From e7573c5ce21a9eb2d12ae81b51cd2400ec4e45d5 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 3 Aug 2009 12:48:25 +0200 Subject: [PATCH 001/738] lib/relocator --- conf/i386.rmk | 6 + include/grub/i386/multiboot.h | 11 +- include/grub/i386/relocator.h | 40 +++++ lib/i386/relocator.c | 148 ++++++++++++++++++ lib/i386/relocator_asm.S | 269 +++++++++++++++++++++++++++++++++ lib/i386/relocator_backward.S | 2 + loader/i386/multiboot.c | 64 ++++---- loader/i386/multiboot_elfxx.c | 14 +- loader/i386/multiboot_helper.S | 75 --------- 9 files changed, 509 insertions(+), 120 deletions(-) create mode 100644 include/grub/i386/relocator.h create mode 100644 lib/i386/relocator.c create mode 100644 lib/i386/relocator_asm.S create mode 100644 lib/i386/relocator_backward.S diff --git a/conf/i386.rmk b/conf/i386.rmk index 93f84ce39..33d49b53c 100644 --- a/conf/i386.rmk +++ b/conf/i386.rmk @@ -14,3 +14,9 @@ pkglib_MODULES += vga_text.mod vga_text_mod_SOURCES = term/i386/pc/vga_text.c term/i386/vga_common.c vga_text_mod_CFLAGS = $(COMMON_CFLAGS) vga_text_mod_LDFLAGS = $(COMMON_LDFLAGS) + +pkglib_MODULES += relocator.mod +relocator_mod_SOURCES = lib/i386/relocator.c lib/i386/relocator_asm.S lib/i386/relocator_backward.S +relocator_mod_CFLAGS = $(COMMON_CFLAGS) +relocator_mod_ASFLAGS = $(COMMON_ASFLAGS) +relocator_mod_LDFLAGS = $(COMMON_LDFLAGS) diff --git a/include/grub/i386/multiboot.h b/include/grub/i386/multiboot.h index 2dd7ec008..bd3c573fa 100644 --- a/include/grub/i386/multiboot.h +++ b/include/grub/i386/multiboot.h @@ -27,16 +27,11 @@ void grub_multiboot2_real_boot (grub_addr_t entry, struct grub_multiboot_info *mbi) __attribute__ ((noreturn)); -extern grub_addr_t grub_multiboot_payload_orig; +extern grub_uint32_t grub_multiboot_payload_eip; +extern char *grub_multiboot_payload_orig; extern grub_addr_t grub_multiboot_payload_dest; extern grub_size_t grub_multiboot_payload_size; -extern grub_uint32_t grub_multiboot_payload_entry_offset; -extern grub_uint8_t grub_multiboot_forward_relocator; -extern grub_uint8_t grub_multiboot_forward_relocator_end; -extern grub_uint8_t grub_multiboot_backward_relocator; -extern grub_uint8_t grub_multiboot_backward_relocator_end; - -#define RELOCATOR_SIZEOF(x) (&grub_multiboot_##x##_relocator_end - &grub_multiboot_##x##_relocator) +#define GRUB_MULTIBOOT_STACK_SIZE 4096 #endif /* ! GRUB_MULTIBOOT_CPU_HEADER */ diff --git a/include/grub/i386/relocator.h b/include/grub/i386/relocator.h new file mode 100644 index 000000000..cbc75ed0a --- /dev/null +++ b/include/grub/i386/relocator.h @@ -0,0 +1,40 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_RELOCATOR_CPU_HEADER +#define GRUB_RELOCATOR_CPU_HEADER 1 + +struct grub_relocator32_state +{ + grub_uint32_t esp; + grub_uint32_t eax; + grub_uint32_t ebx; + grub_uint32_t ecx; + grub_uint32_t edx; + grub_uint32_t eip; +}; + +void * +grub_relocator32_alloc (grub_size_t size); +grub_err_t +grub_relocator32_boot (void *relocator, grub_uint32_t dest, + struct grub_relocator32_state state); +void +grub_relocator32_free (void *relocator); + +#endif /* ! GRUB_RELOCATOR_CPU_HEADER */ diff --git a/lib/i386/relocator.c b/lib/i386/relocator.c new file mode 100644 index 000000000..7dbdd1597 --- /dev/null +++ b/lib/i386/relocator.c @@ -0,0 +1,148 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include + +#include +#include +#include + +#include + +extern grub_uint8_t grub_relocator32_forward_start; +extern grub_uint8_t grub_relocator32_forward_end; +extern grub_uint8_t grub_relocator32_backward_start; +extern grub_uint8_t grub_relocator32_backward_end; + +extern grub_uint32_t grub_relocator32_backward_dest; +extern grub_uint32_t grub_relocator32_backward_size; +#ifdef __x86_64__ +extern grub_uint64_t grub_relocator32_backward_src; +#else +extern grub_uint32_t grub_relocator32_backward_src; +#endif + +extern grub_uint32_t grub_relocator32_forward_dest; +extern grub_uint32_t grub_relocator32_forward_size; +#ifdef __x86_64__ +extern grub_uint64_t grub_relocator32_forward_src; +#else +extern grub_uint32_t grub_relocator32_forward_src; +#endif + +extern grub_uint32_t grub_relocator32_forward_eax; +extern grub_uint32_t grub_relocator32_forward_ebx; +extern grub_uint32_t grub_relocator32_forward_ecx; +extern grub_uint32_t grub_relocator32_forward_edx; +extern grub_uint32_t grub_relocator32_forward_eip; +extern grub_uint32_t grub_relocator32_forward_esp; + +extern grub_uint32_t grub_relocator32_backward_eax; +extern grub_uint32_t grub_relocator32_backward_ebx; +extern grub_uint32_t grub_relocator32_backward_ecx; +extern grub_uint32_t grub_relocator32_backward_edx; +extern grub_uint32_t grub_relocator32_backward_eip; +extern grub_uint32_t grub_relocator32_backward_esp; + +#define RELOCATOR_SIZEOF(x) (&grub_relocator32_##x##_end - &grub_relocator32_##x##_start) +#define RELOCATOR_ALIGN 16 + +void * +grub_relocator32_alloc (grub_size_t size) +{ + char *playground; + + playground = grub_malloc ((RELOCATOR_SIZEOF(forward) + RELOCATOR_ALIGN) + + size + + (RELOCATOR_SIZEOF(backward) + RELOCATOR_ALIGN)); + if (! playground) + return 0; + + *(grub_size_t *) playground = size; + + return playground + RELOCATOR_SIZEOF(forward); +} + +void +grub_relocator32_free (void *relocator) +{ + if (relocator) + grub_free ((char *) relocator - RELOCATOR_SIZEOF(forward)); +} + + +grub_err_t +grub_relocator32_boot (void *relocator, grub_uint32_t dest, + struct grub_relocator32_state state) +{ + grub_size_t size; + char *playground; + void (*entry) (); + + playground = (char *) relocator - RELOCATOR_SIZEOF(forward); + size = *(grub_size_t *) playground; + + if (UINT_TO_PTR (dest) >= relocator) + { + int overhead; + + overhead = ALIGN_UP (dest - RELOCATOR_SIZEOF(backward) - RELOCATOR_ALIGN, RELOCATOR_ALIGN); + grub_relocator32_backward_dest = dest - overhead; + grub_relocator32_backward_src = PTR_TO_UINT64 (relocator - overhead); + grub_relocator32_backward_size = size + overhead; + + grub_relocator32_backward_eax = state.eax; + grub_relocator32_backward_ebx = state.ebx; + grub_relocator32_backward_ecx = state.ecx; + grub_relocator32_backward_edx = state.edx; + grub_relocator32_backward_eip = state.eip; + grub_relocator32_backward_esp = state.esp; + + grub_memmove (relocator - overhead, + &grub_relocator32_backward_start, + RELOCATOR_SIZEOF(backward)); + entry = (void (*) ()) (relocator - overhead); + } + else + { + int overhead; + + overhead = ALIGN_UP (dest + size, RELOCATOR_ALIGN) + + RELOCATOR_SIZEOF(forward) - (dest + size); + + grub_relocator32_forward_dest = dest; + grub_relocator32_forward_src = PTR_TO_UINT64 (relocator); + grub_relocator32_forward_size = size + overhead; + + grub_relocator32_forward_eax = state.eax; + grub_relocator32_forward_ebx = state.ebx; + grub_relocator32_forward_ecx = state.ecx; + grub_relocator32_forward_edx = state.edx; + grub_relocator32_forward_eip = state.eip; + grub_relocator32_forward_esp = state.esp; + + grub_memmove (relocator + size + overhead - RELOCATOR_SIZEOF(forward), + &grub_relocator32_forward_start, RELOCATOR_SIZEOF(forward)); + entry = (void (*) ()) (relocator + size + overhead - RELOCATOR_SIZEOF(forward)); + } + entry (); + + /* Not reached. */ + return GRUB_ERR_NONE; +} diff --git a/lib/i386/relocator_asm.S b/lib/i386/relocator_asm.S new file mode 100644 index 000000000..3ef1fa083 --- /dev/null +++ b/lib/i386/relocator_asm.S @@ -0,0 +1,269 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include + +#ifdef BACKWARD +#define RELOCATOR_VARIABLE(x) VARIABLE(grub_relocator32_backward_ ## x) +#else +#define RELOCATOR_VARIABLE(x) VARIABLE(grub_relocator32_forward_ ## x) +#endif + .p2align 4 /* force 16-byte alignment */ + +RELOCATOR_VARIABLE(start) +#ifdef BACKWARD +base: +#endif + cli + +#ifndef __x86_64__ + /* mov imm32, %eax */ + .byte 0xb8 +RELOCATOR_VARIABLE(dest) + .long 0 + mov %eax, %edi + + /* mov imm32, %eax */ + .byte 0xb8 +RELOCATOR_VARIABLE(src) + .long 0 + mov %eax, %esi + + /* mov imm32, %ecx */ + .byte 0xb9 +RELOCATOR_VARIABLE(size) + .long 0 + mov %edi, %eax +#ifndef BACKWARD + add %ecx, %eax +#endif + add $0x3, %ecx + shr $2, %ecx + +#ifdef BACKWARD + /* Backward movsl is implicitly off-by-four. compensate that. */ + subl $4, %esi + subl $4, %edi + + /* Backward copy. */ + std + addl %ecx, %esi + addl %ecx, %edi + + rep + movsl + +#else + /* Forward copy. */ + cld + rep + movsl +#endif + /* %eax contains now our new base. */ + mov %eax, %esi + add $(cont0 - base), %eax + jmp *%eax +cont0: +#else + xorq %rax, %rax + + /* mov imm32, %eax */ + .byte 0xb8 +RELOCATOR_VARIABLE(dest) + .long 0 + mov %eax, %edi + + /* mov imm64, %rax */ + .byte 0xb8 +RELOCATOR_VARIABLE(src) + .long 0, 0 + mov %rax, %rsi + + xorl %rcx, %rcx + /* mov imm32, %ecx */ + .byte 0xb9 +RELOCATOR_VARIABLE(size) + .long 0 + + mov %rdi, %rax +#ifndef BACKWARD + add %rcx, %rax +#endif + add $0x3, %rcx + shr $2, %rcx + +#ifdef BACKWARD + /* Backward movsl is implicitly off-by-four. compensate that. */ + subl $4, %rsi + subl $4, %rdi + + /* Backward copy. */ + std + addl %rcx, %rsi + addl %rcx, %rdi + + rep + movsl + +#else + /* Forward copy. */ + cld + rep + movsl +#endif + + /* %rax contains now our new 'base'. */ + mov %rax, %rsi +#ifdef APPLE_CC + add $(cont0 - base), %eax +#else + add $(cont0 - base), %rax +#endif + jmp *%rax +cont0: +#ifdef APPLE_CC + lea (cont1 - base) (%esi, 1), %eax + mov %eax, (jump_vector - base) (%esi, 1) + + lea (gdt - base) (%esi, 1), %eax + mov %eax, (gdt_addr - base) (%esi, 1) + + /* Switch to compatibility mode. */ + + lgdt (gdtdesc - base) (%esi, 1) + + /* Update %cs. Thanks to David Miller for pointing this mistake out. */ + ljmp *(jump_vector - base) (%esi,1) +#else + lea (cont1 - base) (%rsi, 1), %rax + mov %eax, (jump_vector - base) (%rsi, 1) + + lea (gdt - base) (%rsi, 1), %rax + mov %rax, (gdt_addr - base) (%rsi, 1) + + /* Switch to compatibility mode. */ + + lgdt (gdtdesc - base) (%rsi, 1) + + /* Update %cs. Thanks to David Miller for pointing this mistake out. */ + ljmp *(jump_vector - base) (%rsi, 1) +#endif + +cont1: + .code32 + + /* Update other registers. */ + mov $0x18, %eax + mov %eax, %ds + mov %eax, %es + mov %eax, %fs + mov %eax, %gs + mov %eax, %ss + + /* Disable paging. */ + mov %cr0, %eax + and $0x7fffffff, %eax + mov %eax, %cr0 + + /* Disable amd64. */ + mov $0xc0000080, %ecx + rdmsr + and $0xfffffeff, %eax + wrmsr + + /* Turn off PAE. */ + movl %cr4, %eax + and $0xffffffcf, %eax + mov %eax, %cr4 + + jmp cont2 +cont2: +#endif + .code32 + + /* mov imm32, %eax */ + .byte 0xb8 +RELOCATOR_VARIABLE (esp) + .long 0 + + movl %eax, %esp + + /* mov imm32, %eax */ + .byte 0xb8 +RELOCATOR_VARIABLE (eax) + .long 0 + + /* mov imm32, %ebx */ + .byte 0xbb +RELOCATOR_VARIABLE (ebx) + .long 0 + + /* mov imm32, %ecx */ + .byte 0xb9 +RELOCATOR_VARIABLE (ecx) + .long 0 + + /* mov imm32, %edx */ + .byte 0xba +RELOCATOR_VARIABLE (edx) + .long 0 + + /* Cleared direction flag is of no problem with any current + payload and makes this implementation easier. */ + cld + + .byte 0xea +RELOCATOR_VARIABLE (eip) + .long 0 + .word 0x08 + +#ifdef __x86_64__ + /* GDT. Copied from loader/i386/linux.c. */ + .p2align 4 +gdt: + /* NULL. */ + .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + + /* Reserved. */ + .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + + /* Code segment. */ + .byte 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x9A, 0xCF, 0x00 + + /* Data segment. */ + .byte 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x92, 0xCF, 0x00 + +gdtdesc: + .word 31 +gdt_addr: + /* Filled by the code. */ + .quad 0 + + .p2align 4 +jump_vector: + /* Jump location. Is filled by the code */ + .long 0 + .long 0x10 +#endif + +#ifndef BACKWARD +base: +#endif + + +RELOCATOR_VARIABLE(end) diff --git a/lib/i386/relocator_backward.S b/lib/i386/relocator_backward.S new file mode 100644 index 000000000..06913470e --- /dev/null +++ b/lib/i386/relocator_backward.S @@ -0,0 +1,2 @@ +#define BACKWARD +#include "relocator_asm.S" diff --git a/loader/i386/multiboot.c b/loader/i386/multiboot.c index 87ffcae8d..974395f63 100644 --- a/loader/i386/multiboot.c +++ b/loader/i386/multiboot.c @@ -48,18 +48,35 @@ #include #include #endif +#include extern grub_dl_t my_mod; static struct grub_multiboot_info *mbi, *mbi_dest; -static grub_addr_t entry; -static char *playground; static grub_size_t code_size; +char *grub_multiboot_payload_orig; +grub_addr_t grub_multiboot_payload_dest; +grub_size_t grub_multiboot_payload_size; +grub_uint32_t grub_multiboot_payload_eip; +grub_uint32_t grub_multiboot_payload_esp; + static grub_err_t grub_multiboot_boot (void) { - grub_multiboot_real_boot (entry, mbi_dest); + struct grub_relocator32_state state = + { + .eax = MULTIBOOT_MAGIC2, + .ebx = PTR_TO_UINT32 (mbi_dest), + .ecx = 0, + .edx = 0, + .eip = grub_multiboot_payload_eip, + .esp = grub_multiboot_payload_esp + }; + + grub_relocator32_boot (grub_multiboot_payload_orig, + grub_multiboot_payload_dest, + state); /* Not reached. */ return GRUB_ERR_NONE; @@ -248,11 +265,8 @@ grub_multiboot (int argc, char *argv[]) goto fail; } - if (playground) - { - grub_free (playground); - playground = NULL; - } + grub_relocator32_free (grub_multiboot_payload_orig); + grub_multiboot_payload_orig = NULL; mmap_length = grub_get_multiboot_mmap_len (); @@ -267,11 +281,13 @@ grub_multiboot (int argc, char *argv[]) ((void *) ((x) + code_size + cmdline_length)) #define mbi_addr(x) ((void *) ((x) + code_size + cmdline_length + boot_loader_name_length)) #define mmap_addr(x) ((void *) ((x) + code_size + cmdline_length + boot_loader_name_length + sizeof (struct grub_multiboot_info))) +#define stack_addr(x) ((void *) ((x) + code_size + cmdline_length + boot_loader_name_length + sizeof (struct grub_multiboot_info) + mmap_length + GRUB_MULTIBOOT_STACK_SIZE)) grub_multiboot_payload_size = cmdline_length /* boot_loader_name_length might need to grow for mbi,etc to be aligned (see below) */ + boot_loader_name_length + 3 - + sizeof (struct grub_multiboot_info) + mmap_length; + + sizeof (struct grub_multiboot_info) + mmap_length + + GRUB_MULTIBOOT_STACK_SIZE; if (header->flags & MULTIBOOT_AOUT_KLUDGE) { @@ -287,11 +303,12 @@ grub_multiboot (int argc, char *argv[]) grub_multiboot_payload_dest = header->load_addr; grub_multiboot_payload_size += code_size; - playground = grub_malloc (RELOCATOR_SIZEOF(forward) + grub_multiboot_payload_size + RELOCATOR_SIZEOF(backward)); - if (! playground) - goto fail; - grub_multiboot_payload_orig = (long) playground + RELOCATOR_SIZEOF(forward); + grub_multiboot_payload_orig + = grub_relocator32_alloc (grub_multiboot_payload_size); + + if (! grub_multiboot_payload_orig) + goto fail; if ((grub_file_seek (file, offset)) == (grub_off_t) - 1) goto fail; @@ -304,7 +321,7 @@ grub_multiboot (int argc, char *argv[]) grub_memset ((void *) (grub_multiboot_payload_orig + load_size), 0, header->bss_end_addr - header->load_addr - load_size); - grub_multiboot_payload_entry_offset = header->entry_addr - header->load_addr; + grub_multiboot_payload_eip = header->entry_addr; } else if (grub_multiboot_load_elf (file, buffer) != GRUB_ERR_NONE) @@ -325,23 +342,6 @@ grub_multiboot (int argc, char *argv[]) mbi->mmap_addr = (grub_uint32_t) mmap_addr (grub_multiboot_payload_dest); mbi->flags |= MULTIBOOT_INFO_MEM_MAP; - if (grub_multiboot_payload_dest >= grub_multiboot_payload_orig) - { - grub_memmove (playground, &grub_multiboot_forward_relocator, RELOCATOR_SIZEOF(forward)); - entry = (grub_addr_t) playground; - } - else - { - grub_memmove ((char *) (grub_multiboot_payload_orig + grub_multiboot_payload_size), - &grub_multiboot_backward_relocator, RELOCATOR_SIZEOF(backward)); - entry = (grub_addr_t) grub_multiboot_payload_orig + grub_multiboot_payload_size; - } - - grub_dprintf ("multiboot_loader", "dest=%p, size=0x%x, entry_offset=0x%x\n", - (void *) grub_multiboot_payload_dest, - grub_multiboot_payload_size, - grub_multiboot_payload_entry_offset); - /* Convert from bytes to kilobytes. */ mbi->mem_lower = grub_mmap_get_lower () / 1024; mbi->mem_upper = grub_mmap_get_upper () / 1024; @@ -371,6 +371,8 @@ grub_multiboot (int argc, char *argv[]) if (grub_multiboot_get_bootdev (&mbi->boot_device)) mbi->flags |= MULTIBOOT_INFO_BOOTDEV; + grub_multiboot_payload_esp = PTR_TO_UINT32 (stack_addr (grub_multiboot_payload_dest)); + grub_loader_set (grub_multiboot_boot, grub_multiboot_unload, 1); fail: diff --git a/loader/i386/multiboot_elfxx.c b/loader/i386/multiboot_elfxx.c index 77c47118c..0b9820dcc 100644 --- a/loader/i386/multiboot_elfxx.c +++ b/loader/i386/multiboot_elfxx.c @@ -32,6 +32,8 @@ #error "I'm confused" #endif +#include + #define CONCAT(a,b) CONCAT_(a, b) #define CONCAT_(a,b) a ## b @@ -99,11 +101,12 @@ CONCAT(grub_multiboot_load_elf, XX) (grub_file_t file, void *buffer) grub_multiboot_payload_dest = phdr(lowest_segment)->p_paddr; grub_multiboot_payload_size += code_size; - playground = grub_malloc (RELOCATOR_SIZEOF(forward) + grub_multiboot_payload_size + RELOCATOR_SIZEOF(backward)); - if (! playground) - return grub_errno; - grub_multiboot_payload_orig = (long) playground + RELOCATOR_SIZEOF(forward); + grub_multiboot_payload_orig + = grub_relocator32_alloc (grub_multiboot_payload_size); + + if (!grub_multiboot_payload_orig) + return grub_errno; /* Load every loadable segment in memory. */ for (i = 0; i < ehdr->e_phnum; i++) @@ -135,8 +138,7 @@ CONCAT(grub_multiboot_load_elf, XX) (grub_file_t file, void *buffer) if (phdr(i)->p_vaddr <= ehdr->e_entry && phdr(i)->p_vaddr + phdr(i)->p_memsz > ehdr->e_entry) { - grub_multiboot_payload_entry_offset = (ehdr->e_entry - phdr(i)->p_vaddr) - + (phdr(i)->p_paddr - phdr(lowest_segment)->p_paddr); + grub_multiboot_payload_eip = ehdr->e_entry; break; } diff --git a/loader/i386/multiboot_helper.S b/loader/i386/multiboot_helper.S index d1094588b..2f9af778b 100644 --- a/loader/i386/multiboot_helper.S +++ b/loader/i386/multiboot_helper.S @@ -22,81 +22,6 @@ .p2align 2 /* force 4-byte alignment */ -/* - * This starts the multiboot kernel. - */ - -VARIABLE(grub_multiboot_payload_size) - .long 0 -VARIABLE(grub_multiboot_payload_orig) - .long 0 -VARIABLE(grub_multiboot_payload_dest) - .long 0 -VARIABLE(grub_multiboot_payload_entry_offset) - .long 0 - -/* - * The relocators below understand the following parameters: - * ecx: Size of the block to be copied. - * esi: Where to copy from (always lowest address, even if we're relocating - * backwards). - * edi: Where to copy to (likewise). - * edx: Offset of the entry point (relative to the beginning of the block). - */ - -VARIABLE(grub_multiboot_forward_relocator) - /* Add entry offset. */ - addl %edi, %edx - - /* Forward copy. */ - cld - rep - movsb - - jmp *%edx -VARIABLE(grub_multiboot_forward_relocator_end) - -VARIABLE(grub_multiboot_backward_relocator) - /* Add entry offset (before %edi is mangled). */ - addl %edi, %edx - - /* Backward movsb is implicitly off-by-one. compensate that. */ - decl %esi - decl %edi - - /* Backward copy. */ - std - addl %ecx, %esi - addl %ecx, %edi - rep - movsb - - cld - jmp *%edx -VARIABLE(grub_multiboot_backward_relocator_end) - -FUNCTION(grub_multiboot_real_boot) - /* Push the entry address on the stack. */ - pushl %eax - /* Move the address of the multiboot information structure to ebx. */ - movl %edx,%ebx - - /* Interrupts should be disabled. */ - cli - - /* Where do we copy what from. */ - movl EXT_C(grub_multiboot_payload_size), %ecx - movl EXT_C(grub_multiboot_payload_orig), %esi - movl EXT_C(grub_multiboot_payload_dest), %edi - movl EXT_C(grub_multiboot_payload_entry_offset), %edx - - /* Move the magic value into eax. */ - movl $MULTIBOOT_MAGIC2, %eax - - /* Jump to the relocator. */ - popl %ebp - jmp *%ebp - /* * This starts the multiboot 2 kernel. */ From c2a583ec38e29afa894a236c2bda65bf1e0bb83c Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 3 Aug 2009 13:45:37 +0200 Subject: [PATCH 002/738] 64-bit bugfixes --- lib/i386/relocator_asm.S | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/lib/i386/relocator_asm.S b/lib/i386/relocator_asm.S index 3ef1fa083..f16d7f263 100644 --- a/lib/i386/relocator_asm.S +++ b/lib/i386/relocator_asm.S @@ -89,12 +89,13 @@ RELOCATOR_VARIABLE(dest) mov %eax, %edi /* mov imm64, %rax */ + .byte 0x48 .byte 0xb8 RELOCATOR_VARIABLE(src) .long 0, 0 mov %rax, %rsi - xorl %rcx, %rcx + xorq %rcx, %rcx /* mov imm32, %ecx */ .byte 0xb9 RELOCATOR_VARIABLE(size) @@ -109,13 +110,13 @@ RELOCATOR_VARIABLE(size) #ifdef BACKWARD /* Backward movsl is implicitly off-by-four. compensate that. */ - subl $4, %rsi - subl $4, %rdi + subq $4, %rsi + subq $4, %rdi /* Backward copy. */ std - addl %rcx, %rsi - addl %rcx, %rdi + addq %rcx, %rsi + addq %rcx, %rdi rep movsl @@ -230,7 +231,11 @@ RELOCATOR_VARIABLE (edx) .byte 0xea RELOCATOR_VARIABLE (eip) .long 0 +#ifdef __x86_64__ + .word 0x10 +#else .word 0x08 +#endif #ifdef __x86_64__ /* GDT. Copied from loader/i386/linux.c. */ From fe7546f39a9aed99f6f92403db4e59a35af212c0 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 3 Aug 2009 13:50:02 +0200 Subject: [PATCH 003/738] indent --- lib/i386/relocator.c | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/lib/i386/relocator.c b/lib/i386/relocator.c index 7dbdd1597..6a9b3ce1b 100644 --- a/lib/i386/relocator.c +++ b/lib/i386/relocator.c @@ -68,22 +68,23 @@ grub_relocator32_alloc (grub_size_t size) { char *playground; - playground = grub_malloc ((RELOCATOR_SIZEOF(forward) + RELOCATOR_ALIGN) - + size - + (RELOCATOR_SIZEOF(backward) + RELOCATOR_ALIGN)); - if (! playground) + playground = grub_malloc ((RELOCATOR_SIZEOF (forward) + RELOCATOR_ALIGN) + + size + + (RELOCATOR_SIZEOF (backward) + + RELOCATOR_ALIGN)); + if (!playground) return 0; *(grub_size_t *) playground = size; - return playground + RELOCATOR_SIZEOF(forward); + return playground + RELOCATOR_SIZEOF (forward); } void grub_relocator32_free (void *relocator) { if (relocator) - grub_free ((char *) relocator - RELOCATOR_SIZEOF(forward)); + grub_free ((char *) relocator - RELOCATOR_SIZEOF (forward)); } @@ -95,14 +96,16 @@ grub_relocator32_boot (void *relocator, grub_uint32_t dest, char *playground; void (*entry) (); - playground = (char *) relocator - RELOCATOR_SIZEOF(forward); + playground = (char *) relocator - RELOCATOR_SIZEOF (forward); size = *(grub_size_t *) playground; if (UINT_TO_PTR (dest) >= relocator) { int overhead; - overhead = ALIGN_UP (dest - RELOCATOR_SIZEOF(backward) - RELOCATOR_ALIGN, RELOCATOR_ALIGN); + overhead = + ALIGN_UP (dest - RELOCATOR_SIZEOF (backward) - RELOCATOR_ALIGN, + RELOCATOR_ALIGN); grub_relocator32_backward_dest = dest - overhead; grub_relocator32_backward_src = PTR_TO_UINT64 (relocator - overhead); grub_relocator32_backward_size = size + overhead; @@ -116,15 +119,15 @@ grub_relocator32_boot (void *relocator, grub_uint32_t dest, grub_memmove (relocator - overhead, &grub_relocator32_backward_start, - RELOCATOR_SIZEOF(backward)); - entry = (void (*) ()) (relocator - overhead); + RELOCATOR_SIZEOF (backward)); + entry = (void (*)()) (relocator - overhead); } else { int overhead; - overhead = ALIGN_UP (dest + size, RELOCATOR_ALIGN) - + RELOCATOR_SIZEOF(forward) - (dest + size); + overhead = ALIGN_UP (dest + size, RELOCATOR_ALIGN) + + RELOCATOR_SIZEOF (forward) - (dest + size); grub_relocator32_forward_dest = dest; grub_relocator32_forward_src = PTR_TO_UINT64 (relocator); @@ -137,9 +140,12 @@ grub_relocator32_boot (void *relocator, grub_uint32_t dest, grub_relocator32_forward_eip = state.eip; grub_relocator32_forward_esp = state.esp; - grub_memmove (relocator + size + overhead - RELOCATOR_SIZEOF(forward), - &grub_relocator32_forward_start, RELOCATOR_SIZEOF(forward)); - entry = (void (*) ()) (relocator + size + overhead - RELOCATOR_SIZEOF(forward)); + grub_memmove (relocator + size + overhead - RELOCATOR_SIZEOF (forward), + &grub_relocator32_forward_start, + RELOCATOR_SIZEOF (forward)); + entry = + (void (*)()) (relocator + size + overhead - + RELOCATOR_SIZEOF (forward)); } entry (); From 23a2f35a0bcef47b68ab07310456643750d639af Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 3 Aug 2009 13:52:03 +0200 Subject: [PATCH 004/738] trailing whitespaces in asm --- lib/i386/relocator_asm.S | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/lib/i386/relocator_asm.S b/lib/i386/relocator_asm.S index f16d7f263..d022a6840 100644 --- a/lib/i386/relocator_asm.S +++ b/lib/i386/relocator_asm.S @@ -17,12 +17,12 @@ */ #include - + #ifdef BACKWARD #define RELOCATOR_VARIABLE(x) VARIABLE(grub_relocator32_backward_ ## x) #else #define RELOCATOR_VARIABLE(x) VARIABLE(grub_relocator32_forward_ ## x) -#endif +#endif .p2align 4 /* force 16-byte alignment */ RELOCATOR_VARIABLE(start) @@ -201,9 +201,9 @@ cont2: .byte 0xb8 RELOCATOR_VARIABLE (esp) .long 0 - + movl %eax, %esp - + /* mov imm32, %eax */ .byte 0xb8 RELOCATOR_VARIABLE (eax) @@ -270,5 +270,4 @@ jump_vector: base: #endif - RELOCATOR_VARIABLE(end) From 7c8f178d02c533be018a83db48429a08d4952a3a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 3 Aug 2009 14:30:51 +0200 Subject: [PATCH 005/738] realloc --- include/grub/i386/relocator.h | 15 ++++++++------- lib/i386/relocator.c | 19 +++++++++++++++++++ 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/include/grub/i386/relocator.h b/include/grub/i386/relocator.h index cbc75ed0a..ef7fe23aa 100644 --- a/include/grub/i386/relocator.h +++ b/include/grub/i386/relocator.h @@ -19,6 +19,9 @@ #ifndef GRUB_RELOCATOR_CPU_HEADER #define GRUB_RELOCATOR_CPU_HEADER 1 +#include +#include + struct grub_relocator32_state { grub_uint32_t esp; @@ -29,12 +32,10 @@ struct grub_relocator32_state grub_uint32_t eip; }; -void * -grub_relocator32_alloc (grub_size_t size); -grub_err_t -grub_relocator32_boot (void *relocator, grub_uint32_t dest, - struct grub_relocator32_state state); -void -grub_relocator32_free (void *relocator); +void *grub_relocator32_alloc (grub_size_t size); +grub_err_t grub_relocator32_boot (void *relocator, grub_uint32_t dest, + struct grub_relocator32_state state); +void *grub_relocator32_realloc (void *relocator, grub_size_t size); +void grub_relocator32_free (void *relocator); #endif /* ! GRUB_RELOCATOR_CPU_HEADER */ diff --git a/lib/i386/relocator.c b/lib/i386/relocator.c index 6a9b3ce1b..0205d8ef4 100644 --- a/lib/i386/relocator.c +++ b/lib/i386/relocator.c @@ -80,6 +80,25 @@ grub_relocator32_alloc (grub_size_t size) return playground + RELOCATOR_SIZEOF (forward); } +void * +grub_relocator32_realloc (void *relocator, grub_size_t size) +{ + char *playground; + + playground = (char *) relocator - RELOCATOR_SIZEOF (forward); + + playground = grub_realloc (playground, + (RELOCATOR_SIZEOF (forward) + RELOCATOR_ALIGN) + + size + + (RELOCATOR_SIZEOF (backward) + RELOCATOR_ALIGN)); + if (!playground) + return 0; + + *(grub_size_t *) playground = size; + + return playground + RELOCATOR_SIZEOF (forward); +} + void grub_relocator32_free (void *relocator) { From 5c29f4d96291f88bd0529c4037dec4c1c72f646e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 5 Aug 2009 19:30:43 +0200 Subject: [PATCH 006/738] Improvements --- THANKS | 1 + include/grub/i386/pc/memory.h | 17 +-- lib/i386/relocator.c | 12 +- lib/i386/relocator_asm.S | 252 +++++++++++++++++----------------- 4 files changed, 130 insertions(+), 152 deletions(-) diff --git a/THANKS b/THANKS index 5ce190944..82b4bc838 100644 --- a/THANKS +++ b/THANKS @@ -8,6 +8,7 @@ generally assist in the GRUB 2 maintainership process: Andrey Shuvikov Bibo Mao +David Miller Guillem Jover Harley D. Eades III Hitoshi Ozeki diff --git a/include/grub/i386/pc/memory.h b/include/grub/i386/pc/memory.h index d7910ab15..b1d75dbc9 100644 --- a/include/grub/i386/pc/memory.h +++ b/include/grub/i386/pc/memory.h @@ -28,6 +28,8 @@ #include #endif +#include + /* The scratch buffer used in real mode code. */ #define GRUB_MEMORY_MACHINE_SCRATCH_ADDR 0x68000 #define GRUB_MEMORY_MACHINE_SCRATCH_SEG (GRUB_MEMORY_MACHINE_SCRATCH_ADDR >> 4) @@ -63,21 +65,6 @@ /* The address where another boot loader is loaded. */ #define GRUB_MEMORY_MACHINE_BOOT_LOADER_ADDR 0x7c00 -/* The flag for protected mode. */ -#define GRUB_MEMORY_MACHINE_CR0_PE_ON 0x1 - -/* The code segment of the protected mode. */ -#define GRUB_MEMORY_MACHINE_PROT_MODE_CSEG 0x8 - -/* The data segment of the protected mode. */ -#define GRUB_MEMORY_MACHINE_PROT_MODE_DSEG 0x10 - -/* The code segment of the pseudo real mode. */ -#define GRUB_MEMORY_MACHINE_PSEUDO_REAL_CSEG 0x18 - -/* The data segment of the pseudo real mode. */ -#define GRUB_MEMORY_MACHINE_PSEUDO_REAL_DSEG 0x20 - #ifndef ASM_FILE struct grub_machine_mmap_entry diff --git a/lib/i386/relocator.c b/lib/i386/relocator.c index 0205d8ef4..3f0a40a27 100644 --- a/lib/i386/relocator.c +++ b/lib/i386/relocator.c @@ -32,19 +32,11 @@ extern grub_uint8_t grub_relocator32_backward_end; extern grub_uint32_t grub_relocator32_backward_dest; extern grub_uint32_t grub_relocator32_backward_size; -#ifdef __x86_64__ -extern grub_uint64_t grub_relocator32_backward_src; -#else -extern grub_uint32_t grub_relocator32_backward_src; -#endif +extern grub_addr_t grub_relocator32_backward_src; extern grub_uint32_t grub_relocator32_forward_dest; extern grub_uint32_t grub_relocator32_forward_size; -#ifdef __x86_64__ -extern grub_uint64_t grub_relocator32_forward_src; -#else -extern grub_uint32_t grub_relocator32_forward_src; -#endif +extern grub_addr_t grub_relocator32_forward_src; extern grub_uint32_t grub_relocator32_forward_eax; extern grub_uint32_t grub_relocator32_forward_ebx; diff --git a/lib/i386/relocator_asm.S b/lib/i386/relocator_asm.S index d022a6840..7d58c8e97 100644 --- a/lib/i386/relocator_asm.S +++ b/lib/i386/relocator_asm.S @@ -17,12 +17,35 @@ */ #include +#include #ifdef BACKWARD #define RELOCATOR_VARIABLE(x) VARIABLE(grub_relocator32_backward_ ## x) #else #define RELOCATOR_VARIABLE(x) VARIABLE(grub_relocator32_forward_ ## x) #endif +#ifdef __x86_64__ +#define RAX %rax +#define RCX %rcx +#define RDI %rdi +#define RSI %rdi +#else +#define RAX %eax +#define RCX %ecx +#define RDI %edi +#define RSI %esi +#endif + +/* Apple's linker has a problem with 64-bit relocations. */ +#if defined (__apple__) || ! defined (__x86_64__) +#define RSIA %esi +#define RAXA %eax +#else +#define RSIA %rsi +#define RAXA %rax +#endif + + .p2align 4 /* force 16-byte alignment */ RELOCATOR_VARIABLE(start) @@ -35,88 +58,64 @@ base: /* mov imm32, %eax */ .byte 0xb8 RELOCATOR_VARIABLE(dest) - .long 0 - mov %eax, %edi + .long 0 + movl %eax, %edi /* mov imm32, %eax */ .byte 0xb8 RELOCATOR_VARIABLE(src) - .long 0 - mov %eax, %esi + .long 0 + movl %eax, %esi /* mov imm32, %ecx */ .byte 0xb9 RELOCATOR_VARIABLE(size) - .long 0 - mov %edi, %eax -#ifndef BACKWARD - add %ecx, %eax -#endif - add $0x3, %ecx - shr $2, %ecx - -#ifdef BACKWARD - /* Backward movsl is implicitly off-by-four. compensate that. */ - subl $4, %esi - subl $4, %edi - - /* Backward copy. */ - std - addl %ecx, %esi - addl %ecx, %edi - - rep - movsl - + .long 0 #else - /* Forward copy. */ - cld - rep - movsl -#endif - /* %eax contains now our new base. */ - mov %eax, %esi - add $(cont0 - base), %eax - jmp *%eax -cont0: -#else - xorq %rax, %rax + xorq %rax, %rax /* mov imm32, %eax */ .byte 0xb8 RELOCATOR_VARIABLE(dest) - .long 0 - mov %eax, %edi + .long 0 + movq %rax, %rdi /* mov imm64, %rax */ .byte 0x48 .byte 0xb8 RELOCATOR_VARIABLE(src) - .long 0, 0 - mov %rax, %rsi + .long 0, 0 + movq %rax, %rsi - xorq %rcx, %rcx + xorq %rcx, %rcx /* mov imm32, %ecx */ .byte 0xb9 RELOCATOR_VARIABLE(size) - .long 0 + .long 0 - mov %rdi, %rax -#ifndef BACKWARD - add %rcx, %rax #endif - add $0x3, %rcx - shr $2, %rcx + mov RDI, RAX + +#ifdef BACKWARD + add RCX, RSI + add RDX, RDI +#endif + +#ifndef BACKWARD + add RCX, RAX +#endif + addq $0x3, RCX + shrq $2, RCX + + #ifdef BACKWARD /* Backward movsl is implicitly off-by-four. compensate that. */ - subq $4, %rsi - subq $4, %rdi + subq $4, RSI + subq $4, RDI /* Backward copy. */ std - addq %rcx, %rsi - addq %rcx, %rdi rep movsl @@ -129,142 +128,141 @@ RELOCATOR_VARIABLE(size) #endif /* %rax contains now our new 'base'. */ - mov %rax, %rsi -#ifdef APPLE_CC - add $(cont0 - base), %eax -#else - add $(cont0 - base), %rax -#endif - jmp *%rax + mov RAX, RSI + add $(cont0 - base), RAXA + jmp *RAX cont0: -#ifdef APPLE_CC - lea (cont1 - base) (%esi, 1), %eax - mov %eax, (jump_vector - base) (%esi, 1) + lea (cont1 - base) (RSIA, 1), RAXA + movl %eax, (jump_vector - base) (RSIA, 1) - lea (gdt - base) (%esi, 1), %eax - mov %eax, (gdt_addr - base) (%esi, 1) + lea (gdt - base) (RSIA, 1), RAXA + mov RAXA, (gdt_addr - base) (RSIA, 1) /* Switch to compatibility mode. */ - lgdt (gdtdesc - base) (%esi, 1) + lgdt (gdtdesc - base) (RSIA, 1) /* Update %cs. Thanks to David Miller for pointing this mistake out. */ - ljmp *(jump_vector - base) (%esi,1) -#else - lea (cont1 - base) (%rsi, 1), %rax - mov %eax, (jump_vector - base) (%rsi, 1) - - lea (gdt - base) (%rsi, 1), %rax - mov %rax, (gdt_addr - base) (%rsi, 1) - - /* Switch to compatibility mode. */ - - lgdt (gdtdesc - base) (%rsi, 1) - - /* Update %cs. Thanks to David Miller for pointing this mistake out. */ - ljmp *(jump_vector - base) (%rsi, 1) -#endif + ljmp *(jump_vector - base) (RSIA, 1) cont1: .code32 /* Update other registers. */ - mov $0x18, %eax - mov %eax, %ds - mov %eax, %es - mov %eax, %fs - mov %eax, %gs - mov %eax, %ss + movl $GRUB_MEMORY_MACHINE_PROT_MODE_DSEG, %eax + movl %eax, %ds + movl %eax, %es + movl %eax, %fs + movl %eax, %gs + movl %eax, %ss /* Disable paging. */ - mov %cr0, %eax - and $0x7fffffff, %eax - mov %eax, %cr0 + movl %cr0, %eax + andl $0x7fffffff, %eax + movl %eax, %cr0 /* Disable amd64. */ - mov $0xc0000080, %ecx + movl $0xc0000080, %ecx rdmsr - and $0xfffffeff, %eax + andl $0xfffffeff, %eax wrmsr /* Turn off PAE. */ - movl %cr4, %eax - and $0xffffffcf, %eax - mov %eax, %cr4 + movl %cr4, %eax + andl $0xffffffcf, %eax + movl %eax, %cr4 - jmp cont2 + jmp cont2 cont2: -#endif .code32 /* mov imm32, %eax */ .byte 0xb8 RELOCATOR_VARIABLE (esp) - .long 0 + .long 0 - movl %eax, %esp + movl %eax, %esp /* mov imm32, %eax */ .byte 0xb8 RELOCATOR_VARIABLE (eax) - .long 0 + .long 0 /* mov imm32, %ebx */ .byte 0xbb RELOCATOR_VARIABLE (ebx) - .long 0 + .long 0 /* mov imm32, %ecx */ .byte 0xb9 RELOCATOR_VARIABLE (ecx) - .long 0 + .long 0 /* mov imm32, %edx */ .byte 0xba RELOCATOR_VARIABLE (edx) - .long 0 + .long 0 /* Cleared direction flag is of no problem with any current payload and makes this implementation easier. */ cld - .byte 0xea + .byte 0xea RELOCATOR_VARIABLE (eip) - .long 0 -#ifdef __x86_64__ - .word 0x10 -#else - .word 0x08 -#endif + .long 0 + .word 0x08 -#ifdef __x86_64__ - /* GDT. Copied from loader/i386/linux.c. */ - .p2align 4 + /* GDT. The same as is used in 32-bit GRUB. */ + .p2align 4 gdt: - /* NULL. */ - .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + .word 0, 0 + .byte 0, 0, 0, 0 - /* Reserved. */ - .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + /* -- code segment -- + * base = 0x00000000, limit = 0xFFFFF (4 KiB Granularity), present + * type = 32bit code execute/read, DPL = 0 + */ + .word 0xFFFF, 0 + .byte 0, 0x9A, 0xCF, 0 - /* Code segment. */ - .byte 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x9A, 0xCF, 0x00 + /* -- data segment -- + * base = 0x00000000, limit 0xFFFFF (4 KiB Granularity), present + * type = 32 bit data read/write, DPL = 0 + */ + .word 0xFFFF, 0 + .byte 0, 0x92, 0xCF, 0 - /* Data segment. */ - .byte 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x92, 0xCF, 0x00 + /* -- 16 bit real mode CS -- + * base = 0x00000000, limit 0x0FFFF (1 B Granularity), present + * type = 16 bit code execute/read only/conforming, DPL = 0 + */ + .word 0xFFFF, 0 + .byte 0, 0x9E, 0, 0 + /* -- 16 bit real mode DS -- + * base = 0x00000000, limit 0x0FFFF (1 B Granularity), present + * type = 16 bit data read/write, DPL = 0 + */ + .word 0xFFFF, 0 + .byte 0, 0x92, 0, 0 + + .p2align 4 gdtdesc: - .word 31 + .word 0x27 gdt_addr: +#ifdef __x86_64__ /* Filled by the code. */ - .quad 0 - - .p2align 4 + .quad 0 +#else + /* Filled by the code. */ + .long 0 +#endif + + .p2align 4 jump_vector: /* Jump location. Is filled by the code */ - .long 0 - .long 0x10 -#endif + .long 0 + .long GRUB_MEMORY_MACHINE_PROT_MODE_CSEG #ifndef BACKWARD base: From b131c45455556d58940b53071e1bb1a8ed8fd2bf Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 5 Aug 2009 19:58:05 +0200 Subject: [PATCH 007/738] Improvements for Apple? --- include/grub/i386/memory.h | 30 ++++++++++ include/grub/i386/pc/memory.h | 12 ++++ kern/i386/realmode.S | 4 +- lib/i386/relocator_asm.S | 107 ++++++++++++++-------------------- 4 files changed, 87 insertions(+), 66 deletions(-) create mode 100644 include/grub/i386/memory.h diff --git a/include/grub/i386/memory.h b/include/grub/i386/memory.h new file mode 100644 index 000000000..a0f3192b8 --- /dev/null +++ b/include/grub/i386/memory.h @@ -0,0 +1,30 @@ +/* memory.h - describe the memory map */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2007,2008 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_MEMORY_CPU_HEADER +#define GRUB_MEMORY_CPU_HEADER 1 + +/* The flag for protected mode. */ +#define GRUB_MEMORY_CPU_CR0_PE_ON 0x1 +#define GRUB_MEMORY_CPU_CR4_PAE_ON 0x00000040 +#define GRUB_MEMORY_CPU_CR0_PAGING_ON 0x80000000 +#define GRUB_MEMORY_CPU_AMD64_MSR 0xc0000080 +#define GRUB_MEMORY_CPU_AMD64_MSR_ON 0x00000100 + +#endif /* ! GRUB_MEMORY_CPU_HEADER */ diff --git a/include/grub/i386/pc/memory.h b/include/grub/i386/pc/memory.h index b1d75dbc9..7a132fd24 100644 --- a/include/grub/i386/pc/memory.h +++ b/include/grub/i386/pc/memory.h @@ -65,6 +65,18 @@ /* The address where another boot loader is loaded. */ #define GRUB_MEMORY_MACHINE_BOOT_LOADER_ADDR 0x7c00 +/* The code segment of the protected mode. */ +#define GRUB_MEMORY_MACHINE_PROT_MODE_CSEG 0x8 + +/* The data segment of the protected mode. */ +#define GRUB_MEMORY_MACHINE_PROT_MODE_DSEG 0x10 + +/* The code segment of the pseudo real mode. */ +#define GRUB_MEMORY_MACHINE_PSEUDO_REAL_CSEG 0x18 + +/* The data segment of the pseudo real mode. */ +#define GRUB_MEMORY_MACHINE_PSEUDO_REAL_DSEG 0x20 + #ifndef ASM_FILE struct grub_machine_mmap_entry diff --git a/kern/i386/realmode.S b/kern/i386/realmode.S index 11f4d5347..5f28f9eb3 100644 --- a/kern/i386/realmode.S +++ b/kern/i386/realmode.S @@ -127,7 +127,7 @@ real_to_prot: /* turn on protected mode */ movl %cr0, %eax - orl $GRUB_MEMORY_MACHINE_CR0_PE_ON, %eax + orl $GRUB_MEMORY_CPU_CR0_PE_ON, %eax movl %eax, %cr0 /* jump to relocation, flush prefetch queue, and reload %cs */ @@ -196,7 +196,7 @@ tmpcseg: /* clear the PE bit of CR0 */ movl %cr0, %eax - andl $(~GRUB_MEMORY_MACHINE_CR0_PE_ON), %eax + andl $(~GRUB_MEMORY_CPU_CR0_PE_ON), %eax movl %eax, %cr0 /* flush prefetch queue, reload %cs */ diff --git a/lib/i386/relocator_asm.S b/lib/i386/relocator_asm.S index 7d58c8e97..72c057ce2 100644 --- a/lib/i386/relocator_asm.S +++ b/lib/i386/relocator_asm.S @@ -27,30 +27,28 @@ #ifdef __x86_64__ #define RAX %rax #define RCX %rcx +#define RDX %rdx #define RDI %rdi #define RSI %rdi #else #define RAX %eax #define RCX %ecx +#define RDX %edx #define RDI %edi #define RSI %esi #endif -/* Apple's linker has a problem with 64-bit relocations. */ -#if defined (__apple__) || ! defined (__x86_64__) -#define RSIA %esi -#define RAXA %eax -#else -#define RSIA %rsi -#define RAXA %rax -#endif +/* The code segment of the protected mode. */ +#define CODE_SEGMENT 0x10 +/* The data segment of the protected mode. */ +#define DATA_SEGMENT 0x18 .p2align 4 /* force 16-byte alignment */ RELOCATOR_VARIABLE(start) #ifdef BACKWARD -base: +L_base: #endif cli @@ -105,14 +103,14 @@ RELOCATOR_VARIABLE(size) #ifndef BACKWARD add RCX, RAX #endif - addq $0x3, RCX - shrq $2, RCX + add $0x3, RCX + shr $2, RCX #ifdef BACKWARD /* Backward movsl is implicitly off-by-four. compensate that. */ - subq $4, RSI - subq $4, RDI + sub $4, RSI + sub $4, RDI /* Backward copy. */ std @@ -129,27 +127,27 @@ RELOCATOR_VARIABLE(size) /* %rax contains now our new 'base'. */ mov RAX, RSI - add $(cont0 - base), RAXA + add $(L_cont0 - L_base), RAX jmp *RAX -cont0: - lea (cont1 - base) (RSIA, 1), RAXA - movl %eax, (jump_vector - base) (RSIA, 1) +L_cont0: + lea (L_cont1 - L_base) (RSI, 1), RAX + movl %eax, (L_jump_vector - L_base) (RSI, 1) - lea (gdt - base) (RSIA, 1), RAXA - mov RAXA, (gdt_addr - base) (RSIA, 1) + lea (L_gdt - L_base) (RSI, 1), RAX + mov RAX, (L_gdt_addr - L_base) (RSI, 1) /* Switch to compatibility mode. */ - lgdt (gdtdesc - base) (RSIA, 1) + lgdt (L_gdtdesc - L_base) (RSI, 1) /* Update %cs. Thanks to David Miller for pointing this mistake out. */ - ljmp *(jump_vector - base) (RSIA, 1) + ljmp *(L_jump_vector - L_base) (RSI, 1) -cont1: +L_cont1: .code32 /* Update other registers. */ - movl $GRUB_MEMORY_MACHINE_PROT_MODE_DSEG, %eax + movl $DATA_SEGMENT, %eax movl %eax, %ds movl %eax, %es movl %eax, %fs @@ -158,22 +156,22 @@ cont1: /* Disable paging. */ movl %cr0, %eax - andl $0x7fffffff, %eax + andl $(~GRUB_MEMORY_CPU_CR0_PAGING_ON), %eax movl %eax, %cr0 /* Disable amd64. */ - movl $0xc0000080, %ecx + movl $GRUB_MEMORY_CPU_AMD64_MSR, %ecx rdmsr - andl $0xfffffeff, %eax + andl $(~GRUB_MEMORY_CPU_AMD64_MSR_ON), %eax wrmsr /* Turn off PAE. */ movl %cr4, %eax - andl $0xffffffcf, %eax + andl $GRUB_MEMORY_CPU_CR4_PAE_ON, %eax movl %eax, %cr4 - jmp cont2 -cont2: + jmp L_cont2 +L_cont2: .code32 /* mov imm32, %eax */ @@ -212,44 +210,25 @@ RELOCATOR_VARIABLE (eip) .long 0 .word 0x08 - /* GDT. The same as is used in 32-bit GRUB. */ + /* GDT. Copied from loader/i386/linux.c. */ .p2align 4 -gdt: - .word 0, 0 - .byte 0, 0, 0, 0 +L_gdt: + /* NULL. */ + .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + + /* Reserved. */ + .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - /* -- code segment -- - * base = 0x00000000, limit = 0xFFFFF (4 KiB Granularity), present - * type = 32bit code execute/read, DPL = 0 - */ - .word 0xFFFF, 0 - .byte 0, 0x9A, 0xCF, 0 + /* Code segment. */ + .byte 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x9A, 0xCF, 0x00 - /* -- data segment -- - * base = 0x00000000, limit 0xFFFFF (4 KiB Granularity), present - * type = 32 bit data read/write, DPL = 0 - */ - .word 0xFFFF, 0 - .byte 0, 0x92, 0xCF, 0 - - /* -- 16 bit real mode CS -- - * base = 0x00000000, limit 0x0FFFF (1 B Granularity), present - * type = 16 bit code execute/read only/conforming, DPL = 0 - */ - .word 0xFFFF, 0 - .byte 0, 0x9E, 0, 0 - - /* -- 16 bit real mode DS -- - * base = 0x00000000, limit 0x0FFFF (1 B Granularity), present - * type = 16 bit data read/write, DPL = 0 - */ - .word 0xFFFF, 0 - .byte 0, 0x92, 0, 0 + /* Data segment. */ + .byte 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x92, 0xCF, 0x00 .p2align 4 -gdtdesc: +L_gdtdesc: .word 0x27 -gdt_addr: +L_gdt_addr: #ifdef __x86_64__ /* Filled by the code. */ .quad 0 @@ -259,13 +238,13 @@ gdt_addr: #endif .p2align 4 -jump_vector: +L_jump_vector: /* Jump location. Is filled by the code */ .long 0 - .long GRUB_MEMORY_MACHINE_PROT_MODE_CSEG + .long CODE_SEGMENT #ifndef BACKWARD -base: +L_base: #endif RELOCATOR_VARIABLE(end) From e27fbc80e4c7bbd6a75dd609446448c77915620b Mon Sep 17 00:00:00 2001 From: phcoder Date: Fri, 9 Oct 2009 19:50:31 +0200 Subject: [PATCH 008/738] kernel.img compiles on mipsel-qemu-r4k --- conf/mips.rmk | 125 +++++++++++++++++++++++++ conf/mipsel-qemu-r4k.rmk | 4 + configure.ac | 1 + include/grub/mipsel/kernel.h | 32 +++++++ include/grub/mipsel/qemu-r4k/kernel.h | 35 +++++++ include/grub/mipsel/qemu-r4k/machine.h | 24 +++++ include/grub/mipsel/qemu-r4k/memory.h | 35 +++++++ include/grub/mipsel/qemu-r4k/time.h | 34 +++++++ include/grub/mipsel/time.h | 0 include/grub/mipsel/types.h | 31 ++++++ kern/mipsel/cache.S | 5 + kern/mipsel/dl.c | 109 +++++++++++++++++++++ kern/mipsel/qemu-r4k/init.c | 58 ++++++++++++ kern/mipsel/qemu-r4k/startup.S | 55 +++++++++++ lib/mipsel/setjmp.S | 0 15 files changed, 548 insertions(+) create mode 100644 conf/mips.rmk create mode 100644 conf/mipsel-qemu-r4k.rmk create mode 100644 include/grub/mipsel/kernel.h create mode 100644 include/grub/mipsel/qemu-r4k/kernel.h create mode 100644 include/grub/mipsel/qemu-r4k/machine.h create mode 100644 include/grub/mipsel/qemu-r4k/memory.h create mode 100644 include/grub/mipsel/qemu-r4k/time.h create mode 100644 include/grub/mipsel/time.h create mode 100644 include/grub/mipsel/types.h create mode 100644 kern/mipsel/cache.S create mode 100644 kern/mipsel/dl.c create mode 100644 kern/mipsel/qemu-r4k/init.c create mode 100644 kern/mipsel/qemu-r4k/startup.S create mode 100644 lib/mipsel/setjmp.S diff --git a/conf/mips.rmk b/conf/mips.rmk new file mode 100644 index 000000000..6d8df9e4e --- /dev/null +++ b/conf/mips.rmk @@ -0,0 +1,125 @@ + +# -*- makefile -*- + +COMMON_ASFLAGS = -nostdinc +COMMON_CFLAGS = +COMMON_LDFLAGS += -nostdlib + +# Used by various components. These rules need to precede them. +script/sh/lexer.c_DEPENDENCIES = grub_script.tab.h + +# Images. + +MOSTLYCLEANFILES += symlist.c kernel_syms.lst +DEFSYMFILES += kernel_syms.lst + +kernel_img_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ + env.h err.h file.h fs.h kernel.h misc.h mm.h net.h parser.h reader.h \ + symbol.h term.h time.h types.h loader.h partition.h \ + msdos_partition.h machine/kernel.h handler.h list.h \ + command.h + +symlist.c: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h gensymlist.sh + /bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) + +kernel_syms.lst: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h genkernsyms.sh + /bin/sh genkernsyms.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) + +# Programs +pkglib_PROGRAMS = kernel.img + +# Utilities. +sbin_UTILITIES = grub-mkdevicemap +ifeq ($(enable_grub_emu), yes) +sbin_UTILITIES += grub-emu +endif + +# For grub-mkdevicemap. +grub_mkdevicemap_SOURCES = util/grub-mkdevicemap.c util/deviceiter.c \ + util/devicemap.c util/misc.c + +# For grub-emu +util/grub-emu.c_DEPENDENCIES = grub_emu_init.h +grub_emu_SOURCES = commands/minicmd.c commands/cat.c commands/cmp.c \ + commands/configfile.c commands/help.c \ + commands/search.c commands/handler.c commands/test.c \ + commands/ls.c commands/blocklist.c commands/hexdump.c \ + lib/hexdump.c commands/reboot.c \ + lib/envblk.c commands/loadenv.c \ + commands/gptsync.c commands/probe.c commands/xnu_uuid.c \ + commands/password.c commands/keystatus.c \ + disk/loopback.c \ + \ + fs/affs.c fs/cpio.c fs/fat.c fs/ext2.c fs/hfs.c \ + fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \ + fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c \ + fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/afs_be.c \ + fs/befs.c fs/befs_be.c fs/tar.c \ + \ + io/gzio.c \ + kern/device.c kern/disk.c kern/dl.c kern/elf.c kern/env.c \ + kern/err.c kern/file.c kern/fs.c commands/boot.c kern/main.c \ + kern/misc.c kern/parser.c kern/partition.c kern/reader.c \ + kern/rescue_reader.c kern/rescue_parser.c \ + kern/term.c kern/list.c kern/handler.c fs/fshelp.c \ + kern/command.c kern/corecmd.c commands/extcmd.c \ + lib/arg.c normal/cmdline.c normal/datetime.c \ + normal/completion.c normal/misc.c \ + normal/handler.c normal/auth.c normal/autofs.c normal/main.c \ + normal/menu.c \ + normal/menu_text.c \ + normal/menu_entry.c normal/menu_viewer.c \ + normal/color.c \ + script/sh/main.c script/sh/execute.c script/sh/function.c \ + script/sh/lexer.c script/sh/script.c \ + partmap/amiga.c partmap/apple.c partmap/msdos.c partmap/sun.c \ + partmap/acorn.c \ + util/console.c util/hostfs.c util/grub-emu.c util/misc.c \ + util/hostdisk.c util/getroot.c \ + \ + disk/raid.c disk/raid5_recover.c disk/raid6_recover.c \ + disk/mdraid_linux.c disk/dmraid_nvidia.c disk/lvm.c \ + commands/parttool.c parttool/msdospart.c \ + grub_script.tab.c grub_emu_init.c + +grub_emu_LDFLAGS = $(LIBCURSES) + +kernel_img_SOURCES = kern/mipsel/qemu-r4k/startup.S \ + kern/main.c kern/device.c kern/$(target_cpu)/$(target_machine)/init.c \ + kern/disk.c kern/dl.c kern/err.c kern/file.c kern/fs.c \ + kern/misc.c kern/mm.c kern/reader.c kern/term.c \ + kern/rescue_parser.c kern/rescue_reader.c \ + kern/list.c kern/handler.c kern/command.c kern/corecmd.c \ + kern/parser.c kern/partition.c kern/env.c kern/$(target_cpu)/dl.c \ + kern/generic/millisleep.c kern/time.c \ + symlist.c kern/$(target_cpu)/cache.S +kernel_img_CFLAGS = $(COMMON_CFLAGS) +kernel_img_ASFLAGS = $(COMMON_ASFLAGS) +kernel_img_LDFLAGS = $(COMMON_LDFLAGS) -static-libgcc -lgcc \ + -Wl,-N,-S,-Ttext,$(LINK_BASE),-Bstatic + +# Scripts. +sbin_SCRIPTS = grub-install +bin_SCRIPTS = grub-mkrescue + +# Modules. +pkglib_MODULES = memdisk.mod \ + lsmmap.mod + +# For boot.mod. +pkglib_MODULES += boot.mod +boot_mod_SOURCES = commands/boot.c lib/i386/pc/biosnum.c +boot_mod_CFLAGS = $(COMMON_CFLAGS) +boot_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For memdisk.mod. +memdisk_mod_SOURCES = disk/memdisk.c +memdisk_mod_CFLAGS = $(COMMON_CFLAGS) +memdisk_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For lsmmap.mod +lsmmap_mod_SOURCES = commands/lsmmap.c +lsmmap_mod_CFLAGS = $(COMMON_CFLAGS) +lsmmap_mod_LDFLAGS = $(COMMON_LDFLAGS) + +include $(srcdir)/conf/common.mk diff --git a/conf/mipsel-qemu-r4k.rmk b/conf/mipsel-qemu-r4k.rmk new file mode 100644 index 000000000..3ff36c472 --- /dev/null +++ b/conf/mipsel-qemu-r4k.rmk @@ -0,0 +1,4 @@ +# -*- makefile -*- +LINK_BASE = 0x80010000 +target_machine=qemu-r4k +include $(srcdir)/conf/mips.mk diff --git a/configure.ac b/configure.ac index 3e4da66c8..74dcc5dd4 100644 --- a/configure.ac +++ b/configure.ac @@ -89,6 +89,7 @@ case "$target_cpu"-"$platform" in i386-qemu) ;; powerpc-ieee1275) ;; sparc64-ieee1275) ;; + mipsel-qemu-r4k) ;; *) AC_MSG_ERROR([platform "$platform" is not supported for target CPU "$target_cpu"]) ;; esac diff --git a/include/grub/mipsel/kernel.h b/include/grub/mipsel/kernel.h new file mode 100644 index 000000000..326f1244d --- /dev/null +++ b/include/grub/mipsel/kernel.h @@ -0,0 +1,32 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_KERNEL_CPU_HEADER +#define GRUB_KERNEL_CPU_HEADER 1 + +#define GRUB_MOD_ALIGN 0x1000 + +/* Minimal gap between _end and the start of the modules. It's a hack + for PowerMac to prevent "CLAIM failed" error. The real fix is to + rewrite grub-mkimage to generate valid ELF files. */ +#define GRUB_MOD_GAP 0x8000 + +#define GRUB_KERNEL_CPU_PREFIX 0x8 +#define GRUB_KERNEL_CPU_DATA_END 0x48 + +#endif diff --git a/include/grub/mipsel/qemu-r4k/kernel.h b/include/grub/mipsel/qemu-r4k/kernel.h new file mode 100644 index 000000000..6a10f2df1 --- /dev/null +++ b/include/grub/mipsel/qemu-r4k/kernel.h @@ -0,0 +1,35 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2006,2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_KERNEL_MACHINE_HEADER +#define GRUB_KERNEL_MACHINE_HEADER 1 + +#include + +#ifndef ASM_FILE + +void EXPORT_FUNC (grub_reboot) (void); +void EXPORT_FUNC (grub_halt) (void); + +/* The prefix which points to the directory where GRUB modules and its + configuration file are located. */ +extern char grub_prefix[]; + +#endif + +#endif /* ! GRUB_KERNEL_MACHINE_HEADER */ diff --git a/include/grub/mipsel/qemu-r4k/machine.h b/include/grub/mipsel/qemu-r4k/machine.h new file mode 100644 index 000000000..9bad5dca9 --- /dev/null +++ b/include/grub/mipsel/qemu-r4k/machine.h @@ -0,0 +1,24 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2007 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_MACHINE_MACHINE_HEADER +#define GRUB_MACHINE_MACHINE_HEADER 1 + +#define GRUB_MACHINE_MIPS_QEMU 1 + +#endif /* ! GRUB_MACHINE_MACHINE_HEADER */ diff --git a/include/grub/mipsel/qemu-r4k/memory.h b/include/grub/mipsel/qemu-r4k/memory.h new file mode 100644 index 000000000..6021bab04 --- /dev/null +++ b/include/grub/mipsel/qemu-r4k/memory.h @@ -0,0 +1,35 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_MEMORY_MACHINE_HEADER +#define GRUB_MEMORY_MACHINE_HEADER 1 + +#ifndef ASM_FILE +#include +#include +#include +#endif + +#define GRUB_MACHINE_MEMORY_STACK_HIGH 0x81000000 + +#ifndef ASM_FILE +grub_err_t EXPORT_FUNC (grub_machine_mmap_iterate) +(int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t)); +#endif + +#endif diff --git a/include/grub/mipsel/qemu-r4k/time.h b/include/grub/mipsel/qemu-r4k/time.h new file mode 100644 index 000000000..a73f64dea --- /dev/null +++ b/include/grub/mipsel/qemu-r4k/time.h @@ -0,0 +1,34 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2004,2005,2007 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef KERNEL_MACHINE_TIME_HEADER +#define KERNEL_MACHINE_TIME_HEADER 1 + +#include + +#define GRUB_TICKS_PER_SECOND 1000 + +/* Return the real time in ticks. */ +grub_uint32_t EXPORT_FUNC (grub_get_rtc) (void); + +static inline void +grub_cpu_idle(void) +{ +} + +#endif /* ! KERNEL_MACHINE_TIME_HEADER */ diff --git a/include/grub/mipsel/time.h b/include/grub/mipsel/time.h new file mode 100644 index 000000000..e69de29bb diff --git a/include/grub/mipsel/types.h b/include/grub/mipsel/types.h new file mode 100644 index 000000000..94a35be6e --- /dev/null +++ b/include/grub/mipsel/types.h @@ -0,0 +1,31 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2006,2007,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_TYPES_CPU_HEADER +#define GRUB_TYPES_CPU_HEADER 1 + +/* The size of void *. */ +#define GRUB_TARGET_SIZEOF_VOID_P 4 + +/* The size of long. */ +#define GRUB_TARGET_SIZEOF_LONG 4 + +/* mipsEL is little-endian. */ +#undef GRUB_TARGET_WORDS_BIGENDIAN + +#endif /* ! GRUB_TYPES_CPU_HEADER */ diff --git a/kern/mipsel/cache.S b/kern/mipsel/cache.S new file mode 100644 index 000000000..5341f07a2 --- /dev/null +++ b/kern/mipsel/cache.S @@ -0,0 +1,5 @@ +#include + +FUNCTION (grub_arch_sync_caches) +FUNCTION (_flush_cache) + j $31 diff --git a/kern/mipsel/dl.c b/kern/mipsel/dl.c new file mode 100644 index 000000000..57854964b --- /dev/null +++ b/kern/mipsel/dl.c @@ -0,0 +1,109 @@ +/* dl-386.c - arch-dependent part of loadable module support */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2005,2007,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include + +/* Check if EHDR is a valid ELF header. */ +grub_err_t +grub_arch_dl_check_header (void *ehdr) +{ + Elf_Ehdr *e = ehdr; + + /* Check the magic numbers. */ + if (e->e_ident[EI_CLASS] != ELFCLASS32 + || e->e_ident[EI_DATA] != ELFDATA2LSB + || e->e_machine != EM_386) + return grub_error (GRUB_ERR_BAD_OS, "invalid arch specific ELF magic"); + + return GRUB_ERR_NONE; +} + +/* Relocate symbols. */ +grub_err_t +grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) +{ + Elf_Ehdr *e = ehdr; + Elf_Shdr *s; + Elf_Word entsize; + unsigned i; + + /* Find a symbol table. */ + 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_SYMTAB) + break; + + if (i == e->e_shnum) + return grub_error (GRUB_ERR_BAD_MODULE, "no symtab found"); + + 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++) + { + Elf_Word *addr; + Elf_Sym *sym; + + if (seg->size < rel->r_offset) + return grub_error (GRUB_ERR_BAD_MODULE, + "reloc offset is out of the segment"); + + addr = (Elf_Word *) ((char *) seg->addr + rel->r_offset); + sym = (Elf_Sym *) ((char *) mod->symtab + + entsize * ELF_R_SYM (rel->r_info)); + + switch (ELF_R_TYPE (rel->r_info)) + { + case R_386_32: + *addr += sym->st_value; + break; + + case R_386_PC32: + *addr += (sym->st_value - (Elf_Word) seg->addr + - rel->r_offset); + break; + } + } + } + } + + return GRUB_ERR_NONE; +} diff --git a/kern/mipsel/qemu-r4k/init.c b/kern/mipsel/qemu-r4k/init.c new file mode 100644 index 000000000..0600a345f --- /dev/null +++ b/kern/mipsel/qemu-r4k/init.c @@ -0,0 +1,58 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +grub_uint32_t +grub_get_rtc (void) +{ + static int calln = 0; + return calln++; +} + +void +grub_machine_init (void) +{ +} + +void +grub_machine_fini (void) +{ +} + +void +grub_exit (void) +{ + while (1); +} + +void +grub_halt (void) +{ + while (1); +} + +void +grub_reboot (void) +{ + while (1); +} + +void +grub_machine_set_prefix (void) +{ + grub_env_set ("prefix", grub_prefix); +} + +extern char _start[]; +extern char _end[]; + +grub_addr_t +grub_arch_modules_addr (void) +{ + return ALIGN_UP((grub_addr_t) _end + GRUB_MOD_GAP, GRUB_MOD_ALIGN); +} diff --git a/kern/mipsel/qemu-r4k/startup.S b/kern/mipsel/qemu-r4k/startup.S new file mode 100644 index 000000000..19de4779d --- /dev/null +++ b/kern/mipsel/qemu-r4k/startup.S @@ -0,0 +1,55 @@ +/* startup.S - Startup code for the MIPS. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include + +.extern __bss_start +.extern _end + + .globl __start, _start, start +__start: +_start: +start: + b codestart + . = _start + GRUB_KERNEL_CPU_PREFIX + +VARIABLE(grub_prefix) + /* to be filled by grub-mkelfimage */ + + /* + * Leave some breathing room for the prefix. + */ + + . = _start + GRUB_KERNEL_CPU_DATA_END +codestart: + lui $t1, %hi(__bss_start) + addiu $t1, %lo(__bss_start) + lui $t2, %hi(_end) + addiu $t2, %lo(_end) + +bsscont: + sb $0,0($t1) + addiu $t1,$t1,1 + sltu $t3,$t1,$t2 + bne $3, $0, bsscont + + li $sp, GRUB_MACHINE_MEMORY_STACK_HIGH + b grub_main \ No newline at end of file diff --git a/lib/mipsel/setjmp.S b/lib/mipsel/setjmp.S new file mode 100644 index 000000000..e69de29bb From de75aa3d67a83ce74cac4aa74e47f9affb1489a6 Mon Sep 17 00:00:00 2001 From: phcoder Date: Sat, 10 Oct 2009 13:30:14 +0200 Subject: [PATCH 009/738] Hello from mipsel --- conf/mips.rmk | 8 ++++---- genmoddep.awk | 2 +- include/grub/mipsel/qemu-r4k/memory.h | 18 ++++++++++++++++++ kern/main.c | 16 ++++++++++++++++ kern/mipsel/cache.S | 2 +- kern/mipsel/qemu-r4k/init.c | 16 ++++++++++++++++ kern/misc.c | 2 +- kern/term.c | 14 +++++++++----- 8 files changed, 66 insertions(+), 12 deletions(-) diff --git a/conf/mips.rmk b/conf/mips.rmk index 6d8df9e4e..ad0219b06 100644 --- a/conf/mips.rmk +++ b/conf/mips.rmk @@ -2,7 +2,7 @@ # -*- makefile -*- COMMON_ASFLAGS = -nostdinc -COMMON_CFLAGS = +COMMON_CFLAGS = -mexplicit-relocs -mflush-func=grub_cpu_flush_cache COMMON_LDFLAGS += -nostdlib # Used by various components. These rules need to precede them. @@ -17,7 +17,7 @@ kernel_img_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ env.h err.h file.h fs.h kernel.h misc.h mm.h net.h parser.h reader.h \ symbol.h term.h time.h types.h loader.h partition.h \ msdos_partition.h machine/kernel.h handler.h list.h \ - command.h + command.h machine/memory.h cpu/libgcc.h cpu/cache.h symlist.c: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h gensymlist.sh /bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) @@ -99,8 +99,8 @@ kernel_img_LDFLAGS = $(COMMON_LDFLAGS) -static-libgcc -lgcc \ -Wl,-N,-S,-Ttext,$(LINK_BASE),-Bstatic # Scripts. -sbin_SCRIPTS = grub-install -bin_SCRIPTS = grub-mkrescue +sbin_SCRIPTS = +bin_SCRIPTS = # Modules. pkglib_MODULES = memdisk.mod \ diff --git a/genmoddep.awk b/genmoddep.awk index f7f085e99..af967ec07 100644 --- a/genmoddep.awk +++ b/genmoddep.awk @@ -29,7 +29,7 @@ FNR == 1 { if ($1 in symtab) { modtab[module] = modtab[module] " " symtab[$1]; } - else { + else if ($1 != "__gnu_local_gp"){ printf "%s in %s is not defined\n", $1, module >"/dev/stderr"; error++; exit; diff --git a/include/grub/mipsel/qemu-r4k/memory.h b/include/grub/mipsel/qemu-r4k/memory.h index 6021bab04..21f295b67 100644 --- a/include/grub/mipsel/qemu-r4k/memory.h +++ b/include/grub/mipsel/qemu-r4k/memory.h @@ -27,9 +27,27 @@ #define GRUB_MACHINE_MEMORY_STACK_HIGH 0x81000000 +#define GRUB_MACHINE_MEMORY_AVAILABLE 1 + #ifndef ASM_FILE grub_err_t EXPORT_FUNC (grub_machine_mmap_iterate) (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t)); +grub_err_t EXPORT_FUNC(grub_machine_mmap_iterate) + (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t)); + +static inline grub_err_t +grub_machine_mmap_register (grub_uint64_t start __attribute__ ((unused)), + grub_uint64_t size __attribute__ ((unused)), + int type __attribute__ ((unused)), + int handle __attribute__ ((unused))) +{ + return GRUB_ERR_NONE; +} +static inline grub_err_t +grub_machine_mmap_unregister (int handle __attribute__ ((unused))) +{ + return GRUB_ERR_NONE; +} #endif #endif diff --git a/kern/main.c b/kern/main.c index 9215d55e7..222897d7d 100644 --- a/kern/main.c +++ b/kern/main.c @@ -149,29 +149,45 @@ grub_load_normal_mode (void) void grub_main (void) { + *((grub_uint8_t *)0x140003f8) = '1'; + /* First of all, initialize the machine. */ grub_machine_init (); + *((grub_uint8_t *)0x140003f8) = '2'; + /* Hello. */ grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT); + *((grub_uint8_t *)0x140003f8) = 'a'; grub_printf ("Welcome to GRUB!\n\n"); + *((grub_uint8_t *)0x140003f8) = 'b'; grub_setcolorstate (GRUB_TERM_COLOR_STANDARD); + *((grub_uint8_t *)0x140003f8) = '3'; + /* Load pre-loaded modules and free the space. */ grub_register_exported_symbols (); grub_load_modules (); + *((grub_uint8_t *)0x140003f8) = '4'; + /* It is better to set the root device as soon as possible, for convenience. */ grub_machine_set_prefix (); grub_env_export ("prefix"); grub_set_root_dev (); + *((grub_uint8_t *)0x140003f8) = '5'; + grub_register_core_commands (); grub_register_rescue_parser (); grub_register_rescue_reader (); + *((grub_uint8_t *)0x140003f8) = '6'; + grub_load_config (); + *((grub_uint8_t *)0x140003f8) = '7'; grub_load_normal_mode (); + *((grub_uint8_t *)0x140003f8) = '8'; grub_reader_loop (0); } diff --git a/kern/mipsel/cache.S b/kern/mipsel/cache.S index 5341f07a2..f613f57f2 100644 --- a/kern/mipsel/cache.S +++ b/kern/mipsel/cache.S @@ -1,5 +1,5 @@ #include FUNCTION (grub_arch_sync_caches) -FUNCTION (_flush_cache) +FUNCTION (grub_cpu_flush_cache) j $31 diff --git a/kern/mipsel/qemu-r4k/init.c b/kern/mipsel/qemu-r4k/init.c index 0600a345f..c4aec14ff 100644 --- a/kern/mipsel/qemu-r4k/init.c +++ b/kern/mipsel/qemu-r4k/init.c @@ -4,9 +4,13 @@ #include #include #include +#include #include +#include #include +#define RAMSIZE (*(grub_uint32_t *) ((16 << 20) - 264)) + grub_uint32_t grub_get_rtc (void) { @@ -17,6 +21,8 @@ grub_get_rtc (void) void grub_machine_init (void) { + grub_mm_init_region ((void *) GRUB_MACHINE_MEMORY_STACK_HIGH, + RAMSIZE - GRUB_MACHINE_MEMORY_STACK_HIGH); } void @@ -56,3 +62,13 @@ grub_arch_modules_addr (void) { return ALIGN_UP((grub_addr_t) _end + GRUB_MOD_GAP, GRUB_MOD_ALIGN); } + +grub_err_t +grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, + grub_uint64_t, + grub_uint32_t)) +{ + hook (0, RAMSIZE, + GRUB_MACHINE_MEMORY_AVAILABLE); + return GRUB_ERR_NONE; +} diff --git a/kern/misc.c b/kern/misc.c index 1c38fe661..ba19705f3 100644 --- a/kern/misc.c +++ b/kern/misc.c @@ -598,7 +598,7 @@ grub_vsprintf (char *str, const char *fmt, va_list args) if (str) *str++ = ch; else - grub_putchar (ch); + grub_putchar (ch); count++; } diff --git a/kern/term.c b/kern/term.c index 94d5a9e1d..22660c6a8 100644 --- a/kern/term.c +++ b/kern/term.c @@ -48,8 +48,9 @@ struct grub_handler_class grub_term_output_class = void grub_putcode (grub_uint32_t code) { - int height = grub_getwh () & 255; + // int height = grub_getwh () & 255; +#if 0 if (code == '\t' && grub_cur_term_output->getxy) { int n; @@ -60,13 +61,15 @@ grub_putcode (grub_uint32_t code) return; } +#endif - (grub_cur_term_output->putchar) (code); + // (grub_cur_term_output->putchar) (code); + *((grub_uint8_t *)0x140003f8) = code; if (code == '\n') { grub_putcode ('\r'); - +#if 0 grub_more_lines++; if (grub_more && grub_more_lines == height - 1) @@ -93,6 +96,7 @@ grub_putcode (grub_uint32_t code) else grub_more_lines = 0; } +#endif } } @@ -182,14 +186,14 @@ grub_cls (void) void grub_setcolorstate (grub_term_color_state state) { - if (grub_cur_term_output->setcolorstate) + if (grub_cur_term_output && grub_cur_term_output->setcolorstate) (grub_cur_term_output->setcolorstate) (state); } void grub_setcolor (grub_uint8_t normal_color, grub_uint8_t highlight_color) { - if (grub_cur_term_output->setcolor) + if (grub_cur_term_output && grub_cur_term_output->setcolor) (grub_cur_term_output->setcolor) (normal_color, highlight_color); } From 7dc7e76a56d730f45c8d9e70d44e21e501fe0bb3 Mon Sep 17 00:00:00 2001 From: phcoder Date: Sat, 10 Oct 2009 13:50:10 +0200 Subject: [PATCH 010/738] cleanup and bugfix --- kern/main.c | 16 ---------------- kern/mipsel/qemu-r4k/init.c | 5 ++++- kern/misc.c | 2 +- 3 files changed, 5 insertions(+), 18 deletions(-) diff --git a/kern/main.c b/kern/main.c index 222897d7d..9215d55e7 100644 --- a/kern/main.c +++ b/kern/main.c @@ -149,45 +149,29 @@ grub_load_normal_mode (void) void grub_main (void) { - *((grub_uint8_t *)0x140003f8) = '1'; - /* First of all, initialize the machine. */ grub_machine_init (); - *((grub_uint8_t *)0x140003f8) = '2'; - /* Hello. */ grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT); - *((grub_uint8_t *)0x140003f8) = 'a'; grub_printf ("Welcome to GRUB!\n\n"); - *((grub_uint8_t *)0x140003f8) = 'b'; grub_setcolorstate (GRUB_TERM_COLOR_STANDARD); - *((grub_uint8_t *)0x140003f8) = '3'; - /* Load pre-loaded modules and free the space. */ grub_register_exported_symbols (); grub_load_modules (); - *((grub_uint8_t *)0x140003f8) = '4'; - /* It is better to set the root device as soon as possible, for convenience. */ grub_machine_set_prefix (); grub_env_export ("prefix"); grub_set_root_dev (); - *((grub_uint8_t *)0x140003f8) = '5'; - grub_register_core_commands (); grub_register_rescue_parser (); grub_register_rescue_reader (); - *((grub_uint8_t *)0x140003f8) = '6'; - grub_load_config (); - *((grub_uint8_t *)0x140003f8) = '7'; grub_load_normal_mode (); - *((grub_uint8_t *)0x140003f8) = '8'; grub_reader_loop (0); } diff --git a/kern/mipsel/qemu-r4k/init.c b/kern/mipsel/qemu-r4k/init.c index c4aec14ff..269e8b6e6 100644 --- a/kern/mipsel/qemu-r4k/init.c +++ b/kern/mipsel/qemu-r4k/init.c @@ -21,8 +21,11 @@ grub_get_rtc (void) void grub_machine_init (void) { + void *tst; grub_mm_init_region ((void *) GRUB_MACHINE_MEMORY_STACK_HIGH, - RAMSIZE - GRUB_MACHINE_MEMORY_STACK_HIGH); + RAMSIZE - (GRUB_MACHINE_MEMORY_STACK_HIGH & 0x7fffffff)); + tst = grub_malloc (10); + grub_free (tst); } void diff --git a/kern/misc.c b/kern/misc.c index ba19705f3..1c38fe661 100644 --- a/kern/misc.c +++ b/kern/misc.c @@ -598,7 +598,7 @@ grub_vsprintf (char *str, const char *fmt, va_list args) if (str) *str++ = ch; else - grub_putchar (ch); + grub_putchar (ch); count++; } From 33dc6f74d2f5d8d0a38f3c96f883c30e2f5b2aa5 Mon Sep 17 00:00:00 2001 From: phcoder Date: Sat, 10 Oct 2009 14:19:50 +0200 Subject: [PATCH 011/738] bugfixes. Merge MIPS and MIPSel --- conf/mips.rmk | 2 +- configure.ac | 3 +++ include/grub/mips/cache.h | 27 +++++++++++++++++++ include/grub/{mipsel => mips}/kernel.h | 0 include/grub/mips/libgcc.h | 26 ++++++++++++++++++ .../grub/{mipsel => mips}/qemu-r4k/kernel.h | 0 .../grub/{mipsel => mips}/qemu-r4k/machine.h | 0 .../grub/{mipsel => mips}/qemu-r4k/memory.h | 0 include/grub/{mipsel => mips}/qemu-r4k/time.h | 0 include/grub/{mipsel => mips}/time.h | 0 include/grub/{mipsel => mips}/types.h | 7 +++++ kern/{mipsel => mips}/cache.S | 0 kern/{mipsel => mips}/dl.c | 6 +++++ kern/{mipsel => mips}/qemu-r4k/init.c | 0 kern/{mipsel => mips}/qemu-r4k/startup.S | 0 kern/term.c | 11 +++++--- lib/mipsel/setjmp.S | 0 17 files changed, 77 insertions(+), 5 deletions(-) create mode 100644 include/grub/mips/cache.h rename include/grub/{mipsel => mips}/kernel.h (100%) create mode 100644 include/grub/mips/libgcc.h rename include/grub/{mipsel => mips}/qemu-r4k/kernel.h (100%) rename include/grub/{mipsel => mips}/qemu-r4k/machine.h (100%) rename include/grub/{mipsel => mips}/qemu-r4k/memory.h (100%) rename include/grub/{mipsel => mips}/qemu-r4k/time.h (100%) rename include/grub/{mipsel => mips}/time.h (100%) rename include/grub/{mipsel => mips}/types.h (84%) rename kern/{mipsel => mips}/cache.S (100%) rename kern/{mipsel => mips}/dl.c (95%) rename kern/{mipsel => mips}/qemu-r4k/init.c (100%) rename kern/{mipsel => mips}/qemu-r4k/startup.S (100%) delete mode 100644 lib/mipsel/setjmp.S diff --git a/conf/mips.rmk b/conf/mips.rmk index ad0219b06..b0a078197 100644 --- a/conf/mips.rmk +++ b/conf/mips.rmk @@ -84,7 +84,7 @@ grub_emu_SOURCES = commands/minicmd.c commands/cat.c commands/cmp.c \ grub_emu_LDFLAGS = $(LIBCURSES) -kernel_img_SOURCES = kern/mipsel/qemu-r4k/startup.S \ +kernel_img_SOURCES = kern/mips/qemu-r4k/startup.S \ kern/main.c kern/device.c kern/$(target_cpu)/$(target_machine)/init.c \ kern/disk.c kern/dl.c kern/err.c kern/file.c kern/fs.c \ kern/misc.c kern/mm.c kern/reader.c kern/term.c \ diff --git a/configure.ac b/configure.ac index 74dcc5dd4..fa85c29b4 100644 --- a/configure.ac +++ b/configure.ac @@ -90,12 +90,15 @@ case "$target_cpu"-"$platform" in powerpc-ieee1275) ;; sparc64-ieee1275) ;; mipsel-qemu-r4k) ;; + mips-qemu-r4k) ;; *) AC_MSG_ERROR([platform "$platform" is not supported for target CPU "$target_cpu"]) ;; esac case "$target_cpu" in i386 | powerpc) target_m32=1 ;; x86_64 | sparc64) target_m64=1 ;; + mipsel) TARGET_CFLAGS="$TARGET_CFLAGS -DGRUB_CPU_MIPSEL=1"; target_cpu=mips ;; + mips) TARGET_CFLAGS="$TARGET_CFLAGS -DGRUB_CPU_MIPS=1" ;; esac case "$host_os" in diff --git a/include/grub/mips/cache.h b/include/grub/mips/cache.h new file mode 100644 index 000000000..c3470571e --- /dev/null +++ b/include/grub/mips/cache.h @@ -0,0 +1,27 @@ +/* cache.h - Flush the processor's cache. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2004,2007 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_CPU_CACHE_H +#define GRUB_CPU_CACHE_H 1 + +#include +#include + +void EXPORT_FUNC(grub_cpu_flush_cache) (void *start, grub_size_t size, int type); +#endif diff --git a/include/grub/mipsel/kernel.h b/include/grub/mips/kernel.h similarity index 100% rename from include/grub/mipsel/kernel.h rename to include/grub/mips/kernel.h diff --git a/include/grub/mips/libgcc.h b/include/grub/mips/libgcc.h new file mode 100644 index 000000000..a65842522 --- /dev/null +++ b/include/grub/mips/libgcc.h @@ -0,0 +1,26 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2004,2007 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +void *EXPORT_FUNC (memset) (void *s, int c, int n) __attribute__ ((weak)); +void EXPORT_FUNC (__ashldi3) (void) __attribute__ ((weak)); +void EXPORT_FUNC (__ashrdi3) (void) __attribute__ ((weak)); +void EXPORT_FUNC (__lshrdi3) (void) __attribute__ ((weak)); +void EXPORT_FUNC (__trampoline_setup) (void) __attribute__ ((weak)); +void EXPORT_FUNC (__ucmpdi2) (void) __attribute__ ((weak)); +void EXPORT_FUNC (__bswapsi2) (void) __attribute__ ((weak)); +void EXPORT_FUNC (__bswapdi2) (void) __attribute__ ((weak)); diff --git a/include/grub/mipsel/qemu-r4k/kernel.h b/include/grub/mips/qemu-r4k/kernel.h similarity index 100% rename from include/grub/mipsel/qemu-r4k/kernel.h rename to include/grub/mips/qemu-r4k/kernel.h diff --git a/include/grub/mipsel/qemu-r4k/machine.h b/include/grub/mips/qemu-r4k/machine.h similarity index 100% rename from include/grub/mipsel/qemu-r4k/machine.h rename to include/grub/mips/qemu-r4k/machine.h diff --git a/include/grub/mipsel/qemu-r4k/memory.h b/include/grub/mips/qemu-r4k/memory.h similarity index 100% rename from include/grub/mipsel/qemu-r4k/memory.h rename to include/grub/mips/qemu-r4k/memory.h diff --git a/include/grub/mipsel/qemu-r4k/time.h b/include/grub/mips/qemu-r4k/time.h similarity index 100% rename from include/grub/mipsel/qemu-r4k/time.h rename to include/grub/mips/qemu-r4k/time.h diff --git a/include/grub/mipsel/time.h b/include/grub/mips/time.h similarity index 100% rename from include/grub/mipsel/time.h rename to include/grub/mips/time.h diff --git a/include/grub/mipsel/types.h b/include/grub/mips/types.h similarity index 84% rename from include/grub/mipsel/types.h rename to include/grub/mips/types.h index 94a35be6e..f5f4602e4 100644 --- a/include/grub/mipsel/types.h +++ b/include/grub/mips/types.h @@ -25,7 +25,14 @@ /* The size of long. */ #define GRUB_TARGET_SIZEOF_LONG 4 +#ifdef GRUB_CPU_MIPSEL /* mipsEL is little-endian. */ #undef GRUB_TARGET_WORDS_BIGENDIAN +#elif defined (GRUB_CPU_MIPS) +/* mips is big-endian. */ +#define GRUB_TARGET_WORDS_BIGENDIAN +#else +#error Neither GRUB_CPU_MIPS nor GRUB_CPU_MIPSEL is defined +#endif #endif /* ! GRUB_TYPES_CPU_HEADER */ diff --git a/kern/mipsel/cache.S b/kern/mips/cache.S similarity index 100% rename from kern/mipsel/cache.S rename to kern/mips/cache.S diff --git a/kern/mipsel/dl.c b/kern/mips/dl.c similarity index 95% rename from kern/mipsel/dl.c rename to kern/mips/dl.c index 57854964b..ca93893d2 100644 --- a/kern/mipsel/dl.c +++ b/kern/mips/dl.c @@ -92,6 +92,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) switch (ELF_R_TYPE (rel->r_info)) { +#if 0 case R_386_32: *addr += sym->st_value; break; @@ -100,6 +101,11 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) *addr += (sym->st_value - (Elf_Word) seg->addr - rel->r_offset); break; +#endif + default: + grub_printf ("Unknown relocation type %d\n", + ELF_R_TYPE (rel->r_info)); + break } } } diff --git a/kern/mipsel/qemu-r4k/init.c b/kern/mips/qemu-r4k/init.c similarity index 100% rename from kern/mipsel/qemu-r4k/init.c rename to kern/mips/qemu-r4k/init.c diff --git a/kern/mipsel/qemu-r4k/startup.S b/kern/mips/qemu-r4k/startup.S similarity index 100% rename from kern/mipsel/qemu-r4k/startup.S rename to kern/mips/qemu-r4k/startup.S diff --git a/kern/term.c b/kern/term.c index 22660c6a8..0a99ff318 100644 --- a/kern/term.c +++ b/kern/term.c @@ -135,21 +135,24 @@ grub_getcharwidth (grub_uint32_t code) int grub_getkey (void) { - return (grub_cur_term_input->getkey) (); + while (!(*((grub_uint8_t *)0x140003f8+5) & 0x01)); + return *((grub_uint8_t *)0x140003f8); + // return (grub_cur_term_input->getkey) (); } int grub_checkkey (void) { - return (grub_cur_term_input->checkkey) (); + return !!(*((grub_uint8_t *)0x140003f8+5) & 0x01); + //return (grub_cur_term_input->checkkey) (); } int grub_getkeystatus (void) { - if (grub_cur_term_input->getkeystatus) + /* if (grub_cur_term_input->getkeystatus) return (grub_cur_term_input->getkeystatus) (); - else + else*/ return 0; } diff --git a/lib/mipsel/setjmp.S b/lib/mipsel/setjmp.S deleted file mode 100644 index e69de29bb..000000000 From c7f26cf640f5231b30f62d1c50e0b5e91c8492b9 Mon Sep 17 00:00:00 2001 From: phcoder Date: Sat, 10 Oct 2009 14:20:33 +0200 Subject: [PATCH 012/738] missing file --- lib/mips/setjmp.S | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 lib/mips/setjmp.S diff --git a/lib/mips/setjmp.S b/lib/mips/setjmp.S new file mode 100644 index 000000000..e69de29bb From e8b458be456d537500d8d7b0641509f31a70bb74 Mon Sep 17 00:00:00 2001 From: phcoder Date: Sat, 10 Oct 2009 14:27:28 +0200 Subject: [PATCH 013/738] fixes --- conf/{mipsel-qemu-r4k.rmk => mips-qemu-r4k.rmk} | 0 configure.ac | 10 ++++++++-- kern/mips/dl.c | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) rename conf/{mipsel-qemu-r4k.rmk => mips-qemu-r4k.rmk} (100%) diff --git a/conf/mipsel-qemu-r4k.rmk b/conf/mips-qemu-r4k.rmk similarity index 100% rename from conf/mipsel-qemu-r4k.rmk rename to conf/mips-qemu-r4k.rmk diff --git a/configure.ac b/configure.ac index fa85c29b4..97486e421 100644 --- a/configure.ac +++ b/configure.ac @@ -97,8 +97,14 @@ esac case "$target_cpu" in i386 | powerpc) target_m32=1 ;; x86_64 | sparc64) target_m64=1 ;; - mipsel) TARGET_CFLAGS="$TARGET_CFLAGS -DGRUB_CPU_MIPSEL=1"; target_cpu=mips ;; - mips) TARGET_CFLAGS="$TARGET_CFLAGS -DGRUB_CPU_MIPS=1" ;; + mipsel) + TARGET_CFLAGS="$TARGET_CFLAGS -DGRUB_CPU_MIPSEL=1"; + CFLAGS="$CFLAGS -DGRUB_CPU_MIPSEL=1"; + target_cpu=mips ;; + mips) + TARGET_CFLAGS="$TARGET_CFLAGS -DGRUB_CPU_MIPS=1"; + CFLAGS="$CFLAGS -DGRUB_CPU_MIPS=1"; + target_cpu=mips ;; esac case "$host_os" in diff --git a/kern/mips/dl.c b/kern/mips/dl.c index ca93893d2..504bb2ef5 100644 --- a/kern/mips/dl.c +++ b/kern/mips/dl.c @@ -105,7 +105,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) default: grub_printf ("Unknown relocation type %d\n", ELF_R_TYPE (rel->r_info)); - break + break; } } } From 6315da883109d22dcabd3493d9cad38547d780db Mon Sep 17 00:00:00 2001 From: phcoder Date: Sat, 10 Oct 2009 14:54:18 +0200 Subject: [PATCH 014/738] fake __gnu_local_gp --- conf/mips.rmk | 2 +- genmoddep.awk | 2 +- kern/mips/dl.c | 9 ++++++++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/conf/mips.rmk b/conf/mips.rmk index b0a078197..77eaa06cf 100644 --- a/conf/mips.rmk +++ b/conf/mips.rmk @@ -17,7 +17,7 @@ kernel_img_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ env.h err.h file.h fs.h kernel.h misc.h mm.h net.h parser.h reader.h \ symbol.h term.h time.h types.h loader.h partition.h \ msdos_partition.h machine/kernel.h handler.h list.h \ - command.h machine/memory.h cpu/libgcc.h cpu/cache.h + command.h machine/memory.h cpu/libgcc.h cpu/cache.h cpu/dl.h symlist.c: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h gensymlist.sh /bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) diff --git a/genmoddep.awk b/genmoddep.awk index af967ec07..f7f085e99 100644 --- a/genmoddep.awk +++ b/genmoddep.awk @@ -29,7 +29,7 @@ FNR == 1 { if ($1 in symtab) { modtab[module] = modtab[module] " " symtab[$1]; } - else if ($1 != "__gnu_local_gp"){ + else { printf "%s in %s is not defined\n", $1, module >"/dev/stderr"; error++; exit; diff --git a/kern/mips/dl.c b/kern/mips/dl.c index 504bb2ef5..f8b11a3eb 100644 --- a/kern/mips/dl.c +++ b/kern/mips/dl.c @@ -21,6 +21,7 @@ #include #include #include +#include /* Check if EHDR is a valid ELF header. */ grub_err_t @@ -29,9 +30,15 @@ grub_arch_dl_check_header (void *ehdr) Elf_Ehdr *e = ehdr; /* Check the magic numbers. */ +#ifdef WORDS_BIGENDIAN + if (e->e_ident[EI_CLASS] != ELFCLASS32 + || e->e_ident[EI_DATA] != ELFDATA2MSB + || e->e_machine != EM_MIPS) +#else if (e->e_ident[EI_CLASS] != ELFCLASS32 || e->e_ident[EI_DATA] != ELFDATA2LSB - || e->e_machine != EM_386) + || e->e_machine != EM_MIPS) +#endif return grub_error (GRUB_ERR_BAD_OS, "invalid arch specific ELF magic"); return GRUB_ERR_NONE; From 3f9f11b6d2e3ba8d6fac72223ba44c070c86908d Mon Sep 17 00:00:00 2001 From: phcoder Date: Sat, 10 Oct 2009 20:52:15 +0200 Subject: [PATCH 015/738] time & reloc --- kern/disk.c | 3 ++ kern/mips/dl.c | 103 +++++++++++++++++++++++++++++++++++--- kern/mips/qemu-r4k/init.c | 3 +- 3 files changed, 99 insertions(+), 10 deletions(-) diff --git a/kern/disk.c b/kern/disk.c index e463626fb..7fbe2e6a6 100644 --- a/kern/disk.c +++ b/kern/disk.c @@ -267,12 +267,15 @@ grub_disk_open (const char *name) 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) break; else if (grub_errno == GRUB_ERR_UNKNOWN_DEVICE) grub_errno = GRUB_ERR_NONE; else goto fail; + grub_printf ("survived\n"); } if (! dev) diff --git a/kern/mips/dl.c b/kern/mips/dl.c index f8b11a3eb..83af37b75 100644 --- a/kern/mips/dl.c +++ b/kern/mips/dl.c @@ -22,6 +22,8 @@ #include #include #include +#include +#include /* Check if EHDR is a valid ELF header. */ grub_err_t @@ -52,6 +54,9 @@ 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; /* Find a symbol table. */ 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; + 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); i < e->e_shnum; 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); sym = (Elf_Sym *) ((char *) mod->symtab + 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)) { -#if 0 - case R_386_32: - *addr += sym->st_value; + case R_MIPS_HI16: + { + grub_uint32_t value; + + /* Handle partner lo16 relocation. Lower part is + treated as signed. Hence add 0x8000 to compensate. + */ + 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_386_PC32: - *addr += (sym->st_value - (Elf_Word) seg->addr - - rel->r_offset); + 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; -#endif default: grub_printf ("Unknown relocation type %d\n", ELF_R_TYPE (rel->r_info)); diff --git a/kern/mips/qemu-r4k/init.c b/kern/mips/qemu-r4k/init.c index 269e8b6e6..f7d304313 100644 --- a/kern/mips/qemu-r4k/init.c +++ b/kern/mips/qemu-r4k/init.c @@ -24,8 +24,7 @@ grub_machine_init (void) void *tst; grub_mm_init_region ((void *) GRUB_MACHINE_MEMORY_STACK_HIGH, RAMSIZE - (GRUB_MACHINE_MEMORY_STACK_HIGH & 0x7fffffff)); - tst = grub_malloc (10); - grub_free (tst); + grub_install_get_time_ms (grub_rtc_get_time_ms); } void From f651d13a18ba734b2fa9cf4164217c826f52bf23 Mon Sep 17 00:00:00 2001 From: phcoder Date: Sat, 10 Oct 2009 20:59:18 +0200 Subject: [PATCH 016/738] split serial --- conf/i386-coreboot.rmk | 2 +- conf/i386-ieee1275.rmk | 2 +- conf/i386-pc.rmk | 2 +- include/grub/i386/io.h | 2 ++ include/grub/{i386/pc => }/serial.h | 4 ++-- term/{i386/pc => }/serial.c | 8 ++++---- 6 files changed, 11 insertions(+), 9 deletions(-) rename include/grub/{i386/pc => }/serial.h (96%) rename term/{i386/pc => }/serial.c (98%) diff --git a/conf/i386-coreboot.rmk b/conf/i386-coreboot.rmk index 09ec7787c..59a9ed607 100644 --- a/conf/i386-coreboot.rmk +++ b/conf/i386-coreboot.rmk @@ -187,7 +187,7 @@ halt_mod_CFLAGS = $(COMMON_CFLAGS) halt_mod_LDFLAGS = $(COMMON_LDFLAGS) # For serial.mod. -serial_mod_SOURCES = term/i386/pc/serial.c +serial_mod_SOURCES = term/serial.c serial_mod_CFLAGS = $(COMMON_CFLAGS) serial_mod_LDFLAGS = $(COMMON_LDFLAGS) diff --git a/conf/i386-ieee1275.rmk b/conf/i386-ieee1275.rmk index 4b640de49..48c3ce9d9 100644 --- a/conf/i386-ieee1275.rmk +++ b/conf/i386-ieee1275.rmk @@ -156,7 +156,7 @@ halt_mod_CFLAGS = $(COMMON_CFLAGS) halt_mod_LDFLAGS = $(COMMON_LDFLAGS) # For serial.mod. -serial_mod_SOURCES = term/i386/pc/serial.c +serial_mod_SOURCES = term/serial.c serial_mod_CFLAGS = $(COMMON_CFLAGS) serial_mod_LDFLAGS = $(COMMON_LDFLAGS) diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk index bf8fbfb9d..c4a4e7754 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -260,7 +260,7 @@ halt_mod_CFLAGS = $(COMMON_CFLAGS) halt_mod_LDFLAGS = $(COMMON_LDFLAGS) # For serial.mod. -serial_mod_SOURCES = term/i386/pc/serial.c +serial_mod_SOURCES = term/serial.c serial_mod_CFLAGS = $(COMMON_CFLAGS) serial_mod_LDFLAGS = $(COMMON_LDFLAGS) diff --git a/include/grub/i386/io.h b/include/grub/i386/io.h index 0e567766b..ae12a3e3d 100644 --- a/include/grub/i386/io.h +++ b/include/grub/i386/io.h @@ -21,6 +21,8 @@ #ifndef GRUB_IO_H #define GRUB_IO_H 1 +typedef unsigned short int grub_port_t; + static __inline unsigned char grub_inb (unsigned short int port) { diff --git a/include/grub/i386/pc/serial.h b/include/grub/serial.h similarity index 96% rename from include/grub/i386/pc/serial.h rename to include/grub/serial.h index 0632ff79d..1c35b4093 100644 --- a/include/grub/i386/pc/serial.h +++ b/include/grub/serial.h @@ -17,8 +17,8 @@ * along with GRUB. If not, see . */ -#ifndef GRUB_SERIAL_MACHINE_HEADER -#define GRUB_SERIAL_MACHINE_HEADER 1 +#ifndef GRUB_SERIAL_HEADER +#define GRUB_SERIAL_HEADER 1 /* Macros. */ diff --git a/term/i386/pc/serial.c b/term/serial.c similarity index 98% rename from term/i386/pc/serial.c rename to term/serial.c index 1d74dbbc8..eac43bf1b 100644 --- a/term/i386/pc/serial.c +++ b/term/serial.c @@ -54,7 +54,7 @@ static const struct grub_arg_option options[] = /* Serial port settings. */ struct serial_port { - unsigned short port; + grub_port_t port; unsigned short divisor; unsigned short word_len; unsigned int parity; @@ -68,12 +68,12 @@ static struct serial_port serial_settings; static const unsigned short *serial_hw_io_addr = (const unsigned short *) GRUB_MEMORY_MACHINE_BIOS_DATA_AREA_ADDR; #define GRUB_SERIAL_PORT_NUM 4 #else -static const unsigned short serial_hw_io_addr[] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 }; +static const grub_port_t serial_hw_io_addr[] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 }; #define GRUB_SERIAL_PORT_NUM (ARRAY_SIZE(serial_hw_io_addr)) #endif /* Return the port number for the UNITth serial device. */ -static inline unsigned short +static inline grub_port_t serial_hw_get_port (const unsigned int unit) { if (unit < GRUB_SERIAL_PORT_NUM) @@ -503,7 +503,7 @@ grub_cmd_serial (grub_extcmd_t cmd, } if (state[1].set) - serial_settings.port = (unsigned short) grub_strtoul (state[1].arg, 0, 0); + serial_settings.port = (grub_port_t) grub_strtoul (state[1].arg, 0, 0); if (state[2].set) { From 65e64ea4b15c88c53f31d6d3e22a912ff7001174 Mon Sep 17 00:00:00 2001 From: phcoder Date: Sat, 10 Oct 2009 21:23:51 +0200 Subject: [PATCH 017/738] mkimage fix --- util/elf/grub-mkimage.c | 42 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 37 insertions(+), 5 deletions(-) diff --git a/util/elf/grub-mkimage.c b/util/elf/grub-mkimage.c index 535427208..ea5a1f64e 100644 --- a/util/elf/grub-mkimage.c +++ b/util/elf/grub-mkimage.c @@ -97,7 +97,7 @@ load_note (Elf32_Phdr *phdr, FILE *out) void load_modules (grub_addr_t modbase, Elf32_Phdr *phdr, const char *dir, - char *mods[], FILE *out, char *memdisk_path) + char *mods[], FILE *out, char *memdisk_path, char *config_path) { char *module_img; struct grub_util_path_list *path_list; @@ -106,6 +106,7 @@ load_modules (grub_addr_t modbase, Elf32_Phdr *phdr, const char *dir, size_t offset; size_t total_module_size; size_t memdisk_size = 0; + size_t config_size = 0; path_list = grub_util_resolve_dependencies (dir, "moddep.lst", mods); @@ -119,6 +120,13 @@ load_modules (grub_addr_t modbase, Elf32_Phdr *phdr, const char *dir, total_module_size += memdisk_size + sizeof (struct grub_module_header); } + if (config_path) + { + config_size = ALIGN_UP(grub_util_get_image_size (config_path), 512); + grub_util_info ("the size of memory disk is 0x%x", config_size); + total_module_size += config_size + sizeof (struct grub_module_header); + } + for (p = path_list; p; p = p->next) { total_module_size += (grub_util_get_image_size (p->name) @@ -165,6 +173,19 @@ load_modules (grub_addr_t modbase, Elf32_Phdr *phdr, const char *dir, offset += memdisk_size; } + if (config_path) + { + struct grub_module_header *header; + + header = (struct grub_module_header *) (module_img + offset); + header->type = OBJ_TYPE_CONFIG; + header->size = grub_host_to_target32 (config_size + sizeof (*header)); + offset += sizeof (*header); + + grub_util_load_image (config_path, module_img + offset); + offset += config_size; + } + /* Write the module data to the new segment. */ grub_util_write_image_at (module_img, total_module_size, @@ -181,7 +202,7 @@ load_modules (grub_addr_t modbase, Elf32_Phdr *phdr, const char *dir, } void -add_segments (char *dir, char *prefix, FILE *out, int chrp, char *mods[], char *memdisk_path) +add_segments (char *dir, char *prefix, FILE *out, int chrp, char *mods[], char *memdisk_path, char *config_path) { Elf32_Ehdr ehdr; Elf32_Phdr *phdrs = NULL; @@ -270,7 +291,7 @@ add_segments (char *dir, char *prefix, FILE *out, int chrp, char *mods[], char * phdr->p_offset = grub_host_to_target32 (ALIGN_UP (grub_util_get_fp_size (out), GRUB_TARGET_SIZEOF_LONG)); - load_modules (modbase, phdr, dir, mods, out, memdisk_path); + load_modules (modbase, phdr, dir, mods, out, memdisk_path, config_path); } if (chrp) @@ -313,6 +334,7 @@ static struct option options[] = {"directory", required_argument, 0, 'd'}, {"prefix", required_argument, 0, 'p'}, {"memdisk", required_argument, 0, 'm'}, + {"config", required_argument, 0, 'c'}, {"output", required_argument, 0, 'o'}, {"help", no_argument, 0, 'h'}, {"note", no_argument, 0, 'n'}, @@ -335,6 +357,7 @@ Make a bootable image of GRUB.\n\ -d, --directory=DIR use images and modules under DIR [default=%s]\n\ -p, --prefix=DIR set grub_prefix directory\n\ -m, --memdisk=FILE embed FILE as a memdisk image\n\ + -c, --config=FILE embed FILE as boot config\n\ -o, --output=FILE output a generated image to FILE\n\ -h, --help display this message and exit\n\ -n, --note add NOTE segment for CHRP Open Firmware\n\ @@ -355,13 +378,14 @@ main (int argc, char *argv[]) char *dir = NULL; char *prefix = NULL; char *memdisk = NULL; + char *config = NULL; int chrp = 0; progname = "grub-mkimage"; while (1) { - int c = getopt_long (argc, argv, "d:p:m:o:hVvn", options, 0); + int c = getopt_long (argc, argv, "d:p:m:c:o:hVvn", options, 0); if (c == -1) break; @@ -387,6 +411,13 @@ main (int argc, char *argv[]) prefix = xstrdup ("(memdisk)/boot/grub"); break; + case 'c': + if (config) + free (config); + config = xstrdup (optarg); + + break; + case 'h': usage (0); break; @@ -417,7 +448,8 @@ main (int argc, char *argv[]) if (! fp) grub_util_error ("cannot open %s", output); - add_segments (dir ? : GRUB_LIBDIR, prefix, fp, chrp, argv + optind, memdisk); + add_segments (dir ? : GRUB_LIBDIR, prefix, fp, chrp, argv + optind, memdisk, + config); fclose (fp); From ffa9860a862294ddb821f4bcc74914771e1fa5ab Mon Sep 17 00:00:00 2001 From: phcoder Date: Sun, 11 Oct 2009 02:07:52 +0200 Subject: [PATCH 018/738] various fixes --- conf/mips.rmk | 8 ++++- fs/cpio.c | 9 ++++-- genmk.rb | 2 ++ include/grub/mips/dl.h | 25 ++++++++++++++++ include/grub/mips/io.h | 62 +++++++++++++++++++++++++++++++++++++++ kern/disk.c | 3 -- kern/mips/dl.c | 36 ++++++++++++++++------- kern/mips/qemu-r4k/init.c | 1 + kern/term.c | 58 ++++++++++++++++++++++++------------ term/serial.c | 12 ++++++-- 10 files changed, 177 insertions(+), 39 deletions(-) create mode 100644 include/grub/mips/dl.h create mode 100644 include/grub/mips/io.h diff --git a/conf/mips.rmk b/conf/mips.rmk index 77eaa06cf..d03b5d8f5 100644 --- a/conf/mips.rmk +++ b/conf/mips.rmk @@ -91,7 +91,7 @@ kernel_img_SOURCES = kern/mips/qemu-r4k/startup.S \ kern/rescue_parser.c kern/rescue_reader.c \ kern/list.c kern/handler.c kern/command.c kern/corecmd.c \ kern/parser.c kern/partition.c kern/env.c kern/$(target_cpu)/dl.c \ - kern/generic/millisleep.c kern/time.c \ + kern/generic/millisleep.c kern/generic/rtc_get_time_ms.c kern/time.c \ symlist.c kern/$(target_cpu)/cache.S kernel_img_CFLAGS = $(COMMON_CFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) @@ -122,4 +122,10 @@ lsmmap_mod_SOURCES = commands/lsmmap.c lsmmap_mod_CFLAGS = $(COMMON_CFLAGS) lsmmap_mod_LDFLAGS = $(COMMON_LDFLAGS) +# For serial.mod. +pkglib_MODULES += serial.mod +serial_mod_SOURCES = term/serial.c +serial_mod_CFLAGS = $(COMMON_CFLAGS) +serial_mod_LDFLAGS = $(COMMON_LDFLAGS) + include $(srcdir)/conf/common.mk diff --git a/fs/cpio.c b/fs/cpio.c index 1ec4ebeaf..26218c310 100644 --- a/fs/cpio.c +++ b/fs/cpio.c @@ -280,8 +280,10 @@ grub_cpio_open (grub_file_t file, const char *name) /* Compare NAME and FN by hand in order to cope with duplicate slashes. */ - i = 1; + i = 0; j = 0; + while (name[i] == '/') + i++; while (1) { if (name[i] != fn[j]) @@ -290,13 +292,16 @@ grub_cpio_open (grub_file_t file, const char *name) if (name[i] == '\0') break; - if (name[i] == '/' && name[i+1] == '/') + while (name[i] == '/' && name[i+1] == '/') i++; i++; j++; } + if (name[i] != fn[j]) + goto no_match; + file->data = data; file->size = data->size; grub_free (fn); diff --git a/genmk.rb b/genmk.rb index 50bf88fe1..71b57816f 100644 --- a/genmk.rb +++ b/genmk.rb @@ -319,6 +319,7 @@ MOSTLYCLEANFILES += #{deps_str} #{@name}: $(#{prefix}_DEPENDENCIES) #{objs_str} $(TARGET_CC) -o $@ #{objs_str} $(TARGET_LDFLAGS) $(#{prefix}_LDFLAGS) + $(STRIP) -R .rel.dyn -R .reginfo -R .note -R .comment $@ " + objs.collect_with_index do |obj, i| src = sources[i] @@ -330,6 +331,7 @@ MOSTLYCLEANFILES += #{deps_str} "#{obj}: #{src} $(#{src}_DEPENDENCIES) $(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) #{extra_flags} $(TARGET_#{flag}) $(#{prefix}_#{flag}) -MD -c -o $@ $< + -include #{dep} " diff --git a/include/grub/mips/dl.h b/include/grub/mips/dl.h new file mode 100644 index 000000000..4dbd97ca9 --- /dev/null +++ b/include/grub/mips/dl.h @@ -0,0 +1,25 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_CPU_DL_H +#define GRUB_CPU_DL_H 1 + +/* Dummy __gnu_local_gp. Resolved by linker. */ +char EXPORT_VAR (__gnu_local_gp); + +#endif /* ! GRUB_CPU_DL_H */ diff --git a/include/grub/mips/io.h b/include/grub/mips/io.h new file mode 100644 index 000000000..b86452c0a --- /dev/null +++ b/include/grub/mips/io.h @@ -0,0 +1,62 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_IO_H +#define GRUB_IO_H 1 + +#include + +typedef grub_addr_t grub_port_t; + +static __inline unsigned char +grub_inb (grub_port_t port) +{ + return *(grub_uint8_t *) port; +} + +static __inline unsigned short int +grub_inw (grub_port_t port) +{ + return *(grub_uint16_t *) port; +} + +static __inline unsigned int +grub_inl (grub_port_t port) +{ + return *(grub_uint32_t *) port; +} + +static __inline void +grub_outb (unsigned char value, grub_port_t port) +{ + *(grub_uint8_t *) port = value; +} + +static __inline void +grub_outw (unsigned short int value, grub_port_t port) +{ + *(grub_uint16_t *) port = value; +} + +static __inline void +grub_outl (unsigned int value, grub_port_t port) +{ + *(grub_uint32_t *) port = value; +} + +#endif /* _SYS_IO_H */ diff --git a/kern/disk.c b/kern/disk.c index 7fbe2e6a6..e463626fb 100644 --- a/kern/disk.c +++ b/kern/disk.c @@ -267,15 +267,12 @@ grub_disk_open (const char *name) 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) break; else if (grub_errno == GRUB_ERR_UNKNOWN_DEVICE) grub_errno = GRUB_ERR_NONE; else goto fail; - grub_printf ("survived\n"); } if (! dev) diff --git a/kern/mips/dl.c b/kern/mips/dl.c index 83af37b75..e25ccce3a 100644 --- a/kern/mips/dl.c +++ b/kern/mips/dl.c @@ -57,6 +57,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) grub_size_t gp_size = 0; /* FIXME: suboptimal. */ grub_uint32_t *gp, *gpptr; + grub_uint32_t gp0; /* Find a symbol table. */ for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff); @@ -70,6 +71,18 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) entsize = s->sh_entsize; + /* Find reginfo. */ + 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_MIPS_REGINFO) + break; + + if (i == e->e_shnum) + return grub_error (GRUB_ERR_BAD_MODULE, "no reginfo found"); + + 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)) @@ -107,7 +120,6 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) 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); i < e->e_shnum; @@ -166,8 +178,13 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) *(grub_uint16_t *) addr += (sym->st_value) & 0xffff; break; case R_MIPS_32: - *(grub_uint32_t *) addr = sym->st_value; + *(grub_uint32_t *) addr += sym->st_value; break; + case R_MIPS_GPREL32: + *(grub_uint32_t *) addr = sym->st_value + + *(grub_uint32_t *) addr + gp0 - (grub_uint32_t)gp; + break; + case R_MIPS_26: { grub_uint32_t value; @@ -189,16 +206,13 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) = 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; default: - grub_printf ("Unknown relocation type %d\n", - ELF_R_TYPE (rel->r_info)); + { + grub_free (gp); + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "Unknown relocation type %d\n", + ELF_R_TYPE (rel->r_info)); + } break; } } diff --git a/kern/mips/qemu-r4k/init.c b/kern/mips/qemu-r4k/init.c index f7d304313..085c60bf8 100644 --- a/kern/mips/qemu-r4k/init.c +++ b/kern/mips/qemu-r4k/init.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include diff --git a/kern/term.c b/kern/term.c index 0a99ff318..789e4651b 100644 --- a/kern/term.c +++ b/kern/term.c @@ -48,9 +48,11 @@ struct grub_handler_class grub_term_output_class = void grub_putcode (grub_uint32_t code) { - // int height = grub_getwh () & 255; + int height = grub_getwh () & 255; + + if (!grub_cur_term_output) + return; -#if 0 if (code == '\t' && grub_cur_term_output->getxy) { int n; @@ -61,15 +63,13 @@ grub_putcode (grub_uint32_t code) return; } -#endif - // (grub_cur_term_output->putchar) (code); - *((grub_uint8_t *)0x140003f8) = code; + (grub_cur_term_output->putchar) (code); if (code == '\n') { grub_putcode ('\r'); -#if 0 + grub_more_lines++; if (grub_more && grub_more_lines == height - 1) @@ -96,7 +96,6 @@ grub_putcode (grub_uint32_t code) else grub_more_lines = 0; } -#endif } } @@ -129,54 +128,66 @@ grub_putchar (int c) grub_ssize_t grub_getcharwidth (grub_uint32_t code) { + if (!grub_cur_term_output) + return 1; return (grub_cur_term_output->getcharwidth) (code); } int grub_getkey (void) { - while (!(*((grub_uint8_t *)0x140003f8+5) & 0x01)); - return *((grub_uint8_t *)0x140003f8); - // return (grub_cur_term_input->getkey) (); + int c; + if (!grub_cur_term_input) + return 0; + return (grub_cur_term_input->getkey) (); } int grub_checkkey (void) { - return !!(*((grub_uint8_t *)0x140003f8+5) & 0x01); - //return (grub_cur_term_input->checkkey) (); + if (!grub_cur_term_input) + return 0; + return (grub_cur_term_input->checkkey) (); } int grub_getkeystatus (void) { - /* if (grub_cur_term_input->getkeystatus) + if (grub_cur_term_input && grub_cur_term_input->getkeystatus) return (grub_cur_term_input->getkeystatus) (); - else*/ + else return 0; } grub_uint16_t grub_getxy (void) { + if (!grub_cur_term_output) + return 0; return (grub_cur_term_output->getxy) (); } grub_uint16_t grub_getwh (void) { + if (!grub_cur_term_output) + return (80 << 8) | 25; return (grub_cur_term_output->getwh) (); } void grub_gotoxy (grub_uint8_t x, grub_uint8_t y) { - (grub_cur_term_output->gotoxy) (x, y); + if (grub_cur_term_output && grub_cur_term_output->gotoxy) + (grub_cur_term_output->gotoxy) (x, y); } void grub_cls (void) { + if (!grub_cur_term_output) + return; + if ((grub_cur_term_output->flags & GRUB_TERM_DUMB) || (grub_env_get ("debug"))) { grub_putchar ('\n'); @@ -189,20 +200,29 @@ grub_cls (void) void grub_setcolorstate (grub_term_color_state state) { - if (grub_cur_term_output && grub_cur_term_output->setcolorstate) + if (!grub_cur_term_output) + return; + + if (grub_cur_term_output->setcolorstate) (grub_cur_term_output->setcolorstate) (state); } void grub_setcolor (grub_uint8_t normal_color, grub_uint8_t highlight_color) { - if (grub_cur_term_output && grub_cur_term_output->setcolor) + if (!grub_cur_term_output) + return; + + if (grub_cur_term_output->setcolor) (grub_cur_term_output->setcolor) (normal_color, highlight_color); } void grub_getcolor (grub_uint8_t *normal_color, grub_uint8_t *highlight_color) { + if (!grub_cur_term_output) + return; + if (grub_cur_term_output->getcolor) (grub_cur_term_output->getcolor) (normal_color, highlight_color); } @@ -212,7 +232,7 @@ grub_setcursor (int on) { int ret = cursor_state; - if (grub_cur_term_output->setcursor) + if (grub_cur_term_output && grub_cur_term_output->setcursor) { (grub_cur_term_output->setcursor) (on); cursor_state = on; @@ -230,7 +250,7 @@ grub_getcursor (void) void grub_refresh (void) { - if (grub_cur_term_output->refresh) + if (grub_cur_term_output && grub_cur_term_output->refresh) (grub_cur_term_output->refresh) (); } diff --git a/term/serial.c b/term/serial.c index eac43bf1b..6c2d8ac09 100644 --- a/term/serial.c +++ b/term/serial.c @@ -18,8 +18,8 @@ #include #include -#include -#include +#include +//#include #include #include #include @@ -67,6 +67,9 @@ static struct serial_port serial_settings; #ifdef GRUB_MACHINE_PCBIOS static const unsigned short *serial_hw_io_addr = (const unsigned short *) GRUB_MEMORY_MACHINE_BIOS_DATA_AREA_ADDR; #define GRUB_SERIAL_PORT_NUM 4 +#elif defined (GRUB_MACHINE_MIPS_QEMU) +static const grub_port_t serial_hw_io_addr[] = { 0x140003f8 }; +#define GRUB_SERIAL_PORT_NUM (ARRAY_SIZE(serial_hw_io_addr)) #else static const grub_port_t serial_hw_io_addr[] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 }; #define GRUB_SERIAL_PORT_NUM (ARRAY_SIZE(serial_hw_io_addr)) @@ -149,7 +152,7 @@ serial_translate_key_sequence (void) if (input_buf[0] != '\e' || input_buf[1] != '[') return; - for (i = 0; ARRAY_SIZE (three_code_table); i++) + for (i = 0; i < ARRAY_SIZE (three_code_table); i++) if (three_code_table[i].key == input_buf[2]) { input_buf[0] = three_code_table[i].ascii; @@ -254,6 +257,9 @@ grub_serial_getkey (void) ; c = input_buf[0]; + if (c == 0x7f) + c = GRUB_TERM_BACKSPACE; + grub_memmove (input_buf, input_buf + 1, --npending); return c; From 50739170dbf9cef4df6d73ba4126e962073c7118 Mon Sep 17 00:00:00 2001 From: phcoder Date: Sun, 11 Oct 2009 14:18:58 +0200 Subject: [PATCH 019/738] seems to work now. A lot is still missing though --- include/grub/mips/qemu-r4k/memory.h | 3 ++- include/grub/mips/types.h | 2 +- kern/dl.c | 17 ++++++++--------- kern/mips/qemu-r4k/init.c | 5 ++--- kern/term.c | 1 - term/serial.c | 4 ++-- 6 files changed, 15 insertions(+), 17 deletions(-) diff --git a/include/grub/mips/qemu-r4k/memory.h b/include/grub/mips/qemu-r4k/memory.h index 21f295b67..87e68674e 100644 --- a/include/grub/mips/qemu-r4k/memory.h +++ b/include/grub/mips/qemu-r4k/memory.h @@ -25,7 +25,8 @@ #include #endif -#define GRUB_MACHINE_MEMORY_STACK_HIGH 0x81000000 +#define GRUB_MACHINE_MEMORY_STACK_HIGH 0x80f00000 +#define GRUB_MACHINE_MEMORY_USABLE 0x81000000 #define GRUB_MACHINE_MEMORY_AVAILABLE 1 diff --git a/include/grub/mips/types.h b/include/grub/mips/types.h index f5f4602e4..fe09afa3e 100644 --- a/include/grub/mips/types.h +++ b/include/grub/mips/types.h @@ -31,7 +31,7 @@ #elif defined (GRUB_CPU_MIPS) /* mips is big-endian. */ #define GRUB_TARGET_WORDS_BIGENDIAN -#else +#elif !defined (GRUB_SYMBOL_GENERATOR) #error Neither GRUB_CPU_MIPS nor GRUB_CPU_MIPSEL is defined #endif diff --git a/kern/dl.c b/kern/dl.c index 78ebc1e38..7cc5855bd 100644 --- a/kern/dl.c +++ b/kern/dl.c @@ -342,6 +342,7 @@ grub_dl_resolve_symbols (grub_dl_t mod, Elf_Ehdr *e) switch (type) { case STT_NOTYPE: + case STT_OBJECT: /* Resolve a global symbol. */ if (sym->st_name != 0 && sym->st_shndx == 0) { @@ -351,15 +352,13 @@ grub_dl_resolve_symbols (grub_dl_t mod, Elf_Ehdr *e) "the symbol `%s' not found", name); } else - sym->st_value = 0; - break; - - case STT_OBJECT: - sym->st_value += (Elf_Addr) grub_dl_get_section_addr (mod, - sym->st_shndx); - if (bind != STB_LOCAL) - if (grub_dl_register_symbol (name, (void *) sym->st_value, mod)) - return grub_errno; + { + sym->st_value += (Elf_Addr) grub_dl_get_section_addr (mod, + sym->st_shndx); + if (bind != STB_LOCAL) + if (grub_dl_register_symbol (name, (void *) sym->st_value, mod)) + return grub_errno; + } break; case STT_FUNC: diff --git a/kern/mips/qemu-r4k/init.c b/kern/mips/qemu-r4k/init.c index 085c60bf8..8dfda57c2 100644 --- a/kern/mips/qemu-r4k/init.c +++ b/kern/mips/qemu-r4k/init.c @@ -22,9 +22,8 @@ grub_get_rtc (void) void grub_machine_init (void) { - void *tst; - grub_mm_init_region ((void *) GRUB_MACHINE_MEMORY_STACK_HIGH, - RAMSIZE - (GRUB_MACHINE_MEMORY_STACK_HIGH & 0x7fffffff)); + grub_mm_init_region ((void *) GRUB_MACHINE_MEMORY_USABLE, + RAMSIZE - (GRUB_MACHINE_MEMORY_USABLE & 0x7fffffff)); grub_install_get_time_ms (grub_rtc_get_time_ms); } diff --git a/kern/term.c b/kern/term.c index 789e4651b..0e3595df3 100644 --- a/kern/term.c +++ b/kern/term.c @@ -136,7 +136,6 @@ grub_getcharwidth (grub_uint32_t code) int grub_getkey (void) { - int c; if (!grub_cur_term_input) return 0; return (grub_cur_term_input->getkey) (); diff --git a/term/serial.c b/term/serial.c index 6c2d8ac09..4b6ac981d 100644 --- a/term/serial.c +++ b/term/serial.c @@ -29,7 +29,7 @@ #include #define TEXT_WIDTH 80 -#define TEXT_HEIGHT 25 +#define TEXT_HEIGHT 24 static unsigned int xpos, ypos; static unsigned int keep_track = 1; @@ -370,7 +370,7 @@ grub_serial_putchar (grub_uint32_t c) break; case '\n': - if (ypos < TEXT_HEIGHT) + if (ypos < TEXT_HEIGHT - 1) ypos++; break; From 1540a0840253fc2504ba4d3fb24e8b4882c2ab18 Mon Sep 17 00:00:00 2001 From: phcoder Date: Sun, 11 Oct 2009 18:18:18 +0200 Subject: [PATCH 020/738] various fixes. MIPSsim support --- conf/mips-qemu-mipssim.rmk | 4 ++ conf/mips.rmk | 14 ++++- configure.ac | 2 + disk/ata.c | 5 +- include/grub/ata.h | 4 +- include/grub/mips/libgcc.h | 15 +++-- include/grub/mips/pci.h | 70 ++++++++++++++++++++++ include/grub/mips/qemu-mipssim/kernel.h | 35 +++++++++++ include/grub/mips/qemu-mipssim/machine.h | 24 ++++++++ include/grub/mips/qemu-mipssim/memory.h | 54 +++++++++++++++++ include/grub/mips/qemu-mipssim/time.h | 35 +++++++++++ include/grub/mips/qemu-r4k/machine.h | 2 +- kern/mips/qemu-mipssim/init.c | 76 ++++++++++++++++++++++++ kern/mips/qemu-mipssim/startup.S | 55 +++++++++++++++++ term/serial.c | 5 +- 15 files changed, 385 insertions(+), 15 deletions(-) create mode 100644 conf/mips-qemu-mipssim.rmk create mode 100644 include/grub/mips/pci.h create mode 100644 include/grub/mips/qemu-mipssim/kernel.h create mode 100644 include/grub/mips/qemu-mipssim/machine.h create mode 100644 include/grub/mips/qemu-mipssim/memory.h create mode 100644 include/grub/mips/qemu-mipssim/time.h create mode 100644 kern/mips/qemu-mipssim/init.c create mode 100644 kern/mips/qemu-mipssim/startup.S diff --git a/conf/mips-qemu-mipssim.rmk b/conf/mips-qemu-mipssim.rmk new file mode 100644 index 000000000..9000ae296 --- /dev/null +++ b/conf/mips-qemu-mipssim.rmk @@ -0,0 +1,4 @@ +# -*- makefile -*- +LINK_BASE = 0x80010000 +target_machine=qemu-mipssim +include $(srcdir)/conf/mips.mk diff --git a/conf/mips.rmk b/conf/mips.rmk index d03b5d8f5..6ebd7d665 100644 --- a/conf/mips.rmk +++ b/conf/mips.rmk @@ -84,7 +84,7 @@ grub_emu_SOURCES = commands/minicmd.c commands/cat.c commands/cmp.c \ grub_emu_LDFLAGS = $(LIBCURSES) -kernel_img_SOURCES = kern/mips/qemu-r4k/startup.S \ +kernel_img_SOURCES = kern/$(target_cpu)/$(target_machine)/startup.S \ kern/main.c kern/device.c kern/$(target_cpu)/$(target_machine)/init.c \ kern/disk.c kern/dl.c kern/err.c kern/file.c kern/fs.c \ kern/misc.c kern/mm.c kern/reader.c kern/term.c \ @@ -128,4 +128,16 @@ serial_mod_SOURCES = term/serial.c serial_mod_CFLAGS = $(COMMON_CFLAGS) serial_mod_LDFLAGS = $(COMMON_LDFLAGS) +# For ata.mod. +pkglib_MODULES += ata.mod +ata_mod_SOURCES = disk/ata.c +ata_mod_CFLAGS = $(COMMON_CFLAGS) +ata_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For pci.mod. +pkglib_MODULES += pci.mod +pci_mod_SOURCES = bus/pci.c +pci_mod_CFLAGS = $(COMMON_CFLAGS) +pci_mod_LDFLAGS = $(COMMON_LDFLAGS) + include $(srcdir)/conf/common.mk diff --git a/configure.ac b/configure.ac index 97486e421..98750280e 100644 --- a/configure.ac +++ b/configure.ac @@ -91,6 +91,8 @@ case "$target_cpu"-"$platform" in sparc64-ieee1275) ;; mipsel-qemu-r4k) ;; mips-qemu-r4k) ;; + mipsel-qemu-mipssim) ;; + mips-qemu-mipssim) ;; *) AC_MSG_ERROR([platform "$platform" is not supported for target CPU "$target_cpu"]) ;; esac diff --git a/disk/ata.c b/disk/ata.c index 78d396526..b8ce88df3 100644 --- a/disk/ata.c +++ b/disk/ata.c @@ -24,10 +24,11 @@ #include #include #include +#include /* At the moment, only two IDE ports are supported. */ -static const int grub_ata_ioaddress[] = { 0x1f0, 0x170 }; -static const int grub_ata_ioaddress2[] = { 0x3f6, 0x376 }; +static const grub_port_t grub_ata_ioaddress[] = { 0x1f0, 0x170 }; +static const grub_port_t grub_ata_ioaddress2[] = { 0x3f6, 0x376 }; static struct grub_ata_device *grub_ata_devices; diff --git a/include/grub/ata.h b/include/grub/ata.h index aaa2e147a..940e67102 100644 --- a/include/grub/ata.h +++ b/include/grub/ata.h @@ -98,8 +98,8 @@ struct grub_ata_device /* IO addresses on which the registers for this device can be found. */ - int ioaddress; - int ioaddress2; + grub_port_t ioaddress; + grub_port_t ioaddress2; /* Two devices can be connected to a single cable. Use this field to select device 0 (commonly known as "master") or device 1 diff --git a/include/grub/mips/libgcc.h b/include/grub/mips/libgcc.h index a65842522..a04a8f140 100644 --- a/include/grub/mips/libgcc.h +++ b/include/grub/mips/libgcc.h @@ -16,11 +16,10 @@ * along with GRUB. If not, see . */ -void *EXPORT_FUNC (memset) (void *s, int c, int n) __attribute__ ((weak)); -void EXPORT_FUNC (__ashldi3) (void) __attribute__ ((weak)); -void EXPORT_FUNC (__ashrdi3) (void) __attribute__ ((weak)); -void EXPORT_FUNC (__lshrdi3) (void) __attribute__ ((weak)); -void EXPORT_FUNC (__trampoline_setup) (void) __attribute__ ((weak)); -void EXPORT_FUNC (__ucmpdi2) (void) __attribute__ ((weak)); -void EXPORT_FUNC (__bswapsi2) (void) __attribute__ ((weak)); -void EXPORT_FUNC (__bswapdi2) (void) __attribute__ ((weak)); +void *EXPORT_FUNC (memset) (void *s, int c, int n); +void EXPORT_FUNC (__ashldi3) (void); +void EXPORT_FUNC (__ashrdi3) (void); +void EXPORT_FUNC (__lshrdi3) (void); +void EXPORT_FUNC (__ucmpdi2) (void); +void EXPORT_FUNC (__bswapsi2) (void); +void EXPORT_FUNC (__bswapdi2) (void); diff --git a/include/grub/mips/pci.h b/include/grub/mips/pci.h new file mode 100644 index 000000000..38a95a467 --- /dev/null +++ b/include/grub/mips/pci.h @@ -0,0 +1,70 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_CPU_PCI_H +#define GRUB_CPU_PCI_H 1 + +#include +#include + +#define GRUB_PCI_ADDR_REG 0x14000cf8 +#define GRUB_PCI_DATA_REG 0x14000cfc + +static inline grub_uint32_t +grub_pci_read (grub_pci_address_t addr) +{ + grub_outl (addr, GRUB_PCI_ADDR_REG); + return grub_inl (GRUB_PCI_DATA_REG); +} + +static inline grub_uint16_t +grub_pci_read_word (grub_pci_address_t addr) +{ + grub_outl (addr & ~3, GRUB_PCI_ADDR_REG); + return grub_inw (GRUB_PCI_DATA_REG + (addr & 3)); +} + +static inline grub_uint8_t +grub_pci_read_byte (grub_pci_address_t addr) +{ + grub_outl (addr & ~3, GRUB_PCI_ADDR_REG); + return grub_inb (GRUB_PCI_DATA_REG + (addr & 3)); +} + +static inline void +grub_pci_write (grub_pci_address_t addr, grub_uint32_t data) +{ + grub_outl (addr, GRUB_PCI_ADDR_REG); + grub_outl (data, GRUB_PCI_DATA_REG); +} + +static inline void +grub_pci_write_word (grub_pci_address_t addr, grub_uint16_t data) +{ + grub_outl (addr & ~3, GRUB_PCI_ADDR_REG); + grub_outw (data, GRUB_PCI_DATA_REG + (addr & 3)); +} + +static inline void +grub_pci_write_byte (grub_pci_address_t addr, grub_uint8_t data) +{ + grub_outl (addr & ~3, GRUB_PCI_ADDR_REG); + grub_outb (data, GRUB_PCI_DATA_REG + (addr & 3)); +} + +#endif /* GRUB_CPU_PCI_H */ diff --git a/include/grub/mips/qemu-mipssim/kernel.h b/include/grub/mips/qemu-mipssim/kernel.h new file mode 100644 index 000000000..6a10f2df1 --- /dev/null +++ b/include/grub/mips/qemu-mipssim/kernel.h @@ -0,0 +1,35 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2006,2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_KERNEL_MACHINE_HEADER +#define GRUB_KERNEL_MACHINE_HEADER 1 + +#include + +#ifndef ASM_FILE + +void EXPORT_FUNC (grub_reboot) (void); +void EXPORT_FUNC (grub_halt) (void); + +/* The prefix which points to the directory where GRUB modules and its + configuration file are located. */ +extern char grub_prefix[]; + +#endif + +#endif /* ! GRUB_KERNEL_MACHINE_HEADER */ diff --git a/include/grub/mips/qemu-mipssim/machine.h b/include/grub/mips/qemu-mipssim/machine.h new file mode 100644 index 000000000..9062662bc --- /dev/null +++ b/include/grub/mips/qemu-mipssim/machine.h @@ -0,0 +1,24 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2007 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_MACHINE_MACHINE_HEADER +#define GRUB_MACHINE_MACHINE_HEADER 1 + +#define GRUB_MACHINE_MIPS_QEMU_MIPSSIM 1 + +#endif /* ! GRUB_MACHINE_MACHINE_HEADER */ diff --git a/include/grub/mips/qemu-mipssim/memory.h b/include/grub/mips/qemu-mipssim/memory.h new file mode 100644 index 000000000..87e68674e --- /dev/null +++ b/include/grub/mips/qemu-mipssim/memory.h @@ -0,0 +1,54 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_MEMORY_MACHINE_HEADER +#define GRUB_MEMORY_MACHINE_HEADER 1 + +#ifndef ASM_FILE +#include +#include +#include +#endif + +#define GRUB_MACHINE_MEMORY_STACK_HIGH 0x80f00000 +#define GRUB_MACHINE_MEMORY_USABLE 0x81000000 + +#define GRUB_MACHINE_MEMORY_AVAILABLE 1 + +#ifndef ASM_FILE +grub_err_t EXPORT_FUNC (grub_machine_mmap_iterate) +(int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t)); +grub_err_t EXPORT_FUNC(grub_machine_mmap_iterate) + (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t)); + +static inline grub_err_t +grub_machine_mmap_register (grub_uint64_t start __attribute__ ((unused)), + grub_uint64_t size __attribute__ ((unused)), + int type __attribute__ ((unused)), + int handle __attribute__ ((unused))) +{ + return GRUB_ERR_NONE; +} +static inline grub_err_t +grub_machine_mmap_unregister (int handle __attribute__ ((unused))) +{ + return GRUB_ERR_NONE; +} +#endif + +#endif diff --git a/include/grub/mips/qemu-mipssim/time.h b/include/grub/mips/qemu-mipssim/time.h new file mode 100644 index 000000000..5c8564e0d --- /dev/null +++ b/include/grub/mips/qemu-mipssim/time.h @@ -0,0 +1,35 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2004,2005,2007 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef KERNEL_MACHINE_TIME_HEADER +#define KERNEL_MACHINE_TIME_HEADER 1 + +#include + +#define GRUB_TICKS_PER_SECOND 1000 + +/* Return the real time in ticks. */ +grub_uint32_t EXPORT_FUNC (grub_get_rtc) (void); + +static inline void +grub_cpu_idle(void) +{ + /* asm volatile ("wait");*/ +} + +#endif /* ! KERNEL_MACHINE_TIME_HEADER */ diff --git a/include/grub/mips/qemu-r4k/machine.h b/include/grub/mips/qemu-r4k/machine.h index 9bad5dca9..386cad750 100644 --- a/include/grub/mips/qemu-r4k/machine.h +++ b/include/grub/mips/qemu-r4k/machine.h @@ -19,6 +19,6 @@ #ifndef GRUB_MACHINE_MACHINE_HEADER #define GRUB_MACHINE_MACHINE_HEADER 1 -#define GRUB_MACHINE_MIPS_QEMU 1 +#define GRUB_MACHINE_MIPS_QEMU_R4K 1 #endif /* ! GRUB_MACHINE_MACHINE_HEADER */ diff --git a/kern/mips/qemu-mipssim/init.c b/kern/mips/qemu-mipssim/init.c new file mode 100644 index 000000000..d4001cf1c --- /dev/null +++ b/kern/mips/qemu-mipssim/init.c @@ -0,0 +1,76 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define RAMSIZE (64 << 20) + +grub_uint32_t +grub_get_rtc (void) +{ + static int calln = 0; + return calln++; +} + +void +grub_machine_init (void) +{ + grub_mm_init_region ((void *) GRUB_MACHINE_MEMORY_USABLE, + RAMSIZE - (GRUB_MACHINE_MEMORY_USABLE & 0x7fffffff)); + grub_install_get_time_ms (grub_rtc_get_time_ms); +} + +void +grub_machine_fini (void) +{ +} + +void +grub_exit (void) +{ + while (1); +} + +void +grub_halt (void) +{ + while (1); +} + +void +grub_reboot (void) +{ + while (1); +} + +void +grub_machine_set_prefix (void) +{ + grub_env_set ("prefix", grub_prefix); +} + +extern char _start[]; +extern char _end[]; + +grub_addr_t +grub_arch_modules_addr (void) +{ + return ALIGN_UP((grub_addr_t) _end + GRUB_MOD_GAP, GRUB_MOD_ALIGN); +} + +grub_err_t +grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, + grub_uint64_t, + grub_uint32_t)) +{ + hook (0, RAMSIZE, + GRUB_MACHINE_MEMORY_AVAILABLE); + return GRUB_ERR_NONE; +} diff --git a/kern/mips/qemu-mipssim/startup.S b/kern/mips/qemu-mipssim/startup.S new file mode 100644 index 000000000..19de4779d --- /dev/null +++ b/kern/mips/qemu-mipssim/startup.S @@ -0,0 +1,55 @@ +/* startup.S - Startup code for the MIPS. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include + +.extern __bss_start +.extern _end + + .globl __start, _start, start +__start: +_start: +start: + b codestart + . = _start + GRUB_KERNEL_CPU_PREFIX + +VARIABLE(grub_prefix) + /* to be filled by grub-mkelfimage */ + + /* + * Leave some breathing room for the prefix. + */ + + . = _start + GRUB_KERNEL_CPU_DATA_END +codestart: + lui $t1, %hi(__bss_start) + addiu $t1, %lo(__bss_start) + lui $t2, %hi(_end) + addiu $t2, %lo(_end) + +bsscont: + sb $0,0($t1) + addiu $t1,$t1,1 + sltu $t3,$t1,$t2 + bne $3, $0, bsscont + + li $sp, GRUB_MACHINE_MEMORY_STACK_HIGH + b grub_main \ No newline at end of file diff --git a/term/serial.c b/term/serial.c index 4b6ac981d..30f8bb91a 100644 --- a/term/serial.c +++ b/term/serial.c @@ -67,7 +67,10 @@ static struct serial_port serial_settings; #ifdef GRUB_MACHINE_PCBIOS static const unsigned short *serial_hw_io_addr = (const unsigned short *) GRUB_MEMORY_MACHINE_BIOS_DATA_AREA_ADDR; #define GRUB_SERIAL_PORT_NUM 4 -#elif defined (GRUB_MACHINE_MIPS_QEMU) +#elif defined (GRUB_MACHINE_MIPS_QEMU_MIPSSIM) +static const grub_port_t serial_hw_io_addr[] = { 0x1fd003f8 }; +#define GRUB_SERIAL_PORT_NUM (ARRAY_SIZE(serial_hw_io_addr)) +#elif defined (GRUB_MACHINE_MIPS_QEMU_R4K) static const grub_port_t serial_hw_io_addr[] = { 0x140003f8 }; #define GRUB_SERIAL_PORT_NUM (ARRAY_SIZE(serial_hw_io_addr)) #else From 9ed5ff3f6f03a145d2698d9b521ebebb6c3f2f6c Mon Sep 17 00:00:00 2001 From: phcoder Date: Sun, 11 Oct 2009 22:20:55 +0200 Subject: [PATCH 021/738] made relocator more portable --- lib/i386/relocator.c | 141 ++++++++++++------------------------------- lib/relocator.c | 97 +++++++++++++++++++++++++++++ 2 files changed, 137 insertions(+), 101 deletions(-) create mode 100644 lib/relocator.c diff --git a/lib/i386/relocator.c b/lib/i386/relocator.c index 3f0a40a27..84832eb02 100644 --- a/lib/i386/relocator.c +++ b/lib/i386/relocator.c @@ -54,112 +54,51 @@ extern grub_uint32_t grub_relocator32_backward_esp; #define RELOCATOR_SIZEOF(x) (&grub_relocator32_##x##_end - &grub_relocator32_##x##_start) #define RELOCATOR_ALIGN 16 +#define PREFIX(x) grub_relocator32_ ## x -void * -grub_relocator32_alloc (grub_size_t size) +static void +write_relocator_bw (void *ptr, void *src, grub_uint32_t dest, + grub_size_t size, struct grub_relocator32_state state) { - char *playground; - - playground = grub_malloc ((RELOCATOR_SIZEOF (forward) + RELOCATOR_ALIGN) - + size - + (RELOCATOR_SIZEOF (backward) + - RELOCATOR_ALIGN)); - if (!playground) - return 0; - - *(grub_size_t *) playground = size; - - return playground + RELOCATOR_SIZEOF (forward); -} - -void * -grub_relocator32_realloc (void *relocator, grub_size_t size) -{ - char *playground; - - playground = (char *) relocator - RELOCATOR_SIZEOF (forward); - - playground = grub_realloc (playground, - (RELOCATOR_SIZEOF (forward) + RELOCATOR_ALIGN) - + size - + (RELOCATOR_SIZEOF (backward) + RELOCATOR_ALIGN)); - if (!playground) - return 0; - - *(grub_size_t *) playground = size; - - return playground + RELOCATOR_SIZEOF (forward); -} - -void -grub_relocator32_free (void *relocator) -{ - if (relocator) - grub_free ((char *) relocator - RELOCATOR_SIZEOF (forward)); -} - - -grub_err_t -grub_relocator32_boot (void *relocator, grub_uint32_t dest, - struct grub_relocator32_state state) -{ - grub_size_t size; - char *playground; void (*entry) (); - playground = (char *) relocator - RELOCATOR_SIZEOF (forward); - size = *(grub_size_t *) playground; + grub_relocator32_backward_dest = dest; + grub_relocator32_backward_src = PTR_TO_UINT64 (src); + grub_relocator32_backward_size = size; - if (UINT_TO_PTR (dest) >= relocator) - { - int overhead; + grub_relocator32_backward_eax = state.eax; + grub_relocator32_backward_ebx = state.ebx; + grub_relocator32_backward_ecx = state.ecx; + grub_relocator32_backward_edx = state.edx; + grub_relocator32_backward_eip = state.eip; + grub_relocator32_backward_esp = state.esp; - overhead = - ALIGN_UP (dest - RELOCATOR_SIZEOF (backward) - RELOCATOR_ALIGN, - RELOCATOR_ALIGN); - grub_relocator32_backward_dest = dest - overhead; - grub_relocator32_backward_src = PTR_TO_UINT64 (relocator - overhead); - grub_relocator32_backward_size = size + overhead; - - grub_relocator32_backward_eax = state.eax; - grub_relocator32_backward_ebx = state.ebx; - grub_relocator32_backward_ecx = state.ecx; - grub_relocator32_backward_edx = state.edx; - grub_relocator32_backward_eip = state.eip; - grub_relocator32_backward_esp = state.esp; - - grub_memmove (relocator - overhead, - &grub_relocator32_backward_start, - RELOCATOR_SIZEOF (backward)); - entry = (void (*)()) (relocator - overhead); - } - else - { - int overhead; - - overhead = ALIGN_UP (dest + size, RELOCATOR_ALIGN) - + RELOCATOR_SIZEOF (forward) - (dest + size); - - grub_relocator32_forward_dest = dest; - grub_relocator32_forward_src = PTR_TO_UINT64 (relocator); - grub_relocator32_forward_size = size + overhead; - - grub_relocator32_forward_eax = state.eax; - grub_relocator32_forward_ebx = state.ebx; - grub_relocator32_forward_ecx = state.ecx; - grub_relocator32_forward_edx = state.edx; - grub_relocator32_forward_eip = state.eip; - grub_relocator32_forward_esp = state.esp; - - grub_memmove (relocator + size + overhead - RELOCATOR_SIZEOF (forward), - &grub_relocator32_forward_start, - RELOCATOR_SIZEOF (forward)); - entry = - (void (*)()) (relocator + size + overhead - - RELOCATOR_SIZEOF (forward)); - } + grub_memmove (ptr, + &grub_relocator32_backward_start, + RELOCATOR_SIZEOF (backward)); + entry = (void (*)()) (ptr); + entry (); +} + +static void +write_relocator_bw (void *ptr, void *src, grub_uint32_t dest, + grub_size_t size, struct grub_relocator32_state state) +{ + + grub_relocator32_forward_dest = dest; + grub_relocator32_forward_src = PTR_TO_UINT64 (src); + grub_relocator32_forward_size = size; + + grub_relocator32_forward_eax = state.eax; + grub_relocator32_forward_ebx = state.ebx; + grub_relocator32_forward_ecx = state.ecx; + grub_relocator32_forward_edx = state.edx; + grub_relocator32_forward_eip = state.eip; + grub_relocator32_forward_esp = state.esp; + + grub_memmove (ptr, + &grub_relocator32_forward_start, + RELOCATOR_SIZEOF (forward)); + entry = (void (*)()) ptr; entry (); - - /* Not reached. */ - return GRUB_ERR_NONE; } diff --git a/lib/relocator.c b/lib/relocator.c new file mode 100644 index 000000000..750753b6d --- /dev/null +++ b/lib/relocator.c @@ -0,0 +1,97 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +void * +PREFIX (alloc) (grub_size_t size) +{ + char *playground; + + playground = grub_malloc ((RELOCATOR_SIZEOF (forward) + RELOCATOR_ALIGN) + + size + + (RELOCATOR_SIZEOF (backward) + + RELOCATOR_ALIGN)); + if (!playground) + return 0; + + *(grub_size_t *) playground = size; + + return playground + RELOCATOR_SIZEOF (forward); +} + +void * +PREFIX (realloc) (void *relocator, grub_size_t size) +{ + char *playground; + + playground = (char *) relocator - RELOCATOR_SIZEOF (forward); + + playground = grub_realloc (playground, + (RELOCATOR_SIZEOF (forward) + RELOCATOR_ALIGN) + + size + + (RELOCATOR_SIZEOF (backward) + RELOCATOR_ALIGN)); + if (!playground) + return 0; + + *(grub_size_t *) playground = size; + + return playground + RELOCATOR_SIZEOF (forward); +} + +void +PREFIX(free) (void *relocator) +{ + if (relocator) + grub_free ((char *) relocator - RELOCATOR_SIZEOF (forward)); +} + +grub_err_t +PREFIX (boot) (void *relocator, grub_uint32_t dest, + struct grub_relocator32_state state) +{ + grub_size_t size; + char *playground; + + playground = (char *) relocator - RELOCATOR_SIZEOF (forward); + size = *(grub_size_t *) playground; + + if (UINT_TO_PTR (dest) >= relocator) + { + int overhead; + void *reldest = relocator - overhead; + overhead = + ALIGN_UP (dest - RELOCATOR_SIZEOF (backward) - RELOCATOR_ALIGN, + RELOCATOR_ALIGN); + write_call_relocator_bw (relocator - overhead, + relocator - overhead, + dest - overhead, size + overhead, state); + } + else + { + int overhead; + + overhead = ALIGN_UP (dest + size, RELOCATOR_ALIGN) + + RELOCATOR_SIZEOF (forward) - (dest + size); + + write_call_relocator_fw (relocator + size + overhead + - RELOCATOR_SIZEOF (forward), + relocator, dest, size + overhead, state); + } + + /* Not reached. */ + return GRUB_ERR_NONE; +} From 023593d766e6b3a05bf7e7c5118640bba4a1c659 Mon Sep 17 00:00:00 2001 From: phcoder Date: Sun, 11 Oct 2009 23:00:22 +0200 Subject: [PATCH 022/738] relocator dor mips --- conf/mips.rmk | 7 +++ include/grub/mips/relocator.h | 39 ++++++++++++ kern/mips/qemu-mipssim/startup.S | 2 +- lib/mips/relocator.c | 102 +++++++++++++++++++++++++++++++ lib/mips/relocator_asm.S | 50 +++++++++++++++ 5 files changed, 199 insertions(+), 1 deletion(-) create mode 100644 include/grub/mips/relocator.h create mode 100644 lib/mips/relocator.c create mode 100644 lib/mips/relocator_asm.S diff --git a/conf/mips.rmk b/conf/mips.rmk index 6ebd7d665..46b74d68f 100644 --- a/conf/mips.rmk +++ b/conf/mips.rmk @@ -140,4 +140,11 @@ pci_mod_SOURCES = bus/pci.c pci_mod_CFLAGS = $(COMMON_CFLAGS) pci_mod_LDFLAGS = $(COMMON_LDFLAGS) +# For relocator.mod. +pkglib_MODULES += relocator.mod +relocator_mod_SOURCES = lib/$(target_cpu)/relocator.c lib/$(target_cpu)/relocator_asm.S +relocator_mod_CFLAGS = $(COMMON_CFLAGS) +relocator_mod_ASFLAGS = $(COMMON_ASFLAGS) +relocator_mod_LDFLAGS = $(COMMON_LDFLAGS) + include $(srcdir)/conf/common.mk diff --git a/include/grub/mips/relocator.h b/include/grub/mips/relocator.h new file mode 100644 index 000000000..838ef832f --- /dev/null +++ b/include/grub/mips/relocator.h @@ -0,0 +1,39 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_RELOCATOR_CPU_HEADER +#define GRUB_RELOCATOR_CPU_HEADER 1 + +#include +#include + +struct grub_relocator32_state +{ + /* gpr[0] is ignored since it's hardwired to 0. */ + grub_uint32_t gpr[32]; + /* Register holding target $pc. */ + int jumpreg; +}; + +void *grub_relocator32_alloc (grub_size_t size); +grub_err_t grub_relocator32_boot (void *relocator, grub_uint32_t dest, + struct grub_relocator32_state state); +void *grub_relocator32_realloc (void *relocator, grub_size_t size); +void grub_relocator32_free (void *relocator); + +#endif /* ! GRUB_RELOCATOR_CPU_HEADER */ diff --git a/kern/mips/qemu-mipssim/startup.S b/kern/mips/qemu-mipssim/startup.S index 19de4779d..36c5fabd7 100644 --- a/kern/mips/qemu-mipssim/startup.S +++ b/kern/mips/qemu-mipssim/startup.S @@ -49,7 +49,7 @@ bsscont: sb $0,0($t1) addiu $t1,$t1,1 sltu $t3,$t1,$t2 - bne $3, $0, bsscont + bne $t3, $t0, bsscont li $sp, GRUB_MACHINE_MEMORY_STACK_HIGH b grub_main \ No newline at end of file diff --git a/lib/mips/relocator.c b/lib/mips/relocator.c new file mode 100644 index 000000000..4ec7f6c08 --- /dev/null +++ b/lib/mips/relocator.c @@ -0,0 +1,102 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include + +#include +#include +#include + +#include + +/* Remark: doesn't work with source outside of 4G. + Use relocator64 in this case. + */ + +extern grub_uint8_t grub_relocator32_forward_start; +extern grub_uint8_t grub_relocator32_forward_end; +extern grub_uint8_t grub_relocator32_backward_start; +extern grub_uint8_t grub_relocator32_backward_end; + +#define REGW_SIZEOF (2 * sizeof (grub_uint32_t)) +#define JUMP_SIZEOF (sizeof (grub_uint32_t)) + +#define RELOCATOR_SRC_SIZEOF(x) (&grub_relocator32_##x##_end \ + - &grub_relocator32_##x##_start) +#define RELOCATOR_SIZEOF(x) (RELOCATOR_SRC_SIZEOF(x) \ + + REGW_SIZEOF * (31 + 3) + JUMP_SIZEOF) +#define RELOCATOR_ALIGN 16 + +#define PREFIX(x) grub_relocator32_ ## x + +static void +write_reg (int regn, grub_uint32_t val, void **target) +{ + /* lui $r, (val+0x8000). */ + *(grub_uint32_t *) *target = ((0x3c00 | regn) << 16) | ((val + 0x8000) >> 16); + *target = ((grub_uint32_t *) *target) + 1; + /* addiu $r, $r, val. */ + *(grub_uint32_t *) *target = (((0x2400 | regn << 5 | regn) << 16) + | ((val + 0x8000) >> 16)); + *target = ((grub_uint32_t *) *target) + 1; +} + +static void +write_jump (int regn, void **target) +{ + /* j $r. */ + *(grub_uint32_t *) *target = (regn<<21) | 0x8; + *target = ((grub_uint32_t *) *target) + 1; +} + +static void +write_call_relocator_bw (void *ptr0, void *src, grub_uint32_t dest, + grub_size_t size, struct grub_relocator32_state state) +{ + void *ptr = ptr0; + int i; + write_reg (1, (grub_uint32_t) src, &ptr); + write_reg (2, dest, &ptr); + write_reg (3, size, &ptr); + grub_memcpy (ptr, &grub_relocator32_backward_start, + RELOCATOR_SRC_SIZEOF (backward)); + for (i = 1; i < 32; i++) + write_reg (i, state.gpr[i], &ptr); + write_jump (state.jumpreg, &ptr); + ((void (*) ())ptr0) (); +} + +static void +write_call_relocator_fw (void *ptr0, void *src, grub_uint32_t dest, + grub_size_t size, struct grub_relocator32_state state) +{ + void *ptr = ptr0; + int i; + write_reg (1, (grub_uint32_t) src, &ptr); + write_reg (2, dest, &ptr); + write_reg (3, size, &ptr); + grub_memcpy (ptr, &grub_relocator32_forward_start, + RELOCATOR_SRC_SIZEOF (forward)); + for (i = 1; i < 32; i++) + write_reg (i, state.gpr[i], &ptr); + write_jump (state.jumpreg, &ptr); + ((void (*) ())ptr0) (); +} + +#include "../relocator.c" diff --git a/lib/mips/relocator_asm.S b/lib/mips/relocator_asm.S new file mode 100644 index 000000000..607a46303 --- /dev/null +++ b/lib/mips/relocator_asm.S @@ -0,0 +1,50 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include + +#ifdef BACKWARD +#define RELOCATOR_VARIABLE(x) VARIABLE(grub_relocator32_backward_ ## x) +#else +#define RELOCATOR_VARIABLE(x) VARIABLE(grub_relocator32_forward_ ## x) +#endif + + .p2align 4 /* force 16-byte alignment */ + +VARIABLE (grub_relocator32_forward_start) +copycont1: + lb $4,0($1) + sb $4,0($2) + addiu $3, $3, 0xffff + subu $4,$3,$0 + bne $4, $0, copycont1 +VARIABLE (grub_relocator32_forward_end) + +VARIABLE (grub_relocator32_backward_start) + addu $2, $2, $3 + addu $1, $1, $3 + /* Backward movsl is implicitly off-by-one. compensate that. */ + addiu $2, $2, 0xffff + addiu $1, $1, 0xffff +copycont2: + lb $4,0($1) + sb $4,0($2) + addiu $3, 0xffff + subu $4,$3,$0 + bne $4, $0, copycont2 +VARIABLE (grub_relocator32_backward_end) From b07c261cfc645565126fd017209bde492a492247 Mon Sep 17 00:00:00 2001 From: phcoder Date: Sun, 11 Oct 2009 23:00:40 +0200 Subject: [PATCH 023/738] fix warning --- lib/relocator.c | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/relocator.c b/lib/relocator.c index 750753b6d..622adc517 100644 --- a/lib/relocator.c +++ b/lib/relocator.c @@ -72,7 +72,6 @@ PREFIX (boot) (void *relocator, grub_uint32_t dest, if (UINT_TO_PTR (dest) >= relocator) { int overhead; - void *reldest = relocator - overhead; overhead = ALIGN_UP (dest - RELOCATOR_SIZEOF (backward) - RELOCATOR_ALIGN, RELOCATOR_ALIGN); From 141278b5e065eea1074a5818a8083a61dffa73bd Mon Sep 17 00:00:00 2001 From: phcoder Date: Mon, 12 Oct 2009 11:23:08 +0200 Subject: [PATCH 024/738] fix --- lib/i386/relocator.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/lib/i386/relocator.c b/lib/i386/relocator.c index 84832eb02..94cbfba72 100644 --- a/lib/i386/relocator.c +++ b/lib/i386/relocator.c @@ -57,11 +57,9 @@ extern grub_uint32_t grub_relocator32_backward_esp; #define PREFIX(x) grub_relocator32_ ## x static void -write_relocator_bw (void *ptr, void *src, grub_uint32_t dest, - grub_size_t size, struct grub_relocator32_state state) +write_call_relocator_bw (void *ptr, void *src, grub_uint32_t dest, + grub_size_t size, struct grub_relocator32_state state) { - void (*entry) (); - grub_relocator32_backward_dest = dest; grub_relocator32_backward_src = PTR_TO_UINT64 (src); grub_relocator32_backward_size = size; @@ -76,13 +74,12 @@ write_relocator_bw (void *ptr, void *src, grub_uint32_t dest, grub_memmove (ptr, &grub_relocator32_backward_start, RELOCATOR_SIZEOF (backward)); - entry = (void (*)()) (ptr); - entry (); + ((void (*)()) ptr) (); } static void -write_relocator_bw (void *ptr, void *src, grub_uint32_t dest, - grub_size_t size, struct grub_relocator32_state state) +write_call_relocator_fw (void *ptr, void *src, grub_uint32_t dest, + grub_size_t size, struct grub_relocator32_state state) { grub_relocator32_forward_dest = dest; @@ -99,6 +96,7 @@ write_relocator_bw (void *ptr, void *src, grub_uint32_t dest, grub_memmove (ptr, &grub_relocator32_forward_start, RELOCATOR_SIZEOF (forward)); - entry = (void (*)()) ptr; - entry (); + ((void (*)()) ptr) (); } + +#include "../relocator.c" From 81a642e8e2c6fc8f070651e1f9b10fb563b39018 Mon Sep 17 00:00:00 2001 From: phcoder Date: Fri, 16 Oct 2009 17:40:59 +0200 Subject: [PATCH 025/738] linux.c --- include/grub/elfload.h | 4 ++-- kern/elf.c | 17 ++++++++++++++--- lib/mips/relocator.c | 12 ++++++------ lib/mips/relocator_asm.S | 26 +++++++++++++------------- 4 files changed, 35 insertions(+), 24 deletions(-) diff --git a/include/grub/elfload.h b/include/grub/elfload.h index 6e09e0d05..77ee41675 100644 --- a/include/grub/elfload.h +++ b/include/grub/elfload.h @@ -46,12 +46,12 @@ grub_elf_t grub_elf_file (grub_file_t); grub_err_t grub_elf_close (grub_elf_t); int grub_elf_is_elf32 (grub_elf_t); -grub_size_t grub_elf32_size (grub_elf_t); +grub_size_t grub_elf32_size (grub_elf_t, Elf32_Addr *); grub_err_t grub_elf32_load (grub_elf_t, grub_elf32_load_hook_t, grub_addr_t *, grub_size_t *); int grub_elf_is_elf64 (grub_elf_t); -grub_size_t grub_elf64_size (grub_elf_t); +grub_size_t grub_elf64_size (grub_elf_t, Elf64_Addr *); grub_err_t grub_elf64_load (grub_elf_t, grub_elf64_load_hook_t, grub_addr_t *, grub_size_t *); diff --git a/kern/elf.c b/kern/elf.c index f14161060..1e51839a0 100644 --- a/kern/elf.c +++ b/kern/elf.c @@ -172,7 +172,7 @@ grub_elf32_phdr_iterate (grub_elf_t elf, /* Calculate the amount of memory spanned by the segments. */ grub_size_t -grub_elf32_size (grub_elf_t elf) +grub_elf32_size (grub_elf_t elf, Elf32_Addr *base) { Elf32_Addr segments_start = (Elf32_Addr) -1; Elf32_Addr segments_end = 0; @@ -196,6 +196,9 @@ grub_elf32_size (grub_elf_t elf) grub_elf32_phdr_iterate (elf, calcsize, 0); + if (base) + *base = 0; + if (nr_phdrs == 0) { grub_error (GRUB_ERR_BAD_OS, "No program headers present"); @@ -209,10 +212,12 @@ grub_elf32_size (grub_elf_t elf) return 0; } + if (base) + *base = segments_start; + return segments_end - segments_start; } - /* Load every loadable segment into memory specified by `_load_hook'. */ grub_err_t grub_elf32_load (grub_elf_t _elf, grub_elf32_load_hook_t _load_hook, @@ -351,7 +356,7 @@ grub_elf64_phdr_iterate (grub_elf_t elf, /* Calculate the amount of memory spanned by the segments. */ grub_size_t -grub_elf64_size (grub_elf_t elf) +grub_elf64_size (grub_elf_t elf, Elf64_Addr *base) { Elf64_Addr segments_start = (Elf64_Addr) -1; Elf64_Addr segments_end = 0; @@ -375,6 +380,9 @@ grub_elf64_size (grub_elf_t elf) grub_elf64_phdr_iterate (elf, calcsize, 0); + if (base) + *base = 0; + if (nr_phdrs == 0) { grub_error (GRUB_ERR_BAD_OS, "No program headers present"); @@ -388,6 +396,9 @@ grub_elf64_size (grub_elf_t elf) return 0; } + if (base) + *base = segments_start; + return segments_end - segments_start; } diff --git a/lib/mips/relocator.c b/lib/mips/relocator.c index 4ec7f6c08..91e66893a 100644 --- a/lib/mips/relocator.c +++ b/lib/mips/relocator.c @@ -71,9 +71,9 @@ write_call_relocator_bw (void *ptr0, void *src, grub_uint32_t dest, { void *ptr = ptr0; int i; - write_reg (1, (grub_uint32_t) src, &ptr); - write_reg (2, dest, &ptr); - write_reg (3, size, &ptr); + write_reg (2, (grub_uint32_t) src, &ptr); + write_reg (3, dest, &ptr); + write_reg (4, size, &ptr); grub_memcpy (ptr, &grub_relocator32_backward_start, RELOCATOR_SRC_SIZEOF (backward)); for (i = 1; i < 32; i++) @@ -88,9 +88,9 @@ write_call_relocator_fw (void *ptr0, void *src, grub_uint32_t dest, { void *ptr = ptr0; int i; - write_reg (1, (grub_uint32_t) src, &ptr); - write_reg (2, dest, &ptr); - write_reg (3, size, &ptr); + write_reg (2, (grub_uint32_t) src, &ptr); + write_reg (3, dest, &ptr); + write_reg (4, size, &ptr); grub_memcpy (ptr, &grub_relocator32_forward_start, RELOCATOR_SRC_SIZEOF (forward)); for (i = 1; i < 32; i++) diff --git a/lib/mips/relocator_asm.S b/lib/mips/relocator_asm.S index 607a46303..24541e2d0 100644 --- a/lib/mips/relocator_asm.S +++ b/lib/mips/relocator_asm.S @@ -28,23 +28,23 @@ VARIABLE (grub_relocator32_forward_start) copycont1: - lb $4,0($1) - sb $4,0($2) - addiu $3, $3, 0xffff - subu $4,$3,$0 - bne $4, $0, copycont1 + lb $5,0($2) + sb $5,0($3) + addiu $4, $4, 0xffff + subu $5,$4,$0 + bne $5, $0, copycont1 VARIABLE (grub_relocator32_forward_end) VARIABLE (grub_relocator32_backward_start) - addu $2, $2, $3 - addu $1, $1, $3 + addu $3, $3, $4 + addu $2, $2, $4 /* Backward movsl is implicitly off-by-one. compensate that. */ + addiu $3, $3, 0xffff addiu $2, $2, 0xffff - addiu $1, $1, 0xffff copycont2: - lb $4,0($1) - sb $4,0($2) - addiu $3, 0xffff - subu $4,$3,$0 - bne $4, $0, copycont2 + lb $5,0($2) + sb $5,0($3) + addiu $4, 0xffff + subu $5,$4,$0 + bne $5, $0, copycont2 VARIABLE (grub_relocator32_backward_end) From ea818634b5c283698b28eb03c76c602a0048e4fd Mon Sep 17 00:00:00 2001 From: phcoder Date: Fri, 16 Oct 2009 18:13:18 +0200 Subject: [PATCH 026/738] actual file --- loader/mips/linux.c | 317 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 317 insertions(+) create mode 100644 loader/mips/linux.c diff --git a/loader/mips/linux.c b/loader/mips/linux.c new file mode 100644 index 000000000..6b94304a5 --- /dev/null +++ b/loader/mips/linux.c @@ -0,0 +1,317 @@ +/* linux.c - boot Linux */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003, 2004, 2005, 2007, 2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define ELF32_LOADMASK (0x00000000UL) +#define ELF64_LOADMASK (0x0000000000000000ULL) + +static grub_dl_t my_mod; + +static int loaded; + +static grub_size_t initrd_size; +static grub_size_t linux_size; + +static char *linux_args; + +static grub_uint8_t *playground; +static grub_addr_t target_addr, entry_addr, initrd_addr, args_addr; + +static grub_err_t +grub_linux_boot (void) +{ + grub_ssize_t actual; + struct grub_relocator32_state state; + + /* Boot the kernel. */ + state.gpr[1] = entry_addr; + state.jumpreg = 1; + grub_relocator32_boot (playground, target_addr, state); + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_linux_release_mem (void) +{ + grub_relocator32_free (playground); + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_linux_unload (void) +{ + grub_err_t err; + + err = grub_linux_release_mem (); + grub_dl_unref (my_mod); + + loaded = 0; + + return err; +} + +static grub_err_t +grub_linux_load32 (grub_elf_t elf, char *args) +{ + Elf32_Addr base; + int found_addr = 0; + int argsoff; + + /* Linux's entry point incorrectly contains a virtual address. */ + entry_addr = elf->ehdr.ehdr32.e_entry & ~ELF32_LOADMASK; + + linux_size = grub_elf32_size (elf, &base); + if (linux_size == 0) + return grub_errno; + target_addr = base; + /* Pad it; the kernel scribbles over memory beyond its load address. */ + linux_size += 0x100000; + argsoff = linux_size; + args_addr = target_addr + argsoff; + linux_size += grub_strlen (args) + 1; + + playground = grub_relocator32_alloc (linux_size); + if (!playground) + return grub_errno; + + grub_memcpy (playground + argsoff, args, grub_strlen (args) + 1); + + /* Now load the segments into the area we claimed. */ + auto grub_err_t offset_phdr (Elf32_Phdr *phdr, grub_addr_t *addr, int *do_load); + grub_err_t offset_phdr (Elf32_Phdr *phdr, grub_addr_t *addr, int *do_load) + { + if (phdr->p_type != PT_LOAD) + { + *do_load = 0; + return 0; + } + *do_load = 1; + + /* Linux's program headers incorrectly contain virtual addresses. + * Translate those to physical, and offset to the area we claimed. */ + *addr = phdr->p_paddr - base + playground; + return 0; + } + return grub_elf32_load (elf, offset_phdr, 0, 0); +} + +static grub_err_t +grub_linux_load64 (grub_elf_t elf) +{ + Elf64_Addr base; + int found_addr = 0; + int argsoff; + + /* Linux's entry point incorrectly contains a virtual address. */ + entry_addr = elf->ehdr.ehdr64.e_entry & ~ELF64_LOADMASK; + + linux_size = grub_elf64_size (elf, &base); + if (linux_size == 0) + return grub_errno; + target_addr = base; + /* Pad it; the kernel scribbles over memory beyond its load address. */ + linux_size += 0x100000; + argsoff = linux_size; + args_addr = target_addr + argsoff; + linux_size += grub_strlen (args) + 1; + + playground = grub_relocator32_alloc (linux_size); + if (!playground) + return grub_errno; + + grub_memcpy (playground + argsoff, args, grub_strlen (args) + 1); + + /* Now load the segments into the area we claimed. */ + auto grub_err_t offset_phdr (Elf64_Phdr *phdr, grub_addr_t *addr, int *do_load); + grub_err_t offset_phdr (Elf64_Phdr *phdr, grub_addr_t *addr, int *do_load) + { + if (phdr->p_type != PT_LOAD) + { + *do_load = 0; + return 0; + } + *do_load = 1; + /* Linux's program headers incorrectly contain virtual addresses. + * Translate those to physical, and offset to the area we claimed. */ + *addr = phdr->p_paddr - base + playground; + return 0; + } + return grub_elf64_load (elf, offset_phdr, 0, 0); +} + +static grub_err_t +grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ + grub_elf_t elf = 0; + int i; + int size; + char *dest; + + grub_dl_ref (my_mod); + + if (argc == 0) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "no kernel specified"); + goto out; + } + + elf = grub_elf_open (argv[0]); + if (! elf) + goto out; + + if (elf->ehdr.ehdr32.e_type != ET_EXEC) + { + grub_error (GRUB_ERR_UNKNOWN_OS, + "This ELF file is not of the right type\n"); + goto out; + } + + /* Release the previously used memory. */ + grub_loader_unset (); + + size = sizeof ("BOOT_IMAGE=") + grub_strlen (argv[0]); + for (i = 0; i < argc; i++) + size += grub_strlen (argv[i]) + 1; + + linux_args = grub_malloc (size); + if (! linux_args) + goto out; + + /* Specify the boot file. */ + dest = grub_stpcpy (linux_args, "BOOT_IMAGE="); + dest = grub_stpcpy (dest, argv[0]); + + for (i = 1; i < argc; i++) + { + *dest++ = ' '; + dest = grub_stpcpy (dest, argv[i]); + } + + if (grub_elf_is_elf32 (elf)) + grub_linux_load32 (elf, linux_args); + else + if (grub_elf_is_elf64 (elf)) + grub_linux_load64 (elf, linux_args); + else + { + grub_error (GRUB_ERR_BAD_FILE_TYPE, "Unknown ELF class"); + goto out; + } + +out: + + if (elf) + grub_elf_close (elf); + + if (grub_errno != GRUB_ERR_NONE) + { + grub_linux_release_mem (); + grub_dl_unref (my_mod); + loaded = 0; + } + else + { + grub_loader_set (grub_linux_boot, grub_linux_unload, 1); + initrd_addr = 0; + loaded = 1; + } + + return grub_errno; +} + +static grub_err_t +grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ + grub_file_t file = 0; + grub_ssize_t size; + grub_addr_t addr; + int found_addr = 0; + + if (argc == 0) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "no initrd specified"); + goto fail; + } + + if (!loaded) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "You need to load the kernel first."); + goto fail; + } + + file = grub_file_open (argv[0]); + if (! file) + return grub_errno; + + size = grub_file_size (file); + + playground = grub_relocator32_realloc (playground, linux_size + size); + if (!playground) + { + grub_file_close (file); + return grub_errno; + } + + grub_dprintf ("loader", "Loading initrd at 0x%x, size 0x%x\n", addr, size); + + if (grub_file_read (file, playground + linux_size, size) != size) + { + grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file"); + grub_file_close (file); + + return grub_errno; + } + + initrd_addr = target_addr + linux_size; + initrd_size = size; + + grub_file_close (file); + + return GRUB_ERR_NONE; +} + +static grub_command_t cmd_linux, cmd_initrd; + +GRUB_MOD_INIT(linux) +{ + cmd_linux = grub_register_command ("linux", grub_cmd_linux, + 0, "load a linux kernel"); + cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd, + 0, "load an initrd"); + my_mod = mod; +} + +GRUB_MOD_FINI(linux) +{ + grub_unregister_command (cmd_linux); + grub_unregister_command (cmd_initrd); +} From a45337b5d7bf769b9e1533b349ed597932b90126 Mon Sep 17 00:00:00 2001 From: phcoder Date: Sat, 17 Oct 2009 12:18:39 +0200 Subject: [PATCH 027/738] first linux boot --- conf/mips.rmk | 6 ++++++ lib/mips/relocator.c | 8 +++++--- lib/mips/relocator_asm.S | 4 ++++ loader/mips/linux.c | 20 +++++--------------- 4 files changed, 20 insertions(+), 18 deletions(-) diff --git a/conf/mips.rmk b/conf/mips.rmk index 46b74d68f..9920f6878 100644 --- a/conf/mips.rmk +++ b/conf/mips.rmk @@ -147,4 +147,10 @@ relocator_mod_CFLAGS = $(COMMON_CFLAGS) relocator_mod_ASFLAGS = $(COMMON_ASFLAGS) relocator_mod_LDFLAGS = $(COMMON_LDFLAGS) +pkglib_MODULES += linux.mod +linux_mod_SOURCES = loader/$(target_cpu)/linux.c +linux_mod_CFLAGS = $(COMMON_CFLAGS) +linux_mod_ASFLAGS = $(COMMON_ASFLAGS) +linux_mod_LDFLAGS = $(COMMON_LDFLAGS) + include $(srcdir)/conf/common.mk diff --git a/lib/mips/relocator.c b/lib/mips/relocator.c index 91e66893a..cc9d23f39 100644 --- a/lib/mips/relocator.c +++ b/lib/mips/relocator.c @@ -53,7 +53,7 @@ write_reg (int regn, grub_uint32_t val, void **target) *target = ((grub_uint32_t *) *target) + 1; /* addiu $r, $r, val. */ *(grub_uint32_t *) *target = (((0x2400 | regn << 5 | regn) << 16) - | ((val + 0x8000) >> 16)); + | (val & 0xffff)); *target = ((grub_uint32_t *) *target) + 1; } @@ -76,10 +76,11 @@ write_call_relocator_bw (void *ptr0, void *src, grub_uint32_t dest, write_reg (4, size, &ptr); grub_memcpy (ptr, &grub_relocator32_backward_start, RELOCATOR_SRC_SIZEOF (backward)); + ptr = (grub_uint8_t *) ptr + RELOCATOR_SRC_SIZEOF (backward); for (i = 1; i < 32; i++) write_reg (i, state.gpr[i], &ptr); write_jump (state.jumpreg, &ptr); - ((void (*) ())ptr0) (); + ((void (*) ()) ptr0) (); } static void @@ -93,10 +94,11 @@ write_call_relocator_fw (void *ptr0, void *src, grub_uint32_t dest, write_reg (4, size, &ptr); grub_memcpy (ptr, &grub_relocator32_forward_start, RELOCATOR_SRC_SIZEOF (forward)); + ptr = (grub_uint8_t *) ptr + RELOCATOR_SRC_SIZEOF (forward); for (i = 1; i < 32; i++) write_reg (i, state.gpr[i], &ptr); write_jump (state.jumpreg, &ptr); - ((void (*) ())ptr0) (); + ((void (*) ()) ptr0) (); } #include "../relocator.c" diff --git a/lib/mips/relocator_asm.S b/lib/mips/relocator_asm.S index 24541e2d0..8dea8a4e3 100644 --- a/lib/mips/relocator_asm.S +++ b/lib/mips/relocator_asm.S @@ -30,6 +30,8 @@ VARIABLE (grub_relocator32_forward_start) copycont1: lb $5,0($2) sb $5,0($3) + addiu $2, $2, 0x1 + addiu $3, $3, 0x1 addiu $4, $4, 0xffff subu $5,$4,$0 bne $5, $0, copycont1 @@ -44,6 +46,8 @@ VARIABLE (grub_relocator32_backward_start) copycont2: lb $5,0($2) sb $5,0($3) + addiu $2, $2, 0xffff + addiu $3, $3, 0xffff addiu $4, 0xffff subu $5,$4,$0 bne $5, $0, copycont2 diff --git a/loader/mips/linux.c b/loader/mips/linux.c index 6b94304a5..03e489bf7 100644 --- a/loader/mips/linux.c +++ b/loader/mips/linux.c @@ -45,7 +45,6 @@ static grub_addr_t target_addr, entry_addr, initrd_addr, args_addr; static grub_err_t grub_linux_boot (void) { - grub_ssize_t actual; struct grub_relocator32_state state; /* Boot the kernel. */ @@ -81,7 +80,6 @@ static grub_err_t grub_linux_load32 (grub_elf_t elf, char *args) { Elf32_Addr base; - int found_addr = 0; int argsoff; /* Linux's entry point incorrectly contains a virtual address. */ @@ -116,17 +114,16 @@ grub_linux_load32 (grub_elf_t elf, char *args) /* Linux's program headers incorrectly contain virtual addresses. * Translate those to physical, and offset to the area we claimed. */ - *addr = phdr->p_paddr - base + playground; + *addr = (grub_addr_t) (phdr->p_paddr - base + playground); return 0; } return grub_elf32_load (elf, offset_phdr, 0, 0); } static grub_err_t -grub_linux_load64 (grub_elf_t elf) +grub_linux_load64 (grub_elf_t elf, char *args) { Elf64_Addr base; - int found_addr = 0; int argsoff; /* Linux's entry point incorrectly contains a virtual address. */ @@ -160,7 +157,7 @@ grub_linux_load64 (grub_elf_t elf) *do_load = 1; /* Linux's program headers incorrectly contain virtual addresses. * Translate those to physical, and offset to the area we claimed. */ - *addr = phdr->p_paddr - base + playground; + *addr = (grub_addr_t) (phdr->p_paddr - base + playground); return 0; } return grub_elf64_load (elf, offset_phdr, 0, 0); @@ -254,19 +251,12 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), grub_file_t file = 0; grub_ssize_t size; grub_addr_t addr; - int found_addr = 0; if (argc == 0) - { - grub_error (GRUB_ERR_BAD_ARGUMENT, "no initrd specified"); - goto fail; - } + return grub_error (GRUB_ERR_BAD_ARGUMENT, "no initrd specified"); if (!loaded) - { - grub_error (GRUB_ERR_BAD_ARGUMENT, "You need to load the kernel first."); - goto fail; - } + return grub_error (GRUB_ERR_BAD_ARGUMENT, "You need to load the kernel first."); file = grub_file_open (argv[0]); if (! file) From fdb3c3acb095033527ca5c4d337857d559e15283 Mon Sep 17 00:00:00 2001 From: phcoder Date: Sun, 18 Oct 2009 00:22:15 +0200 Subject: [PATCH 028/738] simplify mipsel handling --- configure.ac | 4 ---- include/grub/mips/types.h | 6 ++---- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/configure.ac b/configure.ac index 98750280e..f0aeb1aa8 100644 --- a/configure.ac +++ b/configure.ac @@ -100,12 +100,8 @@ case "$target_cpu" in i386 | powerpc) target_m32=1 ;; x86_64 | sparc64) target_m64=1 ;; mipsel) - TARGET_CFLAGS="$TARGET_CFLAGS -DGRUB_CPU_MIPSEL=1"; - CFLAGS="$CFLAGS -DGRUB_CPU_MIPSEL=1"; target_cpu=mips ;; mips) - TARGET_CFLAGS="$TARGET_CFLAGS -DGRUB_CPU_MIPS=1"; - CFLAGS="$CFLAGS -DGRUB_CPU_MIPS=1"; target_cpu=mips ;; esac diff --git a/include/grub/mips/types.h b/include/grub/mips/types.h index fe09afa3e..aed597451 100644 --- a/include/grub/mips/types.h +++ b/include/grub/mips/types.h @@ -25,14 +25,12 @@ /* The size of long. */ #define GRUB_TARGET_SIZEOF_LONG 4 -#ifdef GRUB_CPU_MIPSEL +#ifdef __MIPSEL__ /* mipsEL is little-endian. */ #undef GRUB_TARGET_WORDS_BIGENDIAN -#elif defined (GRUB_CPU_MIPS) +#else /* mips is big-endian. */ #define GRUB_TARGET_WORDS_BIGENDIAN -#elif !defined (GRUB_SYMBOL_GENERATOR) -#error Neither GRUB_CPU_MIPS nor GRUB_CPU_MIPSEL is defined #endif #endif /* ! GRUB_TYPES_CPU_HEADER */ From be320b471f23cdde2be971dd68c80c59a43579f9 Mon Sep 17 00:00:00 2001 From: phcoder Date: Sun, 18 Oct 2009 00:23:00 +0200 Subject: [PATCH 029/738] cache handling --- kern/mips/cache.S | 6 +++++- lib/mips/relocator_asm.S | 6 ++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/kern/mips/cache.S b/kern/mips/cache.S index f613f57f2..ec13a9b95 100644 --- a/kern/mips/cache.S +++ b/kern/mips/cache.S @@ -1,5 +1,9 @@ #include -FUNCTION (grub_arch_sync_caches) + /* FIXME: This should invalidate only part of memory. */ FUNCTION (grub_cpu_flush_cache) +FUNCTION (grub_arch_sync_caches) +#if __mips >= 2 + sync +#endif j $31 diff --git a/lib/mips/relocator_asm.S b/lib/mips/relocator_asm.S index 8dea8a4e3..5503b4032 100644 --- a/lib/mips/relocator_asm.S +++ b/lib/mips/relocator_asm.S @@ -35,6 +35,9 @@ copycont1: addiu $4, $4, 0xffff subu $5,$4,$0 bne $5, $0, copycont1 +#if __mips >= 2 + sync +#endif VARIABLE (grub_relocator32_forward_end) VARIABLE (grub_relocator32_backward_start) @@ -51,4 +54,7 @@ copycont2: addiu $4, 0xffff subu $5,$4,$0 bne $5, $0, copycont2 +#if __mips >= 2 + sync +#endif VARIABLE (grub_relocator32_backward_end) From 4c7f8ce16d571bc86f6deef5b9eb4533cec71387 Mon Sep 17 00:00:00 2001 From: phcoder Date: Sun, 18 Oct 2009 00:23:45 +0200 Subject: [PATCH 030/738] warning fixes --- lib/mips/relocator.c | 4 ++-- loader/mips/linux.c | 3 --- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/lib/mips/relocator.c b/lib/mips/relocator.c index cc9d23f39..b0fb4b2a5 100644 --- a/lib/mips/relocator.c +++ b/lib/mips/relocator.c @@ -80,7 +80,7 @@ write_call_relocator_bw (void *ptr0, void *src, grub_uint32_t dest, for (i = 1; i < 32; i++) write_reg (i, state.gpr[i], &ptr); write_jump (state.jumpreg, &ptr); - ((void (*) ()) ptr0) (); + ((void (*) (void)) ptr0) (); } static void @@ -98,7 +98,7 @@ write_call_relocator_fw (void *ptr0, void *src, grub_uint32_t dest, for (i = 1; i < 32; i++) write_reg (i, state.gpr[i], &ptr); write_jump (state.jumpreg, &ptr); - ((void (*) ()) ptr0) (); + ((void (*) (void)) ptr0) (); } #include "../relocator.c" diff --git a/loader/mips/linux.c b/loader/mips/linux.c index 03e489bf7..3e526c699 100644 --- a/loader/mips/linux.c +++ b/loader/mips/linux.c @@ -250,7 +250,6 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), { grub_file_t file = 0; grub_ssize_t size; - grub_addr_t addr; if (argc == 0) return grub_error (GRUB_ERR_BAD_ARGUMENT, "no initrd specified"); @@ -271,8 +270,6 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), return grub_errno; } - grub_dprintf ("loader", "Loading initrd at 0x%x, size 0x%x\n", addr, size); - if (grub_file_read (file, playground + linux_size, size) != size) { grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file"); From 9385e55bddb8f4008b3ac4a9c87fc0d3f4949f09 Mon Sep 17 00:00:00 2001 From: phcoder Date: Sun, 18 Oct 2009 00:24:17 +0200 Subject: [PATCH 031/738] warning fixes --- lib/relocator.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/relocator.c b/lib/relocator.c index 622adc517..e551f337f 100644 --- a/lib/relocator.c +++ b/lib/relocator.c @@ -75,8 +75,8 @@ PREFIX (boot) (void *relocator, grub_uint32_t dest, overhead = ALIGN_UP (dest - RELOCATOR_SIZEOF (backward) - RELOCATOR_ALIGN, RELOCATOR_ALIGN); - write_call_relocator_bw (relocator - overhead, - relocator - overhead, + write_call_relocator_bw ((char *) relocator - overhead, + (char *) relocator - overhead, dest - overhead, size + overhead, state); } else @@ -86,7 +86,7 @@ PREFIX (boot) (void *relocator, grub_uint32_t dest, overhead = ALIGN_UP (dest + size, RELOCATOR_ALIGN) + RELOCATOR_SIZEOF (forward) - (dest + size); - write_call_relocator_fw (relocator + size + overhead + write_call_relocator_fw ((char *) relocator + size + overhead - RELOCATOR_SIZEOF (forward), relocator, dest, size + overhead, state); } From d71b572aeaa8fd53524d66cc1a5eba354affac3a Mon Sep 17 00:00:00 2001 From: phcoder Date: Sun, 18 Oct 2009 00:25:22 +0200 Subject: [PATCH 032/738] empty loader.h added --- include/grub/mips/qemu-r4k/loader.h | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 include/grub/mips/qemu-r4k/loader.h diff --git a/include/grub/mips/qemu-r4k/loader.h b/include/grub/mips/qemu-r4k/loader.h new file mode 100644 index 000000000..e69de29bb From cba2cae2f5abbe76b6733389cb36cd37ce1f50cf Mon Sep 17 00:00:00 2001 From: phcoder Date: Sun, 18 Oct 2009 11:49:09 +0200 Subject: [PATCH 033/738] simplified serial --- include/grub/i386/coreboot/serial.h | 24 ++++++++++++++++++++++++ include/grub/i386/ieee1275/serial.h | 2 +- include/grub/mips/qemu-mipssim/serial.h | 24 ++++++++++++++++++++++++ include/grub/mips/qemu-r4k/serial.h | 24 ++++++++++++++++++++++++ term/serial.c | 10 ++-------- 5 files changed, 75 insertions(+), 9 deletions(-) create mode 100644 include/grub/i386/coreboot/serial.h create mode 100644 include/grub/mips/qemu-mipssim/serial.h create mode 100644 include/grub/mips/qemu-r4k/serial.h diff --git a/include/grub/i386/coreboot/serial.h b/include/grub/i386/coreboot/serial.h new file mode 100644 index 000000000..b6819d587 --- /dev/null +++ b/include/grub/i386/coreboot/serial.h @@ -0,0 +1,24 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_MACHINE_SERIAL_HEADER +#define GRUB_MACHINE_SERIAL_HEADER 1 + +#define GRUB_MACHINE_SERIAL_PORTS { 0x3f8, 0x2f8, 0x3e8, 0x2e8 } + +#endif diff --git a/include/grub/i386/ieee1275/serial.h b/include/grub/i386/ieee1275/serial.h index 2c527f626..2d8563414 100644 --- a/include/grub/i386/ieee1275/serial.h +++ b/include/grub/i386/ieee1275/serial.h @@ -1 +1 @@ -#include +#include diff --git a/include/grub/mips/qemu-mipssim/serial.h b/include/grub/mips/qemu-mipssim/serial.h new file mode 100644 index 000000000..55d64fec4 --- /dev/null +++ b/include/grub/mips/qemu-mipssim/serial.h @@ -0,0 +1,24 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_MACHINE_SERIAL_HEADER +#define GRUB_MACHINE_SERIAL_HEADER 1 + +#define GRUB_MACHINE_SERIAL_PORTS { 0x1fd003f8 } + +#endif diff --git a/include/grub/mips/qemu-r4k/serial.h b/include/grub/mips/qemu-r4k/serial.h new file mode 100644 index 000000000..1f8ce0804 --- /dev/null +++ b/include/grub/mips/qemu-r4k/serial.h @@ -0,0 +1,24 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_MACHINE_SERIAL_HEADER +#define GRUB_MACHINE_SERIAL_HEADER 1 + +#define GRUB_MACHINE_SERIAL_PORTS { 0x140003f8 } + +#endif diff --git a/term/serial.c b/term/serial.c index 30f8bb91a..648b5baf6 100644 --- a/term/serial.c +++ b/term/serial.c @@ -19,7 +19,6 @@ #include #include #include -//#include #include #include #include @@ -67,14 +66,9 @@ static struct serial_port serial_settings; #ifdef GRUB_MACHINE_PCBIOS static const unsigned short *serial_hw_io_addr = (const unsigned short *) GRUB_MEMORY_MACHINE_BIOS_DATA_AREA_ADDR; #define GRUB_SERIAL_PORT_NUM 4 -#elif defined (GRUB_MACHINE_MIPS_QEMU_MIPSSIM) -static const grub_port_t serial_hw_io_addr[] = { 0x1fd003f8 }; -#define GRUB_SERIAL_PORT_NUM (ARRAY_SIZE(serial_hw_io_addr)) -#elif defined (GRUB_MACHINE_MIPS_QEMU_R4K) -static const grub_port_t serial_hw_io_addr[] = { 0x140003f8 }; -#define GRUB_SERIAL_PORT_NUM (ARRAY_SIZE(serial_hw_io_addr)) #else -static const grub_port_t serial_hw_io_addr[] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 }; +#include +static const grub_port_t serial_hw_io_addr[] = GRUB_MACHINE_SERIAL_PORTS; #define GRUB_SERIAL_PORT_NUM (ARRAY_SIZE(serial_hw_io_addr)) #endif From 686135601f3d48d9cd795392ae8016887f54c8f2 Mon Sep 17 00:00:00 2001 From: phcoder Date: Sun, 18 Oct 2009 11:50:40 +0200 Subject: [PATCH 034/738] simplified mips/mipsel --- configure.ac | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/configure.ac b/configure.ac index f0aeb1aa8..c02b8c0c9 100644 --- a/configure.ac +++ b/configure.ac @@ -46,6 +46,7 @@ AC_ARG_PROGRAM case "$target_cpu" in i[[3456]]86) target_cpu=i386 ;; sparc) target_cpu=sparc64 ;; + mipsel) target_cpu=mips ;; esac # Specify the platform (such as firmware). @@ -89,9 +90,7 @@ case "$target_cpu"-"$platform" in i386-qemu) ;; powerpc-ieee1275) ;; sparc64-ieee1275) ;; - mipsel-qemu-r4k) ;; mips-qemu-r4k) ;; - mipsel-qemu-mipssim) ;; mips-qemu-mipssim) ;; *) AC_MSG_ERROR([platform "$platform" is not supported for target CPU "$target_cpu"]) ;; esac @@ -99,10 +98,6 @@ esac case "$target_cpu" in i386 | powerpc) target_m32=1 ;; x86_64 | sparc64) target_m64=1 ;; - mipsel) - target_cpu=mips ;; - mips) - target_cpu=mips ;; esac case "$host_os" in From 1c2cdb26d36c374fe218e45e3966cc4942ed992c Mon Sep 17 00:00:00 2001 From: phcoder Date: Sun, 18 Oct 2009 12:04:20 +0200 Subject: [PATCH 035/738] yeeloong headers --- include/grub/mips/yeeloong/kernel.h | 35 ++++++++++++++++++ include/grub/mips/yeeloong/loader.h | 0 include/grub/mips/yeeloong/machine.h | 24 +++++++++++++ include/grub/mips/yeeloong/memory.h | 53 ++++++++++++++++++++++++++++ include/grub/mips/yeeloong/serial.h | 24 +++++++++++++ include/grub/mips/yeeloong/time.h | 34 ++++++++++++++++++ 6 files changed, 170 insertions(+) create mode 100644 include/grub/mips/yeeloong/kernel.h create mode 100644 include/grub/mips/yeeloong/loader.h create mode 100644 include/grub/mips/yeeloong/machine.h create mode 100644 include/grub/mips/yeeloong/memory.h create mode 100644 include/grub/mips/yeeloong/serial.h create mode 100644 include/grub/mips/yeeloong/time.h diff --git a/include/grub/mips/yeeloong/kernel.h b/include/grub/mips/yeeloong/kernel.h new file mode 100644 index 000000000..6a10f2df1 --- /dev/null +++ b/include/grub/mips/yeeloong/kernel.h @@ -0,0 +1,35 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2006,2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_KERNEL_MACHINE_HEADER +#define GRUB_KERNEL_MACHINE_HEADER 1 + +#include + +#ifndef ASM_FILE + +void EXPORT_FUNC (grub_reboot) (void); +void EXPORT_FUNC (grub_halt) (void); + +/* The prefix which points to the directory where GRUB modules and its + configuration file are located. */ +extern char grub_prefix[]; + +#endif + +#endif /* ! GRUB_KERNEL_MACHINE_HEADER */ diff --git a/include/grub/mips/yeeloong/loader.h b/include/grub/mips/yeeloong/loader.h new file mode 100644 index 000000000..e69de29bb diff --git a/include/grub/mips/yeeloong/machine.h b/include/grub/mips/yeeloong/machine.h new file mode 100644 index 000000000..9f29b4a46 --- /dev/null +++ b/include/grub/mips/yeeloong/machine.h @@ -0,0 +1,24 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2007 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_MACHINE_MACHINE_HEADER +#define GRUB_MACHINE_MACHINE_HEADER 1 + +#define GRUB_MACHINE_MIPS_YEELOONG 1 + +#endif /* ! GRUB_MACHINE_MACHINE_HEADER */ diff --git a/include/grub/mips/yeeloong/memory.h b/include/grub/mips/yeeloong/memory.h new file mode 100644 index 000000000..72ebcefa4 --- /dev/null +++ b/include/grub/mips/yeeloong/memory.h @@ -0,0 +1,53 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_MEMORY_MACHINE_HEADER +#define GRUB_MEMORY_MACHINE_HEADER 1 + +#ifndef ASM_FILE +#include +#include +#include +#endif + +#define GRUB_MACHINE_MEMORY_STACK_HIGH 0x801ffff0 + +#define GRUB_MACHINE_MEMORY_AVAILABLE 1 + +#ifndef ASM_FILE +grub_err_t EXPORT_FUNC (grub_machine_mmap_iterate) +(int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t)); +grub_err_t EXPORT_FUNC(grub_machine_mmap_iterate) + (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t)); + +static inline grub_err_t +grub_machine_mmap_register (grub_uint64_t start __attribute__ ((unused)), + grub_uint64_t size __attribute__ ((unused)), + int type __attribute__ ((unused)), + int handle __attribute__ ((unused))) +{ + return GRUB_ERR_NONE; +} +static inline grub_err_t +grub_machine_mmap_unregister (int handle __attribute__ ((unused))) +{ + return GRUB_ERR_NONE; +} +#endif + +#endif diff --git a/include/grub/mips/yeeloong/serial.h b/include/grub/mips/yeeloong/serial.h new file mode 100644 index 000000000..9390ea18a --- /dev/null +++ b/include/grub/mips/yeeloong/serial.h @@ -0,0 +1,24 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_MACHINE_SERIAL_HEADER +#define GRUB_MACHINE_SERIAL_HEADER 1 + +#define GRUB_MACHINE_SERIAL_PORTS { 0xbff003f8 } + +#endif diff --git a/include/grub/mips/yeeloong/time.h b/include/grub/mips/yeeloong/time.h new file mode 100644 index 000000000..a73f64dea --- /dev/null +++ b/include/grub/mips/yeeloong/time.h @@ -0,0 +1,34 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2004,2005,2007 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef KERNEL_MACHINE_TIME_HEADER +#define KERNEL_MACHINE_TIME_HEADER 1 + +#include + +#define GRUB_TICKS_PER_SECOND 1000 + +/* Return the real time in ticks. */ +grub_uint32_t EXPORT_FUNC (grub_get_rtc) (void); + +static inline void +grub_cpu_idle(void) +{ +} + +#endif /* ! KERNEL_MACHINE_TIME_HEADER */ From 8adc0f006054961979de55e5a607b570398def09 Mon Sep 17 00:00:00 2001 From: phcoder Date: Sun, 18 Oct 2009 12:08:52 +0200 Subject: [PATCH 036/738] unified startup.S --- kern/mips/qemu-mipssim/startup.S | 55 ------------------------------ kern/mips/{qemu-r4k => }/startup.S | 0 2 files changed, 55 deletions(-) delete mode 100644 kern/mips/qemu-mipssim/startup.S rename kern/mips/{qemu-r4k => }/startup.S (100%) diff --git a/kern/mips/qemu-mipssim/startup.S b/kern/mips/qemu-mipssim/startup.S deleted file mode 100644 index 36c5fabd7..000000000 --- a/kern/mips/qemu-mipssim/startup.S +++ /dev/null @@ -1,55 +0,0 @@ -/* startup.S - Startup code for the MIPS. */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2009 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include - -.extern __bss_start -.extern _end - - .globl __start, _start, start -__start: -_start: -start: - b codestart - . = _start + GRUB_KERNEL_CPU_PREFIX - -VARIABLE(grub_prefix) - /* to be filled by grub-mkelfimage */ - - /* - * Leave some breathing room for the prefix. - */ - - . = _start + GRUB_KERNEL_CPU_DATA_END -codestart: - lui $t1, %hi(__bss_start) - addiu $t1, %lo(__bss_start) - lui $t2, %hi(_end) - addiu $t2, %lo(_end) - -bsscont: - sb $0,0($t1) - addiu $t1,$t1,1 - sltu $t3,$t1,$t2 - bne $t3, $t0, bsscont - - li $sp, GRUB_MACHINE_MEMORY_STACK_HIGH - b grub_main \ No newline at end of file diff --git a/kern/mips/qemu-r4k/startup.S b/kern/mips/startup.S similarity index 100% rename from kern/mips/qemu-r4k/startup.S rename to kern/mips/startup.S From ad17a401d69c7971ac83e449d6dc7d3fbeb6acc8 Mon Sep 17 00:00:00 2001 From: phcoder Date: Sun, 18 Oct 2009 14:10:31 +0200 Subject: [PATCH 037/738] new image format for mips. Asm part --- conf/mips.rmk | 5 +- configure.ac | 2 + genmk.rb | 2 +- include/grub/mips/kernel.h | 12 +++-- kern/mips/startup.S | 98 +++++++++++++++++++++++++++++++------- 5 files changed, 94 insertions(+), 25 deletions(-) diff --git a/conf/mips.rmk b/conf/mips.rmk index 9920f6878..a76ecac14 100644 --- a/conf/mips.rmk +++ b/conf/mips.rmk @@ -26,7 +26,7 @@ kernel_syms.lst: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h genke /bin/sh genkernsyms.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) # Programs -pkglib_PROGRAMS = kernel.img +pkglib_IMAGES = kernel.img # Utilities. sbin_UTILITIES = grub-mkdevicemap @@ -84,7 +84,7 @@ grub_emu_SOURCES = commands/minicmd.c commands/cat.c commands/cmp.c \ grub_emu_LDFLAGS = $(LIBCURSES) -kernel_img_SOURCES = kern/$(target_cpu)/$(target_machine)/startup.S \ +kernel_img_SOURCES = kern/$(target_cpu)/startup.S \ kern/main.c kern/device.c kern/$(target_cpu)/$(target_machine)/init.c \ kern/disk.c kern/dl.c kern/err.c kern/file.c kern/fs.c \ kern/misc.c kern/mm.c kern/reader.c kern/term.c \ @@ -97,6 +97,7 @@ kernel_img_CFLAGS = $(COMMON_CFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) kernel_img_LDFLAGS = $(COMMON_LDFLAGS) -static-libgcc -lgcc \ -Wl,-N,-S,-Ttext,$(LINK_BASE),-Bstatic +kernel_img_FORMAT = binary # Scripts. sbin_SCRIPTS = diff --git a/configure.ac b/configure.ac index c02b8c0c9..f13cac52a 100644 --- a/configure.ac +++ b/configure.ac @@ -64,6 +64,7 @@ if test "x$with_platform" = x; then powerpc-*) platform=ieee1275 ;; powerpc64-*) platform=ieee1275 ;; sparc64-*) platform=ieee1275 ;; + mips-*) platform=yeeloong ;; *) AC_MSG_ERROR([unsupported CPU: "$target_cpu"]) ;; esac else @@ -92,6 +93,7 @@ case "$target_cpu"-"$platform" in sparc64-ieee1275) ;; mips-qemu-r4k) ;; mips-qemu-mipssim) ;; + mips-yeeloong) ;; *) AC_MSG_ERROR([platform "$platform" is not supported for target CPU "$target_cpu"]) ;; esac diff --git a/genmk.rb b/genmk.rb index 71b57816f..c608707b7 100644 --- a/genmk.rb +++ b/genmk.rb @@ -68,7 +68,7 @@ MOSTLYCLEAN_IMAGE_TARGETS += mostlyclean-image-#{@name}.#{@rule_count} ifneq ($(TARGET_APPLE_CC),1) #{@name}: #{exe} - $(OBJCOPY) -O $(#{prefix}_FORMAT) --strip-unneeded -R .note -R .comment -R .note.gnu.build-id $< $@ + $(OBJCOPY) -O $(#{prefix}_FORMAT) --strip-unneeded -R .note -R .comment -R .note.gnu.build-id -R .reginfo -R .rel.dyn $< $@ else ifneq (#{exe},kernel.exec) #{@name}: #{exe} ./grub-macho2img diff --git a/include/grub/mips/kernel.h b/include/grub/mips/kernel.h index 326f1244d..3b578ef05 100644 --- a/include/grub/mips/kernel.h +++ b/include/grub/mips/kernel.h @@ -20,13 +20,15 @@ #define GRUB_KERNEL_CPU_HEADER 1 #define GRUB_MOD_ALIGN 0x1000 +/* Non-zero value is only needed for PowerMacs. */ +#define GRUB_MOD_GAP 0x0 -/* Minimal gap between _end and the start of the modules. It's a hack - for PowerMac to prevent "CLAIM failed" error. The real fix is to - rewrite grub-mkimage to generate valid ELF files. */ -#define GRUB_MOD_GAP 0x8000 +#define GRUB_KERNEL_CPU_RAW_SIZE 0x100 +#define GRUB_KERNEL_CPU_COMPRESSED_SIZE 0x8 +#define GRUB_KERNEL_CPU_TOTAL_MODULE_SIZE 0xc +#define GRUB_KERNEL_CPU_KERNEL_IMAGE_SIZE 0x10 -#define GRUB_KERNEL_CPU_PREFIX 0x8 +#define GRUB_KERNEL_CPU_PREFIX 0x0 #define GRUB_KERNEL_CPU_DATA_END 0x48 #endif diff --git a/kern/mips/startup.S b/kern/mips/startup.S index 19de4779d..545aae32a 100644 --- a/kern/mips/startup.S +++ b/kern/mips/startup.S @@ -21,6 +21,8 @@ #include #include +#define BASE_ADDR 8 + .extern __bss_start .extern _end @@ -28,8 +30,84 @@ __start: _start: start: - b codestart - . = _start + GRUB_KERNEL_CPU_PREFIX + bal codestart + . = _start + GRUB_KERNEL_CPU_COMPRESSED_SIZE +compressed_size: + .long 0 + . = _start + GRUB_KERNEL_CPU_TOTAL_MODULE_SIZE +total_module_size: + .long 0 + . = _start + GRUB_KERNEL_CPU_KERNEL_IMAGE_SIZE +kernel_image_size: + .long 0 +codestart: + /* Decompress the payload. */ + addiu $t2, $ra, GRUB_KERNEL_CPU_RAW_SIZE - BASE_ADDR + lui $t1, %hi(compressed) + addiu $t1, %lo(compressed) + lw $t3, (GRUB_KERNEL_CPU_COMPRESSED_SIZE - BASE_ADDR)($ra) + + /* $t2 contains source compressed address, $t1 is destination, + $t3 is compressed size. FIXME: put LZMA here. Don't clober $ra + */ +reloccont: + lb $t4, 0($t2) + sb $t4, 0($t1) + addiu $t1,$t1,1 + addiu $t2,$t2,1 + addiu $t3, 0xffff + bne $t3, $0, reloccont + + /* Move the modules out of BSS. */ + lui $t1, %hi(compressed) + addiu $t1, %lo(compressed) + lw $t2, (GRUB_KERNEL_CPU_KERNEL_IMAGE_SIZE - BASE_ADDR)($ra) + addu $t2, $t1, $t2 + + lui $t1, %hi(_end) + addiu $t1, %lo(_end) + addiu $t1, (GRUB_MOD_ALIGN-1) + li $t3, (GRUB_MOD_ALIGN-1) + nor $t3, $t3, $0 + and $t1, $t1, $t3 + /* Pass modules address as first argument. */ + move $a0, $t1 + + lw $t3, (GRUB_KERNEL_CPU_TOTAL_MODULE_SIZE - BASE_ADDR)($ra) + + /* $t2 is source. $t1 is destination. $t3 is size. */ +modulesmovcont: + lb $t4, 0($t2) + sb $t4, 0($t1) + addiu $t1,$t1,1 + addiu $t2,$t2,1 + addiu $t3, 0xffff + bne $t3, $0, modulesmovcont + + /* Clean BSS. */ + + lui $t1, %hi(__bss_start) + addiu $t1, %lo(__bss_start) + lui $t2, %hi(_end) + addiu $t2, %lo(_end) +bsscont: + sb $0,0($t1) + addiu $t1,$t1,1 + sltu $t3,$t1,$t2 + bne $t3, $0, bsscont + + li $sp, GRUB_MACHINE_MEMORY_STACK_HIGH + lui $t1, %hi(grub_main) + addiu $t1, %lo(grub_main) + +#if __mips >= 2 + sync +#endif + jr $t1 + + . = _start + GRUB_KERNEL_CPU_RAW_SIZE +compressed: + . = _start + GRUB_KERNEL_CPU_RAW_SIZE + GRUB_KERNEL_CPU_PREFIX VARIABLE(grub_prefix) /* to be filled by grub-mkelfimage */ @@ -38,18 +116,4 @@ VARIABLE(grub_prefix) * Leave some breathing room for the prefix. */ - . = _start + GRUB_KERNEL_CPU_DATA_END -codestart: - lui $t1, %hi(__bss_start) - addiu $t1, %lo(__bss_start) - lui $t2, %hi(_end) - addiu $t2, %lo(_end) - -bsscont: - sb $0,0($t1) - addiu $t1,$t1,1 - sltu $t3,$t1,$t2 - bne $3, $0, bsscont - - li $sp, GRUB_MACHINE_MEMORY_STACK_HIGH - b grub_main \ No newline at end of file + . = _start + GRUB_KERNEL_CPU_RAW_SIZE + GRUB_KERNEL_CPU_DATA_END From a9a6948ac34717504d719984d3d13c4755ea3c47 Mon Sep 17 00:00:00 2001 From: phcoder Date: Sun, 18 Oct 2009 15:04:14 +0200 Subject: [PATCH 038/738] grub as flash for qemu-gdium --- conf/i386-pc.rmk | 2 +- conf/mips.rmk | 7 +++++++ include/grub/mips/kernel.h | 20 +++++++++++++++++-- include/grub/mips/qemu-r4k/kernel.h | 1 + include/grub/mips/yeeloong/kernel.h | 5 +---- include/grub/mips/yeeloong/memory.h | 1 + kern/main.c | 1 + kern/mips/startup.S | 10 +++++----- kern/term.c | 5 ++++- .../pc/grub-mkimage.c => grub-mkrawimage.c} | 10 +++++++--- 10 files changed, 46 insertions(+), 16 deletions(-) rename util/{i386/pc/grub-mkimage.c => grub-mkrawimage.c} (98%) diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk index c4a4e7754..74125eaa5 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -87,7 +87,7 @@ sbin_UTILITIES += grub-emu endif # For grub-mkimage. -grub_mkimage_SOURCES = util/i386/pc/grub-mkimage.c util/misc.c \ +grub_mkimage_SOURCES = util/grub-mkrawimage.c util/misc.c \ util/resolve.c lib/LzmaEnc.c lib/LzFind.c grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR) util/i386/pc/grub-mkimage.c_DEPENDENCIES = Makefile diff --git a/conf/mips.rmk b/conf/mips.rmk index a76ecac14..553256a9b 100644 --- a/conf/mips.rmk +++ b/conf/mips.rmk @@ -103,6 +103,13 @@ kernel_img_FORMAT = binary sbin_SCRIPTS = bin_SCRIPTS = +# For grub-mkimage. +bin_UTILITIES += grub-mkimage +grub_mkimage_SOURCES = util/grub-mkrawimage.c util/misc.c \ + util/resolve.c lib/LzmaEnc.c lib/LzFind.c +grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR) +util/i386/pc/grub-mkimage.c_DEPENDENCIES = Makefile + # Modules. pkglib_MODULES = memdisk.mod \ lsmmap.mod diff --git a/include/grub/mips/kernel.h b/include/grub/mips/kernel.h index 3b578ef05..4a7c9293c 100644 --- a/include/grub/mips/kernel.h +++ b/include/grub/mips/kernel.h @@ -28,7 +28,23 @@ #define GRUB_KERNEL_CPU_TOTAL_MODULE_SIZE 0xc #define GRUB_KERNEL_CPU_KERNEL_IMAGE_SIZE 0x10 -#define GRUB_KERNEL_CPU_PREFIX 0x0 -#define GRUB_KERNEL_CPU_DATA_END 0x48 +#define GRUB_KERNEL_CPU_PREFIX GRUB_KERNEL_CPU_RAW_SIZE +#define GRUB_KERNEL_CPU_DATA_END GRUB_KERNEL_CPU_RAW_SIZE + 0x48 + +#define GRUB_KERNEL_MACHINE_RAW_SIZE GRUB_KERNEL_CPU_RAW_SIZE + +#define GRUB_KERNEL_MACHINE_PREFIX GRUB_KERNEL_CPU_PREFIX +#define GRUB_KERNEL_MACHINE_DATA_END GRUB_KERNEL_CPU_DATA_END +#define GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE GRUB_KERNEL_CPU_KERNEL_IMAGE_SIZE +#define GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE GRUB_KERNEL_CPU_TOTAL_MODULE_SIZE +#define GRUB_KERNEL_MACHINE_COMPRESSED_SIZE GRUB_KERNEL_CPU_COMPRESSED_SIZE + +#ifndef ASM_FILE + +/* The prefix which points to the directory where GRUB modules and its + configuration file are located. */ +extern char grub_prefix[]; + +#endif #endif diff --git a/include/grub/mips/qemu-r4k/kernel.h b/include/grub/mips/qemu-r4k/kernel.h index 6a10f2df1..dbf74c1b2 100644 --- a/include/grub/mips/qemu-r4k/kernel.h +++ b/include/grub/mips/qemu-r4k/kernel.h @@ -20,6 +20,7 @@ #define GRUB_KERNEL_MACHINE_HEADER 1 #include +#include #ifndef ASM_FILE diff --git a/include/grub/mips/yeeloong/kernel.h b/include/grub/mips/yeeloong/kernel.h index 6a10f2df1..230455dbf 100644 --- a/include/grub/mips/yeeloong/kernel.h +++ b/include/grub/mips/yeeloong/kernel.h @@ -20,16 +20,13 @@ #define GRUB_KERNEL_MACHINE_HEADER 1 #include +#include #ifndef ASM_FILE void EXPORT_FUNC (grub_reboot) (void); void EXPORT_FUNC (grub_halt) (void); -/* The prefix which points to the directory where GRUB modules and its - configuration file are located. */ -extern char grub_prefix[]; - #endif #endif /* ! GRUB_KERNEL_MACHINE_HEADER */ diff --git a/include/grub/mips/yeeloong/memory.h b/include/grub/mips/yeeloong/memory.h index 72ebcefa4..bc8f47b12 100644 --- a/include/grub/mips/yeeloong/memory.h +++ b/include/grub/mips/yeeloong/memory.h @@ -26,6 +26,7 @@ #endif #define GRUB_MACHINE_MEMORY_STACK_HIGH 0x801ffff0 +#define GRUB_MACHINE_MEMORY_USABLE 0x81000000 #define GRUB_MACHINE_MEMORY_AVAILABLE 1 diff --git a/kern/main.c b/kern/main.c index 9215d55e7..31dc0a36a 100644 --- a/kern/main.c +++ b/kern/main.c @@ -48,6 +48,7 @@ grub_module_iterate (int (*hook) (struct grub_module_header *header)) header < (struct grub_module_header *) (modbase + modinfo->size); header = (struct grub_module_header *) ((char *) header + header->size)) { + grub_printf ("%p:", header); if (hook (header)) break; } diff --git a/kern/mips/startup.S b/kern/mips/startup.S index 545aae32a..b31b49331 100644 --- a/kern/mips/startup.S +++ b/kern/mips/startup.S @@ -59,8 +59,8 @@ reloccont: bne $t3, $0, reloccont /* Move the modules out of BSS. */ - lui $t1, %hi(compressed) - addiu $t1, %lo(compressed) + lui $t1, %hi(_start) + addiu $t1, %lo(_start) lw $t2, (GRUB_KERNEL_CPU_KERNEL_IMAGE_SIZE - BASE_ADDR)($ra) addu $t2, $t1, $t2 @@ -71,7 +71,7 @@ reloccont: nor $t3, $t3, $0 and $t1, $t1, $t3 /* Pass modules address as first argument. */ - move $a0, $t1 +// move $a0, $t1 lw $t3, (GRUB_KERNEL_CPU_TOTAL_MODULE_SIZE - BASE_ADDR)($ra) @@ -107,7 +107,7 @@ bsscont: . = _start + GRUB_KERNEL_CPU_RAW_SIZE compressed: - . = _start + GRUB_KERNEL_CPU_RAW_SIZE + GRUB_KERNEL_CPU_PREFIX + . = _start + GRUB_KERNEL_CPU_PREFIX VARIABLE(grub_prefix) /* to be filled by grub-mkelfimage */ @@ -116,4 +116,4 @@ VARIABLE(grub_prefix) * Leave some breathing room for the prefix. */ - . = _start + GRUB_KERNEL_CPU_RAW_SIZE + GRUB_KERNEL_CPU_DATA_END + . = _start + GRUB_KERNEL_CPU_DATA_END diff --git a/kern/term.c b/kern/term.c index 0e3595df3..271cf8d78 100644 --- a/kern/term.c +++ b/kern/term.c @@ -51,7 +51,10 @@ grub_putcode (grub_uint32_t code) int height = grub_getwh () & 255; if (!grub_cur_term_output) - return; + { + *(grub_uint8_t *)0xbff003f8 = code; + return; + } if (code == '\t' && grub_cur_term_output->getxy) { diff --git a/util/i386/pc/grub-mkimage.c b/util/grub-mkrawimage.c similarity index 98% rename from util/i386/pc/grub-mkimage.c rename to util/grub-mkrawimage.c index 15168f8fa..0d26e3cf4 100644 --- a/util/i386/pc/grub-mkimage.c +++ b/util/grub-mkrawimage.c @@ -93,10 +93,10 @@ static void generate_image (const char *dir, char *prefix, FILE *out, char *mods[], char *memdisk_path, char *config_path) { - char *kernel_img, *boot_img, *core_img; - size_t kernel_size, boot_size, total_module_size, core_size; + char *kernel_img, *core_img; + size_t kernel_size, total_module_size, core_size; size_t memdisk_size = 0, config_size = 0; - char *kernel_path, *boot_path; + char *kernel_path; size_t offset; struct grub_util_path_list *path_list, *p, *next; struct grub_module_info *modinfo; @@ -198,6 +198,8 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], #if defined(GRUB_MACHINE_PCBIOS) { unsigned num; + char *boot_path, *boot_img; + size_t boot_size; num = ((core_size + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS); if (num > 0xffff) grub_util_error ("the core image is too big"); @@ -222,6 +224,8 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], { char *rom_img; size_t rom_size; + char *boot_path, *boot_img; + size_t boot_size; boot_path = grub_util_get_path (dir, "boot.img"); boot_size = grub_util_get_image_size (boot_path); From 4a1eefb623104fe61c88f17db2d2dbb13d44a038 Mon Sep 17 00:00:00 2001 From: phcoder Date: Sun, 18 Oct 2009 15:06:47 +0200 Subject: [PATCH 039/738] Revert "simplify mipsel handling" This reverts commit 3451c43f4938a20aee5a2c0d0fa17c29e40b989b. Conflicts: configure.ac --- configure.ac | 11 ++++++++++- include/grub/mips/types.h | 6 ++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index f13cac52a..abfcf92e7 100644 --- a/configure.ac +++ b/configure.ac @@ -46,7 +46,16 @@ AC_ARG_PROGRAM case "$target_cpu" in i[[3456]]86) target_cpu=i386 ;; sparc) target_cpu=sparc64 ;; - mipsel) target_cpu=mips ;; + mipsel) + target_cpu=mips; + TARGET_CFLAGS="$TARGET_CFLAGS -DGRUB_CPU_MIPSEL=1"; + CFLAGS="$CFLAGS -DGRUB_CPU_MIPSEL=1"; + ;; + mips) + target_cpu=mips; + TARGET_CFLAGS="$TARGET_CFLAGS -DGRUB_CPU_MIPS=1"; + CFLAGS="$CFLAGS -DGRUB_CPU_MIPS=1"; + ;; esac # Specify the platform (such as firmware). diff --git a/include/grub/mips/types.h b/include/grub/mips/types.h index aed597451..fe09afa3e 100644 --- a/include/grub/mips/types.h +++ b/include/grub/mips/types.h @@ -25,12 +25,14 @@ /* The size of long. */ #define GRUB_TARGET_SIZEOF_LONG 4 -#ifdef __MIPSEL__ +#ifdef GRUB_CPU_MIPSEL /* mipsEL is little-endian. */ #undef GRUB_TARGET_WORDS_BIGENDIAN -#else +#elif defined (GRUB_CPU_MIPS) /* mips is big-endian. */ #define GRUB_TARGET_WORDS_BIGENDIAN +#elif !defined (GRUB_SYMBOL_GENERATOR) +#error Neither GRUB_CPU_MIPS nor GRUB_CPU_MIPSEL is defined #endif #endif /* ! GRUB_TYPES_CPU_HEADER */ From 3dc648f724bde69f52249576c0189802d677a538 Mon Sep 17 00:00:00 2001 From: phcoder Date: Sun, 18 Oct 2009 15:07:22 +0200 Subject: [PATCH 040/738] missing file --- kern/mips/yeeloong/init.c | 75 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 kern/mips/yeeloong/init.c diff --git a/kern/mips/yeeloong/init.c b/kern/mips/yeeloong/init.c new file mode 100644 index 000000000..eece6076c --- /dev/null +++ b/kern/mips/yeeloong/init.c @@ -0,0 +1,75 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define RAMSIZE (64 << 20) + +grub_uint32_t +grub_get_rtc (void) +{ + static int calln = 0; + return calln++; +} + +void +grub_machine_init (void) +{ + grub_mm_init_region ((void *) GRUB_MACHINE_MEMORY_USABLE, + RAMSIZE - (GRUB_MACHINE_MEMORY_USABLE & 0x7fffffff)); + grub_install_get_time_ms (grub_rtc_get_time_ms); +} + +void +grub_machine_fini (void) +{ +} + +void +grub_exit (void) +{ + while (1); +} + +void +grub_halt (void) +{ + while (1); +} + +void +grub_reboot (void) +{ + while (1); +} + +void +grub_machine_set_prefix (void) +{ + grub_env_set ("prefix", grub_prefix); +} + +extern char _end[]; + +grub_addr_t +grub_arch_modules_addr (void) +{ + return ALIGN_UP((grub_addr_t) _end + GRUB_MOD_GAP, GRUB_MOD_ALIGN); +} + +grub_err_t +grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, + grub_uint64_t, + grub_uint32_t)) +{ + hook (0, RAMSIZE, + GRUB_MACHINE_MEMORY_AVAILABLE); + return GRUB_ERR_NONE; +} From 877128fa4550b9ce69413bba2f9bd52e8080d91e Mon Sep 17 00:00:00 2001 From: phcoder Date: Sun, 18 Oct 2009 16:10:42 +0200 Subject: [PATCH 041/738] copy modules backwards --- kern/mips/startup.S | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/kern/mips/startup.S b/kern/mips/startup.S index b31b49331..fca319e22 100644 --- a/kern/mips/startup.S +++ b/kern/mips/startup.S @@ -75,12 +75,18 @@ reloccont: lw $t3, (GRUB_KERNEL_CPU_TOTAL_MODULE_SIZE - BASE_ADDR)($ra) + /* Backward copy. */ + add $t1, $t1, $t3 + add $t2, $t2, $t3 + addiu $t1, $t1, 0xffff + addiu $t2, $t2, 0xffff + /* $t2 is source. $t1 is destination. $t3 is size. */ modulesmovcont: lb $t4, 0($t2) sb $t4, 0($t1) - addiu $t1,$t1,1 - addiu $t2,$t2,1 + addiu $t1,$t1,0xffff + addiu $t2,$t2,0xffff addiu $t3, 0xffff bne $t3, $0, modulesmovcont From 19f9e339c31e080cbae35fe1b808414c2a2eb2f8 Mon Sep 17 00:00:00 2001 From: phcoder Date: Sun, 18 Oct 2009 16:15:04 +0200 Subject: [PATCH 042/738] revert changes to kern/main.c --- kern/main.c | 1 - 1 file changed, 1 deletion(-) diff --git a/kern/main.c b/kern/main.c index 31dc0a36a..9215d55e7 100644 --- a/kern/main.c +++ b/kern/main.c @@ -48,7 +48,6 @@ grub_module_iterate (int (*hook) (struct grub_module_header *header)) header < (struct grub_module_header *) (modbase + modinfo->size); header = (struct grub_module_header *) ((char *) header + header->size)) { - grub_printf ("%p:", header); if (hook (header)) break; } From 65aa1698d3bb704f9fa6cb33bfd96ed99beb0156 Mon Sep 17 00:00:00 2001 From: phcoder Date: Mon, 19 Oct 2009 12:58:52 +0200 Subject: [PATCH 043/738] use $t9 instead of $ra as a base register --- kern/mips/startup.S | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/kern/mips/startup.S b/kern/mips/startup.S index fca319e22..afab3642e 100644 --- a/kern/mips/startup.S +++ b/kern/mips/startup.S @@ -42,13 +42,14 @@ kernel_image_size: .long 0 codestart: /* Decompress the payload. */ - addiu $t2, $ra, GRUB_KERNEL_CPU_RAW_SIZE - BASE_ADDR + move $t9, $ra + addiu $t2, $t9, GRUB_KERNEL_CPU_RAW_SIZE - BASE_ADDR lui $t1, %hi(compressed) addiu $t1, %lo(compressed) - lw $t3, (GRUB_KERNEL_CPU_COMPRESSED_SIZE - BASE_ADDR)($ra) + lw $t3, (GRUB_KERNEL_CPU_COMPRESSED_SIZE - BASE_ADDR)($t9) /* $t2 contains source compressed address, $t1 is destination, - $t3 is compressed size. FIXME: put LZMA here. Don't clober $ra + $t3 is compressed size. FIXME: put LZMA here. Don't clober $t9 */ reloccont: lb $t4, 0($t2) @@ -61,7 +62,7 @@ reloccont: /* Move the modules out of BSS. */ lui $t1, %hi(_start) addiu $t1, %lo(_start) - lw $t2, (GRUB_KERNEL_CPU_KERNEL_IMAGE_SIZE - BASE_ADDR)($ra) + lw $t2, (GRUB_KERNEL_CPU_KERNEL_IMAGE_SIZE - BASE_ADDR)($t9) addu $t2, $t1, $t2 lui $t1, %hi(_end) @@ -73,7 +74,7 @@ reloccont: /* Pass modules address as first argument. */ // move $a0, $t1 - lw $t3, (GRUB_KERNEL_CPU_TOTAL_MODULE_SIZE - BASE_ADDR)($ra) + lw $t3, (GRUB_KERNEL_CPU_TOTAL_MODULE_SIZE - BASE_ADDR)($t9) /* Backward copy. */ add $t1, $t1, $t3 From 0fc89efd85045a99121df5003e4745086fea620c Mon Sep 17 00:00:00 2001 From: phcoder Date: Mon, 19 Oct 2009 12:59:33 +0200 Subject: [PATCH 044/738] use $t0-$t3 as arguments for relocator --- lib/mips/relocator.c | 12 ++++++------ lib/mips/relocator_asm.S | 36 ++++++++++++++++++------------------ 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/lib/mips/relocator.c b/lib/mips/relocator.c index b0fb4b2a5..4a67418c4 100644 --- a/lib/mips/relocator.c +++ b/lib/mips/relocator.c @@ -71,9 +71,9 @@ write_call_relocator_bw (void *ptr0, void *src, grub_uint32_t dest, { void *ptr = ptr0; int i; - write_reg (2, (grub_uint32_t) src, &ptr); - write_reg (3, dest, &ptr); - write_reg (4, size, &ptr); + write_reg (8, (grub_uint32_t) src, &ptr); + write_reg (9, dest, &ptr); + write_reg (10, size, &ptr); grub_memcpy (ptr, &grub_relocator32_backward_start, RELOCATOR_SRC_SIZEOF (backward)); ptr = (grub_uint8_t *) ptr + RELOCATOR_SRC_SIZEOF (backward); @@ -89,9 +89,9 @@ write_call_relocator_fw (void *ptr0, void *src, grub_uint32_t dest, { void *ptr = ptr0; int i; - write_reg (2, (grub_uint32_t) src, &ptr); - write_reg (3, dest, &ptr); - write_reg (4, size, &ptr); + write_reg (8, (grub_uint32_t) src, &ptr); + write_reg (9, dest, &ptr); + write_reg (10, size, &ptr); grub_memcpy (ptr, &grub_relocator32_forward_start, RELOCATOR_SRC_SIZEOF (forward)); ptr = (grub_uint8_t *) ptr + RELOCATOR_SRC_SIZEOF (forward); diff --git a/lib/mips/relocator_asm.S b/lib/mips/relocator_asm.S index 5503b4032..6f6108edc 100644 --- a/lib/mips/relocator_asm.S +++ b/lib/mips/relocator_asm.S @@ -28,32 +28,32 @@ VARIABLE (grub_relocator32_forward_start) copycont1: - lb $5,0($2) - sb $5,0($3) - addiu $2, $2, 0x1 - addiu $3, $3, 0x1 - addiu $4, $4, 0xffff - subu $5,$4,$0 - bne $5, $0, copycont1 + lb $11,0($8) + sb $11,0($9) + addiu $8, $8, 0x1 + addiu $9, $9, 0x1 + addiu $10, $10, 0xffff + subu $11,$10,$0 + bne $11, $0, copycont1 #if __mips >= 2 sync #endif VARIABLE (grub_relocator32_forward_end) VARIABLE (grub_relocator32_backward_start) - addu $3, $3, $4 - addu $2, $2, $4 + addu $9, $9, $10 + addu $8, $8, $10 /* Backward movsl is implicitly off-by-one. compensate that. */ - addiu $3, $3, 0xffff - addiu $2, $2, 0xffff + addiu $9, $9, 0xffff + addiu $8, $8, 0xffff copycont2: - lb $5,0($2) - sb $5,0($3) - addiu $2, $2, 0xffff - addiu $3, $3, 0xffff - addiu $4, 0xffff - subu $5,$4,$0 - bne $5, $0, copycont2 + lb $11,0($8) + sb $11,0($9) + addiu $8, $8, 0xffff + addiu $9, $9, 0xffff + addiu $10, 0xffff + subu $11,$10,$0 + bne $11, $0, copycont2 #if __mips >= 2 sync #endif From bb272a0f5db4b2ec075f25588f48b50dfe9b8387 Mon Sep 17 00:00:00 2001 From: phcoder Date: Mon, 19 Oct 2009 13:00:34 +0200 Subject: [PATCH 045/738] add linux argument passing --- loader/mips/linux.c | 130 ++++++++++++++++++++++---------------------- 1 file changed, 64 insertions(+), 66 deletions(-) diff --git a/loader/mips/linux.c b/loader/mips/linux.c index 3e526c699..b04249767 100644 --- a/loader/mips/linux.c +++ b/loader/mips/linux.c @@ -37,10 +37,8 @@ static int loaded; static grub_size_t initrd_size; static grub_size_t linux_size; -static char *linux_args; - static grub_uint8_t *playground; -static grub_addr_t target_addr, entry_addr, initrd_addr, args_addr; +static grub_addr_t target_addr, entry_addr, initrd_addr, argc_addr, argv_addr; static grub_err_t grub_linux_boot (void) @@ -49,6 +47,8 @@ grub_linux_boot (void) /* Boot the kernel. */ state.gpr[1] = entry_addr; + state.gpr[4] = argc_addr; + state.gpr[5] = argv_addr; state.jumpreg = 1; grub_relocator32_boot (playground, target_addr, state); @@ -77,10 +77,10 @@ grub_linux_unload (void) } static grub_err_t -grub_linux_load32 (grub_elf_t elf, char *args) +grub_linux_load32 (grub_elf_t elf, void **extra_mem, grub_size_t extra_size) { Elf32_Addr base; - int argsoff; + int extraoff; /* Linux's entry point incorrectly contains a virtual address. */ entry_addr = elf->ehdr.ehdr32.e_entry & ~ELF32_LOADMASK; @@ -91,15 +91,15 @@ grub_linux_load32 (grub_elf_t elf, char *args) target_addr = base; /* Pad it; the kernel scribbles over memory beyond its load address. */ linux_size += 0x100000; - argsoff = linux_size; - args_addr = target_addr + argsoff; - linux_size += grub_strlen (args) + 1; + linux_size = ALIGN_UP (base + linux_size, 4) - base; + extraoff = linux_size; + linux_size += extra_size; playground = grub_relocator32_alloc (linux_size); if (!playground) return grub_errno; - grub_memcpy (playground + argsoff, args, grub_strlen (args) + 1); + *extra_mem = playground + extraoff; /* Now load the segments into the area we claimed. */ auto grub_err_t offset_phdr (Elf32_Phdr *phdr, grub_addr_t *addr, int *do_load); @@ -121,10 +121,10 @@ grub_linux_load32 (grub_elf_t elf, char *args) } static grub_err_t -grub_linux_load64 (grub_elf_t elf, char *args) +grub_linux_load64 (grub_elf_t elf, void **extra_mem, grub_size_t extra_size) { Elf64_Addr base; - int argsoff; + int extraoff; /* Linux's entry point incorrectly contains a virtual address. */ entry_addr = elf->ehdr.ehdr64.e_entry & ~ELF64_LOADMASK; @@ -135,15 +135,15 @@ grub_linux_load64 (grub_elf_t elf, char *args) target_addr = base; /* Pad it; the kernel scribbles over memory beyond its load address. */ linux_size += 0x100000; - argsoff = linux_size; - args_addr = target_addr + argsoff; - linux_size += grub_strlen (args) + 1; + linux_size = ALIGN_UP (base + linux_size, 4) - base; + extraoff = linux_size; + linux_size += extra_size; playground = grub_relocator32_alloc (linux_size); if (!playground) return grub_errno; - grub_memcpy (playground + argsoff, args, grub_strlen (args) + 1); + *extra_mem = playground + extraoff; /* Now load the segments into the area we claimed. */ auto grub_err_t offset_phdr (Elf64_Phdr *phdr, grub_addr_t *addr, int *do_load); @@ -170,78 +170,76 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), grub_elf_t elf = 0; int i; int size; - char *dest; - - grub_dl_ref (my_mod); + void *extra; + grub_uint32_t *linux_argv; + char *linux_args; + grub_err_t err; if (argc == 0) - { - grub_error (GRUB_ERR_BAD_ARGUMENT, "no kernel specified"); - goto out; - } + return grub_error (GRUB_ERR_BAD_ARGUMENT, "no kernel specified"); elf = grub_elf_open (argv[0]); if (! elf) - goto out; + return grub_errno; if (elf->ehdr.ehdr32.e_type != ET_EXEC) { - grub_error (GRUB_ERR_UNKNOWN_OS, - "This ELF file is not of the right type\n"); - goto out; + grub_elf_close (elf); + return grub_error (GRUB_ERR_UNKNOWN_OS, + "This ELF file is not of the right type\n"); } /* Release the previously used memory. */ grub_loader_unset (); + loaded = 0; - size = sizeof ("BOOT_IMAGE=") + grub_strlen (argv[0]); - for (i = 0; i < argc; i++) - size += grub_strlen (argv[i]) + 1; + size = sizeof (grub_uint32_t) * argc + ALIGN_UP (sizeof ("g"), 4) + + sizeof (grub_uint32_t); + for (i = 1; i < argc; i++) + size += ALIGN_UP (grub_strlen (argv[i]) + 1, 4); - linux_args = grub_malloc (size); - if (! linux_args) - goto out; + if (grub_elf_is_elf32 (elf)) + err = grub_linux_load32 (elf, &extra, size); + else + if (grub_elf_is_elf64 (elf)) + err = grub_linux_load64 (elf, &extra, size); + else + err = grub_error (GRUB_ERR_BAD_FILE_TYPE, "Unknown ELF class"); - /* Specify the boot file. */ - dest = grub_stpcpy (linux_args, "BOOT_IMAGE="); - dest = grub_stpcpy (dest, argv[0]); + grub_elf_close (elf); + + if (err) + return err; + + *(grub_uint32_t *) extra = argc; + argc_addr = (grub_uint8_t *) extra - (grub_uint8_t *) playground + + target_addr; + extra = (grub_uint32_t *) extra + 1; + linux_argv = extra; + argv_addr = (grub_uint8_t *) linux_argv - (grub_uint8_t *) playground + + target_addr; + extra = linux_argv + argc; + linux_args = extra; + + *linux_argv = (grub_uint32_t) linux_args; + grub_memcpy (linux_args, "g", sizeof ("g")); + linux_args += ALIGN_UP (sizeof ("g"), 4); + linux_argv++; for (i = 1; i < argc; i++) { - *dest++ = ' '; - dest = grub_stpcpy (dest, argv[i]); + *linux_argv = (grub_uint32_t) linux_args; + grub_memcpy (linux_args, argv[i], grub_strlen (argv[i]) + 1); + linux_args += ALIGN_UP (grub_strlen (argv[i]) + 1, 4); + linux_argv++; } - if (grub_elf_is_elf32 (elf)) - grub_linux_load32 (elf, linux_args); - else - if (grub_elf_is_elf64 (elf)) - grub_linux_load64 (elf, linux_args); - else - { - grub_error (GRUB_ERR_BAD_FILE_TYPE, "Unknown ELF class"); - goto out; - } + grub_loader_set (grub_linux_boot, grub_linux_unload, 1); + initrd_addr = 0; + loaded = 1; + grub_dl_ref (my_mod); -out: - - if (elf) - grub_elf_close (elf); - - if (grub_errno != GRUB_ERR_NONE) - { - grub_linux_release_mem (); - grub_dl_unref (my_mod); - loaded = 0; - } - else - { - grub_loader_set (grub_linux_boot, grub_linux_unload, 1); - initrd_addr = 0; - loaded = 1; - } - - return grub_errno; + return GRUB_ERR_NONE; } static grub_err_t From e145631831d8fb04dae96a4a106d8a1f901e90ac Mon Sep 17 00:00:00 2001 From: phcoder Date: Mon, 19 Oct 2009 13:03:38 +0200 Subject: [PATCH 046/738] pci for yeeloong --- include/grub/mips/pci.h | 71 +------------------------------- include/grub/mips/yeeloong/pci.h | 71 ++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+), 70 deletions(-) create mode 100644 include/grub/mips/yeeloong/pci.h diff --git a/include/grub/mips/pci.h b/include/grub/mips/pci.h index 38a95a467..8b49d8479 100644 --- a/include/grub/mips/pci.h +++ b/include/grub/mips/pci.h @@ -1,70 +1 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2008 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_CPU_PCI_H -#define GRUB_CPU_PCI_H 1 - -#include -#include - -#define GRUB_PCI_ADDR_REG 0x14000cf8 -#define GRUB_PCI_DATA_REG 0x14000cfc - -static inline grub_uint32_t -grub_pci_read (grub_pci_address_t addr) -{ - grub_outl (addr, GRUB_PCI_ADDR_REG); - return grub_inl (GRUB_PCI_DATA_REG); -} - -static inline grub_uint16_t -grub_pci_read_word (grub_pci_address_t addr) -{ - grub_outl (addr & ~3, GRUB_PCI_ADDR_REG); - return grub_inw (GRUB_PCI_DATA_REG + (addr & 3)); -} - -static inline grub_uint8_t -grub_pci_read_byte (grub_pci_address_t addr) -{ - grub_outl (addr & ~3, GRUB_PCI_ADDR_REG); - return grub_inb (GRUB_PCI_DATA_REG + (addr & 3)); -} - -static inline void -grub_pci_write (grub_pci_address_t addr, grub_uint32_t data) -{ - grub_outl (addr, GRUB_PCI_ADDR_REG); - grub_outl (data, GRUB_PCI_DATA_REG); -} - -static inline void -grub_pci_write_word (grub_pci_address_t addr, grub_uint16_t data) -{ - grub_outl (addr & ~3, GRUB_PCI_ADDR_REG); - grub_outw (data, GRUB_PCI_DATA_REG + (addr & 3)); -} - -static inline void -grub_pci_write_byte (grub_pci_address_t addr, grub_uint8_t data) -{ - grub_outl (addr & ~3, GRUB_PCI_ADDR_REG); - grub_outb (data, GRUB_PCI_DATA_REG + (addr & 3)); -} - -#endif /* GRUB_CPU_PCI_H */ +#include diff --git a/include/grub/mips/yeeloong/pci.h b/include/grub/mips/yeeloong/pci.h new file mode 100644 index 000000000..f65d3bf38 --- /dev/null +++ b/include/grub/mips/yeeloong/pci.h @@ -0,0 +1,71 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_MACHINE_PCI_H +#define GRUB_MACHINE_PCI_H 1 + +#include +#include + +#define GRUB_MACHINE_PCI_IOSPACE 0xbfe80000 +#define GRUB_MACHINE_PCI_CONTROL_REG (*(grub_uint32_t *) 0x1fe00118) + + +static inline grub_uint32_t +grub_pci_read (grub_pci_address_t addr) +{ + GRUB_MACHINE_PCI_CONTROL_REG = addr >> 16; + return *(grub_uint32_t *) (GRUB_PCI_IOSPACE | (addr & 0xffff)); +} + +static inline grub_uint16_t +grub_pci_read_word (grub_pci_address_t addr) +{ + GRUB_MACHINE_PCI_CONTROL_REG = addr >> 16; + return *(grub_uint16_t *) (GRUB_PCI_IOSPACE | (addr & 0xffff)); +} + +static inline grub_uint8_t +grub_pci_read_byte (grub_pci_address_t addr) +{ + GRUB_MACHINE_PCI_CONTROL_REG = addr >> 16; + return *(grub_uint8_t *) (GRUB_PCI_IOSPACE | (addr & 0xffff)); +} + +static inline void +grub_pci_write (grub_pci_address_t addr, grub_uint32_t data) +{ + GRUB_MACHINE_PCI_CONTROL_REG = addr >> 16; + *(grub_uint32_t *) (GRUB_PCI_IOSPACE | (addr & 0xffff)) = data; +} + +static inline void +grub_pci_write_word (grub_pci_address_t addr, grub_uint16_t data) +{ + GRUB_MACHINE_PCI_CONTROL_REG = addr >> 16; + *(grub_uint16_t *) (GRUB_PCI_IOSPACE | (addr & 0xffff)) = data; +} + +static inline void +grub_pci_write_byte (grub_pci_address_t addr, grub_uint8_t data) +{ + GRUB_MACHINE_PCI_CONTROL_REG = addr >> 16; + *(grub_uint8_t *) (GRUB_PCI_IOSPACE | (addr & 0xffff)) = data; +} + +#endif /* GRUB_MACHINE_PCI_H */ From 82b1f15b6b41defc86f6800b7d3139323962b7fd Mon Sep 17 00:00:00 2001 From: phcoder Date: Mon, 19 Oct 2009 13:06:16 +0200 Subject: [PATCH 047/738] declaration fix --- include/grub/mips/yeeloong/pci.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/include/grub/mips/yeeloong/pci.h b/include/grub/mips/yeeloong/pci.h index f65d3bf38..bbe7bc202 100644 --- a/include/grub/mips/yeeloong/pci.h +++ b/include/grub/mips/yeeloong/pci.h @@ -30,42 +30,42 @@ static inline grub_uint32_t grub_pci_read (grub_pci_address_t addr) { GRUB_MACHINE_PCI_CONTROL_REG = addr >> 16; - return *(grub_uint32_t *) (GRUB_PCI_IOSPACE | (addr & 0xffff)); + return *(grub_uint32_t *) (GRUB_MACHINE_PCI_IOSPACE | (addr & 0xffff)); } static inline grub_uint16_t grub_pci_read_word (grub_pci_address_t addr) { GRUB_MACHINE_PCI_CONTROL_REG = addr >> 16; - return *(grub_uint16_t *) (GRUB_PCI_IOSPACE | (addr & 0xffff)); + return *(grub_uint16_t *) (GRUB_MACHINE_PCI_IOSPACE | (addr & 0xffff)); } static inline grub_uint8_t grub_pci_read_byte (grub_pci_address_t addr) { GRUB_MACHINE_PCI_CONTROL_REG = addr >> 16; - return *(grub_uint8_t *) (GRUB_PCI_IOSPACE | (addr & 0xffff)); + return *(grub_uint8_t *) (GRUB_MACHINE_PCI_IOSPACE | (addr & 0xffff)); } static inline void grub_pci_write (grub_pci_address_t addr, grub_uint32_t data) { GRUB_MACHINE_PCI_CONTROL_REG = addr >> 16; - *(grub_uint32_t *) (GRUB_PCI_IOSPACE | (addr & 0xffff)) = data; + *(grub_uint32_t *) (GRUB_MACHINE_PCI_IOSPACE | (addr & 0xffff)) = data; } static inline void grub_pci_write_word (grub_pci_address_t addr, grub_uint16_t data) { GRUB_MACHINE_PCI_CONTROL_REG = addr >> 16; - *(grub_uint16_t *) (GRUB_PCI_IOSPACE | (addr & 0xffff)) = data; + *(grub_uint16_t *) (GRUB_MACHINE_PCI_IOSPACE | (addr & 0xffff)) = data; } static inline void grub_pci_write_byte (grub_pci_address_t addr, grub_uint8_t data) { GRUB_MACHINE_PCI_CONTROL_REG = addr >> 16; - *(grub_uint8_t *) (GRUB_PCI_IOSPACE | (addr & 0xffff)) = data; + *(grub_uint8_t *) (GRUB_MACHINE_PCI_IOSPACE | (addr & 0xffff)) = data; } #endif /* GRUB_MACHINE_PCI_H */ From 6592e23a4e95ae82fc24ed34a033f2e11da4ab75 Mon Sep 17 00:00:00 2001 From: phcoder Date: Mon, 19 Oct 2009 16:38:07 +0200 Subject: [PATCH 048/738] usb on mipsel --- bus/usb/ohci.c | 23 +++++++++++++---------- conf/mips.rmk | 37 +++++++++++++++++++++++++++++++++++++ term/usb_keyboard.c | 1 - 3 files changed, 50 insertions(+), 11 deletions(-) diff --git a/bus/usb/ohci.c b/bus/usb/ohci.c index 32fb7cf91..f13156455 100644 --- a/bus/usb/ohci.c +++ b/bus/usb/ohci.c @@ -27,6 +27,8 @@ #include #include +#define vtop(x) ((x) & 0x7fffffff) + struct grub_ohci_hcca { /* Pointers to Interrupt Endpoint Descriptors. Not used by @@ -178,7 +180,7 @@ grub_ohci_pci_iter (int bus, int device, int func, grub_ohci_writereg32 (o, GRUB_OHCI_REG_FRAME_INTERVAL, frame_interval); /* Setup the HCCA. */ - grub_ohci_writereg32 (o, GRUB_OHCI_REG_HCCA, (grub_uint32_t) o->hcca); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_HCCA, vtop ((grub_uint32_t) o->hcca)); grub_dprintf ("ohci", "OHCI HCCA\n"); /* Enable the OHCI. */ @@ -264,10 +266,10 @@ grub_ohci_transaction (grub_ohci_td_t td, buffer = (grub_uint32_t) data; buffer_end = buffer + size - 1; - td->token = grub_cpu_to_le32 (token); - td->buffer = grub_cpu_to_le32 (buffer); + td->token = grub_cpu_to_le32 (vtop (token)); + td->buffer = grub_cpu_to_le32 (vtop (buffer)); td->next_td = 0; - td->buffer_end = grub_cpu_to_le32 (buffer_end); + td->buffer_end = grub_cpu_to_le32 (vtop (buffer_end)); } static grub_usb_err_t @@ -307,7 +309,7 @@ grub_ohci_transfer (grub_usb_controller_t dev, grub_ohci_transaction (&td_list[i], tr->pid, tr->toggle, tr->size, tr->data); - td_list[i].next_td = grub_cpu_to_le32 (&td_list[i + 1]); + td_list[i].next_td = grub_cpu_to_le32 (vtop (&td_list[i + 1])); } /* Setup the Endpoint Descriptor. */ @@ -324,9 +326,9 @@ grub_ohci_transfer (grub_usb_controller_t dev, /* Set the maximum packet size. */ target |= transfer->max << 16; - td_head = (grub_uint32_t) td_list; + td_head = vtop ((grub_uint32_t) td_list); - td_tail = (grub_uint32_t) &td_list[transfer->transcnt]; + td_tail = vtop ((grub_uint32_t) &td_list[transfer->transcnt]); ed->target = grub_cpu_to_le32 (target); ed->td_head = grub_cpu_to_le32 (td_head); @@ -353,7 +355,8 @@ grub_ohci_transfer (grub_usb_controller_t dev, status &= ~(1 << 2); grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, status); - grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKHEAD, (grub_uint32_t) ed); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKHEAD, + vtop ((grub_uint32_t) ed)); /* Enable the Bulk list. */ control |= 1 << 5; @@ -381,9 +384,9 @@ grub_ohci_transfer (grub_usb_controller_t dev, grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, status); grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD, - (grub_uint32_t) ed); + vtop ((grub_uint32_t) ed)); grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD+1, - (grub_uint32_t) ed); + vtop ((grub_uint32_t) ed)); /* Enable the Control list. */ control |= 1 << 4; diff --git a/conf/mips.rmk b/conf/mips.rmk index 553256a9b..f63e9bafc 100644 --- a/conf/mips.rmk +++ b/conf/mips.rmk @@ -148,6 +148,43 @@ pci_mod_SOURCES = bus/pci.c pci_mod_CFLAGS = $(COMMON_CFLAGS) pci_mod_LDFLAGS = $(COMMON_LDFLAGS) +# For lspci.mod +pkglib_MODULES += lspci.mod +lspci_mod_SOURCES = commands/lspci.c +lspci_mod_CFLAGS = $(COMMON_CFLAGS) +lspci_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For ohci.mod +pkglib_MODULES += ohci.mod +ohci_mod_SOURCES = bus/usb/ohci.c +ohci_mod_CFLAGS = $(COMMON_CFLAGS) +ohci_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For usb.mod +pkglib_MODULES += usb.mod +usb_mod_SOURCES = bus/usb/usb.c bus/usb/usbtrans.c bus/usb/usbhub.c +usb_mod_CFLAGS = $(COMMON_CFLAGS) +usb_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For usbtest.mod +pkglib_MODULES += usbtest.mod +usbtest_mod_SOURCES = commands/usbtest.c +usbtest_mod_CFLAGS = $(COMMON_CFLAGS) +usbtest_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For usbms.mod +pkglib_MODULES += usbms.mod +usbms_mod_SOURCES = disk/usbms.c +usbms_mod_CFLAGS = $(COMMON_CFLAGS) +usbms_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For usb_keyboard.mod +pkglib_MODULES += usb_keyboard.mod +usb_keyboard_mod_SOURCES = term/usb_keyboard.c +usb_keyboard_mod_CFLAGS = $(COMMON_CFLAGS) +usb_keyboard_mod_LDFLAGS = $(COMMON_LDFLAGS) + + # For relocator.mod. pkglib_MODULES += relocator.mod relocator_mod_SOURCES = lib/$(target_cpu)/relocator.c lib/$(target_cpu)/relocator_asm.S diff --git a/term/usb_keyboard.c b/term/usb_keyboard.c index 76b9bc3d4..e1842e995 100644 --- a/term/usb_keyboard.c +++ b/term/usb_keyboard.c @@ -19,7 +19,6 @@ #include #include -#include #include #include #include From 0b0b59d8d8d3e60060008624ec354b7a725dbeef Mon Sep 17 00:00:00 2001 From: phcoder Date: Mon, 19 Oct 2009 16:39:13 +0200 Subject: [PATCH 049/738] add ptov for symetry --- bus/usb/ohci.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bus/usb/ohci.c b/bus/usb/ohci.c index f13156455..4c844d089 100644 --- a/bus/usb/ohci.c +++ b/bus/usb/ohci.c @@ -28,6 +28,7 @@ #include #define vtop(x) ((x) & 0x7fffffff) +#define ptov(x) ((x) | 0x80000000) struct grub_ohci_hcca { @@ -154,7 +155,7 @@ grub_ohci_pci_iter (int bus, int device, int func, if (! o) return 1; - o->iobase = (grub_uint32_t *) base; + o->iobase = (grub_uint32_t *) ptov (base); /* Reserve memory for the HCCA. */ o->hcca = (struct grub_ohci_hcca *) grub_memalign (256, 256); From 7c8f6c181c420b1545a9783605dd78cccc1822b6 Mon Sep 17 00:00:00 2001 From: phcoder Date: Mon, 19 Oct 2009 18:07:58 +0200 Subject: [PATCH 050/738] initial envp support --- loader/mips/linux.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/loader/mips/linux.c b/loader/mips/linux.c index b04249767..056eca793 100644 --- a/loader/mips/linux.c +++ b/loader/mips/linux.c @@ -38,7 +38,8 @@ static grub_size_t initrd_size; static grub_size_t linux_size; static grub_uint8_t *playground; -static grub_addr_t target_addr, entry_addr, initrd_addr, argc_addr, argv_addr; +static grub_addr_t target_addr, entry_addr, initrd_addr, argc_addr; +static grub_addr_t argv_addr, envp_addr; static grub_err_t grub_linux_boot (void) @@ -49,6 +50,7 @@ grub_linux_boot (void) state.gpr[1] = entry_addr; state.gpr[4] = argc_addr; state.gpr[5] = argv_addr; + state.gpr[6] = envp_addr; state.jumpreg = 1; grub_relocator32_boot (playground, target_addr, state); @@ -171,7 +173,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), int i; int size; void *extra; - grub_uint32_t *linux_argv; + grub_uint32_t *linux_argv, *linux_envp; char *linux_args; grub_err_t err; @@ -194,7 +196,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), loaded = 0; size = sizeof (grub_uint32_t) * argc + ALIGN_UP (sizeof ("g"), 4) - + sizeof (grub_uint32_t); + + sizeof (grub_uint32_t) + (0 + 1) * sizeof (grub_uint32_t); for (i = 1; i < argc; i++) size += ALIGN_UP (grub_strlen (argv[i]) + 1, 4); @@ -221,19 +223,27 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), extra = linux_argv + argc; linux_args = extra; - *linux_argv = (grub_uint32_t) linux_args; + *linux_argv = (grub_uint8_t *) linux_args - (grub_uint8_t *) playground + + target_addr; grub_memcpy (linux_args, "g", sizeof ("g")); linux_args += ALIGN_UP (sizeof ("g"), 4); linux_argv++; for (i = 1; i < argc; i++) { - *linux_argv = (grub_uint32_t) linux_args; + *linux_argv = (grub_uint8_t *) linux_args - (grub_uint8_t *) playground + + target_addr; grub_memcpy (linux_args, argv[i], grub_strlen (argv[i]) + 1); linux_args += ALIGN_UP (grub_strlen (argv[i]) + 1, 4); linux_argv++; } + extra = linux_args; + linux_envp = extra; + envp_addr = (grub_uint8_t *) linux_envp - (grub_uint8_t *) playground + + target_addr; + linux_envp[0] = 0; + grub_loader_set (grub_linux_boot, grub_linux_unload, 1); initrd_addr = 0; loaded = 1; From b0000ec899cd31f1777d9b976a5b0265d39ce339 Mon Sep 17 00:00:00 2001 From: phcoder Date: Mon, 19 Oct 2009 18:08:22 +0200 Subject: [PATCH 051/738] compile error fix --- bus/usb/ohci.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bus/usb/ohci.c b/bus/usb/ohci.c index 4c844d089..388f65928 100644 --- a/bus/usb/ohci.c +++ b/bus/usb/ohci.c @@ -310,7 +310,8 @@ grub_ohci_transfer (grub_usb_controller_t dev, grub_ohci_transaction (&td_list[i], tr->pid, tr->toggle, tr->size, tr->data); - td_list[i].next_td = grub_cpu_to_le32 (vtop (&td_list[i + 1])); + td_list[i].next_td = grub_cpu_to_le32 (vtop ((grub_addr_t) + &td_list[i + 1])); } /* Setup the Endpoint Descriptor. */ From 1e4f46c162ed5d9bb5b425927104788d7d93498b Mon Sep 17 00:00:00 2001 From: phcoder Date: Mon, 19 Oct 2009 18:08:44 +0200 Subject: [PATCH 052/738] fixed pci base address --- include/grub/mips/yeeloong/pci.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/grub/mips/yeeloong/pci.h b/include/grub/mips/yeeloong/pci.h index bbe7bc202..fd6718c63 100644 --- a/include/grub/mips/yeeloong/pci.h +++ b/include/grub/mips/yeeloong/pci.h @@ -23,7 +23,7 @@ #include #define GRUB_MACHINE_PCI_IOSPACE 0xbfe80000 -#define GRUB_MACHINE_PCI_CONTROL_REG (*(grub_uint32_t *) 0x1fe00118) +#define GRUB_MACHINE_PCI_CONTROL_REG (*(grub_uint32_t *) 0xbfe00118) static inline grub_uint32_t From 81d1980198ce7c068d2ed6e32552c52d531dbf9e Mon Sep 17 00:00:00 2001 From: phcoder Date: Mon, 19 Oct 2009 18:09:13 +0200 Subject: [PATCH 053/738] changed rate of pseudo-clockk to avoid USB stalls --- kern/mips/yeeloong/init.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/kern/mips/yeeloong/init.c b/kern/mips/yeeloong/init.c index eece6076c..0b2bff051 100644 --- a/kern/mips/yeeloong/init.c +++ b/kern/mips/yeeloong/init.c @@ -15,8 +15,9 @@ grub_uint32_t grub_get_rtc (void) { - static int calln = 0; - return calln++; + static grub_uint64_t calln = 0; + + return (calln++) >> 8; } void From 061282ed1107d411c90ca3a19bdb93327b5376ab Mon Sep 17 00:00:00 2001 From: phcoder Date: Thu, 22 Oct 2009 17:10:54 +0200 Subject: [PATCH 054/738] bonito impl. I/O cleanup --- bus/bonito.c | 90 ++++++++++++++++++++++++++++++++ conf/mips.rmk | 6 --- include/grub/mips/io.h | 12 ++--- include/grub/mips/yeeloong/pci.h | 58 +++++++++++++++----- 4 files changed, 140 insertions(+), 26 deletions(-) create mode 100644 bus/bonito.c diff --git a/bus/bonito.c b/bus/bonito.c new file mode 100644 index 000000000..a7a530de1 --- /dev/null +++ b/bus/bonito.c @@ -0,0 +1,90 @@ +/* bonito.c - PCI bonito interface. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include + +static grub_uint32_t base_win[GRUB_MACHINE_PCI_NUM_WIN]; +static const grub_size_t sizes_win[GRUB_MACHINE_PCI_NUM_WIN] = + {GRUB_MACHINE_PCI_WIN1_SIZE, GRUB_MACHINE_PCI_WIN_SIZE, + GRUB_MACHINE_PCI_WIN_SIZE}; +/* Usage counters. */ +static int usage_win[GRUB_MACHINE_PCI_NUM_WIN]; +static grub_addr_t addr_win[GRUB_MACHINE_PCI_NUM_WIN] = + {GRUB_MACHINE_PCI_WIN1_ADDR, GRUB_MACHINE_PCI_WIN2_ADDR, + GRUB_MACHINE_PCI_WIN3_ADDR}; + +static inline void +write_bases (void) +{ + int i; + grub_uint32_t reg = 0; + for (i = 0; i < GRUB_MACHINE_PCI_NUM_WIN; i++) + reg |= (((base_win[i] >> GRUB_MACHINE_PCI_WIN_SHIFT) + & GRUB_MACHINE_PCI_WIN_MASK) + >> (i * GRUB_MACHINE_PCI_WIN_MASK_SIZE)); + GRUB_MACHINE_PCI_IO_CTRL_REG = reg; +} + +void * +grub_pci_device_map_range (grub_pci_device_t dev __attribute__ ((unused)), + grub_addr_t base, grub_size_t size) +{ + int i; + grub_addr_t newbase; + + /* First try already used registers. */ + for (i = 0; i < GRUB_MACHINE_PCI_NUM_WIN; i++) + if (usage_win[i] && base_win[i] <= base + && base_win[i] + sizes_win[i] > base + size) + { + usage_win[i]++; + return (void *) + (addr_win[i] | (base & GRUB_MACHINE_PCI_WIN_OFFSET_MASK)); + } + /* Map new register. */ + newbase = base & ~GRUB_MACHINE_PCI_WIN_OFFSET_MASK; + for (i = 0; i < GRUB_MACHINE_PCI_NUM_WIN; i++) + if (!usage_win[i] && newbase <= base + && newbase + sizes_win[i] > base + size) + { + usage_win[i]++; + base_win[i] = newbase; + write_bases (); + return (void *) + (addr_win[i] | (base & GRUB_MACHINE_PCI_WIN_OFFSET_MASK)); + } + grub_fatal ("Out of PCI windows."); +} + +void +grub_pci_device_unmap_range (grub_pci_device_t dev __attribute__ ((unused)), + void *mem __attribute__ ((unused)), + grub_size_t size __attribute__ ((unused))) +{ + int i; + for (i = 0; i < GRUB_MACHINE_PCI_NUM_WIN; i++) + if (usage_win[i] && addr_win[i] + == (((grub_addr_t) mem) & ~GRUB_MACHINE_PCI_WIN_OFFSET_MASK)) + { + usage_win[i]--; + return; + } + grub_fatal ("Tried to unmap not mapped region"); +} diff --git a/conf/mips.rmk b/conf/mips.rmk index f63e9bafc..19ed78237 100644 --- a/conf/mips.rmk +++ b/conf/mips.rmk @@ -142,12 +142,6 @@ ata_mod_SOURCES = disk/ata.c ata_mod_CFLAGS = $(COMMON_CFLAGS) ata_mod_LDFLAGS = $(COMMON_LDFLAGS) -# For pci.mod. -pkglib_MODULES += pci.mod -pci_mod_SOURCES = bus/pci.c -pci_mod_CFLAGS = $(COMMON_CFLAGS) -pci_mod_LDFLAGS = $(COMMON_LDFLAGS) - # For lspci.mod pkglib_MODULES += lspci.mod lspci_mod_SOURCES = commands/lspci.c diff --git a/include/grub/mips/io.h b/include/grub/mips/io.h index b86452c0a..dee76bde5 100644 --- a/include/grub/mips/io.h +++ b/include/grub/mips/io.h @@ -26,37 +26,37 @@ typedef grub_addr_t grub_port_t; static __inline unsigned char grub_inb (grub_port_t port) { - return *(grub_uint8_t *) port; + return *(volatile grub_uint8_t *) port; } static __inline unsigned short int grub_inw (grub_port_t port) { - return *(grub_uint16_t *) port; + return *(volatile grub_uint16_t *) port; } static __inline unsigned int grub_inl (grub_port_t port) { - return *(grub_uint32_t *) port; + return *(volatile grub_uint32_t *) port; } static __inline void grub_outb (unsigned char value, grub_port_t port) { - *(grub_uint8_t *) port = value; + *(volatile grub_uint8_t *) port = value; } static __inline void grub_outw (unsigned short int value, grub_port_t port) { - *(grub_uint16_t *) port = value; + *(volatile grub_uint16_t *) port = value; } static __inline void grub_outl (unsigned int value, grub_port_t port) { - *(grub_uint32_t *) port = value; + *(volatile grub_uint32_t *) port = value; } #endif /* _SYS_IO_H */ diff --git a/include/grub/mips/yeeloong/pci.h b/include/grub/mips/yeeloong/pci.h index fd6718c63..9970d6ee0 100644 --- a/include/grub/mips/yeeloong/pci.h +++ b/include/grub/mips/yeeloong/pci.h @@ -22,50 +22,80 @@ #include #include -#define GRUB_MACHINE_PCI_IOSPACE 0xbfe80000 -#define GRUB_MACHINE_PCI_CONTROL_REG (*(grub_uint32_t *) 0xbfe00118) +#define GRUB_MACHINE_PCI_CONFSPACE 0xbfe80000 +#define GRUB_MACHINE_PCI_CONF_CTRL_REG (*(volatile grub_uint32_t *) 0xbfe00118) +#define GRUB_MACHINE_PCI_IO_CTRL_REG (*(volatile grub_uint32_t *) 0xbfe00110) +#define GRUB_MACHINE_PCI_WIN_MASK_SIZE 6 +#define GRUB_MACHINE_PCI_WIN_MASK ((1 << GRUB_MACHINE_PCI_WIN_MASK_SIZE) - 1) +/* We have 3 PCI windows. */ +#define GRUB_MACHINE_PCI_NUM_WIN 3 +/* Each window is 64MiB. */ +#define GRUB_MACHINE_PCI_WIN_SHIFT 26 +#define GRUB_MACHINE_PCI_WIN_OFFSET_MASK ((1 << GRUB_MACHINE_PCI_WIN_SHIFT) - 1) + +#define GRUB_MACHINE_PCI_WIN_SIZE 0x04000000 +/* Graphical acceleration takes 1 MiB away. */ +#define GRUB_MACHINE_PCI_WIN1_SIZE 0x03f00000 + +#define GRUB_MACHINE_PCI_WIN1_ADDR 0xb0000000 +#define GRUB_MACHINE_PCI_WIN2_ADDR 0xb4000000 +#define GRUB_MACHINE_PCI_WIN3_ADDR 0xb8000000 static inline grub_uint32_t grub_pci_read (grub_pci_address_t addr) { - GRUB_MACHINE_PCI_CONTROL_REG = addr >> 16; - return *(grub_uint32_t *) (GRUB_MACHINE_PCI_IOSPACE | (addr & 0xffff)); + GRUB_MACHINE_PCI_CONF_CTRL_REG = addr >> 16; + return *(volatile grub_uint32_t *) (GRUB_MACHINE_PCI_CONFSPACE + | (addr & 0xffff)); } static inline grub_uint16_t grub_pci_read_word (grub_pci_address_t addr) { - GRUB_MACHINE_PCI_CONTROL_REG = addr >> 16; - return *(grub_uint16_t *) (GRUB_MACHINE_PCI_IOSPACE | (addr & 0xffff)); + GRUB_MACHINE_PCI_CONF_CTRL_REG = addr >> 16; + return *(volatile grub_uint16_t *) (GRUB_MACHINE_PCI_CONFSPACE + | (addr & 0xffff)); } static inline grub_uint8_t grub_pci_read_byte (grub_pci_address_t addr) { - GRUB_MACHINE_PCI_CONTROL_REG = addr >> 16; - return *(grub_uint8_t *) (GRUB_MACHINE_PCI_IOSPACE | (addr & 0xffff)); + GRUB_MACHINE_PCI_CONF_CTRL_REG = addr >> 16; + return *(volatile grub_uint8_t *) (GRUB_MACHINE_PCI_CONFSPACE + | (addr & 0xffff)); } static inline void grub_pci_write (grub_pci_address_t addr, grub_uint32_t data) { - GRUB_MACHINE_PCI_CONTROL_REG = addr >> 16; - *(grub_uint32_t *) (GRUB_MACHINE_PCI_IOSPACE | (addr & 0xffff)) = data; + GRUB_MACHINE_PCI_CONF_CTRL_REG = addr >> 16; + *(volatile grub_uint32_t *) (GRUB_MACHINE_PCI_CONFSPACE + | (addr & 0xffff)) = data; } static inline void grub_pci_write_word (grub_pci_address_t addr, grub_uint16_t data) { - GRUB_MACHINE_PCI_CONTROL_REG = addr >> 16; - *(grub_uint16_t *) (GRUB_MACHINE_PCI_IOSPACE | (addr & 0xffff)) = data; + GRUB_MACHINE_PCI_CONF_CTRL_REG = addr >> 16; + *(volatile grub_uint16_t *) (GRUB_MACHINE_PCI_CONFSPACE + | (addr & 0xffff)) = data; } static inline void grub_pci_write_byte (grub_pci_address_t addr, grub_uint8_t data) { - GRUB_MACHINE_PCI_CONTROL_REG = addr >> 16; - *(grub_uint8_t *) (GRUB_MACHINE_PCI_IOSPACE | (addr & 0xffff)) = data; + GRUB_MACHINE_PCI_CONF_CTRL_REG = addr >> 16; + *(volatile grub_uint8_t *) (GRUB_MACHINE_PCI_CONFSPACE + | (addr & 0xffff)) = data; } +void * +grub_pci_device_map_range (grub_pci_device_t dev __attribute__ ((unused)), + grub_addr_t base, grub_size_t size); +void +grub_pci_device_unmap_range (grub_pci_device_t dev __attribute__ ((unused)), + void *mem, + grub_size_t size __attribute__ ((unused))); + #endif /* GRUB_MACHINE_PCI_H */ From 5855d253f4f7bcb815eedfd083ff4a24a9f1a063 Mon Sep 17 00:00:00 2001 From: phcoder Date: Fri, 23 Oct 2009 18:20:04 +0200 Subject: [PATCH 055/738] elf format --- util/grub-mkrawimage.c | 133 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 119 insertions(+), 14 deletions(-) diff --git a/util/grub-mkrawimage.c b/util/grub-mkrawimage.c index 0d26e3cf4..2097cefeb 100644 --- a/util/grub-mkrawimage.c +++ b/util/grub-mkrawimage.c @@ -22,6 +22,8 @@ #include #include #include +#include +#include #include #include #include @@ -91,7 +93,14 @@ compress_kernel (char *kernel_img, size_t kernel_size, static void generate_image (const char *dir, char *prefix, FILE *out, char *mods[], - char *memdisk_path, char *config_path) + char *memdisk_path, char *config_path, +#ifdef GRUB_PLATFORM_IMAGE_DEFAULT + grub_platform_image_format_t format +#else + int dummy __attribute__ ((unused)) +#endif + +) { char *kernel_img, *core_img; size_t kernel_size, total_module_size, core_size; @@ -211,10 +220,9 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], boot_img = grub_util_read_image (boot_path); - /* i386 is a little endian architecture. */ *((grub_uint16_t *) (boot_img + GRUB_DISK_SECTOR_SIZE - GRUB_BOOT_MACHINE_LIST_SIZE + 8)) - = grub_cpu_to_le16 (num); + = grub_host_to_target16 (num); grub_util_write_image (boot_img, boot_size, out); free (boot_img); @@ -238,12 +246,12 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], memset (rom_img, 0, rom_size); *((grub_int32_t *) (core_img + GRUB_KERNEL_MACHINE_CORE_ENTRY_ADDR)) - = grub_cpu_to_le32 ((grub_uint32_t) -rom_size); + = grub_host_to_target32 ((grub_uint32_t) -rom_size); memcpy (rom_img, core_img, core_size); *((grub_int32_t *) (boot_img + GRUB_BOOT_MACHINE_CORE_ENTRY_ADDR)) - = grub_cpu_to_le32 ((grub_uint32_t) -rom_size); + = grub_host_to_target32 ((grub_uint32_t) -rom_size); memcpy (rom_img + rom_size - boot_size, boot_img, boot_size); @@ -254,18 +262,17 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], free (boot_img); free (boot_path); } - #endif #ifdef GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE *((grub_uint32_t *) (core_img + GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE)) - = grub_cpu_to_le32 (total_module_size); + = grub_host_to_target32 (total_module_size); #endif *((grub_uint32_t *) (core_img + GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE)) - = grub_cpu_to_le32 (kernel_size); + = grub_host_to_target32 (kernel_size); #ifdef GRUB_KERNEL_MACHINE_COMPRESSED_SIZE *((grub_uint32_t *) (core_img + GRUB_KERNEL_MACHINE_COMPRESSED_SIZE)) - = grub_cpu_to_le32 (core_size - GRUB_KERNEL_MACHINE_RAW_SIZE); + = grub_host_to_target32 (core_size - GRUB_KERNEL_MACHINE_RAW_SIZE); #endif #if defined(GRUB_KERNEL_MACHINE_INSTALL_DOS_PART) && defined(GRUB_KERNEL_MACHINE_INSTALL_BSD_PART) @@ -274,9 +281,9 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], if (prefix[0] == '(') { *((grub_int32_t *) (core_img + GRUB_KERNEL_MACHINE_INSTALL_DOS_PART)) - = grub_cpu_to_le32 (-2); + = grub_host_to_target32 (-2); *((grub_int32_t *) (core_img + GRUB_KERNEL_MACHINE_INSTALL_BSD_PART)) - = grub_cpu_to_le32 (-2); + = grub_host_to_target32 (-2); } #endif @@ -286,6 +293,68 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], GRUB_KERNEL_MACHINE_LINK_ADDR + core_size, GRUB_MEMORY_MACHINE_UPPER); #endif +#if defined(GRUB_MACHINE_MIPS) + if (format == GRUB_PLATFORM_IMAGE_ELF) + { + char *elf_img; + size_t program_size; + Elf32_Ehdr *ehdr; + Elf32_Phdr *phdr; + grub_uint32_t target_addr; + + program_size = ALIGN_UP (core_size, 4); + + elf_img = xmalloc (program_size + sizeof (*ehdr) + sizeof (*phdr)); + memset (elf_img, 0, program_size + sizeof (*ehdr) + sizeof (*phdr)); + memcpy (elf_img + sizeof (*ehdr) + sizeof (*phdr), core_img, core_size); + ehdr = (void *) elf_img; + phdr = (void *) (elf_img + sizeof (*ehdr)); + memcpy (ehdr->e_ident, ELFMAG, SELFMAG); + ehdr->e_ident[EI_CLASS] = ELFCLASS32; +#ifdef GRUB_CPU_MIPSEL + ehdr->e_ident[EI_DATA] = ELFDATA2LSB; +#else + ehdr->e_ident[EI_DATA] = ELFDATA2MSB; +#endif + ehdr->e_ident[EI_VERSION] = EV_CURRENT; + ehdr->e_ident[EI_OSABI] = ELFOSABI_NONE; + ehdr->e_type = grub_host_to_target16 (ET_EXEC); + ehdr->e_machine = grub_host_to_target16 (EM_MIPS); + ehdr->e_version = grub_host_to_target32 (EV_CURRENT); + + ehdr->e_phoff = grub_host_to_target32 ((char *) phdr - (char *) ehdr); + ehdr->e_phentsize = grub_host_to_target16 (sizeof (*phdr)); + ehdr->e_phnum = grub_host_to_target16 (1); + + /* No section headers. */ + ehdr->e_shoff = grub_host_to_target32 (0); + ehdr->e_shentsize = grub_host_to_target16 (0); + ehdr->e_shnum = grub_host_to_target16 (0); + ehdr->e_shstrndx = grub_host_to_target16 (0); + + ehdr->e_ehsize = grub_host_to_target16 (sizeof (*ehdr)); + + phdr->p_type = grub_host_to_target32 (PT_LOAD); + phdr->p_offset = grub_host_to_target32 (sizeof (*ehdr) + sizeof (*phdr)); + phdr->p_flags = grub_host_to_target32 (PF_R | PF_W | PF_X); + + target_addr = ALIGN_UP (GRUB_KERNEL_MACHINE_LINK_ADDR + + kernel_size + total_module_size, 32); + ehdr->e_entry = grub_host_to_target32 (target_addr); + phdr->p_vaddr = grub_host_to_target32 (target_addr); + phdr->p_paddr = grub_host_to_target32 (target_addr); + phdr->p_align = grub_host_to_target32 (GRUB_KERNEL_MACHINE_LINK_ALIGN); + ehdr->e_flags = grub_host_to_target32 (0x1000 | EF_MIPS_NOREORDER + | EF_MIPS_PIC | EF_MIPS_CPIC); + phdr->p_filesz = grub_host_to_target32 (core_size); + phdr->p_memsz = grub_host_to_target32 (core_size); + + free (core_img); + core_img = elf_img; + core_size = program_size + sizeof (*ehdr) + sizeof (*phdr); + } +#endif + grub_util_write_image (core_img, core_size, out); free (kernel_img); free (core_img); @@ -309,6 +378,9 @@ static struct option options[] = {"memdisk", required_argument, 0, 'm'}, {"config", required_argument, 0, 'c'}, {"output", required_argument, 0, 'o'}, +#ifdef GRUB_PLATFORM_IMAGE_DEFAULT + {"format", required_argument, 0, 'f'}, +#endif {"help", no_argument, 0, 'h'}, {"version", no_argument, 0, 'V'}, {"verbose", no_argument, 0, 'v'}, @@ -330,7 +402,15 @@ Make a bootable image of GRUB.\n\ -p, --prefix=DIR set grub_prefix directory [default=%s]\n\ -m, --memdisk=FILE embed FILE as a memdisk image\n\ -c, --config=FILE embed FILE as boot config\n\ - -o, --output=FILE output a generated image to FILE [default=stdout]\n\ + -o, --output=FILE output a generated image to FILE [default=stdout]\n" +#ifdef GRUB_PLATFORM_IMAGE_DEFAULT + "\ + -f, --format=FORMAT generate an image in format [default=" + GRUB_PLATFORM_IMAGE_DEFAULT_FORMAT "]\n \ + available formats: " + GRUB_PLATFORM_IMAGE_FORMATS "\n" +#endif + "\ -h, --help display this message and exit\n\ -V, --version print version information and exit\n\ -v, --verbose print verbose messages\n\ @@ -350,12 +430,15 @@ main (int argc, char *argv[]) char *memdisk = NULL; char *config = NULL; FILE *fp = stdout; +#ifdef GRUB_PLATFORM_IMAGE_DEFAULT + grub_platform_image_format_t format = GRUB_PLATFORM_IMAGE_DEFAULT; +#endif progname = "grub-mkimage"; while (1) { - int c = getopt_long (argc, argv, "d:p:m:c:o:hVv", options, 0); + int c = getopt_long (argc, argv, "d:p:m:c:o:f:hVv", options, 0); if (c == -1) break; @@ -369,6 +452,22 @@ main (int argc, char *argv[]) output = xstrdup (optarg); break; +#ifdef GRUB_PLATFORM_IMAGE_DEFAULT + case 'f': +#ifdef GRUB_PLATFORM_IMAGE_RAW + if (strcmp (optarg, "raw") == 0) + format = GRUB_PLATFORM_IMAGE_RAW; + else +#endif +#ifdef GRUB_PLATFORM_IMAGE_ELF + if (strcmp (optarg, "elf") == 0) + format = GRUB_PLATFORM_IMAGE_ELF; + else +#endif + usage (1); + break; +#endif + case 'd': if (dir) free (dir); @@ -429,7 +528,13 @@ main (int argc, char *argv[]) } generate_image (dir ? : GRUB_LIBDIR, prefix ? : DEFAULT_DIRECTORY, fp, - argv + optind, memdisk, config); + argv + optind, memdisk, config, +#ifdef GRUB_PLATFORM_IMAGE_DEFAULT + format +#else + 0 +#endif + ); fclose (fp); From 270bd79ca79d2b2fa951ed0e3a2cd3409a5f5d50 Mon Sep 17 00:00:00 2001 From: phcoder Date: Fri, 23 Oct 2009 18:20:52 +0200 Subject: [PATCH 056/738] kernel constants updated --- include/grub/mips/kernel.h | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/include/grub/mips/kernel.h b/include/grub/mips/kernel.h index 4a7c9293c..29f7e4d4e 100644 --- a/include/grub/mips/kernel.h +++ b/include/grub/mips/kernel.h @@ -19,10 +19,12 @@ #ifndef GRUB_KERNEL_CPU_HEADER #define GRUB_KERNEL_CPU_HEADER 1 -#define GRUB_MOD_ALIGN 0x1000 +#define GRUB_MOD_ALIGN 0x1 /* Non-zero value is only needed for PowerMacs. */ #define GRUB_MOD_GAP 0x0 +#define GRUB_KERNEL_MACHINE_LINK_ALIGN 32 + #define GRUB_KERNEL_CPU_RAW_SIZE 0x100 #define GRUB_KERNEL_CPU_COMPRESSED_SIZE 0x8 #define GRUB_KERNEL_CPU_TOTAL_MODULE_SIZE 0xc @@ -39,8 +41,21 @@ #define GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE GRUB_KERNEL_CPU_TOTAL_MODULE_SIZE #define GRUB_KERNEL_MACHINE_COMPRESSED_SIZE GRUB_KERNEL_CPU_COMPRESSED_SIZE +#define GRUB_PLATFORM_IMAGE_FORMATS "raw, elf" +#define GRUB_PLATFORM_IMAGE_DEFAULT_FORMAT "raw" + +#define GRUB_PLATFORM_IMAGE_DEFAULT GRUB_PLATFORM_IMAGE_RAW + #ifndef ASM_FILE +typedef enum { + GRUB_PLATFORM_IMAGE_RAW, + GRUB_PLATFORM_IMAGE_ELF +} + grub_platform_image_format_t; +#define GRUB_PLATFORM_IMAGE_RAW GRUB_PLATFORM_IMAGE_RAW +#define GRUB_PLATFORM_IMAGE_ELF GRUB_PLATFORM_IMAGE_ELF + /* The prefix which points to the directory where GRUB modules and its configuration file are located. */ extern char grub_prefix[]; From f0628ef04f3b2f3d043b76855ed2362a0e8fdd0e Mon Sep 17 00:00:00 2001 From: phcoder Date: Fri, 23 Oct 2009 18:21:15 +0200 Subject: [PATCH 057/738] additional "machines" --- include/grub/mips/yeeloong/machine.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/grub/mips/yeeloong/machine.h b/include/grub/mips/yeeloong/machine.h index 9f29b4a46..f20d9d210 100644 --- a/include/grub/mips/yeeloong/machine.h +++ b/include/grub/mips/yeeloong/machine.h @@ -20,5 +20,7 @@ #define GRUB_MACHINE_MACHINE_HEADER 1 #define GRUB_MACHINE_MIPS_YEELOONG 1 +#define GRUB_MACHINE_MIPS 1 +#define GRUB_MACHINE_MIPS_BONITO 1 #endif /* ! GRUB_MACHINE_MACHINE_HEADER */ From e95fcb5379226014a7ca4d003d2ac5ab402a4305 Mon Sep 17 00:00:00 2001 From: phcoder Date: Sat, 24 Oct 2009 10:44:00 +0200 Subject: [PATCH 058/738] move common init function to kern/mips/init.c --- kern/mips/init.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 kern/mips/init.c diff --git a/kern/mips/init.c b/kern/mips/init.c new file mode 100644 index 000000000..5adcedcbb --- /dev/null +++ b/kern/mips/init.c @@ -0,0 +1,35 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include + +void +grub_machine_set_prefix (void) +{ + grub_env_set ("prefix", grub_prefix); +} + +extern char _end[]; + +grub_addr_t +grub_arch_modules_addr (void) +{ + return (grub_addr_t) _end; +} From 01e825cc4b2e8a227c13f7dfcf3ccfcffc1121d5 Mon Sep 17 00:00:00 2001 From: phcoder Date: Sat, 24 Oct 2009 10:44:32 +0200 Subject: [PATCH 059/738] basic framebuffer support --- video/sm712.c | 197 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 197 insertions(+) create mode 100644 video/sm712.c diff --git a/video/sm712.c b/video/sm712.c new file mode 100644 index 000000000..5ebd865b7 --- /dev/null +++ b/video/sm712.c @@ -0,0 +1,197 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2006,2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#define grub_video_render_target grub_video_fbrender_target + +#include +#include +#include +#include +#include +#include +#include +#include + +static struct +{ + struct grub_video_mode_info mode_info; + struct grub_video_render_target *render_target; + + unsigned int bytes_per_scan_line; + unsigned int bytes_per_pixel; + grub_uint8_t *ptr; + int index_color_mode; + int mapped; + grub_pci_device_t dev; +} framebuffer; + +static grub_err_t +grub_video_sm712_video_init (void) +{ + /* Reset frame buffer. */ + grub_memset (&framebuffer, 0, sizeof(framebuffer)); + + return grub_video_fb_init (); +} + +static grub_err_t +grub_video_sm712_video_fini (void) +{ + if (framebuffer.mapped) + grub_pci_device_unmap_range (framebuffer.dev, framebuffer.ptr, + 1024 * 600 * 2); + + return grub_video_fb_fini (); +} + +static grub_err_t +grub_video_sm712_setup (unsigned int width, unsigned int height, + unsigned int mode_type) +{ + int depth; + grub_err_t err; + + /* Decode depth from mode_type. If it is zero, then autodetect. */ + depth = (mode_type & GRUB_VIDEO_MODE_TYPE_DEPTH_MASK) + >> GRUB_VIDEO_MODE_TYPE_DEPTH_POS; + + if ((1024 != width && width != 0) || (600 != height && height != 0) + || (16 != depth && depth != 0)) + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "Only 1024x600x16 is supported"); + + /* Fill mode info details. */ + framebuffer.mode_info.width = 1024; + framebuffer.mode_info.height = 600; + framebuffer.mode_info.mode_type = GRUB_VIDEO_MODE_TYPE_RGB; + framebuffer.mode_info.bpp = 16; + framebuffer.mode_info.bytes_per_pixel = 2; + framebuffer.mode_info.pitch = 1024 * 2; + framebuffer.mode_info.number_of_colors = 256; + framebuffer.mode_info.red_mask_size = 5; + framebuffer.mode_info.red_field_pos = 11; + framebuffer.mode_info.green_mask_size = 6; + framebuffer.mode_info.green_field_pos = 5; + framebuffer.mode_info.blue_mask_size = 5; + framebuffer.mode_info.blue_field_pos = 0; + framebuffer.mode_info.reserved_mask_size = 0; + framebuffer.mode_info.reserved_field_pos = 0; + framebuffer.mode_info.blit_format = grub_video_get_blit_format (&framebuffer.mode_info); + *(volatile grub_uint32_t *) 0xbfe00110 = 1; + framebuffer.ptr = (void *) 0xb0000000; + // framebuffer.ptr = grub_pci_device_map_range (framebuffer.dev, 1 << 26, + // 1024 * 600 * 2); + framebuffer.mapped = 1; + + err = grub_video_fb_create_render_target_from_pointer (&framebuffer.render_target, &framebuffer.mode_info, framebuffer.ptr); + + if (err) + return err; + + err = grub_video_fb_set_active_render_target (framebuffer.render_target); + + if (err) + return err; + + /* Copy default palette to initialize emulated palette. */ + err = grub_video_fb_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS, + grub_video_fbstd_colors); + return err; +} + +static grub_err_t +grub_video_sm712_set_palette (unsigned int start, unsigned int count, + struct grub_video_palette_data *palette_data) +{ + if (framebuffer.index_color_mode) + { + /* TODO: Implement setting indexed color mode palette to hardware. */ + } + + /* Then set color to emulated palette. */ + return grub_video_fb_set_palette (start, count, palette_data); +} + +static grub_err_t +grub_video_sm712_swap_buffers (void) +{ + /* TODO: Implement buffer swapping. */ + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_video_sm712_set_active_render_target (struct grub_video_render_target *target) +{ + if (target == GRUB_VIDEO_RENDER_TARGET_DISPLAY) + target = framebuffer.render_target; + + return grub_video_fb_set_active_render_target (target); +} + +static grub_err_t +grub_video_sm712_get_info_and_fini (struct grub_video_mode_info *mode_info, + void **framebuf) +{ + grub_memcpy (mode_info, &(framebuffer.mode_info), sizeof (*mode_info)); + *framebuf = (char *) framebuffer.ptr; + + grub_video_fb_fini (); + + return GRUB_ERR_NONE; +} + + +static struct grub_video_adapter grub_video_sm712_adapter = + { + .name = "SM712 Video Driver", + + .init = grub_video_sm712_video_init, + .fini = grub_video_sm712_video_fini, + .setup = grub_video_sm712_setup, + .get_info = grub_video_fb_get_info, + .get_info_and_fini = grub_video_sm712_get_info_and_fini, + .set_palette = grub_video_sm712_set_palette, + .get_palette = grub_video_fb_get_palette, + .set_viewport = grub_video_fb_set_viewport, + .get_viewport = grub_video_fb_get_viewport, + .map_color = grub_video_fb_map_color, + .map_rgb = grub_video_fb_map_rgb, + .map_rgba = grub_video_fb_map_rgba, + .unmap_color = grub_video_fb_unmap_color, + .fill_rect = grub_video_fb_fill_rect, + .blit_bitmap = grub_video_fb_blit_bitmap, + .blit_render_target = grub_video_fb_blit_render_target, + .scroll = grub_video_fb_scroll, + .swap_buffers = grub_video_sm712_swap_buffers, + .create_render_target = grub_video_fb_create_render_target, + .delete_render_target = grub_video_fb_delete_render_target, + .set_active_render_target = grub_video_sm712_set_active_render_target, + .get_active_render_target = grub_video_fb_get_active_render_target, + + .next = 0 + }; + +GRUB_MOD_INIT(video_sm712) +{ + grub_video_register (&grub_video_sm712_adapter); +} + +GRUB_MOD_FINI(video_sm712) +{ + grub_video_unregister (&grub_video_sm712_adapter); +} From 8bf6643e526b112344fa80d906bdbbd662d8fd36 Mon Sep 17 00:00:00 2001 From: phcoder Date: Sat, 24 Oct 2009 10:45:54 +0200 Subject: [PATCH 060/738] untracked rmk file added --- conf/mips-yeeloong.rmk | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 conf/mips-yeeloong.rmk diff --git a/conf/mips-yeeloong.rmk b/conf/mips-yeeloong.rmk new file mode 100644 index 000000000..95ec26522 --- /dev/null +++ b/conf/mips-yeeloong.rmk @@ -0,0 +1,18 @@ +# -*- makefile -*- +LINK_BASE = 0x80200000 +target_machine=yeeloong +COMMON_CFLAGS += -march=mips3 +COMMON_ASFLAGS += -march=mips3 +include $(srcdir)/conf/mips.mk + +# For pci.mod. +pkglib_MODULES += pci.mod +pci_mod_SOURCES = bus/pci.c bus/bonito.c +pci_mod_CFLAGS = $(COMMON_CFLAGS) +pci_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For pci.mod. +pkglib_MODULES += sm712.mod +sm712_mod_SOURCES = video/sm712.c +sm712_mod_CFLAGS = $(COMMON_CFLAGS) +sm712_mod_LDFLAGS = $(COMMON_LDFLAGS) From 1e1ddb6cb924e1b8d260f6e5029766b2b02bf5d2 Mon Sep 17 00:00:00 2001 From: phcoder Date: Sat, 24 Oct 2009 10:56:21 +0200 Subject: [PATCH 061/738] init fixes --- kern/mips/yeeloong/init.c | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/kern/mips/yeeloong/init.c b/kern/mips/yeeloong/init.c index 0b2bff051..01acd4f1c 100644 --- a/kern/mips/yeeloong/init.c +++ b/kern/mips/yeeloong/init.c @@ -1,3 +1,21 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + #include #include #include @@ -51,26 +69,11 @@ grub_reboot (void) while (1); } -void -grub_machine_set_prefix (void) -{ - grub_env_set ("prefix", grub_prefix); -} - -extern char _end[]; - -grub_addr_t -grub_arch_modules_addr (void) -{ - return ALIGN_UP((grub_addr_t) _end + GRUB_MOD_GAP, GRUB_MOD_ALIGN); -} - grub_err_t grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t)) { - hook (0, RAMSIZE, - GRUB_MACHINE_MEMORY_AVAILABLE); + hook (0, RAMSIZE, GRUB_MACHINE_MEMORY_AVAILABLE); return GRUB_ERR_NONE; } From e6efd24fa0f23115fe0c96dbd6cea87da61d03d7 Mon Sep 17 00:00:00 2001 From: phcoder Date: Sat, 24 Oct 2009 10:58:20 +0200 Subject: [PATCH 062/738] working but suboptimal cache flusher --- kern/mips/cache.S | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/kern/mips/cache.S b/kern/mips/cache.S index ec13a9b95..e4436450f 100644 --- a/kern/mips/cache.S +++ b/kern/mips/cache.S @@ -3,7 +3,12 @@ /* FIXME: This should invalidate only part of memory. */ FUNCTION (grub_cpu_flush_cache) FUNCTION (grub_arch_sync_caches) -#if __mips >= 2 - sync -#endif +repeat: + cache 1, 0($a0) + cache 0, 0($a0) + cache 3, 0($a0) + cache 0, 0($a0) + addiu $a0, $a0, 1 + addiu $a1, $a1, 0xffff + bne $a1, $zero, repeat j $31 From 3c842eea9f9881f48866ed6a77536e4bd13a3ec6 Mon Sep 17 00:00:00 2001 From: phcoder Date: Sat, 24 Oct 2009 12:43:49 +0200 Subject: [PATCH 063/738] fixed rmk --- conf/mips.rmk | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/conf/mips.rmk b/conf/mips.rmk index 19ed78237..cba8281e8 100644 --- a/conf/mips.rmk +++ b/conf/mips.rmk @@ -1,8 +1,8 @@ # -*- makefile -*- -COMMON_ASFLAGS = -nostdinc -COMMON_CFLAGS = -mexplicit-relocs -mflush-func=grub_cpu_flush_cache +COMMON_ASFLAGS += -nostdinc +COMMON_CFLAGS += -mexplicit-relocs -mflush-func=grub_cpu_flush_cache COMMON_LDFLAGS += -nostdlib # Used by various components. These rules need to precede them. @@ -85,7 +85,8 @@ grub_emu_SOURCES = commands/minicmd.c commands/cat.c commands/cmp.c \ grub_emu_LDFLAGS = $(LIBCURSES) kernel_img_SOURCES = kern/$(target_cpu)/startup.S \ - kern/main.c kern/device.c kern/$(target_cpu)/$(target_machine)/init.c \ + kern/main.c kern/device.c kern/$(target_cpu)/init.c \ + kern/$(target_cpu)/$(target_machine)/init.c \ kern/disk.c kern/dl.c kern/err.c kern/file.c kern/fs.c \ kern/misc.c kern/mm.c kern/reader.c kern/term.c \ kern/rescue_parser.c kern/rescue_reader.c \ @@ -107,7 +108,7 @@ bin_SCRIPTS = bin_UTILITIES += grub-mkimage grub_mkimage_SOURCES = util/grub-mkrawimage.c util/misc.c \ util/resolve.c lib/LzmaEnc.c lib/LzFind.c -grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR) +grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(LINK_BASE) util/i386/pc/grub-mkimage.c_DEPENDENCIES = Makefile # Modules. @@ -178,7 +179,6 @@ usb_keyboard_mod_SOURCES = term/usb_keyboard.c usb_keyboard_mod_CFLAGS = $(COMMON_CFLAGS) usb_keyboard_mod_LDFLAGS = $(COMMON_LDFLAGS) - # For relocator.mod. pkglib_MODULES += relocator.mod relocator_mod_SOURCES = lib/$(target_cpu)/relocator.c lib/$(target_cpu)/relocator_asm.S From a9b7a540bd7214b31763ebe7d7dc8facb97438c3 Mon Sep 17 00:00:00 2001 From: phcoder Date: Sat, 24 Oct 2009 12:44:42 +0200 Subject: [PATCH 064/738] font preload --- font/font.c | 16 +--------- font/font_cmd.c | 70 ++++++++++++++++++++++++++++++++++++++++-- include/grub/font.h | 3 +- include/grub/kernel.h | 3 +- util/grub-mkrawimage.c | 49 ++++++++++++++++++++++++----- 5 files changed, 114 insertions(+), 27 deletions(-) diff --git a/font/font.c b/font/font.c index a81291916..a6cdf3c93 100644 --- a/font/font.c +++ b/font/font.c @@ -17,7 +17,6 @@ * along with GRUB. If not, see . */ -#include #include #include #include @@ -374,25 +373,12 @@ read_section_as_short (struct font_file_section *section, grub_int16_t *value) /* Load a font and add it to the beginning of the global font list. Returns 0 upon success, nonzero upon failure. */ int -grub_font_load (const char *filename) +grub_font_load (grub_file_t file) { - grub_file_t file = 0; struct font_file_section section; char magic[4]; grub_font_t font = 0; -#if FONT_DEBUG >= 1 - grub_printf("add_font(%s)\n", filename); -#endif - - file = grub_buffile_open (filename, 1024); - if (!file) - goto fail; - -#if FONT_DEBUG >= 3 - grub_printf("file opened\n"); -#endif - /* Read the FILE section. It indicates the file format. */ if (open_section (file, §ion) != 0) goto fail; diff --git a/font/font_cmd.c b/font/font_cmd.c index 0402b8d77..8b9817409 100644 --- a/font/font_cmd.c +++ b/font/font_cmd.c @@ -17,10 +17,13 @@ * along with GRUB. If not, see . */ +#include #include #include #include #include +#include +#include static grub_err_t loadfont_command (grub_command_t cmd __attribute__ ((unused)), @@ -31,8 +34,16 @@ loadfont_command (grub_command_t cmd __attribute__ ((unused)), return grub_error (GRUB_ERR_BAD_ARGUMENT, "no font specified"); while (argc--) - if (grub_font_load (*args++) != 0) - return GRUB_ERR_BAD_FONT; + { + grub_file_t file = 0; + + file = grub_buffile_open (*args++, 1024); + if (!file) + return grub_errno; + + if (grub_font_load (file) != 0) + return GRUB_ERR_BAD_FONT; + } return GRUB_ERR_NONE; } @@ -54,12 +65,67 @@ lsfonts_command (grub_command_t cmd __attribute__ ((unused)), return GRUB_ERR_NONE; } +static grub_ssize_t +pseudo_file_read (struct grub_file *file, char *buf, grub_size_t len) +{ + grub_memcpy (buf, (char *) file->data + file->offset, len); + return len; +} + +static grub_err_t +pseudo_file_close (struct grub_file *file) +{ + grub_free (file->data); + file->data = 0; + return GRUB_ERR_NONE; +} + + +/* Filesystem descriptor. */ +static struct grub_fs pseudo_fs = +{ + .name = "Font Loader", + .read = pseudo_file_read, + .close = pseudo_file_close +}; + + +static int +load_font_module (struct grub_module_header *header) +{ + grub_file_t file; + if (header->type != OBJ_TYPE_FONT) + return 0; + + file = grub_malloc (sizeof (*file)); + + file->read_hook = 0; + + file->offset = 0; + file->size = header->size - sizeof (struct grub_module_header); + file->data = grub_malloc (header->size - sizeof (struct grub_module_header)); + if (!file->data) + return 0; + grub_memcpy (file->data, (char *) header + sizeof (struct grub_module_header), + file->size); + + file->device = 0; + file->fs = &pseudo_fs; + + grub_font_load (file); + + return 0; +} + + static grub_command_t cmd_loadfont, cmd_lsfonts; GRUB_MOD_INIT(font_manager) { grub_font_loader_init (); + grub_module_iterate (load_font_module); + cmd_loadfont = grub_register_command ("loadfont", loadfont_command, "loadfont FILE...", diff --git a/include/grub/font.h b/include/grub/font.h index 8a5f3ac7d..2129c30b3 100644 --- a/include/grub/font.h +++ b/include/grub/font.h @@ -21,6 +21,7 @@ #include #include +#include /* Forward declaration of opaque structure grub_font. Users only pass struct grub_font pointers to the font module functions, @@ -74,7 +75,7 @@ void grub_font_loader_init (void); /* Load a font and add it to the beginning of the global font list. Returns: 0 upon success; nonzero upon failure. */ -int grub_font_load (const char *filename); +int grub_font_load (grub_file_t file); /* Get the font that has the specified name. Font names are in the form "Family Name Bold Italic 14", where Bold and Italic are optional. diff --git a/include/grub/kernel.h b/include/grub/kernel.h index 75ec77c2a..9586a90b9 100644 --- a/include/grub/kernel.h +++ b/include/grub/kernel.h @@ -26,7 +26,8 @@ enum { OBJ_TYPE_ELF, OBJ_TYPE_MEMDISK, - OBJ_TYPE_CONFIG + OBJ_TYPE_CONFIG, + OBJ_TYPE_FONT }; /* The module header. */ diff --git a/util/grub-mkrawimage.c b/util/grub-mkrawimage.c index 2097cefeb..5005afd1f 100644 --- a/util/grub-mkrawimage.c +++ b/util/grub-mkrawimage.c @@ -93,7 +93,7 @@ compress_kernel (char *kernel_img, size_t kernel_size, static void generate_image (const char *dir, char *prefix, FILE *out, char *mods[], - char *memdisk_path, char *config_path, + char *memdisk_path, char *font_path, char *config_path, #ifdef GRUB_PLATFORM_IMAGE_DEFAULT grub_platform_image_format_t format #else @@ -104,7 +104,7 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], { char *kernel_img, *core_img; size_t kernel_size, total_module_size, core_size; - size_t memdisk_size = 0, config_size = 0; + size_t memdisk_size = 0, font_size = 0, config_size = 0; char *kernel_path; size_t offset; struct grub_util_path_list *path_list, *p, *next; @@ -124,6 +124,12 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], total_module_size += memdisk_size + sizeof (struct grub_module_header); } + if (font_path) + { + font_size = ALIGN_UP(grub_util_get_image_size (font_path), 4); + total_module_size += font_size + sizeof (struct grub_module_header); + } + if (config_path) { config_size = grub_util_get_image_size (config_path) + 1; @@ -183,6 +189,20 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], offset += memdisk_size; } + if (font_path) + { + struct grub_module_header *header; + + header = (struct grub_module_header *) (kernel_img + offset); + memset (header, 0, sizeof (struct grub_module_header)); + header->type = OBJ_TYPE_FONT; + header->size = grub_host_to_target32 (font_size + sizeof (*header)); + offset += sizeof (*header); + + grub_util_load_image (font_path, kernel_img + offset); + offset += font_size; + } + if (config_path) { struct grub_module_header *header; @@ -339,7 +359,10 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], phdr->p_flags = grub_host_to_target32 (PF_R | PF_W | PF_X); target_addr = ALIGN_UP (GRUB_KERNEL_MACHINE_LINK_ADDR - + kernel_size + total_module_size, 32); + + kernel_size + total_module_size + + 0x100000 + // + BSS_SIZE + , 32); ehdr->e_entry = grub_host_to_target32 (target_addr); phdr->p_vaddr = grub_host_to_target32 (target_addr); phdr->p_paddr = grub_host_to_target32 (target_addr); @@ -376,10 +399,11 @@ static struct option options[] = {"directory", required_argument, 0, 'd'}, {"prefix", required_argument, 0, 'p'}, {"memdisk", required_argument, 0, 'm'}, + {"font", required_argument, 0, 'f'}, {"config", required_argument, 0, 'c'}, {"output", required_argument, 0, 'o'}, #ifdef GRUB_PLATFORM_IMAGE_DEFAULT - {"format", required_argument, 0, 'f'}, + {"format", required_argument, 0, 'O'}, #endif {"help", no_argument, 0, 'h'}, {"version", no_argument, 0, 'V'}, @@ -401,11 +425,12 @@ Make a bootable image of GRUB.\n\ -d, --directory=DIR use images and modules under DIR [default=%s]\n\ -p, --prefix=DIR set grub_prefix directory [default=%s]\n\ -m, --memdisk=FILE embed FILE as a memdisk image\n\ + -f, --font=FILE embed FILE as a boot font\n\ -c, --config=FILE embed FILE as boot config\n\ -o, --output=FILE output a generated image to FILE [default=stdout]\n" #ifdef GRUB_PLATFORM_IMAGE_DEFAULT "\ - -f, --format=FORMAT generate an image in format [default=" + -O, --format=FORMAT generate an image in format [default=" GRUB_PLATFORM_IMAGE_DEFAULT_FORMAT "]\n \ available formats: " GRUB_PLATFORM_IMAGE_FORMATS "\n" @@ -428,6 +453,7 @@ main (int argc, char *argv[]) char *dir = NULL; char *prefix = NULL; char *memdisk = NULL; + char *font = NULL; char *config = NULL; FILE *fp = stdout; #ifdef GRUB_PLATFORM_IMAGE_DEFAULT @@ -438,7 +464,7 @@ main (int argc, char *argv[]) while (1) { - int c = getopt_long (argc, argv, "d:p:m:c:o:f:hVv", options, 0); + int c = getopt_long (argc, argv, "d:p:m:c:o:O:f:hVv", options, 0); if (c == -1) break; @@ -453,7 +479,7 @@ main (int argc, char *argv[]) break; #ifdef GRUB_PLATFORM_IMAGE_DEFAULT - case 'f': + case 'O': #ifdef GRUB_PLATFORM_IMAGE_RAW if (strcmp (optarg, "raw") == 0) format = GRUB_PLATFORM_IMAGE_RAW; @@ -487,6 +513,13 @@ main (int argc, char *argv[]) prefix = xstrdup ("(memdisk)/boot/grub"); break; + case 'f': + if (font) + free (font); + + font = xstrdup (optarg); + break; + case 'c': if (config) free (config); @@ -528,7 +561,7 @@ main (int argc, char *argv[]) } generate_image (dir ? : GRUB_LIBDIR, prefix ? : DEFAULT_DIRECTORY, fp, - argv + optind, memdisk, config, + argv + optind, memdisk, font, config, #ifdef GRUB_PLATFORM_IMAGE_DEFAULT format #else From 1a5c44303c355c87b38088d981e46a75e35c0f32 Mon Sep 17 00:00:00 2001 From: phcoder Date: Sat, 24 Oct 2009 12:45:04 +0200 Subject: [PATCH 065/738] load modules before saying welcome --- kern/main.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/kern/main.c b/kern/main.c index 9215d55e7..084ce621b 100644 --- a/kern/main.c +++ b/kern/main.c @@ -152,15 +152,16 @@ grub_main (void) /* First of all, initialize the machine. */ grub_machine_init (); - /* Hello. */ - grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT); - grub_printf ("Welcome to GRUB!\n\n"); - grub_setcolorstate (GRUB_TERM_COLOR_STANDARD); - /* Load pre-loaded modules and free the space. */ grub_register_exported_symbols (); grub_load_modules (); + /* Hello. */ + grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT); + grub_printf ("Welcome to GRUB!\n\n"); + grub_refresh (); + grub_setcolorstate (GRUB_TERM_COLOR_STANDARD); + /* It is better to set the root device as soon as possible, for convenience. */ grub_machine_set_prefix (); From 1ec31f046e99d015fa36a5a1cfef9b80c3c2b74d Mon Sep 17 00:00:00 2001 From: phcoder Date: Sat, 24 Oct 2009 12:45:47 +0200 Subject: [PATCH 066/738] change gfxterm resolution --- term/gfxterm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/term/gfxterm.c b/term/gfxterm.c index f161499e6..277660016 100644 --- a/term/gfxterm.c +++ b/term/gfxterm.c @@ -27,7 +27,7 @@ #include #include -#define DEFAULT_VIDEO_MODE "1024x768,800x600,640x480" +#define DEFAULT_VIDEO_MODE "1024x600" #define DEFAULT_BORDER_WIDTH 10 #define DEFAULT_STANDARD_COLOR 0x07 From 8c4c25fe739701a462daabffdc3dd04879ee3ddd Mon Sep 17 00:00:00 2001 From: phcoder Date: Sat, 24 Oct 2009 15:16:38 +0200 Subject: [PATCH 067/738] use bonito for sm712 --- video/sm712.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/video/sm712.c b/video/sm712.c index 5ebd865b7..df4f50172 100644 --- a/video/sm712.c +++ b/video/sm712.c @@ -92,10 +92,8 @@ grub_video_sm712_setup (unsigned int width, unsigned int height, framebuffer.mode_info.reserved_mask_size = 0; framebuffer.mode_info.reserved_field_pos = 0; framebuffer.mode_info.blit_format = grub_video_get_blit_format (&framebuffer.mode_info); - *(volatile grub_uint32_t *) 0xbfe00110 = 1; - framebuffer.ptr = (void *) 0xb0000000; - // framebuffer.ptr = grub_pci_device_map_range (framebuffer.dev, 1 << 26, - // 1024 * 600 * 2); + framebuffer.ptr = grub_pci_device_map_range (framebuffer.dev, 1 << 26, + 1024 * 600 * 2); framebuffer.mapped = 1; err = grub_video_fb_create_render_target_from_pointer (&framebuffer.render_target, &framebuffer.mode_info, framebuffer.ptr); From 072acffa2099300fa5e9741b84a9383d05d868d8 Mon Sep 17 00:00:00 2001 From: phcoder Date: Sat, 24 Oct 2009 21:01:27 +0200 Subject: [PATCH 068/738] gfxterm fix --- term/gfxterm.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/term/gfxterm.c b/term/gfxterm.c index 277660016..20dc11c20 100644 --- a/term/gfxterm.c +++ b/term/gfxterm.c @@ -95,6 +95,7 @@ struct grub_virtual_screen /* Color settings. */ grub_video_color_t fg_color; grub_video_color_t bg_color; + grub_video_color_t bg_color_display; /* Text buffer for virtual screen. Contains (columns * rows) number of entries. */ @@ -237,6 +238,8 @@ grub_virtual_screen_setup (unsigned int x, unsigned int y, grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY); + virtual_screen.bg_color_display = grub_video_map_rgba(0, 0, 0, 0); + /* Clear out text buffer. */ for (i = 0; i < virtual_screen.columns * virtual_screen.rows; i++) clear_char (&(virtual_screen.text_buffer[i])); @@ -345,7 +348,7 @@ redraw_screen_rect (unsigned int x, unsigned int y, /* If bitmap is smaller than requested blit area, use background color. */ - color = virtual_screen.bg_color; + color = virtual_screen.bg_color_display; /* Fill right side of the bitmap if needed. */ if ((x + width >= bitmap_width) && (y < bitmap_height)) @@ -392,7 +395,7 @@ redraw_screen_rect (unsigned int x, unsigned int y, else { /* Render background layer. */ - color = virtual_screen.bg_color; + color = virtual_screen.bg_color_display; grub_video_fill_rect (color, x, y, width, height); /* Render text layer as replaced (to get texts background color). */ @@ -814,7 +817,8 @@ grub_gfxterm_cls (void) /* Clear text layer. */ grub_video_set_active_render_target (text_layer); color = virtual_screen.bg_color; - grub_video_fill_rect (color, 0, 0, mode_info.width, mode_info.height); + grub_video_fill_rect (color, 0, 0, virtual_screen.width, + virtual_screen.height); grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY); /* Mark virtual screen to be redrawn. */ From 810d8224cd2d1f117a34e62d573bbe503a1b1b41 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 2 Nov 2009 23:42:07 +0100 Subject: [PATCH 069/738] PCI cleanup --- bus/bonito.c | 4 ++-- bus/pci.c | 4 ++-- include/grub/i386/pci.h | 6 ++++-- include/grub/mips/yeeloong/pci.h | 31 +++++++++++++++++-------------- 4 files changed, 25 insertions(+), 20 deletions(-) diff --git a/bus/bonito.c b/bus/bonito.c index a7a530de1..3f794c45a 100644 --- a/bus/bonito.c +++ b/bus/bonito.c @@ -42,7 +42,7 @@ write_bases (void) GRUB_MACHINE_PCI_IO_CTRL_REG = reg; } -void * +volatile void * grub_pci_device_map_range (grub_pci_device_t dev __attribute__ ((unused)), grub_addr_t base, grub_size_t size) { @@ -75,7 +75,7 @@ grub_pci_device_map_range (grub_pci_device_t dev __attribute__ ((unused)), void grub_pci_device_unmap_range (grub_pci_device_t dev __attribute__ ((unused)), - void *mem __attribute__ ((unused)), + volatile void *mem __attribute__ ((unused)), grub_size_t size __attribute__ ((unused))) { int i; diff --git a/bus/pci.c b/bus/pci.c index fe4cad181..08bc90ab2 100644 --- a/bus/pci.c +++ b/bus/pci.c @@ -35,9 +35,9 @@ grub_pci_iterate (grub_pci_iteratefunc_t hook) grub_pci_id_t id; grub_uint32_t hdr; - for (dev.bus = 0; dev.bus < 256; dev.bus++) + for (dev.bus = 0; dev.bus < GRUB_PCI_NUM_BUS; dev.bus++) { - for (dev.device = 0; dev.device < 32; dev.device++) + for (dev.device = 0; dev.device < GRUB_PCI_NUM_DEVICES; dev.device++) { for (dev.function = 0; dev.function < 8; dev.function++) { diff --git a/include/grub/i386/pci.h b/include/grub/i386/pci.h index 5b5f5f0df..a62adf507 100644 --- a/include/grub/i386/pci.h +++ b/include/grub/i386/pci.h @@ -24,6 +24,8 @@ #define GRUB_PCI_ADDR_REG 0xcf8 #define GRUB_PCI_DATA_REG 0xcfc +#define GRUB_PCI_NUM_BUS 256 +#define GRUB_PCI_NUM_DEVICES 32 static inline grub_uint32_t grub_pci_read (grub_pci_address_t addr) @@ -67,12 +69,12 @@ grub_pci_write_byte (grub_pci_address_t addr, grub_uint8_t data) grub_outb (data, GRUB_PCI_DATA_REG + (addr & 3)); } -static inline void * +static inline volatile void * grub_pci_device_map_range (grub_pci_device_t dev __attribute__ ((unused)), grub_addr_t base, grub_size_t size __attribute__ ((unused))) { - return (void *) base; + return (volatile void *) base; } static inline void diff --git a/include/grub/mips/yeeloong/pci.h b/include/grub/mips/yeeloong/pci.h index 9970d6ee0..8ba9f39d8 100644 --- a/include/grub/mips/yeeloong/pci.h +++ b/include/grub/mips/yeeloong/pci.h @@ -22,6 +22,9 @@ #include #include +#define GRUB_PCI_NUM_BUS 1 +#define GRUB_PCI_NUM_DEVICES 16 + #define GRUB_MACHINE_PCI_CONFSPACE 0xbfe80000 #define GRUB_MACHINE_PCI_CONF_CTRL_REG (*(volatile grub_uint32_t *) 0xbfe00118) #define GRUB_MACHINE_PCI_IO_CTRL_REG (*(volatile grub_uint32_t *) 0xbfe00110) @@ -45,57 +48,57 @@ static inline grub_uint32_t grub_pci_read (grub_pci_address_t addr) { - GRUB_MACHINE_PCI_CONF_CTRL_REG = addr >> 16; + GRUB_MACHINE_PCI_CONF_CTRL_REG = 1 << ((addr >> 11) & 0xf); return *(volatile grub_uint32_t *) (GRUB_MACHINE_PCI_CONFSPACE - | (addr & 0xffff)); + | (addr & 0x03ff)); } static inline grub_uint16_t grub_pci_read_word (grub_pci_address_t addr) { - GRUB_MACHINE_PCI_CONF_CTRL_REG = addr >> 16; + GRUB_MACHINE_PCI_CONF_CTRL_REG = 1 << ((addr >> 11) & 0xf); return *(volatile grub_uint16_t *) (GRUB_MACHINE_PCI_CONFSPACE - | (addr & 0xffff)); + | (addr & 0x03ff)); } static inline grub_uint8_t grub_pci_read_byte (grub_pci_address_t addr) { - GRUB_MACHINE_PCI_CONF_CTRL_REG = addr >> 16; + GRUB_MACHINE_PCI_CONF_CTRL_REG = 1 << ((addr >> 11) & 0xf); return *(volatile grub_uint8_t *) (GRUB_MACHINE_PCI_CONFSPACE - | (addr & 0xffff)); + | (addr & 0x03ff)); } static inline void grub_pci_write (grub_pci_address_t addr, grub_uint32_t data) { - GRUB_MACHINE_PCI_CONF_CTRL_REG = addr >> 16; + GRUB_MACHINE_PCI_CONF_CTRL_REG = 1 << ((addr >> 11) & 0xf); *(volatile grub_uint32_t *) (GRUB_MACHINE_PCI_CONFSPACE - | (addr & 0xffff)) = data; + | (addr & 0x03ff)) = data; } static inline void grub_pci_write_word (grub_pci_address_t addr, grub_uint16_t data) { - GRUB_MACHINE_PCI_CONF_CTRL_REG = addr >> 16; + GRUB_MACHINE_PCI_CONF_CTRL_REG = 1 << ((addr >> 11) & 0xf); *(volatile grub_uint16_t *) (GRUB_MACHINE_PCI_CONFSPACE - | (addr & 0xffff)) = data; + | (addr & 0x03ff)) = data; } static inline void grub_pci_write_byte (grub_pci_address_t addr, grub_uint8_t data) { - GRUB_MACHINE_PCI_CONF_CTRL_REG = addr >> 16; + GRUB_MACHINE_PCI_CONF_CTRL_REG = 1 << ((addr >> 11) & 0xf); *(volatile grub_uint8_t *) (GRUB_MACHINE_PCI_CONFSPACE - | (addr & 0xffff)) = data; + | (addr & 0x03ff)) = data; } -void * +volatile void * grub_pci_device_map_range (grub_pci_device_t dev __attribute__ ((unused)), grub_addr_t base, grub_size_t size); void grub_pci_device_unmap_range (grub_pci_device_t dev __attribute__ ((unused)), - void *mem, + volatile void *mem, grub_size_t size __attribute__ ((unused))); #endif /* GRUB_MACHINE_PCI_H */ From 1b4595cebf919f2497be93858a4ec61a4c14db22 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 2 Nov 2009 23:57:09 +0100 Subject: [PATCH 070/738] AT keyboard support for Yeeloong --- conf/i386.rmk | 2 +- conf/mips.rmk | 6 ++++++ include/grub/i386/at_keyboard.h | 32 -------------------------------- term/{i386/pc => }/at_keyboard.c | 6 +++--- 4 files changed, 10 insertions(+), 36 deletions(-) rename term/{i386/pc => }/at_keyboard.c (98%) diff --git a/conf/i386.rmk b/conf/i386.rmk index 33d49b53c..15529a122 100644 --- a/conf/i386.rmk +++ b/conf/i386.rmk @@ -6,7 +6,7 @@ cpuid_mod_CFLAGS = $(COMMON_CFLAGS) cpuid_mod_LDFLAGS = $(COMMON_LDFLAGS) pkglib_MODULES += at_keyboard.mod -at_keyboard_mod_SOURCES = term/i386/pc/at_keyboard.c +at_keyboard_mod_SOURCES = term/at_keyboard.c at_keyboard_mod_CFLAGS = $(COMMON_CFLAGS) at_keyboard_mod_LDFLAGS = $(COMMON_LDFLAGS) diff --git a/conf/mips.rmk b/conf/mips.rmk index cba8281e8..03765ad8e 100644 --- a/conf/mips.rmk +++ b/conf/mips.rmk @@ -192,4 +192,10 @@ linux_mod_CFLAGS = $(COMMON_CFLAGS) linux_mod_ASFLAGS = $(COMMON_ASFLAGS) linux_mod_LDFLAGS = $(COMMON_LDFLAGS) +# For at_keyboard.mod. +pkglib_MODULES += at_keyboard.mod +at_keyboard_mod_SOURCES = term/at_keyboard.c +at_keyboard_mod_CFLAGS = $(COMMON_CFLAGS) +at_keyboard_mod_LDFLAGS = $(COMMON_LDFLAGS) + include $(srcdir)/conf/common.mk diff --git a/include/grub/i386/at_keyboard.h b/include/grub/i386/at_keyboard.h index 96b21627f..8769c2f11 100644 --- a/include/grub/i386/at_keyboard.h +++ b/include/grub/i386/at_keyboard.h @@ -19,39 +19,7 @@ #ifndef GRUB_CPU_AT_KEYBOARD_HEADER #define GRUB_CPU_AT_KEYBOARD_HEADER 1 -#include - -#define SHIFT_L 0x2a -#define SHIFT_R 0x36 -#define CTRL 0x1d -#define ALT 0x38 -#define CAPS_LOCK 0x3a - #define KEYBOARD_REG_DATA 0x60 #define KEYBOARD_REG_STATUS 0x64 -/* Used for sending commands to the controller. */ -#define KEYBOARD_COMMAND_ISREADY(x) !((x) & 0x02) -#define KEYBOARD_COMMAND_READ 0x20 -#define KEYBOARD_COMMAND_WRITE 0x60 -#define KEYBOARD_COMMAND_REBOOT 0xfe - -#define KEYBOARD_SCANCODE_SET1 0x40 - -#define KEYBOARD_ISMAKE(x) !((x) & 0x80) -#define KEYBOARD_ISREADY(x) ((x) & 0x01) -#define KEYBOARD_SCANCODE(x) ((x) & 0x7f) - -#ifdef GRUB_MACHINE_IEEE1275 -#define OLPC_UP GRUB_TERM_UP -#define OLPC_DOWN GRUB_TERM_DOWN -#define OLPC_LEFT GRUB_TERM_LEFT -#define OLPC_RIGHT GRUB_TERM_RIGHT -#else -#define OLPC_UP '\0' -#define OLPC_DOWN '\0' -#define OLPC_LEFT '\0' -#define OLPC_RIGHT '\0' -#endif - #endif diff --git a/term/i386/pc/at_keyboard.c b/term/at_keyboard.c similarity index 98% rename from term/i386/pc/at_keyboard.c rename to term/at_keyboard.c index cf30e7242..5d8dc3d89 100644 --- a/term/i386/pc/at_keyboard.c +++ b/term/at_keyboard.c @@ -17,9 +17,9 @@ */ #include -#include -#include -#include +#include +#include +#include #include #include From 811c0d8b5c09a2c887dd1bb61b28f3fa466c63e9 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 3 Nov 2009 00:00:59 +0100 Subject: [PATCH 071/738] missing kbd files --- include/grub/at_keyboard.h | 54 ++++++++++++++++++++++++ include/grub/mips/at_keyboard.h | 1 + include/grub/mips/yeeloong/at_keyboard.h | 25 +++++++++++ 3 files changed, 80 insertions(+) create mode 100644 include/grub/at_keyboard.h create mode 100644 include/grub/mips/at_keyboard.h create mode 100644 include/grub/mips/yeeloong/at_keyboard.h diff --git a/include/grub/at_keyboard.h b/include/grub/at_keyboard.h new file mode 100644 index 000000000..e2436e0f6 --- /dev/null +++ b/include/grub/at_keyboard.h @@ -0,0 +1,54 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2007,2008 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_AT_KEYBOARD_HEADER +#define GRUB_AT_KEYBOARD_HEADER 1 + +#include + +#define SHIFT_L 0x2a +#define SHIFT_R 0x36 +#define CTRL 0x1d +#define ALT 0x38 +#define CAPS_LOCK 0x3a + +/* Used for sending commands to the controller. */ +#define KEYBOARD_COMMAND_ISREADY(x) !((x) & 0x02) +#define KEYBOARD_COMMAND_READ 0x20 +#define KEYBOARD_COMMAND_WRITE 0x60 +#define KEYBOARD_COMMAND_REBOOT 0xfe + +#define KEYBOARD_SCANCODE_SET1 0x40 + +#define KEYBOARD_ISMAKE(x) !((x) & 0x80) +#define KEYBOARD_ISREADY(x) ((x) & 0x01) +#define KEYBOARD_SCANCODE(x) ((x) & 0x7f) + +#ifdef GRUB_MACHINE_IEEE1275 +#define OLPC_UP GRUB_TERM_UP +#define OLPC_DOWN GRUB_TERM_DOWN +#define OLPC_LEFT GRUB_TERM_LEFT +#define OLPC_RIGHT GRUB_TERM_RIGHT +#else +#define OLPC_UP '\0' +#define OLPC_DOWN '\0' +#define OLPC_LEFT '\0' +#define OLPC_RIGHT '\0' +#endif + +#endif diff --git a/include/grub/mips/at_keyboard.h b/include/grub/mips/at_keyboard.h new file mode 100644 index 000000000..0c307537d --- /dev/null +++ b/include/grub/mips/at_keyboard.h @@ -0,0 +1 @@ +#include diff --git a/include/grub/mips/yeeloong/at_keyboard.h b/include/grub/mips/yeeloong/at_keyboard.h new file mode 100644 index 000000000..f279ac86d --- /dev/null +++ b/include/grub/mips/yeeloong/at_keyboard.h @@ -0,0 +1,25 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_MACHINE_AT_KEYBOARD_HEADER +#define GRUB_MACHINE_AT_KEYBOARD_HEADER 1 + +#define KEYBOARD_REG_DATA 0xbfd00060 +#define KEYBOARD_REG_STATUS 0xbfd00064 + +#endif From b4f4e1f733902404241b4afd1889f0deb2a3f696 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 3 Nov 2009 00:03:09 +0100 Subject: [PATCH 072/738] Initial dirty ATA support --- conf/mips.rmk | 6 ++++++ disk/ata.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/conf/mips.rmk b/conf/mips.rmk index 03765ad8e..cd99cca75 100644 --- a/conf/mips.rmk +++ b/conf/mips.rmk @@ -198,4 +198,10 @@ at_keyboard_mod_SOURCES = term/at_keyboard.c at_keyboard_mod_CFLAGS = $(COMMON_CFLAGS) at_keyboard_mod_LDFLAGS = $(COMMON_LDFLAGS) +# For ata_pthru.mod. +pkglib_MODULES += ata_pthru.mod +ata_pthru_mod_SOURCES = disk/ata_pthru.c +ata_pthru_mod_CFLAGS = $(COMMON_CFLAGS) +ata_pthru_mod_LDFLAGS = $(COMMON_LDFLAGS) + include $(srcdir)/conf/common.mk diff --git a/disk/ata.c b/disk/ata.c index 00e370960..5b74bb673 100644 --- a/disk/ata.c +++ b/disk/ata.c @@ -27,8 +27,10 @@ #include /* At the moment, only two IDE ports are supported. */ -static const grub_port_t grub_ata_ioaddress[] = { 0x1f0, 0x170 }; -static const grub_port_t grub_ata_ioaddress2[] = { 0x3f6, 0x376 }; +static const grub_port_t grub_ata_ioaddress[] = { 0xbfd001f0}; +static const grub_port_t grub_ata_ioaddress2[] = { 0xbfd003f6}; +//static const grub_port_t grub_ata_ioaddress[] = { 0x1f0, 0x170 }; +//static const grub_port_t grub_ata_ioaddress2[] = { 0x3f6, 0x376 }; static struct grub_ata_device *grub_ata_devices; @@ -388,6 +390,7 @@ grub_ata_device_initialize (int port, int device, int addr, int addr2) return 0; } +#if 0 static int NESTED_FUNC_ATTR grub_ata_pciinit (grub_pci_device_t dev, grub_pci_id_t pciid __attribute__((unused))) @@ -485,6 +488,48 @@ grub_ata_initialize (void) grub_pci_iterate (grub_ata_pciinit); return 0; } +#endif + +static grub_err_t +grub_ata_initialize (void) +{ + int rega; + int regb; + + rega = grub_ata_ioaddress[0]; + regb = grub_ata_ioaddress2[0]; + + grub_dprintf ("ata", + "rega=0x%x regb=0x%x\n", + rega, regb); + + if (rega && regb) + { + grub_errno = GRUB_ERR_NONE; + grub_ata_device_initialize (0, 0, rega, regb); + + /* Most errors raised by grub_ata_device_initialize() are harmless. + They just indicate this particular drive is not responding, most + likely because it doesn't exist. We might want to ignore specific + error types here, instead of printing them. */ + if (grub_errno) + { + grub_print_error (); + grub_errno = GRUB_ERR_NONE; + } + + grub_ata_device_initialize (0, 1, rega, regb); + + /* Likewise. */ + if (grub_errno) + { + grub_print_error (); + grub_errno = GRUB_ERR_NONE; + } + } + + return 0; +} static void From 36dba59c0792378a6fc829a58f3a70ac67458423 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 3 Nov 2009 00:04:15 +0100 Subject: [PATCH 073/738] Use PCI for sm712 --- video/sm712.c | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/video/sm712.c b/video/sm712.c index df4f50172..93156c9ae 100644 --- a/video/sm712.c +++ b/video/sm712.c @@ -37,6 +37,7 @@ static struct grub_uint8_t *ptr; int index_color_mode; int mapped; + grub_uint32_t base; grub_pci_device_t dev; } framebuffer; @@ -65,6 +66,27 @@ grub_video_sm712_setup (unsigned int width, unsigned int height, { int depth; grub_err_t err; + int found = 0; + + int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid __attribute__ ((unused))) + { + grub_pci_address_t addr; + grub_uint32_t class; + + addr = grub_pci_make_address (dev, 2); + class = grub_pci_read (addr); + + if (((class >> 16) & 0xffff) != 0x0300 || pciid != 0x0712126f) + return 0; + + found = 1; + + addr = grub_pci_make_address (dev, 4); + framebuffer.base = grub_pci_read (addr); + framebuffer.dev = dev; + + return 1; + } /* Decode depth from mode_type. If it is zero, then autodetect. */ depth = (mode_type & GRUB_VIDEO_MODE_TYPE_DEPTH_MASK) @@ -75,6 +97,15 @@ grub_video_sm712_setup (unsigned int width, unsigned int height, return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "Only 1024x600x16 is supported"); + grub_pci_iterate (find_card); + if (!found) + return grub_error (GRUB_ERR_IO, "Couldn't find graphics card"); + + if (found && framebuffer.base == 0) + { + /* FIXME: change framebuffer base */ + } + /* Fill mode info details. */ framebuffer.mode_info.width = 1024; framebuffer.mode_info.height = 600; @@ -92,8 +123,10 @@ grub_video_sm712_setup (unsigned int width, unsigned int height, framebuffer.mode_info.reserved_mask_size = 0; framebuffer.mode_info.reserved_field_pos = 0; framebuffer.mode_info.blit_format = grub_video_get_blit_format (&framebuffer.mode_info); - framebuffer.ptr = grub_pci_device_map_range (framebuffer.dev, 1 << 26, - 1024 * 600 * 2); + /* We can safely discard volatile attribute. */ + framebuffer.ptr = (void *) grub_pci_device_map_range (framebuffer.dev, + framebuffer.base, + 1024 * 600 * 2); framebuffer.mapped = 1; err = grub_video_fb_create_render_target_from_pointer (&framebuffer.render_target, &framebuffer.mode_info, framebuffer.ptr); From cc32314161b55f2a9bd7f4a0897deae9d1b8f80f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 3 Nov 2009 00:05:41 +0100 Subject: [PATCH 074/738] Removed memset declaration --- include/grub/mips/libgcc.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/grub/mips/libgcc.h b/include/grub/mips/libgcc.h index a04a8f140..3bea2f998 100644 --- a/include/grub/mips/libgcc.h +++ b/include/grub/mips/libgcc.h @@ -16,7 +16,6 @@ * along with GRUB. If not, see . */ -void *EXPORT_FUNC (memset) (void *s, int c, int n); void EXPORT_FUNC (__ashldi3) (void); void EXPORT_FUNC (__ashrdi3) (void); void EXPORT_FUNC (__lshrdi3) (void); From 02602a700270c3b661500c44cf6565b183d74a58 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 6 Nov 2009 17:37:31 +0100 Subject: [PATCH 075/738] Cleaned __gnu_local_gp handling --- include/grub/mips/dl.h | 2 +- kern/mips/dl.c | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/include/grub/mips/dl.h b/include/grub/mips/dl.h index 4dbd97ca9..9f8404e72 100644 --- a/include/grub/mips/dl.h +++ b/include/grub/mips/dl.h @@ -20,6 +20,6 @@ #define GRUB_CPU_DL_H 1 /* Dummy __gnu_local_gp. Resolved by linker. */ -char EXPORT_VAR (__gnu_local_gp); +extern char EXPORT_VAR (__gnu_local_gp); #endif /* ! GRUB_CPU_DL_H */ diff --git a/kern/mips/dl.c b/kern/mips/dl.c index e25ccce3a..a937c79b4 100644 --- a/kern/mips/dl.c +++ b/kern/mips/dl.c @@ -25,6 +25,9 @@ #include #include +/* Dummy __gnu_local_gp. Resolved by linker. */ +char __gnu_local_gp; + /* Check if EHDR is a valid ELF header. */ grub_err_t grub_arch_dl_check_header (void *ehdr) From b0979f119179bae381a52dd330a2d77a4056e049 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 6 Nov 2009 22:50:44 +0100 Subject: [PATCH 076/738] Cleaned up CS5536 ATA compat support --- disk/ata.c | 77 ++++++++++---------------------- include/grub/i386/pci.h | 1 + include/grub/mips/yeeloong/pci.h | 1 + 3 files changed, 25 insertions(+), 54 deletions(-) diff --git a/disk/ata.c b/disk/ata.c index 5b74bb673..c6d2168f7 100644 --- a/disk/ata.c +++ b/disk/ata.c @@ -27,10 +27,8 @@ #include /* At the moment, only two IDE ports are supported. */ -static const grub_port_t grub_ata_ioaddress[] = { 0xbfd001f0}; -static const grub_port_t grub_ata_ioaddress2[] = { 0xbfd003f6}; -//static const grub_port_t grub_ata_ioaddress[] = { 0x1f0, 0x170 }; -//static const grub_port_t grub_ata_ioaddress2[] = { 0x3f6, 0x376 }; +static const grub_port_t grub_ata_ioaddress[] = { 0x1f0, 0x170 }; +static const grub_port_t grub_ata_ioaddress2[] = { 0x3f6, 0x376 }; static struct grub_ata_device *grub_ata_devices; @@ -350,8 +348,8 @@ grub_ata_device_initialize (int port, int device, int addr, int addr2) /* Setup the device information. */ dev->port = port; dev->device = device; - dev->ioaddress = addr; - dev->ioaddress2 = addr2; + dev->ioaddress = addr + GRUB_MACHINE_PCI_IO_BASE; + dev->ioaddress2 = addr2 + GRUB_MACHINE_PCI_IO_BASE; dev->next = NULL; grub_ata_regset (dev, GRUB_ATA_REG_DISK, dev->device << 4); @@ -390,10 +388,9 @@ grub_ata_device_initialize (int port, int device, int addr, int addr2) return 0; } -#if 0 static int NESTED_FUNC_ATTR grub_ata_pciinit (grub_pci_device_t dev, - grub_pci_id_t pciid __attribute__((unused))) + grub_pci_id_t pciid) { static int compat_use[2] = { 0 }; grub_pci_address_t addr; @@ -404,19 +401,34 @@ grub_ata_pciinit (grub_pci_device_t dev, int regb; int i; static int controller = 0; + int cs5536 = 0; + int nports = 2; /* Read class. */ addr = grub_pci_make_address (dev, 2); class = grub_pci_read (addr); + /* AMD CS5536 Southbridge. */ + if (pciid == 0x208f1022) + { + cs5536 = 1; + nports = 1; + } + /* Check if this class ID matches that of a PCI IDE Controller. */ - if (class >> 16 != 0x0101) + if (!cs5536 && (class >> 16 != 0x0101)) return 0; - for (i = 0; i < 2; i++) + for (i = 0; i < nports; i++) { /* Set to 0 when the channel operated in compatibility mode. */ - int compat = (class >> (8 + 2 * i)) & 1; + int compat; + + /* We don't support non-compatibility mode for CS5536. */ + if (cs5536) + compat = 0; + else + compat = (class >> (8 + 2 * i)) & 1; rega = 0; regb = 0; @@ -488,49 +500,6 @@ grub_ata_initialize (void) grub_pci_iterate (grub_ata_pciinit); return 0; } -#endif - -static grub_err_t -grub_ata_initialize (void) -{ - int rega; - int regb; - - rega = grub_ata_ioaddress[0]; - regb = grub_ata_ioaddress2[0]; - - grub_dprintf ("ata", - "rega=0x%x regb=0x%x\n", - rega, regb); - - if (rega && regb) - { - grub_errno = GRUB_ERR_NONE; - grub_ata_device_initialize (0, 0, rega, regb); - - /* Most errors raised by grub_ata_device_initialize() are harmless. - They just indicate this particular drive is not responding, most - likely because it doesn't exist. We might want to ignore specific - error types here, instead of printing them. */ - if (grub_errno) - { - grub_print_error (); - grub_errno = GRUB_ERR_NONE; - } - - grub_ata_device_initialize (0, 1, rega, regb); - - /* Likewise. */ - if (grub_errno) - { - grub_print_error (); - grub_errno = GRUB_ERR_NONE; - } - } - - return 0; -} - static void grub_ata_setlba (struct grub_ata_device *dev, grub_disk_addr_t sector, diff --git a/include/grub/i386/pci.h b/include/grub/i386/pci.h index a62adf507..5ed93c28f 100644 --- a/include/grub/i386/pci.h +++ b/include/grub/i386/pci.h @@ -22,6 +22,7 @@ #include #include +#define GRUB_MACHINE_PCI_IO_BASE 0 #define GRUB_PCI_ADDR_REG 0xcf8 #define GRUB_PCI_DATA_REG 0xcfc #define GRUB_PCI_NUM_BUS 256 diff --git a/include/grub/mips/yeeloong/pci.h b/include/grub/mips/yeeloong/pci.h index 8ba9f39d8..c7bd31d4f 100644 --- a/include/grub/mips/yeeloong/pci.h +++ b/include/grub/mips/yeeloong/pci.h @@ -25,6 +25,7 @@ #define GRUB_PCI_NUM_BUS 1 #define GRUB_PCI_NUM_DEVICES 16 +#define GRUB_MACHINE_PCI_IO_BASE 0xbfd00000 #define GRUB_MACHINE_PCI_CONFSPACE 0xbfe80000 #define GRUB_MACHINE_PCI_CONF_CTRL_REG (*(volatile grub_uint32_t *) 0xbfe00118) #define GRUB_MACHINE_PCI_IO_CTRL_REG (*(volatile grub_uint32_t *) 0xbfe00110) From 77546cfd8f761de380a74ed6c87ea8bffb07cb5a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 9 Nov 2009 22:07:57 +0100 Subject: [PATCH 077/738] Restored missing headers --- include/grub/mips/reboot.h | 24 ++++++++++++++++++++++++ include/grub/mips/yeeloong/boot.h | 0 2 files changed, 24 insertions(+) create mode 100644 include/grub/mips/reboot.h create mode 100644 include/grub/mips/yeeloong/boot.h diff --git a/include/grub/mips/reboot.h b/include/grub/mips/reboot.h new file mode 100644 index 000000000..b28fca158 --- /dev/null +++ b/include/grub/mips/reboot.h @@ -0,0 +1,24 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_REBOOT_CPU_HEADER +#define GRUB_REBOOT_CPU_HEADER 1 + +extern void grub_reboot (void); + +#endif diff --git a/include/grub/mips/yeeloong/boot.h b/include/grub/mips/yeeloong/boot.h new file mode 100644 index 000000000..e69de29bb From 1f56d837883e066a8791af4c297bc809934e7409 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 14 Nov 2009 17:00:39 +0100 Subject: [PATCH 078/738] Initial reimport of double buffering --- ChangeLog.video | 31 ++++++ commands/minicmd.c | 1 - include/grub/video.h | 5 + include/grub/video_fb.h | 11 ++ kern/misc.c | 4 - kern/term.c | 1 + normal/cmdline.c | 10 +- term/gfxterm.c | 7 ++ video/fb/video_fb.c | 52 ++++++++++ video/i386/pc/vbe.c | 219 +++++++++++++++++++++++++++++++++++++--- 10 files changed, 318 insertions(+), 23 deletions(-) create mode 100644 ChangeLog.video diff --git a/ChangeLog.video b/ChangeLog.video new file mode 100644 index 000000000..c088b7f36 --- /dev/null +++ b/ChangeLog.video @@ -0,0 +1,31 @@ +2009-08-24 Colin D Bennett +2009-08-24 Vladimir Serbinenko + + Double buffering support. + + * commands/i386/pc/videotest.c (grub_cmd_videotest): Swap doublebuffers. + * include/grub/video.h: Update comment. + * include/grub/video_fb.h (grub_video_fb_doublebuf_update_screen_t): + New type. + (grub_video_fb_doublebuf_blit_init): New prototype. + * term/gfxterm.c (scroll_up): Support double buffering. + (grub_gfxterm_refresh): Likewise. + * video/fb/video_fb.c (doublebuf_blit_update_screen): New function. + (grub_video_fb_doublebuf_blit_init): Likewise. + * video/i386/pc/vbe.c (framebuffer): Remove 'render_target'. Add + 'front_target', 'back_target', 'offscreen_buffer', 'page_size', + 'displayed_page', 'render_page' and 'update_screen'. + (grub_video_vbe_fini): Free offscreen buffer. + (doublebuf_pageflipping_commit): New function. + (doublebuf_pageflipping_update_screen): Likewise. + (doublebuf_pageflipping_init): Likewise. + (double_buffering_init): Likewise. + (grub_video_vbe_setup): Enable doublebuffering. + (grub_video_vbe_swap_buffers): Implement. + (grub_video_vbe_set_active_render_target): Handle double buffering. + (grub_video_vbe_get_active_render_target): Likewise. + (grub_video_vbe_get_info_and_fini): Likewise. Free offscreen_buffer. + (grub_video_vbe_adapter): Use grub_video_vbe_get_active_render_target. + (grub_video_vbe_enable_double_buffering): Likewise. + (grub_video_vbe_swap_buffers): Use update_screen. + (grub_video_set_mode): Use double buffering. diff --git a/commands/minicmd.c b/commands/minicmd.c index 6c9c33a0e..7a1695838 100644 --- a/commands/minicmd.c +++ b/commands/minicmd.c @@ -315,7 +315,6 @@ grub_mini_cmd_lsmod (struct grub_command *cmd __attribute__ ((unused)), grub_printf ("%s", dep->mod->name); } grub_putchar ('\n'); - grub_refresh (); return 0; } diff --git a/include/grub/video.h b/include/grub/video.h index 53fe67c4e..4f8b5cf7b 100644 --- a/include/grub/video.h +++ b/include/grub/video.h @@ -34,6 +34,9 @@ struct grub_video_render_target; struct grub_video_bitmap; /* Defines used to describe video mode or rendering target. */ +/* If following is set render target contains previously displayed image + after swapping buffers (otherwise it contains newly displayedd image). + */ #define GRUB_VIDEO_MODE_TYPE_PURE_TEXT 0x00000040 #define GRUB_VIDEO_MODE_TYPE_ALPHA 0x00000020 #define GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED 0x00000010 @@ -48,6 +51,8 @@ struct grub_video_bitmap; #define GRUB_VIDEO_MODE_TYPE_DEPTH_MASK 0x0000ff00 #define GRUB_VIDEO_MODE_TYPE_DEPTH_POS 8 +/* The basic render target representing the whole display. This always + renders to the back buffer when double-buffering is in use. */ #define GRUB_VIDEO_RENDER_TARGET_DISPLAY \ ((struct grub_video_render_target *) 0) diff --git a/include/grub/video_fb.h b/include/grub/video_fb.h index 17debd69f..3046a597b 100644 --- a/include/grub/video_fb.h +++ b/include/grub/video_fb.h @@ -115,4 +115,15 @@ grub_video_fb_get_active_render_target (struct grub_video_fbrender_target **targ grub_err_t grub_video_fb_set_active_render_target (struct grub_video_fbrender_target *target); +typedef grub_err_t +(*grub_video_fb_doublebuf_update_screen_t) (struct grub_video_fbrender_target *front, + struct grub_video_fbrender_target *back); + +grub_err_t +grub_video_fb_doublebuf_blit_init (struct grub_video_fbrender_target **front, + struct grub_video_fbrender_target **back, + grub_video_fb_doublebuf_update_screen_t *update_screen, + struct grub_video_mode_info mode_info, + void *framebuf); + #endif /* ! GRUB_VIDEO_FB_HEADER */ diff --git a/kern/misc.c b/kern/misc.c index cacfbc753..38a5638b3 100644 --- a/kern/misc.c +++ b/kern/misc.c @@ -161,7 +161,6 @@ grub_vprintf (const char *fmt, va_list args) int ret; ret = grub_vsprintf (0, fmt, args); - grub_refresh (); return ret; } @@ -818,9 +817,6 @@ grub_vsprintf (char *str, const char *fmt, va_list args) if (str) *str = '\0'; - if (count && !str) - grub_refresh (); - return count; } diff --git a/kern/term.c b/kern/term.c index 94d5a9e1d..8c4e1e339 100644 --- a/kern/term.c +++ b/kern/term.c @@ -131,6 +131,7 @@ grub_getcharwidth (grub_uint32_t code) int grub_getkey (void) { + grub_refresh (); return (grub_cur_term_input->getkey) (); } diff --git a/normal/cmdline.c b/normal/cmdline.c index 7a5b6ec84..3816ce9d6 100644 --- a/normal/cmdline.c +++ b/normal/cmdline.c @@ -199,8 +199,6 @@ grub_cmdline_get (const char *prompt, char cmdline[], unsigned max_len, xpos = (plen + lpos) % 79; ypos = ystart + (plen + lpos) / 79; grub_gotoxy (xpos, ypos); - - grub_refresh (); } void cl_print (int pos, int c) @@ -241,8 +239,6 @@ grub_cmdline_get (const char *prompt, char cmdline[], unsigned max_len, cl_print (lpos - len, echo_char); cl_set_pos (); } - - grub_refresh (); } void cl_delete (unsigned len) @@ -262,8 +258,6 @@ grub_cmdline_get (const char *prompt, char cmdline[], unsigned max_len, cl_print (lpos, echo_char); cl_set_pos (); } - - grub_refresh (); } plen = grub_strlen (prompt); @@ -283,6 +277,8 @@ grub_cmdline_get (const char *prompt, char cmdline[], unsigned max_len, if (history && hist_used == 0) grub_history_add (buf); + grub_refresh (); + while ((key = GRUB_TERM_ASCII_CHAR (grub_getkey ())) != '\n' && key != '\r') { if (readline) @@ -457,6 +453,8 @@ grub_cmdline_get (const char *prompt, char cmdline[], unsigned max_len, } break; } + + grub_refresh (); } grub_putchar ('\n'); diff --git a/term/gfxterm.c b/term/gfxterm.c index 57c51cffa..1a46a867d 100644 --- a/term/gfxterm.c +++ b/term/gfxterm.c @@ -124,6 +124,8 @@ static unsigned int calculate_normal_character_width (grub_font_t font); static unsigned char calculate_character_width (struct grub_font_glyph *glyph); +static void grub_gfxterm_refresh (void); + static void set_term_color (grub_uint8_t term_color) { @@ -815,6 +817,9 @@ grub_gfxterm_cls (void) /* Mark virtual screen to be redrawn. */ dirty_region_add_virtualscreen (); + + dirty_region_redraw (); + grub_gfxterm_refresh (); } static void @@ -877,6 +882,8 @@ grub_gfxterm_refresh (void) { /* Redraw only changed regions. */ dirty_region_redraw (); + + grub_video_swap_buffers (); } static grub_err_t diff --git a/video/fb/video_fb.c b/video/fb/video_fb.c index 5f2917da6..b7323b5b7 100644 --- a/video/fb/video_fb.c +++ b/video/fb/video_fb.c @@ -66,6 +66,8 @@ grub_video_fb_init (void) grub_err_t grub_video_fb_fini (void) { + /* TODO: destroy render targets. */ + grub_free (palette); render_target = 0; palette = 0; @@ -1182,3 +1184,53 @@ grub_video_fb_get_active_render_target (struct grub_video_fbrender_target **targ return GRUB_ERR_NONE; } + +static grub_err_t +doublebuf_blit_update_screen (struct grub_video_fbrender_target *front, + struct grub_video_fbrender_target *back) +{ + grub_memcpy (front->data, back->data, + front->mode_info.pitch * front->mode_info.height); + return GRUB_ERR_NONE; +} + +grub_err_t +grub_video_fb_doublebuf_blit_init (struct grub_video_fbrender_target **front, + struct grub_video_fbrender_target **back, + grub_video_fb_doublebuf_update_screen_t *update_screen, + struct grub_video_mode_info mode_info, + void *framebuf) +{ + grub_err_t err; + int page_size = mode_info.pitch * mode_info.height; + void *offscreen_buffer; + + err = grub_video_fb_create_render_target_from_pointer (front, &mode_info, + framebuf); + if (err) + return err; + + offscreen_buffer = grub_malloc (page_size); + if (! offscreen_buffer) + { + grub_video_fb_delete_render_target (*front); + *front = 0; + return grub_errno; + } + + err = grub_video_fb_create_render_target_from_pointer (back, &mode_info, + offscreen_buffer); + + if (err) + { + grub_video_fb_delete_render_target (*front); + grub_free (offscreen_buffer); + *front = 0; + return grub_errno; + } + (*back)->is_allocated = 1; + + *update_screen = doublebuf_blit_update_screen; + + return GRUB_ERR_NONE; +} diff --git a/video/i386/pc/vbe.c b/video/i386/pc/vbe.c index 8759ba652..f2c414a99 100644 --- a/video/i386/pc/vbe.c +++ b/video/i386/pc/vbe.c @@ -36,13 +36,25 @@ static struct grub_vbe_mode_info_block active_vbe_mode_info; static struct { struct grub_video_mode_info mode_info; - struct grub_video_render_target *render_target; + struct grub_video_render_target *front_target; + struct grub_video_render_target *back_target; unsigned int bytes_per_scan_line; unsigned int bytes_per_pixel; grub_uint32_t active_vbe_mode; grub_uint8_t *ptr; int index_color_mode; + + char *offscreen_buffer; + + grub_size_t page_size; /* The size of a page in bytes. */ + + /* For page flipping strategy. */ + int displayed_page; /* The page # that is the front buffer. */ + int render_page; /* The page # that is the back buffer. */ + + /* Virtual functions. */ + grub_video_fb_doublebuf_update_screen_t update_screen; } framebuffer; static grub_uint32_t initial_vbe_mode; @@ -344,6 +356,7 @@ static grub_err_t grub_video_vbe_fini (void) { grub_vbe_status_t status; + grub_err_t err; /* Restore old video mode. */ status = grub_vbe_bios_set_mode (initial_vbe_mode, 0); @@ -355,11 +368,170 @@ grub_video_vbe_fini (void) grub_free (vbe_mode_list); vbe_mode_list = NULL; - /* TODO: destroy render targets. */ - - return grub_video_fb_fini (); + err = grub_video_fb_fini (); + grub_free (framebuffer.offscreen_buffer); + return err; } +/* + Set framebuffer render target page and display the proper page, based on + `doublebuf_state.render_page' and `doublebuf_state.displayed_page', + respectively. +*/ +static grub_err_t +doublebuf_pageflipping_commit (void) +{ + /* Tell the video adapter to display the new front page. */ + int display_start_line + = framebuffer.mode_info.height * framebuffer.displayed_page; + + grub_vbe_status_t vbe_err = + grub_vbe_bios_set_display_start (0, display_start_line); + + if (vbe_err != GRUB_VBE_STATUS_OK) + return grub_error (GRUB_ERR_IO, "couldn't commit pageflip"); + + return 0; +} + +static grub_err_t +doublebuf_pageflipping_update_screen (struct grub_video_fbrender_target *front + __attribute__ ((unused)), + struct grub_video_fbrender_target *back + __attribute__ ((unused))) +{ + int new_displayed_page; + struct grub_video_fbrender_target *target; + grub_err_t err; + + /* Swap the page numbers in the framebuffer struct. */ + new_displayed_page = framebuffer.render_page; + framebuffer.render_page = framebuffer.displayed_page; + framebuffer.displayed_page = new_displayed_page; + + err = doublebuf_pageflipping_commit (); + if (err) + { + /* Restore previous state. */ + framebuffer.render_page = framebuffer.displayed_page; + framebuffer.displayed_page = new_displayed_page; + return err; + } + + grub_memcpy (framebuffer.ptr + framebuffer.render_page + * framebuffer.page_size, framebuffer.ptr + + framebuffer.displayed_page * framebuffer.page_size, + framebuffer.page_size); + + target = framebuffer.back_target; + framebuffer.back_target = framebuffer.front_target; + framebuffer.front_target = target; + + err = grub_video_fb_get_active_render_target (&target); + if (err) + return err; + + if (target == framebuffer.back_target) + err = grub_video_fb_set_active_render_target (framebuffer.front_target); + else if (target == framebuffer.front_target) + err = grub_video_fb_set_active_render_target (framebuffer.back_target); + + return err; +} + +static grub_err_t +doublebuf_pageflipping_init (void) +{ + /* Get video RAM size in bytes. */ + grub_size_t vram_size = controller_info.total_memory << 16; + grub_err_t err; + + framebuffer.page_size = + framebuffer.mode_info.pitch * framebuffer.mode_info.height; + + if (2 * framebuffer.page_size > vram_size) + return grub_error (GRUB_ERR_OUT_OF_MEMORY, + "Not enough video memory for double buffering."); + + framebuffer.displayed_page = 0; + framebuffer.render_page = 1; + + framebuffer.update_screen = doublebuf_pageflipping_update_screen; + + err = grub_video_fb_create_render_target_from_pointer (&framebuffer.front_target, &framebuffer.mode_info, framebuffer.ptr); + if (err) + return err; + + err = grub_video_fb_create_render_target_from_pointer (&framebuffer.back_target, &framebuffer.mode_info, framebuffer.ptr + framebuffer.page_size); + if (err) + { + grub_video_fb_delete_render_target (framebuffer.front_target); + return err; + } + + /* Set the framebuffer memory data pointer and display the right page. */ + err = doublebuf_pageflipping_commit (); + if (err) + { + grub_video_fb_delete_render_target (framebuffer.front_target); + grub_video_fb_delete_render_target (framebuffer.back_target); + return err; + } + + return GRUB_ERR_NONE; +} + +/* Select the best double buffering mode available. */ +static grub_err_t +double_buffering_init (unsigned int mode_type, unsigned int mode_mask) +{ + grub_err_t err; + + if (grub_video_check_mode_flag (mode_type, mode_mask, + GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED, 1)) + { + err = doublebuf_pageflipping_init (); + if (!err) + { + framebuffer.mode_info.mode_type + |= GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED; + return GRUB_ERR_NONE; + } + + grub_errno = GRUB_ERR_NONE; + + err = grub_video_fb_doublebuf_blit_init (&framebuffer.front_target, + &framebuffer.back_target, + &framebuffer.update_screen, + framebuffer.mode_info, + framebuffer.ptr); + + if (!err) + { + framebuffer.mode_info.mode_type + |= GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED; + return GRUB_ERR_NONE; + } + + grub_errno = GRUB_ERR_NONE; + } + + /* Fall back to no double buffering. */ + err = grub_video_fb_create_render_target_from_pointer (&framebuffer.front_target, &framebuffer.mode_info, framebuffer.ptr); + + if (err) + return err; + + framebuffer.back_target = framebuffer.front_target; + framebuffer.update_screen = 0; + + framebuffer.mode_info.mode_type &= ~GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED; + + return GRUB_ERR_NONE; +} + + + static grub_err_t grub_video_vbe_setup (unsigned int width, unsigned int height, unsigned int mode_type, unsigned int mode_mask) @@ -488,12 +660,12 @@ grub_video_vbe_setup (unsigned int width, unsigned int height, framebuffer.mode_info.blit_format = grub_video_get_blit_format (&framebuffer.mode_info); - err = grub_video_fb_create_render_target_from_pointer (&framebuffer.render_target, &framebuffer.mode_info, framebuffer.ptr); - + /* Set up double buffering and targets. */ + err = double_buffering_init (mode_type, mode_mask); if (err) return err; - err = grub_video_fb_set_active_render_target (framebuffer.render_target); + err = grub_video_fb_set_active_render_target (framebuffer.back_target); if (err) return err; @@ -530,7 +702,15 @@ grub_video_vbe_set_palette (unsigned int start, unsigned int count, static grub_err_t grub_video_vbe_swap_buffers (void) { - /* TODO: Implement buffer swapping. */ + grub_err_t err; + if (!framebuffer.update_screen) + return GRUB_ERR_NONE; + + err = framebuffer.update_screen (framebuffer.front_target, + framebuffer.back_target); + if (err) + return err; + return GRUB_ERR_NONE; } @@ -538,27 +718,42 @@ static grub_err_t grub_video_vbe_set_active_render_target (struct grub_video_render_target *target) { if (target == GRUB_VIDEO_RENDER_TARGET_DISPLAY) - target = framebuffer.render_target; + target = framebuffer.back_target; return grub_video_fb_set_active_render_target (target); } +static grub_err_t +grub_video_vbe_get_active_render_target (struct grub_video_render_target **target) +{ + grub_err_t err; + err = grub_video_fb_get_active_render_target (target); + if (err) + return err; + + if (*target == framebuffer.back_target) + *target = GRUB_VIDEO_RENDER_TARGET_DISPLAY; + + return GRUB_ERR_NONE; +} + static grub_err_t grub_video_vbe_get_info_and_fini (struct grub_video_mode_info *mode_info, void **framebuf) { grub_memcpy (mode_info, &(framebuffer.mode_info), sizeof (*mode_info)); - *framebuf = (char *) framebuffer.ptr; + *framebuf = (char *) framebuffer.ptr + + framebuffer.displayed_page * framebuffer.page_size; grub_free (vbe_mode_list); vbe_mode_list = NULL; grub_video_fb_fini (); + grub_free (framebuffer.offscreen_buffer); return GRUB_ERR_NONE; } - static struct grub_video_adapter grub_video_vbe_adapter = { .name = "VESA BIOS Extension Video Driver", @@ -584,7 +779,7 @@ static struct grub_video_adapter grub_video_vbe_adapter = .create_render_target = grub_video_fb_create_render_target, .delete_render_target = grub_video_fb_delete_render_target, .set_active_render_target = grub_video_vbe_set_active_render_target, - .get_active_render_target = grub_video_fb_get_active_render_target, + .get_active_render_target = grub_video_vbe_get_active_render_target, .next = 0 }; From bbe73b09954b3d82a039c6a88bd5a58114354b13 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 14 Nov 2009 17:59:11 +0100 Subject: [PATCH 079/738] Improved performance by not requiring updating swap in gfxterm --- include/grub/video.h | 5 ++-- term/gfxterm.c | 55 +++++++++++++++++++++++++++++++------------- video/i386/pc/vbe.c | 50 ++++++++++++++++++++++++++++------------ 3 files changed, 77 insertions(+), 33 deletions(-) diff --git a/include/grub/video.h b/include/grub/video.h index 4f8b5cf7b..a1882f57b 100644 --- a/include/grub/video.h +++ b/include/grub/video.h @@ -34,9 +34,10 @@ struct grub_video_render_target; struct grub_video_bitmap; /* Defines used to describe video mode or rendering target. */ -/* If following is set render target contains previously displayed image - after swapping buffers (otherwise it contains newly displayedd image). +/* If following is set render target contains currenly displayed image + after swapping buffers (otherwise it contains previously displayed image). */ +#define GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP 0x00000080 #define GRUB_VIDEO_MODE_TYPE_PURE_TEXT 0x00000040 #define GRUB_VIDEO_MODE_TYPE_ALPHA 0x00000020 #define GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED 0x00000010 diff --git a/term/gfxterm.c b/term/gfxterm.c index 1a46a867d..6906b77a1 100644 --- a/term/gfxterm.c +++ b/term/gfxterm.c @@ -474,8 +474,6 @@ dirty_region_redraw (void) height = dirty_region.bottom_right_y - y + 1; redraw_screen_rect (x, y, width, height); - - dirty_region_reset (); } static void @@ -566,9 +564,6 @@ scroll_up (void) { /* Remove cursor. */ draw_cursor (0); - - /* Redraw only changed regions. */ - dirty_region_redraw (); } /* Scroll text buffer with one line to up. */ @@ -584,28 +579,52 @@ scroll_up (void) i++) clear_char (&(virtual_screen.text_buffer[i])); - /* Scroll physical screen. */ - grub_video_set_active_render_target (text_layer); - color = virtual_screen.bg_color; - grub_video_scroll (color, 0, -virtual_screen.normal_char_height); - grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY); - /* If we have bitmap, re-draw screen, otherwise scroll physical screen too. */ if (bitmap) { + /* Scroll physical screen. */ + grub_video_set_active_render_target (text_layer); + color = virtual_screen.bg_color; + grub_video_scroll (color, 0, -virtual_screen.normal_char_height); + /* Mark virtual screen to be redrawn. */ dirty_region_add_virtualscreen (); } else { - /* Clear new border area. */ - grub_video_fill_rect (color, - virtual_screen.offset_x, virtual_screen.offset_y, - virtual_screen.width, virtual_screen.normal_char_height); + int i = 1; + if (mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED + && !(mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP)) + i++; + + color = virtual_screen.bg_color; + + while (i--) + { + /* Clear new border area. */ + grub_video_fill_rect (color, + virtual_screen.offset_x, + virtual_screen.offset_y, + virtual_screen.width, + virtual_screen.normal_char_height); + + grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY); + dirty_region_redraw (); + + /* Scroll physical screen. */ + grub_video_scroll (color, 0, -virtual_screen.normal_char_height); + + if (i) + grub_video_swap_buffers (); + } + dirty_region_reset (); /* Scroll physical screen. */ + grub_video_set_active_render_target (text_layer); + color = virtual_screen.bg_color; grub_video_scroll (color, 0, -virtual_screen.normal_char_height); + /* Draw cursor if visible. */ if (virtual_screen.cursor_state) draw_cursor (1); @@ -818,7 +837,6 @@ grub_gfxterm_cls (void) /* Mark virtual screen to be redrawn. */ dirty_region_add_virtualscreen (); - dirty_region_redraw (); grub_gfxterm_refresh (); } @@ -884,6 +902,11 @@ grub_gfxterm_refresh (void) dirty_region_redraw (); grub_video_swap_buffers (); + + if (mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED + && !(mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP)) + dirty_region_redraw (); + dirty_region_reset (); } static grub_err_t diff --git a/video/i386/pc/vbe.c b/video/i386/pc/vbe.c index f2c414a99..a039710a2 100644 --- a/video/i386/pc/vbe.c +++ b/video/i386/pc/vbe.c @@ -418,10 +418,11 @@ doublebuf_pageflipping_update_screen (struct grub_video_fbrender_target *front return err; } - grub_memcpy (framebuffer.ptr + framebuffer.render_page - * framebuffer.page_size, framebuffer.ptr - + framebuffer.displayed_page * framebuffer.page_size, - framebuffer.page_size); + if (framebuffer.mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP) + grub_memcpy (framebuffer.ptr + framebuffer.render_page + * framebuffer.page_size, framebuffer.ptr + + framebuffer.displayed_page * framebuffer.page_size, + framebuffer.page_size); target = framebuffer.back_target; framebuffer.back_target = framebuffer.front_target; @@ -486,19 +487,38 @@ static grub_err_t double_buffering_init (unsigned int mode_type, unsigned int mode_mask) { grub_err_t err; + int updating_swap_needed; + updating_swap_needed + = grub_video_check_mode_flag (mode_type, mode_mask, + GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP, 0); + + /* Do double buffering only if it's either requested or efficient. */ if (grub_video_check_mode_flag (mode_type, mode_mask, - GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED, 1)) + GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED, + !updating_swap_needed)) { + framebuffer.mode_info.mode_type |= GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED; + if (updating_swap_needed) + framebuffer.mode_info.mode_type |= GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP; err = doublebuf_pageflipping_init (); if (!err) - { - framebuffer.mode_info.mode_type - |= GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED; - return GRUB_ERR_NONE; - } + return GRUB_ERR_NONE; + + framebuffer.mode_info.mode_type + &= ~(GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED + | GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP); grub_errno = GRUB_ERR_NONE; + } + + if (grub_video_check_mode_flag (mode_type, mode_mask, + GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED, + 0)) + { + framebuffer.mode_info.mode_type + |= (GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED + | GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP); err = grub_video_fb_doublebuf_blit_init (&framebuffer.front_target, &framebuffer.back_target, @@ -507,11 +527,11 @@ double_buffering_init (unsigned int mode_type, unsigned int mode_mask) framebuffer.ptr); if (!err) - { - framebuffer.mode_info.mode_type - |= GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED; - return GRUB_ERR_NONE; - } + return GRUB_ERR_NONE; + + framebuffer.mode_info.mode_type + &= ~(GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED + | GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP); grub_errno = GRUB_ERR_NONE; } From 85536ab717ff52e6d0b6e146811b923f367e1853 Mon Sep 17 00:00:00 2001 From: Colin D Bennet Date: Sat, 14 Nov 2009 23:11:55 +0100 Subject: [PATCH 080/738] 2009-11-14 Colin D Bennet Trigonometry support. * include/grub/trig.h: New file. * lib/trig.c: Likewise. * maintainance/gentrigtables.py: Likewise. * conf/common.rmk (pkglib_MODULES): Add trig.mod. (trig_mod_SOURCES): New variable. (trig_mod_CFLAGS): Likewise. (trig_mod_LDFLAGS): Likewise. --- conf/common.rmk | 6 +++ include/grub/trig.h | 44 +++++++++++++++++++ lib/trig.c | 83 +++++++++++++++++++++++++++++++++++ maintainance/gentrigtables.py | 58 ++++++++++++++++++++++++ 4 files changed, 191 insertions(+) create mode 100644 include/grub/trig.h create mode 100644 lib/trig.c create mode 100644 maintainance/gentrigtables.py diff --git a/conf/common.rmk b/conf/common.rmk index 3dddeb66d..4ec0dab1e 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -638,6 +638,12 @@ xnu_uuid_mod_SOURCES = commands/xnu_uuid.c xnu_uuid_mod_CFLAGS = $(COMMON_CFLAGS) xnu_uuid_mod_LDFLAGS = $(COMMON_LDFLAGS) +# For trig.mod. +pkglib_MODULES += trig.mod +trig_mod_SOURCES = lib/trig.c +trig_mod_CFLAGS = $(COMMON_CFLAGS) +trig_mod_LDFLAGS = $(COMMON_LDFLAGS) + pkglib_MODULES += setjmp.mod setjmp_mod_SOURCES = lib/$(target_cpu)/setjmp.S setjmp_mod_ASFLAGS = $(COMMON_ASFLAGS) diff --git a/include/grub/trig.h b/include/grub/trig.h new file mode 100644 index 000000000..2512a5f07 --- /dev/null +++ b/include/grub/trig.h @@ -0,0 +1,44 @@ +/* trig.h - Trigonometric function support. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_TRIG_HEADER +#define GRUB_TRIG_HEADER 1 + +#define GRUB_TRIG_ANGLE_MAX 256 +#define GRUB_TRIG_ANGLE_MASK 255 +#define GRUB_TRIG_FRACTION_SCALE 16384 + +extern short grub_trig_sintab[]; +extern short grub_trig_costab[]; + +static __inline int +grub_sin (int x) +{ + x &= GRUB_TRIG_ANGLE_MASK; + return grub_trig_sintab[x]; +} + +static __inline int +grub_cos (int x) +{ + x &= GRUB_TRIG_ANGLE_MASK; + return grub_trig_costab[x]; +} + +#endif /* ! GRUB_TRIG_HEADER */ diff --git a/lib/trig.c b/lib/trig.c new file mode 100644 index 000000000..e36aa38ef --- /dev/null +++ b/lib/trig.c @@ -0,0 +1,83 @@ +/* trig.c - Trigonometric table definitions. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include + +/* These tables were generated with `gentrigtables.py'. */ + +short grub_trig_sintab[] = +{ + 0,402,804,1205,1606,2006,2404,2801,3196,3590, + 3981,4370,4756,5139,5520,5897,6270,6639,7005,7366, + 7723,8076,8423,8765,9102,9434,9760,10080,10394,10702, + 11003,11297,11585,11866,12140,12406,12665,12916,13160,13395, + 13623,13842,14053,14256,14449,14635,14811,14978,15137,15286, + 15426,15557,15679,15791,15893,15986,16069,16143,16207,16261, + 16305,16340,16364,16379,16384,16379,16364,16340,16305,16261, + 16207,16143,16069,15986,15893,15791,15679,15557,15426,15286, + 15137,14978,14811,14635,14449,14256,14053,13842,13623,13395, + 13160,12916,12665,12406,12140,11866,11585,11297,11003,10702, + 10394,10080,9760,9434,9102,8765,8423,8076,7723,7366, + 7005,6639,6270,5897,5520,5139,4756,4370,3981,3590, + 3196,2801,2404,2006,1606,1205,804,402,0,-402, + -804,-1205,-1606,-2006,-2404,-2801,-3196,-3590,-3981,-4370, + -4756,-5139,-5520,-5897,-6270,-6639,-7005,-7366,-7723,-8076, + -8423,-8765,-9102,-9434,-9760,-10080,-10394,-10702,-11003,-11297, + -11585,-11866,-12140,-12406,-12665,-12916,-13160,-13395,-13623,-13842, + -14053,-14256,-14449,-14635,-14811,-14978,-15137,-15286,-15426,-15557, + -15679,-15791,-15893,-15986,-16069,-16143,-16207,-16261,-16305,-16340, + -16364,-16379,-16384,-16379,-16364,-16340,-16305,-16261,-16207,-16143, + -16069,-15986,-15893,-15791,-15679,-15557,-15426,-15286,-15137,-14978, + -14811,-14635,-14449,-14256,-14053,-13842,-13623,-13395,-13160,-12916, + -12665,-12406,-12140,-11866,-11585,-11297,-11003,-10702,-10394,-10080, + -9760,-9434,-9102,-8765,-8423,-8076,-7723,-7366,-7005,-6639, + -6270,-5897,-5520,-5139,-4756,-4370,-3981,-3590,-3196,-2801, + -2404,-2006,-1606,-1205,-804,-402 +}; + +short grub_trig_costab[] = +{ + 16384,16379,16364,16340,16305,16261,16207,16143,16069,15986, + 15893,15791,15679,15557,15426,15286,15137,14978,14811,14635, + 14449,14256,14053,13842,13623,13395,13160,12916,12665,12406, + 12140,11866,11585,11297,11003,10702,10394,10080,9760,9434, + 9102,8765,8423,8076,7723,7366,7005,6639,6270,5897, + 5520,5139,4756,4370,3981,3590,3196,2801,2404,2006, + 1606,1205,804,402,0,-402,-804,-1205,-1606,-2006, + -2404,-2801,-3196,-3590,-3981,-4370,-4756,-5139,-5520,-5897, + -6270,-6639,-7005,-7366,-7723,-8076,-8423,-8765,-9102,-9434, + -9760,-10080,-10394,-10702,-11003,-11297,-11585,-11866,-12140,-12406, + -12665,-12916,-13160,-13395,-13623,-13842,-14053,-14256,-14449,-14635, + -14811,-14978,-15137,-15286,-15426,-15557,-15679,-15791,-15893,-15986, + -16069,-16143,-16207,-16261,-16305,-16340,-16364,-16379,-16384,-16379, + -16364,-16340,-16305,-16261,-16207,-16143,-16069,-15986,-15893,-15791, + -15679,-15557,-15426,-15286,-15137,-14978,-14811,-14635,-14449,-14256, + -14053,-13842,-13623,-13395,-13160,-12916,-12665,-12406,-12140,-11866, + -11585,-11297,-11003,-10702,-10394,-10080,-9760,-9434,-9102,-8765, + -8423,-8076,-7723,-7366,-7005,-6639,-6270,-5897,-5520,-5139, + -4756,-4370,-3981,-3590,-3196,-2801,-2404,-2006,-1606,-1205, + -804,-402,0,402,804,1205,1606,2006,2404,2801, + 3196,3590,3981,4370,4756,5139,5520,5897,6270,6639, + 7005,7366,7723,8076,8423,8765,9102,9434,9760,10080, + 10394,10702,11003,11297,11585,11866,12140,12406,12665,12916, + 13160,13395,13623,13842,14053,14256,14449,14635,14811,14978, + 15137,15286,15426,15557,15679,15791,15893,15986,16069,16143, + 16207,16261,16305,16340,16364,16379 +}; + diff --git a/maintainance/gentrigtables.py b/maintainance/gentrigtables.py new file mode 100644 index 000000000..7c069f833 --- /dev/null +++ b/maintainance/gentrigtables.py @@ -0,0 +1,58 @@ +#!/usr/bin/python +# Script to generate trigonometric function tables. +# +# GRUB -- GRand Unified Bootloader +# Copyright (C) 2008 Free Software Foundation, Inc. +# +# GRUB is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# GRUB is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GRUB. If not, see . + +from math import * +from sys import stdout + +def write(x): + stdout.write(x) + +def writeTable(arr, name): + indent = ' ' * 4 + write("short ") + write(name) + write("[] =\n{\n") + write(indent) + for i in range(len(arr)): + if i != 0: + write(",") + if i % 10 == 0: + write("\n") + write(indent) + write("%d" % arr[i]) + write("\n};\n") + +def main(): + sintab = [] + costab = [] + for i in range(256): + # Convert to an angle in 1/256 of a circle. + x = i * 2 * pi / 256 + sintab.append(int(round(sin(x) * 16384))) + costab.append(int(round(cos(x) * 16384))) + + write("#define TRIG_ANGLE_MAX 256\n") + write("#define TRIG_FRACTION_SCALE 16384\n") + writeTable(sintab, "sintab") + writeTable(costab, "costab") + +if __name__ == "__main__": + main() + +# vim:ai et sw=4 ts=4 From c51a5caeab7dcbc9f9f49b923543bbb1645de70e Mon Sep 17 00:00:00 2001 From: Colin D Bennet Date: Sun, 15 Nov 2009 00:03:03 +0100 Subject: [PATCH 081/738] 2009-11-14 Colin D Bennet 2009-11-14 Vladimir Serbinenko Support for gfxterm in a window. * include/grub/gfxterm.h: New file. * include/grub/video.h (struct grub_video_rect): New declaration. (grub_video_rect_t): Likewise. * term/gfxterm.c (struct grub_gfxterm_window): New type. (refcount): New variable. (render_target): Likewise. (window): Likewise. (repaint_callback): Likewise. (grub_virtual_screen_setup): Use 'render_target'. (init_window): New function. (grub_gfxterm_init_window): Likewise. (grub_gfxterm_init): Check reference counter. Use init_window. (destroy_window): New function. (grub_gfxterm_destroy_window): Likewise. (grub_gfxterm_fini): Check reference counter. Use destroy_window. (redraw_screen_rect): Restore viewport. Use 'render_target' and 'window'. Call 'repaint_callback'. (write_char): Use 'render_target'. (draw_cursor): Likewise. (scroll_up): Restore viewport. Use 'render_target' and 'window'. Call 'repaint_callback'. (grub_gfxterm_cls): Likewise. (grub_gfxterm_refresh): Use 'window'. (grub_gfxterm_set_repaint_callback): New function. (grub_gfxterm_background_image_cmd): Use 'window'. (grub_gfxterm_get_term): New function. (GRUB_MOD_INIT(term_gfxterm)): Set 'refcount' to 0. Also-By: Vladimir Serbinenko --- ChangeLog.gfxtermwindow | 36 +++++++ include/grub/gfxterm.h | 42 ++++++++ include/grub/video.h | 10 ++ term/gfxterm.c | 226 ++++++++++++++++++++++++++++++++-------- 4 files changed, 269 insertions(+), 45 deletions(-) create mode 100644 ChangeLog.gfxtermwindow create mode 100644 include/grub/gfxterm.h diff --git a/ChangeLog.gfxtermwindow b/ChangeLog.gfxtermwindow new file mode 100644 index 000000000..d23038ba7 --- /dev/null +++ b/ChangeLog.gfxtermwindow @@ -0,0 +1,36 @@ +2009-11-14 Colin D Bennet +2009-11-14 Vladimir Serbinenko + + Support for gfxterm in a window. + + * include/grub/gfxterm.h: New file. + * include/grub/video.h (struct grub_video_rect): New declaration. + (grub_video_rect_t): Likewise. + * term/gfxterm.c (struct grub_gfxterm_window): New type. + (refcount): New variable. + (render_target): Likewise. + (window): Likewise. + (repaint_callback): Likewise. + (grub_virtual_screen_setup): Use 'render_target'. + (init_window): New function. + (grub_gfxterm_init_window): Likewise. + (grub_gfxterm_init): Check reference counter. + Use init_window. + (destroy_window): New function. + (grub_gfxterm_destroy_window): Likewise. + (grub_gfxterm_fini): Check reference counter. + Use destroy_window. + (redraw_screen_rect): Restore viewport. + Use 'render_target' and 'window'. + Call 'repaint_callback'. + (write_char): Use 'render_target'. + (draw_cursor): Likewise. + (scroll_up): Restore viewport. + Use 'render_target' and 'window'. + Call 'repaint_callback'. + (grub_gfxterm_cls): Likewise. + (grub_gfxterm_refresh): Use 'window'. + (grub_gfxterm_set_repaint_callback): New function. + (grub_gfxterm_background_image_cmd): Use 'window'. + (grub_gfxterm_get_term): New function. + (GRUB_MOD_INIT(term_gfxterm)): Set 'refcount' to 0. diff --git a/include/grub/gfxterm.h b/include/grub/gfxterm.h new file mode 100644 index 000000000..e607bd5e1 --- /dev/null +++ b/include/grub/gfxterm.h @@ -0,0 +1,42 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006,2007,2008 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_GFXTERM_HEADER +#define GRUB_GFXTERM_HEADER 1 + +#include +#include +#include +#include + +grub_err_t +grub_gfxterm_init_window (struct grub_video_render_target *target, + int x, int y, int width, int height, + int double_repaint, + const char *font_name, int border_width); + +void grub_gfxterm_destroy_window (void); + +const struct grub_term_output *grub_gfxterm_get_term (void); + +typedef void (*grub_gfxterm_repaint_callback_t)(int x, int y, + int width, int height); + +void grub_gfxterm_set_repaint_callback (grub_gfxterm_repaint_callback_t func); + +#endif /* ! GRUB_GFXTERM_HEADER */ diff --git a/include/grub/video.h b/include/grub/video.h index a1882f57b..833df04c8 100644 --- a/include/grub/video.h +++ b/include/grub/video.h @@ -157,6 +157,16 @@ struct grub_video_mode_info grub_uint8_t fg_alpha; }; +/* A 2D rectangle type. */ +struct grub_video_rect +{ + int x; + int y; + int width; + int height; +}; +typedef struct grub_video_rect grub_video_rect_t; + struct grub_video_palette_data { grub_uint8_t r; /* Red color value (0-255). */ diff --git a/term/gfxterm.c b/term/gfxterm.c index 62cf98416..3fc151c8b 100644 --- a/term/gfxterm.c +++ b/term/gfxterm.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -103,9 +104,28 @@ struct grub_virtual_screen struct grub_colored_char *text_buffer; }; -static struct grub_virtual_screen virtual_screen; +struct grub_gfxterm_window +{ + unsigned x; + unsigned y; + unsigned width; + unsigned height; + int double_repaint; +}; + +static int refcount; +static struct grub_video_render_target *render_target; +static struct grub_gfxterm_window window; +static struct grub_virtual_screen virtual_screen; +static grub_gfxterm_repaint_callback_t repaint_callback; + +static grub_err_t init_window (struct grub_video_render_target *target, + int x, int y, int width, int height, + int double_repaint, + const char *font_name, int border_width); + +static void destroy_window (void); -static struct grub_video_mode_info mode_info; static struct grub_video_render_target *text_layer; @@ -239,7 +259,7 @@ grub_virtual_screen_setup (unsigned int x, unsigned int y, set_term_color (virtual_screen.term_color); - grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY); + grub_video_set_active_render_target (render_target); /* Clear out text buffer. */ for (i = 0; i < virtual_screen.columns * virtual_screen.rows; i++) @@ -248,21 +268,71 @@ grub_virtual_screen_setup (unsigned int x, unsigned int y, return grub_errno; } +static grub_err_t +init_window (struct grub_video_render_target *target, + int x, int y, int width, int height, int double_repaint, + const char *font_name, int border_width) +{ + /* Clean up any prior instance. */ + destroy_window (); + + /* Set the render target. */ + render_target = target; + + /* Create virtual screen. */ + if (grub_virtual_screen_setup (border_width, border_width, + width - 2 * border_width, + height - 2 * border_width, + font_name) + != GRUB_ERR_NONE) + { + return grub_errno; + } + + /* Set window bounds. */ + window.x = x; + window.y = y; + window.width = width; + window.height = height; + window.double_repaint = double_repaint; + + /* Mark whole window as dirty. */ + dirty_region_reset (); + dirty_region_add (0, 0, width, height); + + return grub_errno; +} + +grub_err_t +grub_gfxterm_init_window (struct grub_video_render_target *target, + int x, int y, int width, int height, + int double_repaint, + const char *font_name, int border_width) +{ + if (refcount++ == 0) + init_window (target, x, y, width, height, double_repaint, + font_name, border_width); + return grub_errno; +} + static grub_err_t grub_gfxterm_init (void) { - char *font_name; - char *modevar; + const char *font_name; + const char *modevar; + struct grub_video_mode_info mode_info; char *tmp; - grub_video_color_t color; - int width; - int height; grub_err_t err; - /* Select the font to use. */ + /* If gfxterm has already been initialized by calling the init_window + function, then leave it alone when it is set as the current terminal. */ + if (refcount++ != 0) + return GRUB_ERR_NONE; + + /* Select the font to use. */ font_name = grub_env_get ("gfxterm_font"); if (! font_name) - font_name = ""; /* Allow fallback to any font. */ + font_name = ""; /* Allow fallback to any font. */ /* Parse gfxmode environment variable if set. */ modevar = grub_env_get ("gfxmode"); @@ -273,6 +343,8 @@ grub_gfxterm_init (void) { tmp = grub_malloc (grub_strlen (modevar) + sizeof (DEFAULT_VIDEO_MODE) + 1); + if (! tmp) + return grub_errno; grub_sprintf (tmp, "%s;" DEFAULT_VIDEO_MODE, modevar); err = grub_video_set_mode (tmp, GRUB_VIDEO_MODE_TYPE_PURE_TEXT, 0); @@ -292,27 +364,29 @@ grub_gfxterm_init (void) grub_video_fill_rect (color, 0, 0, mode_info.width, mode_info.height); bitmap = 0; - /* Leave borders for virtual screen. */ - width = mode_info.width - (2 * DEFAULT_BORDER_WIDTH); - height = mode_info.height - (2 * DEFAULT_BORDER_WIDTH); + /* Select the font to use. */ + font_name = grub_env_get ("gfxterm_font"); + if (! font_name) + font_name = ""; /* Allow fallback to any font. */ - /* Create virtual screen. */ - if (grub_virtual_screen_setup (DEFAULT_BORDER_WIDTH, DEFAULT_BORDER_WIDTH, - width, height, font_name) != GRUB_ERR_NONE) + /* Leave borders for virtual screen. */ + if (init_window (GRUB_VIDEO_RENDER_TARGET_DISPLAY, + 0, 0, mode_info.width, mode_info.height, + mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED + && !(mode_info.mode_type + & GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP), + font_name, + DEFAULT_BORDER_WIDTH) != GRUB_ERR_NONE) { grub_video_restore (); return grub_errno; } - /* Mark whole screen as dirty. */ - dirty_region_reset (); - dirty_region_add (0, 0, mode_info.width, mode_info.height); - - return (grub_errno = GRUB_ERR_NONE); + return grub_errno; } -static grub_err_t -grub_gfxterm_fini (void) +static void +destroy_window (void) { if (bitmap) { @@ -320,11 +394,30 @@ grub_gfxterm_fini (void) bitmap = 0; } + repaint_callback = 0; grub_virtual_screen_free (); +} - grub_video_restore (); +void +grub_gfxterm_destroy_window (void) +{ + if (--refcount == 0) + destroy_window (); +} - return GRUB_ERR_NONE; +static grub_err_t +grub_gfxterm_fini (void) +{ + /* Don't destroy an explicitly initialized terminal instance when it is + unset as the current terminal. */ + if (--refcount == 0) + { + destroy_window (); + grub_video_restore (); + } + + /* Clear error state. */ + return (grub_errno = GRUB_ERR_NONE); } static void @@ -332,9 +425,15 @@ redraw_screen_rect (unsigned int x, unsigned int y, unsigned int width, unsigned int height) { grub_video_color_t color; + grub_video_rect_t saved_view; - grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY); - + grub_video_set_active_render_target (render_target); + /* Save viewport and set it to our window. */ + grub_video_get_viewport ((unsigned *) &saved_view.x, + (unsigned *) &saved_view.y, + (unsigned *) &saved_view.width, + (unsigned *) &saved_view.height); + grub_video_set_viewport (window.x, window.y, window.width, window.height); if (bitmap) { @@ -401,6 +500,14 @@ redraw_screen_rect (unsigned int x, unsigned int y, y - virtual_screen.offset_y, width, height); } + + /* Restore saved viewport. */ + grub_video_set_viewport (saved_view.x, saved_view.y, + saved_view.width, saved_view.height); + grub_video_set_active_render_target (render_target); + + if (repaint_callback) + repaint_callback (x, y, width, height); } static void @@ -515,7 +622,7 @@ write_char (void) grub_video_set_active_render_target (text_layer); grub_video_fill_rect (bgcolor, x, y, width, height); grub_font_draw_glyph (glyph, color, x, y + ascent); - grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY); + grub_video_set_active_render_target (render_target); /* Mark character to be drawn. */ dirty_region_add (virtual_screen.offset_x + x, virtual_screen.offset_y + y, @@ -546,7 +653,7 @@ draw_cursor (int show) /* Render cursor to text layer. */ grub_video_set_active_render_target (text_layer); grub_video_fill_rect (color, x, y, width, height); - grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY); + grub_video_set_active_render_target (render_target); /* Mark cursor to be redrawn. */ dirty_region_add (virtual_screen.offset_x + x, @@ -594,10 +701,18 @@ scroll_up (void) } else { - int i = 1; - if (mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED - && !(mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP)) - i++; + grub_video_rect_t saved_view; + int i; + + grub_video_set_active_render_target (render_target); + /* Save viewport and set it to our window. */ + grub_video_get_viewport ((unsigned *) &saved_view.x, + (unsigned *) &saved_view.y, + (unsigned *) &saved_view.width, + (unsigned *) &saved_view.height); + grub_video_set_viewport (window.x, window.y, window.width, window.height); + + i = window.double_repaint ? 2 : 1; color = virtual_screen.bg_color; @@ -610,7 +725,7 @@ scroll_up (void) virtual_screen.width, virtual_screen.normal_char_height); - grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY); + grub_video_set_active_render_target (render_target); dirty_region_redraw (); /* Scroll physical screen. */ @@ -626,11 +741,18 @@ scroll_up (void) color = virtual_screen.bg_color; grub_video_scroll (color, 0, -virtual_screen.normal_char_height); + /* Restore saved viewport. */ + grub_video_set_viewport (saved_view.x, saved_view.y, + saved_view.width, saved_view.height); + grub_video_set_active_render_target (render_target); /* Draw cursor if visible. */ if (virtual_screen.cursor_state) draw_cursor (1); } + + if (repaint_callback) + repaint_callback (window.x, window.y, window.width, window.height); } static void @@ -833,8 +955,9 @@ grub_gfxterm_cls (void) /* Clear text layer. */ grub_video_set_active_render_target (text_layer); color = virtual_screen.bg_color; - grub_video_fill_rect (color, 0, 0, mode_info.width, mode_info.height); - grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY); + grub_video_fill_rect (color, 0, 0, + virtual_screen.width, virtual_screen.height); + grub_video_set_active_render_target (render_target); /* Mark virtual screen to be redrawn. */ dirty_region_add_virtualscreen (); @@ -905,12 +1028,17 @@ grub_gfxterm_refresh (void) grub_video_swap_buffers (); - if (mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED - && !(mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP)) + if (window.double_repaint) dirty_region_redraw (); dirty_region_reset (); } +void +grub_gfxterm_set_repaint_callback (grub_gfxterm_repaint_callback_t func) +{ + repaint_callback = func; +} + /* Option array indices. */ #define BACKGROUND_CMD_ARGINDEX_MODE 0 @@ -940,7 +1068,7 @@ grub_gfxterm_background_image_cmd (grub_extcmd_t cmd __attribute__ ((unused)), /* Mark whole screen as dirty. */ dirty_region_reset (); - dirty_region_add (0, 0, mode_info.width, mode_info.height); + dirty_region_add (0, 0, window.width, window.height); } /* If filename was provided, try to load that. */ @@ -956,13 +1084,13 @@ grub_gfxterm_background_image_cmd (grub_extcmd_t cmd __attribute__ ((unused)), || grub_strcmp (state[BACKGROUND_CMD_ARGINDEX_MODE].arg, "stretch") == 0) { - if (mode_info.width != grub_video_bitmap_get_width (bitmap) - || mode_info.height != grub_video_bitmap_get_height (bitmap)) + if (window.width != grub_video_bitmap_get_width (bitmap) + || window.height != grub_video_bitmap_get_height (bitmap)) { struct grub_video_bitmap *scaled_bitmap; grub_video_bitmap_create_scaled (&scaled_bitmap, - mode_info.width, - mode_info.height, + window.width, + window.height, bitmap, GRUB_VIDEO_BITMAP_SCALE_METHOD_BEST); if (grub_errno == GRUB_ERR_NONE) @@ -979,11 +1107,11 @@ grub_gfxterm_background_image_cmd (grub_extcmd_t cmd __attribute__ ((unused)), { /* Determine bitmap dimensions. */ bitmap_width = grub_video_bitmap_get_width (bitmap); - bitmap_height = grub_video_bitmap_get_width (bitmap); + bitmap_height = grub_video_bitmap_get_height (bitmap); /* Mark whole screen as dirty. */ dirty_region_reset (); - dirty_region_add (0, 0, mode_info.width, mode_info.height); + dirty_region_add (0, 0, window.width, window.height); } } @@ -1012,10 +1140,18 @@ static struct grub_term_output grub_video_term = .next = 0 }; +const struct grub_term_output * +grub_gfxterm_get_term (void) +{ + return &grub_video_term; +} + static grub_extcmd_t background_image_cmd_handle; GRUB_MOD_INIT(term_gfxterm) { + refcount = 0; + grub_term_register_output ("gfxterm", &grub_video_term); background_image_cmd_handle = grub_register_extcmd ("background_image", From 927d0134c72432fd1cdff4591cc5eee6a509d60f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 20 Nov 2009 10:28:42 +0100 Subject: [PATCH 082/738] SDL --- Makefile.in | 2 + conf/i386-pc.rmk | 6 ++ configure.ac | 34 ++++++ util/sdl.c | 263 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 305 insertions(+) create mode 100644 util/sdl.c diff --git a/Makefile.in b/Makefile.in index 7706cd26b..f2b4e7fc0 100644 --- a/Makefile.in +++ b/Makefile.in @@ -107,12 +107,14 @@ endif AWK = @AWK@ LIBCURSES = @LIBCURSES@ LIBUSB = @LIBUSB@ +LIBSDL = @LIBSDL@ YACC = @YACC@ UNIFONT_BDF = @UNIFONT_BDF@ # Options. enable_grub_emu = @enable_grub_emu@ enable_grub_emu_usb = @enable_grub_emu_usb@ +enable_grub_emu_sdl = @enable_grub_emu_sdl@ enable_grub_fstest = @enable_grub_fstest@ enable_grub_pe2elf = @enable_grub_pe2elf@ enable_grub_mkfont = @enable_grub_mkfont@ diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk index e1688ccd5..382c45ca3 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -153,6 +153,12 @@ grub_emu_SOURCES = commands/minicmd.c commands/cat.c commands/cmp.c \ fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/afs_be.c \ fs/befs.c fs/befs_be.c fs/tar.c \ \ + video/video.c video/fb/video_fb.c video/fb/fbblit.c \ + video/fb/fbfill.c video/fb/fbutil.c commands/videotest.c \ + video/bitmap.c video/readers/tga.c video/readers/jpeg.c \ + video/readers/png.c font/font_cmd.c font/font.c term/gfxterm.c \ + io/bufio.c \ + \ util/console.c util/hostfs.c util/grub-emu.c util/misc.c \ util/hostdisk.c util/getroot.c \ \ diff --git a/configure.ac b/configure.ac index 587f2118d..d2b281639 100644 --- a/configure.ac +++ b/configure.ac @@ -519,6 +519,10 @@ if test x"$enable_grub_emu" = xno ; then grub_emu_excuse="explicitly disabled" fi +AC_ARG_ENABLE([grub-emu-sdl], + [AS_HELP_STRING([--enable-grub-emu-sdl], + [build and install the `grub-emu' debugging utility with SDL support (default=guessed)])]) + [# Check for curses libraries.] [if [ x"$grub_emu_excuse" = x ]; then ] AC_CHECK_LIB([ncurses], [wgetch], [LIBCURSES="-lncurses"], @@ -567,6 +571,31 @@ enable_grub_emu_usb=no fi AC_SUBST([enable_grub_emu]) + +if test x"$enable_grub_emu_sdl" = xno ; then + grub_emu_sdl_excuse="explicitely disabled" +fi +[if [ x"$grub_emu_sdl_excuse" = x ]; then + # Check for libSDL libraries.] +AC_CHECK_LIB([SDL], [SDL_Init], [LIBSDL="-lSDL"], + [grub_emu_sdl_excuse=["libSDL libraries are required to build \`grub-emu' with SDL support"]]) + AC_SUBST([LIBSDL]) +[fi] +[if [ x"$grub_emu_sdl_excuse" = x ]; then + # Check for headers.] + AC_CHECK_HEADERS([SDL/SDL.h], [], + [grub_emu_sdl_excuse=["libSDL header file is required to build \`grub-emu' with SDL support"]]) +[fi] +if test x"enable_grub_emu_sdl" = xyes && test x"$grub_emu_sdl_excuse" != x ; then + AC_MSG_ERROR([SDL support for grub-emu was explicitely requested but can't be compiled]) +fi +if test x"$grub_emu_sdl_excuse" = x ; then +enable_grub_emu_sdl=yes +else +enable_grub_emu_sdl=no +fi + +AC_SUBST([enable_grub_emu_sdl]) AC_SUBST([enable_grub_emu_usb]) AC_ARG_ENABLE([grub-fstest], @@ -641,6 +670,11 @@ echo USB support for grub-emu: Yes else echo USB support for grub-emu: No "($grub_emu_usb_excuse)" fi +if [ x"$grub_emu_sdl_excuse" = x ]; then +echo SDL support for grub-emu: Yes +else +echo SDL support for grub-emu: No "($grub_emu_sdl_excuse)" +fi if [ x"$enable_mm_debug" = xyes ]; then echo With memory debugging: Yes else diff --git a/util/sdl.c b/util/sdl.c new file mode 100644 index 000000000..a5a310518 --- /dev/null +++ b/util/sdl.c @@ -0,0 +1,263 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2006,2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#define grub_video_render_target grub_video_fbrender_target + +#include +#include +#include +#include +#include +#include +#include +#include + +static SDL_Surface *window = 0; +static struct grub_video_render_target *sdl_render_target; +static struct grub_video_mode_info mode_info; + +static grub_err_t +grub_video_sdl_set_palette (unsigned int start, unsigned int count, + struct grub_video_palette_data *palette_data); + +static grub_err_t +grub_video_sdl_init (void) +{ + window = 0; + + if (SDL_Init (SDL_INIT_VIDEO) < 0) + return grub_error (GRUB_ERR_BAD_DEVICE, "Couldn't init SDL: %s", + SDL_GetError ()); + + grub_memset (&mode_info, 0, sizeof (mode_info)); + + return grub_video_fb_init (); +} + +static grub_err_t +grub_video_sdl_fini (void) +{ + SDL_Quit (); + window = 0; + + grub_memset (&mode_info, 0, sizeof (mode_info)); + + return grub_video_fb_fini (); +} + +static inline unsigned int +get_mask_size (grub_uint32_t mask) +{ + unsigned i; + for (i = 0; mask > 1U << i; i++); + return i; +} + +static grub_err_t +grub_video_sdl_setup (unsigned int width, unsigned int height, + unsigned int mode_type, unsigned int mode_mask) +{ + int depth; + int flags = 0; + grub_err_t err; + + /* Decode depth from mode_type. If it is zero, then autodetect. */ + depth = (mode_type & GRUB_VIDEO_MODE_TYPE_DEPTH_MASK) + >> GRUB_VIDEO_MODE_TYPE_DEPTH_POS; + + if (depth == 0) + depth = 32; + + if (width == 0 && height == 0) + { + width = 800; + height = 600; + } + + if ((mode_type & GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED) + || !(mode_mask & GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED)) + flags |= SDL_DOUBLEBUF; + + window = SDL_SetVideoMode (width, height, depth, flags | SDL_HWSURFACE); + if (! window) + window = SDL_SetVideoMode (width, height, depth, flags | SDL_SWSURFACE); + if (! window) + return grub_error (GRUB_ERR_BAD_DEVICE, "Couldn't open window: %s", + SDL_GetError ()); + + grub_memset (&sdl_render_target, 0, sizeof (sdl_render_target)); + + mode_info.width = window->w; + mode_info.height = window->h; + mode_info.mode_type = 0; + if (window->flags & SDL_DOUBLEBUF) + mode_info.mode_type + |= GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED; + if (window->format->palette) + mode_info.mode_type |= GRUB_VIDEO_MODE_TYPE_INDEX_COLOR; + else + mode_info.mode_type |= GRUB_VIDEO_MODE_TYPE_RGB; + + mode_info.bpp = window->format->BitsPerPixel; + mode_info.bytes_per_pixel = window->format->BytesPerPixel; + mode_info.pitch = window->pitch; + + /* In index color mode, number of colors. In RGB mode this is 256. */ + if (window->format->palette) + mode_info.number_of_colors + = 1 << window->format->BitsPerPixel; + else + mode_info.number_of_colors = 256; + + if (! window->format->palette) + { + mode_info.red_mask_size + = get_mask_size (window->format->Rmask >> window->format->Rshift); + mode_info.red_field_pos = window->format->Rshift; + mode_info.green_mask_size + = get_mask_size (window->format->Gmask >> window->format->Gshift); + mode_info.green_field_pos = window->format->Gshift; + mode_info.blue_mask_size + = get_mask_size (window->format->Bmask >> window->format->Bshift); + mode_info.blue_field_pos = window->format->Bshift; + mode_info.reserved_mask_size + = get_mask_size (window->format->Amask >> window->format->Ashift); + mode_info.reserved_field_pos = window->format->Ashift; + mode_info.blit_format + = grub_video_get_blit_format (&mode_info); + } + + err = grub_video_fb_create_render_target_from_pointer (&sdl_render_target, + &mode_info, + window->pixels); + if (err) + return err; + + /* Copy default palette to initialize emulated palette. */ + grub_video_sdl_set_palette (0, (sizeof (grub_video_fbstd_colors) + / sizeof (grub_video_fbstd_colors[0])), + grub_video_fbstd_colors); + + /* Reset render target to SDL one. */ + return grub_video_fb_set_active_render_target (sdl_render_target); +} + +static grub_err_t +grub_video_sdl_set_palette (unsigned int start, unsigned int count, + struct grub_video_palette_data *palette_data) +{ + unsigned i; + if (window->format->palette) + { + SDL_Color *tmp = grub_malloc (count * sizeof (tmp[0])); + for (i = 0; i < count; i++) + { + tmp[i].r = palette_data[i].r; + tmp[i].g = palette_data[i].g; + tmp[i].b = palette_data[i].b; + tmp[i].unused = palette_data[i].a; + } + SDL_SetColors (window, tmp, start, count); + grub_free (tmp); + } + + return grub_video_fb_set_palette (start, count, palette_data); +} + +grub_err_t +grub_video_sdl_set_viewport (unsigned int x, unsigned int y, + unsigned int width, unsigned int height) +{ + /* Make sure viewport is withing screen dimensions. If viewport was set + to be out of the region, mark its size as zero. */ + if (x > (unsigned) window->w) + { + x = 0; + width = 0; + } + + if (y > (unsigned) window->h) + { + y = 0; + height = 0; + } + + if (x + width > (unsigned) window->w) + width = window->w - x; + + if (y + height > (unsigned) window->h) + height = window->h - y; + return grub_video_fb_set_viewport (x, y, width, height); +} + +static grub_err_t +grub_video_sdl_swap_buffers (void) +{ + if (SDL_Flip (window) < 0) + return grub_error (GRUB_ERR_BAD_DEVICE, "couldn't swap buffers: %s", + SDL_GetError ()); + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_video_sdl_set_active_render_target (struct grub_video_render_target *target) +{ + if (target == GRUB_VIDEO_RENDER_TARGET_DISPLAY) + return grub_video_fb_set_active_render_target (sdl_render_target); + + return grub_video_fb_set_active_render_target (target); +} + +static struct grub_video_adapter grub_video_sdl_adapter = + { + .name = "SDL Video Driver", + + .init = grub_video_sdl_init, + .fini = grub_video_sdl_fini, + .setup = grub_video_sdl_setup, + .get_info = grub_video_fb_get_info, + .set_palette = grub_video_sdl_set_palette, + .get_palette = grub_video_fb_get_palette, + .set_viewport = grub_video_fb_set_viewport, + .get_viewport = grub_video_fb_get_viewport, + .map_color = grub_video_fb_map_color, + .map_rgb = grub_video_fb_map_rgb, + .map_rgba = grub_video_fb_map_rgba, + .unmap_color = grub_video_fb_unmap_color, + .fill_rect = grub_video_fb_fill_rect, + .blit_bitmap = grub_video_fb_blit_bitmap, + .blit_render_target = grub_video_fb_blit_render_target, + .scroll = grub_video_fb_scroll, + .swap_buffers = grub_video_sdl_swap_buffers, + .create_render_target = grub_video_fb_create_render_target, + .delete_render_target = grub_video_fb_delete_render_target, + .set_active_render_target = grub_video_sdl_set_active_render_target, + .get_active_render_target = grub_video_fb_get_active_render_target, + + .next = 0 + }; + +GRUB_MOD_INIT(sdl) +{ + grub_video_register (&grub_video_sdl_adapter); +} + +GRUB_MOD_FINI(sdl) +{ + grub_video_unregister (&grub_video_sdl_adapter); +} From a9d407a81e6761a24f4816d43035e7accdc1ad4d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 20 Nov 2009 10:46:30 +0100 Subject: [PATCH 083/738] Reimported scaling --- ChangeLog.scale | 16 ++ conf/common.rmk | 6 + include/grub/bitmap_scale.h | 48 ++++++ include/grub/xnu.h | 3 + loader/i386/pc/xnu.c | 45 ++++-- loader/xnu.c | 37 ++++- term/gfxterm.c | 53 ++++++- video/bitmap_scale.c | 308 ++++++++++++++++++++++++++++++++++++ 8 files changed, 490 insertions(+), 26 deletions(-) create mode 100644 ChangeLog.scale create mode 100644 include/grub/bitmap_scale.h create mode 100644 video/bitmap_scale.c diff --git a/ChangeLog.scale b/ChangeLog.scale new file mode 100644 index 000000000..eb12d3b21 --- /dev/null +++ b/ChangeLog.scale @@ -0,0 +1,16 @@ +2009-08-24 Colin D Bennett + + Bitmap scaling support. + + * conf/common.rmk (pkglib_MODULES): Add bitmap_scale.mod. + (bitmap_scale_mod_SOURCES): New variable. + (bitmap_scale_mod_CFLAGS): Likewise. + (bitmap_scale_mod_LDFLAGS): Likewise. + * include/grub/bitmap_scale.h: New file. + * term/gfxterm.c (BACKGROUND_CMD_ARGINDEX_MODE): New definiton. + (background_image_cmd_options): New variable. + (grub_gfxterm_background_image_cmd): Support bitmap stretching. + (cmd): Rename and change type to ... + (background_image_cmd_handle): ... this. All users updated. + (GRUB_MOD_INIT(term_gfxterm)): Make background_image extended command. + * video/bitmap_scale.c: New file. diff --git a/conf/common.rmk b/conf/common.rmk index 173f24b62..98681bc1c 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -567,6 +567,12 @@ bitmap_mod_SOURCES = video/bitmap.c bitmap_mod_CFLAGS = $(COMMON_CFLAGS) bitmap_mod_LDFLAGS = $(COMMON_LDFLAGS) +# For bitmap_scale.mod +pkglib_MODULES += bitmap_scale.mod +bitmap_scale_mod_SOURCES = video/bitmap_scale.c +bitmap_scale_mod_CFLAGS = $(COMMON_CFLAGS) +bitmap_scale_mod_LDFLAGS = $(COMMON_LDFLAGS) + # For tga.mod tga_mod_SOURCES = video/readers/tga.c tga_mod_CFLAGS = $(COMMON_CFLAGS) diff --git a/include/grub/bitmap_scale.h b/include/grub/bitmap_scale.h new file mode 100644 index 000000000..7ea9d7914 --- /dev/null +++ b/include/grub/bitmap_scale.h @@ -0,0 +1,48 @@ +/* bitmap_scale.h - Bitmap scaling functions. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_BITMAP_SCALE_HEADER +#define GRUB_BITMAP_SCALE_HEADER 1 + +#include +#include +#include + +enum grub_video_bitmap_scale_method +{ + /* Choose the fastest interpolation algorithm. */ + GRUB_VIDEO_BITMAP_SCALE_METHOD_FASTEST, + /* Choose the highest quality interpolation algorithm. */ + GRUB_VIDEO_BITMAP_SCALE_METHOD_BEST, + + /* Specific algorithms: */ + /* Nearest neighbor interpolation. */ + GRUB_VIDEO_BITMAP_SCALE_METHOD_NEAREST, + /* Bilinear interpolation. */ + GRUB_VIDEO_BITMAP_SCALE_METHOD_BILINEAR +}; + +grub_err_t +grub_video_bitmap_create_scaled (struct grub_video_bitmap **dst, + int dst_width, int dst_height, + struct grub_video_bitmap *src, + enum + grub_video_bitmap_scale_method scale_method); + +#endif /* ! GRUB_BITMAP_SCALE_HEADER */ diff --git a/include/grub/xnu.h b/include/grub/xnu.h index c3902e670..b058bd1b9 100644 --- a/include/grub/xnu.h +++ b/include/grub/xnu.h @@ -104,4 +104,7 @@ extern grub_uint32_t grub_xnu_heap_real_start; extern grub_size_t grub_xnu_heap_size; extern char *grub_xnu_heap_start; extern struct grub_video_bitmap *grub_xnu_bitmap; +typedef enum {GRUB_XNU_BITMAP_CENTER, GRUB_XNU_BITMAP_STRETCH} + grub_xnu_bitmap_mode_t; +extern grub_xnu_bitmap_mode_t grub_xnu_bitmap_mode; #endif diff --git a/loader/i386/pc/xnu.c b/loader/i386/pc/xnu.c index 839d0ad44..1a222e6e5 100644 --- a/loader/i386/pc/xnu.c +++ b/loader/i386/pc/xnu.c @@ -22,6 +22,7 @@ #include #include #include +#include #define min(a,b) (((a) < (b)) ? (a) : (b)) #define max(a,b) (((a) > (b)) ? (a) : (b)) @@ -37,6 +38,7 @@ grub_xnu_set_video (struct grub_xnu_boot_params *params) char *tmp, *modevar; void *framebuffer; grub_err_t err; + struct grub_video_bitmap *bitmap = NULL; modevar = grub_env_get ("gfxpayload"); /* Consider only graphical 32-bit deep modes. */ @@ -63,31 +65,46 @@ grub_xnu_set_video (struct grub_xnu_boot_params *params) if (err) return err; + ret = grub_video_get_info (&mode_info); + if (ret) + return grub_error (GRUB_ERR_IO, "couldn't retrieve video parameters"); + if (grub_xnu_bitmap) + { + if (grub_xnu_bitmap_mode == GRUB_XNU_BITMAP_STRETCH) + err = grub_video_bitmap_create_scaled (&bitmap, + mode_info.width, + mode_info.height, + grub_xnu_bitmap, + GRUB_VIDEO_BITMAP_SCALE_METHOD_BEST); + else + bitmap = grub_xnu_bitmap; + } + + if (bitmap) { int x, y; - x = mode_info.width - grub_xnu_bitmap->mode_info.width; + x = mode_info.width - bitmap->mode_info.width; x /= 2; - y = mode_info.height - grub_xnu_bitmap->mode_info.height; + y = mode_info.height - bitmap->mode_info.height; y /= 2; - err = grub_video_blit_bitmap (grub_xnu_bitmap, + err = grub_video_blit_bitmap (bitmap, GRUB_VIDEO_BLIT_REPLACE, x > 0 ? x : 0, y > 0 ? y : 0, x < 0 ? -x : 0, y < 0 ? -y : 0, - min (grub_xnu_bitmap->mode_info.width, + min (bitmap->mode_info.width, mode_info.width), - min (grub_xnu_bitmap->mode_info.height, + min (bitmap->mode_info.height, mode_info.height)); - if (err) - { - grub_print_error (); - grub_errno = GRUB_ERR_NONE; - grub_xnu_bitmap = 0; - } - err = GRUB_ERR_NONE; + } + if (err) + { + grub_print_error (); + grub_errno = GRUB_ERR_NONE; + bitmap = 0; } ret = grub_video_get_info_and_fini (&mode_info, &framebuffer); @@ -100,8 +117,8 @@ grub_xnu_set_video (struct grub_xnu_boot_params *params) params->lfb_line_len = mode_info.pitch; params->lfb_base = PTR_TO_UINT32 (framebuffer); - params->lfb_mode = grub_xnu_bitmap - ? GRUB_XNU_VIDEO_SPLASH : GRUB_XNU_VIDEO_TEXT_IN_VIDEO; + params->lfb_mode = bitmap ? GRUB_XNU_VIDEO_SPLASH + : GRUB_XNU_VIDEO_TEXT_IN_VIDEO; return GRUB_ERR_NONE; } diff --git a/loader/xnu.c b/loader/xnu.c index aac4ae372..e0ae9cefe 100644 --- a/loader/xnu.c +++ b/loader/xnu.c @@ -31,6 +31,7 @@ #include #include #include +#include struct grub_xnu_devtree_key *grub_xnu_devtree_root = 0; static int driverspackagenum = 0; @@ -1272,18 +1273,37 @@ grub_cmd_xnu_kextdir (grub_command_t cmd __attribute__ ((unused)), } struct grub_video_bitmap *grub_xnu_bitmap = 0; +grub_xnu_bitmap_mode_t grub_xnu_bitmap_mode; + +/* Option array indices. */ +#define XNU_SPLASH_CMD_ARGINDEX_MODE 0 + +static const struct grub_arg_option xnu_splash_cmd_options[] = + { + {"mode", 'm', 0, "Background image mode.", "stretch|normal", + ARG_TYPE_STRING}, + {0, 0, 0, 0, 0, 0} + }; static grub_err_t -grub_cmd_xnu_splash (grub_command_t cmd __attribute__ ((unused)), +grub_cmd_xnu_splash (grub_extcmd_t cmd, int argc, char *args[]) { grub_err_t err; if (argc != 1) return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required"); + if (cmd->state[XNU_SPLASH_CMD_ARGINDEX_MODE].set && + grub_strcmp (cmd->state[XNU_SPLASH_CMD_ARGINDEX_MODE].arg, + "stretch") == 0) + grub_xnu_bitmap_mode = GRUB_XNU_BITMAP_STRETCH; + else + grub_xnu_bitmap_mode = GRUB_XNU_BITMAP_CENTER; + err = grub_video_bitmap_load (&grub_xnu_bitmap, args[0]); if (err) grub_xnu_bitmap = 0; + return err; } @@ -1316,8 +1336,10 @@ grub_xnu_unlock () locked = 0; } -static grub_command_t cmd_kernel, cmd_mkext, cmd_kext, cmd_kextdir, - cmd_ramdisk, cmd_devtree, cmd_resume, cmd_splash; +static grub_command_t cmd_kernel, cmd_mkext, cmd_kext, ; +static grub_command_t cmd_devtree; +static grub_command_t cmd_kextdir, cmd_ramdisk, cmd_resume; +static grub_extcmd_t cmd_splash; GRUB_MOD_INIT(xnu) { @@ -1335,8 +1357,11 @@ GRUB_MOD_INIT(xnu) "It will be seen as md0"); cmd_devtree = grub_register_command ("xnu_devtree", grub_cmd_xnu_devtree, 0, "Load XNU devtree"); - cmd_splash = grub_register_command ("xnu_splash", grub_cmd_xnu_splash, 0, - "Load a splash image for XNU"); + cmd_splash = grub_register_extcmd ("xnu_splash", + grub_cmd_xnu_splash, + GRUB_COMMAND_FLAG_BOTH, 0, + "Load a splash image for XNU", + xnu_splash_cmd_options); #ifndef GRUB_UTIL cmd_resume = grub_register_command ("xnu_resume", grub_cmd_xnu_resume, @@ -1356,5 +1381,5 @@ GRUB_MOD_FINI(xnu) grub_unregister_command (cmd_devtree); grub_unregister_command (cmd_ramdisk); grub_unregister_command (cmd_kernel); - grub_unregister_command (cmd_splash); + grub_unregister_extcmd (cmd_splash); } diff --git a/term/gfxterm.c b/term/gfxterm.c index 6906b77a1..62cf98416 100644 --- a/term/gfxterm.c +++ b/term/gfxterm.c @@ -26,6 +26,8 @@ #include #include #include +#include +#include #define DEFAULT_VIDEO_MODE "auto" #define DEFAULT_BORDER_WIDTH 10 @@ -909,11 +911,23 @@ grub_gfxterm_refresh (void) dirty_region_reset (); } +/* Option array indices. */ +#define BACKGROUND_CMD_ARGINDEX_MODE 0 + +static const struct grub_arg_option background_image_cmd_options[] = + { + {"mode", 'm', 0, "Background image mode.", "stretch|normal", + ARG_TYPE_STRING}, + {0, 0, 0, 0, 0, 0} + }; + static grub_err_t -grub_gfxterm_background_image_cmd (grub_command_t cmd __attribute__ ((unused)), +grub_gfxterm_background_image_cmd (grub_extcmd_t cmd __attribute__ ((unused)), int argc, char **args) { + struct grub_arg_list *state = cmd->state; + /* Check that we have video adapter active. */ if (grub_video_get_info(NULL) != GRUB_ERR_NONE) return grub_errno; @@ -937,6 +951,29 @@ grub_gfxterm_background_image_cmd (grub_command_t cmd __attribute__ ((unused)), if (grub_errno != GRUB_ERR_NONE) return grub_errno; + /* Determine if the bitmap should be scaled to fit the screen. */ + if (!state[BACKGROUND_CMD_ARGINDEX_MODE].set + || grub_strcmp (state[BACKGROUND_CMD_ARGINDEX_MODE].arg, + "stretch") == 0) + { + if (mode_info.width != grub_video_bitmap_get_width (bitmap) + || mode_info.height != grub_video_bitmap_get_height (bitmap)) + { + struct grub_video_bitmap *scaled_bitmap; + grub_video_bitmap_create_scaled (&scaled_bitmap, + mode_info.width, + mode_info.height, + bitmap, + GRUB_VIDEO_BITMAP_SCALE_METHOD_BEST); + if (grub_errno == GRUB_ERR_NONE) + { + /* Replace the original bitmap with the scaled one. */ + grub_video_bitmap_destroy (bitmap); + bitmap = scaled_bitmap; + } + } + } + /* If bitmap was loaded correctly, display it. */ if (bitmap) { @@ -975,18 +1012,22 @@ static struct grub_term_output grub_video_term = .next = 0 }; -static grub_command_t cmd; +static grub_extcmd_t background_image_cmd_handle; GRUB_MOD_INIT(term_gfxterm) { grub_term_register_output ("gfxterm", &grub_video_term); - cmd = grub_register_command ("background_image", - grub_gfxterm_background_image_cmd, - 0, "Load background image for active terminal"); + background_image_cmd_handle = + grub_register_extcmd ("background_image", + grub_gfxterm_background_image_cmd, + GRUB_COMMAND_FLAG_BOTH, + "background_image [-m (stretch|normal)] FILE", + "Load background image for active terminal.", + background_image_cmd_options); } GRUB_MOD_FINI(term_gfxterm) { - grub_unregister_command (cmd); + grub_unregister_extcmd (background_image_cmd_handle); grub_term_unregister_output (&grub_video_term); } diff --git a/video/bitmap_scale.c b/video/bitmap_scale.c new file mode 100644 index 000000000..6f8ff247e --- /dev/null +++ b/video/bitmap_scale.c @@ -0,0 +1,308 @@ +/* bitmap_scale.c - Bitmap scaling. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006,2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +/* Prototypes for module-local functions. */ +static grub_err_t scale_nn (struct grub_video_bitmap *dst, + struct grub_video_bitmap *src); +static grub_err_t scale_bilinear (struct grub_video_bitmap *dst, + struct grub_video_bitmap *src); + +/* This function creates a new scaled version of the bitmap SRC. The new + bitmap has dimensions DST_WIDTH by DST_HEIGHT. The scaling algorithm + is given by SCALE_METHOD. If an error is encountered, the return code is + not equal to GRUB_ERR_NONE, and the bitmap DST is either not created, or + it is destroyed before this function returns. + + Supports only direct color modes which have components separated + into bytes (e.g., RGBA 8:8:8:8 or BGR 8:8:8 true color). + But because of this simplifying assumption, the implementation is + greatly simplified. */ +grub_err_t +grub_video_bitmap_create_scaled (struct grub_video_bitmap **dst, + int dst_width, int dst_height, + struct grub_video_bitmap *src, + enum grub_video_bitmap_scale_method + scale_method) +{ + *dst = 0; + + /* Verify the simplifying assumptions. */ + if (src == 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "null src bitmap in grub_video_bitmap_create_scaled"); + if (src->mode_info.red_field_pos % 8 != 0 + || src->mode_info.green_field_pos % 8 != 0 + || src->mode_info.blue_field_pos % 8 != 0 + || src->mode_info.reserved_field_pos % 8 != 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "src format not supported for scale"); + if (src->mode_info.width == 0 || src->mode_info.height == 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "source bitmap has a zero dimension"); + if (dst_width <= 0 || dst_height <= 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "requested to scale to a size w/ a zero dimension"); + if (src->mode_info.bytes_per_pixel * 8 != src->mode_info.bpp) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "bitmap to scale has inconsistent Bpp and bpp"); + + /* Create the new bitmap. */ + grub_err_t ret; + ret = grub_video_bitmap_create (dst, dst_width, dst_height, + src->mode_info.blit_format); + if (ret != GRUB_ERR_NONE) + return ret; /* Error. */ + + switch (scale_method) + { + case GRUB_VIDEO_BITMAP_SCALE_METHOD_FASTEST: + case GRUB_VIDEO_BITMAP_SCALE_METHOD_NEAREST: + ret = scale_nn (*dst, src); + break; + case GRUB_VIDEO_BITMAP_SCALE_METHOD_BEST: + case GRUB_VIDEO_BITMAP_SCALE_METHOD_BILINEAR: + ret = scale_bilinear (*dst, src); + break; + default: + ret = grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid scale_method value"); + break; + } + + if (ret == GRUB_ERR_NONE) + { + /* Success: *dst is now a pointer to the scaled bitmap. */ + return GRUB_ERR_NONE; + } + else + { + /* Destroy the bitmap and return the error code. */ + grub_video_bitmap_destroy (*dst); + *dst = 0; + return ret; + } +} + +/* Nearest neighbor bitmap scaling algorithm. + + Copy the bitmap SRC to the bitmap DST, scaling the bitmap to fit the + dimensions of DST. This function uses the nearest neighbor algorithm to + interpolate the pixels. + + Supports only direct color modes which have components separated + into bytes (e.g., RGBA 8:8:8:8 or BGR 8:8:8 true color). + But because of this simplifying assumption, the implementation is + greatly simplified. */ +static grub_err_t +scale_nn (struct grub_video_bitmap *dst, struct grub_video_bitmap *src) +{ + /* Verify the simplifying assumptions. */ + if (dst == 0 || src == 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "null bitmap in scale_nn"); + if (dst->mode_info.red_field_pos % 8 != 0 + || dst->mode_info.green_field_pos % 8 != 0 + || dst->mode_info.blue_field_pos % 8 != 0 + || dst->mode_info.reserved_field_pos % 8 != 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "dst format not supported"); + if (src->mode_info.red_field_pos % 8 != 0 + || src->mode_info.green_field_pos % 8 != 0 + || src->mode_info.blue_field_pos % 8 != 0 + || src->mode_info.reserved_field_pos % 8 != 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "src format not supported"); + if (dst->mode_info.red_field_pos != src->mode_info.red_field_pos + || dst->mode_info.red_mask_size != src->mode_info.red_mask_size + || dst->mode_info.green_field_pos != src->mode_info.green_field_pos + || dst->mode_info.green_mask_size != src->mode_info.green_mask_size + || dst->mode_info.blue_field_pos != src->mode_info.blue_field_pos + || dst->mode_info.blue_mask_size != src->mode_info.blue_mask_size + || dst->mode_info.reserved_field_pos != + src->mode_info.reserved_field_pos + || dst->mode_info.reserved_mask_size != + src->mode_info.reserved_mask_size) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "dst and src not compatible"); + if (dst->mode_info.bytes_per_pixel != src->mode_info.bytes_per_pixel) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "dst and src not compatible"); + if (dst->mode_info.width == 0 || dst->mode_info.height == 0 + || src->mode_info.width == 0 || src->mode_info.height == 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "bitmap has a zero dimension"); + + grub_uint8_t *ddata = dst->data; + grub_uint8_t *sdata = src->data; + int dw = dst->mode_info.width; + int dh = dst->mode_info.height; + int sw = src->mode_info.width; + int sh = src->mode_info.height; + int dstride = dst->mode_info.pitch; + int sstride = src->mode_info.pitch; + /* bytes_per_pixel is the same for both src and dst. */ + int bytes_per_pixel = dst->mode_info.bytes_per_pixel; + + int dy; + for (dy = 0; dy < dh; dy++) + { + int dx; + for (dx = 0; dx < dw; dx++) + { + grub_uint8_t *dptr; + grub_uint8_t *sptr; + int sx; + int sy; + int comp; + + /* Compute the source coordinate that the destination coordinate + maps to. Note: sx/sw = dx/dw => sx = sw*dx/dw. */ + sx = sw * dx / dw; + sy = sh * dy / dh; + + /* Get the address of the pixels in src and dst. */ + dptr = ddata + dy * dstride + dx * bytes_per_pixel; + sptr = sdata + sy * sstride + sx * bytes_per_pixel; + + /* Copy the pixel color value. */ + for (comp = 0; comp < bytes_per_pixel; comp++) + dptr[comp] = sptr[comp]; + } + } + return GRUB_ERR_NONE; +} + +/* Bilinear interpolation image scaling algorithm. + + Copy the bitmap SRC to the bitmap DST, scaling the bitmap to fit the + dimensions of DST. This function uses the bilinear interpolation algorithm + to interpolate the pixels. + + Supports only direct color modes which have components separated + into bytes (e.g., RGBA 8:8:8:8 or BGR 8:8:8 true color). + But because of this simplifying assumption, the implementation is + greatly simplified. */ +static grub_err_t +scale_bilinear (struct grub_video_bitmap *dst, struct grub_video_bitmap *src) +{ + /* Verify the simplifying assumptions. */ + if (dst == 0 || src == 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "null bitmap in scale func"); + if (dst->mode_info.red_field_pos % 8 != 0 + || dst->mode_info.green_field_pos % 8 != 0 + || dst->mode_info.blue_field_pos % 8 != 0 + || dst->mode_info.reserved_field_pos % 8 != 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "dst format not supported"); + if (src->mode_info.red_field_pos % 8 != 0 + || src->mode_info.green_field_pos % 8 != 0 + || src->mode_info.blue_field_pos % 8 != 0 + || src->mode_info.reserved_field_pos % 8 != 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "src format not supported"); + if (dst->mode_info.red_field_pos != src->mode_info.red_field_pos + || dst->mode_info.red_mask_size != src->mode_info.red_mask_size + || dst->mode_info.green_field_pos != src->mode_info.green_field_pos + || dst->mode_info.green_mask_size != src->mode_info.green_mask_size + || dst->mode_info.blue_field_pos != src->mode_info.blue_field_pos + || dst->mode_info.blue_mask_size != src->mode_info.blue_mask_size + || dst->mode_info.reserved_field_pos != + src->mode_info.reserved_field_pos + || dst->mode_info.reserved_mask_size != + src->mode_info.reserved_mask_size) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "dst and src not compatible"); + if (dst->mode_info.bytes_per_pixel != src->mode_info.bytes_per_pixel) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "dst and src not compatible"); + if (dst->mode_info.width == 0 || dst->mode_info.height == 0 + || src->mode_info.width == 0 || src->mode_info.height == 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "bitmap has a zero dimension"); + + grub_uint8_t *ddata = dst->data; + grub_uint8_t *sdata = src->data; + int dw = dst->mode_info.width; + int dh = dst->mode_info.height; + int sw = src->mode_info.width; + int sh = src->mode_info.height; + int dstride = dst->mode_info.pitch; + int sstride = src->mode_info.pitch; + /* bytes_per_pixel is the same for both src and dst. */ + int bytes_per_pixel = dst->mode_info.bytes_per_pixel; + + int dy; + for (dy = 0; dy < dh; dy++) + { + int dx; + for (dx = 0; dx < dw; dx++) + { + grub_uint8_t *dptr; + grub_uint8_t *sptr; + int sx; + int sy; + int comp; + + /* Compute the source coordinate that the destination coordinate + maps to. Note: sx/sw = dx/dw => sx = sw*dx/dw. */ + sx = sw * dx / dw; + sy = sh * dy / dh; + + /* Get the address of the pixels in src and dst. */ + dptr = ddata + dy * dstride + dx * bytes_per_pixel; + sptr = sdata + sy * sstride + sx * bytes_per_pixel; + + /* If we have enough space to do so, use bilinear interpolation. + Otherwise, fall back to nearest neighbor for this pixel. */ + if (sx < sw - 1 && sy < sh - 1) + { + /* Do bilinear interpolation. */ + + /* Fixed-point .8 numbers representing the fraction of the + distance in the x (u) and y (v) direction within the + box of 4 pixels in the source. */ + int u = (256 * sw * dx / dw) - (sx * 256); + int v = (256 * sh * dy / dh) - (sy * 256); + + for (comp = 0; comp < bytes_per_pixel; comp++) + { + /* Get the component's values for the + four source corner pixels. */ + grub_uint8_t f00 = sptr[comp]; + grub_uint8_t f10 = sptr[comp + bytes_per_pixel]; + grub_uint8_t f01 = sptr[comp + sstride]; + grub_uint8_t f11 = sptr[comp + sstride + bytes_per_pixel]; + + /* Do linear interpolations along the top and bottom + rows of the box. */ + grub_uint8_t f0y = (256 - v) * f00 / 256 + v * f01 / 256; + grub_uint8_t f1y = (256 - v) * f10 / 256 + v * f11 / 256; + + /* Interpolate vertically. */ + grub_uint8_t fxy = (256 - u) * f0y / 256 + u * f1y / 256; + + dptr[comp] = fxy; + } + } + else + { + /* Fall back to nearest neighbor interpolation. */ + /* Copy the pixel color value. */ + for (comp = 0; comp < bytes_per_pixel; comp++) + dptr[comp] = sptr[comp]; + } + } + } + return GRUB_ERR_NONE; +} From 1488fac7ef235d579972822b1cbc6e2e2932fc8b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 20 Nov 2009 13:53:36 +0100 Subject: [PATCH 084/738] Fixed missing make directives --- conf/i386-pc.rmk | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk index 382c45ca3..4c2aec617 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -155,7 +155,7 @@ grub_emu_SOURCES = commands/minicmd.c commands/cat.c commands/cmp.c \ \ video/video.c video/fb/video_fb.c video/fb/fbblit.c \ video/fb/fbfill.c video/fb/fbutil.c commands/videotest.c \ - video/bitmap.c video/readers/tga.c video/readers/jpeg.c \ + video/bitmap.c video/bitmap_scale.c video/readers/tga.c video/readers/jpeg.c \ video/readers/png.c font/font_cmd.c font/font.c term/gfxterm.c \ io/bufio.c \ \ @@ -175,6 +175,11 @@ grub_emu_SOURCES += disk/usbms.c util/usb.c bus/usb/usb.c \ grub_emu_LDFLAGS += $(LIBCURSES) $(LIBUSB) endif +ifeq ($(enable_grub_emu_sdl), yes) +grub_emu_SOURCES += util/sdl.c +grub_emu_LDFLAGS += $(LIBSDL) +endif + sbin_SCRIPTS += grub-install grub_install_SOURCES = util/grub-install.in From 71bc82683468a4c3bfd63aedbf0155bd5957eea2 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 20 Nov 2009 13:55:43 +0100 Subject: [PATCH 085/738] Fixed syntax error --- loader/xnu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/loader/xnu.c b/loader/xnu.c index e0ae9cefe..ab88317d2 100644 --- a/loader/xnu.c +++ b/loader/xnu.c @@ -1336,7 +1336,7 @@ grub_xnu_unlock () locked = 0; } -static grub_command_t cmd_kernel, cmd_mkext, cmd_kext, ; +static grub_command_t cmd_kernel, cmd_mkext, cmd_kext; static grub_command_t cmd_devtree; static grub_command_t cmd_kextdir, cmd_ramdisk, cmd_resume; static grub_extcmd_t cmd_splash; From a8287184e360c8f198fc3174f99e8032df44881a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 20 Nov 2009 14:19:20 +0100 Subject: [PATCH 086/738] renamed ChangeLog --- ChangeLog.video => ChangeLog.doublebuf | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename ChangeLog.video => ChangeLog.doublebuf (100%) diff --git a/ChangeLog.video b/ChangeLog.doublebuf similarity index 100% rename from ChangeLog.video rename to ChangeLog.doublebuf From b49991d823c428b4daf69c877d15fcc31e99c950 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 20 Nov 2009 14:27:52 +0100 Subject: [PATCH 087/738] ChangeLog --- ChangeLog.sdl | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 ChangeLog.sdl diff --git a/ChangeLog.sdl b/ChangeLog.sdl new file mode 100644 index 000000000..8bf8c082a --- /dev/null +++ b/ChangeLog.sdl @@ -0,0 +1,11 @@ +2009-11-20 Vladimir Serbinenko + + SDL support. + + * Makefile.in (LIBSDL): New variable. + (enable_grub_emu_sdl): Likewise. + * conf/i386-pc.rmk (grub_emu_SOURCES): Add video files. + (grub_emu_SOURCES) [enable_grub_emu_sdl]: Add util/sdl.c. + (grub_emu_LDFLAGS) [enable_grub_emu_sdl]: Add $(LIBSDL). + * configure.ac: Detect SDL availability and add --enable-grub-emu-sdl + * util/sdl.c: New file. From b4dae692eb6afc9aed7bd7d6ee47824086def7e4 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 20 Nov 2009 14:30:58 +0100 Subject: [PATCH 088/738] Fixed variable declarations --- term/gfxterm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/term/gfxterm.c b/term/gfxterm.c index 3fc151c8b..5330c4ac4 100644 --- a/term/gfxterm.c +++ b/term/gfxterm.c @@ -323,6 +323,7 @@ grub_gfxterm_init (void) struct grub_video_mode_info mode_info; char *tmp; grub_err_t err; + grub_video_color_t color; /* If gfxterm has already been initialized by calling the init_window function, then leave it alone when it is set as the current terminal. */ @@ -702,7 +703,6 @@ scroll_up (void) else { grub_video_rect_t saved_view; - int i; grub_video_set_active_render_target (render_target); /* Save viewport and set it to our window. */ From ac3b7128d6d7e89fd103d6ad4054ce3db56195d6 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 20 Nov 2009 14:45:33 +0100 Subject: [PATCH 089/738] 2009-11-20 Colin D Bennett * normal/menu_text.c (get_entry_number): Move from here ... * normal/menu.c (get_entry_number): ... moved here. * include/grub/menu.h (grub_menu_get_default_entry_index): New prototype. * normal/menu.c (grub_menu_get_default_entry_index): New function. * normal/menu_text.c (run_menu): Use grub_menu_get_default_entry_index. --- ChangeLog.menu | 9 ++++++++ include/grub/menu.h | 1 + normal/menu.c | 54 +++++++++++++++++++++++++++++++++++++++++++++ normal/menu_text.c | 50 +---------------------------------------- 4 files changed, 65 insertions(+), 49 deletions(-) create mode 100644 ChangeLog.menu diff --git a/ChangeLog.menu b/ChangeLog.menu new file mode 100644 index 000000000..cb048bc9f --- /dev/null +++ b/ChangeLog.menu @@ -0,0 +1,9 @@ +2009-11-20 Colin D Bennett + + * normal/menu_text.c (get_entry_number): Move from here ... + * normal/menu.c (get_entry_number): ... moved here. + * include/grub/menu.h (grub_menu_get_default_entry_index): + New prototype. + * normal/menu.c (grub_menu_get_default_entry_index): New function. + * normal/menu_text.c (run_menu): Use grub_menu_get_default_entry_index. + diff --git a/include/grub/menu.h b/include/grub/menu.h index c7114a93b..cfe7e7cec 100644 --- a/include/grub/menu.h +++ b/include/grub/menu.h @@ -93,5 +93,6 @@ void grub_menu_execute_with_fallback (grub_menu_t menu, grub_menu_execute_callback_t callback, void *callback_data); void grub_menu_entry_run (grub_menu_entry_t entry); +int grub_menu_get_default_entry_index (grub_menu_t menu); #endif /* GRUB_MENU_HEADER */ diff --git a/normal/menu.c b/normal/menu.c index b9f74b7d7..282dddae5 100644 --- a/normal/menu.c +++ b/normal/menu.c @@ -180,3 +180,57 @@ grub_menu_execute_with_fallback (grub_menu_t menu, callback->notify_failure (callback_data); } + +/* Get the entry number from the variable NAME. */ +static int +get_entry_number (grub_menu_t menu, const char *name) +{ + char *val; + int entry; + + val = grub_env_get (name); + if (! val) + return -1; + + grub_error_push (); + + entry = (int) grub_strtoul (val, 0, 0); + + if (grub_errno == GRUB_ERR_BAD_NUMBER) + { + /* See if the variable matches the title of a menu entry. */ + grub_menu_entry_t e = menu->entry_list; + int i; + + grub_errno = GRUB_ERR_NONE; + + for (i = 0; e; i++) + { + if (grub_strcmp (e->title, val) == 0) + { + entry = i; + break; + } + e = e->next; + } + + if (! e) + entry = -1; + } + + if (grub_errno != GRUB_ERR_NONE) + { + grub_errno = GRUB_ERR_NONE; + entry = -1; + } + + grub_error_pop (); + + return entry; +} + +int +grub_menu_get_default_entry_index (grub_menu_t menu) +{ + return get_entry_number (menu, "default"); +} diff --git a/normal/menu_text.c b/normal/menu_text.c index 19f9cf756..d02230a8f 100644 --- a/normal/menu_text.c +++ b/normal/menu_text.c @@ -235,54 +235,6 @@ grub_menu_init_page (int nested, int edit) print_message (nested, edit); } -/* Get the entry number from the variable NAME. */ -static int -get_entry_number (grub_menu_t menu, const char *name) -{ - char *val; - int entry; - - val = grub_env_get (name); - if (! val) - return -1; - - grub_error_push (); - - entry = (int) grub_strtoul (val, 0, 0); - - if (grub_errno == GRUB_ERR_BAD_NUMBER) - { - /* See if the variable matches the title of a menu entry. */ - grub_menu_entry_t e = menu->entry_list; - int i; - - grub_errno = GRUB_ERR_NONE; - - for (i = 0; e; i++) - { - if (grub_strcmp (e->title, val) == 0) - { - entry = i; - break; - } - e = e->next; - } - - if (! e) - entry = -1; - } - - if (grub_errno != GRUB_ERR_NONE) - { - grub_errno = GRUB_ERR_NONE; - entry = -1; - } - - grub_error_pop (); - - return entry; -} - static void print_timeout (int timeout, int offset, int second_stage) { @@ -313,7 +265,7 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot) first = 0; - default_entry = get_entry_number (menu, "default"); + default_entry = grub_menu_get_default_entry_index (menu); /* If DEFAULT_ENTRY is not within the menu entries, fall back to the first entry. */ From cbf97a87d9d63c46e8057f163238cec42fa4ec43 Mon Sep 17 00:00:00 2001 From: Colin D Bennett Date: Fri, 20 Nov 2009 14:51:01 +0100 Subject: [PATCH 090/738] * include/grub/menu_viewer.h (grub_menu_viewer_init): New prototype. (grub_menu_viewer_should_return): Likewise. * normal/main.c (GRUB_MOD_INIT (normal)): Call grub_menu_viewer_init. * normal/menu_text.c (run_menu): Enable menu switching. * normal/menu_viewer.c (should_return): New variable. (menu_viewer_changed): Likewise. (grub_menu_viewer_show_menu): Handle menu viewer changes. (grub_menu_viewer_should_return): New function. (menuviewer_write_hook): Likewise. (grub_menu_viewer_init): Likewise. --- ChangeLog.menu | 10 ++++++++++ include/grub/menu_viewer.h | 5 +++++ normal/main.c | 2 ++ normal/menu_text.c | 9 +++++++-- normal/menu_viewer.c | 37 ++++++++++++++++++++++++++++++++++--- 5 files changed, 58 insertions(+), 5 deletions(-) diff --git a/ChangeLog.menu b/ChangeLog.menu index cb048bc9f..32c0a85d5 100644 --- a/ChangeLog.menu +++ b/ChangeLog.menu @@ -6,4 +6,14 @@ New prototype. * normal/menu.c (grub_menu_get_default_entry_index): New function. * normal/menu_text.c (run_menu): Use grub_menu_get_default_entry_index. + * include/grub/menu_viewer.h (grub_menu_viewer_init): New prototype. + (grub_menu_viewer_should_return): Likewise. + * normal/main.c (GRUB_MOD_INIT (normal)): Call grub_menu_viewer_init. + * normal/menu_text.c (run_menu): Enable menu switching. + * normal/menu_viewer.c (should_return): New variable. + (menu_viewer_changed): Likewise. + (grub_menu_viewer_show_menu): Handle menu viewer changes. + (grub_menu_viewer_should_return): New function. + (menuviewer_write_hook): Likewise. + (grub_menu_viewer_init): Likewise. diff --git a/include/grub/menu_viewer.h b/include/grub/menu_viewer.h index 725c97548..211f6e3e9 100644 --- a/include/grub/menu_viewer.h +++ b/include/grub/menu_viewer.h @@ -36,8 +36,13 @@ struct grub_menu_viewer }; typedef struct grub_menu_viewer *grub_menu_viewer_t; +void grub_menu_viewer_init (void); + void grub_menu_viewer_register (grub_menu_viewer_t viewer); grub_err_t grub_menu_viewer_show_menu (grub_menu_t menu, int nested); +/* Return nonzero iff the menu viewer should clean up and return ASAP. */ +int grub_menu_viewer_should_return (void); + #endif /* GRUB_MENU_VIEWER_HEADER */ diff --git a/normal/main.c b/normal/main.c index 748eef805..736c20e47 100644 --- a/normal/main.c +++ b/normal/main.c @@ -584,6 +584,8 @@ GRUB_MOD_INIT(normal) /* Preserve hooks after context changes. */ grub_env_export ("color_normal"); grub_env_export ("color_highlight"); + + grub_menu_viewer_init (); } GRUB_MOD_FINI(normal) diff --git a/normal/menu_text.c b/normal/menu_text.c index d02230a8f..68c7afeee 100644 --- a/normal/menu_text.c +++ b/normal/menu_text.c @@ -300,7 +300,7 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot) if (timeout > 0) print_timeout (timeout, offset, 0); - while (1) + while (! grub_menu_viewer_should_return ()) { int c; timeout = grub_menu_get_timeout (); @@ -473,6 +473,10 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot) } goto refresh; + case 't': + grub_env_set ("menuviewer", "gfxmenu"); + goto refresh; + default: break; } @@ -481,7 +485,8 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot) } } - /* Never reach here. */ + /* Exit menu without activating an item. This occurs if the user presses + * 't', switching to the graphical menu viewer. */ return -1; } diff --git a/normal/menu_viewer.c b/normal/menu_viewer.c index 1bd271a21..7a547a764 100644 --- a/normal/menu_viewer.c +++ b/normal/menu_viewer.c @@ -26,6 +26,9 @@ /* The list of menu viewers. */ static grub_menu_viewer_t menu_viewer_list; +static int should_return; +static int menu_viewer_changed; + void grub_menu_viewer_register (grub_menu_viewer_t viewer) { @@ -55,16 +58,23 @@ static grub_menu_viewer_t get_current_menu_viewer (void) grub_err_t grub_menu_viewer_show_menu (grub_menu_t menu, int nested) { - grub_menu_viewer_t cur = get_current_menu_viewer (); grub_err_t err1, err2; - if (!cur) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "No menu viewer available."); while (1) { + grub_menu_viewer_t cur = get_current_menu_viewer (); + if (!cur) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "No menu viewer available."); + + menu_viewer_changed = 0; + should_return = 0; + err1 = cur->show_menu (menu, nested); grub_print_error (); + if (menu_viewer_changed) + continue; + err2 = grub_auth_check_authentication (NULL); if (err2) { @@ -79,3 +89,24 @@ grub_menu_viewer_show_menu (grub_menu_t menu, int nested) return err1; } +int +grub_menu_viewer_should_return (void) +{ + return should_return; +} + +static char * +menuviewer_write_hook (struct grub_env_var *var __attribute__ ((unused)), + const char *val) +{ + menu_viewer_changed = 1; + should_return = 1; + return grub_strdup (val); +} + +void +grub_menu_viewer_init (void) +{ + grub_register_variable_hook ("menuviewer", 0, menuviewer_write_hook); +} + From bd86691a07c81cab2ba6f364cdfdedb34914ef37 Mon Sep 17 00:00:00 2001 From: Colin D Bennett Date: Fri, 20 Nov 2009 15:09:48 +0100 Subject: [PATCH 091/738] 2009-11-20 Colin D Bennett * include/grub/misc.h (grub_iscntrl): New inline function. (grub_isalnum): Likewise. (grub_strtol): Likewise. --- ChangeLog.gfxmenumisc | 6 ++++++ include/grub/misc.h | 49 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 ChangeLog.gfxmenumisc diff --git a/ChangeLog.gfxmenumisc b/ChangeLog.gfxmenumisc new file mode 100644 index 000000000..ace9862ba --- /dev/null +++ b/ChangeLog.gfxmenumisc @@ -0,0 +1,6 @@ +2009-11-20 Colin D Bennett + + * include/grub/misc.h (grub_iscntrl): New inline function. + (grub_isalnum): Likewise. + (grub_strtol): Likewise. + diff --git a/include/grub/misc.h b/include/grub/misc.h index faa2d5c42..b843b9202 100644 --- a/include/grub/misc.h +++ b/include/grub/misc.h @@ -94,6 +94,12 @@ char *EXPORT_FUNC(grub_strstr) (const char *haystack, const char *needle); int EXPORT_FUNC(grub_isspace) (int c); int EXPORT_FUNC(grub_isprint) (int c); +static inline int +grub_iscntrl (int c) +{ + return (c >= 0x00 && c <= 0x1F) || c == 0x7F; +} + static inline int grub_isalpha (int c) { @@ -112,6 +118,12 @@ grub_isdigit (int c) return (c >= '0' && c <= '9'); } +static inline int +grub_isalnum (int c) +{ + return grub_isalpha (c) || grub_isdigit (c); +} + static inline int grub_tolower (int c) { @@ -166,6 +178,43 @@ grub_strncasecmp (const char *s1, const char *s2, grub_size_t n) unsigned long EXPORT_FUNC(grub_strtoul) (const char *str, char **end, int base); unsigned long long EXPORT_FUNC(grub_strtoull) (const char *str, char **end, int base); + +static inline long +grub_strtol (const char *str, char **end, int base) +{ + int negative = 0; + unsigned long magnitude; + + while (*str && grub_isspace (*str)) + str++; + + if (*str == '-') + { + negative = 1; + str++; + } + + magnitude = grub_strtoull (str, end, base); + if (negative) + { + if (magnitude > (unsigned long) GRUB_LONG_MAX + 1) + { + grub_error (GRUB_ERR_OUT_OF_RANGE, "negative overflow"); + return GRUB_LONG_MIN; + } + return -((long) magnitude); + } + else + { + if (magnitude > GRUB_LONG_MAX) + { + grub_error (GRUB_ERR_OUT_OF_RANGE, "positive overflow"); + return GRUB_LONG_MAX; + } + return (long) magnitude; + } +} + char *EXPORT_FUNC(grub_strdup) (const char *s); char *EXPORT_FUNC(grub_strndup) (const char *s, grub_size_t n); void *EXPORT_FUNC(grub_memset) (void *s, int c, grub_size_t n); From 1f1551457faf627f0c310f514c597da93138f0c1 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 20 Nov 2009 16:00:13 +0100 Subject: [PATCH 092/738] ChangeLog --- ChangeLog.trig | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 ChangeLog.trig diff --git a/ChangeLog.trig b/ChangeLog.trig new file mode 100644 index 000000000..c3cd73594 --- /dev/null +++ b/ChangeLog.trig @@ -0,0 +1,11 @@ +2009-11-14 Colin D Bennet + + Trigonometry support. + + * include/grub/trig.h: New file. + * lib/trig.c: Likewise. + * maintainance/gentrigtables.py: Likewise. + * conf/common.rmk (pkglib_MODULES): Add trig.mod. + (trig_mod_SOURCES): New variable. + (trig_mod_CFLAGS): Likewise. + (trig_mod_LDFLAGS): Likewise. From d920a32ab688df7cce1667434cc6785ebc840386 Mon Sep 17 00:00:00 2001 From: Colin D Bennett Date: Fri, 20 Nov 2009 16:02:58 +0100 Subject: [PATCH 093/738] gfxmenu import --- conf/common.rmk | 22 + docs/gfxmenu-theme-example.txt | 128 ++++++ gfxmenu/gfxmenu.c | 235 +++++++++++ gfxmenu/gui_box.c | 372 +++++++++++++++++ gfxmenu/gui_canvas.c | 268 ++++++++++++ gfxmenu/gui_circular_progress.c | 339 +++++++++++++++ gfxmenu/gui_image.c | 270 ++++++++++++ gfxmenu/gui_label.c | 248 +++++++++++ gfxmenu/gui_list.c | 625 +++++++++++++++++++++++++++ gfxmenu/gui_progress_bar.c | 378 +++++++++++++++++ gfxmenu/gui_string_util.c | 358 ++++++++++++++++ gfxmenu/gui_util.c | 101 +++++ gfxmenu/icon_manager.c | 258 ++++++++++++ gfxmenu/model.c | 191 +++++++++ gfxmenu/named_colors.c | 209 +++++++++ gfxmenu/theme_loader.c | 720 ++++++++++++++++++++++++++++++++ gfxmenu/view.c | 497 ++++++++++++++++++++++ gfxmenu/widget-box.c | 313 ++++++++++++++ include/grub/gfxmenu_model.h | 59 +++ include/grub/gfxmenu_view.h | 91 ++++ include/grub/gfxwidgets.h | 49 +++ include/grub/gui.h | 165 ++++++++ include/grub/gui_string_util.h | 39 ++ include/grub/icon_manager.h | 41 ++ include/grub/term.h | 2 +- 25 files changed, 5977 insertions(+), 1 deletion(-) create mode 100644 docs/gfxmenu-theme-example.txt create mode 100644 gfxmenu/gfxmenu.c create mode 100644 gfxmenu/gui_box.c create mode 100644 gfxmenu/gui_canvas.c create mode 100644 gfxmenu/gui_circular_progress.c create mode 100644 gfxmenu/gui_image.c create mode 100644 gfxmenu/gui_label.c create mode 100644 gfxmenu/gui_list.c create mode 100644 gfxmenu/gui_progress_bar.c create mode 100644 gfxmenu/gui_string_util.c create mode 100644 gfxmenu/gui_util.c create mode 100644 gfxmenu/icon_manager.c create mode 100644 gfxmenu/model.c create mode 100644 gfxmenu/named_colors.c create mode 100644 gfxmenu/theme_loader.c create mode 100644 gfxmenu/view.c create mode 100644 gfxmenu/widget-box.c create mode 100644 include/grub/gfxmenu_model.h create mode 100644 include/grub/gfxmenu_view.h create mode 100644 include/grub/gfxwidgets.h create mode 100644 include/grub/gui.h create mode 100644 include/grub/gui_string_util.h create mode 100644 include/grub/icon_manager.h diff --git a/conf/common.rmk b/conf/common.rmk index 3dddeb66d..4c1b845df 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -417,6 +417,28 @@ hello_mod_SOURCES = hello/hello.c hello_mod_CFLAGS = $(COMMON_CFLAGS) hello_mod_LDFLAGS = $(COMMON_LDFLAGS) +# For gfxmenu.mod. +pkglib_MODULES += gfxmenu.mod +gfxmenu_mod_SOURCES = \ + gfxmenu/gfxmenu.c \ + gfxmenu/model.c \ + gfxmenu/view.c \ + gfxmenu/icon_manager.c \ + gfxmenu/theme_loader.c \ + gfxmenu/widget-box.c \ + gfxmenu/gui_canvas.c \ + gfxmenu/gui_circular_progress.c \ + gfxmenu/gui_box.c \ + gfxmenu/gui_label.c \ + gfxmenu/gui_list.c \ + gfxmenu/gui_image.c \ + gfxmenu/gui_progress_bar.c \ + gfxmenu/gui_util.c \ + gfxmenu/gui_string_util.c \ + gfxmenu/named_colors.c +gfxmenu_mod_CFLAGS = $(COMMON_CFLAGS) +gfxmenu_mod_LDFLAGS = $(COMMON_LDFLAGS) + # For parttool.mod. parttool_mod_SOURCES = commands/parttool.c parttool_mod_CFLAGS = $(COMMON_CFLAGS) diff --git a/docs/gfxmenu-theme-example.txt b/docs/gfxmenu-theme-example.txt new file mode 100644 index 000000000..4363dc8df --- /dev/null +++ b/docs/gfxmenu-theme-example.txt @@ -0,0 +1,128 @@ +# GRUB gfxmenu theme "winter". +# Uses background image from: +# http://www.cyberpunkcafe.com/e107_plugins/autogallery/autogallery.php?show=1.Open%20Source%20Wallpaper +# "without-leaves.png" was called "Without Leafs in Winter.png" + +lua-script: "winter.lua" +title-text: "" +title-font: "Helvetica Bold 18" +status-font: "Helvetica 8" +terminal-font: "Fixed 9" +title-color: "40, 40, 40" +status-color: "#FFF" +status-bg-color: "0, 166, 183, 128" +desktop-image: "without-leaves.png" +desktop-color: "0, 154, 183" +terminal-box: "terminal_*.png" + ++ boot_menu { + position = (120, 60) + preferred_size = (400, -1) + item_font = "Helvetica Bold 14" + selected_item_font = "Helvetica Bold 14" + item_color = "0, 0, 0" + selected_item_color = "203, 251, 255" + menu_pixmap_style = "menu_*.png" + selected_item_pixmap_style = "select_*.png" + icon_width = 44 + icon_height = 44 + item_height = 32 + item_padding = 0 + item_icon_space = 3 + item_spacing = 11 +} + +# You can add text at arbitrary locations on the screen. +# The specification within the "+label {...}" block is free-form, +# so you can use as much or as little white space as you like. + ++ label { + position = (170, 50) + font = "smoothansi 13" + color = "0,0,128" + text = "This is the Winter theme ... brought to you by GRUB!" +} + +# Show the text alignment supported by labels. ++ vbox { + position = (220, 347) + preferred_size = (200, -1) # A preferred size of -1 means automatic. + + label { text="Text alignment demo" align="center" font="aqui 11" } + + label { text="Left" align="left" font="cure 11" } + + label { text="Center" align="center" font="cure 11" } + + label { text="Right" align="right" font="cure 11" } +} + ++ vbox { + position = (580, 10) + + label { text="GNU" font="gelly 11" color="0, 0, 0" } + + label { text="GRUB" font="aqui 11" color="0, 0, 0" } + + label { text="boot loader" font="cure 11" color="0, 0, 0" } +} + ++ hbox { + position = (80, 10) + + label { text="GNU" font="gelly 11" color="0, 0, 0" } + + label { text="GRUB" font="aqui 11" color="0, 0, 0" } + + label { text="boot loader" font="cure 11" color="0, 0, 0" } +} + +# Demonstration of a compound layout: boxes within boxes. ++ hbox +{ + position = (480, 3) + + + vbox + { + # Note: We can't just use 'size' to set the image's size, + # since the vbox will resize the component according to its + # preferred size, which for images is the native image size. + + + image { file="/boot/grub/themes/icons/ubuntu.png" + preferred_size = (20, 20) } + + image { file="/boot/grub/themes/icons/gentoo.png" + preferred_size = (20, 20) } + } + + + vbox + { + + label { text="GRand" font="cure 11" color=#99F } + + label { text="Unified" font="cure 11" color=#BBF } + + label { text="Bootloader" font="cure 11" color=#DDF } + } +} + +# By defining a 'progress_bar' type component with an ID of '__timeout__', +# the progress bar will be used to display the time remaining before an +# the default entry is automatically booted. ++ progress_bar +{ + id = "__timeout__" + position = (80, 393) + preferred_size = (500, 24) + font = "cure 11" + text_color = #000 + fg_color = #CCF + bg_color = #66B + border_color = #006 + show_text = false +} + +# Although the progress_bar component is normally used to indicate the +# time remaining, it's also possible to create other components with an ID +# of '__timeout__'. All components with and ID of 'timeout_bar' will have +# the following properties set based on the timeout value: +# text, value, start, end, visible. +# In this case, we have set 'show_text=false' on the progress bar, and use +# the following label's 'text' property to display the message. ++ label +{ + id = "__timeout__" + position = (80, 420) + preferred_size = (500, 24) + font = "lime 11" + color = #117 + align = "center" +} + + diff --git a/gfxmenu/gfxmenu.c b/gfxmenu/gfxmenu.c new file mode 100644 index 000000000..85ce5879d --- /dev/null +++ b/gfxmenu/gfxmenu.c @@ -0,0 +1,235 @@ +/* gfxmenu.c - Graphical menu interface controller. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void switch_to_text_menu (void) +{ + grub_env_set ("menuviewer", "text"); +} + +static void +process_key_press (int c, + grub_gfxmenu_model_t model, + grub_gfxmenu_view_t view, + int nested, + int *should_exit) +{ + /* When a key is pressed, stop the timeout. */ + grub_gfxmenu_model_clear_timeout (model); + + if (c == 'j' || c == GRUB_TERM_DOWN) + { + int i = grub_gfxmenu_model_get_selected_index (model); + int num_items = grub_gfxmenu_model_get_num_entries (model); + if (i < num_items - 1) + { + i++; + grub_gfxmenu_model_set_selected_index (model, i); + } + } + else if (c == 'k' || c == GRUB_TERM_UP) + { + int i = grub_gfxmenu_model_get_selected_index (model); + if (i > 0) + { + i--; + grub_gfxmenu_model_set_selected_index (model, i); + } + } + else if (c == '\r' || c == '\n' || c == GRUB_TERM_RIGHT) + { + int selected = grub_gfxmenu_model_get_selected_index (model); + int num_entries = grub_gfxmenu_model_get_num_entries (model); + if (selected >= 0 && selected < num_entries) + { + grub_menu_entry_t entry = + grub_gfxmenu_model_get_entry (model, selected); + grub_gfxmenu_view_execute_entry (view, entry); + } + } + else if (c == 'c') + { + grub_gfxmenu_view_run_terminal (view); + } + else if (c == 't') + { + /* The write hook for 'menuviewer' will cause + * grub_menu_viewer_should_return to return nonzero. */ + switch_to_text_menu (); + *should_exit = 1; + } + else if (c == '1') + { + grub_gfxmenu_view_load_theme (view, + "/boot/grub/themes/proto/theme.txt"); + } + else if (c == '2') + { + grub_gfxmenu_view_load_theme (view, + "/boot/grub/themes/winter/theme.txt"); + } + else if (c == '3') + { + grub_gfxmenu_view_load_theme (view, + "/boot/grub/themes/ubuntu1/theme.txt"); + } + else if (c == '4') + { + grub_gfxmenu_view_load_theme (view, + "/boot/grub/themes/ubuntu2/theme.txt"); + } + else if (nested && c == GRUB_TERM_ESC) + { + *should_exit = 1; + } + + if (grub_errno != GRUB_ERR_NONE) + *should_exit = 1; +} + +static void +handle_key_events (grub_gfxmenu_model_t model, + grub_gfxmenu_view_t view, + int nested, + int *should_exit) +{ + while ((! *should_exit) && (grub_checkkey () != -1)) + { + int key = grub_getkey (); + int c = GRUB_TERM_ASCII_CHAR (key); + process_key_press (c, model, view, nested, should_exit); + } +} + +static grub_err_t +show_menu (grub_menu_t menu, int nested) +{ + grub_gfxmenu_model_t model; + + model = grub_gfxmenu_model_new (menu); + if (! model) + { + grub_print_error (); + grub_printf ("Initializing menu data for graphical menu failed;\n" + "falling back to text based menu.\n"); + grub_wait_after_message (); + switch_to_text_menu (); + return grub_errno; + } + + grub_gfxmenu_view_t view; + + /* Create the view. */ + const char *theme_path = grub_env_get ("theme"); + if (! theme_path) + theme_path = "/boot/grub/themes/proto/theme.txt"; + + view = grub_gfxmenu_view_new (theme_path, model); + if (! view) + { + grub_print_error (); + grub_printf ("Starting graphical menu failed;\n" + "falling back to text based menu.\n"); + grub_wait_after_message (); + grub_gfxmenu_model_destroy (model); + switch_to_text_menu (); + return grub_errno; + } + + /* Initially select the default menu entry. */ + int default_index = grub_menu_get_default_entry_index (menu); + grub_gfxmenu_model_set_selected_index (model, default_index); + + /* Start the timer to execute the default entry. */ + grub_gfxmenu_model_set_timeout (model); + + /* Main event loop. */ + int exit_requested = 0; + while ((! exit_requested) && (! grub_menu_viewer_should_return ())) + { + if (grub_gfxmenu_model_timeout_expired (model)) + { + grub_gfxmenu_model_clear_timeout (model); + int i = grub_gfxmenu_model_get_selected_index (model); + grub_menu_entry_t e = grub_gfxmenu_model_get_entry (model, i); + grub_gfxmenu_view_execute_with_fallback (view, e); + continue; + } + + grub_gfxmenu_view_draw (view); + grub_video_swap_buffers (); + handle_key_events (model, view, nested, &exit_requested); + } + + grub_gfxmenu_view_destroy (view); + grub_gfxmenu_model_destroy (model); + + return grub_errno; +} + +static grub_err_t +grub_cmd_gfxmenu (grub_command_t cmd UNUSED, + int argc UNUSED, char **args UNUSED) +{ + grub_menu_t menu = grub_env_get_data_slot ("menu"); + if (! menu) + return grub_error (GRUB_ERR_MENU, "no menu context"); + + return show_menu (menu, 1); +} + +static struct grub_menu_viewer menu_viewer = +{ + .name = "gfxmenu", + .show_menu = show_menu +}; + +static grub_command_t cmd; + +GRUB_MOD_INIT (gfxmenu) +{ + (void) mod; /* To stop warning. */ + grub_menu_viewer_register (&menu_viewer); + cmd = grub_register_command ("gfxmenu", grub_cmd_gfxmenu, + "gfxmenu", + "Show graphical menu interface"); +} + +GRUB_MOD_FINI (gfxmenu) +{ + grub_unregister_command (cmd); +} diff --git a/gfxmenu/gui_box.c b/gfxmenu/gui_box.c new file mode 100644 index 000000000..876d0733f --- /dev/null +++ b/gfxmenu/gui_box.c @@ -0,0 +1,372 @@ +/* gui_box.c - GUI container that stack components. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include + +struct component_node +{ + grub_gui_component_t component; + struct component_node *next; + struct component_node *prev; +}; + +typedef struct grub_gui_box *grub_gui_box_t; + +typedef void (*layout_func_t) (grub_gui_box_t self, int modify_layout, + int *width, int *height); + +struct grub_gui_box +{ + struct grub_gui_container_ops *container; + + grub_gui_container_t parent; + grub_video_rect_t bounds; + char *id; + int preferred_width; + int preferred_height; + + /* Doubly linked list of components with dummy head & tail nodes. */ + struct component_node chead; + struct component_node ctail; + + /* The layout function: differs for vertical and horizontal boxes. */ + layout_func_t layout_func; +}; + +static void +box_destroy (void *vself) +{ + grub_gui_box_t self = vself; + struct component_node *cur; + struct component_node *next; + for (cur = self->chead.next; cur != &self->ctail; cur = next) + { + /* Copy the 'next' pointer, since we need it for the next iteration, + and we're going to free the memory it is stored in. */ + next = cur->next; + /* Destroy the child component. */ + cur->component->ops->destroy (cur->component); + /* Free the linked list node. */ + grub_free (cur); + } + grub_free (self); +} + +static const char * +box_get_id (void *vself) +{ + grub_gui_box_t self = vself; + return self->id; +} + +static int +box_is_instance (void *vself __attribute__((unused)), const char *type) +{ + return (grub_strcmp (type, "component") == 0 + || grub_strcmp (type, "container") == 0); +} + +static void +layout_horizontally (grub_gui_box_t self, int modify_layout, + int *width, int *height) +{ + /* Start at the left (chead) and set the x coordinates as we go right. */ + /* All components have their width set to the box's width. */ + + struct component_node *cur; + int x = 0; + if (height) + *height = 0; + for (cur = self->chead.next; cur != &self->ctail; cur = cur->next) + { + grub_gui_component_t c = cur->component; + grub_video_rect_t r; + + c->ops->get_preferred_size (c, &r.width, &r.height); + + /* Check and possibly update the maximum width, if non-null. */ + if (height && r.height > *height) + *height = r.height; + + /* Set the component's bounds, if the flag is set. */ + if (modify_layout) + { + r.x = x; + r.y = 0; + /* Width comes from the component's preferred size. */ + r.height = self->bounds.height; + c->ops->set_bounds (c, &r); + } + + x += r.width; + } + + /* Return the sum of the children's preferred widths. */ + if (width) + *width = x; +} + +static void +layout_vertically (grub_gui_box_t self, int modify_layout, + int *width, int *height) +{ + /* Start at the top (chead) and set the y coordinates as we go down. */ + /* All components have their width set to the vbox's width. */ + + struct component_node *cur; + int y = 0; + if (width) + *width = 0; + for (cur = self->chead.next; cur != &self->ctail; cur = cur->next) + { + grub_gui_component_t c = cur->component; + grub_video_rect_t r; + + c->ops->get_preferred_size (c, &r.width, &r.height); + + /* Check and possibly update the maximum width, if non-null. */ + if (width && r.width > *width) + *width = r.width; + + /* Set the component's bounds, if the flag is set. */ + if (modify_layout) + { + r.x = 0; + r.y = y; + r.width = self->bounds.width; + /* Height comes from the component's preferred size. */ + c->ops->set_bounds (c, &r); + } + + y += r.height; + } + + /* Return the sum of the children's preferred heights. */ + if (height) + *height = y; +} + +static void +box_paint (void *vself) +{ + grub_gui_box_t self = vself; + struct component_node *cur; + grub_video_rect_t vpsave; + + grub_gui_set_viewport (&self->bounds, &vpsave); + for (cur = self->chead.next; cur != &self->ctail; cur = cur->next) + { + grub_gui_component_t comp = cur->component; + comp->ops->paint (comp); + } + grub_gui_restore_viewport (&vpsave); +} + +static void +box_set_parent (void *vself, grub_gui_container_t parent) +{ + grub_gui_box_t self = vself; + self->parent = parent; +} + +static grub_gui_container_t +box_get_parent (void *vself) +{ + grub_gui_box_t self = vself; + return self->parent; +} + +static void +box_set_bounds (void *vself, const grub_video_rect_t *bounds) +{ + grub_gui_box_t self = vself; + self->bounds = *bounds; + self->layout_func (self, 1, 0, 0); /* Relayout the children. */ +} + +static void +box_get_bounds (void *vself, grub_video_rect_t *bounds) +{ + grub_gui_box_t self = vself; + *bounds = self->bounds; +} + +/* The box's preferred size is based on the preferred sizes + of its children. */ +static void +box_get_preferred_size (void *vself, int *width, int *height) +{ + grub_gui_box_t self = vself; + self->layout_func (self, 0, width, height); /* Just calculate the size. */ + + /* Allow preferred dimensions to override the computed dimensions. */ + if (self->preferred_width >= 0) + *width = self->preferred_width; + if (self->preferred_height >= 0) + *height = self->preferred_height; +} + +static grub_err_t +box_set_property (void *vself, const char *name, const char *value) +{ + grub_gui_box_t self = vself; + if (grub_strcmp (name, "id") == 0) + { + grub_free (self->id); + if (value) + { + self->id = grub_strdup (value); + if (! self->id) + return grub_errno; + } + else + self->id = 0; + } + else if (grub_strcmp (name, "preferred_size") == 0) + { + int w; + int h; + if (grub_gui_parse_2_tuple (value, &w, &h) != GRUB_ERR_NONE) + return grub_errno; + self->preferred_width = w; + self->preferred_height = h; + } + + return grub_errno; +} + +static void +box_add (void *vself, grub_gui_component_t comp) +{ + grub_gui_box_t self = vself; + struct component_node *node; + node = grub_malloc (sizeof (*node)); + if (! node) + return; /* Note: probably should handle the error. */ + node->component = comp; + /* Insert the node before the tail. */ + node->prev = self->ctail.prev; + node->prev->next = node; + node->next = &self->ctail; + node->next->prev = node; + + comp->ops->set_parent (comp, (grub_gui_container_t) self); + self->layout_func (self, 1, 0, 0); /* Relayout the children. */ +} + +static void +box_remove (void *vself, grub_gui_component_t comp) +{ + grub_gui_box_t self = vself; + struct component_node *cur; + for (cur = self->chead.next; cur != &self->ctail; cur = cur->next) + { + if (cur->component == comp) + { + /* Unlink 'cur' from the list. */ + cur->prev->next = cur->next; + cur->next->prev = cur->prev; + /* Free the node's memory (but don't destroy the component). */ + grub_free (cur); + /* Must not loop again, since 'cur' would be dereferenced! */ + return; + } + } +} + +static void +box_iterate_children (void *vself, + grub_gui_component_callback cb, void *userdata) +{ + grub_gui_box_t self = vself; + struct component_node *cur; + for (cur = self->chead.next; cur != &self->ctail; cur = cur->next) + cb (cur->component, userdata); +} + +static struct grub_gui_container_ops box_ops = +{ + .component = + { + .destroy = box_destroy, + .get_id = box_get_id, + .is_instance = box_is_instance, + .paint = box_paint, + .set_parent = box_set_parent, + .get_parent = box_get_parent, + .set_bounds = box_set_bounds, + .get_bounds = box_get_bounds, + .get_preferred_size = box_get_preferred_size, + .set_property = box_set_property + }, + .add = box_add, + .remove = box_remove, + .iterate_children = box_iterate_children +}; + +/* Box constructor. Specify the appropriate layout function to create + a horizontal or vertical stacking box. */ +static grub_gui_box_t +box_new (layout_func_t layout_func) +{ + grub_gui_box_t box; + box = grub_malloc (sizeof (*box)); + if (! box) + return 0; + box->container = &box_ops; + box->parent = 0; + box->bounds.x = 0; + box->bounds.y = 0; + box->bounds.width = 0; + box->bounds.height = 0; + box->id = 0; + box->preferred_width = -1; + box->preferred_height = -1; + box->chead.component = 0; + box->chead.prev = 0; + box->chead.next = &box->ctail; + box->ctail.component = 0; + box->ctail.prev = &box->chead; + box->ctail.next = 0; + box->layout_func = layout_func; + return box; +} + +/* Create a new container that stacks its child components horizontally, + from left to right. Each child get a width corresponding to its + preferred width. The height of each child is set the maximum of the + preferred heights of all children. */ +grub_gui_container_t +grub_gui_hbox_new (void) +{ + return (grub_gui_container_t) box_new (layout_horizontally); +} + +/* Create a new container that stacks its child components verticallyj, + from top to bottom. Each child get a height corresponding to its + preferred height. The width of each child is set the maximum of the + preferred widths of all children. */ +grub_gui_container_t +grub_gui_vbox_new (void) +{ + return (grub_gui_container_t) box_new (layout_vertically); +} diff --git a/gfxmenu/gui_canvas.c b/gfxmenu/gui_canvas.c new file mode 100644 index 000000000..a2cd77df6 --- /dev/null +++ b/gfxmenu/gui_canvas.c @@ -0,0 +1,268 @@ +/* gui_canvas.c - GUI container allowing manually placed components. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include + +/* TODO Add layering so that components can be properly overlaid. */ + +struct component_node +{ + grub_gui_component_t component; + struct component_node *next; +}; + +struct grub_gui_canvas +{ + struct grub_gui_container_ops *container; + + grub_gui_container_t parent; + grub_video_rect_t bounds; + char *id; + int preferred_width; + int preferred_height; + /* Component list (dummy head node). */ + struct component_node components; +}; + +typedef struct grub_gui_canvas *grub_gui_canvas_t; + +static void +canvas_destroy (void *vself) +{ + grub_gui_canvas_t self = vself; + struct component_node *cur; + struct component_node *next; + for (cur = self->components.next; cur; cur = next) + { + /* Copy the 'next' pointer, since we need it for the next iteration, + and we're going to free the memory it is stored in. */ + next = cur->next; + /* Destroy the child component. */ + cur->component->ops->destroy (cur->component); + /* Free the linked list node. */ + grub_free (cur); + } + grub_free (self); +} + +static const char * +canvas_get_id (void *vself) +{ + grub_gui_canvas_t self = vself; + return self->id; +} + +static int +canvas_is_instance (void *vself __attribute__((unused)), const char *type) +{ + return (grub_strcmp (type, "component") == 0 + || grub_strcmp (type, "container") == 0); +} + +static void +canvas_paint (void *vself) +{ + grub_gui_canvas_t self = vself; + struct component_node *cur; + grub_video_rect_t vpsave; + + grub_gui_set_viewport (&self->bounds, &vpsave); + for (cur = self->components.next; cur; cur = cur->next) + { + int pw; + int ph; + grub_video_rect_t r; + grub_gui_component_t comp; + + comp = cur->component; + + /* Give the child its preferred size. */ + comp->ops->get_preferred_size (comp, &pw, &ph); + comp->ops->get_bounds (comp, &r); + if (r.width != pw || r.height != ph) + { + r.width = pw; + r.height = ph; + comp->ops->set_bounds (comp, &r); + } + + /* Paint the child. */ + comp->ops->paint (comp); + } + grub_gui_restore_viewport (&vpsave); +} + +static void +canvas_set_parent (void *vself, grub_gui_container_t parent) +{ + grub_gui_canvas_t self = vself; + self->parent = parent; +} + +static grub_gui_container_t +canvas_get_parent (void *vself) +{ + grub_gui_canvas_t self = vself; + return self->parent; +} + +static void +canvas_set_bounds (void *vself, const grub_video_rect_t *bounds) +{ + grub_gui_canvas_t self = vself; + self->bounds = *bounds; +} + +static void +canvas_get_bounds (void *vself, grub_video_rect_t *bounds) +{ + grub_gui_canvas_t self = vself; + *bounds = self->bounds; +} + +static void +canvas_get_preferred_size (void *vself, int *width, int *height) +{ + grub_gui_canvas_t self = vself; + *width = 0; + *height = 0; + + /* Allow preferred dimensions to override the empty dimensions. */ + if (self->preferred_width >= 0) + *width = self->preferred_width; + if (self->preferred_height >= 0) + *height = self->preferred_height; +} + +static grub_err_t +canvas_set_property (void *vself, const char *name, const char *value) +{ + grub_gui_canvas_t self = vself; + if (grub_strcmp (name, "id") == 0) + { + grub_free (self->id); + if (value) + { + self->id = grub_strdup (value); + if (! self->id) + return grub_errno; + } + else + self->id = 0; + } + else if (grub_strcmp (name, "preferred_size") == 0) + { + int w; + int h; + if (grub_gui_parse_2_tuple (value, &w, &h) != GRUB_ERR_NONE) + return grub_errno; + self->preferred_width = w; + self->preferred_height = h; + } + return grub_errno; +} + +static void +canvas_add (void *vself, grub_gui_component_t comp) +{ + grub_gui_canvas_t self = vself; + struct component_node *node; + node = grub_malloc (sizeof (*node)); + if (! node) + return; /* Note: probably should handle the error. */ + node->component = comp; + node->next = self->components.next; + self->components.next = node; + comp->ops->set_parent (comp, (grub_gui_container_t) self); +} + +static void +canvas_remove (void *vself, grub_gui_component_t comp) +{ + grub_gui_canvas_t self = vself; + struct component_node *cur; + struct component_node *prev; + prev = &self->components; + for (cur = self->components.next; cur; prev = cur, cur = cur->next) + { + if (cur->component == comp) + { + /* Unlink 'cur' from the list. */ + prev->next = cur->next; + /* Free the node's memory (but don't destroy the component). */ + grub_free (cur); + /* Must not loop again, since 'cur' would be dereferenced! */ + return; + } + } +} + +static void +canvas_iterate_children (void *vself, + grub_gui_component_callback cb, void *userdata) +{ + grub_gui_canvas_t self = vself; + struct component_node *cur; + for (cur = self->components.next; cur; cur = cur->next) + cb (cur->component, userdata); +} + +static struct grub_gui_container_ops canvas_ops = +{ + .component = + { + .destroy = canvas_destroy, + .get_id = canvas_get_id, + .is_instance = canvas_is_instance, + .paint = canvas_paint, + .set_parent = canvas_set_parent, + .get_parent = canvas_get_parent, + .set_bounds = canvas_set_bounds, + .get_bounds = canvas_get_bounds, + .get_preferred_size = canvas_get_preferred_size, + .set_property = canvas_set_property + }, + .add = canvas_add, + .remove = canvas_remove, + .iterate_children = canvas_iterate_children +}; + +grub_gui_container_t +grub_gui_canvas_new (void) +{ + grub_gui_canvas_t canvas; + canvas = grub_malloc (sizeof (*canvas)); + if (! canvas) + return 0; + canvas->container = &canvas_ops; + canvas->parent = 0; + canvas->bounds.x = 0; + canvas->bounds.y = 0; + canvas->bounds.width = 0; + canvas->bounds.height = 0; + canvas->id = 0; + canvas->preferred_width = -1; + canvas->preferred_height = -1; + canvas->components.component = 0; + canvas->components.next = 0; + return (grub_gui_container_t) canvas; +} diff --git a/gfxmenu/gui_circular_progress.c b/gfxmenu/gui_circular_progress.c new file mode 100644 index 000000000..cd95c51f9 --- /dev/null +++ b/gfxmenu/gui_circular_progress.c @@ -0,0 +1,339 @@ +/* gui_circular_process.c - GUI circular progress indicator component. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +struct grub_gui_circular_progress +{ + struct grub_gui_component_ops *circprog_ops; + + grub_gui_container_t parent; + grub_video_rect_t bounds; + char *id; + int preferred_width; + int preferred_height; + int visible; + int start; + int end; + int value; + int num_ticks; + int start_angle; + int ticks_disappear; + char *theme_dir; + int need_to_load_pixmaps; + char *center_file; + char *tick_file; + struct grub_video_bitmap *center_bitmap; + struct grub_video_bitmap *tick_bitmap; +}; + +typedef struct grub_gui_circular_progress *circular_progress_t; + +static void +circprog_destroy (void *vself) +{ + circular_progress_t self = vself; + grub_free (self); +} + +static const char * +circprog_get_id (void *vself) +{ + circular_progress_t self = vself; + return self->id; +} + +static int +circprog_is_instance (void *vself __attribute__((unused)), const char *type) +{ + return grub_strcmp (type, "component") == 0; +} + +static struct grub_video_bitmap * +load_bitmap (const char *dir, const char *file) +{ + struct grub_video_bitmap *bitmap; + char *abspath; + + /* Check arguments. */ + if (! dir || ! file) + return 0; + + /* Resolve to an absolute path. */ + abspath = grub_resolve_relative_path (dir, file); + if (! abspath) + return 0; + + /* Load the image. */ + grub_errno = GRUB_ERR_NONE; + grub_video_bitmap_load (&bitmap, abspath); + grub_errno = GRUB_ERR_NONE; + + grub_free (abspath); + return bitmap; +} + +static int +check_pixmaps (circular_progress_t self) +{ + if (self->need_to_load_pixmaps) + { + if (self->center_bitmap) + grub_video_bitmap_destroy (self->center_bitmap); + self->center_bitmap = load_bitmap (self->theme_dir, self->center_file); + self->tick_bitmap = load_bitmap (self->theme_dir, self->tick_file); + self->need_to_load_pixmaps = 0; + } + + return (self->center_bitmap != 0 && self->tick_bitmap != 0); +} + +static void +circprog_paint (void *vself) +{ + circular_progress_t self = vself; + + if (! self->visible) + return; + if (! check_pixmaps (self)) + return; + + grub_video_rect_t vpsave; + grub_gui_set_viewport (&self->bounds, &vpsave); + + int width = self->bounds.width; + int height = self->bounds.height; + int center_width = grub_video_bitmap_get_width (self->center_bitmap); + int center_height = grub_video_bitmap_get_height (self->center_bitmap); + int tick_width = grub_video_bitmap_get_width (self->tick_bitmap); + int tick_height = grub_video_bitmap_get_height (self->tick_bitmap); + grub_video_blit_bitmap (self->center_bitmap, GRUB_VIDEO_BLIT_BLEND, + (width - center_width) / 2, + (height - center_height) / 2, 0, 0, + center_width, center_height); + + int radius = width / 2 - tick_width / 2 - 1; + int nticks = (self->num_ticks + * (self->value - self->start) + / (self->end - self->start)); + int tick_begin; + int tick_end; + /* Do ticks appear or disappear as the value approached the end? */ + if (self->ticks_disappear) + { + tick_begin = nticks; + tick_end = self->num_ticks - 1; + } + else + { + tick_begin = 0; + tick_end = nticks - 1; + } + + int i; + for (i = tick_begin; i < tick_end; i++) + { + int x; + int y; + int angle; + + /* Calculate the location of the tick. */ + angle = self->start_angle + i * GRUB_TRIG_ANGLE_MAX / self->num_ticks; + x = width / 2 + (grub_cos (angle) * radius / GRUB_TRIG_FRACTION_SCALE); + y = height / 2 + (grub_sin (angle) * radius / GRUB_TRIG_FRACTION_SCALE); + + /* Adjust (x,y) so the tick is centered. */ + x -= tick_width / 2; + y -= tick_height / 2; + + /* Draw the tick. */ + grub_video_blit_bitmap (self->tick_bitmap, GRUB_VIDEO_BLIT_BLEND, + x, y, 0, 0, tick_width, tick_height); + } + + grub_gui_restore_viewport (&vpsave); +} + +static void +circprog_set_parent (void *vself, grub_gui_container_t parent) +{ + circular_progress_t self = vself; + self->parent = parent; +} + +static grub_gui_container_t +circprog_get_parent (void *vself) +{ + circular_progress_t self = vself; + return self->parent; +} + +static void +circprog_set_bounds (void *vself, const grub_video_rect_t *bounds) +{ + circular_progress_t self = vself; + self->bounds = *bounds; +} + +static void +circprog_get_bounds (void *vself, grub_video_rect_t *bounds) +{ + circular_progress_t self = vself; + *bounds = self->bounds; +} + +static void +circprog_get_preferred_size (void *vself, int *width, int *height) +{ + circular_progress_t self = vself; + + *width = 0; + *height = 0; + + /* Allow preferred dimensions to override the circprog dimensions. */ + if (self->preferred_width >= 0) + *width = self->preferred_width; + if (self->preferred_height >= 0) + *height = self->preferred_height; +} + +static grub_err_t +circprog_set_property (void *vself, const char *name, const char *value) +{ + circular_progress_t self = vself; + if (grub_strcmp (name, "value") == 0) + { + self->value = grub_strtol (value, 0, 10); + } + else if (grub_strcmp (name, "start") == 0) + { + self->start = grub_strtol (value, 0, 10); + } + else if (grub_strcmp (name, "end") == 0) + { + self->end = grub_strtol (value, 0, 10); + } + else if (grub_strcmp (name, "num_ticks") == 0) + { + self->num_ticks = grub_strtol (value, 0, 10); + } + else if (grub_strcmp (name, "start_angle") == 0) + { + self->start_angle = grub_strtol (value, 0, 10); + } + else if (grub_strcmp (name, "ticks_disappear") == 0) + { + self->ticks_disappear = grub_strcmp (value, "false") != 0; + } + else if (grub_strcmp (name, "center_bitmap") == 0) + { + self->need_to_load_pixmaps = 1; + grub_free (self->center_file); + self->center_file = value ? grub_strdup (value) : 0; + } + else if (grub_strcmp (name, "tick_bitmap") == 0) + { + self->need_to_load_pixmaps = 1; + grub_free (self->tick_file); + self->tick_file = value ? grub_strdup (value) : 0; + } + else if (grub_strcmp (name, "theme_dir") == 0) + { + self->need_to_load_pixmaps = 1; + grub_free (self->theme_dir); + self->theme_dir = value ? grub_strdup (value) : 0; + } + else if (grub_strcmp (name, "preferred_size") == 0) + { + int w; + int h; + if (grub_gui_parse_2_tuple (value, &w, &h) != GRUB_ERR_NONE) + return grub_errno; + self->preferred_width = w; + self->preferred_height = h; + } + else if (grub_strcmp (name, "visible") == 0) + { + self->visible = grub_strcmp (value, "false") != 0; + } + else if (grub_strcmp (name, "id") == 0) + { + grub_free (self->id); + if (value) + self->id = grub_strdup (value); + else + self->id = 0; + } + return grub_errno; +} + +static struct grub_gui_component_ops circprog_ops = +{ + .destroy = circprog_destroy, + .get_id = circprog_get_id, + .is_instance = circprog_is_instance, + .paint = circprog_paint, + .set_parent = circprog_set_parent, + .get_parent = circprog_get_parent, + .set_bounds = circprog_set_bounds, + .get_bounds = circprog_get_bounds, + .get_preferred_size = circprog_get_preferred_size, + .set_property = circprog_set_property +}; + +grub_gui_component_t +grub_gui_circular_progress_new (void) +{ + circular_progress_t self; + self = grub_malloc (sizeof (*self)); + if (! self) + return 0; + self->circprog_ops = &circprog_ops; + self->parent = 0; + self->bounds.x = 0; + self->bounds.y = 0; + self->bounds.width = 0; + self->bounds.height = 0; + self->id = 0; + self->preferred_width = -1; + self->preferred_height = -1; + self->visible = 1; + self->start = 0; + self->end = 0; + self->value = 0; + self->num_ticks = 64; + self->start_angle = -64; + self->ticks_disappear = 0; + + self->theme_dir = 0; + self->need_to_load_pixmaps = 0; + self->center_file = 0; + self->tick_file = 0; + self->center_bitmap = 0; + self->tick_bitmap = 0; + + return (grub_gui_component_t) self; +} diff --git a/gfxmenu/gui_image.c b/gfxmenu/gui_image.c new file mode 100644 index 000000000..1c58a535b --- /dev/null +++ b/gfxmenu/gui_image.c @@ -0,0 +1,270 @@ +/* gui_image.c - GUI component to display an image. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +struct grub_gui_image +{ + struct grub_gui_component_ops *image; + + grub_gui_container_t parent; + grub_video_rect_t bounds; + char *id; + int preferred_width; + int preferred_height; + struct grub_video_bitmap *raw_bitmap; + struct grub_video_bitmap *bitmap; +}; + +typedef struct grub_gui_image *grub_gui_image_t; + +static void +image_destroy (void *vself) +{ + grub_gui_image_t self = vself; + + /* Free the scaled bitmap, unless it's a reference to the raw bitmap. */ + if (self->bitmap && (self->bitmap != self->raw_bitmap)) + grub_video_bitmap_destroy (self->bitmap); + if (self->raw_bitmap) + grub_video_bitmap_destroy (self->raw_bitmap); + + grub_free (self); +} + +static const char * +image_get_id (void *vself) +{ + grub_gui_image_t self = vself; + return self->id; +} + +static int +image_is_instance (void *vself __attribute__((unused)), const char *type) +{ + return grub_strcmp (type, "component") == 0; +} + +static void +image_paint (void *vself) +{ + grub_gui_image_t self = vself; + if (! self->bitmap) + return; + grub_video_rect_t vpsave; + grub_gui_set_viewport (&self->bounds, &vpsave); + grub_video_blit_bitmap (self->bitmap, GRUB_VIDEO_BLIT_BLEND, + 0, 0, 0, 0, + grub_video_bitmap_get_width (self->bitmap), + grub_video_bitmap_get_height (self->bitmap)); + grub_gui_restore_viewport (&vpsave); +} + +static void +image_set_parent (void *vself, grub_gui_container_t parent) +{ + grub_gui_image_t self = vself; + self->parent = parent; +} + +static grub_gui_container_t +image_get_parent (void *vself) +{ + grub_gui_image_t self = vself; + return self->parent; +} + +static grub_err_t +rescale_image (grub_gui_image_t self) +{ + if (! self->raw_bitmap) + { + if (self->bitmap) + { + grub_video_bitmap_destroy (self->bitmap); + self->bitmap = 0; + } + return grub_errno; + } + + unsigned width = self->bounds.width; + unsigned height = self->bounds.height; + + if (self->bitmap + && (grub_video_bitmap_get_width (self->bitmap) == width) + && (grub_video_bitmap_get_height (self->bitmap) == height)) + { + /* Nothing to do; already the right size. */ + return grub_errno; + } + + /* Free any old scaled bitmap, + *unless* it's a reference to the raw bitmap. */ + if (self->bitmap && (self->bitmap != self->raw_bitmap)) + grub_video_bitmap_destroy (self->bitmap); + + self->bitmap = 0; + + /* Create a scaled bitmap, unless the requested size is the same + as the raw size -- in that case a reference is made. */ + if (grub_video_bitmap_get_width (self->raw_bitmap) == width + && grub_video_bitmap_get_height (self->raw_bitmap) == height) + { + self->bitmap = self->raw_bitmap; + return grub_errno; + } + + /* Don't scale to an invalid size. */ + if (width == 0 || height == 0) + return grub_errno; + + /* Create the scaled bitmap. */ + grub_video_bitmap_create_scaled (&self->bitmap, + width, + height, + self->raw_bitmap, + GRUB_VIDEO_BITMAP_SCALE_METHOD_BEST); + if (grub_errno != GRUB_ERR_NONE) + { + grub_error_push (); + grub_error (grub_errno, "failed to scale bitmap for image component"); + } + return grub_errno; +} + +static void +image_set_bounds (void *vself, const grub_video_rect_t *bounds) +{ + grub_gui_image_t self = vself; + self->bounds = *bounds; + rescale_image (self); +} + +static void +image_get_bounds (void *vself, grub_video_rect_t *bounds) +{ + grub_gui_image_t self = vself; + *bounds = self->bounds; +} + +static void +image_get_preferred_size (void *vself, int *width, int *height) +{ + grub_gui_image_t self = vself; + + if (self->raw_bitmap) + { + *width = grub_video_bitmap_get_width (self->raw_bitmap); + *height = grub_video_bitmap_get_height (self->raw_bitmap); + } + else + { + *width = 0; + *height = 0; + } + + /* Allow preferred dimensions to override the image dimensions. */ + if (self->preferred_width >= 0) + *width = self->preferred_width; + if (self->preferred_height >= 0) + *height = self->preferred_height; +} + +static grub_err_t +load_image (grub_gui_image_t self, const char *path) +{ + struct grub_video_bitmap *bitmap; + if (grub_video_bitmap_load (&bitmap, path) != GRUB_ERR_NONE) + return grub_errno; + + if (self->bitmap && (self->bitmap != self->raw_bitmap)) + grub_video_bitmap_destroy (self->bitmap); + if (self->raw_bitmap) + grub_video_bitmap_destroy (self->raw_bitmap); + + self->raw_bitmap = bitmap; + return rescale_image (self); +} + +static grub_err_t +image_set_property (void *vself, const char *name, const char *value) +{ + grub_gui_image_t self = vself; + if (grub_strcmp (name, "file") == 0) + return load_image (self, value); + else if (grub_strcmp (name, "preferred_size") == 0) + { + int w; + int h; + if (grub_gui_parse_2_tuple (value, &w, &h) != GRUB_ERR_NONE) + return grub_errno; + self->preferred_width = w; + self->preferred_height = h; + } + else if (grub_strcmp (name, "id") == 0) + { + grub_free (self->id); + if (value) + self->id = grub_strdup (value); + else + self->id = 0; + } + return grub_errno; +} + +static struct grub_gui_component_ops image_ops = +{ + .destroy = image_destroy, + .get_id = image_get_id, + .is_instance = image_is_instance, + .paint = image_paint, + .set_parent = image_set_parent, + .get_parent = image_get_parent, + .set_bounds = image_set_bounds, + .get_bounds = image_get_bounds, + .get_preferred_size = image_get_preferred_size, + .set_property = image_set_property +}; + +grub_gui_component_t +grub_gui_image_new (void) +{ + grub_gui_image_t image; + image = grub_malloc (sizeof (*image)); + if (! image) + return 0; + image->image = &image_ops; + image->parent = 0; + image->bounds.x = 0; + image->bounds.y = 0; + image->bounds.width = 0; + image->bounds.height = 0; + image->id = 0; + image->preferred_width = -1; + image->preferred_height = -1; + image->raw_bitmap = 0; + image->bitmap = 0; + return (grub_gui_component_t) image; +} + diff --git a/gfxmenu/gui_label.c b/gfxmenu/gui_label.c new file mode 100644 index 000000000..2e49c787e --- /dev/null +++ b/gfxmenu/gui_label.c @@ -0,0 +1,248 @@ +/* gui_label.c - GUI component to display a line of text. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include + +static const char *align_options[] = +{ + "left", + "center", + "right", + 0 +}; + +enum align_mode { + align_left, + align_center, + align_right +}; + +struct grub_gui_label +{ + struct grub_gui_component_ops *label; + + grub_gui_container_t parent; + grub_video_rect_t bounds; + char *id; + int preferred_width; + int preferred_height; + int visible; + char *text; + grub_font_t font; + grub_gui_color_t color; + enum align_mode align; +}; + +typedef struct grub_gui_label *grub_gui_label_t; + +static void +label_destroy (void *vself) +{ + grub_gui_label_t self = vself; + grub_free (self->text); + grub_free (self); +} + +static const char * +label_get_id (void *vself) +{ + grub_gui_label_t self = vself; + return self->id; +} + +static int +label_is_instance (void *vself __attribute__((unused)), const char *type) +{ + return grub_strcmp (type, "component") == 0; +} + +static void +label_paint (void *vself) +{ + grub_gui_label_t self = vself; + + if (! self->visible) + return; + + /* Calculate the starting x coordinate. */ + int left_x; + if (self->align == align_left) + left_x = 0; + else if (self->align == align_center) + left_x = ((self->bounds.width + - grub_font_get_string_width (self->font, self->text)) + ) / 2; + else if (self->align == align_right) + left_x = (self->bounds.width + - grub_font_get_string_width (self->font, self->text)); + else + return; /* Invalid alignment. */ + + grub_video_rect_t vpsave; + grub_gui_set_viewport (&self->bounds, &vpsave); + grub_font_draw_string (self->text, + self->font, + grub_gui_map_color (self->color), + left_x, + grub_font_get_ascent (self->font)); + grub_gui_restore_viewport (&vpsave); +} + +static void +label_set_parent (void *vself, grub_gui_container_t parent) +{ + grub_gui_label_t self = vself; + self->parent = parent; +} + +static grub_gui_container_t +label_get_parent (void *vself) +{ + grub_gui_label_t self = vself; + return self->parent; +} + +static void +label_set_bounds (void *vself, const grub_video_rect_t *bounds) +{ + grub_gui_label_t self = vself; + self->bounds = *bounds; +} + +static void +label_get_bounds (void *vself, grub_video_rect_t *bounds) +{ + grub_gui_label_t self = vself; + *bounds = self->bounds; +} + +static void +label_get_preferred_size (void *vself, int *width, int *height) +{ + grub_gui_label_t self = vself; + *width = grub_font_get_string_width (self->font, self->text); + *height = (grub_font_get_ascent (self->font) + + grub_font_get_descent (self->font)); + + /* Allow preferred dimensions to override the computed dimensions. */ + if (self->preferred_width >= 0) + *width = self->preferred_width; + if (self->preferred_height >= 0) + *height = self->preferred_height; +} + +static void +label_set_property (void *vself, const char *name, const char *value) +{ + grub_gui_label_t self = vself; + if (grub_strcmp (name, "text") == 0) + { + grub_free (self->text); + if (! value) + value = ""; + self->text = grub_strdup (value); + } + else if (grub_strcmp (name, "font") == 0) + { + self->font = grub_font_get (value); + } + else if (grub_strcmp (name, "color") == 0) + { + grub_gui_parse_color (value, &self->color); + } + else if (grub_strcmp (name, "align") == 0) + { + int i; + for (i = 0; align_options[i]; i++) + { + if (grub_strcmp (align_options[i], value) == 0) + { + self->align = i; /* Set the alignment mode. */ + break; + } + } + } + else if (grub_strcmp (name, "visible") == 0) + { + self->visible = grub_strcmp (value, "false") != 0; + } + else if (grub_strcmp (name, "preferred_size") == 0) + { + int w; + int h; + if (grub_gui_parse_2_tuple (value, &w, &h) == GRUB_ERR_NONE) + { + self->preferred_width = w; + self->preferred_height = h; + } + } + else if (grub_strcmp (name, "id") == 0) + { + grub_free (self->id); + if (value) + self->id = grub_strdup (value); + else + self->id = 0; + } +} + +static struct grub_gui_component_ops label_ops = +{ + .destroy = label_destroy, + .get_id = label_get_id, + .is_instance = label_is_instance, + .paint = label_paint, + .set_parent = label_set_parent, + .get_parent = label_get_parent, + .set_bounds = label_set_bounds, + .get_bounds = label_get_bounds, + .get_preferred_size = label_get_preferred_size, + .set_property = label_set_property +}; + +grub_gui_component_t +grub_gui_label_new (void) +{ + grub_gui_label_t label; + label = grub_malloc (sizeof (*label)); + if (! label) + return 0; + label->label = &label_ops; + label->parent = 0; + label->bounds.x = 0; + label->bounds.y = 0; + label->bounds.width = 0; + label->bounds.height = 0; + label->id = 0; + label->preferred_width = -1; + label->preferred_height = -1; + label->visible = 1; + label->text = grub_strdup (""); + label->font = grub_font_get ("Helvetica 10"); + label->color.red = 0; + label->color.green = 0; + label->color.blue = 0; + label->color.alpha = 255; + label->align = align_left; + return (grub_gui_component_t) label; +} diff --git a/gfxmenu/gui_list.c b/gfxmenu/gui_list.c new file mode 100644 index 000000000..aa9655b45 --- /dev/null +++ b/gfxmenu/gui_list.c @@ -0,0 +1,625 @@ +/* gui_list.c - GUI component to display a selectable list of items. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +struct grub_gui_list_impl +{ + struct grub_gui_list_ops *list_ops; + + grub_gui_container_t parent; + grub_video_rect_t bounds; + char *id; + int preferred_width; + int preferred_height; + int visible; + + int icon_width; + int icon_height; + int item_height; + int item_padding; + int item_icon_space; + int item_spacing; + grub_font_t item_font; + grub_font_t selected_item_font; + grub_gui_color_t item_color; + int selected_item_color_set; + grub_gui_color_t selected_item_color; + + int draw_scrollbar; + int need_to_recreate_scrollbar; + char *scrollbar_frame_pattern; + char *scrollbar_thumb_pattern; + grub_gfxmenu_box_t scrollbar_frame; + grub_gfxmenu_box_t scrollbar_thumb; + int scrollbar_width; + + int min_items_shown; + int max_items_shown; + int first_shown_index; + + int need_to_recreate_boxes; + char *theme_dir; + char *menu_box_pattern; + char *selected_item_box_pattern; + grub_gfxmenu_box_t menu_box; + grub_gfxmenu_box_t selected_item_box; + + grub_gfxmenu_icon_manager_t icon_manager; + grub_gfxmenu_model_t menu; +}; + +typedef struct grub_gui_list_impl *list_impl_t; + +static void +list_destroy (void *vself) +{ + list_impl_t self = vself; + + grub_free (self->theme_dir); + grub_free (self->menu_box_pattern); + grub_free (self->selected_item_box_pattern); + if (self->menu_box) + self->menu_box->destroy (self->menu_box); + if (self->selected_item_box) + self->selected_item_box->destroy (self->selected_item_box); + if (self->icon_manager) + grub_gfxmenu_icon_manager_destroy (self->icon_manager); + + grub_free (self); +} + +static int +get_num_shown_items (list_impl_t self) +{ + int n = grub_gfxmenu_model_get_num_entries (self->menu); + if (self->min_items_shown != -1 && n < self->min_items_shown) + n = self->min_items_shown; + if (self->max_items_shown != -1 && n > self->max_items_shown) + n = self->max_items_shown; + return n; +} + +static int +check_boxes (list_impl_t self) +{ + if (self->need_to_recreate_boxes) + { + grub_gui_recreate_box (&self->menu_box, + self->menu_box_pattern, + self->theme_dir); + + grub_gui_recreate_box (&self->selected_item_box, + self->selected_item_box_pattern, + self->theme_dir); + + self->need_to_recreate_boxes = 0; + } + + return (self->menu_box != 0 && self->selected_item_box != 0); +} + +static int +check_scrollbar (list_impl_t self) +{ + if (self->need_to_recreate_scrollbar) + { + grub_gui_recreate_box (&self->scrollbar_frame, + self->scrollbar_frame_pattern, + self->theme_dir); + + grub_gui_recreate_box (&self->scrollbar_thumb, + self->scrollbar_thumb_pattern, + self->theme_dir); + + self->need_to_recreate_scrollbar = 0; + } + + return (self->scrollbar_frame != 0 && self->scrollbar_thumb != 0); +} + +static const char * +list_get_id (void *vself) +{ + list_impl_t self = vself; + return self->id; +} + +static int +list_is_instance (void *vself __attribute__((unused)), const char *type) +{ + return (grub_strcmp (type, "component") == 0 + || grub_strcmp (type, "list") == 0); +} + +static struct grub_video_bitmap * +get_item_icon (list_impl_t self, int item_index) +{ + grub_menu_entry_t entry; + entry = grub_gfxmenu_model_get_entry (self->menu, item_index); + if (! entry) + return 0; + + return grub_gfxmenu_icon_manager_get_icon (self->icon_manager, entry); +} + +static void +make_selected_item_visible (list_impl_t self) +{ + int selected_index = grub_gfxmenu_model_get_selected_index (self->menu); + if (selected_index < 0) + return; /* No item is selected. */ + int num_shown_items = get_num_shown_items (self); + int last_shown_index = self->first_shown_index + (num_shown_items - 1); + if (selected_index < self->first_shown_index) + self->first_shown_index = selected_index; + else if (selected_index > last_shown_index) + self->first_shown_index = selected_index - (num_shown_items - 1); +} + +/* Draw a scrollbar on the menu. */ +static void +draw_scrollbar (list_impl_t self, + int value, int extent, int min, int max, + int rightx, int topy, int height) +{ + grub_gfxmenu_box_t frame = self->scrollbar_frame; + grub_gfxmenu_box_t thumb = self->scrollbar_thumb; + int frame_vertical_pad = (frame->get_top_pad (frame) + + frame->get_bottom_pad (frame)); + int frame_horizontal_pad = (frame->get_left_pad (frame) + + frame->get_right_pad (frame)); + int tracktop = topy + frame->get_top_pad (frame); + int tracklen = height - frame_vertical_pad; + frame->set_content_size (frame, self->scrollbar_width, tracklen); + int thumby = tracktop + tracklen * (value - min) / (max - min); + int thumbheight = tracklen * extent / (max - min) + 1; + thumb->set_content_size (thumb, + self->scrollbar_width - frame_horizontal_pad, + thumbheight - (thumb->get_top_pad (thumb) + + thumb->get_bottom_pad (thumb))); + frame->draw (frame, + rightx - (self->scrollbar_width + frame_horizontal_pad), + topy); + thumb->draw (thumb, + rightx - (self->scrollbar_width - frame->get_right_pad (frame)), + thumby); +} + +/* Draw the list of items. */ +static void +draw_menu (list_impl_t self) +{ + if (! self->menu_box || ! self->selected_item_box) + return; + + int boxpad = self->item_padding; + int icon_text_space = self->item_icon_space; + int item_vspace = self->item_spacing; + + int ascent = grub_font_get_ascent (self->item_font); + int descent = grub_font_get_descent (self->item_font); + int item_height = self->item_height; + + int total_num_items = grub_gfxmenu_model_get_num_entries (self->menu); + int num_shown_items = get_num_shown_items (self); + grub_gfxmenu_box_t box = self->menu_box; + int width = self->bounds.width; + int height = self->bounds.height; + + int box_left_pad = box->get_left_pad (box); + int box_top_pad = box->get_top_pad (box); + int box_right_pad = box->get_right_pad (box); + int box_bottom_pad = box->get_bottom_pad (box); + + box->set_content_size (box, + width - box_left_pad - box_right_pad, + height - box_top_pad - box_bottom_pad); + + box->draw (box, 0, 0); + + make_selected_item_visible (self); + + int drawing_scrollbar = (self->draw_scrollbar + && (num_shown_items < total_num_items) + && check_scrollbar (self)); + + int scrollbar_h_space = drawing_scrollbar ? self->scrollbar_width : 0; + + int item_top = box_top_pad + boxpad; + int item_left = box_left_pad + boxpad; + int menu_index; + int visible_index; + + for (visible_index = 0, menu_index = self->first_shown_index; + visible_index < num_shown_items && menu_index < total_num_items; + visible_index++, menu_index++) + { + int is_selected = + (menu_index == grub_gfxmenu_model_get_selected_index (self->menu)); + + if (is_selected) + { + grub_gfxmenu_box_t selbox = self->selected_item_box; + int sel_leftpad = selbox->get_left_pad (selbox); + int sel_toppad = selbox->get_top_pad (selbox); + selbox->set_content_size (selbox, + (width - 2 * boxpad + - box_left_pad - box_right_pad + - scrollbar_h_space), + item_height); + selbox->draw (selbox, + item_left - sel_leftpad, + item_top - sel_toppad); + } + + struct grub_video_bitmap *icon; + if ((icon = get_item_icon (self, menu_index)) != 0) + grub_video_blit_bitmap (icon, GRUB_VIDEO_BLIT_BLEND, + item_left, + item_top + (item_height - self->icon_height) / 2, + 0, 0, self->icon_width, self->icon_height); + + const char *item_title = + grub_gfxmenu_model_get_entry_title (self->menu, menu_index); + grub_font_t font = + (is_selected && self->selected_item_font + ? self->selected_item_font + : self->item_font); + grub_gui_color_t text_color = + ((is_selected && self->selected_item_color_set) + ? self->selected_item_color + : self->item_color); + grub_font_draw_string (item_title, + font, + grub_gui_map_color (text_color), + item_left + self->icon_width + icon_text_space, + (item_top + (item_height - (ascent + descent)) + / 2 + ascent)); + + item_top += item_height + item_vspace; + } + + if (drawing_scrollbar) + draw_scrollbar (self, + self->first_shown_index, num_shown_items, + 0, total_num_items, + width - box_right_pad + self->scrollbar_width, + box_top_pad + boxpad, + height - box_top_pad - box_bottom_pad); +} + +static void +list_paint (void *vself) +{ + list_impl_t self = vself; + + if (! self->visible) + return; + + check_boxes (self); + + grub_video_rect_t vpsave; + grub_gui_set_viewport (&self->bounds, &vpsave); + draw_menu (self); + grub_gui_restore_viewport (&vpsave); +} + +static void +list_set_parent (void *vself, grub_gui_container_t parent) +{ + list_impl_t self = vself; + self->parent = parent; +} + +static grub_gui_container_t +list_get_parent (void *vself) +{ + list_impl_t self = vself; + return self->parent; +} + +static void +list_set_bounds (void *vself, const grub_video_rect_t *bounds) +{ + list_impl_t self = vself; + self->bounds = *bounds; +} + +static void +list_get_bounds (void *vself, grub_video_rect_t *bounds) +{ + list_impl_t self = vself; + *bounds = self->bounds; +} + +static void +list_get_preferred_size (void *vself, int *width, int *height) +{ + list_impl_t self = vself; + + if (check_boxes (self)) + { + int boxpad = self->item_padding; + int item_vspace = self->item_spacing; + int item_height = self->item_height; + int num_items = get_num_shown_items (self); + + grub_gfxmenu_box_t box = self->menu_box; + int box_left_pad = box->get_left_pad (box); + int box_top_pad = box->get_top_pad (box); + int box_right_pad = box->get_right_pad (box); + int box_bottom_pad = box->get_bottom_pad (box); + + *width = 400 + 2 * boxpad + box_left_pad + box_right_pad; + + /* Set the menu box height to fit the items. */ + *height = (item_height * num_items + + item_vspace * (num_items - 1) + + 2 * boxpad + + box_top_pad + box_bottom_pad); + } + else + { + *width = 0; + *height = 0; + } + + /* Allow preferred dimensions to override the computed dimensions. */ + if (self->preferred_width >= 0) + *width = self->preferred_width; + if (self->preferred_height >= 0) + *height = self->preferred_height; +} + +static grub_err_t +list_set_property (void *vself, const char *name, const char *value) +{ + list_impl_t self = vself; + if (grub_strcmp (name, "item_font") == 0) + { + self->item_font = grub_font_get (value); + } + else if (grub_strcmp (name, "selected_item_font") == 0) + { + if (! value || grub_strcmp (value, "inherit") == 0) + self->selected_item_font = 0; + else + self->selected_item_font = grub_font_get (value); + } + else if (grub_strcmp (name, "item_color") == 0) + { + grub_gui_parse_color (value, &self->item_color); + } + else if (grub_strcmp (name, "selected_item_color") == 0) + { + if (! value || grub_strcmp (value, "inherit") == 0) + { + self->selected_item_color_set = 0; + } + else + { + if (grub_gui_parse_color (value, &self->selected_item_color) + == GRUB_ERR_NONE) + self->selected_item_color_set = 1; + } + } + else if (grub_strcmp (name, "icon_width") == 0) + { + self->icon_width = grub_strtol (value, 0, 10); + grub_gfxmenu_icon_manager_set_icon_size (self->icon_manager, + self->icon_width, + self->icon_height); + } + else if (grub_strcmp (name, "icon_height") == 0) + { + self->icon_height = grub_strtol (value, 0, 10); + grub_gfxmenu_icon_manager_set_icon_size (self->icon_manager, + self->icon_width, + self->icon_height); + } + else if (grub_strcmp (name, "item_height") == 0) + { + self->item_height = grub_strtol (value, 0, 10); + } + else if (grub_strcmp (name, "item_padding") == 0) + { + self->item_padding = grub_strtol (value, 0, 10); + } + else if (grub_strcmp (name, "item_icon_space") == 0) + { + self->item_icon_space = grub_strtol (value, 0, 10); + } + else if (grub_strcmp (name, "item_spacing") == 0) + { + self->item_spacing = grub_strtol (value, 0, 10); + } + else if (grub_strcmp (name, "visible") == 0) + { + self->visible = grub_strcmp (value, "false") != 0; + } + else if (grub_strcmp (name, "menu_pixmap_style") == 0) + { + self->need_to_recreate_boxes = 1; + grub_free (self->menu_box_pattern); + self->menu_box_pattern = value ? grub_strdup (value) : 0; + } + else if (grub_strcmp (name, "selected_item_pixmap_style") == 0) + { + self->need_to_recreate_boxes = 1; + grub_free (self->selected_item_box_pattern); + self->selected_item_box_pattern = value ? grub_strdup (value) : 0; + } + else if (grub_strcmp (name, "scrollbar_frame") == 0) + { + self->need_to_recreate_scrollbar = 1; + grub_free (self->scrollbar_frame_pattern); + self->scrollbar_frame_pattern = value ? grub_strdup (value) : 0; + } + else if (grub_strcmp (name, "scrollbar_thumb") == 0) + { + self->need_to_recreate_scrollbar = 1; + grub_free (self->scrollbar_thumb_pattern); + self->scrollbar_thumb_pattern = value ? grub_strdup (value) : 0; + } + else if (grub_strcmp (name, "scrollbar_width") == 0) + { + self->scrollbar_width = grub_strtol (value, 0, 10); + } + else if (grub_strcmp (name, "scrollbar") == 0) + { + self->draw_scrollbar = grub_strcmp (value, "false") != 0; + } + else if (grub_strcmp (name, "min_items_shown") == 0) + { + self->min_items_shown = grub_strtol (value, 0, 10); + } + else if (grub_strcmp (name, "max_items_shown") == 0) + { + self->max_items_shown = grub_strtol (value, 0, 10); + } + else if (grub_strcmp (name, "theme_dir") == 0) + { + self->need_to_recreate_boxes = 1; + grub_free (self->theme_dir); + self->theme_dir = value ? grub_strdup (value) : 0; + } + else if (grub_strcmp (name, "preferred_size") == 0) + { + int w; + int h; + if (grub_gui_parse_2_tuple (value, &w, &h) != GRUB_ERR_NONE) + return grub_errno; + self->preferred_width = w; + self->preferred_height = h; + } + else if (grub_strcmp (name, "id") == 0) + { + grub_free (self->id); + if (value) + self->id = grub_strdup (value); + else + self->id = 0; + } + return grub_errno; +} + +/* Set necessary information that the gfxmenu view provides. */ +static void +list_set_view_info (void *vself, + const char *theme_path, + grub_gfxmenu_model_t menu) +{ + list_impl_t self = vself; + grub_gfxmenu_icon_manager_set_theme_path (self->icon_manager, theme_path); + self->menu = menu; +} + +static struct grub_gui_list_ops list_ops = +{ + .component_ops = + { + .destroy = list_destroy, + .get_id = list_get_id, + .is_instance = list_is_instance, + .paint = list_paint, + .set_parent = list_set_parent, + .get_parent = list_get_parent, + .set_bounds = list_set_bounds, + .get_bounds = list_get_bounds, + .get_preferred_size = list_get_preferred_size, + .set_property = list_set_property + }, + .set_view_info = list_set_view_info +}; + +grub_gui_component_t +grub_gui_list_new (void) +{ + list_impl_t self; + grub_font_t default_font; + grub_gui_color_t default_fg_color; + grub_gui_color_t default_bg_color; + + self = grub_malloc (sizeof (*self)); + if (! self) + return 0; + + self->list_ops = &list_ops; + self->parent = 0; + self->bounds.x = 0; + self->bounds.y = 0; + self->bounds.width = 0; + self->bounds.height = 0; + self->id = 0; + self->preferred_width = -1; + self->preferred_height = -1; + self->visible = 1; + + default_font = grub_font_get ("Helvetica 12"); + default_fg_color = grub_gui_color_rgb (0, 0, 0); + default_bg_color = grub_gui_color_rgb (255, 255, 255); + + self->icon_width = 32; + self->icon_height = 32; + self->item_height = 42; + self->item_padding = 14; + self->item_icon_space = 4; + self->item_spacing = 16; + self->item_font = default_font; + self->selected_item_font = 0; /* Default to using the item_font. */ + self->item_color = default_fg_color; + self->selected_item_color_set = 0; /* Default to using the item_color. */ + self->selected_item_color = default_fg_color; + + self->draw_scrollbar = 1; + self->need_to_recreate_scrollbar = 1; + self->scrollbar_frame = 0; + self->scrollbar_thumb = 0; + self->scrollbar_frame_pattern = 0; + self->scrollbar_thumb_pattern = 0; + self->scrollbar_width = 16; + + self->min_items_shown = -1; + self->max_items_shown = -1; + self->first_shown_index = 0; + + self->need_to_recreate_boxes = 0; + self->theme_dir = 0; + self->menu_box_pattern = 0; + self->selected_item_box_pattern = 0; + self->menu_box = grub_gfxmenu_create_box (0, 0); + self->selected_item_box = grub_gfxmenu_create_box (0, 0); + + self->icon_manager = grub_gfxmenu_icon_manager_new (); + if (! self->icon_manager) + { + self->list_ops->component_ops.destroy (self); + return 0; + } + grub_gfxmenu_icon_manager_set_icon_size (self->icon_manager, + self->icon_width, + self->icon_height); + return (grub_gui_component_t) self; +} diff --git a/gfxmenu/gui_progress_bar.c b/gfxmenu/gui_progress_bar.c new file mode 100644 index 000000000..440d4b2fc --- /dev/null +++ b/gfxmenu/gui_progress_bar.c @@ -0,0 +1,378 @@ +/* gui_progress_bar.c - GUI progress bar component. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include + +struct grub_gui_progress_bar +{ + struct grub_gui_component_ops *progress_bar; + + grub_gui_container_t parent; + grub_video_rect_t bounds; + char *id; + int preferred_width; + int preferred_height; + int visible; + int start; + int end; + int value; + int show_text; + char *text; + grub_font_t font; + grub_gui_color_t text_color; + grub_gui_color_t border_color; + grub_gui_color_t bg_color; + grub_gui_color_t fg_color; + + char *theme_dir; + int need_to_recreate_pixmaps; + char *bar_pattern; + char *highlight_pattern; + grub_gfxmenu_box_t bar_box; + grub_gfxmenu_box_t highlight_box; +}; + +typedef struct grub_gui_progress_bar *grub_gui_progress_bar_t; + +static void +progress_bar_destroy (void *vself) +{ + grub_gui_progress_bar_t self = vself; + grub_free (self); +} + +static const char * +progress_bar_get_id (void *vself) +{ + grub_gui_progress_bar_t self = vself; + return self->id; +} + +static int +progress_bar_is_instance (void *vself __attribute__((unused)), const char *type) +{ + return grub_strcmp (type, "component") == 0; +} + +static int +check_pixmaps (grub_gui_progress_bar_t self) +{ + if (self->need_to_recreate_pixmaps) + { + grub_gui_recreate_box (&self->bar_box, + self->bar_pattern, + self->theme_dir); + + grub_gui_recreate_box (&self->highlight_box, + self->highlight_pattern, + self->theme_dir); + + self->need_to_recreate_pixmaps = 0; + } + + return (self->bar_box != 0 && self->highlight_box != 0); +} + +static void +draw_filled_rect_bar (grub_gui_progress_bar_t self) +{ + /* Set the progress bar's frame. */ + grub_video_rect_t f; + f.x = 1; + f.y = 1; + f.width = self->bounds.width - 2; + f.height = self->bounds.height - 2; + + /* Border. */ + grub_video_fill_rect (grub_gui_map_color (self->border_color), + f.x - 1, f.y - 1, + f.width + 2, f.height + 2); + + /* Bar background. */ + int barwidth = (f.width + * (self->value - self->start) + / (self->end - self->start)); + grub_video_fill_rect (grub_gui_map_color (self->bg_color), + f.x + barwidth, f.y, + f.width - barwidth, f.height); + + /* Bar foreground. */ + grub_video_fill_rect (grub_gui_map_color (self->fg_color), + f.x, f.y, + barwidth, f.height); +} + +static void +draw_pixmap_bar (grub_gui_progress_bar_t self) +{ + grub_gfxmenu_box_t bar = self->bar_box; + grub_gfxmenu_box_t hl = self->highlight_box; + int w = self->bounds.width; + int h = self->bounds.height; + int bar_l_pad = bar->get_left_pad (bar); + int bar_r_pad = bar->get_right_pad (bar); + int bar_t_pad = bar->get_top_pad (bar); + int bar_b_pad = bar->get_bottom_pad (bar); + int bar_h_pad = bar_l_pad + bar_r_pad; + int bar_v_pad = bar_t_pad + bar_b_pad; + int tracklen = w - bar_h_pad; + int trackheight = h - bar_v_pad; + bar->set_content_size (bar, tracklen, trackheight); + + int barwidth = (tracklen + * (self->value - self->start) + / (self->end - self->start)); + hl->set_content_size (hl, barwidth, h - bar_v_pad); + + bar->draw (bar, 0, 0); + hl->draw (hl, bar_l_pad, bar_t_pad); +} + +static void +draw_text (grub_gui_progress_bar_t self) +{ + const char *text = self->text; + if (text && self->show_text) + { + grub_font_t font = self->font; + grub_video_color_t text_color = grub_gui_map_color (self->text_color); + int width = self->bounds.width; + int height = self->bounds.height; + + /* Center the text. */ + int text_width = grub_font_get_string_width (font, text); + int x = (width - text_width) / 2; + int y = ((height - grub_font_get_descent (font)) / 2 + + grub_font_get_ascent (font) / 2); + grub_font_draw_string (text, font, text_color, x, y); + } +} + +static void +progress_bar_paint (void *vself) +{ + grub_gui_progress_bar_t self = vself; + if (! self->visible) + return; + + grub_video_rect_t vpsave; + grub_gui_set_viewport (&self->bounds, &vpsave); + + if (check_pixmaps (self)) + draw_pixmap_bar (self); + else + draw_filled_rect_bar (self); + + draw_text (self); + + grub_gui_restore_viewport (&vpsave); +} + +static void +progress_bar_set_parent (void *vself, grub_gui_container_t parent) +{ + grub_gui_progress_bar_t self = vself; + self->parent = parent; +} + +static grub_gui_container_t +progress_bar_get_parent (void *vself) +{ + grub_gui_progress_bar_t self = vself; + return self->parent; +} + +static void +progress_bar_set_bounds (void *vself, const grub_video_rect_t *bounds) +{ + grub_gui_progress_bar_t self = vself; + self->bounds = *bounds; +} + +static void +progress_bar_get_bounds (void *vself, grub_video_rect_t *bounds) +{ + grub_gui_progress_bar_t self = vself; + *bounds = self->bounds; +} + +static void +progress_bar_get_preferred_size (void *vself, int *width, int *height) +{ + grub_gui_progress_bar_t self = vself; + + *width = 200; + *height = 28; + + /* Allow preferred dimensions to override the progress_bar dimensions. */ + if (self->preferred_width >= 0) + *width = self->preferred_width; + if (self->preferred_height >= 0) + *height = self->preferred_height; +} + +static grub_err_t +progress_bar_set_property (void *vself, const char *name, const char *value) +{ + grub_gui_progress_bar_t self = vself; + if (grub_strcmp (name, "value") == 0) + { + self->value = grub_strtol (value, 0, 10); + } + else if (grub_strcmp (name, "start") == 0) + { + self->start = grub_strtol (value, 0, 10); + } + else if (grub_strcmp (name, "end") == 0) + { + self->end = grub_strtol (value, 0, 10); + } + else if (grub_strcmp (name, "text") == 0) + { + grub_free (self->text); + if (! value) + value = ""; + self->text = grub_strdup (value); + } + else if (grub_strcmp (name, "font") == 0) + { + self->font = grub_font_get (value); + } + else if (grub_strcmp (name, "text_color") == 0) + { + grub_gui_parse_color (value, &self->text_color); + } + else if (grub_strcmp (name, "border_color") == 0) + { + grub_gui_parse_color (value, &self->border_color); + } + else if (grub_strcmp (name, "bg_color") == 0) + { + grub_gui_parse_color (value, &self->bg_color); + } + else if (grub_strcmp (name, "fg_color") == 0) + { + grub_gui_parse_color (value, &self->fg_color); + } + else if (grub_strcmp (name, "bar_style") == 0) + { + self->need_to_recreate_pixmaps = 1; + grub_free (self->bar_pattern); + self->bar_pattern = value ? grub_strdup (value) : 0; + } + else if (grub_strcmp (name, "highlight_style") == 0) + { + self->need_to_recreate_pixmaps = 1; + grub_free (self->highlight_pattern); + self->highlight_pattern = value ? grub_strdup (value) : 0; + } + else if (grub_strcmp (name, "theme_dir") == 0) + { + self->need_to_recreate_pixmaps = 1; + grub_free (self->theme_dir); + self->theme_dir = value ? grub_strdup (value) : 0; + } + else if (grub_strcmp (name, "preferred_size") == 0) + { + int w; + int h; + if (grub_gui_parse_2_tuple (value, &w, &h) != GRUB_ERR_NONE) + return grub_errno; + self->preferred_width = w; + self->preferred_height = h; + } + else if (grub_strcmp (name, "visible") == 0) + { + self->visible = grub_strcmp (value, "false") != 0; + } + else if (grub_strcmp (name, "show_text") == 0) + { + self->show_text = grub_strcmp (value, "false") != 0; + } + else if (grub_strcmp (name, "id") == 0) + { + grub_free (self->id); + if (value) + self->id = grub_strdup (value); + else + self->id = 0; + } + return grub_errno; +} + +static struct grub_gui_component_ops progress_bar_ops = +{ + .destroy = progress_bar_destroy, + .get_id = progress_bar_get_id, + .is_instance = progress_bar_is_instance, + .paint = progress_bar_paint, + .set_parent = progress_bar_set_parent, + .get_parent = progress_bar_get_parent, + .set_bounds = progress_bar_set_bounds, + .get_bounds = progress_bar_get_bounds, + .get_preferred_size = progress_bar_get_preferred_size, + .set_property = progress_bar_set_property +}; + +grub_gui_component_t +grub_gui_progress_bar_new (void) +{ + grub_gui_progress_bar_t self; + self = grub_malloc (sizeof (*self)); + if (! self) + return 0; + self->progress_bar = &progress_bar_ops; + self->parent = 0; + self->bounds.x = 0; + self->bounds.y = 0; + self->bounds.width = 0; + self->bounds.height = 0; + self->id = 0; + self->preferred_width = -1; + self->preferred_height = -1; + self->visible = 1; + self->start = 0; + self->end = 0; + self->value = 0; + self->show_text = 1; + self->text = grub_strdup (""); + self->font = grub_font_get ("Helvetica 10"); + grub_gui_color_t black = { .red = 0, .green = 0, .blue = 0, .alpha = 255 }; + grub_gui_color_t gray = { .red = 128, .green = 128, .blue = 128, .alpha = 255 }; + grub_gui_color_t lightgray = { .red = 200, .green = 200, .blue = 200, .alpha = 255 }; + self->text_color = black; + self->border_color = black; + self->bg_color = gray; + self->fg_color = lightgray; + + self->theme_dir = 0; + self->need_to_recreate_pixmaps = 0; + self->bar_pattern = 0; + self->highlight_pattern = 0; + self->bar_box = 0; + self->highlight_box = 0; + + return (grub_gui_component_t) self; +} diff --git a/gfxmenu/gui_string_util.c b/gfxmenu/gui_string_util.c new file mode 100644 index 000000000..41170d724 --- /dev/null +++ b/gfxmenu/gui_string_util.c @@ -0,0 +1,358 @@ +/* gui_string_util.c - String utilities used by the GUI system. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include + +/* Create a new NUL-terminated string on the heap as a substring of BUF. + The range of buf included is the half-open interval [START,END). + The index START is inclusive, END is exclusive. */ +char * +grub_new_substring (const char *buf, + grub_size_t start, grub_size_t end) +{ + if (end < start) + return 0; + grub_size_t len = end - start; + char *s = grub_malloc (len + 1); + if (! s) + return 0; + grub_memcpy (s, buf + start, len); + s[len] = '\0'; + return s; +} + +/* Eliminate "." and ".." path elements from PATH. A new heap-allocated + string is returned. */ +static char * +canonicalize_path (const char *path) +{ + int i; + const char *p; + char *newpath = 0; + + /* Count the path components in path. */ + int components = 1; + for (p = path; *p; p++) + if (*p == '/') + components++; + + char **path_array = grub_malloc (components * sizeof (*path_array)); + if (! path_array) + return 0; + + /* Initialize array elements to NULL pointers; in case once of the + allocations fails, the cleanup code can just call grub_free() for all + pointers in the array. */ + for (i = 0; i < components; i++) + path_array[i] = 0; + + /* Parse the path into path_array. */ + p = path; + for (i = 0; i < components && p; i++) + { + /* Find the end of the path element. */ + const char *end = grub_strchr (p, '/'); + if (!end) + end = p + grub_strlen (p); + + /* Copy the element. */ + path_array[i] = grub_new_substring (p, 0, end - p); + if (! path_array[i]) + goto cleanup; + + /* Advance p to point to the start of the next element, or NULL. */ + if (*end) + p = end + 1; + else + p = 0; + } + + /* Eliminate '.' and '..' elements from the path array. */ + int newpath_length = 0; + for (i = components - 1; i >= 0; --i) + { + if (! grub_strcmp (path_array[i], ".")) + { + grub_free (path_array[i]); + path_array[i] = 0; + } + else if (! grub_strcmp (path_array[i], "..") + && i > 0) + { + /* Delete the '..' and the prior path element. */ + grub_free (path_array[i]); + path_array[i] = 0; + --i; + grub_free (path_array[i]); + path_array[i] = 0; + } + else + { + newpath_length += grub_strlen (path_array[i]) + 1; + } + } + + /* Construct a new path string. */ + newpath = grub_malloc (newpath_length + 1); + if (! newpath) + goto cleanup; + + newpath[0] = '\0'; + char *newpath_end = newpath; + int first = 1; + for (i = 0; i < components; i++) + { + char *element = path_array[i]; + if (element) + { + /* For all components but the first, prefix with a slash. */ + if (! first) + newpath_end = grub_stpcpy (newpath_end, "/"); + newpath_end = grub_stpcpy (newpath_end, element); + first = 0; + } + } + +cleanup: + for (i = 0; i < components; i++) + grub_free (path_array[i]); + grub_free (path_array); + + return newpath; +} + +/* Return a new heap-allocated string representing to absolute path + to the file referred to by PATH. If PATH is an absolute path, then + the returned path is a copy of PATH. If PATH is a relative path, then + BASE is with PATH used to construct the absolute path. */ +char * +grub_resolve_relative_path (const char *base, const char *path) +{ + char *abspath; + char *canonpath; + char *p; + + /* If PATH is an absolute path, then just use it as is. */ + if (path[0] == '/' || path[0] == '(') + return canonicalize_path (path); + + abspath = grub_malloc (grub_strlen (base) + grub_strlen (path) + 1); + if (! abspath) + return 0; + + /* Concatenate BASE and PATH. + Note that BASE is expected to have a trailing slash. */ + p = grub_stpcpy (abspath, base); + grub_stpcpy (p, path); + + canonpath = canonicalize_path (abspath); + if (! canonpath) + return abspath; + + grub_free (abspath); + return canonpath; +} + +/* Get the path of the directory where the file at FILE_PATH is located. + FILE_PATH should refer to a file, not a directory. The returned path + includes a trailing slash. + This does not handle GRUB "(hd0,0)" paths properly yet since it only + looks at slashes. */ +char * +grub_get_dirname (const char *file_path) +{ + int i; + int last_slash; + + last_slash = -1; + for (i = grub_strlen (file_path) - 1; i >= 0; --i) + { + if (file_path[i] == '/') + { + last_slash = i; + break; + } + } + if (last_slash == -1) + return grub_strdup ("/"); + + return grub_new_substring (file_path, 0, last_slash + 1); +} + +static __inline int +isxdigit (char c) +{ + return ((c >= '0' && c <= '9') + || (c >= 'a' && c <= 'f') + || (c >= 'A' && c <= 'F')); +} + +static int +parse_hex_color_component (const char *s, unsigned start, unsigned end) +{ + unsigned len; + char buf[3]; + + len = end - start; + /* Check the limits so we don't overrun the buffer. */ + if (len < 1 || len > 2) + return 0; + + if (len == 1) + { + buf[0] = s[start]; /* Get the first and only hex digit. */ + buf[1] = buf[0]; /* Duplicate the hex digit. */ + } + else if (len == 2) + { + buf[0] = s[start]; + buf[1] = s[start + 1]; + } + + buf[2] = '\0'; + + return grub_strtoul (buf, 0, 16); +} + +/* Parse a color string of the form "r, g, b", "#RGB", "#RGBA", + "#RRGGBB", or "#RRGGBBAA". */ +grub_err_t +grub_gui_parse_color (const char *s, grub_gui_color_t *color) +{ + grub_gui_color_t c; + + /* Skip whitespace. */ + while (*s && grub_isspace (*s)) + s++; + + if (*s == '#') + { + /* HTML-style. Number if hex digits: + [6] #RRGGBB [3] #RGB + [8] #RRGGBBAA [4] #RGBA */ + + s++; /* Skip the '#'. */ + /* Count the hexits to determine the format. */ + int hexits = 0; + const char *end = s; + while (isxdigit (*end)) + { + end++; + hexits++; + } + + /* Parse the color components based on the format. */ + if (hexits == 3 || hexits == 4) + { + c.red = parse_hex_color_component (s, 0, 1); + c.green = parse_hex_color_component (s, 1, 2); + c.blue = parse_hex_color_component (s, 2, 3); + if (hexits == 4) + c.alpha = parse_hex_color_component (s, 3, 4); + else + c.alpha = 255; + } + else if (hexits == 6 || hexits == 8) + { + c.red = parse_hex_color_component (s, 0, 2); + c.green = parse_hex_color_component (s, 2, 4); + c.blue = parse_hex_color_component (s, 4, 6); + if (hexits == 8) + c.alpha = parse_hex_color_component (s, 6, 8); + else + c.alpha = 255; + } + else + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "invalid HTML-type color string `%s'", s); + } + else if (grub_isdigit (*s)) + { + /* Comma separated decimal values. */ + c.red = grub_strtoul (s, 0, 0); + if ((s = grub_strchr (s, ',')) == 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "missing 1st comma separator in color `%s'", s); + s++; + c.green = grub_strtoul (s, 0, 0); + if ((s = grub_strchr (s, ',')) == 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "missing 2nd comma separator in color `%s'", s); + s++; + c.blue = grub_strtoul (s, 0, 0); + if ((s = grub_strchr (s, ',')) == 0) + c.alpha = 255; + else + { + s++; + c.alpha = grub_strtoul (s, 0, 0); + } + } + else + { + if (! grub_gui_get_named_color (s, &c)) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "invalid named color `%s'", s); + } + + if (grub_errno == GRUB_ERR_NONE) + *color = c; + return grub_errno; +} + +/* Parse a value in the form "(x, y)", storing the first element (x) into + *PX and the second element (y) into *PY. + Returns GRUB_ERR_NONE if successfully parsed. */ +grub_err_t +grub_gui_parse_2_tuple (const char *s, int *px, int *py) +{ + int x; + int y; + + while (*s && grub_isspace (*s)) + s++; + if (*s != '(') + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "missing `(' in 2-tuple `%s'", s); + + /* Skip the opening parentheses. */ + s++; + if (*s == 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "unexpected end of 2-tuple after `(' in `%s'", s); + + /* Parse the first element. */ + x = grub_strtol (s, 0, 10); + if ((s = grub_strchr (s, ',')) == 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "missing comma in 2-tuple `%s'", s); + + /* Skip the element separator (the comma). */ + s++; + /* Parse the second element. */ + y = grub_strtol (s, 0, 10); + + *px = x; + *py = y; + + return grub_errno; +} diff --git a/gfxmenu/gui_util.c b/gfxmenu/gui_util.c new file mode 100644 index 000000000..eba7bb39e --- /dev/null +++ b/gfxmenu/gui_util.c @@ -0,0 +1,101 @@ +/* gui_util.c - GUI utility functions. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include + + +struct find_by_id_state +{ + const char *match_id; + grub_gui_component_callback match_callback; + void *match_userdata; +}; + +static void +find_by_id_recursively (grub_gui_component_t component, void *userdata) +{ + struct find_by_id_state *state; + const char *id; + + state = (struct find_by_id_state *) userdata; + id = component->ops->get_id (component); + if (id && grub_strcmp (id, state->match_id) == 0) + state->match_callback (component, state->match_userdata); + + if (component->ops->is_instance (component, "container")) + { + grub_gui_container_t container; + container = (grub_gui_container_t) component; + container->ops->iterate_children (container, + find_by_id_recursively, + state); + } +} + +void +grub_gui_find_by_id (grub_gui_component_t root, + const char *id, + grub_gui_component_callback cb, + void *userdata) +{ + struct find_by_id_state state; + state.match_id = id; + state.match_callback = cb; + state.match_userdata = userdata; + find_by_id_recursively (root, &state); +} + + +struct iterate_recursively_state +{ + grub_gui_component_callback callback; + void *userdata; +}; + +static +void iterate_recursively_cb (grub_gui_component_t component, void *userdata) +{ + struct iterate_recursively_state *state; + + state = (struct iterate_recursively_state *) userdata; + state->callback (component, state->userdata); + + if (component->ops->is_instance (component, "container")) + { + grub_gui_container_t container; + container = (grub_gui_container_t) component; + container->ops->iterate_children (container, + iterate_recursively_cb, + state); + } +} + +void +grub_gui_iterate_recursively (grub_gui_component_t root, + grub_gui_component_callback cb, + void *userdata) +{ + struct iterate_recursively_state state; + state.callback = cb; + state.userdata = userdata; + iterate_recursively_cb (root, &state); +} diff --git a/gfxmenu/icon_manager.c b/gfxmenu/icon_manager.c new file mode 100644 index 000000000..a362882e1 --- /dev/null +++ b/gfxmenu/icon_manager.c @@ -0,0 +1,258 @@ +/* icon_manager.c - gfxmenu icon manager. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Currently hard coded to '.png' extension. */ +static const char icon_extension[] = ".png"; + +typedef struct icon_entry +{ + char *class_name; + struct grub_video_bitmap *bitmap; + struct icon_entry *next; +} *icon_entry_t; + +struct grub_gfxmenu_icon_manager +{ + char *theme_path; + int icon_width; + int icon_height; + + /* Icon cache: linked list w/ dummy head node. */ + struct icon_entry cache; +}; + + +/* Create a new icon manager and return a point to it. */ +grub_gfxmenu_icon_manager_t +grub_gfxmenu_icon_manager_new (void) +{ + grub_gfxmenu_icon_manager_t mgr; + mgr = grub_malloc (sizeof (*mgr)); + if (! mgr) + return 0; + + mgr->theme_path = 0; + mgr->icon_width = 0; + mgr->icon_height = 0; + + /* Initialize the dummy head node. */ + mgr->cache.class_name = 0; + mgr->cache.bitmap = 0; + mgr->cache.next = 0; + + return mgr; +} + +/* Destroy the icon manager MGR, freeing all resources used by it. + +Note: Any bitmaps returned by grub_gfxmenu_icon_manager_get_icon() +are destroyed and must not be used by the caller after this function +is called. */ +void +grub_gfxmenu_icon_manager_destroy (grub_gfxmenu_icon_manager_t mgr) +{ + grub_gfxmenu_icon_manager_clear_cache (mgr); + grub_free (mgr->theme_path); + grub_free (mgr); +} + +/* Clear the icon cache. */ +void +grub_gfxmenu_icon_manager_clear_cache (grub_gfxmenu_icon_manager_t mgr) +{ + icon_entry_t cur; + icon_entry_t next; + for (cur = mgr->cache.next; cur; cur = next) + { + next = cur->next; + grub_free (cur->class_name); + grub_video_bitmap_destroy (cur->bitmap); + grub_free (cur); + } + mgr->cache.next = 0; +} + +/* Set the theme path. If the theme path is changed, the icon cache + is cleared. */ +void +grub_gfxmenu_icon_manager_set_theme_path (grub_gfxmenu_icon_manager_t mgr, + const char *path) +{ + /* Clear the cache if the theme path has changed. */ + if (((mgr->theme_path == 0) != (path == 0)) + || (grub_strcmp (mgr->theme_path, path) != 0)) + grub_gfxmenu_icon_manager_clear_cache (mgr); + + grub_free (mgr->theme_path); + mgr->theme_path = path ? grub_strdup (path) : 0; +} + +/* Set the icon size. When icons are requested from the icon manager, + they are scaled to this size before being returned. If the size is + changed, the icon cache is cleared. */ +void +grub_gfxmenu_icon_manager_set_icon_size (grub_gfxmenu_icon_manager_t mgr, + int width, int height) +{ + /* If the width or height is changed, we must clear the cache, since the + scaled bitmaps are stored in the cache. */ + if (width != mgr->icon_width || height != mgr->icon_height) + grub_gfxmenu_icon_manager_clear_cache (mgr); + + mgr->icon_width = width; + mgr->icon_height = height; +} + +/* Try to load an icon for the specified CLASS_NAME in the directory DIR. + Returns 0 if the icon could not be loaded, or returns a pointer to a new + bitmap if it was successful. */ +static struct grub_video_bitmap * +try_loading_icon (grub_gfxmenu_icon_manager_t mgr, + const char *dir, const char *class_name) +{ + char *path = grub_malloc (grub_strlen (dir) + + grub_strlen (class_name) + + grub_strlen (icon_extension) + + 1); + if (! path) + return 0; + + grub_strcpy (path, dir); + grub_strcat (path, class_name); + grub_strcat (path, icon_extension); + + struct grub_video_bitmap *raw_bitmap; + grub_video_bitmap_load (&raw_bitmap, path); + grub_free (path); + grub_errno = GRUB_ERR_NONE; /* Critical to clear the error!! */ + if (! raw_bitmap) + return 0; + + struct grub_video_bitmap *scaled_bitmap; + grub_video_bitmap_create_scaled (&scaled_bitmap, + mgr->icon_width, mgr->icon_height, + raw_bitmap, + GRUB_VIDEO_BITMAP_SCALE_METHOD_BEST); + grub_video_bitmap_destroy (raw_bitmap); + if (! scaled_bitmap) + { + grub_error_push (); + grub_error (grub_errno, "failed to scale icon"); + return 0; + } + + return scaled_bitmap; +} + +/* Get the icon for the specified class CLASS_NAME. If an icon for + CLASS_NAME already exists in the cache, then a reference to the cached + bitmap is returned. If it is not cached, then it is loaded and cached. + If no icon could be could for CLASS_NAME, then 0 is returned. */ +static struct grub_video_bitmap * +get_icon_by_class (grub_gfxmenu_icon_manager_t mgr, const char *class_name) +{ + /* First check the icon cache. */ + icon_entry_t entry; + for (entry = mgr->cache.next; entry; entry = entry->next) + { + if (grub_strcmp (entry->class_name, class_name) == 0) + return entry->bitmap; + } + + if (! mgr->theme_path) + return 0; + + /* Otherwise, we search for an icon to load. */ + char *theme_dir = grub_get_dirname (mgr->theme_path); + char *icons_dir; + struct grub_video_bitmap *icon; + icon = 0; + /* First try the theme's own icons, from "grub/themes/NAME/icons/" */ + icons_dir = grub_resolve_relative_path (theme_dir, "icons/"); + if (icons_dir) + { + icon = try_loading_icon (mgr, icons_dir, class_name); + grub_free (icons_dir); + } + if (! icon) + { + /* If the theme doesn't have an appropriate icon, check in + "grub/themes/icons". */ + /* TODO use GRUB prefix "/icons" */ + icons_dir = grub_resolve_relative_path (theme_dir, "../icons/"); + if (icons_dir) + { + icon = try_loading_icon (mgr, icons_dir, class_name); + grub_free (icons_dir); + } + } + grub_free (theme_dir); + + /* No icon was found. */ + /* This should probably be noted in the cache, so that a search is not + performed each time an icon for CLASS_NAME is requested. */ + if (! icon) + return 0; + + /* Insert a new cache entry for this icon. */ + entry = grub_malloc (sizeof (*entry)); + if (! entry) + { + grub_video_bitmap_destroy (icon); + return 0; + } + entry->class_name = grub_strdup (class_name); + entry->bitmap = icon; + entry->next = mgr->cache.next; + mgr->cache.next = entry; /* Link it into the cache. */ + return entry->bitmap; +} + +/* Get the best available icon for ENTRY. Beginning with the first class + listed in the menu entry and proceeding forward, an icon for each class + is searched for. The first icon found is returned. The returned icon + is scaled to the size specified by + grub_gfxmenu_icon_manager_set_icon_size(). + + Note: Bitmaps returned by this function are destroyed when the + icon manager is destroyed. + */ +struct grub_video_bitmap * +grub_gfxmenu_icon_manager_get_icon (grub_gfxmenu_icon_manager_t mgr, + grub_menu_entry_t entry) +{ + struct grub_menu_entry_class *c; + struct grub_video_bitmap *icon; + + /* Try each class in succession. */ + icon = 0; + for (c = entry->classes->next; c && ! icon; c = c->next) + icon = get_icon_by_class (mgr, c->name); + return icon; +} diff --git a/gfxmenu/model.c b/gfxmenu/model.c new file mode 100644 index 000000000..26490ea1f --- /dev/null +++ b/gfxmenu/model.c @@ -0,0 +1,191 @@ +/* model.c - Graphical menu interface MVC model. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* Model type definition. */ +struct grub_gfxmenu_model +{ + grub_menu_t menu; + int num_entries; + grub_menu_entry_t *entries; + int selected_entry_index; + int timeout_set; + grub_uint64_t timeout_start; + grub_uint64_t timeout_at; +}; + + +grub_gfxmenu_model_t +grub_gfxmenu_model_new (grub_menu_t menu) +{ + grub_gfxmenu_model_t model; + + model = grub_malloc (sizeof (*model)); + if (! model) + return 0; + + model->menu = menu; + model->num_entries = menu->size; + model->entries = 0; + model->selected_entry_index = 0; + model->timeout_set = 0; + model->timeout_at = 0; + if (model->num_entries > 0) + { + model->entries = grub_malloc (model->num_entries + * sizeof (*model->entries)); + if (! model->entries) + goto fail_and_free; + + int i; + grub_menu_entry_t cur; + for (i = 0, cur = menu->entry_list; + i < model->num_entries; + i++, cur = cur->next) + { + model->entries[i] = cur; + } + } + + return model; + +fail_and_free: + grub_free (model->entries); + grub_free (model); + return 0; +} + +void +grub_gfxmenu_model_destroy (grub_gfxmenu_model_t model) +{ + if (! model) + return; + + grub_free (model->entries); + model->entries = 0; + + grub_free (model); +} + +grub_menu_t +grub_gfxmenu_model_get_menu (grub_gfxmenu_model_t model) +{ + return model->menu; +} + +void +grub_gfxmenu_model_set_timeout (grub_gfxmenu_model_t model) +{ + int timeout_sec = grub_menu_get_timeout (); + if (timeout_sec >= 0) + { + model->timeout_start = grub_get_time_ms (); + model->timeout_at = model->timeout_start + timeout_sec * 1000; + model->timeout_set = 1; + } + else + { + model->timeout_set = 0; + } +} + +void +grub_gfxmenu_model_clear_timeout (grub_gfxmenu_model_t model) +{ + model->timeout_set = 0; + grub_menu_set_timeout (-1); +} + +int +grub_gfxmenu_model_get_timeout_ms (grub_gfxmenu_model_t model) +{ + if (!model->timeout_set) + return -1; + + return model->timeout_at - model->timeout_start; +} + +int +grub_gfxmenu_model_get_timeout_remaining_ms (grub_gfxmenu_model_t model) +{ + if (!model->timeout_set) + return -1; + + return model->timeout_at - grub_get_time_ms (); +} + +int +grub_gfxmenu_model_timeout_expired (grub_gfxmenu_model_t model) +{ + if (model->timeout_set + && grub_get_time_ms () >= model->timeout_at) + return 1; + + return 0; +} + +int +grub_gfxmenu_model_get_num_entries (grub_gfxmenu_model_t model) +{ + return model->num_entries; +} + +int +grub_gfxmenu_model_get_selected_index (grub_gfxmenu_model_t model) +{ + return model->selected_entry_index; +} + +void +grub_gfxmenu_model_set_selected_index (grub_gfxmenu_model_t model, int index) +{ + model->selected_entry_index = index; +} + +const char * +grub_gfxmenu_model_get_entry_title (grub_gfxmenu_model_t model, int index) +{ + if (index < 0 || index >= model->num_entries) + { + grub_error (GRUB_ERR_OUT_OF_RANGE, "invalid menu index"); + return 0; + } + + return model->entries[index]->title; +} + +grub_menu_entry_t +grub_gfxmenu_model_get_entry (grub_gfxmenu_model_t model, int index) +{ + if (index < 0 || index >= model->num_entries) + { + grub_error (GRUB_ERR_OUT_OF_RANGE, "invalid menu index"); + return 0; + } + + return model->entries[index]; +} diff --git a/gfxmenu/named_colors.c b/gfxmenu/named_colors.c new file mode 100644 index 000000000..eedbc47fb --- /dev/null +++ b/gfxmenu/named_colors.c @@ -0,0 +1,209 @@ +/* named_colors.c - Named color values. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include + +struct named_color +{ + const char *name; + grub_gui_color_t color; +}; + +/* + Named color list generated from the list of SVG color keywords from + , + processed through the following Perl command: + perl -ne 'chomp;split;print "{ \"$_[0]\", RGB_COLOR($_[2]) },\n"' + */ + +#define RGB_COLOR(r,g,b) {.red = r, .green = g, .blue = b, .alpha = 255} + +static struct named_color named_colors[] = +{ + { "aliceblue", RGB_COLOR(240,248,255) }, + { "antiquewhite", RGB_COLOR(250,235,215) }, + { "aqua", RGB_COLOR(0,255,255) }, + { "aquamarine", RGB_COLOR(127,255,212) }, + { "azure", RGB_COLOR(240,255,255) }, + { "beige", RGB_COLOR(245,245,220) }, + { "bisque", RGB_COLOR(255,228,196) }, + { "black", RGB_COLOR(0,0,0) }, + { "blanchedalmond", RGB_COLOR(255,235,205) }, + { "blue", RGB_COLOR(0,0,255) }, + { "blueviolet", RGB_COLOR(138,43,226) }, + { "brown", RGB_COLOR(165,42,42) }, + { "burlywood", RGB_COLOR(222,184,135) }, + { "cadetblue", RGB_COLOR(95,158,160) }, + { "chartreuse", RGB_COLOR(127,255,0) }, + { "chocolate", RGB_COLOR(210,105,30) }, + { "coral", RGB_COLOR(255,127,80) }, + { "cornflowerblue", RGB_COLOR(100,149,237) }, + { "cornsilk", RGB_COLOR(255,248,220) }, + { "crimson", RGB_COLOR(220,20,60) }, + { "cyan", RGB_COLOR(0,255,255) }, + { "darkblue", RGB_COLOR(0,0,139) }, + { "darkcyan", RGB_COLOR(0,139,139) }, + { "darkgoldenrod", RGB_COLOR(184,134,11) }, + { "darkgray", RGB_COLOR(169,169,169) }, + { "darkgreen", RGB_COLOR(0,100,0) }, + { "darkgrey", RGB_COLOR(169,169,169) }, + { "darkkhaki", RGB_COLOR(189,183,107) }, + { "darkmagenta", RGB_COLOR(139,0,139) }, + { "darkolivegreen", RGB_COLOR(85,107,47) }, + { "darkorange", RGB_COLOR(255,140,0) }, + { "darkorchid", RGB_COLOR(153,50,204) }, + { "darkred", RGB_COLOR(139,0,0) }, + { "darksalmon", RGB_COLOR(233,150,122) }, + { "darkseagreen", RGB_COLOR(143,188,143) }, + { "darkslateblue", RGB_COLOR(72,61,139) }, + { "darkslategray", RGB_COLOR(47,79,79) }, + { "darkslategrey", RGB_COLOR(47,79,79) }, + { "darkturquoise", RGB_COLOR(0,206,209) }, + { "darkviolet", RGB_COLOR(148,0,211) }, + { "deeppink", RGB_COLOR(255,20,147) }, + { "deepskyblue", RGB_COLOR(0,191,255) }, + { "dimgray", RGB_COLOR(105,105,105) }, + { "dimgrey", RGB_COLOR(105,105,105) }, + { "dodgerblue", RGB_COLOR(30,144,255) }, + { "firebrick", RGB_COLOR(178,34,34) }, + { "floralwhite", RGB_COLOR(255,250,240) }, + { "forestgreen", RGB_COLOR(34,139,34) }, + { "fuchsia", RGB_COLOR(255,0,255) }, + { "gainsboro", RGB_COLOR(220,220,220) }, + { "ghostwhite", RGB_COLOR(248,248,255) }, + { "gold", RGB_COLOR(255,215,0) }, + { "goldenrod", RGB_COLOR(218,165,32) }, + { "gray", RGB_COLOR(128,128,128) }, + { "green", RGB_COLOR(0,128,0) }, + { "greenyellow", RGB_COLOR(173,255,47) }, + { "grey", RGB_COLOR(128,128,128) }, + { "honeydew", RGB_COLOR(240,255,240) }, + { "hotpink", RGB_COLOR(255,105,180) }, + { "indianred", RGB_COLOR(205,92,92) }, + { "indigo", RGB_COLOR(75,0,130) }, + { "ivory", RGB_COLOR(255,255,240) }, + { "khaki", RGB_COLOR(240,230,140) }, + { "lavender", RGB_COLOR(230,230,250) }, + { "lavenderblush", RGB_COLOR(255,240,245) }, + { "lawngreen", RGB_COLOR(124,252,0) }, + { "lemonchiffon", RGB_COLOR(255,250,205) }, + { "lightblue", RGB_COLOR(173,216,230) }, + { "lightcoral", RGB_COLOR(240,128,128) }, + { "lightcyan", RGB_COLOR(224,255,255) }, + { "lightgoldenrodyellow", RGB_COLOR(250,250,210) }, + { "lightgray", RGB_COLOR(211,211,211) }, + { "lightgreen", RGB_COLOR(144,238,144) }, + { "lightgrey", RGB_COLOR(211,211,211) }, + { "lightpink", RGB_COLOR(255,182,193) }, + { "lightsalmon", RGB_COLOR(255,160,122) }, + { "lightseagreen", RGB_COLOR(32,178,170) }, + { "lightskyblue", RGB_COLOR(135,206,250) }, + { "lightslategray", RGB_COLOR(119,136,153) }, + { "lightslategrey", RGB_COLOR(119,136,153) }, + { "lightsteelblue", RGB_COLOR(176,196,222) }, + { "lightyellow", RGB_COLOR(255,255,224) }, + { "lime", RGB_COLOR(0,255,0) }, + { "limegreen", RGB_COLOR(50,205,50) }, + { "linen", RGB_COLOR(250,240,230) }, + { "magenta", RGB_COLOR(255,0,255) }, + { "maroon", RGB_COLOR(128,0,0) }, + { "mediumaquamarine", RGB_COLOR(102,205,170) }, + { "mediumblue", RGB_COLOR(0,0,205) }, + { "mediumorchid", RGB_COLOR(186,85,211) }, + { "mediumpurple", RGB_COLOR(147,112,219) }, + { "mediumseagreen", RGB_COLOR(60,179,113) }, + { "mediumslateblue", RGB_COLOR(123,104,238) }, + { "mediumspringgreen", RGB_COLOR(0,250,154) }, + { "mediumturquoise", RGB_COLOR(72,209,204) }, + { "mediumvioletred", RGB_COLOR(199,21,133) }, + { "midnightblue", RGB_COLOR(25,25,112) }, + { "mintcream", RGB_COLOR(245,255,250) }, + { "mistyrose", RGB_COLOR(255,228,225) }, + { "moccasin", RGB_COLOR(255,228,181) }, + { "navajowhite", RGB_COLOR(255,222,173) }, + { "navy", RGB_COLOR(0,0,128) }, + { "oldlace", RGB_COLOR(253,245,230) }, + { "olive", RGB_COLOR(128,128,0) }, + { "olivedrab", RGB_COLOR(107,142,35) }, + { "orange", RGB_COLOR(255,165,0) }, + { "orangered", RGB_COLOR(255,69,0) }, + { "orchid", RGB_COLOR(218,112,214) }, + { "palegoldenrod", RGB_COLOR(238,232,170) }, + { "palegreen", RGB_COLOR(152,251,152) }, + { "paleturquoise", RGB_COLOR(175,238,238) }, + { "palevioletred", RGB_COLOR(219,112,147) }, + { "papayawhip", RGB_COLOR(255,239,213) }, + { "peachpuff", RGB_COLOR(255,218,185) }, + { "peru", RGB_COLOR(205,133,63) }, + { "pink", RGB_COLOR(255,192,203) }, + { "plum", RGB_COLOR(221,160,221) }, + { "powderblue", RGB_COLOR(176,224,230) }, + { "purple", RGB_COLOR(128,0,128) }, + { "red", RGB_COLOR(255,0,0) }, + { "rosybrown", RGB_COLOR(188,143,143) }, + { "royalblue", RGB_COLOR(65,105,225) }, + { "saddlebrown", RGB_COLOR(139,69,19) }, + { "salmon", RGB_COLOR(250,128,114) }, + { "sandybrown", RGB_COLOR(244,164,96) }, + { "seagreen", RGB_COLOR(46,139,87) }, + { "seashell", RGB_COLOR(255,245,238) }, + { "sienna", RGB_COLOR(160,82,45) }, + { "silver", RGB_COLOR(192,192,192) }, + { "skyblue", RGB_COLOR(135,206,235) }, + { "slateblue", RGB_COLOR(106,90,205) }, + { "slategray", RGB_COLOR(112,128,144) }, + { "slategrey", RGB_COLOR(112,128,144) }, + { "snow", RGB_COLOR(255,250,250) }, + { "springgreen", RGB_COLOR(0,255,127) }, + { "steelblue", RGB_COLOR(70,130,180) }, + { "tan", RGB_COLOR(210,180,140) }, + { "teal", RGB_COLOR(0,128,128) }, + { "thistle", RGB_COLOR(216,191,216) }, + { "tomato", RGB_COLOR(255,99,71) }, + { "turquoise", RGB_COLOR(64,224,208) }, + { "violet", RGB_COLOR(238,130,238) }, + { "wheat", RGB_COLOR(245,222,179) }, + { "white", RGB_COLOR(255,255,255) }, + { "whitesmoke", RGB_COLOR(245,245,245) }, + { "yellow", RGB_COLOR(255,255,0) }, + { "yellowgreen", RGB_COLOR(154,205,50) }, + { 0, { 0, 0, 0, 0 } } /* Terminator. */ +}; + +/* Get the color named NAME. If the color was found, returns 1 and + stores the color into *COLOR. If the color was not found, returns 0 and + does not modify *COLOR. */ +int +grub_gui_get_named_color (const char *name, + grub_gui_color_t *color) +{ + int i; + for (i = 0; named_colors[i].name; i++) + { + if (grub_strcmp (named_colors[i].name, name) == 0) + { + *color = named_colors[i].color; + return 1; + } + } + return 0; +} diff --git a/gfxmenu/theme_loader.c b/gfxmenu/theme_loader.c new file mode 100644 index 000000000..3512c7bf1 --- /dev/null +++ b/gfxmenu/theme_loader.c @@ -0,0 +1,720 @@ +/* theme_loader.c - Theme file loader for gfxmenu. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Construct a new box widget using ABSPATTERN to find the pixmap files for + it, storing the new box instance at *BOXPTR. + PATTERN should be of the form: "(hd0,0)/somewhere/style*.png". + The '*' then gets substituted with the various pixmap names that the + box uses. */ +static grub_err_t +recreate_box_absolute (grub_gfxmenu_box_t *boxptr, const char *abspattern) +{ + char *prefix; + char *suffix; + char *star; + grub_gfxmenu_box_t box; + + star = grub_strchr (abspattern, '*'); + if (! star) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "missing `*' in box pixmap pattern `%s'", abspattern); + + /* Prefix: Get the part before the '*'. */ + prefix = grub_malloc (star - abspattern + 1); + if (! prefix) + return grub_errno; + + grub_memcpy (prefix, abspattern, star - abspattern); + prefix[star - abspattern] = '\0'; + + /* Suffix: Everything after the '*' is the suffix. */ + suffix = star + 1; + + box = grub_gfxmenu_create_box (prefix, suffix); + grub_free (prefix); + if (! box) + return grub_errno; + + if (*boxptr) + (*boxptr)->destroy (*boxptr); + *boxptr = box; + return grub_errno; +} + + +/* Construct a new box widget using PATTERN to find the pixmap files for it, + storing the new widget at *BOXPTR. PATTERN should be of the form: + "somewhere/style*.png". The '*' then gets substituted with the various + pixmap names that the widget uses. + + Important! The value of *BOXPTR must be initialized! It must either + (1) Be 0 (a NULL pointer), or + (2) Be a pointer to a valid 'grub_gfxmenu_box_t' instance. + In this case, the previous instance is destroyed. */ +grub_err_t +grub_gui_recreate_box (grub_gfxmenu_box_t *boxptr, + const char *pattern, const char *theme_dir) +{ + char *abspattern; + + /* Check arguments. */ + if (! pattern) + { + /* If no pixmap pattern is given, then just create an empty box. */ + if (*boxptr) + (*boxptr)->destroy (*boxptr); + *boxptr = grub_gfxmenu_create_box (0, 0); + return grub_errno; + } + + if (! theme_dir) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "styled box missing theme directory"); + + /* Resolve to an absolute path. */ + abspattern = grub_resolve_relative_path (theme_dir, pattern); + if (! abspattern) + return grub_errno; + + /* Create the box. */ + recreate_box_absolute (boxptr, abspattern); + grub_free (abspattern); + return grub_errno; +} + +/* Set the specified property NAME on the view to the given string VALUE. + The caller is responsible for the lifetimes of NAME and VALUE. */ +static grub_err_t +theme_set_string (grub_gfxmenu_view_t view, + const char *name, + const char *value, + const char *theme_dir, + const char *filename, + int line_num, + int col_num) +{ + if (! grub_strcmp ("title-font", name)) + view->title_font = grub_font_get (value); + else if (! grub_strcmp ("message-font", name)) + view->message_font = grub_font_get (value); + else if (! grub_strcmp ("terminal-font", name)) + { + grub_free (view->terminal_font_name); + view->terminal_font_name = grub_strdup (value); + if (! view->terminal_font_name) + return grub_errno; + } + else if (! grub_strcmp ("title-color", name)) + grub_gui_parse_color (value, &view->title_color); + else if (! grub_strcmp ("message-color", name)) + grub_gui_parse_color (value, &view->message_color); + else if (! grub_strcmp ("message-bg-color", name)) + grub_gui_parse_color (value, &view->message_bg_color); + else if (! grub_strcmp ("desktop-image", name)) + { + struct grub_video_bitmap *raw_bitmap; + struct grub_video_bitmap *scaled_bitmap; + char *path; + path = grub_resolve_relative_path (theme_dir, value); + if (! path) + return grub_errno; + if (grub_video_bitmap_load (&raw_bitmap, path) != GRUB_ERR_NONE) + { + grub_free (path); + return grub_errno; + } + grub_free(path); + grub_video_bitmap_create_scaled (&scaled_bitmap, + view->screen.width, + view->screen.height, + raw_bitmap, + GRUB_VIDEO_BITMAP_SCALE_METHOD_BEST); + grub_video_bitmap_destroy (raw_bitmap); + if (! scaled_bitmap) + { + grub_error_push (); + return grub_error (grub_errno, "error scaling desktop image"); + } + + grub_video_bitmap_destroy (view->desktop_image); + view->desktop_image = scaled_bitmap; + } + else if (! grub_strcmp ("desktop-color", name)) + grub_gui_parse_color (value, &view->desktop_color); + else if (! grub_strcmp ("terminal-box", name)) + { + grub_err_t err; + err = grub_gui_recreate_box (&view->terminal_box, value, theme_dir); + if (err != GRUB_ERR_NONE) + return err; + } + else if (! grub_strcmp ("title-text", name)) + { + grub_free (view->title_text); + view->title_text = grub_strdup (value); + if (! view->title_text) + return grub_errno; + } + else + { + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "%s:%d:%d unknown property `%s'", + filename, line_num, col_num, name); + } + return grub_errno; +} + +struct parsebuf +{ + char *buf; + int pos; + int len; + int line_num; + int col_num; + const char *filename; + char *theme_dir; + grub_gfxmenu_view_t view; +}; + +static int +has_more (struct parsebuf *p) +{ + return p->pos < p->len; +} + +static int +read_char (struct parsebuf *p) +{ + if (has_more (p)) + { + char c; + c = p->buf[p->pos++]; + if (c == '\n') + { + p->line_num++; + p->col_num = 1; + } + else + { + p->col_num++; + } + return c; + } + else + return -1; +} + +static int +peek_char (struct parsebuf *p) +{ + if (has_more (p)) + return p->buf[p->pos]; + else + return -1; +} + +static int +is_whitespace (char c) +{ + return (c == ' ' + || c == '\t' + || c == '\r' + || c == '\n' + || c == '\f'); +} + +static void +skip_whitespace (struct parsebuf *p) +{ + while (has_more (p) && is_whitespace(peek_char (p))) + read_char (p); +} + +static void +advance_to_next_line (struct parsebuf *p) +{ + int c; + + /* Eat characters up to the newline. */ + do + { + c = read_char (p); + } + while (c != -1 && c != '\n'); +} + +static int +is_identifier_char (int c) +{ + return (c != -1 + && (grub_isalpha(c) + || grub_isdigit(c) + || c == '_' + || c == '-')); +} + +static char * +read_identifier (struct parsebuf *p) +{ + /* Index of the first character of the identifier in p->buf. */ + int start; + /* Next index after the last character of the identifer in p->buf. */ + int end; + + skip_whitespace (p); + + /* Capture the start of the identifier. */ + start = p->pos; + + /* Scan for the end. */ + while (is_identifier_char (peek_char (p))) + read_char (p); + end = p->pos; + + if (end - start < 1) + return 0; + + return grub_new_substring (p->buf, start, end); +} + +static char * +read_expression (struct parsebuf *p) +{ + int start; + int end; + + skip_whitespace (p); + if (peek_char (p) == '"') + { + /* Read as a quoted string. + The quotation marks are not included in the expression value. */ + /* Skip opening quotation mark. */ + read_char (p); + start = p->pos; + while (has_more (p) && peek_char (p) != '"') + read_char (p); + end = p->pos; + /* Skip the terminating quotation mark. */ + read_char (p); + } + else if (peek_char (p) == '(') + { + /* Read as a parenthesized string -- for tuples/coordinates. */ + /* The parentheses are included in the expression value. */ + int c; + + start = p->pos; + do + { + c = read_char (p); + } + while (c != -1 && c != ')'); + end = p->pos; + } + else if (has_more (p)) + { + /* Read as a single word -- for numeric values or words without + whitespace. */ + start = p->pos; + while (has_more (p) && ! is_whitespace (peek_char (p))) + read_char (p); + end = p->pos; + } + else + { + /* The end of the theme file has been reached. */ + grub_error (GRUB_ERR_IO, "%s:%d:%d expression expected in theme file", + p->filename, p->line_num, p->col_num); + return 0; + } + + return grub_new_substring (p->buf, start, end); +} + +/* Read a GUI object specification from the theme file. + Any components created will be added to the GUI container PARENT. */ +static grub_err_t +read_object (struct parsebuf *p, grub_gui_container_t parent) +{ + grub_video_rect_t bounds; + + char *name; + name = read_identifier (p); + if (! name) + goto cleanup; + + grub_gui_component_t component = 0; + if (grub_strcmp (name, "label") == 0) + { + component = grub_gui_label_new (); + } + else if (grub_strcmp (name, "image") == 0) + { + component = grub_gui_image_new (); + } + else if (grub_strcmp (name, "vbox") == 0) + { + component = (grub_gui_component_t) grub_gui_vbox_new (); + } + else if (grub_strcmp (name, "hbox") == 0) + { + component = (grub_gui_component_t) grub_gui_hbox_new (); + } + else if (grub_strcmp (name, "canvas") == 0) + { + component = (grub_gui_component_t) grub_gui_canvas_new (); + } + else if (grub_strcmp (name, "progress_bar") == 0) + { + component = grub_gui_progress_bar_new (); + } + else if (grub_strcmp (name, "circular_progress") == 0) + { + component = grub_gui_circular_progress_new (); + } + else if (grub_strcmp (name, "boot_menu") == 0) + { + component = grub_gui_list_new (); + } + else + { + /* Unknown type. */ + grub_error (GRUB_ERR_IO, "%s:%d:%d unknown object type `%s'", + p->filename, p->line_num, p->col_num, name); + goto cleanup; + } + + if (! component) + goto cleanup; + + /* Inform the component about the theme so it can find its resources. */ + component->ops->set_property (component, "theme_dir", p->theme_dir); + component->ops->set_property (component, "theme_path", p->filename); + + /* Add the component as a child of PARENT. */ + bounds.x = 0; + bounds.y = 0; + bounds.width = -1; + bounds.height = -1; + component->ops->set_bounds (component, &bounds); + parent->ops->add (parent, component); + + skip_whitespace (p); + if (read_char (p) != '{') + { + grub_error (GRUB_ERR_IO, + "%s:%d:%d expected `{' after object type name `%s'", + p->filename, p->line_num, p->col_num, name); + goto cleanup; + } + + while (has_more (p)) + { + skip_whitespace (p); + + /* Check whether the end has been encountered. */ + if (peek_char (p) == '}') + { + /* Skip the closing brace. */ + read_char (p); + break; + } + + if (peek_char (p) == '#') + { + /* Skip comments. */ + advance_to_next_line (p); + continue; + } + + if (peek_char (p) == '+') + { + /* Skip the '+'. */ + read_char (p); + + /* Check whether this component is a container. */ + if (component->ops->is_instance (component, "container")) + { + /* Read the sub-object recursively and add it as a child. */ + if (read_object (p, (grub_gui_container_t) component) != 0) + goto cleanup; + /* After reading the sub-object, resume parsing, expecting + another property assignment or sub-object definition. */ + continue; + } + else + { + grub_error (GRUB_ERR_IO, + "%s:%d:%d attempted to add object to non-container", + p->filename, p->line_num, p->col_num); + goto cleanup; + } + } + + char *property; + property = read_identifier (p); + if (! property) + { + grub_error (GRUB_ERR_IO, "%s:%d:%d identifier expected in theme file", + p->filename, p->line_num, p->col_num); + goto cleanup; + } + + skip_whitespace (p); + if (read_char (p) != '=') + { + grub_error (GRUB_ERR_IO, + "%s:%d:%d expected `=' after property name `%s'", + p->filename, p->line_num, p->col_num, property); + grub_free (property); + goto cleanup; + } + skip_whitespace (p); + + char *value; + value = read_expression (p); + if (! value) + { + grub_free (property); + goto cleanup; + } + + /* Handle the property value. */ + if (grub_strcmp (property, "position") == 0) + { + /* Special case for position value. */ + int x; + int y; + + if (grub_gui_parse_2_tuple (value, &x, &y) == GRUB_ERR_NONE) + { + grub_video_rect_t r; + component->ops->get_bounds (component, &r); + r.x = x; + r.y = y; + component->ops->set_bounds (component, &r); + } + } + else if (grub_strcmp (property, "size") == 0) + { + /* Special case for size value. */ + int w; + int h; + + if (grub_gui_parse_2_tuple (value, &w, &h) == GRUB_ERR_NONE) + { + grub_video_rect_t r; + component->ops->get_bounds (component, &r); + r.width = w; + r.height = h; + component->ops->set_bounds (component, &r); + } + } + else + { + /* General property handling. */ + component->ops->set_property (component, property, value); + } + + grub_free (value); + grub_free (property); + if (grub_errno != GRUB_ERR_NONE) + goto cleanup; + } + + /* Set the object's size to its preferred size unless the user has + explicitly specified the size. */ + component->ops->get_bounds (component, &bounds); + if (bounds.width == -1 || bounds.height == -1) + { + component->ops->get_preferred_size (component, + &bounds.width, &bounds.height); + component->ops->set_bounds (component, &bounds); + } + +cleanup: + grub_free (name); + return grub_errno; +} + +static grub_err_t +read_property (struct parsebuf *p) +{ + char *name; + + /* Read the property name. */ + name = read_identifier (p); + if (! name) + { + advance_to_next_line (p); + return grub_errno; + } + + /* Skip whitespace before separator. */ + skip_whitespace (p); + + /* Read separator. */ + if (read_char (p) != ':') + { + grub_error (GRUB_ERR_IO, + "%s:%d:%d missing separator after property name `%s'", + p->filename, p->line_num, p->col_num, name); + goto done; + } + + /* Skip whitespace after separator. */ + skip_whitespace (p); + + /* Get the value based on its type. */ + if (peek_char (p) == '"') + { + /* String value (e.g., '"My string"'). */ + char *value = read_expression (p); + if (! value) + { + grub_error (GRUB_ERR_IO, "%s:%d:%d missing property value", + p->filename, p->line_num, p->col_num); + goto done; + } + /* If theme_set_string results in an error, grub_errno will be returned + below. */ + theme_set_string (p->view, name, value, p->theme_dir, + p->filename, p->line_num, p->col_num); + grub_free (value); + } + else + { + grub_error (GRUB_ERR_IO, + "%s:%d:%d property value invalid; " + "enclose literal values in quotes (\")", + p->filename, p->line_num, p->col_num); + goto done; + } + +done: + grub_free (name); + return grub_errno; +} + +/* Set properties on the view based on settings from the specified + theme file. */ +grub_err_t +grub_gfxmenu_view_load_theme (grub_gfxmenu_view_t view, const char *theme_path) +{ + grub_file_t file; + struct parsebuf p; + + p.view = view; + p.theme_dir = grub_get_dirname (theme_path); + + file = grub_file_open (theme_path); + if (! file) + { + grub_free (p.theme_dir); + return grub_errno; + } + + p.len = grub_file_size (file); + p.buf = grub_malloc (p.len); + p.pos = 0; + p.line_num = 1; + p.col_num = 1; + p.filename = theme_path; + if (! p.buf) + { + grub_file_close (file); + grub_free (p.theme_dir); + return grub_errno; + } + if (grub_file_read (file, p.buf, p.len) != p.len) + { + grub_free (p.buf); + grub_file_close (file); + grub_free (p.theme_dir); + return grub_errno; + } + + if (view->canvas) + view->canvas->ops->component.destroy (view->canvas); + + view->canvas = grub_gui_canvas_new (); + ((grub_gui_component_t) view->canvas) + ->ops->set_bounds ((grub_gui_component_t) view->canvas, + &view->screen); + + while (has_more (&p)) + { + /* Skip comments (lines beginning with #). */ + if (peek_char (&p) == '#') + { + advance_to_next_line (&p); + continue; + } + + /* Find the first non-whitespace character. */ + skip_whitespace (&p); + + /* Handle the content. */ + if (peek_char (&p) == '+') + { + /* Skip the '+'. */ + read_char (&p); + read_object (&p, view->canvas); + } + else + { + read_property (&p); + } + + if (grub_errno != GRUB_ERR_NONE) + goto fail; + } + + /* Set the new theme path. */ + grub_free (view->theme_path); + view->theme_path = grub_strdup (theme_path); + goto cleanup; + +fail: + if (view->canvas) + { + view->canvas->ops->component.destroy (view->canvas); + view->canvas = 0; + } + +cleanup: + grub_free (p.buf); + grub_file_close (file); + grub_free (p.theme_dir); + return grub_errno; +} diff --git a/gfxmenu/view.c b/gfxmenu/view.c new file mode 100644 index 000000000..56edc86cf --- /dev/null +++ b/gfxmenu/view.c @@ -0,0 +1,497 @@ +/* view.c - Graphical menu interface MVC view. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* The component ID identifying GUI components to be updated as the timeout + status changes. */ +#define TIMEOUT_COMPONENT_ID "__timeout__" + +static void init_terminal (grub_gfxmenu_view_t view); +static void destroy_terminal (void); +static grub_err_t set_graphics_mode (void); +static grub_err_t set_text_mode (void); + +/* Create a new view object, loading the theme specified by THEME_PATH and + associating MODEL with the view. */ +grub_gfxmenu_view_t +grub_gfxmenu_view_new (const char *theme_path, grub_gfxmenu_model_t model) +{ + grub_gfxmenu_view_t view; + + view = grub_malloc (sizeof (*view)); + if (! view) + return 0; + + set_graphics_mode (); + grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY); + grub_video_get_viewport ((unsigned *) &view->screen.x, + (unsigned *) &view->screen.y, + (unsigned *) &view->screen.width, + (unsigned *) &view->screen.height); + + /* Clear the screen; there may be garbage left over in video memory, and + loading the menu style (particularly the background) can take a while. */ + grub_video_fill_rect (grub_video_map_rgb (0, 0, 0), + view->screen.x, view->screen.y, + view->screen.width, view->screen.height); + grub_video_swap_buffers (); + + grub_font_t default_font; + grub_gui_color_t default_fg_color; + grub_gui_color_t default_bg_color; + + default_font = grub_font_get ("Helvetica 12"); + default_fg_color = grub_gui_color_rgb (0, 0, 0); + default_bg_color = grub_gui_color_rgb (255, 255, 255); + + view->model = model; + view->canvas = 0; + + view->title_font = default_font; + view->message_font = default_font; + view->terminal_font_name = grub_strdup ("Fixed 10"); + view->title_color = default_fg_color; + view->message_color = default_bg_color; + view->message_bg_color = default_fg_color; + view->desktop_image = 0; + view->desktop_color = default_bg_color; + view->terminal_box = grub_gfxmenu_create_box (0, 0); + view->title_text = grub_strdup ("GRUB Boot Menu"); + view->progress_message_text = 0; + view->theme_path = 0; + + if (grub_gfxmenu_view_load_theme (view, theme_path) != 0) + { + grub_gfxmenu_view_destroy (view); + return 0; + } + + init_terminal (view); + + return view; +} + +/* Destroy the view object. All used memory is freed. */ +void +grub_gfxmenu_view_destroy (grub_gfxmenu_view_t view) +{ + grub_video_bitmap_destroy (view->desktop_image); + if (view->terminal_box) + view->terminal_box->destroy (view->terminal_box); + grub_free (view->terminal_font_name); + grub_free (view->title_text); + grub_free (view->progress_message_text); + grub_free (view->theme_path); + if (view->canvas) + view->canvas->ops->component.destroy (view->canvas); + grub_free (view); + + set_text_mode (); + destroy_terminal (); +} + +/* Sets MESSAGE as the progress message for the view. + MESSAGE can be 0, in which case no message is displayed. */ +static void +set_progress_message (grub_gfxmenu_view_t view, const char *message) +{ + grub_free (view->progress_message_text); + if (message) + view->progress_message_text = grub_strdup (message); + else + view->progress_message_text = 0; +} + +static void +draw_background (grub_gfxmenu_view_t view) +{ + if (view->desktop_image) + { + struct grub_video_bitmap *img = view->desktop_image; + grub_video_blit_bitmap (img, GRUB_VIDEO_BLIT_REPLACE, + view->screen.x, view->screen.y, 0, 0, + grub_video_bitmap_get_width (img), + grub_video_bitmap_get_height (img)); + } + else + { + grub_video_fill_rect (grub_gui_map_color (view->desktop_color), + view->screen.x, view->screen.y, + view->screen.width, view->screen.height); + } +} + +static void +draw_title (grub_gfxmenu_view_t view) +{ + if (! view->title_text) + return; + + /* Center the title. */ + int title_width = grub_font_get_string_width (view->title_font, + view->title_text); + int x = (view->screen.width - title_width) / 2; + int y = 40 + grub_font_get_ascent (view->title_font); + grub_font_draw_string (view->title_text, + view->title_font, + grub_gui_map_color (view->title_color), + x, y); +} + +struct progress_value_data +{ + const char *visible; + const char *start; + const char *end; + const char *value; + const char *text; +}; + +static void +update_timeout_visit (grub_gui_component_t component, + void *userdata) +{ + struct progress_value_data *pv; + pv = (struct progress_value_data *) userdata; + component->ops->set_property (component, "visible", pv->visible); + component->ops->set_property (component, "start", pv->start); + component->ops->set_property (component, "end", pv->end); + component->ops->set_property (component, "value", pv->value); + component->ops->set_property (component, "text", pv->text); +} + +static void +update_timeout (grub_gfxmenu_view_t view) +{ + char startbuf[20]; + char valuebuf[20]; + char msgbuf[120]; + + int timeout = grub_gfxmenu_model_get_timeout_ms (view->model); + int remaining = grub_gfxmenu_model_get_timeout_remaining_ms (view->model); + struct progress_value_data pv; + + pv.visible = timeout > 0 ? "true" : "false"; + grub_sprintf (startbuf, "%d", -timeout); + pv.start = startbuf; + pv.end = "0"; + grub_sprintf (valuebuf, "%d", remaining > 0 ? -remaining : 0); + pv.value = valuebuf; + + int seconds_remaining_rounded_up = (remaining + 999) / 1000; + grub_sprintf (msgbuf, + "The highlighted entry will be booted automatically in %d s.", + seconds_remaining_rounded_up); + pv.text = msgbuf; + + grub_gui_find_by_id ((grub_gui_component_t) view->canvas, + TIMEOUT_COMPONENT_ID, update_timeout_visit, &pv); +} + +static void +update_menu_visit (grub_gui_component_t component, + void *userdata) +{ + grub_gfxmenu_view_t view; + view = userdata; + if (component->ops->is_instance (component, "list")) + { + grub_gui_list_t list = (grub_gui_list_t) component; + list->ops->set_view_info (list, view->theme_path, view->model); + } +} + +/* Update any boot menu components with the current menu model and + theme path. */ +static void +update_menu_components (grub_gfxmenu_view_t view) +{ + grub_gui_iterate_recursively ((grub_gui_component_t) view->canvas, + update_menu_visit, view); +} + +static void +draw_message (grub_gfxmenu_view_t view) +{ + char *text = view->progress_message_text; + if (! text) + return; + + grub_font_t font = view->message_font; + grub_video_color_t color = grub_gui_map_color (view->message_color); + + /* Set the timeout bar's frame. */ + grub_video_rect_t f; + f.width = view->screen.width * 4 / 5; + f.height = 50; + f.x = view->screen.x + (view->screen.width - f.width) / 2; + f.y = view->screen.y + view->screen.height - 90 - 20 - f.height; + + /* Border. */ + grub_video_fill_rect (color, + f.x-1, f.y-1, f.width+2, f.height+2); + /* Fill. */ + grub_video_fill_rect (grub_gui_map_color (view->message_bg_color), + f.x, f.y, f.width, f.height); + + /* Center the text. */ + int text_width = grub_font_get_string_width (font, text); + int x = f.x + (f.width - text_width) / 2; + int y = (f.y + (f.height - grub_font_get_descent (font)) / 2 + + grub_font_get_ascent (font) / 2); + grub_font_draw_string (text, font, color, x, y); +} + + +void +grub_gfxmenu_view_draw (grub_gfxmenu_view_t view) +{ + grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY); + update_timeout (view); + update_menu_components (view); + + draw_background (view); + if (view->canvas) + view->canvas->ops->component.paint (view->canvas); + draw_title (view); + draw_message (view); +} + +static grub_err_t +set_graphics_mode (void) +{ + const char *modestr = grub_env_get ("gfxmode"); + if (!modestr || !modestr[0]) + modestr = "auto"; + return grub_video_set_mode (modestr, GRUB_VIDEO_MODE_TYPE_PURE_TEXT, 0); +} + +static grub_err_t +set_text_mode (void) +{ + return grub_video_restore (); +} + +static int term_target_width; +static int term_target_height; +static struct grub_video_render_target *term_target; +static int term_initialized; +static grub_term_output_t term_original; +static grub_gfxmenu_view_t term_view; + +static void +repaint_terminal (int x __attribute ((unused)), + int y __attribute ((unused)), + int width __attribute ((unused)), + int height __attribute ((unused))) +{ + if (! term_view) + return; + + grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY); + grub_gfxmenu_view_draw (term_view); + grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY); + + int termx = term_view->screen.x + + term_view->screen.width * (10 - 7) / 10 / 2; + int termy = term_view->screen.y + + term_view->screen.height * (10 - 7) / 10 / 2; + + grub_gfxmenu_box_t term_box = term_view->terminal_box; + if (term_box) + { + term_box->set_content_size (term_box, + term_target_width, term_target_height); + + term_box->draw (term_box, + termx - term_box->get_left_pad (term_box), + termy - term_box->get_top_pad (term_box)); + } + + grub_video_blit_render_target (term_target, GRUB_VIDEO_BLIT_REPLACE, + termx, termy, + 0, 0, term_target_width, term_target_height); + grub_video_swap_buffers (); +} + +static void +init_terminal (grub_gfxmenu_view_t view) +{ + term_original = grub_term_get_current_output (); + + term_target_width = view->screen.width * 7 / 10; + term_target_height = view->screen.height * 7 / 10; + + grub_video_create_render_target (&term_target, + term_target_width, + term_target_height, + GRUB_VIDEO_MODE_TYPE_RGB + | GRUB_VIDEO_MODE_TYPE_ALPHA); + if (grub_errno != GRUB_ERR_NONE) + return; + + /* Note: currently there is no API for changing the gfxterm font + on the fly, so whatever font the initially loaded theme specifies + will be permanent. */ + grub_gfxterm_init_window (term_target, 0, 0, + term_target_width, term_target_height, 0, + view->terminal_font_name, 3); + if (grub_errno != GRUB_ERR_NONE) + return; + term_initialized = 1; + + /* XXX: store static pointer to the 'view' object so the repaint callback can access it. */ + term_view = view; + grub_gfxterm_set_repaint_callback (repaint_terminal); + grub_term_set_current_output (grub_gfxterm_get_term ()); +} + +static void destroy_terminal (void) +{ + term_view = 0; + if (term_initialized) + grub_gfxterm_destroy_window (); + grub_gfxterm_set_repaint_callback (0); + if (term_target) + grub_video_delete_render_target (term_target); + if (term_original) + grub_term_set_current_output (term_original); +} + + +static void +notify_booting (grub_menu_entry_t entry, void *userdata) +{ + grub_gfxmenu_view_t view = (grub_gfxmenu_view_t) userdata; + + char *s = grub_malloc (100 + grub_strlen (entry->title)); + if (!s) + return; + + grub_sprintf (s, "Booting '%s'", entry->title); + set_progress_message (view, s); + grub_free (s); + grub_gfxmenu_view_draw (view); + grub_video_swap_buffers (); +} + +static void +notify_fallback (grub_menu_entry_t entry, void *userdata) +{ + grub_gfxmenu_view_t view = (grub_gfxmenu_view_t) userdata; + + char *s = grub_malloc (100 + grub_strlen (entry->title)); + if (!s) + return; + + grub_sprintf (s, "Falling back to '%s'", entry->title); + set_progress_message (view, s); + grub_free (s); + grub_gfxmenu_view_draw (view); + grub_video_swap_buffers (); +} + +static void +notify_execution_failure (void *userdata __attribute__ ((unused))) +{ +} + + +static struct grub_menu_execute_callback execute_callback = +{ + .notify_booting = notify_booting, + .notify_fallback = notify_fallback, + .notify_failure = notify_execution_failure +}; + +int +grub_gfxmenu_view_execute_with_fallback (grub_gfxmenu_view_t view, + grub_menu_entry_t entry) +{ + grub_menu_execute_with_fallback (grub_gfxmenu_model_get_menu (view->model), + entry, &execute_callback, (void *) view); + + if (set_graphics_mode () != GRUB_ERR_NONE) + return 0; /* Failure. */ + + /* If we returned, there was a failure. */ + set_progress_message (view, + "Unable to automatically boot. " + "Press SPACE to continue."); + grub_gfxmenu_view_draw (view); + grub_video_swap_buffers (); + while (GRUB_TERM_ASCII_CHAR(grub_getkey ()) != ' ') + { + /* Wait for SPACE to be pressed. */ + } + + set_progress_message (view, 0); /* Clear the message. */ + + return 1; /* Ok. */ +} + +int +grub_gfxmenu_view_execute_entry (grub_gfxmenu_view_t view, + grub_menu_entry_t entry) +{ + /* Currently we switch back to text mode by restoring + the original terminal before executing the menu entry. + It is hard to make it work when executing a menu entry + that switches video modes -- it using gfxterm in a + window, the repaint callback seems to crash GRUB. */ + /* TODO: Determine if this works when 'gfxterm' was set as + the current terminal before invoking the gfxmenu. */ + destroy_terminal (); + + grub_menu_execute_entry (entry); + if (grub_errno != GRUB_ERR_NONE) + grub_wait_after_message (); + + if (set_graphics_mode () != GRUB_ERR_NONE) + return 0; /* Failure. */ + + init_terminal (view); + return 1; /* Ok. */ +} + +void +grub_gfxmenu_view_run_terminal (grub_gfxmenu_view_t view __attribute__((unused))) +{ + grub_cmdline_run (1); +} diff --git a/gfxmenu/widget-box.c b/gfxmenu/widget-box.c new file mode 100644 index 000000000..079fd66d4 --- /dev/null +++ b/gfxmenu/widget-box.c @@ -0,0 +1,313 @@ +/* widget_box.c - Pixmap-stylized box widget. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +enum box_pixmaps +{ + BOX_PIXMAP_NW, BOX_PIXMAP_NE, BOX_PIXMAP_SE, BOX_PIXMAP_SW, + BOX_PIXMAP_N, BOX_PIXMAP_E, BOX_PIXMAP_S, BOX_PIXMAP_W, + BOX_PIXMAP_CENTER +}; + +static const char *box_pixmap_names[] = { + /* Corners: */ + "nw", "ne", "se", "sw", + /* Sides: */ + "n", "e", "s", "w", + /* Center: */ + "c" +}; + +#define BOX_NUM_PIXMAPS (sizeof(box_pixmap_names)/sizeof(*box_pixmap_names)) + +static int +get_height (struct grub_video_bitmap *bitmap) +{ + if (bitmap) + return grub_video_bitmap_get_height (bitmap); + else + return 0; +} + +static int +get_width (struct grub_video_bitmap *bitmap) +{ + if (bitmap) + return grub_video_bitmap_get_width (bitmap); + else + return 0; +} + +static void +blit (grub_gfxmenu_box_t self, int pixmap_index, int x, int y) +{ + struct grub_video_bitmap *bitmap; + bitmap = self->scaled_pixmaps[pixmap_index]; + if (! bitmap) + return; + grub_video_blit_bitmap (bitmap, GRUB_VIDEO_BLIT_BLEND, + x, y, 0, 0, + grub_video_bitmap_get_width (bitmap), + grub_video_bitmap_get_height (bitmap)); +} + +static void +draw (grub_gfxmenu_box_t self, int x, int y) +{ + int height_n; + int height_s; + int height_e; + int height_w; + int width_n; + int width_s; + int width_e; + int width_w; + + height_n = get_height (self->scaled_pixmaps[BOX_PIXMAP_N]); + height_s = get_height (self->scaled_pixmaps[BOX_PIXMAP_S]); + height_e = get_height (self->scaled_pixmaps[BOX_PIXMAP_E]); + height_w = get_height (self->scaled_pixmaps[BOX_PIXMAP_W]); + width_n = get_width (self->scaled_pixmaps[BOX_PIXMAP_N]); + width_s = get_width (self->scaled_pixmaps[BOX_PIXMAP_S]); + width_e = get_width (self->scaled_pixmaps[BOX_PIXMAP_E]); + width_w = get_width (self->scaled_pixmaps[BOX_PIXMAP_W]); + + /* Draw sides. */ + blit (self, BOX_PIXMAP_N, x + width_w, y); + blit (self, BOX_PIXMAP_S, x + width_w, y + height_n + self->content_height); + blit (self, BOX_PIXMAP_E, x + width_w + self->content_width, y + height_n); + blit (self, BOX_PIXMAP_W, x, y + height_n); + + /* Draw corners. */ + blit (self, BOX_PIXMAP_NW, x, y); + blit (self, BOX_PIXMAP_NE, x + width_w + self->content_width, y); + blit (self, BOX_PIXMAP_SE, + x + width_w + self->content_width, + y + height_n + self->content_height); + blit (self, BOX_PIXMAP_SW, x, y + height_n + self->content_height); + + /* Draw center. */ + blit (self, BOX_PIXMAP_CENTER, x + width_w, y + height_n); +} + +static grub_err_t +scale_pixmap (grub_gfxmenu_box_t self, int i, int w, int h) +{ + struct grub_video_bitmap **scaled = &self->scaled_pixmaps[i]; + struct grub_video_bitmap *raw = self->raw_pixmaps[i]; + + if (raw == 0) + return grub_errno; + + if (w == -1) + w = grub_video_bitmap_get_width (raw); + if (h == -1) + h = grub_video_bitmap_get_height (raw); + + if (*scaled == 0 + || ((int) grub_video_bitmap_get_width (*scaled) != w) + || ((int) grub_video_bitmap_get_height (*scaled) != h)) + { + if (*scaled) + { + grub_video_bitmap_destroy (*scaled); + *scaled = 0; + } + + /* Don't try to create a bitmap with a zero dimension. */ + if (w != 0 && h != 0) + grub_video_bitmap_create_scaled (scaled, w, h, raw, + GRUB_VIDEO_BITMAP_SCALE_METHOD_BEST); + if (grub_errno != GRUB_ERR_NONE) + { + grub_error_push (); + grub_error (grub_errno, + "failed to scale bitmap for styled box pixmap #%d", i); + } + } + + return grub_errno; +} + +static void +set_content_size (grub_gfxmenu_box_t self, + int width, int height) +{ + self->content_width = width; + self->content_height = height; + + /* Resize sides to match the width and height. */ + /* It is assumed that the corners width/height match the adjacent sides. */ + + /* Resize N and S sides to match width. */ + if (scale_pixmap(self, BOX_PIXMAP_N, width, -1) != GRUB_ERR_NONE) + return; + if (scale_pixmap(self, BOX_PIXMAP_S, width, -1) != GRUB_ERR_NONE) + return; + + /* Resize E and W sides to match height. */ + if (scale_pixmap(self, BOX_PIXMAP_E, -1, height) != GRUB_ERR_NONE) + return; + if (scale_pixmap(self, BOX_PIXMAP_W, -1, height) != GRUB_ERR_NONE) + return; + + /* Don't scale the corners--they are assumed to match the sides. */ + if (scale_pixmap(self, BOX_PIXMAP_NW, -1, -1) != GRUB_ERR_NONE) + return; + if (scale_pixmap(self, BOX_PIXMAP_SW, -1, -1) != GRUB_ERR_NONE) + return; + if (scale_pixmap(self, BOX_PIXMAP_NE, -1, -1) != GRUB_ERR_NONE) + return; + if (scale_pixmap(self, BOX_PIXMAP_SE, -1, -1) != GRUB_ERR_NONE) + return; + + /* Scale the center area. */ + if (scale_pixmap(self, BOX_PIXMAP_CENTER, width, height) != GRUB_ERR_NONE) + return; +} + +static int +get_left_pad (grub_gfxmenu_box_t self) +{ + return get_width (self->raw_pixmaps[BOX_PIXMAP_W]); +} + +static int +get_top_pad (grub_gfxmenu_box_t self) +{ + return get_height (self->raw_pixmaps[BOX_PIXMAP_N]); +} + +static int +get_right_pad (grub_gfxmenu_box_t self) +{ + return get_width (self->raw_pixmaps[BOX_PIXMAP_E]); +} + +static int +get_bottom_pad (grub_gfxmenu_box_t self) +{ + return get_height (self->raw_pixmaps[BOX_PIXMAP_S]); +} + +static void +destroy (grub_gfxmenu_box_t self) +{ + unsigned i; + for (i = 0; i < BOX_NUM_PIXMAPS; i++) + { + if (self->raw_pixmaps[i]) + grub_video_bitmap_destroy(self->raw_pixmaps[i]); + self->raw_pixmaps[i] = 0; + + if (self->scaled_pixmaps[i]) + grub_video_bitmap_destroy(self->scaled_pixmaps[i]); + self->scaled_pixmaps[i] = 0; + } + grub_free (self->raw_pixmaps); + self->raw_pixmaps = 0; + grub_free (self->scaled_pixmaps); + self->scaled_pixmaps = 0; + + /* Free self: must be the last step! */ + grub_free (self); +} + + +/* Create a new box. If PIXMAPS_PREFIX and PIXMAPS_SUFFIX are both non-null, + then an attempt is made to load the north, south, east, west, northwest, + northeast, southeast, southwest, and center pixmaps. + If either PIXMAPS_PREFIX or PIXMAPS_SUFFIX is 0, then no pixmaps are + loaded, and the box has zero-width borders and is drawn transparent. */ +grub_gfxmenu_box_t +grub_gfxmenu_create_box (const char *pixmaps_prefix, + const char *pixmaps_suffix) +{ + unsigned i; + grub_gfxmenu_box_t box; + + box = (grub_gfxmenu_box_t) grub_malloc (sizeof (*box)); + if (! box) + return 0; + + box->content_width = 0; + box->content_height = 0; + box->raw_pixmaps = + (struct grub_video_bitmap **) + grub_malloc (BOX_NUM_PIXMAPS * sizeof (struct grub_video_bitmap *)); + box->scaled_pixmaps = + (struct grub_video_bitmap **) + grub_malloc (BOX_NUM_PIXMAPS * sizeof (struct grub_video_bitmap *)); + + /* Initialize all pixmap pointers to NULL so that proper destruction can + be performed if an error is encountered partway through construction. */ + for (i = 0; i < BOX_NUM_PIXMAPS; i++) + box->raw_pixmaps[i] = 0; + for (i = 0; i < BOX_NUM_PIXMAPS; i++) + box->scaled_pixmaps[i] = 0; + + /* Load the pixmaps. */ + for (i = 0; i < BOX_NUM_PIXMAPS; i++) + { + if (pixmaps_prefix && pixmaps_suffix) + { + char *path; + char *path_end; + + path = grub_malloc (grub_strlen (pixmaps_prefix) + + grub_strlen (box_pixmap_names[i]) + + grub_strlen (pixmaps_suffix) + + 1); + if (! path) + goto fail_and_destroy; + + /* Construct the specific path for this pixmap. */ + path_end = grub_stpcpy (path, pixmaps_prefix); + path_end = grub_stpcpy (path_end, box_pixmap_names[i]); + path_end = grub_stpcpy (path_end, pixmaps_suffix); + + grub_video_bitmap_load (&box->raw_pixmaps[i], path); + grub_free (path); + + /* Ignore missing pixmaps. */ + grub_errno = GRUB_ERR_NONE; + } + } + + box->draw = draw; + box->set_content_size = set_content_size; + box->get_left_pad = get_left_pad; + box->get_top_pad = get_top_pad; + box->get_right_pad = get_right_pad; + box->get_bottom_pad = get_bottom_pad; + box->destroy = destroy; + return box; + +fail_and_destroy: + destroy (box); + return 0; +} diff --git a/include/grub/gfxmenu_model.h b/include/grub/gfxmenu_model.h new file mode 100644 index 000000000..e5c7da3ac --- /dev/null +++ b/include/grub/gfxmenu_model.h @@ -0,0 +1,59 @@ +/* gfxmenu_model.h - gfxmenu model interface. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_GFXMENU_MODEL_HEADER +#define GRUB_GFXMENU_MODEL_HEADER 1 + +#include + +struct grub_gfxmenu_model; /* Forward declaration of opaque type. */ +typedef struct grub_gfxmenu_model *grub_gfxmenu_model_t; + + +grub_gfxmenu_model_t grub_gfxmenu_model_new (grub_menu_t menu); + +void grub_gfxmenu_model_destroy (grub_gfxmenu_model_t model); + +grub_menu_t grub_gfxmenu_model_get_menu (grub_gfxmenu_model_t model); + +void grub_gfxmenu_model_set_timeout (grub_gfxmenu_model_t model); + +void grub_gfxmenu_model_clear_timeout (grub_gfxmenu_model_t model); + +int grub_gfxmenu_model_get_timeout_ms (grub_gfxmenu_model_t model); + +int grub_gfxmenu_model_get_timeout_remaining_ms (grub_gfxmenu_model_t model); + +int grub_gfxmenu_model_timeout_expired (grub_gfxmenu_model_t model); + +int grub_gfxmenu_model_get_num_entries (grub_gfxmenu_model_t model); + +int grub_gfxmenu_model_get_selected_index (grub_gfxmenu_model_t model); + +void grub_gfxmenu_model_set_selected_index (grub_gfxmenu_model_t model, + int index); + +const char *grub_gfxmenu_model_get_entry_title (grub_gfxmenu_model_t model, + int index); + +grub_menu_entry_t grub_gfxmenu_model_get_entry (grub_gfxmenu_model_t model, + int index); + +#endif /* GRUB_GFXMENU_MODEL_HEADER */ + diff --git a/include/grub/gfxmenu_view.h b/include/grub/gfxmenu_view.h new file mode 100644 index 000000000..1144382f2 --- /dev/null +++ b/include/grub/gfxmenu_view.h @@ -0,0 +1,91 @@ +/* gfxmenu_view.h - gfxmenu view interface. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_GFXMENU_VIEW_HEADER +#define GRUB_GFXMENU_VIEW_HEADER 1 + +#include +#include +#include +#include +#include +#include + +struct grub_gfxmenu_view; /* Forward declaration of opaque type. */ +typedef struct grub_gfxmenu_view *grub_gfxmenu_view_t; + + +grub_gfxmenu_view_t grub_gfxmenu_view_new (const char *theme_path, + grub_gfxmenu_model_t model); + +void grub_gfxmenu_view_destroy (grub_gfxmenu_view_t view); + +/* Set properties on the view based on settings from the specified + theme file. */ +grub_err_t grub_gfxmenu_view_load_theme (grub_gfxmenu_view_t view, + const char *theme_path); + +grub_err_t grub_gui_recreate_box (grub_gfxmenu_box_t *boxptr, + const char *pattern, const char *theme_dir); + +void grub_gfxmenu_view_draw (grub_gfxmenu_view_t view); + +int grub_gfxmenu_view_execute_with_fallback (grub_gfxmenu_view_t view, + grub_menu_entry_t entry); + +int grub_gfxmenu_view_execute_entry (grub_gfxmenu_view_t view, + grub_menu_entry_t entry); + +void grub_gfxmenu_view_run_terminal (grub_gfxmenu_view_t view); + + + +/* Implementation details -- this should not be used outside of the + view itself. */ + +#include +#include +#include +#include +#include + +/* Definition of the private representation of the view. */ +struct grub_gfxmenu_view +{ + grub_video_rect_t screen; + + grub_font_t title_font; + grub_font_t message_font; + char *terminal_font_name; + grub_gui_color_t title_color; + grub_gui_color_t message_color; + grub_gui_color_t message_bg_color; + struct grub_video_bitmap *desktop_image; + grub_gui_color_t desktop_color; + grub_gfxmenu_box_t terminal_box; + char *title_text; + char *progress_message_text; + char *theme_path; + + grub_gui_container_t canvas; + + grub_gfxmenu_model_t model; +}; + +#endif /* ! GRUB_GFXMENU_VIEW_HEADER */ diff --git a/include/grub/gfxwidgets.h b/include/grub/gfxwidgets.h new file mode 100644 index 000000000..f9678bf9e --- /dev/null +++ b/include/grub/gfxwidgets.h @@ -0,0 +1,49 @@ +/* gfxwidgets.h - Widgets for the graphical menu (gfxmenu). */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_GFXWIDGETS_HEADER +#define GRUB_GFXWIDGETS_HEADER 1 + +#include + +typedef struct grub_gfxmenu_box *grub_gfxmenu_box_t; + +struct grub_gfxmenu_box +{ + /* The size of the content. */ + int content_width; + int content_height; + + struct grub_video_bitmap **raw_pixmaps; + struct grub_video_bitmap **scaled_pixmaps; + + void (*draw) (grub_gfxmenu_box_t self, int x, int y); + void (*set_content_size) (grub_gfxmenu_box_t self, + int width, int height); + int (*get_left_pad) (grub_gfxmenu_box_t self); + int (*get_top_pad) (grub_gfxmenu_box_t self); + int (*get_right_pad) (grub_gfxmenu_box_t self); + int (*get_bottom_pad) (grub_gfxmenu_box_t self); + void (*destroy) (grub_gfxmenu_box_t self); +}; + +grub_gfxmenu_box_t grub_gfxmenu_create_box (const char *pixmaps_prefix, + const char *pixmaps_suffix); + +#endif /* ! GRUB_GFXWIDGETS_HEADER */ diff --git a/include/grub/gui.h b/include/grub/gui.h new file mode 100644 index 000000000..5b785dbb5 --- /dev/null +++ b/include/grub/gui.h @@ -0,0 +1,165 @@ +/* gui.h - GUI components header file. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include + +#ifndef GRUB_GUI_H +#define GRUB_GUI_H 1 + +/* A representation of a color. Unlike grub_video_color_t, this + representation is independent of any video mode specifics. */ +typedef struct grub_gui_color +{ + grub_uint8_t red; + grub_uint8_t green; + grub_uint8_t blue; + grub_uint8_t alpha; +} grub_gui_color_t; + +typedef struct grub_gui_component *grub_gui_component_t; +typedef struct grub_gui_container *grub_gui_container_t; +typedef struct grub_gui_list *grub_gui_list_t; + +typedef void (*grub_gui_component_callback) (grub_gui_component_t component, + void *userdata); + +/* Component interface. */ + +struct grub_gui_component_ops +{ + void (*destroy) (void *self); + const char * (*get_id) (void *self); + int (*is_instance) (void *self, const char *type); + void (*paint) (void *self); + void (*set_parent) (void *self, grub_gui_container_t parent); + grub_gui_container_t (*get_parent) (void *self); + void (*set_bounds) (void *self, const grub_video_rect_t *bounds); + void (*get_bounds) (void *self, grub_video_rect_t *bounds); + void (*get_preferred_size) (void *self, int *width, int *height); + grub_err_t (*set_property) (void *self, const char *name, const char *value); +}; + +struct grub_gui_container_ops +{ + struct grub_gui_component_ops component; + void (*add) (void *self, grub_gui_component_t comp); + void (*remove) (void *self, grub_gui_component_t comp); + void (*iterate_children) (void *self, + grub_gui_component_callback cb, void *userdata); +}; + +struct grub_gui_list_ops +{ + struct grub_gui_component_ops component_ops; + void (*set_view_info) (void *self, + const char *theme_path, + grub_gfxmenu_model_t menu); +}; + +struct grub_gui_component +{ + struct grub_gui_component_ops *ops; +}; + +struct grub_gui_container +{ + struct grub_gui_container_ops *ops; +}; + +struct grub_gui_list +{ + struct grub_gui_list_ops *ops; +}; + + +/* Interfaces to concrete component classes. */ + +grub_gui_container_t grub_gui_canvas_new (void); +grub_gui_container_t grub_gui_vbox_new (void); +grub_gui_container_t grub_gui_hbox_new (void); +grub_gui_component_t grub_gui_label_new (void); +grub_gui_component_t grub_gui_image_new (void); +grub_gui_component_t grub_gui_progress_bar_new (void); +grub_gui_component_t grub_gui_list_new (void); +grub_gui_component_t grub_gui_circular_progress_new (void); + +/* Manipulation functions. */ + +/* Visit all components with the specified ID. */ +void grub_gui_find_by_id (grub_gui_component_t root, + const char *id, + grub_gui_component_callback cb, + void *userdata); + +/* Visit all components. */ +void grub_gui_iterate_recursively (grub_gui_component_t root, + grub_gui_component_callback cb, + void *userdata); + +/* Helper functions. */ + +static __inline void +grub_gui_save_viewport (grub_video_rect_t *r) +{ + grub_video_get_viewport ((unsigned *) &r->x, + (unsigned *) &r->y, + (unsigned *) &r->width, + (unsigned *) &r->height); +} + +static __inline void +grub_gui_restore_viewport (const grub_video_rect_t *r) +{ + grub_video_set_viewport (r->x, r->y, r->width, r->height); +} + +/* Set a new viewport relative the the current one, saving the current + viewport in OLD so it can be later restored. */ +static __inline void +grub_gui_set_viewport (const grub_video_rect_t *r, grub_video_rect_t *old) +{ + grub_gui_save_viewport (old); + grub_video_set_viewport (old->x + r->x, + old->y + r->y, + r->width, + r->height); +} + +static __inline grub_gui_color_t +grub_gui_color_rgb (int r, int g, int b) +{ + grub_gui_color_t c; + c.red = r; + c.green = g; + c.blue = b; + c.alpha = 255; + return c; +} + +static __inline grub_video_color_t +grub_gui_map_color (grub_gui_color_t c) +{ + return grub_video_map_rgba (c.red, c.green, c.blue, c.alpha); +} + +#endif /* ! GRUB_GUI_H */ diff --git a/include/grub/gui_string_util.h b/include/grub/gui_string_util.h new file mode 100644 index 000000000..7b5fbb3ea --- /dev/null +++ b/include/grub/gui_string_util.h @@ -0,0 +1,39 @@ +/* gui_string_util.h - String utilities for the graphical menu interface. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_GUI_STRING_UTIL_HEADER +#define GRUB_GUI_STRING_UTIL_HEADER 1 + +#include +#include + +char *grub_new_substring (const char *buf, + grub_size_t start, grub_size_t end); + +char *grub_resolve_relative_path (const char *base, const char *path); + +char *grub_get_dirname (const char *file_path); + +int grub_gui_get_named_color (const char *name, grub_gui_color_t *color); + +grub_err_t grub_gui_parse_color (const char *s, grub_gui_color_t *color); + +grub_err_t grub_gui_parse_2_tuple (const char *s, int *px, int *py); + +#endif /* GRUB_GUI_STRING_UTIL_HEADER */ diff --git a/include/grub/icon_manager.h b/include/grub/icon_manager.h new file mode 100644 index 000000000..81c488416 --- /dev/null +++ b/include/grub/icon_manager.h @@ -0,0 +1,41 @@ +/* icon_manager.h - gfxmenu icon manager. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_ICON_MANAGER_HEADER +#define GRUB_ICON_MANAGER_HEADER 1 + +#include +#include + +/* Forward declaration of opaque structure handle type. */ +typedef struct grub_gfxmenu_icon_manager *grub_gfxmenu_icon_manager_t; + +grub_gfxmenu_icon_manager_t grub_gfxmenu_icon_manager_new (void); +void grub_gfxmenu_icon_manager_destroy (grub_gfxmenu_icon_manager_t mgr); +void grub_gfxmenu_icon_manager_clear_cache (grub_gfxmenu_icon_manager_t mgr); +void grub_gfxmenu_icon_manager_set_theme_path (grub_gfxmenu_icon_manager_t mgr, + const char *path); +void grub_gfxmenu_icon_manager_set_icon_size (grub_gfxmenu_icon_manager_t mgr, + int width, int height); +struct grub_video_bitmap * +grub_gfxmenu_icon_manager_get_icon (grub_gfxmenu_icon_manager_t mgr, + grub_menu_entry_t entry); + +#endif /* GRUB_ICON_MANAGER_HEADER */ + diff --git a/include/grub/term.h b/include/grub/term.h index 316d75390..20b85d1cd 100644 --- a/include/grub/term.h +++ b/include/grub/term.h @@ -261,7 +261,7 @@ grub_term_set_current_input (grub_term_input_t term) } static inline grub_err_t -grub_term_set_current_output (grub_term_output_t term) +grub_term_set_current_output (const struct grub_term_output *term) { return grub_handler_set_current (&grub_term_output_class, GRUB_AS_HANDLER (term)); From 704e21180ed65e96111383a8b780eff614e0e035 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 20 Nov 2009 16:07:16 +0100 Subject: [PATCH 094/738] At least it compiles now --- gfxmenu/gui_label.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gfxmenu/gui_label.c b/gfxmenu/gui_label.c index 2e49c787e..eb2a495ff 100644 --- a/gfxmenu/gui_label.c +++ b/gfxmenu/gui_label.c @@ -151,7 +151,7 @@ label_get_preferred_size (void *vself, int *width, int *height) *height = self->preferred_height; } -static void +static grub_err_t label_set_property (void *vself, const char *name, const char *value) { grub_gui_label_t self = vself; @@ -204,6 +204,7 @@ label_set_property (void *vself, const char *name, const char *value) else self->id = 0; } + return GRUB_ERR_NONE; } static struct grub_gui_component_ops label_ops = From 8dec533a1cdeafd13c239121d36ffd507575bc47 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 20 Nov 2009 22:26:08 +0100 Subject: [PATCH 095/738] ChangeLog --- ChangeLog.gfxmenu | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 ChangeLog.gfxmenu diff --git a/ChangeLog.gfxmenu b/ChangeLog.gfxmenu new file mode 100644 index 000000000..bc9db7170 --- /dev/null +++ b/ChangeLog.gfxmenu @@ -0,0 +1,31 @@ +2009-11-20 Colin D Bennett + + * conf/common.rmk (pkglib_MODULES): Add gfxmenu.mod. + (gfxmenu_mod_SOURCES): New variable. + (gfxmenu_mod_CFLAGS): Likewise. + (gfxmenu_mod_LDFLAGS): Likewise. + * include/grub/term.h (grub_term_set_current_output): Declare + argument as const. + * docs/gfxmenu-theme-example.txt: New file. + * gfxmenu/gfxmenu.c: Likewise. + * gfxmenu/gui_box.c: Likewise. + * gfxmenu/gui_canvas.c: Likewise. + * gfxmenu/gui_circular_progress.c: Likewise. + * gfxmenu/gui_image.c: Likewise. + * gfxmenu/gui_label.c: Likewise. + * gfxmenu/gui_list.c: Likewise. + * gfxmenu/gui_progress_bar.c: Likewise. + * gfxmenu/gui_string_util.c: Likewise. + * gfxmenu/gui_util.c: Likewise. + * gfxmenu/icon_manager.c: Likewise. + * gfxmenu/model.c: Likewise. + * gfxmenu/named_colors.c: Likewise. + * gfxmenu/theme_loader.c: Likewise. + * gfxmenu/view.c: Likewise. + * gfxmenu/widget-box.c: Likewise. + * include/grub/gfxmenu_model.h: Likewise. + * include/grub/gfxmenu_view.h: Likewise. + * include/grub/gfxwidgets.h: Likewise. + * include/grub/gui.h: Likewise. + * include/grub/gui_string_util.h: Likewise. + * include/grub/icon_manager.h: Likewise. From aff798d6f4ae597c6b887abc8977d63bc434aa10 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 21 Nov 2009 15:29:12 +0100 Subject: [PATCH 096/738] icondir support --- gfxmenu/gui_string_util.c | 13 ++++++++++--- gfxmenu/icon_manager.c | 18 ++++++++---------- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/gfxmenu/gui_string_util.c b/gfxmenu/gui_string_util.c index 41170d724..31b2f0aca 100644 --- a/gfxmenu/gui_string_util.c +++ b/gfxmenu/gui_string_util.c @@ -150,18 +150,25 @@ grub_resolve_relative_path (const char *base, const char *path) char *abspath; char *canonpath; char *p; + grub_size_t l; /* If PATH is an absolute path, then just use it as is. */ if (path[0] == '/' || path[0] == '(') return canonicalize_path (path); - abspath = grub_malloc (grub_strlen (base) + grub_strlen (path) + 1); + abspath = grub_malloc (grub_strlen (base) + grub_strlen (path) + 3); if (! abspath) return 0; - /* Concatenate BASE and PATH. - Note that BASE is expected to have a trailing slash. */ + /* Concatenate BASE and PATH. */ p = grub_stpcpy (abspath, base); + l = grub_strlen (abspath); + if (l == 0 || abspath[l-1] != '/') + { + *p = '/'; + p++; + *p = 0; + } grub_stpcpy (p, path); canonpath = canonicalize_path (abspath); diff --git a/gfxmenu/icon_manager.c b/gfxmenu/icon_manager.c index a362882e1..b7b891991 100644 --- a/gfxmenu/icon_manager.c +++ b/gfxmenu/icon_manager.c @@ -26,6 +26,7 @@ #include #include #include +#include /* Currently hard coded to '.png' extension. */ static const char icon_extension[] = ".png"; @@ -200,19 +201,16 @@ get_icon_by_class (grub_gfxmenu_icon_manager_t mgr, const char *class_name) icon = try_loading_icon (mgr, icons_dir, class_name); grub_free (icons_dir); } + + grub_free (theme_dir); if (! icon) { - /* If the theme doesn't have an appropriate icon, check in - "grub/themes/icons". */ - /* TODO use GRUB prefix "/icons" */ - icons_dir = grub_resolve_relative_path (theme_dir, "../icons/"); - if (icons_dir) - { - icon = try_loading_icon (mgr, icons_dir, class_name); - grub_free (icons_dir); - } + const char *icondir; + + icondir = grub_env_get ("icondir"); + if (icondir) + icon = try_loading_icon (mgr, icondir, class_name); } - grub_free (theme_dir); /* No icon was found. */ /* This should probably be noted in the cache, so that a search is not From ade85305f87463be23b8c67c38cf670ab6f9dfff Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 21 Nov 2009 17:33:23 +0100 Subject: [PATCH 097/738] recognise mips64(el) targets --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 96aae837e..ed41cc232 100644 --- a/configure.ac +++ b/configure.ac @@ -46,12 +46,12 @@ AC_ARG_PROGRAM case "$target_cpu" in i[[3456]]86) target_cpu=i386 ;; sparc) target_cpu=sparc64 ;; - mipsel) + mipsel|mips64el) target_cpu=mips; TARGET_CFLAGS="$TARGET_CFLAGS -DGRUB_CPU_MIPSEL=1"; CFLAGS="$CFLAGS -DGRUB_CPU_MIPSEL=1"; ;; - mips) + mips|mips64) target_cpu=mips; TARGET_CFLAGS="$TARGET_CFLAGS -DGRUB_CPU_MIPS=1"; CFLAGS="$CFLAGS -DGRUB_CPU_MIPS=1"; From 6abdf8e20d872d2aa991360c394479461fe3125b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 21 Nov 2009 17:33:52 +0100 Subject: [PATCH 098/738] Fix for native miscompilation --- conf/mips.rmk | 2 +- genmoddep.awk | 2 +- include/grub/dl.h | 7 +++++++ include/grub/mips/dl.h | 25 ------------------------- kern/main.c | 3 +++ kern/mips/dl.c | 12 +++++++++--- 6 files changed, 21 insertions(+), 30 deletions(-) delete mode 100644 include/grub/mips/dl.h diff --git a/conf/mips.rmk b/conf/mips.rmk index cd99cca75..233e21180 100644 --- a/conf/mips.rmk +++ b/conf/mips.rmk @@ -17,7 +17,7 @@ kernel_img_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ env.h err.h file.h fs.h kernel.h misc.h mm.h net.h parser.h reader.h \ symbol.h term.h time.h types.h loader.h partition.h \ msdos_partition.h machine/kernel.h handler.h list.h \ - command.h machine/memory.h cpu/libgcc.h cpu/cache.h cpu/dl.h + command.h machine/memory.h cpu/libgcc.h cpu/cache.h symlist.c: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h gensymlist.sh /bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) diff --git a/genmoddep.awk b/genmoddep.awk index f7f085e99..19ac80c71 100644 --- a/genmoddep.awk +++ b/genmoddep.awk @@ -29,7 +29,7 @@ FNR == 1 { if ($1 in symtab) { modtab[module] = modtab[module] " " symtab[$1]; } - else { + else if ($1 != "__gnu_local_gp") { printf "%s in %s is not defined\n", $1, module >"/dev/stderr"; error++; exit; diff --git a/include/grub/dl.h b/include/grub/dl.h index 3f8b328da..5bfcb0cf7 100644 --- a/include/grub/dl.h +++ b/include/grub/dl.h @@ -116,4 +116,11 @@ grub_err_t EXPORT_FUNC(grub_dl_register_symbol) (const char *name, void *addr, grub_err_t grub_arch_dl_check_header (void *ehdr); grub_err_t grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr); +grub_err_t grub_arch_dl_check_header (void *ehdr); + +#if defined (_mips) && ! defined (GRUB_UTIL) +#define GRUB_LINKER_HAVE_INIT 1 +void grub_arch_dl_init_linker (void); +#endif + #endif /* ! GRUB_DL_H */ diff --git a/include/grub/mips/dl.h b/include/grub/mips/dl.h deleted file mode 100644 index 9f8404e72..000000000 --- a/include/grub/mips/dl.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2009 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_CPU_DL_H -#define GRUB_CPU_DL_H 1 - -/* Dummy __gnu_local_gp. Resolved by linker. */ -extern char EXPORT_VAR (__gnu_local_gp); - -#endif /* ! GRUB_CPU_DL_H */ diff --git a/kern/main.c b/kern/main.c index 084ce621b..fa6fba42a 100644 --- a/kern/main.c +++ b/kern/main.c @@ -154,6 +154,9 @@ grub_main (void) /* Load pre-loaded modules and free the space. */ grub_register_exported_symbols (); +#ifdef GRUB_LINKER_HAVE_INIT + grub_arch_dl_init_linker (); +#endif grub_load_modules (); /* Hello. */ diff --git a/kern/mips/dl.c b/kern/mips/dl.c index a937c79b4..f2a0af0d5 100644 --- a/kern/mips/dl.c +++ b/kern/mips/dl.c @@ -23,10 +23,9 @@ #include #include #include -#include /* Dummy __gnu_local_gp. Resolved by linker. */ -char __gnu_local_gp; +static char __gnu_local_gp_dummy; /* Check if EHDR is a valid ELF header. */ grub_err_t @@ -155,7 +154,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) addr = (Elf_Word *) ((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) + if (sym->st_value == (grub_addr_t) &__gnu_local_gp_dummy) sym->st_value = (grub_addr_t) gp; switch (ELF_R_TYPE (rel->r_info)) @@ -224,3 +223,10 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) return GRUB_ERR_NONE; } + +void +grub_arch_dl_init_linker (void) +{ + grub_dl_register_symbol ("__gnu_local_gp", &__gnu_local_gp_dummy, 0); +} + From 87efa251d5ff7474bc5827d6aa1957a12880e3a4 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 21 Nov 2009 17:48:05 +0100 Subject: [PATCH 099/738] Fix a bug in icondir handling --- gfxmenu/icon_manager.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/gfxmenu/icon_manager.c b/gfxmenu/icon_manager.c index b7b891991..0c304ede0 100644 --- a/gfxmenu/icon_manager.c +++ b/gfxmenu/icon_manager.c @@ -137,14 +137,21 @@ static struct grub_video_bitmap * try_loading_icon (grub_gfxmenu_icon_manager_t mgr, const char *dir, const char *class_name) { - char *path = grub_malloc (grub_strlen (dir) - + grub_strlen (class_name) - + grub_strlen (icon_extension) - + 1); + char *path; + int l; + + path = grub_malloc (grub_strlen (dir) + grub_strlen (class_name) + + grub_strlen (icon_extension) + 3); if (! path) return 0; grub_strcpy (path, dir); + l = grub_strlen (path); + if (path[l-1] != '/') + { + path[l] = '/'; + path[l+1] = 0; + } grub_strcat (path, class_name); grub_strcat (path, icon_extension); From f5b23252e2f071650bce4cb9e39ef18f211e95a2 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Sat, 21 Nov 2009 20:59:48 +0000 Subject: [PATCH 100/738] 2009-11-21 Robert Millan * maintainance/gentrigtables.py: Avoid duplicate hardcoding of integer constants. --- ChangeLog.trig | 5 +++++ maintainance/gentrigtables.py | 16 +++++++++------- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/ChangeLog.trig b/ChangeLog.trig index c3cd73594..725e67859 100644 --- a/ChangeLog.trig +++ b/ChangeLog.trig @@ -1,3 +1,8 @@ +2009-11-21 Robert Millan + + * maintainance/gentrigtables.py: Avoid duplicate hardcoding of + integer constants. + 2009-11-14 Colin D Bennet Trigonometry support. diff --git a/maintainance/gentrigtables.py b/maintainance/gentrigtables.py index 7c069f833..81b7bd058 100644 --- a/maintainance/gentrigtables.py +++ b/maintainance/gentrigtables.py @@ -2,7 +2,7 @@ # Script to generate trigonometric function tables. # # GRUB -- GRand Unified Bootloader -# Copyright (C) 2008 Free Software Foundation, Inc. +# Copyright (C) 2008, 2009 Free Software Foundation, Inc. # # GRUB is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -41,14 +41,16 @@ def writeTable(arr, name): def main(): sintab = [] costab = [] - for i in range(256): + angle_max = 256 + fraction_scale = 16384 + for i in range(angle_max): # Convert to an angle in 1/256 of a circle. - x = i * 2 * pi / 256 - sintab.append(int(round(sin(x) * 16384))) - costab.append(int(round(cos(x) * 16384))) + x = i * 2 * pi / angle_max + sintab.append(int(round(sin(x) * fraction_scale))) + costab.append(int(round(cos(x) * fraction_scale))) - write("#define TRIG_ANGLE_MAX 256\n") - write("#define TRIG_FRACTION_SCALE 16384\n") + write("#define TRIG_ANGLE_MAX " + str (angle_max) + "\n") + write("#define TRIG_FRACTION_SCALE " + str (fraction_scale) + "\n") writeTable(sintab, "sintab") writeTable(costab, "costab") From d2be7481856e8c8296a230ed91c410dac81fb207 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Sat, 21 Nov 2009 21:44:08 +0000 Subject: [PATCH 101/738] 2009-11-21 Robert Millan * maintainance/gentrigtables.py: Remove. * lib/trig.c: Likewise. * gentrigtables.c: New file. C rewrite of gentrigtables.py. * conf/common.rmk (trig_mod_SOURCES): Replace `lib/trig.c' with `trigtables.c'. (trigtables.c): New rule. (gentrigtables): Likewise. (DISTCLEANFILES): Add `trigtables.c' and `gentrigtables'. --- ChangeLog.trig | 13 ++++++ conf/common.rmk | 10 ++++- gentrigtables.c | 48 ++++++++++++++++++++ lib/trig.c | 83 ----------------------------------- maintainance/gentrigtables.py | 60 ------------------------- 5 files changed, 69 insertions(+), 145 deletions(-) create mode 100644 gentrigtables.c delete mode 100644 lib/trig.c delete mode 100644 maintainance/gentrigtables.py diff --git a/ChangeLog.trig b/ChangeLog.trig index 725e67859..6aef8f894 100644 --- a/ChangeLog.trig +++ b/ChangeLog.trig @@ -1,3 +1,16 @@ +2009-11-21 Robert Millan + + * maintainance/gentrigtables.py: Remove. + * lib/trig.c: Likewise. + + * gentrigtables.c: New file. C rewrite of gentrigtables.py. + + * conf/common.rmk (trig_mod_SOURCES): Replace `lib/trig.c' with + `trigtables.c'. + (trigtables.c): New rule. + (gentrigtables): Likewise. + (DISTCLEANFILES): Add `trigtables.c' and `gentrigtables'. + 2009-11-21 Robert Millan * maintainance/gentrigtables.py: Avoid duplicate hardcoding of diff --git a/conf/common.rmk b/conf/common.rmk index 439f468dd..e841d5608 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -660,12 +660,18 @@ xnu_uuid_mod_SOURCES = commands/xnu_uuid.c xnu_uuid_mod_CFLAGS = $(COMMON_CFLAGS) xnu_uuid_mod_LDFLAGS = $(COMMON_LDFLAGS) -# For trig.mod. pkglib_MODULES += trig.mod -trig_mod_SOURCES = lib/trig.c +trig_mod_SOURCES = trigtables.c trig_mod_CFLAGS = $(COMMON_CFLAGS) trig_mod_LDFLAGS = $(COMMON_LDFLAGS) +trigtables.c: gentrigtables + ./gentrigtables > $@ +DISTCLEANFILES += trigtables.c +gentrigtables: gentrigtables.c + $(CC) -o $@ $^ $(CPPFLAGS) -lm +DISTCLEANFILES += gentrigtables + pkglib_MODULES += setjmp.mod setjmp_mod_SOURCES = lib/$(target_cpu)/setjmp.S setjmp_mod_ASFLAGS = $(COMMON_ASFLAGS) diff --git a/gentrigtables.c b/gentrigtables.c new file mode 100644 index 000000000..3ef6d08f7 --- /dev/null +++ b/gentrigtables.c @@ -0,0 +1,48 @@ +/* Generate trigonometric function tables. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008, 2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#define _GNU_SOURCE 1 + +#include +#include +#include + +int +main () +{ + int i; + + printf ("#include \n"); + +#define TAB(op) \ + printf ("grub_int16_t grub_trig_" #op "tab[] =\n{"); \ + for (i = 0; i < GRUB_TRIG_ANGLE_MAX; i++) \ + { \ + double x = i * 2 * M_PI / GRUB_TRIG_ANGLE_MAX; \ + if (i % 10 == 0) \ + printf ("\n "); \ + printf ("%d,", (int) (round (op (x) * GRUB_TRIG_FRACTION_SCALE))); \ + } \ + printf ("\n};\n") + + TAB(sin); + TAB(cos); + + exit (0); +} diff --git a/lib/trig.c b/lib/trig.c deleted file mode 100644 index e36aa38ef..000000000 --- a/lib/trig.c +++ /dev/null @@ -1,83 +0,0 @@ -/* trig.c - Trigonometric table definitions. */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2008 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include - -/* These tables were generated with `gentrigtables.py'. */ - -short grub_trig_sintab[] = -{ - 0,402,804,1205,1606,2006,2404,2801,3196,3590, - 3981,4370,4756,5139,5520,5897,6270,6639,7005,7366, - 7723,8076,8423,8765,9102,9434,9760,10080,10394,10702, - 11003,11297,11585,11866,12140,12406,12665,12916,13160,13395, - 13623,13842,14053,14256,14449,14635,14811,14978,15137,15286, - 15426,15557,15679,15791,15893,15986,16069,16143,16207,16261, - 16305,16340,16364,16379,16384,16379,16364,16340,16305,16261, - 16207,16143,16069,15986,15893,15791,15679,15557,15426,15286, - 15137,14978,14811,14635,14449,14256,14053,13842,13623,13395, - 13160,12916,12665,12406,12140,11866,11585,11297,11003,10702, - 10394,10080,9760,9434,9102,8765,8423,8076,7723,7366, - 7005,6639,6270,5897,5520,5139,4756,4370,3981,3590, - 3196,2801,2404,2006,1606,1205,804,402,0,-402, - -804,-1205,-1606,-2006,-2404,-2801,-3196,-3590,-3981,-4370, - -4756,-5139,-5520,-5897,-6270,-6639,-7005,-7366,-7723,-8076, - -8423,-8765,-9102,-9434,-9760,-10080,-10394,-10702,-11003,-11297, - -11585,-11866,-12140,-12406,-12665,-12916,-13160,-13395,-13623,-13842, - -14053,-14256,-14449,-14635,-14811,-14978,-15137,-15286,-15426,-15557, - -15679,-15791,-15893,-15986,-16069,-16143,-16207,-16261,-16305,-16340, - -16364,-16379,-16384,-16379,-16364,-16340,-16305,-16261,-16207,-16143, - -16069,-15986,-15893,-15791,-15679,-15557,-15426,-15286,-15137,-14978, - -14811,-14635,-14449,-14256,-14053,-13842,-13623,-13395,-13160,-12916, - -12665,-12406,-12140,-11866,-11585,-11297,-11003,-10702,-10394,-10080, - -9760,-9434,-9102,-8765,-8423,-8076,-7723,-7366,-7005,-6639, - -6270,-5897,-5520,-5139,-4756,-4370,-3981,-3590,-3196,-2801, - -2404,-2006,-1606,-1205,-804,-402 -}; - -short grub_trig_costab[] = -{ - 16384,16379,16364,16340,16305,16261,16207,16143,16069,15986, - 15893,15791,15679,15557,15426,15286,15137,14978,14811,14635, - 14449,14256,14053,13842,13623,13395,13160,12916,12665,12406, - 12140,11866,11585,11297,11003,10702,10394,10080,9760,9434, - 9102,8765,8423,8076,7723,7366,7005,6639,6270,5897, - 5520,5139,4756,4370,3981,3590,3196,2801,2404,2006, - 1606,1205,804,402,0,-402,-804,-1205,-1606,-2006, - -2404,-2801,-3196,-3590,-3981,-4370,-4756,-5139,-5520,-5897, - -6270,-6639,-7005,-7366,-7723,-8076,-8423,-8765,-9102,-9434, - -9760,-10080,-10394,-10702,-11003,-11297,-11585,-11866,-12140,-12406, - -12665,-12916,-13160,-13395,-13623,-13842,-14053,-14256,-14449,-14635, - -14811,-14978,-15137,-15286,-15426,-15557,-15679,-15791,-15893,-15986, - -16069,-16143,-16207,-16261,-16305,-16340,-16364,-16379,-16384,-16379, - -16364,-16340,-16305,-16261,-16207,-16143,-16069,-15986,-15893,-15791, - -15679,-15557,-15426,-15286,-15137,-14978,-14811,-14635,-14449,-14256, - -14053,-13842,-13623,-13395,-13160,-12916,-12665,-12406,-12140,-11866, - -11585,-11297,-11003,-10702,-10394,-10080,-9760,-9434,-9102,-8765, - -8423,-8076,-7723,-7366,-7005,-6639,-6270,-5897,-5520,-5139, - -4756,-4370,-3981,-3590,-3196,-2801,-2404,-2006,-1606,-1205, - -804,-402,0,402,804,1205,1606,2006,2404,2801, - 3196,3590,3981,4370,4756,5139,5520,5897,6270,6639, - 7005,7366,7723,8076,8423,8765,9102,9434,9760,10080, - 10394,10702,11003,11297,11585,11866,12140,12406,12665,12916, - 13160,13395,13623,13842,14053,14256,14449,14635,14811,14978, - 15137,15286,15426,15557,15679,15791,15893,15986,16069,16143, - 16207,16261,16305,16340,16364,16379 -}; - diff --git a/maintainance/gentrigtables.py b/maintainance/gentrigtables.py deleted file mode 100644 index 81b7bd058..000000000 --- a/maintainance/gentrigtables.py +++ /dev/null @@ -1,60 +0,0 @@ -#!/usr/bin/python -# Script to generate trigonometric function tables. -# -# GRUB -- GRand Unified Bootloader -# Copyright (C) 2008, 2009 Free Software Foundation, Inc. -# -# GRUB is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# GRUB is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GRUB. If not, see . - -from math import * -from sys import stdout - -def write(x): - stdout.write(x) - -def writeTable(arr, name): - indent = ' ' * 4 - write("short ") - write(name) - write("[] =\n{\n") - write(indent) - for i in range(len(arr)): - if i != 0: - write(",") - if i % 10 == 0: - write("\n") - write(indent) - write("%d" % arr[i]) - write("\n};\n") - -def main(): - sintab = [] - costab = [] - angle_max = 256 - fraction_scale = 16384 - for i in range(angle_max): - # Convert to an angle in 1/256 of a circle. - x = i * 2 * pi / angle_max - sintab.append(int(round(sin(x) * fraction_scale))) - costab.append(int(round(cos(x) * fraction_scale))) - - write("#define TRIG_ANGLE_MAX " + str (angle_max) + "\n") - write("#define TRIG_FRACTION_SCALE " + str (fraction_scale) + "\n") - writeTable(sintab, "sintab") - writeTable(costab, "costab") - -if __name__ == "__main__": - main() - -# vim:ai et sw=4 ts=4 From befd7fb24a66b5bcfb22a48afff5fe92b6cebf98 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 22 Nov 2009 02:54:03 +0100 Subject: [PATCH 102/738] Fixed path to grub-mkrawimage.c --- po/POTFILES | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/po/POTFILES b/po/POTFILES index 5b1239a5e..241b192d8 100644 --- a/po/POTFILES +++ b/po/POTFILES @@ -1,5 +1,5 @@ # List of files which contain translatable strings. -util/i386/pc/grub-mkimage.c +util/grub-mkrawimage.c util/i386/pc/grub-setup.c util/mkisofs/eltorito.c From 6755a5c359ff0cca213e338269524005b56a9486 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 22 Nov 2009 02:55:07 +0100 Subject: [PATCH 103/738] Fixed grub-mkimage source list --- conf/mips.rmk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/mips.rmk b/conf/mips.rmk index 233e21180..02c96d2eb 100644 --- a/conf/mips.rmk +++ b/conf/mips.rmk @@ -106,7 +106,7 @@ bin_SCRIPTS = # For grub-mkimage. bin_UTILITIES += grub-mkimage -grub_mkimage_SOURCES = util/grub-mkrawimage.c util/misc.c \ +grub_mkimage_SOURCES = gnulib/progname.c util/grub-mkrawimage.c util/misc.c \ util/resolve.c lib/LzmaEnc.c lib/LzFind.c grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(LINK_BASE) util/i386/pc/grub-mkimage.c_DEPENDENCIES = Makefile From 42810eb1a0c7c789a177a19a15d76cf2db42a99b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 22 Nov 2009 02:56:49 +0100 Subject: [PATCH 104/738] Improved cache handling --- kern/mips/cache.S | 2 -- lib/mips/relocator_asm.S | 10 ++++------ 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/kern/mips/cache.S b/kern/mips/cache.S index e4436450f..a226069fd 100644 --- a/kern/mips/cache.S +++ b/kern/mips/cache.S @@ -6,8 +6,6 @@ FUNCTION (grub_arch_sync_caches) repeat: cache 1, 0($a0) cache 0, 0($a0) - cache 3, 0($a0) - cache 0, 0($a0) addiu $a0, $a0, 1 addiu $a1, $a1, 0xffff bne $a1, $zero, repeat diff --git a/lib/mips/relocator_asm.S b/lib/mips/relocator_asm.S index 6f6108edc..f901fbe89 100644 --- a/lib/mips/relocator_asm.S +++ b/lib/mips/relocator_asm.S @@ -30,14 +30,13 @@ VARIABLE (grub_relocator32_forward_start) copycont1: lb $11,0($8) sb $11,0($9) + cache 1, 0($9) + cache 0, 0($9) addiu $8, $8, 0x1 addiu $9, $9, 0x1 addiu $10, $10, 0xffff subu $11,$10,$0 bne $11, $0, copycont1 -#if __mips >= 2 - sync -#endif VARIABLE (grub_relocator32_forward_end) VARIABLE (grub_relocator32_backward_start) @@ -49,12 +48,11 @@ VARIABLE (grub_relocator32_backward_start) copycont2: lb $11,0($8) sb $11,0($9) + cache 1, 0($9) + cache 0, 0($9) addiu $8, $8, 0xffff addiu $9, $9, 0xffff addiu $10, 0xffff subu $11,$10,$0 bne $11, $0, copycont2 -#if __mips >= 2 - sync -#endif VARIABLE (grub_relocator32_backward_end) From 8719095cc8942b5b8d23fc48ebf90e1bcda3d0a5 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 22 Nov 2009 15:05:20 +0100 Subject: [PATCH 105/738] Hopefully fixed cache problems in relocator --- lib/mips/relocator.c | 5 +++++ lib/mips/relocator_asm.S | 29 +++++++++++++++++++++-------- lib/relocator.c | 17 +++++++++++++++++ 3 files changed, 43 insertions(+), 8 deletions(-) diff --git a/lib/mips/relocator.c b/lib/mips/relocator.c index 4a67418c4..61c93e39f 100644 --- a/lib/mips/relocator.c +++ b/lib/mips/relocator.c @@ -22,6 +22,7 @@ #include #include #include +#include #include @@ -80,6 +81,8 @@ write_call_relocator_bw (void *ptr0, void *src, grub_uint32_t dest, for (i = 1; i < 32; i++) write_reg (i, state.gpr[i], &ptr); write_jump (state.jumpreg, &ptr); + grub_arch_sync_caches (ptr0, ptr - ptr0); + grub_dprintf ("relocator", "Backward relocator: about to jump to %p\n", ptr0); ((void (*) (void)) ptr0) (); } @@ -98,6 +101,8 @@ write_call_relocator_fw (void *ptr0, void *src, grub_uint32_t dest, for (i = 1; i < 32; i++) write_reg (i, state.gpr[i], &ptr); write_jump (state.jumpreg, &ptr); + grub_arch_sync_caches (ptr0, ptr - ptr0); + grub_dprintf ("relocator", "Forward relocator: about to jump to %p\n", ptr0); ((void (*) (void)) ptr0) (); } diff --git a/lib/mips/relocator_asm.S b/lib/mips/relocator_asm.S index f901fbe89..f9cdf1470 100644 --- a/lib/mips/relocator_asm.S +++ b/lib/mips/relocator_asm.S @@ -17,29 +17,35 @@ */ #include - -#ifdef BACKWARD -#define RELOCATOR_VARIABLE(x) VARIABLE(grub_relocator32_backward_ ## x) -#else -#define RELOCATOR_VARIABLE(x) VARIABLE(grub_relocator32_forward_ ## x) -#endif .p2align 4 /* force 16-byte alignment */ VARIABLE (grub_relocator32_forward_start) + move $12, $9 + move $13, $10 + copycont1: lb $11,0($8) sb $11,0($9) - cache 1, 0($9) - cache 0, 0($9) addiu $8, $8, 0x1 addiu $9, $9, 0x1 addiu $10, $10, 0xffff subu $11,$10,$0 bne $11, $0, copycont1 + +cachecont1: + cache 1,0($12) + cache 0,0($12) + addiu $12, $12, 0x1 + addiu $13, $13, 0xffff + subu $11,$13,$0 + bne $11, $0, cachecont1 VARIABLE (grub_relocator32_forward_end) VARIABLE (grub_relocator32_backward_start) + move $12, $9 + move $13, $10 + addu $9, $9, $10 addu $8, $8, $10 /* Backward movsl is implicitly off-by-one. compensate that. */ @@ -55,4 +61,11 @@ copycont2: addiu $10, 0xffff subu $11,$10,$0 bne $11, $0, copycont2 +cachecont2: + cache 1,0($12) + cache 0,0($12) + addiu $12, $12, 0x1 + addiu $13, $13, 0xffff + subu $11,$13,$0 + bne $11, $0, cachecont2 VARIABLE (grub_relocator32_backward_end) diff --git a/lib/relocator.c b/lib/relocator.c index e551f337f..bebf7ada9 100644 --- a/lib/relocator.c +++ b/lib/relocator.c @@ -69,12 +69,23 @@ PREFIX (boot) (void *relocator, grub_uint32_t dest, playground = (char *) relocator - RELOCATOR_SIZEOF (forward); size = *(grub_size_t *) playground; + grub_dprintf ("relocator", + "Relocator: source: %p, destination: 0x%x, size: 0x%x\n", + relocator, dest, size); + if (UINT_TO_PTR (dest) >= relocator) { int overhead; overhead = ALIGN_UP (dest - RELOCATOR_SIZEOF (backward) - RELOCATOR_ALIGN, RELOCATOR_ALIGN); + grub_dprintf ("relocator", + "Backward relocator: code %p, source: %p, " + "destination: 0x%x, size: 0x%x\n", + (char *) relocator - overhead, + (char *) relocator - overhead, + dest - overhead, size + overhead); + write_call_relocator_bw ((char *) relocator - overhead, (char *) relocator - overhead, dest - overhead, size + overhead, state); @@ -85,6 +96,12 @@ PREFIX (boot) (void *relocator, grub_uint32_t dest, overhead = ALIGN_UP (dest + size, RELOCATOR_ALIGN) + RELOCATOR_SIZEOF (forward) - (dest + size); + grub_dprintf ("relocator", + "Forward relocator: code %p, source: %p, " + "destination: 0x%x, size: 0x%x\n", + (char *) relocator + size + overhead + - RELOCATOR_SIZEOF (forward), + relocator, dest, size + overhead); write_call_relocator_fw ((char *) relocator + size + overhead - RELOCATOR_SIZEOF (forward), From 1c805a5a3ec6de0f2ef1a0bae67625b199fbf6c1 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 23 Nov 2009 00:16:49 +0100 Subject: [PATCH 106/738] Fixed cache invalidating --- kern/mips/cache.S | 31 ++++++++++++++++++++++++------- lib/mips/relocator.c | 4 ++-- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/kern/mips/cache.S b/kern/mips/cache.S index a226069fd..8353e1b04 100644 --- a/kern/mips/cache.S +++ b/kern/mips/cache.S @@ -3,10 +3,27 @@ /* FIXME: This should invalidate only part of memory. */ FUNCTION (grub_cpu_flush_cache) FUNCTION (grub_arch_sync_caches) -repeat: - cache 1, 0($a0) - cache 0, 0($a0) - addiu $a0, $a0, 1 - addiu $a1, $a1, 0xffff - bne $a1, $zero, repeat - j $31 + move $t2, $a0 + addu $t3, $a0, $a1 + srl $t2, $t2, 5 + sll $t2, $t2, 5 + addu $t3, $t3, 0x1f + srl $t3, $t3, 5 + sll $t3, $t3, 5 + move $t0, $t2 + subu $t1, $t3, $t2 +r1: + cache 1, 0($t0) + addiu $t0, $t0, 0x1 + addiu $t1, $t1, 0xffff + bne $t1, $zero, r1 + sync + move $t0, $t2 + subu $t1, $t3, $t2 +r2: + cache 0, 0($t0) + addiu $t0, $t0, 0x1 + addiu $t1, $t1, 0xffff + bne $t1, $zero, r2 + sync + j $ra diff --git a/lib/mips/relocator.c b/lib/mips/relocator.c index 61c93e39f..796473bf7 100644 --- a/lib/mips/relocator.c +++ b/lib/mips/relocator.c @@ -81,7 +81,7 @@ write_call_relocator_bw (void *ptr0, void *src, grub_uint32_t dest, for (i = 1; i < 32; i++) write_reg (i, state.gpr[i], &ptr); write_jump (state.jumpreg, &ptr); - grub_arch_sync_caches (ptr0, ptr - ptr0); + grub_arch_sync_caches (ptr0, (grub_uint8_t *) ptr - (grub_uint8_t *) ptr0); grub_dprintf ("relocator", "Backward relocator: about to jump to %p\n", ptr0); ((void (*) (void)) ptr0) (); } @@ -101,7 +101,7 @@ write_call_relocator_fw (void *ptr0, void *src, grub_uint32_t dest, for (i = 1; i < 32; i++) write_reg (i, state.gpr[i], &ptr); write_jump (state.jumpreg, &ptr); - grub_arch_sync_caches (ptr0, ptr - ptr0); + grub_arch_sync_caches (ptr0, (grub_uint8_t *) ptr - (grub_uint8_t *) ptr0); grub_dprintf ("relocator", "Forward relocator: about to jump to %p\n", ptr0); ((void (*) (void)) ptr0) (); } From 8eea9034f874cece57c42bc2ce447128bb914cba Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 23 Nov 2009 20:18:10 +0100 Subject: [PATCH 107/738] Use LOCAL in relocator --- lib/i386/relocator_asm.S | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/lib/i386/relocator_asm.S b/lib/i386/relocator_asm.S index 72c057ce2..343991d3d 100644 --- a/lib/i386/relocator_asm.S +++ b/lib/i386/relocator_asm.S @@ -48,7 +48,7 @@ RELOCATOR_VARIABLE(start) #ifdef BACKWARD -L_base: +LOCAL(base): #endif cli @@ -127,23 +127,23 @@ RELOCATOR_VARIABLE(size) /* %rax contains now our new 'base'. */ mov RAX, RSI - add $(L_cont0 - L_base), RAX + add $(LOCAL(cont0) - LOCAL(base)), RAX jmp *RAX -L_cont0: - lea (L_cont1 - L_base) (RSI, 1), RAX - movl %eax, (L_jump_vector - L_base) (RSI, 1) +LOCAL(cont0): + lea (LOCAL(cont1) - LOCAL(base)) (RSI, 1), RAX + movl %eax, (LOCAL(jump_vector) - LOCAL(base)) (RSI, 1) - lea (L_gdt - L_base) (RSI, 1), RAX - mov RAX, (L_gdt_addr - L_base) (RSI, 1) + lea (LOCAL(gdt) - LOCAL(base)) (RSI, 1), RAX + mov RAX, (LOCAL(gdt_addr) - LOCAL(base)) (RSI, 1) /* Switch to compatibility mode. */ - lgdt (L_gdtdesc - L_base) (RSI, 1) + lgdt (LOCAL(gdtdesc) - LOCAL(base)) (RSI, 1) /* Update %cs. Thanks to David Miller for pointing this mistake out. */ - ljmp *(L_jump_vector - L_base) (RSI, 1) + ljmp *(LOCAL(jump_vector) - LOCAL(base)) (RSI, 1) -L_cont1: +LOCAL(cont1): .code32 /* Update other registers. */ @@ -170,8 +170,8 @@ L_cont1: andl $GRUB_MEMORY_CPU_CR4_PAE_ON, %eax movl %eax, %cr4 - jmp L_cont2 -L_cont2: + jmp LOCAL(cont2) +LOCAL(cont2): .code32 /* mov imm32, %eax */ @@ -212,7 +212,7 @@ RELOCATOR_VARIABLE (eip) /* GDT. Copied from loader/i386/linux.c. */ .p2align 4 -L_gdt: +LOCAL(gdt): /* NULL. */ .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 @@ -226,9 +226,9 @@ L_gdt: .byte 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x92, 0xCF, 0x00 .p2align 4 -L_gdtdesc: +LOCAL(gdtdesc): .word 0x27 -L_gdt_addr: +LOCAL(gdt_addr): #ifdef __x86_64__ /* Filled by the code. */ .quad 0 @@ -238,13 +238,13 @@ L_gdt_addr: #endif .p2align 4 -L_jump_vector: +LOCAL(jump_vector): /* Jump location. Is filled by the code */ .long 0 .long CODE_SEGMENT #ifndef BACKWARD -L_base: +LOCAL(base): #endif RELOCATOR_VARIABLE(end) From a5c894bcd986b2ad3bba9d17d732d5542b39e168 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 24 Nov 2009 04:19:33 +0100 Subject: [PATCH 108/738] Enable gfxmenu on grub-emu --- conf/any-emu.rmk | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/conf/any-emu.rmk b/conf/any-emu.rmk index 82e297986..d79ec542b 100644 --- a/conf/any-emu.rmk +++ b/conf/any-emu.rmk @@ -45,6 +45,14 @@ grub_emu_SOURCES = commands/minicmd.c commands/cat.c commands/cmp.c \ video/readers/jpeg.c video/readers/png.c font/font_cmd.c \ font/font.c term/gfxterm.c io/bufio.c \ \ + gfxmenu/gfxmenu.c gfxmenu/model.c gfxmenu/view.c \ + gfxmenu/icon_manager.c gfxmenu/theme_loader.c \ + gfxmenu/widget-box.c gfxmenu/gui_canvas.c \ + gfxmenu/gui_circular_progress.c gfxmenu/gui_box.c \ + gfxmenu/gui_label.c gfxmenu/gui_list.c gfxmenu/gui_image.c \ + gfxmenu/gui_progress_bar.c gfxmenu/gui_util.c \ + gfxmenu/gui_string_util.c gfxmenu/named_colors.c trigtables.c \ + \ util/console.c util/hostfs.c util/grub-emu.c util/misc.c \ util/hostdisk.c util/getroot.c \ \ @@ -87,6 +95,13 @@ DISTCLEANFILES += grub_emu_init.c # FIXME: this could be shared with common.rmk +trigtables.c: gentrigtables + ./gentrigtables > $@ +DISTCLEANFILES += trigtables.c +gentrigtables: gentrigtables.c + $(CC) -o $@ $^ $(CPPFLAGS) -lm +DISTCLEANFILES += gentrigtables + # For grub-mkfont. ifeq ($(enable_grub_mkfont), yes) bin_UTILITIES += grub-mkfont From a9c12f853332e801a4a300ace7fadfc8d9d5738f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 24 Nov 2009 04:20:18 +0100 Subject: [PATCH 109/738] Remove hardcoded hotkeys --- gfxmenu/gfxmenu.c | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/gfxmenu/gfxmenu.c b/gfxmenu/gfxmenu.c index 85ce5879d..c854c68da 100644 --- a/gfxmenu/gfxmenu.c +++ b/gfxmenu/gfxmenu.c @@ -92,26 +92,6 @@ process_key_press (int c, switch_to_text_menu (); *should_exit = 1; } - else if (c == '1') - { - grub_gfxmenu_view_load_theme (view, - "/boot/grub/themes/proto/theme.txt"); - } - else if (c == '2') - { - grub_gfxmenu_view_load_theme (view, - "/boot/grub/themes/winter/theme.txt"); - } - else if (c == '3') - { - grub_gfxmenu_view_load_theme (view, - "/boot/grub/themes/ubuntu1/theme.txt"); - } - else if (c == '4') - { - grub_gfxmenu_view_load_theme (view, - "/boot/grub/themes/ubuntu2/theme.txt"); - } else if (nested && c == GRUB_TERM_ESC) { *should_exit = 1; From 8f41eb558284ffca53d8e80a98a6924b286f09ab Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 24 Nov 2009 04:21:07 +0100 Subject: [PATCH 110/738] Use return instead of exit () in gentrigtables.c --- gentrigtables.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gentrigtables.c b/gentrigtables.c index 3ef6d08f7..772cd6224 100644 --- a/gentrigtables.c +++ b/gentrigtables.c @@ -44,5 +44,5 @@ main () TAB(sin); TAB(cos); - exit (0); + return 0; } From 93fd2dd8095288fd823b746a30a3f8430d9c11fd Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 24 Nov 2009 04:22:22 +0100 Subject: [PATCH 111/738] Optimise gfxterm in gfxmenu by avoiding indirect repainting --- gfxmenu/view.c | 93 +++++++++++++++++++++++++------------------------- 1 file changed, 46 insertions(+), 47 deletions(-) diff --git a/gfxmenu/view.c b/gfxmenu/view.c index 56edc86cf..e807d3838 100644 --- a/gfxmenu/view.c +++ b/gfxmenu/view.c @@ -42,6 +42,8 @@ status changes. */ #define TIMEOUT_COMPONENT_ID "__timeout__" +static grub_gfxmenu_view_t term_view; + static void init_terminal (grub_gfxmenu_view_t view); static void destroy_terminal (void); static grub_err_t set_graphics_mode (void); @@ -310,86 +312,82 @@ set_text_mode (void) static int term_target_width; static int term_target_height; -static struct grub_video_render_target *term_target; static int term_initialized; static grub_term_output_t term_original; -static grub_gfxmenu_view_t term_view; static void -repaint_terminal (int x __attribute ((unused)), - int y __attribute ((unused)), - int width __attribute ((unused)), - int height __attribute ((unused))) +draw_terminal_box (void) { - if (! term_view) + grub_gfxmenu_box_t term_box; + int termx; + int termy; + + term_box = term_view->terminal_box; + if (!term_box) return; - grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY); - grub_gfxmenu_view_draw (term_view); - grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY); - - int termx = term_view->screen.x - + term_view->screen.width * (10 - 7) / 10 / 2; - int termy = term_view->screen.y - + term_view->screen.height * (10 - 7) / 10 / 2; - - grub_gfxmenu_box_t term_box = term_view->terminal_box; - if (term_box) - { - term_box->set_content_size (term_box, - term_target_width, term_target_height); - - term_box->draw (term_box, - termx - term_box->get_left_pad (term_box), - termy - term_box->get_top_pad (term_box)); - } - - grub_video_blit_render_target (term_target, GRUB_VIDEO_BLIT_REPLACE, - termx, termy, - 0, 0, term_target_width, term_target_height); - grub_video_swap_buffers (); + termx = term_view->screen.x + term_view->screen.width * (10 - 7) / 10 / 2; + termy = term_view->screen.y + term_view->screen.height * (10 - 7) / 10 / 2; + + term_box->set_content_size (term_box, term_target_width, + term_target_height); + + term_box->draw (term_box, + termx - term_box->get_left_pad (term_box), + termy - term_box->get_top_pad (term_box)); } static void init_terminal (grub_gfxmenu_view_t view) { + int termx; + int termy; + struct grub_video_mode_info mode_info; + grub_err_t err; + int double_repaint; + term_original = grub_term_get_current_output (); term_target_width = view->screen.width * 7 / 10; term_target_height = view->screen.height * 7 / 10; - grub_video_create_render_target (&term_target, - term_target_width, - term_target_height, - GRUB_VIDEO_MODE_TYPE_RGB - | GRUB_VIDEO_MODE_TYPE_ALPHA); - if (grub_errno != GRUB_ERR_NONE) - return; + termx = view->screen.x + view->screen.width * (10 - 7) / 10 / 2; + termy = view->screen.y + view->screen.height * (10 - 7) / 10 / 2; + + err = grub_video_get_info (&mode_info); + if (err) + { + grub_errno = GRUB_ERR_NONE; + double_repaint = 1; + } + else + double_repaint = (mode_info.mode_type + & GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED) + && !(mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP); /* Note: currently there is no API for changing the gfxterm font on the fly, so whatever font the initially loaded theme specifies will be permanent. */ - grub_gfxterm_init_window (term_target, 0, 0, - term_target_width, term_target_height, 0, - view->terminal_font_name, 3); + grub_gfxterm_init_window (GRUB_VIDEO_RENDER_TARGET_DISPLAY, termx, termy, + term_target_width, term_target_height, + double_repaint, view->terminal_font_name, 3); if (grub_errno != GRUB_ERR_NONE) return; term_initialized = 1; - /* XXX: store static pointer to the 'view' object so the repaint callback can access it. */ + grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY); + grub_gfxmenu_view_draw (view); + grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY); + term_view = view; - grub_gfxterm_set_repaint_callback (repaint_terminal); + grub_term_set_current_output (grub_gfxterm_get_term ()); } static void destroy_terminal (void) { - term_view = 0; if (term_initialized) grub_gfxterm_destroy_window (); - grub_gfxterm_set_repaint_callback (0); - if (term_target) - grub_video_delete_render_target (term_target); if (term_original) grub_term_set_current_output (term_original); } @@ -493,5 +491,6 @@ grub_gfxmenu_view_execute_entry (grub_gfxmenu_view_t view, void grub_gfxmenu_view_run_terminal (grub_gfxmenu_view_t view __attribute__((unused))) { + draw_terminal_box (); grub_cmdline_run (1); } From 4545f150f38e536b38d54f2a578671f578918fcf Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 24 Nov 2009 05:02:30 +0100 Subject: [PATCH 112/738] Various cleanups --- gfxmenu/gfxmenu.c | 113 +++++++++++++++++++++++++--------------------- 1 file changed, 62 insertions(+), 51 deletions(-) diff --git a/gfxmenu/gfxmenu.c b/gfxmenu/gfxmenu.c index c854c68da..6f7382c18 100644 --- a/gfxmenu/gfxmenu.c +++ b/gfxmenu/gfxmenu.c @@ -51,50 +51,63 @@ process_key_press (int c, /* When a key is pressed, stop the timeout. */ grub_gfxmenu_model_clear_timeout (model); - if (c == 'j' || c == GRUB_TERM_DOWN) - { - int i = grub_gfxmenu_model_get_selected_index (model); - int num_items = grub_gfxmenu_model_get_num_entries (model); - if (i < num_items - 1) - { - i++; - grub_gfxmenu_model_set_selected_index (model, i); - } - } - else if (c == 'k' || c == GRUB_TERM_UP) - { - int i = grub_gfxmenu_model_get_selected_index (model); - if (i > 0) - { - i--; - grub_gfxmenu_model_set_selected_index (model, i); - } - } - else if (c == '\r' || c == '\n' || c == GRUB_TERM_RIGHT) - { - int selected = grub_gfxmenu_model_get_selected_index (model); - int num_entries = grub_gfxmenu_model_get_num_entries (model); - if (selected >= 0 && selected < num_entries) - { - grub_menu_entry_t entry = - grub_gfxmenu_model_get_entry (model, selected); - grub_gfxmenu_view_execute_entry (view, entry); - } - } - else if (c == 'c') + switch (c) { + case 'j': + case GRUB_TERM_DOWN: + { + int i = grub_gfxmenu_model_get_selected_index (model); + int num_items = grub_gfxmenu_model_get_num_entries (model); + if (i < num_items - 1) + { + i++; + grub_gfxmenu_model_set_selected_index (model, i); + } + } + break; + + case 'k': + case GRUB_TERM_UP: + { + int i = grub_gfxmenu_model_get_selected_index (model); + if (i > 0) + { + i--; + grub_gfxmenu_model_set_selected_index (model, i); + } + } + break; + + case '\r': + case '\n': + case GRUB_TERM_RIGHT: + { + int selected = grub_gfxmenu_model_get_selected_index (model); + int num_entries = grub_gfxmenu_model_get_num_entries (model); + if (selected >= 0 && selected < num_entries) + { + grub_menu_entry_t entry = + grub_gfxmenu_model_get_entry (model, selected); + grub_gfxmenu_view_execute_entry (view, entry); + } + } + break; + + case 'c': grub_gfxmenu_view_run_terminal (view); - } - else if (c == 't') - { + break; + + case 't': /* The write hook for 'menuviewer' will cause * grub_menu_viewer_should_return to return nonzero. */ switch_to_text_menu (); *should_exit = 1; - } - else if (nested && c == GRUB_TERM_ESC) - { - *should_exit = 1; + break; + + case GRUB_TERM_ESC: + if (nested) + *should_exit = 1; + break; } if (grub_errno != GRUB_ERR_NONE) @@ -119,32 +132,29 @@ static grub_err_t show_menu (grub_menu_t menu, int nested) { grub_gfxmenu_model_t model; + grub_gfxmenu_view_t view; + const char *theme_path; + + theme_path = grub_env_get ("theme"); + if (! theme_path) + { + switch_to_text_menu (); + return grub_error (GRUB_ERR_FILE_NOT_FOUND, "no theme specified"); + } model = grub_gfxmenu_model_new (menu); if (! model) { - grub_print_error (); - grub_printf ("Initializing menu data for graphical menu failed;\n" - "falling back to text based menu.\n"); - grub_wait_after_message (); switch_to_text_menu (); return grub_errno; } - grub_gfxmenu_view_t view; - /* Create the view. */ - const char *theme_path = grub_env_get ("theme"); - if (! theme_path) - theme_path = "/boot/grub/themes/proto/theme.txt"; - view = grub_gfxmenu_view_new (theme_path, model); + if (! view) { grub_print_error (); - grub_printf ("Starting graphical menu failed;\n" - "falling back to text based menu.\n"); - grub_wait_after_message (); grub_gfxmenu_model_destroy (model); switch_to_text_menu (); return grub_errno; @@ -159,6 +169,7 @@ show_menu (grub_menu_t menu, int nested) /* Main event loop. */ int exit_requested = 0; + while ((! exit_requested) && (! grub_menu_viewer_should_return ())) { if (grub_gfxmenu_model_timeout_expired (model)) From 947fa16c8b8bf6a0f91ca7b01da8c47f8cc9361c Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 24 Nov 2009 07:17:18 +0100 Subject: [PATCH 113/738] Important speedup by not redrawing too much --- gfxmenu/gfxmenu.c | 12 +- gfxmenu/gui_box.c | 4 +- gfxmenu/gui_canvas.c | 5 +- gfxmenu/gui_circular_progress.c | 6 +- gfxmenu/gui_image.c | 8 +- gfxmenu/gui_label.c | 5 +- gfxmenu/gui_list.c | 6 +- gfxmenu/gui_progress_bar.c | 4 +- gfxmenu/view.c | 214 +++++++++++++++++++++++--------- include/grub/gfxmenu_view.h | 14 +++ include/grub/gui.h | 16 ++- 11 files changed, 221 insertions(+), 73 deletions(-) diff --git a/gfxmenu/gfxmenu.c b/gfxmenu/gfxmenu.c index 6f7382c18..ab1c8befb 100644 --- a/gfxmenu/gfxmenu.c +++ b/gfxmenu/gfxmenu.c @@ -35,6 +35,7 @@ #include #include #include +#include static void switch_to_text_menu (void) { @@ -62,6 +63,7 @@ process_key_press (int c, { i++; grub_gfxmenu_model_set_selected_index (model, i); + grub_gfxmenu_redraw_menu (view); } } break; @@ -74,6 +76,7 @@ process_key_press (int c, { i--; grub_gfxmenu_model_set_selected_index (model, i); + grub_gfxmenu_redraw_menu (view); } } break; @@ -170,8 +173,14 @@ show_menu (grub_menu_t menu, int nested) /* Main event loop. */ int exit_requested = 0; + grub_gfxmenu_view_draw (view); + grub_video_swap_buffers (); + if (view->double_repaint) + grub_gfxmenu_view_draw (view); + while ((! exit_requested) && (! grub_menu_viewer_should_return ())) { + grub_gfxmenu_redraw_timeout (view); if (grub_gfxmenu_model_timeout_expired (model)) { grub_gfxmenu_model_clear_timeout (model); @@ -181,9 +190,8 @@ show_menu (grub_menu_t menu, int nested) continue; } - grub_gfxmenu_view_draw (view); - grub_video_swap_buffers (); handle_key_events (model, view, nested, &exit_requested); + grub_cpu_idle (); } grub_gfxmenu_view_destroy (view); diff --git a/gfxmenu/gui_box.c b/gfxmenu/gui_box.c index 876d0733f..4fe131f98 100644 --- a/gfxmenu/gui_box.c +++ b/gfxmenu/gui_box.c @@ -166,7 +166,7 @@ layout_vertically (grub_gui_box_t self, int modify_layout, } static void -box_paint (void *vself) +box_paint (void *vself, const grub_video_rect_t *region) { grub_gui_box_t self = vself; struct component_node *cur; @@ -176,7 +176,7 @@ box_paint (void *vself) for (cur = self->chead.next; cur != &self->ctail; cur = cur->next) { grub_gui_component_t comp = cur->component; - comp->ops->paint (comp); + comp->ops->paint (comp, region); } grub_gui_restore_viewport (&vpsave); } diff --git a/gfxmenu/gui_canvas.c b/gfxmenu/gui_canvas.c index a2cd77df6..d155364d7 100644 --- a/gfxmenu/gui_canvas.c +++ b/gfxmenu/gui_canvas.c @@ -79,7 +79,7 @@ canvas_is_instance (void *vself __attribute__((unused)), const char *type) } static void -canvas_paint (void *vself) +canvas_paint (void *vself, const grub_video_rect_t *region) { grub_gui_canvas_t self = vself; struct component_node *cur; @@ -106,7 +106,8 @@ canvas_paint (void *vself) } /* Paint the child. */ - comp->ops->paint (comp); + if (grub_video_have_common_points (region, &r)) + comp->ops->paint (comp, region); } grub_gui_restore_viewport (&vpsave); } diff --git a/gfxmenu/gui_circular_progress.c b/gfxmenu/gui_circular_progress.c index cd95c51f9..f3c8bc3af 100644 --- a/gfxmenu/gui_circular_progress.c +++ b/gfxmenu/gui_circular_progress.c @@ -112,12 +112,16 @@ check_pixmaps (circular_progress_t self) } static void -circprog_paint (void *vself) +circprog_paint (void *vself, const grub_video_rect_t *region) { circular_progress_t self = vself; if (! self->visible) return; + + if (!grub_video_have_common_points (region, &self->bounds)) + return; + if (! check_pixmaps (self)) return; diff --git a/gfxmenu/gui_image.c b/gfxmenu/gui_image.c index 1c58a535b..eb2ff1ee0 100644 --- a/gfxmenu/gui_image.c +++ b/gfxmenu/gui_image.c @@ -67,12 +67,16 @@ image_is_instance (void *vself __attribute__((unused)), const char *type) } static void -image_paint (void *vself) +image_paint (void *vself, const grub_video_rect_t *region) { grub_gui_image_t self = vself; + grub_video_rect_t vpsave; + if (! self->bitmap) return; - grub_video_rect_t vpsave; + if (!grub_video_have_common_points (region, &self->bounds)) + return; + grub_gui_set_viewport (&self->bounds, &vpsave); grub_video_blit_bitmap (self->bitmap, GRUB_VIDEO_BLIT_BLEND, 0, 0, 0, 0, diff --git a/gfxmenu/gui_label.c b/gfxmenu/gui_label.c index eb2a495ff..30474f52f 100644 --- a/gfxmenu/gui_label.c +++ b/gfxmenu/gui_label.c @@ -77,13 +77,16 @@ label_is_instance (void *vself __attribute__((unused)), const char *type) } static void -label_paint (void *vself) +label_paint (void *vself, const grub_video_rect_t *region) { grub_gui_label_t self = vself; if (! self->visible) return; + if (!grub_video_have_common_points (region, &self->bounds)) + return; + /* Calculate the starting x coordinate. */ int left_x; if (self->align == align_left) diff --git a/gfxmenu/gui_list.c b/gfxmenu/gui_list.c index aa9655b45..bf6d94657 100644 --- a/gfxmenu/gui_list.c +++ b/gfxmenu/gui_list.c @@ -311,16 +311,18 @@ draw_menu (list_impl_t self) } static void -list_paint (void *vself) +list_paint (void *vself, const grub_video_rect_t *region) { list_impl_t self = vself; + grub_video_rect_t vpsave; if (! self->visible) return; + if (!grub_video_have_common_points (region, &self->bounds)) + return; check_boxes (self); - grub_video_rect_t vpsave; grub_gui_set_viewport (&self->bounds, &vpsave); draw_menu (self); grub_gui_restore_viewport (&vpsave); diff --git a/gfxmenu/gui_progress_bar.c b/gfxmenu/gui_progress_bar.c index 440d4b2fc..498711169 100644 --- a/gfxmenu/gui_progress_bar.c +++ b/gfxmenu/gui_progress_bar.c @@ -171,11 +171,13 @@ draw_text (grub_gui_progress_bar_t self) } static void -progress_bar_paint (void *vself) +progress_bar_paint (void *vself, const grub_video_rect_t *region) { grub_gui_progress_bar_t self = vself; if (! self->visible) return; + if (!grub_video_have_common_points (region, &self->bounds)) + return; grub_video_rect_t vpsave; grub_gui_set_viewport (&self->bounds, &vpsave); diff --git a/gfxmenu/view.c b/gfxmenu/view.c index e807d3838..1c512fee1 100644 --- a/gfxmenu/view.c +++ b/gfxmenu/view.c @@ -55,6 +55,8 @@ grub_gfxmenu_view_t grub_gfxmenu_view_new (const char *theme_path, grub_gfxmenu_model_t model) { grub_gfxmenu_view_t view; + grub_err_t err; + struct grub_video_mode_info mode_info; view = grub_malloc (sizeof (*view)); if (! view) @@ -67,6 +69,18 @@ grub_gfxmenu_view_new (const char *theme_path, grub_gfxmenu_model_t model) (unsigned *) &view->screen.width, (unsigned *) &view->screen.height); + err = grub_video_get_info (&mode_info); + if (err) + { + grub_free (view); + return 0; + } + else + view->double_repaint = (mode_info.mode_type + & GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED) + && !(mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP); + + /* Clear the screen; there may be garbage left over in video memory, and loading the menu style (particularly the background) can take a while. */ grub_video_fill_rect (grub_video_map_rgb (0, 0, 0), @@ -97,6 +111,15 @@ grub_gfxmenu_view_new (const char *theme_path, grub_gfxmenu_model_t model) view->title_text = grub_strdup ("GRUB Boot Menu"); view->progress_message_text = 0; view->theme_path = 0; + view->last_seconds_remaining = -2; + + /* Set the timeout bar's frame. */ + view->progress_message_frame.width = view->screen.width * 4 / 5; + view->progress_message_frame.height = 50; + view->progress_message_frame.x = view->screen.x + + (view->screen.width - view->progress_message_frame.width) / 2; + view->progress_message_frame.y = view->screen.y + + view->screen.height - 90 - 20 - view->progress_message_frame.height; if (grub_gfxmenu_view_load_theme (view, theme_path) != 0) { @@ -141,21 +164,23 @@ set_progress_message (grub_gfxmenu_view_t view, const char *message) } static void -draw_background (grub_gfxmenu_view_t view) +redraw_background (grub_gfxmenu_view_t view, + const grub_video_rect_t *bounds) { if (view->desktop_image) { struct grub_video_bitmap *img = view->desktop_image; grub_video_blit_bitmap (img, GRUB_VIDEO_BLIT_REPLACE, - view->screen.x, view->screen.y, 0, 0, - grub_video_bitmap_get_width (img), - grub_video_bitmap_get_height (img)); + bounds->x, bounds->y, + bounds->x - view->screen.x, + bounds->y - view->screen.y, + bounds->width, bounds->height); } else { grub_video_fill_rect (grub_gui_map_color (view->desktop_color), - view->screen.x, view->screen.y, - view->screen.width, view->screen.height); + bounds->x, bounds->y, + bounds->width, bounds->height); } } @@ -191,6 +216,7 @@ update_timeout_visit (grub_gui_component_t component, { struct progress_value_data *pv; pv = (struct progress_value_data *) userdata; + component->ops->set_property (component, "visible", pv->visible); component->ops->set_property (component, "start", pv->start); component->ops->set_property (component, "end", pv->end); @@ -198,16 +224,43 @@ update_timeout_visit (grub_gui_component_t component, component->ops->set_property (component, "text", pv->text); } -static void -update_timeout (grub_gfxmenu_view_t view) + +static inline void +update_timeout (grub_gfxmenu_view_t view, int is_init) { char startbuf[20]; char valuebuf[20]; char msgbuf[120]; - int timeout = grub_gfxmenu_model_get_timeout_ms (view->model); - int remaining = grub_gfxmenu_model_get_timeout_remaining_ms (view->model); + int timeout; + int remaining; struct progress_value_data pv; + int seconds_remaining_rounded_up; + + auto void redraw_timeout_visit (grub_gui_component_t component, + void *userdata __attribute__ ((unused))); + + auto void redraw_timeout_visit (grub_gui_component_t component, + void *userdata __attribute__ ((unused))) + { + grub_video_rect_t bounds; + component->ops->get_bounds (component, &bounds); + grub_gfxmenu_view_redraw (view, &bounds); + } + + timeout = grub_gfxmenu_model_get_timeout_ms (view->model); + if (timeout > 0) + { + remaining = grub_gfxmenu_model_get_timeout_remaining_ms (view->model); + seconds_remaining_rounded_up = (remaining + 999) / 1000; + } + else + seconds_remaining_rounded_up = -1; + + if (view->last_seconds_remaining == seconds_remaining_rounded_up && !is_init) + return; + + view->last_seconds_remaining = seconds_remaining_rounded_up; pv.visible = timeout > 0 ? "true" : "false"; grub_sprintf (startbuf, "%d", -timeout); @@ -216,7 +269,6 @@ update_timeout (grub_gfxmenu_view_t view) grub_sprintf (valuebuf, "%d", remaining > 0 ? -remaining : 0); pv.value = valuebuf; - int seconds_remaining_rounded_up = (remaining + 999) / 1000; grub_sprintf (msgbuf, "The highlighted entry will be booted automatically in %d s.", seconds_remaining_rounded_up); @@ -224,6 +276,21 @@ update_timeout (grub_gfxmenu_view_t view) grub_gui_find_by_id ((grub_gui_component_t) view->canvas, TIMEOUT_COMPONENT_ID, update_timeout_visit, &pv); + if (!is_init) + { + grub_gui_find_by_id ((grub_gui_component_t) view->canvas, + TIMEOUT_COMPONENT_ID, redraw_timeout_visit, &pv); + grub_video_swap_buffers (); + if (view->double_repaint) + grub_gui_find_by_id ((grub_gui_component_t) view->canvas, + TIMEOUT_COMPONENT_ID, redraw_timeout_visit, &pv); + } +} + +void +grub_gfxmenu_redraw_timeout (grub_gfxmenu_view_t view) +{ + update_timeout (view, 0); } static void @@ -252,19 +319,13 @@ static void draw_message (grub_gfxmenu_view_t view) { char *text = view->progress_message_text; + grub_video_rect_t f = view->progress_message_frame; if (! text) return; grub_font_t font = view->message_font; grub_video_color_t color = grub_gui_map_color (view->message_color); - /* Set the timeout bar's frame. */ - grub_video_rect_t f; - f.width = view->screen.width * 4 / 5; - f.height = 50; - f.x = view->screen.x + (view->screen.width - f.width) / 2; - f.y = view->screen.y + view->screen.height - 90 - 20 - f.height; - /* Border. */ grub_video_fill_rect (color, f.x-1, f.y-1, f.width+2, f.height+2); @@ -280,19 +341,62 @@ draw_message (grub_gfxmenu_view_t view) grub_font_draw_string (text, font, color, x, y); } +void +grub_gfxmenu_view_redraw (grub_gfxmenu_view_t view, + const grub_video_rect_t *region) +{ + grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY); + + redraw_background (view, region); + if (view->canvas) + view->canvas->ops->component.paint (view->canvas, region); + draw_title (view); + if (grub_video_have_common_points (&view->progress_message_frame, region)) + draw_message (view); +} void grub_gfxmenu_view_draw (grub_gfxmenu_view_t view) { - grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY); - update_timeout (view); + update_timeout (view, 1); update_menu_components (view); - draw_background (view); - if (view->canvas) - view->canvas->ops->component.paint (view->canvas); - draw_title (view); - draw_message (view); + grub_gfxmenu_view_redraw (view, &view->screen); + grub_video_swap_buffers (); + if (view->double_repaint) + grub_gfxmenu_view_redraw (view, &view->screen); +} + +static void +redraw_menu_visit (grub_gui_component_t component, + void *userdata) +{ + grub_gfxmenu_view_t view; + view = userdata; + if (component->ops->is_instance (component, "list")) + { + grub_gui_list_t list; + grub_video_rect_t bounds; + + list = (grub_gui_list_t) component; + component->ops->get_bounds (component, &bounds); + grub_gfxmenu_view_redraw (view, &bounds); + } +} + +void +grub_gfxmenu_redraw_menu (grub_gfxmenu_view_t view) +{ + update_menu_components (view); + + grub_gui_iterate_recursively ((grub_gui_component_t) view->canvas, + redraw_menu_visit, view); + grub_video_swap_buffers (); + if (view->double_repaint) + { + grub_gui_iterate_recursively ((grub_gui_component_t) view->canvas, + redraw_menu_visit, view); + } } static grub_err_t @@ -316,7 +420,7 @@ static int term_initialized; static grub_term_output_t term_original; static void -draw_terminal_box (void) +draw_terminal_box (grub_gfxmenu_view_t view) { grub_gfxmenu_box_t term_box; int termx; @@ -335,6 +439,11 @@ draw_terminal_box (void) term_box->draw (term_box, termx - term_box->get_left_pad (term_box), termy - term_box->get_top_pad (term_box)); + grub_video_swap_buffers (); + if (view->double_repaint) + term_box->draw (term_box, + termx - term_box->get_left_pad (term_box), + termy - term_box->get_top_pad (term_box)); } static void @@ -342,9 +451,6 @@ init_terminal (grub_gfxmenu_view_t view) { int termx; int termy; - struct grub_video_mode_info mode_info; - grub_err_t err; - int double_repaint; term_original = grub_term_get_current_output (); @@ -354,34 +460,20 @@ init_terminal (grub_gfxmenu_view_t view) termx = view->screen.x + view->screen.width * (10 - 7) / 10 / 2; termy = view->screen.y + view->screen.height * (10 - 7) / 10 / 2; - err = grub_video_get_info (&mode_info); - if (err) - { - grub_errno = GRUB_ERR_NONE; - double_repaint = 1; - } - else - double_repaint = (mode_info.mode_type - & GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED) - && !(mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP); - /* Note: currently there is no API for changing the gfxterm font on the fly, so whatever font the initially loaded theme specifies will be permanent. */ grub_gfxterm_init_window (GRUB_VIDEO_RENDER_TARGET_DISPLAY, termx, termy, term_target_width, term_target_height, - double_repaint, view->terminal_font_name, 3); + view->double_repaint, view->terminal_font_name, 3); if (grub_errno != GRUB_ERR_NONE) return; term_initialized = 1; - grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY); - grub_gfxmenu_view_draw (view); - grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY); - term_view = view; grub_term_set_current_output (grub_gfxterm_get_term ()); + grub_refresh (); } static void destroy_terminal (void) @@ -405,8 +497,10 @@ notify_booting (grub_menu_entry_t entry, void *userdata) grub_sprintf (s, "Booting '%s'", entry->title); set_progress_message (view, s); grub_free (s); - grub_gfxmenu_view_draw (view); + grub_gfxmenu_view_redraw (view, &view->progress_message_frame); grub_video_swap_buffers (); + if (view->double_repaint) + grub_gfxmenu_view_redraw (view, &view->progress_message_frame); } static void @@ -421,8 +515,10 @@ notify_fallback (grub_menu_entry_t entry, void *userdata) grub_sprintf (s, "Falling back to '%s'", entry->title); set_progress_message (view, s); grub_free (s); - grub_gfxmenu_view_draw (view); + grub_gfxmenu_view_redraw (view, &view->progress_message_frame); grub_video_swap_buffers (); + if (view->double_repaint) + grub_gfxmenu_view_redraw (view, &view->progress_message_frame); } static void @@ -442,6 +538,8 @@ int grub_gfxmenu_view_execute_with_fallback (grub_gfxmenu_view_t view, grub_menu_entry_t entry) { + draw_terminal_box (view); + grub_menu_execute_with_fallback (grub_gfxmenu_model_get_menu (view->model), entry, &execute_callback, (void *) view); @@ -453,7 +551,6 @@ grub_gfxmenu_view_execute_with_fallback (grub_gfxmenu_view_t view, "Unable to automatically boot. " "Press SPACE to continue."); grub_gfxmenu_view_draw (view); - grub_video_swap_buffers (); while (GRUB_TERM_ASCII_CHAR(grub_getkey ()) != ' ') { /* Wait for SPACE to be pressed. */ @@ -461,6 +558,11 @@ grub_gfxmenu_view_execute_with_fallback (grub_gfxmenu_view_t view, set_progress_message (view, 0); /* Clear the message. */ + grub_gfxmenu_view_redraw (view, &view->progress_message_frame); + grub_video_swap_buffers (); + if (view->double_repaint) + grub_gfxmenu_view_redraw (view, &view->progress_message_frame); + return 1; /* Ok. */ } @@ -468,14 +570,7 @@ int grub_gfxmenu_view_execute_entry (grub_gfxmenu_view_t view, grub_menu_entry_t entry) { - /* Currently we switch back to text mode by restoring - the original terminal before executing the menu entry. - It is hard to make it work when executing a menu entry - that switches video modes -- it using gfxterm in a - window, the repaint callback seems to crash GRUB. */ - /* TODO: Determine if this works when 'gfxterm' was set as - the current terminal before invoking the gfxmenu. */ - destroy_terminal (); + draw_terminal_box (view); grub_menu_execute_entry (entry); if (grub_errno != GRUB_ERR_NONE) @@ -484,13 +579,14 @@ grub_gfxmenu_view_execute_entry (grub_gfxmenu_view_t view, if (set_graphics_mode () != GRUB_ERR_NONE) return 0; /* Failure. */ - init_terminal (view); + grub_gfxmenu_view_draw (view); return 1; /* Ok. */ } void -grub_gfxmenu_view_run_terminal (grub_gfxmenu_view_t view __attribute__((unused))) +grub_gfxmenu_view_run_terminal (grub_gfxmenu_view_t view) { - draw_terminal_box (); + draw_terminal_box (view); grub_cmdline_run (1); + grub_gfxmenu_view_draw (view); } diff --git a/include/grub/gfxmenu_view.h b/include/grub/gfxmenu_view.h index 1144382f2..c86334400 100644 --- a/include/grub/gfxmenu_view.h +++ b/include/grub/gfxmenu_view.h @@ -54,7 +54,15 @@ int grub_gfxmenu_view_execute_entry (grub_gfxmenu_view_t view, void grub_gfxmenu_view_run_terminal (grub_gfxmenu_view_t view); +void +grub_gfxmenu_redraw_menu (grub_gfxmenu_view_t view); +void +grub_gfxmenu_redraw_timeout (grub_gfxmenu_view_t view); + +void +grub_gfxmenu_view_redraw (grub_gfxmenu_view_t view, + const grub_video_rect_t *region); /* Implementation details -- this should not be used outside of the view itself. */ @@ -86,6 +94,12 @@ struct grub_gfxmenu_view grub_gui_container_t canvas; grub_gfxmenu_model_t model; + + int last_seconds_remaining; + + int double_repaint; + + grub_video_rect_t progress_message_frame; }; #endif /* ! GRUB_GFXMENU_VIEW_HEADER */ diff --git a/include/grub/gui.h b/include/grub/gui.h index 5b785dbb5..385c0962b 100644 --- a/include/grub/gui.h +++ b/include/grub/gui.h @@ -50,13 +50,14 @@ struct grub_gui_component_ops void (*destroy) (void *self); const char * (*get_id) (void *self); int (*is_instance) (void *self, const char *type); - void (*paint) (void *self); + void (*paint) (void *self, const grub_video_rect_t *bounds); void (*set_parent) (void *self, grub_gui_container_t parent); grub_gui_container_t (*get_parent) (void *self); void (*set_bounds) (void *self, const grub_video_rect_t *bounds); void (*get_bounds) (void *self, grub_video_rect_t *bounds); void (*get_preferred_size) (void *self, int *width, int *height); grub_err_t (*set_property) (void *self, const char *name, const char *value); + void (*repaint) (void *self, int second_pass); }; struct grub_gui_container_ops @@ -162,4 +163,17 @@ grub_gui_map_color (grub_gui_color_t c) return grub_video_map_rgba (c.red, c.green, c.blue, c.alpha); } +static inline int +grub_video_have_common_points (const grub_video_rect_t *a, + const grub_video_rect_t *b) +{ + if (!((a->x <= b->x && b->x <= a->x + a->width) + || (b->x <= a->x && a->x <= b->x + b->width))) + return 0; + if (!((a->y <= b->y && b->y <= a->y + a->height) + || (b->y <= a->y && a->y <= b->y + b->height))) + return 0; + return 1; +} + #endif /* ! GRUB_GUI_H */ From f788bf3cd4a3ae22d25d305f42652651ccc962f5 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Thu, 26 Nov 2009 23:54:26 +0000 Subject: [PATCH 114/738] Add (unused) mode_mask parameter (implicitly documented in ChangeLog.videomask) --- video/efi_fb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/video/efi_fb.c b/video/efi_fb.c index 2faff12f9..a4a9950b1 100644 --- a/video/efi_fb.c +++ b/video/efi_fb.c @@ -197,7 +197,7 @@ grub_video_efi_fini (void) static grub_err_t grub_video_efi_setup (unsigned int width, unsigned int height, - unsigned int mode_type) + unsigned int mode_type, unsigned int mode_mask __attribute__ ((unused))) { unsigned int depth; int found = 0; From 2fac00e6687eb0b55e7102c2d6c64a389084bc77 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 27 Nov 2009 10:20:24 +0100 Subject: [PATCH 115/738] Fixed a warning --- gfxmenu/view.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gfxmenu/view.c b/gfxmenu/view.c index 1c512fee1..7d9bb1cd0 100644 --- a/gfxmenu/view.c +++ b/gfxmenu/view.c @@ -255,7 +255,10 @@ update_timeout (grub_gfxmenu_view_t view, int is_init) seconds_remaining_rounded_up = (remaining + 999) / 1000; } else - seconds_remaining_rounded_up = -1; + { + seconds_remaining_rounded_up = -1; + remaining = -1; + } if (view->last_seconds_remaining == seconds_remaining_rounded_up && !is_init) return; From 3c68ed3d804353ec94d3b5154e3f6e0016ba22f9 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 28 Nov 2009 23:34:48 +0100 Subject: [PATCH 116/738] Deduplicated cache handling. Fixed jump hatch being filled with random stuff --- kern/mips/cache.S | 26 ++-------------------- kern/mips/cache_flush.S | 23 ++++++++++++++++++++ lib/mips/relocator.c | 3 +++ lib/mips/relocator_asm.S | 47 +++++----------------------------------- 4 files changed, 34 insertions(+), 65 deletions(-) create mode 100644 kern/mips/cache_flush.S diff --git a/kern/mips/cache.S b/kern/mips/cache.S index 8353e1b04..2c35b6da2 100644 --- a/kern/mips/cache.S +++ b/kern/mips/cache.S @@ -1,29 +1,7 @@ + #include - /* FIXME: This should invalidate only part of memory. */ FUNCTION (grub_cpu_flush_cache) FUNCTION (grub_arch_sync_caches) - move $t2, $a0 - addu $t3, $a0, $a1 - srl $t2, $t2, 5 - sll $t2, $t2, 5 - addu $t3, $t3, 0x1f - srl $t3, $t3, 5 - sll $t3, $t3, 5 - move $t0, $t2 - subu $t1, $t3, $t2 -r1: - cache 1, 0($t0) - addiu $t0, $t0, 0x1 - addiu $t1, $t1, 0xffff - bne $t1, $zero, r1 - sync - move $t0, $t2 - subu $t1, $t3, $t2 -r2: - cache 0, 0($t0) - addiu $t0, $t0, 0x1 - addiu $t1, $t1, 0xffff - bne $t1, $zero, r2 - sync +#include "cache_flush.S" j $ra diff --git a/kern/mips/cache_flush.S b/kern/mips/cache_flush.S new file mode 100644 index 000000000..5667ee7b4 --- /dev/null +++ b/kern/mips/cache_flush.S @@ -0,0 +1,23 @@ + move $t2, $a0 + addu $t3, $a0, $a1 + srl $t2, $t2, 5 + sll $t2, $t2, 5 + addu $t3, $t3, 0x1f + srl $t3, $t3, 5 + sll $t3, $t3, 5 + move $t0, $t2 + subu $t1, $t3, $t2 +1: + cache 1, 0($t0) + addiu $t0, $t0, 0x1 + addiu $t1, $t1, 0xffff + bne $t1, $zero, 1b + sync + move $t0, $t2 + subu $t1, $t3, $t2 +2: + cache 0, 0($t0) + addiu $t0, $t0, 0x1 + addiu $t1, $t1, 0xffff + bne $t1, $zero, 2b + sync diff --git a/lib/mips/relocator.c b/lib/mips/relocator.c index 796473bf7..40be263c7 100644 --- a/lib/mips/relocator.c +++ b/lib/mips/relocator.c @@ -64,6 +64,9 @@ write_jump (int regn, void **target) /* j $r. */ *(grub_uint32_t *) *target = (regn<<21) | 0x8; *target = ((grub_uint32_t *) *target) + 1; + /* nop. */ + *(grub_uint32_t *) *target = 0; + *target = ((grub_uint32_t *) *target) + 1; } static void diff --git a/lib/mips/relocator_asm.S b/lib/mips/relocator_asm.S index 9daf0d32f..ff4fa31e0 100644 --- a/lib/mips/relocator_asm.S +++ b/lib/mips/relocator_asm.S @@ -21,8 +21,8 @@ .p2align 4 /* force 16-byte alignment */ VARIABLE (grub_relocator32_forward_start) - move $12, $9 - move $13, $10 + move $a0, $9 + move $a1, $10 copycont1: lb $11,0($8) @@ -32,31 +32,13 @@ copycont1: addiu $10, $10, 0xffff bne $10, $0, copycont1 - move $9, $12 - move $10, $13 -cachecont1a: - cache 1,0($12) - addiu $12, $12, 0x1 - addiu $13, $13, 0xffff - bne $13, $0, cachecont1a - - sync - - move $12, $9 - move $13, $10 -cachecont1b: - cache 0,0($12) - addiu $12, $12, 0x1 - addiu $13, $13, 0xffff - bne $13, $0, cachecont1b - - sync +#include "../../kern/mips/cache_flush.S" VARIABLE (grub_relocator32_forward_end) VARIABLE (grub_relocator32_backward_start) - move $12, $9 - move $13, $10 + move $a0, $9 + move $a1, $10 addu $9, $9, $10 addu $8, $8, $10 @@ -71,23 +53,6 @@ copycont2: addiu $10, 0xffff bne $10, $0, copycont2 - move $9, $12 - move $10, $13 -cachecont2a: - cache 1,0($12) - addiu $12, $12, 0x1 - addiu $13, $13, 0xffff - bne $13, $0, cachecont2a +#include "../../kern/mips/cache_flush.S" - sync - - move $12, $9 - move $13, $10 -cachecont2b: - cache 0,0($12) - addiu $12, $12, 0x1 - addiu $13, $13, 0xffff - bne $13, $0, cachecont2b - - sync VARIABLE (grub_relocator32_backward_end) From 368a0c61fd2f05347dd88a154f49aba39204317e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 29 Nov 2009 01:09:30 +0100 Subject: [PATCH 117/738] Made linux command line work --- loader/mips/linux.c | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/loader/mips/linux.c b/loader/mips/linux.c index 056eca793..26a31034c 100644 --- a/loader/mips/linux.c +++ b/loader/mips/linux.c @@ -38,7 +38,8 @@ static grub_size_t initrd_size; static grub_size_t linux_size; static grub_uint8_t *playground; -static grub_addr_t target_addr, entry_addr, initrd_addr, argc_addr; +static grub_addr_t target_addr, entry_addr, initrd_addr; +static int linux_argc; static grub_addr_t argv_addr, envp_addr; static grub_err_t @@ -48,7 +49,7 @@ grub_linux_boot (void) /* Boot the kernel. */ state.gpr[1] = entry_addr; - state.gpr[4] = argc_addr; + state.gpr[4] = linux_argc; state.gpr[5] = argv_addr; state.gpr[6] = envp_addr; state.jumpreg = 1; @@ -195,11 +196,16 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), grub_loader_unset (); loaded = 0; - size = sizeof (grub_uint32_t) * argc + ALIGN_UP (sizeof ("g"), 4) - + sizeof (grub_uint32_t) + (0 + 1) * sizeof (grub_uint32_t); + /* For arguments. */ + linux_argc = argc; + size = (linux_argc + 1) * sizeof (grub_uint32_t); + size += ALIGN_UP (sizeof ("g"), 4); for (i = 1; i < argc; i++) size += ALIGN_UP (grub_strlen (argv[i]) + 1, 4); + /* For the environment. */ + size += sizeof (grub_uint32_t); + if (grub_elf_is_elf32 (elf)) err = grub_linux_load32 (elf, &extra, size); else @@ -212,33 +218,29 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), if (err) return err; - - *(grub_uint32_t *) extra = argc; - argc_addr = (grub_uint8_t *) extra - (grub_uint8_t *) playground - + target_addr; - extra = (grub_uint32_t *) extra + 1; + linux_argv = extra; argv_addr = (grub_uint8_t *) linux_argv - (grub_uint8_t *) playground + target_addr; - extra = linux_argv + argc; + extra = linux_argv + (linux_argc + 1); linux_args = extra; - + grub_memcpy (linux_args, "g", sizeof ("g")); *linux_argv = (grub_uint8_t *) linux_args - (grub_uint8_t *) playground + target_addr; - grub_memcpy (linux_args, "g", sizeof ("g")); - linux_args += ALIGN_UP (sizeof ("g"), 4); linux_argv++; + linux_args += ALIGN_UP (sizeof ("g"), 4); for (i = 1; i < argc; i++) { + grub_memcpy (linux_args, argv[i], grub_strlen (argv[i]) + 1); *linux_argv = (grub_uint8_t *) linux_args - (grub_uint8_t *) playground + target_addr; - grub_memcpy (linux_args, argv[i], grub_strlen (argv[i]) + 1); - linux_args += ALIGN_UP (grub_strlen (argv[i]) + 1, 4); linux_argv++; + linux_args += ALIGN_UP (grub_strlen (argv[i]) + 1, 4); } - + *linux_argv = 0; extra = linux_args; + linux_envp = extra; envp_addr = (grub_uint8_t *) linux_envp - (grub_uint8_t *) playground + target_addr; From 96c210daa3b29022e23e0fb8824d1d4297cb9239 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 29 Nov 2009 03:24:11 +0100 Subject: [PATCH 118/738] Initrd support --- loader/mips/linux.c | 88 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 70 insertions(+), 18 deletions(-) diff --git a/loader/mips/linux.c b/loader/mips/linux.c index 26a31034c..86f4201b0 100644 --- a/loader/mips/linux.c +++ b/loader/mips/linux.c @@ -34,13 +34,14 @@ static grub_dl_t my_mod; static int loaded; -static grub_size_t initrd_size; static grub_size_t linux_size; static grub_uint8_t *playground; -static grub_addr_t target_addr, entry_addr, initrd_addr; +static grub_addr_t target_addr, entry_addr; static int linux_argc; -static grub_addr_t argv_addr, envp_addr; +static grub_off_t argv_off, envp_off; +static grub_off_t rd_addr_arg_off, rd_size_arg_off; +static int initrd_loaded = 0; static grub_err_t grub_linux_boot (void) @@ -50,8 +51,8 @@ grub_linux_boot (void) /* Boot the kernel. */ state.gpr[1] = entry_addr; state.gpr[4] = linux_argc; - state.gpr[5] = argv_addr; - state.gpr[6] = envp_addr; + state.gpr[5] = target_addr + argv_off; + state.gpr[6] = target_addr + envp_off; state.jumpreg = 1; grub_relocator32_boot (playground, target_addr, state); @@ -198,10 +199,23 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), /* For arguments. */ linux_argc = argc; + /* Main arguments. */ size = (linux_argc + 1) * sizeof (grub_uint32_t); - size += ALIGN_UP (sizeof ("g"), 4); + /* Initrd address and size. */ + size += 2 * sizeof (grub_uint32_t); + /* NULL terminator. */ + size += sizeof (grub_uint32_t); + + /* First arguments are always "a0" and "a1". */ + size += ALIGN_UP (sizeof ("a0"), 4); + size += ALIGN_UP (sizeof ("a1"), 4); + /* Normal arguments. */ for (i = 1; i < argc; i++) size += ALIGN_UP (grub_strlen (argv[i]) + 1, 4); + + /* rd arguments. */ + size += ALIGN_UP (sizeof ("rd_start=0xXXXXXXXXXXXXXXXX"), 4); + size += ALIGN_UP (sizeof ("rd_size=0xXXXXXXXXXXXXXXXX"), 4); /* For the environment. */ size += sizeof (grub_uint32_t); @@ -220,15 +234,21 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), return err; linux_argv = extra; - argv_addr = (grub_uint8_t *) linux_argv - (grub_uint8_t *) playground - + target_addr; - extra = linux_argv + (linux_argc + 1); + argv_off = (grub_uint8_t *) linux_argv - (grub_uint8_t *) playground; + extra = linux_argv + (linux_argc + 1 + 1 + 2); linux_args = extra; - grub_memcpy (linux_args, "g", sizeof ("g")); + + grub_memcpy (linux_args, "a0", sizeof ("a0")); *linux_argv = (grub_uint8_t *) linux_args - (grub_uint8_t *) playground + target_addr; linux_argv++; - linux_args += ALIGN_UP (sizeof ("g"), 4); + linux_args += ALIGN_UP (sizeof ("a0"), 4); + + grub_memcpy (linux_args, "a1", sizeof ("a1")); + *linux_argv = (grub_uint8_t *) linux_args - (grub_uint8_t *) playground + + target_addr; + linux_argv++; + linux_args += ALIGN_UP (sizeof ("a1"), 4); for (i = 1; i < argc; i++) { @@ -238,16 +258,28 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), linux_argv++; linux_args += ALIGN_UP (grub_strlen (argv[i]) + 1, 4); } + + /* Reserve space for rd arguments. */ + rd_addr_arg_off = (grub_uint8_t *) linux_args - (grub_uint8_t *) playground; + linux_args += ALIGN_UP (sizeof ("rd_start=0xXXXXXXXXXXXXXXXX"), 4); *linux_argv = 0; + linux_argv++; + + rd_size_arg_off = (grub_uint8_t *) linux_args - (grub_uint8_t *) playground; + linux_args += ALIGN_UP (sizeof ("rd_size=0xXXXXXXXXXXXXXXXX"), 4); + *linux_argv = 0; + linux_argv++; + + *linux_argv = 0; + extra = linux_args; linux_envp = extra; - envp_addr = (grub_uint8_t *) linux_envp - (grub_uint8_t *) playground - + target_addr; + envp_off = (grub_uint8_t *) linux_envp - (grub_uint8_t *) playground; linux_envp[0] = 0; grub_loader_set (grub_linux_boot, grub_linux_unload, 1); - initrd_addr = 0; + initrd_loaded = 0; loaded = 1; grub_dl_ref (my_mod); @@ -260,6 +292,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), { grub_file_t file = 0; grub_ssize_t size; + grub_size_t overhead; if (argc == 0) return grub_error (GRUB_ERR_BAD_ARGUMENT, "no initrd specified"); @@ -267,20 +300,28 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), if (!loaded) return grub_error (GRUB_ERR_BAD_ARGUMENT, "You need to load the kernel first."); + if (initrd_loaded) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "Only one initrd can be loaded."); + file = grub_file_open (argv[0]); if (! file) return grub_errno; size = grub_file_size (file); - playground = grub_relocator32_realloc (playground, linux_size + size); + overhead = ALIGN_UP (target_addr + linux_size + 0x10000, 0x10000) + - (target_addr + linux_size); + + playground = grub_relocator32_realloc (playground, + linux_size + overhead + size); + if (!playground) { grub_file_close (file); return grub_errno; } - if (grub_file_read (file, playground + linux_size, size) != size) + if (grub_file_read (file, playground + linux_size + overhead, size) != size) { grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file"); grub_file_close (file); @@ -288,8 +329,19 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), return grub_errno; } - initrd_addr = target_addr + linux_size; - initrd_size = size; + grub_sprintf ((char *) playground + rd_addr_arg_off, "rd_start=0x%llx", + (unsigned long long) target_addr + linux_size + overhead); + ((grub_uint32_t *) (playground + argv_off))[linux_argc] + = target_addr + rd_addr_arg_off; + linux_argc++; + + grub_sprintf ((char *) playground + rd_size_arg_off, "rd_size=0x%llx", + (unsigned long long) size); + ((grub_uint32_t *) (playground + argv_off))[linux_argc] + = target_addr + rd_size_arg_off; + linux_argc++; + + initrd_loaded = 1; grub_file_close (file); From badcfeeac0680962b4e0b8018b328abf21cf7ff4 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 29 Nov 2009 12:26:15 +0100 Subject: [PATCH 119/738] Fix JUMP_SIZEOF --- lib/mips/relocator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/mips/relocator.c b/lib/mips/relocator.c index 40be263c7..118ddbd6f 100644 --- a/lib/mips/relocator.c +++ b/lib/mips/relocator.c @@ -36,7 +36,7 @@ extern grub_uint8_t grub_relocator32_backward_start; extern grub_uint8_t grub_relocator32_backward_end; #define REGW_SIZEOF (2 * sizeof (grub_uint32_t)) -#define JUMP_SIZEOF (sizeof (grub_uint32_t)) +#define JUMP_SIZEOF (2 * sizeof (grub_uint32_t)) #define RELOCATOR_SRC_SIZEOF(x) (&grub_relocator32_##x##_end \ - &grub_relocator32_##x##_start) From f9e4ed6a45f73a3bbc4b1201db16c3f3ba1e4e8b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 29 Nov 2009 14:26:07 +0100 Subject: [PATCH 120/738] Index of BMP for faster font lookup --- font/font.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/font/font.c b/font/font.c index a81291916..82e0d88e7 100644 --- a/font/font.c +++ b/font/font.c @@ -58,6 +58,7 @@ struct grub_font short leading; grub_uint32_t num_chars; struct char_index_entry *char_index; + grub_uint16_t *bmp_idx; }; /* Definition of font registry. */ @@ -180,6 +181,7 @@ font_init (grub_font_t font) font->descent = 0; font->num_chars = 0; font->char_index = 0; + font->bmp_idx = 0; } /* Open the next section in the file. @@ -273,6 +275,14 @@ load_font_index (grub_file_t file, grub_uint32_t sect_length, struct * sizeof (struct char_index_entry)); if (! font->char_index) return 1; + font->bmp_idx = grub_malloc (0x10000 * sizeof (grub_uint16_t)); + if (! font->bmp_idx) + { + grub_free (font->char_index); + return 1; + } + grub_memset (font->bmp_idx, 0xff, 0x10000 * sizeof (grub_uint16_t)); + #if FONT_DEBUG >= 2 grub_printf("num_chars=%d)\n", font->num_chars); @@ -299,6 +309,9 @@ load_font_index (grub_file_t file, grub_uint32_t sect_length, struct return 1; } + if (entry->code < 0x10000) + font->bmp_idx[entry->code] = i; + last_code = entry->code; /* Read storage flags byte. */ @@ -594,7 +607,7 @@ read_be_int16 (grub_file_t file, grub_int16_t * value) /* Return a pointer to the character index entry for the glyph corresponding to the codepoint CODE in the font FONT. If not found, return zero. */ -static struct char_index_entry * +static inline struct char_index_entry * find_glyph (const grub_font_t font, grub_uint32_t code) { struct char_index_entry *table; @@ -602,8 +615,17 @@ find_glyph (const grub_font_t font, grub_uint32_t code) grub_size_t hi; grub_size_t mid; - /* Do a binary search in `char_index', which is ordered by code point. */ table = font->char_index; + + /* Use BMP index if possible. */ + if (code < 0x10000) + { + if (font->bmp_idx[code] == 0xffff) + return 0; + return &table[font->bmp_idx[code]]; + } + + /* Do a binary search in `char_index', which is ordered by code point. */ lo = 0; hi = font->num_chars - 1; From 26625973e14613858d9fef3afe9913b065935800 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 29 Nov 2009 15:17:18 +0100 Subject: [PATCH 121/738] ChangeLog --- ChangeLog.bmpidx | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 ChangeLog.bmpidx diff --git a/ChangeLog.bmpidx b/ChangeLog.bmpidx new file mode 100644 index 000000000..bae879596 --- /dev/null +++ b/ChangeLog.bmpidx @@ -0,0 +1,9 @@ +2009-11-29 Vladimir Serbinenko + + Optimise glyph lookup by Basic Multilingual Plane lookup array. + + * font/font.c (struct grub_font): New member 'bmp_idx'. + (font_init): Initialise 'bmp_idx'. + (load_font_index): Fill 'bmp_idx'. + (find_glyph): Make inline. Use bmp_idx for BMP characters. + From 3e29c69a8ddf5e5641d35a55a01def964fd89f72 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 30 Nov 2009 10:58:06 +0100 Subject: [PATCH 122/738] 2009-11-30 Vladimir Serbinenko * video/fb/video_fb.c (grub_video_fb_scroll): Optimise by avoiding unnecessary calls. --- ChangeLog.scrollopt | 4 ++ video/fb/video_fb.c | 93 +++++++++++++++++++++++++++++++++++---------- 2 files changed, 76 insertions(+), 21 deletions(-) create mode 100644 ChangeLog.scrollopt diff --git a/ChangeLog.scrollopt b/ChangeLog.scrollopt new file mode 100644 index 000000000..c677a2372 --- /dev/null +++ b/ChangeLog.scrollopt @@ -0,0 +1,4 @@ +2009-11-30 Vladimir Serbinenko + + * video/fb/video_fb.c (grub_video_fb_scroll): Optimise by avoiding + unnecessary calls. diff --git a/video/fb/video_fb.c b/video/fb/video_fb.c index 5f2917da6..15c30c23b 100644 --- a/video/fb/video_fb.c +++ b/video/fb/video_fb.c @@ -974,32 +974,83 @@ grub_video_fb_scroll (grub_video_color_t color, int dx, int dy) { /* 3. Move data in render target. */ struct grub_video_fbblit_info target; - grub_uint8_t *src; - grub_uint8_t *dst; - int j; + int i, j; + int linedelta, linelen; target.mode_info = &render_target->mode_info; target.data = render_target->data; - /* Check vertical direction of the move. */ - if (dy <= 0) - /* 3a. Move data upwards. */ - for (j = 0; j < height; j++) - { - dst = grub_video_fb_get_video_ptr (&target, dst_x, dst_y + j); - src = grub_video_fb_get_video_ptr (&target, src_x, src_y + j); - grub_memmove (dst, src, - width * target.mode_info->bytes_per_pixel); - } + linedelta = target.mode_info->pitch + - width * target.mode_info->bytes_per_pixel; + linelen = width * target.mode_info->bytes_per_pixel; +#define DO_SCROLL \ + /* Check vertical direction of the move. */ \ + if (dy < 0 || (dy == 0 && dx < 0)) \ + { \ + dst = (void *) grub_video_fb_get_video_ptr (&target, \ + dst_x, dst_y); \ + src = (void *) grub_video_fb_get_video_ptr (&target, \ + src_x, src_y); \ + /* 3a. Move data upwards. */ \ + for (j = 0; j < height; j++) \ + { \ + for (i = 0; i < linelen; i++) \ + *(dst++) = *(src++); \ + dst += linedelta; \ + src += linedelta; \ + } \ + } \ + else \ + { \ + /* 3b. Move data downwards. */ \ + dst = (void *) grub_video_fb_get_video_ptr (&target, \ + dst_x + width - 1, \ + dst_y + height - 1); \ + src = (void *) grub_video_fb_get_video_ptr (&target, \ + src_x + width - 1, \ + src_y + height - 1); \ + for (j = 0; j < height; j++) \ + { \ + for (i = 0; i < linelen; i++) \ + *(dst--) = *(src--); \ + dst -= linedelta; \ + src -= linedelta; \ + } \ + } + + /* If everything is aligned on 32-bit use 32-bit copy. */ + if ((grub_addr_t) grub_video_fb_get_video_ptr (&target, src_x, src_y) + % sizeof (grub_uint32_t) == 0 + && (grub_addr_t) grub_video_fb_get_video_ptr (&target, dst_x, dst_y) + % sizeof (grub_uint32_t) == 0 + && linelen % sizeof (grub_uint32_t) == 0 + && linedelta % sizeof (grub_uint32_t) == 0) + { + grub_uint32_t *src, *dst; + linelen /= sizeof (grub_uint32_t); + linedelta /= sizeof (grub_uint32_t); + DO_SCROLL + } + /* If everything is aligned on 16-bit use 16-bit copy. */ + else if ((grub_addr_t) grub_video_fb_get_video_ptr (&target, src_x, src_y) + % sizeof (grub_uint16_t) == 0 + && (grub_addr_t) grub_video_fb_get_video_ptr (&target, + dst_x, dst_y) + % sizeof (grub_uint16_t) == 0 + && linelen % sizeof (grub_uint16_t) == 0 + && linedelta % sizeof (grub_uint16_t) == 0) + { + grub_uint16_t *src, *dst; + linelen /= sizeof (grub_uint16_t); + linedelta /= sizeof (grub_uint16_t); + DO_SCROLL + } + /* If not aligned at all use 8-bit copy. */ else - /* 3b. Move data downwards. */ - for (j = (height - 1); j >= 0; j--) - { - dst = grub_video_fb_get_video_ptr (&target, dst_x, dst_y + j); - src = grub_video_fb_get_video_ptr (&target, src_x, src_y + j); - grub_memmove (dst, src, - width * target.mode_info->bytes_per_pixel); - } + { + grub_uint8_t *src, *dst; + DO_SCROLL + } } /* 4. Fill empty space with specified color. In this implementation From af20edb21d83d413e9721948f71e8ca2035e7d1b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 30 Nov 2009 12:51:20 +0100 Subject: [PATCH 123/738] 2009-11-30 Vladimir Serbinenko Agglomerate scrolling in gfxterm. * term/gfxterm.c (grub_virtual_screen): New member 'total_screen'. (grub_virtual_screen_setup): Initialise 'total_screen'. (write_char): Split to ... (paint_char): ... this ... (write_char): ... and this. (paint_char): Handle delayed scrolling. (draw_cursor): Likewise. (scroll_up): Split to ... (real_scroll): ... this ... (scroll_up): ... and this. (real_scroll): Handle multi-line scroll and draw below-the-bottom characters. (grub_gfxterm_refresh): Call real_scroll. --- term/gfxterm.c | 157 ++++++++++++++++++++++++++++++------------------- 1 file changed, 98 insertions(+), 59 deletions(-) diff --git a/term/gfxterm.c b/term/gfxterm.c index 5330c4ac4..be0487830 100644 --- a/term/gfxterm.c +++ b/term/gfxterm.c @@ -102,6 +102,8 @@ struct grub_virtual_screen /* Text buffer for virtual screen. Contains (columns * rows) number of entries. */ struct grub_colored_char *text_buffer; + + int total_scroll; }; struct grub_gfxterm_window @@ -225,6 +227,7 @@ grub_virtual_screen_setup (unsigned int x, unsigned int y, virtual_screen.cursor_x = 0; virtual_screen.cursor_y = 0; virtual_screen.cursor_state = 1; + virtual_screen.total_scroll = 0; /* Calculate size of text buffer. */ virtual_screen.columns = virtual_screen.width / virtual_screen.normal_char_width; @@ -586,8 +589,8 @@ dirty_region_redraw (void) redraw_screen_rect (x, y, width, height); } -static void -write_char (void) +static inline void +paint_char (unsigned cx, unsigned cy) { struct grub_colored_char *p; struct grub_font_glyph *glyph; @@ -599,10 +602,12 @@ write_char (void) unsigned int height; unsigned int width; + if (cy + virtual_screen.total_scroll >= virtual_screen.rows) + return; + /* Find out active character. */ p = (virtual_screen.text_buffer - + virtual_screen.cursor_x - + (virtual_screen.cursor_y * virtual_screen.columns)); + + cx + (cy * virtual_screen.columns)); p -= p->index; @@ -616,8 +621,8 @@ write_char (void) color = p->fg_color; bgcolor = p->bg_color; - x = virtual_screen.cursor_x * virtual_screen.normal_char_width; - y = virtual_screen.cursor_y * virtual_screen.normal_char_height; + x = cx * virtual_screen.normal_char_width; + y = (cy + virtual_screen.total_scroll) * virtual_screen.normal_char_height; /* Render glyph to text layer. */ grub_video_set_active_render_target (text_layer); @@ -630,64 +635,58 @@ write_char (void) width, height); } -static void +static inline void +write_char (void) +{ + paint_char (virtual_screen.cursor_x, virtual_screen.cursor_y); +} + +static inline void draw_cursor (int show) { + unsigned int x; + unsigned int y; + unsigned int width; + unsigned int height; + grub_video_color_t color; + write_char (); - if (show) - { - unsigned int x; - unsigned int y; - unsigned int width; - unsigned int height; - grub_video_color_t color; + if (!show) + return; - /* Determine cursor properties and position on text layer. */ - x = virtual_screen.cursor_x * virtual_screen.normal_char_width; - width = virtual_screen.normal_char_width; - color = virtual_screen.fg_color; - y = (virtual_screen.cursor_y * virtual_screen.normal_char_height - + grub_font_get_ascent (virtual_screen.font)); - height = 2; + if (virtual_screen.cursor_y + virtual_screen.total_scroll + >= virtual_screen.rows) + return; - /* Render cursor to text layer. */ - grub_video_set_active_render_target (text_layer); - grub_video_fill_rect (color, x, y, width, height); - grub_video_set_active_render_target (render_target); - - /* Mark cursor to be redrawn. */ - dirty_region_add (virtual_screen.offset_x + x, - virtual_screen.offset_y + y, - width, height); - } + /* Determine cursor properties and position on text layer. */ + x = virtual_screen.cursor_x * virtual_screen.normal_char_width; + width = virtual_screen.normal_char_width; + color = virtual_screen.fg_color; + y = ((virtual_screen.cursor_y + virtual_screen.total_scroll) + * virtual_screen.normal_char_height + + grub_font_get_ascent (virtual_screen.font)); + height = 2; + + /* Render cursor to text layer. */ + grub_video_set_active_render_target (text_layer); + grub_video_fill_rect (color, x, y, width, height); + grub_video_set_active_render_target (render_target); + + /* Mark cursor to be redrawn. */ + dirty_region_add (virtual_screen.offset_x + x, + virtual_screen.offset_y + y, + width, height); } static void -scroll_up (void) +real_scroll (void) { - unsigned int i; + unsigned int i, j, was_scroll; grub_video_color_t color; - /* If we don't have background bitmap, remove cursor. */ - if (!bitmap) - { - /* Remove cursor. */ - draw_cursor (0); - } - - /* Scroll text buffer with one line to up. */ - grub_memmove (virtual_screen.text_buffer, - virtual_screen.text_buffer + virtual_screen.columns, - sizeof (*virtual_screen.text_buffer) - * virtual_screen.columns - * (virtual_screen.rows - 1)); - - /* Clear last line in text buffer. */ - for (i = virtual_screen.columns * (virtual_screen.rows - 1); - i < virtual_screen.columns * virtual_screen.rows; - i++) - clear_char (&(virtual_screen.text_buffer[i])); + if (!virtual_screen.total_scroll) + return; /* If we have bitmap, re-draw screen, otherwise scroll physical screen too. */ if (bitmap) @@ -695,7 +694,8 @@ scroll_up (void) /* Scroll physical screen. */ grub_video_set_active_render_target (text_layer); color = virtual_screen.bg_color; - grub_video_scroll (color, 0, -virtual_screen.normal_char_height); + grub_video_scroll (color, 0, -virtual_screen.normal_char_height + * virtual_screen.total_scroll); /* Mark virtual screen to be redrawn. */ dirty_region_add_virtualscreen (); @@ -704,6 +704,9 @@ scroll_up (void) { grub_video_rect_t saved_view; + /* Remove cursor. */ + draw_cursor (0); + grub_video_set_active_render_target (render_target); /* Save viewport and set it to our window. */ grub_video_get_viewport ((unsigned *) &saved_view.x, @@ -723,13 +726,15 @@ scroll_up (void) virtual_screen.offset_x, virtual_screen.offset_y, virtual_screen.width, - virtual_screen.normal_char_height); + virtual_screen.normal_char_height + * virtual_screen.total_scroll); grub_video_set_active_render_target (render_target); dirty_region_redraw (); /* Scroll physical screen. */ - grub_video_scroll (color, 0, -virtual_screen.normal_char_height); + grub_video_scroll (color, 0, -virtual_screen.normal_char_height + * virtual_screen.total_scroll); if (i) grub_video_swap_buffers (); @@ -739,22 +744,54 @@ scroll_up (void) /* Scroll physical screen. */ grub_video_set_active_render_target (text_layer); color = virtual_screen.bg_color; - grub_video_scroll (color, 0, -virtual_screen.normal_char_height); + grub_video_scroll (color, 0, -virtual_screen.normal_char_height + * virtual_screen.total_scroll); /* Restore saved viewport. */ grub_video_set_viewport (saved_view.x, saved_view.y, saved_view.width, saved_view.height); grub_video_set_active_render_target (render_target); - /* Draw cursor if visible. */ - if (virtual_screen.cursor_state) - draw_cursor (1); } + /* Draw cursor if visible. */ + if (virtual_screen.cursor_state) + draw_cursor (1); + + was_scroll = virtual_screen.total_scroll; + virtual_screen.total_scroll = 0; + + /* Draw shadow part. */ + for (i = virtual_screen.rows - was_scroll; + i < virtual_screen.rows; i++) + for (j = 0; j < virtual_screen.columns; j++) + paint_char (j, i); + if (repaint_callback) repaint_callback (window.x, window.y, window.width, window.height); } +static void +scroll_up (void) +{ + unsigned int i; + + /* Scroll text buffer with one line to up. */ + grub_memmove (virtual_screen.text_buffer, + virtual_screen.text_buffer + virtual_screen.columns, + sizeof (*virtual_screen.text_buffer) + * virtual_screen.columns + * (virtual_screen.rows - 1)); + + /* Clear last line in text buffer. */ + for (i = virtual_screen.columns * (virtual_screen.rows - 1); + i < virtual_screen.columns * virtual_screen.rows; + i++) + clear_char (&(virtual_screen.text_buffer[i])); + + virtual_screen.total_scroll++; +} + static void grub_gfxterm_putchar (grub_uint32_t c) { @@ -1023,6 +1060,8 @@ grub_gfxterm_setcursor (int on) static void grub_gfxterm_refresh (void) { + real_scroll (); + /* Redraw only changed regions. */ dirty_region_redraw (); From e59e3e59caa3d3f7dbe54812f7b97964f03aa3aa Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 30 Nov 2009 12:52:39 +0100 Subject: [PATCH 124/738] Changelog --- ChangeLog.gfxtermscroll | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 ChangeLog.gfxtermscroll diff --git a/ChangeLog.gfxtermscroll b/ChangeLog.gfxtermscroll new file mode 100644 index 000000000..b0733116f --- /dev/null +++ b/ChangeLog.gfxtermscroll @@ -0,0 +1,18 @@ +2009-11-30 Vladimir Serbinenko + + Agglomerate scrolling in gfxterm. + + * term/gfxterm.c (grub_virtual_screen): New member 'total_screen'. + (grub_virtual_screen_setup): Initialise 'total_screen'. + (write_char): Split to ... + (paint_char): ... this ... + (write_char): ... and this. + (paint_char): Handle delayed scrolling. + (draw_cursor): Likewise. + (scroll_up): Split to ... + (real_scroll): ... this ... + (scroll_up): ... and this. + (real_scroll): Handle multi-line scroll and draw below-the-bottom + characters. + (grub_gfxterm_refresh): Call real_scroll. + From adbba2a4ef44ccb309dfbf89b5321ff2794d3c46 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 2 Dec 2009 08:37:43 +0100 Subject: [PATCH 125/738] Remove debug serial console with hardcoded address --- kern/term.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/kern/term.c b/kern/term.c index 271cf8d78..0e3595df3 100644 --- a/kern/term.c +++ b/kern/term.c @@ -51,10 +51,7 @@ grub_putcode (grub_uint32_t code) int height = grub_getwh () & 255; if (!grub_cur_term_output) - { - *(grub_uint8_t *)0xbff003f8 = code; - return; - } + return; if (code == '\t' && grub_cur_term_output->getxy) { From 3e5c7dc3d8a6c4e5cf2d958951a8c6fc08fc2ea1 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 2 Dec 2009 08:39:17 +0100 Subject: [PATCH 126/738] Fix qemu-r4k --- conf/mips-qemu-r4k.rmk | 2 ++ conf/mips-yeeloong.rmk | 54 +++++++++++++++++++++++++++++++ conf/mips.rmk | 54 ------------------------------- configure.ac | 1 + include/grub/mips/qemu-r4k/boot.h | 0 kern/mips/qemu-r4k/init.c | 15 --------- 6 files changed, 57 insertions(+), 69 deletions(-) create mode 100644 include/grub/mips/qemu-r4k/boot.h diff --git a/conf/mips-qemu-r4k.rmk b/conf/mips-qemu-r4k.rmk index 3ff36c472..ec14d9336 100644 --- a/conf/mips-qemu-r4k.rmk +++ b/conf/mips-qemu-r4k.rmk @@ -1,4 +1,6 @@ # -*- makefile -*- LINK_BASE = 0x80010000 target_machine=qemu-r4k +COMMON_CFLAGS += -march=mips3 +COMMON_ASFLAGS += -march=mips3 include $(srcdir)/conf/mips.mk diff --git a/conf/mips-yeeloong.rmk b/conf/mips-yeeloong.rmk index 95ec26522..68c426e1b 100644 --- a/conf/mips-yeeloong.rmk +++ b/conf/mips-yeeloong.rmk @@ -11,8 +11,62 @@ pci_mod_SOURCES = bus/pci.c bus/bonito.c pci_mod_CFLAGS = $(COMMON_CFLAGS) pci_mod_LDFLAGS = $(COMMON_LDFLAGS) +# For ata.mod. +pkglib_MODULES += ata.mod +ata_mod_SOURCES = disk/ata.c +ata_mod_CFLAGS = $(COMMON_CFLAGS) +ata_mod_LDFLAGS = $(COMMON_LDFLAGS) + # For pci.mod. pkglib_MODULES += sm712.mod sm712_mod_SOURCES = video/sm712.c sm712_mod_CFLAGS = $(COMMON_CFLAGS) sm712_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For lspci.mod +pkglib_MODULES += lspci.mod +lspci_mod_SOURCES = commands/lspci.c +lspci_mod_CFLAGS = $(COMMON_CFLAGS) +lspci_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For ohci.mod +pkglib_MODULES += ohci.mod +ohci_mod_SOURCES = bus/usb/ohci.c +ohci_mod_CFLAGS = $(COMMON_CFLAGS) +ohci_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For usb.mod +pkglib_MODULES += usb.mod +usb_mod_SOURCES = bus/usb/usb.c bus/usb/usbtrans.c bus/usb/usbhub.c +usb_mod_CFLAGS = $(COMMON_CFLAGS) +usb_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For usbtest.mod +pkglib_MODULES += usbtest.mod +usbtest_mod_SOURCES = commands/usbtest.c +usbtest_mod_CFLAGS = $(COMMON_CFLAGS) +usbtest_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For usbms.mod +pkglib_MODULES += usbms.mod +usbms_mod_SOURCES = disk/usbms.c +usbms_mod_CFLAGS = $(COMMON_CFLAGS) +usbms_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For usb_keyboard.mod +pkglib_MODULES += usb_keyboard.mod +usb_keyboard_mod_SOURCES = term/usb_keyboard.c +usb_keyboard_mod_CFLAGS = $(COMMON_CFLAGS) +usb_keyboard_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For at_keyboard.mod. +pkglib_MODULES += at_keyboard.mod +at_keyboard_mod_SOURCES = term/at_keyboard.c +at_keyboard_mod_CFLAGS = $(COMMON_CFLAGS) +at_keyboard_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For ata_pthru.mod. +pkglib_MODULES += ata_pthru.mod +ata_pthru_mod_SOURCES = disk/ata_pthru.c +ata_pthru_mod_CFLAGS = $(COMMON_CFLAGS) +ata_pthru_mod_LDFLAGS = $(COMMON_LDFLAGS) diff --git a/conf/mips.rmk b/conf/mips.rmk index fd51cfb00..8c99d9813 100644 --- a/conf/mips.rmk +++ b/conf/mips.rmk @@ -137,48 +137,6 @@ serial_mod_SOURCES = term/serial.c serial_mod_CFLAGS = $(COMMON_CFLAGS) serial_mod_LDFLAGS = $(COMMON_LDFLAGS) -# For ata.mod. -pkglib_MODULES += ata.mod -ata_mod_SOURCES = disk/ata.c -ata_mod_CFLAGS = $(COMMON_CFLAGS) -ata_mod_LDFLAGS = $(COMMON_LDFLAGS) - -# For lspci.mod -pkglib_MODULES += lspci.mod -lspci_mod_SOURCES = commands/lspci.c -lspci_mod_CFLAGS = $(COMMON_CFLAGS) -lspci_mod_LDFLAGS = $(COMMON_LDFLAGS) - -# For ohci.mod -pkglib_MODULES += ohci.mod -ohci_mod_SOURCES = bus/usb/ohci.c -ohci_mod_CFLAGS = $(COMMON_CFLAGS) -ohci_mod_LDFLAGS = $(COMMON_LDFLAGS) - -# For usb.mod -pkglib_MODULES += usb.mod -usb_mod_SOURCES = bus/usb/usb.c bus/usb/usbtrans.c bus/usb/usbhub.c -usb_mod_CFLAGS = $(COMMON_CFLAGS) -usb_mod_LDFLAGS = $(COMMON_LDFLAGS) - -# For usbtest.mod -pkglib_MODULES += usbtest.mod -usbtest_mod_SOURCES = commands/usbtest.c -usbtest_mod_CFLAGS = $(COMMON_CFLAGS) -usbtest_mod_LDFLAGS = $(COMMON_LDFLAGS) - -# For usbms.mod -pkglib_MODULES += usbms.mod -usbms_mod_SOURCES = disk/usbms.c -usbms_mod_CFLAGS = $(COMMON_CFLAGS) -usbms_mod_LDFLAGS = $(COMMON_LDFLAGS) - -# For usb_keyboard.mod -pkglib_MODULES += usb_keyboard.mod -usb_keyboard_mod_SOURCES = term/usb_keyboard.c -usb_keyboard_mod_CFLAGS = $(COMMON_CFLAGS) -usb_keyboard_mod_LDFLAGS = $(COMMON_LDFLAGS) - # For relocator.mod. pkglib_MODULES += relocator.mod relocator_mod_SOURCES = lib/$(target_cpu)/relocator.c lib/$(target_cpu)/relocator_asm.S @@ -192,16 +150,4 @@ linux_mod_CFLAGS = $(COMMON_CFLAGS) linux_mod_ASFLAGS = $(COMMON_ASFLAGS) linux_mod_LDFLAGS = $(COMMON_LDFLAGS) -# For at_keyboard.mod. -pkglib_MODULES += at_keyboard.mod -at_keyboard_mod_SOURCES = term/at_keyboard.c -at_keyboard_mod_CFLAGS = $(COMMON_CFLAGS) -at_keyboard_mod_LDFLAGS = $(COMMON_LDFLAGS) - -# For ata_pthru.mod. -pkglib_MODULES += ata_pthru.mod -ata_pthru_mod_SOURCES = disk/ata_pthru.c -ata_pthru_mod_CFLAGS = $(COMMON_CFLAGS) -ata_pthru_mod_LDFLAGS = $(COMMON_LDFLAGS) - include $(srcdir)/conf/common.mk diff --git a/configure.ac b/configure.ac index 88ef06970..62ad58a5d 100644 --- a/configure.ac +++ b/configure.ac @@ -135,6 +135,7 @@ case "$platform" in pc) machine_CFLAGS="-DGRUB_MACHINE_PCBIOS=1" ;; emu) machine_CFLAGS="-DGRUB_MACHINE_EMU=1" ;; yeeloong) machine_CFLAGS="-DGRUB_MACHINE_MIPS_YEELOONG=1 -DGRUB_MACHINE_MIPS=1 -DGRUB_MACHINE_MIPS_BONITO=1" ;; + qemu-r4k) machine_CFLAGS="-DGRUB_MACHINE_MIPS_YEELOONG=1 -DGRUB_MACHINE_MIPS=1 -DGRUB_MACHINE_MIPS_BONITO=1" ;; esac CFLAGS="$CFLAGS $machine_CFLAGS" TARGET_CFLAGS="$TARGET_CFLAGS $machine_CFLAGS" diff --git a/include/grub/mips/qemu-r4k/boot.h b/include/grub/mips/qemu-r4k/boot.h new file mode 100644 index 000000000..e69de29bb diff --git a/kern/mips/qemu-r4k/init.c b/kern/mips/qemu-r4k/init.c index 8dfda57c2..866c7a82a 100644 --- a/kern/mips/qemu-r4k/init.c +++ b/kern/mips/qemu-r4k/init.c @@ -50,21 +50,6 @@ grub_reboot (void) while (1); } -void -grub_machine_set_prefix (void) -{ - grub_env_set ("prefix", grub_prefix); -} - -extern char _start[]; -extern char _end[]; - -grub_addr_t -grub_arch_modules_addr (void) -{ - return ALIGN_UP((grub_addr_t) _end + GRUB_MOD_GAP, GRUB_MOD_ALIGN); -} - grub_err_t grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, From e6b9873356fc31bc226d52f65a7526e3b9838fc7 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 2 Dec 2009 08:40:51 +0100 Subject: [PATCH 127/738] Remove qemu-mipssim --- conf/mips-qemu-mipssim.rmk | 4 -- configure.ac | 1 - include/grub/mips/qemu-mipssim/kernel.h | 35 ----------- include/grub/mips/qemu-mipssim/machine.h | 24 -------- include/grub/mips/qemu-mipssim/memory.h | 54 ----------------- include/grub/mips/qemu-mipssim/serial.h | 24 -------- include/grub/mips/qemu-mipssim/time.h | 35 ----------- kern/mips/qemu-mipssim/init.c | 76 ------------------------ 8 files changed, 253 deletions(-) delete mode 100644 conf/mips-qemu-mipssim.rmk delete mode 100644 include/grub/mips/qemu-mipssim/kernel.h delete mode 100644 include/grub/mips/qemu-mipssim/machine.h delete mode 100644 include/grub/mips/qemu-mipssim/memory.h delete mode 100644 include/grub/mips/qemu-mipssim/serial.h delete mode 100644 include/grub/mips/qemu-mipssim/time.h delete mode 100644 kern/mips/qemu-mipssim/init.c diff --git a/conf/mips-qemu-mipssim.rmk b/conf/mips-qemu-mipssim.rmk deleted file mode 100644 index 9000ae296..000000000 --- a/conf/mips-qemu-mipssim.rmk +++ /dev/null @@ -1,4 +0,0 @@ -# -*- makefile -*- -LINK_BASE = 0x80010000 -target_machine=qemu-mipssim -include $(srcdir)/conf/mips.mk diff --git a/configure.ac b/configure.ac index 62ad58a5d..f08195c37 100644 --- a/configure.ac +++ b/configure.ac @@ -102,7 +102,6 @@ case "$target_cpu"-"$platform" in powerpc-ieee1275) ;; sparc64-ieee1275) ;; mips-qemu-r4k) ;; - mips-qemu-mipssim) ;; mips-yeeloong) ;; *-emu) ;; *) AC_MSG_ERROR([platform "$platform" is not supported for target CPU "$target_cpu"]) ;; diff --git a/include/grub/mips/qemu-mipssim/kernel.h b/include/grub/mips/qemu-mipssim/kernel.h deleted file mode 100644 index 6a10f2df1..000000000 --- a/include/grub/mips/qemu-mipssim/kernel.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2005,2006,2007,2008,2009 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_KERNEL_MACHINE_HEADER -#define GRUB_KERNEL_MACHINE_HEADER 1 - -#include - -#ifndef ASM_FILE - -void EXPORT_FUNC (grub_reboot) (void); -void EXPORT_FUNC (grub_halt) (void); - -/* The prefix which points to the directory where GRUB modules and its - configuration file are located. */ -extern char grub_prefix[]; - -#endif - -#endif /* ! GRUB_KERNEL_MACHINE_HEADER */ diff --git a/include/grub/mips/qemu-mipssim/machine.h b/include/grub/mips/qemu-mipssim/machine.h deleted file mode 100644 index 9062662bc..000000000 --- a/include/grub/mips/qemu-mipssim/machine.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2007 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_MACHINE_MACHINE_HEADER -#define GRUB_MACHINE_MACHINE_HEADER 1 - -#define GRUB_MACHINE_MIPS_QEMU_MIPSSIM 1 - -#endif /* ! GRUB_MACHINE_MACHINE_HEADER */ diff --git a/include/grub/mips/qemu-mipssim/memory.h b/include/grub/mips/qemu-mipssim/memory.h deleted file mode 100644 index 87e68674e..000000000 --- a/include/grub/mips/qemu-mipssim/memory.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2009 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_MEMORY_MACHINE_HEADER -#define GRUB_MEMORY_MACHINE_HEADER 1 - -#ifndef ASM_FILE -#include -#include -#include -#endif - -#define GRUB_MACHINE_MEMORY_STACK_HIGH 0x80f00000 -#define GRUB_MACHINE_MEMORY_USABLE 0x81000000 - -#define GRUB_MACHINE_MEMORY_AVAILABLE 1 - -#ifndef ASM_FILE -grub_err_t EXPORT_FUNC (grub_machine_mmap_iterate) -(int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t)); -grub_err_t EXPORT_FUNC(grub_machine_mmap_iterate) - (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t)); - -static inline grub_err_t -grub_machine_mmap_register (grub_uint64_t start __attribute__ ((unused)), - grub_uint64_t size __attribute__ ((unused)), - int type __attribute__ ((unused)), - int handle __attribute__ ((unused))) -{ - return GRUB_ERR_NONE; -} -static inline grub_err_t -grub_machine_mmap_unregister (int handle __attribute__ ((unused))) -{ - return GRUB_ERR_NONE; -} -#endif - -#endif diff --git a/include/grub/mips/qemu-mipssim/serial.h b/include/grub/mips/qemu-mipssim/serial.h deleted file mode 100644 index 55d64fec4..000000000 --- a/include/grub/mips/qemu-mipssim/serial.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2009 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_MACHINE_SERIAL_HEADER -#define GRUB_MACHINE_SERIAL_HEADER 1 - -#define GRUB_MACHINE_SERIAL_PORTS { 0x1fd003f8 } - -#endif diff --git a/include/grub/mips/qemu-mipssim/time.h b/include/grub/mips/qemu-mipssim/time.h deleted file mode 100644 index 5c8564e0d..000000000 --- a/include/grub/mips/qemu-mipssim/time.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2003,2004,2005,2007 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef KERNEL_MACHINE_TIME_HEADER -#define KERNEL_MACHINE_TIME_HEADER 1 - -#include - -#define GRUB_TICKS_PER_SECOND 1000 - -/* Return the real time in ticks. */ -grub_uint32_t EXPORT_FUNC (grub_get_rtc) (void); - -static inline void -grub_cpu_idle(void) -{ - /* asm volatile ("wait");*/ -} - -#endif /* ! KERNEL_MACHINE_TIME_HEADER */ diff --git a/kern/mips/qemu-mipssim/init.c b/kern/mips/qemu-mipssim/init.c deleted file mode 100644 index d4001cf1c..000000000 --- a/kern/mips/qemu-mipssim/init.c +++ /dev/null @@ -1,76 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define RAMSIZE (64 << 20) - -grub_uint32_t -grub_get_rtc (void) -{ - static int calln = 0; - return calln++; -} - -void -grub_machine_init (void) -{ - grub_mm_init_region ((void *) GRUB_MACHINE_MEMORY_USABLE, - RAMSIZE - (GRUB_MACHINE_MEMORY_USABLE & 0x7fffffff)); - grub_install_get_time_ms (grub_rtc_get_time_ms); -} - -void -grub_machine_fini (void) -{ -} - -void -grub_exit (void) -{ - while (1); -} - -void -grub_halt (void) -{ - while (1); -} - -void -grub_reboot (void) -{ - while (1); -} - -void -grub_machine_set_prefix (void) -{ - grub_env_set ("prefix", grub_prefix); -} - -extern char _start[]; -extern char _end[]; - -grub_addr_t -grub_arch_modules_addr (void) -{ - return ALIGN_UP((grub_addr_t) _end + GRUB_MOD_GAP, GRUB_MOD_ALIGN); -} - -grub_err_t -grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, - grub_uint64_t, - grub_uint32_t)) -{ - hook (0, RAMSIZE, - GRUB_MACHINE_MEMORY_AVAILABLE); - return GRUB_ERR_NONE; -} From 7b5f334bc0840ce65fc681593c7d98336c3e3f57 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 2 Dec 2009 08:49:36 +0100 Subject: [PATCH 128/738] Rename qemu-r4k to qemu-mips --- conf/{mips-qemu-r4k.rmk => mips-qemu-mips.rmk} | 2 +- configure.ac | 4 ++-- include/grub/mips/{qemu-r4k => qemu-mips}/boot.h | 0 include/grub/mips/{qemu-r4k => qemu-mips}/kernel.h | 0 include/grub/mips/{qemu-r4k => qemu-mips}/loader.h | 0 include/grub/mips/{qemu-r4k => qemu-mips}/machine.h | 0 include/grub/mips/{qemu-r4k => qemu-mips}/memory.h | 0 include/grub/mips/{qemu-r4k => qemu-mips}/serial.h | 0 include/grub/mips/{qemu-r4k => qemu-mips}/time.h | 0 kern/mips/{qemu-r4k => qemu-mips}/init.c | 0 10 files changed, 3 insertions(+), 3 deletions(-) rename conf/{mips-qemu-r4k.rmk => mips-qemu-mips.rmk} (84%) rename include/grub/mips/{qemu-r4k => qemu-mips}/boot.h (100%) rename include/grub/mips/{qemu-r4k => qemu-mips}/kernel.h (100%) rename include/grub/mips/{qemu-r4k => qemu-mips}/loader.h (100%) rename include/grub/mips/{qemu-r4k => qemu-mips}/machine.h (100%) rename include/grub/mips/{qemu-r4k => qemu-mips}/memory.h (100%) rename include/grub/mips/{qemu-r4k => qemu-mips}/serial.h (100%) rename include/grub/mips/{qemu-r4k => qemu-mips}/time.h (100%) rename kern/mips/{qemu-r4k => qemu-mips}/init.c (100%) diff --git a/conf/mips-qemu-r4k.rmk b/conf/mips-qemu-mips.rmk similarity index 84% rename from conf/mips-qemu-r4k.rmk rename to conf/mips-qemu-mips.rmk index ec14d9336..d5a985a13 100644 --- a/conf/mips-qemu-r4k.rmk +++ b/conf/mips-qemu-mips.rmk @@ -1,6 +1,6 @@ # -*- makefile -*- LINK_BASE = 0x80010000 -target_machine=qemu-r4k +target_machine=qemu-mips COMMON_CFLAGS += -march=mips3 COMMON_ASFLAGS += -march=mips3 include $(srcdir)/conf/mips.mk diff --git a/configure.ac b/configure.ac index f08195c37..8b089ee58 100644 --- a/configure.ac +++ b/configure.ac @@ -101,7 +101,7 @@ case "$target_cpu"-"$platform" in i386-qemu) ;; powerpc-ieee1275) ;; sparc64-ieee1275) ;; - mips-qemu-r4k) ;; + mips-qemu-mips) ;; mips-yeeloong) ;; *-emu) ;; *) AC_MSG_ERROR([platform "$platform" is not supported for target CPU "$target_cpu"]) ;; @@ -134,7 +134,7 @@ case "$platform" in pc) machine_CFLAGS="-DGRUB_MACHINE_PCBIOS=1" ;; emu) machine_CFLAGS="-DGRUB_MACHINE_EMU=1" ;; yeeloong) machine_CFLAGS="-DGRUB_MACHINE_MIPS_YEELOONG=1 -DGRUB_MACHINE_MIPS=1 -DGRUB_MACHINE_MIPS_BONITO=1" ;; - qemu-r4k) machine_CFLAGS="-DGRUB_MACHINE_MIPS_YEELOONG=1 -DGRUB_MACHINE_MIPS=1 -DGRUB_MACHINE_MIPS_BONITO=1" ;; + qemu-mips) machine_CFLAGS="-DGRUB_MACHINE_MIPS_QEMU_MIPS=1 -DGRUB_MACHINE_MIPS=1 -DGRUB_MACHINE_MIPS_BONITO=1" ;; esac CFLAGS="$CFLAGS $machine_CFLAGS" TARGET_CFLAGS="$TARGET_CFLAGS $machine_CFLAGS" diff --git a/include/grub/mips/qemu-r4k/boot.h b/include/grub/mips/qemu-mips/boot.h similarity index 100% rename from include/grub/mips/qemu-r4k/boot.h rename to include/grub/mips/qemu-mips/boot.h diff --git a/include/grub/mips/qemu-r4k/kernel.h b/include/grub/mips/qemu-mips/kernel.h similarity index 100% rename from include/grub/mips/qemu-r4k/kernel.h rename to include/grub/mips/qemu-mips/kernel.h diff --git a/include/grub/mips/qemu-r4k/loader.h b/include/grub/mips/qemu-mips/loader.h similarity index 100% rename from include/grub/mips/qemu-r4k/loader.h rename to include/grub/mips/qemu-mips/loader.h diff --git a/include/grub/mips/qemu-r4k/machine.h b/include/grub/mips/qemu-mips/machine.h similarity index 100% rename from include/grub/mips/qemu-r4k/machine.h rename to include/grub/mips/qemu-mips/machine.h diff --git a/include/grub/mips/qemu-r4k/memory.h b/include/grub/mips/qemu-mips/memory.h similarity index 100% rename from include/grub/mips/qemu-r4k/memory.h rename to include/grub/mips/qemu-mips/memory.h diff --git a/include/grub/mips/qemu-r4k/serial.h b/include/grub/mips/qemu-mips/serial.h similarity index 100% rename from include/grub/mips/qemu-r4k/serial.h rename to include/grub/mips/qemu-mips/serial.h diff --git a/include/grub/mips/qemu-r4k/time.h b/include/grub/mips/qemu-mips/time.h similarity index 100% rename from include/grub/mips/qemu-r4k/time.h rename to include/grub/mips/qemu-mips/time.h diff --git a/kern/mips/qemu-r4k/init.c b/kern/mips/qemu-mips/init.c similarity index 100% rename from kern/mips/qemu-r4k/init.c rename to kern/mips/qemu-mips/init.c From 0ee6924f69ed278d19764705ac1acdbc92216c2b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 2 Dec 2009 10:00:54 +0100 Subject: [PATCH 129/738] Revert USB-related MIPS changes --- bus/usb/ohci.c | 27 +++++++++++---------------- conf/mips-yeeloong.rmk | 30 ------------------------------ term/usb_keyboard.c | 1 + 3 files changed, 12 insertions(+), 46 deletions(-) diff --git a/bus/usb/ohci.c b/bus/usb/ohci.c index 163cee2eb..5fe9c9507 100644 --- a/bus/usb/ohci.c +++ b/bus/usb/ohci.c @@ -27,9 +27,6 @@ #include #include -#define vtop(x) ((x) & 0x7fffffff) -#define ptov(x) ((x) | 0x80000000) - struct grub_ohci_hcca { /* Pointers to Interrupt Endpoint Descriptors. Not used by @@ -155,7 +152,7 @@ grub_ohci_pci_iter (grub_pci_device_t dev, if (! o) return 1; - o->iobase = (grub_uint32_t *) ptov (base); + o->iobase = (grub_uint32_t *) base; /* Reserve memory for the HCCA. */ o->hcca = (struct grub_ohci_hcca *) grub_memalign (256, 256); @@ -181,7 +178,7 @@ grub_ohci_pci_iter (grub_pci_device_t dev, grub_ohci_writereg32 (o, GRUB_OHCI_REG_FRAME_INTERVAL, frame_interval); /* Setup the HCCA. */ - grub_ohci_writereg32 (o, GRUB_OHCI_REG_HCCA, vtop ((grub_uint32_t) o->hcca)); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_HCCA, (grub_uint32_t) o->hcca); grub_dprintf ("ohci", "OHCI HCCA\n"); /* Enable the OHCI. */ @@ -267,10 +264,10 @@ grub_ohci_transaction (grub_ohci_td_t td, buffer = (grub_uint32_t) data; buffer_end = buffer + size - 1; - td->token = grub_cpu_to_le32 (vtop (token)); - td->buffer = grub_cpu_to_le32 (vtop (buffer)); + td->token = grub_cpu_to_le32 (token); + td->buffer = grub_cpu_to_le32 (buffer); td->next_td = 0; - td->buffer_end = grub_cpu_to_le32 (vtop (buffer_end)); + td->buffer_end = grub_cpu_to_le32 (buffer_end); } static grub_usb_err_t @@ -310,8 +307,7 @@ grub_ohci_transfer (grub_usb_controller_t dev, grub_ohci_transaction (&td_list[i], tr->pid, tr->toggle, tr->size, tr->data); - td_list[i].next_td = grub_cpu_to_le32 (vtop ((grub_addr_t) - &td_list[i + 1])); + td_list[i].next_td = grub_cpu_to_le32 (&td_list[i + 1]); } /* Setup the Endpoint Descriptor. */ @@ -328,9 +324,9 @@ grub_ohci_transfer (grub_usb_controller_t dev, /* Set the maximum packet size. */ target |= transfer->max << 16; - td_head = vtop ((grub_uint32_t) td_list); + td_head = (grub_uint32_t) td_list; - td_tail = vtop ((grub_uint32_t) &td_list[transfer->transcnt]); + td_tail = (grub_uint32_t) &td_list[transfer->transcnt]; ed->target = grub_cpu_to_le32 (target); ed->td_head = grub_cpu_to_le32 (td_head); @@ -357,8 +353,7 @@ grub_ohci_transfer (grub_usb_controller_t dev, status &= ~(1 << 2); grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, status); - grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKHEAD, - vtop ((grub_uint32_t) ed)); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKHEAD, (grub_uint32_t) ed); /* Enable the Bulk list. */ control |= 1 << 5; @@ -386,9 +381,9 @@ grub_ohci_transfer (grub_usb_controller_t dev, grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, status); grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD, - vtop ((grub_uint32_t) ed)); + (grub_uint32_t) ed); grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD+1, - vtop ((grub_uint32_t) ed)); + (grub_uint32_t) ed); /* Enable the Control list. */ control |= 1 << 4; diff --git a/conf/mips-yeeloong.rmk b/conf/mips-yeeloong.rmk index 68c426e1b..16909487d 100644 --- a/conf/mips-yeeloong.rmk +++ b/conf/mips-yeeloong.rmk @@ -29,36 +29,6 @@ lspci_mod_SOURCES = commands/lspci.c lspci_mod_CFLAGS = $(COMMON_CFLAGS) lspci_mod_LDFLAGS = $(COMMON_LDFLAGS) -# For ohci.mod -pkglib_MODULES += ohci.mod -ohci_mod_SOURCES = bus/usb/ohci.c -ohci_mod_CFLAGS = $(COMMON_CFLAGS) -ohci_mod_LDFLAGS = $(COMMON_LDFLAGS) - -# For usb.mod -pkglib_MODULES += usb.mod -usb_mod_SOURCES = bus/usb/usb.c bus/usb/usbtrans.c bus/usb/usbhub.c -usb_mod_CFLAGS = $(COMMON_CFLAGS) -usb_mod_LDFLAGS = $(COMMON_LDFLAGS) - -# For usbtest.mod -pkglib_MODULES += usbtest.mod -usbtest_mod_SOURCES = commands/usbtest.c -usbtest_mod_CFLAGS = $(COMMON_CFLAGS) -usbtest_mod_LDFLAGS = $(COMMON_LDFLAGS) - -# For usbms.mod -pkglib_MODULES += usbms.mod -usbms_mod_SOURCES = disk/usbms.c -usbms_mod_CFLAGS = $(COMMON_CFLAGS) -usbms_mod_LDFLAGS = $(COMMON_LDFLAGS) - -# For usb_keyboard.mod -pkglib_MODULES += usb_keyboard.mod -usb_keyboard_mod_SOURCES = term/usb_keyboard.c -usb_keyboard_mod_CFLAGS = $(COMMON_CFLAGS) -usb_keyboard_mod_LDFLAGS = $(COMMON_LDFLAGS) - # For at_keyboard.mod. pkglib_MODULES += at_keyboard.mod at_keyboard_mod_SOURCES = term/at_keyboard.c diff --git a/term/usb_keyboard.c b/term/usb_keyboard.c index 69d5709b6..5d76c5e02 100644 --- a/term/usb_keyboard.c +++ b/term/usb_keyboard.c @@ -18,6 +18,7 @@ */ #include +#include #include #include #include From 035a008c137592a0a0ae2125cfda8d946a1436e3 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 2 Dec 2009 11:44:29 +0100 Subject: [PATCH 130/738] Remove leftover --- include/grub/dl.h | 2 - include/grub/i386/memory.h.moved | 30 -------- include/grub/i386/relocator.h.moved | 41 ----------- include/grub/mips/qemu-mips/machine.h | 24 ------ kern/mips/startup.S | 2 - lib/i386/relocator.c.moved | 102 -------------------------- lib/i386/relocator_backward.S.moved | 2 - 7 files changed, 203 deletions(-) delete mode 100644 include/grub/i386/memory.h.moved delete mode 100644 include/grub/i386/relocator.h.moved delete mode 100644 include/grub/mips/qemu-mips/machine.h delete mode 100644 lib/i386/relocator.c.moved delete mode 100644 lib/i386/relocator_backward.S.moved diff --git a/include/grub/dl.h b/include/grub/dl.h index 5bfcb0cf7..9340b6ce4 100644 --- a/include/grub/dl.h +++ b/include/grub/dl.h @@ -116,8 +116,6 @@ grub_err_t EXPORT_FUNC(grub_dl_register_symbol) (const char *name, void *addr, grub_err_t grub_arch_dl_check_header (void *ehdr); grub_err_t grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr); -grub_err_t grub_arch_dl_check_header (void *ehdr); - #if defined (_mips) && ! defined (GRUB_UTIL) #define GRUB_LINKER_HAVE_INIT 1 void grub_arch_dl_init_linker (void); diff --git a/include/grub/i386/memory.h.moved b/include/grub/i386/memory.h.moved deleted file mode 100644 index a0f3192b8..000000000 --- a/include/grub/i386/memory.h.moved +++ /dev/null @@ -1,30 +0,0 @@ -/* memory.h - describe the memory map */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2002,2007,2008 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_MEMORY_CPU_HEADER -#define GRUB_MEMORY_CPU_HEADER 1 - -/* The flag for protected mode. */ -#define GRUB_MEMORY_CPU_CR0_PE_ON 0x1 -#define GRUB_MEMORY_CPU_CR4_PAE_ON 0x00000040 -#define GRUB_MEMORY_CPU_CR0_PAGING_ON 0x80000000 -#define GRUB_MEMORY_CPU_AMD64_MSR 0xc0000080 -#define GRUB_MEMORY_CPU_AMD64_MSR_ON 0x00000100 - -#endif /* ! GRUB_MEMORY_CPU_HEADER */ diff --git a/include/grub/i386/relocator.h.moved b/include/grub/i386/relocator.h.moved deleted file mode 100644 index ef7fe23aa..000000000 --- a/include/grub/i386/relocator.h.moved +++ /dev/null @@ -1,41 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2009 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_RELOCATOR_CPU_HEADER -#define GRUB_RELOCATOR_CPU_HEADER 1 - -#include -#include - -struct grub_relocator32_state -{ - grub_uint32_t esp; - grub_uint32_t eax; - grub_uint32_t ebx; - grub_uint32_t ecx; - grub_uint32_t edx; - grub_uint32_t eip; -}; - -void *grub_relocator32_alloc (grub_size_t size); -grub_err_t grub_relocator32_boot (void *relocator, grub_uint32_t dest, - struct grub_relocator32_state state); -void *grub_relocator32_realloc (void *relocator, grub_size_t size); -void grub_relocator32_free (void *relocator); - -#endif /* ! GRUB_RELOCATOR_CPU_HEADER */ diff --git a/include/grub/mips/qemu-mips/machine.h b/include/grub/mips/qemu-mips/machine.h deleted file mode 100644 index 386cad750..000000000 --- a/include/grub/mips/qemu-mips/machine.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2007 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_MACHINE_MACHINE_HEADER -#define GRUB_MACHINE_MACHINE_HEADER 1 - -#define GRUB_MACHINE_MIPS_QEMU_R4K 1 - -#endif /* ! GRUB_MACHINE_MACHINE_HEADER */ diff --git a/kern/mips/startup.S b/kern/mips/startup.S index afab3642e..b27442102 100644 --- a/kern/mips/startup.S +++ b/kern/mips/startup.S @@ -71,8 +71,6 @@ reloccont: li $t3, (GRUB_MOD_ALIGN-1) nor $t3, $t3, $0 and $t1, $t1, $t3 - /* Pass modules address as first argument. */ -// move $a0, $t1 lw $t3, (GRUB_KERNEL_CPU_TOTAL_MODULE_SIZE - BASE_ADDR)($t9) diff --git a/lib/i386/relocator.c.moved b/lib/i386/relocator.c.moved deleted file mode 100644 index ae7caf28b..000000000 --- a/lib/i386/relocator.c.moved +++ /dev/null @@ -1,102 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2009 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include - -#include -#include -#include - -#include - -extern grub_uint8_t grub_relocator32_forward_start; -extern grub_uint8_t grub_relocator32_forward_end; -extern grub_uint8_t grub_relocator32_backward_start; -extern grub_uint8_t grub_relocator32_backward_end; - -extern grub_uint32_t grub_relocator32_backward_dest; -extern grub_uint32_t grub_relocator32_backward_size; -extern grub_addr_t grub_relocator32_backward_src; - -extern grub_uint32_t grub_relocator32_forward_dest; -extern grub_uint32_t grub_relocator32_forward_size; -extern grub_addr_t grub_relocator32_forward_src; - -extern grub_uint32_t grub_relocator32_forward_eax; -extern grub_uint32_t grub_relocator32_forward_ebx; -extern grub_uint32_t grub_relocator32_forward_ecx; -extern grub_uint32_t grub_relocator32_forward_edx; -extern grub_uint32_t grub_relocator32_forward_eip; -extern grub_uint32_t grub_relocator32_forward_esp; - -extern grub_uint32_t grub_relocator32_backward_eax; -extern grub_uint32_t grub_relocator32_backward_ebx; -extern grub_uint32_t grub_relocator32_backward_ecx; -extern grub_uint32_t grub_relocator32_backward_edx; -extern grub_uint32_t grub_relocator32_backward_eip; -extern grub_uint32_t grub_relocator32_backward_esp; - -#define RELOCATOR_SIZEOF(x) (&grub_relocator32_##x##_end - &grub_relocator32_##x##_start) -#define RELOCATOR_ALIGN 16 -#define PREFIX(x) grub_relocator32_ ## x - -static void -write_call_relocator_bw (void *ptr, void *src, grub_uint32_t dest, - grub_size_t size, struct grub_relocator32_state state) -{ - grub_relocator32_backward_dest = dest; - grub_relocator32_backward_src = PTR_TO_UINT64 (src); - grub_relocator32_backward_size = size; - - grub_relocator32_backward_eax = state.eax; - grub_relocator32_backward_ebx = state.ebx; - grub_relocator32_backward_ecx = state.ecx; - grub_relocator32_backward_edx = state.edx; - grub_relocator32_backward_eip = state.eip; - grub_relocator32_backward_esp = state.esp; - - grub_memmove (ptr, - &grub_relocator32_backward_start, - RELOCATOR_SIZEOF (backward)); - ((void (*) (void)) ptr) (); -} - -static void -write_call_relocator_fw (void *ptr, void *src, grub_uint32_t dest, - grub_size_t size, struct grub_relocator32_state state) -{ - - grub_relocator32_forward_dest = dest; - grub_relocator32_forward_src = PTR_TO_UINT64 (src); - grub_relocator32_forward_size = size; - - grub_relocator32_forward_eax = state.eax; - grub_relocator32_forward_ebx = state.ebx; - grub_relocator32_forward_ecx = state.ecx; - grub_relocator32_forward_edx = state.edx; - grub_relocator32_forward_eip = state.eip; - grub_relocator32_forward_esp = state.esp; - - grub_memmove (ptr, - &grub_relocator32_forward_start, - RELOCATOR_SIZEOF (forward)); - ((void (*) (void)) ptr) (); -} - -#include "../relocator.c" diff --git a/lib/i386/relocator_backward.S.moved b/lib/i386/relocator_backward.S.moved deleted file mode 100644 index 06913470e..000000000 --- a/lib/i386/relocator_backward.S.moved +++ /dev/null @@ -1,2 +0,0 @@ -#define BACKWARD -#include "relocator_asm.S" From 3d87b0ea7ca77f7864ebcc79a7465c0d4f0fab39 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 2 Dec 2009 11:48:10 +0100 Subject: [PATCH 131/738] Fix style --- video/sm712.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/video/sm712.c b/video/sm712.c index 93156c9ae..52e43e9ae 100644 --- a/video/sm712.c +++ b/video/sm712.c @@ -92,8 +92,8 @@ grub_video_sm712_setup (unsigned int width, unsigned int height, depth = (mode_type & GRUB_VIDEO_MODE_TYPE_DEPTH_MASK) >> GRUB_VIDEO_MODE_TYPE_DEPTH_POS; - if ((1024 != width && width != 0) || (600 != height && height != 0) - || (16 != depth && depth != 0)) + if ((width != 1024 && width != 0) || (height != 600 && height != 0) + || (depth != 16 && depth != 0)) return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "Only 1024x600x16 is supported"); From ff684a8d7d4dcaf088ace651e3bb5a33226b0f0d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 2 Dec 2009 13:31:10 +0100 Subject: [PATCH 132/738] Propagate gettext changes from trunk --- util/grub-mkrawimage.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/util/grub-mkrawimage.c b/util/grub-mkrawimage.c index 073ebd7ed..bbdbf9c8b 100644 --- a/util/grub-mkrawimage.c +++ b/util/grub-mkrawimage.c @@ -149,7 +149,7 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], grub_util_load_image (kernel_path, kernel_img); if (GRUB_KERNEL_MACHINE_PREFIX + strlen (prefix) + 1 > GRUB_KERNEL_MACHINE_DATA_END) - grub_util_error (_("prefix too long")); + grub_util_error (_("prefix is too long")); strcpy (kernel_img + GRUB_KERNEL_MACHINE_PREFIX, prefix); /* Fill in the grub_module_info structure. */ @@ -419,7 +419,7 @@ static void usage (int status) { if (status) - fprintf (stderr, "Try ``grub-mkimage --help'' for more information.\n"); + fprintf (stderr, _("Try ``%s --help'' for more information.\n"), program_name); else printf (_("\ Usage: grub-mkimage [OPTION]... [MODULES]\n\ From b4c2d69bdea1b05aab5f692948ef91daaa21191d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 2 Dec 2009 13:31:47 +0100 Subject: [PATCH 133/738] Changelog --- ChangeLog.mips | 140 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 ChangeLog.mips diff --git a/ChangeLog.mips b/ChangeLog.mips new file mode 100644 index 000000000..cdfe05532 --- /dev/null +++ b/ChangeLog.mips @@ -0,0 +1,140 @@ +2009-12-02 Vladimir Serbinenko + + MIPS support. + + * bus/bonito.c: New file. + * bus/pci.c (grub_pci_iterate): Use GRUB_PCI_NUM_BUS and + GRUB_PCI_NUM_DEVICES. + * term/i386/pc/serial.c: Move to ... + * term/serial.c: ... here. All users updated. + * util/i386/pc/grub-mkimage.c: Move to ... + * util/grub-mkrawimage.c: ... here. All users updated. + * term/i386/pc/at_keyboard.c: Move to ... + * term/at_keyboard.c: ... here. All users updated. + * conf/mips-qemu-mips.rmk: New file. + * conf/mips-yeeloong.rmk: Likewise. + * conf/mips.rmk: Likewise. + * configure.ac: New platforms mipsel-yeeloong, mips-qemu-mips and + mipsel-qemu-mips. + * disk/ata.c (grub_ata_device_initialize): Add GRUB_MACHINE_PCI_IO_BASE + to port addresses. + (grub_ata_pciinit): Support CS5536. + * font/font.c (grub_font_load): Use grub_file_t instead of filename. + * font/font_cmd.c (loadfont_command): Open file before passing it to + grub_font_load. + (pseudo_file_read): New function. + (pseudo_file_close): Likewise. + (pseudo_fs): New structure. + (load_font_module): New function. + (GRUB_MOD_INIT(font_manager)): Load embedded font. + * fs/cpio.c (grub_cpio_open): Handle partial matches correctly. + * genmk.rb: Strip .rel.dyn, .reginfo, .note and .comment. + * genmoddep.awk: Ignore __gnu_local_gp. It's defined by linker. + * include/grub/i386/at_keyboard.h: Split into ... + * include/grub/at_keyboard.h: ... this ... + * include/grub/i386/at_keyboard.h: ... and this. + * include/grub/dl.h (grub_arch_dl_init_linker) [_mips && !GRUB_UTIL]: + New prototype. + * include/grub/elfload.h (grub_elf32_size): New parameter. All users + updated. + (grub_elf64_size): Likewise. + * include/grub/font.h (grub_font_load): Use grub_file_t instead of + filename. + * include/grub/i386/io.h (grub_port_t): New type. All users updated. + * include/grub/i386/coreboot/serial.h: Rewritten. + * include/grub/i386/ieee1275/serial.h: Include + grub/i386/coreboot/serial.h instead of grub/i386/pc/serial.h. + * include/grub/i386/pc/serial.h: Moved from here ... + * include/grub/serial.h: ... to here. All users updated. + * include/grub/i386/pci.h (GRUB_MACHINE_PCI_IO_BASE): New definition. + (GRUB_PCI_NUM_BUS): Likewise. + (GRUB_PCI_NUM_DEVICES): Likewise. + (grub_pci_device_map_range): Add missing volatile keyword. + * include/grub/kernel.h (OBJ_TYPE_FONT): New enum value. + * include/grub/mips/at_keyboard.h: New file. + * include/grub/mips/cache.h: Likewise. + * include/grub/mips/io.h: Likewise. + * include/grub/mips/kernel.h: Likewise. + * include/grub/mips/libgcc.h: Likewise. + * include/grub/mips/pci.h: Likewise. + * include/grub/mips/qemu-mips/boot.h: Likewise. + * include/grub/mips/qemu-mips/kernel.h: Likewise. + * include/grub/mips/qemu-mips/loader.h: Likewise. + * include/grub/mips/qemu-mips/memory.h: Likewise. + * include/grub/mips/qemu-mips/serial.h: Likewise. + * include/grub/mips/qemu-mips/time.h: Likewise. + * include/grub/mips/reboot.h: Likewise. + * include/grub/mips/relocator.h: Likewise. + * include/grub/mips/time.h: Likewise. + * include/grub/mips/types.h: Likewise. + * include/grub/mips/yeeloong/at_keyboard.h: Likewise. + * include/grub/mips/yeeloong/boot.h: Likewise. + * include/grub/mips/yeeloong/kernel.h: Likewise. + * include/grub/mips/yeeloong/loader.h: Likewise. + * include/grub/mips/yeeloong/memory.h: Likewise. + * include/grub/mips/yeeloong/pci.h: Likewise. + * include/grub/mips/yeeloong/serial.h: Likewise. + * include/grub/mips/yeeloong/time.h: Likewise. + * kern/dl.c (grub_dl_resolve_symbols): Handle STT_OBJECT correctly. + * kern/elf.c (grub_elf32_size): New parameter. All users + updated. + (grub_elf64_size): Likewise. + * kern/main.c (grub_main): Call grub_arch_dl_init_linker if necessary. + Load modules before saying "Welcome to GRUB!". + Call grub_refresh after saying "Welcome to GRUB!". + * kern/mips/cache.S: New file. + * kern/mips/cache_flush.S: Likewise. + * kern/mips/dl.c: Likewise. + * kern/mips/init.c: Likewise. + * kern/mips/qemu-mips/init.c: Likewise. + * kern/mips/startup.S: Likewise. + * kern/mips/yeeloong/init.c: Likewise. + * kern/term.c (grub_putcode): Handle NULL terminal. + (grub_getcharwidth): Likewise. + (grub_getkey): Likewise. + (grub_checkkey): Likewise. + (grub_getkeystatus): Likewise. + (grub_getxy): Likewise. + (grub_getwh): Likewise. + (grub_gotoxy): Likewise. + (grub_cls): Likewise. + (grub_setcolorstate): Likewise. + (grub_setcolor): Likewise. + (grub_getcolor): Likewise. + (grub_refresh): Likewise. + * lib/mips/relocator.c (JUMP_SIZEOF): Fix incorrect value. + (write_jump): Add hatch nop. + * lib/mips/relocator_asm.S: Use kern/mips/cache_flush.S. + * lib/mips/setjmp.S: New file. + * loader/mips/linux.c: Likewise. + * term/i386/pc/at_keyboard.c: Move from here ... + * term/at_keyboard.c: ... to here. + * term/i386/pc/serial.c: Moved from here ... + * term/serial.c: ... to here. All users updated. + (TEXT_HEIGHT): Set to 24 to fit linux terminal. + (serial_hw_io_addr): Use GRUB_MACHINE_SERIAL_PORTS. + (serial_translate_key_sequence): Avoid deadlock. + (grub_serial_getkey): Handle backspace. + (grub_serial_putchar): Fix newline handling. + * util/i386/pc/grub-mkimage.c: Move from here ... + * util/grub-mkrawimage.c: ... to here. All users updated. + (generate_image): New parameters 'font_path' and 'format'. + Support embedding font. + Use grub_host_to_target* instead of grub_cpu_to_le*. + (generate_image) [GRUB_MACHINE_MIPS]: Support ELF encapsulation. + (options) [GRUB_PLATFORM_IMAGE_DEFAULT]: New option "--format". + (options): New option "--font". + (usage): Likewise. + (main) [GRUB_PLATFORM_IMAGE_DEFAULT]: Handle "--format". + (main): Handle "--font". + * term/gfxterm.c (grub_virtual_screen): New member bg_color_display. + (grub_virtual_screen_setup): Set bg_color_display. + (redraw_screen_rect): Use bg_color_display instead of incorrect + bg_color. + (grub_gfxterm_cls): Likewise. + * util/elf/grub-mkimage.c (load_modules): New parameter 'config_path'. + Support embedding config file. + (add_segments): Likewise. + (options): New option "--config". + (main): Handle "--config". + * video/sm712.c: New file. From 1c7926d8237bea29467f496369972ac4451d4e23 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 2 Dec 2009 14:02:37 +0100 Subject: [PATCH 134/738] Remove leftover in mips.rmk --- conf/mips.rmk | 57 --------------------------------------------------- 1 file changed, 57 deletions(-) diff --git a/conf/mips.rmk b/conf/mips.rmk index 8c99d9813..5c96a969f 100644 --- a/conf/mips.rmk +++ b/conf/mips.rmk @@ -27,63 +27,6 @@ kernel_syms.lst: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h genke # Programs pkglib_IMAGES = kernel.img - -# Utilities. -sbin_UTILITIES = grub-mkdevicemap -ifeq ($(enable_grub_emu), yes) -sbin_UTILITIES += grub-emu -endif - -# For grub-mkdevicemap. -grub_mkdevicemap_SOURCES = util/grub-mkdevicemap.c util/deviceiter.c \ - util/devicemap.c util/misc.c - -# For grub-emu -util/grub-emu.c_DEPENDENCIES = grub_emu_init.h -grub_emu_SOURCES = commands/minicmd.c commands/cat.c commands/cmp.c \ - commands/configfile.c commands/help.c \ - commands/search.c commands/handler.c commands/test.c \ - commands/ls.c commands/blocklist.c commands/hexdump.c \ - lib/hexdump.c commands/reboot.c \ - lib/envblk.c commands/loadenv.c \ - commands/gptsync.c commands/probe.c commands/xnu_uuid.c \ - commands/password.c commands/keystatus.c \ - disk/loopback.c \ - \ - fs/affs.c fs/cpio.c fs/fat.c fs/ext2.c fs/hfs.c \ - fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \ - fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c \ - fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/afs_be.c \ - fs/befs.c fs/befs_be.c fs/tar.c \ - \ - io/gzio.c \ - kern/device.c kern/disk.c kern/dl.c kern/elf.c kern/env.c \ - kern/err.c kern/file.c kern/fs.c commands/boot.c kern/main.c \ - kern/misc.c kern/parser.c kern/partition.c kern/reader.c \ - kern/rescue_reader.c kern/rescue_parser.c \ - kern/term.c kern/list.c kern/handler.c fs/fshelp.c \ - kern/command.c kern/corecmd.c commands/extcmd.c \ - lib/arg.c normal/cmdline.c normal/datetime.c \ - normal/completion.c normal/misc.c \ - normal/handler.c normal/auth.c normal/autofs.c normal/main.c \ - normal/menu.c \ - normal/menu_text.c \ - normal/menu_entry.c normal/menu_viewer.c \ - normal/color.c \ - script/sh/main.c script/sh/execute.c script/sh/function.c \ - script/sh/lexer.c script/sh/script.c \ - partmap/amiga.c partmap/apple.c partmap/msdos.c partmap/sun.c \ - partmap/acorn.c \ - util/console.c util/hostfs.c util/grub-emu.c util/misc.c \ - util/hostdisk.c util/getroot.c \ - \ - disk/raid.c disk/raid5_recover.c disk/raid6_recover.c \ - disk/mdraid_linux.c disk/dmraid_nvidia.c disk/lvm.c \ - commands/parttool.c parttool/msdospart.c \ - grub_script.tab.c grub_emu_init.c - -grub_emu_LDFLAGS = $(LIBCURSES) - kernel_img_SOURCES = kern/$(target_cpu)/startup.S \ kern/main.c kern/device.c kern/$(target_cpu)/init.c \ kern/$(target_cpu)/$(target_machine)/init.c \ From 3478d0aa2e372fade831ab5f911eff22a68d98bf Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 2 Dec 2009 14:05:56 +0100 Subject: [PATCH 135/738] Fix warning --- loader/mips/linux.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/loader/mips/linux.c b/loader/mips/linux.c index 86f4201b0..4d9045a65 100644 --- a/loader/mips/linux.c +++ b/loader/mips/linux.c @@ -174,7 +174,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), grub_elf_t elf = 0; int i; int size; - void *extra; + void *extra = NULL; grub_uint32_t *linux_argv, *linux_envp; char *linux_args; grub_err_t err; From d065a04ae4a9eddef91fc52be1e0deb7c9bd3902 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 2 Dec 2009 14:28:11 +0100 Subject: [PATCH 136/738] Fix lexer.c name in mips.rmk --- conf/mips.rmk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/mips.rmk b/conf/mips.rmk index 5c96a969f..63c755c49 100644 --- a/conf/mips.rmk +++ b/conf/mips.rmk @@ -6,7 +6,7 @@ COMMON_CFLAGS += -mexplicit-relocs -mflush-func=grub_cpu_flush_cache COMMON_LDFLAGS += -nostdlib # Used by various components. These rules need to precede them. -script/sh/lexer.c_DEPENDENCIES = grub_script.tab.h +script/lexer.c_DEPENDENCIES = grub_script.tab.h # Images. From f505738643d0c580026f63d28777eb5bef8ff4da Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 2 Dec 2009 14:42:28 +0100 Subject: [PATCH 137/738] Fix warning --- gfxmenu/gui_string_util.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gfxmenu/gui_string_util.c b/gfxmenu/gui_string_util.c index 31b2f0aca..8ea7c497b 100644 --- a/gfxmenu/gui_string_util.c +++ b/gfxmenu/gui_string_util.c @@ -206,7 +206,7 @@ grub_get_dirname (const char *file_path) } static __inline int -isxdigit (char c) +my_isxdigit (char c) { return ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') @@ -261,7 +261,7 @@ grub_gui_parse_color (const char *s, grub_gui_color_t *color) /* Count the hexits to determine the format. */ int hexits = 0; const char *end = s; - while (isxdigit (*end)) + while (my_isxdigit (*end)) { end++; hexits++; From f0299c60d477a90fa96c595b47ca06baec2b5ff8 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 2 Dec 2009 21:01:02 +0100 Subject: [PATCH 138/738] Fix handling of >32K relocations --- kern/mips/dl.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/kern/mips/dl.c b/kern/mips/dl.c index f2a0af0d5..485955e7f 100644 --- a/kern/mips/dl.c +++ b/kern/mips/dl.c @@ -162,18 +162,23 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) case R_MIPS_HI16: { grub_uint32_t value; + Elf_Rel *rel2; /* Handle partner lo16 relocation. Lower part is treated as signed. Hence add 0x8000 to compensate. */ 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; + 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) + { + value += *(grub_int16_t *) + ((char *) seg->addr + rel2->r_offset); + break; + } + *(grub_uint16_t *) addr = (value >> 16) & 0xffff; } break; case R_MIPS_LO16: From 17d1956f5c5bab387f544bdffa0c9041ae8d80c6 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 2 Dec 2009 21:03:41 +0100 Subject: [PATCH 139/738] Fix cursor drawing and whole screen scrolling --- term/gfxterm.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/term/gfxterm.c b/term/gfxterm.c index be0487830..eb2c47c3d 100644 --- a/term/gfxterm.c +++ b/term/gfxterm.c @@ -754,19 +754,22 @@ real_scroll (void) } - /* Draw cursor if visible. */ - if (virtual_screen.cursor_state) - draw_cursor (1); - was_scroll = virtual_screen.total_scroll; virtual_screen.total_scroll = 0; + if (was_scroll > virtual_screen.rows) + was_scroll = virtual_screen.rows; + /* Draw shadow part. */ for (i = virtual_screen.rows - was_scroll; i < virtual_screen.rows; i++) for (j = 0; j < virtual_screen.columns; j++) paint_char (j, i); + /* Draw cursor if visible. */ + if (virtual_screen.cursor_state) + draw_cursor (1); + if (repaint_callback) repaint_callback (window.x, window.y, window.width, window.height); } From c4282e6cb3dfc4e2eaf6b7e8df89e0662e564b42 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Fri, 4 Dec 2009 00:05:48 +0000 Subject: [PATCH 140/738] Remove mips/reboot.h. --- ChangeLog.mips | 1 - include/grub/mips/reboot.h | 24 ------------------------ 2 files changed, 25 deletions(-) delete mode 100644 include/grub/mips/reboot.h diff --git a/ChangeLog.mips b/ChangeLog.mips index cdfe05532..f5f048298 100644 --- a/ChangeLog.mips +++ b/ChangeLog.mips @@ -63,7 +63,6 @@ * include/grub/mips/qemu-mips/memory.h: Likewise. * include/grub/mips/qemu-mips/serial.h: Likewise. * include/grub/mips/qemu-mips/time.h: Likewise. - * include/grub/mips/reboot.h: Likewise. * include/grub/mips/relocator.h: Likewise. * include/grub/mips/time.h: Likewise. * include/grub/mips/types.h: Likewise. diff --git a/include/grub/mips/reboot.h b/include/grub/mips/reboot.h deleted file mode 100644 index b28fca158..000000000 --- a/include/grub/mips/reboot.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2008 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_REBOOT_CPU_HEADER -#define GRUB_REBOOT_CPU_HEADER 1 - -extern void grub_reboot (void); - -#endif From bef393d4b355926078aae8c952a972e01e2adc56 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 5 Dec 2009 18:46:28 +0100 Subject: [PATCH 141/738] fix qemu and coreboot ports --- conf/i386-coreboot.rmk | 4 +++- conf/i386-pc.rmk | 2 +- conf/mips.rmk | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/conf/i386-coreboot.rmk b/conf/i386-coreboot.rmk index d0f953c8a..b6e810605 100644 --- a/conf/i386-coreboot.rmk +++ b/conf/i386-coreboot.rmk @@ -53,9 +53,11 @@ boot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_BOOT_MACHINE_LI boot_img_FORMAT = binary bin_UTILITIES += grub-mkimage -grub_mkimage_SOURCES = util/i386/pc/grub-mkimage.c util/misc.c \ +grub_mkimage_SOURCES = util/grub-mkrawimage.c util/misc.c \ util/resolve.c gnulib/progname.c grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR) +util/grub-mkrawimage.c_DEPENDENCIES = Makefile + pkglib_IMAGES += kernel.img kernel_img_SOURCES = kern/i386/qemu/startup.S \ diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk index c1b1e596e..598e46043 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -87,7 +87,7 @@ sbin_UTILITIES = grub-setup grub_mkimage_SOURCES = gnulib/progname.c util/grub-mkrawimage.c util/misc.c \ util/resolve.c lib/LzmaEnc.c lib/LzFind.c grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR) -util/i386/pc/grub-mkimage.c_DEPENDENCIES = Makefile +util/grub-mkrawimage.c_DEPENDENCIES = Makefile # For grub-setup. util/i386/pc/grub-setup.c_DEPENDENCIES = grub_setup_init.h diff --git a/conf/mips.rmk b/conf/mips.rmk index 63c755c49..a6fcaf88e 100644 --- a/conf/mips.rmk +++ b/conf/mips.rmk @@ -52,7 +52,7 @@ bin_UTILITIES += grub-mkimage grub_mkimage_SOURCES = gnulib/progname.c util/grub-mkrawimage.c util/misc.c \ util/resolve.c lib/LzmaEnc.c lib/LzFind.c grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(LINK_BASE) -util/i386/pc/grub-mkimage.c_DEPENDENCIES = Makefile +util/grub-mkrawimage.c_DEPENDENCIES = Makefile # Modules. pkglib_MODULES = memdisk.mod \ From a22078eb4fbdbb0e667b15c3d74a5b1ad192bcc9 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 6 Dec 2009 15:32:32 +0100 Subject: [PATCH 142/738] Startup code cleanup --- kern/mips/startup.S | 73 +++++++++++++++++++++++++----------------- util/grub-mkrawimage.c | 5 +-- 2 files changed, 44 insertions(+), 34 deletions(-) diff --git a/kern/mips/startup.S b/kern/mips/startup.S index b27442102..7c59e761e 100644 --- a/kern/mips/startup.S +++ b/kern/mips/startup.S @@ -42,27 +42,55 @@ kernel_image_size: .long 0 codestart: /* Decompress the payload. */ - move $t9, $ra - addiu $t2, $t9, GRUB_KERNEL_CPU_RAW_SIZE - BASE_ADDR - lui $t1, %hi(compressed) - addiu $t1, %lo(compressed) - lw $t3, (GRUB_KERNEL_CPU_COMPRESSED_SIZE - BASE_ADDR)($t9) + move $s0, $ra + addiu $a0, $s0, GRUB_KERNEL_CPU_RAW_SIZE - BASE_ADDR + lui $a1, %hi(compressed) + addiu $a1, %lo(compressed) + lw $a2, (GRUB_KERNEL_CPU_COMPRESSED_SIZE - BASE_ADDR)($s0) + move $s1, $a1 - /* $t2 contains source compressed address, $t1 is destination, - $t3 is compressed size. FIXME: put LZMA here. Don't clober $t9 + /* $a0 contains source compressed address, $a1 is destination, + $a2 is compressed size. FIXME: put LZMA here. Don't clober $s0, $s1. + On return $v0 contains uncompressed size. */ + move $v0, $a2 reloccont: - lb $t4, 0($t2) - sb $t4, 0($t1) - addiu $t1,$t1,1 - addiu $t2,$t2,1 - addiu $t3, 0xffff - bne $t3, $0, reloccont + lb $t4, 0($a0) + sb $t4, 0($a1) + addiu $a1,$a1,1 + addiu $a0,$a0,1 + addiu $a2, 0xffff + bne $a2, $0, reloccont + + move $a0, $s1 + move $a1, $v0 + +#include "cache_flush.S" + + lui $t1, %hi(cont) + addiu $t1, %lo(cont) + + jr $t1 + . = _start + GRUB_KERNEL_CPU_RAW_SIZE +compressed: + . = _start + GRUB_KERNEL_CPU_PREFIX + +VARIABLE(grub_prefix) + + /* to be filled by grub-mkelfimage */ + + /* + * Leave some breathing room for the prefix. + */ + + . = _start + GRUB_KERNEL_CPU_DATA_END + +cont: /* Move the modules out of BSS. */ lui $t1, %hi(_start) addiu $t1, %lo(_start) - lw $t2, (GRUB_KERNEL_CPU_KERNEL_IMAGE_SIZE - BASE_ADDR)($t9) + lw $t2, (GRUB_KERNEL_CPU_KERNEL_IMAGE_SIZE - BASE_ADDR)($s0) addu $t2, $t1, $t2 lui $t1, %hi(_end) @@ -72,7 +100,7 @@ reloccont: nor $t3, $t3, $0 and $t1, $t1, $t3 - lw $t3, (GRUB_KERNEL_CPU_TOTAL_MODULE_SIZE - BASE_ADDR)($t9) + lw $t3, (GRUB_KERNEL_CPU_TOTAL_MODULE_SIZE - BASE_ADDR)($s0) /* Backward copy. */ add $t1, $t1, $t3 @@ -105,20 +133,5 @@ bsscont: lui $t1, %hi(grub_main) addiu $t1, %lo(grub_main) -#if __mips >= 2 - sync -#endif jr $t1 - . = _start + GRUB_KERNEL_CPU_RAW_SIZE -compressed: - . = _start + GRUB_KERNEL_CPU_PREFIX - -VARIABLE(grub_prefix) - /* to be filled by grub-mkelfimage */ - - /* - * Leave some breathing room for the prefix. - */ - - . = _start + GRUB_KERNEL_CPU_DATA_END diff --git a/util/grub-mkrawimage.c b/util/grub-mkrawimage.c index bbdbf9c8b..5399f4c42 100644 --- a/util/grub-mkrawimage.c +++ b/util/grub-mkrawimage.c @@ -363,10 +363,7 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], phdr->p_flags = grub_host_to_target32 (PF_R | PF_W | PF_X); target_addr = ALIGN_UP (GRUB_KERNEL_MACHINE_LINK_ADDR - + kernel_size + total_module_size - + 0x100000 - // + BSS_SIZE - , 32); + + kernel_size + total_module_size, 32); ehdr->e_entry = grub_host_to_target32 (target_addr); phdr->p_vaddr = grub_host_to_target32 (target_addr); phdr->p_paddr = grub_host_to_target32 (target_addr); From d5b44e501d227f7b687f895eaa66ae980cfc4902 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 7 Dec 2009 02:09:39 +0100 Subject: [PATCH 143/738] retrieve firmware arguments --- include/grub/mips/kernel.h | 2 +- kern/mips/startup.S | 87 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 85 insertions(+), 4 deletions(-) diff --git a/include/grub/mips/kernel.h b/include/grub/mips/kernel.h index 29f7e4d4e..8b68f7b6b 100644 --- a/include/grub/mips/kernel.h +++ b/include/grub/mips/kernel.h @@ -25,7 +25,7 @@ #define GRUB_KERNEL_MACHINE_LINK_ALIGN 32 -#define GRUB_KERNEL_CPU_RAW_SIZE 0x100 +#define GRUB_KERNEL_CPU_RAW_SIZE 0x200 #define GRUB_KERNEL_CPU_COMPRESSED_SIZE 0x8 #define GRUB_KERNEL_CPU_TOTAL_MODULE_SIZE 0xc #define GRUB_KERNEL_CPU_KERNEL_IMAGE_SIZE 0x10 diff --git a/kern/mips/startup.S b/kern/mips/startup.S index 7c59e761e..5e3fb7ad5 100644 --- a/kern/mips/startup.S +++ b/kern/mips/startup.S @@ -31,6 +31,7 @@ __start: _start: start: bal codestart +base: . = _start + GRUB_KERNEL_CPU_COMPRESSED_SIZE compressed_size: .long 0 @@ -41,8 +42,69 @@ total_module_size: kernel_image_size: .long 0 codestart: - /* Decompress the payload. */ + /* Save our base. */ move $s0, $ra + + /* Parse arguments. Has to be done before relocation. + So need to do it in asm. */ +#ifdef GRUB_MACHINE_MIPS_YEELOONG + /* $a2 has the environment. */ + move $t0, $a2 +argcont: + lw $t1, 0($t0) + beq $t1, $zero, argdone +#define DO_PARSE(str, reg) \ + addiu $t2, $s0, (str-base);\ + bal parsestr;\ + beq $v0, $zero, 1f;\ + move reg, $v0;\ + b 2f;\ +1: + DO_PARSE (busclockstr, $s2) + DO_PARSE (cpuclockstr, $s3) + DO_PARSE (memsizestr, $s4) + DO_PARSE (highmemsizestr, $s5) +2: + addiu $t0, $t0, 4 + b argcont +parsestr: + move $v0, $zero + move $t3, $t1 +3: + lb $t4, 0($t2) + lb $t5, 0($t3) + addiu $t2, $t2, 1 + addiu $t3, $t3, 1 + beq $t5, $zero, 1f + beq $t5, $t4, 3b + bne $t4, $zero, 1f + + addiu $t3, $t3, 0xffff +digcont: + lb $t5, 0($t3) + /* Substract '0' from digit. */ + addiu $t5, $t5, 0xffd0 + bltz $t5, 1f + addiu $t4, $t5, 0xfff7 + bgtz $t4, 1f + /* Multiply $v0 by 10 with bitshifts. */ + sll $v0, $v0, 1 + sll $t4, $v0, 2 + addu $v0, $v0, $t4 + addu $v0, $v0, $t5 + addiu $t3, $t3, 1 + b digcont +1: + jr $ra +busclockstr: .asciiz "busclock=" +cpuclockstr: .asciiz "cpuclock=" +memsizestr: .asciiz "memsize=" +highmemsizestr: .asciiz "highmemsize=" + .p2align 2 +argdone: +#endif + + /* Decompress the payload. */ addiu $a0, $s0, GRUB_KERNEL_CPU_RAW_SIZE - BASE_ADDR lui $a1, %hi(compressed) addiu $a1, %lo(compressed) @@ -50,7 +112,8 @@ codestart: move $s1, $a1 /* $a0 contains source compressed address, $a1 is destination, - $a2 is compressed size. FIXME: put LZMA here. Don't clober $s0, $s1. + $a2 is compressed size. FIXME: put LZMA here. Don't clober $s0, + $s1, $s2, $s3, $s4 and $s5. On return $v0 contains uncompressed size. */ move $v0, $a2 @@ -84,9 +147,27 @@ VARIABLE(grub_prefix) */ . = _start + GRUB_KERNEL_CPU_DATA_END - +#ifdef GRUB_MACHINE_MIPS_YEELOONG +VARIABLE (grub_arch_busclock) + .long 0 +VARIABLE (grub_arch_cpuclock) + .long 0 +VARIABLE (grub_arch_memsize) + .long 0 +VARIABLE (grub_arch_highmemsize) + .long 0 +#endif cont: +#ifdef GRUB_MACHINE_MIPS_YEELOONG + lui $t1, %hi(grub_arch_busclock) + addiu $t1, %lo(grub_arch_busclock) + sw $s2, 0($t1) + sw $s3, 4($t1) + sw $s4, 8($t1) + sw $s5, 12($t1) +#endif + /* Move the modules out of BSS. */ lui $t1, %hi(_start) addiu $t1, %lo(_start) From 0f355bc6b321c2b8755de4facbd484145ddb4312 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 7 Dec 2009 16:16:10 +0100 Subject: [PATCH 144/738] add memory routines --- conf/mips-yeeloong.rmk | 7 +++ include/grub/mips/yeeloong/memory.h | 22 ++++++++-- kern/mips/yeeloong/init.c | 51 ++++++++++++++++------ loader/mips/linux.c | 35 +++++++++++++-- mmap/mips/yeeloong/uppermem.c | 66 +++++++++++++++++++++++++++++ mmap/mmap.c | 2 +- 6 files changed, 164 insertions(+), 19 deletions(-) create mode 100644 mmap/mips/yeeloong/uppermem.c diff --git a/conf/mips-yeeloong.rmk b/conf/mips-yeeloong.rmk index 16909487d..a06b3fa5e 100644 --- a/conf/mips-yeeloong.rmk +++ b/conf/mips-yeeloong.rmk @@ -40,3 +40,10 @@ pkglib_MODULES += ata_pthru.mod ata_pthru_mod_SOURCES = disk/ata_pthru.c ata_pthru_mod_CFLAGS = $(COMMON_CFLAGS) ata_pthru_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For mmap.mod. +pkglib_MODULES += mmap.mod +mmap_mod_SOURCES = mmap/mmap.c mmap/mips/yeeloong/uppermem.c +mmap_mod_CFLAGS = $(COMMON_CFLAGS) +mmap_mod_LDFLAGS = $(COMMON_LDFLAGS) +mmap_mod_ASFLAGS = $(COMMON_ASFLAGS) diff --git a/include/grub/mips/yeeloong/memory.h b/include/grub/mips/yeeloong/memory.h index bc8f47b12..c85db712a 100644 --- a/include/grub/mips/yeeloong/memory.h +++ b/include/grub/mips/yeeloong/memory.h @@ -26,15 +26,22 @@ #endif #define GRUB_MACHINE_MEMORY_STACK_HIGH 0x801ffff0 -#define GRUB_MACHINE_MEMORY_USABLE 0x81000000 +#define GRUB_ARCH_LOWMEMVSTART 0x80000000 +#define GRUB_ARCH_LOWMEMPSTART 0x00000000 +#define GRUB_ARCH_LOWMEMMAXSIZE 0x10000000 +#define GRUB_ARCH_HIGHMEMPSTART 0x10000000 + #define GRUB_MACHINE_MEMORY_AVAILABLE 1 +#define GRUB_MACHINE_MEMORY_MAX_TYPE 1 + /* This one is special: it's used internally but is never reported + by firmware. */ +#define GRUB_MACHINE_MEMORY_HOLE 2 +#define GRUB_MACHINE_MEMORY_RESERVED GRUB_MACHINE_MEMORY_HOLE #ifndef ASM_FILE grub_err_t EXPORT_FUNC (grub_machine_mmap_iterate) (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t)); -grub_err_t EXPORT_FUNC(grub_machine_mmap_iterate) - (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t)); static inline grub_err_t grub_machine_mmap_register (grub_uint64_t start __attribute__ ((unused)), @@ -49,6 +56,15 @@ grub_machine_mmap_unregister (int handle __attribute__ ((unused))) { return GRUB_ERR_NONE; } + +grub_uint64_t grub_mmap_get_lower (void); +grub_uint64_t grub_mmap_get_upper (void); + +extern grub_uint32_t EXPORT_VAR (grub_arch_memsize); +extern grub_uint32_t EXPORT_VAR (grub_arch_highmemsize); +extern grub_uint32_t EXPORT_VAR (grub_arch_busclock); +extern grub_uint32_t EXPORT_VAR (grub_arch_cpuclock); + #endif #endif diff --git a/kern/mips/yeeloong/init.c b/kern/mips/yeeloong/init.c index 01acd4f1c..1bd9d2ed9 100644 --- a/kern/mips/yeeloong/init.c +++ b/kern/mips/yeeloong/init.c @@ -28,8 +28,6 @@ #include #include -#define RAMSIZE (64 << 20) - grub_uint32_t grub_get_rtc (void) { @@ -38,11 +36,48 @@ grub_get_rtc (void) return (calln++) >> 8; } +grub_err_t +grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, + grub_uint64_t, + grub_uint32_t)) +{ + hook (GRUB_ARCH_LOWMEMPSTART, grub_arch_memsize << 20, + GRUB_MACHINE_MEMORY_AVAILABLE); + hook (GRUB_ARCH_HIGHMEMPSTART, grub_arch_highmemsize << 20, + GRUB_MACHINE_MEMORY_AVAILABLE); + return GRUB_ERR_NONE; +} + + +static void * +get_modules_end (void) +{ + struct grub_module_info *modinfo; + struct grub_module_header *header; + grub_addr_t modbase; + + modbase = grub_arch_modules_addr (); + modinfo = (struct grub_module_info *) modbase; + + /* Check if there are any modules. */ + if ((modinfo == 0) || modinfo->magic != GRUB_MODULE_MAGIC) + return modinfo; + + for (header = (struct grub_module_header *) (modbase + modinfo->offset); + header < (struct grub_module_header *) (modbase + modinfo->size); + header = (struct grub_module_header *) ((char *) header + header->size)); + + return header; +} + void grub_machine_init (void) { - grub_mm_init_region ((void *) GRUB_MACHINE_MEMORY_USABLE, - RAMSIZE - (GRUB_MACHINE_MEMORY_USABLE & 0x7fffffff)); + void *modend; + modend = get_modules_end (); + grub_mm_init_region (modend, (grub_arch_memsize << 20) + - (((grub_addr_t) modend) - GRUB_ARCH_LOWMEMVSTART)); + /* FIXME: use upper memory as well. */ grub_install_get_time_ms (grub_rtc_get_time_ms); } @@ -69,11 +104,3 @@ grub_reboot (void) while (1); } -grub_err_t -grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, - grub_uint64_t, - grub_uint32_t)) -{ - hook (0, RAMSIZE, GRUB_MACHINE_MEMORY_AVAILABLE); - return GRUB_ERR_NONE; -} diff --git a/loader/mips/linux.c b/loader/mips/linux.c index 4d9045a65..635f84a28 100644 --- a/loader/mips/linux.c +++ b/loader/mips/linux.c @@ -26,6 +26,10 @@ #include #include #include +#include + +/* For frequencies. */ +#include #define ELF32_LOADMASK (0x00000000UL) #define ELF64_LOADMASK (0x0000000000000000ULL) @@ -176,7 +180,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), int size; void *extra = NULL; grub_uint32_t *linux_argv, *linux_envp; - char *linux_args; + char *linux_args, *linux_envs; grub_err_t err; if (argc == 0) @@ -218,7 +222,12 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), size += ALIGN_UP (sizeof ("rd_size=0xXXXXXXXXXXXXXXXX"), 4); /* For the environment. */ - size += sizeof (grub_uint32_t); + size += sizeof (grub_uint32_t); + size += 4 * sizeof (grub_uint32_t); + size += ALIGN_UP (sizeof ("memsize=XXXXXXXXXXXXXXXXXXXX"), 4) + + ALIGN_UP (sizeof ("highmemsize=XXXXXXXXXXXXXXXXXXXX"), 4) + + ALIGN_UP (sizeof ("busclock=XXXXXXXXXX"), 4) + + ALIGN_UP (sizeof ("cpuclock=XXXXXXXXXX"), 4); if (grub_elf_is_elf32 (elf)) err = grub_linux_load32 (elf, &extra, size); @@ -276,7 +285,27 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), linux_envp = extra; envp_off = (grub_uint8_t *) linux_envp - (grub_uint8_t *) playground; - linux_envp[0] = 0; + linux_envs = (char *) (linux_envp + 5); + grub_sprintf (linux_envs, "memsize=%lld", (unsigned long long) grub_mmap_get_lower () >> 20); + linux_envp[0] = (grub_uint8_t *) linux_envs - (grub_uint8_t *) playground + + target_addr; + linux_envs += ALIGN_UP (grub_strlen (linux_envs) + 1, 4); + grub_sprintf (linux_envs, "highmemsize=%lld", (unsigned long long) grub_mmap_get_upper () >> 20); + linux_envp[1] = (grub_uint8_t *) linux_envs - (grub_uint8_t *) playground + + target_addr; + linux_envs += ALIGN_UP (grub_strlen (linux_envs) + 1, 4); + + grub_sprintf (linux_envs, "busclock=%d", grub_arch_busclock); + linux_envp[2] = (grub_uint8_t *) linux_envs - (grub_uint8_t *) playground + + target_addr; + linux_envs += ALIGN_UP (grub_strlen (linux_envs) + 1, 4); + grub_sprintf (linux_envs, "cpuclock=%d", grub_arch_cpuclock); + linux_envp[3] = (grub_uint8_t *) linux_envs - (grub_uint8_t *) playground + + target_addr; + linux_envs += ALIGN_UP (grub_strlen (linux_envs) + 1, 4); + + + linux_envp[4] = 0; grub_loader_set (grub_linux_boot, grub_linux_unload, 1); initrd_loaded = 0; diff --git a/mmap/mips/yeeloong/uppermem.c b/mmap/mips/yeeloong/uppermem.c new file mode 100644 index 000000000..3c5f814de --- /dev/null +++ b/mmap/mips/yeeloong/uppermem.c @@ -0,0 +1,66 @@ +/* Compute amount of lower and upper memory till the first hole. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include + +grub_uint64_t +grub_mmap_get_lower (void) +{ + grub_uint64_t lower = 0; + + auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t); + int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, + grub_uint32_t type) + { + if (type != GRUB_MACHINE_MEMORY_AVAILABLE) + return 0; + if (addr == 0) + lower = size; + return 0; + } + + grub_mmap_iterate (hook); + if (lower > GRUB_ARCH_LOWMEMMAXSIZE) + lower = GRUB_ARCH_LOWMEMMAXSIZE; + return lower; +} + +grub_uint64_t +grub_mmap_get_upper (void) +{ + grub_uint64_t upper = 0; + + auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t); + int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, + grub_uint32_t type) + { + if (type != GRUB_MACHINE_MEMORY_AVAILABLE) + return 0; + if (addr <= GRUB_ARCH_HIGHMEMPSTART && addr + size + > GRUB_ARCH_HIGHMEMPSTART) + upper = addr + size - GRUB_ARCH_HIGHMEMPSTART; + return 0; + } + + grub_mmap_iterate (hook); + return upper; +} diff --git a/mmap/mmap.c b/mmap/mmap.c index 7598cf501..d379a99f9 100644 --- a/mmap/mmap.c +++ b/mmap/mmap.c @@ -52,7 +52,7 @@ grub_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, #ifdef GRUB_MACHINE_MEMORY_AVAILABLE [GRUB_MACHINE_MEMORY_AVAILABLE] = 1, #endif -#ifdef GRUB_MACHINE_MEMORY_RESERVED +#if defined (GRUB_MACHINE_MEMORY_RESERVED) && GRUB_MACHINE_MEMORY_RESERVED != GRUB_MACHINE_MEMORY_HOLE [GRUB_MACHINE_MEMORY_RESERVED] = 3, #endif #ifdef GRUB_MACHINE_MEMORY_ACPI From 52d67f54e0236f9e0def0c48f4753d47991450ae Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 7 Dec 2009 16:51:21 +0100 Subject: [PATCH 145/738] fix linux parameter passing on mips --- loader/mips/linux.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/loader/mips/linux.c b/loader/mips/linux.c index 635f84a28..bb71d63e9 100644 --- a/loader/mips/linux.c +++ b/loader/mips/linux.c @@ -204,15 +204,14 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), /* For arguments. */ linux_argc = argc; /* Main arguments. */ - size = (linux_argc + 1) * sizeof (grub_uint32_t); + size = (linux_argc) * sizeof (grub_uint32_t); /* Initrd address and size. */ size += 2 * sizeof (grub_uint32_t); /* NULL terminator. */ size += sizeof (grub_uint32_t); - /* First arguments are always "a0" and "a1". */ + /* First argument is always "a0". */ size += ALIGN_UP (sizeof ("a0"), 4); - size += ALIGN_UP (sizeof ("a1"), 4); /* Normal arguments. */ for (i = 1; i < argc; i++) size += ALIGN_UP (grub_strlen (argv[i]) + 1, 4); @@ -244,7 +243,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), linux_argv = extra; argv_off = (grub_uint8_t *) linux_argv - (grub_uint8_t *) playground; - extra = linux_argv + (linux_argc + 1 + 1 + 2); + extra = linux_argv + (linux_argc + 1 + 2); linux_args = extra; grub_memcpy (linux_args, "a0", sizeof ("a0")); @@ -253,12 +252,6 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), linux_argv++; linux_args += ALIGN_UP (sizeof ("a0"), 4); - grub_memcpy (linux_args, "a1", sizeof ("a1")); - *linux_argv = (grub_uint8_t *) linux_args - (grub_uint8_t *) playground - + target_addr; - linux_argv++; - linux_args += ALIGN_UP (sizeof ("a1"), 4); - for (i = 1; i < argc; i++) { grub_memcpy (linux_args, argv[i], grub_strlen (argv[i]) + 1); From d114e89ca8223fc37118cfc47768be87b64f1e99 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 9 Dec 2009 17:58:48 +0100 Subject: [PATCH 146/738] Add clock --- include/grub/mips/yeeloong/memory.h | 2 -- include/grub/mips/yeeloong/time.h | 7 +++++-- include/grub/time.h | 2 +- kern/mips/yeeloong/init.c | 14 +++++++++++--- loader/mips/linux.c | 1 + 5 files changed, 18 insertions(+), 8 deletions(-) diff --git a/include/grub/mips/yeeloong/memory.h b/include/grub/mips/yeeloong/memory.h index c85db712a..922db2404 100644 --- a/include/grub/mips/yeeloong/memory.h +++ b/include/grub/mips/yeeloong/memory.h @@ -62,8 +62,6 @@ grub_uint64_t grub_mmap_get_upper (void); extern grub_uint32_t EXPORT_VAR (grub_arch_memsize); extern grub_uint32_t EXPORT_VAR (grub_arch_highmemsize); -extern grub_uint32_t EXPORT_VAR (grub_arch_busclock); -extern grub_uint32_t EXPORT_VAR (grub_arch_cpuclock); #endif diff --git a/include/grub/mips/yeeloong/time.h b/include/grub/mips/yeeloong/time.h index a73f64dea..7f468bf12 100644 --- a/include/grub/mips/yeeloong/time.h +++ b/include/grub/mips/yeeloong/time.h @@ -21,10 +21,13 @@ #include -#define GRUB_TICKS_PER_SECOND 1000 +#define GRUB_TICKS_PER_SECOND (grub_arch_cpuclock / 2) /* Return the real time in ticks. */ -grub_uint32_t EXPORT_FUNC (grub_get_rtc) (void); +grub_uint64_t EXPORT_FUNC (grub_get_rtc) (void); + +extern grub_uint32_t EXPORT_VAR (grub_arch_busclock); +extern grub_uint32_t EXPORT_VAR (grub_arch_cpuclock); static inline void grub_cpu_idle(void) diff --git a/include/grub/time.h b/include/grub/time.h index 115fbd95e..5aafdc9ed 100644 --- a/include/grub/time.h +++ b/include/grub/time.h @@ -23,7 +23,7 @@ #include #include -#ifdef GRUB_MACHINE_EMU +#if defined (GRUB_MACHINE_EMU) || defined (GRUB_UTIL) #define GRUB_TICKS_PER_SECOND 100000 #else #include diff --git a/kern/mips/yeeloong/init.c b/kern/mips/yeeloong/init.c index 1bd9d2ed9..8b93ac18f 100644 --- a/kern/mips/yeeloong/init.c +++ b/kern/mips/yeeloong/init.c @@ -28,12 +28,20 @@ #include #include -grub_uint32_t +/* FIXME: use interrupt to count high. */ +grub_uint64_t grub_get_rtc (void) { - static grub_uint64_t calln = 0; + static grub_uint32_t high = 0; + static grub_uint32_t last = 0; + grub_uint32_t low; - return (calln++) >> 8; + asm volatile ("mfc0 %0, $9": "=r" (low)); + if (low < last) + high++; + last = low; + + return (((grub_uint64_t) high) << 32) | low; } grub_err_t diff --git a/loader/mips/linux.c b/loader/mips/linux.c index bb71d63e9..8d7cda0ed 100644 --- a/loader/mips/linux.c +++ b/loader/mips/linux.c @@ -30,6 +30,7 @@ /* For frequencies. */ #include +#include #define ELF32_LOADMASK (0x00000000UL) #define ELF64_LOADMASK (0x0000000000000000ULL) From 546d06078308974936c686040dc24287fcabc681 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 9 Dec 2009 19:39:21 +0100 Subject: [PATCH 147/738] grub-install for yeeloong --- conf/mips-yeeloong.rmk | 4 ++++ util/grub-install.in | 30 +++++++++++++++++++++++------- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/conf/mips-yeeloong.rmk b/conf/mips-yeeloong.rmk index a06b3fa5e..d28194ebc 100644 --- a/conf/mips-yeeloong.rmk +++ b/conf/mips-yeeloong.rmk @@ -47,3 +47,7 @@ mmap_mod_SOURCES = mmap/mmap.c mmap/mips/yeeloong/uppermem.c mmap_mod_CFLAGS = $(COMMON_CFLAGS) mmap_mod_LDFLAGS = $(COMMON_LDFLAGS) mmap_mod_ASFLAGS = $(COMMON_ASFLAGS) + +sbin_SCRIPTS += grub-install +grub_install_SOURCES = util/grub-install.in + diff --git a/util/grub-install.in b/util/grub-install.in index 4df620812..494ac6bc3 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -29,10 +29,11 @@ PACKAGE_TARNAME=@PACKAGE_TARNAME@ PACKAGE_VERSION=@PACKAGE_VERSION@ target_cpu=@target_cpu@ platform=@platform@ +font=@datadir@/@PACKAGE_TARNAME@/ascii.pf2 pkglibdir=${libdir}/`echo ${PACKAGE_TARNAME}/${target_cpu}-${platform} | sed ${transform}` grub_setup=${sbindir}/`echo grub-setup | sed ${transform}` -if [ "${target_cpu}-${platform}" = "i386-pc" ] ; then +if [ "${target_cpu}-${platform}" = "i386-pc" ] || [ "${target_cpu}-${platform}" = "mips-yeeloong" ] ; then grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}` else grub_mkimage=${bindir}/`echo grub-mkelfimage | sed ${transform}` @@ -79,6 +80,11 @@ if [ "${target_cpu}-${platform}" = "i386-pc" ] ; then cat <&2 usage exit 1 @@ -274,21 +282,27 @@ partmap_module=`$grub_probe --target=partmap --device ${grub_device} 2> /dev/nul # Device abstraction module, if any (lvm, raid). devabstraction_module=`$grub_probe --target=abstraction --device ${grub_device}` +if [ "${target_cpu}-${platform}" = "mips-yeeloong" ] ; then + modules="sm712 gfxterm at_keyboard $modules" +fi + # The order in this list is critical. Be careful when modifying it. modules="$modules $disk_module" modules="$modules $fs_module $partmap_module $devabstraction_module" prefix_drive= if [ "x${devabstraction_module}" = "x" ] ; then - if echo "${install_device}" | grep -qx "(.*)" ; then - install_drive="${install_device}" - else - install_drive="`$grub_probe --target=drive --device ${install_device}`" + if [ x"${install_device}" != x ]; then + if echo "${install_device}" | grep -qx "(.*)" ; then + install_drive="${install_device}" + else + install_drive="`$grub_probe --target=drive --device ${install_device}`" + fi + install_drive="`echo ${install_drive} | sed -e s/,[0-9]*[a-z]*//g`" fi grub_drive="`$grub_probe --target=drive --device ${grub_device}`" # Strip partition number - install_drive="`echo ${install_drive} | sed -e s/,[0-9]*[a-z]*//g`" grub_drive="`echo ${grub_drive} | sed -e s/,[0-9]*[a-z]*//g`" if [ "$disk_module" = ata ] ; then # generic method (used on coreboot and ata mod) @@ -323,6 +337,8 @@ if [ "${target_cpu}-${platform}" = "i386-pc" ] ; then # Now perform the installation. $grub_setup ${setup_verbose} ${setup_force} --directory=${grubdir} --device-map=${device_map} \ ${install_device} || exit 1 +elif [ "${target_cpu}-${platform}" = "mips-yeeloong" ] ; then + $grub_mkimage -f ${font} -d ${pkglibdir} -O elf --output=/boot/grub.elf --prefix=${prefix_drive}${relative_grubdir} $modules || exit 1 else $grub_mkimage -d ${pkglibdir} --output=/boot/multiboot.img --prefix=${prefix_drive}${relative_grubdir} $modules || exit 1 fi From 02772f981b413ff6bbd13744570737ec2fc6bae6 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 9 Dec 2009 20:34:14 +0100 Subject: [PATCH 148/738] correct return value of checkkey for null-terminal --- kern/term.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kern/term.c b/kern/term.c index 0e3595df3..52a265a6d 100644 --- a/kern/term.c +++ b/kern/term.c @@ -145,7 +145,7 @@ int grub_checkkey (void) { if (!grub_cur_term_input) - return 0; + return -1; return (grub_cur_term_input->checkkey) (); } From 8f44a91ea999abd9b5ce2821c82f4f9f2981bc71 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 9 Dec 2009 21:47:58 +0100 Subject: [PATCH 149/738] Fix bug in at_keyboard which blocked the menu countdown. --- term/at_keyboard.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/term/at_keyboard.c b/term/at_keyboard.c index 5d8dc3d89..9171430f4 100644 --- a/term/at_keyboard.c +++ b/term/at_keyboard.c @@ -24,6 +24,7 @@ #include static short at_keyboard_status = 0; +static int pending_key = -1; #define KEYBOARD_STATUS_SHIFT_L (1 << 0) #define KEYBOARD_STATUS_SHIFT_R (1 << 1) @@ -192,14 +193,27 @@ grub_at_keyboard_getkey_noblock (void) static int grub_at_keyboard_checkkey (void) { - /* FIXME: this will be triggered by BREAK events. */ - return KEYBOARD_ISREADY (grub_inb (KEYBOARD_REG_STATUS)) ? 1 : -1; + if (pending_key != -1) + return 1; + + pending_key = grub_at_keyboard_getkey_noblock (); + + if (pending_key != -1) + return 1; + + return -1; } static int grub_at_keyboard_getkey (void) { int key; + if (pending_key != -1) + { + key = pending_key; + pending_key = -1; + return key; + } do { key = grub_at_keyboard_getkey_noblock (); @@ -210,6 +224,8 @@ grub_at_keyboard_getkey (void) static grub_err_t grub_keyboard_controller_init (void) { + pending_key = -1; + at_keyboard_status = 0; grub_keyboard_controller_orig = grub_keyboard_controller_read (); grub_keyboard_controller_write (grub_keyboard_controller_orig | KEYBOARD_SCANCODE_SET1); return GRUB_ERR_NONE; From febfc12c6ee6b04d5a02320b8741a098738f8057 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Thu, 10 Dec 2009 22:38:54 +0000 Subject: [PATCH 150/738] 2009-12-10 Robert Millan * include/grub/mips/libgcc.h: Only export symbols for functions that libgcc provides. --- ChangeLog.mips | 5 +++++ include/grub/mips/libgcc.h | 16 +++++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/ChangeLog.mips b/ChangeLog.mips index f5f048298..d12b0d180 100644 --- a/ChangeLog.mips +++ b/ChangeLog.mips @@ -1,3 +1,8 @@ +2009-12-10 Robert Millan + + * include/grub/mips/libgcc.h: Only export symbols for functions + that libgcc provides. + 2009-12-02 Vladimir Serbinenko MIPS support. diff --git a/include/grub/mips/libgcc.h b/include/grub/mips/libgcc.h index 3bea2f998..f06ea1c1c 100644 --- a/include/grub/mips/libgcc.h +++ b/include/grub/mips/libgcc.h @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2004,2007 Free Software Foundation, Inc. + * Copyright (C) 2004,2007,2009 Free Software Foundation, Inc. * * GRUB is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,9 +16,23 @@ * along with GRUB. If not, see . */ +#include + +#ifdef HAVE___ASHLDI3 void EXPORT_FUNC (__ashldi3) (void); +#endif +#ifdef HAVE___ASHRDI3 void EXPORT_FUNC (__ashrdi3) (void); +#endif +#ifdef HAVE___LSHRDI3 void EXPORT_FUNC (__lshrdi3) (void); +#endif +#ifdef HAVE___UCMPDI2 void EXPORT_FUNC (__ucmpdi2) (void); +#endif +#ifdef HAVE___BSWAPSI2 void EXPORT_FUNC (__bswapsi2) (void); +#endif +#ifdef HAVE___BSWAPDI2 void EXPORT_FUNC (__bswapdi2) (void); +#endif From acdf01cd1b5780152ce79f4dcce28dbe94fe2a8a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 11 Dec 2009 21:28:27 +0100 Subject: [PATCH 151/738] cmostest command --- commands/i386/cmostest.c | 59 ++++++++++++++++++++++++++++++++++++++++ conf/i386-coreboot.rmk | 6 ++++ conf/i386-pc.rmk | 6 ++++ 3 files changed, 71 insertions(+) create mode 100644 commands/i386/cmostest.c diff --git a/commands/i386/cmostest.c b/commands/i386/cmostest.c new file mode 100644 index 000000000..7171766cd --- /dev/null +++ b/commands/i386/cmostest.c @@ -0,0 +1,59 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include + +static grub_err_t +grub_cmd_cmostest (struct grub_command *cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ + int byte, bit; + char *rest; + + if (argc != 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "Address required."); + + byte = grub_strtoul (argv[0], &rest, 0); + if (*rest != ':') + return grub_error (GRUB_ERR_BAD_ARGUMENT, "Address required."); + + bit = grub_strtoul (rest + 1, 0, 0); + + if (grub_cmos_read (byte) & (1 << bit)) + return GRUB_ERR_NONE; + + return grub_error (GRUB_ERR_TEST_FAILURE, "false"); +} + +static grub_command_t cmd; + + +GRUB_MOD_INIT(cmostest) +{ + cmd = grub_register_command ("cmostest", grub_cmd_cmostest, + "cmostest BYTE:BIT", + "Test bit at BYTE:BIT in CMOS."); +} + +GRUB_MOD_FINI(cmostest) +{ + grub_unregister_command (cmd); +} diff --git a/conf/i386-coreboot.rmk b/conf/i386-coreboot.rmk index e597328e7..b49af84ce 100644 --- a/conf/i386-coreboot.rmk +++ b/conf/i386-coreboot.rmk @@ -202,5 +202,11 @@ lsmmap_mod_SOURCES = commands/lsmmap.c lsmmap_mod_CFLAGS = $(COMMON_CFLAGS) lsmmap_mod_LDFLAGS = $(COMMON_LDFLAGS) +# For cmostest.mod +pkglib_MODULES += cmostest.mod +cmostest_mod_SOURCES = commands/i386/cmostest.c +cmostest_mod_CFLAGS = $(COMMON_CFLAGS) +cmostest_mod_LDFLAGS = $(COMMON_LDFLAGS) + include $(srcdir)/conf/i386.mk include $(srcdir)/conf/common.mk diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk index 7e54b3b67..8d373e30b 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -335,6 +335,12 @@ hdparm_mod_SOURCES = commands/hdparm.c lib/hexdump.c hdparm_mod_CFLAGS = $(COMMON_CFLAGS) hdparm_mod_LDFLAGS = $(COMMON_LDFLAGS) +# For cmostest.mod +pkglib_MODULES += cmostest.mod +cmostest_mod_SOURCES = commands/i386/cmostest.c +cmostest_mod_CFLAGS = $(COMMON_CFLAGS) +cmostest_mod_LDFLAGS = $(COMMON_LDFLAGS) + ifeq ($(enable_efiemu), yes) efiemu32.o: efiemu/runtime/efiemu.c $(TARGET_OBJ2ELF) From d4af2a73dc93ff2febf98924e22fc802e5d115db Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 11 Dec 2009 22:14:09 +0100 Subject: [PATCH 152/738] datetime for yeeloong --- conf/i386-coreboot.rmk | 2 +- conf/i386-ieee1275.rmk | 2 +- conf/i386-pc.rmk | 2 +- conf/mips-yeeloong.rmk | 19 +++++++ include/grub/cmos.h | 72 ++++++++++++++++++++++++ include/grub/i386/cmos.h | 48 +--------------- include/grub/mips/cmos.h | 1 + include/grub/mips/yeeloong/cmos.h | 28 +++++++++ lib/{i386/datetime.c => cmos_datetime.c} | 6 +- 9 files changed, 127 insertions(+), 53 deletions(-) create mode 100644 include/grub/cmos.h create mode 100644 include/grub/mips/cmos.h create mode 100644 include/grub/mips/yeeloong/cmos.h rename lib/{i386/datetime.c => cmos_datetime.c} (95%) diff --git a/conf/i386-coreboot.rmk b/conf/i386-coreboot.rmk index b6e810605..794e9a993 100644 --- a/conf/i386-coreboot.rmk +++ b/conf/i386-coreboot.rmk @@ -185,7 +185,7 @@ lspci_mod_CFLAGS = $(COMMON_CFLAGS) lspci_mod_LDFLAGS = $(COMMON_LDFLAGS) # For datetime.mod -datetime_mod_SOURCES = lib/i386/datetime.c +datetime_mod_SOURCES = lib/cmos_datetime.c datetime_mod_CFLAGS = $(COMMON_CFLAGS) datetime_mod_LDFLAGS = $(COMMON_LDFLAGS) diff --git a/conf/i386-ieee1275.rmk b/conf/i386-ieee1275.rmk index 4ee334325..5481cf1f7 100644 --- a/conf/i386-ieee1275.rmk +++ b/conf/i386-ieee1275.rmk @@ -122,7 +122,7 @@ lspci_mod_CFLAGS = $(COMMON_CFLAGS) lspci_mod_LDFLAGS = $(COMMON_LDFLAGS) # For datetime.mod -datetime_mod_SOURCES = lib/i386/datetime.c +datetime_mod_SOURCES = lib/cmos_datetime.c datetime_mod_CFLAGS = $(COMMON_CFLAGS) datetime_mod_LDFLAGS = $(COMMON_LDFLAGS) diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk index 598e46043..baba84939 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -306,7 +306,7 @@ pxecmd_mod_CFLAGS = $(COMMON_CFLAGS) pxecmd_mod_LDFLAGS = $(COMMON_LDFLAGS) # For datetime.mod -datetime_mod_SOURCES = lib/i386/datetime.c +datetime_mod_SOURCES = lib/cmos_datetime.c datetime_mod_CFLAGS = $(COMMON_CFLAGS) datetime_mod_LDFLAGS = $(COMMON_LDFLAGS) diff --git a/conf/mips-yeeloong.rmk b/conf/mips-yeeloong.rmk index d28194ebc..4257bba74 100644 --- a/conf/mips-yeeloong.rmk +++ b/conf/mips-yeeloong.rmk @@ -48,6 +48,25 @@ mmap_mod_CFLAGS = $(COMMON_CFLAGS) mmap_mod_LDFLAGS = $(COMMON_LDFLAGS) mmap_mod_ASFLAGS = $(COMMON_ASFLAGS) +# For datetime.mod +pkglib_MODULES += datetime.mod +datetime_mod_SOURCES = lib/cmos_datetime.c +datetime_mod_CFLAGS = $(COMMON_CFLAGS) +datetime_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For date.mod +pkglib_MODULES += date.mod +date_mod_SOURCES = commands/date.c +date_mod_CFLAGS = $(COMMON_CFLAGS) +date_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For datehook.mod +pkglib_MODULES += datehook.mod +datehook_mod_SOURCES = hook/datehook.c +datehook_mod_CFLAGS = $(COMMON_CFLAGS) +datehook_mod_LDFLAGS = $(COMMON_LDFLAGS) + + sbin_SCRIPTS += grub-install grub_install_SOURCES = util/grub-install.in diff --git a/include/grub/cmos.h b/include/grub/cmos.h new file mode 100644 index 000000000..f508e3bf6 --- /dev/null +++ b/include/grub/cmos.h @@ -0,0 +1,72 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008, 2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_CMOS_H +#define GRUB_CMOS_H 1 + +#include +#include +#include + +#define GRUB_CMOS_INDEX_SECOND 0 +#define GRUB_CMOS_INDEX_SECOND_ALARM 1 +#define GRUB_CMOS_INDEX_MINUTE 2 +#define GRUB_CMOS_INDEX_MINUTE_ALARM 3 +#define GRUB_CMOS_INDEX_HOUR 4 +#define GRUB_CMOS_INDEX_HOUR_ALARM 5 +#define GRUB_CMOS_INDEX_DAY_OF_WEEK 6 +#define GRUB_CMOS_INDEX_DAY_OF_MONTH 7 +#define GRUB_CMOS_INDEX_MONTH 8 +#define GRUB_CMOS_INDEX_YEAR 9 + +#define GRUB_CMOS_INDEX_STATUS_A 0xA +#define GRUB_CMOS_INDEX_STATUS_B 0xB +#define GRUB_CMOS_INDEX_STATUS_C 0xC +#define GRUB_CMOS_INDEX_STATUS_D 0xD + +#define GRUB_CMOS_STATUS_B_DAYLIGHT 1 +#define GRUB_CMOS_STATUS_B_24HOUR 2 +#define GRUB_CMOS_STATUS_B_BINARY 4 + +static inline grub_uint8_t +grub_bcd_to_num (grub_uint8_t a) +{ + return ((a >> 4) * 10 + (a & 0xF)); +} + +static inline grub_uint8_t +grub_num_to_bcd (grub_uint8_t a) +{ + return (((a / 10) << 4) + (a % 10)); +} + +static inline grub_uint8_t +grub_cmos_read (grub_uint8_t index) +{ + grub_outb (index, GRUB_CMOS_ADDR_REG); + return grub_inb (GRUB_CMOS_DATA_REG); +} + +static inline void +grub_cmos_write (grub_uint8_t index, grub_uint8_t value) +{ + grub_outb (index, GRUB_CMOS_ADDR_REG); + grub_outb (value, GRUB_CMOS_DATA_REG); +} + +#endif /* GRUB_CMOS_H */ diff --git a/include/grub/i386/cmos.h b/include/grub/i386/cmos.h index 1c0530dba..8b1fa3586 100644 --- a/include/grub/i386/cmos.h +++ b/include/grub/i386/cmos.h @@ -20,55 +20,9 @@ #define GRUB_CPU_CMOS_H 1 #include -#include +#include #define GRUB_CMOS_ADDR_REG 0x70 #define GRUB_CMOS_DATA_REG 0x71 -#define GRUB_CMOS_INDEX_SECOND 0 -#define GRUB_CMOS_INDEX_SECOND_ALARM 1 -#define GRUB_CMOS_INDEX_MINUTE 2 -#define GRUB_CMOS_INDEX_MINUTE_ALARM 3 -#define GRUB_CMOS_INDEX_HOUR 4 -#define GRUB_CMOS_INDEX_HOUR_ALARM 5 -#define GRUB_CMOS_INDEX_DAY_OF_WEEK 6 -#define GRUB_CMOS_INDEX_DAY_OF_MONTH 7 -#define GRUB_CMOS_INDEX_MONTH 8 -#define GRUB_CMOS_INDEX_YEAR 9 - -#define GRUB_CMOS_INDEX_STATUS_A 0xA -#define GRUB_CMOS_INDEX_STATUS_B 0xB -#define GRUB_CMOS_INDEX_STATUS_C 0xC -#define GRUB_CMOS_INDEX_STATUS_D 0xD - -#define GRUB_CMOS_STATUS_B_DAYLIGHT 1 -#define GRUB_CMOS_STATUS_B_24HOUR 2 -#define GRUB_CMOS_STATUS_B_BINARY 4 - -static inline grub_uint8_t -grub_bcd_to_num (grub_uint8_t a) -{ - return ((a >> 4) * 10 + (a & 0xF)); -} - -static inline grub_uint8_t -grub_num_to_bcd (grub_uint8_t a) -{ - return (((a / 10) << 4) + (a % 10)); -} - -static inline grub_uint8_t -grub_cmos_read (grub_uint8_t index) -{ - grub_outb (index, GRUB_CMOS_ADDR_REG); - return grub_inb (GRUB_CMOS_DATA_REG); -} - -static inline void -grub_cmos_write (grub_uint8_t index, grub_uint8_t value) -{ - grub_outb (index, GRUB_CMOS_ADDR_REG); - grub_outb (value, GRUB_CMOS_DATA_REG); -} - #endif /* GRUB_CPU_CMOS_H */ diff --git a/include/grub/mips/cmos.h b/include/grub/mips/cmos.h new file mode 100644 index 000000000..79a7a4c1b --- /dev/null +++ b/include/grub/mips/cmos.h @@ -0,0 +1 @@ +#include diff --git a/include/grub/mips/yeeloong/cmos.h b/include/grub/mips/yeeloong/cmos.h new file mode 100644 index 000000000..f2a32d736 --- /dev/null +++ b/include/grub/mips/yeeloong/cmos.h @@ -0,0 +1,28 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_CPU_CMOS_H +#define GRUB_CPU_CMOS_H 1 + +#include +#include + +#define GRUB_CMOS_ADDR_REG 0xbfd00070 +#define GRUB_CMOS_DATA_REG 0xbfd00071 + +#endif /* GRUB_CPU_CMOS_H */ diff --git a/lib/i386/datetime.c b/lib/cmos_datetime.c similarity index 95% rename from lib/i386/datetime.c rename to lib/cmos_datetime.c index 63858ed03..8db60b48c 100644 --- a/lib/i386/datetime.c +++ b/lib/cmos_datetime.c @@ -1,7 +1,7 @@ -/* kern/i386/datetime.c - x86 CMOS datetime function. +/* kern/cmos_datetime.c - CMOS datetime function. * * GRUB -- GRand Unified Bootloader - * Copyright (C) 2008 Free Software Foundation, Inc. + * Copyright (C) 2008,2009 Free Software Foundation, Inc. * * GRUB is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,7 +18,7 @@ */ #include -#include +#include grub_err_t grub_get_datetime (struct grub_datetime *datetime) From 5417641c666b64feb035c9b893a45e8987071390 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 12 Dec 2009 02:33:15 +0100 Subject: [PATCH 153/738] Fix loading of modules of size not divisible by 4 --- util/grub-mkrawimage.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/util/grub-mkrawimage.c b/util/grub-mkrawimage.c index 5399f4c42..58b30f5be 100644 --- a/util/grub-mkrawimage.c +++ b/util/grub-mkrawimage.c @@ -134,7 +134,7 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], if (config_path) { - config_size = grub_util_get_image_size (config_path) + 1; + config_size = ALIGN_UP(grub_util_get_image_size (config_path) + 1, 4); grub_util_info ("the size of config file is 0x%x", config_size); total_module_size += config_size + sizeof (struct grub_module_header); } @@ -163,15 +163,17 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], for (p = path_list; p; p = p->next) { struct grub_module_header *header; - size_t mod_size; + size_t mod_size, orig_size; - mod_size = grub_util_get_image_size (p->name); + orig_size = grub_util_get_image_size (p->name); + mod_size = ALIGN_UP(orig_size, 4); header = (struct grub_module_header *) (kernel_img + offset); memset (header, 0, sizeof (struct grub_module_header)); header->type = OBJ_TYPE_ELF; header->size = grub_host_to_target32 (mod_size + sizeof (*header)); offset += sizeof (*header); + memset (kernel_img + offset + orig_size, 0, mod_size - orig_size); grub_util_load_image (p->name, kernel_img + offset); offset += mod_size; From b66948bd8852092def61b4e7c07e680dc10e2680 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 12 Dec 2009 02:33:41 +0100 Subject: [PATCH 154/738] setjmp on mips --- include/grub/mips/setjmp.h | 27 ++++++++++++++++ lib/mips/setjmp.S | 65 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+) create mode 100644 include/grub/mips/setjmp.h diff --git a/include/grub/mips/setjmp.h b/include/grub/mips/setjmp.h new file mode 100644 index 000000000..5e5985586 --- /dev/null +++ b/include/grub/mips/setjmp.h @@ -0,0 +1,27 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2004,2006,2007,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_SETJMP_CPU_HEADER +#define GRUB_SETJMP_CPU_HEADER 1 + +typedef unsigned long grub_jmp_buf[11]; + +int grub_setjmp (grub_jmp_buf env) __attribute__ ((returns_twice)); +void grub_longjmp (grub_jmp_buf env, int val) __attribute__ ((noreturn)); + +#endif /* ! GRUB_SETJMP_CPU_HEADER */ diff --git a/lib/mips/setjmp.S b/lib/mips/setjmp.S index e69de29bb..8ab6222c4 100644 --- a/lib/mips/setjmp.S +++ b/lib/mips/setjmp.S @@ -0,0 +1,65 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2007,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include + + .file "setjmp.S" + + .text + +/* + * int grub_setjmp (grub_jmp_buf env) + */ +FUNCTION(grub_setjmp) + sw $s0, 0($a0) + sw $s1, 4($a0) + sw $s2, 8($a0) + sw $s3, 12($a0) + sw $s4, 16($a0) + sw $s5, 20($a0) + sw $s6, 24($a0) + sw $s7, 28($a0) + sw $s8, 32($a0) + sw $gp, 36($a0) + sw $sp, 40($a0) + sw $ra, 44($a0) + move $v0, $zero + move $v1, $zero + jr $ra +/* + * int grub_longjmp (grub_jmp_buf env, int val) + */ +FUNCTION(grub_longjmp) + lw $s0, 0($a0) + lw $s1, 4($a0) + lw $s2, 8($a0) + lw $s3, 12($a0) + lw $s4, 16($a0) + lw $s5, 20($a0) + lw $s6, 24($a0) + lw $s7, 28($a0) + lw $s8, 32($a0) + lw $gp, 36($a0) + lw $sp, 40($a0) + lw $ra, 44($a0) + move $v0, $a1 + bne $v0, $zero, 1f + addiu $v0, $v0, 1 +1: + move $v1, $zero + jr $ra From 7cba88bbde9f37089f4bce8eaefec1e77f0c9903 Mon Sep 17 00:00:00 2001 From: Felix Zielcke Date: Sun, 13 Dec 2009 21:03:47 +0100 Subject: [PATCH 155/738] Include instead of in kern/i386/qemu/mmap.c to fix a compiler warning --- kern/i386/qemu/mmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kern/i386/qemu/mmap.c b/kern/i386/qemu/mmap.c index 4ccae023a..c7fc4f45e 100644 --- a/kern/i386/qemu/mmap.c +++ b/kern/i386/qemu/mmap.c @@ -22,7 +22,7 @@ #include #include #include -#include +#include #define QEMU_CMOS_MEMSIZE_HIGH 0x35 #define QEMU_CMOS_MEMSIZE_LOW 0x34 From ffb2403f5fadfd83cd8abaf716078f4f93cb24ed Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Tue, 15 Dec 2009 21:06:04 +0000 Subject: [PATCH 156/738] Undo DEFAULT_VIDEO_MODE kludge (correct solution is in gfxmenu branch) --- term/gfxterm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/term/gfxterm.c b/term/gfxterm.c index 20dc11c20..972c7236d 100644 --- a/term/gfxterm.c +++ b/term/gfxterm.c @@ -27,7 +27,7 @@ #include #include -#define DEFAULT_VIDEO_MODE "1024x600" +#define DEFAULT_VIDEO_MODE "1024x768,800x600,640x480" #define DEFAULT_BORDER_WIDTH 10 #define DEFAULT_STANDARD_COLOR 0x07 From 0d48a435a0370bd30920bb507c301b67e218145e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 19 Dec 2009 21:30:00 +0100 Subject: [PATCH 157/738] 2009-12-19 Vladimir Serbinenko MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * include/grub/types.h (UNUSED): Removed since it conflicts with NetBSD headers. All users changed to direct __attribute__ ((unused)). Reported by Grégoire Sutre. --- ChangeLog | 6 ++++++ commands/read.c | 2 +- fs/i386/pc/pxe.c | 6 ++++-- include/grub/types.h | 2 -- kern/elf.c | 8 ++++++-- loader/i386/pc/multiboot2.c | 9 ++++++--- loader/ieee1275/multiboot2.c | 6 ++++-- loader/machoXX.c | 19 ++++++++++--------- loader/multiboot2.c | 3 ++- util/getroot.c | 2 +- util/ieee1275/devicemap.c | 6 ++++-- util/ieee1275/ofpath.c | 17 ++++++++++------- 12 files changed, 54 insertions(+), 32 deletions(-) diff --git a/ChangeLog b/ChangeLog index cc616c078..d386f7b71 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2009-12-19 Vladimir Serbinenko + + * include/grub/types.h (UNUSED): Removed since it conflicts with + NetBSD headers. All users changed to direct __attribute__ ((unused)). + Reported by Grégoire Sutre. + 2009-12-19 Carles Pina i Estany * normal/menu_text.c (STANDARD_MARGIN): New macro. diff --git a/commands/read.c b/commands/read.c index 82b30b461..aa6af37b5 100644 --- a/commands/read.c +++ b/commands/read.c @@ -62,7 +62,7 @@ grub_getline (void) } static grub_err_t -grub_cmd_read (grub_command_t cmd UNUSED, int argc, char **args) +grub_cmd_read (grub_command_t cmd __attribute__ ((unused)), int argc, char **args) { char *line = grub_getline (); if (! line) diff --git a/fs/i386/pc/pxe.c b/fs/i386/pc/pxe.c index 6c41d4298..dec3b91bf 100644 --- a/fs/i386/pc/pxe.c +++ b/fs/i386/pc/pxe.c @@ -107,9 +107,11 @@ static struct grub_disk_dev grub_pxe_dev = }; static grub_err_t -grub_pxefs_dir (grub_device_t device UNUSED, const char *path UNUSED, +grub_pxefs_dir (grub_device_t device __attribute__ ((unused)), + const char *path __attribute__ ((unused)), int (*hook) (const char *filename, - const struct grub_dirhook_info *info) UNUSED) + const struct grub_dirhook_info *info) + __attribute__ ((unused))) { return GRUB_ERR_NONE; } diff --git a/include/grub/types.h b/include/grub/types.h index 8e2ad15ef..5f6b7ec62 100644 --- a/include/grub/types.h +++ b/include/grub/types.h @@ -22,8 +22,6 @@ #include #include -#define UNUSED __attribute__ ((unused)) - #ifdef GRUB_UTIL # define GRUB_CPU_SIZEOF_VOID_P SIZEOF_VOID_P # define GRUB_CPU_SIZEOF_LONG SIZEOF_LONG diff --git a/kern/elf.c b/kern/elf.c index f14161060..951049e73 100644 --- a/kern/elf.c +++ b/kern/elf.c @@ -181,7 +181,9 @@ grub_elf32_size (grub_elf_t elf) /* Run through the program headers to calculate the total memory size we * should claim. */ auto int NESTED_FUNC_ATTR calcsize (grub_elf_t _elf, Elf32_Phdr *phdr, void *_arg); - int NESTED_FUNC_ATTR calcsize (grub_elf_t UNUSED _elf, Elf32_Phdr *phdr, void UNUSED *_arg) + int NESTED_FUNC_ATTR calcsize (grub_elf_t _elf __attribute__ ((unused)), + Elf32_Phdr *phdr, + void *_arg __attribute__ ((unused))) { /* Only consider loadable segments. */ if (phdr->p_type != PT_LOAD) @@ -360,7 +362,9 @@ grub_elf64_size (grub_elf_t elf) /* Run through the program headers to calculate the total memory size we * should claim. */ auto int NESTED_FUNC_ATTR calcsize (grub_elf_t _elf, Elf64_Phdr *phdr, void *_arg); - int NESTED_FUNC_ATTR calcsize (grub_elf_t UNUSED _elf, Elf64_Phdr *phdr, void UNUSED *_arg) + int NESTED_FUNC_ATTR calcsize (grub_elf_t _elf __attribute__ ((unused)), + Elf64_Phdr *phdr, + void *_arg __attribute__ ((unused))) { /* Only consider loadable segments. */ if (phdr->p_type != PT_LOAD) diff --git a/loader/i386/pc/multiboot2.c b/loader/i386/pc/multiboot2.c index e2d649613..6ef8c70ca 100644 --- a/loader/i386/pc/multiboot2.c +++ b/loader/i386/pc/multiboot2.c @@ -27,7 +27,8 @@ #include grub_err_t -grub_mb2_arch_elf32_hook (Elf32_Phdr *phdr, UNUSED grub_addr_t *addr, +grub_mb2_arch_elf32_hook (Elf32_Phdr *phdr, + grub_addr_t *addr __attribute__ ((unused)), int *do_load) { Elf32_Addr paddr = phdr->p_paddr; @@ -48,7 +49,8 @@ grub_mb2_arch_elf32_hook (Elf32_Phdr *phdr, UNUSED grub_addr_t *addr, } grub_err_t -grub_mb2_arch_elf64_hook (Elf64_Phdr *phdr, UNUSED grub_addr_t *addr, +grub_mb2_arch_elf64_hook (Elf64_Phdr *phdr, + grub_addr_t *addr __attribute__ ((unused)), int *do_load) { Elf64_Addr paddr = phdr->p_paddr; @@ -82,7 +84,8 @@ grub_mb2_arch_module_alloc (grub_size_t size, grub_addr_t *addr) } grub_err_t -grub_mb2_arch_module_free (grub_addr_t addr, UNUSED grub_size_t size) +grub_mb2_arch_module_free (grub_addr_t addr, + grub_size_t size __attribute__ ((unused))) { grub_free((void *) addr); return GRUB_ERR_NONE; diff --git a/loader/ieee1275/multiboot2.c b/loader/ieee1275/multiboot2.c index 3646e8091..3b0ab758e 100644 --- a/loader/ieee1275/multiboot2.c +++ b/loader/ieee1275/multiboot2.c @@ -36,7 +36,8 @@ typedef void (*kernel_entry_t) (unsigned long, void *, int (void *), /* Claim the memory occupied by the multiboot kernel. */ grub_err_t -grub_mb2_arch_elf32_hook (Elf32_Phdr *phdr, UNUSED grub_addr_t *addr, +grub_mb2_arch_elf32_hook (Elf32_Phdr *phdr, + grub_addr_t *addr __attribute__((unused)), int *do_load) { int rc; @@ -61,7 +62,8 @@ grub_mb2_arch_elf32_hook (Elf32_Phdr *phdr, UNUSED grub_addr_t *addr, /* Claim the memory occupied by the multiboot kernel. */ grub_err_t -grub_mb2_arch_elf64_hook (Elf64_Phdr *phdr, UNUSED grub_addr_t *addr, +grub_mb2_arch_elf64_hook (Elf64_Phdr *phdr, + grub_addr_t *addr __attribute__((unused)), int *do_load) { int rc; diff --git a/loader/machoXX.c b/loader/machoXX.c index d42dd8b55..8441e0128 100644 --- a/loader/machoXX.c +++ b/loader/machoXX.c @@ -123,8 +123,9 @@ SUFFIX (grub_macho_size) (grub_macho_t macho, grub_macho_addr_t *segments_start, should claim. */ auto int NESTED_FUNC_ATTR calcsize (grub_macho_t _macho, struct grub_macho_cmd *phdr, void *_arg); - int NESTED_FUNC_ATTR calcsize (grub_macho_t UNUSED _macho, - struct grub_macho_cmd *hdr0, void UNUSED *_arg) + int NESTED_FUNC_ATTR calcsize (grub_macho_t _macho __attribute__ ((unused)), + struct grub_macho_cmd *hdr0, + void *_arg __attribute__ ((unused))) { grub_macho_segment_t *hdr = (grub_macho_segment_t *) hdr0; if (hdr->cmd != GRUB_MACHO_CMD_SEGMENT) @@ -166,10 +167,10 @@ SUFFIX (grub_macho_load) (grub_macho_t macho, char *offset, int flags) grub_err_t err = 0; auto int NESTED_FUNC_ATTR do_load(grub_macho_t _macho, struct grub_macho_cmd *hdr0, - void UNUSED *_arg); + void *_arg __attribute__ ((unused))); int NESTED_FUNC_ATTR do_load(grub_macho_t _macho, struct grub_macho_cmd *hdr0, - void UNUSED *_arg) + void *_arg __attribute__ ((unused))) { grub_macho_segment_t *hdr = (grub_macho_segment_t *) hdr0; @@ -223,11 +224,11 @@ SUFFIX (grub_macho_get_entry_point) (grub_macho_t macho) { grub_macho_addr_t entry_point = 0; auto int NESTED_FUNC_ATTR hook(grub_macho_t _macho, - struct grub_macho_cmd *hdr, - void UNUSED *_arg); - int NESTED_FUNC_ATTR hook(grub_macho_t UNUSED _macho, - struct grub_macho_cmd *hdr, - void UNUSED *_arg) + struct grub_macho_cmd *hdr, + void *_arg __attribute__ ((unused))); + int NESTED_FUNC_ATTR hook(grub_macho_t _macho __attribute__ ((unused)), + struct grub_macho_cmd *hdr, + void *_arg __attribute__ ((unused))) { if (hdr->cmd == GRUB_MACHO_CMD_THREAD) entry_point = ((grub_macho_thread_t *) hdr)->entry_point; diff --git a/loader/multiboot2.c b/loader/multiboot2.c index 976285b85..4c73a2f17 100644 --- a/loader/multiboot2.c +++ b/loader/multiboot2.c @@ -222,7 +222,8 @@ grub_mb2_unload (void) } static grub_err_t -grub_mb2_load_other (UNUSED grub_file_t file, UNUSED void *buffer) +grub_mb2_load_other (grub_file_t file __attribute__ ((unused)), + void *buffer __attribute__ ((unused))) { /* XXX Create module tag here. */ return grub_error (GRUB_ERR_UNKNOWN_OS, "currently only ELF is supported"); diff --git a/util/getroot.c b/util/getroot.c index c6c229967..db772b968 100644 --- a/util/getroot.c +++ b/util/getroot.c @@ -488,7 +488,7 @@ grub_util_is_dmraid (const char *os_dev) } int -grub_util_get_dev_abstraction (const char *os_dev UNUSED) +grub_util_get_dev_abstraction (const char *os_dev __attribute__((unused))) { #ifdef __linux__ /* Check for LVM. */ diff --git a/util/ieee1275/devicemap.c b/util/ieee1275/devicemap.c index bddfc17e7..19ab746ef 100644 --- a/util/ieee1275/devicemap.c +++ b/util/ieee1275/devicemap.c @@ -35,8 +35,10 @@ escape_of_path (const char *orig_path) } void -grub_util_emit_devicemap_entry (FILE *fp, char *name, int is_floppy UNUSED, - int *num_fd UNUSED, int *num_hd UNUSED) +grub_util_emit_devicemap_entry (FILE *fp, char *name, + int is_floppy __attribute__((unused)), + int *num_fd __attribute__((unused)), + int *num_hd __attribute__((unused))) { const char *orig_path = grub_util_devname_to_ofpath (name); char *ofpath = escape_of_path (orig_path); diff --git a/util/ieee1275/ofpath.c b/util/ieee1275/ofpath.c index 7b464bf09..e90488fc3 100644 --- a/util/ieee1275/ofpath.c +++ b/util/ieee1275/ofpath.c @@ -39,7 +39,6 @@ #include #ifdef OFPATH_STANDALONE -#define UNUSED __attribute__((unused)) #define xmalloc malloc void grub_util_error (const char *fmt, ...) @@ -199,8 +198,10 @@ get_basename(char *p) static void of_path_of_vdisk(char *of_path, - const char *devname UNUSED, const char *device, - const char *devnode UNUSED, const char *devicenode) + const char *devname __attribute__((unused)), + const char *device, + const char *devnode __attribute__((unused)), + const char *devicenode) { char *sysfs_path, *p; int devno, junk; @@ -217,8 +218,9 @@ of_path_of_vdisk(char *of_path, static void of_path_of_ide(char *of_path, - const char *devname UNUSED, const char *device, - const char *devnode UNUSED, const char *devicenode) + const char *devname __attribute__((unused)), const char *device, + const char *devnode __attribute__((unused)), + const char *devicenode) { char *sysfs_path, *p; int chan, devno; @@ -299,8 +301,9 @@ check_sas (char *sysfs_path, int *tgt) static void of_path_of_scsi(char *of_path, - const char *devname UNUSED, const char *device, - const char *devnode UNUSED, const char *devicenode) + const char *devname __attribute__((unused)), const char *device, + const char *devnode __attribute__((unused)), + const char *devicenode) { const char *p, *digit_string, *disk_name; int host, bus, tgt, lun; From 3d79d70fe4d78302b6c0a116278e490193154dc6 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 20 Dec 2009 01:51:38 +0100 Subject: [PATCH 158/738] Don't use UNUSED --- gfxmenu/gfxmenu.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/gfxmenu/gfxmenu.c b/gfxmenu/gfxmenu.c index ab1c8befb..62ee34234 100644 --- a/gfxmenu/gfxmenu.c +++ b/gfxmenu/gfxmenu.c @@ -201,8 +201,9 @@ show_menu (grub_menu_t menu, int nested) } static grub_err_t -grub_cmd_gfxmenu (grub_command_t cmd UNUSED, - int argc UNUSED, char **args UNUSED) +grub_cmd_gfxmenu (grub_command_t cmd __attribute__ ((unused)), + int argc __attribute__ ((unused)), + char **args __attribute__ ((unused))) { grub_menu_t menu = grub_env_get_data_slot ("menu"); if (! menu) From 2fbcbbc3895142f5ddc17518eacc7a5b7fbeb575 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 20 Dec 2009 02:52:39 +0100 Subject: [PATCH 159/738] Save 314 bytes on not handling contexts in core --- conf/any-emu.rmk | 2 +- conf/common.rmk | 2 +- conf/i386-coreboot.rmk | 3 +- conf/i386-efi.rmk | 3 +- conf/i386-ieee1275.rmk | 2 +- conf/i386-pc.rmk | 3 +- conf/powerpc-ieee1275.rmk | 2 +- conf/sparc64-ieee1275.rmk | 2 +- conf/x86_64-efi.rmk | 2 +- include/grub/env.h | 30 ++---- include/grub/env_private.h | 46 +++++++++ include/grub/normal.h | 2 + kern/corecmd.c | 14 --- kern/env.c | 203 ++----------------------------------- kern/main.c | 2 - normal/context.c | 172 +++++++++++++++++++++++++++++++ normal/main.c | 12 ++- 17 files changed, 259 insertions(+), 243 deletions(-) create mode 100644 include/grub/env_private.h create mode 100644 normal/context.c diff --git a/conf/any-emu.rmk b/conf/any-emu.rmk index fb97de0a0..066bb52ba 100644 --- a/conf/any-emu.rmk +++ b/conf/any-emu.rmk @@ -27,7 +27,7 @@ grub_emu_SOURCES = commands/minicmd.c commands/cat.c commands/cmp.c \ normal/handler.c normal/auth.c normal/autofs.c \ normal/completion.c normal/main.c normal/color.c \ normal/menu.c normal/menu_entry.c normal/menu_viewer.c \ - normal/menu_text.c \ + normal/menu_text.c normal/context.c \ script/main.c script/execute.c script/function.c \ script/lexer.c script/script.c grub_script.tab.c \ partmap/amiga.c partmap/apple.c partmap/msdos.c partmap/sun.c \ diff --git a/conf/common.rmk b/conf/common.rmk index 1ed30a404..74e2b5bc4 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -543,7 +543,7 @@ normal_mod_SOURCES = normal/main.c normal/cmdline.c normal/dyncmd.c \ normal/auth.c normal/autofs.c normal/handler.c \ normal/color.c normal/completion.c normal/datetime.c normal/menu.c \ normal/menu_entry.c normal/menu_text.c normal/menu_viewer.c \ - normal/misc.c + normal/misc.c normal/context.c normal_mod_CFLAGS = $(COMMON_CFLAGS) normal_mod_LDFLAGS = $(COMMON_LDFLAGS) diff --git a/conf/i386-coreboot.rmk b/conf/i386-coreboot.rmk index e597328e7..1efea8afb 100644 --- a/conf/i386-coreboot.rmk +++ b/conf/i386-coreboot.rmk @@ -35,7 +35,8 @@ kernel_img_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \ partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \ machine/boot.h machine/console.h machine/init.h \ - machine/memory.h machine/loader.h list.h handler.h command.h i18n.h + machine/memory.h machine/loader.h list.h handler.h command.h i18n.h \ + env_private.h kernel_img_CFLAGS = $(COMMON_CFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) kernel_img_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,$(GRUB_KERNEL_MACHINE_LINK_ADDR),-Bstatic diff --git a/conf/i386-efi.rmk b/conf/i386-efi.rmk index 261fe4092..2de0e9304 100644 --- a/conf/i386-efi.rmk +++ b/conf/i386-efi.rmk @@ -51,7 +51,8 @@ kernel_img_SOURCES = kern/i386/efi/startup.S kern/main.c kern/device.c \ kernel_img_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \ partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \ - efi/efi.h efi/time.h efi/disk.h i386/pit.h list.h handler.h command.h i18n.h + efi/efi.h efi/time.h efi/disk.h i386/pit.h list.h handler.h command.h \ + i18n.h env_private.h kernel_img_CFLAGS = $(COMMON_CFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) kernel_img_LDFLAGS = $(COMMON_LDFLAGS) diff --git a/conf/i386-ieee1275.rmk b/conf/i386-ieee1275.rmk index 8d9577844..08c6c8f37 100644 --- a/conf/i386-ieee1275.rmk +++ b/conf/i386-ieee1275.rmk @@ -33,7 +33,7 @@ kernel_img_HEADERS = cache.h device.h disk.h dl.h elf.h elfload.h \ env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \ partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \ ieee1275/ieee1275.h machine/kernel.h machine/loader.h machine/memory.h \ - list.h handler.h command.h i18n.h + list.h handler.h command.h i18n.h env_private.h kernel_img_CFLAGS = $(COMMON_CFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) kernel_img_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,0x10000,-Bstatic diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk index 046c71641..8cec19f19 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -64,7 +64,8 @@ kernel_img_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \ machine/biosdisk.h machine/boot.h machine/console.h machine/init.h \ machine/memory.h machine/loader.h machine/vga.h machine/vbe.h \ - machine/kernel.h machine/pxe.h i386/pit.h list.h handler.h command.h i18n.h + machine/kernel.h machine/pxe.h i386/pit.h list.h handler.h command.h \ + i18n.h env_private.h kernel_img_CFLAGS = $(COMMON_CFLAGS) $(TARGET_IMG_CFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) kernel_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_KERNEL_MACHINE_LINK_ADDR) $(COMMON_CFLAGS) diff --git a/conf/powerpc-ieee1275.rmk b/conf/powerpc-ieee1275.rmk index 85b1fa211..9c16299d1 100644 --- a/conf/powerpc-ieee1275.rmk +++ b/conf/powerpc-ieee1275.rmk @@ -17,7 +17,7 @@ kernel_img_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ env.h err.h file.h fs.h kernel.h misc.h mm.h net.h parser.h reader.h \ symbol.h term.h time.h types.h powerpc/libgcc.h loader.h partition.h \ msdos_partition.h ieee1275/ieee1275.h machine/kernel.h handler.h list.h \ - command.h i18n.h + command.h i18n.h env_private.h symlist.c: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h gensymlist.sh /bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) diff --git a/conf/sparc64-ieee1275.rmk b/conf/sparc64-ieee1275.rmk index d19e927a5..d34adeb3c 100644 --- a/conf/sparc64-ieee1275.rmk +++ b/conf/sparc64-ieee1275.rmk @@ -31,7 +31,7 @@ kernel_img_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \ list.h handler.h command.h i18n.h \ sparc64/libgcc.h ieee1275/ieee1275.h machine/kernel.h \ - sparc64/ieee1275/ieee1275.h + sparc64/ieee1275/ieee1275.h env_private.h kernel_img_SOURCES = kern/sparc64/ieee1275/crt0.S kern/ieee1275/cmain.c \ kern/ieee1275/ieee1275.c kern/main.c kern/device.c \ kern/disk.c kern/dl.c kern/err.c kern/file.c kern/fs.c \ diff --git a/conf/x86_64-efi.rmk b/conf/x86_64-efi.rmk index 0d1289c6f..f5f0db25e 100644 --- a/conf/x86_64-efi.rmk +++ b/conf/x86_64-efi.rmk @@ -51,7 +51,7 @@ kernel_img_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \ partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \ efi/efi.h efi/time.h efi/disk.h machine/loader.h i386/pit.h list.h \ - handler.h command.h i18n.h + handler.h command.h i18n.h env_private.h kernel_img_CFLAGS = $(COMMON_CFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) kernel_img_LDFLAGS = $(COMMON_LDFLAGS) diff --git a/include/grub/env.h b/include/grub/env.h index 440185a59..ae4fd8745 100644 --- a/include/grub/env.h +++ b/include/grub/env.h @@ -22,6 +22,7 @@ #include #include #include +#include struct grub_env_var; @@ -30,18 +31,6 @@ typedef char *(*grub_env_read_hook_t) (struct grub_env_var *var, typedef char *(*grub_env_write_hook_t) (struct grub_env_var *var, const char *val); -enum grub_env_var_type - { - /* The default variable type which is local in current context. */ - GRUB_ENV_VAR_LOCAL, - - /* The exported type, which is passed to new contexts. */ - GRUB_ENV_VAR_GLOBAL, - - /* The data slot type, which is used to store arbitrary data. */ - GRUB_ENV_VAR_DATA - }; - struct grub_env_var { char *name; @@ -50,23 +39,24 @@ struct grub_env_var grub_env_write_hook_t write_hook; struct grub_env_var *next; struct grub_env_var **prevp; - enum grub_env_var_type type; + int global; }; grub_err_t EXPORT_FUNC(grub_env_set) (const char *name, const char *val); char *EXPORT_FUNC(grub_env_get) (const char *name); void EXPORT_FUNC(grub_env_unset) (const char *name); void EXPORT_FUNC(grub_env_iterate) (int (*func) (struct grub_env_var *var)); +struct grub_env_var *EXPORT_FUNC(grub_env_find) (const char *name); grub_err_t EXPORT_FUNC(grub_register_variable_hook) (const char *name, grub_env_read_hook_t read_hook, grub_env_write_hook_t write_hook); -grub_err_t EXPORT_FUNC(grub_env_context_open) (int export); -grub_err_t EXPORT_FUNC(grub_env_context_close) (void); -grub_err_t EXPORT_FUNC(grub_env_export) (const char *name); -grub_err_t EXPORT_FUNC(grub_env_set_data_slot) (const char *name, - const void *ptr); -void *EXPORT_FUNC(grub_env_get_data_slot) (const char *name); -void EXPORT_FUNC(grub_env_unset_data_slot) (const char *name); +grub_err_t grub_env_context_open (int export); +grub_err_t grub_env_context_close (void); +grub_err_t grub_env_export (const char *name); + +void grub_env_unset_menu (void); +grub_menu_t grub_env_get_menu (void); +void grub_env_set_menu (grub_menu_t nmenu); #endif /* ! GRUB_ENV_HEADER */ diff --git a/include/grub/env_private.h b/include/grub/env_private.h new file mode 100644 index 000000000..bb001533f --- /dev/null +++ b/include/grub/env_private.h @@ -0,0 +1,46 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2005,2006,2007,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_ENV_PRIVATE_HEADER +#define GRUB_ENV_PRIVATE_HEADER 1 + +#include + +/* The size of the hash table. */ +#define HASHSZ 13 + +/* A hashtable for quick lookup of variables. */ +struct grub_env_context +{ + /* A hash table for variables. */ + struct grub_env_var *vars[HASHSZ]; + + /* One level deeper on the stack. */ + struct grub_env_context *prev; +}; + +/* This is used for sorting only. */ +struct grub_env_sorted_var +{ + struct grub_env_var *var; + struct grub_env_sorted_var *next; +}; + +extern struct grub_env_context *EXPORT_VAR(grub_current_context); + +#endif /* ! GRUB_ENV_PRIVATE_HEADER */ diff --git a/include/grub/normal.h b/include/grub/normal.h index feebc85b1..15f4671d2 100644 --- a/include/grub/normal.h +++ b/include/grub/normal.h @@ -84,6 +84,8 @@ void read_command_list (void); /* Defined in `autofs.c'. */ void read_fs_list (void); +void grub_context_init (void); +void grub_context_fini (void); #ifdef GRUB_UTIL void grub_normal_init (void); diff --git a/kern/corecmd.c b/kern/corecmd.c index 03944f2df..7e8a3b4f6 100644 --- a/kern/corecmd.c +++ b/kern/corecmd.c @@ -73,18 +73,6 @@ grub_core_cmd_unset (struct grub_command *cmd __attribute__ ((unused)), return 0; } -static grub_err_t -grub_core_cmd_export (struct grub_command *cmd __attribute__ ((unused)), - int argc, char **args) -{ - if (argc < 1) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - "no environment variable specified"); - - grub_env_export (args[0]); - return 0; -} - /* insmod MODULE */ static grub_err_t grub_core_cmd_insmod (struct grub_command *cmd __attribute__ ((unused)), @@ -193,8 +181,6 @@ grub_register_core_commands (void) "set [ENVVAR=VALUE]", "set an environment variable"); grub_register_command ("unset", grub_core_cmd_unset, "unset ENVVAR", "remove an environment variable"); - grub_register_command ("export", grub_core_cmd_export, - "export ENVVAR", "Export a variable."); grub_register_command ("ls", grub_core_cmd_ls, "ls [ARG]", "list devices or files"); grub_register_command ("insmod", grub_core_cmd_insmod, diff --git a/kern/env.c b/kern/env.c index 750902af8..fdb3c9a34 100644 --- a/kern/env.c +++ b/kern/env.c @@ -18,34 +18,15 @@ */ #include +#include #include #include -/* The size of the hash table. */ -#define HASHSZ 13 - -/* A hashtable for quick lookup of variables. */ -struct grub_env_context -{ - /* A hash table for variables. */ - struct grub_env_var *vars[HASHSZ]; - - /* One level deeper on the stack. */ - struct grub_env_context *prev; -}; - -/* This is used for sorting only. */ -struct grub_env_sorted_var -{ - struct grub_env_var *var; - struct grub_env_sorted_var *next; -}; - /* The initial context. */ static struct grub_env_context initial_context; /* The current context. */ -static struct grub_env_context *current_context = &initial_context; +struct grub_env_context *grub_current_context = &initial_context; /* Return the hash representation of the string S. */ static unsigned int @@ -60,87 +41,20 @@ grub_env_hashval (const char *s) return i % HASHSZ; } -static struct grub_env_var * +struct grub_env_var * grub_env_find (const char *name) { struct grub_env_var *var; int idx = grub_env_hashval (name); /* Look for the variable in the current context. */ - for (var = current_context->vars[idx]; var; var = var->next) + for (var = grub_current_context->vars[idx]; var; var = var->next) if (grub_strcmp (var->name, name) == 0) return var; return 0; } -grub_err_t -grub_env_context_open (int export) -{ - struct grub_env_context *context; - int i; - - context = grub_zalloc (sizeof (*context)); - if (! context) - return grub_errno; - - context->prev = current_context; - current_context = context; - - /* Copy exported variables. */ - for (i = 0; i < HASHSZ; i++) - { - struct grub_env_var *var; - - for (var = context->prev->vars[i]; var; var = var->next) - { - if (export && var->type == GRUB_ENV_VAR_GLOBAL) - { - if (grub_env_set (var->name, var->value) != GRUB_ERR_NONE) - { - grub_env_context_close (); - return grub_errno; - } - grub_register_variable_hook (var->name, var->read_hook, var->write_hook); - } - } - } - - return GRUB_ERR_NONE; -} - -grub_err_t -grub_env_context_close (void) -{ - struct grub_env_context *context; - int i; - - if (! current_context->prev) - grub_fatal ("cannot close the initial context"); - - /* Free the variables associated with this context. */ - for (i = 0; i < HASHSZ; i++) - { - struct grub_env_var *p, *q; - - for (p = current_context->vars[i]; p; p = q) - { - q = p->next; - grub_free (p->name); - if (p->type != GRUB_ENV_VAR_DATA) - grub_free (p->value); - grub_free (p); - } - } - - /* Restore the previous context. */ - context = current_context->prev; - grub_free (current_context); - current_context = context; - - return GRUB_ERR_NONE; -} - static void grub_env_insert (struct grub_env_context *context, struct grub_env_var *var) @@ -164,18 +78,6 @@ grub_env_remove (struct grub_env_var *var) var->next->prevp = var->prevp; } -grub_err_t -grub_env_export (const char *name) -{ - struct grub_env_var *var; - - var = grub_env_find (name); - if (var) - var->type = GRUB_ENV_VAR_GLOBAL; - - return GRUB_ERR_NONE; -} - grub_err_t grub_env_set (const char *name, const char *val) { @@ -207,9 +109,8 @@ grub_env_set (const char *name, const char *val) if (! var) return grub_errno; - /* This is not necessary, because GRUB_ENV_VAR_LOCAL == 0. But leave - this for readability. */ - var->type = GRUB_ENV_VAR_LOCAL; + /* This is not necessary. But leave this for readability. */ + var->global = 0; var->name = grub_strdup (name); if (! var->name) @@ -219,7 +120,7 @@ grub_env_set (const char *name, const char *val) if (! var->value) goto fail; - grub_env_insert (current_context, var); + grub_env_insert (grub_current_context, var); return GRUB_ERR_NONE; @@ -263,8 +164,7 @@ grub_env_unset (const char *name) grub_env_remove (var); grub_free (var->name); - if (var->type != GRUB_ENV_VAR_DATA) - grub_free (var->value); + grub_free (var->value); grub_free (var); } @@ -280,14 +180,10 @@ grub_env_iterate (int (*func) (struct grub_env_var *var)) { struct grub_env_var *var; - for (var = current_context->vars[i]; var; var = var->next) + for (var = grub_current_context->vars[i]; var; var = var->next) { struct grub_env_sorted_var *p, **q; - /* Ignore data slots. */ - if (var->type == GRUB_ENV_VAR_DATA) - continue; - sorted_var = grub_malloc (sizeof (*sorted_var)); if (! sorted_var) goto fail; @@ -343,84 +239,3 @@ grub_register_variable_hook (const char *name, return GRUB_ERR_NONE; } - -static char * -mangle_data_slot_name (const char *name) -{ - char *mangled_name; - - mangled_name = grub_malloc (grub_strlen (name) + 2); - if (! mangled_name) - return 0; - - grub_sprintf (mangled_name, "\e%s", name); - return mangled_name; -} - -grub_err_t -grub_env_set_data_slot (const char *name, const void *ptr) -{ - char *mangled_name; - struct grub_env_var *var; - - mangled_name = mangle_data_slot_name (name); - if (! mangled_name) - goto fail; - - /* If the variable does already exist, just update the variable. */ - var = grub_env_find (mangled_name); - if (var) - { - var->value = (char *) ptr; - return GRUB_ERR_NONE; - } - - /* The variable does not exist, so create a new one. */ - var = grub_zalloc (sizeof (*var)); - if (! var) - goto fail; - - var->type = GRUB_ENV_VAR_DATA; - var->name = mangled_name; - var->value = (char *) ptr; - - grub_env_insert (current_context, var); - - return GRUB_ERR_NONE; - - fail: - - grub_free (mangled_name); - return grub_errno; -} - -void * -grub_env_get_data_slot (const char *name) -{ - char *mangled_name; - void *ptr = 0; - - mangled_name = mangle_data_slot_name (name); - if (! mangled_name) - goto fail; - - ptr = grub_env_get (mangled_name); - grub_free (mangled_name); - - fail: - - return ptr; -} - -void -grub_env_unset_data_slot (const char *name) -{ - char *mangled_name; - - mangled_name = mangle_data_slot_name (name); - if (! mangled_name) - return; - - grub_env_unset (mangled_name); - grub_free (mangled_name); -} diff --git a/kern/main.c b/kern/main.c index 9215d55e7..b76d2d20e 100644 --- a/kern/main.c +++ b/kern/main.c @@ -114,7 +114,6 @@ grub_set_root_dev (void) const char *prefix; grub_register_variable_hook ("root", 0, grub_env_write_root); - grub_env_export ("root"); prefix = grub_env_get ("prefix"); @@ -164,7 +163,6 @@ grub_main (void) /* It is better to set the root device as soon as possible, for convenience. */ grub_machine_set_prefix (); - grub_env_export ("prefix"); grub_set_root_dev (); grub_register_core_commands (); diff --git a/normal/context.c b/normal/context.c new file mode 100644 index 000000000..d9ad3b61d --- /dev/null +++ b/normal/context.c @@ -0,0 +1,172 @@ +/* env.c - Environment variables */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2005,2006,2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include + +struct menu_pointer +{ + grub_menu_t menu; + struct menu_pointer *prev; +}; + +struct menu_pointer initial_menu; +struct menu_pointer *current_menu = &initial_menu; + +void +grub_env_unset_menu (void) +{ + current_menu->menu = NULL; +} + +grub_menu_t +grub_env_get_menu (void) +{ + return current_menu->menu; +} + +void +grub_env_set_menu (grub_menu_t nmenu) +{ + current_menu->menu = nmenu; +} + +grub_err_t +grub_env_context_open (int export) +{ + struct grub_env_context *context; + int i; + struct menu_pointer *menu; + + context = grub_zalloc (sizeof (*context)); + if (! context) + return grub_errno; + menu = grub_zalloc (sizeof (*menu)); + if (! menu) + return grub_errno; + + context->prev = grub_current_context; + grub_current_context = context; + + menu->prev = current_menu; + current_menu = menu; + + /* Copy exported variables. */ + for (i = 0; i < HASHSZ; i++) + { + struct grub_env_var *var; + + for (var = context->prev->vars[i]; var; var = var->next) + { + if (export && var->global) + { + if (grub_env_set (var->name, var->value) != GRUB_ERR_NONE) + { + grub_env_context_close (); + return grub_errno; + } + grub_register_variable_hook (var->name, var->read_hook, var->write_hook); + } + } + } + + return GRUB_ERR_NONE; +} + +grub_err_t +grub_env_context_close (void) +{ + struct grub_env_context *context; + int i; + struct menu_pointer *menu; + + if (! grub_current_context->prev) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "cannot close the initial context"); + + /* Free the variables associated with this context. */ + for (i = 0; i < HASHSZ; i++) + { + struct grub_env_var *p, *q; + + for (p = grub_current_context->vars[i]; p; p = q) + { + q = p->next; + grub_free (p->name); + grub_free (p->value); + grub_free (p); + } + } + + /* Restore the previous context. */ + context = grub_current_context->prev; + grub_free (grub_current_context); + grub_current_context = context; + + menu = current_menu->prev; + grub_free (current_menu); + current_menu = menu; + + return GRUB_ERR_NONE; +} + +grub_err_t +grub_env_export (const char *name) +{ + struct grub_env_var *var; + + var = grub_env_find (name); + if (var) + var->global = 1; + + return GRUB_ERR_NONE; +} + +static grub_command_t export_cmd; + +static grub_err_t +grub_cmd_export (struct grub_command *cmd __attribute__ ((unused)), + int argc, char **args) +{ + if (argc < 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "no environment variable specified"); + + grub_env_export (args[0]); + return 0; +} + +void +grub_context_init (void) +{ + grub_env_export ("root"); + grub_env_export ("prefix"); + + export_cmd = grub_register_command ("export", grub_cmd_export, + "export ENVVAR", "Export a variable."); +} + +void +grub_context_fini (void) +{ + grub_unregister_command (export_cmd); +} diff --git a/normal/main.c b/normal/main.c index f080a6971..52581613a 100644 --- a/normal/main.c +++ b/normal/main.c @@ -133,7 +133,7 @@ free_menu (grub_menu_t menu) } grub_free (menu); - grub_env_unset_data_slot ("menu"); + grub_env_unset_menu (); } static void @@ -174,7 +174,7 @@ grub_normal_add_menu_entry (int argc, const char **args, return grub_errno; classes_tail = classes_head; - menu = grub_env_get_data_slot ("menu"); + menu = grub_env_get_menu (); if (! menu) return grub_error (GRUB_ERR_MENU, "no menu context"); @@ -357,14 +357,14 @@ read_config_file (const char *config) grub_menu_t newmenu; - newmenu = grub_env_get_data_slot ("menu"); + newmenu = grub_env_get_menu (); if (! newmenu) { newmenu = grub_zalloc (sizeof (*newmenu)); if (! newmenu) return 0; - grub_env_set_data_slot ("menu", newmenu); + grub_env_set_menu (newmenu); } /* Try to open the config file. */ @@ -562,6 +562,8 @@ grub_env_write_pager (struct grub_env_var *var __attribute__ ((unused)), GRUB_MOD_INIT(normal) { + grub_context_init (); + /* Normal mode shouldn't be unloaded. */ if (mod) grub_dl_ref (mod); @@ -589,6 +591,8 @@ GRUB_MOD_INIT(normal) GRUB_MOD_FINI(normal) { + grub_context_fini (); + grub_set_history (0); grub_reader_unregister (&grub_normal_reader); grub_register_variable_hook ("pager", 0, 0); From 4011be3b1a647596572e2c79349bd70adcaecc42 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 20 Dec 2009 14:21:04 +0100 Subject: [PATCH 160/738] ChangeLog --- ChangeLog.newenv | 55 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 ChangeLog.newenv diff --git a/ChangeLog.newenv b/ChangeLog.newenv new file mode 100644 index 000000000..3c1b09cfc --- /dev/null +++ b/ChangeLog.newenv @@ -0,0 +1,55 @@ +2009-12-20 Vladimir Serbinenko + + Move context handling out of the kernel. + + * conf/any-emu.rmk (grub_emu_SOURCES): Add normal/context.c. + * conf/common.rmk (normal_mod_SOURCES): Add normal/context.c. + * conf/i386-coreboot.rmk (kernel_img_HEADERS): Add env_private.h. + * conf/i386-efi.rmk: Likewise. + * conf/i386-ieee1275.rmk: Likewise. + * conf/i386-pc.rmk: Likewise. + * conf/powerpc-ieee1275.rmk: Likewise. + * conf/sparc64-ieee1275.rmk: Likewise. + * conf/x86_64-efi.rmk: Likewise. + * include/grub/env.h: Include grub/menu.h. + (grub_env_var_type): Removed. + (grub_env_var): Replaced field 'type' with 'global'. + (grub_env_find): New prototype. + (grub_env_context_open): Remove EXPORT_FUNC. + (grub_env_context_close): Likewise. + (grub_env_export): Likewise. + (grub_env_set_data_slot): Removed. + (grub_env_get_data_slot): Likewise. + (grub_env_unset_data_slot): Likewise. + (grub_env_unset_menu): New prototype. + (grub_env_set_menu): Likewise. + (grub_env_get_menu): Likewise. + * include/grub/env_private.h: New file. + * include/grub/normal.h (grub_context_init): New prototype. + (grub_context_fini): Likewise. + * kern/corecmd.c (grub_core_cmd_export): Moved from here ... + * normal/context.c (grub_cmd_export): ... to here. + * kern/env.c: Include env_private.h. + (HASHSZ): Moved to include/grub/env_private.h. + (grub_env_context): Likewise. + (grub_env_sorted_var): Likewise. + (current_context): Renamed from this ... + (grub_current_context): ...to this. 'static' removed. All users updated. + (grub_env_find): Removed 'static'. + (grub_env_context_open): Moved to normal/context.c. + (grub_env_context_close): Likewise. + (grub_env_export): Likewise. + (mangle_data_slot_name): Removed. + (grub_env_set_data_slot): Likewise. + (grub_env_get_data_slot): Likewise. + (grub_env_unset_data_slot): Likewise. + * kern/main.c (grub_set_root_dev): Don't export root. + It will be done later. + (grub_main): Don't export prefix. + It will be done later. + * normal/context.c: New file. + * normal/main.c (free_menu): Use grub_env_unset_menu. + (grub_normal_add_menu_entry): Use grub_env_get_menu. + (read_config_file): Use grub_env_get_menu and grub_env_set_menu. + (GRUB_MOD_INIT(normal)): Call grub_context_init. + (GRUB_MOD_FINI(normal)): Call grub_context_fini. From b617a75beff8af749ee5f35183f37c27472f4a37 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 21 Dec 2009 22:38:51 +0100 Subject: [PATCH 161/738] Fix compilation on ppc --- loader/powerpc/ieee1275/linux.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/loader/powerpc/ieee1275/linux.c b/loader/powerpc/ieee1275/linux.c index 79fbf0b02..1056ab9eb 100644 --- a/loader/powerpc/ieee1275/linux.c +++ b/loader/powerpc/ieee1275/linux.c @@ -110,7 +110,7 @@ grub_linux_load32 (grub_elf_t elf) if (entry == 0) entry = 0x01400000; - linux_size = grub_elf32_size (elf); + linux_size = grub_elf32_size (elf, 0); if (linux_size == 0) return grub_errno; /* Pad it; the kernel scribbles over memory beyond its load address. */ @@ -160,7 +160,7 @@ grub_linux_load64 (grub_elf_t elf) if (entry == 0) entry = 0x01400000; - linux_size = grub_elf64_size (elf); + linux_size = grub_elf64_size (elf, 0); if (linux_size == 0) return grub_errno; /* Pad it; the kernel scribbles over memory beyond its load address. */ From fbb8a88714844a34b9a817e2af8960bda6e4ce58 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 22 Dec 2009 15:09:25 +0100 Subject: [PATCH 162/738] Byte-addressable PCI config space --- ChangeLog.pciclean | 52 +++++++++++++++++++++++++++++++++++++++++ bus/pci.c | 6 ++--- bus/usb/ohci.c | 4 ++-- bus/usb/uhci.c | 4 ++-- commands/efi/fixvideo.c | 2 +- commands/efi/loadbios.c | 4 ++-- commands/lspci.c | 22 ++++++++++------- disk/ata.c | 9 ++++--- include/grub/pci.h | 31 ++++++++++++++++++++++++ loader/i386/efi/linux.c | 2 +- loader/i386/efi/xnu.c | 2 +- util/pci.c | 2 +- video/efi_uga.c | 2 +- 13 files changed, 117 insertions(+), 25 deletions(-) create mode 100644 ChangeLog.pciclean diff --git a/ChangeLog.pciclean b/ChangeLog.pciclean new file mode 100644 index 000000000..f50a48875 --- /dev/null +++ b/ChangeLog.pciclean @@ -0,0 +1,52 @@ +2009-12-22 Vladimir Serbinenko + + Byte-addressable PCI configuration space. + + * bus/pci.c (grub_pci_make_address): Use byte address instead of + dword address. + (grub_pci_iterate): Use macroses GRUB_PCI_REG_PCI_ID and + GRUB_PCI_REG_CACHELINE. + * bus/usb/ohci.c (grub_ohci_pci_iter): Use macroses + GRUB_PCI_REG_CLASS and GRUB_PCI_REG_ADDRESS_REG0. + * bus/usb/uhci.c (grub_ohci_pci_iter): Use macroses + GRUB_PCI_REG_CLASS and GRUB_PCI_REG_ADDRESS_REG4. + * commands/efi/fixvideo.c (scan_card): Use macros GRUB_PCI_REG_CLASS. + * commands/efi/loadbios.c (enable_rom_area): Pass byte-address to + grub_pci_make_address. + (lock_rom_area): Likewise. + * commands/lspci.c (grub_lspci_iter): Use macroses + GRUB_PCI_REG_CLASS and GRUB_PCI_REG_ADDRESSES. Handle byte-addressing + of grub_pci_make_address. + * disk/ata.c (grub_ata_pciinit): Likewise. + * include/grub/pci.h (GRUB_PCI_REG_PCI_ID): New macro. + (GRUB_PCI_REG_VENDOR): Likewise. + (GRUB_PCI_REG_DEVICE): Likewise. + (GRUB_PCI_REG_COMMAND): Likewise. + (GRUB_PCI_REG_STATUS): Likewise. + (GRUB_PCI_REG_REVISION): Likewise. + (GRUB_PCI_REG_CLASS): Likewise. + (GRUB_PCI_REG_CACHELINE): Likewise. + (GRUB_PCI_REG_LAT_TIMER): Likewise. + (GRUB_PCI_REG_HEADER_TYPE): Likewise. + (GRUB_PCI_REG_BIST): Likewise. + (GRUB_PCI_REG_ADDRESSES): Likewise. + (GRUB_PCI_REG_ADDRESS_REG): Likewise. + (GRUB_PCI_REG_ADDRESS_REG): Likewise. + (GRUB_PCI_REG_ADDRESS_REG): Likewise. + (GRUB_PCI_REG_ADDRESS_REG): Likewise. + (GRUB_PCI_REG_ADDRESS_REG): Likewise. + (GRUB_PCI_REG_ADDRESS_REG): Likewise. + (GRUB_PCI_REG_CIS_POINTER): Likewise. + (GRUB_PCI_REG_SUBVENDOR): Likewise. + (GRUB_PCI_REG_SUBSYSTEM): Likewise. + (GRUB_PCI_REG_ROM_ADDRESS): Likewise. + (GRUB_PCI_REG_CAP_POINTER): Likewise. + (GRUB_PCI_REG_IRQ_LINE): Likewise. + (GRUB_PCI_REG_IRQ_PIN): Likewise. + (GRUB_PCI_REG_MIN_GNT): Likewise. + (GRUB_PCI_REG_MAX_LAT): Likewise. + * loader/i386/efi/linux.c (find_framebuf): Use GRUB_PCI_REG_CLASS. + * loader/i386/efi/xnu.c (find_framebuf): Likewise. + * video/efi_uga.c (find_framebuf): Likewise. + * util/pci.c (grub_pci_make_address): Use byte-addressed configuration + space. diff --git a/bus/pci.c b/bus/pci.c index fe4cad181..13b67c908 100644 --- a/bus/pci.c +++ b/bus/pci.c @@ -24,7 +24,7 @@ grub_pci_address_t grub_pci_make_address (grub_pci_device_t dev, int reg) { return (1 << 31) | (dev.bus << 16) | (dev.device << 11) - | (dev.function << 8) | (reg << 2); + | (dev.function << 8) | reg; } void @@ -41,7 +41,7 @@ grub_pci_iterate (grub_pci_iteratefunc_t hook) { for (dev.function = 0; dev.function < 8; dev.function++) { - addr = grub_pci_make_address (dev, 0); + addr = grub_pci_make_address (dev, GRUB_PCI_REG_PCI_ID); id = grub_pci_read (addr); /* Check if there is a device present. */ @@ -54,7 +54,7 @@ grub_pci_iterate (grub_pci_iteratefunc_t hook) /* Probe only func = 0 if the device if not multifunction */ if (dev.function == 0) { - addr = grub_pci_make_address (dev, 3); + addr = grub_pci_make_address (dev, GRUB_PCI_REG_CACHELINE); hdr = grub_pci_read (addr); if (!(hdr & 0x800000)) break; diff --git a/bus/usb/ohci.c b/bus/usb/ohci.c index 5fe9c9507..6d185bc7f 100644 --- a/bus/usb/ohci.c +++ b/bus/usb/ohci.c @@ -126,7 +126,7 @@ grub_ohci_pci_iter (grub_pci_device_t dev, grub_uint32_t revision; grub_uint32_t frame_interval; - addr = grub_pci_make_address (dev, 2); + addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); class_code = grub_pci_read (addr) >> 8; interf = class_code & 0xFF; @@ -138,7 +138,7 @@ grub_ohci_pci_iter (grub_pci_device_t dev, return 0; /* Determine IO base address. */ - addr = grub_pci_make_address (dev, 4); + addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); base = grub_pci_read (addr); #if 0 diff --git a/bus/usb/uhci.c b/bus/usb/uhci.c index e83fccc1d..947f2367b 100644 --- a/bus/usb/uhci.c +++ b/bus/usb/uhci.c @@ -150,7 +150,7 @@ grub_uhci_pci_iter (grub_pci_device_t dev, struct grub_uhci *u; int i; - addr = grub_pci_make_address (dev, 2); + addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); class_code = grub_pci_read (addr) >> 8; interf = class_code & 0xFF; @@ -162,7 +162,7 @@ grub_uhci_pci_iter (grub_pci_device_t dev, return 0; /* Determine IO base address. */ - addr = grub_pci_make_address (dev, 8); + addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG4); base = grub_pci_read (addr); /* Stop if there is no IO space base address defined. */ if (! (base & 1)) diff --git a/commands/efi/fixvideo.c b/commands/efi/fixvideo.c index 685662237..dea69c8b1 100644 --- a/commands/efi/fixvideo.c +++ b/commands/efi/fixvideo.c @@ -42,7 +42,7 @@ scan_card (grub_pci_device_t dev, grub_pci_id_t pciid) { grub_pci_address_t addr; - addr = grub_pci_make_address (dev, 2); + addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); if (grub_pci_read_byte (addr + 3) == 0x3) { struct grub_video_patch *p = video_patches; diff --git a/commands/efi/loadbios.c b/commands/efi/loadbios.c index d7ad42690..183ba7e85 100644 --- a/commands/efi/loadbios.c +++ b/commands/efi/loadbios.c @@ -50,7 +50,7 @@ enable_rom_area (void) return 0; } - addr = grub_pci_make_address (dev, 36); + addr = grub_pci_make_address (dev, 144); grub_pci_write_byte (addr++, 0x30); grub_pci_write_byte (addr++, 0x33); grub_pci_write_byte (addr++, 0x33); @@ -76,7 +76,7 @@ lock_rom_area (void) grub_pci_address_t addr; grub_pci_device_t dev = { .bus = 0, .device = 0, .function = 0}; - addr = grub_pci_make_address (dev, 36); + addr = grub_pci_make_address (dev, 144); grub_pci_write_byte (addr++, 0x10); grub_pci_write_byte (addr++, 0x11); grub_pci_write_byte (addr++, 0x11); diff --git a/commands/lspci.c b/commands/lspci.c index 559bb8242..c515da762 100644 --- a/commands/lspci.c +++ b/commands/lspci.c @@ -134,7 +134,7 @@ grub_lspci_iter (grub_pci_device_t dev, grub_pci_id_t pciid) grub_printf ("%02x:%02x.%x %04x:%04x", grub_pci_get_bus (dev), grub_pci_get_device (dev), grub_pci_get_function (dev), pciid & 0xFFFF, pciid >> 16); - addr = grub_pci_make_address (dev, 2); + addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); class = grub_pci_read (addr); /* Lookup the class name, if there isn't a specific one, @@ -155,14 +155,14 @@ grub_lspci_iter (grub_pci_device_t dev, grub_pci_id_t pciid) if (iospace) { - reg = 4; - while (reg < 10) + reg = GRUB_PCI_REG_ADDRESSES; + while (reg < GRUB_PCI_REG_CIS_POINTER) { grub_uint64_t space; addr = grub_pci_make_address (dev, reg); space = grub_pci_read (addr); - reg++; + reg += sizeof (grub_uint32_t); if (space == 0) continue; @@ -170,7 +170,9 @@ grub_lspci_iter (grub_pci_device_t dev, grub_pci_id_t pciid) switch (space & GRUB_PCI_ADDR_SPACE_MASK) { case GRUB_PCI_ADDR_SPACE_IO: - grub_printf ("\tIO space %d at 0x%llx\n", (reg - 1) - 4, + grub_printf ("\tIO space %d at 0x%llx\n", + ((reg - GRUB_PCI_REG_ADDRESSES) + / sizeof (grub_uint32_t)) - 1, (unsigned long long) (space & GRUB_PCI_ADDR_IO_MASK)); break; @@ -180,9 +182,11 @@ grub_lspci_iter (grub_pci_device_t dev, grub_pci_id_t pciid) { addr = grub_pci_make_address (dev, reg); space |= ((grub_uint64_t) grub_pci_read (addr)) << 32; - reg++; + reg += sizeof (grub_uint32_t); grub_printf ("\t64-bit memory space %d at 0x%016llx [%s]\n", - (reg - 2) - 4, (unsigned long long) + ((reg - GRUB_PCI_REG_ADDRESSES) + / sizeof (grub_uint32_t)) - 2, + (unsigned long long) (space & GRUB_PCI_ADDR_MEM_MASK), space & GRUB_PCI_ADDR_MEM_PREFETCH ? "prefetchable" : "non-prefetchable"); @@ -190,7 +194,9 @@ grub_lspci_iter (grub_pci_device_t dev, grub_pci_id_t pciid) } else grub_printf ("\t32-bit memory space %d at 0x%016llx [%s]\n", - (reg - 1) - 4, (unsigned long long) + ((reg - GRUB_PCI_REG_ADDRESSES) + / sizeof (grub_uint32_t)) - 1, + (unsigned long long) (space & GRUB_PCI_ADDR_MEM_MASK), space & GRUB_PCI_ADDR_MEM_PREFETCH ? "prefetchable" : "non-prefetchable"); diff --git a/disk/ata.c b/disk/ata.c index af8c87180..bc8383d4e 100644 --- a/disk/ata.c +++ b/disk/ata.c @@ -402,7 +402,7 @@ grub_ata_pciinit (grub_pci_device_t dev, static int controller = 0; /* Read class. */ - addr = grub_pci_make_address (dev, 2); + addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); class = grub_pci_read (addr); /* Check if this class ID matches that of a PCI IDE Controller. */ @@ -429,9 +429,12 @@ grub_ata_pciinit (grub_pci_device_t dev, { /* Read the BARs, which either contain a mmapped IO address or the IO port address. */ - addr = grub_pci_make_address (dev, 4 + 2 * i); + addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESSES + + sizeof (grub_uint64_t) * i); bar1 = grub_pci_read (addr); - addr = grub_pci_make_address (dev, 5 + 2 * i); + addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESSES + + sizeof (grub_uint64_t) * i + + sizeof (grub_uint32_t)); bar2 = grub_pci_read (addr); /* Check if the BARs describe an IO region. */ diff --git a/include/grub/pci.h b/include/grub/pci.h index 2bea05410..1f3ac7fc7 100644 --- a/include/grub/pci.h +++ b/include/grub/pci.h @@ -35,6 +35,37 @@ #define GRUB_PCI_ADDR_MEM_MASK ~0xf #define GRUB_PCI_ADDR_IO_MASK ~0x03 +#define GRUB_PCI_REG_PCI_ID 0x00 +#define GRUB_PCI_REG_VENDOR 0x00 +#define GRUB_PCI_REG_DEVICE 0x02 +#define GRUB_PCI_REG_COMMAND 0x04 +#define GRUB_PCI_REG_STATUS 0x06 +#define GRUB_PCI_REG_REVISION 0x08 +#define GRUB_PCI_REG_CLASS 0x08 +#define GRUB_PCI_REG_CACHELINE 0x0c +#define GRUB_PCI_REG_LAT_TIMER 0x0d +#define GRUB_PCI_REG_HEADER_TYPE 0x0e +#define GRUB_PCI_REG_BIST 0x0f +#define GRUB_PCI_REG_ADDRESSES 0x10 + +/* Beware that 64-bit address takes 2 registers. */ +#define GRUB_PCI_REG_ADDRESS_REG0 0x10 +#define GRUB_PCI_REG_ADDRESS_REG1 0x14 +#define GRUB_PCI_REG_ADDRESS_REG2 0x18 +#define GRUB_PCI_REG_ADDRESS_REG3 0x1c +#define GRUB_PCI_REG_ADDRESS_REG4 0x20 +#define GRUB_PCI_REG_ADDRESS_REG5 0x24 + +#define GRUB_PCI_REG_CIS_POINTER 0x28 +#define GRUB_PCI_REG_SUBVENDOR 0x2c +#define GRUB_PCI_REG_SUBSYSTEM 0x2e +#define GRUB_PCI_REG_ROM_ADDRESS 0x30 +#define GRUB_PCI_REG_CAP_POINTER 0x34 +#define GRUB_PCI_REG_IRQ_LINE 0x3c +#define GRUB_PCI_REG_IRQ_PIN 0x3d +#define GRUB_PCI_REG_MIN_GNT 0x3e +#define GRUB_PCI_REG_MAX_LAT 0x3f + typedef grub_uint32_t grub_pci_id_t; #ifdef GRUB_UTIL diff --git a/loader/i386/efi/linux.c b/loader/i386/efi/linux.c index 8cd4d23f2..ad09f7c36 100644 --- a/loader/i386/efi/linux.c +++ b/loader/i386/efi/linux.c @@ -477,7 +477,7 @@ find_framebuf (grub_uint32_t *fb_base, grub_uint32_t *line_len) { grub_pci_address_t addr; - addr = grub_pci_make_address (dev, 2); + addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); if (grub_pci_read (addr) >> 24 == 0x3) { int i; diff --git a/loader/i386/efi/xnu.c b/loader/i386/efi/xnu.c index 236732804..af54ac5c1 100644 --- a/loader/i386/efi/xnu.c +++ b/loader/i386/efi/xnu.c @@ -79,7 +79,7 @@ find_framebuf (grub_uint32_t *fb_base, grub_uint32_t *line_len) { grub_pci_address_t addr; - addr = grub_pci_make_address (dev, 2); + addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); if (grub_pci_read (addr) >> 24 == 0x3) { int i; diff --git a/util/pci.c b/util/pci.c index a0c1867be..420ae320b 100644 --- a/util/pci.c +++ b/util/pci.c @@ -26,7 +26,7 @@ grub_pci_make_address (grub_pci_device_t dev, int reg) { grub_pci_address_t ret; ret.dev = dev; - ret.pos = reg << 2; + ret.pos = reg; return ret; } diff --git a/video/efi_uga.c b/video/efi_uga.c index 9bca64306..959b266a9 100644 --- a/video/efi_uga.c +++ b/video/efi_uga.c @@ -92,7 +92,7 @@ find_framebuf (grub_uint32_t *fb_base, grub_uint32_t *line_len) { grub_pci_address_t addr; - addr = grub_pci_make_address (dev, 2); + addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); if (grub_pci_read (addr) >> 24 == 0x3) { int i; From adc89895e05a4cdd5cd69bfc313fd09633f900f9 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 22 Dec 2009 16:42:45 +0100 Subject: [PATCH 163/738] setpci implementation --- commands/setpci.c | 340 ++++++++++++++++++++++++++++++++++++++++++++++ conf/i386.rmk | 6 + 2 files changed, 346 insertions(+) create mode 100644 commands/setpci.c diff --git a/commands/setpci.c b/commands/setpci.c new file mode 100644 index 000000000..aa5e51de9 --- /dev/null +++ b/commands/setpci.c @@ -0,0 +1,340 @@ +/* lspci.c - List PCI devices. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008, 2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +struct pci_register +{ + const char *name; + grub_uint16_t addr; + unsigned size; +}; + +struct pci_register pci_registers[] = + { + {"VENDOR_ID", GRUB_PCI_REG_VENDOR , 2}, + {"DEVICE_ID", GRUB_PCI_REG_DEVICE , 2}, + {"COMMAND", GRUB_PCI_REG_COMMAND , 2}, + {"STATUS", GRUB_PCI_REG_STATUS , 2}, + {"REVISION", GRUB_PCI_REG_REVISION , 1}, + {"CLASS_PROG", GRUB_PCI_REG_CLASS + 1 , 1}, + {"CLASS_DEVICE", GRUB_PCI_REG_CLASS + 2 , 2}, + {"CACHE_LINE_SIZE", GRUB_PCI_REG_CACHELINE , 1}, + {"LATENCY_TIMER", GRUB_PCI_REG_LAT_TIMER , 1}, + {"HEADER_TYPE", GRUB_PCI_REG_HEADER_TYPE , 1}, + {"BIST", GRUB_PCI_REG_BIST , 1}, + {"BASE_ADDRESS_0", GRUB_PCI_REG_ADDRESS_REG0, 4}, + {"BASE_ADDRESS_1", GRUB_PCI_REG_ADDRESS_REG1, 4}, + {"BASE_ADDRESS_2", GRUB_PCI_REG_ADDRESS_REG2, 4}, + {"BASE_ADDRESS_3", GRUB_PCI_REG_ADDRESS_REG3, 4}, + {"BASE_ADDRESS_4", GRUB_PCI_REG_ADDRESS_REG4, 4}, + {"BASE_ADDRESS_5", GRUB_PCI_REG_ADDRESS_REG5, 4}, + {"CARDBUS_CIS", GRUB_PCI_REG_CIS_POINTER , 4}, + {"SUBVENDOR_ID", GRUB_PCI_REG_SUBVENDOR , 2}, + {"SUBSYSTEM_ID", GRUB_PCI_REG_SUBSYSTEM , 2}, + {"ROM_ADDRESS", GRUB_PCI_REG_ROM_ADDRESS , 4}, + {"CAP_POINTER", GRUB_PCI_REG_CAP_POINTER , 1}, + {"INTERRUPT_LINE", GRUB_PCI_REG_IRQ_LINE , 1}, + {"INTERRUPT_PIN", GRUB_PCI_REG_IRQ_PIN , 1}, + {"MIN_GNT", GRUB_PCI_REG_MIN_GNT , 1}, + {"MAX_LAT", GRUB_PCI_REG_MIN_GNT , 1}, + }; + +static const struct grub_arg_option options[] = + { + {0, 'd', 0, "Select device by vendor and device IDs.", + "[vendor]:[device]", ARG_TYPE_STRING}, + {0, 's', 0, "Select device by its position on the bus.", + "[bus]:[slot][.func]", ARG_TYPE_STRING}, + {0, 'v', 0, "Save read value into variable VARNAME.", + "VARNAME", ARG_TYPE_STRING}, + {0, 0, 0, 0, 0, 0} + }; + +static grub_uint32_t pciid_check_mask, pciid_check_value; +static int bus, device, function; +static int check_bus, check_device, check_function; +static grub_uint32_t write_mask, regwrite; +static int regsize; +static grub_uint16_t regaddr; +static const char *varname; + +static int NESTED_FUNC_ATTR +grub_setpci_iter (grub_pci_device_t dev, grub_pci_id_t pciid) +{ + grub_uint32_t regval = 0; + grub_pci_address_t addr; + + if ((pciid & pciid_check_mask) != pciid_check_value) + return 0; + + if (check_bus && grub_pci_get_bus (dev) != bus) + return 0; + + if (check_device && grub_pci_get_device (dev) != device) + return 0; + + if (check_function && grub_pci_get_function (dev) != device) + return 0; + + addr = grub_pci_make_address (dev, regaddr); + + switch (regsize) + { + case 1: + regval = grub_pci_read_byte (addr); + break; + + case 2: + regval = grub_pci_read_word (addr); + break; + + case 4: + regval = grub_pci_read (addr); + break; + } + + if (varname) + { + char buf[sizeof ("XXXXXXXX")]; + grub_sprintf (buf, "%x", regval); + grub_env_set (varname, buf); + return 1; + } + + if (!write_mask) + { + grub_printf ("Register %x of %d:%d.%d is %x\n", regaddr, + grub_pci_get_bus (dev), + grub_pci_get_device (dev), + grub_pci_get_function (dev), + regval); + return 0; + } + + regval = (regval & ~write_mask) | regwrite; + + switch (regsize) + { + case 1: + grub_pci_write_byte (addr, regval); + break; + + case 2: + grub_pci_write_word (addr, regval); + break; + + case 4: + grub_pci_write (addr, regval); + break; + } + + return 0; +} + +static grub_err_t +grub_cmd_setpci (grub_extcmd_t cmd, int argc, char **argv) +{ + const char *ptr; + unsigned i; + + pciid_check_value = 0; + pciid_check_mask = 0; + + if (cmd->state[0].set) + { + ptr = cmd->state[0].arg; + pciid_check_value |= (grub_strtoul (ptr, (char **) &ptr, 16) & 0xffff); + if (grub_errno == GRUB_ERR_BAD_NUMBER) + { + grub_errno = GRUB_ERR_NONE; + ptr = cmd->state[0].arg; + } + else + pciid_check_mask |= 0xffff; + if (grub_errno) + return grub_errno; + if (*ptr != ':') + return grub_error (GRUB_ERR_BAD_ARGUMENT, "Colon expected."); + ptr++; + pciid_check_value |= (grub_strtoul (ptr, (char **) &ptr, 16) & 0xffff) + << 16; + if (grub_errno == GRUB_ERR_BAD_NUMBER) + grub_errno = GRUB_ERR_NONE; + else + pciid_check_mask |= 0xffff0000; + } + + pciid_check_value &= pciid_check_mask; + + check_bus = check_device = check_function = 0; + + if (cmd->state[1].set) + { + const char *optr; + + ptr = cmd->state[1].arg; + optr = ptr; + bus = grub_strtoul (ptr, (char **) &ptr, 16); + if (grub_errno == GRUB_ERR_BAD_NUMBER) + { + grub_errno = GRUB_ERR_NONE; + ptr = optr; + } + else + check_bus = 1; + if (grub_errno) + return grub_errno; + if (*ptr != ':') + return grub_error (GRUB_ERR_BAD_ARGUMENT, "Colon expected."); + ptr++; + optr = ptr; + device = grub_strtoul (ptr, (char **) &ptr, 16); + if (grub_errno == GRUB_ERR_BAD_NUMBER) + { + grub_errno = GRUB_ERR_NONE; + ptr = optr; + } + else + check_device = 1; + if (*ptr == '.') + { + ptr++; + function = grub_strtoul (ptr, (char **) &ptr, 16); + if (grub_errno) + return grub_errno; + check_function = 1; + } + } + + if (cmd->state[2].set) + varname = cmd->state[2].arg; + else + varname = NULL; + + write_mask = 0; + + if (argc == 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "Command expected."); + + if (argc > 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "Only one command is supported."); + + ptr = argv[0]; + + for (i = 0; i < ARRAY_SIZE (pci_registers); i++) + { + if (grub_strncmp (ptr, pci_registers[i].name, + grub_strlen (pci_registers[i].name)) == 0) + break; + } + if (i == ARRAY_SIZE (pci_registers)) + { + regsize = 0; + regaddr = grub_strtoul (ptr, (char **) &ptr, 16); + if (grub_errno) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "Unknown register"); + } + else + { + regaddr = pci_registers[i].addr; + regsize = pci_registers[i].size; + ptr += grub_strlen (pci_registers[i].name); + } + + if (grub_errno) + return grub_errno; + + if (*ptr == '+') + { + ptr++; + regaddr += grub_strtoul (ptr, (char **) &ptr, 16); + if (grub_errno) + return grub_errno; + } + + if (grub_memcmp (ptr, ".L", sizeof (".L") - 1) == 0 + || grub_memcmp (ptr, ".l", sizeof (".l") - 1) == 0) + { + regsize = 4; + ptr += sizeof (".l") - 1; + } + else if (grub_memcmp (ptr, ".W", sizeof (".W") - 1) == 0 + || grub_memcmp (ptr, ".w", sizeof (".w") - 1) == 0) + { + regsize = 2; + ptr += sizeof (".w") - 1; + } + else if (grub_memcmp (ptr, ".B", sizeof (".B") - 1) == 0 + || grub_memcmp (ptr, ".b", sizeof (".b") - 1) == 0) + { + regsize = 1; + ptr += sizeof (".b") - 1; + } + + if (!regsize) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "Unknown register size."); + + write_mask = 0; + if (*ptr == '=') + { + ptr++; + regwrite = grub_strtoul (ptr, (char **) &ptr, 16); + if (grub_errno) + return grub_errno; + write_mask = 0xffffffff; + if (*ptr == ':') + { + ptr++; + write_mask = grub_strtoul (ptr, (char **) &ptr, 16); + if (grub_errno) + return grub_errno; + write_mask = 0xffffffff; + } + regwrite &= write_mask; + } + + if (write_mask && varname) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "Option -v isn't valid for writes."); + + grub_pci_iterate (grub_setpci_iter); + return GRUB_ERR_NONE; +} + +static grub_extcmd_t cmd; + +GRUB_MOD_INIT(setpci) +{ + cmd = grub_register_extcmd ("setpci", grub_cmd_setpci, GRUB_COMMAND_FLAG_BOTH, + "setpci [-s POSITION] [-d DEVICE] [-v VAR] " + "[REGISTER][=VALUE[:MASK]]", + "Manipulate PCI devices.", options); +} + +GRUB_MOD_FINI(setpci) +{ + grub_unregister_extcmd (cmd); +} diff --git a/conf/i386.rmk b/conf/i386.rmk index c3f036d0f..2c1edf62f 100644 --- a/conf/i386.rmk +++ b/conf/i386.rmk @@ -25,3 +25,9 @@ pkglib_MODULES += ata.mod ata_mod_SOURCES = disk/ata.c ata_mod_CFLAGS = $(COMMON_CFLAGS) ata_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For setpci.mod +pkglib_MODULES += setpci.mod +setpci_mod_SOURCES = commands/setpci.c +setpci_mod_CFLAGS = $(COMMON_CFLAGS) +setpci_mod_LDFLAGS = $(COMMON_LDFLAGS) From e2a101ab76764f80afc62141f56520cfdeed65e8 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 22 Dec 2009 17:18:48 +0100 Subject: [PATCH 164/738] I/O rw support --- commands/iorw.c | 146 ++++++++++++++++++++++++++++++++++++++++++++++++ conf/i386.rmk | 6 ++ 2 files changed, 152 insertions(+) create mode 100644 commands/iorw.c diff --git a/commands/iorw.c b/commands/iorw.c new file mode 100644 index 000000000..5e685a264 --- /dev/null +++ b/commands/iorw.c @@ -0,0 +1,146 @@ +/* memrw.c - command to read / write physical memory */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include + +static grub_extcmd_t cmd_read_byte, cmd_read_word, cmd_read_dword; +static grub_command_t cmd_write_byte, cmd_write_word, cmd_write_dword; + +static const struct grub_arg_option options[] = + { + {0, 'v', 0, "Save read value into variable VARNAME.", + "VARNAME", ARG_TYPE_STRING}, + {0, 0, 0, 0, 0, 0} + }; + + +static grub_err_t +grub_cmd_read (grub_extcmd_t cmd, int argc, char **argv) +{ + grub_target_addr_t addr; + grub_uint32_t value = 0; + char buf[sizeof ("XXXXXXXX")]; + + if (argc != 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid number of arguments"); + + addr = grub_strtoul (argv[0], 0, 0); + switch (cmd->cmd->name[sizeof ("grub_in") - 1]) + { + case 'l': + value = grub_inl (addr); + break; + + case 'w': + value = grub_inw (addr); + break; + + case 'b': + value = grub_inb (addr); + break; + } + + if (cmd->state[0].set) + { + grub_sprintf (buf, "%x", value); + grub_env_set (cmd->state[0].arg, buf); + } + else + grub_printf ("0x%x\n", value); + + return 0; +} + +static grub_err_t +grub_cmd_write (grub_command_t cmd, int argc, char **argv) +{ + grub_target_addr_t addr; + grub_uint32_t value; + grub_uint32_t mask = 0xffffffff; + + if (argc != 2 && argc != 3) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid number of arguments"); + + addr = grub_strtoul (argv[0], 0, 0); + value = grub_strtoul (argv[1], 0, 0); + if (argc == 3) + mask = grub_strtoul (argv[2], 0, 0); + value &= mask; + switch (cmd->name[sizeof ("grub_out") - 1]) + { + case 'l': + if (mask != 0xffffffff) + grub_outl ((grub_inl (addr) & ~mask) | value, addr); + else + grub_outl (value, addr); + break; + + case 'w': + if ((mask & 0xffff) != 0xffff) + grub_outw ((grub_inw (addr) & ~mask) | value, addr); + else + grub_outw (value, addr); + break; + + case 'b': + if ((mask & 0xff) != 0xff) + grub_outb ((grub_inb (addr) & ~mask) | value, addr); + else + grub_outb (value, addr); + break; + } + + return 0; +} + +GRUB_MOD_INIT(memrw) +{ + cmd_read_byte = + grub_register_extcmd ("grub_inb", grub_cmd_read, GRUB_COMMAND_FLAG_BOTH, + "grub_inb PORT", "Read byte from PORT.", options); + cmd_read_word = + grub_register_extcmd ("grub_inw", grub_cmd_read, GRUB_COMMAND_FLAG_BOTH, + "grub_inw PORT", "Read word from PORT.", options); + cmd_read_dword = + grub_register_extcmd ("grub_inl", grub_cmd_read, GRUB_COMMAND_FLAG_BOTH, + "grub_inl PORT", "Read dword from PORT.", options); + cmd_write_byte = + grub_register_command ("grub_outb", grub_cmd_write, + "grub_outb PORT VALUE [MASK]", "Write byte VALUE to PORT."); + cmd_write_word = + grub_register_command ("grub_outw", grub_cmd_write, + "grub_outw PORT VALUE [MASK]", "Write word VALUE to PORT."); + cmd_write_dword = + grub_register_command ("grub_outl", grub_cmd_write, + "grub_outl ADDR VALUE [MASK]", "Write dword VALUE to PORT."); +} + +GRUB_MOD_FINI(memrw) +{ + grub_unregister_extcmd (cmd_read_byte); + grub_unregister_extcmd (cmd_read_word); + grub_unregister_extcmd (cmd_read_dword); + grub_unregister_command (cmd_write_byte); + grub_unregister_command (cmd_write_word); + grub_unregister_command (cmd_write_dword); +} diff --git a/conf/i386.rmk b/conf/i386.rmk index c3f036d0f..45d2c0818 100644 --- a/conf/i386.rmk +++ b/conf/i386.rmk @@ -25,3 +25,9 @@ pkglib_MODULES += ata.mod ata_mod_SOURCES = disk/ata.c ata_mod_CFLAGS = $(COMMON_CFLAGS) ata_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For iorw.mod. +pkglib_MODULES += iorw.mod +iorw_mod_SOURCES = commands/iorw.c +iorw_mod_CFLAGS = $(COMMON_CFLAGS) +iorw_mod_LDFLAGS = $(COMMON_LDFLAGS) From 9b1209ba15cc0cddaf965f98777eb6cbd1213129 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 26 Dec 2009 02:37:01 +0100 Subject: [PATCH 165/738] Cache loaded theme --- gfxmenu/gfxmenu.c | 63 +++++++++++++++++++++++++++----- gfxmenu/view.c | 71 ++++++++----------------------------- include/grub/gfxmenu_view.h | 3 +- 3 files changed, 70 insertions(+), 67 deletions(-) diff --git a/gfxmenu/gfxmenu.c b/gfxmenu/gfxmenu.c index 0d807914b..f39cdbbfe 100644 --- a/gfxmenu/gfxmenu.c +++ b/gfxmenu/gfxmenu.c @@ -37,21 +37,39 @@ #include #include -void -grub_gfxmenu_viewer_fini (void *data) -{ - grub_gfxmenu_view_t view = data; +grub_gfxmenu_view_t cached_view; - grub_gfxmenu_view_destroy (view); +static grub_err_t +set_graphics_mode (void) +{ + const char *modestr = grub_env_get ("gfxmode"); + if (!modestr || !modestr[0]) + modestr = "auto"; + return grub_video_set_mode (modestr, GRUB_VIDEO_MODE_TYPE_PURE_TEXT, 0); +} + +/* FIXME: conflicts with gfxterm. */ +static grub_err_t +set_text_mode (void) +{ + return grub_video_restore (); +} + +void +grub_gfxmenu_viewer_fini (void *data __attribute__ ((unused))) +{ + set_text_mode (); } /* FIXME: 't' and 'c'. */ grub_err_t grub_gfxmenu_try (int entry, grub_menu_t menu, int nested) { - grub_gfxmenu_view_t view; + grub_gfxmenu_view_t view = NULL; const char *theme_path; struct grub_menu_viewer *instance; + grub_err_t err; + struct grub_video_mode_info mode_info; theme_path = grub_env_get ("theme"); if (! theme_path) @@ -61,15 +79,41 @@ grub_gfxmenu_try (int entry, grub_menu_t menu, int nested) if (!instance) return grub_errno; - /* Create the view. */ - view = grub_gfxmenu_view_new (theme_path, menu, entry, nested); + set_graphics_mode (); + err = grub_video_get_info (&mode_info); + if (err) + { + set_text_mode (); + return 0; + } - if (! view) + if (!cached_view || grub_strcmp (cached_view->theme_path, theme_path) != 0 + || cached_view->screen.width != (int) mode_info.width + || cached_view->screen.height != (int) mode_info.height) + { + grub_free (cached_view); + /* Create the view. */ + cached_view = grub_gfxmenu_view_new (theme_path, mode_info.width, + mode_info.height); + } + + if (! cached_view) { grub_free (instance); + set_text_mode (); return grub_errno; } + view = cached_view; + + view->double_repaint = (mode_info.mode_type + & GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED) + && !(mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP); + view->selected = entry; + view->menu = menu; + view->nested = nested; + view->first_timeout = -1; + grub_gfxmenu_view_draw (view); instance->data = view; @@ -90,5 +134,6 @@ GRUB_MOD_INIT (gfxmenu) GRUB_MOD_FINI (gfxmenu) { + grub_gfxmenu_view_destroy (cached_view); grub_gfxmenu_try_hook = NULL; } diff --git a/gfxmenu/view.c b/gfxmenu/view.c index 882469447..8c460ff88 100644 --- a/gfxmenu/view.c +++ b/gfxmenu/view.c @@ -45,62 +45,31 @@ static grub_gfxmenu_view_t term_view; #endif -static grub_err_t set_graphics_mode (void); -static grub_err_t set_text_mode (void); - /* Create a new view object, loading the theme specified by THEME_PATH and associating MODEL with the view. */ grub_gfxmenu_view_t -grub_gfxmenu_view_new (const char *theme_path, grub_menu_t menu, int entry, - int nested) +grub_gfxmenu_view_new (const char *theme_path, + int width, int height) { grub_gfxmenu_view_t view; - grub_err_t err; - struct grub_video_mode_info mode_info; + grub_font_t default_font; + grub_gui_color_t default_fg_color; + grub_gui_color_t default_bg_color; view = grub_malloc (sizeof (*view)); if (! view) return 0; - set_graphics_mode (); - grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY); - grub_video_get_viewport ((unsigned *) &view->screen.x, - (unsigned *) &view->screen.y, - (unsigned *) &view->screen.width, - (unsigned *) &view->screen.height); - - err = grub_video_get_info (&mode_info); - if (err) - { - grub_free (view); - return 0; - } - else - view->double_repaint = (mode_info.mode_type - & GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED) - && !(mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP); - - - /* Clear the screen; there may be garbage left over in video memory, and - loading the menu style (particularly the background) can take a while. */ - grub_video_fill_rect (grub_video_map_rgb (0, 0, 0), - view->screen.x, view->screen.y, - view->screen.width, view->screen.height); - grub_video_swap_buffers (); - - grub_font_t default_font; - grub_gui_color_t default_fg_color; - grub_gui_color_t default_bg_color; + view->screen.x = 0; + view->screen.y = 0; + view->screen.width = width; + view->screen.height = height; default_font = grub_font_get ("Helvetica 12"); default_fg_color = grub_gui_color_rgb (0, 0, 0); default_bg_color = grub_gui_color_rgb (255, 255, 255); view->canvas = 0; - view->selected = entry; - view->menu = menu; - view->nested = nested; - view->first_timeout = -1; view->title_font = default_font; view->message_font = default_font; @@ -151,7 +120,6 @@ grub_gfxmenu_view_destroy (grub_gfxmenu_view_t view) view->canvas->ops->component.destroy (view->canvas); grub_free (view); - set_text_mode (); #if 0 destroy_terminal (); #endif @@ -376,6 +344,12 @@ grub_gfxmenu_view_redraw (grub_gfxmenu_view_t view, void grub_gfxmenu_view_draw (grub_gfxmenu_view_t view) { + /* Clear the screen; there may be garbage left over in video memory. */ + grub_video_fill_rect (grub_video_map_rgb (0, 0, 0), + view->screen.x, view->screen.y, + view->screen.width, view->screen.height); + grub_video_swap_buffers (); + update_menu_components (view); grub_gfxmenu_view_redraw (view, &view->screen); @@ -426,21 +400,6 @@ grub_gfxmenu_set_chosen_entry (int entry, void *data) } -static grub_err_t -set_graphics_mode (void) -{ - const char *modestr = grub_env_get ("gfxmode"); - if (!modestr || !modestr[0]) - modestr = "auto"; - return grub_video_set_mode (modestr, GRUB_VIDEO_MODE_TYPE_PURE_TEXT, 0); -} - -static grub_err_t -set_text_mode (void) -{ - return grub_video_restore (); -} - /* FIXME */ #if 0 static int term_target_width; diff --git a/include/grub/gfxmenu_view.h b/include/grub/gfxmenu_view.h index 92cedc6a7..1b83cc5a3 100644 --- a/include/grub/gfxmenu_view.h +++ b/include/grub/gfxmenu_view.h @@ -31,8 +31,7 @@ typedef struct grub_gfxmenu_view *grub_gfxmenu_view_t; grub_gfxmenu_view_t grub_gfxmenu_view_new (const char *theme_path, - grub_menu_t menu, int entry, - int nested); + int width, int height); void grub_gfxmenu_view_destroy (grub_gfxmenu_view_t view); From d3ee2d201e3a241ee1f39e9a2a2e3e6580579186 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 26 Dec 2009 16:41:54 +0100 Subject: [PATCH 166/738] Various fixes to make gfxmenu work smoothly in multioutput environment --- gfxmenu/gfxmenu.c | 43 +++++----- gfxmenu/view.c | 109 ++++++++++---------------- include/grub/gfxmenu_view.h | 8 -- include/grub/gfxterm.h | 18 +++-- include/grub/menu.h | 4 - term/gfxterm.c | 152 ++++++++++++++++-------------------- 6 files changed, 137 insertions(+), 197 deletions(-) diff --git a/gfxmenu/gfxmenu.c b/gfxmenu/gfxmenu.c index f39cdbbfe..b093ec49e 100644 --- a/gfxmenu/gfxmenu.c +++ b/gfxmenu/gfxmenu.c @@ -39,26 +39,9 @@ grub_gfxmenu_view_t cached_view; -static grub_err_t -set_graphics_mode (void) -{ - const char *modestr = grub_env_get ("gfxmode"); - if (!modestr || !modestr[0]) - modestr = "auto"; - return grub_video_set_mode (modestr, GRUB_VIDEO_MODE_TYPE_PURE_TEXT, 0); -} - -/* FIXME: conflicts with gfxterm. */ -static grub_err_t -set_text_mode (void) -{ - return grub_video_restore (); -} - void grub_gfxmenu_viewer_fini (void *data __attribute__ ((unused))) { - set_text_mode (); } /* FIXME: 't' and 'c'. */ @@ -73,18 +56,23 @@ grub_gfxmenu_try (int entry, grub_menu_t menu, int nested) theme_path = grub_env_get ("theme"); if (! theme_path) - return grub_error (GRUB_ERR_FILE_NOT_FOUND, "no theme specified"); + { + grub_gfxterm_fullscreen (); + return grub_error (GRUB_ERR_FILE_NOT_FOUND, "no theme specified"); + } instance = grub_zalloc (sizeof (*instance)); if (!instance) - return grub_errno; + { + grub_gfxterm_fullscreen (); + return grub_errno; + } - set_graphics_mode (); err = grub_video_get_info (&mode_info); if (err) { - set_text_mode (); - return 0; + grub_gfxterm_fullscreen (); + return err; } if (!cached_view || grub_strcmp (cached_view->theme_path, theme_path) != 0 @@ -100,7 +88,7 @@ grub_gfxmenu_try (int entry, grub_menu_t menu, int nested) if (! cached_view) { grub_free (instance); - set_text_mode (); + grub_gfxterm_fullscreen (); return grub_errno; } @@ -129,6 +117,15 @@ grub_gfxmenu_try (int entry, grub_menu_t menu, int nested) GRUB_MOD_INIT (gfxmenu) { + struct grub_term_output *term; + + FOR_ACTIVE_TERM_OUTPUTS(term) + if (grub_gfxmenu_try_hook && grub_strcmp (term->name, "gfxterm") == 0) + { + grub_gfxterm_fullscreen (); + break; + } + grub_gfxmenu_try_hook = grub_gfxmenu_try; } diff --git a/gfxmenu/view.c b/gfxmenu/view.c index 8c460ff88..a7ca14530 100644 --- a/gfxmenu/view.c +++ b/gfxmenu/view.c @@ -41,9 +41,10 @@ status changes. */ #define TIMEOUT_COMPONENT_ID "__timeout__" -#if 0 +static void +init_terminal (grub_gfxmenu_view_t view); +static grub_video_rect_t term_rect; static grub_gfxmenu_view_t term_view; -#endif /* Create a new view object, loading the theme specified by THEME_PATH and associating MODEL with the view. */ @@ -98,10 +99,6 @@ grub_gfxmenu_view_new (const char *theme_path, return 0; } -#if 0 - init_terminal (view); -#endif - return view; } @@ -119,26 +116,8 @@ grub_gfxmenu_view_destroy (grub_gfxmenu_view_t view) if (view->canvas) view->canvas->ops->component.destroy (view->canvas); grub_free (view); - -#if 0 - destroy_terminal (); -#endif } -#if 0 -/* Sets MESSAGE as the progress message for the view. - MESSAGE can be 0, in which case no message is displayed. */ -static void -set_progress_message (grub_gfxmenu_view_t view, const char *message) -{ - grub_free (view->progress_message_text); - if (message) - view->progress_message_text = grub_strdup (message); - else - view->progress_message_text = 0; -} -#endif - static void redraw_background (grub_gfxmenu_view_t view, const grub_video_rect_t *bounds) @@ -331,6 +310,9 @@ void grub_gfxmenu_view_redraw (grub_gfxmenu_view_t view, const grub_video_rect_t *region) { + if (grub_video_have_common_points (&term_rect, region)) + grub_gfxterm_schedule_repaint (); + grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY); redraw_background (view, region); @@ -344,11 +326,17 @@ grub_gfxmenu_view_redraw (grub_gfxmenu_view_t view, void grub_gfxmenu_view_draw (grub_gfxmenu_view_t view) { + init_terminal (view); + /* Clear the screen; there may be garbage left over in video memory. */ grub_video_fill_rect (grub_video_map_rgb (0, 0, 0), view->screen.x, view->screen.y, view->screen.width, view->screen.height); grub_video_swap_buffers (); + if (view->double_repaint) + grub_video_fill_rect (grub_video_map_rgb (0, 0, 0), + view->screen.x, view->screen.y, + view->screen.width, view->screen.height); update_menu_components (view); @@ -399,77 +387,60 @@ grub_gfxmenu_set_chosen_entry (int entry, void *data) grub_gfxmenu_redraw_menu (view); } - -/* FIXME */ -#if 0 -static int term_target_width; -static int term_target_height; -static int term_initialized; -static grub_term_output_t term_original; - static void -draw_terminal_box (grub_gfxmenu_view_t view) +grub_gfxmenu_draw_terminal_box (void) { grub_gfxmenu_box_t term_box; - int termx; - int termy; term_box = term_view->terminal_box; if (!term_box) return; - - termx = term_view->screen.x + term_view->screen.width * (10 - 7) / 10 / 2; - termy = term_view->screen.y + term_view->screen.height * (10 - 7) / 10 / 2; - term_box->set_content_size (term_box, term_target_width, - term_target_height); + term_box->set_content_size (term_box, term_rect.width, + term_rect.height); term_box->draw (term_box, - termx - term_box->get_left_pad (term_box), - termy - term_box->get_top_pad (term_box)); + term_rect.x - term_box->get_left_pad (term_box), + term_rect.y - term_box->get_top_pad (term_box)); grub_video_swap_buffers (); - if (view->double_repaint) + if (term_view->double_repaint) term_box->draw (term_box, - termx - term_box->get_left_pad (term_box), - termy - term_box->get_top_pad (term_box)); + term_rect.x - term_box->get_left_pad (term_box), + term_rect.y - term_box->get_top_pad (term_box)); } static void init_terminal (grub_gfxmenu_view_t view) { - int termx; - int termy; + term_rect.width = view->screen.width * 7 / 10; + term_rect.height = view->screen.height * 7 / 10; - term_original = grub_term_get_current_output (); + term_rect.x = view->screen.x + view->screen.width * (10 - 7) / 10 / 2; + term_rect.y = view->screen.y + view->screen.height * (10 - 7) / 10 / 2; - term_target_width = view->screen.width * 7 / 10; - term_target_height = view->screen.height * 7 / 10; - - termx = view->screen.x + view->screen.width * (10 - 7) / 10 / 2; - termy = view->screen.y + view->screen.height * (10 - 7) / 10 / 2; + term_view = view; /* Note: currently there is no API for changing the gfxterm font on the fly, so whatever font the initially loaded theme specifies will be permanent. */ - grub_gfxterm_init_window (GRUB_VIDEO_RENDER_TARGET_DISPLAY, termx, termy, - term_target_width, term_target_height, - view->double_repaint, view->terminal_font_name, 3); - if (grub_errno != GRUB_ERR_NONE) - return; - term_initialized = 1; - - term_view = view; - - grub_term_set_current_output (grub_gfxterm_get_term ()); - grub_refresh (); + grub_gfxterm_set_window (GRUB_VIDEO_RENDER_TARGET_DISPLAY, term_rect.x, + term_rect.y, + term_rect.width, term_rect.height, + view->double_repaint, view->terminal_font_name, 3); + grub_gfxterm_decorator_hook = grub_gfxmenu_draw_terminal_box; } -static void destroy_terminal (void) +#if 0 +/* Sets MESSAGE as the progress message for the view. + MESSAGE can be 0, in which case no message is displayed. */ +static void +set_progress_message (grub_gfxmenu_view_t view, const char *message) { - if (term_initialized) - grub_gfxterm_destroy_window (); - if (term_original) - grub_term_set_current_output (term_original); + grub_free (view->progress_message_text); + if (message) + view->progress_message_text = grub_strdup (message); + else + view->progress_message_text = 0; } static void diff --git a/include/grub/gfxmenu_view.h b/include/grub/gfxmenu_view.h index 1b83cc5a3..7cbfa89d3 100644 --- a/include/grub/gfxmenu_view.h +++ b/include/grub/gfxmenu_view.h @@ -45,14 +45,6 @@ grub_err_t grub_gui_recreate_box (grub_gfxmenu_box_t *boxptr, void grub_gfxmenu_view_draw (grub_gfxmenu_view_t view); -int grub_gfxmenu_view_execute_with_fallback (grub_gfxmenu_view_t view, - grub_menu_entry_t entry); - -int grub_gfxmenu_view_execute_entry (grub_gfxmenu_view_t view, - grub_menu_entry_t entry); - -void grub_gfxmenu_view_run_terminal (grub_gfxmenu_view_t view); - void grub_gfxmenu_redraw_menu (grub_gfxmenu_view_t view); diff --git a/include/grub/gfxterm.h b/include/grub/gfxterm.h index e607bd5e1..fe3da7409 100644 --- a/include/grub/gfxterm.h +++ b/include/grub/gfxterm.h @@ -25,18 +25,20 @@ #include grub_err_t -grub_gfxterm_init_window (struct grub_video_render_target *target, - int x, int y, int width, int height, - int double_repaint, - const char *font_name, int border_width); - -void grub_gfxterm_destroy_window (void); - -const struct grub_term_output *grub_gfxterm_get_term (void); +grub_gfxterm_set_window (struct grub_video_render_target *target, + int x, int y, int width, int height, + int double_repaint, + const char *font_name, int border_width); typedef void (*grub_gfxterm_repaint_callback_t)(int x, int y, int width, int height); void grub_gfxterm_set_repaint_callback (grub_gfxterm_repaint_callback_t func); +void grub_gfxterm_schedule_repaint (void); + +grub_err_t grub_gfxterm_fullscreen (void); + +extern void (*grub_gfxterm_decorator_hook) (void); + #endif /* ! GRUB_GFXTERM_HEADER */ diff --git a/include/grub/menu.h b/include/grub/menu.h index 20a1fc47f..78f461b92 100644 --- a/include/grub/menu.h +++ b/include/grub/menu.h @@ -83,10 +83,6 @@ typedef struct grub_menu_execute_callback } *grub_menu_execute_callback_t; -extern grub_err_t (*grub_gfxmenu_try_hook) (int entry, grub_menu_t menu, - int nested); - - grub_menu_entry_t grub_menu_get_entry (grub_menu_t menu, int no); int grub_menu_get_timeout (void); void grub_menu_set_timeout (int timeout); diff --git a/term/gfxterm.c b/term/gfxterm.c index eb2c47c3d..8ef7d848b 100644 --- a/term/gfxterm.c +++ b/term/gfxterm.c @@ -115,20 +115,16 @@ struct grub_gfxterm_window int double_repaint; }; -static int refcount; static struct grub_video_render_target *render_target; +void (*grub_gfxterm_decorator_hook) (void) = NULL; static struct grub_gfxterm_window window; static struct grub_virtual_screen virtual_screen; static grub_gfxterm_repaint_callback_t repaint_callback; - -static grub_err_t init_window (struct grub_video_render_target *target, - int x, int y, int width, int height, - int double_repaint, - const char *font_name, int border_width); +static int repaint_schedulded = 0; +static int repaint_was_schedulded = 0; static void destroy_window (void); - static struct grub_video_render_target *text_layer; static unsigned int bitmap_width; @@ -271,10 +267,17 @@ grub_virtual_screen_setup (unsigned int x, unsigned int y, return grub_errno; } -static grub_err_t -init_window (struct grub_video_render_target *target, - int x, int y, int width, int height, int double_repaint, - const char *font_name, int border_width) +void +grub_gfxterm_schedule_repaint (void) +{ + repaint_schedulded = 1; +} + +grub_err_t +grub_gfxterm_set_window (struct grub_video_render_target *target, + int x, int y, int width, int height, + int double_repaint, + const char *font_name, int border_width) { /* Clean up any prior instance. */ destroy_window (); @@ -299,45 +302,55 @@ init_window (struct grub_video_render_target *target, window.height = height; window.double_repaint = double_repaint; - /* Mark whole window as dirty. */ dirty_region_reset (); - dirty_region_add (0, 0, width, height); + grub_gfxterm_schedule_repaint (); return grub_errno; } grub_err_t -grub_gfxterm_init_window (struct grub_video_render_target *target, - int x, int y, int width, int height, - int double_repaint, - const char *font_name, int border_width) -{ - if (refcount++ == 0) - init_window (target, x, y, width, height, double_repaint, - font_name, border_width); - return grub_errno; -} - -static grub_err_t -grub_gfxterm_init (void) +grub_gfxterm_fullscreen (void) { const char *font_name; - const char *modevar; struct grub_video_mode_info mode_info; - char *tmp; - grub_err_t err; grub_video_color_t color; + grub_err_t err; - /* If gfxterm has already been initialized by calling the init_window - function, then leave it alone when it is set as the current terminal. */ - if (refcount++ != 0) - return GRUB_ERR_NONE; + err = grub_video_get_info (&mode_info); + /* Figure out what mode we ended up. */ + if (err) + return err; + + grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY); + + /* Make sure screen is black. */ + color = grub_video_map_rgb (0, 0, 0); + grub_video_fill_rect (color, 0, 0, mode_info.width, mode_info.height); + bitmap = 0; /* Select the font to use. */ font_name = grub_env_get ("gfxterm_font"); if (! font_name) font_name = ""; /* Allow fallback to any font. */ + grub_gfxterm_decorator_hook = NULL; + + return grub_gfxterm_set_window (GRUB_VIDEO_RENDER_TARGET_DISPLAY, + 0, 0, mode_info.width, mode_info.height, + mode_info.mode_type + & GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED + && !(mode_info.mode_type + & GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP), + font_name, DEFAULT_BORDER_WIDTH); +} + +static grub_err_t +grub_gfxterm_init (void) +{ + char *tmp; + grub_err_t err; + const char *modevar; + /* Parse gfxmode environment variable if set. */ modevar = grub_env_get ("gfxmode"); if (! modevar || *modevar == 0) @@ -358,35 +371,11 @@ grub_gfxterm_init (void) if (err) return err; - err = grub_video_get_info (&mode_info); - /* Figure out what mode we ended up. */ + err = grub_gfxterm_fullscreen (); if (err) - return err; + grub_video_restore (); - /* Make sure screen is black. */ - color = grub_video_map_rgb (0, 0, 0); - grub_video_fill_rect (color, 0, 0, mode_info.width, mode_info.height); - bitmap = 0; - - /* Select the font to use. */ - font_name = grub_env_get ("gfxterm_font"); - if (! font_name) - font_name = ""; /* Allow fallback to any font. */ - - /* Leave borders for virtual screen. */ - if (init_window (GRUB_VIDEO_RENDER_TARGET_DISPLAY, - 0, 0, mode_info.width, mode_info.height, - mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED - && !(mode_info.mode_type - & GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP), - font_name, - DEFAULT_BORDER_WIDTH) != GRUB_ERR_NONE) - { - grub_video_restore (); - return grub_errno; - } - - return grub_errno; + return err; } static void @@ -402,26 +391,15 @@ destroy_window (void) grub_virtual_screen_free (); } -void -grub_gfxterm_destroy_window (void) -{ - if (--refcount == 0) - destroy_window (); -} - static grub_err_t grub_gfxterm_fini (void) { - /* Don't destroy an explicitly initialized terminal instance when it is - unset as the current terminal. */ - if (--refcount == 0) - { - destroy_window (); - grub_video_restore (); - } + destroy_window (); + grub_video_restore (); /* Clear error state. */ - return (grub_errno = GRUB_ERR_NONE); + grub_errno = GRUB_ERR_NONE; + return GRUB_ERR_NONE; } static void @@ -521,6 +499,7 @@ dirty_region_reset (void) dirty_region.top_left_y = -1; dirty_region.bottom_right_x = -1; dirty_region.bottom_right_y = -1; + repaint_was_schedulded = 0; } static int @@ -540,6 +519,16 @@ dirty_region_add (int x, int y, unsigned int width, unsigned int height) if ((width == 0) || (height == 0)) return; + if (repaint_schedulded) + { + x = virtual_screen.offset_x; + y = virtual_screen.offset_y; + width = virtual_screen.width; + height = virtual_screen.height; + repaint_schedulded = 0; + repaint_was_schedulded = 1; + } + if (dirty_region_is_empty ()) { dirty_region.top_left_x = x; @@ -586,6 +575,9 @@ dirty_region_redraw (void) width = dirty_region.bottom_right_x - x + 1; height = dirty_region.bottom_right_y - y + 1; + if (repaint_was_schedulded && grub_gfxterm_decorator_hook) + grub_gfxterm_decorator_hook (); + redraw_screen_rect (x, y, width, height); } @@ -1109,7 +1101,6 @@ grub_gfxterm_background_image_cmd (grub_extcmd_t cmd __attribute__ ((unused)), bitmap = 0; /* Mark whole screen as dirty. */ - dirty_region_reset (); dirty_region_add (0, 0, window.width, window.height); } @@ -1152,7 +1143,6 @@ grub_gfxterm_background_image_cmd (grub_extcmd_t cmd __attribute__ ((unused)), bitmap_height = grub_video_bitmap_get_height (bitmap); /* Mark whole screen as dirty. */ - dirty_region_reset (); dirty_region_add (0, 0, window.width, window.height); } } @@ -1182,18 +1172,10 @@ static struct grub_term_output grub_video_term = .next = 0 }; -const struct grub_term_output * -grub_gfxterm_get_term (void) -{ - return &grub_video_term; -} - static grub_extcmd_t background_image_cmd_handle; GRUB_MOD_INIT(term_gfxterm) { - refcount = 0; - grub_term_register_output ("gfxterm", &grub_video_term); background_image_cmd_handle = grub_register_extcmd ("background_image", From 4cc972be91c947f12a9edcd10946ae1119494fe7 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 26 Dec 2009 16:58:01 +0100 Subject: [PATCH 167/738] Clarify FIXME comments. --- gfxmenu/gfxmenu.c | 2 +- gfxmenu/view.c | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/gfxmenu/gfxmenu.c b/gfxmenu/gfxmenu.c index b093ec49e..1fe6e7297 100644 --- a/gfxmenu/gfxmenu.c +++ b/gfxmenu/gfxmenu.c @@ -44,7 +44,7 @@ grub_gfxmenu_viewer_fini (void *data __attribute__ ((unused))) { } -/* FIXME: 't' and 'c'. */ +/* FIXME: Previously 't' changed to text menu is it necessary? */ grub_err_t grub_gfxmenu_try (int entry, grub_menu_t menu, int nested) { diff --git a/gfxmenu/view.c b/gfxmenu/view.c index a7ca14530..c32211261 100644 --- a/gfxmenu/view.c +++ b/gfxmenu/view.c @@ -430,6 +430,9 @@ init_terminal (grub_gfxmenu_view_t view) grub_gfxterm_decorator_hook = grub_gfxmenu_draw_terminal_box; } +/* FIXME: previously notifications were displayed in special case. + Is it necessary? + */ #if 0 /* Sets MESSAGE as the progress message for the view. MESSAGE can be 0, in which case no message is displayed. */ From 3251f0f88be2499e889c7b8634b9d12d253af28b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 27 Dec 2009 16:37:18 +0100 Subject: [PATCH 168/738] Regexp support --- ChangeLog.regexp | 17 + commands/regexp.c | 79 + conf/common.rmk | 5 + gnulib/regcomp.c | 3851 +++++++++++++++++++++++++++++++ gnulib/regex.c | 26 + gnulib/regex_internal.c | 1737 ++++++++++++++ gnulib/regex_internal.h | 828 +++++++ gnulib/regexec.c | 4407 ++++++++++++++++++++++++++++++++++++ include/grub/gnulib-wrap.h | 181 ++ include/grub/regex.h | 675 ++++++ 10 files changed, 11806 insertions(+) create mode 100644 ChangeLog.regexp create mode 100644 commands/regexp.c create mode 100644 gnulib/regcomp.c create mode 100644 gnulib/regex.c create mode 100644 gnulib/regex_internal.c create mode 100644 gnulib/regex_internal.h create mode 100644 gnulib/regexec.c create mode 100644 include/grub/gnulib-wrap.h create mode 100644 include/grub/regex.h diff --git a/ChangeLog.regexp b/ChangeLog.regexp new file mode 100644 index 000000000..c5329964c --- /dev/null +++ b/ChangeLog.regexp @@ -0,0 +1,17 @@ +2009-12-27 Vladimir Serbinenko + + Regexp support. + + * conf/common.rmk (pkglib_MODULES): Add regexp.mod. + (regexp_mod_SOURCES): New variable. + (regexp_mod_CFLAGS): Likewise. + (regexp_mod_LDFLAGS): Likewise. + * commands/regexp.c: New file. + * include/grub/gnulib-wrap.h: Likewise. + * gnulib/regcomp.c: New file. Imported from gnulib. + * gnulib/regex.c: Likewise. + * gnulib/regex_internal.c: Likewise. + * gnulib/regex_internal.h: Likewise. + * gnulib/regexec.c: Likewise. + * include/grub/regex.h: Likewise. + diff --git a/commands/regexp.c b/commands/regexp.c new file mode 100644 index 000000000..6ceb78f0f --- /dev/null +++ b/commands/regexp.c @@ -0,0 +1,79 @@ +/* regexp.c -- The regexp command. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2007 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include + +static grub_err_t +grub_cmd_regexp (grub_command_t cmd __attribute__ ((unused)), + int argc, char **args) +{ + int argn = 0; + int matches = 0; + regex_t regex; + int ret; + grub_size_t s; + char *comperr; + grub_err_t err; + + if (argc != 2) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "2 arguments expected"); + + ret = regcomp (®ex, args[0], RE_SYNTAX_GNU_AWK); + if (ret) + goto fail; + + ret = regexec (®ex, args[1], 0, 0, 0); + if (!ret) + { + regfree (®ex); + return GRUB_ERR_NONE; + } + + fail: + s = regerror (ret, ®ex, 0, 0); + comperr = grub_malloc (s); + if (!comperr) + { + regfree (®ex); + return grub_errno; + } + regerror (ret, ®ex, comperr, s); + err = grub_error (GRUB_ERR_TEST_FAILURE, "%s", comperr); + regfree (®ex); + grub_free (comperr); + return err; +} + +static grub_command_t cmd; + +GRUB_MOD_INIT(regexp) +{ + cmd = grub_register_command ("regexp", grub_cmd_regexp, + "REGEXP STRING", + "Test if REGEXP matches STRING."); +} + +GRUB_MOD_FINI(regexp) +{ + grub_unregister_command (cmd); +} diff --git a/conf/common.rmk b/conf/common.rmk index 4fd005777..73fb4d0e4 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -650,3 +650,8 @@ pkglib_MODULES += charset.mod charset_mod_SOURCES = lib/charset.c charset_mod_CFLAGS = $(COMMON_CFLAGS) charset_mod_LDFLAGS = $(COMMON_LDFLAGS) + +pkglib_MODULES += regexp.mod +regexp_mod_SOURCES = gnulib/regex.c commands/regexp.c +regexp_mod_CFLAGS = $(COMMON_CFLAGS) -Wno-sign-compare -Wno-unused +regexp_mod_LDFLAGS = $(COMMON_LDFLAGS) diff --git a/gnulib/regcomp.c b/gnulib/regcomp.c new file mode 100644 index 000000000..6472ff6b2 --- /dev/null +++ b/gnulib/regcomp.c @@ -0,0 +1,3851 @@ +/* Extended regular expression matching and search library. + Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009 + Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Isamu Hasegawa . + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +static reg_errcode_t re_compile_internal (regex_t *preg, const char * pattern, + size_t length, reg_syntax_t syntax); +static void re_compile_fastmap_iter (regex_t *bufp, + const re_dfastate_t *init_state, + char *fastmap); +static reg_errcode_t init_dfa (re_dfa_t *dfa, size_t pat_len); +#ifdef RE_ENABLE_I18N +static void free_charset (re_charset_t *cset); +#endif /* RE_ENABLE_I18N */ +static void free_workarea_compile (regex_t *preg); +static reg_errcode_t create_initial_state (re_dfa_t *dfa); +#ifdef RE_ENABLE_I18N +static void optimize_utf8 (re_dfa_t *dfa); +#endif +static reg_errcode_t analyze (regex_t *preg); +static reg_errcode_t preorder (bin_tree_t *root, + reg_errcode_t (fn (void *, bin_tree_t *)), + void *extra); +static reg_errcode_t postorder (bin_tree_t *root, + reg_errcode_t (fn (void *, bin_tree_t *)), + void *extra); +static reg_errcode_t optimize_subexps (void *extra, bin_tree_t *node); +static reg_errcode_t lower_subexps (void *extra, bin_tree_t *node); +static bin_tree_t *lower_subexp (reg_errcode_t *err, regex_t *preg, + bin_tree_t *node); +static reg_errcode_t calc_first (void *extra, bin_tree_t *node); +static reg_errcode_t calc_next (void *extra, bin_tree_t *node); +static reg_errcode_t link_nfa_nodes (void *extra, bin_tree_t *node); +static Idx duplicate_node (re_dfa_t *dfa, Idx org_idx, unsigned int constraint); +static Idx search_duplicated_node (const re_dfa_t *dfa, Idx org_node, + unsigned int constraint); +static reg_errcode_t calc_eclosure (re_dfa_t *dfa); +static reg_errcode_t calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa, + Idx node, bool root); +static reg_errcode_t calc_inveclosure (re_dfa_t *dfa); +static Idx fetch_number (re_string_t *input, re_token_t *token, + reg_syntax_t syntax); +static int peek_token (re_token_t *token, re_string_t *input, + reg_syntax_t syntax) internal_function; +static bin_tree_t *parse (re_string_t *regexp, regex_t *preg, + reg_syntax_t syntax, reg_errcode_t *err); +static bin_tree_t *parse_reg_exp (re_string_t *regexp, regex_t *preg, + re_token_t *token, reg_syntax_t syntax, + Idx nest, reg_errcode_t *err); +static bin_tree_t *parse_branch (re_string_t *regexp, regex_t *preg, + re_token_t *token, reg_syntax_t syntax, + Idx nest, reg_errcode_t *err); +static bin_tree_t *parse_expression (re_string_t *regexp, regex_t *preg, + re_token_t *token, reg_syntax_t syntax, + Idx nest, reg_errcode_t *err); +static bin_tree_t *parse_sub_exp (re_string_t *regexp, regex_t *preg, + re_token_t *token, reg_syntax_t syntax, + Idx nest, reg_errcode_t *err); +static bin_tree_t *parse_dup_op (bin_tree_t *dup_elem, re_string_t *regexp, + re_dfa_t *dfa, re_token_t *token, + reg_syntax_t syntax, reg_errcode_t *err); +static bin_tree_t *parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, + re_token_t *token, reg_syntax_t syntax, + reg_errcode_t *err); +static reg_errcode_t parse_bracket_element (bracket_elem_t *elem, + re_string_t *regexp, + re_token_t *token, int token_len, + re_dfa_t *dfa, + reg_syntax_t syntax, + bool accept_hyphen); +static reg_errcode_t parse_bracket_symbol (bracket_elem_t *elem, + re_string_t *regexp, + re_token_t *token); +#ifdef RE_ENABLE_I18N +static reg_errcode_t build_equiv_class (bitset_t sbcset, + re_charset_t *mbcset, + Idx *equiv_class_alloc, + const unsigned char *name); +static reg_errcode_t build_charclass (RE_TRANSLATE_TYPE trans, + bitset_t sbcset, + re_charset_t *mbcset, + Idx *char_class_alloc, + const unsigned char *class_name, + reg_syntax_t syntax); +#else /* not RE_ENABLE_I18N */ +static reg_errcode_t build_equiv_class (bitset_t sbcset, + const unsigned char *name); +static reg_errcode_t build_charclass (RE_TRANSLATE_TYPE trans, + bitset_t sbcset, + const unsigned char *class_name, + reg_syntax_t syntax); +#endif /* not RE_ENABLE_I18N */ +static bin_tree_t *build_charclass_op (re_dfa_t *dfa, + RE_TRANSLATE_TYPE trans, + const unsigned char *class_name, + const unsigned char *extra, + bool non_match, reg_errcode_t *err); +static bin_tree_t *create_tree (re_dfa_t *dfa, + bin_tree_t *left, bin_tree_t *right, + re_token_type_t type); +static bin_tree_t *create_token_tree (re_dfa_t *dfa, + bin_tree_t *left, bin_tree_t *right, + const re_token_t *token); +static bin_tree_t *duplicate_tree (const bin_tree_t *src, re_dfa_t *dfa); +static void free_token (re_token_t *node); +static reg_errcode_t free_tree (void *extra, bin_tree_t *node); +static reg_errcode_t mark_opt_subexp (void *extra, bin_tree_t *node); + +/* This table gives an error message for each of the error codes listed + in regex.h. Obviously the order here has to be same as there. + POSIX doesn't require that we do anything for REG_NOERROR, + but why not be nice? */ + +static const char __re_error_msgid[] = + { +#define REG_NOERROR_IDX 0 + gettext_noop ("Success") /* REG_NOERROR */ + "\0" +#define REG_NOMATCH_IDX (REG_NOERROR_IDX + sizeof "Success") + gettext_noop ("No match") /* REG_NOMATCH */ + "\0" +#define REG_BADPAT_IDX (REG_NOMATCH_IDX + sizeof "No match") + gettext_noop ("Invalid regular expression") /* REG_BADPAT */ + "\0" +#define REG_ECOLLATE_IDX (REG_BADPAT_IDX + sizeof "Invalid regular expression") + gettext_noop ("Invalid collation character") /* REG_ECOLLATE */ + "\0" +#define REG_ECTYPE_IDX (REG_ECOLLATE_IDX + sizeof "Invalid collation character") + gettext_noop ("Invalid character class name") /* REG_ECTYPE */ + "\0" +#define REG_EESCAPE_IDX (REG_ECTYPE_IDX + sizeof "Invalid character class name") + gettext_noop ("Trailing backslash") /* REG_EESCAPE */ + "\0" +#define REG_ESUBREG_IDX (REG_EESCAPE_IDX + sizeof "Trailing backslash") + gettext_noop ("Invalid back reference") /* REG_ESUBREG */ + "\0" +#define REG_EBRACK_IDX (REG_ESUBREG_IDX + sizeof "Invalid back reference") + gettext_noop ("Unmatched [ or [^") /* REG_EBRACK */ + "\0" +#define REG_EPAREN_IDX (REG_EBRACK_IDX + sizeof "Unmatched [ or [^") + gettext_noop ("Unmatched ( or \\(") /* REG_EPAREN */ + "\0" +#define REG_EBRACE_IDX (REG_EPAREN_IDX + sizeof "Unmatched ( or \\(") + gettext_noop ("Unmatched \\{") /* REG_EBRACE */ + "\0" +#define REG_BADBR_IDX (REG_EBRACE_IDX + sizeof "Unmatched \\{") + gettext_noop ("Invalid content of \\{\\}") /* REG_BADBR */ + "\0" +#define REG_ERANGE_IDX (REG_BADBR_IDX + sizeof "Invalid content of \\{\\}") + gettext_noop ("Invalid range end") /* REG_ERANGE */ + "\0" +#define REG_ESPACE_IDX (REG_ERANGE_IDX + sizeof "Invalid range end") + gettext_noop ("Memory exhausted") /* REG_ESPACE */ + "\0" +#define REG_BADRPT_IDX (REG_ESPACE_IDX + sizeof "Memory exhausted") + gettext_noop ("Invalid preceding regular expression") /* REG_BADRPT */ + "\0" +#define REG_EEND_IDX (REG_BADRPT_IDX + sizeof "Invalid preceding regular expression") + gettext_noop ("Premature end of regular expression") /* REG_EEND */ + "\0" +#define REG_ESIZE_IDX (REG_EEND_IDX + sizeof "Premature end of regular expression") + gettext_noop ("Regular expression too big") /* REG_ESIZE */ + "\0" +#define REG_ERPAREN_IDX (REG_ESIZE_IDX + sizeof "Regular expression too big") + gettext_noop ("Unmatched ) or \\)") /* REG_ERPAREN */ + }; + +static const size_t __re_error_msgid_idx[] = + { + REG_NOERROR_IDX, + REG_NOMATCH_IDX, + REG_BADPAT_IDX, + REG_ECOLLATE_IDX, + REG_ECTYPE_IDX, + REG_EESCAPE_IDX, + REG_ESUBREG_IDX, + REG_EBRACK_IDX, + REG_EPAREN_IDX, + REG_EBRACE_IDX, + REG_BADBR_IDX, + REG_ERANGE_IDX, + REG_ESPACE_IDX, + REG_BADRPT_IDX, + REG_EEND_IDX, + REG_ESIZE_IDX, + REG_ERPAREN_IDX + }; + +/* Entry points for GNU code. */ + +/* re_compile_pattern is the GNU regular expression compiler: it + compiles PATTERN (of length LENGTH) and puts the result in BUFP. + Returns 0 if the pattern was valid, otherwise an error string. + + Assumes the `allocated' (and perhaps `buffer') and `translate' fields + are set in BUFP on entry. */ + +#ifdef _LIBC +const char * +re_compile_pattern (pattern, length, bufp) + const char *pattern; + size_t length; + struct re_pattern_buffer *bufp; +#else /* size_t might promote */ +const char * +re_compile_pattern (const char *pattern, size_t length, + struct re_pattern_buffer *bufp) +#endif +{ + reg_errcode_t ret; + + /* And GNU code determines whether or not to get register information + by passing null for the REGS argument to re_match, etc., not by + setting no_sub, unless RE_NO_SUB is set. */ + bufp->no_sub = !!(re_syntax_options & RE_NO_SUB); + + /* Match anchors at newline. */ + bufp->newline_anchor = 1; + + ret = re_compile_internal (bufp, pattern, length, re_syntax_options); + + if (!ret) + return NULL; + return gettext (__re_error_msgid + __re_error_msgid_idx[(int) ret]); +} +#ifdef _LIBC +weak_alias (__re_compile_pattern, re_compile_pattern) +#endif + +/* Set by `re_set_syntax' to the current regexp syntax to recognize. Can + also be assigned to arbitrarily: each pattern buffer stores its own + syntax, so it can be changed between regex compilations. */ +/* This has no initializer because initialized variables in Emacs + become read-only after dumping. */ +reg_syntax_t re_syntax_options; + + +/* Specify the precise syntax of regexps for compilation. This provides + for compatibility for various utilities which historically have + different, incompatible syntaxes. + + The argument SYNTAX is a bit mask comprised of the various bits + defined in regex.h. We return the old syntax. */ + +reg_syntax_t +re_set_syntax (syntax) + reg_syntax_t syntax; +{ + reg_syntax_t ret = re_syntax_options; + + re_syntax_options = syntax; + return ret; +} +#ifdef _LIBC +weak_alias (__re_set_syntax, re_set_syntax) +#endif + +int +re_compile_fastmap (bufp) + struct re_pattern_buffer *bufp; +{ + re_dfa_t *dfa = (re_dfa_t *) bufp->buffer; + char *fastmap = bufp->fastmap; + + memset (fastmap, '\0', sizeof (char) * SBC_MAX); + re_compile_fastmap_iter (bufp, dfa->init_state, fastmap); + if (dfa->init_state != dfa->init_state_word) + re_compile_fastmap_iter (bufp, dfa->init_state_word, fastmap); + if (dfa->init_state != dfa->init_state_nl) + re_compile_fastmap_iter (bufp, dfa->init_state_nl, fastmap); + if (dfa->init_state != dfa->init_state_begbuf) + re_compile_fastmap_iter (bufp, dfa->init_state_begbuf, fastmap); + bufp->fastmap_accurate = 1; + return 0; +} +#ifdef _LIBC +weak_alias (__re_compile_fastmap, re_compile_fastmap) +#endif + +static inline void +__attribute ((always_inline)) +re_set_fastmap (char *fastmap, bool icase, int ch) +{ + fastmap[ch] = 1; + if (icase) + fastmap[tolower (ch)] = 1; +} + +/* Helper function for re_compile_fastmap. + Compile fastmap for the initial_state INIT_STATE. */ + +static void +re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state, + char *fastmap) +{ + re_dfa_t *dfa = (re_dfa_t *) bufp->buffer; + Idx node_cnt; + bool icase = (dfa->mb_cur_max == 1 && (bufp->syntax & RE_ICASE)); + for (node_cnt = 0; node_cnt < init_state->nodes.nelem; ++node_cnt) + { + Idx node = init_state->nodes.elems[node_cnt]; + re_token_type_t type = dfa->nodes[node].type; + + if (type == CHARACTER) + { + re_set_fastmap (fastmap, icase, dfa->nodes[node].opr.c); +#ifdef RE_ENABLE_I18N + if ((bufp->syntax & RE_ICASE) && dfa->mb_cur_max > 1) + { + unsigned char buf[MB_LEN_MAX]; + unsigned char *p; + wchar_t wc; + mbstate_t state; + + p = buf; + *p++ = dfa->nodes[node].opr.c; + while (++node < dfa->nodes_len + && dfa->nodes[node].type == CHARACTER + && dfa->nodes[node].mb_partial) + *p++ = dfa->nodes[node].opr.c; + memset (&state, '\0', sizeof (state)); + if (__mbrtowc (&wc, (const char *) buf, p - buf, + &state) == p - buf + && (__wcrtomb ((char *) buf, towlower (wc), &state) + != (size_t) -1)) + re_set_fastmap (fastmap, false, buf[0]); + } +#endif + } + else if (type == SIMPLE_BRACKET) + { + int i, ch; + for (i = 0, ch = 0; i < BITSET_WORDS; ++i) + { + int j; + bitset_word_t w = dfa->nodes[node].opr.sbcset[i]; + for (j = 0; j < BITSET_WORD_BITS; ++j, ++ch) + if (w & ((bitset_word_t) 1 << j)) + re_set_fastmap (fastmap, icase, ch); + } + } +#ifdef RE_ENABLE_I18N + else if (type == COMPLEX_BRACKET) + { + re_charset_t *cset = dfa->nodes[node].opr.mbcset; + Idx i; + +# ifdef _LIBC + /* See if we have to try all bytes which start multiple collation + elements. + e.g. In da_DK, we want to catch 'a' since "aa" is a valid + collation element, and don't catch 'b' since 'b' is + the only collation element which starts from 'b' (and + it is caught by SIMPLE_BRACKET). */ + if (_NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES) != 0 + && (cset->ncoll_syms || cset->nranges)) + { + const int32_t *table = (const int32_t *) + _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB); + for (i = 0; i < SBC_MAX; ++i) + if (table[i] < 0) + re_set_fastmap (fastmap, icase, i); + } +# endif /* _LIBC */ + + /* See if we have to start the match at all multibyte characters, + i.e. where we would not find an invalid sequence. This only + applies to multibyte character sets; for single byte character + sets, the SIMPLE_BRACKET again suffices. */ + if (dfa->mb_cur_max > 1 + && (cset->nchar_classes || cset->non_match +# ifdef _LIBC + || cset->nequiv_classes +# endif /* _LIBC */ + )) + { + unsigned char c = 0; + do + { + mbstate_t mbs; + memset (&mbs, 0, sizeof (mbs)); + if (__mbrtowc (NULL, (char *) &c, 1, &mbs) == (size_t) -2) + re_set_fastmap (fastmap, false, (int) c); + } + while (++c != 0); + } + + else + { + /* ... Else catch all bytes which can start the mbchars. */ + for (i = 0; i < cset->nmbchars; ++i) + { + char buf[256]; + mbstate_t state; + memset (&state, '\0', sizeof (state)); + if (__wcrtomb (buf, cset->mbchars[i], &state) != (size_t) -1) + re_set_fastmap (fastmap, icase, *(unsigned char *) buf); + if ((bufp->syntax & RE_ICASE) && dfa->mb_cur_max > 1) + { + if (__wcrtomb (buf, towlower (cset->mbchars[i]), &state) + != (size_t) -1) + re_set_fastmap (fastmap, false, *(unsigned char *) buf); + } + } + } + } +#endif /* RE_ENABLE_I18N */ + else if (type == OP_PERIOD +#ifdef RE_ENABLE_I18N + || type == OP_UTF8_PERIOD +#endif /* RE_ENABLE_I18N */ + || type == END_OF_RE) + { + memset (fastmap, '\1', sizeof (char) * SBC_MAX); + if (type == END_OF_RE) + bufp->can_be_null = 1; + return; + } + } +} + +/* Entry point for POSIX code. */ +/* regcomp takes a regular expression as a string and compiles it. + + PREG is a regex_t *. We do not expect any fields to be initialized, + since POSIX says we shouldn't. Thus, we set + + `buffer' to the compiled pattern; + `used' to the length of the compiled pattern; + `syntax' to RE_SYNTAX_POSIX_EXTENDED if the + REG_EXTENDED bit in CFLAGS is set; otherwise, to + RE_SYNTAX_POSIX_BASIC; + `newline_anchor' to REG_NEWLINE being set in CFLAGS; + `fastmap' to an allocated space for the fastmap; + `fastmap_accurate' to zero; + `re_nsub' to the number of subexpressions in PATTERN. + + PATTERN is the address of the pattern string. + + CFLAGS is a series of bits which affect compilation. + + If REG_EXTENDED is set, we use POSIX extended syntax; otherwise, we + use POSIX basic syntax. + + If REG_NEWLINE is set, then . and [^...] don't match newline. + Also, regexec will try a match beginning after every newline. + + If REG_ICASE is set, then we considers upper- and lowercase + versions of letters to be equivalent when matching. + + If REG_NOSUB is set, then when PREG is passed to regexec, that + routine will report only success or failure, and nothing about the + registers. + + It returns 0 if it succeeds, nonzero if it doesn't. (See regex.h for + the return codes and their meanings.) */ + +int +regcomp (preg, pattern, cflags) + regex_t *_Restrict_ preg; + const char *_Restrict_ pattern; + int cflags; +{ + reg_errcode_t ret; + reg_syntax_t syntax = ((cflags & REG_EXTENDED) ? RE_SYNTAX_POSIX_EXTENDED + : RE_SYNTAX_POSIX_BASIC); + + preg->buffer = NULL; + preg->allocated = 0; + preg->used = 0; + + /* Try to allocate space for the fastmap. */ + preg->fastmap = re_malloc (char, SBC_MAX); + if (BE (preg->fastmap == NULL, 0)) + return REG_ESPACE; + + syntax |= (cflags & REG_ICASE) ? RE_ICASE : 0; + + /* If REG_NEWLINE is set, newlines are treated differently. */ + if (cflags & REG_NEWLINE) + { /* REG_NEWLINE implies neither . nor [^...] match newline. */ + syntax &= ~RE_DOT_NEWLINE; + syntax |= RE_HAT_LISTS_NOT_NEWLINE; + /* It also changes the matching behavior. */ + preg->newline_anchor = 1; + } + else + preg->newline_anchor = 0; + preg->no_sub = !!(cflags & REG_NOSUB); + preg->translate = NULL; + + ret = re_compile_internal (preg, pattern, strlen (pattern), syntax); + + /* POSIX doesn't distinguish between an unmatched open-group and an + unmatched close-group: both are REG_EPAREN. */ + if (ret == REG_ERPAREN) + ret = REG_EPAREN; + + /* We have already checked preg->fastmap != NULL. */ + if (BE (ret == REG_NOERROR, 1)) + /* Compute the fastmap now, since regexec cannot modify the pattern + buffer. This function never fails in this implementation. */ + (void) re_compile_fastmap (preg); + else + { + /* Some error occurred while compiling the expression. */ + re_free (preg->fastmap); + preg->fastmap = NULL; + } + + return (int) ret; +} +#ifdef _LIBC +weak_alias (__regcomp, regcomp) +#endif + +/* Returns a message corresponding to an error code, ERRCODE, returned + from either regcomp or regexec. We don't use PREG here. */ + +#ifdef _LIBC +size_t +regerror (errcode, preg, errbuf, errbuf_size) + int errcode; + const regex_t *_Restrict_ preg; + char *_Restrict_ errbuf; + size_t errbuf_size; +#else /* size_t might promote */ +size_t +regerror (int errcode, const regex_t *_Restrict_ preg, + char *_Restrict_ errbuf, size_t errbuf_size) +#endif +{ + const char *msg; + size_t msg_size; + + if (BE (errcode < 0 + || errcode >= (int) (sizeof (__re_error_msgid_idx) + / sizeof (__re_error_msgid_idx[0])), 0)) + /* Only error codes returned by the rest of the code should be passed + to this routine. If we are given anything else, or if other regex + code generates an invalid error code, then the program has a bug. + Dump core so we can fix it. */ + abort (); + + msg = gettext (__re_error_msgid + __re_error_msgid_idx[errcode]); + + msg_size = strlen (msg) + 1; /* Includes the null. */ + + if (BE (errbuf_size != 0, 1)) + { + size_t cpy_size = msg_size; + if (BE (msg_size > errbuf_size, 0)) + { + cpy_size = errbuf_size - 1; + errbuf[cpy_size] = '\0'; + } + memcpy (errbuf, msg, cpy_size); + } + + return msg_size; +} +#ifdef _LIBC +weak_alias (__regerror, regerror) +#endif + + +#ifdef RE_ENABLE_I18N +/* This static array is used for the map to single-byte characters when + UTF-8 is used. Otherwise we would allocate memory just to initialize + it the same all the time. UTF-8 is the preferred encoding so this is + a worthwhile optimization. */ +static const bitset_t utf8_sb_map = +{ + /* Set the first 128 bits. */ +# if 4 * BITSET_WORD_BITS < ASCII_CHARS +# error "bitset_word_t is narrower than 32 bits" +# elif 3 * BITSET_WORD_BITS < ASCII_CHARS + BITSET_WORD_MAX, BITSET_WORD_MAX, BITSET_WORD_MAX, +# elif 2 * BITSET_WORD_BITS < ASCII_CHARS + BITSET_WORD_MAX, BITSET_WORD_MAX, +# elif 1 * BITSET_WORD_BITS < ASCII_CHARS + BITSET_WORD_MAX, +# endif + (BITSET_WORD_MAX + >> (SBC_MAX % BITSET_WORD_BITS == 0 + ? 0 + : BITSET_WORD_BITS - SBC_MAX % BITSET_WORD_BITS)) +}; +#endif + + +static void +free_dfa_content (re_dfa_t *dfa) +{ + Idx i, j; + + if (dfa->nodes) + for (i = 0; i < dfa->nodes_len; ++i) + free_token (dfa->nodes + i); + re_free (dfa->nexts); + for (i = 0; i < dfa->nodes_len; ++i) + { + if (dfa->eclosures != NULL) + re_node_set_free (dfa->eclosures + i); + if (dfa->inveclosures != NULL) + re_node_set_free (dfa->inveclosures + i); + if (dfa->edests != NULL) + re_node_set_free (dfa->edests + i); + } + re_free (dfa->edests); + re_free (dfa->eclosures); + re_free (dfa->inveclosures); + re_free (dfa->nodes); + + if (dfa->state_table) + for (i = 0; i <= dfa->state_hash_mask; ++i) + { + struct re_state_table_entry *entry = dfa->state_table + i; + for (j = 0; j < entry->num; ++j) + { + re_dfastate_t *state = entry->array[j]; + free_state (state); + } + re_free (entry->array); + } + re_free (dfa->state_table); +#ifdef RE_ENABLE_I18N + if (dfa->sb_char != utf8_sb_map) + re_free (dfa->sb_char); +#endif + re_free (dfa->subexp_map); +#ifdef DEBUG + re_free (dfa->re_str); +#endif + + re_free (dfa); +} + + +/* Free dynamically allocated space used by PREG. */ + +void +regfree (preg) + regex_t *preg; +{ + re_dfa_t *dfa = (re_dfa_t *) preg->buffer; + if (BE (dfa != NULL, 1)) + free_dfa_content (dfa); + preg->buffer = NULL; + preg->allocated = 0; + + re_free (preg->fastmap); + preg->fastmap = NULL; + + re_free (preg->translate); + preg->translate = NULL; +} +#ifdef _LIBC +weak_alias (__regfree, regfree) +#endif + +/* Entry points compatible with 4.2 BSD regex library. We don't define + them unless specifically requested. */ + +#if defined _REGEX_RE_COMP || defined _LIBC + +/* BSD has one and only one pattern buffer. */ +static struct re_pattern_buffer re_comp_buf; + +char * +# ifdef _LIBC +/* Make these definitions weak in libc, so POSIX programs can redefine + these names if they don't use our functions, and still use + regcomp/regexec above without link errors. */ +weak_function +# endif +re_comp (s) + const char *s; +{ + reg_errcode_t ret; + char *fastmap; + + if (!s) + { + if (!re_comp_buf.buffer) + return gettext ("No previous regular expression"); + return 0; + } + + if (re_comp_buf.buffer) + { + fastmap = re_comp_buf.fastmap; + re_comp_buf.fastmap = NULL; + __regfree (&re_comp_buf); + memset (&re_comp_buf, '\0', sizeof (re_comp_buf)); + re_comp_buf.fastmap = fastmap; + } + + if (re_comp_buf.fastmap == NULL) + { + re_comp_buf.fastmap = (char *) malloc (SBC_MAX); + if (re_comp_buf.fastmap == NULL) + return (char *) gettext (__re_error_msgid + + __re_error_msgid_idx[(int) REG_ESPACE]); + } + + /* Since `re_exec' always passes NULL for the `regs' argument, we + don't need to initialize the pattern buffer fields which affect it. */ + + /* Match anchors at newlines. */ + re_comp_buf.newline_anchor = 1; + + ret = re_compile_internal (&re_comp_buf, s, strlen (s), re_syntax_options); + + if (!ret) + return NULL; + + /* Yes, we're discarding `const' here if !HAVE_LIBINTL. */ + return (char *) gettext (__re_error_msgid + __re_error_msgid_idx[(int) ret]); +} + +#ifdef _LIBC +libc_freeres_fn (free_mem) +{ + __regfree (&re_comp_buf); +} +#endif + +#endif /* _REGEX_RE_COMP */ + +/* Internal entry point. + Compile the regular expression PATTERN, whose length is LENGTH. + SYNTAX indicate regular expression's syntax. */ + +static reg_errcode_t +re_compile_internal (regex_t *preg, const char * pattern, size_t length, + reg_syntax_t syntax) +{ + reg_errcode_t err = REG_NOERROR; + re_dfa_t *dfa; + re_string_t regexp; + + /* Initialize the pattern buffer. */ + preg->fastmap_accurate = 0; + preg->syntax = syntax; + preg->not_bol = preg->not_eol = 0; + preg->used = 0; + preg->re_nsub = 0; + preg->can_be_null = 0; + preg->regs_allocated = REGS_UNALLOCATED; + + /* Initialize the dfa. */ + dfa = (re_dfa_t *) preg->buffer; + if (BE (preg->allocated < sizeof (re_dfa_t), 0)) + { + /* If zero allocated, but buffer is non-null, try to realloc + enough space. This loses if buffer's address is bogus, but + that is the user's responsibility. If ->buffer is NULL this + is a simple allocation. */ + dfa = re_realloc (preg->buffer, re_dfa_t, 1); + if (dfa == NULL) + return REG_ESPACE; + preg->allocated = sizeof (re_dfa_t); + preg->buffer = (unsigned char *) dfa; + } + preg->used = sizeof (re_dfa_t); + + err = init_dfa (dfa, length); + if (BE (err != REG_NOERROR, 0)) + { + free_dfa_content (dfa); + preg->buffer = NULL; + preg->allocated = 0; + return err; + } +#ifdef DEBUG + /* Note: length+1 will not overflow since it is checked in init_dfa. */ + dfa->re_str = re_malloc (char, length + 1); + strncpy (dfa->re_str, pattern, length + 1); +#endif + + __libc_lock_init (dfa->lock); + + err = re_string_construct (®exp, pattern, length, preg->translate, + (syntax & RE_ICASE) != 0, dfa); + if (BE (err != REG_NOERROR, 0)) + { + re_compile_internal_free_return: + free_workarea_compile (preg); + re_string_destruct (®exp); + free_dfa_content (dfa); + preg->buffer = NULL; + preg->allocated = 0; + return err; + } + + /* Parse the regular expression, and build a structure tree. */ + preg->re_nsub = 0; + dfa->str_tree = parse (®exp, preg, syntax, &err); + if (BE (dfa->str_tree == NULL, 0)) + goto re_compile_internal_free_return; + + /* Analyze the tree and create the nfa. */ + err = analyze (preg); + if (BE (err != REG_NOERROR, 0)) + goto re_compile_internal_free_return; + +#ifdef RE_ENABLE_I18N + /* If possible, do searching in single byte encoding to speed things up. */ + if (dfa->is_utf8 && !(syntax & RE_ICASE) && preg->translate == NULL) + optimize_utf8 (dfa); +#endif + + /* Then create the initial state of the dfa. */ + err = create_initial_state (dfa); + + /* Release work areas. */ + free_workarea_compile (preg); + re_string_destruct (®exp); + + if (BE (err != REG_NOERROR, 0)) + { + free_dfa_content (dfa); + preg->buffer = NULL; + preg->allocated = 0; + } + + return err; +} + +/* Initialize DFA. We use the length of the regular expression PAT_LEN + as the initial length of some arrays. */ + +static reg_errcode_t +init_dfa (re_dfa_t *dfa, size_t pat_len) +{ + __re_size_t table_size; +#ifdef RE_ENABLE_I18N + size_t max_i18n_object_size = MAX (sizeof (wchar_t), sizeof (wctype_t)); +#else + size_t max_i18n_object_size = 0; +#endif + size_t max_object_size = + MAX (sizeof (struct re_state_table_entry), + MAX (sizeof (re_token_t), + MAX (sizeof (re_node_set), + MAX (sizeof (regmatch_t), + max_i18n_object_size)))); + + memset (dfa, '\0', sizeof (re_dfa_t)); + + /* Force allocation of str_tree_storage the first time. */ + dfa->str_tree_storage_idx = BIN_TREE_STORAGE_SIZE; + + /* Avoid overflows. The extra "/ 2" is for the table_size doubling + calculation below, and for similar doubling calculations + elsewhere. And it's <= rather than <, because some of the + doubling calculations add 1 afterwards. */ + if (BE (SIZE_MAX / max_object_size / 2 <= pat_len, 0)) + return REG_ESPACE; + + dfa->nodes_alloc = pat_len + 1; + dfa->nodes = re_malloc (re_token_t, dfa->nodes_alloc); + + /* table_size = 2 ^ ceil(log pat_len) */ + for (table_size = 1; ; table_size <<= 1) + if (table_size > pat_len) + break; + + dfa->state_table = calloc (sizeof (struct re_state_table_entry), table_size); + dfa->state_hash_mask = table_size - 1; + + dfa->mb_cur_max = MB_CUR_MAX; +#ifdef _LIBC + if (dfa->mb_cur_max == 6 + && strcmp (_NL_CURRENT (LC_CTYPE, _NL_CTYPE_CODESET_NAME), "UTF-8") == 0) + dfa->is_utf8 = 1; + dfa->map_notascii = (_NL_CURRENT_WORD (LC_CTYPE, _NL_CTYPE_MAP_TO_NONASCII) + != 0); +#else + if (strcmp (locale_charset (), "UTF-8") == 0) + dfa->is_utf8 = 1; + + /* We check exhaustively in the loop below if this charset is a + superset of ASCII. */ + dfa->map_notascii = 0; +#endif + +#ifdef RE_ENABLE_I18N + if (dfa->mb_cur_max > 1) + { + if (dfa->is_utf8) + dfa->sb_char = (re_bitset_ptr_t) utf8_sb_map; + else + { + int i, j, ch; + + dfa->sb_char = (re_bitset_ptr_t) calloc (sizeof (bitset_t), 1); + if (BE (dfa->sb_char == NULL, 0)) + return REG_ESPACE; + + /* Set the bits corresponding to single byte chars. */ + for (i = 0, ch = 0; i < BITSET_WORDS; ++i) + for (j = 0; j < BITSET_WORD_BITS; ++j, ++ch) + { + wint_t wch = __btowc (ch); + if (wch != WEOF) + dfa->sb_char[i] |= (bitset_word_t) 1 << j; +# ifndef _LIBC + if (isascii (ch) && wch != ch) + dfa->map_notascii = 1; +# endif + } + } + } +#endif + + if (BE (dfa->nodes == NULL || dfa->state_table == NULL, 0)) + return REG_ESPACE; + return REG_NOERROR; +} + +/* Initialize WORD_CHAR table, which indicate which character is + "word". In this case "word" means that it is the word construction + character used by some operators like "\<", "\>", etc. */ + +static void +internal_function +init_word_char (re_dfa_t *dfa) +{ + int i, j, ch; + dfa->word_ops_used = 1; + for (i = 0, ch = 0; i < BITSET_WORDS; ++i) + for (j = 0; j < BITSET_WORD_BITS; ++j, ++ch) + if (isalnum (ch) || ch == '_') + dfa->word_char[i] |= (bitset_word_t) 1 << j; +} + +/* Free the work area which are only used while compiling. */ + +static void +free_workarea_compile (regex_t *preg) +{ + re_dfa_t *dfa = (re_dfa_t *) preg->buffer; + bin_tree_storage_t *storage, *next; + for (storage = dfa->str_tree_storage; storage; storage = next) + { + next = storage->next; + re_free (storage); + } + dfa->str_tree_storage = NULL; + dfa->str_tree_storage_idx = BIN_TREE_STORAGE_SIZE; + dfa->str_tree = NULL; + re_free (dfa->org_indices); + dfa->org_indices = NULL; +} + +/* Create initial states for all contexts. */ + +static reg_errcode_t +create_initial_state (re_dfa_t *dfa) +{ + Idx first, i; + reg_errcode_t err; + re_node_set init_nodes; + + /* Initial states have the epsilon closure of the node which is + the first node of the regular expression. */ + first = dfa->str_tree->first->node_idx; + dfa->init_node = first; + err = re_node_set_init_copy (&init_nodes, dfa->eclosures + first); + if (BE (err != REG_NOERROR, 0)) + return err; + + /* The back-references which are in initial states can epsilon transit, + since in this case all of the subexpressions can be null. + Then we add epsilon closures of the nodes which are the next nodes of + the back-references. */ + if (dfa->nbackref > 0) + for (i = 0; i < init_nodes.nelem; ++i) + { + Idx node_idx = init_nodes.elems[i]; + re_token_type_t type = dfa->nodes[node_idx].type; + + Idx clexp_idx; + if (type != OP_BACK_REF) + continue; + for (clexp_idx = 0; clexp_idx < init_nodes.nelem; ++clexp_idx) + { + re_token_t *clexp_node; + clexp_node = dfa->nodes + init_nodes.elems[clexp_idx]; + if (clexp_node->type == OP_CLOSE_SUBEXP + && clexp_node->opr.idx == dfa->nodes[node_idx].opr.idx) + break; + } + if (clexp_idx == init_nodes.nelem) + continue; + + if (type == OP_BACK_REF) + { + Idx dest_idx = dfa->edests[node_idx].elems[0]; + if (!re_node_set_contains (&init_nodes, dest_idx)) + { + re_node_set_merge (&init_nodes, dfa->eclosures + dest_idx); + i = 0; + } + } + } + + /* It must be the first time to invoke acquire_state. */ + dfa->init_state = re_acquire_state_context (&err, dfa, &init_nodes, 0); + /* We don't check ERR here, since the initial state must not be NULL. */ + if (BE (dfa->init_state == NULL, 0)) + return err; + if (dfa->init_state->has_constraint) + { + dfa->init_state_word = re_acquire_state_context (&err, dfa, &init_nodes, + CONTEXT_WORD); + dfa->init_state_nl = re_acquire_state_context (&err, dfa, &init_nodes, + CONTEXT_NEWLINE); + dfa->init_state_begbuf = re_acquire_state_context (&err, dfa, + &init_nodes, + CONTEXT_NEWLINE + | CONTEXT_BEGBUF); + if (BE (dfa->init_state_word == NULL || dfa->init_state_nl == NULL + || dfa->init_state_begbuf == NULL, 0)) + return err; + } + else + dfa->init_state_word = dfa->init_state_nl + = dfa->init_state_begbuf = dfa->init_state; + + re_node_set_free (&init_nodes); + return REG_NOERROR; +} + +#ifdef RE_ENABLE_I18N +/* If it is possible to do searching in single byte encoding instead of UTF-8 + to speed things up, set dfa->mb_cur_max to 1, clear is_utf8 and change + DFA nodes where needed. */ + +static void +optimize_utf8 (re_dfa_t *dfa) +{ + Idx node; + int i; + bool mb_chars = false; + bool has_period = false; + + for (node = 0; node < dfa->nodes_len; ++node) + switch (dfa->nodes[node].type) + { + case CHARACTER: + if (dfa->nodes[node].opr.c >= ASCII_CHARS) + mb_chars = true; + break; + case ANCHOR: + switch (dfa->nodes[node].opr.ctx_type) + { + case LINE_FIRST: + case LINE_LAST: + case BUF_FIRST: + case BUF_LAST: + break; + default: + /* Word anchors etc. cannot be handled. It's okay to test + opr.ctx_type since constraints (for all DFA nodes) are + created by ORing one or more opr.ctx_type values. */ + return; + } + break; + case OP_PERIOD: + has_period = true; + break; + case OP_BACK_REF: + case OP_ALT: + case END_OF_RE: + case OP_DUP_ASTERISK: + case OP_OPEN_SUBEXP: + case OP_CLOSE_SUBEXP: + break; + case COMPLEX_BRACKET: + return; + case SIMPLE_BRACKET: + /* Just double check. */ + { + int rshift = (ASCII_CHARS % BITSET_WORD_BITS == 0 + ? 0 + : BITSET_WORD_BITS - ASCII_CHARS % BITSET_WORD_BITS); + for (i = ASCII_CHARS / BITSET_WORD_BITS; i < BITSET_WORDS; ++i) + { + if (dfa->nodes[node].opr.sbcset[i] >> rshift != 0) + return; + rshift = 0; + } + } + break; + default: + abort (); + } + + if (mb_chars || has_period) + for (node = 0; node < dfa->nodes_len; ++node) + { + if (dfa->nodes[node].type == CHARACTER + && dfa->nodes[node].opr.c >= ASCII_CHARS) + dfa->nodes[node].mb_partial = 0; + else if (dfa->nodes[node].type == OP_PERIOD) + dfa->nodes[node].type = OP_UTF8_PERIOD; + } + + /* The search can be in single byte locale. */ + dfa->mb_cur_max = 1; + dfa->is_utf8 = 0; + dfa->has_mb_node = dfa->nbackref > 0 || has_period; +} +#endif + +/* Analyze the structure tree, and calculate "first", "next", "edest", + "eclosure", and "inveclosure". */ + +static reg_errcode_t +analyze (regex_t *preg) +{ + re_dfa_t *dfa = (re_dfa_t *) preg->buffer; + reg_errcode_t ret; + + /* Allocate arrays. */ + dfa->nexts = re_malloc (Idx, dfa->nodes_alloc); + dfa->org_indices = re_malloc (Idx, dfa->nodes_alloc); + dfa->edests = re_malloc (re_node_set, dfa->nodes_alloc); + dfa->eclosures = re_malloc (re_node_set, dfa->nodes_alloc); + if (BE (dfa->nexts == NULL || dfa->org_indices == NULL || dfa->edests == NULL + || dfa->eclosures == NULL, 0)) + return REG_ESPACE; + + dfa->subexp_map = re_malloc (Idx, preg->re_nsub); + if (dfa->subexp_map != NULL) + { + Idx i; + for (i = 0; i < preg->re_nsub; i++) + dfa->subexp_map[i] = i; + preorder (dfa->str_tree, optimize_subexps, dfa); + for (i = 0; i < preg->re_nsub; i++) + if (dfa->subexp_map[i] != i) + break; + if (i == preg->re_nsub) + { + free (dfa->subexp_map); + dfa->subexp_map = NULL; + } + } + + ret = postorder (dfa->str_tree, lower_subexps, preg); + if (BE (ret != REG_NOERROR, 0)) + return ret; + ret = postorder (dfa->str_tree, calc_first, dfa); + if (BE (ret != REG_NOERROR, 0)) + return ret; + preorder (dfa->str_tree, calc_next, dfa); + ret = preorder (dfa->str_tree, link_nfa_nodes, dfa); + if (BE (ret != REG_NOERROR, 0)) + return ret; + ret = calc_eclosure (dfa); + if (BE (ret != REG_NOERROR, 0)) + return ret; + + /* We only need this during the prune_impossible_nodes pass in regexec.c; + skip it if p_i_n will not run, as calc_inveclosure can be quadratic. */ + if ((!preg->no_sub && preg->re_nsub > 0 && dfa->has_plural_match) + || dfa->nbackref) + { + dfa->inveclosures = re_malloc (re_node_set, dfa->nodes_len); + if (BE (dfa->inveclosures == NULL, 0)) + return REG_ESPACE; + ret = calc_inveclosure (dfa); + } + + return ret; +} + +/* Our parse trees are very unbalanced, so we cannot use a stack to + implement parse tree visits. Instead, we use parent pointers and + some hairy code in these two functions. */ +static reg_errcode_t +postorder (bin_tree_t *root, reg_errcode_t (fn (void *, bin_tree_t *)), + void *extra) +{ + bin_tree_t *node, *prev; + + for (node = root; ; ) + { + /* Descend down the tree, preferably to the left (or to the right + if that's the only child). */ + while (node->left || node->right) + if (node->left) + node = node->left; + else + node = node->right; + + do + { + reg_errcode_t err = fn (extra, node); + if (BE (err != REG_NOERROR, 0)) + return err; + if (node->parent == NULL) + return REG_NOERROR; + prev = node; + node = node->parent; + } + /* Go up while we have a node that is reached from the right. */ + while (node->right == prev || node->right == NULL); + node = node->right; + } +} + +static reg_errcode_t +preorder (bin_tree_t *root, reg_errcode_t (fn (void *, bin_tree_t *)), + void *extra) +{ + bin_tree_t *node; + + for (node = root; ; ) + { + reg_errcode_t err = fn (extra, node); + if (BE (err != REG_NOERROR, 0)) + return err; + + /* Go to the left node, or up and to the right. */ + if (node->left) + node = node->left; + else + { + bin_tree_t *prev = NULL; + while (node->right == prev || node->right == NULL) + { + prev = node; + node = node->parent; + if (!node) + return REG_NOERROR; + } + node = node->right; + } + } +} + +/* Optimization pass: if a SUBEXP is entirely contained, strip it and tell + re_search_internal to map the inner one's opr.idx to this one's. Adjust + backreferences as well. Requires a preorder visit. */ +static reg_errcode_t +optimize_subexps (void *extra, bin_tree_t *node) +{ + re_dfa_t *dfa = (re_dfa_t *) extra; + + if (node->token.type == OP_BACK_REF && dfa->subexp_map) + { + int idx = node->token.opr.idx; + node->token.opr.idx = dfa->subexp_map[idx]; + dfa->used_bkref_map |= 1 << node->token.opr.idx; + } + + else if (node->token.type == SUBEXP + && node->left && node->left->token.type == SUBEXP) + { + Idx other_idx = node->left->token.opr.idx; + + node->left = node->left->left; + if (node->left) + node->left->parent = node; + + dfa->subexp_map[other_idx] = dfa->subexp_map[node->token.opr.idx]; + if (other_idx < BITSET_WORD_BITS) + dfa->used_bkref_map &= ~((bitset_word_t) 1 << other_idx); + } + + return REG_NOERROR; +} + +/* Lowering pass: Turn each SUBEXP node into the appropriate concatenation + of OP_OPEN_SUBEXP, the body of the SUBEXP (if any) and OP_CLOSE_SUBEXP. */ +static reg_errcode_t +lower_subexps (void *extra, bin_tree_t *node) +{ + regex_t *preg = (regex_t *) extra; + reg_errcode_t err = REG_NOERROR; + + if (node->left && node->left->token.type == SUBEXP) + { + node->left = lower_subexp (&err, preg, node->left); + if (node->left) + node->left->parent = node; + } + if (node->right && node->right->token.type == SUBEXP) + { + node->right = lower_subexp (&err, preg, node->right); + if (node->right) + node->right->parent = node; + } + + return err; +} + +static bin_tree_t * +lower_subexp (reg_errcode_t *err, regex_t *preg, bin_tree_t *node) +{ + re_dfa_t *dfa = (re_dfa_t *) preg->buffer; + bin_tree_t *body = node->left; + bin_tree_t *op, *cls, *tree1, *tree; + + if (preg->no_sub + /* We do not optimize empty subexpressions, because otherwise we may + have bad CONCAT nodes with NULL children. This is obviously not + very common, so we do not lose much. An example that triggers + this case is the sed "script" /\(\)/x. */ + && node->left != NULL + && (node->token.opr.idx >= BITSET_WORD_BITS + || !(dfa->used_bkref_map + & ((bitset_word_t) 1 << node->token.opr.idx)))) + return node->left; + + /* Convert the SUBEXP node to the concatenation of an + OP_OPEN_SUBEXP, the contents, and an OP_CLOSE_SUBEXP. */ + op = create_tree (dfa, NULL, NULL, OP_OPEN_SUBEXP); + cls = create_tree (dfa, NULL, NULL, OP_CLOSE_SUBEXP); + tree1 = body ? create_tree (dfa, body, cls, CONCAT) : cls; + tree = create_tree (dfa, op, tree1, CONCAT); + if (BE (tree == NULL || tree1 == NULL || op == NULL || cls == NULL, 0)) + { + *err = REG_ESPACE; + return NULL; + } + + op->token.opr.idx = cls->token.opr.idx = node->token.opr.idx; + op->token.opt_subexp = cls->token.opt_subexp = node->token.opt_subexp; + return tree; +} + +/* Pass 1 in building the NFA: compute FIRST and create unlinked automaton + nodes. Requires a postorder visit. */ +static reg_errcode_t +calc_first (void *extra, bin_tree_t *node) +{ + re_dfa_t *dfa = (re_dfa_t *) extra; + if (node->token.type == CONCAT) + { + node->first = node->left->first; + node->node_idx = node->left->node_idx; + } + else + { + node->first = node; + node->node_idx = re_dfa_add_node (dfa, node->token); + if (BE (node->node_idx == REG_MISSING, 0)) + return REG_ESPACE; + if (node->token.type == ANCHOR) + dfa->nodes[node->node_idx].constraint = node->token.opr.ctx_type; + } + return REG_NOERROR; +} + +/* Pass 2: compute NEXT on the tree. Preorder visit. */ +static reg_errcode_t +calc_next (void *extra, bin_tree_t *node) +{ + switch (node->token.type) + { + case OP_DUP_ASTERISK: + node->left->next = node; + break; + case CONCAT: + node->left->next = node->right->first; + node->right->next = node->next; + break; + default: + if (node->left) + node->left->next = node->next; + if (node->right) + node->right->next = node->next; + break; + } + return REG_NOERROR; +} + +/* Pass 3: link all DFA nodes to their NEXT node (any order will do). */ +static reg_errcode_t +link_nfa_nodes (void *extra, bin_tree_t *node) +{ + re_dfa_t *dfa = (re_dfa_t *) extra; + Idx idx = node->node_idx; + reg_errcode_t err = REG_NOERROR; + + switch (node->token.type) + { + case CONCAT: + break; + + case END_OF_RE: + assert (node->next == NULL); + break; + + case OP_DUP_ASTERISK: + case OP_ALT: + { + Idx left, right; + dfa->has_plural_match = 1; + if (node->left != NULL) + left = node->left->first->node_idx; + else + left = node->next->node_idx; + if (node->right != NULL) + right = node->right->first->node_idx; + else + right = node->next->node_idx; + assert (REG_VALID_INDEX (left)); + assert (REG_VALID_INDEX (right)); + err = re_node_set_init_2 (dfa->edests + idx, left, right); + } + break; + + case ANCHOR: + case OP_OPEN_SUBEXP: + case OP_CLOSE_SUBEXP: + err = re_node_set_init_1 (dfa->edests + idx, node->next->node_idx); + break; + + case OP_BACK_REF: + dfa->nexts[idx] = node->next->node_idx; + if (node->token.type == OP_BACK_REF) + re_node_set_init_1 (dfa->edests + idx, dfa->nexts[idx]); + break; + + default: + assert (!IS_EPSILON_NODE (node->token.type)); + dfa->nexts[idx] = node->next->node_idx; + break; + } + + return err; +} + +/* Duplicate the epsilon closure of the node ROOT_NODE. + Note that duplicated nodes have constraint INIT_CONSTRAINT in addition + to their own constraint. */ + +static reg_errcode_t +internal_function +duplicate_node_closure (re_dfa_t *dfa, Idx top_org_node, Idx top_clone_node, + Idx root_node, unsigned int init_constraint) +{ + Idx org_node, clone_node; + bool ok; + unsigned int constraint = init_constraint; + for (org_node = top_org_node, clone_node = top_clone_node;;) + { + Idx org_dest, clone_dest; + if (dfa->nodes[org_node].type == OP_BACK_REF) + { + /* If the back reference epsilon-transit, its destination must + also have the constraint. Then duplicate the epsilon closure + of the destination of the back reference, and store it in + edests of the back reference. */ + org_dest = dfa->nexts[org_node]; + re_node_set_empty (dfa->edests + clone_node); + clone_dest = duplicate_node (dfa, org_dest, constraint); + if (BE (clone_dest == REG_MISSING, 0)) + return REG_ESPACE; + dfa->nexts[clone_node] = dfa->nexts[org_node]; + ok = re_node_set_insert (dfa->edests + clone_node, clone_dest); + if (BE (! ok, 0)) + return REG_ESPACE; + } + else if (dfa->edests[org_node].nelem == 0) + { + /* In case of the node can't epsilon-transit, don't duplicate the + destination and store the original destination as the + destination of the node. */ + dfa->nexts[clone_node] = dfa->nexts[org_node]; + break; + } + else if (dfa->edests[org_node].nelem == 1) + { + /* In case of the node can epsilon-transit, and it has only one + destination. */ + org_dest = dfa->edests[org_node].elems[0]; + re_node_set_empty (dfa->edests + clone_node); + clone_dest = search_duplicated_node (dfa, org_dest, constraint); + /* If the node is root_node itself, it means the epsilon closure + has a loop. Then tie it to the destination of the root_node. */ + if (org_node == root_node && clone_node != org_node) + { + ok = re_node_set_insert (dfa->edests + clone_node, org_dest); + if (BE (! ok, 0)) + return REG_ESPACE; + break; + } + /* In case the node has another constraint, append it. */ + constraint |= dfa->nodes[org_node].constraint; + clone_dest = duplicate_node (dfa, org_dest, constraint); + if (BE (clone_dest == REG_MISSING, 0)) + return REG_ESPACE; + ok = re_node_set_insert (dfa->edests + clone_node, clone_dest); + if (BE (! ok, 0)) + return REG_ESPACE; + } + else /* dfa->edests[org_node].nelem == 2 */ + { + /* In case of the node can epsilon-transit, and it has two + destinations. In the bin_tree_t and DFA, that's '|' and '*'. */ + org_dest = dfa->edests[org_node].elems[0]; + re_node_set_empty (dfa->edests + clone_node); + /* Search for a duplicated node which satisfies the constraint. */ + clone_dest = search_duplicated_node (dfa, org_dest, constraint); + if (clone_dest == REG_MISSING) + { + /* There is no such duplicated node, create a new one. */ + reg_errcode_t err; + clone_dest = duplicate_node (dfa, org_dest, constraint); + if (BE (clone_dest == REG_MISSING, 0)) + return REG_ESPACE; + ok = re_node_set_insert (dfa->edests + clone_node, clone_dest); + if (BE (! ok, 0)) + return REG_ESPACE; + err = duplicate_node_closure (dfa, org_dest, clone_dest, + root_node, constraint); + if (BE (err != REG_NOERROR, 0)) + return err; + } + else + { + /* There is a duplicated node which satisfy the constraint, + use it to avoid infinite loop. */ + ok = re_node_set_insert (dfa->edests + clone_node, clone_dest); + if (BE (! ok, 0)) + return REG_ESPACE; + } + + org_dest = dfa->edests[org_node].elems[1]; + clone_dest = duplicate_node (dfa, org_dest, constraint); + if (BE (clone_dest == REG_MISSING, 0)) + return REG_ESPACE; + ok = re_node_set_insert (dfa->edests + clone_node, clone_dest); + if (BE (! ok, 0)) + return REG_ESPACE; + } + org_node = org_dest; + clone_node = clone_dest; + } + return REG_NOERROR; +} + +/* Search for a node which is duplicated from the node ORG_NODE, and + satisfies the constraint CONSTRAINT. */ + +static Idx +search_duplicated_node (const re_dfa_t *dfa, Idx org_node, + unsigned int constraint) +{ + Idx idx; + for (idx = dfa->nodes_len - 1; dfa->nodes[idx].duplicated && idx > 0; --idx) + { + if (org_node == dfa->org_indices[idx] + && constraint == dfa->nodes[idx].constraint) + return idx; /* Found. */ + } + return REG_MISSING; /* Not found. */ +} + +/* Duplicate the node whose index is ORG_IDX and set the constraint CONSTRAINT. + Return the index of the new node, or REG_MISSING if insufficient storage is + available. */ + +static Idx +duplicate_node (re_dfa_t *dfa, Idx org_idx, unsigned int constraint) +{ + Idx dup_idx = re_dfa_add_node (dfa, dfa->nodes[org_idx]); + if (BE (dup_idx != REG_MISSING, 1)) + { + dfa->nodes[dup_idx].constraint = constraint; + dfa->nodes[dup_idx].constraint |= dfa->nodes[org_idx].constraint; + dfa->nodes[dup_idx].duplicated = 1; + + /* Store the index of the original node. */ + dfa->org_indices[dup_idx] = org_idx; + } + return dup_idx; +} + +static reg_errcode_t +calc_inveclosure (re_dfa_t *dfa) +{ + Idx src, idx; + bool ok; + for (idx = 0; idx < dfa->nodes_len; ++idx) + re_node_set_init_empty (dfa->inveclosures + idx); + + for (src = 0; src < dfa->nodes_len; ++src) + { + Idx *elems = dfa->eclosures[src].elems; + for (idx = 0; idx < dfa->eclosures[src].nelem; ++idx) + { + ok = re_node_set_insert_last (dfa->inveclosures + elems[idx], src); + if (BE (! ok, 0)) + return REG_ESPACE; + } + } + + return REG_NOERROR; +} + +/* Calculate "eclosure" for all the node in DFA. */ + +static reg_errcode_t +calc_eclosure (re_dfa_t *dfa) +{ + Idx node_idx; + bool incomplete; +#ifdef DEBUG + assert (dfa->nodes_len > 0); +#endif + incomplete = false; + /* For each nodes, calculate epsilon closure. */ + for (node_idx = 0; ; ++node_idx) + { + reg_errcode_t err; + re_node_set eclosure_elem; + if (node_idx == dfa->nodes_len) + { + if (!incomplete) + break; + incomplete = false; + node_idx = 0; + } + +#ifdef DEBUG + assert (dfa->eclosures[node_idx].nelem != REG_MISSING); +#endif + + /* If we have already calculated, skip it. */ + if (dfa->eclosures[node_idx].nelem != 0) + continue; + /* Calculate epsilon closure of `node_idx'. */ + err = calc_eclosure_iter (&eclosure_elem, dfa, node_idx, true); + if (BE (err != REG_NOERROR, 0)) + return err; + + if (dfa->eclosures[node_idx].nelem == 0) + { + incomplete = true; + re_node_set_free (&eclosure_elem); + } + } + return REG_NOERROR; +} + +/* Calculate epsilon closure of NODE. */ + +static reg_errcode_t +calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa, Idx node, bool root) +{ + reg_errcode_t err; + Idx i; + bool incomplete; + bool ok; + re_node_set eclosure; + incomplete = false; + err = re_node_set_alloc (&eclosure, dfa->edests[node].nelem + 1); + if (BE (err != REG_NOERROR, 0)) + return err; + + /* This indicates that we are calculating this node now. + We reference this value to avoid infinite loop. */ + dfa->eclosures[node].nelem = REG_MISSING; + + /* If the current node has constraints, duplicate all nodes + since they must inherit the constraints. */ + if (dfa->nodes[node].constraint + && dfa->edests[node].nelem + && !dfa->nodes[dfa->edests[node].elems[0]].duplicated) + { + err = duplicate_node_closure (dfa, node, node, node, + dfa->nodes[node].constraint); + if (BE (err != REG_NOERROR, 0)) + return err; + } + + /* Expand each epsilon destination nodes. */ + if (IS_EPSILON_NODE(dfa->nodes[node].type)) + for (i = 0; i < dfa->edests[node].nelem; ++i) + { + re_node_set eclosure_elem; + Idx edest = dfa->edests[node].elems[i]; + /* If calculating the epsilon closure of `edest' is in progress, + return intermediate result. */ + if (dfa->eclosures[edest].nelem == REG_MISSING) + { + incomplete = true; + continue; + } + /* If we haven't calculated the epsilon closure of `edest' yet, + calculate now. Otherwise use calculated epsilon closure. */ + if (dfa->eclosures[edest].nelem == 0) + { + err = calc_eclosure_iter (&eclosure_elem, dfa, edest, false); + if (BE (err != REG_NOERROR, 0)) + return err; + } + else + eclosure_elem = dfa->eclosures[edest]; + /* Merge the epsilon closure of `edest'. */ + re_node_set_merge (&eclosure, &eclosure_elem); + /* If the epsilon closure of `edest' is incomplete, + the epsilon closure of this node is also incomplete. */ + if (dfa->eclosures[edest].nelem == 0) + { + incomplete = true; + re_node_set_free (&eclosure_elem); + } + } + + /* Epsilon closures include itself. */ + ok = re_node_set_insert (&eclosure, node); + if (BE (! ok, 0)) + return REG_ESPACE; + if (incomplete && !root) + dfa->eclosures[node].nelem = 0; + else + dfa->eclosures[node] = eclosure; + *new_set = eclosure; + return REG_NOERROR; +} + +/* Functions for token which are used in the parser. */ + +/* Fetch a token from INPUT. + We must not use this function inside bracket expressions. */ + +static void +internal_function +fetch_token (re_token_t *result, re_string_t *input, reg_syntax_t syntax) +{ + re_string_skip_bytes (input, peek_token (result, input, syntax)); +} + +/* Peek a token from INPUT, and return the length of the token. + We must not use this function inside bracket expressions. */ + +static int +internal_function +peek_token (re_token_t *token, re_string_t *input, reg_syntax_t syntax) +{ + unsigned char c; + + if (re_string_eoi (input)) + { + token->type = END_OF_RE; + return 0; + } + + c = re_string_peek_byte (input, 0); + token->opr.c = c; + + token->word_char = 0; +#ifdef RE_ENABLE_I18N + token->mb_partial = 0; + if (input->mb_cur_max > 1 && + !re_string_first_byte (input, re_string_cur_idx (input))) + { + token->type = CHARACTER; + token->mb_partial = 1; + return 1; + } +#endif + if (c == '\\') + { + unsigned char c2; + if (re_string_cur_idx (input) + 1 >= re_string_length (input)) + { + token->type = BACK_SLASH; + return 1; + } + + c2 = re_string_peek_byte_case (input, 1); + token->opr.c = c2; + token->type = CHARACTER; +#ifdef RE_ENABLE_I18N + if (input->mb_cur_max > 1) + { + wint_t wc = re_string_wchar_at (input, + re_string_cur_idx (input) + 1); + token->word_char = IS_WIDE_WORD_CHAR (wc) != 0; + } + else +#endif + token->word_char = IS_WORD_CHAR (c2) != 0; + + switch (c2) + { + case '|': + if (!(syntax & RE_LIMITED_OPS) && !(syntax & RE_NO_BK_VBAR)) + token->type = OP_ALT; + break; + case '1': case '2': case '3': case '4': case '5': + case '6': case '7': case '8': case '9': + if (!(syntax & RE_NO_BK_REFS)) + { + token->type = OP_BACK_REF; + token->opr.idx = c2 - '1'; + } + break; + case '<': + if (!(syntax & RE_NO_GNU_OPS)) + { + token->type = ANCHOR; + token->opr.ctx_type = WORD_FIRST; + } + break; + case '>': + if (!(syntax & RE_NO_GNU_OPS)) + { + token->type = ANCHOR; + token->opr.ctx_type = WORD_LAST; + } + break; + case 'b': + if (!(syntax & RE_NO_GNU_OPS)) + { + token->type = ANCHOR; + token->opr.ctx_type = WORD_DELIM; + } + break; + case 'B': + if (!(syntax & RE_NO_GNU_OPS)) + { + token->type = ANCHOR; + token->opr.ctx_type = NOT_WORD_DELIM; + } + break; + case 'w': + if (!(syntax & RE_NO_GNU_OPS)) + token->type = OP_WORD; + break; + case 'W': + if (!(syntax & RE_NO_GNU_OPS)) + token->type = OP_NOTWORD; + break; + case 's': + if (!(syntax & RE_NO_GNU_OPS)) + token->type = OP_SPACE; + break; + case 'S': + if (!(syntax & RE_NO_GNU_OPS)) + token->type = OP_NOTSPACE; + break; + case '`': + if (!(syntax & RE_NO_GNU_OPS)) + { + token->type = ANCHOR; + token->opr.ctx_type = BUF_FIRST; + } + break; + case '\'': + if (!(syntax & RE_NO_GNU_OPS)) + { + token->type = ANCHOR; + token->opr.ctx_type = BUF_LAST; + } + break; + case '(': + if (!(syntax & RE_NO_BK_PARENS)) + token->type = OP_OPEN_SUBEXP; + break; + case ')': + if (!(syntax & RE_NO_BK_PARENS)) + token->type = OP_CLOSE_SUBEXP; + break; + case '+': + if (!(syntax & RE_LIMITED_OPS) && (syntax & RE_BK_PLUS_QM)) + token->type = OP_DUP_PLUS; + break; + case '?': + if (!(syntax & RE_LIMITED_OPS) && (syntax & RE_BK_PLUS_QM)) + token->type = OP_DUP_QUESTION; + break; + case '{': + if ((syntax & RE_INTERVALS) && (!(syntax & RE_NO_BK_BRACES))) + token->type = OP_OPEN_DUP_NUM; + break; + case '}': + if ((syntax & RE_INTERVALS) && (!(syntax & RE_NO_BK_BRACES))) + token->type = OP_CLOSE_DUP_NUM; + break; + default: + break; + } + return 2; + } + + token->type = CHARACTER; +#ifdef RE_ENABLE_I18N + if (input->mb_cur_max > 1) + { + wint_t wc = re_string_wchar_at (input, re_string_cur_idx (input)); + token->word_char = IS_WIDE_WORD_CHAR (wc) != 0; + } + else +#endif + token->word_char = IS_WORD_CHAR (token->opr.c); + + switch (c) + { + case '\n': + if (syntax & RE_NEWLINE_ALT) + token->type = OP_ALT; + break; + case '|': + if (!(syntax & RE_LIMITED_OPS) && (syntax & RE_NO_BK_VBAR)) + token->type = OP_ALT; + break; + case '*': + token->type = OP_DUP_ASTERISK; + break; + case '+': + if (!(syntax & RE_LIMITED_OPS) && !(syntax & RE_BK_PLUS_QM)) + token->type = OP_DUP_PLUS; + break; + case '?': + if (!(syntax & RE_LIMITED_OPS) && !(syntax & RE_BK_PLUS_QM)) + token->type = OP_DUP_QUESTION; + break; + case '{': + if ((syntax & RE_INTERVALS) && (syntax & RE_NO_BK_BRACES)) + token->type = OP_OPEN_DUP_NUM; + break; + case '}': + if ((syntax & RE_INTERVALS) && (syntax & RE_NO_BK_BRACES)) + token->type = OP_CLOSE_DUP_NUM; + break; + case '(': + if (syntax & RE_NO_BK_PARENS) + token->type = OP_OPEN_SUBEXP; + break; + case ')': + if (syntax & RE_NO_BK_PARENS) + token->type = OP_CLOSE_SUBEXP; + break; + case '[': + token->type = OP_OPEN_BRACKET; + break; + case '.': + token->type = OP_PERIOD; + break; + case '^': + if (!(syntax & (RE_CONTEXT_INDEP_ANCHORS | RE_CARET_ANCHORS_HERE)) && + re_string_cur_idx (input) != 0) + { + char prev = re_string_peek_byte (input, -1); + if (!(syntax & RE_NEWLINE_ALT) || prev != '\n') + break; + } + token->type = ANCHOR; + token->opr.ctx_type = LINE_FIRST; + break; + case '$': + if (!(syntax & RE_CONTEXT_INDEP_ANCHORS) && + re_string_cur_idx (input) + 1 != re_string_length (input)) + { + re_token_t next; + re_string_skip_bytes (input, 1); + peek_token (&next, input, syntax); + re_string_skip_bytes (input, -1); + if (next.type != OP_ALT && next.type != OP_CLOSE_SUBEXP) + break; + } + token->type = ANCHOR; + token->opr.ctx_type = LINE_LAST; + break; + default: + break; + } + return 1; +} + +/* Peek a token from INPUT, and return the length of the token. + We must not use this function out of bracket expressions. */ + +static int +internal_function +peek_token_bracket (re_token_t *token, re_string_t *input, reg_syntax_t syntax) +{ + unsigned char c; + if (re_string_eoi (input)) + { + token->type = END_OF_RE; + return 0; + } + c = re_string_peek_byte (input, 0); + token->opr.c = c; + +#ifdef RE_ENABLE_I18N + if (input->mb_cur_max > 1 && + !re_string_first_byte (input, re_string_cur_idx (input))) + { + token->type = CHARACTER; + return 1; + } +#endif /* RE_ENABLE_I18N */ + + if (c == '\\' && (syntax & RE_BACKSLASH_ESCAPE_IN_LISTS) + && re_string_cur_idx (input) + 1 < re_string_length (input)) + { + /* In this case, '\' escape a character. */ + unsigned char c2; + re_string_skip_bytes (input, 1); + c2 = re_string_peek_byte (input, 0); + token->opr.c = c2; + token->type = CHARACTER; + return 1; + } + if (c == '[') /* '[' is a special char in a bracket exps. */ + { + unsigned char c2; + int token_len; + if (re_string_cur_idx (input) + 1 < re_string_length (input)) + c2 = re_string_peek_byte (input, 1); + else + c2 = 0; + token->opr.c = c2; + token_len = 2; + switch (c2) + { + case '.': + token->type = OP_OPEN_COLL_ELEM; + break; + case '=': + token->type = OP_OPEN_EQUIV_CLASS; + break; + case ':': + if (syntax & RE_CHAR_CLASSES) + { + token->type = OP_OPEN_CHAR_CLASS; + break; + } + /* else fall through. */ + default: + token->type = CHARACTER; + token->opr.c = c; + token_len = 1; + break; + } + return token_len; + } + switch (c) + { + case '-': + token->type = OP_CHARSET_RANGE; + break; + case ']': + token->type = OP_CLOSE_BRACKET; + break; + case '^': + token->type = OP_NON_MATCH_LIST; + break; + default: + token->type = CHARACTER; + } + return 1; +} + +/* Functions for parser. */ + +/* Entry point of the parser. + Parse the regular expression REGEXP and return the structure tree. + If an error is occured, ERR is set by error code, and return NULL. + This function build the following tree, from regular expression : + CAT + / \ + / \ + EOR + + CAT means concatenation. + EOR means end of regular expression. */ + +static bin_tree_t * +parse (re_string_t *regexp, regex_t *preg, reg_syntax_t syntax, + reg_errcode_t *err) +{ + re_dfa_t *dfa = (re_dfa_t *) preg->buffer; + bin_tree_t *tree, *eor, *root; + re_token_t current_token; + dfa->syntax = syntax; + fetch_token (¤t_token, regexp, syntax | RE_CARET_ANCHORS_HERE); + tree = parse_reg_exp (regexp, preg, ¤t_token, syntax, 0, err); + if (BE (*err != REG_NOERROR && tree == NULL, 0)) + return NULL; + eor = create_tree (dfa, NULL, NULL, END_OF_RE); + if (tree != NULL) + root = create_tree (dfa, tree, eor, CONCAT); + else + root = eor; + if (BE (eor == NULL || root == NULL, 0)) + { + *err = REG_ESPACE; + return NULL; + } + return root; +} + +/* This function build the following tree, from regular expression + |: + ALT + / \ + / \ + + + ALT means alternative, which represents the operator `|'. */ + +static bin_tree_t * +parse_reg_exp (re_string_t *regexp, regex_t *preg, re_token_t *token, + reg_syntax_t syntax, Idx nest, reg_errcode_t *err) +{ + re_dfa_t *dfa = (re_dfa_t *) preg->buffer; + bin_tree_t *tree, *branch = NULL; + tree = parse_branch (regexp, preg, token, syntax, nest, err); + if (BE (*err != REG_NOERROR && tree == NULL, 0)) + return NULL; + + while (token->type == OP_ALT) + { + fetch_token (token, regexp, syntax | RE_CARET_ANCHORS_HERE); + if (token->type != OP_ALT && token->type != END_OF_RE + && (nest == 0 || token->type != OP_CLOSE_SUBEXP)) + { + branch = parse_branch (regexp, preg, token, syntax, nest, err); + if (BE (*err != REG_NOERROR && branch == NULL, 0)) + return NULL; + } + else + branch = NULL; + tree = create_tree (dfa, tree, branch, OP_ALT); + if (BE (tree == NULL, 0)) + { + *err = REG_ESPACE; + return NULL; + } + } + return tree; +} + +/* This function build the following tree, from regular expression + : + CAT + / \ + / \ + + + CAT means concatenation. */ + +static bin_tree_t * +parse_branch (re_string_t *regexp, regex_t *preg, re_token_t *token, + reg_syntax_t syntax, Idx nest, reg_errcode_t *err) +{ + bin_tree_t *tree, *expr; + re_dfa_t *dfa = (re_dfa_t *) preg->buffer; + tree = parse_expression (regexp, preg, token, syntax, nest, err); + if (BE (*err != REG_NOERROR && tree == NULL, 0)) + return NULL; + + while (token->type != OP_ALT && token->type != END_OF_RE + && (nest == 0 || token->type != OP_CLOSE_SUBEXP)) + { + expr = parse_expression (regexp, preg, token, syntax, nest, err); + if (BE (*err != REG_NOERROR && expr == NULL, 0)) + { + return NULL; + } + if (tree != NULL && expr != NULL) + { + tree = create_tree (dfa, tree, expr, CONCAT); + if (tree == NULL) + { + *err = REG_ESPACE; + return NULL; + } + } + else if (tree == NULL) + tree = expr; + /* Otherwise expr == NULL, we don't need to create new tree. */ + } + return tree; +} + +/* This function build the following tree, from regular expression a*: + * + | + a +*/ + +static bin_tree_t * +parse_expression (re_string_t *regexp, regex_t *preg, re_token_t *token, + reg_syntax_t syntax, Idx nest, reg_errcode_t *err) +{ + re_dfa_t *dfa = (re_dfa_t *) preg->buffer; + bin_tree_t *tree; + switch (token->type) + { + case CHARACTER: + tree = create_token_tree (dfa, NULL, NULL, token); + if (BE (tree == NULL, 0)) + { + *err = REG_ESPACE; + return NULL; + } +#ifdef RE_ENABLE_I18N + if (dfa->mb_cur_max > 1) + { + while (!re_string_eoi (regexp) + && !re_string_first_byte (regexp, re_string_cur_idx (regexp))) + { + bin_tree_t *mbc_remain; + fetch_token (token, regexp, syntax); + mbc_remain = create_token_tree (dfa, NULL, NULL, token); + tree = create_tree (dfa, tree, mbc_remain, CONCAT); + if (BE (mbc_remain == NULL || tree == NULL, 0)) + { + *err = REG_ESPACE; + return NULL; + } + } + } +#endif + break; + case OP_OPEN_SUBEXP: + tree = parse_sub_exp (regexp, preg, token, syntax, nest + 1, err); + if (BE (*err != REG_NOERROR && tree == NULL, 0)) + return NULL; + break; + case OP_OPEN_BRACKET: + tree = parse_bracket_exp (regexp, dfa, token, syntax, err); + if (BE (*err != REG_NOERROR && tree == NULL, 0)) + return NULL; + break; + case OP_BACK_REF: + if (!BE (dfa->completed_bkref_map & (1 << token->opr.idx), 1)) + { + *err = REG_ESUBREG; + return NULL; + } + dfa->used_bkref_map |= 1 << token->opr.idx; + tree = create_token_tree (dfa, NULL, NULL, token); + if (BE (tree == NULL, 0)) + { + *err = REG_ESPACE; + return NULL; + } + ++dfa->nbackref; + dfa->has_mb_node = 1; + break; + case OP_OPEN_DUP_NUM: + if (syntax & RE_CONTEXT_INVALID_DUP) + { + *err = REG_BADRPT; + return NULL; + } + /* FALLTHROUGH */ + case OP_DUP_ASTERISK: + case OP_DUP_PLUS: + case OP_DUP_QUESTION: + if (syntax & RE_CONTEXT_INVALID_OPS) + { + *err = REG_BADRPT; + return NULL; + } + else if (syntax & RE_CONTEXT_INDEP_OPS) + { + fetch_token (token, regexp, syntax); + return parse_expression (regexp, preg, token, syntax, nest, err); + } + /* else fall through */ + case OP_CLOSE_SUBEXP: + if ((token->type == OP_CLOSE_SUBEXP) && + !(syntax & RE_UNMATCHED_RIGHT_PAREN_ORD)) + { + *err = REG_ERPAREN; + return NULL; + } + /* else fall through */ + case OP_CLOSE_DUP_NUM: + /* We treat it as a normal character. */ + + /* Then we can these characters as normal characters. */ + token->type = CHARACTER; + /* mb_partial and word_char bits should be initialized already + by peek_token. */ + tree = create_token_tree (dfa, NULL, NULL, token); + if (BE (tree == NULL, 0)) + { + *err = REG_ESPACE; + return NULL; + } + break; + case ANCHOR: + if ((token->opr.ctx_type + & (WORD_DELIM | NOT_WORD_DELIM | WORD_FIRST | WORD_LAST)) + && dfa->word_ops_used == 0) + init_word_char (dfa); + if (token->opr.ctx_type == WORD_DELIM + || token->opr.ctx_type == NOT_WORD_DELIM) + { + bin_tree_t *tree_first, *tree_last; + if (token->opr.ctx_type == WORD_DELIM) + { + token->opr.ctx_type = WORD_FIRST; + tree_first = create_token_tree (dfa, NULL, NULL, token); + token->opr.ctx_type = WORD_LAST; + } + else + { + token->opr.ctx_type = INSIDE_WORD; + tree_first = create_token_tree (dfa, NULL, NULL, token); + token->opr.ctx_type = INSIDE_NOTWORD; + } + tree_last = create_token_tree (dfa, NULL, NULL, token); + tree = create_tree (dfa, tree_first, tree_last, OP_ALT); + if (BE (tree_first == NULL || tree_last == NULL || tree == NULL, 0)) + { + *err = REG_ESPACE; + return NULL; + } + } + else + { + tree = create_token_tree (dfa, NULL, NULL, token); + if (BE (tree == NULL, 0)) + { + *err = REG_ESPACE; + return NULL; + } + } + /* We must return here, since ANCHORs can't be followed + by repetition operators. + eg. RE"^*" is invalid or "", + it must not be "". */ + fetch_token (token, regexp, syntax); + return tree; + case OP_PERIOD: + tree = create_token_tree (dfa, NULL, NULL, token); + if (BE (tree == NULL, 0)) + { + *err = REG_ESPACE; + return NULL; + } + if (dfa->mb_cur_max > 1) + dfa->has_mb_node = 1; + break; + case OP_WORD: + case OP_NOTWORD: + tree = build_charclass_op (dfa, regexp->trans, + (const unsigned char *) "alnum", + (const unsigned char *) "_", + token->type == OP_NOTWORD, err); + if (BE (*err != REG_NOERROR && tree == NULL, 0)) + return NULL; + break; + case OP_SPACE: + case OP_NOTSPACE: + tree = build_charclass_op (dfa, regexp->trans, + (const unsigned char *) "space", + (const unsigned char *) "", + token->type == OP_NOTSPACE, err); + if (BE (*err != REG_NOERROR && tree == NULL, 0)) + return NULL; + break; + case OP_ALT: + case END_OF_RE: + return NULL; + case BACK_SLASH: + *err = REG_EESCAPE; + return NULL; + default: + /* Must not happen? */ +#ifdef DEBUG + assert (0); +#endif + return NULL; + } + fetch_token (token, regexp, syntax); + + while (token->type == OP_DUP_ASTERISK || token->type == OP_DUP_PLUS + || token->type == OP_DUP_QUESTION || token->type == OP_OPEN_DUP_NUM) + { + tree = parse_dup_op (tree, regexp, dfa, token, syntax, err); + if (BE (*err != REG_NOERROR && tree == NULL, 0)) + return NULL; + /* In BRE consecutive duplications are not allowed. */ + if ((syntax & RE_CONTEXT_INVALID_DUP) + && (token->type == OP_DUP_ASTERISK + || token->type == OP_OPEN_DUP_NUM)) + { + *err = REG_BADRPT; + return NULL; + } + } + + return tree; +} + +/* This function build the following tree, from regular expression + (): + SUBEXP + | + +*/ + +static bin_tree_t * +parse_sub_exp (re_string_t *regexp, regex_t *preg, re_token_t *token, + reg_syntax_t syntax, Idx nest, reg_errcode_t *err) +{ + re_dfa_t *dfa = (re_dfa_t *) preg->buffer; + bin_tree_t *tree; + size_t cur_nsub; + cur_nsub = preg->re_nsub++; + + fetch_token (token, regexp, syntax | RE_CARET_ANCHORS_HERE); + + /* The subexpression may be a null string. */ + if (token->type == OP_CLOSE_SUBEXP) + tree = NULL; + else + { + tree = parse_reg_exp (regexp, preg, token, syntax, nest, err); + if (BE (*err == REG_NOERROR && token->type != OP_CLOSE_SUBEXP, 0)) + *err = REG_EPAREN; + if (BE (*err != REG_NOERROR, 0)) + return NULL; + } + + if (cur_nsub <= '9' - '1') + dfa->completed_bkref_map |= 1 << cur_nsub; + + tree = create_tree (dfa, tree, NULL, SUBEXP); + if (BE (tree == NULL, 0)) + { + *err = REG_ESPACE; + return NULL; + } + tree->token.opr.idx = cur_nsub; + return tree; +} + +/* This function parse repetition operators like "*", "+", "{1,3}" etc. */ + +static bin_tree_t * +parse_dup_op (bin_tree_t *elem, re_string_t *regexp, re_dfa_t *dfa, + re_token_t *token, reg_syntax_t syntax, reg_errcode_t *err) +{ + bin_tree_t *tree = NULL, *old_tree = NULL; + Idx i, start, end, start_idx = re_string_cur_idx (regexp); + re_token_t start_token = *token; + + if (token->type == OP_OPEN_DUP_NUM) + { + end = 0; + start = fetch_number (regexp, token, syntax); + if (start == REG_MISSING) + { + if (token->type == CHARACTER && token->opr.c == ',') + start = 0; /* We treat "{,m}" as "{0,m}". */ + else + { + *err = REG_BADBR; /* {} is invalid. */ + return NULL; + } + } + if (BE (start != REG_ERROR, 1)) + { + /* We treat "{n}" as "{n,n}". */ + end = ((token->type == OP_CLOSE_DUP_NUM) ? start + : ((token->type == CHARACTER && token->opr.c == ',') + ? fetch_number (regexp, token, syntax) : REG_ERROR)); + } + if (BE (start == REG_ERROR || end == REG_ERROR, 0)) + { + /* Invalid sequence. */ + if (BE (!(syntax & RE_INVALID_INTERVAL_ORD), 0)) + { + if (token->type == END_OF_RE) + *err = REG_EBRACE; + else + *err = REG_BADBR; + + return NULL; + } + + /* If the syntax bit is set, rollback. */ + re_string_set_index (regexp, start_idx); + *token = start_token; + token->type = CHARACTER; + /* mb_partial and word_char bits should be already initialized by + peek_token. */ + return elem; + } + + if (BE (end != REG_MISSING && start > end, 0)) + { + /* First number greater than second. */ + *err = REG_BADBR; + return NULL; + } + } + else + { + start = (token->type == OP_DUP_PLUS) ? 1 : 0; + end = (token->type == OP_DUP_QUESTION) ? 1 : REG_MISSING; + } + + fetch_token (token, regexp, syntax); + + if (BE (elem == NULL, 0)) + return NULL; + if (BE (start == 0 && end == 0, 0)) + { + postorder (elem, free_tree, NULL); + return NULL; + } + + /* Extract "{n,m}" to "...{0,}". */ + if (BE (start > 0, 0)) + { + tree = elem; + for (i = 2; i <= start; ++i) + { + elem = duplicate_tree (elem, dfa); + tree = create_tree (dfa, tree, elem, CONCAT); + if (BE (elem == NULL || tree == NULL, 0)) + goto parse_dup_op_espace; + } + + if (start == end) + return tree; + + /* Duplicate ELEM before it is marked optional. */ + elem = duplicate_tree (elem, dfa); + old_tree = tree; + } + else + old_tree = NULL; + + if (elem->token.type == SUBEXP) + postorder (elem, mark_opt_subexp, (void *) (long) elem->token.opr.idx); + + tree = create_tree (dfa, elem, NULL, + (end == REG_MISSING ? OP_DUP_ASTERISK : OP_ALT)); + if (BE (tree == NULL, 0)) + goto parse_dup_op_espace; + + /* This loop is actually executed only when end != REG_MISSING, + to rewrite {0,n} as ((...?)?)?... We have + already created the start+1-th copy. */ + if ((Idx) -1 < 0 || end != REG_MISSING) + for (i = start + 2; i <= end; ++i) + { + elem = duplicate_tree (elem, dfa); + tree = create_tree (dfa, tree, elem, CONCAT); + if (BE (elem == NULL || tree == NULL, 0)) + goto parse_dup_op_espace; + + tree = create_tree (dfa, tree, NULL, OP_ALT); + if (BE (tree == NULL, 0)) + goto parse_dup_op_espace; + } + + if (old_tree) + tree = create_tree (dfa, old_tree, tree, CONCAT); + + return tree; + + parse_dup_op_espace: + *err = REG_ESPACE; + return NULL; +} + +/* Size of the names for collating symbol/equivalence_class/character_class. + I'm not sure, but maybe enough. */ +#define BRACKET_NAME_BUF_SIZE 32 + +#ifndef _LIBC + /* Local function for parse_bracket_exp only used in case of NOT _LIBC. + Build the range expression which starts from START_ELEM, and ends + at END_ELEM. The result are written to MBCSET and SBCSET. + RANGE_ALLOC is the allocated size of mbcset->range_starts, and + mbcset->range_ends, is a pointer argument sinse we may + update it. */ + +static reg_errcode_t +internal_function +# ifdef RE_ENABLE_I18N +build_range_exp (bitset_t sbcset, re_charset_t *mbcset, Idx *range_alloc, + bracket_elem_t *start_elem, bracket_elem_t *end_elem) +# else /* not RE_ENABLE_I18N */ +build_range_exp (bitset_t sbcset, bracket_elem_t *start_elem, + bracket_elem_t *end_elem) +# endif /* not RE_ENABLE_I18N */ +{ + unsigned int start_ch, end_ch; + /* Equivalence Classes and Character Classes can't be a range start/end. */ + if (BE (start_elem->type == EQUIV_CLASS || start_elem->type == CHAR_CLASS + || end_elem->type == EQUIV_CLASS || end_elem->type == CHAR_CLASS, + 0)) + return REG_ERANGE; + + /* We can handle no multi character collating elements without libc + support. */ + if (BE ((start_elem->type == COLL_SYM + && strlen ((char *) start_elem->opr.name) > 1) + || (end_elem->type == COLL_SYM + && strlen ((char *) end_elem->opr.name) > 1), 0)) + return REG_ECOLLATE; + +# ifdef RE_ENABLE_I18N + { + wchar_t wc; + wint_t start_wc; + wint_t end_wc; + wchar_t cmp_buf[6] = {L'\0', L'\0', L'\0', L'\0', L'\0', L'\0'}; + + start_ch = ((start_elem->type == SB_CHAR) ? start_elem->opr.ch + : ((start_elem->type == COLL_SYM) ? start_elem->opr.name[0] + : 0)); + end_ch = ((end_elem->type == SB_CHAR) ? end_elem->opr.ch + : ((end_elem->type == COLL_SYM) ? end_elem->opr.name[0] + : 0)); + start_wc = ((start_elem->type == SB_CHAR || start_elem->type == COLL_SYM) + ? __btowc (start_ch) : start_elem->opr.wch); + end_wc = ((end_elem->type == SB_CHAR || end_elem->type == COLL_SYM) + ? __btowc (end_ch) : end_elem->opr.wch); + if (start_wc == WEOF || end_wc == WEOF) + return REG_ECOLLATE; + cmp_buf[0] = start_wc; + cmp_buf[4] = end_wc; + if (wcscoll (cmp_buf, cmp_buf + 4) > 0) + return REG_ERANGE; + + /* Got valid collation sequence values, add them as a new entry. + However, for !_LIBC we have no collation elements: if the + character set is single byte, the single byte character set + that we build below suffices. parse_bracket_exp passes + no MBCSET if dfa->mb_cur_max == 1. */ + if (mbcset) + { + /* Check the space of the arrays. */ + if (BE (*range_alloc == mbcset->nranges, 0)) + { + /* There is not enough space, need realloc. */ + wchar_t *new_array_start, *new_array_end; + Idx new_nranges; + + /* +1 in case of mbcset->nranges is 0. */ + new_nranges = 2 * mbcset->nranges + 1; + /* Use realloc since mbcset->range_starts and mbcset->range_ends + are NULL if *range_alloc == 0. */ + new_array_start = re_realloc (mbcset->range_starts, wchar_t, + new_nranges); + new_array_end = re_realloc (mbcset->range_ends, wchar_t, + new_nranges); + + if (BE (new_array_start == NULL || new_array_end == NULL, 0)) + return REG_ESPACE; + + mbcset->range_starts = new_array_start; + mbcset->range_ends = new_array_end; + *range_alloc = new_nranges; + } + + mbcset->range_starts[mbcset->nranges] = start_wc; + mbcset->range_ends[mbcset->nranges++] = end_wc; + } + + /* Build the table for single byte characters. */ + for (wc = 0; wc < SBC_MAX; ++wc) + { + cmp_buf[2] = wc; + if (wcscoll (cmp_buf, cmp_buf + 2) <= 0 + && wcscoll (cmp_buf + 2, cmp_buf + 4) <= 0) + bitset_set (sbcset, wc); + } + } +# else /* not RE_ENABLE_I18N */ + { + unsigned int ch; + start_ch = ((start_elem->type == SB_CHAR ) ? start_elem->opr.ch + : ((start_elem->type == COLL_SYM) ? start_elem->opr.name[0] + : 0)); + end_ch = ((end_elem->type == SB_CHAR ) ? end_elem->opr.ch + : ((end_elem->type == COLL_SYM) ? end_elem->opr.name[0] + : 0)); + if (start_ch > end_ch) + return REG_ERANGE; + /* Build the table for single byte characters. */ + for (ch = 0; ch < SBC_MAX; ++ch) + if (start_ch <= ch && ch <= end_ch) + bitset_set (sbcset, ch); + } +# endif /* not RE_ENABLE_I18N */ + return REG_NOERROR; +} +#endif /* not _LIBC */ + +#ifndef _LIBC +/* Helper function for parse_bracket_exp only used in case of NOT _LIBC.. + Build the collating element which is represented by NAME. + The result are written to MBCSET and SBCSET. + COLL_SYM_ALLOC is the allocated size of mbcset->coll_sym, is a + pointer argument since we may update it. */ + +static reg_errcode_t +internal_function +build_collating_symbol (bitset_t sbcset, +# ifdef RE_ENABLE_I18N + re_charset_t *mbcset, Idx *coll_sym_alloc, +# endif + const unsigned char *name) +{ + size_t name_len = strlen ((const char *) name); + if (BE (name_len != 1, 0)) + return REG_ECOLLATE; + else + { + bitset_set (sbcset, name[0]); + return REG_NOERROR; + } +} +#endif /* not _LIBC */ + +/* This function parse bracket expression like "[abc]", "[a-c]", + "[[.a-a.]]" etc. */ + +static bin_tree_t * +parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token, + reg_syntax_t syntax, reg_errcode_t *err) +{ +#ifdef _LIBC + const unsigned char *collseqmb; + const char *collseqwc; + uint32_t nrules; + int32_t table_size; + const int32_t *symb_table; + const unsigned char *extra; + + /* Local function for parse_bracket_exp used in _LIBC environement. + Seek the collating symbol entry correspondings to NAME. + Return the index of the symbol in the SYMB_TABLE. */ + + auto inline int32_t + __attribute ((always_inline)) + seek_collating_symbol_entry (name, name_len) + const unsigned char *name; + size_t name_len; + { + int32_t hash = elem_hash ((const char *) name, name_len); + int32_t elem = hash % table_size; + if (symb_table[2 * elem] != 0) + { + int32_t second = hash % (table_size - 2) + 1; + + do + { + /* First compare the hashing value. */ + if (symb_table[2 * elem] == hash + /* Compare the length of the name. */ + && name_len == extra[symb_table[2 * elem + 1]] + /* Compare the name. */ + && memcmp (name, &extra[symb_table[2 * elem + 1] + 1], + name_len) == 0) + { + /* Yep, this is the entry. */ + break; + } + + /* Next entry. */ + elem += second; + } + while (symb_table[2 * elem] != 0); + } + return elem; + } + + /* Local function for parse_bracket_exp used in _LIBC environement. + Look up the collation sequence value of BR_ELEM. + Return the value if succeeded, UINT_MAX otherwise. */ + + auto inline unsigned int + __attribute ((always_inline)) + lookup_collation_sequence_value (br_elem) + bracket_elem_t *br_elem; + { + if (br_elem->type == SB_CHAR) + { + /* + if (MB_CUR_MAX == 1) + */ + if (nrules == 0) + return collseqmb[br_elem->opr.ch]; + else + { + wint_t wc = __btowc (br_elem->opr.ch); + return __collseq_table_lookup (collseqwc, wc); + } + } + else if (br_elem->type == MB_CHAR) + { + return __collseq_table_lookup (collseqwc, br_elem->opr.wch); + } + else if (br_elem->type == COLL_SYM) + { + size_t sym_name_len = strlen ((char *) br_elem->opr.name); + if (nrules != 0) + { + int32_t elem, idx; + elem = seek_collating_symbol_entry (br_elem->opr.name, + sym_name_len); + if (symb_table[2 * elem] != 0) + { + /* We found the entry. */ + idx = symb_table[2 * elem + 1]; + /* Skip the name of collating element name. */ + idx += 1 + extra[idx]; + /* Skip the byte sequence of the collating element. */ + idx += 1 + extra[idx]; + /* Adjust for the alignment. */ + idx = (idx + 3) & ~3; + /* Skip the multibyte collation sequence value. */ + idx += sizeof (unsigned int); + /* Skip the wide char sequence of the collating element. */ + idx += sizeof (unsigned int) * + (1 + *(unsigned int *) (extra + idx)); + /* Return the collation sequence value. */ + return *(unsigned int *) (extra + idx); + } + else if (symb_table[2 * elem] == 0 && sym_name_len == 1) + { + /* No valid character. Match it as a single byte + character. */ + return collseqmb[br_elem->opr.name[0]]; + } + } + else if (sym_name_len == 1) + return collseqmb[br_elem->opr.name[0]]; + } + return UINT_MAX; + } + + /* Local function for parse_bracket_exp used in _LIBC environement. + Build the range expression which starts from START_ELEM, and ends + at END_ELEM. The result are written to MBCSET and SBCSET. + RANGE_ALLOC is the allocated size of mbcset->range_starts, and + mbcset->range_ends, is a pointer argument sinse we may + update it. */ + + auto inline reg_errcode_t + __attribute ((always_inline)) + build_range_exp (sbcset, mbcset, range_alloc, start_elem, end_elem) + re_charset_t *mbcset; + Idx *range_alloc; + bitset_t sbcset; + bracket_elem_t *start_elem, *end_elem; + { + unsigned int ch; + uint32_t start_collseq; + uint32_t end_collseq; + + /* Equivalence Classes and Character Classes can't be a range + start/end. */ + if (BE (start_elem->type == EQUIV_CLASS || start_elem->type == CHAR_CLASS + || end_elem->type == EQUIV_CLASS || end_elem->type == CHAR_CLASS, + 0)) + return REG_ERANGE; + + start_collseq = lookup_collation_sequence_value (start_elem); + end_collseq = lookup_collation_sequence_value (end_elem); + /* Check start/end collation sequence values. */ + if (BE (start_collseq == UINT_MAX || end_collseq == UINT_MAX, 0)) + return REG_ECOLLATE; + if (BE ((syntax & RE_NO_EMPTY_RANGES) && start_collseq > end_collseq, 0)) + return REG_ERANGE; + + /* Got valid collation sequence values, add them as a new entry. + However, if we have no collation elements, and the character set + is single byte, the single byte character set that we + build below suffices. */ + if (nrules > 0 || dfa->mb_cur_max > 1) + { + /* Check the space of the arrays. */ + if (BE (*range_alloc == mbcset->nranges, 0)) + { + /* There is not enough space, need realloc. */ + uint32_t *new_array_start; + uint32_t *new_array_end; + Idx new_nranges; + + /* +1 in case of mbcset->nranges is 0. */ + new_nranges = 2 * mbcset->nranges + 1; + new_array_start = re_realloc (mbcset->range_starts, uint32_t, + new_nranges); + new_array_end = re_realloc (mbcset->range_ends, uint32_t, + new_nranges); + + if (BE (new_array_start == NULL || new_array_end == NULL, 0)) + return REG_ESPACE; + + mbcset->range_starts = new_array_start; + mbcset->range_ends = new_array_end; + *range_alloc = new_nranges; + } + + mbcset->range_starts[mbcset->nranges] = start_collseq; + mbcset->range_ends[mbcset->nranges++] = end_collseq; + } + + /* Build the table for single byte characters. */ + for (ch = 0; ch < SBC_MAX; ch++) + { + uint32_t ch_collseq; + /* + if (MB_CUR_MAX == 1) + */ + if (nrules == 0) + ch_collseq = collseqmb[ch]; + else + ch_collseq = __collseq_table_lookup (collseqwc, __btowc (ch)); + if (start_collseq <= ch_collseq && ch_collseq <= end_collseq) + bitset_set (sbcset, ch); + } + return REG_NOERROR; + } + + /* Local function for parse_bracket_exp used in _LIBC environement. + Build the collating element which is represented by NAME. + The result are written to MBCSET and SBCSET. + COLL_SYM_ALLOC is the allocated size of mbcset->coll_sym, is a + pointer argument sinse we may update it. */ + + auto inline reg_errcode_t + __attribute ((always_inline)) + build_collating_symbol (sbcset, mbcset, coll_sym_alloc, name) + re_charset_t *mbcset; + Idx *coll_sym_alloc; + bitset_t sbcset; + const unsigned char *name; + { + int32_t elem, idx; + size_t name_len = strlen ((const char *) name); + if (nrules != 0) + { + elem = seek_collating_symbol_entry (name, name_len); + if (symb_table[2 * elem] != 0) + { + /* We found the entry. */ + idx = symb_table[2 * elem + 1]; + /* Skip the name of collating element name. */ + idx += 1 + extra[idx]; + } + else if (symb_table[2 * elem] == 0 && name_len == 1) + { + /* No valid character, treat it as a normal + character. */ + bitset_set (sbcset, name[0]); + return REG_NOERROR; + } + else + return REG_ECOLLATE; + + /* Got valid collation sequence, add it as a new entry. */ + /* Check the space of the arrays. */ + if (BE (*coll_sym_alloc == mbcset->ncoll_syms, 0)) + { + /* Not enough, realloc it. */ + /* +1 in case of mbcset->ncoll_syms is 0. */ + Idx new_coll_sym_alloc = 2 * mbcset->ncoll_syms + 1; + /* Use realloc since mbcset->coll_syms is NULL + if *alloc == 0. */ + int32_t *new_coll_syms = re_realloc (mbcset->coll_syms, int32_t, + new_coll_sym_alloc); + if (BE (new_coll_syms == NULL, 0)) + return REG_ESPACE; + mbcset->coll_syms = new_coll_syms; + *coll_sym_alloc = new_coll_sym_alloc; + } + mbcset->coll_syms[mbcset->ncoll_syms++] = idx; + return REG_NOERROR; + } + else + { + if (BE (name_len != 1, 0)) + return REG_ECOLLATE; + else + { + bitset_set (sbcset, name[0]); + return REG_NOERROR; + } + } + } +#endif + + re_token_t br_token; + re_bitset_ptr_t sbcset; +#ifdef RE_ENABLE_I18N + re_charset_t *mbcset; + Idx coll_sym_alloc = 0, range_alloc = 0, mbchar_alloc = 0; + Idx equiv_class_alloc = 0, char_class_alloc = 0; +#endif /* not RE_ENABLE_I18N */ + bool non_match = false; + bin_tree_t *work_tree; + int token_len; + bool first_round = true; +#ifdef _LIBC + collseqmb = (const unsigned char *) + _NL_CURRENT (LC_COLLATE, _NL_COLLATE_COLLSEQMB); + nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES); + if (nrules) + { + /* + if (MB_CUR_MAX > 1) + */ + collseqwc = _NL_CURRENT (LC_COLLATE, _NL_COLLATE_COLLSEQWC); + table_size = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_SYMB_HASH_SIZEMB); + symb_table = (const int32_t *) _NL_CURRENT (LC_COLLATE, + _NL_COLLATE_SYMB_TABLEMB); + extra = (const unsigned char *) _NL_CURRENT (LC_COLLATE, + _NL_COLLATE_SYMB_EXTRAMB); + } +#endif + sbcset = (re_bitset_ptr_t) calloc (sizeof (bitset_t), 1); +#ifdef RE_ENABLE_I18N + mbcset = (re_charset_t *) calloc (sizeof (re_charset_t), 1); +#endif /* RE_ENABLE_I18N */ +#ifdef RE_ENABLE_I18N + if (BE (sbcset == NULL || mbcset == NULL, 0)) +#else + if (BE (sbcset == NULL, 0)) +#endif /* RE_ENABLE_I18N */ + { + *err = REG_ESPACE; + return NULL; + } + + token_len = peek_token_bracket (token, regexp, syntax); + if (BE (token->type == END_OF_RE, 0)) + { + *err = REG_BADPAT; + goto parse_bracket_exp_free_return; + } + if (token->type == OP_NON_MATCH_LIST) + { +#ifdef RE_ENABLE_I18N + mbcset->non_match = 1; +#endif /* not RE_ENABLE_I18N */ + non_match = true; + if (syntax & RE_HAT_LISTS_NOT_NEWLINE) + bitset_set (sbcset, '\n'); + re_string_skip_bytes (regexp, token_len); /* Skip a token. */ + token_len = peek_token_bracket (token, regexp, syntax); + if (BE (token->type == END_OF_RE, 0)) + { + *err = REG_BADPAT; + goto parse_bracket_exp_free_return; + } + } + + /* We treat the first ']' as a normal character. */ + if (token->type == OP_CLOSE_BRACKET) + token->type = CHARACTER; + + while (1) + { + bracket_elem_t start_elem, end_elem; + unsigned char start_name_buf[BRACKET_NAME_BUF_SIZE]; + unsigned char end_name_buf[BRACKET_NAME_BUF_SIZE]; + reg_errcode_t ret; + int token_len2 = 0; + bool is_range_exp = false; + re_token_t token2; + + start_elem.opr.name = start_name_buf; + ret = parse_bracket_element (&start_elem, regexp, token, token_len, dfa, + syntax, first_round); + if (BE (ret != REG_NOERROR, 0)) + { + *err = ret; + goto parse_bracket_exp_free_return; + } + first_round = false; + + /* Get information about the next token. We need it in any case. */ + token_len = peek_token_bracket (token, regexp, syntax); + + /* Do not check for ranges if we know they are not allowed. */ + if (start_elem.type != CHAR_CLASS && start_elem.type != EQUIV_CLASS) + { + if (BE (token->type == END_OF_RE, 0)) + { + *err = REG_EBRACK; + goto parse_bracket_exp_free_return; + } + if (token->type == OP_CHARSET_RANGE) + { + re_string_skip_bytes (regexp, token_len); /* Skip '-'. */ + token_len2 = peek_token_bracket (&token2, regexp, syntax); + if (BE (token2.type == END_OF_RE, 0)) + { + *err = REG_EBRACK; + goto parse_bracket_exp_free_return; + } + if (token2.type == OP_CLOSE_BRACKET) + { + /* We treat the last '-' as a normal character. */ + re_string_skip_bytes (regexp, -token_len); + token->type = CHARACTER; + } + else + is_range_exp = true; + } + } + + if (is_range_exp == true) + { + end_elem.opr.name = end_name_buf; + ret = parse_bracket_element (&end_elem, regexp, &token2, token_len2, + dfa, syntax, true); + if (BE (ret != REG_NOERROR, 0)) + { + *err = ret; + goto parse_bracket_exp_free_return; + } + + token_len = peek_token_bracket (token, regexp, syntax); + +#ifdef _LIBC + *err = build_range_exp (sbcset, mbcset, &range_alloc, + &start_elem, &end_elem); +#else +# ifdef RE_ENABLE_I18N + *err = build_range_exp (sbcset, + dfa->mb_cur_max > 1 ? mbcset : NULL, + &range_alloc, &start_elem, &end_elem); +# else + *err = build_range_exp (sbcset, &start_elem, &end_elem); +# endif +#endif /* RE_ENABLE_I18N */ + if (BE (*err != REG_NOERROR, 0)) + goto parse_bracket_exp_free_return; + } + else + { + switch (start_elem.type) + { + case SB_CHAR: + bitset_set (sbcset, start_elem.opr.ch); + break; +#ifdef RE_ENABLE_I18N + case MB_CHAR: + /* Check whether the array has enough space. */ + if (BE (mbchar_alloc == mbcset->nmbchars, 0)) + { + wchar_t *new_mbchars; + /* Not enough, realloc it. */ + /* +1 in case of mbcset->nmbchars is 0. */ + mbchar_alloc = 2 * mbcset->nmbchars + 1; + /* Use realloc since array is NULL if *alloc == 0. */ + new_mbchars = re_realloc (mbcset->mbchars, wchar_t, + mbchar_alloc); + if (BE (new_mbchars == NULL, 0)) + goto parse_bracket_exp_espace; + mbcset->mbchars = new_mbchars; + } + mbcset->mbchars[mbcset->nmbchars++] = start_elem.opr.wch; + break; +#endif /* RE_ENABLE_I18N */ + case EQUIV_CLASS: + *err = build_equiv_class (sbcset, +#ifdef RE_ENABLE_I18N + mbcset, &equiv_class_alloc, +#endif /* RE_ENABLE_I18N */ + start_elem.opr.name); + if (BE (*err != REG_NOERROR, 0)) + goto parse_bracket_exp_free_return; + break; + case COLL_SYM: + *err = build_collating_symbol (sbcset, +#ifdef RE_ENABLE_I18N + mbcset, &coll_sym_alloc, +#endif /* RE_ENABLE_I18N */ + start_elem.opr.name); + if (BE (*err != REG_NOERROR, 0)) + goto parse_bracket_exp_free_return; + break; + case CHAR_CLASS: + *err = build_charclass (regexp->trans, sbcset, +#ifdef RE_ENABLE_I18N + mbcset, &char_class_alloc, +#endif /* RE_ENABLE_I18N */ + start_elem.opr.name, syntax); + if (BE (*err != REG_NOERROR, 0)) + goto parse_bracket_exp_free_return; + break; + default: + assert (0); + break; + } + } + if (BE (token->type == END_OF_RE, 0)) + { + *err = REG_EBRACK; + goto parse_bracket_exp_free_return; + } + if (token->type == OP_CLOSE_BRACKET) + break; + } + + re_string_skip_bytes (regexp, token_len); /* Skip a token. */ + + /* If it is non-matching list. */ + if (non_match) + bitset_not (sbcset); + +#ifdef RE_ENABLE_I18N + /* Ensure only single byte characters are set. */ + if (dfa->mb_cur_max > 1) + bitset_mask (sbcset, dfa->sb_char); + + if (mbcset->nmbchars || mbcset->ncoll_syms || mbcset->nequiv_classes + || mbcset->nranges || (dfa->mb_cur_max > 1 && (mbcset->nchar_classes + || mbcset->non_match))) + { + bin_tree_t *mbc_tree; + int sbc_idx; + /* Build a tree for complex bracket. */ + dfa->has_mb_node = 1; + br_token.type = COMPLEX_BRACKET; + br_token.opr.mbcset = mbcset; + mbc_tree = create_token_tree (dfa, NULL, NULL, &br_token); + if (BE (mbc_tree == NULL, 0)) + goto parse_bracket_exp_espace; + for (sbc_idx = 0; sbc_idx < BITSET_WORDS; ++sbc_idx) + if (sbcset[sbc_idx]) + break; + /* If there are no bits set in sbcset, there is no point + of having both SIMPLE_BRACKET and COMPLEX_BRACKET. */ + if (sbc_idx < BITSET_WORDS) + { + /* Build a tree for simple bracket. */ + br_token.type = SIMPLE_BRACKET; + br_token.opr.sbcset = sbcset; + work_tree = create_token_tree (dfa, NULL, NULL, &br_token); + if (BE (work_tree == NULL, 0)) + goto parse_bracket_exp_espace; + + /* Then join them by ALT node. */ + work_tree = create_tree (dfa, work_tree, mbc_tree, OP_ALT); + if (BE (work_tree == NULL, 0)) + goto parse_bracket_exp_espace; + } + else + { + re_free (sbcset); + work_tree = mbc_tree; + } + } + else +#endif /* not RE_ENABLE_I18N */ + { +#ifdef RE_ENABLE_I18N + free_charset (mbcset); +#endif + /* Build a tree for simple bracket. */ + br_token.type = SIMPLE_BRACKET; + br_token.opr.sbcset = sbcset; + work_tree = create_token_tree (dfa, NULL, NULL, &br_token); + if (BE (work_tree == NULL, 0)) + goto parse_bracket_exp_espace; + } + return work_tree; + + parse_bracket_exp_espace: + *err = REG_ESPACE; + parse_bracket_exp_free_return: + re_free (sbcset); +#ifdef RE_ENABLE_I18N + free_charset (mbcset); +#endif /* RE_ENABLE_I18N */ + return NULL; +} + +/* Parse an element in the bracket expression. */ + +static reg_errcode_t +parse_bracket_element (bracket_elem_t *elem, re_string_t *regexp, + re_token_t *token, int token_len, re_dfa_t *dfa, + reg_syntax_t syntax, bool accept_hyphen) +{ +#ifdef RE_ENABLE_I18N + int cur_char_size; + cur_char_size = re_string_char_size_at (regexp, re_string_cur_idx (regexp)); + if (cur_char_size > 1) + { + elem->type = MB_CHAR; + elem->opr.wch = re_string_wchar_at (regexp, re_string_cur_idx (regexp)); + re_string_skip_bytes (regexp, cur_char_size); + return REG_NOERROR; + } +#endif /* RE_ENABLE_I18N */ + re_string_skip_bytes (regexp, token_len); /* Skip a token. */ + if (token->type == OP_OPEN_COLL_ELEM || token->type == OP_OPEN_CHAR_CLASS + || token->type == OP_OPEN_EQUIV_CLASS) + return parse_bracket_symbol (elem, regexp, token); + if (BE (token->type == OP_CHARSET_RANGE, 0) && !accept_hyphen) + { + /* A '-' must only appear as anything but a range indicator before + the closing bracket. Everything else is an error. */ + re_token_t token2; + (void) peek_token_bracket (&token2, regexp, syntax); + if (token2.type != OP_CLOSE_BRACKET) + /* The actual error value is not standardized since this whole + case is undefined. But ERANGE makes good sense. */ + return REG_ERANGE; + } + elem->type = SB_CHAR; + elem->opr.ch = token->opr.c; + return REG_NOERROR; +} + +/* Parse a bracket symbol in the bracket expression. Bracket symbols are + such as [::], [..], and + [==]. */ + +static reg_errcode_t +parse_bracket_symbol (bracket_elem_t *elem, re_string_t *regexp, + re_token_t *token) +{ + unsigned char ch, delim = token->opr.c; + int i = 0; + if (re_string_eoi(regexp)) + return REG_EBRACK; + for (;; ++i) + { + if (i >= BRACKET_NAME_BUF_SIZE) + return REG_EBRACK; + if (token->type == OP_OPEN_CHAR_CLASS) + ch = re_string_fetch_byte_case (regexp); + else + ch = re_string_fetch_byte (regexp); + if (re_string_eoi(regexp)) + return REG_EBRACK; + if (ch == delim && re_string_peek_byte (regexp, 0) == ']') + break; + elem->opr.name[i] = ch; + } + re_string_skip_bytes (regexp, 1); + elem->opr.name[i] = '\0'; + switch (token->type) + { + case OP_OPEN_COLL_ELEM: + elem->type = COLL_SYM; + break; + case OP_OPEN_EQUIV_CLASS: + elem->type = EQUIV_CLASS; + break; + case OP_OPEN_CHAR_CLASS: + elem->type = CHAR_CLASS; + break; + default: + break; + } + return REG_NOERROR; +} + + /* Helper function for parse_bracket_exp. + Build the equivalence class which is represented by NAME. + The result are written to MBCSET and SBCSET. + EQUIV_CLASS_ALLOC is the allocated size of mbcset->equiv_classes, + is a pointer argument sinse we may update it. */ + +static reg_errcode_t +#ifdef RE_ENABLE_I18N +build_equiv_class (bitset_t sbcset, re_charset_t *mbcset, + Idx *equiv_class_alloc, const unsigned char *name) +#else /* not RE_ENABLE_I18N */ +build_equiv_class (bitset_t sbcset, const unsigned char *name) +#endif /* not RE_ENABLE_I18N */ +{ +#ifdef _LIBC + uint32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES); + if (nrules != 0) + { + const int32_t *table, *indirect; + const unsigned char *weights, *extra, *cp; + unsigned char char_buf[2]; + int32_t idx1, idx2; + unsigned int ch; + size_t len; + /* This #include defines a local function! */ +# include + /* Calculate the index for equivalence class. */ + cp = name; + table = (const int32_t *) _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB); + weights = (const unsigned char *) _NL_CURRENT (LC_COLLATE, + _NL_COLLATE_WEIGHTMB); + extra = (const unsigned char *) _NL_CURRENT (LC_COLLATE, + _NL_COLLATE_EXTRAMB); + indirect = (const int32_t *) _NL_CURRENT (LC_COLLATE, + _NL_COLLATE_INDIRECTMB); + idx1 = findidx (&cp); + if (BE (idx1 == 0 || cp < name + strlen ((const char *) name), 0)) + /* This isn't a valid character. */ + return REG_ECOLLATE; + + /* Build single byte matcing table for this equivalence class. */ + char_buf[1] = (unsigned char) '\0'; + len = weights[idx1]; + for (ch = 0; ch < SBC_MAX; ++ch) + { + char_buf[0] = ch; + cp = char_buf; + idx2 = findidx (&cp); +/* + idx2 = table[ch]; +*/ + if (idx2 == 0) + /* This isn't a valid character. */ + continue; + if (len == weights[idx2]) + { + int cnt = 0; + while (cnt <= len && + weights[idx1 + 1 + cnt] == weights[idx2 + 1 + cnt]) + ++cnt; + + if (cnt > len) + bitset_set (sbcset, ch); + } + } + /* Check whether the array has enough space. */ + if (BE (*equiv_class_alloc == mbcset->nequiv_classes, 0)) + { + /* Not enough, realloc it. */ + /* +1 in case of mbcset->nequiv_classes is 0. */ + Idx new_equiv_class_alloc = 2 * mbcset->nequiv_classes + 1; + /* Use realloc since the array is NULL if *alloc == 0. */ + int32_t *new_equiv_classes = re_realloc (mbcset->equiv_classes, + int32_t, + new_equiv_class_alloc); + if (BE (new_equiv_classes == NULL, 0)) + return REG_ESPACE; + mbcset->equiv_classes = new_equiv_classes; + *equiv_class_alloc = new_equiv_class_alloc; + } + mbcset->equiv_classes[mbcset->nequiv_classes++] = idx1; + } + else +#endif /* _LIBC */ + { + if (BE (strlen ((const char *) name) != 1, 0)) + return REG_ECOLLATE; + bitset_set (sbcset, *name); + } + return REG_NOERROR; +} + + /* Helper function for parse_bracket_exp. + Build the character class which is represented by NAME. + The result are written to MBCSET and SBCSET. + CHAR_CLASS_ALLOC is the allocated size of mbcset->char_classes, + is a pointer argument sinse we may update it. */ + +static reg_errcode_t +#ifdef RE_ENABLE_I18N +build_charclass (RE_TRANSLATE_TYPE trans, bitset_t sbcset, + re_charset_t *mbcset, Idx *char_class_alloc, + const unsigned char *class_name, reg_syntax_t syntax) +#else /* not RE_ENABLE_I18N */ +build_charclass (RE_TRANSLATE_TYPE trans, bitset_t sbcset, + const unsigned char *class_name, reg_syntax_t syntax) +#endif /* not RE_ENABLE_I18N */ +{ + int i; + const char *name = (const char *) class_name; + + /* In case of REG_ICASE "upper" and "lower" match the both of + upper and lower cases. */ + if ((syntax & RE_ICASE) + && (strcmp (name, "upper") == 0 || strcmp (name, "lower") == 0)) + name = "alpha"; + +#ifdef RE_ENABLE_I18N + /* Check the space of the arrays. */ + if (BE (*char_class_alloc == mbcset->nchar_classes, 0)) + { + /* Not enough, realloc it. */ + /* +1 in case of mbcset->nchar_classes is 0. */ + Idx new_char_class_alloc = 2 * mbcset->nchar_classes + 1; + /* Use realloc since array is NULL if *alloc == 0. */ + wctype_t *new_char_classes = re_realloc (mbcset->char_classes, wctype_t, + new_char_class_alloc); + if (BE (new_char_classes == NULL, 0)) + return REG_ESPACE; + mbcset->char_classes = new_char_classes; + *char_class_alloc = new_char_class_alloc; + } + mbcset->char_classes[mbcset->nchar_classes++] = __wctype (name); +#endif /* RE_ENABLE_I18N */ + +#define BUILD_CHARCLASS_LOOP(ctype_func) \ + do { \ + if (BE (trans != NULL, 0)) \ + { \ + for (i = 0; i < SBC_MAX; ++i) \ + if (ctype_func (i)) \ + bitset_set (sbcset, trans[i]); \ + } \ + else \ + { \ + for (i = 0; i < SBC_MAX; ++i) \ + if (ctype_func (i)) \ + bitset_set (sbcset, i); \ + } \ + } while (0) + + if (strcmp (name, "alnum") == 0) + BUILD_CHARCLASS_LOOP (isalnum); + else if (strcmp (name, "cntrl") == 0) + BUILD_CHARCLASS_LOOP (iscntrl); + else if (strcmp (name, "lower") == 0) + BUILD_CHARCLASS_LOOP (islower); + else if (strcmp (name, "space") == 0) + BUILD_CHARCLASS_LOOP (isspace); + else if (strcmp (name, "alpha") == 0) + BUILD_CHARCLASS_LOOP (isalpha); + else if (strcmp (name, "digit") == 0) + BUILD_CHARCLASS_LOOP (isdigit); + else if (strcmp (name, "print") == 0) + BUILD_CHARCLASS_LOOP (isprint); + else if (strcmp (name, "upper") == 0) + BUILD_CHARCLASS_LOOP (isupper); + else if (strcmp (name, "blank") == 0) + BUILD_CHARCLASS_LOOP (isblank); + else if (strcmp (name, "graph") == 0) + BUILD_CHARCLASS_LOOP (isgraph); + else if (strcmp (name, "punct") == 0) + BUILD_CHARCLASS_LOOP (ispunct); + else if (strcmp (name, "xdigit") == 0) + BUILD_CHARCLASS_LOOP (isxdigit); + else + return REG_ECTYPE; + + return REG_NOERROR; +} + +static bin_tree_t * +build_charclass_op (re_dfa_t *dfa, RE_TRANSLATE_TYPE trans, + const unsigned char *class_name, + const unsigned char *extra, bool non_match, + reg_errcode_t *err) +{ + re_bitset_ptr_t sbcset; +#ifdef RE_ENABLE_I18N + re_charset_t *mbcset; + Idx alloc = 0; +#endif /* not RE_ENABLE_I18N */ + reg_errcode_t ret; + re_token_t br_token; + bin_tree_t *tree; + + sbcset = (re_bitset_ptr_t) calloc (sizeof (bitset_t), 1); +#ifdef RE_ENABLE_I18N + mbcset = (re_charset_t *) calloc (sizeof (re_charset_t), 1); +#endif /* RE_ENABLE_I18N */ + +#ifdef RE_ENABLE_I18N + if (BE (sbcset == NULL || mbcset == NULL, 0)) +#else /* not RE_ENABLE_I18N */ + if (BE (sbcset == NULL, 0)) +#endif /* not RE_ENABLE_I18N */ + { + *err = REG_ESPACE; + return NULL; + } + + if (non_match) + { +#ifdef RE_ENABLE_I18N + mbcset->non_match = 1; +#endif /* not RE_ENABLE_I18N */ + } + + /* We don't care the syntax in this case. */ + ret = build_charclass (trans, sbcset, +#ifdef RE_ENABLE_I18N + mbcset, &alloc, +#endif /* RE_ENABLE_I18N */ + class_name, 0); + + if (BE (ret != REG_NOERROR, 0)) + { + re_free (sbcset); +#ifdef RE_ENABLE_I18N + free_charset (mbcset); +#endif /* RE_ENABLE_I18N */ + *err = ret; + return NULL; + } + /* \w match '_' also. */ + for (; *extra; extra++) + bitset_set (sbcset, *extra); + + /* If it is non-matching list. */ + if (non_match) + bitset_not (sbcset); + +#ifdef RE_ENABLE_I18N + /* Ensure only single byte characters are set. */ + if (dfa->mb_cur_max > 1) + bitset_mask (sbcset, dfa->sb_char); +#endif + + /* Build a tree for simple bracket. */ + br_token.type = SIMPLE_BRACKET; + br_token.opr.sbcset = sbcset; + tree = create_token_tree (dfa, NULL, NULL, &br_token); + if (BE (tree == NULL, 0)) + goto build_word_op_espace; + +#ifdef RE_ENABLE_I18N + if (dfa->mb_cur_max > 1) + { + bin_tree_t *mbc_tree; + /* Build a tree for complex bracket. */ + br_token.type = COMPLEX_BRACKET; + br_token.opr.mbcset = mbcset; + dfa->has_mb_node = 1; + mbc_tree = create_token_tree (dfa, NULL, NULL, &br_token); + if (BE (mbc_tree == NULL, 0)) + goto build_word_op_espace; + /* Then join them by ALT node. */ + tree = create_tree (dfa, tree, mbc_tree, OP_ALT); + if (BE (mbc_tree != NULL, 1)) + return tree; + } + else + { + free_charset (mbcset); + return tree; + } +#else /* not RE_ENABLE_I18N */ + return tree; +#endif /* not RE_ENABLE_I18N */ + + build_word_op_espace: + re_free (sbcset); +#ifdef RE_ENABLE_I18N + free_charset (mbcset); +#endif /* RE_ENABLE_I18N */ + *err = REG_ESPACE; + return NULL; +} + +/* This is intended for the expressions like "a{1,3}". + Fetch a number from `input', and return the number. + Return REG_MISSING if the number field is empty like "{,1}". + Return REG_ERROR if an error occurred. */ + +static Idx +fetch_number (re_string_t *input, re_token_t *token, reg_syntax_t syntax) +{ + Idx num = REG_MISSING; + unsigned char c; + while (1) + { + fetch_token (token, input, syntax); + c = token->opr.c; + if (BE (token->type == END_OF_RE, 0)) + return REG_ERROR; + if (token->type == OP_CLOSE_DUP_NUM || c == ',') + break; + num = ((token->type != CHARACTER || c < '0' || '9' < c + || num == REG_ERROR) + ? REG_ERROR + : ((num == REG_MISSING) ? c - '0' : num * 10 + c - '0')); + num = (num > RE_DUP_MAX) ? REG_ERROR : num; + } + return num; +} + +#ifdef RE_ENABLE_I18N +static void +free_charset (re_charset_t *cset) +{ + re_free (cset->mbchars); +# ifdef _LIBC + re_free (cset->coll_syms); + re_free (cset->equiv_classes); + re_free (cset->range_starts); + re_free (cset->range_ends); +# endif + re_free (cset->char_classes); + re_free (cset); +} +#endif /* RE_ENABLE_I18N */ + +/* Functions for binary tree operation. */ + +/* Create a tree node. */ + +static bin_tree_t * +create_tree (re_dfa_t *dfa, bin_tree_t *left, bin_tree_t *right, + re_token_type_t type) +{ + re_token_t t; + t.type = type; + return create_token_tree (dfa, left, right, &t); +} + +static bin_tree_t * +create_token_tree (re_dfa_t *dfa, bin_tree_t *left, bin_tree_t *right, + const re_token_t *token) +{ + bin_tree_t *tree; + if (BE (dfa->str_tree_storage_idx == BIN_TREE_STORAGE_SIZE, 0)) + { + bin_tree_storage_t *storage = re_malloc (bin_tree_storage_t, 1); + + if (storage == NULL) + return NULL; + storage->next = dfa->str_tree_storage; + dfa->str_tree_storage = storage; + dfa->str_tree_storage_idx = 0; + } + tree = &dfa->str_tree_storage->data[dfa->str_tree_storage_idx++]; + + tree->parent = NULL; + tree->left = left; + tree->right = right; + tree->token = *token; + tree->token.duplicated = 0; + tree->token.opt_subexp = 0; + tree->first = NULL; + tree->next = NULL; + tree->node_idx = REG_MISSING; + + if (left != NULL) + left->parent = tree; + if (right != NULL) + right->parent = tree; + return tree; +} + +/* Mark the tree SRC as an optional subexpression. + To be called from preorder or postorder. */ + +static reg_errcode_t +mark_opt_subexp (void *extra, bin_tree_t *node) +{ + Idx idx = (Idx) (long) extra; + if (node->token.type == SUBEXP && node->token.opr.idx == idx) + node->token.opt_subexp = 1; + + return REG_NOERROR; +} + +/* Free the allocated memory inside NODE. */ + +static void +free_token (re_token_t *node) +{ +#ifdef RE_ENABLE_I18N + if (node->type == COMPLEX_BRACKET && node->duplicated == 0) + free_charset (node->opr.mbcset); + else +#endif /* RE_ENABLE_I18N */ + if (node->type == SIMPLE_BRACKET && node->duplicated == 0) + re_free (node->opr.sbcset); +} + +/* Worker function for tree walking. Free the allocated memory inside NODE + and its children. */ + +static reg_errcode_t +free_tree (void *extra, bin_tree_t *node) +{ + free_token (&node->token); + return REG_NOERROR; +} + + +/* Duplicate the node SRC, and return new node. This is a preorder + visit similar to the one implemented by the generic visitor, but + we need more infrastructure to maintain two parallel trees --- so, + it's easier to duplicate. */ + +static bin_tree_t * +duplicate_tree (const bin_tree_t *root, re_dfa_t *dfa) +{ + const bin_tree_t *node; + bin_tree_t *dup_root; + bin_tree_t **p_new = &dup_root, *dup_node = root->parent; + + for (node = root; ; ) + { + /* Create a new tree and link it back to the current parent. */ + *p_new = create_token_tree (dfa, NULL, NULL, &node->token); + if (*p_new == NULL) + return NULL; + (*p_new)->parent = dup_node; + (*p_new)->token.duplicated = 1; + dup_node = *p_new; + + /* Go to the left node, or up and to the right. */ + if (node->left) + { + node = node->left; + p_new = &dup_node->left; + } + else + { + const bin_tree_t *prev = NULL; + while (node->right == prev || node->right == NULL) + { + prev = node; + node = node->parent; + dup_node = dup_node->parent; + if (!node) + return dup_root; + } + node = node->right; + p_new = &dup_node->right; + } + } +} diff --git a/gnulib/regex.c b/gnulib/regex.c new file mode 100644 index 000000000..76998f8d3 --- /dev/null +++ b/gnulib/regex.c @@ -0,0 +1,26 @@ +/* Extended regular expression matching and search library. + Copyright (C) 2002, 2003, 2005, 2006 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Isamu Hasegawa . + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include + +#include "regex_internal.h" + +#include "regex_internal.c" +#include "regcomp.c" +#include "regexec.c" diff --git a/gnulib/regex_internal.c b/gnulib/regex_internal.c new file mode 100644 index 000000000..904b88ed9 --- /dev/null +++ b/gnulib/regex_internal.c @@ -0,0 +1,1737 @@ +/* Extended regular expression matching and search library. + Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 + Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Isamu Hasegawa . + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +static void re_string_construct_common (const char *str, Idx len, + re_string_t *pstr, + RE_TRANSLATE_TYPE trans, bool icase, + const re_dfa_t *dfa) internal_function; +static re_dfastate_t *create_ci_newstate (const re_dfa_t *dfa, + const re_node_set *nodes, + re_hashval_t hash) internal_function; +static re_dfastate_t *create_cd_newstate (const re_dfa_t *dfa, + const re_node_set *nodes, + unsigned int context, + re_hashval_t hash) internal_function; + +/* Functions for string operation. */ + +/* This function allocate the buffers. It is necessary to call + re_string_reconstruct before using the object. */ + +static reg_errcode_t +internal_function +re_string_allocate (re_string_t *pstr, const char *str, Idx len, Idx init_len, + RE_TRANSLATE_TYPE trans, bool icase, const re_dfa_t *dfa) +{ + reg_errcode_t ret; + Idx init_buf_len; + + /* Ensure at least one character fits into the buffers. */ + if (init_len < dfa->mb_cur_max) + init_len = dfa->mb_cur_max; + init_buf_len = (len + 1 < init_len) ? len + 1: init_len; + re_string_construct_common (str, len, pstr, trans, icase, dfa); + + ret = re_string_realloc_buffers (pstr, init_buf_len); + if (BE (ret != REG_NOERROR, 0)) + return ret; + + pstr->word_char = dfa->word_char; + pstr->word_ops_used = dfa->word_ops_used; + pstr->mbs = pstr->mbs_allocated ? pstr->mbs : (unsigned char *) str; + pstr->valid_len = (pstr->mbs_allocated || dfa->mb_cur_max > 1) ? 0 : len; + pstr->valid_raw_len = pstr->valid_len; + return REG_NOERROR; +} + +/* This function allocate the buffers, and initialize them. */ + +static reg_errcode_t +internal_function +re_string_construct (re_string_t *pstr, const char *str, Idx len, + RE_TRANSLATE_TYPE trans, bool icase, const re_dfa_t *dfa) +{ + reg_errcode_t ret; + memset (pstr, '\0', sizeof (re_string_t)); + re_string_construct_common (str, len, pstr, trans, icase, dfa); + + if (len > 0) + { + ret = re_string_realloc_buffers (pstr, len + 1); + if (BE (ret != REG_NOERROR, 0)) + return ret; + } + pstr->mbs = pstr->mbs_allocated ? pstr->mbs : (unsigned char *) str; + + if (icase) + { +#ifdef RE_ENABLE_I18N + if (dfa->mb_cur_max > 1) + { + while (1) + { + ret = build_wcs_upper_buffer (pstr); + if (BE (ret != REG_NOERROR, 0)) + return ret; + if (pstr->valid_raw_len >= len) + break; + if (pstr->bufs_len > pstr->valid_len + dfa->mb_cur_max) + break; + ret = re_string_realloc_buffers (pstr, pstr->bufs_len * 2); + if (BE (ret != REG_NOERROR, 0)) + return ret; + } + } + else +#endif /* RE_ENABLE_I18N */ + build_upper_buffer (pstr); + } + else + { +#ifdef RE_ENABLE_I18N + if (dfa->mb_cur_max > 1) + build_wcs_buffer (pstr); + else +#endif /* RE_ENABLE_I18N */ + { + if (trans != NULL) + re_string_translate_buffer (pstr); + else + { + pstr->valid_len = pstr->bufs_len; + pstr->valid_raw_len = pstr->bufs_len; + } + } + } + + return REG_NOERROR; +} + +/* Helper functions for re_string_allocate, and re_string_construct. */ + +static reg_errcode_t +internal_function +re_string_realloc_buffers (re_string_t *pstr, Idx new_buf_len) +{ +#ifdef RE_ENABLE_I18N + if (pstr->mb_cur_max > 1) + { + wint_t *new_wcs; + + /* Avoid overflow. */ + size_t max_object_size = MAX (sizeof (wint_t), sizeof (Idx)); + if (BE (SIZE_MAX / max_object_size < new_buf_len, 0)) + return REG_ESPACE; + + new_wcs = re_realloc (pstr->wcs, wint_t, new_buf_len); + if (BE (new_wcs == NULL, 0)) + return REG_ESPACE; + pstr->wcs = new_wcs; + if (pstr->offsets != NULL) + { + Idx *new_offsets = re_realloc (pstr->offsets, Idx, new_buf_len); + if (BE (new_offsets == NULL, 0)) + return REG_ESPACE; + pstr->offsets = new_offsets; + } + } +#endif /* RE_ENABLE_I18N */ + if (pstr->mbs_allocated) + { + unsigned char *new_mbs = re_realloc (pstr->mbs, unsigned char, + new_buf_len); + if (BE (new_mbs == NULL, 0)) + return REG_ESPACE; + pstr->mbs = new_mbs; + } + pstr->bufs_len = new_buf_len; + return REG_NOERROR; +} + + +static void +internal_function +re_string_construct_common (const char *str, Idx len, re_string_t *pstr, + RE_TRANSLATE_TYPE trans, bool icase, + const re_dfa_t *dfa) +{ + pstr->raw_mbs = (const unsigned char *) str; + pstr->len = len; + pstr->raw_len = len; + pstr->trans = trans; + pstr->icase = icase; + pstr->mbs_allocated = (trans != NULL || icase); + pstr->mb_cur_max = dfa->mb_cur_max; + pstr->is_utf8 = dfa->is_utf8; + pstr->map_notascii = dfa->map_notascii; + pstr->stop = pstr->len; + pstr->raw_stop = pstr->stop; +} + +#ifdef RE_ENABLE_I18N + +/* Build wide character buffer PSTR->WCS. + If the byte sequence of the string are: + (0), (1), (0), (1), + Then wide character buffer will be: + , WEOF , , WEOF , + We use WEOF for padding, they indicate that the position isn't + a first byte of a multibyte character. + + Note that this function assumes PSTR->VALID_LEN elements are already + built and starts from PSTR->VALID_LEN. */ + +static void +internal_function +build_wcs_buffer (re_string_t *pstr) +{ +#ifdef _LIBC + unsigned char buf[MB_LEN_MAX]; + assert (MB_LEN_MAX >= pstr->mb_cur_max); +#else + unsigned char buf[64]; +#endif + mbstate_t prev_st; + Idx byte_idx, end_idx, remain_len; + size_t mbclen; + + /* Build the buffers from pstr->valid_len to either pstr->len or + pstr->bufs_len. */ + end_idx = (pstr->bufs_len > pstr->len) ? pstr->len : pstr->bufs_len; + for (byte_idx = pstr->valid_len; byte_idx < end_idx;) + { + wchar_t wc; + const char *p; + + remain_len = end_idx - byte_idx; + prev_st = pstr->cur_state; + /* Apply the translation if we need. */ + if (BE (pstr->trans != NULL, 0)) + { + int i, ch; + + for (i = 0; i < pstr->mb_cur_max && i < remain_len; ++i) + { + ch = pstr->raw_mbs [pstr->raw_mbs_idx + byte_idx + i]; + buf[i] = pstr->mbs[byte_idx + i] = pstr->trans[ch]; + } + p = (const char *) buf; + } + else + p = (const char *) pstr->raw_mbs + pstr->raw_mbs_idx + byte_idx; + mbclen = __mbrtowc (&wc, p, remain_len, &pstr->cur_state); + if (BE (mbclen == (size_t) -2, 0)) + { + /* The buffer doesn't have enough space, finish to build. */ + pstr->cur_state = prev_st; + break; + } + else if (BE (mbclen == (size_t) -1 || mbclen == 0, 0)) + { + /* We treat these cases as a singlebyte character. */ + mbclen = 1; + wc = (wchar_t) pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx]; + if (BE (pstr->trans != NULL, 0)) + wc = pstr->trans[wc]; + pstr->cur_state = prev_st; + } + + /* Write wide character and padding. */ + pstr->wcs[byte_idx++] = wc; + /* Write paddings. */ + for (remain_len = byte_idx + mbclen - 1; byte_idx < remain_len ;) + pstr->wcs[byte_idx++] = WEOF; + } + pstr->valid_len = byte_idx; + pstr->valid_raw_len = byte_idx; +} + +/* Build wide character buffer PSTR->WCS like build_wcs_buffer, + but for REG_ICASE. */ + +static reg_errcode_t +internal_function +build_wcs_upper_buffer (re_string_t *pstr) +{ + mbstate_t prev_st; + Idx src_idx, byte_idx, end_idx, remain_len; + size_t mbclen; +#ifdef _LIBC + char buf[MB_LEN_MAX]; + assert (MB_LEN_MAX >= pstr->mb_cur_max); +#else + char buf[64]; +#endif + + byte_idx = pstr->valid_len; + end_idx = (pstr->bufs_len > pstr->len) ? pstr->len : pstr->bufs_len; + + /* The following optimization assumes that ASCII characters can be + mapped to wide characters with a simple cast. */ + if (! pstr->map_notascii && pstr->trans == NULL && !pstr->offsets_needed) + { + while (byte_idx < end_idx) + { + wchar_t wc; + + if (isascii (pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx]) + && mbsinit (&pstr->cur_state)) + { + /* In case of a singlebyte character. */ + pstr->mbs[byte_idx] + = toupper (pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx]); + /* The next step uses the assumption that wchar_t is encoded + ASCII-safe: all ASCII values can be converted like this. */ + pstr->wcs[byte_idx] = (wchar_t) pstr->mbs[byte_idx]; + ++byte_idx; + continue; + } + + remain_len = end_idx - byte_idx; + prev_st = pstr->cur_state; + mbclen = __mbrtowc (&wc, + ((const char *) pstr->raw_mbs + pstr->raw_mbs_idx + + byte_idx), remain_len, &pstr->cur_state); + if (BE (mbclen < (size_t) -2, 1)) + { + wchar_t wcu = wc; + if (iswlower (wc)) + { + size_t mbcdlen; + + wcu = towupper (wc); + mbcdlen = wcrtomb (buf, wcu, &prev_st); + if (BE (mbclen == mbcdlen, 1)) + memcpy (pstr->mbs + byte_idx, buf, mbclen); + else + { + src_idx = byte_idx; + goto offsets_needed; + } + } + else + memcpy (pstr->mbs + byte_idx, + pstr->raw_mbs + pstr->raw_mbs_idx + byte_idx, mbclen); + pstr->wcs[byte_idx++] = wcu; + /* Write paddings. */ + for (remain_len = byte_idx + mbclen - 1; byte_idx < remain_len ;) + pstr->wcs[byte_idx++] = WEOF; + } + else if (mbclen == (size_t) -1 || mbclen == 0) + { + /* It is an invalid character or '\0'. Just use the byte. */ + int ch = pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx]; + pstr->mbs[byte_idx] = ch; + /* And also cast it to wide char. */ + pstr->wcs[byte_idx++] = (wchar_t) ch; + if (BE (mbclen == (size_t) -1, 0)) + pstr->cur_state = prev_st; + } + else + { + /* The buffer doesn't have enough space, finish to build. */ + pstr->cur_state = prev_st; + break; + } + } + pstr->valid_len = byte_idx; + pstr->valid_raw_len = byte_idx; + return REG_NOERROR; + } + else + for (src_idx = pstr->valid_raw_len; byte_idx < end_idx;) + { + wchar_t wc; + const char *p; + offsets_needed: + remain_len = end_idx - byte_idx; + prev_st = pstr->cur_state; + if (BE (pstr->trans != NULL, 0)) + { + int i, ch; + + for (i = 0; i < pstr->mb_cur_max && i < remain_len; ++i) + { + ch = pstr->raw_mbs [pstr->raw_mbs_idx + src_idx + i]; + buf[i] = pstr->trans[ch]; + } + p = (const char *) buf; + } + else + p = (const char *) pstr->raw_mbs + pstr->raw_mbs_idx + src_idx; + mbclen = __mbrtowc (&wc, p, remain_len, &pstr->cur_state); + if (BE (mbclen < (size_t) -2, 1)) + { + wchar_t wcu = wc; + if (iswlower (wc)) + { + size_t mbcdlen; + + wcu = towupper (wc); + mbcdlen = wcrtomb ((char *) buf, wcu, &prev_st); + if (BE (mbclen == mbcdlen, 1)) + memcpy (pstr->mbs + byte_idx, buf, mbclen); + else if (mbcdlen != (size_t) -1) + { + size_t i; + + if (byte_idx + mbcdlen > pstr->bufs_len) + { + pstr->cur_state = prev_st; + break; + } + + if (pstr->offsets == NULL) + { + pstr->offsets = re_malloc (Idx, pstr->bufs_len); + + if (pstr->offsets == NULL) + return REG_ESPACE; + } + if (!pstr->offsets_needed) + { + for (i = 0; i < (size_t) byte_idx; ++i) + pstr->offsets[i] = i; + pstr->offsets_needed = 1; + } + + memcpy (pstr->mbs + byte_idx, buf, mbcdlen); + pstr->wcs[byte_idx] = wcu; + pstr->offsets[byte_idx] = src_idx; + for (i = 1; i < mbcdlen; ++i) + { + pstr->offsets[byte_idx + i] + = src_idx + (i < mbclen ? i : mbclen - 1); + pstr->wcs[byte_idx + i] = WEOF; + } + pstr->len += mbcdlen - mbclen; + if (pstr->raw_stop > src_idx) + pstr->stop += mbcdlen - mbclen; + end_idx = (pstr->bufs_len > pstr->len) + ? pstr->len : pstr->bufs_len; + byte_idx += mbcdlen; + src_idx += mbclen; + continue; + } + else + memcpy (pstr->mbs + byte_idx, p, mbclen); + } + else + memcpy (pstr->mbs + byte_idx, p, mbclen); + + if (BE (pstr->offsets_needed != 0, 0)) + { + size_t i; + for (i = 0; i < mbclen; ++i) + pstr->offsets[byte_idx + i] = src_idx + i; + } + src_idx += mbclen; + + pstr->wcs[byte_idx++] = wcu; + /* Write paddings. */ + for (remain_len = byte_idx + mbclen - 1; byte_idx < remain_len ;) + pstr->wcs[byte_idx++] = WEOF; + } + else if (mbclen == (size_t) -1 || mbclen == 0) + { + /* It is an invalid character or '\0'. Just use the byte. */ + int ch = pstr->raw_mbs[pstr->raw_mbs_idx + src_idx]; + + if (BE (pstr->trans != NULL, 0)) + ch = pstr->trans [ch]; + pstr->mbs[byte_idx] = ch; + + if (BE (pstr->offsets_needed != 0, 0)) + pstr->offsets[byte_idx] = src_idx; + ++src_idx; + + /* And also cast it to wide char. */ + pstr->wcs[byte_idx++] = (wchar_t) ch; + if (BE (mbclen == (size_t) -1, 0)) + pstr->cur_state = prev_st; + } + else + { + /* The buffer doesn't have enough space, finish to build. */ + pstr->cur_state = prev_st; + break; + } + } + pstr->valid_len = byte_idx; + pstr->valid_raw_len = src_idx; + return REG_NOERROR; +} + +/* Skip characters until the index becomes greater than NEW_RAW_IDX. + Return the index. */ + +static Idx +internal_function +re_string_skip_chars (re_string_t *pstr, Idx new_raw_idx, wint_t *last_wc) +{ + mbstate_t prev_st; + Idx rawbuf_idx; + size_t mbclen; + wint_t wc = WEOF; + + /* Skip the characters which are not necessary to check. */ + for (rawbuf_idx = pstr->raw_mbs_idx + pstr->valid_raw_len; + rawbuf_idx < new_raw_idx;) + { + wchar_t wc2; + Idx remain_len; + remain_len = pstr->len - rawbuf_idx; + prev_st = pstr->cur_state; + mbclen = __mbrtowc (&wc2, (const char *) pstr->raw_mbs + rawbuf_idx, + remain_len, &pstr->cur_state); + if (BE (mbclen == (size_t) -2 || mbclen == (size_t) -1 || mbclen == 0, 0)) + { + /* We treat these cases as a single byte character. */ + if (mbclen == 0 || remain_len == 0) + wc = L'\0'; + else + wc = *(unsigned char *) (pstr->raw_mbs + rawbuf_idx); + mbclen = 1; + pstr->cur_state = prev_st; + } + else + wc = wc2; + /* Then proceed the next character. */ + rawbuf_idx += mbclen; + } + *last_wc = wc; + return rawbuf_idx; +} +#endif /* RE_ENABLE_I18N */ + +/* Build the buffer PSTR->MBS, and apply the translation if we need. + This function is used in case of REG_ICASE. */ + +static void +internal_function +build_upper_buffer (re_string_t *pstr) +{ + Idx char_idx, end_idx; + end_idx = (pstr->bufs_len > pstr->len) ? pstr->len : pstr->bufs_len; + + for (char_idx = pstr->valid_len; char_idx < end_idx; ++char_idx) + { + int ch = pstr->raw_mbs[pstr->raw_mbs_idx + char_idx]; + if (BE (pstr->trans != NULL, 0)) + ch = pstr->trans[ch]; + if (islower (ch)) + pstr->mbs[char_idx] = toupper (ch); + else + pstr->mbs[char_idx] = ch; + } + pstr->valid_len = char_idx; + pstr->valid_raw_len = char_idx; +} + +/* Apply TRANS to the buffer in PSTR. */ + +static void +internal_function +re_string_translate_buffer (re_string_t *pstr) +{ + Idx buf_idx, end_idx; + end_idx = (pstr->bufs_len > pstr->len) ? pstr->len : pstr->bufs_len; + + for (buf_idx = pstr->valid_len; buf_idx < end_idx; ++buf_idx) + { + int ch = pstr->raw_mbs[pstr->raw_mbs_idx + buf_idx]; + pstr->mbs[buf_idx] = pstr->trans[ch]; + } + + pstr->valid_len = buf_idx; + pstr->valid_raw_len = buf_idx; +} + +/* This function re-construct the buffers. + Concretely, convert to wide character in case of pstr->mb_cur_max > 1, + convert to upper case in case of REG_ICASE, apply translation. */ + +static reg_errcode_t +internal_function +re_string_reconstruct (re_string_t *pstr, Idx idx, int eflags) +{ + Idx offset; + + if (BE (pstr->raw_mbs_idx <= idx, 0)) + offset = idx - pstr->raw_mbs_idx; + else + { + /* Reset buffer. */ +#ifdef RE_ENABLE_I18N + if (pstr->mb_cur_max > 1) + memset (&pstr->cur_state, '\0', sizeof (mbstate_t)); +#endif /* RE_ENABLE_I18N */ + pstr->len = pstr->raw_len; + pstr->stop = pstr->raw_stop; + pstr->valid_len = 0; + pstr->raw_mbs_idx = 0; + pstr->valid_raw_len = 0; + pstr->offsets_needed = 0; + pstr->tip_context = ((eflags & REG_NOTBOL) ? CONTEXT_BEGBUF + : CONTEXT_NEWLINE | CONTEXT_BEGBUF); + if (!pstr->mbs_allocated) + pstr->mbs = (unsigned char *) pstr->raw_mbs; + offset = idx; + } + + if (BE (offset != 0, 1)) + { + /* Should the already checked characters be kept? */ + if (BE (offset < pstr->valid_raw_len, 1)) + { + /* Yes, move them to the front of the buffer. */ +#ifdef RE_ENABLE_I18N + if (BE (pstr->offsets_needed, 0)) + { + Idx low = 0, high = pstr->valid_len, mid; + do + { + mid = (high + low) / 2; + if (pstr->offsets[mid] > offset) + high = mid; + else if (pstr->offsets[mid] < offset) + low = mid + 1; + else + break; + } + while (low < high); + if (pstr->offsets[mid] < offset) + ++mid; + pstr->tip_context = re_string_context_at (pstr, mid - 1, + eflags); + /* This can be quite complicated, so handle specially + only the common and easy case where the character with + different length representation of lower and upper + case is present at or after offset. */ + if (pstr->valid_len > offset + && mid == offset && pstr->offsets[mid] == offset) + { + memmove (pstr->wcs, pstr->wcs + offset, + (pstr->valid_len - offset) * sizeof (wint_t)); + memmove (pstr->mbs, pstr->mbs + offset, pstr->valid_len - offset); + pstr->valid_len -= offset; + pstr->valid_raw_len -= offset; + for (low = 0; low < pstr->valid_len; low++) + pstr->offsets[low] = pstr->offsets[low + offset] - offset; + } + else + { + /* Otherwise, just find out how long the partial multibyte + character at offset is and fill it with WEOF/255. */ + pstr->len = pstr->raw_len - idx + offset; + pstr->stop = pstr->raw_stop - idx + offset; + pstr->offsets_needed = 0; + while (mid > 0 && pstr->offsets[mid - 1] == offset) + --mid; + while (mid < pstr->valid_len) + if (pstr->wcs[mid] != WEOF) + break; + else + ++mid; + if (mid == pstr->valid_len) + pstr->valid_len = 0; + else + { + pstr->valid_len = pstr->offsets[mid] - offset; + if (pstr->valid_len) + { + for (low = 0; low < pstr->valid_len; ++low) + pstr->wcs[low] = WEOF; + memset (pstr->mbs, 255, pstr->valid_len); + } + } + pstr->valid_raw_len = pstr->valid_len; + } + } + else +#endif + { + pstr->tip_context = re_string_context_at (pstr, offset - 1, + eflags); +#ifdef RE_ENABLE_I18N + if (pstr->mb_cur_max > 1) + memmove (pstr->wcs, pstr->wcs + offset, + (pstr->valid_len - offset) * sizeof (wint_t)); +#endif /* RE_ENABLE_I18N */ + if (BE (pstr->mbs_allocated, 0)) + memmove (pstr->mbs, pstr->mbs + offset, + pstr->valid_len - offset); + pstr->valid_len -= offset; + pstr->valid_raw_len -= offset; +#if DEBUG + assert (pstr->valid_len > 0); +#endif + } + } + else + { +#ifdef RE_ENABLE_I18N + /* No, skip all characters until IDX. */ + Idx prev_valid_len = pstr->valid_len; + + if (BE (pstr->offsets_needed, 0)) + { + pstr->len = pstr->raw_len - idx + offset; + pstr->stop = pstr->raw_stop - idx + offset; + pstr->offsets_needed = 0; + } +#endif + pstr->valid_len = 0; +#ifdef RE_ENABLE_I18N + if (pstr->mb_cur_max > 1) + { + Idx wcs_idx; + wint_t wc = WEOF; + + if (pstr->is_utf8) + { + const unsigned char *raw, *p, *end; + + /* Special case UTF-8. Multi-byte chars start with any + byte other than 0x80 - 0xbf. */ + raw = pstr->raw_mbs + pstr->raw_mbs_idx; + end = raw + (offset - pstr->mb_cur_max); + if (end < pstr->raw_mbs) + end = pstr->raw_mbs; + p = raw + offset - 1; +#ifdef _LIBC + /* We know the wchar_t encoding is UCS4, so for the simple + case, ASCII characters, skip the conversion step. */ + if (isascii (*p) && BE (pstr->trans == NULL, 1)) + { + memset (&pstr->cur_state, '\0', sizeof (mbstate_t)); + /* pstr->valid_len = 0; */ + wc = (wchar_t) *p; + } + else +#endif + for (; p >= end; --p) + if ((*p & 0xc0) != 0x80) + { + mbstate_t cur_state; + wchar_t wc2; + Idx mlen = raw + pstr->len - p; + unsigned char buf[6]; + size_t mbclen; + + if (BE (pstr->trans != NULL, 0)) + { + int i = mlen < 6 ? mlen : 6; + while (--i >= 0) + buf[i] = pstr->trans[p[i]]; + } + /* XXX Don't use mbrtowc, we know which conversion + to use (UTF-8 -> UCS4). */ + memset (&cur_state, 0, sizeof (cur_state)); + mbclen = __mbrtowc (&wc2, (const char *) p, mlen, + &cur_state); + if (raw + offset - p <= mbclen + && mbclen < (size_t) -2) + { + memset (&pstr->cur_state, '\0', + sizeof (mbstate_t)); + pstr->valid_len = mbclen - (raw + offset - p); + wc = wc2; + } + break; + } + } + + if (wc == WEOF) + pstr->valid_len = re_string_skip_chars (pstr, idx, &wc) - idx; + if (wc == WEOF) + pstr->tip_context + = re_string_context_at (pstr, prev_valid_len - 1, eflags); + else + pstr->tip_context = ((BE (pstr->word_ops_used != 0, 0) + && IS_WIDE_WORD_CHAR (wc)) + ? CONTEXT_WORD + : ((IS_WIDE_NEWLINE (wc) + && pstr->newline_anchor) + ? CONTEXT_NEWLINE : 0)); + if (BE (pstr->valid_len, 0)) + { + for (wcs_idx = 0; wcs_idx < pstr->valid_len; ++wcs_idx) + pstr->wcs[wcs_idx] = WEOF; + if (pstr->mbs_allocated) + memset (pstr->mbs, 255, pstr->valid_len); + } + pstr->valid_raw_len = pstr->valid_len; + } + else +#endif /* RE_ENABLE_I18N */ + { + int c = pstr->raw_mbs[pstr->raw_mbs_idx + offset - 1]; + pstr->valid_raw_len = 0; + if (pstr->trans) + c = pstr->trans[c]; + pstr->tip_context = (bitset_contain (pstr->word_char, c) + ? CONTEXT_WORD + : ((IS_NEWLINE (c) && pstr->newline_anchor) + ? CONTEXT_NEWLINE : 0)); + } + } + if (!BE (pstr->mbs_allocated, 0)) + pstr->mbs += offset; + } + pstr->raw_mbs_idx = idx; + pstr->len -= offset; + pstr->stop -= offset; + + /* Then build the buffers. */ +#ifdef RE_ENABLE_I18N + if (pstr->mb_cur_max > 1) + { + if (pstr->icase) + { + reg_errcode_t ret = build_wcs_upper_buffer (pstr); + if (BE (ret != REG_NOERROR, 0)) + return ret; + } + else + build_wcs_buffer (pstr); + } + else +#endif /* RE_ENABLE_I18N */ + if (BE (pstr->mbs_allocated, 0)) + { + if (pstr->icase) + build_upper_buffer (pstr); + else if (pstr->trans != NULL) + re_string_translate_buffer (pstr); + } + else + pstr->valid_len = pstr->len; + + pstr->cur_idx = 0; + return REG_NOERROR; +} + +static unsigned char +internal_function __attribute ((pure)) +re_string_peek_byte_case (const re_string_t *pstr, Idx idx) +{ + int ch; + Idx off; + + /* Handle the common (easiest) cases first. */ + if (BE (!pstr->mbs_allocated, 1)) + return re_string_peek_byte (pstr, idx); + +#ifdef RE_ENABLE_I18N + if (pstr->mb_cur_max > 1 + && ! re_string_is_single_byte_char (pstr, pstr->cur_idx + idx)) + return re_string_peek_byte (pstr, idx); +#endif + + off = pstr->cur_idx + idx; +#ifdef RE_ENABLE_I18N + if (pstr->offsets_needed) + off = pstr->offsets[off]; +#endif + + ch = pstr->raw_mbs[pstr->raw_mbs_idx + off]; + +#ifdef RE_ENABLE_I18N + /* Ensure that e.g. for tr_TR.UTF-8 BACKSLASH DOTLESS SMALL LETTER I + this function returns CAPITAL LETTER I instead of first byte of + DOTLESS SMALL LETTER I. The latter would confuse the parser, + since peek_byte_case doesn't advance cur_idx in any way. */ + if (pstr->offsets_needed && !isascii (ch)) + return re_string_peek_byte (pstr, idx); +#endif + + return ch; +} + +static unsigned char +internal_function __attribute ((pure)) +re_string_fetch_byte_case (re_string_t *pstr) +{ + if (BE (!pstr->mbs_allocated, 1)) + return re_string_fetch_byte (pstr); + +#ifdef RE_ENABLE_I18N + if (pstr->offsets_needed) + { + Idx off; + int ch; + + /* For tr_TR.UTF-8 [[:islower:]] there is + [[: CAPITAL LETTER I WITH DOT lower:]] in mbs. Skip + in that case the whole multi-byte character and return + the original letter. On the other side, with + [[: DOTLESS SMALL LETTER I return [[:I, as doing + anything else would complicate things too much. */ + + if (!re_string_first_byte (pstr, pstr->cur_idx)) + return re_string_fetch_byte (pstr); + + off = pstr->offsets[pstr->cur_idx]; + ch = pstr->raw_mbs[pstr->raw_mbs_idx + off]; + + if (! isascii (ch)) + return re_string_fetch_byte (pstr); + + re_string_skip_bytes (pstr, + re_string_char_size_at (pstr, pstr->cur_idx)); + return ch; + } +#endif + + return pstr->raw_mbs[pstr->raw_mbs_idx + pstr->cur_idx++]; +} + +static void +internal_function +re_string_destruct (re_string_t *pstr) +{ +#ifdef RE_ENABLE_I18N + re_free (pstr->wcs); + re_free (pstr->offsets); +#endif /* RE_ENABLE_I18N */ + if (pstr->mbs_allocated) + re_free (pstr->mbs); +} + +/* Return the context at IDX in INPUT. */ + +static unsigned int +internal_function +re_string_context_at (const re_string_t *input, Idx idx, int eflags) +{ + int c; + if (BE (! REG_VALID_INDEX (idx), 0)) + /* In this case, we use the value stored in input->tip_context, + since we can't know the character in input->mbs[-1] here. */ + return input->tip_context; + if (BE (idx == input->len, 0)) + return ((eflags & REG_NOTEOL) ? CONTEXT_ENDBUF + : CONTEXT_NEWLINE | CONTEXT_ENDBUF); +#ifdef RE_ENABLE_I18N + if (input->mb_cur_max > 1) + { + wint_t wc; + Idx wc_idx = idx; + while(input->wcs[wc_idx] == WEOF) + { +#ifdef DEBUG + /* It must not happen. */ + assert (REG_VALID_INDEX (wc_idx)); +#endif + --wc_idx; + if (! REG_VALID_INDEX (wc_idx)) + return input->tip_context; + } + wc = input->wcs[wc_idx]; + if (BE (input->word_ops_used != 0, 0) && IS_WIDE_WORD_CHAR (wc)) + return CONTEXT_WORD; + return (IS_WIDE_NEWLINE (wc) && input->newline_anchor + ? CONTEXT_NEWLINE : 0); + } + else +#endif + { + c = re_string_byte_at (input, idx); + if (bitset_contain (input->word_char, c)) + return CONTEXT_WORD; + return IS_NEWLINE (c) && input->newline_anchor ? CONTEXT_NEWLINE : 0; + } +} + +/* Functions for set operation. */ + +static reg_errcode_t +internal_function +re_node_set_alloc (re_node_set *set, Idx size) +{ + set->alloc = size; + set->nelem = 0; + set->elems = re_malloc (Idx, size); + if (BE (set->elems == NULL, 0)) + return REG_ESPACE; + return REG_NOERROR; +} + +static reg_errcode_t +internal_function +re_node_set_init_1 (re_node_set *set, Idx elem) +{ + set->alloc = 1; + set->nelem = 1; + set->elems = re_malloc (Idx, 1); + if (BE (set->elems == NULL, 0)) + { + set->alloc = set->nelem = 0; + return REG_ESPACE; + } + set->elems[0] = elem; + return REG_NOERROR; +} + +static reg_errcode_t +internal_function +re_node_set_init_2 (re_node_set *set, Idx elem1, Idx elem2) +{ + set->alloc = 2; + set->elems = re_malloc (Idx, 2); + if (BE (set->elems == NULL, 0)) + return REG_ESPACE; + if (elem1 == elem2) + { + set->nelem = 1; + set->elems[0] = elem1; + } + else + { + set->nelem = 2; + if (elem1 < elem2) + { + set->elems[0] = elem1; + set->elems[1] = elem2; + } + else + { + set->elems[0] = elem2; + set->elems[1] = elem1; + } + } + return REG_NOERROR; +} + +static reg_errcode_t +internal_function +re_node_set_init_copy (re_node_set *dest, const re_node_set *src) +{ + dest->nelem = src->nelem; + if (src->nelem > 0) + { + dest->alloc = dest->nelem; + dest->elems = re_malloc (Idx, dest->alloc); + if (BE (dest->elems == NULL, 0)) + { + dest->alloc = dest->nelem = 0; + return REG_ESPACE; + } + memcpy (dest->elems, src->elems, src->nelem * sizeof (Idx)); + } + else + re_node_set_init_empty (dest); + return REG_NOERROR; +} + +/* Calculate the intersection of the sets SRC1 and SRC2. And merge it to + DEST. Return value indicate the error code or REG_NOERROR if succeeded. + Note: We assume dest->elems is NULL, when dest->alloc is 0. */ + +static reg_errcode_t +internal_function +re_node_set_add_intersect (re_node_set *dest, const re_node_set *src1, + const re_node_set *src2) +{ + Idx i1, i2, is, id, delta, sbase; + if (src1->nelem == 0 || src2->nelem == 0) + return REG_NOERROR; + + /* We need dest->nelem + 2 * elems_in_intersection; this is a + conservative estimate. */ + if (src1->nelem + src2->nelem + dest->nelem > dest->alloc) + { + Idx new_alloc = src1->nelem + src2->nelem + dest->alloc; + Idx *new_elems = re_realloc (dest->elems, Idx, new_alloc); + if (BE (new_elems == NULL, 0)) + return REG_ESPACE; + dest->elems = new_elems; + dest->alloc = new_alloc; + } + + /* Find the items in the intersection of SRC1 and SRC2, and copy + into the top of DEST those that are not already in DEST itself. */ + sbase = dest->nelem + src1->nelem + src2->nelem; + i1 = src1->nelem - 1; + i2 = src2->nelem - 1; + id = dest->nelem - 1; + for (;;) + { + if (src1->elems[i1] == src2->elems[i2]) + { + /* Try to find the item in DEST. Maybe we could binary search? */ + while (REG_VALID_INDEX (id) && dest->elems[id] > src1->elems[i1]) + --id; + + if (! REG_VALID_INDEX (id) || dest->elems[id] != src1->elems[i1]) + dest->elems[--sbase] = src1->elems[i1]; + + if (! REG_VALID_INDEX (--i1) || ! REG_VALID_INDEX (--i2)) + break; + } + + /* Lower the highest of the two items. */ + else if (src1->elems[i1] < src2->elems[i2]) + { + if (! REG_VALID_INDEX (--i2)) + break; + } + else + { + if (! REG_VALID_INDEX (--i1)) + break; + } + } + + id = dest->nelem - 1; + is = dest->nelem + src1->nelem + src2->nelem - 1; + delta = is - sbase + 1; + + /* Now copy. When DELTA becomes zero, the remaining + DEST elements are already in place; this is more or + less the same loop that is in re_node_set_merge. */ + dest->nelem += delta; + if (delta > 0 && REG_VALID_INDEX (id)) + for (;;) + { + if (dest->elems[is] > dest->elems[id]) + { + /* Copy from the top. */ + dest->elems[id + delta--] = dest->elems[is--]; + if (delta == 0) + break; + } + else + { + /* Slide from the bottom. */ + dest->elems[id + delta] = dest->elems[id]; + if (! REG_VALID_INDEX (--id)) + break; + } + } + + /* Copy remaining SRC elements. */ + memcpy (dest->elems, dest->elems + sbase, delta * sizeof (Idx)); + + return REG_NOERROR; +} + +/* Calculate the union set of the sets SRC1 and SRC2. And store it to + DEST. Return value indicate the error code or REG_NOERROR if succeeded. */ + +static reg_errcode_t +internal_function +re_node_set_init_union (re_node_set *dest, const re_node_set *src1, + const re_node_set *src2) +{ + Idx i1, i2, id; + if (src1 != NULL && src1->nelem > 0 && src2 != NULL && src2->nelem > 0) + { + dest->alloc = src1->nelem + src2->nelem; + dest->elems = re_malloc (Idx, dest->alloc); + if (BE (dest->elems == NULL, 0)) + return REG_ESPACE; + } + else + { + if (src1 != NULL && src1->nelem > 0) + return re_node_set_init_copy (dest, src1); + else if (src2 != NULL && src2->nelem > 0) + return re_node_set_init_copy (dest, src2); + else + re_node_set_init_empty (dest); + return REG_NOERROR; + } + for (i1 = i2 = id = 0 ; i1 < src1->nelem && i2 < src2->nelem ;) + { + if (src1->elems[i1] > src2->elems[i2]) + { + dest->elems[id++] = src2->elems[i2++]; + continue; + } + if (src1->elems[i1] == src2->elems[i2]) + ++i2; + dest->elems[id++] = src1->elems[i1++]; + } + if (i1 < src1->nelem) + { + memcpy (dest->elems + id, src1->elems + i1, + (src1->nelem - i1) * sizeof (Idx)); + id += src1->nelem - i1; + } + else if (i2 < src2->nelem) + { + memcpy (dest->elems + id, src2->elems + i2, + (src2->nelem - i2) * sizeof (Idx)); + id += src2->nelem - i2; + } + dest->nelem = id; + return REG_NOERROR; +} + +/* Calculate the union set of the sets DEST and SRC. And store it to + DEST. Return value indicate the error code or REG_NOERROR if succeeded. */ + +static reg_errcode_t +internal_function +re_node_set_merge (re_node_set *dest, const re_node_set *src) +{ + Idx is, id, sbase, delta; + if (src == NULL || src->nelem == 0) + return REG_NOERROR; + if (dest->alloc < 2 * src->nelem + dest->nelem) + { + Idx new_alloc = 2 * (src->nelem + dest->alloc); + Idx *new_buffer = re_realloc (dest->elems, Idx, new_alloc); + if (BE (new_buffer == NULL, 0)) + return REG_ESPACE; + dest->elems = new_buffer; + dest->alloc = new_alloc; + } + + if (BE (dest->nelem == 0, 0)) + { + dest->nelem = src->nelem; + memcpy (dest->elems, src->elems, src->nelem * sizeof (Idx)); + return REG_NOERROR; + } + + /* Copy into the top of DEST the items of SRC that are not + found in DEST. Maybe we could binary search in DEST? */ + for (sbase = dest->nelem + 2 * src->nelem, + is = src->nelem - 1, id = dest->nelem - 1; + REG_VALID_INDEX (is) && REG_VALID_INDEX (id); ) + { + if (dest->elems[id] == src->elems[is]) + is--, id--; + else if (dest->elems[id] < src->elems[is]) + dest->elems[--sbase] = src->elems[is--]; + else /* if (dest->elems[id] > src->elems[is]) */ + --id; + } + + if (REG_VALID_INDEX (is)) + { + /* If DEST is exhausted, the remaining items of SRC must be unique. */ + sbase -= is + 1; + memcpy (dest->elems + sbase, src->elems, (is + 1) * sizeof (Idx)); + } + + id = dest->nelem - 1; + is = dest->nelem + 2 * src->nelem - 1; + delta = is - sbase + 1; + if (delta == 0) + return REG_NOERROR; + + /* Now copy. When DELTA becomes zero, the remaining + DEST elements are already in place. */ + dest->nelem += delta; + for (;;) + { + if (dest->elems[is] > dest->elems[id]) + { + /* Copy from the top. */ + dest->elems[id + delta--] = dest->elems[is--]; + if (delta == 0) + break; + } + else + { + /* Slide from the bottom. */ + dest->elems[id + delta] = dest->elems[id]; + if (! REG_VALID_INDEX (--id)) + { + /* Copy remaining SRC elements. */ + memcpy (dest->elems, dest->elems + sbase, + delta * sizeof (Idx)); + break; + } + } + } + + return REG_NOERROR; +} + +/* Insert the new element ELEM to the re_node_set* SET. + SET should not already have ELEM. + Return true if successful. */ + +static bool +internal_function +re_node_set_insert (re_node_set *set, Idx elem) +{ + Idx idx; + /* In case the set is empty. */ + if (set->alloc == 0) + return BE (re_node_set_init_1 (set, elem) == REG_NOERROR, 1); + + if (BE (set->nelem, 0) == 0) + { + /* We already guaranteed above that set->alloc != 0. */ + set->elems[0] = elem; + ++set->nelem; + return true; + } + + /* Realloc if we need. */ + if (set->alloc == set->nelem) + { + Idx *new_elems; + set->alloc = set->alloc * 2; + new_elems = re_realloc (set->elems, Idx, set->alloc); + if (BE (new_elems == NULL, 0)) + return false; + set->elems = new_elems; + } + + /* Move the elements which follows the new element. Test the + first element separately to skip a check in the inner loop. */ + if (elem < set->elems[0]) + { + idx = 0; + for (idx = set->nelem; idx > 0; idx--) + set->elems[idx] = set->elems[idx - 1]; + } + else + { + for (idx = set->nelem; set->elems[idx - 1] > elem; idx--) + set->elems[idx] = set->elems[idx - 1]; + } + + /* Insert the new element. */ + set->elems[idx] = elem; + ++set->nelem; + return true; +} + +/* Insert the new element ELEM to the re_node_set* SET. + SET should not already have any element greater than or equal to ELEM. + Return true if successful. */ + +static bool +internal_function +re_node_set_insert_last (re_node_set *set, Idx elem) +{ + /* Realloc if we need. */ + if (set->alloc == set->nelem) + { + Idx *new_elems; + set->alloc = (set->alloc + 1) * 2; + new_elems = re_realloc (set->elems, Idx, set->alloc); + if (BE (new_elems == NULL, 0)) + return false; + set->elems = new_elems; + } + + /* Insert the new element. */ + set->elems[set->nelem++] = elem; + return true; +} + +/* Compare two node sets SET1 and SET2. + Return true if SET1 and SET2 are equivalent. */ + +static bool +internal_function __attribute ((pure)) +re_node_set_compare (const re_node_set *set1, const re_node_set *set2) +{ + Idx i; + if (set1 == NULL || set2 == NULL || set1->nelem != set2->nelem) + return false; + for (i = set1->nelem ; REG_VALID_INDEX (--i) ; ) + if (set1->elems[i] != set2->elems[i]) + return false; + return true; +} + +/* Return (idx + 1) if SET contains the element ELEM, return 0 otherwise. */ + +static Idx +internal_function __attribute ((pure)) +re_node_set_contains (const re_node_set *set, Idx elem) +{ + __re_size_t idx, right, mid; + if (! REG_VALID_NONZERO_INDEX (set->nelem)) + return 0; + + /* Binary search the element. */ + idx = 0; + right = set->nelem - 1; + while (idx < right) + { + mid = (idx + right) / 2; + if (set->elems[mid] < elem) + idx = mid + 1; + else + right = mid; + } + return set->elems[idx] == elem ? idx + 1 : 0; +} + +static void +internal_function +re_node_set_remove_at (re_node_set *set, Idx idx) +{ + if (idx < 0 || idx >= set->nelem) + return; + --set->nelem; + for (; idx < set->nelem; idx++) + set->elems[idx] = set->elems[idx + 1]; +} + + +/* Add the token TOKEN to dfa->nodes, and return the index of the token. + Or return REG_MISSING if an error occurred. */ + +static Idx +internal_function +re_dfa_add_node (re_dfa_t *dfa, re_token_t token) +{ + if (BE (dfa->nodes_len >= dfa->nodes_alloc, 0)) + { + size_t new_nodes_alloc = dfa->nodes_alloc * 2; + Idx *new_nexts, *new_indices; + re_node_set *new_edests, *new_eclosures; + re_token_t *new_nodes; + size_t max_object_size = + MAX (sizeof (re_token_t), + MAX (sizeof (re_node_set), + sizeof (Idx))); + + /* Avoid overflows. */ + if (BE (SIZE_MAX / 2 / max_object_size < dfa->nodes_alloc, 0)) + return REG_MISSING; + + new_nodes = re_realloc (dfa->nodes, re_token_t, new_nodes_alloc); + if (BE (new_nodes == NULL, 0)) + return REG_MISSING; + dfa->nodes = new_nodes; + new_nexts = re_realloc (dfa->nexts, Idx, new_nodes_alloc); + new_indices = re_realloc (dfa->org_indices, Idx, new_nodes_alloc); + new_edests = re_realloc (dfa->edests, re_node_set, new_nodes_alloc); + new_eclosures = re_realloc (dfa->eclosures, re_node_set, new_nodes_alloc); + if (BE (new_nexts == NULL || new_indices == NULL + || new_edests == NULL || new_eclosures == NULL, 0)) + return REG_MISSING; + dfa->nexts = new_nexts; + dfa->org_indices = new_indices; + dfa->edests = new_edests; + dfa->eclosures = new_eclosures; + dfa->nodes_alloc = new_nodes_alloc; + } + dfa->nodes[dfa->nodes_len] = token; + dfa->nodes[dfa->nodes_len].constraint = 0; +#ifdef RE_ENABLE_I18N + { + int type = token.type; + dfa->nodes[dfa->nodes_len].accept_mb = + (type == OP_PERIOD && dfa->mb_cur_max > 1) || type == COMPLEX_BRACKET; + } +#endif + dfa->nexts[dfa->nodes_len] = REG_MISSING; + re_node_set_init_empty (dfa->edests + dfa->nodes_len); + re_node_set_init_empty (dfa->eclosures + dfa->nodes_len); + return dfa->nodes_len++; +} + +static inline re_hashval_t +internal_function +calc_state_hash (const re_node_set *nodes, unsigned int context) +{ + re_hashval_t hash = nodes->nelem + context; + Idx i; + for (i = 0 ; i < nodes->nelem ; i++) + hash += nodes->elems[i]; + return hash; +} + +/* Search for the state whose node_set is equivalent to NODES. + Return the pointer to the state, if we found it in the DFA. + Otherwise create the new one and return it. In case of an error + return NULL and set the error code in ERR. + Note: - We assume NULL as the invalid state, then it is possible that + return value is NULL and ERR is REG_NOERROR. + - We never return non-NULL value in case of any errors, it is for + optimization. */ + +static re_dfastate_t * +internal_function +re_acquire_state (reg_errcode_t *err, const re_dfa_t *dfa, + const re_node_set *nodes) +{ + re_hashval_t hash; + re_dfastate_t *new_state; + struct re_state_table_entry *spot; + Idx i; +#ifdef lint + /* Suppress bogus uninitialized-variable warnings. */ + *err = REG_NOERROR; +#endif + if (BE (nodes->nelem == 0, 0)) + { + *err = REG_NOERROR; + return NULL; + } + hash = calc_state_hash (nodes, 0); + spot = dfa->state_table + (hash & dfa->state_hash_mask); + + for (i = 0 ; i < spot->num ; i++) + { + re_dfastate_t *state = spot->array[i]; + if (hash != state->hash) + continue; + if (re_node_set_compare (&state->nodes, nodes)) + return state; + } + + /* There are no appropriate state in the dfa, create the new one. */ + new_state = create_ci_newstate (dfa, nodes, hash); + if (BE (new_state == NULL, 0)) + *err = REG_ESPACE; + + return new_state; +} + +/* Search for the state whose node_set is equivalent to NODES and + whose context is equivalent to CONTEXT. + Return the pointer to the state, if we found it in the DFA. + Otherwise create the new one and return it. In case of an error + return NULL and set the error code in ERR. + Note: - We assume NULL as the invalid state, then it is possible that + return value is NULL and ERR is REG_NOERROR. + - We never return non-NULL value in case of any errors, it is for + optimization. */ + +static re_dfastate_t * +internal_function +re_acquire_state_context (reg_errcode_t *err, const re_dfa_t *dfa, + const re_node_set *nodes, unsigned int context) +{ + re_hashval_t hash; + re_dfastate_t *new_state; + struct re_state_table_entry *spot; + Idx i; +#ifdef lint + /* Suppress bogus uninitialized-variable warnings. */ + *err = REG_NOERROR; +#endif + if (nodes->nelem == 0) + { + *err = REG_NOERROR; + return NULL; + } + hash = calc_state_hash (nodes, context); + spot = dfa->state_table + (hash & dfa->state_hash_mask); + + for (i = 0 ; i < spot->num ; i++) + { + re_dfastate_t *state = spot->array[i]; + if (state->hash == hash + && state->context == context + && re_node_set_compare (state->entrance_nodes, nodes)) + return state; + } + /* There are no appropriate state in `dfa', create the new one. */ + new_state = create_cd_newstate (dfa, nodes, context, hash); + if (BE (new_state == NULL, 0)) + *err = REG_ESPACE; + + return new_state; +} + +/* Finish initialization of the new state NEWSTATE, and using its hash value + HASH put in the appropriate bucket of DFA's state table. Return value + indicates the error code if failed. */ + +static reg_errcode_t +register_state (const re_dfa_t *dfa, re_dfastate_t *newstate, + re_hashval_t hash) +{ + struct re_state_table_entry *spot; + reg_errcode_t err; + Idx i; + + newstate->hash = hash; + err = re_node_set_alloc (&newstate->non_eps_nodes, newstate->nodes.nelem); + if (BE (err != REG_NOERROR, 0)) + return REG_ESPACE; + for (i = 0; i < newstate->nodes.nelem; i++) + { + Idx elem = newstate->nodes.elems[i]; + if (!IS_EPSILON_NODE (dfa->nodes[elem].type)) + if (BE (! re_node_set_insert_last (&newstate->non_eps_nodes, elem), 0)) + return REG_ESPACE; + } + + spot = dfa->state_table + (hash & dfa->state_hash_mask); + if (BE (spot->alloc <= spot->num, 0)) + { + Idx new_alloc = 2 * spot->num + 2; + re_dfastate_t **new_array = re_realloc (spot->array, re_dfastate_t *, + new_alloc); + if (BE (new_array == NULL, 0)) + return REG_ESPACE; + spot->array = new_array; + spot->alloc = new_alloc; + } + spot->array[spot->num++] = newstate; + return REG_NOERROR; +} + +static void +free_state (re_dfastate_t *state) +{ + re_node_set_free (&state->non_eps_nodes); + re_node_set_free (&state->inveclosure); + if (state->entrance_nodes != &state->nodes) + { + re_node_set_free (state->entrance_nodes); + re_free (state->entrance_nodes); + } + re_node_set_free (&state->nodes); + re_free (state->word_trtable); + re_free (state->trtable); + re_free (state); +} + +/* Create the new state which is independ of contexts. + Return the new state if succeeded, otherwise return NULL. */ + +static re_dfastate_t * +internal_function +create_ci_newstate (const re_dfa_t *dfa, const re_node_set *nodes, + re_hashval_t hash) +{ + Idx i; + reg_errcode_t err; + re_dfastate_t *newstate; + + newstate = (re_dfastate_t *) calloc (sizeof (re_dfastate_t), 1); + if (BE (newstate == NULL, 0)) + return NULL; + err = re_node_set_init_copy (&newstate->nodes, nodes); + if (BE (err != REG_NOERROR, 0)) + { + re_free (newstate); + return NULL; + } + + newstate->entrance_nodes = &newstate->nodes; + for (i = 0 ; i < nodes->nelem ; i++) + { + re_token_t *node = dfa->nodes + nodes->elems[i]; + re_token_type_t type = node->type; + if (type == CHARACTER && !node->constraint) + continue; +#ifdef RE_ENABLE_I18N + newstate->accept_mb |= node->accept_mb; +#endif /* RE_ENABLE_I18N */ + + /* If the state has the halt node, the state is a halt state. */ + if (type == END_OF_RE) + newstate->halt = 1; + else if (type == OP_BACK_REF) + newstate->has_backref = 1; + else if (type == ANCHOR || node->constraint) + newstate->has_constraint = 1; + } + err = register_state (dfa, newstate, hash); + if (BE (err != REG_NOERROR, 0)) + { + free_state (newstate); + newstate = NULL; + } + return newstate; +} + +/* Create the new state which is depend on the context CONTEXT. + Return the new state if succeeded, otherwise return NULL. */ + +static re_dfastate_t * +internal_function +create_cd_newstate (const re_dfa_t *dfa, const re_node_set *nodes, + unsigned int context, re_hashval_t hash) +{ + Idx i, nctx_nodes = 0; + reg_errcode_t err; + re_dfastate_t *newstate; + + newstate = (re_dfastate_t *) calloc (sizeof (re_dfastate_t), 1); + if (BE (newstate == NULL, 0)) + return NULL; + err = re_node_set_init_copy (&newstate->nodes, nodes); + if (BE (err != REG_NOERROR, 0)) + { + re_free (newstate); + return NULL; + } + + newstate->context = context; + newstate->entrance_nodes = &newstate->nodes; + + for (i = 0 ; i < nodes->nelem ; i++) + { + re_token_t *node = dfa->nodes + nodes->elems[i]; + re_token_type_t type = node->type; + unsigned int constraint = node->constraint; + + if (type == CHARACTER && !constraint) + continue; +#ifdef RE_ENABLE_I18N + newstate->accept_mb |= node->accept_mb; +#endif /* RE_ENABLE_I18N */ + + /* If the state has the halt node, the state is a halt state. */ + if (type == END_OF_RE) + newstate->halt = 1; + else if (type == OP_BACK_REF) + newstate->has_backref = 1; + + if (constraint) + { + if (newstate->entrance_nodes == &newstate->nodes) + { + newstate->entrance_nodes = re_malloc (re_node_set, 1); + if (BE (newstate->entrance_nodes == NULL, 0)) + { + free_state (newstate); + return NULL; + } + re_node_set_init_copy (newstate->entrance_nodes, nodes); + nctx_nodes = 0; + newstate->has_constraint = 1; + } + + if (NOT_SATISFY_PREV_CONSTRAINT (constraint,context)) + { + re_node_set_remove_at (&newstate->nodes, i - nctx_nodes); + ++nctx_nodes; + } + } + } + err = register_state (dfa, newstate, hash); + if (BE (err != REG_NOERROR, 0)) + { + free_state (newstate); + newstate = NULL; + } + return newstate; +} diff --git a/gnulib/regex_internal.h b/gnulib/regex_internal.h new file mode 100644 index 000000000..977f8b02c --- /dev/null +++ b/gnulib/regex_internal.h @@ -0,0 +1,828 @@ +/* Extended regular expression matching and search library. + Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 + Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Isamu Hasegawa . + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef _REGEX_INTERNAL_H +#define _REGEX_INTERNAL_H 1 + +/* In case that the system doesn't have isblank(). */ +#if !defined _LIBC && ! (defined isblank || (HAVE_ISBLANK && HAVE_DECL_ISBLANK)) +# define isblank(ch) ((ch) == ' ' || (ch) == '\t') +#endif + +#ifdef _LIBC +# ifndef _RE_DEFINE_LOCALE_FUNCTIONS +# define _RE_DEFINE_LOCALE_FUNCTIONS 1 +# include +# include +# include +# endif +#endif + +/* This is for other GNU distributions with internationalized messages. */ +#if (HAVE_LIBINTL_H && ENABLE_NLS) || defined _LIBC +# include +# ifdef _LIBC +# undef gettext +# define gettext(msgid) \ + INTUSE(__dcgettext) (_libc_intl_domainname, msgid, LC_MESSAGES) +# endif +#else +# define gettext(msgid) (msgid) +#endif + +#ifndef gettext_noop +/* This define is so xgettext can find the internationalizable + strings. */ +# define gettext_noop(String) String +#endif + +/* For loser systems without the definition. */ +#ifndef SIZE_MAX +# define SIZE_MAX ((size_t) -1) +#endif + +#if (defined MB_CUR_MAX && HAVE_LOCALE_H && HAVE_WCTYPE_H && HAVE_ISWCTYPE && HAVE_WCSCOLL) || _LIBC +# define RE_ENABLE_I18N +#endif + +#if __GNUC__ >= 3 +# define BE(expr, val) __builtin_expect (expr, val) +#else +# define BE(expr, val) (expr) +# ifdef _LIBC +# define inline +# endif +#endif + +/* Number of ASCII characters. */ +#define ASCII_CHARS 0x80 + +/* Number of single byte characters. */ +#define SBC_MAX (UCHAR_MAX + 1) + +#define COLL_ELEM_LEN_MAX 8 + +/* The character which represents newline. */ +#define NEWLINE_CHAR '\n' +#define WIDE_NEWLINE_CHAR L'\n' + +/* Rename to standard API for using out of glibc. */ +#ifndef _LIBC +# define __wctype wctype +# define __iswctype iswctype +# define __btowc btowc +# define __wcrtomb wcrtomb +# define __mbrtowc mbrtowc +# define __regfree regfree +# define attribute_hidden +#endif /* not _LIBC */ + +#if __GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1) +# define __attribute(arg) __attribute__ (arg) +#else +# define __attribute(arg) +#endif + +typedef __re_idx_t Idx; + +/* Special return value for failure to match. */ +#define REG_MISSING ((Idx) -1) + +/* Special return value for internal error. */ +#define REG_ERROR ((Idx) -2) + +/* Test whether N is a valid index, and is not one of the above. */ +#ifdef _REGEX_LARGE_OFFSETS +# define REG_VALID_INDEX(n) ((Idx) (n) < REG_ERROR) +#else +# define REG_VALID_INDEX(n) (0 <= (n)) +#endif + +/* Test whether N is a valid nonzero index. */ +#ifdef _REGEX_LARGE_OFFSETS +# define REG_VALID_NONZERO_INDEX(n) ((Idx) ((n) - 1) < (Idx) (REG_ERROR - 1)) +#else +# define REG_VALID_NONZERO_INDEX(n) (0 < (n)) +#endif + +/* A hash value, suitable for computing hash tables. */ +typedef __re_size_t re_hashval_t; + +/* An integer used to represent a set of bits. It must be unsigned, + and must be at least as wide as unsigned int. */ +typedef unsigned long int bitset_word_t; +/* All bits set in a bitset_word_t. */ +#define BITSET_WORD_MAX ULONG_MAX + +/* Number of bits in a bitset_word_t. For portability to hosts with + padding bits, do not use '(sizeof (bitset_word_t) * CHAR_BIT)'; + instead, deduce it directly from BITSET_WORD_MAX. Avoid + greater-than-32-bit integers and unconditional shifts by more than + 31 bits, as they're not portable. */ +#if BITSET_WORD_MAX == 0xffffffffUL +# define BITSET_WORD_BITS 32 +#elif BITSET_WORD_MAX >> 31 >> 4 == 1 +# define BITSET_WORD_BITS 36 +#elif BITSET_WORD_MAX >> 31 >> 16 == 1 +# define BITSET_WORD_BITS 48 +#elif BITSET_WORD_MAX >> 31 >> 28 == 1 +# define BITSET_WORD_BITS 60 +#elif BITSET_WORD_MAX >> 31 >> 31 >> 1 == 1 +# define BITSET_WORD_BITS 64 +#elif BITSET_WORD_MAX >> 31 >> 31 >> 9 == 1 +# define BITSET_WORD_BITS 72 +#elif BITSET_WORD_MAX >> 31 >> 31 >> 31 >> 31 >> 3 == 1 +# define BITSET_WORD_BITS 128 +#elif BITSET_WORD_MAX >> 31 >> 31 >> 31 >> 31 >> 31 >> 31 >> 31 >> 31 >> 7 == 1 +# define BITSET_WORD_BITS 256 +#elif BITSET_WORD_MAX >> 31 >> 31 >> 31 >> 31 >> 31 >> 31 >> 31 >> 31 >> 7 > 1 +# define BITSET_WORD_BITS 257 /* any value > SBC_MAX will do here */ +# if BITSET_WORD_BITS <= SBC_MAX +# error "Invalid SBC_MAX" +# endif +#else +# error "Add case for new bitset_word_t size" +#endif + +/* Number of bitset_word_t values in a bitset_t. */ +#define BITSET_WORDS ((SBC_MAX + BITSET_WORD_BITS - 1) / BITSET_WORD_BITS) + +typedef bitset_word_t bitset_t[BITSET_WORDS]; +typedef bitset_word_t *re_bitset_ptr_t; +typedef const bitset_word_t *re_const_bitset_ptr_t; + +#define PREV_WORD_CONSTRAINT 0x0001 +#define PREV_NOTWORD_CONSTRAINT 0x0002 +#define NEXT_WORD_CONSTRAINT 0x0004 +#define NEXT_NOTWORD_CONSTRAINT 0x0008 +#define PREV_NEWLINE_CONSTRAINT 0x0010 +#define NEXT_NEWLINE_CONSTRAINT 0x0020 +#define PREV_BEGBUF_CONSTRAINT 0x0040 +#define NEXT_ENDBUF_CONSTRAINT 0x0080 +#define WORD_DELIM_CONSTRAINT 0x0100 +#define NOT_WORD_DELIM_CONSTRAINT 0x0200 + +typedef enum +{ + INSIDE_WORD = PREV_WORD_CONSTRAINT | NEXT_WORD_CONSTRAINT, + WORD_FIRST = PREV_NOTWORD_CONSTRAINT | NEXT_WORD_CONSTRAINT, + WORD_LAST = PREV_WORD_CONSTRAINT | NEXT_NOTWORD_CONSTRAINT, + INSIDE_NOTWORD = PREV_NOTWORD_CONSTRAINT | NEXT_NOTWORD_CONSTRAINT, + LINE_FIRST = PREV_NEWLINE_CONSTRAINT, + LINE_LAST = NEXT_NEWLINE_CONSTRAINT, + BUF_FIRST = PREV_BEGBUF_CONSTRAINT, + BUF_LAST = NEXT_ENDBUF_CONSTRAINT, + WORD_DELIM = WORD_DELIM_CONSTRAINT, + NOT_WORD_DELIM = NOT_WORD_DELIM_CONSTRAINT +} re_context_type; + +typedef struct +{ + Idx alloc; + Idx nelem; + Idx *elems; +} re_node_set; + +typedef enum +{ + NON_TYPE = 0, + + /* Node type, These are used by token, node, tree. */ + CHARACTER = 1, + END_OF_RE = 2, + SIMPLE_BRACKET = 3, + OP_BACK_REF = 4, + OP_PERIOD = 5, +#ifdef RE_ENABLE_I18N + COMPLEX_BRACKET = 6, + OP_UTF8_PERIOD = 7, +#endif /* RE_ENABLE_I18N */ + + /* We define EPSILON_BIT as a macro so that OP_OPEN_SUBEXP is used + when the debugger shows values of this enum type. */ +#define EPSILON_BIT 8 + OP_OPEN_SUBEXP = EPSILON_BIT | 0, + OP_CLOSE_SUBEXP = EPSILON_BIT | 1, + OP_ALT = EPSILON_BIT | 2, + OP_DUP_ASTERISK = EPSILON_BIT | 3, + ANCHOR = EPSILON_BIT | 4, + + /* Tree type, these are used only by tree. */ + CONCAT = 16, + SUBEXP = 17, + + /* Token type, these are used only by token. */ + OP_DUP_PLUS = 18, + OP_DUP_QUESTION, + OP_OPEN_BRACKET, + OP_CLOSE_BRACKET, + OP_CHARSET_RANGE, + OP_OPEN_DUP_NUM, + OP_CLOSE_DUP_NUM, + OP_NON_MATCH_LIST, + OP_OPEN_COLL_ELEM, + OP_CLOSE_COLL_ELEM, + OP_OPEN_EQUIV_CLASS, + OP_CLOSE_EQUIV_CLASS, + OP_OPEN_CHAR_CLASS, + OP_CLOSE_CHAR_CLASS, + OP_WORD, + OP_NOTWORD, + OP_SPACE, + OP_NOTSPACE, + BACK_SLASH + +} re_token_type_t; + +#ifdef RE_ENABLE_I18N +typedef struct +{ + /* Multibyte characters. */ + wchar_t *mbchars; + + /* Collating symbols. */ +# ifdef _LIBC + int32_t *coll_syms; +# endif + + /* Equivalence classes. */ +# ifdef _LIBC + int32_t *equiv_classes; +# endif + + /* Range expressions. */ +# ifdef _LIBC + uint32_t *range_starts; + uint32_t *range_ends; +# else /* not _LIBC */ + wchar_t *range_starts; + wchar_t *range_ends; +# endif /* not _LIBC */ + + /* Character classes. */ + wctype_t *char_classes; + + /* If this character set is the non-matching list. */ + unsigned int non_match : 1; + + /* # of multibyte characters. */ + Idx nmbchars; + + /* # of collating symbols. */ + Idx ncoll_syms; + + /* # of equivalence classes. */ + Idx nequiv_classes; + + /* # of range expressions. */ + Idx nranges; + + /* # of character classes. */ + Idx nchar_classes; +} re_charset_t; +#endif /* RE_ENABLE_I18N */ + +typedef struct +{ + union + { + unsigned char c; /* for CHARACTER */ + re_bitset_ptr_t sbcset; /* for SIMPLE_BRACKET */ +#ifdef RE_ENABLE_I18N + re_charset_t *mbcset; /* for COMPLEX_BRACKET */ +#endif /* RE_ENABLE_I18N */ + Idx idx; /* for BACK_REF */ + re_context_type ctx_type; /* for ANCHOR */ + } opr; +#if __GNUC__ >= 2 && !__STRICT_ANSI__ + re_token_type_t type : 8; +#else + re_token_type_t type; +#endif + unsigned int constraint : 10; /* context constraint */ + unsigned int duplicated : 1; + unsigned int opt_subexp : 1; +#ifdef RE_ENABLE_I18N + unsigned int accept_mb : 1; + /* These 2 bits can be moved into the union if needed (e.g. if running out + of bits; move opr.c to opr.c.c and move the flags to opr.c.flags). */ + unsigned int mb_partial : 1; +#endif + unsigned int word_char : 1; +} re_token_t; + +#define IS_EPSILON_NODE(type) ((type) & EPSILON_BIT) + +struct re_string_t +{ + /* Indicate the raw buffer which is the original string passed as an + argument of regexec(), re_search(), etc.. */ + const unsigned char *raw_mbs; + /* Store the multibyte string. In case of "case insensitive mode" like + REG_ICASE, upper cases of the string are stored, otherwise MBS points + the same address that RAW_MBS points. */ + unsigned char *mbs; +#ifdef RE_ENABLE_I18N + /* Store the wide character string which is corresponding to MBS. */ + wint_t *wcs; + Idx *offsets; + mbstate_t cur_state; +#endif + /* Index in RAW_MBS. Each character mbs[i] corresponds to + raw_mbs[raw_mbs_idx + i]. */ + Idx raw_mbs_idx; + /* The length of the valid characters in the buffers. */ + Idx valid_len; + /* The corresponding number of bytes in raw_mbs array. */ + Idx valid_raw_len; + /* The length of the buffers MBS and WCS. */ + Idx bufs_len; + /* The index in MBS, which is updated by re_string_fetch_byte. */ + Idx cur_idx; + /* length of RAW_MBS array. */ + Idx raw_len; + /* This is RAW_LEN - RAW_MBS_IDX + VALID_LEN - VALID_RAW_LEN. */ + Idx len; + /* End of the buffer may be shorter than its length in the cases such + as re_match_2, re_search_2. Then, we use STOP for end of the buffer + instead of LEN. */ + Idx raw_stop; + /* This is RAW_STOP - RAW_MBS_IDX adjusted through OFFSETS. */ + Idx stop; + + /* The context of mbs[0]. We store the context independently, since + the context of mbs[0] may be different from raw_mbs[0], which is + the beginning of the input string. */ + unsigned int tip_context; + /* The translation passed as a part of an argument of re_compile_pattern. */ + RE_TRANSLATE_TYPE trans; + /* Copy of re_dfa_t's word_char. */ + re_const_bitset_ptr_t word_char; + /* true if REG_ICASE. */ + unsigned char icase; + unsigned char is_utf8; + unsigned char map_notascii; + unsigned char mbs_allocated; + unsigned char offsets_needed; + unsigned char newline_anchor; + unsigned char word_ops_used; + int mb_cur_max; +}; +typedef struct re_string_t re_string_t; + + +struct re_dfa_t; +typedef struct re_dfa_t re_dfa_t; + +#ifndef _LIBC +# if defined __i386__ && !defined __EMX__ +# define internal_function __attribute ((regparm (3), stdcall)) +# else +# define internal_function +# endif +#endif + +static reg_errcode_t re_string_realloc_buffers (re_string_t *pstr, + Idx new_buf_len) + internal_function; +#ifdef RE_ENABLE_I18N +static void build_wcs_buffer (re_string_t *pstr) internal_function; +static reg_errcode_t build_wcs_upper_buffer (re_string_t *pstr) + internal_function; +#endif /* RE_ENABLE_I18N */ +static void build_upper_buffer (re_string_t *pstr) internal_function; +static void re_string_translate_buffer (re_string_t *pstr) internal_function; +static unsigned int re_string_context_at (const re_string_t *input, Idx idx, + int eflags) + internal_function __attribute ((pure)); +#define re_string_peek_byte(pstr, offset) \ + ((pstr)->mbs[(pstr)->cur_idx + offset]) +#define re_string_fetch_byte(pstr) \ + ((pstr)->mbs[(pstr)->cur_idx++]) +#define re_string_first_byte(pstr, idx) \ + ((idx) == (pstr)->valid_len || (pstr)->wcs[idx] != WEOF) +#define re_string_is_single_byte_char(pstr, idx) \ + ((pstr)->wcs[idx] != WEOF && ((pstr)->valid_len == (idx) + 1 \ + || (pstr)->wcs[(idx) + 1] != WEOF)) +#define re_string_eoi(pstr) ((pstr)->stop <= (pstr)->cur_idx) +#define re_string_cur_idx(pstr) ((pstr)->cur_idx) +#define re_string_get_buffer(pstr) ((pstr)->mbs) +#define re_string_length(pstr) ((pstr)->len) +#define re_string_byte_at(pstr,idx) ((pstr)->mbs[idx]) +#define re_string_skip_bytes(pstr,idx) ((pstr)->cur_idx += (idx)) +#define re_string_set_index(pstr,idx) ((pstr)->cur_idx = (idx)) + +#include + +#ifndef _LIBC +# if HAVE_ALLOCA +/* The OS usually guarantees only one guard page at the bottom of the stack, + and a page size can be as small as 4096 bytes. So we cannot safely + allocate anything larger than 4096 bytes. Also care for the possibility + of a few compiler-allocated temporary stack slots. */ +# define __libc_use_alloca(n) ((n) < 4032) +# else +/* alloca is implemented with malloc, so just use malloc. */ +# define __libc_use_alloca(n) 0 +# endif +#endif + +#ifndef MAX +# define MAX(a,b) ((a) < (b) ? (b) : (a)) +#endif + +#define re_malloc(t,n) ((t *) malloc ((n) * sizeof (t))) +#define re_realloc(p,t,n) ((t *) realloc (p, (n) * sizeof (t))) +#define re_free(p) free (p) + +struct bin_tree_t +{ + struct bin_tree_t *parent; + struct bin_tree_t *left; + struct bin_tree_t *right; + struct bin_tree_t *first; + struct bin_tree_t *next; + + re_token_t token; + + /* `node_idx' is the index in dfa->nodes, if `type' == 0. + Otherwise `type' indicate the type of this node. */ + Idx node_idx; +}; +typedef struct bin_tree_t bin_tree_t; + +#define BIN_TREE_STORAGE_SIZE \ + ((1024 - sizeof (void *)) / sizeof (bin_tree_t)) + +struct bin_tree_storage_t +{ + struct bin_tree_storage_t *next; + bin_tree_t data[BIN_TREE_STORAGE_SIZE]; +}; +typedef struct bin_tree_storage_t bin_tree_storage_t; + +#define CONTEXT_WORD 1 +#define CONTEXT_NEWLINE (CONTEXT_WORD << 1) +#define CONTEXT_BEGBUF (CONTEXT_NEWLINE << 1) +#define CONTEXT_ENDBUF (CONTEXT_BEGBUF << 1) + +#define IS_WORD_CONTEXT(c) ((c) & CONTEXT_WORD) +#define IS_NEWLINE_CONTEXT(c) ((c) & CONTEXT_NEWLINE) +#define IS_BEGBUF_CONTEXT(c) ((c) & CONTEXT_BEGBUF) +#define IS_ENDBUF_CONTEXT(c) ((c) & CONTEXT_ENDBUF) +#define IS_ORDINARY_CONTEXT(c) ((c) == 0) + +#define IS_WORD_CHAR(ch) (isalnum (ch) || (ch) == '_') +#define IS_NEWLINE(ch) ((ch) == NEWLINE_CHAR) +#define IS_WIDE_WORD_CHAR(ch) (iswalnum (ch) || (ch) == L'_') +#define IS_WIDE_NEWLINE(ch) ((ch) == WIDE_NEWLINE_CHAR) + +#define NOT_SATISFY_PREV_CONSTRAINT(constraint,context) \ + ((((constraint) & PREV_WORD_CONSTRAINT) && !IS_WORD_CONTEXT (context)) \ + || ((constraint & PREV_NOTWORD_CONSTRAINT) && IS_WORD_CONTEXT (context)) \ + || ((constraint & PREV_NEWLINE_CONSTRAINT) && !IS_NEWLINE_CONTEXT (context))\ + || ((constraint & PREV_BEGBUF_CONSTRAINT) && !IS_BEGBUF_CONTEXT (context))) + +#define NOT_SATISFY_NEXT_CONSTRAINT(constraint,context) \ + ((((constraint) & NEXT_WORD_CONSTRAINT) && !IS_WORD_CONTEXT (context)) \ + || (((constraint) & NEXT_NOTWORD_CONSTRAINT) && IS_WORD_CONTEXT (context)) \ + || (((constraint) & NEXT_NEWLINE_CONSTRAINT) && !IS_NEWLINE_CONTEXT (context)) \ + || (((constraint) & NEXT_ENDBUF_CONSTRAINT) && !IS_ENDBUF_CONTEXT (context))) + +struct re_dfastate_t +{ + re_hashval_t hash; + re_node_set nodes; + re_node_set non_eps_nodes; + re_node_set inveclosure; + re_node_set *entrance_nodes; + struct re_dfastate_t **trtable, **word_trtable; + unsigned int context : 4; + unsigned int halt : 1; + /* If this state can accept `multi byte'. + Note that we refer to multibyte characters, and multi character + collating elements as `multi byte'. */ + unsigned int accept_mb : 1; + /* If this state has backreference node(s). */ + unsigned int has_backref : 1; + unsigned int has_constraint : 1; +}; +typedef struct re_dfastate_t re_dfastate_t; + +struct re_state_table_entry +{ + Idx num; + Idx alloc; + re_dfastate_t **array; +}; + +/* Array type used in re_sub_match_last_t and re_sub_match_top_t. */ + +typedef struct +{ + Idx next_idx; + Idx alloc; + re_dfastate_t **array; +} state_array_t; + +/* Store information about the node NODE whose type is OP_CLOSE_SUBEXP. */ + +typedef struct +{ + Idx node; + Idx str_idx; /* The position NODE match at. */ + state_array_t path; +} re_sub_match_last_t; + +/* Store information about the node NODE whose type is OP_OPEN_SUBEXP. + And information about the node, whose type is OP_CLOSE_SUBEXP, + corresponding to NODE is stored in LASTS. */ + +typedef struct +{ + Idx str_idx; + Idx node; + state_array_t *path; + Idx alasts; /* Allocation size of LASTS. */ + Idx nlasts; /* The number of LASTS. */ + re_sub_match_last_t **lasts; +} re_sub_match_top_t; + +struct re_backref_cache_entry +{ + Idx node; + Idx str_idx; + Idx subexp_from; + Idx subexp_to; + char more; + char unused; + unsigned short int eps_reachable_subexps_map; +}; + +typedef struct +{ + /* The string object corresponding to the input string. */ + re_string_t input; +#if defined _LIBC || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L) + const re_dfa_t *const dfa; +#else + const re_dfa_t *dfa; +#endif + /* EFLAGS of the argument of regexec. */ + int eflags; + /* Where the matching ends. */ + Idx match_last; + Idx last_node; + /* The state log used by the matcher. */ + re_dfastate_t **state_log; + Idx state_log_top; + /* Back reference cache. */ + Idx nbkref_ents; + Idx abkref_ents; + struct re_backref_cache_entry *bkref_ents; + int max_mb_elem_len; + Idx nsub_tops; + Idx asub_tops; + re_sub_match_top_t **sub_tops; +} re_match_context_t; + +typedef struct +{ + re_dfastate_t **sifted_states; + re_dfastate_t **limited_states; + Idx last_node; + Idx last_str_idx; + re_node_set limits; +} re_sift_context_t; + +struct re_fail_stack_ent_t +{ + Idx idx; + Idx node; + regmatch_t *regs; + re_node_set eps_via_nodes; +}; + +struct re_fail_stack_t +{ + Idx num; + Idx alloc; + struct re_fail_stack_ent_t *stack; +}; + +struct re_dfa_t +{ + re_token_t *nodes; + size_t nodes_alloc; + size_t nodes_len; + Idx *nexts; + Idx *org_indices; + re_node_set *edests; + re_node_set *eclosures; + re_node_set *inveclosures; + struct re_state_table_entry *state_table; + re_dfastate_t *init_state; + re_dfastate_t *init_state_word; + re_dfastate_t *init_state_nl; + re_dfastate_t *init_state_begbuf; + bin_tree_t *str_tree; + bin_tree_storage_t *str_tree_storage; + re_bitset_ptr_t sb_char; + int str_tree_storage_idx; + + /* number of subexpressions `re_nsub' is in regex_t. */ + re_hashval_t state_hash_mask; + Idx init_node; + Idx nbackref; /* The number of backreference in this dfa. */ + + /* Bitmap expressing which backreference is used. */ + bitset_word_t used_bkref_map; + bitset_word_t completed_bkref_map; + + unsigned int has_plural_match : 1; + /* If this dfa has "multibyte node", which is a backreference or + a node which can accept multibyte character or multi character + collating element. */ + unsigned int has_mb_node : 1; + unsigned int is_utf8 : 1; + unsigned int map_notascii : 1; + unsigned int word_ops_used : 1; + int mb_cur_max; + bitset_t word_char; + reg_syntax_t syntax; + Idx *subexp_map; +#ifdef DEBUG + char* re_str; +#endif +#ifdef _LIBC + __libc_lock_define (, lock) +#endif +}; + +#define re_node_set_init_empty(set) memset (set, '\0', sizeof (re_node_set)) +#define re_node_set_remove(set,id) \ + (re_node_set_remove_at (set, re_node_set_contains (set, id) - 1)) +#define re_node_set_empty(p) ((p)->nelem = 0) +#define re_node_set_free(set) re_free ((set)->elems) + + +typedef enum +{ + SB_CHAR, + MB_CHAR, + EQUIV_CLASS, + COLL_SYM, + CHAR_CLASS +} bracket_elem_type; + +typedef struct +{ + bracket_elem_type type; + union + { + unsigned char ch; + unsigned char *name; + wchar_t wch; + } opr; +} bracket_elem_t; + + +/* Inline functions for bitset_t operation. */ + +static inline void +bitset_set (bitset_t set, Idx i) +{ + set[i / BITSET_WORD_BITS] |= (bitset_word_t) 1 << i % BITSET_WORD_BITS; +} + +static inline void +bitset_clear (bitset_t set, Idx i) +{ + set[i / BITSET_WORD_BITS] &= ~ ((bitset_word_t) 1 << i % BITSET_WORD_BITS); +} + +static inline bool +bitset_contain (const bitset_t set, Idx i) +{ + return (set[i / BITSET_WORD_BITS] >> i % BITSET_WORD_BITS) & 1; +} + +static inline void +bitset_empty (bitset_t set) +{ + memset (set, '\0', sizeof (bitset_t)); +} + +static inline void +bitset_set_all (bitset_t set) +{ + memset (set, -1, sizeof (bitset_word_t) * (SBC_MAX / BITSET_WORD_BITS)); + if (SBC_MAX % BITSET_WORD_BITS != 0) + set[BITSET_WORDS - 1] = + ((bitset_word_t) 1 << SBC_MAX % BITSET_WORD_BITS) - 1; +} + +static inline void +bitset_copy (bitset_t dest, const bitset_t src) +{ + memcpy (dest, src, sizeof (bitset_t)); +} + +static inline void +bitset_not (bitset_t set) +{ + int bitset_i; + for (bitset_i = 0; bitset_i < SBC_MAX / BITSET_WORD_BITS; ++bitset_i) + set[bitset_i] = ~set[bitset_i]; + if (SBC_MAX % BITSET_WORD_BITS != 0) + set[BITSET_WORDS - 1] = + ((((bitset_word_t) 1 << SBC_MAX % BITSET_WORD_BITS) - 1) + & ~set[BITSET_WORDS - 1]); +} + +static inline void +bitset_merge (bitset_t dest, const bitset_t src) +{ + int bitset_i; + for (bitset_i = 0; bitset_i < BITSET_WORDS; ++bitset_i) + dest[bitset_i] |= src[bitset_i]; +} + +static inline void +bitset_mask (bitset_t dest, const bitset_t src) +{ + int bitset_i; + for (bitset_i = 0; bitset_i < BITSET_WORDS; ++bitset_i) + dest[bitset_i] &= src[bitset_i]; +} + +#ifdef RE_ENABLE_I18N +/* Inline functions for re_string. */ +static inline int +internal_function __attribute ((pure)) +re_string_char_size_at (const re_string_t *pstr, Idx idx) +{ + int byte_idx; + if (pstr->mb_cur_max == 1) + return 1; + for (byte_idx = 1; idx + byte_idx < pstr->valid_len; ++byte_idx) + if (pstr->wcs[idx + byte_idx] != WEOF) + break; + return byte_idx; +} + +static inline wint_t +internal_function __attribute ((pure)) +re_string_wchar_at (const re_string_t *pstr, Idx idx) +{ + if (pstr->mb_cur_max == 1) + return (wint_t) pstr->mbs[idx]; + return (wint_t) pstr->wcs[idx]; +} + +static int +internal_function __attribute ((pure)) +re_string_elem_size_at (const re_string_t *pstr, Idx idx) +{ +# ifdef _LIBC + const unsigned char *p, *extra; + const int32_t *table, *indirect; + int32_t tmp; +# include + uint_fast32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES); + + if (nrules != 0) + { + table = (const int32_t *) _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB); + extra = (const unsigned char *) + _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAMB); + indirect = (const int32_t *) _NL_CURRENT (LC_COLLATE, + _NL_COLLATE_INDIRECTMB); + p = pstr->mbs + idx; + tmp = findidx (&p); + return p - pstr->mbs - idx; + } + else +# endif /* _LIBC */ + return 1; +} +#endif /* RE_ENABLE_I18N */ + +#endif /* _REGEX_INTERNAL_H */ diff --git a/gnulib/regexec.c b/gnulib/regexec.c new file mode 100644 index 000000000..21a81669f --- /dev/null +++ b/gnulib/regexec.c @@ -0,0 +1,4407 @@ +/* Extended regular expression matching and search library. + Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 + Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Isamu Hasegawa . + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +static reg_errcode_t match_ctx_init (re_match_context_t *cache, int eflags, + Idx n) internal_function; +static void match_ctx_clean (re_match_context_t *mctx) internal_function; +static void match_ctx_free (re_match_context_t *cache) internal_function; +static reg_errcode_t match_ctx_add_entry (re_match_context_t *cache, Idx node, + Idx str_idx, Idx from, Idx to) + internal_function; +static Idx search_cur_bkref_entry (const re_match_context_t *mctx, Idx str_idx) + internal_function; +static reg_errcode_t match_ctx_add_subtop (re_match_context_t *mctx, Idx node, + Idx str_idx) internal_function; +static re_sub_match_last_t * match_ctx_add_sublast (re_sub_match_top_t *subtop, + Idx node, Idx str_idx) + internal_function; +static void sift_ctx_init (re_sift_context_t *sctx, re_dfastate_t **sifted_sts, + re_dfastate_t **limited_sts, Idx last_node, + Idx last_str_idx) + internal_function; +static reg_errcode_t re_search_internal (const regex_t *preg, + const char *string, Idx length, + Idx start, Idx last_start, Idx stop, + size_t nmatch, regmatch_t pmatch[], + int eflags) internal_function; +static regoff_t re_search_2_stub (struct re_pattern_buffer *bufp, + const char *string1, Idx length1, + const char *string2, Idx length2, + Idx start, regoff_t range, + struct re_registers *regs, + Idx stop, bool ret_len) internal_function; +static regoff_t re_search_stub (struct re_pattern_buffer *bufp, + const char *string, Idx length, Idx start, + regoff_t range, Idx stop, + struct re_registers *regs, + bool ret_len) internal_function; +static unsigned int re_copy_regs (struct re_registers *regs, regmatch_t *pmatch, + Idx nregs, int regs_allocated) + internal_function; +static reg_errcode_t prune_impossible_nodes (re_match_context_t *mctx) + internal_function; +static Idx check_matching (re_match_context_t *mctx, bool fl_longest_match, + Idx *p_match_first) internal_function; +static Idx check_halt_state_context (const re_match_context_t *mctx, + const re_dfastate_t *state, Idx idx) + internal_function; +static void update_regs (const re_dfa_t *dfa, regmatch_t *pmatch, + regmatch_t *prev_idx_match, Idx cur_node, + Idx cur_idx, Idx nmatch) internal_function; +static reg_errcode_t push_fail_stack (struct re_fail_stack_t *fs, + Idx str_idx, Idx dest_node, Idx nregs, + regmatch_t *regs, + re_node_set *eps_via_nodes) + internal_function; +static reg_errcode_t set_regs (const regex_t *preg, + const re_match_context_t *mctx, + size_t nmatch, regmatch_t *pmatch, + bool fl_backtrack) internal_function; +static reg_errcode_t free_fail_stack_return (struct re_fail_stack_t *fs) + internal_function; + +#ifdef RE_ENABLE_I18N +static int sift_states_iter_mb (const re_match_context_t *mctx, + re_sift_context_t *sctx, + Idx node_idx, Idx str_idx, Idx max_str_idx) + internal_function; +#endif /* RE_ENABLE_I18N */ +static reg_errcode_t sift_states_backward (const re_match_context_t *mctx, + re_sift_context_t *sctx) + internal_function; +static reg_errcode_t build_sifted_states (const re_match_context_t *mctx, + re_sift_context_t *sctx, Idx str_idx, + re_node_set *cur_dest) + internal_function; +static reg_errcode_t update_cur_sifted_state (const re_match_context_t *mctx, + re_sift_context_t *sctx, + Idx str_idx, + re_node_set *dest_nodes) + internal_function; +static reg_errcode_t add_epsilon_src_nodes (const re_dfa_t *dfa, + re_node_set *dest_nodes, + const re_node_set *candidates) + internal_function; +static bool check_dst_limits (const re_match_context_t *mctx, + const re_node_set *limits, + Idx dst_node, Idx dst_idx, Idx src_node, + Idx src_idx) internal_function; +static int check_dst_limits_calc_pos_1 (const re_match_context_t *mctx, + int boundaries, Idx subexp_idx, + Idx from_node, Idx bkref_idx) + internal_function; +static int check_dst_limits_calc_pos (const re_match_context_t *mctx, + Idx limit, Idx subexp_idx, + Idx node, Idx str_idx, + Idx bkref_idx) internal_function; +static reg_errcode_t check_subexp_limits (const re_dfa_t *dfa, + re_node_set *dest_nodes, + const re_node_set *candidates, + re_node_set *limits, + struct re_backref_cache_entry *bkref_ents, + Idx str_idx) internal_function; +static reg_errcode_t sift_states_bkref (const re_match_context_t *mctx, + re_sift_context_t *sctx, + Idx str_idx, const re_node_set *candidates) + internal_function; +static reg_errcode_t merge_state_array (const re_dfa_t *dfa, + re_dfastate_t **dst, + re_dfastate_t **src, Idx num) + internal_function; +static re_dfastate_t *find_recover_state (reg_errcode_t *err, + re_match_context_t *mctx) internal_function; +static re_dfastate_t *transit_state (reg_errcode_t *err, + re_match_context_t *mctx, + re_dfastate_t *state) internal_function; +static re_dfastate_t *merge_state_with_log (reg_errcode_t *err, + re_match_context_t *mctx, + re_dfastate_t *next_state) + internal_function; +static reg_errcode_t check_subexp_matching_top (re_match_context_t *mctx, + re_node_set *cur_nodes, + Idx str_idx) internal_function; +#if 0 +static re_dfastate_t *transit_state_sb (reg_errcode_t *err, + re_match_context_t *mctx, + re_dfastate_t *pstate) + internal_function; +#endif +#ifdef RE_ENABLE_I18N +static reg_errcode_t transit_state_mb (re_match_context_t *mctx, + re_dfastate_t *pstate) + internal_function; +#endif /* RE_ENABLE_I18N */ +static reg_errcode_t transit_state_bkref (re_match_context_t *mctx, + const re_node_set *nodes) + internal_function; +static reg_errcode_t get_subexp (re_match_context_t *mctx, + Idx bkref_node, Idx bkref_str_idx) + internal_function; +static reg_errcode_t get_subexp_sub (re_match_context_t *mctx, + const re_sub_match_top_t *sub_top, + re_sub_match_last_t *sub_last, + Idx bkref_node, Idx bkref_str) + internal_function; +static Idx find_subexp_node (const re_dfa_t *dfa, const re_node_set *nodes, + Idx subexp_idx, int type) internal_function; +static reg_errcode_t check_arrival (re_match_context_t *mctx, + state_array_t *path, Idx top_node, + Idx top_str, Idx last_node, Idx last_str, + int type) internal_function; +static reg_errcode_t check_arrival_add_next_nodes (re_match_context_t *mctx, + Idx str_idx, + re_node_set *cur_nodes, + re_node_set *next_nodes) + internal_function; +static reg_errcode_t check_arrival_expand_ecl (const re_dfa_t *dfa, + re_node_set *cur_nodes, + Idx ex_subexp, int type) + internal_function; +static reg_errcode_t check_arrival_expand_ecl_sub (const re_dfa_t *dfa, + re_node_set *dst_nodes, + Idx target, Idx ex_subexp, + int type) internal_function; +static reg_errcode_t expand_bkref_cache (re_match_context_t *mctx, + re_node_set *cur_nodes, Idx cur_str, + Idx subexp_num, int type) + internal_function; +static bool build_trtable (const re_dfa_t *dfa, + re_dfastate_t *state) internal_function; +#ifdef RE_ENABLE_I18N +static int check_node_accept_bytes (const re_dfa_t *dfa, Idx node_idx, + const re_string_t *input, Idx idx) + internal_function; +# ifdef _LIBC +static unsigned int find_collation_sequence_value (const unsigned char *mbs, + size_t name_len) + internal_function; +# endif /* _LIBC */ +#endif /* RE_ENABLE_I18N */ +static Idx group_nodes_into_DFAstates (const re_dfa_t *dfa, + const re_dfastate_t *state, + re_node_set *states_node, + bitset_t *states_ch) internal_function; +static bool check_node_accept (const re_match_context_t *mctx, + const re_token_t *node, Idx idx) + internal_function; +static reg_errcode_t extend_buffers (re_match_context_t *mctx) + internal_function; + +/* Entry point for POSIX code. */ + +/* regexec searches for a given pattern, specified by PREG, in the + string STRING. + + If NMATCH is zero or REG_NOSUB was set in the cflags argument to + `regcomp', we ignore PMATCH. Otherwise, we assume PMATCH has at + least NMATCH elements, and we set them to the offsets of the + corresponding matched substrings. + + EFLAGS specifies `execution flags' which affect matching: if + REG_NOTBOL is set, then ^ does not match at the beginning of the + string; if REG_NOTEOL is set, then $ does not match at the end. + + We return 0 if we find a match and REG_NOMATCH if not. */ + +int +regexec (preg, string, nmatch, pmatch, eflags) + const regex_t *_Restrict_ preg; + const char *_Restrict_ string; + size_t nmatch; + regmatch_t pmatch[_Restrict_arr_]; + int eflags; +{ + reg_errcode_t err; + Idx start, length; +#ifdef _LIBC + re_dfa_t *dfa = (re_dfa_t *) preg->buffer; +#endif + + if (eflags & ~(REG_NOTBOL | REG_NOTEOL | REG_STARTEND)) + return REG_BADPAT; + + if (eflags & REG_STARTEND) + { + start = pmatch[0].rm_so; + length = pmatch[0].rm_eo; + } + else + { + start = 0; + length = strlen (string); + } + + __libc_lock_lock (dfa->lock); + if (preg->no_sub) + err = re_search_internal (preg, string, length, start, length, + length, 0, NULL, eflags); + else + err = re_search_internal (preg, string, length, start, length, + length, nmatch, pmatch, eflags); + __libc_lock_unlock (dfa->lock); + return err != REG_NOERROR; +} + +#ifdef _LIBC +# include +versioned_symbol (libc, __regexec, regexec, GLIBC_2_3_4); + +# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4) +__typeof__ (__regexec) __compat_regexec; + +int +attribute_compat_text_section +__compat_regexec (const regex_t *_Restrict_ preg, + const char *_Restrict_ string, size_t nmatch, + regmatch_t pmatch[], int eflags) +{ + return regexec (preg, string, nmatch, pmatch, + eflags & (REG_NOTBOL | REG_NOTEOL)); +} +compat_symbol (libc, __compat_regexec, regexec, GLIBC_2_0); +# endif +#endif + +/* Entry points for GNU code. */ + +/* re_match, re_search, re_match_2, re_search_2 + + The former two functions operate on STRING with length LENGTH, + while the later two operate on concatenation of STRING1 and STRING2 + with lengths LENGTH1 and LENGTH2, respectively. + + re_match() matches the compiled pattern in BUFP against the string, + starting at index START. + + re_search() first tries matching at index START, then it tries to match + starting from index START + 1, and so on. The last start position tried + is START + RANGE. (Thus RANGE = 0 forces re_search to operate the same + way as re_match().) + + The parameter STOP of re_{match,search}_2 specifies that no match exceeding + the first STOP characters of the concatenation of the strings should be + concerned. + + If REGS is not NULL, and BUFP->no_sub is not set, the offsets of the match + and all groups is stored in REGS. (For the "_2" variants, the offsets are + computed relative to the concatenation, not relative to the individual + strings.) + + On success, re_match* functions return the length of the match, re_search* + return the position of the start of the match. Return value -1 means no + match was found and -2 indicates an internal error. */ + +regoff_t +re_match (bufp, string, length, start, regs) + struct re_pattern_buffer *bufp; + const char *string; + Idx length, start; + struct re_registers *regs; +{ + return re_search_stub (bufp, string, length, start, 0, length, regs, true); +} +#ifdef _LIBC +weak_alias (__re_match, re_match) +#endif + +regoff_t +re_search (bufp, string, length, start, range, regs) + struct re_pattern_buffer *bufp; + const char *string; + Idx length, start; + regoff_t range; + struct re_registers *regs; +{ + return re_search_stub (bufp, string, length, start, range, length, regs, + false); +} +#ifdef _LIBC +weak_alias (__re_search, re_search) +#endif + +regoff_t +re_match_2 (bufp, string1, length1, string2, length2, start, regs, stop) + struct re_pattern_buffer *bufp; + const char *string1, *string2; + Idx length1, length2, start, stop; + struct re_registers *regs; +{ + return re_search_2_stub (bufp, string1, length1, string2, length2, + start, 0, regs, stop, true); +} +#ifdef _LIBC +weak_alias (__re_match_2, re_match_2) +#endif + +regoff_t +re_search_2 (bufp, string1, length1, string2, length2, start, range, regs, stop) + struct re_pattern_buffer *bufp; + const char *string1, *string2; + Idx length1, length2, start, stop; + regoff_t range; + struct re_registers *regs; +{ + return re_search_2_stub (bufp, string1, length1, string2, length2, + start, range, regs, stop, false); +} +#ifdef _LIBC +weak_alias (__re_search_2, re_search_2) +#endif + +static regoff_t +internal_function +re_search_2_stub (struct re_pattern_buffer *bufp, + const char *string1, Idx length1, + const char *string2, Idx length2, + Idx start, regoff_t range, struct re_registers *regs, + Idx stop, bool ret_len) +{ + const char *str; + regoff_t rval; + Idx len = length1 + length2; + char *s = NULL; + + if (BE (length1 < 0 || length2 < 0 || stop < 0 || len < length1, 0)) + return -2; + + /* Concatenate the strings. */ + if (length2 > 0) + if (length1 > 0) + { + s = re_malloc (char, len); + + if (BE (s == NULL, 0)) + return -2; +#ifdef _LIBC + memcpy (__mempcpy (s, string1, length1), string2, length2); +#else + memcpy (s, string1, length1); + memcpy (s + length1, string2, length2); +#endif + str = s; + } + else + str = string2; + else + str = string1; + + rval = re_search_stub (bufp, str, len, start, range, stop, regs, + ret_len); + re_free (s); + return rval; +} + +/* The parameters have the same meaning as those of re_search. + Additional parameters: + If RET_LEN is true the length of the match is returned (re_match style); + otherwise the position of the match is returned. */ + +static regoff_t +internal_function +re_search_stub (struct re_pattern_buffer *bufp, + const char *string, Idx length, + Idx start, regoff_t range, Idx stop, struct re_registers *regs, + bool ret_len) +{ + reg_errcode_t result; + regmatch_t *pmatch; + Idx nregs; + regoff_t rval; + int eflags = 0; +#ifdef _LIBC + re_dfa_t *dfa = (re_dfa_t *) bufp->buffer; +#endif + Idx last_start = start + range; + + /* Check for out-of-range. */ + if (BE (start < 0 || start > length, 0)) + return -1; + if (BE (length < last_start || (0 <= range && last_start < start), 0)) + last_start = length; + else if (BE (last_start < 0 || (range < 0 && start <= last_start), 0)) + last_start = 0; + + __libc_lock_lock (dfa->lock); + + eflags |= (bufp->not_bol) ? REG_NOTBOL : 0; + eflags |= (bufp->not_eol) ? REG_NOTEOL : 0; + + /* Compile fastmap if we haven't yet. */ + if (start < last_start && bufp->fastmap != NULL && !bufp->fastmap_accurate) + re_compile_fastmap (bufp); + + if (BE (bufp->no_sub, 0)) + regs = NULL; + + /* We need at least 1 register. */ + if (regs == NULL) + nregs = 1; + else if (BE (bufp->regs_allocated == REGS_FIXED + && regs->num_regs <= bufp->re_nsub, 0)) + { + nregs = regs->num_regs; + if (BE (nregs < 1, 0)) + { + /* Nothing can be copied to regs. */ + regs = NULL; + nregs = 1; + } + } + else + nregs = bufp->re_nsub + 1; + pmatch = re_malloc (regmatch_t, nregs); + if (BE (pmatch == NULL, 0)) + { + rval = -2; + goto out; + } + + result = re_search_internal (bufp, string, length, start, last_start, stop, + nregs, pmatch, eflags); + + rval = 0; + + /* I hope we needn't fill ther regs with -1's when no match was found. */ + if (result != REG_NOERROR) + rval = -1; + else if (regs != NULL) + { + /* If caller wants register contents data back, copy them. */ + bufp->regs_allocated = re_copy_regs (regs, pmatch, nregs, + bufp->regs_allocated); + if (BE (bufp->regs_allocated == REGS_UNALLOCATED, 0)) + rval = -2; + } + + if (BE (rval == 0, 1)) + { + if (ret_len) + { + assert (pmatch[0].rm_so == start); + rval = pmatch[0].rm_eo - start; + } + else + rval = pmatch[0].rm_so; + } + re_free (pmatch); + out: + __libc_lock_unlock (dfa->lock); + return rval; +} + +static unsigned int +internal_function +re_copy_regs (struct re_registers *regs, regmatch_t *pmatch, Idx nregs, + int regs_allocated) +{ + int rval = REGS_REALLOCATE; + Idx i; + Idx need_regs = nregs + 1; + /* We need one extra element beyond `num_regs' for the `-1' marker GNU code + uses. */ + + /* Have the register data arrays been allocated? */ + if (regs_allocated == REGS_UNALLOCATED) + { /* No. So allocate them with malloc. */ + regs->start = re_malloc (regoff_t, need_regs); + if (BE (regs->start == NULL, 0)) + return REGS_UNALLOCATED; + regs->end = re_malloc (regoff_t, need_regs); + if (BE (regs->end == NULL, 0)) + { + re_free (regs->start); + return REGS_UNALLOCATED; + } + regs->num_regs = need_regs; + } + else if (regs_allocated == REGS_REALLOCATE) + { /* Yes. If we need more elements than were already + allocated, reallocate them. If we need fewer, just + leave it alone. */ + if (BE (need_regs > regs->num_regs, 0)) + { + regoff_t *new_start = re_realloc (regs->start, regoff_t, need_regs); + regoff_t *new_end; + if (BE (new_start == NULL, 0)) + return REGS_UNALLOCATED; + new_end = re_realloc (regs->end, regoff_t, need_regs); + if (BE (new_end == NULL, 0)) + { + re_free (new_start); + return REGS_UNALLOCATED; + } + regs->start = new_start; + regs->end = new_end; + regs->num_regs = need_regs; + } + } + else + { + assert (regs_allocated == REGS_FIXED); + /* This function may not be called with REGS_FIXED and nregs too big. */ + assert (regs->num_regs >= nregs); + rval = REGS_FIXED; + } + + /* Copy the regs. */ + for (i = 0; i < nregs; ++i) + { + regs->start[i] = pmatch[i].rm_so; + regs->end[i] = pmatch[i].rm_eo; + } + for ( ; i < regs->num_regs; ++i) + regs->start[i] = regs->end[i] = -1; + + return rval; +} + +/* Set REGS to hold NUM_REGS registers, storing them in STARTS and + ENDS. Subsequent matches using PATTERN_BUFFER and REGS will use + this memory for recording register information. STARTS and ENDS + must be allocated using the malloc library routine, and must each + be at least NUM_REGS * sizeof (regoff_t) bytes long. + + If NUM_REGS == 0, then subsequent matches should allocate their own + register data. + + Unless this function is called, the first search or match using + PATTERN_BUFFER will allocate its own register data, without + freeing the old data. */ + +void +re_set_registers (bufp, regs, num_regs, starts, ends) + struct re_pattern_buffer *bufp; + struct re_registers *regs; + __re_size_t num_regs; + regoff_t *starts, *ends; +{ + if (num_regs) + { + bufp->regs_allocated = REGS_REALLOCATE; + regs->num_regs = num_regs; + regs->start = starts; + regs->end = ends; + } + else + { + bufp->regs_allocated = REGS_UNALLOCATED; + regs->num_regs = 0; + regs->start = regs->end = NULL; + } +} +#ifdef _LIBC +weak_alias (__re_set_registers, re_set_registers) +#endif + +/* Entry points compatible with 4.2 BSD regex library. We don't define + them unless specifically requested. */ + +#if defined _REGEX_RE_COMP || defined _LIBC +int +# ifdef _LIBC +weak_function +# endif +re_exec (s) + const char *s; +{ + return 0 == regexec (&re_comp_buf, s, 0, NULL, 0); +} +#endif /* _REGEX_RE_COMP */ + +/* Internal entry point. */ + +/* Searches for a compiled pattern PREG in the string STRING, whose + length is LENGTH. NMATCH, PMATCH, and EFLAGS have the same + meaning as with regexec. LAST_START is START + RANGE, where + START and RANGE have the same meaning as with re_search. + Return REG_NOERROR if we find a match, and REG_NOMATCH if not, + otherwise return the error code. + Note: We assume front end functions already check ranges. + (0 <= LAST_START && LAST_START <= LENGTH) */ + +static reg_errcode_t +internal_function +re_search_internal (const regex_t *preg, + const char *string, Idx length, + Idx start, Idx last_start, Idx stop, + size_t nmatch, regmatch_t pmatch[], + int eflags) +{ + reg_errcode_t err; + const re_dfa_t *dfa = (const re_dfa_t *) preg->buffer; + Idx left_lim, right_lim; + int incr; + bool fl_longest_match; + int match_kind; + Idx match_first; + Idx match_last = REG_MISSING; + Idx extra_nmatch; + bool sb; + int ch; +#if defined _LIBC || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L) + re_match_context_t mctx = { .dfa = dfa }; +#else + re_match_context_t mctx; +#endif + char *fastmap = ((preg->fastmap != NULL && preg->fastmap_accurate + && start != last_start && !preg->can_be_null) + ? preg->fastmap : NULL); + RE_TRANSLATE_TYPE t = preg->translate; + +#if !(defined _LIBC || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L)) + memset (&mctx, '\0', sizeof (re_match_context_t)); + mctx.dfa = dfa; +#endif + + extra_nmatch = (nmatch > preg->re_nsub) ? nmatch - (preg->re_nsub + 1) : 0; + nmatch -= extra_nmatch; + + /* Check if the DFA haven't been compiled. */ + if (BE (preg->used == 0 || dfa->init_state == NULL + || dfa->init_state_word == NULL || dfa->init_state_nl == NULL + || dfa->init_state_begbuf == NULL, 0)) + return REG_NOMATCH; + +#ifdef DEBUG + /* We assume front-end functions already check them. */ + assert (0 <= last_start && last_start <= length); +#endif + + /* If initial states with non-begbuf contexts have no elements, + the regex must be anchored. If preg->newline_anchor is set, + we'll never use init_state_nl, so do not check it. */ + if (dfa->init_state->nodes.nelem == 0 + && dfa->init_state_word->nodes.nelem == 0 + && (dfa->init_state_nl->nodes.nelem == 0 + || !preg->newline_anchor)) + { + if (start != 0 && last_start != 0) + return REG_NOMATCH; + start = last_start = 0; + } + + /* We must check the longest matching, if nmatch > 0. */ + fl_longest_match = (nmatch != 0 || dfa->nbackref); + + err = re_string_allocate (&mctx.input, string, length, dfa->nodes_len + 1, + preg->translate, (preg->syntax & RE_ICASE) != 0, + dfa); + if (BE (err != REG_NOERROR, 0)) + goto free_return; + mctx.input.stop = stop; + mctx.input.raw_stop = stop; + mctx.input.newline_anchor = preg->newline_anchor; + + err = match_ctx_init (&mctx, eflags, dfa->nbackref * 2); + if (BE (err != REG_NOERROR, 0)) + goto free_return; + + /* We will log all the DFA states through which the dfa pass, + if nmatch > 1, or this dfa has "multibyte node", which is a + back-reference or a node which can accept multibyte character or + multi character collating element. */ + if (nmatch > 1 || dfa->has_mb_node) + { + /* Avoid overflow. */ + if (BE (SIZE_MAX / sizeof (re_dfastate_t *) <= mctx.input.bufs_len, 0)) + { + err = REG_ESPACE; + goto free_return; + } + + mctx.state_log = re_malloc (re_dfastate_t *, mctx.input.bufs_len + 1); + if (BE (mctx.state_log == NULL, 0)) + { + err = REG_ESPACE; + goto free_return; + } + } + else + mctx.state_log = NULL; + + match_first = start; + mctx.input.tip_context = (eflags & REG_NOTBOL) ? CONTEXT_BEGBUF + : CONTEXT_NEWLINE | CONTEXT_BEGBUF; + + /* Check incrementally whether of not the input string match. */ + incr = (last_start < start) ? -1 : 1; + left_lim = (last_start < start) ? last_start : start; + right_lim = (last_start < start) ? start : last_start; + sb = dfa->mb_cur_max == 1; + match_kind = + (fastmap + ? ((sb || !(preg->syntax & RE_ICASE || t) ? 4 : 0) + | (start <= last_start ? 2 : 0) + | (t != NULL ? 1 : 0)) + : 8); + + for (;; match_first += incr) + { + err = REG_NOMATCH; + if (match_first < left_lim || right_lim < match_first) + goto free_return; + + /* Advance as rapidly as possible through the string, until we + find a plausible place to start matching. This may be done + with varying efficiency, so there are various possibilities: + only the most common of them are specialized, in order to + save on code size. We use a switch statement for speed. */ + switch (match_kind) + { + case 8: + /* No fastmap. */ + break; + + case 7: + /* Fastmap with single-byte translation, match forward. */ + while (BE (match_first < right_lim, 1) + && !fastmap[t[(unsigned char) string[match_first]]]) + ++match_first; + goto forward_match_found_start_or_reached_end; + + case 6: + /* Fastmap without translation, match forward. */ + while (BE (match_first < right_lim, 1) + && !fastmap[(unsigned char) string[match_first]]) + ++match_first; + + forward_match_found_start_or_reached_end: + if (BE (match_first == right_lim, 0)) + { + ch = match_first >= length + ? 0 : (unsigned char) string[match_first]; + if (!fastmap[t ? t[ch] : ch]) + goto free_return; + } + break; + + case 4: + case 5: + /* Fastmap without multi-byte translation, match backwards. */ + while (match_first >= left_lim) + { + ch = match_first >= length + ? 0 : (unsigned char) string[match_first]; + if (fastmap[t ? t[ch] : ch]) + break; + --match_first; + } + if (match_first < left_lim) + goto free_return; + break; + + default: + /* In this case, we can't determine easily the current byte, + since it might be a component byte of a multibyte + character. Then we use the constructed buffer instead. */ + for (;;) + { + /* If MATCH_FIRST is out of the valid range, reconstruct the + buffers. */ + __re_size_t offset = match_first - mctx.input.raw_mbs_idx; + if (BE (offset >= (__re_size_t) mctx.input.valid_raw_len, 0)) + { + err = re_string_reconstruct (&mctx.input, match_first, + eflags); + if (BE (err != REG_NOERROR, 0)) + goto free_return; + + offset = match_first - mctx.input.raw_mbs_idx; + } + /* If MATCH_FIRST is out of the buffer, leave it as '\0'. + Note that MATCH_FIRST must not be smaller than 0. */ + ch = (match_first >= length + ? 0 : re_string_byte_at (&mctx.input, offset)); + if (fastmap[ch]) + break; + match_first += incr; + if (match_first < left_lim || match_first > right_lim) + { + err = REG_NOMATCH; + goto free_return; + } + } + break; + } + + /* Reconstruct the buffers so that the matcher can assume that + the matching starts from the beginning of the buffer. */ + err = re_string_reconstruct (&mctx.input, match_first, eflags); + if (BE (err != REG_NOERROR, 0)) + goto free_return; + +#ifdef RE_ENABLE_I18N + /* Don't consider this char as a possible match start if it part, + yet isn't the head, of a multibyte character. */ + if (!sb && !re_string_first_byte (&mctx.input, 0)) + continue; +#endif + + /* It seems to be appropriate one, then use the matcher. */ + /* We assume that the matching starts from 0. */ + mctx.state_log_top = mctx.nbkref_ents = mctx.max_mb_elem_len = 0; + match_last = check_matching (&mctx, fl_longest_match, + start <= last_start ? &match_first : NULL); + if (match_last != REG_MISSING) + { + if (BE (match_last == REG_ERROR, 0)) + { + err = REG_ESPACE; + goto free_return; + } + else + { + mctx.match_last = match_last; + if ((!preg->no_sub && nmatch > 1) || dfa->nbackref) + { + re_dfastate_t *pstate = mctx.state_log[match_last]; + mctx.last_node = check_halt_state_context (&mctx, pstate, + match_last); + } + if ((!preg->no_sub && nmatch > 1 && dfa->has_plural_match) + || dfa->nbackref) + { + err = prune_impossible_nodes (&mctx); + if (err == REG_NOERROR) + break; + if (BE (err != REG_NOMATCH, 0)) + goto free_return; + match_last = REG_MISSING; + } + else + break; /* We found a match. */ + } + } + + match_ctx_clean (&mctx); + } + +#ifdef DEBUG + assert (match_last != REG_MISSING); + assert (err == REG_NOERROR); +#endif + + /* Set pmatch[] if we need. */ + if (nmatch > 0) + { + Idx reg_idx; + + /* Initialize registers. */ + for (reg_idx = 1; reg_idx < nmatch; ++reg_idx) + pmatch[reg_idx].rm_so = pmatch[reg_idx].rm_eo = -1; + + /* Set the points where matching start/end. */ + pmatch[0].rm_so = 0; + pmatch[0].rm_eo = mctx.match_last; + /* FIXME: This function should fail if mctx.match_last exceeds + the maximum possible regoff_t value. We need a new error + code REG_OVERFLOW. */ + + if (!preg->no_sub && nmatch > 1) + { + err = set_regs (preg, &mctx, nmatch, pmatch, + dfa->has_plural_match && dfa->nbackref > 0); + if (BE (err != REG_NOERROR, 0)) + goto free_return; + } + + /* At last, add the offset to the each registers, since we slided + the buffers so that we could assume that the matching starts + from 0. */ + for (reg_idx = 0; reg_idx < nmatch; ++reg_idx) + if (pmatch[reg_idx].rm_so != -1) + { +#ifdef RE_ENABLE_I18N + if (BE (mctx.input.offsets_needed != 0, 0)) + { + pmatch[reg_idx].rm_so = + (pmatch[reg_idx].rm_so == mctx.input.valid_len + ? mctx.input.valid_raw_len + : mctx.input.offsets[pmatch[reg_idx].rm_so]); + pmatch[reg_idx].rm_eo = + (pmatch[reg_idx].rm_eo == mctx.input.valid_len + ? mctx.input.valid_raw_len + : mctx.input.offsets[pmatch[reg_idx].rm_eo]); + } +#else + assert (mctx.input.offsets_needed == 0); +#endif + pmatch[reg_idx].rm_so += match_first; + pmatch[reg_idx].rm_eo += match_first; + } + for (reg_idx = 0; reg_idx < extra_nmatch; ++reg_idx) + { + pmatch[nmatch + reg_idx].rm_so = -1; + pmatch[nmatch + reg_idx].rm_eo = -1; + } + + if (dfa->subexp_map) + for (reg_idx = 0; reg_idx + 1 < nmatch; reg_idx++) + if (dfa->subexp_map[reg_idx] != reg_idx) + { + pmatch[reg_idx + 1].rm_so + = pmatch[dfa->subexp_map[reg_idx] + 1].rm_so; + pmatch[reg_idx + 1].rm_eo + = pmatch[dfa->subexp_map[reg_idx] + 1].rm_eo; + } + } + + free_return: + re_free (mctx.state_log); + if (dfa->nbackref) + match_ctx_free (&mctx); + re_string_destruct (&mctx.input); + return err; +} + +static reg_errcode_t +internal_function +prune_impossible_nodes (re_match_context_t *mctx) +{ + const re_dfa_t *const dfa = mctx->dfa; + Idx halt_node, match_last; + reg_errcode_t ret; + re_dfastate_t **sifted_states; + re_dfastate_t **lim_states = NULL; + re_sift_context_t sctx; +#ifdef DEBUG + assert (mctx->state_log != NULL); +#endif + match_last = mctx->match_last; + halt_node = mctx->last_node; + + /* Avoid overflow. */ + if (BE (SIZE_MAX / sizeof (re_dfastate_t *) <= match_last, 0)) + return REG_ESPACE; + + sifted_states = re_malloc (re_dfastate_t *, match_last + 1); + if (BE (sifted_states == NULL, 0)) + { + ret = REG_ESPACE; + goto free_return; + } + if (dfa->nbackref) + { + lim_states = re_malloc (re_dfastate_t *, match_last + 1); + if (BE (lim_states == NULL, 0)) + { + ret = REG_ESPACE; + goto free_return; + } + while (1) + { + memset (lim_states, '\0', + sizeof (re_dfastate_t *) * (match_last + 1)); + sift_ctx_init (&sctx, sifted_states, lim_states, halt_node, + match_last); + ret = sift_states_backward (mctx, &sctx); + re_node_set_free (&sctx.limits); + if (BE (ret != REG_NOERROR, 0)) + goto free_return; + if (sifted_states[0] != NULL || lim_states[0] != NULL) + break; + do + { + --match_last; + if (! REG_VALID_INDEX (match_last)) + { + ret = REG_NOMATCH; + goto free_return; + } + } while (mctx->state_log[match_last] == NULL + || !mctx->state_log[match_last]->halt); + halt_node = check_halt_state_context (mctx, + mctx->state_log[match_last], + match_last); + } + ret = merge_state_array (dfa, sifted_states, lim_states, + match_last + 1); + re_free (lim_states); + lim_states = NULL; + if (BE (ret != REG_NOERROR, 0)) + goto free_return; + } + else + { + sift_ctx_init (&sctx, sifted_states, lim_states, halt_node, match_last); + ret = sift_states_backward (mctx, &sctx); + re_node_set_free (&sctx.limits); + if (BE (ret != REG_NOERROR, 0)) + goto free_return; + if (sifted_states[0] == NULL) + { + ret = REG_NOMATCH; + goto free_return; + } + } + re_free (mctx->state_log); + mctx->state_log = sifted_states; + sifted_states = NULL; + mctx->last_node = halt_node; + mctx->match_last = match_last; + ret = REG_NOERROR; + free_return: + re_free (sifted_states); + re_free (lim_states); + return ret; +} + +/* Acquire an initial state and return it. + We must select appropriate initial state depending on the context, + since initial states may have constraints like "\<", "^", etc.. */ + +static inline re_dfastate_t * +__attribute ((always_inline)) internal_function +acquire_init_state_context (reg_errcode_t *err, const re_match_context_t *mctx, + Idx idx) +{ + const re_dfa_t *const dfa = mctx->dfa; + if (dfa->init_state->has_constraint) + { + unsigned int context; + context = re_string_context_at (&mctx->input, idx - 1, mctx->eflags); + if (IS_WORD_CONTEXT (context)) + return dfa->init_state_word; + else if (IS_ORDINARY_CONTEXT (context)) + return dfa->init_state; + else if (IS_BEGBUF_CONTEXT (context) && IS_NEWLINE_CONTEXT (context)) + return dfa->init_state_begbuf; + else if (IS_NEWLINE_CONTEXT (context)) + return dfa->init_state_nl; + else if (IS_BEGBUF_CONTEXT (context)) + { + /* It is relatively rare case, then calculate on demand. */ + return re_acquire_state_context (err, dfa, + dfa->init_state->entrance_nodes, + context); + } + else + /* Must not happen? */ + return dfa->init_state; + } + else + return dfa->init_state; +} + +/* Check whether the regular expression match input string INPUT or not, + and return the index where the matching end. Return REG_MISSING if + there is no match, and return REG_ERROR in case of an error. + FL_LONGEST_MATCH means we want the POSIX longest matching. + If P_MATCH_FIRST is not NULL, and the match fails, it is set to the + next place where we may want to try matching. + Note that the matcher assume that the maching starts from the current + index of the buffer. */ + +static Idx +internal_function +check_matching (re_match_context_t *mctx, bool fl_longest_match, + Idx *p_match_first) +{ + const re_dfa_t *const dfa = mctx->dfa; + reg_errcode_t err; + Idx match = 0; + Idx match_last = REG_MISSING; + Idx cur_str_idx = re_string_cur_idx (&mctx->input); + re_dfastate_t *cur_state; + bool at_init_state = p_match_first != NULL; + Idx next_start_idx = cur_str_idx; + + err = REG_NOERROR; + cur_state = acquire_init_state_context (&err, mctx, cur_str_idx); + /* An initial state must not be NULL (invalid). */ + if (BE (cur_state == NULL, 0)) + { + assert (err == REG_ESPACE); + return REG_ERROR; + } + + if (mctx->state_log != NULL) + { + mctx->state_log[cur_str_idx] = cur_state; + + /* Check OP_OPEN_SUBEXP in the initial state in case that we use them + later. E.g. Processing back references. */ + if (BE (dfa->nbackref, 0)) + { + at_init_state = false; + err = check_subexp_matching_top (mctx, &cur_state->nodes, 0); + if (BE (err != REG_NOERROR, 0)) + return err; + + if (cur_state->has_backref) + { + err = transit_state_bkref (mctx, &cur_state->nodes); + if (BE (err != REG_NOERROR, 0)) + return err; + } + } + } + + /* If the RE accepts NULL string. */ + if (BE (cur_state->halt, 0)) + { + if (!cur_state->has_constraint + || check_halt_state_context (mctx, cur_state, cur_str_idx)) + { + if (!fl_longest_match) + return cur_str_idx; + else + { + match_last = cur_str_idx; + match = 1; + } + } + } + + while (!re_string_eoi (&mctx->input)) + { + re_dfastate_t *old_state = cur_state; + Idx next_char_idx = re_string_cur_idx (&mctx->input) + 1; + + if (BE (next_char_idx >= mctx->input.bufs_len, 0) + || (BE (next_char_idx >= mctx->input.valid_len, 0) + && mctx->input.valid_len < mctx->input.len)) + { + err = extend_buffers (mctx); + if (BE (err != REG_NOERROR, 0)) + { + assert (err == REG_ESPACE); + return REG_ERROR; + } + } + + cur_state = transit_state (&err, mctx, cur_state); + if (mctx->state_log != NULL) + cur_state = merge_state_with_log (&err, mctx, cur_state); + + if (cur_state == NULL) + { + /* Reached the invalid state or an error. Try to recover a valid + state using the state log, if available and if we have not + already found a valid (even if not the longest) match. */ + if (BE (err != REG_NOERROR, 0)) + return REG_ERROR; + + if (mctx->state_log == NULL + || (match && !fl_longest_match) + || (cur_state = find_recover_state (&err, mctx)) == NULL) + break; + } + + if (BE (at_init_state, 0)) + { + if (old_state == cur_state) + next_start_idx = next_char_idx; + else + at_init_state = false; + } + + if (cur_state->halt) + { + /* Reached a halt state. + Check the halt state can satisfy the current context. */ + if (!cur_state->has_constraint + || check_halt_state_context (mctx, cur_state, + re_string_cur_idx (&mctx->input))) + { + /* We found an appropriate halt state. */ + match_last = re_string_cur_idx (&mctx->input); + match = 1; + + /* We found a match, do not modify match_first below. */ + p_match_first = NULL; + if (!fl_longest_match) + break; + } + } + } + + if (p_match_first) + *p_match_first += next_start_idx; + + return match_last; +} + +/* Check NODE match the current context. */ + +static bool +internal_function +check_halt_node_context (const re_dfa_t *dfa, Idx node, unsigned int context) +{ + re_token_type_t type = dfa->nodes[node].type; + unsigned int constraint = dfa->nodes[node].constraint; + if (type != END_OF_RE) + return false; + if (!constraint) + return true; + if (NOT_SATISFY_NEXT_CONSTRAINT (constraint, context)) + return false; + return true; +} + +/* Check the halt state STATE match the current context. + Return 0 if not match, if the node, STATE has, is a halt node and + match the context, return the node. */ + +static Idx +internal_function +check_halt_state_context (const re_match_context_t *mctx, + const re_dfastate_t *state, Idx idx) +{ + Idx i; + unsigned int context; +#ifdef DEBUG + assert (state->halt); +#endif + context = re_string_context_at (&mctx->input, idx, mctx->eflags); + for (i = 0; i < state->nodes.nelem; ++i) + if (check_halt_node_context (mctx->dfa, state->nodes.elems[i], context)) + return state->nodes.elems[i]; + return 0; +} + +/* Compute the next node to which "NFA" transit from NODE("NFA" is a NFA + corresponding to the DFA). + Return the destination node, and update EPS_VIA_NODES; + return REG_MISSING in case of errors. */ + +static Idx +internal_function +proceed_next_node (const re_match_context_t *mctx, Idx nregs, regmatch_t *regs, + Idx *pidx, Idx node, re_node_set *eps_via_nodes, + struct re_fail_stack_t *fs) +{ + const re_dfa_t *const dfa = mctx->dfa; + Idx i; + bool ok; + if (IS_EPSILON_NODE (dfa->nodes[node].type)) + { + re_node_set *cur_nodes = &mctx->state_log[*pidx]->nodes; + re_node_set *edests = &dfa->edests[node]; + Idx dest_node; + ok = re_node_set_insert (eps_via_nodes, node); + if (BE (! ok, 0)) + return REG_ERROR; + /* Pick up a valid destination, or return REG_MISSING if none + is found. */ + for (dest_node = REG_MISSING, i = 0; i < edests->nelem; ++i) + { + Idx candidate = edests->elems[i]; + if (!re_node_set_contains (cur_nodes, candidate)) + continue; + if (dest_node == REG_MISSING) + dest_node = candidate; + + else + { + /* In order to avoid infinite loop like "(a*)*", return the second + epsilon-transition if the first was already considered. */ + if (re_node_set_contains (eps_via_nodes, dest_node)) + return candidate; + + /* Otherwise, push the second epsilon-transition on the fail stack. */ + else if (fs != NULL + && push_fail_stack (fs, *pidx, candidate, nregs, regs, + eps_via_nodes)) + return REG_ERROR; + + /* We know we are going to exit. */ + break; + } + } + return dest_node; + } + else + { + Idx naccepted = 0; + re_token_type_t type = dfa->nodes[node].type; + +#ifdef RE_ENABLE_I18N + if (dfa->nodes[node].accept_mb) + naccepted = check_node_accept_bytes (dfa, node, &mctx->input, *pidx); + else +#endif /* RE_ENABLE_I18N */ + if (type == OP_BACK_REF) + { + Idx subexp_idx = dfa->nodes[node].opr.idx + 1; + naccepted = regs[subexp_idx].rm_eo - regs[subexp_idx].rm_so; + if (fs != NULL) + { + if (regs[subexp_idx].rm_so == -1 || regs[subexp_idx].rm_eo == -1) + return REG_MISSING; + else if (naccepted) + { + char *buf = (char *) re_string_get_buffer (&mctx->input); + if (memcmp (buf + regs[subexp_idx].rm_so, buf + *pidx, + naccepted) != 0) + return REG_MISSING; + } + } + + if (naccepted == 0) + { + Idx dest_node; + ok = re_node_set_insert (eps_via_nodes, node); + if (BE (! ok, 0)) + return REG_ERROR; + dest_node = dfa->edests[node].elems[0]; + if (re_node_set_contains (&mctx->state_log[*pidx]->nodes, + dest_node)) + return dest_node; + } + } + + if (naccepted != 0 + || check_node_accept (mctx, dfa->nodes + node, *pidx)) + { + Idx dest_node = dfa->nexts[node]; + *pidx = (naccepted == 0) ? *pidx + 1 : *pidx + naccepted; + if (fs && (*pidx > mctx->match_last || mctx->state_log[*pidx] == NULL + || !re_node_set_contains (&mctx->state_log[*pidx]->nodes, + dest_node))) + return REG_MISSING; + re_node_set_empty (eps_via_nodes); + return dest_node; + } + } + return REG_MISSING; +} + +static reg_errcode_t +internal_function +push_fail_stack (struct re_fail_stack_t *fs, Idx str_idx, Idx dest_node, + Idx nregs, regmatch_t *regs, re_node_set *eps_via_nodes) +{ + reg_errcode_t err; + Idx num = fs->num++; + if (fs->num == fs->alloc) + { + struct re_fail_stack_ent_t *new_array; + new_array = realloc (fs->stack, (sizeof (struct re_fail_stack_ent_t) + * fs->alloc * 2)); + if (new_array == NULL) + return REG_ESPACE; + fs->alloc *= 2; + fs->stack = new_array; + } + fs->stack[num].idx = str_idx; + fs->stack[num].node = dest_node; + fs->stack[num].regs = re_malloc (regmatch_t, nregs); + if (fs->stack[num].regs == NULL) + return REG_ESPACE; + memcpy (fs->stack[num].regs, regs, sizeof (regmatch_t) * nregs); + err = re_node_set_init_copy (&fs->stack[num].eps_via_nodes, eps_via_nodes); + return err; +} + +static Idx +internal_function +pop_fail_stack (struct re_fail_stack_t *fs, Idx *pidx, Idx nregs, + regmatch_t *regs, re_node_set *eps_via_nodes) +{ + Idx num = --fs->num; + assert (REG_VALID_INDEX (num)); + *pidx = fs->stack[num].idx; + memcpy (regs, fs->stack[num].regs, sizeof (regmatch_t) * nregs); + re_node_set_free (eps_via_nodes); + re_free (fs->stack[num].regs); + *eps_via_nodes = fs->stack[num].eps_via_nodes; + return fs->stack[num].node; +} + +/* Set the positions where the subexpressions are starts/ends to registers + PMATCH. + Note: We assume that pmatch[0] is already set, and + pmatch[i].rm_so == pmatch[i].rm_eo == -1 for 0 < i < nmatch. */ + +static reg_errcode_t +internal_function +set_regs (const regex_t *preg, const re_match_context_t *mctx, size_t nmatch, + regmatch_t *pmatch, bool fl_backtrack) +{ + const re_dfa_t *dfa = (const re_dfa_t *) preg->buffer; + Idx idx, cur_node; + re_node_set eps_via_nodes; + struct re_fail_stack_t *fs; + struct re_fail_stack_t fs_body = { 0, 2, NULL }; + regmatch_t *prev_idx_match; + bool prev_idx_match_malloced = false; + +#ifdef DEBUG + assert (nmatch > 1); + assert (mctx->state_log != NULL); +#endif + if (fl_backtrack) + { + fs = &fs_body; + fs->stack = re_malloc (struct re_fail_stack_ent_t, fs->alloc); + if (fs->stack == NULL) + return REG_ESPACE; + } + else + fs = NULL; + + cur_node = dfa->init_node; + re_node_set_init_empty (&eps_via_nodes); + + if (__libc_use_alloca (nmatch * sizeof (regmatch_t))) + prev_idx_match = (regmatch_t *) alloca (nmatch * sizeof (regmatch_t)); + else + { + prev_idx_match = re_malloc (regmatch_t, nmatch); + if (prev_idx_match == NULL) + { + free_fail_stack_return (fs); + return REG_ESPACE; + } + prev_idx_match_malloced = true; + } + memcpy (prev_idx_match, pmatch, sizeof (regmatch_t) * nmatch); + + for (idx = pmatch[0].rm_so; idx <= pmatch[0].rm_eo ;) + { + update_regs (dfa, pmatch, prev_idx_match, cur_node, idx, nmatch); + + if (idx == pmatch[0].rm_eo && cur_node == mctx->last_node) + { + Idx reg_idx; + if (fs) + { + for (reg_idx = 0; reg_idx < nmatch; ++reg_idx) + if (pmatch[reg_idx].rm_so > -1 && pmatch[reg_idx].rm_eo == -1) + break; + if (reg_idx == nmatch) + { + re_node_set_free (&eps_via_nodes); + if (prev_idx_match_malloced) + re_free (prev_idx_match); + return free_fail_stack_return (fs); + } + cur_node = pop_fail_stack (fs, &idx, nmatch, pmatch, + &eps_via_nodes); + } + else + { + re_node_set_free (&eps_via_nodes); + if (prev_idx_match_malloced) + re_free (prev_idx_match); + return REG_NOERROR; + } + } + + /* Proceed to next node. */ + cur_node = proceed_next_node (mctx, nmatch, pmatch, &idx, cur_node, + &eps_via_nodes, fs); + + if (BE (! REG_VALID_INDEX (cur_node), 0)) + { + if (BE (cur_node == REG_ERROR, 0)) + { + re_node_set_free (&eps_via_nodes); + if (prev_idx_match_malloced) + re_free (prev_idx_match); + free_fail_stack_return (fs); + return REG_ESPACE; + } + if (fs) + cur_node = pop_fail_stack (fs, &idx, nmatch, pmatch, + &eps_via_nodes); + else + { + re_node_set_free (&eps_via_nodes); + if (prev_idx_match_malloced) + re_free (prev_idx_match); + return REG_NOMATCH; + } + } + } + re_node_set_free (&eps_via_nodes); + if (prev_idx_match_malloced) + re_free (prev_idx_match); + return free_fail_stack_return (fs); +} + +static reg_errcode_t +internal_function +free_fail_stack_return (struct re_fail_stack_t *fs) +{ + if (fs) + { + Idx fs_idx; + for (fs_idx = 0; fs_idx < fs->num; ++fs_idx) + { + re_node_set_free (&fs->stack[fs_idx].eps_via_nodes); + re_free (fs->stack[fs_idx].regs); + } + re_free (fs->stack); + } + return REG_NOERROR; +} + +static void +internal_function +update_regs (const re_dfa_t *dfa, regmatch_t *pmatch, + regmatch_t *prev_idx_match, Idx cur_node, Idx cur_idx, Idx nmatch) +{ + int type = dfa->nodes[cur_node].type; + if (type == OP_OPEN_SUBEXP) + { + Idx reg_num = dfa->nodes[cur_node].opr.idx + 1; + + /* We are at the first node of this sub expression. */ + if (reg_num < nmatch) + { + pmatch[reg_num].rm_so = cur_idx; + pmatch[reg_num].rm_eo = -1; + } + } + else if (type == OP_CLOSE_SUBEXP) + { + Idx reg_num = dfa->nodes[cur_node].opr.idx + 1; + if (reg_num < nmatch) + { + /* We are at the last node of this sub expression. */ + if (pmatch[reg_num].rm_so < cur_idx) + { + pmatch[reg_num].rm_eo = cur_idx; + /* This is a non-empty match or we are not inside an optional + subexpression. Accept this right away. */ + memcpy (prev_idx_match, pmatch, sizeof (regmatch_t) * nmatch); + } + else + { + if (dfa->nodes[cur_node].opt_subexp + && prev_idx_match[reg_num].rm_so != -1) + /* We transited through an empty match for an optional + subexpression, like (a?)*, and this is not the subexp's + first match. Copy back the old content of the registers + so that matches of an inner subexpression are undone as + well, like in ((a?))*. */ + memcpy (pmatch, prev_idx_match, sizeof (regmatch_t) * nmatch); + else + /* We completed a subexpression, but it may be part of + an optional one, so do not update PREV_IDX_MATCH. */ + pmatch[reg_num].rm_eo = cur_idx; + } + } + } +} + +/* This function checks the STATE_LOG from the SCTX->last_str_idx to 0 + and sift the nodes in each states according to the following rules. + Updated state_log will be wrote to STATE_LOG. + + Rules: We throw away the Node `a' in the STATE_LOG[STR_IDX] if... + 1. When STR_IDX == MATCH_LAST(the last index in the state_log): + If `a' isn't the LAST_NODE and `a' can't epsilon transit to + the LAST_NODE, we throw away the node `a'. + 2. When 0 <= STR_IDX < MATCH_LAST and `a' accepts + string `s' and transit to `b': + i. If 'b' isn't in the STATE_LOG[STR_IDX+strlen('s')], we throw + away the node `a'. + ii. If 'b' is in the STATE_LOG[STR_IDX+strlen('s')] but 'b' is + thrown away, we throw away the node `a'. + 3. When 0 <= STR_IDX < MATCH_LAST and 'a' epsilon transit to 'b': + i. If 'b' isn't in the STATE_LOG[STR_IDX], we throw away the + node `a'. + ii. If 'b' is in the STATE_LOG[STR_IDX] but 'b' is thrown away, + we throw away the node `a'. */ + +#define STATE_NODE_CONTAINS(state,node) \ + ((state) != NULL && re_node_set_contains (&(state)->nodes, node)) + +static reg_errcode_t +internal_function +sift_states_backward (const re_match_context_t *mctx, re_sift_context_t *sctx) +{ + reg_errcode_t err; + int null_cnt = 0; + Idx str_idx = sctx->last_str_idx; + re_node_set cur_dest; + +#ifdef DEBUG + assert (mctx->state_log != NULL && mctx->state_log[str_idx] != NULL); +#endif + + /* Build sifted state_log[str_idx]. It has the nodes which can epsilon + transit to the last_node and the last_node itself. */ + err = re_node_set_init_1 (&cur_dest, sctx->last_node); + if (BE (err != REG_NOERROR, 0)) + return err; + err = update_cur_sifted_state (mctx, sctx, str_idx, &cur_dest); + if (BE (err != REG_NOERROR, 0)) + goto free_return; + + /* Then check each states in the state_log. */ + while (str_idx > 0) + { + /* Update counters. */ + null_cnt = (sctx->sifted_states[str_idx] == NULL) ? null_cnt + 1 : 0; + if (null_cnt > mctx->max_mb_elem_len) + { + memset (sctx->sifted_states, '\0', + sizeof (re_dfastate_t *) * str_idx); + re_node_set_free (&cur_dest); + return REG_NOERROR; + } + re_node_set_empty (&cur_dest); + --str_idx; + + if (mctx->state_log[str_idx]) + { + err = build_sifted_states (mctx, sctx, str_idx, &cur_dest); + if (BE (err != REG_NOERROR, 0)) + goto free_return; + } + + /* Add all the nodes which satisfy the following conditions: + - It can epsilon transit to a node in CUR_DEST. + - It is in CUR_SRC. + And update state_log. */ + err = update_cur_sifted_state (mctx, sctx, str_idx, &cur_dest); + if (BE (err != REG_NOERROR, 0)) + goto free_return; + } + err = REG_NOERROR; + free_return: + re_node_set_free (&cur_dest); + return err; +} + +static reg_errcode_t +internal_function +build_sifted_states (const re_match_context_t *mctx, re_sift_context_t *sctx, + Idx str_idx, re_node_set *cur_dest) +{ + const re_dfa_t *const dfa = mctx->dfa; + const re_node_set *cur_src = &mctx->state_log[str_idx]->non_eps_nodes; + Idx i; + + /* Then build the next sifted state. + We build the next sifted state on `cur_dest', and update + `sifted_states[str_idx]' with `cur_dest'. + Note: + `cur_dest' is the sifted state from `state_log[str_idx + 1]'. + `cur_src' points the node_set of the old `state_log[str_idx]' + (with the epsilon nodes pre-filtered out). */ + for (i = 0; i < cur_src->nelem; i++) + { + Idx prev_node = cur_src->elems[i]; + int naccepted = 0; + bool ok; + +#ifdef DEBUG + re_token_type_t type = dfa->nodes[prev_node].type; + assert (!IS_EPSILON_NODE (type)); +#endif +#ifdef RE_ENABLE_I18N + /* If the node may accept `multi byte'. */ + if (dfa->nodes[prev_node].accept_mb) + naccepted = sift_states_iter_mb (mctx, sctx, prev_node, + str_idx, sctx->last_str_idx); +#endif /* RE_ENABLE_I18N */ + + /* We don't check backreferences here. + See update_cur_sifted_state(). */ + if (!naccepted + && check_node_accept (mctx, dfa->nodes + prev_node, str_idx) + && STATE_NODE_CONTAINS (sctx->sifted_states[str_idx + 1], + dfa->nexts[prev_node])) + naccepted = 1; + + if (naccepted == 0) + continue; + + if (sctx->limits.nelem) + { + Idx to_idx = str_idx + naccepted; + if (check_dst_limits (mctx, &sctx->limits, + dfa->nexts[prev_node], to_idx, + prev_node, str_idx)) + continue; + } + ok = re_node_set_insert (cur_dest, prev_node); + if (BE (! ok, 0)) + return REG_ESPACE; + } + + return REG_NOERROR; +} + +/* Helper functions. */ + +static reg_errcode_t +internal_function +clean_state_log_if_needed (re_match_context_t *mctx, Idx next_state_log_idx) +{ + Idx top = mctx->state_log_top; + + if (next_state_log_idx >= mctx->input.bufs_len + || (next_state_log_idx >= mctx->input.valid_len + && mctx->input.valid_len < mctx->input.len)) + { + reg_errcode_t err; + err = extend_buffers (mctx); + if (BE (err != REG_NOERROR, 0)) + return err; + } + + if (top < next_state_log_idx) + { + memset (mctx->state_log + top + 1, '\0', + sizeof (re_dfastate_t *) * (next_state_log_idx - top)); + mctx->state_log_top = next_state_log_idx; + } + return REG_NOERROR; +} + +static reg_errcode_t +internal_function +merge_state_array (const re_dfa_t *dfa, re_dfastate_t **dst, + re_dfastate_t **src, Idx num) +{ + Idx st_idx; + reg_errcode_t err; + for (st_idx = 0; st_idx < num; ++st_idx) + { + if (dst[st_idx] == NULL) + dst[st_idx] = src[st_idx]; + else if (src[st_idx] != NULL) + { + re_node_set merged_set; + err = re_node_set_init_union (&merged_set, &dst[st_idx]->nodes, + &src[st_idx]->nodes); + if (BE (err != REG_NOERROR, 0)) + return err; + dst[st_idx] = re_acquire_state (&err, dfa, &merged_set); + re_node_set_free (&merged_set); + if (BE (err != REG_NOERROR, 0)) + return err; + } + } + return REG_NOERROR; +} + +static reg_errcode_t +internal_function +update_cur_sifted_state (const re_match_context_t *mctx, + re_sift_context_t *sctx, Idx str_idx, + re_node_set *dest_nodes) +{ + const re_dfa_t *const dfa = mctx->dfa; + reg_errcode_t err = REG_NOERROR; + const re_node_set *candidates; + candidates = ((mctx->state_log[str_idx] == NULL) ? NULL + : &mctx->state_log[str_idx]->nodes); + + if (dest_nodes->nelem == 0) + sctx->sifted_states[str_idx] = NULL; + else + { + if (candidates) + { + /* At first, add the nodes which can epsilon transit to a node in + DEST_NODE. */ + err = add_epsilon_src_nodes (dfa, dest_nodes, candidates); + if (BE (err != REG_NOERROR, 0)) + return err; + + /* Then, check the limitations in the current sift_context. */ + if (sctx->limits.nelem) + { + err = check_subexp_limits (dfa, dest_nodes, candidates, &sctx->limits, + mctx->bkref_ents, str_idx); + if (BE (err != REG_NOERROR, 0)) + return err; + } + } + + sctx->sifted_states[str_idx] = re_acquire_state (&err, dfa, dest_nodes); + if (BE (err != REG_NOERROR, 0)) + return err; + } + + if (candidates && mctx->state_log[str_idx]->has_backref) + { + err = sift_states_bkref (mctx, sctx, str_idx, candidates); + if (BE (err != REG_NOERROR, 0)) + return err; + } + return REG_NOERROR; +} + +static reg_errcode_t +internal_function +add_epsilon_src_nodes (const re_dfa_t *dfa, re_node_set *dest_nodes, + const re_node_set *candidates) +{ + reg_errcode_t err = REG_NOERROR; + Idx i; + + re_dfastate_t *state = re_acquire_state (&err, dfa, dest_nodes); + if (BE (err != REG_NOERROR, 0)) + return err; + + if (!state->inveclosure.alloc) + { + err = re_node_set_alloc (&state->inveclosure, dest_nodes->nelem); + if (BE (err != REG_NOERROR, 0)) + return REG_ESPACE; + for (i = 0; i < dest_nodes->nelem; i++) + re_node_set_merge (&state->inveclosure, + dfa->inveclosures + dest_nodes->elems[i]); + } + return re_node_set_add_intersect (dest_nodes, candidates, + &state->inveclosure); +} + +static reg_errcode_t +internal_function +sub_epsilon_src_nodes (const re_dfa_t *dfa, Idx node, re_node_set *dest_nodes, + const re_node_set *candidates) +{ + Idx ecl_idx; + reg_errcode_t err; + re_node_set *inv_eclosure = dfa->inveclosures + node; + re_node_set except_nodes; + re_node_set_init_empty (&except_nodes); + for (ecl_idx = 0; ecl_idx < inv_eclosure->nelem; ++ecl_idx) + { + Idx cur_node = inv_eclosure->elems[ecl_idx]; + if (cur_node == node) + continue; + if (IS_EPSILON_NODE (dfa->nodes[cur_node].type)) + { + Idx edst1 = dfa->edests[cur_node].elems[0]; + Idx edst2 = ((dfa->edests[cur_node].nelem > 1) + ? dfa->edests[cur_node].elems[1] : REG_MISSING); + if ((!re_node_set_contains (inv_eclosure, edst1) + && re_node_set_contains (dest_nodes, edst1)) + || (REG_VALID_NONZERO_INDEX (edst2) + && !re_node_set_contains (inv_eclosure, edst2) + && re_node_set_contains (dest_nodes, edst2))) + { + err = re_node_set_add_intersect (&except_nodes, candidates, + dfa->inveclosures + cur_node); + if (BE (err != REG_NOERROR, 0)) + { + re_node_set_free (&except_nodes); + return err; + } + } + } + } + for (ecl_idx = 0; ecl_idx < inv_eclosure->nelem; ++ecl_idx) + { + Idx cur_node = inv_eclosure->elems[ecl_idx]; + if (!re_node_set_contains (&except_nodes, cur_node)) + { + Idx idx = re_node_set_contains (dest_nodes, cur_node) - 1; + re_node_set_remove_at (dest_nodes, idx); + } + } + re_node_set_free (&except_nodes); + return REG_NOERROR; +} + +static bool +internal_function +check_dst_limits (const re_match_context_t *mctx, const re_node_set *limits, + Idx dst_node, Idx dst_idx, Idx src_node, Idx src_idx) +{ + const re_dfa_t *const dfa = mctx->dfa; + Idx lim_idx, src_pos, dst_pos; + + Idx dst_bkref_idx = search_cur_bkref_entry (mctx, dst_idx); + Idx src_bkref_idx = search_cur_bkref_entry (mctx, src_idx); + for (lim_idx = 0; lim_idx < limits->nelem; ++lim_idx) + { + Idx subexp_idx; + struct re_backref_cache_entry *ent; + ent = mctx->bkref_ents + limits->elems[lim_idx]; + subexp_idx = dfa->nodes[ent->node].opr.idx; + + dst_pos = check_dst_limits_calc_pos (mctx, limits->elems[lim_idx], + subexp_idx, dst_node, dst_idx, + dst_bkref_idx); + src_pos = check_dst_limits_calc_pos (mctx, limits->elems[lim_idx], + subexp_idx, src_node, src_idx, + src_bkref_idx); + + /* In case of: + ( ) + ( ) + ( ) */ + if (src_pos == dst_pos) + continue; /* This is unrelated limitation. */ + else + return true; + } + return false; +} + +static int +internal_function +check_dst_limits_calc_pos_1 (const re_match_context_t *mctx, int boundaries, + Idx subexp_idx, Idx from_node, Idx bkref_idx) +{ + const re_dfa_t *const dfa = mctx->dfa; + const re_node_set *eclosures = dfa->eclosures + from_node; + Idx node_idx; + + /* Else, we are on the boundary: examine the nodes on the epsilon + closure. */ + for (node_idx = 0; node_idx < eclosures->nelem; ++node_idx) + { + Idx node = eclosures->elems[node_idx]; + switch (dfa->nodes[node].type) + { + case OP_BACK_REF: + if (bkref_idx != REG_MISSING) + { + struct re_backref_cache_entry *ent = mctx->bkref_ents + bkref_idx; + do + { + Idx dst; + int cpos; + + if (ent->node != node) + continue; + + if (subexp_idx < BITSET_WORD_BITS + && !(ent->eps_reachable_subexps_map + & ((bitset_word_t) 1 << subexp_idx))) + continue; + + /* Recurse trying to reach the OP_OPEN_SUBEXP and + OP_CLOSE_SUBEXP cases below. But, if the + destination node is the same node as the source + node, don't recurse because it would cause an + infinite loop: a regex that exhibits this behavior + is ()\1*\1* */ + dst = dfa->edests[node].elems[0]; + if (dst == from_node) + { + if (boundaries & 1) + return -1; + else /* if (boundaries & 2) */ + return 0; + } + + cpos = + check_dst_limits_calc_pos_1 (mctx, boundaries, subexp_idx, + dst, bkref_idx); + if (cpos == -1 /* && (boundaries & 1) */) + return -1; + if (cpos == 0 && (boundaries & 2)) + return 0; + + if (subexp_idx < BITSET_WORD_BITS) + ent->eps_reachable_subexps_map + &= ~((bitset_word_t) 1 << subexp_idx); + } + while (ent++->more); + } + break; + + case OP_OPEN_SUBEXP: + if ((boundaries & 1) && subexp_idx == dfa->nodes[node].opr.idx) + return -1; + break; + + case OP_CLOSE_SUBEXP: + if ((boundaries & 2) && subexp_idx == dfa->nodes[node].opr.idx) + return 0; + break; + + default: + break; + } + } + + return (boundaries & 2) ? 1 : 0; +} + +static int +internal_function +check_dst_limits_calc_pos (const re_match_context_t *mctx, Idx limit, + Idx subexp_idx, Idx from_node, Idx str_idx, + Idx bkref_idx) +{ + struct re_backref_cache_entry *lim = mctx->bkref_ents + limit; + int boundaries; + + /* If we are outside the range of the subexpression, return -1 or 1. */ + if (str_idx < lim->subexp_from) + return -1; + + if (lim->subexp_to < str_idx) + return 1; + + /* If we are within the subexpression, return 0. */ + boundaries = (str_idx == lim->subexp_from); + boundaries |= (str_idx == lim->subexp_to) << 1; + if (boundaries == 0) + return 0; + + /* Else, examine epsilon closure. */ + return check_dst_limits_calc_pos_1 (mctx, boundaries, subexp_idx, + from_node, bkref_idx); +} + +/* Check the limitations of sub expressions LIMITS, and remove the nodes + which are against limitations from DEST_NODES. */ + +static reg_errcode_t +internal_function +check_subexp_limits (const re_dfa_t *dfa, re_node_set *dest_nodes, + const re_node_set *candidates, re_node_set *limits, + struct re_backref_cache_entry *bkref_ents, Idx str_idx) +{ + reg_errcode_t err; + Idx node_idx, lim_idx; + + for (lim_idx = 0; lim_idx < limits->nelem; ++lim_idx) + { + Idx subexp_idx; + struct re_backref_cache_entry *ent; + ent = bkref_ents + limits->elems[lim_idx]; + + if (str_idx <= ent->subexp_from || ent->str_idx < str_idx) + continue; /* This is unrelated limitation. */ + + subexp_idx = dfa->nodes[ent->node].opr.idx; + if (ent->subexp_to == str_idx) + { + Idx ops_node = REG_MISSING; + Idx cls_node = REG_MISSING; + for (node_idx = 0; node_idx < dest_nodes->nelem; ++node_idx) + { + Idx node = dest_nodes->elems[node_idx]; + re_token_type_t type = dfa->nodes[node].type; + if (type == OP_OPEN_SUBEXP + && subexp_idx == dfa->nodes[node].opr.idx) + ops_node = node; + else if (type == OP_CLOSE_SUBEXP + && subexp_idx == dfa->nodes[node].opr.idx) + cls_node = node; + } + + /* Check the limitation of the open subexpression. */ + /* Note that (ent->subexp_to = str_idx != ent->subexp_from). */ + if (REG_VALID_INDEX (ops_node)) + { + err = sub_epsilon_src_nodes (dfa, ops_node, dest_nodes, + candidates); + if (BE (err != REG_NOERROR, 0)) + return err; + } + + /* Check the limitation of the close subexpression. */ + if (REG_VALID_INDEX (cls_node)) + for (node_idx = 0; node_idx < dest_nodes->nelem; ++node_idx) + { + Idx node = dest_nodes->elems[node_idx]; + if (!re_node_set_contains (dfa->inveclosures + node, + cls_node) + && !re_node_set_contains (dfa->eclosures + node, + cls_node)) + { + /* It is against this limitation. + Remove it form the current sifted state. */ + err = sub_epsilon_src_nodes (dfa, node, dest_nodes, + candidates); + if (BE (err != REG_NOERROR, 0)) + return err; + --node_idx; + } + } + } + else /* (ent->subexp_to != str_idx) */ + { + for (node_idx = 0; node_idx < dest_nodes->nelem; ++node_idx) + { + Idx node = dest_nodes->elems[node_idx]; + re_token_type_t type = dfa->nodes[node].type; + if (type == OP_CLOSE_SUBEXP || type == OP_OPEN_SUBEXP) + { + if (subexp_idx != dfa->nodes[node].opr.idx) + continue; + /* It is against this limitation. + Remove it form the current sifted state. */ + err = sub_epsilon_src_nodes (dfa, node, dest_nodes, + candidates); + if (BE (err != REG_NOERROR, 0)) + return err; + } + } + } + } + return REG_NOERROR; +} + +static reg_errcode_t +internal_function +sift_states_bkref (const re_match_context_t *mctx, re_sift_context_t *sctx, + Idx str_idx, const re_node_set *candidates) +{ + const re_dfa_t *const dfa = mctx->dfa; + reg_errcode_t err; + Idx node_idx, node; + re_sift_context_t local_sctx; + Idx first_idx = search_cur_bkref_entry (mctx, str_idx); + + if (first_idx == REG_MISSING) + return REG_NOERROR; + + local_sctx.sifted_states = NULL; /* Mark that it hasn't been initialized. */ + + for (node_idx = 0; node_idx < candidates->nelem; ++node_idx) + { + Idx enabled_idx; + re_token_type_t type; + struct re_backref_cache_entry *entry; + node = candidates->elems[node_idx]; + type = dfa->nodes[node].type; + /* Avoid infinite loop for the REs like "()\1+". */ + if (node == sctx->last_node && str_idx == sctx->last_str_idx) + continue; + if (type != OP_BACK_REF) + continue; + + entry = mctx->bkref_ents + first_idx; + enabled_idx = first_idx; + do + { + Idx subexp_len; + Idx to_idx; + Idx dst_node; + bool ok; + re_dfastate_t *cur_state; + + if (entry->node != node) + continue; + subexp_len = entry->subexp_to - entry->subexp_from; + to_idx = str_idx + subexp_len; + dst_node = (subexp_len ? dfa->nexts[node] + : dfa->edests[node].elems[0]); + + if (to_idx > sctx->last_str_idx + || sctx->sifted_states[to_idx] == NULL + || !STATE_NODE_CONTAINS (sctx->sifted_states[to_idx], dst_node) + || check_dst_limits (mctx, &sctx->limits, node, + str_idx, dst_node, to_idx)) + continue; + + if (local_sctx.sifted_states == NULL) + { + local_sctx = *sctx; + err = re_node_set_init_copy (&local_sctx.limits, &sctx->limits); + if (BE (err != REG_NOERROR, 0)) + goto free_return; + } + local_sctx.last_node = node; + local_sctx.last_str_idx = str_idx; + ok = re_node_set_insert (&local_sctx.limits, enabled_idx); + if (BE (! ok, 0)) + { + err = REG_ESPACE; + goto free_return; + } + cur_state = local_sctx.sifted_states[str_idx]; + err = sift_states_backward (mctx, &local_sctx); + if (BE (err != REG_NOERROR, 0)) + goto free_return; + if (sctx->limited_states != NULL) + { + err = merge_state_array (dfa, sctx->limited_states, + local_sctx.sifted_states, + str_idx + 1); + if (BE (err != REG_NOERROR, 0)) + goto free_return; + } + local_sctx.sifted_states[str_idx] = cur_state; + re_node_set_remove (&local_sctx.limits, enabled_idx); + + /* mctx->bkref_ents may have changed, reload the pointer. */ + entry = mctx->bkref_ents + enabled_idx; + } + while (enabled_idx++, entry++->more); + } + err = REG_NOERROR; + free_return: + if (local_sctx.sifted_states != NULL) + { + re_node_set_free (&local_sctx.limits); + } + + return err; +} + + +#ifdef RE_ENABLE_I18N +static int +internal_function +sift_states_iter_mb (const re_match_context_t *mctx, re_sift_context_t *sctx, + Idx node_idx, Idx str_idx, Idx max_str_idx) +{ + const re_dfa_t *const dfa = mctx->dfa; + int naccepted; + /* Check the node can accept `multi byte'. */ + naccepted = check_node_accept_bytes (dfa, node_idx, &mctx->input, str_idx); + if (naccepted > 0 && str_idx + naccepted <= max_str_idx && + !STATE_NODE_CONTAINS (sctx->sifted_states[str_idx + naccepted], + dfa->nexts[node_idx])) + /* The node can't accept the `multi byte', or the + destination was already thrown away, then the node + could't accept the current input `multi byte'. */ + naccepted = 0; + /* Otherwise, it is sure that the node could accept + `naccepted' bytes input. */ + return naccepted; +} +#endif /* RE_ENABLE_I18N */ + + +/* Functions for state transition. */ + +/* Return the next state to which the current state STATE will transit by + accepting the current input byte, and update STATE_LOG if necessary. + If STATE can accept a multibyte char/collating element/back reference + update the destination of STATE_LOG. */ + +static re_dfastate_t * +internal_function +transit_state (reg_errcode_t *err, re_match_context_t *mctx, + re_dfastate_t *state) +{ + re_dfastate_t **trtable; + unsigned char ch; + +#ifdef RE_ENABLE_I18N + /* If the current state can accept multibyte. */ + if (BE (state->accept_mb, 0)) + { + *err = transit_state_mb (mctx, state); + if (BE (*err != REG_NOERROR, 0)) + return NULL; + } +#endif /* RE_ENABLE_I18N */ + + /* Then decide the next state with the single byte. */ +#if 0 + if (0) + /* don't use transition table */ + return transit_state_sb (err, mctx, state); +#endif + + /* Use transition table */ + ch = re_string_fetch_byte (&mctx->input); + for (;;) + { + trtable = state->trtable; + if (BE (trtable != NULL, 1)) + return trtable[ch]; + + trtable = state->word_trtable; + if (BE (trtable != NULL, 1)) + { + unsigned int context; + context + = re_string_context_at (&mctx->input, + re_string_cur_idx (&mctx->input) - 1, + mctx->eflags); + if (IS_WORD_CONTEXT (context)) + return trtable[ch + SBC_MAX]; + else + return trtable[ch]; + } + + if (!build_trtable (mctx->dfa, state)) + { + *err = REG_ESPACE; + return NULL; + } + + /* Retry, we now have a transition table. */ + } +} + +/* Update the state_log if we need */ +static re_dfastate_t * +internal_function +merge_state_with_log (reg_errcode_t *err, re_match_context_t *mctx, + re_dfastate_t *next_state) +{ + const re_dfa_t *const dfa = mctx->dfa; + Idx cur_idx = re_string_cur_idx (&mctx->input); + + if (cur_idx > mctx->state_log_top) + { + mctx->state_log[cur_idx] = next_state; + mctx->state_log_top = cur_idx; + } + else if (mctx->state_log[cur_idx] == 0) + { + mctx->state_log[cur_idx] = next_state; + } + else + { + re_dfastate_t *pstate; + unsigned int context; + re_node_set next_nodes, *log_nodes, *table_nodes = NULL; + /* If (state_log[cur_idx] != 0), it implies that cur_idx is + the destination of a multibyte char/collating element/ + back reference. Then the next state is the union set of + these destinations and the results of the transition table. */ + pstate = mctx->state_log[cur_idx]; + log_nodes = pstate->entrance_nodes; + if (next_state != NULL) + { + table_nodes = next_state->entrance_nodes; + *err = re_node_set_init_union (&next_nodes, table_nodes, + log_nodes); + if (BE (*err != REG_NOERROR, 0)) + return NULL; + } + else + next_nodes = *log_nodes; + /* Note: We already add the nodes of the initial state, + then we don't need to add them here. */ + + context = re_string_context_at (&mctx->input, + re_string_cur_idx (&mctx->input) - 1, + mctx->eflags); + next_state = mctx->state_log[cur_idx] + = re_acquire_state_context (err, dfa, &next_nodes, context); + /* We don't need to check errors here, since the return value of + this function is next_state and ERR is already set. */ + + if (table_nodes != NULL) + re_node_set_free (&next_nodes); + } + + if (BE (dfa->nbackref, 0) && next_state != NULL) + { + /* Check OP_OPEN_SUBEXP in the current state in case that we use them + later. We must check them here, since the back references in the + next state might use them. */ + *err = check_subexp_matching_top (mctx, &next_state->nodes, + cur_idx); + if (BE (*err != REG_NOERROR, 0)) + return NULL; + + /* If the next state has back references. */ + if (next_state->has_backref) + { + *err = transit_state_bkref (mctx, &next_state->nodes); + if (BE (*err != REG_NOERROR, 0)) + return NULL; + next_state = mctx->state_log[cur_idx]; + } + } + + return next_state; +} + +/* Skip bytes in the input that correspond to part of a + multi-byte match, then look in the log for a state + from which to restart matching. */ +static re_dfastate_t * +internal_function +find_recover_state (reg_errcode_t *err, re_match_context_t *mctx) +{ + re_dfastate_t *cur_state; + do + { + Idx max = mctx->state_log_top; + Idx cur_str_idx = re_string_cur_idx (&mctx->input); + + do + { + if (++cur_str_idx > max) + return NULL; + re_string_skip_bytes (&mctx->input, 1); + } + while (mctx->state_log[cur_str_idx] == NULL); + + cur_state = merge_state_with_log (err, mctx, NULL); + } + while (*err == REG_NOERROR && cur_state == NULL); + return cur_state; +} + +/* Helper functions for transit_state. */ + +/* From the node set CUR_NODES, pick up the nodes whose types are + OP_OPEN_SUBEXP and which have corresponding back references in the regular + expression. And register them to use them later for evaluating the + correspoding back references. */ + +static reg_errcode_t +internal_function +check_subexp_matching_top (re_match_context_t *mctx, re_node_set *cur_nodes, + Idx str_idx) +{ + const re_dfa_t *const dfa = mctx->dfa; + Idx node_idx; + reg_errcode_t err; + + /* TODO: This isn't efficient. + Because there might be more than one nodes whose types are + OP_OPEN_SUBEXP and whose index is SUBEXP_IDX, we must check all + nodes. + E.g. RE: (a){2} */ + for (node_idx = 0; node_idx < cur_nodes->nelem; ++node_idx) + { + Idx node = cur_nodes->elems[node_idx]; + if (dfa->nodes[node].type == OP_OPEN_SUBEXP + && dfa->nodes[node].opr.idx < BITSET_WORD_BITS + && (dfa->used_bkref_map + & ((bitset_word_t) 1 << dfa->nodes[node].opr.idx))) + { + err = match_ctx_add_subtop (mctx, node, str_idx); + if (BE (err != REG_NOERROR, 0)) + return err; + } + } + return REG_NOERROR; +} + +#if 0 +/* Return the next state to which the current state STATE will transit by + accepting the current input byte. */ + +static re_dfastate_t * +transit_state_sb (reg_errcode_t *err, re_match_context_t *mctx, + re_dfastate_t *state) +{ + const re_dfa_t *const dfa = mctx->dfa; + re_node_set next_nodes; + re_dfastate_t *next_state; + Idx node_cnt, cur_str_idx = re_string_cur_idx (&mctx->input); + unsigned int context; + + *err = re_node_set_alloc (&next_nodes, state->nodes.nelem + 1); + if (BE (*err != REG_NOERROR, 0)) + return NULL; + for (node_cnt = 0; node_cnt < state->nodes.nelem; ++node_cnt) + { + Idx cur_node = state->nodes.elems[node_cnt]; + if (check_node_accept (mctx, dfa->nodes + cur_node, cur_str_idx)) + { + *err = re_node_set_merge (&next_nodes, + dfa->eclosures + dfa->nexts[cur_node]); + if (BE (*err != REG_NOERROR, 0)) + { + re_node_set_free (&next_nodes); + return NULL; + } + } + } + context = re_string_context_at (&mctx->input, cur_str_idx, mctx->eflags); + next_state = re_acquire_state_context (err, dfa, &next_nodes, context); + /* We don't need to check errors here, since the return value of + this function is next_state and ERR is already set. */ + + re_node_set_free (&next_nodes); + re_string_skip_bytes (&mctx->input, 1); + return next_state; +} +#endif + +#ifdef RE_ENABLE_I18N +static reg_errcode_t +internal_function +transit_state_mb (re_match_context_t *mctx, re_dfastate_t *pstate) +{ + const re_dfa_t *const dfa = mctx->dfa; + reg_errcode_t err; + Idx i; + + for (i = 0; i < pstate->nodes.nelem; ++i) + { + re_node_set dest_nodes, *new_nodes; + Idx cur_node_idx = pstate->nodes.elems[i]; + int naccepted; + Idx dest_idx; + unsigned int context; + re_dfastate_t *dest_state; + + if (!dfa->nodes[cur_node_idx].accept_mb) + continue; + + if (dfa->nodes[cur_node_idx].constraint) + { + context = re_string_context_at (&mctx->input, + re_string_cur_idx (&mctx->input), + mctx->eflags); + if (NOT_SATISFY_NEXT_CONSTRAINT (dfa->nodes[cur_node_idx].constraint, + context)) + continue; + } + + /* How many bytes the node can accept? */ + naccepted = check_node_accept_bytes (dfa, cur_node_idx, &mctx->input, + re_string_cur_idx (&mctx->input)); + if (naccepted == 0) + continue; + + /* The node can accepts `naccepted' bytes. */ + dest_idx = re_string_cur_idx (&mctx->input) + naccepted; + mctx->max_mb_elem_len = ((mctx->max_mb_elem_len < naccepted) ? naccepted + : mctx->max_mb_elem_len); + err = clean_state_log_if_needed (mctx, dest_idx); + if (BE (err != REG_NOERROR, 0)) + return err; +#ifdef DEBUG + assert (dfa->nexts[cur_node_idx] != REG_MISSING); +#endif + new_nodes = dfa->eclosures + dfa->nexts[cur_node_idx]; + + dest_state = mctx->state_log[dest_idx]; + if (dest_state == NULL) + dest_nodes = *new_nodes; + else + { + err = re_node_set_init_union (&dest_nodes, + dest_state->entrance_nodes, new_nodes); + if (BE (err != REG_NOERROR, 0)) + return err; + } + context = re_string_context_at (&mctx->input, dest_idx - 1, + mctx->eflags); + mctx->state_log[dest_idx] + = re_acquire_state_context (&err, dfa, &dest_nodes, context); + if (dest_state != NULL) + re_node_set_free (&dest_nodes); + if (BE (mctx->state_log[dest_idx] == NULL && err != REG_NOERROR, 0)) + return err; + } + return REG_NOERROR; +} +#endif /* RE_ENABLE_I18N */ + +static reg_errcode_t +internal_function +transit_state_bkref (re_match_context_t *mctx, const re_node_set *nodes) +{ + const re_dfa_t *const dfa = mctx->dfa; + reg_errcode_t err; + Idx i; + Idx cur_str_idx = re_string_cur_idx (&mctx->input); + + for (i = 0; i < nodes->nelem; ++i) + { + Idx dest_str_idx, prev_nelem, bkc_idx; + Idx node_idx = nodes->elems[i]; + unsigned int context; + const re_token_t *node = dfa->nodes + node_idx; + re_node_set *new_dest_nodes; + + /* Check whether `node' is a backreference or not. */ + if (node->type != OP_BACK_REF) + continue; + + if (node->constraint) + { + context = re_string_context_at (&mctx->input, cur_str_idx, + mctx->eflags); + if (NOT_SATISFY_NEXT_CONSTRAINT (node->constraint, context)) + continue; + } + + /* `node' is a backreference. + Check the substring which the substring matched. */ + bkc_idx = mctx->nbkref_ents; + err = get_subexp (mctx, node_idx, cur_str_idx); + if (BE (err != REG_NOERROR, 0)) + goto free_return; + + /* And add the epsilon closures (which is `new_dest_nodes') of + the backreference to appropriate state_log. */ +#ifdef DEBUG + assert (dfa->nexts[node_idx] != REG_MISSING); +#endif + for (; bkc_idx < mctx->nbkref_ents; ++bkc_idx) + { + Idx subexp_len; + re_dfastate_t *dest_state; + struct re_backref_cache_entry *bkref_ent; + bkref_ent = mctx->bkref_ents + bkc_idx; + if (bkref_ent->node != node_idx || bkref_ent->str_idx != cur_str_idx) + continue; + subexp_len = bkref_ent->subexp_to - bkref_ent->subexp_from; + new_dest_nodes = (subexp_len == 0 + ? dfa->eclosures + dfa->edests[node_idx].elems[0] + : dfa->eclosures + dfa->nexts[node_idx]); + dest_str_idx = (cur_str_idx + bkref_ent->subexp_to + - bkref_ent->subexp_from); + context = re_string_context_at (&mctx->input, dest_str_idx - 1, + mctx->eflags); + dest_state = mctx->state_log[dest_str_idx]; + prev_nelem = ((mctx->state_log[cur_str_idx] == NULL) ? 0 + : mctx->state_log[cur_str_idx]->nodes.nelem); + /* Add `new_dest_node' to state_log. */ + if (dest_state == NULL) + { + mctx->state_log[dest_str_idx] + = re_acquire_state_context (&err, dfa, new_dest_nodes, + context); + if (BE (mctx->state_log[dest_str_idx] == NULL + && err != REG_NOERROR, 0)) + goto free_return; + } + else + { + re_node_set dest_nodes; + err = re_node_set_init_union (&dest_nodes, + dest_state->entrance_nodes, + new_dest_nodes); + if (BE (err != REG_NOERROR, 0)) + { + re_node_set_free (&dest_nodes); + goto free_return; + } + mctx->state_log[dest_str_idx] + = re_acquire_state_context (&err, dfa, &dest_nodes, context); + re_node_set_free (&dest_nodes); + if (BE (mctx->state_log[dest_str_idx] == NULL + && err != REG_NOERROR, 0)) + goto free_return; + } + /* We need to check recursively if the backreference can epsilon + transit. */ + if (subexp_len == 0 + && mctx->state_log[cur_str_idx]->nodes.nelem > prev_nelem) + { + err = check_subexp_matching_top (mctx, new_dest_nodes, + cur_str_idx); + if (BE (err != REG_NOERROR, 0)) + goto free_return; + err = transit_state_bkref (mctx, new_dest_nodes); + if (BE (err != REG_NOERROR, 0)) + goto free_return; + } + } + } + err = REG_NOERROR; + free_return: + return err; +} + +/* Enumerate all the candidates which the backreference BKREF_NODE can match + at BKREF_STR_IDX, and register them by match_ctx_add_entry(). + Note that we might collect inappropriate candidates here. + However, the cost of checking them strictly here is too high, then we + delay these checking for prune_impossible_nodes(). */ + +static reg_errcode_t +internal_function +get_subexp (re_match_context_t *mctx, Idx bkref_node, Idx bkref_str_idx) +{ + const re_dfa_t *const dfa = mctx->dfa; + Idx subexp_num, sub_top_idx; + const char *buf = (const char *) re_string_get_buffer (&mctx->input); + /* Return if we have already checked BKREF_NODE at BKREF_STR_IDX. */ + Idx cache_idx = search_cur_bkref_entry (mctx, bkref_str_idx); + if (cache_idx != REG_MISSING) + { + const struct re_backref_cache_entry *entry + = mctx->bkref_ents + cache_idx; + do + if (entry->node == bkref_node) + return REG_NOERROR; /* We already checked it. */ + while (entry++->more); + } + + subexp_num = dfa->nodes[bkref_node].opr.idx; + + /* For each sub expression */ + for (sub_top_idx = 0; sub_top_idx < mctx->nsub_tops; ++sub_top_idx) + { + reg_errcode_t err; + re_sub_match_top_t *sub_top = mctx->sub_tops[sub_top_idx]; + re_sub_match_last_t *sub_last; + Idx sub_last_idx, sl_str, bkref_str_off; + + if (dfa->nodes[sub_top->node].opr.idx != subexp_num) + continue; /* It isn't related. */ + + sl_str = sub_top->str_idx; + bkref_str_off = bkref_str_idx; + /* At first, check the last node of sub expressions we already + evaluated. */ + for (sub_last_idx = 0; sub_last_idx < sub_top->nlasts; ++sub_last_idx) + { + regoff_t sl_str_diff; + sub_last = sub_top->lasts[sub_last_idx]; + sl_str_diff = sub_last->str_idx - sl_str; + /* The matched string by the sub expression match with the substring + at the back reference? */ + if (sl_str_diff > 0) + { + if (BE (bkref_str_off + sl_str_diff > mctx->input.valid_len, 0)) + { + /* Not enough chars for a successful match. */ + if (bkref_str_off + sl_str_diff > mctx->input.len) + break; + + err = clean_state_log_if_needed (mctx, + bkref_str_off + + sl_str_diff); + if (BE (err != REG_NOERROR, 0)) + return err; + buf = (const char *) re_string_get_buffer (&mctx->input); + } + if (memcmp (buf + bkref_str_off, buf + sl_str, sl_str_diff) != 0) + /* We don't need to search this sub expression any more. */ + break; + } + bkref_str_off += sl_str_diff; + sl_str += sl_str_diff; + err = get_subexp_sub (mctx, sub_top, sub_last, bkref_node, + bkref_str_idx); + + /* Reload buf, since the preceding call might have reallocated + the buffer. */ + buf = (const char *) re_string_get_buffer (&mctx->input); + + if (err == REG_NOMATCH) + continue; + if (BE (err != REG_NOERROR, 0)) + return err; + } + + if (sub_last_idx < sub_top->nlasts) + continue; + if (sub_last_idx > 0) + ++sl_str; + /* Then, search for the other last nodes of the sub expression. */ + for (; sl_str <= bkref_str_idx; ++sl_str) + { + Idx cls_node; + regoff_t sl_str_off; + const re_node_set *nodes; + sl_str_off = sl_str - sub_top->str_idx; + /* The matched string by the sub expression match with the substring + at the back reference? */ + if (sl_str_off > 0) + { + if (BE (bkref_str_off >= mctx->input.valid_len, 0)) + { + /* If we are at the end of the input, we cannot match. */ + if (bkref_str_off >= mctx->input.len) + break; + + err = extend_buffers (mctx); + if (BE (err != REG_NOERROR, 0)) + return err; + + buf = (const char *) re_string_get_buffer (&mctx->input); + } + if (buf [bkref_str_off++] != buf[sl_str - 1]) + break; /* We don't need to search this sub expression + any more. */ + } + if (mctx->state_log[sl_str] == NULL) + continue; + /* Does this state have a ')' of the sub expression? */ + nodes = &mctx->state_log[sl_str]->nodes; + cls_node = find_subexp_node (dfa, nodes, subexp_num, + OP_CLOSE_SUBEXP); + if (cls_node == REG_MISSING) + continue; /* No. */ + if (sub_top->path == NULL) + { + sub_top->path = calloc (sizeof (state_array_t), + sl_str - sub_top->str_idx + 1); + if (sub_top->path == NULL) + return REG_ESPACE; + } + /* Can the OP_OPEN_SUBEXP node arrive the OP_CLOSE_SUBEXP node + in the current context? */ + err = check_arrival (mctx, sub_top->path, sub_top->node, + sub_top->str_idx, cls_node, sl_str, + OP_CLOSE_SUBEXP); + if (err == REG_NOMATCH) + continue; + if (BE (err != REG_NOERROR, 0)) + return err; + sub_last = match_ctx_add_sublast (sub_top, cls_node, sl_str); + if (BE (sub_last == NULL, 0)) + return REG_ESPACE; + err = get_subexp_sub (mctx, sub_top, sub_last, bkref_node, + bkref_str_idx); + if (err == REG_NOMATCH) + continue; + } + } + return REG_NOERROR; +} + +/* Helper functions for get_subexp(). */ + +/* Check SUB_LAST can arrive to the back reference BKREF_NODE at BKREF_STR. + If it can arrive, register the sub expression expressed with SUB_TOP + and SUB_LAST. */ + +static reg_errcode_t +internal_function +get_subexp_sub (re_match_context_t *mctx, const re_sub_match_top_t *sub_top, + re_sub_match_last_t *sub_last, Idx bkref_node, Idx bkref_str) +{ + reg_errcode_t err; + Idx to_idx; + /* Can the subexpression arrive the back reference? */ + err = check_arrival (mctx, &sub_last->path, sub_last->node, + sub_last->str_idx, bkref_node, bkref_str, + OP_OPEN_SUBEXP); + if (err != REG_NOERROR) + return err; + err = match_ctx_add_entry (mctx, bkref_node, bkref_str, sub_top->str_idx, + sub_last->str_idx); + if (BE (err != REG_NOERROR, 0)) + return err; + to_idx = bkref_str + sub_last->str_idx - sub_top->str_idx; + return clean_state_log_if_needed (mctx, to_idx); +} + +/* Find the first node which is '(' or ')' and whose index is SUBEXP_IDX. + Search '(' if FL_OPEN, or search ')' otherwise. + TODO: This function isn't efficient... + Because there might be more than one nodes whose types are + OP_OPEN_SUBEXP and whose index is SUBEXP_IDX, we must check all + nodes. + E.g. RE: (a){2} */ + +static Idx +internal_function +find_subexp_node (const re_dfa_t *dfa, const re_node_set *nodes, + Idx subexp_idx, int type) +{ + Idx cls_idx; + for (cls_idx = 0; cls_idx < nodes->nelem; ++cls_idx) + { + Idx cls_node = nodes->elems[cls_idx]; + const re_token_t *node = dfa->nodes + cls_node; + if (node->type == type + && node->opr.idx == subexp_idx) + return cls_node; + } + return REG_MISSING; +} + +/* Check whether the node TOP_NODE at TOP_STR can arrive to the node + LAST_NODE at LAST_STR. We record the path onto PATH since it will be + heavily reused. + Return REG_NOERROR if it can arrive, or REG_NOMATCH otherwise. */ + +static reg_errcode_t +internal_function +check_arrival (re_match_context_t *mctx, state_array_t *path, Idx top_node, + Idx top_str, Idx last_node, Idx last_str, int type) +{ + const re_dfa_t *const dfa = mctx->dfa; + reg_errcode_t err = REG_NOERROR; + Idx subexp_num, backup_cur_idx, str_idx, null_cnt; + re_dfastate_t *cur_state = NULL; + re_node_set *cur_nodes, next_nodes; + re_dfastate_t **backup_state_log; + unsigned int context; + + subexp_num = dfa->nodes[top_node].opr.idx; + /* Extend the buffer if we need. */ + if (BE (path->alloc < last_str + mctx->max_mb_elem_len + 1, 0)) + { + re_dfastate_t **new_array; + Idx old_alloc = path->alloc; + Idx new_alloc = old_alloc + last_str + mctx->max_mb_elem_len + 1; + if (BE (new_alloc < old_alloc, 0) + || BE (SIZE_MAX / sizeof (re_dfastate_t *) < new_alloc, 0)) + return REG_ESPACE; + new_array = re_realloc (path->array, re_dfastate_t *, new_alloc); + if (BE (new_array == NULL, 0)) + return REG_ESPACE; + path->array = new_array; + path->alloc = new_alloc; + memset (new_array + old_alloc, '\0', + sizeof (re_dfastate_t *) * (path->alloc - old_alloc)); + } + + str_idx = path->next_idx ? path->next_idx : top_str; + + /* Temporary modify MCTX. */ + backup_state_log = mctx->state_log; + backup_cur_idx = mctx->input.cur_idx; + mctx->state_log = path->array; + mctx->input.cur_idx = str_idx; + + /* Setup initial node set. */ + context = re_string_context_at (&mctx->input, str_idx - 1, mctx->eflags); + if (str_idx == top_str) + { + err = re_node_set_init_1 (&next_nodes, top_node); + if (BE (err != REG_NOERROR, 0)) + return err; + err = check_arrival_expand_ecl (dfa, &next_nodes, subexp_num, type); + if (BE (err != REG_NOERROR, 0)) + { + re_node_set_free (&next_nodes); + return err; + } + } + else + { + cur_state = mctx->state_log[str_idx]; + if (cur_state && cur_state->has_backref) + { + err = re_node_set_init_copy (&next_nodes, &cur_state->nodes); + if (BE (err != REG_NOERROR, 0)) + return err; + } + else + re_node_set_init_empty (&next_nodes); + } + if (str_idx == top_str || (cur_state && cur_state->has_backref)) + { + if (next_nodes.nelem) + { + err = expand_bkref_cache (mctx, &next_nodes, str_idx, + subexp_num, type); + if (BE (err != REG_NOERROR, 0)) + { + re_node_set_free (&next_nodes); + return err; + } + } + cur_state = re_acquire_state_context (&err, dfa, &next_nodes, context); + if (BE (cur_state == NULL && err != REG_NOERROR, 0)) + { + re_node_set_free (&next_nodes); + return err; + } + mctx->state_log[str_idx] = cur_state; + } + + for (null_cnt = 0; str_idx < last_str && null_cnt <= mctx->max_mb_elem_len;) + { + re_node_set_empty (&next_nodes); + if (mctx->state_log[str_idx + 1]) + { + err = re_node_set_merge (&next_nodes, + &mctx->state_log[str_idx + 1]->nodes); + if (BE (err != REG_NOERROR, 0)) + { + re_node_set_free (&next_nodes); + return err; + } + } + if (cur_state) + { + err = check_arrival_add_next_nodes (mctx, str_idx, + &cur_state->non_eps_nodes, + &next_nodes); + if (BE (err != REG_NOERROR, 0)) + { + re_node_set_free (&next_nodes); + return err; + } + } + ++str_idx; + if (next_nodes.nelem) + { + err = check_arrival_expand_ecl (dfa, &next_nodes, subexp_num, type); + if (BE (err != REG_NOERROR, 0)) + { + re_node_set_free (&next_nodes); + return err; + } + err = expand_bkref_cache (mctx, &next_nodes, str_idx, + subexp_num, type); + if (BE (err != REG_NOERROR, 0)) + { + re_node_set_free (&next_nodes); + return err; + } + } + context = re_string_context_at (&mctx->input, str_idx - 1, mctx->eflags); + cur_state = re_acquire_state_context (&err, dfa, &next_nodes, context); + if (BE (cur_state == NULL && err != REG_NOERROR, 0)) + { + re_node_set_free (&next_nodes); + return err; + } + mctx->state_log[str_idx] = cur_state; + null_cnt = cur_state == NULL ? null_cnt + 1 : 0; + } + re_node_set_free (&next_nodes); + cur_nodes = (mctx->state_log[last_str] == NULL ? NULL + : &mctx->state_log[last_str]->nodes); + path->next_idx = str_idx; + + /* Fix MCTX. */ + mctx->state_log = backup_state_log; + mctx->input.cur_idx = backup_cur_idx; + + /* Then check the current node set has the node LAST_NODE. */ + if (cur_nodes != NULL && re_node_set_contains (cur_nodes, last_node)) + return REG_NOERROR; + + return REG_NOMATCH; +} + +/* Helper functions for check_arrival. */ + +/* Calculate the destination nodes of CUR_NODES at STR_IDX, and append them + to NEXT_NODES. + TODO: This function is similar to the functions transit_state*(), + however this function has many additional works. + Can't we unify them? */ + +static reg_errcode_t +internal_function +check_arrival_add_next_nodes (re_match_context_t *mctx, Idx str_idx, + re_node_set *cur_nodes, re_node_set *next_nodes) +{ + const re_dfa_t *const dfa = mctx->dfa; + bool ok; + Idx cur_idx; +#ifdef RE_ENABLE_I18N + reg_errcode_t err = REG_NOERROR; +#endif + re_node_set union_set; + re_node_set_init_empty (&union_set); + for (cur_idx = 0; cur_idx < cur_nodes->nelem; ++cur_idx) + { + int naccepted = 0; + Idx cur_node = cur_nodes->elems[cur_idx]; +#ifdef DEBUG + re_token_type_t type = dfa->nodes[cur_node].type; + assert (!IS_EPSILON_NODE (type)); +#endif +#ifdef RE_ENABLE_I18N + /* If the node may accept `multi byte'. */ + if (dfa->nodes[cur_node].accept_mb) + { + naccepted = check_node_accept_bytes (dfa, cur_node, &mctx->input, + str_idx); + if (naccepted > 1) + { + re_dfastate_t *dest_state; + Idx next_node = dfa->nexts[cur_node]; + Idx next_idx = str_idx + naccepted; + dest_state = mctx->state_log[next_idx]; + re_node_set_empty (&union_set); + if (dest_state) + { + err = re_node_set_merge (&union_set, &dest_state->nodes); + if (BE (err != REG_NOERROR, 0)) + { + re_node_set_free (&union_set); + return err; + } + } + ok = re_node_set_insert (&union_set, next_node); + if (BE (! ok, 0)) + { + re_node_set_free (&union_set); + return REG_ESPACE; + } + mctx->state_log[next_idx] = re_acquire_state (&err, dfa, + &union_set); + if (BE (mctx->state_log[next_idx] == NULL + && err != REG_NOERROR, 0)) + { + re_node_set_free (&union_set); + return err; + } + } + } +#endif /* RE_ENABLE_I18N */ + if (naccepted + || check_node_accept (mctx, dfa->nodes + cur_node, str_idx)) + { + ok = re_node_set_insert (next_nodes, dfa->nexts[cur_node]); + if (BE (! ok, 0)) + { + re_node_set_free (&union_set); + return REG_ESPACE; + } + } + } + re_node_set_free (&union_set); + return REG_NOERROR; +} + +/* For all the nodes in CUR_NODES, add the epsilon closures of them to + CUR_NODES, however exclude the nodes which are: + - inside the sub expression whose number is EX_SUBEXP, if FL_OPEN. + - out of the sub expression whose number is EX_SUBEXP, if !FL_OPEN. +*/ + +static reg_errcode_t +internal_function +check_arrival_expand_ecl (const re_dfa_t *dfa, re_node_set *cur_nodes, + Idx ex_subexp, int type) +{ + reg_errcode_t err; + Idx idx, outside_node; + re_node_set new_nodes; +#ifdef DEBUG + assert (cur_nodes->nelem); +#endif + err = re_node_set_alloc (&new_nodes, cur_nodes->nelem); + if (BE (err != REG_NOERROR, 0)) + return err; + /* Create a new node set NEW_NODES with the nodes which are epsilon + closures of the node in CUR_NODES. */ + + for (idx = 0; idx < cur_nodes->nelem; ++idx) + { + Idx cur_node = cur_nodes->elems[idx]; + const re_node_set *eclosure = dfa->eclosures + cur_node; + outside_node = find_subexp_node (dfa, eclosure, ex_subexp, type); + if (outside_node == REG_MISSING) + { + /* There are no problematic nodes, just merge them. */ + err = re_node_set_merge (&new_nodes, eclosure); + if (BE (err != REG_NOERROR, 0)) + { + re_node_set_free (&new_nodes); + return err; + } + } + else + { + /* There are problematic nodes, re-calculate incrementally. */ + err = check_arrival_expand_ecl_sub (dfa, &new_nodes, cur_node, + ex_subexp, type); + if (BE (err != REG_NOERROR, 0)) + { + re_node_set_free (&new_nodes); + return err; + } + } + } + re_node_set_free (cur_nodes); + *cur_nodes = new_nodes; + return REG_NOERROR; +} + +/* Helper function for check_arrival_expand_ecl. + Check incrementally the epsilon closure of TARGET, and if it isn't + problematic append it to DST_NODES. */ + +static reg_errcode_t +internal_function +check_arrival_expand_ecl_sub (const re_dfa_t *dfa, re_node_set *dst_nodes, + Idx target, Idx ex_subexp, int type) +{ + Idx cur_node; + for (cur_node = target; !re_node_set_contains (dst_nodes, cur_node);) + { + bool ok; + + if (dfa->nodes[cur_node].type == type + && dfa->nodes[cur_node].opr.idx == ex_subexp) + { + if (type == OP_CLOSE_SUBEXP) + { + ok = re_node_set_insert (dst_nodes, cur_node); + if (BE (! ok, 0)) + return REG_ESPACE; + } + break; + } + ok = re_node_set_insert (dst_nodes, cur_node); + if (BE (! ok, 0)) + return REG_ESPACE; + if (dfa->edests[cur_node].nelem == 0) + break; + if (dfa->edests[cur_node].nelem == 2) + { + reg_errcode_t err; + err = check_arrival_expand_ecl_sub (dfa, dst_nodes, + dfa->edests[cur_node].elems[1], + ex_subexp, type); + if (BE (err != REG_NOERROR, 0)) + return err; + } + cur_node = dfa->edests[cur_node].elems[0]; + } + return REG_NOERROR; +} + + +/* For all the back references in the current state, calculate the + destination of the back references by the appropriate entry + in MCTX->BKREF_ENTS. */ + +static reg_errcode_t +internal_function +expand_bkref_cache (re_match_context_t *mctx, re_node_set *cur_nodes, + Idx cur_str, Idx subexp_num, int type) +{ + const re_dfa_t *const dfa = mctx->dfa; + reg_errcode_t err; + Idx cache_idx_start = search_cur_bkref_entry (mctx, cur_str); + struct re_backref_cache_entry *ent; + + if (cache_idx_start == REG_MISSING) + return REG_NOERROR; + + restart: + ent = mctx->bkref_ents + cache_idx_start; + do + { + Idx to_idx, next_node; + + /* Is this entry ENT is appropriate? */ + if (!re_node_set_contains (cur_nodes, ent->node)) + continue; /* No. */ + + to_idx = cur_str + ent->subexp_to - ent->subexp_from; + /* Calculate the destination of the back reference, and append it + to MCTX->STATE_LOG. */ + if (to_idx == cur_str) + { + /* The backreference did epsilon transit, we must re-check all the + node in the current state. */ + re_node_set new_dests; + reg_errcode_t err2, err3; + next_node = dfa->edests[ent->node].elems[0]; + if (re_node_set_contains (cur_nodes, next_node)) + continue; + err = re_node_set_init_1 (&new_dests, next_node); + err2 = check_arrival_expand_ecl (dfa, &new_dests, subexp_num, type); + err3 = re_node_set_merge (cur_nodes, &new_dests); + re_node_set_free (&new_dests); + if (BE (err != REG_NOERROR || err2 != REG_NOERROR + || err3 != REG_NOERROR, 0)) + { + err = (err != REG_NOERROR ? err + : (err2 != REG_NOERROR ? err2 : err3)); + return err; + } + /* TODO: It is still inefficient... */ + goto restart; + } + else + { + re_node_set union_set; + next_node = dfa->nexts[ent->node]; + if (mctx->state_log[to_idx]) + { + bool ok; + if (re_node_set_contains (&mctx->state_log[to_idx]->nodes, + next_node)) + continue; + err = re_node_set_init_copy (&union_set, + &mctx->state_log[to_idx]->nodes); + ok = re_node_set_insert (&union_set, next_node); + if (BE (err != REG_NOERROR || ! ok, 0)) + { + re_node_set_free (&union_set); + err = err != REG_NOERROR ? err : REG_ESPACE; + return err; + } + } + else + { + err = re_node_set_init_1 (&union_set, next_node); + if (BE (err != REG_NOERROR, 0)) + return err; + } + mctx->state_log[to_idx] = re_acquire_state (&err, dfa, &union_set); + re_node_set_free (&union_set); + if (BE (mctx->state_log[to_idx] == NULL + && err != REG_NOERROR, 0)) + return err; + } + } + while (ent++->more); + return REG_NOERROR; +} + +/* Build transition table for the state. + Return true if successful. */ + +static bool +internal_function +build_trtable (const re_dfa_t *dfa, re_dfastate_t *state) +{ + reg_errcode_t err; + Idx i, j; + int ch; + bool need_word_trtable = false; + bitset_word_t elem, mask; + bool dests_node_malloced = false; + bool dest_states_malloced = false; + Idx ndests; /* Number of the destination states from `state'. */ + re_dfastate_t **trtable; + re_dfastate_t **dest_states = NULL, **dest_states_word, **dest_states_nl; + re_node_set follows, *dests_node; + bitset_t *dests_ch; + bitset_t acceptable; + + struct dests_alloc + { + re_node_set dests_node[SBC_MAX]; + bitset_t dests_ch[SBC_MAX]; + } *dests_alloc; + + /* We build DFA states which corresponds to the destination nodes + from `state'. `dests_node[i]' represents the nodes which i-th + destination state contains, and `dests_ch[i]' represents the + characters which i-th destination state accepts. */ + if (__libc_use_alloca (sizeof (struct dests_alloc))) + dests_alloc = (struct dests_alloc *) alloca (sizeof (struct dests_alloc)); + else + { + dests_alloc = re_malloc (struct dests_alloc, 1); + if (BE (dests_alloc == NULL, 0)) + return false; + dests_node_malloced = true; + } + dests_node = dests_alloc->dests_node; + dests_ch = dests_alloc->dests_ch; + + /* Initialize transiton table. */ + state->word_trtable = state->trtable = NULL; + + /* At first, group all nodes belonging to `state' into several + destinations. */ + ndests = group_nodes_into_DFAstates (dfa, state, dests_node, dests_ch); + if (BE (! REG_VALID_NONZERO_INDEX (ndests), 0)) + { + if (dests_node_malloced) + free (dests_alloc); + if (ndests == 0) + { + state->trtable = (re_dfastate_t **) + calloc (sizeof (re_dfastate_t *), SBC_MAX); + return true; + } + return false; + } + + err = re_node_set_alloc (&follows, ndests + 1); + if (BE (err != REG_NOERROR, 0)) + goto out_free; + + /* Avoid arithmetic overflow in size calculation. */ + if (BE ((((SIZE_MAX - (sizeof (re_node_set) + sizeof (bitset_t)) * SBC_MAX) + / (3 * sizeof (re_dfastate_t *))) + < ndests), + 0)) + goto out_free; + + if (__libc_use_alloca ((sizeof (re_node_set) + sizeof (bitset_t)) * SBC_MAX + + ndests * 3 * sizeof (re_dfastate_t *))) + dest_states = (re_dfastate_t **) + alloca (ndests * 3 * sizeof (re_dfastate_t *)); + else + { + dest_states = (re_dfastate_t **) + malloc (ndests * 3 * sizeof (re_dfastate_t *)); + if (BE (dest_states == NULL, 0)) + { +out_free: + if (dest_states_malloced) + free (dest_states); + re_node_set_free (&follows); + for (i = 0; i < ndests; ++i) + re_node_set_free (dests_node + i); + if (dests_node_malloced) + free (dests_alloc); + return false; + } + dest_states_malloced = true; + } + dest_states_word = dest_states + ndests; + dest_states_nl = dest_states_word + ndests; + bitset_empty (acceptable); + + /* Then build the states for all destinations. */ + for (i = 0; i < ndests; ++i) + { + Idx next_node; + re_node_set_empty (&follows); + /* Merge the follows of this destination states. */ + for (j = 0; j < dests_node[i].nelem; ++j) + { + next_node = dfa->nexts[dests_node[i].elems[j]]; + if (next_node != REG_MISSING) + { + err = re_node_set_merge (&follows, dfa->eclosures + next_node); + if (BE (err != REG_NOERROR, 0)) + goto out_free; + } + } + dest_states[i] = re_acquire_state_context (&err, dfa, &follows, 0); + if (BE (dest_states[i] == NULL && err != REG_NOERROR, 0)) + goto out_free; + /* If the new state has context constraint, + build appropriate states for these contexts. */ + if (dest_states[i]->has_constraint) + { + dest_states_word[i] = re_acquire_state_context (&err, dfa, &follows, + CONTEXT_WORD); + if (BE (dest_states_word[i] == NULL && err != REG_NOERROR, 0)) + goto out_free; + + if (dest_states[i] != dest_states_word[i] && dfa->mb_cur_max > 1) + need_word_trtable = true; + + dest_states_nl[i] = re_acquire_state_context (&err, dfa, &follows, + CONTEXT_NEWLINE); + if (BE (dest_states_nl[i] == NULL && err != REG_NOERROR, 0)) + goto out_free; + } + else + { + dest_states_word[i] = dest_states[i]; + dest_states_nl[i] = dest_states[i]; + } + bitset_merge (acceptable, dests_ch[i]); + } + + if (!BE (need_word_trtable, 0)) + { + /* We don't care about whether the following character is a word + character, or we are in a single-byte character set so we can + discern by looking at the character code: allocate a + 256-entry transition table. */ + trtable = state->trtable = + (re_dfastate_t **) calloc (sizeof (re_dfastate_t *), SBC_MAX); + if (BE (trtable == NULL, 0)) + goto out_free; + + /* For all characters ch...: */ + for (i = 0; i < BITSET_WORDS; ++i) + for (ch = i * BITSET_WORD_BITS, elem = acceptable[i], mask = 1; + elem; + mask <<= 1, elem >>= 1, ++ch) + if (BE (elem & 1, 0)) + { + /* There must be exactly one destination which accepts + character ch. See group_nodes_into_DFAstates. */ + for (j = 0; (dests_ch[j][i] & mask) == 0; ++j) + ; + + /* j-th destination accepts the word character ch. */ + if (dfa->word_char[i] & mask) + trtable[ch] = dest_states_word[j]; + else + trtable[ch] = dest_states[j]; + } + } + else + { + /* We care about whether the following character is a word + character, and we are in a multi-byte character set: discern + by looking at the character code: build two 256-entry + transition tables, one starting at trtable[0] and one + starting at trtable[SBC_MAX]. */ + trtable = state->word_trtable = + (re_dfastate_t **) calloc (sizeof (re_dfastate_t *), 2 * SBC_MAX); + if (BE (trtable == NULL, 0)) + goto out_free; + + /* For all characters ch...: */ + for (i = 0; i < BITSET_WORDS; ++i) + for (ch = i * BITSET_WORD_BITS, elem = acceptable[i], mask = 1; + elem; + mask <<= 1, elem >>= 1, ++ch) + if (BE (elem & 1, 0)) + { + /* There must be exactly one destination which accepts + character ch. See group_nodes_into_DFAstates. */ + for (j = 0; (dests_ch[j][i] & mask) == 0; ++j) + ; + + /* j-th destination accepts the word character ch. */ + trtable[ch] = dest_states[j]; + trtable[ch + SBC_MAX] = dest_states_word[j]; + } + } + + /* new line */ + if (bitset_contain (acceptable, NEWLINE_CHAR)) + { + /* The current state accepts newline character. */ + for (j = 0; j < ndests; ++j) + if (bitset_contain (dests_ch[j], NEWLINE_CHAR)) + { + /* k-th destination accepts newline character. */ + trtable[NEWLINE_CHAR] = dest_states_nl[j]; + if (need_word_trtable) + trtable[NEWLINE_CHAR + SBC_MAX] = dest_states_nl[j]; + /* There must be only one destination which accepts + newline. See group_nodes_into_DFAstates. */ + break; + } + } + + if (dest_states_malloced) + free (dest_states); + + re_node_set_free (&follows); + for (i = 0; i < ndests; ++i) + re_node_set_free (dests_node + i); + + if (dests_node_malloced) + free (dests_alloc); + + return true; +} + +/* Group all nodes belonging to STATE into several destinations. + Then for all destinations, set the nodes belonging to the destination + to DESTS_NODE[i] and set the characters accepted by the destination + to DEST_CH[i]. This function return the number of destinations. */ + +static Idx +internal_function +group_nodes_into_DFAstates (const re_dfa_t *dfa, const re_dfastate_t *state, + re_node_set *dests_node, bitset_t *dests_ch) +{ + reg_errcode_t err; + bool ok; + Idx i, j, k; + Idx ndests; /* Number of the destinations from `state'. */ + bitset_t accepts; /* Characters a node can accept. */ + const re_node_set *cur_nodes = &state->nodes; + bitset_empty (accepts); + ndests = 0; + + /* For all the nodes belonging to `state', */ + for (i = 0; i < cur_nodes->nelem; ++i) + { + re_token_t *node = &dfa->nodes[cur_nodes->elems[i]]; + re_token_type_t type = node->type; + unsigned int constraint = node->constraint; + + /* Enumerate all single byte character this node can accept. */ + if (type == CHARACTER) + bitset_set (accepts, node->opr.c); + else if (type == SIMPLE_BRACKET) + { + bitset_merge (accepts, node->opr.sbcset); + } + else if (type == OP_PERIOD) + { +#ifdef RE_ENABLE_I18N + if (dfa->mb_cur_max > 1) + bitset_merge (accepts, dfa->sb_char); + else +#endif + bitset_set_all (accepts); + if (!(dfa->syntax & RE_DOT_NEWLINE)) + bitset_clear (accepts, '\n'); + if (dfa->syntax & RE_DOT_NOT_NULL) + bitset_clear (accepts, '\0'); + } +#ifdef RE_ENABLE_I18N + else if (type == OP_UTF8_PERIOD) + { + if (ASCII_CHARS % BITSET_WORD_BITS == 0) + memset (accepts, -1, ASCII_CHARS / CHAR_BIT); + else + bitset_merge (accepts, utf8_sb_map); + if (!(dfa->syntax & RE_DOT_NEWLINE)) + bitset_clear (accepts, '\n'); + if (dfa->syntax & RE_DOT_NOT_NULL) + bitset_clear (accepts, '\0'); + } +#endif + else + continue; + + /* Check the `accepts' and sift the characters which are not + match it the context. */ + if (constraint) + { + if (constraint & NEXT_NEWLINE_CONSTRAINT) + { + bool accepts_newline = bitset_contain (accepts, NEWLINE_CHAR); + bitset_empty (accepts); + if (accepts_newline) + bitset_set (accepts, NEWLINE_CHAR); + else + continue; + } + if (constraint & NEXT_ENDBUF_CONSTRAINT) + { + bitset_empty (accepts); + continue; + } + + if (constraint & NEXT_WORD_CONSTRAINT) + { + bitset_word_t any_set = 0; + if (type == CHARACTER && !node->word_char) + { + bitset_empty (accepts); + continue; + } +#ifdef RE_ENABLE_I18N + if (dfa->mb_cur_max > 1) + for (j = 0; j < BITSET_WORDS; ++j) + any_set |= (accepts[j] &= (dfa->word_char[j] | ~dfa->sb_char[j])); + else +#endif + for (j = 0; j < BITSET_WORDS; ++j) + any_set |= (accepts[j] &= dfa->word_char[j]); + if (!any_set) + continue; + } + if (constraint & NEXT_NOTWORD_CONSTRAINT) + { + bitset_word_t any_set = 0; + if (type == CHARACTER && node->word_char) + { + bitset_empty (accepts); + continue; + } +#ifdef RE_ENABLE_I18N + if (dfa->mb_cur_max > 1) + for (j = 0; j < BITSET_WORDS; ++j) + any_set |= (accepts[j] &= ~(dfa->word_char[j] & dfa->sb_char[j])); + else +#endif + for (j = 0; j < BITSET_WORDS; ++j) + any_set |= (accepts[j] &= ~dfa->word_char[j]); + if (!any_set) + continue; + } + } + + /* Then divide `accepts' into DFA states, or create a new + state. Above, we make sure that accepts is not empty. */ + for (j = 0; j < ndests; ++j) + { + bitset_t intersec; /* Intersection sets, see below. */ + bitset_t remains; + /* Flags, see below. */ + bitset_word_t has_intersec, not_subset, not_consumed; + + /* Optimization, skip if this state doesn't accept the character. */ + if (type == CHARACTER && !bitset_contain (dests_ch[j], node->opr.c)) + continue; + + /* Enumerate the intersection set of this state and `accepts'. */ + has_intersec = 0; + for (k = 0; k < BITSET_WORDS; ++k) + has_intersec |= intersec[k] = accepts[k] & dests_ch[j][k]; + /* And skip if the intersection set is empty. */ + if (!has_intersec) + continue; + + /* Then check if this state is a subset of `accepts'. */ + not_subset = not_consumed = 0; + for (k = 0; k < BITSET_WORDS; ++k) + { + not_subset |= remains[k] = ~accepts[k] & dests_ch[j][k]; + not_consumed |= accepts[k] = accepts[k] & ~dests_ch[j][k]; + } + + /* If this state isn't a subset of `accepts', create a + new group state, which has the `remains'. */ + if (not_subset) + { + bitset_copy (dests_ch[ndests], remains); + bitset_copy (dests_ch[j], intersec); + err = re_node_set_init_copy (dests_node + ndests, &dests_node[j]); + if (BE (err != REG_NOERROR, 0)) + goto error_return; + ++ndests; + } + + /* Put the position in the current group. */ + ok = re_node_set_insert (&dests_node[j], cur_nodes->elems[i]); + if (BE (! ok, 0)) + goto error_return; + + /* If all characters are consumed, go to next node. */ + if (!not_consumed) + break; + } + /* Some characters remain, create a new group. */ + if (j == ndests) + { + bitset_copy (dests_ch[ndests], accepts); + err = re_node_set_init_1 (dests_node + ndests, cur_nodes->elems[i]); + if (BE (err != REG_NOERROR, 0)) + goto error_return; + ++ndests; + bitset_empty (accepts); + } + } + return ndests; + error_return: + for (j = 0; j < ndests; ++j) + re_node_set_free (dests_node + j); + return REG_MISSING; +} + +#ifdef RE_ENABLE_I18N +/* Check how many bytes the node `dfa->nodes[node_idx]' accepts. + Return the number of the bytes the node accepts. + STR_IDX is the current index of the input string. + + This function handles the nodes which can accept one character, or + one collating element like '.', '[a-z]', opposite to the other nodes + can only accept one byte. */ + +static int +internal_function +check_node_accept_bytes (const re_dfa_t *dfa, Idx node_idx, + const re_string_t *input, Idx str_idx) +{ + const re_token_t *node = dfa->nodes + node_idx; + int char_len, elem_len; + Idx i; + + if (BE (node->type == OP_UTF8_PERIOD, 0)) + { + unsigned char c = re_string_byte_at (input, str_idx), d; + if (BE (c < 0xc2, 1)) + return 0; + + if (str_idx + 2 > input->len) + return 0; + + d = re_string_byte_at (input, str_idx + 1); + if (c < 0xe0) + return (d < 0x80 || d > 0xbf) ? 0 : 2; + else if (c < 0xf0) + { + char_len = 3; + if (c == 0xe0 && d < 0xa0) + return 0; + } + else if (c < 0xf8) + { + char_len = 4; + if (c == 0xf0 && d < 0x90) + return 0; + } + else if (c < 0xfc) + { + char_len = 5; + if (c == 0xf8 && d < 0x88) + return 0; + } + else if (c < 0xfe) + { + char_len = 6; + if (c == 0xfc && d < 0x84) + return 0; + } + else + return 0; + + if (str_idx + char_len > input->len) + return 0; + + for (i = 1; i < char_len; ++i) + { + d = re_string_byte_at (input, str_idx + i); + if (d < 0x80 || d > 0xbf) + return 0; + } + return char_len; + } + + char_len = re_string_char_size_at (input, str_idx); + if (node->type == OP_PERIOD) + { + if (char_len <= 1) + return 0; + /* FIXME: I don't think this if is needed, as both '\n' + and '\0' are char_len == 1. */ + /* '.' accepts any one character except the following two cases. */ + if ((!(dfa->syntax & RE_DOT_NEWLINE) && + re_string_byte_at (input, str_idx) == '\n') || + ((dfa->syntax & RE_DOT_NOT_NULL) && + re_string_byte_at (input, str_idx) == '\0')) + return 0; + return char_len; + } + + elem_len = re_string_elem_size_at (input, str_idx); + if ((elem_len <= 1 && char_len <= 1) || char_len == 0) + return 0; + + if (node->type == COMPLEX_BRACKET) + { + const re_charset_t *cset = node->opr.mbcset; +# ifdef _LIBC + const unsigned char *pin + = ((const unsigned char *) re_string_get_buffer (input) + str_idx); + Idx j; + uint32_t nrules; +# endif /* _LIBC */ + int match_len = 0; + wchar_t wc = ((cset->nranges || cset->nchar_classes || cset->nmbchars) + ? re_string_wchar_at (input, str_idx) : 0); + + /* match with multibyte character? */ + for (i = 0; i < cset->nmbchars; ++i) + if (wc == cset->mbchars[i]) + { + match_len = char_len; + goto check_node_accept_bytes_match; + } + /* match with character_class? */ + for (i = 0; i < cset->nchar_classes; ++i) + { + wctype_t wt = cset->char_classes[i]; + if (__iswctype (wc, wt)) + { + match_len = char_len; + goto check_node_accept_bytes_match; + } + } + +# ifdef _LIBC + nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES); + if (nrules != 0) + { + unsigned int in_collseq = 0; + const int32_t *table, *indirect; + const unsigned char *weights, *extra; + const char *collseqwc; + int32_t idx; + /* This #include defines a local function! */ +# include + + /* match with collating_symbol? */ + if (cset->ncoll_syms) + extra = (const unsigned char *) + _NL_CURRENT (LC_COLLATE, _NL_COLLATE_SYMB_EXTRAMB); + for (i = 0; i < cset->ncoll_syms; ++i) + { + const unsigned char *coll_sym = extra + cset->coll_syms[i]; + /* Compare the length of input collating element and + the length of current collating element. */ + if (*coll_sym != elem_len) + continue; + /* Compare each bytes. */ + for (j = 0; j < *coll_sym; j++) + if (pin[j] != coll_sym[1 + j]) + break; + if (j == *coll_sym) + { + /* Match if every bytes is equal. */ + match_len = j; + goto check_node_accept_bytes_match; + } + } + + if (cset->nranges) + { + if (elem_len <= char_len) + { + collseqwc = _NL_CURRENT (LC_COLLATE, _NL_COLLATE_COLLSEQWC); + in_collseq = __collseq_table_lookup (collseqwc, wc); + } + else + in_collseq = find_collation_sequence_value (pin, elem_len); + } + /* match with range expression? */ + for (i = 0; i < cset->nranges; ++i) + if (cset->range_starts[i] <= in_collseq + && in_collseq <= cset->range_ends[i]) + { + match_len = elem_len; + goto check_node_accept_bytes_match; + } + + /* match with equivalence_class? */ + if (cset->nequiv_classes) + { + const unsigned char *cp = pin; + table = (const int32_t *) + _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB); + weights = (const unsigned char *) + _NL_CURRENT (LC_COLLATE, _NL_COLLATE_WEIGHTMB); + extra = (const unsigned char *) + _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAMB); + indirect = (const int32_t *) + _NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTMB); + idx = findidx (&cp); + if (idx > 0) + for (i = 0; i < cset->nequiv_classes; ++i) + { + int32_t equiv_class_idx = cset->equiv_classes[i]; + size_t weight_len = weights[idx]; + if (weight_len == weights[equiv_class_idx]) + { + Idx cnt = 0; + while (cnt <= weight_len + && (weights[equiv_class_idx + 1 + cnt] + == weights[idx + 1 + cnt])) + ++cnt; + if (cnt > weight_len) + { + match_len = elem_len; + goto check_node_accept_bytes_match; + } + } + } + } + } + else +# endif /* _LIBC */ + { + /* match with range expression? */ +#if __GNUC__ >= 2 && ! (__STDC_VERSION__ < 199901L && __STRICT_ANSI__) + wchar_t cmp_buf[] = {L'\0', L'\0', wc, L'\0', L'\0', L'\0'}; +#else + wchar_t cmp_buf[] = {L'\0', L'\0', L'\0', L'\0', L'\0', L'\0'}; + cmp_buf[2] = wc; +#endif + for (i = 0; i < cset->nranges; ++i) + { + cmp_buf[0] = cset->range_starts[i]; + cmp_buf[4] = cset->range_ends[i]; + if (wcscoll (cmp_buf, cmp_buf + 2) <= 0 + && wcscoll (cmp_buf + 2, cmp_buf + 4) <= 0) + { + match_len = char_len; + goto check_node_accept_bytes_match; + } + } + } + check_node_accept_bytes_match: + if (!cset->non_match) + return match_len; + else + { + if (match_len > 0) + return 0; + else + return (elem_len > char_len) ? elem_len : char_len; + } + } + return 0; +} + +# ifdef _LIBC +static unsigned int +internal_function +find_collation_sequence_value (const unsigned char *mbs, size_t mbs_len) +{ + uint32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES); + if (nrules == 0) + { + if (mbs_len == 1) + { + /* No valid character. Match it as a single byte character. */ + const unsigned char *collseq = (const unsigned char *) + _NL_CURRENT (LC_COLLATE, _NL_COLLATE_COLLSEQMB); + return collseq[mbs[0]]; + } + return UINT_MAX; + } + else + { + int32_t idx; + const unsigned char *extra = (const unsigned char *) + _NL_CURRENT (LC_COLLATE, _NL_COLLATE_SYMB_EXTRAMB); + int32_t extrasize = (const unsigned char *) + _NL_CURRENT (LC_COLLATE, _NL_COLLATE_SYMB_EXTRAMB + 1) - extra; + + for (idx = 0; idx < extrasize;) + { + int mbs_cnt; + bool found = false; + int32_t elem_mbs_len; + /* Skip the name of collating element name. */ + idx = idx + extra[idx] + 1; + elem_mbs_len = extra[idx++]; + if (mbs_len == elem_mbs_len) + { + for (mbs_cnt = 0; mbs_cnt < elem_mbs_len; ++mbs_cnt) + if (extra[idx + mbs_cnt] != mbs[mbs_cnt]) + break; + if (mbs_cnt == elem_mbs_len) + /* Found the entry. */ + found = true; + } + /* Skip the byte sequence of the collating element. */ + idx += elem_mbs_len; + /* Adjust for the alignment. */ + idx = (idx + 3) & ~3; + /* Skip the collation sequence value. */ + idx += sizeof (uint32_t); + /* Skip the wide char sequence of the collating element. */ + idx = idx + sizeof (uint32_t) * (extra[idx] + 1); + /* If we found the entry, return the sequence value. */ + if (found) + return *(uint32_t *) (extra + idx); + /* Skip the collation sequence value. */ + idx += sizeof (uint32_t); + } + return UINT_MAX; + } +} +# endif /* _LIBC */ +#endif /* RE_ENABLE_I18N */ + +/* Check whether the node accepts the byte which is IDX-th + byte of the INPUT. */ + +static bool +internal_function +check_node_accept (const re_match_context_t *mctx, const re_token_t *node, + Idx idx) +{ + unsigned char ch; + ch = re_string_byte_at (&mctx->input, idx); + switch (node->type) + { + case CHARACTER: + if (node->opr.c != ch) + return false; + break; + + case SIMPLE_BRACKET: + if (!bitset_contain (node->opr.sbcset, ch)) + return false; + break; + +#ifdef RE_ENABLE_I18N + case OP_UTF8_PERIOD: + if (ch >= ASCII_CHARS) + return false; + /* FALLTHROUGH */ +#endif + case OP_PERIOD: + if ((ch == '\n' && !(mctx->dfa->syntax & RE_DOT_NEWLINE)) + || (ch == '\0' && (mctx->dfa->syntax & RE_DOT_NOT_NULL))) + return false; + break; + + default: + return false; + } + + if (node->constraint) + { + /* The node has constraints. Check whether the current context + satisfies the constraints. */ + unsigned int context = re_string_context_at (&mctx->input, idx, + mctx->eflags); + if (NOT_SATISFY_NEXT_CONSTRAINT (node->constraint, context)) + return false; + } + + return true; +} + +/* Extend the buffers, if the buffers have run out. */ + +static reg_errcode_t +internal_function +extend_buffers (re_match_context_t *mctx) +{ + reg_errcode_t ret; + re_string_t *pstr = &mctx->input; + + /* Avoid overflow. */ + if (BE (SIZE_MAX / 2 / sizeof (re_dfastate_t *) <= pstr->bufs_len, 0)) + return REG_ESPACE; + + /* Double the lengthes of the buffers. */ + ret = re_string_realloc_buffers (pstr, pstr->bufs_len * 2); + if (BE (ret != REG_NOERROR, 0)) + return ret; + + if (mctx->state_log != NULL) + { + /* And double the length of state_log. */ + /* XXX We have no indication of the size of this buffer. If this + allocation fail we have no indication that the state_log array + does not have the right size. */ + re_dfastate_t **new_array = re_realloc (mctx->state_log, re_dfastate_t *, + pstr->bufs_len + 1); + if (BE (new_array == NULL, 0)) + return REG_ESPACE; + mctx->state_log = new_array; + } + + /* Then reconstruct the buffers. */ + if (pstr->icase) + { +#ifdef RE_ENABLE_I18N + if (pstr->mb_cur_max > 1) + { + ret = build_wcs_upper_buffer (pstr); + if (BE (ret != REG_NOERROR, 0)) + return ret; + } + else +#endif /* RE_ENABLE_I18N */ + build_upper_buffer (pstr); + } + else + { +#ifdef RE_ENABLE_I18N + if (pstr->mb_cur_max > 1) + build_wcs_buffer (pstr); + else +#endif /* RE_ENABLE_I18N */ + { + if (pstr->trans != NULL) + re_string_translate_buffer (pstr); + } + } + return REG_NOERROR; +} + + +/* Functions for matching context. */ + +/* Initialize MCTX. */ + +static reg_errcode_t +internal_function +match_ctx_init (re_match_context_t *mctx, int eflags, Idx n) +{ + mctx->eflags = eflags; + mctx->match_last = REG_MISSING; + if (n > 0) + { + /* Avoid overflow. */ + size_t max_object_size = + MAX (sizeof (struct re_backref_cache_entry), + sizeof (re_sub_match_top_t *)); + if (BE (SIZE_MAX / max_object_size < n, 0)) + return REG_ESPACE; + + mctx->bkref_ents = re_malloc (struct re_backref_cache_entry, n); + mctx->sub_tops = re_malloc (re_sub_match_top_t *, n); + if (BE (mctx->bkref_ents == NULL || mctx->sub_tops == NULL, 0)) + return REG_ESPACE; + } + /* Already zero-ed by the caller. + else + mctx->bkref_ents = NULL; + mctx->nbkref_ents = 0; + mctx->nsub_tops = 0; */ + mctx->abkref_ents = n; + mctx->max_mb_elem_len = 1; + mctx->asub_tops = n; + return REG_NOERROR; +} + +/* Clean the entries which depend on the current input in MCTX. + This function must be invoked when the matcher changes the start index + of the input, or changes the input string. */ + +static void +internal_function +match_ctx_clean (re_match_context_t *mctx) +{ + Idx st_idx; + for (st_idx = 0; st_idx < mctx->nsub_tops; ++st_idx) + { + Idx sl_idx; + re_sub_match_top_t *top = mctx->sub_tops[st_idx]; + for (sl_idx = 0; sl_idx < top->nlasts; ++sl_idx) + { + re_sub_match_last_t *last = top->lasts[sl_idx]; + re_free (last->path.array); + re_free (last); + } + re_free (top->lasts); + if (top->path) + { + re_free (top->path->array); + re_free (top->path); + } + free (top); + } + + mctx->nsub_tops = 0; + mctx->nbkref_ents = 0; +} + +/* Free all the memory associated with MCTX. */ + +static void +internal_function +match_ctx_free (re_match_context_t *mctx) +{ + /* First, free all the memory associated with MCTX->SUB_TOPS. */ + match_ctx_clean (mctx); + re_free (mctx->sub_tops); + re_free (mctx->bkref_ents); +} + +/* Add a new backreference entry to MCTX. + Note that we assume that caller never call this function with duplicate + entry, and call with STR_IDX which isn't smaller than any existing entry. +*/ + +static reg_errcode_t +internal_function +match_ctx_add_entry (re_match_context_t *mctx, Idx node, Idx str_idx, Idx from, + Idx to) +{ + if (mctx->nbkref_ents >= mctx->abkref_ents) + { + struct re_backref_cache_entry* new_entry; + new_entry = re_realloc (mctx->bkref_ents, struct re_backref_cache_entry, + mctx->abkref_ents * 2); + if (BE (new_entry == NULL, 0)) + { + re_free (mctx->bkref_ents); + return REG_ESPACE; + } + mctx->bkref_ents = new_entry; + memset (mctx->bkref_ents + mctx->nbkref_ents, '\0', + sizeof (struct re_backref_cache_entry) * mctx->abkref_ents); + mctx->abkref_ents *= 2; + } + if (mctx->nbkref_ents > 0 + && mctx->bkref_ents[mctx->nbkref_ents - 1].str_idx == str_idx) + mctx->bkref_ents[mctx->nbkref_ents - 1].more = 1; + + mctx->bkref_ents[mctx->nbkref_ents].node = node; + mctx->bkref_ents[mctx->nbkref_ents].str_idx = str_idx; + mctx->bkref_ents[mctx->nbkref_ents].subexp_from = from; + mctx->bkref_ents[mctx->nbkref_ents].subexp_to = to; + + /* This is a cache that saves negative results of check_dst_limits_calc_pos. + If bit N is clear, means that this entry won't epsilon-transition to + an OP_OPEN_SUBEXP or OP_CLOSE_SUBEXP for the N+1-th subexpression. If + it is set, check_dst_limits_calc_pos_1 will recurse and try to find one + such node. + + A backreference does not epsilon-transition unless it is empty, so set + to all zeros if FROM != TO. */ + mctx->bkref_ents[mctx->nbkref_ents].eps_reachable_subexps_map + = (from == to ? -1 : 0); + + mctx->bkref_ents[mctx->nbkref_ents++].more = 0; + if (mctx->max_mb_elem_len < to - from) + mctx->max_mb_elem_len = to - from; + return REG_NOERROR; +} + +/* Return the first entry with the same str_idx, or REG_MISSING if none is + found. Note that MCTX->BKREF_ENTS is already sorted by MCTX->STR_IDX. */ + +static Idx +internal_function +search_cur_bkref_entry (const re_match_context_t *mctx, Idx str_idx) +{ + Idx left, right, mid, last; + last = right = mctx->nbkref_ents; + for (left = 0; left < right;) + { + mid = (left + right) / 2; + if (mctx->bkref_ents[mid].str_idx < str_idx) + left = mid + 1; + else + right = mid; + } + if (left < last && mctx->bkref_ents[left].str_idx == str_idx) + return left; + else + return REG_MISSING; +} + +/* Register the node NODE, whose type is OP_OPEN_SUBEXP, and which matches + at STR_IDX. */ + +static reg_errcode_t +internal_function +match_ctx_add_subtop (re_match_context_t *mctx, Idx node, Idx str_idx) +{ +#ifdef DEBUG + assert (mctx->sub_tops != NULL); + assert (mctx->asub_tops > 0); +#endif + if (BE (mctx->nsub_tops == mctx->asub_tops, 0)) + { + Idx new_asub_tops = mctx->asub_tops * 2; + re_sub_match_top_t **new_array = re_realloc (mctx->sub_tops, + re_sub_match_top_t *, + new_asub_tops); + if (BE (new_array == NULL, 0)) + return REG_ESPACE; + mctx->sub_tops = new_array; + mctx->asub_tops = new_asub_tops; + } + mctx->sub_tops[mctx->nsub_tops] = calloc (1, sizeof (re_sub_match_top_t)); + if (BE (mctx->sub_tops[mctx->nsub_tops] == NULL, 0)) + return REG_ESPACE; + mctx->sub_tops[mctx->nsub_tops]->node = node; + mctx->sub_tops[mctx->nsub_tops++]->str_idx = str_idx; + return REG_NOERROR; +} + +/* Register the node NODE, whose type is OP_CLOSE_SUBEXP, and which matches + at STR_IDX, whose corresponding OP_OPEN_SUBEXP is SUB_TOP. */ + +static re_sub_match_last_t * +internal_function +match_ctx_add_sublast (re_sub_match_top_t *subtop, Idx node, Idx str_idx) +{ + re_sub_match_last_t *new_entry; + if (BE (subtop->nlasts == subtop->alasts, 0)) + { + Idx new_alasts = 2 * subtop->alasts + 1; + re_sub_match_last_t **new_array = re_realloc (subtop->lasts, + re_sub_match_last_t *, + new_alasts); + if (BE (new_array == NULL, 0)) + return NULL; + subtop->lasts = new_array; + subtop->alasts = new_alasts; + } + new_entry = calloc (1, sizeof (re_sub_match_last_t)); + if (BE (new_entry != NULL, 1)) + { + subtop->lasts[subtop->nlasts] = new_entry; + new_entry->node = node; + new_entry->str_idx = str_idx; + ++subtop->nlasts; + } + return new_entry; +} + +static void +internal_function +sift_ctx_init (re_sift_context_t *sctx, re_dfastate_t **sifted_sts, + re_dfastate_t **limited_sts, Idx last_node, Idx last_str_idx) +{ + sctx->sifted_states = sifted_sts; + sctx->limited_states = limited_sts; + sctx->last_node = last_node; + sctx->last_str_idx = last_str_idx; + re_node_set_init_empty (&sctx->limits); +} diff --git a/include/grub/gnulib-wrap.h b/include/grub/gnulib-wrap.h new file mode 100644 index 000000000..0e9235c18 --- /dev/null +++ b/include/grub/gnulib-wrap.h @@ -0,0 +1,181 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_GNULIB_WRAP_H +#define GRUB_GNULIB_WRAP_H 1 + +#include +#include + +typedef grub_size_t size_t; +typedef int bool; +static const bool true = 1; +static const bool false = 0; + +#define assert(x) assert_real(__FILE__, __LINE__, x) + +static inline void +assert_real (const char *file, int line, int cond) +{ + if (!cond) + grub_fatal ("Assertion failed at %s:%d\n", file, line); +} + +static inline char * +locale_charset (void) +{ + return "UTF-8"; +} + +#define MB_CUR_MAX 6 + +static inline void * +realloc (void *ptr, grub_size_t size) +{ + return grub_realloc (ptr, size); +} + +static inline int +toupper (int c) +{ + return grub_toupper (c); +} + +static inline int +isspace (int c) +{ + return grub_isspace (c); +} + +static inline int +isdigit (int c) +{ + return grub_isdigit (c); +} + +static inline int +islower (int c) +{ + return (c >= 'a' && c <= 'z'); +} + +static inline int +isupper (int c) +{ + return (c >= 'A' && c <= 'Z'); +} + +static inline int +isxdigit (int c) +{ + return (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F') + || (c >= '0' && c <= '9'); +} + +static inline int +isprint (int c) +{ + return grub_isprint (c); +} + +static inline int +iscntrl (int c) +{ + return !grub_isprint (c); +} + +static inline int +isgraph (int c) +{ + return grub_isprint (c) && !grub_isspace (c); +} + +static inline int +isalnum (int c) +{ + return grub_isalpha (c) || grub_isdigit (c); +} + +static inline int +ispunct (int c) +{ + return grub_isprint (c) && !grub_isspace (c) && !isalnum (c); +} + +static inline int +isalpha (int c) +{ + return grub_isalpha (c); +} + +static inline int +tolower (int c) +{ + return grub_tolower (c); +} + +static inline grub_size_t +strlen (const char *s) +{ + return grub_strlen (s); +} + +static inline int +strcmp (const char *s1, const char *s2) +{ + return grub_strcmp (s1, s2); +} + +static inline void +abort (void) +{ + grub_abort (); +} + +static inline void +free (void *ptr) +{ + grub_free (ptr); +} + +static inline void * +malloc (grub_size_t size) +{ + return grub_malloc (size); +} + +static inline void * +calloc (grub_size_t size, grub_size_t nelem) +{ + return grub_zalloc (size * nelem); +} + +#define ULONG_MAX GRUB_ULONG_MAX +#define UCHAR_MAX 0xff + +/* UCS-4. */ +typedef grub_uint32_t wchar_t; + +#undef __libc_lock_init +#define __libc_lock_init(x) +#undef __libc_lock_lock +#define __libc_lock_lock(x) +#undef __libc_lock_unlock +#define __libc_lock_unlock(x) + +#endif diff --git a/include/grub/regex.h b/include/grub/regex.h new file mode 100644 index 000000000..091342d0b --- /dev/null +++ b/include/grub/regex.h @@ -0,0 +1,675 @@ +/* Definitions for data structures and routines for the regular + expression library. + Copyright (C) 1985,1989-93,1995-98,2000,2001,2002,2003,2005,2006 + Free Software Foundation, Inc. + This file is part of the GNU C Library. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef _REGEX_H +#define _REGEX_H 1 + +#include + +/* Allow the use in C++ code. */ +#ifdef __cplusplus +extern "C" { +#endif + +/* Define __USE_GNU_REGEX to declare GNU extensions that violate the + POSIX name space rules. */ +#undef __USE_GNU_REGEX +#if (defined _GNU_SOURCE \ + || (!defined _POSIX_C_SOURCE && !defined _POSIX_SOURCE \ + && !defined _XOPEN_SOURCE)) +# define __USE_GNU_REGEX 1 +#endif + +#ifdef _REGEX_LARGE_OFFSETS + +/* Use types and values that are wide enough to represent signed and + unsigned byte offsets in memory. This currently works only when + the regex code is used outside of the GNU C library; it is not yet + supported within glibc itself, and glibc users should not define + _REGEX_LARGE_OFFSETS. */ + +/* The type of the offset of a byte within a string. + For historical reasons POSIX 1003.1-2004 requires that regoff_t be + at least as wide as off_t. However, many common POSIX platforms set + regoff_t to the more-sensible ssize_t and the Open Group has + signalled its intention to change the requirement to be that + regoff_t be at least as wide as ptrdiff_t and ssize_t; see XBD ERN + 60 (2005-08-25). We don't know of any hosts where ssize_t or + ptrdiff_t is wider than ssize_t, so ssize_t is safe. */ +typedef ssize_t regoff_t; + +/* The type of nonnegative object indexes. Traditionally, GNU regex + uses 'int' for these. Code that uses __re_idx_t should work + regardless of whether the type is signed. */ +typedef size_t __re_idx_t; + +/* The type of object sizes. */ +typedef size_t __re_size_t; + +/* The type of object sizes, in places where the traditional code + uses unsigned long int. */ +typedef size_t __re_long_size_t; + +#else + +/* Use types that are binary-compatible with the traditional GNU regex + implementation, which mishandles strings longer than INT_MAX. */ + +typedef int regoff_t; +typedef int __re_idx_t; +typedef unsigned int __re_size_t; +typedef unsigned long int __re_long_size_t; + +#endif + +/* The following two types have to be signed and unsigned integer type + wide enough to hold a value of a pointer. For most ANSI compilers + ptrdiff_t and size_t should be likely OK. Still size of these two + types is 2 for Microsoft C. Ugh... */ +typedef long int s_reg_t; +typedef unsigned long int active_reg_t; + +/* The following bits are used to determine the regexp syntax we + recognize. The set/not-set meanings are chosen so that Emacs syntax + remains the value 0. The bits are given in alphabetical order, and + the definitions shifted by one from the previous bit; thus, when we + add or remove a bit, only one other definition need change. */ +typedef unsigned long int reg_syntax_t; + +#ifdef __USE_GNU_REGEX + +/* If this bit is not set, then \ inside a bracket expression is literal. + If set, then such a \ quotes the following character. */ +# define RE_BACKSLASH_ESCAPE_IN_LISTS ((unsigned long int) 1) + +/* If this bit is not set, then + and ? are operators, and \+ and \? are + literals. + If set, then \+ and \? are operators and + and ? are literals. */ +# define RE_BK_PLUS_QM (RE_BACKSLASH_ESCAPE_IN_LISTS << 1) + +/* If this bit is set, then character classes are supported. They are: + [:alpha:], [:upper:], [:lower:], [:digit:], [:alnum:], [:xdigit:], + [:space:], [:print:], [:punct:], [:graph:], and [:cntrl:]. + If not set, then character classes are not supported. */ +# define RE_CHAR_CLASSES (RE_BK_PLUS_QM << 1) + +/* If this bit is set, then ^ and $ are always anchors (outside bracket + expressions, of course). + If this bit is not set, then it depends: + ^ is an anchor if it is at the beginning of a regular + expression or after an open-group or an alternation operator; + $ is an anchor if it is at the end of a regular expression, or + before a close-group or an alternation operator. + + This bit could be (re)combined with RE_CONTEXT_INDEP_OPS, because + POSIX draft 11.2 says that * etc. in leading positions is undefined. + We already implemented a previous draft which made those constructs + invalid, though, so we haven't changed the code back. */ +# define RE_CONTEXT_INDEP_ANCHORS (RE_CHAR_CLASSES << 1) + +/* If this bit is set, then special characters are always special + regardless of where they are in the pattern. + If this bit is not set, then special characters are special only in + some contexts; otherwise they are ordinary. Specifically, + * + ? and intervals are only special when not after the beginning, + open-group, or alternation operator. */ +# define RE_CONTEXT_INDEP_OPS (RE_CONTEXT_INDEP_ANCHORS << 1) + +/* If this bit is set, then *, +, ?, and { cannot be first in an re or + immediately after an alternation or begin-group operator. */ +# define RE_CONTEXT_INVALID_OPS (RE_CONTEXT_INDEP_OPS << 1) + +/* If this bit is set, then . matches newline. + If not set, then it doesn't. */ +# define RE_DOT_NEWLINE (RE_CONTEXT_INVALID_OPS << 1) + +/* If this bit is set, then . doesn't match NUL. + If not set, then it does. */ +# define RE_DOT_NOT_NULL (RE_DOT_NEWLINE << 1) + +/* If this bit is set, nonmatching lists [^...] do not match newline. + If not set, they do. */ +# define RE_HAT_LISTS_NOT_NEWLINE (RE_DOT_NOT_NULL << 1) + +/* If this bit is set, either \{...\} or {...} defines an + interval, depending on RE_NO_BK_BRACES. + If not set, \{, \}, {, and } are literals. */ +# define RE_INTERVALS (RE_HAT_LISTS_NOT_NEWLINE << 1) + +/* If this bit is set, +, ? and | aren't recognized as operators. + If not set, they are. */ +# define RE_LIMITED_OPS (RE_INTERVALS << 1) + +/* If this bit is set, newline is an alternation operator. + If not set, newline is literal. */ +# define RE_NEWLINE_ALT (RE_LIMITED_OPS << 1) + +/* If this bit is set, then `{...}' defines an interval, and \{ and \} + are literals. + If not set, then `\{...\}' defines an interval. */ +# define RE_NO_BK_BRACES (RE_NEWLINE_ALT << 1) + +/* If this bit is set, (...) defines a group, and \( and \) are literals. + If not set, \(...\) defines a group, and ( and ) are literals. */ +# define RE_NO_BK_PARENS (RE_NO_BK_BRACES << 1) + +/* If this bit is set, then \ matches . + If not set, then \ is a back-reference. */ +# define RE_NO_BK_REFS (RE_NO_BK_PARENS << 1) + +/* If this bit is set, then | is an alternation operator, and \| is literal. + If not set, then \| is an alternation operator, and | is literal. */ +# define RE_NO_BK_VBAR (RE_NO_BK_REFS << 1) + +/* If this bit is set, then an ending range point collating higher + than the starting range point, as in [z-a], is invalid. + If not set, then when ending range point collates higher than the + starting range point, the range is ignored. */ +# define RE_NO_EMPTY_RANGES (RE_NO_BK_VBAR << 1) + +/* If this bit is set, then an unmatched ) is ordinary. + If not set, then an unmatched ) is invalid. */ +# define RE_UNMATCHED_RIGHT_PAREN_ORD (RE_NO_EMPTY_RANGES << 1) + +/* If this bit is set, succeed as soon as we match the whole pattern, + without further backtracking. */ +# define RE_NO_POSIX_BACKTRACKING (RE_UNMATCHED_RIGHT_PAREN_ORD << 1) + +/* If this bit is set, do not process the GNU regex operators. + If not set, then the GNU regex operators are recognized. */ +# define RE_NO_GNU_OPS (RE_NO_POSIX_BACKTRACKING << 1) + +/* If this bit is set, turn on internal regex debugging. + If not set, and debugging was on, turn it off. + This only works if regex.c is compiled -DDEBUG. + We define this bit always, so that all that's needed to turn on + debugging is to recompile regex.c; the calling code can always have + this bit set, and it won't affect anything in the normal case. */ +# define RE_DEBUG (RE_NO_GNU_OPS << 1) + +/* If this bit is set, a syntactically invalid interval is treated as + a string of ordinary characters. For example, the ERE 'a{1' is + treated as 'a\{1'. */ +# define RE_INVALID_INTERVAL_ORD (RE_DEBUG << 1) + +/* If this bit is set, then ignore case when matching. + If not set, then case is significant. */ +# define RE_ICASE (RE_INVALID_INTERVAL_ORD << 1) + +/* This bit is used internally like RE_CONTEXT_INDEP_ANCHORS but only + for ^, because it is difficult to scan the regex backwards to find + whether ^ should be special. */ +# define RE_CARET_ANCHORS_HERE (RE_ICASE << 1) + +/* If this bit is set, then \{ cannot be first in an bre or + immediately after an alternation or begin-group operator. */ +# define RE_CONTEXT_INVALID_DUP (RE_CARET_ANCHORS_HERE << 1) + +/* If this bit is set, then no_sub will be set to 1 during + re_compile_pattern. */ +# define RE_NO_SUB (RE_CONTEXT_INVALID_DUP << 1) + +#endif /* defined __USE_GNU_REGEX */ + +/* This global variable defines the particular regexp syntax to use (for + some interfaces). When a regexp is compiled, the syntax used is + stored in the pattern buffer, so changing this does not affect + already-compiled regexps. */ +extern reg_syntax_t re_syntax_options; + +#ifdef __USE_GNU_REGEX +/* Define combinations of the above bits for the standard possibilities. + (The [[[ comments delimit what gets put into the Texinfo file, so + don't delete them!) */ +/* [[[begin syntaxes]]] */ +# define RE_SYNTAX_EMACS 0 + +# define RE_SYNTAX_AWK \ + (RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DOT_NOT_NULL \ + | RE_NO_BK_PARENS | RE_NO_BK_REFS \ + | RE_NO_BK_VBAR | RE_NO_EMPTY_RANGES \ + | RE_DOT_NEWLINE | RE_CONTEXT_INDEP_ANCHORS \ + | RE_UNMATCHED_RIGHT_PAREN_ORD | RE_NO_GNU_OPS) + +# define RE_SYNTAX_GNU_AWK \ + ((RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DEBUG) \ + & ~(RE_DOT_NOT_NULL | RE_INTERVALS | RE_CONTEXT_INDEP_OPS \ + | RE_CONTEXT_INVALID_OPS )) + +# define RE_SYNTAX_POSIX_AWK \ + (RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS \ + | RE_INTERVALS | RE_NO_GNU_OPS) + +# define RE_SYNTAX_GREP \ + (RE_BK_PLUS_QM | RE_CHAR_CLASSES \ + | RE_HAT_LISTS_NOT_NEWLINE | RE_INTERVALS \ + | RE_NEWLINE_ALT) + +# define RE_SYNTAX_EGREP \ + (RE_CHAR_CLASSES | RE_CONTEXT_INDEP_ANCHORS \ + | RE_CONTEXT_INDEP_OPS | RE_HAT_LISTS_NOT_NEWLINE \ + | RE_NEWLINE_ALT | RE_NO_BK_PARENS \ + | RE_NO_BK_VBAR) + +# define RE_SYNTAX_POSIX_EGREP \ + (RE_SYNTAX_EGREP | RE_INTERVALS | RE_NO_BK_BRACES \ + | RE_INVALID_INTERVAL_ORD) + +/* P1003.2/D11.2, section 4.20.7.1, lines 5078ff. */ +# define RE_SYNTAX_ED RE_SYNTAX_POSIX_BASIC + +# define RE_SYNTAX_SED RE_SYNTAX_POSIX_BASIC + +/* Syntax bits common to both basic and extended POSIX regex syntax. */ +# define _RE_SYNTAX_POSIX_COMMON \ + (RE_CHAR_CLASSES | RE_DOT_NEWLINE | RE_DOT_NOT_NULL \ + | RE_INTERVALS | RE_NO_EMPTY_RANGES) + +# define RE_SYNTAX_POSIX_BASIC \ + (_RE_SYNTAX_POSIX_COMMON | RE_BK_PLUS_QM | RE_CONTEXT_INVALID_DUP) + +/* Differs from ..._POSIX_BASIC only in that RE_BK_PLUS_QM becomes + RE_LIMITED_OPS, i.e., \? \+ \| are not recognized. Actually, this + isn't minimal, since other operators, such as \`, aren't disabled. */ +# define RE_SYNTAX_POSIX_MINIMAL_BASIC \ + (_RE_SYNTAX_POSIX_COMMON | RE_LIMITED_OPS) + +# define RE_SYNTAX_POSIX_EXTENDED \ + (_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \ + | RE_CONTEXT_INDEP_OPS | RE_NO_BK_BRACES \ + | RE_NO_BK_PARENS | RE_NO_BK_VBAR \ + | RE_CONTEXT_INVALID_OPS | RE_UNMATCHED_RIGHT_PAREN_ORD) + +/* Differs from ..._POSIX_EXTENDED in that RE_CONTEXT_INDEP_OPS is + removed and RE_NO_BK_REFS is added. */ +# define RE_SYNTAX_POSIX_MINIMAL_EXTENDED \ + (_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \ + | RE_CONTEXT_INVALID_OPS | RE_NO_BK_BRACES \ + | RE_NO_BK_PARENS | RE_NO_BK_REFS \ + | RE_NO_BK_VBAR | RE_UNMATCHED_RIGHT_PAREN_ORD) +/* [[[end syntaxes]]] */ + +#endif /* defined __USE_GNU_REGEX */ + +#ifdef __USE_GNU_REGEX + +/* Maximum number of duplicates an interval can allow. POSIX-conforming + systems might define this in , but we want our + value, so remove any previous define. */ +# ifdef RE_DUP_MAX +# undef RE_DUP_MAX +# endif + +/* RE_DUP_MAX is 2**15 - 1 because an earlier implementation stored + the counter as a 2-byte signed integer. This is no longer true, so + RE_DUP_MAX could be increased to (INT_MAX / 10 - 1), or to + ((SIZE_MAX - 2) / 10 - 1) if _REGEX_LARGE_OFFSETS is defined. + However, there would be a huge performance problem if someone + actually used a pattern like a\{214748363\}, so RE_DUP_MAX retains + its historical value. */ +# define RE_DUP_MAX (0x7fff) + +#endif /* defined __USE_GNU_REGEX */ + + +/* POSIX `cflags' bits (i.e., information for `regcomp'). */ + +/* If this bit is set, then use extended regular expression syntax. + If not set, then use basic regular expression syntax. */ +#define REG_EXTENDED 1 + +/* If this bit is set, then ignore case when matching. + If not set, then case is significant. */ +#define REG_ICASE (1 << 1) + +/* If this bit is set, then anchors do not match at newline + characters in the string. + If not set, then anchors do match at newlines. */ +#define REG_NEWLINE (1 << 2) + +/* If this bit is set, then report only success or fail in regexec. + If not set, then returns differ between not matching and errors. */ +#define REG_NOSUB (1 << 3) + + +/* POSIX `eflags' bits (i.e., information for regexec). */ + +/* If this bit is set, then the beginning-of-line operator doesn't match + the beginning of the string (presumably because it's not the + beginning of a line). + If not set, then the beginning-of-line operator does match the + beginning of the string. */ +#define REG_NOTBOL 1 + +/* Like REG_NOTBOL, except for the end-of-line. */ +#define REG_NOTEOL (1 << 1) + +/* Use PMATCH[0] to delimit the start and end of the search in the + buffer. */ +#define REG_STARTEND (1 << 2) + + +/* If any error codes are removed, changed, or added, update the + `__re_error_msgid' table in regcomp.c. */ + +typedef enum +{ + _REG_ENOSYS = -1, /* This will never happen for this implementation. */ + _REG_NOERROR = 0, /* Success. */ + _REG_NOMATCH, /* Didn't find a match (for regexec). */ + + /* POSIX regcomp return error codes. (In the order listed in the + standard.) */ + _REG_BADPAT, /* Invalid pattern. */ + _REG_ECOLLATE, /* Invalid collating element. */ + _REG_ECTYPE, /* Invalid character class name. */ + _REG_EESCAPE, /* Trailing backslash. */ + _REG_ESUBREG, /* Invalid back reference. */ + _REG_EBRACK, /* Unmatched left bracket. */ + _REG_EPAREN, /* Parenthesis imbalance. */ + _REG_EBRACE, /* Unmatched \{. */ + _REG_BADBR, /* Invalid contents of \{\}. */ + _REG_ERANGE, /* Invalid range end. */ + _REG_ESPACE, /* Ran out of memory. */ + _REG_BADRPT, /* No preceding re for repetition op. */ + + /* Error codes we've added. */ + _REG_EEND, /* Premature end. */ + _REG_ESIZE, /* Compiled pattern bigger than 2^16 bytes. */ + _REG_ERPAREN /* Unmatched ) or \); not returned from regcomp. */ +} reg_errcode_t; + +#ifdef _XOPEN_SOURCE +# define REG_ENOSYS _REG_ENOSYS +#endif +#define REG_NOERROR _REG_NOERROR +#define REG_NOMATCH _REG_NOMATCH +#define REG_BADPAT _REG_BADPAT +#define REG_ECOLLATE _REG_ECOLLATE +#define REG_ECTYPE _REG_ECTYPE +#define REG_EESCAPE _REG_EESCAPE +#define REG_ESUBREG _REG_ESUBREG +#define REG_EBRACK _REG_EBRACK +#define REG_EPAREN _REG_EPAREN +#define REG_EBRACE _REG_EBRACE +#define REG_BADBR _REG_BADBR +#define REG_ERANGE _REG_ERANGE +#define REG_ESPACE _REG_ESPACE +#define REG_BADRPT _REG_BADRPT +#define REG_EEND _REG_EEND +#define REG_ESIZE _REG_ESIZE +#define REG_ERPAREN _REG_ERPAREN + +/* struct re_pattern_buffer normally uses member names like `buffer' + that POSIX does not allow. In POSIX mode these members have names + with leading `re_' (e.g., `re_buffer'). */ +#ifdef __USE_GNU_REGEX +# define _REG_RE_NAME(id) id +# define _REG_RM_NAME(id) id +#else +# define _REG_RE_NAME(id) re_##id +# define _REG_RM_NAME(id) rm_##id +#endif + +/* The user can specify the type of the re_translate member by + defining the macro RE_TRANSLATE_TYPE, which defaults to unsigned + char *. This pollutes the POSIX name space, so in POSIX mode just + use unsigned char *. */ +#ifdef __USE_GNU_REGEX +# ifndef RE_TRANSLATE_TYPE +# define RE_TRANSLATE_TYPE unsigned char * +# endif +# define REG_TRANSLATE_TYPE RE_TRANSLATE_TYPE +#else +# define REG_TRANSLATE_TYPE unsigned char * +#endif + +/* This data structure represents a compiled pattern. Before calling + the pattern compiler, the fields `buffer', `allocated', `fastmap', + `translate', and `no_sub' can be set. After the pattern has been + compiled, the `re_nsub' field is available. All other fields are + private to the regex routines. */ + +struct re_pattern_buffer +{ + /* Space that holds the compiled pattern. It is declared as + `unsigned char *' because its elements are sometimes used as + array indexes. */ + unsigned char *_REG_RE_NAME (buffer); + + /* Number of bytes to which `buffer' points. */ + __re_long_size_t _REG_RE_NAME (allocated); + + /* Number of bytes actually used in `buffer'. */ + __re_long_size_t _REG_RE_NAME (used); + + /* Syntax setting with which the pattern was compiled. */ + reg_syntax_t _REG_RE_NAME (syntax); + + /* Pointer to a fastmap, if any, otherwise zero. re_search uses the + fastmap, if there is one, to skip over impossible starting points + for matches. */ + char *_REG_RE_NAME (fastmap); + + /* Either a translate table to apply to all characters before + comparing them, or zero for no translation. The translation is + applied to a pattern when it is compiled and to a string when it + is matched. */ + REG_TRANSLATE_TYPE _REG_RE_NAME (translate); + + /* Number of subexpressions found by the compiler. */ + size_t re_nsub; + + /* Zero if this pattern cannot match the empty string, one else. + Well, in truth it's used only in `re_search_2', to see whether or + not we should use the fastmap, so we don't set this absolutely + perfectly; see `re_compile_fastmap' (the `duplicate' case). */ + unsigned int _REG_RE_NAME (can_be_null) : 1; + + /* If REGS_UNALLOCATED, allocate space in the `regs' structure + for `max (RE_NREGS, re_nsub + 1)' groups. + If REGS_REALLOCATE, reallocate space if necessary. + If REGS_FIXED, use what's there. */ +#ifdef __USE_GNU_REGEX +# define REGS_UNALLOCATED 0 +# define REGS_REALLOCATE 1 +# define REGS_FIXED 2 +#endif + unsigned int _REG_RE_NAME (regs_allocated) : 2; + + /* Set to zero when `regex_compile' compiles a pattern; set to one + by `re_compile_fastmap' if it updates the fastmap. */ + unsigned int _REG_RE_NAME (fastmap_accurate) : 1; + + /* If set, `re_match_2' does not return information about + subexpressions. */ + unsigned int _REG_RE_NAME (no_sub) : 1; + + /* If set, a beginning-of-line anchor doesn't match at the beginning + of the string. */ + unsigned int _REG_RE_NAME (not_bol) : 1; + + /* Similarly for an end-of-line anchor. */ + unsigned int _REG_RE_NAME (not_eol) : 1; + + /* If true, an anchor at a newline matches. */ + unsigned int _REG_RE_NAME (newline_anchor) : 1; + +/* [[[end pattern_buffer]]] */ +}; + +typedef struct re_pattern_buffer regex_t; + +/* This is the structure we store register match data in. See + regex.texinfo for a full description of what registers match. */ +struct re_registers +{ + __re_size_t _REG_RM_NAME (num_regs); + regoff_t *_REG_RM_NAME (start); + regoff_t *_REG_RM_NAME (end); +}; + + +/* If `regs_allocated' is REGS_UNALLOCATED in the pattern buffer, + `re_match_2' returns information about at least this many registers + the first time a `regs' structure is passed. */ +#if !defined RE_NREGS && defined __USE_GNU_REGEX +# define RE_NREGS 30 +#endif + + +/* POSIX specification for registers. Aside from the different names than + `re_registers', POSIX uses an array of structures, instead of a + structure of arrays. */ +typedef struct +{ + regoff_t rm_so; /* Byte offset from string's start to substring's start. */ + regoff_t rm_eo; /* Byte offset from string's start to substring's end. */ +} regmatch_t; + +/* Declarations for routines. */ + +/* Sets the current default syntax to SYNTAX, and return the old syntax. + You can also simply assign to the `re_syntax_options' variable. */ +extern reg_syntax_t re_set_syntax (reg_syntax_t __syntax); + +/* Compile the regular expression PATTERN, with length LENGTH + and syntax given by the global `re_syntax_options', into the buffer + BUFFER. Return NULL if successful, and an error string if not. */ +extern const char *re_compile_pattern (const char *__pattern, size_t __length, + struct re_pattern_buffer *__buffer); + + +/* Compile a fastmap for the compiled pattern in BUFFER; used to + accelerate searches. Return 0 if successful and -2 if was an + internal error. */ +extern int re_compile_fastmap (struct re_pattern_buffer *__buffer); + + +/* Search in the string STRING (with length LENGTH) for the pattern + compiled into BUFFER. Start searching at position START, for RANGE + characters. Return the starting position of the match, -1 for no + match, or -2 for an internal error. Also return register + information in REGS (if REGS and BUFFER->no_sub are nonzero). */ +extern regoff_t re_search (struct re_pattern_buffer *__buffer, + const char *__string, __re_idx_t __length, + __re_idx_t __start, regoff_t __range, + struct re_registers *__regs); + + +/* Like `re_search', but search in the concatenation of STRING1 and + STRING2. Also, stop searching at index START + STOP. */ +extern regoff_t re_search_2 (struct re_pattern_buffer *__buffer, + const char *__string1, __re_idx_t __length1, + const char *__string2, __re_idx_t __length2, + __re_idx_t __start, regoff_t __range, + struct re_registers *__regs, + __re_idx_t __stop); + + +/* Like `re_search', but return how many characters in STRING the regexp + in BUFFER matched, starting at position START. */ +extern regoff_t re_match (struct re_pattern_buffer *__buffer, + const char *__string, __re_idx_t __length, + __re_idx_t __start, struct re_registers *__regs); + + +/* Relates to `re_match' as `re_search_2' relates to `re_search'. */ +extern regoff_t re_match_2 (struct re_pattern_buffer *__buffer, + const char *__string1, __re_idx_t __length1, + const char *__string2, __re_idx_t __length2, + __re_idx_t __start, struct re_registers *__regs, + __re_idx_t __stop); + + +/* Set REGS to hold NUM_REGS registers, storing them in STARTS and + ENDS. Subsequent matches using BUFFER and REGS will use this memory + for recording register information. STARTS and ENDS must be + allocated with malloc, and must each be at least `NUM_REGS * sizeof + (regoff_t)' bytes long. + + If NUM_REGS == 0, then subsequent matches should allocate their own + register data. + + Unless this function is called, the first search or match using + PATTERN_BUFFER will allocate its own register data, without + freeing the old data. */ +extern void re_set_registers (struct re_pattern_buffer *__buffer, + struct re_registers *__regs, + __re_size_t __num_regs, + regoff_t *__starts, regoff_t *__ends); + +#if defined _REGEX_RE_COMP || defined _LIBC +# ifndef _CRAY +/* 4.2 bsd compatibility. */ +extern char *re_comp (const char *); +extern int re_exec (const char *); +# endif +#endif + +/* GCC 2.95 and later have "__restrict"; C99 compilers have + "restrict", and "configure" may have defined "restrict". + Other compilers use __restrict, __restrict__, and _Restrict, and + 'configure' might #define 'restrict' to those words, so pick a + different name. */ +#ifndef _Restrict_ +# if 199901L <= __STDC_VERSION__ +# define _Restrict_ restrict +# elif 2 < __GNUC__ || (2 == __GNUC__ && 95 <= __GNUC_MINOR__) +# define _Restrict_ __restrict +# else +# define _Restrict_ +# endif +#endif +/* gcc 3.1 and up support the [restrict] syntax. Don't trust + sys/cdefs.h's definition of __restrict_arr, though, as it + mishandles gcc -ansi -pedantic. */ +#ifndef _Restrict_arr_ +# if ((199901L <= __STDC_VERSION__ \ + || ((3 < __GNUC__ || (3 == __GNUC__ && 1 <= __GNUC_MINOR__)) \ + && !__STRICT_ANSI__)) \ + && !defined __GNUG__) +# define _Restrict_arr_ _Restrict_ +# else +# define _Restrict_arr_ +# endif +#endif + +/* POSIX compatibility. */ +extern int regcomp (regex_t *_Restrict_ __preg, + const char *_Restrict_ __pattern, + int __cflags); + +extern int regexec (const regex_t *_Restrict_ __preg, + const char *_Restrict_ __string, size_t __nmatch, + regmatch_t __pmatch[_Restrict_arr_], + int __eflags); + +extern size_t regerror (int __errcode, const regex_t *_Restrict_ __preg, + char *_Restrict_ __errbuf, size_t __errbuf_size); + +extern void regfree (regex_t *__preg); + + +#ifdef __cplusplus +} +#endif /* C++ */ + +#endif /* regex.h */ From 6392d412a0cf04ea8db9f3d91dfc3b97d22ec853 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 27 Dec 2009 16:53:39 +0100 Subject: [PATCH 169/738] Changelog --- ChangeLog.io | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 ChangeLog.io diff --git a/ChangeLog.io b/ChangeLog.io new file mode 100644 index 000000000..59af361c8 --- /dev/null +++ b/ChangeLog.io @@ -0,0 +1,7 @@ +2009-12-27 Vladimir Serbinenko + + * commands/iorw.c: New file. + * conf/i386.rmk (pkglib_MODULES): Add iorw.mod. + (iorw_mod_SOURCES): New variable. + (iorw_mod_CFLAGS): Likewise. + (iorw_mod_LDFLAGS): Likewise. From 281d82347e4c6fdfe31e5c3a18196f373651af4d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 27 Dec 2009 17:02:03 +0100 Subject: [PATCH 170/738] ChangeLog --- ChangeLog.setpci | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 ChangeLog.setpci diff --git a/ChangeLog.setpci b/ChangeLog.setpci new file mode 100644 index 000000000..e488379ce --- /dev/null +++ b/ChangeLog.setpci @@ -0,0 +1,9 @@ +2009-12-27 Vladimir Serbinenko + + setpci support. + + * commands/setpci.c: New file. + * conf/i386.rmk (pkglib_MODULES): Add setpci.mod. + (setpci_mod_SOURCES): New variable. + (setpci_mod_CFLAGS): Likewise. + (setpci_mod_LDFLAGS): Likewise. From a2b4c09b1c48c5e3b8958291a06c2ee651b5a57d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 27 Dec 2009 22:24:46 +0100 Subject: [PATCH 171/738] Don't destroy NULL view --- gfxmenu/view.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gfxmenu/view.c b/gfxmenu/view.c index 7d9bb1cd0..e2348b6ef 100644 --- a/gfxmenu/view.c +++ b/gfxmenu/view.c @@ -136,6 +136,8 @@ grub_gfxmenu_view_new (const char *theme_path, grub_gfxmenu_model_t model) void grub_gfxmenu_view_destroy (grub_gfxmenu_view_t view) { + if (!view) + return; grub_video_bitmap_destroy (view->desktop_image); if (view->terminal_box) view->terminal_box->destroy (view->terminal_box); From 45a8e94c9ceb0a29f9c4b8e0cb1356af9fd5aa4d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 28 Dec 2009 01:06:48 +0100 Subject: [PATCH 172/738] Ensure embeded config finishes with \0 --- util/grub-mkrawimage.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/util/grub-mkrawimage.c b/util/grub-mkrawimage.c index 8186c8601..c5af6ad82 100644 --- a/util/grub-mkrawimage.c +++ b/util/grub-mkrawimage.c @@ -106,7 +106,7 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], { char *kernel_img, *core_img; size_t kernel_size, total_module_size, core_size; - size_t memdisk_size = 0, font_size = 0, config_size = 0; + size_t memdisk_size = 0, font_size = 0, config_size = 0, config_size_pure = 0; char *kernel_path; size_t offset; struct grub_util_path_list *path_list, *p, *next; @@ -134,7 +134,8 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], if (config_path) { - config_size = ALIGN_UP(grub_util_get_image_size (config_path) + 1, 4); + config_size_pure = grub_util_get_image_size (config_path) + 1; + config_size = ALIGN_UP(config_size_pure, 4); grub_util_info ("the size of config file is 0x%x", config_size); total_module_size += config_size + sizeof (struct grub_module_header); } @@ -218,8 +219,8 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], offset += sizeof (*header); grub_util_load_image (config_path, kernel_img + offset); + *(kernel_img + offset + config_size_pure - 1) = 0; offset += config_size; - *(kernel_img + offset - 1) = 0; } grub_util_info ("kernel_img=%p, kernel_size=0x%x", kernel_img, kernel_size); From 94c201f71436ecfc131ca2cbac9a4497ffb6822c Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 28 Dec 2009 01:07:18 +0100 Subject: [PATCH 173/738] Add forgotten config_opt parameter --- util/grub-install.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/grub-install.in b/util/grub-install.in index c59065072..ad01ff6fc 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -347,7 +347,7 @@ if [ "${target_cpu}-${platform}" = "i386-pc" ] || [ "${target_cpu}-${platform}" $grub_setup ${setup_verbose} ${setup_force} --directory=${grubdir} --device-map=${device_map} \ ${install_device} || exit 1 elif [ "${target_cpu}-${platform}" = "mips-yeeloong" ] ; then - $grub_mkimage -f ${font} -d ${pkglibdir} -O elf --output=/boot/grub.elf --prefix=${prefix_drive}${relative_grubdir} $modules || exit 1 + $grub_mkimage ${config_opt} -f ${font} -d ${pkglibdir} -O elf --output=/boot/grub.elf --prefix=${prefix_drive}${relative_grubdir} $modules || exit 1 else $grub_mkimage ${config_opt} -d ${pkglibdir} --output=/boot/multiboot.img --prefix=${prefix_drive}${relative_grubdir} $modules || exit 1 fi From aa2209101c1f140c562a83449e9c443c2e6c448f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 28 Dec 2009 22:23:28 +0100 Subject: [PATCH 174/738] Fix i386-qemu compilation --- conf/i386-coreboot.rmk | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/conf/i386-coreboot.rmk b/conf/i386-coreboot.rmk index 1efea8afb..6f078a256 100644 --- a/conf/i386-coreboot.rmk +++ b/conf/i386-coreboot.rmk @@ -80,7 +80,8 @@ kernel_img_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \ partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \ machine/boot.h machine/console.h machine/init.h \ - machine/memory.h machine/loader.h list.h handler.h command.h i18n.h + machine/memory.h machine/loader.h list.h handler.h command.h i18n.h \ + env_private.h kernel_img_CFLAGS = $(COMMON_CFLAGS) -DGRUB_BOOT_MACHINE_LINK_ADDR=$(GRUB_BOOT_MACHINE_LINK_ADDR) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR) kernel_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_KERNEL_MACHINE_LINK_ADDR) From dccad19408df39cdde9a4c9422bc25dfacfa303c Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 28 Dec 2009 22:37:36 +0100 Subject: [PATCH 175/738] Fix compilation on x86_64-efi --- commands/lspci.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/commands/lspci.c b/commands/lspci.c index c515da762..ab756616a 100644 --- a/commands/lspci.c +++ b/commands/lspci.c @@ -171,7 +171,7 @@ grub_lspci_iter (grub_pci_device_t dev, grub_pci_id_t pciid) { case GRUB_PCI_ADDR_SPACE_IO: grub_printf ("\tIO space %d at 0x%llx\n", - ((reg - GRUB_PCI_REG_ADDRESSES) + (unsigned) ((reg - GRUB_PCI_REG_ADDRESSES) / sizeof (grub_uint32_t)) - 1, (unsigned long long) (space & GRUB_PCI_ADDR_IO_MASK)); @@ -184,7 +184,7 @@ grub_lspci_iter (grub_pci_device_t dev, grub_pci_id_t pciid) space |= ((grub_uint64_t) grub_pci_read (addr)) << 32; reg += sizeof (grub_uint32_t); grub_printf ("\t64-bit memory space %d at 0x%016llx [%s]\n", - ((reg - GRUB_PCI_REG_ADDRESSES) + (unsigned) ((reg - GRUB_PCI_REG_ADDRESSES) / sizeof (grub_uint32_t)) - 2, (unsigned long long) (space & GRUB_PCI_ADDR_MEM_MASK), @@ -194,7 +194,7 @@ grub_lspci_iter (grub_pci_device_t dev, grub_pci_id_t pciid) } else grub_printf ("\t32-bit memory space %d at 0x%016llx [%s]\n", - ((reg - GRUB_PCI_REG_ADDRESSES) + (unsigned) ((reg - GRUB_PCI_REG_ADDRESSES) / sizeof (grub_uint32_t)) - 1, (unsigned long long) (space & GRUB_PCI_ADDR_MEM_MASK), From 8b442f3f4c57caa5244e52f609fc3f6484ff274b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 29 Dec 2009 10:04:06 +0100 Subject: [PATCH 176/738] asprintf and snprintf support --- commands/ls.c | 14 ++++--- commands/memrw.c | 2 +- commands/parttool.c | 3 +- commands/search.c | 15 ++------ commands/xnu_uuid.c | 24 ++++++------ disk/ata.c | 21 +++++++---- disk/efi/efidisk.c | 18 +++------ disk/i386/pc/biosdisk.c | 3 +- disk/raid.c | 4 +- disk/scsi.c | 7 +++- disk/usbms.c | 10 +++-- efiemu/main.c | 3 +- fs/ext2.c | 15 +++++--- fs/fat.c | 6 +-- fs/hfs.c | 7 ++-- fs/hfsplus.c | 7 ++-- fs/i386/pc/pxe.c | 24 +++++------- fs/iso9660.c | 27 +++++++++----- fs/jfs.c | 21 +++++------ fs/ntfs.c | 3 +- fs/reiserfs.c | 15 +++++--- fs/ufs.c | 9 ++--- fs/xfs.c | 15 +++++--- gettext/gettext.c | 9 ++++- hook/datehook.c | 2 +- include/grub/misc.h | 9 ++++- kern/device.c | 14 +++++-- kern/dl.c | 4 +- kern/efi/init.c | 5 +-- kern/env.c | 9 +---- kern/err.c | 2 +- kern/i386/pc/init.c | 18 ++++++--- kern/ieee1275/init.c | 11 +++--- kern/ieee1275/openfw.c | 36 ++++++++---------- kern/misc.c | 71 ++++++++++++++++++++++++++++++++---- kern/sparc64/ieee1275/init.c | 5 +-- lib/hexdump.c | 7 ++-- loader/i386/bsd.c | 12 ++++-- loader/i386/linux.c | 23 +++++------- loader/i386/pc/xnu.c | 4 +- loader/i386/xnu.c | 10 +++-- loader/xnu.c | 3 +- normal/autofs.c | 3 +- normal/completion.c | 28 +++++++------- normal/dyncmd.c | 3 +- normal/handler.c | 3 +- normal/main.c | 29 ++++++++------- normal/menu.c | 2 +- normal/menu_text.c | 21 ++++++----- partmap/acorn.c | 9 +---- partmap/amiga.c | 9 +---- partmap/apple.c | 9 +---- partmap/gpt.c | 9 +---- partmap/msdos.c | 14 ++----- partmap/sun.c | 8 +--- script/execute.c | 6 +-- term/gfxterm.c | 6 +-- term/ieee1275/ofconsole.c | 17 +++++---- term/tparm.c | 4 +- util/grub-fstest.c | 34 +++++++++++++---- 60 files changed, 396 insertions(+), 345 deletions(-) diff --git a/commands/ls.c b/commands/ls.c index 4b1500398..3b5fe450d 100644 --- a/commands/ls.c +++ b/commands/ls.c @@ -86,7 +86,7 @@ grub_ls_list_files (char *dirname, int longlist, int all, int human) int print_files_long (const char *filename, const struct grub_dirhook_info *info) { - char pathname[grub_strlen (dirname) + grub_strlen (filename) + 1]; + char *pathname; if ((! all) && (filename[0] == '.')) return 0; @@ -96,9 +96,12 @@ grub_ls_list_files (char *dirname, int longlist, int all, int human) grub_file_t file; if (dirname[grub_strlen (dirname) - 1] == '/') - grub_sprintf (pathname, "%s%s", dirname, filename); + pathname = grub_asprintf ("%s%s", dirname, filename); else - grub_sprintf (pathname, "%s/%s", dirname, filename); + pathname = grub_asprintf ("%s/%s", dirname, filename); + + if (!pathname) + return 1; /* XXX: For ext2fs symlinks are detected as files while they should be reported as directories. */ @@ -130,8 +133,9 @@ grub_ls_list_files (char *dirname, int longlist, int all, int human) grub_uint32_t whole, fraction; whole = grub_divmod64 (fsize, 100, &fraction); - grub_sprintf (buf, "%u.%02u%c", whole, fraction, - grub_human_sizes[units]); + grub_snprintf (buf, sizeof (buf), + "%u.%02u%c", whole, fraction, + grub_human_sizes[units]); grub_printf ("%-12s", buf); } else diff --git a/commands/memrw.c b/commands/memrw.c index 8e9c3db11..2a34ce8f6 100644 --- a/commands/memrw.c +++ b/commands/memrw.c @@ -61,7 +61,7 @@ grub_cmd_read (grub_extcmd_t cmd, int argc, char **argv) if (cmd->state[0].set) { - grub_sprintf (buf, "%x", value); + grub_snprintf (buf, sizeof (buf), "%x", value); grub_env_set (cmd->state[0].arg, buf); } else diff --git a/commands/parttool.c b/commands/parttool.c index 62fe5ad2b..f2eb58927 100644 --- a/commands/parttool.c +++ b/commands/parttool.c @@ -182,12 +182,11 @@ grub_cmd_parttool (grub_command_t cmd __attribute__ ((unused)), { char *filename; - filename = grub_malloc (grub_strlen (prefix) + sizeof ("/parttool.lst")); + filename = grub_asprintf ("%s/parttool.lst", prefix); if (filename) { grub_file_t file; - grub_sprintf (filename, "%s/parttool.lst", prefix); file = grub_file_open (filename); if (file) { diff --git a/commands/search.c b/commands/search.c index 01e83739b..78d73ba6a 100644 --- a/commands/search.c +++ b/commands/search.c @@ -33,7 +33,6 @@ void FUNC_NAME (const char *key, const char *var, int no_floppy) { int count = 0; - char *buf = NULL; grub_fs_autoload_hook_t saved_autoload; auto int iterate_device (const char *name); @@ -48,24 +47,20 @@ FUNC_NAME (const char *key, const char *var, int no_floppy) #ifdef DO_SEARCH_FILE { - grub_size_t len; - char *p; + char *buf; grub_file_t file; - len = grub_strlen (name) + 2 + grub_strlen (key) + 1; - p = grub_realloc (buf, len); - if (! p) + buf = grub_asprintf ("(%s)%s", name, key); + if (! buf) return 1; - buf = p; - grub_sprintf (buf, "(%s)%s", name, key); - file = grub_file_open (buf); if (file) { found = 1; grub_file_close (file); } + grub_free (buf); } #else { @@ -135,8 +130,6 @@ FUNC_NAME (const char *key, const char *var, int no_floppy) else grub_device_iterate (iterate_device); - grub_free (buf); - if (grub_errno == GRUB_ERR_NONE && count == 0) grub_error (GRUB_ERR_FILE_NOT_FOUND, "no such device: %s", key); } diff --git a/commands/xnu_uuid.c b/commands/xnu_uuid.c index 31e69ad13..735d999a2 100644 --- a/commands/xnu_uuid.c +++ b/commands/xnu_uuid.c @@ -349,18 +349,18 @@ grub_cmd_xnu_uuid (grub_command_t cmd __attribute__ ((unused)), grub_memcpy (hashme.prefix, hash_prefix, sizeof (hashme.prefix)); md5 ((char *) &hashme, sizeof (hashme), (char *) xnu_uuid); - grub_sprintf (uuid_string, - "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", - (unsigned int) xnu_uuid[0], (unsigned int) xnu_uuid[1], - (unsigned int) xnu_uuid[2], (unsigned int) xnu_uuid[3], - (unsigned int) xnu_uuid[4], (unsigned int) xnu_uuid[5], - (unsigned int) ((xnu_uuid[6] & 0xf) | 0x30), - (unsigned int) xnu_uuid[7], - (unsigned int) ((xnu_uuid[8] & 0x3f) | 0x80), - (unsigned int) xnu_uuid[9], - (unsigned int) xnu_uuid[10], (unsigned int) xnu_uuid[11], - (unsigned int) xnu_uuid[12], (unsigned int) xnu_uuid[13], - (unsigned int) xnu_uuid[14], (unsigned int) xnu_uuid[15]); + grub_snprintf (uuid_string, sizeof (uuid_string), + "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", + (unsigned int) xnu_uuid[0], (unsigned int) xnu_uuid[1], + (unsigned int) xnu_uuid[2], (unsigned int) xnu_uuid[3], + (unsigned int) xnu_uuid[4], (unsigned int) xnu_uuid[5], + (unsigned int) ((xnu_uuid[6] & 0xf) | 0x30), + (unsigned int) xnu_uuid[7], + (unsigned int) ((xnu_uuid[8] & 0x3f) | 0x80), + (unsigned int) xnu_uuid[9], + (unsigned int) xnu_uuid[10], (unsigned int) xnu_uuid[11], + (unsigned int) xnu_uuid[12], (unsigned int) xnu_uuid[13], + (unsigned int) xnu_uuid[14], (unsigned int) xnu_uuid[15]); for (ptr = uuid_string; *ptr; ptr++) *ptr = grub_toupper (*ptr); if (argc == 1) diff --git a/disk/ata.c b/disk/ata.c index 864ae9488..79d436222 100644 --- a/disk/ata.c +++ b/disk/ata.c @@ -648,12 +648,14 @@ grub_ata_iterate (int (*hook) (const char *name)) for (dev = grub_ata_devices; dev; dev = dev->next) { - char devname[5]; - grub_sprintf (devname, "ata%d", dev->port * 2 + dev->device); + char devname[10]; if (dev->atapi) continue; + grub_snprintf (devname, sizeof (devname), + "ata%d", dev->port * 2 + dev->device); + if (hook (devname)) return 1; } @@ -668,8 +670,9 @@ grub_ata_open (const char *name, grub_disk_t disk) for (dev = grub_ata_devices; dev; dev = dev->next) { - char devname[5]; - grub_sprintf (devname, "ata%d", dev->port * 2 + dev->device); + char devname[10]; + grub_snprintf (devname, sizeof (devname), + "ata%d", dev->port * 2 + dev->device); if (grub_strcmp (name, devname) == 0) break; } @@ -735,8 +738,9 @@ grub_atapi_iterate (int (*hook) (const char *name, int luns)) for (dev = grub_ata_devices; dev; dev = dev->next) { - char devname[7]; - grub_sprintf (devname, "ata%d", dev->port * 2 + dev->device); + char devname[10]; + grub_snprintf (devname, sizeof (devname), + "ata%d", dev->port * 2 + dev->device); if (! dev->atapi) continue; @@ -808,8 +812,9 @@ grub_atapi_open (const char *name, struct grub_scsi *scsi) for (dev = grub_ata_devices; dev; dev = dev->next) { - char devname[7]; - grub_sprintf (devname, "ata%d", dev->port * 2 + dev->device); + char devname[10]; + grub_snprintf (devname, sizeof (devname), + "ata%d", dev->port * 2 + dev->device); if (!grub_strcmp (devname, name)) { diff --git a/disk/efi/efidisk.c b/disk/efi/efidisk.c index de848594a..0b5731c0f 100644 --- a/disk/efi/efidisk.c +++ b/disk/efi/efidisk.c @@ -440,7 +440,7 @@ grub_efidisk_iterate (int (*hook) (const char *name)) for (d = fd_devices, count = 0; d; d = d->next, count++) { - grub_sprintf (buf, "fd%d", count); + grub_snprintf (buf, sizeof (buf), "fd%d", count); grub_dprintf ("efidisk", "iterating %s\n", buf); if (hook (buf)) return 1; @@ -448,7 +448,7 @@ grub_efidisk_iterate (int (*hook) (const char *name)) for (d = hd_devices, count = 0; d; d = d->next, count++) { - grub_sprintf (buf, "hd%d", count); + grub_snprintf (buf, sizeof (buf), "hd%d", count); grub_dprintf ("efidisk", "iterating %s\n", buf); if (hook (buf)) return 1; @@ -456,7 +456,7 @@ grub_efidisk_iterate (int (*hook) (const char *name)) for (d = cd_devices, count = 0; d; d = d->next, count++) { - grub_sprintf (buf, "cd%d", count); + grub_snprintf (buf, sizeof (buf), "cd%d", count); grub_dprintf ("efidisk", "iterating %s\n", buf); if (hook (buf)) return 1; @@ -805,18 +805,10 @@ grub_efidisk_get_device_name (grub_efi_handle_t *handle) return 0; } - device_name = grub_malloc (grub_strlen (parent->name) + 1 - + grub_strlen (partition_name) + 1); - if (! device_name) - { - grub_free (partition_name); - grub_disk_close (parent); - return 0; - } - - grub_sprintf (device_name, "%s,%s", parent->name, partition_name); + device_name = grub_asprintf ("%s,%s", parent->name, partition_name); grub_free (partition_name); grub_disk_close (parent); + return device_name; } else diff --git a/disk/i386/pc/biosdisk.c b/disk/i386/pc/biosdisk.c index af184b1ba..cc3da48d0 100644 --- a/disk/i386/pc/biosdisk.c +++ b/disk/i386/pc/biosdisk.c @@ -56,7 +56,8 @@ grub_biosdisk_call_hook (int (*hook) (const char *name), int drive) { char name[10]; - grub_sprintf (name, (drive & 0x80) ? "hd%d" : "fd%d", drive & (~0x80)); + grub_snprintf (name, sizeof (name), + (drive & 0x80) ? "hd%d" : "fd%d", drive & (~0x80)); return hook (name); } diff --git a/disk/raid.c b/disk/raid.c index c48a41d8d..5d4456e93 100644 --- a/disk/raid.c +++ b/disk/raid.c @@ -556,7 +556,7 @@ insert_array (grub_disk_t disk, struct grub_raid_array *new_array, } } - array->name = grub_malloc (13); + array->name = grub_asprintf ("md%d", array->number); if (! array->name) { grub_free (array->uuid); @@ -565,8 +565,6 @@ insert_array (grub_disk_t disk, struct grub_raid_array *new_array, return grub_errno; } - grub_sprintf (array->name, "md%d", array->number); - grub_dprintf ("raid", "Found array %s (%s)\n", array->name, scanner_name); diff --git a/disk/scsi.c b/disk/scsi.c index 21b888559..6717bc351 100644 --- a/disk/scsi.c +++ b/disk/scsi.c @@ -197,7 +197,6 @@ grub_scsi_iterate (int (*hook) (const char *name)) int scsi_iterate (const char *name, int luns) { - char sname[40]; int i; /* In case of a single LUN, just return `usbX'. */ @@ -208,9 +207,13 @@ grub_scsi_iterate (int (*hook) (const char *name)) distinguish it. */ for (i = 0; i < luns; i++) { - grub_sprintf (sname, "%s%c", name, 'a' + i); + char *sname; + sname = grub_asprintf ("%s%c", name, 'a' + i); + if (!sname) + return 1; if (hook (sname)) return 1; + grub_free (sname); } return 0; } diff --git a/disk/usbms.c b/disk/usbms.c index 51e886520..708168e81 100644 --- a/disk/usbms.c +++ b/disk/usbms.c @@ -200,11 +200,15 @@ grub_usbms_iterate (int (*hook) (const char *name, int luns)) for (p = grub_usbms_dev_list; p; p = p->next) { - char devname[20]; - grub_sprintf (devname, "usb%d", cnt); + char *devname; + devname = grub_asprintf ("usb%d", cnt); if (hook (devname, p->luns)) - return 1; + { + grub_free (devname); + return 1; + } + grub_free (devname); cnt++; } diff --git a/efiemu/main.c b/efiemu/main.c index a3cfdb5b5..70a12080f 100644 --- a/efiemu/main.c +++ b/efiemu/main.c @@ -255,12 +255,11 @@ grub_efiemu_autocore (void) suffix = grub_efiemu_get_default_core_name (); - filename = grub_malloc (grub_strlen (prefix) + grub_strlen (suffix) + 2); + filename = grub_asprintf ("%s/%s", prefix, suffix); if (! filename) return grub_error (GRUB_ERR_OUT_OF_MEMORY, "couldn't allocate temporary space"); - grub_sprintf (filename, "%s/%s", prefix, suffix); err = grub_efiemu_load_file (filename); grub_free (filename); diff --git a/fs/ext2.c b/fs/ext2.c index e7a20a43b..d00b79b22 100644 --- a/fs/ext2.c +++ b/fs/ext2.c @@ -875,12 +875,15 @@ grub_ext2_uuid (grub_device_t device, char **uuid) data = grub_ext2_mount (disk); if (data) { - *uuid = grub_malloc (40 + sizeof ('\0')); - grub_sprintf (*uuid, "%04x%04x-%04x-%04x-%04x-%04x%04x%04x", - grub_be_to_cpu16 (data->sblock.uuid[0]), grub_be_to_cpu16 (data->sblock.uuid[1]), - grub_be_to_cpu16 (data->sblock.uuid[2]), grub_be_to_cpu16 (data->sblock.uuid[3]), - grub_be_to_cpu16 (data->sblock.uuid[4]), grub_be_to_cpu16 (data->sblock.uuid[5]), - grub_be_to_cpu16 (data->sblock.uuid[6]), grub_be_to_cpu16 (data->sblock.uuid[7])); + *uuid = grub_asprintf ("%04x%04x-%04x-%04x-%04x-%04x%04x%04x", + grub_be_to_cpu16 (data->sblock.uuid[0]), + grub_be_to_cpu16 (data->sblock.uuid[1]), + grub_be_to_cpu16 (data->sblock.uuid[2]), + grub_be_to_cpu16 (data->sblock.uuid[3]), + grub_be_to_cpu16 (data->sblock.uuid[4]), + grub_be_to_cpu16 (data->sblock.uuid[5]), + grub_be_to_cpu16 (data->sblock.uuid[6]), + grub_be_to_cpu16 (data->sblock.uuid[7])); } else *uuid = NULL; diff --git a/fs/fat.c b/fs/fat.c index 8a0fc0292..a0a40cfab 100644 --- a/fs/fat.c +++ b/fs/fat.c @@ -833,9 +833,9 @@ grub_fat_uuid (grub_device_t device, char **uuid) data = grub_fat_mount (disk); if (data) { - *uuid = grub_malloc (sizeof ("xxxx-xxxx")); - grub_sprintf (*uuid, "%04x-%04x", (grub_uint16_t) (data->uuid >> 16), - (grub_uint16_t) data->uuid); + *uuid = grub_asprintf ("%04x-%04x", + (grub_uint16_t) (data->uuid >> 16), + (grub_uint16_t) data->uuid); } else *uuid = NULL; diff --git a/fs/hfs.c b/fs/hfs.c index 4dd1e3131..676d7a680 100644 --- a/fs/hfs.c +++ b/fs/hfs.c @@ -1082,10 +1082,9 @@ grub_hfs_uuid (grub_device_t device, char **uuid) data = grub_hfs_mount (device->disk); if (data && data->sblock.num_serial != 0) { - *uuid = grub_malloc (16 + sizeof ('\0')); - grub_sprintf (*uuid, "%016llx", - (unsigned long long) - grub_be_to_cpu64 (data->sblock.num_serial)); + *uuid = grub_asprintf ("%016llx", + (unsigned long long) + grub_be_to_cpu64 (data->sblock.num_serial)); } else *uuid = NULL; diff --git a/fs/hfsplus.c b/fs/hfsplus.c index 9310b6502..6556bedaa 100644 --- a/fs/hfsplus.c +++ b/fs/hfsplus.c @@ -995,10 +995,9 @@ grub_hfsplus_uuid (grub_device_t device, char **uuid) data = grub_hfsplus_mount (disk); if (data) { - *uuid = grub_malloc (16 + sizeof ('\0')); - grub_sprintf (*uuid, "%016llx", - (unsigned long long) - grub_be_to_cpu64 (data->volheader.num_serial)); + *uuid = grub_asprintf ("%016llx", + (unsigned long long) + grub_be_to_cpu64 (data->volheader.num_serial)); } else *uuid = NULL; diff --git a/fs/i386/pc/pxe.c b/fs/i386/pc/pxe.c index 03385b3e3..60a49fc53 100644 --- a/fs/i386/pc/pxe.c +++ b/fs/i386/pc/pxe.c @@ -356,7 +356,8 @@ set_mac_env (grub_uint8_t *mac_addr, grub_size_t mac_len) for (i = 0; i < mac_len; i++) { - grub_sprintf (ptr, "%02x:", mac_addr[i] & 0xff); + grub_snprintf (ptr, sizeof (buf) - (ptr - buf), + "%02x:", mac_addr[i] & 0xff); ptr += (sizeof ("XX:") - 1); } if (mac_len) @@ -483,8 +484,8 @@ set_ip_env (char *varname, grub_uint32_t ip) { char buf[sizeof ("XXX.XXX.XXX.XXX")]; - grub_sprintf (buf, "%d.%d.%d.%d", (ip & 0xff), - (ip >> 8) & 0xff, (ip >> 16) & 0xff, (ip >> 24) & 0xff); + grub_snprintf (buf, sizeof (buf), "%d.%d.%d.%d", (ip & 0xff), + (ip >> 8) & 0xff, (ip >> 16) & 0xff, (ip >> 24) & 0xff); grub_env_set (varname, buf); } @@ -500,15 +501,13 @@ write_ip_env (grub_uint32_t *ip, const char *val) return 0; /* Normalize the IP. */ - buf = grub_malloc (sizeof ("XXX.XXX.XXX.XXX")); + buf = grub_asprintf ("%d.%d.%d.%d", (newip & 0xff), (newip >> 8) & 0xff, + (newip >> 16) & 0xff, (newip >> 24) & 0xff); if (!buf) return 0; *ip = newip; - grub_sprintf (buf, "%d.%d.%d.%d", (newip & 0xff), (newip >> 8) & 0xff, - (newip >> 16) & 0xff, (newip >> 24) & 0xff); - return buf; } @@ -544,11 +543,10 @@ grub_env_write_pxe_blocksize (struct grub_env_var *var __attribute__ ((unused)), else if (size > GRUB_PXE_MAX_BLKSIZE) size = GRUB_PXE_MAX_BLKSIZE; - buf = grub_malloc (sizeof ("XXXXXX XXXXXX")); + buf = grub_asprintf ("%d", size); if (!buf) return 0; - grub_sprintf (buf, "%d", size); grub_pxe_blksize = size; return buf; @@ -562,12 +560,10 @@ GRUB_MOD_INIT(pxe) { char *buf; - buf = grub_malloc (sizeof ("XXXXXX XXXXXX")); + buf = grub_asprintf ("%d", grub_pxe_blksize); if (buf) - { - grub_sprintf (buf, "%d", grub_pxe_blksize); - grub_env_set ("net_pxe_blksize", buf); - } + grub_env_set ("net_pxe_blksize", buf); + grub_free (buf); set_ip_env ("pxe_default_server", grub_pxe_default_server_ip); set_ip_env ("pxe_default_gateway", grub_pxe_default_gateway_ip); diff --git a/fs/iso9660.c b/fs/iso9660.c index 2fb0ffb63..576badf63 100644 --- a/fs/iso9660.c +++ b/fs/iso9660.c @@ -837,16 +837,23 @@ grub_iso9660_uuid (grub_device_t device, char **uuid) } else { - *uuid = grub_malloc (sizeof ("YYYY-MM-DD-HH-mm-ss-hh")); - grub_sprintf (*uuid, "%c%c%c%c-%c%c-%c%c-%c%c-%c%c-%c%c-%c%c", - data->voldesc.modified.year[0], data->voldesc.modified.year[1], - data->voldesc.modified.year[2], data->voldesc.modified.year[3], - data->voldesc.modified.month[0], data->voldesc.modified.month[1], - data->voldesc.modified.day[0], data->voldesc.modified.day[1], - data->voldesc.modified.hour[0], data->voldesc.modified.hour[1], - data->voldesc.modified.minute[0], data->voldesc.modified.minute[1], - data->voldesc.modified.second[0], data->voldesc.modified.second[1], - data->voldesc.modified.hundredth[0], data->voldesc.modified.hundredth[1]); + *uuid = grub_asprintf ("%c%c%c%c-%c%c-%c%c-%c%c-%c%c-%c%c-%c%c", + data->voldesc.modified.year[0], + data->voldesc.modified.year[1], + data->voldesc.modified.year[2], + data->voldesc.modified.year[3], + data->voldesc.modified.month[0], + data->voldesc.modified.month[1], + data->voldesc.modified.day[0], + data->voldesc.modified.day[1], + data->voldesc.modified.hour[0], + data->voldesc.modified.hour[1], + data->voldesc.modified.minute[0], + data->voldesc.modified.minute[1], + data->voldesc.modified.second[0], + data->voldesc.modified.second[1], + data->voldesc.modified.hundredth[0], + data->voldesc.modified.hundredth[1]); } } else diff --git a/fs/jfs.c b/fs/jfs.c index dc5eaed67..1bc3c7758 100644 --- a/fs/jfs.c +++ b/fs/jfs.c @@ -842,17 +842,16 @@ grub_jfs_uuid (grub_device_t device, char **uuid) data = grub_jfs_mount (disk); if (data) { - *uuid = grub_malloc (40 + sizeof ('\0')); - - grub_sprintf (*uuid, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", - data->sblock.uuid[0], data->sblock.uuid[1], - data->sblock.uuid[2], data->sblock.uuid[3], - data->sblock.uuid[4], data->sblock.uuid[5], - data->sblock.uuid[6], data->sblock.uuid[7], - data->sblock.uuid[8], data->sblock.uuid[9], - data->sblock.uuid[10], data->sblock.uuid[11], - data->sblock.uuid[12], data->sblock.uuid[13], - data->sblock.uuid[14], data->sblock.uuid[15]); + *uuid = grub_asprintf ("%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-" + "%02x%02x%02x%02x%02x%02x", + data->sblock.uuid[0], data->sblock.uuid[1], + data->sblock.uuid[2], data->sblock.uuid[3], + data->sblock.uuid[4], data->sblock.uuid[5], + data->sblock.uuid[6], data->sblock.uuid[7], + data->sblock.uuid[8], data->sblock.uuid[9], + data->sblock.uuid[10], data->sblock.uuid[11], + data->sblock.uuid[12], data->sblock.uuid[13], + data->sblock.uuid[14], data->sblock.uuid[15]); } else *uuid = NULL; diff --git a/fs/ntfs.c b/fs/ntfs.c index 87db1a561..eadf9d6a2 100644 --- a/fs/ntfs.c +++ b/fs/ntfs.c @@ -1072,8 +1072,7 @@ grub_ntfs_uuid (grub_device_t device, char **uuid) data = grub_ntfs_mount (disk); if (data) { - *uuid = grub_malloc (16 + sizeof ('\0')); - grub_sprintf (*uuid, "%016llx", (unsigned long long) data->uuid); + *uuid = grub_asprintf ("%016llx", (unsigned long long) data->uuid); } else *uuid = NULL; diff --git a/fs/reiserfs.c b/fs/reiserfs.c index a8ba75910..d5a20ee6c 100644 --- a/fs/reiserfs.c +++ b/fs/reiserfs.c @@ -1335,12 +1335,15 @@ grub_reiserfs_uuid (grub_device_t device, char **uuid) data = grub_reiserfs_mount (disk); if (data) { - *uuid = grub_malloc (sizeof ("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")); - grub_sprintf (*uuid, "%04x%04x-%04x-%04x-%04x-%04x%04x%04x", - grub_be_to_cpu16 (data->superblock.uuid[0]), grub_be_to_cpu16 (data->superblock.uuid[1]), - grub_be_to_cpu16 (data->superblock.uuid[2]), grub_be_to_cpu16 (data->superblock.uuid[3]), - grub_be_to_cpu16 (data->superblock.uuid[4]), grub_be_to_cpu16 (data->superblock.uuid[5]), - grub_be_to_cpu16 (data->superblock.uuid[6]), grub_be_to_cpu16 (data->superblock.uuid[7])); + *uuid = grub_asprintf ("%04x%04x-%04x-%04x-%04x-%04x%04x%04x", + grub_be_to_cpu16 (data->superblock.uuid[0]), + grub_be_to_cpu16 (data->superblock.uuid[1]), + grub_be_to_cpu16 (data->superblock.uuid[2]), + grub_be_to_cpu16 (data->superblock.uuid[3]), + grub_be_to_cpu16 (data->superblock.uuid[4]), + grub_be_to_cpu16 (data->superblock.uuid[5]), + grub_be_to_cpu16 (data->superblock.uuid[6]), + grub_be_to_cpu16 (data->superblock.uuid[7])); } else *uuid = NULL; diff --git a/fs/ufs.c b/fs/ufs.c index f95a6e12e..575c9f449 100644 --- a/fs/ufs.c +++ b/fs/ufs.c @@ -732,12 +732,9 @@ grub_ufs_uuid (grub_device_t device, char **uuid) data = grub_ufs_mount (disk); if (data && (data->sblock.uuidhi != 0 || data->sblock.uuidlow != 0)) - { - *uuid = grub_malloc (16 + sizeof ('\0')); - grub_sprintf (*uuid, "%08x%08x", - (unsigned) grub_le_to_cpu32 (data->sblock.uuidhi), - (unsigned) grub_le_to_cpu32 (data->sblock.uuidlow)); - } + *uuid = grub_asprintf ("%08x%08x", + (unsigned) grub_le_to_cpu32 (data->sblock.uuidhi), + (unsigned) grub_le_to_cpu32 (data->sblock.uuidlow)); else *uuid = NULL; diff --git a/fs/xfs.c b/fs/xfs.c index c15ec7341..e3f58c9de 100644 --- a/fs/xfs.c +++ b/fs/xfs.c @@ -777,12 +777,15 @@ grub_xfs_uuid (grub_device_t device, char **uuid) data = grub_xfs_mount (disk); if (data) { - *uuid = grub_malloc (sizeof ("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")); - grub_sprintf (*uuid, "%04x%04x-%04x-%04x-%04x-%04x%04x%04x", - grub_be_to_cpu16 (data->sblock.uuid[0]), grub_be_to_cpu16 (data->sblock.uuid[1]), - grub_be_to_cpu16 (data->sblock.uuid[2]), grub_be_to_cpu16 (data->sblock.uuid[3]), - grub_be_to_cpu16 (data->sblock.uuid[4]), grub_be_to_cpu16 (data->sblock.uuid[5]), - grub_be_to_cpu16 (data->sblock.uuid[6]), grub_be_to_cpu16 (data->sblock.uuid[7])); + *uuid = grub_asprintf ("%04x%04x-%04x-%04x-%04x-%04x%04x%04x", + grub_be_to_cpu16 (data->sblock.uuid[0]), + grub_be_to_cpu16 (data->sblock.uuid[1]), + grub_be_to_cpu16 (data->sblock.uuid[2]), + grub_be_to_cpu16 (data->sblock.uuid[3]), + grub_be_to_cpu16 (data->sblock.uuid[4]), + grub_be_to_cpu16 (data->sblock.uuid[5]), + grub_be_to_cpu16 (data->sblock.uuid[6]), + grub_be_to_cpu16 (data->sblock.uuid[7])); } else *uuid = NULL; diff --git a/gettext/gettext.c b/gettext/gettext.c index 3472b2fb8..f271f24ab 100644 --- a/gettext/gettext.c +++ b/gettext/gettext.c @@ -275,14 +275,19 @@ grub_gettext_init_ext (const char *lang) /* Warning: if changing some paths in the below line, change the grub_malloc contents below. */ - grub_sprintf (mo_file, "%s/%s.mo", locale_dir, lang); + mo_file = grub_asprintf ("%s/%s.mo", locale_dir, lang); + if (!mo_file) + return; fd_mo = grub_mofile_open (mo_file); /* Will try adding .gz as well. */ if (fd_mo == NULL) { - grub_sprintf (mo_file, "%s.gz", mo_file); + grub_free (mo_file); + mo_file = grub_asprintf ("%s.gz", mo_file); + if (!mo_file) + return; fd_mo = grub_mofile_open (mo_file); } diff --git a/hook/datehook.c b/hook/datehook.c index b7663cc21..4876e1198 100644 --- a/hook/datehook.c +++ b/hook/datehook.c @@ -76,7 +76,7 @@ grub_read_hook_datetime (struct grub_env_var *var, return grub_get_weekday_name (&datetime); } - grub_sprintf (buf, "%d", n); + grub_snprintf (buf, sizeof (buf), "%d", n); break; } } diff --git a/include/grub/misc.h b/include/grub/misc.h index 92fb460cf..f4d722081 100644 --- a/include/grub/misc.h +++ b/include/grub/misc.h @@ -179,8 +179,13 @@ void EXPORT_FUNC(grub_real_dprintf) (const char *file, const char *condition, const char *fmt, ...) __attribute__ ((format (printf, 4, 5))); int EXPORT_FUNC(grub_vprintf) (const char *fmt, va_list args); -int EXPORT_FUNC(grub_sprintf) (char *str, const char *fmt, ...) __attribute__ ((format (printf, 2, 3))); -int EXPORT_FUNC(grub_vsprintf) (char *str, const char *fmt, va_list args); +int EXPORT_FUNC(grub_snprintf) (char *str, grub_size_t n, const char *fmt, ...) + __attribute__ ((format (printf, 3, 4))); +int EXPORT_FUNC(grub_vsnprintf) (char *str, grub_size_t n, const char *fmt, + va_list args); +char *EXPORT_FUNC(grub_asprintf) (const char *fmt, ...) + __attribute__ ((format (printf, 1, 2))); +char *EXPORT_FUNC(grub_avsprintf) (const char *fmt, va_list args); void EXPORT_FUNC(grub_exit) (void) __attribute__ ((noreturn)); void EXPORT_FUNC(grub_abort) (void) __attribute__ ((noreturn)); grub_ssize_t EXPORT_FUNC(grub_utf8_to_ucs4) (grub_uint32_t *dest, diff --git a/kern/device.c b/kern/device.c index 9f219949b..d1692baa0 100644 --- a/kern/device.c +++ b/kern/device.c @@ -86,7 +86,7 @@ grub_device_iterate (int (*hook) (const char *name)) struct part_ent { struct part_ent *next; - char name[0]; + char *name; } *ents; int iterate_disk (const char *disk_name) @@ -118,6 +118,7 @@ grub_device_iterate (int (*hook) (const char *name)) if (!ret) ret = hook (p->name); + grub_free (p->name); grub_free (p); p = next; } @@ -138,15 +139,20 @@ grub_device_iterate (int (*hook) (const char *name)) if (! partition_name) return 1; - p = grub_malloc (sizeof (p->next) + grub_strlen (disk->name) + 1 + - grub_strlen (partition_name) + 1); + p = grub_malloc (sizeof (p->next)); if (!p) { grub_free (partition_name); return 1; } - grub_sprintf (p->name, "%s,%s", disk->name, partition_name); + p->name = grub_asprintf ("%s,%s", disk->name, partition_name); + if (!p->name) + { + grub_free (partition_name); + grub_free (p); + return 1; + } grub_free (partition_name); p->next = ents; diff --git a/kern/dl.c b/kern/dl.c index 20ab1c5c2..36bbd882c 100644 --- a/kern/dl.c +++ b/kern/dl.c @@ -628,12 +628,10 @@ grub_dl_load (const char *name) return 0; } - filename = (char *) grub_malloc (grub_strlen (grub_dl_dir) + 1 - + grub_strlen (name) + 4 + 1); + filename = grub_asprintf ("%s/%s.mod", grub_dl_dir, name); if (! filename) return 0; - grub_sprintf (filename, "%s/%s.mod", grub_dl_dir, name); mod = grub_dl_load_file (filename); grub_free (filename); diff --git a/kern/efi/init.c b/kern/efi/init.c index f9ba03852..443684000 100644 --- a/kern/efi/init.c +++ b/kern/efi/init.c @@ -63,11 +63,10 @@ grub_efi_set_prefix (void) if (p) *p = '\0'; - prefix = grub_malloc (1 + grub_strlen (device) + 1 - + grub_strlen (file) + 1); + prefix = grub_asprintf ("(%s)%s", device, file); if (prefix) { - grub_sprintf (prefix, "(%s)%s", device, file); + grub_env_set ("prefix", prefix); grub_free (prefix); } diff --git a/kern/env.c b/kern/env.c index 969227dec..dd167a709 100644 --- a/kern/env.c +++ b/kern/env.c @@ -356,14 +356,7 @@ grub_register_variable_hook (const char *name, static char * mangle_data_slot_name (const char *name) { - char *mangled_name; - - mangled_name = grub_malloc (grub_strlen (name) + 2); - if (! mangled_name) - return 0; - - grub_sprintf (mangled_name, "\e%s", name); - return mangled_name; + return grub_asprintf ("\e%s", name); } grub_err_t diff --git a/kern/err.c b/kern/err.c index 311130154..5a63b4187 100644 --- a/kern/err.c +++ b/kern/err.c @@ -44,7 +44,7 @@ grub_error (grub_err_t n, const char *fmt, ...) grub_errno = n; va_start (ap, fmt); - grub_vsprintf (grub_errmsg, fmt, ap); + grub_vsnprintf (grub_errmsg, sizeof (grub_errmsg), fmt, ap); va_end (ap); return n; diff --git a/kern/i386/pc/init.c b/kern/i386/pc/init.c index ebe4bb6ea..029ec4c6b 100644 --- a/kern/i386/pc/init.c +++ b/kern/i386/pc/init.c @@ -56,22 +56,30 @@ static char * make_install_device (void) { /* XXX: This should be enough. */ - char dev[100]; + char dev[100], *ptr = dev; if (grub_prefix[0] != '(') { /* No hardcoded root partition - make it from the boot drive and the partition number encoded at the install time. */ - grub_sprintf (dev, "(%cd%u", (grub_boot_drive & 0x80) ? 'h' : 'f', + grub_snprintf (dev, sizeof (dev), + "(%cd%u", (grub_boot_drive & 0x80) ? 'h' : 'f', grub_boot_drive & 0x7f); + ptr += grub_strlen (ptr); if (grub_install_dos_part >= 0) - grub_sprintf (dev + grub_strlen (dev), ",%u", grub_install_dos_part + 1); + grub_snprintf (ptr, sizeof (dev) - (ptr - dev), + ",%u", grub_install_dos_part + 1); + + ptr += grub_strlen (ptr); if (grub_install_bsd_part >= 0) - grub_sprintf (dev + grub_strlen (dev), ",%c", grub_install_bsd_part + 'a'); + grub_snprintf (ptr, sizeof (dev) - (ptr - dev), ",%c", + grub_install_bsd_part + 'a'); - grub_sprintf (dev + grub_strlen (dev), ")%s", grub_prefix); + ptr += grub_strlen (ptr); + + grub_snprintf (ptr, sizeof (dev) - (ptr - dev), ")%s", grub_prefix); grub_strcpy (grub_prefix, dev); } diff --git a/kern/ieee1275/init.c b/kern/ieee1275/init.c index f3305d71c..7ef628397 100644 --- a/kern/ieee1275/init.c +++ b/kern/ieee1275/init.c @@ -111,11 +111,12 @@ grub_machine_set_prefix (void) *lastslash = '\0'; grub_translate_ieee1275_path (filename); - newprefix = grub_malloc (grub_strlen (prefix) - + grub_strlen (filename)); - grub_sprintf (newprefix, "%s%s", prefix, filename); - grub_free (prefix); - prefix = newprefix; + newprefix = grub_asprintf ("%s%s", prefix, filename); + if (newprefix) + { + grub_free (prefix); + prefix = newprefix; + } } } diff --git a/kern/ieee1275/openfw.c b/kern/ieee1275/openfw.c index c38eb450f..50bd9557a 100644 --- a/kern/ieee1275/openfw.c +++ b/kern/ieee1275/openfw.c @@ -38,7 +38,7 @@ grub_children_iterate (char *devpath, grub_ieee1275_phandle_t dev; grub_ieee1275_phandle_t child; char *childtype, *childpath; - char *childname, *fullname; + char *childname; int ret = 0; if (grub_ieee1275_finddevice (devpath, &dev)) @@ -63,19 +63,12 @@ grub_children_iterate (char *devpath, grub_free (childtype); return 0; } - fullname = grub_malloc (IEEE1275_MAX_PATH_LEN); - if (!fullname) - { - grub_free (childname); - grub_free (childpath); - grub_free (childtype); - return 0; - } do { struct grub_ieee1275_devalias alias; grub_ssize_t actual; + char *fullname; if (grub_ieee1275_get_property (child, "device_type", childtype, IEEE1275_MAX_PROP_LEN, &actual)) @@ -89,18 +82,25 @@ grub_children_iterate (char *devpath, IEEE1275_MAX_PROP_LEN, &actual)) continue; - grub_sprintf (fullname, "%s/%s", devpath, childname); + fullname = grub_asprintf ("%s/%s", devpath, childname); + if (!fullname) + { + grub_free (childname); + grub_free (childpath); + grub_free (childtype); + return 0; + } alias.type = childtype; alias.path = childpath; alias.name = fullname; ret = hook (&alias); + grub_free (fullname); if (ret) break; } while (grub_ieee1275_peer (child, &child)); - grub_free (fullname); grub_free (childname); grub_free (childpath); grub_free (childtype); @@ -330,12 +330,11 @@ grub_ieee1275_parse_args (const char *path, enum grub_ieee1275_parse_type ptype) { char *filepath = comma + 1; - ret = grub_malloc (grub_strlen (filepath) + 1); /* Make sure filepath has leading backslash. */ if (filepath[0] != '\\') - grub_sprintf (ret, "\\%s", filepath); + ret = grub_asprintf ("\\%s", filepath); else - grub_strcpy (ret, filepath); + ret = grub_strdup (filepath); } } else if (ptype == GRUB_PARSE_PARTITION) @@ -383,15 +382,10 @@ grub_ieee1275_encode_devname (const char *path) /* GRUB partition 1 is OF partition 0. */ partno++; - /* Assume partno will require less than five bytes to encode. */ - encoding = grub_malloc (grub_strlen (device) + 3 + 5); - grub_sprintf (encoding, "(%s,%d)", device, partno); + encoding = grub_asprintf ("(%s,%d)", device, partno); } else - { - encoding = grub_malloc (grub_strlen (device) + 2); - grub_sprintf (encoding, "(%s)", device); - } + encoding = grub_asprintf ("(%s)", device); grub_free (partition); grub_free (device); diff --git a/kern/misc.c b/kern/misc.c index f6d189e94..087bef7fe 100644 --- a/kern/misc.c +++ b/kern/misc.c @@ -25,6 +25,9 @@ #include #include +static int +grub_vsnprintf_real (char *str, grub_size_t n, const char *fmt, va_list args); + static int grub_iswordseparator (int c) { @@ -202,7 +205,7 @@ grub_vprintf (const char *fmt, va_list args) { int ret; - ret = grub_vsprintf (0, fmt, args); + ret = grub_vsnprintf_real (0, 0, fmt, args); grub_refresh (); return ret; } @@ -626,11 +629,11 @@ grub_lltoa (char *str, int c, unsigned long long n) return p; } -int -grub_vsprintf (char *str, const char *fmt, va_list args) +static int +grub_vsnprintf_real (char *str, grub_size_t n, const char *fmt, va_list args) { char c; - int count = 0; + grub_size_t count = 0; auto void write_char (unsigned char ch); auto void write_str (const char *s); auto void write_fill (const char ch, int n); @@ -638,7 +641,10 @@ grub_vsprintf (char *str, const char *fmt, va_list args) void write_char (unsigned char ch) { if (str) - *str++ = ch; + { + if (count < n) + *str++ = ch; + } else grub_putchar (ch); @@ -867,13 +873,64 @@ grub_vsprintf (char *str, const char *fmt, va_list args) } int -grub_sprintf (char *str, const char *fmt, ...) +grub_vsnprintf (char *str, grub_size_t n, const char *fmt, va_list ap) +{ + grub_size_t ret; + + if (!n) + return 0; + + n--; + + ret = grub_vsnprintf_real (str, n, fmt, ap); + + return ret < n ? ret : n; +} + +int +grub_snprintf (char *str, grub_size_t n, const char *fmt, ...) { va_list ap; int ret; va_start (ap, fmt); - ret = grub_vsprintf (str, fmt, ap); + ret = grub_vsnprintf (str, n, fmt, ap); + va_end (ap); + + return ret; +} + +#define PREALLOC_SIZE 255 + +char * +grub_avsprintf (const char *fmt, va_list ap) +{ + grub_size_t s, as = PREALLOC_SIZE; + char *ret; + + while (1) + { + ret = grub_malloc (as + 1); + if (!ret) + return NULL; + + s = grub_vsnprintf (ret, as, fmt, ap); + if (s <= as) + return ret; + + grub_free (ret); + as = s; + } +} + +char * +grub_asprintf (const char *fmt, ...) +{ + va_list ap; + char *ret; + + va_start (ap, fmt); + ret = grub_avsprintf (fmt, ap); va_end (ap); return ret; diff --git a/kern/sparc64/ieee1275/init.c b/kern/sparc64/ieee1275/init.c index 699f9631b..339d836a3 100644 --- a/kern/sparc64/ieee1275/init.c +++ b/kern/sparc64/ieee1275/init.c @@ -90,10 +90,7 @@ grub_machine_set_prefix (void) } prefix = grub_ieee1275_encode_devname (bootpath); - path = grub_malloc (grub_strlen (grub_prefix) - + grub_strlen (prefix) - + 2); - grub_sprintf(path, "%s%s", prefix, grub_prefix); + path = grub_asprintf("%s%s", prefix, grub_prefix); grub_strcpy (grub_prefix, path); diff --git a/lib/hexdump.c b/lib/hexdump.c index c69cb093b..db16f6926 100644 --- a/lib/hexdump.c +++ b/lib/hexdump.c @@ -31,21 +31,22 @@ hexdump (unsigned long bse, char *buf, int len) { int cnt, i; - pos = grub_sprintf (line, "%08lx ", bse); + pos = grub_snprintf (line, sizeof (line), "%08lx ", bse); cnt = 16; if (cnt > len) cnt = len; for (i = 0; i < cnt; i++) { - pos += grub_sprintf (&line[pos], "%02x ", (unsigned char) buf[i]); + pos += grub_snprintf (&line[pos], sizeof (line) - pos, + "%02x ", (unsigned char) buf[i]); if ((i & 7) == 7) line[pos++] = ' '; } for (; i < 16; i++) { - pos += grub_sprintf (&line[pos], " "); + pos += grub_snprintf (&line[pos], sizeof (line) - pos, " "); if ((i & 7) == 7) line[pos++] = ' '; } diff --git a/loader/i386/bsd.c b/loader/i386/bsd.c index ca60b0be9..06eb5bfd9 100644 --- a/loader/i386/bsd.c +++ b/loader/i386/bsd.c @@ -1138,14 +1138,20 @@ grub_cmd_freebsd_loadenv (grub_command_t cmd __attribute__ ((unused)), if (*curr) { - char name[grub_strlen (curr) + sizeof("kFreeBSD.")]; + char *name; if (*p == '"') p++; - grub_sprintf (name, "kFreeBSD.%s", curr); - if (grub_env_set (name, p)) + name = grub_asprintf ("kFreeBSD.%s", curr); + if (!name) goto fail; + if (grub_env_set (name, p)) + { + grub_free (name); + goto fail; + } + grub_free (name); } } diff --git a/loader/i386/linux.c b/loader/i386/linux.c index 899216783..93f3da058 100644 --- a/loader/i386/linux.c +++ b/loader/i386/linux.c @@ -517,11 +517,9 @@ grub_linux_boot (void) May change in future if we have modes without framebuffer. */ if (modevar && *modevar != 0) { - tmp = grub_malloc (grub_strlen (modevar) - + sizeof (";text")); + tmp = grub_asprintf ("%s;text", modevar); if (! tmp) return grub_errno; - grub_sprintf (tmp, "%s;text", modevar); err = grub_video_set_mode (tmp, 0); grub_free (tmp); } @@ -779,19 +777,18 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), break; } - buf = grub_malloc (sizeof ("WWWWxHHHHxDD;WWWWxHHHH")); - if (! buf) - goto fail; - linux_mode = &linux_vesafb_modes[vid_mode - GRUB_LINUX_VID_MODE_VESA_START]; - grub_sprintf (buf, "%ux%ux%u,%ux%u", - linux_vesafb_res[linux_mode->res_index].width, - linux_vesafb_res[linux_mode->res_index].height, - linux_mode->depth, - linux_vesafb_res[linux_mode->res_index].width, - linux_vesafb_res[linux_mode->res_index].height); + buf = grub_asprintf ("%ux%ux%u,%ux%u", + linux_vesafb_res[linux_mode->res_index].width, + linux_vesafb_res[linux_mode->res_index].height, + linux_mode->depth, + linux_vesafb_res[linux_mode->res_index].width, + linux_vesafb_res[linux_mode->res_index].height); + if (! buf) + goto fail; + grub_printf ("%s is deprecated. " "Use set gfxpayload=%s before " "linux command instead.\n", diff --git a/loader/i386/pc/xnu.c b/loader/i386/pc/xnu.c index ebb176bb4..07c1ee37e 100644 --- a/loader/i386/pc/xnu.c +++ b/loader/i386/pc/xnu.c @@ -52,12 +52,10 @@ grub_xnu_set_video (struct grub_xnu_boot_params *params) err = grub_video_set_mode (DEFAULT_VIDEO_MODE, video_hook); else { - tmp = grub_malloc (grub_strlen (modevar) - + sizeof (DEFAULT_VIDEO_MODE) + 1); + tmp = grub_asprintf ("%s;" DEFAULT_VIDEO_MODE, modevar); if (! tmp) return grub_error (GRUB_ERR_OUT_OF_MEMORY, "couldn't allocate temporary storag"); - grub_sprintf (tmp, "%s;" DEFAULT_VIDEO_MODE, modevar); err = grub_video_set_mode (tmp, video_hook); grub_free (tmp); } diff --git a/loader/i386/xnu.c b/loader/i386/xnu.c index f71e2c306..ef3e90538 100644 --- a/loader/i386/xnu.c +++ b/loader/i386/xnu.c @@ -748,11 +748,13 @@ grub_cpu_xnu_fill_devicetree (void) #endif /* The name of key for new table. */ - grub_sprintf (guidbuf, "%08x-%04x-%04x-%02x%02x-", - guid.data1, guid.data2, guid.data3, guid.data4[0], - guid.data4[1]); + grub_snprintf (guidbuf, sizeof (guidbuf), "%08x-%04x-%04x-%02x%02x-", + guid.data1, guid.data2, guid.data3, guid.data4[0], + guid.data4[1]); for (j = 2; j < 8; j++) - grub_sprintf (guidbuf + grub_strlen (guidbuf), "%02x", guid.data4[j]); + grub_snprintf (guidbuf + grub_strlen (guidbuf), + sizeof (guidbuf) - grub_strlen (guidbuf), + "%02x", guid.data4[j]); /* For some reason GUID has to be in uppercase. */ for (j = 0; guidbuf[j] ; j++) if (guidbuf[j] >= 'a' && guidbuf[j] <= 'f') diff --git a/loader/xnu.c b/loader/xnu.c index f3ae3888a..bb1178e17 100644 --- a/loader/xnu.c +++ b/loader/xnu.c @@ -568,10 +568,9 @@ grub_xnu_register_memory (char *prefix, int *suffix, return grub_error (GRUB_ERR_OUT_OF_MEMORY, "can't register memory"); if (suffix) { - driverkey->name = grub_malloc (grub_strlen (prefix) + 10); + driverkey->name = grub_asprintf ("%s%d", prefix, (*suffix)++); if (!driverkey->name) return grub_error (GRUB_ERR_OUT_OF_MEMORY, "can't register memory"); - grub_sprintf (driverkey->name, "%s%d", prefix, (*suffix)++); } else driverkey->name = grub_strdup (prefix); diff --git a/normal/autofs.c b/normal/autofs.c index ce354a22c..d1a6d2110 100644 --- a/normal/autofs.c +++ b/normal/autofs.c @@ -63,12 +63,11 @@ read_fs_list (void) { char *filename; - filename = grub_malloc (grub_strlen (prefix) + sizeof ("/fs.lst")); + filename = grub_asprintf ("%s/fs.lst", prefix); if (filename) { grub_file_t file; - grub_sprintf (filename, "%s/fs.lst", prefix); file = grub_file_open (filename); if (file) { diff --git a/normal/completion.c b/normal/completion.c index d264028cc..81972636d 100644 --- a/normal/completion.c +++ b/normal/completion.c @@ -107,17 +107,12 @@ iterate_partition (grub_disk_t disk, const grub_partition_t p) if (! partition_name) return 1; - name = grub_malloc (grub_strlen (disk_name) + 1 - + grub_strlen (partition_name) + 1); - if (! name) - { - grub_free (partition_name); - return 1; - } - - grub_sprintf (name, "%s,%s", disk_name, partition_name); + name = grub_asprintf ("%s,%s", disk_name, partition_name); grub_free (partition_name); + if (! name) + return 1; + ret = add_completion (name, ")", GRUB_COMPLETION_TYPE_PARTITION); grub_free (name); return ret; @@ -141,11 +136,15 @@ iterate_dir (const char *filename, const struct grub_dirhook_info *info) } else if (grub_strcmp (filename, ".") && grub_strcmp (filename, "..")) { - char fname[grub_strlen (filename) + 2]; + char *fname; - grub_sprintf (fname, "%s/", filename); + fname = grub_asprintf ("%s/", filename); if (add_completion (fname, "", GRUB_COMPLETION_TYPE_FILE)) - return 1; + { + grub_free (fname); + return 1; + } + grub_free (fname); } return 0; @@ -360,8 +359,9 @@ complete_arguments (char *command) if (!option->longarg) continue; - longarg = grub_malloc (grub_strlen (option->longarg)); - grub_sprintf (longarg, "--%s", option->longarg); + longarg = grub_asprintf ("--%s", option->longarg); + if (!longarg) + return 1; if (add_completion (longarg, " ", GRUB_COMPLETION_TYPE_ARGUMENT)) { diff --git a/normal/dyncmd.c b/normal/dyncmd.c index 04f1945dc..0a9bb347a 100644 --- a/normal/dyncmd.c +++ b/normal/dyncmd.c @@ -75,12 +75,11 @@ read_command_list (void) { char *filename; - filename = grub_malloc (grub_strlen (prefix) + sizeof ("/command.lst")); + filename = grub_asprintf ("%s/command.lst", prefix); if (filename) { grub_file_t file; - grub_sprintf (filename, "%s/command.lst", prefix); file = grub_file_open (filename); if (file) { diff --git a/normal/handler.c b/normal/handler.c index b44dc7a68..034be77d1 100644 --- a/normal/handler.c +++ b/normal/handler.c @@ -172,12 +172,11 @@ read_handler_list (void) { char *filename; - filename = grub_malloc (grub_strlen (prefix) + sizeof ("/handler.lst")); + filename = grub_asprintf ("%s/handler.lst", prefix); if (filename) { grub_file_t file; - grub_sprintf (filename, "%s/handler.lst", prefix); file = grub_file_open (filename); if (file) { diff --git a/normal/main.c b/normal/main.c index 23de7e238..7aeba37ca 100644 --- a/normal/main.c +++ b/normal/main.c @@ -389,16 +389,17 @@ grub_normal_init_page (void) int posx; const char *msg = _("GNU GRUB version %s"); - char *msg_formatted = grub_malloc (grub_strlen(msg) + - grub_strlen(PACKAGE_VERSION)); - - grub_cls (); - - grub_sprintf (msg_formatted, msg, PACKAGE_VERSION); + char *msg_formatted; grub_uint32_t *unicode_msg; grub_uint32_t *last_position; + grub_cls (); + + msg_formatted = grub_asprintf (msg, PACKAGE_VERSION); + if (!msg_formatted) + return; + msg_len = grub_utf8_to_ucs4_alloc (msg_formatted, &unicode_msg, &last_position); @@ -475,11 +476,10 @@ grub_cmd_normal (struct grub_command *cmd, prefix = grub_env_get ("prefix"); if (prefix) { - config = grub_malloc (grub_strlen (prefix) + sizeof ("/grub.cfg")); + config = grub_asprintf ("%s/grub.cfg", prefix); if (! config) goto quit; - grub_sprintf (config, "%s/grub.cfg", prefix); grub_enter_normal_mode (config); grub_free (config); } @@ -528,10 +528,11 @@ grub_normal_reader_init (void) const char *msg_esc = _("ESC at any time exits."); - char *msg_formatted = grub_malloc (sizeof (char) * (grub_strlen (msg) + - grub_strlen(msg_esc) + 1)); + char *msg_formatted; - grub_sprintf (msg_formatted, msg, reader_nested ? msg_esc : ""); + msg_formatted = grub_asprintf (msg, reader_nested ? msg_esc : ""); + if (!msg_formatted) + return grub_errno; grub_print_message_indented (msg_formatted, 3, STANDARD_MARGIN); grub_puts ("\n"); @@ -546,9 +547,11 @@ static grub_err_t grub_normal_read_line (char **line, int cont) { grub_parser_t parser = grub_parser_get_current (); - char prompt[sizeof(">") + grub_strlen (parser->name)]; + char *prompt; - grub_sprintf (prompt, "%s>", parser->name); + prompt = grub_asprintf ("%s>", parser->name); + if (!prompt) + return grub_errno; while (1) { diff --git a/normal/menu.c b/normal/menu.c index 8ee7d1c22..99ffc67dd 100644 --- a/normal/menu.c +++ b/normal/menu.c @@ -78,7 +78,7 @@ grub_menu_set_timeout (int timeout) { char buf[16]; - grub_sprintf (buf, "%d", timeout); + grub_snprintf (buf, sizeof (buf), "%d", timeout); grub_env_set ("timeout", buf); } } diff --git a/normal/menu_text.c b/normal/menu_text.c index bac15f32b..3bcf35a93 100644 --- a/normal/menu_text.c +++ b/normal/menu_text.c @@ -210,13 +210,14 @@ command-line or ESC to return menu."), STANDARD_MARGIN, STANDARD_MARGIN); } else { - const char *msg = _("Use the %C and %C keys to select which \ -entry is highlighted.\n"); - char *msg_translated = - grub_malloc (sizeof (char) * grub_strlen (msg) + 1); + const char *msg = _("Use the %C and %C keys to select which " + "entry is highlighted.\n"); + char *msg_translated; - grub_sprintf (msg_translated, msg, (grub_uint32_t) GRUB_TERM_DISP_UP, - (grub_uint32_t) GRUB_TERM_DISP_DOWN); + msg_translated = grub_asprintf (msg, (grub_uint32_t) GRUB_TERM_DISP_UP, + (grub_uint32_t) GRUB_TERM_DISP_DOWN); + if (!msg_translated) + return; grub_putchar ('\n'); grub_print_message_indented (msg_translated, STANDARD_MARGIN, STANDARD_MARGIN); @@ -394,13 +395,13 @@ print_timeout (int timeout, int offset) { const char *msg = _("The highlighted entry will be booted automatically in %ds."); + char *msg_translated; grub_gotoxy (0, GRUB_TERM_HEIGHT - 3); - char *msg_translated = - grub_malloc (sizeof (char) * grub_strlen (msg) + 5); - - grub_sprintf (msg_translated, msg, timeout); + msg_translated = grub_asprintf (msg, timeout); + if (!msg_translated) + return; grub_print_message_indented (msg_translated, 3, 0); int posx; diff --git a/partmap/acorn.c b/partmap/acorn.c index 076d998f8..aead5ff85 100644 --- a/partmap/acorn.c +++ b/partmap/acorn.c @@ -175,14 +175,7 @@ fail: static char * acorn_partition_map_get_name (const grub_partition_t p) { - char *name; - - name = grub_malloc (13); - if (! name) - return 0; - - grub_sprintf (name, "%d", p->index + 1); - return name; + return grub_asprintf ("%d", p->index + 1); } diff --git a/partmap/amiga.c b/partmap/amiga.c index e8ba9181c..691bd4c3e 100644 --- a/partmap/amiga.c +++ b/partmap/amiga.c @@ -184,14 +184,7 @@ amiga_partition_map_probe (grub_disk_t disk, const char *str) static char * amiga_partition_map_get_name (const grub_partition_t p) { - char *name; - - name = grub_malloc (13); - if (! name) - return 0; - - grub_sprintf (name, "%d", p->index + 1); - return name; + return grub_asprintf ("%d", p->index + 1); } diff --git a/partmap/apple.c b/partmap/apple.c index 765912672..a5f7fdd8a 100644 --- a/partmap/apple.c +++ b/partmap/apple.c @@ -227,14 +227,7 @@ apple_partition_map_probe (grub_disk_t disk, const char *str) static char * apple_partition_map_get_name (const grub_partition_t p) { - char *name; - - name = grub_malloc (13); - if (! name) - return 0; - - grub_sprintf (name, "%d", p->index + 1); - return name; + return grub_asprintf ("%d", p->index + 1); } diff --git a/partmap/gpt.c b/partmap/gpt.c index 4a4957437..ed583e0a3 100644 --- a/partmap/gpt.c +++ b/partmap/gpt.c @@ -162,14 +162,7 @@ gpt_partition_map_probe (grub_disk_t disk, const char *str) static char * gpt_partition_map_get_name (const grub_partition_t p) { - char *name; - - name = grub_malloc (13); - if (! name) - return 0; - - grub_sprintf (name, "%d", p->index + 1); - return name; + return grub_asprintf ("%d", p->index + 1); } diff --git a/partmap/msdos.c b/partmap/msdos.c index 6ba7fb927..ea3266605 100644 --- a/partmap/msdos.c +++ b/partmap/msdos.c @@ -300,21 +300,15 @@ pc_partition_map_probe (grub_disk_t disk, const char *str) static char * pc_partition_map_get_name (const grub_partition_t p) { - char *name; struct grub_msdos_partition *pcdata = p->data; - name = grub_malloc (13); - if (! name) - return 0; - if (pcdata->bsd_part < 0) - grub_sprintf (name, "%d", pcdata->dos_part + 1); + return grub_asprintf ("%d", pcdata->dos_part + 1); else if (pcdata->dos_part < 0) - grub_sprintf (name, "%c", pcdata->bsd_part + 'a'); + return grub_asprintf ("%c", pcdata->bsd_part + 'a'); else - grub_sprintf (name, "%d,%c", pcdata->dos_part + 1, pcdata->bsd_part + 'a'); - - return name; + return grub_asprintf ("%d,%c", pcdata->dos_part + 1, + pcdata->bsd_part + 'a'); } diff --git a/partmap/sun.c b/partmap/sun.c index e816ec17a..89d0c5303 100644 --- a/partmap/sun.c +++ b/partmap/sun.c @@ -184,13 +184,7 @@ sun_partition_map_probe (grub_disk_t disk, const char *str) static char * sun_partition_map_get_name (const grub_partition_t p) { - char *name; - - name = grub_malloc (13); - if (name) - grub_sprintf (name, "%d", p->index + 1); - - return name; + return grub_asprintf ("%d", p->index + 1); } /* Partition map type. */ diff --git a/script/execute.c b/script/execute.c index 08224fc7d..ee7e099bc 100644 --- a/script/execute.c +++ b/script/execute.c @@ -92,7 +92,7 @@ grub_script_execute_cmdline (struct grub_script_cmd *cmd) grub_err_t ret = 0; int argcount = 0; grub_script_function_t func = 0; - char errnobuf[6]; + char errnobuf[18]; char *cmdname; /* Lookup the command. */ @@ -123,7 +123,7 @@ grub_script_execute_cmdline (struct grub_script_cmd *cmd) } grub_free (assign); - grub_sprintf (errnobuf, "%d", grub_errno); + grub_snprintf (errnobuf, sizeof (errnobuf), "%d", grub_errno); grub_env_set ("?", errnobuf); return 0; @@ -156,7 +156,7 @@ grub_script_execute_cmdline (struct grub_script_cmd *cmd) grub_free (args[i]); grub_free (args); - grub_sprintf (errnobuf, "%d", ret); + grub_snprintf (errnobuf, sizeof (errnobuf), "%d", ret); grub_env_set ("?", errnobuf); return ret; diff --git a/term/gfxterm.c b/term/gfxterm.c index fa19a5d85..7c99ae053 100644 --- a/term/gfxterm.c +++ b/term/gfxterm.c @@ -272,9 +272,9 @@ grub_gfxterm_init (void) err = grub_video_set_mode (DEFAULT_VIDEO_MODE, video_hook); else { - tmp = grub_malloc (grub_strlen (modevar) - + sizeof (DEFAULT_VIDEO_MODE) + 1); - grub_sprintf (tmp, "%s;" DEFAULT_VIDEO_MODE, modevar); + tmp = grub_asprintf ("%s;" DEFAULT_VIDEO_MODE, modevar); + if (!tmp) + return grub_errno; err = grub_video_set_mode (tmp, video_hook); grub_free (tmp); } diff --git a/term/ieee1275/ofconsole.c b/term/ieee1275/ofconsole.c index fbed9eca1..88606a4bc 100644 --- a/term/ieee1275/ofconsole.c +++ b/term/ieee1275/ofconsole.c @@ -104,7 +104,7 @@ grub_ofconsole_getcharwidth (grub_uint32_t c __attribute__((unused))) static void grub_ofconsole_setcolorstate (grub_term_color_state state) { - char setcol[20]; + char *setcol; int fg; int bg; @@ -123,8 +123,10 @@ grub_ofconsole_setcolorstate (grub_term_color_state state) return; } - grub_sprintf (setcol, "\e[3%dm\e[4%dm", fg, bg); - grub_ofconsole_writeesc (setcol); + setcol = grub_asprintf ("\e[3%dm\e[4%dm", fg, bg); + if (setcol) + grub_ofconsole_writeesc (setcol); + grub_free (setcol); } static void @@ -287,15 +289,16 @@ grub_ofconsole_getwh (void) static void grub_ofconsole_gotoxy (grub_uint8_t x, grub_uint8_t y) { - char s[11]; /* 5 + 3 + 3. */ - if (! grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_ANSI)) { + char *s; grub_curr_x = x; grub_curr_y = y; - grub_sprintf (s, "\e[%d;%dH", y + 1, x + 1); - grub_ofconsole_writeesc (s); + s = grub_asprintf ("\e[%d;%dH", y + 1, x + 1); + if (s) + grub_ofconsole_writeesc (s); + grub_free (s); } else { diff --git a/term/tparm.c b/term/tparm.c index fa25bd32c..adf0b3a7c 100644 --- a/term/tparm.c +++ b/term/tparm.c @@ -167,7 +167,7 @@ save_text(const char *fmt, const char *s, int len) get_space(s_len + 1); - (void) grub_sprintf(out_buff + out_used, fmt, s); + (void) grub_snprintf(out_buff + out_used, s_len + 1, fmt, s); out_used += grub_strlen(out_buff + out_used); } @@ -179,7 +179,7 @@ save_number(const char *fmt, int number, int len) get_space((unsigned) len + 1); - (void) grub_sprintf(out_buff + out_used, fmt, number); + (void) grub_snprintf(out_buff + out_used, len + 1, fmt, number); out_used += grub_strlen(out_buff + out_used); } diff --git a/util/grub-fstest.c b/util/grub-fstest.c index fa54fe414..d33ecb764 100644 --- a/util/grub-fstest.c +++ b/util/grub-fstest.c @@ -278,18 +278,26 @@ cmd_crc (char *pathname) static void fstest (char **images, int num_disks, int cmd, int n, char **args) { - char host_file[128]; - char loop_name[8]; - char *argv[3] = { "-p", loop_name, host_file}; + char *host_file; + char *loop_name; + char *argv[3] = { "-p" }; int i; for (i = 0; i < num_disks; i++) { - if (grub_strlen (images[i]) + 7 > sizeof (host_file)) - grub_util_error ("Pathname %s too long.", images[i]); + loop_name = grub_asprintf ("loop%d", i); + host_file = grub_asprintf ("(host)%s", images[i]); - grub_sprintf (loop_name, "loop%d", i); - grub_sprintf (host_file, "(host)%s", images[i]); + if (!loop_name || !host_file) + { + grub_free (loop_name); + grub_free (host_file); + grub_util_error (grub_errmsg); + return; + } + + argv[1] = loop_name; + argv[2] = host_file; if (execute_command ("loopback", 3, argv)) grub_util_error ("loopback command fails."); @@ -328,9 +336,19 @@ fstest (char **images, int num_disks, int cmd, int n, char **args) for (i = 0; i < num_disks; i++) { - grub_sprintf (loop_name, "loop%d", i); + grub_free (loop_name); + loop_name = grub_asprintf ("loop%d", i); + if (!loop_name) + { + grub_free (host_file); + grub_util_error (grub_errmsg); + return; + } execute_command ("loopback", 2, argv); } + + grub_free (loop_name); + grub_free (host_file); } static struct option options[] = { From ac0289ba9269f9acc776b0ba7b4ad38134dfcedc Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 29 Dec 2009 11:24:13 +0100 Subject: [PATCH 177/738] grub-mkrescue for EFI (untested) --- conf/common.rmk | 6 ++++++ conf/i386-coreboot.rmk | 7 +------ conf/i386-efi.rmk | 3 +++ conf/i386-ieee1275.rmk | 7 +------ conf/i386-pc.rmk | 7 +------ conf/powerpc-ieee1275.rmk | 6 ------ conf/sparc64-ieee1275.rmk | 6 ------ conf/x86_64-efi.rmk | 3 +++ util/grub-mkrescue.in | 35 ++++++++++++++++++++++++++++++++--- 9 files changed, 47 insertions(+), 33 deletions(-) diff --git a/conf/common.rmk b/conf/common.rmk index 896705526..a961e502a 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -632,3 +632,9 @@ pkglib_MODULES += setjmp.mod setjmp_mod_SOURCES = lib/$(target_cpu)/setjmp.S setjmp_mod_ASFLAGS = $(COMMON_ASFLAGS) setjmp_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For memdisk.mod. +pkglib_MODULES += memdisk.mod +memdisk_mod_SOURCES = disk/memdisk.c +memdisk_mod_CFLAGS = $(COMMON_CFLAGS) +memdisk_mod_LDFLAGS = $(COMMON_LDFLAGS) diff --git a/conf/i386-coreboot.rmk b/conf/i386-coreboot.rmk index ccc326f5c..439e462c5 100644 --- a/conf/i386-coreboot.rmk +++ b/conf/i386-coreboot.rmk @@ -102,7 +102,7 @@ grub_mkrescue_SOURCES = util/grub-mkrescue.in # Modules. pkglib_MODULES = linux.mod multiboot.mod \ aout.mod play.mod serial.mod \ - memdisk.mod pci.mod lspci.mod reboot.mod \ + pci.mod lspci.mod reboot.mod \ halt.mod datetime.mod date.mod datehook.mod \ lsmmap.mod mmap.mod @@ -165,11 +165,6 @@ play_mod_SOURCES = commands/i386/pc/play.c play_mod_CFLAGS = $(COMMON_CFLAGS) play_mod_LDFLAGS = $(COMMON_LDFLAGS) -# For memdisk.mod. -memdisk_mod_SOURCES = disk/memdisk.c -memdisk_mod_CFLAGS = $(COMMON_CFLAGS) -memdisk_mod_LDFLAGS = $(COMMON_LDFLAGS) - # For pci.mod pci_mod_SOURCES = bus/pci.c pci_mod_CFLAGS = $(COMMON_CFLAGS) diff --git a/conf/i386-efi.rmk b/conf/i386-efi.rmk index c135ded4e..e55d7c95a 100644 --- a/conf/i386-efi.rmk +++ b/conf/i386-efi.rmk @@ -15,6 +15,9 @@ grub_mkimage_SOURCES = gnulib/progname.c util/i386/efi/grub-mkimage.c \ util/misc.c util/resolve.c util/i386/efi/grub-mkimage.c_DEPENDENCIES = Makefile +bin_SCRIPTS += grub-mkrescue +grub_mkrescue_SOURCES = util/grub-mkrescue.in + # For grub-setup. #grub_setup_SOURCES = util/i386/pc/grub-setup.c util/hostdisk.c \ # util/misc.c util/getroot.c kern/device.c kern/disk.c \ diff --git a/conf/i386-ieee1275.rmk b/conf/i386-ieee1275.rmk index 8d9577844..78a100c1a 100644 --- a/conf/i386-ieee1275.rmk +++ b/conf/i386-ieee1275.rmk @@ -56,7 +56,7 @@ grub_install_SOURCES = util/ieee1275/grub-install.in # Modules. pkglib_MODULES = halt.mod reboot.mod suspend.mod \ aout.mod serial.mod linux.mod \ - nand.mod memdisk.mod pci.mod lspci.mod datetime.mod \ + nand.mod pci.mod lspci.mod datetime.mod \ date.mod datehook.mod lsmmap.mod mmap.mod # For boot.mod. @@ -106,11 +106,6 @@ nand_mod_SOURCES = disk/ieee1275/nand.c nand_mod_CFLAGS = $(COMMON_CFLAGS) nand_mod_LDFLAGS = $(COMMON_LDFLAGS) -# For memdisk.mod. -memdisk_mod_SOURCES = disk/memdisk.c -memdisk_mod_CFLAGS = $(COMMON_CFLAGS) -memdisk_mod_LDFLAGS = $(COMMON_LDFLAGS) - # For pci.mod pci_mod_SOURCES = bus/pci.c pci_mod_CFLAGS = $(COMMON_CFLAGS) diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk index 7e54b3b67..b682aad94 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -121,7 +121,7 @@ grub_mkfloppy_SOURCES = util/i386/pc/grub-mkfloppy.in pkglib_MODULES = biosdisk.mod chain.mod \ multiboot.mod reboot.mod halt.mod \ vbe.mod vbetest.mod vbeinfo.mod play.mod serial.mod \ - vga.mod memdisk.mod pci.mod lspci.mod \ + vga.mod pci.mod lspci.mod \ aout.mod bsd.mod pxe.mod pxecmd.mod datetime.mod date.mod \ datehook.mod lsmmap.mod ata_pthru.mod hdparm.mod \ usb.mod uhci.mod ohci.mod usbtest.mod usbms.mod usb_keyboard.mod \ @@ -239,11 +239,6 @@ vga_mod_SOURCES = term/i386/pc/vga.c vga_mod_CFLAGS = $(COMMON_CFLAGS) vga_mod_LDFLAGS = $(COMMON_LDFLAGS) -# For memdisk.mod. -memdisk_mod_SOURCES = disk/memdisk.c -memdisk_mod_CFLAGS = $(COMMON_CFLAGS) -memdisk_mod_LDFLAGS = $(COMMON_LDFLAGS) - # For pci.mod pci_mod_SOURCES = bus/pci.c pci_mod_CFLAGS = $(COMMON_CFLAGS) diff --git a/conf/powerpc-ieee1275.rmk b/conf/powerpc-ieee1275.rmk index 85b1fa211..0b5b03c5d 100644 --- a/conf/powerpc-ieee1275.rmk +++ b/conf/powerpc-ieee1275.rmk @@ -62,7 +62,6 @@ pkglib_MODULES = halt.mod \ reboot.mod \ suspend.mod \ multiboot.mod \ - memdisk.mod \ lsmmap.mod # For boot.mod. @@ -98,11 +97,6 @@ multiboot_mod_SOURCES = loader/ieee1275/multiboot2.c \ multiboot_mod_CFLAGS = $(COMMON_CFLAGS) multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS) -# For memdisk.mod. -memdisk_mod_SOURCES = disk/memdisk.c -memdisk_mod_CFLAGS = $(COMMON_CFLAGS) -memdisk_mod_LDFLAGS = $(COMMON_LDFLAGS) - # For lsmmap.mod lsmmap_mod_SOURCES = commands/lsmmap.c lsmmap_mod_CFLAGS = $(COMMON_CFLAGS) diff --git a/conf/sparc64-ieee1275.rmk b/conf/sparc64-ieee1275.rmk index 8c8bf27e6..dc845e1a5 100644 --- a/conf/sparc64-ieee1275.rmk +++ b/conf/sparc64-ieee1275.rmk @@ -99,7 +99,6 @@ grub_install_SOURCES = util/sparc64/ieee1275/grub-install.in pkglib_MODULES = halt.mod \ linux.mod \ reboot.mod \ - memdisk.mod \ lsmmap.mod # For boot.mod. @@ -123,11 +122,6 @@ halt_mod_SOURCES = commands/halt.c halt_mod_CFLAGS = $(COMMON_CFLAGS) halt_mod_LDFLAGS = $(COMMON_LDFLAGS) -# For memdisk.mod. -memdisk_mod_SOURCES = disk/memdisk.c -memdisk_mod_CFLAGS = $(COMMON_CFLAGS) -memdisk_mod_LDFLAGS = $(COMMON_LDFLAGS) - # For lsmmap.mod lsmmap_mod_SOURCES = commands/lsmmap.c lsmmap_mod_CFLAGS = $(COMMON_CFLAGS) diff --git a/conf/x86_64-efi.rmk b/conf/x86_64-efi.rmk index 22ed2d639..2de6ab443 100644 --- a/conf/x86_64-efi.rmk +++ b/conf/x86_64-efi.rmk @@ -14,6 +14,9 @@ bin_UTILITIES = grub-mkimage grub_mkimage_SOURCES = gnulib/progname.c util/i386/efi/grub-mkimage.c \ util/misc.c util/resolve.c +bin_SCRIPTS += grub-mkrescue +grub_mkrescue_SOURCES = util/grub-mkrescue.in + # For grub-setup. #grub_setup_SOURCES = util/i386/pc/grub-setup.c util/hostdisk.c \ # util/misc.c util/getroot.c kern/device.c kern/disk.c \ diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in index 51639ccb1..30f319dc3 100644 --- a/util/grub-mkrescue.in +++ b/util/grub-mkrescue.in @@ -31,6 +31,8 @@ native_platform=@platform@ coreboot_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/${target_cpu}-coreboot pc_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/${target_cpu}-pc +efi32_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/i386-efi +efi64_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/x86_64-efi # Usage: usage # Print the usage. @@ -109,13 +111,23 @@ if [ "${override_dir}" = "" ] ; then if test -e "${pc_dir}" ; then process_input_dir ${pc_dir} pc fi + if test -e "${efi32_dir}" ; then + process_input_dir ${efi32_dir} efi32 + fi + if test -e "${efi64_dir}" ; then + process_input_dir ${efi64_dir} efi64 + fi else process_input_dir ${override_dir} ${native_platform} coreboot_dir= pc_dir= - case "${native_platform}" in - coreboot) coreboot_dir=${override_dir} ;; - pc) pc_dir=${override_dir} ;; + efi32_dir= + efi64_dir= + case "${target_cpu}-${native_platform}" in + i386-coreboot) coreboot_dir=${override_dir} ;; + i386-pc) pc_dir=${override_dir} ;; + i386-efi) efi32_dir=${override_dir} ;; + x86_64-efi) efi64_dir=${override_dir} ;; esac fi @@ -168,6 +180,23 @@ if test -e "${pc_dir}" ; then grub_mkisofs_arguments="${grub_mkisofs_arguments} -b boot/grub/i386-pc/eltorito.img -boot-info-table" fi +# build bootx64.efi +if test -e "${efi64_dir}" ; then + echo "Generates bootx64.efi" + mkdir -p ${iso9660_dir}/efi/boot + grub-mkimage -d ${efi64_dir}/ -o ${iso9660_dir}/efi/boot/bootx64.efi --prefix=/boot/grub/x86_64-efi \ + search iso9660 configfile sh + + modules="$(cat ${efi64_dir}/partmap.lst) ${modules}" + (for i in ${modules} ; do + if [ "x$i" != xkernel.mod ]; then + echo "insmod $i" + fi + done ; \ + echo "source /boot/grub/grub.cfg") \ + > ${iso9660_dir}/boot/grub/x86_64-efi/grub.cfg +fi + # build iso image grub-mkisofs ${grub_mkisofs_arguments} -o ${output_image} -r ${iso9660_dir} ${source} rm -rf ${iso9660_dir} From 9a17588459f2bc876c7b3f4c9d86b0489ca1bc5b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 29 Dec 2009 17:31:02 +0100 Subject: [PATCH 178/738] Initial support for scalable gfxmenu --- gfxmenu/gui_box.c | 232 +++++++++++++++++++------------- gfxmenu/gui_canvas.c | 120 ++++++++--------- gfxmenu/gui_circular_progress.c | 52 +------ gfxmenu/gui_image.c | 38 +----- gfxmenu/gui_label.c | 36 +---- gfxmenu/gui_list.c | 64 +++------ gfxmenu/gui_progress_bar.c | 48 +------ gfxmenu/gui_string_util.c | 38 ------ gfxmenu/theme_loader.c | 104 ++++++++------ gfxmenu/view.c | 4 +- include/grub/gui.h | 59 +++++++- include/grub/gui_string_util.h | 2 - include/grub/video.h | 8 +- 13 files changed, 368 insertions(+), 437 deletions(-) diff --git a/gfxmenu/gui_box.c b/gfxmenu/gui_box.c index 4fe131f98..45028e5b1 100644 --- a/gfxmenu/gui_box.c +++ b/gfxmenu/gui_box.c @@ -32,17 +32,16 @@ struct component_node typedef struct grub_gui_box *grub_gui_box_t; typedef void (*layout_func_t) (grub_gui_box_t self, int modify_layout, - int *width, int *height); + unsigned *minimal_width, + unsigned *minimal_height); struct grub_gui_box { - struct grub_gui_container_ops *container; + struct grub_gui_container container; grub_gui_container_t parent; grub_video_rect_t bounds; char *id; - int preferred_width; - int preferred_height; /* Doubly linked list of components with dummy head & tail nodes. */ struct component_node chead; @@ -87,82 +86,158 @@ box_is_instance (void *vself __attribute__((unused)), const char *type) static void layout_horizontally (grub_gui_box_t self, int modify_layout, - int *width, int *height) + unsigned *min_width, unsigned *min_height) { /* Start at the left (chead) and set the x coordinates as we go right. */ /* All components have their width set to the box's width. */ struct component_node *cur; - int x = 0; - if (height) - *height = 0; + unsigned w = 0, mwfrac = 0, h = 0, x = 0; + grub_fixed_unsigned_t wfrac = 0; + int bogus_frac = 0; + for (cur = self->chead.next; cur != &self->ctail; cur = cur->next) { grub_gui_component_t c = cur->component; + unsigned mw = 0, mh = 0; + + if (c->ops->get_minimal_size) + c->ops->get_minimal_size (c, &mw, &mh); + + if (!c->ishfrac && c->h > h) + h = c->h; + if (mh > h) + h = mh; + if (!c->iswfrac) + w += mw > c->w ? mw : c->w; + if (c->iswfrac) + { + wfrac += c->wfrac; + mwfrac += mw; + } + } + if (wfrac > GRUB_FIXED_1 || (w > 0 && wfrac == GRUB_FIXED_1)) + bogus_frac = 1; + + if (min_width) + { + if (wfrac < GRUB_FIXED_1) + *min_width = grub_fixed_ufu_divide (w, GRUB_FIXED_1 - wfrac); + else + *min_width = w; + if (*min_width < w + mwfrac) + *min_width = w + mwfrac; + } + if (min_height) + *min_height = h; + + if (!modify_layout) + return; + + for (cur = self->chead.next; cur != &self->ctail; cur = cur->next) + { grub_video_rect_t r; + grub_gui_component_t c = cur->component; + unsigned mw = 0, mh = 0; - c->ops->get_preferred_size (c, &r.width, &r.height); + r.x = x; + r.y = 0; + r.width = 32; + r.height = h; - /* Check and possibly update the maximum width, if non-null. */ - if (height && r.height > *height) - *height = r.height; + if (c->ops->get_minimal_size) + c->ops->get_minimal_size (c, &mw, &mh); - /* Set the component's bounds, if the flag is set. */ - if (modify_layout) - { - r.x = x; - r.y = 0; - /* Width comes from the component's preferred size. */ - r.height = self->bounds.height; - c->ops->set_bounds (c, &r); - } + if (!c->iswfrac) + r.width = c->w; + if (c->iswfrac && !bogus_frac) + r.width = grub_fixed_ufu_multiply (self->bounds.width, c->wfrac); + + if (r.width < mw) + r.width = mw; + + c->ops->set_bounds (c, &r); x += r.width; } - - /* Return the sum of the children's preferred widths. */ - if (width) - *width = x; } static void layout_vertically (grub_gui_box_t self, int modify_layout, - int *width, int *height) + unsigned *min_width, unsigned *min_height) { - /* Start at the top (chead) and set the y coordinates as we go down. */ - /* All components have their width set to the vbox's width. */ + /* Start at the top (chead) and set the y coordinates as we go rdown. */ + /* All components have their height set to the box's height. */ struct component_node *cur; - int y = 0; - if (width) - *width = 0; + unsigned h = 0, mhfrac = 0, w = 0, y = 0; + grub_fixed_unsigned_t hfrac = 0; + int bogus_frac = 0; + for (cur = self->chead.next; cur != &self->ctail; cur = cur->next) { grub_gui_component_t c = cur->component; + unsigned mw = 0, mh = 0; + + if (c->ops->get_minimal_size) + c->ops->get_minimal_size (c, &mw, &mh); + + if (!c->iswfrac && c->w > w) + w = c->w; + if (mw > w) + w = mw; + if (!c->ishfrac) + h += mh > c->h ? mh : c->h; + if (c->ishfrac) + { + hfrac += c->hfrac; + mhfrac += mh; + } + } + if (hfrac > GRUB_FIXED_1 || (h > 0 && hfrac == GRUB_FIXED_1)) + bogus_frac = 1; + + if (min_height) + { + if (hfrac < GRUB_FIXED_1) + *min_height = grub_fixed_ufu_divide (h, GRUB_FIXED_1 - hfrac); + else + *min_height = h; + if (*min_height < h + mhfrac) + *min_height = h + mhfrac; + } + if (min_width) + *min_width = w; + + if (!modify_layout) + return; + + for (cur = self->chead.next; cur != &self->ctail; cur = cur->next) + { grub_video_rect_t r; + grub_gui_component_t c = cur->component; + unsigned mw = 0, mh = 0; - c->ops->get_preferred_size (c, &r.width, &r.height); + r.x = 0; + r.y = y; + r.width = w; + r.height = 32; - /* Check and possibly update the maximum width, if non-null. */ - if (width && r.width > *width) - *width = r.width; + if (c->ops->get_minimal_size) + c->ops->get_minimal_size (c, &mw, &mh); - /* Set the component's bounds, if the flag is set. */ - if (modify_layout) - { - r.x = 0; - r.y = y; - r.width = self->bounds.width; - /* Height comes from the component's preferred size. */ - c->ops->set_bounds (c, &r); - } + if (!c->ishfrac) + r.height = c->h; + if (c->ishfrac) + r.height = grub_fixed_ufu_multiply (self->bounds.height, c->hfrac); + + if (r.height < mh) + r.height = mh; + + c->ops->set_bounds (c, &r); y += r.height; } - - /* Return the sum of the children's preferred heights. */ - if (height) - *height = y; } static void @@ -213,16 +288,10 @@ box_get_bounds (void *vself, grub_video_rect_t *bounds) /* The box's preferred size is based on the preferred sizes of its children. */ static void -box_get_preferred_size (void *vself, int *width, int *height) +box_get_minimal_size (void *vself, unsigned *width, unsigned *height) { grub_gui_box_t self = vself; self->layout_func (self, 0, width, height); /* Just calculate the size. */ - - /* Allow preferred dimensions to override the computed dimensions. */ - if (self->preferred_width >= 0) - *width = self->preferred_width; - if (self->preferred_height >= 0) - *height = self->preferred_height; } static grub_err_t @@ -241,15 +310,6 @@ box_set_property (void *vself, const char *name, const char *value) else self->id = 0; } - else if (grub_strcmp (name, "preferred_size") == 0) - { - int w; - int h; - if (grub_gui_parse_2_tuple (value, &w, &h) != GRUB_ERR_NONE) - return grub_errno; - self->preferred_width = w; - self->preferred_height = h; - } return grub_errno; } @@ -303,21 +363,22 @@ box_iterate_children (void *vself, cb (cur->component, userdata); } +static struct grub_gui_component_ops box_comp_ops = + { + .destroy = box_destroy, + .get_id = box_get_id, + .is_instance = box_is_instance, + .paint = box_paint, + .set_parent = box_set_parent, + .get_parent = box_get_parent, + .set_bounds = box_set_bounds, + .get_bounds = box_get_bounds, + .get_minimal_size = box_get_minimal_size, + .set_property = box_set_property + }; + static struct grub_gui_container_ops box_ops = { - .component = - { - .destroy = box_destroy, - .get_id = box_get_id, - .is_instance = box_is_instance, - .paint = box_paint, - .set_parent = box_set_parent, - .get_parent = box_get_parent, - .set_bounds = box_set_bounds, - .get_bounds = box_get_bounds, - .get_preferred_size = box_get_preferred_size, - .set_property = box_set_property - }, .add = box_add, .remove = box_remove, .iterate_children = box_iterate_children @@ -329,24 +390,13 @@ static grub_gui_box_t box_new (layout_func_t layout_func) { grub_gui_box_t box; - box = grub_malloc (sizeof (*box)); + box = grub_zalloc (sizeof (*box)); if (! box) return 0; - box->container = &box_ops; - box->parent = 0; - box->bounds.x = 0; - box->bounds.y = 0; - box->bounds.width = 0; - box->bounds.height = 0; - box->id = 0; - box->preferred_width = -1; - box->preferred_height = -1; - box->chead.component = 0; - box->chead.prev = 0; + box->container.ops = &box_ops; + box->container.component.ops = &box_comp_ops; box->chead.next = &box->ctail; - box->ctail.component = 0; box->ctail.prev = &box->chead; - box->ctail.next = 0; box->layout_func = layout_func; return box; } diff --git a/gfxmenu/gui_canvas.c b/gfxmenu/gui_canvas.c index d155364d7..8b55b2a73 100644 --- a/gfxmenu/gui_canvas.c +++ b/gfxmenu/gui_canvas.c @@ -32,13 +32,11 @@ struct component_node struct grub_gui_canvas { - struct grub_gui_container_ops *container; + struct grub_gui_container container; grub_gui_container_t parent; grub_video_rect_t bounds; char *id; - int preferred_width; - int preferred_height; /* Component list (dummy head node). */ struct component_node components; }; @@ -88,22 +86,52 @@ canvas_paint (void *vself, const grub_video_rect_t *region) grub_gui_set_viewport (&self->bounds, &vpsave); for (cur = self->components.next; cur; cur = cur->next) { - int pw; - int ph; grub_video_rect_t r; grub_gui_component_t comp; comp = cur->component; - /* Give the child its preferred size. */ - comp->ops->get_preferred_size (comp, &pw, &ph); - comp->ops->get_bounds (comp, &r); - if (r.width != pw || r.height != ph) - { - r.width = pw; - r.height = ph; - comp->ops->set_bounds (comp, &r); - } + r.x = 0; + r.y = 0; + r.width = 32; + r.height = 32; + + if (!comp->iswfrac && comp->w) + r.width = comp->w; + + if (!comp->ishfrac && comp->h) + r.height = comp->h; + + if (!comp->isxfrac && comp->x) + r.x = comp->x; + + if (!comp->isyfrac && comp->y) + r.y = comp->y; + + if (comp->ishfrac && comp->hfrac) + r.height = grub_fixed_ufu_multiply (self->bounds.height, comp->hfrac); + + if (comp->iswfrac && comp->wfrac) + r.width = grub_fixed_ufu_multiply (self->bounds.width, comp->wfrac); + + if (comp->isxfrac && comp->xfrac) + r.x = grub_fixed_ufu_multiply (self->bounds.width, comp->xfrac); + + if (comp->isyfrac && comp->yfrac) + r.y = grub_fixed_ufu_multiply (self->bounds.height, comp->yfrac); + + if (comp->ops->get_minimal_size) + { + unsigned mw; + unsigned mh; + comp->ops->get_minimal_size (comp, &mw, &mh); + if (r.width < mw) + r.width = mw; + if (r.height < mh) + r.height = mh; + } + + comp->ops->set_bounds (comp, &r); /* Paint the child. */ if (grub_video_have_common_points (region, &r)) @@ -140,20 +168,6 @@ canvas_get_bounds (void *vself, grub_video_rect_t *bounds) *bounds = self->bounds; } -static void -canvas_get_preferred_size (void *vself, int *width, int *height) -{ - grub_gui_canvas_t self = vself; - *width = 0; - *height = 0; - - /* Allow preferred dimensions to override the empty dimensions. */ - if (self->preferred_width >= 0) - *width = self->preferred_width; - if (self->preferred_height >= 0) - *height = self->preferred_height; -} - static grub_err_t canvas_set_property (void *vself, const char *name, const char *value) { @@ -170,15 +184,6 @@ canvas_set_property (void *vself, const char *name, const char *value) else self->id = 0; } - else if (grub_strcmp (name, "preferred_size") == 0) - { - int w; - int h; - if (grub_gui_parse_2_tuple (value, &w, &h) != GRUB_ERR_NONE) - return grub_errno; - self->preferred_width = w; - self->preferred_height = h; - } return grub_errno; } @@ -227,21 +232,21 @@ canvas_iterate_children (void *vself, cb (cur->component, userdata); } +static struct grub_gui_component_ops canvas_comp_ops = +{ + .destroy = canvas_destroy, + .get_id = canvas_get_id, + .is_instance = canvas_is_instance, + .paint = canvas_paint, + .set_parent = canvas_set_parent, + .get_parent = canvas_get_parent, + .set_bounds = canvas_set_bounds, + .get_bounds = canvas_get_bounds, + .set_property = canvas_set_property +}; + static struct grub_gui_container_ops canvas_ops = { - .component = - { - .destroy = canvas_destroy, - .get_id = canvas_get_id, - .is_instance = canvas_is_instance, - .paint = canvas_paint, - .set_parent = canvas_set_parent, - .get_parent = canvas_get_parent, - .set_bounds = canvas_set_bounds, - .get_bounds = canvas_get_bounds, - .get_preferred_size = canvas_get_preferred_size, - .set_property = canvas_set_property - }, .add = canvas_add, .remove = canvas_remove, .iterate_children = canvas_iterate_children @@ -251,19 +256,10 @@ grub_gui_container_t grub_gui_canvas_new (void) { grub_gui_canvas_t canvas; - canvas = grub_malloc (sizeof (*canvas)); + canvas = grub_zalloc (sizeof (*canvas)); if (! canvas) return 0; - canvas->container = &canvas_ops; - canvas->parent = 0; - canvas->bounds.x = 0; - canvas->bounds.y = 0; - canvas->bounds.width = 0; - canvas->bounds.height = 0; - canvas->id = 0; - canvas->preferred_width = -1; - canvas->preferred_height = -1; - canvas->components.component = 0; - canvas->components.next = 0; + canvas->container.ops = &canvas_ops; + canvas->container.component.ops = &canvas_comp_ops; return (grub_gui_container_t) canvas; } diff --git a/gfxmenu/gui_circular_progress.c b/gfxmenu/gui_circular_progress.c index f3c8bc3af..e57d1c236 100644 --- a/gfxmenu/gui_circular_progress.c +++ b/gfxmenu/gui_circular_progress.c @@ -28,13 +28,11 @@ struct grub_gui_circular_progress { - struct grub_gui_component_ops *circprog_ops; + struct grub_gui_component comp; grub_gui_container_t parent; grub_video_rect_t bounds; char *id; - int preferred_width; - int preferred_height; int visible; int start; int end; @@ -209,21 +207,6 @@ circprog_get_bounds (void *vself, grub_video_rect_t *bounds) *bounds = self->bounds; } -static void -circprog_get_preferred_size (void *vself, int *width, int *height) -{ - circular_progress_t self = vself; - - *width = 0; - *height = 0; - - /* Allow preferred dimensions to override the circprog dimensions. */ - if (self->preferred_width >= 0) - *width = self->preferred_width; - if (self->preferred_height >= 0) - *height = self->preferred_height; -} - static grub_err_t circprog_set_property (void *vself, const char *name, const char *value) { @@ -270,15 +253,6 @@ circprog_set_property (void *vself, const char *name, const char *value) grub_free (self->theme_dir); self->theme_dir = value ? grub_strdup (value) : 0; } - else if (grub_strcmp (name, "preferred_size") == 0) - { - int w; - int h; - if (grub_gui_parse_2_tuple (value, &w, &h) != GRUB_ERR_NONE) - return grub_errno; - self->preferred_width = w; - self->preferred_height = h; - } else if (grub_strcmp (name, "visible") == 0) { self->visible = grub_strcmp (value, "false") != 0; @@ -304,7 +278,6 @@ static struct grub_gui_component_ops circprog_ops = .get_parent = circprog_get_parent, .set_bounds = circprog_set_bounds, .get_bounds = circprog_get_bounds, - .get_preferred_size = circprog_get_preferred_size, .set_property = circprog_set_property }; @@ -312,32 +285,13 @@ grub_gui_component_t grub_gui_circular_progress_new (void) { circular_progress_t self; - self = grub_malloc (sizeof (*self)); + self = grub_zalloc (sizeof (*self)); if (! self) return 0; - self->circprog_ops = &circprog_ops; - self->parent = 0; - self->bounds.x = 0; - self->bounds.y = 0; - self->bounds.width = 0; - self->bounds.height = 0; - self->id = 0; - self->preferred_width = -1; - self->preferred_height = -1; + self->comp.ops = &circprog_ops; self->visible = 1; - self->start = 0; - self->end = 0; - self->value = 0; self->num_ticks = 64; self->start_angle = -64; - self->ticks_disappear = 0; - - self->theme_dir = 0; - self->need_to_load_pixmaps = 0; - self->center_file = 0; - self->tick_file = 0; - self->center_bitmap = 0; - self->tick_bitmap = 0; return (grub_gui_component_t) self; } diff --git a/gfxmenu/gui_image.c b/gfxmenu/gui_image.c index eb2ff1ee0..ef8bcbe9a 100644 --- a/gfxmenu/gui_image.c +++ b/gfxmenu/gui_image.c @@ -26,13 +26,11 @@ struct grub_gui_image { - struct grub_gui_component_ops *image; + struct grub_gui_component component; grub_gui_container_t parent; grub_video_rect_t bounds; char *id; - int preferred_width; - int preferred_height; struct grub_video_bitmap *raw_bitmap; struct grub_video_bitmap *bitmap; }; @@ -172,8 +170,9 @@ image_get_bounds (void *vself, grub_video_rect_t *bounds) *bounds = self->bounds; } +/* FIXME: inform rendering system it's not forced minimum. */ static void -image_get_preferred_size (void *vself, int *width, int *height) +image_get_minimal_size (void *vself, unsigned *width, unsigned *height) { grub_gui_image_t self = vself; @@ -187,12 +186,6 @@ image_get_preferred_size (void *vself, int *width, int *height) *width = 0; *height = 0; } - - /* Allow preferred dimensions to override the image dimensions. */ - if (self->preferred_width >= 0) - *width = self->preferred_width; - if (self->preferred_height >= 0) - *height = self->preferred_height; } static grub_err_t @@ -217,15 +210,6 @@ image_set_property (void *vself, const char *name, const char *value) grub_gui_image_t self = vself; if (grub_strcmp (name, "file") == 0) return load_image (self, value); - else if (grub_strcmp (name, "preferred_size") == 0) - { - int w; - int h; - if (grub_gui_parse_2_tuple (value, &w, &h) != GRUB_ERR_NONE) - return grub_errno; - self->preferred_width = w; - self->preferred_height = h; - } else if (grub_strcmp (name, "id") == 0) { grub_free (self->id); @@ -247,7 +231,7 @@ static struct grub_gui_component_ops image_ops = .get_parent = image_get_parent, .set_bounds = image_set_bounds, .get_bounds = image_get_bounds, - .get_preferred_size = image_get_preferred_size, + .get_minimal_size = image_get_minimal_size, .set_property = image_set_property }; @@ -255,20 +239,10 @@ grub_gui_component_t grub_gui_image_new (void) { grub_gui_image_t image; - image = grub_malloc (sizeof (*image)); + image = grub_zalloc (sizeof (*image)); if (! image) return 0; - image->image = &image_ops; - image->parent = 0; - image->bounds.x = 0; - image->bounds.y = 0; - image->bounds.width = 0; - image->bounds.height = 0; - image->id = 0; - image->preferred_width = -1; - image->preferred_height = -1; - image->raw_bitmap = 0; - image->bitmap = 0; + image->component.ops = &image_ops; return (grub_gui_component_t) image; } diff --git a/gfxmenu/gui_label.c b/gfxmenu/gui_label.c index 30474f52f..b2835ea1a 100644 --- a/gfxmenu/gui_label.c +++ b/gfxmenu/gui_label.c @@ -39,13 +39,11 @@ enum align_mode { struct grub_gui_label { - struct grub_gui_component_ops *label; + struct grub_gui_component comp; grub_gui_container_t parent; grub_video_rect_t bounds; char *id; - int preferred_width; - int preferred_height; int visible; char *text; grub_font_t font; @@ -140,18 +138,12 @@ label_get_bounds (void *vself, grub_video_rect_t *bounds) } static void -label_get_preferred_size (void *vself, int *width, int *height) +label_get_minimal_size (void *vself, unsigned *width, unsigned *height) { grub_gui_label_t self = vself; *width = grub_font_get_string_width (self->font, self->text); *height = (grub_font_get_ascent (self->font) + grub_font_get_descent (self->font)); - - /* Allow preferred dimensions to override the computed dimensions. */ - if (self->preferred_width >= 0) - *width = self->preferred_width; - if (self->preferred_height >= 0) - *height = self->preferred_height; } static grub_err_t @@ -189,16 +181,6 @@ label_set_property (void *vself, const char *name, const char *value) { self->visible = grub_strcmp (value, "false") != 0; } - else if (grub_strcmp (name, "preferred_size") == 0) - { - int w; - int h; - if (grub_gui_parse_2_tuple (value, &w, &h) == GRUB_ERR_NONE) - { - self->preferred_width = w; - self->preferred_height = h; - } - } else if (grub_strcmp (name, "id") == 0) { grub_free (self->id); @@ -220,7 +202,7 @@ static struct grub_gui_component_ops label_ops = .get_parent = label_get_parent, .set_bounds = label_set_bounds, .get_bounds = label_get_bounds, - .get_preferred_size = label_get_preferred_size, + .get_minimal_size = label_get_minimal_size, .set_property = label_set_property }; @@ -228,18 +210,10 @@ grub_gui_component_t grub_gui_label_new (void) { grub_gui_label_t label; - label = grub_malloc (sizeof (*label)); + label = grub_zalloc (sizeof (*label)); if (! label) return 0; - label->label = &label_ops; - label->parent = 0; - label->bounds.x = 0; - label->bounds.y = 0; - label->bounds.width = 0; - label->bounds.height = 0; - label->id = 0; - label->preferred_width = -1; - label->preferred_height = -1; + label->comp.ops = &label_ops; label->visible = 1; label->text = grub_strdup (""); label->font = grub_font_get ("Helvetica 10"); diff --git a/gfxmenu/gui_list.c b/gfxmenu/gui_list.c index bf6d94657..c55cfd85c 100644 --- a/gfxmenu/gui_list.c +++ b/gfxmenu/gui_list.c @@ -26,13 +26,11 @@ struct grub_gui_list_impl { - struct grub_gui_list_ops *list_ops; + struct grub_gui_list list; grub_gui_container_t parent; grub_video_rect_t bounds; char *id; - int preferred_width; - int preferred_height; int visible; int icon_width; @@ -357,7 +355,7 @@ list_get_bounds (void *vself, grub_video_rect_t *bounds) } static void -list_get_preferred_size (void *vself, int *width, int *height) +list_get_minimal_size (void *vself, unsigned *width, unsigned *height) { list_impl_t self = vself; @@ -387,12 +385,6 @@ list_get_preferred_size (void *vself, int *width, int *height) *width = 0; *height = 0; } - - /* Allow preferred dimensions to override the computed dimensions. */ - if (self->preferred_width >= 0) - *width = self->preferred_width; - if (self->preferred_height >= 0) - *height = self->preferred_height; } static grub_err_t @@ -507,15 +499,6 @@ list_set_property (void *vself, const char *name, const char *value) grub_free (self->theme_dir); self->theme_dir = value ? grub_strdup (value) : 0; } - else if (grub_strcmp (name, "preferred_size") == 0) - { - int w; - int h; - if (grub_gui_parse_2_tuple (value, &w, &h) != GRUB_ERR_NONE) - return grub_errno; - self->preferred_width = w; - self->preferred_height = h; - } else if (grub_strcmp (name, "id") == 0) { grub_free (self->id); @@ -538,21 +521,22 @@ list_set_view_info (void *vself, self->menu = menu; } +static struct grub_gui_component_ops list_comp_ops = + { + .destroy = list_destroy, + .get_id = list_get_id, + .is_instance = list_is_instance, + .paint = list_paint, + .set_parent = list_set_parent, + .get_parent = list_get_parent, + .set_bounds = list_set_bounds, + .get_bounds = list_get_bounds, + .get_minimal_size = list_get_minimal_size, + .set_property = list_set_property + }; + static struct grub_gui_list_ops list_ops = { - .component_ops = - { - .destroy = list_destroy, - .get_id = list_get_id, - .is_instance = list_is_instance, - .paint = list_paint, - .set_parent = list_set_parent, - .get_parent = list_get_parent, - .set_bounds = list_set_bounds, - .get_bounds = list_get_bounds, - .get_preferred_size = list_get_preferred_size, - .set_property = list_set_property - }, .set_view_info = list_set_view_info }; @@ -564,19 +548,13 @@ grub_gui_list_new (void) grub_gui_color_t default_fg_color; grub_gui_color_t default_bg_color; - self = grub_malloc (sizeof (*self)); + self = grub_zalloc (sizeof (*self)); if (! self) return 0; - self->list_ops = &list_ops; - self->parent = 0; - self->bounds.x = 0; - self->bounds.y = 0; - self->bounds.width = 0; - self->bounds.height = 0; - self->id = 0; - self->preferred_width = -1; - self->preferred_height = -1; + self->list.ops = &list_ops; + self->list.component.ops = &list_comp_ops; + self->visible = 1; default_font = grub_font_get ("Helvetica 12"); @@ -617,7 +595,7 @@ grub_gui_list_new (void) self->icon_manager = grub_gfxmenu_icon_manager_new (); if (! self->icon_manager) { - self->list_ops->component_ops.destroy (self); + self->list.component.ops->destroy (self); return 0; } grub_gfxmenu_icon_manager_set_icon_size (self->icon_manager, diff --git a/gfxmenu/gui_progress_bar.c b/gfxmenu/gui_progress_bar.c index 498711169..9af93cff5 100644 --- a/gfxmenu/gui_progress_bar.c +++ b/gfxmenu/gui_progress_bar.c @@ -27,13 +27,11 @@ struct grub_gui_progress_bar { - struct grub_gui_component_ops *progress_bar; + struct grub_gui_component component; grub_gui_container_t parent; grub_video_rect_t bounds; char *id; - int preferred_width; - int preferred_height; int visible; int start; int end; @@ -221,18 +219,11 @@ progress_bar_get_bounds (void *vself, grub_video_rect_t *bounds) } static void -progress_bar_get_preferred_size (void *vself, int *width, int *height) +progress_bar_get_minimal_size (void *vself __attribute__ ((unused)), + unsigned *width, unsigned *height) { - grub_gui_progress_bar_t self = vself; - *width = 200; *height = 28; - - /* Allow preferred dimensions to override the progress_bar dimensions. */ - if (self->preferred_width >= 0) - *width = self->preferred_width; - if (self->preferred_height >= 0) - *height = self->preferred_height; } static grub_err_t @@ -296,15 +287,6 @@ progress_bar_set_property (void *vself, const char *name, const char *value) grub_free (self->theme_dir); self->theme_dir = value ? grub_strdup (value) : 0; } - else if (grub_strcmp (name, "preferred_size") == 0) - { - int w; - int h; - if (grub_gui_parse_2_tuple (value, &w, &h) != GRUB_ERR_NONE) - return grub_errno; - self->preferred_width = w; - self->preferred_height = h; - } else if (grub_strcmp (name, "visible") == 0) { self->visible = grub_strcmp (value, "false") != 0; @@ -334,7 +316,7 @@ static struct grub_gui_component_ops progress_bar_ops = .get_parent = progress_bar_get_parent, .set_bounds = progress_bar_set_bounds, .get_bounds = progress_bar_get_bounds, - .get_preferred_size = progress_bar_get_preferred_size, + .get_minimal_size = progress_bar_get_minimal_size, .set_property = progress_bar_set_property }; @@ -342,22 +324,11 @@ grub_gui_component_t grub_gui_progress_bar_new (void) { grub_gui_progress_bar_t self; - self = grub_malloc (sizeof (*self)); + self = grub_zalloc (sizeof (*self)); if (! self) return 0; - self->progress_bar = &progress_bar_ops; - self->parent = 0; - self->bounds.x = 0; - self->bounds.y = 0; - self->bounds.width = 0; - self->bounds.height = 0; - self->id = 0; - self->preferred_width = -1; - self->preferred_height = -1; + self->component.ops = &progress_bar_ops; self->visible = 1; - self->start = 0; - self->end = 0; - self->value = 0; self->show_text = 1; self->text = grub_strdup (""); self->font = grub_font_get ("Helvetica 10"); @@ -369,12 +340,5 @@ grub_gui_progress_bar_new (void) self->bg_color = gray; self->fg_color = lightgray; - self->theme_dir = 0; - self->need_to_recreate_pixmaps = 0; - self->bar_pattern = 0; - self->highlight_pattern = 0; - self->bar_box = 0; - self->highlight_box = 0; - return (grub_gui_component_t) self; } diff --git a/gfxmenu/gui_string_util.c b/gfxmenu/gui_string_util.c index 8ea7c497b..8c51e396a 100644 --- a/gfxmenu/gui_string_util.c +++ b/gfxmenu/gui_string_util.c @@ -325,41 +325,3 @@ grub_gui_parse_color (const char *s, grub_gui_color_t *color) *color = c; return grub_errno; } - -/* Parse a value in the form "(x, y)", storing the first element (x) into - *PX and the second element (y) into *PY. - Returns GRUB_ERR_NONE if successfully parsed. */ -grub_err_t -grub_gui_parse_2_tuple (const char *s, int *px, int *py) -{ - int x; - int y; - - while (*s && grub_isspace (*s)) - s++; - if (*s != '(') - return grub_error (GRUB_ERR_BAD_ARGUMENT, - "missing `(' in 2-tuple `%s'", s); - - /* Skip the opening parentheses. */ - s++; - if (*s == 0) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - "unexpected end of 2-tuple after `(' in `%s'", s); - - /* Parse the first element. */ - x = grub_strtol (s, 0, 10); - if ((s = grub_strchr (s, ',')) == 0) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - "missing comma in 2-tuple `%s'", s); - - /* Skip the element separator (the comma). */ - s++; - /* Parse the second element. */ - y = grub_strtol (s, 0, 10); - - *px = x; - *py = y; - - return grub_errno; -} diff --git a/gfxmenu/theme_loader.c b/gfxmenu/theme_loader.c index 3512c7bf1..29bc1d2a6 100644 --- a/gfxmenu/theme_loader.c +++ b/gfxmenu/theme_loader.c @@ -510,35 +510,73 @@ read_object (struct parsebuf *p, grub_gui_container_t parent) } /* Handle the property value. */ - if (grub_strcmp (property, "position") == 0) + if (grub_strcmp (property, "left") == 0) { - /* Special case for position value. */ - int x; - int y; - - if (grub_gui_parse_2_tuple (value, &x, &y) == GRUB_ERR_NONE) - { - grub_video_rect_t r; - component->ops->get_bounds (component, &r); - r.x = x; - r.y = y; - component->ops->set_bounds (component, &r); - } + unsigned num; + char *ptr; + num = grub_strtoul (value, &ptr, 0); + if (*ptr == '%') + { + component->isxfrac = 1; + component->xfrac + = grub_fixed_fuf_divide (grub_unsigned_to_fixed (num), 100); + } + else + { + component->isxfrac = 0; + component->x = num; + } } - else if (grub_strcmp (property, "size") == 0) + else if (grub_strcmp (property, "top") == 0) { - /* Special case for size value. */ - int w; - int h; - - if (grub_gui_parse_2_tuple (value, &w, &h) == GRUB_ERR_NONE) - { - grub_video_rect_t r; - component->ops->get_bounds (component, &r); - r.width = w; - r.height = h; - component->ops->set_bounds (component, &r); - } + unsigned num; + char *ptr; + num = grub_strtoul (value, &ptr, 0); + if (*ptr == '%') + { + component->isyfrac = 1; + component->yfrac + = grub_fixed_fuf_divide (grub_unsigned_to_fixed (num), 100); + } + else + { + component->isyfrac = 0; + component->y = num; + } + } + else if (grub_strcmp (property, "width") == 0) + { + unsigned num; + char *ptr; + num = grub_strtoul (value, &ptr, 0); + if (*ptr == '%') + { + component->iswfrac = 1; + component->wfrac + = grub_fixed_fuf_divide (grub_unsigned_to_fixed (num), 100); + } + else + { + component->iswfrac = 0; + component->w = num; + } + } + else if (grub_strcmp (property, "height") == 0) + { + unsigned num; + char *ptr; + num = grub_strtoul (value, &ptr, 0); + if (*ptr == '%') + { + component->ishfrac = 1; + component->hfrac + = grub_fixed_fuf_divide (grub_unsigned_to_fixed (num), 100); + } + else + { + component->ishfrac = 0; + component->h = num; + } } else { @@ -552,16 +590,6 @@ read_object (struct parsebuf *p, grub_gui_container_t parent) goto cleanup; } - /* Set the object's size to its preferred size unless the user has - explicitly specified the size. */ - component->ops->get_bounds (component, &bounds); - if (bounds.width == -1 || bounds.height == -1) - { - component->ops->get_preferred_size (component, - &bounds.width, &bounds.height); - component->ops->set_bounds (component, &bounds); - } - cleanup: grub_free (name); return grub_errno; @@ -665,7 +693,7 @@ grub_gfxmenu_view_load_theme (grub_gfxmenu_view_t view, const char *theme_path) } if (view->canvas) - view->canvas->ops->component.destroy (view->canvas); + view->canvas->component.ops->destroy (view->canvas); view->canvas = grub_gui_canvas_new (); ((grub_gui_component_t) view->canvas) @@ -708,7 +736,7 @@ grub_gfxmenu_view_load_theme (grub_gfxmenu_view_t view, const char *theme_path) fail: if (view->canvas) { - view->canvas->ops->component.destroy (view->canvas); + view->canvas->component.ops->destroy (view->canvas); view->canvas = 0; } diff --git a/gfxmenu/view.c b/gfxmenu/view.c index e2348b6ef..414541dda 100644 --- a/gfxmenu/view.c +++ b/gfxmenu/view.c @@ -146,7 +146,7 @@ grub_gfxmenu_view_destroy (grub_gfxmenu_view_t view) grub_free (view->progress_message_text); grub_free (view->theme_path); if (view->canvas) - view->canvas->ops->component.destroy (view->canvas); + view->canvas->component.ops->destroy (view->canvas); grub_free (view); set_text_mode (); @@ -354,7 +354,7 @@ grub_gfxmenu_view_redraw (grub_gfxmenu_view_t view, redraw_background (view, region); if (view->canvas) - view->canvas->ops->component.paint (view->canvas, region); + view->canvas->component.ops->paint (view->canvas, region); draw_title (view); if (grub_video_have_common_points (&view->progress_message_frame, region)) draw_message (view); diff --git a/include/grub/gui.h b/include/grub/gui.h index 385c0962b..873d29e76 100644 --- a/include/grub/gui.h +++ b/include/grub/gui.h @@ -55,14 +55,13 @@ struct grub_gui_component_ops grub_gui_container_t (*get_parent) (void *self); void (*set_bounds) (void *self, const grub_video_rect_t *bounds); void (*get_bounds) (void *self, grub_video_rect_t *bounds); - void (*get_preferred_size) (void *self, int *width, int *height); + void (*get_minimal_size) (void *self, unsigned *width, unsigned *height); grub_err_t (*set_property) (void *self, const char *name, const char *value); void (*repaint) (void *self, int second_pass); }; struct grub_gui_container_ops { - struct grub_gui_component_ops component; void (*add) (void *self, grub_gui_component_t comp); void (*remove) (void *self, grub_gui_component_t comp); void (*iterate_children) (void *self, @@ -71,24 +70,78 @@ struct grub_gui_container_ops struct grub_gui_list_ops { - struct grub_gui_component_ops component_ops; void (*set_view_info) (void *self, const char *theme_path, grub_gfxmenu_model_t menu); }; +typedef grub_uint32_t grub_fixed_unsigned_t; +#define GRUB_FIXED_1 0x10000 + +static inline unsigned +grub_fixed_ufu_divide (grub_uint32_t a, grub_fixed_unsigned_t b) +{ + return (a << 16) / b; +} + +static inline grub_fixed_unsigned_t +grub_fixed_fuf_divide (grub_fixed_unsigned_t a, grub_uint32_t b) +{ + return a / b; +} + +static inline unsigned +grub_fixed_ufu_multiply (grub_uint32_t a, grub_fixed_unsigned_t b) +{ + return (a * b) >> 16; +} + +static inline unsigned +grub_fixed_to_unsigned (grub_fixed_unsigned_t in) +{ + return in >> 16; +} + +static inline grub_fixed_unsigned_t +grub_unsigned_to_fixed (unsigned in) +{ + return in << 16; +} + struct grub_gui_component { struct grub_gui_component_ops *ops; + int isxfrac:1; + int isyfrac:1; + int iswfrac:1; + int ishfrac:1; + union { + unsigned x; + grub_fixed_unsigned_t xfrac; + }; + union { + unsigned y; + grub_fixed_unsigned_t yfrac; + }; + union { + unsigned w; + grub_fixed_unsigned_t wfrac; + }; + union { + unsigned h; + grub_fixed_unsigned_t hfrac; + }; }; struct grub_gui_container { + struct grub_gui_component component; struct grub_gui_container_ops *ops; }; struct grub_gui_list { + struct grub_gui_component component; struct grub_gui_list_ops *ops; }; diff --git a/include/grub/gui_string_util.h b/include/grub/gui_string_util.h index 7b5fbb3ea..1baa2eede 100644 --- a/include/grub/gui_string_util.h +++ b/include/grub/gui_string_util.h @@ -34,6 +34,4 @@ int grub_gui_get_named_color (const char *name, grub_gui_color_t *color); grub_err_t grub_gui_parse_color (const char *s, grub_gui_color_t *color); -grub_err_t grub_gui_parse_2_tuple (const char *s, int *px, int *py); - #endif /* GRUB_GUI_STRING_UTIL_HEADER */ diff --git a/include/grub/video.h b/include/grub/video.h index 833df04c8..868e87871 100644 --- a/include/grub/video.h +++ b/include/grub/video.h @@ -160,10 +160,10 @@ struct grub_video_mode_info /* A 2D rectangle type. */ struct grub_video_rect { - int x; - int y; - int width; - int height; + unsigned x; + unsigned y; + unsigned width; + unsigned height; }; typedef struct grub_video_rect grub_video_rect_t; From 07e727f751028b3f9cdfa2c0ab892b8307e41d2b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 29 Dec 2009 17:53:10 +0100 Subject: [PATCH 179/738] Add missing include --- normal/context.c | 1 + 1 file changed, 1 insertion(+) diff --git a/normal/context.c b/normal/context.c index 412dbd84c..08a841699 100644 --- a/normal/context.c +++ b/normal/context.c @@ -22,6 +22,7 @@ #include #include #include +#include struct menu_pointer { From 7a68c375f36455f16d5aeae14d9055bb164537aa Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 29 Dec 2009 17:57:20 +0100 Subject: [PATCH 180/738] Fix warnings --- gfxmenu/gfxmenu.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/gfxmenu/gfxmenu.c b/gfxmenu/gfxmenu.c index 1fe6e7297..1db96a80f 100644 --- a/gfxmenu/gfxmenu.c +++ b/gfxmenu/gfxmenu.c @@ -39,13 +39,13 @@ grub_gfxmenu_view_t cached_view; -void +static void grub_gfxmenu_viewer_fini (void *data __attribute__ ((unused))) { } /* FIXME: Previously 't' changed to text menu is it necessary? */ -grub_err_t +static grub_err_t grub_gfxmenu_try (int entry, grub_menu_t menu, int nested) { grub_gfxmenu_view_t view = NULL; @@ -76,8 +76,8 @@ grub_gfxmenu_try (int entry, grub_menu_t menu, int nested) } if (!cached_view || grub_strcmp (cached_view->theme_path, theme_path) != 0 - || cached_view->screen.width != (int) mode_info.width - || cached_view->screen.height != (int) mode_info.height) + || cached_view->screen.width != mode_info.width + || cached_view->screen.height != mode_info.height) { grub_free (cached_view); /* Create the view. */ From 8291c2a3c929359652cf115dae40e40110018f6a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 29 Dec 2009 18:40:52 +0100 Subject: [PATCH 181/738] Fix a missing declaration --- video/sm712.c | 1 + 1 file changed, 1 insertion(+) diff --git a/video/sm712.c b/video/sm712.c index 52e43e9ae..5383b695e 100644 --- a/video/sm712.c +++ b/video/sm712.c @@ -68,6 +68,7 @@ grub_video_sm712_setup (unsigned int width, unsigned int height, grub_err_t err; int found = 0; + auto int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid __attribute__ ((unused))); int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid __attribute__ ((unused))) { grub_pci_address_t addr; From 0997ea7a43b941074c370b631dbf0012ce35471d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 29 Dec 2009 22:19:00 +0100 Subject: [PATCH 182/738] Fix compilation on sparc64 --- loader/sparc64/ieee1275/linux.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/loader/sparc64/ieee1275/linux.c b/loader/sparc64/ieee1275/linux.c index 3af93df7d..6513626d4 100644 --- a/loader/sparc64/ieee1275/linux.c +++ b/loader/sparc64/ieee1275/linux.c @@ -246,7 +246,7 @@ grub_linux_load64 (grub_elf_t elf) linux_entry = elf->ehdr.ehdr64.e_entry; linux_addr = 0x40004000; off = 0x4000; - linux_size = grub_elf64_size (elf); + linux_size = grub_elf64_size (elf, 0); if (linux_size == 0) return grub_errno; From f8882fe8f92af456ebd629038d931276bdb0a1ff Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 29 Dec 2009 22:50:38 +0100 Subject: [PATCH 183/738] Fix mismerge --- normal/menu.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/normal/menu.c b/normal/menu.c index 850350edd..17730eff3 100644 --- a/normal/menu.c +++ b/normal/menu.c @@ -232,9 +232,6 @@ menu_fini (void) viewers = NULL; } -/* FIXME: allow text menu in parallel with gfxmenu. */ -grub_err_t (*grub_gfxmenu_try_hook) (int entry, grub_menu_t menu, - int nested) = NULL; static void menu_init (int entry, grub_menu_t menu, int nested) { From 16c8e9fd6618ab15d9d6743f68c1021961870775 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 29 Dec 2009 23:01:12 +0100 Subject: [PATCH 184/738] Reimport hotkey support --- ChangeLog.hotkey | 9 +++++++++ include/grub/menu.h | 2 ++ normal/main.c | 39 +++++++++++++++++++++++++++++++++++++++ normal/menu.c | 15 ++++++++++++--- 4 files changed, 62 insertions(+), 3 deletions(-) create mode 100644 ChangeLog.hotkey diff --git a/ChangeLog.hotkey b/ChangeLog.hotkey new file mode 100644 index 000000000..1117b975c --- /dev/null +++ b/ChangeLog.hotkey @@ -0,0 +1,9 @@ +2009-08-24 Vladimir Serbinenko + + Hotkey support + + * include/grub/menu.h (grub_menu_entry): New field 'hotkey'. + * normal/main.c (hotkey_aliases): New variable. + (grub_normal_add_menu_entry): Parse "--hotkey". + * normal/menu_text.c (run_menu): Handle hotkeys. + diff --git a/include/grub/menu.h b/include/grub/menu.h index 78f461b92..e5e5fb110 100644 --- a/include/grub/menu.h +++ b/include/grub/menu.h @@ -47,6 +47,8 @@ struct grub_menu_entry /* The sourcecode of the menu entry, used by the editor. */ const char *sourcecode; + int hotkey; + /* The next element. */ struct grub_menu_entry *next; }; diff --git a/normal/main.c b/normal/main.c index 6d7a558f3..fd1088a10 100644 --- a/normal/main.c +++ b/normal/main.c @@ -155,6 +155,17 @@ free_menu_entry_classes (struct grub_menu_entry_class *head) } } +static struct +{ + char *name; + int key; +} hotkey_aliases[] = + { + {"backspace", '\b'}, + {"tab", '\t'}, + {"delete", GRUB_TERM_DC} + }; + /* Add a menu entry to the current menu context (as given by the environment variable data slot `menu'). As the configuration file is read, the script parser calls this when a menu entry is to be created. */ @@ -171,6 +182,7 @@ grub_normal_add_menu_entry (int argc, const char **args, struct grub_menu_entry_class *classes_head; /* Dummy head node for list. */ struct grub_menu_entry_class *classes_tail; char *users = NULL; + int hotkey = 0; /* Allocate dummy head node for class list. */ classes_head = grub_zalloc (sizeof (struct grub_menu_entry_class)); @@ -237,6 +249,32 @@ grub_normal_add_menu_entry (int argc, const char **args, continue; } + else if (grub_strcmp(arg, "hotkey") == 0) + { + unsigned j; + + i++; + if (args[i][1] == 0) + { + hotkey = args[i][0]; + continue; + } + + for (j = 0; j < ARRAY_SIZE (hotkey_aliases); j++) + if (grub_strcmp (args[i], hotkey_aliases[j].name) == 0) + { + hotkey = hotkey_aliases[j].key; + break; + } + + if (j < ARRAY_SIZE (hotkey_aliases)) + continue; + + failed = 1; + grub_error (GRUB_ERR_MENU, + "Invalid hotkey: '%s'.", args[i]); + break; + } else { /* Handle invalid argument. */ @@ -293,6 +331,7 @@ grub_normal_add_menu_entry (int argc, const char **args, } (*last)->title = menutitle; + (*last)->hotkey = hotkey; (*last)->classes = classes_head; if (users) (*last)->restricted = 1; diff --git a/normal/menu.c b/normal/menu.c index 850350edd..19e83831d 100644 --- a/normal/menu.c +++ b/normal/menu.c @@ -232,9 +232,6 @@ menu_fini (void) viewers = NULL; } -/* FIXME: allow text menu in parallel with gfxmenu. */ -grub_err_t (*grub_gfxmenu_try_hook) (int entry, grub_menu_t menu, - int nested) = NULL; static void menu_init (int entry, grub_menu_t menu, int nested) { @@ -479,6 +476,18 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot) goto refresh; default: + { + grub_menu_entry_t entry; + int i; + for (i = 0, entry = menu->entry_list; i < menu->size; + i++, entry = entry->next) + if (entry->hotkey == c) + { + menu_fini (); + *auto_boot = 0; + return i; + } + } break; } } From 1ad5c7f8446edf88765b9e48313228b43c23ad7e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 29 Dec 2009 23:32:31 +0100 Subject: [PATCH 185/738] Fix compilation warning --- gnulib/regex_internal.h | 2 +- include/grub/gnulib-wrap.h | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/gnulib/regex_internal.h b/gnulib/regex_internal.h index 977f8b02c..3cdc548d3 100644 --- a/gnulib/regex_internal.h +++ b/gnulib/regex_internal.h @@ -58,7 +58,7 @@ # define SIZE_MAX ((size_t) -1) #endif -#if (defined MB_CUR_MAX && HAVE_LOCALE_H && HAVE_WCTYPE_H && HAVE_ISWCTYPE && HAVE_WCSCOLL) || _LIBC +#if (defined MB_CUR_MAX && HAVE_LOCALE_H && HAVE_WCTYPE_H && HAVE_ISWCTYPE && HAVE_WCSCOLL) || defined (_LIBC) # define RE_ENABLE_I18N #endif diff --git a/include/grub/gnulib-wrap.h b/include/grub/gnulib-wrap.h index 0e9235c18..e3f7b23b0 100644 --- a/include/grub/gnulib-wrap.h +++ b/include/grub/gnulib-wrap.h @@ -22,6 +22,14 @@ #include #include +#define HAVE_ISBLANK 0 +#define HAVE_LIBINTL_H 0 +#define HAVE_LOCALE_H 0 +#define __STRICT_ANSI__ 0 +#define DEBUG 0 +#define _Restrict_ __restrict +#define _Restrict_arr_ __restrict + typedef grub_size_t size_t; typedef int bool; static const bool true = 1; @@ -165,6 +173,12 @@ calloc (grub_size_t size, grub_size_t nelem) return grub_zalloc (size * nelem); } +static inline char *strncpy (char *dest, const char *src, int c) +{ + return grub_strncpy (dest, src, c); +} + + #define ULONG_MAX GRUB_ULONG_MAX #define UCHAR_MAX 0xff From 11c22894af0bd5d82be12740424befc75e67451a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 30 Dec 2009 14:24:10 +0100 Subject: [PATCH 186/738] Fix warning in kern/misc.c --- kern/misc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kern/misc.c b/kern/misc.c index 087bef7fe..2b0db8518 100644 --- a/kern/misc.c +++ b/kern/misc.c @@ -630,7 +630,7 @@ grub_lltoa (char *str, int c, unsigned long long n) } static int -grub_vsnprintf_real (char *str, grub_size_t n, const char *fmt, va_list args) +grub_vsnprintf_real (char *str, grub_size_t max_len, const char *fmt, va_list args) { char c; grub_size_t count = 0; @@ -642,7 +642,7 @@ grub_vsnprintf_real (char *str, grub_size_t n, const char *fmt, va_list args) { if (str) { - if (count < n) + if (count < max_len) *str++ = ch; } else From ba2d24dc113d5c2634797860ede3de57904ee700 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 30 Dec 2009 15:31:45 +0100 Subject: [PATCH 187/738] Add missing -ffreestanding on mips --- conf/mips.rmk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/mips.rmk b/conf/mips.rmk index a6fcaf88e..1ef9579e8 100644 --- a/conf/mips.rmk +++ b/conf/mips.rmk @@ -2,7 +2,7 @@ # -*- makefile -*- COMMON_ASFLAGS += -nostdinc -COMMON_CFLAGS += -mexplicit-relocs -mflush-func=grub_cpu_flush_cache +COMMON_CFLAGS += -ffreestanding -mexplicit-relocs -mflush-func=grub_cpu_flush_cache COMMON_LDFLAGS += -nostdlib # Used by various components. These rules need to precede them. From 18277ec1f74e10d0f2d1fc0798e4e020810e15e5 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 31 Dec 2009 14:03:45 +0100 Subject: [PATCH 188/738] Fix typo --- kern/misc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kern/misc.c b/kern/misc.c index 2b0db8518..047b1e845 100644 --- a/kern/misc.c +++ b/kern/misc.c @@ -914,7 +914,7 @@ grub_avsprintf (const char *fmt, va_list ap) if (!ret) return NULL; - s = grub_vsnprintf (ret, as, fmt, ap); + s = grub_vsnprintf_real (ret, as, fmt, ap); if (s <= as) return ret; From b9da1700808ea5d8492aaf7c9daa0dcc048e5271 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 5 Jan 2010 19:38:11 +0100 Subject: [PATCH 189/738] Preliminary support for mixed percent and linear declarations --- gfxmenu/gui_box.c | 50 ++++++++----------- gfxmenu/gui_canvas.c | 66 +++++++++++++------------ gfxmenu/theme_loader.c | 108 +++++++++++++++-------------------------- include/grub/gui.h | 58 +++++++++------------- 4 files changed, 117 insertions(+), 165 deletions(-) diff --git a/gfxmenu/gui_box.c b/gfxmenu/gui_box.c index 45028e5b1..38b15f96d 100644 --- a/gfxmenu/gui_box.c +++ b/gfxmenu/gui_box.c @@ -93,7 +93,7 @@ layout_horizontally (grub_gui_box_t self, int modify_layout, struct component_node *cur; unsigned w = 0, mwfrac = 0, h = 0, x = 0; - grub_fixed_unsigned_t wfrac = 0; + grub_fixed_signed_t wfrac = 0; int bogus_frac = 0; for (cur = self->chead.next; cur != &self->ctail; cur = cur->next) @@ -104,17 +104,14 @@ layout_horizontally (grub_gui_box_t self, int modify_layout, if (c->ops->get_minimal_size) c->ops->get_minimal_size (c, &mw, &mh); - if (!c->ishfrac && c->h > h) + if (c->h > (signed) h) h = c->h; if (mh > h) h = mh; - if (!c->iswfrac) - w += mw > c->w ? mw : c->w; - if (c->iswfrac) - { - wfrac += c->wfrac; - mwfrac += mw; - } + wfrac += c->wfrac; + w += c->w; + if (mw - c->w > 0) + mwfrac += mw - c->w; } if (wfrac > GRUB_FIXED_1 || (w > 0 && wfrac == GRUB_FIXED_1)) bogus_frac = 1; @@ -122,7 +119,7 @@ layout_horizontally (grub_gui_box_t self, int modify_layout, if (min_width) { if (wfrac < GRUB_FIXED_1) - *min_width = grub_fixed_ufu_divide (w, GRUB_FIXED_1 - wfrac); + *min_width = grub_fixed_sfs_divide (w, GRUB_FIXED_1 - wfrac); else *min_width = w; if (*min_width < w + mwfrac) @@ -142,16 +139,14 @@ layout_horizontally (grub_gui_box_t self, int modify_layout, r.x = x; r.y = 0; - r.width = 32; r.height = h; if (c->ops->get_minimal_size) c->ops->get_minimal_size (c, &mw, &mh); - if (!c->iswfrac) - r.width = c->w; - if (c->iswfrac && !bogus_frac) - r.width = grub_fixed_ufu_multiply (self->bounds.width, c->wfrac); + r.width = c->w; + if (!bogus_frac) + r.width += grub_fixed_sfs_multiply (self->bounds.width, c->wfrac); if (r.width < mw) r.width = mw; @@ -171,7 +166,7 @@ layout_vertically (grub_gui_box_t self, int modify_layout, struct component_node *cur; unsigned h = 0, mhfrac = 0, w = 0, y = 0; - grub_fixed_unsigned_t hfrac = 0; + grub_fixed_signed_t hfrac = 0; int bogus_frac = 0; for (cur = self->chead.next; cur != &self->ctail; cur = cur->next) @@ -182,17 +177,14 @@ layout_vertically (grub_gui_box_t self, int modify_layout, if (c->ops->get_minimal_size) c->ops->get_minimal_size (c, &mw, &mh); - if (!c->iswfrac && c->w > w) + if (c->w > (signed) w) w = c->w; if (mw > w) w = mw; - if (!c->ishfrac) - h += mh > c->h ? mh : c->h; - if (c->ishfrac) - { - hfrac += c->hfrac; - mhfrac += mh; - } + hfrac += c->hfrac; + h += c->h; + if (mh - c->h > 0) + mhfrac += mh - c->h; } if (hfrac > GRUB_FIXED_1 || (h > 0 && hfrac == GRUB_FIXED_1)) bogus_frac = 1; @@ -200,7 +192,7 @@ layout_vertically (grub_gui_box_t self, int modify_layout, if (min_height) { if (hfrac < GRUB_FIXED_1) - *min_height = grub_fixed_ufu_divide (h, GRUB_FIXED_1 - hfrac); + *min_height = grub_fixed_sfs_divide (h, GRUB_FIXED_1 - hfrac); else *min_height = h; if (*min_height < h + mhfrac) @@ -221,15 +213,13 @@ layout_vertically (grub_gui_box_t self, int modify_layout, r.x = 0; r.y = y; r.width = w; - r.height = 32; if (c->ops->get_minimal_size) c->ops->get_minimal_size (c, &mw, &mh); - if (!c->ishfrac) - r.height = c->h; - if (c->ishfrac) - r.height = grub_fixed_ufu_multiply (self->bounds.height, c->hfrac); + r.height = c->h; + if (!bogus_frac) + r.height += grub_fixed_sfs_multiply (self->bounds.height, c->hfrac); if (r.height < mh) r.height = mh; diff --git a/gfxmenu/gui_canvas.c b/gfxmenu/gui_canvas.c index 8b55b2a73..b3919c2d3 100644 --- a/gfxmenu/gui_canvas.c +++ b/gfxmenu/gui_canvas.c @@ -88,49 +88,51 @@ canvas_paint (void *vself, const grub_video_rect_t *region) { grub_video_rect_t r; grub_gui_component_t comp; + signed x, y, w, h; comp = cur->component; - r.x = 0; - r.y = 0; - r.width = 32; - r.height = 32; - - if (!comp->iswfrac && comp->w) - r.width = comp->w; - - if (!comp->ishfrac && comp->h) - r.height = comp->h; - - if (!comp->isxfrac && comp->x) - r.x = comp->x; - - if (!comp->isyfrac && comp->y) - r.y = comp->y; - - if (comp->ishfrac && comp->hfrac) - r.height = grub_fixed_ufu_multiply (self->bounds.height, comp->hfrac); - - if (comp->iswfrac && comp->wfrac) - r.width = grub_fixed_ufu_multiply (self->bounds.width, comp->wfrac); - - if (comp->isxfrac && comp->xfrac) - r.x = grub_fixed_ufu_multiply (self->bounds.width, comp->xfrac); - - if (comp->isyfrac && comp->yfrac) - r.y = grub_fixed_ufu_multiply (self->bounds.height, comp->yfrac); + w = grub_fixed_sfs_multiply (self->bounds.width, comp->wfrac) + comp->w; + h = grub_fixed_sfs_multiply (self->bounds.height, comp->hfrac) + comp->h; + x = grub_fixed_sfs_multiply (self->bounds.width, comp->xfrac) + comp->x; + y = grub_fixed_sfs_multiply (self->bounds.height, comp->yfrac) + comp->y; if (comp->ops->get_minimal_size) { unsigned mw; unsigned mh; comp->ops->get_minimal_size (comp, &mw, &mh); - if (r.width < mw) - r.width = mw; - if (r.height < mh) - r.height = mh; + if (w < (signed) mw) + w = mw; + if (h < (signed) mh) + h = mh; } + /* Sanity checks. */ + if (w <= 0) + w = 32; + if (h <= 0) + h = 32; + + if (x >= (signed) self->bounds.width) + x = self->bounds.width - 32; + if (y >= (signed) self->bounds.height) + y = self->bounds.height - 32; + + if (x < 0) + x = 0; + if (y < 0) + y = 0; + + if (x + w >= (signed) self->bounds.width) + w = self->bounds.width - x; + if (y + h >= (signed) self->bounds.height) + h = self->bounds.height - y; + + r.x = x; + r.y = y; + r.width = w; + r.height = h; comp->ops->set_bounds (comp, &r); /* Paint the child. */ diff --git a/gfxmenu/theme_loader.c b/gfxmenu/theme_loader.c index 29bc1d2a6..09637d6b4 100644 --- a/gfxmenu/theme_loader.c +++ b/gfxmenu/theme_loader.c @@ -361,6 +361,40 @@ read_expression (struct parsebuf *p) return grub_new_substring (p->buf, start, end); } +static grub_err_t +parse_proportional_spec (char *value, signed *abs, grub_fixed_signed_t *prop) +{ + signed num; + char *ptr; + int sig = 0; + *abs = 0; + *prop = 0; + ptr = value; + while (*ptr) + { + sig = 0; + + while (*ptr == '-' || *ptr == '+') + { + if (*ptr == '-') + sig = !sig; + ptr++; + } + + num = grub_strtoul (ptr, &ptr, 0); + if (grub_errno) + return grub_errno; + if (sig) + num = -num; + if (*ptr == '%') + *prop += grub_fixed_fsf_divide (grub_signed_to_fixed (num), 100); + else + *abs += num; + } + return GRUB_ERR_NONE; +} + + /* Read a GUI object specification from the theme file. Any components created will be added to the GUI container PARENT. */ static grub_err_t @@ -511,78 +545,16 @@ read_object (struct parsebuf *p, grub_gui_container_t parent) /* Handle the property value. */ if (grub_strcmp (property, "left") == 0) - { - unsigned num; - char *ptr; - num = grub_strtoul (value, &ptr, 0); - if (*ptr == '%') - { - component->isxfrac = 1; - component->xfrac - = grub_fixed_fuf_divide (grub_unsigned_to_fixed (num), 100); - } - else - { - component->isxfrac = 0; - component->x = num; - } - } + parse_proportional_spec (value, &component->x, &component->xfrac); else if (grub_strcmp (property, "top") == 0) - { - unsigned num; - char *ptr; - num = grub_strtoul (value, &ptr, 0); - if (*ptr == '%') - { - component->isyfrac = 1; - component->yfrac - = grub_fixed_fuf_divide (grub_unsigned_to_fixed (num), 100); - } - else - { - component->isyfrac = 0; - component->y = num; - } - } + parse_proportional_spec (value, &component->y, &component->yfrac); else if (grub_strcmp (property, "width") == 0) - { - unsigned num; - char *ptr; - num = grub_strtoul (value, &ptr, 0); - if (*ptr == '%') - { - component->iswfrac = 1; - component->wfrac - = grub_fixed_fuf_divide (grub_unsigned_to_fixed (num), 100); - } - else - { - component->iswfrac = 0; - component->w = num; - } - } + parse_proportional_spec (value, &component->w, &component->wfrac); else if (grub_strcmp (property, "height") == 0) - { - unsigned num; - char *ptr; - num = grub_strtoul (value, &ptr, 0); - if (*ptr == '%') - { - component->ishfrac = 1; - component->hfrac - = grub_fixed_fuf_divide (grub_unsigned_to_fixed (num), 100); - } - else - { - component->ishfrac = 0; - component->h = num; - } - } + parse_proportional_spec (value, &component->h, &component->hfrac); else - { - /* General property handling. */ - component->ops->set_property (component, property, value); - } + /* General property handling. */ + component->ops->set_property (component, property, value); grub_free (value); grub_free (property); diff --git a/include/grub/gui.h b/include/grub/gui.h index 873d29e76..7c4774838 100644 --- a/include/grub/gui.h +++ b/include/grub/gui.h @@ -75,62 +75,50 @@ struct grub_gui_list_ops grub_gfxmenu_model_t menu); }; -typedef grub_uint32_t grub_fixed_unsigned_t; +typedef signed grub_fixed_signed_t; #define GRUB_FIXED_1 0x10000 -static inline unsigned -grub_fixed_ufu_divide (grub_uint32_t a, grub_fixed_unsigned_t b) +static inline signed +grub_fixed_sfs_divide (signed a, grub_fixed_signed_t b) { - return (a << 16) / b; + return (a * GRUB_FIXED_1) / b; } -static inline grub_fixed_unsigned_t -grub_fixed_fuf_divide (grub_fixed_unsigned_t a, grub_uint32_t b) +static inline grub_fixed_signed_t +grub_fixed_fsf_divide (grub_fixed_signed_t a, signed b) { return a / b; } -static inline unsigned -grub_fixed_ufu_multiply (grub_uint32_t a, grub_fixed_unsigned_t b) +static inline signed +grub_fixed_sfs_multiply (signed a, grub_fixed_signed_t b) { - return (a * b) >> 16; + return (a * b) / GRUB_FIXED_1; } -static inline unsigned -grub_fixed_to_unsigned (grub_fixed_unsigned_t in) +static inline signed +grub_fixed_to_signed (grub_fixed_signed_t in) { - return in >> 16; + return in / GRUB_FIXED_1; } -static inline grub_fixed_unsigned_t -grub_unsigned_to_fixed (unsigned in) +static inline grub_fixed_signed_t +grub_signed_to_fixed (signed in) { - return in << 16; + return in * GRUB_FIXED_1; } struct grub_gui_component { struct grub_gui_component_ops *ops; - int isxfrac:1; - int isyfrac:1; - int iswfrac:1; - int ishfrac:1; - union { - unsigned x; - grub_fixed_unsigned_t xfrac; - }; - union { - unsigned y; - grub_fixed_unsigned_t yfrac; - }; - union { - unsigned w; - grub_fixed_unsigned_t wfrac; - }; - union { - unsigned h; - grub_fixed_unsigned_t hfrac; - }; + signed x; + grub_fixed_signed_t xfrac; + signed y; + grub_fixed_signed_t yfrac; + signed w; + grub_fixed_signed_t wfrac; + signed h; + grub_fixed_signed_t hfrac; }; struct grub_gui_container From 6812d2e72d05e88645c8daabf72c3848170a5b91 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 5 Jan 2010 21:06:27 +0100 Subject: [PATCH 190/738] Fix non-skipping of percent sign --- gfxmenu/theme_loader.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gfxmenu/theme_loader.c b/gfxmenu/theme_loader.c index 09637d6b4..3854c6c53 100644 --- a/gfxmenu/theme_loader.c +++ b/gfxmenu/theme_loader.c @@ -387,7 +387,10 @@ parse_proportional_spec (char *value, signed *abs, grub_fixed_signed_t *prop) if (sig) num = -num; if (*ptr == '%') - *prop += grub_fixed_fsf_divide (grub_signed_to_fixed (num), 100); + { + *prop += grub_fixed_fsf_divide (grub_signed_to_fixed (num), 100); + ptr++; + } else *abs += num; } From be42af388421dcb922fb8b55388f2b852df4d275 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 5 Jan 2010 21:07:06 +0100 Subject: [PATCH 191/738] Compute list size automatically --- gfxmenu/gui_list.c | 39 +++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/gfxmenu/gui_list.c b/gfxmenu/gui_list.c index c55cfd85c..b4886a2cc 100644 --- a/gfxmenu/gui_list.c +++ b/gfxmenu/gui_list.c @@ -53,8 +53,6 @@ struct grub_gui_list_impl grub_gfxmenu_box_t scrollbar_thumb; int scrollbar_width; - int min_items_shown; - int max_items_shown; int first_shown_index; int need_to_recreate_boxes; @@ -91,12 +89,16 @@ list_destroy (void *vself) static int get_num_shown_items (list_impl_t self) { - int n = grub_gfxmenu_model_get_num_entries (self->menu); - if (self->min_items_shown != -1 && n < self->min_items_shown) - n = self->min_items_shown; - if (self->max_items_shown != -1 && n > self->max_items_shown) - n = self->max_items_shown; - return n; + int boxpad = self->item_padding; + int item_vspace = self->item_spacing; + int item_height = self->item_height; + + grub_gfxmenu_box_t box = self->menu_box; + int box_top_pad = box->get_top_pad (box); + int box_bottom_pad = box->get_bottom_pad (box); + + return (self->bounds.height + item_vspace - 2 * boxpad + - box_top_pad - box_bottom_pad) / (item_height + item_vspace); } static int @@ -364,15 +366,22 @@ list_get_minimal_size (void *vself, unsigned *width, unsigned *height) int boxpad = self->item_padding; int item_vspace = self->item_spacing; int item_height = self->item_height; - int num_items = get_num_shown_items (self); + int num_items = 3; grub_gfxmenu_box_t box = self->menu_box; int box_left_pad = box->get_left_pad (box); int box_top_pad = box->get_top_pad (box); int box_right_pad = box->get_right_pad (box); int box_bottom_pad = box->get_bottom_pad (box); + unsigned width_s; + + *width = grub_font_get_string_width (self->item_font, "Typical OS"); + width_s = grub_font_get_string_width (self->selected_item_font, + "Typical OS"); + if (*width < width_s) + *width = width_s; - *width = 400 + 2 * boxpad + box_left_pad + box_right_pad; + *width += 2 * boxpad + box_left_pad + box_right_pad; /* Set the menu box height to fit the items. */ *height = (item_height * num_items @@ -485,14 +494,6 @@ list_set_property (void *vself, const char *name, const char *value) { self->draw_scrollbar = grub_strcmp (value, "false") != 0; } - else if (grub_strcmp (name, "min_items_shown") == 0) - { - self->min_items_shown = grub_strtol (value, 0, 10); - } - else if (grub_strcmp (name, "max_items_shown") == 0) - { - self->max_items_shown = grub_strtol (value, 0, 10); - } else if (grub_strcmp (name, "theme_dir") == 0) { self->need_to_recreate_boxes = 1; @@ -581,8 +582,6 @@ grub_gui_list_new (void) self->scrollbar_thumb_pattern = 0; self->scrollbar_width = 16; - self->min_items_shown = -1; - self->max_items_shown = -1; self->first_shown_index = 0; self->need_to_recreate_boxes = 0; From eb1c959440899c2bfd7dbc514b5ec11b17a2a283 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 5 Jan 2010 21:24:33 +0100 Subject: [PATCH 192/738] grub-mkconfig support for themes --- util/grub-mkconfig.in | 1 + util/grub.d/00_header.in | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in index 49e52b313..7e667fb3e 100644 --- a/util/grub-mkconfig.in +++ b/util/grub-mkconfig.in @@ -220,6 +220,7 @@ export GRUB_DEFAULT \ GRUB_DISABLE_LINUX_UUID \ GRUB_DISABLE_LINUX_RECOVERY \ GRUB_GFXMODE \ + GRUB_THEME \ GRUB_DISABLE_OS_PROBER if test "x${grub_cfg}" != "x"; then diff --git a/util/grub.d/00_header.in b/util/grub.d/00_header.in index 0adfe6b76..da394783a 100644 --- a/util/grub.d/00_header.in +++ b/util/grub.d/00_header.in @@ -93,6 +93,15 @@ if loadfont `make_system_path_relative_to_its_root ${GRUB_FONT_PATH}` ; then # understand terminal_output terminal gfxterm fi +EOF +if [ x$GRUB_THEME != x ] && [ -f $GRUB_THEME ] \ + && is_path_readable_by_grub $GRUB_THEME; then + echo "Found theme: $GRUB_THEME" >&2 + prepare_grub_to_access_device `${grub_probe} --target=device $GRUB_THEME` + echo "insmod gfxmenu" + echo "set theme=(\$root)/`make_system_path_relative_to_its_root $GRUB_THEME`" +fi + cat << EOF fi EOF ;; From b9d28aa05fdd761074189b0acb1f3fd666f3894e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 5 Jan 2010 23:22:02 +0100 Subject: [PATCH 193/738] Fix missing viewport in gui_list --- gfxmenu/gui_list.c | 82 +++++++++++++++++++++++++--------------------- 1 file changed, 45 insertions(+), 37 deletions(-) diff --git a/gfxmenu/gui_list.c b/gfxmenu/gui_list.c index b4886a2cc..fd0f11635 100644 --- a/gfxmenu/gui_list.c +++ b/gfxmenu/gui_list.c @@ -209,7 +209,8 @@ draw_scrollbar (list_impl_t self, /* Draw the list of items. */ static void -draw_menu (list_impl_t self) +draw_menu (list_impl_t self, int width, int drawing_scrollbar, + int num_shown_items) { if (! self->menu_box || ! self->selected_item_box) return; @@ -222,38 +223,19 @@ draw_menu (list_impl_t self) int descent = grub_font_get_descent (self->item_font); int item_height = self->item_height; - int total_num_items = grub_gfxmenu_model_get_num_entries (self->menu); - int num_shown_items = get_num_shown_items (self); - grub_gfxmenu_box_t box = self->menu_box; - int width = self->bounds.width; - int height = self->bounds.height; - - int box_left_pad = box->get_left_pad (box); - int box_top_pad = box->get_top_pad (box); - int box_right_pad = box->get_right_pad (box); - int box_bottom_pad = box->get_bottom_pad (box); - - box->set_content_size (box, - width - box_left_pad - box_right_pad, - height - box_top_pad - box_bottom_pad); - - box->draw (box, 0, 0); - make_selected_item_visible (self); - int drawing_scrollbar = (self->draw_scrollbar - && (num_shown_items < total_num_items) - && check_scrollbar (self)); - int scrollbar_h_space = drawing_scrollbar ? self->scrollbar_width : 0; - int item_top = box_top_pad + boxpad; - int item_left = box_left_pad + boxpad; + grub_gfxmenu_box_t selbox = self->selected_item_box; + int sel_leftpad = selbox->get_left_pad (selbox); + int item_top = boxpad; + int item_left = boxpad + sel_leftpad; int menu_index; int visible_index; for (visible_index = 0, menu_index = self->first_shown_index; - visible_index < num_shown_items && menu_index < total_num_items; + visible_index < num_shown_items && menu_index < self->menu->size; visible_index++, menu_index++) { int is_selected = @@ -261,12 +243,9 @@ draw_menu (list_impl_t self) if (is_selected) { - grub_gfxmenu_box_t selbox = self->selected_item_box; - int sel_leftpad = selbox->get_left_pad (selbox); int sel_toppad = selbox->get_top_pad (selbox); selbox->set_content_size (selbox, (width - 2 * boxpad - - box_left_pad - box_right_pad - scrollbar_h_space), item_height); selbox->draw (selbox, @@ -300,14 +279,6 @@ draw_menu (list_impl_t self) item_top += item_height + item_vspace; } - - if (drawing_scrollbar) - draw_scrollbar (self, - self->first_shown_index, num_shown_items, - 0, total_num_items, - width - box_right_pad + self->scrollbar_width, - box_top_pad + boxpad, - height - box_top_pad - box_bottom_pad); } static void @@ -323,8 +294,45 @@ list_paint (void *vself, const grub_video_rect_t *region) check_boxes (self); + if (! self->menu_box || ! self->selected_item_box) + return; + grub_gui_set_viewport (&self->bounds, &vpsave); - draw_menu (self); + { + grub_gfxmenu_box_t box = self->menu_box; + int box_left_pad = box->get_left_pad (box); + int box_top_pad = box->get_top_pad (box); + int box_right_pad = box->get_right_pad (box); + int box_bottom_pad = box->get_bottom_pad (box); + grub_video_rect_t vpsave2, content_rect; + int num_shown_items = get_num_shown_items (self); + int drawing_scrollbar = (self->draw_scrollbar + && (num_shown_items < self->menu->size) + && check_scrollbar (self)); + + content_rect.x = box_left_pad; + content_rect.y = box_top_pad; + content_rect.width = self->bounds.width - box_left_pad - box_right_pad; + content_rect.height = self->bounds.height - box_top_pad - box_bottom_pad; + + box->set_content_size (box, content_rect.width, content_rect.height); + + box->draw (box, 0, 0); + + grub_gui_set_viewport (&content_rect, &vpsave2); + draw_menu (self, content_rect.width, drawing_scrollbar, num_shown_items); + grub_gui_restore_viewport (&vpsave2); + + if (drawing_scrollbar) + draw_scrollbar (self, + self->first_shown_index, num_shown_items, + 0, self->menu->size, + content_rect.width - box_right_pad + + self->scrollbar_width, + box_top_pad + self->item_padding, + content_rect.height - box_top_pad - box_bottom_pad); + } + grub_gui_restore_viewport (&vpsave); } From ea51afb099a6a88288f6b4f0800b16e0ca76d9dc Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 5 Jan 2010 23:49:40 +0100 Subject: [PATCH 194/738] Use pixmapbar only when images available --- gfxmenu/gui_progress_bar.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/gfxmenu/gui_progress_bar.c b/gfxmenu/gui_progress_bar.c index 9af93cff5..95be91e2a 100644 --- a/gfxmenu/gui_progress_bar.c +++ b/gfxmenu/gui_progress_bar.c @@ -46,6 +46,7 @@ struct grub_gui_progress_bar char *theme_dir; int need_to_recreate_pixmaps; + int pixmapbar_available; char *bar_pattern; char *highlight_pattern; grub_gfxmenu_box_t bar_box; @@ -77,6 +78,8 @@ progress_bar_is_instance (void *vself __attribute__((unused)), const char *type) static int check_pixmaps (grub_gui_progress_bar_t self) { + if (!self->pixmapbar_available) + return 0; if (self->need_to_recreate_pixmaps) { grub_gui_recreate_box (&self->bar_box, @@ -137,6 +140,7 @@ draw_pixmap_bar (grub_gui_progress_bar_t self) int bar_v_pad = bar_t_pad + bar_b_pad; int tracklen = w - bar_h_pad; int trackheight = h - bar_v_pad; + bar->set_content_size (bar, tracklen, trackheight); int barwidth = (tracklen @@ -172,12 +176,16 @@ static void progress_bar_paint (void *vself, const grub_video_rect_t *region) { grub_gui_progress_bar_t self = vself; + grub_video_rect_t vpsave; + if (! self->visible) return; if (!grub_video_have_common_points (region, &self->bounds)) return; - grub_video_rect_t vpsave; + if (self->end == self->start) + return; + grub_gui_set_viewport (&self->bounds, &vpsave); if (check_pixmaps (self)) @@ -272,12 +280,14 @@ progress_bar_set_property (void *vself, const char *name, const char *value) else if (grub_strcmp (name, "bar_style") == 0) { self->need_to_recreate_pixmaps = 1; + self->pixmapbar_available = 1; grub_free (self->bar_pattern); self->bar_pattern = value ? grub_strdup (value) : 0; } else if (grub_strcmp (name, "highlight_style") == 0) { self->need_to_recreate_pixmaps = 1; + self->pixmapbar_available = 1; grub_free (self->highlight_pattern); self->highlight_pattern = value ? grub_strdup (value) : 0; } From 4d253049d5139b34e35154e74850d3c68e4d0b8b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 6 Jan 2010 01:42:21 +0100 Subject: [PATCH 195/738] Fix non-clearing of timeout. Template support for timeout text. --- gfxmenu/gui_circular_progress.c | 39 +++++++------- gfxmenu/gui_progress_bar.c | 96 +++++++++++++++++++++------------ gfxmenu/view.c | 44 ++++++--------- include/grub/gui.h | 11 ++++ normal/menu.c | 2 + 5 files changed, 110 insertions(+), 82 deletions(-) diff --git a/gfxmenu/gui_circular_progress.c b/gfxmenu/gui_circular_progress.c index 7634c368d..9a859ee2e 100644 --- a/gfxmenu/gui_circular_progress.c +++ b/gfxmenu/gui_circular_progress.c @@ -28,7 +28,7 @@ struct grub_gui_circular_progress { - struct grub_gui_component comp; + struct grub_gui_progress progress; grub_gui_container_t parent; grub_video_rect_t bounds; @@ -215,19 +215,7 @@ static grub_err_t circprog_set_property (void *vself, const char *name, const char *value) { circular_progress_t self = vself; - if (grub_strcmp (name, "value") == 0) - { - self->value = grub_strtol (value, 0, 10); - } - else if (grub_strcmp (name, "start") == 0) - { - self->start = grub_strtol (value, 0, 10); - } - else if (grub_strcmp (name, "end") == 0) - { - self->end = grub_strtol (value, 0, 10); - } - else if (grub_strcmp (name, "num_ticks") == 0) + if (grub_strcmp (name, "num_ticks") == 0) { self->num_ticks = grub_strtol (value, 0, 10); } @@ -257,10 +245,6 @@ circprog_set_property (void *vself, const char *name, const char *value) grub_free (self->theme_dir); self->theme_dir = value ? grub_strdup (value) : 0; } - else if (grub_strcmp (name, "visible") == 0) - { - self->visible = grub_strcmp (value, "false") != 0; - } else if (grub_strcmp (name, "id") == 0) { grub_free (self->id); @@ -272,6 +256,17 @@ circprog_set_property (void *vself, const char *name, const char *value) return grub_errno; } +static void +circprog_set_state (void *vself, int visible, int start, + int current, int end) +{ + circular_progress_t self = vself; + self->visible = visible; + self->start = start; + self->value = current; + self->end = end; +} + static struct grub_gui_component_ops circprog_ops = { .destroy = circprog_destroy, @@ -285,6 +280,11 @@ static struct grub_gui_component_ops circprog_ops = .set_property = circprog_set_property }; +static struct grub_gui_progress_ops circprog_prog_ops = + { + .set_state = circprog_set_state + }; + grub_gui_component_t grub_gui_circular_progress_new (void) { @@ -292,7 +292,8 @@ grub_gui_circular_progress_new (void) self = grub_zalloc (sizeof (*self)); if (! self) return 0; - self->comp.ops = &circprog_ops; + self->progress.ops = &circprog_prog_ops; + self->progress.component.ops = &circprog_ops; self->visible = 1; self->num_ticks = 64; self->start_angle = -64; diff --git a/gfxmenu/gui_progress_bar.c b/gfxmenu/gui_progress_bar.c index d982924cb..6a7f43962 100644 --- a/gfxmenu/gui_progress_bar.c +++ b/gfxmenu/gui_progress_bar.c @@ -24,10 +24,11 @@ #include #include #include +#include struct grub_gui_progress_bar { - struct grub_gui_component component; + struct grub_gui_progress progress; grub_gui_container_t parent; grub_video_rect_t bounds; @@ -37,7 +38,7 @@ struct grub_gui_progress_bar int end; int value; int show_text; - char *text; + char *template; grub_font_t font; grub_gui_color_t text_color; grub_gui_color_t border_color; @@ -156,14 +157,20 @@ draw_pixmap_bar (grub_gui_progress_bar_t self) static void draw_text (grub_gui_progress_bar_t self) { - const char *text = self->text; - if (text && self->show_text) + if (self->template) { grub_font_t font = self->font; grub_video_color_t text_color = grub_gui_map_color (self->text_color); int width = self->bounds.width; int height = self->bounds.height; - + char *text = grub_asprintf (self->template, + self->value > 0 ? self->value : -self->value); + if (!text) + { + grub_print_error (); + grub_errno = GRUB_ERR_NONE; + return; + } /* Center the text. */ int text_width = grub_font_get_string_width (font, text); int x = (width - text_width) / 2; @@ -228,35 +235,60 @@ progress_bar_get_bounds (void *vself, grub_video_rect_t *bounds) } static void -progress_bar_get_minimal_size (void *vself __attribute__ ((unused)), +progress_bar_get_minimal_size (void *vself, unsigned *width, unsigned *height) { + unsigned text_width = 0, text_height = 0; + grub_gui_progress_bar_t self = vself; + + if (self->template) + { + text_width = grub_font_get_string_width (self->font, self->template); + text_width += grub_font_get_string_width (self->font, "XXXXXXXXXX"); + text_height = grub_font_get_descent (self->font) + + grub_font_get_ascent (self->font); + } *width = 200; + if (*width < text_width) + *width = text_width; *height = 28; + if (*height < text_height) + *height = text_height; +} + +static void +progress_bar_set_state (void *vself, int visible, int start, + int current, int end) +{ + grub_gui_progress_bar_t self = vself; + self->visible = visible; + self->start = start; + self->value = current; + self->end = end; } static grub_err_t progress_bar_set_property (void *vself, const char *name, const char *value) { grub_gui_progress_bar_t self = vself; - if (grub_strcmp (name, "value") == 0) + if (grub_strcmp (name, "text") == 0) { - self->value = grub_strtol (value, 0, 10); - } - else if (grub_strcmp (name, "start") == 0) - { - self->start = grub_strtol (value, 0, 10); - } - else if (grub_strcmp (name, "end") == 0) - { - self->end = grub_strtol (value, 0, 10); - } - else if (grub_strcmp (name, "text") == 0) - { - grub_free (self->text); - if (! value) - value = ""; - self->text = grub_strdup (value); + grub_free (self->template); + if (grub_strcmp (value, "@TIMEOUT_NOTIFICATION_LONG@") == 0) + value + = _("The highlighted entry will be executed automatically in %ds."); + else if (grub_strcmp (value, "@TIMEOUT_NOTIFICATION_MIDDLE@") == 0) + /* TRANSLATORS: 's' stands for seconds. + It's a standalone timeout notification. + Please use the short form in your language. */ + value = _("%ds remaining."); + else if (grub_strcmp (value, "@TIMEOUT_NOTIFICATION_SHORT@") == 0) + /* TRANSLATORS: 's' stands for seconds. + It's a standalone timeout notification. + Please use the shortest form available in you language. */ + value = _("%ds"); + + self->template = grub_strdup (value); } else if (grub_strcmp (name, "font") == 0) { @@ -298,14 +330,6 @@ progress_bar_set_property (void *vself, const char *name, const char *value) grub_free (self->theme_dir); self->theme_dir = value ? grub_strdup (value) : 0; } - else if (grub_strcmp (name, "visible") == 0) - { - self->visible = grub_strcmp (value, "false") != 0; - } - else if (grub_strcmp (name, "show_text") == 0) - { - self->show_text = grub_strcmp (value, "false") != 0; - } else if (grub_strcmp (name, "id") == 0) { grub_free (self->id); @@ -331,6 +355,11 @@ static struct grub_gui_component_ops progress_bar_ops = .set_property = progress_bar_set_property }; +static struct grub_gui_progress_ops progress_bar_pb_ops = + { + .set_state = progress_bar_set_state + }; + grub_gui_component_t grub_gui_progress_bar_new (void) { @@ -338,10 +367,9 @@ grub_gui_progress_bar_new (void) self = grub_zalloc (sizeof (*self)); if (! self) return 0; - self->component.ops = &progress_bar_ops; + self->progress.ops = &progress_bar_pb_ops; + self->progress.component.ops = &progress_bar_ops; self->visible = 1; - self->show_text = 1; - self->text = grub_strdup (""); self->font = grub_font_get ("Helvetica 10"); grub_gui_color_t black = { .red = 0, .green = 0, .blue = 0, .alpha = 255 }; grub_gui_color_t gray = { .red = 128, .green = 128, .blue = 128, .alpha = 255 }; diff --git a/gfxmenu/view.c b/gfxmenu/view.c index 5008b105b..611c01e1b 100644 --- a/gfxmenu/view.c +++ b/gfxmenu/view.c @@ -160,11 +160,10 @@ draw_title (grub_gfxmenu_view_t view) struct progress_value_data { - const char *visible; - const char *start; - const char *end; - const char *value; - const char *text; + int visible; + int start; + int end; + int value; }; static void @@ -174,19 +173,14 @@ update_timeout_visit (grub_gui_component_t component, struct progress_value_data *pv; pv = (struct progress_value_data *) userdata; - component->ops->set_property (component, "visible", pv->visible); - component->ops->set_property (component, "start", pv->start); - component->ops->set_property (component, "end", pv->end); - component->ops->set_property (component, "value", pv->value); - component->ops->set_property (component, "text", pv->text); + ((struct grub_gui_progress *) component)->ops + ->set_state ((struct grub_gui_progress *) component, + pv->visible, pv->start, pv->value, pv->end); } void grub_gfxmenu_print_timeout (int timeout, void *data) { - char valuebuf[sizeof ("-XXXXXXXXXXX")]; - char startbuf[sizeof ("-XXXXXXXXXXX")]; - char msgbuf[120]; struct grub_gfxmenu_view *view = data; struct progress_value_data pv; @@ -205,17 +199,10 @@ grub_gfxmenu_print_timeout (int timeout, void *data) if (view->first_timeout == -1) view->first_timeout = timeout; - pv.visible = "true"; - grub_sprintf (startbuf, "%d", -(view->first_timeout + 1)); - pv.start = startbuf; - pv.end = "0"; - grub_sprintf (valuebuf, "%d", -timeout); - pv.value = valuebuf; - - grub_sprintf (msgbuf, - "The highlighted entry will be booted automatically in %d s.", - timeout); - pv.text = msgbuf; + pv.visible = 1; + pv.start = -(view->first_timeout + 1); + pv.end = 0; + pv.value = -timeout; grub_gui_find_by_id ((grub_gui_component_t) view->canvas, TIMEOUT_COMPONENT_ID, update_timeout_visit, &pv); @@ -244,11 +231,10 @@ grub_gfxmenu_clear_timeout (void *data) grub_gfxmenu_view_redraw (view, &bounds); } - pv.visible = "false"; - pv.start = "1"; - pv.end = "0"; - pv.value = "0"; - pv.text = ""; + pv.visible = 0; + pv.start = 1; + pv.end = 0; + pv.value = 0; grub_gui_find_by_id ((grub_gui_component_t) view->canvas, TIMEOUT_COMPONENT_ID, update_timeout_visit, &pv); diff --git a/include/grub/gui.h b/include/grub/gui.h index 6f8f44805..7bd71acd3 100644 --- a/include/grub/gui.h +++ b/include/grub/gui.h @@ -74,6 +74,11 @@ struct grub_gui_list_ops grub_gfxmenu_view_t view); }; +struct grub_gui_progress_ops +{ + void (*set_state) (void *self, int visible, int start, int current, int end); +}; + typedef signed grub_fixed_signed_t; #define GRUB_FIXED_1 0x10000 @@ -120,6 +125,12 @@ struct grub_gui_component grub_fixed_signed_t hfrac; }; +struct grub_gui_progress +{ + struct grub_gui_component component; + struct grub_gui_progress_ops *ops; +}; + struct grub_gui_container { struct grub_gui_component component; diff --git a/normal/menu.c b/normal/menu.c index 17730eff3..bbd1049e4 100644 --- a/normal/menu.c +++ b/normal/menu.c @@ -362,6 +362,8 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot) if (timeout > 0) menu_print_timeout (timeout); + else + clear_timeout (); while (1) { From 2ab45155287b5a6088fab6b65a95069f83904ce9 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 6 Jan 2010 10:50:50 +0100 Subject: [PATCH 196/738] Push error before calling grub_gfxterm_fullscreen --- gfxmenu/gfxmenu.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/gfxmenu/gfxmenu.c b/gfxmenu/gfxmenu.c index 1db96a80f..a2e765156 100644 --- a/gfxmenu/gfxmenu.c +++ b/gfxmenu/gfxmenu.c @@ -57,21 +57,27 @@ grub_gfxmenu_try (int entry, grub_menu_t menu, int nested) theme_path = grub_env_get ("theme"); if (! theme_path) { + grub_error_push (); grub_gfxterm_fullscreen (); + grub_error_pop (); return grub_error (GRUB_ERR_FILE_NOT_FOUND, "no theme specified"); } instance = grub_zalloc (sizeof (*instance)); if (!instance) { + grub_error_push (); grub_gfxterm_fullscreen (); + grub_error_pop (); return grub_errno; } err = grub_video_get_info (&mode_info); if (err) { + grub_error_push (); grub_gfxterm_fullscreen (); + grub_error_pop (); return err; } @@ -88,7 +94,9 @@ grub_gfxmenu_try (int entry, grub_menu_t menu, int nested) if (! cached_view) { grub_free (instance); + grub_error_push (); grub_gfxterm_fullscreen (); + grub_error_pop (); return grub_errno; } From cd622720c84608c9ab561f41a689ed58e3804bb4 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 6 Jan 2010 10:51:23 +0100 Subject: [PATCH 197/738] Clear both buffers on gfxterm init --- term/gfxterm.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/term/gfxterm.c b/term/gfxterm.c index 0abe0f07d..26e94e474 100644 --- a/term/gfxterm.c +++ b/term/gfxterm.c @@ -315,6 +315,7 @@ grub_gfxterm_fullscreen (void) struct grub_video_mode_info mode_info; grub_video_color_t color; grub_err_t err; + int double_redraw; err = grub_video_get_info (&mode_info); /* Figure out what mode we ended up. */ @@ -323,9 +324,17 @@ grub_gfxterm_fullscreen (void) grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY); + double_redraw = mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED + && !(mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP); + /* Make sure screen is black. */ color = grub_video_map_rgb (0, 0, 0); grub_video_fill_rect (color, 0, 0, mode_info.width, mode_info.height); + if (double_redraw) + { + grub_video_swap_buffers (); + grub_video_fill_rect (color, 0, 0, mode_info.width, mode_info.height); + } bitmap = 0; /* Select the font to use. */ @@ -337,10 +346,7 @@ grub_gfxterm_fullscreen (void) return grub_gfxterm_set_window (GRUB_VIDEO_RENDER_TARGET_DISPLAY, 0, 0, mode_info.width, mode_info.height, - mode_info.mode_type - & GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED - && !(mode_info.mode_type - & GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP), + double_redraw, font_name, DEFAULT_BORDER_WIDTH); } From 34d2c9a10faf2abb7d4dc1562b272f692008a878 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 6 Jan 2010 22:19:28 +0100 Subject: [PATCH 198/738] Fix compilation error --- gfxmenu/gui_progress_bar.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/gfxmenu/gui_progress_bar.c b/gfxmenu/gui_progress_bar.c index 6a7f43962..550b5d43c 100644 --- a/gfxmenu/gui_progress_bar.c +++ b/gfxmenu/gui_progress_bar.c @@ -163,14 +163,15 @@ draw_text (grub_gui_progress_bar_t self) grub_video_color_t text_color = grub_gui_map_color (self->text_color); int width = self->bounds.width; int height = self->bounds.height; - char *text = grub_asprintf (self->template, - self->value > 0 ? self->value : -self->value); + char *text = grub_malloc (grub_strlen (self->template) + 10); if (!text) { grub_print_error (); grub_errno = GRUB_ERR_NONE; return; } + grub_sprintf (text, self->template, + self->value > 0 ? self->value : -self->value); /* Center the text. */ int text_width = grub_font_get_string_width (font, text); int x = (width - text_width) / 2; From c1b952d3d9a79ad03ded72d8abc58c0190f8a065 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Thu, 7 Jan 2010 18:20:11 +0000 Subject: [PATCH 199/738] 2010-01-07 Robert Millan * util/grub.d/10_hurd.in: Add --class information to menuentries. * util/grub.d/10_kfreebsd.in: Likewise. * util/grub.d/10_linux.in: Likewise. --- ChangeLog.mkconfig | 5 +++++ util/grub.d/10_hurd.in | 7 +++++-- util/grub.d/10_kfreebsd.in | 16 ++++++++++++---- util/grub.d/10_linux.in | 7 +++++-- 4 files changed, 27 insertions(+), 8 deletions(-) create mode 100644 ChangeLog.mkconfig diff --git a/ChangeLog.mkconfig b/ChangeLog.mkconfig new file mode 100644 index 000000000..665c938c7 --- /dev/null +++ b/ChangeLog.mkconfig @@ -0,0 +1,5 @@ +2010-01-07 Robert Millan + + * util/grub.d/10_hurd.in: Add --class information to menuentries. + * util/grub.d/10_kfreebsd.in: Likewise. + * util/grub.d/10_linux.in: Likewise. diff --git a/util/grub.d/10_hurd.in b/util/grub.d/10_hurd.in index c1871e07a..b56c585ee 100644 --- a/util/grub.d/10_hurd.in +++ b/util/grub.d/10_hurd.in @@ -1,7 +1,7 @@ #! /bin/sh -e # grub-mkconfig helper script. -# Copyright (C) 2006,2007,2008 Free Software Foundation, Inc. +# Copyright (C) 2006,2007,2008,2010 Free Software Foundation, Inc. # # GRUB is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -21,10 +21,13 @@ exec_prefix=@exec_prefix@ libdir=@libdir@ . ${libdir}/grub/grub-mkconfig_lib +CLASS="--class gnu --class os" + if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then OS=GNU else OS="${GRUB_DISTRIBUTOR} GNU/Hurd" + CLASS="--class $(echo ${GRUB_DISTRIBUTOR} | tr '[A-Z]' '[a-z]') ${CLASS}" fi at_least_one=false @@ -69,7 +72,7 @@ if ${all_of_them} && test -e /lib/ld.so.1 ; then : ; else fi cat << EOF -menuentry "${OS}" { +menuentry "${OS}" ${CLASS} { EOF prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/" cat << EOF diff --git a/util/grub.d/10_kfreebsd.in b/util/grub.d/10_kfreebsd.in index 026f1d7ac..7eb26072c 100644 --- a/util/grub.d/10_kfreebsd.in +++ b/util/grub.d/10_kfreebsd.in @@ -1,7 +1,7 @@ #! /bin/sh -e # grub-mkconfig helper script. -# Copyright (C) 2006,2007,2008,2009 Free Software Foundation, Inc. +# Copyright (C) 2006,2007,2008,2009,2010 Free Software Foundation, Inc. # # GRUB is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -26,9 +26,17 @@ libdir=@libdir@ export TEXTDOMAIN=@PACKAGE@ export TEXTDOMAINDIR=@LOCALEDIR@ +CLASS="--class os" + case "${GRUB_DISTRIBUTOR}" in - Debian) OS="${GRUB_DISTRIBUTOR} GNU/kFreeBSD" ;; - *) OS="FreeBSD" ;; + Debian) + OS="${GRUB_DISTRIBUTOR} GNU/kFreeBSD" + CLASS="--class $(echo ${GRUB_DISTRIBUTOR} | tr '[A-Z]' '[a-z]') --class gnu-kfreebsd --class gnu ${CLASS}" + ;; + *) + OS="FreeBSD" + CLASS="--class freebsd --class bsd ${CLASS}" + ;; esac kfreebsd_entry () @@ -38,7 +46,7 @@ kfreebsd_entry () recovery="$3" # not used yet args="$4" # not used yet title="$(gettext "%s, with kFreeBSD %s")" - printf "menuentry \"${title}\" {" ${os} ${version} + printf "menuentry \"${title}\" ${CLASS} {" ${os} ${version} save_default_entry | sed -e "s/^/\t/" if [ -z "${prepare_boot_cache}" ]; then prepare_boot_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/")" diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in index dc9696ec8..74d880641 100644 --- a/util/grub.d/10_linux.in +++ b/util/grub.d/10_linux.in @@ -1,7 +1,7 @@ #! /bin/sh -e # grub-mkconfig helper script. -# Copyright (C) 2006,2007,2008,2009 Free Software Foundation, Inc. +# Copyright (C) 2006,2007,2008,2009,2010 Free Software Foundation, Inc. # # GRUB is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -26,10 +26,13 @@ libdir=@libdir@ export TEXTDOMAIN=@PACKAGE@ export TEXTDOMAINDIR=@LOCALEDIR@ +CLASS="--class gnu-linux --class gnu --class os" + if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then OS=GNU/Linux else OS="${GRUB_DISTRIBUTOR} GNU/Linux" + CLASS="--class $(echo ${GRUB_DISTRIBUTOR} | tr '[A-Z]' '[a-z]') ${CLASS}" fi # loop-AES arranges things so that /dev/loop/X can be our root device, but @@ -58,7 +61,7 @@ linux_entry () else title="$(gettext "%s, with Linux %s")" fi - printf "menuentry \"${title}\" {" ${os} ${version} + printf "menuentry \"${title}\" ${CLASS} {" ${os} ${version} save_default_entry | sed -e "s/^/\t/" if [ -z "${prepare_boot_cache}" ]; then prepare_boot_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/")" From b5c72e3b0f2f09274cc67cbc335f1e3ca73f289e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 8 Jan 2010 19:15:49 +0100 Subject: [PATCH 200/738] Fix list scrollbar position miscalculation --- gfxmenu/gui_list.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gfxmenu/gui_list.c b/gfxmenu/gui_list.c index ccf360ad3..8377bf4bb 100644 --- a/gfxmenu/gui_list.c +++ b/gfxmenu/gui_list.c @@ -327,7 +327,7 @@ list_paint (void *vself, const grub_video_rect_t *region) draw_scrollbar (self, self->first_shown_index, num_shown_items, 0, self->view->menu->size, - content_rect.width - box_right_pad + self->bounds.width - box_right_pad + self->scrollbar_width, box_top_pad + self->item_padding, content_rect.height - box_top_pad - box_bottom_pad); From 2810a4ef1c2462f44da08a66b9337793a2b3fdd5 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 9 Jan 2010 11:48:38 +0100 Subject: [PATCH 201/738] Fix scrollbar height --- gfxmenu/gui_list.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gfxmenu/gui_list.c b/gfxmenu/gui_list.c index 8377bf4bb..a78339385 100644 --- a/gfxmenu/gui_list.c +++ b/gfxmenu/gui_list.c @@ -330,7 +330,7 @@ list_paint (void *vself, const grub_video_rect_t *region) self->bounds.width - box_right_pad + self->scrollbar_width, box_top_pad + self->item_padding, - content_rect.height - box_top_pad - box_bottom_pad); + self->bounds.height - box_top_pad - box_bottom_pad); } grub_gui_restore_viewport (&vpsave); From 21a99f580417062f9a79ee7ab4a05753f2a47571 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Sat, 9 Jan 2010 20:27:58 +0530 Subject: [PATCH 202/738] added grub-script-check tool --- conf/common.rmk | 21 ++++ util/grub-script-check.c | 254 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 275 insertions(+) create mode 100644 util/grub-script-check.c diff --git a/conf/common.rmk b/conf/common.rmk index c5e4fcecf..50a4d2111 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -88,11 +88,32 @@ endif bin_UTILITIES += grub-mkrelpath grub_mkrelpath_SOURCES = gnulib/progname.c util/grub-mkrelpath.c util/misc.c +# For grub-script-check. +bin_UTILITIES += grub-script-check +util/grub-script-check.c_DEPENDENCIES = grub_script_check_init.h +grub_script_check_SOURCES = gnulib/progname.c util/grub-script-check.c util/misc.c \ + script/main.c script/script.c script/function.c script/lexer.c \ + kern/handler.c kern/err.c kern/parser.c kern/list.c \ + kern/misc.c kern/env.c grub_script_check_init.c grub_script.tab.c + # For the parser. grub_script.tab.c grub_script.tab.h: script/parser.y $(YACC) -d -p grub_script_yy -b grub_script $(srcdir)/script/parser.y DISTCLEANFILES += grub_script.tab.c grub_script.tab.h +# For grub-check. +grub_script_check_init.lst: geninit.sh $(filter-out grub_script_check_init.c,$(grub_script_check_SOURCES)) + rm -f $@; grep GRUB_MOD_INIT $(filter %.c,$^) /dev/null > $@ +DISTCLEANFILES += grub_script_check_init.lst + +grub_script_check_init.h: grub_script_check_init.lst $(filter-out grub_script_check_init.c,$(grub_script_check_SOURCES)) geninitheader.sh + rm -f $@; sh $(srcdir)/geninitheader.sh $< > $@ +DISTCLEANFILES += grub_script_check_init.h + +grub_script_check_init.c: grub_script_check_init.lst $(filter-out grub_script_check_init.c,$(grub_script_check_SOURCES)) geninit.sh + rm -f $@; sh $(srcdir)/geninit.sh $< $(filter %.c,$^) > $@ +DISTCLEANFILES += grub_script_check_init.c + # For grub-probe. grub_probe_init.lst: geninit.sh $(filter-out grub_probe_init.c,$(grub_probe_SOURCES)) rm -f $@; grep GRUB_MOD_INIT $(filter %.c,$^) /dev/null > $@ diff --git a/util/grub-script-check.c b/util/grub-script-check.c new file mode 100644 index 000000000..3136c6530 --- /dev/null +++ b/util/grub-script-check.c @@ -0,0 +1,254 @@ +/* grub-script-check.c - check grub script file for syntax errors */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2004,2005,2006,2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#define _GNU_SOURCE 1 + +#include +#include +#include +#include +#include +#include + +#include "progname.h" + +void +grub_putchar (int c) +{ + putchar (c); +} + +int +grub_getkey (void) +{ + return -1; +} + +void +grub_refresh (void) +{ + fflush (stdout); +} + +struct grub_handler_class grub_term_input_class; +struct grub_handler_class grub_term_output_class; + +char * +grub_script_execute_argument_to_string (struct grub_script_arg *arg __attribute__ ((unused))) +{ + return 0; +} + +grub_err_t +grub_script_execute_cmdline (struct grub_script_cmd *cmd __attribute__ ((unused))) +{ + return 0; +} + +grub_err_t +grub_script_execute_cmdblock (struct grub_script_cmd *cmd __attribute__ ((unused))) +{ + return 0; +} + +grub_err_t +grub_script_execute_cmdif (struct grub_script_cmd *cmd __attribute__ ((unused))) +{ + return 0; +} + +grub_err_t +grub_script_execute_menuentry (struct grub_script_cmd *cmd) +{ + struct grub_script_cmd_menuentry *menu; + menu = (struct grub_script_cmd_menuentry *)cmd; + + if (menu->sourcecode) + { + grub_free (menu->sourcecode); + menu->sourcecode = 0; + } + return 0; +} + +grub_err_t +grub_script_execute (struct grub_script *script) +{ + if (script == 0 || script->cmd == 0) + return 0; + + return script->cmd->exec (script->cmd); +} + +static struct option options[] = + { + {"help", no_argument, 0, 'h'}, + {"version", no_argument, 0, 'V'}, + {"verbose", no_argument, 0, 'v'}, + {0, 0, 0, 0} + }; + +static void +usage (int status) +{ + if (status) + fprintf (stderr, + "Try ``%s --help'' for more information.\n", program_name); + else + printf ("\ +Usage: %s [PATH]\n\ +\n\ +Checks GRUB script configuration file for syntax errors.\n\ +\n\ + -h, --help display this message and exit\n\ + -V, --version print version information and exit\n\ + -v, --verbose print script being processed\n\ +\n\ +Report bugs to <%s>.\n\ +", program_name, + PACKAGE_BUGREPORT); + exit (status); +} + +int +main (int argc, char *argv[]) +{ + char *argument; + char *input; + FILE *file = 0; + int verbose = 0; + struct grub_script *script; + + auto grub_err_t get_config_line (char **line, int cont); + grub_err_t get_config_line (char **line, int cont __attribute__ ((unused))) + { + char *cmdline = 0; + size_t len = 0; + ssize_t read; + + read = getline(&cmdline, &len, (file ?: stdin)); + if (read == -1) + { + *line = 0; + grub_errno = GRUB_ERR_READ_ERROR; + + if (cmdline) + free (cmdline); + return grub_errno; + } + + if (verbose) + grub_printf("%s", cmdline); + + *line = grub_strdup (cmdline); + + free (cmdline); + return 0; + } + + set_program_name (argv[0]); + setlocale (LC_ALL, ""); + bindtextdomain (PACKAGE, LOCALEDIR); + textdomain (PACKAGE); + + /* Check for options. */ + while (1) + { + int c = getopt_long (argc, argv, "hvV", options, 0); + + if (c == -1) + break; + else + switch (c) + { + case 'h': + usage (0); + break; + + case 'V': + printf ("%s (%s) %s\n", program_name, PACKAGE_NAME, PACKAGE_VERSION); + return 0; + + case 'v': + verbose = 1; + break; + + default: + usage (1); + break; + } + } + + /* Obtain ARGUMENT. */ + if (optind >= argc) + { + file = 0; // read from stdin + } + else if (optind + 1 != argc) + { + fprintf (stderr, "Unknown extra argument `%s'.\n", argv[optind + 1]); + usage (1); + } + else + { + argument = argv[optind]; + file = fopen (argument, "r"); + if (! file) + { + fprintf (stderr, "%s: %s: %s\n", program_name, argument, strerror(errno)); + usage (1); + } + } + + /* Initialize all modules. */ + grub_init_all (); + + do + { + input = 0; + get_config_line(&input, 0); + if (! input) + break; + + script = grub_script_parse (input, get_config_line); + if (script) + { + grub_script_execute (script); + grub_script_free (script); + } + + grub_free (input); + } while (script != 0); + + /* Free resources. */ + grub_fini_all (); + if (file) fclose (file); + + return (script == 0); +} From 58ad6b39c4f549eb6a268fba5ea25d48c25ebf43 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Sat, 9 Jan 2010 20:31:33 +0530 Subject: [PATCH 203/738] added changelog file --- conf/common.rmk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/common.rmk b/conf/common.rmk index 50a4d2111..83464d3dd 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -101,7 +101,7 @@ grub_script.tab.c grub_script.tab.h: script/parser.y $(YACC) -d -p grub_script_yy -b grub_script $(srcdir)/script/parser.y DISTCLEANFILES += grub_script.tab.c grub_script.tab.h -# For grub-check. +# For grub-script-check. grub_script_check_init.lst: geninit.sh $(filter-out grub_script_check_init.c,$(grub_script_check_SOURCES)) rm -f $@; grep GRUB_MOD_INIT $(filter %.c,$^) /dev/null > $@ DISTCLEANFILES += grub_script_check_init.lst From 337470f1e1c427d52603e0ee3bb9e29aa886180b Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Sat, 9 Jan 2010 20:31:52 +0530 Subject: [PATCH 204/738] added changelog --- ChangeLog.grub-script-check | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 ChangeLog.grub-script-check diff --git a/ChangeLog.grub-script-check b/ChangeLog.grub-script-check new file mode 100644 index 000000000..6ed178d24 --- /dev/null +++ b/ChangeLog.grub-script-check @@ -0,0 +1,9 @@ +2010-01-09 BVK Chaitanya + + Added new tool, grub-scrit-check to verify grub.cfg syntax. + + * util/grub-script-check.c: grub-script-check tool. + * conf/common.rmk: Make rules for grub-script-check. + + + From 0b4de514913ce6e5f4f29fc274a499264d6d6586 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Sun, 10 Jan 2010 23:13:53 +0100 Subject: [PATCH 205/738] 2010-01-10 Robert Millan * conf/common.rmk (bin_UTILITIES): Add `grub-bin2h'. (grub_bin2h_SOURCES): New variable. * util/bin2h.c: New file. --- ChangeLog.kernel-font | 5 ++++ conf/common.rmk | 3 ++ util/bin2h.c | 69 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 77 insertions(+) create mode 100644 ChangeLog.kernel-font create mode 100644 util/bin2h.c diff --git a/ChangeLog.kernel-font b/ChangeLog.kernel-font new file mode 100644 index 000000000..c21696db9 --- /dev/null +++ b/ChangeLog.kernel-font @@ -0,0 +1,5 @@ +2010-01-10 Robert Millan + + * conf/common.rmk (bin_UTILITIES): Add `grub-bin2h'. + (grub_bin2h_SOURCES): New variable. + * util/bin2h.c: New file. diff --git a/conf/common.rmk b/conf/common.rmk index 3f1689370..0a67cf0cf 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -88,6 +88,9 @@ endif bin_UTILITIES += grub-mkrelpath grub_mkrelpath_SOURCES = gnulib/progname.c util/grub-mkrelpath.c util/misc.c +bin_UTILITIES += grub-bin2h +grub_bin2h_SOURCES = util/bin2h.c + # For the parser. grub_script.tab.c grub_script.tab.h: script/parser.y $(YACC) -d -p grub_script_yy -b grub_script $(srcdir)/script/parser.y diff --git a/util/bin2h.c b/util/bin2h.c new file mode 100644 index 000000000..e93a89032 --- /dev/null +++ b/util/bin2h.c @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include + +int +main (int argc, char *argv[]) +{ + int b, i; + char *sym; + unsigned int len; + + if (argc != 3) + { + fprintf (stderr, "Usage: %s symbol_name length\n", argv[0]); + exit (1); + } + + sym = argv[1]; + len = atoi (argv[2]); + + b = getchar (); + if (b == EOF) + goto abort; + + printf ("/* THIS CHUNK OF BYTES IS AUTOMATICALY GENERATED */\n" + "unsigned char %s[%u] =\n{\n", sym, len); + + while (1) + { + printf ("0x%02x", b); + + b = getchar (); + if (b == EOF) + goto end; + + for (i = 0; i < 16 - 1; i++) + { + printf (", 0x%02x", b); + + b = getchar (); + if (b == EOF) + goto end; + } + + printf (",\n"); + } + +end: + printf ("\n};\n"); + +abort: + exit (0); +} From f40f890a124031ae3b2b3d02c12a8622625f4484 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Mon, 11 Jan 2010 00:03:42 +0100 Subject: [PATCH 206/738] Eliminate obnoxious length parameter --- util/bin2h.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/util/bin2h.c b/util/bin2h.c index e93a89032..4139b52eb 100644 --- a/util/bin2h.c +++ b/util/bin2h.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Free Software Foundation, Inc. + * Copyright (C) 2008,2010 Free Software Foundation, Inc. * * GRUB is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -23,23 +23,21 @@ main (int argc, char *argv[]) { int b, i; char *sym; - unsigned int len; - if (argc != 3) + if (argc != 2) { - fprintf (stderr, "Usage: %s symbol_name length\n", argv[0]); + fprintf (stderr, "Usage: %s symbol_name\n", argv[0]); exit (1); } sym = argv[1]; - len = atoi (argv[2]); b = getchar (); if (b == EOF) goto abort; printf ("/* THIS CHUNK OF BYTES IS AUTOMATICALY GENERATED */\n" - "unsigned char %s[%u] =\n{\n", sym, len); + "unsigned char %s[] =\n{\n", sym); while (1) { From 26ba5c22623cce2dd1adc94a5aad950cace26062 Mon Sep 17 00:00:00 2001 From: carles Date: Sun, 10 Jan 2010 23:33:57 +0000 Subject: [PATCH 207/738] 2010-01-10 Carles Pina i Estany * font/font.c: Include `ascii.h'. (ASCII_BITMAP_SIZE): New macro. (ascii_font_glyph): Define. (ascii_glyph_lookup): New function. (grub_font_get_string_width): Change comment. If glyph not found, use ascii_glyph_lookup. (grub_font_get_glyph_with_fallback): If glyph not available returns ascii_glyph_lookup. * util/grub-mkfont.c (file_formats): New enum. (options): Add `ascii-bitmaps' new option. (usage): Add `asii-bitmaps' new option. (write_font_ascii_bitmap): New function. (write_font): Rename to ... (write_font_p2): ... this. Remove print_glyphs call. (main): Use file_format. Implement code for ranges if ascii-bitmaps is used. Call print_glyphs. * Makefile.in (pkgdata_DATA): Add `font/ascii.h'. --- ChangeLog.kernel-font | 20 +++++++++++ Makefile.in | 8 ++++- font/font.c | 61 +++++++++++++++++++++++++++++++--- util/grub-mkfont.c | 77 +++++++++++++++++++++++++++++++++++++++---- 4 files changed, 154 insertions(+), 12 deletions(-) diff --git a/ChangeLog.kernel-font b/ChangeLog.kernel-font index c21696db9..9933c21a5 100644 --- a/ChangeLog.kernel-font +++ b/ChangeLog.kernel-font @@ -1,3 +1,23 @@ +2010-01-10 Carles Pina i Estany + + * font/font.c: Include `ascii.h'. + (ASCII_BITMAP_SIZE): New macro. + (ascii_font_glyph): Define. + (ascii_glyph_lookup): New function. + (grub_font_get_string_width): Change comment. If glyph not found, use + ascii_glyph_lookup. + (grub_font_get_glyph_with_fallback): If glyph not available returns + ascii_glyph_lookup. + * util/grub-mkfont.c (file_formats): New enum. + (options): Add `ascii-bitmaps' new option. + (usage): Add `asii-bitmaps' new option. + (write_font_ascii_bitmap): New function. + (write_font): Rename to ... + (write_font_p2): ... this. Remove print_glyphs call. + (main): Use file_format. Implement code for ranges if ascii-bitmaps is + used. Call print_glyphs. + * Makefile.in (pkgdata_DATA): Add `font/ascii.h'. + 2010-01-10 Robert Millan * conf/common.rmk (bin_UTILITIES): Add `grub-bin2h'. diff --git a/Makefile.in b/Makefile.in index 79045ee64..f30264b00 100644 --- a/Makefile.in +++ b/Makefile.in @@ -234,7 +234,7 @@ else ifeq ($(enable_grub_mkfont),yes) -pkgdata_DATA += unicode.pf2 ascii.pf2 +pkgdata_DATA += unicode.pf2 ascii.pf2 font/ascii.h # Arrows and lines are needed to draw the menu, so we always include them UNICODE_ARROWS=0x2190-0x2193 @@ -245,6 +245,12 @@ unicode.pf2: $(FONT_SOURCE) grub-mkfont ascii.pf2: $(FONT_SOURCE) grub-mkfont $(builddir)/grub-mkfont -o $@ $(FONT_SOURCE) -r 0x0-0x7f,$(UNICODE_ARROWS),$(UNICODE_LINES) + +font/ascii.bitmaps: $(FONT_SOURCE) grub-mkfont + $(builddir)/grub-mkfont --ascii-bitmaps -o $@ $(FONT_SOURCE) + +font/ascii.h: font/ascii.bitmaps grub-bin2h + $(builddir)/grub-bin2h ascii_bitmaps 2048 < font/ascii.bitmaps > font/ascii.h endif endif diff --git a/font/font.c b/font/font.c index 44827a9a1..9819958e3 100644 --- a/font/font.c +++ b/font/font.c @@ -17,6 +17,8 @@ * along with GRUB. If not, see . */ +#define GENERATE_ASCII + #include #include #include @@ -27,6 +29,10 @@ #include #include +#ifdef GENERATE_ASCII +#include "ascii.h" +#endif + #ifndef FONT_DEBUG #define FONT_DEBUG 0 #endif @@ -43,6 +49,7 @@ struct char_index_entry #define FONT_WEIGHT_NORMAL 100 #define FONT_WEIGHT_BOLD 200 +#define ASCII_BITMAP_SIZE 16 struct grub_font { @@ -129,6 +136,48 @@ static struct grub_font null_font; /* Flag to ensure module is initialized only once. */ static grub_uint8_t font_loader_initialized; +#ifdef GENERATE_ASCII +static struct grub_font_glyph *ascii_font_glyph[0x80]; +#endif + +static struct grub_font_glyph * +ascii_glyph_lookup (grub_uint32_t code) +{ +#ifdef GENERATE_ASCII + static int ascii_failback_initialized = 0; + + if (code >= 0x80) + return unknown_glyph; + + if (ascii_failback_initialized == 0) + { + int current; + for (current = 0; current < 0x80; current++) + { + ascii_font_glyph[current] = grub_malloc(sizeof(struct grub_font_glyph) + + ASCII_BITMAP_SIZE); + + ascii_font_glyph[current]->width = 8; + ascii_font_glyph[current]->height = 16; + ascii_font_glyph[current]->offset_x = 0; + ascii_font_glyph[current]->offset_y = -2; + ascii_font_glyph[current]->device_width = 8; + + grub_memcpy (ascii_font_glyph[current]->bitmap, + &ascii_bitmaps[(0x7f - current) * ASCII_BITMAP_SIZE], + ASCII_BITMAP_SIZE); + } + + ascii_failback_initialized = 1; + } + + return ascii_font_glyph[code]; +#else + (void) code; + return unknown_glyph; +#endif +} + void grub_font_loader_init (void) { @@ -865,15 +914,17 @@ grub_font_get_string_width (grub_font_t font, const char *str) } /* Get the glyph for FONT corresponding to the Unicode code point CODE. - Returns a pointer to an glyph indicating there is no glyph available - if CODE does not exist in the font. The glyphs are cached once loaded. */ + Returns the ASCII glyph for the code if no other fonts are available. + The glyphs are cached once loaded. */ struct grub_font_glyph * grub_font_get_glyph (grub_font_t font, grub_uint32_t code) { struct grub_font_glyph *glyph; glyph = grub_font_get_glyph_internal (font, code); if (glyph == 0) - glyph = unknown_glyph; + { + glyph = ascii_glyph_lookup (code); + } return glyph; } @@ -968,8 +1019,8 @@ grub_font_get_glyph_with_fallback (grub_font_t font, grub_uint32_t code) if (best_glyph) return best_glyph; else - /* Glyph not available in any font. Return unknown glyph. */ - return unknown_glyph; + /* Glyph not available in any font. Return ASCII failback. */ + return ascii_glyph_lookup (code); } diff --git a/util/grub-mkfont.c b/util/grub-mkfont.c index 3d1c6faac..e8e712f2c 100644 --- a/util/grub-mkfont.c +++ b/util/grub-mkfont.c @@ -49,6 +49,12 @@ struct grub_glyph_info grub_uint8_t bitmap[0]; }; +enum file_formats +{ + PF2, + ASCII_BITMAPS +}; + #define GRUB_FONT_FLAG_BOLD 1 #define GRUB_FONT_FLAG_NOBITMAP 2 #define GRUB_FONT_FLAG_NOHINTING 4 @@ -87,6 +93,7 @@ static struct option options[] = {"help", no_argument, 0, 'h'}, {"version", no_argument, 0, 'V'}, {"verbose", no_argument, 0, 'v'}, + {"ascii-bitmaps", no_argument, 0, 0x102}, {0, 0, 0, 0} }; @@ -102,6 +109,7 @@ usage (int status) Usage: %s [OPTIONS] FONT_FILES\n\ \nOptions:\n\ -o, --output=FILE_NAME set output file name\n\ + --ascii-bitmaps save only the ASCII bitmaps\n\ -i, --index=N set face index\n\ -r, --range=A-B[,C-D] set font range\n\ -n, --name=S set font family name\n\ @@ -337,7 +345,39 @@ print_glyphs (struct grub_font_info *font_info) } void -write_font (struct grub_font_info *font_info, char *output_file) +write_font_ascii_bitmap (struct grub_font_info *font_info, char *output_file) +{ + FILE *file; + struct grub_glyph_info *glyph; + int num; + + file = fopen (output_file, "wb"); + if (! file) + grub_util_error ("Can\'t write to file %s.", output_file); + + int correct_size; + for (glyph = font_info->glyph, num = 0; glyph; glyph = glyph->next, num++) + { + correct_size = 1; + if (glyph->width != 8 || glyph->height != 16) + { + // printf ("Width or height from glyph U+%04x not supported, skipping.\n", glyph->char_code); + correct_size = 0; + } + int row; + for (row = 0; row < glyph->height; row++) + { + if (correct_size) + fwrite (&glyph->bitmap[row], sizeof(glyph->bitmap[row]), 1, file); + else + fwrite (&correct_size, 1, 1, file); + } + } + fclose (file); +} + +void +write_font_pf2 (struct grub_font_info *font_info, char *output_file) { FILE *file; grub_uint32_t leng, data; @@ -473,9 +513,6 @@ write_font (struct grub_font_info *font_info, char *output_file) grub_util_write_image ((char *) &cur->bitmap[0], cur->bitmap_size, file); } - if (font_verbosity > 1) - print_glyphs (font_info); - fclose (file); } @@ -487,6 +524,7 @@ main (int argc, char *argv[]) int font_index = 0; int font_size = 0; char *output_file = NULL; + enum file_formats file_format = PF2; memset (&font_info, 0, sizeof (font_info)); @@ -552,7 +590,7 @@ main (int argc, char *argv[]) font_info.ranges = xrealloc (font_info.ranges, (font_info.num_range + GRUB_FONT_RANGE_BLOCK) * - sizeof (int) * 2); + sizeof (grub_uint32_t) * 2); font_info.ranges[font_info.num_range * 2] = a; font_info.ranges[font_info.num_range * 2 + 1] = b; @@ -591,12 +629,33 @@ main (int argc, char *argv[]) font_verbosity++; break; + case 0x102: + file_format = ASCII_BITMAPS; + break; + default: usage (1); break; } } + if (file_format == ASCII_BITMAPS && font_info.num_range > 0) + { + grub_util_error ("Option --ascii-bitmaps doesn't accept ranges (use ASCII)."); + return 1; + } + + else if (file_format == ASCII_BITMAPS) + { + font_info.ranges = xrealloc (font_info.ranges, + GRUB_FONT_RANGE_BLOCK * + sizeof (grub_uint32_t) * 2); + + font_info.ranges[0] = (grub_uint32_t) 0x00; + font_info.ranges[1] = (grub_uint32_t) 0x7f; + font_info.num_range = 1; + } + if (! output_file) grub_util_error ("No output file is specified."); @@ -638,7 +697,13 @@ main (int argc, char *argv[]) FT_Done_FreeType (ft_lib); - write_font (&font_info, output_file); + if (file_format == PF2) + write_font_pf2 (&font_info, output_file); + else if (file_format == ASCII_BITMAPS) + write_font_ascii_bitmap (&font_info, output_file); + + if (font_verbosity > 1) + print_glyphs (&font_info); return 0; } From d1fb0f65de960a99c3c1d918d1fb69167456b4d8 Mon Sep 17 00:00:00 2001 From: carles Date: Mon, 11 Jan 2010 00:10:38 +0000 Subject: [PATCH 208/738] 2010-01-10 Carles Pina i Estany * font/font.c: Update copyright years. * util/grub-mkfont.c (write_font_ascii_bitmap): Change comment format. --- ChangeLog.kernel-font | 5 +++++ font/font.c | 2 +- util/grub-mkfont.c | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog.kernel-font b/ChangeLog.kernel-font index 9933c21a5..e7ca2a374 100644 --- a/ChangeLog.kernel-font +++ b/ChangeLog.kernel-font @@ -1,3 +1,8 @@ +2010-01-10 Carles Pina i Estany + + * font/font.c: Update copyright years. + * util/grub-mkfont.c (write_font_ascii_bitmap): Change comment format. + 2010-01-10 Carles Pina i Estany * font/font.c: Include `ascii.h'. diff --git a/font/font.c b/font/font.c index 9819958e3..a00aef94f 100644 --- a/font/font.c +++ b/font/font.c @@ -1,7 +1,7 @@ /* font.c - Font API and font file loader. */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2003,2005,2006,2007,2008,2009 Free Software Foundation, Inc. + * Copyright (C) 2003,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc. * * GRUB is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/util/grub-mkfont.c b/util/grub-mkfont.c index e8e712f2c..3dd0bafdd 100644 --- a/util/grub-mkfont.c +++ b/util/grub-mkfont.c @@ -361,7 +361,7 @@ write_font_ascii_bitmap (struct grub_font_info *font_info, char *output_file) correct_size = 1; if (glyph->width != 8 || glyph->height != 16) { - // printf ("Width or height from glyph U+%04x not supported, skipping.\n", glyph->char_code); + /* printf ("Width or height from glyph U+%04x not supported, skipping.\n", glyph->char_code); */ correct_size = 0; } int row; From 502dc3e5c4e36ac4c6fc3112c8afad79ab123342 Mon Sep 17 00:00:00 2001 From: Felix Zielcke Date: Mon, 11 Jan 2010 11:30:47 +0100 Subject: [PATCH 209/738] 2010-01-11 Felix Zielcke * po/POTFILES: Replace `term/i386/pc/serial.c' with `term/serial.c'. --- ChangeLog.mips | 4 ++++ po/POTFILES | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog.mips b/ChangeLog.mips index d12b0d180..1bbe1c273 100644 --- a/ChangeLog.mips +++ b/ChangeLog.mips @@ -1,3 +1,7 @@ +2010-01-11 Felix Zielcke + + * po/POTFILES: Replace `term/i386/pc/serial.c' with `term/serial.c'. + 2009-12-10 Robert Millan * include/grub/mips/libgcc.h: Only export symbols for functions diff --git a/po/POTFILES b/po/POTFILES index d6b20fef6..04a3516fa 100644 --- a/po/POTFILES +++ b/po/POTFILES @@ -75,7 +75,7 @@ normal/menu_entry.c normal/menu_text.c normal/misc.c -term/i386/pc/serial.c +term/serial.c util/grub-mkrawimage.c util/i386/pc/grub-setup.c From 3b6f7ab75d3c4aa8bc59d56b71284ece7c809b5f Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Mon, 11 Jan 2010 19:19:24 +0100 Subject: [PATCH 210/738] Add missing menuviewer initialization. --- util/grub.d/00_header.in | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/util/grub.d/00_header.in b/util/grub.d/00_header.in index da394783a..306bef3c3 100644 --- a/util/grub.d/00_header.in +++ b/util/grub.d/00_header.in @@ -1,7 +1,7 @@ #! /bin/sh -e # grub-mkconfig helper script. -# Copyright (C) 2006,2007,2008,2009 Free Software Foundation, Inc. +# Copyright (C) 2006,2007,2008,2009,2010 Free Software Foundation, Inc. # # GRUB is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -98,8 +98,11 @@ if [ x$GRUB_THEME != x ] && [ -f $GRUB_THEME ] \ && is_path_readable_by_grub $GRUB_THEME; then echo "Found theme: $GRUB_THEME" >&2 prepare_grub_to_access_device `${grub_probe} --target=device $GRUB_THEME` - echo "insmod gfxmenu" - echo "set theme=(\$root)/`make_system_path_relative_to_its_root $GRUB_THEME`" + cat << EOF +insmod gfxmenu +set theme=(\$root)`make_system_path_relative_to_its_root $GRUB_THEME` +set menuviewer=gfxmenu +EOF fi cat << EOF fi From d0230c211973d781cb1fe9eefa6157290f09916e Mon Sep 17 00:00:00 2001 From: carles Date: Mon, 11 Jan 2010 20:43:11 +0000 Subject: [PATCH 211/738] 2010-01-11 Carles Pina i Estany * font/font.c (GENERATE_ASCII): Change the name to USE_ASCII_FAILBACK. By default: disabled. * Makefile.in (font/ascii.h): Remove the non-needed grub/bin2h size parameter. --- ChangeLog.kernel-font | 7 +++++++ Makefile.in | 2 +- font/font.c | 8 ++++---- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/ChangeLog.kernel-font b/ChangeLog.kernel-font index e7ca2a374..36c3b695b 100644 --- a/ChangeLog.kernel-font +++ b/ChangeLog.kernel-font @@ -1,3 +1,10 @@ +2010-01-11 Carles Pina i Estany + + * font/font.c (GENERATE_ASCII): Change the name to USE_ASCII_FAILBACK. + By default: disabled. + * Makefile.in (font/ascii.h): Remove the non-needed grub/bin2h size + parameter. + 2010-01-10 Carles Pina i Estany * font/font.c: Update copyright years. diff --git a/Makefile.in b/Makefile.in index f30264b00..ff59c4efd 100644 --- a/Makefile.in +++ b/Makefile.in @@ -250,7 +250,7 @@ font/ascii.bitmaps: $(FONT_SOURCE) grub-mkfont $(builddir)/grub-mkfont --ascii-bitmaps -o $@ $(FONT_SOURCE) font/ascii.h: font/ascii.bitmaps grub-bin2h - $(builddir)/grub-bin2h ascii_bitmaps 2048 < font/ascii.bitmaps > font/ascii.h + $(builddir)/grub-bin2h ascii_bitmaps < font/ascii.bitmaps > font/ascii.h endif endif diff --git a/font/font.c b/font/font.c index a00aef94f..7aef1b163 100644 --- a/font/font.c +++ b/font/font.c @@ -17,7 +17,7 @@ * along with GRUB. If not, see . */ -#define GENERATE_ASCII +//#define USE_ASCII_FAILBACK 0 #include #include @@ -29,7 +29,7 @@ #include #include -#ifdef GENERATE_ASCII +#ifdef USE_ASCII_FAILBACK #include "ascii.h" #endif @@ -136,14 +136,14 @@ static struct grub_font null_font; /* Flag to ensure module is initialized only once. */ static grub_uint8_t font_loader_initialized; -#ifdef GENERATE_ASCII +#ifdef USE_ASCII_FAILBACK static struct grub_font_glyph *ascii_font_glyph[0x80]; #endif static struct grub_font_glyph * ascii_glyph_lookup (grub_uint32_t code) { -#ifdef GENERATE_ASCII +#ifdef USE_ASCII_FAILBACK static int ascii_failback_initialized = 0; if (code >= 0x80) From bd719e5a73757956671a640c5897a842a739d773 Mon Sep 17 00:00:00 2001 From: carles Date: Tue, 12 Jan 2010 20:37:45 +0000 Subject: [PATCH 212/738] 2010-01-12 Carles Pina i Estany * Makefile.in (DUSE_ASCII_FAILBACK): New macro. --- ChangeLog.kernel-font | 4 ++++ Makefile.in | 2 ++ 2 files changed, 6 insertions(+) diff --git a/ChangeLog.kernel-font b/ChangeLog.kernel-font index 36c3b695b..69e3dafe8 100644 --- a/ChangeLog.kernel-font +++ b/ChangeLog.kernel-font @@ -1,3 +1,7 @@ +2010-01-12 Carles Pina i Estany + + * Makefile.in (DUSE_ASCII_FAILBACK): New macro. + 2010-01-11 Carles Pina i Estany * font/font.c (GENERATE_ASCII): Change the name to USE_ASCII_FAILBACK. diff --git a/Makefile.in b/Makefile.in index ff59c4efd..c551a0d79 100644 --- a/Makefile.in +++ b/Makefile.in @@ -251,6 +251,8 @@ font/ascii.bitmaps: $(FONT_SOURCE) grub-mkfont font/ascii.h: font/ascii.bitmaps grub-bin2h $(builddir)/grub-bin2h ascii_bitmaps < font/ascii.bitmaps > font/ascii.h + +TARGET_CFLAGS += -DUSE_ASCII_FAILBACK=1 endif endif From 57e41c71bc8af58384bccbfa9090704e02e33157 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 14 Jan 2010 15:54:14 +0100 Subject: [PATCH 213/738] multiboot video support --- ChangeLog.mbivid | 24 +++++ include/grub/multiboot.h | 2 + include/grub/video.h | 12 +++ include/multiboot.h | 38 ++++++- include/multiboot2.h | 38 ++++++- loader/i386/multiboot.c | 33 +++++- loader/i386/multiboot_mbi.c | 194 +++++++++++++++++++++++++++++++++++- video/efi_gop.c | 1 + video/efi_uga.c | 1 + video/i386/pc/vbe.c | 1 + video/video.c | 8 ++ 11 files changed, 345 insertions(+), 7 deletions(-) create mode 100644 ChangeLog.mbivid diff --git a/ChangeLog.mbivid b/ChangeLog.mbivid new file mode 100644 index 000000000..da4fa3c88 --- /dev/null +++ b/ChangeLog.mbivid @@ -0,0 +1,24 @@ +2010-01-14 Vladimir Serbinenko + + Video multiboot support. + + * include/grub/multiboot.h (grub_multiboot_set_accepts_video): + New prototype. + * include/grub/video.h (grub_video_driver_id): New type. + (grub_video_adapter): New member 'id'. All users updated. + (grub_video_get_driver_id): New proto. + * include/multiboot.h: Resynced with multiboot specification. + * include/multiboot2.h: Likewise. + * loader/i386/multiboot.c (UNSUPPORTED_FLAGS): Support video flags. + (grub_multiboot): Parse MULTIBOOT_VIDEO_MODE fields. + * loader/i386/multiboot_mbi.c (DEFAULT_VIDEO_MODE): New constant. + (HAS_VGA_TEXT): Likewise. + (HAS_VBE): Likewise. + (accepts_video): New variable. + (grub_multiboot_set_accepts_video): New function. + (grub_multiboot_get_mbi_size): Account for video structures. + (set_video_mode): New function. + (fill_vbe_info) [HAS_VBE]: Likewise. + (retrieve_video_parameters): Likewise. + (grub_multiboot_make_mbi): Fill video fields. + * video/video.c (grub_video_get_driver_id): New function. diff --git a/include/grub/multiboot.h b/include/grub/multiboot.h index f9edb0c59..665292e33 100644 --- a/include/grub/multiboot.h +++ b/include/grub/multiboot.h @@ -35,6 +35,8 @@ void grub_multiboot (int argc, char *argv[]); void grub_module (int argc, char *argv[]); +void grub_multiboot_set_accepts_video (int val); + grub_size_t grub_multiboot_get_mbi_size (void); grub_err_t grub_multiboot_make_mbi (void *orig, grub_uint32_t dest, grub_off_t buf_off, grub_size_t bufsize); diff --git a/include/grub/video.h b/include/grub/video.h index 4145db465..437c98eb9 100644 --- a/include/grub/video.h +++ b/include/grub/video.h @@ -159,10 +159,19 @@ struct grub_video_palette_data grub_uint8_t a; /* Reserved bits value (0-255). */ }; +typedef enum grub_video_driver_id + { + GRUB_VIDEO_DRIVER_NONE, + GRUB_VIDEO_DRIVER_VBE, + GRUB_VIDEO_DRIVER_EFI_UGA, + GRUB_VIDEO_DRIVER_EFI_GOP + } grub_video_driver_id_t; + struct grub_video_adapter { /* The video adapter name. */ const char *name; + grub_video_driver_id_t id; /* Initialize the video adapter. */ grub_err_t (*init) (void); @@ -310,4 +319,7 @@ grub_err_t grub_video_set_mode (const char *modestring, int NESTED_FUNC_ATTR (*hook) (grub_video_adapter_t p, struct grub_video_mode_info *mode_info)); +grub_video_driver_id_t +grub_video_get_driver_id (void); + #endif /* ! GRUB_VIDEO_HEADER */ diff --git a/include/multiboot.h b/include/multiboot.h index da7afd9b3..460347d22 100644 --- a/include/multiboot.h +++ b/include/multiboot.h @@ -85,10 +85,12 @@ #define MULTIBOOT_INFO_APM_TABLE 0x00000400 /* Is there video information? */ -#define MULTIBOOT_INFO_VIDEO_INFO 0x00000800 +#define MULTIBOOT_INFO_VBE_INFO 0x00000800 +#define MULTIBOOT_INFO_FRAMEBUFFER_INFO 0x00001000 #ifndef ASM_FILE +typedef unsigned char multiboot_uint8_t; typedef unsigned short multiboot_uint16_t; typedef unsigned int multiboot_uint32_t; typedef unsigned long long multiboot_uint64_t; @@ -187,9 +189,43 @@ struct multiboot_info multiboot_uint16_t vbe_interface_seg; multiboot_uint16_t vbe_interface_off; multiboot_uint16_t vbe_interface_len; + + multiboot_uint64_t framebuffer_addr; + multiboot_uint32_t framebuffer_pitch; + multiboot_uint32_t framebuffer_width; + multiboot_uint32_t framebuffer_height; + multiboot_uint8_t framebuffer_bpp; + multiboot_uint8_t framebuffer_type; + union + { + struct + { + multiboot_uint32_t framebuffer_palette_addr; + multiboot_uint16_t framebuffer_palette_num_colors; + }; + struct + { + multiboot_uint8_t framebuffer_red_field_position; + multiboot_uint8_t framebuffer_red_mask_size; + multiboot_uint8_t framebuffer_green_field_position; + multiboot_uint8_t framebuffer_green_mask_size; + multiboot_uint8_t framebuffer_blue_field_position; + multiboot_uint8_t framebuffer_blue_mask_size; + }; + }; }; typedef struct multiboot_info multiboot_info_t; +struct multiboot_color +{ + multiboot_uint8_t red; + multiboot_uint8_t green; + multiboot_uint8_t blue; +}; + +#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0 +#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB 1 + struct multiboot_mmap_entry { multiboot_uint32_t size; diff --git a/include/multiboot2.h b/include/multiboot2.h index 0488849d7..8bcf5a7e4 100644 --- a/include/multiboot2.h +++ b/include/multiboot2.h @@ -85,10 +85,12 @@ #define MULTIBOOT_INFO_APM_TABLE 0x00000400 /* Is there video information? */ -#define MULTIBOOT_INFO_VIDEO_INFO 0x00000800 +#define MULTIBOOT_INFO_VBE_INFO 0x00000800 +#define MULTIBOOT_INFO_FRAMEBUFFER_INFO 0x00001000 #ifndef ASM_FILE +typedef unsigned char multiboot_uint8_t; typedef unsigned short multiboot_uint16_t; typedef unsigned int multiboot_uint32_t; typedef unsigned long long multiboot_uint64_t; @@ -187,9 +189,43 @@ struct multiboot_info multiboot_uint16_t vbe_interface_seg; multiboot_uint16_t vbe_interface_off; multiboot_uint16_t vbe_interface_len; + + multiboot_uint64_t framebuffer_addr; + multiboot_uint32_t framebuffer_pitch; + multiboot_uint32_t framebuffer_width; + multiboot_uint32_t framebuffer_height; + multiboot_uint8_t framebuffer_bpp; + multiboot_uint8_t framebuffer_type; + union + { + struct + { + multiboot_uint32_t framebuffer_palette_addr; + multiboot_uint16_t framebuffer_palette_num_colors; + }; + struct + { + multiboot_uint8_t framebuffer_red_field_position; + multiboot_uint8_t framebuffer_red_mask_size; + multiboot_uint8_t framebuffer_green_field_position; + multiboot_uint8_t framebuffer_green_mask_size; + multiboot_uint8_t framebuffer_blue_field_position; + multiboot_uint8_t framebuffer_blue_mask_size; + }; + }; }; typedef struct multiboot_info multiboot_info_t; +struct multiboot_color +{ + multiboot_uint8_t red; + multiboot_uint8_t green; + multiboot_uint8_t blue; +}; + +#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0 +#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB 1 + struct multiboot_mmap_entry { multiboot_uint32_t size; diff --git a/loader/i386/multiboot.c b/loader/i386/multiboot.c index 5dc304117..15f9977c9 100644 --- a/loader/i386/multiboot.c +++ b/loader/i386/multiboot.c @@ -20,7 +20,6 @@ /* * FIXME: The following features from the Multiboot specification still * need to be implemented: - * - VBE support * - symbol table * - drives table * - ROM configuration table @@ -28,13 +27,11 @@ */ /* The bits in the required part of flags field we don't support. */ -#define UNSUPPORTED_FLAGS 0x0000fffc +#define UNSUPPORTED_FLAGS 0x0000fff8 #include #include #include -#include -#include #include #include #include @@ -232,6 +229,34 @@ grub_multiboot (int argc, char *argv[]) else if (grub_multiboot_load_elf (file, buffer) != GRUB_ERR_NONE) goto fail; + if (header->flags & MULTIBOOT_VIDEO_MODE) + { + switch (header->mode_type) + { + case 1: + grub_env_set ("gfxpayload", "text"); + break; + + case 0: + { + char buf[sizeof ("XXXXXXXXXXxXXXXXXXXXXxXXXXXXXXXX,XXXXXXXXXXxXXXXXXXXXX,auto")]; + if (header->depth && header->width && header->height) + grub_sprintf (buf, "%dx%dx%d,%dx%d,auto", header->width, + header->height, header->depth, header->width, + header->height); + else if (header->width && header->height) + grub_sprintf (buf, "%dx%d,auto", header->width, header->height); + else + grub_sprintf (buf, "auto"); + + grub_env_set ("gfxpayload", buf); + break; + } + } + } + + grub_multiboot_set_accepts_video (!!(header->flags & MULTIBOOT_VIDEO_MODE)); + grub_multiboot_set_bootdev (); grub_loader_set (grub_multiboot_boot, grub_multiboot_unload, 0); diff --git a/loader/i386/multiboot_mbi.c b/loader/i386/multiboot_mbi.c index 58802d44c..f362b800d 100644 --- a/loader/i386/multiboot_mbi.c +++ b/loader/i386/multiboot_mbi.c @@ -29,6 +29,18 @@ #include #include #include +#include + +#if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_QEMU) +#include +#define DEFAULT_VIDEO_MODE "text" +#define HAS_VGA_TEXT 1 +#define HAS_VBE 1 +#else +#define DEFAULT_VIDEO_MODE "auto" +#define HAS_VGA_TEXT 0 +#define HAS_VBE 0 +#endif struct module { @@ -46,6 +58,13 @@ static unsigned modcnt; static char *cmdline = NULL; static grub_uint32_t bootdev; static int bootdev_set; +static int accepts_video; + +void +grub_multiboot_set_accepts_video (int val) +{ + accepts_video = val; +} /* Return the length of the Multiboot mmap that will be needed to allocate our platform's map. */ @@ -73,7 +92,12 @@ grub_multiboot_get_mbi_size (void) { return sizeof (struct multiboot_info) + ALIGN_UP (cmdline_size, 4) + modcnt * sizeof (struct multiboot_mod_list) + total_modcmd - + ALIGN_UP (sizeof(PACKAGE_STRING), 4) + grub_get_multiboot_mmap_len (); + + ALIGN_UP (sizeof(PACKAGE_STRING), 4) + grub_get_multiboot_mmap_len () +#if HAS_VBE + + sizeof (struct grub_vbe_info_block) + + sizeof (struct grub_vbe_mode_info_block) +#endif + + 256 * sizeof (struct multiboot_color); } /* Fill previously allocated Multiboot mmap. */ @@ -106,6 +130,160 @@ grub_fill_multiboot_mmap (struct multiboot_mmap_entry *first_entry) grub_mmap_iterate (hook); } +static grub_err_t +set_video_mode (void) +{ + grub_err_t err; + const char *modevar; + + if (accepts_video || !HAS_VGA_TEXT) + { + modevar = grub_env_get ("gfxpayload"); + if (! modevar || *modevar == 0) + err = grub_video_set_mode (DEFAULT_VIDEO_MODE, 0); + else + { + char *tmp; + tmp = grub_malloc (grub_strlen (modevar) + + sizeof (DEFAULT_VIDEO_MODE) + 1); + if (! tmp) + return grub_errno; + grub_sprintf (tmp, "%s;" DEFAULT_VIDEO_MODE, modevar); + err = grub_video_set_mode (tmp, 0); + grub_free (tmp); + } + } + else + err = grub_video_set_mode ("text", 0); + + return err; +} + +#if HAS_VBE +static grub_err_t +fill_vbe_info (struct multiboot_info *mbi, grub_uint8_t *ptrorig, + grub_uint32_t ptrdest) +{ + grub_vbe_status_t status; + grub_uint32_t vbe_mode; + void *scratch = (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR; + + status = grub_vbe_bios_get_controller_info (scratch); + if (status != GRUB_VBE_STATUS_OK) + return grub_error (GRUB_ERR_IO, "Can't get controller info."); + + mbi->vbe_control_info = ptrdest; + grub_memcpy (ptrorig, scratch, sizeof (struct grub_vbe_info_block)); + ptrorig += sizeof (struct grub_vbe_info_block); + ptrdest += sizeof (struct grub_vbe_info_block); + + status = grub_vbe_bios_get_mode (scratch); + vbe_mode = *(grub_uint32_t *) scratch; + if (status != GRUB_VBE_STATUS_OK) + return grub_error (GRUB_ERR_IO, "Can't get VBE mode."); + mbi->vbe_mode = vbe_mode; + + status = grub_vbe_bios_get_mode_info (vbe_mode, scratch); + if (status != GRUB_VBE_STATUS_OK) + return grub_error (GRUB_ERR_IO, "Can't get mode info."); + mbi->vbe_mode_info = ptrdest; + grub_memcpy (ptrorig, scratch, sizeof (struct grub_vbe_mode_info_block)); + ptrorig += sizeof (struct grub_vbe_mode_info_block); + ptrdest += sizeof (struct grub_vbe_mode_info_block); + + /* FIXME: retrieve those. */ + mbi->vbe_interface_seg = 0; + mbi->vbe_interface_off = 0; + mbi->vbe_interface_len = 0; + + mbi->flags |= MULTIBOOT_INFO_VBE_INFO; + + return GRUB_ERR_NONE; +} +#endif + +static grub_err_t +retrieve_video_parameters (struct multiboot_info *mbi, + grub_uint8_t *ptrorig, grub_uint32_t ptrdest) +{ + grub_err_t err; + struct grub_video_mode_info mode_info; + void *framebuffer; +#if HAS_VBE + int vbe_active; +#endif + struct grub_video_palette_data palette[256]; + + err = set_video_mode (); + if (err) + return err; + + grub_video_get_palette (0, ARRAY_SIZE (palette), palette); + +#if HAS_VBE + { + grub_video_driver_id_t driv_id; + driv_id = grub_video_get_driver_id (); + + vbe_active = ((driv_id == GRUB_VIDEO_DRIVER_VBE) + || ((driv_id == GRUB_VIDEO_DRIVER_NONE) && HAS_VGA_TEXT)); + } +#endif + + err = grub_video_get_info_and_fini (&mode_info, &framebuffer); + if (err) + return err; + + mbi->framebuffer_addr = (grub_addr_t) framebuffer; + mbi->framebuffer_pitch = mode_info.pitch; + + mbi->framebuffer_width = mode_info.width; + mbi->framebuffer_height = mode_info.height; + + mbi->framebuffer_bpp = mode_info.bpp; + + if (mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) + { + struct multiboot_color *mb_palette; + unsigned i; + mbi->framebuffer_type = MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED; + mbi->framebuffer_palette_addr = ptrdest; + mbi->framebuffer_palette_num_colors = mode_info.number_of_colors; + if (mbi->framebuffer_palette_num_colors > ARRAY_SIZE (palette)) + mbi->framebuffer_palette_num_colors = ARRAY_SIZE (palette); + mb_palette = (struct multiboot_color *) ptrorig; + for (i = 0; i < mbi->framebuffer_palette_num_colors; i++) + { + mb_palette[i].red = palette[i].r; + mb_palette[i].green = palette[i].g; + mb_palette[i].blue = palette[i].b; + } + ptrorig += mbi->framebuffer_palette_num_colors + * sizeof (struct multiboot_color); + ptrdest += mbi->framebuffer_palette_num_colors + * sizeof (struct multiboot_color); + } + else + { + mbi->framebuffer_type = MULTIBOOT_FRAMEBUFFER_TYPE_RGB; + mbi->framebuffer_red_field_position = mode_info.green_field_pos; + mbi->framebuffer_red_mask_size = mode_info.green_mask_size; + mbi->framebuffer_green_field_position = mode_info.green_field_pos; + mbi->framebuffer_green_mask_size = mode_info.green_mask_size; + mbi->framebuffer_blue_field_position = mode_info.blue_field_pos; + mbi->framebuffer_blue_mask_size = mode_info.blue_mask_size; + } + + mbi->flags |= MULTIBOOT_INFO_FRAMEBUFFER_INFO; + +#if HAS_VBE + if (vbe_active) + fill_vbe_info (mbi, ptrorig, ptrdest); +#endif + + return GRUB_ERR_NONE; +} + grub_err_t grub_multiboot_make_mbi (void *orig, grub_uint32_t dest, grub_off_t buf_off, grub_size_t bufsize) @@ -117,6 +295,7 @@ grub_multiboot_make_mbi (void *orig, grub_uint32_t dest, grub_off_t buf_off, unsigned i; struct module *cur; grub_size_t mmap_size; + grub_err_t err; if (bufsize < grub_multiboot_get_mbi_size ()) return grub_error (GRUB_ERR_OUT_OF_MEMORY, "mbi buffer is too small"); @@ -182,6 +361,19 @@ grub_multiboot_make_mbi (void *orig, grub_uint32_t dest, grub_off_t buf_off, mbi->flags |= MULTIBOOT_INFO_BOOTDEV; } + err = retrieve_video_parameters (mbi, ptrorig, ptrdest); + if (err) + { + grub_print_error (); + grub_errno = GRUB_ERR_NONE; + } +#if HAS_VBE + ptrorig += sizeof (struct grub_vbe_info_block); + ptrdest += sizeof (struct grub_vbe_info_block); + ptrorig += sizeof (struct grub_vbe_mode_info_block); + ptrdest += sizeof (struct grub_vbe_mode_info_block); +#endif + return GRUB_ERR_NONE; } diff --git a/video/efi_gop.c b/video/efi_gop.c index 30863c1ed..13ef0ddae 100644 --- a/video/efi_gop.c +++ b/video/efi_gop.c @@ -353,6 +353,7 @@ grub_video_gop_get_info_and_fini (struct grub_video_mode_info *mode_info, static struct grub_video_adapter grub_video_gop_adapter = { .name = "EFI GOP driver", + .id = GRUB_VIDEO_DRIVER_EFI_GOP, .init = grub_video_gop_init, .fini = grub_video_gop_fini, diff --git a/video/efi_uga.c b/video/efi_uga.c index 12ca35cde..7ef7594cc 100644 --- a/video/efi_uga.c +++ b/video/efi_uga.c @@ -300,6 +300,7 @@ grub_video_uga_get_info_and_fini (struct grub_video_mode_info *mode_info, static struct grub_video_adapter grub_video_uga_adapter = { .name = "EFI UGA driver", + .id = GRUB_VIDEO_DRIVER_EFI_UGA, .init = grub_video_uga_init, .fini = grub_video_uga_fini, diff --git a/video/i386/pc/vbe.c b/video/i386/pc/vbe.c index 17d9b3282..918bab0b0 100644 --- a/video/i386/pc/vbe.c +++ b/video/i386/pc/vbe.c @@ -557,6 +557,7 @@ grub_video_vbe_get_info_and_fini (struct grub_video_mode_info *mode_info, static struct grub_video_adapter grub_video_vbe_adapter = { .name = "VESA BIOS Extension Video Driver", + .id = GRUB_VIDEO_DRIVER_VBE, .init = grub_video_vbe_init, .fini = grub_video_vbe_fini, diff --git a/video/video.c b/video/video.c index 682bebcbf..e678c2982 100644 --- a/video/video.c +++ b/video/video.c @@ -93,6 +93,14 @@ grub_video_get_info (struct grub_video_mode_info *mode_info) return grub_video_adapter_active->get_info (mode_info); } +grub_video_driver_id_t +grub_video_get_driver_id (void) +{ + if (! grub_video_adapter_active) + return GRUB_VIDEO_DRIVER_NONE; + return grub_video_adapter_active->id; +} + /* Get information about active video mode. */ grub_err_t grub_video_get_info_and_fini (struct grub_video_mode_info *mode_info, From 885d1a8d9090fe19e05dddea39ac5e689e75a7ec Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Thu, 14 Jan 2010 20:33:10 +0000 Subject: [PATCH 214/738] Support --help and --version in grub-bin2h. --- ChangeLog.kernel-font | 2 +- conf/common.rmk | 2 +- util/bin2h.c | 66 ++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 64 insertions(+), 6 deletions(-) diff --git a/ChangeLog.kernel-font b/ChangeLog.kernel-font index 69e3dafe8..3842f9b51 100644 --- a/ChangeLog.kernel-font +++ b/ChangeLog.kernel-font @@ -34,7 +34,7 @@ used. Call print_glyphs. * Makefile.in (pkgdata_DATA): Add `font/ascii.h'. -2010-01-10 Robert Millan +2010-01-14 Robert Millan * conf/common.rmk (bin_UTILITIES): Add `grub-bin2h'. (grub_bin2h_SOURCES): New variable. diff --git a/conf/common.rmk b/conf/common.rmk index 0a67cf0cf..ee503f8b6 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -89,7 +89,7 @@ bin_UTILITIES += grub-mkrelpath grub_mkrelpath_SOURCES = gnulib/progname.c util/grub-mkrelpath.c util/misc.c bin_UTILITIES += grub-bin2h -grub_bin2h_SOURCES = util/bin2h.c +grub_bin2h_SOURCES = gnulib/progname.c util/bin2h.c # For the parser. grub_script.tab.c grub_script.tab.h: script/parser.y diff --git a/util/bin2h.c b/util/bin2h.c index 4139b52eb..5ce47f086 100644 --- a/util/bin2h.c +++ b/util/bin2h.c @@ -15,22 +15,80 @@ * along with GRUB. If not, see . */ +#include #include #include +#define _GNU_SOURCE 1 +#include + +#include "progname.h" + +static struct option options[] = + { + {"help", no_argument, 0, 'h' }, + {"version", no_argument, 0, 'V' }, + {0, 0, 0, 0 } + }; + +static void +usage (int status) +{ + if (status) + fprintf (stderr, + "Try ``%s --help'' for more information.\n", program_name); + else + printf ("\ +Usage: %s [OPTIONS] SYMBOL-NAME\n\ +\n\ + -h, --help display this message and exit\n\ + -V, --version print version information and exit\n\ +\n\ +Report bugs to <%s>.\n\ +", program_name, PACKAGE_BUGREPORT); + + exit (status); +} + int main (int argc, char *argv[]) { int b, i; char *sym; - if (argc != 2) + set_program_name (argv[0]); + + /* Check for options. */ + while (1) { - fprintf (stderr, "Usage: %s symbol_name\n", argv[0]); - exit (1); + int c = getopt_long (argc, argv, "snm:r:hVv", options, 0); + + if (c == -1) + break; + else + switch (c) + { + case 'h': + usage (0); + break; + + case 'V': + printf ("%s (%s) %s\n", program_name, PACKAGE_NAME, PACKAGE_VERSION); + return 0; + + default: + usage (1); + break; + } } - sym = argv[1]; + if (optind >= argc) + usage (1); + + if (optind + 1 != argc) + usage (1); + + sym = argv[optind]; b = getchar (); if (b == EOF) From b4f58b4aec8455d5ea0162e7b1ff163c944ab0cf Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Thu, 14 Jan 2010 22:17:05 +0100 Subject: [PATCH 215/738] Fix $srcdir != $builddir build by moving ascii.h to top dir. --- ChangeLog.kernel-font | 4 ++-- Makefile.in | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/ChangeLog.kernel-font b/ChangeLog.kernel-font index 3842f9b51..576c85904 100644 --- a/ChangeLog.kernel-font +++ b/ChangeLog.kernel-font @@ -6,7 +6,7 @@ * font/font.c (GENERATE_ASCII): Change the name to USE_ASCII_FAILBACK. By default: disabled. - * Makefile.in (font/ascii.h): Remove the non-needed grub/bin2h size + * Makefile.in (ascii.h): Remove the non-needed grub/bin2h size parameter. 2010-01-10 Carles Pina i Estany @@ -32,7 +32,7 @@ (write_font_p2): ... this. Remove print_glyphs call. (main): Use file_format. Implement code for ranges if ascii-bitmaps is used. Call print_glyphs. - * Makefile.in (pkgdata_DATA): Add `font/ascii.h'. + * Makefile.in (pkgdata_DATA): Add `ascii.h'. 2010-01-14 Robert Millan diff --git a/Makefile.in b/Makefile.in index c551a0d79..a3084c69a 100644 --- a/Makefile.in +++ b/Makefile.in @@ -234,7 +234,7 @@ else ifeq ($(enable_grub_mkfont),yes) -pkgdata_DATA += unicode.pf2 ascii.pf2 font/ascii.h +pkgdata_DATA += unicode.pf2 ascii.pf2 ascii.h # Arrows and lines are needed to draw the menu, so we always include them UNICODE_ARROWS=0x2190-0x2193 @@ -246,11 +246,11 @@ unicode.pf2: $(FONT_SOURCE) grub-mkfont ascii.pf2: $(FONT_SOURCE) grub-mkfont $(builddir)/grub-mkfont -o $@ $(FONT_SOURCE) -r 0x0-0x7f,$(UNICODE_ARROWS),$(UNICODE_LINES) -font/ascii.bitmaps: $(FONT_SOURCE) grub-mkfont +ascii.bitmaps: $(FONT_SOURCE) grub-mkfont $(builddir)/grub-mkfont --ascii-bitmaps -o $@ $(FONT_SOURCE) -font/ascii.h: font/ascii.bitmaps grub-bin2h - $(builddir)/grub-bin2h ascii_bitmaps < font/ascii.bitmaps > font/ascii.h +ascii.h: ascii.bitmaps grub-bin2h + $(builddir)/grub-bin2h ascii_bitmaps < $< > $@ TARGET_CFLAGS += -DUSE_ASCII_FAILBACK=1 endif From 017402922228e69ff88f11a3d396ee2ed03f0420 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 15 Jan 2010 15:46:59 +0100 Subject: [PATCH 216/738] Add EGA text support --- include/multiboot.h | 6 ++-- include/multiboot2.h | 6 ++-- loader/i386/multiboot_mbi.c | 69 ++++++++++++++++++++++++++----------- 3 files changed, 55 insertions(+), 26 deletions(-) diff --git a/include/multiboot.h b/include/multiboot.h index 460347d22..57c154c98 100644 --- a/include/multiboot.h +++ b/include/multiboot.h @@ -195,6 +195,9 @@ struct multiboot_info multiboot_uint32_t framebuffer_width; multiboot_uint32_t framebuffer_height; multiboot_uint8_t framebuffer_bpp; +#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0 +#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB 1 +#define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT 2 multiboot_uint8_t framebuffer_type; union { @@ -223,9 +226,6 @@ struct multiboot_color multiboot_uint8_t blue; }; -#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0 -#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB 1 - struct multiboot_mmap_entry { multiboot_uint32_t size; diff --git a/include/multiboot2.h b/include/multiboot2.h index 8bcf5a7e4..a241a70ad 100644 --- a/include/multiboot2.h +++ b/include/multiboot2.h @@ -195,6 +195,9 @@ struct multiboot_info multiboot_uint32_t framebuffer_width; multiboot_uint32_t framebuffer_height; multiboot_uint8_t framebuffer_bpp; +#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0 +#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB 1 +#define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT 2 multiboot_uint8_t framebuffer_type; union { @@ -223,9 +226,6 @@ struct multiboot_color multiboot_uint8_t blue; }; -#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0 -#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB 1 - struct multiboot_mmap_entry { multiboot_uint32_t size; diff --git a/loader/i386/multiboot_mbi.c b/loader/i386/multiboot_mbi.c index f362b800d..ddbbf3cfd 100644 --- a/loader/i386/multiboot_mbi.c +++ b/loader/i386/multiboot_mbi.c @@ -162,11 +162,12 @@ set_video_mode (void) #if HAS_VBE static grub_err_t fill_vbe_info (struct multiboot_info *mbi, grub_uint8_t *ptrorig, - grub_uint32_t ptrdest) + grub_uint32_t ptrdest, int fill_generic) { grub_vbe_status_t status; grub_uint32_t vbe_mode; void *scratch = (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR; + struct grub_vbe_mode_info_block *mode_info; status = grub_vbe_bios_get_controller_info (scratch); if (status != GRUB_VBE_STATUS_OK) @@ -180,14 +181,27 @@ fill_vbe_info (struct multiboot_info *mbi, grub_uint8_t *ptrorig, status = grub_vbe_bios_get_mode (scratch); vbe_mode = *(grub_uint32_t *) scratch; if (status != GRUB_VBE_STATUS_OK) - return grub_error (GRUB_ERR_IO, "Can't get VBE mode."); + return grub_error (GRUB_ERR_IO, "can't get VBE mode"); mbi->vbe_mode = vbe_mode; - status = grub_vbe_bios_get_mode_info (vbe_mode, scratch); - if (status != GRUB_VBE_STATUS_OK) - return grub_error (GRUB_ERR_IO, "Can't get mode info."); + mode_info = (struct grub_vbe_mode_info_block *) ptrorig; mbi->vbe_mode_info = ptrdest; - grub_memcpy (ptrorig, scratch, sizeof (struct grub_vbe_mode_info_block)); + /* get_mode_info isn't available for mode 3. */ + if (vbe_mode == 3) + { + grub_memset (mode_info, 0, sizeof (struct grub_vbe_mode_info_block)); + mode_info->memory_model = GRUB_VBE_MEMORY_MODEL_TEXT; + mode_info->x_resolution = 80; + mode_info->y_resolution = 25; + } + else + { + status = grub_vbe_bios_get_mode_info (vbe_mode, scratch); + if (status != GRUB_VBE_STATUS_OK) + return grub_error (GRUB_ERR_IO, "can't get mode info"); + grub_memcpy (mode_info, scratch, + sizeof (struct grub_vbe_mode_info_block)); + } ptrorig += sizeof (struct grub_vbe_mode_info_block); ptrdest += sizeof (struct grub_vbe_mode_info_block); @@ -198,6 +212,21 @@ fill_vbe_info (struct multiboot_info *mbi, grub_uint8_t *ptrorig, mbi->flags |= MULTIBOOT_INFO_VBE_INFO; + if (fill_generic && mode_info->memory_model == GRUB_VBE_MEMORY_MODEL_TEXT) + { + mbi->framebuffer_addr = 0xb8000; + + mbi->framebuffer_pitch = 2 * mode_info->x_resolution; + mbi->framebuffer_width = mode_info->x_resolution; + mbi->framebuffer_height = mode_info->y_resolution; + + mbi->framebuffer_bpp = 16; + + mbi->framebuffer_type = MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT; + + mbi->flags |= MULTIBOOT_INFO_FRAMEBUFFER_INFO; + } + return GRUB_ERR_NONE; } #endif @@ -209,25 +238,25 @@ retrieve_video_parameters (struct multiboot_info *mbi, grub_err_t err; struct grub_video_mode_info mode_info; void *framebuffer; -#if HAS_VBE - int vbe_active; -#endif + grub_video_driver_id_t driv_id; struct grub_video_palette_data palette[256]; err = set_video_mode (); if (err) - return err; + { + grub_print_error (); + grub_errno = GRUB_ERR_NONE; + } grub_video_get_palette (0, ARRAY_SIZE (palette), palette); -#if HAS_VBE - { - grub_video_driver_id_t driv_id; - driv_id = grub_video_get_driver_id (); - - vbe_active = ((driv_id == GRUB_VIDEO_DRIVER_VBE) - || ((driv_id == GRUB_VIDEO_DRIVER_NONE) && HAS_VGA_TEXT)); - } + driv_id = grub_video_get_driver_id (); +#if HAS_VGA_TEXT + if (driv_id == GRUB_VIDEO_DRIVER_NONE) + return fill_vbe_info (mbi, ptrorig, ptrdest, 1); +#else + if (driv_id == GRUB_VIDEO_DRIVER_NONE) + return GRUB_ERR_NONE; #endif err = grub_video_get_info_and_fini (&mode_info, &framebuffer); @@ -277,8 +306,8 @@ retrieve_video_parameters (struct multiboot_info *mbi, mbi->flags |= MULTIBOOT_INFO_FRAMEBUFFER_INFO; #if HAS_VBE - if (vbe_active) - fill_vbe_info (mbi, ptrorig, ptrdest); + if (driv_id == GRUB_VIDEO_DRIVER_VBE) + return fill_vbe_info (mbi, ptrorig, ptrdest, 0); #endif return GRUB_ERR_NONE; From 5408044f4c6805bfbec81a6a166218b37899d9fd Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 16 Jan 2010 16:25:43 +0100 Subject: [PATCH 217/738] Multiboot 2 tags support --- ChangeLog.tag | 40 +++ conf/i386.rmk | 2 +- include/grub/i386/multiboot.h | 8 - include/grub/multiboot.h | 21 +- include/multiboot2.h | 257 ++++++++----------- loader/i386/multiboot.c | 138 +++++++++- loader/i386/multiboot_mbi.c | 210 ++++----------- loader/i386/multiboot_mbi2.c | 468 ++++++++++++++++++++++++++++++++++ 8 files changed, 827 insertions(+), 317 deletions(-) create mode 100644 ChangeLog.tag create mode 100644 loader/i386/multiboot_mbi2.c diff --git a/ChangeLog.tag b/ChangeLog.tag new file mode 100644 index 000000000..dbeea1017 --- /dev/null +++ b/ChangeLog.tag @@ -0,0 +1,40 @@ +2010-01-16 Vladimir Serbinenko + + Multiboot2 tag support + + * conf/i386.rmk (multiboot2_mod_SOURCES): Replace + loader/i386/multiboot_mbi.c with loader/i386/multiboot_mbi2.c. + * include/grub/i386/multiboot.h (grub_multiboot_real_boot): Removed. + (grub_multiboot2_real_boot): Likewise. + * include/grub/multiboot.h (grub_multiboot_set_accepts_video): Removed. + (grub_get_multiboot_mmap_len): New proto. + (grub_fill_multiboot_mmap): Likewise. + (grub_multiboot_set_video_mode): Likewise. + (grub_multiboot_fill_vbe_info_real): Likewise. + * include/multiboot2.h: Resynced with specification. + * loader/i386/multiboot_mbi.c (DEFAULT_VIDEO_MODE): Moved from here... + * loader/i386/multiboot.c (DEFAULT_VIDEO_MODE): ... here. + * loader/i386/multiboot_mbi.c (HAS_VGA_TEXT): Moved from here .. + * include/grub/multiboot.h (GRUB_MACHINE_HAS_VGA_TEXT): ... here. All + users updated. + * loader/i386/multiboot_mbi.c (HAS_VBE): Moved from here .. + * include/grub/multiboot.h (GRUB_MACHINE_HAS_VBE): ... here. All + users updated. + * loader/i386/multiboot_mbi.c (accepts_video): Moved from here... + * loader/i386/multiboot.c (accepts_video): ... here. All users updated. + * loader/i386/multiboot_mbi.c (grub_multiboot_set_accepts_video): + Removed. + * loader/i386/multiboot_mbi.c (grub_get_multiboot_mmap_len): + Moved from here... + * loader/i386/multiboot.c (grub_get_multiboot_mmap_len): ... here. + * loader/i386/multiboot_mbi.c (grub_fill_multiboot_mmap): + Moved from here... + * loader/i386/multiboot.c (grub_fill_multiboot_mmap): ... here. + * loader/i386/multiboot_mbi.c (set_video_mode): Moved from here... + * loader/i386/multiboot.c (grub_multiboot_set_video_mode): ... here. + All users updated. + * loader/i386/multiboot_mbi.c (fill_vbe_info): Moved generic parts + from here... + * loader/i386/multiboot.c (grub_multiboot_fill_vbe_info_real): ... here. + All users updated. + * loader/i386/multiboot_mbi2.c: New file. diff --git a/conf/i386.rmk b/conf/i386.rmk index 7ef337c61..064ee3ab4 100644 --- a/conf/i386.rmk +++ b/conf/i386.rmk @@ -36,7 +36,7 @@ multiboot_mod_ASFLAGS = $(COMMON_ASFLAGS) pkglib_MODULES += multiboot2.mod multiboot2_mod_SOURCES = loader/i386/multiboot.c \ - loader/i386/multiboot_mbi.c \ + loader/i386/multiboot_mbi2.c \ loader/multiboot_loader.c multiboot2_mod_CFLAGS = $(COMMON_CFLAGS) -DGRUB_USE_MULTIBOOT2 multiboot2_mod_LDFLAGS = $(COMMON_LDFLAGS) diff --git a/include/grub/i386/multiboot.h b/include/grub/i386/multiboot.h index 584955449..8131e9477 100644 --- a/include/grub/i386/multiboot.h +++ b/include/grub/i386/multiboot.h @@ -19,14 +19,6 @@ #ifndef GRUB_MULTIBOOT_CPU_HEADER #define GRUB_MULTIBOOT_CPU_HEADER 1 -/* The asm part of the multiboot loader. */ -void grub_multiboot_real_boot (grub_addr_t entry, - struct multiboot_info *mbi) - __attribute__ ((noreturn)); -void grub_multiboot2_real_boot (grub_addr_t entry, - struct multiboot_info *mbi) - __attribute__ ((noreturn)); - extern grub_uint32_t grub_multiboot_payload_eip; extern char *grub_multiboot_payload_orig; extern grub_addr_t grub_multiboot_payload_dest; diff --git a/include/grub/multiboot.h b/include/grub/multiboot.h index 665292e33..8a7289820 100644 --- a/include/grub/multiboot.h +++ b/include/grub/multiboot.h @@ -35,8 +35,6 @@ void grub_multiboot (int argc, char *argv[]); void grub_module (int argc, char *argv[]); -void grub_multiboot_set_accepts_video (int val); - grub_size_t grub_multiboot_get_mbi_size (void); grub_err_t grub_multiboot_make_mbi (void *orig, grub_uint32_t dest, grub_off_t buf_off, grub_size_t bufsize); @@ -46,5 +44,24 @@ grub_err_t grub_multiboot_add_module (grub_addr_t start, grub_size_t size, int argc, char *argv[]); void grub_multiboot_set_bootdev (void); +grub_uint32_t grub_get_multiboot_mmap_len (void); +void grub_fill_multiboot_mmap (struct multiboot_mmap_entry *first_entry); +grub_err_t grub_multiboot_set_video_mode (void); + +#if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_QEMU) +#include +grub_err_t +grub_multiboot_fill_vbe_info_real (struct grub_vbe_info_block *vbe_control_info, + struct grub_vbe_mode_info_block *vbe_mode_info, + multiboot_uint16_t *vbe_mode, + multiboot_uint16_t *vbe_interface_seg, + multiboot_uint16_t *vbe_interface_off, + multiboot_uint16_t *vbe_interface_len); +#define GRUB_MACHINE_HAS_VBE 1 +#define GRUB_MACHINE_HAS_VGA_TEXT 1 +#else +#define GRUB_MACHINE_HAS_VBE 0 +#define GRUB_MACHINE_HAS_VGA_TEXT 0 +#endif #endif /* ! GRUB_MULTIBOOT_HEADER */ diff --git a/include/multiboot2.h b/include/multiboot2.h index a241a70ad..a76364fa7 100644 --- a/include/multiboot2.h +++ b/include/multiboot2.h @@ -51,42 +51,15 @@ /* This flag indicates the use of the address fields in the header. */ #define MULTIBOOT_AOUT_KLUDGE 0x00010000 -/* Flags to be set in the 'flags' member of the multiboot info structure. */ - -/* is there basic lower/upper memory information? */ -#define MULTIBOOT_INFO_MEMORY 0x00000001 -/* is there a boot device set? */ -#define MULTIBOOT_INFO_BOOTDEV 0x00000002 -/* is the command-line defined? */ -#define MULTIBOOT_INFO_CMDLINE 0x00000004 -/* are there modules to do something with? */ -#define MULTIBOOT_INFO_MODS 0x00000008 - -/* These next two are mutually exclusive */ - -/* is there a symbol table loaded? */ -#define MULTIBOOT_INFO_AOUT_SYMS 0x00000010 -/* is there an ELF section header table? */ -#define MULTIBOOT_INFO_ELF_SHDR 0X00000020 - -/* is there a full memory map? */ -#define MULTIBOOT_INFO_MEM_MAP 0x00000040 - -/* Is there drive info? */ -#define MULTIBOOT_INFO_DRIVE_INFO 0x00000080 - -/* Is there a config table? */ -#define MULTIBOOT_INFO_CONFIG_TABLE 0x00000100 - -/* Is there a boot loader name? */ -#define MULTIBOOT_INFO_BOOT_LOADER_NAME 0x00000200 - -/* Is there a APM table? */ -#define MULTIBOOT_INFO_APM_TABLE 0x00000400 - -/* Is there video information? */ -#define MULTIBOOT_INFO_VBE_INFO 0x00000800 -#define MULTIBOOT_INFO_FRAMEBUFFER_INFO 0x00001000 +#define MULTIBOOT_TAG_TYPE_END 0 +#define MULTIBOOT_TAG_TYPE_CMDLINE 1 +#define MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME 2 +#define MULTIBOOT_TAG_TYPE_MODULE 3 +#define MULTIBOOT_TAG_TYPE_BASIC_MEMINFO 4 +#define MULTIBOOT_TAG_TYPE_BOOTDEV 5 +#define MULTIBOOT_TAG_TYPE_MMAP 6 +#define MULTIBOOT_TAG_TYPE_VBE 7 +#define MULTIBOOT_TAG_TYPE_FRAMEBUFFER 8 #ifndef ASM_FILE @@ -120,105 +93,6 @@ struct multiboot_header multiboot_uint32_t depth; }; -/* The symbol table for a.out. */ -struct multiboot_aout_symbol_table -{ - multiboot_uint32_t tabsize; - multiboot_uint32_t strsize; - multiboot_uint32_t addr; - multiboot_uint32_t reserved; -}; -typedef struct multiboot_aout_symbol_table multiboot_aout_symbol_table_t; - -/* The section header table for ELF. */ -struct multiboot_elf_section_header_table -{ - multiboot_uint32_t num; - multiboot_uint32_t size; - multiboot_uint32_t addr; - multiboot_uint32_t shndx; -}; -typedef struct multiboot_elf_section_header_table multiboot_elf_section_header_table_t; - -struct multiboot_info -{ - /* Multiboot info version number */ - multiboot_uint32_t flags; - - /* Available memory from BIOS */ - multiboot_uint32_t mem_lower; - multiboot_uint32_t mem_upper; - - /* "root" partition */ - multiboot_uint32_t boot_device; - - /* Kernel command line */ - multiboot_uint32_t cmdline; - - /* Boot-Module list */ - multiboot_uint32_t mods_count; - multiboot_uint32_t mods_addr; - - union - { - multiboot_aout_symbol_table_t aout_sym; - multiboot_elf_section_header_table_t elf_sec; - } u; - - /* Memory Mapping buffer */ - multiboot_uint32_t mmap_length; - multiboot_uint32_t mmap_addr; - - /* Drive Info buffer */ - multiboot_uint32_t drives_length; - multiboot_uint32_t drives_addr; - - /* ROM configuration table */ - multiboot_uint32_t config_table; - - /* Boot Loader Name */ - multiboot_uint32_t boot_loader_name; - - /* APM table */ - multiboot_uint32_t apm_table; - - /* Video */ - multiboot_uint32_t vbe_control_info; - multiboot_uint32_t vbe_mode_info; - multiboot_uint16_t vbe_mode; - multiboot_uint16_t vbe_interface_seg; - multiboot_uint16_t vbe_interface_off; - multiboot_uint16_t vbe_interface_len; - - multiboot_uint64_t framebuffer_addr; - multiboot_uint32_t framebuffer_pitch; - multiboot_uint32_t framebuffer_width; - multiboot_uint32_t framebuffer_height; - multiboot_uint8_t framebuffer_bpp; -#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0 -#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB 1 -#define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT 2 - multiboot_uint8_t framebuffer_type; - union - { - struct - { - multiboot_uint32_t framebuffer_palette_addr; - multiboot_uint16_t framebuffer_palette_num_colors; - }; - struct - { - multiboot_uint8_t framebuffer_red_field_position; - multiboot_uint8_t framebuffer_red_mask_size; - multiboot_uint8_t framebuffer_green_field_position; - multiboot_uint8_t framebuffer_green_mask_size; - multiboot_uint8_t framebuffer_blue_field_position; - multiboot_uint8_t framebuffer_blue_mask_size; - }; - }; -}; -typedef struct multiboot_info multiboot_info_t; - struct multiboot_color { multiboot_uint8_t red; @@ -237,19 +111,114 @@ struct multiboot_mmap_entry } __attribute__((packed)); typedef struct multiboot_mmap_entry multiboot_memory_map_t; -struct multiboot_mod_list +struct multiboot_tag { - /* the memory used goes from bytes 'mod_start' to 'mod_end-1' inclusive */ + multiboot_uint32_t type; + multiboot_uint32_t size; +}; + +struct multiboot_tag_string +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + char string[0]; +}; + +struct multiboot_tag_module +{ + multiboot_uint32_t type; + multiboot_uint32_t size; multiboot_uint32_t mod_start; multiboot_uint32_t mod_end; - - /* Module command line */ - multiboot_uint32_t cmdline; - - /* padding to take it to 16 bytes (must be zero) */ - multiboot_uint32_t pad; + char cmdline[0]; +}; + +struct multiboot_tag_basic_meminfo +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t mem_lower; + multiboot_uint32_t mem_upper; +}; + +struct multiboot_tag_bootdev +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t biosdev; + multiboot_uint32_t slice; + multiboot_uint32_t part; +}; + +struct multiboot_tag_mmap +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + struct multiboot_mmap_entry entries[0]; +}; + +struct multiboot_vbe_info_block +{ + multiboot_uint8_t external_specification[512]; +}; + +struct multiboot_vbe_mode_info_block +{ + multiboot_uint8_t external_specification[256]; +}; + +struct multiboot_tag_vbe +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + + multiboot_uint16_t vbe_mode; + multiboot_uint16_t vbe_interface_seg; + multiboot_uint16_t vbe_interface_off; + multiboot_uint16_t vbe_interface_len; + + struct multiboot_vbe_info_block vbe_control_info; + struct multiboot_vbe_mode_info_block vbe_mode_info; +}; + +struct multiboot_tag_framebuffer_common +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + + multiboot_uint64_t framebuffer_addr; + multiboot_uint32_t framebuffer_pitch; + multiboot_uint32_t framebuffer_width; + multiboot_uint32_t framebuffer_height; + multiboot_uint8_t framebuffer_bpp; +#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0 +#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB 1 +#define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT 2 + multiboot_uint8_t framebuffer_type; +}; + +struct multiboot_tag_framebuffer +{ + struct multiboot_tag_framebuffer_common common; + + union + { + struct + { + multiboot_uint16_t framebuffer_palette_num_colors; + struct multiboot_color framebuffer_palette[0]; + }; + struct + { + multiboot_uint8_t framebuffer_red_field_position; + multiboot_uint8_t framebuffer_red_mask_size; + multiboot_uint8_t framebuffer_green_field_position; + multiboot_uint8_t framebuffer_green_mask_size; + multiboot_uint8_t framebuffer_blue_field_position; + multiboot_uint8_t framebuffer_blue_mask_size; + }; + }; }; -typedef struct multiboot_mod_list multiboot_module_t; #endif /* ! ASM_FILE */ diff --git a/loader/i386/multiboot.c b/loader/i386/multiboot.c index 0ac3ca339..86bb91ec8 100644 --- a/loader/i386/multiboot.c +++ b/loader/i386/multiboot.c @@ -44,11 +44,18 @@ #include #include #include +#include #ifdef GRUB_MACHINE_EFI #include #endif +#if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_QEMU) +#define DEFAULT_VIDEO_MODE "text" +#else +#define DEFAULT_VIDEO_MODE "auto" +#endif + extern grub_dl_t my_mod; static grub_size_t code_size, alloc_mbi; @@ -56,6 +63,135 @@ char *grub_multiboot_payload_orig; grub_addr_t grub_multiboot_payload_dest; grub_size_t grub_multiboot_pure_size; grub_uint32_t grub_multiboot_payload_eip; +static int accepts_video; + +/* Return the length of the Multiboot mmap that will be needed to allocate + our platform's map. */ +grub_uint32_t +grub_get_multiboot_mmap_len (void) +{ + grub_size_t count = 0; + + auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t); + int NESTED_FUNC_ATTR hook (grub_uint64_t addr __attribute__ ((unused)), + grub_uint64_t size __attribute__ ((unused)), + grub_uint32_t type __attribute__ ((unused))) + { + count++; + return 0; + } + + grub_mmap_iterate (hook); + + return count * sizeof (struct multiboot_mmap_entry); +} + +/* Fill previously allocated Multiboot mmap. */ +void +grub_fill_multiboot_mmap (struct multiboot_mmap_entry *first_entry) +{ + struct multiboot_mmap_entry *mmap_entry = (struct multiboot_mmap_entry *) first_entry; + + auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t); + int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, grub_uint32_t type) + { + mmap_entry->addr = addr; + mmap_entry->len = size; + switch (type) + { + case GRUB_MACHINE_MEMORY_AVAILABLE: + mmap_entry->type = MULTIBOOT_MEMORY_AVAILABLE; + break; + + default: + mmap_entry->type = MULTIBOOT_MEMORY_RESERVED; + break; + } + mmap_entry->size = sizeof (struct multiboot_mmap_entry) - sizeof (mmap_entry->size); + mmap_entry++; + + return 0; + } + + grub_mmap_iterate (hook); +} + +grub_err_t +grub_multiboot_set_video_mode (void) +{ + grub_err_t err; + const char *modevar; + + if (accepts_video || !GRUB_MACHINE_HAS_VGA_TEXT) + { + modevar = grub_env_get ("gfxpayload"); + if (! modevar || *modevar == 0) + err = grub_video_set_mode (DEFAULT_VIDEO_MODE, 0); + else + { + char *tmp; + tmp = grub_malloc (grub_strlen (modevar) + + sizeof (DEFAULT_VIDEO_MODE) + 1); + if (! tmp) + return grub_errno; + grub_sprintf (tmp, "%s;" DEFAULT_VIDEO_MODE, modevar); + err = grub_video_set_mode (tmp, 0); + grub_free (tmp); + } + } + else + err = grub_video_set_mode ("text", 0); + + return err; +} + +#if GRUB_MACHINE_HAS_VBE +grub_err_t +grub_multiboot_fill_vbe_info_real (struct grub_vbe_info_block *vbe_control_info, + struct grub_vbe_mode_info_block *vbe_mode_info, + multiboot_uint16_t *vbe_mode, + multiboot_uint16_t *vbe_interface_seg, + multiboot_uint16_t *vbe_interface_off, + multiboot_uint16_t *vbe_interface_len) +{ + grub_vbe_status_t status; + void *scratch = (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR; + + status = grub_vbe_bios_get_controller_info (scratch); + if (status != GRUB_VBE_STATUS_OK) + return grub_error (GRUB_ERR_IO, "Can't get controller info."); + grub_memcpy (vbe_control_info, scratch, sizeof (struct grub_vbe_info_block)); + + status = grub_vbe_bios_get_mode (scratch); + *vbe_mode = *(grub_uint32_t *) scratch; + if (status != GRUB_VBE_STATUS_OK) + return grub_error (GRUB_ERR_IO, "can't get VBE mode"); + + /* get_mode_info isn't available for mode 3. */ + if (*vbe_mode == 3) + { + grub_memset (vbe_mode_info, 0, sizeof (struct grub_vbe_mode_info_block)); + vbe_mode_info->memory_model = GRUB_VBE_MEMORY_MODEL_TEXT; + vbe_mode_info->x_resolution = 80; + vbe_mode_info->y_resolution = 25; + } + else + { + status = grub_vbe_bios_get_mode_info (*vbe_mode, scratch); + if (status != GRUB_VBE_STATUS_OK) + return grub_error (GRUB_ERR_IO, "can't get mode info"); + grub_memcpy (vbe_mode_info, scratch, + sizeof (struct grub_vbe_mode_info_block)); + } + + /* FIXME: retrieve those. */ + *vbe_interface_seg = 0; + *vbe_interface_off = 0; + *vbe_interface_len = 0; + + return GRUB_ERR_NONE; +} +#endif static grub_err_t grub_multiboot_boot (void) @@ -265,7 +401,7 @@ grub_multiboot (int argc, char *argv[]) } } - grub_multiboot_set_accepts_video (!!(header->flags & MULTIBOOT_VIDEO_MODE)); + accepts_video = !!(header->flags & MULTIBOOT_VIDEO_MODE); grub_multiboot_set_bootdev (); diff --git a/loader/i386/multiboot_mbi.c b/loader/i386/multiboot_mbi.c index ddbbf3cfd..9c45b3352 100644 --- a/loader/i386/multiboot_mbi.c +++ b/loader/i386/multiboot_mbi.c @@ -31,17 +31,6 @@ #include #include -#if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_QEMU) -#include -#define DEFAULT_VIDEO_MODE "text" -#define HAS_VGA_TEXT 1 -#define HAS_VBE 1 -#else -#define DEFAULT_VIDEO_MODE "auto" -#define HAS_VGA_TEXT 0 -#define HAS_VBE 0 -#endif - struct module { struct module *next; @@ -58,34 +47,6 @@ static unsigned modcnt; static char *cmdline = NULL; static grub_uint32_t bootdev; static int bootdev_set; -static int accepts_video; - -void -grub_multiboot_set_accepts_video (int val) -{ - accepts_video = val; -} - -/* Return the length of the Multiboot mmap that will be needed to allocate - our platform's map. */ -static grub_uint32_t -grub_get_multiboot_mmap_len (void) -{ - grub_size_t count = 0; - - auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t); - int NESTED_FUNC_ATTR hook (grub_uint64_t addr __attribute__ ((unused)), - grub_uint64_t size __attribute__ ((unused)), - grub_uint32_t type __attribute__ ((unused))) - { - count++; - return 0; - } - - grub_mmap_iterate (hook); - - return count * sizeof (struct multiboot_mmap_entry); -} grub_size_t grub_multiboot_get_mbi_size (void) @@ -93,142 +54,45 @@ grub_multiboot_get_mbi_size (void) return sizeof (struct multiboot_info) + ALIGN_UP (cmdline_size, 4) + modcnt * sizeof (struct multiboot_mod_list) + total_modcmd + ALIGN_UP (sizeof(PACKAGE_STRING), 4) + grub_get_multiboot_mmap_len () -#if HAS_VBE +#if GRUB_MACHINE_HAS_VBE + sizeof (struct grub_vbe_info_block) + sizeof (struct grub_vbe_mode_info_block) #endif + 256 * sizeof (struct multiboot_color); } -/* Fill previously allocated Multiboot mmap. */ -static void -grub_fill_multiboot_mmap (struct multiboot_mmap_entry *first_entry) -{ - struct multiboot_mmap_entry *mmap_entry = (struct multiboot_mmap_entry *) first_entry; - - auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t); - int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, grub_uint32_t type) - { - mmap_entry->addr = addr; - mmap_entry->len = size; - switch (type) - { - case GRUB_MACHINE_MEMORY_AVAILABLE: - mmap_entry->type = MULTIBOOT_MEMORY_AVAILABLE; - break; - - default: - mmap_entry->type = MULTIBOOT_MEMORY_RESERVED; - break; - } - mmap_entry->size = sizeof (struct multiboot_mmap_entry) - sizeof (mmap_entry->size); - mmap_entry++; - - return 0; - } - - grub_mmap_iterate (hook); -} - +#if GRUB_MACHINE_HAS_VBE static grub_err_t -set_video_mode (void) +fill_vbe_info (struct multiboot_info *mbi, + struct grub_vbe_mode_info_block **vbe_mode_info_out, + grub_uint8_t *ptrorig, grub_addr_t ptrdest) { + struct grub_vbe_info_block *vbe_control_info; + struct grub_vbe_mode_info_block *vbe_mode_info; grub_err_t err; - const char *modevar; - if (accepts_video || !HAS_VGA_TEXT) - { - modevar = grub_env_get ("gfxpayload"); - if (! modevar || *modevar == 0) - err = grub_video_set_mode (DEFAULT_VIDEO_MODE, 0); - else - { - char *tmp; - tmp = grub_malloc (grub_strlen (modevar) - + sizeof (DEFAULT_VIDEO_MODE) + 1); - if (! tmp) - return grub_errno; - grub_sprintf (tmp, "%s;" DEFAULT_VIDEO_MODE, modevar); - err = grub_video_set_mode (tmp, 0); - grub_free (tmp); - } - } - else - err = grub_video_set_mode ("text", 0); - - return err; -} - -#if HAS_VBE -static grub_err_t -fill_vbe_info (struct multiboot_info *mbi, grub_uint8_t *ptrorig, - grub_uint32_t ptrdest, int fill_generic) -{ - grub_vbe_status_t status; - grub_uint32_t vbe_mode; - void *scratch = (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR; - struct grub_vbe_mode_info_block *mode_info; - - status = grub_vbe_bios_get_controller_info (scratch); - if (status != GRUB_VBE_STATUS_OK) - return grub_error (GRUB_ERR_IO, "Can't get controller info."); - + vbe_control_info = (struct grub_vbe_info_block *) ptrorig; mbi->vbe_control_info = ptrdest; - grub_memcpy (ptrorig, scratch, sizeof (struct grub_vbe_info_block)); ptrorig += sizeof (struct grub_vbe_info_block); ptrdest += sizeof (struct grub_vbe_info_block); - - status = grub_vbe_bios_get_mode (scratch); - vbe_mode = *(grub_uint32_t *) scratch; - if (status != GRUB_VBE_STATUS_OK) - return grub_error (GRUB_ERR_IO, "can't get VBE mode"); - mbi->vbe_mode = vbe_mode; - - mode_info = (struct grub_vbe_mode_info_block *) ptrorig; + vbe_mode_info = (struct grub_vbe_mode_info_block *) ptrorig; mbi->vbe_mode_info = ptrdest; - /* get_mode_info isn't available for mode 3. */ - if (vbe_mode == 3) - { - grub_memset (mode_info, 0, sizeof (struct grub_vbe_mode_info_block)); - mode_info->memory_model = GRUB_VBE_MEMORY_MODEL_TEXT; - mode_info->x_resolution = 80; - mode_info->y_resolution = 25; - } - else - { - status = grub_vbe_bios_get_mode_info (vbe_mode, scratch); - if (status != GRUB_VBE_STATUS_OK) - return grub_error (GRUB_ERR_IO, "can't get mode info"); - grub_memcpy (mode_info, scratch, - sizeof (struct grub_vbe_mode_info_block)); - } ptrorig += sizeof (struct grub_vbe_mode_info_block); ptrdest += sizeof (struct grub_vbe_mode_info_block); - - /* FIXME: retrieve those. */ - mbi->vbe_interface_seg = 0; - mbi->vbe_interface_off = 0; - mbi->vbe_interface_len = 0; + err = grub_multiboot_fill_vbe_info_real (vbe_control_info, vbe_mode_info, + &mbi->vbe_mode, + &mbi->vbe_interface_seg, + &mbi->vbe_interface_off, + &mbi->vbe_interface_len); + if (err) + return err; mbi->flags |= MULTIBOOT_INFO_VBE_INFO; - - if (fill_generic && mode_info->memory_model == GRUB_VBE_MEMORY_MODEL_TEXT) - { - mbi->framebuffer_addr = 0xb8000; - - mbi->framebuffer_pitch = 2 * mode_info->x_resolution; - mbi->framebuffer_width = mode_info->x_resolution; - mbi->framebuffer_height = mode_info->y_resolution; - - mbi->framebuffer_bpp = 16; - - mbi->framebuffer_type = MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT; - - mbi->flags |= MULTIBOOT_INFO_FRAMEBUFFER_INFO; - } - + if (vbe_mode_info_out) + *vbe_mode_info_out = vbe_mode_info; return GRUB_ERR_NONE; } + #endif static grub_err_t @@ -241,7 +105,7 @@ retrieve_video_parameters (struct multiboot_info *mbi, grub_video_driver_id_t driv_id; struct grub_video_palette_data palette[256]; - err = set_video_mode (); + err = grub_multiboot_set_video_mode (); if (err) { grub_print_error (); @@ -251,9 +115,29 @@ retrieve_video_parameters (struct multiboot_info *mbi, grub_video_get_palette (0, ARRAY_SIZE (palette), palette); driv_id = grub_video_get_driver_id (); -#if HAS_VGA_TEXT +#if GRUB_MACHINE_HAS_VGA_TEXT if (driv_id == GRUB_VIDEO_DRIVER_NONE) - return fill_vbe_info (mbi, ptrorig, ptrdest, 1); + { + struct grub_vbe_mode_info_block *vbe_mode_info; + err = fill_vbe_info (mbi, &vbe_mode_info, ptrorig, ptrdest); + if (err) + return err; + if (vbe_mode_info->memory_model == GRUB_VBE_MEMORY_MODEL_TEXT) + { + mbi->framebuffer_addr = 0xb8000; + + mbi->framebuffer_pitch = 2 * vbe_mode_info->x_resolution; + mbi->framebuffer_width = vbe_mode_info->x_resolution; + mbi->framebuffer_height = vbe_mode_info->y_resolution; + + mbi->framebuffer_bpp = 16; + + mbi->framebuffer_type = MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT; + + mbi->flags |= MULTIBOOT_INFO_FRAMEBUFFER_INFO; + } + return GRUB_ERR_NONE; + } #else if (driv_id == GRUB_VIDEO_DRIVER_NONE) return GRUB_ERR_NONE; @@ -305,9 +189,13 @@ retrieve_video_parameters (struct multiboot_info *mbi, mbi->flags |= MULTIBOOT_INFO_FRAMEBUFFER_INFO; -#if HAS_VBE +#if GRUB_MACHINE_HAS_VBE if (driv_id == GRUB_VIDEO_DRIVER_VBE) - return fill_vbe_info (mbi, ptrorig, ptrdest, 0); + { + err = fill_vbe_info (mbi, NULL, ptrorig, ptrdest); + if (err) + return err; + } #endif return GRUB_ERR_NONE; @@ -396,7 +284,7 @@ grub_multiboot_make_mbi (void *orig, grub_uint32_t dest, grub_off_t buf_off, grub_print_error (); grub_errno = GRUB_ERR_NONE; } -#if HAS_VBE +#if GRUB_MACHINE_HAS_VBE ptrorig += sizeof (struct grub_vbe_info_block); ptrdest += sizeof (struct grub_vbe_info_block); ptrorig += sizeof (struct grub_vbe_mode_info_block); diff --git a/loader/i386/multiboot_mbi2.c b/loader/i386/multiboot_mbi2.c new file mode 100644 index 000000000..031d4c0eb --- /dev/null +++ b/loader/i386/multiboot_mbi2.c @@ -0,0 +1,468 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#ifdef GRUB_MACHINE_PCBIOS +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_QEMU) +#include +#define DEFAULT_VIDEO_MODE "text" +#define HAS_VGA_TEXT 1 +#define HAS_VBE 1 +#else +#define DEFAULT_VIDEO_MODE "auto" +#define HAS_VGA_TEXT 0 +#define HAS_VBE 0 +#endif + +struct module +{ + struct module *next; + grub_addr_t start; + grub_size_t size; + char *cmdline; + int cmdline_size; +}; + +struct module *modules, *modules_last; +static grub_size_t cmdline_size; +static grub_size_t total_modcmd; +static unsigned modcnt; +static char *cmdline = NULL; +static int bootdev_set; +static grub_uint32_t biosdev, slice, part; + +grub_size_t +grub_multiboot_get_mbi_size (void) +{ + return sizeof (struct multiboot_tag) + + (sizeof (struct multiboot_tag_string) + ALIGN_UP (cmdline_size, 4)) + + (sizeof (struct multiboot_tag_string) + + ALIGN_UP (sizeof (PACKAGE_STRING), 4)) + + (modcnt * sizeof (struct multiboot_tag_module) + total_modcmd) + + sizeof (struct multiboot_tag_basic_meminfo) + + sizeof (struct multiboot_tag_bootdev) + + (sizeof (struct multiboot_tag_mmap) + grub_get_multiboot_mmap_len ()) + + sizeof (struct multiboot_tag_vbe); +} + +#ifdef GRUB_MACHINE_HAS_VBE + +static grub_err_t +fill_vbe_info (struct grub_vbe_mode_info_block **vbe_mode_info_out, + grub_uint8_t **ptrorig) +{ + struct multiboot_tag_vbe *tag = (struct multiboot_tag_vbe *) *ptrorig; + grub_err_t err; + + tag->type = MULTIBOOT_TAG_TYPE_VBE; + tag->size = 0; + err = grub_multiboot_fill_vbe_info_real ((struct grub_vbe_info_block *) + &(tag->vbe_control_info), + (struct grub_vbe_mode_info_block *) + &(tag->vbe_mode_info), + &(tag->vbe_mode), + &(tag->vbe_interface_seg), + &(tag->vbe_interface_off), + &(tag->vbe_interface_len)); + if (err) + return err; + if (vbe_mode_info_out) + *vbe_mode_info_out = (struct grub_vbe_mode_info_block *) + &(tag->vbe_mode_info); + tag->size = sizeof (struct multiboot_tag_vbe); + *ptrorig += tag->size; + return GRUB_ERR_NONE; +} + +#endif + +static grub_err_t +retrieve_video_parameters (grub_uint8_t **ptrorig) +{ + grub_err_t err; + struct grub_video_mode_info mode_info; + void *framebuffer; + grub_video_driver_id_t driv_id; + struct grub_video_palette_data palette[256]; + struct multiboot_tag_framebuffer *tag + = (struct multiboot_tag_framebuffer *) *ptrorig; + + err = grub_multiboot_set_video_mode (); + if (err) + { + grub_print_error (); + grub_errno = GRUB_ERR_NONE; + } + + grub_video_get_palette (0, ARRAY_SIZE (palette), palette); + + driv_id = grub_video_get_driver_id (); +#if HAS_VGA_TEXT + if (driv_id == GRUB_VIDEO_DRIVER_NONE) + { + struct grub_vbe_mode_info_block *vbe_mode_info; + err = fill_vbe_info (&vbe_mode_info, ptrorig); + if (err) + return err; + if (vbe_mode_info->memory_model == GRUB_VBE_MEMORY_MODEL_TEXT) + { + tag = (struct multiboot_tag_framebuffer *) *ptrorig; + tag->common.type = MULTIBOOT_TAG_TYPE_FRAMEBUFFER; + tag->common.size = 0; + + tag->common.framebuffer_addr = 0xb8000; + + tag->common.framebuffer_pitch = 2 * vbe_mode_info->x_resolution; + tag->common.framebuffer_width = vbe_mode_info->x_resolution; + tag->common.framebuffer_height = vbe_mode_info->y_resolution; + + tag->common.framebuffer_bpp = 16; + + tag->common.framebuffer_type = MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT; + tag->common.size = sizeof (tag->common); + *ptrorig += tag->common.size; + } + return GRUB_ERR_NONE; + } +#else + if (driv_id == GRUB_VIDEO_DRIVER_NONE) + return GRUB_ERR_NONE; +#endif + + err = grub_video_get_info_and_fini (&mode_info, &framebuffer); + if (err) + return err; + + tag = (struct multiboot_tag_framebuffer *) *ptrorig; + tag->common.type = MULTIBOOT_TAG_TYPE_FRAMEBUFFER; + tag->common.size = 0; + + tag->common.framebuffer_addr = (grub_addr_t) framebuffer; + tag->common.framebuffer_pitch = mode_info.pitch; + + tag->common.framebuffer_width = mode_info.width; + tag->common.framebuffer_height = mode_info.height; + + tag->common.framebuffer_bpp = mode_info.bpp; + + if (mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) + { + unsigned i; + tag->common.framebuffer_type = MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED; + tag->framebuffer_palette_num_colors = mode_info.number_of_colors; + if (tag->framebuffer_palette_num_colors > ARRAY_SIZE (palette)) + tag->framebuffer_palette_num_colors = ARRAY_SIZE (palette); + tag->common.size = sizeof (struct multiboot_tag_framebuffer_common) + + sizeof (multiboot_uint16_t) + tag->framebuffer_palette_num_colors + * sizeof (struct multiboot_color); + for (i = 0; i < tag->framebuffer_palette_num_colors; i++) + { + tag->framebuffer_palette[i].red = palette[i].r; + tag->framebuffer_palette[i].green = palette[i].g; + tag->framebuffer_palette[i].blue = palette[i].b; + } + *ptrorig += tag->common.size; + } + else + { + tag->common.framebuffer_type = MULTIBOOT_FRAMEBUFFER_TYPE_RGB; + tag->common.framebuffer_type = MULTIBOOT_FRAMEBUFFER_TYPE_RGB; + tag->framebuffer_red_field_position = mode_info.green_field_pos; + tag->framebuffer_red_mask_size = mode_info.green_mask_size; + tag->framebuffer_green_field_position = mode_info.green_field_pos; + tag->framebuffer_green_mask_size = mode_info.green_mask_size; + tag->framebuffer_blue_field_position = mode_info.blue_field_pos; + tag->framebuffer_blue_mask_size = mode_info.blue_mask_size; + + tag->common.size = sizeof (struct multiboot_tag_framebuffer_common) + 6; + } + +#if HAS_VBE + if (driv_id == GRUB_VIDEO_DRIVER_VBE) + { + err = fill_vbe_info (NULL, ptrorig); + if (err) + return err; + } +#endif + + return GRUB_ERR_NONE; +} + +grub_err_t +grub_multiboot_make_mbi (void *orig, grub_uint32_t dest, grub_off_t buf_off, + grub_size_t bufsize) +{ + grub_uint8_t *ptrorig = (grub_uint8_t *) orig + buf_off; + grub_err_t err; + + if (bufsize < grub_multiboot_get_mbi_size ()) + return grub_error (GRUB_ERR_OUT_OF_MEMORY, "mbi buffer is too small"); + + { + struct multiboot_tag_string *tag = (struct multiboot_tag_string *) ptrorig; + tag->type = MULTIBOOT_TAG_TYPE_CMDLINE; + tag->size = sizeof (struct multiboot_tag_string) + + ALIGN_UP (cmdline_size, 4); + grub_memcpy (tag->string, cmdline, cmdline_size); + ptrorig += tag->size; + } + + { + struct multiboot_tag_string *tag = (struct multiboot_tag_string *) ptrorig; + tag->type = MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME; + tag->size = sizeof (struct multiboot_tag_string) + + ALIGN_UP (sizeof (PACKAGE_STRING), 4); + grub_memcpy (tag->string, PACKAGE_STRING, sizeof (PACKAGE_STRING)); + ptrorig += tag->size; + } + + { + unsigned i; + struct module *cur; + + for (i = 0, cur = modules; i < modcnt; i++, cur = cur->next) + { + struct multiboot_tag_module *tag + = (struct multiboot_tag_module *) ptrorig; + tag->type = MULTIBOOT_TAG_TYPE_MODULE; + tag->size = sizeof (struct multiboot_tag_module) + + ALIGN_UP (sizeof (cur->cmdline_size), 4); + + tag->mod_start = dest + cur->start; + tag->mod_end = tag->mod_start + cur->size; + grub_memcpy (tag->cmdline, cur->cmdline, cur->cmdline_size); + ptrorig += tag->size; + } + } + + { + struct multiboot_tag_mmap *tag = (struct multiboot_tag_mmap *) ptrorig; + tag->type = MULTIBOOT_TAG_TYPE_MMAP; + tag->size = sizeof (struct multiboot_tag_mmap) + + grub_get_multiboot_mmap_len (); + grub_fill_multiboot_mmap (tag->entries); + ptrorig += tag->size; + } + + { + struct multiboot_tag_basic_meminfo *tag + = (struct multiboot_tag_basic_meminfo *) ptrorig; + tag->type = MULTIBOOT_TAG_TYPE_BASIC_MEMINFO; + tag->size = sizeof (struct multiboot_tag_basic_meminfo); + + /* Convert from bytes to kilobytes. */ + tag->mem_lower = grub_mmap_get_lower () / 1024; + tag->mem_upper = grub_mmap_get_upper () / 1024; + ptrorig += tag->size; + } + + if (bootdev_set) + { + struct multiboot_tag_bootdev *tag + = (struct multiboot_tag_bootdev *) ptrorig; + tag->type = MULTIBOOT_TAG_TYPE_BOOTDEV; + tag->size = sizeof (struct multiboot_tag_bootdev); + + tag->biosdev = biosdev; + tag->slice = slice; + tag->part = part; + ptrorig += tag->size; + } + + { + err = retrieve_video_parameters (&ptrorig); + if (err) + { + grub_print_error (); + grub_errno = GRUB_ERR_NONE; + } + } + + { + struct multiboot_tag *tag = (struct multiboot_tag *) ptrorig; + tag->type = MULTIBOOT_TAG_TYPE_END; + tag->size = sizeof (struct multiboot_tag); + ptrorig += tag->size; + } + + return GRUB_ERR_NONE; +} + +void +grub_multiboot_free_mbi (void) +{ + struct module *cur, *next; + + cmdline_size = 0; + total_modcmd = 0; + modcnt = 0; + grub_free (cmdline); + cmdline = NULL; + bootdev_set = 0; + + for (cur = modules; cur; cur = next) + { + next = cur->next; + grub_free (cur->cmdline); + grub_free (cur); + } + modules = NULL; + modules_last = NULL; +} + +grub_err_t +grub_multiboot_init_mbi (int argc, char *argv[]) +{ + grub_ssize_t len = 0; + char *p; + int i; + + grub_multiboot_free_mbi (); + + for (i = 0; i < argc; i++) + len += grub_strlen (argv[i]) + 1; + if (len == 0) + len = 1; + + cmdline = p = grub_malloc (len); + if (! cmdline) + return grub_errno; + cmdline_size = len; + + for (i = 0; i < argc; i++) + { + p = grub_stpcpy (p, argv[i]); + *(p++) = ' '; + } + + /* Remove the space after the last word. */ + if (p != cmdline) + p--; + *p = '\0'; + + return GRUB_ERR_NONE; +} + +grub_err_t +grub_multiboot_add_module (grub_addr_t start, grub_size_t size, + int argc, char *argv[]) +{ + struct module *newmod; + char *p; + grub_ssize_t len = 0; + int i; + + newmod = grub_malloc (sizeof (*newmod)); + if (!newmod) + return grub_errno; + newmod->start = start; + newmod->size = size; + + for (i = 0; i < argc; i++) + len += grub_strlen (argv[i]) + 1; + + if (len == 0) + len = 1; + + newmod->cmdline = p = grub_malloc (len); + if (! newmod->cmdline) + { + grub_free (newmod); + return grub_errno; + } + newmod->cmdline_size = len; + total_modcmd += ALIGN_UP (len, 4); + + for (i = 0; i < argc; i++) + { + p = grub_stpcpy (p, argv[i]); + *(p++) = ' '; + } + + /* Remove the space after the last word. */ + if (p != newmod->cmdline) + p--; + *p = '\0'; + + if (modules_last) + modules_last->next = newmod; + else + { + modules = newmod; + modules_last->next = NULL; + } + modules_last = newmod; + + modcnt++; + + return GRUB_ERR_NONE; +} + +void +grub_multiboot_set_bootdev (void) +{ + char *p; + grub_device_t dev; + + slice = ~0; + part = ~0; + +#ifdef GRUB_MACHINE_PCBIOS + biosdev = grub_get_root_biosnumber (); +#else + biosdev = 0xffffffff; +#endif + + dev = grub_device_open (0); + if (dev && dev->disk && dev->disk->partition) + { + + p = dev->disk->partition->partmap->get_name (dev->disk->partition); + if (p) + { + if ((p[0] >= '0') && (p[0] <= '9')) + { + slice = grub_strtoul (p, &p, 0) - 1; + + if ((p) && (p[0] == ',')) + p++; + } + + if ((p[0] >= 'a') && (p[0] <= 'z')) + part = p[0] - 'a'; + } + } + if (dev) + grub_device_close (dev); + + bootdev_set = 1; +} From 234328552802a698c7dc66c0d5f204975cd62a64 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 16 Jan 2010 16:36:42 +0100 Subject: [PATCH 218/738] Don't pass biosdev if not booted from BIOS disk --- loader/i386/multiboot_mbi.c | 3 +++ loader/i386/multiboot_mbi2.c | 3 +++ 2 files changed, 6 insertions(+) diff --git a/loader/i386/multiboot_mbi.c b/loader/i386/multiboot_mbi.c index 9c45b3352..3e63b3456 100644 --- a/loader/i386/multiboot_mbi.c +++ b/loader/i386/multiboot_mbi.c @@ -417,6 +417,9 @@ grub_multiboot_set_bootdev (void) biosdev = 0xffffffff; #endif + if (biosdev == 0xffffffff) + return; + dev = grub_device_open (0); if (dev && dev->disk && dev->disk->partition) { diff --git a/loader/i386/multiboot_mbi2.c b/loader/i386/multiboot_mbi2.c index 031d4c0eb..de234727b 100644 --- a/loader/i386/multiboot_mbi2.c +++ b/loader/i386/multiboot_mbi2.c @@ -442,6 +442,9 @@ grub_multiboot_set_bootdev (void) biosdev = 0xffffffff; #endif + if (biosdev == 0xffffffff) + return; + dev = grub_device_open (0); if (dev && dev->disk && dev->disk->partition) { From 1c4ad986aa89b41f8478ae94689557f362c9fe82 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 16 Jan 2010 17:18:02 +0100 Subject: [PATCH 219/738] size field in tagged mbi --- loader/i386/multiboot_mbi2.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/loader/i386/multiboot_mbi2.c b/loader/i386/multiboot_mbi2.c index de234727b..636b63923 100644 --- a/loader/i386/multiboot_mbi2.c +++ b/loader/i386/multiboot_mbi2.c @@ -62,7 +62,7 @@ static grub_uint32_t biosdev, slice, part; grub_size_t grub_multiboot_get_mbi_size (void) { - return sizeof (struct multiboot_tag) + return sizeof (grub_uint32_t) + sizeof (struct multiboot_tag) + (sizeof (struct multiboot_tag_string) + ALIGN_UP (cmdline_size, 4)) + (sizeof (struct multiboot_tag_string) + ALIGN_UP (sizeof (PACKAGE_STRING), 4)) @@ -221,12 +221,15 @@ grub_err_t grub_multiboot_make_mbi (void *orig, grub_uint32_t dest, grub_off_t buf_off, grub_size_t bufsize) { - grub_uint8_t *ptrorig = (grub_uint8_t *) orig + buf_off; + grub_uint8_t *ptrorig; + grub_uint8_t *mbistart = (grub_uint8_t *) orig + buf_off; grub_err_t err; if (bufsize < grub_multiboot_get_mbi_size ()) return grub_error (GRUB_ERR_OUT_OF_MEMORY, "mbi buffer is too small"); + ptrorig = (grub_uint8_t *) orig + buf_off + sizeof (grub_uint32_t); + { struct multiboot_tag_string *tag = (struct multiboot_tag_string *) ptrorig; tag->type = MULTIBOOT_TAG_TYPE_CMDLINE; @@ -314,6 +317,8 @@ grub_multiboot_make_mbi (void *orig, grub_uint32_t dest, grub_off_t buf_off, ptrorig += tag->size; } + *(grub_uint32_t *) mbistart = ptrorig - mbistart; + return GRUB_ERR_NONE; } From a0c2a0f6ff17b99fc8de9a0e13dbdae31ba1533a Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Sun, 17 Jan 2010 17:29:57 +0000 Subject: [PATCH 220/738] 2010-01-17 Robert Millan * include/grub/test.h: Add license header. * tests/example_functional_test.c: Likewise. * tests/example_unit_test.c: Likewise. * tests/lib/functional_test.c: Likewise. * tests/lib/test.c: Likewise. * tests/lib/unit_test.c: Likewise. --- ChangeLog | 9 +++++++++ include/grub/test.h | 18 ++++++++++++++++++ tests/example_functional_test.c | 18 ++++++++++++++++++ tests/example_unit_test.c | 18 ++++++++++++++++++ tests/lib/functional_test.c | 18 ++++++++++++++++++ tests/lib/test.c | 18 ++++++++++++++++++ tests/lib/unit_test.c | 18 ++++++++++++++++++ 7 files changed, 117 insertions(+) diff --git a/ChangeLog b/ChangeLog index 41f9aeaa4..9ef3d3d42 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2010-01-17 Robert Millan + + * include/grub/test.h: Add license header. + * tests/example_functional_test.c: Likewise. + * tests/example_unit_test.c: Likewise. + * tests/lib/functional_test.c: Likewise. + * tests/lib/test.c: Likewise. + * tests/lib/unit_test.c: Likewise. + 2010-01-17 Vladimir Serbinenko Use flag-based instead of hook-based video mode selection and "auto" diff --git a/include/grub/test.h b/include/grub/test.h index 544e1c817..a7d3a2399 100644 --- a/include/grub/test.h +++ b/include/grub/test.h @@ -1,3 +1,21 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + #ifndef GRUB_TEST_HEADER #define GRUB_TEST_HEADER diff --git a/tests/example_functional_test.c b/tests/example_functional_test.c index 475d1c7f0..f43c0f1ce 100644 --- a/tests/example_functional_test.c +++ b/tests/example_functional_test.c @@ -1,3 +1,21 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + /* All tests need to include test.h for GRUB testing framework. */ #include diff --git a/tests/example_unit_test.c b/tests/example_unit_test.c index e2fad06ff..4999f1412 100644 --- a/tests/example_unit_test.c +++ b/tests/example_unit_test.c @@ -1,3 +1,21 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + /* Unit tests are normal programs, so they can include C library. */ #include diff --git a/tests/lib/functional_test.c b/tests/lib/functional_test.c index 8ad034503..8ff08cf8a 100644 --- a/tests/lib/functional_test.c +++ b/tests/lib/functional_test.c @@ -1,3 +1,21 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + #include #include #include diff --git a/tests/lib/test.c b/tests/lib/test.c index aba2f4415..cd0799f56 100644 --- a/tests/lib/test.c +++ b/tests/lib/test.c @@ -1,3 +1,21 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + #include #include #include diff --git a/tests/lib/unit_test.c b/tests/lib/unit_test.c index 2ca011433..e461150de 100644 --- a/tests/lib/unit_test.c +++ b/tests/lib/unit_test.c @@ -1,3 +1,21 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + #include #include #include From 8040619d881d40059292ff7e8f92882eea77ac7d Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Mon, 18 Jan 2010 07:49:50 +0000 Subject: [PATCH 221/738] 2010-01-18 Robert Millan * include/grub/i386/linux.h (GRUB_VIDEO_TYPE_TEXT): Rename to ... (GRUB_VIDEO_LINUX_TYPE_TEXT): ... this. Update all users. (GRUB_VIDEO_TYPE_VLFB): Rename to ... (GRUB_VIDEO_LINUX_TYPE_VESA): ... this. Update all users. (GRUB_VIDEO_TYPE_EFI): Rename to ... (GRUB_VIDEO_LINUX_TYPE_SIMPLE): ... this. Update all users. --- ChangeLog | 9 +++++++++ include/grub/i386/linux.h | 6 +++--- loader/i386/efi/linux.c | 4 ++-- loader/i386/linux.c | 6 +++--- 4 files changed, 17 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9ef3d3d42..a53cf9279 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2010-01-18 Robert Millan + + * include/grub/i386/linux.h (GRUB_VIDEO_TYPE_TEXT): Rename to ... + (GRUB_VIDEO_LINUX_TYPE_TEXT): ... this. Update all users. + (GRUB_VIDEO_TYPE_VLFB): Rename to ... + (GRUB_VIDEO_LINUX_TYPE_VESA): ... this. Update all users. + (GRUB_VIDEO_TYPE_EFI): Rename to ... + (GRUB_VIDEO_LINUX_TYPE_SIMPLE): ... this. Update all users. + 2010-01-17 Robert Millan * include/grub/test.h: Add license header. diff --git a/include/grub/i386/linux.h b/include/grub/i386/linux.h index 8a5a84da3..f02a722d6 100644 --- a/include/grub/i386/linux.h +++ b/include/grub/i386/linux.h @@ -79,9 +79,9 @@ struct grub_e820_mmap grub_uint32_t type; } __attribute__((packed)); -#define GRUB_VIDEO_TYPE_TEXT 0x01 -#define GRUB_VIDEO_TYPE_VLFB 0x23 /* VESA VGA in graphic mode */ -#define GRUB_VIDEO_TYPE_EFI 0x70 +#define GRUB_VIDEO_LINUX_TYPE_TEXT 0x01 +#define GRUB_VIDEO_LINUX_TYPE_VESA 0x23 /* VESA VGA in graphic mode. */ +#define GRUB_VIDEO_LINUX_TYPE_SIMPLE 0x70 /* Linear framebuffer without any additional functions. */ /* For the Linux/i386 boot protocol version 2.03. */ struct linux_kernel_header diff --git a/loader/i386/efi/linux.c b/loader/i386/efi/linux.c index 1abcc06db..2e26f3929 100644 --- a/loader/i386/efi/linux.c +++ b/loader/i386/efi/linux.c @@ -587,7 +587,7 @@ grub_linux_setup_video (struct linux_kernel_params *params) params->reserved_mask_size = 8; params->reserved_field_pos = 24; - params->have_vga = GRUB_VIDEO_TYPE_VLFB; + params->have_vga = GRUB_VIDEO_LINUX_TYPE_VESA; params->vid_mode = 0x338; /* 1024x768x32 */ return 0; @@ -852,7 +852,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), else if (grub_memcmp (argv[i], "video=efifb", 11) == 0) { if (params->have_vga) - params->have_vga = GRUB_VIDEO_TYPE_EFI; + params->have_vga = GRUB_VIDEO_LINUX_TYPE_SIMPLE; } /* Specify the boot file. */ diff --git a/loader/i386/linux.c b/loader/i386/linux.c index 7712bf2bf..a81e84135 100644 --- a/loader/i386/linux.c +++ b/loader/i386/linux.c @@ -538,16 +538,16 @@ grub_linux_boot (void) } if (! grub_linux_setup_video (params)) - params->have_vga = GRUB_VIDEO_TYPE_VLFB; + params->have_vga = GRUB_VIDEO_LINUX_TYPE_VESA; else { - params->have_vga = GRUB_VIDEO_TYPE_TEXT; + params->have_vga = GRUB_VIDEO_LINUX_TYPE_TEXT; params->video_width = 80; params->video_height = 25; } /* Initialize these last, because terminal position could be affected by printfs above. */ - if (params->have_vga == GRUB_VIDEO_TYPE_TEXT) + if (params->have_vga == GRUB_VIDEO_LINUX_TYPE_TEXT) { grub_term_output_t term; int found = 0; From 2997c41ffd1bb3c27e9ed3dd0b3ae25da4986e39 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Mon, 18 Jan 2010 16:58:31 +0530 Subject: [PATCH 222/738] update copyright year --- util/grub-script-check.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/grub-script-check.c b/util/grub-script-check.c index bfb44c511..3bfd6a425 100644 --- a/util/grub-script-check.c +++ b/util/grub-script-check.c @@ -1,7 +1,7 @@ /* grub-script-check.c - check grub script file for syntax errors */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2003,2004,2005,2006,2007,2008,2009 Free Software Foundation, Inc. + * Copyright (C) 2003,2004,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc. * * GRUB is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by From 88d170128f13c6cd31c9e164fe6bc656d94ffb7c Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Mon, 18 Jan 2010 13:45:40 +0000 Subject: [PATCH 223/738] 2010-01-18 Robert Millan Fix annoying UI bug in rescue mode. Thanks to Tristan Gingold for spotting it back in 2008. Shame on me for forgetting he did. * kern/rescue_reader.c (grub_rescue_run): Skip zero-length lines. --- ChangeLog | 7 +++++++ kern/rescue_reader.c | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index a53cf9279..df7f90587 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-01-18 Robert Millan + + Fix annoying UI bug in rescue mode. Thanks to Tristan Gingold for + spotting it back in 2008. Shame on me for forgetting he did. + + * kern/rescue_reader.c (grub_rescue_run): Skip zero-length lines. + 2010-01-18 Robert Millan * include/grub/i386/linux.h (GRUB_VIDEO_TYPE_TEXT): Rename to ... diff --git a/kern/rescue_reader.c b/kern/rescue_reader.c index 732124b1a..f573cf41f 100644 --- a/kern/rescue_reader.c +++ b/kern/rescue_reader.c @@ -1,7 +1,7 @@ /* rescue_reader.c - rescue mode reader */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2009 Free Software Foundation, Inc. + * Copyright (C) 2009,2010 Free Software Foundation, Inc. * * GRUB is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -83,7 +83,7 @@ grub_rescue_run (void) grub_errno = GRUB_ERR_NONE; grub_rescue_read_line (&line, 0); - if (! line) + if (! line || line[0] == '\0') continue; grub_parser_get_current ()->parse_line (line, grub_rescue_read_line); From a2eaee157c8ccab8e7200fe1fb248dcf8dd74218 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Mon, 18 Jan 2010 19:49:19 +0530 Subject: [PATCH 224/738] Add missing ChangeLog entry for -r2078 --- ChangeLog | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ChangeLog b/ChangeLog index df7f90587..963d91514 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-01-18 BVK Chaitanya + + Added new tool, grub-scrit-check to verify grub.cfg syntax. + + * util/grub-script-check.c: grub-script-check tool. + * conf/common.rmk: Make rules for grub-script-check. + 2010-01-18 Robert Millan Fix annoying UI bug in rescue mode. Thanks to Tristan Gingold for From 2cb6be4bc2f0b4e5ab366116698451f2d862c899 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Mon, 18 Jan 2010 16:08:25 +0000 Subject: [PATCH 225/738] 2010-01-18 Robert Millan * loader/i386/efi/linux.c (grub_cmd_linux): Stop pretending we're ELILO. This is no longer necessary. --- ChangeLog | 5 +++++ loader/i386/efi/linux.c | 5 ++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 963d91514..f44ecc714 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-01-18 Robert Millan + + * loader/i386/efi/linux.c (grub_cmd_linux): Stop pretending we're + ELILO. This is no longer necessary. + 2010-01-18 BVK Chaitanya Added new tool, grub-scrit-check to verify grub.cfg syntax. diff --git a/loader/i386/efi/linux.c b/loader/i386/efi/linux.c index 2e26f3929..053c3ed22 100644 --- a/loader/i386/efi/linux.c +++ b/loader/i386/efi/linux.c @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2006,2007,2008,2009 Free Software Foundation, Inc. + * Copyright (C) 2006,2007,2008,2009,2010 Free Software Foundation, Inc. * * GRUB is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -676,8 +676,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), goto fail; } - /* XXX Linux assumes that only elilo can boot Linux on EFI!!! */ - params->type_of_loader = (LINUX_LOADER_ID_ELILO << 4); + params->type_of_loader = (LINUX_LOADER_ID_GRUB << 4); params->cl_magic = GRUB_LINUX_CL_MAGIC; params->cl_offset = 0x1000; From b2cab848777f66daa9fab089575805639d9eb213 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Mon, 18 Jan 2010 16:22:03 +0000 Subject: [PATCH 226/738] 2010-01-18 Robert Millan * acinclude.m4: Remove `nop' assembly instruction; it's not implemented by all architectures. --- ChangeLog | 5 +++++ acinclude.m4 | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index f44ecc714..8d117a5c4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-01-18 Robert Millan + + * acinclude.m4: Remove `nop' assembly instruction; it's not + implemented by all architectures. + 2010-01-18 Robert Millan * loader/i386/efi/linux.c (grub_cmd_linux): Stop pretending we're diff --git a/acinclude.m4 b/acinclude.m4 index 6f9baf18f..36a3b3e08 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -18,7 +18,7 @@ AC_DEFUN(grub_PROG_TARGET_CC, [AC_MSG_CHECKING([whether target compiler is working]) AC_CACHE_VAL(grub_cv_prog_target_cc, [AC_LINK_IFELSE([AC_LANG_PROGRAM([[ -asm (".globl start; start: nop"); +asm (".globl start; start:"); int main (void); ]], [[]])], [grub_cv_prog_target_cc=yes], From 262bff8d83bed88171cc2002d700a6bae75ba885 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 18 Jan 2010 17:40:23 +0100 Subject: [PATCH 227/738] 2010-01-18 Vladimir Serbinenko Add missing *BSD copyright headers. * include/grub/aout.h: Add BSD licence. * include/grub/i386/bsd.h: Parts under different licences moved to ... * include/grub/i386/freebsd_linker.h: ... here, * include/grub/i386/freebsd_reboot.h: ... here, * include/grub/i386/netbsd_bootinfo.h: ... here, * include/grub/i386/netbsd_reboot.h: ... here, * include/grub/i386/openbsd_bootarg.h: ... here, * include/grub/i386/openbsd_reboot.h: ... and here. Added appropriate licence to each file. --- ChangeLog | 14 ++ include/grub/aout.h | 32 +++++ include/grub/i386/bsd.h | 193 ++-------------------------- include/grub/i386/freebsd_linker.h | 74 +++++++++++ include/grub/i386/freebsd_reboot.h | 77 +++++++++++ include/grub/i386/netbsd_bootinfo.h | 112 ++++++++++++++++ include/grub/i386/netbsd_reboot.h | 81 ++++++++++++ include/grub/i386/openbsd_bootarg.h | 72 +++++++++++ include/grub/i386/openbsd_reboot.h | 79 ++++++++++++ 9 files changed, 553 insertions(+), 181 deletions(-) create mode 100644 include/grub/i386/freebsd_linker.h create mode 100644 include/grub/i386/freebsd_reboot.h create mode 100644 include/grub/i386/netbsd_bootinfo.h create mode 100644 include/grub/i386/netbsd_reboot.h create mode 100644 include/grub/i386/openbsd_bootarg.h create mode 100644 include/grub/i386/openbsd_reboot.h diff --git a/ChangeLog b/ChangeLog index 8d117a5c4..633ebd62a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2010-01-18 Vladimir Serbinenko + + Add missing *BSD copyright headers. + + * include/grub/aout.h: Add BSD licence. + * include/grub/i386/bsd.h: Parts under different licences moved to ... + * include/grub/i386/freebsd_linker.h: ... here, + * include/grub/i386/freebsd_reboot.h: ... here, + * include/grub/i386/netbsd_bootinfo.h: ... here, + * include/grub/i386/netbsd_reboot.h: ... here, + * include/grub/i386/openbsd_bootarg.h: ... here, + * include/grub/i386/openbsd_reboot.h: ... and here. Added appropriate + licence to each file. + 2010-01-18 Robert Millan * acinclude.m4: Remove `nop' assembly instruction; it's not diff --git a/include/grub/aout.h b/include/grub/aout.h index c5650ddf8..04e85f8b0 100644 --- a/include/grub/aout.h +++ b/include/grub/aout.h @@ -16,6 +16,38 @@ * along with GRUB. If not, see . */ +/*- + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * from: @(#)exec.h 8.1 (Berkeley) 6/11/93 + * $FreeBSD$ + */ + #ifndef GRUB_AOUT_HEADER #define GRUB_AOUT_HEADER 1 diff --git a/include/grub/i386/bsd.h b/include/grub/i386/bsd.h index 8ffaf7d18..53db09e61 100644 --- a/include/grub/i386/bsd.h +++ b/include/grub/i386/bsd.h @@ -20,6 +20,13 @@ #define GRUB_BSD_CPU_HEADER 1 #include +#include +#include +#include +#include +#include +#include + enum bsd_kernel_types { @@ -31,62 +38,15 @@ enum bsd_kernel_types #define GRUB_BSD_TEMP_BUFFER 0x80000 -#define FREEBSD_RB_ASKNAME (1 << 0) /* ask for file name to reboot from */ -#define FREEBSD_RB_SINGLE (1 << 1) /* reboot to single user only */ -#define FREEBSD_RB_NOSYNC (1 << 2) /* dont sync before reboot */ -#define FREEBSD_RB_HALT (1 << 3) /* don't reboot, just halt */ -#define FREEBSD_RB_INITNAME (1 << 4) /* name given for /etc/init (unused) */ -#define FREEBSD_RB_DFLTROOT (1 << 5) /* use compiled-in rootdev */ -#define FREEBSD_RB_KDB (1 << 6) /* give control to kernel debugger */ -#define FREEBSD_RB_RDONLY (1 << 7) /* mount root fs read-only */ -#define FREEBSD_RB_DUMP (1 << 8) /* dump kernel memory before reboot */ -#define FREEBSD_RB_MINIROOT (1 << 9) /* mini-root present in memory at boot time */ -#define FREEBSD_RB_CONFIG (1 << 10) /* invoke user configuration routing */ -#define FREEBSD_RB_VERBOSE (1 << 11) /* print all potentially useful info */ -#define FREEBSD_RB_SERIAL (1 << 12) /* user serial port as console */ -#define FREEBSD_RB_CDROM (1 << 13) /* use cdrom as root */ -#define FREEBSD_RB_GDB (1 << 15) /* use GDB remote debugger instead of DDB */ -#define FREEBSD_RB_MUTE (1 << 16) /* Come up with the console muted */ -#define FREEBSD_RB_PAUSE (1 << 20) -#define FREEBSD_RB_QUIET (1 << 21) -#define FREEBSD_RB_NOINTR (1 << 28) -#define FREENSD_RB_MULTIPLE (1 << 29) /* Use multiple consoles */ -#define FREEBSD_RB_DUAL FREENSD_RB_MULTIPLE -#define FREEBSD_RB_BOOTINFO (1 << 31) /* have `struct bootinfo *' arg */ - -#define FREEBSD_B_DEVMAGIC 0xa0000000 -#define FREEBSD_B_SLICESHIFT 20 -#define FREEBSD_B_UNITSHIFT 16 -#define FREEBSD_B_PARTSHIFT 8 -#define FREEBSD_B_TYPESHIFT 0 +#define FREEBSD_B_DEVMAGIC OPENBSD_B_DEVMAGIC +#define FREEBSD_B_SLICESHIFT OPENBSD_B_CTRLSHIFT +#define FREEBSD_B_UNITSHIFT OPENBSD_B_UNITSHIFT +#define FREEBSD_B_PARTSHIFT OPENBSD_B_PARTSHIFT +#define FREEBSD_B_TYPESHIFT OPENBSD_B_TYPESHIFT #define FREEBSD_BOOTINFO_VERSION 1 #define FREEBSD_N_BIOS_GEOM 8 -#define FREEBSD_MODINFO_END 0x0000 /* End of list */ -#define FREEBSD_MODINFO_NAME 0x0001 /* Name of module (string) */ -#define FREEBSD_MODINFO_TYPE 0x0002 /* Type of module (string) */ -#define FREEBSD_MODINFO_ADDR 0x0003 /* Loaded address */ -#define FREEBSD_MODINFO_SIZE 0x0004 /* Size of module */ -#define FREEBSD_MODINFO_EMPTY 0x0005 /* Has been deleted */ -#define FREEBSD_MODINFO_ARGS 0x0006 /* Parameters string */ -#define FREEBSD_MODINFO_METADATA 0x8000 /* Module-specfic */ - -#define FREEBSD_MODINFOMD_AOUTEXEC 0x0001 /* a.out exec header */ -#define FREEBSD_MODINFOMD_ELFHDR 0x0002 /* ELF header */ -#define FREEBSD_MODINFOMD_SSYM 0x0003 /* start of symbols */ -#define FREEBSD_MODINFOMD_ESYM 0x0004 /* end of symbols */ -#define FREEBSD_MODINFOMD_DYNAMIC 0x0005 /* _DYNAMIC pointer */ -#define FREEBSD_MODINFOMD_ENVP 0x0006 /* envp[] */ -#define FREEBSD_MODINFOMD_HOWTO 0x0007 /* boothowto */ -#define FREEBSD_MODINFOMD_KERNEND 0x0008 /* kernend */ -#define FREEBSD_MODINFOMD_SHDR 0x0009 /* section header table */ -#define FREEBSD_MODINFOMD_NOCOPY 0x8000 /* don't copy this metadata to the kernel */ - -#define FREEBSD_MODINFOMD_SMAP 0x1001 - -#define FREEBSD_MODINFOMD_DEPLIST (0x4001 | FREEBSD_MODINFOMD_NOCOPY) /* depends on */ - #define FREEBSD_MODTYPE_KERNEL "elf kernel" #define FREEBSD_MODTYPE_KERNEL64 "elf64 kernel" #define FREEBSD_MODTYPE_ELF_MODULE "elf module" @@ -113,44 +73,6 @@ struct grub_freebsd_bootinfo grub_uint32_t bi_modulep; } __attribute__ ((packed)); -#define OPENBSD_RB_ASKNAME (1 << 0) /* ask for file name to reboot from */ -#define OPENBSD_RB_SINGLE (1 << 1) /* reboot to single user only */ -#define OPENBSD_RB_NOSYNC (1 << 2) /* dont sync before reboot */ -#define OPENBSD_RB_HALT (1 << 3) /* don't reboot, just halt */ -#define OPENBSD_RB_INITNAME (1 << 4) /* name given for /etc/init (unused) */ -#define OPENBSD_RB_DFLTROOT (1 << 5) /* use compiled-in rootdev */ -#define OPENBSD_RB_KDB (1 << 6) /* give control to kernel debugger */ -#define OPENBSD_RB_RDONLY (1 << 7) /* mount root fs read-only */ -#define OPENBSD_RB_DUMP (1 << 8) /* dump kernel memory before reboot */ -#define OPENBSD_RB_MINIROOT (1 << 9) /* mini-root present in memory at boot time */ -#define OPENBSD_RB_CONFIG (1 << 10) /* change configured devices */ -#define OPENBSD_RB_TIMEBAD (1 << 11) /* don't call resettodr() in boot() */ -#define OPENBSD_RB_POWERDOWN (1 << 12) /* attempt to power down machine */ -#define OPENBSD_RB_SERCONS (1 << 13) /* use serial console if available */ -#define OPENBSD_RB_USERREQ (1 << 14) /* boot() called at user request (e.g. ddb) */ - -#define OPENBSD_B_DEVMAGIC 0xa0000000 -#define OPENBSD_B_ADAPTORSHIFT 24 -#define OPENBSD_B_CTRLSHIFT 20 -#define OPENBSD_B_UNITSHIFT 16 -#define OPENBSD_B_PARTSHIFT 8 -#define OPENBSD_B_TYPESHIFT 0 - -#define OPENBSD_BOOTARG_APIVER (OPENBSD_BAPIV_VECTOR | \ - OPENBSD_BAPIV_ENV | \ - OPENBSD_BAPIV_BMEMMAP) - -#define OPENBSD_BAPIV_ANCIENT 0x0 /* MD old i386 bootblocks */ -#define OPENBSD_BAPIV_VARS 0x1 /* MD structure w/ add info passed */ -#define OPENBSD_BAPIV_VECTOR 0x2 /* MI vector of MD structures passed */ -#define OPENBSD_BAPIV_ENV 0x4 /* MI environment vars vector */ -#define OPENBSD_BAPIV_BMEMMAP 0x8 /* MI memory map passed is in bytes */ - -#define OPENBSD_BOOTARG_ENV 0x1000 -#define OPENBSD_BOOTARG_END -1 - -#define OPENBSD_BOOTARG_MMAP 0 - struct grub_openbsd_bios_mmap { grub_uint64_t addr; @@ -162,97 +84,6 @@ struct grub_openbsd_bios_mmap grub_uint32_t type; }; -struct grub_openbsd_bootargs -{ - int ba_type; - int ba_size; - struct grub_openbsd_bootargs *ba_next; -} __attribute__ ((packed)); - -#define NETBSD_RB_AUTOBOOT 0 /* flags for system auto-booting itself */ - -#define NETBSD_RB_ASKNAME (1 << 0) /* ask for file name to reboot from */ -#define NETBSD_RB_SINGLE (1 << 1) /* reboot to single user only */ -#define NETBSD_RB_NOSYNC (1 << 2) /* dont sync before reboot */ -#define NETBSD_RB_HALT (1 << 3) /* don't reboot, just halt */ -#define NETBSD_RB_INITNAME (1 << 4) /* name given for /etc/init (unused) */ -#define NETBSD_RB_UNUSED1 (1 << 5) /* was RB_DFLTROOT, obsolete */ -#define NETBSD_RB_KDB (1 << 6) /* give control to kernel debugger */ -#define NETBSD_RB_RDONLY (1 << 7) /* mount root fs read-only */ -#define NETBSD_RB_DUMP (1 << 8) /* dump kernel memory before reboot */ -#define NETBSD_RB_MINIROOT (1 << 9) /* mini-root present in memory at boot time */ -#define NETBSD_RB_STRING (1 << 10) /* use provided bootstr */ -#define NETBSD_RB_POWERDOWN ((1 << 11) | RB_HALT) /* turn power off (or at least halt) */ -#define NETBSD_RB_USERCONFIG (1 << 12) /* change configured devices */ - -#define NETBSD_AB_NORMAL 0 /* boot normally (default) */ - -#define NETBSD_AB_QUIET (1 << 16) /* boot quietly */ -#define NETBSD_AB_VERBOSE (1 << 17) /* boot verbosely */ -#define NETBSD_AB_SILENT (1 << 18) /* boot silently */ -#define NETBSD_AB_DEBUG (1 << 19) /* boot with debug messages */ -#define NETBSD_AB_NOSMP (1 << 28) /* Boot without SMP support. */ -#define NETBSD_AB_NOACPI (1 << 29) /* Boot without ACPI support. */ - -struct grub_netbsd_bootinfo -{ - grub_uint32_t bi_count; - void *bi_data[1]; -}; - -#define NETBSD_BTINFO_BOOTPATH 0 -#define NETBSD_BTINFO_ROOTDEVICE 1 -#define NETBSD_BTINFO_BOOTDISK 3 -#define NETBSD_BTINFO_MEMMAP 9 - -struct grub_netbsd_btinfo_common -{ - int len; - int type; -}; - -struct grub_netbsd_btinfo_mmap_header -{ - struct grub_netbsd_btinfo_common common; - grub_uint32_t count; -}; - -struct grub_netbsd_btinfo_mmap_entry -{ - grub_uint64_t addr; - grub_uint64_t len; -#define NETBSD_MMAP_AVAILABLE 1 -#define NETBSD_MMAP_RESERVED 2 -#define NETBSD_MMAP_ACPI 3 -#define NETBSD_MMAP_NVS 4 - grub_uint32_t type; -}; - -struct grub_netbsd_btinfo_bootpath -{ - struct grub_netbsd_btinfo_common common; - char bootpath[80]; -}; - -struct grub_netbsd_btinfo_rootdevice -{ - struct grub_netbsd_btinfo_common common; - char devname[16]; -}; - -struct grub_netbsd_btinfo_bootdisk -{ - struct grub_netbsd_btinfo_common common; - int labelsector; /* label valid if != -1 */ - struct - { - grub_uint16_t type, checksum; - char packname[16]; - } label; - int biosdev; - int partition; -}; - void grub_unix_real_boot (grub_addr_t entry, ...) __attribute__ ((cdecl,noreturn)); grub_err_t grub_freebsd_load_elfmodule32 (grub_file_t file, int argc, diff --git a/include/grub/i386/freebsd_linker.h b/include/grub/i386/freebsd_linker.h new file mode 100644 index 000000000..3c1eb64b6 --- /dev/null +++ b/include/grub/i386/freebsd_linker.h @@ -0,0 +1,74 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +/*- + * Copyright (c) 1997-2000 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: stable/8/sys/sys/linker.h 199583 2009-11-20 15:27:52Z jhb $ + */ + +#ifndef GRUB_FREEBSD_LINKER_CPU_HEADER +#define GRUB_FREEBSD_LINKER_CPU_HEADER 1 + +#define FREEBSD_MODINFO_END 0x0000 /* End of list */ +#define FREEBSD_MODINFO_NAME 0x0001 /* Name of module (string) */ +#define FREEBSD_MODINFO_TYPE 0x0002 /* Type of module (string) */ +#define FREEBSD_MODINFO_ADDR 0x0003 /* Loaded address */ +#define FREEBSD_MODINFO_SIZE 0x0004 /* Size of module */ +#define FREEBSD_MODINFO_EMPTY 0x0005 /* Has been deleted */ +#define FREEBSD_MODINFO_ARGS 0x0006 /* Parameters string */ +#define FREEBSD_MODINFO_METADATA 0x8000 /* Module-specfic */ + +#define FREEBSD_MODINFOMD_AOUTEXEC 0x0001 /* a.out exec header */ +#define FREEBSD_MODINFOMD_ELFHDR 0x0002 /* ELF header */ +#define FREEBSD_MODINFOMD_SSYM 0x0003 /* start of symbols */ +#define FREEBSD_MODINFOMD_ESYM 0x0004 /* end of symbols */ +#define FREEBSD_MODINFOMD_DYNAMIC 0x0005 /* _DYNAMIC pointer */ +#define FREEBSD_MODINFOMD_ENVP 0x0006 /* envp[] */ +#define FREEBSD_MODINFOMD_HOWTO 0x0007 /* boothowto */ +#define FREEBSD_MODINFOMD_KERNEND 0x0008 /* kernend */ +#define FREEBSD_MODINFOMD_SHDR 0x0009 /* section header table */ +#define FREEBSD_MODINFOMD_NOCOPY 0x8000 /* don't copy this metadata to the kernel */ + +#define FREEBSD_MODINFOMD_SMAP 0x1001 + +#define FREEBSD_MODINFOMD_DEPLIST (0x4001 | FREEBSD_MODINFOMD_NOCOPY) /* depends on */ + +#endif diff --git a/include/grub/i386/freebsd_reboot.h b/include/grub/i386/freebsd_reboot.h new file mode 100644 index 000000000..9c17f6efa --- /dev/null +++ b/include/grub/i386/freebsd_reboot.h @@ -0,0 +1,77 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +/*- + * Copyright (c) 1982, 1986, 1988, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)reboot.h 8.3 (Berkeley) 12/13/94 + * $FreeBSD: stable/8/sys/sys/reboot.h 199583 2009-11-20 15:27:52Z jhb $ + */ + +#ifndef GRUB_FREEBSD_REBOOT_CPU_HEADER +#define GRUB_FREEBSD_REBOOT_CPU_HEADER 1 + +#define FREEBSD_RB_ASKNAME (1 << 0) /* ask for file name to reboot from */ +#define FREEBSD_RB_SINGLE (1 << 1) /* reboot to single user only */ +#define FREEBSD_RB_NOSYNC (1 << 2) /* dont sync before reboot */ +#define FREEBSD_RB_HALT (1 << 3) /* don't reboot, just halt */ +#define FREEBSD_RB_INITNAME (1 << 4) /* name given for /etc/init (unused) */ +#define FREEBSD_RB_DFLTROOT (1 << 5) /* use compiled-in rootdev */ +#define FREEBSD_RB_KDB (1 << 6) /* give control to kernel debugger */ +#define FREEBSD_RB_RDONLY (1 << 7) /* mount root fs read-only */ +#define FREEBSD_RB_DUMP (1 << 8) /* dump kernel memory before reboot */ +#define FREEBSD_RB_MINIROOT (1 << 9) /* mini-root present in memory at boot time */ +#define FREEBSD_RB_CONFIG (1 << 10) /* invoke user configuration routing */ +#define FREEBSD_RB_VERBOSE (1 << 11) /* print all potentially useful info */ +#define FREEBSD_RB_SERIAL (1 << 12) /* user serial port as console */ +#define FREEBSD_RB_CDROM (1 << 13) /* use cdrom as root */ +#define FREEBSD_RB_GDB (1 << 15) /* use GDB remote debugger instead of DDB */ +#define FREEBSD_RB_MUTE (1 << 16) /* Come up with the console muted */ +#define FREEBSD_RB_PAUSE (1 << 20) +#define FREEBSD_RB_QUIET (1 << 21) +#define FREEBSD_RB_NOINTR (1 << 28) +#define FREENSD_RB_MULTIPLE (1 << 29) /* Use multiple consoles */ +#define FREEBSD_RB_DUAL FREENSD_RB_MULTIPLE +#define FREEBSD_RB_BOOTINFO (1 << 31) /* have `struct bootinfo *' arg */ + +#endif diff --git a/include/grub/i386/netbsd_bootinfo.h b/include/grub/i386/netbsd_bootinfo.h new file mode 100644 index 000000000..776ecf3b0 --- /dev/null +++ b/include/grub/i386/netbsd_bootinfo.h @@ -0,0 +1,112 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +/* $NetBSD: bootinfo.h,v 1.16 2009/08/24 02:15:46 jmcneill Exp $ */ + +/* + * Copyright (c) 1997 + * Matthias Drochner. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef GRUB_NETBSD_BOOTINFO_CPU_HEADER +#define GRUB_NETBSD_BOOTINFO_CPU_HEADER 1 + +#include + + +#define NETBSD_BTINFO_BOOTPATH 0 +#define NETBSD_BTINFO_ROOTDEVICE 1 +#define NETBSD_BTINFO_BOOTDISK 3 +#define NETBSD_BTINFO_MEMMAP 9 + +struct grub_netbsd_btinfo_common +{ + int len; + int type; +}; + +struct grub_netbsd_btinfo_mmap_header +{ + struct grub_netbsd_btinfo_common common; + grub_uint32_t count; +}; + +struct grub_netbsd_btinfo_mmap_entry +{ + grub_uint64_t addr; + grub_uint64_t len; +#define NETBSD_MMAP_AVAILABLE 1 +#define NETBSD_MMAP_RESERVED 2 +#define NETBSD_MMAP_ACPI 3 +#define NETBSD_MMAP_NVS 4 + grub_uint32_t type; +}; + +struct grub_netbsd_btinfo_bootpath +{ + struct grub_netbsd_btinfo_common common; + char bootpath[80]; +}; + +struct grub_netbsd_btinfo_rootdevice +{ + struct grub_netbsd_btinfo_common common; + char devname[16]; +}; + +struct grub_netbsd_btinfo_bootdisk +{ + struct grub_netbsd_btinfo_common common; + int labelsector; /* label valid if != -1 */ + struct + { + grub_uint16_t type, checksum; + char packname[16]; + } label; + int biosdev; + int partition; +}; + +struct grub_netbsd_bootinfo +{ + grub_uint32_t bi_count; + void *bi_data[1]; +}; + +#endif diff --git a/include/grub/i386/netbsd_reboot.h b/include/grub/i386/netbsd_reboot.h new file mode 100644 index 000000000..ee82455bc --- /dev/null +++ b/include/grub/i386/netbsd_reboot.h @@ -0,0 +1,81 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +/* $NetBSD: reboot.h,v 1.25 2007/12/25 18:33:48 perry Exp $ */ + +/* + * Copyright (c) 1982, 1986, 1988, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)reboot.h 8.3 (Berkeley) 12/13/94 + */ + +#ifndef GRUB_NETBSD_REBOOT_CPU_HEADER +#define GRUB_NETBSD_REBOOT_CPU_HEADER 1 + +#define NETBSD_RB_AUTOBOOT 0 /* flags for system auto-booting itself */ + +#define NETBSD_RB_ASKNAME (1 << 0) /* ask for file name to reboot from */ +#define NETBSD_RB_SINGLE (1 << 1) /* reboot to single user only */ +#define NETBSD_RB_NOSYNC (1 << 2) /* dont sync before reboot */ +#define NETBSD_RB_HALT (1 << 3) /* don't reboot, just halt */ +#define NETBSD_RB_INITNAME (1 << 4) /* name given for /etc/init (unused) */ +#define NETBSD_RB_UNUSED1 (1 << 5) /* was RB_DFLTROOT, obsolete */ +#define NETBSD_RB_KDB (1 << 6) /* give control to kernel debugger */ +#define NETBSD_RB_RDONLY (1 << 7) /* mount root fs read-only */ +#define NETBSD_RB_DUMP (1 << 8) /* dump kernel memory before reboot */ +#define NETBSD_RB_MINIROOT (1 << 9) /* mini-root present in memory at boot time */ +#define NETBSD_RB_STRING (1 << 10) /* use provided bootstr */ +#define NETBSD_RB_POWERDOWN ((1 << 11) | RB_HALT) /* turn power off (or at least halt) */ +#define NETBSD_RB_USERCONFIG (1 << 12) /* change configured devices */ + +#define NETBSD_AB_NORMAL 0 /* boot normally (default) */ + +#define NETBSD_AB_QUIET (1 << 16) /* boot quietly */ +#define NETBSD_AB_VERBOSE (1 << 17) /* boot verbosely */ +#define NETBSD_AB_SILENT (1 << 18) /* boot silently */ +#define NETBSD_AB_DEBUG (1 << 19) /* boot with debug messages */ +#define NETBSD_AB_NOSMP (1 << 28) /* Boot without SMP support. */ +#define NETBSD_AB_NOACPI (1 << 29) /* Boot without ACPI support. */ + + +#endif diff --git a/include/grub/i386/openbsd_bootarg.h b/include/grub/i386/openbsd_bootarg.h new file mode 100644 index 000000000..ccbe1ca12 --- /dev/null +++ b/include/grub/i386/openbsd_bootarg.h @@ -0,0 +1,72 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +/* $OpenBSD: bootarg.h,v 1.11 2003/06/02 20:20:54 mickey Exp $ */ + +/* + * Copyright (c) 1996-1999 Michael Shalayeff + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef GRUB_OPENBSD_BOOTARG_CPU_HEADER +#define GRUB_OPENBSD_BOOTARG_CPU_HEADER 1 + +#define OPENBSD_BOOTARG_APIVER (OPENBSD_BAPIV_VECTOR | \ + OPENBSD_BAPIV_ENV | \ + OPENBSD_BAPIV_BMEMMAP) + +#define OPENBSD_BAPIV_ANCIENT 0x0 /* MD old i386 bootblocks */ +#define OPENBSD_BAPIV_VARS 0x1 /* MD structure w/ add info passed */ +#define OPENBSD_BAPIV_VECTOR 0x2 /* MI vector of MD structures passed */ +#define OPENBSD_BAPIV_ENV 0x4 /* MI environment vars vector */ +#define OPENBSD_BAPIV_BMEMMAP 0x8 /* MI memory map passed is in bytes */ + +#define OPENBSD_BOOTARG_ENV 0x1000 +#define OPENBSD_BOOTARG_END -1 + +#define OPENBSD_BOOTARG_MMAP 0 + +struct grub_openbsd_bootargs +{ + int ba_type; + int ba_size; + struct grub_openbsd_bootargs *ba_next; +} __attribute__ ((packed)); + +#endif diff --git a/include/grub/i386/openbsd_reboot.h b/include/grub/i386/openbsd_reboot.h new file mode 100644 index 000000000..3f6571a44 --- /dev/null +++ b/include/grub/i386/openbsd_reboot.h @@ -0,0 +1,79 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +/* $OpenBSD: reboot.h,v 1.13 2004/03/10 23:02:53 tom Exp $ */ +/* $NetBSD: reboot.h,v 1.9 1996/04/22 01:23:25 christos Exp $ */ + +/* + * Copyright (c) 1982, 1986, 1988, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)reboot.h 8.2 (Berkeley) 7/10/94 + */ + +#ifndef GRUB_OPENBSD_REBOOT_CPU_HEADER +#define GRUB_OPENBSD_REBOOT_CPU_HEADER 1 + +#define OPENBSD_RB_ASKNAME (1 << 0) /* ask for file name to reboot from */ +#define OPENBSD_RB_SINGLE (1 << 1) /* reboot to single user only */ +#define OPENBSD_RB_NOSYNC (1 << 2) /* dont sync before reboot */ +#define OPENBSD_RB_HALT (1 << 3) /* don't reboot, just halt */ +#define OPENBSD_RB_INITNAME (1 << 4) /* name given for /etc/init (unused) */ +#define OPENBSD_RB_DFLTROOT (1 << 5) /* use compiled-in rootdev */ +#define OPENBSD_RB_KDB (1 << 6) /* give control to kernel debugger */ +#define OPENBSD_RB_RDONLY (1 << 7) /* mount root fs read-only */ +#define OPENBSD_RB_DUMP (1 << 8) /* dump kernel memory before reboot */ +#define OPENBSD_RB_MINIROOT (1 << 9) /* mini-root present in memory at boot time */ +#define OPENBSD_RB_CONFIG (1 << 10) /* change configured devices */ +#define OPENBSD_RB_TIMEBAD (1 << 11) /* don't call resettodr() in boot() */ +#define OPENBSD_RB_POWERDOWN (1 << 12) /* attempt to power down machine */ +#define OPENBSD_RB_SERCONS (1 << 13) /* use serial console if available */ +#define OPENBSD_RB_USERREQ (1 << 14) /* boot() called at user request (e.g. ddb) */ + +#define OPENBSD_B_DEVMAGIC 0xa0000000 +#define OPENBSD_B_ADAPTORSHIFT 24 +#define OPENBSD_B_CTRLSHIFT 20 +#define OPENBSD_B_UNITSHIFT 16 +#define OPENBSD_B_PARTSHIFT 8 +#define OPENBSD_B_TYPESHIFT 0 + +#endif From 6f7db5d676bee808d78e9775747d06abebb280b6 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 18 Jan 2010 19:25:20 +0100 Subject: [PATCH 228/738] 2010-01-18 Vladimir Serbinenko * include/grub/i386/bsd.h: Fix include pathes. --- ChangeLog | 4 ++++ include/grub/i386/bsd.h | 12 ++++++------ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 633ebd62a..7b22a6aea 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-01-18 Vladimir Serbinenko + + * include/grub/i386/bsd.h: Fix include pathes. + 2010-01-18 Vladimir Serbinenko Add missing *BSD copyright headers. diff --git a/include/grub/i386/bsd.h b/include/grub/i386/bsd.h index 53db09e61..e26c35652 100644 --- a/include/grub/i386/bsd.h +++ b/include/grub/i386/bsd.h @@ -20,12 +20,12 @@ #define GRUB_BSD_CPU_HEADER 1 #include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include enum bsd_kernel_types From cba98e8dbc6744c7c947d7fa81949ec30f40442e Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Mon, 18 Jan 2010 19:31:10 +0000 Subject: [PATCH 229/738] 2010-01-18 Robert Millan * commands/terminal.c (grub_cmd_terminal_input) (grub_cmd_terminal_output): Check return of terminal init() routines, and abort if errors are raised. --- ChangeLog | 6 ++++++ commands/terminal.c | 20 ++++++++++++-------- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7b22a6aea..3111a9381 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-01-18 Robert Millan + + * commands/terminal.c (grub_cmd_terminal_input) + (grub_cmd_terminal_output): Check return of terminal init() + routines, and abort if errors are raised. + 2010-01-18 Vladimir Serbinenko * include/grub/i386/bsd.h: Fix include pathes. diff --git a/commands/terminal.c b/commands/terminal.c index b30f43130..bf4187180 100644 --- a/commands/terminal.c +++ b/commands/terminal.c @@ -112,10 +112,11 @@ grub_cmd_terminal_input (grub_command_t cmd __attribute__ ((unused)), break; if (term) { + if (term->init && term->init () != GRUB_ERR_NONE) + return grub_errno; + grub_list_remove (GRUB_AS_LIST_P (&(grub_term_inputs_disabled)), GRUB_AS_LIST (term)); - if (term->init) - term->init (); grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs), GRUB_AS_LIST (term)); } @@ -152,10 +153,11 @@ grub_cmd_terminal_input (grub_command_t cmd __attribute__ ((unused)), break; if (term) { + if (term->init && term->init () != GRUB_ERR_NONE) + return grub_errno; + grub_list_remove (GRUB_AS_LIST_P (&(grub_term_inputs_disabled)), GRUB_AS_LIST (term)); - if (term->init) - term->init (); grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs), GRUB_AS_LIST (term)); } @@ -269,10 +271,11 @@ grub_cmd_terminal_output (grub_command_t cmd __attribute__ ((unused)), break; if (term) { + if (term->init && term->init () != GRUB_ERR_NONE) + return grub_errno; + grub_list_remove (GRUB_AS_LIST_P (&(grub_term_outputs_disabled)), GRUB_AS_LIST (term)); - if (term->init) - term->init (); grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs), GRUB_AS_LIST (term)); } @@ -310,10 +313,11 @@ grub_cmd_terminal_output (grub_command_t cmd __attribute__ ((unused)), break; if (term) { + if (term->init && term->init () != GRUB_ERR_NONE) + return grub_errno; + grub_list_remove (GRUB_AS_LIST_P (&(grub_term_outputs_disabled)), GRUB_AS_LIST (term)); - if (term->init) - term->init (); grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs), GRUB_AS_LIST (term)); } From 9444b678a11af01e6432353f0f456f8640d0aeb0 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Mon, 18 Jan 2010 19:43:39 +0000 Subject: [PATCH 230/738] 2010-01-18 Robert Millan * include/grub/term.h (grub_term_register_input, grub_term_register_output): Check return of terminal init() routines, and abort if errors are raised. * commands/terminal.c: Update copyright year. --- ChangeLog | 8 ++++++++ commands/terminal.c | 2 +- include/grub/term.h | 12 +++++------- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3111a9381..40984c187 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2010-01-18 Robert Millan + + * include/grub/term.h (grub_term_register_input, + grub_term_register_output): Check return of terminal init() + routines, and abort if errors are raised. + + * commands/terminal.c: Update copyright year. + 2010-01-18 Robert Millan * commands/terminal.c (grub_cmd_terminal_input) diff --git a/commands/terminal.c b/commands/terminal.c index bf4187180..e725123b8 100644 --- a/commands/terminal.c +++ b/commands/terminal.c @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2009 Free Software Foundation, Inc. + * Copyright (C) 2009,2010 Free Software Foundation, Inc. * * GRUB is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/include/grub/term.h b/include/grub/term.h index 3d644b848..143aabe1e 100644 --- a/include/grub/term.h +++ b/include/grub/term.h @@ -208,9 +208,8 @@ grub_term_register_input (const char *name __attribute__ ((unused)), else { /* If this is the first terminal, enable automatically. */ - if (term->init) - term->init (); - grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs), GRUB_AS_LIST (term)); + if (! term->init || term->init () == GRUB_ERR_NONE) + grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs), GRUB_AS_LIST (term)); } } @@ -224,10 +223,9 @@ grub_term_register_output (const char *name __attribute__ ((unused)), else { /* If this is the first terminal, enable automatically. */ - if (term->init) - term->init (); - grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs), - GRUB_AS_LIST (term)); + if (! term->init || term->init () == GRUB_ERR_NONE) + grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs), + GRUB_AS_LIST (term)); } } From 41f683d45610aaa7e9da629a5388c386b7f2dd31 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Mon, 18 Jan 2010 20:20:34 +0000 Subject: [PATCH 231/738] 2010-01-18 Robert Millan * include/grub/term.h (grub_term_register_input, grub_term_register_output): Check return of terminal init() routines, and abort if errors are raised. * commands/terminal.c: Update copyright year. --- ChangeLog.kernel-font | 7 +++++++ conf/common.rmk | 5 +++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/ChangeLog.kernel-font b/ChangeLog.kernel-font index 576c85904..73f8a895e 100644 --- a/ChangeLog.kernel-font +++ b/ChangeLog.kernel-font @@ -1,3 +1,10 @@ +2010-01-18 Robert Millan + + Fix parallel builds. + + * conf/common.rmk (font/font.c_DEPENDENCIES): New variable (makes + font.c depend on ascii.h). + 2010-01-12 Carles Pina i Estany * Makefile.in (DUSE_ASCII_FAILBACK): New macro. diff --git a/conf/common.rmk b/conf/common.rmk index a83bd0fca..956ed8ec3 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -600,7 +600,7 @@ sh_mod_LDFLAGS = $(COMMON_LDFLAGS) # Common Video Subsystem specific modules. pkglib_MODULES += video.mod videotest.mod bitmap.mod tga.mod jpeg.mod \ - png.mod font.mod gfxterm.mod video_fb.mod + png.mod gfxterm.mod video_fb.mod # For video.mod. video_mod_SOURCES = video/video.c @@ -637,7 +637,8 @@ png_mod_SOURCES = video/readers/png.c png_mod_CFLAGS = $(COMMON_CFLAGS) png_mod_LDFLAGS = $(COMMON_LDFLAGS) -# For font.mod. +pkglib_MODULES += font.mod +font/font.c_DEPENDENCIES = ascii.h font_mod_SOURCES = font/font_cmd.c font/font.c font_mod_CFLAGS = $(COMMON_CFLAGS) font_mod_LDFLAGS = $(COMMON_LDFLAGS) From 4df7b90f9434e341fd0402acb578d11b44eb5de3 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Mon, 18 Jan 2010 22:07:05 +0000 Subject: [PATCH 232/738] Add (unused) mode_mask parameter to grub_video_sm712_setup() --- video/sm712.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/video/sm712.c b/video/sm712.c index 5383b695e..1e0f59b9d 100644 --- a/video/sm712.c +++ b/video/sm712.c @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2005,2006,2007,2008,2009 Free Software Foundation, Inc. + * Copyright (C) 2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc. * * GRUB is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -62,7 +62,7 @@ grub_video_sm712_video_fini (void) static grub_err_t grub_video_sm712_setup (unsigned int width, unsigned int height, - unsigned int mode_type) + unsigned int mode_type, unsigned int mode_mask __attribute__ ((unused))) { int depth; grub_err_t err; From 915fc1b8bfa683a1cb456d4c4e38806d2631f4ed Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 20 Jan 2010 01:08:46 +0100 Subject: [PATCH 233/738] 2010-01-20 Vladimir Serbinenko * include/multiboot.h: Resynced with spec. * include/multiboot2.h: Likewise. * loader/i386/multiboot_mbi.c (grub_fill_multiboot_mmap): Handle GRUB_MACHINE_MEMORY_ACPI_RECLAIMABLE and GRUB_MACHINE_MEMORY_NVS. --- ChangeLog | 7 +++++++ include/multiboot.h | 2 ++ include/multiboot2.h | 2 ++ loader/i386/multiboot_mbi.c | 12 ++++++++++++ 4 files changed, 23 insertions(+) diff --git a/ChangeLog b/ChangeLog index 40984c187..9097153e2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-01-20 Vladimir Serbinenko + + * include/multiboot.h: Resynced with spec. + * include/multiboot2.h: Likewise. + * loader/i386/multiboot_mbi.c (grub_fill_multiboot_mmap): Handle + GRUB_MACHINE_MEMORY_ACPI_RECLAIMABLE and GRUB_MACHINE_MEMORY_NVS. + 2010-01-18 Robert Millan * include/grub/term.h (grub_term_register_input, diff --git a/include/multiboot.h b/include/multiboot.h index 57c154c98..c529c5c5f 100644 --- a/include/multiboot.h +++ b/include/multiboot.h @@ -233,6 +233,8 @@ struct multiboot_mmap_entry multiboot_uint64_t len; #define MULTIBOOT_MEMORY_AVAILABLE 1 #define MULTIBOOT_MEMORY_RESERVED 2 +#define MULTIBOOT_MEMORY_ACPI_RECLAIMABLE 3 +#define MULTIBOOT_MEMORY_NVS 4 multiboot_uint32_t type; } __attribute__((packed)); typedef struct multiboot_mmap_entry multiboot_memory_map_t; diff --git a/include/multiboot2.h b/include/multiboot2.h index a241a70ad..1b649d514 100644 --- a/include/multiboot2.h +++ b/include/multiboot2.h @@ -233,6 +233,8 @@ struct multiboot_mmap_entry multiboot_uint64_t len; #define MULTIBOOT_MEMORY_AVAILABLE 1 #define MULTIBOOT_MEMORY_RESERVED 2 +#define MULTIBOOT_MEMORY_ACPI_RECLAIMABLE 3 +#define MULTIBOOT_MEMORY_NVS 4 multiboot_uint32_t type; } __attribute__((packed)); typedef struct multiboot_mmap_entry multiboot_memory_map_t; diff --git a/loader/i386/multiboot_mbi.c b/loader/i386/multiboot_mbi.c index 58bb68323..5154a64df 100644 --- a/loader/i386/multiboot_mbi.c +++ b/loader/i386/multiboot_mbi.c @@ -110,6 +110,18 @@ grub_fill_multiboot_mmap (struct multiboot_mmap_entry *first_entry) case GRUB_MACHINE_MEMORY_AVAILABLE: mmap_entry->type = MULTIBOOT_MEMORY_AVAILABLE; break; + +#ifdef GRUB_MACHINE_MEMORY_ACPI_RECLAIMABLE + case GRUB_MACHINE_MEMORY_ACPI_RECLAIMABLE: + mmap_entry->type = MULTIBOOT_MEMORY_ACPI_RECLAIMABLE; + break; +#endif + +#ifdef GRUB_MACHINE_MEMORY_NVS + case GRUB_MACHINE_MEMORY_NVS: + mmap_entry->type = MULTIBOOT_MEMORY_NVS; + break; +#endif default: mmap_entry->type = MULTIBOOT_MEMORY_RESERVED; From 7a988ee134edafbd460fc455798b02217bb5bd71 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Wed, 20 Jan 2010 00:34:57 +0000 Subject: [PATCH 234/738] Remove a debug comment. --- font/font.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/font/font.c b/font/font.c index 7aef1b163..9f8e0f5c6 100644 --- a/font/font.c +++ b/font/font.c @@ -17,8 +17,6 @@ * along with GRUB. If not, see . */ -//#define USE_ASCII_FAILBACK 0 - #include #include #include From e3538adaea469c20a2ab77d97891b068bb5b6013 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Wed, 20 Jan 2010 01:19:53 +0000 Subject: [PATCH 235/738] 2009-12-20 Robert Millan * kern/mips/yeeloong/init.c (grub_video_sm712_init) (grub_video_video_init, grub_video_bitmap_init) (grub_font_manager_init, grub_term_gfxterm_init) (grub_at_keyboard_init): New extern declarations. (grub_machine_init): Initialize gfxterm and at_keyboard. * kern/main.c (grub_main): Revert grub_printf delay kludge. * util/grub-install.in: Revert embed of `at_keyboard.mod' and `gfxterm.mod' into core image. * conf/mips.rmk (pkglib_IMAGES, kernel_img_SOURCES) (kernel_img_CFLAGS, kernel_img_ASFLAGS, kernel_img_LDFLAGS) (kernel_img_FORMAT): Copy to ... * conf/mips-qemu-mips.rmk (pkglib_IMAGES, kernel_img_SOURCES) (kernel_img_CFLAGS, kernel_img_ASFLAGS, kernel_img_LDFLAGS) (kernel_img_FORMAT): ... here, and ... * conf/mips-yeeloong.rmk (pkglib_IMAGES, kernel_img_SOURCES) (kernel_img_CFLAGS, kernel_img_ASFLAGS, kernel_img_LDFLAGS) (kernel_img_FORMAT): ... here. (kernel_img_SOURCES): Add files necessary for output (gfxterm) and input (at_keyboard) terminals in kernel. (kernel_img_CFLAGS): Add `-DUSE_ASCII_FAILBACK'. (pkglib_MODULES): Remove `pci.mod'. (pci_mod_SOURCES, pci_mod_CFLAGS, pci_mod_LDFLAGS) (sm712_mod_SOURCES, sm712_mod_CFLAGS, sm712_mod_LDFLAGS) (at_keyboard_mod_SOURCES, at_keyboard_mod_CFLAGS) (at_keyboard_mod_LDFLAGS): Remove variables. --- ChangeLog.mips | 35 +++++++++++++++++++++++++++++++++ conf/mips-qemu-mips.rmk | 17 ++++++++++++++++ conf/mips-yeeloong.rmk | 41 +++++++++++++++++++++++---------------- conf/mips.rmk | 18 ----------------- kern/main.c | 12 ++++++------ kern/mips/yeeloong/init.c | 19 +++++++++++++++++- util/grub-install.in | 4 ---- 7 files changed, 100 insertions(+), 46 deletions(-) diff --git a/ChangeLog.mips b/ChangeLog.mips index 1bbe1c273..12797095d 100644 --- a/ChangeLog.mips +++ b/ChangeLog.mips @@ -1,3 +1,38 @@ +2009-12-20 Robert Millan + + * kern/mips/yeeloong/init.c (grub_video_sm712_init) + (grub_video_video_init, grub_video_bitmap_init) + (grub_font_manager_init, grub_term_gfxterm_init) + (grub_at_keyboard_init): New extern declarations. + (grub_machine_init): Initialize gfxterm and at_keyboard. + + * kern/main.c (grub_main): Revert grub_printf delay kludge. + + * util/grub-install.in: Revert embed of `at_keyboard.mod' and + `gfxterm.mod' into core image. + + * conf/mips.rmk (pkglib_IMAGES, kernel_img_SOURCES) + (kernel_img_CFLAGS, kernel_img_ASFLAGS, kernel_img_LDFLAGS) + (kernel_img_FORMAT): Copy to ... + + * conf/mips-qemu-mips.rmk (pkglib_IMAGES, kernel_img_SOURCES) + (kernel_img_CFLAGS, kernel_img_ASFLAGS, kernel_img_LDFLAGS) + (kernel_img_FORMAT): ... here, and ... + + * conf/mips-yeeloong.rmk (pkglib_IMAGES, kernel_img_SOURCES) + (kernel_img_CFLAGS, kernel_img_ASFLAGS, kernel_img_LDFLAGS) + (kernel_img_FORMAT): ... here. + + (kernel_img_SOURCES): Add files necessary for output (gfxterm) + and input (at_keyboard) terminals in kernel. + (kernel_img_CFLAGS): Add `-DUSE_ASCII_FAILBACK'. + + (pkglib_MODULES): Remove `pci.mod'. + (pci_mod_SOURCES, pci_mod_CFLAGS, pci_mod_LDFLAGS) + (sm712_mod_SOURCES, sm712_mod_CFLAGS, sm712_mod_LDFLAGS) + (at_keyboard_mod_SOURCES, at_keyboard_mod_CFLAGS) + (at_keyboard_mod_LDFLAGS): Remove variables. + 2010-01-11 Felix Zielcke * po/POTFILES: Replace `term/i386/pc/serial.c' with `term/serial.c'. diff --git a/conf/mips-qemu-mips.rmk b/conf/mips-qemu-mips.rmk index d5a985a13..e06370122 100644 --- a/conf/mips-qemu-mips.rmk +++ b/conf/mips-qemu-mips.rmk @@ -4,3 +4,20 @@ target_machine=qemu-mips COMMON_CFLAGS += -march=mips3 COMMON_ASFLAGS += -march=mips3 include $(srcdir)/conf/mips.mk + +pkglib_IMAGES = kernel.img +kernel_img_SOURCES = kern/$(target_cpu)/startup.S \ + kern/main.c kern/device.c kern/$(target_cpu)/init.c \ + kern/$(target_cpu)/$(target_machine)/init.c \ + kern/disk.c kern/dl.c kern/err.c kern/file.c kern/fs.c \ + kern/misc.c kern/mm.c kern/term.c \ + kern/rescue_parser.c kern/rescue_reader.c \ + kern/list.c kern/handler.c kern/command.c kern/corecmd.c \ + kern/parser.c kern/partition.c kern/env.c kern/$(target_cpu)/dl.c \ + kern/generic/millisleep.c kern/generic/rtc_get_time_ms.c kern/time.c \ + symlist.c kern/$(target_cpu)/cache.S +kernel_img_CFLAGS = $(COMMON_CFLAGS) +kernel_img_ASFLAGS = $(COMMON_ASFLAGS) +kernel_img_LDFLAGS = $(COMMON_LDFLAGS) -static-libgcc -lgcc \ + -Wl,-N,-S,-Ttext,$(LINK_BASE),-Bstatic +kernel_img_FORMAT = binary diff --git a/conf/mips-yeeloong.rmk b/conf/mips-yeeloong.rmk index 4257bba74..964f29384 100644 --- a/conf/mips-yeeloong.rmk +++ b/conf/mips-yeeloong.rmk @@ -5,11 +5,30 @@ COMMON_CFLAGS += -march=mips3 COMMON_ASFLAGS += -march=mips3 include $(srcdir)/conf/mips.mk -# For pci.mod. -pkglib_MODULES += pci.mod -pci_mod_SOURCES = bus/pci.c bus/bonito.c -pci_mod_CFLAGS = $(COMMON_CFLAGS) -pci_mod_LDFLAGS = $(COMMON_LDFLAGS) +pkglib_IMAGES = kernel.img +kernel_img_SOURCES = kern/$(target_cpu)/startup.S \ + kern/main.c kern/device.c kern/$(target_cpu)/init.c \ + kern/$(target_cpu)/$(target_machine)/init.c \ + kern/disk.c kern/dl.c kern/err.c kern/file.c kern/fs.c \ + kern/misc.c kern/mm.c kern/term.c \ + kern/rescue_parser.c kern/rescue_reader.c \ + kern/list.c kern/handler.c kern/command.c kern/corecmd.c \ + kern/parser.c kern/partition.c kern/env.c kern/$(target_cpu)/dl.c \ + kern/generic/millisleep.c kern/generic/rtc_get_time_ms.c kern/time.c \ + kern/$(target_cpu)/cache.S \ + \ + term/at_keyboard.c \ + font/font_cmd.c font/font.c io/bufio.c \ + video/video.c video/fb/video_fb.c video/fb/fbblit.c \ + video/fb/fbfill.c video/fb/fbutil.c video/bitmap.c \ + video/sm712.c bus/pci.c bus/bonito.c \ + term/gfxterm.c commands/extcmd.c lib/arg.c \ + symlist.c +kernel_img_CFLAGS = $(COMMON_CFLAGS) -DUSE_ASCII_FAILBACK +kernel_img_ASFLAGS = $(COMMON_ASFLAGS) +kernel_img_LDFLAGS = $(COMMON_LDFLAGS) -static-libgcc -lgcc \ + -Wl,-N,-S,-Ttext,$(LINK_BASE),-Bstatic +kernel_img_FORMAT = binary # For ata.mod. pkglib_MODULES += ata.mod @@ -17,24 +36,12 @@ ata_mod_SOURCES = disk/ata.c ata_mod_CFLAGS = $(COMMON_CFLAGS) ata_mod_LDFLAGS = $(COMMON_LDFLAGS) -# For pci.mod. -pkglib_MODULES += sm712.mod -sm712_mod_SOURCES = video/sm712.c -sm712_mod_CFLAGS = $(COMMON_CFLAGS) -sm712_mod_LDFLAGS = $(COMMON_LDFLAGS) - # For lspci.mod pkglib_MODULES += lspci.mod lspci_mod_SOURCES = commands/lspci.c lspci_mod_CFLAGS = $(COMMON_CFLAGS) lspci_mod_LDFLAGS = $(COMMON_LDFLAGS) -# For at_keyboard.mod. -pkglib_MODULES += at_keyboard.mod -at_keyboard_mod_SOURCES = term/at_keyboard.c -at_keyboard_mod_CFLAGS = $(COMMON_CFLAGS) -at_keyboard_mod_LDFLAGS = $(COMMON_LDFLAGS) - # For ata_pthru.mod. pkglib_MODULES += ata_pthru.mod ata_pthru_mod_SOURCES = disk/ata_pthru.c diff --git a/conf/mips.rmk b/conf/mips.rmk index 55fd83d73..fedfb4c54 100644 --- a/conf/mips.rmk +++ b/conf/mips.rmk @@ -25,24 +25,6 @@ symlist.c: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h gensymlist. kernel_syms.lst: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h genkernsyms.sh /bin/sh genkernsyms.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) -# Programs -pkglib_IMAGES = kernel.img -kernel_img_SOURCES = kern/$(target_cpu)/startup.S \ - kern/main.c kern/device.c kern/$(target_cpu)/init.c \ - kern/$(target_cpu)/$(target_machine)/init.c \ - kern/disk.c kern/dl.c kern/err.c kern/file.c kern/fs.c \ - kern/misc.c kern/mm.c kern/term.c \ - kern/rescue_parser.c kern/rescue_reader.c \ - kern/list.c kern/handler.c kern/command.c kern/corecmd.c \ - kern/parser.c kern/partition.c kern/env.c kern/$(target_cpu)/dl.c \ - kern/generic/millisleep.c kern/generic/rtc_get_time_ms.c kern/time.c \ - symlist.c kern/$(target_cpu)/cache.S -kernel_img_CFLAGS = $(COMMON_CFLAGS) -kernel_img_ASFLAGS = $(COMMON_ASFLAGS) -kernel_img_LDFLAGS = $(COMMON_LDFLAGS) -static-libgcc -lgcc \ - -Wl,-N,-S,-Ttext,$(LINK_BASE),-Bstatic -kernel_img_FORMAT = binary - # Scripts. sbin_SCRIPTS = bin_SCRIPTS = diff --git a/kern/main.c b/kern/main.c index ae32d47f6..57a0f4a3d 100644 --- a/kern/main.c +++ b/kern/main.c @@ -152,6 +152,12 @@ grub_main (void) /* First of all, initialize the machine. */ grub_machine_init (); + /* Hello. */ + grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT); + grub_printf ("Welcome to GRUB!\n\n"); + grub_refresh (); + grub_setcolorstate (GRUB_TERM_COLOR_STANDARD); + /* Load pre-loaded modules and free the space. */ grub_register_exported_symbols (); #ifdef GRUB_LINKER_HAVE_INIT @@ -159,12 +165,6 @@ grub_main (void) #endif grub_load_modules (); - /* Hello. */ - grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT); - grub_printf ("Welcome to GRUB!\n\n"); - grub_refresh (); - grub_setcolorstate (GRUB_TERM_COLOR_STANDARD); - /* It is better to set the root device as soon as possible, for convenience. */ grub_machine_set_prefix (); diff --git a/kern/mips/yeeloong/init.c b/kern/mips/yeeloong/init.c index 8b93ac18f..14e8a39a2 100644 --- a/kern/mips/yeeloong/init.c +++ b/kern/mips/yeeloong/init.c @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2009 Free Software Foundation, Inc. + * Copyright (C) 2009,2010 Free Software Foundation, Inc. * * GRUB is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -28,6 +28,13 @@ #include #include +extern void grub_video_sm712_init (void); +extern void grub_video_video_init (void); +extern void grub_video_bitmap_init (void); +extern void grub_font_manager_init (void); +extern void grub_term_gfxterm_init (void); +extern void grub_at_keyboard_init (void); + /* FIXME: use interrupt to count high. */ grub_uint64_t grub_get_rtc (void) @@ -87,6 +94,16 @@ grub_machine_init (void) - (((grub_addr_t) modend) - GRUB_ARCH_LOWMEMVSTART)); /* FIXME: use upper memory as well. */ grub_install_get_time_ms (grub_rtc_get_time_ms); + + /* Initialize output terminal (can't be done earlier, as gfxterm + relies on a working heap. */ + grub_video_sm712_init (); + grub_video_video_init (); + grub_video_bitmap_init (); + grub_font_manager_init (); + grub_term_gfxterm_init (); + + grub_at_keyboard_init (); } void diff --git a/util/grub-install.in b/util/grub-install.in index 509593d63..bb323d706 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -292,10 +292,6 @@ partmap_module=`$grub_probe --target=partmap --device ${grub_device} 2> /dev/nul # Device abstraction module, if any (lvm, raid). devabstraction_module=`$grub_probe --target=abstraction --device ${grub_device}` -if [ "${target_cpu}-${platform}" = "mips-yeeloong" ] ; then - modules="sm712 gfxterm at_keyboard $modules" -fi - # The order in this list is critical. Be careful when modifying it. modules="$modules $disk_module" modules="$modules $fs_module $partmap_module $devabstraction_module" From ff9890710e5f06fa93e856acf61ab1a6366d8a87 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Wed, 20 Jan 2010 01:29:06 +0000 Subject: [PATCH 236/738] 2009-12-20 Robert Millan * loader/mips/linux.c (grub_cmd_initrd) (GRUB_MOD_INIT(linux)): Adjust and gettextize a few strings. --- ChangeLog.mips | 5 +++++ loader/mips/linux.c | 10 +++++----- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/ChangeLog.mips b/ChangeLog.mips index 12797095d..274bf7dc4 100644 --- a/ChangeLog.mips +++ b/ChangeLog.mips @@ -1,3 +1,8 @@ +2009-12-20 Robert Millan + + * loader/mips/linux.c (grub_cmd_initrd) + (GRUB_MOD_INIT(linux)): Adjust and gettextize a few strings. + 2009-12-20 Robert Millan * kern/mips/yeeloong/init.c (grub_video_sm712_init) diff --git a/loader/mips/linux.c b/loader/mips/linux.c index 8d7cda0ed..b52f098ac 100644 --- a/loader/mips/linux.c +++ b/loader/mips/linux.c @@ -1,7 +1,7 @@ /* linux.c - boot Linux */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2003, 2004, 2005, 2007, 2009 Free Software Foundation, Inc. + * Copyright (C) 2003,2004,2005,2007,2009,2010 Free Software Foundation, Inc. * * GRUB is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -318,10 +318,10 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), grub_size_t overhead; if (argc == 0) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "no initrd specified"); + return grub_error (GRUB_ERR_BAD_ARGUMENT, "No initrd specified"); if (!loaded) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "You need to load the kernel first."); + return grub_error (GRUB_ERR_BAD_ARGUMENT, "You need to load Linux first."); if (initrd_loaded) return grub_error (GRUB_ERR_BAD_ARGUMENT, "Only one initrd can be loaded."); @@ -376,9 +376,9 @@ static grub_command_t cmd_linux, cmd_initrd; GRUB_MOD_INIT(linux) { cmd_linux = grub_register_command ("linux", grub_cmd_linux, - 0, "load a linux kernel"); + 0, N_("Load Linux.")); cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd, - 0, "load an initrd"); + 0, N_("Load initrd.")); my_mod = mod; } From 917dd370404a540884a8216a1c3c94a4504867f9 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 20 Jan 2010 02:11:07 +0000 Subject: [PATCH 237/738] 2010-01-20 Dan Merillat * kern/device.c (grub_device_iterate): Allocate new part_ent structure based on sizeof (*p) rather than sizeof (p->next), to account for structure padding. * util/grub-probe.c (probe_raid_level): Return -1 immediately if disk is NULL, which might happen for LVM physical volumes with no LVM signature. --- ChangeLog | 10 ++++++++++ kern/device.c | 2 +- util/grub-probe.c | 5 +++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 3b31a527f..08c2851d5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2010-01-20 Dan Merillat + + * kern/device.c (grub_device_iterate): Allocate new part_ent + structure based on sizeof (*p) rather than sizeof (p->next), to + account for structure padding. + + * util/grub-probe.c (probe_raid_level): Return -1 immediately if + disk is NULL, which might happen for LVM physical volumes with no + LVM signature. + 2009-12-20 Robert Millan * loader/mips/linux.c (grub_cmd_initrd) diff --git a/kern/device.c b/kern/device.c index f519c63b2..7d3577051 100644 --- a/kern/device.c +++ b/kern/device.c @@ -138,7 +138,7 @@ grub_device_iterate (int (*hook) (const char *name)) if (! partition_name) return 1; - p = grub_malloc (sizeof (p->next) + grub_strlen (disk->name) + 1 + + p = grub_malloc (sizeof (*p) + grub_strlen (disk->name) + 1 + grub_strlen (partition_name) + 1); if (!p) { diff --git a/util/grub-probe.c b/util/grub-probe.c index 879098542..ba2fe4c35 100644 --- a/util/grub-probe.c +++ b/util/grub-probe.c @@ -94,6 +94,11 @@ probe_partmap (grub_disk_t disk) static int probe_raid_level (grub_disk_t disk) { + /* disk might be NULL in the case of a LVM physical volume with no LVM + signature. Ignore such cases here. */ + if (!disk) + return -1; + if (disk->dev->id != GRUB_DISK_DEVICE_RAID_ID) return -1; From c893cc87fc45f7ae6385793021a0d1ac200ec992 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Wed, 20 Jan 2010 02:43:19 +0000 Subject: [PATCH 238/738] 2009-12-20 Robert Millan * commands/loadenv.c (check_blocklists): Use `grub_err_t' as return value (and revert all return statements). Update users. --- ChangeLog | 5 +++++ commands/loadenv.c | 21 ++++++++------------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index 08c2851d5..bac4c317a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2009-12-20 Robert Millan + + * commands/loadenv.c (check_blocklists): Use `grub_err_t' as + return value (and revert all return statements). Update users. + 2010-01-20 Dan Merillat * kern/device.c (grub_device_iterate): Allocate new part_ent diff --git a/commands/loadenv.c b/commands/loadenv.c index 910392614..51b88cbc9 100644 --- a/commands/loadenv.c +++ b/commands/loadenv.c @@ -1,7 +1,7 @@ /* loadenv.c - command to load/save environment variable. */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2008,2009 Free Software Foundation, Inc. + * Copyright (C) 2008,2009,2010 Free Software Foundation, Inc. * * GRUB is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -196,7 +196,7 @@ free_blocklists (struct blocklist *p) } } -static int +static grub_err_t check_blocklists (grub_envblk_t envblk, struct blocklist *blocklists, grub_file_t file) { @@ -219,8 +219,7 @@ check_blocklists (grub_envblk_t envblk, struct blocklist *blocklists, { /* This might be actually valid, but it is unbelievable that any filesystem makes such a silly allocation. */ - grub_error (GRUB_ERR_BAD_FS, "malformed file"); - return 0; + return grub_error (GRUB_ERR_BAD_FS, "malformed file"); } } @@ -230,8 +229,7 @@ check_blocklists (grub_envblk_t envblk, struct blocklist *blocklists, if (total_length != grub_file_size (file)) { /* Maybe sparse, unallocated sectors. No way in GRUB. */ - grub_error (GRUB_ERR_BAD_FILE_TYPE, "sparse file not allowed"); - return 0; + return grub_error (GRUB_ERR_BAD_FILE_TYPE, "sparse file not allowed"); } /* One more sanity check. Re-read all sectors by blocklists, and compare @@ -249,16 +247,13 @@ check_blocklists (grub_envblk_t envblk, struct blocklist *blocklists, if (grub_disk_read (disk, p->sector - part_start, p->offset, p->length, blockbuf)) - return 0; + return grub_errno; if (grub_memcmp (buf + index, blockbuf, p->length) != 0) - { - grub_error (GRUB_ERR_FILE_READ_ERROR, "invalid blocklist"); - return 0; - } + return grub_error (GRUB_ERR_FILE_READ_ERROR, "invalid blocklist"); } - return 1; + return GRUB_ERR_NONE; } static int @@ -347,7 +342,7 @@ grub_cmd_save_env (grub_extcmd_t cmd, int argc, char **args) if (! envblk) goto fail; - if (! check_blocklists (envblk, head, file)) + if (check_blocklists (envblk, head, file)) goto fail; while (argc) From 55ff526642883e65ee690825750a1d76df843a1f Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Wed, 20 Jan 2010 02:50:36 +0000 Subject: [PATCH 239/738] 2009-12-20 Robert Millan * normal/menu.c (notify_execution_failure): Clarify error message. --- ChangeLog | 4 ++++ normal/menu.c | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index bac4c317a..3fac1bd6a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2009-12-20 Robert Millan + + * normal/menu.c (notify_execution_failure): Clarify error message. + 2009-12-20 Robert Millan * commands/loadenv.c (check_blocklists): Use `grub_err_t' as diff --git a/normal/menu.c b/normal/menu.c index 17730eff3..5e79d9405 100644 --- a/normal/menu.c +++ b/normal/menu.c @@ -1,7 +1,7 @@ /* menu.c - General supporting functionality for menus. */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2003,2004,2005,2006,2007,2008,2009 Free Software Foundation, Inc. + * Copyright (C) 2003,2004,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc. * * GRUB is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -519,7 +519,7 @@ notify_execution_failure (void *userdata __attribute__((unused))) grub_errno = GRUB_ERR_NONE; } grub_printf ("\n "); - grub_printf_ (N_("Failed to boot default entries.\n")); + grub_printf_ (N_("Failed to boot both default and fallback entries.\n")); grub_wait_after_message (); } From 47d5f3c1c2238eb6bcd55215dfdbfd356b879f97 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 20 Jan 2010 08:01:48 +0100 Subject: [PATCH 240/738] 2010-01-20 Vladimir Serbinenko * loader/mips/linux.c: Include missing grub/i18n.h. --- ChangeLog | 4 ++++ loader/mips/linux.c | 1 + 2 files changed, 5 insertions(+) diff --git a/ChangeLog b/ChangeLog index 3fac1bd6a..772e1620b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-01-20 Vladimir Serbinenko + + * loader/mips/linux.c: Include missing grub/i18n.h. + 2009-12-20 Robert Millan * normal/menu.c (notify_execution_failure): Clarify error message. diff --git a/loader/mips/linux.c b/loader/mips/linux.c index b52f098ac..1eb747c3b 100644 --- a/loader/mips/linux.c +++ b/loader/mips/linux.c @@ -27,6 +27,7 @@ #include #include #include +#include /* For frequencies. */ #include From 119c50eab3e43d7bc66c6c533dd837f1d1429855 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 20 Jan 2010 08:02:45 +0100 Subject: [PATCH 241/738] 2010-01-20 Vladimir Serbinenko * include/grub/x86_64/at_keyboard.h: New file. --- ChangeLog | 4 ++++ include/grub/x86_64/at_keyboard.h | 1 + 2 files changed, 5 insertions(+) create mode 100644 include/grub/x86_64/at_keyboard.h diff --git a/ChangeLog b/ChangeLog index 772e1620b..192054e7b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-01-20 Vladimir Serbinenko + + * include/grub/x86_64/at_keyboard.h: New file. + 2010-01-20 Vladimir Serbinenko * loader/mips/linux.c: Include missing grub/i18n.h. diff --git a/include/grub/x86_64/at_keyboard.h b/include/grub/x86_64/at_keyboard.h new file mode 100644 index 000000000..c632aa85c --- /dev/null +++ b/include/grub/x86_64/at_keyboard.h @@ -0,0 +1 @@ +#include From f80927cadb4181fed6c7215fe24e3ea69c800789 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 20 Jan 2010 08:04:01 +0100 Subject: [PATCH 242/738] 2010-01-20 Vladimir Serbinenko * conf/mips.rmk (kernel_img_HEADERS) [yeeloong]: Add pci.h. --- ChangeLog | 4 ++++ conf/mips.rmk | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/ChangeLog b/ChangeLog index 192054e7b..add252622 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-01-20 Vladimir Serbinenko + + * conf/mips.rmk (kernel_img_HEADERS) [yeeloong]: Add pci.h. + 2010-01-20 Vladimir Serbinenko * include/grub/x86_64/at_keyboard.h: New file. diff --git a/conf/mips.rmk b/conf/mips.rmk index fedfb4c54..d0b1c484c 100644 --- a/conf/mips.rmk +++ b/conf/mips.rmk @@ -19,6 +19,10 @@ kernel_img_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ msdos_partition.h machine/kernel.h handler.h list.h \ command.h machine/memory.h cpu/libgcc.h cpu/cache.h i18n.h +ifeq ($(platform), yeeloong) +kernel_img_HEADERS += pci.h +endif + symlist.c: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h gensymlist.sh /bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) From 7ee92c32e1cd3e8156e9838f5ca052e52a8e5aa2 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 20 Jan 2010 08:04:39 +0100 Subject: [PATCH 243/738] 2010-01-20 Vladimir Serbinenko * include/grub/font.h (grub_font_load): Fix prototype. --- ChangeLog | 4 ++++ include/grub/font.h | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index add252622..d7118325c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-01-20 Vladimir Serbinenko + + * include/grub/font.h (grub_font_load): Fix prototype. + 2010-01-20 Vladimir Serbinenko * conf/mips.rmk (kernel_img_HEADERS) [yeeloong]: Add pci.h. diff --git a/include/grub/font.h b/include/grub/font.h index 2129c30b3..1816e3570 100644 --- a/include/grub/font.h +++ b/include/grub/font.h @@ -75,7 +75,7 @@ void grub_font_loader_init (void); /* Load a font and add it to the beginning of the global font list. Returns: 0 upon success; nonzero upon failure. */ -int grub_font_load (grub_file_t file); +int grub_font_load (const char *filename); /* Get the font that has the specified name. Font names are in the form "Family Name Bold Italic 14", where Bold and Italic are optional. From aca655fd208845e1eaa9bef406d3f7c7630e6d3f Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Wed, 20 Jan 2010 12:48:35 +0530 Subject: [PATCH 244/738] fix grub-script-check warnings --- ChangeLog | 5 +++++ include/grub/script_sh.h | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index d7118325c..0c8b841e4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-01-20 BVK Chaitanya + + * include/grub/script_sh.h (sourcecode): Remove const qualifier to + fix grub-script-check warning. + 2010-01-20 Vladimir Serbinenko * include/grub/font.h (grub_font_load): Fix prototype. diff --git a/include/grub/script_sh.h b/include/grub/script_sh.h index f6177b02a..0bd14abcd 100644 --- a/include/grub/script_sh.h +++ b/include/grub/script_sh.h @@ -112,7 +112,7 @@ struct grub_script_cmd_menuentry struct grub_script_arglist *arglist; /* The sourcecode the entry will be generated from. */ - const char *sourcecode; + char *sourcecode; /* Options. XXX: Not used yet. */ int options; From b09a4a8dff41f224a8ddf96039c50ae3c526bd64 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 20 Jan 2010 09:01:25 +0100 Subject: [PATCH 245/738] add missing error handling --- normal/main.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/normal/main.c b/normal/main.c index 555d56aba..0c192712f 100644 --- a/normal/main.c +++ b/normal/main.c @@ -570,6 +570,9 @@ grub_normal_read_line_real (char **line, int cont, int nested) else prompt = grub_asprintf ("%s>", parser->name); + if (!prompt) + return grub_errno; + while (1) { *line = grub_cmdline_get (prompt); From adb893f2ae22bab455665ed861388812f0288aaf Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 20 Jan 2010 09:02:01 +0100 Subject: [PATCH 246/738] use correct size strings in mips/linux.c --- loader/mips/linux.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/loader/mips/linux.c b/loader/mips/linux.c index 2d3e1ca5d..51060c4fb 100644 --- a/loader/mips/linux.c +++ b/loader/mips/linux.c @@ -281,7 +281,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), linux_envp = extra; envp_off = (grub_uint8_t *) linux_envp - (grub_uint8_t *) playground; linux_envs = (char *) (linux_envp + 5); - grub_snprintf (linux_envs, sizeof ("memsize=XXXXXXXXXXXXXXXXXXXX"), + grub_snprintf (linux_envs, sizeof ("memsize=XXXXXXXXXXXXXXXXXXXX"), "memsize=%lld", (unsigned long long) grub_mmap_get_lower () >> 20); linux_envp[0] = (grub_uint8_t *) linux_envs - (grub_uint8_t *) playground @@ -294,12 +294,12 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + target_addr; linux_envs += ALIGN_UP (grub_strlen (linux_envs) + 1, 4); - grub_snprintf (linux_envs, sizeof ("busclock=XXXXXXXXXXXXXXXXXXXX"), + grub_snprintf (linux_envs, sizeof ("busclock=XXXXXXXXXX"), "busclock=%d", grub_arch_busclock); linux_envp[2] = (grub_uint8_t *) linux_envs - (grub_uint8_t *) playground + target_addr; linux_envs += ALIGN_UP (grub_strlen (linux_envs) + 1, 4); - grub_snprintf (linux_envs, sizeof ("cpuclock=XXXXXXXXXXXXXXXXXXXX"), + grub_snprintf (linux_envs, sizeof ("cpuclock=XXXXXXXXXX"), "cpuclock=%d", grub_arch_cpuclock); linux_envp[3] = (grub_uint8_t *) linux_envs - (grub_uint8_t *) playground + target_addr; @@ -360,14 +360,14 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), } grub_snprintf ((char *) playground + rd_addr_arg_off, - sizeof ("rd_start=XXXXXXXXXXXXXXXXXXXX"), "rd_start=0x%llx", + sizeof ("rd_start=0xXXXXXXXXXXXXXXXX"), "rd_start=0x%llx", (unsigned long long) target_addr + linux_size + overhead); ((grub_uint32_t *) (playground + argv_off))[linux_argc] = target_addr + rd_addr_arg_off; linux_argc++; grub_snprintf ((char *) playground + rd_size_arg_off, - sizeof ("rd_size=XXXXXXXXXXXXXXXXXXXX"), "rd_size=0x%llx", + sizeof ("rd_size=0xXXXXXXXXXXXXXXXXX"), "rd_size=0x%llx", (unsigned long long) size); ((grub_uint32_t *) (playground + argv_off))[linux_argc] = target_addr + rd_size_arg_off; From 61eb45eee720cb9ccf3e794f6a0b1d4e7adff225 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 20 Jan 2010 09:12:47 +0100 Subject: [PATCH 247/738] Rename asprint into xasprintf and avsprintf into xvasprintf --- commands/hashsum.c | 2 +- commands/help.c | 2 +- commands/ls.c | 4 ++-- commands/parttool.c | 2 +- commands/search.c | 2 +- disk/efi/efidisk.c | 2 +- disk/raid.c | 2 +- disk/scsi.c | 2 +- disk/usbms.c | 2 +- efiemu/main.c | 2 +- fs/ext2.c | 2 +- fs/fat.c | 2 +- fs/hfs.c | 2 +- fs/hfsplus.c | 2 +- fs/i386/pc/pxe.c | 6 +++--- fs/iso9660.c | 2 +- fs/jfs.c | 2 +- fs/ntfs.c | 2 +- fs/reiserfs.c | 2 +- fs/ufs.c | 2 +- fs/xfs.c | 2 +- gettext/gettext.c | 4 ++-- include/grub/misc.h | 4 ++-- kern/device.c | 2 +- kern/dl.c | 2 +- kern/efi/init.c | 2 +- kern/env.c | 2 +- kern/ieee1275/init.c | 2 +- kern/ieee1275/openfw.c | 8 ++++---- kern/misc.c | 6 +++--- kern/sparc64/ieee1275/init.c | 2 +- loader/i386/bsd.c | 2 +- loader/i386/linux.c | 4 ++-- loader/i386/multiboot.c | 4 ++-- loader/i386/multiboot_mbi.c | 2 +- loader/i386/pc/xnu.c | 2 +- loader/xnu.c | 2 +- normal/autofs.c | 2 +- normal/completion.c | 6 +++--- normal/crypto.c | 2 +- normal/dyncmd.c | 2 +- normal/handler.c | 2 +- normal/main.c | 10 +++++----- normal/menu_text.c | 4 ++-- normal/term.c | 2 +- partmap/acorn.c | 2 +- partmap/amiga.c | 2 +- partmap/apple.c | 2 +- partmap/gpt.c | 2 +- partmap/msdos.c | 6 +++--- partmap/sun.c | 2 +- term/gfxterm.c | 2 +- term/ieee1275/ofconsole.c | 4 ++-- tests/lib/test.c | 2 +- util/grub-fstest.c | 6 +++--- 55 files changed, 79 insertions(+), 79 deletions(-) diff --git a/commands/hashsum.c b/commands/hashsum.c index a098ab7af..a4e71b844 100644 --- a/commands/hashsum.c +++ b/commands/hashsum.c @@ -111,7 +111,7 @@ check_list (const gcry_md_spec_t *hash, const char *hashfilename, { char *filename; - filename = grub_asprintf ("%s/%s", prefix, p); + filename = grub_xasprintf ("%s/%s", prefix, p); if (!filename) return grub_errno; file = grub_file_open (filename); diff --git a/commands/help.c b/commands/help.c index a19b395cd..1181c3bfb 100644 --- a/commands/help.c +++ b/commands/help.c @@ -47,7 +47,7 @@ grub_cmd_help (grub_extcmd_t ext __attribute__ ((unused)), int argc, grub_uint32_t *unicode_command_help; grub_uint32_t *unicode_last_position; - command_help = grub_asprintf ("%s %s", cmd->name, summary_translated); + command_help = grub_xasprintf ("%s %s", cmd->name, summary_translated); if (!command_help) return 1; diff --git a/commands/ls.c b/commands/ls.c index cfa46ec6e..8a8319ac8 100644 --- a/commands/ls.c +++ b/commands/ls.c @@ -97,9 +97,9 @@ grub_ls_list_files (char *dirname, int longlist, int all, int human) grub_file_t file; if (dirname[grub_strlen (dirname) - 1] == '/') - pathname = grub_asprintf ("%s%s", dirname, filename); + pathname = grub_xasprintf ("%s%s", dirname, filename); else - pathname = grub_asprintf ("%s/%s", dirname, filename); + pathname = grub_xasprintf ("%s/%s", dirname, filename); if (!pathname) return 1; diff --git a/commands/parttool.c b/commands/parttool.c index 3bffb8eb0..5ad6133ca 100644 --- a/commands/parttool.c +++ b/commands/parttool.c @@ -183,7 +183,7 @@ grub_cmd_parttool (grub_command_t cmd __attribute__ ((unused)), { char *filename; - filename = grub_asprintf ("%s/parttool.lst", prefix); + filename = grub_xasprintf ("%s/parttool.lst", prefix); if (filename) { grub_file_t file; diff --git a/commands/search.c b/commands/search.c index 51b7794fc..afb2e98e8 100644 --- a/commands/search.c +++ b/commands/search.c @@ -50,7 +50,7 @@ FUNC_NAME (const char *key, const char *var, int no_floppy) char *buf; grub_file_t file; - buf = grub_asprintf ("(%s)%s", name, key); + buf = grub_xasprintf ("(%s)%s", name, key); if (! buf) return 1; diff --git a/disk/efi/efidisk.c b/disk/efi/efidisk.c index 0b5731c0f..58300a0d2 100644 --- a/disk/efi/efidisk.c +++ b/disk/efi/efidisk.c @@ -805,7 +805,7 @@ grub_efidisk_get_device_name (grub_efi_handle_t *handle) return 0; } - device_name = grub_asprintf ("%s,%s", parent->name, partition_name); + device_name = grub_xasprintf ("%s,%s", parent->name, partition_name); grub_free (partition_name); grub_disk_close (parent); diff --git a/disk/raid.c b/disk/raid.c index 3d25c1747..2d544afdc 100644 --- a/disk/raid.c +++ b/disk/raid.c @@ -556,7 +556,7 @@ insert_array (grub_disk_t disk, struct grub_raid_array *new_array, } } - array->name = grub_asprintf ("md%d", array->number); + array->name = grub_xasprintf ("md%d", array->number); if (! array->name) { grub_free (array->uuid); diff --git a/disk/scsi.c b/disk/scsi.c index 2afdc1a15..6f3233b29 100644 --- a/disk/scsi.c +++ b/disk/scsi.c @@ -208,7 +208,7 @@ grub_scsi_iterate (int (*hook) (const char *name)) for (i = 0; i < luns; i++) { char *sname; - sname = grub_asprintf ("%s%c", name, 'a' + i); + sname = grub_xasprintf ("%s%c", name, 'a' + i); if (!sname) return 1; if (hook (sname)) diff --git a/disk/usbms.c b/disk/usbms.c index 708168e81..8554b224f 100644 --- a/disk/usbms.c +++ b/disk/usbms.c @@ -201,7 +201,7 @@ grub_usbms_iterate (int (*hook) (const char *name, int luns)) for (p = grub_usbms_dev_list; p; p = p->next) { char *devname; - devname = grub_asprintf ("usb%d", cnt); + devname = grub_xasprintf ("usb%d", cnt); if (hook (devname, p->luns)) { diff --git a/efiemu/main.c b/efiemu/main.c index 70a12080f..9480bfc4d 100644 --- a/efiemu/main.c +++ b/efiemu/main.c @@ -255,7 +255,7 @@ grub_efiemu_autocore (void) suffix = grub_efiemu_get_default_core_name (); - filename = grub_asprintf ("%s/%s", prefix, suffix); + filename = grub_xasprintf ("%s/%s", prefix, suffix); if (! filename) return grub_error (GRUB_ERR_OUT_OF_MEMORY, "couldn't allocate temporary space"); diff --git a/fs/ext2.c b/fs/ext2.c index 4339b981b..ac36b329b 100644 --- a/fs/ext2.c +++ b/fs/ext2.c @@ -875,7 +875,7 @@ grub_ext2_uuid (grub_device_t device, char **uuid) data = grub_ext2_mount (disk); if (data) { - *uuid = grub_asprintf ("%04x%04x-%04x-%04x-%04x-%04x%04x%04x", + *uuid = grub_xasprintf ("%04x%04x-%04x-%04x-%04x-%04x%04x%04x", grub_be_to_cpu16 (data->sblock.uuid[0]), grub_be_to_cpu16 (data->sblock.uuid[1]), grub_be_to_cpu16 (data->sblock.uuid[2]), diff --git a/fs/fat.c b/fs/fat.c index a0a40cfab..d008dc10d 100644 --- a/fs/fat.c +++ b/fs/fat.c @@ -833,7 +833,7 @@ grub_fat_uuid (grub_device_t device, char **uuid) data = grub_fat_mount (disk); if (data) { - *uuid = grub_asprintf ("%04x-%04x", + *uuid = grub_xasprintf ("%04x-%04x", (grub_uint16_t) (data->uuid >> 16), (grub_uint16_t) data->uuid); } diff --git a/fs/hfs.c b/fs/hfs.c index 701b09468..cef856326 100644 --- a/fs/hfs.c +++ b/fs/hfs.c @@ -1082,7 +1082,7 @@ grub_hfs_uuid (grub_device_t device, char **uuid) data = grub_hfs_mount (device->disk); if (data && data->sblock.num_serial != 0) { - *uuid = grub_asprintf ("%016llx", + *uuid = grub_xasprintf ("%016llx", (unsigned long long) grub_be_to_cpu64 (data->sblock.num_serial)); } diff --git a/fs/hfsplus.c b/fs/hfsplus.c index 6556bedaa..bcb8e9584 100644 --- a/fs/hfsplus.c +++ b/fs/hfsplus.c @@ -995,7 +995,7 @@ grub_hfsplus_uuid (grub_device_t device, char **uuid) data = grub_hfsplus_mount (disk); if (data) { - *uuid = grub_asprintf ("%016llx", + *uuid = grub_xasprintf ("%016llx", (unsigned long long) grub_be_to_cpu64 (data->volheader.num_serial)); } diff --git a/fs/i386/pc/pxe.c b/fs/i386/pc/pxe.c index 60a49fc53..8bfe17594 100644 --- a/fs/i386/pc/pxe.c +++ b/fs/i386/pc/pxe.c @@ -501,7 +501,7 @@ write_ip_env (grub_uint32_t *ip, const char *val) return 0; /* Normalize the IP. */ - buf = grub_asprintf ("%d.%d.%d.%d", (newip & 0xff), (newip >> 8) & 0xff, + buf = grub_xasprintf ("%d.%d.%d.%d", (newip & 0xff), (newip >> 8) & 0xff, (newip >> 16) & 0xff, (newip >> 24) & 0xff); if (!buf) return 0; @@ -543,7 +543,7 @@ grub_env_write_pxe_blocksize (struct grub_env_var *var __attribute__ ((unused)), else if (size > GRUB_PXE_MAX_BLKSIZE) size = GRUB_PXE_MAX_BLKSIZE; - buf = grub_asprintf ("%d", size); + buf = grub_xasprintf ("%d", size); if (!buf) return 0; @@ -560,7 +560,7 @@ GRUB_MOD_INIT(pxe) { char *buf; - buf = grub_asprintf ("%d", grub_pxe_blksize); + buf = grub_xasprintf ("%d", grub_pxe_blksize); if (buf) grub_env_set ("net_pxe_blksize", buf); grub_free (buf); diff --git a/fs/iso9660.c b/fs/iso9660.c index 928e1f984..a8a310f50 100644 --- a/fs/iso9660.c +++ b/fs/iso9660.c @@ -840,7 +840,7 @@ grub_iso9660_uuid (grub_device_t device, char **uuid) } else { - *uuid = grub_asprintf ("%c%c%c%c-%c%c-%c%c-%c%c-%c%c-%c%c-%c%c", + *uuid = grub_xasprintf ("%c%c%c%c-%c%c-%c%c-%c%c-%c%c-%c%c-%c%c", data->voldesc.modified.year[0], data->voldesc.modified.year[1], data->voldesc.modified.year[2], diff --git a/fs/jfs.c b/fs/jfs.c index 1bc3c7758..c9839a22f 100644 --- a/fs/jfs.c +++ b/fs/jfs.c @@ -842,7 +842,7 @@ grub_jfs_uuid (grub_device_t device, char **uuid) data = grub_jfs_mount (disk); if (data) { - *uuid = grub_asprintf ("%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-" + *uuid = grub_xasprintf ("%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-" "%02x%02x%02x%02x%02x%02x", data->sblock.uuid[0], data->sblock.uuid[1], data->sblock.uuid[2], data->sblock.uuid[3], diff --git a/fs/ntfs.c b/fs/ntfs.c index 63c1eeb82..dd041e23a 100644 --- a/fs/ntfs.c +++ b/fs/ntfs.c @@ -1072,7 +1072,7 @@ grub_ntfs_uuid (grub_device_t device, char **uuid) data = grub_ntfs_mount (disk); if (data) { - *uuid = grub_asprintf ("%016llx", (unsigned long long) data->uuid); + *uuid = grub_xasprintf ("%016llx", (unsigned long long) data->uuid); } else *uuid = NULL; diff --git a/fs/reiserfs.c b/fs/reiserfs.c index d5a20ee6c..444bf3120 100644 --- a/fs/reiserfs.c +++ b/fs/reiserfs.c @@ -1335,7 +1335,7 @@ grub_reiserfs_uuid (grub_device_t device, char **uuid) data = grub_reiserfs_mount (disk); if (data) { - *uuid = grub_asprintf ("%04x%04x-%04x-%04x-%04x-%04x%04x%04x", + *uuid = grub_xasprintf ("%04x%04x-%04x-%04x-%04x-%04x%04x%04x", grub_be_to_cpu16 (data->superblock.uuid[0]), grub_be_to_cpu16 (data->superblock.uuid[1]), grub_be_to_cpu16 (data->superblock.uuid[2]), diff --git a/fs/ufs.c b/fs/ufs.c index e8d48852b..40cf068e6 100644 --- a/fs/ufs.c +++ b/fs/ufs.c @@ -732,7 +732,7 @@ grub_ufs_uuid (grub_device_t device, char **uuid) data = grub_ufs_mount (disk); if (data && (data->sblock.uuidhi != 0 || data->sblock.uuidlow != 0)) - *uuid = grub_asprintf ("%08x%08x", + *uuid = grub_xasprintf ("%08x%08x", (unsigned) grub_le_to_cpu32 (data->sblock.uuidhi), (unsigned) grub_le_to_cpu32 (data->sblock.uuidlow)); else diff --git a/fs/xfs.c b/fs/xfs.c index 309460b61..9dffe31d1 100644 --- a/fs/xfs.c +++ b/fs/xfs.c @@ -777,7 +777,7 @@ grub_xfs_uuid (grub_device_t device, char **uuid) data = grub_xfs_mount (disk); if (data) { - *uuid = grub_asprintf ("%04x%04x-%04x-%04x-%04x-%04x%04x%04x", + *uuid = grub_xasprintf ("%04x%04x-%04x-%04x-%04x-%04x%04x%04x", grub_be_to_cpu16 (data->sblock.uuid[0]), grub_be_to_cpu16 (data->sblock.uuid[1]), grub_be_to_cpu16 (data->sblock.uuid[2]), diff --git a/gettext/gettext.c b/gettext/gettext.c index e835b0e1a..9a1756be7 100644 --- a/gettext/gettext.c +++ b/gettext/gettext.c @@ -286,7 +286,7 @@ grub_gettext_init_ext (const char *lang) /* Warning: if changing some paths in the below line, change the grub_malloc contents below. */ - mo_file = grub_asprintf ("%s/%s.mo", locale_dir, lang); + mo_file = grub_xasprintf ("%s/%s.mo", locale_dir, lang); if (!mo_file) return; @@ -296,7 +296,7 @@ grub_gettext_init_ext (const char *lang) if (fd_mo == NULL) { grub_free (mo_file); - mo_file = grub_asprintf ("%s.gz", mo_file); + mo_file = grub_xasprintf ("%s.gz", mo_file); if (!mo_file) return; fd_mo = grub_mofile_open (mo_file); diff --git a/include/grub/misc.h b/include/grub/misc.h index 2c1817492..221734a22 100644 --- a/include/grub/misc.h +++ b/include/grub/misc.h @@ -199,9 +199,9 @@ int EXPORT_FUNC(grub_snprintf) (char *str, grub_size_t n, const char *fmt, ...) __attribute__ ((format (printf, 3, 4))); int EXPORT_FUNC(grub_vsnprintf) (char *str, grub_size_t n, const char *fmt, va_list args); -char *EXPORT_FUNC(grub_asprintf) (const char *fmt, ...) +char *EXPORT_FUNC(grub_xasprintf) (const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); -char *EXPORT_FUNC(grub_avsprintf) (const char *fmt, va_list args); +char *EXPORT_FUNC(grub_xvasprintf) (const char *fmt, va_list args); void EXPORT_FUNC(grub_exit) (void) __attribute__ ((noreturn)); void EXPORT_FUNC(grub_abort) (void) __attribute__ ((noreturn)); grub_size_t EXPORT_FUNC(grub_utf8_to_ucs4) (grub_uint32_t *dest, diff --git a/kern/device.c b/kern/device.c index 3727ddcd9..5cfd190f3 100644 --- a/kern/device.c +++ b/kern/device.c @@ -146,7 +146,7 @@ grub_device_iterate (int (*hook) (const char *name)) return 1; } - p->name = grub_asprintf ("%s,%s", disk->name, partition_name); + p->name = grub_xasprintf ("%s,%s", disk->name, partition_name); if (!p->name) { grub_free (partition_name); diff --git a/kern/dl.c b/kern/dl.c index ce134a34f..4735a004a 100644 --- a/kern/dl.c +++ b/kern/dl.c @@ -627,7 +627,7 @@ grub_dl_load (const char *name) return 0; } - filename = grub_asprintf ("%s/%s.mod", grub_dl_dir, name); + filename = grub_xasprintf ("%s/%s.mod", grub_dl_dir, name); if (! filename) return 0; diff --git a/kern/efi/init.c b/kern/efi/init.c index 7f5f4ddd2..a0b4ff779 100644 --- a/kern/efi/init.c +++ b/kern/efi/init.c @@ -63,7 +63,7 @@ grub_efi_set_prefix (void) if (p) *p = '\0'; - prefix = grub_asprintf ("(%s)%s", device, file); + prefix = grub_xasprintf ("(%s)%s", device, file); if (prefix) { diff --git a/kern/env.c b/kern/env.c index 49a8db362..cebb4eeff 100644 --- a/kern/env.c +++ b/kern/env.c @@ -357,7 +357,7 @@ grub_register_variable_hook (const char *name, static char * mangle_data_slot_name (const char *name) { - return grub_asprintf ("\e%s", name); + return grub_xasprintf ("\e%s", name); } grub_err_t diff --git a/kern/ieee1275/init.c b/kern/ieee1275/init.c index b09623f1b..04e4e2dca 100644 --- a/kern/ieee1275/init.c +++ b/kern/ieee1275/init.c @@ -111,7 +111,7 @@ grub_machine_set_prefix (void) *lastslash = '\0'; grub_translate_ieee1275_path (filename); - newprefix = grub_asprintf ("%s%s", prefix, filename); + newprefix = grub_xasprintf ("%s%s", prefix, filename); if (newprefix) { grub_free (prefix); diff --git a/kern/ieee1275/openfw.c b/kern/ieee1275/openfw.c index 50bd9557a..5f0aad119 100644 --- a/kern/ieee1275/openfw.c +++ b/kern/ieee1275/openfw.c @@ -82,7 +82,7 @@ grub_children_iterate (char *devpath, IEEE1275_MAX_PROP_LEN, &actual)) continue; - fullname = grub_asprintf ("%s/%s", devpath, childname); + fullname = grub_xasprintf ("%s/%s", devpath, childname); if (!fullname) { grub_free (childname); @@ -332,7 +332,7 @@ grub_ieee1275_parse_args (const char *path, enum grub_ieee1275_parse_type ptype) /* Make sure filepath has leading backslash. */ if (filepath[0] != '\\') - ret = grub_asprintf ("\\%s", filepath); + ret = grub_xasprintf ("\\%s", filepath); else ret = grub_strdup (filepath); } @@ -382,10 +382,10 @@ grub_ieee1275_encode_devname (const char *path) /* GRUB partition 1 is OF partition 0. */ partno++; - encoding = grub_asprintf ("(%s,%d)", device, partno); + encoding = grub_xasprintf ("(%s,%d)", device, partno); } else - encoding = grub_asprintf ("(%s)", device); + encoding = grub_xasprintf ("(%s)", device); grub_free (partition); grub_free (device); diff --git a/kern/misc.c b/kern/misc.c index b1446de5c..ba31d24bb 100644 --- a/kern/misc.c +++ b/kern/misc.c @@ -913,7 +913,7 @@ grub_snprintf (char *str, grub_size_t n, const char *fmt, ...) #define PREALLOC_SIZE 255 char * -grub_avsprintf (const char *fmt, va_list ap) +grub_xvasprintf (const char *fmt, va_list ap) { grub_size_t s, as = PREALLOC_SIZE; char *ret; @@ -934,13 +934,13 @@ grub_avsprintf (const char *fmt, va_list ap) } char * -grub_asprintf (const char *fmt, ...) +grub_xasprintf (const char *fmt, ...) { va_list ap; char *ret; va_start (ap, fmt); - ret = grub_avsprintf (fmt, ap); + ret = grub_xvasprintf (fmt, ap); va_end (ap); return ret; diff --git a/kern/sparc64/ieee1275/init.c b/kern/sparc64/ieee1275/init.c index 339d836a3..115328f40 100644 --- a/kern/sparc64/ieee1275/init.c +++ b/kern/sparc64/ieee1275/init.c @@ -90,7 +90,7 @@ grub_machine_set_prefix (void) } prefix = grub_ieee1275_encode_devname (bootpath); - path = grub_asprintf("%s%s", prefix, grub_prefix); + path = grub_xasprintf("%s%s", prefix, grub_prefix); grub_strcpy (grub_prefix, path); diff --git a/loader/i386/bsd.c b/loader/i386/bsd.c index 7215c4e82..2598371b7 100644 --- a/loader/i386/bsd.c +++ b/loader/i386/bsd.c @@ -1150,7 +1150,7 @@ grub_cmd_freebsd_loadenv (grub_command_t cmd __attribute__ ((unused)), if (*p == '"') p++; - name = grub_asprintf ("kFreeBSD.%s", curr); + name = grub_xasprintf ("kFreeBSD.%s", curr); if (!name) goto fail; if (grub_env_set (name, p)) diff --git a/loader/i386/linux.c b/loader/i386/linux.c index c764dad25..5d9edbe7d 100644 --- a/loader/i386/linux.c +++ b/loader/i386/linux.c @@ -519,7 +519,7 @@ grub_linux_boot (void) May change in future if we have modes without framebuffer. */ if (modevar && *modevar != 0) { - tmp = grub_asprintf ("%s;text", modevar); + tmp = grub_xasprintf ("%s;text", modevar); if (! tmp) return grub_errno; err = grub_video_set_mode (tmp, 0, 0); @@ -797,7 +797,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), linux_mode = &linux_vesafb_modes[vid_mode - GRUB_LINUX_VID_MODE_VESA_START]; - buf = grub_asprintf ("%ux%ux%u,%ux%u", + buf = grub_xasprintf ("%ux%ux%u,%ux%u", linux_vesafb_res[linux_mode->res_index].width, linux_vesafb_res[linux_mode->res_index].height, linux_mode->depth, diff --git a/loader/i386/multiboot.c b/loader/i386/multiboot.c index 16c19b6d1..fc9588269 100644 --- a/loader/i386/multiboot.c +++ b/loader/i386/multiboot.c @@ -252,11 +252,11 @@ grub_multiboot (int argc, char *argv[]) { char *buf; if (header->depth && header->width && header->height) - buf = grub_asprintf ("%dx%dx%d,%dx%d,auto", header->width, + buf = grub_xasprintf ("%dx%dx%d,%dx%d,auto", header->width, header->height, header->depth, header->width, header->height); else if (header->width && header->height) - buf = grub_asprintf ("%dx%d,auto", header->width, header->height); + buf = grub_xasprintf ("%dx%d,auto", header->width, header->height); else buf = grub_strdup ("auto"); diff --git a/loader/i386/multiboot_mbi.c b/loader/i386/multiboot_mbi.c index 4493c03c7..a154d1b23 100644 --- a/loader/i386/multiboot_mbi.c +++ b/loader/i386/multiboot_mbi.c @@ -150,7 +150,7 @@ set_video_mode (void) else { char *tmp; - tmp = grub_asprintf ("%s;" DEFAULT_VIDEO_MODE, modevar); + tmp = grub_xasprintf ("%s;" DEFAULT_VIDEO_MODE, modevar); if (! tmp) return grub_errno; err = grub_video_set_mode (tmp, 0, 0); diff --git a/loader/i386/pc/xnu.c b/loader/i386/pc/xnu.c index 1c8b1ddec..c683dd0f9 100644 --- a/loader/i386/pc/xnu.c +++ b/loader/i386/pc/xnu.c @@ -47,7 +47,7 @@ grub_xnu_set_video (struct grub_xnu_boot_params *params) 32 << GRUB_VIDEO_MODE_TYPE_DEPTH_POS); else { - tmp = grub_asprintf ("%s;" DEFAULT_VIDEO_MODE, modevar); + tmp = grub_xasprintf ("%s;" DEFAULT_VIDEO_MODE, modevar); if (! tmp) return grub_error (GRUB_ERR_OUT_OF_MEMORY, "couldn't allocate temporary storag"); diff --git a/loader/xnu.c b/loader/xnu.c index 30ce95b3f..e0a2dfe8b 100644 --- a/loader/xnu.c +++ b/loader/xnu.c @@ -569,7 +569,7 @@ grub_xnu_register_memory (char *prefix, int *suffix, return grub_error (GRUB_ERR_OUT_OF_MEMORY, "can't register memory"); if (suffix) { - driverkey->name = grub_asprintf ("%s%d", prefix, (*suffix)++); + driverkey->name = grub_xasprintf ("%s%d", prefix, (*suffix)++); if (!driverkey->name) return grub_error (GRUB_ERR_OUT_OF_MEMORY, "can't register memory"); } diff --git a/normal/autofs.c b/normal/autofs.c index 94c08c59e..57e43fdf4 100644 --- a/normal/autofs.c +++ b/normal/autofs.c @@ -57,7 +57,7 @@ read_fs_list (void) { char *filename; - filename = grub_asprintf ("%s/fs.lst", prefix); + filename = grub_xasprintf ("%s/fs.lst", prefix); if (filename) { grub_file_t file; diff --git a/normal/completion.c b/normal/completion.c index aed4c4787..13e8f7a6b 100644 --- a/normal/completion.c +++ b/normal/completion.c @@ -107,7 +107,7 @@ iterate_partition (grub_disk_t disk, const grub_partition_t p) if (! partition_name) return 1; - name = grub_asprintf ("%s,%s", disk_name, partition_name); + name = grub_xasprintf ("%s,%s", disk_name, partition_name); grub_free (partition_name); if (! name) @@ -138,7 +138,7 @@ iterate_dir (const char *filename, const struct grub_dirhook_info *info) { char *fname; - fname = grub_asprintf ("%s/", filename); + fname = grub_xasprintf ("%s/", filename); if (add_completion (fname, "", GRUB_COMPLETION_TYPE_FILE)) { grub_free (fname); @@ -359,7 +359,7 @@ complete_arguments (char *command) if (!option->longarg) continue; - longarg = grub_asprintf ("--%s", option->longarg); + longarg = grub_xasprintf ("--%s", option->longarg); if (!longarg) return 1; diff --git a/normal/crypto.c b/normal/crypto.c index 7ca0de900..932f26f97 100644 --- a/normal/crypto.c +++ b/normal/crypto.c @@ -80,7 +80,7 @@ read_crypto_list (void) return; } - filename = grub_asprintf ("%s/crypto.lst", prefix); + filename = grub_xasprintf ("%s/crypto.lst", prefix); if (!filename) { grub_errno = GRUB_ERR_NONE; diff --git a/normal/dyncmd.c b/normal/dyncmd.c index 8f324626c..ca9a82289 100644 --- a/normal/dyncmd.c +++ b/normal/dyncmd.c @@ -69,7 +69,7 @@ read_command_list (void) { char *filename; - filename = grub_asprintf ("%s/command.lst", prefix); + filename = grub_xasprintf ("%s/command.lst", prefix); if (filename) { grub_file_t file; diff --git a/normal/handler.c b/normal/handler.c index 034be77d1..686626929 100644 --- a/normal/handler.c +++ b/normal/handler.c @@ -172,7 +172,7 @@ read_handler_list (void) { char *filename; - filename = grub_asprintf ("%s/handler.lst", prefix); + filename = grub_xasprintf ("%s/handler.lst", prefix); if (filename) { grub_file_t file; diff --git a/normal/main.c b/normal/main.c index 0c192712f..6e3518a59 100644 --- a/normal/main.c +++ b/normal/main.c @@ -412,7 +412,7 @@ grub_normal_init_page (struct grub_term_output *term) grub_term_cls (term); - msg_formatted = grub_asprintf (msg, PACKAGE_VERSION); + msg_formatted = grub_xasprintf (msg, PACKAGE_VERSION); if (!msg_formatted) return; @@ -502,7 +502,7 @@ grub_cmd_normal (struct grub_command *cmd __attribute__ ((unused)), prefix = grub_env_get ("prefix"); if (prefix) { - config = grub_asprintf ("%s/grub.cfg", prefix); + config = grub_xasprintf ("%s/grub.cfg", prefix); if (! config) goto quit; @@ -541,7 +541,7 @@ grub_normal_reader_init (int nested) const char *msg_esc = _("ESC at any time exits."); char *msg_formatted; - msg_formatted = grub_asprintf (msg, nested ? msg_esc : ""); + msg_formatted = grub_xasprintf (msg, nested ? msg_esc : ""); if (!msg_formatted) return grub_errno; @@ -566,9 +566,9 @@ grub_normal_read_line_real (char **line, int cont, int nested) char *prompt; if (cont) - prompt = grub_asprintf (">"); + prompt = grub_xasprintf (">"); else - prompt = grub_asprintf ("%s>", parser->name); + prompt = grub_xasprintf ("%s>", parser->name); if (!prompt) return grub_errno; diff --git a/normal/menu_text.c b/normal/menu_text.c index f7a1358f4..b39f57512 100644 --- a/normal/menu_text.c +++ b/normal/menu_text.c @@ -187,7 +187,7 @@ command-line or ESC to return menu."), STANDARD_MARGIN, STANDARD_MARGIN, "entry is highlighted.\n"); char *msg_translated; - msg_translated = grub_asprintf (msg, (grub_uint32_t) GRUB_TERM_DISP_UP, + msg_translated = grub_xasprintf (msg, (grub_uint32_t) GRUB_TERM_DISP_UP, (grub_uint32_t) GRUB_TERM_DISP_DOWN); if (!msg_translated) return; @@ -367,7 +367,7 @@ menu_text_print_timeout (int timeout, void *dataptr) grub_term_gotoxy (data->term, 0, grub_term_height (data->term) - 3); - msg_translated = grub_asprintf (msg, timeout); + msg_translated = grub_xasprintf (msg, timeout); if (!msg_translated) { grub_print_error (); diff --git a/normal/term.c b/normal/term.c index 86902c7a1..42201fbb3 100644 --- a/normal/term.c +++ b/normal/term.c @@ -167,7 +167,7 @@ read_terminal_list (void) return; } - filename = grub_asprintf ("%s/terminal.lst", prefix); + filename = grub_xasprintf ("%s/terminal.lst", prefix); if (!filename) { grub_errno = GRUB_ERR_NONE; diff --git a/partmap/acorn.c b/partmap/acorn.c index aead5ff85..081b6ee94 100644 --- a/partmap/acorn.c +++ b/partmap/acorn.c @@ -175,7 +175,7 @@ fail: static char * acorn_partition_map_get_name (const grub_partition_t p) { - return grub_asprintf ("%d", p->index + 1); + return grub_xasprintf ("%d", p->index + 1); } diff --git a/partmap/amiga.c b/partmap/amiga.c index 691bd4c3e..f832db354 100644 --- a/partmap/amiga.c +++ b/partmap/amiga.c @@ -184,7 +184,7 @@ amiga_partition_map_probe (grub_disk_t disk, const char *str) static char * amiga_partition_map_get_name (const grub_partition_t p) { - return grub_asprintf ("%d", p->index + 1); + return grub_xasprintf ("%d", p->index + 1); } diff --git a/partmap/apple.c b/partmap/apple.c index 18dbef586..a1a645acf 100644 --- a/partmap/apple.c +++ b/partmap/apple.c @@ -227,7 +227,7 @@ apple_partition_map_probe (grub_disk_t disk, const char *str) static char * apple_partition_map_get_name (const grub_partition_t p) { - return grub_asprintf ("%d", p->index + 1); + return grub_xasprintf ("%d", p->index + 1); } diff --git a/partmap/gpt.c b/partmap/gpt.c index ed583e0a3..cb1229bee 100644 --- a/partmap/gpt.c +++ b/partmap/gpt.c @@ -162,7 +162,7 @@ gpt_partition_map_probe (grub_disk_t disk, const char *str) static char * gpt_partition_map_get_name (const grub_partition_t p) { - return grub_asprintf ("%d", p->index + 1); + return grub_xasprintf ("%d", p->index + 1); } diff --git a/partmap/msdos.c b/partmap/msdos.c index ea3266605..1c3861cc7 100644 --- a/partmap/msdos.c +++ b/partmap/msdos.c @@ -303,11 +303,11 @@ pc_partition_map_get_name (const grub_partition_t p) struct grub_msdos_partition *pcdata = p->data; if (pcdata->bsd_part < 0) - return grub_asprintf ("%d", pcdata->dos_part + 1); + return grub_xasprintf ("%d", pcdata->dos_part + 1); else if (pcdata->dos_part < 0) - return grub_asprintf ("%c", pcdata->bsd_part + 'a'); + return grub_xasprintf ("%c", pcdata->bsd_part + 'a'); else - return grub_asprintf ("%d,%c", pcdata->dos_part + 1, + return grub_xasprintf ("%d,%c", pcdata->dos_part + 1, pcdata->bsd_part + 'a'); } diff --git a/partmap/sun.c b/partmap/sun.c index 89d0c5303..42cf0d598 100644 --- a/partmap/sun.c +++ b/partmap/sun.c @@ -184,7 +184,7 @@ sun_partition_map_probe (grub_disk_t disk, const char *str) static char * sun_partition_map_get_name (const grub_partition_t p) { - return grub_asprintf ("%d", p->index + 1); + return grub_xasprintf ("%d", p->index + 1); } /* Partition map type. */ diff --git a/term/gfxterm.c b/term/gfxterm.c index 50752bf89..a8aca7820 100644 --- a/term/gfxterm.c +++ b/term/gfxterm.c @@ -270,7 +270,7 @@ grub_gfxterm_init (void) GRUB_VIDEO_MODE_TYPE_PURE_TEXT, 0); else { - tmp = grub_asprintf ("%s;" DEFAULT_VIDEO_MODE, modevar); + tmp = grub_xasprintf ("%s;" DEFAULT_VIDEO_MODE, modevar); if (!tmp) return grub_errno; err = grub_video_set_mode (tmp, GRUB_VIDEO_MODE_TYPE_PURE_TEXT, 0); diff --git a/term/ieee1275/ofconsole.c b/term/ieee1275/ofconsole.c index b6be80cbe..dd4270eff 100644 --- a/term/ieee1275/ofconsole.c +++ b/term/ieee1275/ofconsole.c @@ -128,7 +128,7 @@ grub_ofconsole_setcolorstate (grub_term_color_state state) return; } - setcol = grub_asprintf ("\e[3%dm\e[4%dm", fg, bg); + setcol = grub_xasprintf ("\e[3%dm\e[4%dm", fg, bg); if (setcol) grub_ofconsole_writeesc (setcol); grub_free (setcol); @@ -301,7 +301,7 @@ grub_ofconsole_gotoxy (grub_uint8_t x, grub_uint8_t y) grub_curr_x = x; grub_curr_y = y; - s = grub_asprintf ("\e[%d;%dH", y + 1, x + 1); + s = grub_xasprintf ("\e[%d;%dH", y + 1, x + 1); if (s) grub_ofconsole_writeesc (s); grub_free (s); diff --git a/tests/lib/test.c b/tests/lib/test.c index a90a9972c..b5c054370 100644 --- a/tests/lib/test.c +++ b/tests/lib/test.c @@ -56,7 +56,7 @@ add_failure (const char *file, failure->file = grub_strdup (file ? : ""); failure->funp = grub_strdup (funp ? : ""); failure->line = line; - failure->message = grub_avsprintf (fmt, args); + failure->message = grub_xvasprintf (fmt, args); grub_list_push (GRUB_AS_LIST_P (&failure_list), GRUB_AS_LIST (failure)); } diff --git a/util/grub-fstest.c b/util/grub-fstest.c index e249920fe..bf30286a4 100644 --- a/util/grub-fstest.c +++ b/util/grub-fstest.c @@ -285,8 +285,8 @@ fstest (char **images, int num_disks, int cmd, int n, char **args) for (i = 0; i < num_disks; i++) { - loop_name = grub_asprintf ("loop%d", i); - host_file = grub_asprintf ("(host)%s", images[i]); + loop_name = grub_xasprintf ("loop%d", i); + host_file = grub_xasprintf ("(host)%s", images[i]); if (!loop_name || !host_file) { @@ -337,7 +337,7 @@ fstest (char **images, int num_disks, int cmd, int n, char **args) for (i = 0; i < num_disks; i++) { grub_free (loop_name); - loop_name = grub_asprintf ("loop%d", i); + loop_name = grub_xasprintf ("loop%d", i); if (!loop_name) { grub_free (host_file); From 93079f9f96d045d22ed610de34bdd20680592765 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 20 Jan 2010 09:28:35 +0100 Subject: [PATCH 248/738] ChangeLog --- ChangeLog.xasprintf | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 ChangeLog.xasprintf diff --git a/ChangeLog.xasprintf b/ChangeLog.xasprintf new file mode 100644 index 000000000..0aeefe93c --- /dev/null +++ b/ChangeLog.xasprintf @@ -0,0 +1,17 @@ +2010-01-20 Vladimir Serbinenko + + * include/grub/misc.h (grub_sprintf): Removed. All users switched to + grub_xasprintf or grub_snprintf. + (grub_vsprintf): Likewise. + (grub_snprintf): New proto. + (grub_vsnprintf): Likewise. + (grub_xasprintf): Likewise. + (grub_xvasprintf): Likewise. + * kern/misc.c (grub_vprintf): Use grub_vsnprintf_real. + (grub_sprintf): Removed. + (grub_vsnprintf): New function. + (grub_snprintf): Likewise. + (grub_xvasprintf): Likewise. + (grub_xasprintf): Likewise. + (grub_vsprintf): Renamed to ... + (grub_vsnprintf_real): ...this. New argument max_len. From 327dbcd7b93721524508b806bec9198f18ff71fd Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 20 Jan 2010 10:59:15 +0100 Subject: [PATCH 249/738] 2010-01-20 Vladimir Serbinenko Don't try to generate lists for kernel.img. * conf/i386-efi.rmk (pkglib_PROGRAMS): New variable. (pkglib_MODULES): Remove kernel.img. (kernel_img_EXPORTS): Removed. (kernel_img_RELOCATABLE): New variable. * conf/x86_64-efi.rmk: Likewise. * genmk.rb: Remove *_EXPORTS support and add *_RELOCATABLE support. --- ChangeLog | 11 +++++++++++ conf/i386-efi.rmk | 5 +++-- conf/x86_64-efi.rmk | 5 +++-- genmk.rb | 10 ++++++---- 4 files changed, 23 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7c842e777..f814b940d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2010-01-20 Vladimir Serbinenko + + Don't try to generate lists for kernel.img. + + * conf/i386-efi.rmk (pkglib_PROGRAMS): New variable. + (pkglib_MODULES): Remove kernel.img. + (kernel_img_EXPORTS): Removed. + (kernel_img_RELOCATABLE): New variable. + * conf/x86_64-efi.rmk: Likewise. + * genmk.rb: Remove *_EXPORTS support and add *_RELOCATABLE support. + 2010-01-20 Vladimir Serbinenko * include/grub/misc.h (grub_sprintf): Removed. All users switched to diff --git a/conf/i386-efi.rmk b/conf/i386-efi.rmk index f3281a1bc..cbadc7e1a 100644 --- a/conf/i386-efi.rmk +++ b/conf/i386-efi.rmk @@ -30,13 +30,14 @@ sbin_SCRIPTS = grub-install grub_install_SOURCES = util/i386/efi/grub-install.in # Modules. -pkglib_MODULES = kernel.img chain.mod appleldr.mod \ +pkglib_PROGRAMS = kernel.img +pkglib_MODULES = chain.mod appleldr.mod \ linux.mod halt.mod reboot.mod pci.mod lspci.mod \ datetime.mod date.mod datehook.mod loadbios.mod \ fixvideo.mod mmap.mod acpi.mod # For kernel.img. -kernel_img_EXPORTS = no +kernel_img_RELOCATABLE = yes kernel_img_SOURCES = kern/i386/efi/startup.S kern/main.c kern/device.c \ kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \ kern/misc.c kern/mm.c kern/term.c \ diff --git a/conf/x86_64-efi.rmk b/conf/x86_64-efi.rmk index 122700711..e5b3aec25 100644 --- a/conf/x86_64-efi.rmk +++ b/conf/x86_64-efi.rmk @@ -29,13 +29,14 @@ sbin_SCRIPTS = grub-install grub_install_SOURCES = util/i386/efi/grub-install.in # Modules. -pkglib_MODULES = kernel.img chain.mod appleldr.mod \ +pkglib_PROGRAMS = kernel.img +pkglib_MODULES = chain.mod appleldr.mod \ halt.mod reboot.mod linux.mod pci.mod lspci.mod \ datetime.mod date.mod datehook.mod loadbios.mod \ fixvideo.mod mmap.mod acpi.mod # For kernel.img. -kernel_img_EXPORTS = no +kernel_img_RELOCATABLE = yes kernel_img_SOURCES = kern/x86_64/efi/startup.S kern/x86_64/efi/callwrap.S \ kern/main.c kern/device.c \ kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \ diff --git a/genmk.rb b/genmk.rb index 1ce064022..df03e1dfe 100644 --- a/genmk.rb +++ b/genmk.rb @@ -132,13 +132,11 @@ clean-module-#{@name}.#{@rule_count}: CLEAN_MODULE_TARGETS += clean-module-#{@name}.#{@rule_count} -ifneq ($(#{prefix}_EXPORTS),no) clean-module-#{@name}-symbol.#{@rule_count}: rm -f #{defsym} CLEAN_MODULE_TARGETS += clean-module-#{@name}-symbol.#{@rule_count} DEFSYMFILES += #{defsym} -endif mostlyclean-module-#{@name}.#{@rule_count}: rm -f #{deps_str} @@ -170,7 +168,6 @@ endif #{mod_src}: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh sh $(srcdir)/genmodsrc.sh '#{mod_name}' $< > $@ || (rm -f $@; exit 1) -ifneq ($(#{prefix}_EXPORTS),no) ifneq ($(TARGET_APPLE_CC),1) #{defsym}: #{pre_obj} $(NM) -g --defined-only -P -p $< | sed 's/^\\([^ ]*\\).*/\\1 #{mod_name}/' > $@ @@ -178,7 +175,6 @@ else #{defsym}: #{pre_obj} $(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]' | sed 's/^\\([^ ]*\\).*/\\1 #{mod_name}/' > $@ endif -endif #{undsym}: #{pre_obj} echo '#{mod_name}' > $@ @@ -331,9 +327,15 @@ class Program "CLEANFILES += #{@name} #{objs_str} MOSTLYCLEANFILES += #{deps_str} +ifeq ($(#{prefix}_RELOCATABLE),yes) +#{@name}: $(#{prefix}_DEPENDENCIES) #{objs_str} + $(TARGET_CC) -Wl,-r,-d -o $@ #{objs_str} $(TARGET_LDFLAGS) $(#{prefix}_LDFLAGS) + $(STRIP) --strip-unneeded -K start -R .note -R .comment $@ +else #{@name}: $(#{prefix}_DEPENDENCIES) #{objs_str} $(TARGET_CC) -o $@ #{objs_str} $(TARGET_LDFLAGS) $(#{prefix}_LDFLAGS) $(STRIP) -R .rel.dyn -R .reginfo -R .note -R .comment $@ +endif " + objs.collect_with_index do |obj, i| src = sources[i] From 02cf98ca8d6d7663864adbb5e44a8c76c9ab4096 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 20 Jan 2010 13:27:23 +0100 Subject: [PATCH 250/738] 2010-01-20 Vladimir Serbinenko MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * configure.ac: Add /usr/share/fonts/unifont/unifont.pcf.gz as possible unifont location (Gentoo). Reported by: Alexander Brüning --- ChangeLog | 6 ++++++ configure.ac | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index f814b940d..9883b5f02 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-01-20 Vladimir Serbinenko + + * configure.ac: Add /usr/share/fonts/unifont/unifont.pcf.gz + as possible unifont location (Gentoo). + Reported by: Alexander Brüning + 2010-01-20 Vladimir Serbinenko Don't try to generate lists for kernel.img. diff --git a/configure.ac b/configure.ac index a8e137b90..b1435de44 100644 --- a/configure.ac +++ b/configure.ac @@ -168,7 +168,7 @@ if test "x$YACC" = x; then AC_MSG_ERROR([bison is not found]) fi -for file in /usr/src/unifont.bdf /usr/share/fonts/X11/misc/unifont.pcf.gz ; do +for file in /usr/src/unifont.bdf /usr/share/fonts/X11/misc/unifont.pcf.gz /usr/share/fonts/unifont/unifont.pcf.gz; do if test -e $file ; then AC_SUBST([FONT_SOURCE], [$file]) break From 94fabf587a791d77daf7eeee4c2442d469348e06 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Wed, 20 Jan 2010 13:55:30 +0000 Subject: [PATCH 251/738] 2010-01-20 Robert Millan * util/grub.d/00_header.in: Fix handling of locale_dir. --- ChangeLog | 4 ++++ util/grub.d/00_header.in | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 9883b5f02..fbd2a37db 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-01-20 Robert Millan + + * util/grub.d/00_header.in: Fix handling of locale_dir. + 2010-01-20 Vladimir Serbinenko * configure.ac: Add /usr/share/fonts/unifont/unifont.pcf.gz diff --git a/util/grub.d/00_header.in b/util/grub.d/00_header.in index 0048ebed1..0610792c6 100644 --- a/util/grub.d/00_header.in +++ b/util/grub.d/00_header.in @@ -1,7 +1,7 @@ #! /bin/sh -e # grub-mkconfig helper script. -# Copyright (C) 2006,2007,2008,2009 Free Software Foundation, Inc. +# Copyright (C) 2006,2007,2008,2009,2010 Free Software Foundation, Inc. # # GRUB is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -122,7 +122,9 @@ esac # Gettext variables and module if [ "x${LANG}" != "xC" ] ; then + prepare_grub_to_access_device $(${grub_probe} --target=device ${locale_dir}) cat << EOF +set locale_dir=(\$root)$(make_system_path_relative_to_its_root ${locale_dir}) set locale_dir=${locale_dir} set lang=${grub_lang} insmod gettext From 6419c43e4f767cd5f3dcf4258c45bd3edcb60efa Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Wed, 20 Jan 2010 13:56:45 +0000 Subject: [PATCH 252/738] Fix indentation in util/grub.d/00_header.in output --- util/grub.d/00_header.in | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/util/grub.d/00_header.in b/util/grub.d/00_header.in index 306bef3c3..7cee825d2 100644 --- a/util/grub.d/00_header.in +++ b/util/grub.d/00_header.in @@ -97,11 +97,11 @@ EOF if [ x$GRUB_THEME != x ] && [ -f $GRUB_THEME ] \ && is_path_readable_by_grub $GRUB_THEME; then echo "Found theme: $GRUB_THEME" >&2 - prepare_grub_to_access_device `${grub_probe} --target=device $GRUB_THEME` + prepare_grub_to_access_device `${grub_probe} --target=device $GRUB_THEME` | sed -e "s/^/ /" cat << EOF -insmod gfxmenu -set theme=(\$root)`make_system_path_relative_to_its_root $GRUB_THEME` -set menuviewer=gfxmenu + insmod gfxmenu + set theme=(\$root)`make_system_path_relative_to_its_root $GRUB_THEME` + set menuviewer=gfxmenu EOF fi cat << EOF From 34a66d995b3fc6222cdbfaa2c3cf48398de3034c Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Wed, 20 Jan 2010 14:10:46 +0000 Subject: [PATCH 253/738] 2010-01-20 Robert Millan * util/grub.d/00_header.in: Fix stupid mistake from last commit. --- ChangeLog | 4 ++++ util/grub.d/00_header.in | 1 - 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index fbd2a37db..547070e8a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-01-20 Robert Millan + + * util/grub.d/00_header.in: Fix stupid mistake from last commit. + 2010-01-20 Robert Millan * util/grub.d/00_header.in: Fix handling of locale_dir. diff --git a/util/grub.d/00_header.in b/util/grub.d/00_header.in index 0610792c6..23e0cb569 100644 --- a/util/grub.d/00_header.in +++ b/util/grub.d/00_header.in @@ -125,7 +125,6 @@ if [ "x${LANG}" != "xC" ] ; then prepare_grub_to_access_device $(${grub_probe} --target=device ${locale_dir}) cat << EOF set locale_dir=(\$root)$(make_system_path_relative_to_its_root ${locale_dir}) -set locale_dir=${locale_dir} set lang=${grub_lang} insmod gettext EOF From cbca0ada6273773415e192fb53e9e987f17b05f5 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 20 Jan 2010 15:26:31 +0100 Subject: [PATCH 254/738] 2010-01-20 Vladimir Serbinenko Fix any-emu compilation. * conf/any-emu.rmk (bin_UTILITIES): Add grub-bin2h. * grub_bin2h_SOURCES: New variable. --- ChangeLog | 7 +++++++ conf/any-emu.rmk | 3 +++ 2 files changed, 10 insertions(+) diff --git a/ChangeLog b/ChangeLog index 547070e8a..7274a9920 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-01-20 Vladimir Serbinenko + + Fix any-emu compilation. + + * conf/any-emu.rmk (bin_UTILITIES): Add grub-bin2h. + * grub_bin2h_SOURCES: New variable. + 2010-01-20 Robert Millan * util/grub.d/00_header.in: Fix stupid mistake from last commit. diff --git a/conf/any-emu.rmk b/conf/any-emu.rmk index cee9e8338..5aa923893 100644 --- a/conf/any-emu.rmk +++ b/conf/any-emu.rmk @@ -98,3 +98,6 @@ endif grub_script.tab.c grub_script.tab.h: script/parser.y $(YACC) -d -p grub_script_yy -b grub_script $(srcdir)/script/parser.y DISTCLEANFILES += grub_script.tab.c grub_script.tab.h + +bin_UTILITIES += grub-bin2h +grub_bin2h_SOURCES = gnulib/progname.c util/bin2h.c From f66924a414b5440c06d73d0a4d74ded3cb580637 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Wed, 20 Jan 2010 14:40:00 +0000 Subject: [PATCH 255/738] 2010-01-20 Robert Millan * util/misc.c (make_system_path_relative_to_its_root): Work around special-casing of "/", as previous incarnation of this routine did. --- ChangeLog | 5 +++++ util/misc.c | 7 +++++++ 2 files changed, 12 insertions(+) diff --git a/ChangeLog b/ChangeLog index 7274a9920..c4048a66e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-01-20 Robert Millan + + * util/misc.c (make_system_path_relative_to_its_root): Work around + special-casing of "/", as previous incarnation of this routine did. + 2010-01-20 Vladimir Serbinenko Fix any-emu compilation. diff --git a/util/misc.c b/util/misc.c index 0b682c445..c5ab62e42 100644 --- a/util/misc.c +++ b/util/misc.c @@ -577,6 +577,13 @@ make_system_path_relative_to_its_root (const char *path) len--; } + /* This works around special-casing of "/" in Un*x. This function never + prints trailing slashes (so that its output can be appended a slash + unconditionally). Each slash in is considered a preceding slash, and + therefore the root directory is an empty string. */ + if (!strcmp (buf3, "/")) + buf3[0] = '\0'; + return buf3; } From 00308ecfe8d536340a319ae5a33dc001589bf843 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 20 Jan 2010 15:43:21 +0100 Subject: [PATCH 256/738] 2010-01-20 Vladimir Serbinenko * conf/common.rmk (font/font.c_DEPENDENCIES): Condition on FONT_SOURCE. --- ChangeLog | 4 ++++ conf/common.rmk | 2 ++ 2 files changed, 6 insertions(+) diff --git a/ChangeLog b/ChangeLog index c4048a66e..c6b4d7baf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-01-20 Vladimir Serbinenko + + * conf/common.rmk (font/font.c_DEPENDENCIES): Condition on FONT_SOURCE. + 2010-01-20 Robert Millan * util/misc.c (make_system_path_relative_to_its_root): Work around diff --git a/conf/common.rmk b/conf/common.rmk index 956ed8ec3..4e5ed9c73 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -638,7 +638,9 @@ png_mod_CFLAGS = $(COMMON_CFLAGS) png_mod_LDFLAGS = $(COMMON_LDFLAGS) pkglib_MODULES += font.mod +ifneq (, $(FONT_SOURCE)) font/font.c_DEPENDENCIES = ascii.h +endif font_mod_SOURCES = font/font_cmd.c font/font.c font_mod_CFLAGS = $(COMMON_CFLAGS) font_mod_LDFLAGS = $(COMMON_LDFLAGS) From d44844828a137c0325c46aedb56c2946ccb30aa0 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Wed, 20 Jan 2010 16:30:20 +0000 Subject: [PATCH 257/738] 2010-01-20 Robert Millan * loader/i386/linux.c (grub_cmd_linux): If `vga=' was used, write down that VESA is supported. (grub_linux_boot): Use generic framebuffer unless VESA is known to be supported. --- ChangeLog | 7 +++++++ loader/i386/linux.c | 10 +++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index c6b4d7baf..f96b99f77 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-01-20 Robert Millan + + * loader/i386/linux.c (grub_cmd_linux): If `vga=' was used, write down + that VESA is supported. + (grub_linux_boot): Use generic framebuffer unless VESA is known to be + supported. + 2010-01-20 Vladimir Serbinenko * conf/common.rmk (font/font.c_DEPENDENCIES): Condition on FONT_SOURCE. diff --git a/loader/i386/linux.c b/loader/i386/linux.c index 5d9edbe7d..831d8b25a 100644 --- a/loader/i386/linux.c +++ b/loader/i386/linux.c @@ -536,7 +536,11 @@ grub_linux_boot (void) } if (! grub_linux_setup_video (params)) - params->have_vga = GRUB_VIDEO_LINUX_TYPE_VESA; + { + /* Use generic framebuffer unless VESA is known to be supported. */ + if (params->have_vga != GRUB_VIDEO_LINUX_TYPE_VESA) + params->have_vga = GRUB_VIDEO_LINUX_TYPE_SIMPLE; + } else { params->have_vga = GRUB_VIDEO_LINUX_TYPE_TEXT; @@ -794,6 +798,10 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), break; } + /* We can't detect VESA, but user is implicitly telling us that it + is built-in because `vga=' parameter was used. */ + params->have_vga = GRUB_VIDEO_LINUX_TYPE_VESA; + linux_mode = &linux_vesafb_modes[vid_mode - GRUB_LINUX_VID_MODE_VESA_START]; From 96d73208a17dea7455a9dee49fc57270bd41919c Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Wed, 20 Jan 2010 17:01:12 +0000 Subject: [PATCH 258/738] 2010-01-20 Robert Millan * util/grub.d/10_linux.in (linux_entry): Set gfxpayload=keep when it can be reliably determined to be supported. --- ChangeLog | 5 +++++ util/grub.d/10_linux.in | 9 +++++++++ 2 files changed, 14 insertions(+) diff --git a/ChangeLog b/ChangeLog index f96b99f77..4ef13e931 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-01-20 Robert Millan + + * util/grub.d/10_linux.in (linux_entry): Set gfxpayload=keep when it + can be reliably determined to be supported. + 2010-01-20 Robert Millan * loader/i386/linux.c (grub_cmd_linux): If `vga=' was used, write down diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in index 3ecf454e2..90a6e83e7 100644 --- a/util/grub.d/10_linux.in +++ b/util/grub.d/10_linux.in @@ -60,6 +60,15 @@ linux_entry () fi printf "menuentry \"${title}\" {\n" "${os}" "${version}" save_default_entry | sed -e "s/^/\t/" + + # Use ELILO's generic "efifb" when it's known to be available. + # FIXME: We need an interface to select vesafb in case efifb can't be used. + if grep -qx "CONFIG_FB_EFI=y" /boot/config-${version} 2> /dev/null ; then + cat << EOF + set gfxpayload=keep +EOF + fi + if [ -z "${prepare_boot_cache}" ]; then prepare_boot_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/")" fi From 61c8e880e455d4c129ab06cae7f79f98e1014256 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 20 Jan 2010 20:33:01 +0100 Subject: [PATCH 259/738] Add comments to loadbios.c --- commands/efi/loadbios.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/commands/efi/loadbios.c b/commands/efi/loadbios.c index 183ba7e85..f48e4c5cb 100644 --- a/commands/efi/loadbios.c +++ b/commands/efi/loadbios.c @@ -50,6 +50,7 @@ enable_rom_area (void) return 0; } + /* FIXME: should be macroified. */ addr = grub_pci_make_address (dev, 144); grub_pci_write_byte (addr++, 0x30); grub_pci_write_byte (addr++, 0x33); @@ -76,6 +77,7 @@ lock_rom_area (void) grub_pci_address_t addr; grub_pci_device_t dev = { .bus = 0, .device = 0, .function = 0}; + /* FIXME: should be macroified. */ addr = grub_pci_make_address (dev, 144); grub_pci_write_byte (addr++, 0x10); grub_pci_write_byte (addr++, 0x11); From fdb1b2ea4e9eba8272b47e07029b05ffa6af5984 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 20 Jan 2010 20:49:18 +0100 Subject: [PATCH 260/738] 2010-01-20 Vladimir Serbinenko * video/sm712.c (grub_video_sm712_setup): Use GRUB_PCI_REG_CLASS. --- ChangeLog | 1 + video/sm712.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index b54f6aeec..d789f821e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -48,6 +48,7 @@ * loader/i386/efi/linux.c (find_framebuf): Use GRUB_PCI_REG_CLASS. * loader/i386/efi/xnu.c (find_framebuf): Likewise. * video/efi_uga.c (find_framebuf): Likewise. + * video/sm712.c (grub_video_sm712_setup): Likewise. * util/pci.c (grub_pci_make_address): Use byte-addressed configuration space. diff --git a/video/sm712.c b/video/sm712.c index 1e0f59b9d..a86470b7d 100644 --- a/video/sm712.c +++ b/video/sm712.c @@ -74,7 +74,7 @@ grub_video_sm712_setup (unsigned int width, unsigned int height, grub_pci_address_t addr; grub_uint32_t class; - addr = grub_pci_make_address (dev, 2); + addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); class = grub_pci_read (addr); if (((class >> 16) & 0xffff) != 0x0300 || pciid != 0x0712126f) @@ -82,7 +82,7 @@ grub_video_sm712_setup (unsigned int width, unsigned int height, found = 1; - addr = grub_pci_make_address (dev, 4); + addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); framebuffer.base = grub_pci_read (addr); framebuffer.dev = dev; From baccdb23a716413b74faaae556e7fbad5eb2c951 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 20 Jan 2010 20:54:58 +0100 Subject: [PATCH 261/738] Use grub_snprintf in commands/setpci.c --- commands/setpci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commands/setpci.c b/commands/setpci.c index aa5e51de9..f780547a2 100644 --- a/commands/setpci.c +++ b/commands/setpci.c @@ -118,7 +118,7 @@ grub_setpci_iter (grub_pci_device_t dev, grub_pci_id_t pciid) if (varname) { char buf[sizeof ("XXXXXXXX")]; - grub_sprintf (buf, "%x", regval); + grub_snprintf (buf, sizeof (buf), "%x", regval); grub_env_set (varname, buf); return 1; } From a9ed4ff36fde7c285cdeb80879dd70659190b7a5 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 20 Jan 2010 22:21:08 +0100 Subject: [PATCH 262/738] 2010-01-20 Vladimir Serbinenko * conf/mips.rmk (kernel_img_HEADERS): Add env_private.h --- ChangeLog | 6 +++++- conf/mips.rmk | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index bb66685b1..64aa9d593 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,8 @@ -2009-11-29 Vladimir Serbinenko +2010-01-20 Vladimir Serbinenko + + * conf/mips.rmk (kernel_img_HEADERS): Add env_private.h + +2010-01-20 Vladimir Serbinenko Optimise glyph lookup by Basic Multilingual Plane lookup array. diff --git a/conf/mips.rmk b/conf/mips.rmk index d0b1c484c..1ef4fc395 100644 --- a/conf/mips.rmk +++ b/conf/mips.rmk @@ -17,7 +17,7 @@ kernel_img_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ env.h err.h file.h fs.h kernel.h misc.h mm.h net.h parser.h reader.h \ symbol.h term.h time.h types.h loader.h partition.h \ msdos_partition.h machine/kernel.h handler.h list.h \ - command.h machine/memory.h cpu/libgcc.h cpu/cache.h i18n.h + command.h machine/memory.h cpu/libgcc.h cpu/cache.h i18n.h env_private.h ifeq ($(platform), yeeloong) kernel_img_HEADERS += pci.h From 67eb14272d46340bae6f69b35138d9c8996ecd00 Mon Sep 17 00:00:00 2001 From: Felix Zielcke Date: Wed, 20 Jan 2010 23:53:53 +0100 Subject: [PATCH 263/738] 2010-01-20 Felix Zielcke * util/misc.c (make_system_path_relative_to_its_root): Change the work around for handling "/" to the correct fix. Fix a memory leak. Use xstrdup instead of strdup. --- ChangeLog | 6 ++++++ util/misc.c | 31 ++++++++++++++++++------------- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index 64aa9d593..e69ead80d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-01-20 Felix Zielcke + + * util/misc.c (make_system_path_relative_to_its_root): Change the work + around for handling "/" to the correct fix. Fix a memory leak. Use + xstrdup instead of strdup. + 2010-01-20 Vladimir Serbinenko * conf/mips.rmk (kernel_img_HEADERS): Add env_private.h diff --git a/util/misc.c b/util/misc.c index c5ab62e42..b4960087e 100644 --- a/util/misc.c +++ b/util/misc.c @@ -513,13 +513,13 @@ make_system_path_relative_to_its_root (const char *path) grub_util_error ("failed to get canonical path of %s", path); len = strlen (p) + 1; - buf = strdup (p); + buf = xstrdup (p); free (p); if (stat (buf, &st) < 0) grub_util_error ("cannot stat %s: %s", buf, strerror (errno)); - buf2 = strdup (buf); + buf2 = xstrdup (buf); num = st.st_dev; /* This loop sets offset to the number of chars of the root @@ -541,12 +541,16 @@ make_system_path_relative_to_its_root (const char *path) /* buf is another filesystem; we found it. */ if (st.st_dev != num) { - /* offset == 0 means path given is the mount point. */ + /* offset == 0 means path given is the mount point. + This works around special-casing of "/" in Un*x. This function never + prints trailing slashes (so that its output can be appended a slash + unconditionally). Each slash in is considered a preceding slash, and + therefore the root directory is an empty string. */ if (offset == 0) { free (buf); free (buf2); - return strdup ("/"); + return xstrdup (""); } else break; @@ -563,11 +567,19 @@ make_system_path_relative_to_its_root (const char *path) buf2[len - 1] = '\0'; len--; } - return buf2; + if (len > 1) + return buf2; + else + { + /* This means path given is just a backslash. As above + we have to return an empty string. */ + free (buf2); + return xtrdup (""); + } } } free (buf); - buf3 = strdup (buf2 + offset); + buf3 = xstrdup (buf2 + offset); free (buf2); len = strlen (buf3); @@ -577,13 +589,6 @@ make_system_path_relative_to_its_root (const char *path) len--; } - /* This works around special-casing of "/" in Un*x. This function never - prints trailing slashes (so that its output can be appended a slash - unconditionally). Each slash in is considered a preceding slash, and - therefore the root directory is an empty string. */ - if (!strcmp (buf3, "/")) - buf3[0] = '\0'; - return buf3; } From caab4fd6ca335f1b2b397f77f5816a3785685a6b Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Thu, 21 Jan 2010 08:04:49 +0000 Subject: [PATCH 264/738] 2010-01-21 Robert Millan * po/POTFILES: Remove mkisofs-related files. They have their own TLP domain now. --- ChangeLog | 5 +++++ po/POTFILES | 9 --------- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index e69ead80d..d1e146bca 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-01-21 Robert Millan + + * po/POTFILES: Remove mkisofs-related files. They have their own TLP + domain now. + 2010-01-20 Felix Zielcke * util/misc.c (make_system_path_relative_to_its_root): Change the work diff --git a/po/POTFILES b/po/POTFILES index 04a3516fa..5fabb0634 100644 --- a/po/POTFILES +++ b/po/POTFILES @@ -79,12 +79,3 @@ term/serial.c util/grub-mkrawimage.c util/i386/pc/grub-setup.c - -util/mkisofs/eltorito.c -util/mkisofs/joliet.c -util/mkisofs/mkisofs.c -util/mkisofs/mkisofs.h -util/mkisofs/multi.c -util/mkisofs/rock.c -util/mkisofs/tree.c -util/mkisofs/write.c From 01fc7054b953ee43611fb160038f9db33835f962 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 21 Jan 2010 13:58:40 +0100 Subject: [PATCH 265/738] 2010-01-21 Vladimir Serbinenko * util/misc.c (make_system_path_relative_to_its_root): Fix typo. --- ChangeLog | 4 ++++ util/misc.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index d1e146bca..7f872f71a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-01-21 Vladimir Serbinenko + + * util/misc.c (make_system_path_relative_to_its_root): Fix typo. + 2010-01-21 Robert Millan * po/POTFILES: Remove mkisofs-related files. They have their own TLP diff --git a/util/misc.c b/util/misc.c index b4960087e..8f66e4350 100644 --- a/util/misc.c +++ b/util/misc.c @@ -574,7 +574,7 @@ make_system_path_relative_to_its_root (const char *path) /* This means path given is just a backslash. As above we have to return an empty string. */ free (buf2); - return xtrdup (""); + return xstrdup (""); } } } From f9ab2e25d3655a4401daa0f92ed1033c77d7c307 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 21 Jan 2010 17:35:14 +0100 Subject: [PATCH 266/738] 2010-01-21 Vladimir Serbinenko * include/grub/i386/bsd.h (FREEBSD_N_BIOS_GEOM): Removed. (grub_freebsd_bootinfo): Rewritten. * loader/i386/bsd.c (grub_freebsd_boot): Use new grub_freebsd_bootinfo. --- ChangeLog | 6 ++++++ include/grub/i386/bsd.h | 30 +++++++++++------------------- loader/i386/bsd.c | 20 ++++++++++---------- 3 files changed, 27 insertions(+), 29 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7f872f71a..f5bb1617b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-01-21 Vladimir Serbinenko + + * include/grub/i386/bsd.h (FREEBSD_N_BIOS_GEOM): Removed. + (grub_freebsd_bootinfo): Rewritten. + * loader/i386/bsd.c (grub_freebsd_boot): Use new grub_freebsd_bootinfo. + 2010-01-21 Vladimir Serbinenko * util/misc.c (make_system_path_relative_to_its_root): Fix typo. diff --git a/include/grub/i386/bsd.h b/include/grub/i386/bsd.h index e26c35652..4d55f04fb 100644 --- a/include/grub/i386/bsd.h +++ b/include/grub/i386/bsd.h @@ -44,33 +44,25 @@ enum bsd_kernel_types #define FREEBSD_B_PARTSHIFT OPENBSD_B_PARTSHIFT #define FREEBSD_B_TYPESHIFT OPENBSD_B_TYPESHIFT -#define FREEBSD_BOOTINFO_VERSION 1 -#define FREEBSD_N_BIOS_GEOM 8 - #define FREEBSD_MODTYPE_KERNEL "elf kernel" #define FREEBSD_MODTYPE_KERNEL64 "elf64 kernel" #define FREEBSD_MODTYPE_ELF_MODULE "elf module" #define FREEBSD_MODTYPE_ELF_MODULE_OBJ "elf obj module" #define FREEBSD_MODTYPE_RAW "raw" +#define FREEBSD_BOOTINFO_VERSION 1 + struct grub_freebsd_bootinfo { - grub_uint32_t bi_version; - grub_uint8_t *bi_kernelname; - struct nfs_diskless *bi_nfs_diskless; - grub_uint32_t bi_n_bios_used; - grub_uint32_t bi_bios_geom[FREEBSD_N_BIOS_GEOM]; - grub_uint32_t bi_size; - grub_uint8_t bi_memsizes_valid; - grub_uint8_t bi_bios_dev; - grub_uint8_t bi_pad[2]; - grub_uint32_t bi_basemem; - grub_uint32_t bi_extmem; - grub_uint32_t bi_symtab; - grub_uint32_t bi_esymtab; - grub_uint32_t bi_kernend; - grub_uint32_t bi_envp; - grub_uint32_t bi_modulep; + grub_uint32_t version; + grub_uint8_t unused1[44]; + grub_uint32_t length; + grub_uint8_t unused2; + grub_uint8_t boot_device; + grub_uint8_t unused3[18]; + grub_uint32_t kern_end; + grub_uint32_t environment; + grub_uint32_t tags; } __attribute__ ((packed)); struct grub_openbsd_bios_mmap diff --git a/loader/i386/bsd.c b/loader/i386/bsd.c index 2598371b7..3dd3c70c5 100644 --- a/loader/i386/bsd.c +++ b/loader/i386/bsd.c @@ -461,14 +461,14 @@ grub_freebsd_boot (void) } grub_memset (&bi, 0, sizeof (bi)); - bi.bi_version = FREEBSD_BOOTINFO_VERSION; - bi.bi_size = sizeof (bi); + bi.version = FREEBSD_BOOTINFO_VERSION; + bi.length = sizeof (bi); grub_bsd_get_device (&biosdev, &unit, &slice, &part); bootdev = (FREEBSD_B_DEVMAGIC + ((slice + 1) << FREEBSD_B_SLICESHIFT) + (unit << FREEBSD_B_UNITSHIFT) + (part << FREEBSD_B_PARTSHIFT)); - bi.bi_bios_dev = biosdev; + bi.boot_device = biosdev; p = (char *) kern_end; @@ -478,7 +478,7 @@ grub_freebsd_boot (void) { *(p++) = 0; - bi.bi_envp = kern_end; + bi.environment = kern_end; kern_end = ALIGN_PAGE ((grub_uint32_t) p); } @@ -491,23 +491,23 @@ grub_freebsd_boot (void) return grub_errno; grub_memcpy ((char *) kern_end, mod_buf, mod_buf_len); - bi.bi_modulep = kern_end; + bi.tags = kern_end; kern_end = ALIGN_PAGE (kern_end + mod_buf_len); if (is_64bit) kern_end += 4096 * 4; - md_ofs = bi.bi_modulep + kern_end_mdofs; + md_ofs = bi.tags + kern_end_mdofs; ofs = (is_64bit) ? 16 : 12; *((grub_uint32_t *) md_ofs) = kern_end; md_ofs -= ofs; - *((grub_uint32_t *) md_ofs) = bi.bi_envp; + *((grub_uint32_t *) md_ofs) = bi.environment; md_ofs -= ofs; *((grub_uint32_t *) md_ofs) = bootflags; } - bi.bi_kernend = kern_end; + bi.kern_end = kern_end; grub_video_set_mode ("text", 0, 0); @@ -554,12 +554,12 @@ grub_freebsd_boot (void) &grub_bsd64_trampoline_end - &grub_bsd64_trampoline_start); /* Launch trampoline. */ - launch_trampoline (entry, entry_hi, pagetable, bi.bi_modulep, + launch_trampoline (entry, entry_hi, pagetable, bi.tags, kern_end); } else grub_unix_real_boot (entry, bootflags | FREEBSD_RB_BOOTINFO, bootdev, - 0, 0, 0, &bi, bi.bi_modulep, kern_end); + 0, 0, 0, &bi, bi.tags, kern_end); /* Not reached. */ return GRUB_ERR_NONE; From d645e0f8e8e9243ad193df4fd2b4bbc97ec79121 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 22 Jan 2010 00:07:28 +0100 Subject: [PATCH 267/738] 2010-01-21 Vladimir Serbinenko * term/ieee1275/ofconsole.c (grub_ofconsole_dimensions): Allocate on stack since heap is unavailable at that point. --- ChangeLog | 5 +++++ term/ieee1275/ofconsole.c | 33 ++++++++++++--------------------- 2 files changed, 17 insertions(+), 21 deletions(-) diff --git a/ChangeLog b/ChangeLog index f5bb1617b..f227f5dbc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-01-21 Vladimir Serbinenko + + * term/ieee1275/ofconsole.c (grub_ofconsole_dimensions): Allocate on + stack since heap is unavailable at that point. + 2010-01-21 Vladimir Serbinenko * include/grub/i386/bsd.h (FREEBSD_N_BIOS_GEOM): Removed. diff --git a/term/ieee1275/ofconsole.c b/term/ieee1275/ofconsole.c index dd4270eff..3799e2e27 100644 --- a/term/ieee1275/ofconsole.c +++ b/term/ieee1275/ofconsole.c @@ -245,37 +245,28 @@ static void grub_ofconsole_dimensions (void) { grub_ieee1275_ihandle_t options; - char *val; grub_ssize_t lval; if (! grub_ieee1275_finddevice ("/options", &options) && options != (grub_ieee1275_ihandle_t) -1) { if (! grub_ieee1275_get_property_length (options, "screen-#columns", - &lval) && lval != -1) + &lval) + && lval >= 0 && lval < 1024) { - val = grub_malloc (lval); - if (val) - { - if (! grub_ieee1275_get_property (options, "screen-#columns", - val, lval, 0)) - grub_ofconsole_width = (grub_uint8_t) grub_strtoul (val, 0, 10); + char val[lval]; - grub_free (val); - } + if (! grub_ieee1275_get_property (options, "screen-#columns", + val, lval, 0)) + grub_ofconsole_width = (grub_uint8_t) grub_strtoul (val, 0, 10); } - if (! grub_ieee1275_get_property_length (options, "screen-#rows", - &lval) && lval != -1) + if (! grub_ieee1275_get_property_length (options, "screen-#rows", &lval) + && lval >= 0 && lval < 1024) { - val = grub_malloc (lval); - if (val) - { - if (! grub_ieee1275_get_property (options, "screen-#rows", - val, lval, 0)) - grub_ofconsole_height = (grub_uint8_t) grub_strtoul (val, 0, 10); - - grub_free (val); - } + char val[lval]; + if (! grub_ieee1275_get_property (options, "screen-#rows", + val, lval, 0)) + grub_ofconsole_height = (grub_uint8_t) grub_strtoul (val, 0, 10); } } From bf86e59a76c3731e2b68c20ce5915ed4c07571a7 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 22 Jan 2010 00:33:07 +0100 Subject: [PATCH 268/738] 2010-01-22 Vladimir Serbinenko * kern/ieee1275/init.c (grub_machine_set_prefix): Don't check for presence of "prefix" variable as it breaks when normal.mod is embedded. --- ChangeLog | 6 ++++++ kern/ieee1275/init.c | 4 ---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index f227f5dbc..5eef8a821 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-01-22 Vladimir Serbinenko + + * kern/ieee1275/init.c (grub_machine_set_prefix): Don't check for + presence of "prefix" variable as it breaks when normal.mod is + embedded. + 2010-01-21 Vladimir Serbinenko * term/ieee1275/ofconsole.c (grub_ofconsole_dimensions): Allocate on diff --git a/kern/ieee1275/init.c b/kern/ieee1275/init.c index 04e4e2dca..f3a4f4d81 100644 --- a/kern/ieee1275/init.c +++ b/kern/ieee1275/init.c @@ -75,10 +75,6 @@ grub_machine_set_prefix (void) char *filename; char *prefix; - if (grub_env_get ("prefix")) - /* We already set prefix in grub_machine_init(). */ - return; - if (grub_prefix[0]) { grub_env_set ("prefix", grub_prefix); From 547e494f1bb81037efd44ec4fed7bac264764d3f Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Fri, 22 Jan 2010 19:07:27 +0530 Subject: [PATCH 269/738] lexer-rewrite rebase commit --- ChangeLog.lexer-rewrite | 70 ++++ conf/any-emu.rmk | 10 +- conf/common.rmk | 12 +- conf/i386-coreboot.rmk | 2 +- conf/i386-efi.rmk | 2 +- conf/i386-ieee1275.rmk | 2 +- conf/i386-pc.rmk | 2 +- conf/powerpc-ieee1275.rmk | 2 +- conf/sparc64-ieee1275.rmk | 2 +- conf/tests.rmk | 24 +- conf/x86_64-efi.rmk | 2 +- configure.ac | 5 + include/grub/script_sh.h | 60 +-- script/execute.c | 218 ++++++---- script/function.c | 4 +- script/lexer.c | 612 ++++++++++++----------------- script/parser.y | 311 ++++++++------- script/script.c | 110 +++--- script/yylex.l | 331 ++++++++++++++++ tests/grub_script_echo1.in | 32 ++ tests/grub_script_echo_keywords.in | 3 + tests/grub_script_vars1.in | 34 ++ tests/util/grub-shell-tester.in | 2 +- tests/util/grub-shell.in | 2 +- util/grub-script-check.c | 12 +- 25 files changed, 1214 insertions(+), 652 deletions(-) create mode 100644 ChangeLog.lexer-rewrite create mode 100644 script/yylex.l create mode 100644 tests/grub_script_echo1.in create mode 100644 tests/grub_script_echo_keywords.in create mode 100644 tests/grub_script_vars1.in diff --git a/ChangeLog.lexer-rewrite b/ChangeLog.lexer-rewrite new file mode 100644 index 000000000..56c637976 --- /dev/null +++ b/ChangeLog.lexer-rewrite @@ -0,0 +1,70 @@ +2010-01-10 BVK Chaitanya + + * conf/any-emu.rmk: Build rule updates. + * conf/common.rmk: Likewise. + * conf/i386-coreboot.rmk: Likewise. + * conf/i386-efi.rmk: Likewise. + * conf/i386-ieee1275.rmk: Likewise. + * conf/i386-pc.rmk: Likewise. + * conf/powerpc-ieee1275.rmk: Likewise. + * conf/x86_64-efi.rmk: Likewise. + + * configure.ac: Configure check for flex. + + * include/grub/script_sh.h (grub_script_arg_type_t): More argument + types. + (grub_lexer_param): Struct member updates. + (grub_parser_param): Likewise. + (GRUB_LEXER_TOKEN_MAX): Maximum token size. + (GRUB_LEXER_RECORD_INCREMENT): Memory increments' size. + (grub_script_lexer_init): Prototype update. + (grub_script_lexer_record_start): Likewise. + (grub_script_lexer_record_stop): Likewise. + (grub_script_lexer_yywrap): New function prototype. + (grub_script_lexer_fini): Likewise. + (grub_script_execute_argument_to_string): Removed by... + (grub_script_execute_argument_to_argv): ...better version. + + * script/execute.c (ROUND_UPTO): New macro. + (grub_script_execute_cmdline): Out of memory fixes. + (grub_script_execute_menuentry): Likewise. + (grub_script_execute_argument_to_string): Removed. Update all + users by... + (grub_script_execute_argument_to_argv): ...better version. + * script/function.c (grub_script_function_create): Use + grub_script_execute_argument_to_argv instead of + grub_script_execute_argument_to_string. + + * script/lexer.c (check_varstate): Removed. + (check_textstate): Removed. + (grub_script_lexer_record_start): Likewise. + (grub_script_lexer_record_stop): Likewise. + (recordchar): Replaced with... + (grub_script_lexer_record): ...new function. + (nextchar): Removed. + (grub_script_lexer_init): Rewritten. + (grub_script_yylex): Rewritten. + (append_newline): New function. + (grub_script_lexer_yywrap): New function. + (grub_script_lexer_fini): New function. + (grub_script_yyerror): Sets error flag. + + * script/yylex.l: New file. + (grub_lexer_yyfree): Wrapper for flex yyffre. + (grub_lexer_yyalloc): Likewise. + (grub_lexer_yyrealloc): Likewise. + * script/parser.y: Refactored. + + * script/script.c (grub_script_arg_add): Out of memory fixes. + (grub_script_add_arglist): Likewise. + (grub_script_create_cmdline): Likewise. + (grub_script_create_cmdmenu): Likewise. + (grub_script_add_cmd): Likewise. + (grub_script_parse): Use grub_script_lexer_fini to deallocated. + * util/grub-script-check.c (grub_script_execute_menuentry): Remove + unnecessary code. + + * tests/grub_script_echo1.in: New testcase. + * tests/grub_script_vars1.in: New testcase. + * tests/grub_script_echo_keywords.in: New testcase. + diff --git a/conf/any-emu.rmk b/conf/any-emu.rmk index 1277af791..cf343e61f 100644 --- a/conf/any-emu.rmk +++ b/conf/any-emu.rmk @@ -1,7 +1,7 @@ # -*- makefile -*- # Used by various components. These rules need to precede them. -script/lexer.c_DEPENDENCIES = grub_script.tab.h +script/lexer.c_DEPENDENCIES = grub_script.tab.h grub_script.yy.h sbin_UTILITIES += grub-emu util/grub-emu.c_DEPENDENCIES = grub_emu_init.h @@ -33,6 +33,8 @@ grub_emu_SOURCES = commands/minicmd.c commands/cat.c commands/cmp.c \ commands/terminal.c normal/context.c lib/charset.c \ script/main.c script/execute.c script/function.c \ script/lexer.c script/script.c grub_script.tab.c \ + grub_script.yy.c \ + \ partmap/amiga.c partmap/apple.c partmap/msdos.c partmap/sun.c \ partmap/acorn.c partmap/gpt.c \ \ @@ -99,5 +101,11 @@ grub_script.tab.c grub_script.tab.h: script/parser.y $(YACC) -d -p grub_script_yy -b grub_script $(srcdir)/script/parser.y DISTCLEANFILES += grub_script.tab.c grub_script.tab.h +grub_script.yy.c grub_script.yy.h: script/yylex.l + $(LEX) -o grub_script.yy.c --header-file=grub_script.yy.h $(srcdir)/script/yylex.l + sed -i 's/^#include.*\(\|\|\|\|\)//g' grub_script.yy.h + sed -i 's/^#include.*\(\|\|\|\|\)//g' grub_script.yy.c +DISTCLEANFILES += grub_script.yy.c grub_script.yy.h + bin_UTILITIES += grub-bin2h grub_bin2h_SOURCES = gnulib/progname.c util/bin2h.c diff --git a/conf/common.rmk b/conf/common.rmk index 2ea8ebd5a..52491d530 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -91,13 +91,21 @@ grub_mkrelpath_SOURCES = gnulib/progname.c util/grub-mkrelpath.c util/misc.c bin_UTILITIES += grub-bin2h grub_bin2h_SOURCES = gnulib/progname.c util/bin2h.c +# For the lexer. +grub_script.yy.c grub_script.yy.h: script/yylex.l + $(LEX) -o grub_script.yy.c --header-file=grub_script.yy.h $(srcdir)/script/yylex.l + sed -i 's/^#include.*\(\|\|\|\|\)//g' grub_script.yy.h + sed -i 's/^#include.*\(\|\|\|\|\)//g' grub_script.yy.c +DISTCLEANFILES += grub_script.yy.c grub_script.yy.h + # For grub-script-check. bin_UTILITIES += grub-script-check util/grub-script-check.c_DEPENDENCIES = grub_script_check_init.h grub_script_check_SOURCES = gnulib/progname.c util/grub-script-check.c util/misc.c \ script/main.c script/script.c script/function.c script/lexer.c \ kern/handler.c kern/err.c kern/parser.c kern/list.c \ - kern/misc.c kern/env.c grub_script_check_init.c grub_script.tab.c + kern/misc.c kern/env.c grub_script_check_init.c grub_script.tab.c \ + grub_script.yy.c # For the parser. grub_script.tab.c grub_script.tab.h: script/parser.y @@ -594,7 +602,7 @@ normal_mod_LDFLAGS = $(COMMON_LDFLAGS) # For sh.mod. sh_mod_SOURCES = script/main.c script/script.c script/execute.c \ - script/function.c script/lexer.c grub_script.tab.c + script/function.c script/lexer.c grub_script.tab.c grub_script.yy.c sh_mod_CFLAGS = $(COMMON_CFLAGS) sh_mod_LDFLAGS = $(COMMON_LDFLAGS) diff --git a/conf/i386-coreboot.rmk b/conf/i386-coreboot.rmk index 9563c0b2b..c9703d082 100644 --- a/conf/i386-coreboot.rmk +++ b/conf/i386-coreboot.rmk @@ -5,7 +5,7 @@ COMMON_CFLAGS = -fno-builtin -mrtd -mregparm=3 -m32 COMMON_LDFLAGS = -m32 -nostdlib # Used by various components. These rules need to precede them. -script/lexer.c_DEPENDENCIES = grub_script.tab.h +script/lexer.c_DEPENDENCIES = grub_script.tab.h grub_script.yy.h # Images. diff --git a/conf/i386-efi.rmk b/conf/i386-efi.rmk index c03abb429..4314c15eb 100644 --- a/conf/i386-efi.rmk +++ b/conf/i386-efi.rmk @@ -5,7 +5,7 @@ COMMON_CFLAGS = -fno-builtin -m32 COMMON_LDFLAGS = -melf_i386 -nostdlib # Used by various components. These rules need to precede them. -script/lexer.c_DEPENDENCIES = grub_script.tab.h +script/lexer.c_DEPENDENCIES = grub_script.tab.h grub_script.yy.h # Utilities. bin_UTILITIES = grub-mkimage diff --git a/conf/i386-ieee1275.rmk b/conf/i386-ieee1275.rmk index e19f6e9a1..7c6520323 100644 --- a/conf/i386-ieee1275.rmk +++ b/conf/i386-ieee1275.rmk @@ -5,7 +5,7 @@ COMMON_CFLAGS = -ffreestanding -mrtd -mregparm=3 COMMON_LDFLAGS = -nostdlib # Used by various components. These rules need to precede them. -script/lexer.c_DEPENDENCIES = grub_script.tab.h +script/lexer.c_DEPENDENCIES = grub_script.tab.h grub_script.yy.h # Images. pkglib_PROGRAMS = kernel.img diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk index 580bfea0a..9cae817ff 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -7,7 +7,7 @@ COMMON_CFLAGS = -fno-builtin -mrtd -mregparm=3 -m32 COMMON_LDFLAGS = -m32 -nostdlib # Used by various components. These rules need to precede them. -script/lexer.c_DEPENDENCIES = grub_script.tab.h +script/lexer.c_DEPENDENCIES = grub_script.tab.h grub_script.yy.h # Images. pkglib_IMAGES = boot.img cdboot.img diskboot.img kernel.img lnxboot.img \ diff --git a/conf/powerpc-ieee1275.rmk b/conf/powerpc-ieee1275.rmk index 23bd2d620..90afb0b8b 100644 --- a/conf/powerpc-ieee1275.rmk +++ b/conf/powerpc-ieee1275.rmk @@ -6,7 +6,7 @@ COMMON_CFLAGS = -ffreestanding COMMON_LDFLAGS += -nostdlib # Used by various components. These rules need to precede them. -script/lexer.c_DEPENDENCIES = grub_script.tab.h +script/lexer.c_DEPENDENCIES = grub_script.tab.h grub_script.yy.h # Images. diff --git a/conf/sparc64-ieee1275.rmk b/conf/sparc64-ieee1275.rmk index befc7dce5..946c1f06b 100644 --- a/conf/sparc64-ieee1275.rmk +++ b/conf/sparc64-ieee1275.rmk @@ -6,7 +6,7 @@ COMMON_CFLAGS = -ffreestanding -m64 -mno-app-regs COMMON_LDFLAGS = -melf64_sparc -nostdlib -mno-relax # Used by various components. These rules need to precede them. -script/lexer.c_DEPENDENCIES = grub_script.tab.h +script/lexer.c_DEPENDENCIES = grub_script.tab.h grub_script.yy.h # Images. pkglib_IMAGES = boot.img diskboot.img kernel.img diff --git a/conf/tests.rmk b/conf/tests.rmk index 18b23ff5a..c5080f58c 100644 --- a/conf/tests.rmk +++ b/conf/tests.rmk @@ -37,12 +37,28 @@ example_scripted_test_SOURCES = tests/example_scripted_test.in check_SCRIPTS += example_grub_script_test example_grub_script_test_SOURCES = tests/example_grub_script_test.in +# +# Rules for real tests +# + +check_SCRIPTS += grub_script_echo1 +grub_script_echo1_SOURCES = tests/grub_script_echo1.in + +check_SCRIPTS += grub_script_echo_keywords +grub_script_echo_keywords_SOURCES = tests/grub_script_echo_keywords.in + +check_SCRIPTS += grub_script_vars1 +grub_script_vars1_SOURCES = tests/grub_script_vars1.in # List of tests to execute on "make check" -SCRIPTED_TESTS = example_scripted_test -SCRIPTED_TESTS += example_grub_script_test -UNIT_TESTS = example_unit_test -FUNCTIONAL_TESTS = example_functional_test.mod +# SCRIPTED_TESTS = example_scripted_test +# SCRIPTED_TESTS += example_grub_script_test +# UNIT_TESTS = example_unit_test +# FUNCTIONAL_TESTS = example_functional_test.mod + +SCRIPTED_TESTS = grub_script_echo1 +SCRIPTED_TESTS += grub_script_echo_keywords +SCRIPTED_TESTS += grub_script_vars1 # dependencies between tests and testing-tools $(SCRIPTED_TESTS): grub-shell grub-shell-tester diff --git a/conf/x86_64-efi.rmk b/conf/x86_64-efi.rmk index d5c3c24cb..b46236ade 100644 --- a/conf/x86_64-efi.rmk +++ b/conf/x86_64-efi.rmk @@ -5,7 +5,7 @@ COMMON_CFLAGS = -fno-builtin -m64 COMMON_LDFLAGS = -melf_x86_64 -nostdlib # Used by various components. These rules need to precede them. -script/lexer.c_DEPENDENCIES = grub_script.tab.h +script/lexer.c_DEPENDENCIES = grub_script.tab.h grub_script.yy.h # Utilities. bin_UTILITIES = grub-mkimage diff --git a/configure.ac b/configure.ac index b1435de44..ea2218d9e 100644 --- a/configure.ac +++ b/configure.ac @@ -163,6 +163,11 @@ if test "x$CMP" = x; then AC_MSG_ERROR([cmp is not found]) fi +AC_CHECK_PROGS([LEX], [flex]) +if test "x$LEX" = x; then + AC_MSG_ERROR([flex is not found]) +fi + AC_CHECK_PROGS([YACC], [bison]) if test "x$YACC" = x; then AC_MSG_ERROR([bison is not found]) diff --git a/include/grub/script_sh.h b/include/grub/script_sh.h index 0bd14abcd..889017d2a 100644 --- a/include/grub/script_sh.h +++ b/include/grub/script_sh.h @@ -1,7 +1,7 @@ /* normal_parser.h */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2005,2007,2009 Free Software Foundation, Inc. + * Copyright (C) 2005,2007,2009,2010 Free Software Foundation, Inc. * * GRUB is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -45,8 +45,11 @@ struct grub_script typedef enum { - GRUB_SCRIPT_ARG_TYPE_STR, - GRUB_SCRIPT_ARG_TYPE_VAR + GRUB_SCRIPT_ARG_TYPE_VAR, + GRUB_SCRIPT_ARG_TYPE_TEXT, + GRUB_SCRIPT_ARG_TYPE_DQVAR, + GRUB_SCRIPT_ARG_TYPE_DQSTR, + GRUB_SCRIPT_ARG_TYPE_SQSTR } grub_script_arg_type_t; /* A part of an argument. */ @@ -121,12 +124,6 @@ struct grub_script_cmd_menuentry /* State of the lexer as passed to the lexer. */ struct grub_lexer_param { - /* Set to 0 when the lexer is done. */ - int done; - - /* State of the state machine. */ - grub_parser_state_t state; - /* Function used by the lexer to get a new line when more input is expected, but not available. */ grub_reader_getline_t getline; @@ -137,10 +134,6 @@ struct grub_lexer_param depleted. */ int refs; - /* The character stream that has to be parsed. */ - char *script; - char *newscript; /* XXX */ - /* While walking through the databuffer, `record' the characters to this other buffer. It can be used to edit the menu entry at a later moment. */ @@ -157,13 +150,32 @@ struct grub_lexer_param /* Size of RECORDING. */ int recordlen; - /* The token that is already parsed but not yet returned. */ - int tokenonhold; + /* End of file reached. */ + int eof; - /* Was the last token a newline? */ - int was_newline; + /* Merge multiple word tokens. */ + int merge_start; + int merge_end; + + /* Text of current token. */ + char *text; + + /* Type of text. */ + grub_script_arg_type_t type; + + /* Flex scanner. */ + void *yyscanner; + + /* Flex scanner buffer. */ + void *buffer; + + /* Length of current token text. */ + unsigned size; }; +#define GRUB_LEXER_TOKEN_MAX 256 +#define GRUB_LEXER_RECORD_INCREMENT 256 + /* State of the parser as passes to the parser. */ struct grub_parser_param { @@ -223,12 +235,16 @@ void grub_script_free (struct grub_script *script); struct grub_script *grub_script_create (struct grub_script_cmd *cmd, struct grub_script_mem *mem); -struct grub_lexer_param *grub_script_lexer_init (char *s, +struct grub_lexer_param *grub_script_lexer_init (struct grub_parser_param *parser, + char *script, grub_reader_getline_t getline); +void grub_script_lexer_fini (struct grub_lexer_param *); void grub_script_lexer_ref (struct grub_lexer_param *); void grub_script_lexer_deref (struct grub_lexer_param *); -void grub_script_lexer_record_start (struct grub_lexer_param *); -char *grub_script_lexer_record_stop (struct grub_lexer_param *); +void grub_script_lexer_record_start (struct grub_parser_param *); +char *grub_script_lexer_record_stop (struct grub_parser_param *); +int grub_script_lexer_yywrap (struct grub_parser_param *); +void grub_script_lexer_record (struct grub_parser_param *, char *); /* Functions to track allocated memory. */ struct grub_script_mem *grub_script_mem_record (struct grub_parser_param *state); @@ -284,7 +300,7 @@ int grub_script_function_iterate (int (*iterate) (grub_script_function_t)); int grub_script_function_call (grub_script_function_t func, int argc, char **args); -char * -grub_script_execute_argument_to_string (struct grub_script_arg *arg); +char ** +grub_script_execute_arglist_to_argv (struct grub_script_arglist *arglist); #endif /* ! GRUB_NORMAL_PARSER_HEADER */ diff --git a/script/execute.c b/script/execute.c index ee7e099bc..83b6649ce 100644 --- a/script/execute.c +++ b/script/execute.c @@ -1,7 +1,7 @@ /* execute.c -- Execute a GRUB script. */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2005,2007,2008,2009 Free Software Foundation, Inc. + * Copyright (C) 2005,2007,2008,2009,2010 Free Software Foundation, Inc. * * GRUB is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -35,49 +35,146 @@ grub_script_execute_cmd (struct grub_script_cmd *cmd) return cmd->exec (cmd); } -/* Parse ARG and return the textual representation. Add strings are - concatenated and all values of the variables are filled in. */ -char * -grub_script_execute_argument_to_string (struct grub_script_arg *arg) +#define ROUND_UPTO(sz,up) (((sz) + (up) - 1) / (up) * (up)) + +/* Expand arguments in ARGLIST into multiple arguments. */ +char ** +grub_script_execute_arglist_to_argv (struct grub_script_arglist *arglist) { - int size = 0; - char *val; - char *chararg; - struct grub_script_arg *argi; + int i; + int oom; + int argc; + int empty; + char *ptr; + char **argv; + char *value; + struct grub_script_arg *arg; - /* First determine the size of the argument. */ - for (argi = arg; argi; argi = argi->next) + auto void push (char *str); + void push (char *str) + { + char **p; + + if (oom) + return; + + p = grub_realloc (argv, ROUND_UPTO (sizeof(char*) * (argc + 1), 32)); + if (!p) + oom = 1; + else + { + p[argc++] = str; + argv = p; + } + } + + auto char* append (const char *str, grub_size_t nchar); + char* append (const char *str, grub_size_t nchar) + { + int len; + int old; + char *p; + + if (oom || !str) + return 0; + + len = nchar ?: grub_strlen (str); + old = argv[argc - 1] ? grub_strlen (argv[argc - 1]) : 0; + p = grub_realloc (argv[argc - 1], ROUND_UPTO(old + len + 1, 32)); + + if (p) + { + grub_strncpy (p + old, str, len); + p[old + len] = '\0'; + } + else + { + oom = 1; + grub_free (argv[argc - 1]); + } + argv[argc - 1] = p; + return argv[argc - 1]; + } + + /* Move *STR to the begining of next word, but return current word. */ + auto char* move_to_next (char **str); + char* move_to_next (char **str) + { + char *end; + char *start; + + if (oom || !str || !*str) + return 0; + + start = *str; + while (*start && grub_isspace (*start)) start++; + if (*start == '\0') + return 0; + + end = start + 1; + while (*end && !grub_isspace (*end)) end++; + + *str = end; + return start; + } + + oom = 0; + argv = 0; + argc = 0; + push (0); + for (; arglist; arglist = arglist->next) { - if (argi->type == 1) + empty = 1; + arg = arglist->arg; + while (arg) { - val = grub_env_get (argi->str); - if (val) - size += grub_strlen (val); + switch (arg->type) + { + case GRUB_SCRIPT_ARG_TYPE_VAR: + value = grub_env_get (arg->str); + while (*value && (ptr = move_to_next(&value))) + { + empty = 0; + append (ptr, value - ptr); + if (*value) push(0); + } + break; + + case GRUB_SCRIPT_ARG_TYPE_TEXT: + if (grub_strlen (arg->str) > 0) + { + empty = 0; + append (arg->str, 0); + } + break; + + case GRUB_SCRIPT_ARG_TYPE_DQSTR: + case GRUB_SCRIPT_ARG_TYPE_SQSTR: + empty = 0; + append (arg->str, 0); + break; + + case GRUB_SCRIPT_ARG_TYPE_DQVAR: + empty = 0; + append (grub_env_get (arg->str), 0); + break; + } + arg = arg->next; } - else - size += grub_strlen (argi->str); + if (!empty) + push (0); + } + push (0); /* Ensure argv[argc] == 0. */ + + if (oom) + { + for (i = 0; i < argc; i++) + grub_free (argv[i]); + grub_free (argv); + argv = 0; } - /* Create the argument. */ - chararg = grub_malloc (size + 1); - if (! chararg) - return 0; - - *chararg = '\0'; - /* First determine the size of the argument. */ - for (argi = arg; argi; argi = argi->next) - { - if (argi->type == 1) - { - val = grub_env_get (argi->str); - if (val) - grub_strcat (chararg, val); - } - else - grub_strcat (chararg, argi->str); - } - - return chararg; + return argv; } /* Execute a single command line. */ @@ -85,7 +182,6 @@ grub_err_t grub_script_execute_cmdline (struct grub_script_cmd *cmd) { struct grub_script_cmdline *cmdline = (struct grub_script_cmdline *) cmd; - struct grub_script_arglist *arglist; char **args = 0; int i = 0; grub_command_t grubcmd; @@ -96,7 +192,11 @@ grub_script_execute_cmdline (struct grub_script_cmd *cmd) char *cmdname; /* Lookup the command. */ - cmdname = grub_script_execute_argument_to_string (cmdline->arglist->arg); + args = grub_script_execute_arglist_to_argv (cmdline->arglist); + if (!args) + return grub_errno; + + cmdname = args[0]; grubcmd = grub_command_find (cmdname); if (! grubcmd) { @@ -129,27 +229,15 @@ grub_script_execute_cmdline (struct grub_script_cmd *cmd) return 0; } } - grub_free (cmdname); - if (cmdline->arglist->next) - { - argcount = cmdline->arglist->argcount - 1; - - /* Create argv from the arguments. */ - args = grub_malloc (sizeof (char *) * argcount); - for (arglist = cmdline->arglist->next; arglist; arglist = arglist->next) - { - char *str; - str = grub_script_execute_argument_to_string (arglist->arg); - args[i++] = str; - } - } + /* Count argv size. */ + for (argcount = 0; args[argcount]; argcount++); /* Execute the GRUB command or function. */ if (grubcmd) - ret = (grubcmd->func) (grubcmd, argcount, args); + ret = (grubcmd->func) (grubcmd, argcount - 1, args + 1); else - ret = grub_script_function_call (func, argcount, args); + ret = grub_script_function_call (func, argcount - 1, args + 1); /* Free arguments. */ for (i = 0; i < argcount; i++) @@ -202,7 +290,6 @@ grub_err_t grub_script_execute_menuentry (struct grub_script_cmd *cmd) { struct grub_script_cmd_menuentry *cmd_menuentry; - struct grub_script_arglist *arglist; char **args = 0; int argcount = 0; int i = 0; @@ -211,22 +298,11 @@ grub_script_execute_menuentry (struct grub_script_cmd *cmd) if (cmd_menuentry->arglist) { - argcount = cmd_menuentry->arglist->argcount; + args = grub_script_execute_arglist_to_argv (cmd_menuentry->arglist); + if (!args) + return grub_errno; - /* Create argv from the arguments. */ - args = grub_malloc (sizeof (char *) * argcount); - - if (! args) - { - return grub_errno; - } - - for (arglist = cmd_menuentry->arglist; arglist; arglist = arglist->next) - { - char *str; - str = grub_script_execute_argument_to_string (arglist->arg); - args[i++] = str; - } + for (argcount = 0; args[argcount]; argcount++); } grub_normal_add_menu_entry (argcount, (const char **) args, diff --git a/script/function.c b/script/function.c index a3950a8a0..ded470c4e 100644 --- a/script/function.c +++ b/script/function.c @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2005,2007,2009 Free Software Foundation, Inc. + * Copyright (C) 2005,2007,2009,2010 Free Software Foundation, Inc. * * GRUB is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -34,7 +34,7 @@ grub_script_function_create (struct grub_script_arg *functionname_arg, if (! func) return 0; - func->name = grub_script_execute_argument_to_string (functionname_arg); + func->name = grub_strdup (functionname_arg->str); if (! func->name) { grub_free (func); diff --git a/script/lexer.c b/script/lexer.c index 5bcdf628b..d43c9f157 100644 --- a/script/lexer.c +++ b/script/lexer.c @@ -1,7 +1,7 @@ /* lexer.c - The scripting lexer. */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2005,2006,2007,2008,2009 Free Software Foundation, Inc. + * Copyright (C) 2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc. * * GRUB is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -23,42 +23,7 @@ #include #include "grub_script.tab.h" - -static int -check_varstate (grub_parser_state_t state) -{ - return (state == GRUB_PARSER_STATE_VARNAME - || state == GRUB_PARSER_STATE_VAR - || state == GRUB_PARSER_STATE_QVAR - || state == GRUB_PARSER_STATE_VARNAME2 - || state == GRUB_PARSER_STATE_QVARNAME - || state == GRUB_PARSER_STATE_QVARNAME2); -} - -static int -check_textstate (grub_parser_state_t state) -{ - return (state == GRUB_PARSER_STATE_TEXT - || state == GRUB_PARSER_STATE_ESC - || state == GRUB_PARSER_STATE_QUOTE - || state == GRUB_PARSER_STATE_DQUOTE); -} - -struct grub_lexer_param * -grub_script_lexer_init (char *script, grub_reader_getline_t getline) -{ - struct grub_lexer_param *param; - - param = grub_zalloc (sizeof (*param)); - if (! param) - return 0; - - param->state = GRUB_PARSER_STATE_TEXT; - param->getline = getline; - param->script = script; - - return param; -} +#include "grub_script.yy.h" void grub_script_lexer_ref (struct grub_lexer_param *state) @@ -74,360 +39,305 @@ grub_script_lexer_deref (struct grub_lexer_param *state) /* Start recording all characters passing through the lexer. */ void -grub_script_lexer_record_start (struct grub_lexer_param *state) +grub_script_lexer_record_start (struct grub_parser_param *parser) { - state->record = 1; - state->recordlen = 100; - state->recording = grub_malloc (state->recordlen); - state->recordpos = 0; + struct grub_lexer_param *lexer = parser->lexerstate; + + lexer->record = 1; + lexer->recordpos = 0; + if (lexer->recording) /* reuse last record */ + return; + + lexer->recordlen = GRUB_LEXER_RECORD_INCREMENT; + lexer->recording = grub_malloc (lexer->recordlen); + + if (!lexer->recording) + { + grub_script_yyerror (parser, 0); + lexer->record = 0; + lexer->recordlen = 0; + } } char * -grub_script_lexer_record_stop (struct grub_lexer_param *state) +grub_script_lexer_record_stop (struct grub_parser_param *parser) { - state->record = 0; + char *ptr; + char *result; + struct grub_lexer_param *lexer = parser->lexerstate; - /* Delete the last character, it is a `}'. */ - if (state->recordpos > 0) - { - if (state->recording[--state->recordpos] != '}') - { - grub_printf ("Internal error while parsing menu entry"); - for (;;); /* XXX */ - } - state->recording[state->recordpos] = '\0'; - } + auto char *compact (char *start, char *end); + char *compact (char *start, char *end) + { + /* Delete '{' and '}' characters and whitespaces. */ + while (*start && grub_isspace (*start)) start++; + if (*start == '{') start++; + while (*start && grub_isspace (*start)) start++; - return state->recording; + while (*end && grub_isspace (*end)) end--; + if (*end == '}') end--; + while (*end && grub_isspace (*end)) end--; + *end = '\0'; + + return start; + } + + if (!lexer->record || !lexer->recording) + return 0; + + /* XXX This is not necessary in BASH. */ + + ptr = compact (lexer->recording, lexer->recording + lexer->recordpos - 1); + lexer->record = 0; + lexer->recordpos = 0; + + /* This memory would be freed by, grub_script_free. */ + result = grub_script_malloc (parser, grub_strlen (ptr) + 1); + if (result) + grub_strcpy (result, ptr); + + return result; } -/* When recording is enabled, record the character C as the next item - in the character stream. */ -static void -recordchar (struct grub_lexer_param *state, char c) + +/* Record STR if input recording is enabled. */ +void +grub_script_lexer_record (struct grub_parser_param *parser, char *str) { - if (state->recordpos == state->recordlen) + int len; + struct grub_lexer_param *lexer = parser->lexerstate; + + if (!lexer->record) + return; + + len = grub_strlen (str); + if (lexer->recordpos + len >= lexer->recordlen - 1) { - char *old = state->recording; - state->recordlen += 100; - state->recording = grub_realloc (state->recording, state->recordlen); - if (! state->recording) + char *old = lexer->recording; + lexer->recordlen += GRUB_LEXER_RECORD_INCREMENT; + lexer->recording = grub_realloc (lexer->recording, lexer->recordlen); + if (!lexer->recording) { grub_free (old); - state->record = 0; + lexer->record = 0; + grub_script_yyerror (parser, 0); + return; } } - state->recording[state->recordpos++] = c; + grub_strcpy (lexer->recording + lexer->recordpos, str); + lexer->recordpos += len; } -/* Fetch the next character for the lexer. */ -static void -nextchar (struct grub_lexer_param *state) +/* Append '\n' to SRC, before '\0' */ +static char * +append_newline (const char *src) { - if (state->record) - recordchar (state, *state->script); - state->script++; + char *line; + grub_size_t len; + + len = grub_strlen (src); + line = grub_malloc (len + 1); + if (!line) + return 0; + + grub_strcpy (line, src); + + line[len] = '\n'; + line[len + 1] = '\0'; + return line; } +/* Read next line of input if necessary, and set yyscanner buffers. */ int -grub_script_yylex (union YYSTYPE *yylval, struct grub_parser_param *parsestate) +grub_script_lexer_yywrap (struct grub_parser_param *parserstate) { - grub_parser_state_t newstate; - char use; - struct grub_lexer_param *state = parsestate->lexerstate; - int firstrun = 1; + int len; + char *line; + char *line2; + YY_BUFFER_STATE buffer; + struct grub_lexer_param *lexerstate = parserstate->lexerstate; - yylval->arg = 0; + if (!lexerstate->refs) + return 0; - if (state->tokenonhold) + if (!lexerstate->getline) { - int token = state->tokenonhold; - state->tokenonhold = 0; - return token; + grub_script_yyerror (parserstate, "unexpected end of file"); + return 0; } - for (;! state->done; firstrun = 0) + line = 0; + buffer = 0; + lexerstate->getline (&line, 1); + if (!line) { - if (! state->script || ! *state->script) + grub_script_yyerror (parserstate, 0); /* XXX this could be for ^C case? */ + return 0; + } + + len = grub_strlen (line); + if (line[len - 1] == '\n') + { + buffer = yy_scan_string (line, lexerstate->yyscanner); + } + else + { + line2 = append_newline (line); + if (line2) { - /* Check if more tokens are requested by the parser. */ - if (((state->refs && ! parsestate->err) - || state->state == GRUB_PARSER_STATE_ESC - || state->state == GRUB_PARSER_STATE_QUOTE - || state->state == GRUB_PARSER_STATE_DQUOTE) - && state->getline) - { - int doexit = 0; - if (state->state != GRUB_PARSER_STATE_ESC - && state->state != GRUB_PARSER_STATE_QUOTE - && state->state != GRUB_PARSER_STATE_DQUOTE - && ! state->was_newline) - { - state->was_newline = 1; - state->tokenonhold = '\n'; - break; - } - while (! state->script || ! *state->script) - { - grub_free (state->newscript); - state->newscript = 0; - state->getline (&state->newscript, 1); - state->script = state->newscript; - if (! state->script) - { - doexit = 1; - break; - } - } - if (doexit) - break; - grub_dprintf ("scripting", "token=`\\n'\n"); - recordchar (state, '\n'); - if (state->state == GRUB_PARSER_STATE_VARNAME) - state->state = GRUB_PARSER_STATE_TEXT; - if (state->state == GRUB_PARSER_STATE_QVARNAME) - state->state = GRUB_PARSER_STATE_DQUOTE; - if (state->state == GRUB_PARSER_STATE_DQUOTE - || state->state == GRUB_PARSER_STATE_QUOTE) - yylval->arg = grub_script_arg_add (parsestate, yylval->arg, - GRUB_SCRIPT_ARG_TYPE_STR, - "\n"); - } - else - { - grub_free (state->newscript); - state->newscript = 0; - state->done = 1; - grub_dprintf ("scripting", "token=`\\n'\n"); - state->tokenonhold = '\n'; - break; - } - } - state->was_newline = 0; - - newstate = grub_parser_cmdline_state (state->state, *state->script, &use); - - /* Check if it is a text. */ - if (check_textstate (newstate)) - { - char *buffer = NULL; - int bufpos = 0; - /* Buffer is initially large enough to hold most commands - but extends automatically when needed. */ - int bufsize = 128; - - buffer = grub_malloc (bufsize); - - /* In case the string is not quoted, this can be a one char - length symbol. */ - if (newstate == GRUB_PARSER_STATE_TEXT) - { - int doexit = 0; - switch (*state->script) - { - case ' ': - while (*state->script) - { - newstate = grub_parser_cmdline_state (state->state, - *state->script, &use); - if (! (state->state == GRUB_PARSER_STATE_TEXT - && *state->script == ' ')) - { - grub_dprintf ("scripting", "token=` '\n"); - if (! firstrun) - doexit = 1; - break; - } - state->state = newstate; - nextchar (state); - } - grub_dprintf ("scripting", "token=` '\n"); - if (! firstrun) - doexit = 1; - break; - case '{': - case '}': - case ';': - case '\n': - { - char c; - grub_dprintf ("scripting", "token=`%c'\n", *state->script); - c = *state->script; - nextchar (state); - state->tokenonhold = c; - doexit = 1; - break; - } - } - if (doexit) - { - grub_free (buffer); - break; - } - } - - /* Read one token, possible quoted. */ - while (*state->script) - { - newstate = grub_parser_cmdline_state (state->state, - *state->script, &use); - - /* Check if a variable name starts. */ - if (check_varstate (newstate)) - break; - - /* If the string is not quoted or escaped, stop processing - when a special token was found. It will be recognized - next time when this function is called. */ - if (newstate == GRUB_PARSER_STATE_TEXT - && state->state != GRUB_PARSER_STATE_ESC - && state->state != GRUB_PARSER_STATE_QUOTE - && state->state != GRUB_PARSER_STATE_DQUOTE) - { - int breakout = 0; - - switch (use) - { - case ' ': - case '{': - case '}': - case ';': - case '\n': - breakout = 1; - } - if (breakout) - break; - } - - if (use) - { - if (bufsize <= bufpos + 1) - { - bufsize <<= 1; - buffer = grub_realloc (buffer, bufsize); - } - buffer[bufpos++] = use; - } - - state->state = newstate; - nextchar (state); - } - - /* A string of text was read in. */ - if (bufsize <= bufpos + 1) - { - bufsize <<= 1; - buffer = grub_realloc (buffer, bufsize); - } - - buffer[bufpos++] = 0; - - grub_dprintf ("scripting", "token=`%s'\n", buffer); - yylval->arg = grub_script_arg_add (parsestate, yylval->arg, - GRUB_SCRIPT_ARG_TYPE_STR, buffer); - - grub_free (buffer); - } - else if (newstate == GRUB_PARSER_STATE_VAR - || newstate == GRUB_PARSER_STATE_QVAR) - { - char *buffer = NULL; - int bufpos = 0; - /* Buffer is initially large enough to hold most commands - but extends automatically when needed. */ - int bufsize = 128; - - buffer = grub_malloc (bufsize); - - /* This is a variable, read the variable name. */ - while (*state->script) - { - newstate = grub_parser_cmdline_state (state->state, - *state->script, &use); - - /* Check if this character is not part of the variable name - anymore. */ - if (! (check_varstate (newstate))) - { - if (state->state == GRUB_PARSER_STATE_VARNAME2 - || state->state == GRUB_PARSER_STATE_QVARNAME2) - nextchar (state); - state->state = newstate; - break; - } - - if (use) - { - if (bufsize <= bufpos + 1) - { - bufsize <<= 1; - buffer = grub_realloc (buffer, bufsize); - } - buffer[bufpos++] = use; - } - - nextchar (state); - state->state = newstate; - } - - if (bufsize <= bufpos + 1) - { - bufsize <<= 1; - buffer = grub_realloc (buffer, bufsize); - } - - buffer[bufpos++] = 0; - - state->state = newstate; - yylval->arg = grub_script_arg_add (parsestate, yylval->arg, - GRUB_SCRIPT_ARG_TYPE_VAR, buffer); - grub_dprintf ("scripting", "vartoken=`%s'\n", buffer); - - grub_free (buffer); - } - else - { - /* There is either text or a variable name. In the case you - arrive here there is a serious problem with the lexer. */ - grub_error (GRUB_ERR_BAD_ARGUMENT, "internal error"); - return 0; + buffer = yy_scan_string (line2, lexerstate->yyscanner); + grub_free (line2); } } - if (yylval->arg == 0) + grub_free (line); + if (!buffer) { - int token = state->tokenonhold; - state->tokenonhold = 0; - return token; + grub_script_yyerror (parserstate, 0); + return 0; } - if (yylval->arg->next == 0 && yylval->arg->type == GRUB_SCRIPT_ARG_TYPE_STR) + return 1; +} + +struct grub_lexer_param * +grub_script_lexer_init (struct grub_parser_param *parser, char *script, + grub_reader_getline_t getline) +{ + int len; + char *script2; + YY_BUFFER_STATE buffer; + struct grub_lexer_param *lexerstate; + + lexerstate = grub_zalloc (sizeof (*lexerstate)); + if (!lexerstate) + return 0; + + lexerstate->text = grub_malloc (GRUB_LEXER_TOKEN_MAX); + if (!lexerstate->text) { - /* Detect some special tokens. */ - if (! grub_strcmp (yylval->arg->str, "while")) - return GRUB_PARSER_TOKEN_WHILE; - else if (! grub_strcmp (yylval->arg->str, "if")) - return GRUB_PARSER_TOKEN_IF; - else if (! grub_strcmp (yylval->arg->str, "function")) - return GRUB_PARSER_TOKEN_FUNCTION; - else if (! grub_strcmp (yylval->arg->str, "menuentry")) - return GRUB_PARSER_TOKEN_MENUENTRY; - else if (! grub_strcmp (yylval->arg->str, "@")) - return GRUB_PARSER_TOKEN_MENUENTRY; - else if (! grub_strcmp (yylval->arg->str, "else")) - return GRUB_PARSER_TOKEN_ELSE; - else if (! grub_strcmp (yylval->arg->str, "then")) - return GRUB_PARSER_TOKEN_THEN; - else if (! grub_strcmp (yylval->arg->str, "fi")) - return GRUB_PARSER_TOKEN_FI; + grub_free (lexerstate); + return 0; } - return GRUB_PARSER_TOKEN_ARG; + lexerstate->getline = getline; /* rest are all zeros already */ + if (yylex_init (&lexerstate->yyscanner)) + { + grub_free (lexerstate->text); + grub_free (lexerstate); + return 0; + } + + buffer = 0; + script = script ? : "\n"; + len = grub_strlen (script); + + if (script[len - 1] == '\n') + { + buffer = yy_scan_string (script, lexerstate->yyscanner); + } + else + { + script2 = append_newline (script); + if (script2) + { + buffer = yy_scan_string (script2, lexerstate->yyscanner); + grub_free (script2); + } + } + + if (!buffer) + { + yylex_destroy (lexerstate->yyscanner); + grub_free (lexerstate->yyscanner); + + grub_free (lexerstate->text); + grub_free (lexerstate); + return 0; + } + yyset_extra (parser, lexerstate->yyscanner); + + return lexerstate; } void -grub_script_yyerror (struct grub_parser_param *lex __attribute__ ((unused)), - char const *err) +grub_script_lexer_fini (struct grub_lexer_param *lexerstate) { - grub_printf ("%s\n", err); + if (!lexerstate) + return; + + yylex_destroy (lexerstate->yyscanner); + + grub_free (lexerstate->recording); + grub_free (lexerstate->text); + grub_free (lexerstate); +} + +int +grub_script_yylex (union YYSTYPE *value, + struct grub_parser_param *parserstate) +{ + char *str; + int token; + grub_script_arg_type_t type; + struct grub_lexer_param *lexerstate = parserstate->lexerstate; + + value->arg = 0; + if (parserstate->err) + return GRUB_PARSER_TOKEN_BAD; + + if (lexerstate->eof) + return GRUB_PARSER_TOKEN_EOF; + + /* + * Words with environment variables, like foo${bar}baz needs + * multiple tokens to be merged into a single grub_script_arg. We + * use two variables to achieve this: lexerstate->merge_start and + * lexerstate->merge_end + */ + + lexerstate->merge_start = 0; + lexerstate->merge_end = 0; + do + { + /* Empty lexerstate->text. */ + lexerstate->size = 0; + lexerstate->text[0] = '\0'; + + token = yylex (value, lexerstate->yyscanner); + if (token == GRUB_PARSER_TOKEN_BAD) + break; + + /* Merging feature uses lexerstate->text instead of yytext. */ + if (lexerstate->merge_start) + { + lexerstate->text[lexerstate->size] = '\0'; + str = lexerstate->text; + type = lexerstate->type; + } + else + { + str = yyget_text (lexerstate->yyscanner); + type = GRUB_SCRIPT_ARG_TYPE_TEXT; + } + /* grub_printf ("tok %u, txt [%s] size %u\n", token, str, lexerstate->size); */ + + value->arg = grub_script_arg_add (parserstate, value->arg, type, str); + } + while (lexerstate->merge_start && !lexerstate->merge_end); + + if (!value->arg || parserstate->err) + return GRUB_PARSER_TOKEN_BAD; + + return token; +} + +void +grub_script_yyerror (struct grub_parser_param *state, char const *err) +{ + if (err) + grub_error (GRUB_ERR_INVALID_COMMAND, err); + + grub_print_error (); + state->err++; } diff --git a/script/parser.y b/script/parser.y index 094a8856e..6d1b5bdbc 100644 --- a/script/parser.y +++ b/script/parser.y @@ -1,7 +1,7 @@ /* parser.y - The scripting parser. */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2005,2006,2007,2008,2009 Free Software Foundation, Inc. + * Copyright (C) 2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc. * * GRUB is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,10 +21,10 @@ #include #include -#define YYFREE grub_free -#define YYMALLOC grub_malloc +#define YYFREE grub_free +#define YYMALLOC grub_malloc #define YYLTYPE_IS_TRIVIAL 0 -#define YYENABLE_NLS 0 +#define YYENABLE_NLS 0 %} @@ -35,163 +35,208 @@ char *string; } -%token GRUB_PARSER_TOKEN_IF "if" -%token GRUB_PARSER_TOKEN_WHILE "while" -%token GRUB_PARSER_TOKEN_FUNCTION "function" -%token GRUB_PARSER_TOKEN_MENUENTRY "menuentry" -%token GRUB_PARSER_TOKEN_ELSE "else" -%token GRUB_PARSER_TOKEN_THEN "then" -%token GRUB_PARSER_TOKEN_FI "fi" -%token GRUB_PARSER_TOKEN_ARG -%type script_init script grubcmd command commands commandblock menuentry if -%type arguments; -%type GRUB_PARSER_TOKEN_ARG; +%token GRUB_PARSER_TOKEN_BAD +%token GRUB_PARSER_TOKEN_EOF 0 "end-of-input" + +%token GRUB_PARSER_TOKEN_NEWLINE "\n" +%token GRUB_PARSER_TOKEN_AND "&&" +%token GRUB_PARSER_TOKEN_OR "||" +%token GRUB_PARSER_TOKEN_SEMI2 ";;" +%token GRUB_PARSER_TOKEN_PIPE "|" +%token GRUB_PARSER_TOKEN_AMP "&" +%token GRUB_PARSER_TOKEN_SEMI ";" +%token GRUB_PARSER_TOKEN_LPAR "(" +%token GRUB_PARSER_TOKEN_RPAR ")" +%token GRUB_PARSER_TOKEN_LBR "{" +%token GRUB_PARSER_TOKEN_RBR "}" +%token GRUB_PARSER_TOKEN_NOT "!" +%token GRUB_PARSER_TOKEN_LSQBR2 "[" +%token GRUB_PARSER_TOKEN_RSQBR2 "]" +%token GRUB_PARSER_TOKEN_LT "<" +%token GRUB_PARSER_TOKEN_GT ">" + +%token GRUB_PARSER_TOKEN_CASE "case" +%token GRUB_PARSER_TOKEN_DO "do" +%token GRUB_PARSER_TOKEN_DONE "done" +%token GRUB_PARSER_TOKEN_ELIF "elif" +%token GRUB_PARSER_TOKEN_ELSE "else" +%token GRUB_PARSER_TOKEN_ESAC "esac" +%token GRUB_PARSER_TOKEN_FI "fi" +%token GRUB_PARSER_TOKEN_FOR "for" +%token GRUB_PARSER_TOKEN_IF "if" +%token GRUB_PARSER_TOKEN_IN "in" +%token GRUB_PARSER_TOKEN_SELECT "select" +%token GRUB_PARSER_TOKEN_THEN "then" +%token GRUB_PARSER_TOKEN_UNTIL "until" +%token GRUB_PARSER_TOKEN_WHILE "while" +%token GRUB_PARSER_TOKEN_TIME "time" +%token GRUB_PARSER_TOKEN_FUNCTION "function" +%token GRUB_PARSER_TOKEN_MENUENTRY "menuentry" +%token GRUB_PARSER_TOKEN_NAME "name" +%token GRUB_PARSER_TOKEN_WORD "word" + +%type word argument arguments0 arguments1 +%type script_init script grubcmd ifcmd command +%type commands1 menuentry statement %pure-parser -%lex-param { struct grub_parser_param *state }; +%error-verbose + +%lex-param { struct grub_parser_param *state }; %parse-param { struct grub_parser_param *state }; +%start script_init + %% /* It should be possible to do this in a clean way... */ -script_init: { state->err = 0; } script - { - state->parsed = $2; - } +script_init: { state->err = 0; } script { state->parsed = $2; state->err = 0; } ; -script: { $$ = 0; } - | '\n' { $$ = 0; } - | commands { $$ = $1; } - | function '\n' { $$ = 0; } - | menuentry '\n' { $$ = $1; } - | error - { - $$ = 0; - yyerror (state, "Incorrect command"); - state->err = 1; - yyerrok; - } +script: newlines0 + { + $$ = 0; + } + | script statement delimiter + { + struct grub_script_cmdblock *cmdblock; + cmdblock = (struct grub_script_cmdblock *) $1; + $$ = grub_script_add_cmd (state, cmdblock, $2); + } + | error + { + $$ = 0; + yyerror (state, "Incorrect command"); + yyerrok; + } ; -delimiter: '\n' - | ';' - | delimiter '\n' +newlines0: /* Empty */ | newlines1 ; +newlines1: newlines0 "\n" ; + +delimiter: ";" + | "\n" +; +delimiters0: /* Empty */ | delimiters1 ; +delimiters1: delimiter + | delimiters1 "\n" ; -newlines: /* Empty */ - | newlines '\n' +word: GRUB_PARSER_TOKEN_NAME { $$ = grub_script_add_arglist (state, 0, $1); } + | GRUB_PARSER_TOKEN_WORD { $$ = grub_script_add_arglist (state, 0, $1); } ; +statement: command { $$ = $1; } + | function { $$ = 0; } + | menuentry { $$ = $1; } - -arguments: GRUB_PARSER_TOKEN_ARG - { - $$ = grub_script_add_arglist (state, 0, $1); - } - | arguments GRUB_PARSER_TOKEN_ARG - { - $$ = grub_script_add_arglist (state, $1, $2); - } +argument : "case" { $$ = grub_script_add_arglist (state, 0, $1); } + | "do" { $$ = grub_script_add_arglist (state, 0, $1); } + | "done" { $$ = grub_script_add_arglist (state, 0, $1); } + | "elif" { $$ = grub_script_add_arglist (state, 0, $1); } + | "else" { $$ = grub_script_add_arglist (state, 0, $1); } + | "esac" { $$ = grub_script_add_arglist (state, 0, $1); } + | "fi" { $$ = grub_script_add_arglist (state, 0, $1); } + | "for" { $$ = grub_script_add_arglist (state, 0, $1); } + | "if" { $$ = grub_script_add_arglist (state, 0, $1); } + | "in" { $$ = grub_script_add_arglist (state, 0, $1); } + | "select" { $$ = grub_script_add_arglist (state, 0, $1); } + | "then" { $$ = grub_script_add_arglist (state, 0, $1); } + | "until" { $$ = grub_script_add_arglist (state, 0, $1); } + | "while" { $$ = grub_script_add_arglist (state, 0, $1); } + | "function" { $$ = grub_script_add_arglist (state, 0, $1); } + | "menuentry" { $$ = grub_script_add_arglist (state, 0, $1); } + | word { $$ = $1; } ; -grubcmd: arguments - { - $$ = grub_script_create_cmdline (state, $1); - } +arguments0: /* Empty */ { $$ = 0; } + | arguments1 { $$ = $1; } +; +arguments1: argument arguments0 + { + if ($1 && $2) + { + $1->next = $2; + $1->argcount += $2->argcount; + $2->argcount = 0; + } + $$ = $1; + } +; + +grubcmd: word arguments0 + { + if ($1 && $2) { + $1->next = $2; + $1->argcount += $2->argcount; + $2->argcount = 0; + } + $$ = grub_script_create_cmdline (state, $1); + } ; /* A single command. */ -command: grubcmd delimiter { $$ = $1; } - | if delimiter { $$ = $1; } - | commandblock delimiter { $$ = $1; } +command: grubcmd { $$ = $1; } + | ifcmd { $$ = $1; } ; -/* A block of commands. */ -commands: command - { - $$ = grub_script_add_cmd (state, 0, $1); - } - | command commands - { - struct grub_script_cmdblock *cmd; - cmd = (struct grub_script_cmdblock *) $2; - $$ = grub_script_add_cmd (state, cmd, $1); - } +/* A list of commands. */ +commands1: newlines0 command + { + $$ = grub_script_add_cmd (state, 0, $2); + } + | commands1 delimiters1 command + { + struct grub_script_cmdblock *cmdblock; + cmdblock = (struct grub_script_cmdblock *) $1; + $$ = grub_script_add_cmd (state, cmdblock, $3); + } ; -/* A function. Carefully save the memory that is allocated. Don't - change any stuff because it might seem like a fun thing to do! - Special care was take to make sure the mid-rule actions are - executed on the right moment. So the `commands' rule should be - recognized after executing the `grub_script_mem_record; and before - `grub_script_mem_record_stop'. */ -function: "function" GRUB_PARSER_TOKEN_ARG - { - grub_script_lexer_ref (state->lexerstate); - } newlines '{' - { - /* The first part of the function was recognized. - Now start recording the memory usage to store - this function. */ - state->func_mem = grub_script_mem_record (state); - } newlines commands '}' - { - struct grub_script *script; +function: "function" "name" + { + grub_script_lexer_ref (state->lexerstate); + state->func_mem = grub_script_mem_record (state); + } + delimiters0 "{" commands1 delimiters1 "}" + { + struct grub_script *script; + state->func_mem = grub_script_mem_record_stop (state, + state->func_mem); + script = grub_script_create ($6, state->func_mem); + if (script) + grub_script_function_create ($2, script); - /* All the memory usage for parsing this function - was recorded. */ - state->func_mem = grub_script_mem_record_stop (state, - state->func_mem); - script = grub_script_create ($8, state->func_mem); - if (script) - grub_script_function_create ($2, script); - grub_script_lexer_deref (state->lexerstate); - } + grub_script_lexer_deref (state->lexerstate); + } ; -/* Carefully designed, together with `menuentry' so everything happens - just in the expected order. */ -commandblock: '{' - { - grub_script_lexer_ref (state->lexerstate); - } - newlines commands '}' - { - grub_script_lexer_deref (state->lexerstate); - $$ = $4; - } +menuentry: "menuentry" + { + grub_script_lexer_ref (state->lexerstate); + } + arguments1 + { + grub_script_lexer_record_start (state); + } + delimiters0 "{" commands1 delimiters1 "}" + { + char *menu_entry; + menu_entry = grub_script_lexer_record_stop (state); + grub_script_lexer_deref (state->lexerstate); + $$ = grub_script_create_cmdmenu (state, $3, menu_entry, 0); + } ; -/* A menu entry. Carefully save the memory that is allocated. */ -menuentry: "menuentry" - { - grub_script_lexer_ref (state->lexerstate); - } arguments newlines '{' - { - grub_script_lexer_record_start (state->lexerstate); - } newlines commands '}' - { - char *menu_entry; - menu_entry = grub_script_lexer_record_stop (state->lexerstate); - grub_script_lexer_deref (state->lexerstate); - $$ = grub_script_create_cmdmenu (state, $3, menu_entry, 0); - } +if: "if" { grub_script_lexer_ref (state->lexerstate); } ; - -/* The first part of the if statement. It's used to switch the lexer - to a state in which it demands more tokens. */ -if_statement: "if" { grub_script_lexer_ref (state->lexerstate); } -; - -/* The if statement. */ -if: if_statement commands "then" newlines commands "fi" - { - $$ = grub_script_create_cmdif (state, $2, $5, 0); - grub_script_lexer_deref (state->lexerstate); - } - | if_statement commands "then" newlines commands "else" newlines commands "fi" - { - $$ = grub_script_create_cmdif (state, $2, $5, $8); - grub_script_lexer_deref (state->lexerstate); - } +ifcmd: if commands1 delimiters1 "then" commands1 delimiters1 "fi" + { + $$ = grub_script_create_cmdif (state, $2, $5, 0); + grub_script_lexer_deref (state->lexerstate); + } + | if commands1 delimiters1 "then" commands1 delimiters1 "else" commands1 delimiters1 "fi" + { + $$ = grub_script_create_cmdif (state, $2, $5, $8); + grub_script_lexer_deref (state->lexerstate); + } ; diff --git a/script/script.c b/script/script.c index c04a44966..b2d870745 100644 --- a/script/script.c +++ b/script/script.c @@ -1,7 +1,7 @@ /* script.c -- Functions to create an in memory description of the script. */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2005,2006,2007,2009 Free Software Foundation, Inc. + * Copyright (C) 2005,2006,2007,2009,2010 Free Software Foundation, Inc. * * GRUB is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -24,12 +24,10 @@ /* It is not possible to deallocate the memory when a syntax error was found. Because of that it is required to keep track of all memory - allocations. The memory is freed in case of an error, or - assigned to the parsed script when parsing was successful. */ + allocations. The memory is freed in case of an error, or assigned + to the parsed script when parsing was successful. -/* XXX */ - -/* In case of the normal malloc, some additional bytes are allocated + In case of the normal malloc, some additional bytes are allocated for this datastructure. All reserved memory is stored in a linked list so it can be easily freed. The original memory can be found from &mem. */ @@ -46,6 +44,8 @@ grub_script_malloc (struct grub_parser_param *state, grub_size_t size) struct grub_script_mem *mem; mem = (struct grub_script_mem *) grub_malloc (size + sizeof (*mem) - sizeof (char)); + if (!mem) + return 0; grub_dprintf ("scripting", "malloc %p\n", mem); mem->next = state->memused; @@ -94,32 +94,40 @@ grub_script_mem_record_stop (struct grub_parser_param *state, void grub_script_free (struct grub_script *script) { - if (! script) + if (!script) return; grub_script_mem_free (script->mem); grub_free (script); } - + /* Extend the argument arg with a variable or string of text. If ARG is zero a new list is created. */ struct grub_script_arg * -grub_script_arg_add (struct grub_parser_param *state, struct grub_script_arg *arg, - grub_script_arg_type_t type, char *str) +grub_script_arg_add (struct grub_parser_param *state, + struct grub_script_arg *arg, grub_script_arg_type_t type, + char *str) { struct grub_script_arg *argpart; struct grub_script_arg *ll; int len; - argpart = (struct grub_script_arg *) grub_script_malloc (state, sizeof (*arg)); + argpart = + (struct grub_script_arg *) grub_script_malloc (state, sizeof (*arg)); + if (!argpart) + return arg; + argpart->type = type; len = grub_strlen (str) + 1; argpart->str = grub_script_malloc (state, len); + if (!argpart->str) + return arg; /* argpart is freed later, during grub_script_free. */ + grub_memcpy (argpart->str, str, len); argpart->next = 0; - if (! arg) + if (!arg) return argpart; for (ll = arg; ll->next; ll = ll->next); @@ -132,19 +140,24 @@ grub_script_arg_add (struct grub_parser_param *state, struct grub_script_arg *ar is zero, a new list will be created. */ struct grub_script_arglist * grub_script_add_arglist (struct grub_parser_param *state, - struct grub_script_arglist *list, struct grub_script_arg *arg) + struct grub_script_arglist *list, + struct grub_script_arg *arg) { struct grub_script_arglist *link; struct grub_script_arglist *ll; grub_dprintf ("scripting", "arglist\n"); - link = (struct grub_script_arglist *) grub_script_malloc (state, sizeof (*link)); + link = + (struct grub_script_arglist *) grub_script_malloc (state, sizeof (*link)); + if (!link) + return list; + link->next = 0; link->arg = arg; link->argcount = 0; - if (! list) + if (!list) { link->argcount++; return link; @@ -171,6 +184,9 @@ grub_script_create_cmdline (struct grub_parser_param *state, grub_dprintf ("scripting", "cmdline\n"); cmd = grub_script_malloc (state, sizeof (*cmd)); + if (!cmd) + return 0; + cmd->cmd.exec = grub_script_execute_cmdline; cmd->cmd.next = 0; cmd->arglist = arglist; @@ -193,6 +209,9 @@ grub_script_create_cmdif (struct grub_parser_param *state, grub_dprintf ("scripting", "cmdif\n"); cmd = grub_script_malloc (state, sizeof (*cmd)); + if (!cmd) + return 0; + cmd->cmd.exec = grub_script_execute_cmdif; cmd->cmd.next = 0; cmd->exec_to_evaluate = exec_to_evaluate; @@ -209,30 +228,16 @@ grub_script_create_cmdif (struct grub_parser_param *state, struct grub_script_cmd * grub_script_create_cmdmenu (struct grub_parser_param *state, struct grub_script_arglist *arglist, - char *sourcecode, - int options) + char *sourcecode, int options) { struct grub_script_cmd_menuentry *cmd; - int i; - - /* Skip leading newlines to make the sourcecode better readable when - using the editor. */ - while (*sourcecode == '\n') - sourcecode++; - - /* Having trailing returns can some some annoying conflicts, remove - them. XXX: Can the parser be improved to handle this? */ - for (i = grub_strlen (sourcecode) - 1; i > 0; i--) - { - if (sourcecode[i] != '\n') - break; - sourcecode[i] = '\0'; - } cmd = grub_script_malloc (state, sizeof (*cmd)); + if (!cmd) + return 0; + cmd->cmd.exec = grub_script_execute_menuentry; cmd->cmd.next = 0; - /* XXX: Check if this memory is properly freed. */ cmd->sourcecode = sourcecode; cmd->arglist = arglist; cmd->options = options; @@ -248,15 +253,19 @@ grub_script_add_cmd (struct grub_parser_param *state, struct grub_script_cmdblock *cmdblock, struct grub_script_cmd *cmd) { + struct grub_script_cmd *ptr; + grub_dprintf ("scripting", "cmdblock\n"); - if (! cmd) + if (!cmd) return (struct grub_script_cmd *) cmdblock; - if (! cmdblock) + if (!cmdblock) { - cmdblock = (struct grub_script_cmdblock *) grub_script_malloc (state, - sizeof (*cmdblock)); + cmdblock = grub_script_malloc (state, sizeof (*cmdblock)); + if (!cmdblock) + return 0; + cmdblock->cmd.exec = grub_script_execute_cmdblock; cmdblock->cmd.next = 0; cmdblock->cmdlist = cmd; @@ -264,22 +273,29 @@ grub_script_add_cmd (struct grub_parser_param *state, } else { - cmd->next = cmdblock->cmdlist; - cmdblock->cmdlist = cmd; + if (!cmdblock->cmdlist) + cmdblock->cmdlist = cmd; + else + { + ptr = cmdblock->cmdlist; + while (ptr->next) + ptr = ptr->next; + ptr->next = cmd; + } } return (struct grub_script_cmd *) cmdblock; } - + struct grub_script * grub_script_create (struct grub_script_cmd *cmd, struct grub_script_mem *mem) { struct grub_script *parsed; parsed = grub_malloc (sizeof (*parsed)); - if (! parsed) + if (!parsed) { grub_script_mem_free (mem); grub_free (cmd); @@ -304,16 +320,16 @@ grub_script_parse (char *script, grub_reader_getline_t getline) struct grub_parser_param *parsestate; parsed = grub_malloc (sizeof (*parsed)); - if (! parsed) + if (!parsed) return 0; parsestate = grub_zalloc (sizeof (*parsestate)); - if (! parsestate) + if (!parsestate) return 0; /* Initialize the lexer. */ - lexstate = grub_script_lexer_init (script, getline); - if (! lexstate) + lexstate = grub_script_lexer_init (parsestate, script, getline); + if (!lexstate) { grub_free (parsed); grub_free (parsestate); @@ -330,7 +346,7 @@ grub_script_parse (char *script, grub_reader_getline_t getline) struct grub_script_mem *memfree; memfree = grub_script_mem_record_stop (parsestate, membackup); grub_script_mem_free (memfree); - grub_free (lexstate); + grub_script_lexer_fini (lexstate); grub_free (parsestate); return 0; } @@ -338,7 +354,7 @@ grub_script_parse (char *script, grub_reader_getline_t getline) parsed->mem = grub_script_mem_record_stop (parsestate, membackup); parsed->cmd = parsestate->parsed; - grub_free (lexstate); + grub_script_lexer_fini (lexstate); grub_free (parsestate); return parsed; diff --git a/script/yylex.l b/script/yylex.l new file mode 100644 index 000000000..4f6c00e21 --- /dev/null +++ b/script/yylex.l @@ -0,0 +1,331 @@ +%{ +/* yylex.l The scripting lexer. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009,2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include "grub_script.tab.h" + +#define yyfree grub_lexer_yyfree +#define yyalloc grub_lexer_yyalloc +#define yyrealloc grub_lexer_yyrealloc + +/* + * As we don't have access to yyscanner, we cannot do much except to + * print the fatal error. + */ +#define YY_FATAL_ERROR(msg) \ + do { \ + grub_printf ("fatal error: %s\n", msg); \ + } while (0) + +#define PUSH(c) \ + do { \ + if (yyextra->lexerstate->size >= GRUB_LEXER_TOKEN_MAX - 1) \ + grub_script_yyerror (yyextra, "token too long"); \ + else \ + yyextra->lexerstate->text[yyextra->lexerstate->size++] = c; \ + } while (0) + +#define COPY(str) \ + do { \ + char *ptr = str; \ + while (*ptr && ! yyextra->err) \ + { \ + PUSH (*ptr); \ + ptr++; \ + } \ + } while (0) + +#define RECORD \ + do { \ + grub_script_lexer_record (yyextra, yytext); \ + } while (0) + +#define ARG(t) \ + do { \ + yyextra->lexerstate->type = t; \ + return GRUB_PARSER_TOKEN_WORD; \ + } while (0) + +/* We don't need YY_INPUT, as we rely on yy_scan_strings */ +#define YY_INPUT(buf,res,max) do { res = 0; } while (0) + +/* forward declarations */ +static void grub_lexer_yyfree (void *, yyscan_t yyscanner); +static void* grub_lexer_yyalloc (yy_size_t, yyscan_t yyscanner); +static void* grub_lexer_yyrealloc (void*, yy_size_t, yyscan_t yyscanner); + +%} + +%top{ + +/* + * Some flex hacks for -nostdinc; XXX We need to fix these when libc + * support becomes availble in GRUB. + */ + +#include + +typedef grub_size_t size_t; +typedef grub_size_t yy_size_t; +#define YY_TYPEDEF_YY_SIZE_T 1 + +#define FILE void +#define stdin 0 +#define stdout 0 +#define EOF 0 + +#define errno grub_errno +#define EINVAL GRUB_ERR_BAD_NUMBER +#define ENOMEM GRUB_ERR_OUT_OF_MEMORY + +#define strlen grub_strlen +#define memset grub_memset + +#define fprintf(...) 0 +#define exit(...) + +#pragma GCC diagnostic warning "-Wunused-variable" +#pragma GCC diagnostic warning "-Wunused-function" +#pragma GCC diagnostic warning "-Wunused-parameter" +#pragma GCC diagnostic warning "-Wstrict-prototypes" +#pragma GCC diagnostic warning "-Wmissing-prototypes" + +} + +%option ecs +%option meta-ecs + +%option warn +%option array +%option stack +%option reentrant +%option bison-bridge +%option never-interactive + +%option noyyfree noyyalloc noyyrealloc +%option nounistd nostdinit nodefault noyylineno noyywrap + +/* Reduce lexer size, by not defining these. */ +%option noyy_top_state +%option noinput nounput +%option noyyget_in noyyset_in +%option noyyget_out noyyset_out +%option noyyget_debug noyyset_debug +%option noyyget_lineno noyyset_lineno + +%option extra-type="struct grub_parser_param*" + +BLANK [ \t] +COMMENT ^[ \t]*#.*$ + +CHAR [^|&;()<> \t\n\'\"] +DIGITS [[:digit:]]+ +NAME [[:alpha:]_][[:alnum:][:digit:]_]* + +ESC \\. +VARIABLE ${NAME}|$\{{NAME}\}|${DIGITS}|$\{{DIGITS}\}|$\?|$\{\?\} +DQSTR \"([^\"]|\\\")*\" +SQSTR \'[^\']*\' +WORD ({CHAR}|{DQSTR}|{SQSTR}|{ESC}|{VARIABLE})+ + +%x SPLIT +%x DQUOTE +%x SQUOTE +%x VAR + +%% + + /* White spaces */ +{BLANK}+ { RECORD; } +{COMMENT} { RECORD; } + + /* Special symbols */ +"\n" { RECORD; return GRUB_PARSER_TOKEN_NEWLINE; } +"||" { RECORD; return GRUB_PARSER_TOKEN_OR; } +"&&" { RECORD; return GRUB_PARSER_TOKEN_AND; } +";;" { RECORD; return GRUB_PARSER_TOKEN_SEMI2; } +"|" { RECORD; return GRUB_PARSER_TOKEN_PIPE; } +"&" { RECORD; return GRUB_PARSER_TOKEN_AMP; } +";" { RECORD; return GRUB_PARSER_TOKEN_SEMI; } +"(" { RECORD; return GRUB_PARSER_TOKEN_LPAR; } +")" { RECORD; return GRUB_PARSER_TOKEN_RPAR; } +"<" { RECORD; return GRUB_PARSER_TOKEN_LT; } +">" { RECORD; return GRUB_PARSER_TOKEN_GT; } + + /* Reserved words */ +"!" { RECORD; return GRUB_PARSER_TOKEN_NOT; } +"{" { RECORD; return GRUB_PARSER_TOKEN_LBR; } +"}" { RECORD; return GRUB_PARSER_TOKEN_RBR; } +"[[" { RECORD; return GRUB_PARSER_TOKEN_RSQBR2; } +"]]" { RECORD; return GRUB_PARSER_TOKEN_LSQBR2; } +"time" { RECORD; return GRUB_PARSER_TOKEN_TIME; } +"case" { RECORD; return GRUB_PARSER_TOKEN_CASE; } +"do" { RECORD; return GRUB_PARSER_TOKEN_DO; } +"done" { RECORD; return GRUB_PARSER_TOKEN_DONE; } +"elif" { RECORD; return GRUB_PARSER_TOKEN_ELIF; } +"else" { RECORD; return GRUB_PARSER_TOKEN_ELSE; } +"esac" { RECORD; return GRUB_PARSER_TOKEN_ESAC; } +"fi" { RECORD; return GRUB_PARSER_TOKEN_FI; } +"for" { RECORD; return GRUB_PARSER_TOKEN_FOR; } +"if" { RECORD; return GRUB_PARSER_TOKEN_IF; } +"in" { RECORD; return GRUB_PARSER_TOKEN_IN; } +"select" { RECORD; return GRUB_PARSER_TOKEN_SELECT; } +"then" { RECORD; return GRUB_PARSER_TOKEN_THEN; } +"until" { RECORD; return GRUB_PARSER_TOKEN_UNTIL; } +"while" { RECORD; return GRUB_PARSER_TOKEN_WHILE; } +"function" { RECORD; return GRUB_PARSER_TOKEN_FUNCTION; } +"menuentry" { RECORD; return GRUB_PARSER_TOKEN_MENUENTRY; } + +{NAME} { RECORD; return GRUB_PARSER_TOKEN_NAME; } +{WORD} { + RECORD; + /* resplit yytext */ + yypush_buffer_state (YY_CURRENT_BUFFER, yyscanner); + if (yy_scan_string (yytext, yyscanner)) + { + yyextra->lexerstate->merge_start = 1; + yy_push_state (SPLIT, yyscanner); + } + else + { + grub_script_yyerror (yyextra, 0); + yypop_buffer_state (yyscanner); + return GRUB_PARSER_TOKEN_WORD; + } + } + +.|\n { + grub_script_yyerror (yyextra, "unrecognized token"); + return GRUB_PARSER_TOKEN_BAD; + } + + + /* Split word into multiple args */ + +{ + \\. { PUSH (yytext[1]); } + \" { + yy_push_state (DQUOTE, yyscanner); + ARG (GRUB_SCRIPT_ARG_TYPE_TEXT); + } + \' { + yy_push_state (SQUOTE, yyscanner); + ARG (GRUB_SCRIPT_ARG_TYPE_TEXT); + } + \$ { + yy_push_state (VAR, yyscanner); + ARG (GRUB_SCRIPT_ARG_TYPE_TEXT); + } + {CHAR} { PUSH (yytext[0]); } + .|\n { + /* This cannot happen. */ + grub_script_yyerror (yyextra, "internal error: unexpected characters in a word"); + return GRUB_PARSER_TOKEN_BAD; + } + + <> { + yy_pop_state (yyscanner); + yypop_buffer_state (yyscanner); + yyextra->lexerstate->merge_end = 1; + ARG (GRUB_SCRIPT_ARG_TYPE_TEXT); + } +} + +{ + \? | + {DIGITS} | + {NAME} { + COPY (yytext); + yy_pop_state (yyscanner); + if (YY_START == SPLIT) + ARG (GRUB_SCRIPT_ARG_TYPE_VAR); + else + ARG (GRUB_SCRIPT_ARG_TYPE_DQVAR); + } + \{\?\} | + \{{DIGITS}\} | + \{{NAME}\} { + yytext[yyleng - 1] = '\0'; + COPY (yytext + 1); + yy_pop_state (yyscanner); + if (YY_START == SPLIT) + ARG (GRUB_SCRIPT_ARG_TYPE_VAR); + else + ARG (GRUB_SCRIPT_ARG_TYPE_DQVAR); + } + .|\n { return GRUB_PARSER_TOKEN_BAD; } +} + +{ + \' { + yy_pop_state (yyscanner); + ARG (GRUB_SCRIPT_ARG_TYPE_SQSTR); + } + (.|\n) { PUSH (yytext[0]); } +} + +{ + \" { + yy_pop_state (yyscanner); + ARG (GRUB_SCRIPT_ARG_TYPE_DQSTR); + } + \$ { + yy_push_state (VAR, yyscanner); + ARG (GRUB_SCRIPT_ARG_TYPE_DQSTR); + } + \\\\ { PUSH ('\\'); } + \\\" { PUSH ('\"'); } + \\\n { /* ignore */ } + (.|\n) { PUSH (yytext[0]); } +} + +<> { + yypop_buffer_state (yyscanner); + if (! grub_script_lexer_yywrap (yyextra)) + { + yyextra->lexerstate->eof = 1; + return GRUB_PARSER_TOKEN_EOF; + } + } + +%% + +static void +grub_lexer_yyfree (void *ptr, yyscan_t yyscanner __attribute__ ((unused))) +{ + grub_free(ptr); +} + +static void* +grub_lexer_yyalloc (yy_size_t size, yyscan_t yyscanner __attribute__ ((unused))) +{ + return grub_malloc (size); +} + +static void* +grub_lexer_yyrealloc (void *ptr, yy_size_t size, + yyscan_t yyscanner __attribute__ ((unused))) +{ + return grub_realloc (ptr, size); +} + diff --git a/tests/grub_script_echo1.in b/tests/grub_script_echo1.in new file mode 100644 index 000000000..048907a76 --- /dev/null +++ b/tests/grub_script_echo1.in @@ -0,0 +1,32 @@ +#! @builddir@/grub-shell-tester + +# Run GRUB script in a Qemu instance +# Copyright (C) 2010 Free Software Foundation, Inc. +# +# GRUB is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# GRUB is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GRUB. If not, see . + +foo=bar +echo $foo ${foo} +echo "$foo" "${foo}" +echo '$foo' '${foo}' +echo a$foob a${foo}b +echo ab"cd"ef$foo'gh'ij${foo}kl\ mn\"op\'qr\$st\(uv\yz\) + +foo=c +bar=h +echo e"$foo"${bar}o +e"$foo"${bar}o hello world + +foo=echo +$foo 1234 diff --git a/tests/grub_script_echo_keywords.in b/tests/grub_script_echo_keywords.in new file mode 100644 index 000000000..a6383f0e2 --- /dev/null +++ b/tests/grub_script_echo_keywords.in @@ -0,0 +1,3 @@ +#! @builddir@/grub-shell-tester + +echo if then else fi for do done diff --git a/tests/grub_script_vars1.in b/tests/grub_script_vars1.in new file mode 100644 index 000000000..9ff897627 --- /dev/null +++ b/tests/grub_script_vars1.in @@ -0,0 +1,34 @@ +#! @builddir@/grub-shell-tester + +# Run GRUB script in a Qemu instance +# Copyright (C) 2010 Free Software Foundation, Inc. +# +# GRUB is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# GRUB is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GRUB. If not, see . + +var=foo +echo $var +echo "$var" +echo ${var} +echo "${var}" + +echo $1 $2 $? + +foo=foo +echo "" $foo + +echo $bar $foo + +bar="" +echo $bar $foo + diff --git a/tests/util/grub-shell-tester.in b/tests/util/grub-shell-tester.in index 6ed4ebcac..e9507c8f5 100644 --- a/tests/util/grub-shell-tester.in +++ b/tests/util/grub-shell-tester.in @@ -1,7 +1,7 @@ #! /bin/bash -e # Compares GRUB script output with BASH output. -# Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009 Free Software Foundation, Inc. +# Copyright (C) 2009,2010 Free Software Foundation, Inc. # # GRUB is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by diff --git a/tests/util/grub-shell.in b/tests/util/grub-shell.in index e6fef8313..2b9131547 100644 --- a/tests/util/grub-shell.in +++ b/tests/util/grub-shell.in @@ -1,7 +1,7 @@ #! /bin/bash -e # Run GRUB script in a Qemu instance -# Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009 Free Software Foundation, Inc. +# Copyright (C) 2009,2010 Free Software Foundation, Inc. # # GRUB is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by diff --git a/util/grub-script-check.c b/util/grub-script-check.c index 3bfd6a425..0ad24186d 100644 --- a/util/grub-script-check.c +++ b/util/grub-script-check.c @@ -1,7 +1,7 @@ /* grub-script-check.c - check grub script file for syntax errors */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2003,2004,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc. + * Copyright (C) 2009,2010 Free Software Foundation, Inc. * * GRUB is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -82,16 +82,8 @@ grub_script_execute_cmdif (struct grub_script_cmd *cmd __attribute__ ((unused))) } grub_err_t -grub_script_execute_menuentry (struct grub_script_cmd *cmd) +grub_script_execute_menuentry (struct grub_script_cmd *cmd __attribute__ ((unused))) { - struct grub_script_cmd_menuentry *menu; - menu = (struct grub_script_cmd_menuentry *)cmd; - - if (menu->sourcecode) - { - grub_free (menu->sourcecode); - menu->sourcecode = 0; - } return 0; } From 566863ca1973b0cb39d469e46a384e59bcc437b4 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Fri, 22 Jan 2010 17:12:40 +0000 Subject: [PATCH 270/738] 2010-01-22 Robert Millan Use generic grub_reboot() for i386-efi. * kern/efi/efi.c [__i386__] (grub_reboot): Remove. * kern/i386/efi/startup.S: Include `"../realmode.S"'. * kern/i386/realmode.S: Include `'. --- ChangeLog | 8 ++++++++ kern/efi/efi.c | 5 ++++- kern/i386/efi/startup.S | 4 +++- kern/i386/realmode.S | 3 ++- 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5eef8a821..e559f218e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2010-01-22 Robert Millan + + Use generic grub_reboot() for i386-efi. + + * kern/efi/efi.c [__i386__] (grub_reboot): Remove. + * kern/i386/efi/startup.S: Include `"../realmode.S"'. + * kern/i386/realmode.S: Include `'. + 2010-01-22 Vladimir Serbinenko * kern/ieee1275/init.c (grub_machine_set_prefix): Don't check for diff --git a/kern/efi/efi.c b/kern/efi/efi.c index c6ce04c5e..d8b225535 100644 --- a/kern/efi/efi.c +++ b/kern/efi/efi.c @@ -1,7 +1,7 @@ /* efi.c - generic EFI support */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2006,2007,2008,2009 Free Software Foundation, Inc. + * Copyright (C) 2006,2007,2008,2009,2010 Free Software Foundation, Inc. * * GRUB is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -162,6 +162,8 @@ grub_exit (void) for (;;) ; } +/* On i386, a firmware-independant grub_reboot() is provided by realmode.S. */ +#ifndef __i386__ void grub_reboot (void) { @@ -169,6 +171,7 @@ grub_reboot (void) efi_call_4 (grub_efi_system_table->runtime_services->reset_system, GRUB_EFI_RESET_COLD, GRUB_EFI_SUCCESS, 0, NULL); } +#endif void grub_halt (void) diff --git a/kern/i386/efi/startup.S b/kern/i386/efi/startup.S index b88628010..5b464ab83 100644 --- a/kern/i386/efi/startup.S +++ b/kern/i386/efi/startup.S @@ -1,7 +1,7 @@ /* startup.S - bootstrap GRUB itself */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2006,2007 Free Software Foundation, Inc. + * Copyright (C) 2006,2007,2010 Free Software Foundation, Inc. * * GRUB is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -62,3 +62,5 @@ codestart: movl %eax, EXT_C(grub_efi_system_table) call EXT_C(grub_main) ret + +#include "../realmode.S" diff --git a/kern/i386/realmode.S b/kern/i386/realmode.S index a74eb1217..578c8d2a8 100644 --- a/kern/i386/realmode.S +++ b/kern/i386/realmode.S @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2009 Free Software Foundation, Inc. + * Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2009,2010 Free Software Foundation, Inc. * * GRUB is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,6 +16,7 @@ * along with GRUB. If not, see . */ +#include /* * Note: These functions defined in this file may be called from C. From df6dc2113acd4db226e7a5066916096775656222 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Sat, 23 Jan 2010 00:14:00 +0530 Subject: [PATCH 271/738] removed arbitrary limit on token size --- include/grub/script_sh.h | 9 +-- script/lexer.c | 6 +- script/yylex.l | 155 +++++++++++++++++++++------------------ 3 files changed, 89 insertions(+), 81 deletions(-) diff --git a/include/grub/script_sh.h b/include/grub/script_sh.h index 889017d2a..1eb6d0bb8 100644 --- a/include/grub/script_sh.h +++ b/include/grub/script_sh.h @@ -157,8 +157,10 @@ struct grub_lexer_param int merge_start; int merge_end; - /* Text of current token. */ + /* Part of a multi-part token. */ char *text; + unsigned used; + unsigned size; /* Type of text. */ grub_script_arg_type_t type; @@ -168,12 +170,9 @@ struct grub_lexer_param /* Flex scanner buffer. */ void *buffer; - - /* Length of current token text. */ - unsigned size; }; -#define GRUB_LEXER_TOKEN_MAX 256 +#define GRUB_LEXER_INITIAL_TEXT_SIZE 32 #define GRUB_LEXER_RECORD_INCREMENT 256 /* State of the parser as passes to the parser. */ diff --git a/script/lexer.c b/script/lexer.c index d43c9f157..179e1d1d2 100644 --- a/script/lexer.c +++ b/script/lexer.c @@ -213,7 +213,8 @@ grub_script_lexer_init (struct grub_parser_param *parser, char *script, if (!lexerstate) return 0; - lexerstate->text = grub_malloc (GRUB_LEXER_TOKEN_MAX); + lexerstate->size = GRUB_LEXER_INITIAL_TEXT_SIZE; + lexerstate->text = grub_malloc (lexerstate->size); if (!lexerstate->text) { grub_free (lexerstate); @@ -301,7 +302,7 @@ grub_script_yylex (union YYSTYPE *value, do { /* Empty lexerstate->text. */ - lexerstate->size = 0; + lexerstate->used = 1; lexerstate->text[0] = '\0'; token = yylex (value, lexerstate->yyscanner); @@ -311,7 +312,6 @@ grub_script_yylex (union YYSTYPE *value, /* Merging feature uses lexerstate->text instead of yytext. */ if (lexerstate->merge_start) { - lexerstate->text[lexerstate->size] = '\0'; str = lexerstate->text; type = lexerstate->type; } diff --git a/script/yylex.l b/script/yylex.l index 4f6c00e21..c19461c9a 100644 --- a/script/yylex.l +++ b/script/yylex.l @@ -37,31 +37,19 @@ grub_printf ("fatal error: %s\n", msg); \ } while (0) -#define PUSH(c) \ - do { \ - if (yyextra->lexerstate->size >= GRUB_LEXER_TOKEN_MAX - 1) \ - grub_script_yyerror (yyextra, "token too long"); \ - else \ - yyextra->lexerstate->text[yyextra->lexerstate->size++] = c; \ - } while (0) - -#define COPY(str) \ - do { \ - char *ptr = str; \ - while (*ptr && ! yyextra->err) \ - { \ - PUSH (*ptr); \ - ptr++; \ - } \ +#define COPY(str, hint) \ + do { \ + copy_string (yyextra, str, hint); \ } while (0) -#define RECORD \ - do { \ - grub_script_lexer_record (yyextra, yytext); \ + +#define RECORD \ + do { \ + grub_script_lexer_record (yyextra, yytext); \ } while (0) -#define ARG(t) \ - do { \ +#define ARG(t) \ + do { \ yyextra->lexerstate->type = t; \ return GRUB_PARSER_TOKEN_WORD; \ } while (0) @@ -73,6 +61,8 @@ static void grub_lexer_yyfree (void *, yyscan_t yyscanner); static void* grub_lexer_yyalloc (yy_size_t, yyscan_t yyscanner); static void* grub_lexer_yyrealloc (void*, yy_size_t, yyscan_t yyscanner); +static void copy_string (struct grub_parser_param *, const char *, + unsigned hint); %} @@ -201,52 +191,47 @@ WORD ({CHAR}|{DQSTR}|{SQSTR}|{ESC}|{VARIABLE})+ RECORD; /* resplit yytext */ yypush_buffer_state (YY_CURRENT_BUFFER, yyscanner); - if (yy_scan_string (yytext, yyscanner)) - { - yyextra->lexerstate->merge_start = 1; - yy_push_state (SPLIT, yyscanner); - } - else - { - grub_script_yyerror (yyextra, 0); - yypop_buffer_state (yyscanner); - return GRUB_PARSER_TOKEN_WORD; - } + if (yy_scan_string (yytext, yyscanner)) + { + yyextra->lexerstate->merge_start = 1; + yy_push_state (SPLIT, yyscanner); + } + else + { + grub_script_yyerror (yyextra, 0); + yypop_buffer_state (yyscanner); + return GRUB_PARSER_TOKEN_WORD; + } } .|\n { grub_script_yyerror (yyextra, "unrecognized token"); - return GRUB_PARSER_TOKEN_BAD; + return GRUB_PARSER_TOKEN_BAD; } /* Split word into multiple args */ { - \\. { PUSH (yytext[1]); } + \\. { COPY (yytext + 1, yyleng - 1); } \" { - yy_push_state (DQUOTE, yyscanner); + yy_push_state (DQUOTE, yyscanner); ARG (GRUB_SCRIPT_ARG_TYPE_TEXT); } \' { - yy_push_state (SQUOTE, yyscanner); + yy_push_state (SQUOTE, yyscanner); ARG (GRUB_SCRIPT_ARG_TYPE_TEXT); } \$ { yy_push_state (VAR, yyscanner); ARG (GRUB_SCRIPT_ARG_TYPE_TEXT); - } - {CHAR} { PUSH (yytext[0]); } - .|\n { - /* This cannot happen. */ - grub_script_yyerror (yyextra, "internal error: unexpected characters in a word"); - return GRUB_PARSER_TOKEN_BAD; - } - + } + \\ | + [^\"\'$\\]+ { COPY (yytext, yyleng); } <> { - yy_pop_state (yyscanner); - yypop_buffer_state (yyscanner); - yyextra->lexerstate->merge_end = 1; + yy_pop_state (yyscanner); + yypop_buffer_state (yyscanner); + yyextra->lexerstate->merge_end = 1; ARG (GRUB_SCRIPT_ARG_TYPE_TEXT); } } @@ -255,23 +240,23 @@ WORD ({CHAR}|{DQSTR}|{SQSTR}|{ESC}|{VARIABLE})+ \? | {DIGITS} | {NAME} { - COPY (yytext); - yy_pop_state (yyscanner); - if (YY_START == SPLIT) - ARG (GRUB_SCRIPT_ARG_TYPE_VAR); - else - ARG (GRUB_SCRIPT_ARG_TYPE_DQVAR); - } + COPY (yytext, yyleng); + yy_pop_state (yyscanner); + if (YY_START == SPLIT) + ARG (GRUB_SCRIPT_ARG_TYPE_VAR); + else + ARG (GRUB_SCRIPT_ARG_TYPE_DQVAR); + } \{\?\} | \{{DIGITS}\} | \{{NAME}\} { yytext[yyleng - 1] = '\0'; - COPY (yytext + 1); + COPY (yytext + 1, yyleng - 2); yy_pop_state (yyscanner); - if (YY_START == SPLIT) - ARG (GRUB_SCRIPT_ARG_TYPE_VAR); - else - ARG (GRUB_SCRIPT_ARG_TYPE_DQVAR); + if (YY_START == SPLIT) + ARG (GRUB_SCRIPT_ARG_TYPE_VAR); + else + ARG (GRUB_SCRIPT_ARG_TYPE_DQVAR); } .|\n { return GRUB_PARSER_TOKEN_BAD; } } @@ -279,33 +264,34 @@ WORD ({CHAR}|{DQSTR}|{SQSTR}|{ESC}|{VARIABLE})+ { \' { yy_pop_state (yyscanner); - ARG (GRUB_SCRIPT_ARG_TYPE_SQSTR); + ARG (GRUB_SCRIPT_ARG_TYPE_SQSTR); } - (.|\n) { PUSH (yytext[0]); } + [^\']+ { COPY (yytext, yyleng); } } { \" { yy_pop_state (yyscanner); - ARG (GRUB_SCRIPT_ARG_TYPE_DQSTR); + ARG (GRUB_SCRIPT_ARG_TYPE_DQSTR); } \$ { yy_push_state (VAR, yyscanner); - ARG (GRUB_SCRIPT_ARG_TYPE_DQSTR); - } - \\\\ { PUSH ('\\'); } - \\\" { PUSH ('\"'); } + ARG (GRUB_SCRIPT_ARG_TYPE_DQSTR); + } + \\\\ { COPY ("\\", 1); } + \\\" { COPY ("\"", 1); } \\\n { /* ignore */ } - (.|\n) { PUSH (yytext[0]); } + [^\"$\\\n]+ { COPY (yytext, yyleng); } + (.|\n) { COPY (yytext, yyleng); } } <> { - yypop_buffer_state (yyscanner); - if (! grub_script_lexer_yywrap (yyextra)) - { - yyextra->lexerstate->eof = 1; - return GRUB_PARSER_TOKEN_EOF; - } + yypop_buffer_state (yyscanner); + if (! grub_script_lexer_yywrap (yyextra)) + { + yyextra->lexerstate->eof = 1; + return GRUB_PARSER_TOKEN_EOF; + } } %% @@ -329,3 +315,26 @@ grub_lexer_yyrealloc (void *ptr, yy_size_t size, return grub_realloc (ptr, size); } +static void copy_string (struct grub_parser_param *parser, const char *str, unsigned hint) +{ + int len; + int size; + char *ptr; + + len = hint ? hint : grub_strlen (str); + if (parser->lexerstate->used + len >= parser->lexerstate->size) + { + size = parser->lexerstate->size * 2; + ptr = grub_realloc (parser->lexerstate->text, size); + if (!ptr) + { + grub_script_yyerror (parser, 0); + return; + } + + parser->lexerstate->text = ptr; + parser->lexerstate->size = size; + } + grub_strcpy (parser->lexerstate->text + parser->lexerstate->used - 1, str); + parser->lexerstate->used += len; +} From bae09d0d47418def5585a22a0a8af50ebfae327a Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Sat, 23 Jan 2010 00:42:55 +0530 Subject: [PATCH 272/738] remove arbitrary limit on menuentry recording --- include/grub/script_sh.h | 4 ++-- script/lexer.c | 15 +++++++++------ script/yylex.l | 6 ++++-- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/include/grub/script_sh.h b/include/grub/script_sh.h index 1eb6d0bb8..5ada7c7e5 100644 --- a/include/grub/script_sh.h +++ b/include/grub/script_sh.h @@ -172,8 +172,8 @@ struct grub_lexer_param void *buffer; }; -#define GRUB_LEXER_INITIAL_TEXT_SIZE 32 -#define GRUB_LEXER_RECORD_INCREMENT 256 +#define GRUB_LEXER_INITIAL_TEXT_SIZE 32 +#define GRUB_LEXER_INITIAL_RECORD_SIZE 256 /* State of the parser as passes to the parser. */ struct grub_parser_param diff --git a/script/lexer.c b/script/lexer.c index 179e1d1d2..834ca1e91 100644 --- a/script/lexer.c +++ b/script/lexer.c @@ -45,12 +45,11 @@ grub_script_lexer_record_start (struct grub_parser_param *parser) lexer->record = 1; lexer->recordpos = 0; - if (lexer->recording) /* reuse last record */ + if (lexer->recording) /* reuse last record */ return; - lexer->recordlen = GRUB_LEXER_RECORD_INCREMENT; + lexer->recordlen = GRUB_LEXER_INITIAL_RECORD_SIZE; lexer->recording = grub_malloc (lexer->recordlen); - if (!lexer->recording) { grub_script_yyerror (parser, 0); @@ -99,27 +98,31 @@ grub_script_lexer_record_stop (struct grub_parser_param *parser) return result; } +#define MAX(a,b) ((a) < (b) ? (b) : (a)) /* Record STR if input recording is enabled. */ void grub_script_lexer_record (struct grub_parser_param *parser, char *str) { int len; + char *old; struct grub_lexer_param *lexer = parser->lexerstate; if (!lexer->record) return; len = grub_strlen (str); - if (lexer->recordpos + len >= lexer->recordlen - 1) + if (lexer->recordpos + len + 1 > lexer->recordlen) { - char *old = lexer->recording; - lexer->recordlen += GRUB_LEXER_RECORD_INCREMENT; + old = lexer->recording; + lexer->recordlen = MAX (len, lexer->recordlen) * 2; lexer->recording = grub_realloc (lexer->recording, lexer->recordlen); if (!lexer->recording) { grub_free (old); lexer->record = 0; + lexer->recordpos = 0; + lexer->recordlen /= 2; grub_script_yyerror (parser, 0); return; } diff --git a/script/yylex.l b/script/yylex.l index c19461c9a..9cafba5c2 100644 --- a/script/yylex.l +++ b/script/yylex.l @@ -315,16 +315,18 @@ grub_lexer_yyrealloc (void *ptr, yy_size_t size, return grub_realloc (ptr, size); } +#define MAX(a,b) ((a) < (b) ? (b) : (a)) + static void copy_string (struct grub_parser_param *parser, const char *str, unsigned hint) { - int len; int size; char *ptr; + unsigned len; len = hint ? hint : grub_strlen (str); if (parser->lexerstate->used + len >= parser->lexerstate->size) { - size = parser->lexerstate->size * 2; + size = MAX (len, parser->lexerstate->size) * 2; ptr = grub_realloc (parser->lexerstate->text, size); if (!ptr) { From 454fcd1c9bd5229c2fccabb1e34cbf0b1693ba92 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 22 Jan 2010 20:40:21 +0100 Subject: [PATCH 273/738] 2010-01-22 Vladimir Serbinenko * configure.ac: Check for _restgpr_14_x. * include/grub/powerpc/libgcc.h [HAVE__RESTGPR_14_X]: Add _restgpr_*_x and _savegpr_* prototypes. --- ChangeLog | 6 ++++++ configure.ac | 2 +- include/grub/powerpc/libgcc.h | 39 +++++++++++++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index e559f218e..a44d1f66e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-01-22 Vladimir Serbinenko + + * configure.ac: Check for _restgpr_14_x. + * include/grub/powerpc/libgcc.h [HAVE__RESTGPR_14_X]: Add _restgpr_*_x + and _savegpr_* prototypes. + 2010-01-22 Robert Millan Use generic grub_reboot() for i386-efi. diff --git a/configure.ac b/configure.ac index b1435de44..f621b5648 100644 --- a/configure.ac +++ b/configure.ac @@ -439,7 +439,7 @@ AC_SUBST(TARGET_CPPFLAGS) AC_SUBST(TARGET_LDFLAGS) # Check for libgcc symbols (must be performed before we add -nostdlib to LDFLAGS) -AC_CHECK_FUNCS(__bswapsi2 __bswapdi2 __ashldi3 __ashrdi3 __lshrdi3 __trampoline_setup __ucmpdi2) +AC_CHECK_FUNCS(__bswapsi2 __bswapdi2 __ashldi3 __ashrdi3 __lshrdi3 __trampoline_setup __ucmpdi2 _restgpr_14_x) # Set them to their new values for the tests below. CC="$TARGET_CC" diff --git a/include/grub/powerpc/libgcc.h b/include/grub/powerpc/libgcc.h index 452ad4366..6be122308 100644 --- a/include/grub/powerpc/libgcc.h +++ b/include/grub/powerpc/libgcc.h @@ -33,3 +33,42 @@ void EXPORT_FUNC (__trampoline_setup) (void); #ifdef HAVE___UCMPDI2 void EXPORT_FUNC (__ucmpdi2) (void); #endif + +#ifdef HAVE__RESTGPR_14_X +void EXPORT_FUNC (_restgpr_14_x) (void); +void EXPORT_FUNC (_restgpr_15_x) (void); +void EXPORT_FUNC (_restgpr_16_x) (void); +void EXPORT_FUNC (_restgpr_17_x) (void); +void EXPORT_FUNC (_restgpr_18_x) (void); +void EXPORT_FUNC (_restgpr_19_x) (void); +void EXPORT_FUNC (_restgpr_20_x) (void); +void EXPORT_FUNC (_restgpr_21_x) (void); +void EXPORT_FUNC (_restgpr_22_x) (void); +void EXPORT_FUNC (_restgpr_23_x) (void); +void EXPORT_FUNC (_restgpr_24_x) (void); +void EXPORT_FUNC (_restgpr_25_x) (void); +void EXPORT_FUNC (_restgpr_26_x) (void); +void EXPORT_FUNC (_restgpr_27_x) (void); +void EXPORT_FUNC (_restgpr_28_x) (void); +void EXPORT_FUNC (_restgpr_29_x) (void); +void EXPORT_FUNC (_restgpr_30_x) (void); +void EXPORT_FUNC (_restgpr_31_x) (void); +void EXPORT_FUNC (_savegpr_14) (void); +void EXPORT_FUNC (_savegpr_15) (void); +void EXPORT_FUNC (_savegpr_16) (void); +void EXPORT_FUNC (_savegpr_17) (void); +void EXPORT_FUNC (_savegpr_18) (void); +void EXPORT_FUNC (_savegpr_19) (void); +void EXPORT_FUNC (_savegpr_20) (void); +void EXPORT_FUNC (_savegpr_21) (void); +void EXPORT_FUNC (_savegpr_22) (void); +void EXPORT_FUNC (_savegpr_23) (void); +void EXPORT_FUNC (_savegpr_24) (void); +void EXPORT_FUNC (_savegpr_25) (void); +void EXPORT_FUNC (_savegpr_26) (void); +void EXPORT_FUNC (_savegpr_27) (void); +void EXPORT_FUNC (_savegpr_28) (void); +void EXPORT_FUNC (_savegpr_29) (void); +void EXPORT_FUNC (_savegpr_30) (void); +void EXPORT_FUNC (_savegpr_31) (void); +#endif From 4b358c0a56edfcd90e52a1fb6334408ffa6909fa Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 22 Jan 2010 20:42:02 +0100 Subject: [PATCH 274/738] 2010-01-22 Vladimir Serbinenko * term/ieee1275/ofconsole.c (grub_ofconsole_setcolorstate): Allocate on stack since heap may be unavailable at that point. (grub_ofconsole_gotoxy): Likewise. --- ChangeLog | 6 ++++++ term/ieee1275/ofconsole.c | 16 ++++++---------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index a44d1f66e..d700466fa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-01-22 Vladimir Serbinenko + + * term/ieee1275/ofconsole.c (grub_ofconsole_setcolorstate): Allocate on + stack since heap may be unavailable at that point. + (grub_ofconsole_gotoxy): Likewise. + 2010-01-22 Vladimir Serbinenko * configure.ac: Check for _restgpr_14_x. diff --git a/term/ieee1275/ofconsole.c b/term/ieee1275/ofconsole.c index 3799e2e27..51dca7a53 100644 --- a/term/ieee1275/ofconsole.c +++ b/term/ieee1275/ofconsole.c @@ -109,7 +109,7 @@ grub_ofconsole_getcharwidth (grub_uint32_t c __attribute__((unused))) static void grub_ofconsole_setcolorstate (grub_term_color_state state) { - char *setcol; + char setcol[256]; int fg; int bg; @@ -128,10 +128,8 @@ grub_ofconsole_setcolorstate (grub_term_color_state state) return; } - setcol = grub_xasprintf ("\e[3%dm\e[4%dm", fg, bg); - if (setcol) - grub_ofconsole_writeesc (setcol); - grub_free (setcol); + grub_snprintf (setcol, sizeof (setcol), "\e[3%dm\e[4%dm", fg, bg); + grub_ofconsole_writeesc (setcol); } static void @@ -288,14 +286,12 @@ grub_ofconsole_gotoxy (grub_uint8_t x, grub_uint8_t y) { if (! grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_ANSI)) { - char *s; + char s[256]; grub_curr_x = x; grub_curr_y = y; - s = grub_xasprintf ("\e[%d;%dH", y + 1, x + 1); - if (s) - grub_ofconsole_writeesc (s); - grub_free (s); + grub_snprintf (s, sizeof (s), "\e[%d;%dH", y + 1, x + 1); + grub_ofconsole_writeesc (s); } else { From 345dd552add27340079e6b3458dcb2c2866ee9fa Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Sat, 23 Jan 2010 08:57:26 +0530 Subject: [PATCH 275/738] replace ROUND_UPTO with ALIGN_UP --- script/execute.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/script/execute.c b/script/execute.c index 83b6649ce..4197598fb 100644 --- a/script/execute.c +++ b/script/execute.c @@ -35,8 +35,6 @@ grub_script_execute_cmd (struct grub_script_cmd *cmd) return cmd->exec (cmd); } -#define ROUND_UPTO(sz,up) (((sz) + (up) - 1) / (up) * (up)) - /* Expand arguments in ARGLIST into multiple arguments. */ char ** grub_script_execute_arglist_to_argv (struct grub_script_arglist *arglist) @@ -58,7 +56,7 @@ grub_script_execute_arglist_to_argv (struct grub_script_arglist *arglist) if (oom) return; - p = grub_realloc (argv, ROUND_UPTO (sizeof(char*) * (argc + 1), 32)); + p = grub_realloc (argv, ALIGN_UP (sizeof(char*) * (argc + 1), 32)); if (!p) oom = 1; else @@ -80,7 +78,7 @@ grub_script_execute_arglist_to_argv (struct grub_script_arglist *arglist) len = nchar ?: grub_strlen (str); old = argv[argc - 1] ? grub_strlen (argv[argc - 1]) : 0; - p = grub_realloc (argv[argc - 1], ROUND_UPTO(old + len + 1, 32)); + p = grub_realloc (argv[argc - 1], ALIGN_UP(old + len + 1, 32)); if (p) { From 1fb08ed515591c2da70227cc9958f6aaa2311ac0 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Sat, 23 Jan 2010 09:12:46 +0530 Subject: [PATCH 276/738] return arg count from grub_script_execute_arglist_to_argv --- include/grub/script_sh.h | 2 +- script/execute.c | 15 ++++++--------- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/include/grub/script_sh.h b/include/grub/script_sh.h index 5ada7c7e5..c8c610d7b 100644 --- a/include/grub/script_sh.h +++ b/include/grub/script_sh.h @@ -300,6 +300,6 @@ int grub_script_function_call (grub_script_function_t func, int argc, char **args); char ** -grub_script_execute_arglist_to_argv (struct grub_script_arglist *arglist); +grub_script_execute_arglist_to_argv (struct grub_script_arglist *arglist, int *count); #endif /* ! GRUB_NORMAL_PARSER_HEADER */ diff --git a/script/execute.c b/script/execute.c index 4197598fb..5d60e9f8c 100644 --- a/script/execute.c +++ b/script/execute.c @@ -37,7 +37,7 @@ grub_script_execute_cmd (struct grub_script_cmd *cmd) /* Expand arguments in ARGLIST into multiple arguments. */ char ** -grub_script_execute_arglist_to_argv (struct grub_script_arglist *arglist) +grub_script_execute_arglist_to_argv (struct grub_script_arglist *arglist, int *count) { int i; int oom; @@ -162,7 +162,6 @@ grub_script_execute_arglist_to_argv (struct grub_script_arglist *arglist) if (!empty) push (0); } - push (0); /* Ensure argv[argc] == 0. */ if (oom) { @@ -172,6 +171,9 @@ grub_script_execute_arglist_to_argv (struct grub_script_arglist *arglist) argv = 0; } + if (argv) + *count = argc - 1; + return argv; } @@ -190,7 +192,7 @@ grub_script_execute_cmdline (struct grub_script_cmd *cmd) char *cmdname; /* Lookup the command. */ - args = grub_script_execute_arglist_to_argv (cmdline->arglist); + args = grub_script_execute_arglist_to_argv (cmdline->arglist, &argcount); if (!args) return grub_errno; @@ -228,9 +230,6 @@ grub_script_execute_cmdline (struct grub_script_cmd *cmd) } } - /* Count argv size. */ - for (argcount = 0; args[argcount]; argcount++); - /* Execute the GRUB command or function. */ if (grubcmd) ret = (grubcmd->func) (grubcmd, argcount - 1, args + 1); @@ -296,11 +295,9 @@ grub_script_execute_menuentry (struct grub_script_cmd *cmd) if (cmd_menuentry->arglist) { - args = grub_script_execute_arglist_to_argv (cmd_menuentry->arglist); + args = grub_script_execute_arglist_to_argv (cmd_menuentry->arglist, &argcount); if (!args) return grub_errno; - - for (argcount = 0; args[argcount]; argcount++); } grub_normal_add_menu_entry (argcount, (const char **) args, From 836727564e7b27462d0dffc9ea41a2463370f5d1 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Sat, 23 Jan 2010 09:18:13 +0530 Subject: [PATCH 277/738] replace grub_printf with grub_dprintf --- script/lexer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script/lexer.c b/script/lexer.c index 834ca1e91..17c38a353 100644 --- a/script/lexer.c +++ b/script/lexer.c @@ -323,7 +323,7 @@ grub_script_yylex (union YYSTYPE *value, str = yyget_text (lexerstate->yyscanner); type = GRUB_SCRIPT_ARG_TYPE_TEXT; } - /* grub_printf ("tok %u, txt [%s] size %u\n", token, str, lexerstate->size); */ + grub_dprintf("lexer", "token %u text [%s]\n", token, str); value->arg = grub_script_arg_add (parserstate, value->arg, type, str); } From 1a0c3b4809152c876e15c2196a1ea1084f131f27 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Sat, 23 Jan 2010 10:14:32 +0530 Subject: [PATCH 278/738] some bug fixes --- script/lexer.c | 2 +- script/yylex.l | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/script/lexer.c b/script/lexer.c index 17c38a353..caefdb7a7 100644 --- a/script/lexer.c +++ b/script/lexer.c @@ -139,7 +139,7 @@ append_newline (const char *src) grub_size_t len; len = grub_strlen (src); - line = grub_malloc (len + 1); + line = grub_malloc (len + 2); if (!line) return 0; diff --git a/script/yylex.l b/script/yylex.l index 9cafba5c2..7cef8496b 100644 --- a/script/yylex.l +++ b/script/yylex.l @@ -128,13 +128,13 @@ typedef grub_size_t yy_size_t; BLANK [ \t] COMMENT ^[ \t]*#.*$ -CHAR [^|&;()<> \t\n\'\"] +CHAR [^|&$;()<> \t\n\'\"\\] DIGITS [[:digit:]]+ NAME [[:alpha:]_][[:alnum:][:digit:]_]* ESC \\. VARIABLE ${NAME}|$\{{NAME}\}|${DIGITS}|$\{{DIGITS}\}|$\?|$\{\?\} -DQSTR \"([^\"]|\\\")*\" +DQSTR \"([^\\\"]|{ESC})*\" SQSTR \'[^\']*\' WORD ({CHAR}|{DQSTR}|{SQSTR}|{ESC}|{VARIABLE})+ @@ -190,6 +190,7 @@ WORD ({CHAR}|{DQSTR}|{SQSTR}|{ESC}|{VARIABLE})+ {WORD} { RECORD; /* resplit yytext */ + grub_dprintf ("lexer", "word: [%s]\n", yytext); yypush_buffer_state (YY_CURRENT_BUFFER, yyscanner); if (yy_scan_string (yytext, yyscanner)) { @@ -209,7 +210,6 @@ WORD ({CHAR}|{DQSTR}|{SQSTR}|{ESC}|{VARIABLE})+ return GRUB_PARSER_TOKEN_BAD; } - /* Split word into multiple args */ { From d63cdb6e704c4006b1aabe94a2f04a925414fa2e Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Sat, 23 Jan 2010 10:16:05 +0530 Subject: [PATCH 279/738] removed error-verbose to reduce resulting sh.mod size --- script/parser.y | 2 -- 1 file changed, 2 deletions(-) diff --git a/script/parser.y b/script/parser.y index 6d1b5bdbc..b8d981866 100644 --- a/script/parser.y +++ b/script/parser.y @@ -80,8 +80,6 @@ %type commands1 menuentry statement %pure-parser -%error-verbose - %lex-param { struct grub_parser_param *state }; %parse-param { struct grub_parser_param *state }; From 1368740e693e3030319ae064eecc9e21fe8e6018 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Sat, 23 Jan 2010 10:28:52 +0530 Subject: [PATCH 280/738] one more bug fix in grub_script_execute_arglist_to_argv --- script/execute.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script/execute.c b/script/execute.c index 5d60e9f8c..c956960da 100644 --- a/script/execute.c +++ b/script/execute.c @@ -130,7 +130,7 @@ grub_script_execute_arglist_to_argv (struct grub_script_arglist *arglist, int *c { case GRUB_SCRIPT_ARG_TYPE_VAR: value = grub_env_get (arg->str); - while (*value && (ptr = move_to_next(&value))) + while (value && *value && (ptr = move_to_next(&value))) { empty = 0; append (ptr, value - ptr); From 4e6a305be4782194a1aaf83e962f54b313db2ac8 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Sat, 23 Jan 2010 11:03:41 +0530 Subject: [PATCH 281/738] for loop support to grub script --- ChangeLog.for-loop | 13 +++++++++++++ conf/tests.rmk | 4 ++++ include/grub/script_sh.h | 22 ++++++++++++++++++++++ script/execute.c | 26 ++++++++++++++++++++++++++ script/parser.y | 14 +++++++++++++- script/script.c | 24 ++++++++++++++++++++++++ tests/grub_script_for1.in | 27 +++++++++++++++++++++++++++ util/grub-script-check.c | 6 ++++++ 8 files changed, 135 insertions(+), 1 deletion(-) create mode 100644 ChangeLog.for-loop create mode 100644 tests/grub_script_for1.in diff --git a/ChangeLog.for-loop b/ChangeLog.for-loop new file mode 100644 index 000000000..0fbb9d04a --- /dev/null +++ b/ChangeLog.for-loop @@ -0,0 +1,13 @@ +2010-01-12 BVK Chaitanya + + For loop support to GRUB script. + + * include/grub/script_sh.h (grub_script_cmdfor): New struct. + (grub_script_create_cmdfor): New function prototype. + (grub_script_execute_cmdfor): New function prototype. + * script/execute.c (grub_script_execute_cmdfor): New function. + * script/parser.y (command): New for command. + (forcmd): New grammar rule. + * script/script.c (grub_script_create_cmdfor): New function. + * util/grub-script-check.c (grub_script_execute_cmdfor): New + function. diff --git a/conf/tests.rmk b/conf/tests.rmk index c5080f58c..92f14797d 100644 --- a/conf/tests.rmk +++ b/conf/tests.rmk @@ -50,6 +50,9 @@ grub_script_echo_keywords_SOURCES = tests/grub_script_echo_keywords.in check_SCRIPTS += grub_script_vars1 grub_script_vars1_SOURCES = tests/grub_script_vars1.in +check_SCRIPTS += grub_script_for1 +grub_script_for1_SOURCES = tests/grub_script_for1.in + # List of tests to execute on "make check" # SCRIPTED_TESTS = example_scripted_test # SCRIPTED_TESTS += example_grub_script_test @@ -59,6 +62,7 @@ grub_script_vars1_SOURCES = tests/grub_script_vars1.in SCRIPTED_TESTS = grub_script_echo1 SCRIPTED_TESTS += grub_script_echo_keywords SCRIPTED_TESTS += grub_script_vars1 +SCRIPTED_TESTS += grub_script_for1 # dependencies between tests and testing-tools $(SCRIPTED_TESTS): grub-shell grub-shell-tester diff --git a/include/grub/script_sh.h b/include/grub/script_sh.h index c8c610d7b..4436afbf1 100644 --- a/include/grub/script_sh.h +++ b/include/grub/script_sh.h @@ -106,6 +106,21 @@ struct grub_script_cmdif struct grub_script_cmd *exec_on_false; }; +/* A for statement. */ +struct grub_script_cmdfor +{ + struct grub_script_cmd cmd; + + /* The name used as looping variable. */ + struct grub_script_arg *name; + + /* The words loop iterates over. */ + struct grub_script_arglist *words; + + /* The command list executed in each loop. */ + struct grub_script_cmd *list; +}; + /* A menu entry generate statement. */ struct grub_script_cmd_menuentry { @@ -213,6 +228,12 @@ grub_script_create_cmdif (struct grub_parser_param *state, struct grub_script_cmd *exec_on_true, struct grub_script_cmd *exec_on_false); +struct grub_script_cmd * +grub_script_create_cmdfor (struct grub_parser_param *state, + struct grub_script_arg *name, + struct grub_script_arglist *words, + struct grub_script_cmd *list); + struct grub_script_cmd * grub_script_create_cmdmenu (struct grub_parser_param *state, struct grub_script_arglist *arglist, @@ -261,6 +282,7 @@ void grub_script_yyerror (struct grub_parser_param *, char const *); grub_err_t grub_script_execute_cmdline (struct grub_script_cmd *cmd); grub_err_t grub_script_execute_cmdblock (struct grub_script_cmd *cmd); grub_err_t grub_script_execute_cmdif (struct grub_script_cmd *cmd); +grub_err_t grub_script_execute_cmdfor (struct grub_script_cmd *cmd); grub_err_t grub_script_execute_menuentry (struct grub_script_cmd *cmd); /* Execute any GRUB pre-parsed command or script. */ diff --git a/script/execute.c b/script/execute.c index c956960da..aa6975fdd 100644 --- a/script/execute.c +++ b/script/execute.c @@ -282,6 +282,32 @@ grub_script_execute_cmdif (struct grub_script_cmd *cmd) return grub_script_execute_cmd (cmdif->exec_on_false); } +/* Execute a for statement. */ +grub_err_t +grub_script_execute_cmdfor (struct grub_script_cmd *cmd) +{ + int i; + int result; + char **args; + int argcount; + struct grub_script_cmdfor *cmdfor = (struct grub_script_cmdfor *) cmd; + + args = grub_script_execute_arglist_to_argv (cmdfor->words, &argcount); + if (!args) + return grub_errno; + + result = 0; + for (i = 0; i < argcount; i++) + { + grub_env_set (cmdfor->name->str, args[i]); + result = grub_script_execute_cmd (cmdfor->list); + grub_free (args[i]); + } + + grub_free (args); + return result; +} + /* Execute the menu entry generate statement. */ grub_err_t grub_script_execute_menuentry (struct grub_script_cmd *cmd) diff --git a/script/parser.y b/script/parser.y index b8d981866..26a6e3735 100644 --- a/script/parser.y +++ b/script/parser.y @@ -76,7 +76,7 @@ %token GRUB_PARSER_TOKEN_WORD "word" %type word argument arguments0 arguments1 -%type script_init script grubcmd ifcmd command +%type script_init script grubcmd ifcmd forcmd command %type commands1 menuentry statement %pure-parser @@ -175,6 +175,7 @@ grubcmd: word arguments0 /* A single command. */ command: grubcmd { $$ = $1; } | ifcmd { $$ = $1; } + | forcmd { $$ = $1; } ; /* A list of commands. */ @@ -238,3 +239,14 @@ ifcmd: if commands1 delimiters1 "then" commands1 delimiters1 "fi" grub_script_lexer_deref (state->lexerstate); } ; + +forcmd: "for" "name" + { + grub_script_lexer_ref (state->lexerstate); + } + "in" arguments0 delimiters1 "do" commands1 delimiters1 "done" + { + $$ = grub_script_create_cmdfor (state, $2, $5, $8); + grub_script_lexer_deref (state->lexerstate); + } +; diff --git a/script/script.c b/script/script.c index b2d870745..9142a8245 100644 --- a/script/script.c +++ b/script/script.c @@ -221,6 +221,30 @@ grub_script_create_cmdif (struct grub_parser_param *state, return (struct grub_script_cmd *) cmd; } +/* Create a command that functions as a for statement. */ +struct grub_script_cmd * +grub_script_create_cmdfor (struct grub_parser_param *state, + struct grub_script_arg *name, + struct grub_script_arglist *words, + struct grub_script_cmd *list) +{ + struct grub_script_cmdfor *cmd; + + grub_dprintf ("scripting", "cmdfor\n"); + + cmd = grub_script_malloc (state, sizeof (*cmd)); + if (! cmd) + return 0; + + cmd->cmd.exec = grub_script_execute_cmdfor; + cmd->cmd.next = 0; + cmd->name = name; + cmd->words = words; + cmd->list = list; + + return (struct grub_script_cmd *) cmd; +} + /* Create a command that adds a menu entry to the menu. Title is an argument that is parsed to generate a string that can be used as the title. The sourcecode for this entry is passed in SOURCECODE. diff --git a/tests/grub_script_for1.in b/tests/grub_script_for1.in new file mode 100644 index 000000000..e39a7664d --- /dev/null +++ b/tests/grub_script_for1.in @@ -0,0 +1,27 @@ +#! @builddir@/grub-shell-tester + +for x in one two 'three 3' "four 4" five six-6; do echo $x; done + +for x in one two 'three 3' "four 4" five six-6 +do + echo $x +done + +foo="1 2" +for x in ab${foo}cd; do echo $x; done +for x in "ab${foo}cd"; do echo $x; done + +a="one two three" +y=foo +echo $y +for y in $a; do + echo $y +done +echo $y + + +b="one two three" +for z in $b; do + echo $z +done +echo $z diff --git a/util/grub-script-check.c b/util/grub-script-check.c index 0ad24186d..3b3f5bd47 100644 --- a/util/grub-script-check.c +++ b/util/grub-script-check.c @@ -81,6 +81,12 @@ grub_script_execute_cmdif (struct grub_script_cmd *cmd __attribute__ ((unused))) return 0; } +grub_err_t +grub_script_execute_cmdfor (struct grub_script_cmd *cmd __attribute__ ((unused))) +{ + return 0; +} + grub_err_t grub_script_execute_menuentry (struct grub_script_cmd *cmd __attribute__ ((unused))) { From 10523df4781740c499113bed7f1827f627f82cbf Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Sat, 23 Jan 2010 11:19:26 +0530 Subject: [PATCH 282/738] while and until loops support --- include/grub/script_sh.h | 22 ++++++++++++++++++++++ script/execute.c | 20 ++++++++++++++++++++ script/parser.y | 35 ++++++++++++++++++++++++++++++----- script/script.c | 22 ++++++++++++++++++++++ util/grub-script-check.c | 6 ++++++ 5 files changed, 100 insertions(+), 5 deletions(-) diff --git a/include/grub/script_sh.h b/include/grub/script_sh.h index 4436afbf1..207b5fcbc 100644 --- a/include/grub/script_sh.h +++ b/include/grub/script_sh.h @@ -121,6 +121,21 @@ struct grub_script_cmdfor struct grub_script_cmd *list; }; +/* A while/until command. */ +struct grub_script_cmdwhile +{ + struct grub_script_cmd cmd; + + /* The command list used as condition. */ + struct grub_script_cmd *cond; + + /* The command list executed in each loop. */ + struct grub_script_cmd *list; + + /* The flag to indicate this as "until" loop. */ + int until; +}; + /* A menu entry generate statement. */ struct grub_script_cmd_menuentry { @@ -234,6 +249,12 @@ grub_script_create_cmdfor (struct grub_parser_param *state, struct grub_script_arglist *words, struct grub_script_cmd *list); +struct grub_script_cmd * +grub_script_create_cmdwhile (struct grub_parser_param *state, + struct grub_script_cmd *cond, + struct grub_script_cmd *list, + int is_an_until_loop); + struct grub_script_cmd * grub_script_create_cmdmenu (struct grub_parser_param *state, struct grub_script_arglist *arglist, @@ -283,6 +304,7 @@ grub_err_t grub_script_execute_cmdline (struct grub_script_cmd *cmd); grub_err_t grub_script_execute_cmdblock (struct grub_script_cmd *cmd); grub_err_t grub_script_execute_cmdif (struct grub_script_cmd *cmd); grub_err_t grub_script_execute_cmdfor (struct grub_script_cmd *cmd); +grub_err_t grub_script_execute_cmdwhile (struct grub_script_cmd *cmd); grub_err_t grub_script_execute_menuentry (struct grub_script_cmd *cmd); /* Execute any GRUB pre-parsed command or script. */ diff --git a/script/execute.c b/script/execute.c index aa6975fdd..b905de46f 100644 --- a/script/execute.c +++ b/script/execute.c @@ -308,6 +308,26 @@ grub_script_execute_cmdfor (struct grub_script_cmd *cmd) return result; } +/* Execute a "while" or "until" command. */ +grub_err_t +grub_script_execute_cmdwhile (struct grub_script_cmd *cmd) +{ + int cond; + int result; + struct grub_script_cmdwhile *cmdwhile = (struct grub_script_cmdwhile *) cmd; + + result = 0; + do { + cond = grub_script_execute_cmd (cmdwhile->cond); + if ((cmdwhile->until && !cond) || (!cmdwhile->until && cond)) + break; + + result = grub_script_execute_cmd (cmdwhile->list); + } while (1); /* XXX Put a check for ^C here */ + + return result; +} + /* Execute the menu entry generate statement. */ grub_err_t grub_script_execute_menuentry (struct grub_script_cmd *cmd) diff --git a/script/parser.y b/script/parser.y index 26a6e3735..4d22ae400 100644 --- a/script/parser.y +++ b/script/parser.y @@ -76,8 +76,9 @@ %token GRUB_PARSER_TOKEN_WORD "word" %type word argument arguments0 arguments1 -%type script_init script grubcmd ifcmd forcmd command -%type commands1 menuentry statement +%type script_init script +%type grubcmd ifcmd forcmd whilecmd untilcmd +%type command commands1 menuentry statement %pure-parser %lex-param { struct grub_parser_param *state }; @@ -173,9 +174,11 @@ grubcmd: word arguments0 ; /* A single command. */ -command: grubcmd { $$ = $1; } - | ifcmd { $$ = $1; } - | forcmd { $$ = $1; } +command: grubcmd { $$ = $1; } + | ifcmd { $$ = $1; } + | forcmd { $$ = $1; } + | whilecmd { $$ = $1; } + | untilcmd { $$ = $1; } ; /* A list of commands. */ @@ -250,3 +253,25 @@ forcmd: "for" "name" grub_script_lexer_deref (state->lexerstate); } ; + +whilecmd: "while" + { + grub_script_lexer_ref (state->lexerstate); + } + commands1 delimiters1 "do" commands1 delimiters1 "done" + { + $$ = grub_script_create_cmdwhile (state, $3, $6, 0); + grub_script_lexer_deref (state->lexerstate); + } +; + +untilcmd: "until" + { + grub_script_lexer_ref (state->lexerstate); + } + commands1 delimiters1 "do" commands1 delimiters1 "done" + { + $$ = grub_script_create_cmdwhile (state, $3, $6, 1); + grub_script_lexer_deref (state->lexerstate); + } +; diff --git a/script/script.c b/script/script.c index 9142a8245..4c87d9491 100644 --- a/script/script.c +++ b/script/script.c @@ -245,6 +245,28 @@ grub_script_create_cmdfor (struct grub_parser_param *state, return (struct grub_script_cmd *) cmd; } +/* Create a "while" or "until" command. */ +struct grub_script_cmd * +grub_script_create_cmdwhile (struct grub_parser_param *state, + struct grub_script_cmd *cond, + struct grub_script_cmd *list, + int is_an_until_loop) +{ + struct grub_script_cmdwhile *cmd; + + cmd = grub_script_malloc (state, sizeof (*cmd)); + if (! cmd) + return 0; + + cmd->cmd.exec = grub_script_execute_cmdwhile; + cmd->cmd.next = 0; + cmd->cond = cond; + cmd->list = list; + cmd->until = is_an_until_loop; + + return (struct grub_script_cmd *) cmd; +} + /* Create a command that adds a menu entry to the menu. Title is an argument that is parsed to generate a string that can be used as the title. The sourcecode for this entry is passed in SOURCECODE. diff --git a/util/grub-script-check.c b/util/grub-script-check.c index 3b3f5bd47..eb11988e3 100644 --- a/util/grub-script-check.c +++ b/util/grub-script-check.c @@ -87,6 +87,12 @@ grub_script_execute_cmdfor (struct grub_script_cmd *cmd __attribute__ ((unused)) return 0; } +grub_err_t +grub_script_execute_cmdwhile (struct grub_script_cmd *cmd __attribute__ ((unused))) +{ + return 0; +} + grub_err_t grub_script_execute_menuentry (struct grub_script_cmd *cmd __attribute__ ((unused))) { From f4c499f86f3ea8e3e3cedbc70ca53e15c480725d Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Sat, 23 Jan 2010 19:46:28 +0530 Subject: [PATCH 283/738] replaced magic numbers with macros --- script/execute.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/script/execute.c b/script/execute.c index c956960da..d42918f50 100644 --- a/script/execute.c +++ b/script/execute.c @@ -35,6 +35,9 @@ grub_script_execute_cmd (struct grub_script_cmd *cmd) return cmd->exec (cmd); } +#define ARG_ALLOCATION_UNIT (32 * sizeof (char)) +#define ARGV_ALLOCATION_UNIT (8 * sizeof (void*)) + /* Expand arguments in ARGLIST into multiple arguments. */ char ** grub_script_execute_arglist_to_argv (struct grub_script_arglist *arglist, int *count) @@ -56,7 +59,7 @@ grub_script_execute_arglist_to_argv (struct grub_script_arglist *arglist, int *c if (oom) return; - p = grub_realloc (argv, ALIGN_UP (sizeof(char*) * (argc + 1), 32)); + p = grub_realloc (argv, ALIGN_UP (sizeof(char*) * (argc + 1), ARGV_ALLOCATION_UNIT)); if (!p) oom = 1; else @@ -78,7 +81,7 @@ grub_script_execute_arglist_to_argv (struct grub_script_arglist *arglist, int *c len = nchar ?: grub_strlen (str); old = argv[argc - 1] ? grub_strlen (argv[argc - 1]) : 0; - p = grub_realloc (argv[argc - 1], ALIGN_UP(old + len + 1, 32)); + p = grub_realloc (argv[argc - 1], ALIGN_UP(old + len + 1, ARG_ALLOCATION_UNIT)); if (p) { From fc9e58104a1a99e0bc2956a77b365820d035fb39 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Sat, 23 Jan 2010 22:38:10 +0530 Subject: [PATCH 284/738] fix underquoted AC_DEFUN parameters --- ChangeLog | 4 ++++ acinclude.m4 | 32 ++++++++++++++++---------------- 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/ChangeLog b/ChangeLog index d700466fa..9bb6b1c01 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-01-23 BVK Chaitanya + + * acinclude.m4: Quote underquoted AC_DEFUN parameters. + 2010-01-22 Vladimir Serbinenko * term/ieee1275/ofconsole.c (grub_ofconsole_setcolorstate): Allocate on diff --git a/acinclude.m4 b/acinclude.m4 index 36a3b3e08..692404e20 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -14,7 +14,7 @@ $2 dnl Check whether target compiler is working -AC_DEFUN(grub_PROG_TARGET_CC, +AC_DEFUN([grub_PROG_TARGET_CC], [AC_MSG_CHECKING([whether target compiler is working]) AC_CACHE_VAL(grub_cv_prog_target_cc, [AC_LINK_IFELSE([AC_LANG_PROGRAM([[ @@ -36,7 +36,7 @@ dnl grub_ASM_USCORE checks if C symbols get an underscore after dnl compiling to assembler. dnl Written by Pavel Roskin. Based on grub_ASM_EXT_C written by dnl Erich Boleyn and modified by Yoshinori K. Okuji. -AC_DEFUN(grub_ASM_USCORE, +AC_DEFUN([grub_ASM_USCORE], [AC_REQUIRE([AC_PROG_CC]) AC_MSG_CHECKING([if C symbols get an underscore after compilation]) AC_CACHE_VAL(grub_cv_asm_uscore, @@ -75,7 +75,7 @@ AC_MSG_RESULT([$grub_cv_asm_uscore]) dnl Some versions of `objcopy -O binary' vary their output depending dnl on the link address. -AC_DEFUN(grub_PROG_OBJCOPY_ABSOLUTE, +AC_DEFUN([grub_PROG_OBJCOPY_ABSOLUTE], [AC_MSG_CHECKING([whether ${OBJCOPY} works for absolute addresses]) AC_CACHE_VAL(grub_cv_prog_objcopy_absolute, [cat > conftest.c <<\EOF @@ -119,7 +119,7 @@ fi dnl Supply --build-id=none to ld if building modules. dnl This suppresses warnings from ld on some systems -AC_DEFUN(grub_PROG_LD_BUILD_ID_NONE, +AC_DEFUN([grub_PROG_LD_BUILD_ID_NONE], [AC_MSG_CHECKING([whether linker accepts --build-id=none]) AC_CACHE_VAL(grub_cv_prog_ld_build_id_none, [save_LDFLAGS="$LDFLAGS" @@ -150,7 +150,7 @@ dnl dnl We only support the newer versions, because the old versions cause dnl major pain, by requiring manual assembly to get 16-bit instructions into dnl asm files. -AC_DEFUN(grub_I386_ASM_ADDR32, +AC_DEFUN([grub_I386_ASM_ADDR32], [AC_REQUIRE([AC_PROG_CC]) AC_REQUIRE([grub_I386_ASM_PREFIX_REQUIREMENT]) AC_MSG_CHECKING([for .code16 addr32 assembler support]) @@ -178,7 +178,7 @@ AC_MSG_RESULT([$grub_cv_i386_asm_addr32])]) dnl check if our compiler is apple cc dnl because it requires numerous workarounds -AC_DEFUN(grub_apple_cc, +AC_DEFUN([grub_apple_cc], [AC_REQUIRE([AC_PROG_CC]) AC_MSG_CHECKING([whether our compiler is apple cc]) AC_CACHE_VAL(grub_cv_apple_cc, @@ -193,7 +193,7 @@ AC_MSG_RESULT([$grub_cv_apple_cc])]) dnl check if our target compiler is apple cc dnl because it requires numerous workarounds -AC_DEFUN(grub_apple_target_cc, +AC_DEFUN([grub_apple_target_cc], [AC_REQUIRE([AC_PROG_CC]) AC_MSG_CHECKING([whether our target compiler is apple cc]) AC_CACHE_VAL(grub_cv_apple_target_cc, @@ -210,7 +210,7 @@ AC_MSG_RESULT([$grub_cv_apple_target_cc])]) dnl Later versions of GAS requires that addr32 and data32 prefixes dnl appear in the same lines as the instructions they modify, while dnl earlier versions requires that they appear in separate lines. -AC_DEFUN(grub_I386_ASM_PREFIX_REQUIREMENT, +AC_DEFUN([grub_I386_ASM_PREFIX_REQUIREMENT], [AC_REQUIRE([AC_PROG_CC]) AC_MSG_CHECKING(dnl [whether addr32 must be in the same line as the instruction]) @@ -246,7 +246,7 @@ AC_MSG_RESULT([$grub_cv_i386_asm_prefix_requirement])]) dnl Older versions of GAS require that absolute indirect calls/jumps are dnl not prefixed with `*', while later versions warn if not prefixed. -AC_DEFUN(grub_I386_ASM_ABSOLUTE_WITHOUT_ASTERISK, +AC_DEFUN([grub_I386_ASM_ABSOLUTE_WITHOUT_ASTERISK], [AC_REQUIRE([AC_PROG_CC]) AC_MSG_CHECKING(dnl [whether an absolute indirect call/jump must not be prefixed with an asterisk]) @@ -276,7 +276,7 @@ AC_MSG_RESULT([$grub_cv_i386_asm_absolute_without_asterisk])]) dnl Check what symbol is defined as a bss start symbol. dnl Written by Michael Hohmoth and Yoshinori K. Okuji. -AC_DEFUN(grub_CHECK_BSS_START_SYMBOL, +AC_DEFUN([grub_CHECK_BSS_START_SYMBOL], [AC_REQUIRE([AC_PROG_CC]) AC_MSG_CHECKING([if __bss_start is defined by the compiler]) AC_CACHE_VAL(grub_cv_check_uscore_uscore_bss_start_symbol, @@ -320,7 +320,7 @@ fi dnl Check what symbol is defined as an end symbol. dnl Written by Yoshinori K. Okuji. -AC_DEFUN(grub_CHECK_END_SYMBOL, +AC_DEFUN([grub_CHECK_END_SYMBOL], [AC_REQUIRE([AC_PROG_CC]) AC_MSG_CHECKING([if end is defined by the compiler]) AC_CACHE_VAL(grub_cv_check_end_symbol, @@ -352,7 +352,7 @@ fi ]) dnl Check if the C compiler generates calls to `__enable_execute_stack()'. -AC_DEFUN(grub_CHECK_ENABLE_EXECUTE_STACK,[ +AC_DEFUN([grub_CHECK_ENABLE_EXECUTE_STACK],[ AC_MSG_CHECKING([whether `$CC' generates calls to `__enable_execute_stack()']) AC_LANG_CONFTEST([[ void f (int (*p) (void)); @@ -379,7 +379,7 @@ rm -f conftest* dnl Check if the C compiler supports `-fstack-protector'. -AC_DEFUN(grub_CHECK_STACK_PROTECTOR,[ +AC_DEFUN([grub_CHECK_STACK_PROTECTOR],[ [# Smashing stack protector. ssp_possible=yes] AC_MSG_CHECKING([whether `$CC' accepts `-fstack-protector']) @@ -398,7 +398,7 @@ else ]) dnl Check if the C compiler supports `-mstack-arg-probe' (Cygwin). -AC_DEFUN(grub_CHECK_STACK_ARG_PROBE,[ +AC_DEFUN([grub_CHECK_STACK_ARG_PROBE],[ [# Smashing stack arg probe. sap_possible=yes] AC_MSG_CHECKING([whether `$CC' accepts `-mstack-arg-probe']) @@ -414,7 +414,7 @@ else ]) dnl Check if ln can handle directories properly (mingw). -AC_DEFUN(grub_CHECK_LINK_DIR,[ +AC_DEFUN([grub_CHECK_LINK_DIR],[ AC_MSG_CHECKING([whether ln can handle directories properly]) [mkdir testdir 2>/dev/null case $srcdir in @@ -432,7 +432,7 @@ rm -rf testdir] ]) dnl Check if the C compiler supports `-fPIE'. -AC_DEFUN(grub_CHECK_PIE,[ +AC_DEFUN([grub_CHECK_PIE],[ [# Position independent executable. pie_possible=yes] AC_MSG_CHECKING([whether `$CC' has `-fPIE' as default]) From 69be5b74be62f112d9e4afc10c1ede8c42cb502c Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 23 Jan 2010 22:56:08 +0100 Subject: [PATCH 285/738] 2010-01-23 Vladimir Serbinenko * configure.ac: Check for libgcc symbols with -nostdlib. --- ChangeLog | 4 ++++ configure.ac | 17 ++++++++++++----- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9bb6b1c01..cec7af8a5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-01-23 Vladimir Serbinenko + + * configure.ac: Check for libgcc symbols with -nostdlib. + 2010-01-23 BVK Chaitanya * acinclude.m4: Quote underquoted AC_DEFUN parameters. diff --git a/configure.ac b/configure.ac index f621b5648..012aef96e 100644 --- a/configure.ac +++ b/configure.ac @@ -438,18 +438,25 @@ AC_SUBST(TARGET_ASFLAGS) AC_SUBST(TARGET_CPPFLAGS) AC_SUBST(TARGET_LDFLAGS) -# Check for libgcc symbols (must be performed before we add -nostdlib to LDFLAGS) -AC_CHECK_FUNCS(__bswapsi2 __bswapdi2 __ashldi3 __ashrdi3 __lshrdi3 __trampoline_setup __ucmpdi2 _restgpr_14_x) - # Set them to their new values for the tests below. CC="$TARGET_CC" +if test "x$TARGET_APPLE_CC" = x1 ; then +CFLAGS="$TARGET_CFLAGS -nostdlib -Wno-error" +else +CFLAGS="$TARGET_CFLAGS -nostdlib -Wl,--defsym,___main=0x8100 -Wl,--defsym,abort=main -Wno-error" +fi +CPPFLAGS="$TARGET_CPPFLAGS" +LDFLAGS="$TARGET_LDFLAGS" +LIBS=-lgcc + +# Check for libgcc symbols +AC_CHECK_FUNCS(__bswapsi2 __bswapdi2 __ashldi3 __ashrdi3 __lshrdi3 __trampoline_setup __ucmpdi2 _restgpr_14_x) + if test "x$TARGET_APPLE_CC" = x1 ; then CFLAGS="$TARGET_CFLAGS -nostdlib" else CFLAGS="$TARGET_CFLAGS -nostdlib -Wl,--defsym,___main=0x8100" fi -CPPFLAGS="$TARGET_CPPFLAGS" -LDFLAGS="$TARGET_LDFLAGS" # Defined in aclocal.m4. grub_PROG_TARGET_CC From c273d4cea97158122d3eb9baad6497efac8e9126 Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Sun, 24 Jan 2010 14:30:10 +0100 Subject: [PATCH 286/738] 2010-01-24 Samuel Thibault * util/grub.d/10_hurd.in: Add a recovery mode. --- ChangeLog | 4 ++++ util/grub.d/10_hurd.in | 22 ++++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/ChangeLog b/ChangeLog index cec7af8a5..ee582693f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-01-24 Samuel Thibault + + * util/grub.d/10_hurd.in: Add a recovery mode. + 2010-01-23 Vladimir Serbinenko * configure.ac: Check for libgcc symbols with -nostdlib. diff --git a/util/grub.d/10_hurd.in b/util/grub.d/10_hurd.in index 65a9a70b1..8c9060932 100644 --- a/util/grub.d/10_hurd.in +++ b/util/grub.d/10_hurd.in @@ -89,3 +89,25 @@ cat << EOF module /lib/ld.so.1 exec /hurd/exec '\$(exec-task=task-create)' } EOF + +cat << EOF +menuentry "${OS} (recovery mode)" { +EOF +prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/" +cat << EOF + echo $(gettext "Loading GNU Mach ...") + multiboot ${kernel} root=device:${GRUB_DEVICE#/dev/} -s +EOF +save_default_entry | sed -e "s/^/\t/" +prepare_grub_to_access_device ${GRUB_DEVICE} | sed -e "s/^/\t/" +cat << EOF + echo $(gettext "Loading the Hurd ...") + module /hurd/${hurd_fs}.static ${hurd_fs} \\ + --multiboot-command-line='\${kernel-command-line}' \\ + --host-priv-port='\${host-port}' \\ + --device-master-port='\${device-port}' \\ + --exec-server-task='\${exec-task}' -T typed '\${root}' \\ + '\$(task-create)' '\$(task-resume)' + module /lib/ld.so.1 exec /hurd/exec '\$(exec-task=task-create)' +} +EOF From 67951a534f282c5463cb0274f4ec14d38a91eff7 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Sun, 24 Jan 2010 21:04:29 +0000 Subject: [PATCH 287/738] 2010-01-24 Robert Millan * loader/mips/linux.c (grub_cmd_linux, grub_cmd_initrd): Don't capitalize error strings. --- ChangeLog | 5 +++++ loader/mips/linux.c | 12 ++++++------ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index ee582693f..7367d9679 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-01-24 Robert Millan + + * loader/mips/linux.c (grub_cmd_linux, grub_cmd_initrd): Don't + capitalize error strings. + 2010-01-24 Samuel Thibault * util/grub.d/10_hurd.in: Add a recovery mode. diff --git a/loader/mips/linux.c b/loader/mips/linux.c index 51060c4fb..64497f466 100644 --- a/loader/mips/linux.c +++ b/loader/mips/linux.c @@ -196,7 +196,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), { grub_elf_close (elf); return grub_error (GRUB_ERR_UNKNOWN_OS, - "This ELF file is not of the right type\n"); + "this ELF file is not of the right type\n"); } /* Release the previously used memory. */ @@ -236,7 +236,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), if (grub_elf_is_elf64 (elf)) err = grub_linux_load64 (elf, &extra, size); else - err = grub_error (GRUB_ERR_BAD_FILE_TYPE, "Unknown ELF class"); + err = grub_error (GRUB_ERR_BAD_FILE_TYPE, "unknown ELF class"); grub_elf_close (elf); @@ -325,13 +325,13 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), grub_size_t overhead; if (argc == 0) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "No initrd specified"); + return grub_error (GRUB_ERR_BAD_ARGUMENT, "no initrd specified"); if (!loaded) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "You need to load Linux first."); + return grub_error (GRUB_ERR_BAD_ARGUMENT, "you need to load Linux first."); if (initrd_loaded) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "Only one initrd can be loaded."); + return grub_error (GRUB_ERR_BAD_ARGUMENT, "only one initrd can be loaded."); file = grub_file_open (argv[0]); if (! file) @@ -353,7 +353,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), if (grub_file_read (file, playground + linux_size + overhead, size) != size) { - grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file"); + grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file"); grub_file_close (file); return grub_errno; From ea4a7e35ebb262325dc194832530ae9bc4f30184 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Sutre?= Date: Mon, 25 Jan 2010 10:06:55 +0100 Subject: [PATCH 288/738] =?UTF-8?q?2010-01-25=20=20Gr=C3=A9goire=20Sutre?= =?UTF-8?q?=20=20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * configure.ac: Check for `limits.h'. * util/misc.c: Include `' (for PATH_MAX). --- ChangeLog | 5 +++++ configure.ac | 2 +- util/misc.c | 3 +++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 7367d9679..ab11ad50f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-01-25 Grégoire Sutre + + * configure.ac: Check for `limits.h'. + * util/misc.c: Include `' (for PATH_MAX). + 2010-01-24 Robert Millan * loader/mips/linux.c (grub_cmd_linux, grub_cmd_initrd): Don't diff --git a/configure.ac b/configure.ac index 012aef96e..be498be8b 100644 --- a/configure.ac +++ b/configure.ac @@ -221,7 +221,7 @@ AC_HEADER_MAJOR AC_HEADER_DIRENT AC_CHECK_FUNCS(memmove sbrk strdup lstat getuid getgid) AC_CHECK_HEADERS(sys/mkdev.h sys/sysmacros.h malloc.h termios.h sys/types.h) -AC_CHECK_HEADERS(unistd.h string.h strings.h sys/stat.h sys/fcntl.h) +AC_CHECK_HEADERS(unistd.h string.h strings.h sys/stat.h sys/fcntl.h limits.h) # # Check for target programs. diff --git a/util/misc.c b/util/misc.c index 8f66e4350..371e7cc14 100644 --- a/util/misc.c +++ b/util/misc.c @@ -30,6 +30,9 @@ #include #include #include +#ifdef HAVE_LIMITS_H +#include +#endif #include #include From 37effddaf3687c8099669b38d9d2fbaa79076bac Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Mon, 25 Jan 2010 22:01:14 +0530 Subject: [PATCH 289/738] make parenthesis as valid word characters --- ChangeLog.lexer-rewrite | 5 +++++ script/parser.y | 2 -- script/yylex.l | 4 +--- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/ChangeLog.lexer-rewrite b/ChangeLog.lexer-rewrite index 56c637976..9b2ab9e2f 100644 --- a/ChangeLog.lexer-rewrite +++ b/ChangeLog.lexer-rewrite @@ -1,3 +1,8 @@ +2010-01-25 BVK Chaitanya + + * script/yylex.l: Accept parenthesis as part of word. + * script/parser.y: Remove GRUB_PARSER_TOKEN_{LPAR,RPAR} tokens. + 2010-01-10 BVK Chaitanya * conf/any-emu.rmk: Build rule updates. diff --git a/script/parser.y b/script/parser.y index b8d981866..baf1fd9b5 100644 --- a/script/parser.y +++ b/script/parser.y @@ -45,8 +45,6 @@ %token GRUB_PARSER_TOKEN_PIPE "|" %token GRUB_PARSER_TOKEN_AMP "&" %token GRUB_PARSER_TOKEN_SEMI ";" -%token GRUB_PARSER_TOKEN_LPAR "(" -%token GRUB_PARSER_TOKEN_RPAR ")" %token GRUB_PARSER_TOKEN_LBR "{" %token GRUB_PARSER_TOKEN_RBR "}" %token GRUB_PARSER_TOKEN_NOT "!" diff --git a/script/yylex.l b/script/yylex.l index 7cef8496b..db276ef61 100644 --- a/script/yylex.l +++ b/script/yylex.l @@ -128,7 +128,7 @@ typedef grub_size_t yy_size_t; BLANK [ \t] COMMENT ^[ \t]*#.*$ -CHAR [^|&$;()<> \t\n\'\"\\] +CHAR [^|&$;<> \t\n\'\"\\] DIGITS [[:digit:]]+ NAME [[:alpha:]_][[:alnum:][:digit:]_]* @@ -157,8 +157,6 @@ WORD ({CHAR}|{DQSTR}|{SQSTR}|{ESC}|{VARIABLE})+ "|" { RECORD; return GRUB_PARSER_TOKEN_PIPE; } "&" { RECORD; return GRUB_PARSER_TOKEN_AMP; } ";" { RECORD; return GRUB_PARSER_TOKEN_SEMI; } -"(" { RECORD; return GRUB_PARSER_TOKEN_LPAR; } -")" { RECORD; return GRUB_PARSER_TOKEN_RPAR; } "<" { RECORD; return GRUB_PARSER_TOKEN_LT; } ">" { RECORD; return GRUB_PARSER_TOKEN_GT; } From 847effd8bf38e04839db3b673f7827f4bd781de0 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 25 Jan 2010 17:04:22 +0000 Subject: [PATCH 290/738] 2010-01-25 Colin Watson * util/hostdisk.c (open_device): Add trailing newline to debug message. --- ChangeLog | 5 +++++ util/hostdisk.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index ab11ad50f..12b7ccb31 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-01-25 Colin Watson + + * util/hostdisk.c (open_device): Add trailing newline to debug + message. + 2010-01-25 Grégoire Sutre * configure.ac: Check for `limits.h'. diff --git a/util/hostdisk.c b/util/hostdisk.c index 603445801..a594f75ec 100644 --- a/util/hostdisk.c +++ b/util/hostdisk.c @@ -340,7 +340,7 @@ open_device (const grub_disk_t disk, grub_disk_addr_t sector, int flags) is_partition = linux_find_partition (dev, disk->partition->start); /* Open the partition. */ - grub_dprintf ("hostdisk", "opening the device `%s' in open_device()", dev); + grub_dprintf ("hostdisk", "opening the device `%s' in open_device()\n", dev); fd = open (dev, flags); if (fd < 0) { From 7181e2281f559317133fa9e3c5924451872061fd Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 25 Jan 2010 17:47:51 +0000 Subject: [PATCH 291/738] 2010-01-25 Colin Watson * configure.ac: Check for Linux device-mapper support. * util/hostdisk.c (device_is_mapped): New function. (find_partition_start): New function, partly broken out from linux_find_partition and grub_util_biosdisk_get_grub_dev but with device-mapper support added. (linux_find_partition): Use find_partition_start. (convert_system_partition_to_system_disk): Add `st' argument. Support Linux /dev/mapper/* devices if device-mapper support is available; only DM-RAID devices are understood at present. (find_system_device): Add `st' argument. Pass it to convert_system_partition_to_system_disk. (grub_util_biosdisk_get_grub_dev): Pass stat result to find_system_device and convert_system_partition_to_system_disk. Use find_partition_start. --- ChangeLog.dmraid-probe | 16 +++ configure.ac | 17 +++ util/hostdisk.c | 243 +++++++++++++++++++++++++++++++++++------ 3 files changed, 242 insertions(+), 34 deletions(-) create mode 100644 ChangeLog.dmraid-probe diff --git a/ChangeLog.dmraid-probe b/ChangeLog.dmraid-probe new file mode 100644 index 000000000..8b8f25533 --- /dev/null +++ b/ChangeLog.dmraid-probe @@ -0,0 +1,16 @@ +2010-01-25 Colin Watson + + * configure.ac: Check for Linux device-mapper support. + * util/hostdisk.c (device_is_mapped): New function. + (find_partition_start): New function, partly broken out from + linux_find_partition and grub_util_biosdisk_get_grub_dev but with + device-mapper support added. + (linux_find_partition): Use find_partition_start. + (convert_system_partition_to_system_disk): Add `st' argument. + Support Linux /dev/mapper/* devices if device-mapper support is + available; only DM-RAID devices are understood at present. + (find_system_device): Add `st' argument. Pass it to + convert_system_partition_to_system_disk. + (grub_util_biosdisk_get_grub_dev): Pass stat result to + find_system_device and convert_system_partition_to_system_disk. Use + find_partition_start. diff --git a/configure.ac b/configure.ac index be498be8b..4f1a6dffe 100644 --- a/configure.ac +++ b/configure.ac @@ -659,6 +659,23 @@ AC_SUBST([enable_grub_mkfont]) AC_SUBST([freetype_cflags]) AC_SUBST([freetype_libs]) +AC_ARG_ENABLE([device-mapper], + [AS_HELP_STRING([--enable-device-mapper], + [enable Linux device-mapper support (default=guessed)])]) +if test x"$enable_device_mapper" = xno ; then + device_mapper_excuse="explicitly disabled" +fi + +if test x"$device_mapper_excuse" = x ; then + # Check for device-mapper library. + AC_CHECK_LIB([devmapper], [dm_task_create], + [LDFLAGS="$LDFLAGS -ldevmapper" + AC_DEFINE([HAVE_DEVICE_MAPPER], [1], + [Define to 1 if you have the devmapper library.])], + [device_mapper_excuse="need devmapper library"]) + AC_SUBST([LIBDEVMAPPER]) +fi + AC_SUBST(ASFLAGS) # Output files. diff --git a/util/hostdisk.c b/util/hostdisk.c index a594f75ec..309e112bf 100644 --- a/util/hostdisk.c +++ b/util/hostdisk.c @@ -97,6 +97,10 @@ struct hd_geometry # include #endif +#ifdef HAVE_DEVICE_MAPPER +# include +#endif + struct { char *drive; @@ -253,6 +257,115 @@ grub_util_biosdisk_open (const char *name, grub_disk_t disk) return GRUB_ERR_NONE; } +#ifdef HAVE_DEVICE_MAPPER +static int +device_is_mapped (const char *dev) +{ + struct stat st; + + if (stat (dev, &st) < 0) + return 0; + + return dm_is_dm_major (major (st.st_rdev)); +} +#endif /* HAVE_DEVICE_MAPPER */ + +#if defined(__linux__) || defined(__CYGWIN__) +static grub_disk_addr_t +find_partition_start (const char *dev) +{ + int fd; + struct hd_geometry hdg; + +#ifdef HAVE_DEVICE_MAPPER + if (device_is_mapped (dev)) { + struct dm_task *task = NULL; + grub_uint64_t start, length; + char *target_type, *params, *space; + grub_disk_addr_t partition_start; + + /* If any device-mapper operation fails, we fall back silently to + HDIO_GETGEO. */ + task = dm_task_create (DM_DEVICE_TABLE); + if (! task) + { + grub_dprintf ("hostdisk", "dm_task_create failed\n"); + goto devmapper_fail; + } + + if (! dm_task_set_name (task, dev)) + { + grub_dprintf ("hostdisk", "dm_task_set_name failed\n"); + goto devmapper_fail; + } + + if (! dm_task_run (task)) + { + grub_dprintf ("hostdisk", "dm_task_run failed\n"); + goto devmapper_fail; + } + + dm_get_next_target (task, NULL, &start, &length, &target_type, ¶ms); + if (! target_type) + { + grub_dprintf ("hostdisk", "no dm target\n"); + goto devmapper_fail; + } + if (strcmp (target_type, "linear") != 0) + { + grub_dprintf ("hostdisk", "ignoring dm target %s (not linear)\n", + target_type); + goto devmapper_fail; + } + if (! params) + { + grub_dprintf ("hostdisk", "no dm params\n"); + goto devmapper_fail; + } + + /* The params string for a linear target looks like this: + DEVICE-NAME START-SECTOR + Parse this out. */ + space = strchr (params, ' '); + if (! space) + goto devmapper_fail; + errno = 0; + partition_start = strtoull (space + 1, NULL, 10); + if (errno == 0) + { + grub_dprintf ("hostdisk", "dm %s starts at %llu\n", + dev, partition_start); + dm_task_destroy (task); + return partition_start; + } + +devmapper_fail: + if (task) + dm_task_destroy (task); + } +#endif /* HAVE_DEVICE_MAPPER */ + + fd = open (dev, O_RDONLY); + if (fd == -1) + { + grub_error (GRUB_ERR_BAD_DEVICE, "cannot open `%s' while attempting to get disk geometry", dev); + return 0; + } + + if (ioctl (fd, HDIO_GETGEO, &hdg)) + { + grub_error (GRUB_ERR_BAD_DEVICE, + "cannot get geometry of `%s'", dev); + close (fd); + return 0; + } + + close (fd); + + return hdg.start; +} +#endif /* __linux__ || __CYGWIN__ */ + #ifdef __linux__ static int linux_find_partition (char *dev, unsigned long sector) @@ -284,22 +397,20 @@ linux_find_partition (char *dev, unsigned long sector) for (i = 1; i < 10000; i++) { int fd; - struct hd_geometry hdg; + grub_disk_addr_t start; sprintf (p, format, i); + fd = open (real_dev, O_RDONLY); if (fd == -1) return 0; - - if (ioctl (fd, HDIO_GETGEO, &hdg)) - { - close (fd); - return 0; - } - close (fd); - if (hdg.start == sector) + start = find_partition_start (real_dev); + /* We don't care about errors here. */ + grub_errno = GRUB_ERR_NONE; + + if (start == sector) { strcpy (dev, real_dev); return 1; @@ -699,7 +810,7 @@ make_device_name (int drive, int dos_part, int bsd_part) } static char * -convert_system_partition_to_system_disk (const char *os_dev) +convert_system_partition_to_system_disk (const char *os_dev, struct stat *st) { #if defined(__linux__) char *path = xmalloc (PATH_MAX); @@ -817,6 +928,83 @@ convert_system_partition_to_system_disk (const char *os_dev) p[4] = '\0'; return path; } + +#ifdef HAVE_DEVICE_MAPPER + /* If this is a DM-RAID device. */ + if ((strncmp ("mapper/", p, 7) == 0)) + { + static struct dm_tree *tree = NULL; + uint32_t maj, min; + struct dm_tree_node *node, *child; + void *handle; + const char *node_uuid, *child_uuid, *child_name; + + if (! tree) + tree = dm_tree_create (); + + if (! tree) + { + grub_dprintf ("hostdisk", "dm_tree_create failed\n"); + return NULL; + } + + maj = major (st->st_rdev); + min = minor (st->st_rdev); + if (! dm_tree_add_dev (tree, maj, min)) + { + grub_dprintf ("hostdisk", "dm_tree_add_dev failed\n"); + return NULL; + } + + node = dm_tree_find_node (tree, maj, min); + if (! node) + { + grub_dprintf ("hostdisk", "dm_tree_find_node failed\n"); + return NULL; + } + node_uuid = dm_tree_node_get_uuid (node); + if (! node_uuid) + { + grub_dprintf ("hostdisk", "%s has no DM uuid\n", path); + return NULL; + } + else if (strncmp (node_uuid, "DMRAID-", 7) != 0) + { + grub_dprintf ("hostdisk", "%s is not DM-RAID\n", path); + return NULL; + } + + handle = NULL; + /* Counter-intuitively, device-mapper refers to the disk-like + device containing a DM-RAID partition device as a "child" of + the partition device. */ + child = dm_tree_next_child (&handle, node, 0); + if (! child) + { + grub_dprintf ("hostdisk", "%s has no DM children\n", path); + return NULL; + } + child_uuid = dm_tree_node_get_uuid (child); + if (! child_uuid) + { + grub_dprintf ("hostdisk", "%s child has no DM uuid\n", path); + return NULL; + } + else if (strncmp (child_uuid, "DMRAID-", 7) != 0) + { + grub_dprintf ("hostdisk", "%s child is not DM-RAID\n", path); + return NULL; + } + child_name = dm_tree_node_get_name (child); + if (! child_name) + { + grub_dprintf ("hostdisk", "%s child has no DM name\n", path); + return NULL; + } + + return xasprintf ("/dev/mapper/%s", child_name); + } +#endif /* HAVE_DEVICE_MAPPER */ } return path; @@ -872,12 +1060,12 @@ device_is_wholedisk (const char *os_dev) #endif static int -find_system_device (const char *os_dev) +find_system_device (const char *os_dev, struct stat *st) { unsigned int i; char *os_disk; - os_disk = convert_system_partition_to_system_disk (os_dev); + os_disk = convert_system_partition_to_system_disk (os_dev, st); if (! os_disk) return -1; @@ -911,7 +1099,7 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) return 0; } - drive = find_system_device (os_dev); + drive = find_system_device (os_dev, &st); if (drive < 0) { grub_error (GRUB_ERR_BAD_DEVICE, @@ -919,8 +1107,8 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) return 0; } - if (grub_strcmp (os_dev, convert_system_partition_to_system_disk (os_dev)) - == 0) + if (grub_strcmp (os_dev, + convert_system_partition_to_system_disk (os_dev, &st)) == 0) return make_device_name (drive, -1, -1); #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__APPLE__) @@ -942,8 +1130,7 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) { char *name; grub_disk_t disk; - int fd; - struct hd_geometry hdg; + grub_disk_addr_t start; int dos_part = -1; int bsd_part = -1; auto int find_partition (grub_disk_t disk, @@ -973,7 +1160,7 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) partition->index, partition->start); } - if (hdg.start == partition->start) + if (start == partition->start) { if (pcdata) { @@ -996,28 +1183,16 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) if (MAJOR (st.st_rdev) == FLOPPY_MAJOR) return name; - fd = open (os_dev, O_RDONLY); - if (fd == -1) + start = find_partition_start (os_dev); + if (grub_errno != GRUB_ERR_NONE) { - grub_error (GRUB_ERR_BAD_DEVICE, "cannot open `%s' while attempting to get disk geometry", os_dev); free (name); return 0; } - if (ioctl (fd, HDIO_GETGEO, &hdg)) - { - grub_error (GRUB_ERR_BAD_DEVICE, - "cannot get geometry of `%s'", os_dev); - close (fd); - free (name); - return 0; - } + grub_util_info ("%s starts from %lu", os_dev, start); - close (fd); - - grub_util_info ("%s starts from %lu", os_dev, hdg.start); - - if (hdg.start == 0 && device_is_wholedisk (os_dev)) + if (start == 0 && device_is_wholedisk (os_dev)) return name; grub_util_info ("opening the device %s", name); From 42e0cba3af386ae4e5df2e82c759d833bae1ae47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Sutre?= Date: Tue, 26 Jan 2010 01:57:56 +0100 Subject: [PATCH 292/738] Reset LIBS after check for libgcc symbols in configure.ac. --- ChangeLog | 4 ++++ configure.ac | 1 + 2 files changed, 5 insertions(+) diff --git a/ChangeLog b/ChangeLog index 12b7ccb31..e66e2d403 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-01-26 Vladimir Serbinenko + + * configure.ac: Reset LIBS after check for libgcc symbols. + 2010-01-25 Colin Watson * util/hostdisk.c (open_device): Add trailing newline to debug diff --git a/configure.ac b/configure.ac index be498be8b..e6751e5cf 100644 --- a/configure.ac +++ b/configure.ac @@ -457,6 +457,7 @@ CFLAGS="$TARGET_CFLAGS -nostdlib" else CFLAGS="$TARGET_CFLAGS -nostdlib -Wl,--defsym,___main=0x8100" fi +LIBS="" # Defined in aclocal.m4. grub_PROG_TARGET_CC From c1273662b92bb745d7b1dbdcc247fea7b918e25e Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Tue, 26 Jan 2010 09:39:51 +0530 Subject: [PATCH 293/738] added change log file --- ChangeLog.while-until-loops | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 ChangeLog.while-until-loops diff --git a/ChangeLog.while-until-loops b/ChangeLog.while-until-loops new file mode 100644 index 000000000..33a3a839d --- /dev/null +++ b/ChangeLog.while-until-loops @@ -0,0 +1,15 @@ +2010-01-26 BVK Chaitanya + + While and until loops support to GRUB script. + + * include/grub/script_sh.h (grub_script_cmdwhile): New struct. + (grub_script_create_cmdwhile): New function prototype. + (grub_script_execute_cmdwhile): New function prototype. + * script/execute.c (grub_script_execute_cmdwhile): New function. + * script/parser.y (command): New commands. + (whilecmd): New grammar rule. + (untilcmd): New grammar rule. + * script/script.c (grub_script_create_cmdwhile): New function. + * util/grub-script-check.c (grub_script_execute_cmdwhile): New + function. + From 3342306cec42aed344501adaeb13571a3dc4c1ae Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Tue, 26 Jan 2010 12:32:24 +0530 Subject: [PATCH 294/738] several fixes in return value handling --- ChangeLog.while-until-loops | 5 +++++ commands/test.c | 3 +-- commands/true.c | 2 +- conf/tests.rmk | 4 ++++ script/execute.c | 28 ++++++++++++++++------------ 5 files changed, 27 insertions(+), 15 deletions(-) diff --git a/ChangeLog.while-until-loops b/ChangeLog.while-until-loops index 33a3a839d..ac54b8cd9 100644 --- a/ChangeLog.while-until-loops +++ b/ChangeLog.while-until-loops @@ -13,3 +13,8 @@ * util/grub-script-check.c (grub_script_execute_cmdwhile): New function. + * tests/grub_script_while1.in: New testcase. + * conf/tests.rmk: New testcase make rule. + + * commands/true.c (grub_cmd_false): Remove printing error message. + * commands/test.c (grub_cmd_test): Likewise. diff --git a/commands/test.c b/commands/test.c index 6995165cf..64ad69522 100644 --- a/commands/test.c +++ b/commands/test.c @@ -412,8 +412,7 @@ grub_cmd_test (grub_command_t cmd __attribute__ ((unused)), if (argc >= 1 && grub_strcmp (args[argc - 1], "]") == 0) argc--; - return test_parse (args, &argn, argc) ? GRUB_ERR_NONE - : grub_error (GRUB_ERR_TEST_FAILURE, "false"); + return test_parse (args, &argn, argc) ? 0 : 1; } static grub_command_t cmd_1, cmd_2; diff --git a/commands/true.c b/commands/true.c index aa8125853..20403c588 100644 --- a/commands/true.c +++ b/commands/true.c @@ -34,7 +34,7 @@ grub_cmd_false (struct grub_command *cmd __attribute__ ((unused)), int argc __attribute__ ((unused)), char *argv[] __attribute__ ((unused))) { - return grub_error (GRUB_ERR_TEST_FAILURE, "false"); + return 1; } static grub_command_t cmd_true, cmd_false; diff --git a/conf/tests.rmk b/conf/tests.rmk index 92f14797d..442beb0d3 100644 --- a/conf/tests.rmk +++ b/conf/tests.rmk @@ -53,6 +53,9 @@ grub_script_vars1_SOURCES = tests/grub_script_vars1.in check_SCRIPTS += grub_script_for1 grub_script_for1_SOURCES = tests/grub_script_for1.in +check_SCRIPTS += grub_script_while1 +grub_script_while1_SOURCES = tests/grub_script_while1.in + # List of tests to execute on "make check" # SCRIPTED_TESTS = example_scripted_test # SCRIPTED_TESTS += example_grub_script_test @@ -63,6 +66,7 @@ SCRIPTED_TESTS = grub_script_echo1 SCRIPTED_TESTS += grub_script_echo_keywords SCRIPTED_TESTS += grub_script_vars1 SCRIPTED_TESTS += grub_script_for1 +SCRIPTED_TESTS += grub_script_while1 # dependencies between tests and testing-tools $(SCRIPTED_TESTS): grub-shell grub-shell-tester diff --git a/script/execute.c b/script/execute.c index b905de46f..37686627d 100644 --- a/script/execute.c +++ b/script/execute.c @@ -26,13 +26,24 @@ #include #include +/* Max digits for a char is 3 (0xFF is 255), similarly for an int it + is sizeof (int) * 3, and one extra for a possible -ve sign. */ +#define ERRNO_DIGITS_MAX (sizeof (int) * 3 + 1) + static grub_err_t grub_script_execute_cmd (struct grub_script_cmd *cmd) { + int ret; + char errnobuf[ERRNO_DIGITS_MAX + 1]; + if (cmd == 0) return 0; - return cmd->exec (cmd); + ret = cmd->exec (cmd); + + grub_snprintf (errnobuf, sizeof (errnobuf), "%d", ret); + grub_env_set ("?", errnobuf); + return ret; } /* Expand arguments in ARGLIST into multiple arguments. */ @@ -188,7 +199,6 @@ grub_script_execute_cmdline (struct grub_script_cmd *cmd) grub_err_t ret = 0; int argcount = 0; grub_script_function_t func = 0; - char errnobuf[18]; char *cmdname; /* Lookup the command. */ @@ -222,11 +232,7 @@ grub_script_execute_cmdline (struct grub_script_cmd *cmd) grub_env_set (assign, eq); } grub_free (assign); - - grub_snprintf (errnobuf, sizeof (errnobuf), "%d", grub_errno); - grub_env_set ("?", errnobuf); - - return 0; + return grub_errno; } } @@ -241,9 +247,6 @@ grub_script_execute_cmdline (struct grub_script_cmd *cmd) grub_free (args[i]); grub_free (args); - grub_snprintf (errnobuf, sizeof (errnobuf), "%d", ret); - grub_env_set ("?", errnobuf); - return ret; } @@ -251,13 +254,14 @@ grub_script_execute_cmdline (struct grub_script_cmd *cmd) grub_err_t grub_script_execute_cmdblock (struct grub_script_cmd *cmd) { + int ret = 0; struct grub_script_cmdblock *cmdblock = (struct grub_script_cmdblock *) cmd; /* Loop over every command and execute it. */ for (cmd = cmdblock->cmdlist; cmd; cmd = cmd->next) - grub_script_execute_cmd (cmd); + ret = grub_script_execute_cmd (cmd); - return 0; + return ret; } /* Execute an if statement. */ From 2aa1646307cc44f4ae31d340d24f70fdc226b0fa Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Tue, 26 Jan 2010 12:32:47 +0530 Subject: [PATCH 295/738] new testcase for while and until loops --- tests/grub_script_while1.in | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 tests/grub_script_while1.in diff --git a/tests/grub_script_while1.in b/tests/grub_script_while1.in new file mode 100644 index 000000000..554247f76 --- /dev/null +++ b/tests/grub_script_while1.in @@ -0,0 +1,32 @@ +#! @builddir@/grub-shell-tester + +echo one +foo="" +while test "$foo" != "1111"; do foo="${foo}1"; echo "$foo"; done + +echo two +foo="" +while test "$foo" != "aaaa" +do + foo="${foo}a" + echo $foo +done + +foo="" +until test "$foo" = "1111"; do foo="${foo}1"; echo $foo; done +foo="" +until test "$foo" = "aaaa" +do + foo="${foo}a" + echo $foo +done + +# check "$?" in condition gets its value from while body commands +foo="" +false +while test "$?" != "0" +do + echo $foo + foo="${foo}1" + test "$foo" = "111111" +done From b5c5144ab11c3b9168949abe2c52a069ba58e862 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Tue, 26 Jan 2010 14:33:23 +0530 Subject: [PATCH 296/738] made while/until loop condition check more readable --- script/execute.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script/execute.c b/script/execute.c index 37686627d..cdfe47337 100644 --- a/script/execute.c +++ b/script/execute.c @@ -323,7 +323,7 @@ grub_script_execute_cmdwhile (struct grub_script_cmd *cmd) result = 0; do { cond = grub_script_execute_cmd (cmdwhile->cond); - if ((cmdwhile->until && !cond) || (!cmdwhile->until && cond)) + if (cmdwhile->until ? !cond : cond) break; result = grub_script_execute_cmd (cmdwhile->list); From b769a37b6ea0593c865e8a3ec501dd03757e44eb Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 26 Jan 2010 14:26:16 +0000 Subject: [PATCH 297/738] 2010-01-26 Colin Watson * conf/common.rmk (grub_mkdevicemap_SOURCES): Add kern/env.c, kern/err.c, kern/list.c, and kern/misc.c. * util/deviceiter.c [__linux__]: Define MINOR. (grub_util_iterate_devices): Add support for DM-RAID disk devices. * util/mkdevicemap.c (grub_putchar): New function. (grub_getkey): New function. (grub_refresh): New function. (main): Set debug=all if -v -v is used. --- ChangeLog.dmraid-probe | 12 +++- conf/common.rmk | 3 +- util/deviceiter.c | 140 ++++++++++++++++++++++++++++++++++++++++ util/grub-mkdevicemap.c | 22 +++++++ 4 files changed, 175 insertions(+), 2 deletions(-) diff --git a/ChangeLog.dmraid-probe b/ChangeLog.dmraid-probe index 8b8f25533..505cf7ba4 100644 --- a/ChangeLog.dmraid-probe +++ b/ChangeLog.dmraid-probe @@ -1,6 +1,7 @@ -2010-01-25 Colin Watson +2010-01-26 Colin Watson * configure.ac: Check for Linux device-mapper support. + * util/hostdisk.c (device_is_mapped): New function. (find_partition_start): New function, partly broken out from linux_find_partition and grub_util_biosdisk_get_grub_dev but with @@ -14,3 +15,12 @@ (grub_util_biosdisk_get_grub_dev): Pass stat result to find_system_device and convert_system_partition_to_system_disk. Use find_partition_start. + + * conf/common.rmk (grub_mkdevicemap_SOURCES): Add kern/env.c, + kern/err.c, kern/list.c, and kern/misc.c. + * util/deviceiter.c [__linux__]: Define MINOR. + (grub_util_iterate_devices): Add support for DM-RAID disk devices. + * util/mkdevicemap.c (grub_putchar): New function. + (grub_getkey): New function. + (grub_refresh): New function. + (main): Set debug=all if -v -v is used. diff --git a/conf/common.rmk b/conf/common.rmk index 2ea8ebd5a..94a96a313 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -3,7 +3,8 @@ sbin_UTILITIES += grub-mkdevicemap grub_mkdevicemap_SOURCES = gnulib/progname.c util/grub-mkdevicemap.c \ util/deviceiter.c \ - util/misc.c + util/misc.c \ + kern/env.c kern/err.c kern/list.c kern/misc.c ifeq ($(target_cpu)-$(platform), sparc64-ieee1275) grub_mkdevicemap_SOURCES += util/ieee1275/ofpath.c util/ieee1275/devicemap.c diff --git a/util/deviceiter.c b/util/deviceiter.c index b0a9e1388..03813bc7d 100644 --- a/util/deviceiter.c +++ b/util/deviceiter.c @@ -31,6 +31,8 @@ #include #include +#include +#include #ifdef __linux__ # if !defined(__GLIBC__) || \ @@ -62,12 +64,23 @@ struct hd_geometry | ((unsigned int) (__dev >> 32) & ~0xfff); \ }) # endif /* ! MAJOR */ +# ifndef MINOR +# define MINOR(dev) \ + ({ \ + unsigned long long __dev = (dev); \ + (unsigned) (__dev & 0xff) | ((unsigned int) (__dev >> 12) & ~0xff); \ + }) +# endif /* ! MINOR */ # ifndef CDROM_GET_CAPABILITY # define CDROM_GET_CAPABILITY 0x5331 /* get capabilities */ # endif /* ! CDROM_GET_CAPABILITY */ # ifndef BLKGETSIZE # define BLKGETSIZE _IO(0x12,96) /* return device size */ # endif /* ! BLKGETSIZE */ + +#ifdef HAVE_DEVICE_MAPPER +# include +#endif #endif /* __linux__ */ /* Use __FreeBSD_kernel__ instead of __FreeBSD__ for compatibility with @@ -411,6 +424,16 @@ check_device (const char *device) return 1; } +#ifdef __linux__ +# ifdef HAVE_DEVICE_MAPPER +struct dmraid_seen +{ + struct dmraid_seen *next; + const char *name; +}; +# endif /* HAVE_DEVICE_MAPPER */ +#endif /* __linux__ */ + void grub_util_iterate_devices (int NESTED_FUNC_ATTR (*hook) (const char *, int), int floppy_disks) @@ -643,6 +666,123 @@ grub_util_iterate_devices (int NESTED_FUNC_ATTR (*hook) (const char *, int), return; } } + +# ifdef HAVE_DEVICE_MAPPER +# define dmraid_check(cond, ...) \ + if (! (cond)) \ + { \ + grub_dprintf ("deviceiter", __VA_ARGS__); \ + goto dmraid_end; \ + } + + /* DM-RAID. */ + { + struct dm_tree *tree = NULL; + struct dm_task *task = NULL; + struct dm_names *names = NULL; + unsigned int next = 0; + void *top_handle, *second_handle; + struct dm_tree_node *root, *top, *second; + struct dmraid_seen *seen = NULL; + + /* Build DM tree for all devices. */ + tree = dm_tree_create (); + dmraid_check (tree, "dm_tree_create failed\n"); + task = dm_task_create (DM_DEVICE_LIST); + dmraid_check (task, "dm_task_create failed\n"); + dmraid_check (dm_task_run (task), "dm_task_run failed\n"); + names = dm_task_get_names (task); + dmraid_check (names, "dm_task_get_names failed\n"); + dmraid_check (names->dev, "No DM devices found\n"); + do + { + names = (void *) names + next; + dmraid_check (dm_tree_add_dev (tree, MAJOR (names->dev), + MINOR (names->dev)), + "dm_tree_add_dev (%s) failed\n", names->name); + next = names->next; + } + while (next); + + /* Walk the second-level children of the inverted tree; that is, devices + which are directly composed of non-DM devices such as hard disks. + This class includes all DM-RAID disks and excludes all DM-RAID + partitions. */ + root = dm_tree_find_node (tree, 0, 0); + top_handle = NULL; + top = dm_tree_next_child (&top_handle, root, 1); + while (top) + { + second_handle = NULL; + second = dm_tree_next_child (&second_handle, top, 1); + while (second) + { + const char *node_name, *node_uuid; + char *name; + struct dmraid_seen *seen_elt; + + node_name = dm_tree_node_get_name (second); + dmraid_check (node_name, "dm_tree_node_get_name failed\n"); + node_uuid = dm_tree_node_get_uuid (second); + dmraid_check (node_uuid, "dm_tree_node_get_uuid failed\n"); + if (strncmp (node_uuid, "DMRAID-", 7) != 0) + { + grub_dprintf ("deviceiter", "%s is not DM-RAID\n", node_name); + goto dmraid_next_child; + } + + /* Have we already seen this node? There are typically very few + DM-RAID disks, so a list should be fast enough. */ + if (grub_named_list_find (GRUB_AS_NAMED_LIST (seen), node_name)) + { + grub_dprintf ("deviceiter", "Already seen DM device %s\n", + node_name); + goto dmraid_next_child; + } + + name = xasprintf ("/dev/mapper/%s", node_name); + if (check_device (name)) + { + if (hook (name, 0)) + { + free (name); + while (seen) + { + struct dmraid_seen *seen_elt = + grub_list_pop (GRUB_AS_LIST_P (&seen)); + free (seen_elt); + } + if (task) + dm_task_destroy (task); + if (tree) + dm_tree_free (tree); + return; + } + } + free (name); + + seen_elt = xmalloc (sizeof *seen_elt); + seen_elt->name = node_name; + grub_list_push (GRUB_AS_LIST_P (&seen), GRUB_AS_LIST (seen_elt)); + +dmraid_next_child: + second = dm_tree_next_child (&second_handle, top, 1); + } + top = dm_tree_next_child (&top_handle, root, 1); + } + +dmraid_end: + while (seen) + { + struct dmraid_seen *seen_elt = grub_list_pop (GRUB_AS_LIST_P (&seen)); + free (seen_elt); + } + if (task) + dm_task_destroy (task); + if (tree) + dm_tree_free (tree); + } +# endif /* HAVE_DEVICE_MAPPER */ #endif /* __linux__ */ } diff --git a/util/grub-mkdevicemap.c b/util/grub-mkdevicemap.c index c68482af1..db37f99e6 100644 --- a/util/grub-mkdevicemap.c +++ b/util/grub-mkdevicemap.c @@ -31,6 +31,7 @@ #include #include +#include #include #define _GNU_SOURCE 1 @@ -38,6 +39,24 @@ #include "progname.h" +void +grub_putchar (int c) +{ + putchar (c); +} + +int +grub_getkey (void) +{ + return -1; +} + +void +grub_refresh (void) +{ + fflush (stdout); +} + static void make_device_map (const char *device_map, int floppy_disks) { @@ -158,6 +177,9 @@ main (int argc, char *argv[]) } } + if (verbosity > 1) + grub_env_set ("debug", "all"); + make_device_map (dev_map ? : DEFAULT_DEVICE_MAP, floppy_disks); free (dev_map); From 59cad637aec20e1a5122c6a0a7f30ed48b5b4b2a Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Tue, 26 Jan 2010 16:45:16 +0100 Subject: [PATCH 298/738] Update my email address --- ChangeLog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index e66e2d403..aabc66370 100644 --- a/ChangeLog +++ b/ChangeLog @@ -23847,7 +23847,7 @@ * genmk.rb (PModule#rule): Make sure to get only symbol names from the output of nm. - Reported by Robert Millan . + Reported by Robert Millan . 2003-09-25 Yoshinori K. Okuji From 3973a59a3476cb9201f70446e03b6e5301b3c3bf Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Tue, 26 Jan 2010 16:39:37 +0000 Subject: [PATCH 299/738] 2010-01-26 Robert Millan * include/grub/i386/pc/boot.h (GRUB_BOOT_MACHINE_PXE_DL): New macro. * boot/i386/pc/pxeboot.S: Include `'. (_start): Macroify `0x7F'. * kern/i386/pc/init.c: Include `'. (make_install_device): Use "(pxe)" as fallback prefix when booting via PXE. --- ChangeLog | 11 +++++++++++ boot/i386/pc/pxeboot.S | 6 ++++-- include/grub/i386/pc/boot.h | 2 ++ kern/i386/pc/init.c | 37 ++++++++++++++++++++++--------------- 4 files changed, 39 insertions(+), 17 deletions(-) diff --git a/ChangeLog b/ChangeLog index aabc66370..293e40a40 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2010-01-26 Robert Millan + + * include/grub/i386/pc/boot.h (GRUB_BOOT_MACHINE_PXE_DL): New macro. + + * boot/i386/pc/pxeboot.S: Include `'. + (_start): Macroify `0x7F'. + + * kern/i386/pc/init.c: Include `'. + (make_install_device): Use "(pxe)" as fallback prefix when booting + via PXE. + 2010-01-26 Vladimir Serbinenko * configure.ac: Reset LIBS after check for libgcc symbols. diff --git a/boot/i386/pc/pxeboot.S b/boot/i386/pc/pxeboot.S index 28c90e29b..446bfc781 100644 --- a/boot/i386/pc/pxeboot.S +++ b/boot/i386/pc/pxeboot.S @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2000,2005,2007,2008,2009 Free Software Foundation, Inc. + * Copyright (C) 2000,2005,2007,2008,2009,2010 Free Software Foundation, Inc. * * GRUB is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,6 +16,8 @@ * along with GRUB. If not, see . */ +#include + .file "pxeboot.S" .text @@ -28,7 +30,7 @@ _start: start: /* Use drive number 0x7F for PXE */ - movb $0x7F, %dl + movb $GRUB_BOOT_MACHINE_PXE_DL, %dl /* Jump to the real world */ ljmp $0, $0x8200 diff --git a/include/grub/i386/pc/boot.h b/include/grub/i386/pc/boot.h index 508b10742..e88c62b71 100644 --- a/include/grub/i386/pc/boot.h +++ b/include/grub/i386/pc/boot.h @@ -66,6 +66,8 @@ /* The size of a block list used in the kernel startup code. */ #define GRUB_BOOT_MACHINE_LIST_SIZE 12 +#define GRUB_BOOT_MACHINE_PXE_DL 0x7f + #ifndef ASM_FILE /* This is the blocklist used in the diskboot image. */ diff --git a/kern/i386/pc/init.c b/kern/i386/pc/init.c index e45ad3971..1707049fe 100644 --- a/kern/i386/pc/init.c +++ b/kern/i386/pc/init.c @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009 Free Software Foundation, Inc. + * Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc. * * GRUB is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -62,22 +63,28 @@ make_install_device (void) { /* No hardcoded root partition - make it from the boot drive and the partition number encoded at the install time. */ - grub_snprintf (dev, sizeof (dev), - "(%cd%u", (grub_boot_drive & 0x80) ? 'h' : 'f', - grub_boot_drive & 0x7f); - ptr += grub_strlen (ptr); + if (grub_boot_drive == GRUB_BOOT_MACHINE_PXE_DL) + { + grub_strcpy (dev, "(pxe"); + ptr += sizeof ("(pxe") - 1; + } + else + { + grub_snprintf (dev, sizeof (dev), + "(%cd%u", (grub_boot_drive & 0x80) ? 'h' : 'f', + grub_boot_drive & 0x7f); + ptr += grub_strlen (ptr); - if (grub_install_dos_part >= 0) - grub_snprintf (ptr, sizeof (dev) - (ptr - dev), - ",%u", grub_install_dos_part + 1); + if (grub_install_dos_part >= 0) + grub_snprintf (ptr, sizeof (dev) - (ptr - dev), + ",%u", grub_install_dos_part + 1); + ptr += grub_strlen (ptr); - ptr += grub_strlen (ptr); - - if (grub_install_bsd_part >= 0) - grub_snprintf (ptr, sizeof (dev) - (ptr - dev), ",%c", - grub_install_bsd_part + 'a'); - - ptr += grub_strlen (ptr); + if (grub_install_bsd_part >= 0) + grub_snprintf (ptr, sizeof (dev) - (ptr - dev), ",%c", + grub_install_bsd_part + 'a'); + ptr += grub_strlen (ptr); + } grub_snprintf (ptr, sizeof (dev) - (ptr - dev), ")%s", grub_prefix); grub_strcpy (grub_prefix, dev); From 94e7e712819fa4a320b013fb850341679a9fa71d Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Tue, 26 Jan 2010 18:12:49 +0000 Subject: [PATCH 300/738] 2010-01-26 Robert Millan * util/bin2h.c (usage): Make --help actually explain what `grub-bin2h' does. --- ChangeLog | 5 +++++ util/bin2h.c | 2 ++ 2 files changed, 7 insertions(+) diff --git a/ChangeLog b/ChangeLog index 293e40a40..097d6b217 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-01-26 Robert Millan + + * util/bin2h.c (usage): Make --help actually explain what `grub-bin2h' + does. + 2010-01-26 Robert Millan * include/grub/i386/pc/boot.h (GRUB_BOOT_MACHINE_PXE_DL): New macro. diff --git a/util/bin2h.c b/util/bin2h.c index 5ce47f086..3a0723ea3 100644 --- a/util/bin2h.c +++ b/util/bin2h.c @@ -41,6 +41,8 @@ usage (int status) printf ("\ Usage: %s [OPTIONS] SYMBOL-NAME\n\ \n\ +Convert a binary file to a C header.\n\ +\n\ -h, --help display this message and exit\n\ -V, --version print version information and exit\n\ \n\ From de0b7a4ed1e72ea5e66027d80c6a708418980b70 Mon Sep 17 00:00:00 2001 From: carles Date: Tue, 26 Jan 2010 20:16:08 +0000 Subject: [PATCH 301/738] 2010-01-25 Carles Pina i Estany * font/font.c: Include `grub/fontformat.h. Remove font file format constants. (grub_font_load): Use the new macros. * include/grub/fontformat.h: New file. * util/grub-mkfont.c: Include `grub/fontformat.c'. (write_font_pf2): Use the new macros. --- ChangeLog | 9 +++++++ font/font.c | 51 +++++++++++++++++++++------------------ include/grub/fontformat.h | 38 +++++++++++++++++++++++++++++ util/grub-mkfont.c | 38 +++++++++++++++++++---------- 4 files changed, 99 insertions(+), 37 deletions(-) create mode 100644 include/grub/fontformat.h diff --git a/ChangeLog b/ChangeLog index 097d6b217..a0628fd7d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2010-01-25 Carles Pina i Estany + + * font/font.c: Include `grub/fontformat.h. + Remove font file format constants. + (grub_font_load): Use the new macros. + * include/grub/fontformat.h: New file. + * util/grub-mkfont.c: Include `grub/fontformat.c'. + (write_font_pf2): Use the new macros. + 2010-01-26 Robert Millan * util/bin2h.c (usage): Make --help actually explain what `grub-bin2h' diff --git a/font/font.c b/font/font.c index 587e418cc..639f4d720 100644 --- a/font/font.c +++ b/font/font.c @@ -26,6 +26,7 @@ #include #include #include +#include #ifdef USE_ASCII_FAILBACK #include "ascii.h" @@ -89,19 +90,6 @@ struct font_file_section int eof; }; -/* Font file format constants. */ -static const char pff2_magic[4] = { 'P', 'F', 'F', '2' }; -static const char section_names_file[4] = { 'F', 'I', 'L', 'E' }; -static const char section_names_font_name[4] = { 'N', 'A', 'M', 'E' }; -static const char section_names_point_size[4] = { 'P', 'T', 'S', 'Z' }; -static const char section_names_weight[4] = { 'W', 'E', 'I', 'G' }; -static const char section_names_max_char_width[4] = { 'M', 'A', 'X', 'W' }; -static const char section_names_max_char_height[4] = { 'M', 'A', 'X', 'H' }; -static const char section_names_ascent[4] = { 'A', 'S', 'C', 'E' }; -static const char section_names_descent[4] = { 'D', 'E', 'S', 'C' }; -static const char section_names_char_index[4] = { 'C', 'H', 'I', 'X' }; -static const char section_names_data[4] = { 'D', 'A', 'T', 'A' }; - /* Replace unknown glyphs with a rounded question mark. */ static grub_uint8_t unknown_glyph_bitmap[] = { @@ -460,7 +448,8 @@ grub_font_load (const char *filename) #if FONT_DEBUG >= 3 grub_printf("opened FILE section\n"); #endif - if (grub_memcmp (section.name, section_names_file, 4) != 0) + if (grub_memcmp (section.name, FONT_FORMAT_SECTION_NAMES_FILE, + sizeof(FONT_FORMAT_SECTION_NAMES_FILE) - 1) != 0) { grub_error (GRUB_ERR_BAD_FONT, "font file format error: 1st section must be FILE"); @@ -489,7 +478,7 @@ grub_font_load (const char *filename) grub_printf("read magic ok\n"); #endif - if (grub_memcmp (magic, pff2_magic, 4) != 0) + if (grub_memcmp (magic, FONT_FORMAT_PFF2_MAGIC, 4) != 0) { grub_error (GRUB_ERR_BAD_FONT, "invalid font magic %x %x %x %x", magic[0], magic[1], magic[2], magic[3]); @@ -529,18 +518,22 @@ grub_font_load (const char *filename) section.name[2], section.name[3]); #endif - if (grub_memcmp (section.name, section_names_font_name, 4) == 0) + if (grub_memcmp (section.name, FONT_FORMAT_SECTION_NAMES_FONT_NAME, + sizeof(FONT_FORMAT_SECTION_NAMES_FONT_NAME) - 1) == 0) { font->name = read_section_as_string (§ion); if (!font->name) goto fail; } - else if (grub_memcmp (section.name, section_names_point_size, 4) == 0) + else if (grub_memcmp (section.name, + FONT_FORMAT_SECTION_NAMES_POINT_SIZE, + sizeof(FONT_FORMAT_SECTION_NAMES_POINT_SIZE) - 1) == 0) { if (read_section_as_short (§ion, &font->point_size) != 0) goto fail; } - else if (grub_memcmp (section.name, section_names_weight, 4) == 0) + else if (grub_memcmp (section.name, FONT_FORMAT_SECTION_NAMES_WEIGHT, + sizeof(FONT_FORMAT_SECTION_NAMES_WEIGHT) - 1) == 0) { char *wt; wt = read_section_as_string (§ion); @@ -553,32 +546,42 @@ grub_font_load (const char *filename) font->weight = FONT_WEIGHT_BOLD; grub_free (wt); } - else if (grub_memcmp (section.name, section_names_max_char_width, 4) == 0) + else if (grub_memcmp (section.name, + FONT_FORMAT_SECTION_NAMES_MAX_CHAR_WIDTH, + sizeof(FONT_FORMAT_SECTION_NAMES_MAX_CHAR_WIDTH) - 1) == 0) { if (read_section_as_short (§ion, &font->max_char_width) != 0) goto fail; } - else if (grub_memcmp (section.name, section_names_max_char_height, 4) == 0) + else if (grub_memcmp (section.name, + FONT_FORMAT_SECTION_NAMES_MAX_CHAR_HEIGHT, + sizeof(FONT_FORMAT_SECTION_NAMES_MAX_CHAR_HEIGHT) - 1) == 0) { if (read_section_as_short (§ion, &font->max_char_height) != 0) goto fail; } - else if (grub_memcmp (section.name, section_names_ascent, 4) == 0) + else if (grub_memcmp (section.name, + FONT_FORMAT_SECTION_NAMES_ASCENT, + sizeof(FONT_FORMAT_SECTION_NAMES_ASCENT) - 1) == 0) { if (read_section_as_short (§ion, &font->ascent) != 0) goto fail; } - else if (grub_memcmp (section.name, section_names_descent, 4) == 0) + else if (grub_memcmp (section.name, FONT_FORMAT_SECTION_NAMES_DESCENT, + sizeof(FONT_FORMAT_SECTION_NAMES_DESCENT) - 1) == 0) { if (read_section_as_short (§ion, &font->descent) != 0) goto fail; } - else if (grub_memcmp (section.name, section_names_char_index, 4) == 0) + else if (grub_memcmp (section.name, + FONT_FORMAT_SECTION_NAMES_CHAR_INDEX, + sizeof(FONT_FORMAT_SECTION_NAMES_CHAR_INDEX) - 1) == 0) { if (load_font_index (file, section.length, font) != 0) goto fail; } - else if (grub_memcmp (section.name, section_names_data, 4) == 0) + else if (grub_memcmp (section.name, FONT_FORMAT_SECTION_NAMES_DATA, + sizeof(FONT_FORMAT_SECTION_NAMES_DATA) - 1) == 0) { /* When the DATA section marker is reached, we stop reading. */ break; diff --git a/include/grub/fontformat.h b/include/grub/fontformat.h new file mode 100644 index 000000000..b5060588c --- /dev/null +++ b/include/grub/fontformat.h @@ -0,0 +1,38 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_FONT_FORMAT_HEADER +#define GRUB_FONT_FORMAT_HEADER 1 + +/* FONT_FORMAT_PFF2_MAGIC use only 4 relevants bytes and the \0. */ +#define FONT_FORMAT_PFF2_MAGIC "PFF2" +#define FONT_FORMAT_SECTION_NAMES_FILE "FILE" +#define FONT_FORMAT_SECTION_NAMES_FONT_NAME "NAME" +#define FONT_FORMAT_SECTION_NAMES_POINT_SIZE "PTSZ" +#define FONT_FORMAT_SECTION_NAMES_WEIGHT "WEIG" +#define FONT_FORMAT_SECTION_NAMES_MAX_CHAR_WIDTH "MAXW" +#define FONT_FORMAT_SECTION_NAMES_MAX_CHAR_HEIGHT "MAXH" +#define FONT_FORMAT_SECTION_NAMES_ASCENT "ASCE" +#define FONT_FORMAT_SECTION_NAMES_DESCENT "DESC" +#define FONT_FORMAT_SECTION_NAMES_CHAR_INDEX "CHIX" +#define FONT_FORMAT_SECTION_NAMES_DATA "DATA" +#define FONT_FORMAT_SECTION_NAMES_FAMILY "FAMI" +#define FONT_FORMAT_SECTION_NAMES_SLAN "SLAN" + +#endif /* ! GRUB_FONT_FORMAT_HEADER */ + diff --git a/util/grub-mkfont.c b/util/grub-mkfont.c index 38906a70e..51e2e494c 100644 --- a/util/grub-mkfont.c +++ b/util/grub-mkfont.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -392,9 +393,10 @@ write_font_pf2 (struct grub_font_info *font_info, char *output_file) offset = 0; leng = grub_cpu_to_be32 (4); - grub_util_write_image ("FILE", 4, file); + grub_util_write_image (FONT_FORMAT_SECTION_NAMES_FILE, + sizeof(FONT_FORMAT_SECTION_NAMES_FILE) - 1, file); grub_util_write_image ((char *) &leng, 4, file); - grub_util_write_image ("PFF2", 4, file); + grub_util_write_image (FONT_FORMAT_PFF2_MAGIC, 4, file); offset += 12; if (! font_info->name) @@ -416,20 +418,25 @@ write_font_pf2 (struct grub_font_info *font_info, char *output_file) font_name = xasprintf ("%s %s %d", font_info->name, &style_name[1], font_info->size); - write_string_section ("NAME", font_name, &offset, file); - write_string_section ("FAMI", font_info->name, &offset, file); - write_string_section ("WEIG", + write_string_section (FONT_FORMAT_SECTION_NAMES_FONT_NAME, + font_name, &offset, file); + write_string_section (FONT_FORMAT_SECTION_NAMES_FAMILY, + font_info->name, &offset, file); + write_string_section (FONT_FORMAT_SECTION_NAMES_WEIGHT, (font_info->style & FT_STYLE_FLAG_BOLD) ? "bold" : "normal", &offset, file); - write_string_section ("SLAN", + write_string_section (FONT_FORMAT_SECTION_NAMES_SLAN, (font_info->style & FT_STYLE_FLAG_ITALIC) ? "italic" : "normal", &offset, file); - write_be16_section ("PTSZ", font_info->size, &offset, file); - write_be16_section ("MAXW", font_info->max_width, &offset, file); - write_be16_section ("MAXH", font_info->max_height, &offset, file); + write_be16_section (FONT_FORMAT_SECTION_NAMES_POINT_SIZE, + font_info->size, &offset, file); + write_be16_section (FONT_FORMAT_SECTION_NAMES_MAX_CHAR_WIDTH, + font_info->max_width, &offset, file); + write_be16_section (FONT_FORMAT_SECTION_NAMES_MAX_CHAR_HEIGHT, + font_info->max_height, &offset, file); if (! font_info->desc) { @@ -447,8 +454,10 @@ write_font_pf2 (struct grub_font_info *font_info, char *output_file) font_info->asce = font_info->max_y; } - write_be16_section ("ASCE", font_info->asce, &offset, file); - write_be16_section ("DESC", font_info->desc, &offset, file); + write_be16_section (FONT_FORMAT_SECTION_NAMES_ASCENT, + font_info->asce, &offset, file); + write_be16_section (FONT_FORMAT_SECTION_NAMES_DESCENT, + font_info->desc, &offset, file); if (font_verbosity > 0) { @@ -479,7 +488,9 @@ write_font_pf2 (struct grub_font_info *font_info, char *output_file) printf ("Number of glyph: %d\n", num); leng = grub_cpu_to_be32 (num * 9); - grub_util_write_image ("CHIX", 4, file); + grub_util_write_image (FONT_FORMAT_SECTION_NAMES_CHAR_INDEX, + sizeof(FONT_FORMAT_SECTION_NAMES_CHAR_INDEX) - 1, + file); grub_util_write_image ((char *) &leng, 4, file); offset += 8 + num * 9 + 8; @@ -495,7 +506,8 @@ write_font_pf2 (struct grub_font_info *font_info, char *output_file) } leng = 0xffffffff; - grub_util_write_image ("DATA", 4, file); + grub_util_write_image (FONT_FORMAT_SECTION_NAMES_DATA, + sizeof(FONT_FORMAT_SECTION_NAMES_DATA) - 1, file); grub_util_write_image ((char *) &leng, 4, file); for (cur = font_info->glyph; cur; cur = cur->next) From b510928c3857245d4415cab78b87279ce6bcfbd3 Mon Sep 17 00:00:00 2001 From: carles Date: Tue, 26 Jan 2010 21:23:59 +0000 Subject: [PATCH 302/738] 2010-01-26 Carles Pina i Estany * util/bin2h.c (usage): Fix warning (space after backslash). --- ChangeLog | 4 ++++ util/bin2h.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index a0628fd7d..ca129a3be 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-01-26 Carles Pina i Estany + + * util/bin2h.c (usage): Fix warning (space after backslash). + 2010-01-25 Carles Pina i Estany * font/font.c: Include `grub/fontformat.h. diff --git a/util/bin2h.c b/util/bin2h.c index 3a0723ea3..e81ede8c6 100644 --- a/util/bin2h.c +++ b/util/bin2h.c @@ -42,7 +42,7 @@ usage (int status) Usage: %s [OPTIONS] SYMBOL-NAME\n\ \n\ Convert a binary file to a C header.\n\ -\n\ +\n\ -h, --help display this message and exit\n\ -V, --version print version information and exit\n\ \n\ From aa2f9dd26d5dac1f64a5a08417c4638f47e7f564 Mon Sep 17 00:00:00 2001 From: carles Date: Tue, 26 Jan 2010 23:07:37 +0000 Subject: [PATCH 303/738] Correct ChangeLog entry date. --- ChangeLog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index ca129a3be..b54d3bcbc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,7 +2,7 @@ * util/bin2h.c (usage): Fix warning (space after backslash). -2010-01-25 Carles Pina i Estany +2010-01-26 Carles Pina i Estany * font/font.c: Include `grub/fontformat.h. Remove font file format constants. From 254e2ce59664771f59f8698b1dd62429caccbda0 Mon Sep 17 00:00:00 2001 From: carles Date: Wed, 27 Jan 2010 00:19:46 +0000 Subject: [PATCH 304/738] 2010-01-27 Carles Pina i Estany * util/lvm.c: New macro LVM_DEV_MAPPER_STRING. (grub_util_lvm_isvolume): Use LVM_DEV_MAPPER_STRING. --- ChangeLog | 5 +++++ util/lvm.c | 8 +++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index b54d3bcbc..e3988f150 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-01-27 Carles Pina i Estany + + * util/lvm.c: New macro LVM_DEV_MAPPER_STRING. + (grub_util_lvm_isvolume): Use LVM_DEV_MAPPER_STRING. + 2010-01-26 Carles Pina i Estany * util/bin2h.c (usage): Fix warning (space after backslash). diff --git a/util/lvm.c b/util/lvm.c index 8a8ed1e4c..0a0916344 100644 --- a/util/lvm.c +++ b/util/lvm.c @@ -26,6 +26,8 @@ #include #include +#define LVM_DEV_MAPPER_STRING "/dev/mapper/" + int grub_util_lvm_isvolume (char *name) { @@ -33,10 +35,10 @@ grub_util_lvm_isvolume (char *name) struct stat st; int err; - devname = xmalloc (strlen (name) + 13); + devname = xmalloc (strlen (name) + sizeof (LVM_DEV_MAPPER_STRING)); - strcpy (devname, "/dev/mapper/"); - strcpy (devname+12, name); + strcpy (devname, LVM_DEV_MAPPER_STRING); + strcpy (devname + sizeof(LVM_DEV_MAPPER_STRING) - 1, name); err = stat (devname, &st); free (devname); From af75a9f19a81c2c5fada0c44779a491fae388e96 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Wed, 27 Jan 2010 01:49:11 +0000 Subject: [PATCH 305/738] 2010-01-27 Robert Millan * util/grub-fstest.c (fstest): Rewrite allocation, fixing a few memleak conditions. --- ChangeLog | 5 +++++ util/grub-fstest.c | 37 ++++++++++++++++++------------------- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/ChangeLog b/ChangeLog index e3988f150..c4930acb8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-01-27 Robert Millan + + * util/grub-fstest.c (fstest): Rewrite allocation, fixing a few + memleak conditions. + 2010-01-27 Carles Pina i Estany * util/lvm.c: New macro LVM_DEV_MAPPER_STRING. diff --git a/util/grub-fstest.c b/util/grub-fstest.c index bf30286a4..c03c43451 100644 --- a/util/grub-fstest.c +++ b/util/grub-fstest.c @@ -280,27 +280,29 @@ fstest (char **images, int num_disks, int cmd, int n, char **args) { char *host_file; char *loop_name; - char *argv[3] = { "-p" }; + char *argv[3]; int i; + argv[0] = "-p"; + for (i = 0; i < num_disks; i++) { loop_name = grub_xasprintf ("loop%d", i); - host_file = grub_xasprintf ("(host)%s", images[i]); + if (!loop_name) + grub_util_error (grub_errmsg); - if (!loop_name || !host_file) - { - grub_free (loop_name); - grub_free (host_file); - grub_util_error (grub_errmsg); - return; - } + host_file = grub_xasprintf ("(host)%s", images[i]); + if (!host_file) + grub_util_error (grub_errmsg); argv[1] = loop_name; argv[2] = host_file; if (execute_command ("loopback", 3, argv)) grub_util_error ("loopback command fails"); + + grub_free (loop_name); + grub_free (host_file); } grub_lvm_fini (); @@ -336,19 +338,16 @@ fstest (char **images, int num_disks, int cmd, int n, char **args) for (i = 0; i < num_disks; i++) { - grub_free (loop_name); loop_name = grub_xasprintf ("loop%d", i); if (!loop_name) - { - grub_free (host_file); - grub_util_error (grub_errmsg); - return; - } - execute_command ("loopback", 2, argv); - } + grub_util_error (grub_errmsg); - grub_free (loop_name); - grub_free (host_file); + argv[1] = loop_name; + + execute_command ("loopback", 2, argv); + + grub_free (loop_name); + } } static struct option options[] = { From c294d9d8123c85abaebbc48a169e88f0cff08c39 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Wed, 27 Jan 2010 03:11:20 +0000 Subject: [PATCH 306/738] 2010-01-27 Robert Millan Remove unused parameter. * fs/iso9660.c (struct grub_iso9660_data): Remove `length' parameter. (grub_iso9660_open): Remove initialization of `data->length'. --- ChangeLog | 7 +++++++ fs/iso9660.c | 2 -- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index c4930acb8..6c79d2b30 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-01-27 Robert Millan + + Remove unused parameter. + + * fs/iso9660.c (struct grub_iso9660_data): Remove `length' parameter. + (grub_iso9660_open): Remove initialization of `data->length'. + 2010-01-27 Robert Millan * util/grub-fstest.c (fstest): Rewrite allocation, fixing a few diff --git a/fs/iso9660.c b/fs/iso9660.c index a8a310f50..cadfbba2b 100644 --- a/fs/iso9660.c +++ b/fs/iso9660.c @@ -136,7 +136,6 @@ struct grub_iso9660_data struct grub_iso9660_primary_voldesc voldesc; grub_disk_t disk; unsigned int first_sector; - unsigned int length; int rockridge; int susp_skip; int joliet; @@ -744,7 +743,6 @@ grub_iso9660_open (struct grub_file *file, const char *name) goto fail; data->first_sector = foundnode->blk; - data->length = foundnode->size; file->data = data; file->size = foundnode->size; From 67667b9ced0abf5d0931c551d29a6faab2e1623e Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Wed, 27 Jan 2010 03:15:03 +0000 Subject: [PATCH 307/738] 2010-01-27 Robert Millan * kern/disk.c (grub_disk_read): Fix bug that would cause infinite loop when using read hooks on files whose size isn't sector-aligned. --- ChangeLog | 5 +++++ kern/disk.c | 10 ++++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6c79d2b30..e0ee80d22 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-01-27 Robert Millan + + * kern/disk.c (grub_disk_read): Fix bug that would cause infinite + loop when using read hooks on files whose size isn't sector-aligned. + 2010-01-27 Robert Millan Remove unused parameter. diff --git a/kern/disk.c b/kern/disk.c index 544896f2f..075838d1e 100644 --- a/kern/disk.c +++ b/kern/disk.c @@ -464,12 +464,14 @@ grub_disk_read (grub_disk_t disk, grub_disk_addr_t sector, if (disk->read_hook) while (size) { + grub_size_t to_read = (size > GRUB_DISK_SECTOR_SIZE) ? GRUB_DISK_SECTOR_SIZE : size; (disk->read_hook) (sector, real_offset, - ((size > GRUB_DISK_SECTOR_SIZE) - ? GRUB_DISK_SECTOR_SIZE - : size)); + to_read); + if (grub_errno != GRUB_ERR_NONE) + goto finish; + sector++; - size -= GRUB_DISK_SECTOR_SIZE - real_offset; + size -= to_read - real_offset; real_offset = 0; } From 27dea7eda42de98a181a799ee52cd74f1cb201bd Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Wed, 27 Jan 2010 03:18:14 +0000 Subject: [PATCH 308/738] 2010-01-27 Robert Millan * util/hostfs.c: Include `'. (grub_hostfs_read): Handle errors from fseeko() and fread(). --- ChangeLog | 5 +++++ util/hostfs.c | 16 ++++++++++++---- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index e0ee80d22..60ce328bf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-01-27 Robert Millan + + * util/hostfs.c: Include `'. + (grub_hostfs_read): Handle errors from fseeko() and fread(). + 2010-01-27 Robert Millan * kern/disk.c (grub_disk_read): Fix bug that would cause infinite diff --git a/util/hostfs.c b/util/hostfs.c index df930b42e..501ad4664 100644 --- a/util/hostfs.c +++ b/util/hostfs.c @@ -1,7 +1,7 @@ /* hostfs.c - Dummy filesystem to provide access to the hosts filesystem */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2007,2008,2009 Free Software Foundation, Inc. + * Copyright (C) 2007,2008,2009,2010 Free Software Foundation, Inc. * * GRUB is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -26,6 +26,7 @@ #include #include +#include /* dirent.d_type is a BSD extension, not part of POSIX */ @@ -118,10 +119,17 @@ grub_hostfs_read (grub_file_t file, char *buf, grub_size_t len) FILE *f; f = (FILE *) file->data; - fseeko (f, file->offset, SEEK_SET); - int s = fread (buf, 1, len, f); + if (fseeko (f, file->offset, SEEK_SET) != 0) + { + grub_error (GRUB_ERR_OUT_OF_RANGE, "fseeko: %s", strerror (errno)); + return -1; + } - return s; + unsigned int s = fread (buf, 1, len, f); + if (s != len) + grub_error (GRUB_ERR_FILE_READ_ERROR, "fread: %s", strerror (errno)); + + return (signed) s; } static grub_err_t From e709ebe2ef8fc4b64fcf092744a3edd6bba2c9eb Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 27 Jan 2010 16:29:21 +0100 Subject: [PATCH 309/738] 2010-01-27 Vladimir Serbinenko * commands/hashsum.c (hash_file): Avoid possible stack overflow by having a 4KiB and not 32KiB buffer size. --- ChangeLog | 5 +++++ commands/hashsum.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 60ce328bf..aceb55009 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-01-27 Vladimir Serbinenko + + * commands/hashsum.c (hash_file): Avoid possible stack overflow by + having a 4KiB and not 32KiB buffer size. + 2010-01-27 Robert Millan * util/hostfs.c: Include `'. diff --git a/commands/hashsum.c b/commands/hashsum.c index a4e71b844..951479fa7 100644 --- a/commands/hashsum.c +++ b/commands/hashsum.c @@ -57,7 +57,7 @@ static grub_err_t hash_file (grub_file_t file, const gcry_md_spec_t *hash, void *result) { grub_uint8_t context[hash->contextsize]; - char *readbuf[4096]; + grub_uint8_t readbuf[4096]; grub_memset (context, 0, sizeof (context)); hash->init (context); From 989e1f934b0d612ea9e06d0af61ad0f5586cb2e4 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 27 Jan 2010 17:30:03 +0100 Subject: [PATCH 310/738] 2010-01-27 Vladimir Serbinenko * kern/disk.c (grub_disk_read): Fix offset computation when reading last sectors. --- ChangeLog | 5 +++++ kern/disk.c | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index aceb55009..ba4a7d7e3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-01-27 Vladimir Serbinenko + + * kern/disk.c (grub_disk_read): Fix offset computation when reading + last sectors. + 2010-01-27 Vladimir Serbinenko * commands/hashsum.c (hash_file): Avoid possible stack overflow by diff --git a/kern/disk.c b/kern/disk.c index 075838d1e..a01373072 100644 --- a/kern/disk.c +++ b/kern/disk.c @@ -441,7 +441,7 @@ grub_disk_read (grub_disk_t disk, grub_disk_addr_t sector, grub_errno = GRUB_ERR_NONE; - num = ((size + GRUB_DISK_SECTOR_SIZE - 1) + num = ((size + real_offset + pos + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS); p = grub_realloc (tmp_buf, num << GRUB_DISK_SECTOR_BITS); @@ -458,7 +458,7 @@ grub_disk_read (grub_disk_t disk, grub_disk_addr_t sector, goto finish; } - grub_memcpy (buf, tmp_buf + real_offset, size); + grub_memcpy (buf, tmp_buf + pos + real_offset, size); /* Call the read hook, if any. */ if (disk->read_hook) From 63533ab09361a8a623ec95cecdc20cc098fbca51 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 27 Jan 2010 17:47:36 +0100 Subject: [PATCH 311/738] 2010-01-27 Vladimir Serbinenko * normal/cmdline.c (grub_cmdline_get): Fix completion in the middle of the line. --- ChangeLog | 5 +++++ normal/cmdline.c | 18 ++++++++++++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index ba4a7d7e3..a7f995e29 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-01-27 Vladimir Serbinenko + + * normal/cmdline.c (grub_cmdline_get): Fix completion in the middle + of the line. + 2010-01-27 Vladimir Serbinenko * kern/disk.c (grub_disk_read): Fix offset computation when reading diff --git a/normal/cmdline.c b/normal/cmdline.c index bcffffeab..997965fca 100644 --- a/normal/cmdline.c +++ b/normal/cmdline.c @@ -419,10 +419,13 @@ grub_cmdline_get (const char *prompt) int restore; char *insertu8; char *bufu8; + grub_uint32_t c; + c = buf[lpos]; buf[lpos] = '\0'; bufu8 = grub_ucs4_to_utf8_alloc (buf, lpos); + buf[lpos] = c; if (!bufu8) { grub_print_error (); @@ -462,8 +465,19 @@ grub_cmdline_get (const char *prompt) insertlen, 0); if (t > 0) { - insert[t] = 0; - cl_insert (insert); + if (insert[t-1] == ' ' && buf[lpos] == ' ') + { + insert[t-1] = 0; + if (t != 1) + cl_insert (insert); + lpos++; + cl_set_pos_all (); + } + else + { + insert[t] = 0; + cl_insert (insert); + } } grub_free (insertu8); From 2e1cb9bbbf3e5d6ee800037b26f9ae9707787d68 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Thu, 28 Jan 2010 12:49:40 +0000 Subject: [PATCH 312/738] 2010-01-28 Colin Watson * util/grub.d/10_linux.in: This script does not use any of the contents of gettext.sh, only the external command `gettext', so stop sourcing it. (Moreover, gettext.sh isn't necessarily installed in the same prefix as GRUB.) * util/grub.d/10_kfreebsd.in: Likewise. --- ChangeLog | 8 ++++++++ util/grub.d/10_kfreebsd.in | 1 - util/grub.d/10_linux.in | 1 - 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index a7f995e29..59e46f124 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2010-01-28 Colin Watson + + * util/grub.d/10_linux.in: This script does not use any of the + contents of gettext.sh, only the external command `gettext', so stop + sourcing it. (Moreover, gettext.sh isn't necessarily installed in + the same prefix as GRUB.) + * util/grub.d/10_kfreebsd.in: Likewise. + 2010-01-27 Vladimir Serbinenko * normal/cmdline.c (grub_cmdline_get): Fix completion in the middle diff --git a/util/grub.d/10_kfreebsd.in b/util/grub.d/10_kfreebsd.in index b84b90a33..62d2fe321 100644 --- a/util/grub.d/10_kfreebsd.in +++ b/util/grub.d/10_kfreebsd.in @@ -22,7 +22,6 @@ bindir=@bindir@ libdir=@libdir@ . ${libdir}/grub/grub-mkconfig_lib -. ${bindir}/gettext.sh export TEXTDOMAIN=@PACKAGE@ export TEXTDOMAINDIR=@localedir@ diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in index 90a6e83e7..b1c75a25b 100644 --- a/util/grub.d/10_linux.in +++ b/util/grub.d/10_linux.in @@ -22,7 +22,6 @@ bindir=@bindir@ libdir=@libdir@ . ${libdir}/grub/grub-mkconfig_lib -. ${bindir}/gettext.sh export TEXTDOMAIN=@PACKAGE@ export TEXTDOMAINDIR=@localedir@ From ec1444e6dffc8bf907439f1e0bd97c1fb53f78f0 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Thu, 28 Jan 2010 15:27:41 +0000 Subject: [PATCH 313/738] 2010-01-28 Robert Millan * Makefile.in (check): Exit with fail status when one of the tests fails. * tests/example_functional_test.c (example_test): Fix reversed assert. * tests/example_unit_test.c (example_test): Likewise. --- ChangeLog | 7 +++++++ Makefile.in | 10 ++++------ tests/example_functional_test.c | 2 +- tests/example_unit_test.c | 2 +- 4 files changed, 13 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index 59e46f124..d40f765a7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-01-28 Robert Millan + + * Makefile.in (check): Exit with fail status when one of the tests + fails. + * tests/example_functional_test.c (example_test): Fix reversed assert. + * tests/example_unit_test.c (example_test): Likewise. + 2010-01-28 Colin Watson * util/grub.d/10_linux.in: This script does not use any of the diff --git a/Makefile.in b/Makefile.in index d0bbe3b25..aa03002f4 100644 --- a/Makefile.in +++ b/Makefile.in @@ -473,23 +473,21 @@ distcheck: dist check: all $(UNIT_TESTS) $(FUNCTIONAL_TESTS) $(SCRIPTED_TESTS) @list="$(UNIT_TESTS)"; \ + set -e; \ for file in $$list; do \ $(builddir)/$$file; \ done @list="$(FUNCTIONAL_TESTS)"; \ + set -e; \ for file in $$list; do \ mod=`basename $$file .mod`; \ echo "insmod functional_test; insmod $$mod; functional_test" \ | $(builddir)/grub-shell; \ done @list="$(SCRIPTED_TESTS)"; \ + set -e; \ for file in $$list; do \ - echo "$$file:"; \ - if $(builddir)/$$file; then \ - echo "$$file: PASS"; \ - else \ - echo "$$file: FAIL"; \ - fi; \ + $(builddir)/$$file; \ done .SUFFIX: diff --git a/tests/example_functional_test.c b/tests/example_functional_test.c index f43c0f1ce..6802d2d53 100644 --- a/tests/example_functional_test.c +++ b/tests/example_functional_test.c @@ -28,7 +28,7 @@ example_test (void) /* Check if 1st argument is true and report with custom error message. */ grub_test_assert (2 == 2, "2 equal 2 expected"); - grub_test_assert (2 == 3, "2 is not equal to %d", 3); + grub_test_assert (2 != 3, "2 matches %d", 3); } /* Register example_test method as a functional test. */ diff --git a/tests/example_unit_test.c b/tests/example_unit_test.c index 4999f1412..d721a9d0a 100644 --- a/tests/example_unit_test.c +++ b/tests/example_unit_test.c @@ -31,7 +31,7 @@ example_test (void) /* Check if 1st argument is true and report with custom error message. */ grub_test_assert (2 == 2, "2 equal 2 expected"); - grub_test_assert (2 == 3, "2 is not equal to %d", 3); + grub_test_assert (2 != 3, "2 matches %d", 3); } /* Register example_test method as a unit test. */ From 275d6f6bd44f85d2b91a53cfe0622c26034fae8a Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Thu, 28 Jan 2010 21:43:28 +0530 Subject: [PATCH 314/738] fix grub-script-check --- include/grub/script_sh.h | 2 +- util/grub-script-check.c | 22 +++++++++++++--------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/include/grub/script_sh.h b/include/grub/script_sh.h index 0bd14abcd..f6177b02a 100644 --- a/include/grub/script_sh.h +++ b/include/grub/script_sh.h @@ -112,7 +112,7 @@ struct grub_script_cmd_menuentry struct grub_script_arglist *arglist; /* The sourcecode the entry will be generated from. */ - char *sourcecode; + const char *sourcecode; /* Options. XXX: Not used yet. */ int options; diff --git a/util/grub-script-check.c b/util/grub-script-check.c index 3bfd6a425..5bc5df1c1 100644 --- a/util/grub-script-check.c +++ b/util/grub-script-check.c @@ -82,16 +82,8 @@ grub_script_execute_cmdif (struct grub_script_cmd *cmd __attribute__ ((unused))) } grub_err_t -grub_script_execute_menuentry (struct grub_script_cmd *cmd) +grub_script_execute_menuentry (struct grub_script_cmd *cmd __attribute__ ((unused))) { - struct grub_script_cmd_menuentry *menu; - menu = (struct grub_script_cmd_menuentry *)cmd; - - if (menu->sourcecode) - { - grub_free (menu->sourcecode); - menu->sourcecode = 0; - } return 0; } @@ -146,6 +138,7 @@ main (int argc, char *argv[]) auto grub_err_t get_config_line (char **line, int cont); grub_err_t get_config_line (char **line, int cont __attribute__ ((unused))) { + int i; char *cmdline = 0; size_t len = 0; ssize_t read; @@ -164,6 +157,17 @@ main (int argc, char *argv[]) if (verbose) grub_printf("%s", cmdline); + for (i = 0; cmdline[i] != '\0'; i++) + { + /* Replace tabs and carriage returns with spaces. */ + if (cmdline[i] == '\t' || cmdline[i] == '\r') + cmdline[i] = ' '; + + /* Replace '\n' with '\0'. */ + if (cmdline[i] == '\n') + cmdline[i] = '\0'; + } + *line = grub_strdup (cmdline); free (cmdline); From f45d2663b08b4df452e054261cbf229d9c4779a5 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Thu, 28 Jan 2010 21:46:59 +0530 Subject: [PATCH 315/738] add changelog --- ChangeLog | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ChangeLog b/ChangeLog index a7f995e29..c000b38d6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-01-28 BVK Chaitanya + + * include/grub/script_sh.h (sourcecode): Add const qualifier. + * util/grub-script-check.c (getline): Fix empty lines case. + 2010-01-27 Vladimir Serbinenko * normal/cmdline.c (grub_cmdline_get): Fix completion in the middle From bf7fcba2d7665e01c6bd6f5c2fd9da4ce69d9674 Mon Sep 17 00:00:00 2001 From: Christian Schmitt Date: Thu, 28 Jan 2010 23:10:37 +0100 Subject: [PATCH 316/738] 2010-01-28 Christian Schmitt * util/ieee1275/grub-install.in: Fix nvsetenv arguments. --- ChangeLog | 4 ++++ util/ieee1275/grub-install.in | 10 +++++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4e30a39a8..f0d881599 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-01-28 Christian Schmitt + + * util/ieee1275/grub-install.in: Fix nvsetenv arguments. + 2010-01-28 BVK Chaitanya * include/grub/script_sh.h (sourcecode): Add const qualifier. diff --git a/util/ieee1275/grub-install.in b/util/ieee1275/grub-install.in index 9a26b0dca..97c485d55 100644 --- a/util/ieee1275/grub-install.in +++ b/util/ieee1275/grub-install.in @@ -46,8 +46,8 @@ install_device= debug=no update_nvram=yes -ofpathname=/usr/sbin/ofpathname -nvsetenv=/sbin/nvsetenv +ofpathname=`which ofpathname` +nvsetenv=`which nvsetenv` # Usage: usage # Print the usage. @@ -216,11 +216,11 @@ if test $update_nvram = yes; then } # Point boot-device at the new grub install - boot_device="boot-device $ofpath:$partno,\\grub" - "$nvsetenv" "$boot_device" || { + boot_device="$ofpath:$partno,\\grub" + "$nvsetenv" boot-device "$boot_device" || { echo "$nvsetenv failed." echo "You will have to set boot-device manually. At the Open Firmware prompt, type:" - echo " setenv $boot_device" + echo " setenv boot-device $boot_device" exit 1 } fi From 61e89d9db65c78389111b5e5e8696145a3eb1b82 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 31 Jan 2010 01:26:11 +0100 Subject: [PATCH 317/738] 2010-01-31 Vladimir Serbinenko * font/font.c (find_glyph): Check that bmp_idx is available before using it. (grub_font_get_string_width): Never call grub_font_get_glyph_internal with (font == NULL). --- ChangeLog | 7 +++++++ font/font.c | 7 ++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index f0d881599..eced79d59 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-01-31 Vladimir Serbinenko + + * font/font.c (find_glyph): Check that bmp_idx is available before + using it. + (grub_font_get_string_width): Never call grub_font_get_glyph_internal + with (font == NULL). + 2010-01-28 Christian Schmitt * util/ieee1275/grub-install.in: Fix nvsetenv arguments. diff --git a/font/font.c b/font/font.c index 639f4d720..16f2ed35b 100644 --- a/font/font.c +++ b/font/font.c @@ -668,7 +668,7 @@ find_glyph (const grub_font_t font, grub_uint32_t code) table = font->char_index; /* Use BMP index if possible. */ - if (code < 0x10000) + if (code < 0x10000 && font->bmp_idx) { if (font->bmp_idx[code] == 0xffff) return 0; @@ -942,8 +942,9 @@ grub_font_get_string_width (grub_font_t font, const char *str) struct grub_font_glyph * grub_font_get_glyph (grub_font_t font, grub_uint32_t code) { - struct grub_font_glyph *glyph; - glyph = grub_font_get_glyph_internal (font, code); + struct grub_font_glyph *glyph = 0; + if (font) + glyph = grub_font_get_glyph_internal (font, code); if (glyph == 0) { glyph = ascii_glyph_lookup (code); From fbab7b0794256f5b44c5f9769ea272e55cb6bcc1 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 31 Jan 2010 01:57:17 +0100 Subject: [PATCH 318/738] Framebuffer on PowerPC-based macs --- conf/powerpc-ieee1275.rmk | 5 + include/grub/ieee1275/ieee1275.h | 4 + kern/ieee1275/openfw.c | 23 ++- video/ieee1275.c | 298 +++++++++++++++++++++++++++++++ 4 files changed, 327 insertions(+), 3 deletions(-) create mode 100644 video/ieee1275.c diff --git a/conf/powerpc-ieee1275.rmk b/conf/powerpc-ieee1275.rmk index 23bd2d620..8622293ab 100644 --- a/conf/powerpc-ieee1275.rmk +++ b/conf/powerpc-ieee1275.rmk @@ -70,6 +70,11 @@ boot_mod_SOURCES = commands/boot.c lib/i386/pc/biosnum.c boot_mod_CFLAGS = $(COMMON_CFLAGS) boot_mod_LDFLAGS = $(COMMON_LDFLAGS) +pkglib_MODULES += ieee1275_fb.mod +ieee1275_fb_mod_SOURCES = video/ieee1275.c +ieee1275_fb_mod_CFLAGS = $(COMMON_CFLAGS) +ieee1275_fb_mod_LDFLAGS = $(COMMON_LDFLAGS) + # For linux.mod. linux_mod_SOURCES = loader/powerpc/ieee1275/linux.c linux_mod_CFLAGS = $(COMMON_CFLAGS) diff --git a/include/grub/ieee1275/ieee1275.h b/include/grub/ieee1275/ieee1275.h index 8b31e32e2..2aad199da 100644 --- a/include/grub/ieee1275/ieee1275.h +++ b/include/grub/ieee1275/ieee1275.h @@ -176,4 +176,8 @@ int EXPORT_FUNC(grub_claimmap) (grub_addr_t addr, grub_size_t size); char *EXPORT_FUNC(grub_ieee1275_encode_devname) (const char *path); char *EXPORT_FUNC(grub_ieee1275_get_filename) (const char *path); +int EXPORT_FUNC(grub_ieee1275_devices_iterate) (int (*hook) + (struct grub_ieee1275_devalias * + alias)); + #endif /* ! GRUB_IEEE1275_HEADER */ diff --git a/kern/ieee1275/openfw.c b/kern/ieee1275/openfw.c index 5f0aad119..684680231 100644 --- a/kern/ieee1275/openfw.c +++ b/kern/ieee1275/openfw.c @@ -72,7 +72,7 @@ grub_children_iterate (char *devpath, if (grub_ieee1275_get_property (child, "device_type", childtype, IEEE1275_MAX_PROP_LEN, &actual)) - continue; + childtype[0] = 0; if (grub_ieee1275_package_to_path (child, childpath, IEEE1275_MAX_PATH_LEN, &actual)) @@ -82,7 +82,10 @@ grub_children_iterate (char *devpath, IEEE1275_MAX_PROP_LEN, &actual)) continue; - fullname = grub_xasprintf ("%s/%s", devpath, childname); + if (devpath[0] == '/' && devpath[1] == 0) + fullname = grub_xasprintf ("/%s", childname); + else + fullname = grub_xasprintf ("%s/%s", devpath, childname); if (!fullname) { grub_free (childname); @@ -99,7 +102,7 @@ grub_children_iterate (char *devpath, if (ret) break; } - while (grub_ieee1275_peer (child, &child)); + while (grub_ieee1275_peer (child, &child) != -1); grub_free (childname); grub_free (childpath); @@ -108,6 +111,20 @@ grub_children_iterate (char *devpath, return ret; } +int +grub_ieee1275_devices_iterate (int (*hook) (struct grub_ieee1275_devalias *alias)) +{ + auto int it_through (struct grub_ieee1275_devalias *alias); + int it_through (struct grub_ieee1275_devalias *alias) + { + if (hook (alias)) + return 1; + return grub_children_iterate (alias->name, it_through); + } + + return grub_children_iterate ("/", it_through); +} + /* Iterate through all device aliases. This function can be used to find a device of a specific type. */ int diff --git a/video/ieee1275.c b/video/ieee1275.c new file mode 100644 index 000000000..a9fc16a0f --- /dev/null +++ b/video/ieee1275.c @@ -0,0 +1,298 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2006,2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#define grub_video_render_target grub_video_fbrender_target + +#include +#include +#include +#include +#include +#include +#include +#include + +/* Only 8-bit indexed color is supported for now. */ + +static unsigned old_width, old_height; +static int restore_needed; +static char *display; + +static struct +{ + struct grub_video_mode_info mode_info; + struct grub_video_render_target *render_target; + grub_uint8_t *ptr; +} framebuffer; + +static grub_err_t +grub_video_ieee1275_set_palette (unsigned int start, unsigned int count, + struct grub_video_palette_data *palette_data); + +static void +set_video_mode (unsigned width __attribute__ ((unused)), + unsigned height __attribute__ ((unused))) +{ + /* TODO */ +} + +static void +find_display (void) +{ + auto int hook (struct grub_ieee1275_devalias *alias); + int hook (struct grub_ieee1275_devalias *alias) + { + if (grub_strcmp (alias->type, "display") == 0) + { + grub_dprintf ("video", "Found display %s\n", alias->name); + display = grub_strdup (alias->name); + return 1; + } + return 0; + } + + grub_ieee1275_devices_iterate (hook); +} + +static grub_err_t +grub_video_ieee1275_init (void) +{ + grub_memset (&framebuffer, 0, sizeof(framebuffer)); + return grub_video_fb_init (); +} + +static grub_err_t +grub_video_ieee1275_fini (void) +{ + if (restore_needed) + { + set_video_mode (old_width, old_height); + restore_needed = 0; + } + return grub_video_fb_fini (); +} + +static grub_err_t +grub_video_ieee1275_fill_mode_info (grub_ieee1275_phandle_t dev, + struct grub_video_mode_info *out) +{ + grub_uint32_t tmp; + + grub_memset (out, 0, sizeof (*out)); + + if (grub_ieee1275_get_integer_property (dev, "width", &tmp, + sizeof (tmp), 0)) + return grub_error (GRUB_ERR_IO, "Couldn't retrieve display width."); + out->width = tmp; + + if (grub_ieee1275_get_integer_property (dev, "height", &tmp, + sizeof (tmp), 0)) + return grub_error (GRUB_ERR_IO, "Couldn't retrieve display height."); + out->height = tmp; + + if (grub_ieee1275_get_integer_property (dev, "linebytes", &tmp, + sizeof (tmp), 0)) + return grub_error (GRUB_ERR_IO, "Couldn't retrieve display pitch."); + out->pitch = tmp; + + out->mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR; + out->bpp = 8; + out->bytes_per_pixel = 1; + out->number_of_colors = 256; + + out->blit_format = grub_video_get_blit_format (out); + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_video_ieee1275_setup (unsigned int width, unsigned int height, + unsigned int mode_type __attribute__ ((unused)), + unsigned int mode_mask __attribute__ ((unused))) +{ + grub_uint32_t current_width, current_height, address; + grub_err_t err; + grub_ieee1275_phandle_t dev; + + if (!display) + return grub_error (GRUB_ERR_IO, "Couldn't find display device."); + + if (grub_ieee1275_finddevice (display, &dev)) + return grub_error (GRUB_ERR_IO, "Couldn't open display device."); + + if (grub_ieee1275_get_integer_property (dev, "width", ¤t_width, + sizeof (current_width), 0)) + return grub_error (GRUB_ERR_IO, "Couldn't retrieve display width."); + + if (grub_ieee1275_get_integer_property (dev, "height", ¤t_height, + sizeof (current_width), 0)) + return grub_error (GRUB_ERR_IO, "Couldn't retrieve display height."); + + if ((width == current_width && height == current_height) + || (width == 0 && height == 0)) + { + grub_dprintf ("video", "IEEE1275: keeping current mode %dx%d\n", + current_width, current_height); + } + else + { + grub_dprintf ("video", "IEEE1275: Setting mode %dx%d\n", width, height); + /* TODO. */ + } + + err = grub_video_ieee1275_fill_mode_info (dev, &framebuffer.mode_info); + if (err) + { + grub_dprintf ("video", "IEEE1275: couldn't fill mode info\n"); + return err; + } + + if (grub_ieee1275_get_integer_property (dev, "address", &address, + sizeof (address), 0)) + return grub_error (GRUB_ERR_IO, "Couldn't retrieve display address."); + + framebuffer.ptr = (void *) address; + + grub_video_ieee1275_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS, + grub_video_fbstd_colors); + + grub_dprintf ("video", "IEEE1275: initialising FB @ %p %dx%dx%d\n", + framebuffer.ptr, framebuffer.mode_info.width, + framebuffer.mode_info.height, framebuffer.mode_info.bpp); + + err = grub_video_fb_create_render_target_from_pointer + (&framebuffer.render_target, &framebuffer.mode_info, framebuffer.ptr); + + if (err) + { + grub_dprintf ("video", "IEEE1275: Couldn't create FB target\n"); + return err; + } + + err = grub_video_fb_set_active_render_target (framebuffer.render_target); + + if (err) + { + grub_dprintf ("video", "IEEE1275: Couldn't set FB target\n"); + return err; + } + + err = grub_video_fb_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS, + grub_video_fbstd_colors); + + if (err) + grub_dprintf ("video", "IEEE1275: Couldn't set palette\n"); + else + grub_dprintf ("video", "IEEE1275: Success\n"); + + return err; +} + +static grub_err_t +grub_video_ieee1275_swap_buffers (void) +{ + /* TODO: Implement buffer swapping. */ + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_video_ieee1275_set_active_render_target (struct grub_video_render_target *target) +{ + if (target == GRUB_VIDEO_RENDER_TARGET_DISPLAY) + target = framebuffer.render_target; + + return grub_video_fb_set_active_render_target (target); +} + +static grub_err_t +grub_video_ieee1275_get_info_and_fini (struct grub_video_mode_info *mode_info, + void **framebuf) +{ + grub_memcpy (mode_info, &(framebuffer.mode_info), sizeof (*mode_info)); + *framebuf = (char *) framebuffer.ptr; + + grub_video_fb_fini (); + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_video_ieee1275_set_palette (unsigned int start, unsigned int count, + struct grub_video_palette_data *palette_data) +{ + grub_err_t err; + struct grub_video_palette_data fb_palette_data[256]; + + err = grub_video_fb_set_palette (start, count, palette_data); + if (err) + return err; + + grub_video_fb_get_palette (0, 256, fb_palette_data); + + /* TODO. */ + + return GRUB_ERR_NONE; +} + +static struct grub_video_adapter grub_video_ieee1275_adapter = + { + .name = "IEEE1275 video driver", + + .init = grub_video_ieee1275_init, + .fini = grub_video_ieee1275_fini, + .setup = grub_video_ieee1275_setup, + .get_info = grub_video_fb_get_info, + .get_info_and_fini = grub_video_ieee1275_get_info_and_fini, + .set_palette = grub_video_ieee1275_set_palette, + .get_palette = grub_video_fb_get_palette, + .set_viewport = grub_video_fb_set_viewport, + .get_viewport = grub_video_fb_get_viewport, + .map_color = grub_video_fb_map_color, + .map_rgb = grub_video_fb_map_rgb, + .map_rgba = grub_video_fb_map_rgba, + .unmap_color = grub_video_fb_unmap_color, + .fill_rect = grub_video_fb_fill_rect, + .blit_bitmap = grub_video_fb_blit_bitmap, + .blit_render_target = grub_video_fb_blit_render_target, + .scroll = grub_video_fb_scroll, + .swap_buffers = grub_video_ieee1275_swap_buffers, + .create_render_target = grub_video_fb_create_render_target, + .delete_render_target = grub_video_fb_delete_render_target, + .set_active_render_target = grub_video_ieee1275_set_active_render_target, + .get_active_render_target = grub_video_fb_get_active_render_target, + + .next = 0 + }; + +GRUB_MOD_INIT(ieee1275_fb) +{ + find_display (); + if (display) + grub_video_register (&grub_video_ieee1275_adapter); +} + +GRUB_MOD_FINI(ieee1275_fb) +{ + if (restore_needed) + { + set_video_mode (old_width, old_height); + restore_needed = 0; + } + if (display) + grub_video_unregister (&grub_video_ieee1275_adapter); + grub_free (display); +} From 3b205d4ddf7c61363f9868dba14e8b95c22c95b4 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 31 Jan 2010 11:11:03 +0100 Subject: [PATCH 319/738] 2010-01-31 Vladimir Serbinenko * disk/ieee1275/ofdisk.c (grub_ofdisk_iterate): Fix off-by-one error. --- ChangeLog | 4 ++++ disk/ieee1275/ofdisk.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index eced79d59..4598e1b74 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-01-31 Vladimir Serbinenko + + * disk/ieee1275/ofdisk.c (grub_ofdisk_iterate): Fix off-by-one error. + 2010-01-31 Vladimir Serbinenko * font/font.c (find_glyph): Check that bmp_idx is available before diff --git a/disk/ieee1275/ofdisk.c b/disk/ieee1275/ofdisk.c index c8c4d1a4e..051ece0b9 100644 --- a/disk/ieee1275/ofdisk.c +++ b/disk/ieee1275/ofdisk.c @@ -118,7 +118,7 @@ grub_ofdisk_iterate (int (*hook) (const char *name)) static char * compute_dev_path (const char *name) { - char *devpath = grub_malloc (grub_strlen (name) + 2); + char *devpath = grub_malloc (grub_strlen (name) + 3); char *p, c; if (!devpath) From b9c4f55b6fb10c07d96c4dd983d3e58a4ba09504 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Sun, 31 Jan 2010 19:37:37 +0000 Subject: [PATCH 320/738] handle DM-RAID disks in convert_system_partition_to_system_disk --- ChangeLog.dmraid-probe | 2 +- util/hostdisk.c | 25 +++++++++++++++++++------ 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/ChangeLog.dmraid-probe b/ChangeLog.dmraid-probe index 505cf7ba4..c52436bb5 100644 --- a/ChangeLog.dmraid-probe +++ b/ChangeLog.dmraid-probe @@ -1,4 +1,4 @@ -2010-01-26 Colin Watson +2010-01-31 Colin Watson * configure.ac: Check for Linux device-mapper support. diff --git a/util/hostdisk.c b/util/hostdisk.c index 309e112bf..464977978 100644 --- a/util/hostdisk.c +++ b/util/hostdisk.c @@ -937,7 +937,7 @@ convert_system_partition_to_system_disk (const char *os_dev, struct stat *st) uint32_t maj, min; struct dm_tree_node *node, *child; void *handle; - const char *node_uuid, *child_uuid, *child_name; + const char *node_uuid, *mapper_name, *child_uuid, *child_name; if (! tree) tree = dm_tree_create (); @@ -975,6 +975,7 @@ convert_system_partition_to_system_disk (const char *os_dev, struct stat *st) } handle = NULL; + mapper_name = NULL; /* Counter-intuitively, device-mapper refers to the disk-like device containing a DM-RAID partition device as a "child" of the partition device. */ @@ -982,27 +983,39 @@ convert_system_partition_to_system_disk (const char *os_dev, struct stat *st) if (! child) { grub_dprintf ("hostdisk", "%s has no DM children\n", path); - return NULL; + goto devmapper_out; } child_uuid = dm_tree_node_get_uuid (child); if (! child_uuid) { grub_dprintf ("hostdisk", "%s child has no DM uuid\n", path); - return NULL; + goto devmapper_out; } else if (strncmp (child_uuid, "DMRAID-", 7) != 0) { grub_dprintf ("hostdisk", "%s child is not DM-RAID\n", path); - return NULL; + goto devmapper_out; } child_name = dm_tree_node_get_name (child); if (! child_name) { grub_dprintf ("hostdisk", "%s child has no DM name\n", path); - return NULL; + goto devmapper_out; } + mapper_name = child_name; - return xasprintf ("/dev/mapper/%s", child_name); +devmapper_out: + if (! mapper_name) + { + /* This is a DM-RAID disk, not a partition. */ + mapper_name = dm_tree_node_get_name (node); + if (! mapper_name) + { + grub_dprintf ("hostdisk", "%s has no DM name\n", path); + return NULL; + } + } + return xasprintf ("/dev/mapper/%s", mapper_name); } #endif /* HAVE_DEVICE_MAPPER */ } From 996649b073c98b4f13d2908cf887f4bd52d2ce5f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 3 Feb 2010 00:43:55 +0100 Subject: [PATCH 321/738] 2010-02-03 Vladimir Serbinenko * disk/i386/pc/biosdisk.c (grub_biosdisk_read): Handle non-2048 aligned CDROM reads. (grub_biosdisk_write): Refuse to write to CDROM. --- ChangeLog | 6 ++++++ disk/i386/pc/biosdisk.c | 14 +++++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 4598e1b74..83d0c58a8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-02-03 Vladimir Serbinenko + + * disk/i386/pc/biosdisk.c (grub_biosdisk_read): Handle non-2048 aligned + CDROM reads. + (grub_biosdisk_write): Refuse to write to CDROM. + 2010-01-31 Vladimir Serbinenko * disk/ieee1275/ofdisk.c (grub_ofdisk_iterate): Fix off-by-one error. diff --git a/disk/i386/pc/biosdisk.c b/disk/i386/pc/biosdisk.c index 682474b1a..94d0e3708 100644 --- a/disk/i386/pc/biosdisk.c +++ b/disk/i386/pc/biosdisk.c @@ -307,8 +307,17 @@ grub_biosdisk_read (grub_disk_t disk, grub_disk_addr_t sector, while (size) { grub_size_t len; + grub_size_t cdoff = 0; len = get_safe_sectors (sector, data->sectors); + + if (data->flags & GRUB_BIOSDISK_FLAG_CDROM) + { + cdoff = (sector & 3) << GRUB_DISK_SECTOR_BITS; + len = ALIGN_UP (sector + len, 4) - (sector & ~3); + sector &= ~3; + } + if (len > size) len = size; @@ -316,7 +325,7 @@ grub_biosdisk_read (grub_disk_t disk, grub_disk_addr_t sector, GRUB_MEMORY_MACHINE_SCRATCH_SEG)) return grub_errno; - grub_memcpy (buf, (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR, + grub_memcpy (buf, (void *) (GRUB_MEMORY_MACHINE_SCRATCH_ADDR + cdoff), len << GRUB_DISK_SECTOR_BITS); buf += len << GRUB_DISK_SECTOR_BITS; sector += len; @@ -332,6 +341,9 @@ grub_biosdisk_write (grub_disk_t disk, grub_disk_addr_t sector, { struct grub_biosdisk_data *data = disk->data; + if (data->flags & GRUB_BIOSDISK_FLAG_CDROM) + return grub_error (GRUB_ERR_IO, "can't write to CDROM"); + while (size) { grub_size_t len; From 399f6e4d9cf9c1a3aedf2a113f81680e03395c08 Mon Sep 17 00:00:00 2001 From: Torsten Landschoff Date: Wed, 3 Feb 2010 00:46:55 +0100 Subject: [PATCH 322/738] 2010-02-03 Torsten Landschoff * kern/disk.c (grub_disk_read): Fix offset computation when reading last sectors. --- ChangeLog | 5 +++++ kern/disk.c | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 83d0c58a8..d7ae963dd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-02-03 Torsten Landschoff + + * kern/disk.c (grub_disk_read): Fix offset computation when reading + last sectors. + 2010-02-03 Vladimir Serbinenko * disk/i386/pc/biosdisk.c (grub_biosdisk_read): Handle non-2048 aligned diff --git a/kern/disk.c b/kern/disk.c index a01373072..5c30e1727 100644 --- a/kern/disk.c +++ b/kern/disk.c @@ -441,7 +441,7 @@ grub_disk_read (grub_disk_t disk, grub_disk_addr_t sector, grub_errno = GRUB_ERR_NONE; - num = ((size + real_offset + pos + GRUB_DISK_SECTOR_SIZE - 1) + num = ((size + real_offset + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS); p = grub_realloc (tmp_buf, num << GRUB_DISK_SECTOR_BITS); @@ -458,7 +458,7 @@ grub_disk_read (grub_disk_t disk, grub_disk_addr_t sector, goto finish; } - grub_memcpy (buf, tmp_buf + pos + real_offset, size); + grub_memcpy (buf, tmp_buf + real_offset, size); /* Call the read hook, if any. */ if (disk->read_hook) From 2b4068e99251e7e6e123b8440375b6f64fe73291 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 3 Feb 2010 00:49:35 +0100 Subject: [PATCH 323/738] 2010-02-03 Vladimir Serbinenko * util/hostdisk.c (open_device): Don't use partition device when reading before the partition. (grub_util_biosdisk_read): Don't read from partition and before the partition in single operation. (grub_util_biosdisk_write): Don't write to partition and before the partition in single operation. --- ChangeLog | 9 +++++++++ util/hostdisk.c | 37 ++++++++++++++++++++++++++++++++++++- 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index d7ae963dd..54a51afc0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2010-02-03 Vladimir Serbinenko + + * util/hostdisk.c (open_device): Don't use partition device when reading + before the partition. + (grub_util_biosdisk_read): Don't read from partition and before the + partition in single operation. + (grub_util_biosdisk_write): Don't write to partition and before the + partition in single operation. + 2010-02-03 Torsten Landschoff * kern/disk.c (grub_disk_read): Fix offset computation when reading diff --git a/util/hostdisk.c b/util/hostdisk.c index a594f75ec..5c56b7579 100644 --- a/util/hostdisk.c +++ b/util/hostdisk.c @@ -336,7 +336,8 @@ open_device (const grub_disk_t disk, grub_disk_addr_t sector, int flags) char dev[PATH_MAX]; strcpy (dev, map[disk->id].device); - if (disk->partition && strncmp (map[disk->id].device, "/dev/", 5) == 0) + if (disk->partition && sector >= disk->partition->start + && strncmp (map[disk->id].device, "/dev/", 5) == 0) is_partition = linux_find_partition (dev, disk->partition->start); /* Open the partition. */ @@ -490,6 +491,23 @@ grub_util_biosdisk_read (grub_disk_t disk, grub_disk_addr_t sector, { int fd; + /* Split pre-partition and partition reads. */ + if (disk->partition && sector < disk->partition->start + && sector + size > disk->partition->start) + { + grub_err_t err; + err = grub_util_biosdisk_read (disk, sector, + disk->partition->start - sector, + buf); + if (err) + return err; + + return grub_util_biosdisk_read (disk, disk->partition->start, + size - (disk->partition->start - sector), + buf + ((disk->partition->start - sector) + << GRUB_DISK_SECTOR_BITS)); + } + fd = open_device (disk, sector, O_RDONLY); if (fd < 0) return grub_errno; @@ -527,6 +545,23 @@ grub_util_biosdisk_write (grub_disk_t disk, grub_disk_addr_t sector, { int fd; + /* Split pre-partition and partition writes. */ + if (disk->partition && sector < disk->partition->start + && sector + size > disk->partition->start) + { + grub_err_t err; + err = grub_util_biosdisk_write (disk, sector, + disk->partition->start - sector, + buf); + if (err) + return err; + + return grub_util_biosdisk_write (disk, disk->partition->start, + size - (disk->partition->start - sector), + buf + ((disk->partition->start - sector) + << GRUB_DISK_SECTOR_BITS)); + } + fd = open_device (disk, sector, O_WRONLY); if (fd < 0) return grub_errno; From 98f5714739f9978b4e2c16941ba0b75a9b9bb826 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 3 Feb 2010 01:34:55 +0100 Subject: [PATCH 324/738] Fix mips compilation --- conf/mips-yeeloong.rmk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/mips-yeeloong.rmk b/conf/mips-yeeloong.rmk index 964f29384..eb0dc9676 100644 --- a/conf/mips-yeeloong.rmk +++ b/conf/mips-yeeloong.rmk @@ -21,7 +21,7 @@ kernel_img_SOURCES = kern/$(target_cpu)/startup.S \ font/font_cmd.c font/font.c io/bufio.c \ video/video.c video/fb/video_fb.c video/fb/fbblit.c \ video/fb/fbfill.c video/fb/fbutil.c video/bitmap.c \ - video/sm712.c bus/pci.c bus/bonito.c \ + video/bitmap_scale.c video/sm712.c bus/pci.c bus/bonito.c \ term/gfxterm.c commands/extcmd.c lib/arg.c \ symlist.c kernel_img_CFLAGS = $(COMMON_CFLAGS) -DUSE_ASCII_FAILBACK From a800277e8d63dbab8de3f8bd2e8c56ad3e9d5778 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 5 Feb 2010 09:08:22 -0800 Subject: [PATCH 325/738] remove left-over LIBDEVMAPPER substitution --- configure.ac | 1 - 1 file changed, 1 deletion(-) diff --git a/configure.ac b/configure.ac index 4f1a6dffe..8e412f001 100644 --- a/configure.ac +++ b/configure.ac @@ -673,7 +673,6 @@ if test x"$device_mapper_excuse" = x ; then AC_DEFINE([HAVE_DEVICE_MAPPER], [1], [Define to 1 if you have the devmapper library.])], [device_mapper_excuse="need devmapper library"]) - AC_SUBST([LIBDEVMAPPER]) fi AC_SUBST(ASFLAGS) From 58b78c121d96defe92ea8e60fe6b730cbd0f496d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 5 Feb 2010 23:04:09 +0100 Subject: [PATCH 326/738] error on unsupported resolution --- video/ieee1275.c | 1 + 1 file changed, 1 insertion(+) diff --git a/video/ieee1275.c b/video/ieee1275.c index a9fc16a0f..21b65bd32 100644 --- a/video/ieee1275.c +++ b/video/ieee1275.c @@ -152,6 +152,7 @@ grub_video_ieee1275_setup (unsigned int width, unsigned int height, { grub_dprintf ("video", "IEEE1275: Setting mode %dx%d\n", width, height); /* TODO. */ + return grub_error (GRUB_ERR_IO, "can't set mode %dx%d", width, height); } err = grub_video_ieee1275_fill_mode_info (dev, &framebuffer.mode_info); From 4f8528fc2b30a7ef05f7896f54cec961ce49276b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 6 Feb 2010 00:30:25 +0100 Subject: [PATCH 327/738] 2010-02-06 Vladimir Serbinenko * kern/ieee1275/openfw.c (grub_devalias_iterate): Stop iterating on error. --- ChangeLog | 5 +++++ kern/ieee1275/openfw.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 54a51afc0..d92d92117 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-02-06 Vladimir Serbinenko + + * kern/ieee1275/openfw.c (grub_devalias_iterate): Stop iterating on + error. + 2010-02-03 Vladimir Serbinenko * util/hostdisk.c (open_device): Don't use partition device when reading diff --git a/kern/ieee1275/openfw.c b/kern/ieee1275/openfw.c index 5f0aad119..39432c584 100644 --- a/kern/ieee1275/openfw.c +++ b/kern/ieee1275/openfw.c @@ -135,7 +135,7 @@ grub_devalias_iterate (int (*hook) (struct grub_ieee1275_devalias *alias)) /* Find the first property. */ aliasname[0] = '\0'; - while (grub_ieee1275_next_property (aliases, aliasname, aliasname)) + while (grub_ieee1275_next_property (aliases, aliasname, aliasname) > 0) { grub_ieee1275_phandle_t dev; grub_ssize_t pathlen; From 5562834e18004d4639dc6bcf1b9a20d925d9869c Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 6 Feb 2010 00:32:07 +0100 Subject: [PATCH 328/738] 2010-02-06 Vladimir Serbinenko * kern/ieee1275/openfw.c (grub_ieee1275_encode_devname): Support whole disk devices. --- ChangeLog | 5 +++++ kern/ieee1275/openfw.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index d92d92117..e2a8f7575 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-02-06 Vladimir Serbinenko + + * kern/ieee1275/openfw.c (grub_ieee1275_encode_devname): Support whole + disk devices. + 2010-02-06 Vladimir Serbinenko * kern/ieee1275/openfw.c (grub_devalias_iterate): Stop iterating on diff --git a/kern/ieee1275/openfw.c b/kern/ieee1275/openfw.c index 39432c584..dd9a9138f 100644 --- a/kern/ieee1275/openfw.c +++ b/kern/ieee1275/openfw.c @@ -374,7 +374,7 @@ grub_ieee1275_encode_devname (const char *path) char *partition = grub_ieee1275_parse_args (path, GRUB_PARSE_PARTITION); char *encoding; - if (partition) + if (partition && partition[0]) { unsigned int partno = grub_strtoul (partition, 0, 0); From 3746a6bc3191c93a41216d03f8436c838dba6d99 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 6 Feb 2010 15:25:59 +0100 Subject: [PATCH 329/738] 2010-02-06 Vladimir Serbinenko * fs/i386/pc/pxe.c (grub_pxefs_dir): Return with failure on non-pxe disk. (grub_pxefs_open): Likewise. --- ChangeLog | 6 ++++++ fs/i386/pc/pxe.c | 8 +++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 117933d07..eed0f93bc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-02-06 Vladimir Serbinenko + + * fs/i386/pc/pxe.c (grub_pxefs_dir): Return with failure on + non-pxe disk. + (grub_pxefs_open): Likewise. + 2010-02-06 Colin D Bennett * conf/common.rmk (pkglib_MODULES): Add gfxmenu.mod. diff --git a/fs/i386/pc/pxe.c b/fs/i386/pc/pxe.c index 8bfe17594..92529883e 100644 --- a/fs/i386/pc/pxe.c +++ b/fs/i386/pc/pxe.c @@ -173,12 +173,15 @@ static struct grub_disk_dev grub_pxe_dev = }; static grub_err_t -grub_pxefs_dir (grub_device_t device __attribute__ ((unused)), +grub_pxefs_dir (grub_device_t device, const char *path __attribute__ ((unused)), int (*hook) (const char *filename, const struct grub_dirhook_info *info) __attribute__ ((unused))) { + if (device->disk->dev->id != GRUB_DISK_DEVICE_PXE_ID) + return grub_error (GRUB_ERR_IO, "not a pxe disk"); + return GRUB_ERR_NONE; } @@ -194,6 +197,9 @@ grub_pxefs_open (struct grub_file *file, const char *name) struct grub_pxe_disk_data *disk_data = file->device->disk->data; grub_file_t file_int, bufio; + if (file->device->disk->dev->id != GRUB_DISK_DEVICE_PXE_ID) + return grub_error (GRUB_ERR_IO, "not a pxe disk"); + if (curr_file != 0) { grub_pxe_call (GRUB_PXENV_TFTP_CLOSE, &c.c2); From 911df80c54af99b2e83a6ab1e51e813f7a9f81f0 Mon Sep 17 00:00:00 2001 From: Yves Blusseau Date: Sat, 6 Feb 2010 15:37:23 +0100 Subject: [PATCH 330/738] 2010-02-06 Yves Blusseau * conf/common.rmk (grub_script_check_SOURCES): add missing dependencies. (grub_mkpasswd_pbkdf2_SOURCES): Likewise. --- ChangeLog | 5 +++++ conf/common.rmk | 5 +++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index eed0f93bc..ba2561819 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-02-06 Yves Blusseau + + * conf/common.rmk (grub_script_check_SOURCES): add missing dependencies. + (grub_mkpasswd_pbkdf2_SOURCES): Likewise. + 2010-02-06 Vladimir Serbinenko * fs/i386/pc/pxe.c (grub_pxefs_dir): Return with failure on diff --git a/conf/common.rmk b/conf/common.rmk index 13ca431ba..6cce36395 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -94,7 +94,8 @@ grub_bin2h_SOURCES = gnulib/progname.c util/bin2h.c # For grub-script-check. bin_UTILITIES += grub-script-check util/grub-script-check.c_DEPENDENCIES = grub_script_check_init.h -grub_script_check_SOURCES = gnulib/progname.c util/grub-script-check.c util/misc.c \ +grub_script_check_SOURCES = gnulib/progname.c gnulib/getdelim.c gnulib/getline.c \ + util/grub-script-check.c util/misc.c \ script/main.c script/script.c script/function.c script/lexer.c \ kern/handler.c kern/err.c kern/parser.c kern/list.c \ kern/misc.c kern/env.c grub_script_check_init.c grub_script.tab.c @@ -759,7 +760,7 @@ password_pbkdf2_mod_CFLAGS = $(COMMON_CFLAGS) password_pbkdf2_mod_LDFLAGS = $(COMMON_LDFLAGS) bin_UTILITIES += grub-mkpasswd-pbkdf2 -grub_mkpasswd_pbkdf2_SOURCES = gnulib/progname.c util/grub-mkpasswd-pbkdf2.c lib/crypto.c lib/libgcrypt-grub/cipher/sha512.c lib/pbkdf2.c util/misc.c kern/err.c +grub_mkpasswd_pbkdf2_SOURCES = gnulib/progname.c gnulib/getdelim.c gnulib/getline.c util/grub-mkpasswd-pbkdf2.c lib/crypto.c lib/libgcrypt-grub/cipher/sha512.c lib/pbkdf2.c util/misc.c kern/err.c grub_mkpasswd_pbkdf2_CFLAGS += -Wno-missing-field-initializers -Wno-error -I$(srcdir)/lib/libgcrypt_wrap -DGRUB_MKPASSWD=1 include $(srcdir)/conf/gcry.mk From 89494cb55c887e7b3150dbcfed50fd360521a67b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 6 Feb 2010 15:51:22 +0100 Subject: [PATCH 331/738] 2010-02-06 Vladimir Serbinenko * disk/ieee1275/ofdisk.c (grub_ofdisk_read): Correct error handling. --- ChangeLog | 4 ++++ disk/ieee1275/ofdisk.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index ba2561819..72d5bd899 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,10 @@ * conf/common.rmk (grub_script_check_SOURCES): add missing dependencies. (grub_mkpasswd_pbkdf2_SOURCES): Likewise. +2010-02-06 Vladimir Serbinenko + + * disk/ieee1275/ofdisk.c (grub_ofdisk_read): Correct error handling. + 2010-02-06 Vladimir Serbinenko * fs/i386/pc/pxe.c (grub_pxefs_dir): Return with failure on diff --git a/disk/ieee1275/ofdisk.c b/disk/ieee1275/ofdisk.c index 051ece0b9..238cff33d 100644 --- a/disk/ieee1275/ofdisk.c +++ b/disk/ieee1275/ofdisk.c @@ -248,7 +248,7 @@ grub_ofdisk_read (grub_disk_t disk, grub_disk_addr_t sector, (long long) sector); grub_ieee1275_read ((grub_ieee1275_ihandle_t) (unsigned long) disk->data, buf, size * 512UL, &actual); - if (actual != actual) + if (actual != (grub_ssize_t) (size * 512UL)) return grub_error (GRUB_ERR_READ_ERROR, "read error on block: %llu", (long long) sector); From 7b5d0fe4440c8a061ab9a9cb3089b546cb9f88f6 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 6 Feb 2010 15:53:39 +0100 Subject: [PATCH 332/738] Increase heap limit --- kern/ieee1275/init.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kern/ieee1275/init.c b/kern/ieee1275/init.c index f3a4f4d81..75f261a71 100644 --- a/kern/ieee1275/init.c +++ b/kern/ieee1275/init.c @@ -38,11 +38,11 @@ #define HEAP_MIN_SIZE (unsigned long) (2 * 1024 * 1024) /* The maximum heap size we're going to claim */ -#define HEAP_MAX_SIZE (unsigned long) (4 * 1024 * 1024) +#define HEAP_MAX_SIZE (unsigned long) (32 * 1024 * 1024) /* If possible, we will avoid claiming heap above this address, because it seems to cause relocation problems with OSes that link at 4 MiB */ -#define HEAP_MAX_ADDR (unsigned long) (4 * 1024 * 1024) +#define HEAP_MAX_ADDR (unsigned long) (32 * 1024 * 1024) extern char _start[]; extern char _end[]; From 09706ce58a85af4ba3b9306c02ebf8f560f857a0 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 6 Feb 2010 16:00:29 +0100 Subject: [PATCH 333/738] Fixed ChangeLog --- ChangeLog | 14 ++++++++++---- ChangeLog.gfxmenu | 0 ChangeLog.mkconfig | 5 ----- 3 files changed, 10 insertions(+), 9 deletions(-) delete mode 100644 ChangeLog.gfxmenu delete mode 100644 ChangeLog.mkconfig diff --git a/ChangeLog b/ChangeLog index 72d5bd899..c0c15024e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,18 +1,24 @@ +2010-02-06 Vladimir Serbinenko + + * disk/ieee1275/ofdisk.c (grub_ofdisk_read): Correct error handling. + 2010-02-06 Yves Blusseau * conf/common.rmk (grub_script_check_SOURCES): add missing dependencies. (grub_mkpasswd_pbkdf2_SOURCES): Likewise. -2010-02-06 Vladimir Serbinenko - - * disk/ieee1275/ofdisk.c (grub_ofdisk_read): Correct error handling. - 2010-02-06 Vladimir Serbinenko * fs/i386/pc/pxe.c (grub_pxefs_dir): Return with failure on non-pxe disk. (grub_pxefs_open): Likewise. +2010-02-06 Robert Millan + + * util/grub.d/10_hurd.in: Add --class information to menuentries. + * util/grub.d/10_kfreebsd.in: Likewise. + * util/grub.d/10_linux.in: Likewise. + 2010-02-06 Colin D Bennett * conf/common.rmk (pkglib_MODULES): Add gfxmenu.mod. diff --git a/ChangeLog.gfxmenu b/ChangeLog.gfxmenu deleted file mode 100644 index e69de29bb..000000000 diff --git a/ChangeLog.mkconfig b/ChangeLog.mkconfig deleted file mode 100644 index 665c938c7..000000000 --- a/ChangeLog.mkconfig +++ /dev/null @@ -1,5 +0,0 @@ -2010-01-07 Robert Millan - - * util/grub.d/10_hurd.in: Add --class information to menuentries. - * util/grub.d/10_kfreebsd.in: Likewise. - * util/grub.d/10_linux.in: Likewise. From e0a3000a5cab9e6d306e8af82301f9b0f1087940 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 6 Feb 2010 16:00:56 +0100 Subject: [PATCH 334/738] ChangeLog --- ChangeLog.ofwfb | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 ChangeLog.ofwfb diff --git a/ChangeLog.ofwfb b/ChangeLog.ofwfb new file mode 100644 index 000000000..49063b54d --- /dev/null +++ b/ChangeLog.ofwfb @@ -0,0 +1,16 @@ +2010-02-06 Vladimir Serbinenko + + * conf/powerpc-ieee1275.rmk (pkglib_MODULES): Add ieee1275_fb.mod. + (ieee1275_fb_mod_SOURCES): New variable. + (ieee1275_fb_mod_CFLAGS): Likewise. + (ieee1275_fb_mod_LDFLAGS): Likewise. + * include/grub/ieee1275/ieee1275.h (grub_ieee1275_devices_iterate): + New proto. + * kern/ieee1275/init.c (HEAP_MAX_SIZE): Increased. + (HEAP_MAX_ADDR): Likewise. + * kern/ieee1275/openfw.c (grub_children_iterate): Don't skip empty + type. + Correct stop condition. + (grub_ieee1275_devices_iterate): New function. + * video/ieee1275.c: New file. + From 51906b8c8a774ce75737fec2396472e0827f9186 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 6 Feb 2010 16:32:45 +0100 Subject: [PATCH 335/738] 2010-02-06 Vladimir Serbinenko * loader/i386/pc/xnu.c (grub_xnu_set_video): Add const qualifier to modevar. Return grub_errno on allocation error. --- ChangeLog | 6 ++++++ loader/i386/pc/xnu.c | 6 +++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index c0c15024e..6da224094 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-02-06 Vladimir Serbinenko + + * loader/i386/pc/xnu.c (grub_xnu_set_video): Add const qualifier to + modevar. + Return grub_errno on allocation error. + 2010-02-06 Vladimir Serbinenko * disk/ieee1275/ofdisk.c (grub_ofdisk_read): Correct error handling. diff --git a/loader/i386/pc/xnu.c b/loader/i386/pc/xnu.c index 57937946b..39a595d9b 100644 --- a/loader/i386/pc/xnu.c +++ b/loader/i386/pc/xnu.c @@ -35,7 +35,8 @@ grub_xnu_set_video (struct grub_xnu_boot_params *params) { struct grub_video_mode_info mode_info; int ret; - char *tmp, *modevar; + char *tmp; + const char *modevar; void *framebuffer; grub_err_t err; struct grub_video_bitmap *bitmap = NULL; @@ -51,8 +52,7 @@ grub_xnu_set_video (struct grub_xnu_boot_params *params) { tmp = grub_xasprintf ("%s;" DEFAULT_VIDEO_MODE, modevar); if (! tmp) - return grub_error (GRUB_ERR_OUT_OF_MEMORY, - "couldn't allocate temporary storag"); + return grub_errno; err = grub_video_set_mode (tmp, GRUB_VIDEO_MODE_TYPE_PURE_TEXT | GRUB_VIDEO_MODE_TYPE_DEPTH_MASK, From 15cb7d433feada360f1a25a22bace90badaf7c00 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 6 Feb 2010 18:43:37 +0100 Subject: [PATCH 336/738] Reimport nestpart --- ChangeLog.nestpart | 73 ++++++++++++ commands/blocklist.c | 3 +- commands/loadenv.c | 11 +- conf/any-emu.rmk | 2 +- conf/common.rmk | 12 +- conf/i386-pc.rmk | 2 +- conf/sparc64-ieee1275.rmk | 4 +- include/grub/bsdlabel.h | 89 ++++++++++++++ include/grub/msdos_partition.h | 94 --------------- include/grub/partition.h | 21 ++-- kern/disk.c | 18 ++- kern/partition.c | 164 +++++++++++++++++++++++--- loader/i386/bsd.c | 19 +-- loader/i386/multiboot_mbi.c | 21 +--- loader/i386/pc/chainloader.c | 21 +++- partmap/acorn.c | 61 +--------- partmap/amiga.c | 67 +---------- partmap/apple.c | 72 ++---------- partmap/bsdlabel.c | 97 ++++++++++++++++ partmap/gpt.c | 80 +++---------- partmap/msdos.c | 205 +++------------------------------ partmap/sun.c | 59 +--------- parttool/msdospart.c | 4 +- util/grub-probe.c | 5 +- util/hostdisk.c | 41 +++---- util/i386/pc/grub-setup.c | 36 +++--- 26 files changed, 561 insertions(+), 720 deletions(-) create mode 100644 ChangeLog.nestpart create mode 100644 include/grub/bsdlabel.h create mode 100644 partmap/bsdlabel.c diff --git a/ChangeLog.nestpart b/ChangeLog.nestpart new file mode 100644 index 000000000..a2726181b --- /dev/null +++ b/ChangeLog.nestpart @@ -0,0 +1,73 @@ +2009-06-08 Vladimir Serbinenko + + Nested partitions + + * commands/blocklist.c (grub_cmd_blocklist): Don't check whether + 'partition' is NULL, grub_partition_get_start already does that. + * commands/loadenv.c (check_blocklists): Likewise. + (write_blocklists): Likewise. + * conf/common.rmk (grub_probe_SOURCES): Add partmap/bsdlabel.c. + (grub_fstest_SOURCES): Likewise. + (pkglib_MODULES): Add bsdlabel.mod. + (bsdlabel_mod_SOURCES): New variable. + (bsdlabel_mod_CFLAGS): Likewise. + (bsdlabel_mod_LDFLAGS): Likewise. + * conf/i386-coreboot.rmk (grub_emu_SOURCES): Add partmap/bsdlabel.c. + * conf/i386-pc.rmk (grub_setup_SOURCES): Likewise. + (grub_emu_SOURCES): Likewise. + * conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise. + * conf/sparc64-ieee1275.rmk (grub_emu_SOURCES): Likewise. + * include/grub/bsdlabel.h: New file. + * include/grub/partition.h (grub_partition_map): Remove 'probe' and + 'get_name'. + (grub_partition): Add 'parent' and 'number'. + (grub_partition_get_start): Handle nested partitions. + * include/grub/pc_partition.h: Remove bsd-related entries. + (grub_pc_partition): Remove. + * kern/disk.c (grub_disk_close): Free partition data. + (grub_disk_adjust_range): Handle nested partitions. + * kern/partition.c (grub_partition_map_probe): New function. + (grub_partition_probe): Parse name to number, handle subpartitions. + (get_partmap): New function. + (grub_partition_iterate): Handle subpartitions. + (grub_partition_get_name): Likewise. + * loader/i386/pc/bsd.c (grub_bsd_get_device): Likewise. + * loader/i386/multiboot.c (grub_multiboot_get_bootdev): Likewise. + * loader/i386/pc/chainloader.c (grub_chainloader_cmd): Likewise. + * partmap/acorn.c (acorn_partition_map_iterate): Don't force raw access. + Set 'number'. + (acorn_partition_map_probe): Remove. + (acorn_partition_map_get_name): Likewise. + * partmap/amiga.c (amiga_partition_map_iterate): Don't force raw access. + Set 'number'. + Set 'index' to 0 since there can be only one partition entry per sector. + (amiga_partition_map_probe): Remove. + (amiga_partition_map_get_name): Likewise. + * partmap/apple.c (apple_partition_map_iterate): Don't force raw access. + Set 'number'. + Set 'offset' and 'index' to real positions of partitions. + (apple_partition_map_probe): Remove. + (apple_partition_map_get_name): Likewise. + * partmap/bsdlabel.c: New file. + * partmap/gpt.c (gpt_partition_map_iterate): Don't force raw access. + Set 'number'. + Allocate 'data' so it can be correctly freed. + Set 'index' to offset inside sector. + (gpt_partition_map_probe): Remove. + (gpt_partition_map_get_name): Likewise. + * partmap/pc.c (grub_partition_parse): Remove. + (pc_partition_map_iterate): Don't force raw access. + Set 'number'. + Make 'ext_offset' a local variable. + (pc_partition_map_probe): Remove. + (pc_partition_map_get_name): Remove. + * partmap/sun.c (sun_partition_map_iterate): Don't force raw access. + Set 'number'. + (sun_partition_map_probe): Remove. + (sun_partition_map_get_name): Likewise. + * parttool/pcpart.c (grub_pcpart_boot): Handle nested partitions. + (grub_pcpart_type): Likewise. + * util/hostdisk.c (open_device): Handle new numbering scheme. + (grub_util_biosdisk_get_grub_dev): Handle nested partitions. + * util/i386/pc/grub-setup.c (setup): Handle new numbering scheme. + * util/grub-probe.c (probe_partmap): Handle nested paritions. diff --git a/commands/blocklist.c b/commands/blocklist.c index fec59a828..cace31113 100644 --- a/commands/blocklist.c +++ b/commands/blocklist.c @@ -90,8 +90,7 @@ grub_cmd_blocklist (grub_command_t cmd __attribute__ ((unused)), return grub_error (GRUB_ERR_BAD_DEVICE, "this command is available only for disk devices"); - if (file->device->disk->partition) - part_start = grub_partition_get_start (file->device->disk->partition); + part_start = grub_partition_get_start (file->device->disk->partition); file->read_hook = read_blocklist; diff --git a/commands/loadenv.c b/commands/loadenv.c index 51b88cbc9..d763b2d5e 100644 --- a/commands/loadenv.c +++ b/commands/loadenv.c @@ -235,10 +235,8 @@ check_blocklists (grub_envblk_t envblk, struct blocklist *blocklists, /* One more sanity check. Re-read all sectors by blocklists, and compare those with the data read via a file. */ disk = file->device->disk; - if (disk->partition) - part_start = grub_partition_get_start (disk->partition); - else - part_start = 0; + + part_start = grub_partition_get_start (disk->partition); buf = grub_envblk_buffer (envblk); for (p = blocklists, index = 0; p; index += p->length, p = p->next) @@ -268,10 +266,7 @@ write_blocklists (grub_envblk_t envblk, struct blocklist *blocklists, buf = grub_envblk_buffer (envblk); disk = file->device->disk; - if (disk->partition) - part_start = grub_partition_get_start (disk->partition); - else - part_start = 0; + part_start = grub_partition_get_start (disk->partition); index = 0; for (p = blocklists; p; index += p->length, p = p->next) diff --git a/conf/any-emu.rmk b/conf/any-emu.rmk index 1277af791..aaee3ec53 100644 --- a/conf/any-emu.rmk +++ b/conf/any-emu.rmk @@ -34,7 +34,7 @@ grub_emu_SOURCES = commands/minicmd.c commands/cat.c commands/cmp.c \ script/main.c script/execute.c script/function.c \ script/lexer.c script/script.c grub_script.tab.c \ partmap/amiga.c partmap/apple.c partmap/msdos.c partmap/sun.c \ - partmap/acorn.c partmap/gpt.c \ + partmap/acorn.c partmap/gpt.c partmap/bsd.c \ \ fs/affs.c fs/cpio.c fs/fat.c fs/ext2.c fs/hfs.c \ fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \ diff --git a/conf/common.rmk b/conf/common.rmk index 2ea8ebd5a..4cf20463c 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -32,7 +32,8 @@ grub_probe_SOURCES = gnulib/progname.c util/grub-probe.c \ fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/afs_be.c \ fs/befs.c fs/befs_be.c fs/tar.c \ \ - partmap/msdos.c partmap/apple.c partmap/sun.c partmap/gpt.c\ + partmap/msdos.c partmap/bsdlabel.c partmap/apple.c \ + partmap/sun.c partmap/gpt.c\ kern/fs.c kern/env.c fs/fshelp.c \ disk/raid.c disk/mdraid_linux.c disk/lvm.c grub_probe_init.c @@ -69,8 +70,8 @@ grub_fstest_SOURCES = gnulib/progname.c util/grub-fstest.c util/hostfs.c \ fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/afs_be.c fs/befs.c \ fs/befs_be.c fs/tar.c \ \ - kern/partition.c partmap/msdos.c partmap/apple.c partmap/sun.c \ - partmap/gpt.c \ + kern/partition.c partmap/msdos.c partmap/bsdlabel.c \ + partmap/apple.c partmap/sun.c partmap/gpt.c \ kern/fs.c kern/env.c fs/fshelp.c disk/raid.c \ disk/raid5_recover.c disk/raid6_recover.c \ disk/mdraid_linux.c disk/dmraid_nvidia.c disk/lvm.c \ @@ -376,6 +377,11 @@ part_gpt_mod_SOURCES = partmap/gpt.c part_gpt_mod_CFLAGS = $(COMMON_CFLAGS) part_gpt_mod_LDFLAGS = $(COMMON_LDFLAGS) +pkglib_MODULES += part_bsd.mod +part_bsd_mod_SOURCES = partmap/bsdlabel.c +part_bsd_mod_CFLAGS = $(COMMON_CFLAGS) +part_bsd_mod_LDFLAGS = $(COMMON_LDFLAGS) + # Special disk structures and generic drivers pkglib_MODULES += raid.mod raid5rec.mod raid6rec.mod mdraid.mod dm_nv.mod \ diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk index 580bfea0a..efbf5bfa2 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -104,7 +104,7 @@ grub_setup_SOURCES = gnulib/progname.c \ fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/afs_be.c \ fs/befs.c fs/befs_be.c fs/tar.c \ \ - partmap/msdos.c partmap/gpt.c \ + partmap/msdos.c partmap/bsdlabel.c partmap/gpt.c \ \ disk/raid.c disk/mdraid_linux.c disk/lvm.c \ util/raid.c util/lvm.c \ diff --git a/conf/sparc64-ieee1275.rmk b/conf/sparc64-ieee1275.rmk index befc7dce5..9ec8dd22c 100644 --- a/conf/sparc64-ieee1275.rmk +++ b/conf/sparc64-ieee1275.rmk @@ -78,8 +78,8 @@ grub_setup_SOURCES = util/sparc64/ieee1275/grub-setup.c util/hostdisk.c \ fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/afs_be.c \ fs/befs.c fs/befs_be.c fs/tar.c \ \ - partmap/amiga.c partmap/apple.c partmap/msdos.c \ - partmap/sun.c partmap/acorn.c \ + partmap/amiga.c partmap/apple.c partmap/msdos.c \ + partmap/bsdlabel.c partmap/sun.c partmap/acorn.c \ \ disk/raid.c disk/mdraid_linux.c disk/lvm.c \ util/raid.c util/lvm.c gnulib/progname.c \ diff --git a/include/grub/bsdlabel.h b/include/grub/bsdlabel.h new file mode 100644 index 000000000..d88b25353 --- /dev/null +++ b/include/grub/bsdlabel.h @@ -0,0 +1,89 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2004,2007 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_BSDLABEL_PARTITION_HEADER +#define GRUB_BSDLABEL_PARTITION_HEADER 1 + +/* Constants for BSD disk label. */ +#define GRUB_PC_PARTITION_BSD_LABEL_SECTOR 1 +#define GRUB_PC_PARTITION_BSD_LABEL_MAGIC 0x82564557 + +/* BSD partition types. */ +#define GRUB_PC_PARTITION_BSD_TYPE_UNUSED 0 +#define GRUB_PC_PARTITION_BSD_TYPE_SWAP 1 +#define GRUB_PC_PARTITION_BSD_TYPE_V6 2 +#define GRUB_PC_PARTITION_BSD_TYPE_V7 3 +#define GRUB_PC_PARTITION_BSD_TYPE_SYSV 4 +#define GRUB_PC_PARTITION_BSD_TYPE_V71K 5 +#define GRUB_PC_PARTITION_BSD_TYPE_V8 6 +#define GRUB_PC_PARTITION_BSD_TYPE_BSDFFS 7 +#define GRUB_PC_PARTITION_BSD_TYPE_MSDOS 8 +#define GRUB_PC_PARTITION_BSD_TYPE_BSDLFS 9 +#define GRUB_PC_PARTITION_BSD_TYPE_OTHER 10 +#define GRUB_PC_PARTITION_BSD_TYPE_HPFS 11 +#define GRUB_PC_PARTITION_BSD_TYPE_ISO9660 12 +#define GRUB_PC_PARTITION_BSD_TYPE_BOOT 13 + +/* FreeBSD-specific types. */ +#define GRUB_PC_PARTITION_FREEBSD_TYPE_VINUM 14 +#define GRUB_PC_PARTITION_FREEBSD_TYPE_RAID 15 +#define GRUB_PC_PARTITION_FREEBSD_TYPE_JFS2 21 + +/* NetBSD-specific types. */ +#define GRUB_PC_PARTITION_NETBSD_TYPE_ADOS 14 +#define GRUB_PC_PARTITION_NETBSD_TYPE_HFS 15 +#define GRUB_PC_PARTITION_NETBSD_TYPE_FILECORE 16 +#define GRUB_PC_PARTITION_NETBSD_TYPE_EXT2FS 17 +#define GRUB_PC_PARTITION_NETBSD_TYPE_NTFS 18 +#define GRUB_PC_PARTITION_NETBSD_TYPE_RAID 19 +#define GRUB_PC_PARTITION_NETBSD_TYPE_CCD 20 +#define GRUB_PC_PARTITION_NETBSD_TYPE_JFS2 21 +#define GRUB_PC_PARTITION_NETBSD_TYPE_APPLEUFS 22 + +/* OpenBSD-specific types. */ +#define GRUB_PC_PARTITION_OPENBSD_TYPE_ADOS 14 +#define GRUB_PC_PARTITION_OPENBSD_TYPE_HFS 15 +#define GRUB_PC_PARTITION_OPENBSD_TYPE_FILECORE 16 +#define GRUB_PC_PARTITION_OPENBSD_TYPE_EXT2FS 17 +#define GRUB_PC_PARTITION_OPENBSD_TYPE_NTFS 18 +#define GRUB_PC_PARTITION_OPENBSD_TYPE_RAID 19 + +/* The BSD partition entry. */ +struct grub_partition_bsd_entry +{ + grub_uint32_t size; + grub_uint32_t offset; + grub_uint32_t fragment_size; + grub_uint8_t fs_type; + grub_uint8_t fs_fragments; + grub_uint16_t fs_cylinders; +} __attribute__ ((packed)); + +/* The BSD disk label. Only define members useful for GRUB. */ +struct grub_partition_bsd_disk_label +{ + grub_uint32_t magic; + grub_uint8_t padding[128]; + grub_uint32_t magic2; + grub_uint16_t checksum; + grub_uint16_t num_partitions; + grub_uint32_t boot_size; + grub_uint32_t superblock_size; +} __attribute__ ((packed)); + +#endif /* ! GRUB_PC_PARTITION_HEADER */ diff --git a/include/grub/msdos_partition.h b/include/grub/msdos_partition.h index 273d8c95e..650d78493 100644 --- a/include/grub/msdos_partition.h +++ b/include/grub/msdos_partition.h @@ -53,75 +53,6 @@ #define GRUB_PC_PARTITION_TYPE_GPT_DISK 0xee #define GRUB_PC_PARTITION_TYPE_LINUX_RAID 0xfd -/* Constants for BSD disk label. */ -#define GRUB_PC_PARTITION_BSD_LABEL_SECTOR 1 -#define GRUB_PC_PARTITION_BSD_LABEL_MAGIC 0x82564557 -#define GRUB_PC_PARTITION_BSD_MAX_ENTRIES 8 - -/* BSD partition types. */ -#define GRUB_PC_PARTITION_BSD_TYPE_UNUSED 0 -#define GRUB_PC_PARTITION_BSD_TYPE_SWAP 1 -#define GRUB_PC_PARTITION_BSD_TYPE_V6 2 -#define GRUB_PC_PARTITION_BSD_TYPE_V7 3 -#define GRUB_PC_PARTITION_BSD_TYPE_SYSV 4 -#define GRUB_PC_PARTITION_BSD_TYPE_V71K 5 -#define GRUB_PC_PARTITION_BSD_TYPE_V8 6 -#define GRUB_PC_PARTITION_BSD_TYPE_BSDFFS 7 -#define GRUB_PC_PARTITION_BSD_TYPE_MSDOS 8 -#define GRUB_PC_PARTITION_BSD_TYPE_BSDLFS 9 -#define GRUB_PC_PARTITION_BSD_TYPE_OTHER 10 -#define GRUB_PC_PARTITION_BSD_TYPE_HPFS 11 -#define GRUB_PC_PARTITION_BSD_TYPE_ISO9660 12 -#define GRUB_PC_PARTITION_BSD_TYPE_BOOT 13 - -/* FreeBSD-specific types. */ -#define GRUB_PC_PARTITION_FREEBSD_TYPE_VINUM 14 -#define GRUB_PC_PARTITION_FREEBSD_TYPE_RAID 15 -#define GRUB_PC_PARTITION_FREEBSD_TYPE_JFS2 21 - -/* NetBSD-specific types. */ -#define GRUB_PC_PARTITION_NETBSD_TYPE_ADOS 14 -#define GRUB_PC_PARTITION_NETBSD_TYPE_HFS 15 -#define GRUB_PC_PARTITION_NETBSD_TYPE_FILECORE 16 -#define GRUB_PC_PARTITION_NETBSD_TYPE_EXT2FS 17 -#define GRUB_PC_PARTITION_NETBSD_TYPE_NTFS 18 -#define GRUB_PC_PARTITION_NETBSD_TYPE_RAID 19 -#define GRUB_PC_PARTITION_NETBSD_TYPE_CCD 20 -#define GRUB_PC_PARTITION_NETBSD_TYPE_JFS2 21 -#define GRUB_PC_PARTITION_NETBSD_TYPE_APPLEUFS 22 - -/* OpenBSD-specific types. */ -#define GRUB_PC_PARTITION_OPENBSD_TYPE_ADOS 14 -#define GRUB_PC_PARTITION_OPENBSD_TYPE_HFS 15 -#define GRUB_PC_PARTITION_OPENBSD_TYPE_FILECORE 16 -#define GRUB_PC_PARTITION_OPENBSD_TYPE_EXT2FS 17 -#define GRUB_PC_PARTITION_OPENBSD_TYPE_NTFS 18 -#define GRUB_PC_PARTITION_OPENBSD_TYPE_RAID 19 - -/* The BSD partition entry. */ -struct grub_msdos_partition_bsd_entry -{ - grub_uint32_t size; - grub_uint32_t offset; - grub_uint32_t fragment_size; - grub_uint8_t fs_type; - grub_uint8_t fs_fragments; - grub_uint16_t fs_cylinders; -} __attribute__ ((packed)); - -/* The BSD disk label. Only define members useful for GRUB. */ -struct grub_msdos_partition_disk_label -{ - grub_uint32_t magic; - grub_uint8_t padding[128]; - grub_uint32_t magic2; - grub_uint16_t checksum; - grub_uint16_t num_partitions; - grub_uint32_t boot_size; - grub_uint32_t superblock_size; - struct grub_msdos_partition_bsd_entry entries[GRUB_PC_PARTITION_BSD_MAX_ENTRIES]; -} __attribute__ ((packed)); - /* The partition entry. */ struct grub_msdos_partition_entry { @@ -168,23 +99,6 @@ struct grub_msdos_partition_mbr } __attribute__ ((packed)); -struct grub_msdos_partition -{ - /* The DOS partition number. */ - int dos_part; - - /* The BSD partition number (a == 0). */ - int bsd_part; - - /* The DOS partition type. */ - int dos_type; - - /* The BSD partition type. */ - int bsd_type; - - /* The offset of the extended partition. */ - unsigned long ext_offset; -}; static inline int grub_msdos_partition_is_empty (int type) @@ -200,12 +114,4 @@ grub_msdos_partition_is_extended (int type) || type == GRUB_PC_PARTITION_TYPE_LINUX_EXTENDED); } -static inline int -grub_msdos_partition_is_bsd (int type) -{ - return (type == GRUB_PC_PARTITION_TYPE_FREEBSD - || type == GRUB_PC_PARTITION_TYPE_OPENBSD - || type == GRUB_PC_PARTITION_TYPE_NETBSD); -} - #endif /* ! GRUB_PC_PARTITION_HEADER */ diff --git a/include/grub/partition.h b/include/grub/partition.h index d35658cdd..5e8c476e0 100644 --- a/include/grub/partition.h +++ b/include/grub/partition.h @@ -36,13 +36,6 @@ struct grub_partition_map int (*hook) (struct grub_disk *disk, const grub_partition_t partition)); - /* Return the partition named STR on the disk DISK. */ - grub_partition_t (*probe) (struct grub_disk *disk, - const char *str); - - /* Return the name of the partition PARTITION. */ - char *(*get_name) (const grub_partition_t partition); - /* The next partition map type. */ struct grub_partition_map *next; }; @@ -51,6 +44,9 @@ typedef struct grub_partition_map *grub_partition_map_t; /* Partition description. */ struct grub_partition { + /* The partition number. */ + int number; + /* The start sector. */ grub_disk_addr_t start; @@ -66,6 +62,9 @@ struct grub_partition /* Partition map type specific data. */ void *data; + /* Parent partition map. */ + struct grub_partition *parent; + /* The type partition map. */ grub_partition_map_t partmap; }; @@ -101,7 +100,13 @@ void grub_apple_partition_map_fini (void); static inline grub_disk_addr_t grub_partition_get_start (const grub_partition_t p) { - return p->start; + grub_partition_t part; + grub_uint64_t part_start = 0; + + for (part = p; part; part = part->parent) + part_start += part->start; + + return part_start; } static inline grub_uint64_t diff --git a/kern/disk.c b/kern/disk.c index a01373072..ffd6039f7 100644 --- a/kern/disk.c +++ b/kern/disk.c @@ -330,6 +330,7 @@ grub_disk_open (const char *name) void grub_disk_close (grub_disk_t disk) { + grub_partition_t part; grub_dprintf ("disk", "Closing `%s'.\n", disk->name); if (disk->dev && disk->dev->close) @@ -338,7 +339,13 @@ grub_disk_close (grub_disk_t disk) /* Reset the timer. */ grub_last_time = grub_get_time_ms (); - grub_free (disk->partition); + while (disk->partition) + { + part = disk->partition->parent; + grub_free (disk->partition->data); + grub_free (disk->partition); + disk->partition = part; + } grub_free ((void *) disk->name); grub_free (disk); } @@ -349,18 +356,19 @@ grub_disk_close (grub_disk_t disk) - Verify that the range is inside the partition. */ static grub_err_t grub_disk_adjust_range (grub_disk_t disk, grub_disk_addr_t *sector, - grub_off_t *offset, grub_size_t size) + grub_off_t *offset, grub_size_t size) { + grub_partition_t part; *sector += *offset >> GRUB_DISK_SECTOR_BITS; *offset &= GRUB_DISK_SECTOR_SIZE - 1; - if (disk->partition) + for (part = disk->partition; part; part = part->parent) { grub_disk_addr_t start; grub_uint64_t len; - start = grub_partition_get_start (disk->partition); - len = grub_partition_get_len (disk->partition); + start = part->start; + len = part->len; if (*sector >= len || len - *sector < ((*offset + size + GRUB_DISK_SECTOR_SIZE - 1) diff --git a/kern/partition.c b/kern/partition.c index 4d5c63a95..1f3f6556d 100644 --- a/kern/partition.c +++ b/kern/partition.c @@ -17,6 +17,7 @@ */ #include +#include #include #include @@ -54,17 +55,58 @@ grub_partition_map_iterate (int (*hook) (const grub_partition_map_t partmap)) return 0; } +static grub_partition_t +grub_partition_map_probe (const grub_partition_map_t partmap, + grub_disk_t disk, int partnum) +{ + grub_partition_t p = 0; + + auto int find_func (grub_disk_t d, const grub_partition_t partition); + + int find_func (grub_disk_t d __attribute__ ((unused)), + const grub_partition_t partition) + { + if (partnum == partition->number) + { + p = (grub_partition_t) grub_malloc (sizeof (*p)); + if (! p) + return 1; + + grub_memcpy (p, partition, sizeof (*p)); + return 1; + } + + return 0; + } + + partmap->iterate (disk, find_func); + if (grub_errno) + goto fail; + + return p; + + fail: + grub_free (p); + return 0; +} + grub_partition_t grub_partition_probe (struct grub_disk *disk, const char *str) { grub_partition_t part = 0; + grub_partition_t curpart = 0; + grub_partition_t tail; + const char *ptr; + int num; auto int part_map_probe (const grub_partition_map_t partmap); int part_map_probe (const grub_partition_map_t partmap) { - part = partmap->probe (disk, str); - if (part) + disk->partition = part; + curpart = grub_partition_map_probe (partmap, disk, num); + disk->partition = tail; + if (curpart) return 1; if (grub_errno == GRUB_ERR_BAD_PART_TABLE) @@ -77,27 +119,54 @@ grub_partition_probe (struct grub_disk *disk, const char *str) return 1; } - /* Use the first partition map type found. */ - grub_partition_map_iterate (part_map_probe); + part = tail = disk->partition; + + for (ptr = str; *ptr;) + { + /* BSD-like partition specification. */ + if (*ptr >= 'a' && *ptr <= 'z') + num = *(ptr++) - 'a'; + else + num = grub_strtoul (ptr, (char **) &ptr, 0) - 1; + + curpart = 0; + /* Use the first partition map type found. */ + grub_partition_map_iterate (part_map_probe); + + if (! curpart) + { + while (part) + { + curpart = part->parent; + grub_free (part); + part = curpart; + } + return 0; + } + curpart->parent = part; + part = curpart; + if (! ptr || *ptr != ',') + break; + ptr++; + } return part; } -int -grub_partition_iterate (struct grub_disk *disk, - int (*hook) (grub_disk_t disk, - const grub_partition_t partition)) +static grub_partition_map_t +get_partmap (struct grub_disk *disk) { grub_partition_map_t partmap = 0; - int ret = 0; - + struct grub_partition part; + int found = 0; auto int part_map_iterate (const grub_partition_map_t p); auto int part_map_iterate_hook (grub_disk_t d, const grub_partition_t partition); - int part_map_iterate_hook (grub_disk_t d __attribute__ ((unused)), - const grub_partition_t partition __attribute__ ((unused))) + const grub_partition_t partition) { + found = 1; + part = *partition; return 1; } @@ -106,22 +175,58 @@ grub_partition_iterate (struct grub_disk *disk, grub_dprintf ("partition", "Detecting %s...\n", p->name); p->iterate (disk, part_map_iterate_hook); - if (grub_errno != GRUB_ERR_NONE) + if (grub_errno != GRUB_ERR_NONE || ! found) { /* Continue to next partition map type. */ grub_dprintf ("partition", "%s detection failed.\n", p->name); grub_errno = GRUB_ERR_NONE; return 0; } + grub_free (part.data); grub_dprintf ("partition", "%s detection succeeded.\n", p->name); partmap = p; return 1; } - grub_partition_map_iterate (part_map_iterate); - if (partmap) - ret = partmap->iterate (disk, hook); + return partmap; +} + +int +grub_partition_iterate (struct grub_disk *disk, + int (*hook) (grub_disk_t disk, + const grub_partition_t partition)) +{ + int ret = 0; + + auto int part_iterate (grub_disk_t dsk, const grub_partition_t p); + + int part_iterate (grub_disk_t dsk, + const grub_partition_t partition) + { + struct grub_partition p = *partition; + grub_partition_map_t partmap = 0; + p.parent = dsk->partition; + dsk->partition = 0; + if (hook (dsk, &p)) + return 1; + if (p.start != 0) + { + dsk->partition = &p; + partmap = get_partmap (dsk); + if (partmap) + ret = partmap->iterate (dsk, part_iterate); + } + dsk->partition = p.parent; + return ret; + } + + { + grub_partition_map_t partmap = 0; + partmap = get_partmap (disk); + if (partmap) + ret = partmap->iterate (disk, part_iterate); + } return ret; } @@ -129,5 +234,30 @@ grub_partition_iterate (struct grub_disk *disk, char * grub_partition_get_name (const grub_partition_t partition) { - return partition->partmap->get_name (partition); + char *out = 0; + /* Even on 64-bit machines this buffer is enough to hold longest number. */ + char buf[25]; + int curlen = 0; + grub_partition_t part; + for (part = partition; part; part = part->parent) + { + int strl; + grub_snprintf (buf, sizeof (buf), "%d", part->number + 1); + strl = grub_strlen (buf); + if (curlen) + { + out = grub_realloc (out, curlen + strl + 2); + grub_memcpy (out + strl + 1, out, curlen); + out[curlen + 1 + strl] = 0; + grub_memcpy (out, buf, strl); + out[strl] = ','; + curlen = curlen + 1 + strl; + } + else + { + curlen = strl; + out = grub_strdup (buf); + } + } + return out; } diff --git a/loader/i386/bsd.c b/loader/i386/bsd.c index 3dd3c70c5..3c7fe2fee 100644 --- a/loader/i386/bsd.c +++ b/loader/i386/bsd.c @@ -140,7 +140,6 @@ grub_bsd_get_device (grub_uint32_t * biosdev, grub_uint32_t * unit, grub_uint32_t * slice, grub_uint32_t * part) { - char *p; grub_device_t dev; #ifdef GRUB_MACHINE_PCBIOS @@ -154,21 +153,13 @@ grub_bsd_get_device (grub_uint32_t * biosdev, dev = grub_device_open (0); if (dev && dev->disk && dev->disk->partition) { - - p = dev->disk->partition->partmap->get_name (dev->disk->partition); - if (p) + if (dev->disk->partition->parent) { - if ((p[0] >= '0') && (p[0] <= '9')) - { - *slice = grub_strtoul (p, &p, 0); - - if ((p) && (p[0] == ',')) - p++; - } - - if ((p[0] >= 'a') && (p[0] <= 'z')) - *part = p[0] - 'a'; + *part = dev->disk->partition->number; + *slice = dev->disk->partition->parent->number + 1; } + else + *slice = dev->disk->partition->number + 1; } if (dev) grub_device_close (dev); diff --git a/loader/i386/multiboot_mbi.c b/loader/i386/multiboot_mbi.c index a154d1b23..928677512 100644 --- a/loader/i386/multiboot_mbi.c +++ b/loader/i386/multiboot_mbi.c @@ -435,7 +435,6 @@ grub_multiboot_add_module (grub_addr_t start, grub_size_t size, void grub_multiboot_set_bootdev (void) { - char *p; grub_uint32_t biosdev, slice = ~0, part = ~0; grub_device_t dev; @@ -448,21 +447,13 @@ grub_multiboot_set_bootdev (void) dev = grub_device_open (0); if (dev && dev->disk && dev->disk->partition) { - - p = dev->disk->partition->partmap->get_name (dev->disk->partition); - if (p) - { - if ((p[0] >= '0') && (p[0] <= '9')) - { - slice = grub_strtoul (p, &p, 0) - 1; - - if ((p) && (p[0] == ',')) - p++; - } - - if ((p[0] >= 'a') && (p[0] <= 'z')) - part = p[0] - 'a'; + if (dev->disk->partition->parent) + { + part = dev->disk->partition->number; + slice = dev->disk->partition->parent->number; } + else + slice = dev->disk->partition->number; } if (dev) grub_device_close (dev); diff --git a/loader/i386/pc/chainloader.c b/loader/i386/pc/chainloader.c index fbc356895..935f5a6d1 100644 --- a/loader/i386/pc/chainloader.c +++ b/loader/i386/pc/chainloader.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -98,10 +99,22 @@ grub_chainloader_cmd (const char *filename, grub_chainloader_flags_t flags) dev = grub_device_open (0); if (dev && dev->disk && dev->disk->partition) { - grub_disk_read (dev->disk, dev->disk->partition->offset, 446, 64, - (void *) GRUB_MEMORY_MACHINE_PART_TABLE_ADDR); - part_addr = (void *) (GRUB_MEMORY_MACHINE_PART_TABLE_ADDR - + (dev->disk->partition->index << 4)); + grub_disk_t disk = dev->disk; + + if (disk) + { + grub_partition_t p = disk->partition; + + if (p && grub_strcmp (p->partmap->name, "part_msdos") == 0) + { + disk->partition = p->parent; + grub_disk_read (disk, p->offset, 446, 64, + (void *) GRUB_MEMORY_MACHINE_PART_TABLE_ADDR); + part_addr = (void *) (GRUB_MEMORY_MACHINE_PART_TABLE_ADDR + + (p->index << 4)); + disk->partition = p; + } + } } if (dev) diff --git a/partmap/acorn.c b/partmap/acorn.c index 081b6ee94..12ef9c781 100644 --- a/partmap/acorn.c +++ b/partmap/acorn.c @@ -96,21 +96,17 @@ acorn_partition_map_iterate (grub_disk_t disk, const grub_partition_t partition)) { struct grub_partition part; - struct grub_disk raw; struct linux_part map[LINUX_MAP_ENTRIES]; int i; - grub_disk_addr_t sector; + grub_disk_addr_t sector = 0; grub_err_t err; - /* Enforce raw disk access. */ - raw = *disk; - raw.partition = 0; - - err = acorn_partition_map_find (&raw, map, §or); + err = acorn_partition_map_find (disk, map, §or); if (err) return err; part.partmap = &grub_acorn_partition_map; + part.data = 0; for (i = 0; i != LINUX_MAP_ENTRIES; ++i) { @@ -121,7 +117,7 @@ acorn_partition_map_iterate (grub_disk_t disk, part.start = sector + map[i].start; part.len = map[i].size; part.offset = 6; - part.index = i; + part.number = part.index = i; if (hook (disk, &part)) return grub_errno; @@ -130,53 +126,6 @@ acorn_partition_map_iterate (grub_disk_t disk, return GRUB_ERR_NONE; } - -static grub_partition_t -acorn_partition_map_probe (grub_disk_t disk, const char *str) -{ - struct linux_part map[LINUX_MAP_ENTRIES]; - struct grub_disk raw = *disk; - unsigned long partnum = grub_strtoul (str, 0, 10) - 1; - grub_disk_addr_t sector; - grub_err_t err; - grub_partition_t p; - - /* Enforce raw disk access. */ - raw.partition = 0; - - /* Get the partition number. */ - if (partnum > LINUX_MAP_ENTRIES) - goto fail; - - err = acorn_partition_map_find (&raw, map, §or); - if (err) - return 0; - - if (map[partnum].magic != LINUX_NATIVE_MAGIC - && map[partnum].magic != LINUX_SWAP_MAGIC) - goto fail; - - p = grub_malloc (sizeof (struct grub_partition)); - if (! p) - return 0; - - p->start = sector + map[partnum].start; - p->len = map[partnum].size; - p->offset = 6; - p->index = partnum; - return p; - -fail: - grub_error (GRUB_ERR_BAD_FILENAME, "invalid partition"); - return 0; -} - - -static char * -acorn_partition_map_get_name (const grub_partition_t p) -{ - return grub_xasprintf ("%d", p->index + 1); -} /* Partition map type. */ @@ -184,8 +133,6 @@ static struct grub_partition_map grub_acorn_partition_map = { .name = "part_acorn", .iterate = acorn_partition_map_iterate, - .probe = acorn_partition_map_probe, - .get_name = acorn_partition_map_get_name }; GRUB_MOD_INIT(acorn_partition_map) diff --git a/partmap/amiga.c b/partmap/amiga.c index f832db354..2c6a5afa2 100644 --- a/partmap/amiga.c +++ b/partmap/amiga.c @@ -76,20 +76,15 @@ amiga_partition_map_iterate (grub_disk_t disk, { struct grub_partition part; struct grub_amiga_rdsk rdsk; - struct grub_disk raw; int partno = 0; int next = -1; unsigned pos; - /* Enforce raw disk access. */ - raw = *disk; - raw.partition = 0; - /* The RDSK block is one of the first 15 blocks. */ for (pos = 0; pos < 15; pos++) { /* Read the RDSK block which is a descriptor for the entire disk. */ - if (grub_disk_read (&raw, pos, 0, sizeof (rdsk), &rdsk)) + if (grub_disk_read (disk, pos, 0, sizeof (rdsk), &rdsk)) return grub_errno; if (grub_strcmp ((char *) rdsk.magic, "RDSK") == 0) @@ -104,13 +99,15 @@ amiga_partition_map_iterate (grub_disk_t disk, return grub_error (GRUB_ERR_BAD_PART_TABLE, "Amiga partition map not found"); + part.data = 0; + /* The end of the partition list is marked using "-1". */ while (next != -1) { struct grub_amiga_partition apart; /* Read the RDSK block which is a descriptor for the entire disk. */ - if (grub_disk_read (&raw, next, 0, sizeof (apart), &apart)) + if (grub_disk_read (disk, next, 0, sizeof (apart), &apart)) return grub_errno; /* Calculate the first block and the size of the partition. */ @@ -123,7 +120,8 @@ amiga_partition_map_iterate (grub_disk_t disk, * grub_be_to_cpu32 (apart.block_per_track)); part.offset = (grub_off_t) next * 512; - part.index = partno; + part.number = partno; + part.index = 0; part.partmap = &grub_amiga_partition_map; if (hook (disk, &part)) @@ -136,65 +134,12 @@ amiga_partition_map_iterate (grub_disk_t disk, return 0; } - -static grub_partition_t -amiga_partition_map_probe (grub_disk_t disk, const char *str) -{ - grub_partition_t p = 0; - int partnum = 0; - char *s = (char *) str; - - auto int find_func (grub_disk_t d, const grub_partition_t partition); - - int find_func (grub_disk_t d __attribute__ ((unused)), - const grub_partition_t partition) - { - if (partnum == partition->index) - { - p = (grub_partition_t) grub_malloc (sizeof (*p)); - if (! p) - return 1; - - grub_memcpy (p, partition, sizeof (*p)); - return 1; - } - - return 0; - } - - /* Get the partition number. */ - partnum = grub_strtoul (s, 0, 10) - 1; - if (grub_errno) - { - grub_error (GRUB_ERR_BAD_FILENAME, "invalid partition"); - return 0; - } - - if (amiga_partition_map_iterate (disk, find_func)) - goto fail; - - return p; - - fail: - grub_free (p); - return 0; -} - - -static char * -amiga_partition_map_get_name (const grub_partition_t p) -{ - return grub_xasprintf ("%d", p->index + 1); -} - /* Partition map type. */ static struct grub_partition_map grub_amiga_partition_map = { .name = "part_amiga", .iterate = amiga_partition_map_iterate, - .probe = amiga_partition_map_probe, - .get_name = amiga_partition_map_get_name }; GRUB_MOD_INIT(amiga_partition_map) diff --git a/partmap/apple.c b/partmap/apple.c index a1a645acf..40c59f517 100644 --- a/partmap/apple.c +++ b/partmap/apple.c @@ -105,17 +105,12 @@ apple_partition_map_iterate (grub_disk_t disk, struct grub_partition part; struct grub_apple_header aheader; struct grub_apple_part apart; - struct grub_disk raw; int partno = 0, partnum = 0; unsigned pos; - /* Enforce raw disk access. */ - raw = *disk; - raw.partition = 0; - part.partmap = &grub_apple_partition_map; - if (grub_disk_read (&raw, 0, 0, sizeof (aheader), &aheader)) + if (grub_disk_read (disk, 0, 0, sizeof (aheader), &aheader)) return grub_errno; if (grub_be_to_cpu16 (aheader.magic) != GRUB_APPLE_HEADER_MAGIC) @@ -127,14 +122,17 @@ apple_partition_map_iterate (grub_disk_t disk, goto fail; } + part.data = 0; pos = grub_be_to_cpu16 (aheader.blocksize); do { - if (grub_disk_read (&raw, pos / GRUB_DISK_SECTOR_SIZE, - pos % GRUB_DISK_SECTOR_SIZE, - sizeof (struct grub_apple_part), &apart)) - return grub_errno; + part.offset = pos / GRUB_DISK_SECTOR_SIZE; + part.index = pos % GRUB_DISK_SECTOR_SIZE; + + if (grub_disk_read (disk, part.offset, part.index, + sizeof (struct grub_apple_part), &apart)) + return grub_errno; if (grub_be_to_cpu16 (apart.magic) != GRUB_APPLE_PART_MAGIC) { @@ -156,6 +154,7 @@ apple_partition_map_iterate (grub_disk_t disk, / GRUB_DISK_SECTOR_SIZE; part.offset = pos; part.index = partno; + part.number = partno; grub_dprintf ("partition", "partition %d: name %s, type %s, start 0x%x, len 0x%x\n", @@ -179,65 +178,12 @@ apple_partition_map_iterate (grub_disk_t disk, "Apple partition map not found"); } - -static grub_partition_t -apple_partition_map_probe (grub_disk_t disk, const char *str) -{ - grub_partition_t p = 0; - int partnum = 0; - char *s = (char *) str; - - auto int find_func (grub_disk_t d, const grub_partition_t partition); - - int find_func (grub_disk_t d __attribute__ ((unused)), - const grub_partition_t partition) - { - if (partnum == partition->index) - { - p = (grub_partition_t) grub_malloc (sizeof (*p)); - if (! p) - return 1; - - grub_memcpy (p, partition, sizeof (*p)); - return 1; - } - - return 0; - } - - /* Get the partition number. */ - partnum = grub_strtoul (s, 0, 10) - 1; - if (grub_errno) - { - grub_error (GRUB_ERR_BAD_FILENAME, "invalid partition"); - return 0; - } - - if (apple_partition_map_iterate (disk, find_func)) - goto fail; - - return p; - - fail: - grub_free (p); - return 0; -} - - -static char * -apple_partition_map_get_name (const grub_partition_t p) -{ - return grub_xasprintf ("%d", p->index + 1); -} - /* Partition map type. */ static struct grub_partition_map grub_apple_partition_map = { .name = "part_apple", .iterate = apple_partition_map_iterate, - .probe = apple_partition_map_probe, - .get_name = apple_partition_map_get_name }; GRUB_MOD_INIT(apple_partition_map) diff --git a/partmap/bsdlabel.c b/partmap/bsdlabel.c new file mode 100644 index 000000000..861388164 --- /dev/null +++ b/partmap/bsdlabel.c @@ -0,0 +1,97 @@ +/* bsdlabel.c - Read BSD style partition tables. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2004,2005,2006,2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +static struct grub_partition_map grub_bsdlabel_partition_map; + + +static grub_err_t +bsdlabel_partition_map_iterate (grub_disk_t disk, + int (*hook) (grub_disk_t disk, + const grub_partition_t partition)) +{ + struct grub_partition_bsd_disk_label label; + struct grub_partition p; + grub_disk_addr_t delta = 0; + unsigned pos; + + /* BSDLabel offsets are absolute even when it's embed inside partition. */ + delta = grub_partition_get_start (disk->partition); + + /* Read the BSD label. */ + if (grub_disk_read (disk, GRUB_PC_PARTITION_BSD_LABEL_SECTOR, + 0, sizeof (label), &label)) + return grub_errno; + + /* Check if it is valid. */ + if (label.magic != grub_cpu_to_le32 (GRUB_PC_PARTITION_BSD_LABEL_MAGIC)) + return grub_error (GRUB_ERR_BAD_PART_TABLE, "no signature"); + + pos = sizeof (label) + GRUB_PC_PARTITION_BSD_LABEL_SECTOR + * GRUB_DISK_SECTOR_SIZE; + + for (p.number = 0; + p.number < grub_cpu_to_le16 (label.num_partitions); + p.number++) + { + struct grub_partition_bsd_entry be; + + p.offset = pos / GRUB_DISK_SECTOR_SIZE; + p.index = pos % GRUB_DISK_SECTOR_SIZE; + + if (grub_disk_read (disk, p.offset, p.index, sizeof (be), &be)) + return grub_errno; + + p.start = grub_le_to_cpu32 (be.offset) - delta; + p.len = grub_le_to_cpu32 (be.size); + p.partmap = &grub_bsdlabel_partition_map; + + if (be.fs_type != GRUB_PC_PARTITION_BSD_TYPE_UNUSED) + if (hook (disk, &p)) + return grub_errno; + + pos += sizeof (struct grub_partition_bsd_entry); + } + + return GRUB_ERR_NONE; +} + + +/* Partition map type. */ +static struct grub_partition_map grub_bsdlabel_partition_map = + { + .name = "part_bsd", + .iterate = bsdlabel_partition_map_iterate, + }; + +GRUB_MOD_INIT(bsd_partition_map) +{ + grub_partition_map_register (&grub_bsdlabel_partition_map); +} + +GRUB_MOD_FINI(bsd_partition_map) +{ + grub_partition_map_unregister (&grub_bsdlabel_partition_map); +} diff --git a/partmap/gpt.c b/partmap/gpt.c index cb1229bee..922a7303b 100644 --- a/partmap/gpt.c +++ b/partmap/gpt.c @@ -44,18 +44,13 @@ gpt_partition_map_iterate (grub_disk_t disk, struct grub_partition part; struct grub_gpt_header gpt; struct grub_gpt_partentry entry; - struct grub_disk raw; struct grub_msdos_partition_mbr mbr; grub_uint64_t entries; unsigned int i; int last_offset = 0; - /* Enforce raw disk access. */ - raw = *disk; - raw.partition = 0; - /* Read the protective MBR. */ - if (grub_disk_read (&raw, 0, 0, sizeof (mbr), &mbr)) + if (grub_disk_read (disk, 0, 0, sizeof (mbr), &mbr)) return grub_errno; /* Check if it is valid. */ @@ -67,7 +62,7 @@ gpt_partition_map_iterate (grub_disk_t disk, return grub_error (GRUB_ERR_BAD_PART_TABLE, "no GPT partition map found"); /* Read the GPT header. */ - if (grub_disk_read (&raw, 1, 0, sizeof (gpt), &gpt)) + if (grub_disk_read (disk, 1, 0, sizeof (gpt), &gpt)) return grub_errno; if (grub_memcmp (gpt.magic, grub_gpt_magic, sizeof (grub_gpt_magic))) @@ -76,11 +71,15 @@ gpt_partition_map_iterate (grub_disk_t disk, grub_dprintf ("gpt", "Read a valid GPT header\n"); entries = grub_le_to_cpu64 (gpt.partitions); + part.data = grub_malloc (sizeof (entry)); for (i = 0; i < grub_le_to_cpu32 (gpt.maxpart); i++) { - if (grub_disk_read (&raw, entries, last_offset, + if (grub_disk_read (disk, entries, last_offset, sizeof (entry), &entry)) - return grub_errno; + { + grub_free (part.data); + return grub_errno; + } if (grub_memcmp (&grub_gpt_partition_type_empty, &entry.type, sizeof (grub_gpt_partition_type_empty))) @@ -90,16 +89,17 @@ gpt_partition_map_iterate (grub_disk_t disk, part.len = (grub_le_to_cpu64 (entry.end) - grub_le_to_cpu64 (entry.start) + 1); part.offset = entries; - part.index = i; + part.number = i; + part.index = last_offset; part.partmap = &grub_gpt_partition_map; - part.data = &entry; + grub_memcpy (part.data, &entry, sizeof (entry)); grub_dprintf ("gpt", "GPT entry %d: start=%lld, length=%lld\n", i, (unsigned long long) part.start, (unsigned long long) part.len); if (hook (disk, &part)) - return 1; + return grub_errno; } last_offset += grub_le_to_cpu32 (gpt.partentry_size); @@ -110,59 +110,9 @@ gpt_partition_map_iterate (grub_disk_t disk, } } - return 0; -} + grub_free (part.data); - -static grub_partition_t -gpt_partition_map_probe (grub_disk_t disk, const char *str) -{ - grub_partition_t p = 0; - int partnum = 0; - char *s = (char *) str; - - auto int find_func (grub_disk_t d, const grub_partition_t partition); - - int find_func (grub_disk_t d __attribute__ ((unused)), - const grub_partition_t partition) - { - if (partnum == partition->index) - { - p = (grub_partition_t) grub_malloc (sizeof (*p)); - if (! p) - return 1; - - grub_memcpy (p, partition, sizeof (*p)); - return 1; - } - - return 0; - } - - /* Get the partition number. */ - partnum = grub_strtoul (s, 0, 10) - 1; - if (grub_errno) - { - grub_error (GRUB_ERR_BAD_FILENAME, "invalid partition"); - return 0; - } - - gpt_partition_map_iterate (disk, find_func); - if (grub_errno) - goto fail; - - return p; - - fail: - grub_free (p); - return 0; -} - - -static char * -gpt_partition_map_get_name (const grub_partition_t p) -{ - return grub_xasprintf ("%d", p->index + 1); + return GRUB_ERR_NONE; } @@ -171,8 +121,6 @@ static struct grub_partition_map grub_gpt_partition_map = { .name = "part_gpt", .iterate = gpt_partition_map_iterate, - .probe = gpt_partition_map_probe, - .get_name = gpt_partition_map_get_name }; GRUB_MOD_INIT(gpt_partition_map) diff --git a/partmap/msdos.c b/partmap/msdos.c index 1c3861cc7..0fbf7ef3d 100644 --- a/partmap/msdos.c +++ b/partmap/msdos.c @@ -27,87 +27,21 @@ static struct grub_partition_map grub_msdos_partition_map; -/* Parse the partition representation in STR and return a partition. */ -static grub_partition_t -grub_partition_parse (const char *str) -{ - grub_partition_t p; - struct grub_msdos_partition *pcdata; - - char *s = (char *) str; - - p = (grub_partition_t) grub_malloc (sizeof (*p)); - if (! p) - return 0; - - pcdata = (struct grub_msdos_partition *) grub_malloc (sizeof (*pcdata)); - if (! pcdata) - goto fail; - - p->data = pcdata; - p->partmap = &grub_msdos_partition_map; - - /* Initialize some of the fields with invalid values. */ - pcdata->bsd_part = pcdata->dos_type = pcdata->bsd_type = p->index = -1; - - /* Get the DOS partition number. The number is counted from one for - the user interface, and from zero internally. */ - pcdata->dos_part = grub_strtoul (s, &s, 0) - 1; - - if (grub_errno) - { - /* Not found. Maybe only a BSD label is specified. */ - pcdata->dos_part = -1; - grub_errno = GRUB_ERR_NONE; - } - else if (*s == ',') - s++; - - if (*s) - { - if (*s >= 'a' && *s <= 'h') - { - pcdata->bsd_part = *s - 'a'; - s++; - } - - if (*s) - goto fail; - } - - if (pcdata->dos_part == -1 && pcdata->bsd_part == -1) - goto fail; - - return p; - - fail: - grub_free (p); - grub_free (pcdata); - grub_error (GRUB_ERR_BAD_FILENAME, "invalid partition"); - return 0; -} - static grub_err_t pc_partition_map_iterate (grub_disk_t disk, int (*hook) (grub_disk_t disk, const grub_partition_t partition)) { struct grub_partition p; - struct grub_msdos_partition pcdata; struct grub_msdos_partition_mbr mbr; - struct grub_msdos_partition_disk_label label; - struct grub_disk raw; int labeln = 0; grub_disk_addr_t lastaddr; - - /* Enforce raw disk access. */ - raw = *disk; - raw.partition = 0; + grub_disk_addr_t ext_offset; p.offset = 0; - pcdata.ext_offset = 0; - pcdata.dos_part = -1; - p.data = &pcdata; + ext_offset = 0; + p.data = 0; + p.number = -1; p.partmap = &grub_msdos_partition_map; /* Any value different than `p.offset' will satisfy the check during @@ -120,7 +54,7 @@ pc_partition_map_iterate (grub_disk_t disk, struct grub_msdos_partition_entry *e; /* Read the MBR. */ - if (grub_disk_read (&raw, p.offset, 0, sizeof (mbr), &mbr)) + if (grub_disk_read (disk, p.offset, 0, sizeof (mbr), &mbr)) goto finish; /* This is our loop-detection algorithm. It works the following way: @@ -150,13 +84,10 @@ pc_partition_map_iterate (grub_disk_t disk, p.start = p.offset + grub_le_to_cpu32 (e->start); p.len = grub_le_to_cpu32 (e->length); - pcdata.bsd_part = -1; - pcdata.dos_type = e->type; - pcdata.bsd_type = -1; grub_dprintf ("partition", "partition %d: flag 0x%x, type 0x%x, start 0x%llx, len 0x%llx\n", - p.index, e->flag, pcdata.dos_type, + p.index, e->flag, e->type, (unsigned long long) p.start, (unsigned long long) p.len); @@ -168,59 +99,15 @@ pc_partition_map_iterate (grub_disk_t disk, if (! grub_msdos_partition_is_empty (e->type) && ! grub_msdos_partition_is_extended (e->type)) { - pcdata.dos_part++; + p.number++; if (hook (disk, &p)) - return 1; - - /* Check if this is a BSD partition. */ - if (grub_msdos_partition_is_bsd (e->type)) - { - /* Check if the BSD label is within the DOS partition. */ - if (p.len <= GRUB_PC_PARTITION_BSD_LABEL_SECTOR) - { - grub_dprintf ("partition", "no space for disk label\n"); - continue; - } - /* Read the BSD label. */ - if (grub_disk_read (&raw, - (p.start - + GRUB_PC_PARTITION_BSD_LABEL_SECTOR), - 0, - sizeof (label), - &label)) - goto finish; - - /* Check if it is valid. */ - if (label.magic - != grub_cpu_to_le32 (GRUB_PC_PARTITION_BSD_LABEL_MAGIC)) - { - grub_dprintf ("partition", - "invalid disk label magic 0x%x on partition %d\n", - label.magic, p.index); - continue; - } - for (pcdata.bsd_part = 0; - pcdata.bsd_part < grub_cpu_to_le16 (label.num_partitions); - pcdata.bsd_part++) - { - struct grub_msdos_partition_bsd_entry *be - = label.entries + pcdata.bsd_part; - - p.start = grub_le_to_cpu32 (be->offset); - p.len = grub_le_to_cpu32 (be->size); - pcdata.bsd_type = be->fs_type; - - if (be->fs_type != GRUB_PC_PARTITION_BSD_TYPE_UNUSED) - if (hook (disk, &p)) - return 1; - } - } + return grub_errno; } - else if (pcdata.dos_part < 4) + else if (p.number < 4) /* If this partition is a logical one, shouldn't increase the partition number. */ - pcdata.dos_part++; + p.number++; } /* Find an extended partition. */ @@ -230,9 +117,9 @@ pc_partition_map_iterate (grub_disk_t disk, if (grub_msdos_partition_is_extended (e->type)) { - p.offset = pcdata.ext_offset + grub_le_to_cpu32 (e->start); - if (! pcdata.ext_offset) - pcdata.ext_offset = p.offset; + p.offset = ext_offset + grub_le_to_cpu32 (e->start); + if (! ext_offset) + ext_offset = p.offset; break; } @@ -247,78 +134,12 @@ pc_partition_map_iterate (grub_disk_t disk, return grub_errno; } - -static grub_partition_t -pc_partition_map_probe (grub_disk_t disk, const char *str) -{ - grub_partition_t p; - struct grub_msdos_partition *pcdata; - - auto int find_func (grub_disk_t d, const grub_partition_t partition); - - int find_func (grub_disk_t d __attribute__ ((unused)), - const grub_partition_t partition) - { - struct grub_msdos_partition *partdata = partition->data; - - if ((pcdata->dos_part == partdata->dos_part || pcdata->dos_part == -1) - && pcdata->bsd_part == partdata->bsd_part) - { - grub_memcpy (p, partition, sizeof (*p)); - p->data = pcdata; - grub_memcpy (pcdata, partdata, sizeof (*pcdata)); - return 1; - } - - return 0; - } - - p = grub_partition_parse (str); - if (! p) - return 0; - - pcdata = p->data; - pc_partition_map_iterate (disk, find_func); - if (grub_errno) - goto fail; - - if (p->index < 0) - { - grub_error (GRUB_ERR_BAD_DEVICE, "no such partition"); - goto fail; - } - - return p; - - fail: - grub_free (p); - grub_free (pcdata); - return 0; -} - - -static char * -pc_partition_map_get_name (const grub_partition_t p) -{ - struct grub_msdos_partition *pcdata = p->data; - - if (pcdata->bsd_part < 0) - return grub_xasprintf ("%d", pcdata->dos_part + 1); - else if (pcdata->dos_part < 0) - return grub_xasprintf ("%c", pcdata->bsd_part + 'a'); - else - return grub_xasprintf ("%d,%c", pcdata->dos_part + 1, - pcdata->bsd_part + 'a'); -} - /* Partition map type. */ static struct grub_partition_map grub_msdos_partition_map = { .name = "part_msdos", .iterate = pc_partition_map_iterate, - .probe = pc_partition_map_probe, - .get_name = pc_partition_map_get_name }; GRUB_MOD_INIT(pc_partition_map) diff --git a/partmap/sun.c b/partmap/sun.c index 42cf0d598..ff01d1018 100644 --- a/partmap/sun.c +++ b/partmap/sun.c @@ -88,19 +88,15 @@ sun_partition_map_iterate (grub_disk_t disk, const grub_partition_t partition)) { grub_partition_t p; - struct grub_disk raw; struct grub_sun_block block; int partnum; - raw = *disk; - raw.partition = 0; - p = (grub_partition_t) grub_zalloc (sizeof (struct grub_partition)); if (! p) return grub_errno; p->partmap = &grub_sun_partition_map; - if (grub_disk_read (&raw, 0, 0, sizeof (struct grub_sun_block), + if (grub_disk_read (disk, 0, 0, sizeof (struct grub_sun_block), &block) == GRUB_ERR_NONE) { if (GRUB_PARTMAP_SUN_MAGIC != grub_be_to_cpu16 (block.magic)) @@ -124,7 +120,7 @@ sun_partition_map_iterate (grub_disk_t disk, * grub_be_to_cpu16 (block.ntrks) * grub_be_to_cpu16 (block.nsect)); p->len = grub_be_to_cpu32 (desc->num_sectors); - p->index = partnum; + p->number = p->index = partnum; if (p->len) { if (hook (disk, p)) @@ -138,62 +134,11 @@ sun_partition_map_iterate (grub_disk_t disk, return grub_errno; } -static grub_partition_t -sun_partition_map_probe (grub_disk_t disk, const char *str) -{ - grub_partition_t p = 0; - int partnum = 0; - char *s = (char *) str; - - auto int find_func (grub_disk_t d, const grub_partition_t partition); - - int find_func (grub_disk_t d __attribute__ ((unused)), - const grub_partition_t partition) - { - if (partnum == partition->index) - { - p = (grub_partition_t) grub_malloc (sizeof (*p)); - if (p) - grub_memcpy (p, partition, sizeof (*p)); - - return 1; - } - - return 0; - } - - grub_errno = GRUB_ERR_NONE; - partnum = grub_strtoul (s, 0, 10) - 1; - if (grub_errno == GRUB_ERR_NONE) - { - if (sun_partition_map_iterate (disk, find_func)) - { - grub_free (p); - p = 0; - } - } - else - { - grub_error (GRUB_ERR_BAD_FILENAME, "invalid partition"); - p = 0; - } - - return p; -} - -static char * -sun_partition_map_get_name (const grub_partition_t p) -{ - return grub_xasprintf ("%d", p->index + 1); -} - /* Partition map type. */ static struct grub_partition_map grub_sun_partition_map = { .name = "part_sun", .iterate = sun_partition_map_iterate, - .probe = sun_partition_map_probe, - .get_name = sun_partition_map_get_name }; GRUB_MOD_INIT(sun_partition_map) diff --git a/parttool/msdospart.c b/parttool/msdospart.c index dbb25bc52..b1fe689f4 100644 --- a/parttool/msdospart.c +++ b/parttool/msdospart.c @@ -49,7 +49,7 @@ static grub_err_t grub_pcpart_boot (const grub_device_t dev, index = dev->disk->partition->index; part = dev->disk->partition; - dev->disk->partition = 0; + dev->disk->partition = part->parent; /* Read the MBR. */ if (grub_disk_read (dev->disk, 0, 0, sizeof (mbr), &mbr)) @@ -96,7 +96,7 @@ static grub_err_t grub_pcpart_type (const grub_device_t dev, index = dev->disk->partition->index; part = dev->disk->partition; - dev->disk->partition = 0; + dev->disk->partition = part->parent; /* Read the parttable. */ if (grub_disk_read (dev->disk, part->offset, 0, diff --git a/util/grub-probe.c b/util/grub-probe.c index ba2fe4c35..948f10dcf 100644 --- a/util/grub-probe.c +++ b/util/grub-probe.c @@ -82,13 +82,16 @@ grub_refresh (void) static void probe_partmap (grub_disk_t disk) { + grub_partition_t part; + if (disk->partition == NULL) { grub_util_info ("no partition map found for %s", disk->name); return; } - printf ("%s\n", disk->partition->partmap->name); + for (part = disk->partition; part; part = part->parent) + printf ("%s\n", part->partmap->name); } static int diff --git a/util/hostdisk.c b/util/hostdisk.c index a594f75ec..0bccf4ca7 100644 --- a/util/hostdisk.c +++ b/util/hostdisk.c @@ -334,10 +334,13 @@ open_device (const grub_disk_t disk, grub_disk_addr_t sector, int flags) { int is_partition = 0; char dev[PATH_MAX]; + grub_disk_addr_t part_start = 0; + + part_start = grub_partition_get_start (disk->partition); strcpy (dev, map[disk->id].device); if (disk->partition && strncmp (map[disk->id].device, "/dev/", 5) == 0) - is_partition = linux_find_partition (dev, disk->partition->start); + is_partition = linux_find_partition (dev, part_start); /* Open the partition. */ grub_dprintf ("hostdisk", "opening the device `%s' in open_device()\n", dev); @@ -353,7 +356,7 @@ open_device (const grub_disk_t disk, grub_disk_addr_t sector, int flags) ioctl (fd, BLKFLSBUF, 0); if (is_partition) - sector -= disk->partition->start; + sector -= part_start; } #else /* ! __linux__ */ #if defined (__FreeBSD__) || defined(__FreeBSD_kernel__) @@ -952,39 +955,25 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) int find_partition (grub_disk_t disk __attribute__ ((unused)), const grub_partition_t partition) { - struct grub_msdos_partition *pcdata = NULL; + grub_disk_addr_t part_start = 0; + grub_util_info ("Partition %d starts from %lu", + partition->number, partition->start); - if (strcmp (partition->partmap->name, "part_msdos") == 0) - pcdata = partition->data; + part_start = grub_partition_get_start (partition); - if (pcdata) + if (hdg.start == part_start) { - if (pcdata->bsd_part < 0) - grub_util_info ("DOS partition %d starts from %lu", - pcdata->dos_part, partition->start); - else - grub_util_info ("BSD partition %d,%c starts from %lu", - pcdata->dos_part, pcdata->bsd_part + 'a', - partition->start); - } - else - { - grub_util_info ("Partition %d starts from %lu", - partition->index, partition->start); - } - - if (hdg.start == partition->start) - { - if (pcdata) + if (partition->parent) { - dos_part = pcdata->dos_part; - bsd_part = pcdata->bsd_part; + dos_part = partition->parent->number; + bsd_part = partition->number; } else { - dos_part = partition->index; + dos_part = partition->number; bsd_part = -1; } + return 1; } diff --git a/util/i386/pc/grub-setup.c b/util/i386/pc/grub-setup.c index 4e2517ef2..15351ca5a 100644 --- a/util/i386/pc/grub-setup.c +++ b/util/i386/pc/grub-setup.c @@ -116,15 +116,10 @@ setup (const char *dir, int NESTED_FUNC_ATTR find_usable_region_msdos (grub_disk_t disk __attribute__ ((unused)), const grub_partition_t p) { - struct grub_msdos_partition *pcdata = p->data; - /* There's always an embed region, and it starts right after the MBR. */ embed_region.start = 1; - /* For its end offset, include as many dummy partitions as we can. */ - if (! grub_msdos_partition_is_empty (pcdata->dos_type) - && ! grub_msdos_partition_is_bsd (pcdata->dos_type) - && embed_region.end > p->start) + if (embed_region.end > p->start) embed_region.end = p->start; return 0; @@ -289,22 +284,19 @@ setup (const char *dir, /* Embed information about the installed location. */ if (root_dev->disk->partition) { - if (strcmp (root_dev->disk->partition->partmap->name, - "part_msdos") == 0) - { - struct grub_msdos_partition *pcdata = - root_dev->disk->partition->data; - dos_part = pcdata->dos_part; - bsd_part = pcdata->bsd_part; - } - else if (strcmp (root_dev->disk->partition->partmap->name, - "part_gpt") == 0) - { - dos_part = root_dev->disk->partition->index; - bsd_part = -1; - } + if (root_dev->disk->partition->parent) + { + if (root_dev->disk->partition->parent->parent) + grub_util_error ("Installing on doubly nested partitions is " + "not supported"); + dos_part = root_dev->disk->partition->parent->number; + bsd_part = root_dev->disk->partition->number; + } else - grub_util_error (_("no DOS-style partitions found")); + { + dos_part = root_dev->disk->partition->number; + bsd_part = -1; + } } else dos_part = bsd_part = -1; @@ -337,6 +329,8 @@ setup (const char *dir, int NESTED_FUNC_ATTR identify_partmap (grub_disk_t disk __attribute__ ((unused)), const grub_partition_t p) { + if (p->parent) + return 0; dest_partmap = p->partmap->name; return 1; } From 85f90358b1cec1276994594e9def1cd4ce1de6f7 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 6 Feb 2010 19:33:53 +0100 Subject: [PATCH 337/738] Remove part_ prefix --- loader/i386/pc/chainloader.c | 2 +- partmap/acorn.c | 2 +- partmap/amiga.c | 2 +- partmap/apple.c | 2 +- partmap/bsdlabel.c | 2 +- partmap/gpt.c | 2 +- partmap/msdos.c | 2 +- partmap/sun.c | 2 +- parttool/msdospart.c | 4 ++-- util/grub-install.in | 5 ++++- util/i386/efi/grub-install.in | 5 ++++- util/i386/pc/grub-setup.c | 6 +++--- util/ieee1275/grub-install.in | 5 ++++- 13 files changed, 25 insertions(+), 16 deletions(-) diff --git a/loader/i386/pc/chainloader.c b/loader/i386/pc/chainloader.c index 935f5a6d1..502031d0e 100644 --- a/loader/i386/pc/chainloader.c +++ b/loader/i386/pc/chainloader.c @@ -105,7 +105,7 @@ grub_chainloader_cmd (const char *filename, grub_chainloader_flags_t flags) { grub_partition_t p = disk->partition; - if (p && grub_strcmp (p->partmap->name, "part_msdos") == 0) + if (p && grub_strcmp (p->partmap->name, "msdos") == 0) { disk->partition = p->parent; grub_disk_read (disk, p->offset, 446, 64, diff --git a/partmap/acorn.c b/partmap/acorn.c index 12ef9c781..0c3abf11d 100644 --- a/partmap/acorn.c +++ b/partmap/acorn.c @@ -131,7 +131,7 @@ acorn_partition_map_iterate (grub_disk_t disk, /* Partition map type. */ static struct grub_partition_map grub_acorn_partition_map = { - .name = "part_acorn", + .name = "acorn", .iterate = acorn_partition_map_iterate, }; diff --git a/partmap/amiga.c b/partmap/amiga.c index 2c6a5afa2..5b6a4598f 100644 --- a/partmap/amiga.c +++ b/partmap/amiga.c @@ -138,7 +138,7 @@ amiga_partition_map_iterate (grub_disk_t disk, /* Partition map type. */ static struct grub_partition_map grub_amiga_partition_map = { - .name = "part_amiga", + .name = "amiga", .iterate = amiga_partition_map_iterate, }; diff --git a/partmap/apple.c b/partmap/apple.c index 40c59f517..35bdcc8d7 100644 --- a/partmap/apple.c +++ b/partmap/apple.c @@ -182,7 +182,7 @@ apple_partition_map_iterate (grub_disk_t disk, /* Partition map type. */ static struct grub_partition_map grub_apple_partition_map = { - .name = "part_apple", + .name = "apple", .iterate = apple_partition_map_iterate, }; diff --git a/partmap/bsdlabel.c b/partmap/bsdlabel.c index 861388164..f4df7e1fa 100644 --- a/partmap/bsdlabel.c +++ b/partmap/bsdlabel.c @@ -82,7 +82,7 @@ bsdlabel_partition_map_iterate (grub_disk_t disk, /* Partition map type. */ static struct grub_partition_map grub_bsdlabel_partition_map = { - .name = "part_bsd", + .name = "bsd", .iterate = bsdlabel_partition_map_iterate, }; diff --git a/partmap/gpt.c b/partmap/gpt.c index 922a7303b..2c942e164 100644 --- a/partmap/gpt.c +++ b/partmap/gpt.c @@ -119,7 +119,7 @@ gpt_partition_map_iterate (grub_disk_t disk, /* Partition map type. */ static struct grub_partition_map grub_gpt_partition_map = { - .name = "part_gpt", + .name = "gpt", .iterate = gpt_partition_map_iterate, }; diff --git a/partmap/msdos.c b/partmap/msdos.c index 0fbf7ef3d..accf3fdba 100644 --- a/partmap/msdos.c +++ b/partmap/msdos.c @@ -138,7 +138,7 @@ pc_partition_map_iterate (grub_disk_t disk, /* Partition map type. */ static struct grub_partition_map grub_msdos_partition_map = { - .name = "part_msdos", + .name = "msdos", .iterate = pc_partition_map_iterate, }; diff --git a/partmap/sun.c b/partmap/sun.c index ff01d1018..6f8945026 100644 --- a/partmap/sun.c +++ b/partmap/sun.c @@ -137,7 +137,7 @@ sun_partition_map_iterate (grub_disk_t disk, /* Partition map type. */ static struct grub_partition_map grub_sun_partition_map = { - .name = "part_sun", + .name = "sun", .iterate = sun_partition_map_iterate, }; diff --git a/parttool/msdospart.c b/parttool/msdospart.c index b1fe689f4..57921f35f 100644 --- a/parttool/msdospart.c +++ b/parttool/msdospart.c @@ -140,10 +140,10 @@ static grub_err_t grub_pcpart_type (const grub_device_t dev, GRUB_MOD_INIT (pcpart) { - activate_table_handle = grub_parttool_register ("part_msdos", + activate_table_handle = grub_parttool_register ("msdos", grub_pcpart_boot, grub_pcpart_bootargs); - type_table_handle = grub_parttool_register ("part_msdos", + type_table_handle = grub_parttool_register ("msdos", grub_pcpart_type, grub_pcpart_typeargs); diff --git a/util/grub-install.in b/util/grub-install.in index bb323d706..6672067b7 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -287,7 +287,10 @@ fi # Then the partition map module. In order to support partition-less media, # this command is allowed to fail (--target=fs already grants us that the # filesystem will be accessible). -partmap_module=`$grub_probe --target=partmap --device ${grub_device} 2> /dev/null` +partmap_module= +for x in `$grub_probe --target=partmap --device ${grub_device} 2> /dev/null`; do + partmap_module="$partmap_module part_$x"; +done # Device abstraction module, if any (lvm, raid). devabstraction_module=`$grub_probe --target=abstraction --device ${grub_device}` diff --git a/util/i386/efi/grub-install.in b/util/i386/efi/grub-install.in index caa7be7e4..b04bc59bd 100644 --- a/util/i386/efi/grub-install.in +++ b/util/i386/efi/grub-install.in @@ -194,7 +194,10 @@ fi # Then the partition map module. In order to support partition-less media, # this command is allowed to fail (--target=fs already grants us that the # filesystem will be accessible). -partmap_module=`$grub_probe --target=partmap --device-map=${device_map} ${grubdir} 2> /dev/null` +partmap_module= +for x in `$grub_probe --target=partmap --device ${grub_device} 2> /dev/null`; do + partmap_module="$partmap_module part_$x"; +done # Device abstraction module, if any (lvm, raid). devabstraction_module=`$grub_probe --target=abstraction --device-map=${device_map} ${grubdir}` diff --git a/util/i386/pc/grub-setup.c b/util/i386/pc/grub-setup.c index 15351ca5a..27c9cd434 100644 --- a/util/i386/pc/grub-setup.c +++ b/util/i386/pc/grub-setup.c @@ -343,16 +343,16 @@ setup (const char *dir, goto unable_to_embed; } - if (strcmp (dest_partmap, "part_msdos") == 0) + if (strcmp (dest_partmap, "msdos") == 0) grub_partition_iterate (dest_dev->disk, find_usable_region_msdos); - else if (strcmp (dest_partmap, "part_gpt") == 0) + else if (strcmp (dest_partmap, "gpt") == 0) grub_partition_iterate (dest_dev->disk, find_usable_region_gpt); else grub_util_error (_("No DOS-style partitions found")); if (embed_region.end == embed_region.start) { - if (! strcmp (dest_partmap, "part_msdos")) + if (! strcmp (dest_partmap, "msdos")) grub_util_warn (_("This msdos-style partition label has no post-MBR gap; embedding won't be possible!")); else grub_util_warn (_("This GPT partition label has no BIOS Boot Partition; embedding won't be possible!")); diff --git a/util/ieee1275/grub-install.in b/util/ieee1275/grub-install.in index 97c485d55..be4053542 100644 --- a/util/ieee1275/grub-install.in +++ b/util/ieee1275/grub-install.in @@ -179,7 +179,10 @@ fi # Then the partition map module. In order to support partition-less media, # this command is allowed to fail (--target=fs already grants us that the # filesystem will be accessible). -partmap_module=`$grub_probe --target=partmap --device-map=${device_map} ${grubdir} 2> /dev/null` +partmap_module= +for x in `$grub_probe --target=partmap --device ${grub_device} 2> /dev/null`; do + partmap_module="$partmap_module part_$x"; +done # Device abstraction module, if any (lvm, raid). devabstraction_module=`$grub_probe --target=abstraction --device-map=${device_map} ${grubdir}` From 468d69fec23203f110f1ae3610c123c58e929d4f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 6 Feb 2010 20:49:57 +0100 Subject: [PATCH 338/738] 2010-02-06 Vladimir Serbinenko * fs/fat.c (grub_fat_iterate_dir): Free unibuf at exit. --- ChangeLog | 4 ++++ fs/fat.c | 1 + 2 files changed, 5 insertions(+) diff --git a/ChangeLog b/ChangeLog index 6da224094..b9dfd7e73 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-02-06 Vladimir Serbinenko + + * fs/fat.c (grub_fat_iterate_dir): Free unibuf at exit. + 2010-02-06 Vladimir Serbinenko * loader/i386/pc/xnu.c (grub_xnu_set_video): Add const qualifier to diff --git a/fs/fat.c b/fs/fat.c index d008dc10d..89050943c 100644 --- a/fs/fat.c +++ b/fs/fat.c @@ -592,6 +592,7 @@ grub_fat_iterate_dir (grub_disk_t disk, struct grub_fat_data *data, } grub_free (filename); + grub_free (unibuf); return grub_errno; } From 6846cec5f76a14d2ca98f87e909d23e170e2da62 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 6 Feb 2010 20:52:11 +0100 Subject: [PATCH 339/738] 2010-02-06 Vladimir Serbinenko * commands/ls.c (grub_ls_list_files): Free pathname on exit. --- ChangeLog | 4 ++++ commands/ls.c | 5 +++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index b9dfd7e73..e60191a7d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-02-06 Vladimir Serbinenko + + * commands/ls.c (grub_ls_list_files): Free pathname on exit. + 2010-02-06 Vladimir Serbinenko * fs/fat.c (grub_fat_iterate_dir): Free unibuf at exit. diff --git a/commands/ls.c b/commands/ls.c index 8a8319ac8..eb1049617 100644 --- a/commands/ls.c +++ b/commands/ls.c @@ -87,14 +87,13 @@ grub_ls_list_files (char *dirname, int longlist, int all, int human) int print_files_long (const char *filename, const struct grub_dirhook_info *info) { - char *pathname; - if ((! all) && (filename[0] == '.')) return 0; if (! info->dir) { grub_file_t file; + char *pathname; if (dirname[grub_strlen (dirname) - 1] == '/') pathname = grub_xasprintf ("%s%s", dirname, filename); @@ -110,6 +109,7 @@ grub_ls_list_files (char *dirname, int longlist, int all, int human) if (! file) { grub_errno = 0; + grub_free (pathname); return 0; } @@ -144,6 +144,7 @@ grub_ls_list_files (char *dirname, int longlist, int all, int human) } grub_file_close (file); + grub_free (pathname); } else grub_printf ("%-12s", "DIR"); From f51a90d0cff937298dcd754282235fb70f210663 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 6 Feb 2010 20:59:56 +0100 Subject: [PATCH 340/738] 2010-02-06 Vladimir Serbinenko * partmap/sun.c (sun_partition_map_iterate): Restructure flow to fix buggy hook call and memory leak. --- ChangeLog | 5 ++++ partmap/sun.c | 64 ++++++++++++++++++++++++++++++--------------------- 2 files changed, 43 insertions(+), 26 deletions(-) diff --git a/ChangeLog b/ChangeLog index e60191a7d..8de063bf2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-02-06 Vladimir Serbinenko + + * partmap/sun.c (sun_partition_map_iterate): Restructure flow to fix + buggy hook call and memory leak. + 2010-02-06 Vladimir Serbinenko * commands/ls.c (grub_ls_list_files): Free pathname on exit. diff --git a/partmap/sun.c b/partmap/sun.c index 42cf0d598..df9adb0c0 100644 --- a/partmap/sun.c +++ b/partmap/sun.c @@ -91,6 +91,7 @@ sun_partition_map_iterate (grub_disk_t disk, struct grub_disk raw; struct grub_sun_block block; int partnum; + grub_err_t err; raw = *disk; raw.partition = 0; @@ -100,36 +101,47 @@ sun_partition_map_iterate (grub_disk_t disk, return grub_errno; p->partmap = &grub_sun_partition_map; - if (grub_disk_read (&raw, 0, 0, sizeof (struct grub_sun_block), - &block) == GRUB_ERR_NONE) + err = grub_disk_read (&raw, 0, 0, sizeof (struct grub_sun_block), + &block); + if (err) { - if (GRUB_PARTMAP_SUN_MAGIC != grub_be_to_cpu16 (block.magic)) - grub_error (GRUB_ERR_BAD_PART_TABLE, "not a sun partition table"); + grub_free (p); + return err; + } - if (! grub_sun_is_valid (&block)) - grub_error (GRUB_ERR_BAD_PART_TABLE, "invalid checksum"); + if (GRUB_PARTMAP_SUN_MAGIC != grub_be_to_cpu16 (block.magic)) + { + grub_free (p); + return grub_error (GRUB_ERR_BAD_PART_TABLE, + "not a sun partition table"); + } - /* Maybe another error value would be better, because partition - table _is_ recognized but invalid. */ - for (partnum = 0; partnum < GRUB_PARTMAP_SUN_MAX_PARTS; partnum++) + if (! grub_sun_is_valid (&block)) + { + grub_free (p); + return grub_error (GRUB_ERR_BAD_PART_TABLE, "invalid checksum"); + } + + /* Maybe another error value would be better, because partition + table _is_ recognized but invalid. */ + for (partnum = 0; partnum < GRUB_PARTMAP_SUN_MAX_PARTS; partnum++) + { + struct grub_sun_partition_descriptor *desc; + + if (block.infos[partnum].id == 0 + || block.infos[partnum].id == GRUB_PARTMAP_SUN_WHOLE_DISK_ID) + continue; + + desc = &block.partitions[partnum]; + p->start = ((grub_uint64_t) grub_be_to_cpu32 (desc->start_cylinder) + * grub_be_to_cpu16 (block.ntrks) + * grub_be_to_cpu16 (block.nsect)); + p->len = grub_be_to_cpu32 (desc->num_sectors); + p->index = partnum; + if (p->len) { - struct grub_sun_partition_descriptor *desc; - - if (block.infos[partnum].id == 0 - || block.infos[partnum].id == GRUB_PARTMAP_SUN_WHOLE_DISK_ID) - continue; - - desc = &block.partitions[partnum]; - p->start = ((grub_uint64_t) grub_be_to_cpu32 (desc->start_cylinder) - * grub_be_to_cpu16 (block.ntrks) - * grub_be_to_cpu16 (block.nsect)); - p->len = grub_be_to_cpu32 (desc->num_sectors); - p->index = partnum; - if (p->len) - { - if (hook (disk, p)) - partnum = GRUB_PARTMAP_SUN_MAX_PARTS; - } + if (hook (disk, p)) + partnum = GRUB_PARTMAP_SUN_MAX_PARTS; } } From f3e309ad7dc2c07d2a6b5f4e0d86fc80cd46f755 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 6 Feb 2010 21:00:53 +0100 Subject: [PATCH 341/738] Use (hd0,msdos1) syntax. Eliminate partmap_iterate --- conf/any-emu.rmk | 2 +- conf/common.rmk | 2 +- conf/i386-pc.rmk | 14 ++-- conf/sparc64-ieee1275.rmk | 6 +- include/grub/partition.h | 26 ++++-- kern/partition.c | 170 ++++++++++++++------------------------ 6 files changed, 92 insertions(+), 128 deletions(-) diff --git a/conf/any-emu.rmk b/conf/any-emu.rmk index 53d4d1be7..9038aa45d 100644 --- a/conf/any-emu.rmk +++ b/conf/any-emu.rmk @@ -34,7 +34,7 @@ grub_emu_SOURCES = commands/minicmd.c commands/cat.c commands/cmp.c \ script/main.c script/execute.c script/function.c \ script/lexer.c script/script.c grub_script.tab.c \ partmap/amiga.c partmap/apple.c partmap/msdos.c partmap/sun.c \ - partmap/acorn.c partmap/gpt.c partmap/bsd.c \ + partmap/acorn.c partmap/gpt.c partmap/bsdlabel.c \ \ fs/affs.c fs/cpio.c fs/fat.c fs/ext2.c fs/hfs.c \ fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \ diff --git a/conf/common.rmk b/conf/common.rmk index 2033d2478..009db2907 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -24,7 +24,7 @@ util/grub-probe.c_DEPENDENCIES = grub_probe_init.h grub_probe_SOURCES = gnulib/progname.c util/grub-probe.c \ util/hostdisk.c util/misc.c util/getroot.c \ kern/device.c kern/disk.c kern/err.c kern/misc.c \ - kern/parser.c kern/partition.c kern/file.c \ + kern/parser.c kern/partition.c kern/file.c kern/list.c \ \ fs/affs.c fs/cpio.c fs/fat.c fs/ext2.c fs/hfs.c \ fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \ diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk index efbf5bfa2..02675be91 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -94,14 +94,14 @@ util/grub-mkrawimage.c_DEPENDENCIES = Makefile util/i386/pc/grub-setup.c_DEPENDENCIES = grub_setup_init.h grub_setup_SOURCES = gnulib/progname.c \ util/i386/pc/grub-setup.c util/hostdisk.c \ - util/misc.c util/getroot.c kern/device.c kern/disk.c \ - kern/err.c kern/misc.c kern/parser.c kern/partition.c \ - kern/file.c kern/fs.c kern/env.c fs/fshelp.c \ + util/misc.c util/getroot.c kern/device.c kern/disk.c \ + kern/err.c kern/misc.c kern/parser.c kern/partition.c \ + kern/file.c kern/list.c kern/fs.c kern/env.c fs/fshelp.c \ \ - fs/affs.c fs/cpio.c fs/ext2.c fs/fat.c fs/hfs.c \ - fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \ - fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c \ - fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/afs_be.c \ + fs/affs.c fs/cpio.c fs/ext2.c fs/fat.c fs/hfs.c \ + fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \ + fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c \ + fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/afs_be.c \ fs/befs.c fs/befs_be.c fs/tar.c \ \ partmap/msdos.c partmap/bsdlabel.c partmap/gpt.c \ diff --git a/conf/sparc64-ieee1275.rmk b/conf/sparc64-ieee1275.rmk index 9ec8dd22c..a428c14d1 100644 --- a/conf/sparc64-ieee1275.rmk +++ b/conf/sparc64-ieee1275.rmk @@ -68,9 +68,9 @@ grub_mkimage_SOURCES = util/sparc64/ieee1275/grub-mkimage.c util/misc.c \ # For grub-setup. util/sparc64/ieee1275/grub-setup.c_DEPENDENCIES = grub_setup_init.h grub_setup_SOURCES = util/sparc64/ieee1275/grub-setup.c util/hostdisk.c \ - util/misc.c util/getroot.c kern/device.c kern/disk.c \ - kern/err.c kern/misc.c kern/parser.c kern/partition.c \ - kern/file.c kern/fs.c kern/env.c fs/fshelp.c \ + util/misc.c util/getroot.c kern/device.c kern/disk.c \ + kern/err.c kern/misc.c kern/parser.c kern/partition.c \ + kern/file.c kern/fs.c kern/env.c kern/list.c fs/fshelp.c \ \ fs/affs.c fs/cpio.c fs/ext2.c fs/fat.c fs/hfs.c \ fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \ diff --git a/include/grub/partition.h b/include/grub/partition.h index 5e8c476e0..bd97144c9 100644 --- a/include/grub/partition.h +++ b/include/grub/partition.h @@ -20,6 +20,7 @@ #define GRUB_PART_HEADER 1 #include +#include struct grub_disk; @@ -28,6 +29,9 @@ typedef struct grub_partition *grub_partition_t; /* Partition map type. */ struct grub_partition_map { + /* The next partition map type. */ + struct grub_partition_map *next; + /* The name of the partition map type. */ const char *name; @@ -35,9 +39,6 @@ struct grub_partition_map grub_err_t (*iterate) (struct grub_disk *disk, int (*hook) (struct grub_disk *disk, const grub_partition_t partition)); - - /* The next partition map type. */ - struct grub_partition_map *next; }; typedef struct grub_partition_map *grub_partition_map_t; @@ -76,11 +77,24 @@ int EXPORT_FUNC(grub_partition_iterate) (struct grub_disk *disk, const grub_partition_t partition)); char *EXPORT_FUNC(grub_partition_get_name) (const grub_partition_t partition); -int EXPORT_FUNC(grub_partition_map_iterate) (int (*hook) (const grub_partition_map_t partmap)); -void EXPORT_FUNC(grub_partition_map_register) (grub_partition_map_t partmap); +extern grub_partition_map_t EXPORT_VAR(grub_partition_map_list); -void EXPORT_FUNC(grub_partition_map_unregister) (grub_partition_map_t partmap); +static inline void +grub_partition_map_register (grub_partition_map_t partmap) +{ + grub_list_push (GRUB_AS_LIST_P (&grub_partition_map_list), + GRUB_AS_LIST (partmap)); +} + +static inline void +grub_partition_map_unregister (grub_partition_map_t partmap) +{ + grub_list_remove (GRUB_AS_LIST_P (&grub_partition_map_list), + GRUB_AS_LIST (partmap)); +} + +#define FOR_PARTITION_MAPS(var) for (var = grub_partition_map_list; var; var = var->next) #ifdef GRUB_UTIL void grub_msdos_partition_map_init (void); diff --git a/kern/partition.c b/kern/partition.c index 1f3f6556d..2a33ac329 100644 --- a/kern/partition.c +++ b/kern/partition.c @@ -21,39 +21,7 @@ #include #include -static grub_partition_map_t grub_partition_map_list; - -void -grub_partition_map_register (grub_partition_map_t partmap) -{ - partmap->next = grub_partition_map_list; - grub_partition_map_list = partmap; -} - -void -grub_partition_map_unregister (grub_partition_map_t partmap) -{ - grub_partition_map_t *p, q; - - for (p = &grub_partition_map_list, q = *p; q; p = &(q->next), q = q->next) - if (q == partmap) - { - *p = q->next; - break; - } -} - -int -grub_partition_map_iterate (int (*hook) (const grub_partition_map_t partmap)) -{ - grub_partition_map_t p; - - for (p = grub_partition_map_list; p; p = p->next) - if (hook (p)) - return 1; - - return 0; -} +grub_partition_map_t grub_partition_map_list; static grub_partition_t grub_partition_map_probe (const grub_partition_map_t partmap, @@ -97,41 +65,45 @@ grub_partition_probe (struct grub_disk *disk, const char *str) grub_partition_t curpart = 0; grub_partition_t tail; const char *ptr; - int num; - - auto int part_map_probe (const grub_partition_map_t partmap); - - int part_map_probe (const grub_partition_map_t partmap) - { - disk->partition = part; - curpart = grub_partition_map_probe (partmap, disk, num); - disk->partition = tail; - if (curpart) - return 1; - - if (grub_errno == GRUB_ERR_BAD_PART_TABLE) - { - /* Continue to next partition map type. */ - grub_errno = GRUB_ERR_NONE; - return 0; - } - - return 1; - } part = tail = disk->partition; for (ptr = str; *ptr;) { - /* BSD-like partition specification. */ - if (*ptr >= 'a' && *ptr <= 'z') - num = *(ptr++) - 'a'; - else - num = grub_strtoul (ptr, (char **) &ptr, 0) - 1; + grub_partition_map_t partmap; + int num; + const char *partname, *partname_end; + + partname = ptr; + while (*ptr && grub_isalpha (*ptr)) + ptr++; + partname_end = ptr; + num = grub_strtoul (ptr, (char **) &ptr, 0) - 1; curpart = 0; /* Use the first partition map type found. */ - grub_partition_map_iterate (part_map_probe); + FOR_PARTITION_MAPS(partmap) + { + if (partname_end != partname && + (grub_strncmp (partmap->name, partname, partname_end - partname) + != 0 || partmap->name[partname_end - partname] != 0)) + continue; + + disk->partition = part; + curpart = grub_partition_map_probe (partmap, disk, num); + disk->partition = tail; + if (curpart) + break; + + if (grub_errno == GRUB_ERR_BAD_PART_TABLE) + { + /* Continue to next partition map type. */ + grub_errno = GRUB_ERR_NONE; + continue; + } + + break; + } if (! curpart) { @@ -153,45 +125,6 @@ grub_partition_probe (struct grub_disk *disk, const char *str) return part; } -static grub_partition_map_t -get_partmap (struct grub_disk *disk) -{ - grub_partition_map_t partmap = 0; - struct grub_partition part; - int found = 0; - auto int part_map_iterate (const grub_partition_map_t p); - auto int part_map_iterate_hook (grub_disk_t d, - const grub_partition_t partition); - int part_map_iterate_hook (grub_disk_t d __attribute__ ((unused)), - const grub_partition_t partition) - { - found = 1; - part = *partition; - return 1; - } - - int part_map_iterate (const grub_partition_map_t p) - { - grub_dprintf ("partition", "Detecting %s...\n", p->name); - p->iterate (disk, part_map_iterate_hook); - - if (grub_errno != GRUB_ERR_NONE || ! found) - { - /* Continue to next partition map type. */ - grub_dprintf ("partition", "%s detection failed.\n", p->name); - grub_errno = GRUB_ERR_NONE; - return 0; - } - grub_free (part.data); - - grub_dprintf ("partition", "%s detection succeeded.\n", p->name); - partmap = p; - return 1; - } - grub_partition_map_iterate (part_map_iterate); - return partmap; -} - int grub_partition_iterate (struct grub_disk *disk, int (*hook) (grub_disk_t disk, @@ -205,27 +138,42 @@ grub_partition_iterate (struct grub_disk *disk, const grub_partition_t partition) { struct grub_partition p = *partition; - grub_partition_map_t partmap = 0; p.parent = dsk->partition; dsk->partition = 0; if (hook (dsk, &p)) + { + ret = 1; return 1; + } if (p.start != 0) { + const struct grub_partition_map *partmap; dsk->partition = &p; - partmap = get_partmap (dsk); - if (partmap) - ret = partmap->iterate (dsk, part_iterate); + FOR_PARTITION_MAPS(partmap) + { + grub_err_t err; + err = partmap->iterate (dsk, part_iterate); + if (err) + grub_errno = GRUB_ERR_NONE; + if (ret) + break; + } } dsk->partition = p.parent; return ret; } { - grub_partition_map_t partmap = 0; - partmap = get_partmap (disk); - if (partmap) - ret = partmap->iterate (disk, part_iterate); + const struct grub_partition_map *partmap; + FOR_PARTITION_MAPS(partmap) + { + grub_err_t err; + err = partmap->iterate (disk, part_iterate); + if (err) + grub_errno = GRUB_ERR_NONE; + if (ret) + break; + } } return ret; @@ -235,14 +183,16 @@ char * grub_partition_get_name (const grub_partition_t partition) { char *out = 0; - /* Even on 64-bit machines this buffer is enough to hold longest number. */ - char buf[25]; int curlen = 0; grub_partition_t part; for (part = partition; part; part = part->parent) { + /* Even on 64-bit machines this buffer is enough to hold + longest number. */ + char buf[grub_strlen (part->partmap->name) + 25]; int strl; - grub_snprintf (buf, sizeof (buf), "%d", part->number + 1); + grub_snprintf (buf, sizeof (buf), "%s%d", part->partmap->name, + part->number + 1); strl = grub_strlen (buf); if (curlen) { From 05d4e36ff618034f037fa91345627ff721926d2e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 6 Feb 2010 21:36:24 +0100 Subject: [PATCH 342/738] reimport sunpc --- conf/any-emu.rmk | 3 +- conf/common.rmk | 11 +++- conf/i386-pc.rmk | 3 +- partmap/sunpc.c | 144 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 156 insertions(+), 5 deletions(-) create mode 100644 partmap/sunpc.c diff --git a/conf/any-emu.rmk b/conf/any-emu.rmk index 9038aa45d..33cb001a5 100644 --- a/conf/any-emu.rmk +++ b/conf/any-emu.rmk @@ -34,7 +34,8 @@ grub_emu_SOURCES = commands/minicmd.c commands/cat.c commands/cmp.c \ script/main.c script/execute.c script/function.c \ script/lexer.c script/script.c grub_script.tab.c \ partmap/amiga.c partmap/apple.c partmap/msdos.c partmap/sun.c \ - partmap/acorn.c partmap/gpt.c partmap/bsdlabel.c \ + partmap/acorn.c partmap/gpt.c partmap/bsdlabel.c \ + partmap/sunpc.c \ \ fs/affs.c fs/cpio.c fs/fat.c fs/ext2.c fs/hfs.c \ fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \ diff --git a/conf/common.rmk b/conf/common.rmk index 009db2907..aefb5ac6f 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -33,7 +33,7 @@ grub_probe_SOURCES = gnulib/progname.c util/grub-probe.c \ fs/befs.c fs/befs_be.c fs/tar.c \ \ partmap/msdos.c partmap/bsdlabel.c partmap/apple.c \ - partmap/sun.c partmap/gpt.c\ + partmap/sun.c partmap/sunpc.c partmap/gpt.c \ kern/fs.c kern/env.c fs/fshelp.c \ disk/raid.c disk/mdraid_linux.c disk/lvm.c grub_probe_init.c @@ -70,8 +70,8 @@ grub_fstest_SOURCES = gnulib/progname.c util/grub-fstest.c util/hostfs.c \ fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/afs_be.c fs/befs.c \ fs/befs_be.c fs/tar.c \ \ - kern/partition.c partmap/msdos.c partmap/bsdlabel.c \ - partmap/apple.c partmap/sun.c partmap/gpt.c \ + kern/partition.c partmap/msdos.c partmap/bsdlabel.c \ + partmap/apple.c partmap/sun.c partmap/sunpc.c partmap/gpt.c \ kern/fs.c kern/env.c fs/fshelp.c disk/raid.c \ disk/raid5_recover.c disk/raid6_recover.c \ disk/mdraid_linux.c disk/dmraid_nvidia.c disk/lvm.c \ @@ -383,6 +383,11 @@ part_bsd_mod_SOURCES = partmap/bsdlabel.c part_bsd_mod_CFLAGS = $(COMMON_CFLAGS) part_bsd_mod_LDFLAGS = $(COMMON_LDFLAGS) +pkglib_MODULES += part_sunpc.mod +part_sunpc_mod_SOURCES = partmap/sunpc.c +part_sunpc_mod_CFLAGS = $(COMMON_CFLAGS) +part_sunpc_mod_LDFLAGS = $(COMMON_LDFLAGS) + # Special disk structures and generic drivers pkglib_MODULES += raid.mod raid5rec.mod raid6rec.mod mdraid.mod dm_nv.mod \ diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk index 02675be91..4cdc819bd 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -104,7 +104,8 @@ grub_setup_SOURCES = gnulib/progname.c \ fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/afs_be.c \ fs/befs.c fs/befs_be.c fs/tar.c \ \ - partmap/msdos.c partmap/bsdlabel.c partmap/gpt.c \ + partmap/msdos.c partmap/bsdlabel.c partmap/sunpc.c \ + partmap/gpt.c \ \ disk/raid.c disk/mdraid_linux.c disk/lvm.c \ util/raid.c util/lvm.c \ diff --git a/partmap/sunpc.c b/partmap/sunpc.c new file mode 100644 index 000000000..e3b16f00c --- /dev/null +++ b/partmap/sunpc.c @@ -0,0 +1,144 @@ +/* sunpc.c - Read SUN PC style partition tables. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2005,2006,2007,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define GRUB_PARTMAP_SUN_PC_MAGIC 0xDABE +#define GRUB_PARTMAP_SUN_PC_MAX_PARTS 16 +#define GRUB_PARTMAP_SUN_PC_WHOLE_DISK_ID 0x05 + +struct grub_sun_pc_partition_descriptor +{ + grub_uint16_t id; + grub_uint16_t unused; + grub_uint32_t start_sector; + grub_uint32_t num_sectors; +} __attribute__ ((packed)); + +struct grub_sun_pc_block +{ + grub_uint8_t unused[72]; + struct grub_sun_pc_partition_descriptor partitions[GRUB_PARTMAP_SUN_PC_MAX_PARTS]; + grub_uint8_t unused2[244]; + grub_uint16_t magic; /* Magic number. */ + grub_uint16_t csum; /* Label xor'd checksum. */ +} __attribute__ ((packed)); + +static struct grub_partition_map grub_sun_pc_partition_map; + +/* Verify checksum (true=ok). */ +static int +grub_sun_is_valid (struct grub_sun_pc_block *label) +{ + grub_uint16_t *pos; + grub_uint16_t sum = 0; + + for (pos = (grub_uint16_t *) label; + pos < (grub_uint16_t *) (label + 1); + pos++) + sum ^= *pos; + + return ! sum; +} + +static grub_err_t +sun_pc_partition_map_iterate (grub_disk_t disk, + int (*hook) (grub_disk_t disk, + const grub_partition_t partition)) +{ + grub_partition_t p; + struct grub_sun_pc_block block; + int partnum; + grub_err_t err; + + p = (grub_partition_t) grub_zalloc (sizeof (struct grub_partition)); + if (! p) + return grub_errno; + + p->partmap = &grub_sun_pc_partition_map; + err = grub_disk_read (disk, 1, 0, sizeof (struct grub_sun_pc_block), &block); + if (err) + { + grub_free (p); + return err; + } + + if (GRUB_PARTMAP_SUN_PC_MAGIC != grub_le_to_cpu16 (block.magic)) + { + grub_free (p); + return grub_error (GRUB_ERR_BAD_PART_TABLE, + "not a sun_pc partition table"); + } + + if (! grub_sun_is_valid (&block)) + { + grub_free (p); + return grub_error (GRUB_ERR_BAD_PART_TABLE, "invalid checksum"); + } + + /* Maybe another error value would be better, because partition + table _is_ recognized but invalid. */ + for (partnum = 0; partnum < GRUB_PARTMAP_SUN_PC_MAX_PARTS; partnum++) + { + struct grub_sun_pc_partition_descriptor *desc; + + if (block.partitions[partnum].id == 0 + || block.partitions[partnum].id == GRUB_PARTMAP_SUN_PC_WHOLE_DISK_ID) + continue; + + desc = &block.partitions[partnum]; + p->start = grub_le_to_cpu32 (desc->start_sector); + p->len = grub_le_to_cpu32 (desc->num_sectors); + p->number = partnum; + if (p->len) + { + if (hook (disk, p)) + partnum = GRUB_PARTMAP_SUN_PC_MAX_PARTS; + } + } + + grub_free (p); + + return grub_errno; +} + +/* Partition map type. */ +static struct grub_partition_map grub_sun_pc_partition_map = + { + .name = "sunpc", + .iterate = sun_pc_partition_map_iterate, + }; + +GRUB_MOD_INIT(sun_pc_partition_map) +{ + grub_partition_map_register (&grub_sun_pc_partition_map); +} + +GRUB_MOD_FINI(sun_pc_partition_map) +{ + grub_partition_map_unregister (&grub_sun_pc_partition_map); +} + From b6c0d9c2019996754e8a04b53a328c43c85f5c73 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 6 Feb 2010 23:39:14 +0100 Subject: [PATCH 343/738] 2010-02-06 Vladimir Serbinenko * kern/misc.c (grub_utf8_to_ucs4): Don't eat valid characters preceeded by non-valid ones. * kern/term.c (grub_putchar): Likewise. --- ChangeLog | 6 ++++++ kern/misc.c | 4 ++++ kern/term.c | 9 +++++---- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8de063bf2..e71065338 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-02-06 Vladimir Serbinenko + + * kern/misc.c (grub_utf8_to_ucs4): Don't eat valid characters preceeded + by non-valid ones. + * kern/term.c (grub_putchar): Likewise. + 2010-02-06 Vladimir Serbinenko * partmap/sun.c (sun_partition_map_iterate): Restructure flow to fix diff --git a/kern/misc.c b/kern/misc.c index 309267786..f45991d96 100644 --- a/kern/misc.c +++ b/kern/misc.c @@ -971,6 +971,10 @@ grub_utf8_to_ucs4 (grub_uint32_t *dest, grub_size_t destsize, { /* invalid */ code = '?'; + /* Character c may be valid, don't eat it. */ + src--; + if (srcsize != (grub_size_t)-1) + srcsize++; count = 0; } else diff --git a/kern/term.c b/kern/term.c index b381d9336..6e3a2b454 100644 --- a/kern/term.c +++ b/kern/term.c @@ -57,16 +57,17 @@ grub_putchar (int c) { static grub_size_t size = 0; static grub_uint8_t buf[6]; + grub_uint8_t *rest; grub_uint32_t code; - grub_size_t ret; buf[size++] = c; - ret = grub_utf8_to_ucs4 (&code, 1, buf, size, 0); - if (ret != 0) + while (grub_utf8_to_ucs4 (&code, 1, buf, size, (const grub_uint8_t **) &rest) + != 0) { struct grub_term_output *term; - size = 0; + size -= rest - buf; + grub_memmove (buf, rest, size); FOR_ACTIVE_TERM_OUTPUTS(term) grub_putcode (code, term); if (code == '\n' && grub_newline_hook) From 007d0695e2f4a60f2a1919f002c6fda589f1750b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 7 Feb 2010 00:36:18 +0100 Subject: [PATCH 344/738] 2010-02-07 Vladimir Serbinenko * include/grub/i18n.h (grub_gettext_dummy): Removed. * kern/misc.c (grub_gettext_dummy): Make static. --- ChangeLog | 5 +++++ include/grub/i18n.h | 1 - kern/misc.c | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index e71065338..b6b74e8a3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-02-07 Vladimir Serbinenko + + * include/grub/i18n.h (grub_gettext_dummy): Removed. + * kern/misc.c (grub_gettext_dummy): Make static. + 2010-02-06 Vladimir Serbinenko * kern/misc.c (grub_utf8_to_ucs4): Don't eat valid characters preceeded diff --git a/include/grub/i18n.h b/include/grub/i18n.h index 4d4a0b7bd..0cba54765 100644 --- a/include/grub/i18n.h +++ b/include/grub/i18n.h @@ -22,7 +22,6 @@ #include #include -const char *EXPORT_FUNC(grub_gettext_dummy) (const char *s); extern const char *(*EXPORT_VAR(grub_gettext)) (const char *s); /* NLS can be disabled through the configure --disable-nls option. */ diff --git a/kern/misc.c b/kern/misc.c index f45991d96..4772e22b0 100644 --- a/kern/misc.c +++ b/kern/misc.c @@ -35,7 +35,7 @@ grub_iswordseparator (int c) } /* grub_gettext_dummy is not translating anything. */ -const char * +static const char * grub_gettext_dummy (const char *s) { return s; From a4bced7752d6be5c367c46f1322c93b642f3e4f1 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 7 Feb 2010 00:40:17 +0100 Subject: [PATCH 345/738] 2010-02-07 Vladimir Serbinenko * include/grub/dl.h (grub_dl_register_symbol): Don't export. --- ChangeLog | 4 ++++ include/grub/dl.h | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index b6b74e8a3..1f1b1c2e2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-02-07 Vladimir Serbinenko + + * include/grub/dl.h (grub_dl_register_symbol): Don't export. + 2010-02-07 Vladimir Serbinenko * include/grub/i18n.h (grub_gettext_dummy): Removed. diff --git a/include/grub/dl.h b/include/grub/dl.h index 9340b6ce4..ac0ecd336 100644 --- a/include/grub/dl.h +++ b/include/grub/dl.h @@ -110,8 +110,8 @@ int EXPORT_FUNC(grub_dl_unref) (grub_dl_t mod); #endif void EXPORT_FUNC(grub_dl_iterate) (int (*hook) (grub_dl_t mod)); grub_dl_t EXPORT_FUNC(grub_dl_get) (const char *name); -grub_err_t EXPORT_FUNC(grub_dl_register_symbol) (const char *name, void *addr, - grub_dl_t mod); +grub_err_t grub_dl_register_symbol (const char *name, void *addr, + grub_dl_t mod); grub_err_t grub_arch_dl_check_header (void *ehdr); grub_err_t grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr); From 74b45184e47b791abac5324241aa887ce74310ab Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 7 Feb 2010 00:46:09 +0100 Subject: [PATCH 346/738] 2010-02-07 Vladimir Serbinenko * include/grub/err.h (grub_err_printf): Don't export. --- ChangeLog | 4 ++++ include/grub/err.h | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1f1b1c2e2..22c14424e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-02-07 Vladimir Serbinenko + + * include/grub/err.h (grub_err_printf): Don't export. + 2010-02-07 Vladimir Serbinenko * include/grub/dl.h (grub_dl_register_symbol): Don't export. diff --git a/include/grub/err.h b/include/grub/err.h index 7a5ce1ae0..e44705389 100644 --- a/include/grub/err.h +++ b/include/grub/err.h @@ -66,7 +66,7 @@ void EXPORT_FUNC(grub_fatal) (const char *fmt, ...) __attribute__ ((noreturn)); void EXPORT_FUNC(grub_error_push) (void); int EXPORT_FUNC(grub_error_pop) (void); void EXPORT_FUNC(grub_print_error) (void); -int EXPORT_FUNC(grub_err_printf) (const char *fmt, ...) -__attribute__ ((format (printf, 1, 2))); +int grub_err_printf (const char *fmt, ...) + __attribute__ ((format (printf, 1, 2))); #endif /* ! GRUB_ERR_HEADER */ From 8f891adc6f193b70915635418c2b73b5450b1546 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 7 Feb 2010 00:52:31 +0100 Subject: [PATCH 347/738] 2010-02-07 Vladimir Serbinenko * include/grub/cache.h (grub_arch_sync_caches) [i386 || x86_64]: Inline. * kern/i386/coreboot/init.c (grub_arch_sync_caches): Remove. * kern/i386/efi/init.c (grub_arch_sync_caches): Likewise. * kern/i386/ieee1275/init.c (grub_arch_sync_caches): Likewise. * kern/i386/pc/init.c (grub_arch_sync_caches): Likewise. * util/misc.c (grub_arch_sync_caches) [i386 || x86_64]: Likewise. --- ChangeLog | 9 +++++++++ include/grub/cache.h | 8 ++++++++ kern/i386/coreboot/init.c | 6 ------ kern/i386/efi/init.c | 6 ------ kern/i386/ieee1275/init.c | 6 ------ kern/i386/pc/init.c | 6 ------ util/misc.c | 2 ++ 7 files changed, 19 insertions(+), 24 deletions(-) diff --git a/ChangeLog b/ChangeLog index 22c14424e..c91b4a042 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2010-02-07 Vladimir Serbinenko + + * include/grub/cache.h (grub_arch_sync_caches) [i386 || x86_64]: Inline. + * kern/i386/coreboot/init.c (grub_arch_sync_caches): Remove. + * kern/i386/efi/init.c (grub_arch_sync_caches): Likewise. + * kern/i386/ieee1275/init.c (grub_arch_sync_caches): Likewise. + * kern/i386/pc/init.c (grub_arch_sync_caches): Likewise. + * util/misc.c (grub_arch_sync_caches) [i386 || x86_64]: Likewise. + 2010-02-07 Vladimir Serbinenko * include/grub/err.h (grub_err_printf): Don't export. diff --git a/include/grub/cache.h b/include/grub/cache.h index 745af43c3..27e44f0a2 100644 --- a/include/grub/cache.h +++ b/include/grub/cache.h @@ -23,6 +23,14 @@ #include #include +#if defined (__i386__) || defined (__x86_64__) +static inline void +grub_arch_sync_caches (void *address __attribute__ ((unused)), + grub_size_t len __attribute__ ((unused))) +{ +} +#else void EXPORT_FUNC(grub_arch_sync_caches) (void *address, grub_size_t len); +#endif #endif /* ! GRUB_CACHE_HEADER */ diff --git a/kern/i386/coreboot/init.c b/kern/i386/coreboot/init.c index 550a2a60a..5f80f28c1 100644 --- a/kern/i386/coreboot/init.c +++ b/kern/i386/coreboot/init.c @@ -67,12 +67,6 @@ grub_exit (void) grub_cpu_idle (); } -void -grub_arch_sync_caches (void *address __attribute__ ((unused)), - grub_size_t len __attribute__ ((unused))) -{ -} - void grub_machine_init (void) { diff --git a/kern/i386/efi/init.c b/kern/i386/efi/init.c index e1950d758..f73f828c6 100644 --- a/kern/i386/efi/init.c +++ b/kern/i386/efi/init.c @@ -45,9 +45,3 @@ grub_machine_set_prefix (void) { grub_efi_set_prefix (); } - -void -grub_arch_sync_caches (void *address __attribute__ ((unused)), - grub_size_t len __attribute__ ((unused))) -{ -} diff --git a/kern/i386/ieee1275/init.c b/kern/i386/ieee1275/init.c index 7658ee1a7..9fb98739b 100644 --- a/kern/i386/ieee1275/init.c +++ b/kern/i386/ieee1275/init.c @@ -26,9 +26,3 @@ void grub_stop_floppy (void) { } - -void -grub_arch_sync_caches (void *address __attribute__ ((unused)), - grub_size_t len __attribute__ ((unused))) -{ -} diff --git a/kern/i386/pc/init.c b/kern/i386/pc/init.c index 1707049fe..fa646df19 100644 --- a/kern/i386/pc/init.c +++ b/kern/i386/pc/init.c @@ -47,12 +47,6 @@ static int num_regions; grub_addr_t grub_os_area_addr; grub_size_t grub_os_area_size; -void -grub_arch_sync_caches (void *address __attribute__ ((unused)), - grub_size_t len __attribute__ ((unused))) -{ -} - static char * make_install_device (void) { diff --git a/util/misc.c b/util/misc.c index 371e7cc14..4e8eec323 100644 --- a/util/misc.c +++ b/util/misc.c @@ -371,11 +371,13 @@ grub_millisleep (grub_uint32_t ms) #endif +#if !(defined (__i386__) || defined (__x86_64__)) void grub_arch_sync_caches (void *address __attribute__ ((unused)), grub_size_t len __attribute__ ((unused))) { } +#endif #ifndef HAVE_VASPRINTF From 6b2ad14b7aeb2c168859889c2aa54da5a24f8cbb Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 7 Feb 2010 01:33:37 +0100 Subject: [PATCH 348/738] 2010-02-07 Vladimir Serbinenko * fs/reiserfs.c (grub_reiserfs_read): Use #if 0 instead of commenting code out. --- ChangeLog | 5 +++++ fs/reiserfs.c | 6 ++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index c91b4a042..771ba8e04 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-02-07 Vladimir Serbinenko + + * fs/reiserfs.c (grub_reiserfs_read): Use #if 0 instead of commenting + code out. + 2010-02-07 Vladimir Serbinenko * include/grub/cache.h (grub_arch_sync_caches) [i386 || x86_64]: Inline. diff --git a/fs/reiserfs.c b/fs/reiserfs.c index 444bf3120..c3db52f60 100644 --- a/fs/reiserfs.c +++ b/fs/reiserfs.c @@ -1189,7 +1189,8 @@ grub_reiserfs_read (grub_file_t file, char *buf, grub_size_t len) (unsigned long long) (current_position - initial_position), (unsigned long) len); return current_position - initial_position; -/* + +#if 0 switch (found.type) { case GRUB_REISERFS_DIRECT: @@ -1232,7 +1233,8 @@ grub_reiserfs_read (grub_file_t file, char *buf, grub_size_t len) goto fail; } - return read_length;*/ + return read_length; +#endif fail: grub_free (indirect_block_ptr); From 74e31b5ca20e3cf62d2233e4efcc82dd5ab3df05 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 7 Feb 2010 01:41:23 +0100 Subject: [PATCH 349/738] 2010-02-07 Vladimir Serbinenko * loader/i386/linux.c (grub_linux_setup_video): Handle error appropriately. --- ChangeLog | 5 +++++ loader/i386/linux.c | 11 +++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 771ba8e04..46c96bdb2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-02-07 Vladimir Serbinenko + + * loader/i386/linux.c (grub_linux_setup_video): Handle error + appropriately. + 2010-02-07 Vladimir Serbinenko * fs/reiserfs.c (grub_reiserfs_read): Use #if 0 instead of commenting diff --git a/loader/i386/linux.c b/loader/i386/linux.c index 831d8b25a..630aec6f4 100644 --- a/loader/i386/linux.c +++ b/loader/i386/linux.c @@ -394,12 +394,15 @@ grub_linux_setup_video (struct linux_kernel_params *params) { struct grub_video_mode_info mode_info; void *framebuffer; - int ret; + grub_err_t err; - ret = grub_video_get_info_and_fini (&mode_info, &framebuffer); + err = grub_video_get_info_and_fini (&mode_info, &framebuffer); - if (ret) - return 1; + if (err) + { + grub_errno = GRUB_ERR_NONE; + return 1; + } params->lfb_width = mode_info.width; params->lfb_height = mode_info.height; From 58548abbc3c738c27bba25e45aeaaa2fdba1a992 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 7 Feb 2010 01:48:38 +0100 Subject: [PATCH 350/738] Remove data member in partition structure --- include/grub/partition.h | 3 --- kern/disk.c | 1 - partmap/acorn.c | 1 - partmap/amiga.c | 2 -- partmap/apple.c | 11 +++++------ partmap/gpt.c | 9 +-------- partmap/msdos.c | 1 - util/i386/pc/grub-setup.c | 10 +++++++--- 8 files changed, 13 insertions(+), 25 deletions(-) diff --git a/include/grub/partition.h b/include/grub/partition.h index bd97144c9..9feb9459d 100644 --- a/include/grub/partition.h +++ b/include/grub/partition.h @@ -60,9 +60,6 @@ struct grub_partition /* The index of this partition in the partition table. */ int index; - /* Partition map type specific data. */ - void *data; - /* Parent partition map. */ struct grub_partition *parent; diff --git a/kern/disk.c b/kern/disk.c index 514f28c15..ccd5f200f 100644 --- a/kern/disk.c +++ b/kern/disk.c @@ -342,7 +342,6 @@ grub_disk_close (grub_disk_t disk) while (disk->partition) { part = disk->partition->parent; - grub_free (disk->partition->data); grub_free (disk->partition); disk->partition = part; } diff --git a/partmap/acorn.c b/partmap/acorn.c index 0c3abf11d..f3b36106e 100644 --- a/partmap/acorn.c +++ b/partmap/acorn.c @@ -106,7 +106,6 @@ acorn_partition_map_iterate (grub_disk_t disk, return err; part.partmap = &grub_acorn_partition_map; - part.data = 0; for (i = 0; i != LINUX_MAP_ENTRIES; ++i) { diff --git a/partmap/amiga.c b/partmap/amiga.c index 5b6a4598f..b5fba0dbc 100644 --- a/partmap/amiga.c +++ b/partmap/amiga.c @@ -99,8 +99,6 @@ amiga_partition_map_iterate (grub_disk_t disk, return grub_error (GRUB_ERR_BAD_PART_TABLE, "Amiga partition map not found"); - part.data = 0; - /* The end of the partition list is marked using "-1". */ while (next != -1) { diff --git a/partmap/apple.c b/partmap/apple.c index 35bdcc8d7..b9d3e9174 100644 --- a/partmap/apple.c +++ b/partmap/apple.c @@ -122,17 +122,16 @@ apple_partition_map_iterate (grub_disk_t disk, goto fail; } - part.data = 0; pos = grub_be_to_cpu16 (aheader.blocksize); do { - part.offset = pos / GRUB_DISK_SECTOR_SIZE; - part.index = pos % GRUB_DISK_SECTOR_SIZE; + part.offset = pos / GRUB_DISK_SECTOR_SIZE; + part.index = pos % GRUB_DISK_SECTOR_SIZE; - if (grub_disk_read (disk, part.offset, part.index, - sizeof (struct grub_apple_part), &apart)) - return grub_errno; + if (grub_disk_read (disk, part.offset, part.index, + sizeof (struct grub_apple_part), &apart)) + return grub_errno; if (grub_be_to_cpu16 (apart.magic) != GRUB_APPLE_PART_MAGIC) { diff --git a/partmap/gpt.c b/partmap/gpt.c index 2c942e164..8b799d4d5 100644 --- a/partmap/gpt.c +++ b/partmap/gpt.c @@ -71,15 +71,11 @@ gpt_partition_map_iterate (grub_disk_t disk, grub_dprintf ("gpt", "Read a valid GPT header\n"); entries = grub_le_to_cpu64 (gpt.partitions); - part.data = grub_malloc (sizeof (entry)); for (i = 0; i < grub_le_to_cpu32 (gpt.maxpart); i++) { if (grub_disk_read (disk, entries, last_offset, sizeof (entry), &entry)) - { - grub_free (part.data); - return grub_errno; - } + return grub_errno; if (grub_memcmp (&grub_gpt_partition_type_empty, &entry.type, sizeof (grub_gpt_partition_type_empty))) @@ -92,7 +88,6 @@ gpt_partition_map_iterate (grub_disk_t disk, part.number = i; part.index = last_offset; part.partmap = &grub_gpt_partition_map; - grub_memcpy (part.data, &entry, sizeof (entry)); grub_dprintf ("gpt", "GPT entry %d: start=%lld, length=%lld\n", i, (unsigned long long) part.start, @@ -110,8 +105,6 @@ gpt_partition_map_iterate (grub_disk_t disk, } } - grub_free (part.data); - return GRUB_ERR_NONE; } diff --git a/partmap/msdos.c b/partmap/msdos.c index accf3fdba..bafd86eb6 100644 --- a/partmap/msdos.c +++ b/partmap/msdos.c @@ -40,7 +40,6 @@ pc_partition_map_iterate (grub_disk_t disk, p.offset = 0; ext_offset = 0; - p.data = 0; p.number = -1; p.partmap = &grub_msdos_partition_map; diff --git a/util/i386/pc/grub-setup.c b/util/i386/pc/grub-setup.c index 27c9cd434..af0217d10 100644 --- a/util/i386/pc/grub-setup.c +++ b/util/i386/pc/grub-setup.c @@ -130,17 +130,21 @@ setup (const char *dir, int NESTED_FUNC_ATTR find_usable_region_gpt (grub_disk_t disk __attribute__ ((unused)), const grub_partition_t p) { - struct grub_gpt_partentry *gptdata = p->data; + struct grub_gpt_partentry gptdata; + + disk->partition = p->parent; + if (grub_disk_read (disk, p->offset, p->index, + sizeof (gptdata), &gptdata)) + return 0; /* If there's an embed region, it is in a dedicated partition. */ - if (! memcmp (&gptdata->type, &grub_gpt_partition_type_bios_boot, 16)) + if (! memcmp (&gptdata.type, &grub_gpt_partition_type_bios_boot, 16)) { embed_region.start = p->start; embed_region.end = p->start + p->len; return 1; } - return 0; } From 909301af11e312a64fba7929bbb53f48b9460615 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 7 Feb 2010 02:07:35 +0100 Subject: [PATCH 351/738] First try at generating grub-emu from modules --- Makefile.in | 2 +- commands/sleep.c | 1 - conf/any-emu.rmk | 113 ++++++++++++++++++++----------------------- configure.ac | 1 + disk/loopback.c | 4 +- font/font_cmd.c | 4 +- genemuinit.sh | 68 ++++++++++++++++++++++++++ genemuinitheader.sh | 48 ++++++++++++++++++ include/grub/i18n.h | 8 +-- partmap/acorn.c | 4 +- partmap/amiga.c | 4 +- partmap/apple.c | 4 +- partmap/gpt.c | 4 +- partmap/msdos.c | 4 +- partmap/sun.c | 4 +- parttool/msdospart.c | 4 +- term/gfxterm.c | 12 ++--- util/grub-emu.c | 6 +-- video/bitmap.c | 4 +- video/readers/jpeg.c | 4 +- video/readers/png.c | 4 +- video/readers/tga.c | 4 +- video/video.c | 4 +- 23 files changed, 209 insertions(+), 106 deletions(-) create mode 100644 genemuinit.sh create mode 100644 genemuinitheader.sh diff --git a/Makefile.in b/Makefile.in index 46b380cd5..faf13a134 100644 --- a/Makefile.in +++ b/Makefile.in @@ -84,7 +84,7 @@ TARGET_ASFLAGS = @TARGET_ASFLAGS@ TARGET_MODULE_FORMAT = @TARGET_MODULE_FORMAT@ TARGET_APPLE_CC = @TARGET_APPLE_CC@ OBJCONV = @OBJCONV@ -TARGET_CPPFLAGS = @TARGET_CPPFLAGS@ -nostdinc -isystem $(shell $(TARGET_CC) -print-file-name=include) -I$(srcdir)/include -I$(builddir) -I$(builddir)/include \ +TARGET_CPPFLAGS = @TARGET_CPPFLAGS@ -I$(srcdir)/include -I$(builddir) -I$(builddir)/include \ -Wall -W TARGET_LDFLAGS = @TARGET_LDFLAGS@ TARGET_IMG_LDSCRIPT = @TARGET_IMG_LDSCRIPT@ diff --git a/commands/sleep.c b/commands/sleep.c index 9207b60a7..cb208c96f 100644 --- a/commands/sleep.c +++ b/commands/sleep.c @@ -22,7 +22,6 @@ #include #include #include -#include #include static const struct grub_arg_option options[] = diff --git a/conf/any-emu.rmk b/conf/any-emu.rmk index fb97de0a0..310076345 100644 --- a/conf/any-emu.rmk +++ b/conf/any-emu.rmk @@ -1,94 +1,85 @@ # -*- makefile -*- +COMMON_LDFLAGS += -nostdlib +COMMON_CFLAGS += -DGRUB_UTIL=1 + # Used by various components. These rules need to precede them. script/lexer.c_DEPENDENCIES = grub_script.tab.h -sbin_UTILITIES += grub-emu +#sbin_UTILITIES += grub-emu util/grub-emu.c_DEPENDENCIES = grub_emu_init.h -grub_emu_SOURCES = commands/minicmd.c commands/cat.c commands/cmp.c \ - commands/configfile.c commands/echo.c commands/help.c \ - commands/handler.c commands/ls.c commands/test.c \ - commands/search.c commands/blocklist.c commands/hexdump.c \ - lib/hexdump.c commands/halt.c commands/reboot.c \ - lib/envblk.c commands/loadenv.c \ - commands/gptsync.c commands/probe.c commands/xnu_uuid.c \ - commands/password.c commands/keystatus.c \ - disk/host.c disk/loopback.c disk/scsi.c \ - fs/fshelp.c \ - \ - io/gzio.c \ - kern/device.c kern/disk.c kern/dl.c kern/elf.c kern/env.c \ +pkglib_MODULES += main.mod +main_mod_SOURCES = kern/device.c kern/disk.c kern/dl.c kern/env.c \ kern/err.c kern/list.c kern/handler.c \ - kern/command.c kern/corecmd.c commands/extcmd.c kern/file.c \ + kern/command.c kern/corecmd.c kern/file.c \ kern/fs.c commands/boot.c kern/main.c kern/misc.c kern/parser.c \ kern/partition.c kern/reader.c kern/term.c \ kern/rescue_reader.c kern/rescue_parser.c \ - lib/arg.c normal/cmdline.c normal/datetime.c normal/misc.c \ - normal/handler.c normal/auth.c normal/autofs.c \ - normal/completion.c normal/main.c normal/color.c \ - normal/menu.c normal/menu_entry.c normal/menu_viewer.c \ - normal/menu_text.c \ - script/main.c script/execute.c script/function.c \ - script/lexer.c script/script.c grub_script.tab.c \ - partmap/amiga.c partmap/apple.c partmap/msdos.c partmap/sun.c \ - partmap/acorn.c partmap/gpt.c \ \ - fs/affs.c fs/cpio.c fs/fat.c fs/ext2.c fs/hfs.c \ - fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \ - fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c \ - fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/afs_be.c \ - fs/befs.c fs/befs_be.c fs/tar.c \ - \ - util/console.c util/hostfs.c util/grub-emu.c util/misc.c \ + util/console.c util/grub-emu.c util/misc.c \ util/hostdisk.c util/getroot.c \ \ - disk/raid.c disk/raid5_recover.c disk/raid6_recover.c \ - disk/mdraid_linux.c disk/dmraid_nvidia.c disk/lvm.c \ - commands/parttool.c parttool/msdospart.c \ grub_emu_init.c gnulib/progname.c +main_mod_CFLAGS = $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 +main_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For hostfs.mod. +pkglib_MODULES += hostfs.mod +hostfs_mod_SOURCES = util/hostfs.c +hostfs_mod_CFLAGS = $(COMMON_CFLAGS) +hostfs_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For host.mod. +pkglib_MODULES += host.mod +host_mod_SOURCES = disk/host.c +host_mod_CFLAGS = $(COMMON_CFLAGS) +host_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For reboot.mod. +pkglib_MODULES += reboot.mod +reboot_mod_SOURCES = commands/reboot.c +reboot_mod_CFLAGS = $(COMMON_CFLAGS) +reboot_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For halt.mod. +pkglib_MODULES += halt.mod +halt_mod_SOURCES = commands/halt.c +halt_mod_CFLAGS = $(COMMON_CFLAGS) +halt_mod_LDFLAGS = $(COMMON_LDFLAGS) ifeq ($(target_cpu), i386) -grub_emu_SOURCES += commands/i386/cpuid.c +pkglib_MODULES += cpuid.mod +cpuid_mod_SOURCES = commands/i386/cpuid.c +cpuid_mod_CFLAGS = $(COMMON_CFLAGS) +cpuid_mod_LDFLAGS = $(COMMON_LDFLAGS) endif grub_emu_LDFLAGS = $(LIBCURSES) ifeq ($(enable_grub_emu_usb), yes) -grub_emu_SOURCES += disk/usbms.c util/usb.c bus/usb/usb.c \ +pkglib_MODULES += usb.mod +usb_mod_SOURCES = disk/usbms.c util/usb.c bus/usb/usb.c \ commands/usbtest.c -grub_emu_LDFLAGS += $(LIBCURSES) $(LIBUSB) +cpuid_mod_CFLAGS = $(COMMON_CFLAGS) +usb_mod_LDFLAGS = $(COMMON_LDFLAGS) $(LIBUSB) endif ifeq ($(enable_grub_emu_pci), yes) -grub_emu_SOURCES += util/pci.c commands/lspci.c -grub_emu_LDFLAGS += $(LIBPCIACCESS) +pkglib_MODULES += pci.mod +pci_mod_SOURCES = util/pci.c commands/lspci.c +pci_mod_LDFLAGS = $(LIBPCIACCESS) endif -grub_emu_init.lst: geninit.sh $(filter-out grub_emu_init.c,$(grub_emu_SOURCES)) - rm -f $@; grep GRUB_MOD_INIT $(filter %.c,$^) /dev/null > $@ -DISTCLEANFILES += grub_emu_init.lst -grub_emu_init.h: grub_emu_init.lst $(filter-out grub_emu_init.c,$(grub_emu_SOURCES)) geninitheader.sh - rm -f $@; sh $(srcdir)/geninitheader.sh $< > $@ +grub_emu_init.h: genemuinitheader.sh + rm -f $@; echo $(pkglib_MODULES) |sh $(srcdir)/genemuinitheader.sh > $@ DISTCLEANFILES += grub_emu_init.h -grub_emu_init.c: grub_emu_init.lst $(filter-out grub_emu_init.c,$(grub_emu_SOURCES)) geninit.sh grub_emu_init.h - rm -f $@; sh $(srcdir)/geninit.sh $< $(filter %.c,$^) > $@ +grub_emu_init.c: genemuinit.sh + rm -f $@; echo $(pkglib_MODULES) |sed 's,elf.mod,,;s,extcmd.mod,,;s,main.mod,,;s,gzio.mod,,;s,fshelp.mod,,;s,bufio.mod,,;s,setjmp.mod,,;'|sh $(srcdir)/genemuinit.sh > $@ DISTCLEANFILES += grub_emu_init.c +include $(srcdir)/conf/common.mk - - -# FIXME: this could be shared with common.rmk - -# For grub-mkfont. -ifeq ($(enable_grub_mkfont), yes) -bin_UTILITIES += grub-mkfont -grub_mkfont_SOURCES = gnulib/progname.c util/grub-mkfont.c util/misc.c -grub_mkfont_CFLAGS = $(freetype_cflags) -grub_mkfont_LDFLAGS = $(freetype_libs) -endif - -grub_script.tab.c grub_script.tab.h: script/parser.y - $(YACC) -d -p grub_script_yy -b grub_script $(srcdir)/script/parser.y -DISTCLEANFILES += grub_script.tab.c grub_script.tab.h +grub-emu: $(pkglib_MODULES) + $(CC) -o $@ $(pkglib_MODULES) $(grub_emu_LDFLAGS) $(LDFLAGS) $(grub_emu_SOURCES) diff --git a/configure.ac b/configure.ac index 6560d3e31..098e4524e 100644 --- a/configure.ac +++ b/configure.ac @@ -74,6 +74,7 @@ fi if test -z "$target_alias"; then case "$target_cpu"-"$platform" in x86_64-efi) ;; + x86_64-emu) ;; x86_64-*) target_cpu=i386 ;; powerpc64-ieee1275) target_cpu=powerpc ;; esac diff --git a/disk/loopback.c b/disk/loopback.c index 29805182e..a8bc25d8c 100644 --- a/disk/loopback.c +++ b/disk/loopback.c @@ -241,7 +241,7 @@ static struct grub_disk_dev grub_loopback_dev = static grub_extcmd_t cmd; -GRUB_MOD_INIT(loop) +GRUB_MOD_INIT(loopback) { cmd = grub_register_extcmd ("loopback", grub_cmd_loopback, GRUB_COMMAND_FLAG_BOTH, @@ -250,7 +250,7 @@ GRUB_MOD_INIT(loop) grub_disk_dev_register (&grub_loopback_dev); } -GRUB_MOD_FINI(loop) +GRUB_MOD_FINI(loopback) { grub_unregister_extcmd (cmd); grub_disk_dev_unregister (&grub_loopback_dev); diff --git a/font/font_cmd.c b/font/font_cmd.c index 0402b8d77..b3eeb4dca 100644 --- a/font/font_cmd.c +++ b/font/font_cmd.c @@ -56,7 +56,7 @@ lsfonts_command (grub_command_t cmd __attribute__ ((unused)), static grub_command_t cmd_loadfont, cmd_lsfonts; -GRUB_MOD_INIT(font_manager) +GRUB_MOD_INIT(font) { grub_font_loader_init (); @@ -69,7 +69,7 @@ GRUB_MOD_INIT(font_manager) 0, "List the loaded fonts."); } -GRUB_MOD_FINI(font_manager) +GRUB_MOD_FINI(font) { /* TODO: Determine way to free allocated resources. Warning: possible pointer references could be in use. */ diff --git a/genemuinit.sh b/genemuinit.sh new file mode 100644 index 000000000..e40a683af --- /dev/null +++ b/genemuinit.sh @@ -0,0 +1,68 @@ +#! /bin/sh +# +# Copyright (C) 2002,2005,2007 Free Software Foundation, Inc. +# +# This gensymlist.sh is free software; the author +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +lst="$1" +shift + +cat <. + */ + +#include "grub_emu_init.h" + +EOF + +cat <. + */ + +EOF + +cat < # include -# define _(str) gettext(str) -#else +//# define _(str) gettext(str) +//#else # define _(str) grub_gettext(str) const char *EXPORT_FUNC(grub_gettext_dummy) (const char *s); extern const char *(*EXPORT_VAR(grub_gettext)) (const char *s); -#endif + //#endif #define N_(str) str diff --git a/partmap/acorn.c b/partmap/acorn.c index e005975c0..ed8738755 100644 --- a/partmap/acorn.c +++ b/partmap/acorn.c @@ -195,12 +195,12 @@ static struct grub_partition_map grub_acorn_partition_map = .get_name = acorn_partition_map_get_name }; -GRUB_MOD_INIT(acorn_partition_map) +GRUB_MOD_INIT(part_acorn) { grub_partition_map_register (&grub_acorn_partition_map); } -GRUB_MOD_FINI(acorn_partition_map) +GRUB_MOD_FINI(part_acorn) { grub_partition_map_unregister (&grub_acorn_partition_map); } diff --git a/partmap/amiga.c b/partmap/amiga.c index dce9f4f1f..f769d4048 100644 --- a/partmap/amiga.c +++ b/partmap/amiga.c @@ -204,12 +204,12 @@ static struct grub_partition_map grub_amiga_partition_map = .get_name = amiga_partition_map_get_name }; -GRUB_MOD_INIT(amiga_partition_map) +GRUB_MOD_INIT(part_amiga) { grub_partition_map_register (&grub_amiga_partition_map); } -GRUB_MOD_FINI(amiga_partition_map) +GRUB_MOD_FINI(part_amiga) { grub_partition_map_unregister (&grub_amiga_partition_map); } diff --git a/partmap/apple.c b/partmap/apple.c index 4dea55a32..6208ebcea 100644 --- a/partmap/apple.c +++ b/partmap/apple.c @@ -247,12 +247,12 @@ static struct grub_partition_map grub_apple_partition_map = .get_name = apple_partition_map_get_name }; -GRUB_MOD_INIT(apple_partition_map) +GRUB_MOD_INIT(part_apple) { grub_partition_map_register (&grub_apple_partition_map); } -GRUB_MOD_FINI(apple_partition_map) +GRUB_MOD_FINI(part_apple) { grub_partition_map_unregister (&grub_apple_partition_map); } diff --git a/partmap/gpt.c b/partmap/gpt.c index 4a4957437..46f3f0a37 100644 --- a/partmap/gpt.c +++ b/partmap/gpt.c @@ -182,12 +182,12 @@ static struct grub_partition_map grub_gpt_partition_map = .get_name = gpt_partition_map_get_name }; -GRUB_MOD_INIT(gpt_partition_map) +GRUB_MOD_INIT(part_gpt) { grub_partition_map_register (&grub_gpt_partition_map); } -GRUB_MOD_FINI(gpt_partition_map) +GRUB_MOD_FINI(part_gpt) { grub_partition_map_unregister (&grub_gpt_partition_map); } diff --git a/partmap/msdos.c b/partmap/msdos.c index 6ba7fb927..bae7ced9b 100644 --- a/partmap/msdos.c +++ b/partmap/msdos.c @@ -327,12 +327,12 @@ static struct grub_partition_map grub_msdos_partition_map = .get_name = pc_partition_map_get_name }; -GRUB_MOD_INIT(pc_partition_map) +GRUB_MOD_INIT(part_msdos) { grub_partition_map_register (&grub_msdos_partition_map); } -GRUB_MOD_FINI(pc_partition_map) +GRUB_MOD_FINI(part_msdos) { grub_partition_map_unregister (&grub_msdos_partition_map); } diff --git a/partmap/sun.c b/partmap/sun.c index e816ec17a..39cd29969 100644 --- a/partmap/sun.c +++ b/partmap/sun.c @@ -202,12 +202,12 @@ static struct grub_partition_map grub_sun_partition_map = .get_name = sun_partition_map_get_name }; -GRUB_MOD_INIT(sun_partition_map) +GRUB_MOD_INIT(part_sun) { grub_partition_map_register (&grub_sun_partition_map); } -GRUB_MOD_FINI(sun_partition_map) +GRUB_MOD_FINI(part_sun) { grub_partition_map_unregister (&grub_sun_partition_map); } diff --git a/parttool/msdospart.c b/parttool/msdospart.c index dbb25bc52..6ce48a977 100644 --- a/parttool/msdospart.c +++ b/parttool/msdospart.c @@ -138,7 +138,7 @@ static grub_err_t grub_pcpart_type (const grub_device_t dev, return GRUB_ERR_NONE; } -GRUB_MOD_INIT (pcpart) +GRUB_MOD_INIT (msdospart) { activate_table_handle = grub_parttool_register ("part_msdos", grub_pcpart_boot, @@ -148,7 +148,7 @@ GRUB_MOD_INIT (pcpart) grub_pcpart_typeargs); } -GRUB_MOD_FINI(pcpart) +GRUB_MOD_FINI(msdospart) { grub_parttool_unregister (activate_table_handle); grub_parttool_unregister (type_table_handle); diff --git a/term/gfxterm.c b/term/gfxterm.c index f161499e6..5c94a6b9a 100644 --- a/term/gfxterm.c +++ b/term/gfxterm.c @@ -251,7 +251,7 @@ static int NESTED_FUNC_ATTR video_hook (grub_video_adapter_t p __attribute__ ((u } static grub_err_t -grub_gfxterm_init (void) +grub_gfxterm_term_init (void) { char *font_name; char *modevar; @@ -312,7 +312,7 @@ grub_gfxterm_init (void) } static grub_err_t -grub_gfxterm_fini (void) +grub_gfxterm_term_fini (void) { if (bitmap) { @@ -932,8 +932,8 @@ grub_gfxterm_background_image_cmd (grub_command_t cmd __attribute__ ((unused)), static struct grub_term_output grub_video_term = { .name = "gfxterm", - .init = grub_gfxterm_init, - .fini = grub_gfxterm_fini, + .init = grub_gfxterm_term_init, + .fini = grub_gfxterm_term_fini, .putchar = grub_gfxterm_putchar, .getcharwidth = grub_gfxterm_getcharwidth, .getwh = grub_virtual_screen_getwh, @@ -951,7 +951,7 @@ static struct grub_term_output grub_video_term = static grub_command_t cmd; -GRUB_MOD_INIT(term_gfxterm) +GRUB_MOD_INIT(gfxterm) { grub_term_register_output ("gfxterm", &grub_video_term); cmd = grub_register_command ("background_image", @@ -959,7 +959,7 @@ GRUB_MOD_INIT(term_gfxterm) 0, "Load background image for active terminal"); } -GRUB_MOD_FINI(term_gfxterm) +GRUB_MOD_FINI(gfxterm) { grub_unregister_command (cmd); grub_term_unregister_output (&grub_video_term); diff --git a/util/grub-emu.c b/util/grub-emu.c index e65c8585e..b3117ab53 100644 --- a/util/grub-emu.c +++ b/util/grub-emu.c @@ -51,7 +51,7 @@ static char *prefix = NULL; grub_addr_t grub_arch_modules_addr (void) { - return NULL; + return 0; } grub_err_t @@ -106,10 +106,6 @@ grub_machine_fini (void) grub_console_fini (); } -void -read_command_list (void) -{ -} static struct option options[] = diff --git a/video/bitmap.c b/video/bitmap.c index 7b135a5dc..02ded85c6 100644 --- a/video/bitmap.c +++ b/video/bitmap.c @@ -243,11 +243,11 @@ void *grub_video_bitmap_get_data (struct grub_video_bitmap *bitmap) } /* Initialize bitmap module. */ -GRUB_MOD_INIT(video_bitmap) +GRUB_MOD_INIT(bitmap) { } /* Finalize bitmap module. */ -GRUB_MOD_FINI(video_bitmap) +GRUB_MOD_FINI(bitmap) { } diff --git a/video/readers/jpeg.c b/video/readers/jpeg.c index 460a52872..8b7398c39 100644 --- a/video/readers/jpeg.c +++ b/video/readers/jpeg.c @@ -725,7 +725,7 @@ static struct grub_video_bitmap_reader jpeg_reader = { .next = 0 }; -GRUB_MOD_INIT (video_reader_jpeg) +GRUB_MOD_INIT (jpeg) { grub_video_bitmap_reader_register (&jpg_reader); grub_video_bitmap_reader_register (&jpeg_reader); @@ -736,7 +736,7 @@ GRUB_MOD_INIT (video_reader_jpeg) #endif } -GRUB_MOD_FINI (video_reader_jpeg) +GRUB_MOD_FINI (jpeg) { #if defined(JPEG_DEBUG) grub_unregister_command ("jpegtest"); diff --git a/video/readers/png.c b/video/readers/png.c index c2008aeb2..7acce2145 100644 --- a/video/readers/png.c +++ b/video/readers/png.c @@ -890,7 +890,7 @@ static struct grub_video_bitmap_reader png_reader = { .next = 0 }; -GRUB_MOD_INIT (video_reader_png) +GRUB_MOD_INIT (png) { grub_video_bitmap_reader_register (&png_reader); #if defined(PNG_DEBUG) @@ -900,7 +900,7 @@ GRUB_MOD_INIT (video_reader_png) #endif } -GRUB_MOD_FINI (video_reader_png) +GRUB_MOD_FINI (png) { #if defined(PNG_DEBUG) grub_unregister_command ("pngtest"); diff --git a/video/readers/tga.c b/video/readers/tga.c index d0ca2770f..5f0a7f890 100644 --- a/video/readers/tga.c +++ b/video/readers/tga.c @@ -476,7 +476,7 @@ static struct grub_video_bitmap_reader tga_reader = { .next = 0 }; -GRUB_MOD_INIT(video_reader_tga) +GRUB_MOD_INIT(tga) { grub_video_bitmap_reader_register (&tga_reader); #if defined(TGA_DEBUG) @@ -485,7 +485,7 @@ GRUB_MOD_INIT(video_reader_tga) #endif } -GRUB_MOD_FINI(video_reader_tga) +GRUB_MOD_FINI(tga) { #if defined(TGA_DEBUG) grub_unregister_command ("tgatest"); diff --git a/video/video.c b/video/video.c index c1d66bdd0..5dcca7c7e 100644 --- a/video/video.c +++ b/video/video.c @@ -713,11 +713,11 @@ grub_video_set_mode (const char *modestring, } /* Initialize Video API module. */ -GRUB_MOD_INIT(video_video) +GRUB_MOD_INIT(video) { } /* Finalize Video API module. */ -GRUB_MOD_FINI(video_video) +GRUB_MOD_FINI(video) { } From 98e6959dead1c97d77e3b6dc8dc25cf1bd6cd173 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 7 Feb 2010 02:37:48 +0100 Subject: [PATCH 352/738] 2010-02-07 Vladimir Serbinenko Fix warnings in grub-emu when compiling with maximum warning options. * util/grub-emu.c (ENABLE_RELOCATABLE): New definition. (grub_arch_modules_addr): Return 0 and not NULL. * util/misc.c (ENABLE_RELOCATABLE): New definition. (xstrdup): USe newstr instead of dup. --- ChangeLog | 9 +++++++++ util/grub-emu.c | 3 ++- util/misc.c | 9 +++++---- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 46c96bdb2..33b0ea3bd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2010-02-07 Vladimir Serbinenko + + Fix warnings in grub-emu when compiling with maximum warning options. + + * util/grub-emu.c (ENABLE_RELOCATABLE): New definition. + (grub_arch_modules_addr): Return 0 and not NULL. + * util/misc.c (ENABLE_RELOCATABLE): New definition. + (xstrdup): USe newstr instead of dup. + 2010-02-07 Vladimir Serbinenko * loader/i386/linux.c (grub_linux_setup_video): Handle error diff --git a/util/grub-emu.c b/util/grub-emu.c index 21fc6fa09..554556ae8 100644 --- a/util/grub-emu.c +++ b/util/grub-emu.c @@ -40,6 +40,7 @@ #include +#define ENABLE_RELOCATABLE 0 #include "progname.h" /* Used for going back to the main function. */ @@ -51,7 +52,7 @@ static char *prefix = NULL; grub_addr_t grub_arch_modules_addr (void) { - return NULL; + return 0; } grub_err_t diff --git a/util/misc.c b/util/misc.c index 4e8eec323..8c79e8d9b 100644 --- a/util/misc.c +++ b/util/misc.c @@ -43,6 +43,7 @@ #include #include +#define ENABLE_RELOCATABLE 0 #include "progname.h" /* Include malloc.h, only if memalign is available. It is known that @@ -142,13 +143,13 @@ char * xstrdup (const char *str) { size_t len; - char *dup; + char *newstr; len = strlen (str); - dup = (char *) xmalloc (len + 1); - memcpy (dup, str, len + 1); + newstr = (char *) xmalloc (len + 1); + memcpy (newstr, str, len + 1); - return dup; + return newstr; } char * From f88d801b1733c5decb09cfcce3ead23455894fc7 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 7 Feb 2010 02:44:47 +0100 Subject: [PATCH 353/738] 2010-02-07 Vladimir Serbinenko Fix warnings in grub-emu when compiling with maximum warning options. * util/hostdisk.c (grub_util_biosdisk_get_grub_dev): Rename one instance of disk to dsk to avoid shadowing. --- ChangeLog | 2 ++ util/hostdisk.c | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 33b0ea3bd..4de8073ee 100644 --- a/ChangeLog +++ b/ChangeLog @@ -6,6 +6,8 @@ (grub_arch_modules_addr): Return 0 and not NULL. * util/misc.c (ENABLE_RELOCATABLE): New definition. (xstrdup): USe newstr instead of dup. + * util/hostdisk.c (grub_util_biosdisk_get_grub_dev): Rename one instance + of disk to dsk to avoid shadowing. 2010-02-07 Vladimir Serbinenko diff --git a/util/hostdisk.c b/util/hostdisk.c index 5c56b7579..9a3f30ce0 100644 --- a/util/hostdisk.c +++ b/util/hostdisk.c @@ -981,10 +981,10 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) struct hd_geometry hdg; int dos_part = -1; int bsd_part = -1; - auto int find_partition (grub_disk_t disk, + auto int find_partition (grub_disk_t dsk, const grub_partition_t partition); - int find_partition (grub_disk_t disk __attribute__ ((unused)), + int find_partition (grub_disk_t dsk __attribute__ ((unused)), const grub_partition_t partition) { struct grub_msdos_partition *pcdata = NULL; From 74e4934e1c8147e622a843a7ca7a3b7c98a0783e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 7 Feb 2010 02:47:18 +0100 Subject: [PATCH 354/738] 2010-02-07 Vladimir Serbinenko * util/hostdisk.c (grub_util_biosdisk_get_grub_dev): Rename one instance of disk to dsk to avoid shadowing. (find_free_slot): Fix prototype. * util/getroot.c (grub_util_is_dmraid): Make static. * include/grub/time.h (grub_get_rtc) [GRUB_MACHINE_EMU || GRUB_UTIL]: Add missing prototype. * util/sdl.c (grub_video_sdl_set_viewport): Remove. --- ChangeLog | 7 ++++++- include/grub/time.h | 2 ++ util/getroot.c | 3 ++- util/hostdisk.c | 2 +- util/sdl.c | 26 -------------------------- 5 files changed, 11 insertions(+), 29 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4de8073ee..ec3318c5b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -5,9 +5,14 @@ * util/grub-emu.c (ENABLE_RELOCATABLE): New definition. (grub_arch_modules_addr): Return 0 and not NULL. * util/misc.c (ENABLE_RELOCATABLE): New definition. - (xstrdup): USe newstr instead of dup. + (xstrdup): Use newstr instead of dup. * util/hostdisk.c (grub_util_biosdisk_get_grub_dev): Rename one instance of disk to dsk to avoid shadowing. + (find_free_slot): Fix prototype. + * util/getroot.c (grub_util_is_dmraid): Make static. + * include/grub/time.h (grub_get_rtc) [GRUB_MACHINE_EMU || GRUB_UTIL]: + Add missing prototype. + * util/sdl.c (grub_video_sdl_set_viewport): Remove. 2010-02-07 Vladimir Serbinenko diff --git a/include/grub/time.h b/include/grub/time.h index 5aafdc9ed..ae2617edb 100644 --- a/include/grub/time.h +++ b/include/grub/time.h @@ -25,6 +25,8 @@ #if defined (GRUB_MACHINE_EMU) || defined (GRUB_UTIL) #define GRUB_TICKS_PER_SECOND 100000 +/* Return the real time in ticks. */ +grub_uint32_t EXPORT_FUNC (grub_get_rtc) (void); #else #include #endif diff --git a/util/getroot.c b/util/getroot.c index 6357c8a26..82393635c 100644 --- a/util/getroot.c +++ b/util/getroot.c @@ -460,7 +460,8 @@ grub_guess_root_device (const char *dir) return os_dev; } -int + +static int grub_util_is_dmraid (const char *os_dev) { if (! strncmp (os_dev, "/dev/mapper/nvidia_", 19)) diff --git a/util/hostdisk.c b/util/hostdisk.c index 9a3f30ce0..98d3d53ae 100644 --- a/util/hostdisk.c +++ b/util/hostdisk.c @@ -137,7 +137,7 @@ find_grub_drive (const char *name) } static int -find_free_slot () +find_free_slot (void) { unsigned int i; diff --git a/util/sdl.c b/util/sdl.c index a5a310518..d261db6b0 100644 --- a/util/sdl.c +++ b/util/sdl.c @@ -179,32 +179,6 @@ grub_video_sdl_set_palette (unsigned int start, unsigned int count, return grub_video_fb_set_palette (start, count, palette_data); } -grub_err_t -grub_video_sdl_set_viewport (unsigned int x, unsigned int y, - unsigned int width, unsigned int height) -{ - /* Make sure viewport is withing screen dimensions. If viewport was set - to be out of the region, mark its size as zero. */ - if (x > (unsigned) window->w) - { - x = 0; - width = 0; - } - - if (y > (unsigned) window->h) - { - y = 0; - height = 0; - } - - if (x + width > (unsigned) window->w) - width = window->w - x; - - if (y + height > (unsigned) window->h) - height = window->h - y; - return grub_video_fb_set_viewport (x, y, width, height); -} - static grub_err_t grub_video_sdl_swap_buffers (void) { From dcb3f497be11f052e794385fed50b1d8367c5fb0 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 7 Feb 2010 03:29:59 +0100 Subject: [PATCH 355/738] Rename main.mod to kernel.img --- conf/any-emu.rmk | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/conf/any-emu.rmk b/conf/any-emu.rmk index 2fc8daf45..ebcc9087c 100644 --- a/conf/any-emu.rmk +++ b/conf/any-emu.rmk @@ -8,8 +8,9 @@ script/lexer.c_DEPENDENCIES = grub_script.tab.h #sbin_UTILITIES += grub-emu util/grub-emu.c_DEPENDENCIES = grub_emu_init.h -pkglib_MODULES += main.mod -main_mod_SOURCES = kern/device.c kern/disk.c kern/dl.c kern/env.c \ +kernel_img_RELOCATABLE = yes +pkglib_PROGRAMS = kernel.img +kernel_img_SOURCES = kern/device.c kern/disk.c kern/dl.c kern/env.c \ kern/err.c kern/list.c kern/handler.c \ kern/command.c kern/corecmd.c kern/file.c \ kern/fs.c commands/boot.c kern/main.c kern/misc.c kern/parser.c \ @@ -20,8 +21,8 @@ main_mod_SOURCES = kern/device.c kern/disk.c kern/dl.c kern/env.c \ util/hostdisk.c util/getroot.c \ \ grub_emu_init.c gnulib/progname.c -main_mod_CFLAGS = $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 -main_mod_LDFLAGS = $(COMMON_LDFLAGS) +kernel_img_CFLAGS = $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 +kernel_img_LDFLAGS = $(COMMON_LDFLAGS) # For hostfs.mod. pkglib_MODULES += hostfs.mod @@ -85,11 +86,11 @@ grub_emu_init.h: genemuinitheader.sh DISTCLEANFILES += grub_emu_init.h grub_emu_init.c: genemuinit.sh - rm -f $@; echo $(pkglib_MODULES) |sed 's,elf.mod,,;s,extcmd.mod,,;s,main.mod,,;s,gzio.mod,,;s,fshelp.mod,,;s,bufio.mod,,;s,setjmp.mod,,;s,crypto.mod,,;s,pbkdf2.mod,,;s,trig.mod,,;s,bitmap_scale.mod,,;s,charset.mod,,;'|sh $(srcdir)/genemuinit.sh > $@ + rm -f $@; echo $(pkglib_MODULES) |sed 's,elf.mod,,;s,extcmd.mod,,;s,gzio.mod,,;s,fshelp.mod,,;s,bufio.mod,,;s,setjmp.mod,,;s,crypto.mod,,;s,pbkdf2.mod,,;s,trig.mod,,;s,bitmap_scale.mod,,;s,charset.mod,,;'|sh $(srcdir)/genemuinit.sh > $@ DISTCLEANFILES += grub_emu_init.c include $(srcdir)/conf/common.mk -grub-emu: $(pkglib_MODULES) - $(CC) -o $@ $(pkglib_MODULES) $(grub_emu_LDFLAGS) $(LDFLAGS) +grub-emu: $(pkglib_MODULES) $(pkglib_PROGRAMS) + $(CC) -o $@ $(pkglib_MODULES) $(pkglib_PROGRAMS) $(grub_emu_LDFLAGS) $(LDFLAGS) From c5160d75c4efaa62f8d57f180c6d544b44096ca1 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 7 Feb 2010 03:43:07 +0100 Subject: [PATCH 356/738] Don't strip on any-emu --- conf/any-emu.rmk | 1 + genmk.rb | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/conf/any-emu.rmk b/conf/any-emu.rmk index ebcc9087c..983dc2c1f 100644 --- a/conf/any-emu.rmk +++ b/conf/any-emu.rmk @@ -23,6 +23,7 @@ kernel_img_SOURCES = kern/device.c kern/disk.c kern/dl.c kern/env.c \ grub_emu_init.c gnulib/progname.c kernel_img_CFLAGS = $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 kernel_img_LDFLAGS = $(COMMON_LDFLAGS) +TARGET_NO_STRIP = yes # For hostfs.mod. pkglib_MODULES += hostfs.mod diff --git a/genmk.rb b/genmk.rb index df03e1dfe..65bcb3ddd 100644 --- a/genmk.rb +++ b/genmk.rb @@ -148,7 +148,7 @@ ifneq ($(TARGET_APPLE_CC),1) -rm -f $@ $(TARGET_CC) $(#{prefix}_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ #{pre_obj} #{mod_obj} if test ! -z \"$(TARGET_OBJ2ELF)\"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi - $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@ + if test x$(TARGET_NO_STRIP) != xyes ; then $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@; fi else #{@name}: #{pre_obj} #{mod_obj} $(TARGET_OBJ2ELF) -rm -f $@ @@ -330,11 +330,11 @@ MOSTLYCLEANFILES += #{deps_str} ifeq ($(#{prefix}_RELOCATABLE),yes) #{@name}: $(#{prefix}_DEPENDENCIES) #{objs_str} $(TARGET_CC) -Wl,-r,-d -o $@ #{objs_str} $(TARGET_LDFLAGS) $(#{prefix}_LDFLAGS) - $(STRIP) --strip-unneeded -K start -R .note -R .comment $@ + if test x$(TARGET_NO_STRIP) != xyes ; then $(STRIP) --strip-unneeded -K start -R .note -R .comment $@; fi else #{@name}: $(#{prefix}_DEPENDENCIES) #{objs_str} $(TARGET_CC) -o $@ #{objs_str} $(TARGET_LDFLAGS) $(#{prefix}_LDFLAGS) - $(STRIP) -R .rel.dyn -R .reginfo -R .note -R .comment $@ + if test x$(TARGET_NO_STRIP) != xyes ; then $(STRIP) -R .rel.dyn -R .reginfo -R .note -R .comment $@; fi endif " + objs.collect_with_index do |obj, i| From ebe841ad55b15f9920675b567c02bb6661e5bd18 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 7 Feb 2010 03:48:38 +0100 Subject: [PATCH 357/738] Don't try to generate moddep.lst on any-emu.rmk --- conf/any-emu.rmk | 1 + genmk.rb | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/conf/any-emu.rmk b/conf/any-emu.rmk index 983dc2c1f..7ed5fa74b 100644 --- a/conf/any-emu.rmk +++ b/conf/any-emu.rmk @@ -24,6 +24,7 @@ kernel_img_SOURCES = kern/device.c kern/disk.c kern/dl.c kern/env.c \ kernel_img_CFLAGS = $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 kernel_img_LDFLAGS = $(COMMON_LDFLAGS) TARGET_NO_STRIP = yes +TARGET_NO_DYNAMIC_MODULES = yes # For hostfs.mod. pkglib_MODULES += hostfs.mod diff --git a/genmk.rb b/genmk.rb index 65bcb3ddd..7df15043a 100644 --- a/genmk.rb +++ b/genmk.rb @@ -143,6 +143,13 @@ mostlyclean-module-#{@name}.#{@rule_count}: MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-#{@name}.#{@rule_count} UNDSYMFILES += #{undsym} +ifeq ($(TARGET_NO_DYNAMIC_MODULES), yes) +#{@name}: #{pre_obj} $(TARGET_OBJ2ELF) + -rm -f $@ + $(TARGET_CC) $(#{prefix}_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ #{pre_obj} + if test ! -z \"$(TARGET_OBJ2ELF)\"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi + if test x$(TARGET_NO_STRIP) != xyes ; then $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@; fi +else ifneq ($(TARGET_APPLE_CC),1) #{@name}: #{pre_obj} #{mod_obj} $(TARGET_OBJ2ELF) -rm -f $@ @@ -157,6 +164,7 @@ else $(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@ -rm -f $@.bin endif +endif #{pre_obj}: $(#{prefix}_DEPENDENCIES) #{objs_str} -rm -f $@ From 285505d3fc59db1fc760e1d459809c7d282ac309 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 7 Feb 2010 03:58:14 +0100 Subject: [PATCH 358/738] Eliminate blacklist of modules w/o init --- conf/any-emu.rmk | 6 +++--- genemuinit.sh | 10 +++++++--- genemuinitheader.sh | 10 +++++++--- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/conf/any-emu.rmk b/conf/any-emu.rmk index 7ed5fa74b..3e92cbe73 100644 --- a/conf/any-emu.rmk +++ b/conf/any-emu.rmk @@ -84,11 +84,11 @@ endif grub_emu_init.h: genemuinitheader.sh - rm -f $@; echo $(pkglib_MODULES) |sh $(srcdir)/genemuinitheader.sh > $@ + rm -f $@; echo $(pkglib_MODULES) | sh $(srcdir)/genemuinitheader.sh $(NM) > $@ DISTCLEANFILES += grub_emu_init.h -grub_emu_init.c: genemuinit.sh - rm -f $@; echo $(pkglib_MODULES) |sed 's,elf.mod,,;s,extcmd.mod,,;s,gzio.mod,,;s,fshelp.mod,,;s,bufio.mod,,;s,setjmp.mod,,;s,crypto.mod,,;s,pbkdf2.mod,,;s,trig.mod,,;s,bitmap_scale.mod,,;s,charset.mod,,;'|sh $(srcdir)/genemuinit.sh > $@ +grub_emu_init.c: genemuinit.sh $(pkglib_MODULES) + rm -f $@; echo $(pkglib_MODULES) | sh $(srcdir)/genemuinit.sh $(NM) > $@ DISTCLEANFILES += grub_emu_init.c include $(srcdir)/conf/common.mk diff --git a/genemuinit.sh b/genemuinit.sh index e40a683af..45c15ecb9 100644 --- a/genemuinit.sh +++ b/genemuinit.sh @@ -11,7 +11,7 @@ # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. -lst="$1" +nm="$1" shift cat < /dev/null; then + echo "grub_${line}_init ();" | sed 's,\.mod,,g;' + fi done cat < /dev/null; then + echo "grub_${line}_fini ();" | sed 's,\.mod,,g;' + fi done cat < /dev/null; then + echo "void grub_${line}_init (void);" | sed 's,\.mod,,g;' + fi + if ${nm} --defined-only -P -p ${line} | grep grub_mod_fini > /dev/null; then + echo "void grub_${line}_fini (void);" | sed 's,\.mod,,g;' + fi done From 1eebb21608647883706de5fe9022652eed5a7e01 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 7 Feb 2010 04:01:22 +0100 Subject: [PATCH 359/738] Add missing dependency --- conf/any-emu.rmk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/any-emu.rmk b/conf/any-emu.rmk index 3e92cbe73..542cd9bd1 100644 --- a/conf/any-emu.rmk +++ b/conf/any-emu.rmk @@ -83,7 +83,7 @@ grub_emu_LDFLAGS += $(LIBPCIACCESS) endif -grub_emu_init.h: genemuinitheader.sh +grub_emu_init.h: genemuinitheader.sh $(pkglib_MODULES) rm -f $@; echo $(pkglib_MODULES) | sh $(srcdir)/genemuinitheader.sh $(NM) > $@ DISTCLEANFILES += grub_emu_init.h From 2083672af13f98a2efcd467b1a818eff5669b942 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 7 Feb 2010 04:23:44 +0100 Subject: [PATCH 360/738] Remove -DGRUB_UTIL when compiling grub-emu --- commands/parttool.c | 2 +- conf/any-emu.rmk | 4 +-- efiemu/main.c | 4 +-- efiemu/mm.c | 4 +-- include/grub/dl.h | 9 +++-- include/grub/mm.h | 2 +- include/grub/multiboot2.h | 70 --------------------------------------- include/grub/normal.h | 33 ------------------ include/grub/partition.h | 14 -------- include/grub/pci.h | 2 +- kern/dl.c | 2 +- loader/xnu.c | 6 ++-- util/grub-emu.c | 2 -- util/misc.c | 4 +++ 14 files changed, 24 insertions(+), 134 deletions(-) delete mode 100644 include/grub/multiboot2.h diff --git a/commands/parttool.c b/commands/parttool.c index 5ad6133ca..0850c5e1d 100644 --- a/commands/parttool.c +++ b/commands/parttool.c @@ -175,7 +175,7 @@ grub_cmd_parttool (grub_command_t cmd __attribute__ ((unused)), } /* Load modules. */ -#ifndef GRUB_UTIL +#if GRUB_NO_MODULES { const char *prefix; prefix = grub_env_get ("prefix"); diff --git a/conf/any-emu.rmk b/conf/any-emu.rmk index 542cd9bd1..0f717c59c 100644 --- a/conf/any-emu.rmk +++ b/conf/any-emu.rmk @@ -1,7 +1,7 @@ # -*- makefile -*- COMMON_LDFLAGS += -nostdlib -COMMON_CFLAGS += -DGRUB_UTIL=1 +COMMON_CFLAGS += # Used by various components. These rules need to precede them. script/lexer.c_DEPENDENCIES = grub_script.tab.h @@ -21,7 +21,7 @@ kernel_img_SOURCES = kern/device.c kern/disk.c kern/dl.c kern/env.c \ util/hostdisk.c util/getroot.c \ \ grub_emu_init.c gnulib/progname.c -kernel_img_CFLAGS = $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 +kernel_img_CFLAGS = $(CPPFLAGS) $(CFLAGS) kernel_img_LDFLAGS = $(COMMON_LDFLAGS) TARGET_NO_STRIP = yes TARGET_NO_DYNAMIC_MODULES = yes diff --git a/efiemu/main.c b/efiemu/main.c index 9480bfc4d..8a8a508fa 100644 --- a/efiemu/main.c +++ b/efiemu/main.c @@ -265,7 +265,7 @@ grub_efiemu_autocore (void) grub_free (filename); if (err) return err; -#ifndef GRUB_UTIL +#ifndef GRUB_MACHINE_EMU err = grub_machine_efiemu_init_tables (); if (err) return err; @@ -313,7 +313,7 @@ grub_cmd_efiemu_load (grub_command_t cmd __attribute__ ((unused)), err = grub_efiemu_load_file (args[0]); if (err) return err; -#ifndef GRUB_UTIL +#ifndef GRUB_MACHINE_EMU err = grub_machine_efiemu_init_tables (); if (err) return err; diff --git a/efiemu/mm.c b/efiemu/mm.c index 6099a14ee..4b293606f 100644 --- a/efiemu/mm.c +++ b/efiemu/mm.c @@ -281,7 +281,7 @@ grub_efiemu_mmap_init (void) // the place for memory used by efiemu itself mmap_reserved_size = GRUB_EFI_MAX_MEMORY_TYPE + 1; -#ifndef GRUB_UTIL +#ifndef GRUB_MACHINE_EMU grub_machine_mmap_iterate (bounds_hook); #endif @@ -394,7 +394,7 @@ grub_efiemu_mmap_fill (void) } } -#ifndef GRUB_UTIL +#ifndef GRUB_MACHINE_EMU grub_machine_mmap_iterate (fill_hook); #endif diff --git a/include/grub/dl.h b/include/grub/dl.h index ac0ecd336..17e03f400 100644 --- a/include/grub/dl.h +++ b/include/grub/dl.h @@ -91,7 +91,12 @@ grub_dl_t grub_dl_load_core (void *addr, grub_size_t size); int EXPORT_FUNC(grub_dl_unload) (grub_dl_t mod); void grub_dl_unload_unneeded (void); void grub_dl_unload_all (void); -#ifdef GRUB_UTIL +#if defined (GRUB_MACHINE_EMU) || defined (GRUB_UTIL) +#define GRUB_NO_MODULES 1 +#else +#define GRUB_NO_MODULES 0 +#endif +#if GRUB_NO_MODULES static inline int grub_dl_ref (grub_dl_t mod) { @@ -116,7 +121,7 @@ grub_err_t grub_dl_register_symbol (const char *name, void *addr, grub_err_t grub_arch_dl_check_header (void *ehdr); grub_err_t grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr); -#if defined (_mips) && ! defined (GRUB_UTIL) +#if defined (_mips) && ! defined (GRUB_UTIL) && !defined (GRUB_MACHINE_EMU) #define GRUB_LINKER_HAVE_INIT 1 void grub_arch_dl_init_linker (void); #endif diff --git a/include/grub/mm.h b/include/grub/mm.h index 4caf80511..4f443ee25 100644 --- a/include/grub/mm.h +++ b/include/grub/mm.h @@ -36,7 +36,7 @@ void *EXPORT_FUNC(grub_realloc) (void *ptr, grub_size_t size); void *EXPORT_FUNC(grub_memalign) (grub_size_t align, grub_size_t size); /* For debugging. */ -#if defined(MM_DEBUG) && !defined(GRUB_UTIL) +#if defined(MM_DEBUG) && !defined(GRUB_UTIL) && !defined (GRUB_MACHINE_EMU) /* Set this variable to 1 when you want to trace all memory function calls. */ extern int EXPORT_VAR(grub_mm_debug); diff --git a/include/grub/multiboot2.h b/include/grub/multiboot2.h deleted file mode 100644 index af10cdc21..000000000 --- a/include/grub/multiboot2.h +++ /dev/null @@ -1,70 +0,0 @@ -/* multiboot2.h - multiboot2 header file with grub definitions. */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2005,2007 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_MULTIBOOT2_HEADER -#define GRUB_MULTIBOOT2_HEADER 1 - -#include -#include -#include - -#ifndef GRUB_UTIL -typedef grub_uint32_t uint32_t; -typedef grub_uint64_t uint64_t; -#define __WORDSIZE GRUB_TARGET_WORDSIZE -#endif - -struct multiboot2_tag_header; - -grub_err_t -grub_mb2_tag_alloc (grub_addr_t *addr, int key, grub_size_t len); - -grub_err_t -grub_mb2_tags_arch_create (void); - -void -grub_mb2_arch_boot (grub_addr_t entry, void *tags); - -void -grub_mb2_arch_unload (struct multiboot2_tag_header *tags); - -grub_err_t -grub_mb2_arch_elf32_hook (Elf32_Phdr *phdr, grub_addr_t *addr, int *do_load); - -grub_err_t -grub_mb2_arch_elf64_hook (Elf64_Phdr *phdr, grub_addr_t *addr, int *do_load); - -grub_err_t -grub_mb2_arch_module_alloc (grub_size_t size, grub_addr_t *addr); - -grub_err_t -grub_mb2_arch_module_free (grub_addr_t addr, grub_size_t size); - -void -grub_multiboot2 (int argc, char *argv[]); - -void -grub_module2 (int argc, char *argv[]); - -#define for_each_tag(tag, tags) \ - for (tag = tags; \ - tag && tag->key != MULTIBOOT2_TAG_END; \ - tag = (struct multiboot2_tag_header *)((char *)tag + tag->len)) - -#endif /* ! GRUB_MULTIBOOT2_HEADER */ diff --git a/include/grub/normal.h b/include/grub/normal.h index e804fde77..fad1a41ba 100644 --- a/include/grub/normal.h +++ b/include/grub/normal.h @@ -110,37 +110,4 @@ void read_terminal_list (void); void grub_set_more (int onoff); -#ifdef GRUB_UTIL -void grub_normal_init (void); -void grub_normal_fini (void); -void grub_hello_init (void); -void grub_hello_fini (void); -void grub_ls_init (void); -void grub_ls_fini (void); -void grub_cat_init (void); -void grub_cat_fini (void); -void grub_boot_init (void); -void grub_boot_fini (void); -void grub_cmp_init (void); -void grub_cmp_fini (void); -void grub_terminal_init (void); -void grub_terminal_fini (void); -void grub_loop_init (void); -void grub_loop_fini (void); -void grub_help_init (void); -void grub_help_fini (void); -void grub_halt_init (void); -void grub_halt_fini (void); -void grub_reboot_init (void); -void grub_reboot_fini (void); -void grub_configfile_init (void); -void grub_configfile_fini (void); -void grub_search_init (void); -void grub_search_fini (void); -void grub_test_init (void); -void grub_test_fini (void); -void grub_blocklist_init (void); -void grub_blocklist_fini (void); -#endif - #endif /* ! GRUB_NORMAL_HEADER */ diff --git a/include/grub/partition.h b/include/grub/partition.h index d35658cdd..faa89cea6 100644 --- a/include/grub/partition.h +++ b/include/grub/partition.h @@ -83,20 +83,6 @@ void EXPORT_FUNC(grub_partition_map_register) (grub_partition_map_t partmap); void EXPORT_FUNC(grub_partition_map_unregister) (grub_partition_map_t partmap); -#ifdef GRUB_UTIL -void grub_msdos_partition_map_init (void); -void grub_msdos_partition_map_fini (void); -void grub_amiga_partition_map_init (void); -void grub_amiga_partition_map_fini (void); -void grub_apple_partition_map_init (void); -void grub_apple_partition_map_fini (void); -void grub_sun_partition_map_init (void); -void grub_sun_partition_map_fini (void); -void grub_gpt_partition_map_init (void); -void grub_gpt_partition_map_fini (void); -void grub_apple_partition_map_init (void); -void grub_apple_partition_map_fini (void); -#endif static inline grub_disk_addr_t grub_partition_get_start (const grub_partition_t p) diff --git a/include/grub/pci.h b/include/grub/pci.h index 1f3ac7fc7..89bd1034a 100644 --- a/include/grub/pci.h +++ b/include/grub/pci.h @@ -68,7 +68,7 @@ typedef grub_uint32_t grub_pci_id_t; -#ifdef GRUB_UTIL +#ifdef GRUB_MACHINE_EMU #include #else typedef grub_uint32_t grub_pci_address_t; diff --git a/kern/dl.c b/kern/dl.c index 4735a004a..278d5b568 100644 --- a/kern/dl.c +++ b/kern/dl.c @@ -469,7 +469,7 @@ grub_dl_resolve_dependencies (grub_dl_t mod, Elf_Ehdr *e) return GRUB_ERR_NONE; } -#ifndef GRUB_UTIL +#if !GRUB_NO_MODULES int grub_dl_ref (grub_dl_t mod) { diff --git a/loader/xnu.c b/loader/xnu.c index cf9fa740b..8f1d0c641 100644 --- a/loader/xnu.c +++ b/loader/xnu.c @@ -1390,7 +1390,7 @@ grub_cmd_xnu_splash (grub_extcmd_t cmd, } -#ifndef GRUB_UTIL +#ifndef GRUB_MACHINE_EMU static grub_err_t grub_cmd_xnu_resume (grub_command_t cmd __attribute__ ((unused)), int argc, char *args[]) @@ -1444,7 +1444,7 @@ GRUB_MOD_INIT(xnu) N_("Load a splash image for XNU."), xnu_splash_cmd_options); -#ifndef GRUB_UTIL +#ifndef GRUB_MACHINE_EMU cmd_resume = grub_register_command ("xnu_resume", grub_cmd_xnu_resume, 0, N_("Load XNU hibernate image.")); #endif @@ -1456,7 +1456,7 @@ GRUB_MOD_INIT(xnu) GRUB_MOD_FINI(xnu) { -#ifndef GRUB_UTIL +#ifndef GRUB_MACHINE_EMU grub_unregister_command (cmd_resume); #endif grub_unregister_command (cmd_mkext); diff --git a/util/grub-emu.c b/util/grub-emu.c index f64e66c5f..08ae19836 100644 --- a/util/grub-emu.c +++ b/util/grub-emu.c @@ -157,8 +157,6 @@ main (int argc, char *argv[]) set_program_name (argv[0]); - grub_util_init_nls (); - while ((opt = getopt_long (argc, argv, "r:d:m:vH:hV", options, 0)) != -1) switch (opt) { diff --git a/util/misc.c b/util/misc.c index 8c79e8d9b..7381c8fdd 100644 --- a/util/misc.c +++ b/util/misc.c @@ -104,6 +104,7 @@ grub_util_error (const char *fmt, ...) exit (1); } +#ifdef GRUB_UTIL int grub_err_printf (const char *fmt, ...) { @@ -116,6 +117,7 @@ grub_err_printf (const char *fmt, ...) return ret; } +#endif void * xmalloc (size_t size) @@ -598,6 +600,7 @@ make_system_path_relative_to_its_root (const char *path) return buf3; } +#ifdef GRUB_UTIL void grub_util_init_nls (void) { @@ -607,3 +610,4 @@ grub_util_init_nls (void) textdomain (PACKAGE); #endif /* ENABLE_NLS */ } +#endif From 19987ffa0249acd32cb76eff5e4aeef33f3a1076 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 7 Feb 2010 04:45:54 +0100 Subject: [PATCH 361/738] Remove the need for explicit make grub-emu --- Makefile.in | 11 +++++++---- conf/any-emu.rmk | 5 +++-- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/Makefile.in b/Makefile.in index 853eea9db..e69c18b40 100644 --- a/Makefile.in +++ b/Makefile.in @@ -178,7 +178,10 @@ endif ### General targets. CLEANFILES += $(pkglib_DATA) $(pkgdata_DATA) po/*.mo -pkglib_DATA += moddep.lst command.lst fs.lst partmap.lst parttool.lst handler.lst video.lst crypto.lst terminal.lst +pkglib_DATA += command.lst fs.lst partmap.lst parttool.lst handler.lst video.lst crypto.lst terminal.lst +ifneq ($(platform), emu) +pkglib_DATA += moddep.lst +endif moddep.lst: $(DEFSYMFILES) $(UNDSYMFILES) genmoddep.awk cat $(DEFSYMFILES) /dev/null \ | $(AWK) -f $(srcdir)/genmoddep.awk $(UNDSYMFILES) > $@ \ @@ -278,7 +281,7 @@ build_env.mk: Makefile ) > $@ pkglib_BUILDDIR += config.h grub_script.tab.h -all-local: $(PROGRAMS) $(PKGLIB) $(PKGDATA) $(SCRIPTS) $(INFOS) $(MKFILES) $(foreach lang, $(LINGUAS), po/$(lang).mo) +all-local: $(PROGRAMS) $(GRUB_EMU) $(PKGLIB) $(PKGDATA) $(SCRIPTS) $(INFOS) $(MKFILES) $(foreach lang, $(LINGUAS), po/$(lang).mo) install: install-local @@ -299,7 +302,7 @@ install-local: all $(INSTALL_DATA) $$dir$$file $(DESTDIR)$(pkgdatadir)/$$dest; \ done $(SHELL) $(mkinstalldirs) $(DESTDIR)$(bindir) $(DESTDIR)$(mandir)/man1 - @list='$(bin_UTILITIES)'; for file in $$list; do \ + @list='$(bin_UTILITIES) $(GRUB_EMU)'; for file in $$list; do \ if test -f "$$file"; then dir=; else dir="$(srcdir)/"; fi; \ dest="`echo $$file | sed 's,.*/,,' | sed '$(transform)'`"; \ $(INSTALL_PROGRAM) $$dir$$file $(DESTDIR)$(bindir)/$$dest; \ @@ -375,7 +378,7 @@ uninstall: dest="`echo $$file | sed 's,.*/,,'`"; \ rm -f $(DESTDIR)$(pkgdatadir)/$$dest; \ done - @list='$(bin_UTILITIES) $(bin_SCRIPTS)'; for file in $$list; do \ + @list='$(bin_UTILITIES) $(bin_SCRIPTS) $(GRUB_EMU)'; for file in $$list; do \ dest="`echo $$file | sed 's,.*/,,' | sed '$(transform)'`"; \ rm -f $(DESTDIR)$(bindir)/$$dest; \ rm -f $(DESTDIR)$(mandir)/man1/$$dest.1; \ diff --git a/conf/any-emu.rmk b/conf/any-emu.rmk index 0f717c59c..7e9e34920 100644 --- a/conf/any-emu.rmk +++ b/conf/any-emu.rmk @@ -82,6 +82,7 @@ pci_mod_LDFLAGS = $(COMMON_LDFLAGS) grub_emu_LDFLAGS += $(LIBPCIACCESS) endif +include $(srcdir)/conf/common.mk grub_emu_init.h: genemuinitheader.sh $(pkglib_MODULES) rm -f $@; echo $(pkglib_MODULES) | sh $(srcdir)/genemuinitheader.sh $(NM) > $@ @@ -91,8 +92,8 @@ grub_emu_init.c: genemuinit.sh $(pkglib_MODULES) rm -f $@; echo $(pkglib_MODULES) | sh $(srcdir)/genemuinit.sh $(NM) > $@ DISTCLEANFILES += grub_emu_init.c -include $(srcdir)/conf/common.mk - +CLEANFILES += grub-emu grub-emu: $(pkglib_MODULES) $(pkglib_PROGRAMS) $(CC) -o $@ $(pkglib_MODULES) $(pkglib_PROGRAMS) $(grub_emu_LDFLAGS) $(LDFLAGS) +GRUB_EMU=grub-emu From ceb294b7eef0d0bd14376e9f2bfb32f909975771 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 7 Feb 2010 04:47:46 +0100 Subject: [PATCH 362/738] Don't create useless .lst --- Makefile.in | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Makefile.in b/Makefile.in index e69c18b40..820bfa946 100644 --- a/Makefile.in +++ b/Makefile.in @@ -178,9 +178,8 @@ endif ### General targets. CLEANFILES += $(pkglib_DATA) $(pkgdata_DATA) po/*.mo -pkglib_DATA += command.lst fs.lst partmap.lst parttool.lst handler.lst video.lst crypto.lst terminal.lst ifneq ($(platform), emu) -pkglib_DATA += moddep.lst +pkglib_DATA += moddep.lst command.lst fs.lst partmap.lst parttool.lst handler.lst video.lst crypto.lst terminal.lst endif moddep.lst: $(DEFSYMFILES) $(UNDSYMFILES) genmoddep.awk cat $(DEFSYMFILES) /dev/null \ From c3e6233987018f036f54c92f0e303db57a364529 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 7 Feb 2010 04:50:30 +0100 Subject: [PATCH 363/738] REmove the need for disable-werror --- conf/any-emu.rmk | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/conf/any-emu.rmk b/conf/any-emu.rmk index 7e9e34920..77092454b 100644 --- a/conf/any-emu.rmk +++ b/conf/any-emu.rmk @@ -20,12 +20,18 @@ kernel_img_SOURCES = kern/device.c kern/disk.c kern/dl.c kern/env.c \ util/console.c util/grub-emu.c util/misc.c \ util/hostdisk.c util/getroot.c \ \ - grub_emu_init.c gnulib/progname.c + grub_emu_init.c kernel_img_CFLAGS = $(CPPFLAGS) $(CFLAGS) kernel_img_LDFLAGS = $(COMMON_LDFLAGS) TARGET_NO_STRIP = yes TARGET_NO_DYNAMIC_MODULES = yes +# progname.c always has warnings. Compile it separately. +pkglib_MODULES += progname.mod +progname_mod_SOURCES = gnulib/progname.c +progname_mod_CFLAGS = $(COMMON_CFLAGS) -Wno-error +progname_mod_LDFLAGS = $(COMMON_LDFLAGS) + # For hostfs.mod. pkglib_MODULES += hostfs.mod hostfs_mod_SOURCES = util/hostfs.c From f38873b80b1c55d0f8020500adf3351589294365 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 7 Feb 2010 15:17:26 +0100 Subject: [PATCH 364/738] Build system support for grub-emu modules --- Makefile.in | 8 +++++++- conf/any-emu.rmk | 46 ++++++++++++++++++++++++++++++++-------------- configure.ac | 16 ++++++++++++++++ genmk.rb | 34 ++++++++++++++++++++-------------- genmoddep.awk | 4 ++-- include/grub/dl.h | 4 ++-- include/grub/sdl.h | 24 ++++++++++++++++++++++++ util/grub-emu.c | 9 +++++++++ util/misc.c | 2 ++ 9 files changed, 114 insertions(+), 33 deletions(-) create mode 100644 include/grub/sdl.h diff --git a/Makefile.in b/Makefile.in index 820bfa946..8eaf17a7a 100644 --- a/Makefile.in +++ b/Makefile.in @@ -43,6 +43,7 @@ pkglibdir = $(libdir)/`echo @PACKAGE_TARNAME@/$(target_cpu)-$(platform) | sed ' # Internationalization library. LIBINTL = @LIBINTL@ +TARGET_NO_MODULES = @TARGET_NO_MODULES@ XGETTEXT = @XGETTEXT@ MSGMERGE = @MSGMERGE@ @@ -175,10 +176,15 @@ include $(srcdir)/conf/tests.mk -include $(wildcard $(GRUB_CONTRIB)/*/conf/common.mk) endif +ifeq ($(TARGET_NO_MODULES), yes) + TARGET_CFLAGS += -DGRUB_TARGET_NO_MODULES=1 + CFLAGS += -DGRUB_TARGET_NO_MODULES=1 +endif + ### General targets. CLEANFILES += $(pkglib_DATA) $(pkgdata_DATA) po/*.mo -ifneq ($(platform), emu) +ifneq ($(TARGET_NO_MODULES), yes) pkglib_DATA += moddep.lst command.lst fs.lst partmap.lst parttool.lst handler.lst video.lst crypto.lst terminal.lst endif moddep.lst: $(DEFSYMFILES) $(UNDSYMFILES) genmoddep.awk diff --git a/conf/any-emu.rmk b/conf/any-emu.rmk index 77092454b..009f1079b 100644 --- a/conf/any-emu.rmk +++ b/conf/any-emu.rmk @@ -13,30 +13,33 @@ pkglib_PROGRAMS = kernel.img kernel_img_SOURCES = kern/device.c kern/disk.c kern/dl.c kern/env.c \ kern/err.c kern/list.c kern/handler.c \ kern/command.c kern/corecmd.c kern/file.c \ - kern/fs.c commands/boot.c kern/main.c kern/misc.c kern/parser.c \ + kern/fs.c kern/main.c kern/misc.c kern/parser.c \ kern/partition.c kern/term.c \ kern/rescue_reader.c kern/rescue_parser.c \ \ util/console.c util/grub-emu.c util/misc.c \ util/hostdisk.c util/getroot.c \ \ - grub_emu_init.c -kernel_img_CFLAGS = $(CPPFLAGS) $(CFLAGS) + gnulib/progname.c util/hostfs.c +kernel_img_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ + env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \ + partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \ + list.h handler.h command.h i18n.h env_private.h +kernel_img_CFLAGS = $(CPPFLAGS) $(CFLAGS) -Wno-undef kernel_img_LDFLAGS = $(COMMON_LDFLAGS) TARGET_NO_STRIP = yes -TARGET_NO_DYNAMIC_MODULES = yes -# progname.c always has warnings. Compile it separately. -pkglib_MODULES += progname.mod -progname_mod_SOURCES = gnulib/progname.c -progname_mod_CFLAGS = $(COMMON_CFLAGS) -Wno-error -progname_mod_LDFLAGS = $(COMMON_LDFLAGS) +ifneq ($(TARGET_NO_MODULES), yes) +kernel_img_SOURCES += symlist.c +else +kernel_img_SOURCES += grub_emu_init.c +endif -# For hostfs.mod. -pkglib_MODULES += hostfs.mod -hostfs_mod_SOURCES = util/hostfs.c -hostfs_mod_CFLAGS = $(COMMON_CFLAGS) -hostfs_mod_LDFLAGS = $(COMMON_LDFLAGS) +# For boot.mod. +pkglib_MODULES += boot.mod +boot_mod_SOURCES = commands/boot.c lib/i386/pc/biosnum.c +boot_mod_CFLAGS = $(COMMON_CFLAGS) +boot_mod_LDFLAGS = $(COMMON_LDFLAGS) # For host.mod. pkglib_MODULES += host.mod @@ -77,8 +80,10 @@ endif ifeq ($(enable_grub_emu_sdl), yes) pkglib_MODULES += sdl.mod sdl_mod_SOURCES = util/sdl.c +sdl_mod_CFLAGS = $(COMMON_CFLAGS) sdl_mod_LDFLAGS = $(COMMON_LDFLAGS) grub_emu_LDFLAGS += $(LIBSDL) +kernel_img_HEADERS += sdl.h endif ifeq ($(enable_grub_emu_pci), yes) @@ -90,6 +95,14 @@ endif include $(srcdir)/conf/common.mk +MOSTLYCLEANFILES += symlist.c kernel_syms.lst +DEFSYMFILES += kernel_syms.lst +symlist.c: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h gensymlist.sh + /bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) + +kernel_syms.lst: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h genkernsyms.sh + /bin/sh genkernsyms.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) + grub_emu_init.h: genemuinitheader.sh $(pkglib_MODULES) rm -f $@; echo $(pkglib_MODULES) | sh $(srcdir)/genemuinitheader.sh $(NM) > $@ DISTCLEANFILES += grub_emu_init.h @@ -99,7 +112,12 @@ grub_emu_init.c: genemuinit.sh $(pkglib_MODULES) DISTCLEANFILES += grub_emu_init.c CLEANFILES += grub-emu +ifneq ($(TARGET_NO_MODULES), yes) +grub-emu: $(pkglib_PROGRAMS) + $(CC) -o $@ $(pkglib_PROGRAMS) $(grub_emu_LDFLAGS) $(LDFLAGS) +else grub-emu: $(pkglib_MODULES) $(pkglib_PROGRAMS) $(CC) -o $@ $(pkglib_MODULES) $(pkglib_PROGRAMS) $(grub_emu_LDFLAGS) $(LDFLAGS) +endif GRUB_EMU=grub-emu diff --git a/configure.ac b/configure.ac index f3fcd8c48..7c8bdb62c 100644 --- a/configure.ac +++ b/configure.ac @@ -548,6 +548,10 @@ AC_ARG_ENABLE([grub-emu-pci], [AS_HELP_STRING([--enable-grub-emu-pci], [build and install the `grub-emu' debugging utility with PCI support (potentially dangerous) (default=no)])]) +AC_ARG_ENABLE([grub-emu-modules], + [AS_HELP_STRING([--enable-grub-emu-modules], + [Support module loading in `grub-emu' debugging utility (default=no)])]) + if test "$platform" = emu; then missing_ncurses= [# Check for curses libraries.] @@ -566,6 +570,13 @@ if test x"$missing_ncurses" = xtrue ; then AC_MSG_ERROR([grub-emu can't be compiled without ncurses]) fi +if test x"$enable_grub_emu_modules" = xyes ; then + TARGET_NO_MODULES=no +else + TARGET_NO_MODULES=yes +fi +AC_SUBST(TARGET_NO_MODULES) + if test x"$enable_grub_emu_usb" = xno ; then grub_emu_usb_excuse="explicitly disabled" fi @@ -733,6 +744,11 @@ echo PCI support for grub-emu: Yes else echo PCI support for grub-emu: No "($grub_emu_pci_excuse)" fi +if [ x"$TARGET_NO_MODULES" = xno ]; then +echo Module support for grub-emu: Yes +else +echo Module support for grub-emu: No +fi fi if [ x"$enable_mm_debug" = xyes ]; then echo With memory debugging: Yes diff --git a/genmk.rb b/genmk.rb index 7df15043a..5cecc5d16 100644 --- a/genmk.rb +++ b/genmk.rb @@ -143,7 +143,7 @@ mostlyclean-module-#{@name}.#{@rule_count}: MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-#{@name}.#{@rule_count} UNDSYMFILES += #{undsym} -ifeq ($(TARGET_NO_DYNAMIC_MODULES), yes) +ifeq ($(TARGET_NO_MODULES), yes) #{@name}: #{pre_obj} $(TARGET_OBJ2ELF) -rm -f $@ $(TARGET_CC) $(#{prefix}_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ #{pre_obj} @@ -322,28 +322,32 @@ class Program end attr_reader :dir, :name + def print_tail() + prefix = @name.to_var + print "CLEANFILES += #{@name} $(#{prefix}_OBJECTS) +ifeq ($(#{prefix}_RELOCATABLE),yes) +#{@name}: $(#{prefix}_DEPENDENCIES) $(#{prefix}_OBJECTS) + $(TARGET_CC) -Wl,-r,-d -o $@ $(#{prefix}_OBJECTS) $(TARGET_LDFLAGS) $(#{prefix}_LDFLAGS) + if test x$(TARGET_NO_STRIP) != xyes ; then $(STRIP) --strip-unneeded -K start -R .note -R .comment $@; fi +else +#{@name}: $(#{prefix}_DEPENDENCIES) $(#{prefix}_OBJECTS) + $(TARGET_CC) -o $@ $(#{prefix}_OBJECTS) $(TARGET_LDFLAGS) $(#{prefix}_LDFLAGS) + if test x$(TARGET_NO_STRIP) != xyes ; then $(STRIP) -R .rel.dyn -R .reginfo -R .note -R .comment $@; fi +endif + +" + end + def rule(sources) prefix = @name.to_var objs = sources.collect do |src| raise "unknown source file `#{src}'" if /\.[cS]$/ !~ src prefix + '-' + src.to_obj end - objs_str = objs.join(' '); deps = objs.collect {|obj| obj.suffix('d')} deps_str = deps.join(' '); - "CLEANFILES += #{@name} #{objs_str} -MOSTLYCLEANFILES += #{deps_str} - -ifeq ($(#{prefix}_RELOCATABLE),yes) -#{@name}: $(#{prefix}_DEPENDENCIES) #{objs_str} - $(TARGET_CC) -Wl,-r,-d -o $@ #{objs_str} $(TARGET_LDFLAGS) $(#{prefix}_LDFLAGS) - if test x$(TARGET_NO_STRIP) != xyes ; then $(STRIP) --strip-unneeded -K start -R .note -R .comment $@; fi -else -#{@name}: $(#{prefix}_DEPENDENCIES) #{objs_str} - $(TARGET_CC) -o $@ #{objs_str} $(TARGET_LDFLAGS) $(#{prefix}_LDFLAGS) - if test x$(TARGET_NO_STRIP) != xyes ; then $(STRIP) -R .rel.dyn -R .reginfo -R .note -R .comment $@; fi -endif + "MOSTLYCLEANFILES += #{deps_str} " + objs.collect_with_index do |obj, i| src = sources[i] @@ -358,6 +362,7 @@ endif -include #{dep} +#{prefix}_OBJECTS += #{obj} " end.join('') end @@ -466,4 +471,5 @@ while l = gets end utils.each {|util| util.print_tail()} +programs.each {|program| program.print_tail()} diff --git a/genmoddep.awk b/genmoddep.awk index 19ac80c71..9f751389b 100644 --- a/genmoddep.awk +++ b/genmoddep.awk @@ -32,13 +32,13 @@ FNR == 1 { else if ($1 != "__gnu_local_gp") { printf "%s in %s is not defined\n", $1, module >"/dev/stderr"; error++; - exit; +# exit; } } # Output the result. END { - if (error == 1) + if (error != 0) exit 1; for (mod in modtab) { diff --git a/include/grub/dl.h b/include/grub/dl.h index 17e03f400..cfb7c2f99 100644 --- a/include/grub/dl.h +++ b/include/grub/dl.h @@ -91,7 +91,7 @@ grub_dl_t grub_dl_load_core (void *addr, grub_size_t size); int EXPORT_FUNC(grub_dl_unload) (grub_dl_t mod); void grub_dl_unload_unneeded (void); void grub_dl_unload_all (void); -#if defined (GRUB_MACHINE_EMU) || defined (GRUB_UTIL) +#if defined (GRUB_UTIL) || defined (GRUB_TARGET_NO_MODULES) #define GRUB_NO_MODULES 1 #else #define GRUB_NO_MODULES 0 @@ -121,7 +121,7 @@ grub_err_t grub_dl_register_symbol (const char *name, void *addr, grub_err_t grub_arch_dl_check_header (void *ehdr); grub_err_t grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr); -#if defined (_mips) && ! defined (GRUB_UTIL) && !defined (GRUB_MACHINE_EMU) +#if defined (_mips) && ! GRUB_NO_MODULES #define GRUB_LINKER_HAVE_INIT 1 void grub_arch_dl_init_linker (void); #endif diff --git a/include/grub/sdl.h b/include/grub/sdl.h new file mode 100644 index 000000000..e4efdc9b1 --- /dev/null +++ b/include/grub/sdl.h @@ -0,0 +1,24 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +void EXPORT_FUNC (SDL_Quit) (void); +void EXPORT_FUNC (SDL_SetColors) (void); +void EXPORT_FUNC (SDL_Init) (void); +void EXPORT_FUNC (SDL_GetError) (void); +void EXPORT_FUNC (SDL_Flip) (void); +void EXPORT_FUNC (SDL_SetVideoMode) (void); diff --git a/util/grub-emu.c b/util/grub-emu.c index 08ae19836..3ad6e406c 100644 --- a/util/grub-emu.c +++ b/util/grub-emu.c @@ -146,6 +146,9 @@ usage (int status) } +void grub_hostfs_init (void); +void grub_hostfs_fini (void); + int main (int argc, char *argv[]) { @@ -204,11 +207,14 @@ main (int argc, char *argv[]) signal (SIGINT, SIG_IGN); grub_console_init (); + grub_hostfs_init (); /* XXX: This is a bit unportable. */ grub_util_biosdisk_init (dev_map); +#if GRUB_NO_MODULES grub_init_all (); +#endif /* Make sure that there is a root device. */ if (! root_dev) @@ -235,7 +241,10 @@ main (int argc, char *argv[]) if (setjmp (main_env) == 0) grub_main (); +#if GRUB_NO_MODULES grub_fini_all (); +#endif + grub_hostfs_fini (); grub_machine_fini (); diff --git a/util/misc.c b/util/misc.c index 7381c8fdd..16a8b234b 100644 --- a/util/misc.c +++ b/util/misc.c @@ -319,10 +319,12 @@ grub_mm_init_region (void *addr __attribute__ ((unused)), { } +#if GRUB_NO_MODULES void grub_register_exported_symbols (void) { } +#endif void grub_exit (void) From b255e9cfb3939bd36f039e269d30e718ac00d62d Mon Sep 17 00:00:00 2001 From: Yves Blusseau Date: Sun, 7 Feb 2010 16:02:51 +0100 Subject: [PATCH 365/738] 2010-02-07 Yves Blusseau * gnulib/getdelim.c: add missing header (type ssize_t must be defined). --- ChangeLog | 4 ++++ gnulib/getdelim.c | 1 + 2 files changed, 5 insertions(+) diff --git a/ChangeLog b/ChangeLog index ec3318c5b..540639220 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-02-07 Yves Blusseau + + * gnulib/getdelim.c: add missing header (type ssize_t must be defined). + 2010-02-07 Vladimir Serbinenko Fix warnings in grub-emu when compiling with maximum warning options. diff --git a/gnulib/getdelim.c b/gnulib/getdelim.c index 12f2167c9..85818b565 100644 --- a/gnulib/getdelim.c +++ b/gnulib/getdelim.c @@ -27,6 +27,7 @@ #include #include #include +#include #ifndef SSIZE_MAX # define SSIZE_MAX ((ssize_t) (SIZE_MAX / 2)) From 3dca5319c6a1f6bee442e29e82866aefd0da6056 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 7 Feb 2010 16:13:59 +0100 Subject: [PATCH 366/738] module support in grub-emu --- conf/any-emu.rmk | 19 +++++++++--------- conf/common.rmk | 10 +++++----- util/grub-emu.c | 13 +++++++++--- util/hostdisk.c | 4 ++-- util/misc.c | 52 +----------------------------------------------- 5 files changed, 27 insertions(+), 71 deletions(-) diff --git a/conf/any-emu.rmk b/conf/any-emu.rmk index 009f1079b..ad71f06bd 100644 --- a/conf/any-emu.rmk +++ b/conf/any-emu.rmk @@ -7,7 +7,6 @@ COMMON_CFLAGS += script/lexer.c_DEPENDENCIES = grub_script.tab.h #sbin_UTILITIES += grub-emu -util/grub-emu.c_DEPENDENCIES = grub_emu_init.h kernel_img_RELOCATABLE = yes pkglib_PROGRAMS = kernel.img kernel_img_SOURCES = kern/device.c kern/disk.c kern/dl.c kern/env.c \ @@ -18,9 +17,9 @@ kernel_img_SOURCES = kern/device.c kern/disk.c kern/dl.c kern/env.c \ kern/rescue_reader.c kern/rescue_parser.c \ \ util/console.c util/grub-emu.c util/misc.c \ - util/hostdisk.c util/getroot.c \ + util/hostdisk.c util/getroot.c util/mm.c \ \ - gnulib/progname.c util/hostfs.c + gnulib/progname.c util/hostfs.c disk/host.c kernel_img_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \ partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \ @@ -30,9 +29,15 @@ kernel_img_LDFLAGS = $(COMMON_LDFLAGS) TARGET_NO_STRIP = yes ifneq ($(TARGET_NO_MODULES), yes) -kernel_img_SOURCES += symlist.c +kernel_img_SOURCES += symlist.c kern/$(target_cpu)/dl.c +ifneq ($(target_cpu), i386) +ifneq ($(target_cpu), x86_64) +kernel_img_SOURCES += kern/$(target_cpu)/cache.S +endif +endif else kernel_img_SOURCES += grub_emu_init.c +grub_emu_init.c_DEPENDENCIES = grub_emu_init.h endif # For boot.mod. @@ -41,12 +46,6 @@ boot_mod_SOURCES = commands/boot.c lib/i386/pc/biosnum.c boot_mod_CFLAGS = $(COMMON_CFLAGS) boot_mod_LDFLAGS = $(COMMON_LDFLAGS) -# For host.mod. -pkglib_MODULES += host.mod -host_mod_SOURCES = disk/host.c -host_mod_CFLAGS = $(COMMON_CFLAGS) -host_mod_LDFLAGS = $(COMMON_LDFLAGS) - # For reboot.mod. pkglib_MODULES += reboot.mod reboot_mod_SOURCES = commands/reboot.c diff --git a/conf/common.rmk b/conf/common.rmk index 6cce36395..a77512643 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -22,7 +22,7 @@ util/elf/grub-mkimage.c_DEPENDENCIES = Makefile sbin_UTILITIES += grub-probe util/grub-probe.c_DEPENDENCIES = grub_probe_init.h grub_probe_SOURCES = gnulib/progname.c util/grub-probe.c \ - util/hostdisk.c util/misc.c util/getroot.c \ + util/hostdisk.c util/misc.c util/getroot.c util/mm.c \ kern/device.c kern/disk.c kern/err.c kern/misc.c \ kern/parser.c kern/partition.c kern/file.c \ \ @@ -57,7 +57,7 @@ grub_mkisofs_CFLAGS = -D_FILE_OFFSET_BITS=64 \ # For grub-fstest. util/grub-fstest.c_DEPENDENCIES = grub_fstest_init.h grub_fstest_SOURCES = gnulib/progname.c util/grub-fstest.c util/hostfs.c \ - util/misc.c \ + util/misc.c util/mm.c \ kern/file.c kern/device.c kern/disk.c kern/err.c kern/misc.c \ disk/host.c disk/loopback.c kern/list.c kern/command.c \ lib/arg.c commands/extcmd.c normal/datetime.c normal/misc.c \ @@ -95,7 +95,7 @@ grub_bin2h_SOURCES = gnulib/progname.c util/bin2h.c bin_UTILITIES += grub-script-check util/grub-script-check.c_DEPENDENCIES = grub_script_check_init.h grub_script_check_SOURCES = gnulib/progname.c gnulib/getdelim.c gnulib/getline.c \ - util/grub-script-check.c util/misc.c \ + util/grub-script-check.c util/misc.c util/mm.c \ script/main.c script/script.c script/function.c script/lexer.c \ kern/handler.c kern/err.c kern/parser.c kern/list.c \ kern/misc.c kern/env.c grub_script_check_init.c grub_script.tab.c @@ -159,7 +159,7 @@ DISTCLEANFILES += grub_fstest_init.c # for grub-editenv bin_UTILITIES += grub-editenv -grub_editenv_SOURCES = gnulib/progname.c util/grub-editenv.c lib/envblk.c util/misc.c kern/misc.c kern/err.c +grub_editenv_SOURCES = gnulib/progname.c util/grub-editenv.c lib/envblk.c util/misc.c util/mm.c kern/misc.c kern/err.c CLEANFILES += grub-editenv # Needed for genmk.rb to work @@ -760,7 +760,7 @@ password_pbkdf2_mod_CFLAGS = $(COMMON_CFLAGS) password_pbkdf2_mod_LDFLAGS = $(COMMON_LDFLAGS) bin_UTILITIES += grub-mkpasswd-pbkdf2 -grub_mkpasswd_pbkdf2_SOURCES = gnulib/progname.c gnulib/getdelim.c gnulib/getline.c util/grub-mkpasswd-pbkdf2.c lib/crypto.c lib/libgcrypt-grub/cipher/sha512.c lib/pbkdf2.c util/misc.c kern/err.c +grub_mkpasswd_pbkdf2_SOURCES = gnulib/progname.c gnulib/getdelim.c gnulib/getline.c util/grub-mkpasswd-pbkdf2.c lib/crypto.c lib/libgcrypt-grub/cipher/sha512.c lib/pbkdf2.c util/misc.c util/mm.c kern/err.c grub_mkpasswd_pbkdf2_CFLAGS += -Wno-missing-field-initializers -Wno-error -I$(srcdir)/lib/libgcrypt_wrap -DGRUB_MKPASSWD=1 include $(srcdir)/conf/gcry.mk diff --git a/util/grub-emu.c b/util/grub-emu.c index 3ad6e406c..fadb79385 100644 --- a/util/grub-emu.c +++ b/util/grub-emu.c @@ -38,8 +38,6 @@ #include #include -#include - #define ENABLE_RELOCATABLE 0 #include "progname.h" @@ -55,6 +53,7 @@ grub_arch_modules_addr (void) return 0; } +#if GRUB_NO_MODULES grub_err_t grub_arch_dl_check_header (void *ehdr) { @@ -71,6 +70,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) return GRUB_ERR_BAD_MODULE; } +#endif void grub_reboot (void) @@ -148,6 +148,8 @@ usage (int status) void grub_hostfs_init (void); void grub_hostfs_fini (void); +void grub_host_init (void); +void grub_host_fini (void); int main (int argc, char *argv[]) @@ -207,6 +209,7 @@ main (int argc, char *argv[]) signal (SIGINT, SIG_IGN); grub_console_init (); + grub_host_init (); grub_hostfs_init (); /* XXX: This is a bit unportable. */ @@ -232,7 +235,10 @@ main (int argc, char *argv[]) } } - dir = grub_get_prefix (dir); + if (strcmp (root_dev, "host") == 0) + dir = xstrdup (dir); + else + dir = grub_get_prefix (dir); prefix = xmalloc (strlen (root_dev) + 2 + strlen (dir) + 1); sprintf (prefix, "(%s)%s", root_dev, dir); free (dir); @@ -245,6 +251,7 @@ main (int argc, char *argv[]) grub_fini_all (); #endif grub_hostfs_fini (); + grub_host_fini (); grub_machine_fini (); diff --git a/util/hostdisk.c b/util/hostdisk.c index 98d3d53ae..0b22e0ad3 100644 --- a/util/hostdisk.c +++ b/util/hostdisk.c @@ -168,7 +168,7 @@ grub_util_biosdisk_open (const char *name, grub_disk_t disk) drive = find_grub_drive (name); if (drive < 0) - return grub_error (GRUB_ERR_BAD_DEVICE, + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no mapping exists for `%s'", name); disk->has_partitions = 1; @@ -949,7 +949,7 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) drive = find_system_device (os_dev); if (drive < 0) { - grub_error (GRUB_ERR_BAD_DEVICE, + grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no mapping exists for `%s'", os_dev); return 0; } diff --git a/util/misc.c b/util/misc.c index 16a8b234b..6182f138e 100644 --- a/util/misc.c +++ b/util/misc.c @@ -262,56 +262,6 @@ grub_util_write_image (const char *img, size_t size, FILE *out) grub_util_error ("write failed"); } -void * -grub_malloc (grub_size_t size) -{ - return xmalloc (size); -} - -void * -grub_zalloc (grub_size_t size) -{ - void *ret; - - ret = xmalloc (size); - memset (ret, 0, size); - return ret; -} - -void -grub_free (void *ptr) -{ - free (ptr); -} - -void * -grub_realloc (void *ptr, grub_size_t size) -{ - return xrealloc (ptr, size); -} - -void * -grub_memalign (grub_size_t align, grub_size_t size) -{ - void *p; - -#if defined(HAVE_POSIX_MEMALIGN) - if (posix_memalign (&p, align, size) != 0) - p = 0; -#elif defined(HAVE_MEMALIGN) - p = memalign (align, size); -#else - (void) align; - (void) size; - grub_util_error ("grub_memalign is not supported"); -#endif - - if (! p) - grub_util_error ("out of memory"); - - return p; -} - /* Some functions that we don't use. */ void grub_mm_init_region (void *addr __attribute__ ((unused)), @@ -376,7 +326,7 @@ grub_millisleep (grub_uint32_t ms) #endif -#if !(defined (__i386__) || defined (__x86_64__)) +#if !(defined (__i386__) || defined (__x86_64__)) && GRUB_NO_MODULES void grub_arch_sync_caches (void *address __attribute__ ((unused)), grub_size_t len __attribute__ ((unused))) From ac307b2ae4e58d2854281bf4a00527b778a4dd2b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 7 Feb 2010 16:47:50 +0100 Subject: [PATCH 367/738] Cleanup --- Makefile.in | 6 ++++-- conf/any-emu.rmk | 1 - 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Makefile.in b/Makefile.in index 820bfa946..7af2df1f0 100644 --- a/Makefile.in +++ b/Makefile.in @@ -89,8 +89,10 @@ TARGET_ASFLAGS = @TARGET_ASFLAGS@ TARGET_MODULE_FORMAT = @TARGET_MODULE_FORMAT@ TARGET_APPLE_CC = @TARGET_APPLE_CC@ OBJCONV = @OBJCONV@ -TARGET_CPPFLAGS = @TARGET_CPPFLAGS@ -I$(srcdir)/include -I$(builddir) -I$(builddir)/include \ - -Wall -W +TARGET_CPPFLAGS = @TARGET_CPPFLAGS@ -I$(srcdir)/include -I$(builddir) -I$(builddir)/include -Wall -W +ifneq ($(platform), emu) +TARGET_CPPFLAGS += -nostdinc -isystem $(shell $(TARGET_CC) -print-file-name=include) +endif TARGET_LDFLAGS = @TARGET_LDFLAGS@ TARGET_IMG_LDSCRIPT = @TARGET_IMG_LDSCRIPT@ TARGET_IMG_LDFLAGS = @TARGET_IMG_LDFLAGS@ diff --git a/conf/any-emu.rmk b/conf/any-emu.rmk index 77092454b..529174bc3 100644 --- a/conf/any-emu.rmk +++ b/conf/any-emu.rmk @@ -6,7 +6,6 @@ COMMON_CFLAGS += # Used by various components. These rules need to precede them. script/lexer.c_DEPENDENCIES = grub_script.tab.h -#sbin_UTILITIES += grub-emu util/grub-emu.c_DEPENDENCIES = grub_emu_init.h kernel_img_RELOCATABLE = yes pkglib_PROGRAMS = kernel.img From 62853e73e5b455f2208d3ba410736a4bd0b407d9 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 7 Feb 2010 16:48:11 +0100 Subject: [PATCH 368/738] ChangeLog --- ChangeLog.emu-mod | 57 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 ChangeLog.emu-mod diff --git a/ChangeLog.emu-mod b/ChangeLog.emu-mod new file mode 100644 index 000000000..7ebdecdd8 --- /dev/null +++ b/ChangeLog.emu-mod @@ -0,0 +1,57 @@ +2010-02-07 Vladimir Serbinenko + + Compile parts of grub-emu as modules. + + * Makefile.in (TARGET_CPPFLAGS) [emu]: Remove -nostdinc -isystem. + (pkglib_DATA) [emu]: Remove moddep.lst command.lst fs.lst + partmap.lst parttool.lst handler.lst video.lst crypto.lst terminal.lst. + (all-local): Add $(GRUB_EMU). + (install-local): Install $(GRUB_EMU). + (uninstall): Uninstall $(GRUB_EMU). + * commands/parttool.c: Replace GRUB_UTIL with GRUB_NO_MODULES. + * kern/dl.c: Likewise. + * commands/sleep.c: Not include machine/time.h. + * conf/any-emu.rmk (COMMON_LDFLAGS): New variable. + (COMMON_CFLAGS): Likewise. + (sbin_UTILITIES): Remove grub-emu. + (grub_emu_SOURCES): Removed. + (kernel_img_RELOCATABLE): New variable. + (pkglib_PROGRAMS): Add kernel.img. + (kernel_img_SOURCES): New variable + (kernel_img_CFLAGS): Likewise. + (kernel_img_LDFLAGS): Likewise. + (TARGET_NO_STRIP): Likewise. + (TARGET_NO_DYNAMIC_MODULES): Likewise. + (pkglib_MODULES): Add progname.mod, hostfs.mod, host.mod, reboot.mod, + halt.mod, cpuid.mod, usb.mod, sdl.mod and pci.mod. + (grub-emu): New target. + (GRUB_EMU): New variable. + * configure.ac: Whitelist -emu as possible x86_64 architecture. + * efiemu/main.c: Replace GRUB_UTIL with GRUB_MACHINE_EMU. + * loader/xnu.c: Likewise. + * include/grub/pci.h: Likewise. + * genemuinit.sh: New file. + * genemuinitheader.sh: Likewise. + * genmk.rb: Don't strip if TARGET_NO_STRIP is yes. + Support TARGET_NO_DYNAMIC_MODULES. + * include/grub/dl.h (GRUB_NO_MODULES): New variable. + * commands/search.c: Fix GRUB_MOD_INIT and GRUB_MOD_FINI arguments. + * disk/loopback.c: Likewise. + * font/font_cmd.c: Likewise. + * partmap/acorn.c: Likewise. + * partmap/amiga.c: Likewise. + * partmap/apple.c: Likewise. + * partmap/gpt.c: Likewise. + * partmap/msdos.c: Likewise. + * partmap/sun.c: Likewise. + * parttool/msdospart.c: Likewise. + * term/gfxterm.c: Likewise. + * video/bitmap.c: Likewise. + * video/readers/jpeg.c: Likewise. + * video/readers/png.c: Likewise. + * video/readers/tga.c: Likewise. + * video/video.c: Likewise. + * util/grub-emu.c (read_command_list): Removed. + (main): Don't call util_init_nls. + * util/misc.c (grub_err_printf) [!GRUB_UTIL]: Removed. + (grub_util_init_nls) [!GRUB_UTIL]: Likewise. From 6e14234c874224e88345492373c77eee34d00e18 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 7 Feb 2010 16:51:16 +0100 Subject: [PATCH 369/738] 2010-02-07 Vladimir Serbinenko * include/grub/multiboot2.h: Remove leftover file. --- ChangeLog | 6 +++- include/grub/multiboot2.h | 70 --------------------------------------- 2 files changed, 5 insertions(+), 71 deletions(-) delete mode 100644 include/grub/multiboot2.h diff --git a/ChangeLog b/ChangeLog index 540639220..7e9e18348 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,10 @@ +2010-02-07 Vladimir Serbinenko + + * include/grub/multiboot2.h: Remove leftover file. + 2010-02-07 Yves Blusseau - * gnulib/getdelim.c: add missing header (type ssize_t must be defined). + * gnulib/getdelim.c: add missing header (type ssize_t must be defined). 2010-02-07 Vladimir Serbinenko diff --git a/include/grub/multiboot2.h b/include/grub/multiboot2.h deleted file mode 100644 index af10cdc21..000000000 --- a/include/grub/multiboot2.h +++ /dev/null @@ -1,70 +0,0 @@ -/* multiboot2.h - multiboot2 header file with grub definitions. */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2005,2007 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_MULTIBOOT2_HEADER -#define GRUB_MULTIBOOT2_HEADER 1 - -#include -#include -#include - -#ifndef GRUB_UTIL -typedef grub_uint32_t uint32_t; -typedef grub_uint64_t uint64_t; -#define __WORDSIZE GRUB_TARGET_WORDSIZE -#endif - -struct multiboot2_tag_header; - -grub_err_t -grub_mb2_tag_alloc (grub_addr_t *addr, int key, grub_size_t len); - -grub_err_t -grub_mb2_tags_arch_create (void); - -void -grub_mb2_arch_boot (grub_addr_t entry, void *tags); - -void -grub_mb2_arch_unload (struct multiboot2_tag_header *tags); - -grub_err_t -grub_mb2_arch_elf32_hook (Elf32_Phdr *phdr, grub_addr_t *addr, int *do_load); - -grub_err_t -grub_mb2_arch_elf64_hook (Elf64_Phdr *phdr, grub_addr_t *addr, int *do_load); - -grub_err_t -grub_mb2_arch_module_alloc (grub_size_t size, grub_addr_t *addr); - -grub_err_t -grub_mb2_arch_module_free (grub_addr_t addr, grub_size_t size); - -void -grub_multiboot2 (int argc, char *argv[]); - -void -grub_module2 (int argc, char *argv[]); - -#define for_each_tag(tag, tags) \ - for (tag = tags; \ - tag && tag->key != MULTIBOOT2_TAG_END; \ - tag = (struct multiboot2_tag_header *)((char *)tag + tag->len)) - -#endif /* ! GRUB_MULTIBOOT2_HEADER */ From e28e32ae51c75a64333deffbd78f1cda9c376fc8 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 7 Feb 2010 16:52:47 +0100 Subject: [PATCH 370/738] 2010-02-07 Vladimir Serbinenko * include/grub/normal.h [GRUB_UTIL]: Remove leftover declarations. * include/grub/partition.h [GRUB_UTIL]: Likewise. --- ChangeLog | 2 ++ include/grub/normal.h | 33 --------------------------------- include/grub/partition.h | 14 -------------- 3 files changed, 2 insertions(+), 47 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7e9e18348..dede0af2e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,8 @@ 2010-02-07 Vladimir Serbinenko * include/grub/multiboot2.h: Remove leftover file. + * include/grub/normal.h [GRUB_UTIL]: Remove leftover declarations. + * include/grub/partition.h [GRUB_UTIL]: Likewise. 2010-02-07 Yves Blusseau diff --git a/include/grub/normal.h b/include/grub/normal.h index e804fde77..fad1a41ba 100644 --- a/include/grub/normal.h +++ b/include/grub/normal.h @@ -110,37 +110,4 @@ void read_terminal_list (void); void grub_set_more (int onoff); -#ifdef GRUB_UTIL -void grub_normal_init (void); -void grub_normal_fini (void); -void grub_hello_init (void); -void grub_hello_fini (void); -void grub_ls_init (void); -void grub_ls_fini (void); -void grub_cat_init (void); -void grub_cat_fini (void); -void grub_boot_init (void); -void grub_boot_fini (void); -void grub_cmp_init (void); -void grub_cmp_fini (void); -void grub_terminal_init (void); -void grub_terminal_fini (void); -void grub_loop_init (void); -void grub_loop_fini (void); -void grub_help_init (void); -void grub_help_fini (void); -void grub_halt_init (void); -void grub_halt_fini (void); -void grub_reboot_init (void); -void grub_reboot_fini (void); -void grub_configfile_init (void); -void grub_configfile_fini (void); -void grub_search_init (void); -void grub_search_fini (void); -void grub_test_init (void); -void grub_test_fini (void); -void grub_blocklist_init (void); -void grub_blocklist_fini (void); -#endif - #endif /* ! GRUB_NORMAL_HEADER */ diff --git a/include/grub/partition.h b/include/grub/partition.h index d35658cdd..faa89cea6 100644 --- a/include/grub/partition.h +++ b/include/grub/partition.h @@ -83,20 +83,6 @@ void EXPORT_FUNC(grub_partition_map_register) (grub_partition_map_t partmap); void EXPORT_FUNC(grub_partition_map_unregister) (grub_partition_map_t partmap); -#ifdef GRUB_UTIL -void grub_msdos_partition_map_init (void); -void grub_msdos_partition_map_fini (void); -void grub_amiga_partition_map_init (void); -void grub_amiga_partition_map_fini (void); -void grub_apple_partition_map_init (void); -void grub_apple_partition_map_fini (void); -void grub_sun_partition_map_init (void); -void grub_sun_partition_map_fini (void); -void grub_gpt_partition_map_init (void); -void grub_gpt_partition_map_fini (void); -void grub_apple_partition_map_init (void); -void grub_apple_partition_map_fini (void); -#endif static inline grub_disk_addr_t grub_partition_get_start (const grub_partition_t p) From a1a8d38a5862ec296e5940be1f38af8804118f09 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 7 Feb 2010 17:30:16 +0100 Subject: [PATCH 371/738] Use nostdinc --- conf/any-emu.rmk | 25 ++++--------------------- util/grub-emu.c | 9 +++++++++ util/hostdisk.c | 6 +++--- 3 files changed, 16 insertions(+), 24 deletions(-) diff --git a/conf/any-emu.rmk b/conf/any-emu.rmk index 529174bc3..d3d2c2f2f 100644 --- a/conf/any-emu.rmk +++ b/conf/any-emu.rmk @@ -1,7 +1,7 @@ # -*- makefile -*- COMMON_LDFLAGS += -nostdlib -COMMON_CFLAGS += +COMMON_CFLAGS += -nostdinc -isystem $(shell $(TARGET_CC) -print-file-name=include) # Used by various components. These rules need to precede them. script/lexer.c_DEPENDENCIES = grub_script.tab.h @@ -19,30 +19,12 @@ kernel_img_SOURCES = kern/device.c kern/disk.c kern/dl.c kern/env.c \ util/console.c util/grub-emu.c util/misc.c \ util/hostdisk.c util/getroot.c \ \ - grub_emu_init.c -kernel_img_CFLAGS = $(CPPFLAGS) $(CFLAGS) + grub_emu_init.c gnulib/progname.c util/hostfs.c disk/host.c +kernel_img_CFLAGS = $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) -Wno-undef -I$(srcdir)/gnulib kernel_img_LDFLAGS = $(COMMON_LDFLAGS) TARGET_NO_STRIP = yes TARGET_NO_DYNAMIC_MODULES = yes -# progname.c always has warnings. Compile it separately. -pkglib_MODULES += progname.mod -progname_mod_SOURCES = gnulib/progname.c -progname_mod_CFLAGS = $(COMMON_CFLAGS) -Wno-error -progname_mod_LDFLAGS = $(COMMON_LDFLAGS) - -# For hostfs.mod. -pkglib_MODULES += hostfs.mod -hostfs_mod_SOURCES = util/hostfs.c -hostfs_mod_CFLAGS = $(COMMON_CFLAGS) -hostfs_mod_LDFLAGS = $(COMMON_LDFLAGS) - -# For host.mod. -pkglib_MODULES += host.mod -host_mod_SOURCES = disk/host.c -host_mod_CFLAGS = $(COMMON_CFLAGS) -host_mod_LDFLAGS = $(COMMON_LDFLAGS) - # For reboot.mod. pkglib_MODULES += reboot.mod reboot_mod_SOURCES = commands/reboot.c @@ -76,6 +58,7 @@ endif ifeq ($(enable_grub_emu_sdl), yes) pkglib_MODULES += sdl.mod sdl_mod_SOURCES = util/sdl.c +sdl_mod_CFLAGS = sdl_mod_LDFLAGS = $(COMMON_LDFLAGS) grub_emu_LDFLAGS += $(LIBSDL) endif diff --git a/util/grub-emu.c b/util/grub-emu.c index 08ae19836..7d4544509 100644 --- a/util/grub-emu.c +++ b/util/grub-emu.c @@ -146,6 +146,11 @@ usage (int status) } +void grub_hostfs_init (void); +void grub_hostfs_fini (void); +void grub_host_init (void); +void grub_host_fini (void); + int main (int argc, char *argv[]) { @@ -204,6 +209,8 @@ main (int argc, char *argv[]) signal (SIGINT, SIG_IGN); grub_console_init (); + grub_host_init (); + grub_hostfs_init (); /* XXX: This is a bit unportable. */ grub_util_biosdisk_init (dev_map); @@ -236,6 +243,8 @@ main (int argc, char *argv[]) grub_main (); grub_fini_all (); + grub_hostfs_fini (); + grub_host_fini (); grub_machine_fini (); diff --git a/util/hostdisk.c b/util/hostdisk.c index 98d3d53ae..be5d05afc 100644 --- a/util/hostdisk.c +++ b/util/hostdisk.c @@ -168,7 +168,7 @@ grub_util_biosdisk_open (const char *name, grub_disk_t disk) drive = find_grub_drive (name); if (drive < 0) - return grub_error (GRUB_ERR_BAD_DEVICE, + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no mapping exists for `%s'", name); disk->has_partitions = 1; @@ -198,7 +198,7 @@ grub_util_biosdisk_open (const char *name, grub_disk_t disk) fd = open (map[drive].device, O_RDONLY); if (fd == -1) - return grub_error (GRUB_ERR_BAD_DEVICE, "cannot open `%s' while attempting to get disk size", map[drive].device); + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "cannot open `%s' while attempting to get disk size", map[drive].device); # if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__APPLE__) if (fstat (fd, &st) < 0 || ! S_ISCHR (st.st_mode)) @@ -244,7 +244,7 @@ grub_util_biosdisk_open (const char *name, grub_disk_t disk) # warning "No special routine to get the size of a block device is implemented for your OS. This is not possibly fatal." #endif if (stat (map[drive].device, &st) < 0) - return grub_error (GRUB_ERR_BAD_DEVICE, "cannot stat `%s'", map[drive].device); + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "cannot stat `%s'", map[drive].device); disk->total_sectors = st.st_size >> GRUB_DISK_SECTOR_BITS; From b4674703a12144315b2d725c40bc490645727712 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 7 Feb 2010 17:39:52 +0100 Subject: [PATCH 372/738] Add fno-builtin --- conf/any-emu.rmk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/any-emu.rmk b/conf/any-emu.rmk index d3d2c2f2f..a4ee9b755 100644 --- a/conf/any-emu.rmk +++ b/conf/any-emu.rmk @@ -1,7 +1,7 @@ # -*- makefile -*- COMMON_LDFLAGS += -nostdlib -COMMON_CFLAGS += -nostdinc -isystem $(shell $(TARGET_CC) -print-file-name=include) +COMMON_CFLAGS += -nostdinc -isystem $(shell $(TARGET_CC) -print-file-name=include) -fno-builtin # Used by various components. These rules need to precede them. script/lexer.c_DEPENDENCIES = grub_script.tab.h From 7eed9925e2b2a0bf59a26b4947ee0cd603b4d885 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 7 Feb 2010 18:10:36 +0100 Subject: [PATCH 373/738] missing files --- ChangeLog.emu-modload | 18 +++++++++ util/mm.c | 85 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 103 insertions(+) create mode 100644 ChangeLog.emu-modload create mode 100644 util/mm.c diff --git a/ChangeLog.emu-modload b/ChangeLog.emu-modload new file mode 100644 index 000000000..dd0ea6bf0 --- /dev/null +++ b/ChangeLog.emu-modload @@ -0,0 +1,18 @@ +2010-02-07 Vladimir Serbinenko + + grub-emu module load support. + + * Makefile.in (TARGET_NO_MODULES): New variable. All users of + NO_DYNAMIC_MODULES switched to this. + (TARGET_CFLAGS): Add -DGRUB_TARGET_NO_MODULES=1 if applicable. + (CFLAGS): Likewise. + * conf/any-emu.rmk: Generate symlist. + * configure.ac (grub-emu-modules): New option. + * genmk.rb: Handle multiple source lists. + * genmoddep.awk: Output all undefined symbols. + * include/grub/sdl.h: New file. + * util/grub-emu.c (main): Hanle (host) root. + * util/hostdisk.c (grub_util_biosdisk_get_grub_dev): Error with + GRUB_ERR_UNKNOWN_DEVICE. + * util/misc.c: Move mm functions to ... + * util/mm.c: ... here. All users updated. diff --git a/util/mm.c b/util/mm.c new file mode 100644 index 000000000..0e9e9f3a8 --- /dev/null +++ b/util/mm.c @@ -0,0 +1,85 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2003,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include + +void * +grub_malloc (grub_size_t size) +{ + void *ret; + ret = malloc (size); + if (!ret) + grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory"); + return ret; +} + +void * +grub_zalloc (grub_size_t size) +{ + void *ret; + + ret = grub_malloc (size); + if (!ret) + return NULL; + memset (ret, 0, size); + return ret; +} + +void +grub_free (void *ptr) +{ + free (ptr); +} + +void * +grub_realloc (void *ptr, grub_size_t size) +{ + void *ret; + ret = realloc (ptr, size); + if (!ret) + grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory"); + return ret; +} + +void * +grub_memalign (grub_size_t align, grub_size_t size) +{ + void *p; + +#if defined(HAVE_POSIX_MEMALIGN) + if (align < sizeof (void *)) + align = sizeof (void *); + if (posix_memalign (&p, align, size) != 0) + p = 0; +#elif defined(HAVE_MEMALIGN) + p = memalign (align, size); +#else + (void) align; + (void) size; + grub_util_error ("grub_memalign is not supported"); +#endif + + if (!p) + grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory"); + + return p; +} From c98d2a13c20f4e5bd75b500d7cbbd739c4b71a61 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Sun, 7 Feb 2010 10:27:03 -0800 Subject: [PATCH 374/738] 2010-02-07 Colin Watson * NEWS: Update. --- ChangeLog | 4 ++++ NEWS | 15 +++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/ChangeLog b/ChangeLog index dede0af2e..37081a9e4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-02-07 Colin Watson + + * NEWS: Update. + 2010-02-07 Vladimir Serbinenko * include/grub/multiboot2.h: Remove leftover file. diff --git a/NEWS b/NEWS index cc725fd3b..828eea081 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,20 @@ New in 1.98: +* Graphical menu support. + +* MIPS support. + +* Saved default menu entry support, with new utilities `grub-reboot' and + `grub-set-default'. + +* Unit testing framework. + +* Support for multiple terminals. + +* Encrypted password support, with a new utility `grub-mkpasswd-pbkdf2'. + +* `grub-mkfloppy' removed; use `grub-mkrescue' to create floppy images. + * Add grub-probe support for GNU/Hurd. * Add support for gettext. From 473df63dc0fa943ab4b3bdbbabc224dd63a1a45d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 7 Feb 2010 19:57:55 +0100 Subject: [PATCH 375/738] 2010-02-07 Vladimir Serbinenko * genkernsyms.sh.in: Use TARGET_CC. --- ChangeLog | 4 ++++ genkernsyms.sh.in | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 37081a9e4..f7b2ce8bf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-02-07 Vladimir Serbinenko + + * genkernsyms.sh.in: Use TARGET_CC. + 2010-02-07 Colin Watson * NEWS: Update. diff --git a/genkernsyms.sh.in b/genkernsyms.sh.in index b2f3f7af9..c5c63b2d5 100644 --- a/genkernsyms.sh.in +++ b/genkernsyms.sh.in @@ -14,7 +14,7 @@ ### The configure script will replace these variables. : ${srcdir=@srcdir@} -: ${CC=@CC@} +: ${CC=@TARGET_CC@} u= grep "^#define HAVE_ASM_USCORE" config.h >/dev/null 2>&1 && u="_" From 56e33364c54611d68cce355bdf1c191c3d69b157 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 7 Feb 2010 19:59:19 +0100 Subject: [PATCH 376/738] Fix yeeloong compilation --- kern/mips/yeeloong/init.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/kern/mips/yeeloong/init.c b/kern/mips/yeeloong/init.c index 14e8a39a2..d48a7341a 100644 --- a/kern/mips/yeeloong/init.c +++ b/kern/mips/yeeloong/init.c @@ -29,10 +29,10 @@ #include extern void grub_video_sm712_init (void); -extern void grub_video_video_init (void); -extern void grub_video_bitmap_init (void); -extern void grub_font_manager_init (void); -extern void grub_term_gfxterm_init (void); +extern void grub_video_init (void); +extern void grub_bitmap_init (void); +extern void grub_font_init (void); +extern void grub_gfxterm_init (void); extern void grub_at_keyboard_init (void); /* FIXME: use interrupt to count high. */ @@ -98,10 +98,10 @@ grub_machine_init (void) /* Initialize output terminal (can't be done earlier, as gfxterm relies on a working heap. */ grub_video_sm712_init (); - grub_video_video_init (); - grub_video_bitmap_init (); - grub_font_manager_init (); - grub_term_gfxterm_init (); + grub_video_init (); + grub_bitmap_init (); + grub_font_init (); + grub_gfxterm_init (); grub_at_keyboard_init (); } From 62509f04348a468b9db6894ae15e9dc14bbff484 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 7 Feb 2010 22:49:45 +0100 Subject: [PATCH 377/738] 2010-02-07 Vladimir Serbinenko * kern/ieee1275/openfw.c (grub_halt): Try executing "poweroff". --- ChangeLog | 4 ++++ kern/ieee1275/openfw.c | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index f7b2ce8bf..ff8f3d41c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-02-07 Vladimir Serbinenko + + * kern/ieee1275/openfw.c (grub_halt): Try executing "poweroff". + 2010-02-07 Vladimir Serbinenko * genkernsyms.sh.in: Use TARGET_CC. diff --git a/kern/ieee1275/openfw.c b/kern/ieee1275/openfw.c index dd9a9138f..e5f565c4c 100644 --- a/kern/ieee1275/openfw.c +++ b/kern/ieee1275/openfw.c @@ -405,8 +405,9 @@ grub_reboot (void) void grub_halt (void) { - /* Not standardized. We try both known commands. */ + /* Not standardized. We try three known commands. */ grub_ieee1275_interpret ("shut-down", 0); grub_ieee1275_interpret ("power-off", 0); + grub_ieee1275_interpret ("poweroff", 0); } From f84dc56090d055077b4c9bc222e665b20bf22094 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 7 Feb 2010 22:56:25 +0100 Subject: [PATCH 378/738] Initial implementation of ofwclock --- ChangeLog.ofwclock | 15 ++++ conf/powerpc-ieee1275.rmk | 17 +++++ conf/sparc64-ieee1275.rmk | 17 +++++ lib/ieee1275/datetime.c | 142 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 191 insertions(+) create mode 100644 ChangeLog.ofwclock create mode 100644 lib/ieee1275/datetime.c diff --git a/ChangeLog.ofwclock b/ChangeLog.ofwclock new file mode 100644 index 000000000..1cdd99cd4 --- /dev/null +++ b/ChangeLog.ofwclock @@ -0,0 +1,15 @@ +2010-02-07 Vladimir Serbinenko + + * conf/powerpc-ieee1275.rmk (pkglib_MODULES): Add datetime.mod, + date.mod, datehook.mod. + (datetime_mod_SOURCES): New variable. + (datetime_mod_CFLAGS): Likewise. + (datetime_mod_LDFLAGS): Likewise. + (date_mod_SOURCES): Likewise. + (date_mod_CFLAGS): Likewise. + (date_mod_LDFLAGS): Likewise. + (datehook_mod_SOURCES): Likewise. + (datehook_mod_CFLAGS): Likewise. + (datehook_mod_LDFLAGS): Likewise. + * conf/sparc64-ieee1275.rmk: Likewise. + * lib/ieee1275/datetime.c: New file. diff --git a/conf/powerpc-ieee1275.rmk b/conf/powerpc-ieee1275.rmk index 8622293ab..73e56e66f 100644 --- a/conf/powerpc-ieee1275.rmk +++ b/conf/powerpc-ieee1275.rmk @@ -105,4 +105,21 @@ lsmmap_mod_SOURCES = commands/lsmmap.c lsmmap_mod_CFLAGS = $(COMMON_CFLAGS) lsmmap_mod_LDFLAGS = $(COMMON_LDFLAGS) +pkglib_MODULES += datetime.mod date.mod datehook.mod + +# For datetime.mod +datetime_mod_SOURCES = lib/ieee1275/datetime.c +datetime_mod_CFLAGS = $(COMMON_CFLAGS) +datetime_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For date.mod +date_mod_SOURCES = commands/date.c +date_mod_CFLAGS = $(COMMON_CFLAGS) +date_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For datehook.mod +datehook_mod_SOURCES = hook/datehook.c +datehook_mod_CFLAGS = $(COMMON_CFLAGS) +datehook_mod_LDFLAGS = $(COMMON_LDFLAGS) + include $(srcdir)/conf/common.mk diff --git a/conf/sparc64-ieee1275.rmk b/conf/sparc64-ieee1275.rmk index befc7dce5..6210826e2 100644 --- a/conf/sparc64-ieee1275.rmk +++ b/conf/sparc64-ieee1275.rmk @@ -133,4 +133,21 @@ lsmmap_mod_SOURCES = commands/lsmmap.c lsmmap_mod_CFLAGS = $(COMMON_CFLAGS) lsmmap_mod_LDFLAGS = $(COMMON_LDFLAGS) +pkglib_MODULES += datetime.mod date.mod datehook.mod + +# For datetime.mod +datetime_mod_SOURCES = lib/ieee1275/datetime.c +datetime_mod_CFLAGS = $(COMMON_CFLAGS) +datetime_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For date.mod +date_mod_SOURCES = commands/date.c +date_mod_CFLAGS = $(COMMON_CFLAGS) +date_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For datehook.mod +datehook_mod_SOURCES = hook/datehook.c +datehook_mod_CFLAGS = $(COMMON_CFLAGS) +datehook_mod_LDFLAGS = $(COMMON_LDFLAGS) + include $(srcdir)/conf/common.mk diff --git a/lib/ieee1275/datetime.c b/lib/ieee1275/datetime.c new file mode 100644 index 000000000..aaf17b0fa --- /dev/null +++ b/lib/ieee1275/datetime.c @@ -0,0 +1,142 @@ +/* kern/cmos_datetime.c - CMOS datetime function. + * + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include + +static char *rtc = 0; + +static void +find_rtc (void) +{ + auto int hook (struct grub_ieee1275_devalias *alias); + int hook (struct grub_ieee1275_devalias *alias) + { + if (grub_strcmp (alias->type, "rtc") == 0) + { + grub_dprintf ("datetime", "Found RTC %s\n", alias->name); + rtc = grub_strdup (alias->name); + return 1; + } + return 0; + } + + grub_ieee1275_devices_iterate (hook); +} + +grub_err_t +grub_get_datetime (struct grub_datetime *datetime) +{ + struct get_time_args + { + struct grub_ieee1275_common_hdr common; + grub_ieee1275_cell_t method; + grub_ieee1275_cell_t device; + grub_ieee1275_cell_t catch_result; + grub_ieee1275_cell_t year; + grub_ieee1275_cell_t month; + grub_ieee1275_cell_t day; + grub_ieee1275_cell_t hour; + grub_ieee1275_cell_t minute; + grub_ieee1275_cell_t second; + } + args; + int status; + grub_ieee1275_ihandle_t ihandle; + + if (!rtc) + find_rtc (); + if (!rtc) + return grub_error (GRUB_ERR_IO, "no RTC found"); + + status = grub_ieee1275_open (rtc, &ihandle); + if (status == -1) + return grub_error (GRUB_ERR_IO, "couldn't open RTC"); + + INIT_IEEE1275_COMMON (&args.common, "call-method", 2, 7); + args.device = (grub_ieee1275_cell_t) ihandle; + args.method = (grub_ieee1275_cell_t) "get-time"; + + status = IEEE1275_CALL_ENTRY_FN (&args); + + grub_ieee1275_close (ihandle); + + if (status == -1) + return grub_error (GRUB_ERR_IO, "get-time failed"); + + datetime->year = args.year; + datetime->month = args.month; + datetime->day = args.day; + datetime->hour = args.hour; + datetime->minute = args.minute; + datetime->second = args.second; + + return GRUB_ERR_NONE; +} + +grub_err_t +grub_set_datetime (struct grub_datetime *datetime) +{ + struct get_time_args + { + struct grub_ieee1275_common_hdr common; + grub_ieee1275_cell_t method; + grub_ieee1275_cell_t device; + grub_ieee1275_cell_t year; + grub_ieee1275_cell_t month; + grub_ieee1275_cell_t day; + grub_ieee1275_cell_t hour; + grub_ieee1275_cell_t minute; + grub_ieee1275_cell_t second; + grub_ieee1275_cell_t catch_result; + } + args; + int status; + grub_ieee1275_ihandle_t ihandle; + + if (!rtc) + find_rtc (); + if (!rtc) + return grub_error (GRUB_ERR_IO, "no RTC found"); + + status = grub_ieee1275_open (rtc, &ihandle); + if (status == -1) + return grub_error (GRUB_ERR_IO, "couldn't open RTC"); + + INIT_IEEE1275_COMMON (&args.common, "call-method", 8, 1); + args.device = (grub_ieee1275_cell_t) ihandle; + args.method = (grub_ieee1275_cell_t) "set-time"; + + args.year = datetime->year; + args.month = datetime->month; + args.day = datetime->day; + args.hour = datetime->hour; + args.minute = datetime->minute; + args.second = datetime->second; + + status = IEEE1275_CALL_ENTRY_FN (&args); + + grub_ieee1275_close (ihandle); + + if (status == -1) + return grub_error (GRUB_ERR_IO, "set-time failed"); + + return GRUB_ERR_NONE; +} From ec0be08d40bf33e612f152d0d58324cce4800afe Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 7 Feb 2010 23:49:49 +0100 Subject: [PATCH 379/738] Clean building system --- commands/lsmmap.c | 4 ++ conf/any-emu.rmk | 10 +-- conf/common.rmk | 36 +++++++++++ conf/i386-coreboot.rmk | 108 +------------------------------ conf/i386-efi.rmk | 35 +--------- conf/i386-ieee1275.rmk | 54 ++-------------- conf/i386-pc.rmk | 63 ++---------------- conf/i386-qemu.rmk | 108 ++++++++++++++++++++++++++++++- conf/i386.rmk | 25 +++++++ conf/mips-yeeloong.rmk | 13 ---- conf/mips.rmk | 20 ------ conf/powerpc-ieee1275.rmk | 44 ++----------- conf/sparc64-ieee1275.rmk | 47 +++----------- conf/x86_64-efi.rmk | 35 +--------- disk/memdisk.c | 1 - hook/datehook.c | 4 +- include/grub/datetime.h | 7 ++ include/grub/i386/efi/serial.h | 1 + include/grub/x86_64/efi/serial.h | 1 + util/time.c | 46 +++++++++++++ video/ieee1275.c | 5 +- 21 files changed, 261 insertions(+), 406 deletions(-) create mode 100644 include/grub/i386/efi/serial.h create mode 100644 include/grub/x86_64/efi/serial.h create mode 100644 util/time.c diff --git a/commands/lsmmap.c b/commands/lsmmap.c index d5eef1ce9..2755df9c4 100644 --- a/commands/lsmmap.c +++ b/commands/lsmmap.c @@ -16,7 +16,9 @@ * along with GRUB. If not, see . */ +#ifndef GRUB_MACHINE_EMU #include +#endif #include #include #include @@ -34,7 +36,9 @@ grub_cmd_lsmmap (grub_command_t cmd __attribute__ ((unused)), (long long) addr, (long long) size, type); return 0; } +#ifndef GRUB_MACHINE_EMU grub_machine_mmap_iterate (hook); +#endif return 0; } diff --git a/conf/any-emu.rmk b/conf/any-emu.rmk index a4ee9b755..ee5ab3cd4 100644 --- a/conf/any-emu.rmk +++ b/conf/any-emu.rmk @@ -12,12 +12,12 @@ pkglib_PROGRAMS = kernel.img kernel_img_SOURCES = kern/device.c kern/disk.c kern/dl.c kern/env.c \ kern/err.c kern/list.c kern/handler.c \ kern/command.c kern/corecmd.c kern/file.c \ - kern/fs.c commands/boot.c kern/main.c kern/misc.c kern/parser.c \ + kern/fs.c kern/main.c kern/misc.c kern/parser.c \ kern/partition.c kern/term.c \ kern/rescue_reader.c kern/rescue_parser.c \ \ util/console.c util/grub-emu.c util/misc.c \ - util/hostdisk.c util/getroot.c \ + util/hostdisk.c util/getroot.c util/time.c \ \ grub_emu_init.c gnulib/progname.c util/hostfs.c disk/host.c kernel_img_CFLAGS = $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) -Wno-undef -I$(srcdir)/gnulib @@ -25,12 +25,6 @@ kernel_img_LDFLAGS = $(COMMON_LDFLAGS) TARGET_NO_STRIP = yes TARGET_NO_DYNAMIC_MODULES = yes -# For reboot.mod. -pkglib_MODULES += reboot.mod -reboot_mod_SOURCES = commands/reboot.c -reboot_mod_CFLAGS = $(COMMON_CFLAGS) -reboot_mod_LDFLAGS = $(COMMON_LDFLAGS) - # For halt.mod. pkglib_MODULES += halt.mod halt_mod_SOURCES = commands/halt.c diff --git a/conf/common.rmk b/conf/common.rmk index 6cce36395..f3c85d971 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -759,6 +759,42 @@ password_pbkdf2_mod_SOURCES = commands/password_pbkdf2.c password_pbkdf2_mod_CFLAGS = $(COMMON_CFLAGS) password_pbkdf2_mod_LDFLAGS = $(COMMON_LDFLAGS) +# For memdisk.mod. +pkglib_MODULES += memdisk.mod +memdisk_mod_SOURCES = disk/memdisk.c +memdisk_mod_CFLAGS = $(COMMON_CFLAGS) +memdisk_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For reboot.mod. +pkglib_MODULES += reboot.mod +reboot_mod_SOURCES = commands/reboot.c +reboot_mod_CFLAGS = $(COMMON_CFLAGS) +reboot_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For date.mod +pkglib_MODULES += date.mod +date_mod_SOURCES = commands/date.c +date_mod_CFLAGS = $(COMMON_CFLAGS) +date_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For datehook.mod +pkglib_MODULES += datehook.mod +datehook_mod_SOURCES = hook/datehook.c +datehook_mod_CFLAGS = $(COMMON_CFLAGS) +datehook_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For lsmmap.mod +pkglib_MODULES += lsmmap.mod +lsmmap_mod_SOURCES = commands/lsmmap.c +lsmmap_mod_CFLAGS = $(COMMON_CFLAGS) +lsmmap_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For boot.mod. +pkglib_MODULES += boot.mod +boot_mod_SOURCES = commands/boot.c lib/i386/pc/biosnum.c +boot_mod_CFLAGS = $(COMMON_CFLAGS) +boot_mod_LDFLAGS = $(COMMON_LDFLAGS) + bin_UTILITIES += grub-mkpasswd-pbkdf2 grub_mkpasswd_pbkdf2_SOURCES = gnulib/progname.c gnulib/getdelim.c gnulib/getline.c util/grub-mkpasswd-pbkdf2.c lib/crypto.c lib/libgcrypt-grub/cipher/sha512.c lib/pbkdf2.c util/misc.c kern/err.c grub_mkpasswd_pbkdf2_CFLAGS += -Wno-missing-field-initializers -Wno-error -I$(srcdir)/lib/libgcrypt_wrap -DGRUB_MKPASSWD=1 diff --git a/conf/i386-coreboot.rmk b/conf/i386-coreboot.rmk index 9563c0b2b..85407b47e 100644 --- a/conf/i386-coreboot.rmk +++ b/conf/i386-coreboot.rmk @@ -11,8 +11,6 @@ script/lexer.c_DEPENDENCIES = grub_script.tab.h GRUB_KERNEL_MACHINE_LINK_ADDR = 0x8200 -ifeq ($(platform), coreboot) - pkglib_PROGRAMS += kernel.img kernel_img_SOURCES = kern/i386/coreboot/startup.S \ kern/i386/misc.S \ @@ -41,55 +39,6 @@ kernel_img_CFLAGS = $(COMMON_CFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) kernel_img_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,$(GRUB_KERNEL_MACHINE_LINK_ADDR),-Bstatic -endif - -ifeq ($(platform), qemu) - -GRUB_BOOT_MACHINE_LINK_ADDR = 0xffe00 - -pkglib_IMAGES += boot.img -boot_img_SOURCES = boot/i386/qemu/boot.S -boot_img_ASFLAGS = $(COMMON_ASFLAGS) -DGRUB_BOOT_MACHINE_LINK_ADDR=$(GRUB_BOOT_MACHINE_LINK_ADDR) -boot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_BOOT_MACHINE_LINK_ADDR) -boot_img_FORMAT = binary - -bin_UTILITIES += grub-mkimage -grub_mkimage_SOURCES = util/grub-mkrawimage.c util/misc.c \ - util/resolve.c gnulib/progname.c -grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR) -util/grub-mkrawimage.c_DEPENDENCIES = Makefile - - -pkglib_IMAGES += kernel.img -kernel_img_SOURCES = kern/i386/qemu/startup.S \ - kern/i386/misc.S \ - kern/i386/coreboot/init.c \ - kern/i386/qemu/mmap.c \ - kern/i386/halt.c \ - kern/main.c kern/device.c \ - kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \ - kern/misc.c kern/mm.c kern/term.c \ - kern/rescue_parser.c kern/rescue_reader.c \ - kern/time.c kern/list.c kern/handler.c kern/command.c kern/corecmd.c \ - kern/$(target_cpu)/dl.c kern/parser.c kern/partition.c \ - kern/i386/tsc.c kern/i386/pit.c \ - kern/generic/rtc_get_time_ms.c \ - kern/generic/millisleep.c \ - kern/env.c \ - term/i386/pc/vga_text.c term/i386/vga_common.c \ - symlist.c -kernel_img_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ - env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \ - partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \ - machine/boot.h machine/console.h machine/init.h \ - machine/memory.h machine/loader.h list.h handler.h command.h i18n.h \ - env_private.h -kernel_img_CFLAGS = $(COMMON_CFLAGS) -DGRUB_BOOT_MACHINE_LINK_ADDR=$(GRUB_BOOT_MACHINE_LINK_ADDR) -kernel_img_ASFLAGS = $(COMMON_ASFLAGS) -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR) -kernel_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_KERNEL_MACHINE_LINK_ADDR) -kernel_img_FORMAT = binary -endif - MOSTLYCLEANFILES += symlist.c kernel_syms.lst DEFSYMFILES += kernel_syms.lst @@ -106,17 +55,7 @@ bin_SCRIPTS += grub-mkrescue grub_mkrescue_SOURCES = util/grub-mkrescue.in # Modules. -pkglib_MODULES = linux.mod \ - aout.mod play.mod serial.mod \ - memdisk.mod pci.mod lspci.mod reboot.mod \ - halt.mod datetime.mod date.mod datehook.mod \ - lsmmap.mod mmap.mod - -# For boot.mod. -pkglib_MODULES += boot.mod -boot_mod_SOURCES = commands/boot.c -boot_mod_CFLAGS = $(COMMON_CFLAGS) -boot_mod_LDFLAGS = $(COMMON_LDFLAGS) +pkglib_MODULES = linux.mod aout.mod halt.mod datetime.mod mmap.mod # For mmap.mod. mmap_mod_SOURCES = mmap/mmap.c mmap/i386/uppermem.c mmap/i386/mmap.c @@ -129,21 +68,11 @@ linux_mod_SOURCES = loader/i386/linux.c linux_mod_CFLAGS = $(COMMON_CFLAGS) linux_mod_LDFLAGS = $(COMMON_LDFLAGS) -# For reboot.mod. -reboot_mod_SOURCES = commands/reboot.c -reboot_mod_CFLAGS = $(COMMON_CFLAGS) -reboot_mod_LDFLAGS = $(COMMON_LDFLAGS) - # For halt.mod. halt_mod_SOURCES = commands/halt.c halt_mod_CFLAGS = $(COMMON_CFLAGS) halt_mod_LDFLAGS = $(COMMON_LDFLAGS) -# For serial.mod. -serial_mod_SOURCES = term/serial.c -serial_mod_CFLAGS = $(COMMON_CFLAGS) -serial_mod_LDFLAGS = $(COMMON_LDFLAGS) - # For aout.mod. aout_mod_SOURCES = loader/aout.c aout_mod_CFLAGS = $(COMMON_CFLAGS) @@ -156,45 +85,10 @@ bsd_mod_CFLAGS = $(COMMON_CFLAGS) bsd_mod_LDFLAGS = $(COMMON_LDFLAGS) bsd_mod_ASFLAGS = $(COMMON_ASFLAGS) -# For play.mod. -play_mod_SOURCES = commands/i386/pc/play.c -play_mod_CFLAGS = $(COMMON_CFLAGS) -play_mod_LDFLAGS = $(COMMON_LDFLAGS) - -# For memdisk.mod. -memdisk_mod_SOURCES = disk/memdisk.c -memdisk_mod_CFLAGS = $(COMMON_CFLAGS) -memdisk_mod_LDFLAGS = $(COMMON_LDFLAGS) - -# For pci.mod -pci_mod_SOURCES = bus/pci.c -pci_mod_CFLAGS = $(COMMON_CFLAGS) -pci_mod_LDFLAGS = $(COMMON_LDFLAGS) - -# For lspci.mod -lspci_mod_SOURCES = commands/lspci.c -lspci_mod_CFLAGS = $(COMMON_CFLAGS) -lspci_mod_LDFLAGS = $(COMMON_LDFLAGS) - # For datetime.mod datetime_mod_SOURCES = lib/cmos_datetime.c datetime_mod_CFLAGS = $(COMMON_CFLAGS) datetime_mod_LDFLAGS = $(COMMON_LDFLAGS) -# For date.mod -date_mod_SOURCES = commands/date.c -date_mod_CFLAGS = $(COMMON_CFLAGS) -date_mod_LDFLAGS = $(COMMON_LDFLAGS) - -# For datehook.mod -datehook_mod_SOURCES = hook/datehook.c -datehook_mod_CFLAGS = $(COMMON_CFLAGS) -datehook_mod_LDFLAGS = $(COMMON_LDFLAGS) - -# For lsmmap.mod -lsmmap_mod_SOURCES = commands/lsmmap.c -lsmmap_mod_CFLAGS = $(COMMON_CFLAGS) -lsmmap_mod_LDFLAGS = $(COMMON_LDFLAGS) - include $(srcdir)/conf/i386.mk include $(srcdir)/conf/common.mk diff --git a/conf/i386-efi.rmk b/conf/i386-efi.rmk index c03abb429..345350406 100644 --- a/conf/i386-efi.rmk +++ b/conf/i386-efi.rmk @@ -32,8 +32,8 @@ grub_install_SOURCES = util/i386/efi/grub-install.in # Modules. pkglib_PROGRAMS = kernel.img pkglib_MODULES = chain.mod appleldr.mod \ - linux.mod halt.mod reboot.mod pci.mod lspci.mod \ - datetime.mod date.mod datehook.mod loadbios.mod \ + linux.mod halt.mod \ + datetime.mod loadbios.mod \ fixvideo.mod mmap.mod acpi.mod # For kernel.img. @@ -68,12 +68,6 @@ symlist.c: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h gensymlist. kernel_syms.lst: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h genkernsyms.sh /bin/sh genkernsyms.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) -# For boot.mod. -pkglib_MODULES += boot.mod -boot_mod_SOURCES = commands/boot.c -boot_mod_CFLAGS = $(COMMON_CFLAGS) -boot_mod_LDFLAGS = $(COMMON_LDFLAGS) - # For acpi.mod. acpi_mod_SOURCES = commands/acpi.c commands/efi/acpi.c acpi_mod_CFLAGS = $(COMMON_CFLAGS) @@ -105,36 +99,11 @@ halt_mod_SOURCES = commands/halt.c halt_mod_CFLAGS = $(COMMON_CFLAGS) halt_mod_LDFLAGS = $(COMMON_LDFLAGS) -# For reboot.mod. -reboot_mod_SOURCES = commands/reboot.c -reboot_mod_CFLAGS = $(COMMON_CFLAGS) -reboot_mod_LDFLAGS = $(COMMON_LDFLAGS) - -# For pci.mod -pci_mod_SOURCES = bus/pci.c -pci_mod_CFLAGS = $(COMMON_CFLAGS) -pci_mod_LDFLAGS = $(COMMON_LDFLAGS) - -# For lspci.mod -lspci_mod_SOURCES = commands/lspci.c -lspci_mod_CFLAGS = $(COMMON_CFLAGS) -lspci_mod_LDFLAGS = $(COMMON_LDFLAGS) - # For datetime.mod datetime_mod_SOURCES = lib/efi/datetime.c datetime_mod_CFLAGS = $(COMMON_CFLAGS) datetime_mod_LDFLAGS = $(COMMON_LDFLAGS) -# For date.mod -date_mod_SOURCES = commands/date.c -date_mod_CFLAGS = $(COMMON_CFLAGS) -date_mod_LDFLAGS = $(COMMON_LDFLAGS) - -# For datehook.mod -datehook_mod_SOURCES = hook/datehook.c -datehook_mod_CFLAGS = $(COMMON_CFLAGS) -datehook_mod_LDFLAGS = $(COMMON_LDFLAGS) - # For loadbios.mod loadbios_mod_SOURCES = commands/efi/loadbios.c loadbios_mod_CFLAGS = $(COMMON_CFLAGS) diff --git a/conf/i386-ieee1275.rmk b/conf/i386-ieee1275.rmk index e19f6e9a1..6e5fd3055 100644 --- a/conf/i386-ieee1275.rmk +++ b/conf/i386-ieee1275.rmk @@ -54,16 +54,10 @@ sbin_SCRIPTS = grub-install grub_install_SOURCES = util/ieee1275/grub-install.in # Modules. -pkglib_MODULES = halt.mod reboot.mod suspend.mod \ - aout.mod serial.mod linux.mod \ - nand.mod memdisk.mod pci.mod lspci.mod datetime.mod \ - date.mod datehook.mod lsmmap.mod mmap.mod - -# For boot.mod. -pkglib_MODULES += boot.mod -boot_mod_SOURCES = commands/boot.c -boot_mod_CFLAGS = $(COMMON_CFLAGS) -boot_mod_LDFLAGS = $(COMMON_LDFLAGS) +pkglib_MODULES = halt.mod suspend.mod \ + aout.mod linux.mod \ + nand.mod datetime.mod \ + mmap.mod # For mmap.mod. mmap_mod_SOURCES = mmap/mmap.c mmap/i386/uppermem.c mmap/i386/mmap.c @@ -81,21 +75,11 @@ suspend_mod_SOURCES = commands/ieee1275/suspend.c suspend_mod_CFLAGS = $(COMMON_CFLAGS) suspend_mod_LDFLAGS = $(COMMON_LDFLAGS) -# For reboot.mod -reboot_mod_SOURCES = commands/reboot.c -reboot_mod_CFLAGS = $(COMMON_CFLAGS) -reboot_mod_LDFLAGS = $(COMMON_LDFLAGS) - # For halt.mod halt_mod_SOURCES = commands/halt.c halt_mod_CFLAGS = $(COMMON_CFLAGS) halt_mod_LDFLAGS = $(COMMON_LDFLAGS) -# For serial.mod. -serial_mod_SOURCES = term/serial.c -serial_mod_CFLAGS = $(COMMON_CFLAGS) -serial_mod_LDFLAGS = $(COMMON_LDFLAGS) - # For linux.mod. linux_mod_SOURCES = loader/i386/ieee1275/linux.c linux_mod_CFLAGS = $(COMMON_CFLAGS) @@ -106,40 +90,10 @@ nand_mod_SOURCES = disk/ieee1275/nand.c nand_mod_CFLAGS = $(COMMON_CFLAGS) nand_mod_LDFLAGS = $(COMMON_LDFLAGS) -# For memdisk.mod. -memdisk_mod_SOURCES = disk/memdisk.c -memdisk_mod_CFLAGS = $(COMMON_CFLAGS) -memdisk_mod_LDFLAGS = $(COMMON_LDFLAGS) - -# For pci.mod -pci_mod_SOURCES = bus/pci.c -pci_mod_CFLAGS = $(COMMON_CFLAGS) -pci_mod_LDFLAGS = $(COMMON_LDFLAGS) - -# For lspci.mod -lspci_mod_SOURCES = commands/lspci.c -lspci_mod_CFLAGS = $(COMMON_CFLAGS) -lspci_mod_LDFLAGS = $(COMMON_LDFLAGS) - # For datetime.mod datetime_mod_SOURCES = lib/cmos_datetime.c datetime_mod_CFLAGS = $(COMMON_CFLAGS) datetime_mod_LDFLAGS = $(COMMON_LDFLAGS) -# For date.mod -date_mod_SOURCES = commands/date.c -date_mod_CFLAGS = $(COMMON_CFLAGS) -date_mod_LDFLAGS = $(COMMON_LDFLAGS) - -# For datehook.mod -datehook_mod_SOURCES = hook/datehook.c -datehook_mod_CFLAGS = $(COMMON_CFLAGS) -datehook_mod_LDFLAGS = $(COMMON_LDFLAGS) - -# For lsmmap.mod -lsmmap_mod_SOURCES = commands/lsmmap.c -lsmmap_mod_CFLAGS = $(COMMON_CFLAGS) -lsmmap_mod_LDFLAGS = $(COMMON_LDFLAGS) - include $(srcdir)/conf/i386.mk include $(srcdir)/conf/common.mk diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk index 580bfea0a..b30863812 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -107,7 +107,7 @@ grub_setup_SOURCES = gnulib/progname.c \ partmap/msdos.c partmap/gpt.c \ \ disk/raid.c disk/mdraid_linux.c disk/lvm.c \ - util/raid.c util/lvm.c \ + util/raid.c util/lvm.c \ grub_setup_init.c sbin_SCRIPTS += grub-install @@ -117,20 +117,14 @@ bin_SCRIPTS += grub-mkrescue grub_mkrescue_SOURCES = util/grub-mkrescue.in pkglib_MODULES = biosdisk.mod chain.mod \ - reboot.mod halt.mod \ - vbe.mod vbetest.mod vbeinfo.mod play.mod serial.mod \ - vga.mod memdisk.mod pci.mod lspci.mod \ - aout.mod bsd.mod pxe.mod pxecmd.mod datetime.mod date.mod \ - datehook.mod lsmmap.mod ata_pthru.mod hdparm.mod \ + halt.mod \ + vbe.mod vbetest.mod vbeinfo.mod \ + vga.mod \ + aout.mod bsd.mod pxe.mod pxecmd.mod datetime.mod \ + ata_pthru.mod hdparm.mod \ usb.mod uhci.mod ohci.mod usbtest.mod usbms.mod usb_keyboard.mod \ efiemu.mod mmap.mod acpi.mod drivemap.mod -# For boot.mod. -pkglib_MODULES += boot.mod -boot_mod_SOURCES = commands/boot.c lib/i386/pc/biosnum.c -boot_mod_CFLAGS = $(COMMON_CFLAGS) -boot_mod_LDFLAGS = $(COMMON_LDFLAGS) - # For drivemap.mod. drivemap_mod_SOURCES = commands/i386/pc/drivemap.c \ commands/i386/pc/drivemap_int13h.S @@ -187,21 +181,11 @@ xnu_mod_CFLAGS = $(COMMON_CFLAGS) xnu_mod_LDFLAGS = $(COMMON_LDFLAGS) xnu_mod_ASFLAGS = $(COMMON_ASFLAGS) -# For reboot.mod. -reboot_mod_SOURCES = commands/reboot.c -reboot_mod_CFLAGS = $(COMMON_CFLAGS) -reboot_mod_LDFLAGS = $(COMMON_LDFLAGS) - # For halt.mod. halt_mod_SOURCES = commands/i386/pc/halt.c halt_mod_CFLAGS = $(COMMON_CFLAGS) halt_mod_LDFLAGS = $(COMMON_LDFLAGS) -# For serial.mod. -serial_mod_SOURCES = term/serial.c -serial_mod_CFLAGS = $(COMMON_CFLAGS) -serial_mod_LDFLAGS = $(COMMON_LDFLAGS) - # For vbe.mod. vbe_mod_SOURCES = video/i386/pc/vbe.c vbe_mod_CFLAGS = $(COMMON_CFLAGS) @@ -217,31 +201,11 @@ vbetest_mod_SOURCES = commands/i386/pc/vbetest.c vbetest_mod_CFLAGS = $(COMMON_CFLAGS) vbetest_mod_LDFLAGS = $(COMMON_LDFLAGS) -# For play.mod. -play_mod_SOURCES = commands/i386/pc/play.c -play_mod_CFLAGS = $(COMMON_CFLAGS) -play_mod_LDFLAGS = $(COMMON_LDFLAGS) - # For vga.mod. vga_mod_SOURCES = term/i386/pc/vga.c vga_mod_CFLAGS = $(COMMON_CFLAGS) vga_mod_LDFLAGS = $(COMMON_LDFLAGS) -# For memdisk.mod. -memdisk_mod_SOURCES = disk/memdisk.c -memdisk_mod_CFLAGS = $(COMMON_CFLAGS) -memdisk_mod_LDFLAGS = $(COMMON_LDFLAGS) - -# For pci.mod -pci_mod_SOURCES = bus/pci.c -pci_mod_CFLAGS = $(COMMON_CFLAGS) -pci_mod_LDFLAGS = $(COMMON_LDFLAGS) - -# For lspci.mod -lspci_mod_SOURCES = commands/lspci.c -lspci_mod_CFLAGS = $(COMMON_CFLAGS) -lspci_mod_LDFLAGS = $(COMMON_LDFLAGS) - # For aout.mod aout_mod_SOURCES = loader/aout.c aout_mod_CFLAGS = $(COMMON_CFLAGS) @@ -298,21 +262,6 @@ datetime_mod_SOURCES = lib/cmos_datetime.c datetime_mod_CFLAGS = $(COMMON_CFLAGS) datetime_mod_LDFLAGS = $(COMMON_LDFLAGS) -# For date.mod -date_mod_SOURCES = commands/date.c -date_mod_CFLAGS = $(COMMON_CFLAGS) -date_mod_LDFLAGS = $(COMMON_LDFLAGS) - -# For datehook.mod -datehook_mod_SOURCES = hook/datehook.c -datehook_mod_CFLAGS = $(COMMON_CFLAGS) -datehook_mod_LDFLAGS = $(COMMON_LDFLAGS) - -# For lsmmap.mod -lsmmap_mod_SOURCES = commands/lsmmap.c -lsmmap_mod_CFLAGS = $(COMMON_CFLAGS) -lsmmap_mod_LDFLAGS = $(COMMON_LDFLAGS) - # For ata_pthru.mod. ata_pthru_mod_SOURCES = disk/ata_pthru.c ata_pthru_mod_CFLAGS = $(COMMON_CFLAGS) diff --git a/conf/i386-qemu.rmk b/conf/i386-qemu.rmk index 573a5d0f3..17e4f1129 100644 --- a/conf/i386-qemu.rmk +++ b/conf/i386-qemu.rmk @@ -1,2 +1,108 @@ # -*- makefile -*- -include $(srcdir)/conf/i386-coreboot.mk + +COMMON_ASFLAGS = -nostdinc -fno-builtin -m32 +COMMON_CFLAGS = -fno-builtin -mrtd -mregparm=3 -m32 +COMMON_LDFLAGS = -m32 -nostdlib + +# Used by various components. These rules need to precede them. +script/lexer.c_DEPENDENCIES = grub_script.tab.h + +# Images. + +GRUB_KERNEL_MACHINE_LINK_ADDR = 0x8200 +GRUB_BOOT_MACHINE_LINK_ADDR = 0xffe00 + +pkglib_IMAGES += boot.img +boot_img_SOURCES = boot/i386/qemu/boot.S +boot_img_ASFLAGS = $(COMMON_ASFLAGS) -DGRUB_BOOT_MACHINE_LINK_ADDR=$(GRUB_BOOT_MACHINE_LINK_ADDR) +boot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_BOOT_MACHINE_LINK_ADDR) +boot_img_FORMAT = binary + +bin_UTILITIES += grub-mkimage +grub_mkimage_SOURCES = util/grub-mkrawimage.c util/misc.c \ + util/resolve.c gnulib/progname.c +grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR) +util/grub-mkrawimage.c_DEPENDENCIES = Makefile + +pkglib_IMAGES += kernel.img +kernel_img_SOURCES = kern/i386/qemu/startup.S \ + kern/i386/misc.S \ + kern/i386/coreboot/init.c \ + kern/i386/qemu/mmap.c \ + kern/i386/halt.c \ + kern/main.c kern/device.c \ + kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \ + kern/misc.c kern/mm.c kern/term.c \ + kern/rescue_parser.c kern/rescue_reader.c \ + kern/time.c kern/list.c kern/handler.c kern/command.c kern/corecmd.c \ + kern/$(target_cpu)/dl.c kern/parser.c kern/partition.c \ + kern/i386/tsc.c kern/i386/pit.c \ + kern/generic/rtc_get_time_ms.c \ + kern/generic/millisleep.c \ + kern/env.c \ + term/i386/pc/vga_text.c term/i386/vga_common.c \ + symlist.c +kernel_img_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ + env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \ + partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \ + machine/boot.h machine/console.h machine/init.h \ + machine/memory.h machine/loader.h list.h handler.h command.h i18n.h \ + env_private.h +kernel_img_CFLAGS = $(COMMON_CFLAGS) -DGRUB_BOOT_MACHINE_LINK_ADDR=$(GRUB_BOOT_MACHINE_LINK_ADDR) +kernel_img_ASFLAGS = $(COMMON_ASFLAGS) -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR) +kernel_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_KERNEL_MACHINE_LINK_ADDR) +kernel_img_FORMAT = binary + +MOSTLYCLEANFILES += symlist.c kernel_syms.lst +DEFSYMFILES += kernel_syms.lst + +symlist.c: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h gensymlist.sh + /bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) + +kernel_syms.lst: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h genkernsyms.sh + /bin/sh genkernsyms.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) + +sbin_SCRIPTS += grub-install +grub_install_SOURCES = util/grub-install.in + +bin_SCRIPTS += grub-mkrescue +grub_mkrescue_SOURCES = util/grub-mkrescue.in + +# Modules. +pkglib_MODULES = linux.mod aout.mod halt.mod datetime.mod mmap.mod + +# For mmap.mod. +mmap_mod_SOURCES = mmap/mmap.c mmap/i386/uppermem.c mmap/i386/mmap.c +mmap_mod_CFLAGS = $(COMMON_CFLAGS) +mmap_mod_LDFLAGS = $(COMMON_LDFLAGS) +mmap_mod_ASFLAGS = $(COMMON_ASFLAGS) + +# For linux.mod. +linux_mod_SOURCES = loader/i386/linux.c +linux_mod_CFLAGS = $(COMMON_CFLAGS) +linux_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For halt.mod. +halt_mod_SOURCES = commands/halt.c +halt_mod_CFLAGS = $(COMMON_CFLAGS) +halt_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For aout.mod. +aout_mod_SOURCES = loader/aout.c +aout_mod_CFLAGS = $(COMMON_CFLAGS) +aout_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For bsd.mod +pkglib_MODULES += bsd.mod +bsd_mod_SOURCES = loader/i386/bsd.c loader/i386/bsd32.c loader/i386/bsd64.c loader/i386/bsd_helper.S loader/i386/bsd_trampoline.S +bsd_mod_CFLAGS = $(COMMON_CFLAGS) +bsd_mod_LDFLAGS = $(COMMON_LDFLAGS) +bsd_mod_ASFLAGS = $(COMMON_ASFLAGS) + +# For datetime.mod +datetime_mod_SOURCES = lib/cmos_datetime.c +datetime_mod_CFLAGS = $(COMMON_CFLAGS) +datetime_mod_LDFLAGS = $(COMMON_LDFLAGS) + +include $(srcdir)/conf/i386.mk +include $(srcdir)/conf/common.mk diff --git a/conf/i386.rmk b/conf/i386.rmk index d240858fe..86b6fd795 100644 --- a/conf/i386.rmk +++ b/conf/i386.rmk @@ -47,3 +47,28 @@ multiboot2_mod_SOURCES = loader/i386/multiboot.c \ multiboot2_mod_CFLAGS = $(COMMON_CFLAGS) -DGRUB_USE_MULTIBOOT2 multiboot2_mod_LDFLAGS = $(COMMON_LDFLAGS) multiboot2_mod_ASFLAGS = $(COMMON_ASFLAGS) + +# For serial.mod. +pkglib_MODULES += serial.mod +serial_mod_SOURCES = term/serial.c +serial_mod_CFLAGS = $(COMMON_CFLAGS) +serial_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For pci.mod +pkglib_MODULES += pci.mod +pci_mod_SOURCES = bus/pci.c +pci_mod_CFLAGS = $(COMMON_CFLAGS) +pci_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For lspci.mod +pkglib_MODULES += lspci.mod +lspci_mod_SOURCES = commands/lspci.c +lspci_mod_CFLAGS = $(COMMON_CFLAGS) +lspci_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For play.mod. +pkglib_MODULES += play.mod +play_mod_SOURCES = commands/i386/pc/play.c +play_mod_CFLAGS = $(COMMON_CFLAGS) +play_mod_LDFLAGS = $(COMMON_LDFLAGS) + diff --git a/conf/mips-yeeloong.rmk b/conf/mips-yeeloong.rmk index eb0dc9676..d5e1d1c5d 100644 --- a/conf/mips-yeeloong.rmk +++ b/conf/mips-yeeloong.rmk @@ -61,19 +61,6 @@ datetime_mod_SOURCES = lib/cmos_datetime.c datetime_mod_CFLAGS = $(COMMON_CFLAGS) datetime_mod_LDFLAGS = $(COMMON_LDFLAGS) -# For date.mod -pkglib_MODULES += date.mod -date_mod_SOURCES = commands/date.c -date_mod_CFLAGS = $(COMMON_CFLAGS) -date_mod_LDFLAGS = $(COMMON_LDFLAGS) - -# For datehook.mod -pkglib_MODULES += datehook.mod -datehook_mod_SOURCES = hook/datehook.c -datehook_mod_CFLAGS = $(COMMON_CFLAGS) -datehook_mod_LDFLAGS = $(COMMON_LDFLAGS) - - sbin_SCRIPTS += grub-install grub_install_SOURCES = util/grub-install.in diff --git a/conf/mips.rmk b/conf/mips.rmk index 1ef4fc395..e04b0adf2 100644 --- a/conf/mips.rmk +++ b/conf/mips.rmk @@ -40,26 +40,6 @@ grub_mkimage_SOURCES = gnulib/progname.c util/grub-mkrawimage.c util/misc.c \ grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(LINK_BASE) util/grub-mkrawimage.c_DEPENDENCIES = Makefile -# Modules. -pkglib_MODULES = memdisk.mod \ - lsmmap.mod - -# For boot.mod. -pkglib_MODULES += boot.mod -boot_mod_SOURCES = commands/boot.c lib/i386/pc/biosnum.c -boot_mod_CFLAGS = $(COMMON_CFLAGS) -boot_mod_LDFLAGS = $(COMMON_LDFLAGS) - -# For memdisk.mod. -memdisk_mod_SOURCES = disk/memdisk.c -memdisk_mod_CFLAGS = $(COMMON_CFLAGS) -memdisk_mod_LDFLAGS = $(COMMON_LDFLAGS) - -# For lsmmap.mod -lsmmap_mod_SOURCES = commands/lsmmap.c -lsmmap_mod_CFLAGS = $(COMMON_CFLAGS) -lsmmap_mod_LDFLAGS = $(COMMON_LDFLAGS) - # For serial.mod. pkglib_MODULES += serial.mod serial_mod_SOURCES = term/serial.c diff --git a/conf/powerpc-ieee1275.rmk b/conf/powerpc-ieee1275.rmk index 73e56e66f..a22c38ec1 100644 --- a/conf/powerpc-ieee1275.rmk +++ b/conf/powerpc-ieee1275.rmk @@ -57,69 +57,33 @@ grub_install_SOURCES = util/ieee1275/grub-install.in grub_mkrescue_SOURCES = util/powerpc/ieee1275/grub-mkrescue.in # Modules. -pkglib_MODULES = halt.mod \ - linux.mod \ - reboot.mod \ - suspend.mod \ - memdisk.mod \ - lsmmap.mod - -# For boot.mod. -pkglib_MODULES += boot.mod -boot_mod_SOURCES = commands/boot.c lib/i386/pc/biosnum.c -boot_mod_CFLAGS = $(COMMON_CFLAGS) -boot_mod_LDFLAGS = $(COMMON_LDFLAGS) - pkglib_MODULES += ieee1275_fb.mod ieee1275_fb_mod_SOURCES = video/ieee1275.c ieee1275_fb_mod_CFLAGS = $(COMMON_CFLAGS) ieee1275_fb_mod_LDFLAGS = $(COMMON_LDFLAGS) # For linux.mod. +pkglib_MODULES += linux.mod linux_mod_SOURCES = loader/powerpc/ieee1275/linux.c linux_mod_CFLAGS = $(COMMON_CFLAGS) linux_mod_LDFLAGS = $(COMMON_LDFLAGS) # For suspend.mod +pkglib_MODULES += suspend.mod suspend_mod_SOURCES = commands/ieee1275/suspend.c suspend_mod_CFLAGS = $(COMMON_CFLAGS) suspend_mod_LDFLAGS = $(COMMON_LDFLAGS) -# For reboot.mod -reboot_mod_SOURCES = commands/reboot.c -reboot_mod_CFLAGS = $(COMMON_CFLAGS) -reboot_mod_LDFLAGS = $(COMMON_LDFLAGS) - # For halt.mod +pkglib_MODULES += halt.mod halt_mod_SOURCES = commands/halt.c halt_mod_CFLAGS = $(COMMON_CFLAGS) halt_mod_LDFLAGS = $(COMMON_LDFLAGS) -# For memdisk.mod. -memdisk_mod_SOURCES = disk/memdisk.c -memdisk_mod_CFLAGS = $(COMMON_CFLAGS) -memdisk_mod_LDFLAGS = $(COMMON_LDFLAGS) - -# For lsmmap.mod -lsmmap_mod_SOURCES = commands/lsmmap.c -lsmmap_mod_CFLAGS = $(COMMON_CFLAGS) -lsmmap_mod_LDFLAGS = $(COMMON_LDFLAGS) - -pkglib_MODULES += datetime.mod date.mod datehook.mod - # For datetime.mod +pkglib_MODULES += datetime.mod datetime_mod_SOURCES = lib/ieee1275/datetime.c datetime_mod_CFLAGS = $(COMMON_CFLAGS) datetime_mod_LDFLAGS = $(COMMON_LDFLAGS) -# For date.mod -date_mod_SOURCES = commands/date.c -date_mod_CFLAGS = $(COMMON_CFLAGS) -date_mod_LDFLAGS = $(COMMON_LDFLAGS) - -# For datehook.mod -datehook_mod_SOURCES = hook/datehook.c -datehook_mod_CFLAGS = $(COMMON_CFLAGS) -datehook_mod_LDFLAGS = $(COMMON_LDFLAGS) - include $(srcdir)/conf/common.mk diff --git a/conf/sparc64-ieee1275.rmk b/conf/sparc64-ieee1275.rmk index 6210826e2..69ed325b2 100644 --- a/conf/sparc64-ieee1275.rmk +++ b/conf/sparc64-ieee1275.rmk @@ -82,7 +82,7 @@ grub_setup_SOURCES = util/sparc64/ieee1275/grub-setup.c util/hostdisk.c \ partmap/sun.c partmap/acorn.c \ \ disk/raid.c disk/mdraid_linux.c disk/lvm.c \ - util/raid.c util/lvm.c gnulib/progname.c \ + util/raid.c util/lvm.c gnulib/progname.c \ grub_setup_init.c # For grub-ofpathname. @@ -96,58 +96,27 @@ sbin_SCRIPTS = grub-install grub_install_SOURCES = util/grub-install.in # Modules. -pkglib_MODULES = halt.mod \ - linux.mod \ - reboot.mod \ - memdisk.mod \ - lsmmap.mod - -# For boot.mod. -pkglib_MODULES += boot.mod -boot_mod_SOURCES = commands/boot.c lib/i386/pc/biosnum.c -boot_mod_CFLAGS = $(COMMON_CFLAGS) -boot_mod_LDFLAGS = $(COMMON_LDFLAGS) +pkglib_MODULES += ieee1275_fb.mod +ieee1275_fb_mod_SOURCES = video/ieee1275.c +ieee1275_fb_mod_CFLAGS = $(COMMON_CFLAGS) +ieee1275_fb_mod_LDFLAGS = $(COMMON_LDFLAGS) # For linux.mod. +pkglib_MODULES += linux.mod linux_mod_SOURCES = loader/sparc64/ieee1275/linux.c linux_mod_CFLAGS = $(COMMON_CFLAGS) linux_mod_LDFLAGS = $(COMMON_LDFLAGS) -# For reboot.mod. -reboot_mod_SOURCES = commands/reboot.c -reboot_mod_CFLAGS = $(COMMON_CFLAGS) -reboot_mod_LDFLAGS = $(COMMON_LDFLAGS) - # For halt.mod. +pkglib_MODULES += halt.mod halt_mod_SOURCES = commands/halt.c halt_mod_CFLAGS = $(COMMON_CFLAGS) halt_mod_LDFLAGS = $(COMMON_LDFLAGS) -# For memdisk.mod. -memdisk_mod_SOURCES = disk/memdisk.c -memdisk_mod_CFLAGS = $(COMMON_CFLAGS) -memdisk_mod_LDFLAGS = $(COMMON_LDFLAGS) - -# For lsmmap.mod -lsmmap_mod_SOURCES = commands/lsmmap.c -lsmmap_mod_CFLAGS = $(COMMON_CFLAGS) -lsmmap_mod_LDFLAGS = $(COMMON_LDFLAGS) - -pkglib_MODULES += datetime.mod date.mod datehook.mod - # For datetime.mod +pkglib_MODULES += datetime.mod datetime_mod_SOURCES = lib/ieee1275/datetime.c datetime_mod_CFLAGS = $(COMMON_CFLAGS) datetime_mod_LDFLAGS = $(COMMON_LDFLAGS) -# For date.mod -date_mod_SOURCES = commands/date.c -date_mod_CFLAGS = $(COMMON_CFLAGS) -date_mod_LDFLAGS = $(COMMON_LDFLAGS) - -# For datehook.mod -datehook_mod_SOURCES = hook/datehook.c -datehook_mod_CFLAGS = $(COMMON_CFLAGS) -datehook_mod_LDFLAGS = $(COMMON_LDFLAGS) - include $(srcdir)/conf/common.mk diff --git a/conf/x86_64-efi.rmk b/conf/x86_64-efi.rmk index d5c3c24cb..4116894f4 100644 --- a/conf/x86_64-efi.rmk +++ b/conf/x86_64-efi.rmk @@ -31,8 +31,8 @@ grub_install_SOURCES = util/i386/efi/grub-install.in # Modules. pkglib_PROGRAMS = kernel.img pkglib_MODULES = chain.mod appleldr.mod \ - halt.mod reboot.mod linux.mod pci.mod lspci.mod \ - datetime.mod date.mod datehook.mod loadbios.mod \ + halt.mod linux.mod \ + datetime.mod loadbios.mod \ fixvideo.mod mmap.mod acpi.mod # For kernel.img. @@ -67,12 +67,6 @@ symlist.c: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h gensymlist. kernel_syms.lst: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h genkernsyms.sh /bin/sh genkernsyms.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) -# For boot.mod. -pkglib_MODULES += boot.mod -boot_mod_SOURCES = commands/boot.c lib/i386/pc/biosnum.c -boot_mod_CFLAGS = $(COMMON_CFLAGS) -boot_mod_LDFLAGS = $(COMMON_LDFLAGS) - # For acpi.mod. acpi_mod_SOURCES = commands/acpi.c commands/efi/acpi.c acpi_mod_CFLAGS = $(COMMON_CFLAGS) @@ -105,36 +99,11 @@ halt_mod_SOURCES = commands/halt.c halt_mod_CFLAGS = $(COMMON_CFLAGS) halt_mod_LDFLAGS = $(COMMON_LDFLAGS) -# For reboot.mod. -reboot_mod_SOURCES = commands/reboot.c -reboot_mod_CFLAGS = $(COMMON_CFLAGS) -reboot_mod_LDFLAGS = $(COMMON_LDFLAGS) - -# For pci.mod -pci_mod_SOURCES = bus/pci.c -pci_mod_CFLAGS = $(COMMON_CFLAGS) -pci_mod_LDFLAGS = $(COMMON_LDFLAGS) - -# For lspci.mod -lspci_mod_SOURCES = commands/lspci.c -lspci_mod_CFLAGS = $(COMMON_CFLAGS) -lspci_mod_LDFLAGS = $(COMMON_LDFLAGS) - # For datetime.mod datetime_mod_SOURCES = lib/efi/datetime.c datetime_mod_CFLAGS = $(COMMON_CFLAGS) datetime_mod_LDFLAGS = $(COMMON_LDFLAGS) -# For date.mod -date_mod_SOURCES = commands/date.c -date_mod_CFLAGS = $(COMMON_CFLAGS) -date_mod_LDFLAGS = $(COMMON_LDFLAGS) - -# For datehook.mod -datehook_mod_SOURCES = hook/datehook.c -datehook_mod_CFLAGS = $(COMMON_CFLAGS) -datehook_mod_LDFLAGS = $(COMMON_LDFLAGS) - # For loadbios.mod loadbios_mod_SOURCES = commands/efi/loadbios.c loadbios_mod_CFLAGS = $(COMMON_CFLAGS) diff --git a/disk/memdisk.c b/disk/memdisk.c index 4a0470837..2e8885020 100644 --- a/disk/memdisk.c +++ b/disk/memdisk.c @@ -23,7 +23,6 @@ #include #include #include -#include static char *memdisk_addr; static grub_off_t memdisk_size = 0; diff --git a/hook/datehook.c b/hook/datehook.c index 4876e1198..9b5b54bf3 100644 --- a/hook/datehook.c +++ b/hook/datehook.c @@ -84,7 +84,7 @@ grub_read_hook_datetime (struct grub_env_var *var, return buf; } -GRUB_MOD_INIT(datetime) +GRUB_MOD_INIT(datehook) { int i; @@ -93,7 +93,7 @@ GRUB_MOD_INIT(datetime) grub_read_hook_datetime, 0); } -GRUB_MOD_FINI(datetime) +GRUB_MOD_FINI(datehook) { int i; diff --git a/include/grub/datetime.h b/include/grub/datetime.h index 2dbba55e2..e721e89af 100644 --- a/include/grub/datetime.h +++ b/include/grub/datetime.h @@ -33,10 +33,17 @@ struct grub_datetime }; /* Return date and time. */ +#ifdef GRUB_MACHINE_EMU +grub_err_t EXPORT_FUNC(grub_get_datetime) (struct grub_datetime *datetime); + +/* Set date and time. */ +grub_err_t EXPORT_FUNC(grub_set_datetime) (struct grub_datetime *datetime); +#else grub_err_t grub_get_datetime (struct grub_datetime *datetime); /* Set date and time. */ grub_err_t grub_set_datetime (struct grub_datetime *datetime); +#endif int grub_get_weekday (struct grub_datetime *datetime); char *grub_get_weekday_name (struct grub_datetime *datetime); diff --git a/include/grub/i386/efi/serial.h b/include/grub/i386/efi/serial.h new file mode 100644 index 000000000..2d8563414 --- /dev/null +++ b/include/grub/i386/efi/serial.h @@ -0,0 +1 @@ +#include diff --git a/include/grub/x86_64/efi/serial.h b/include/grub/x86_64/efi/serial.h new file mode 100644 index 000000000..2d8563414 --- /dev/null +++ b/include/grub/x86_64/efi/serial.h @@ -0,0 +1 @@ +#include diff --git a/util/time.c b/util/time.c new file mode 100644 index 000000000..5da8092a9 --- /dev/null +++ b/util/time.c @@ -0,0 +1,46 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include + +grub_err_t +grub_get_datetime (struct grub_datetime *datetime) +{ + struct tm *mytm; + time_t mytime; + + mytime = time (&mytime); + mytm = gmtime (&mytime); + + datetime->year = mytm->tm_year + 1900; + datetime->month = mytm->tm_mon + 1; + datetime->day = mytm->tm_mday; + datetime->hour = mytm->tm_hour; + datetime->minute = mytm->tm_min; + datetime->second = mytm->tm_sec; + + return GRUB_ERR_NONE; +} + +grub_err_t +grub_set_datetime (struct grub_datetime *datetime __attribute__ ((unused))) +{ + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "no clock setting routine available"); +} diff --git a/video/ieee1275.c b/video/ieee1275.c index 21b65bd32..0cf47a1a8 100644 --- a/video/ieee1275.c +++ b/video/ieee1275.c @@ -124,7 +124,8 @@ grub_video_ieee1275_setup (unsigned int width, unsigned int height, unsigned int mode_type __attribute__ ((unused)), unsigned int mode_mask __attribute__ ((unused))) { - grub_uint32_t current_width, current_height, address; + grub_uint32_t current_width, current_height; + grub_addr_t address; grub_err_t err; grub_ieee1275_phandle_t dev; @@ -162,7 +163,7 @@ grub_video_ieee1275_setup (unsigned int width, unsigned int height, return err; } - if (grub_ieee1275_get_integer_property (dev, "address", &address, + if (grub_ieee1275_get_integer_property (dev, "address", (void *) &address, sizeof (address), 0)) return grub_error (GRUB_ERR_IO, "Couldn't retrieve display address."); From 660960d6972a1ea59f2fb23fbadd2529b5a72620 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 9 Feb 2010 14:09:08 +0100 Subject: [PATCH 380/738] 2010-02-09 Vladimir Serbinenko * configure.ac: Check for ft2build.h. --- ChangeLog | 4 ++++ configure.ac | 10 ++++++++++ 2 files changed, 14 insertions(+) diff --git a/ChangeLog b/ChangeLog index ff8f3d41c..793018ca9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-02-09 Vladimir Serbinenko + + * configure.ac: Check for ft2build.h. + 2010-02-07 Vladimir Serbinenko * kern/ieee1275/openfw.c (grub_halt): Try executing "poweroff". diff --git a/configure.ac b/configure.ac index b4323e24f..48702afd6 100644 --- a/configure.ac +++ b/configure.ac @@ -679,6 +679,16 @@ if test x"$grub_mkfont_excuse" = x ; then freetype_cflags=`freetype-config --cflags` freetype_libs=`freetype-config --libs` fi + +if test x"$grub_mkfont_excuse" = x ; then + # Check for freetype libraries. + SAVED_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $freetype_cflags" + AC_CHECK_HEADERS([ft2build.h], [], + [grub_mkfont_excuse=["need freetype2 headers"]]) + CFLAGS="$SAVED_CFLAGS" +fi + if test x"$enable_grub_mkfont" = xyes && test x"$grub_mkfont_excuse" != x ; then AC_MSG_ERROR([grub-mkfont was explicitly requested but can't be compiled]) fi From 2d2a9cd5b6c3b886efc73213a53726ab50f1c3a9 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 9 Feb 2010 15:32:42 +0100 Subject: [PATCH 381/738] GRUB_FILE implementation --- ChangeLog.grub-file | 13 +++++++++++++ fs/reiserfs.c | 2 +- genmk.rb | 10 +++++----- include/grub/list.h | 2 +- include/grub/misc.h | 2 +- include/grub/mm.h | 10 +++++----- include/grub/test.h | 2 +- kern/mm.c | 2 +- lib/libgcrypt_wrap/cipher_wrap.h | 2 +- 9 files changed, 29 insertions(+), 16 deletions(-) create mode 100644 ChangeLog.grub-file diff --git a/ChangeLog.grub-file b/ChangeLog.grub-file new file mode 100644 index 000000000..6b3126a16 --- /dev/null +++ b/ChangeLog.grub-file @@ -0,0 +1,13 @@ +2010-02-09 Vladimir Serbinenko + + Don't use __FILE__. + + * genmk.rb: Add -DGRUB_FILE to all C targets. + * fs/reiserfs.c: Replace __FILE__ with GRUB_FILE. + * include/grub/list.h: Likewise. + * include/grub/misc.h: Likewise. + * include/grub/mm.h: Likewise. + * include/grub/test.h: Likewise. + * kern/mm.c: Likewise. + * lib/libgcrypt_wrap/cipher_wrap.h: Likewise. + diff --git a/fs/reiserfs.c b/fs/reiserfs.c index c3db52f60..5acd339c5 100644 --- a/fs/reiserfs.c +++ b/fs/reiserfs.c @@ -62,7 +62,7 @@ static grub_dl_t my_mod; -#define assert(boolean) real_assert (boolean, __FILE__, __LINE__) +#define assert(boolean) real_assert (boolean, GRUB_FILE, __LINE__) static inline void real_assert (int boolean, const char *file, const int line) { diff --git a/genmk.rb b/genmk.rb index df03e1dfe..ac5252412 100644 --- a/genmk.rb +++ b/genmk.rb @@ -91,7 +91,7 @@ endif dir = File.dirname(src) "#{obj}: #{src} $(#{src}_DEPENDENCIES) - $(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) #{extra_flags} $(TARGET_#{flag}) $(#{prefix}_#{flag}) -MD -c -o $@ $< + $(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) #{extra_flags} $(TARGET_#{flag}) $(#{prefix}_#{flag}) -DGRUB_FILE=\\\"#{src}\\\" -MD -c -o $@ $< -include #{dep} " @@ -163,7 +163,7 @@ endif $(TARGET_CC) $(#{prefix}_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ #{objs_str} #{mod_obj}: #{mod_src} - $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(#{prefix}_CFLAGS) -c -o $@ $< + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(#{prefix}_CFLAGS) -DGRUB_FILE=\\\"#{mod_src}\\\" -c -o $@ $< #{mod_src}: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh sh $(srcdir)/genmodsrc.sh '#{mod_name}' $< > $@ || (rm -f $@; exit 1) @@ -197,7 +197,7 @@ endif dir = File.dirname(src) "#{obj}: #{src} $(#{src}_DEPENDENCIES) - $(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) #{extra_flags} $(TARGET_#{flag}) $(#{prefix}_#{flag}) -MD -c -o $@ $< + $(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) #{extra_flags} $(TARGET_#{flag}) $(#{prefix}_#{flag}) -DGRUB_FILE=\\\"#{src}\\\" -MD -c -o $@ $< -include #{dep} clean-module-#{extra_target}.#{@rule_count}: @@ -299,7 +299,7 @@ MOSTLYCLEAN_UTILITY_TARGETS += mostlyclean-utility-#{@name}.#{@rule_count} dir = File.dirname(src) "#{obj}: #{src} $(#{src}_DEPENDENCIES) - $(CC) -I#{dir} -I$(srcdir)/#{dir} $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(#{prefix}_CFLAGS) -MD -c -o $@ $< + $(CC) -I#{dir} -I$(srcdir)/#{dir} $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(#{prefix}_CFLAGS) -DGRUB_FILE=\\\"#{src}\\\" -MD -c -o $@ $< -include #{dep} " @@ -346,7 +346,7 @@ endif dir = File.dirname(src) "#{obj}: #{src} $(#{src}_DEPENDENCIES) - $(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) #{extra_flags} $(TARGET_#{flag}) $(#{prefix}_#{flag}) -MD -c -o $@ $< + $(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) #{extra_flags} $(TARGET_#{flag}) $(#{prefix}_#{flag}) -DGRUB_FILE=\\\"#{src}\\\" -MD -c -o $@ $< -include #{dep} diff --git a/include/grub/list.h b/include/grub/list.h index b7703e214..5559158dc 100644 --- a/include/grub/list.h +++ b/include/grub/list.h @@ -52,7 +52,7 @@ grub_bad_type_cast_real (int line, const char *file) return 0; } -#define grub_bad_type_cast() grub_bad_type_cast_real(__LINE__, __FILE__) +#define grub_bad_type_cast() grub_bad_type_cast_real(__LINE__, GRUB_FILE) #define GRUB_FIELD_MATCH(ptr, type, field) \ ((char *) &(ptr)->field == (char *) &((type) (ptr))->field) diff --git a/include/grub/misc.h b/include/grub/misc.h index dcbafba87..5b1477ed4 100644 --- a/include/grub/misc.h +++ b/include/grub/misc.h @@ -46,7 +46,7 @@ #define ARRAY_SIZE(array) (sizeof (array) / sizeof (array[0])) #define COMPILE_TIME_ASSERT(cond) switch (0) { case 1: case !(cond): ; } -#define grub_dprintf(condition, fmt, args...) grub_real_dprintf(__FILE__, __LINE__, condition, fmt, ## args) +#define grub_dprintf(condition, fmt, args...) grub_real_dprintf(GRUB_FILE, __LINE__, condition, fmt, ## args) /* XXX: If grub_memmove is too slow, we must implement grub_memcpy. */ #define grub_memcpy(d,s,n) grub_memmove ((d), (s), (n)) diff --git a/include/grub/mm.h b/include/grub/mm.h index 4caf80511..acefd2ea7 100644 --- a/include/grub/mm.h +++ b/include/grub/mm.h @@ -44,19 +44,19 @@ void grub_mm_dump_free (void); void grub_mm_dump (unsigned lineno); #define grub_malloc(size) \ - grub_debug_malloc (__FILE__, __LINE__, size) + grub_debug_malloc (GRUB_FILE, __LINE__, size) #define grub_zalloc(size) \ - grub_debug_zalloc (__FILE__, __LINE__, size) + grub_debug_zalloc (GRUB_FILE, __LINE__, size) #define grub_realloc(ptr,size) \ - grub_debug_realloc (__FILE__, __LINE__, ptr, size) + grub_debug_realloc (GRUB_FILE, __LINE__, ptr, size) #define grub_memalign(align,size) \ - grub_debug_memalign (__FILE__, __LINE__, align, size) + grub_debug_memalign (GRUB_FILE, __LINE__, align, size) #define grub_free(ptr) \ - grub_debug_free (__FILE__, __LINE__, ptr) + grub_debug_free (GRUB_FILE, __LINE__, ptr) void *EXPORT_FUNC(grub_debug_malloc) (const char *file, int line, grub_size_t size); diff --git a/include/grub/test.h b/include/grub/test.h index a7d3a2399..27591cca2 100644 --- a/include/grub/test.h +++ b/include/grub/test.h @@ -54,7 +54,7 @@ void grub_test_nonzero (int cond, const char *file, /* Macro to fill in location details and an optional error message. */ #define grub_test_assert(cond, ...) \ - grub_test_nonzero(cond, __FILE__, __FUNCTION__, __LINE__, \ + grub_test_nonzero(cond, GRUB_FILE, __FUNCTION__, __LINE__, \ ## __VA_ARGS__, \ "assert failed: %s", #cond) diff --git a/kern/mm.c b/kern/mm.c index ef97b018e..3237b040c 100644 --- a/kern/mm.c +++ b/kern/mm.c @@ -388,7 +388,7 @@ grub_free (void *ptr) do { grub_printf ("%s:%d: q=%p, q->size=0x%x, q->magic=0x%x\n", - __FILE__, __LINE__, q, q->size, q->magic); + GRUB_FILE, __LINE__, q, q->size, q->magic); q = q->next; } while (q != r->first); diff --git a/lib/libgcrypt_wrap/cipher_wrap.h b/lib/libgcrypt_wrap/cipher_wrap.h index e05f0cda9..b4530c112 100644 --- a/lib/libgcrypt_wrap/cipher_wrap.h +++ b/lib/libgcrypt_wrap/cipher_wrap.h @@ -59,7 +59,7 @@ typedef union { double g; } PROPERLY_ALIGNED_TYPE; -#define gcry_assert(x) grub_assert_real(__FILE__, __LINE__, x) +#define gcry_assert(x) grub_assert_real(GRUB_FILE, __LINE__, x) static inline void grub_assert_real (const char *file, int line, int cond) From a3df209041d587f7dd50958bd1f8b20fae42a68f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 9 Feb 2010 21:16:17 +0100 Subject: [PATCH 382/738] Fix libusb compilation --- conf/any-emu.rmk | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/conf/any-emu.rmk b/conf/any-emu.rmk index a4ee9b755..2ded20e2e 100644 --- a/conf/any-emu.rmk +++ b/conf/any-emu.rmk @@ -47,11 +47,29 @@ endif grub_emu_LDFLAGS = $(LIBCURSES) ifeq ($(enable_grub_emu_usb), yes) +pkglib_MODULES += libusb.mod +libusb_mod_SOURCES = util/usb.c +libusb_mod_CFLAGS = +libusb_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For usb.mod pkglib_MODULES += usb.mod -usb_mod_SOURCES = disk/usbms.c util/usb.c bus/usb/usb.c \ - commands/usbtest.c +usb_mod_SOURCES = bus/usb/usb.c usb_mod_CFLAGS = $(COMMON_CFLAGS) usb_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For usbtest.mod +pkglib_MODULES += usbtest.mod +usbtest_mod_SOURCES = commands/usbtest.c +usbtest_mod_CFLAGS = $(COMMON_CFLAGS) +usbtest_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For usbms.mod +pkglib_MODULES += usbms.mod +usbms_mod_SOURCES = disk/usbms.c +usbms_mod_CFLAGS = $(COMMON_CFLAGS) +usbms_mod_LDFLAGS = $(COMMON_LDFLAGS) + grub_emu_LDFLAGS += $(LIBUSB) endif From 38c95667d6e4e16aa273be18b5d405972352a23f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 10 Feb 2010 00:05:19 +0100 Subject: [PATCH 383/738] Unify efi rmk --- conf/i386-efi.rmk | 130 +---------------------------------------- conf/x86-efi.rmk | 138 ++++++++++++++++++++++++++++++++++++++++++++ conf/x86_64-efi.rmk | 130 +---------------------------------------- 3 files changed, 140 insertions(+), 258 deletions(-) create mode 100644 conf/x86-efi.rmk diff --git a/conf/i386-efi.rmk b/conf/i386-efi.rmk index 345350406..b6e6821f4 100644 --- a/conf/i386-efi.rmk +++ b/conf/i386-efi.rmk @@ -4,132 +4,4 @@ COMMON_ASFLAGS = -nostdinc -fno-builtin -m32 COMMON_CFLAGS = -fno-builtin -m32 COMMON_LDFLAGS = -melf_i386 -nostdlib -# Used by various components. These rules need to precede them. -script/lexer.c_DEPENDENCIES = grub_script.tab.h - -# Utilities. -bin_UTILITIES = grub-mkimage - -# For grub-mkimage. -grub_mkimage_SOURCES = gnulib/progname.c util/i386/efi/grub-mkimage.c \ - util/misc.c util/resolve.c -util/i386/efi/grub-mkimage.c_DEPENDENCIES = Makefile - -# For grub-setup. -#grub_setup_SOURCES = util/i386/pc/grub-setup.c util/hostdisk.c \ -# util/misc.c util/getroot.c kern/device.c kern/disk.c \ -# kern/err.c kern/misc.c fs/fat.c fs/ext2.c fs/xfs.c fs/affs.c \ -# fs/sfs.c kern/parser.c kern/partition.c partmap/msdos.c \ -# fs/ufs.c fs/ufs2.c fs/minix.c fs/hfs.c fs/jfs.c fs/hfsplus.c kern/file.c \ -# kern/fs.c kern/env.c fs/fshelp.c - -# Scripts. -sbin_SCRIPTS = grub-install - -# For grub-install. -grub_install_SOURCES = util/i386/efi/grub-install.in - -# Modules. -pkglib_PROGRAMS = kernel.img -pkglib_MODULES = chain.mod appleldr.mod \ - linux.mod halt.mod \ - datetime.mod loadbios.mod \ - fixvideo.mod mmap.mod acpi.mod - -# For kernel.img. -kernel_img_RELOCATABLE = yes -kernel_img_SOURCES = kern/i386/efi/startup.S kern/main.c kern/device.c \ - kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \ - kern/misc.c kern/mm.c kern/term.c \ - kern/rescue_parser.c kern/rescue_reader.c \ - kern/$(target_cpu)/dl.c kern/i386/efi/init.c kern/parser.c kern/partition.c \ - kern/env.c symlist.c kern/efi/efi.c kern/efi/init.c kern/efi/mm.c \ - term/efi/console.c disk/efi/efidisk.c \ - kern/time.c kern/list.c kern/handler.c kern/command.c kern/corecmd.c \ - kern/i386/tsc.c kern/i386/pit.c \ - kern/generic/rtc_get_time_ms.c \ - kern/generic/millisleep.c -kernel_img_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ - env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \ - partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \ - efi/efi.h efi/time.h efi/disk.h i386/pit.h list.h handler.h command.h \ - i18n.h env_private.h -kernel_img_CFLAGS = $(COMMON_CFLAGS) -kernel_img_ASFLAGS = $(COMMON_ASFLAGS) -kernel_img_LDFLAGS = $(COMMON_LDFLAGS) - -MOSTLYCLEANFILES += symlist.c -MOSTLYCLEANFILES += symlist.c kernel_syms.lst -DEFSYMFILES += kernel_syms.lst - -symlist.c: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h gensymlist.sh - /bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) - -kernel_syms.lst: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h genkernsyms.sh - /bin/sh genkernsyms.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) - -# For acpi.mod. -acpi_mod_SOURCES = commands/acpi.c commands/efi/acpi.c -acpi_mod_CFLAGS = $(COMMON_CFLAGS) -acpi_mod_LDFLAGS = $(COMMON_LDFLAGS) - -# For mmap.mod. -mmap_mod_SOURCES = mmap/mmap.c mmap/i386/uppermem.c mmap/i386/mmap.c \ - mmap/efi/mmap.c -mmap_mod_CFLAGS = $(COMMON_CFLAGS) -mmap_mod_LDFLAGS = $(COMMON_LDFLAGS) - -# For chain.mod. -chain_mod_SOURCES = loader/efi/chainloader.c -chain_mod_CFLAGS = $(COMMON_CFLAGS) -chain_mod_LDFLAGS = $(COMMON_LDFLAGS) - -# For appleldr.mod. -appleldr_mod_SOURCES = loader/efi/appleloader.c -appleldr_mod_CFLAGS = $(COMMON_CFLAGS) -appleldr_mod_LDFLAGS = $(COMMON_LDFLAGS) - -# For linux.mod. -linux_mod_SOURCES = loader/i386/efi/linux.c -linux_mod_CFLAGS = $(COMMON_CFLAGS) -linux_mod_LDFLAGS = $(COMMON_LDFLAGS) - -# For halt.mod. -halt_mod_SOURCES = commands/halt.c -halt_mod_CFLAGS = $(COMMON_CFLAGS) -halt_mod_LDFLAGS = $(COMMON_LDFLAGS) - -# For datetime.mod -datetime_mod_SOURCES = lib/efi/datetime.c -datetime_mod_CFLAGS = $(COMMON_CFLAGS) -datetime_mod_LDFLAGS = $(COMMON_LDFLAGS) - -# For loadbios.mod -loadbios_mod_SOURCES = commands/efi/loadbios.c -loadbios_mod_CFLAGS = $(COMMON_CFLAGS) -loadbios_mod_LDFLAGS = $(COMMON_LDFLAGS) - -# For fixvideo.mod -fixvideo_mod_SOURCES = commands/efi/fixvideo.c -fixvideo_mod_CFLAGS = $(COMMON_CFLAGS) -fixvideo_mod_LDFLAGS = $(COMMON_LDFLAGS) - -pkglib_MODULES += efi_uga.mod -efi_uga_mod_SOURCES = video/efi_uga.c -efi_uga_mod_CFLAGS = $(COMMON_CFLAGS) -efi_uga_mod_LDFLAGS = $(COMMON_LDFLAGS) - -pkglib_MODULES += efi_gop.mod -efi_gop_mod_SOURCES = video/efi_gop.c -efi_gop_mod_CFLAGS = $(COMMON_CFLAGS) -efi_gop_mod_LDFLAGS = $(COMMON_LDFLAGS) - -pkglib_MODULES += xnu.mod -xnu_mod_SOURCES = loader/xnu_resume.c loader/i386/xnu.c loader/i386/efi/xnu.c \ - loader/macho32.c loader/macho64.c loader/macho.c loader/xnu.c -xnu_mod_CFLAGS = $(COMMON_CFLAGS) -xnu_mod_LDFLAGS = $(COMMON_LDFLAGS) -xnu_mod_ASFLAGS = $(COMMON_ASFLAGS) - -include $(srcdir)/conf/i386.mk -include $(srcdir)/conf/common.mk +include $(srcdir)/conf/x86-efi.mk \ No newline at end of file diff --git a/conf/x86-efi.rmk b/conf/x86-efi.rmk new file mode 100644 index 000000000..b115d174b --- /dev/null +++ b/conf/x86-efi.rmk @@ -0,0 +1,138 @@ +# -*- makefile -*- + +# Used by various components. These rules need to precede them. +script/lexer.c_DEPENDENCIES = grub_script.tab.h + +# Utilities. +bin_UTILITIES = grub-mkimage + +# For grub-mkimage. +grub_mkimage_SOURCES = gnulib/progname.c util/i386/efi/grub-mkimage.c \ + util/misc.c util/resolve.c +util/i386/efi/grub-mkimage.c_DEPENDENCIES = Makefile + +# For grub-setup. +#grub_setup_SOURCES = util/i386/pc/grub-setup.c util/hostdisk.c \ +# util/misc.c util/getroot.c kern/device.c kern/disk.c \ +# kern/err.c kern/misc.c fs/fat.c fs/ext2.c fs/xfs.c fs/affs.c \ +# fs/sfs.c kern/parser.c kern/partition.c partmap/msdos.c \ +# fs/ufs.c fs/ufs2.c fs/minix.c fs/hfs.c fs/jfs.c fs/hfsplus.c kern/file.c \ +# kern/fs.c kern/env.c fs/fshelp.c + +# Scripts. +sbin_SCRIPTS = grub-install + +# For grub-install. +grub_install_SOURCES = util/i386/efi/grub-install.in + +# Modules. +pkglib_PROGRAMS = kernel.img +pkglib_MODULES = chain.mod appleldr.mod \ + linux.mod halt.mod \ + datetime.mod loadbios.mod \ + fixvideo.mod mmap.mod acpi.mod + +# For kernel.img. +kernel_img_RELOCATABLE = yes +kernel_img_SOURCES = kern/$(target_cpu)/efi/startup.S kern/main.c kern/device.c \ + kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \ + kern/misc.c kern/mm.c kern/term.c \ + kern/rescue_parser.c kern/rescue_reader.c \ + kern/$(target_cpu)/dl.c kern/i386/efi/init.c kern/parser.c kern/partition.c \ + kern/env.c symlist.c kern/efi/efi.c kern/efi/init.c kern/efi/mm.c \ + term/efi/console.c disk/efi/efidisk.c \ + kern/time.c kern/list.c kern/handler.c kern/command.c kern/corecmd.c \ + kern/i386/tsc.c kern/i386/pit.c \ + kern/generic/rtc_get_time_ms.c \ + kern/generic/millisleep.c +ifeq ($(target_cpu),x86_64) +kernel_img_SOURCES += kern/x86_64/efi/callwrap.S +endif +kernel_img_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ + env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \ + partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \ + efi/efi.h efi/time.h efi/disk.h i386/pit.h list.h handler.h command.h \ + i18n.h env_private.h +kernel_img_CFLAGS = $(COMMON_CFLAGS) +kernel_img_ASFLAGS = $(COMMON_ASFLAGS) +kernel_img_LDFLAGS = $(COMMON_LDFLAGS) + +MOSTLYCLEANFILES += symlist.c +MOSTLYCLEANFILES += symlist.c kernel_syms.lst +DEFSYMFILES += kernel_syms.lst + +symlist.c: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h gensymlist.sh + /bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) + +kernel_syms.lst: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h genkernsyms.sh + /bin/sh genkernsyms.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) + +# For acpi.mod. +acpi_mod_SOURCES = commands/acpi.c commands/efi/acpi.c +acpi_mod_CFLAGS = $(COMMON_CFLAGS) +acpi_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For mmap.mod. +mmap_mod_SOURCES = mmap/mmap.c mmap/i386/uppermem.c mmap/i386/mmap.c \ + mmap/efi/mmap.c +mmap_mod_CFLAGS = $(COMMON_CFLAGS) +mmap_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For chain.mod. +chain_mod_SOURCES = loader/efi/chainloader.c +chain_mod_CFLAGS = $(COMMON_CFLAGS) +chain_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For appleldr.mod. +appleldr_mod_SOURCES = loader/efi/appleloader.c +appleldr_mod_CFLAGS = $(COMMON_CFLAGS) +appleldr_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For linux.mod. +linux_mod_SOURCES = loader/i386/efi/linux.c +ifeq ($(target_cpu), x86_64) +linux_mod_SOURCES += loader/i386/linux_trampoline.S +endif +linux_mod_CFLAGS = $(COMMON_CFLAGS) +linux_mod_ASFLAGS = $(COMMON_ASFLAGS) +linux_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For halt.mod. +halt_mod_SOURCES = commands/halt.c +halt_mod_CFLAGS = $(COMMON_CFLAGS) +halt_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For datetime.mod +datetime_mod_SOURCES = lib/efi/datetime.c +datetime_mod_CFLAGS = $(COMMON_CFLAGS) +datetime_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For loadbios.mod +loadbios_mod_SOURCES = commands/efi/loadbios.c +loadbios_mod_CFLAGS = $(COMMON_CFLAGS) +loadbios_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For fixvideo.mod +fixvideo_mod_SOURCES = commands/efi/fixvideo.c +fixvideo_mod_CFLAGS = $(COMMON_CFLAGS) +fixvideo_mod_LDFLAGS = $(COMMON_LDFLAGS) + +pkglib_MODULES += efi_uga.mod +efi_uga_mod_SOURCES = video/efi_uga.c +efi_uga_mod_CFLAGS = $(COMMON_CFLAGS) +efi_uga_mod_LDFLAGS = $(COMMON_LDFLAGS) + +pkglib_MODULES += efi_gop.mod +efi_gop_mod_SOURCES = video/efi_gop.c +efi_gop_mod_CFLAGS = $(COMMON_CFLAGS) +efi_gop_mod_LDFLAGS = $(COMMON_LDFLAGS) + +pkglib_MODULES += xnu.mod +xnu_mod_SOURCES = loader/xnu_resume.c loader/i386/xnu.c loader/i386/efi/xnu.c \ + loader/macho32.c loader/macho64.c loader/macho.c loader/xnu.c +xnu_mod_CFLAGS = $(COMMON_CFLAGS) +xnu_mod_LDFLAGS = $(COMMON_LDFLAGS) +xnu_mod_ASFLAGS = $(COMMON_ASFLAGS) + +include $(srcdir)/conf/i386.mk +include $(srcdir)/conf/common.mk diff --git a/conf/x86_64-efi.rmk b/conf/x86_64-efi.rmk index 4116894f4..816cce34e 100644 --- a/conf/x86_64-efi.rmk +++ b/conf/x86_64-efi.rmk @@ -4,132 +4,4 @@ COMMON_ASFLAGS = -nostdinc -fno-builtin -m64 COMMON_CFLAGS = -fno-builtin -m64 COMMON_LDFLAGS = -melf_x86_64 -nostdlib -# Used by various components. These rules need to precede them. -script/lexer.c_DEPENDENCIES = grub_script.tab.h - -# Utilities. -bin_UTILITIES = grub-mkimage - -# For grub-mkimage. -grub_mkimage_SOURCES = gnulib/progname.c util/i386/efi/grub-mkimage.c \ - util/misc.c util/resolve.c - -# For grub-setup. -#grub_setup_SOURCES = util/i386/pc/grub-setup.c util/hostdisk.c \ -# util/misc.c util/getroot.c kern/device.c kern/disk.c \ -# kern/err.c kern/misc.c fs/fat.c fs/ext2.c fs/xfs.c fs/affs.c \ -# fs/sfs.c kern/parser.c kern/partition.c partmap/msdos.c \ -# fs/ufs.c fs/ufs2.c fs/minix.c fs/hfs.c fs/jfs.c fs/hfsplus.c kern/file.c \ -# kern/fs.c kern/env.c fs/fshelp.c - -# Scripts. -sbin_SCRIPTS = grub-install - -# For grub-install. -grub_install_SOURCES = util/i386/efi/grub-install.in - -# Modules. -pkglib_PROGRAMS = kernel.img -pkglib_MODULES = chain.mod appleldr.mod \ - halt.mod linux.mod \ - datetime.mod loadbios.mod \ - fixvideo.mod mmap.mod acpi.mod - -# For kernel.img. -kernel_img_RELOCATABLE = yes -kernel_img_SOURCES = kern/x86_64/efi/startup.S kern/x86_64/efi/callwrap.S \ - kern/main.c kern/device.c \ - kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \ - kern/misc.c kern/mm.c kern/term.c \ - kern/rescue_parser.c kern/rescue_reader.c \ - kern/$(target_cpu)/dl.c kern/i386/efi/init.c kern/parser.c kern/partition.c \ - kern/env.c symlist.c kern/efi/efi.c kern/efi/init.c kern/efi/mm.c \ - kern/time.c kern/list.c kern/handler.c kern/command.c kern/corecmd.c \ - kern/i386/tsc.c kern/i386/pit.c \ - kern/generic/millisleep.c kern/generic/rtc_get_time_ms.c \ - term/efi/console.c disk/efi/efidisk.c -kernel_img_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ - env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \ - partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \ - efi/efi.h efi/time.h efi/disk.h machine/loader.h i386/pit.h list.h \ - handler.h command.h i18n.h env_private.h -kernel_img_CFLAGS = $(COMMON_CFLAGS) -kernel_img_ASFLAGS = $(COMMON_ASFLAGS) -kernel_img_LDFLAGS = $(COMMON_LDFLAGS) - -MOSTLYCLEANFILES += symlist.c -MOSTLYCLEANFILES += symlist.c kernel_syms.lst -DEFSYMFILES += kernel_syms.lst - -symlist.c: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h gensymlist.sh - /bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) - -kernel_syms.lst: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h genkernsyms.sh - /bin/sh genkernsyms.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) - -# For acpi.mod. -acpi_mod_SOURCES = commands/acpi.c commands/efi/acpi.c -acpi_mod_CFLAGS = $(COMMON_CFLAGS) -acpi_mod_LDFLAGS = $(COMMON_LDFLAGS) - -# For mmap.mod. -mmap_mod_SOURCES = mmap/mmap.c mmap/i386/uppermem.c mmap/i386/mmap.c \ - mmap/efi/mmap.c -mmap_mod_CFLAGS = $(COMMON_CFLAGS) -mmap_mod_LDFLAGS = $(COMMON_LDFLAGS) - -# For chain.mod. -chain_mod_SOURCES = loader/efi/chainloader.c -chain_mod_CFLAGS = $(COMMON_CFLAGS) -chain_mod_LDFLAGS = $(COMMON_LDFLAGS) - -# For appleldr.mod. -appleldr_mod_SOURCES = loader/efi/appleloader.c -appleldr_mod_CFLAGS = $(COMMON_CFLAGS) -appleldr_mod_LDFLAGS = $(COMMON_LDFLAGS) - -# For linux.mod. -linux_mod_SOURCES = loader/i386/efi/linux.c loader/i386/linux_trampoline.S -linux_mod_CFLAGS = $(COMMON_CFLAGS) -linux_mod_ASFLAGS = $(COMMON_ASFLAGS) -linux_mod_LDFLAGS = $(COMMON_LDFLAGS) - -# For halt.mod. -halt_mod_SOURCES = commands/halt.c -halt_mod_CFLAGS = $(COMMON_CFLAGS) -halt_mod_LDFLAGS = $(COMMON_LDFLAGS) - -# For datetime.mod -datetime_mod_SOURCES = lib/efi/datetime.c -datetime_mod_CFLAGS = $(COMMON_CFLAGS) -datetime_mod_LDFLAGS = $(COMMON_LDFLAGS) - -# For loadbios.mod -loadbios_mod_SOURCES = commands/efi/loadbios.c -loadbios_mod_CFLAGS = $(COMMON_CFLAGS) -loadbios_mod_LDFLAGS = $(COMMON_LDFLAGS) - -# For fixvideo.mod -fixvideo_mod_SOURCES = commands/efi/fixvideo.c -fixvideo_mod_CFLAGS = $(COMMON_CFLAGS) -fixvideo_mod_LDFLAGS = $(COMMON_LDFLAGS) - -pkglib_MODULES += efi_uga.mod -efi_uga_mod_SOURCES = video/efi_uga.c -efi_uga_mod_CFLAGS = $(COMMON_CFLAGS) -efi_uga_mod_LDFLAGS = $(COMMON_LDFLAGS) - -pkglib_MODULES += efi_gop.mod -efi_gop_mod_SOURCES = video/efi_gop.c -efi_gop_mod_CFLAGS = $(COMMON_CFLAGS) -efi_gop_mod_LDFLAGS = $(COMMON_LDFLAGS) - -pkglib_MODULES += xnu.mod -xnu_mod_SOURCES = loader/xnu_resume.c loader/i386/xnu.c loader/i386/efi/xnu.c \ - loader/macho32.c loader/macho64.c loader/macho.c loader/xnu.c -xnu_mod_CFLAGS = $(COMMON_CFLAGS) -xnu_mod_LDFLAGS = $(COMMON_LDFLAGS) -xnu_mod_ASFLAGS = $(COMMON_ASFLAGS) - -include $(srcdir)/conf/i386.mk -include $(srcdir)/conf/common.mk +include $(srcdir)/conf/x86-efi.mk From ed4e9b07a4a3bcf2c89079e450f80bc9db5a5de7 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 10 Feb 2010 00:16:28 +0100 Subject: [PATCH 384/738] unify symlist.c --- conf/common.rmk | 9 +++++++++ conf/i386-coreboot.rmk | 9 --------- conf/i386-ieee1275.rmk | 9 --------- conf/i386-pc.rmk | 9 --------- conf/i386-qemu.rmk | 9 --------- conf/mips.rmk | 10 ---------- conf/powerpc-ieee1275.rmk | 9 --------- conf/sparc64-ieee1275.rmk | 9 --------- conf/x86-efi.rmk | 10 ---------- 9 files changed, 9 insertions(+), 74 deletions(-) diff --git a/conf/common.rmk b/conf/common.rmk index f3c85d971..4133e7c97 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -100,6 +100,15 @@ grub_script_check_SOURCES = gnulib/progname.c gnulib/getdelim.c gnulib/getline.c kern/handler.c kern/err.c kern/parser.c kern/list.c \ kern/misc.c kern/env.c grub_script_check_init.c grub_script.tab.c +MOSTLYCLEANFILES += symlist.c kernel_syms.lst +DEFSYMFILES += kernel_syms.lst + +symlist.c: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h gensymlist.sh + /bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) + +kernel_syms.lst: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h genkernsyms.sh + /bin/sh genkernsyms.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) + # For the parser. grub_script.tab.c grub_script.tab.h: script/parser.y $(YACC) -d -p grub_script_yy -b grub_script $(srcdir)/script/parser.y diff --git a/conf/i386-coreboot.rmk b/conf/i386-coreboot.rmk index 85407b47e..dbcba7f6b 100644 --- a/conf/i386-coreboot.rmk +++ b/conf/i386-coreboot.rmk @@ -39,15 +39,6 @@ kernel_img_CFLAGS = $(COMMON_CFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) kernel_img_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,$(GRUB_KERNEL_MACHINE_LINK_ADDR),-Bstatic -MOSTLYCLEANFILES += symlist.c kernel_syms.lst -DEFSYMFILES += kernel_syms.lst - -symlist.c: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h gensymlist.sh - /bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) - -kernel_syms.lst: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h genkernsyms.sh - /bin/sh genkernsyms.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) - sbin_SCRIPTS += grub-install grub_install_SOURCES = util/grub-install.in diff --git a/conf/i386-ieee1275.rmk b/conf/i386-ieee1275.rmk index 6e5fd3055..ebcde000c 100644 --- a/conf/i386-ieee1275.rmk +++ b/conf/i386-ieee1275.rmk @@ -38,15 +38,6 @@ kernel_img_CFLAGS = $(COMMON_CFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) kernel_img_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,0x10000,-Bstatic -MOSTLYCLEANFILES += symlist.c kernel_syms.lst -DEFSYMFILES += kernel_syms.lst - -symlist.c: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h gensymlist.sh - /bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) - -kernel_syms.lst: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h genkernsyms.sh - /bin/sh genkernsyms.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) - # Scripts. sbin_SCRIPTS = grub-install diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk index b30863812..535c91109 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -71,15 +71,6 @@ kernel_img_ASFLAGS = $(COMMON_ASFLAGS) kernel_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_KERNEL_MACHINE_LINK_ADDR) $(COMMON_CFLAGS) kernel_img_FORMAT = binary -MOSTLYCLEANFILES += symlist.c kernel_syms.lst -DEFSYMFILES += kernel_syms.lst - -symlist.c: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h gensymlist.sh - /bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) - -kernel_syms.lst: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h genkernsyms.sh - /bin/sh genkernsyms.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) - # Utilities. bin_UTILITIES = grub-mkimage sbin_UTILITIES = grub-setup diff --git a/conf/i386-qemu.rmk b/conf/i386-qemu.rmk index 17e4f1129..af150932f 100644 --- a/conf/i386-qemu.rmk +++ b/conf/i386-qemu.rmk @@ -53,15 +53,6 @@ kernel_img_ASFLAGS = $(COMMON_ASFLAGS) -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KE kernel_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_KERNEL_MACHINE_LINK_ADDR) kernel_img_FORMAT = binary -MOSTLYCLEANFILES += symlist.c kernel_syms.lst -DEFSYMFILES += kernel_syms.lst - -symlist.c: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h gensymlist.sh - /bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) - -kernel_syms.lst: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h genkernsyms.sh - /bin/sh genkernsyms.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) - sbin_SCRIPTS += grub-install grub_install_SOURCES = util/grub-install.in diff --git a/conf/mips.rmk b/conf/mips.rmk index e04b0adf2..32d945734 100644 --- a/conf/mips.rmk +++ b/conf/mips.rmk @@ -9,10 +9,6 @@ COMMON_LDFLAGS += -nostdlib script/lexer.c_DEPENDENCIES = grub_script.tab.h # Images. - -MOSTLYCLEANFILES += symlist.c kernel_syms.lst -DEFSYMFILES += kernel_syms.lst - kernel_img_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ env.h err.h file.h fs.h kernel.h misc.h mm.h net.h parser.h reader.h \ symbol.h term.h time.h types.h loader.h partition.h \ @@ -23,12 +19,6 @@ ifeq ($(platform), yeeloong) kernel_img_HEADERS += pci.h endif -symlist.c: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h gensymlist.sh - /bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) - -kernel_syms.lst: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h genkernsyms.sh - /bin/sh genkernsyms.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) - # Scripts. sbin_SCRIPTS = bin_SCRIPTS = diff --git a/conf/powerpc-ieee1275.rmk b/conf/powerpc-ieee1275.rmk index a22c38ec1..d5d6d3bd2 100644 --- a/conf/powerpc-ieee1275.rmk +++ b/conf/powerpc-ieee1275.rmk @@ -10,21 +10,12 @@ script/lexer.c_DEPENDENCIES = grub_script.tab.h # Images. -MOSTLYCLEANFILES += symlist.c kernel_syms.lst -DEFSYMFILES += kernel_syms.lst - kernel_img_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ env.h err.h file.h fs.h kernel.h misc.h mm.h net.h parser.h reader.h \ symbol.h term.h time.h types.h powerpc/libgcc.h loader.h partition.h \ msdos_partition.h ieee1275/ieee1275.h machine/kernel.h handler.h list.h \ command.h i18n.h env_private.h -symlist.c: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h gensymlist.sh - /bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) - -kernel_syms.lst: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h genkernsyms.sh - /bin/sh genkernsyms.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) - # Programs pkglib_PROGRAMS = kernel.img diff --git a/conf/sparc64-ieee1275.rmk b/conf/sparc64-ieee1275.rmk index 69ed325b2..2668f1060 100644 --- a/conf/sparc64-ieee1275.rmk +++ b/conf/sparc64-ieee1275.rmk @@ -23,9 +23,6 @@ diskboot_img_ASFLAGS = $(COMMON_ASFLAGS) diskboot_img_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-Ttext,0x4200 diskboot_img_FORMAT = binary -MOSTLYCLEANFILES += symlist.c kernel_syms.lst -DEFSYMFILES += kernel_syms.lst - kernel_img_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \ partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \ @@ -51,12 +48,6 @@ kernel_img_ASFLAGS = $(COMMON_ASFLAGS) kernel_img_LDFLAGS = -nostdlib -Wl,-N,-Ttext,0x200000,-Bstatic,-melf64_sparc -static-libgcc -lgcc kernel_img_FORMAT = binary -symlist.c: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h gensymlist.sh - /bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) - -kernel_syms.lst: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h genkernsyms.sh - /bin/sh genkernsyms.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) - # Utilities. bin_UTILITIES = grub-mkimage sbin_UTILITIES = grub-setup grub-ofpathname diff --git a/conf/x86-efi.rmk b/conf/x86-efi.rmk index b115d174b..58918e145 100644 --- a/conf/x86-efi.rmk +++ b/conf/x86-efi.rmk @@ -57,16 +57,6 @@ kernel_img_CFLAGS = $(COMMON_CFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) kernel_img_LDFLAGS = $(COMMON_LDFLAGS) -MOSTLYCLEANFILES += symlist.c -MOSTLYCLEANFILES += symlist.c kernel_syms.lst -DEFSYMFILES += kernel_syms.lst - -symlist.c: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h gensymlist.sh - /bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) - -kernel_syms.lst: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h genkernsyms.sh - /bin/sh genkernsyms.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) - # For acpi.mod. acpi_mod_SOURCES = commands/acpi.c commands/efi/acpi.c acpi_mod_CFLAGS = $(COMMON_CFLAGS) From efca454179d415fea918ee6f3d565cd5d9bb3af8 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 10 Feb 2010 01:05:40 +0100 Subject: [PATCH 385/738] Merge kernel_img_HEADERS --- conf/common.rmk | 6 ++++++ conf/i386-coreboot.rmk | 6 ------ conf/i386-ieee1275.rmk | 6 +----- conf/i386-pc.rmk | 9 ++------- conf/i386-qemu.rmk | 6 ------ conf/mips-yeeloong.rmk | 1 + conf/mips.rmk | 10 +--------- conf/powerpc-ieee1275.rmk | 6 +----- conf/sparc64-ieee1275.rmk | 7 +------ conf/x86-efi.rmk | 6 +----- gensymlist.sh.in | 1 + 11 files changed, 15 insertions(+), 49 deletions(-) diff --git a/conf/common.rmk b/conf/common.rmk index 4133e7c97..b97de8e22 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -103,6 +103,12 @@ grub_script_check_SOURCES = gnulib/progname.c gnulib/getdelim.c gnulib/getline.c MOSTLYCLEANFILES += symlist.c kernel_syms.lst DEFSYMFILES += kernel_syms.lst +kernel_img_HEADERS += boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ + env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \ + partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \ + machine/memory.h machine/loader.h machine/kernel.h \ + list.h handler.h command.h i18n.h env_private.h + symlist.c: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h gensymlist.sh /bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) diff --git a/conf/i386-coreboot.rmk b/conf/i386-coreboot.rmk index dbcba7f6b..44b80761e 100644 --- a/conf/i386-coreboot.rmk +++ b/conf/i386-coreboot.rmk @@ -29,12 +29,6 @@ kernel_img_SOURCES = kern/i386/coreboot/startup.S \ kern/env.c \ term/i386/pc/vga_text.c term/i386/vga_common.c \ symlist.c -kernel_img_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ - env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \ - partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \ - machine/boot.h machine/console.h machine/init.h \ - machine/memory.h machine/loader.h list.h handler.h command.h i18n.h \ - env_private.h kernel_img_CFLAGS = $(COMMON_CFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) kernel_img_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,$(GRUB_KERNEL_MACHINE_LINK_ADDR),-Bstatic diff --git a/conf/i386-ieee1275.rmk b/conf/i386-ieee1275.rmk index ebcde000c..d23ba4c0e 100644 --- a/conf/i386-ieee1275.rmk +++ b/conf/i386-ieee1275.rmk @@ -29,11 +29,7 @@ kernel_img_SOURCES = kern/i386/ieee1275/startup.S \ term/ieee1275/ofconsole.c \ disk/ieee1275/ofdisk.c \ symlist.c -kernel_img_HEADERS = cache.h device.h disk.h dl.h elf.h elfload.h \ - env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \ - partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \ - ieee1275/ieee1275.h machine/kernel.h machine/loader.h machine/memory.h \ - list.h handler.h command.h i18n.h env_private.h +kernel_img_HEADERS += ieee1275/ieee1275.h kernel_img_CFLAGS = $(COMMON_CFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) kernel_img_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,0x10000,-Bstatic diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk index 535c91109..b620c43af 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -59,13 +59,8 @@ kernel_img_SOURCES = kern/i386/pc/startup.S \ kern/env.c \ term/i386/pc/console.c term/i386/vga_common.c \ symlist.c -kernel_img_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ - env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \ - partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \ - machine/biosdisk.h machine/boot.h machine/console.h machine/init.h \ - machine/memory.h machine/loader.h machine/vga.h machine/vbe.h \ - machine/kernel.h machine/pxe.h i386/pit.h list.h handler.h command.h \ - i18n.h env_private.h +kernel_img_HEADERS += machine/biosdisk.h machine/vga.h machine/vbe.h \ + machine/pxe.h i386/pit.h machine/init.h kernel_img_CFLAGS = $(COMMON_CFLAGS) $(TARGET_IMG_CFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) kernel_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_KERNEL_MACHINE_LINK_ADDR) $(COMMON_CFLAGS) diff --git a/conf/i386-qemu.rmk b/conf/i386-qemu.rmk index af150932f..355870c89 100644 --- a/conf/i386-qemu.rmk +++ b/conf/i386-qemu.rmk @@ -42,12 +42,6 @@ kernel_img_SOURCES = kern/i386/qemu/startup.S \ kern/env.c \ term/i386/pc/vga_text.c term/i386/vga_common.c \ symlist.c -kernel_img_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ - env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \ - partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \ - machine/boot.h machine/console.h machine/init.h \ - machine/memory.h machine/loader.h list.h handler.h command.h i18n.h \ - env_private.h kernel_img_CFLAGS = $(COMMON_CFLAGS) -DGRUB_BOOT_MACHINE_LINK_ADDR=$(GRUB_BOOT_MACHINE_LINK_ADDR) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR) kernel_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_KERNEL_MACHINE_LINK_ADDR) diff --git a/conf/mips-yeeloong.rmk b/conf/mips-yeeloong.rmk index d5e1d1c5d..8b6c0426a 100644 --- a/conf/mips-yeeloong.rmk +++ b/conf/mips-yeeloong.rmk @@ -24,6 +24,7 @@ kernel_img_SOURCES = kern/$(target_cpu)/startup.S \ video/bitmap_scale.c video/sm712.c bus/pci.c bus/bonito.c \ term/gfxterm.c commands/extcmd.c lib/arg.c \ symlist.c +kernel_img_HEADERS += pci.h kernel_img_CFLAGS = $(COMMON_CFLAGS) -DUSE_ASCII_FAILBACK kernel_img_ASFLAGS = $(COMMON_ASFLAGS) kernel_img_LDFLAGS = $(COMMON_LDFLAGS) -static-libgcc -lgcc \ diff --git a/conf/mips.rmk b/conf/mips.rmk index 32d945734..6948d8d66 100644 --- a/conf/mips.rmk +++ b/conf/mips.rmk @@ -9,15 +9,7 @@ COMMON_LDFLAGS += -nostdlib script/lexer.c_DEPENDENCIES = grub_script.tab.h # Images. -kernel_img_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ - env.h err.h file.h fs.h kernel.h misc.h mm.h net.h parser.h reader.h \ - symbol.h term.h time.h types.h loader.h partition.h \ - msdos_partition.h machine/kernel.h handler.h list.h \ - command.h machine/memory.h cpu/libgcc.h cpu/cache.h i18n.h env_private.h - -ifeq ($(platform), yeeloong) -kernel_img_HEADERS += pci.h -endif +kernel_img_HEADERS += cpu/libgcc.h cpu/cache.h # Scripts. sbin_SCRIPTS = diff --git a/conf/powerpc-ieee1275.rmk b/conf/powerpc-ieee1275.rmk index d5d6d3bd2..59cde4efe 100644 --- a/conf/powerpc-ieee1275.rmk +++ b/conf/powerpc-ieee1275.rmk @@ -10,11 +10,7 @@ script/lexer.c_DEPENDENCIES = grub_script.tab.h # Images. -kernel_img_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ - env.h err.h file.h fs.h kernel.h misc.h mm.h net.h parser.h reader.h \ - symbol.h term.h time.h types.h powerpc/libgcc.h loader.h partition.h \ - msdos_partition.h ieee1275/ieee1275.h machine/kernel.h handler.h list.h \ - command.h i18n.h env_private.h +kernel_img_HEADERS += cpu/libgcc.h ieee1275/ieee1275.h # Programs pkglib_PROGRAMS = kernel.img diff --git a/conf/sparc64-ieee1275.rmk b/conf/sparc64-ieee1275.rmk index 2668f1060..dbca42e58 100644 --- a/conf/sparc64-ieee1275.rmk +++ b/conf/sparc64-ieee1275.rmk @@ -23,12 +23,7 @@ diskboot_img_ASFLAGS = $(COMMON_ASFLAGS) diskboot_img_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-Ttext,0x4200 diskboot_img_FORMAT = binary -kernel_img_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ - env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \ - partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \ - list.h handler.h command.h i18n.h \ - sparc64/libgcc.h ieee1275/ieee1275.h machine/kernel.h \ - sparc64/ieee1275/ieee1275.h env_private.h +kernel_img_HEADERS += cpu/libgcc.h ieee1275/ieee1275.h cpu/ieee1275/ieee1275.h kernel_img_SOURCES = kern/sparc64/ieee1275/crt0.S kern/ieee1275/cmain.c \ kern/ieee1275/ieee1275.c kern/main.c kern/device.c \ kern/disk.c kern/dl.c kern/err.c kern/file.c kern/fs.c \ diff --git a/conf/x86-efi.rmk b/conf/x86-efi.rmk index 58918e145..94f305506 100644 --- a/conf/x86-efi.rmk +++ b/conf/x86-efi.rmk @@ -48,11 +48,7 @@ kernel_img_SOURCES = kern/$(target_cpu)/efi/startup.S kern/main.c kern/device.c ifeq ($(target_cpu),x86_64) kernel_img_SOURCES += kern/x86_64/efi/callwrap.S endif -kernel_img_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ - env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \ - partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \ - efi/efi.h efi/time.h efi/disk.h i386/pit.h list.h handler.h command.h \ - i18n.h env_private.h +kernel_img_HEADERS += efi/efi.h efi/time.h efi/disk.h i386/pit.h kernel_img_CFLAGS = $(COMMON_CFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) kernel_img_LDFLAGS = $(COMMON_LDFLAGS) diff --git a/gensymlist.sh.in b/gensymlist.sh.in index 27fc5e61a..087d0072f 100644 --- a/gensymlist.sh.in +++ b/gensymlist.sh.in @@ -37,6 +37,7 @@ cat <. */ +#include EOF for i in $*; do From 428b0b2edd213d8c966a8afb0a91154dac514dc6 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 10 Feb 2010 01:09:23 +0100 Subject: [PATCH 386/738] Unify lexer.c_DEPENDENCIES --- conf/any-emu.rmk | 3 --- conf/common.rmk | 3 +++ conf/i386-coreboot.rmk | 3 --- conf/i386-ieee1275.rmk | 3 --- conf/i386-pc.rmk | 3 --- conf/i386-qemu.rmk | 3 --- conf/mips.rmk | 3 --- conf/powerpc-ieee1275.rmk | 3 --- conf/sparc64-ieee1275.rmk | 3 --- conf/x86-efi.rmk | 3 --- 10 files changed, 3 insertions(+), 27 deletions(-) diff --git a/conf/any-emu.rmk b/conf/any-emu.rmk index ee5ab3cd4..95f44844c 100644 --- a/conf/any-emu.rmk +++ b/conf/any-emu.rmk @@ -3,9 +3,6 @@ COMMON_LDFLAGS += -nostdlib COMMON_CFLAGS += -nostdinc -isystem $(shell $(TARGET_CC) -print-file-name=include) -fno-builtin -# Used by various components. These rules need to precede them. -script/lexer.c_DEPENDENCIES = grub_script.tab.h - util/grub-emu.c_DEPENDENCIES = grub_emu_init.h kernel_img_RELOCATABLE = yes pkglib_PROGRAMS = kernel.img diff --git a/conf/common.rmk b/conf/common.rmk index b97de8e22..55a430572 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -1,5 +1,8 @@ # -*- makefile -*- +# Used by various components. These rules need to precede them. +script/lexer.c_DEPENDENCIES = grub_script.tab.h + sbin_UTILITIES += grub-mkdevicemap grub_mkdevicemap_SOURCES = gnulib/progname.c util/grub-mkdevicemap.c \ util/deviceiter.c \ diff --git a/conf/i386-coreboot.rmk b/conf/i386-coreboot.rmk index 44b80761e..048356a53 100644 --- a/conf/i386-coreboot.rmk +++ b/conf/i386-coreboot.rmk @@ -4,9 +4,6 @@ COMMON_ASFLAGS = -nostdinc -fno-builtin -m32 COMMON_CFLAGS = -fno-builtin -mrtd -mregparm=3 -m32 COMMON_LDFLAGS = -m32 -nostdlib -# Used by various components. These rules need to precede them. -script/lexer.c_DEPENDENCIES = grub_script.tab.h - # Images. GRUB_KERNEL_MACHINE_LINK_ADDR = 0x8200 diff --git a/conf/i386-ieee1275.rmk b/conf/i386-ieee1275.rmk index d23ba4c0e..c65e2f7de 100644 --- a/conf/i386-ieee1275.rmk +++ b/conf/i386-ieee1275.rmk @@ -4,9 +4,6 @@ COMMON_ASFLAGS = -m32 -nostdinc -fno-builtin COMMON_CFLAGS = -ffreestanding -mrtd -mregparm=3 COMMON_LDFLAGS = -nostdlib -# Used by various components. These rules need to precede them. -script/lexer.c_DEPENDENCIES = grub_script.tab.h - # Images. pkglib_PROGRAMS = kernel.img diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk index b620c43af..57904b265 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -6,9 +6,6 @@ COMMON_ASFLAGS = -nostdinc -fno-builtin -m32 COMMON_CFLAGS = -fno-builtin -mrtd -mregparm=3 -m32 COMMON_LDFLAGS = -m32 -nostdlib -# Used by various components. These rules need to precede them. -script/lexer.c_DEPENDENCIES = grub_script.tab.h - # Images. pkglib_IMAGES = boot.img cdboot.img diskboot.img kernel.img lnxboot.img \ pxeboot.img diff --git a/conf/i386-qemu.rmk b/conf/i386-qemu.rmk index 355870c89..c7209f348 100644 --- a/conf/i386-qemu.rmk +++ b/conf/i386-qemu.rmk @@ -4,9 +4,6 @@ COMMON_ASFLAGS = -nostdinc -fno-builtin -m32 COMMON_CFLAGS = -fno-builtin -mrtd -mregparm=3 -m32 COMMON_LDFLAGS = -m32 -nostdlib -# Used by various components. These rules need to precede them. -script/lexer.c_DEPENDENCIES = grub_script.tab.h - # Images. GRUB_KERNEL_MACHINE_LINK_ADDR = 0x8200 diff --git a/conf/mips.rmk b/conf/mips.rmk index 6948d8d66..84eed8805 100644 --- a/conf/mips.rmk +++ b/conf/mips.rmk @@ -5,9 +5,6 @@ COMMON_ASFLAGS += -nostdinc COMMON_CFLAGS += -ffreestanding -mexplicit-relocs -mflush-func=grub_cpu_flush_cache COMMON_LDFLAGS += -nostdlib -# Used by various components. These rules need to precede them. -script/lexer.c_DEPENDENCIES = grub_script.tab.h - # Images. kernel_img_HEADERS += cpu/libgcc.h cpu/cache.h diff --git a/conf/powerpc-ieee1275.rmk b/conf/powerpc-ieee1275.rmk index 59cde4efe..ce54ca494 100644 --- a/conf/powerpc-ieee1275.rmk +++ b/conf/powerpc-ieee1275.rmk @@ -5,9 +5,6 @@ COMMON_ASFLAGS = -nostdinc -D__ASSEMBLY__ COMMON_CFLAGS = -ffreestanding COMMON_LDFLAGS += -nostdlib -# Used by various components. These rules need to precede them. -script/lexer.c_DEPENDENCIES = grub_script.tab.h - # Images. kernel_img_HEADERS += cpu/libgcc.h ieee1275/ieee1275.h diff --git a/conf/sparc64-ieee1275.rmk b/conf/sparc64-ieee1275.rmk index dbca42e58..ffa8c1e7c 100644 --- a/conf/sparc64-ieee1275.rmk +++ b/conf/sparc64-ieee1275.rmk @@ -5,9 +5,6 @@ COMMON_ASFLAGS = -nostdinc -m64 COMMON_CFLAGS = -ffreestanding -m64 -mno-app-regs COMMON_LDFLAGS = -melf64_sparc -nostdlib -mno-relax -# Used by various components. These rules need to precede them. -script/lexer.c_DEPENDENCIES = grub_script.tab.h - # Images. pkglib_IMAGES = boot.img diskboot.img kernel.img diff --git a/conf/x86-efi.rmk b/conf/x86-efi.rmk index 94f305506..b27855aa4 100644 --- a/conf/x86-efi.rmk +++ b/conf/x86-efi.rmk @@ -1,8 +1,5 @@ # -*- makefile -*- -# Used by various components. These rules need to precede them. -script/lexer.c_DEPENDENCIES = grub_script.tab.h - # Utilities. bin_UTILITIES = grub-mkimage From c395ad834ea17c3bf75cf84ae09a57806b43f718 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 10 Feb 2010 01:10:09 +0100 Subject: [PATCH 387/738] Remove leftover __ASSEMBLY__ --- conf/powerpc-ieee1275.rmk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/powerpc-ieee1275.rmk b/conf/powerpc-ieee1275.rmk index ce54ca494..e7668fc5d 100644 --- a/conf/powerpc-ieee1275.rmk +++ b/conf/powerpc-ieee1275.rmk @@ -1,7 +1,7 @@ # -*- makefile -*- -COMMON_ASFLAGS = -nostdinc -D__ASSEMBLY__ +COMMON_ASFLAGS = -nostdinc COMMON_CFLAGS = -ffreestanding COMMON_LDFLAGS += -nostdlib From 5c2ee77128083e2b53ec0fd4f4916322c13c0399 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 10 Feb 2010 01:39:23 +0100 Subject: [PATCH 388/738] Share common compilation flags --- Makefile.in | 8 ++++---- conf/any-emu.rmk | 1 - conf/i386-coreboot.rmk | 4 +--- conf/i386-efi.rmk | 4 +--- conf/i386-ieee1275.rmk | 4 +--- conf/i386-pc.rmk | 4 +--- conf/i386-qemu.rmk | 4 +--- conf/mips.rmk | 4 +--- conf/powerpc-ieee1275.rmk | 4 ---- conf/sparc64-ieee1275.rmk | 7 +++---- conf/x86_64-efi.rmk | 4 +--- configure.ac | 2 ++ 12 files changed, 16 insertions(+), 34 deletions(-) diff --git a/Makefile.in b/Makefile.in index 7af2df1f0..c4059e58e 100644 --- a/Makefile.in +++ b/Makefile.in @@ -84,8 +84,8 @@ LDFLAGS = @LDFLAGS@ $(LIBS) CPPFLAGS = @CPPFLAGS@ -I$(builddir) -I$(builddir)/include -I$(srcdir)/gnulib -I$(srcdir)/include -Wall -W \ -DGRUB_LIBDIR=\"$(pkglibdir)\" -DLOCALEDIR=\"$(localedir)\" TARGET_CC = @TARGET_CC@ -TARGET_CFLAGS = @TARGET_CFLAGS@ -TARGET_ASFLAGS = @TARGET_ASFLAGS@ +TARGET_CFLAGS = -ffreestanding @TARGET_CFLAGS@ +TARGET_ASFLAGS = -nostdinc -fno-builtin @TARGET_ASFLAGS@ TARGET_MODULE_FORMAT = @TARGET_MODULE_FORMAT@ TARGET_APPLE_CC = @TARGET_APPLE_CC@ OBJCONV = @OBJCONV@ @@ -93,9 +93,9 @@ TARGET_CPPFLAGS = @TARGET_CPPFLAGS@ -I$(srcdir)/include -I$(builddir) -I$(buildd ifneq ($(platform), emu) TARGET_CPPFLAGS += -nostdinc -isystem $(shell $(TARGET_CC) -print-file-name=include) endif -TARGET_LDFLAGS = @TARGET_LDFLAGS@ +TARGET_LDFLAGS = -nostdlib @TARGET_LDFLAGS@ TARGET_IMG_LDSCRIPT = @TARGET_IMG_LDSCRIPT@ -TARGET_IMG_LDFLAGS = @TARGET_IMG_LDFLAGS@ +TARGET_IMG_LDFLAGS = -nostdlib @TARGET_IMG_LDFLAGS@ TARGET_IMG_CFLAGS = @TARGET_IMG_CFLAGS@ TARGET_OBJ2ELF = @TARGET_OBJ2ELF@ EXEEXT = @EXEEXT@ diff --git a/conf/any-emu.rmk b/conf/any-emu.rmk index 95f44844c..c06e7758a 100644 --- a/conf/any-emu.rmk +++ b/conf/any-emu.rmk @@ -1,6 +1,5 @@ # -*- makefile -*- -COMMON_LDFLAGS += -nostdlib COMMON_CFLAGS += -nostdinc -isystem $(shell $(TARGET_CC) -print-file-name=include) -fno-builtin util/grub-emu.c_DEPENDENCIES = grub_emu_init.h diff --git a/conf/i386-coreboot.rmk b/conf/i386-coreboot.rmk index 048356a53..3cef9313f 100644 --- a/conf/i386-coreboot.rmk +++ b/conf/i386-coreboot.rmk @@ -1,8 +1,6 @@ # -*- makefile -*- -COMMON_ASFLAGS = -nostdinc -fno-builtin -m32 -COMMON_CFLAGS = -fno-builtin -mrtd -mregparm=3 -m32 -COMMON_LDFLAGS = -m32 -nostdlib +COMMON_CFLAGS = -mrtd -mregparm=3 # Images. diff --git a/conf/i386-efi.rmk b/conf/i386-efi.rmk index b6e6821f4..a92cff224 100644 --- a/conf/i386-efi.rmk +++ b/conf/i386-efi.rmk @@ -1,7 +1,5 @@ # -*- makefile -*- -COMMON_ASFLAGS = -nostdinc -fno-builtin -m32 -COMMON_CFLAGS = -fno-builtin -m32 -COMMON_LDFLAGS = -melf_i386 -nostdlib +COMMON_LDFLAGS = -melf_i386 include $(srcdir)/conf/x86-efi.mk \ No newline at end of file diff --git a/conf/i386-ieee1275.rmk b/conf/i386-ieee1275.rmk index c65e2f7de..d4a459b3e 100644 --- a/conf/i386-ieee1275.rmk +++ b/conf/i386-ieee1275.rmk @@ -1,8 +1,6 @@ # -*- makefile -*- -COMMON_ASFLAGS = -m32 -nostdinc -fno-builtin -COMMON_CFLAGS = -ffreestanding -mrtd -mregparm=3 -COMMON_LDFLAGS = -nostdlib +COMMON_CFLAGS = -mrtd -mregparm=3 # Images. pkglib_PROGRAMS = kernel.img diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk index 57904b265..19c996543 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -2,9 +2,7 @@ GRUB_KERNEL_MACHINE_LINK_ADDR = 0x8200 -COMMON_ASFLAGS = -nostdinc -fno-builtin -m32 -COMMON_CFLAGS = -fno-builtin -mrtd -mregparm=3 -m32 -COMMON_LDFLAGS = -m32 -nostdlib +COMMON_CFLAGS = -mrtd -mregparm=3 # Images. pkglib_IMAGES = boot.img cdboot.img diskboot.img kernel.img lnxboot.img \ diff --git a/conf/i386-qemu.rmk b/conf/i386-qemu.rmk index c7209f348..97273e1ce 100644 --- a/conf/i386-qemu.rmk +++ b/conf/i386-qemu.rmk @@ -1,8 +1,6 @@ # -*- makefile -*- -COMMON_ASFLAGS = -nostdinc -fno-builtin -m32 -COMMON_CFLAGS = -fno-builtin -mrtd -mregparm=3 -m32 -COMMON_LDFLAGS = -m32 -nostdlib +COMMON_CFLAGS = -mrtd -mregparm=3 # Images. diff --git a/conf/mips.rmk b/conf/mips.rmk index 84eed8805..b43edbf69 100644 --- a/conf/mips.rmk +++ b/conf/mips.rmk @@ -1,9 +1,7 @@ # -*- makefile -*- -COMMON_ASFLAGS += -nostdinc -COMMON_CFLAGS += -ffreestanding -mexplicit-relocs -mflush-func=grub_cpu_flush_cache -COMMON_LDFLAGS += -nostdlib +COMMON_CFLAGS += -mexplicit-relocs -mflush-func=grub_cpu_flush_cache # Images. kernel_img_HEADERS += cpu/libgcc.h cpu/cache.h diff --git a/conf/powerpc-ieee1275.rmk b/conf/powerpc-ieee1275.rmk index e7668fc5d..86f6ddcb3 100644 --- a/conf/powerpc-ieee1275.rmk +++ b/conf/powerpc-ieee1275.rmk @@ -1,10 +1,6 @@ # -*- makefile -*- -COMMON_ASFLAGS = -nostdinc -COMMON_CFLAGS = -ffreestanding -COMMON_LDFLAGS += -nostdlib - # Images. kernel_img_HEADERS += cpu/libgcc.h ieee1275/ieee1275.h diff --git a/conf/sparc64-ieee1275.rmk b/conf/sparc64-ieee1275.rmk index ffa8c1e7c..507a05ab9 100644 --- a/conf/sparc64-ieee1275.rmk +++ b/conf/sparc64-ieee1275.rmk @@ -1,9 +1,8 @@ # -*- makefile -*- -COMMON_ASFLAGS = -nostdinc -m64 -COMMON_CFLAGS = -ffreestanding -m64 -mno-app-regs -COMMON_LDFLAGS = -melf64_sparc -nostdlib -mno-relax +COMMON_CFLAGS = -mno-app-regs +COMMON_LDFLAGS = -melf64_sparc -mno-relax # Images. pkglib_IMAGES = boot.img diskboot.img kernel.img @@ -37,7 +36,7 @@ kernel_img_SOURCES = kern/sparc64/ieee1275/crt0.S kern/ieee1275/cmain.c \ symlist.c kern/$(target_cpu)/cache.S kernel_img_CFLAGS = $(COMMON_CFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) -kernel_img_LDFLAGS = -nostdlib -Wl,-N,-Ttext,0x200000,-Bstatic,-melf64_sparc -static-libgcc -lgcc +kernel_img_LDFLAGS = -Wl,-N,-Ttext,0x200000,-Bstatic,-melf64_sparc -static-libgcc -lgcc kernel_img_FORMAT = binary # Utilities. diff --git a/conf/x86_64-efi.rmk b/conf/x86_64-efi.rmk index 816cce34e..200621280 100644 --- a/conf/x86_64-efi.rmk +++ b/conf/x86_64-efi.rmk @@ -1,7 +1,5 @@ # -*- makefile -*- -COMMON_ASFLAGS = -nostdinc -fno-builtin -m64 -COMMON_CFLAGS = -fno-builtin -m64 -COMMON_LDFLAGS = -melf_x86_64 -nostdlib +COMMON_LDFLAGS = -melf_x86_64 include $(srcdir)/conf/x86-efi.mk diff --git a/configure.ac b/configure.ac index f3fcd8c48..462fca225 100644 --- a/configure.ac +++ b/configure.ac @@ -353,6 +353,7 @@ AC_MSG_RESULT([$TARGET_OBJ2ELF]) if test "x$target_m32" = x1; then # Force 32-bit mode. TARGET_CFLAGS="$TARGET_CFLAGS -m32" + TARGET_ASFLAGS="$TARGET_CFLAGS -m32" TARGET_LDFLAGS="$TARGET_LDFLAGS -m32" TARGET_MODULE_FORMAT="elf32" fi @@ -360,6 +361,7 @@ fi if test "x$target_m64" = x1; then # Force 64-bit mode. TARGET_CFLAGS="$TARGET_CFLAGS -m64" + TARGET_ASFLAGS="$TARGET_ASFLAGS -m64" TARGET_LDFLAGS="$TARGET_LDFLAGS -m64" TARGET_MODULE_FORMAT="elf64" fi From 9a31b3a79763b6080327741a8f86618016c5ddbf Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 10 Feb 2010 01:49:47 +0100 Subject: [PATCH 389/738] Fix yeeloong compilation --- conf/mips-yeeloong.rmk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/conf/mips-yeeloong.rmk b/conf/mips-yeeloong.rmk index 8b6c0426a..0d57a2884 100644 --- a/conf/mips-yeeloong.rmk +++ b/conf/mips-yeeloong.rmk @@ -3,6 +3,8 @@ LINK_BASE = 0x80200000 target_machine=yeeloong COMMON_CFLAGS += -march=mips3 COMMON_ASFLAGS += -march=mips3 + +kernel_img_HEADERS += pci.h include $(srcdir)/conf/mips.mk pkglib_IMAGES = kernel.img @@ -24,7 +26,6 @@ kernel_img_SOURCES = kern/$(target_cpu)/startup.S \ video/bitmap_scale.c video/sm712.c bus/pci.c bus/bonito.c \ term/gfxterm.c commands/extcmd.c lib/arg.c \ symlist.c -kernel_img_HEADERS += pci.h kernel_img_CFLAGS = $(COMMON_CFLAGS) -DUSE_ASCII_FAILBACK kernel_img_ASFLAGS = $(COMMON_ASFLAGS) kernel_img_LDFLAGS = $(COMMON_LDFLAGS) -static-libgcc -lgcc \ @@ -64,4 +65,3 @@ datetime_mod_LDFLAGS = $(COMMON_LDFLAGS) sbin_SCRIPTS += grub-install grub_install_SOURCES = util/grub-install.in - From 52d45a32d3d51ddd8d62c42ab374c15b0f13ac98 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 10 Feb 2010 01:50:40 +0100 Subject: [PATCH 390/738] Add missing tailing newline --- conf/i386-efi.rmk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/i386-efi.rmk b/conf/i386-efi.rmk index a92cff224..e826cb333 100644 --- a/conf/i386-efi.rmk +++ b/conf/i386-efi.rmk @@ -2,4 +2,4 @@ COMMON_LDFLAGS = -melf_i386 -include $(srcdir)/conf/x86-efi.mk \ No newline at end of file +include $(srcdir)/conf/x86-efi.mk From 67443b0d684a8485cdf8706b01ceac6b67180793 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 10 Feb 2010 01:51:02 +0100 Subject: [PATCH 391/738] Remove useless efi grub-setup --- conf/x86-efi.rmk | 8 -------- 1 file changed, 8 deletions(-) diff --git a/conf/x86-efi.rmk b/conf/x86-efi.rmk index b27855aa4..5cb472168 100644 --- a/conf/x86-efi.rmk +++ b/conf/x86-efi.rmk @@ -8,14 +8,6 @@ grub_mkimage_SOURCES = gnulib/progname.c util/i386/efi/grub-mkimage.c \ util/misc.c util/resolve.c util/i386/efi/grub-mkimage.c_DEPENDENCIES = Makefile -# For grub-setup. -#grub_setup_SOURCES = util/i386/pc/grub-setup.c util/hostdisk.c \ -# util/misc.c util/getroot.c kern/device.c kern/disk.c \ -# kern/err.c kern/misc.c fs/fat.c fs/ext2.c fs/xfs.c fs/affs.c \ -# fs/sfs.c kern/parser.c kern/partition.c partmap/msdos.c \ -# fs/ufs.c fs/ufs2.c fs/minix.c fs/hfs.c fs/jfs.c fs/hfsplus.c kern/file.c \ -# kern/fs.c kern/env.c fs/fshelp.c - # Scripts. sbin_SCRIPTS = grub-install From dd01d3970f99a644f03baa09cbd8e85618d2545d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 10 Feb 2010 18:09:44 +0100 Subject: [PATCH 392/738] 2010-02-10 Vladimir Serbinenko * script/execute.c (grub_script_execute_cmdline): Use grub_print_error to show messages instead of discarding them. Process errors after executing command and not before. Keep old method too as precaution. --- ChangeLog | 7 +++++++ script/execute.c | 9 +++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 793018ca9..b3e77335b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-02-10 Vladimir Serbinenko + + * script/execute.c (grub_script_execute_cmdline): Use grub_print_error + to show messages instead of discarding them. + Process errors after executing command and not before. Keep old method + too as precaution. + 2010-02-09 Vladimir Serbinenko * configure.ac: Check for ft2build.h. diff --git a/script/execute.c b/script/execute.c index ee7e099bc..a0773c191 100644 --- a/script/execute.c +++ b/script/execute.c @@ -100,8 +100,8 @@ grub_script_execute_cmdline (struct grub_script_cmd *cmd) grubcmd = grub_command_find (cmdname); if (! grubcmd) { - /* Ignore errors. */ - grub_errno = GRUB_ERR_NONE; + /* Shouldn't happen but precaution is good. */ + grub_print_error (); /* It's not a GRUB command, try all functions. */ func = grub_script_function_find (cmdname); @@ -156,6 +156,11 @@ grub_script_execute_cmdline (struct grub_script_cmd *cmd) grub_free (args[i]); grub_free (args); + if (grub_errno == GRUB_ERR_TEST_FAILURE) + grub_errno = GRUB_ERR_NONE; + + grub_print_error (); + grub_snprintf (errnobuf, sizeof (errnobuf), "%d", ret); grub_env_set ("?", errnobuf); From 65a533e78a4e79b59f24b792bc7dd80c9d1afefb Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 10 Feb 2010 19:53:13 +0100 Subject: [PATCH 393/738] 2010-02-10 Vladimir Serbinenko Support GRUB_GFXPAYLOAD_LINUX. * util/grub-mkconfig.in: Export GRUB_GFXPAYLOAD_LINUX. * util/grub.d/10_linux.in (linux_entry): Handle GRUB_GFXPAYLOAD_LINUX. --- ChangeLog | 7 +++++++ util/grub-mkconfig.in | 1 + util/grub.d/10_linux.in | 10 ++++++++-- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index b3e77335b..b4eb12a54 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-02-10 Vladimir Serbinenko + + Support GRUB_GFXPAYLOAD_LINUX. + + * util/grub-mkconfig.in: Export GRUB_GFXPAYLOAD_LINUX. + * util/grub.d/10_linux.in (linux_entry): Handle GRUB_GFXPAYLOAD_LINUX. + 2010-02-10 Vladimir Serbinenko * script/execute.c (grub_script_execute_cmdline): Use grub_print_error diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in index 7e667fb3e..1363f479a 100644 --- a/util/grub-mkconfig.in +++ b/util/grub-mkconfig.in @@ -221,6 +221,7 @@ export GRUB_DEFAULT \ GRUB_DISABLE_LINUX_RECOVERY \ GRUB_GFXMODE \ GRUB_THEME \ + GRUB_GFXPAYLOAD_LINUX \ GRUB_DISABLE_OS_PROBER if test "x${grub_cfg}" != "x"; then diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in index 8d5379fd6..046874ef0 100644 --- a/util/grub.d/10_linux.in +++ b/util/grub.d/10_linux.in @@ -65,9 +65,15 @@ linux_entry () # Use ELILO's generic "efifb" when it's known to be available. # FIXME: We need an interface to select vesafb in case efifb can't be used. - if grep -qx "CONFIG_FB_EFI=y" /boot/config-${version} 2> /dev/null ; then - cat << EOF + if [ "x$GRUB_GFXPAYLOAD_LINUX" = x ]; then + if grep -qx "CONFIG_FB_EFI=y" /boot/config-${version} 2> /dev/null ; then + cat << EOF set gfxpayload=keep +EOF + fi + else + cat << EOF + set gfxpayload=$GRUB_GFXPAYLOAD_LINUX EOF fi From 7cae4377a2cccea05d6b40a69cd8ac0ad4af4702 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 10 Feb 2010 20:27:12 +0100 Subject: [PATCH 394/738] 2010-02-10 Vladimir Serbinenko Pass SIMPLE framebuffer size in bytes and not 64K blocks. * loader/i386/efi/linux.c (grub_linux_setup_video): Don't divide by 64K. * loader/i386/linux.c (grub_linux_setup_video): Likewise. (grub_linux_boot): Divide by 64K when on VESA. --- ChangeLog | 8 ++++++++ loader/i386/efi/linux.c | 2 +- loader/i386/linux.c | 4 +++- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index b4eb12a54..70353ec0c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2010-02-10 Vladimir Serbinenko + + Pass SIMPLE framebuffer size in bytes and not 64K blocks. + + * loader/i386/efi/linux.c (grub_linux_setup_video): Don't divide by 64K. + * loader/i386/linux.c (grub_linux_setup_video): Likewise. + (grub_linux_boot): Divide by 64K when on VESA. + 2010-02-10 Vladimir Serbinenko Support GRUB_GFXPAYLOAD_LINUX. diff --git a/loader/i386/efi/linux.c b/loader/i386/efi/linux.c index ebaf89743..a6db22e22 100644 --- a/loader/i386/efi/linux.c +++ b/loader/i386/efi/linux.c @@ -576,7 +576,7 @@ grub_linux_setup_video (struct linux_kernel_params *params) params->lfb_line_len = line_len; params->lfb_base = fb_base; - params->lfb_size = (line_len * params->lfb_height + 65535) >> 16; + params->lfb_size = ALIGN_UP (line_len * params->lfb_height, 65536); params->red_mask_size = 8; params->red_field_pos = 16; diff --git a/loader/i386/linux.c b/loader/i386/linux.c index 630aec6f4..d3d935182 100644 --- a/loader/i386/linux.c +++ b/loader/i386/linux.c @@ -410,7 +410,7 @@ grub_linux_setup_video (struct linux_kernel_params *params) params->lfb_line_len = mode_info.pitch; params->lfb_base = (grub_size_t) framebuffer; - params->lfb_size = (params->lfb_line_len * params->lfb_height + 65535) >> 16; + params->lfb_size = ALIGN_UP (params->lfb_line_len * params->lfb_height, 65536); params->red_mask_size = mode_info.red_mask_size; params->red_field_pos = mode_info.red_field_pos; @@ -543,6 +543,8 @@ grub_linux_boot (void) /* Use generic framebuffer unless VESA is known to be supported. */ if (params->have_vga != GRUB_VIDEO_LINUX_TYPE_VESA) params->have_vga = GRUB_VIDEO_LINUX_TYPE_SIMPLE; + else + params->lfb_size >>= 16; } else { From a929c8cd1efbd4322ca6118d25fb4b0c63c77564 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Thu, 11 Feb 2010 18:49:57 +0530 Subject: [PATCH 395/738] fix off-by-one error in menuentry cmd --- ChangeLog.lexer-rewrite | 5 +++++ script/lexer.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog.lexer-rewrite b/ChangeLog.lexer-rewrite index 9b2ab9e2f..24d009d14 100644 --- a/ChangeLog.lexer-rewrite +++ b/ChangeLog.lexer-rewrite @@ -1,3 +1,8 @@ +2010-02-10 BVK Chaitanya + + * script/lexer.c (grub_script_lexer_record_stop): Fix off-by-one + bug. + 2010-01-25 BVK Chaitanya * script/yylex.l: Accept parenthesis as part of word. diff --git a/script/lexer.c b/script/lexer.c index caefdb7a7..42a570348 100644 --- a/script/lexer.c +++ b/script/lexer.c @@ -76,7 +76,7 @@ grub_script_lexer_record_stop (struct grub_parser_param *parser) while (*end && grub_isspace (*end)) end--; if (*end == '}') end--; while (*end && grub_isspace (*end)) end--; - *end = '\0'; + end[1] = '\0'; return start; } From 6bea3f8983a193bb26933556e12d5544d3aac75b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 12 Feb 2010 20:08:56 +0100 Subject: [PATCH 396/738] merge sparc grub-mkimage into grub-mkrawimage --- conf/sparc64-ieee1275.rmk | 2 +- configure.ac | 9 +- include/grub/sparc64/ieee1275/kernel.h | 2 + util/grub-mkrawimage.c | 26 ++- util/sparc64/ieee1275/grub-mkimage.c | 300 ------------------------- 5 files changed, 35 insertions(+), 304 deletions(-) delete mode 100644 util/sparc64/ieee1275/grub-mkimage.c diff --git a/conf/sparc64-ieee1275.rmk b/conf/sparc64-ieee1275.rmk index befc7dce5..6a91b40ee 100644 --- a/conf/sparc64-ieee1275.rmk +++ b/conf/sparc64-ieee1275.rmk @@ -62,7 +62,7 @@ bin_UTILITIES = grub-mkimage sbin_UTILITIES = grub-setup grub-ofpathname # For grub-mkimage. -grub_mkimage_SOURCES = util/sparc64/ieee1275/grub-mkimage.c util/misc.c \ +grub_mkimage_SOURCES = util/grub-mkrawimage.c util/misc.c \ util/resolve.c gnulib/progname.c # For grub-setup. diff --git a/configure.ac b/configure.ac index 48702afd6..b5db67b7a 100644 --- a/configure.ac +++ b/configure.ac @@ -138,9 +138,14 @@ case "$platform" in qemu) machine_CFLAGS="-DGRUB_MACHINE_QEMU=1" ;; pc) machine_CFLAGS="-DGRUB_MACHINE_PCBIOS=1" ;; emu) machine_CFLAGS="-DGRUB_MACHINE_EMU=1" ;; - yeeloong) machine_CFLAGS="-DGRUB_MACHINE_MIPS_YEELOONG=1 -DGRUB_MACHINE_MIPS=1 -DGRUB_MACHINE_MIPS_BONITO=1" ;; - qemu-mips) machine_CFLAGS="-DGRUB_MACHINE_MIPS_QEMU_MIPS=1 -DGRUB_MACHINE_MIPS=1 -DGRUB_MACHINE_MIPS_BONITO=1" ;; + yeeloong) machine_CFLAGS="-DGRUB_MACHINE_MIPS_YEELOONG=1 -DGRUB_MACHINE_MIPS_BONITO=1" ;; + qemu-mips) machine_CFLAGS="-DGRUB_MACHINE_MIPS_QEMU_MIPS=1 -DGRUB_MACHINE_MIPS_BONITO=1" ;; esac +case "$target_cpu" in + mips) machine_CFLAGS="$machine_CFLAGS -DGRUB_MACHINE_MIPS=1" ;; + sparc64) machine_CFLAGS="$machine_CFLAGS -DGRUB_MACHINE_SPARC64=1" ;; +esac + CFLAGS="$CFLAGS $machine_CFLAGS" TARGET_ASFLAGS="$TARGET_ASFLAGS $machine_CFLAGS" TARGET_CFLAGS="$TARGET_CFLAGS $machine_CFLAGS" diff --git a/include/grub/sparc64/ieee1275/kernel.h b/include/grub/sparc64/ieee1275/kernel.h index e63e1f616..8eb1671a8 100644 --- a/include/grub/sparc64/ieee1275/kernel.h +++ b/include/grub/sparc64/ieee1275/kernel.h @@ -39,6 +39,8 @@ /* End of the data section. */ #define GRUB_KERNEL_MACHINE_DATA_END 0x114 +#define GRUB_KERNEL_MACHINE_RAW_SIZE 0 + #ifndef ASM_FILE #include diff --git a/util/grub-mkrawimage.c b/util/grub-mkrawimage.c index 2316479e9..e17446f78 100644 --- a/util/grub-mkrawimage.c +++ b/util/grub-mkrawimage.c @@ -142,7 +142,7 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], } for (p = path_list; p; p = p->next) - total_module_size += (grub_util_get_image_size (p->name) + total_module_size += (ALIGN_UP (grub_util_get_image_size (p->name), 4) + sizeof (struct grub_module_header)); grub_util_info ("the total module size is 0x%x", total_module_size); @@ -295,6 +295,30 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], core_img = rom_img; core_size = rom_size; + free (boot_img); + free (boot_path); + } +#elif defined (GRUB_MACHINE_SPARC64) + { + unsigned int num; + char *boot_path, *boot_img; + size_t boot_size; + + num = ((core_size + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS); + num <<= GRUB_DISK_SECTOR_BITS; + + boot_path = grub_util_get_path (dir, "diskboot.img"); + boot_size = grub_util_get_image_size (boot_path); + if (boot_size != GRUB_DISK_SECTOR_SIZE) + grub_util_error ("diskboot.img is not one sector size"); + + boot_img = grub_util_read_image (boot_path); + + *((grub_uint32_t *) (boot_img + GRUB_DISK_SECTOR_SIZE + - GRUB_BOOT_MACHINE_LIST_SIZE + 8)) + = grub_host_to_target32 (num); + + grub_util_write_image (boot_img, boot_size, out); free (boot_img); free (boot_path); } diff --git a/util/sparc64/ieee1275/grub-mkimage.c b/util/sparc64/ieee1275/grub-mkimage.c deleted file mode 100644 index 6907b8d8a..000000000 --- a/util/sparc64/ieee1275/grub-mkimage.c +++ /dev/null @@ -1,300 +0,0 @@ -/* grub-mkimage.c - make a bootable image */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2008,2009,2010 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#define _GNU_SOURCE 1 -#include - -#include "progname.h" - -static void -compress_kernel (char *kernel_img, size_t kernel_size, - char **core_img, size_t *core_size) -{ - /* No compression support yet. */ - grub_util_info ("kernel_img=%p, kernel_size=0x%x", kernel_img, kernel_size); - *core_img = xmalloc (kernel_size); - memcpy (*core_img, kernel_img, kernel_size); - *core_size = kernel_size; -} - -static void -generate_image (const char *dir, const char *prefix, FILE *out, char *mods[], char *memdisk_path) -{ - size_t kernel_size, total_module_size, memdisk_size, core_size, boot_size, offset; - char *kernel_path, *kernel_img, *core_img, *boot_path, *boot_img; - struct grub_util_path_list *path_list, *p; - struct grub_module_info *modinfo; - grub_addr_t module_addr; - unsigned int num; - - path_list = grub_util_resolve_dependencies (dir, "moddep.lst", mods); - - kernel_path = grub_util_get_path (dir, "kernel.img"); - kernel_size = grub_util_get_image_size (kernel_path); - - total_module_size = sizeof (struct grub_module_info); - for (p = path_list; p; p = p->next) - total_module_size += (grub_util_get_image_size (p->name) - + sizeof (struct grub_module_header)); - - memdisk_size = 0; - if (memdisk_path) - { - memdisk_size = ALIGN_UP(grub_util_get_image_size (memdisk_path), 512); - grub_util_info ("the size of memory disk is 0x%x", memdisk_size); - total_module_size += memdisk_size + sizeof (struct grub_module_header); - } - - grub_util_info ("the total module size is 0x%x", total_module_size); - - kernel_img = xmalloc (kernel_size + total_module_size); - grub_util_load_image (kernel_path, kernel_img); - - if ((GRUB_KERNEL_MACHINE_PREFIX + strlen (prefix) + 1) - > GRUB_KERNEL_MACHINE_DATA_END) - grub_util_error ("prefix too long"); - strcpy (kernel_img + GRUB_KERNEL_MACHINE_PREFIX, prefix); - - /* Fill in the grub_module_info structure. */ - modinfo = (struct grub_module_info *) (kernel_img + kernel_size); - modinfo->magic = GRUB_MODULE_MAGIC; - modinfo->offset = sizeof (struct grub_module_info); - modinfo->size = total_module_size; - - offset = kernel_size + sizeof (struct grub_module_info); - for (p = path_list; p; p = p->next) - { - struct grub_module_header *header; - size_t mod_size; - - mod_size = grub_util_get_image_size (p->name); - - header = (struct grub_module_header *) (kernel_img + offset); - header->type = OBJ_TYPE_ELF; - header->size = grub_host_to_target32 (mod_size + sizeof (*header)); - offset += sizeof (*header); - - grub_util_load_image (p->name, kernel_img + offset); - offset += mod_size; - } - - if (memdisk_path) - { - struct grub_module_header *header; - - header = (struct grub_module_header *) (kernel_img + offset); - header->type = OBJ_TYPE_MEMDISK; - header->size = grub_host_to_target32 (memdisk_size + sizeof (*header)); - offset += sizeof (*header); - - grub_util_load_image (memdisk_path, kernel_img + offset); - offset += memdisk_size; - } - - compress_kernel (kernel_img, kernel_size + total_module_size, - &core_img, &core_size); - - grub_util_info ("the core size is 0x%x", core_size); - - num = ((core_size + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS); - num <<= GRUB_DISK_SECTOR_BITS; - - boot_path = grub_util_get_path (dir, "diskboot.img"); - boot_size = grub_util_get_image_size (boot_path); - if (boot_size != GRUB_DISK_SECTOR_SIZE) - grub_util_error ("diskboot.img is not one sector size"); - - boot_img = grub_util_read_image (boot_path); - - /* sparc is a big endian architecture. */ - *((grub_uint32_t *) (boot_img + GRUB_DISK_SECTOR_SIZE - - GRUB_BOOT_MACHINE_LIST_SIZE + 8)) - = grub_cpu_to_be32 (num); - - grub_util_write_image (boot_img, boot_size, out); - free (boot_img); - free (boot_path); - - module_addr = (path_list - ? (GRUB_BOOT_MACHINE_IMAGE_ADDRESS + kernel_size) - : 0); - - grub_util_info ("the first module address is 0x%x", module_addr); - - *((grub_uint32_t *) (core_img + GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE)) - = grub_cpu_to_be32 (total_module_size); - *((grub_uint32_t *) (core_img + GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE)) - = grub_cpu_to_be32 (kernel_size); - - /* No compression support yet. */ - *((grub_uint32_t *) (core_img + GRUB_KERNEL_MACHINE_COMPRESSED_SIZE)) - = grub_cpu_to_be32 (0); - - grub_util_write_image (core_img, core_size, out); - free (kernel_img); - free (core_img); - free (kernel_path); - - while (path_list) - { - struct grub_util_path_list *next = path_list->next; - free ((void *) path_list->name); - free (path_list); - path_list = next; - } -} - -static struct option options[] = - { - {"directory", required_argument, 0, 'd'}, - {"prefix", required_argument, 0, 'p'}, - {"memdisk", required_argument, 0, 'm'}, - {"output", required_argument, 0, 'o'}, - {"help", no_argument, 0, 'h'}, - {"version", no_argument, 0, 'V'}, - {"verbose", no_argument, 0, 'v'}, - {0, 0, 0, 0} - }; - -static void -usage (int status) -{ - if (status) - fprintf (stderr, "Try `%s --help' for more information.\n", program_name); - else - printf ("\ -Usage: %s [OPTION]... [MODULES]\n\ -\n\ -Make a bootable image of GRUB.\n\ -\n\ - -d, --directory=DIR use images and modules under DIR [default=%s]\n\ - -p, --prefix=DIR set grub_prefix directory [default=%s]\n\ - -m, --memdisk=FILE embed FILE as a memdisk image\n\ - -o, --output=FILE output a generated image to FILE [default=stdout]\n\ - -h, --help display this message and exit\n\ - -V, --version print version information and exit\n\ - -v, --verbose print verbose messages\n\ -\n\ -Report bugs to <%s>.\n\ -", program_name, GRUB_LIBDIR, DEFAULT_DIRECTORY, PACKAGE_BUGREPORT); - - exit (status); -} - -int -main (int argc, char *argv[]) -{ - char *output = NULL; - char *dir = NULL; - char *prefix = NULL; - char *memdisk = NULL; - FILE *fp = stdout; - - set_program_name (argv[0]); - - grub_util_init_nls (); - - while (1) - { - int c = getopt_long (argc, argv, "d:p:m:o:hVv", options, 0); - - if (c == -1) - break; - else - switch (c) - { - case 'o': - if (output) - free (output); - output = xstrdup (optarg); - break; - - case 'd': - if (dir) - free (dir); - dir = xstrdup (optarg); - break; - - case 'm': - if (memdisk) - free (memdisk); - memdisk = xstrdup (optarg); - - if (prefix) - free (prefix); - prefix = xstrdup ("(memdisk)/boot/grub"); - break; - - case 'h': - usage (0); - break; - - case 'p': - if (prefix) - free (prefix); - prefix = xstrdup (optarg); - break; - - case 'V': - printf ("grub-mkimage (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION); - return 0; - - case 'v': - verbosity++; - break; - - default: - usage (1); - break; - } - } - - if (output) - { - fp = fopen (output, "wb"); - if (! fp) - grub_util_error ("cannot open %s", output); - } - - generate_image (dir ? : GRUB_LIBDIR, - prefix ? : DEFAULT_DIRECTORY, fp, - argv + optind, memdisk); - - fclose (fp); - - if (dir) - free (dir); - - return 0; -} From 82da2062d83a2ce5a7c7657c910a051cc47ba809 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 13 Feb 2010 15:25:37 +0100 Subject: [PATCH 397/738] 2010-02-13 Vladimir Serbinenko * util/grub-mkrawimage.c (generate_image): Add forgotten ALIGN_UP. --- ChangeLog | 4 ++++ util/grub-mkrawimage.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 70353ec0c..ddbccd1be 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-02-13 Vladimir Serbinenko + + * util/grub-mkrawimage.c (generate_image): Add forgotten ALIGN_UP. + 2010-02-10 Vladimir Serbinenko Pass SIMPLE framebuffer size in bytes and not 64K blocks. diff --git a/util/grub-mkrawimage.c b/util/grub-mkrawimage.c index 2316479e9..5e8948c27 100644 --- a/util/grub-mkrawimage.c +++ b/util/grub-mkrawimage.c @@ -142,7 +142,7 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], } for (p = path_list; p; p = p->next) - total_module_size += (grub_util_get_image_size (p->name) + total_module_size += (ALIGN_UP (grub_util_get_image_size (p->name), 4) + sizeof (struct grub_module_header)); grub_util_info ("the total module size is 0x%x", total_module_size); From b274d734f3c82897f7a6337b0a2d055f29421e20 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 13 Feb 2010 15:40:13 +0100 Subject: [PATCH 398/738] 2010-02-13 Vladimir Serbinenko Properly create cross-endian images. * include/grub/types.h (grub_host_to_target_addr): New macro * util/grub-mkrawimage.c (generate_image): Add missing host_to_target. --- ChangeLog | 7 +++++++ include/grub/types.h | 6 ++++++ util/grub-mkrawimage.c | 14 +++++++------- 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index ddbccd1be..0d84d9340 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-02-13 Vladimir Serbinenko + + Properly create cross-endian images. + + * include/grub/types.h (grub_host_to_target_addr): New macro + * util/grub-mkrawimage.c (generate_image): Add missing host_to_target. + 2010-02-13 Vladimir Serbinenko * util/grub-mkrawimage.c (generate_image): Add forgotten ALIGN_UP. diff --git a/include/grub/types.h b/include/grub/types.h index 93174b424..9eaafd0c1 100644 --- a/include/grub/types.h +++ b/include/grub/types.h @@ -223,4 +223,10 @@ static inline grub_uint64_t grub_swap_bytes64(grub_uint64_t x) # endif #endif /* ! WORDS_BIGENDIAN */ +#if GRUB_TARGET_SIZEOF_VOID_P == 8 +# define grub_host_to_target_addr(x) grub_host_to_target64(x) +#else +# define grub_host_to_target_addr(x) grub_host_to_target32(x) +#endif + #endif /* ! GRUB_TYPES_HEADER */ diff --git a/util/grub-mkrawimage.c b/util/grub-mkrawimage.c index 5e8948c27..023854c0c 100644 --- a/util/grub-mkrawimage.c +++ b/util/grub-mkrawimage.c @@ -157,9 +157,9 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], /* Fill in the grub_module_info structure. */ modinfo = (struct grub_module_info *) (kernel_img + kernel_size); memset (modinfo, 0, sizeof (struct grub_module_info)); - modinfo->magic = GRUB_MODULE_MAGIC; - modinfo->offset = sizeof (struct grub_module_info); - modinfo->size = total_module_size; + modinfo->magic = grub_host_to_target32 (GRUB_MODULE_MAGIC); + modinfo->offset = grub_host_to_target_addr (sizeof (struct grub_module_info)); + modinfo->size = grub_host_to_target_addr (total_module_size); offset = kernel_size + sizeof (struct grub_module_info); for (p = path_list; p; p = p->next) @@ -172,7 +172,7 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], header = (struct grub_module_header *) (kernel_img + offset); memset (header, 0, sizeof (struct grub_module_header)); - header->type = OBJ_TYPE_ELF; + header->type = grub_host_to_target32 (OBJ_TYPE_ELF); header->size = grub_host_to_target32 (mod_size + sizeof (*header)); offset += sizeof (*header); memset (kernel_img + offset + orig_size, 0, mod_size - orig_size); @@ -187,7 +187,7 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], header = (struct grub_module_header *) (kernel_img + offset); memset (header, 0, sizeof (struct grub_module_header)); - header->type = OBJ_TYPE_MEMDISK; + header->type = grub_host_to_target32 (OBJ_TYPE_MEMDISK); header->size = grub_host_to_target32 (memdisk_size + sizeof (*header)); offset += sizeof (*header); @@ -201,7 +201,7 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], header = (struct grub_module_header *) (kernel_img + offset); memset (header, 0, sizeof (struct grub_module_header)); - header->type = OBJ_TYPE_FONT; + header->type = grub_host_to_target32 (OBJ_TYPE_FONT); header->size = grub_host_to_target32 (font_size + sizeof (*header)); offset += sizeof (*header); @@ -215,7 +215,7 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], header = (struct grub_module_header *) (kernel_img + offset); memset (header, 0, sizeof (struct grub_module_header)); - header->type = OBJ_TYPE_CONFIG; + header->type = grub_host_to_target32 (OBJ_TYPE_CONFIG); header->size = grub_host_to_target32 (config_size + sizeof (*header)); offset += sizeof (*header); From da278c4d348bbc0ce2c3e812282c6f82c234b08d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 13 Feb 2010 15:54:27 +0100 Subject: [PATCH 399/738] 2010-02-13 Vladimir Serbinenko Properly align 64-bit targets. * util/grub-mkrawimage.c (ALIGN_ADDR): New macro. (generate_image): Use ALIGN_ADDR. --- ChangeLog | 7 +++++++ util/grub-mkrawimage.c | 12 +++++++----- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0d84d9340..9591c45a9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-02-13 Vladimir Serbinenko + + Properly align 64-bit targets. + + * util/grub-mkrawimage.c (ALIGN_ADDR): New macro. + (generate_image): Use ALIGN_ADDR. + 2010-02-13 Vladimir Serbinenko Properly create cross-endian images. diff --git a/util/grub-mkrawimage.c b/util/grub-mkrawimage.c index 023854c0c..4ed29744f 100644 --- a/util/grub-mkrawimage.c +++ b/util/grub-mkrawimage.c @@ -41,6 +41,8 @@ #include "progname.h" +#define ALIGN_ADDR(x) (ALIGN_UP((x), GRUB_TARGET_SIZEOF_VOID_P)) + #ifdef ENABLE_LZMA #include @@ -129,20 +131,20 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], if (font_path) { - font_size = ALIGN_UP(grub_util_get_image_size (font_path), 4); + font_size = ALIGN_ADDR (grub_util_get_image_size (font_path)); total_module_size += font_size + sizeof (struct grub_module_header); } if (config_path) { config_size_pure = grub_util_get_image_size (config_path) + 1; - config_size = ALIGN_UP(config_size_pure, 4); + config_size = ALIGN_ADDR (config_size_pure); grub_util_info ("the size of config file is 0x%x", config_size); total_module_size += config_size + sizeof (struct grub_module_header); } for (p = path_list; p; p = p->next) - total_module_size += (ALIGN_UP (grub_util_get_image_size (p->name), 4) + total_module_size += (ALIGN_ADDR (grub_util_get_image_size (p->name)) + sizeof (struct grub_module_header)); grub_util_info ("the total module size is 0x%x", total_module_size); @@ -168,7 +170,7 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], size_t mod_size, orig_size; orig_size = grub_util_get_image_size (p->name); - mod_size = ALIGN_UP(orig_size, 4); + mod_size = ALIGN_ADDR (orig_size); header = (struct grub_module_header *) (kernel_img + offset); memset (header, 0, sizeof (struct grub_module_header)); @@ -339,7 +341,7 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], Elf32_Phdr *phdr; grub_uint32_t target_addr; - program_size = ALIGN_UP (core_size, 4); + program_size = ALIGN_ADDR (core_size); elf_img = xmalloc (program_size + sizeof (*ehdr) + sizeof (*phdr)); memset (elf_img, 0, program_size + sizeof (*ehdr) + sizeof (*phdr)); From bdca260795fdc2b58a7ca83d46a9ce97aedbd7e4 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 13 Feb 2010 15:57:42 +0100 Subject: [PATCH 400/738] 2010-02-13 Vladimir Serbinenko * util/grub-mkrawimage.c (main): Call set_program_name. --- ChangeLog | 4 ++++ util/grub-mkrawimage.c | 2 ++ 2 files changed, 6 insertions(+) diff --git a/ChangeLog b/ChangeLog index 9591c45a9..760ac720c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-02-13 Vladimir Serbinenko + + * util/grub-mkrawimage.c (main): Call set_program_name. + 2010-02-13 Vladimir Serbinenko Properly align 64-bit targets. diff --git a/util/grub-mkrawimage.c b/util/grub-mkrawimage.c index 4ed29744f..83bb51c02 100644 --- a/util/grub-mkrawimage.c +++ b/util/grub-mkrawimage.c @@ -476,6 +476,8 @@ main (int argc, char *argv[]) grub_platform_image_format_t format = GRUB_PLATFORM_IMAGE_DEFAULT; #endif + set_program_name (argv[0]); + grub_util_init_nls (); while (1) From ca62070b698ab3acc91eb1594b77d404dd1c1546 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 13 Feb 2010 16:13:28 +0100 Subject: [PATCH 401/738] 2010-02-13 Vladimir Serbinenko Fix over-4GiB seek on sparc64. * include/grub/ieee1275/ieee1275.h (grub_ieee1275_seek): Replace pos_i and pos_lo with pos. All users updated. * include/grub/powerpc/ieee1275/ieee1275.h (GRUB_IEEE1275_CELL_SIZEOF): New constant. * include/grub/sparc64/ieee1275/ieee1275.h (GRUB_IEEE1275_CELL_SIZEOF): Likewise. * kern/ieee1275/ieee1275.c (grub_ieee1275_seek): Split pos into pos_hi and pos_lo. --- ChangeLog | 13 +++++++++++++ disk/ieee1275/ofdisk.c | 2 +- include/grub/ieee1275/ieee1275.h | 2 +- include/grub/powerpc/ieee1275/ieee1275.h | 1 + include/grub/sparc64/ieee1275/ieee1275.h | 1 + kern/ieee1275/ieee1275.c | 15 +++++++++++---- 6 files changed, 28 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 760ac720c..6f1820d5e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2010-02-13 Vladimir Serbinenko + + Fix over-4GiB seek on sparc64. + + * include/grub/ieee1275/ieee1275.h (grub_ieee1275_seek): + Replace pos_i and pos_lo with pos. All users updated. + * include/grub/powerpc/ieee1275/ieee1275.h (GRUB_IEEE1275_CELL_SIZEOF): + New constant. + * include/grub/sparc64/ieee1275/ieee1275.h (GRUB_IEEE1275_CELL_SIZEOF): + Likewise. + * kern/ieee1275/ieee1275.c (grub_ieee1275_seek): Split pos into pos_hi + and pos_lo. + 2010-02-13 Vladimir Serbinenko * util/grub-mkrawimage.c (main): Call set_program_name. diff --git a/disk/ieee1275/ofdisk.c b/disk/ieee1275/ofdisk.c index 238cff33d..0adedf33f 100644 --- a/disk/ieee1275/ofdisk.c +++ b/disk/ieee1275/ofdisk.c @@ -241,7 +241,7 @@ grub_ofdisk_read (grub_disk_t disk, grub_disk_addr_t sector, pos = sector * 512UL; grub_ieee1275_seek ((grub_ieee1275_ihandle_t) (unsigned long) disk->data, - (int) (pos >> 32), (int) pos & 0xFFFFFFFFUL, &status); + pos, &status); if (status < 0) return grub_error (GRUB_ERR_READ_ERROR, "seek error, can't seek block %llu", diff --git a/include/grub/ieee1275/ieee1275.h b/include/grub/ieee1275/ieee1275.h index 8b31e32e2..a852a7b61 100644 --- a/include/grub/ieee1275/ieee1275.h +++ b/include/grub/ieee1275/ieee1275.h @@ -138,7 +138,7 @@ int EXPORT_FUNC(grub_ieee1275_read) (grub_ieee1275_ihandle_t ihandle, void *buffer, grub_size_t len, grub_ssize_t *actualp); int EXPORT_FUNC(grub_ieee1275_seek) (grub_ieee1275_ihandle_t ihandle, - int pos_hi, int pos_lo, + grub_disk_addr_t pos, grub_ssize_t *result); int EXPORT_FUNC(grub_ieee1275_peer) (grub_ieee1275_phandle_t node, grub_ieee1275_phandle_t *result); diff --git a/include/grub/powerpc/ieee1275/ieee1275.h b/include/grub/powerpc/ieee1275/ieee1275.h index 7e93055c9..3c7683fad 100644 --- a/include/grub/powerpc/ieee1275/ieee1275.h +++ b/include/grub/powerpc/ieee1275/ieee1275.h @@ -22,6 +22,7 @@ #include +#define GRUB_IEEE1275_CELL_SIZEOF 4 typedef grub_uint32_t grub_ieee1275_cell_t; #endif /* ! GRUB_IEEE1275_MACHINE_HEADER */ diff --git a/include/grub/sparc64/ieee1275/ieee1275.h b/include/grub/sparc64/ieee1275/ieee1275.h index b25e98a6d..1619510fb 100644 --- a/include/grub/sparc64/ieee1275/ieee1275.h +++ b/include/grub/sparc64/ieee1275/ieee1275.h @@ -22,6 +22,7 @@ #include +#define GRUB_IEEE1275_CELL_SIZEOF 8 typedef grub_uint64_t grub_ieee1275_cell_t; /* Encoding of 'mode' argument to grub_ieee1275_map_physical() */ diff --git a/kern/ieee1275/ieee1275.c b/kern/ieee1275/ieee1275.c index 8a5773c23..9e2919172 100644 --- a/kern/ieee1275/ieee1275.c +++ b/kern/ieee1275/ieee1275.c @@ -284,8 +284,8 @@ grub_ieee1275_read (grub_ieee1275_ihandle_t ihandle, void *buffer, } int -grub_ieee1275_seek (grub_ieee1275_ihandle_t ihandle, int pos_hi, - int pos_lo, grub_ssize_t *result) +grub_ieee1275_seek (grub_ieee1275_ihandle_t ihandle, grub_disk_addr_t pos, + grub_ssize_t *result) { struct write_args { @@ -299,8 +299,15 @@ grub_ieee1275_seek (grub_ieee1275_ihandle_t ihandle, int pos_hi, INIT_IEEE1275_COMMON (&args.common, "seek", 3, 1); args.ihandle = ihandle; - args.pos_hi = (grub_ieee1275_cell_t) pos_hi; - args.pos_lo = (grub_ieee1275_cell_t) pos_lo; + /* To prevent stupid gcc warning. */ +#if GRUB_IEEE1275_CELL_SIZEOF >= 8 + args.pos_hi = 0; + args.pos_lo = pos; +#else + args.pos_hi = (grub_ieee1275_cell_t) (pos >> (8 * GRUB_IEEE1275_CELL_SIZEOF)); + args.pos_lo = (grub_ieee1275_cell_t) + (pos & ((1ULL << (8 * GRUB_IEEE1275_CELL_SIZEOF)) - 1)); +#endif if (IEEE1275_CALL_ENTRY_FN (&args) == -1) return -1; From e0128bbdc4243cb676156cca5c1a31f216d562f6 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 13 Feb 2010 16:16:40 +0100 Subject: [PATCH 402/738] 2010-02-13 Vladimir Serbinenko * disk/ieee1275/ofdisk.c (grub_ofdisk_read): Remove excessively verbose dprintf. --- ChangeLog | 5 +++++ disk/ieee1275/ofdisk.c | 4 ---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6f1820d5e..6690f7f81 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-02-13 Vladimir Serbinenko + + * disk/ieee1275/ofdisk.c (grub_ofdisk_read): Remove excessively + verbose dprintf. + 2010-02-13 Vladimir Serbinenko Fix over-4GiB seek on sparc64. diff --git a/disk/ieee1275/ofdisk.c b/disk/ieee1275/ofdisk.c index 0adedf33f..05c0dd04d 100644 --- a/disk/ieee1275/ofdisk.c +++ b/disk/ieee1275/ofdisk.c @@ -234,10 +234,6 @@ grub_ofdisk_read (grub_disk_t disk, grub_disk_addr_t sector, grub_ssize_t status, actual; unsigned long long pos; - grub_dprintf ("disk", - "Reading handle %p: sector 0x%llx, size 0x%lx, buf %p.\n", - (void *) disk->data, (long long) sector, (long) size, buf); - pos = sector * 512UL; grub_ieee1275_seek ((grub_ieee1275_ihandle_t) (unsigned long) disk->data, From 17cec782c4463f8c92d130eca1f0e2439803c1e2 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 13 Feb 2010 16:23:20 +0100 Subject: [PATCH 403/738] 2010-02-13 Vladimir Serbinenko * kern/sparc64/ieee1275/crt0.S (codestart): Move modules backwards. --- ChangeLog | 4 ++++ kern/sparc64/ieee1275/crt0.S | 8 ++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6690f7f81..47da5ccf2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-02-13 Vladimir Serbinenko + + * kern/sparc64/ieee1275/crt0.S (codestart): Move modules backwards. + 2010-02-13 Vladimir Serbinenko * disk/ieee1275/ofdisk.c (grub_ofdisk_read): Remove excessively diff --git a/kern/sparc64/ieee1275/crt0.S b/kern/sparc64/ieee1275/crt0.S index 4e67cbc19..3749f3005 100644 --- a/kern/sparc64/ieee1275/crt0.S +++ b/kern/sparc64/ieee1275/crt0.S @@ -53,12 +53,16 @@ codestart: or %o3, %lo(_end), %o3 sethi %hi(grub_total_module_size), %o4 lduw [%o4 + %lo(grub_total_module_size)], %o4 + add %o2, %o4, %o2 + add %o3, %o4, %o3 + sub %o2, 4, %o2 + sub %o3, 4, %o3 1: lduw [%o2], %o5 stw %o5, [%o3] subcc %o4, 4, %o4 - add %o2, 4, %o2 + sub %o2, 4, %o2 bne,pt %icc, 1b - add %o3, 4, %o3 + sub %o3, 4, %o3 /* Now it's safe to clear out the BSS. */ sethi %hi(__bss_start), %o2 From a49217cff7157395f3770f84fd5b1f01d107cce3 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 13 Feb 2010 16:26:50 +0100 Subject: [PATCH 404/738] aout image support --- boot/sparc64/ieee1275/diskboot.S | 2 +- conf/sparc64-ieee1275.rmk | 2 +- include/grub/aout.h | 5 + include/grub/kernel.h | 2 + include/grub/sparc64/ieee1275/kernel.h | 13 +++ kern/main.c | 19 ++++ kern/mips/yeeloong/init.c | 28 +----- kern/sparc64/ieee1275/crt0.S | 2 +- kern/sparc64/ieee1275/init.c | 2 +- util/grub-mkrawimage.c | 128 +++++++++++++++---------- 10 files changed, 122 insertions(+), 81 deletions(-) diff --git a/boot/sparc64/ieee1275/diskboot.S b/boot/sparc64/ieee1275/diskboot.S index 68ed0eee0..5016bf9e0 100644 --- a/boot/sparc64/ieee1275/diskboot.S +++ b/boot/sparc64/ieee1275/diskboot.S @@ -129,7 +129,7 @@ bootit: mov NOTIFICATION_DONE_LEN, %o3 sethi %hi(GRUB_BOOT_MACHINE_IMAGE_ADDRESS), %o2 jmpl %o2 + %lo(GRUB_BOOT_MACHINE_IMAGE_ADDRESS), %o7 - mov CIF_REG, %o0 + mov CIF_REG, %o4 1: ba,a 1b lastlist: diff --git a/conf/sparc64-ieee1275.rmk b/conf/sparc64-ieee1275.rmk index 6a91b40ee..4b51a5c3e 100644 --- a/conf/sparc64-ieee1275.rmk +++ b/conf/sparc64-ieee1275.rmk @@ -48,7 +48,7 @@ kernel_img_SOURCES = kern/sparc64/ieee1275/crt0.S kern/ieee1275/cmain.c \ symlist.c kern/$(target_cpu)/cache.S kernel_img_CFLAGS = $(COMMON_CFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) -kernel_img_LDFLAGS = -nostdlib -Wl,-N,-Ttext,0x200000,-Bstatic,-melf64_sparc -static-libgcc -lgcc +kernel_img_LDFLAGS = -nostdlib -Wl,-N,-Ttext,0x4400,-Bstatic,-melf64_sparc -static-libgcc -lgcc kernel_img_FORMAT = binary symlist.c: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h gensymlist.sh diff --git a/include/grub/aout.h b/include/grub/aout.h index 04e85f8b0..f962a97b3 100644 --- a/include/grub/aout.h +++ b/include/grub/aout.h @@ -102,6 +102,7 @@ union grub_aout_header #define AOUT_MID_I386 134 /* i386 BSD binary */ #define AOUT_MID_SPARC 138 /* sparc */ #define AOUT_MID_HP200 200 /* hp200 (68010) BSD binary */ +#define AOUT_MID_SUN 0x103 #define AOUT_MID_HP300 300 /* hp300 (68020+68881) BSD binary */ #define AOUT_MID_HPUX 0x20C /* hp200/300 HP-UX binary */ #define AOUT_MID_HPUX800 0x20B /* hp800 HP-UX binary */ @@ -114,10 +115,14 @@ union grub_aout_header #define AOUT_GETMID(header) ((header).a_midmag >> 16) & 0x03ff) #define AOUT_GETFLAG(header) ((header).a_midmag >> 26) & 0x3f) +#ifndef GRUB_UTIL + int EXPORT_FUNC(grub_aout_get_type) (union grub_aout_header *header); grub_err_t EXPORT_FUNC(grub_aout_load) (grub_file_t file, int offset, grub_addr_t load_addr, int load_size, grub_addr_t bss_end_addr); +#endif + #endif /* ! GRUB_AOUT_HEADER */ diff --git a/include/grub/kernel.h b/include/grub/kernel.h index 9586a90b9..bf52ffcb4 100644 --- a/include/grub/kernel.h +++ b/include/grub/kernel.h @@ -59,6 +59,8 @@ extern grub_addr_t grub_arch_modules_addr (void); extern void EXPORT_FUNC(grub_module_iterate) (int (*hook) (struct grub_module_header *)); +grub_addr_t grub_modules_get_end (void); + /* The start point of the C code. */ void grub_main (void); diff --git a/include/grub/sparc64/ieee1275/kernel.h b/include/grub/sparc64/ieee1275/kernel.h index 8eb1671a8..78e039bc5 100644 --- a/include/grub/sparc64/ieee1275/kernel.h +++ b/include/grub/sparc64/ieee1275/kernel.h @@ -41,8 +41,21 @@ #define GRUB_KERNEL_MACHINE_RAW_SIZE 0 +#define GRUB_PLATFORM_IMAGE_FORMATS "raw, aout" +#define GRUB_PLATFORM_IMAGE_DEFAULT_FORMAT "raw" + +#define GRUB_PLATFORM_IMAGE_DEFAULT GRUB_PLATFORM_IMAGE_RAW + #ifndef ASM_FILE +typedef enum { + GRUB_PLATFORM_IMAGE_RAW, + GRUB_PLATFORM_IMAGE_AOUT +} + grub_platform_image_format_t; +#define GRUB_PLATFORM_IMAGE_RAW GRUB_PLATFORM_IMAGE_RAW +#define GRUB_PLATFORM_IMAGE_AOUT GRUB_PLATFORM_IMAGE_AOUT + #include #include diff --git a/kern/main.c b/kern/main.c index 456105378..54235821d 100644 --- a/kern/main.c +++ b/kern/main.c @@ -53,6 +53,25 @@ grub_module_iterate (int (*hook) (struct grub_module_header *header)) } } +/* This is actualy platform-independant but used only on yeeloong and sparc. */ +#if defined (GRUB_MACHINE_MIPS_YEELOONG) || defined (GRUB_MACHINE_SPARC64) +grub_addr_t +grub_modules_get_end (void) +{ + struct grub_module_info *modinfo; + grub_addr_t modbase; + + modbase = grub_arch_modules_addr (); + modinfo = (struct grub_module_info *) modbase; + + /* Check if there are any modules. */ + if ((modinfo == 0) || modinfo->magic != GRUB_MODULE_MAGIC) + return modbase; + + return modbase + modinfo->size; +} +#endif + /* Load all modules in core. */ static void grub_load_modules (void) diff --git a/kern/mips/yeeloong/init.c b/kern/mips/yeeloong/init.c index 14e8a39a2..d148d08dc 100644 --- a/kern/mips/yeeloong/init.c +++ b/kern/mips/yeeloong/init.c @@ -63,35 +63,13 @@ grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, return GRUB_ERR_NONE; } - -static void * -get_modules_end (void) -{ - struct grub_module_info *modinfo; - struct grub_module_header *header; - grub_addr_t modbase; - - modbase = grub_arch_modules_addr (); - modinfo = (struct grub_module_info *) modbase; - - /* Check if there are any modules. */ - if ((modinfo == 0) || modinfo->magic != GRUB_MODULE_MAGIC) - return modinfo; - - for (header = (struct grub_module_header *) (modbase + modinfo->offset); - header < (struct grub_module_header *) (modbase + modinfo->size); - header = (struct grub_module_header *) ((char *) header + header->size)); - - return header; -} - void grub_machine_init (void) { - void *modend; - modend = get_modules_end (); + grub_addr_t modend; + modend = grub_modules_get_end (); grub_mm_init_region (modend, (grub_arch_memsize << 20) - - (((grub_addr_t) modend) - GRUB_ARCH_LOWMEMVSTART)); + - (modend - GRUB_ARCH_LOWMEMVSTART)); /* FIXME: use upper memory as well. */ grub_install_get_time_ms (grub_rtc_get_time_ms); diff --git a/kern/sparc64/ieee1275/crt0.S b/kern/sparc64/ieee1275/crt0.S index 4e67cbc19..1dc65dc64 100644 --- a/kern/sparc64/ieee1275/crt0.S +++ b/kern/sparc64/ieee1275/crt0.S @@ -24,7 +24,7 @@ .globl _start _start: ba codestart - nop + mov %o4, %o0 . = EXT_C(_start) + GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE diff --git a/kern/sparc64/ieee1275/init.c b/kern/sparc64/ieee1275/init.c index 115328f40..5827be658 100644 --- a/kern/sparc64/ieee1275/init.c +++ b/kern/sparc64/ieee1275/init.c @@ -104,7 +104,7 @@ grub_machine_set_prefix (void) static void grub_heap_init (void) { - grub_mm_init_region ((void *)(long)0x4000UL, 0x200000 - 0x4000); + grub_mm_init_region ((void *) grub_modules_get_end (), 0x200000); } static void diff --git a/util/grub-mkrawimage.c b/util/grub-mkrawimage.c index e17446f78..26ccd7d94 100644 --- a/util/grub-mkrawimage.c +++ b/util/grub-mkrawimage.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -230,6 +231,36 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], grub_util_info ("the core size is 0x%x", core_size); +#ifdef GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE + *((grub_uint32_t *) (core_img + GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE)) + = grub_host_to_target32 (total_module_size); +#endif + *((grub_uint32_t *) (core_img + GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE)) + = grub_host_to_target32 (kernel_size); +#ifdef GRUB_KERNEL_MACHINE_COMPRESSED_SIZE + *((grub_uint32_t *) (core_img + GRUB_KERNEL_MACHINE_COMPRESSED_SIZE)) + = grub_host_to_target32 (core_size - GRUB_KERNEL_MACHINE_RAW_SIZE); +#endif + +#if defined(GRUB_KERNEL_MACHINE_INSTALL_DOS_PART) && defined(GRUB_KERNEL_MACHINE_INSTALL_BSD_PART) + /* If we included a drive in our prefix, let GRUB know it doesn't have to + prepend the drive told by BIOS. */ + if (prefix[0] == '(') + { + *((grub_int32_t *) (core_img + GRUB_KERNEL_MACHINE_INSTALL_DOS_PART)) + = grub_host_to_target32 (-2); + *((grub_int32_t *) (core_img + GRUB_KERNEL_MACHINE_INSTALL_BSD_PART)) + = grub_host_to_target32 (-2); + } +#endif + +#ifdef GRUB_MACHINE_PCBIOS + if (GRUB_KERNEL_MACHINE_LINK_ADDR + core_size > GRUB_MEMORY_MACHINE_UPPER) + grub_util_error (_("core image is too big (%p > %p)"), + GRUB_KERNEL_MACHINE_LINK_ADDR + core_size, + GRUB_MEMORY_MACHINE_UPPER); +#endif + #if defined(GRUB_MACHINE_PCBIOS) { unsigned num; @@ -299,62 +330,50 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], free (boot_path); } #elif defined (GRUB_MACHINE_SPARC64) - { - unsigned int num; - char *boot_path, *boot_img; - size_t boot_size; - - num = ((core_size + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS); - num <<= GRUB_DISK_SECTOR_BITS; - - boot_path = grub_util_get_path (dir, "diskboot.img"); - boot_size = grub_util_get_image_size (boot_path); - if (boot_size != GRUB_DISK_SECTOR_SIZE) - grub_util_error ("diskboot.img is not one sector size"); - - boot_img = grub_util_read_image (boot_path); - - *((grub_uint32_t *) (boot_img + GRUB_DISK_SECTOR_SIZE - - GRUB_BOOT_MACHINE_LIST_SIZE + 8)) - = grub_host_to_target32 (num); - - grub_util_write_image (boot_img, boot_size, out); - free (boot_img); - free (boot_path); - } -#endif - -#ifdef GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE - *((grub_uint32_t *) (core_img + GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE)) - = grub_host_to_target32 (total_module_size); -#endif - *((grub_uint32_t *) (core_img + GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE)) - = grub_host_to_target32 (kernel_size); -#ifdef GRUB_KERNEL_MACHINE_COMPRESSED_SIZE - *((grub_uint32_t *) (core_img + GRUB_KERNEL_MACHINE_COMPRESSED_SIZE)) - = grub_host_to_target32 (core_size - GRUB_KERNEL_MACHINE_RAW_SIZE); -#endif - -#if defined(GRUB_KERNEL_MACHINE_INSTALL_DOS_PART) && defined(GRUB_KERNEL_MACHINE_INSTALL_BSD_PART) - /* If we included a drive in our prefix, let GRUB know it doesn't have to - prepend the drive told by BIOS. */ - if (prefix[0] == '(') + if (format == GRUB_PLATFORM_IMAGE_AOUT) { - *((grub_int32_t *) (core_img + GRUB_KERNEL_MACHINE_INSTALL_DOS_PART)) - = grub_host_to_target32 (-2); - *((grub_int32_t *) (core_img + GRUB_KERNEL_MACHINE_INSTALL_BSD_PART)) - = grub_host_to_target32 (-2); + void *aout_img; + size_t aout_size; + struct grub_aout32_header *aout_head; + + aout_size = core_size + sizeof (*aout_head); + aout_img = xmalloc (aout_size); + aout_head = aout_img; + aout_head->a_midmag = grub_host_to_target32 ((AOUT_MID_SUN << 16) + | AOUT32_OMAGIC); + aout_head->a_text = grub_host_to_target32 (core_size); + aout_head->a_entry = grub_host_to_target32 (0x4400); + memcpy (aout_img + sizeof (*aout_head), core_img, core_size); + + free (core_img); + core_img = aout_img; + core_size = aout_size; } -#endif + else + { + unsigned int num; + char *boot_path, *boot_img; + size_t boot_size; -#ifdef GRUB_MACHINE_PCBIOS - if (GRUB_KERNEL_MACHINE_LINK_ADDR + core_size > GRUB_MEMORY_MACHINE_UPPER) - grub_util_error (_("core image is too big (%p > %p)"), - GRUB_KERNEL_MACHINE_LINK_ADDR + core_size, - GRUB_MEMORY_MACHINE_UPPER); -#endif + num = ((core_size + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS); + num <<= GRUB_DISK_SECTOR_BITS; -#if defined(GRUB_MACHINE_MIPS) + boot_path = grub_util_get_path (dir, "diskboot.img"); + boot_size = grub_util_get_image_size (boot_path); + if (boot_size != GRUB_DISK_SECTOR_SIZE) + grub_util_error ("diskboot.img is not one sector size"); + + boot_img = grub_util_read_image (boot_path); + + *((grub_uint32_t *) (boot_img + GRUB_DISK_SECTOR_SIZE + - GRUB_BOOT_MACHINE_LIST_SIZE + 8)) + = grub_host_to_target32 (num); + + grub_util_write_image (boot_img, boot_size, out); + free (boot_img); + free (boot_path); + } +#elif defined(GRUB_MACHINE_MIPS) if (format == GRUB_PLATFORM_IMAGE_ELF) { char *elf_img; @@ -527,6 +546,11 @@ main (int argc, char *argv[]) if (strcmp (optarg, "elf") == 0) format = GRUB_PLATFORM_IMAGE_ELF; else +#endif +#ifdef GRUB_PLATFORM_IMAGE_AOUT + if (strcmp (optarg, "aout") == 0) + format = GRUB_PLATFORM_IMAGE_AOUT; + else #endif usage (1); break; From 8c6052cea547d2d6960d22b19b75a75870cb98bc Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 13 Feb 2010 16:30:22 +0100 Subject: [PATCH 405/738] 2010-02-13 Vladimir Serbinenko * loader/sparc64/ieee1275/linux.c (alloc_phys): Correct bounds checking. --- ChangeLog | 4 ++++ loader/sparc64/ieee1275/linux.c | 10 +++++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 47da5ccf2..c9f64df01 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-02-13 Vladimir Serbinenko + + * loader/sparc64/ieee1275/linux.c (alloc_phys): Correct bounds checking. + 2010-02-13 Vladimir Serbinenko * kern/sparc64/ieee1275/crt0.S (codestart): Move modules backwards. diff --git a/loader/sparc64/ieee1275/linux.c b/loader/sparc64/ieee1275/linux.c index 42bae6bb8..51d82ddcc 100644 --- a/loader/sparc64/ieee1275/linux.c +++ b/loader/sparc64/ieee1275/linux.c @@ -193,20 +193,20 @@ alloc_phys (grub_addr_t size) return 0; addr = align_addr (addr, FOUR_MB); - if (addr >= end) + if (addr + size >= end) return 0; if (addr >= grub_phys_start && addr < grub_phys_end) { addr = align_addr (grub_phys_end, FOUR_MB); - if (addr >= end) + if (addr + size >= end) return 0; } if ((addr + size) >= grub_phys_start && (addr + size) < grub_phys_end) { addr = align_addr (grub_phys_end, FOUR_MB); - if (addr >= end) + if (addr + size >= end) return 0; } @@ -217,14 +217,14 @@ alloc_phys (grub_addr_t size) if (addr >= linux_paddr && addr < linux_end) { addr = linux_end; - if (addr >= end) + if (addr + size >= end) return 0; } if ((addr + size) >= linux_paddr && (addr + size) < linux_end) { addr = linux_end; - if (addr >= end) + if (addr + size >= end) return 0; } } From 2c0fcc366632cbbf9bf14a6ded41088a0a72f4df Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 13 Feb 2010 16:32:24 +0100 Subject: [PATCH 406/738] 2010-02-13 Vladimir Serbinenko * loader/sparc64/ieee1275/linux.c (align_addr): Remove. (alloc_phys): Use ALIGN_UP instead of align_addr. --- ChangeLog | 5 +++++ loader/sparc64/ieee1275/linux.c | 14 ++++---------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index c9f64df01..01067182f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-02-13 Vladimir Serbinenko + + * loader/sparc64/ieee1275/linux.c (align_addr): Remove. + (alloc_phys): Use ALIGN_UP instead of align_addr. + 2010-02-13 Vladimir Serbinenko * loader/sparc64/ieee1275/linux.c (alloc_phys): Correct bounds checking. diff --git a/loader/sparc64/ieee1275/linux.c b/loader/sparc64/ieee1275/linux.c index 51d82ddcc..65f334ab3 100644 --- a/loader/sparc64/ieee1275/linux.c +++ b/loader/sparc64/ieee1275/linux.c @@ -173,12 +173,6 @@ grub_linux_unload (void) #define FOUR_MB (4 * 1024 * 1024) -static grub_addr_t -align_addr(grub_addr_t val, grub_addr_t align) -{ - return (val + (align - 1)) & ~(align - 1); -} - static grub_addr_t alloc_phys (grub_addr_t size) { @@ -192,27 +186,27 @@ alloc_phys (grub_addr_t size) if (type != 1) return 0; - addr = align_addr (addr, FOUR_MB); + addr = ALIGN_UP (addr, FOUR_MB); if (addr + size >= end) return 0; if (addr >= grub_phys_start && addr < grub_phys_end) { - addr = align_addr (grub_phys_end, FOUR_MB); + addr = ALIGN_UP (grub_phys_end, FOUR_MB); if (addr + size >= end) return 0; } if ((addr + size) >= grub_phys_start && (addr + size) < grub_phys_end) { - addr = align_addr (grub_phys_end, FOUR_MB); + addr = ALIGN_UP (grub_phys_end, FOUR_MB); if (addr + size >= end) return 0; } if (loaded) { - grub_addr_t linux_end = align_addr (linux_paddr + linux_size, FOUR_MB); + grub_addr_t linux_end = ALIGN_UP (linux_paddr + linux_size, FOUR_MB); if (addr >= linux_paddr && addr < linux_end) { From 69e137e819725cd86617aa3de826c4b19f390f5a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 13 Feb 2010 16:40:29 +0100 Subject: [PATCH 407/738] 2010-02-13 Vladimir Serbinenko * term/ieee1275/ofconsole.c (grub_ofconsole_readkey): Macroify constants. --- ChangeLog | 5 +++++ term/ieee1275/ofconsole.c | 18 +++++++++--------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index 01067182f..ff5621a56 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-02-13 Vladimir Serbinenko + + * term/ieee1275/ofconsole.c (grub_ofconsole_readkey): Macroify + constants. + 2010-02-13 Vladimir Serbinenko * loader/sparc64/ieee1275/linux.c (align_addr): Remove. diff --git a/term/ieee1275/ofconsole.c b/term/ieee1275/ofconsole.c index 51dca7a53..6073e25d2 100644 --- a/term/ieee1275/ofconsole.c +++ b/term/ieee1275/ofconsole.c @@ -165,7 +165,7 @@ grub_ofconsole_readkey (int *key) return 1; } - if (c != 91) + if (c != '[') return 0; grub_ieee1275_read (stdin_ihandle, &c, 1, &actual); @@ -174,21 +174,21 @@ grub_ofconsole_readkey (int *key) switch (c) { - case 65: + case 'A': /* Up: Ctrl-p. */ - c = 16; + c = GRUB_TERM_UP; break; - case 66: + case 'B': /* Down: Ctrl-n. */ - c = 14; + c = GRUB_TERM_DOWN; break; - case 67: + case 'C': /* Right: Ctrl-f. */ - c = 6; + c = GRUB_TERM_RIGHT; break; - case 68: + case 'D': /* Left: Ctrl-b. */ - c = 2; + c = GRUB_TERM_LEFT; break; } } From 5b59a4e367fc4510e0ae4f4181c0c71841233783 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 13 Feb 2010 16:44:34 +0100 Subject: [PATCH 408/738] 2010-02-13 Vladimir Serbinenko * disk/ieee1275/ofdisk.c (grub_ofdisk_open): Check device type before opening and not after. --- ChangeLog | 5 +++++ disk/ieee1275/ofdisk.c | 20 ++++++++++---------- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index ff5621a56..eb937f97e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-02-13 Vladimir Serbinenko + + * disk/ieee1275/ofdisk.c (grub_ofdisk_open): Check device type before + opening and not after. + 2010-02-13 Vladimir Serbinenko * term/ieee1275/ofconsole.c (grub_ofconsole_readkey): Macroify diff --git a/disk/ieee1275/ofdisk.c b/disk/ieee1275/ofdisk.c index 05c0dd04d..e5a4a67fa 100644 --- a/disk/ieee1275/ofdisk.c +++ b/disk/ieee1275/ofdisk.c @@ -172,16 +172,6 @@ grub_ofdisk_open (const char *name, grub_disk_t disk) grub_dprintf ("disk", "Opening `%s'.\n", op->devpath); - grub_ieee1275_open (op->devpath, &dev_ihandle); - if (! dev_ihandle) - { - grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't open device"); - goto fail; - } - - grub_dprintf ("disk", "Opened `%s' as handle %p.\n", op->devpath, - (void *) (unsigned long) dev_ihandle); - if (grub_ieee1275_finddevice (op->devpath, &dev)) { grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't read device properties"); @@ -201,6 +191,16 @@ grub_ofdisk_open (const char *name, grub_disk_t disk) goto fail; } + grub_ieee1275_open (op->devpath, &dev_ihandle); + if (! dev_ihandle) + { + grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't open device"); + goto fail; + } + + grub_dprintf ("disk", "Opened `%s' as handle %p.\n", op->devpath, + (void *) (unsigned long) dev_ihandle); + /* XXX: There is no property to read the number of blocks. There should be a property `#blocks', but it is not there. Perhaps it is possible to use seek for this. */ From 904935c3effb50738589b6d52d7219e6534a8a0f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 13 Feb 2010 16:48:22 +0100 Subject: [PATCH 409/738] 2010-02-13 Vladimir Serbinenko Merge grub_ieee1275_map_physical into grub_map and rename to grub_ieee1275_map * include/grub/ieee1275/ieee1275.h (grub_ieee1275_map): New proto. * include/grub/sparc64/ieee1275/ieee1275.h (grub_ieee1275_map_physical): Remove. * kern/ieee1275/openfw.c (grub_map): Rename to ... (grub_ieee1275_map): ... this. All users updated. Add phys_lo when necessary. * kern/sparc64/ieee1275/ieee1275.c (grub_ieee1275_map_physical): Remove. --- ChangeLog | 13 ++++++++++ include/grub/ieee1275/ieee1275.h | 4 +++ include/grub/sparc64/ieee1275/ieee1275.h | 4 --- kern/ieee1275/openfw.c | 27 ++++++++++++++----- kern/sparc64/ieee1275/ieee1275.c | 33 ------------------------ loader/sparc64/ieee1275/linux.c | 6 ++--- 6 files changed, 40 insertions(+), 47 deletions(-) diff --git a/ChangeLog b/ChangeLog index eb937f97e..bd8165647 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2010-02-13 Vladimir Serbinenko + + Merge grub_ieee1275_map_physical into grub_map and rename to + grub_ieee1275_map + + * include/grub/ieee1275/ieee1275.h (grub_ieee1275_map): New proto. + * include/grub/sparc64/ieee1275/ieee1275.h (grub_ieee1275_map_physical): + Remove. + * kern/ieee1275/openfw.c (grub_map): Rename to ... + (grub_ieee1275_map): ... this. All users updated. Add phys_lo when + necessary. + * kern/sparc64/ieee1275/ieee1275.c (grub_ieee1275_map_physical): Remove. + 2010-02-13 Vladimir Serbinenko * disk/ieee1275/ofdisk.c (grub_ofdisk_open): Check device type before diff --git a/include/grub/ieee1275/ieee1275.h b/include/grub/ieee1275/ieee1275.h index a852a7b61..62e8f3812 100644 --- a/include/grub/ieee1275/ieee1275.h +++ b/include/grub/ieee1275/ieee1275.h @@ -173,6 +173,10 @@ grub_err_t EXPORT_FUNC(grub_machine_mmap_iterate) (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t)); int EXPORT_FUNC(grub_claimmap) (grub_addr_t addr, grub_size_t size); +int +EXPORT_FUNC(grub_ieee1275_map) (grub_addr_t phys, grub_addr_t virt, + grub_size_t size, grub_uint32_t mode); + char *EXPORT_FUNC(grub_ieee1275_encode_devname) (const char *path); char *EXPORT_FUNC(grub_ieee1275_get_filename) (const char *path); diff --git a/include/grub/sparc64/ieee1275/ieee1275.h b/include/grub/sparc64/ieee1275/ieee1275.h index 1619510fb..527c46ae7 100644 --- a/include/grub/sparc64/ieee1275/ieee1275.h +++ b/include/grub/sparc64/ieee1275/ieee1275.h @@ -37,10 +37,6 @@ typedef grub_uint64_t grub_ieee1275_cell_t; #define IEEE1275_MAP_DEFAULT (IEEE1275_MAP_WRITE | IEEE1275_MAP_READ | \ IEEE1275_MAP_EXEC | IEEE1275_MAP_CACHED) -extern int EXPORT_FUNC(grub_ieee1275_map_physical) (grub_addr_t paddr, - grub_addr_t vaddr, - grub_size_t size, - grub_uint32_t mode); extern int EXPORT_FUNC(grub_ieee1275_claim_vaddr) (grub_addr_t vaddr, grub_size_t size); extern int EXPORT_FUNC(grub_ieee1275_alloc_physmem) (grub_addr_t *paddr, diff --git a/kern/ieee1275/openfw.c b/kern/ieee1275/openfw.c index e5f565c4c..13fccbf9a 100644 --- a/kern/ieee1275/openfw.c +++ b/kern/ieee1275/openfw.c @@ -199,9 +199,9 @@ nextprop: } /* Call the "map" method of /chosen/mmu. */ -static int -grub_map (grub_addr_t phys, grub_addr_t virt, grub_uint32_t size, - grub_uint8_t mode) +int +grub_ieee1275_map (grub_addr_t phys, grub_addr_t virt, grub_size_t size, + grub_uint32_t mode) { struct map_args { struct grub_ieee1275_common_hdr common; @@ -210,17 +210,30 @@ grub_map (grub_addr_t phys, grub_addr_t virt, grub_uint32_t size, grub_ieee1275_cell_t mode; grub_ieee1275_cell_t size; grub_ieee1275_cell_t virt; - grub_ieee1275_cell_t phys; +#ifdef GRUB_MACHINE_SPARC64 + grub_ieee1275_cell_t phys_high; +#endif + grub_ieee1275_cell_t phys_low; grub_ieee1275_cell_t catch_result; } args; - INIT_IEEE1275_COMMON (&args.common, "call-method", 6, 1); + INIT_IEEE1275_COMMON (&args.common, "call-method", +#ifdef GRUB_MACHINE_SPARC64 + 7, +#else + 6, +#endif + 1); args.method = (grub_ieee1275_cell_t) "map"; args.ihandle = grub_ieee1275_mmu; - args.phys = phys; +#ifdef GRUB_MACHINE_SPARC64 + args.phys_high = 0; +#endif + args.phys_low = phys; args.virt = virt; args.size = size; args.mode = mode; /* Format is WIMG0PP. */ + args.catch_result = (grub_ieee1275_cell_t) -1; if (IEEE1275_CALL_ENTRY_FN (&args) == -1) return -1; @@ -235,7 +248,7 @@ grub_claimmap (grub_addr_t addr, grub_size_t size) return -1; if (! grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_REAL_MODE) - && grub_map (addr, addr, size, 0x00)) + && grub_ieee1275_map (addr, addr, size, 0x00)) { grub_printf ("map failed: address 0x%llx, size 0x%llx\n", (long long) addr, (long long) size); diff --git a/kern/sparc64/ieee1275/ieee1275.c b/kern/sparc64/ieee1275/ieee1275.c index 438a171ca..53be692c3 100644 --- a/kern/sparc64/ieee1275/ieee1275.c +++ b/kern/sparc64/ieee1275/ieee1275.c @@ -21,39 +21,6 @@ /* Sun specific ieee1275 interfaces used by GRUB. */ -int -grub_ieee1275_map_physical (grub_addr_t paddr, grub_addr_t vaddr, - grub_size_t size, grub_uint32_t mode) -{ - struct map_physical_args - { - struct grub_ieee1275_common_hdr common; - grub_ieee1275_cell_t method; - grub_ieee1275_cell_t ihandle; - grub_ieee1275_cell_t mode; - grub_ieee1275_cell_t size; - grub_ieee1275_cell_t virt; - grub_ieee1275_cell_t phys_high; - grub_ieee1275_cell_t phys_low; - grub_ieee1275_cell_t catch_result; - } - args; - - INIT_IEEE1275_COMMON (&args.common, "call-method", 7, 1); - args.method = (grub_ieee1275_cell_t) "map"; - args.ihandle = grub_ieee1275_mmu; - args.mode = mode; - args.size = size; - args.virt = vaddr; - args.phys_high = 0; - args.phys_low = paddr; - args.catch_result = (grub_ieee1275_cell_t) -1; - - if (IEEE1275_CALL_ENTRY_FN (&args) == -1) - return -1; - return args.catch_result; -} - int grub_ieee1275_claim_vaddr (grub_addr_t vaddr, grub_size_t size) { diff --git a/loader/sparc64/ieee1275/linux.c b/loader/sparc64/ieee1275/linux.c index 65f334ab3..24a6849a6 100644 --- a/loader/sparc64/ieee1275/linux.c +++ b/loader/sparc64/ieee1275/linux.c @@ -252,8 +252,8 @@ grub_linux_load64 (grub_elf_t elf) if (paddr == (grub_addr_t) -1) return grub_error (GRUB_ERR_OUT_OF_MEMORY, "couldn't allocate physical memory"); - ret = grub_ieee1275_map_physical (paddr, linux_addr - off, - linux_size + off, IEEE1275_MAP_DEFAULT); + ret = grub_ieee1275_map (paddr, linux_addr - off, + linux_size + off, IEEE1275_MAP_DEFAULT); if (ret) return grub_error (GRUB_ERR_OUT_OF_MEMORY, "couldn't map physical memory"); @@ -403,7 +403,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), "couldn't allocate physical memory"); goto fail; } - ret = grub_ieee1275_map_physical (paddr, addr, size, IEEE1275_MAP_DEFAULT); + ret = grub_ieee1275_map (paddr, addr, size, IEEE1275_MAP_DEFAULT); if (ret) { grub_error (GRUB_ERR_OUT_OF_MEMORY, From 10f6389453e746a5235e5db6c70b4b55dc0355a6 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 13 Feb 2010 18:48:33 +0100 Subject: [PATCH 410/738] Fix raw image addresses --- boot/sparc64/ieee1275/boot.S | 2 +- boot/sparc64/ieee1275/diskboot.S | 2 +- include/grub/sparc64/ieee1275/boot.h | 5 +++-- util/grub-mkrawimage.c | 3 ++- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/boot/sparc64/ieee1275/boot.S b/boot/sparc64/ieee1275/boot.S index 74f4ee014..167406017 100644 --- a/boot/sparc64/ieee1275/boot.S +++ b/boot/sparc64/ieee1275/boot.S @@ -118,7 +118,7 @@ prom_call: boot_continue: mov %o7, PIC_REG /* PIC base */ - sethi %hi(SCRATCH_PAD), %l1 /* OF argument slots */ + sethi %hi(SCRATCH_PAD_BOOT), %l1 /* OF argument slots */ /* Find the /chosen node so we can fetch the stdout handle, * and thus perform console output. diff --git a/boot/sparc64/ieee1275/diskboot.S b/boot/sparc64/ieee1275/diskboot.S index 5016bf9e0..a4d4b5bf9 100644 --- a/boot/sparc64/ieee1275/diskboot.S +++ b/boot/sparc64/ieee1275/diskboot.S @@ -81,7 +81,7 @@ prom_call: after_info_block: - sethi %hi(SCRATCH_PAD), %l1 /* OF argument slots */ + sethi %hi(SCRATCH_PAD_DISKBOOT), %l1 /* OF argument slots */ GET_ABS(notification_string, %o2) call console_write diff --git a/include/grub/sparc64/ieee1275/boot.h b/include/grub/sparc64/ieee1275/boot.h index 95f311ce5..e1c1aa675 100644 --- a/include/grub/sparc64/ieee1275/boot.h +++ b/include/grub/sparc64/ieee1275/boot.h @@ -25,7 +25,8 @@ #define BOOTDEV_REG %l6 #define PIC_REG %l7 -#define SCRATCH_PAD 0x10000 +#define SCRATCH_PAD_BOOT 0x5000 +#define SCRATCH_PAD_DISKBOOT 0x4000 #define GET_ABS(symbol, reg) \ add PIC_REG, (symbol - pic_base), reg @@ -51,7 +52,7 @@ #define GRUB_BOOT_MACHINE_LIST_SIZE 12 -#define GRUB_BOOT_MACHINE_IMAGE_ADDRESS 0x200000 +#define GRUB_BOOT_MACHINE_IMAGE_ADDRESS 0x4400 #define GRUB_BOOT_MACHINE_KERNEL_ADDR 0x4200 diff --git a/util/grub-mkrawimage.c b/util/grub-mkrawimage.c index d0be7149c..933c46963 100644 --- a/util/grub-mkrawimage.c +++ b/util/grub-mkrawimage.c @@ -344,7 +344,8 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], aout_head->a_midmag = grub_host_to_target32 ((AOUT_MID_SUN << 16) | AOUT32_OMAGIC); aout_head->a_text = grub_host_to_target32 (core_size); - aout_head->a_entry = grub_host_to_target32 (0x4400); + aout_head->a_entry + = grub_host_to_target32 (GRUB_BOOT_MACHINE_IMAGE_ADDRESS); memcpy (aout_img + sizeof (*aout_head), core_img, core_size); free (core_img); From 8c717950104035bb2d9f70bb8f31cdcaee4fb8bb Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 14 Feb 2010 02:10:46 +0100 Subject: [PATCH 411/738] 2010-02-13 Vladimir Serbinenko * io/gzio.c (grub_gzio_open): Use grub_zalloc. --- ChangeLog | 4 ++++ io/gzio.c | 3 +-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index bd8165647..2084735e0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-02-13 Vladimir Serbinenko + + * io/gzio.c (grub_gzio_open): Use grub_zalloc. + 2010-02-13 Vladimir Serbinenko Merge grub_ieee1275_map_physical into grub_map and rename to diff --git a/io/gzio.c b/io/gzio.c index 39f6d7b13..9bf609105 100644 --- a/io/gzio.c +++ b/io/gzio.c @@ -1121,14 +1121,13 @@ grub_gzio_open (grub_file_t io, int transparent) if (! file) return 0; - gzio = grub_malloc (sizeof (*gzio)); + gzio = grub_zalloc (sizeof (*gzio)); if (! gzio) { grub_free (file); return 0; } - grub_memset (gzio, 0, sizeof (*gzio)); gzio->file = io; file->device = io->device; From 095f5f82f7c68f8bfabf1b35c1204626fa4dddf6 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 14 Feb 2010 13:18:33 +0100 Subject: [PATCH 412/738] 2010-02-14 Vladimir Serbinenko * fs/i386/pc/pxe.c (GRUB_MOD_INIT): Fix typo. Reported by: Pavel Pisa. --- ChangeLog | 5 +++++ fs/i386/pc/pxe.c | 8 ++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2084735e0..1dfaca669 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-02-14 Vladimir Serbinenko + + * fs/i386/pc/pxe.c (GRUB_MOD_INIT): Fix typo. + Reported by: Pavel Pisa. + 2010-02-13 Vladimir Serbinenko * io/gzio.c (grub_gzio_open): Use grub_zalloc. diff --git a/fs/i386/pc/pxe.c b/fs/i386/pc/pxe.c index 92529883e..82d8ee583 100644 --- a/fs/i386/pc/pxe.c +++ b/fs/i386/pc/pxe.c @@ -568,21 +568,21 @@ GRUB_MOD_INIT(pxe) buf = grub_xasprintf ("%d", grub_pxe_blksize); if (buf) - grub_env_set ("net_pxe_blksize", buf); + grub_env_set ("pxe_blksize", buf); grub_free (buf); set_ip_env ("pxe_default_server", grub_pxe_default_server_ip); set_ip_env ("pxe_default_gateway", grub_pxe_default_gateway_ip); set_ip_env ("net_pxe_ip", grub_pxe_your_ip); - grub_register_variable_hook ("net_pxe_default_server", 0, + grub_register_variable_hook ("pxe_default_server", 0, grub_env_write_pxe_default_server); - grub_register_variable_hook ("net_pxe_default_gateway", 0, + grub_register_variable_hook ("pxe_default_gateway", 0, grub_env_write_pxe_default_gateway); /* XXX: Is it possible to change IP in PXE? */ grub_register_variable_hook ("net_pxe_ip", 0, grub_env_write_readonly); - grub_register_variable_hook ("net_pxe_blksize", 0, + grub_register_variable_hook ("pxe_blksize", 0, grub_env_write_pxe_blocksize); grub_disk_dev_register (&grub_pxe_dev); grub_fs_register (&grub_pxefs_fs); From 320dd174b5efd6dd7fde6636180f0547aaaae889 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 14 Feb 2010 14:32:21 +0100 Subject: [PATCH 413/738] Increase stack size on sparc --- include/grub/sparc64/ieee1275/ieee1275.h | 2 ++ include/grub/sparc64/ieee1275/kernel.h | 1 + kern/sparc64/ieee1275/crt0.S | 16 +++++++++++++--- kern/sparc64/ieee1275/init.c | 6 +++++- loader/sparc64/ieee1275/linux.c | 17 +++++++++++------ 5 files changed, 32 insertions(+), 10 deletions(-) diff --git a/include/grub/sparc64/ieee1275/ieee1275.h b/include/grub/sparc64/ieee1275/ieee1275.h index 527c46ae7..32c77f80f 100644 --- a/include/grub/sparc64/ieee1275/ieee1275.h +++ b/include/grub/sparc64/ieee1275/ieee1275.h @@ -43,4 +43,6 @@ extern int EXPORT_FUNC(grub_ieee1275_alloc_physmem) (grub_addr_t *paddr, grub_size_t size, grub_uint32_t align); +extern grub_addr_t EXPORT_VAR (grub_ieee1275_original_stack); + #endif /* ! GRUB_IEEE1275_MACHINE_HEADER */ diff --git a/include/grub/sparc64/ieee1275/kernel.h b/include/grub/sparc64/ieee1275/kernel.h index 78e039bc5..a16fb88e7 100644 --- a/include/grub/sparc64/ieee1275/kernel.h +++ b/include/grub/sparc64/ieee1275/kernel.h @@ -40,6 +40,7 @@ #define GRUB_KERNEL_MACHINE_DATA_END 0x114 #define GRUB_KERNEL_MACHINE_RAW_SIZE 0 +#define GRUB_KERNEL_MACHINE_STACK_SIZE 0x40000 #define GRUB_PLATFORM_IMAGE_FORMATS "raw, aout" #define GRUB_PLATFORM_IMAGE_DEFAULT_FORMAT "raw" diff --git a/kern/sparc64/ieee1275/crt0.S b/kern/sparc64/ieee1275/crt0.S index f1ff6b466..d5a172296 100644 --- a/kern/sparc64/ieee1275/crt0.S +++ b/kern/sparc64/ieee1275/crt0.S @@ -53,8 +53,17 @@ codestart: or %o3, %lo(_end), %o3 sethi %hi(grub_total_module_size), %o4 lduw [%o4 + %lo(grub_total_module_size)], %o4 + add %o2, %o4, %o2 add %o3, %o4, %o3 + + /* Save ieee1275 stack for future use by booter. */ + mov %o6, %o1 + /* Our future stack. */ + sethi %hi(GRUB_KERNEL_MACHINE_STACK_SIZE - 2047), %o5 + or %o5, %lo(GRUB_KERNEL_MACHINE_STACK_SIZE - 2047), %o5 + add %o3, %o5, %o6 + sub %o2, 4, %o2 sub %o3, 4, %o3 1: lduw [%o2], %o5 @@ -62,7 +71,7 @@ codestart: subcc %o4, 4, %o4 sub %o2, 4, %o2 bne,pt %icc, 1b - sub %o3, 4, %o3 + sub %o3, 4, %o3 /* Now it's safe to clear out the BSS. */ sethi %hi(__bss_start), %o2 @@ -74,8 +83,9 @@ codestart: cmp %o2, %o3 blt,pt %xcc, 1b nop + sethi %hi(grub_ieee1275_original_stack), %o2 + stx %o1, [%o2 + %lo(grub_ieee1275_original_stack)] sethi %hi(grub_ieee1275_entry_fn), %o2 - stx %o0, [%o2 + %lo(grub_ieee1275_entry_fn)] call grub_main - nop + stx %o0, [%o2 + %lo(grub_ieee1275_entry_fn)] 1: ba,a 1b diff --git a/kern/sparc64/ieee1275/init.c b/kern/sparc64/ieee1275/init.c index 5827be658..a995217bc 100644 --- a/kern/sparc64/ieee1275/init.c +++ b/kern/sparc64/ieee1275/init.c @@ -23,12 +23,15 @@ #include #include #include +#include #include #include #include #include #include +grub_addr_t grub_ieee1275_original_stack; + void grub_exit (void) { @@ -104,7 +107,8 @@ grub_machine_set_prefix (void) static void grub_heap_init (void) { - grub_mm_init_region ((void *) grub_modules_get_end (), 0x200000); + grub_mm_init_region ((void *) (grub_modules_get_end () + + GRUB_KERNEL_MACHINE_STACK_SIZE), 0x200000); } static void diff --git a/loader/sparc64/ieee1275/linux.c b/loader/sparc64/ieee1275/linux.c index 24a6849a6..f55b4fa2a 100644 --- a/loader/sparc64/ieee1275/linux.c +++ b/loader/sparc64/ieee1275/linux.c @@ -58,9 +58,6 @@ static grub_size_t linux_size; static char *linux_args; -typedef void (*kernel_entry_t) (unsigned long, unsigned long, - unsigned long, unsigned long, int (void *)); - struct linux_bootstr_info { int len, valid; char buf[]; @@ -92,7 +89,6 @@ static grub_err_t grub_linux_boot (void) { struct linux_bootstr_info *bp; - kernel_entry_t linuxmain; struct linux_hdrs *hp; grub_addr_t addr; @@ -141,8 +137,17 @@ grub_linux_boot (void) grub_dprintf ("loader", "Jumping to Linux...\n"); /* Boot the kernel. */ - linuxmain = (kernel_entry_t) linux_addr; - linuxmain (0, 0, 0, 0, grub_ieee1275_entry_fn); + asm volatile ("sethi %hi(grub_ieee1275_entry_fn), %o1\n" + "ldx [%o1 + %lo(grub_ieee1275_entry_fn)], %o4\n" + "sethi %hi(grub_ieee1275_original_stack), %o1\n" + "ldx [%o1 + %lo(grub_ieee1275_original_stack)], %o6\n" + "sethi %hi(linux_addr), %o1\n" + "ldx [%o1 + %lo(linux_addr)], %o5\n" + "mov %g0, %o0\n" + "mov %g0, %o2\n" + "mov %g0, %o3\n" + "jmp %o5\n" + "mov %g0, %o1\n"); return GRUB_ERR_NONE; } From bc028f2f86ad3fa97afc0262fe414190717a988f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 14 Feb 2010 14:46:19 +0100 Subject: [PATCH 414/738] 2010-02-14 Vladimir Serbinenko Prevent unknown commands from stopping menuentry execution. * script/execute.c (grub_script_execute_cmdline): Print error after unknown command. --- ChangeLog | 7 +++++++ script/execute.c | 5 +++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1dfaca669..7c8e0a988 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-02-14 Vladimir Serbinenko + + Prevent unknown commands from stopping menuentry execution. + + * script/execute.c (grub_script_execute_cmdline): Print error after + unknown command. + 2010-02-14 Vladimir Serbinenko * fs/i386/pc/pxe.c (GRUB_MOD_INIT): Fix typo. diff --git a/script/execute.c b/script/execute.c index a0773c191..6e914aeeb 100644 --- a/script/execute.c +++ b/script/execute.c @@ -100,8 +100,7 @@ grub_script_execute_cmdline (struct grub_script_cmd *cmd) grubcmd = grub_command_find (cmdname); if (! grubcmd) { - /* Shouldn't happen but precaution is good. */ - grub_print_error (); + grub_errno = GRUB_ERR_NONE; /* It's not a GRUB command, try all functions. */ func = grub_script_function_find (cmdname); @@ -126,6 +125,8 @@ grub_script_execute_cmdline (struct grub_script_cmd *cmd) grub_snprintf (errnobuf, sizeof (errnobuf), "%d", grub_errno); grub_env_set ("?", errnobuf); + grub_print_error (); + return 0; } } From d27859b2eccc98d3c5e0ce50d4dfd58b253e6df0 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 14 Feb 2010 14:47:50 +0100 Subject: [PATCH 415/738] 2010-02-14 Vladimir Serbinenko * util/grub-mkconfig_lib.in (prepare_grub_to_access_device): Enclose set root in single quotes to prevent \, from being unescaped. --- ChangeLog | 5 +++++ util/grub-mkconfig_lib.in | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 7c8e0a988..403394560 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-02-14 Vladimir Serbinenko + + * util/grub-mkconfig_lib.in (prepare_grub_to_access_device): Enclose + set root in single quotes to prevent \, from being unescaped. + 2010-02-14 Vladimir Serbinenko Prevent unknown commands from stopping menuentry execution. diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in index fc24c7b70..45354041a 100644 --- a/util/grub-mkconfig_lib.in +++ b/util/grub-mkconfig_lib.in @@ -120,7 +120,7 @@ prepare_grub_to_access_device () # If there's a filesystem UUID that GRUB is capable of identifying, use it; # otherwise set root as per value in device.map. - echo "set root=`${grub_probe} --device ${device} --target=drive`" + echo "set root='`${grub_probe} --device ${device} --target=drive`'" if fs_uuid="`${grub_probe} --device ${device} --target=fs_uuid 2> /dev/null`" ; then echo "search --no-floppy --fs-uuid --set ${fs_uuid}" fi From e29f95dc538733358ed22678a75198c3281bc696 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 14 Feb 2010 14:51:06 +0100 Subject: [PATCH 416/738] 2010-02-14 Vladimir Serbinenko * term/ieee1275/ofconsole.c (grub_ofconsole_putchar): Don't output non-ASCII characters. --- ChangeLog | 5 +++++ term/ieee1275/ofconsole.c | 47 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 403394560..a75dd8636 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-02-14 Vladimir Serbinenko + + * term/ieee1275/ofconsole.c (grub_ofconsole_putchar): Don't output + non-ASCII characters. + 2010-02-14 Vladimir Serbinenko * util/grub-mkconfig_lib.in (prepare_grub_to_access_device): Enclose diff --git a/term/ieee1275/ofconsole.c b/term/ieee1275/ofconsole.c index 6073e25d2..86b150a33 100644 --- a/term/ieee1275/ofconsole.c +++ b/term/ieee1275/ofconsole.c @@ -77,7 +77,52 @@ grub_ofconsole_writeesc (const char *str) static void grub_ofconsole_putchar (grub_uint32_t c) { - char chr = c; + char chr; + + if (c > 0x7F) + { + /* Better than nothing. */ + switch (c) + { + case GRUB_TERM_DISP_LEFT: + c = '<'; + break; + + case GRUB_TERM_DISP_UP: + c = '^'; + break; + + case GRUB_TERM_DISP_RIGHT: + c = '>'; + break; + + case GRUB_TERM_DISP_DOWN: + c = 'v'; + break; + + case GRUB_TERM_DISP_HLINE: + c = '-'; + break; + + case GRUB_TERM_DISP_VLINE: + c = '|'; + break; + + case GRUB_TERM_DISP_UL: + case GRUB_TERM_DISP_UR: + case GRUB_TERM_DISP_LL: + case GRUB_TERM_DISP_LR: + c = '+'; + break; + + default: + c = '?'; + break; + } + } + + chr = c; + if (c == '\n') { grub_curr_y++; From a08769434f565d7ef0ad1cffb5050e4894ff115e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 14 Feb 2010 14:52:10 +0100 Subject: [PATCH 417/738] 2010-02-14 Vladimir Serbinenko * term/ieee1275/ofconsole.c (grub_ofconsole_readkey): Wait for possible escape sequence after \e. --- ChangeLog | 5 +++++ term/ieee1275/ofconsole.c | 12 ++++++++++++ 2 files changed, 17 insertions(+) diff --git a/ChangeLog b/ChangeLog index a75dd8636..8d654ce88 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-02-14 Vladimir Serbinenko + + * term/ieee1275/ofconsole.c (grub_ofconsole_readkey): Wait for possible + escape sequence after \e. + 2010-02-14 Vladimir Serbinenko * term/ieee1275/ofconsole.c (grub_ofconsole_putchar): Don't output diff --git a/term/ieee1275/ofconsole.c b/term/ieee1275/ofconsole.c index 86b150a33..82108022a 100644 --- a/term/ieee1275/ofconsole.c +++ b/term/ieee1275/ofconsole.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -203,7 +204,14 @@ grub_ofconsole_readkey (int *key) if (actual > 0 && c == '\e') { + grub_uint64_t start; grub_ieee1275_read (stdin_ihandle, &c, 1, &actual); + + /* On 9600 we have to wait up to 12 milliseconds. */ + start = grub_get_time_ms (); + while (actual <= 0 && grub_get_time_ms () - start < 12) + grub_ieee1275_read (stdin_ihandle, &c, 1, &actual); + if (actual <= 0) { *key = '\e'; @@ -214,6 +222,10 @@ grub_ofconsole_readkey (int *key) return 0; grub_ieee1275_read (stdin_ihandle, &c, 1, &actual); + /* On 9600 we have to wait up to 12 milliseconds. */ + start = grub_get_time_ms (); + while (actual <= 0 && grub_get_time_ms () - start < 12) + grub_ieee1275_read (stdin_ihandle, &c, 1, &actual); if (actual <= 0) return 0; From 04459e70a353d59a83b10e0135e6e0b27e104b48 Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Sun, 14 Feb 2010 17:07:34 +0100 Subject: [PATCH 418/738] 2010-02-07 Samuel Thibault * commands/i386/pc/play.c (BASE_TEMPO): Set to 60 * GRUB_TICKS_PER_SECOND instead of 120. --- ChangeLog | 5 +++++ commands/i386/pc/play.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 8d654ce88..03388c7f3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-02-07 Samuel Thibault + + * commands/i386/pc/play.c (BASE_TEMPO): Set to 60 * + GRUB_TICKS_PER_SECOND instead of 120. + 2010-02-14 Vladimir Serbinenko * term/ieee1275/ofconsole.c (grub_ofconsole_readkey): Wait for possible diff --git a/commands/i386/pc/play.c b/commands/i386/pc/play.c index 1151dddf4..04bf8625d 100644 --- a/commands/i386/pc/play.c +++ b/commands/i386/pc/play.c @@ -29,7 +29,7 @@ #include #include -#define BASE_TEMPO 120 +#define BASE_TEMPO (60 * GRUB_TICKS_PER_SECOND) /* The speaker port. */ #define SPEAKER 0x61 From 14da0fb7e81cc5f46903201563f8d3302d25a88c Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Sun, 14 Feb 2010 17:25:52 +0100 Subject: [PATCH 419/738] 2010-02-14 Samuel Thibault * commands/i386/pc/play.c (T_REST, T_FINE, struct note, beep_on): Use grub_uint16_t instead of short. (grub_cmd_play): Use grub_uint32_t instead of int, convert data from disk from little endian to cpu endianness. --- ChangeLog | 7 +++++++ commands/i386/pc/play.c | 22 ++++++++++++++-------- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index 03388c7f3..950a26f3d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-02-14 Samuel Thibault + + * commands/i386/pc/play.c (T_REST, T_FINE, struct note, beep_on): Use + grub_uint16_t instead of short. + (grub_cmd_play): Use grub_uint32_t instead of int, convert data from + disk from little endian to cpu endianness. + 2010-02-07 Samuel Thibault * commands/i386/pc/play.c (BASE_TEMPO): Set to 60 * diff --git a/commands/i386/pc/play.c b/commands/i386/pc/play.c index 04bf8625d..84819b551 100644 --- a/commands/i386/pc/play.c +++ b/commands/i386/pc/play.c @@ -101,13 +101,13 @@ #define PIT_CTRL_COUNT_BINARY 0x00 /* 16-bit binary counter. */ #define PIT_CTRL_COUNT_BCD 0x01 /* 4-decade BCD counter. */ -#define T_REST ((short) 0) -#define T_FINE ((short) -1) +#define T_REST ((grub_uint16_t) 0) +#define T_FINE ((grub_uint16_t) -1) struct note { - short pitch; - short duration; + grub_uint16_t pitch; + grub_uint16_t duration; }; static void @@ -120,7 +120,7 @@ beep_off (void) } static void -beep_on (short pitch) +beep_on (grub_uint16_t pitch) { unsigned char status; unsigned int counter; @@ -149,7 +149,7 @@ grub_cmd_play (grub_command_t cmd __attribute__ ((unused)), { grub_file_t file; struct note buf; - int tempo; + grub_uint32_t tempo; unsigned int to; if (argc != 1) @@ -166,12 +166,18 @@ grub_cmd_play (grub_command_t cmd __attribute__ ((unused)), "file doesn't even contains a full tempo record"); } + tempo = grub_le_to_cpu32(tempo); + grub_dprintf ("play","tempo = %d\n", tempo); while (grub_file_read (file, &buf, - sizeof (struct note)) == sizeof (struct note) - && buf.pitch != T_FINE && grub_checkkey () < 0) + sizeof (struct note)) == sizeof (struct note)) { + buf.pitch = grub_le_to_cpu16(buf.pitch); + buf.duration = grub_le_to_cpu16(buf.duration); + + if (buf.pitch == T_FINE || grub_checkkey () >= 0) + break; grub_dprintf ("play", "pitch = %d, duration = %d\n", buf.pitch, buf.duration); From 37c8483b9756d3ea161d0f7a123c4bd57e1cddaf Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Sun, 14 Feb 2010 18:14:16 +0100 Subject: [PATCH 420/738] 2010-02-14 Samuel Thibault * commands/i386/pc/play.c (grub_cmd_play): If grub_file_open fails, parse arguments as inline tempo and notes. Move code for playing notes to... (play): ... new function. --- ChangeLog | 7 +++ commands/i386/pc/play.c | 125 +++++++++++++++++++++++++++------------- 2 files changed, 92 insertions(+), 40 deletions(-) diff --git a/ChangeLog b/ChangeLog index 950a26f3d..60a1f5db3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-02-14 Samuel Thibault + + * commands/i386/pc/play.c (grub_cmd_play): If grub_file_open fails, + parse arguments as inline tempo and notes. Move code for playing notes + to... + (play): ... new function. + 2010-02-14 Samuel Thibault * commands/i386/pc/play.c (T_REST, T_FINE, struct note, beep_on): Use diff --git a/commands/i386/pc/play.c b/commands/i386/pc/play.c index 84819b551..1bca3d763 100644 --- a/commands/i386/pc/play.c +++ b/commands/i386/pc/play.c @@ -143,66 +143,111 @@ beep_on (grub_uint16_t pitch) grub_outb (status | SPEAKER_TMR2 | SPEAKER_DATA, SPEAKER); } +/* Returns whether playing should continue. */ +static int +play (unsigned tempo, struct note *note) +{ + unsigned int to; + + if (note->pitch == T_FINE || grub_checkkey () >= 0) + return 1; + + grub_dprintf ("play", "pitch = %d, duration = %d\n", note->pitch, + note->duration); + + switch (note->pitch) + { + case T_REST: + beep_off (); + break; + + default: + beep_on (note->pitch); + break; + } + + to = grub_get_rtc () + BASE_TEMPO * note->duration / tempo; + while (((unsigned int) grub_get_rtc () <= to) && (grub_checkkey () < 0)) + ; + + return 0; +} + static grub_err_t grub_cmd_play (grub_command_t cmd __attribute__ ((unused)), int argc, char **args) { grub_file_t file; - struct note buf; - grub_uint32_t tempo; - unsigned int to; - if (argc != 1) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required"); + if (argc < 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name or tempo and notes required"); file = grub_file_open (args[0]); - if (! file) - return grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found"); - - if (grub_file_read (file, &tempo, sizeof(tempo)) != sizeof(tempo)) + if (file) { - grub_file_close (file); - return grub_error (GRUB_ERR_FILE_READ_ERROR, - "file doesn't even contains a full tempo record"); - } + struct note buf; + grub_uint32_t tempo; - tempo = grub_le_to_cpu32(tempo); - - grub_dprintf ("play","tempo = %d\n", tempo); - - while (grub_file_read (file, &buf, - sizeof (struct note)) == sizeof (struct note)) - { - buf.pitch = grub_le_to_cpu16(buf.pitch); - buf.duration = grub_le_to_cpu16(buf.duration); - - if (buf.pitch == T_FINE || grub_checkkey () >= 0) - break; - - grub_dprintf ("play", "pitch = %d, duration = %d\n", buf.pitch, - buf.duration); - - switch (buf.pitch) + if (grub_file_read (file, &tempo, sizeof (tempo)) != sizeof (tempo)) { - case T_REST: - beep_off (); - break; + grub_file_close (file); + return grub_error (GRUB_ERR_FILE_READ_ERROR, + "file doesn't even contains a full tempo record"); + } - default: - beep_on (buf.pitch); + tempo = grub_le_to_cpu32 (tempo); + grub_dprintf ("play","tempo = %d\n", tempo); + + while (grub_file_read (file, &buf, + sizeof (struct note)) == sizeof (struct note)) + { + buf.pitch = grub_le_to_cpu16 (buf.pitch); + buf.duration = grub_le_to_cpu16 (buf.duration); + + if (play (tempo, &buf)) break; } - to = grub_get_rtc () + BASE_TEMPO * buf.duration / tempo; - while (((unsigned int) grub_get_rtc () <= to) && (grub_checkkey () < 0)) - ; + grub_file_close (file); + } + else + { + char *end; + unsigned tempo; + struct note note; + int i; + tempo = grub_strtoul (args[0], &end, 0); + + if (*end) + /* Was not a number either, assume it was supposed to be a file name. */ + return grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found"); + + grub_dprintf ("play","tempo = %d\n", tempo); + + for (i = 1; i + 1 < argc; i += 2) + { + note.pitch = grub_strtoul (args[i], &end, 0); + if (*end) + { + grub_error (GRUB_ERR_BAD_NUMBER, "bogus pitch number"); + break; + } + + note.duration = grub_strtoul (args[i + 1], &end, 0); + if (*end) + { + grub_error (GRUB_ERR_BAD_NUMBER, "bogus duration number"); + break; + } + + if (play (tempo, ¬e)) + break; + } } beep_off (); - grub_file_close (file); - while (grub_checkkey () > 0) grub_getkey (); From 6fa7cfce657a2862ffd65d581b77443e77bf70b5 Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Sun, 14 Feb 2010 18:36:26 +0100 Subject: [PATCH 421/738] 2010-02-14 Samuel Thibault * commands/i386/pc/play.c (GRUB_MOD_INIT(play)): Fix help. * docs/grub.texi (Command-line and menu entry commands): Document play command. --- ChangeLog | 6 ++++++ commands/i386/pc/play.c | 3 ++- docs/grub.texi | 19 +++++++++++++++++++ 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 60a1f5db3..74f4380f6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-02-14 Samuel Thibault + + * commands/i386/pc/play.c (GRUB_MOD_INIT(play)): Fix help. + * docs/grub.texi (Command-line and menu entry commands): Document play + command. + 2010-02-14 Samuel Thibault * commands/i386/pc/play.c (grub_cmd_play): If grub_file_open fails, diff --git a/commands/i386/pc/play.c b/commands/i386/pc/play.c index 1bca3d763..44d98a1f0 100644 --- a/commands/i386/pc/play.c +++ b/commands/i386/pc/play.c @@ -259,7 +259,8 @@ static grub_command_t cmd; GRUB_MOD_INIT(play) { cmd = grub_register_command ("play", grub_cmd_play, - N_("FILE"), N_("Play a tune.")); + N_("FILE | TEMPO [PITCH1 DURATION1] [PITCH2 DURATION2] ... "), + N_("Play a tune.")); } GRUB_MOD_FINI(play) diff --git a/docs/grub.texi b/docs/grub.texi index 4fa44462e..f8a9bc414 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -1126,6 +1126,7 @@ you forget a command, you can run the command @command{help} * insmod:: Insert a module * keystatus:: Check key modifier status * ls:: List devices or files +* play:: Play a tune * reboot:: Reboot your computer * set:: Set an environment variable * unset:: Unset an environment variable @@ -1364,6 +1365,24 @@ name syntax}), then list the contents of that directory. @end deffn +@node play +@subsection play + +@deffn Command play file | tempo [pitch1 duration1] [pitch2 duration2] ... +Plays a tune + +If the argument is a file name (@pxref{File name syntax}), play the tune +recorded in it. The file format is first the tempo as an unsigned 32bit +little-endian number, then pairs of unsigned 16bit little-endian numbers for +pitch and duration pairs. + +If the arguments are a series of numbers, play the inline tune. + +The tempo is the base for all note durations. 60 gives a 1-second base, 120 +gives a half-second base, etc. Pitches are Hz. +@end deffn + + @node reboot @subsection reboot From a3334e79e8dbba33491e6cdee540f20bc7eebd80 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 14 Feb 2010 20:03:19 +0100 Subject: [PATCH 422/738] Revert gratuituos change of alias.name --- kern/ieee1275/openfw.c | 18 ++---------------- video/ieee1275.c | 4 ++-- 2 files changed, 4 insertions(+), 18 deletions(-) diff --git a/kern/ieee1275/openfw.c b/kern/ieee1275/openfw.c index 92ab2f683..ee8520359 100644 --- a/kern/ieee1275/openfw.c +++ b/kern/ieee1275/openfw.c @@ -68,7 +68,6 @@ grub_children_iterate (char *devpath, { struct grub_ieee1275_devalias alias; grub_ssize_t actual; - char *fullname; if (grub_ieee1275_get_property (child, "device_type", childtype, IEEE1275_MAX_PROP_LEN, &actual)) @@ -82,23 +81,10 @@ grub_children_iterate (char *devpath, IEEE1275_MAX_PROP_LEN, &actual)) continue; - if (devpath[0] == '/' && devpath[1] == 0) - fullname = grub_xasprintf ("/%s", childname); - else - fullname = grub_xasprintf ("%s/%s", devpath, childname); - if (!fullname) - { - grub_free (childname); - grub_free (childpath); - grub_free (childtype); - return 0; - } - alias.type = childtype; alias.path = childpath; - alias.name = fullname; + alias.name = childname; ret = hook (&alias); - grub_free (fullname); if (ret) break; } @@ -119,7 +105,7 @@ grub_ieee1275_devices_iterate (int (*hook) (struct grub_ieee1275_devalias *alias { if (hook (alias)) return 1; - return grub_children_iterate (alias->name, it_through); + return grub_children_iterate (alias->path, it_through); } return grub_children_iterate ("/", it_through); diff --git a/video/ieee1275.c b/video/ieee1275.c index 21b65bd32..3f0b93fb8 100644 --- a/video/ieee1275.c +++ b/video/ieee1275.c @@ -59,8 +59,8 @@ find_display (void) { if (grub_strcmp (alias->type, "display") == 0) { - grub_dprintf ("video", "Found display %s\n", alias->name); - display = grub_strdup (alias->name); + grub_dprintf ("video", "Found display %s\n", alias->path); + display = grub_strdup (alias->path); return 1; } return 0; From 8886d76d245b68d63c11a98038ba2000b83c0919 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 14 Feb 2010 20:04:26 +0100 Subject: [PATCH 423/738] Rename get_time_args to set_time_args --- lib/ieee1275/datetime.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ieee1275/datetime.c b/lib/ieee1275/datetime.c index aaf17b0fa..ef37724ed 100644 --- a/lib/ieee1275/datetime.c +++ b/lib/ieee1275/datetime.c @@ -94,7 +94,7 @@ grub_get_datetime (struct grub_datetime *datetime) grub_err_t grub_set_datetime (struct grub_datetime *datetime) { - struct get_time_args + struct set_time_args { struct grub_ieee1275_common_hdr common; grub_ieee1275_cell_t method; From 07096a4f27bdc9f66e239b2e938a8634b55d00eb Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 14 Feb 2010 20:05:09 +0100 Subject: [PATCH 424/738] Use alias->path --- lib/ieee1275/datetime.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/ieee1275/datetime.c b/lib/ieee1275/datetime.c index ef37724ed..7e6f8d1f1 100644 --- a/lib/ieee1275/datetime.c +++ b/lib/ieee1275/datetime.c @@ -31,8 +31,8 @@ find_rtc (void) { if (grub_strcmp (alias->type, "rtc") == 0) { - grub_dprintf ("datetime", "Found RTC %s\n", alias->name); - rtc = grub_strdup (alias->name); + grub_dprintf ("datetime", "Found RTC %s\n", alias->path); + rtc = grub_strdup (alias->path); return 1; } return 0; From 0dd1e0dd38107f60c8281ea9b9eb912bbf575aff Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 15 Feb 2010 18:59:40 +0100 Subject: [PATCH 425/738] 2010-02-15 Vladimir Serbinenko * gensymlist.sh.in: Use TARGET_CC instead of CC. --- ChangeLog | 4 ++++ gensymlist.sh.in | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 74f4380f6..a080c450c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-02-15 Vladimir Serbinenko + + * gensymlist.sh.in: Use TARGET_CC instead of CC. + 2010-02-14 Samuel Thibault * commands/i386/pc/play.c (GRUB_MOD_INIT(play)): Fix help. diff --git a/gensymlist.sh.in b/gensymlist.sh.in index 27fc5e61a..7cd3b48e3 100644 --- a/gensymlist.sh.in +++ b/gensymlist.sh.in @@ -14,7 +14,7 @@ ### The configure script will replace these variables. : ${srcdir=@srcdir@} -: ${CC=@CC@} +: ${CC=@TARGET_CC@} cat < Date: Mon, 15 Feb 2010 19:01:38 +0100 Subject: [PATCH 426/738] 2010-02-15 Vladimir Serbinenko * term/serial.c (serial_get_divisor) [GRUB_MACHINE_MIPS_YEELOONG]: Double divisor. (serial_hw_init) [GRUB_MACHINE_MIPS_YEELOONG]: Don't enable advanced features. (GRUB_MOD_INIT) [GRUB_MACHINE_MIPS_YEELOONG]: Default to 115200. --- ChangeLog | 8 ++++++++ term/serial.c | 12 ++++++++++++ 2 files changed, 20 insertions(+) diff --git a/ChangeLog b/ChangeLog index a080c450c..c2948b20b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2010-02-15 Vladimir Serbinenko + + * term/serial.c (serial_get_divisor) [GRUB_MACHINE_MIPS_YEELOONG]: + Double divisor. + (serial_hw_init) [GRUB_MACHINE_MIPS_YEELOONG]: Don't enable advanced + features. + (GRUB_MOD_INIT) [GRUB_MACHINE_MIPS_YEELOONG]: Default to 115200. + 2010-02-15 Vladimir Serbinenko * gensymlist.sh.in: Use TARGET_CC instead of CC. diff --git a/term/serial.c b/term/serial.c index 62cd11fee..05497ce40 100644 --- a/term/serial.c +++ b/term/serial.c @@ -232,7 +232,12 @@ serial_get_divisor (unsigned int speed) /* Set the baud rate. */ for (i = 0; i < sizeof (divisor_tab) / sizeof (divisor_tab[0]); i++) if (divisor_tab[i].speed == speed) + /* UART in Yeeloong runs twice the usual rate. */ +#ifdef GRUB_MACHINE_MIPS_YEELOONG + return 2 * divisor_tab[i].div; +#else return divisor_tab[i].div; +#endif return 0; } @@ -292,11 +297,14 @@ serial_hw_init (void) | serial_settings.stop_bits); grub_outb (status, serial_settings.port + UART_LCR); + /* In Yeeloong serial port has only 3 wires. */ +#ifndef GRUB_MACHINE_MIPS_YEELOONG /* Enable the FIFO. */ grub_outb (UART_ENABLE_FIFO, serial_settings.port + UART_FCR); /* Turn on DTR, RTS, and OUT2. */ grub_outb (UART_ENABLE_MODEM, serial_settings.port + UART_MCR); +#endif /* Drain the input buffer. */ while (grub_serial_checkkey () != -1) @@ -613,7 +621,11 @@ GRUB_MOD_INIT(serial) /* Set default settings. */ serial_settings.port = serial_hw_get_port (0); +#ifdef GRUB_MACHINE_MIPS_YEELOONG + serial_settings.divisor = serial_get_divisor (115200); +#else serial_settings.divisor = serial_get_divisor (9600); +#endif serial_settings.word_len = UART_8BITS_WORD; serial_settings.parity = UART_NO_PARITY; serial_settings.stop_bits = UART_1_STOP_BIT; From 13b6d963eaf38d6029b5c3a2f696a573a55a97b3 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 15 Feb 2010 19:03:07 +0100 Subject: [PATCH 427/738] Fix yeeloong compilation --- kern/mips/yeeloong/init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kern/mips/yeeloong/init.c b/kern/mips/yeeloong/init.c index d148d08dc..1a29a9af6 100644 --- a/kern/mips/yeeloong/init.c +++ b/kern/mips/yeeloong/init.c @@ -68,7 +68,7 @@ grub_machine_init (void) { grub_addr_t modend; modend = grub_modules_get_end (); - grub_mm_init_region (modend, (grub_arch_memsize << 20) + grub_mm_init_region ((void *) modend, (grub_arch_memsize << 20) - (modend - GRUB_ARCH_LOWMEMVSTART)); /* FIXME: use upper memory as well. */ grub_install_get_time_ms (grub_rtc_get_time_ms); From 2793c71ea948b5849723f578984950e546a805ca Mon Sep 17 00:00:00 2001 From: Georgy Buranov Date: Tue, 16 Feb 2010 13:13:02 +0100 Subject: [PATCH 428/738] 2010-02-16 Georgy Buranov * disk/efi/efidisk.c (grub_efidisk_get_device_name): Fix a typo. --- ChangeLog | 4 ++++ disk/efi/efidisk.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index c2948b20b..d6925f0dd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-02-16 Georgy Buranov + + * disk/efi/efidisk.c (grub_efidisk_get_device_name): Fix a typo. + 2010-02-15 Vladimir Serbinenko * term/serial.c (serial_get_divisor) [GRUB_MACHINE_MIPS_YEELOONG]: diff --git a/disk/efi/efidisk.c b/disk/efi/efidisk.c index 58300a0d2..f9c6f3153 100644 --- a/disk/efi/efidisk.c +++ b/disk/efi/efidisk.c @@ -825,7 +825,7 @@ grub_efidisk_get_device_name (grub_efi_handle_t *handle) if (! disk) return 1; - if (disk->id == GRUB_DISK_DEVICE_EFIDISK_ID) + if (disk->dev->id == GRUB_DISK_DEVICE_EFIDISK_ID) { struct grub_efidisk_data *d; From d9f31a41ca6acb44a0f4d0ee78e0d464e3167fef Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 16 Feb 2010 13:23:08 +0100 Subject: [PATCH 429/738] 2010-02-16 Vladimir Serbinenko Remove any reference to non-free fonts. * commands/videotest.c (grub_cmd_videotest): Use unifont by default. * docs/gfxmenu-theme-example.txt: Removed. It's both outdated and uses non-free components. * font/font.c (grub_font_get_name): Remove example name. * gfxmenu/gui_label.c (grub_gui_label_new): Use unifont by default. * gfxmenu/gui_list.c (grub_gui_list_new): Likewise. * gfxmenu/gui_progress_bar.c (grub_gui_progress_bar_new): Likewise. * gfxmenu/view.c (grub_gfxmenu_view_new): Likewise. --- ChangeLog | 13 ++++ commands/videotest.c | 11 +-- docs/gfxmenu-theme-example.txt | 128 --------------------------------- font/font.c | 2 +- gfxmenu/gui_label.c | 2 +- gfxmenu/gui_list.c | 2 +- gfxmenu/gui_progress_bar.c | 2 +- gfxmenu/view.c | 2 +- 8 files changed, 21 insertions(+), 141 deletions(-) delete mode 100644 docs/gfxmenu-theme-example.txt diff --git a/ChangeLog b/ChangeLog index d6925f0dd..1817ad732 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2010-02-16 Vladimir Serbinenko + + Remove any reference to non-free fonts. + + * commands/videotest.c (grub_cmd_videotest): Use unifont by default. + * docs/gfxmenu-theme-example.txt: Removed. It's both outdated and + uses non-free components. + * font/font.c (grub_font_get_name): Remove example name. + * gfxmenu/gui_label.c (grub_gui_label_new): Use unifont by default. + * gfxmenu/gui_list.c (grub_gui_list_new): Likewise. + * gfxmenu/gui_progress_bar.c (grub_gui_progress_bar_new): Likewise. + * gfxmenu/view.c (grub_gfxmenu_view_new): Likewise. + 2010-02-16 Georgy Buranov * disk/efi/efidisk.c (grub_efidisk_get_device_name): Fix a typo. diff --git a/commands/videotest.c b/commands/videotest.c index 1730a2031..390811a71 100644 --- a/commands/videotest.c +++ b/commands/videotest.c @@ -69,9 +69,9 @@ grub_cmd_videotest (grub_command_t cmd __attribute__ ((unused)), color = grub_video_map_rgb (0, 255, 255); grub_video_fill_rect (color, 100, 100, 100, 100); - sansbig = grub_font_get ("Helvetica Bold 24"); - sans = grub_font_get ("Helvetica Bold 14"); - sanssmall = grub_font_get ("Helvetica 8"); + sansbig = grub_font_get ("Unknown Regular 16"); + sans = grub_font_get ("Unknown Regular 16"); + sanssmall = grub_font_get ("Unknown Regular 16"); fixed = grub_font_get ("Fixed 20"); if (! sansbig || ! sans || ! sanssmall || ! fixed) return grub_error (GRUB_ERR_BAD_FONT, "no font loaded"); @@ -126,11 +126,6 @@ grub_cmd_videotest (grub_command_t cmd __attribute__ ((unused)), grub_font_draw_string (str, fixed, color, 16, texty); texty += grub_font_get_descent (fixed) + grub_font_get_leading (fixed); - /* Some character don't exist in the Helvetica font, so the font engine - will fall back to using glyphs from another font that does contain them. - TODO The font engine should be smart about selecting a replacement font - and prioritize fonts with similar sizes. */ - texty += grub_font_get_ascent(sansbig); grub_font_draw_string (str, sansbig, color, 16, texty); texty += grub_font_get_descent (sansbig) + grub_font_get_leading (sansbig); diff --git a/docs/gfxmenu-theme-example.txt b/docs/gfxmenu-theme-example.txt deleted file mode 100644 index 4363dc8df..000000000 --- a/docs/gfxmenu-theme-example.txt +++ /dev/null @@ -1,128 +0,0 @@ -# GRUB gfxmenu theme "winter". -# Uses background image from: -# http://www.cyberpunkcafe.com/e107_plugins/autogallery/autogallery.php?show=1.Open%20Source%20Wallpaper -# "without-leaves.png" was called "Without Leafs in Winter.png" - -lua-script: "winter.lua" -title-text: "" -title-font: "Helvetica Bold 18" -status-font: "Helvetica 8" -terminal-font: "Fixed 9" -title-color: "40, 40, 40" -status-color: "#FFF" -status-bg-color: "0, 166, 183, 128" -desktop-image: "without-leaves.png" -desktop-color: "0, 154, 183" -terminal-box: "terminal_*.png" - -+ boot_menu { - position = (120, 60) - preferred_size = (400, -1) - item_font = "Helvetica Bold 14" - selected_item_font = "Helvetica Bold 14" - item_color = "0, 0, 0" - selected_item_color = "203, 251, 255" - menu_pixmap_style = "menu_*.png" - selected_item_pixmap_style = "select_*.png" - icon_width = 44 - icon_height = 44 - item_height = 32 - item_padding = 0 - item_icon_space = 3 - item_spacing = 11 -} - -# You can add text at arbitrary locations on the screen. -# The specification within the "+label {...}" block is free-form, -# so you can use as much or as little white space as you like. - -+ label { - position = (170, 50) - font = "smoothansi 13" - color = "0,0,128" - text = "This is the Winter theme ... brought to you by GRUB!" -} - -# Show the text alignment supported by labels. -+ vbox { - position = (220, 347) - preferred_size = (200, -1) # A preferred size of -1 means automatic. - + label { text="Text alignment demo" align="center" font="aqui 11" } - + label { text="Left" align="left" font="cure 11" } - + label { text="Center" align="center" font="cure 11" } - + label { text="Right" align="right" font="cure 11" } -} - -+ vbox { - position = (580, 10) - + label { text="GNU" font="gelly 11" color="0, 0, 0" } - + label { text="GRUB" font="aqui 11" color="0, 0, 0" } - + label { text="boot loader" font="cure 11" color="0, 0, 0" } -} - -+ hbox { - position = (80, 10) - + label { text="GNU" font="gelly 11" color="0, 0, 0" } - + label { text="GRUB" font="aqui 11" color="0, 0, 0" } - + label { text="boot loader" font="cure 11" color="0, 0, 0" } -} - -# Demonstration of a compound layout: boxes within boxes. -+ hbox -{ - position = (480, 3) - - + vbox - { - # Note: We can't just use 'size' to set the image's size, - # since the vbox will resize the component according to its - # preferred size, which for images is the native image size. - - + image { file="/boot/grub/themes/icons/ubuntu.png" - preferred_size = (20, 20) } - + image { file="/boot/grub/themes/icons/gentoo.png" - preferred_size = (20, 20) } - } - - + vbox - { - + label { text="GRand" font="cure 11" color=#99F } - + label { text="Unified" font="cure 11" color=#BBF } - + label { text="Bootloader" font="cure 11" color=#DDF } - } -} - -# By defining a 'progress_bar' type component with an ID of '__timeout__', -# the progress bar will be used to display the time remaining before an -# the default entry is automatically booted. -+ progress_bar -{ - id = "__timeout__" - position = (80, 393) - preferred_size = (500, 24) - font = "cure 11" - text_color = #000 - fg_color = #CCF - bg_color = #66B - border_color = #006 - show_text = false -} - -# Although the progress_bar component is normally used to indicate the -# time remaining, it's also possible to create other components with an ID -# of '__timeout__'. All components with and ID of 'timeout_bar' will have -# the following properties set based on the timeout value: -# text, value, start, end, visible. -# In this case, we have set 'show_text=false' on the progress bar, and use -# the following label's 'text' property to display the message. -+ label -{ - id = "__timeout__" - position = (80, 420) - preferred_size = (500, 24) - font = "lime 11" - color = #117 - align = "center" -} - - diff --git a/font/font.c b/font/font.c index 16f2ed35b..1b3dc6387 100644 --- a/font/font.c +++ b/font/font.c @@ -862,7 +862,7 @@ grub_font_get (const char *font_name) return &null_font; } -/* Get the full name of the font. For instance, "Helvetica Bold 12". */ +/* Get the full name of the font. */ const char * grub_font_get_name (grub_font_t font) { diff --git a/gfxmenu/gui_label.c b/gfxmenu/gui_label.c index b2835ea1a..a9dd575ac 100644 --- a/gfxmenu/gui_label.c +++ b/gfxmenu/gui_label.c @@ -216,7 +216,7 @@ grub_gui_label_new (void) label->comp.ops = &label_ops; label->visible = 1; label->text = grub_strdup (""); - label->font = grub_font_get ("Helvetica 10"); + label->font = grub_font_get ("Unknown Regular 16"); label->color.red = 0; label->color.green = 0; label->color.blue = 0; diff --git a/gfxmenu/gui_list.c b/gfxmenu/gui_list.c index a78339385..0d771413f 100644 --- a/gfxmenu/gui_list.c +++ b/gfxmenu/gui_list.c @@ -566,7 +566,7 @@ grub_gui_list_new (void) self->visible = 1; - default_font = grub_font_get ("Helvetica 12"); + default_font = grub_font_get ("Unknown Regular 16"); default_fg_color = grub_gui_color_rgb (0, 0, 0); default_bg_color = grub_gui_color_rgb (255, 255, 255); diff --git a/gfxmenu/gui_progress_bar.c b/gfxmenu/gui_progress_bar.c index 4fda61d49..d786aae31 100644 --- a/gfxmenu/gui_progress_bar.c +++ b/gfxmenu/gui_progress_bar.c @@ -371,7 +371,7 @@ grub_gui_progress_bar_new (void) self->progress.ops = &progress_bar_pb_ops; self->progress.component.ops = &progress_bar_ops; self->visible = 1; - self->font = grub_font_get ("Helvetica 10"); + self->font = grub_font_get ("Unknown Regular 16"); grub_gui_color_t black = { .red = 0, .green = 0, .blue = 0, .alpha = 255 }; grub_gui_color_t gray = { .red = 128, .green = 128, .blue = 128, .alpha = 255 }; grub_gui_color_t lightgray = { .red = 200, .green = 200, .blue = 200, .alpha = 255 }; diff --git a/gfxmenu/view.c b/gfxmenu/view.c index 611c01e1b..bf637a96d 100644 --- a/gfxmenu/view.c +++ b/gfxmenu/view.c @@ -66,7 +66,7 @@ grub_gfxmenu_view_new (const char *theme_path, view->screen.width = width; view->screen.height = height; - default_font = grub_font_get ("Helvetica 12"); + default_font = grub_font_get ("Unknown Regular 16"); default_fg_color = grub_gui_color_rgb (0, 0, 0); default_bg_color = grub_gui_color_rgb (255, 255, 255); From 0a39de87d9371ce8d1a844a6f52bdc81ae257420 Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Thu, 18 Feb 2010 08:56:31 +0100 Subject: [PATCH 430/738] 2010-02-14 Samuel Thibault * util/grub-mkconfig.in: Export GRUB_INIT_TUNE. * util/grub.d/00_header.in: Handle GRUB_INIT_TUNE. --- ChangeLog | 5 +++++ util/grub-mkconfig.in | 3 ++- util/grub.d/00_header.in | 8 ++++++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 1817ad732..38bb39ac9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-02-14 Samuel Thibault + + * util/grub-mkconfig.in: Export GRUB_INIT_TUNE. + * util/grub.d/00_header.in: Handle GRUB_INIT_TUNE. + 2010-02-16 Vladimir Serbinenko Remove any reference to non-free fonts. diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in index 1363f479a..fb1dd4544 100644 --- a/util/grub-mkconfig.in +++ b/util/grub-mkconfig.in @@ -222,7 +222,8 @@ export GRUB_DEFAULT \ GRUB_GFXMODE \ GRUB_THEME \ GRUB_GFXPAYLOAD_LINUX \ - GRUB_DISABLE_OS_PROBER + GRUB_DISABLE_OS_PROBER \ + GRUB_INIT_TUNE if test "x${grub_cfg}" != "x"; then rm -f ${grub_cfg}.new diff --git a/util/grub.d/00_header.in b/util/grub.d/00_header.in index a7b051daf..c86f7b867 100644 --- a/util/grub.d/00_header.in +++ b/util/grub.d/00_header.in @@ -158,3 +158,11 @@ else set timeout=${GRUB_TIMEOUT} EOF fi + +# Play an initial tune +if [ "x${GRUB_INIT_TUNE}" != "x" ] ; then + cat << EOF +insmod play +play ${GRUB_INIT_TUNE} +EOF +fi From 42b1d186858987e2672ac0c483fe47d864193f87 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 20 Feb 2010 11:15:51 +0100 Subject: [PATCH 431/738] 2010-02-20 Vladimir Serbinenko * video/fb/video_fb.c (grub_video_fb_scroll): Fix a pixel size bug. Reported by: Michael Suchanek. --- ChangeLog | 7 ++++++- video/fb/video_fb.c | 6 ++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 38bb39ac9..ca8e3c3fd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,9 @@ -2010-02-14 Samuel Thibault +2010-02-20 Vladimir Serbinenko + + * video/fb/video_fb.c (grub_video_fb_scroll): Fix a pixel size bug. + Reported by: Michael Suchanek. + +2010-02-18 Samuel Thibault * util/grub-mkconfig.in: Export GRUB_INIT_TUNE. * util/grub.d/00_header.in: Handle GRUB_INIT_TUNE. diff --git a/video/fb/video_fb.c b/video/fb/video_fb.c index 65652c3cf..9c5577bb9 100644 --- a/video/fb/video_fb.c +++ b/video/fb/video_fb.c @@ -1006,11 +1006,13 @@ grub_video_fb_scroll (grub_video_color_t color, int dx, int dy) { \ /* 3b. Move data downwards. */ \ dst = (void *) grub_video_fb_get_video_ptr (&target, \ - dst_x + width - 1, \ + dst_x + width, \ dst_y + height - 1); \ src = (void *) grub_video_fb_get_video_ptr (&target, \ - src_x + width - 1, \ + src_x + width, \ src_y + height - 1); \ + dst--; \ + src--; \ for (j = 0; j < height; j++) \ { \ for (i = 0; i < linelen; i++) \ From d1484a422ec7d94394e17277584a28730f92ff4e Mon Sep 17 00:00:00 2001 From: Manoel Rebelo Abranches Date: Sat, 20 Feb 2010 11:23:13 +0100 Subject: [PATCH 432/738] 2010-02-20 Manoel Rebelo Abranches * term/ieee1275/ofconsole.c (grub_ofconsole_readkey): Add delete and backspace keys. --- ChangeLog | 5 ++ term/ieee1275/ofconsole.c | 119 ++++++++++++++++++++++++-------------- 2 files changed, 79 insertions(+), 45 deletions(-) diff --git a/ChangeLog b/ChangeLog index ca8e3c3fd..95dcd51a7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-02-20 Manoel Rebelo Abranches + + * term/ieee1275/ofconsole.c (grub_ofconsole_readkey): Add delete and + backspace keys. + 2010-02-20 Vladimir Serbinenko * video/fb/video_fb.c (grub_video_fb_scroll): Fix a pixel size bug. diff --git a/term/ieee1275/ofconsole.c b/term/ieee1275/ofconsole.c index 82108022a..a4ffdcd23 100644 --- a/term/ieee1275/ofconsole.c +++ b/term/ieee1275/ofconsole.c @@ -202,53 +202,82 @@ grub_ofconsole_readkey (int *key) grub_ieee1275_read (stdin_ihandle, &c, 1, &actual); - if (actual > 0 && c == '\e') - { - grub_uint64_t start; - grub_ieee1275_read (stdin_ihandle, &c, 1, &actual); - - /* On 9600 we have to wait up to 12 milliseconds. */ - start = grub_get_time_ms (); - while (actual <= 0 && grub_get_time_ms () - start < 12) - grub_ieee1275_read (stdin_ihandle, &c, 1, &actual); - - if (actual <= 0) + if (actual > 0) + switch(c) + { + case 0x7f: + /* Backspace: Ctrl-h. */ + c = '\b'; + break; + case '\e': { - *key = '\e'; - return 1; + grub_uint64_t start; + grub_ieee1275_read (stdin_ihandle, &c, 1, &actual); + + /* On 9600 we have to wait up to 12 milliseconds. */ + start = grub_get_time_ms (); + while (actual <= 0 && grub_get_time_ms () - start < 12) + grub_ieee1275_read (stdin_ihandle, &c, 1, &actual); + + if (actual <= 0) + { + *key = '\e'; + return 1; + } + + if (c != '[') + return 0; + + grub_ieee1275_read (stdin_ihandle, &c, 1, &actual); + + /* On 9600 we have to wait up to 12 milliseconds. */ + start = grub_get_time_ms (); + while (actual <= 0 && grub_get_time_ms () - start < 12) + grub_ieee1275_read (stdin_ihandle, &c, 1, &actual); + if (actual <= 0) + return 0; + + switch (c) + { + case 'A': + /* Up: Ctrl-p. */ + c = GRUB_TERM_UP; + break; + case 'B': + /* Down: Ctrl-n. */ + c = GRUB_TERM_DOWN; + break; + case 'C': + /* Right: Ctrl-f. */ + c = GRUB_TERM_RIGHT; + break; + case 'D': + /* Left: Ctrl-b. */ + c = GRUB_TERM_LEFT; + break; + case '3': + { + grub_uint64_t start; + grub_ieee1275_read (stdin_ihandle, &c, 1, &actual); + /* On 9600 we have to wait up to 12 milliseconds. */ + start = grub_get_time_ms (); + while (actual <= 0 && grub_get_time_ms () - start < 12) + grub_ieee1275_read (stdin_ihandle, &c, 1, &actual); + + if (actual <= 0) + return 0; + + /* Delete: Ctrl-d. */ + if (c == '~') + c = GRUB_TERM_DC; + else + return 0; + break; + } + break; + } } - - if (c != '[') - return 0; - - grub_ieee1275_read (stdin_ihandle, &c, 1, &actual); - /* On 9600 we have to wait up to 12 milliseconds. */ - start = grub_get_time_ms (); - while (actual <= 0 && grub_get_time_ms () - start < 12) - grub_ieee1275_read (stdin_ihandle, &c, 1, &actual); - if (actual <= 0) - return 0; - - switch (c) - { - case 'A': - /* Up: Ctrl-p. */ - c = GRUB_TERM_UP; - break; - case 'B': - /* Down: Ctrl-n. */ - c = GRUB_TERM_DOWN; - break; - case 'C': - /* Right: Ctrl-f. */ - c = GRUB_TERM_RIGHT; - break; - case 'D': - /* Left: Ctrl-b. */ - c = GRUB_TERM_LEFT; - break; - } - } + } *key = c; return actual > 0; From 7dd05b96dcda4ad27b3d3a4d3025d1e9a3bce1e6 Mon Sep 17 00:00:00 2001 From: carles Date: Sat, 20 Feb 2010 23:31:35 +0000 Subject: [PATCH 433/738] 2010-02-20 Carles Pina i Estany * util/grub-mkrawimage.c (usage): Change string formatting to improve gettext. --- ChangeLog | 5 +++++ util/grub-mkrawimage.c | 13 ++++++++----- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 95dcd51a7..fbfe0ef6a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-02-20 Carles Pina i Estany + + * util/grub-mkrawimage.c (usage): Change string formatting to + improve gettext. + 2010-02-20 Manoel Rebelo Abranches * term/ieee1275/ofconsole.c (grub_ofconsole_readkey): Add delete and diff --git a/util/grub-mkrawimage.c b/util/grub-mkrawimage.c index 83bb51c02..dd84f2d81 100644 --- a/util/grub-mkrawimage.c +++ b/util/grub-mkrawimage.c @@ -446,10 +446,8 @@ Make a bootable image of GRUB.\n\ -o, --output=FILE output a generated image to FILE [default=stdout]\n" #ifdef GRUB_PLATFORM_IMAGE_DEFAULT "\ - -O, --format=FORMAT generate an image in format [default=" - GRUB_PLATFORM_IMAGE_DEFAULT_FORMAT "]\n \ - available formats: " - GRUB_PLATFORM_IMAGE_FORMATS "\n" + -O, --format=FORMAT generate an image in format [default=%s]\n\ + available formats: %s\n" #endif "\ -h, --help display this message and exit\n\ @@ -457,7 +455,12 @@ Make a bootable image of GRUB.\n\ -v, --verbose print verbose messages\n\ \n\ Report bugs to <%s>.\n\ -"), program_name, GRUB_LIBDIR, DEFAULT_DIRECTORY, PACKAGE_BUGREPORT); +"), +program_name, GRUB_LIBDIR, DEFAULT_DIRECTORY, +#ifdef GRUB_PLATFORM_IMAGE_DEFAULT + GRUB_PLATFORM_IMAGE_DEFAULT_FORMAT, GRUB_PLATFORM_IMAGE_FORMATS, +#endif +PACKAGE_BUGREPORT); exit (status); } From 618307dd08e2a1e710ed2d3122b1ae6146c0850f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 22 Feb 2010 09:18:59 +0100 Subject: [PATCH 434/738] 2010-02-20 Vladimir Serbinenko * fs/iso9660.c (grub_iso9660_iterate_dir): Strip version from joliet filename. Reported by: Georgy Buranov --- ChangeLog | 6 ++++++ fs/iso9660.c | 6 +++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index fbfe0ef6a..509870f95 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-02-20 Vladimir Serbinenko + + * fs/iso9660.c (grub_iso9660_iterate_dir): Strip version from joliet + filename. + Reported by: Georgy Buranov + 2010-02-20 Carles Pina i Estany * util/grub-mkrawimage.c (usage): Change string formatting to diff --git a/fs/iso9660.c b/fs/iso9660.c index cadfbba2b..6dc465f25 100644 --- a/fs/iso9660.c +++ b/fs/iso9660.c @@ -629,12 +629,16 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir, if (dir->data->joliet) { - char *oldname; + char *oldname, *semicolon; oldname = filename; filename = grub_iso9660_convert_string ((grub_uint16_t *) oldname, dirent.namelen >> 1); + semicolon = grub_strrchr (filename, ';'); + if (semicolon) + *semicolon = '\0'; + if (filename_alloc) grub_free (oldname); From 33dfc52f44114ec268eba26e18bcb19668b729d8 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 22 Feb 2010 12:42:13 +0000 Subject: [PATCH 435/738] 2010-02-10 Colin King 2010-02-10 Colin Watson Shrink the pre-partition-table part of boot.img by eight bytes. * boot/i386/pc/boot.S (ERR): New macro. (chs_mode): Use ERR. (geometry_error): Likewise. (hd_probe_error): Remove. This is only used once, so we wrwite it inline instead. (read_error): Instead of printing read_error_string, just set up %si and fall through to ... (error_message): ... this new function, also used by ERR. --- ChangeLog.trim-boot-img | 13 +++++++++++++ boot/i386/pc/boot.S | 18 ++++++------------ 2 files changed, 19 insertions(+), 12 deletions(-) create mode 100644 ChangeLog.trim-boot-img diff --git a/ChangeLog.trim-boot-img b/ChangeLog.trim-boot-img new file mode 100644 index 000000000..26408af25 --- /dev/null +++ b/ChangeLog.trim-boot-img @@ -0,0 +1,13 @@ +2010-02-10 Colin King +2010-02-10 Colin Watson + + Shrink the pre-partition-table part of boot.img by eight bytes. + + * boot/i386/pc/boot.S (ERR): New macro. + (chs_mode): Use ERR. + (geometry_error): Likewise. + (hd_probe_error): Remove. This is only used once, so we wrwite + it inline instead. + (read_error): Instead of printing read_error_string, just set up + %si and fall through to ... + (error_message): ... this new function, also used by ERR. diff --git a/boot/i386/pc/boot.S b/boot/i386/pc/boot.S index 257f9044e..4afc57349 100644 --- a/boot/i386/pc/boot.S +++ b/boot/i386/pc/boot.S @@ -27,6 +27,7 @@ /* Print message string */ #define MSG(x) movw $x, %si; call LOCAL(message) +#define ERR(x) movw $x, %si; jmp LOCAL(error_message) .file "boot.S" @@ -233,7 +234,7 @@ LOCAL(chs_mode): jz LOCAL(floppy_probe) /* Nope, we definitely have a hard disk, and we're screwed. */ - jmp LOCAL(hd_probe_error) + ERR(hd_probe_error_string) LOCAL(final_init): /* set the mode to zero */ @@ -360,22 +361,15 @@ LOCAL(copy_buffer): * BIOS Geometry translation error (past the end of the disk geometry!). */ LOCAL(geometry_error): - MSG(geometry_error_string) - jmp LOCAL(general_error) - -/* - * Disk probe failure. - */ -LOCAL(hd_probe_error): - MSG(hd_probe_error_string) - jmp LOCAL(general_error) + ERR(geometry_error_string) /* * Read error on the disk. */ LOCAL(read_error): - MSG(read_error_string) - + movw $read_error_string, %si +LOCAL(error_message): + call LOCAL(message) LOCAL(general_error): MSG(general_error_string) From 2b8fa975d4fc8b4759b947b1dc7559ce8e95ff0a Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 24 Feb 2010 10:02:16 +0000 Subject: [PATCH 436/738] 2010-02-24 Joey Korkames * term/ieee1275/ofconsole.c (grub_ofconsole_readkey): Remove duplicate declaration of `start'. --- ChangeLog | 5 +++++ term/ieee1275/ofconsole.c | 1 - 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 509870f95..fb5c42dce 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-02-24 Joey Korkames + + * term/ieee1275/ofconsole.c (grub_ofconsole_readkey): Remove + duplicate declaration of `start'. + 2010-02-20 Vladimir Serbinenko * fs/iso9660.c (grub_iso9660_iterate_dir): Strip version from joliet diff --git a/term/ieee1275/ofconsole.c b/term/ieee1275/ofconsole.c index a4ffdcd23..c0f895a15 100644 --- a/term/ieee1275/ofconsole.c +++ b/term/ieee1275/ofconsole.c @@ -257,7 +257,6 @@ grub_ofconsole_readkey (int *key) break; case '3': { - grub_uint64_t start; grub_ieee1275_read (stdin_ihandle, &c, 1, &actual); /* On 9600 we have to wait up to 12 milliseconds. */ start = grub_get_time_ms (); From f17d332e493775a5ef3ef3e9140d7cf3b9337816 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 24 Feb 2010 11:29:11 +0100 Subject: [PATCH 437/738] Remove trailing spaces in kern/device.c --- kern/device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kern/device.c b/kern/device.c index 5cfd190f3..cd019fdaf 100644 --- a/kern/device.c +++ b/kern/device.c @@ -152,7 +152,7 @@ grub_device_iterate (int (*hook) (const char *name)) grub_free (partition_name); grub_free (p); return 1; - } + } grub_free (partition_name); p->next = ents; From 607ffde2caa0d6f9734e519b17040fe4bcaf8995 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 24 Feb 2010 15:21:36 +0100 Subject: [PATCH 438/738] 2010-02-24 Vladimir Serbinenko * loader/i386/multiboot_mbi.c (grub_multiboot_set_bootdev): Fix a memory leak. Reported by: Seth Goldberg. --- ChangeLog | 6 ++++++ loader/i386/multiboot_mbi.c | 1 + 2 files changed, 7 insertions(+) diff --git a/ChangeLog b/ChangeLog index fb5c42dce..35ecc7073 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-02-24 Vladimir Serbinenko + + * loader/i386/multiboot_mbi.c (grub_multiboot_set_bootdev): Fix a + memory leak. + Reported by: Seth Goldberg. + 2010-02-24 Joey Korkames * term/ieee1275/ofconsole.c (grub_ofconsole_readkey): Remove diff --git a/loader/i386/multiboot_mbi.c b/loader/i386/multiboot_mbi.c index a154d1b23..3f937c446 100644 --- a/loader/i386/multiboot_mbi.c +++ b/loader/i386/multiboot_mbi.c @@ -463,6 +463,7 @@ grub_multiboot_set_bootdev (void) if ((p[0] >= 'a') && (p[0] <= 'z')) part = p[0] - 'a'; } + grub_free (p); } if (dev) grub_device_close (dev); From 4a8a763c7b03814e70ba26b09c2e0c1108b9164a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 24 Feb 2010 15:24:21 +0100 Subject: [PATCH 439/738] 2010-02-24 Vladimir Serbinenko * normal/crypto.c (read_crypto_list): Fix a memory leak. * normal/term.c (read_terminal_list): Likewise. * normal/main.c (grub_normal_init_page): Likewise. (grub_normal_read_line_real): Likewise. --- ChangeLog | 7 +++++++ normal/crypto.c | 1 + normal/main.c | 4 ++++ normal/term.c | 1 + 4 files changed, 13 insertions(+) diff --git a/ChangeLog b/ChangeLog index 35ecc7073..24981a5fc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-02-24 Vladimir Serbinenko + + * normal/crypto.c (read_crypto_list): Fix a memory leak. + * normal/term.c (read_terminal_list): Likewise. + * normal/main.c (grub_normal_init_page): Likewise. + (grub_normal_read_line_real): Likewise. + 2010-02-24 Vladimir Serbinenko * loader/i386/multiboot_mbi.c (grub_multiboot_set_bootdev): Fix a diff --git a/normal/crypto.c b/normal/crypto.c index 932f26f97..95899fbd5 100644 --- a/normal/crypto.c +++ b/normal/crypto.c @@ -88,6 +88,7 @@ read_crypto_list (void) } file = grub_file_open (filename); + grub_free (filename); if (!file) { grub_errno = GRUB_ERR_NONE; diff --git a/normal/main.c b/normal/main.c index 9f8c12773..2306427fc 100644 --- a/normal/main.c +++ b/normal/main.c @@ -418,6 +418,7 @@ grub_normal_init_page (struct grub_term_output *term) msg_len = grub_utf8_to_ucs4_alloc (msg_formatted, &unicode_msg, &last_position); + grub_free (msg_formatted); if (msg_len < 0) { @@ -582,10 +583,13 @@ grub_normal_read_line_real (char **line, int cont, int nested) if (cont || nested) { grub_free (*line); + grub_free (prompt); *line = 0; return grub_errno; } } + + grub_free (prompt); return 0; } diff --git a/normal/term.c b/normal/term.c index 42201fbb3..e31d403ee 100644 --- a/normal/term.c +++ b/normal/term.c @@ -175,6 +175,7 @@ read_terminal_list (void) } file = grub_file_open (filename); + grub_free (filename); if (!file) { grub_errno = GRUB_ERR_NONE; From a0ca21c2d2ccf7cb6985507b0cef6e676234fd67 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Thu, 25 Feb 2010 13:30:50 +0000 Subject: [PATCH 440/738] 2010-02-25 Jordan Uggla * util/grub-mkconfig.in (GRUB_SAVEDEFAULT): Export new variable. * util/grub-mkconfig_lib.in (save_default_entry): Only save a new default entry if GRUB_SAVEDEFAULT=true. This allows using GRUB_DEFAULT=saved on its own to let grub-reboot work, without saving a new default on every boot. --- ChangeLog | 8 ++++++++ util/grub-mkconfig.in | 3 ++- util/grub-mkconfig_lib.in | 2 +- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 24981a5fc..b8f6ba35d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2010-02-25 Jordan Uggla + + * util/grub-mkconfig.in (GRUB_SAVEDEFAULT): Export new variable. + * util/grub-mkconfig_lib.in (save_default_entry): Only save a new + default entry if GRUB_SAVEDEFAULT=true. This allows using + GRUB_DEFAULT=saved on its own to let grub-reboot work, without + saving a new default on every boot. + 2010-02-24 Vladimir Serbinenko * normal/crypto.c (read_crypto_list): Fix a memory leak. diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in index fb1dd4544..daa110be7 100644 --- a/util/grub-mkconfig.in +++ b/util/grub-mkconfig.in @@ -223,7 +223,8 @@ export GRUB_DEFAULT \ GRUB_THEME \ GRUB_GFXPAYLOAD_LINUX \ GRUB_DISABLE_OS_PROBER \ - GRUB_INIT_TUNE + GRUB_INIT_TUNE \ + GRUB_SAVEDEFAULT if test "x${grub_cfg}" != "x"; then rm -f ${grub_cfg}.new diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in index 45354041a..bcd6baffb 100644 --- a/util/grub-mkconfig_lib.in +++ b/util/grub-mkconfig_lib.in @@ -96,7 +96,7 @@ convert_system_path_to_grub_path () save_default_entry () { - if [ "x${GRUB_DEFAULT}" = "xsaved" ] ; then + if [ "x${GRUB_SAVEDEFAULT}" = "xtrue" ] ; then cat << EOF savedefault EOF From c140a1803787036762faec8f76d931b11f66148a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 25 Feb 2010 15:10:18 +0100 Subject: [PATCH 441/738] 2010-02-25 Vladimir Serbinenko Don't compile video modules on yeeloong since video subsystem is part of kernel. * conf/common.rmk (pkglib_MODULES) [yeeloong]: Remove video.mod, video_fb.mod, bitmap.mod, font.mod, gfxterm.mod and bufio.mod * conf/mips-yeeloong.rmk (kernel_img_HEADERS): Add bitmap.h, video.h, gfxterm.h, font.h, bitmap_scale.h and bufio.h. * conf/mips.rmk (kernel_img_HEADERS): Add values instead of overwriting. * include/grub/bitmap.h: Add EXPORT_FUNC and EXPORT_VAR. * include/grub/bitmap_scale.h: Likewise. * include/grub/bufio.h: Likewise. * include/grub/font.h: Likewise. * include/grub/gfxterm.h: Likewise. * include/grub/video.h: Likewise. * include/grub/vbe.h: Don't include video_fb.h. * video/i386/pc/vbe.c: Include video_fb.h. * commands/i386/pc/vbetest.c: Include video.h. --- ChangeLog | 20 +++++++++ commands/i386/pc/vbetest.c | 1 + conf/common.rmk | 68 +++++++++++++++++----------- conf/mips-yeeloong.rmk | 3 ++ conf/mips.rmk | 2 +- include/grub/bitmap.h | 26 +++++------ include/grub/bitmap_scale.h | 11 ++--- include/grub/bufio.h | 4 +- include/grub/font.h | 40 +++++++++-------- include/grub/gfxterm.h | 14 +++--- include/grub/i386/pc/vbe.h | 2 - include/grub/video.h | 88 +++++++++++++++++++++---------------- video/i386/pc/vbe.c | 1 + 13 files changed, 168 insertions(+), 112 deletions(-) diff --git a/ChangeLog b/ChangeLog index b8f6ba35d..233e1fc2d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,23 @@ +2010-02-25 Vladimir Serbinenko + + Don't compile video modules on yeeloong since video subsystem is part + of kernel. + + * conf/common.rmk (pkglib_MODULES) [yeeloong]: Remove video.mod, + video_fb.mod, bitmap.mod, font.mod, gfxterm.mod and bufio.mod + * conf/mips-yeeloong.rmk (kernel_img_HEADERS): Add bitmap.h, + video.h, gfxterm.h, font.h, bitmap_scale.h and bufio.h. + * conf/mips.rmk (kernel_img_HEADERS): Add values instead of overwriting. + * include/grub/bitmap.h: Add EXPORT_FUNC and EXPORT_VAR. + * include/grub/bitmap_scale.h: Likewise. + * include/grub/bufio.h: Likewise. + * include/grub/font.h: Likewise. + * include/grub/gfxterm.h: Likewise. + * include/grub/video.h: Likewise. + * include/grub/vbe.h: Don't include video_fb.h. + * video/i386/pc/vbe.c: Include video_fb.h. + * commands/i386/pc/vbetest.c: Include video.h. + 2010-02-25 Jordan Uggla * util/grub-mkconfig.in (GRUB_SAVEDEFAULT): Export new variable. diff --git a/commands/i386/pc/vbetest.c b/commands/i386/pc/vbetest.c index d97323087..d2921c09d 100644 --- a/commands/i386/pc/vbetest.c +++ b/commands/i386/pc/vbetest.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include diff --git a/conf/common.rmk b/conf/common.rmk index 6cce36395..7effa8af3 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -621,26 +621,28 @@ sh_mod_SOURCES = script/main.c script/script.c script/execute.c \ sh_mod_CFLAGS = $(COMMON_CFLAGS) sh_mod_LDFLAGS = $(COMMON_LDFLAGS) +ifneq (, $(FONT_SOURCE)) +font/font.c_DEPENDENCIES = ascii.h +endif + # Common Video Subsystem specific modules. -pkglib_MODULES += video.mod videotest.mod bitmap.mod tga.mod jpeg.mod \ - png.mod gfxterm.mod video_fb.mod +# On Yeeloong it's part of kernel +ifneq ($(platform), yeeloong) # For video.mod. +pkglib_MODULES += video.mod video_mod_SOURCES = video/video.c video_mod_CFLAGS = $(COMMON_CFLAGS) video_mod_LDFLAGS = $(COMMON_LDFLAGS) +pkglib_MODULES += video_fb.mod video_fb_mod_SOURCES = video/fb/video_fb.c video/fb/fbblit.c \ video/fb/fbfill.c video/fb/fbutil.c video_fb_mod_CFLAGS = $(COMMON_CFLAGS) video_fb_mod_LDFLAGS = $(COMMON_LDFLAGS) -# For videotest.mod. -videotest_mod_SOURCES = commands/videotest.c -videotest_mod_CFLAGS = $(COMMON_CFLAGS) -videotest_mod_LDFLAGS = $(COMMON_LDFLAGS) - # For bitmap.mod +pkglib_MODULES += bitmap.mod bitmap_mod_SOURCES = video/bitmap.c bitmap_mod_CFLAGS = $(COMMON_CFLAGS) bitmap_mod_LDFLAGS = $(COMMON_LDFLAGS) @@ -651,36 +653,46 @@ bitmap_scale_mod_SOURCES = video/bitmap_scale.c bitmap_scale_mod_CFLAGS = $(COMMON_CFLAGS) bitmap_scale_mod_LDFLAGS = $(COMMON_LDFLAGS) -# For tga.mod -tga_mod_SOURCES = video/readers/tga.c -tga_mod_CFLAGS = $(COMMON_CFLAGS) -tga_mod_LDFLAGS = $(COMMON_LDFLAGS) - -# For jpeg.mod. -jpeg_mod_SOURCES = video/readers/jpeg.c -jpeg_mod_CFLAGS = $(COMMON_CFLAGS) -jpeg_mod_LDFLAGS = $(COMMON_LDFLAGS) - -# For png.mod. -png_mod_SOURCES = video/readers/png.c -png_mod_CFLAGS = $(COMMON_CFLAGS) -png_mod_LDFLAGS = $(COMMON_LDFLAGS) - pkglib_MODULES += font.mod -ifneq (, $(FONT_SOURCE)) -font/font.c_DEPENDENCIES = ascii.h -endif font_mod_SOURCES = font/font_cmd.c font/font.c font_mod_CFLAGS = $(COMMON_CFLAGS) font_mod_LDFLAGS = $(COMMON_LDFLAGS) # For gfxterm.mod. +pkglib_MODULES += gfxterm.mod gfxterm_mod_SOURCES = term/gfxterm.c gfxterm_mod_CFLAGS = $(COMMON_CFLAGS) gfxterm_mod_LDFLAGS = $(COMMON_LDFLAGS) +endif + +# For videotest.mod. +pkglib_MODULES += videotest.mod +videotest_mod_SOURCES = commands/videotest.c +videotest_mod_CFLAGS = $(COMMON_CFLAGS) +videotest_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For tga.mod +pkglib_MODULES += tga.mod +tga_mod_SOURCES = video/readers/tga.c +tga_mod_CFLAGS = $(COMMON_CFLAGS) +tga_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For jpeg.mod. +pkglib_MODULES += jpeg.mod +jpeg_mod_SOURCES = video/readers/jpeg.c +jpeg_mod_CFLAGS = $(COMMON_CFLAGS) +jpeg_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For png.mod. +pkglib_MODULES += png.mod +png_mod_SOURCES = video/readers/png.c +png_mod_CFLAGS = $(COMMON_CFLAGS) +png_mod_LDFLAGS = $(COMMON_LDFLAGS) + + # Misc. -pkglib_MODULES += gzio.mod bufio.mod elf.mod +pkglib_MODULES += gzio.mod elf.mod # For elf.mod. elf_mod_SOURCES = kern/elf.c @@ -692,10 +704,14 @@ gzio_mod_SOURCES = io/gzio.c gzio_mod_CFLAGS = $(COMMON_CFLAGS) gzio_mod_LDFLAGS = $(COMMON_LDFLAGS) +# On Yeeloong it's part of kernel +ifneq ($(platform), yeeloong) # For bufio.mod. +pkglib_MODULES += bufio.mod bufio_mod_SOURCES = io/bufio.c bufio_mod_CFLAGS = $(COMMON_CFLAGS) bufio_mod_LDFLAGS = $(COMMON_LDFLAGS) +endif # For gettext.mod. pkglib_MODULES += gettext.mod diff --git a/conf/mips-yeeloong.rmk b/conf/mips-yeeloong.rmk index eb0dc9676..0d9a4c1bb 100644 --- a/conf/mips-yeeloong.rmk +++ b/conf/mips-yeeloong.rmk @@ -3,6 +3,9 @@ LINK_BASE = 0x80200000 target_machine=yeeloong COMMON_CFLAGS += -march=mips3 COMMON_ASFLAGS += -march=mips3 + +kernel_img_HEADERS += bitmap.h video.h gfxterm.h font.h bitmap_scale.h bufio.h + include $(srcdir)/conf/mips.mk pkglib_IMAGES = kernel.img diff --git a/conf/mips.rmk b/conf/mips.rmk index 1ef4fc395..c7c80a26d 100644 --- a/conf/mips.rmk +++ b/conf/mips.rmk @@ -13,7 +13,7 @@ script/lexer.c_DEPENDENCIES = grub_script.tab.h MOSTLYCLEANFILES += symlist.c kernel_syms.lst DEFSYMFILES += kernel_syms.lst -kernel_img_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ +kernel_img_HEADERS += boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ env.h err.h file.h fs.h kernel.h misc.h mm.h net.h parser.h reader.h \ symbol.h term.h time.h types.h loader.h partition.h \ msdos_partition.h machine/kernel.h handler.h list.h \ diff --git a/include/grub/bitmap.h b/include/grub/bitmap.h index 42c439d69..6e300391a 100644 --- a/include/grub/bitmap.h +++ b/include/grub/bitmap.h @@ -47,24 +47,24 @@ struct grub_video_bitmap_reader }; typedef struct grub_video_bitmap_reader *grub_video_bitmap_reader_t; -void grub_video_bitmap_reader_register (grub_video_bitmap_reader_t reader); -void grub_video_bitmap_reader_unregister (grub_video_bitmap_reader_t reader); +void EXPORT_FUNC (grub_video_bitmap_reader_register) (grub_video_bitmap_reader_t reader); +void EXPORT_FUNC (grub_video_bitmap_reader_unregister) (grub_video_bitmap_reader_t reader); -grub_err_t grub_video_bitmap_create (struct grub_video_bitmap **bitmap, - unsigned int width, unsigned int height, - enum grub_video_blit_format blit_format); +grub_err_t EXPORT_FUNC (grub_video_bitmap_create) (struct grub_video_bitmap **bitmap, + unsigned int width, unsigned int height, + enum grub_video_blit_format blit_format); -grub_err_t grub_video_bitmap_destroy (struct grub_video_bitmap *bitmap); +grub_err_t EXPORT_FUNC (grub_video_bitmap_destroy) (struct grub_video_bitmap *bitmap); -grub_err_t grub_video_bitmap_load (struct grub_video_bitmap **bitmap, - const char *filename); +grub_err_t EXPORT_FUNC (grub_video_bitmap_load) (struct grub_video_bitmap **bitmap, + const char *filename); -unsigned int grub_video_bitmap_get_width (struct grub_video_bitmap *bitmap); -unsigned int grub_video_bitmap_get_height (struct grub_video_bitmap *bitmap); +unsigned int EXPORT_FUNC (grub_video_bitmap_get_width) (struct grub_video_bitmap *bitmap); +unsigned int EXPORT_FUNC (grub_video_bitmap_get_height) (struct grub_video_bitmap *bitmap); -void grub_video_bitmap_get_mode_info (struct grub_video_bitmap *bitmap, - struct grub_video_mode_info *mode_info); +void EXPORT_FUNC (grub_video_bitmap_get_mode_info) (struct grub_video_bitmap *bitmap, + struct grub_video_mode_info *mode_info); -void *grub_video_bitmap_get_data (struct grub_video_bitmap *bitmap); +void *EXPORT_FUNC (grub_video_bitmap_get_data) (struct grub_video_bitmap *bitmap); #endif /* ! GRUB_BITMAP_HEADER */ diff --git a/include/grub/bitmap_scale.h b/include/grub/bitmap_scale.h index 7ea9d7914..dce9fbbf2 100644 --- a/include/grub/bitmap_scale.h +++ b/include/grub/bitmap_scale.h @@ -39,10 +39,11 @@ enum grub_video_bitmap_scale_method }; grub_err_t -grub_video_bitmap_create_scaled (struct grub_video_bitmap **dst, - int dst_width, int dst_height, - struct grub_video_bitmap *src, - enum - grub_video_bitmap_scale_method scale_method); +EXPORT_FUNC (grub_video_bitmap_create_scaled) (struct grub_video_bitmap **dst, + int dst_width, int dst_height, + struct grub_video_bitmap *src, + enum + grub_video_bitmap_scale_method + scale_method); #endif /* ! GRUB_BITMAP_SCALE_HEADER */ diff --git a/include/grub/bufio.h b/include/grub/bufio.h index 9a2294c26..acdd0c882 100644 --- a/include/grub/bufio.h +++ b/include/grub/bufio.h @@ -22,7 +22,7 @@ #include -grub_file_t grub_bufio_open (grub_file_t io, int size); -grub_file_t grub_buffile_open (const char *name, int size); +grub_file_t EXPORT_FUNC (grub_bufio_open) (grub_file_t io, int size); +grub_file_t EXPORT_FUNC (grub_buffile_open) (const char *name, int size); #endif /* ! GRUB_BUFIO_H */ diff --git a/include/grub/font.h b/include/grub/font.h index 1816e3570..7c5c17403 100644 --- a/include/grub/font.h +++ b/include/grub/font.h @@ -81,36 +81,38 @@ int grub_font_load (const char *filename); "Family Name Bold Italic 14", where Bold and Italic are optional. If no font matches the name specified, the most recently loaded font is returned as a fallback. */ -grub_font_t grub_font_get (const char *font_name); +grub_font_t EXPORT_FUNC (grub_font_get) (const char *font_name); -const char *grub_font_get_name (grub_font_t font); +const char *EXPORT_FUNC (grub_font_get_name) (grub_font_t font); -int grub_font_get_max_char_width (grub_font_t font); +int EXPORT_FUNC (grub_font_get_max_char_width) (grub_font_t font); -int grub_font_get_max_char_height (grub_font_t font); +int EXPORT_FUNC (grub_font_get_max_char_height) (grub_font_t font); -int grub_font_get_ascent (grub_font_t font); +int EXPORT_FUNC (grub_font_get_ascent) (grub_font_t font); -int grub_font_get_descent (grub_font_t font); +int EXPORT_FUNC (grub_font_get_descent) (grub_font_t font); -int grub_font_get_leading (grub_font_t font); +int EXPORT_FUNC (grub_font_get_leading) (grub_font_t font); -int grub_font_get_height (grub_font_t font); +int EXPORT_FUNC (grub_font_get_height) (grub_font_t font); -int grub_font_get_string_width (grub_font_t font, const char *str); +int EXPORT_FUNC (grub_font_get_string_width) (grub_font_t font, + const char *str); -struct grub_font_glyph *grub_font_get_glyph (grub_font_t font, - grub_uint32_t code); +struct grub_font_glyph *EXPORT_FUNC (grub_font_get_glyph) (grub_font_t font, + grub_uint32_t code); -struct grub_font_glyph *grub_font_get_glyph_with_fallback (grub_font_t font, - grub_uint32_t code); +struct grub_font_glyph *EXPORT_FUNC (grub_font_get_glyph_with_fallback) (grub_font_t font, + grub_uint32_t code); -grub_err_t grub_font_draw_glyph (struct grub_font_glyph *glyph, - grub_video_color_t color, - int left_x, int baseline_y); +grub_err_t EXPORT_FUNC (grub_font_draw_glyph) (struct grub_font_glyph *glyph, + grub_video_color_t color, + int left_x, int baseline_y); -grub_err_t grub_font_draw_string (const char *str, grub_font_t font, - grub_video_color_t color, - int left_x, int baseline_y); +grub_err_t EXPORT_FUNC (grub_font_draw_string) (const char *str, + grub_font_t font, + grub_video_color_t color, + int left_x, int baseline_y); #endif /* ! GRUB_FONT_HEADER */ diff --git a/include/grub/gfxterm.h b/include/grub/gfxterm.h index fe3da7409..295354baf 100644 --- a/include/grub/gfxterm.h +++ b/include/grub/gfxterm.h @@ -25,20 +25,20 @@ #include grub_err_t -grub_gfxterm_set_window (struct grub_video_render_target *target, - int x, int y, int width, int height, - int double_repaint, - const char *font_name, int border_width); +EXPORT_FUNC (grub_gfxterm_set_window) (struct grub_video_render_target *target, + int x, int y, int width, int height, + int double_repaint, + const char *font_name, int border_width); typedef void (*grub_gfxterm_repaint_callback_t)(int x, int y, int width, int height); void grub_gfxterm_set_repaint_callback (grub_gfxterm_repaint_callback_t func); -void grub_gfxterm_schedule_repaint (void); +void EXPORT_FUNC (grub_gfxterm_schedule_repaint) (void); -grub_err_t grub_gfxterm_fullscreen (void); +grub_err_t EXPORT_FUNC (grub_gfxterm_fullscreen) (void); -extern void (*grub_gfxterm_decorator_hook) (void); +extern void (*EXPORT_VAR (grub_gfxterm_decorator_hook)) (void); #endif /* ! GRUB_GFXTERM_HEADER */ diff --git a/include/grub/i386/pc/vbe.h b/include/grub/i386/pc/vbe.h index 9c4c4dd3d..abf246fa1 100644 --- a/include/grub/i386/pc/vbe.h +++ b/include/grub/i386/pc/vbe.h @@ -19,8 +19,6 @@ #ifndef GRUB_VBE_MACHINE_HEADER #define GRUB_VBE_MACHINE_HEADER 1 -#include - /* Default video mode to be used. */ #define GRUB_VBE_DEFAULT_VIDEO_MODE 0x101 diff --git a/include/grub/video.h b/include/grub/video.h index fa459aebd..57f2b37f2 100644 --- a/include/grub/video.h +++ b/include/grub/video.h @@ -259,13 +259,13 @@ struct grub_video_adapter }; typedef struct grub_video_adapter *grub_video_adapter_t; -void grub_video_register (grub_video_adapter_t adapter); +void EXPORT_FUNC (grub_video_register) (grub_video_adapter_t adapter); void grub_video_unregister (grub_video_adapter_t adapter); void grub_video_iterate (int (*hook) (grub_video_adapter_t adapter)); -grub_err_t grub_video_restore (void); +grub_err_t EXPORT_FUNC (grub_video_restore) (void); -grub_err_t grub_video_get_info (struct grub_video_mode_info *mode_info); +grub_err_t EXPORT_FUNC (grub_video_get_info) (struct grub_video_mode_info *mode_info); /* Framebuffer address may change as a part of normal operation (e.g. double buffering). That's why you need to stop video subsystem to be @@ -283,57 +283,71 @@ grub_err_t grub_video_set_palette (unsigned int start, unsigned int count, grub_err_t grub_video_get_palette (unsigned int start, unsigned int count, struct grub_video_palette_data *palette_data); -grub_err_t grub_video_set_viewport (unsigned int x, unsigned int y, - unsigned int width, unsigned int height); +grub_err_t EXPORT_FUNC (grub_video_set_viewport) (unsigned int x, + unsigned int y, + unsigned int width, + unsigned int height); -grub_err_t grub_video_get_viewport (unsigned int *x, unsigned int *y, - unsigned int *width, unsigned int *height); +grub_err_t EXPORT_FUNC (grub_video_get_viewport) (unsigned int *x, + unsigned int *y, + unsigned int *width, + unsigned int *height); -grub_video_color_t grub_video_map_color (grub_uint32_t color_name); +grub_video_color_t EXPORT_FUNC (grub_video_map_color) (grub_uint32_t color_name); -grub_video_color_t grub_video_map_rgb (grub_uint8_t red, grub_uint8_t green, - grub_uint8_t blue); +grub_video_color_t EXPORT_FUNC (grub_video_map_rgb) (grub_uint8_t red, + grub_uint8_t green, + grub_uint8_t blue); -grub_video_color_t grub_video_map_rgba (grub_uint8_t red, grub_uint8_t green, - grub_uint8_t blue, grub_uint8_t alpha); +grub_video_color_t EXPORT_FUNC (grub_video_map_rgba) (grub_uint8_t red, + grub_uint8_t green, + grub_uint8_t blue, + grub_uint8_t alpha); -grub_err_t grub_video_unmap_color (grub_video_color_t color, - grub_uint8_t *red, grub_uint8_t *green, - grub_uint8_t *blue, grub_uint8_t *alpha); +grub_err_t EXPORT_FUNC (grub_video_unmap_color) (grub_video_color_t color, + grub_uint8_t *red, + grub_uint8_t *green, + grub_uint8_t *blue, + grub_uint8_t *alpha); -grub_err_t grub_video_fill_rect (grub_video_color_t color, int x, int y, - unsigned int width, unsigned int height); +grub_err_t EXPORT_FUNC (grub_video_fill_rect) (grub_video_color_t color, + int x, int y, + unsigned int width, + unsigned int height); -grub_err_t grub_video_blit_bitmap (struct grub_video_bitmap *bitmap, - enum grub_video_blit_operators oper, - int x, int y, int offset_x, int offset_y, - unsigned int width, unsigned int height); +grub_err_t EXPORT_FUNC (grub_video_blit_bitmap) (struct grub_video_bitmap *bitmap, + enum grub_video_blit_operators oper, + int x, int y, + int offset_x, int offset_y, + unsigned int width, + unsigned int height); -grub_err_t grub_video_blit_render_target (struct grub_video_render_target *source, - enum grub_video_blit_operators oper, - int x, int y, - int offset_x, int offset_y, - unsigned int width, - unsigned int height); +grub_err_t EXPORT_FUNC (grub_video_blit_render_target) (struct grub_video_render_target *source, + enum grub_video_blit_operators oper, + int x, int y, + int offset_x, + int offset_y, + unsigned int width, + unsigned int height); grub_err_t grub_video_scroll (grub_video_color_t color, int dx, int dy); -grub_err_t grub_video_swap_buffers (void); +grub_err_t EXPORT_FUNC (grub_video_swap_buffers) (void); -grub_err_t grub_video_create_render_target (struct grub_video_render_target **result, - unsigned int width, - unsigned int height, - unsigned int mode_type); +grub_err_t EXPORT_FUNC (grub_video_create_render_target) (struct grub_video_render_target **result, + unsigned int width, + unsigned int height, + unsigned int mode_type); -grub_err_t grub_video_delete_render_target (struct grub_video_render_target *target); +grub_err_t EXPORT_FUNC (grub_video_delete_render_target) (struct grub_video_render_target *target); -grub_err_t grub_video_set_active_render_target (struct grub_video_render_target *target); +grub_err_t EXPORT_FUNC (grub_video_set_active_render_target) (struct grub_video_render_target *target); grub_err_t grub_video_get_active_render_target (struct grub_video_render_target **target); -grub_err_t grub_video_set_mode (const char *modestring, - unsigned int modemask, - unsigned int modevalue); +grub_err_t EXPORT_FUNC (grub_video_set_mode) (const char *modestring, + unsigned int modemask, + unsigned int modevalue); static inline int grub_video_check_mode_flag (unsigned int flags, unsigned int mask, diff --git a/video/i386/pc/vbe.c b/video/i386/pc/vbe.c index 0107cc297..72b8f1831 100644 --- a/video/i386/pc/vbe.c +++ b/video/i386/pc/vbe.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include From 72b286313ab2c1e94f115b04bda5c17f99150484 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 26 Feb 2010 14:32:24 +0100 Subject: [PATCH 442/738] 2010-02-26 Vladimir Serbinenko * util/grub.d/10_linux.in (linux_entry): Don't default to gfxpayload=keep if Linux doesn't support video handover. --- ChangeLog | 5 +++++ util/grub.d/10_linux.in | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 233e1fc2d..e7617dc1d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-02-26 Vladimir Serbinenko + + * util/grub.d/10_linux.in (linux_entry): Don't default to + gfxpayload=keep if Linux doesn't support video handover. + 2010-02-25 Vladimir Serbinenko Don't compile video modules on yeeloong since video subsystem is part diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in index 046874ef0..2c60bc681 100644 --- a/util/grub.d/10_linux.in +++ b/util/grub.d/10_linux.in @@ -66,7 +66,8 @@ linux_entry () # Use ELILO's generic "efifb" when it's known to be available. # FIXME: We need an interface to select vesafb in case efifb can't be used. if [ "x$GRUB_GFXPAYLOAD_LINUX" = x ]; then - if grep -qx "CONFIG_FB_EFI=y" /boot/config-${version} 2> /dev/null ; then + if grep -qx "CONFIG_FB_EFI=y" /boot/config-${version} 2> /dev/null \ + && grep -qx "CONFIG_VT_HW_CONSOLE_BINDING=y" /boot/config-${version} 2> /dev/null; then cat << EOF set gfxpayload=keep EOF From 5519963bf6ae5804f98b4828b6c9687f9f31a9cf Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 1 Mar 2010 19:07:48 +0100 Subject: [PATCH 443/738] 2010-03-01 Vladimir Serbinenko * configure.ac: Update version to 1.98. --- ChangeLog | 4 ++++ configure.ac | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index e7617dc1d..3812610d7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-03-01 Vladimir Serbinenko + + * configure.ac: Update version to 1.98. + 2010-02-26 Vladimir Serbinenko * util/grub.d/10_linux.in (linux_entry): Don't default to diff --git a/configure.ac b/configure.ac index 48702afd6..ac3f0d196 100644 --- a/configure.ac +++ b/configure.ac @@ -31,7 +31,7 @@ dnl (such as TARGET_CC, TARGET_CFLAGS, etc.) are used for the target dnl type. -AC_INIT([GRUB],[1.97],[bug-grub@gnu.org]) +AC_INIT([GRUB],[1.98],[bug-grub@gnu.org]) AM_INIT_AUTOMAKE() AC_PREREQ(2.60) AC_CONFIG_SRCDIR([include/grub/dl.h]) From 5382b1e4a899b713f3fd50a123e7bfb380e3beef Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 1 Mar 2010 20:24:34 +0100 Subject: [PATCH 444/738] 2010-03-01 Vladimir Serbinenko * commands/cat.c (grub_cmd_cat): Propagate grub_gzfile_open error. --- ChangeLog | 4 ++++ commands/cat.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 3812610d7..2010872b1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-03-01 Vladimir Serbinenko + + * commands/cat.c (grub_cmd_cat): Propagate grub_gzfile_open error. + 2010-03-01 Vladimir Serbinenko * configure.ac: Update version to 1.98. diff --git a/commands/cat.c b/commands/cat.c index 844034777..3bdafc4c6 100644 --- a/commands/cat.c +++ b/commands/cat.c @@ -41,7 +41,7 @@ grub_cmd_cat (grub_command_t cmd __attribute__ ((unused)), file = grub_gzfile_open (args[0], 1); if (! file) - return 0; + return grub_errno; while ((size = grub_file_read (file, buf, sizeof (buf))) > 0 && key != GRUB_TERM_ESC) From c6f2fe52f185525c64980321449e07637ade222f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 1 Mar 2010 20:58:45 +0100 Subject: [PATCH 445/738] 2010-03-01 Vladimir Serbinenko Wait for user entry basing on presence of output rather than on errors. * include/grub/normal.h (grub_normal_get_line_counter): New proto. (grub_install_newline_hook): Likewise. * normal/main.c (GRUB_MOD_INIT): Call grub_install_newline_hook. * normal/menu.c (show_menu): Check line_counter to determine presence of output. * normal/term.c (grub_normal_line_counter): New variable. (grub_normal_get_line_counter): New function. (grub_install_newline_hook): Likewise. --- ChangeLog | 13 +++++++++++++ include/grub/normal.h | 3 +++ normal/main.c | 1 + normal/menu.c | 12 ++++++------ normal/term.c | 16 +++++++++++++++- 5 files changed, 38 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2010872b1..5ba6dd4eb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2010-03-01 Vladimir Serbinenko + + Wait for user entry basing on presence of output rather than on errors. + + * include/grub/normal.h (grub_normal_get_line_counter): New proto. + (grub_install_newline_hook): Likewise. + * normal/main.c (GRUB_MOD_INIT): Call grub_install_newline_hook. + * normal/menu.c (show_menu): Check line_counter to determine presence + of output. + * normal/term.c (grub_normal_line_counter): New variable. + (grub_normal_get_line_counter): New function. + (grub_install_newline_hook): Likewise. + 2010-03-01 Vladimir Serbinenko * commands/cat.c (grub_cmd_cat): Propagate grub_gzfile_open error. diff --git a/include/grub/normal.h b/include/grub/normal.h index fad1a41ba..fe45ddf71 100644 --- a/include/grub/normal.h +++ b/include/grub/normal.h @@ -110,4 +110,7 @@ void read_terminal_list (void); void grub_set_more (int onoff); +int grub_normal_get_line_counter (void); +void grub_install_newline_hook (void); + #endif /* ! GRUB_NORMAL_HEADER */ diff --git a/normal/main.c b/normal/main.c index 2306427fc..5a5467485 100644 --- a/normal/main.c +++ b/normal/main.c @@ -654,6 +654,7 @@ GRUB_MOD_INIT(normal) grub_set_history (GRUB_DEFAULT_HISTORY_SIZE); + grub_install_newline_hook (); grub_register_variable_hook ("pager", 0, grub_env_write_pager); /* Register a command "normal" for the rescue mode. */ diff --git a/normal/menu.c b/normal/menu.c index c47e83bc2..07951dacc 100644 --- a/normal/menu.c +++ b/normal/menu.c @@ -559,14 +559,14 @@ show_menu (grub_menu_t menu, int nested) } else { + int lines_before = grub_normal_get_line_counter (); grub_errno = GRUB_ERR_NONE; grub_menu_execute_entry (e); - if (grub_errno != GRUB_ERR_NONE) - { - grub_print_error (); - grub_errno = GRUB_ERR_NONE; - grub_wait_after_message (); - } + grub_print_error (); + grub_errno = GRUB_ERR_NONE; + + if (lines_before != grub_normal_get_line_counter ()) + grub_wait_after_message (); } } diff --git a/normal/term.c b/normal/term.c index e31d403ee..7bedd6799 100644 --- a/normal/term.c +++ b/normal/term.c @@ -30,6 +30,14 @@ static unsigned grub_more_lines; /* If the more pager is active. */ static int grub_more; +static int grub_normal_line_counter = 0; + +int +grub_normal_get_line_counter (void) +{ + return grub_normal_line_counter; +} + static void process_newline (void) { @@ -41,6 +49,8 @@ process_newline (void) height = grub_term_height (cur); grub_more_lines++; + grub_normal_line_counter++; + if (grub_more && grub_more_lines >= height - 1) { char key; @@ -76,6 +86,11 @@ grub_set_more (int onoff) grub_more--; grub_more_lines = 0; +} + +void +grub_install_newline_hook (void) +{ grub_newline_hook = process_newline; } @@ -150,7 +165,6 @@ grub_terminal_autoload_free (void) grub_term_output_autoload = NULL; } - /* Read the file terminal.lst for auto-loading. */ void read_terminal_list (void) From c4d0b332c54e34b6a40fcda05183943ee192f24c Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 1 Mar 2010 21:00:02 +0100 Subject: [PATCH 446/738] 2010-03-01 Vladimir Serbinenko * fs/ext2.c (grub_ext2_read_block): Fix an integer overflow. --- ChangeLog | 4 ++++ fs/ext2.c | 9 ++++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5ba6dd4eb..90bbce0e2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-03-01 Vladimir Serbinenko + + * fs/ext2.c (grub_ext2_read_block): Fix an integer overflow. + 2010-03-01 Vladimir Serbinenko Wait for user entry basing on presence of output rather than on errors. diff --git a/fs/ext2.c b/fs/ext2.c index ac36b329b..f2fec828a 100644 --- a/fs/ext2.c +++ b/fs/ext2.c @@ -436,7 +436,8 @@ grub_ext2_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) grub_uint32_t indir[blksz / 4]; if (grub_disk_read (data->disk, - grub_le_to_cpu32 (inode->blocks.indir_block) + ((grub_disk_addr_t) + grub_le_to_cpu32 (inode->blocks.indir_block)) << log2_blksz, 0, blksz, indir)) return grub_errno; @@ -452,13 +453,15 @@ grub_ext2_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) grub_uint32_t indir[blksz / 4]; if (grub_disk_read (data->disk, - grub_le_to_cpu32 (inode->blocks.double_indir_block) + ((grub_disk_addr_t) + grub_le_to_cpu32 (inode->blocks.double_indir_block)) << log2_blksz, 0, blksz, indir)) return grub_errno; if (grub_disk_read (data->disk, - grub_le_to_cpu32 (indir[rblock / perblock]) + ((grub_disk_addr_t) + grub_le_to_cpu32 (indir[rblock / perblock])) << log2_blksz, 0, blksz, indir)) return grub_errno; From 22d7b6137a3b362b6230af23dc1009f4ed87a208 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 3 Mar 2010 10:44:12 +0000 Subject: [PATCH 447/738] 2010-03-03 Colin Watson * util/hostdisk.c (struct grub_util_biosdisk_data): New structure. (grub_util_biosdisk_open): Initialise disk->data. (struct linux_partition_cache): New structure. (linux_find_partition): Cache partition start positions; these are expensive to compute on every read and write. (open_device): Cache open file descriptor in disk->data, so that we don't have to reopen it and flush the buffer cache for consecutive operations on the same device. (grub_util_biosdisk_close): New function. (grub_util_biosdisk_dev): Set `close' member. * conf/common.rmk (grub_probe_SOURCES): Add kern/list.c. * conf/i386-efi.rmk (grub_setup_SOURCES): Likewise. * conf/i386-pc.rmk (grub_setup_SOURCES): Likewise. * conf/sparc64-ieee1275.rmk (grub_setup_SOURCES): Likewise. * conf/x86_64-efi.rmk (grub_setup_SOURCES): Likewise. --- ChangeLog.hostdisk-speedup | 18 +++++++ conf/common.rmk | 2 +- conf/i386-efi.rmk | 2 +- conf/i386-pc.rmk | 3 +- conf/sparc64-ieee1275.rmk | 3 +- conf/x86_64-efi.rmk | 2 +- util/hostdisk.c | 104 ++++++++++++++++++++++++++++++++----- 7 files changed, 116 insertions(+), 18 deletions(-) create mode 100644 ChangeLog.hostdisk-speedup diff --git a/ChangeLog.hostdisk-speedup b/ChangeLog.hostdisk-speedup new file mode 100644 index 000000000..ef48978a4 --- /dev/null +++ b/ChangeLog.hostdisk-speedup @@ -0,0 +1,18 @@ +2010-03-03 Colin Watson + + * util/hostdisk.c (struct grub_util_biosdisk_data): New structure. + (grub_util_biosdisk_open): Initialise disk->data. + (struct linux_partition_cache): New structure. + (linux_find_partition): Cache partition start positions; these are + expensive to compute on every read and write. + (open_device): Cache open file descriptor in disk->data, so that we + don't have to reopen it and flush the buffer cache for consecutive + operations on the same device. + (grub_util_biosdisk_close): New function. + (grub_util_biosdisk_dev): Set `close' member. + + * conf/common.rmk (grub_probe_SOURCES): Add kern/list.c. + * conf/i386-efi.rmk (grub_setup_SOURCES): Likewise. + * conf/i386-pc.rmk (grub_setup_SOURCES): Likewise. + * conf/sparc64-ieee1275.rmk (grub_setup_SOURCES): Likewise. + * conf/x86_64-efi.rmk (grub_setup_SOURCES): Likewise. diff --git a/conf/common.rmk b/conf/common.rmk index 7effa8af3..8f63e2db8 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -24,7 +24,7 @@ util/grub-probe.c_DEPENDENCIES = grub_probe_init.h grub_probe_SOURCES = gnulib/progname.c util/grub-probe.c \ util/hostdisk.c util/misc.c util/getroot.c \ kern/device.c kern/disk.c kern/err.c kern/misc.c \ - kern/parser.c kern/partition.c kern/file.c \ + kern/parser.c kern/partition.c kern/file.c kern/list.c \ \ fs/affs.c fs/cpio.c fs/fat.c fs/ext2.c fs/hfs.c \ fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \ diff --git a/conf/i386-efi.rmk b/conf/i386-efi.rmk index c03abb429..8f159e9c0 100644 --- a/conf/i386-efi.rmk +++ b/conf/i386-efi.rmk @@ -21,7 +21,7 @@ util/i386/efi/grub-mkimage.c_DEPENDENCIES = Makefile # kern/err.c kern/misc.c fs/fat.c fs/ext2.c fs/xfs.c fs/affs.c \ # fs/sfs.c kern/parser.c kern/partition.c partmap/msdos.c \ # fs/ufs.c fs/ufs2.c fs/minix.c fs/hfs.c fs/jfs.c fs/hfsplus.c kern/file.c \ -# kern/fs.c kern/env.c fs/fshelp.c +# kern/fs.c kern/env.c kern/list.c fs/fshelp.c # Scripts. sbin_SCRIPTS = grub-install diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk index 580bfea0a..610f4791b 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -96,7 +96,8 @@ grub_setup_SOURCES = gnulib/progname.c \ util/i386/pc/grub-setup.c util/hostdisk.c \ util/misc.c util/getroot.c kern/device.c kern/disk.c \ kern/err.c kern/misc.c kern/parser.c kern/partition.c \ - kern/file.c kern/fs.c kern/env.c fs/fshelp.c \ + kern/file.c kern/fs.c kern/env.c kern/list.c \ + fs/fshelp.c \ \ fs/affs.c fs/cpio.c fs/ext2.c fs/fat.c fs/hfs.c \ fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \ diff --git a/conf/sparc64-ieee1275.rmk b/conf/sparc64-ieee1275.rmk index befc7dce5..e8bdccb2d 100644 --- a/conf/sparc64-ieee1275.rmk +++ b/conf/sparc64-ieee1275.rmk @@ -70,7 +70,8 @@ util/sparc64/ieee1275/grub-setup.c_DEPENDENCIES = grub_setup_init.h grub_setup_SOURCES = util/sparc64/ieee1275/grub-setup.c util/hostdisk.c \ util/misc.c util/getroot.c kern/device.c kern/disk.c \ kern/err.c kern/misc.c kern/parser.c kern/partition.c \ - kern/file.c kern/fs.c kern/env.c fs/fshelp.c \ + kern/file.c kern/fs.c kern/env.c kern/list.c \ + fs/fshelp.c \ \ fs/affs.c fs/cpio.c fs/ext2.c fs/fat.c fs/hfs.c \ fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \ diff --git a/conf/x86_64-efi.rmk b/conf/x86_64-efi.rmk index d5c3c24cb..e17777e0a 100644 --- a/conf/x86_64-efi.rmk +++ b/conf/x86_64-efi.rmk @@ -20,7 +20,7 @@ grub_mkimage_SOURCES = gnulib/progname.c util/i386/efi/grub-mkimage.c \ # kern/err.c kern/misc.c fs/fat.c fs/ext2.c fs/xfs.c fs/affs.c \ # fs/sfs.c kern/parser.c kern/partition.c partmap/msdos.c \ # fs/ufs.c fs/ufs2.c fs/minix.c fs/hfs.c fs/jfs.c fs/hfsplus.c kern/file.c \ -# kern/fs.c kern/env.c fs/fshelp.c +# kern/fs.c kern/env.c kern/list.c fs/fshelp.c # Scripts. sbin_SCRIPTS = grub-install diff --git a/util/hostdisk.c b/util/hostdisk.c index 98d3d53ae..9ece36885 100644 --- a/util/hostdisk.c +++ b/util/hostdisk.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -103,6 +104,12 @@ struct char *device; } map[256]; +struct grub_util_biosdisk_data +{ + char *dev; + int fd; +}; + #ifdef __linux__ /* Check if we have devfs support. */ static int @@ -165,6 +172,7 @@ grub_util_biosdisk_open (const char *name, grub_disk_t disk) { int drive; struct stat st; + struct grub_util_biosdisk_data *data; drive = find_grub_drive (name); if (drive < 0) @@ -173,6 +181,9 @@ grub_util_biosdisk_open (const char *name, grub_disk_t disk) disk->has_partitions = 1; disk->id = drive; + disk->data = data = xmalloc (sizeof (struct grub_util_biosdisk_data)); + data->dev = NULL; + data->fd = -1; /* Get the size. */ #if defined(__MINGW32__) @@ -254,6 +265,17 @@ grub_util_biosdisk_open (const char *name, grub_disk_t disk) } #ifdef __linux__ +/* Cache of partition start sectors for each disk. */ +struct linux_partition_cache +{ + struct linux_partition_cache *next; + char *dev; + unsigned long start; + int partno; +}; + +struct linux_partition_cache *linux_partition_cache_list; + static int linux_find_partition (char *dev, unsigned long sector) { @@ -262,6 +284,7 @@ linux_find_partition (char *dev, unsigned long sector) char *p; int i; char real_dev[PATH_MAX]; + struct linux_partition_cache *cache; strcpy(real_dev, dev); @@ -281,6 +304,16 @@ linux_find_partition (char *dev, unsigned long sector) format = "%d"; } + for (cache = linux_partition_cache_list; cache; cache = cache->next) + { + if (strcmp (cache->dev, dev) == 0 && cache->start == sector) + { + sprintf (p, format, cache->partno); + strcpy (dev, real_dev); + return 1; + } + } + for (i = 1; i < 10000; i++) { int fd; @@ -301,6 +334,15 @@ linux_find_partition (char *dev, unsigned long sector) if (hdg.start == sector) { + struct linux_partition_cache *new_cache_item; + + new_cache_item = xmalloc (sizeof *new_cache_item); + new_cache_item->dev = xstrdup (dev); + new_cache_item->start = hdg.start; + new_cache_item->partno = i; + grub_list_push (GRUB_AS_LIST_P (&linux_partition_cache_list), + GRUB_AS_LIST (new_cache_item)); + strcpy (dev, real_dev); return 1; } @@ -314,6 +356,7 @@ static int open_device (const grub_disk_t disk, grub_disk_addr_t sector, int flags) { int fd; + struct grub_util_biosdisk_data *data = disk->data; #ifdef O_LARGEFILE flags |= O_LARGEFILE; @@ -340,18 +383,30 @@ open_device (const grub_disk_t disk, grub_disk_addr_t sector, int flags) && strncmp (map[disk->id].device, "/dev/", 5) == 0) is_partition = linux_find_partition (dev, disk->partition->start); - /* Open the partition. */ - grub_dprintf ("hostdisk", "opening the device `%s' in open_device()\n", dev); - fd = open (dev, flags); - if (fd < 0) + if (data->dev && strcmp (data->dev, dev) == 0) { - grub_error (GRUB_ERR_BAD_DEVICE, "cannot open `%s'", dev); - return -1; + grub_dprintf ("hostdisk", "reusing open device `%s'\n", dev); + fd = data->fd; } + else + { + /* Open the partition. */ + grub_dprintf ("hostdisk", "opening the device `%s' in open_device()\n", dev); + fd = open (dev, flags); + if (fd < 0) + { + grub_error (GRUB_ERR_BAD_DEVICE, "cannot open `%s'", dev); + return -1; + } - /* Flush the buffer cache to the physical disk. - XXX: This also empties the buffer cache. */ - ioctl (fd, BLKFLSBUF, 0); + /* Flush the buffer cache to the physical disk. + XXX: This also empties the buffer cache. */ + ioctl (fd, BLKFLSBUF, 0); + + free (data->dev); + data->dev = xstrdup (dev); + data->fd = fd; + } if (is_partition) sector -= disk->partition->start; @@ -375,7 +430,21 @@ open_device (const grub_disk_t disk, grub_disk_addr_t sector, int flags) } #endif - fd = open (map[disk->id].device, flags); + if (data->dev && strcmp (data->dev, map[disk->id].device) == 0) + { + grub_dprintf ("hostdisk", "reusing open device `%s'\n", data->dev); + fd = data->fd; + } + else + { + fd = open (map[disk->id].device, flags); + if (fd >= 0) + { + free (data->dev); + data->dev = xstrdup (map[disk->id].device); + data->fd = fd; + } + } #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) if (! (sysctl_oldflags & 0x10) @@ -535,7 +604,6 @@ grub_util_biosdisk_read (grub_disk_t disk, grub_disk_addr_t sector, != (ssize_t) (size << GRUB_DISK_SECTOR_BITS)) grub_error (GRUB_ERR_READ_ERROR, "cannot read from `%s'", map[disk->id].device); - close (fd); return grub_errno; } @@ -570,17 +638,27 @@ grub_util_biosdisk_write (grub_disk_t disk, grub_disk_addr_t sector, != (ssize_t) (size << GRUB_DISK_SECTOR_BITS)) grub_error (GRUB_ERR_WRITE_ERROR, "cannot write to `%s'", map[disk->id].device); - close (fd); return grub_errno; } +static void +grub_util_biosdisk_close (struct grub_disk *disk) +{ + struct grub_util_biosdisk_data *data = disk->data; + + free (data->dev); + if (data->fd != -1) + close (data->fd); + free (data); +} + static struct grub_disk_dev grub_util_biosdisk_dev = { .name = "biosdisk", .id = GRUB_DISK_DEVICE_BIOSDISK_ID, .iterate = grub_util_biosdisk_iterate, .open = grub_util_biosdisk_open, - .close = 0, + .close = grub_util_biosdisk_close, .read = grub_util_biosdisk_read, .write = grub_util_biosdisk_write, .next = 0 From c6293875f961046e9d961db56fbf6082a5d955cc Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 3 Mar 2010 20:03:50 +0000 Subject: [PATCH 448/738] reopen device when the requested access mode changes --- util/hostdisk.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/util/hostdisk.c b/util/hostdisk.c index 9ece36885..b8f3129f0 100644 --- a/util/hostdisk.c +++ b/util/hostdisk.c @@ -107,6 +107,7 @@ struct struct grub_util_biosdisk_data { char *dev; + int access_mode; int fd; }; @@ -183,6 +184,7 @@ grub_util_biosdisk_open (const char *name, grub_disk_t disk) disk->id = drive; disk->data = data = xmalloc (sizeof (struct grub_util_biosdisk_data)); data->dev = NULL; + data->access_mode = 0; data->fd = -1; /* Get the size. */ @@ -383,13 +385,18 @@ open_device (const grub_disk_t disk, grub_disk_addr_t sector, int flags) && strncmp (map[disk->id].device, "/dev/", 5) == 0) is_partition = linux_find_partition (dev, disk->partition->start); - if (data->dev && strcmp (data->dev, dev) == 0) + if (data->dev && strcmp (data->dev, dev) == 0 && + data->access_mode == (flags & O_ACCMODE)) { grub_dprintf ("hostdisk", "reusing open device `%s'\n", dev); fd = data->fd; } else { + free (data->dev); + if (data->fd != -1) + close (data->fd); + /* Open the partition. */ grub_dprintf ("hostdisk", "opening the device `%s' in open_device()\n", dev); fd = open (dev, flags); @@ -403,8 +410,8 @@ open_device (const grub_disk_t disk, grub_disk_addr_t sector, int flags) XXX: This also empties the buffer cache. */ ioctl (fd, BLKFLSBUF, 0); - free (data->dev); data->dev = xstrdup (dev); + data->access_mode = (flags & O_ACCMODE); data->fd = fd; } @@ -430,18 +437,23 @@ open_device (const grub_disk_t disk, grub_disk_addr_t sector, int flags) } #endif - if (data->dev && strcmp (data->dev, map[disk->id].device) == 0) + if (data->dev && strcmp (data->dev, map[disk->id].device) == 0 && + data->access_mode == (flags & O_ACCMODE)) { grub_dprintf ("hostdisk", "reusing open device `%s'\n", data->dev); fd = data->fd; } else { + free (data->dev); + if (data->fd != -1) + close (data->fd); + fd = open (map[disk->id].device, flags); if (fd >= 0) { - free (data->dev); data->dev = xstrdup (map[disk->id].device); + data->access_mode = (flags & O_ACCMODE); data->fd = fd; } } From 08dcd91370183936b9a58882991564afc674a9b7 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 4 Mar 2010 15:12:34 +0100 Subject: [PATCH 449/738] 2010-03-04 Vladimir Serbinenko * util/i386/efi/grub-install.in: Copy gettext files. --- ChangeLog | 4 ++++ util/i386/efi/grub-install.in | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/ChangeLog b/ChangeLog index 90bbce0e2..6eb0d5377 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-03-04 Vladimir Serbinenko + + * util/i386/efi/grub-install.in: Copy gettext files. + 2010-03-01 Vladimir Serbinenko * fs/ext2.c (grub_ext2_read_block): Fix an integer overflow. diff --git a/util/i386/efi/grub-install.in b/util/i386/efi/grub-install.in index caa7be7e4..6a8573e81 100644 --- a/util/i386/efi/grub-install.in +++ b/util/i386/efi/grub-install.in @@ -180,6 +180,14 @@ for file in ${pkglibdir}/*.mod ${pkglibdir}/*.lst; do cp -f $file ${grubdir} || exit 1 done +# Copy gettext files +mkdir -p ${grubdir}/locale/ +for file in ${grubdir}/locale/*.mo ${pkglibdir}/locale/*.mo; do + if test -f "$file"; then + cp -f "$file" ${grubdir}/locale/ + fi +done + if ! test -f ${grubdir}/grubenv; then $grub_editenv ${grubdir}/grubenv create fi From a8efbf649e9fbacf850cee6c80f8b6aea9b691a5 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 4 Mar 2010 15:41:32 +0100 Subject: [PATCH 450/738] 2010-03-04 Vladimir Serbinenko * genmk.rb: Remove terminal*.lst in make clean. --- ChangeLog | 4 ++++ genmk.rb | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 6eb0d5377..e3b704c76 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-03-04 Vladimir Serbinenko + + * genmk.rb: Remove terminal*.lst in make clean. + 2010-03-04 Vladimir Serbinenko * util/i386/efi/grub-install.in: Copy gettext files. diff --git a/genmk.rb b/genmk.rb index df03e1dfe..efea16412 100644 --- a/genmk.rb +++ b/genmk.rb @@ -201,7 +201,7 @@ endif -include #{dep} clean-module-#{extra_target}.#{@rule_count}: - rm -f #{command} #{fs} #{partmap} #{handler} #{parttool} #{video} + rm -f #{command} #{fs} #{partmap} #{handler} #{parttool} #{video} #{terminal} CLEAN_MODULE_TARGETS += clean-module-#{extra_target}.#{@rule_count} From c0ee0385c9bc3a84aaa5de95aacefaff47dd07d6 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 4 Mar 2010 15:50:57 +0100 Subject: [PATCH 451/738] 2010-03-04 Vladimir Serbinenko * Makefile.in (CLEANFILES) [FONT_SOURCE && grub_mkfont]: Add ascii.bitmaps. --- ChangeLog | 5 +++++ Makefile.in | 1 + 2 files changed, 6 insertions(+) diff --git a/ChangeLog b/ChangeLog index e3b704c76..413622c32 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-03-04 Vladimir Serbinenko + + * Makefile.in (CLEANFILES) [FONT_SOURCE && grub_mkfont]: Add + ascii.bitmaps. + 2010-03-04 Vladimir Serbinenko * genmk.rb: Remove terminal*.lst in make clean. diff --git a/Makefile.in b/Makefile.in index 539cde397..5a4ef459f 100644 --- a/Makefile.in +++ b/Makefile.in @@ -239,6 +239,7 @@ else ifeq ($(enable_grub_mkfont),yes) pkgdata_DATA += unicode.pf2 ascii.pf2 ascii.h +CLEANFILES += ascii.bitmaps # Arrows and lines are needed to draw the menu, so we always include them UNICODE_ARROWS=0x2190-0x2193 From b4b7be98dbfa11240c59ba06df51e4baf68253da Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 4 Mar 2010 16:08:46 +0100 Subject: [PATCH 452/738] 2010-03-04 Vladimir Serbinenko * Makefile.in (DISTCLEANFILES): Add stamp-h1. --- ChangeLog | 4 ++++ Makefile.in | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 413622c32..255d3422c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-03-04 Vladimir Serbinenko + + * Makefile.in (DISTCLEANFILES): Add stamp-h1. + 2010-03-04 Vladimir Serbinenko * Makefile.in (CLEANFILES) [FONT_SOURCE && grub_mkfont]: Add diff --git a/Makefile.in b/Makefile.in index 5a4ef459f..4144dfb5a 100644 --- a/Makefile.in +++ b/Makefile.in @@ -147,7 +147,7 @@ INFOS = $(info_INFOS) CLEANFILES = MOSTLYCLEANFILES = DISTCLEANFILES = config.status config.cache config.log config.h \ - Makefile stamp-h include/grub/cpu include/grub/machine \ + Makefile stamp-h stamp-h1 include/grub/cpu include/grub/machine \ gensymlist.sh genkernsyms.sh build_env.mk \ docs/grub.info docs/version.texi docs/stamp-vti From f209b5b2305bdbed24bf9eb215e9625b7ea878be Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 4 Mar 2010 16:13:35 +0100 Subject: [PATCH 453/738] 2010-03-04 Vladimir Serbinenko * normal/crypto.c (read_crypto_list): Fix a typo. Reported by: Seth Goldberg. --- ChangeLog | 7 +++++++ normal/crypto.c | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 255d3422c..9246179f4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,12 @@ +2010-03-04 Vladimir Serbinenko + + * normal/crypto.c (read_crypto_list): Fix a typo. + Reported by: Seth Goldberg. + 2010-03-04 Vladimir Serbinenko * Makefile.in (DISTCLEANFILES): Add stamp-h1. + Reported by: Seth Goldberg. 2010-03-04 Vladimir Serbinenko @@ -10,6 +16,7 @@ 2010-03-04 Vladimir Serbinenko * genmk.rb: Remove terminal*.lst in make clean. + Reported by: Seth Goldberg. 2010-03-04 Vladimir Serbinenko diff --git a/normal/crypto.c b/normal/crypto.c index 95899fbd5..f051e2c4c 100644 --- a/normal/crypto.c +++ b/normal/crypto.c @@ -95,7 +95,7 @@ read_crypto_list (void) return; } - /* Override previous commands.lst. */ + /* Override previous crypto.lst. */ grub_crypto_spec_free (); for (;; grub_free (buf)) From 4760f97911b1c2ba2e98efc3e467381d8dc94af0 Mon Sep 17 00:00:00 2001 From: Christian Franke Date: Thu, 4 Mar 2010 16:25:26 +0100 Subject: [PATCH 454/738] 2010-03-04 Christian Franke * util/grub-pe2elf.c: Add missing include "progname.h". --- ChangeLog | 4 ++++ util/grub-pe2elf.c | 2 ++ 2 files changed, 6 insertions(+) diff --git a/ChangeLog b/ChangeLog index 9246179f4..634193596 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-03-04 Christian Franke + + * util/grub-pe2elf.c: Add missing include "progname.h". + 2010-03-04 Vladimir Serbinenko * normal/crypto.c (read_crypto_list): Fix a typo. diff --git a/util/grub-pe2elf.c b/util/grub-pe2elf.c index 488ad9b23..f370bbfa8 100644 --- a/util/grub-pe2elf.c +++ b/util/grub-pe2elf.c @@ -29,6 +29,8 @@ #include #include +#include "progname.h" + static struct option options[] = { {"help", no_argument, 0, 'h'}, {"version", no_argument, 0, 'V'}, From fc8345da984282291928da32f02f4317e7808a45 Mon Sep 17 00:00:00 2001 From: Jordan Uggla Date: Thu, 4 Mar 2010 16:28:57 +0100 Subject: [PATCH 455/738] 2010-03-04 Jordan Uggla * INSTALL: Add gettext as a dependency and add qemu to a new section "Prerequisites for make-check". --- ChangeLog | 5 +++++ INSTALL | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/ChangeLog b/ChangeLog index 634193596..d3d939985 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-03-04 Jordan Uggla + + * INSTALL: Add gettext as a dependency and add qemu to a new section + "Prerequisites for make-check". + 2010-03-04 Christian Franke * util/grub-pe2elf.c: Add missing include "progname.h". diff --git a/INSTALL b/INSTALL index cfade2026..0dd408bcc 100644 --- a/INSTALL +++ b/INSTALL @@ -14,6 +14,7 @@ configuring the GRUB. * GCC 4.1.3 or later * GNU Make * GNU Bison 2.3 or later +* GNU gettext 0.17 or later * GNU binutils 2.9.1.0.23 or later * Other standard GNU/Unix tools @@ -25,6 +26,10 @@ need the following. * Autoconf 2.60 or later * Automake 1.10.1 or later +Prerequisites for make-check: + +* qemu, specifically the binary 'qemu-system-i386' + Configuring the GRUB ==================== From b54d93ac1ba60ddee1a697e2f0b16d848385752f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 4 Mar 2010 17:03:43 +0100 Subject: [PATCH 456/738] 2010-03-04 Vladimir Serbinenko Disable linux.mod on qemu-mips since it's not functional and leads to compilation failure. * conf/mips.rmk (pkglib_MODULES): Remove linux.mod. * conf/mips-yeeloong.rmk (pkglib_MODULES): Add linux.mod. * conf/mips.rmk (linux_mod_SOURCES): Move from here ... * conf/mips-yeeloong.rmk (linux_mod_SOURCES): ... here * conf/mips.rmk (linux_mod_CFLAGS): Move from here ... * conf/mips-yeeloong.rmk (linux_mod_CFLAGS): ... here * conf/mips.rmk (linux_mod_ASFLAGS): Move from here ... * conf/mips-yeeloong.rmk (linux_mod_ASFLAGS): ... here * conf/mips.rmk (linux_mod_LDFLAGS): Move from here ... * conf/mips-yeeloong.rmk (linux_mod_LDFLAGS): ... here Reported by: BVK Chaitanya --- ChangeLog | 17 +++++++++++++++++ conf/mips-yeeloong.rmk | 5 +++++ conf/mips.rmk | 6 ------ 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index d3d939985..039a80a59 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2010-03-04 Vladimir Serbinenko + + Disable linux.mod on qemu-mips since it's not functional and leads + to compilation failure. + + * conf/mips.rmk (pkglib_MODULES): Remove linux.mod. + * conf/mips-yeeloong.rmk (pkglib_MODULES): Add linux.mod. + * conf/mips.rmk (linux_mod_SOURCES): Move from here ... + * conf/mips-yeeloong.rmk (linux_mod_SOURCES): ... here + * conf/mips.rmk (linux_mod_CFLAGS): Move from here ... + * conf/mips-yeeloong.rmk (linux_mod_CFLAGS): ... here + * conf/mips.rmk (linux_mod_ASFLAGS): Move from here ... + * conf/mips-yeeloong.rmk (linux_mod_ASFLAGS): ... here + * conf/mips.rmk (linux_mod_LDFLAGS): Move from here ... + * conf/mips-yeeloong.rmk (linux_mod_LDFLAGS): ... here + Reported by: BVK Chaitanya + 2010-03-04 Jordan Uggla * INSTALL: Add gettext as a dependency and add qemu to a new section diff --git a/conf/mips-yeeloong.rmk b/conf/mips-yeeloong.rmk index 0d9a4c1bb..9977f7881 100644 --- a/conf/mips-yeeloong.rmk +++ b/conf/mips-yeeloong.rmk @@ -76,6 +76,11 @@ datehook_mod_SOURCES = hook/datehook.c datehook_mod_CFLAGS = $(COMMON_CFLAGS) datehook_mod_LDFLAGS = $(COMMON_LDFLAGS) +pkglib_MODULES += linux.mod +linux_mod_SOURCES = loader/$(target_cpu)/linux.c +linux_mod_CFLAGS = $(COMMON_CFLAGS) +linux_mod_ASFLAGS = $(COMMON_ASFLAGS) +linux_mod_LDFLAGS = $(COMMON_LDFLAGS) sbin_SCRIPTS += grub-install grub_install_SOURCES = util/grub-install.in diff --git a/conf/mips.rmk b/conf/mips.rmk index c7c80a26d..536d35cac 100644 --- a/conf/mips.rmk +++ b/conf/mips.rmk @@ -73,10 +73,4 @@ relocator_mod_CFLAGS = $(COMMON_CFLAGS) relocator_mod_ASFLAGS = $(COMMON_ASFLAGS) relocator_mod_LDFLAGS = $(COMMON_LDFLAGS) -pkglib_MODULES += linux.mod -linux_mod_SOURCES = loader/$(target_cpu)/linux.c -linux_mod_CFLAGS = $(COMMON_CFLAGS) -linux_mod_ASFLAGS = $(COMMON_ASFLAGS) -linux_mod_LDFLAGS = $(COMMON_LDFLAGS) - include $(srcdir)/conf/common.mk From 41168ea49c613eec088ffb3dae7e301a86bce8b0 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 4 Mar 2010 21:30:58 +0100 Subject: [PATCH 457/738] 2010-03-04 Vladimir Serbinenko * normal/autofs.c (autoload_fs_module): Handle errors. --- ChangeLog | 4 ++++ normal/autofs.c | 3 +++ 2 files changed, 7 insertions(+) diff --git a/ChangeLog b/ChangeLog index 039a80a59..f72f71783 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-03-04 Vladimir Serbinenko + + * normal/autofs.c (autoload_fs_module): Handle errors. + 2010-03-04 Vladimir Serbinenko Disable linux.mod on qemu-mips since it's not functional and leads diff --git a/normal/autofs.c b/normal/autofs.c index 57e43fdf4..11b3fc1be 100644 --- a/normal/autofs.c +++ b/normal/autofs.c @@ -38,6 +38,9 @@ autoload_fs_module (void) if (! grub_dl_get (p->name) && grub_dl_load (p->name)) return 1; + if (grub_errno) + grub_print_error (); + fs_module_list = p->next; grub_free (p->name); grub_free (p); From d07803630846b2afda23b926bb28b0523fed8adc Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 4 Mar 2010 21:32:11 +0100 Subject: [PATCH 458/738] 2010-03-04 Vladimir Serbinenko * kern/main.c (grub_load_modules): Handle errors from init functions of embeded modules. --- ChangeLog | 5 +++++ kern/main.c | 3 +++ 2 files changed, 8 insertions(+) diff --git a/ChangeLog b/ChangeLog index f72f71783..f3a6a12f5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-03-04 Vladimir Serbinenko + + * kern/main.c (grub_load_modules): Handle errors from init functions of + embeded modules. + 2010-03-04 Vladimir Serbinenko * normal/autofs.c (autoload_fs_module): Handle errors. diff --git a/kern/main.c b/kern/main.c index 456105378..e7566fab9 100644 --- a/kern/main.c +++ b/kern/main.c @@ -68,6 +68,9 @@ grub_load_modules (void) (header->size - sizeof (struct grub_module_header)))) grub_fatal ("%s", grub_errmsg); + if (grub_errno) + grub_print_error (); + return 0; } From fcee14ed5fad3455597ac9672c48368b9e324b79 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 4 Mar 2010 21:35:36 +0100 Subject: [PATCH 459/738] 2010-03-04 Vladimir Serbinenko * NEWS: mention multiboot on EFI. --- ChangeLog | 4 ++++ NEWS | 2 ++ 2 files changed, 6 insertions(+) diff --git a/ChangeLog b/ChangeLog index f3a6a12f5..bb3637911 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-03-04 Vladimir Serbinenko + + * NEWS: mention multiboot on EFI. + 2010-03-04 Vladimir Serbinenko * kern/main.c (grub_load_modules): Handle errors from init functions of diff --git a/NEWS b/NEWS index 828eea081..66ac67904 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,7 @@ New in 1.98: +* Multiboot on EFI support. + * Graphical menu support. * MIPS support. From c7ef54aab162ffa2b8aeb27dd9885686f4c08432 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 4 Mar 2010 22:33:49 +0100 Subject: [PATCH 460/738] 2010-03-04 Vladimir Serbinenko * configure.ac: Alias amd64 to x86_64. --- ChangeLog | 4 ++++ configure.ac | 1 + 2 files changed, 5 insertions(+) diff --git a/ChangeLog b/ChangeLog index bb3637911..e5f1186a9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-03-04 Vladimir Serbinenko + + * configure.ac: Alias amd64 to x86_64. + 2010-03-04 Vladimir Serbinenko * NEWS: mention multiboot on EFI. diff --git a/configure.ac b/configure.ac index ac3f0d196..1f7d6125c 100644 --- a/configure.ac +++ b/configure.ac @@ -51,6 +51,7 @@ fi case "$target_cpu" in i[[3456]]86) target_cpu=i386 ;; + amd64) target_cpu=x86_64 ;; sparc) target_cpu=sparc64 ;; mipsel|mips64el) target_cpu=mips; From d116e0d8d1a8ac94ee8564e565f002f215452e0d Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Thu, 4 Mar 2010 23:16:34 +0100 Subject: [PATCH 461/738] 2010-03-04 Robert Millan Support relative image path in theme file. * gfxmenu/gui_image.c (grub_gui_image): New member theme_dir. (image_set_property): Handle theme_dir and relative path. --- ChangeLog | 7 +++++++ gfxmenu/gui_image.c | 25 +++++++++++++++++++++++-- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index e5f1186a9..ae4a19108 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-03-04 Robert Millan + + Support relative image path in theme file. + + * gfxmenu/gui_image.c (grub_gui_image): New member theme_dir. + (image_set_property): Handle theme_dir and relative path. + 2010-03-04 Vladimir Serbinenko * configure.ac: Alias amd64 to x86_64. diff --git a/gfxmenu/gui_image.c b/gfxmenu/gui_image.c index ef8bcbe9a..3988f4ba8 100644 --- a/gfxmenu/gui_image.c +++ b/gfxmenu/gui_image.c @@ -31,6 +31,7 @@ struct grub_gui_image grub_gui_container_t parent; grub_video_rect_t bounds; char *id; + char *theme_dir; struct grub_video_bitmap *raw_bitmap; struct grub_video_bitmap *bitmap; }; @@ -208,8 +209,28 @@ static grub_err_t image_set_property (void *vself, const char *name, const char *value) { grub_gui_image_t self = vself; - if (grub_strcmp (name, "file") == 0) - return load_image (self, value); + if (grub_strcmp (name, "theme_dir") == 0) + { + grub_free (self->theme_dir); + self->theme_dir = grub_strdup (value); + } + else if (grub_strcmp (name, "file") == 0) + { + char *absvalue; + grub_err_t err; + + /* Resolve to an absolute path. */ + if (! self->theme_dir) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "unspecified theme_dir"); + absvalue = grub_resolve_relative_path (self->theme_dir, value); + if (! absvalue) + return grub_errno; + + err = load_image (self, absvalue); + grub_free (absvalue); + + return err; + } else if (grub_strcmp (name, "id") == 0) { grub_free (self->id); From 3ab4bd77dd3cf74bbe9e304a0c43835cfc4be314 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 5 Mar 2010 15:29:28 +0100 Subject: [PATCH 462/738] 2010-03-04 Vladimir Serbinenko * disk/scsi.c (grub_scsi_iterate): Fix a memory leak. --- ChangeLog | 4 ++++ disk/scsi.c | 6 ++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index ae4a19108..db2c8855e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-03-04 Vladimir Serbinenko + + * disk/scsi.c (grub_scsi_iterate): Fix a memory leak. + 2010-03-04 Robert Millan Support relative image path in theme file. diff --git a/disk/scsi.c b/disk/scsi.c index 6f3233b29..eba237287 100644 --- a/disk/scsi.c +++ b/disk/scsi.c @@ -208,12 +208,14 @@ grub_scsi_iterate (int (*hook) (const char *name)) for (i = 0; i < luns; i++) { char *sname; + int ret; sname = grub_xasprintf ("%s%c", name, 'a' + i); if (!sname) return 1; - if (hook (sname)) - return 1; + ret = hook (sname); grub_free (sname); + if (ret) + return 1; } return 0; } From 48a5a769a2b7df4544a3883f4c57aaff72031db2 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 5 Mar 2010 15:30:44 +0100 Subject: [PATCH 463/738] 2010-03-04 Vladimir Serbinenko * gettext/gettext.c (grub_gettext_init_ext): Fix a memory leak. --- ChangeLog | 4 ++++ gettext/gettext.c | 7 ------- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index db2c8855e..df53d39ad 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-03-04 Vladimir Serbinenko + + * gettext/gettext.c (grub_gettext_init_ext): Fix a memory leak. + 2010-03-04 Vladimir Serbinenko * disk/scsi.c (grub_scsi_iterate): Fix a memory leak. diff --git a/gettext/gettext.c b/gettext/gettext.c index 9a1756be7..0aa8decbd 100644 --- a/gettext/gettext.c +++ b/gettext/gettext.c @@ -279,13 +279,6 @@ grub_gettext_init_ext (const char *lang) /* mo_file e.g.: /boot/grub/locale/ca.mo */ - mo_file = - grub_malloc (grub_strlen (locale_dir) + grub_strlen ("/") + - grub_strlen (lang) + grub_strlen (".mo") + 1); - - /* Warning: if changing some paths in the below line, change the grub_malloc - contents below. */ - mo_file = grub_xasprintf ("%s/%s.mo", locale_dir, lang); if (!mo_file) return; From 60b03859e891684f20c287197f9016231bafbd60 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 5 Mar 2010 15:38:04 +0100 Subject: [PATCH 464/738] 2010-03-05 Vladimir Serbinenko * util/import_gcry.py: Add autogenerated files to MAINTAINER_CLEANFILES. --- ChangeLog | 4 ++++ util/import_gcry.py | 2 ++ 2 files changed, 6 insertions(+) diff --git a/ChangeLog b/ChangeLog index df53d39ad..fa2f1ff05 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-03-05 Vladimir Serbinenko + + * util/import_gcry.py: Add autogenerated files to MAINTAINER_CLEANFILES. + 2010-03-04 Vladimir Serbinenko * gettext/gettext.c (grub_gettext_init_ext): Fix a memory leak. diff --git a/util/import_gcry.py b/util/import_gcry.py index d71924d53..b9c3edcde 100644 --- a/util/import_gcry.py +++ b/util/import_gcry.py @@ -62,6 +62,7 @@ mdblocksizes = {"_gcry_digest_spec_crc32" : 64, "_gcry_digest_spec_whirlpool" : 64} cryptolist = open (os.path.join (cipher_dir_out, "crypto.lst"), "w") +conf.write ("MAINTAINER_CLEANFILES += $(srcdir)/conf/gcry.rmk $(srcdir)/lib/libgcrypt-grub/cipher/ChangeLog $(srcdir)/lib/libgcrypt-grub/cipher/cipher.h $(srcdir)/lib/libgcrypt-grub/cipher/crypto.lst $(srcdir)/lib/libgcrypt-grub/cipher/g10lib.h $(srcdir)/lib/libgcrypt-grub/cipher/memory.h $(srcdir)/lib/libgcrypt-grub/cipher/types.h\n"); # rijndael is the only cipher using aliases. So no need for mangling, just # hardcode it @@ -87,6 +88,7 @@ for cipher_file in cipher_files: continue nch = False if re.match (".*\.[ch]$", cipher_file): + conf.write ("MAINTAINER_CLEANFILES += $(srcdir)/lib/libgcrypt-grub/cipher/" + cipher_file + "\n"); isc = re.match (".*\.c$", cipher_file) f = open (infile, "r") fw = open (outfile, "w") From 8f9a632b96321457a61c03ddff1faf2a373d52bc Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 6 Mar 2010 17:22:04 +0100 Subject: [PATCH 465/738] 2010-03-05 Vladimir Serbinenko Fix FreeBSD compilation. * Makefile.in (TARGET_CPPFLAGS): Remove -nostdinc -isystem. * configure.ac: Add -nostdinc -isystem to TARGET_CPPFLAGS if it works. --- ChangeLog | 7 +++++++ Makefile.in | 2 +- configure.ac | 13 +++++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index fa2f1ff05..c9356b222 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-03-05 Vladimir Serbinenko + + Fix FreeBSD compilation. + + * Makefile.in (TARGET_CPPFLAGS): Remove -nostdinc -isystem. + * configure.ac: Add -nostdinc -isystem to TARGET_CPPFLAGS if it works. + 2010-03-05 Vladimir Serbinenko * util/import_gcry.py: Add autogenerated files to MAINTAINER_CLEANFILES. diff --git a/Makefile.in b/Makefile.in index 4144dfb5a..47584cdde 100644 --- a/Makefile.in +++ b/Makefile.in @@ -89,7 +89,7 @@ TARGET_ASFLAGS = @TARGET_ASFLAGS@ TARGET_MODULE_FORMAT = @TARGET_MODULE_FORMAT@ TARGET_APPLE_CC = @TARGET_APPLE_CC@ OBJCONV = @OBJCONV@ -TARGET_CPPFLAGS = @TARGET_CPPFLAGS@ -nostdinc -isystem $(shell $(TARGET_CC) -print-file-name=include) -I$(srcdir)/include -I$(builddir) -I$(builddir)/include \ +TARGET_CPPFLAGS = @TARGET_CPPFLAGS@ -I$(srcdir)/include -I$(builddir) -I$(builddir)/include \ -Wall -W TARGET_LDFLAGS = @TARGET_LDFLAGS@ TARGET_IMG_LDSCRIPT = @TARGET_IMG_LDSCRIPT@ diff --git a/configure.ac b/configure.ac index 1f7d6125c..cf43608d1 100644 --- a/configure.ac +++ b/configure.ac @@ -517,6 +517,19 @@ enable_efiemu=no fi AC_SUBST([enable_efiemu]) +AC_CACHE_CHECK([whether -nostdinc -isystem works], [grub_cv_cc_isystem], [ + SAVED_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$TARGET_CPPFLAGS -nostdinc -isystem `$TARGET_CC -print-file-name=include`" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include +int va_arg_func (int fixed, va_list args);]], [[]])], + [grub_cv_cc_isystem=yes], + [grub_cv_cc_isystem=no]) + CPPFLAGS="$SAVED_CPPFLAGS" +]) + +if test x"$grub_cv_cc_isystem" = xyes ; then + TARGET_CPPFLAGS="$TARGET_CPPFLAGS -nostdinc -isystem `$TARGET_CC -print-file-name=include`" +fi # Restore the flags. CC="$tmp_CC" From 2ac227c7f4262618bddc7f3e1a8bbf347bb48af6 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 6 Mar 2010 17:25:40 +0100 Subject: [PATCH 466/738] 2010-03-06 Vladimir Serbinenko * loader/i386/multiboot_mbi.c (grub_multiboot_set_bootdev): Free the right pointer. --- ChangeLog | 5 +++++ loader/i386/multiboot_mbi.c | 6 +++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index c9356b222..a7717dfae 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-03-06 Vladimir Serbinenko + + * loader/i386/multiboot_mbi.c (grub_multiboot_set_bootdev): Free the + right pointer. + 2010-03-05 Vladimir Serbinenko Fix FreeBSD compilation. diff --git a/loader/i386/multiboot_mbi.c b/loader/i386/multiboot_mbi.c index 3f937c446..6391564d6 100644 --- a/loader/i386/multiboot_mbi.c +++ b/loader/i386/multiboot_mbi.c @@ -448,8 +448,8 @@ grub_multiboot_set_bootdev (void) dev = grub_device_open (0); if (dev && dev->disk && dev->disk->partition) { - - p = dev->disk->partition->partmap->get_name (dev->disk->partition); + char *p0; + p = p0 = dev->disk->partition->partmap->get_name (dev->disk->partition); if (p) { if ((p[0] >= '0') && (p[0] <= '9')) @@ -463,7 +463,7 @@ grub_multiboot_set_bootdev (void) if ((p[0] >= 'a') && (p[0] <= 'z')) part = p[0] - 'a'; } - grub_free (p); + grub_free (p0); } if (dev) grub_device_close (dev); From b1f6d291adc857f385ff7b6d33547cc4e3fad119 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 6 Mar 2010 17:27:28 +0100 Subject: [PATCH 467/738] 2010-03-06 Vladimir Serbinenko * loader/i386/bsd.c (grub_bsd_get_device): Fix a memory leak. --- ChangeLog | 4 ++++ loader/i386/bsd.c | 5 +++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index a7717dfae..f444fe349 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-03-06 Vladimir Serbinenko + + * loader/i386/bsd.c (grub_bsd_get_device): Fix a memory leak. + 2010-03-06 Vladimir Serbinenko * loader/i386/multiboot_mbi.c (grub_multiboot_set_bootdev): Free the diff --git a/loader/i386/bsd.c b/loader/i386/bsd.c index 3dd3c70c5..949de408d 100644 --- a/loader/i386/bsd.c +++ b/loader/i386/bsd.c @@ -154,8 +154,8 @@ grub_bsd_get_device (grub_uint32_t * biosdev, dev = grub_device_open (0); if (dev && dev->disk && dev->disk->partition) { - - p = dev->disk->partition->partmap->get_name (dev->disk->partition); + char *p0; + p0 = p = dev->disk->partition->partmap->get_name (dev->disk->partition); if (p) { if ((p[0] >= '0') && (p[0] <= '9')) @@ -169,6 +169,7 @@ grub_bsd_get_device (grub_uint32_t * biosdev, if ((p[0] >= 'a') && (p[0] <= 'z')) *part = p[0] - 'a'; } + grub_free (p0); } if (dev) grub_device_close (dev); From 33e2e6f3735eca22021165c5f556b4d8aaafa0bf Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 6 Mar 2010 17:28:25 +0100 Subject: [PATCH 468/738] 2010-03-06 Vladimir Serbinenko * util/grub-mkrescue.in: Use mktemp with explicit template. --- ChangeLog | 4 ++++ util/grub-mkrescue.in | 18 +++++++++++++----- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index f444fe349..f42395304 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-03-06 Vladimir Serbinenko + + * util/grub-mkrescue.in: Use mktemp with explicit template. + 2010-03-06 Vladimir Serbinenko * loader/i386/bsd.c (grub_bsd_get_device): Fix a memory leak. diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in index 6b3c9ecb8..592cf2df6 100644 --- a/util/grub-mkrescue.in +++ b/util/grub-mkrescue.in @@ -86,7 +86,15 @@ if [ "x${output_image}" = x ] ; then exit 1 fi -iso9660_dir=`mktemp -d` +if test "x$TMP" != x; then + MKTEMP_TEMPLATE="$TMP/grub-mkrescue.XXXXXXXXXX" +elif test "x$TEMP" != x; then + MKTEMP_TEMPLATE="$TEMP/grub-mkrescue.XXXXXXXXXX" +else + MKTEMP_TEMPLATE="/tmp/grub-mkrescue.XXXXXXXXXX" +fi + +iso9660_dir=`mktemp -d "$MKTEMP_TEMPLATE"` mkdir -p ${iso9660_dir}/boot/grub process_input_dir () @@ -133,8 +141,8 @@ fi # build coreboot core.img if test -e "${coreboot_dir}" ; then echo "Enabling coreboot support ..." - memdisk_img=`mktemp` - memdisk_dir=`mktemp -d` + memdisk_img=`mktemp "$MKTEMP_TEMPLATE"` + memdisk_dir=`mktemp -d "$MKTEMP_TEMPLATE"` mkdir -p ${memdisk_dir}/boot/grub # obtain date-based UUID iso_uuid=$(date +%Y-%m-%d-%H-%M-%S-00) @@ -162,12 +170,12 @@ fi # build BIOS core.img if test -e "${pc_dir}" ; then echo "Enabling BIOS support ..." - core_img=`mktemp` + core_img=`mktemp "$MKTEMP_TEMPLATE"` grub-mkimage -d ${pc_dir}/ -o ${core_img} --prefix=/boot/grub/i386-pc \ iso9660 biosdisk cat ${pc_dir}/cdboot.img ${core_img} > ${iso9660_dir}/boot/grub/i386-pc/eltorito.img - embed_img=`mktemp` + embed_img=`mktemp "$MKTEMP_TEMPLATE"` cat ${pc_dir}/boot.img ${core_img} > ${embed_img} rm -f ${core_img} From 696fd607c61b87309c0911744d266ef74514e6d9 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 6 Mar 2010 17:48:15 +0100 Subject: [PATCH 469/738] 2010-03-06 Vladimir Serbinenko * normal/cmdline.c (grub_cmdline_get): Fix gabled line after completition in the middle of string. --- ChangeLog | 5 +++++ normal/cmdline.c | 5 +++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index f42395304..4792506a9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-03-06 Vladimir Serbinenko + + * normal/cmdline.c (grub_cmdline_get): Fix gabled line after + completition in the middle of string. + 2010-03-06 Vladimir Serbinenko * util/grub-mkrescue.in: Use mktemp with explicit template. diff --git a/normal/cmdline.c b/normal/cmdline.c index f63953944..05d665411 100644 --- a/normal/cmdline.c +++ b/normal/cmdline.c @@ -303,8 +303,9 @@ grub_cmdline_get (const char *prompt) grub_memmove (buf + lpos, str, len * sizeof (grub_uint32_t)); llen += len; + cl_set_pos_all (); + cl_print_all (lpos, 0); lpos += len; - cl_print_all (lpos - len, 0); cl_set_pos_all (); } } @@ -473,7 +474,6 @@ grub_cmdline_get (const char *prompt) if (t != 1) cl_insert (insert); lpos++; - cl_set_pos_all (); } else { @@ -485,6 +485,7 @@ grub_cmdline_get (const char *prompt) grub_free (insertu8); grub_free (insert); } + cl_set_pos_all (); } break; From d1e8a02f11bdbd11b9e69c5e7b66ed5671b60125 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 6 Mar 2010 21:27:04 +0100 Subject: [PATCH 470/738] 2010-03-06 Vladimir Serbinenko * configure.ac: Update CPPFLAGS and not CFLAGS when checking for ft2build.h. --- ChangeLog | 5 +++++ configure.ac | 6 +++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4792506a9..33e87f310 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-03-06 Vladimir Serbinenko + + * configure.ac: Update CPPFLAGS and not CFLAGS when checking for + ft2build.h. + 2010-03-06 Vladimir Serbinenko * normal/cmdline.c (grub_cmdline_get): Fix gabled line after diff --git a/configure.ac b/configure.ac index cf43608d1..6deac6c6d 100644 --- a/configure.ac +++ b/configure.ac @@ -696,11 +696,11 @@ fi if test x"$grub_mkfont_excuse" = x ; then # Check for freetype libraries. - SAVED_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $freetype_cflags" + SAVED_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $freetype_cflags" AC_CHECK_HEADERS([ft2build.h], [], [grub_mkfont_excuse=["need freetype2 headers"]]) - CFLAGS="$SAVED_CFLAGS" + CPPFLAGS="$SAVED_CPPFLAGS" fi if test x"$enable_grub_mkfont" = xyes && test x"$grub_mkfont_excuse" != x ; then From fce5d8ff62d3deb264ba5916b62df69998caf916 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 6 Mar 2010 21:49:59 +0100 Subject: [PATCH 471/738] 2010-03-06 Vladimir Serbinenko * NEWS: Put the date of 1.98 release. --- ChangeLog | 4 ++++ NEWS | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 33e87f310..56f19acde 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-03-06 Vladimir Serbinenko + + * NEWS: Put the date of 1.98 release. + 2010-03-06 Vladimir Serbinenko * configure.ac: Update CPPFLAGS and not CFLAGS when checking for diff --git a/NEWS b/NEWS index 66ac67904..1e3334f18 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,4 @@ -New in 1.98: +New in 1.98 - 2010-03-06: * Multiboot on EFI support. From 8eb567e6629c892428c1a563afb6aa40d1a74f64 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 7 Mar 2010 14:59:15 +0100 Subject: [PATCH 472/738] Update with newest mbtag spec --- include/grub/multiboot.h | 2 +- include/multiboot2.h | 33 ++++++++++++++- loader/i386/multiboot.c | 4 +- loader/i386/multiboot_mbi.c | 6 ++- loader/i386/multiboot_mbi2.c | 78 +++++++++++++++++++----------------- 5 files changed, 81 insertions(+), 42 deletions(-) diff --git a/include/grub/multiboot.h b/include/grub/multiboot.h index 27d4d816d..c108e5eef 100644 --- a/include/grub/multiboot.h +++ b/include/grub/multiboot.h @@ -44,7 +44,7 @@ grub_err_t grub_multiboot_add_module (grub_addr_t start, grub_size_t size, int argc, char *argv[]); void grub_multiboot_set_bootdev (void); -grub_uint32_t grub_get_multiboot_mmap_len (void); +grub_uint32_t grub_get_multiboot_mmap_count (void); grub_err_t grub_multiboot_set_video_mode (void); #if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_QEMU) diff --git a/include/multiboot2.h b/include/multiboot2.h index 20c5c5696..36710ddf6 100644 --- a/include/multiboot2.h +++ b/include/multiboot2.h @@ -51,6 +51,7 @@ /* This flag indicates the use of the address fields in the header. */ #define MULTIBOOT_AOUT_KLUDGE 0x00010000 +#define MULTIBOOT_TAG_ALIGN 8 #define MULTIBOOT_TAG_TYPE_END 0 #define MULTIBOOT_TAG_TYPE_CMDLINE 1 #define MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME 2 @@ -102,7 +103,6 @@ struct multiboot_color struct multiboot_mmap_entry { - multiboot_uint32_t size; multiboot_uint64_t addr; multiboot_uint64_t len; #define MULTIBOOT_MEMORY_AVAILABLE 1 @@ -110,6 +110,7 @@ struct multiboot_mmap_entry #define MULTIBOOT_MEMORY_ACPI_RECLAIMABLE 3 #define MULTIBOOT_MEMORY_NVS 4 multiboot_uint32_t type; + multiboot_uint32_t zero; } __attribute__((packed)); typedef struct multiboot_mmap_entry multiboot_memory_map_t; @@ -123,6 +124,8 @@ struct multiboot_tag_string { multiboot_uint32_t type; multiboot_uint32_t size; + multiboot_uint32_t entry_size; + multiboot_uint32_t entry_version; char string[0]; }; @@ -156,6 +159,8 @@ struct multiboot_tag_mmap { multiboot_uint32_t type; multiboot_uint32_t size; + multiboot_uint32_t entry_size; + multiboot_uint32_t entry_version; struct multiboot_mmap_entry entries[0]; }; @@ -197,6 +202,7 @@ struct multiboot_tag_framebuffer_common #define MULTIBOOT_FRAMEBUFFER_TYPE_RGB 1 #define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT 2 multiboot_uint8_t framebuffer_type; + multiboot_uint16_t reserved; }; struct multiboot_tag_framebuffer @@ -222,6 +228,31 @@ struct multiboot_tag_framebuffer }; }; +struct multiboot_tag_elf_sections +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t num; + multiboot_uint32_t entsize; + multiboot_uint32_t shndx; + char sections[0]; +}; + +struct multiboot_tag_apm +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint16_t version; + multiboot_uint16_t cseg; + multiboot_uint32_t offset; + multiboot_uint16_t cseg_16; + multiboot_uint16_t dseg; + multiboot_uint16_t flags; + multiboot_uint16_t cseg_len; + multiboot_uint16_t cseg_16_len; + multiboot_uint16_t dseg_len; +}; + #endif /* ! ASM_FILE */ #endif /* ! MULTIBOOT_HEADER */ diff --git a/loader/i386/multiboot.c b/loader/i386/multiboot.c index 5f9751f33..dab81dc8c 100644 --- a/loader/i386/multiboot.c +++ b/loader/i386/multiboot.c @@ -68,7 +68,7 @@ static int accepts_video; /* Return the length of the Multiboot mmap that will be needed to allocate our platform's map. */ grub_uint32_t -grub_get_multiboot_mmap_len (void) +grub_get_multiboot_mmap_count (void) { grub_size_t count = 0; @@ -83,7 +83,7 @@ grub_get_multiboot_mmap_len (void) grub_mmap_iterate (hook); - return count * sizeof (struct multiboot_mmap_entry); + return count; } grub_err_t diff --git a/loader/i386/multiboot_mbi.c b/loader/i386/multiboot_mbi.c index a8133a705..0d5db3c13 100644 --- a/loader/i386/multiboot_mbi.c +++ b/loader/i386/multiboot_mbi.c @@ -53,7 +53,8 @@ grub_multiboot_get_mbi_size (void) { return sizeof (struct multiboot_info) + ALIGN_UP (cmdline_size, 4) + modcnt * sizeof (struct multiboot_mod_list) + total_modcmd - + ALIGN_UP (sizeof(PACKAGE_STRING), 4) + grub_get_multiboot_mmap_len () + + ALIGN_UP (sizeof(PACKAGE_STRING), 4) + + grub_get_multiboot_mmap_count () * sizeof (struct multiboot_mmap_entry) #if GRUB_MACHINE_HAS_VBE + sizeof (struct grub_vbe_info_block) + sizeof (struct grub_vbe_mode_info_block) @@ -233,7 +234,8 @@ grub_multiboot_make_mbi (void *orig, grub_uint32_t dest, grub_off_t buf_off, mbi->mods_count = 0; } - mmap_size = grub_get_multiboot_mmap_len (); + mmap_size = grub_get_multiboot_mmap_count () + * sizeof (struct multiboot_mmap_entry); grub_fill_multiboot_mmap ((struct multiboot_mmap_entry *) ptrorig); mbi->mmap_length = mmap_size; mbi->mmap_addr = ptrdest; diff --git a/loader/i386/multiboot_mbi2.c b/loader/i386/multiboot_mbi2.c index a53bbe50a..ab803734f 100644 --- a/loader/i386/multiboot_mbi2.c +++ b/loader/i386/multiboot_mbi2.c @@ -62,15 +62,17 @@ static grub_uint32_t biosdev, slice, part; grub_size_t grub_multiboot_get_mbi_size (void) { - return sizeof (grub_uint32_t) + sizeof (struct multiboot_tag) - + (sizeof (struct multiboot_tag_string) + ALIGN_UP (cmdline_size, 4)) + return 2 * sizeof (grub_uint32_t) + sizeof (struct multiboot_tag) + (sizeof (struct multiboot_tag_string) - + ALIGN_UP (sizeof (PACKAGE_STRING), 4)) + + ALIGN_UP (cmdline_size, MULTIBOOT_TAG_ALIGN)) + + (sizeof (struct multiboot_tag_string) + + ALIGN_UP (sizeof (PACKAGE_STRING), MULTIBOOT_TAG_ALIGN)) + (modcnt * sizeof (struct multiboot_tag_module) + total_modcmd) + sizeof (struct multiboot_tag_basic_meminfo) - + sizeof (struct multiboot_tag_bootdev) - + (sizeof (struct multiboot_tag_mmap) + grub_get_multiboot_mmap_len ()) - + sizeof (struct multiboot_tag_vbe); + + ALIGN_UP (sizeof (struct multiboot_tag_bootdev), MULTIBOOT_TAG_ALIGN) + + (sizeof (struct multiboot_tag_mmap) + grub_get_multiboot_mmap_count () + * sizeof (struct multiboot_mmap_entry)) + + sizeof (struct multiboot_tag_vbe) + MULTIBOOT_TAG_ALIGN - 1; } #ifdef GRUB_MACHINE_HAS_VBE @@ -98,7 +100,7 @@ fill_vbe_info (struct grub_vbe_mode_info_block **vbe_mode_info_out, *vbe_mode_info_out = (struct grub_vbe_mode_info_block *) &(tag->vbe_mode_info); tag->size = sizeof (struct multiboot_tag_vbe); - *ptrorig += tag->size; + *ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN); return GRUB_ERR_NONE; } @@ -106,9 +108,9 @@ fill_vbe_info (struct grub_vbe_mode_info_block **vbe_mode_info_out, /* Fill previously allocated Multiboot mmap. */ static void -grub_fill_multiboot_mmap (struct multiboot_mmap_entry *first_entry) +grub_fill_multiboot_mmap (struct multiboot_tag_mmap *tag) { - struct multiboot_mmap_entry *mmap_entry = (struct multiboot_mmap_entry *) first_entry; + struct multiboot_mmap_entry *mmap_entry = tag->entries; auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t); int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, grub_uint32_t type) @@ -137,12 +139,17 @@ grub_fill_multiboot_mmap (struct multiboot_mmap_entry *first_entry) mmap_entry->type = MULTIBOOT_MEMORY_RESERVED; break; } - mmap_entry->size = sizeof (struct multiboot_mmap_entry) - sizeof (mmap_entry->size); mmap_entry++; return 0; } + tag->type = MULTIBOOT_TAG_TYPE_MMAP; + tag->size = sizeof (struct multiboot_tag_mmap) + + sizeof (struct multiboot_mmap_entry) * grub_get_multiboot_mmap_count (); + tag->entry_size = sizeof (struct multiboot_mmap_entry); + tag->entry_version = 0; + grub_mmap_iterate (hook); } @@ -190,7 +197,8 @@ retrieve_video_parameters (grub_uint8_t **ptrorig) tag->common.framebuffer_type = MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT; tag->common.size = sizeof (tag->common); - *ptrorig += tag->common.size; + tag->common.reserved = 0; + *ptrorig += ALIGN_UP (tag->common.size, MULTIBOOT_TAG_ALIGN); } return GRUB_ERR_NONE; } @@ -214,6 +222,8 @@ retrieve_video_parameters (grub_uint8_t **ptrorig) tag->common.framebuffer_height = mode_info.height; tag->common.framebuffer_bpp = mode_info.bpp; + + tag->common.reserved = 0; if (mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) { @@ -231,7 +241,6 @@ retrieve_video_parameters (grub_uint8_t **ptrorig) tag->framebuffer_palette[i].green = palette[i].g; tag->framebuffer_palette[i].blue = palette[i].b; } - *ptrorig += tag->common.size; } else { @@ -246,6 +255,7 @@ retrieve_video_parameters (grub_uint8_t **ptrorig) tag->common.size = sizeof (struct multiboot_tag_framebuffer_common) + 6; } + *ptrorig += ALIGN_UP (tag->common.size, MULTIBOOT_TAG_ALIGN); #if HAS_VBE if (driv_id == GRUB_VIDEO_DRIVER_VBE) @@ -264,30 +274,29 @@ grub_multiboot_make_mbi (void *orig, grub_uint32_t dest, grub_off_t buf_off, grub_size_t bufsize) { grub_uint8_t *ptrorig; - grub_uint8_t *mbistart = (grub_uint8_t *) orig + buf_off; + grub_uint8_t *mbistart = (grub_uint8_t *) orig + buf_off + + (ALIGN_UP (dest + buf_off, MULTIBOOT_TAG_ALIGN) - (dest + buf_off)); grub_err_t err; if (bufsize < grub_multiboot_get_mbi_size ()) return grub_error (GRUB_ERR_OUT_OF_MEMORY, "mbi buffer is too small"); - ptrorig = (grub_uint8_t *) orig + buf_off + sizeof (grub_uint32_t); + ptrorig = mbistart + 2 * sizeof (grub_uint32_t); { struct multiboot_tag_string *tag = (struct multiboot_tag_string *) ptrorig; tag->type = MULTIBOOT_TAG_TYPE_CMDLINE; - tag->size = sizeof (struct multiboot_tag_string) - + ALIGN_UP (cmdline_size, 4); + tag->size = sizeof (struct multiboot_tag_string) + cmdline_size; grub_memcpy (tag->string, cmdline, cmdline_size); - ptrorig += tag->size; + ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN); } { struct multiboot_tag_string *tag = (struct multiboot_tag_string *) ptrorig; tag->type = MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME; - tag->size = sizeof (struct multiboot_tag_string) - + ALIGN_UP (sizeof (PACKAGE_STRING), 4); + tag->size = sizeof (struct multiboot_tag_string) + sizeof (PACKAGE_STRING); grub_memcpy (tag->string, PACKAGE_STRING, sizeof (PACKAGE_STRING)); - ptrorig += tag->size; + ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN); } { @@ -299,23 +308,18 @@ grub_multiboot_make_mbi (void *orig, grub_uint32_t dest, grub_off_t buf_off, struct multiboot_tag_module *tag = (struct multiboot_tag_module *) ptrorig; tag->type = MULTIBOOT_TAG_TYPE_MODULE; - tag->size = sizeof (struct multiboot_tag_module) - + ALIGN_UP (sizeof (cur->cmdline_size), 4); - + tag->size = sizeof (struct multiboot_tag_module) + cur->cmdline_size; tag->mod_start = dest + cur->start; tag->mod_end = tag->mod_start + cur->size; grub_memcpy (tag->cmdline, cur->cmdline, cur->cmdline_size); - ptrorig += tag->size; + ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN); } } { struct multiboot_tag_mmap *tag = (struct multiboot_tag_mmap *) ptrorig; - tag->type = MULTIBOOT_TAG_TYPE_MMAP; - tag->size = sizeof (struct multiboot_tag_mmap) - + grub_get_multiboot_mmap_len (); - grub_fill_multiboot_mmap (tag->entries); - ptrorig += tag->size; + grub_fill_multiboot_mmap (tag); + ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN); } { @@ -327,7 +331,7 @@ grub_multiboot_make_mbi (void *orig, grub_uint32_t dest, grub_off_t buf_off, /* Convert from bytes to kilobytes. */ tag->mem_lower = grub_mmap_get_lower () / 1024; tag->mem_upper = grub_mmap_get_upper () / 1024; - ptrorig += tag->size; + ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN); } if (bootdev_set) @@ -340,7 +344,7 @@ grub_multiboot_make_mbi (void *orig, grub_uint32_t dest, grub_off_t buf_off, tag->biosdev = biosdev; tag->slice = slice; tag->part = part; - ptrorig += tag->size; + ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN); } { @@ -356,10 +360,11 @@ grub_multiboot_make_mbi (void *orig, grub_uint32_t dest, grub_off_t buf_off, struct multiboot_tag *tag = (struct multiboot_tag *) ptrorig; tag->type = MULTIBOOT_TAG_TYPE_END; tag->size = sizeof (struct multiboot_tag); - ptrorig += tag->size; + ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN); } - *(grub_uint32_t *) mbistart = ptrorig - mbistart; + ((grub_uint32_t *) mbistart)[0] = ptrorig - mbistart; + ((grub_uint32_t *) mbistart)[1] = 0; return GRUB_ERR_NONE; } @@ -447,7 +452,7 @@ grub_multiboot_add_module (grub_addr_t start, grub_size_t size, return grub_errno; } newmod->cmdline_size = len; - total_modcmd += ALIGN_UP (len, 4); + total_modcmd += ALIGN_UP (len, MULTIBOOT_TAG_ALIGN); for (i = 0; i < argc; i++) { @@ -495,8 +500,8 @@ grub_multiboot_set_bootdev (void) dev = grub_device_open (0); if (dev && dev->disk && dev->disk->partition) { - - p = dev->disk->partition->partmap->get_name (dev->disk->partition); + char *p0; + p = p0 = dev->disk->partition->partmap->get_name (dev->disk->partition); if (p) { if ((p[0] >= '0') && (p[0] <= '9')) @@ -510,6 +515,7 @@ grub_multiboot_set_bootdev (void) if ((p[0] >= 'a') && (p[0] <= 'z')) part = p[0] - 'a'; } + grub_free (p0); } if (dev) grub_device_close (dev); From 1f15fc1e0a37ec338d37ff4ef361a81514098f6a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 7 Mar 2010 23:02:13 +0100 Subject: [PATCH 473/738] 2010-03-07 Vladimir Serbinenko * genmoddep.awk: Output all missing symbols and not only first. --- ChangeLog | 4 ++++ genmoddep.awk | 3 +-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 56f19acde..667ff0c1e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-03-07 Vladimir Serbinenko + + * genmoddep.awk: Output all missing symbols and not only first. + 2010-03-06 Vladimir Serbinenko * NEWS: Put the date of 1.98 release. diff --git a/genmoddep.awk b/genmoddep.awk index 19ac80c71..48419a091 100644 --- a/genmoddep.awk +++ b/genmoddep.awk @@ -32,13 +32,12 @@ FNR == 1 { else if ($1 != "__gnu_local_gp") { printf "%s in %s is not defined\n", $1, module >"/dev/stderr"; error++; - exit; } } # Output the result. END { - if (error == 1) + if (error >= 1) exit 1; for (mod in modtab) { From b1f6f35ae91d6ee413b8d319e73b7be172a56491 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 8 Mar 2010 15:40:57 +0100 Subject: [PATCH 474/738] Preparation for mbh tag --- conf/i386.rmk | 6 +- include/grub/multiboot.h | 16 +++ include/multiboot.h | 1 + include/multiboot2.h | 78 ++++++++++- loader/i386/multiboot.c | 236 ++++++++++++++-------------------- loader/i386/multiboot_elfxx.c | 5 +- loader/i386/multiboot_mbi.c | 131 +++++++++++++++++++ loader/multiboot_loader.c | 150 --------------------- 8 files changed, 318 insertions(+), 305 deletions(-) delete mode 100644 loader/multiboot_loader.c diff --git a/conf/i386.rmk b/conf/i386.rmk index e5bd27265..076da3bb2 100644 --- a/conf/i386.rmk +++ b/conf/i386.rmk @@ -34,16 +34,14 @@ setpci_mod_LDFLAGS = $(COMMON_LDFLAGS) pkglib_MODULES += multiboot.mod multiboot_mod_SOURCES = loader/i386/multiboot.c \ - loader/i386/multiboot_mbi.c \ - loader/multiboot_loader.c + loader/i386/multiboot_mbi.c multiboot_mod_CFLAGS = $(COMMON_CFLAGS) multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS) multiboot_mod_ASFLAGS = $(COMMON_ASFLAGS) pkglib_MODULES += multiboot2.mod multiboot2_mod_SOURCES = loader/i386/multiboot.c \ - loader/i386/multiboot_mbi2.c \ - loader/multiboot_loader.c + loader/i386/multiboot_mbi2.c multiboot2_mod_CFLAGS = $(COMMON_CFLAGS) -DGRUB_USE_MULTIBOOT2 multiboot2_mod_LDFLAGS = $(COMMON_LDFLAGS) multiboot2_mod_ASFLAGS = $(COMMON_ASFLAGS) diff --git a/include/grub/multiboot.h b/include/grub/multiboot.h index c108e5eef..89efbc6dd 100644 --- a/include/grub/multiboot.h +++ b/include/grub/multiboot.h @@ -20,6 +20,8 @@ #ifndef GRUB_MULTIBOOT_HEADER #define GRUB_MULTIBOOT_HEADER 1 +#include + #ifdef GRUB_USE_MULTIBOOT2 #include /* Same thing as far as our loader is concerned. */ @@ -63,4 +65,18 @@ grub_multiboot_fill_vbe_info_real (struct grub_vbe_info_block *vbe_control_info, #define GRUB_MACHINE_HAS_VGA_TEXT 0 #endif +#define GRUB_MULTIBOOT_CONSOLE_EGA_TEXT 1 +#define GRUB_MULTIBOOT_CONSOLE_FRAMEBUFFER 2 + +grub_err_t +grub_multiboot_set_console (int console_type, int accepted_consoles, + int width, int height, int depth); +grub_err_t +grub_multiboot_load (grub_file_t file); +/* Load ELF32 or ELF64. */ +grub_err_t +grub_multiboot_load_elf (grub_file_t file, void *buffer); +extern grub_size_t grub_multiboot_pure_size; +extern grub_size_t grub_multiboot_alloc_mbi; + #endif /* ! GRUB_MULTIBOOT_HEADER */ diff --git a/include/multiboot.h b/include/multiboot.h index c529c5c5f..fda863e85 100644 --- a/include/multiboot.h +++ b/include/multiboot.h @@ -24,6 +24,7 @@ /* How many bytes from the start of the file we search for the header. */ #define MULTIBOOT_SEARCH 8192 +#define MULTIBOOT_HEADER_ALIGN 4 /* The magic field should contain this. */ #define MULTIBOOT_HEADER_MAGIC 0x1BADB002 diff --git a/include/multiboot2.h b/include/multiboot2.h index 36710ddf6..dae05a7a3 100644 --- a/include/multiboot2.h +++ b/include/multiboot2.h @@ -23,7 +23,8 @@ #define MULTIBOOT_HEADER 1 /* How many bytes from the start of the file we search for the header. */ -#define MULTIBOOT_SEARCH 8192 +#define MULTIBOOT_SEARCH 32768 +#define MULTIBOOT_HEADER_ALIGN 8 /* The magic field should contain this. */ #define MULTIBOOT2_HEADER_MAGIC 0xe85250d6 @@ -62,6 +63,17 @@ #define MULTIBOOT_TAG_TYPE_VBE 7 #define MULTIBOOT_TAG_TYPE_FRAMEBUFFER 8 +#define MULTIBOOT_HEADER_TAG_END 0 +#define MULTIBOOT_HEADER_TAG_INFORMATION_REQUEST 1 +#define MULTIBOOT_HEADER_TAG_ADDRESS 2 +#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS 3 +#define MULTIBOOT_HEADER_TAG_CONSOLE_FLAGS 4 +#define MULTIBOOT_HEADER_TAG_FRAMEBUFFER 5 +#define MULTIBOOT_HEADER_TAG_MODULE_ALIGN 6 + +#define GRUB_MULTIBOOT_ARCHITECTURE_I386 0 +#define MULTIBOOT_HEADER_TAG_OPTIONAL 1 + #ifndef ASM_FILE typedef unsigned char multiboot_uint8_t; @@ -74,21 +86,73 @@ struct multiboot_header /* Must be MULTIBOOT_MAGIC - see above. */ multiboot_uint32_t magic; - /* Feature flags. */ - multiboot_uint32_t flags; + /* ISA */ + multiboot_uint32_t architecture; + + /* Total header length. */ + multiboot_uint32_t header_length; /* The above fields plus this one must equal 0 mod 2^32. */ multiboot_uint32_t checksum; +}; - /* These are only valid if MULTIBOOT_AOUT_KLUDGE is set. */ +struct multiboot_header_tag +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t flags; +}; + +struct multiboot_header_tag_information_request +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t flags; + multiboot_uint32_t requests[0]; +}; + +struct multiboot_header_tag_address +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t flags; multiboot_uint32_t header_addr; multiboot_uint32_t load_addr; multiboot_uint32_t load_end_addr; multiboot_uint32_t bss_end_addr; - multiboot_uint32_t entry_addr; +}; - /* These are only valid if MULTIBOOT_VIDEO_MODE is set. */ - multiboot_uint32_t mode_type; +struct multiboot_header_tag_entry_address +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t flags; + multiboot_uint32_t entry_addr; +}; + +struct multiboot_header_tag_console_flags +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t flags; + multiboot_uint32_t console_flags; +}; + +struct multiboot_header_tag_framebuffer +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t flags; + multiboot_uint32_t width; + multiboot_uint32_t height; + multiboot_uint32_t depth; +}; + +struct multiboot_header_tag_module_align +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t flags; multiboot_uint32_t width; multiboot_uint32_t height; multiboot_uint32_t depth; diff --git a/loader/i386/multiboot.c b/loader/i386/multiboot.c index dab81dc8c..17fefc85a 100644 --- a/loader/i386/multiboot.c +++ b/loader/i386/multiboot.c @@ -26,10 +26,8 @@ * - APM table */ -/* The bits in the required part of flags field we don't support. */ -#define UNSUPPORTED_FLAGS 0x0000fff8 - #include +#include #include #include #include @@ -45,6 +43,7 @@ #include #include #include +#include #ifdef GRUB_MACHINE_EFI #include @@ -56,14 +55,15 @@ #define DEFAULT_VIDEO_MODE "auto" #endif -extern grub_dl_t my_mod; -static grub_size_t code_size, alloc_mbi; +grub_size_t grub_multiboot_alloc_mbi; char *grub_multiboot_payload_orig; grub_addr_t grub_multiboot_payload_dest; grub_size_t grub_multiboot_pure_size; grub_uint32_t grub_multiboot_payload_eip; static int accepts_video; +static grub_dl_t my_mod; + /* Return the length of the Multiboot mmap that will be needed to allocate our platform's map. */ @@ -178,14 +178,14 @@ grub_multiboot_boot (void) }; mbi_size = grub_multiboot_get_mbi_size (); - if (alloc_mbi < mbi_size) + if (grub_multiboot_alloc_mbi < mbi_size) { grub_multiboot_payload_orig = grub_relocator32_realloc (grub_multiboot_payload_orig, grub_multiboot_pure_size + mbi_size); if (!grub_multiboot_payload_orig) return grub_errno; - alloc_mbi = mbi_size; + grub_multiboot_alloc_mbi = mbi_size; } state.ebx = grub_multiboot_payload_dest + grub_multiboot_pure_size; @@ -215,7 +215,7 @@ grub_multiboot_unload (void) grub_relocator32_free (grub_multiboot_payload_orig); - alloc_mbi = 0; + grub_multiboot_alloc_mbi = 0; grub_multiboot_payload_orig = NULL; grub_dl_unref (my_mod); @@ -232,7 +232,7 @@ grub_multiboot_unload (void) #undef MULTIBOOT_LOAD_ELF32 /* Load ELF32 or ELF64. */ -static grub_err_t +grub_err_t grub_multiboot_load_elf (grub_file_t file, void *buffer) { if (grub_multiboot_is_elf32 (buffer)) @@ -243,137 +243,61 @@ grub_multiboot_load_elf (grub_file_t file, void *buffer) return grub_error (GRUB_ERR_UNKNOWN_OS, "unknown ELF class"); } -void -grub_multiboot (int argc, char *argv[]) +grub_err_t +grub_multiboot_set_console (int console_type, int accepted_consoles, + int width, int height, int depth) +{ + if (console_type == GRUB_MULTIBOOT_CONSOLE_FRAMEBUFFER) + { + char *buf; + if (depth && width && height) + buf = grub_xasprintf ("%dx%dx%d,%dx%d,auto", width, + height, depth, width, height); + else if (width && height) + buf = grub_xasprintf ("%dx%d,auto", width, height); + else + buf = grub_strdup ("auto"); + + if (!buf) + return grub_errno; + grub_env_set ("gfxpayload", buf); + grub_free (buf); + } + else + grub_env_set ("gfxpayload", "text"); + + accepts_video = !!(accepted_consoles & GRUB_MULTIBOOT_CONSOLE_FRAMEBUFFER); + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_cmd_multiboot (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) { grub_file_t file = 0; - char buffer[MULTIBOOT_SEARCH]; - struct multiboot_header *header; - grub_ssize_t len; + grub_err_t err; grub_loader_unset (); if (argc == 0) - { - grub_error (GRUB_ERR_BAD_ARGUMENT, "no kernel specified"); - goto fail; - } + return grub_error (GRUB_ERR_BAD_ARGUMENT, "no kernel specified"); file = grub_gzfile_open (argv[0], 1); if (! file) - { - grub_error (GRUB_ERR_BAD_ARGUMENT, "couldn't open file"); - goto fail; - } + return grub_error (GRUB_ERR_BAD_ARGUMENT, "couldn't open file"); - len = grub_file_read (file, buffer, MULTIBOOT_SEARCH); - if (len < 32) - { - grub_error (GRUB_ERR_BAD_OS, "file too small"); - goto fail; - } - - /* Look for the multiboot header in the buffer. The header should - be at least 12 bytes and aligned on a 4-byte boundary. */ - for (header = (struct multiboot_header *) buffer; - ((char *) header <= buffer + len - 12) || (header = 0); - header = (struct multiboot_header *) ((char *) header + 4)) - { - if (header->magic == MULTIBOOT_HEADER_MAGIC - && !(header->magic + header->flags + header->checksum)) - break; - } - - if (header == 0) - { - grub_error (GRUB_ERR_BAD_ARGUMENT, "no multiboot header found"); - goto fail; - } - - if (header->flags & UNSUPPORTED_FLAGS) - { - grub_error (GRUB_ERR_UNKNOWN_OS, - "unsupported flag: 0x%x", header->flags); - goto fail; - } - - grub_relocator32_free (grub_multiboot_payload_orig); - grub_multiboot_payload_orig = NULL; + grub_dl_ref (my_mod); /* Skip filename. */ grub_multiboot_init_mbi (argc - 1, argv + 1); - if (header->flags & MULTIBOOT_AOUT_KLUDGE) - { - int offset = ((char *) header - buffer - - (header->header_addr - header->load_addr)); - int load_size = ((header->load_end_addr == 0) ? file->size - offset : - header->load_end_addr - header->load_addr); + grub_relocator32_free (grub_multiboot_payload_orig); + grub_multiboot_payload_orig = NULL; - if (header->bss_end_addr) - code_size = (header->bss_end_addr - header->load_addr); - else - code_size = load_size; - grub_multiboot_payload_dest = header->load_addr; - - grub_multiboot_pure_size += code_size; - - /* Allocate a bit more to avoid relocations in most cases. */ - alloc_mbi = grub_multiboot_get_mbi_size () + 65536; - grub_multiboot_payload_orig - = grub_relocator32_alloc (grub_multiboot_pure_size + alloc_mbi); - - if (! grub_multiboot_payload_orig) - goto fail; - - if ((grub_file_seek (file, offset)) == (grub_off_t) -1) - goto fail; - - grub_file_read (file, (void *) grub_multiboot_payload_orig, load_size); - if (grub_errno) - goto fail; - - if (header->bss_end_addr) - grub_memset ((void *) (grub_multiboot_payload_orig + load_size), 0, - header->bss_end_addr - header->load_addr - load_size); - - grub_multiboot_payload_eip = header->entry_addr; - - } - else if (grub_multiboot_load_elf (file, buffer) != GRUB_ERR_NONE) + err = grub_multiboot_load (file); + if (err) goto fail; - if (header->flags & MULTIBOOT_VIDEO_MODE) - { - switch (header->mode_type) - { - case 1: - grub_env_set ("gfxpayload", "text"); - break; - - case 0: - { - char *buf; - if (header->depth && header->width && header->height) - buf = grub_xasprintf ("%dx%dx%d,%dx%d,auto", header->width, - header->height, header->depth, header->width, - header->height); - else if (header->width && header->height) - buf = grub_xasprintf ("%dx%d,auto", header->width, header->height); - else - buf = grub_strdup ("auto"); - - if (!buf) - goto fail; - grub_env_set ("gfxpayload", buf); - grub_free (buf); - break; - } - } - } - - accepts_video = !!(header->flags & MULTIBOOT_VIDEO_MODE); - grub_multiboot_set_bootdev (); grub_loader_set (grub_multiboot_boot, grub_multiboot_unload, 0); @@ -385,12 +309,16 @@ grub_multiboot (int argc, char *argv[]) if (grub_errno != GRUB_ERR_NONE) { grub_relocator32_free (grub_multiboot_payload_orig); + grub_multiboot_free_mbi (); grub_dl_unref (my_mod); } + + return grub_errno; } -void -grub_module (int argc, char *argv[]) +static grub_err_t +grub_cmd_module (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) { grub_file_t file = 0; grub_ssize_t size; @@ -398,40 +326,64 @@ grub_module (int argc, char *argv[]) grub_err_t err; if (argc == 0) - { - grub_error (GRUB_ERR_BAD_ARGUMENT, "no module specified"); - goto fail; - } + return grub_error (GRUB_ERR_BAD_ARGUMENT, "no module specified"); if (!grub_multiboot_payload_orig) - { - grub_error (GRUB_ERR_BAD_ARGUMENT, - "you need to load the multiboot kernel first"); - goto fail; - } + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "you need to load the multiboot kernel first"); file = grub_gzfile_open (argv[0], 1); if (! file) - goto fail; + return grub_errno; size = grub_file_size (file); module = grub_memalign (MULTIBOOT_MOD_ALIGN, size); if (! module) - goto fail; + { + grub_file_close (file); + return grub_errno; + } err = grub_multiboot_add_module ((grub_addr_t) module, size, argc - 1, argv + 1); if (err) - goto fail; + { + grub_file_close (file); + return err; + } if (grub_file_read (file, module, size) != size) { - grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file"); - goto fail; + grub_file_close (file); + return grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file"); } - fail: - if (file) - grub_file_close (file); + grub_file_close (file); + return GRUB_ERR_NONE;; } +static grub_command_t cmd_multiboot, cmd_module; + +GRUB_MOD_INIT(multiboot) +{ + cmd_multiboot = +#ifdef GRUB_USE_MULTIBOOT2 + grub_register_command ("multiboot2", grub_cmd_multiboot, + 0, N_("Load a multiboot 2 kernel.")); +#else + grub_register_command ("multiboot", grub_cmd_multiboot, + 0, N_("Load a multiboot kernel.")); +#endif + + cmd_module = + grub_register_command ("module", grub_cmd_module, + 0, N_("Load a multiboot module.")); + + my_mod = mod; +} + +GRUB_MOD_FINI(multiboot) +{ + grub_unregister_command (cmd_multiboot); + grub_unregister_command (cmd_module); +} diff --git a/loader/i386/multiboot_elfxx.c b/loader/i386/multiboot_elfxx.c index 2e35183a4..05fb2c1c1 100644 --- a/loader/i386/multiboot_elfxx.c +++ b/loader/i386/multiboot_elfxx.c @@ -53,6 +53,7 @@ CONCAT(grub_multiboot_load_elf, XX) (grub_file_t file, void *buffer) char *phdr_base; int lowest_segment = -1, highest_segment = -1; int i; + grub_size_t code_size; if (ehdr->e_ident[EI_CLASS] != ELFCLASSXX) return grub_error (GRUB_ERR_UNKNOWN_OS, "invalid ELF class"); @@ -102,9 +103,9 @@ CONCAT(grub_multiboot_load_elf, XX) (grub_file_t file, void *buffer) grub_multiboot_pure_size += code_size; - alloc_mbi = grub_multiboot_get_mbi_size (); + grub_multiboot_alloc_mbi = grub_multiboot_get_mbi_size () + 65536; grub_multiboot_payload_orig - = grub_relocator32_alloc (grub_multiboot_pure_size + alloc_mbi + 65536); + = grub_relocator32_alloc (grub_multiboot_pure_size + grub_multiboot_alloc_mbi); if (!grub_multiboot_payload_orig) return grub_errno; diff --git a/loader/i386/multiboot_mbi.c b/loader/i386/multiboot_mbi.c index 0d5db3c13..e273e29ca 100644 --- a/loader/i386/multiboot_mbi.c +++ b/loader/i386/multiboot_mbi.c @@ -23,6 +23,7 @@ #endif #include #include +#include #include #include #include @@ -30,6 +31,10 @@ #include #include #include +#include + +/* The bits in the required part of flags field we don't support. */ +#define UNSUPPORTED_FLAGS 0x0000fff8 struct module { @@ -48,6 +53,132 @@ static char *cmdline = NULL; static grub_uint32_t bootdev; static int bootdev_set; +grub_err_t +grub_multiboot_load (grub_file_t file) +{ + char *buffer; + grub_ssize_t len; + struct multiboot_header *header; + grub_err_t err; + + buffer = grub_malloc (MULTIBOOT_SEARCH); + if (!buffer) + return grub_errno; + + len = grub_file_read (file, buffer, MULTIBOOT_SEARCH); + if (len < 32) + { + grub_free (buffer); + return grub_error (GRUB_ERR_BAD_OS, "file too small"); + } + + /* Look for the multiboot header in the buffer. The header should + be at least 12 bytes and aligned on a 4-byte boundary. */ + for (header = (struct multiboot_header *) buffer; + ((char *) header <= buffer + len - 12) || (header = 0); + header = (struct multiboot_header *) ((char *) header + MULTIBOOT_HEADER_ALIGN)) + { + if (header->magic == MULTIBOOT_HEADER_MAGIC + && !(header->magic + header->flags + header->checksum)) + break; + } + + if (header == 0) + { + grub_free (buffer); + return grub_error (GRUB_ERR_BAD_ARGUMENT, "no multiboot header found"); + } + + if (header->flags & UNSUPPORTED_FLAGS) + { + grub_free (buffer); + return grub_error (GRUB_ERR_UNKNOWN_OS, + "unsupported flag: 0x%x", header->flags); + } + + if (header->flags & MULTIBOOT_AOUT_KLUDGE) + { + int offset = ((char *) header - buffer - + (header->header_addr - header->load_addr)); + int load_size = ((header->load_end_addr == 0) ? file->size - offset : + header->load_end_addr - header->load_addr); + grub_size_t code_size; + + if (header->bss_end_addr) + code_size = (header->bss_end_addr - header->load_addr); + else + code_size = load_size; + grub_multiboot_payload_dest = header->load_addr; + + grub_multiboot_pure_size += code_size; + + /* Allocate a bit more to avoid relocations in most cases. */ + grub_multiboot_alloc_mbi = grub_multiboot_get_mbi_size () + 65536; + grub_multiboot_payload_orig + = grub_relocator32_alloc (grub_multiboot_pure_size + grub_multiboot_alloc_mbi); + + if (! grub_multiboot_payload_orig) + { + grub_free (buffer); + return grub_errno; + } + + if ((grub_file_seek (file, offset)) == (grub_off_t) -1) + { + grub_free (buffer); + return grub_errno; + } + + grub_file_read (file, (void *) grub_multiboot_payload_orig, load_size); + if (grub_errno) + { + grub_free (buffer); + return grub_errno; + } + + if (header->bss_end_addr) + grub_memset ((void *) (grub_multiboot_payload_orig + load_size), 0, + header->bss_end_addr - header->load_addr - load_size); + + grub_multiboot_payload_eip = header->entry_addr; + + } + else + { + err = grub_multiboot_load_elf (file, buffer); + if (err) + { + grub_free (buffer); + return err; + } + } + + if (header->flags & MULTIBOOT_VIDEO_MODE) + { + switch (header->mode_type) + { + case 1: + err = grub_multiboot_set_console (GRUB_MULTIBOOT_CONSOLE_EGA_TEXT, + GRUB_MULTIBOOT_CONSOLE_EGA_TEXT + | GRUB_MULTIBOOT_CONSOLE_FRAMEBUFFER, + 0, 0, 0); + break; + case 0: + err = grub_multiboot_set_console (GRUB_MULTIBOOT_CONSOLE_FRAMEBUFFER, + GRUB_MULTIBOOT_CONSOLE_EGA_TEXT + | GRUB_MULTIBOOT_CONSOLE_FRAMEBUFFER, + header->width, header->height, + header->depth); + break; + } + } + else + err = grub_multiboot_set_console (GRUB_MULTIBOOT_CONSOLE_EGA_TEXT, + GRUB_MULTIBOOT_CONSOLE_EGA_TEXT, + 0, 0, 0); + return err; +} + grub_size_t grub_multiboot_get_mbi_size (void) { diff --git a/loader/multiboot_loader.c b/loader/multiboot_loader.c deleted file mode 100644 index 6d042fa81..000000000 --- a/loader/multiboot_loader.c +++ /dev/null @@ -1,150 +0,0 @@ -/* multiboot_loader.c - boot multiboot kernel image */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2007,2008,2009,2010 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -grub_dl_t my_mod; - -static int -find_multi_boot1_header (grub_file_t file) -{ - struct multiboot_header *header; - char buffer[MULTIBOOT_SEARCH]; - int found_status = 0; - grub_ssize_t len; - - len = grub_file_read (file, buffer, MULTIBOOT_SEARCH); - if (len < 32) - return found_status; - - /* Look for the multiboot header in the buffer. The header should - be at least 12 bytes and aligned on a 4-byte boundary. */ - for (header = (struct multiboot_header *) buffer; - ((char *) header <= buffer + len - 12) || (header = 0); - header = (struct multiboot_header *) ((char *) header + 4)) - { - if (header->magic == MULTIBOOT_HEADER_MAGIC - && !(header->magic + header->flags + header->checksum)) - { - found_status = 1; - break; - } - } - - return found_status; -} - -static grub_err_t -grub_cmd_multiboot_loader (grub_command_t cmd __attribute__ ((unused)), - int argc, char *argv[]) -{ - grub_file_t file = 0; - int header_multi_ver_found = 0; - - grub_dl_ref (my_mod); - - if (argc == 0) - { - grub_error (GRUB_ERR_BAD_ARGUMENT, "no kernel specified"); - goto fail; - } - - file = grub_gzfile_open (argv[0], 1); - if (! file) - { - grub_error (GRUB_ERR_BAD_ARGUMENT, "couldn't open file"); - goto fail; - } - - /* find which header is in the file */ - if (find_multi_boot1_header (file)) - header_multi_ver_found = 1; - else - { - grub_error (GRUB_ERR_BAD_OS, "multiboot header not found"); - goto fail; - } - - /* close file before calling functions */ - if (file) - grub_file_close (file); - - /* Launch multi boot with header */ - - grub_dprintf ("multiboot_loader", - "Launching multiboot 1 grub_multiboot() function\n"); - grub_multiboot (argc, argv); - - return grub_errno; - -fail: - if (file) - grub_file_close (file); - - grub_dl_unref (my_mod); - - return grub_errno; -} - -static grub_err_t -grub_cmd_module_loader (grub_command_t cmd __attribute__ ((unused)), - int argc, char *argv[]) -{ - - grub_dprintf("multiboot_loader", - "Launching multiboot 1 grub_module() function\n"); - grub_module (argc, argv); - - return grub_errno; -} - -static grub_command_t cmd_multiboot, cmd_module; - -GRUB_MOD_INIT(multiboot) -{ - cmd_multiboot = -#ifdef GRUB_USE_MULTIBOOT2 - grub_register_command ("multiboot2", grub_cmd_multiboot_loader, - 0, N_("Load a multiboot 2 kernel.")); -#else - grub_register_command ("multiboot", grub_cmd_multiboot_loader, - 0, N_("Load a multiboot kernel.")); -#endif - - cmd_module = - grub_register_command ("module", grub_cmd_module_loader, - 0, N_("Load a multiboot module.")); - - my_mod = mod; -} - -GRUB_MOD_FINI(multiboot) -{ - grub_unregister_command (cmd_multiboot); - grub_unregister_command (cmd_module); -} From 4e02ed5014cc2c88a857581ff17f3de5ebb9b61f Mon Sep 17 00:00:00 2001 From: Matt Kraai Date: Mon, 8 Mar 2010 22:20:02 +0000 Subject: [PATCH 475/738] 2010-03-08 Matt Kraai * util/i386/pc/grub-setup.c (setup): Fix a grammatical error (Debian bug #559005). --- ChangeLog | 5 +++++ util/i386/pc/grub-setup.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 667ff0c1e..18eb66b51 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-03-08 Matt Kraai + + * util/i386/pc/grub-setup.c (setup): Fix a grammatical error (Debian + bug #559005). + 2010-03-07 Vladimir Serbinenko * genmoddep.awk: Output all missing symbols and not only first. diff --git a/util/i386/pc/grub-setup.c b/util/i386/pc/grub-setup.c index 4e2517ef2..ace577f37 100644 --- a/util/i386/pc/grub-setup.c +++ b/util/i386/pc/grub-setup.c @@ -418,7 +418,7 @@ unable_to_embed: grub_util_warn (_("Embedding is not possible. GRUB can only be installed in this " "setup by using blocklists. However, blocklists are UNRELIABLE and " - "its use is discouraged.")); + "their use is discouraged.")); if (! force) grub_util_error (_("if you really want blocklists, use --force")); From c3a8dfc8b750e3bebd731aefdcf9788fe2a22f77 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 10 Mar 2010 11:40:20 +0100 Subject: [PATCH 476/738] Tagged header support --- include/grub/multiboot.h | 3 +- include/multiboot2.h | 5 + loader/i386/multiboot.c | 20 +++- loader/i386/multiboot_mbi.c | 6 +- loader/i386/multiboot_mbi2.c | 196 +++++++++++++++++++++++++++++++++++ 5 files changed, 225 insertions(+), 5 deletions(-) diff --git a/include/grub/multiboot.h b/include/grub/multiboot.h index 89efbc6dd..70241ec3c 100644 --- a/include/grub/multiboot.h +++ b/include/grub/multiboot.h @@ -70,7 +70,8 @@ grub_multiboot_fill_vbe_info_real (struct grub_vbe_info_block *vbe_control_info, grub_err_t grub_multiboot_set_console (int console_type, int accepted_consoles, - int width, int height, int depth); + int width, int height, int depth, + int console_required); grub_err_t grub_multiboot_load (grub_file_t file); /* Load ELF32 or ELF64. */ diff --git a/include/multiboot2.h b/include/multiboot2.h index dae05a7a3..820479425 100644 --- a/include/multiboot2.h +++ b/include/multiboot2.h @@ -62,6 +62,8 @@ #define MULTIBOOT_TAG_TYPE_MMAP 6 #define MULTIBOOT_TAG_TYPE_VBE 7 #define MULTIBOOT_TAG_TYPE_FRAMEBUFFER 8 +#define MULTIBOOT_TAG_TYPE_ELF_SECTIONS 9 +#define MULTIBOOT_TAG_TYPE_APM 10 #define MULTIBOOT_HEADER_TAG_END 0 #define MULTIBOOT_HEADER_TAG_INFORMATION_REQUEST 1 @@ -74,6 +76,9 @@ #define GRUB_MULTIBOOT_ARCHITECTURE_I386 0 #define MULTIBOOT_HEADER_TAG_OPTIONAL 1 +#define MULTIBOOT_CONSOLE_FLAGS_CONSOLE_REQUIRED 1 +#define MULTIBOOT_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED 2 + #ifndef ASM_FILE typedef unsigned char multiboot_uint8_t; diff --git a/loader/i386/multiboot.c b/loader/i386/multiboot.c index 17fefc85a..a89233431 100644 --- a/loader/i386/multiboot.c +++ b/loader/i386/multiboot.c @@ -62,6 +62,8 @@ grub_addr_t grub_multiboot_payload_dest; grub_size_t grub_multiboot_pure_size; grub_uint32_t grub_multiboot_payload_eip; static int accepts_video; +static int accepts_ega_text; +static int console_required; static grub_dl_t my_mod; @@ -245,8 +247,23 @@ grub_multiboot_load_elf (grub_file_t file, void *buffer) grub_err_t grub_multiboot_set_console (int console_type, int accepted_consoles, - int width, int height, int depth) + int width, int height, int depth, + int console_req) { + console_required = console_req; + if (!(accepted_consoles + & (GRUB_MULTIBOOT_CONSOLE_FRAMEBUFFER + | (GRUB_MACHINE_HAS_VGA_TEXT ? GRUB_MULTIBOOT_CONSOLE_EGA_TEXT : 0)))) + { + if (console_required) + return grub_error (GRUB_ERR_BAD_OS, + "OS requires a console but none is available"); + grub_printf ("WARNING: no console will be available to OS"); + accepts_video = 0; + accepts_ega_text = 0; + return GRUB_ERR_NONE; + } + if (console_type == GRUB_MULTIBOOT_CONSOLE_FRAMEBUFFER) { char *buf; @@ -267,6 +284,7 @@ grub_multiboot_set_console (int console_type, int accepted_consoles, grub_env_set ("gfxpayload", "text"); accepts_video = !!(accepted_consoles & GRUB_MULTIBOOT_CONSOLE_FRAMEBUFFER); + accepts_ega_text = !!(accepted_consoles & GRUB_MULTIBOOT_CONSOLE_EGA_TEXT); return GRUB_ERR_NONE; } diff --git a/loader/i386/multiboot_mbi.c b/loader/i386/multiboot_mbi.c index e273e29ca..6d104ed1c 100644 --- a/loader/i386/multiboot_mbi.c +++ b/loader/i386/multiboot_mbi.c @@ -161,21 +161,21 @@ grub_multiboot_load (grub_file_t file) err = grub_multiboot_set_console (GRUB_MULTIBOOT_CONSOLE_EGA_TEXT, GRUB_MULTIBOOT_CONSOLE_EGA_TEXT | GRUB_MULTIBOOT_CONSOLE_FRAMEBUFFER, - 0, 0, 0); + 0, 0, 0, 0); break; case 0: err = grub_multiboot_set_console (GRUB_MULTIBOOT_CONSOLE_FRAMEBUFFER, GRUB_MULTIBOOT_CONSOLE_EGA_TEXT | GRUB_MULTIBOOT_CONSOLE_FRAMEBUFFER, header->width, header->height, - header->depth); + header->depth, 0); break; } } else err = grub_multiboot_set_console (GRUB_MULTIBOOT_CONSOLE_EGA_TEXT, GRUB_MULTIBOOT_CONSOLE_EGA_TEXT, - 0, 0, 0); + 0, 0, 0, 0); return err; } diff --git a/loader/i386/multiboot_mbi2.c b/loader/i386/multiboot_mbi2.c index ab803734f..d07ce92f3 100644 --- a/loader/i386/multiboot_mbi2.c +++ b/loader/i386/multiboot_mbi2.c @@ -23,6 +23,7 @@ #endif #include #include +#include #include #include #include @@ -59,6 +60,201 @@ static char *cmdline = NULL; static int bootdev_set; static grub_uint32_t biosdev, slice, part; +grub_err_t +grub_multiboot_load (grub_file_t file) +{ + char *buffer; + grub_ssize_t len; + struct multiboot_header *header; + grub_err_t err; + struct multiboot_header_tag *tag; + struct multiboot_header_tag_address *addr_tag = NULL; + int entry_specified = 0; + grub_addr_t entry = 0; + grub_uint32_t console_required = 0; + struct multiboot_header_tag_framebuffer *fbtag = NULL; + int accepted_consoles = GRUB_MULTIBOOT_CONSOLE_EGA_TEXT; + + buffer = grub_malloc (MULTIBOOT_SEARCH); + if (!buffer) + return grub_errno; + + len = grub_file_read (file, buffer, MULTIBOOT_SEARCH); + if (len < 32) + { + grub_free (buffer); + return grub_error (GRUB_ERR_BAD_OS, "file too small"); + } + + /* Look for the multiboot header in the buffer. The header should + be at least 12 bytes and aligned on a 4-byte boundary. */ + for (header = (struct multiboot_header *) buffer; + ((char *) header <= buffer + len - 12) || (header = 0); + header = (struct multiboot_header *) ((char *) header + MULTIBOOT_HEADER_ALIGN)) + { + if (header->magic == MULTIBOOT_HEADER_MAGIC + && !(header->magic + header->architecture + + header->header_length + header->checksum)) + break; + } + + if (header == 0) + { + grub_free (buffer); + return grub_error (GRUB_ERR_BAD_ARGUMENT, "no multiboot header found"); + } + + for (tag = (struct multiboot_header_tag *) (header + 1); + tag->type != MULTIBOOT_TAG_TYPE_END; + tag = (struct multiboot_header_tag *) ((char *) tag + tag->size)) + switch (tag->type) + { + case MULTIBOOT_HEADER_TAG_INFORMATION_REQUEST: + { + unsigned i; + struct multiboot_header_tag_information_request *request_tag + = (struct multiboot_header_tag_information_request *) tag; + if (request_tag->flags & MULTIBOOT_HEADER_TAG_OPTIONAL) + break; + for (i = 0; i < (request_tag->size - sizeof (request_tag)) + / sizeof (request_tag->requests[0]); i++) + switch (request_tag->requests[i]) + { + case MULTIBOOT_TAG_TYPE_END: + case MULTIBOOT_TAG_TYPE_CMDLINE: + case MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME: + case MULTIBOOT_TAG_TYPE_MODULE: + case MULTIBOOT_TAG_TYPE_BASIC_MEMINFO: + case MULTIBOOT_TAG_TYPE_BOOTDEV: + case MULTIBOOT_TAG_TYPE_MMAP: + case MULTIBOOT_TAG_TYPE_VBE: + case MULTIBOOT_TAG_TYPE_FRAMEBUFFER: + break; + + case MULTIBOOT_TAG_TYPE_ELF_SECTIONS: + case MULTIBOOT_TAG_TYPE_APM: + default: + grub_free (buffer); + return grub_error (GRUB_ERR_UNKNOWN_OS, + "unsupported information tag: 0x%x", + request_tag->requests[i]); + } + break; + } + + case MULTIBOOT_HEADER_TAG_ADDRESS: + addr_tag = (struct multiboot_header_tag_address *) tag; + break; + + case MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS: + entry_specified = 1; + entry = ((struct multiboot_header_tag_entry_address *) tag)->entry_addr; + break; + + case MULTIBOOT_HEADER_TAG_CONSOLE_FLAGS: + if (!(((struct multiboot_header_tag_console_flags *) tag)->console_flags + & MULTIBOOT_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED)) + accepted_consoles &= ~GRUB_MULTIBOOT_CONSOLE_EGA_TEXT; + if (((struct multiboot_header_tag_console_flags *) tag)->console_flags + & MULTIBOOT_CONSOLE_FLAGS_CONSOLE_REQUIRED) + console_required = 1; + break; + + case MULTIBOOT_HEADER_TAG_FRAMEBUFFER: + fbtag = (struct multiboot_header_tag_framebuffer *) tag; + accepted_consoles |= GRUB_MULTIBOOT_CONSOLE_FRAMEBUFFER; + break; + + /* GRUB always page-aligns modules. */ + case MULTIBOOT_HEADER_TAG_MODULE_ALIGN: + break; + + default: + if (! (tag->flags & MULTIBOOT_HEADER_TAG_OPTIONAL)) + { + grub_free (buffer); + return grub_error (GRUB_ERR_UNKNOWN_OS, + "unsupported tag: 0x%x", tag->type); + } + break; + } + + if (addr_tag && !entry_specified) + { + grub_free (buffer); + return grub_error (GRUB_ERR_UNKNOWN_OS, + "load address tag without entry address tag"); + } + + if (addr_tag) + { + int offset = ((char *) header - buffer - + (addr_tag->header_addr - addr_tag->load_addr)); + int load_size = ((addr_tag->load_end_addr == 0) ? file->size - offset : + addr_tag->load_end_addr - addr_tag->load_addr); + grub_size_t code_size; + + if (addr_tag->bss_end_addr) + code_size = (addr_tag->bss_end_addr - addr_tag->load_addr); + else + code_size = load_size; + grub_multiboot_payload_dest = addr_tag->load_addr; + + grub_multiboot_pure_size += code_size; + + /* Allocate a bit more to avoid relocations in most cases. */ + grub_multiboot_alloc_mbi = grub_multiboot_get_mbi_size () + 65536; + grub_multiboot_payload_orig + = grub_relocator32_alloc (grub_multiboot_pure_size + grub_multiboot_alloc_mbi); + + if (! grub_multiboot_payload_orig) + { + grub_free (buffer); + return grub_errno; + } + + if ((grub_file_seek (file, offset)) == (grub_off_t) -1) + { + grub_free (buffer); + return grub_errno; + } + + grub_file_read (file, (void *) grub_multiboot_payload_orig, load_size); + if (grub_errno) + { + grub_free (buffer); + return grub_errno; + } + + if (addr_tag->bss_end_addr) + grub_memset ((void *) (grub_multiboot_payload_orig + load_size), 0, + addr_tag->bss_end_addr - addr_tag->load_addr - load_size); + } + else + { + err = grub_multiboot_load_elf (file, buffer); + if (err) + { + grub_free (buffer); + return err; + } + } + + if (entry_specified) + grub_multiboot_payload_eip = entry; + + if (fbtag) + err = grub_multiboot_set_console (GRUB_MULTIBOOT_CONSOLE_FRAMEBUFFER, + accepted_consoles, + fbtag->width, fbtag->height, + fbtag->depth, console_required); + else + err = grub_multiboot_set_console (GRUB_MULTIBOOT_CONSOLE_EGA_TEXT, + accepted_consoles, + 0, 0, 0, console_required); + return err; +} + grub_size_t grub_multiboot_get_mbi_size (void) { From d68b491ee2428b3160516d5f35a4eddf904ee114 Mon Sep 17 00:00:00 2001 From: Thorsten Glaser Date: Sun, 14 Mar 2010 13:48:55 +0100 Subject: [PATCH 477/738] * util/grub-mkrescue.in: Base ISO UUID on UTC. --- ChangeLog | 4 ++++ util/grub-mkrescue.in | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 18eb66b51..1977f24ad 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-03-14 Thorsten Glaser + + * util/grub-mkrescue.in: Base ISO UUID on UTC. + 2010-03-08 Matt Kraai * util/i386/pc/grub-setup.c (setup): Fix a grammatical error (Debian diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in index 592cf2df6..db29b0899 100644 --- a/util/grub-mkrescue.in +++ b/util/grub-mkrescue.in @@ -145,7 +145,7 @@ if test -e "${coreboot_dir}" ; then memdisk_dir=`mktemp -d "$MKTEMP_TEMPLATE"` mkdir -p ${memdisk_dir}/boot/grub # obtain date-based UUID - iso_uuid=$(date +%Y-%m-%d-%H-%M-%S-00) + iso_uuid=$(date -u +%Y-%m-%d-%H-%M-%S-00) modules="$(cat ${coreboot_dir}/partmap.lst) ${modules}" cat << EOF > ${memdisk_dir}/boot/grub/grub.cfg From 18d4c6f0ce0c4021dcadf6275f6208502eb281ff Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 14 Mar 2010 16:32:50 +0100 Subject: [PATCH 478/738] Fix address size in ofwfb on sparc64 (based on info by bvk) --- video/ieee1275.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/video/ieee1275.c b/video/ieee1275.c index 99c54f5ed..5c6bc1594 100644 --- a/video/ieee1275.c +++ b/video/ieee1275.c @@ -124,8 +124,7 @@ grub_video_ieee1275_setup (unsigned int width, unsigned int height, unsigned int mode_type __attribute__ ((unused)), unsigned int mode_mask __attribute__ ((unused))) { - grub_uint32_t current_width, current_height; - grub_addr_t address; + grub_uint32_t current_width, current_height, address; grub_err_t err; grub_ieee1275_phandle_t dev; @@ -167,7 +166,8 @@ grub_video_ieee1275_setup (unsigned int width, unsigned int height, sizeof (address), 0)) return grub_error (GRUB_ERR_IO, "Couldn't retrieve display address."); - framebuffer.ptr = (void *) address; + /* For some reason sparc64 uses 32-bit pointer too. */ + framebuffer.ptr = (void *) (grub_addr_t) address; grub_video_ieee1275_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS, grub_video_fbstd_colors); From 8d7f2981d06ab50e7aef4084ce56e33b1f3ed4c7 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 14 Mar 2010 16:55:51 +0100 Subject: [PATCH 479/738] Remove leftover date*.mo on sparc64 --- conf/sparc64-ieee1275.rmk | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/conf/sparc64-ieee1275.rmk b/conf/sparc64-ieee1275.rmk index c29f15d14..f8a160e40 100644 --- a/conf/sparc64-ieee1275.rmk +++ b/conf/sparc64-ieee1275.rmk @@ -101,21 +101,4 @@ datetime_mod_SOURCES = lib/ieee1275/datetime.c datetime_mod_CFLAGS = $(COMMON_CFLAGS) datetime_mod_LDFLAGS = $(COMMON_LDFLAGS) -pkglib_MODULES += datetime.mod date.mod datehook.mod - -# For datetime.mod -datetime_mod_SOURCES = lib/ieee1275/datetime.c -datetime_mod_CFLAGS = $(COMMON_CFLAGS) -datetime_mod_LDFLAGS = $(COMMON_LDFLAGS) - -# For date.mod -date_mod_SOURCES = commands/date.c -date_mod_CFLAGS = $(COMMON_CFLAGS) -date_mod_LDFLAGS = $(COMMON_LDFLAGS) - -# For datehook.mod -datehook_mod_SOURCES = hook/datehook.c -datehook_mod_CFLAGS = $(COMMON_CFLAGS) -datehook_mod_LDFLAGS = $(COMMON_LDFLAGS) - include $(srcdir)/conf/common.mk From 1159bdce4a53adba09be544cfe87a02bfe0dea21 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 14 Mar 2010 23:56:13 +0100 Subject: [PATCH 480/738] * kern/mm.c (grub_real_malloc): Satisfy alignment requirement when extra == 0. --- ChangeLog.memalign_fix | 4 ++++ kern/mm.c | 16 +++++++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 ChangeLog.memalign_fix diff --git a/ChangeLog.memalign_fix b/ChangeLog.memalign_fix new file mode 100644 index 000000000..3dac2e51c --- /dev/null +++ b/ChangeLog.memalign_fix @@ -0,0 +1,4 @@ +2010-03-14 Vladimir Serbinenko + + * kern/mm.c (grub_real_malloc): Satisfy alignment requirement when + extra == 0. \ No newline at end of file diff --git a/kern/mm.c b/kern/mm.c index ef97b018e..9720a8b9d 100644 --- a/kern/mm.c +++ b/kern/mm.c @@ -223,7 +223,7 @@ grub_real_malloc (grub_mm_header_t *first, grub_size_t n, grub_size_t align) q->next = p->next; p->magic = GRUB_MM_ALLOC_MAGIC; } - else if (extra == 0 || p->size == n + extra) + else if (align == 1 || p->size == n + extra) { /* There might be alignment requirement, when taking it into account memory block fits in. @@ -240,11 +240,25 @@ grub_real_malloc (grub_mm_header_t *first, grub_size_t n, grub_size_t align) | alloc, size=n | | +---------------+ v */ + p->size -= n; p += p->size; p->size = n; p->magic = GRUB_MM_ALLOC_MAGIC; } + else if (extra == 0) + { + grub_mm_header_t r; + + p->magic = GRUB_MM_ALLOC_MAGIC; + p->size = n; + + r = p + extra + n; + r->magic = GRUB_MM_FREE_MAGIC; + r->size = p->size - extra - n; + r->next = p->next; + q->next = r; + } else { /* There is alignment requirement and there is room in memory From 0ea81d98458645a6ce6830db16f82122b34e4141 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 17 Mar 2010 00:16:11 +0100 Subject: [PATCH 481/738] * video/fb/fbblit.c (grub_video_fbblit_blend_XXXA8888_1bit): Handle alpha_mask_size == 0 case. --- ChangeLog | 5 +++++ video/fb/fbblit.c | 11 ++++++++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3f9d82987..d811fb381 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-03-17 Vladimir Serbinenko + + * video/fb/fbblit.c (grub_video_fbblit_blend_XXXA8888_1bit): Handle + alpha_mask_size == 0 case. + 2010-03-14 BVK Chaitanya GRUB shell lexer and parser improvements. diff --git a/video/fb/fbblit.c b/video/fb/fbblit.c index a0f44d268..15797be97 100644 --- a/video/fb/fbblit.c +++ b/video/fb/fbblit.c @@ -1170,10 +1170,15 @@ grub_video_fbblit_blend_XXXA8888_1bit (struct grub_video_fbblit_info *dst, grub_uint8_t a; if (*srcptr & srcmask) - color = fgcolor; + { + color = fgcolor; + a = src->mode_info->fg_alpha; + } else - color = bgcolor; - a = (color >> 24) & 0xff; + { + color = bgcolor; + a = src->mode_info->bg_alpha; + } if (a == 255) *(grub_uint32_t *) dstptr = color; From ed0e3d30cd3a2284c6209b278a9e6dd126901886 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 17 Mar 2010 08:22:45 +0100 Subject: [PATCH 482/738] * term/i386/pc/vesafb.c: Removed (orphaned, deprecated and broken). --- ChangeLog | 4 + term/i386/pc/vesafb.c | 606 ------------------------------------------ 2 files changed, 4 insertions(+), 606 deletions(-) delete mode 100644 term/i386/pc/vesafb.c diff --git a/ChangeLog b/ChangeLog index d811fb381..475d92eca 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-03-17 Vladimir Serbinenko + + * term/i386/pc/vesafb.c: Removed (orphaned, deprecated and broken). + 2010-03-17 Vladimir Serbinenko * video/fb/fbblit.c (grub_video_fbblit_blend_XXXA8888_1bit): Handle diff --git a/term/i386/pc/vesafb.c b/term/i386/pc/vesafb.c deleted file mode 100644 index 52694ed10..000000000 --- a/term/i386/pc/vesafb.c +++ /dev/null @@ -1,606 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2005,2007,2009 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -// TODO: Deprecated and broken. Scheduled for removal as there is VBE driver in Video subsystem. - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define DEFAULT_CHAR_WIDTH 8 -#define DEFAULT_CHAR_HEIGHT 16 - -#define DEFAULT_FG_COLOR 0xa -#define DEFAULT_BG_COLOR 0x0 - -struct grub_colored_char -{ - /* An Unicode codepoint. */ - grub_uint32_t code; - - /* Color indexes. */ - unsigned char fg_color; - unsigned char bg_color; - - /* The width of this character minus one. */ - unsigned char width; - - /* The column index of this character. */ - unsigned char index; -}; - -struct grub_virtual_screen -{ - /* Dimensions of the virtual screen. */ - grub_uint32_t width; - grub_uint32_t height; - - /* Offset in the display. */ - grub_uint32_t offset_x; - grub_uint32_t offset_y; - - /* TTY Character sizes. */ - grub_uint32_t char_width; - grub_uint32_t char_height; - - /* Virtual screen TTY size. */ - grub_uint32_t columns; - grub_uint32_t rows; - - /* Current cursor details. */ - grub_uint32_t cursor_x; - grub_uint32_t cursor_y; - grub_uint8_t cursor_state; - grub_uint8_t fg_color; - grub_uint8_t bg_color; - - /* Text buffer for virtual screen. Contains (columns * rows) number - of entries. */ - struct grub_colored_char *text_buffer; -}; - -/* Make sure text buffer is not marked as allocated. */ -static struct grub_virtual_screen virtual_screen = - { - .text_buffer = 0 - }; - -static unsigned char *vga_font = 0; -static grub_uint32_t old_mode = 0; - -static struct grub_vbe_mode_info_block mode_info; -static grub_uint8_t *framebuffer = 0; -static grub_uint32_t bytes_per_scan_line = 0; - -static void -grub_virtual_screen_free (void) -{ - /* If virtual screen has been allocated, free it. */ - if (virtual_screen.text_buffer != 0) - grub_free (virtual_screen.text_buffer); - - /* Reset virtual screen data. */ - grub_memset (&virtual_screen, 0, sizeof (virtual_screen)); -} - -static grub_err_t -grub_virtual_screen_setup (grub_uint32_t width, - grub_uint32_t height) -{ - /* Free old virtual screen. */ - grub_virtual_screen_free (); - - /* Initialize with default data. */ - virtual_screen.width = width; - virtual_screen.height = height; - virtual_screen.offset_x = 0; - virtual_screen.offset_y = 0; - virtual_screen.char_width = DEFAULT_CHAR_WIDTH; - virtual_screen.char_height = DEFAULT_CHAR_HEIGHT; - virtual_screen.cursor_x = 0; - virtual_screen.cursor_y = 0; - virtual_screen.cursor_state = 1; - virtual_screen.fg_color = DEFAULT_FG_COLOR; - virtual_screen.bg_color = DEFAULT_BG_COLOR; - - /* Calculate size of text buffer. */ - virtual_screen.columns = virtual_screen.width / virtual_screen.char_width; - virtual_screen.rows = virtual_screen.height / virtual_screen.char_height; - - /* Allocate memory for text buffer. */ - virtual_screen.text_buffer = - (struct grub_colored_char *) grub_malloc (virtual_screen.columns - * virtual_screen.rows - * sizeof (*virtual_screen.text_buffer)); - - return grub_errno; -} - -static grub_err_t -grub_vesafb_mod_init (void) -{ - grub_uint32_t use_mode = GRUB_VBE_DEFAULT_VIDEO_MODE; - struct grub_vbe_info_block controller_info; - char *modevar; - - /* Use fonts from VGA bios. */ - vga_font = grub_vga_get_font (); - - /* Check if we have VESA BIOS installed. */ - if (grub_vbe_probe (&controller_info) != GRUB_ERR_NONE) - return grub_errno; - - /* Check existence of vbe_mode environment variable. */ - modevar = grub_env_get ("vbe_mode"); - - if (modevar != 0) - { - unsigned long value; - - value = grub_strtoul (modevar, 0, 0); - if (grub_errno == GRUB_ERR_NONE) - use_mode = value; - } - - /* Store initial video mode. */ - if (grub_vbe_get_video_mode (&old_mode) != GRUB_ERR_NONE) - return grub_errno; - - /* Setup desired graphics mode. */ - if (grub_vbe_set_video_mode (use_mode, &mode_info) != GRUB_ERR_NONE) - return grub_errno; - - /* Determine framebuffer and bytes per scan line. */ - framebuffer = (grub_uint8_t *) mode_info.phys_base_addr; - - if (controller_info.version >= 0x300) - bytes_per_scan_line = mode_info.lin_bytes_per_scan_line; - else - bytes_per_scan_line = mode_info.bytes_per_scan_line; - - /* Create virtual screen. */ - if (grub_virtual_screen_setup (mode_info.x_resolution, - mode_info.y_resolution) != GRUB_ERR_NONE) - { - grub_vbe_set_video_mode (old_mode, 0); - return grub_errno; - } - - /* Make sure frame buffer is black. */ - grub_memset (framebuffer, - 0, - bytes_per_scan_line * mode_info.y_resolution); - - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_vesafb_mod_fini (void) -{ - grub_virtual_screen_free (); - - grub_vbe_set_video_mode (old_mode, 0); - - return GRUB_ERR_NONE; -} - -static int -grub_virtual_screen_get_glyph (grub_uint32_t code, - unsigned char bitmap[32], - unsigned *width) -{ - if (code > 0x7f) - { - /* Map some unicode characters to the VGA font, if possible. */ - switch (code) - { - case 0x2190: /* left arrow */ - code = 0x1b; - break; - case 0x2191: /* up arrow */ - code = 0x18; - break; - case 0x2192: /* right arrow */ - code = 0x1a; - break; - case 0x2193: /* down arrow */ - code = 0x19; - break; - case 0x2501: /* horizontal line */ - code = 0xc4; - break; - case 0x2503: /* vertical line */ - code = 0xb3; - break; - case 0x250F: /* upper-left corner */ - code = 0xda; - break; - case 0x2513: /* upper-right corner */ - code = 0xbf; - break; - case 0x2517: /* lower-left corner */ - code = 0xc0; - break; - case 0x251B: /* lower-right corner */ - code = 0xd9; - break; - - default: - return grub_font_get_glyph_any (code, bitmap, width); - } - } - - /* TODO This is wrong for the new font module. Should it be fixed? */ - if (bitmap) - grub_memcpy (bitmap, - vga_font + code * virtual_screen.char_height, - virtual_screen.char_height); - *width = 1; - return 1; -} - -static void -grub_virtual_screen_invalidate_char (struct grub_colored_char *p) -{ - p->code = 0xFFFF; - - if (p->width) - { - struct grub_colored_char *q; - - for (q = p + 1; q <= p + p->width; q++) - { - q->code = 0xFFFF; - q->width = 0; - q->index = 0; - } - } - - p->width = 0; -} - -static void -write_char (void) -{ - struct grub_colored_char *p; - unsigned char bitmap[32]; - unsigned width; - unsigned y; - unsigned offset; - - p = (virtual_screen.text_buffer - + virtual_screen.cursor_x - + (virtual_screen.cursor_y * virtual_screen.columns)); - - p -= p->index; - - if (! grub_virtual_screen_get_glyph (p->code, bitmap, &width)) - { - grub_virtual_screen_invalidate_char (p); - width = 0; - } - - for (y = 0, offset = 0; - y < virtual_screen.char_height; - y++, offset++) - { - unsigned i; - - for (i = 0; - (i < width * virtual_screen.char_width) && (offset < 32); - i++) - { - unsigned char color; - - if (bitmap[offset] & (1 << (8-i))) - { - color = p->fg_color; - } - else - { - color = p->bg_color; - } - - grub_vbe_set_pixel_index(i + (virtual_screen.cursor_x - * virtual_screen.char_width), - y + (virtual_screen.cursor_y - * virtual_screen.char_height), - color); - } - } -} - -static void -write_cursor (void) -{ - grub_uint32_t x; - grub_uint32_t y; - - for (y = ((virtual_screen.cursor_y + 1) * virtual_screen.char_height) - 3; - y < ((virtual_screen.cursor_y + 1) * virtual_screen.char_height) - 1; - y++) - { - for (x = virtual_screen.cursor_x * virtual_screen.char_width; - x < (virtual_screen.cursor_x + 1) * virtual_screen.char_width; - x++) - { - grub_vbe_set_pixel_index(x, y, 10); - } - } -} - -static void -scroll_up (void) -{ - grub_uint32_t i; - - /* Scroll text buffer with one line to up. */ - grub_memmove (virtual_screen.text_buffer, - virtual_screen.text_buffer + virtual_screen.columns, - sizeof (*virtual_screen.text_buffer) - * virtual_screen.columns - * (virtual_screen.rows - 1)); - - /* Clear last line in text buffer. */ - for (i = virtual_screen.columns * (virtual_screen.rows - 1); - i < virtual_screen.columns * virtual_screen.rows; - i++) - { - virtual_screen.text_buffer[i].code = ' '; - virtual_screen.text_buffer[i].fg_color = 0; - virtual_screen.text_buffer[i].bg_color = 0; - virtual_screen.text_buffer[i].width = 0; - virtual_screen.text_buffer[i].index = 0; - } - - /* Scroll framebuffer with one line to up. */ - grub_memmove (framebuffer, - framebuffer - + bytes_per_scan_line * virtual_screen.char_height, - bytes_per_scan_line - * (mode_info.y_resolution - virtual_screen.char_height)); - - /* Clear last line in framebuffer. */ - grub_memset (framebuffer - + (bytes_per_scan_line - * (mode_info.y_resolution - virtual_screen.char_height)), - 0, - bytes_per_scan_line * virtual_screen.char_height); -} - -static void -grub_vesafb_putchar (grub_uint32_t c) -{ - if (c == '\a') - /* FIXME */ - return; - - if (c == '\b' || c == '\n' || c == '\r') - { - /* Erase current cursor, if any. */ - if (virtual_screen.cursor_state) - write_char (); - - switch (c) - { - case '\b': - if (virtual_screen.cursor_x > 0) - virtual_screen.cursor_x--; - break; - - case '\n': - if (virtual_screen.cursor_y >= virtual_screen.rows - 1) - scroll_up (); - else - virtual_screen.cursor_y++; - break; - - case '\r': - virtual_screen.cursor_x = 0; - break; - } - - if (virtual_screen.cursor_state) - write_cursor (); - } - else - { - unsigned width; - struct grub_colored_char *p; - - grub_virtual_screen_get_glyph (c, 0, &width); - - if (virtual_screen.cursor_x + width > virtual_screen.columns) - grub_putchar ('\n'); - - p = (virtual_screen.text_buffer + - virtual_screen.cursor_x + - virtual_screen.cursor_y * virtual_screen.columns); - p->code = c; - p->fg_color = virtual_screen.fg_color; - p->bg_color = virtual_screen.bg_color; - p->width = width - 1; - p->index = 0; - - if (width > 1) - { - unsigned i; - - for (i = 1; i < width; i++) - { - p[i].code = ' '; - p[i].width = width - 1; - p[i].index = i; - } - } - - write_char (); - - virtual_screen.cursor_x += width; - if (virtual_screen.cursor_x >= virtual_screen.columns) - { - virtual_screen.cursor_x = 0; - - if (virtual_screen.cursor_y >= virtual_screen.rows - 1) - scroll_up (); - else - virtual_screen.cursor_y++; - } - - if (virtual_screen.cursor_state) - write_cursor (); - } -} - -static grub_ssize_t -grub_vesafb_getcharwidth (grub_uint32_t c) -{ - unsigned width; - - if (! grub_virtual_screen_get_glyph (c, 0, &width)) - return 0; - - return width; -} - -static grub_uint16_t -grub_virtual_screen_getwh (void) -{ - return (virtual_screen.columns << 8) | virtual_screen.rows; -} - -static grub_uint16_t -grub_virtual_screen_getxy (void) -{ - return ((virtual_screen.cursor_x << 8) | virtual_screen.cursor_y); -} - -static void -grub_vesafb_gotoxy (grub_uint8_t x, grub_uint8_t y) -{ - if (x >= virtual_screen.columns || y >= virtual_screen.rows) - { - grub_error (GRUB_ERR_OUT_OF_RANGE, "invalid point (%u,%u)", - (unsigned) x, (unsigned) y); - return; - } - - if (virtual_screen.cursor_state) - write_char (); - - virtual_screen.cursor_x = x; - virtual_screen.cursor_y = y; - - if (virtual_screen.cursor_state) - write_cursor (); -} - -static void -grub_virtual_screen_cls (void) -{ - grub_uint32_t i; - - for (i = 0; i < virtual_screen.columns * virtual_screen.rows; i++) - { - virtual_screen.text_buffer[i].code = ' '; - virtual_screen.text_buffer[i].fg_color = 0; - virtual_screen.text_buffer[i].bg_color = 0; - virtual_screen.text_buffer[i].width = 0; - virtual_screen.text_buffer[i].index = 0; - } - - virtual_screen.cursor_x = virtual_screen.cursor_y = 0; -} - -static void -grub_vesafb_cls (void) -{ - grub_virtual_screen_cls (); - - grub_memset (framebuffer, - 0, - mode_info.y_resolution * bytes_per_scan_line); -} - -static void -grub_virtual_screen_setcolorstate (grub_term_color_state state) -{ - switch (state) - { - case GRUB_TERM_COLOR_STANDARD: - case GRUB_TERM_COLOR_NORMAL: - virtual_screen.fg_color = DEFAULT_FG_COLOR; - virtual_screen.bg_color = DEFAULT_BG_COLOR; - break; - case GRUB_TERM_COLOR_HIGHLIGHT: - virtual_screen.fg_color = DEFAULT_BG_COLOR; - virtual_screen.bg_color = DEFAULT_FG_COLOR; - break; - default: - break; - } -} - -static void -grub_vesafb_setcursor (int on) -{ - if (virtual_screen.cursor_state != on) - { - if (virtual_screen.cursor_state) - write_char (); - else - write_cursor (); - - virtual_screen.cursor_state = on; - } -} - -static struct grub_term_output grub_vesafb_term = - { - .name = "vesafb", - .init = grub_vesafb_mod_init, - .fini = grub_vesafb_mod_fini, - .putchar = grub_vesafb_putchar, - .getcharwidth = grub_vesafb_getcharwidth, - .getwh = grub_virtual_screen_getwh, - .getxy = grub_virtual_screen_getxy, - .gotoxy = grub_vesafb_gotoxy, - .cls = grub_vesafb_cls, - .setcolorstate = grub_virtual_screen_setcolorstate, - .setcursor = grub_vesafb_setcursor, - .flags = 0, - }; - -GRUB_MOD_INIT(vesafb) -{ - grub_term_register_output ("vesafb", &grub_vesafb_term); -} - -GRUB_MOD_FINI(vesafb) -{ - grub_term_unregister_output (&grub_vesafb_term); -} From f84afb2775f07c5265cfae8cb57bbd9a564da4fd Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 18 Mar 2010 00:19:30 +0100 Subject: [PATCH 483/738] * kern/parser.c: Indented. --- ChangeLog | 4 ++ kern/parser.c | 140 +++++++++++++++++++++++++------------------------- 2 files changed, 74 insertions(+), 70 deletions(-) diff --git a/ChangeLog b/ChangeLog index 475d92eca..c5cab1533 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-03-18 Vladimir Serbinenko + + * kern/parser.c: Indented. + 2010-03-17 Vladimir Serbinenko * term/i386/pc/vesafb.c: Removed (orphaned, deprecated and broken). diff --git a/kern/parser.c b/kern/parser.c index dd4608ba9..80312b9b4 100644 --- a/kern/parser.c +++ b/kern/parser.c @@ -26,32 +26,31 @@ /* All the possible state transitions on the command line. If a transition can not be found, it is assumed that there is no transition and keep_value is assumed to be 1. */ -static struct grub_parser_state_transition state_transitions[] = -{ - { GRUB_PARSER_STATE_TEXT, GRUB_PARSER_STATE_QUOTE, '\'', 0}, - { GRUB_PARSER_STATE_TEXT, GRUB_PARSER_STATE_DQUOTE, '\"', 0}, - { GRUB_PARSER_STATE_TEXT, GRUB_PARSER_STATE_VAR, '$', 0}, - { GRUB_PARSER_STATE_TEXT, GRUB_PARSER_STATE_ESC, '\\', 0}, +static struct grub_parser_state_transition state_transitions[] = { + {GRUB_PARSER_STATE_TEXT, GRUB_PARSER_STATE_QUOTE, '\'', 0}, + {GRUB_PARSER_STATE_TEXT, GRUB_PARSER_STATE_DQUOTE, '\"', 0}, + {GRUB_PARSER_STATE_TEXT, GRUB_PARSER_STATE_VAR, '$', 0}, + {GRUB_PARSER_STATE_TEXT, GRUB_PARSER_STATE_ESC, '\\', 0}, - { GRUB_PARSER_STATE_ESC, GRUB_PARSER_STATE_TEXT, 0, 1}, + {GRUB_PARSER_STATE_ESC, GRUB_PARSER_STATE_TEXT, 0, 1}, - { GRUB_PARSER_STATE_QUOTE, GRUB_PARSER_STATE_TEXT, '\'', 0}, + {GRUB_PARSER_STATE_QUOTE, GRUB_PARSER_STATE_TEXT, '\'', 0}, - { GRUB_PARSER_STATE_DQUOTE, GRUB_PARSER_STATE_TEXT, '\"', 0}, - { GRUB_PARSER_STATE_DQUOTE, GRUB_PARSER_STATE_QVAR, '$', 0}, + {GRUB_PARSER_STATE_DQUOTE, GRUB_PARSER_STATE_TEXT, '\"', 0}, + {GRUB_PARSER_STATE_DQUOTE, GRUB_PARSER_STATE_QVAR, '$', 0}, - { GRUB_PARSER_STATE_VAR, GRUB_PARSER_STATE_VARNAME2, '{', 0}, - { GRUB_PARSER_STATE_VAR, GRUB_PARSER_STATE_VARNAME, 0, 1}, - { GRUB_PARSER_STATE_VARNAME, GRUB_PARSER_STATE_TEXT, ' ', 1}, - { GRUB_PARSER_STATE_VARNAME2, GRUB_PARSER_STATE_TEXT, '}', 0}, + {GRUB_PARSER_STATE_VAR, GRUB_PARSER_STATE_VARNAME2, '{', 0}, + {GRUB_PARSER_STATE_VAR, GRUB_PARSER_STATE_VARNAME, 0, 1}, + {GRUB_PARSER_STATE_VARNAME, GRUB_PARSER_STATE_TEXT, ' ', 1}, + {GRUB_PARSER_STATE_VARNAME2, GRUB_PARSER_STATE_TEXT, '}', 0}, - { GRUB_PARSER_STATE_QVAR, GRUB_PARSER_STATE_QVARNAME2, '{', 0}, - { GRUB_PARSER_STATE_QVAR, GRUB_PARSER_STATE_QVARNAME, 0, 1}, - { GRUB_PARSER_STATE_QVARNAME, GRUB_PARSER_STATE_TEXT, '\"', 0}, - { GRUB_PARSER_STATE_QVARNAME, GRUB_PARSER_STATE_DQUOTE, ' ', 1}, - { GRUB_PARSER_STATE_QVARNAME2, GRUB_PARSER_STATE_DQUOTE, '}', 0}, + {GRUB_PARSER_STATE_QVAR, GRUB_PARSER_STATE_QVARNAME2, '{', 0}, + {GRUB_PARSER_STATE_QVAR, GRUB_PARSER_STATE_QVARNAME, 0, 1}, + {GRUB_PARSER_STATE_QVARNAME, GRUB_PARSER_STATE_TEXT, '\"', 0}, + {GRUB_PARSER_STATE_QVARNAME, GRUB_PARSER_STATE_DQUOTE, ' ', 1}, + {GRUB_PARSER_STATE_QVARNAME2, GRUB_PARSER_STATE_DQUOTE, '}', 0}, - { 0, 0, 0, 0} + {0, 0, 0, 0} }; @@ -74,17 +73,17 @@ grub_parser_cmdline_state (grub_parser_state_t state, char c, char *result) if (transition->input == c) break; - if (transition->input == ' ' && ! grub_isalpha (c) - && ! grub_isdigit (c) && c != '_') + if (transition->input == ' ' && !grub_isalpha (c) + && !grub_isdigit (c) && c != '_') break; /* A less perfect match was found, use this one if no exact - match can be found. */ + match can be found. */ if (transition->input == 0) break; } - if (! transition->from_state) + if (!transition->from_state) transition = &default_transition; if (transition->keep_value) @@ -113,43 +112,44 @@ grub_parser_split_cmdline (const char *cmdline, grub_reader_getline_t getline, auto int check_varstate (grub_parser_state_t s); int check_varstate (grub_parser_state_t s) - { - return (s == GRUB_PARSER_STATE_VARNAME - || s == GRUB_PARSER_STATE_VARNAME2 - || s == GRUB_PARSER_STATE_QVARNAME - || s == GRUB_PARSER_STATE_QVARNAME2); - } + { + return (s == GRUB_PARSER_STATE_VARNAME + || s == GRUB_PARSER_STATE_VARNAME2 + || s == GRUB_PARSER_STATE_QVARNAME + || s == GRUB_PARSER_STATE_QVARNAME2); + } auto void add_var (grub_parser_state_t newstate); void add_var (grub_parser_state_t newstate) - { - char *val; + { + char *val; - /* Check if a variable was being read in and the end of the name - was reached. */ - if (! (check_varstate (state) && !check_varstate (newstate))) - return; + /* Check if a variable was being read in and the end of the name + was reached. */ + if (!(check_varstate (state) && !check_varstate (newstate))) + return; - *(vp++) = '\0'; - val = grub_env_get (varname); - vp = varname; - if (! val) - return; + *(vp++) = '\0'; + val = grub_env_get (varname); + vp = varname; + if (!val) + return; - /* Insert the contents of the variable in the buffer. */ - for (; *val; val++) - *(bp++) = *val; - } + /* Insert the contents of the variable in the buffer. */ + for (; *val; val++) + *(bp++) = *val; + } *argc = 0; do { - if (! rd || !*rd) + if (!rd || !*rd) { if (getline) getline (&rd, 1); - else break; + else + break; } if (!rd) @@ -190,7 +190,8 @@ grub_parser_split_cmdline (const char *cmdline, grub_reader_getline_t getline, } state = newstate; } - } while (state != GRUB_PARSER_STATE_TEXT && !check_varstate (state)); + } + while (state != GRUB_PARSER_STATE_TEXT && !check_varstate (state)); /* A special case for when the last character was part of a variable. */ @@ -204,12 +205,12 @@ grub_parser_split_cmdline (const char *cmdline, grub_reader_getline_t getline, /* Reserve memory for the return values. */ args = grub_malloc (bp - buffer); - if (! args) + if (!args) return grub_errno; grub_memcpy (args, buffer, bp - buffer); *argv = grub_malloc (sizeof (char *) * (*argc + 1)); - if (! *argv) + if (!*argv) { grub_free (args); return grub_errno; @@ -229,35 +230,34 @@ grub_parser_split_cmdline (const char *cmdline, grub_reader_getline_t getline, return 0; } -struct grub_handler_class grub_parser_class = - { - .name = "parser" - }; +struct grub_handler_class grub_parser_class = { + .name = "parser" +}; grub_err_t grub_parser_execute (char *source) { auto grub_err_t getline (char **line, int cont); grub_err_t getline (char **line, int cont __attribute__ ((unused))) - { - char *p; + { + char *p; - if (! source) - { - *line = 0; - return 0; - } + if (!source) + { + *line = 0; + return 0; + } - p = grub_strchr (source, '\n'); - if (p) - *p = 0; + p = grub_strchr (source, '\n'); + if (p) + *p = 0; - *line = grub_strdup (source); - if (p) - *p = '\n'; - source = p ? p + 1 : 0; - return 0; - } + *line = grub_strdup (source); + if (p) + *p = '\n'; + source = p ? p + 1 : 0; + return 0; + } while (source) { From c9f58427522fb1e8172561aea9154c32b91a43df Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 19 Mar 2010 11:28:05 +0000 Subject: [PATCH 484/738] * .bzrignore: Add gentrigtables, grub-script-check, grub_script_check_init.c, grub_script_check_init.h, and trigtables.c. --- .bzrignore | 5 +++++ ChangeLog | 6 ++++++ 2 files changed, 11 insertions(+) diff --git a/.bzrignore b/.bzrignore index 8cdc9d12d..5a1443d09 100644 --- a/.bzrignore +++ b/.bzrignore @@ -25,6 +25,7 @@ docs/version.texi *.exec genkernsyms.sh gensymlist.sh +gentrigtables grub-dumpbios grub-editenv grub-emu @@ -40,6 +41,9 @@ grub-pe2elf grub-probe grub_probe_init.c grub_probe_init.h +grub-script-check +grub_script_check_init.c +grub_script_check_init.h grub_script.tab.c grub_script.tab.h grub-setup @@ -62,4 +66,5 @@ stamp-h stamp-h1 stamp-h.in symlist.c +trigtables.c update-grub_lib diff --git a/ChangeLog b/ChangeLog index c5cab1533..6875f1afe 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-03-19 Colin Watson + + * .bzrignore: Add gentrigtables, grub-script-check, + grub_script_check_init.c, grub_script_check_init.h, and + trigtables.c. + 2010-03-18 Vladimir Serbinenko * kern/parser.c: Indented. From 0f3a3e3ece624cc267900771798069cc8e9339a5 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Sun, 21 Mar 2010 10:27:21 +0530 Subject: [PATCH 485/738] added elif patch from Deepak Vankadaru --- conf/tests.rmk | 4 ++++ script/parser.y | 34 ++++++++++++++++++++++------------ tests/grub_script_if.in | 31 +++++++++++++++++++++++++++++++ 3 files changed, 57 insertions(+), 12 deletions(-) create mode 100644 tests/grub_script_if.in diff --git a/conf/tests.rmk b/conf/tests.rmk index 92f14797d..427720e82 100644 --- a/conf/tests.rmk +++ b/conf/tests.rmk @@ -53,6 +53,9 @@ grub_script_vars1_SOURCES = tests/grub_script_vars1.in check_SCRIPTS += grub_script_for1 grub_script_for1_SOURCES = tests/grub_script_for1.in +check_SCRIPTS += grub_script_if +grub_script_if_SOURCES = tests/grub_script_if.in + # List of tests to execute on "make check" # SCRIPTED_TESTS = example_scripted_test # SCRIPTED_TESTS += example_grub_script_test @@ -63,6 +66,7 @@ SCRIPTED_TESTS = grub_script_echo1 SCRIPTED_TESTS += grub_script_echo_keywords SCRIPTED_TESTS += grub_script_vars1 SCRIPTED_TESTS += grub_script_for1 +SCRIPTED_TESTS += grub_script_if # dependencies between tests and testing-tools $(SCRIPTED_TESTS): grub-shell grub-shell-tester diff --git a/script/parser.y b/script/parser.y index caba0f433..4ed58b4f2 100644 --- a/script/parser.y +++ b/script/parser.y @@ -74,7 +74,7 @@ %token GRUB_PARSER_TOKEN_WORD "word" %type word argument arguments0 arguments1 -%type script_init script grubcmd ifcmd forcmd command +%type script_init script grubcmd ifclause ifcmd forcmd command %type commands1 menuentry statement %pure-parser @@ -224,18 +224,28 @@ menuentry: "menuentry" } ; -if: "if" { grub_script_lexer_ref (state->lexerstate); } +ifcmd: "if" + { + grub_script_lexer_ref (state->lexerstate); + } + ifclause "fi" + { + $$ = $3; + grub_script_lexer_deref (state->lexerstate); + } ; -ifcmd: if commands1 delimiters1 "then" commands1 delimiters1 "fi" - { - $$ = grub_script_create_cmdif (state, $2, $5, 0); - grub_script_lexer_deref (state->lexerstate); - } - | if commands1 delimiters1 "then" commands1 delimiters1 "else" commands1 delimiters1 "fi" - { - $$ = grub_script_create_cmdif (state, $2, $5, $8); - grub_script_lexer_deref (state->lexerstate); - } +ifclause: commands1 delimiters1 "then" commands1 delimiters1 + { + $$ = grub_script_create_cmdif (state, $1, $4, 0); + } + | commands1 delimiters1 "then" commands1 delimiters1 "else" commands1 delimiters1 + { + $$ = grub_script_create_cmdif (state, $1, $4, $7); + } + | commands1 delimiters1 "then" commands1 delimiters1 "elif" ifclause + { + $$ = grub_script_create_cmdif (state, $1, $4, $7); + } ; forcmd: "for" "name" diff --git a/tests/grub_script_if.in b/tests/grub_script_if.in new file mode 100644 index 000000000..fb17eaf70 --- /dev/null +++ b/tests/grub_script_if.in @@ -0,0 +1,31 @@ +#! @builddir@/grub-shell-tester + +#basic if, execute +if true; then echo yes; fi + +#basic if, no execution +if false; then echo no; fi + +#if else, execute if path +if true; then echo yes; else echo no; fi + +#if else, execute else path +if false; then echo no; else echo yes; fi + +#if elif, execute elif +if false; then echo no; elif true; then echo yes; fi + +#if elif else, execute else +if false; then echo no; elif false; then echo no; else echo yes; fi + +#if elif(1) elif(2), execute elif(2) +if false; then echo no; elif false; then echo no; elif true; then echo yes; fi + +#if elif(1) elif(2) else, execute else +if false; then echo no; elif false; then echo no; elif false; then echo no; else echo yes; fi + +#if {if elif else}, execute elif +if true; then if false; then echo no; elif true; then echo yes; else echo no; fi; fi + +#if {if elif} else, execute elif. ofcourse no dangling-else problem due to "fi" +if true; then if false; then echo no; elif true; then echo yes; fi; else echo no; fi From bed1d3524efa70ede47428f9a59f669188e0d2aa Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Sun, 21 Mar 2010 23:04:02 +0000 Subject: [PATCH 486/738] * util/grub-install.in: Copy .mo files from @datadir@/locale, to match where 'make install' puts them. * util/i386/efi/grub-install.in: Likewise. --- ChangeLog | 6 ++++++ util/grub-install.in | 7 ++++--- util/i386/efi/grub-install.in | 7 ++++--- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6875f1afe..55c45af87 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-03-21 Colin Watson + + * util/grub-install.in: Copy .mo files from @datadir@/locale, to + match where 'make install' puts them. + * util/i386/efi/grub-install.in: Likewise. + 2010-03-19 Colin Watson * .bzrignore: Add gentrigtables, grub-script-check, diff --git a/util/grub-install.in b/util/grub-install.in index bb323d706..872dde4a2 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -32,6 +32,7 @@ platform=@platform@ host_os=@host_os@ font=@datadir@/@PACKAGE_TARNAME@/ascii.pf2 pkglibdir=${libdir}/`echo ${PACKAGE_TARNAME}/${target_cpu}-${platform} | sed ${transform}` +localedir=@datadir@/locale grub_setup=${sbindir}/`echo grub-setup | sed ${transform}` if [ "${target_cpu}-${platform}" = "i386-pc" ] || [ "${target_cpu}-${platform}" = "sparc64-ieee1275" ] || [ "${target_cpu}-${platform}" = "mips-yeeloong" ] ; then @@ -263,9 +264,9 @@ fi # Copy gettext files mkdir -p ${grubdir}/locale/ -for file in ${grubdir}/locale/*.mo ${pkglibdir}/locale/*.mo; do - if test -f "$file"; then - cp -f "$file" ${grubdir}/locale/ +for dir in ${localedir}/*; do + if test -f "$dir/LC_MESSAGES/grub.mo"; then + cp -f "$dir/LC_MESSAGES/grub.mo" "${grubdir}/locale/${dir##*/}.mo" fi done diff --git a/util/i386/efi/grub-install.in b/util/i386/efi/grub-install.in index 6a8573e81..a97960562 100644 --- a/util/i386/efi/grub-install.in +++ b/util/i386/efi/grub-install.in @@ -31,6 +31,7 @@ target_cpu=@target_cpu@ platform=@platform@ host_os=@host_os@ pkglibdir=${libdir}/`echo ${PACKAGE_TARNAME}/${target_cpu}-${platform} | sed ${transform}` +localedir=@datadir@/locale grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}` grub_mkdevicemap=${sbindir}/`echo grub-mkdevicemap | sed ${transform}` @@ -182,9 +183,9 @@ done # Copy gettext files mkdir -p ${grubdir}/locale/ -for file in ${grubdir}/locale/*.mo ${pkglibdir}/locale/*.mo; do - if test -f "$file"; then - cp -f "$file" ${grubdir}/locale/ +for dir in ${localedir}/*; do + if test -f "$dir/LC_MESSAGES/grub.mo"; then + cp -f "$dir/LC_MESSAGES/grub.mo" "${grubdir}/locale/${dir##*/}.mo" fi done From ba4be5af25221d974e23801c3ae445d5d0d95f54 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Mon, 22 Mar 2010 13:25:09 +0530 Subject: [PATCH 487/738] fixed help message for grub-script-check --- util/grub-script-check.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/grub-script-check.c b/util/grub-script-check.c index 0acf3077f..3c0c62f20 100644 --- a/util/grub-script-check.c +++ b/util/grub-script-check.c @@ -118,7 +118,7 @@ Checks GRUB script configuration file for syntax errors.\n\ \n\ -h, --help display this message and exit\n\ -V, --version print version information and exit\n\ - -v, --verbose print script being processed\n\ + -v, --verbose print the script as it is being processed\n\ \n\ Report bugs to <%s>.\n\ ", program_name, From 8507a6ccdf7442fdac4344577007d238ddcdb6f7 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Mon, 22 Mar 2010 13:54:45 +0530 Subject: [PATCH 488/738] testcase for blanklines in grub script --- conf/tests.rmk | 4 ++++ tests/grub_script_blanklines.in | 14 ++++++++++++++ 2 files changed, 18 insertions(+) create mode 100644 tests/grub_script_blanklines.in diff --git a/conf/tests.rmk b/conf/tests.rmk index c5080f58c..47dea7fb1 100644 --- a/conf/tests.rmk +++ b/conf/tests.rmk @@ -50,6 +50,9 @@ grub_script_echo_keywords_SOURCES = tests/grub_script_echo_keywords.in check_SCRIPTS += grub_script_vars1 grub_script_vars1_SOURCES = tests/grub_script_vars1.in +check_SCRIPTS += grub_script_blanklines +grub_script_blanklines_SOURCES = tests/grub_script_blanklines.in + # List of tests to execute on "make check" # SCRIPTED_TESTS = example_scripted_test # SCRIPTED_TESTS += example_grub_script_test @@ -59,6 +62,7 @@ grub_script_vars1_SOURCES = tests/grub_script_vars1.in SCRIPTED_TESTS = grub_script_echo1 SCRIPTED_TESTS += grub_script_echo_keywords SCRIPTED_TESTS += grub_script_vars1 +SCRIPTED_TESTS += grub_script_blanklines # dependencies between tests and testing-tools $(SCRIPTED_TESTS): grub-shell grub-shell-tester diff --git a/tests/grub_script_blanklines.in b/tests/grub_script_blanklines.in new file mode 100644 index 000000000..71b869bd3 --- /dev/null +++ b/tests/grub_script_blanklines.in @@ -0,0 +1,14 @@ +#! /bin/sh -e + +@builddir@/grub-script-check < Date: Mon, 22 Mar 2010 14:02:48 +0530 Subject: [PATCH 489/738] testcase for the last semicolon behavior --- conf/tests.rmk | 4 ++++ tests/grub_script_final_semicolon.in | 10 ++++++++++ 2 files changed, 14 insertions(+) create mode 100644 tests/grub_script_final_semicolon.in diff --git a/conf/tests.rmk b/conf/tests.rmk index c5080f58c..fdf554a15 100644 --- a/conf/tests.rmk +++ b/conf/tests.rmk @@ -50,6 +50,9 @@ grub_script_echo_keywords_SOURCES = tests/grub_script_echo_keywords.in check_SCRIPTS += grub_script_vars1 grub_script_vars1_SOURCES = tests/grub_script_vars1.in +check_SCRIPTS += grub_script_final_semicolon +grub_script_final_semicolon_SOURCES = tests/grub_script_final_semicolon.in + # List of tests to execute on "make check" # SCRIPTED_TESTS = example_scripted_test # SCRIPTED_TESTS += example_grub_script_test @@ -59,6 +62,7 @@ grub_script_vars1_SOURCES = tests/grub_script_vars1.in SCRIPTED_TESTS = grub_script_echo1 SCRIPTED_TESTS += grub_script_echo_keywords SCRIPTED_TESTS += grub_script_vars1 +SCRIPTED_TESTS += grub_script_final_semicolon # dependencies between tests and testing-tools $(SCRIPTED_TESTS): grub-shell grub-shell-tester diff --git a/tests/grub_script_final_semicolon.in b/tests/grub_script_final_semicolon.in new file mode 100644 index 000000000..99e55e545 --- /dev/null +++ b/tests/grub_script_final_semicolon.in @@ -0,0 +1,10 @@ +#! /bin/sh -e + +@builddir@/grub-script-check < Date: Mon, 22 Mar 2010 14:03:20 +0530 Subject: [PATCH 490/738] fix for grub_script_final_semicolon test --- script/parser.y | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script/parser.y b/script/parser.y index baf1fd9b5..e8a4cdd2c 100644 --- a/script/parser.y +++ b/script/parser.y @@ -92,7 +92,7 @@ script: newlines0 { $$ = 0; } - | script statement delimiter + | script statement delimiter newlines0 { struct grub_script_cmdblock *cmdblock; cmdblock = (struct grub_script_cmdblock *) $1; From 21b9992685e4fa58f818610b6b13c22cb2f85ec7 Mon Sep 17 00:00:00 2001 From: <> Date: Wed, 24 Mar 2010 12:50:15 +0000 Subject: [PATCH 491/738] * .bzrignore: Add grub-bin2h, grub-reboot, and grub-set-default. --- .bzrignore | 3 +++ ChangeLog | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/.bzrignore b/.bzrignore index 5a1443d09..46e8637b6 100644 --- a/.bzrignore +++ b/.bzrignore @@ -26,6 +26,7 @@ docs/version.texi genkernsyms.sh gensymlist.sh gentrigtables +grub-bin2h grub-dumpbios grub-editenv grub-emu @@ -41,11 +42,13 @@ grub-pe2elf grub-probe grub_probe_init.c grub_probe_init.h +grub-reboot grub-script-check grub_script_check_init.c grub_script_check_init.h grub_script.tab.c grub_script.tab.h +grub-set-default grub-setup grub_setup_init.c grub_setup_init.h diff --git a/ChangeLog b/ChangeLog index 55c45af87..6bb82215a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-03-24 Colin Watson + + * .bzrignore: Add grub-bin2h, grub-reboot, and grub-set-default. + 2010-03-21 Colin Watson * util/grub-install.in: Copy .mo files from @datadir@/locale, to From a3940f887483f4b92c1d9204fd40b3a5e80d6bf8 Mon Sep 17 00:00:00 2001 From: Adrian Glaubitz Date: Wed, 24 Mar 2010 12:54:39 +0000 Subject: [PATCH 492/738] * kern/dl.c (grub_dl_resolve_symbols): Improve error message grammar. --- ChangeLog | 5 +++++ kern/dl.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 6bb82215a..e3e39b84a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-03-24 Adrian Glaubitz + + * kern/dl.c (grub_dl_resolve_symbols): Improve error message + grammar. + 2010-03-24 Colin Watson * .bzrignore: Add grub-bin2h, grub-reboot, and grub-set-default. diff --git a/kern/dl.c b/kern/dl.c index 278d5b568..19ee13243 100644 --- a/kern/dl.c +++ b/kern/dl.c @@ -348,7 +348,7 @@ grub_dl_resolve_symbols (grub_dl_t mod, Elf_Ehdr *e) sym->st_value = (Elf_Addr) grub_dl_resolve_symbol (name); if (! sym->st_value) return grub_error (GRUB_ERR_BAD_MODULE, - "the symbol `%s' not found", name); + "symbol not found: `%s'", name); } else { From d85da27cc0e1e670abee72758836f633cd52b297 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 26 Mar 2010 19:14:24 +0100 Subject: [PATCH 493/738] Remove grub_commands_iterate --- commands/help.c | 145 ++++++++++++++++++++--------------------- include/grub/command.h | 7 +- normal/completion.c | 29 ++++----- 3 files changed, 82 insertions(+), 99 deletions(-) diff --git a/commands/help.c b/commands/help.c index 1181c3bfb..ecf77fa4c 100644 --- a/commands/help.c +++ b/commands/help.c @@ -33,94 +33,87 @@ grub_cmd_help (grub_extcmd_t ext __attribute__ ((unused)), int argc, int cnt = 0; char *currarg; - auto int print_command_info (grub_command_t cmd); - auto int print_command_help (grub_command_t cmd); - - int print_command_info (grub_command_t cmd) - { - if ((cmd->prio & GRUB_PRIO_LIST_FLAG_ACTIVE) && - (cmd->flags & GRUB_COMMAND_FLAG_CMDLINE)) - { - struct grub_term_output *term; - const char *summary_translated = _(cmd->summary); - char *command_help; - grub_uint32_t *unicode_command_help; - grub_uint32_t *unicode_last_position; - - command_help = grub_xasprintf ("%s %s", cmd->name, summary_translated); - if (!command_help) - return 1; - - grub_utf8_to_ucs4_alloc (command_help, &unicode_command_help, - &unicode_last_position); - - FOR_ACTIVE_TERM_OUTPUTS(term) - { - unsigned stringwidth; - grub_uint32_t *unicode_last_screen_position; - - unicode_last_screen_position = unicode_command_help; - - stringwidth = 0; - - while (unicode_last_screen_position < unicode_last_position && - stringwidth < ((grub_term_width (term) / 2) - 2)) - { - stringwidth - += grub_term_getcharwidth (term, - *unicode_last_screen_position); - unicode_last_screen_position++; - } - - grub_print_ucs4 (unicode_command_help, - unicode_last_screen_position, term); - if (!(cnt % 2)) - grub_print_spaces (term, grub_term_width (term) / 2 - - stringwidth); - } - if (cnt % 2) - grub_printf ("\n"); - cnt++; - - grub_free (command_help); - grub_free (unicode_command_help); - } - return 0; - } - - int print_command_help (grub_command_t cmd) - { - if (cmd->prio & GRUB_PRIO_LIST_FLAG_ACTIVE) - { - if (! grub_strncmp (cmd->name, currarg, grub_strlen (currarg))) - { - if (cnt++ > 0) - grub_printf ("\n\n"); - - if (cmd->flags & GRUB_COMMAND_FLAG_EXTCMD) - grub_arg_show_help ((grub_extcmd_t) cmd->data); - else - grub_printf ("%s %s %s\n%s\b", _("Usage:"), cmd->name, _(cmd->summary), - _(cmd->description)); - } - } - return 0; - } - if (argc == 0) { - grub_command_iterate (print_command_info); + grub_command_t cmd; + FOR_COMMANDS(cmd) + { + if ((cmd->prio & GRUB_PRIO_LIST_FLAG_ACTIVE) && + (cmd->flags & GRUB_COMMAND_FLAG_CMDLINE)) + { + struct grub_term_output *term; + const char *summary_translated = _(cmd->summary); + char *command_help; + grub_uint32_t *unicode_command_help; + grub_uint32_t *unicode_last_position; + + command_help = grub_xasprintf ("%s %s", cmd->name, summary_translated); + if (!command_help) + break; + + grub_utf8_to_ucs4_alloc (command_help, &unicode_command_help, + &unicode_last_position); + + FOR_ACTIVE_TERM_OUTPUTS(term) + { + unsigned stringwidth; + grub_uint32_t *unicode_last_screen_position; + + unicode_last_screen_position = unicode_command_help; + + stringwidth = 0; + + while (unicode_last_screen_position < unicode_last_position && + stringwidth < ((grub_term_width (term) / 2) - 2)) + { + stringwidth + += grub_term_getcharwidth (term, + *unicode_last_screen_position); + unicode_last_screen_position++; + } + + grub_print_ucs4 (unicode_command_help, + unicode_last_screen_position, term); + if (!(cnt % 2)) + grub_print_spaces (term, grub_term_width (term) / 2 + - stringwidth); + } + if (cnt % 2) + grub_printf ("\n"); + cnt++; + + grub_free (command_help); + grub_free (unicode_command_help); + } + } if (!(cnt % 2)) grub_printf ("\n"); } else { int i; + grub_command_t cmd; for (i = 0; i < argc; i++) { currarg = args[i]; - grub_command_iterate (print_command_help); + FOR_COMMANDS(cmd) + { + if (cmd->prio & GRUB_PRIO_LIST_FLAG_ACTIVE) + { + if (! grub_strncmp (cmd->name, currarg, grub_strlen (currarg))) + { + if (cnt++ > 0) + grub_printf ("\n\n"); + + if (cmd->flags & GRUB_COMMAND_FLAG_EXTCMD) + grub_arg_show_help ((grub_extcmd_t) cmd->data); + else + grub_printf ("%s %s %s\n%s\b", _("Usage:"), cmd->name, _(cmd->summary), + _(cmd->description)); + } + } + } } } diff --git a/include/grub/command.h b/include/grub/command.h index 6e9942b60..3fad88ed0 100644 --- a/include/grub/command.h +++ b/include/grub/command.h @@ -115,12 +115,7 @@ grub_command_execute (const char *name, int argc, char **argv) return (cmd) ? cmd->func (cmd, argc, argv) : GRUB_ERR_FILE_NOT_FOUND; } -static inline int -grub_command_iterate (int (*func) (grub_command_t)) -{ - return grub_list_iterate (GRUB_AS_LIST (grub_command_list), - (grub_list_hook_t) func); -} +#define FOR_COMMANDS(var) for ((var) = grub_command_list; (var); (var) = (var)->next) void grub_register_core_commands (void); diff --git a/normal/completion.c b/normal/completion.c index 13e8f7a6b..13c4b7b05 100644 --- a/normal/completion.c +++ b/normal/completion.c @@ -176,21 +176,6 @@ iterate_dev (const char *devname) return 0; } -static int -iterate_command (grub_command_t cmd) -{ - if (cmd->prio & GRUB_PRIO_LIST_FLAG_ACTIVE) - { - if (cmd->flags & GRUB_COMMAND_FLAG_CMDLINE) - { - if (add_completion (cmd->name, " ", GRUB_COMPLETION_TYPE_COMMAND)) - return 1; - } - } - - return 0; -} - /* Complete a device. */ static int complete_device (void) @@ -421,8 +406,18 @@ grub_normal_do_completion (char *buf, int *restore, if (argc == 1 || argc == 0) { /* Complete a command. */ - if (grub_command_iterate (iterate_command)) - goto fail; + grub_command_t cmd; + FOR_COMMANDS(cmd) + { + if (cmd->prio & GRUB_PRIO_LIST_FLAG_ACTIVE) + { + if (cmd->flags & GRUB_COMMAND_FLAG_CMDLINE) + { + if (add_completion (cmd->name, " ", GRUB_COMPLETION_TYPE_COMMAND)) + goto fail; + } + } + } } else if (*current_word == '-') { From fbc5a383e2742ffdf166ddcd98e12e87999aecf4 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 26 Mar 2010 19:18:19 +0100 Subject: [PATCH 494/738] Remove list_iterate usage auth.c --- normal/auth.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/normal/auth.c b/normal/auth.c index 156b84c37..6d475cc0a 100644 --- a/normal/auth.c +++ b/normal/auth.c @@ -133,25 +133,24 @@ static int is_authenticated (const char *userlist) { const char *superusers; - - auto int hook (grub_list_t item); - int hook (grub_list_t item) - { - const char *name; - if (!((struct grub_auth_user *) item)->authenticated) - return 0; - name = ((struct grub_auth_user *) item)->name; - - return (userlist && grub_strword (userlist, name)) - || grub_strword (superusers, name); - } + struct grub_auth_user *user; superusers = grub_env_get ("superusers"); if (!superusers) return 1; - return grub_list_iterate (GRUB_AS_LIST (users), hook); + for (user = users; user; user = user->next) + { + if (!(user->authenticated)) + continue; + + if ((userlist && grub_strword (userlist, user->name)) + || grub_strword (superusers, user->name)) + return 1; + } + + return 0; } static int From 2aa6398b64430fc5235361b69efbae56e0188aec Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 26 Mar 2010 19:21:01 +0100 Subject: [PATCH 495/738] Remove second part of list_iterate usage auth.c --- normal/auth.c | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/normal/auth.c b/normal/auth.c index 6d475cc0a..87337afda 100644 --- a/normal/auth.c +++ b/normal/auth.c @@ -204,22 +204,7 @@ grub_auth_check_authentication (const char *userlist) grub_err_t err; static unsigned long punishment_delay = 1; char entered[GRUB_AUTH_MAX_PASSLEN]; - - auto int hook (grub_list_t item); - int hook (grub_list_t item) - { - if (grub_strcmp (login, ((struct grub_auth_user *) item)->name) == 0) - cur = (struct grub_auth_user *) item; - return 0; - } - - auto int hook_any (grub_list_t item); - int hook_any (grub_list_t item) - { - if (((struct grub_auth_user *) item)->callback) - cur = (struct grub_auth_user *) item; - return 0; - } + struct grub_auth_user *user; grub_memset (login, 0, sizeof (login)); @@ -239,7 +224,11 @@ grub_auth_check_authentication (const char *userlist) if (!grub_password_get (entered, GRUB_AUTH_MAX_PASSLEN)) goto access_denied; - grub_list_iterate (GRUB_AS_LIST (users), hook); + for (user = users; user; user = user->next) + { + if (grub_strcmp (login, user->name) == 0) + cur = user; + } if (!cur || ! cur->callback) goto access_denied; From 7c0ab99bd2095fdd081e5c627727a3c878b35409 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 26 Mar 2010 19:23:19 +0100 Subject: [PATCH 496/738] Remove list_iterate usage functional_test.c --- tests/lib/functional_test.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/tests/lib/functional_test.c b/tests/lib/functional_test.c index 8ff08cf8a..33eeec451 100644 --- a/tests/lib/functional_test.c +++ b/tests/lib/functional_test.c @@ -26,15 +26,10 @@ grub_functional_test (struct grub_extcmd *cmd __attribute__ ((unused)), int argc __attribute__ ((unused)), char **args __attribute__ ((unused))) { - auto int run_test (grub_test_t test); - int run_test (grub_test_t test) - { - grub_test_run (test); - return 0; - } + grub_test_t test; - grub_list_iterate (GRUB_AS_LIST (grub_test_list), - (grub_list_hook_t) run_test); + for (test = grub_test_list; test; test = test->next) + grub_test_run (test); return GRUB_ERR_NONE; } From 42ca71ca47cbd9b83c9febee2a6a1950c0fcd58f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 26 Mar 2010 19:25:53 +0100 Subject: [PATCH 497/738] FOR_LIST_ELEMENTS convenience macros --- include/grub/list.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/grub/list.h b/include/grub/list.h index 5559158dc..1c00a349e 100644 --- a/include/grub/list.h +++ b/include/grub/list.h @@ -40,6 +40,8 @@ int EXPORT_FUNC(grub_list_iterate) (grub_list_t head, grub_list_hook_t hook); void EXPORT_FUNC(grub_list_insert) (grub_list_t *head, grub_list_t item, grub_list_test_t test); +#define FOR_LIST_ELEMENTS(var, list) for ((var) = (list); (var); (var) = (var)->next) + static inline void * grub_bad_type_cast_real (int line, const char *file) ATTRIBUTE_ERROR ("bad type cast between incompatible grub types"); From 3f8ae91c0913ec34baea73adb4368a44a41e9416 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 26 Mar 2010 19:32:21 +0100 Subject: [PATCH 498/738] Use FOR_LIST_ELEMENTS convenience macros --- include/grub/command.h | 2 +- include/grub/partition.h | 2 +- include/grub/term.h | 8 ++++---- normal/auth.c | 2 +- tests/lib/functional_test.c | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/include/grub/command.h b/include/grub/command.h index 3fad88ed0..6bd3d07c9 100644 --- a/include/grub/command.h +++ b/include/grub/command.h @@ -115,7 +115,7 @@ grub_command_execute (const char *name, int argc, char **argv) return (cmd) ? cmd->func (cmd, argc, argv) : GRUB_ERR_FILE_NOT_FOUND; } -#define FOR_COMMANDS(var) for ((var) = grub_command_list; (var); (var) = (var)->next) +#define FOR_COMMANDS(var) FOR_LIST_ELEMENTS((var), grub_command_list) void grub_register_core_commands (void); diff --git a/include/grub/partition.h b/include/grub/partition.h index 80a9c15f0..722c7b3e0 100644 --- a/include/grub/partition.h +++ b/include/grub/partition.h @@ -91,7 +91,7 @@ grub_partition_map_unregister (grub_partition_map_t partmap) GRUB_AS_LIST (partmap)); } -#define FOR_PARTITION_MAPS(var) for (var = grub_partition_map_list; var; var = var->next) +#define FOR_PARTITION_MAPS(var) FOR_LIST_ELEMENTS((var), (grub_partition_map_list)) static inline grub_disk_addr_t diff --git a/include/grub/term.h b/include/grub/term.h index 143aabe1e..230436388 100644 --- a/include/grub/term.h +++ b/include/grub/term.h @@ -245,10 +245,10 @@ grub_term_unregister_output (grub_term_output_t term) GRUB_AS_LIST (term)); } -#define FOR_ACTIVE_TERM_INPUTS(var) for (var = grub_term_inputs; var; var = var->next) -#define FOR_DISABLED_TERM_INPUTS(var) for (var = grub_term_inputs_disabled; var; var = var->next) -#define FOR_ACTIVE_TERM_OUTPUTS(var) for (var = grub_term_outputs; var; var = var->next) -#define FOR_DISABLED_TERM_OUTPUTS(var) for (var = grub_term_outputs_disabled; var; var = var->next) +#define FOR_ACTIVE_TERM_INPUTS(var) FOR_LIST_ELEMENTS((var), (grub_term_inputs)) +#define FOR_DISABLED_TERM_INPUTS(var) FOR_LIST_ELEMENTS((var), (grub_term_inputs_disabled)) +#define FOR_ACTIVE_TERM_OUTPUTS(var) FOR_LIST_ELEMENTS((var), (grub_term_outputs)) +#define FOR_DISABLED_TERM_OUTPUTS(var) FOR_LIST_ELEMENTS((var), (grub_term_outputs_disabled)) void EXPORT_FUNC(grub_putchar) (int c); void EXPORT_FUNC(grub_putcode) (grub_uint32_t code, diff --git a/normal/auth.c b/normal/auth.c index 87337afda..c28f50024 100644 --- a/normal/auth.c +++ b/normal/auth.c @@ -140,7 +140,7 @@ is_authenticated (const char *userlist) if (!superusers) return 1; - for (user = users; user; user = user->next) + FOR_LIST_ELEMENTS (user, users) { if (!(user->authenticated)) continue; diff --git a/tests/lib/functional_test.c b/tests/lib/functional_test.c index 33eeec451..6aafe4dbb 100644 --- a/tests/lib/functional_test.c +++ b/tests/lib/functional_test.c @@ -28,7 +28,7 @@ grub_functional_test (struct grub_extcmd *cmd __attribute__ ((unused)), { grub_test_t test; - for (test = grub_test_list; test; test = test->next) + FOR_LIST_ELEMENTS (test, grub_test_list) grub_test_run (test); return GRUB_ERR_NONE; } From 41e12098274d28183aa5f46d0c26863383f5b26d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 26 Mar 2010 19:35:34 +0100 Subject: [PATCH 499/738] Remove list_iterate usage tests/ --- tests/lib/test.c | 20 +++++++------------- tests/lib/unit_test.c | 12 ++++-------- 2 files changed, 11 insertions(+), 21 deletions(-) diff --git a/tests/lib/test.c b/tests/lib/test.c index b5c054370..3029495c6 100644 --- a/tests/lib/test.c +++ b/tests/lib/test.c @@ -134,23 +134,17 @@ grub_test_unregister (const char *name) int grub_test_run (grub_test_t test) { - auto int print_failure (grub_test_failure_t item); - int print_failure (grub_test_failure_t item) - { - grub_test_failure_t failure = (grub_test_failure_t) item; - - grub_printf (" %s:%s:%u: %s\n", - (failure->file ? : ""), - (failure->funp ? : ""), - failure->line, (failure->message ? : "")); - return 0; - } + grub_test_failure_t failure; test->main (); grub_printf ("%s:\n", test->name); - grub_list_iterate (GRUB_AS_LIST (failure_list), - (grub_list_hook_t) print_failure); + FOR_LIST_ELEMENTS (failure, failure_list) + grub_printf (" %s:%s:%u: %s\n", + (failure->file ? : ""), + (failure->funp ? : ""), + failure->line, (failure->message ? : "")); + if (!failure_list) grub_printf ("%s: PASS\n", test->name); else diff --git a/tests/lib/unit_test.c b/tests/lib/unit_test.c index e461150de..e8b97b1f4 100644 --- a/tests/lib/unit_test.c +++ b/tests/lib/unit_test.c @@ -34,16 +34,12 @@ main (int argc __attribute__ ((unused)), extern void grub_unit_test_init (void); extern void grub_unit_test_fini (void); - auto int run_test (grub_test_t test); - int run_test (grub_test_t test) - { - status = grub_test_run (test) ? : status; - return 0; - } + grub_test_t test; grub_unit_test_init (); - grub_list_iterate (GRUB_AS_LIST (grub_test_list), - (grub_list_hook_t) run_test); + FOR_LIST_ELEMENTS (test, grub_test_list) + status = grub_test_run (test) ? : status; + grub_unit_test_fini (); exit (status); From fda282327f5c373d2c4ffd8c2b3080d09d742af8 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 26 Mar 2010 19:44:18 +0100 Subject: [PATCH 500/738] Complete eradication of grub_list_iterate --- commands/handler.c | 30 ++++++++++++++++-------------- include/grub/list.h | 1 - kern/list.c | 31 +++++-------------------------- normal/handler.c | 42 ++++++++++++++++-------------------------- 4 files changed, 37 insertions(+), 67 deletions(-) diff --git a/commands/handler.c b/commands/handler.c index f9270972b..2bfa67415 100644 --- a/commands/handler.c +++ b/commands/handler.c @@ -32,21 +32,17 @@ grub_cmd_handler (struct grub_command *cmd __attribute__ ((unused)), void *curr_item = 0; grub_handler_class_t head; - auto int list_item (grub_named_list_t item); - int list_item (grub_named_list_t item) - { - if (item == curr_item) - grub_putchar ('*'); - - grub_printf ("%s\n", item->name); - - return 0; - } - head = grub_handler_class_list; if (argc == 0) { - grub_list_iterate (GRUB_AS_LIST (head), (grub_list_hook_t) list_item); + grub_handler_class_t item; + FOR_LIST_ELEMENTS(item, head) + { + if (item == curr_item) + grub_putchar ('*'); + + grub_printf ("%s\n", item->name); + } } else { @@ -63,9 +59,15 @@ grub_cmd_handler (struct grub_command *cmd __attribute__ ((unused)), if (argc == 0) { + grub_handler_class_t item; curr_item = class->cur_handler; - grub_list_iterate (GRUB_AS_LIST (class->handler_list), - (grub_list_hook_t) list_item); + FOR_LIST_ELEMENTS(item, head) + { + if (item == curr_item) + grub_putchar ('*'); + + grub_printf ("%s\n", item->name); + } } else { diff --git a/include/grub/list.h b/include/grub/list.h index 1c00a349e..2fd418aca 100644 --- a/include/grub/list.h +++ b/include/grub/list.h @@ -36,7 +36,6 @@ typedef int (*grub_list_test_t) (grub_list_t new_item, grub_list_t item); void EXPORT_FUNC(grub_list_push) (grub_list_t *head, grub_list_t item); void * EXPORT_FUNC(grub_list_pop) (grub_list_t *head); void EXPORT_FUNC(grub_list_remove) (grub_list_t *head, grub_list_t item); -int EXPORT_FUNC(grub_list_iterate) (grub_list_t head, grub_list_hook_t hook); void EXPORT_FUNC(grub_list_insert) (grub_list_t *head, grub_list_t item, grub_list_test_t test); diff --git a/kern/list.c b/kern/list.c index 379b0d886..507d13f86 100644 --- a/kern/list.c +++ b/kern/list.c @@ -53,18 +53,6 @@ grub_list_remove (grub_list_t *head, grub_list_t item) } } -int -grub_list_iterate (grub_list_t head, grub_list_hook_t hook) -{ - grub_list_t p; - - for (p = head; p; p = p->next) - if (hook (p)) - return 1; - - return 0; -} - void grub_list_insert (grub_list_t *head, grub_list_t item, grub_list_test_t test) @@ -82,22 +70,13 @@ grub_list_insert (grub_list_t *head, grub_list_t item, void * grub_named_list_find (grub_named_list_t head, const char *name) { - grub_named_list_t result = NULL; + grub_named_list_t item; - auto int list_find (grub_named_list_t item); - int list_find (grub_named_list_t item) - { - if (! grub_strcmp (item->name, name)) - { - result = item; - return 1; - } + FOR_LIST_ELEMENTS (item, head) + if (grub_strcmp (item->name, name) == 0) + return item; - return 0; - } - - grub_list_iterate (GRUB_AS_LIST (head), (grub_list_hook_t) list_find); - return result; + return NULL; } void diff --git a/normal/handler.c b/normal/handler.c index 686626929..8c97fd9a8 100644 --- a/normal/handler.c +++ b/normal/handler.c @@ -138,30 +138,6 @@ read_handler_list (void) static int first_time = 1; const char *class_name; - auto int iterate_handler (grub_handler_t handler); - int iterate_handler (grub_handler_t handler) - { - char name[grub_strlen (class_name) + grub_strlen (handler->name) + 2]; - - grub_strcpy (name, class_name); - grub_strcat (name, "."); - grub_strcat (name, handler->name); - - insert_handler (name, 0); - - return 0; - } - - auto int iterate_class (grub_handler_class_t class); - int iterate_class (grub_handler_class_t class) - { - class_name = class->name; - grub_list_iterate (GRUB_AS_LIST (class->handler_list), - (grub_list_hook_t) iterate_handler); - - return 0; - } - /* Make sure that this function does not get executed twice. */ if (! first_time) return; @@ -209,8 +185,22 @@ read_handler_list (void) } } - grub_list_iterate (GRUB_AS_LIST (grub_handler_class_list), - (grub_list_hook_t) iterate_class); + grub_handler_class_t class; + FOR_LIST_ELEMENTS (class, grub_handler_class_list) + { + grub_handler_t handler; + class_name = class->name; + FOR_LIST_ELEMENTS(handler, class->handler_list) + { + char name[grub_strlen (class_name) + grub_strlen (handler->name) + 2]; + + grub_strcpy (name, class_name); + grub_strcat (name, "."); + grub_strcat (name, handler->name); + + insert_handler (name, 0); + } + } /* Ignore errors. */ grub_errno = GRUB_ERR_NONE; From 82f542016ebd7bd31ce2b74085b22e5f4ead49af Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 26 Mar 2010 20:00:06 +0100 Subject: [PATCH 501/738] Eradicate grub_list_insert --- include/grub/list.h | 2 -- kern/list.c | 39 ++++++++++++++------------------------- 2 files changed, 14 insertions(+), 27 deletions(-) diff --git a/include/grub/list.h b/include/grub/list.h index 2fd418aca..73d51be12 100644 --- a/include/grub/list.h +++ b/include/grub/list.h @@ -36,8 +36,6 @@ typedef int (*grub_list_test_t) (grub_list_t new_item, grub_list_t item); void EXPORT_FUNC(grub_list_push) (grub_list_t *head, grub_list_t item); void * EXPORT_FUNC(grub_list_pop) (grub_list_t *head); void EXPORT_FUNC(grub_list_remove) (grub_list_t *head, grub_list_t item); -void EXPORT_FUNC(grub_list_insert) (grub_list_t *head, grub_list_t item, - grub_list_test_t test); #define FOR_LIST_ELEMENTS(var, list) for ((var) = (list); (var); (var) = (var)->next) diff --git a/kern/list.c b/kern/list.c index 507d13f86..5b0248129 100644 --- a/kern/list.c +++ b/kern/list.c @@ -53,20 +53,6 @@ grub_list_remove (grub_list_t *head, grub_list_t item) } } -void -grub_list_insert (grub_list_t *head, grub_list_t item, - grub_list_test_t test) -{ - grub_list_t *p, q; - - for (p = head, q = *p; q; p = &(q->next), q = q->next) - if (test (item, q)) - break; - - *p = item; - item->next = q; -} - void * grub_named_list_find (grub_named_list_t head, const char *name) { @@ -84,27 +70,30 @@ grub_prio_list_insert (grub_prio_list_t *head, grub_prio_list_t nitem) { int inactive = 0; - auto int test (grub_prio_list_t new_item, grub_prio_list_t item); - int test (grub_prio_list_t new_item, grub_prio_list_t item) + grub_prio_list_t *p, q; + + for (p = head, q = *p; q; p = &(q->next), q = q->next) { int r; - r = grub_strcmp (new_item->name, item->name); - if (r) - return (r < 0); + r = grub_strcmp (nitem->name, q->name); + if (r < 0) + break; + if (r > 0) + continue; - if (new_item->prio >= (item->prio & GRUB_PRIO_LIST_PRIO_MASK)) + if (nitem->prio >= (q->prio & GRUB_PRIO_LIST_PRIO_MASK)) { - item->prio &= ~GRUB_PRIO_LIST_FLAG_ACTIVE; - return 1; + q->prio &= ~GRUB_PRIO_LIST_FLAG_ACTIVE; + break; } inactive = 1; - return 0; } - grub_list_insert (GRUB_AS_LIST_P (head), GRUB_AS_LIST (nitem), - (grub_list_test_t) test); + *p = nitem; + nitem->next = q; + if (! inactive) nitem->prio |= GRUB_PRIO_LIST_FLAG_ACTIVE; } From 8cfa78770df70c60637fddc12749b256382eca7d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 26 Mar 2010 20:05:25 +0100 Subject: [PATCH 502/738] cleanup list.h a bit --- include/grub/list.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/include/grub/list.h b/include/grub/list.h index 73d51be12..d3abd69c4 100644 --- a/include/grub/list.h +++ b/include/grub/list.h @@ -30,9 +30,6 @@ struct grub_list }; typedef struct grub_list *grub_list_t; -typedef int (*grub_list_hook_t) (grub_list_t item); -typedef int (*grub_list_test_t) (grub_list_t new_item, grub_list_t item); - void EXPORT_FUNC(grub_list_push) (grub_list_t *head, grub_list_t item); void * EXPORT_FUNC(grub_list_pop) (grub_list_t *head); void EXPORT_FUNC(grub_list_remove) (grub_list_t *head, grub_list_t item); From 0959e5ec30d629f661129bbaf4dfed8c41c7a5d9 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 26 Mar 2010 20:20:52 +0100 Subject: [PATCH 503/738] Remove grub_list_pop --- gettext/gettext.c | 10 +++------- include/grub/list.h | 1 - kern/list.c | 12 ------------ normal/handler.c | 8 +++++--- tests/lib/test.c | 4 +++- 5 files changed, 11 insertions(+), 24 deletions(-) diff --git a/gettext/gettext.c b/gettext/gettext.c index 0aa8decbd..bc7d42824 100644 --- a/gettext/gettext.c +++ b/gettext/gettext.c @@ -309,14 +309,10 @@ grub_gettext_init_ext (const char *lang) static void grub_gettext_delete_list (void) { - struct grub_gettext_msg *item; - - while ((item = - grub_list_pop (GRUB_AS_LIST_P (&grub_gettext_msg_list))) != 0) + while (grub_gettext_msg_list) { - char *original = (char *) ((struct grub_gettext_msg *) item)->name; - grub_free (original); - + grub_free ((char *) grub_gettext_msg_list->name); + grub_gettext_msg_list = grub_gettext_msg_list->next; /* Don't delete the translated message because could be in use. */ } } diff --git a/include/grub/list.h b/include/grub/list.h index d3abd69c4..75353010c 100644 --- a/include/grub/list.h +++ b/include/grub/list.h @@ -31,7 +31,6 @@ struct grub_list typedef struct grub_list *grub_list_t; void EXPORT_FUNC(grub_list_push) (grub_list_t *head, grub_list_t item); -void * EXPORT_FUNC(grub_list_pop) (grub_list_t *head); void EXPORT_FUNC(grub_list_remove) (grub_list_t *head, grub_list_t item); #define FOR_LIST_ELEMENTS(var, list) for ((var) = (list); (var); (var) = (var)->next) diff --git a/kern/list.c b/kern/list.c index 5b0248129..33c334166 100644 --- a/kern/list.c +++ b/kern/list.c @@ -28,18 +28,6 @@ grub_list_push (grub_list_t *head, grub_list_t item) *head = item; } -void * -grub_list_pop (grub_list_t *head) -{ - grub_list_t item; - - item = *head; - if (item) - *head = item->next; - - return item; -} - void grub_list_remove (grub_list_t *head, grub_list_t item) { diff --git a/normal/handler.c b/normal/handler.c index 8c97fd9a8..4c8b8f769 100644 --- a/normal/handler.c +++ b/normal/handler.c @@ -33,7 +33,7 @@ struct grub_handler_list grub_command_t cmd; }; -static grub_list_t handler_list; +static struct grub_handler_list *handler_list; static grub_err_t grub_handler_cmd (struct grub_command *cmd, @@ -127,7 +127,7 @@ insert_handler (char *name, char *module) } item->cmd->data = data; - grub_list_push (&handler_list, GRUB_AS_LIST (item)); + grub_list_push (GRUB_AS_LIST_P (&handler_list), GRUB_AS_LIST (item)); } /* Read the file handler.lst for auto-loading. */ @@ -211,8 +211,10 @@ free_handler_list (void) { struct grub_handler_list *item; - while ((item = grub_list_pop (&handler_list)) != 0) + while (handler_list) { + item = handler_list; + handler_list = handler_list->next; grub_free (item->cmd->data); grub_unregister_command (item->cmd); grub_free (item->name); diff --git a/tests/lib/test.c b/tests/lib/test.c index 3029495c6..06d78b7d7 100644 --- a/tests/lib/test.c +++ b/tests/lib/test.c @@ -66,8 +66,10 @@ free_failures (void) { grub_test_failure_t item; - while ((item = grub_list_pop (GRUB_AS_LIST_P (&failure_list))) != 0) + while (failure_list) { + item = failure_list; + failure_list = item->next; if (item->message) grub_free (item->message); From 969d1c782da9c66f5b92c70a46cd8dcc78c10a42 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 27 Mar 2010 00:04:14 +0100 Subject: [PATCH 504/738] Simplify Apple CC support. * commands/i386/pc/drivemap_int13h.S: Use LOCAL when possible. Add 0 byte at the end not to have a symbol with empty target. * mmap/i386/pc/mmap_helper.S: Likewise. * genmk.rb: Ignore errors 2030 and 2050. * kern/i386/pc/startup.S: Use LOCAL when possible. --- ChangeLog | 10 ++++ commands/i386/pc/drivemap_int13h.S | 29 ++++------- genmk.rb | 2 +- kern/i386/pc/startup.S | 22 ++++---- mmap/i386/pc/mmap_helper.S | 81 ++++++++++-------------------- 5 files changed, 58 insertions(+), 86 deletions(-) diff --git a/ChangeLog b/ChangeLog index 65d7b9068..91b3069e0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2010-03-27 Vladimir Serbinenko + + Simplify Apple CC support. + + * commands/i386/pc/drivemap_int13h.S: Use LOCAL when possible. + Add 0 byte at the end not to have a symbol with empty target. + * mmap/i386/pc/mmap_helper.S: Likewise. + * genmk.rb: Ignore errors 2030 and 2050. + * kern/i386/pc/startup.S: Use LOCAL when possible. + 2010-03-26 BVK Chaitanya Testcase and the fix for final semicolon on cmdline. diff --git a/commands/i386/pc/drivemap_int13h.S b/commands/i386/pc/drivemap_int13h.S index 440349685..b460cd7b5 100644 --- a/commands/i386/pc/drivemap_int13h.S +++ b/commands/i386/pc/drivemap_int13h.S @@ -19,7 +19,7 @@ #include -#define INT13H_OFFSET(x) ((x) - EXT_C(grub_drivemap_handler)) +#define INT13H_OFFSET(x) ((x) - LOCAL (base)) .code16 @@ -27,6 +27,7 @@ /* The replacement int13 handler. Preserve all registers. */ FUNCTION(grub_drivemap_handler) +LOCAL (base): /* Save %dx for future restore. */ push %dx /* Push flags. Used to simulate interrupt with original flags. */ @@ -35,12 +36,7 @@ FUNCTION(grub_drivemap_handler) /* Map the drive number (always in DL). */ push %ax push %bx -#ifdef APPLE_CC - grub_drivemap_mapstart_ofs = INT13H_OFFSET(EXT_C(grub_drivemap_mapstart)) - movw $grub_drivemap_mapstart_ofs, %bx -#else - movw $INT13H_OFFSET(EXT_C(grub_drivemap_mapstart)), %bx -#endif + movw $INT13H_OFFSET(LOCAL (mapstart)), %bx more_remaining: movw %cs:(%bx), %ax @@ -66,12 +62,7 @@ not_found: popf pushf -#ifdef APPLE_CC - grub_drivemap_oldhandler_ofs = INT13H_OFFSET (EXT_C (grub_drivemap_oldhandler)) - lcall *%cs:grub_drivemap_oldhandler_ofs -#else - lcall *%cs:INT13H_OFFSET (EXT_C (grub_drivemap_oldhandler)) -#endif + lcall *%cs:INT13H_OFFSET (LOCAL (oldhandler)) push %bp mov %sp, %bp @@ -94,11 +85,7 @@ norestore: popf pushf -#ifdef APPLE_CC - lcall *%cs:grub_drivemap_oldhandler_ofs -#else - lcall *%cs:INT13H_OFFSET (EXT_C (grub_drivemap_oldhandler)) -#endif + lcall *%cs:INT13H_OFFSET (LOCAL (oldhandler)) push %bp mov %sp, %bp @@ -111,9 +98,13 @@ norestore: /* Far pointer to the old handler. Stored as a CS:IP in the style of real-mode IVT entries (thus PI:SC in mem). */ VARIABLE(grub_drivemap_oldhandler) +LOCAL (oldhandler): .word 0x0, 0x0 /* This label MUST be at the end of the copied block, since the installer code reserves additional space for mappings at runtime and copies them over it. */ -.align 2 + .align 2 + VARIABLE(grub_drivemap_mapstart) +LOCAL (mapstart): + .byte 0 diff --git a/genmk.rb b/genmk.rb index 46b2ed092..bb5a1dde1 100644 --- a/genmk.rb +++ b/genmk.rb @@ -161,7 +161,7 @@ else -rm -f $@ -rm -f $@.bin $(TARGET_CC) $(#{prefix}_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin #{pre_obj} #{mod_obj} - $(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@ + $(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -ew2030 -ew2050 -nu -nd $@.bin $@ -rm -f $@.bin endif endif diff --git a/kern/i386/pc/startup.S b/kern/i386/pc/startup.S index 23f3f398e..0aa420c6c 100644 --- a/kern/i386/pc/startup.S +++ b/kern/i386/pc/startup.S @@ -53,7 +53,7 @@ #include #include -#define ABS(x) ((x) - _start + GRUB_BOOT_MACHINE_KERNEL_ADDR + 0x200) +#define ABS(x) ((x) - LOCAL (base) + GRUB_BOOT_MACHINE_KERNEL_ADDR + 0x200) .file "startup.S" @@ -66,16 +66,15 @@ .globl start, _start start: _start: +LOCAL (base): /* * Guarantee that "main" is loaded at 0x0:0x8200. */ -#ifdef APPLE_CC - codestart_abs = ABS(codestart) - 0x10000 - ljmp $0, $(codestart_abs) +#ifdef __APPLE__ + ljmp $0, $(ABS(LOCAL (codestart)) - 0x10000) #else - ljmp $0, $ABS(codestart) + ljmp $0, $ABS(LOCAL (codestart)) #endif - /* * Compatibility version number * @@ -183,7 +182,7 @@ multiboot_trampoline: .code16 /* the real mode code continues... */ -codestart: +LOCAL (codestart): cli /* we're not safe here! */ /* set up %ds, %ss, and %es */ @@ -1156,7 +1155,7 @@ FUNCTION(grub_console_real_putchar) */ /* this table is used in translate_keycode below */ -translation_table: +LOCAL (translation_table): .word GRUB_CONSOLE_KEY_LEFT, GRUB_TERM_LEFT .word GRUB_CONSOLE_KEY_RIGHT, GRUB_TERM_RIGHT .word GRUB_CONSOLE_KEY_UP, GRUB_TERM_UP @@ -1178,11 +1177,10 @@ translate_keycode: pushw %bx pushw %si -#ifdef APPLE_CC - translation_table_abs = ABS (translation_table) - 0x10000 - movw $(translation_table_abs), %si +#ifdef __APPLE__ + movw $(ABS(LOCAL (translation_table)) - 0x10000), %si #else - movw $ABS(translation_table), %si + movw $ABS(LOCAL (translation_table)), %si #endif 1: lodsw diff --git a/mmap/i386/pc/mmap_helper.S b/mmap/i386/pc/mmap_helper.S index c6d12fd6c..743954574 100644 --- a/mmap/i386/pc/mmap_helper.S +++ b/mmap/i386/pc/mmap_helper.S @@ -19,32 +19,27 @@ #include -#define DS(x) ((x) - segstart) +#define DS(x) ((x) - LOCAL (segstart)) -segstart: +LOCAL (segstart): VARIABLE(grub_machine_mmaphook_start) .code16 VARIABLE(grub_machine_mmaphook_int12) push %ds push %cs pop %ds -#ifdef APPLE_CC - grub_machine_mmaphook_kblow_rel = DS (EXT_C (grub_machine_mmaphook_kblow)) - movw (grub_machine_mmaphook_kblow_rel), %ax -#else - movw DS (EXT_C (grub_machine_mmaphook_kblow)), %ax -#endif + movw DS (LOCAL (kblow)), %ax pop %ds iret VARIABLE(grub_machine_mmaphook_int15) pushf cmpw $0xe801, %ax - jz e801 + jz LOCAL (e801) cmpw $0xe820, %ax - jz e820 + jz LOCAL (e820) cmpb $0x88, %ah - jz h88 + jz LOCAL (h88) popf /* ljmp */ .byte 0xea @@ -53,67 +48,44 @@ VARIABLE (grub_machine_mmaphook_int15offset) VARIABLE (grub_machine_mmaphook_int15segment) .word 0 -e801: +LOCAL (e801): popf push %ds push %cs pop %ds -#ifdef APPLE_CC - grub_machine_mmaphook_kbin16mb_rel = DS (EXT_C (grub_machine_mmaphook_kbin16mb)) - grub_machine_mmaphook_64kbin4gb_rel = DS (EXT_C (grub_machine_mmaphook_64kbin4gb)) - movw (grub_machine_mmaphook_kbin16mb_rel), %ax - movw (grub_machine_mmaphook_64kbin4gb_rel), %bx -#else - movw DS (EXT_C (grub_machine_mmaphook_kbin16mb)), %ax - movw DS (EXT_C (grub_machine_mmaphook_64kbin4gb)), %bx -#endif + movw DS (LOCAL (kbin16mb)), %ax + movw DS (LOCAL (m64kbin4gb)), %bx movw %ax, %cx movw %bx, %dx pop %ds clc iret -h88: +LOCAL (h88): popf push %ds push %cs pop %ds -#ifdef APPLE_CC - movw (grub_machine_mmaphook_kbin16mb_rel), %ax -#else - movw DS (EXT_C (grub_machine_mmaphook_kbin16mb)), %ax -#endif + movw DS (LOCAL (kbin16mb)), %ax pop %ds clc iret -e820: -#ifdef APPLE_CC - mmaphook_mmap_rel = DS(mmaphook_mmap) - mmaphook_mmap_num_rel = DS(EXT_C(grub_machine_mmaphook_mmap_num)) -#endif +LOCAL (e820): popf push %ds push %cs pop %ds cmpw $20, %cx - jb errexit -#ifdef APPLE_CC - cmpw (mmaphook_mmap_num_rel), %bx -#else - cmpw DS (EXT_C (grub_machine_mmaphook_mmap_num)), %bx -#endif - jae errexit + jb LOCAL (errexit) + cmpw DS (LOCAL (mmap_num)), %bx + jae LOCAL (errexit) cmp $0x534d4150, %edx - jne errexit + jne LOCAL (errexit) push %si push %di movw $20, %cx -#ifdef APPLE_CC - movl $(mmaphook_mmap_rel), %esi -#else - movw $(DS(mmaphook_mmap)), %si -#endif + movw $(DS(LOCAL (mmaphook_mmap))), %si mov %bx, %ax imul $20, %ax add %ax, %si @@ -122,19 +94,15 @@ e820: pop %si movl $20, %ecx inc %bx -#ifdef APPLE_CC - cmpw (mmaphook_mmap_num_rel), %bx -#else - cmpw DS(EXT_C(grub_machine_mmaphook_mmap_num)), %bx -#endif - jb noclean + cmpw DS(LOCAL (mmap_num)), %bx + jb LOCAL (noclean) xor %bx, %bx -noclean: +LOCAL (noclean): mov $0x534d4150, %eax pop %ds clc iret -errexit: +LOCAL (errexit): mov $0x534d4150, %eax pop %ds stc @@ -142,13 +110,18 @@ errexit: iret VARIABLE(grub_machine_mmaphook_mmap_num) +LOCAL (mmap_num): .word 0 VARIABLE(grub_machine_mmaphook_kblow) +LOCAL (kblow): .word 0 VARIABLE (grub_machine_mmaphook_kbin16mb) +LOCAL (kbin16mb): .word 0 VARIABLE (grub_machine_mmaphook_64kbin4gb) +LOCAL (m64kbin4gb): .word 0 -mmaphook_mmap: +LOCAL (mmaphook_mmap): /* Memory map is placed just after the interrupt handlers. */ VARIABLE(grub_machine_mmaphook_end) + .byte 0 From d56a6ac7f67fcfaf5490c0d3d9bb9240ac2c31f7 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 27 Mar 2010 00:19:42 +0100 Subject: [PATCH 505/738] Remove handlers --- commands/handler.c | 103 ------------------ conf/any-emu.rmk | 2 +- conf/common.rmk | 43 ++------ conf/i386-coreboot.rmk | 2 +- conf/i386-ieee1275.rmk | 2 +- conf/i386-pc.rmk | 4 +- conf/i386-qemu.rmk | 2 +- conf/mips-qemu-mips.rmk | 2 +- conf/mips-yeeloong.rmk | 2 +- conf/powerpc-ieee1275.rmk | 2 +- conf/sparc64-ieee1275.rmk | 2 +- conf/x86-efi.rmk | 2 +- include/grub/handler.h | 60 ---------- include/grub/parser.h | 32 +----- include/grub/script_sh.h | 3 + include/grub/term.h | 2 +- kern/handler.c | 64 ----------- kern/main.c | 1 - kern/parser.c | 8 +- kern/rescue_parser.c | 14 +-- kern/rescue_reader.c | 2 +- normal/handler.c | 223 -------------------------------------- normal/main.c | 53 ++------- normal/menu_entry.c | 3 +- script/main.c | 18 +-- util/grub-fstest.c | 3 - util/grub-probe.c | 3 - util/grub-script-check.c | 7 -- util/i386/pc/grub-setup.c | 3 - 29 files changed, 40 insertions(+), 627 deletions(-) delete mode 100644 commands/handler.c delete mode 100644 include/grub/handler.h delete mode 100644 kern/handler.c delete mode 100644 normal/handler.c diff --git a/commands/handler.c b/commands/handler.c deleted file mode 100644 index 2bfa67415..000000000 --- a/commands/handler.c +++ /dev/null @@ -1,103 +0,0 @@ -/* handler.c - commands to list or select handlers */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2009 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include - -static grub_err_t -grub_cmd_handler (struct grub_command *cmd __attribute__ ((unused)), - int argc, char **args) -{ - void *curr_item = 0; - grub_handler_class_t head; - - head = grub_handler_class_list; - if (argc == 0) - { - grub_handler_class_t item; - FOR_LIST_ELEMENTS(item, head) - { - if (item == curr_item) - grub_putchar ('*'); - - grub_printf ("%s\n", item->name); - } - } - else - { - char *class_name; - grub_handler_class_t class; - - class_name = args[0]; - argc--; - args++; - - class = grub_named_list_find (GRUB_AS_NAMED_LIST (head), class_name); - if (! class) - return grub_error (GRUB_ERR_FILE_NOT_FOUND, "class not found"); - - if (argc == 0) - { - grub_handler_class_t item; - curr_item = class->cur_handler; - FOR_LIST_ELEMENTS(item, head) - { - if (item == curr_item) - grub_putchar ('*'); - - grub_printf ("%s\n", item->name); - } - } - else - { - grub_handler_t handler; - - handler = - grub_named_list_find (GRUB_AS_NAMED_LIST (class->handler_list), - args[0]); - - if (! handler) - return grub_error (GRUB_ERR_FILE_NOT_FOUND, "handler not found"); - - grub_handler_set_current (class, handler); - } - } - - return 0; -} - -static grub_command_t cmd_handler; - -GRUB_MOD_INIT(handler) -{ - cmd_handler = - grub_register_command ("handler", grub_cmd_handler, - N_("[class [handler]]"), - N_("List or select a handler.")); -} - -GRUB_MOD_FINI(handler) -{ - grub_unregister_command (cmd_handler); -} diff --git a/conf/any-emu.rmk b/conf/any-emu.rmk index 758a8d720..3a2c47bf5 100644 --- a/conf/any-emu.rmk +++ b/conf/any-emu.rmk @@ -7,7 +7,7 @@ util/grub-emu.c_DEPENDENCIES = grub_emu_init.h kernel_img_RELOCATABLE = yes pkglib_PROGRAMS = kernel.img kernel_img_SOURCES = kern/device.c kern/disk.c kern/dl.c kern/env.c \ - kern/err.c kern/list.c kern/handler.c kern/command.c \ + kern/err.c kern/list.c kern/command.c \ kern/corecmd.c kern/file.c kern/fs.c kern/main.c kern/misc.c \ kern/parser.c kern/partition.c kern/term.c \ kern/rescue_reader.c kern/rescue_parser.c \ diff --git a/conf/common.rmk b/conf/common.rmk index f55bbfe0c..6300af3aa 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -27,7 +27,7 @@ util/grub-probe.c_DEPENDENCIES = grub_probe_init.h grub_probe_SOURCES = gnulib/progname.c util/grub-probe.c \ util/hostdisk.c util/misc.c util/getroot.c \ kern/device.c kern/disk.c kern/err.c kern/misc.c \ - kern/parser.c kern/partition.c kern/file.c kern/list.c \ + kern/partition.c kern/file.c kern/list.c \ \ fs/affs.c fs/cpio.c fs/fat.c fs/ext2.c fs/hfs.c \ fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \ @@ -104,12 +104,11 @@ DISTCLEANFILES += grub_script.yy.c grub_script.yy.h # For grub-script-check. bin_UTILITIES += grub-script-check -util/grub-script-check.c_DEPENDENCIES = grub_script_check_init.h grub_script_check_SOURCES = gnulib/progname.c gnulib/getdelim.c gnulib/getline.c \ util/grub-script-check.c util/misc.c \ script/main.c script/script.c script/function.c script/lexer.c \ - kern/handler.c kern/err.c kern/parser.c kern/list.c \ - kern/misc.c kern/env.c grub_script_check_init.c grub_script.tab.c \ + kern/err.c kern/list.c \ + kern/misc.c kern/env.c grub_script.tab.c \ grub_script.yy.c MOSTLYCLEANFILES += symlist.c kernel_syms.lst @@ -119,7 +118,7 @@ kernel_img_HEADERS += boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \ partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \ machine/memory.h machine/loader.h machine/kernel.h \ - list.h handler.h command.h i18n.h env_private.h + list.h command.h i18n.h env_private.h symlist.c: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h gensymlist.sh /bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) @@ -132,19 +131,6 @@ grub_script.tab.c grub_script.tab.h: script/parser.y $(YACC) -d -p grub_script_yy -b grub_script $(srcdir)/script/parser.y DISTCLEANFILES += grub_script.tab.c grub_script.tab.h -# For grub-script-check. -grub_script_check_init.lst: geninit.sh $(filter-out grub_script_check_init.c,$(grub_script_check_SOURCES)) - rm -f $@; grep GRUB_MOD_INIT $(filter %.c,$^) /dev/null > $@ -DISTCLEANFILES += grub_script_check_init.lst - -grub_script_check_init.h: grub_script_check_init.lst $(filter-out grub_script_check_init.c,$(grub_script_check_SOURCES)) geninitheader.sh - rm -f $@; sh $(srcdir)/geninitheader.sh $< > $@ -DISTCLEANFILES += grub_script_check_init.h - -grub_script_check_init.c: grub_script_check_init.lst $(filter-out grub_script_check_init.c,$(grub_script_check_SOURCES)) geninit.sh - rm -f $@; sh $(srcdir)/geninit.sh $< $(filter %.c,$^) > $@ -DISTCLEANFILES += grub_script_check_init.c - # For grub-probe. grub_probe_init.lst: geninit.sh $(filter-out grub_probe_init.c,$(grub_probe_SOURCES)) rm -f $@; grep GRUB_MOD_INIT $(filter %.c,$^) /dev/null > $@ @@ -455,12 +441,12 @@ scsi_mod_CFLAGS = $(COMMON_CFLAGS) scsi_mod_LDFLAGS = $(COMMON_LDFLAGS) # Commands. -pkglib_MODULES += minicmd.mod extcmd.mod hello.mod handler.mod \ +pkglib_MODULES += minicmd.mod extcmd.mod hello.mod \ ls.mod cmp.mod cat.mod help.mod search.mod loopback.mod \ configfile.mod echo.mod \ terminfo.mod test.mod blocklist.mod hexdump.mod \ read.mod sleep.mod loadenv.mod crc.mod parttool.mod \ - msdospart.mod memrw.mod normal.mod sh.mod \ + msdospart.mod memrw.mod normal.mod \ gptsync.mod true.mod probe.mod password.mod \ keystatus.mod @@ -521,11 +507,6 @@ msdospart_mod_SOURCES = parttool/msdospart.c msdospart_mod_CFLAGS = $(COMMON_CFLAGS) msdospart_mod_LDFLAGS = $(COMMON_LDFLAGS) -# For handler.mod. -handler_mod_SOURCES = commands/handler.c -handler_mod_CFLAGS = $(COMMON_CFLAGS) -handler_mod_LDFLAGS = $(COMMON_LDFLAGS) - # For ls.mod. ls_mod_SOURCES = commands/ls.c ls_mod_CFLAGS = $(COMMON_CFLAGS) @@ -645,19 +626,15 @@ keystatus_mod_LDFLAGS = $(COMMON_LDFLAGS) # For normal.mod. normal_mod_SOURCES = normal/main.c normal/cmdline.c normal/dyncmd.c \ - normal/auth.c normal/autofs.c normal/handler.c \ + normal/auth.c normal/autofs.c \ normal/color.c normal/completion.c normal/datetime.c normal/menu.c \ normal/menu_entry.c normal/menu_text.c \ - normal/misc.c normal/crypto.c normal/term.c normal/context.c + normal/misc.c normal/crypto.c normal/term.c normal/context.c \ + script/main.c script/script.c script/execute.c \ + script/function.c script/lexer.c grub_script.tab.c grub_script.yy.c normal_mod_CFLAGS = $(COMMON_CFLAGS) normal_mod_LDFLAGS = $(COMMON_LDFLAGS) -# For sh.mod. -sh_mod_SOURCES = script/main.c script/script.c script/execute.c \ - script/function.c script/lexer.c grub_script.tab.c grub_script.yy.c -sh_mod_CFLAGS = $(COMMON_CFLAGS) -sh_mod_LDFLAGS = $(COMMON_LDFLAGS) - ifneq (, $(FONT_SOURCE)) font/font.c_DEPENDENCIES = ascii.h endif diff --git a/conf/i386-coreboot.rmk b/conf/i386-coreboot.rmk index 3cef9313f..0979f03ee 100644 --- a/conf/i386-coreboot.rmk +++ b/conf/i386-coreboot.rmk @@ -16,7 +16,7 @@ kernel_img_SOURCES = kern/i386/coreboot/startup.S \ kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \ kern/misc.c kern/mm.c kern/term.c \ kern/rescue_parser.c kern/rescue_reader.c \ - kern/time.c kern/list.c kern/handler.c kern/command.c kern/corecmd.c \ + kern/time.c kern/list.c kern/command.c kern/corecmd.c \ kern/$(target_cpu)/dl.c kern/parser.c kern/partition.c \ kern/i386/tsc.c kern/i386/pit.c \ kern/generic/rtc_get_time_ms.c \ diff --git a/conf/i386-ieee1275.rmk b/conf/i386-ieee1275.rmk index d4a459b3e..f8921df9b 100644 --- a/conf/i386-ieee1275.rmk +++ b/conf/i386-ieee1275.rmk @@ -18,7 +18,7 @@ kernel_img_SOURCES = kern/i386/ieee1275/startup.S \ kern/rescue_parser.c kern/rescue_reader.c \ kern/$(target_cpu)/dl.c kern/parser.c kern/partition.c \ kern/env.c \ - kern/time.c kern/list.c kern/handler.c kern/command.c kern/corecmd.c \ + kern/time.c kern/list.c kern/command.c kern/corecmd.c \ kern/generic/millisleep.c \ kern/ieee1275/ieee1275.c \ term/ieee1275/ofconsole.c \ diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk index ece88446b..7b624837b 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -45,7 +45,7 @@ kernel_img_SOURCES = kern/i386/pc/startup.S \ kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \ kern/misc.c kern/mm.c kern/term.c \ kern/rescue_parser.c kern/rescue_reader.c \ - kern/time.c kern/list.c kern/handler.c kern/command.c kern/corecmd.c \ + kern/time.c kern/list.c kern/command.c kern/corecmd.c \ kern/$(target_cpu)/dl.c kern/i386/pc/init.c kern/i386/pc/mmap.c \ kern/parser.c kern/partition.c \ kern/i386/tsc.c kern/i386/pit.c \ @@ -76,7 +76,7 @@ util/i386/pc/grub-setup.c_DEPENDENCIES = grub_setup_init.h grub_setup_SOURCES = gnulib/progname.c \ util/i386/pc/grub-setup.c util/hostdisk.c \ util/misc.c util/getroot.c kern/device.c kern/disk.c \ - kern/err.c kern/misc.c kern/parser.c kern/partition.c \ + kern/err.c kern/misc.c kern/partition.c \ kern/file.c kern/fs.c kern/env.c kern/list.c \ fs/fshelp.c \ \ diff --git a/conf/i386-qemu.rmk b/conf/i386-qemu.rmk index 97273e1ce..cbe6d0455 100644 --- a/conf/i386-qemu.rmk +++ b/conf/i386-qemu.rmk @@ -29,7 +29,7 @@ kernel_img_SOURCES = kern/i386/qemu/startup.S \ kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \ kern/misc.c kern/mm.c kern/term.c \ kern/rescue_parser.c kern/rescue_reader.c \ - kern/time.c kern/list.c kern/handler.c kern/command.c kern/corecmd.c \ + kern/time.c kern/list.c kern/command.c kern/corecmd.c \ kern/$(target_cpu)/dl.c kern/parser.c kern/partition.c \ kern/i386/tsc.c kern/i386/pit.c \ kern/generic/rtc_get_time_ms.c \ diff --git a/conf/mips-qemu-mips.rmk b/conf/mips-qemu-mips.rmk index e06370122..7cddf72ad 100644 --- a/conf/mips-qemu-mips.rmk +++ b/conf/mips-qemu-mips.rmk @@ -12,7 +12,7 @@ kernel_img_SOURCES = kern/$(target_cpu)/startup.S \ kern/disk.c kern/dl.c kern/err.c kern/file.c kern/fs.c \ kern/misc.c kern/mm.c kern/term.c \ kern/rescue_parser.c kern/rescue_reader.c \ - kern/list.c kern/handler.c kern/command.c kern/corecmd.c \ + kern/list.c kern/command.c kern/corecmd.c \ kern/parser.c kern/partition.c kern/env.c kern/$(target_cpu)/dl.c \ kern/generic/millisleep.c kern/generic/rtc_get_time_ms.c kern/time.c \ symlist.c kern/$(target_cpu)/cache.S diff --git a/conf/mips-yeeloong.rmk b/conf/mips-yeeloong.rmk index 35cd01b4b..bf39bf668 100644 --- a/conf/mips-yeeloong.rmk +++ b/conf/mips-yeeloong.rmk @@ -15,7 +15,7 @@ kernel_img_SOURCES = kern/$(target_cpu)/startup.S \ kern/disk.c kern/dl.c kern/err.c kern/file.c kern/fs.c \ kern/misc.c kern/mm.c kern/term.c \ kern/rescue_parser.c kern/rescue_reader.c \ - kern/list.c kern/handler.c kern/command.c kern/corecmd.c \ + kern/list.c kern/command.c kern/corecmd.c \ kern/parser.c kern/partition.c kern/env.c kern/$(target_cpu)/dl.c \ kern/generic/millisleep.c kern/generic/rtc_get_time_ms.c kern/time.c \ kern/$(target_cpu)/cache.S \ diff --git a/conf/powerpc-ieee1275.rmk b/conf/powerpc-ieee1275.rmk index 86f6ddcb3..7b32b24f1 100644 --- a/conf/powerpc-ieee1275.rmk +++ b/conf/powerpc-ieee1275.rmk @@ -13,7 +13,7 @@ kernel_img_SOURCES = kern/powerpc/ieee1275/startup.S kern/ieee1275/cmain.c \ kern/disk.c kern/dl.c kern/err.c kern/file.c kern/fs.c \ kern/misc.c kern/mm.c kern/term.c \ kern/rescue_parser.c kern/rescue_reader.c \ - kern/list.c kern/handler.c kern/command.c kern/corecmd.c \ + kern/list.c kern/command.c kern/corecmd.c \ kern/ieee1275/init.c \ kern/ieee1275/mmap.c \ term/ieee1275/ofconsole.c \ diff --git a/conf/sparc64-ieee1275.rmk b/conf/sparc64-ieee1275.rmk index 78e511e31..b4079dd1f 100644 --- a/conf/sparc64-ieee1275.rmk +++ b/conf/sparc64-ieee1275.rmk @@ -25,7 +25,7 @@ kernel_img_SOURCES = kern/sparc64/ieee1275/crt0.S kern/ieee1275/cmain.c \ kern/disk.c kern/dl.c kern/err.c kern/file.c kern/fs.c \ kern/misc.c kern/mm.c kern/term.c \ kern/rescue_parser.c kern/rescue_reader.c \ - kern/list.c kern/handler.c kern/command.c kern/corecmd.c \ + kern/list.c kern/command.c kern/corecmd.c \ kern/sparc64/ieee1275/ieee1275.c \ kern/sparc64/ieee1275/init.c \ kern/ieee1275/mmap.c \ diff --git a/conf/x86-efi.rmk b/conf/x86-efi.rmk index 5cb472168..bab68f0f4 100644 --- a/conf/x86-efi.rmk +++ b/conf/x86-efi.rmk @@ -30,7 +30,7 @@ kernel_img_SOURCES = kern/$(target_cpu)/efi/startup.S kern/main.c kern/device.c kern/$(target_cpu)/dl.c kern/i386/efi/init.c kern/parser.c kern/partition.c \ kern/env.c symlist.c kern/efi/efi.c kern/efi/init.c kern/efi/mm.c \ term/efi/console.c disk/efi/efidisk.c \ - kern/time.c kern/list.c kern/handler.c kern/command.c kern/corecmd.c \ + kern/time.c kern/list.c kern/command.c kern/corecmd.c \ kern/i386/tsc.c kern/i386/pit.c \ kern/generic/rtc_get_time_ms.c \ kern/generic/millisleep.c diff --git a/include/grub/handler.h b/include/grub/handler.h deleted file mode 100644 index 77dd7d9c1..000000000 --- a/include/grub/handler.h +++ /dev/null @@ -1,60 +0,0 @@ -/* handler.h - header for grub handler */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2009 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_HANDLER_HEADER -#define GRUB_HANDLER_HEADER 1 - -#include -#include - -struct grub_handler -{ - struct grub_handler *next; - const char *name; - grub_err_t (*init) (void); - grub_err_t (*fini) (void); -}; -typedef struct grub_handler *grub_handler_t; - -struct grub_handler_class -{ - struct grub_handler_class *next; - const char *name; - grub_handler_t handler_list; - grub_handler_t cur_handler; -}; -typedef struct grub_handler_class *grub_handler_class_t; - -extern grub_handler_class_t EXPORT_VAR(grub_handler_class_list); - -void EXPORT_FUNC(grub_handler_register) (grub_handler_class_t class, - grub_handler_t handler); -void EXPORT_FUNC(grub_handler_unregister) (grub_handler_class_t class, - grub_handler_t handler); -grub_err_t EXPORT_FUNC(grub_handler_set_current) (grub_handler_class_t class, - grub_handler_t handler); - -#define GRUB_AS_HANDLER(ptr) \ - ((GRUB_FIELD_MATCH (ptr, grub_handler_t, next) && \ - GRUB_FIELD_MATCH (ptr, grub_handler_t, name) && \ - GRUB_FIELD_MATCH (ptr, grub_handler_t, init) && \ - GRUB_FIELD_MATCH (ptr, grub_handler_t, fini)) ? \ - (grub_handler_t) ptr : grub_bad_type_cast ()) - -#endif /* ! GRUB_HANDLER_HEADER */ diff --git a/include/grub/parser.h b/include/grub/parser.h index 17f0c4303..064f73fcb 100644 --- a/include/grub/parser.h +++ b/include/grub/parser.h @@ -22,7 +22,6 @@ #include #include -#include #include /* All the states for the command line. */ @@ -84,36 +83,9 @@ struct grub_parser }; typedef struct grub_parser *grub_parser_t; -extern struct grub_handler_class EXPORT_VAR(grub_parser_class); grub_err_t EXPORT_FUNC(grub_parser_execute) (char *source); -static inline void -grub_parser_register (const char *name __attribute__ ((unused)), - /* `name' is ignored here, but used by genhandlerlist.sh. */ - grub_parser_t parser) -{ - grub_handler_register (&grub_parser_class, GRUB_AS_HANDLER (parser)); -} - -static inline void -grub_parser_unregister (grub_parser_t parser) -{ - grub_handler_unregister (&grub_parser_class, GRUB_AS_HANDLER (parser)); -} - -static inline grub_parser_t -grub_parser_get_current (void) -{ - return (grub_parser_t) grub_parser_class.cur_handler; -} - -static inline grub_err_t -grub_parser_set_current (grub_parser_t parser) -{ - return grub_handler_set_current (&grub_parser_class, - GRUB_AS_HANDLER (parser)); -} - -void grub_register_rescue_parser (void); +grub_err_t +grub_rescue_parse_line (char *line, grub_reader_getline_t getline); #endif /* ! GRUB_PARSER_HEADER */ diff --git a/include/grub/script_sh.h b/include/grub/script_sh.h index 33c6d2b85..5e85d983e 100644 --- a/include/grub/script_sh.h +++ b/include/grub/script_sh.h @@ -324,4 +324,7 @@ int grub_script_function_call (grub_script_function_t func, char ** grub_script_execute_arglist_to_argv (struct grub_script_arglist *arglist, int *count); +grub_err_t +grub_normal_parse_line (char *line, grub_reader_getline_t getline); + #endif /* ! GRUB_NORMAL_PARSER_HEADER */ diff --git a/include/grub/term.h b/include/grub/term.h index 230436388..4a05909da 100644 --- a/include/grub/term.h +++ b/include/grub/term.h @@ -38,7 +38,7 @@ #include #include #include -#include +#include /* These are used to represent the various color states we use. */ typedef enum diff --git a/kern/handler.c b/kern/handler.c deleted file mode 100644 index 2bf85313c..000000000 --- a/kern/handler.c +++ /dev/null @@ -1,64 +0,0 @@ -/* handler.c - grub handler function */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2009 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include - -grub_handler_class_t grub_handler_class_list; - -void -grub_handler_register (grub_handler_class_t class, grub_handler_t handler) -{ - int first_handler = (class->handler_list == 0); - - grub_list_push (GRUB_AS_LIST_P (&class->handler_list), - GRUB_AS_LIST (handler)); - - if (first_handler) - { - grub_list_push (GRUB_AS_LIST_P (&grub_handler_class_list), - GRUB_AS_LIST (class)); - grub_handler_set_current (class, handler); - } -} - -void -grub_handler_unregister (grub_handler_class_t class, grub_handler_t handler) -{ - grub_list_remove (GRUB_AS_LIST_P (&class->handler_list), - GRUB_AS_LIST (handler)); - - if (class->handler_list == 0) - grub_list_remove (GRUB_AS_LIST_P (&grub_handler_class_list), - GRUB_AS_LIST (class)); -} - -grub_err_t -grub_handler_set_current (grub_handler_class_t class, grub_handler_t handler) -{ - if (class->cur_handler && class->cur_handler->fini) - if ((class->cur_handler->fini) () != GRUB_ERR_NONE) - return grub_errno; - - if (handler->init) - if ((handler->init) () != GRUB_ERR_NONE) - return grub_errno; - - class->cur_handler = handler; - return GRUB_ERR_NONE; -} diff --git a/kern/main.c b/kern/main.c index 2f2c951ab..e644ea5b1 100644 --- a/kern/main.c +++ b/kern/main.c @@ -191,7 +191,6 @@ grub_main (void) grub_set_root_dev (); grub_register_core_commands (); - grub_register_rescue_parser (); grub_load_config (); grub_load_normal_mode (); diff --git a/kern/parser.c b/kern/parser.c index 80312b9b4..06e4ed673 100644 --- a/kern/parser.c +++ b/kern/parser.c @@ -230,10 +230,6 @@ grub_parser_split_cmdline (const char *cmdline, grub_reader_getline_t getline, return 0; } -struct grub_handler_class grub_parser_class = { - .name = "parser" -}; - grub_err_t grub_parser_execute (char *source) { @@ -262,11 +258,9 @@ grub_parser_execute (char *source) while (source) { char *line; - grub_parser_t parser; getline (&line, 0); - parser = grub_parser_get_current (); - parser->parse_line (line, getline); + grub_rescue_parse_line (line, getline); grub_free (line); } diff --git a/kern/rescue_parser.c b/kern/rescue_parser.c index d3725e739..9c85ba6bd 100644 --- a/kern/rescue_parser.c +++ b/kern/rescue_parser.c @@ -24,7 +24,7 @@ #include #include -static grub_err_t +grub_err_t grub_rescue_parse_line (char *line, grub_reader_getline_t getline) { char *name; @@ -74,15 +74,3 @@ grub_rescue_parse_line (char *line, grub_reader_getline_t getline) return grub_errno; } - -static struct grub_parser grub_rescue_parser = - { - .name = "rescue", - .parse_line = grub_rescue_parse_line - }; - -void -grub_register_rescue_parser (void) -{ - grub_parser_register ("rescue", &grub_rescue_parser); -} diff --git a/kern/rescue_reader.c b/kern/rescue_reader.c index f573cf41f..2f053aaea 100644 --- a/kern/rescue_reader.c +++ b/kern/rescue_reader.c @@ -86,7 +86,7 @@ grub_rescue_run (void) if (! line || line[0] == '\0') continue; - grub_parser_get_current ()->parse_line (line, grub_rescue_read_line); + grub_rescue_parse_line (line, grub_rescue_read_line); grub_free (line); } } diff --git a/normal/handler.c b/normal/handler.c deleted file mode 100644 index 4c8b8f769..000000000 --- a/normal/handler.c +++ /dev/null @@ -1,223 +0,0 @@ -/* handler.c - support handler loading */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2009 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -struct grub_handler_list -{ - struct grub_handler_list *next; - char *name; - grub_command_t cmd; -}; - -static struct grub_handler_list *handler_list; - -static grub_err_t -grub_handler_cmd (struct grub_command *cmd, - int argc __attribute__ ((unused)), - char **args __attribute__ ((unused))) -{ - char *p; - grub_handler_class_t class; - grub_handler_t handler; - - p = grub_strchr (cmd->name, '.'); - if (! p) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid command name"); - - if (cmd->data) - { - if (! grub_dl_get (cmd->data)) - { - grub_dl_t mod; - - mod = grub_dl_load (cmd->data); - if (mod) - grub_dl_ref (mod); - else - return grub_errno; - } - grub_free (cmd->data); - cmd->data = 0; - } - - *p = 0; - class = grub_named_list_find (GRUB_AS_NAMED_LIST (grub_handler_class_list), - cmd->name); - *p = '.'; - - if (! class) - return grub_error (GRUB_ERR_FILE_NOT_FOUND, "class not found"); - - - handler = grub_named_list_find (GRUB_AS_NAMED_LIST (class->handler_list), - p + 1); - if (! handler) - return grub_error (GRUB_ERR_FILE_NOT_FOUND, "handler not found"); - - grub_handler_set_current (class, handler); - - return 0; -} - -static void -insert_handler (char *name, char *module) -{ - struct grub_handler_list *item; - char *data; - - if (grub_command_find (name)) - return; - - item = grub_malloc (sizeof (*item)); - if (! item) - return; - - item->name = grub_strdup (name); - if (! item->name) - { - grub_free (item); - return; - } - - if (module) - { - data = grub_strdup (module); - if (! data) - { - grub_free (item->name); - grub_free (item); - return; - } - } - else - data = 0; - - item->cmd = grub_register_command (item->name, grub_handler_cmd, 0, - "Set active handler."); - if (! item->cmd) - { - grub_free (data); - grub_free (item->name); - grub_free (item); - return; - } - - item->cmd->data = data; - grub_list_push (GRUB_AS_LIST_P (&handler_list), GRUB_AS_LIST (item)); -} - -/* Read the file handler.lst for auto-loading. */ -void -read_handler_list (void) -{ - const char *prefix; - static int first_time = 1; - const char *class_name; - - /* Make sure that this function does not get executed twice. */ - if (! first_time) - return; - first_time = 0; - - prefix = grub_env_get ("prefix"); - if (prefix) - { - char *filename; - - filename = grub_xasprintf ("%s/handler.lst", prefix); - if (filename) - { - grub_file_t file; - - file = grub_file_open (filename); - if (file) - { - char *buf = NULL; - for (;; grub_free (buf)) - { - char *p; - - buf = grub_file_getline (file); - - if (! buf) - break; - - if (! grub_isgraph (buf[0])) - continue; - - p = grub_strchr (buf, ':'); - if (! p) - continue; - - *p = '\0'; - while (*++p == ' ') - ; - - insert_handler (buf, p); - } - grub_file_close (file); - } - grub_free (filename); - } - } - - grub_handler_class_t class; - FOR_LIST_ELEMENTS (class, grub_handler_class_list) - { - grub_handler_t handler; - class_name = class->name; - FOR_LIST_ELEMENTS(handler, class->handler_list) - { - char name[grub_strlen (class_name) + grub_strlen (handler->name) + 2]; - - grub_strcpy (name, class_name); - grub_strcat (name, "."); - grub_strcat (name, handler->name); - - insert_handler (name, 0); - } - } - - /* Ignore errors. */ - grub_errno = GRUB_ERR_NONE; -} - -void -free_handler_list (void) -{ - struct grub_handler_list *item; - - while (handler_list) - { - item = handler_list; - handler_list = handler_list->next; - grub_free (item->cmd->data); - grub_unregister_command (item->cmd); - grub_free (item->name); - grub_free (item); - } -} diff --git a/normal/main.c b/normal/main.c index 5a5467485..e16e8ef7d 100644 --- a/normal/main.c +++ b/normal/main.c @@ -31,6 +31,7 @@ #include #include #include +#include #define GRUB_DEFAULT_HISTORY_SIZE 50 @@ -308,7 +309,6 @@ static grub_menu_t read_config_file (const char *config) { grub_file_t file; - grub_parser_t old_parser = 0; auto grub_err_t getline (char **line, int cont); grub_err_t getline (char **line, int cont __attribute__ ((unused))) @@ -322,36 +322,7 @@ read_config_file (const char *config) return grub_errno; if (buf[0] == '#') - { - if (buf[1] == '!') - { - grub_parser_t parser; - grub_named_list_t list; - - buf += 2; - while (grub_isspace (*buf)) - buf++; - - if (! old_parser) - old_parser = grub_parser_get_current (); - - list = GRUB_AS_NAMED_LIST (grub_parser_class.handler_list); - parser = grub_named_list_find (list, buf); - if (parser) - grub_parser_set_current (parser); - else - { - char cmd_name[8 + grub_strlen (buf)]; - - /* Perhaps it's not loaded yet, try the autoload - command. */ - grub_strcpy (cmd_name, "parser."); - grub_strcat (cmd_name, buf); - grub_command_execute (cmd_name, 0, 0); - } - } - grub_free (*line); - } + grub_free (*line); else break; } @@ -387,15 +358,12 @@ read_config_file (const char *config) if ((getline (&line, 0)) || (! line)) break; - grub_parser_get_current ()->parse_line (line, getline); + grub_normal_parse_line (line, getline); grub_free (line); } grub_file_close (file); - if (old_parser) - grub_parser_set_current (old_parser); - return newmenu; } @@ -453,7 +421,6 @@ grub_normal_execute (const char *config, int nested, int batch) grub_menu_t menu = 0; read_lists (NULL, NULL); - read_handler_list (); grub_register_variable_hook ("prefix", NULL, read_lists); grub_command_execute ("parser.grub", 0, 0); @@ -559,17 +526,15 @@ grub_normal_reader_init (int nested) return 0; } - static grub_err_t grub_normal_read_line_real (char **line, int cont, int nested) { - grub_parser_t parser = grub_parser_get_current (); - char *prompt; + const char *prompt; if (cont) - prompt = grub_xasprintf (">"); + prompt = ">"; else - prompt = grub_xasprintf ("%s>", parser->name); + prompt = "grub>"; if (!prompt) return grub_errno; @@ -583,14 +548,11 @@ grub_normal_read_line_real (char **line, int cont, int nested) if (cont || nested) { grub_free (*line); - grub_free (prompt); *line = 0; return grub_errno; } } - grub_free (prompt); - return 0; } @@ -631,7 +593,7 @@ grub_cmdline_run (int nested) if (! line) break; - grub_parser_get_current ()->parse_line (line, grub_normal_read_line); + grub_normal_parse_line (line, grub_normal_read_line); grub_free (line); } } @@ -679,5 +641,4 @@ GRUB_MOD_FINI(normal) grub_set_history (0); grub_register_variable_hook ("pager", 0, 0); grub_fs_autoload_hook = 0; - free_handler_list (); } diff --git a/normal/menu_entry.c b/normal/menu_entry.c index 644fe90fd..c23d67d70 100644 --- a/normal/menu_entry.c +++ b/normal/menu_entry.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -1189,7 +1190,7 @@ run (struct screen *screen) while (currline < screen->num_lines) { editor_getline (&nextline, 0); - if (grub_parser_get_current ()->parse_line (nextline, editor_getline)) + if (grub_normal_parse_line (nextline, editor_getline)) break; } diff --git a/script/main.c b/script/main.c index b5159dc7d..752a8cd8a 100644 --- a/script/main.c +++ b/script/main.c @@ -20,7 +20,7 @@ #include #include -static grub_err_t +grub_err_t grub_normal_parse_line (char *line, grub_reader_getline_t getline) { struct grub_script *parsed_script; @@ -39,19 +39,3 @@ grub_normal_parse_line (char *line, grub_reader_getline_t getline) return grub_errno; } - -static struct grub_parser grub_sh_parser = - { - .name = "grub", - .parse_line = grub_normal_parse_line - }; - -GRUB_MOD_INIT(sh) -{ - grub_parser_register ("grub", &grub_sh_parser); -} - -GRUB_MOD_FINI(sh) -{ - grub_parser_unregister (&grub_sh_parser); -} diff --git a/util/grub-fstest.c b/util/grub-fstest.c index c03c43451..f7e1eb2dd 100644 --- a/util/grub-fstest.c +++ b/util/grub-fstest.c @@ -55,9 +55,6 @@ grub_getkey (void) return -1; } -struct grub_handler_class grub_term_input_class; -struct grub_handler_class grub_term_output_class; - void grub_refresh (void) { diff --git a/util/grub-probe.c b/util/grub-probe.c index 948f10dcf..37b92454a 100644 --- a/util/grub-probe.c +++ b/util/grub-probe.c @@ -70,9 +70,6 @@ grub_getkey (void) return -1; } -struct grub_handler_class grub_term_input_class; -struct grub_handler_class grub_term_output_class; - void grub_refresh (void) { diff --git a/util/grub-script-check.c b/util/grub-script-check.c index 7dc400dde..722736c81 100644 --- a/util/grub-script-check.c +++ b/util/grub-script-check.c @@ -26,8 +26,6 @@ #include #include -#include - #define _GNU_SOURCE 1 #include @@ -232,9 +230,6 @@ main (int argc, char *argv[]) } } - /* Initialize all modules. */ - grub_init_all (); - do { input = 0; @@ -252,8 +247,6 @@ main (int argc, char *argv[]) grub_free (input); } while (script != 0); - /* Free resources. */ - grub_fini_all (); if (file) fclose (file); return (script == 0); diff --git a/util/i386/pc/grub-setup.c b/util/i386/pc/grub-setup.c index 63fa8c328..989b06360 100644 --- a/util/i386/pc/grub-setup.c +++ b/util/i386/pc/grub-setup.c @@ -69,9 +69,6 @@ grub_getkey (void) return -1; } -struct grub_handler_class grub_term_input_class; -struct grub_handler_class grub_term_output_class; - void grub_refresh (void) { From c96db58ec599d1bcfb12bf345fb4988e1ef1a741 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 27 Mar 2010 00:27:42 +0100 Subject: [PATCH 506/738] Remove grub_fs_iterate --- include/grub/fs.h | 26 ++++++++++++++++++++------ kern/fs.c | 32 +------------------------------- 2 files changed, 21 insertions(+), 37 deletions(-) diff --git a/include/grub/fs.h b/include/grub/fs.h index 45f515768..3368eb553 100644 --- a/include/grub/fs.h +++ b/include/grub/fs.h @@ -24,6 +24,8 @@ #include #include +#include + /* Forward declaration is required, because of mutual reference. */ struct grub_file; @@ -38,6 +40,9 @@ struct grub_dirhook_info /* Filesystem descriptor. */ struct grub_fs { + /* The next filesystem. */ + struct grub_fs *next; + /* My name. */ const char *name; @@ -72,9 +77,6 @@ struct grub_fs /* Whether this filesystem reserves first sector for DOS-style boot. */ int reserved_first_sector; #endif - - /* The next filesystem. */ - struct grub_fs *next; }; typedef struct grub_fs *grub_fs_t; @@ -87,10 +89,22 @@ extern struct grub_fs grub_fs_blocklist; the linked list GRUB_FS_LIST through the function grub_fs_register. */ typedef int (*grub_fs_autoload_hook_t) (void); extern grub_fs_autoload_hook_t EXPORT_VAR(grub_fs_autoload_hook); +extern grub_fs_t EXPORT_VAR (grub_fs_list); + +static inline void +grub_fs_register (grub_fs_t fs) +{ + grub_list_push (GRUB_AS_LIST_P (&grub_fs_list), GRUB_AS_LIST (fs)); +} + +static inline void +grub_fs_unregister (grub_fs_t fs) +{ + grub_list_remove (GRUB_AS_LIST_P (&grub_fs_list), GRUB_AS_LIST (fs)); +} + +#define FOR_FILESYSTEMS(var) FOR_LIST_ELEMENTS((var), (grub_fs_list)) -void EXPORT_FUNC(grub_fs_register) (grub_fs_t fs); -void EXPORT_FUNC(grub_fs_unregister) (grub_fs_t fs); -void EXPORT_FUNC(grub_fs_iterate) (int (*hook) (const grub_fs_t fs)); grub_fs_t EXPORT_FUNC(grub_fs_probe) (grub_device_t device); #endif /* ! GRUB_FS_HEADER */ diff --git a/kern/fs.c b/kern/fs.c index 0c456377f..cf800f4cc 100644 --- a/kern/fs.c +++ b/kern/fs.c @@ -27,40 +27,10 @@ #include #include -static grub_fs_t grub_fs_list; +grub_fs_t grub_fs_list = 0; grub_fs_autoload_hook_t grub_fs_autoload_hook = 0; -void -grub_fs_register (grub_fs_t fs) -{ - fs->next = grub_fs_list; - grub_fs_list = fs; -} - -void -grub_fs_unregister (grub_fs_t fs) -{ - grub_fs_t *p, q; - - for (p = &grub_fs_list, q = *p; q; p = &(q->next), q = q->next) - if (q == fs) - { - *p = q->next; - break; - } -} - -void -grub_fs_iterate (int (*hook) (const grub_fs_t fs)) -{ - grub_fs_t p; - - for (p = grub_fs_list; p; p = p->next) - if (hook (p)) - break; -} - grub_fs_t grub_fs_probe (grub_device_t device) { From 9eade9dbd7602d4b9dbae8a09dc89a1631ab314e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 27 Mar 2010 00:36:28 +0100 Subject: [PATCH 507/738] Remove grub_video_iterate --- include/grub/video.h | 29 +++++++++++++++++++++++------ video/video.c | 35 +---------------------------------- 2 files changed, 24 insertions(+), 40 deletions(-) diff --git a/include/grub/video.h b/include/grub/video.h index 57f2b37f2..3e8ea0e96 100644 --- a/include/grub/video.h +++ b/include/grub/video.h @@ -21,6 +21,7 @@ #include #include +#include /* Video color in hardware dependent format. Users should not assume any specific coding format. */ @@ -185,6 +186,9 @@ typedef enum grub_video_driver_id struct grub_video_adapter { + /* The next video adapter. */ + struct grub_video_adapter *next; + /* The video adapter name. */ const char *name; grub_video_driver_id_t id; @@ -253,15 +257,28 @@ struct grub_video_adapter grub_err_t (*set_active_render_target) (struct grub_video_render_target *target); grub_err_t (*get_active_render_target) (struct grub_video_render_target **target); - - /* The next video adapter. */ - struct grub_video_adapter *next; }; typedef struct grub_video_adapter *grub_video_adapter_t; -void EXPORT_FUNC (grub_video_register) (grub_video_adapter_t adapter); -void grub_video_unregister (grub_video_adapter_t adapter); -void grub_video_iterate (int (*hook) (grub_video_adapter_t adapter)); +extern grub_video_adapter_t EXPORT_VAR(grub_video_adapter_list); + +/* Register video driver. */ +static inline void +grub_video_register (grub_video_adapter_t adapter) +{ + grub_list_push (GRUB_AS_LIST_P (&grub_video_adapter_list), + GRUB_AS_LIST (adapter)); +} + +/* Unregister video driver. */ +static inline void +grub_video_unregister (grub_video_adapter_t adapter) +{ + grub_list_remove (GRUB_AS_LIST_P (&grub_video_adapter_list), + GRUB_AS_LIST (adapter)); +} + +#define FOR_VIDEO_ADAPTERS(var) FOR_LIST_ELEMENTS((var), (grub_video_adapter_list)) grub_err_t EXPORT_FUNC (grub_video_restore) (void); diff --git a/video/video.c b/video/video.c index 42418f980..7a1a446e4 100644 --- a/video/video.c +++ b/video/video.c @@ -23,44 +23,11 @@ #include /* The list of video adapters registered to system. */ -static grub_video_adapter_t grub_video_adapter_list; +grub_video_adapter_t grub_video_adapter_list = NULL; /* Active video adapter. */ static grub_video_adapter_t grub_video_adapter_active; -/* Register video driver. */ -void -grub_video_register (grub_video_adapter_t adapter) -{ - adapter->next = grub_video_adapter_list; - grub_video_adapter_list = adapter; -} - -/* Unregister video driver. */ -void -grub_video_unregister (grub_video_adapter_t adapter) -{ - grub_video_adapter_t *p, q; - - for (p = &grub_video_adapter_list, q = *p; q; p = &(q->next), q = q->next) - if (q == adapter) - { - *p = q->next; - break; - } -} - -/* Iterate thru all registered video drivers. */ -void -grub_video_iterate (int (*hook) (grub_video_adapter_t adapter)) -{ - grub_video_adapter_t p; - - for (p = grub_video_adapter_list; p; p = p->next) - if (hook (p)) - break; -} - /* Restore back to initial mode (where applicable). */ grub_err_t grub_video_restore (void) From fcaae9ec1242c54e0bd763d80f8427e70e9f7fde Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 27 Mar 2010 00:52:40 +0100 Subject: [PATCH 508/738] Remove grub_dl_iterate --- commands/minicmd.c | 34 ++++++++++++++------------------ include/grub/dl.h | 6 +++++- kern/dl.c | 49 ++++++++++++---------------------------------- 3 files changed, 32 insertions(+), 57 deletions(-) diff --git a/commands/minicmd.c b/commands/minicmd.c index 4ea9efead..92d262caf 100644 --- a/commands/minicmd.c +++ b/commands/minicmd.c @@ -301,27 +301,23 @@ grub_mini_cmd_lsmod (struct grub_command *cmd __attribute__ ((unused)), int argc __attribute__ ((unused)), char *argv[] __attribute__ ((unused))) { - auto int print_module (grub_dl_t mod); - - int print_module (grub_dl_t mod) - { - grub_dl_dep_t dep; - - grub_printf ("%s\t%d\t\t", mod->name, mod->ref_count); - for (dep = mod->dep; dep; dep = dep->next) - { - if (dep != mod->dep) - grub_putchar (','); - - grub_printf ("%s", dep->mod->name); - } - grub_putchar ('\n'); - - return 0; - } + grub_dl_t mod; grub_printf ("Name\tRef Count\tDependencies\n"); - grub_dl_iterate (print_module); + FOR_DL_MODULES (mod) + { + grub_dl_dep_t dep; + + grub_printf ("%s\t%d\t\t", mod->name, mod->ref_count); + for (dep = mod->dep; dep; dep = dep->next) + { + if (dep != mod->dep) + grub_putchar (','); + + grub_printf ("%s", dep->mod->name); + } + grub_putchar ('\n'); + } return 0; } diff --git a/include/grub/dl.h b/include/grub/dl.h index 17e03f400..c44e85aef 100644 --- a/include/grub/dl.h +++ b/include/grub/dl.h @@ -82,6 +82,7 @@ struct grub_dl Elf_Sym *symtab; void (*init) (struct grub_dl *mod); void (*fini) (void); + struct grub_dl *next; }; typedef struct grub_dl *grub_dl_t; @@ -113,7 +114,10 @@ grub_dl_unref (grub_dl_t mod) int EXPORT_FUNC(grub_dl_ref) (grub_dl_t mod); int EXPORT_FUNC(grub_dl_unref) (grub_dl_t mod); #endif -void EXPORT_FUNC(grub_dl_iterate) (int (*hook) (grub_dl_t mod)); +extern grub_dl_t EXPORT_VAR(grub_dl_head); + +#define FOR_DL_MODULES(var) FOR_LIST_ELEMENTS ((var), (grub_dl_head)) + grub_dl_t EXPORT_FUNC(grub_dl_get) (const char *name); grub_err_t grub_dl_register_symbol (const char *name, void *addr, grub_dl_t mod); diff --git a/kern/dl.c b/kern/dl.c index 19ee13243..cf59cec30 100644 --- a/kern/dl.c +++ b/kern/dl.c @@ -39,31 +39,17 @@ -struct grub_dl_list -{ - struct grub_dl_list *next; - grub_dl_t mod; -}; -typedef struct grub_dl_list *grub_dl_list_t; - -static grub_dl_list_t grub_dl_head; +grub_dl_t grub_dl_head = 0; static grub_err_t grub_dl_add (grub_dl_t mod) { - grub_dl_list_t l; - if (grub_dl_get (mod->name)) return grub_error (GRUB_ERR_BAD_MODULE, "`%s' is already loaded", mod->name); - l = (grub_dl_list_t) grub_malloc (sizeof (*l)); - if (! l) - return grub_errno; - - l->mod = mod; - l->next = grub_dl_head; - grub_dl_head = l; + mod->next = grub_dl_head; + grub_dl_head = mod; return GRUB_ERR_NONE; } @@ -71,13 +57,12 @@ grub_dl_add (grub_dl_t mod) static void grub_dl_remove (grub_dl_t mod) { - grub_dl_list_t *p, q; + grub_dl_t *p, q; for (p = &grub_dl_head, q = *p; q; p = &q->next, q = *p) - if (q->mod == mod) + if (q == mod) { *p = q->next; - grub_free (q); return; } } @@ -85,25 +70,15 @@ grub_dl_remove (grub_dl_t mod) grub_dl_t grub_dl_get (const char *name) { - grub_dl_list_t l; + grub_dl_t l; for (l = grub_dl_head; l; l = l->next) - if (grub_strcmp (name, l->mod->name) == 0) - return l->mod; + if (grub_strcmp (name, l->name) == 0) + return l; return 0; } -void -grub_dl_iterate (int (*hook) (grub_dl_t mod)) -{ - grub_dl_list_t l; - - for (l = grub_dl_head; l; l = l->next) - if (hook (l->mod)) - break; -} - struct grub_symbol @@ -690,11 +665,11 @@ grub_dl_unload_unneeded (void) { /* Because grub_dl_remove modifies the list of modules, this implementation is tricky. */ - grub_dl_list_t p = grub_dl_head; + grub_dl_t p = grub_dl_head; while (p) { - if (grub_dl_unload (p->mod)) + if (grub_dl_unload (p)) { p = grub_dl_head; continue; @@ -710,13 +685,13 @@ grub_dl_unload_all (void) { while (grub_dl_head) { - grub_dl_list_t p; + grub_dl_t p; grub_dl_unload_unneeded (); /* Force to decrement the ref count. This will purge pre-loaded modules and manually inserted modules. */ for (p = grub_dl_head; p; p = p->next) - p->mod->ref_count--; + p->ref_count--; } } From 9cc7b8751eb717834864fc587412a4dbafa7066d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 27 Mar 2010 00:58:35 +0100 Subject: [PATCH 509/738] Remove grub_script_function_iterate --- include/grub/script_sh.h | 6 +++++- script/function.c | 14 +------------- 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/include/grub/script_sh.h b/include/grub/script_sh.h index 5e85d983e..020cbb2f7 100644 --- a/include/grub/script_sh.h +++ b/include/grub/script_sh.h @@ -313,11 +313,15 @@ struct grub_script_function }; typedef struct grub_script_function *grub_script_function_t; +extern grub_script_function_t grub_script_function_list; + +#define FOR_SCRIPT_FUNCTIONS(var) for((var) = grub_script_function_list; \ + (var); (var) = (var)->next) + grub_script_function_t grub_script_function_create (struct grub_script_arg *functionname, struct grub_script *cmd); void grub_script_function_remove (const char *name); grub_script_function_t grub_script_function_find (char *functionname); -int grub_script_function_iterate (int (*iterate) (grub_script_function_t)); int grub_script_function_call (grub_script_function_t func, int argc, char **args); diff --git a/script/function.c b/script/function.c index ded470c4e..810c65233 100644 --- a/script/function.c +++ b/script/function.c @@ -21,7 +21,7 @@ #include #include -static grub_script_function_t grub_script_function_list; +grub_script_function_t grub_script_function_list; grub_script_function_t grub_script_function_create (struct grub_script_arg *functionname_arg, @@ -104,18 +104,6 @@ grub_script_function_find (char *functionname) return func; } -int -grub_script_function_iterate (int (*iterate) (grub_script_function_t)) -{ - grub_script_function_t func; - - for (func = grub_script_function_list; func; func = func->next) - if (iterate (func)) - return 1; - - return 0; -} - int grub_script_function_call (grub_script_function_t func, int argc __attribute__((unused)), From 394a3120a7e082b130108895243ad00648151564 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Sutre?= Date: Sat, 27 Mar 2010 12:19:32 +0100 Subject: [PATCH 510/738] Fix a build failure (-Wundef -Werror) when ENABLE_NLS is not defined, which is the case with --disabled-nls. * include/grub/i18n.h: Use (defined(ENABLE_NLS) && ENABLE_NLS) instead of ENABLE_NLS in all #if preprocessor macros. * util/misc.c: Likewise. * util/mkisofs/mkisofs.c: Likewise. * util/mkisofs/mkisofs.h: Likewise. --- ChangeLog | 11 +++++++++++ include/grub/i18n.h | 6 +++--- util/misc.c | 4 ++-- util/mkisofs/mkisofs.c | 4 ++-- util/mkisofs/mkisofs.h | 6 +++--- 5 files changed, 21 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index 91b3069e0..ef534fd31 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2010-03-27 Grégoire Sutre + + Fix a build failure (-Wundef -Werror) when ENABLE_NLS is not defined, + which is the case with --disabled-nls. + + * include/grub/i18n.h: Use (defined(ENABLE_NLS) + && ENABLE_NLS) instead of ENABLE_NLS in all #if preprocessor macros. + * util/misc.c: Likewise. + * util/mkisofs/mkisofs.c: Likewise. + * util/mkisofs/mkisofs.h: Likewise. + 2010-03-27 Vladimir Serbinenko Simplify Apple CC support. diff --git a/include/grub/i18n.h b/include/grub/i18n.h index 0cba54765..9e7f52d45 100644 --- a/include/grub/i18n.h +++ b/include/grub/i18n.h @@ -25,7 +25,7 @@ extern const char *(*EXPORT_VAR(grub_gettext)) (const char *s); /* NLS can be disabled through the configure --disable-nls option. */ -#if ENABLE_NLS +#if (defined(ENABLE_NLS) && ENABLE_NLS) # ifdef GRUB_UTIL @@ -34,7 +34,7 @@ extern const char *(*EXPORT_VAR(grub_gettext)) (const char *s); # endif /* GRUB_UTIL */ -#else /* ! ENABLE_NLS */ +#else /* ! (defined(ENABLE_NLS) && ENABLE_NLS) */ /* Disabled NLS. The casts to 'const char *' serve the purpose of producing warnings @@ -47,7 +47,7 @@ extern const char *(*EXPORT_VAR(grub_gettext)) (const char *s); # define grub_gettext(str) ((const char *) (str)) # endif /* GRUB_UTIL */ -#endif /* ENABLE_NLS */ +#endif /* (defined(ENABLE_NLS) && ENABLE_NLS) */ #ifdef GRUB_UTIL # define _(str) gettext(str) diff --git a/util/misc.c b/util/misc.c index 7381c8fdd..0f52c218d 100644 --- a/util/misc.c +++ b/util/misc.c @@ -604,10 +604,10 @@ make_system_path_relative_to_its_root (const char *path) void grub_util_init_nls (void) { -#if ENABLE_NLS +#if (defined(ENABLE_NLS) && ENABLE_NLS) setlocale (LC_ALL, ""); bindtextdomain (PACKAGE, LOCALEDIR); textdomain (PACKAGE); -#endif /* ENABLE_NLS */ +#endif /* (defined(ENABLE_NLS) && ENABLE_NLS) */ } #endif diff --git a/util/mkisofs/mkisofs.c b/util/mkisofs/mkisofs.c index 69b4b3d0d..16e2f0c7d 100644 --- a/util/mkisofs/mkisofs.c +++ b/util/mkisofs/mkisofs.c @@ -640,11 +640,11 @@ int FDECL2(main, int, argc, char **, argv){ char *log_file = 0; set_program_name (argv[0]); -#if ENABLE_NLS +#if (defined(ENABLE_NLS) && ENABLE_NLS) setlocale (LC_ALL, ""); bindtextdomain (PACKAGE, LOCALEDIR); textdomain (PACKAGE); -#endif /* ENABLE_NLS */ +#endif /* (defined(ENABLE_NLS) && ENABLE_NLS) */ if (argc < 2) usage(); diff --git a/util/mkisofs/mkisofs.h b/util/mkisofs/mkisofs.h index 482db6ceb..b699516e9 100644 --- a/util/mkisofs/mkisofs.h +++ b/util/mkisofs/mkisofs.h @@ -30,12 +30,12 @@ #include #include -#if ENABLE_NLS +#if (defined(ENABLE_NLS) && ENABLE_NLS) # include # include -#else /* ! ENABLE_NLS */ +#else /* ! (defined(ENABLE_NLS) && ENABLE_NLS) */ /* Disabled NLS. The casts to 'const char *' serve the purpose of producing warnings @@ -43,7 +43,7 @@ On pre-ANSI systems without 'const', the config.h file is supposed to contain "#define const". */ # define gettext(Msgid) ((const char *) (Msgid)) -#endif /* ENABLE_NLS */ +#endif /* (defined(ENABLE_NLS) && ENABLE_NLS) */ #define _(str) gettext(str) #define N_(str) str From 3506b90b0d278ce8dd5fe7ab32903db876cd85ad Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 27 Mar 2010 12:53:40 +0100 Subject: [PATCH 511/738] Resync with gnulib. * Makefile.in (GNULIB_CFLAGS): New variable. * conf/common.rmk (grub_mkisofs_CFLAGS): Add GNULIB_CFLAGS. (grub_script_check_CFLAGS): New variable. * gnulib/alloca.h: Resync with gnulib. * gnulib/error.c: Likewise. * gnulib/error.h: Likewise. * gnulib/fnmatch.c: Likewise. * gnulib/fnmatch_loop.c: Likewise. * gnulib/getdelim.c: Likewise. * gnulib/getline.c: Likewise. * gnulib/getopt.c: Likewise. * gnulib/getopt1.c: Likewise. * gnulib/getopt_int.h: Likewise. * gnulib/gettext.h: Likewise. * gnulib/progname.c: Likewise. * gnulib/progname.h: Likewise. --- ChangeLog | 21 + Makefile.in | 1 + conf/common.rmk | 4 +- gnulib/alloca.h | 4 +- gnulib/error.c | 152 ++-- gnulib/error.h | 24 +- gnulib/fnmatch.c | 198 ++--- gnulib/fnmatch_loop.c | 1730 +++++++++++++++++++++-------------------- gnulib/getdelim.c | 77 +- gnulib/getline.c | 2 +- gnulib/getopt.c | 1247 +++++++++++++++-------------- gnulib/getopt1.c | 128 +-- gnulib/getopt_int.h | 38 +- gnulib/gettext.h | 42 +- gnulib/progname.c | 32 +- gnulib/progname.h | 12 +- 16 files changed, 1891 insertions(+), 1821 deletions(-) diff --git a/ChangeLog b/ChangeLog index ef534fd31..86c1d6ceb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,24 @@ +2010-03-27 Vladimir Serbinenko + + Resync with gnulib. + + * Makefile.in (GNULIB_CFLAGS): New variable. + * conf/common.rmk (grub_mkisofs_CFLAGS): Add GNULIB_CFLAGS. + (grub_script_check_CFLAGS): New variable. + * gnulib/alloca.h: Resync with gnulib. + * gnulib/error.c: Likewise. + * gnulib/error.h: Likewise. + * gnulib/fnmatch.c: Likewise. + * gnulib/fnmatch_loop.c: Likewise. + * gnulib/getdelim.c: Likewise. + * gnulib/getline.c: Likewise. + * gnulib/getopt.c: Likewise. + * gnulib/getopt1.c: Likewise. + * gnulib/getopt_int.h: Likewise. + * gnulib/gettext.h: Likewise. + * gnulib/progname.c: Likewise. + * gnulib/progname.h: Likewise. + 2010-03-27 Grégoire Sutre Fix a build failure (-Wundef -Werror) when ENABLE_NLS is not defined, diff --git a/Makefile.in b/Makefile.in index 07fe6219a..d640b91d6 100644 --- a/Makefile.in +++ b/Makefile.in @@ -79,6 +79,7 @@ LIBS = @LIBS@ $(LIBINTL) CC = @CC@ CFLAGS = @CFLAGS@ +GNULIB_CFLAGS = -Wno-undef -D_GL_UNUSED="__attribute__ ((unused))" ASFLAGS = @ASFLAGS@ LDFLAGS = @LDFLAGS@ $(LIBS) CPPFLAGS = @CPPFLAGS@ -I$(builddir) -I$(builddir)/include -I$(srcdir)/gnulib -I$(srcdir)/include -Wall -W \ diff --git a/conf/common.rmk b/conf/common.rmk index f55bbfe0c..a7536d08e 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -56,7 +56,7 @@ grub_mkisofs_SOURCES = util/mkisofs/eltorito.c \ gnulib/error.c gnulib/progname.c grub_mkisofs_CFLAGS = -D_FILE_OFFSET_BITS=64 \ -I$(srcdir)/util/mkisofs/include \ - -Wno-all -Werror + -Wno-all -Werror $(GNULIB_CFLAGS) # For grub-fstest. util/grub-fstest.c_DEPENDENCIES = grub_fstest_init.h @@ -111,7 +111,7 @@ grub_script_check_SOURCES = gnulib/progname.c gnulib/getdelim.c gnulib/getline.c kern/handler.c kern/err.c kern/parser.c kern/list.c \ kern/misc.c kern/env.c grub_script_check_init.c grub_script.tab.c \ grub_script.yy.c - +grub_script_check_CFLAGS = $(GNULIB_CFLAGS) MOSTLYCLEANFILES += symlist.c kernel_syms.lst DEFSYMFILES += kernel_syms.lst diff --git a/gnulib/alloca.h b/gnulib/alloca.h index 5d16e08b7..107534e98 100644 --- a/gnulib/alloca.h +++ b/gnulib/alloca.h @@ -1,7 +1,7 @@ /* Memory allocation on the stack. - Copyright (C) 1995, 1999, 2001-2004, 2006-2008 Free Software - Foundation, Inc. + Copyright (C) 1995, 1999, 2001-2004, 2006-2010 Free Software Foundation, + Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published diff --git a/gnulib/error.c b/gnulib/error.c index af2287b27..c79e8d42c 100644 --- a/gnulib/error.c +++ b/gnulib/error.c @@ -1,5 +1,5 @@ /* Error handler for noninteractive utilities - Copyright (C) 1990-1998, 2000-2007, 2009 Free Software Foundation, Inc. + Copyright (C) 1990-1998, 2000-2007, 2009-2010 Free Software Foundation, Inc. This file is part of the GNU C Library. This program is free software: you can redistribute it and/or modify @@ -70,8 +70,8 @@ unsigned int error_message_count; extern void __error (int status, int errnum, const char *message, ...) __attribute__ ((__format__ (__printf__, 3, 4))); extern void __error_at_line (int status, int errnum, const char *file_name, - unsigned int line_number, const char *message, - ...) + unsigned int line_number, const char *message, + ...) __attribute__ ((__format__ (__printf__, 5, 6)));; # define error __error # define error_at_line __error_at_line @@ -86,6 +86,7 @@ extern void __error_at_line (int status, int errnum, const char *file_name, #else /* not _LIBC */ # include +# include # if !HAVE_DECL_STRERROR_R && STRERROR_R_CHAR_P # ifndef HAVE_DECL_STRERROR_R @@ -100,8 +101,33 @@ extern char *program_name; # if HAVE_STRERROR_R || defined strerror_r # define __strerror_r strerror_r -# endif /* HAVE_STRERROR_R || defined strerror_r */ -#endif /* not _LIBC */ +# endif /* HAVE_STRERROR_R || defined strerror_r */ +#endif /* not _LIBC */ + +static inline void +flush_stdout (void) +{ +#if !_LIBC && defined F_GETFL + int stdout_fd; + +# if GNULIB_FREOPEN_SAFER + /* Use of gnulib's freopen-safer module normally ensures that + fileno (stdout) == 1 + whenever stdout is open. */ + stdout_fd = STDOUT_FILENO; +# else + /* POSIX states that fileno (stdout) after fclose is unspecified. But in + practice it is not a problem, because stdout is statically allocated and + the fd of a FILE stream is stored as a field in its allocated memory. */ + stdout_fd = fileno (stdout); +# endif + /* POSIX states that fflush (stdout) after fclose is unspecified; it + is safe in glibc, but not on all other platforms. fflush (NULL) + is always defined, but too draconian. */ + if (0 <= stdout_fd && 0 <= fcntl (stdout_fd, F_GETFL)) +#endif + fflush (stdout); +} static void print_errno_message (int errnum) @@ -149,58 +175,58 @@ error_tail (int status, int errnum, const char *message, va_list args) bool use_malloc = false; while (1) - { - if (__libc_use_alloca (len * sizeof (wchar_t))) - wmessage = (wchar_t *) alloca (len * sizeof (wchar_t)); - else - { - if (!use_malloc) - wmessage = NULL; + { + if (__libc_use_alloca (len * sizeof (wchar_t))) + wmessage = (wchar_t *) alloca (len * sizeof (wchar_t)); + else + { + if (!use_malloc) + wmessage = NULL; - wchar_t *p = (wchar_t *) realloc (wmessage, - len * sizeof (wchar_t)); - if (p == NULL) - { - free (wmessage); - fputws_unlocked (L"out of memory\n", stderr); - return; - } - wmessage = p; - use_malloc = true; - } + wchar_t *p = (wchar_t *) realloc (wmessage, + len * sizeof (wchar_t)); + if (p == NULL) + { + free (wmessage); + fputws_unlocked (L"out of memory\n", stderr); + return; + } + wmessage = p; + use_malloc = true; + } - memset (&st, '\0', sizeof (st)); - tmp = message; + memset (&st, '\0', sizeof (st)); + tmp = message; - res = mbsrtowcs (wmessage, &tmp, len, &st); - if (res != len) - break; + res = mbsrtowcs (wmessage, &tmp, len, &st); + if (res != len) + break; - if (__builtin_expect (len >= SIZE_MAX / 2, 0)) - { - /* This really should not happen if everything is fine. */ - res = (size_t) -1; - break; - } + if (__builtin_expect (len >= SIZE_MAX / 2, 0)) + { + /* This really should not happen if everything is fine. */ + res = (size_t) -1; + break; + } - len *= 2; - } + len *= 2; + } if (res == (size_t) -1) - { - /* The string cannot be converted. */ - if (use_malloc) - { - free (wmessage); - use_malloc = false; - } - wmessage = (wchar_t *) L"???"; - } + { + /* The string cannot be converted. */ + if (use_malloc) + { + free (wmessage); + use_malloc = false; + } + wmessage = (wchar_t *) L"???"; + } __vfwprintf (stderr, wmessage, args); if (use_malloc) - free (wmessage); + free (wmessage); } else #endif @@ -235,16 +261,10 @@ error (int status, int errnum, const char *message, ...) cancellation. Therefore disable cancellation for now. */ int state = PTHREAD_CANCEL_ENABLE; __libc_ptf_call (pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, &state), - 0); + 0); #endif -#if !_LIBC && defined F_GETFL - /* POSIX states that fflush (stdout) after fclose is unspecified; it - is safe in glibc, but not on all other platforms. fflush (NULL) - is always defined, but too draconian. */ - if (0 <= fcntl (1, F_GETFL)) -#endif - fflush (stdout); + flush_stdout (); #ifdef _LIBC _IO_flockfile (stderr); #endif @@ -276,7 +296,7 @@ int error_one_per_line; void error_at_line (int status, int errnum, const char *file_name, - unsigned int line_number, const char *message, ...) + unsigned int line_number, const char *message, ...) { va_list args; @@ -286,10 +306,10 @@ error_at_line (int status, int errnum, const char *file_name, static unsigned int old_line_number; if (old_line_number == line_number - && (file_name == old_file_name - || strcmp (old_file_name, file_name) == 0)) - /* Simply return and print nothing. */ - return; + && (file_name == old_file_name + || strcmp (old_file_name, file_name) == 0)) + /* Simply return and print nothing. */ + return; old_file_name = file_name; old_line_number = line_number; @@ -300,16 +320,10 @@ error_at_line (int status, int errnum, const char *file_name, cancellation. Therefore disable cancellation for now. */ int state = PTHREAD_CANCEL_ENABLE; __libc_ptf_call (pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, &state), - 0); + 0); #endif -#if !_LIBC && defined F_GETFL - /* POSIX states that fflush (stdout) after fclose is unspecified; it - is safe in glibc, but not on all other platforms. fflush (NULL) - is always defined, but too draconian. */ - if (0 <= fcntl (1, F_GETFL)) -#endif - fflush (stdout); + flush_stdout (); #ifdef _LIBC _IO_flockfile (stderr); #endif @@ -326,10 +340,10 @@ error_at_line (int status, int errnum, const char *file_name, #if _LIBC __fxprintf (NULL, file_name != NULL ? "%s:%d: " : " ", - file_name, line_number); + file_name, line_number); #else fprintf (stderr, file_name != NULL ? "%s:%d: " : " ", - file_name, line_number); + file_name, line_number); #endif va_start (args, message); diff --git a/gnulib/error.h b/gnulib/error.h index 6d4968114..9deef02d2 100644 --- a/gnulib/error.h +++ b/gnulib/error.h @@ -1,5 +1,6 @@ /* Declaration for error-reporting function - Copyright (C) 1995, 1996, 1997, 2003, 2006, 2008 Free Software Foundation, Inc. + Copyright (C) 1995, 1996, 1997, 2003, 2006, 2008, 2009, 2010 Free Software + Foundation, Inc. This file is part of the GNU C Library. This program is free software: you can redistribute it and/or modify @@ -19,19 +20,18 @@ #define _ERROR_H 1 #ifndef __attribute__ -/* This feature is available in gcc versions 2.5 and later. */ -# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) -# define __attribute__(Spec) /* empty */ -# endif -/* The __-protected variants of `format' and `printf' attributes - are accepted by gcc versions 2.6.4 (effectively 2.7) and later. */ +/* The __attribute__ feature is available in gcc versions 2.5 and later. + The __-protected variants of the attributes 'format' and 'printf' are + accepted by gcc versions 2.6.4 (effectively 2.7) and later. + We enable __attribute__ only if these are supported too, because + gnulib and libintl do '#define printf __printf__' when they override + the 'printf' function. */ # if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7) -# define __format__ format -# define __printf__ printf +# define __attribute__(Spec) /* empty */ # endif #endif -#ifdef __cplusplus +#ifdef __cplusplus extern "C" { #endif @@ -43,7 +43,7 @@ extern void error (int __status, int __errnum, const char *__format, ...) __attribute__ ((__format__ (__printf__, 3, 4))); extern void error_at_line (int __status, int __errnum, const char *__fname, - unsigned int __lineno, const char *__format, ...) + unsigned int __lineno, const char *__format, ...) __attribute__ ((__format__ (__printf__, 5, 6))); /* If NULL, error will flush stdout, then print on stderr the program @@ -58,7 +58,7 @@ extern unsigned int error_message_count; variable controls whether this mode is selected or not. */ extern int error_one_per_line; -#ifdef __cplusplus +#ifdef __cplusplus } #endif diff --git a/gnulib/fnmatch.c b/gnulib/fnmatch.c index 48bc8b5d2..f15dbb806 100644 --- a/gnulib/fnmatch.c +++ b/gnulib/fnmatch.c @@ -1,5 +1,5 @@ -/* Copyright (C) 1991,1992,1993,1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006,2007 - Free Software Foundation, Inc. +/* Copyright (C) 1991, 1992, 1993, 1996, 1997, 1998, 1999, 2000, 2001, 2002, + 2003, 2004, 2005, 2006, 2007, 2009, 2010 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -21,7 +21,7 @@ /* Enable GNU extensions in fnmatch.h. */ #ifndef _GNU_SOURCE -# define _GNU_SOURCE 1 +# define _GNU_SOURCE 1 #endif #if ! defined __builtin_expect && __GNUC__ < 3 @@ -89,7 +89,7 @@ extern int fnmatch (const char *pattern, const char *string, int flags); # define isblank(c) ((c) == ' ' || (c) == '\t') # endif -# define STREQ(s1, s2) ((strcmp (s1, s2) == 0)) +# define STREQ(s1, s2) (strcmp (s1, s2) == 0) # if defined _LIBC || WIDE_CHAR_SUPPORT /* The GNU C library provides support for user-defined character classes @@ -109,25 +109,25 @@ extern int fnmatch (const char *pattern, const char *string, int flags); # endif # ifdef _LIBC -# define ISWCTYPE(WC, WT) __iswctype (WC, WT) +# define ISWCTYPE(WC, WT) __iswctype (WC, WT) # else -# define ISWCTYPE(WC, WT) iswctype (WC, WT) +# define ISWCTYPE(WC, WT) iswctype (WC, WT) # endif # if (HAVE_MBSTATE_T && HAVE_MBSRTOWCS) || _LIBC /* In this case we are implementing the multibyte character handling. */ -# define HANDLE_MULTIBYTE 1 +# define HANDLE_MULTIBYTE 1 # endif # else # define CHAR_CLASS_MAX_LENGTH 6 /* Namely, `xdigit'. */ -# define IS_CHAR_CLASS(string) \ - (STREQ (string, "alpha") || STREQ (string, "upper") \ - || STREQ (string, "lower") || STREQ (string, "digit") \ - || STREQ (string, "alnum") || STREQ (string, "xdigit") \ - || STREQ (string, "space") || STREQ (string, "print") \ - || STREQ (string, "punct") || STREQ (string, "graph") \ +# define IS_CHAR_CLASS(string) \ + (STREQ (string, "alpha") || STREQ (string, "upper") \ + || STREQ (string, "lower") || STREQ (string, "digit") \ + || STREQ (string, "alnum") || STREQ (string, "xdigit") \ + || STREQ (string, "space") || STREQ (string, "print") \ + || STREQ (string, "punct") || STREQ (string, "graph") \ || STREQ (string, "cntrl") || STREQ (string, "blank")) # endif @@ -145,17 +145,17 @@ static int posixly_correct; /* Note that this evaluates C many times. */ # define FOLD(c) ((flags & FNM_CASEFOLD) ? tolower (c) : (c)) -# define CHAR char -# define UCHAR unsigned char -# define INT int -# define FCT internal_fnmatch -# define EXT ext_match -# define END end_pattern -# define L_(CS) CS +# define CHAR char +# define UCHAR unsigned char +# define INT int +# define FCT internal_fnmatch +# define EXT ext_match +# define END end_pattern +# define L_(CS) CS # ifdef _LIBC -# define BTOWC(C) __btowc (C) +# define BTOWC(C) __btowc (C) # else -# define BTOWC(C) btowc (C) +# define BTOWC(C) btowc (C) # endif # define STRLEN(S) strlen (S) # define STRCAT(D, S) strcat (D, S) @@ -175,14 +175,14 @@ static int posixly_correct; # if HANDLE_MULTIBYTE # define FOLD(c) ((flags & FNM_CASEFOLD) ? towlower (c) : (c)) -# define CHAR wchar_t -# define UCHAR wint_t -# define INT wint_t -# define FCT internal_fnwmatch -# define EXT ext_wmatch -# define END end_wpattern -# define L_(CS) L##CS -# define BTOWC(C) (C) +# define CHAR wchar_t +# define UCHAR wint_t +# define INT wint_t +# define FCT internal_fnwmatch +# define EXT ext_wmatch +# define END end_wpattern +# define L_(CS) L##CS +# define BTOWC(C) (C) # ifdef _LIBC # define STRLEN(S) __wcslen (S) # define STRCAT(D, S) __wcscat (D, S) @@ -218,40 +218,40 @@ is_char_class (const wchar_t *wcs) /* Test for a printable character from the portable character set. */ # ifdef _LIBC if (*wcs < 0x20 || *wcs > 0x7e - || *wcs == 0x24 || *wcs == 0x40 || *wcs == 0x60) - return (wctype_t) 0; + || *wcs == 0x24 || *wcs == 0x40 || *wcs == 0x60) + return (wctype_t) 0; # else switch (*wcs) - { - case L' ': case L'!': case L'"': case L'#': case L'%': - case L'&': case L'\'': case L'(': case L')': case L'*': - case L'+': case L',': case L'-': case L'.': case L'/': - case L'0': case L'1': case L'2': case L'3': case L'4': - case L'5': case L'6': case L'7': case L'8': case L'9': - case L':': case L';': case L'<': case L'=': case L'>': - case L'?': - case L'A': case L'B': case L'C': case L'D': case L'E': - case L'F': case L'G': case L'H': case L'I': case L'J': - case L'K': case L'L': case L'M': case L'N': case L'O': - case L'P': case L'Q': case L'R': case L'S': case L'T': - case L'U': case L'V': case L'W': case L'X': case L'Y': - case L'Z': - case L'[': case L'\\': case L']': case L'^': case L'_': - case L'a': case L'b': case L'c': case L'd': case L'e': - case L'f': case L'g': case L'h': case L'i': case L'j': - case L'k': case L'l': case L'm': case L'n': case L'o': - case L'p': case L'q': case L'r': case L's': case L't': - case L'u': case L'v': case L'w': case L'x': case L'y': - case L'z': case L'{': case L'|': case L'}': case L'~': - break; - default: - return (wctype_t) 0; - } + { + case L' ': case L'!': case L'"': case L'#': case L'%': + case L'&': case L'\'': case L'(': case L')': case L'*': + case L'+': case L',': case L'-': case L'.': case L'/': + case L'0': case L'1': case L'2': case L'3': case L'4': + case L'5': case L'6': case L'7': case L'8': case L'9': + case L':': case L';': case L'<': case L'=': case L'>': + case L'?': + case L'A': case L'B': case L'C': case L'D': case L'E': + case L'F': case L'G': case L'H': case L'I': case L'J': + case L'K': case L'L': case L'M': case L'N': case L'O': + case L'P': case L'Q': case L'R': case L'S': case L'T': + case L'U': case L'V': case L'W': case L'X': case L'Y': + case L'Z': + case L'[': case L'\\': case L']': case L'^': case L'_': + case L'a': case L'b': case L'c': case L'd': case L'e': + case L'f': case L'g': case L'h': case L'i': case L'j': + case L'k': case L'l': case L'm': case L'n': case L'o': + case L'p': case L'q': case L'r': case L's': case L't': + case L'u': case L'v': case L'w': case L'x': case L'y': + case L'z': case L'{': case L'|': case L'}': case L'~': + break; + default: + return (wctype_t) 0; + } # endif /* Avoid overrunning the buffer. */ if (cp == s + CHAR_CLASS_MAX_LENGTH) - return (wctype_t) 0; + return (wctype_t) 0; *cp++ = (char) *wcs++; } @@ -287,58 +287,58 @@ fnmatch (const char *pattern, const char *string, int flags) int res; /* Calculate the size needed to convert the strings to - wide characters. */ + wide characters. */ memset (&ps, '\0', sizeof (ps)); patsize = mbsrtowcs (NULL, &pattern, 0, &ps) + 1; if (__builtin_expect (patsize != 0, 1)) - { - assert (mbsinit (&ps)); - strsize = mbsrtowcs (NULL, &string, 0, &ps) + 1; - if (__builtin_expect (strsize != 0, 1)) - { - assert (mbsinit (&ps)); - totsize = patsize + strsize; - if (__builtin_expect (! (patsize <= totsize - && totsize <= SIZE_MAX / sizeof (wchar_t)), - 0)) - { - errno = ENOMEM; - return -1; - } + { + assert (mbsinit (&ps)); + strsize = mbsrtowcs (NULL, &string, 0, &ps) + 1; + if (__builtin_expect (strsize != 0, 1)) + { + assert (mbsinit (&ps)); + totsize = patsize + strsize; + if (__builtin_expect (! (patsize <= totsize + && totsize <= SIZE_MAX / sizeof (wchar_t)), + 0)) + { + errno = ENOMEM; + return -1; + } - /* Allocate room for the wide characters. */ - if (__builtin_expect (totsize < ALLOCA_LIMIT, 1)) - wpattern = (wchar_t *) alloca (totsize * sizeof (wchar_t)); - else - { - wpattern = malloc (totsize * sizeof (wchar_t)); - if (__builtin_expect (! wpattern, 0)) - { - errno = ENOMEM; - return -1; - } - } - wstring = wpattern + patsize; + /* Allocate room for the wide characters. */ + if (__builtin_expect (totsize < ALLOCA_LIMIT, 1)) + wpattern = (wchar_t *) alloca (totsize * sizeof (wchar_t)); + else + { + wpattern = malloc (totsize * sizeof (wchar_t)); + if (__builtin_expect (! wpattern, 0)) + { + errno = ENOMEM; + return -1; + } + } + wstring = wpattern + patsize; - /* Convert the strings into wide characters. */ - mbsrtowcs (wpattern, &pattern, patsize, &ps); - assert (mbsinit (&ps)); - mbsrtowcs (wstring, &string, strsize, &ps); + /* Convert the strings into wide characters. */ + mbsrtowcs (wpattern, &pattern, patsize, &ps); + assert (mbsinit (&ps)); + mbsrtowcs (wstring, &string, strsize, &ps); - res = internal_fnwmatch (wpattern, wstring, wstring + strsize - 1, - flags & FNM_PERIOD, flags); + res = internal_fnwmatch (wpattern, wstring, wstring + strsize - 1, + flags & FNM_PERIOD, flags); - if (__builtin_expect (! (totsize < ALLOCA_LIMIT), 0)) - free (wpattern); - return res; - } - } + if (__builtin_expect (! (totsize < ALLOCA_LIMIT), 0)) + free (wpattern); + return res; + } + } } # endif /* HANDLE_MULTIBYTE */ return internal_fnmatch (pattern, string, string + strlen (string), - flags & FNM_PERIOD, flags); + flags & FNM_PERIOD, flags); } # ifdef _LIBC @@ -351,4 +351,4 @@ compat_symbol (libc, __fnmatch_old, fnmatch, GLIBC_2_0); libc_hidden_ver (__fnmatch, fnmatch) # endif -#endif /* _LIBC or not __GNU_LIBRARY__. */ +#endif /* _LIBC or not __GNU_LIBRARY__. */ diff --git a/gnulib/fnmatch_loop.c b/gnulib/fnmatch_loop.c index c2182ffb0..8cd444404 100644 --- a/gnulib/fnmatch_loop.c +++ b/gnulib/fnmatch_loop.c @@ -1,5 +1,5 @@ -/* Copyright (C) 1991,1992,1993,1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006 - Free Software Foundation, Inc. +/* Copyright (C) 1991, 1992, 1993, 1996, 1997, 1998, 1999, 2000, 2001, 2002, + 2003, 2004, 2005, 2006, 2009, 2010 Free Software Foundation, Inc. This file is part of the GNU C Library. This program is free software; you can redistribute it and/or modify @@ -19,7 +19,7 @@ /* Match STRING against the file name pattern PATTERN, returning zero if it matches, nonzero if not. */ static int EXT (INT opt, const CHAR *pattern, const CHAR *string, - const CHAR *string_end, bool no_leading_period, int flags) + const CHAR *string_end, bool no_leading_period, int flags) internal_function; static const CHAR *END (const CHAR *patternp) internal_function; @@ -46,310 +46,310 @@ FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, c = FOLD (c); switch (c) - { - case L_('?'): - if (__builtin_expect (flags & FNM_EXTMATCH, 0) && *p == '(') - { - int res; + { + case L_('?'): + if (__builtin_expect (flags & FNM_EXTMATCH, 0) && *p == '(') + { + int res; - res = EXT (c, p, n, string_end, no_leading_period, - flags); - if (res != -1) - return res; - } + res = EXT (c, p, n, string_end, no_leading_period, + flags); + if (res != -1) + return res; + } - if (n == string_end) - return FNM_NOMATCH; - else if (*n == L_('/') && (flags & FNM_FILE_NAME)) - return FNM_NOMATCH; - else if (*n == L_('.') && no_leading_period) - return FNM_NOMATCH; - break; + if (n == string_end) + return FNM_NOMATCH; + else if (*n == L_('/') && (flags & FNM_FILE_NAME)) + return FNM_NOMATCH; + else if (*n == L_('.') && no_leading_period) + return FNM_NOMATCH; + break; - case L_('\\'): - if (!(flags & FNM_NOESCAPE)) - { - c = *p++; - if (c == L_('\0')) - /* Trailing \ loses. */ - return FNM_NOMATCH; - c = FOLD (c); - } - if (n == string_end || FOLD ((UCHAR) *n) != c) - return FNM_NOMATCH; - break; + case L_('\\'): + if (!(flags & FNM_NOESCAPE)) + { + c = *p++; + if (c == L_('\0')) + /* Trailing \ loses. */ + return FNM_NOMATCH; + c = FOLD (c); + } + if (n == string_end || FOLD ((UCHAR) *n) != c) + return FNM_NOMATCH; + break; - case L_('*'): - if (__builtin_expect (flags & FNM_EXTMATCH, 0) && *p == '(') - { - int res; + case L_('*'): + if (__builtin_expect (flags & FNM_EXTMATCH, 0) && *p == '(') + { + int res; - res = EXT (c, p, n, string_end, no_leading_period, - flags); - if (res != -1) - return res; - } + res = EXT (c, p, n, string_end, no_leading_period, + flags); + if (res != -1) + return res; + } - if (n != string_end && *n == L_('.') && no_leading_period) - return FNM_NOMATCH; + if (n != string_end && *n == L_('.') && no_leading_period) + return FNM_NOMATCH; - for (c = *p++; c == L_('?') || c == L_('*'); c = *p++) - { - if (*p == L_('(') && (flags & FNM_EXTMATCH) != 0) - { - const CHAR *endp = END (p); - if (endp != p) - { - /* This is a pattern. Skip over it. */ - p = endp; - continue; - } - } + for (c = *p++; c == L_('?') || c == L_('*'); c = *p++) + { + if (*p == L_('(') && (flags & FNM_EXTMATCH) != 0) + { + const CHAR *endp = END (p); + if (endp != p) + { + /* This is a pattern. Skip over it. */ + p = endp; + continue; + } + } - if (c == L_('?')) - { - /* A ? needs to match one character. */ - if (n == string_end) - /* There isn't another character; no match. */ - return FNM_NOMATCH; - else if (*n == L_('/') - && __builtin_expect (flags & FNM_FILE_NAME, 0)) - /* A slash does not match a wildcard under - FNM_FILE_NAME. */ - return FNM_NOMATCH; - else - /* One character of the string is consumed in matching - this ? wildcard, so *??? won't match if there are - less than three characters. */ - ++n; - } - } + if (c == L_('?')) + { + /* A ? needs to match one character. */ + if (n == string_end) + /* There isn't another character; no match. */ + return FNM_NOMATCH; + else if (*n == L_('/') + && __builtin_expect (flags & FNM_FILE_NAME, 0)) + /* A slash does not match a wildcard under + FNM_FILE_NAME. */ + return FNM_NOMATCH; + else + /* One character of the string is consumed in matching + this ? wildcard, so *??? won't match if there are + less than three characters. */ + ++n; + } + } - if (c == L_('\0')) - /* The wildcard(s) is/are the last element of the pattern. - If the name is a file name and contains another slash - this means it cannot match, unless the FNM_LEADING_DIR - flag is set. */ - { - int result = (flags & FNM_FILE_NAME) == 0 ? 0 : FNM_NOMATCH; + if (c == L_('\0')) + /* The wildcard(s) is/are the last element of the pattern. + If the name is a file name and contains another slash + this means it cannot match, unless the FNM_LEADING_DIR + flag is set. */ + { + int result = (flags & FNM_FILE_NAME) == 0 ? 0 : FNM_NOMATCH; - if (flags & FNM_FILE_NAME) - { - if (flags & FNM_LEADING_DIR) - result = 0; - else - { - if (MEMCHR (n, L_('/'), string_end - n) == NULL) - result = 0; - } - } + if (flags & FNM_FILE_NAME) + { + if (flags & FNM_LEADING_DIR) + result = 0; + else + { + if (MEMCHR (n, L_('/'), string_end - n) == NULL) + result = 0; + } + } - return result; - } - else - { - const CHAR *endp; + return result; + } + else + { + const CHAR *endp; - endp = MEMCHR (n, (flags & FNM_FILE_NAME) ? L_('/') : L_('\0'), - string_end - n); - if (endp == NULL) - endp = string_end; + endp = MEMCHR (n, (flags & FNM_FILE_NAME) ? L_('/') : L_('\0'), + string_end - n); + if (endp == NULL) + endp = string_end; - if (c == L_('[') - || (__builtin_expect (flags & FNM_EXTMATCH, 0) != 0 - && (c == L_('@') || c == L_('+') || c == L_('!')) - && *p == L_('('))) - { - int flags2 = ((flags & FNM_FILE_NAME) - ? flags : (flags & ~FNM_PERIOD)); - bool no_leading_period2 = no_leading_period; + if (c == L_('[') + || (__builtin_expect (flags & FNM_EXTMATCH, 0) != 0 + && (c == L_('@') || c == L_('+') || c == L_('!')) + && *p == L_('('))) + { + int flags2 = ((flags & FNM_FILE_NAME) + ? flags : (flags & ~FNM_PERIOD)); + bool no_leading_period2 = no_leading_period; - for (--p; n < endp; ++n, no_leading_period2 = false) - if (FCT (p, n, string_end, no_leading_period2, flags2) - == 0) - return 0; - } - else if (c == L_('/') && (flags & FNM_FILE_NAME)) - { - while (n < string_end && *n != L_('/')) - ++n; - if (n < string_end && *n == L_('/') - && (FCT (p, n + 1, string_end, flags & FNM_PERIOD, flags) - == 0)) - return 0; - } - else - { - int flags2 = ((flags & FNM_FILE_NAME) - ? flags : (flags & ~FNM_PERIOD)); - int no_leading_period2 = no_leading_period; + for (--p; n < endp; ++n, no_leading_period2 = false) + if (FCT (p, n, string_end, no_leading_period2, flags2) + == 0) + return 0; + } + else if (c == L_('/') && (flags & FNM_FILE_NAME)) + { + while (n < string_end && *n != L_('/')) + ++n; + if (n < string_end && *n == L_('/') + && (FCT (p, n + 1, string_end, flags & FNM_PERIOD, flags) + == 0)) + return 0; + } + else + { + int flags2 = ((flags & FNM_FILE_NAME) + ? flags : (flags & ~FNM_PERIOD)); + int no_leading_period2 = no_leading_period; - if (c == L_('\\') && !(flags & FNM_NOESCAPE)) - c = *p; - c = FOLD (c); - for (--p; n < endp; ++n, no_leading_period2 = false) - if (FOLD ((UCHAR) *n) == c - && (FCT (p, n, string_end, no_leading_period2, flags2) - == 0)) - return 0; - } - } + if (c == L_('\\') && !(flags & FNM_NOESCAPE)) + c = *p; + c = FOLD (c); + for (--p; n < endp; ++n, no_leading_period2 = false) + if (FOLD ((UCHAR) *n) == c + && (FCT (p, n, string_end, no_leading_period2, flags2) + == 0)) + return 0; + } + } - /* If we come here no match is possible with the wildcard. */ - return FNM_NOMATCH; + /* If we come here no match is possible with the wildcard. */ + return FNM_NOMATCH; - case L_('['): - { - /* Nonzero if the sense of the character class is inverted. */ - register bool not; - CHAR cold; - UCHAR fn; + case L_('['): + { + /* Nonzero if the sense of the character class is inverted. */ + register bool not; + CHAR cold; + UCHAR fn; - if (posixly_correct == 0) - posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1; + if (posixly_correct == 0) + posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1; - if (n == string_end) - return FNM_NOMATCH; + if (n == string_end) + return FNM_NOMATCH; - if (*n == L_('.') && no_leading_period) - return FNM_NOMATCH; + if (*n == L_('.') && no_leading_period) + return FNM_NOMATCH; - if (*n == L_('/') && (flags & FNM_FILE_NAME)) - /* `/' cannot be matched. */ - return FNM_NOMATCH; + if (*n == L_('/') && (flags & FNM_FILE_NAME)) + /* `/' cannot be matched. */ + return FNM_NOMATCH; - not = (*p == L_('!') || (posixly_correct < 0 && *p == L_('^'))); - if (not) - ++p; + not = (*p == L_('!') || (posixly_correct < 0 && *p == L_('^'))); + if (not) + ++p; - fn = FOLD ((UCHAR) *n); + fn = FOLD ((UCHAR) *n); - c = *p++; - for (;;) - { - if (!(flags & FNM_NOESCAPE) && c == L_('\\')) - { - if (*p == L_('\0')) - return FNM_NOMATCH; - c = FOLD ((UCHAR) *p); - ++p; + c = *p++; + for (;;) + { + if (!(flags & FNM_NOESCAPE) && c == L_('\\')) + { + if (*p == L_('\0')) + return FNM_NOMATCH; + c = FOLD ((UCHAR) *p); + ++p; - goto normal_bracket; - } - else if (c == L_('[') && *p == L_(':')) - { - /* Leave room for the null. */ - CHAR str[CHAR_CLASS_MAX_LENGTH + 1]; - size_t c1 = 0; + goto normal_bracket; + } + else if (c == L_('[') && *p == L_(':')) + { + /* Leave room for the null. */ + CHAR str[CHAR_CLASS_MAX_LENGTH + 1]; + size_t c1 = 0; #if defined _LIBC || WIDE_CHAR_SUPPORT - wctype_t wt; + wctype_t wt; #endif - const CHAR *startp = p; + const CHAR *startp = p; - for (;;) - { - if (c1 == CHAR_CLASS_MAX_LENGTH) - /* The name is too long and therefore the pattern - is ill-formed. */ - return FNM_NOMATCH; + for (;;) + { + if (c1 == CHAR_CLASS_MAX_LENGTH) + /* The name is too long and therefore the pattern + is ill-formed. */ + return FNM_NOMATCH; - c = *++p; - if (c == L_(':') && p[1] == L_(']')) - { - p += 2; - break; - } - if (c < L_('a') || c >= L_('z')) - { - /* This cannot possibly be a character class name. - Match it as a normal range. */ - p = startp; - c = L_('['); - goto normal_bracket; - } - str[c1++] = c; - } - str[c1] = L_('\0'); + c = *++p; + if (c == L_(':') && p[1] == L_(']')) + { + p += 2; + break; + } + if (c < L_('a') || c >= L_('z')) + { + /* This cannot possibly be a character class name. + Match it as a normal range. */ + p = startp; + c = L_('['); + goto normal_bracket; + } + str[c1++] = c; + } + str[c1] = L_('\0'); #if defined _LIBC || WIDE_CHAR_SUPPORT - wt = IS_CHAR_CLASS (str); - if (wt == 0) - /* Invalid character class name. */ - return FNM_NOMATCH; + wt = IS_CHAR_CLASS (str); + if (wt == 0) + /* Invalid character class name. */ + return FNM_NOMATCH; # if defined _LIBC && ! WIDE_CHAR_VERSION - /* The following code is glibc specific but does - there a good job in speeding up the code since - we can avoid the btowc() call. */ - if (_ISCTYPE ((UCHAR) *n, wt)) - goto matched; + /* The following code is glibc specific but does + there a good job in speeding up the code since + we can avoid the btowc() call. */ + if (_ISCTYPE ((UCHAR) *n, wt)) + goto matched; # else - if (ISWCTYPE (BTOWC ((UCHAR) *n), wt)) - goto matched; + if (ISWCTYPE (BTOWC ((UCHAR) *n), wt)) + goto matched; # endif #else - if ((STREQ (str, L_("alnum")) && isalnum ((UCHAR) *n)) - || (STREQ (str, L_("alpha")) && isalpha ((UCHAR) *n)) - || (STREQ (str, L_("blank")) && isblank ((UCHAR) *n)) - || (STREQ (str, L_("cntrl")) && iscntrl ((UCHAR) *n)) - || (STREQ (str, L_("digit")) && isdigit ((UCHAR) *n)) - || (STREQ (str, L_("graph")) && isgraph ((UCHAR) *n)) - || (STREQ (str, L_("lower")) && islower ((UCHAR) *n)) - || (STREQ (str, L_("print")) && isprint ((UCHAR) *n)) - || (STREQ (str, L_("punct")) && ispunct ((UCHAR) *n)) - || (STREQ (str, L_("space")) && isspace ((UCHAR) *n)) - || (STREQ (str, L_("upper")) && isupper ((UCHAR) *n)) - || (STREQ (str, L_("xdigit")) && isxdigit ((UCHAR) *n))) - goto matched; + if ((STREQ (str, L_("alnum")) && isalnum ((UCHAR) *n)) + || (STREQ (str, L_("alpha")) && isalpha ((UCHAR) *n)) + || (STREQ (str, L_("blank")) && isblank ((UCHAR) *n)) + || (STREQ (str, L_("cntrl")) && iscntrl ((UCHAR) *n)) + || (STREQ (str, L_("digit")) && isdigit ((UCHAR) *n)) + || (STREQ (str, L_("graph")) && isgraph ((UCHAR) *n)) + || (STREQ (str, L_("lower")) && islower ((UCHAR) *n)) + || (STREQ (str, L_("print")) && isprint ((UCHAR) *n)) + || (STREQ (str, L_("punct")) && ispunct ((UCHAR) *n)) + || (STREQ (str, L_("space")) && isspace ((UCHAR) *n)) + || (STREQ (str, L_("upper")) && isupper ((UCHAR) *n)) + || (STREQ (str, L_("xdigit")) && isxdigit ((UCHAR) *n))) + goto matched; #endif - c = *p++; - } + c = *p++; + } #ifdef _LIBC - else if (c == L_('[') && *p == L_('=')) - { - UCHAR str[1]; - uint32_t nrules = - _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES); - const CHAR *startp = p; + else if (c == L_('[') && *p == L_('=')) + { + UCHAR str[1]; + uint32_t nrules = + _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES); + const CHAR *startp = p; - c = *++p; - if (c == L_('\0')) - { - p = startp; - c = L_('['); - goto normal_bracket; - } - str[0] = c; + c = *++p; + if (c == L_('\0')) + { + p = startp; + c = L_('['); + goto normal_bracket; + } + str[0] = c; - c = *++p; - if (c != L_('=') || p[1] != L_(']')) - { - p = startp; - c = L_('['); - goto normal_bracket; - } - p += 2; + c = *++p; + if (c != L_('=') || p[1] != L_(']')) + { + p = startp; + c = L_('['); + goto normal_bracket; + } + p += 2; - if (nrules == 0) - { - if ((UCHAR) *n == str[0]) - goto matched; - } - else - { - const int32_t *table; + if (nrules == 0) + { + if ((UCHAR) *n == str[0]) + goto matched; + } + else + { + const int32_t *table; # if WIDE_CHAR_VERSION - const int32_t *weights; - const int32_t *extra; + const int32_t *weights; + const int32_t *extra; # else - const unsigned char *weights; - const unsigned char *extra; + const unsigned char *weights; + const unsigned char *extra; # endif - const int32_t *indirect; - int32_t idx; - const UCHAR *cp = (const UCHAR *) str; + const int32_t *indirect; + int32_t idx; + const UCHAR *cp = (const UCHAR *) str; - /* This #include defines a local function! */ + /* This #include defines a local function! */ # if WIDE_CHAR_VERSION # include # else @@ -357,605 +357,610 @@ FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, # endif # if WIDE_CHAR_VERSION - table = (const int32_t *) - _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEWC); - weights = (const int32_t *) - _NL_CURRENT (LC_COLLATE, _NL_COLLATE_WEIGHTWC); - extra = (const int32_t *) - _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAWC); - indirect = (const int32_t *) - _NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTWC); + table = (const int32_t *) + _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEWC); + weights = (const int32_t *) + _NL_CURRENT (LC_COLLATE, _NL_COLLATE_WEIGHTWC); + extra = (const int32_t *) + _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAWC); + indirect = (const int32_t *) + _NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTWC); # else - table = (const int32_t *) - _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB); - weights = (const unsigned char *) - _NL_CURRENT (LC_COLLATE, _NL_COLLATE_WEIGHTMB); - extra = (const unsigned char *) - _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAMB); - indirect = (const int32_t *) - _NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTMB); + table = (const int32_t *) + _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB); + weights = (const unsigned char *) + _NL_CURRENT (LC_COLLATE, _NL_COLLATE_WEIGHTMB); + extra = (const unsigned char *) + _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAMB); + indirect = (const int32_t *) + _NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTMB); # endif - idx = findidx (&cp); - if (idx != 0) - { - /* We found a table entry. Now see whether the - character we are currently at has the same - equivalance class value. */ - int len = weights[idx]; - int32_t idx2; - const UCHAR *np = (const UCHAR *) n; + idx = findidx (&cp); + if (idx != 0) + { + /* We found a table entry. Now see whether the + character we are currently at has the same + equivalance class value. */ + int len = weights[idx & 0xffffff]; + int32_t idx2; + const UCHAR *np = (const UCHAR *) n; - idx2 = findidx (&np); - if (idx2 != 0 && len == weights[idx2]) - { - int cnt = 0; + idx2 = findidx (&np); + if (idx2 != 0 + && (idx >> 24) == (idx2 >> 24) + && len == weights[idx2 & 0xffffff]) + { + int cnt = 0; - while (cnt < len - && (weights[idx + 1 + cnt] - == weights[idx2 + 1 + cnt])) - ++cnt; + idx &= 0xffffff; + idx2 &= 0xffffff; - if (cnt == len) - goto matched; - } - } - } + while (cnt < len + && (weights[idx + 1 + cnt] + == weights[idx2 + 1 + cnt])) + ++cnt; - c = *p++; - } + if (cnt == len) + goto matched; + } + } + } + + c = *p++; + } #endif - else if (c == L_('\0')) - /* [ (unterminated) loses. */ - return FNM_NOMATCH; - else - { - bool is_range = false; + else if (c == L_('\0')) + /* [ (unterminated) loses. */ + return FNM_NOMATCH; + else + { + bool is_range = false; #ifdef _LIBC - bool is_seqval = false; + bool is_seqval = false; - if (c == L_('[') && *p == L_('.')) - { - uint32_t nrules = - _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES); - const CHAR *startp = p; - size_t c1 = 0; + if (c == L_('[') && *p == L_('.')) + { + uint32_t nrules = + _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES); + const CHAR *startp = p; + size_t c1 = 0; - while (1) - { - c = *++p; - if (c == L_('.') && p[1] == L_(']')) - { - p += 2; - break; - } - if (c == '\0') - return FNM_NOMATCH; - ++c1; - } + while (1) + { + c = *++p; + if (c == L_('.') && p[1] == L_(']')) + { + p += 2; + break; + } + if (c == '\0') + return FNM_NOMATCH; + ++c1; + } - /* We have to handling the symbols differently in - ranges since then the collation sequence is - important. */ - is_range = *p == L_('-') && p[1] != L_('\0'); + /* We have to handling the symbols differently in + ranges since then the collation sequence is + important. */ + is_range = *p == L_('-') && p[1] != L_('\0'); - if (nrules == 0) - { - /* There are no names defined in the collation - data. Therefore we only accept the trivial - names consisting of the character itself. */ - if (c1 != 1) - return FNM_NOMATCH; + if (nrules == 0) + { + /* There are no names defined in the collation + data. Therefore we only accept the trivial + names consisting of the character itself. */ + if (c1 != 1) + return FNM_NOMATCH; - if (!is_range && *n == startp[1]) - goto matched; + if (!is_range && *n == startp[1]) + goto matched; - cold = startp[1]; - c = *p++; - } - else - { - int32_t table_size; - const int32_t *symb_table; + cold = startp[1]; + c = *p++; + } + else + { + int32_t table_size; + const int32_t *symb_table; # ifdef WIDE_CHAR_VERSION - char str[c1]; - size_t strcnt; + char str[c1]; + size_t strcnt; # else # define str (startp + 1) # endif - const unsigned char *extra; - int32_t idx; - int32_t elem; - int32_t second; - int32_t hash; + const unsigned char *extra; + int32_t idx; + int32_t elem; + int32_t second; + int32_t hash; # ifdef WIDE_CHAR_VERSION - /* We have to convert the name to a single-byte - string. This is possible since the names - consist of ASCII characters and the internal - representation is UCS4. */ - for (strcnt = 0; strcnt < c1; ++strcnt) - str[strcnt] = startp[1 + strcnt]; + /* We have to convert the name to a single-byte + string. This is possible since the names + consist of ASCII characters and the internal + representation is UCS4. */ + for (strcnt = 0; strcnt < c1; ++strcnt) + str[strcnt] = startp[1 + strcnt]; # endif - table_size = - _NL_CURRENT_WORD (LC_COLLATE, - _NL_COLLATE_SYMB_HASH_SIZEMB); - symb_table = (const int32_t *) - _NL_CURRENT (LC_COLLATE, - _NL_COLLATE_SYMB_TABLEMB); - extra = (const unsigned char *) - _NL_CURRENT (LC_COLLATE, - _NL_COLLATE_SYMB_EXTRAMB); + table_size = + _NL_CURRENT_WORD (LC_COLLATE, + _NL_COLLATE_SYMB_HASH_SIZEMB); + symb_table = (const int32_t *) + _NL_CURRENT (LC_COLLATE, + _NL_COLLATE_SYMB_TABLEMB); + extra = (const unsigned char *) + _NL_CURRENT (LC_COLLATE, + _NL_COLLATE_SYMB_EXTRAMB); - /* Locate the character in the hashing table. */ - hash = elem_hash (str, c1); + /* Locate the character in the hashing table. */ + hash = elem_hash (str, c1); - idx = 0; - elem = hash % table_size; - if (symb_table[2 * elem] != 0) - { - second = hash % (table_size - 2) + 1; + idx = 0; + elem = hash % table_size; + if (symb_table[2 * elem] != 0) + { + second = hash % (table_size - 2) + 1; - do - { - /* First compare the hashing value. */ - if (symb_table[2 * elem] == hash - && (c1 - == extra[symb_table[2 * elem + 1]]) - && memcmp (str, - &extra[symb_table[2 * elem - + 1] - + 1], c1) == 0) - { - /* Yep, this is the entry. */ - idx = symb_table[2 * elem + 1]; - idx += 1 + extra[idx]; - break; - } + do + { + /* First compare the hashing value. */ + if (symb_table[2 * elem] == hash + && (c1 + == extra[symb_table[2 * elem + 1]]) + && memcmp (str, + &extra[symb_table[2 * elem + + 1] + + 1], c1) == 0) + { + /* Yep, this is the entry. */ + idx = symb_table[2 * elem + 1]; + idx += 1 + extra[idx]; + break; + } - /* Next entry. */ - elem += second; - } - while (symb_table[2 * elem] != 0); - } + /* Next entry. */ + elem += second; + } + while (symb_table[2 * elem] != 0); + } - if (symb_table[2 * elem] != 0) - { - /* Compare the byte sequence but only if - this is not part of a range. */ + if (symb_table[2 * elem] != 0) + { + /* Compare the byte sequence but only if + this is not part of a range. */ # ifdef WIDE_CHAR_VERSION - int32_t *wextra; + int32_t *wextra; - idx += 1 + extra[idx]; - /* Adjust for the alignment. */ - idx = (idx + 3) & ~3; + idx += 1 + extra[idx]; + /* Adjust for the alignment. */ + idx = (idx + 3) & ~3; - wextra = (int32_t *) &extra[idx + 4]; + wextra = (int32_t *) &extra[idx + 4]; # endif - if (! is_range) - { + if (! is_range) + { # ifdef WIDE_CHAR_VERSION - for (c1 = 0; - (int32_t) c1 < wextra[idx]; - ++c1) - if (n[c1] != wextra[1 + c1]) - break; + for (c1 = 0; + (int32_t) c1 < wextra[idx]; + ++c1) + if (n[c1] != wextra[1 + c1]) + break; - if ((int32_t) c1 == wextra[idx]) - goto matched; + if ((int32_t) c1 == wextra[idx]) + goto matched; # else - for (c1 = 0; c1 < extra[idx]; ++c1) - if (n[c1] != extra[1 + c1]) - break; + for (c1 = 0; c1 < extra[idx]; ++c1) + if (n[c1] != extra[1 + c1]) + break; - if (c1 == extra[idx]) - goto matched; + if (c1 == extra[idx]) + goto matched; # endif - } + } - /* Get the collation sequence value. */ - is_seqval = true; + /* Get the collation sequence value. */ + is_seqval = true; # ifdef WIDE_CHAR_VERSION - cold = wextra[1 + wextra[idx]]; + cold = wextra[1 + wextra[idx]]; # else - /* Adjust for the alignment. */ - idx += 1 + extra[idx]; - idx = (idx + 3) & ~4; - cold = *((int32_t *) &extra[idx]); + /* Adjust for the alignment. */ + idx += 1 + extra[idx]; + idx = (idx + 3) & ~4; + cold = *((int32_t *) &extra[idx]); # endif - c = *p++; - } - else if (c1 == 1) - { - /* No valid character. Match it as a - single byte. */ - if (!is_range && *n == str[0]) - goto matched; + c = *p++; + } + else if (c1 == 1) + { + /* No valid character. Match it as a + single byte. */ + if (!is_range && *n == str[0]) + goto matched; - cold = str[0]; - c = *p++; - } - else - return FNM_NOMATCH; - } - } - else + cold = str[0]; + c = *p++; + } + else + return FNM_NOMATCH; + } + } + else # undef str #endif - { - c = FOLD (c); - normal_bracket: + { + c = FOLD (c); + normal_bracket: - /* We have to handling the symbols differently in - ranges since then the collation sequence is - important. */ - is_range = (*p == L_('-') && p[1] != L_('\0') - && p[1] != L_(']')); + /* We have to handling the symbols differently in + ranges since then the collation sequence is + important. */ + is_range = (*p == L_('-') && p[1] != L_('\0') + && p[1] != L_(']')); - if (!is_range && c == fn) - goto matched; + if (!is_range && c == fn) + goto matched; #if _LIBC - /* This is needed if we goto normal_bracket; from - outside of is_seqval's scope. */ - is_seqval = false; + /* This is needed if we goto normal_bracket; from + outside of is_seqval's scope. */ + is_seqval = false; #endif - cold = c; - c = *p++; - } + cold = c; + c = *p++; + } - if (c == L_('-') && *p != L_(']')) - { + if (c == L_('-') && *p != L_(']')) + { #if _LIBC - /* We have to find the collation sequence - value for C. Collation sequence is nothing - we can regularly access. The sequence - value is defined by the order in which the - definitions of the collation values for the - various characters appear in the source - file. A strange concept, nowhere - documented. */ - uint32_t fcollseq; - uint32_t lcollseq; - UCHAR cend = *p++; + /* We have to find the collation sequence + value for C. Collation sequence is nothing + we can regularly access. The sequence + value is defined by the order in which the + definitions of the collation values for the + various characters appear in the source + file. A strange concept, nowhere + documented. */ + uint32_t fcollseq; + uint32_t lcollseq; + UCHAR cend = *p++; # ifdef WIDE_CHAR_VERSION - /* Search in the `names' array for the characters. */ - fcollseq = __collseq_table_lookup (collseq, fn); - if (fcollseq == ~((uint32_t) 0)) - /* XXX We don't know anything about the character - we are supposed to match. This means we are - failing. */ - goto range_not_matched; + /* Search in the `names' array for the characters. */ + fcollseq = __collseq_table_lookup (collseq, fn); + if (fcollseq == ~((uint32_t) 0)) + /* XXX We don't know anything about the character + we are supposed to match. This means we are + failing. */ + goto range_not_matched; - if (is_seqval) - lcollseq = cold; - else - lcollseq = __collseq_table_lookup (collseq, cold); + if (is_seqval) + lcollseq = cold; + else + lcollseq = __collseq_table_lookup (collseq, cold); # else - fcollseq = collseq[fn]; - lcollseq = is_seqval ? cold : collseq[(UCHAR) cold]; + fcollseq = collseq[fn]; + lcollseq = is_seqval ? cold : collseq[(UCHAR) cold]; # endif - is_seqval = false; - if (cend == L_('[') && *p == L_('.')) - { - uint32_t nrules = - _NL_CURRENT_WORD (LC_COLLATE, - _NL_COLLATE_NRULES); - const CHAR *startp = p; - size_t c1 = 0; + is_seqval = false; + if (cend == L_('[') && *p == L_('.')) + { + uint32_t nrules = + _NL_CURRENT_WORD (LC_COLLATE, + _NL_COLLATE_NRULES); + const CHAR *startp = p; + size_t c1 = 0; - while (1) - { - c = *++p; - if (c == L_('.') && p[1] == L_(']')) - { - p += 2; - break; - } - if (c == '\0') - return FNM_NOMATCH; - ++c1; - } + while (1) + { + c = *++p; + if (c == L_('.') && p[1] == L_(']')) + { + p += 2; + break; + } + if (c == '\0') + return FNM_NOMATCH; + ++c1; + } - if (nrules == 0) - { - /* There are no names defined in the - collation data. Therefore we only - accept the trivial names consisting - of the character itself. */ - if (c1 != 1) - return FNM_NOMATCH; + if (nrules == 0) + { + /* There are no names defined in the + collation data. Therefore we only + accept the trivial names consisting + of the character itself. */ + if (c1 != 1) + return FNM_NOMATCH; - cend = startp[1]; - } - else - { - int32_t table_size; - const int32_t *symb_table; + cend = startp[1]; + } + else + { + int32_t table_size; + const int32_t *symb_table; # ifdef WIDE_CHAR_VERSION - char str[c1]; - size_t strcnt; + char str[c1]; + size_t strcnt; # else # define str (startp + 1) # endif - const unsigned char *extra; - int32_t idx; - int32_t elem; - int32_t second; - int32_t hash; + const unsigned char *extra; + int32_t idx; + int32_t elem; + int32_t second; + int32_t hash; # ifdef WIDE_CHAR_VERSION - /* We have to convert the name to a single-byte - string. This is possible since the names - consist of ASCII characters and the internal - representation is UCS4. */ - for (strcnt = 0; strcnt < c1; ++strcnt) - str[strcnt] = startp[1 + strcnt]; + /* We have to convert the name to a single-byte + string. This is possible since the names + consist of ASCII characters and the internal + representation is UCS4. */ + for (strcnt = 0; strcnt < c1; ++strcnt) + str[strcnt] = startp[1 + strcnt]; # endif - table_size = - _NL_CURRENT_WORD (LC_COLLATE, - _NL_COLLATE_SYMB_HASH_SIZEMB); - symb_table = (const int32_t *) - _NL_CURRENT (LC_COLLATE, - _NL_COLLATE_SYMB_TABLEMB); - extra = (const unsigned char *) - _NL_CURRENT (LC_COLLATE, - _NL_COLLATE_SYMB_EXTRAMB); + table_size = + _NL_CURRENT_WORD (LC_COLLATE, + _NL_COLLATE_SYMB_HASH_SIZEMB); + symb_table = (const int32_t *) + _NL_CURRENT (LC_COLLATE, + _NL_COLLATE_SYMB_TABLEMB); + extra = (const unsigned char *) + _NL_CURRENT (LC_COLLATE, + _NL_COLLATE_SYMB_EXTRAMB); - /* Locate the character in the hashing + /* Locate the character in the hashing table. */ - hash = elem_hash (str, c1); + hash = elem_hash (str, c1); - idx = 0; - elem = hash % table_size; - if (symb_table[2 * elem] != 0) - { - second = hash % (table_size - 2) + 1; + idx = 0; + elem = hash % table_size; + if (symb_table[2 * elem] != 0) + { + second = hash % (table_size - 2) + 1; - do - { - /* First compare the hashing value. */ - if (symb_table[2 * elem] == hash - && (c1 - == extra[symb_table[2 * elem + 1]]) - && memcmp (str, - &extra[symb_table[2 * elem + 1] - + 1], c1) == 0) - { - /* Yep, this is the entry. */ - idx = symb_table[2 * elem + 1]; - idx += 1 + extra[idx]; - break; - } + do + { + /* First compare the hashing value. */ + if (symb_table[2 * elem] == hash + && (c1 + == extra[symb_table[2 * elem + 1]]) + && memcmp (str, + &extra[symb_table[2 * elem + 1] + + 1], c1) == 0) + { + /* Yep, this is the entry. */ + idx = symb_table[2 * elem + 1]; + idx += 1 + extra[idx]; + break; + } - /* Next entry. */ - elem += second; - } - while (symb_table[2 * elem] != 0); - } + /* Next entry. */ + elem += second; + } + while (symb_table[2 * elem] != 0); + } - if (symb_table[2 * elem] != 0) - { - /* Compare the byte sequence but only if - this is not part of a range. */ + if (symb_table[2 * elem] != 0) + { + /* Compare the byte sequence but only if + this is not part of a range. */ # ifdef WIDE_CHAR_VERSION - int32_t *wextra; + int32_t *wextra; - idx += 1 + extra[idx]; - /* Adjust for the alignment. */ - idx = (idx + 3) & ~4; + idx += 1 + extra[idx]; + /* Adjust for the alignment. */ + idx = (idx + 3) & ~4; - wextra = (int32_t *) &extra[idx + 4]; + wextra = (int32_t *) &extra[idx + 4]; # endif - /* Get the collation sequence value. */ - is_seqval = true; + /* Get the collation sequence value. */ + is_seqval = true; # ifdef WIDE_CHAR_VERSION - cend = wextra[1 + wextra[idx]]; + cend = wextra[1 + wextra[idx]]; # else - /* Adjust for the alignment. */ - idx += 1 + extra[idx]; - idx = (idx + 3) & ~4; - cend = *((int32_t *) &extra[idx]); + /* Adjust for the alignment. */ + idx += 1 + extra[idx]; + idx = (idx + 3) & ~4; + cend = *((int32_t *) &extra[idx]); # endif - } - else if (symb_table[2 * elem] != 0 && c1 == 1) - { - cend = str[0]; - c = *p++; - } - else - return FNM_NOMATCH; - } + } + else if (symb_table[2 * elem] != 0 && c1 == 1) + { + cend = str[0]; + c = *p++; + } + else + return FNM_NOMATCH; + } # undef str - } - else - { - if (!(flags & FNM_NOESCAPE) && cend == L_('\\')) - cend = *p++; - if (cend == L_('\0')) - return FNM_NOMATCH; - cend = FOLD (cend); - } + } + else + { + if (!(flags & FNM_NOESCAPE) && cend == L_('\\')) + cend = *p++; + if (cend == L_('\0')) + return FNM_NOMATCH; + cend = FOLD (cend); + } - /* XXX It is not entirely clear to me how to handle - characters which are not mentioned in the - collation specification. */ - if ( + /* XXX It is not entirely clear to me how to handle + characters which are not mentioned in the + collation specification. */ + if ( # ifdef WIDE_CHAR_VERSION - lcollseq == 0xffffffff || + lcollseq == 0xffffffff || # endif - lcollseq <= fcollseq) - { - /* We have to look at the upper bound. */ - uint32_t hcollseq; + lcollseq <= fcollseq) + { + /* We have to look at the upper bound. */ + uint32_t hcollseq; - if (is_seqval) - hcollseq = cend; - else - { + if (is_seqval) + hcollseq = cend; + else + { # ifdef WIDE_CHAR_VERSION - hcollseq = - __collseq_table_lookup (collseq, cend); - if (hcollseq == ~((uint32_t) 0)) - { - /* Hum, no information about the upper - bound. The matching succeeds if the - lower bound is matched exactly. */ - if (lcollseq != fcollseq) - goto range_not_matched; + hcollseq = + __collseq_table_lookup (collseq, cend); + if (hcollseq == ~((uint32_t) 0)) + { + /* Hum, no information about the upper + bound. The matching succeeds if the + lower bound is matched exactly. */ + if (lcollseq != fcollseq) + goto range_not_matched; - goto matched; - } + goto matched; + } # else - hcollseq = collseq[cend]; + hcollseq = collseq[cend]; # endif - } + } - if (lcollseq <= hcollseq && fcollseq <= hcollseq) - goto matched; - } + if (lcollseq <= hcollseq && fcollseq <= hcollseq) + goto matched; + } # ifdef WIDE_CHAR_VERSION - range_not_matched: + range_not_matched: # endif #else - /* We use a boring value comparison of the character - values. This is better than comparing using - `strcoll' since the latter would have surprising - and sometimes fatal consequences. */ - UCHAR cend = *p++; + /* We use a boring value comparison of the character + values. This is better than comparing using + `strcoll' since the latter would have surprising + and sometimes fatal consequences. */ + UCHAR cend = *p++; - if (!(flags & FNM_NOESCAPE) && cend == L_('\\')) - cend = *p++; - if (cend == L_('\0')) - return FNM_NOMATCH; + if (!(flags & FNM_NOESCAPE) && cend == L_('\\')) + cend = *p++; + if (cend == L_('\0')) + return FNM_NOMATCH; - /* It is a range. */ - if (cold <= fn && fn <= cend) - goto matched; + /* It is a range. */ + if (cold <= fn && fn <= cend) + goto matched; #endif - c = *p++; - } - } + c = *p++; + } + } - if (c == L_(']')) - break; - } + if (c == L_(']')) + break; + } - if (!not) - return FNM_NOMATCH; - break; + if (!not) + return FNM_NOMATCH; + break; - matched: - /* Skip the rest of the [...] that already matched. */ - do - { - ignore_next: - c = *p++; + matched: + /* Skip the rest of the [...] that already matched. */ + do + { + ignore_next: + c = *p++; - if (c == L_('\0')) - /* [... (unterminated) loses. */ - return FNM_NOMATCH; + if (c == L_('\0')) + /* [... (unterminated) loses. */ + return FNM_NOMATCH; - if (!(flags & FNM_NOESCAPE) && c == L_('\\')) - { - if (*p == L_('\0')) - return FNM_NOMATCH; - /* XXX 1003.2d11 is unclear if this is right. */ - ++p; - } - else if (c == L_('[') && *p == L_(':')) - { - int c1 = 0; - const CHAR *startp = p; + if (!(flags & FNM_NOESCAPE) && c == L_('\\')) + { + if (*p == L_('\0')) + return FNM_NOMATCH; + /* XXX 1003.2d11 is unclear if this is right. */ + ++p; + } + else if (c == L_('[') && *p == L_(':')) + { + int c1 = 0; + const CHAR *startp = p; - while (1) - { - c = *++p; - if (++c1 == CHAR_CLASS_MAX_LENGTH) - return FNM_NOMATCH; + while (1) + { + c = *++p; + if (++c1 == CHAR_CLASS_MAX_LENGTH) + return FNM_NOMATCH; - if (*p == L_(':') && p[1] == L_(']')) - break; + if (*p == L_(':') && p[1] == L_(']')) + break; - if (c < L_('a') || c >= L_('z')) - { - p = startp; - goto ignore_next; - } - } - p += 2; - c = *p++; - } - else if (c == L_('[') && *p == L_('=')) - { - c = *++p; - if (c == L_('\0')) - return FNM_NOMATCH; - c = *++p; - if (c != L_('=') || p[1] != L_(']')) - return FNM_NOMATCH; - p += 2; - c = *p++; - } - else if (c == L_('[') && *p == L_('.')) - { - ++p; - while (1) - { - c = *++p; - if (c == '\0') - return FNM_NOMATCH; + if (c < L_('a') || c >= L_('z')) + { + p = startp; + goto ignore_next; + } + } + p += 2; + c = *p++; + } + else if (c == L_('[') && *p == L_('=')) + { + c = *++p; + if (c == L_('\0')) + return FNM_NOMATCH; + c = *++p; + if (c != L_('=') || p[1] != L_(']')) + return FNM_NOMATCH; + p += 2; + c = *p++; + } + else if (c == L_('[') && *p == L_('.')) + { + ++p; + while (1) + { + c = *++p; + if (c == '\0') + return FNM_NOMATCH; - if (*p == L_('.') && p[1] == L_(']')) - break; - } - p += 2; - c = *p++; - } - } - while (c != L_(']')); - if (not) - return FNM_NOMATCH; - } - break; + if (*p == L_('.') && p[1] == L_(']')) + break; + } + p += 2; + c = *p++; + } + } + while (c != L_(']')); + if (not) + return FNM_NOMATCH; + } + break; - case L_('+'): - case L_('@'): - case L_('!'): - if (__builtin_expect (flags & FNM_EXTMATCH, 0) && *p == '(') - { - int res; + case L_('+'): + case L_('@'): + case L_('!'): + if (__builtin_expect (flags & FNM_EXTMATCH, 0) && *p == '(') + { + int res; - res = EXT (c, p, n, string_end, no_leading_period, flags); - if (res != -1) - return res; - } - goto normal_match; + res = EXT (c, p, n, string_end, no_leading_period, flags); + if (res != -1) + return res; + } + goto normal_match; - case L_('/'): - if (NO_LEADING_PERIOD (flags)) - { - if (n == string_end || c != (UCHAR) *n) - return FNM_NOMATCH; + case L_('/'): + if (NO_LEADING_PERIOD (flags)) + { + if (n == string_end || c != (UCHAR) *n) + return FNM_NOMATCH; - new_no_leading_period = true; - break; - } - /* FALLTHROUGH */ - default: - normal_match: - if (n == string_end || c != FOLD ((UCHAR) *n)) - return FNM_NOMATCH; - } + new_no_leading_period = true; + break; + } + /* FALLTHROUGH */ + default: + normal_match: + if (n == string_end || c != FOLD ((UCHAR) *n)) + return FNM_NOMATCH; + } no_leading_period = new_no_leading_period; ++n; @@ -984,25 +989,25 @@ END (const CHAR *pattern) return pattern; else if (*p == L_('[')) { - /* Handle brackets special. */ - if (posixly_correct == 0) - posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1; + /* Handle brackets special. */ + if (posixly_correct == 0) + posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1; - /* Skip the not sign. We have to recognize it because of a possibly - following ']'. */ - if (*++p == L_('!') || (posixly_correct < 0 && *p == L_('^'))) - ++p; - /* A leading ']' is recognized as such. */ - if (*p == L_(']')) - ++p; - /* Skip over all characters of the list. */ - while (*p != L_(']')) - if (*p++ == L_('\0')) - /* This is no valid pattern. */ - return pattern; + /* Skip the not sign. We have to recognize it because of a possibly + following ']'. */ + if (*++p == L_('!') || (posixly_correct < 0 && *p == L_('^'))) + ++p; + /* A leading ']' is recognized as such. */ + if (*p == L_(']')) + ++p; + /* Skip over all characters of the list. */ + while (*p != L_(']')) + if (*p++ == L_('\0')) + /* This is no valid pattern. */ + return pattern; } else if ((*p == L_('?') || *p == L_('*') || *p == L_('+') || *p == L_('@') - || *p == L_('!')) && p[1] == L_('(')) + || *p == L_('!')) && p[1] == L_('(')) p = END (p + 1); else if (*p == L_(')')) break; @@ -1037,64 +1042,63 @@ EXT (INT opt, const CHAR *pattern, const CHAR *string, const CHAR *string_end, return -1; else if (*p == L_('[')) { - /* Handle brackets special. */ - if (posixly_correct == 0) - posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1; + /* Handle brackets special. */ + if (posixly_correct == 0) + posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1; - /* Skip the not sign. We have to recognize it because of a possibly - following ']'. */ - if (*++p == L_('!') || (posixly_correct < 0 && *p == L_('^'))) - ++p; - /* A leading ']' is recognized as such. */ - if (*p == L_(']')) - ++p; - /* Skip over all characters of the list. */ - while (*p != L_(']')) - if (*p++ == L_('\0')) - /* This is no valid pattern. */ - return -1; + /* Skip the not sign. We have to recognize it because of a possibly + following ']'. */ + if (*++p == L_('!') || (posixly_correct < 0 && *p == L_('^'))) + ++p; + /* A leading ']' is recognized as such. */ + if (*p == L_(']')) + ++p; + /* Skip over all characters of the list. */ + while (*p != L_(']')) + if (*p++ == L_('\0')) + /* This is no valid pattern. */ + return -1; } else if ((*p == L_('?') || *p == L_('*') || *p == L_('+') || *p == L_('@') - || *p == L_('!')) && p[1] == L_('(')) + || *p == L_('!')) && p[1] == L_('(')) /* Remember the nesting level. */ ++level; else if (*p == L_(')')) { - if (level-- == 0) - { - /* This means we found the end of the pattern. */ + if (level-- == 0) + { + /* This means we found the end of the pattern. */ #define NEW_PATTERN \ - struct patternlist *newp; \ - size_t plen; \ - size_t plensize; \ - size_t newpsize; \ - \ - assert (p > startp); \ - plen = (opt == L_('?') || opt == L_('@') \ - ? pattern_len \ - : (unsigned) (p - startp) + 1); \ - plensize = plen * sizeof (CHAR); \ - newpsize = offsetof (struct patternlist, str) + plensize; \ - if ((size_t) -1 / sizeof (CHAR) < plen \ - || newpsize < offsetof (struct patternlist, str) \ - || ALLOCA_LIMIT <= newpsize) \ - return -1; \ - newp = (struct patternlist *) alloca (newpsize); \ - *((CHAR *) MEMPCPY (newp->str, startp, p - startp)) = L_('\0'); \ - newp->next = NULL; \ - *lastp = newp; \ - lastp = &newp->next - NEW_PATTERN; - break; - } + struct patternlist *newp; \ + size_t plen; \ + size_t plensize; \ + size_t newpsize; \ + \ + plen = (opt == L_('?') || opt == L_('@') \ + ? pattern_len \ + : p - startp + 1UL); \ + plensize = plen * sizeof (CHAR); \ + newpsize = offsetof (struct patternlist, str) + plensize; \ + if ((size_t) -1 / sizeof (CHAR) < plen \ + || newpsize < offsetof (struct patternlist, str) \ + || ALLOCA_LIMIT <= newpsize) \ + return -1; \ + newp = (struct patternlist *) alloca (newpsize); \ + *((CHAR *) MEMPCPY (newp->str, startp, p - startp)) = L_('\0'); \ + newp->next = NULL; \ + *lastp = newp; \ + lastp = &newp->next + NEW_PATTERN; + break; + } } else if (*p == L_('|')) { - if (level == 0) - { - NEW_PATTERN; - startp = p + 1; - } + if (level == 0) + { + NEW_PATTERN; + startp = p + 1; + } } assert (list != NULL); assert (p[-1] == L_(')')); @@ -1104,36 +1108,36 @@ EXT (INT opt, const CHAR *pattern, const CHAR *string, const CHAR *string_end, { case L_('*'): if (FCT (p, string, string_end, no_leading_period, flags) == 0) - return 0; + return 0; /* FALLTHROUGH */ case L_('+'): do - { - for (rs = string; rs <= string_end; ++rs) - /* First match the prefix with the current pattern with the - current pattern. */ - if (FCT (list->str, string, rs, no_leading_period, - flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD) == 0 - /* This was successful. Now match the rest with the rest - of the pattern. */ - && (FCT (p, rs, string_end, - rs == string - ? no_leading_period - : rs[-1] == '/' && NO_LEADING_PERIOD (flags), - flags & FNM_FILE_NAME - ? flags : flags & ~FNM_PERIOD) == 0 - /* This didn't work. Try the whole pattern. */ - || (rs != string - && FCT (pattern - 1, rs, string_end, - rs == string - ? no_leading_period - : rs[-1] == '/' && NO_LEADING_PERIOD (flags), - flags & FNM_FILE_NAME - ? flags : flags & ~FNM_PERIOD) == 0))) - /* It worked. Signal success. */ - return 0; - } + { + for (rs = string; rs <= string_end; ++rs) + /* First match the prefix with the current pattern with the + current pattern. */ + if (FCT (list->str, string, rs, no_leading_period, + flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD) == 0 + /* This was successful. Now match the rest with the rest + of the pattern. */ + && (FCT (p, rs, string_end, + rs == string + ? no_leading_period + : rs[-1] == '/' && NO_LEADING_PERIOD (flags), + flags & FNM_FILE_NAME + ? flags : flags & ~FNM_PERIOD) == 0 + /* This didn't work. Try the whole pattern. */ + || (rs != string + && FCT (pattern - 1, rs, string_end, + rs == string + ? no_leading_period + : rs[-1] == '/' && NO_LEADING_PERIOD (flags), + flags & FNM_FILE_NAME + ? flags : flags & ~FNM_PERIOD) == 0))) + /* It worked. Signal success. */ + return 0; + } while ((list = list->next) != NULL); /* None of the patterns lead to a match. */ @@ -1141,20 +1145,20 @@ EXT (INT opt, const CHAR *pattern, const CHAR *string, const CHAR *string_end, case L_('?'): if (FCT (p, string, string_end, no_leading_period, flags) == 0) - return 0; + return 0; /* FALLTHROUGH */ case L_('@'): do - /* I cannot believe it but `strcat' is actually acceptable - here. Match the entire string with the prefix from the - pattern list and the rest of the pattern following the - pattern list. */ - if (FCT (STRCAT (list->str, p), string, string_end, - no_leading_period, - flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD) == 0) - /* It worked. Signal success. */ - return 0; + /* I cannot believe it but `strcat' is actually acceptable + here. Match the entire string with the prefix from the + pattern list and the rest of the pattern following the + pattern list. */ + if (FCT (STRCAT (list->str, p), string, string_end, + no_leading_period, + flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD) == 0) + /* It worked. Signal success. */ + return 0; while ((list = list->next) != NULL); /* None of the patterns lead to a match. */ @@ -1162,28 +1166,28 @@ EXT (INT opt, const CHAR *pattern, const CHAR *string, const CHAR *string_end, case L_('!'): for (rs = string; rs <= string_end; ++rs) - { - struct patternlist *runp; + { + struct patternlist *runp; - for (runp = list; runp != NULL; runp = runp->next) - if (FCT (runp->str, string, rs, no_leading_period, - flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD) == 0) - break; + for (runp = list; runp != NULL; runp = runp->next) + if (FCT (runp->str, string, rs, no_leading_period, + flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD) == 0) + break; - /* If none of the patterns matched see whether the rest does. */ - if (runp == NULL - && (FCT (p, rs, string_end, - rs == string - ? no_leading_period - : rs[-1] == '/' && NO_LEADING_PERIOD (flags), - flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD) - == 0)) - /* This is successful. */ - return 0; - } + /* If none of the patterns matched see whether the rest does. */ + if (runp == NULL + && (FCT (p, rs, string_end, + rs == string + ? no_leading_period + : rs[-1] == '/' && NO_LEADING_PERIOD (flags), + flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD) + == 0)) + /* This is successful. */ + return 0; + } /* None of the patterns together with the rest of the pattern - lead to a match. */ + lead to a match. */ return FNM_NOMATCH; default: diff --git a/gnulib/getdelim.c b/gnulib/getdelim.c index 85818b565..c0240900c 100644 --- a/gnulib/getdelim.c +++ b/gnulib/getdelim.c @@ -1,6 +1,6 @@ /* getdelim.c --- Implementation of replacement getdelim function. - Copyright (C) 1994, 1996, 1997, 1998, 2001, 2003, 2005, 2006, 2007, - 2008, 2009 Free Software Foundation, Inc. + Copyright (C) 1994, 1996, 1997, 1998, 2001, 2003, 2005, 2006, 2007, 2008, + 2009, 2010 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -21,13 +21,16 @@ #include +/* Don't use __attribute__ __nonnull__ in this compilation unit. Otherwise gcc + optimizes away the lineptr == NULL || n == NULL || fp == NULL tests below. */ +#define _GL_ARG_NONNULL(params) + #include #include #include #include #include -#include #ifndef SSIZE_MAX # define SSIZE_MAX ((ssize_t) (SIZE_MAX / 2)) @@ -35,15 +38,15 @@ #if USE_UNLOCKED_IO # include "unlocked-io.h" -# define getc_maybe_unlocked(fp) getc(fp) +# define getc_maybe_unlocked(fp) getc(fp) #elif !HAVE_FLOCKFILE || !HAVE_FUNLOCKFILE || !HAVE_DECL_GETC_UNLOCKED # undef flockfile # undef funlockfile # define flockfile(x) ((void) 0) # define funlockfile(x) ((void) 0) -# define getc_maybe_unlocked(fp) getc(fp) +# define getc_maybe_unlocked(fp) getc(fp) #else -# define getc_maybe_unlocked(fp) getc_unlocked(fp) +# define getc_maybe_unlocked(fp) getc_unlocked(fp) #endif /* Read up to (and including) a DELIMITER from FP into *LINEPTR (and @@ -72,10 +75,10 @@ getdelim (char **lineptr, size_t *n, int delimiter, FILE *fp) *n = 120; new_lineptr = (char *) realloc (*lineptr, *n); if (new_lineptr == NULL) - { - result = -1; - goto unlock_return; - } + { + result = -1; + goto unlock_return; + } *lineptr = new_lineptr; } @@ -85,44 +88,44 @@ getdelim (char **lineptr, size_t *n, int delimiter, FILE *fp) i = getc_maybe_unlocked (fp); if (i == EOF) - { - result = -1; - break; - } + { + result = -1; + break; + } /* Make enough space for len+1 (for final NUL) bytes. */ if (cur_len + 1 >= *n) - { - size_t needed_max = - SSIZE_MAX < SIZE_MAX ? (size_t) SSIZE_MAX + 1 : SIZE_MAX; - size_t needed = 2 * *n + 1; /* Be generous. */ - char *new_lineptr; + { + size_t needed_max = + SSIZE_MAX < SIZE_MAX ? (size_t) SSIZE_MAX + 1 : SIZE_MAX; + size_t needed = 2 * *n + 1; /* Be generous. */ + char *new_lineptr; - if (needed_max < needed) - needed = needed_max; - if (cur_len + 1 >= needed) - { - result = -1; - errno = EOVERFLOW; - goto unlock_return; - } + if (needed_max < needed) + needed = needed_max; + if (cur_len + 1 >= needed) + { + result = -1; + errno = EOVERFLOW; + goto unlock_return; + } - new_lineptr = (char *) realloc (*lineptr, needed); - if (new_lineptr == NULL) - { - result = -1; - goto unlock_return; - } + new_lineptr = (char *) realloc (*lineptr, needed); + if (new_lineptr == NULL) + { + result = -1; + goto unlock_return; + } - *lineptr = new_lineptr; - *n = needed; - } + *lineptr = new_lineptr; + *n = needed; + } (*lineptr)[cur_len] = i; cur_len++; if (i == delimiter) - break; + break; } (*lineptr)[cur_len] = '\0'; result = cur_len ? cur_len : result; diff --git a/gnulib/getline.c b/gnulib/getline.c index eb8f055a8..6cf187be2 100644 --- a/gnulib/getline.c +++ b/gnulib/getline.c @@ -1,5 +1,5 @@ /* getline.c --- Implementation of replacement getline function. - Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc. + Copyright (C) 2005, 2006, 2007, 2009, 2010 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/gnulib/getopt.c b/gnulib/getopt.c index f1e6d1f7c..aaabc8d19 100644 --- a/gnulib/getopt.c +++ b/gnulib/getopt.c @@ -1,9 +1,9 @@ /* Getopt for GNU. - NOTE: getopt is now part of the C library, so if you don't know what + NOTE: getopt is part of the C library, so if you don't know what "Keep this file name-space clean" means, talk to drepper@gnu.org before changing it! - Copyright (C) 1987,88,89,90,91,92,93,94,95,96,98,99,2000,2001,2002,2003,2004,2006,2008 - Free Software Foundation, Inc. + Copyright (C) 1987-1996, 1998-2004, 2006, 2008-2010 Free Software + Foundation, Inc. This file is part of the GNU C Library. This program is free software: you can redistribute it and/or modify @@ -41,12 +41,9 @@ # include #endif -#ifndef attribute_hidden -# define attribute_hidden -#endif - -/* Unlike standard Unix `getopt', functions like `getopt_long' - let the user intersperse the options with the other arguments. +/* This version of `getopt' appears to the caller like standard Unix `getopt' + but it behaves differently for the user, since it allows the user + to intersperse the options with the other arguments. As `getopt_long' works, it permutes the elements of ARGV so that, when it is done, all the options precede everything else. Thus @@ -54,7 +51,7 @@ Using `getopt' or setting the environment variable POSIXLY_CORRECT disables permutation. - Then the application's behavior is completely standard. + Then the behavior is completely standard. GNU application programs can use a third alternative mode in which they can distinguish the relative order of options and other arguments. */ @@ -121,18 +118,18 @@ extern char *__getopt_nonoption_flags; # ifdef USE_NONOPTION_FLAGS # define SWAP_FLAGS(ch1, ch2) \ - if (d->__nonoption_flags_len > 0) \ - { \ - char __tmp = __getopt_nonoption_flags[ch1]; \ - __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \ - __getopt_nonoption_flags[ch2] = __tmp; \ + if (d->__nonoption_flags_len > 0) \ + { \ + char __tmp = __getopt_nonoption_flags[ch1]; \ + __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \ + __getopt_nonoption_flags[ch2] = __tmp; \ } # else # define SWAP_FLAGS(ch1, ch2) # endif -#else /* !_LIBC */ +#else /* !_LIBC */ # define SWAP_FLAGS(ch1, ch2) -#endif /* _LIBC */ +#endif /* _LIBC */ /* Exchange two adjacent subsequences of ARGV. One subsequence is elements [first_nonopt,last_nonopt) @@ -163,57 +160,57 @@ exchange (char **argv, struct _getopt_data *d) if (d->__nonoption_flags_len > 0 && top >= d->__nonoption_flags_max_len) { /* We must extend the array. The user plays games with us and - presents new arguments. */ + presents new arguments. */ char *new_str = malloc (top + 1); if (new_str == NULL) - d->__nonoption_flags_len = d->__nonoption_flags_max_len = 0; + d->__nonoption_flags_len = d->__nonoption_flags_max_len = 0; else - { - memset (__mempcpy (new_str, __getopt_nonoption_flags, - d->__nonoption_flags_max_len), - '\0', top + 1 - d->__nonoption_flags_max_len); - d->__nonoption_flags_max_len = top + 1; - __getopt_nonoption_flags = new_str; - } + { + memset (__mempcpy (new_str, __getopt_nonoption_flags, + d->__nonoption_flags_max_len), + '\0', top + 1 - d->__nonoption_flags_max_len); + d->__nonoption_flags_max_len = top + 1; + __getopt_nonoption_flags = new_str; + } } #endif while (top > middle && middle > bottom) { if (top - middle > middle - bottom) - { - /* Bottom segment is the short one. */ - int len = middle - bottom; - register int i; + { + /* Bottom segment is the short one. */ + int len = middle - bottom; + register int i; - /* Swap it with the top part of the top segment. */ - for (i = 0; i < len; i++) - { - tem = argv[bottom + i]; - argv[bottom + i] = argv[top - (middle - bottom) + i]; - argv[top - (middle - bottom) + i] = tem; - SWAP_FLAGS (bottom + i, top - (middle - bottom) + i); - } - /* Exclude the moved bottom segment from further swapping. */ - top -= len; - } + /* Swap it with the top part of the top segment. */ + for (i = 0; i < len; i++) + { + tem = argv[bottom + i]; + argv[bottom + i] = argv[top - (middle - bottom) + i]; + argv[top - (middle - bottom) + i] = tem; + SWAP_FLAGS (bottom + i, top - (middle - bottom) + i); + } + /* Exclude the moved bottom segment from further swapping. */ + top -= len; + } else - { - /* Top segment is the short one. */ - int len = top - middle; - register int i; + { + /* Top segment is the short one. */ + int len = top - middle; + register int i; - /* Swap it with the bottom part of the bottom segment. */ - for (i = 0; i < len; i++) - { - tem = argv[bottom + i]; - argv[bottom + i] = argv[middle + i]; - argv[middle + i] = tem; - SWAP_FLAGS (bottom + i, middle + i); - } - /* Exclude the moved top segment from further swapping. */ - bottom += len; - } + /* Swap it with the bottom part of the bottom segment. */ + for (i = 0; i < len; i++) + { + tem = argv[bottom + i]; + argv[bottom + i] = argv[middle + i]; + argv[middle + i] = tem; + SWAP_FLAGS (bottom + i, middle + i); + } + /* Exclude the moved top segment from further swapping. */ + bottom += len; + } } /* Update records for the slots the non-options now occupy. */ @@ -225,8 +222,9 @@ exchange (char **argv, struct _getopt_data *d) /* Initialize the internal data when the first call is made. */ static const char * -_getopt_initialize (int argc, char **argv, const char *optstring, - int posixly_correct, struct _getopt_data *d) +_getopt_initialize (int argc _GL_UNUSED, + char **argv _GL_UNUSED, const char *optstring, + struct _getopt_data *d, int posixly_correct) { /* Start processing options with ARGV-element 1 (since ARGV-element 0 is the program name); the sequence of previously skipped @@ -260,25 +258,25 @@ _getopt_initialize (int argc, char **argv, const char *optstring, && argc == __libc_argc && argv == __libc_argv) { if (d->__nonoption_flags_max_len == 0) - { - if (__getopt_nonoption_flags == NULL - || __getopt_nonoption_flags[0] == '\0') - d->__nonoption_flags_max_len = -1; - else - { - const char *orig_str = __getopt_nonoption_flags; - int len = d->__nonoption_flags_max_len = strlen (orig_str); - if (d->__nonoption_flags_max_len < argc) - d->__nonoption_flags_max_len = argc; - __getopt_nonoption_flags = - (char *) malloc (d->__nonoption_flags_max_len); - if (__getopt_nonoption_flags == NULL) - d->__nonoption_flags_max_len = -1; - else - memset (__mempcpy (__getopt_nonoption_flags, orig_str, len), - '\0', d->__nonoption_flags_max_len - len); - } - } + { + if (__getopt_nonoption_flags == NULL + || __getopt_nonoption_flags[0] == '\0') + d->__nonoption_flags_max_len = -1; + else + { + const char *orig_str = __getopt_nonoption_flags; + int len = d->__nonoption_flags_max_len = strlen (orig_str); + if (d->__nonoption_flags_max_len < argc) + d->__nonoption_flags_max_len = argc; + __getopt_nonoption_flags = + (char *) malloc (d->__nonoption_flags_max_len); + if (__getopt_nonoption_flags == NULL) + d->__nonoption_flags_max_len = -1; + else + memset (__mempcpy (__getopt_nonoption_flags, orig_str, len), + '\0', d->__nonoption_flags_max_len - len); + } + } d->__nonoption_flags_len = d->__nonoption_flags_max_len; } else @@ -330,6 +328,10 @@ _getopt_initialize (int argc, char **argv, const char *optstring, `flag' field is nonzero, the value of the option's `val' field if the `flag' field is zero. + The elements of ARGV aren't really const, because we permute them. + But we pretend they're const in the prototype to be compatible + with other systems. + LONGOPTS is a vector of `struct option' terminated by an element containing a name which is zero. @@ -338,15 +340,12 @@ _getopt_initialize (int argc, char **argv, const char *optstring, recent call. If LONG_ONLY is nonzero, '-' as well as '--' can introduce - long-named options. - - If POSIXLY_CORRECT is nonzero, behave as if the POSIXLY_CORRECT - environment variable were set. */ + long-named options. */ int _getopt_internal_r (int argc, char **argv, const char *optstring, - const struct option *longopts, int *longind, - int long_only, int posixly_correct, struct _getopt_data *d) + const struct option *longopts, int *longind, + int long_only, struct _getopt_data *d, int posixly_correct) { int print_errors = d->opterr; if (optstring[0] == ':') @@ -360,9 +359,9 @@ _getopt_internal_r (int argc, char **argv, const char *optstring, if (d->optind == 0 || !d->__initialized) { if (d->optind == 0) - d->optind = 1; /* Don't scan ARGV[0], the program name. */ - optstring = _getopt_initialize (argc, argv, optstring, - posixly_correct, d); + d->optind = 1; /* Don't scan ARGV[0], the program name. */ + optstring = _getopt_initialize (argc, argv, optstring, d, + posixly_correct); d->__initialized = 1; } @@ -372,8 +371,8 @@ _getopt_internal_r (int argc, char **argv, const char *optstring, is only used when the used in the GNU libc. */ #if defined _LIBC && defined USE_NONOPTION_FLAGS # define NONOPTION_P (argv[d->optind][0] != '-' || argv[d->optind][1] == '\0' \ - || (d->optind < d->__nonoption_flags_len \ - && __getopt_nonoption_flags[d->optind] == '1')) + || (d->optind < d->__nonoption_flags_len \ + && __getopt_nonoption_flags[d->optind] == '1')) #else # define NONOPTION_P (argv[d->optind][0] != '-' || argv[d->optind][1] == '\0') #endif @@ -383,78 +382,78 @@ _getopt_internal_r (int argc, char **argv, const char *optstring, /* Advance to the next ARGV-element. */ /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been - moved back by the user (who may also have changed the arguments). */ + moved back by the user (who may also have changed the arguments). */ if (d->__last_nonopt > d->optind) - d->__last_nonopt = d->optind; + d->__last_nonopt = d->optind; if (d->__first_nonopt > d->optind) - d->__first_nonopt = d->optind; + d->__first_nonopt = d->optind; if (d->__ordering == PERMUTE) - { - /* If we have just processed some options following some non-options, - exchange them so that the options come first. */ + { + /* If we have just processed some options following some non-options, + exchange them so that the options come first. */ - if (d->__first_nonopt != d->__last_nonopt - && d->__last_nonopt != d->optind) - exchange ((char **) argv, d); - else if (d->__last_nonopt != d->optind) - d->__first_nonopt = d->optind; + if (d->__first_nonopt != d->__last_nonopt + && d->__last_nonopt != d->optind) + exchange ((char **) argv, d); + else if (d->__last_nonopt != d->optind) + d->__first_nonopt = d->optind; - /* Skip any additional non-options - and extend the range of non-options previously skipped. */ + /* Skip any additional non-options + and extend the range of non-options previously skipped. */ - while (d->optind < argc && NONOPTION_P) - d->optind++; - d->__last_nonopt = d->optind; - } + while (d->optind < argc && NONOPTION_P) + d->optind++; + d->__last_nonopt = d->optind; + } /* The special ARGV-element `--' means premature end of options. - Skip it like a null option, - then exchange with previous non-options as if it were an option, - then skip everything else like a non-option. */ + Skip it like a null option, + then exchange with previous non-options as if it were an option, + then skip everything else like a non-option. */ if (d->optind != argc && !strcmp (argv[d->optind], "--")) - { - d->optind++; + { + d->optind++; - if (d->__first_nonopt != d->__last_nonopt - && d->__last_nonopt != d->optind) - exchange ((char **) argv, d); - else if (d->__first_nonopt == d->__last_nonopt) - d->__first_nonopt = d->optind; - d->__last_nonopt = argc; + if (d->__first_nonopt != d->__last_nonopt + && d->__last_nonopt != d->optind) + exchange ((char **) argv, d); + else if (d->__first_nonopt == d->__last_nonopt) + d->__first_nonopt = d->optind; + d->__last_nonopt = argc; - d->optind = argc; - } + d->optind = argc; + } /* If we have done all the ARGV-elements, stop the scan - and back over any non-options that we skipped and permuted. */ + and back over any non-options that we skipped and permuted. */ if (d->optind == argc) - { - /* Set the next-arg-index to point at the non-options - that we previously skipped, so the caller will digest them. */ - if (d->__first_nonopt != d->__last_nonopt) - d->optind = d->__first_nonopt; - return -1; - } + { + /* Set the next-arg-index to point at the non-options + that we previously skipped, so the caller will digest them. */ + if (d->__first_nonopt != d->__last_nonopt) + d->optind = d->__first_nonopt; + return -1; + } /* If we have come to a non-option and did not permute it, - either stop the scan or describe it to the caller and pass it by. */ + either stop the scan or describe it to the caller and pass it by. */ if (NONOPTION_P) - { - if (d->__ordering == REQUIRE_ORDER) - return -1; - d->optarg = argv[d->optind++]; - return 1; - } + { + if (d->__ordering == REQUIRE_ORDER) + return -1; + d->optarg = argv[d->optind++]; + return 1; + } /* We have found another option-ARGV-element. - Skip the initial punctuation. */ + Skip the initial punctuation. */ d->__nextchar = (argv[d->optind] + 1 - + (longopts != NULL && argv[d->optind][1] == '-')); + + (longopts != NULL && argv[d->optind][1] == '-')); } /* Decode the current option-ARGV-element. */ @@ -474,8 +473,8 @@ _getopt_internal_r (int argc, char **argv, const char *optstring, if (longopts != NULL && (argv[d->optind][1] == '-' - || (long_only && (argv[d->optind][2] - || !strchr (optstring, argv[d->optind][1]))))) + || (long_only && (argv[d->optind][2] + || !strchr (optstring, argv[d->optind][1]))))) { char *nameend; const struct option *p; @@ -486,251 +485,251 @@ _getopt_internal_r (int argc, char **argv, const char *optstring, int option_index; for (nameend = d->__nextchar; *nameend && *nameend != '='; nameend++) - /* Do nothing. */ ; + /* Do nothing. */ ; /* Test all long options for either exact match - or abbreviated matches. */ + or abbreviated matches. */ for (p = longopts, option_index = 0; p->name; p++, option_index++) - if (!strncmp (p->name, d->__nextchar, nameend - d->__nextchar)) - { - if ((unsigned int) (nameend - d->__nextchar) - == (unsigned int) strlen (p->name)) - { - /* Exact match found. */ - pfound = p; - indfound = option_index; - exact = 1; - break; - } - else if (pfound == NULL) - { - /* First nonexact match found. */ - pfound = p; - indfound = option_index; - } - else if (long_only - || pfound->has_arg != p->has_arg - || pfound->flag != p->flag - || pfound->val != p->val) - /* Second or later nonexact match found. */ - ambig = 1; - } + if (!strncmp (p->name, d->__nextchar, nameend - d->__nextchar)) + { + if ((unsigned int) (nameend - d->__nextchar) + == (unsigned int) strlen (p->name)) + { + /* Exact match found. */ + pfound = p; + indfound = option_index; + exact = 1; + break; + } + else if (pfound == NULL) + { + /* First nonexact match found. */ + pfound = p; + indfound = option_index; + } + else if (long_only + || pfound->has_arg != p->has_arg + || pfound->flag != p->flag + || pfound->val != p->val) + /* Second or later nonexact match found. */ + ambig = 1; + } if (ambig && !exact) - { - if (print_errors) - { + { + if (print_errors) + { #if defined _LIBC && defined USE_IN_LIBIO - char *buf; + char *buf; - if (__asprintf (&buf, _("%s: option `%s' is ambiguous\n"), - argv[0], argv[d->optind]) >= 0) - { - _IO_flockfile (stderr); + if (__asprintf (&buf, _("%s: option '%s' is ambiguous\n"), + argv[0], argv[d->optind]) >= 0) + { + _IO_flockfile (stderr); - int old_flags2 = ((_IO_FILE *) stderr)->_flags2; - ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; + int old_flags2 = ((_IO_FILE *) stderr)->_flags2; + ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; - __fxprintf (NULL, "%s", buf); + __fxprintf (NULL, "%s", buf); - ((_IO_FILE *) stderr)->_flags2 = old_flags2; - _IO_funlockfile (stderr); + ((_IO_FILE *) stderr)->_flags2 = old_flags2; + _IO_funlockfile (stderr); - free (buf); - } + free (buf); + } #else - fprintf (stderr, _("%s: option `%s' is ambiguous\n"), - argv[0], argv[d->optind]); + fprintf (stderr, _("%s: option '%s' is ambiguous\n"), + argv[0], argv[d->optind]); #endif - } - d->__nextchar += strlen (d->__nextchar); - d->optind++; - d->optopt = 0; - return '?'; - } + } + d->__nextchar += strlen (d->__nextchar); + d->optind++; + d->optopt = 0; + return '?'; + } if (pfound != NULL) - { - option_index = indfound; - d->optind++; - if (*nameend) - { - /* Don't test has_arg with >, because some C compilers don't - allow it to be used on enums. */ - if (pfound->has_arg) - d->optarg = nameend + 1; - else - { - if (print_errors) - { + { + option_index = indfound; + d->optind++; + if (*nameend) + { + /* Don't test has_arg with >, because some C compilers don't + allow it to be used on enums. */ + if (pfound->has_arg) + d->optarg = nameend + 1; + else + { + if (print_errors) + { #if defined _LIBC && defined USE_IN_LIBIO - char *buf; - int n; + char *buf; + int n; #endif - if (argv[d->optind - 1][1] == '-') - { - /* --option */ + if (argv[d->optind - 1][1] == '-') + { + /* --option */ #if defined _LIBC && defined USE_IN_LIBIO - n = __asprintf (&buf, _("\ -%s: option `--%s' doesn't allow an argument\n"), - argv[0], pfound->name); + n = __asprintf (&buf, _("\ +%s: option '--%s' doesn't allow an argument\n"), + argv[0], pfound->name); #else - fprintf (stderr, _("\ -%s: option `--%s' doesn't allow an argument\n"), - argv[0], pfound->name); + fprintf (stderr, _("\ +%s: option '--%s' doesn't allow an argument\n"), + argv[0], pfound->name); #endif - } - else - { - /* +option or -option */ + } + else + { + /* +option or -option */ #if defined _LIBC && defined USE_IN_LIBIO - n = __asprintf (&buf, _("\ -%s: option `%c%s' doesn't allow an argument\n"), - argv[0], argv[d->optind - 1][0], - pfound->name); + n = __asprintf (&buf, _("\ +%s: option '%c%s' doesn't allow an argument\n"), + argv[0], argv[d->optind - 1][0], + pfound->name); #else - fprintf (stderr, _("\ -%s: option `%c%s' doesn't allow an argument\n"), - argv[0], argv[d->optind - 1][0], - pfound->name); + fprintf (stderr, _("\ +%s: option '%c%s' doesn't allow an argument\n"), + argv[0], argv[d->optind - 1][0], + pfound->name); #endif - } + } #if defined _LIBC && defined USE_IN_LIBIO - if (n >= 0) - { - _IO_flockfile (stderr); + if (n >= 0) + { + _IO_flockfile (stderr); - int old_flags2 = ((_IO_FILE *) stderr)->_flags2; - ((_IO_FILE *) stderr)->_flags2 - |= _IO_FLAGS2_NOTCANCEL; + int old_flags2 = ((_IO_FILE *) stderr)->_flags2; + ((_IO_FILE *) stderr)->_flags2 + |= _IO_FLAGS2_NOTCANCEL; - __fxprintf (NULL, "%s", buf); + __fxprintf (NULL, "%s", buf); - ((_IO_FILE *) stderr)->_flags2 = old_flags2; - _IO_funlockfile (stderr); + ((_IO_FILE *) stderr)->_flags2 = old_flags2; + _IO_funlockfile (stderr); - free (buf); - } + free (buf); + } #endif - } + } - d->__nextchar += strlen (d->__nextchar); + d->__nextchar += strlen (d->__nextchar); - d->optopt = pfound->val; - return '?'; - } - } - else if (pfound->has_arg == 1) - { - if (d->optind < argc) - d->optarg = argv[d->optind++]; - else - { - if (print_errors) - { + d->optopt = pfound->val; + return '?'; + } + } + else if (pfound->has_arg == 1) + { + if (d->optind < argc) + d->optarg = argv[d->optind++]; + else + { + if (print_errors) + { #if defined _LIBC && defined USE_IN_LIBIO - char *buf; + char *buf; - if (__asprintf (&buf, _("\ -%s: option `%s' requires an argument\n"), - argv[0], argv[d->optind - 1]) >= 0) - { - _IO_flockfile (stderr); + if (__asprintf (&buf, _("\ +%s: option '%s' requires an argument\n"), + argv[0], argv[d->optind - 1]) >= 0) + { + _IO_flockfile (stderr); - int old_flags2 = ((_IO_FILE *) stderr)->_flags2; - ((_IO_FILE *) stderr)->_flags2 - |= _IO_FLAGS2_NOTCANCEL; + int old_flags2 = ((_IO_FILE *) stderr)->_flags2; + ((_IO_FILE *) stderr)->_flags2 + |= _IO_FLAGS2_NOTCANCEL; - __fxprintf (NULL, "%s", buf); + __fxprintf (NULL, "%s", buf); - ((_IO_FILE *) stderr)->_flags2 = old_flags2; - _IO_funlockfile (stderr); + ((_IO_FILE *) stderr)->_flags2 = old_flags2; + _IO_funlockfile (stderr); - free (buf); - } + free (buf); + } #else - fprintf (stderr, - _("%s: option `%s' requires an argument\n"), - argv[0], argv[d->optind - 1]); + fprintf (stderr, + _("%s: option '%s' requires an argument\n"), + argv[0], argv[d->optind - 1]); #endif - } - d->__nextchar += strlen (d->__nextchar); - d->optopt = pfound->val; - return optstring[0] == ':' ? ':' : '?'; - } - } - d->__nextchar += strlen (d->__nextchar); - if (longind != NULL) - *longind = option_index; - if (pfound->flag) - { - *(pfound->flag) = pfound->val; - return 0; - } - return pfound->val; - } + } + d->__nextchar += strlen (d->__nextchar); + d->optopt = pfound->val; + return optstring[0] == ':' ? ':' : '?'; + } + } + d->__nextchar += strlen (d->__nextchar); + if (longind != NULL) + *longind = option_index; + if (pfound->flag) + { + *(pfound->flag) = pfound->val; + return 0; + } + return pfound->val; + } /* Can't find it as a long option. If this is not getopt_long_only, - or the option starts with '--' or is not a valid short - option, then it's an error. - Otherwise interpret it as a short option. */ + or the option starts with '--' or is not a valid short + option, then it's an error. + Otherwise interpret it as a short option. */ if (!long_only || argv[d->optind][1] == '-' - || strchr (optstring, *d->__nextchar) == NULL) - { - if (print_errors) - { + || strchr (optstring, *d->__nextchar) == NULL) + { + if (print_errors) + { #if defined _LIBC && defined USE_IN_LIBIO - char *buf; - int n; + char *buf; + int n; #endif - if (argv[d->optind][1] == '-') - { - /* --option */ + if (argv[d->optind][1] == '-') + { + /* --option */ #if defined _LIBC && defined USE_IN_LIBIO - n = __asprintf (&buf, _("%s: unrecognized option `--%s'\n"), - argv[0], d->__nextchar); + n = __asprintf (&buf, _("%s: unrecognized option '--%s'\n"), + argv[0], d->__nextchar); #else - fprintf (stderr, _("%s: unrecognized option `--%s'\n"), - argv[0], d->__nextchar); + fprintf (stderr, _("%s: unrecognized option '--%s'\n"), + argv[0], d->__nextchar); #endif - } - else - { - /* +option or -option */ + } + else + { + /* +option or -option */ #if defined _LIBC && defined USE_IN_LIBIO - n = __asprintf (&buf, _("%s: unrecognized option `%c%s'\n"), - argv[0], argv[d->optind][0], d->__nextchar); + n = __asprintf (&buf, _("%s: unrecognized option '%c%s'\n"), + argv[0], argv[d->optind][0], d->__nextchar); #else - fprintf (stderr, _("%s: unrecognized option `%c%s'\n"), - argv[0], argv[d->optind][0], d->__nextchar); + fprintf (stderr, _("%s: unrecognized option '%c%s'\n"), + argv[0], argv[d->optind][0], d->__nextchar); #endif - } + } #if defined _LIBC && defined USE_IN_LIBIO - if (n >= 0) - { - _IO_flockfile (stderr); + if (n >= 0) + { + _IO_flockfile (stderr); - int old_flags2 = ((_IO_FILE *) stderr)->_flags2; - ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; + int old_flags2 = ((_IO_FILE *) stderr)->_flags2; + ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; - __fxprintf (NULL, "%s", buf); + __fxprintf (NULL, "%s", buf); - ((_IO_FILE *) stderr)->_flags2 = old_flags2; - _IO_funlockfile (stderr); + ((_IO_FILE *) stderr)->_flags2 = old_flags2; + _IO_funlockfile (stderr); - free (buf); - } + free (buf); + } #endif - } - d->__nextchar = (char *) ""; - d->optind++; - d->optopt = 0; - return '?'; - } + } + d->__nextchar = (char *) ""; + d->optind++; + d->optopt = 0; + return '?'; + } } /* Look at and handle the next short option-character. */ @@ -745,335 +744,321 @@ _getopt_internal_r (int argc, char **argv, const char *optstring, if (temp == NULL || c == ':') { - if (print_errors) - { + if (print_errors) + { #if defined _LIBC && defined USE_IN_LIBIO - char *buf; - int n; + char *buf; + int n; #endif - if (d->__posixly_correct) - { - /* 1003.2 specifies the format of this message. */ #if defined _LIBC && defined USE_IN_LIBIO - n = __asprintf (&buf, _("%s: illegal option -- %c\n"), - argv[0], c); + n = __asprintf (&buf, _("%s: invalid option -- '%c'\n"), + argv[0], c); #else - fprintf (stderr, _("%s: illegal option -- %c\n"), argv[0], c); + fprintf (stderr, _("%s: invalid option -- '%c'\n"), argv[0], c); #endif - } - else - { -#if defined _LIBC && defined USE_IN_LIBIO - n = __asprintf (&buf, _("%s: invalid option -- %c\n"), - argv[0], c); -#else - fprintf (stderr, _("%s: invalid option -- %c\n"), argv[0], c); -#endif - } #if defined _LIBC && defined USE_IN_LIBIO - if (n >= 0) - { - _IO_flockfile (stderr); + if (n >= 0) + { + _IO_flockfile (stderr); - int old_flags2 = ((_IO_FILE *) stderr)->_flags2; - ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; + int old_flags2 = ((_IO_FILE *) stderr)->_flags2; + ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; - __fxprintf (NULL, "%s", buf); + __fxprintf (NULL, "%s", buf); - ((_IO_FILE *) stderr)->_flags2 = old_flags2; - _IO_funlockfile (stderr); + ((_IO_FILE *) stderr)->_flags2 = old_flags2; + _IO_funlockfile (stderr); - free (buf); - } + free (buf); + } #endif - } - d->optopt = c; - return '?'; + } + d->optopt = c; + return '?'; } /* Convenience. Treat POSIX -W foo same as long option --foo */ if (temp[0] == 'W' && temp[1] == ';') { - char *nameend; - const struct option *p; - const struct option *pfound = NULL; - int exact = 0; - int ambig = 0; - int indfound = 0; - int option_index; + char *nameend; + const struct option *p; + const struct option *pfound = NULL; + int exact = 0; + int ambig = 0; + int indfound = 0; + int option_index; - /* This is an option that requires an argument. */ - if (*d->__nextchar != '\0') - { - d->optarg = d->__nextchar; - /* If we end this ARGV-element by taking the rest as an arg, - we must advance to the next element now. */ - d->optind++; - } - else if (d->optind == argc) - { - if (print_errors) - { - /* 1003.2 specifies the format of this message. */ + /* This is an option that requires an argument. */ + if (*d->__nextchar != '\0') + { + d->optarg = d->__nextchar; + /* If we end this ARGV-element by taking the rest as an arg, + we must advance to the next element now. */ + d->optind++; + } + else if (d->optind == argc) + { + if (print_errors) + { #if defined _LIBC && defined USE_IN_LIBIO - char *buf; + char *buf; - if (__asprintf (&buf, - _("%s: option requires an argument -- %c\n"), - argv[0], c) >= 0) - { - _IO_flockfile (stderr); + if (__asprintf (&buf, + _("%s: option requires an argument -- '%c'\n"), + argv[0], c) >= 0) + { + _IO_flockfile (stderr); - int old_flags2 = ((_IO_FILE *) stderr)->_flags2; - ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; + int old_flags2 = ((_IO_FILE *) stderr)->_flags2; + ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; - __fxprintf (NULL, "%s", buf); + __fxprintf (NULL, "%s", buf); - ((_IO_FILE *) stderr)->_flags2 = old_flags2; - _IO_funlockfile (stderr); + ((_IO_FILE *) stderr)->_flags2 = old_flags2; + _IO_funlockfile (stderr); - free (buf); - } + free (buf); + } #else - fprintf (stderr, _("%s: option requires an argument -- %c\n"), - argv[0], c); + fprintf (stderr, + _("%s: option requires an argument -- '%c'\n"), + argv[0], c); #endif - } - d->optopt = c; - if (optstring[0] == ':') - c = ':'; - else - c = '?'; - return c; - } - else - /* We already incremented `d->optind' once; - increment it again when taking next ARGV-elt as argument. */ - d->optarg = argv[d->optind++]; + } + d->optopt = c; + if (optstring[0] == ':') + c = ':'; + else + c = '?'; + return c; + } + else + /* We already incremented `d->optind' once; + increment it again when taking next ARGV-elt as argument. */ + d->optarg = argv[d->optind++]; - /* optarg is now the argument, see if it's in the - table of longopts. */ + /* optarg is now the argument, see if it's in the + table of longopts. */ - for (d->__nextchar = nameend = d->optarg; *nameend && *nameend != '='; - nameend++) - /* Do nothing. */ ; + for (d->__nextchar = nameend = d->optarg; *nameend && *nameend != '='; + nameend++) + /* Do nothing. */ ; - /* Test all long options for either exact match - or abbreviated matches. */ - for (p = longopts, option_index = 0; p->name; p++, option_index++) - if (!strncmp (p->name, d->__nextchar, nameend - d->__nextchar)) - { - if ((unsigned int) (nameend - d->__nextchar) == strlen (p->name)) - { - /* Exact match found. */ - pfound = p; - indfound = option_index; - exact = 1; - break; - } - else if (pfound == NULL) - { - /* First nonexact match found. */ - pfound = p; - indfound = option_index; - } - else - /* Second or later nonexact match found. */ - ambig = 1; - } - if (ambig && !exact) - { - if (print_errors) - { + /* Test all long options for either exact match + or abbreviated matches. */ + for (p = longopts, option_index = 0; p->name; p++, option_index++) + if (!strncmp (p->name, d->__nextchar, nameend - d->__nextchar)) + { + if ((unsigned int) (nameend - d->__nextchar) == strlen (p->name)) + { + /* Exact match found. */ + pfound = p; + indfound = option_index; + exact = 1; + break; + } + else if (pfound == NULL) + { + /* First nonexact match found. */ + pfound = p; + indfound = option_index; + } + else + /* Second or later nonexact match found. */ + ambig = 1; + } + if (ambig && !exact) + { + if (print_errors) + { #if defined _LIBC && defined USE_IN_LIBIO - char *buf; + char *buf; - if (__asprintf (&buf, _("%s: option `-W %s' is ambiguous\n"), - argv[0], argv[d->optind]) >= 0) - { - _IO_flockfile (stderr); + if (__asprintf (&buf, _("%s: option '-W %s' is ambiguous\n"), + argv[0], argv[d->optind]) >= 0) + { + _IO_flockfile (stderr); - int old_flags2 = ((_IO_FILE *) stderr)->_flags2; - ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; + int old_flags2 = ((_IO_FILE *) stderr)->_flags2; + ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; - __fxprintf (NULL, "%s", buf); + __fxprintf (NULL, "%s", buf); - ((_IO_FILE *) stderr)->_flags2 = old_flags2; - _IO_funlockfile (stderr); + ((_IO_FILE *) stderr)->_flags2 = old_flags2; + _IO_funlockfile (stderr); - free (buf); - } + free (buf); + } #else - fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"), - argv[0], argv[d->optind]); + fprintf (stderr, _("%s: option '-W %s' is ambiguous\n"), + argv[0], argv[d->optind]); #endif - } - d->__nextchar += strlen (d->__nextchar); - d->optind++; - return '?'; - } - if (pfound != NULL) - { - option_index = indfound; - if (*nameend) - { - /* Don't test has_arg with >, because some C compilers don't - allow it to be used on enums. */ - if (pfound->has_arg) - d->optarg = nameend + 1; - else - { - if (print_errors) - { + } + d->__nextchar += strlen (d->__nextchar); + d->optind++; + return '?'; + } + if (pfound != NULL) + { + option_index = indfound; + if (*nameend) + { + /* Don't test has_arg with >, because some C compilers don't + allow it to be used on enums. */ + if (pfound->has_arg) + d->optarg = nameend + 1; + else + { + if (print_errors) + { #if defined _LIBC && defined USE_IN_LIBIO - char *buf; + char *buf; - if (__asprintf (&buf, _("\ -%s: option `-W %s' doesn't allow an argument\n"), - argv[0], pfound->name) >= 0) - { - _IO_flockfile (stderr); + if (__asprintf (&buf, _("\ +%s: option '-W %s' doesn't allow an argument\n"), + argv[0], pfound->name) >= 0) + { + _IO_flockfile (stderr); - int old_flags2 = ((_IO_FILE *) stderr)->_flags2; - ((_IO_FILE *) stderr)->_flags2 - |= _IO_FLAGS2_NOTCANCEL; + int old_flags2 = ((_IO_FILE *) stderr)->_flags2; + ((_IO_FILE *) stderr)->_flags2 + |= _IO_FLAGS2_NOTCANCEL; - __fxprintf (NULL, "%s", buf); + __fxprintf (NULL, "%s", buf); - ((_IO_FILE *) stderr)->_flags2 = old_flags2; - _IO_funlockfile (stderr); + ((_IO_FILE *) stderr)->_flags2 = old_flags2; + _IO_funlockfile (stderr); - free (buf); - } + free (buf); + } #else - fprintf (stderr, _("\ -%s: option `-W %s' doesn't allow an argument\n"), - argv[0], pfound->name); + fprintf (stderr, _("\ +%s: option '-W %s' doesn't allow an argument\n"), + argv[0], pfound->name); #endif - } + } - d->__nextchar += strlen (d->__nextchar); - return '?'; - } - } - else if (pfound->has_arg == 1) - { - if (d->optind < argc) - d->optarg = argv[d->optind++]; - else - { - if (print_errors) - { + d->__nextchar += strlen (d->__nextchar); + return '?'; + } + } + else if (pfound->has_arg == 1) + { + if (d->optind < argc) + d->optarg = argv[d->optind++]; + else + { + if (print_errors) + { #if defined _LIBC && defined USE_IN_LIBIO - char *buf; + char *buf; - if (__asprintf (&buf, _("\ -%s: option `%s' requires an argument\n"), - argv[0], argv[d->optind - 1]) >= 0) - { - _IO_flockfile (stderr); + if (__asprintf (&buf, _("\ +%s: option '%s' requires an argument\n"), + argv[0], argv[d->optind - 1]) >= 0) + { + _IO_flockfile (stderr); - int old_flags2 = ((_IO_FILE *) stderr)->_flags2; - ((_IO_FILE *) stderr)->_flags2 - |= _IO_FLAGS2_NOTCANCEL; + int old_flags2 = ((_IO_FILE *) stderr)->_flags2; + ((_IO_FILE *) stderr)->_flags2 + |= _IO_FLAGS2_NOTCANCEL; - __fxprintf (NULL, "%s", buf); + __fxprintf (NULL, "%s", buf); - ((_IO_FILE *) stderr)->_flags2 = old_flags2; - _IO_funlockfile (stderr); + ((_IO_FILE *) stderr)->_flags2 = old_flags2; + _IO_funlockfile (stderr); - free (buf); - } + free (buf); + } #else - fprintf (stderr, - _("%s: option `%s' requires an argument\n"), - argv[0], argv[d->optind - 1]); + fprintf (stderr, + _("%s: option '%s' requires an argument\n"), + argv[0], argv[d->optind - 1]); #endif - } - d->__nextchar += strlen (d->__nextchar); - return optstring[0] == ':' ? ':' : '?'; - } - } - d->__nextchar += strlen (d->__nextchar); - if (longind != NULL) - *longind = option_index; - if (pfound->flag) - { - *(pfound->flag) = pfound->val; - return 0; - } - return pfound->val; - } - d->__nextchar = NULL; - return 'W'; /* Let the application handle it. */ + } + d->__nextchar += strlen (d->__nextchar); + return optstring[0] == ':' ? ':' : '?'; + } + } + d->__nextchar += strlen (d->__nextchar); + if (longind != NULL) + *longind = option_index; + if (pfound->flag) + { + *(pfound->flag) = pfound->val; + return 0; + } + return pfound->val; + } + d->__nextchar = NULL; + return 'W'; /* Let the application handle it. */ } if (temp[1] == ':') { - if (temp[2] == ':') - { - /* This is an option that accepts an argument optionally. */ - if (*d->__nextchar != '\0') - { - d->optarg = d->__nextchar; - d->optind++; - } - else - d->optarg = NULL; - d->__nextchar = NULL; - } - else - { - /* This is an option that requires an argument. */ - if (*d->__nextchar != '\0') - { - d->optarg = d->__nextchar; - /* If we end this ARGV-element by taking the rest as an arg, - we must advance to the next element now. */ - d->optind++; - } - else if (d->optind == argc) - { - if (print_errors) - { - /* 1003.2 specifies the format of this message. */ + if (temp[2] == ':') + { + /* This is an option that accepts an argument optionally. */ + if (*d->__nextchar != '\0') + { + d->optarg = d->__nextchar; + d->optind++; + } + else + d->optarg = NULL; + d->__nextchar = NULL; + } + else + { + /* This is an option that requires an argument. */ + if (*d->__nextchar != '\0') + { + d->optarg = d->__nextchar; + /* If we end this ARGV-element by taking the rest as an arg, + we must advance to the next element now. */ + d->optind++; + } + else if (d->optind == argc) + { + if (print_errors) + { #if defined _LIBC && defined USE_IN_LIBIO - char *buf; + char *buf; - if (__asprintf (&buf, _("\ -%s: option requires an argument -- %c\n"), - argv[0], c) >= 0) - { - _IO_flockfile (stderr); + if (__asprintf (&buf, _("\ +%s: option requires an argument -- '%c'\n"), + argv[0], c) >= 0) + { + _IO_flockfile (stderr); - int old_flags2 = ((_IO_FILE *) stderr)->_flags2; - ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; + int old_flags2 = ((_IO_FILE *) stderr)->_flags2; + ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; - __fxprintf (NULL, "%s", buf); + __fxprintf (NULL, "%s", buf); - ((_IO_FILE *) stderr)->_flags2 = old_flags2; - _IO_funlockfile (stderr); + ((_IO_FILE *) stderr)->_flags2 = old_flags2; + _IO_funlockfile (stderr); - free (buf); - } + free (buf); + } #else - fprintf (stderr, - _("%s: option requires an argument -- %c\n"), - argv[0], c); + fprintf (stderr, + _("%s: option requires an argument -- '%c'\n"), + argv[0], c); #endif - } - d->optopt = c; - if (optstring[0] == ':') - c = ':'; - else - c = '?'; - } - else - /* We already incremented `optind' once; - increment it again when taking next ARGV-elt as argument. */ - d->optarg = argv[d->optind++]; - d->__nextchar = NULL; - } + } + d->optopt = c; + if (optstring[0] == ':') + c = ':'; + else + c = '?'; + } + else + /* We already incremented `optind' once; + increment it again when taking next ARGV-elt as argument. */ + d->optarg = argv[d->optind++]; + d->__nextchar = NULL; + } } return c; } @@ -1081,16 +1066,17 @@ _getopt_internal_r (int argc, char **argv, const char *optstring, int _getopt_internal (int argc, char **argv, const char *optstring, - const struct option *longopts, int *longind, - int long_only, int posixly_correct) + const struct option *longopts, int *longind, int long_only, + int posixly_correct) { int result; getopt_data.optind = optind; getopt_data.opterr = opterr; - result = _getopt_internal_r (argc, argv, optstring, longopts, longind, - long_only, posixly_correct, &getopt_data); + result = _getopt_internal_r (argc, argv, optstring, longopts, + longind, long_only, &getopt_data, + posixly_correct); optind = getopt_data.optind; optarg = getopt_data.optarg; @@ -1110,10 +1096,23 @@ enum { POSIXLY_CORRECT = 1 }; int getopt (int argc, char *const *argv, const char *optstring) { - return _getopt_internal (argc, (char **) argv, optstring, NULL, NULL, 0, - POSIXLY_CORRECT); + return _getopt_internal (argc, (char **) argv, optstring, + (const struct option *) 0, + (int *) 0, + 0, POSIXLY_CORRECT); } +#ifdef _LIBC +int +__posix_getopt (int argc, char *const *argv, const char *optstring) +{ + return _getopt_internal (argc, argv, optstring, + (const struct option *) 0, + (int *) 0, + 0, 1); +} +#endif + #ifdef TEST @@ -1132,51 +1131,51 @@ main (int argc, char **argv) c = getopt (argc, argv, "abc:d:0123456789"); if (c == -1) - break; + break; switch (c) - { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - if (digit_optind != 0 && digit_optind != this_option_optind) - printf ("digits occur in two different argv-elements.\n"); - digit_optind = this_option_optind; - printf ("option %c\n", c); - break; + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (digit_optind != 0 && digit_optind != this_option_optind) + printf ("digits occur in two different argv-elements.\n"); + digit_optind = this_option_optind; + printf ("option %c\n", c); + break; - case 'a': - printf ("option a\n"); - break; + case 'a': + printf ("option a\n"); + break; - case 'b': - printf ("option b\n"); - break; + case 'b': + printf ("option b\n"); + break; - case 'c': - printf ("option c with value `%s'\n", optarg); - break; + case 'c': + printf ("option c with value '%s'\n", optarg); + break; - case '?': - break; + case '?': + break; - default: - printf ("?? getopt returned character code 0%o ??\n", c); - } + default: + printf ("?? getopt returned character code 0%o ??\n", c); + } } if (optind < argc) { printf ("non-option ARGV-elements: "); while (optind < argc) - printf ("%s ", argv[optind++]); + printf ("%s ", argv[optind++]); printf ("\n"); } diff --git a/gnulib/getopt1.c b/gnulib/getopt1.c index d6a3ecf4e..046d69f94 100644 --- a/gnulib/getopt1.c +++ b/gnulib/getopt1.c @@ -1,6 +1,6 @@ /* getopt_long and getopt_long_only entry points for GNU getopt. - Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98,2004,2006 - Free Software Foundation, Inc. + Copyright (C) 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1996, 1997, + 1998, 2004, 2006, 2009, 2010 Free Software Foundation, Inc. This file is part of the GNU C Library. This program is free software: you can redistribute it and/or modify @@ -32,25 +32,25 @@ #include #endif -#ifndef NULL +#ifndef NULL #define NULL 0 #endif int getopt_long (int argc, char *__getopt_argv_const *argv, const char *options, - const struct option *long_options, int *opt_index) + const struct option *long_options, int *opt_index) { return _getopt_internal (argc, (char **) argv, options, long_options, - opt_index, 0, 0); + opt_index, 0, 0); } int _getopt_long_r (int argc, char **argv, const char *options, - const struct option *long_options, int *opt_index, - struct _getopt_data *d) + const struct option *long_options, int *opt_index, + struct _getopt_data *d) { return _getopt_internal_r (argc, argv, options, long_options, opt_index, - 0, 0, d); + 0, d, 0); } /* Like getopt_long, but '-' as well as '--' can indicate a long option. @@ -60,20 +60,20 @@ _getopt_long_r (int argc, char **argv, const char *options, int getopt_long_only (int argc, char *__getopt_argv_const *argv, - const char *options, - const struct option *long_options, int *opt_index) + const char *options, + const struct option *long_options, int *opt_index) { return _getopt_internal (argc, (char **) argv, options, long_options, - opt_index, 1, 0); + opt_index, 1, 0); } int _getopt_long_only_r (int argc, char **argv, const char *options, - const struct option *long_options, int *opt_index, - struct _getopt_data *d) + const struct option *long_options, int *opt_index, + struct _getopt_data *d) { return _getopt_internal_r (argc, argv, options, long_options, opt_index, - 1, 0, d); + 1, d, 0); } @@ -91,76 +91,76 @@ main (int argc, char **argv) { int this_option_optind = optind ? optind : 1; int option_index = 0; - static struct option long_options[] = + static const struct option long_options[] = { - {"add", 1, 0, 0}, - {"append", 0, 0, 0}, - {"delete", 1, 0, 0}, - {"verbose", 0, 0, 0}, - {"create", 0, 0, 0}, - {"file", 1, 0, 0}, - {0, 0, 0, 0} + {"add", 1, 0, 0}, + {"append", 0, 0, 0}, + {"delete", 1, 0, 0}, + {"verbose", 0, 0, 0}, + {"create", 0, 0, 0}, + {"file", 1, 0, 0}, + {0, 0, 0, 0} }; c = getopt_long (argc, argv, "abc:d:0123456789", - long_options, &option_index); + long_options, &option_index); if (c == -1) - break; + break; switch (c) - { - case 0: - printf ("option %s", long_options[option_index].name); - if (optarg) - printf (" with arg %s", optarg); - printf ("\n"); - break; + { + case 0: + printf ("option %s", long_options[option_index].name); + if (optarg) + printf (" with arg %s", optarg); + printf ("\n"); + break; - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - if (digit_optind != 0 && digit_optind != this_option_optind) - printf ("digits occur in two different argv-elements.\n"); - digit_optind = this_option_optind; - printf ("option %c\n", c); - break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (digit_optind != 0 && digit_optind != this_option_optind) + printf ("digits occur in two different argv-elements.\n"); + digit_optind = this_option_optind; + printf ("option %c\n", c); + break; - case 'a': - printf ("option a\n"); - break; + case 'a': + printf ("option a\n"); + break; - case 'b': - printf ("option b\n"); - break; + case 'b': + printf ("option b\n"); + break; - case 'c': - printf ("option c with value `%s'\n", optarg); - break; + case 'c': + printf ("option c with value `%s'\n", optarg); + break; - case 'd': - printf ("option d with value `%s'\n", optarg); - break; + case 'd': + printf ("option d with value `%s'\n", optarg); + break; - case '?': - break; + case '?': + break; - default: - printf ("?? getopt returned character code 0%o ??\n", c); - } + default: + printf ("?? getopt returned character code 0%o ??\n", c); + } } if (optind < argc) { printf ("non-option ARGV-elements: "); while (optind < argc) - printf ("%s ", argv[optind++]); + printf ("%s ", argv[optind++]); printf ("\n"); } diff --git a/gnulib/getopt_int.h b/gnulib/getopt_int.h index 3c6628bb9..169def5b2 100644 --- a/gnulib/getopt_int.h +++ b/gnulib/getopt_int.h @@ -1,6 +1,6 @@ /* Internal declarations for getopt. - Copyright (C) 1989-1994,1996-1999,2001,2003,2004 - Free Software Foundation, Inc. + Copyright (C) 1989-1994, 1996-1999, 2001, 2003-2004, 2009-2010 Free Software + Foundation, Inc. This file is part of the GNU C Library. This program is free software: you can redistribute it and/or modify @@ -17,12 +17,14 @@ along with this program. If not, see . */ #ifndef _GETOPT_INT_H -#define _GETOPT_INT_H 1 +#define _GETOPT_INT_H 1 + +#include extern int _getopt_internal (int ___argc, char **___argv, - const char *__shortopts, - const struct option *__longopts, int *__longind, - int __long_only, int __posixly_correct); + const char *__shortopts, + const struct option *__longopts, int *__longind, + int __long_only, int __posixly_correct); /* Reentrant versions which can handle parsing multiple argument @@ -108,23 +110,23 @@ struct _getopt_data /* The initializer is necessary to set OPTIND and OPTERR to their default values and to clear the initialization flag. */ -#define _GETOPT_DATA_INITIALIZER { 1, 1 } +#define _GETOPT_DATA_INITIALIZER { 1, 1 } extern int _getopt_internal_r (int ___argc, char **___argv, - const char *__shortopts, - const struct option *__longopts, int *__longind, - int __long_only, int __posixly_correct, - struct _getopt_data *__data); + const char *__shortopts, + const struct option *__longopts, int *__longind, + int __long_only, struct _getopt_data *__data, + int __posixly_correct); extern int _getopt_long_r (int ___argc, char **___argv, - const char *__shortopts, - const struct option *__longopts, int *__longind, - struct _getopt_data *__data); + const char *__shortopts, + const struct option *__longopts, int *__longind, + struct _getopt_data *__data); extern int _getopt_long_only_r (int ___argc, char **___argv, - const char *__shortopts, - const struct option *__longopts, - int *__longind, - struct _getopt_data *__data); + const char *__shortopts, + const struct option *__longopts, + int *__longind, + struct _getopt_data *__data); #endif /* getopt_int.h */ diff --git a/gnulib/gettext.h b/gnulib/gettext.h index 9d76ec9af..6a069c448 100644 --- a/gnulib/gettext.h +++ b/gnulib/gettext.h @@ -1,5 +1,6 @@ /* Convenience header for conditional use of GNU . - Copyright (C) 1995-1998, 2000-2002, 2004-2006 Free Software Foundation, Inc. + Copyright (C) 1995-1998, 2000-2002, 2004-2006, 2009-2010 Free Software + Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -63,21 +64,30 @@ for invalid uses of the value returned from these functions. On pre-ANSI systems without 'const', the config.h file is supposed to contain "#define const". */ +# undef gettext # define gettext(Msgid) ((const char *) (Msgid)) +# undef dgettext # define dgettext(Domainname, Msgid) ((void) (Domainname), gettext (Msgid)) +# undef dcgettext # define dcgettext(Domainname, Msgid, Category) \ ((void) (Category), dgettext (Domainname, Msgid)) +# undef ngettext # define ngettext(Msgid1, Msgid2, N) \ ((N) == 1 \ ? ((void) (Msgid2), (const char *) (Msgid1)) \ : ((void) (Msgid1), (const char *) (Msgid2))) +# undef dngettext # define dngettext(Domainname, Msgid1, Msgid2, N) \ ((void) (Domainname), ngettext (Msgid1, Msgid2, N)) +# undef dcngettext # define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \ - ((void) (Category), dngettext(Domainname, Msgid1, Msgid2, N)) + ((void) (Category), dngettext (Domainname, Msgid1, Msgid2, N)) +# undef textdomain # define textdomain(Domainname) ((const char *) (Domainname)) +# undef bindtextdomain # define bindtextdomain(Domainname, Dirname) \ ((void) (Domainname), (const char *) (Dirname)) +# undef bind_textdomain_codeset # define bind_textdomain_codeset(Domainname, Codeset) \ ((void) (Domainname), (const char *) (Codeset)) @@ -131,8 +141,8 @@ inline #endif static const char * pgettext_aux (const char *domain, - const char *msg_ctxt_id, const char *msgid, - int category) + const char *msg_ctxt_id, const char *msgid, + int category) { const char *translation = dcgettext (domain, msg_ctxt_id, category); if (translation == msg_ctxt_id) @@ -150,9 +160,9 @@ inline #endif static const char * npgettext_aux (const char *domain, - const char *msg_ctxt_id, const char *msgid, - const char *msgid_plural, unsigned long int n, - int category) + const char *msg_ctxt_id, const char *msgid, + const char *msgid_plural, unsigned long int n, + int category) { const char *translation = dcngettext (domain, msg_ctxt_id, msgid_plural, n, category); @@ -190,8 +200,8 @@ inline #endif static const char * dcpgettext_expr (const char *domain, - const char *msgctxt, const char *msgid, - int category) + const char *msgctxt, const char *msgid, + int category) { size_t msgctxt_len = strlen (msgctxt) + 1; size_t msgid_len = strlen (msgid) + 1; @@ -213,10 +223,10 @@ dcpgettext_expr (const char *domain, translation = dcgettext (domain, msg_ctxt_id, category); #if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS if (msg_ctxt_id != buf) - free (msg_ctxt_id); + free (msg_ctxt_id); #endif if (translation != msg_ctxt_id) - return translation; + return translation; } return msgid; } @@ -235,9 +245,9 @@ inline #endif static const char * dcnpgettext_expr (const char *domain, - const char *msgctxt, const char *msgid, - const char *msgid_plural, unsigned long int n, - int category) + const char *msgctxt, const char *msgid, + const char *msgid_plural, unsigned long int n, + int category) { size_t msgctxt_len = strlen (msgctxt) + 1; size_t msgid_len = strlen (msgid) + 1; @@ -259,10 +269,10 @@ dcnpgettext_expr (const char *domain, translation = dcngettext (domain, msg_ctxt_id, msgid_plural, n, category); #if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS if (msg_ctxt_id != buf) - free (msg_ctxt_id); + free (msg_ctxt_id); #endif if (!(translation == msg_ctxt_id || translation == msgid_plural)) - return translation; + return translation; } return (n == 1 ? msgid : msgid_plural); } diff --git a/gnulib/progname.c b/gnulib/progname.c index bfa374a52..1415e6a55 100644 --- a/gnulib/progname.c +++ b/gnulib/progname.c @@ -1,6 +1,6 @@ /* Program name management. - Copyright (C) 2001-2003, 2005-2009 Free Software Foundation, Inc. - Written by Bruno Haible , 2001. + Copyright (C) 2001-2003, 2005-2010 Free Software Foundation, Inc. + Written by Bruno Haible , 2001. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -23,6 +23,8 @@ #include "progname.h" #include /* get program_invocation_name declaration */ +#include +#include #include @@ -30,7 +32,9 @@ To be initialized by main(). */ const char *program_name = NULL; -/* Set program_name, based on argv[0]. */ +/* Set program_name, based on argv[0]. + argv0 must be a string allocated with indefinite extent, and must not be + modified after this call. */ void set_program_name (const char *argv0) { @@ -42,20 +46,30 @@ set_program_name (const char *argv0) const char *slash; const char *base; + /* Sanity check. POSIX requires the invoking process to pass a non-NULL + argv[0]. */ + if (argv0 == NULL) + { + /* It's a bug in the invoking program. Help diagnosing it. */ + fputs ("A NULL argv[0] was passed through an exec system call.\n", + stderr); + abort (); + } + slash = strrchr (argv0, '/'); base = (slash != NULL ? slash + 1 : argv0); if (base - argv0 >= 7 && strncmp (base - 7, "/.libs/", 7) == 0) { argv0 = base; if (strncmp (base, "lt-", 3) == 0) - { - argv0 = base + 3; - /* On glibc systems, remove the "lt-" prefix from the variable - program_invocation_short_name. */ + { + argv0 = base + 3; + /* On glibc systems, remove the "lt-" prefix from the variable + program_invocation_short_name. */ #if HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME - program_invocation_short_name = (char *) argv0; + program_invocation_short_name = (char *) argv0; #endif - } + } } /* But don't strip off a leading / in general, because when the user diff --git a/gnulib/progname.h b/gnulib/progname.h index 82615c6bc..5ba303bd0 100644 --- a/gnulib/progname.h +++ b/gnulib/progname.h @@ -1,6 +1,6 @@ /* Program name management. - Copyright (C) 2001-2004, 2006 Free Software Foundation, Inc. - Written by Bruno Haible , 2001. + Copyright (C) 2001-2004, 2006, 2009-2010 Free Software Foundation, Inc. + Written by Bruno Haible , 2001. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -31,7 +31,9 @@ extern "C" { /* String containing name the program is called with. */ extern const char *program_name; -/* Set program_name, based on argv[0]. */ +/* Set program_name, based on argv[0]. + argv0 must be a string allocated with indefinite extent, and must not be + modified after this call. */ extern void set_program_name (const char *argv0); #if ENABLE_RELOCATABLE @@ -39,8 +41,8 @@ extern void set_program_name (const char *argv0); /* Set program_name, based on argv[0], and original installation prefix and directory, for relocatability. */ extern void set_program_name_and_installdir (const char *argv0, - const char *orig_installprefix, - const char *orig_installdir); + const char *orig_installprefix, + const char *orig_installdir); #undef set_program_name #define set_program_name(ARG0) \ set_program_name_and_installdir (ARG0, INSTALLPREFIX, INSTALLDIR) From 46960ff9ec75f23666c47b745b041c221655acb5 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 27 Mar 2010 21:50:57 +0100 Subject: [PATCH 512/738] Resynced with multiboot2 spec --- include/multiboot2.h | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/include/multiboot2.h b/include/multiboot2.h index 820479425..59d7c951f 100644 --- a/include/multiboot2.h +++ b/include/multiboot2.h @@ -103,24 +103,24 @@ struct multiboot_header struct multiboot_header_tag { - multiboot_uint32_t type; + multiboot_uint16_t type; + multiboot_uint16_t flags; multiboot_uint32_t size; - multiboot_uint32_t flags; }; struct multiboot_header_tag_information_request { - multiboot_uint32_t type; + multiboot_uint16_t type; + multiboot_uint16_t flags; multiboot_uint32_t size; - multiboot_uint32_t flags; multiboot_uint32_t requests[0]; }; struct multiboot_header_tag_address { - multiboot_uint32_t type; + multiboot_uint16_t type; + multiboot_uint16_t flags; multiboot_uint32_t size; - multiboot_uint32_t flags; multiboot_uint32_t header_addr; multiboot_uint32_t load_addr; multiboot_uint32_t load_end_addr; @@ -129,25 +129,25 @@ struct multiboot_header_tag_address struct multiboot_header_tag_entry_address { - multiboot_uint32_t type; + multiboot_uint16_t type; + multiboot_uint16_t flags; multiboot_uint32_t size; - multiboot_uint32_t flags; multiboot_uint32_t entry_addr; }; struct multiboot_header_tag_console_flags { - multiboot_uint32_t type; + multiboot_uint16_t type; + multiboot_uint16_t flags; multiboot_uint32_t size; - multiboot_uint32_t flags; multiboot_uint32_t console_flags; }; struct multiboot_header_tag_framebuffer { - multiboot_uint32_t type; + multiboot_uint16_t type; + multiboot_uint16_t flags; multiboot_uint32_t size; - multiboot_uint32_t flags; multiboot_uint32_t width; multiboot_uint32_t height; multiboot_uint32_t depth; @@ -155,9 +155,9 @@ struct multiboot_header_tag_framebuffer struct multiboot_header_tag_module_align { - multiboot_uint32_t type; + multiboot_uint16_t type; + multiboot_uint16_t flags; multiboot_uint32_t size; - multiboot_uint32_t flags; multiboot_uint32_t width; multiboot_uint32_t height; multiboot_uint32_t depth; @@ -193,8 +193,6 @@ struct multiboot_tag_string { multiboot_uint32_t type; multiboot_uint32_t size; - multiboot_uint32_t entry_size; - multiboot_uint32_t entry_version; char string[0]; }; From 3a7c36977a37c21d07484ecde445a8cce801a68f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 27 Mar 2010 22:40:49 +0100 Subject: [PATCH 513/738] Fix compilation problem --- loader/i386/multiboot_mbi2.c | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/loader/i386/multiboot_mbi2.c b/loader/i386/multiboot_mbi2.c index d07ce92f3..09d09d5a9 100644 --- a/loader/i386/multiboot_mbi2.c +++ b/loader/i386/multiboot_mbi2.c @@ -678,7 +678,6 @@ grub_multiboot_add_module (grub_addr_t start, grub_size_t size, void grub_multiboot_set_bootdev (void) { - char *p; grub_device_t dev; slice = ~0; @@ -696,22 +695,13 @@ grub_multiboot_set_bootdev (void) dev = grub_device_open (0); if (dev && dev->disk && dev->disk->partition) { - char *p0; - p = p0 = dev->disk->partition->partmap->get_name (dev->disk->partition); - if (p) - { - if ((p[0] >= '0') && (p[0] <= '9')) - { - slice = grub_strtoul (p, &p, 0) - 1; - - if ((p) && (p[0] == ',')) - p++; - } - - if ((p[0] >= 'a') && (p[0] <= 'z')) - part = p[0] - 'a'; + if (dev->disk->partition->parent) + { + part = dev->disk->partition->number; + slice = dev->disk->partition->parent->number; } - grub_free (p0); + else + slice = dev->disk->partition->number; } if (dev) grub_device_close (dev); From fe9381dd00d957b49e6c92fbb17b6ad4e18f1a21 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 27 Mar 2010 22:42:02 +0100 Subject: [PATCH 514/738] Resync changelog --- ChangeLog.tag | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/ChangeLog.tag b/ChangeLog.tag index dbeea1017..73983b463 100644 --- a/ChangeLog.tag +++ b/ChangeLog.tag @@ -4,13 +4,20 @@ * conf/i386.rmk (multiboot2_mod_SOURCES): Replace loader/i386/multiboot_mbi.c with loader/i386/multiboot_mbi2.c. + Remove loader/multiboot_loader.c. * include/grub/i386/multiboot.h (grub_multiboot_real_boot): Removed. (grub_multiboot2_real_boot): Likewise. * include/grub/multiboot.h (grub_multiboot_set_accepts_video): Removed. - (grub_get_multiboot_mmap_len): New proto. + (grub_get_multiboot_mmap_count): New proto. (grub_fill_multiboot_mmap): Likewise. (grub_multiboot_set_video_mode): Likewise. (grub_multiboot_fill_vbe_info_real): Likewise. + (grub_multiboot_set_console): Likewise. + (grub_multiboot_load): Likewise. + (grub_multiboot_load_elf): Likewise. + (GRUB_MULTIBOOT_CONSOLE_EGA_TEXT): New definition. + (GRUB_MULTIBOOT_CONSOLE_FRAMEBUFFER): Likewise. + * include/multiboot.h: Resynced with specification. * include/multiboot2.h: Resynced with specification. * loader/i386/multiboot_mbi.c (DEFAULT_VIDEO_MODE): Moved from here... * loader/i386/multiboot.c (DEFAULT_VIDEO_MODE): ... here. From f5d5c327e3884dd99171fc7b5c17669f356f9b28 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 28 Mar 2010 13:46:42 +0200 Subject: [PATCH 515/738] Remove VBE multiboot support --- ChangeLog.mbivid | 9 ---- ChangeLog.tag | 8 ---- include/grub/multiboot.h | 9 ---- loader/i386/multiboot.c | 49 +-------------------- loader/i386/multiboot_mbi.c | 10 ----- loader/i386/multiboot_mbi2.c | 82 +++++++++++++++--------------------- 6 files changed, 34 insertions(+), 133 deletions(-) delete mode 100644 ChangeLog.mbivid diff --git a/ChangeLog.mbivid b/ChangeLog.mbivid deleted file mode 100644 index 25db22c19..000000000 --- a/ChangeLog.mbivid +++ /dev/null @@ -1,9 +0,0 @@ -2010-01-14 Vladimir Serbinenko - - VBE multiboot support. - - * loader/i386/multiboot_mbi.c (HAS_VBE): New constant. - (grub_multiboot_get_mbi_size) [HAS_VBE]: Account for VBE structures. - (grub_multiboot_make_mbi) [HAS_VBE]: Likewise. - (fill_vbe_info) [HAS_VBE]: New function. - (retrieve_video_parameters) [HAS_VBE]: Call fill_vbe_info. diff --git a/ChangeLog.tag b/ChangeLog.tag index 73983b463..90faf3dd6 100644 --- a/ChangeLog.tag +++ b/ChangeLog.tag @@ -11,7 +11,6 @@ (grub_get_multiboot_mmap_count): New proto. (grub_fill_multiboot_mmap): Likewise. (grub_multiboot_set_video_mode): Likewise. - (grub_multiboot_fill_vbe_info_real): Likewise. (grub_multiboot_set_console): Likewise. (grub_multiboot_load): Likewise. (grub_multiboot_load_elf): Likewise. @@ -24,9 +23,6 @@ * loader/i386/multiboot_mbi.c (HAS_VGA_TEXT): Moved from here .. * include/grub/multiboot.h (GRUB_MACHINE_HAS_VGA_TEXT): ... here. All users updated. - * loader/i386/multiboot_mbi.c (HAS_VBE): Moved from here .. - * include/grub/multiboot.h (GRUB_MACHINE_HAS_VBE): ... here. All - users updated. * loader/i386/multiboot_mbi.c (accepts_video): Moved from here... * loader/i386/multiboot.c (accepts_video): ... here. All users updated. * loader/i386/multiboot_mbi.c (grub_multiboot_set_accepts_video): @@ -40,8 +36,4 @@ * loader/i386/multiboot_mbi.c (set_video_mode): Moved from here... * loader/i386/multiboot.c (grub_multiboot_set_video_mode): ... here. All users updated. - * loader/i386/multiboot_mbi.c (fill_vbe_info): Moved generic parts - from here... - * loader/i386/multiboot.c (grub_multiboot_fill_vbe_info_real): ... here. - All users updated. * loader/i386/multiboot_mbi2.c: New file. diff --git a/include/grub/multiboot.h b/include/grub/multiboot.h index 70241ec3c..49d71fa09 100644 --- a/include/grub/multiboot.h +++ b/include/grub/multiboot.h @@ -51,17 +51,8 @@ grub_err_t grub_multiboot_set_video_mode (void); #if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_QEMU) #include -grub_err_t -grub_multiboot_fill_vbe_info_real (struct grub_vbe_info_block *vbe_control_info, - struct grub_vbe_mode_info_block *vbe_mode_info, - multiboot_uint16_t *vbe_mode, - multiboot_uint16_t *vbe_interface_seg, - multiboot_uint16_t *vbe_interface_off, - multiboot_uint16_t *vbe_interface_len); -#define GRUB_MACHINE_HAS_VBE 1 #define GRUB_MACHINE_HAS_VGA_TEXT 1 #else -#define GRUB_MACHINE_HAS_VBE 0 #define GRUB_MACHINE_HAS_VGA_TEXT 0 #endif diff --git a/loader/i386/multiboot.c b/loader/i386/multiboot.c index a89233431..99d1cf906 100644 --- a/loader/i386/multiboot.c +++ b/loader/i386/multiboot.c @@ -20,6 +20,7 @@ /* * FIXME: The following features from the Multiboot specification still * need to be implemented: + * - VBE support * - symbol table * - drives table * - ROM configuration table @@ -115,54 +116,6 @@ grub_multiboot_set_video_mode (void) return err; } -#if GRUB_MACHINE_HAS_VBE -grub_err_t -grub_multiboot_fill_vbe_info_real (struct grub_vbe_info_block *vbe_control_info, - struct grub_vbe_mode_info_block *vbe_mode_info, - multiboot_uint16_t *vbe_mode, - multiboot_uint16_t *vbe_interface_seg, - multiboot_uint16_t *vbe_interface_off, - multiboot_uint16_t *vbe_interface_len) -{ - grub_vbe_status_t status; - void *scratch = (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR; - - status = grub_vbe_bios_get_controller_info (scratch); - if (status != GRUB_VBE_STATUS_OK) - return grub_error (GRUB_ERR_IO, "Can't get controller info."); - grub_memcpy (vbe_control_info, scratch, sizeof (struct grub_vbe_info_block)); - - status = grub_vbe_bios_get_mode (scratch); - *vbe_mode = *(grub_uint32_t *) scratch; - if (status != GRUB_VBE_STATUS_OK) - return grub_error (GRUB_ERR_IO, "can't get VBE mode"); - - /* get_mode_info isn't available for mode 3. */ - if (*vbe_mode == 3) - { - grub_memset (vbe_mode_info, 0, sizeof (struct grub_vbe_mode_info_block)); - vbe_mode_info->memory_model = GRUB_VBE_MEMORY_MODEL_TEXT; - vbe_mode_info->x_resolution = 80; - vbe_mode_info->y_resolution = 25; - } - else - { - status = grub_vbe_bios_get_mode_info (*vbe_mode, scratch); - if (status != GRUB_VBE_STATUS_OK) - return grub_error (GRUB_ERR_IO, "can't get mode info"); - grub_memcpy (vbe_mode_info, scratch, - sizeof (struct grub_vbe_mode_info_block)); - } - - /* FIXME: retrieve those. */ - *vbe_interface_seg = 0; - *vbe_interface_off = 0; - *vbe_interface_len = 0; - - return GRUB_ERR_NONE; -} -#endif - static grub_err_t grub_multiboot_boot (void) { diff --git a/loader/i386/multiboot_mbi.c b/loader/i386/multiboot_mbi.c index 0deca8930..2a7c70f96 100644 --- a/loader/i386/multiboot_mbi.c +++ b/loader/i386/multiboot_mbi.c @@ -186,10 +186,6 @@ grub_multiboot_get_mbi_size (void) + modcnt * sizeof (struct multiboot_mod_list) + total_modcmd + ALIGN_UP (sizeof(PACKAGE_STRING), 4) + grub_get_multiboot_mmap_count () * sizeof (struct multiboot_mmap_entry) -#if GRUB_MACHINE_HAS_VBE - + sizeof (struct grub_vbe_info_block) - + sizeof (struct grub_vbe_mode_info_block) -#endif + 256 * sizeof (struct multiboot_color); } @@ -391,12 +387,6 @@ grub_multiboot_make_mbi (void *orig, grub_uint32_t dest, grub_off_t buf_off, grub_print_error (); grub_errno = GRUB_ERR_NONE; } -#if GRUB_MACHINE_HAS_VBE - ptrorig += sizeof (struct grub_vbe_info_block); - ptrdest += sizeof (struct grub_vbe_info_block); - ptrorig += sizeof (struct grub_vbe_mode_info_block); - ptrdest += sizeof (struct grub_vbe_mode_info_block); -#endif return GRUB_ERR_NONE; } diff --git a/loader/i386/multiboot_mbi2.c b/loader/i386/multiboot_mbi2.c index 09d09d5a9..436cd0901 100644 --- a/loader/i386/multiboot_mbi2.c +++ b/loader/i386/multiboot_mbi2.c @@ -127,10 +127,10 @@ grub_multiboot_load (grub_file_t file) case MULTIBOOT_TAG_TYPE_BASIC_MEMINFO: case MULTIBOOT_TAG_TYPE_BOOTDEV: case MULTIBOOT_TAG_TYPE_MMAP: - case MULTIBOOT_TAG_TYPE_VBE: case MULTIBOOT_TAG_TYPE_FRAMEBUFFER: break; + case MULTIBOOT_TAG_TYPE_VBE: case MULTIBOOT_TAG_TYPE_ELF_SECTIONS: case MULTIBOOT_TAG_TYPE_APM: default: @@ -271,37 +271,6 @@ grub_multiboot_get_mbi_size (void) + sizeof (struct multiboot_tag_vbe) + MULTIBOOT_TAG_ALIGN - 1; } -#ifdef GRUB_MACHINE_HAS_VBE - -static grub_err_t -fill_vbe_info (struct grub_vbe_mode_info_block **vbe_mode_info_out, - grub_uint8_t **ptrorig) -{ - struct multiboot_tag_vbe *tag = (struct multiboot_tag_vbe *) *ptrorig; - grub_err_t err; - - tag->type = MULTIBOOT_TAG_TYPE_VBE; - tag->size = 0; - err = grub_multiboot_fill_vbe_info_real ((struct grub_vbe_info_block *) - &(tag->vbe_control_info), - (struct grub_vbe_mode_info_block *) - &(tag->vbe_mode_info), - &(tag->vbe_mode), - &(tag->vbe_interface_seg), - &(tag->vbe_interface_off), - &(tag->vbe_interface_len)); - if (err) - return err; - if (vbe_mode_info_out) - *vbe_mode_info_out = (struct grub_vbe_mode_info_block *) - &(tag->vbe_mode_info); - tag->size = sizeof (struct multiboot_tag_vbe); - *ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN); - return GRUB_ERR_NONE; -} - -#endif - /* Fill previously allocated Multiboot mmap. */ static void grub_fill_multiboot_mmap (struct multiboot_tag_mmap *tag) @@ -373,11 +342,35 @@ retrieve_video_parameters (grub_uint8_t **ptrorig) #if HAS_VGA_TEXT if (driv_id == GRUB_VIDEO_DRIVER_NONE) { - struct grub_vbe_mode_info_block *vbe_mode_info; - err = fill_vbe_info (&vbe_mode_info, ptrorig); - if (err) - return err; - if (vbe_mode_info->memory_model == GRUB_VBE_MEMORY_MODEL_TEXT) + struct grub_vbe_mode_info_block vbe_mode_info; + grub_vbe_status_t status; + grub_uint32_t vbe_mode; + void *scratch = (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR; + + status = grub_vbe_bios_get_mode (scratch); + vbe_mode = *(grub_uint32_t *) scratch; + if (status != GRUB_VBE_STATUS_OK) + return GRUB_ERR_NONE; + + /* get_mode_info isn't available for mode 3. */ + if (vbe_mode == 3) + { + grub_memset (&vbe_mode_info, 0, + sizeof (struct grub_vbe_mode_info_block)); + vbe_mode_info.memory_model = GRUB_VBE_MEMORY_MODEL_TEXT; + vbe_mode_info.x_resolution = 80; + vbe_mode_info.y_resolution = 25; + } + else + { + status = grub_vbe_bios_get_mode_info (vbe_mode, scratch); + if (status != GRUB_VBE_STATUS_OK) + return GRUB_ERR_NONE; + grub_memcpy (&vbe_mode_info, scratch, + sizeof (struct grub_vbe_mode_info_block)); + } + + if (vbe_mode_info.memory_model == GRUB_VBE_MEMORY_MODEL_TEXT) { tag = (struct multiboot_tag_framebuffer *) *ptrorig; tag->common.type = MULTIBOOT_TAG_TYPE_FRAMEBUFFER; @@ -385,9 +378,9 @@ retrieve_video_parameters (grub_uint8_t **ptrorig) tag->common.framebuffer_addr = 0xb8000; - tag->common.framebuffer_pitch = 2 * vbe_mode_info->x_resolution; - tag->common.framebuffer_width = vbe_mode_info->x_resolution; - tag->common.framebuffer_height = vbe_mode_info->y_resolution; + tag->common.framebuffer_pitch = 2 * vbe_mode_info.x_resolution; + tag->common.framebuffer_width = vbe_mode_info.x_resolution; + tag->common.framebuffer_height = vbe_mode_info.y_resolution; tag->common.framebuffer_bpp = 16; @@ -453,15 +446,6 @@ retrieve_video_parameters (grub_uint8_t **ptrorig) } *ptrorig += ALIGN_UP (tag->common.size, MULTIBOOT_TAG_ALIGN); -#if HAS_VBE - if (driv_id == GRUB_VIDEO_DRIVER_VBE) - { - err = fill_vbe_info (NULL, ptrorig); - if (err) - return err; - } -#endif - return GRUB_ERR_NONE; } From 016883a55c11f0db1dd3759129d0c83fcfb8eb5d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 28 Mar 2010 14:19:41 +0200 Subject: [PATCH 516/738] * include/multiboot2.h: Resync with spec. --- ChangeLog | 4 ++++ include/multiboot2.h | 14 +------------- 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index b15ba47d5..aba023c7b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-03-28 Vladimir Serbinenko + + * include/multiboot2.h: Resync with spec. + 2010-03-28 Vladimir Serbinenko Multiboot2 tag support diff --git a/include/multiboot2.h b/include/multiboot2.h index 59d7c951f..647109c0b 100644 --- a/include/multiboot2.h +++ b/include/multiboot2.h @@ -36,22 +36,10 @@ #define MULTIBOOT_MOD_ALIGN 0x00001000 /* Alignment of the multiboot info structure. */ -#define MULTIBOOT_INFO_ALIGN 0x00000004 +#define MULTIBOOT_INFO_ALIGN 0x00000008 /* Flags set in the 'flags' member of the multiboot header. */ -/* Align all boot modules on i386 page (4KB) boundaries. */ -#define MULTIBOOT_PAGE_ALIGN 0x00000001 - -/* Must pass memory information to OS. */ -#define MULTIBOOT_MEMORY_INFO 0x00000002 - -/* Must pass video information to OS. */ -#define MULTIBOOT_VIDEO_MODE 0x00000004 - -/* This flag indicates the use of the address fields in the header. */ -#define MULTIBOOT_AOUT_KLUDGE 0x00010000 - #define MULTIBOOT_TAG_ALIGN 8 #define MULTIBOOT_TAG_TYPE_END 0 #define MULTIBOOT_TAG_TYPE_CMDLINE 1 From a64b15feedea40d814aa6e04682605781e43b289 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 28 Mar 2010 21:43:42 +0200 Subject: [PATCH 517/738] resynced with gnulib. Cleaned up wrapping layer --- Makefile.in | 4 +- conf/common.rmk | 6 +- gnulib/regcomp.c | 172 ++++++++++-------- gnulib/regex.c | 50 ++++- {include/grub => gnulib}/regex.h | 7 +- gnulib/regex_internal.c | 101 +++++----- gnulib/regex_internal.h | 49 ++++- gnulib/regexec.c | 161 ++++++++-------- lib/posix_wrap/assert.h | 33 ++++ .../gnulib-wrap.h => lib/posix_wrap/ctype.h | 98 +--------- lib/posix_wrap/langinfo.h | 38 ++++ lib/posix_wrap/limits.h | 0 lib/posix_wrap/localcharset.h | 28 +++ lib/posix_wrap/stdint.h | 1 + lib/posix_wrap/stdio.h | 24 +++ lib/posix_wrap/stdlib.h | 56 ++++++ lib/posix_wrap/string.h | 40 ++++ lib/posix_wrap/sys/types.h | 32 ++++ lib/posix_wrap/wchar.h | 25 +++ lib/posix_wrap/wctype.h | 0 20 files changed, 620 insertions(+), 305 deletions(-) rename {include/grub => gnulib}/regex.h (99%) create mode 100644 lib/posix_wrap/assert.h rename include/grub/gnulib-wrap.h => lib/posix_wrap/ctype.h (51%) create mode 100644 lib/posix_wrap/langinfo.h create mode 100644 lib/posix_wrap/limits.h create mode 100644 lib/posix_wrap/localcharset.h create mode 100644 lib/posix_wrap/stdint.h create mode 100644 lib/posix_wrap/stdio.h create mode 100644 lib/posix_wrap/stdlib.h create mode 100644 lib/posix_wrap/string.h create mode 100644 lib/posix_wrap/sys/types.h create mode 100644 lib/posix_wrap/wchar.h create mode 100644 lib/posix_wrap/wctype.h diff --git a/Makefile.in b/Makefile.in index d640b91d6..2580c15b6 100644 --- a/Makefile.in +++ b/Makefile.in @@ -79,7 +79,9 @@ LIBS = @LIBS@ $(LIBINTL) CC = @CC@ CFLAGS = @CFLAGS@ -GNULIB_CFLAGS = -Wno-undef -D_GL_UNUSED="__attribute__ ((unused))" +POSIX_CFLAGS = -I$(srcdir)/lib/posix_wrap +GNULIB_UTIL_CFLAGS = -Wno-undef -Wno-sign-compare -Wno-unused -D_GL_UNUSED="__attribute__ ((unused))" -I$(srcdir)/gnulib +GNULIB_CFLAGS = $(GNULIB_UTIL_CFLAGS) $(POSIX_CFLAGS) ASFLAGS = @ASFLAGS@ LDFLAGS = @LDFLAGS@ $(LIBS) CPPFLAGS = @CPPFLAGS@ -I$(builddir) -I$(builddir)/include -I$(srcdir)/gnulib -I$(srcdir)/include -Wall -W \ diff --git a/conf/common.rmk b/conf/common.rmk index b2e5e0247..b9ed37d26 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -56,7 +56,7 @@ grub_mkisofs_SOURCES = util/mkisofs/eltorito.c \ gnulib/error.c gnulib/progname.c grub_mkisofs_CFLAGS = -D_FILE_OFFSET_BITS=64 \ -I$(srcdir)/util/mkisofs/include \ - -Wno-all -Werror $(GNULIB_CFLAGS) + -Wno-all -Werror $(GNULIB_UTIL_CFLAGS) # For grub-fstest. util/grub-fstest.c_DEPENDENCIES = grub_fstest_init.h @@ -111,7 +111,7 @@ grub_script_check_SOURCES = gnulib/progname.c gnulib/getdelim.c gnulib/getline.c kern/handler.c kern/err.c kern/parser.c kern/list.c \ kern/misc.c kern/env.c grub_script_check_init.c grub_script.tab.c \ grub_script.yy.c -grub_script_check_CFLAGS = $(GNULIB_CFLAGS) +grub_script_check_CFLAGS = $(GNULIB_UTIL_CFLAGS) MOSTLYCLEANFILES += symlist.c kernel_syms.lst DEFSYMFILES += kernel_syms.lst @@ -788,7 +788,7 @@ charset_mod_LDFLAGS = $(COMMON_LDFLAGS) pkglib_MODULES += regexp.mod regexp_mod_SOURCES = gnulib/regex.c commands/regexp.c -regexp_mod_CFLAGS = $(COMMON_CFLAGS) -Wno-sign-compare -Wno-unused +regexp_mod_CFLAGS = $(COMMON_CFLAGS) $(GNULIB_CFLAGS) regexp_mod_LDFLAGS = $(COMMON_LDFLAGS) pkglib_MODULES += terminal.mod diff --git a/gnulib/regcomp.c b/gnulib/regcomp.c index 6472ff6b2..7eff56925 100644 --- a/gnulib/regcomp.c +++ b/gnulib/regcomp.c @@ -1,6 +1,6 @@ /* Extended regular expression matching and search library. - Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009 - Free Software Foundation, Inc. + Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free + Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Isamu Hasegawa . @@ -383,7 +383,7 @@ re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state, applies to multibyte character sets; for single byte character sets, the SIMPLE_BRACKET again suffices. */ if (dfa->mb_cur_max > 1 - && (cset->nchar_classes || cset->non_match + && (cset->nchar_classes || cset->non_match || cset->nranges # ifdef _LIBC || cset->nequiv_classes # endif /* _LIBC */ @@ -636,7 +636,7 @@ free_dfa_content (re_dfa_t *dfa) re_dfastate_t *state = entry->array[j]; free_state (state); } - re_free (entry->array); + re_free (entry->array); } re_free (dfa->state_table); #ifdef RE_ENABLE_I18N @@ -850,6 +850,9 @@ static reg_errcode_t init_dfa (re_dfa_t *dfa, size_t pat_len) { __re_size_t table_size; +#ifndef _LIBC + char *codeset_name; +#endif #ifdef RE_ENABLE_I18N size_t max_i18n_object_size = MAX (sizeof (wchar_t), sizeof (wctype_t)); #else @@ -893,7 +896,9 @@ init_dfa (re_dfa_t *dfa, size_t pat_len) dfa->map_notascii = (_NL_CURRENT_WORD (LC_CTYPE, _NL_CTYPE_MAP_TO_NONASCII) != 0); #else - if (strcmp (locale_charset (), "UTF-8") == 0) + codeset_name = nl_langinfo (CODESET); + if (strcasecmp (codeset_name, "UTF-8") == 0 + || strcasecmp (codeset_name, "UTF8") == 0) dfa->is_utf8 = 1; /* We check exhaustively in the loop below if this charset is a @@ -1016,7 +1021,10 @@ create_initial_state (re_dfa_t *dfa) Idx dest_idx = dfa->edests[node_idx].elems[0]; if (!re_node_set_contains (&init_nodes, dest_idx)) { - re_node_set_merge (&init_nodes, dfa->eclosures + dest_idx); + reg_errcode_t merge_err + = re_node_set_merge (&init_nodes, dfa->eclosures + dest_idx); + if (merge_err != REG_NOERROR) + return merge_err; i = 0; } } @@ -1085,8 +1093,8 @@ optimize_utf8 (re_dfa_t *dfa) } break; case OP_PERIOD: - has_period = true; - break; + has_period = true; + break; case OP_BACK_REF: case OP_ALT: case END_OF_RE: @@ -1187,7 +1195,7 @@ analyze (regex_t *preg) { dfa->inveclosures = re_malloc (re_node_set, dfa->nodes_len); if (BE (dfa->inveclosures == NULL, 0)) - return REG_ESPACE; + return REG_ESPACE; ret = calc_inveclosure (dfa); } @@ -1209,16 +1217,16 @@ postorder (bin_tree_t *root, reg_errcode_t (fn (void *, bin_tree_t *)), if that's the only child). */ while (node->left || node->right) if (node->left) - node = node->left; - else - node = node->right; + node = node->left; + else + node = node->right; do { reg_errcode_t err = fn (extra, node); if (BE (err != REG_NOERROR, 0)) return err; - if (node->parent == NULL) + if (node->parent == NULL) return REG_NOERROR; prev = node; node = node->parent; @@ -1252,7 +1260,7 @@ preorder (bin_tree_t *root, reg_errcode_t (fn (void *, bin_tree_t *)), prev = node; node = node->parent; if (!node) - return REG_NOERROR; + return REG_NOERROR; } node = node->right; } @@ -1275,13 +1283,13 @@ optimize_subexps (void *extra, bin_tree_t *node) } else if (node->token.type == SUBEXP - && node->left && node->left->token.type == SUBEXP) + && node->left && node->left->token.type == SUBEXP) { Idx other_idx = node->left->token.opr.idx; node->left = node->left->left; if (node->left) - node->left->parent = node; + node->left->parent = node; dfa->subexp_map[other_idx] = dfa->subexp_map[node->token.opr.idx]; if (other_idx < BITSET_WORD_BITS) @@ -1366,9 +1374,9 @@ calc_first (void *extra, bin_tree_t *node) node->first = node; node->node_idx = re_dfa_add_node (dfa, node->token); if (BE (node->node_idx == REG_MISSING, 0)) - return REG_ESPACE; + return REG_ESPACE; if (node->token.type == ANCHOR) - dfa->nodes[node->node_idx].constraint = node->token.opr.ctx_type; + dfa->nodes[node->node_idx].constraint = node->token.opr.ctx_type; } return REG_NOERROR; } @@ -1390,7 +1398,7 @@ calc_next (void *extra, bin_tree_t *node) if (node->left) node->left->next = node->next; if (node->right) - node->right->next = node->next; + node->right->next = node->next; break; } return REG_NOERROR; @@ -1441,7 +1449,7 @@ link_nfa_nodes (void *extra, bin_tree_t *node) case OP_BACK_REF: dfa->nexts[idx] = node->next->node_idx; if (node->token.type == OP_BACK_REF) - re_node_set_init_1 (dfa->edests + idx, dfa->nexts[idx]); + err = re_node_set_init_1 (dfa->edests + idx, dfa->nexts[idx]); break; default: @@ -1498,7 +1506,6 @@ duplicate_node_closure (re_dfa_t *dfa, Idx top_org_node, Idx top_clone_node, destination. */ org_dest = dfa->edests[org_node].elems[0]; re_node_set_empty (dfa->edests + clone_node); - clone_dest = search_duplicated_node (dfa, org_dest, constraint); /* If the node is root_node itself, it means the epsilon closure has a loop. Then tie it to the destination of the root_node. */ if (org_node == root_node && clone_node != org_node) @@ -1542,7 +1549,7 @@ duplicate_node_closure (re_dfa_t *dfa, Idx top_org_node, Idx top_clone_node, } else { - /* There is a duplicated node which satisfy the constraint, + /* There is a duplicated node which satisfies the constraint, use it to avoid infinite loop. */ ok = re_node_set_insert (dfa->edests + clone_node, clone_dest); if (BE (! ok, 0)) @@ -1674,10 +1681,9 @@ calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa, Idx node, bool root) { reg_errcode_t err; Idx i; - bool incomplete; - bool ok; re_node_set eclosure; - incomplete = false; + bool ok; + bool incomplete = false; err = re_node_set_alloc (&eclosure, dfa->edests[node].nelem + 1); if (BE (err != REG_NOERROR, 0)) return err; @@ -1722,7 +1728,9 @@ calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa, Idx node, bool root) else eclosure_elem = dfa->eclosures[edest]; /* Merge the epsilon closure of `edest'. */ - re_node_set_merge (&eclosure, &eclosure_elem); + err = re_node_set_merge (&eclosure, &eclosure_elem); + if (BE (err != REG_NOERROR, 0)) + return err; /* If the epsilon closure of `edest' is incomplete, the epsilon closure of this node is also incomplete. */ if (dfa->eclosures[edest].nelem == 0) @@ -1732,7 +1740,7 @@ calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa, Idx node, bool root) } } - /* Epsilon closures include itself. */ + /* An epsilon closure includes itself. */ ok = re_node_set_insert (&eclosure, node); if (BE (! ok, 0)) return REG_ESPACE; @@ -2319,7 +2327,7 @@ parse_expression (re_string_t *regexp, regex_t *preg, re_token_t *token, && dfa->word_ops_used == 0) init_word_char (dfa); if (token->opr.ctx_type == WORD_DELIM - || token->opr.ctx_type == NOT_WORD_DELIM) + || token->opr.ctx_type == NOT_WORD_DELIM) { bin_tree_t *tree_first, *tree_last; if (token->opr.ctx_type == WORD_DELIM) @@ -2327,13 +2335,13 @@ parse_expression (re_string_t *regexp, regex_t *preg, re_token_t *token, token->opr.ctx_type = WORD_FIRST; tree_first = create_token_tree (dfa, NULL, NULL, token); token->opr.ctx_type = WORD_LAST; - } - else - { + } + else + { token->opr.ctx_type = INSIDE_WORD; tree_first = create_token_tree (dfa, NULL, NULL, token); token->opr.ctx_type = INSIDE_NOTWORD; - } + } tree_last = create_token_tree (dfa, NULL, NULL, token); tree = create_tree (dfa, tree_first, tree_last, OP_ALT); if (BE (tree_first == NULL || tree_last == NULL || tree == NULL, 0)) @@ -2444,7 +2452,7 @@ parse_sub_exp (re_string_t *regexp, regex_t *preg, re_token_t *token, { tree = parse_reg_exp (regexp, preg, token, syntax, nest, err); if (BE (*err == REG_NOERROR && token->type != OP_CLOSE_SUBEXP, 0)) - *err = REG_EPAREN; + *err = REG_EPAREN; if (BE (*err != REG_NOERROR, 0)) return NULL; } @@ -2515,7 +2523,8 @@ parse_dup_op (bin_tree_t *elem, re_string_t *regexp, re_dfa_t *dfa, return elem; } - if (BE (end != REG_MISSING && start > end, 0)) + if (BE ((end != REG_MISSING && start > end) + || token->type != OP_CLOSE_DUP_NUM, 0)) { /* First number greater than second. */ *err = REG_BADBR; @@ -2568,10 +2577,14 @@ parse_dup_op (bin_tree_t *elem, re_string_t *regexp, re_dfa_t *dfa, if (BE (tree == NULL, 0)) goto parse_dup_op_espace; +/* From gnulib's "intprops.h": + True if the arithmetic type T is signed. */ +#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1)) + /* This loop is actually executed only when end != REG_MISSING, to rewrite {0,n} as ((...?)?)?... We have already created the start+1-th copy. */ - if ((Idx) -1 < 0 || end != REG_MISSING) + if (TYPE_SIGNED (Idx) || end != REG_MISSING) for (i = start + 2; i <= end; ++i) { elem = duplicate_tree (elem, dfa); @@ -2609,11 +2622,17 @@ parse_dup_op (bin_tree_t *elem, re_string_t *regexp, re_dfa_t *dfa, static reg_errcode_t internal_function # ifdef RE_ENABLE_I18N -build_range_exp (bitset_t sbcset, re_charset_t *mbcset, Idx *range_alloc, - bracket_elem_t *start_elem, bracket_elem_t *end_elem) +build_range_exp (const reg_syntax_t syntax, + bitset_t sbcset, + re_charset_t *mbcset, + Idx *range_alloc, + const bracket_elem_t *start_elem, + const bracket_elem_t *end_elem) # else /* not RE_ENABLE_I18N */ -build_range_exp (bitset_t sbcset, bracket_elem_t *start_elem, - bracket_elem_t *end_elem) +build_range_exp (const reg_syntax_t syntax, + bitset_t sbcset, + const bracket_elem_t *start_elem, + const bracket_elem_t *end_elem) # endif /* not RE_ENABLE_I18N */ { unsigned int start_ch, end_ch; @@ -2652,7 +2671,9 @@ build_range_exp (bitset_t sbcset, bracket_elem_t *start_elem, return REG_ECOLLATE; cmp_buf[0] = start_wc; cmp_buf[4] = end_wc; - if (wcscoll (cmp_buf, cmp_buf + 4) > 0) + + if (BE ((syntax & RE_NO_EMPTY_RANGES) + && wcscoll (cmp_buf, cmp_buf + 4) > 0, 0)) return REG_ERANGE; /* Got valid collation sequence values, add them as a new entry. @@ -2662,9 +2683,9 @@ build_range_exp (bitset_t sbcset, bracket_elem_t *start_elem, no MBCSET if dfa->mb_cur_max == 1. */ if (mbcset) { - /* Check the space of the arrays. */ - if (BE (*range_alloc == mbcset->nranges, 0)) - { + /* Check the space of the arrays. */ + if (BE (*range_alloc == mbcset->nranges, 0)) + { /* There is not enough space, need realloc. */ wchar_t *new_array_start, *new_array_end; Idx new_nranges; @@ -2674,9 +2695,9 @@ build_range_exp (bitset_t sbcset, bracket_elem_t *start_elem, /* Use realloc since mbcset->range_starts and mbcset->range_ends are NULL if *range_alloc == 0. */ new_array_start = re_realloc (mbcset->range_starts, wchar_t, - new_nranges); + new_nranges); new_array_end = re_realloc (mbcset->range_ends, wchar_t, - new_nranges); + new_nranges); if (BE (new_array_start == NULL || new_array_end == NULL, 0)) return REG_ESPACE; @@ -2684,10 +2705,10 @@ build_range_exp (bitset_t sbcset, bracket_elem_t *start_elem, mbcset->range_starts = new_array_start; mbcset->range_ends = new_array_end; *range_alloc = new_nranges; - } + } - mbcset->range_starts[mbcset->nranges] = start_wc; - mbcset->range_ends[mbcset->nranges++] = end_wc; + mbcset->range_starts[mbcset->nranges] = start_wc; + mbcset->range_ends[mbcset->nranges++] = end_wc; } /* Build the table for single byte characters. */ @@ -2799,7 +2820,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token, return elem; } - /* Local function for parse_bracket_exp used in _LIBC environement. + /* Local function for parse_bracket_exp used in _LIBC environment. Look up the collation sequence value of BR_ELEM. Return the value if succeeded, UINT_MAX otherwise. */ @@ -2823,7 +2844,8 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token, } else if (br_elem->type == MB_CHAR) { - return __collseq_table_lookup (collseqwc, br_elem->opr.wch); + if (nrules != 0) + return __collseq_table_lookup (collseqwc, br_elem->opr.wch); } else if (br_elem->type == COLL_SYM) { @@ -2904,8 +2926,8 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token, build below suffices. */ if (nrules > 0 || dfa->mb_cur_max > 1) { - /* Check the space of the arrays. */ - if (BE (*range_alloc == mbcset->nranges, 0)) + /* Check the space of the arrays. */ + if (BE (*range_alloc == mbcset->nranges, 0)) { /* There is not enough space, need realloc. */ uint32_t *new_array_start; @@ -2917,18 +2939,18 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token, new_array_start = re_realloc (mbcset->range_starts, uint32_t, new_nranges); new_array_end = re_realloc (mbcset->range_ends, uint32_t, - new_nranges); + new_nranges); if (BE (new_array_start == NULL || new_array_end == NULL, 0)) - return REG_ESPACE; + return REG_ESPACE; mbcset->range_starts = new_array_start; mbcset->range_ends = new_array_end; *range_alloc = new_nranges; } - mbcset->range_starts[mbcset->nranges] = start_collseq; - mbcset->range_ends[mbcset->nranges++] = end_collseq; + mbcset->range_starts[mbcset->nranges] = start_collseq; + mbcset->range_ends[mbcset->nranges++] = end_collseq; } /* Build the table for single byte characters. */ @@ -3154,11 +3176,11 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token, &start_elem, &end_elem); #else # ifdef RE_ENABLE_I18N - *err = build_range_exp (sbcset, + *err = build_range_exp (syntax, sbcset, dfa->mb_cur_max > 1 ? mbcset : NULL, &range_alloc, &start_elem, &end_elem); # else - *err = build_range_exp (sbcset, &start_elem, &end_elem); + *err = build_range_exp (syntax, sbcset, &start_elem, &end_elem); # endif #endif /* RE_ENABLE_I18N */ if (BE (*err != REG_NOERROR, 0)) @@ -3262,17 +3284,17 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token, of having both SIMPLE_BRACKET and COMPLEX_BRACKET. */ if (sbc_idx < BITSET_WORDS) { - /* Build a tree for simple bracket. */ - br_token.type = SIMPLE_BRACKET; - br_token.opr.sbcset = sbcset; - work_tree = create_token_tree (dfa, NULL, NULL, &br_token); - if (BE (work_tree == NULL, 0)) - goto parse_bracket_exp_espace; + /* Build a tree for simple bracket. */ + br_token.type = SIMPLE_BRACKET; + br_token.opr.sbcset = sbcset; + work_tree = create_token_tree (dfa, NULL, NULL, &br_token); + if (BE (work_tree == NULL, 0)) + goto parse_bracket_exp_espace; - /* Then join them by ALT node. */ - work_tree = create_tree (dfa, work_tree, mbc_tree, OP_ALT); - if (BE (work_tree == NULL, 0)) - goto parse_bracket_exp_espace; + /* Then join them by ALT node. */ + work_tree = create_tree (dfa, work_tree, mbc_tree, OP_ALT); + if (BE (work_tree == NULL, 0)) + goto parse_bracket_exp_espace; } else { @@ -3291,7 +3313,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token, br_token.opr.sbcset = sbcset; work_tree = create_token_tree (dfa, NULL, NULL, &br_token); if (BE (work_tree == NULL, 0)) - goto parse_bracket_exp_espace; + goto parse_bracket_exp_espace; } return work_tree; @@ -3430,7 +3452,7 @@ build_equiv_class (bitset_t sbcset, const unsigned char *name) /* Build single byte matcing table for this equivalence class. */ char_buf[1] = (unsigned char) '\0'; - len = weights[idx1]; + len = weights[idx1 & 0xffffff]; for (ch = 0; ch < SBC_MAX; ++ch) { char_buf[0] = ch; @@ -3442,11 +3464,15 @@ build_equiv_class (bitset_t sbcset, const unsigned char *name) if (idx2 == 0) /* This isn't a valid character. */ continue; - if (len == weights[idx2]) + /* Compare only if the length matches and the collation rule + index is the same. */ + if (len == weights[idx2 & 0xffffff] && (idx1 >> 24) == (idx2 >> 24)) { int cnt = 0; + while (cnt <= len && - weights[idx1 + 1 + cnt] == weights[idx2 + 1 + cnt]) + weights[(idx1 & 0xffffff) + 1 + cnt] + == weights[(idx2 & 0xffffff) + 1 + cnt]) ++cnt; if (cnt > len) @@ -3842,7 +3868,7 @@ duplicate_tree (const bin_tree_t *root, re_dfa_t *dfa) node = node->parent; dup_node = dup_node->parent; if (!node) - return dup_root; + return dup_root; } node = node->right; p_new = &dup_node->right; diff --git a/gnulib/regex.c b/gnulib/regex.c index 76998f8d3..904fe62c8 100644 --- a/gnulib/regex.c +++ b/gnulib/regex.c @@ -1,5 +1,6 @@ /* Extended regular expression matching and search library. - Copyright (C) 2002, 2003, 2005, 2006 Free Software Foundation, Inc. + Copyright (C) 2002, 2003, 2005, 2006, 2009, 2010 Free Software Foundation, + Inc. This file is part of the GNU C Library. Contributed by Isamu Hasegawa . @@ -17,10 +18,55 @@ with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#include +#include +/* Make sure noone compiles this code with a C++ compiler. */ +#if defined __cplusplus && defined _LIBC +# error "This is C code, use a C compiler" +#endif + +#ifdef _LIBC +/* We have to keep the namespace clean. */ +# define regfree(preg) __regfree (preg) +# define regexec(pr, st, nm, pm, ef) __regexec (pr, st, nm, pm, ef) +# define regcomp(preg, pattern, cflags) __regcomp (preg, pattern, cflags) +# define regerror(errcode, preg, errbuf, errbuf_size) \ + __regerror(errcode, preg, errbuf, errbuf_size) +# define re_set_registers(bu, re, nu, st, en) \ + __re_set_registers (bu, re, nu, st, en) +# define re_match_2(bufp, string1, size1, string2, size2, pos, regs, stop) \ + __re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop) +# define re_match(bufp, string, size, pos, regs) \ + __re_match (bufp, string, size, pos, regs) +# define re_search(bufp, string, size, startpos, range, regs) \ + __re_search (bufp, string, size, startpos, range, regs) +# define re_compile_pattern(pattern, length, bufp) \ + __re_compile_pattern (pattern, length, bufp) +# define re_set_syntax(syntax) __re_set_syntax (syntax) +# define re_search_2(bufp, st1, s1, st2, s2, startpos, range, regs, stop) \ + __re_search_2 (bufp, st1, s1, st2, s2, startpos, range, regs, stop) +# define re_compile_fastmap(bufp) __re_compile_fastmap (bufp) + +# include "../locale/localeinfo.h" +#endif + +/* On some systems, limits.h sets RE_DUP_MAX to a lower value than + GNU regex allows. Include it before , which correctly + #undefs RE_DUP_MAX and sets it to the right value. */ +#include + +#include #include "regex_internal.h" #include "regex_internal.c" #include "regcomp.c" #include "regexec.c" + +/* Binary backward compatibility. */ +#if _LIBC +# include +# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3) +link_warning (re_max_failures, "the 're_max_failures' variable is obsolete and will go away.") +int re_max_failures = 2000; +# endif +#endif diff --git a/include/grub/regex.h b/gnulib/regex.h similarity index 99% rename from include/grub/regex.h rename to gnulib/regex.h index 091342d0b..594d5e6aa 100644 --- a/include/grub/regex.h +++ b/gnulib/regex.h @@ -1,7 +1,8 @@ /* Definitions for data structures and routines for the regular expression library. - Copyright (C) 1985,1989-93,1995-98,2000,2001,2002,2003,2005,2006 - Free Software Foundation, Inc. + Copyright (C) 1985, 1989, 1990, 1991, 1992, 1993, 1995, 1996, 1997, 1998, + 2000, 2001, 2002, 2003, 2005, 2006, 2009, 2010 Free Software Foundation, + Inc. This file is part of the GNU C Library. This program is free software; you can redistribute it and/or modify @@ -21,7 +22,7 @@ #ifndef _REGEX_H #define _REGEX_H 1 -#include +#include /* Allow the use in C++ code. */ #ifdef __cplusplus diff --git a/gnulib/regex_internal.c b/gnulib/regex_internal.c index 904b88ed9..378b767d8 100644 --- a/gnulib/regex_internal.c +++ b/gnulib/regex_internal.c @@ -1,6 +1,6 @@ /* Extended regular expression matching and search library. - Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 - Free Software Foundation, Inc. + Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free + Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Isamu Hasegawa . @@ -36,7 +36,7 @@ static re_dfastate_t *create_cd_newstate (const re_dfa_t *dfa, re_string_reconstruct before using the object. */ static reg_errcode_t -internal_function +internal_function __attribute_warn_unused_result__ re_string_allocate (re_string_t *pstr, const char *str, Idx len, Idx init_len, RE_TRANSLATE_TYPE trans, bool icase, const re_dfa_t *dfa) { @@ -64,7 +64,7 @@ re_string_allocate (re_string_t *pstr, const char *str, Idx len, Idx init_len, /* This function allocate the buffers, and initialize them. */ static reg_errcode_t -internal_function +internal_function __attribute_warn_unused_result__ re_string_construct (re_string_t *pstr, const char *str, Idx len, RE_TRANSLATE_TYPE trans, bool icase, const re_dfa_t *dfa) { @@ -127,7 +127,7 @@ re_string_construct (re_string_t *pstr, const char *str, Idx len, /* Helper functions for re_string_allocate, and re_string_construct. */ static reg_errcode_t -internal_function +internal_function __attribute_warn_unused_result__ re_string_realloc_buffers (re_string_t *pstr, Idx new_buf_len) { #ifdef RE_ENABLE_I18N @@ -267,7 +267,7 @@ build_wcs_buffer (re_string_t *pstr) but for REG_ICASE. */ static reg_errcode_t -internal_function +internal_function __attribute_warn_unused_result__ build_wcs_upper_buffer (re_string_t *pstr) { mbstate_t prev_st; @@ -430,8 +430,8 @@ build_wcs_upper_buffer (re_string_t *pstr) src_idx += mbclen; continue; } - else - memcpy (pstr->mbs + byte_idx, p, mbclen); + else + memcpy (pstr->mbs + byte_idx, p, mbclen); } else memcpy (pstr->mbs + byte_idx, p, mbclen); @@ -569,7 +569,7 @@ re_string_translate_buffer (re_string_t *pstr) convert to upper case in case of REG_ICASE, apply translation. */ static reg_errcode_t -internal_function +internal_function __attribute_warn_unused_result__ re_string_reconstruct (re_string_t *pstr, Idx idx, int eflags) { Idx offset; @@ -964,7 +964,7 @@ re_string_context_at (const re_string_t *input, Idx idx, int eflags) /* Functions for set operation. */ static reg_errcode_t -internal_function +internal_function __attribute_warn_unused_result__ re_node_set_alloc (re_node_set *set, Idx size) { set->alloc = size; @@ -976,7 +976,7 @@ re_node_set_alloc (re_node_set *set, Idx size) } static reg_errcode_t -internal_function +internal_function __attribute_warn_unused_result__ re_node_set_init_1 (re_node_set *set, Idx elem) { set->alloc = 1; @@ -992,7 +992,7 @@ re_node_set_init_1 (re_node_set *set, Idx elem) } static reg_errcode_t -internal_function +internal_function __attribute_warn_unused_result__ re_node_set_init_2 (re_node_set *set, Idx elem1, Idx elem2) { set->alloc = 2; @@ -1022,7 +1022,7 @@ re_node_set_init_2 (re_node_set *set, Idx elem1, Idx elem2) } static reg_errcode_t -internal_function +internal_function __attribute_warn_unused_result__ re_node_set_init_copy (re_node_set *dest, const re_node_set *src) { dest->nelem = src->nelem; @@ -1047,7 +1047,7 @@ re_node_set_init_copy (re_node_set *dest, const re_node_set *src) Note: We assume dest->elems is NULL, when dest->alloc is 0. */ static reg_errcode_t -internal_function +internal_function __attribute_warn_unused_result__ re_node_set_add_intersect (re_node_set *dest, const re_node_set *src1, const re_node_set *src2) { @@ -1062,7 +1062,7 @@ re_node_set_add_intersect (re_node_set *dest, const re_node_set *src1, Idx new_alloc = src1->nelem + src2->nelem + dest->alloc; Idx *new_elems = re_realloc (dest->elems, Idx, new_alloc); if (BE (new_elems == NULL, 0)) - return REG_ESPACE; + return REG_ESPACE; dest->elems = new_elems; dest->alloc = new_alloc; } @@ -1112,20 +1112,20 @@ re_node_set_add_intersect (re_node_set *dest, const re_node_set *src1, if (delta > 0 && REG_VALID_INDEX (id)) for (;;) { - if (dest->elems[is] > dest->elems[id]) - { - /* Copy from the top. */ - dest->elems[id + delta--] = dest->elems[is--]; - if (delta == 0) - break; - } - else - { - /* Slide from the bottom. */ - dest->elems[id + delta] = dest->elems[id]; - if (! REG_VALID_INDEX (--id)) - break; - } + if (dest->elems[is] > dest->elems[id]) + { + /* Copy from the top. */ + dest->elems[id + delta--] = dest->elems[is--]; + if (delta == 0) + break; + } + else + { + /* Slide from the bottom. */ + dest->elems[id + delta] = dest->elems[id]; + if (! REG_VALID_INDEX (--id)) + break; + } } /* Copy remaining SRC elements. */ @@ -1138,7 +1138,7 @@ re_node_set_add_intersect (re_node_set *dest, const re_node_set *src1, DEST. Return value indicate the error code or REG_NOERROR if succeeded. */ static reg_errcode_t -internal_function +internal_function __attribute_warn_unused_result__ re_node_set_init_union (re_node_set *dest, const re_node_set *src1, const re_node_set *src2) { @@ -1191,7 +1191,7 @@ re_node_set_init_union (re_node_set *dest, const re_node_set *src1, DEST. Return value indicate the error code or REG_NOERROR if succeeded. */ static reg_errcode_t -internal_function +internal_function __attribute_warn_unused_result__ re_node_set_merge (re_node_set *dest, const re_node_set *src) { Idx is, id, sbase, delta; @@ -1221,11 +1221,11 @@ re_node_set_merge (re_node_set *dest, const re_node_set *src) REG_VALID_INDEX (is) && REG_VALID_INDEX (id); ) { if (dest->elems[id] == src->elems[is]) - is--, id--; + is--, id--; else if (dest->elems[id] < src->elems[is]) - dest->elems[--sbase] = src->elems[is--]; + dest->elems[--sbase] = src->elems[is--]; else /* if (dest->elems[id] > src->elems[is]) */ - --id; + --id; } if (REG_VALID_INDEX (is)) @@ -1247,21 +1247,21 @@ re_node_set_merge (re_node_set *dest, const re_node_set *src) for (;;) { if (dest->elems[is] > dest->elems[id]) - { + { /* Copy from the top. */ - dest->elems[id + delta--] = dest->elems[is--]; + dest->elems[id + delta--] = dest->elems[is--]; if (delta == 0) break; } else - { - /* Slide from the bottom. */ - dest->elems[id + delta] = dest->elems[id]; + { + /* Slide from the bottom. */ + dest->elems[id + delta] = dest->elems[id]; if (! REG_VALID_INDEX (--id)) { /* Copy remaining SRC elements. */ memcpy (dest->elems, dest->elems + sbase, - delta * sizeof (Idx)); + delta * sizeof (Idx)); break; } } @@ -1275,7 +1275,7 @@ re_node_set_merge (re_node_set *dest, const re_node_set *src) Return true if successful. */ static bool -internal_function +internal_function __attribute_warn_unused_result__ re_node_set_insert (re_node_set *set, Idx elem) { Idx idx; @@ -1308,12 +1308,12 @@ re_node_set_insert (re_node_set *set, Idx elem) { idx = 0; for (idx = set->nelem; idx > 0; idx--) - set->elems[idx] = set->elems[idx - 1]; + set->elems[idx] = set->elems[idx - 1]; } else { for (idx = set->nelem; set->elems[idx - 1] > elem; idx--) - set->elems[idx] = set->elems[idx - 1]; + set->elems[idx] = set->elems[idx - 1]; } /* Insert the new element. */ @@ -1327,7 +1327,7 @@ re_node_set_insert (re_node_set *set, Idx elem) Return true if successful. */ static bool -internal_function +internal_function __attribute_warn_unused_result__ re_node_set_insert_last (re_node_set *set, Idx elem) { /* Realloc if we need. */ @@ -1473,7 +1473,7 @@ calc_state_hash (const re_node_set *nodes, unsigned int context) optimization. */ static re_dfastate_t * -internal_function +internal_function __attribute_warn_unused_result__ re_acquire_state (reg_errcode_t *err, const re_dfa_t *dfa, const re_node_set *nodes) { @@ -1521,7 +1521,7 @@ re_acquire_state (reg_errcode_t *err, const re_dfa_t *dfa, optimization. */ static re_dfastate_t * -internal_function +internal_function __attribute_warn_unused_result__ re_acquire_state_context (reg_errcode_t *err, const re_dfa_t *dfa, const re_node_set *nodes, unsigned int context) { @@ -1562,6 +1562,7 @@ re_acquire_state_context (reg_errcode_t *err, const re_dfa_t *dfa, indicates the error code if failed. */ static reg_errcode_t +__attribute_warn_unused_result__ register_state (const re_dfa_t *dfa, re_dfastate_t *newstate, re_hashval_t hash) { @@ -1616,7 +1617,7 @@ free_state (re_dfastate_t *state) Return the new state if succeeded, otherwise return NULL. */ static re_dfastate_t * -internal_function +internal_function __attribute_warn_unused_result__ create_ci_newstate (const re_dfa_t *dfa, const re_node_set *nodes, re_hashval_t hash) { @@ -1666,7 +1667,7 @@ create_ci_newstate (const re_dfa_t *dfa, const re_node_set *nodes, Return the new state if succeeded, otherwise return NULL. */ static re_dfastate_t * -internal_function +internal_function __attribute_warn_unused_result__ create_cd_newstate (const re_dfa_t *dfa, const re_node_set *nodes, unsigned int context, re_hashval_t hash) { @@ -1715,7 +1716,9 @@ create_cd_newstate (const re_dfa_t *dfa, const re_node_set *nodes, free_state (newstate); return NULL; } - re_node_set_init_copy (newstate->entrance_nodes, nodes); + if (re_node_set_init_copy (newstate->entrance_nodes, nodes) + != REG_NOERROR) + return NULL; nctx_nodes = 0; newstate->has_constraint = 1; } diff --git a/gnulib/regex_internal.h b/gnulib/regex_internal.h index 3cdc548d3..e1b4c61b3 100644 --- a/gnulib/regex_internal.h +++ b/gnulib/regex_internal.h @@ -1,6 +1,6 @@ /* Extended regular expression matching and search library. - Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 - Free Software Foundation, Inc. + Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free + Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Isamu Hasegawa . @@ -21,6 +21,32 @@ #ifndef _REGEX_INTERNAL_H #define _REGEX_INTERNAL_H 1 +#include +#include +#include +#include +#include +#include + +#include +#ifndef _LIBC +# include "localcharset.h" +#endif +#if defined HAVE_LOCALE_H || defined _LIBC +# include +#endif + +#include +#include +#include +#if defined _LIBC +# include +#else +# define __libc_lock_init(NAME) do { } while (0) +# define __libc_lock_lock(NAME) do { } while (0) +# define __libc_lock_unlock(NAME) do { } while (0) +#endif + /* In case that the system doesn't have isblank(). */ #if !defined _LIBC && ! (defined isblank || (HAVE_ISBLANK && HAVE_DECL_ISBLANK)) # define isblank(ch) ((ch) == ' ' || (ch) == '\t') @@ -58,7 +84,7 @@ # define SIZE_MAX ((size_t) -1) #endif -#if (defined MB_CUR_MAX && HAVE_LOCALE_H && HAVE_WCTYPE_H && HAVE_ISWCTYPE && HAVE_WCSCOLL) || defined (_LIBC) +#if (defined MB_CUR_MAX && HAVE_LOCALE_H && HAVE_WCTYPE_H && HAVE_ISWCTYPE && HAVE_WCSCOLL) || _LIBC # define RE_ENABLE_I18N #endif @@ -825,4 +851,21 @@ re_string_elem_size_at (const re_string_t *pstr, Idx idx) } #endif /* RE_ENABLE_I18N */ +#ifndef __GNUC_PREREQ +# if defined __GNUC__ && defined __GNUC_MINOR__ +# define __GNUC_PREREQ(maj, min) \ + ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min)) +# else +# define __GNUC_PREREQ(maj, min) 0 +# endif +#endif + +#if __GNUC_PREREQ (3,4) +# undef __attribute_warn_unused_result__ +# define __attribute_warn_unused_result__ \ + __attribute__ ((__warn_unused_result__)) +#else +# define __attribute_warn_unused_result__ /* empty */ +#endif + #endif /* _REGEX_INTERNAL_H */ diff --git a/gnulib/regexec.c b/gnulib/regexec.c index 21a81669f..9388ac12b 100644 --- a/gnulib/regexec.c +++ b/gnulib/regexec.c @@ -1,6 +1,6 @@ /* Extended regular expression matching and search library. - Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 - Free Software Foundation, Inc. + Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free + Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Isamu Hasegawa . @@ -637,7 +637,7 @@ re_exec (s) (0 <= LAST_START && LAST_START <= LENGTH) */ static reg_errcode_t -internal_function +internal_function __attribute_warn_unused_result__ re_search_internal (const regex_t *preg, const char *string, Idx length, Idx start, Idx last_start, Idx stop, @@ -833,10 +833,10 @@ re_search_internal (const regex_t *preg, break; match_first += incr; if (match_first < left_lim || match_first > right_lim) - { - err = REG_NOMATCH; - goto free_return; - } + { + err = REG_NOMATCH; + goto free_return; + } } break; } @@ -953,14 +953,14 @@ re_search_internal (const regex_t *preg, } if (dfa->subexp_map) - for (reg_idx = 0; reg_idx + 1 < nmatch; reg_idx++) - if (dfa->subexp_map[reg_idx] != reg_idx) - { - pmatch[reg_idx + 1].rm_so - = pmatch[dfa->subexp_map[reg_idx] + 1].rm_so; - pmatch[reg_idx + 1].rm_eo - = pmatch[dfa->subexp_map[reg_idx] + 1].rm_eo; - } + for (reg_idx = 0; reg_idx + 1 < nmatch; reg_idx++) + if (dfa->subexp_map[reg_idx] != reg_idx) + { + pmatch[reg_idx + 1].rm_so + = pmatch[dfa->subexp_map[reg_idx] + 1].rm_so; + pmatch[reg_idx + 1].rm_eo + = pmatch[dfa->subexp_map[reg_idx] + 1].rm_eo; + } } free_return: @@ -972,7 +972,7 @@ re_search_internal (const regex_t *preg, } static reg_errcode_t -internal_function +internal_function __attribute_warn_unused_result__ prune_impossible_nodes (re_match_context_t *mctx) { const re_dfa_t *const dfa = mctx->dfa; @@ -1110,7 +1110,7 @@ acquire_init_state_context (reg_errcode_t *err, const re_match_context_t *mctx, index of the buffer. */ static Idx -internal_function +internal_function __attribute_warn_unused_result__ check_matching (re_match_context_t *mctx, bool fl_longest_match, Idx *p_match_first) { @@ -1149,7 +1149,7 @@ check_matching (re_match_context_t *mctx, bool fl_longest_match, { err = transit_state_bkref (mctx, &cur_state->nodes); if (BE (err != REG_NOERROR, 0)) - return err; + return err; } } } @@ -1176,16 +1176,16 @@ check_matching (re_match_context_t *mctx, bool fl_longest_match, Idx next_char_idx = re_string_cur_idx (&mctx->input) + 1; if (BE (next_char_idx >= mctx->input.bufs_len, 0) - || (BE (next_char_idx >= mctx->input.valid_len, 0) - && mctx->input.valid_len < mctx->input.len)) - { - err = extend_buffers (mctx); - if (BE (err != REG_NOERROR, 0)) + || (BE (next_char_idx >= mctx->input.valid_len, 0) + && mctx->input.valid_len < mctx->input.len)) + { + err = extend_buffers (mctx); + if (BE (err != REG_NOERROR, 0)) { assert (err == REG_ESPACE); return REG_ERROR; } - } + } cur_state = transit_state (&err, mctx, cur_state); if (mctx->state_log != NULL) @@ -1309,17 +1309,17 @@ proceed_next_node (const re_match_context_t *mctx, Idx nregs, regmatch_t *regs, if (dest_node == REG_MISSING) dest_node = candidate; - else + else { /* In order to avoid infinite loop like "(a*)*", return the second - epsilon-transition if the first was already considered. */ + epsilon-transition if the first was already considered. */ if (re_node_set_contains (eps_via_nodes, dest_node)) - return candidate; + return candidate; /* Otherwise, push the second epsilon-transition on the fail stack. */ else if (fs != NULL && push_fail_stack (fs, *pidx, candidate, nregs, regs, - eps_via_nodes)) + eps_via_nodes)) return REG_ERROR; /* We know we are going to exit. */ @@ -1385,7 +1385,7 @@ proceed_next_node (const re_match_context_t *mctx, Idx nregs, regmatch_t *regs, } static reg_errcode_t -internal_function +internal_function __attribute_warn_unused_result__ push_fail_stack (struct re_fail_stack_t *fs, Idx str_idx, Idx dest_node, Idx nregs, regmatch_t *regs, re_node_set *eps_via_nodes) { @@ -1432,7 +1432,7 @@ pop_fail_stack (struct re_fail_stack_t *fs, Idx *pidx, Idx nregs, pmatch[i].rm_so == pmatch[i].rm_eo == -1 for 0 < i < nmatch. */ static reg_errcode_t -internal_function +internal_function __attribute_warn_unused_result__ set_regs (const regex_t *preg, const re_match_context_t *mctx, size_t nmatch, regmatch_t *pmatch, bool fl_backtrack) { @@ -1667,7 +1667,7 @@ sift_states_backward (const re_match_context_t *mctx, re_sift_context_t *sctx) if (mctx->state_log[str_idx]) { err = build_sifted_states (mctx, sctx, str_idx, &cur_dest); - if (BE (err != REG_NOERROR, 0)) + if (BE (err != REG_NOERROR, 0)) goto free_return; } @@ -1686,7 +1686,7 @@ sift_states_backward (const re_match_context_t *mctx, re_sift_context_t *sctx) } static reg_errcode_t -internal_function +internal_function __attribute_warn_unused_result__ build_sifted_states (const re_match_context_t *mctx, re_sift_context_t *sctx, Idx str_idx, re_node_set *cur_dest) { @@ -1848,7 +1848,7 @@ update_cur_sifted_state (const re_match_context_t *mctx, } static reg_errcode_t -internal_function +internal_function __attribute_warn_unused_result__ add_epsilon_src_nodes (const re_dfa_t *dfa, re_node_set *dest_nodes, const re_node_set *candidates) { @@ -1863,10 +1863,14 @@ add_epsilon_src_nodes (const re_dfa_t *dfa, re_node_set *dest_nodes, { err = re_node_set_alloc (&state->inveclosure, dest_nodes->nelem); if (BE (err != REG_NOERROR, 0)) - return REG_ESPACE; + return REG_ESPACE; for (i = 0; i < dest_nodes->nelem; i++) - re_node_set_merge (&state->inveclosure, - dfa->inveclosures + dest_nodes->elems[i]); + { + err = re_node_set_merge (&state->inveclosure, + dfa->inveclosures + dest_nodes->elems[i]); + if (BE (err != REG_NOERROR, 0)) + return REG_ESPACE; + } } return re_node_set_add_intersect (dest_nodes, candidates, &state->inveclosure); @@ -1978,7 +1982,7 @@ check_dst_limits_calc_pos_1 (const re_match_context_t *mctx, int boundaries, { struct re_backref_cache_entry *ent = mctx->bkref_ents + bkref_idx; do - { + { Idx dst; int cpos; @@ -2000,9 +2004,9 @@ check_dst_limits_calc_pos_1 (const re_match_context_t *mctx, int boundaries, if (dst == from_node) { if (boundaries & 1) - return -1; + return -1; else /* if (boundaries & 2) */ - return 0; + return 0; } cpos = @@ -2016,7 +2020,7 @@ check_dst_limits_calc_pos_1 (const re_match_context_t *mctx, int boundaries, if (subexp_idx < BITSET_WORD_BITS) ent->eps_reachable_subexps_map &= ~((bitset_word_t) 1 << subexp_idx); - } + } while (ent++->more); } break; @@ -2158,7 +2162,7 @@ check_subexp_limits (const re_dfa_t *dfa, re_node_set *dest_nodes, } static reg_errcode_t -internal_function +internal_function __attribute_warn_unused_result__ sift_states_bkref (const re_match_context_t *mctx, re_sift_context_t *sctx, Idx str_idx, const re_node_set *candidates) { @@ -2241,7 +2245,7 @@ sift_states_bkref (const re_match_context_t *mctx, re_sift_context_t *sctx, re_node_set_remove (&local_sctx.limits, enabled_idx); /* mctx->bkref_ents may have changed, reload the pointer. */ - entry = mctx->bkref_ents + enabled_idx; + entry = mctx->bkref_ents + enabled_idx; } while (enabled_idx++, entry++->more); } @@ -2288,7 +2292,7 @@ sift_states_iter_mb (const re_match_context_t *mctx, re_sift_context_t *sctx, update the destination of STATE_LOG. */ static re_dfastate_t * -internal_function +internal_function __attribute_warn_unused_result__ transit_state (reg_errcode_t *err, re_match_context_t *mctx, re_dfastate_t *state) { @@ -2322,7 +2326,7 @@ transit_state (reg_errcode_t *err, re_match_context_t *mctx, trtable = state->word_trtable; if (BE (trtable != NULL, 1)) - { + { unsigned int context; context = re_string_context_at (&mctx->input, @@ -2368,21 +2372,21 @@ merge_state_with_log (reg_errcode_t *err, re_match_context_t *mctx, unsigned int context; re_node_set next_nodes, *log_nodes, *table_nodes = NULL; /* If (state_log[cur_idx] != 0), it implies that cur_idx is - the destination of a multibyte char/collating element/ - back reference. Then the next state is the union set of - these destinations and the results of the transition table. */ + the destination of a multibyte char/collating element/ + back reference. Then the next state is the union set of + these destinations and the results of the transition table. */ pstate = mctx->state_log[cur_idx]; log_nodes = pstate->entrance_nodes; if (next_state != NULL) - { - table_nodes = next_state->entrance_nodes; - *err = re_node_set_init_union (&next_nodes, table_nodes, + { + table_nodes = next_state->entrance_nodes; + *err = re_node_set_init_union (&next_nodes, table_nodes, log_nodes); - if (BE (*err != REG_NOERROR, 0)) + if (BE (*err != REG_NOERROR, 0)) return NULL; - } + } else - next_nodes = *log_nodes; + next_nodes = *log_nodes; /* Note: We already add the nodes of the initial state, then we don't need to add them here. */ @@ -2390,12 +2394,12 @@ merge_state_with_log (reg_errcode_t *err, re_match_context_t *mctx, re_string_cur_idx (&mctx->input) - 1, mctx->eflags); next_state = mctx->state_log[cur_idx] - = re_acquire_state_context (err, dfa, &next_nodes, context); + = re_acquire_state_context (err, dfa, &next_nodes, context); /* We don't need to check errors here, since the return value of - this function is next_state and ERR is already set. */ + this function is next_state and ERR is already set. */ if (table_nodes != NULL) - re_node_set_free (&next_nodes); + re_node_set_free (&next_nodes); } if (BE (dfa->nbackref, 0) && next_state != NULL) @@ -2436,9 +2440,9 @@ find_recover_state (reg_errcode_t *err, re_match_context_t *mctx) do { - if (++cur_str_idx > max) - return NULL; - re_string_skip_bytes (&mctx->input, 1); + if (++cur_str_idx > max) + return NULL; + re_string_skip_bytes (&mctx->input, 1); } while (mctx->state_log[cur_str_idx] == NULL); @@ -2546,7 +2550,7 @@ transit_state_mb (re_match_context_t *mctx, re_dfastate_t *pstate) re_dfastate_t *dest_state; if (!dfa->nodes[cur_node_idx].accept_mb) - continue; + continue; if (dfa->nodes[cur_node_idx].constraint) { @@ -2714,7 +2718,7 @@ transit_state_bkref (re_match_context_t *mctx, const re_node_set *nodes) delay these checking for prune_impossible_nodes(). */ static reg_errcode_t -internal_function +internal_function __attribute_warn_unused_result__ get_subexp (re_match_context_t *mctx, Idx bkref_node, Idx bkref_str_idx) { const re_dfa_t *const dfa = mctx->dfa; @@ -2727,7 +2731,7 @@ get_subexp (re_match_context_t *mctx, Idx bkref_node, Idx bkref_str_idx) const struct re_backref_cache_entry *entry = mctx->bkref_ents + cache_idx; do - if (entry->node == bkref_node) + if (entry->node == bkref_node) return REG_NOERROR; /* We already checked it. */ while (entry++->more); } @@ -2915,7 +2919,7 @@ find_subexp_node (const re_dfa_t *dfa, const re_node_set *nodes, Return REG_NOERROR if it can arrive, or REG_NOMATCH otherwise. */ static reg_errcode_t -internal_function +internal_function __attribute_warn_unused_result__ check_arrival (re_match_context_t *mctx, state_array_t *path, Idx top_node, Idx top_str, Idx last_node, Idx last_str, int type) { @@ -3077,7 +3081,7 @@ check_arrival (re_match_context_t *mctx, state_array_t *path, Idx top_node, Can't we unify them? */ static reg_errcode_t -internal_function +internal_function __attribute_warn_unused_result__ check_arrival_add_next_nodes (re_match_context_t *mctx, Idx str_idx, re_node_set *cur_nodes, re_node_set *next_nodes) { @@ -3211,7 +3215,7 @@ check_arrival_expand_ecl (const re_dfa_t *dfa, re_node_set *cur_nodes, problematic append it to DST_NODES. */ static reg_errcode_t -internal_function +internal_function __attribute_warn_unused_result__ check_arrival_expand_ecl_sub (const re_dfa_t *dfa, re_node_set *dst_nodes, Idx target, Idx ex_subexp, int type) { @@ -3256,7 +3260,7 @@ check_arrival_expand_ecl_sub (const re_dfa_t *dfa, re_node_set *dst_nodes, in MCTX->BKREF_ENTS. */ static reg_errcode_t -internal_function +internal_function __attribute_warn_unused_result__ expand_bkref_cache (re_match_context_t *mctx, re_node_set *cur_nodes, Idx cur_str, Idx subexp_num, int type) { @@ -3622,7 +3626,7 @@ group_nodes_into_DFAstates (const re_dfa_t *dfa, const re_dfastate_t *state, } #ifdef RE_ENABLE_I18N else if (type == OP_UTF8_PERIOD) - { + { if (ASCII_CHARS % BITSET_WORD_BITS == 0) memset (accepts, -1, ASCII_CHARS / CHAR_BIT); else @@ -3631,7 +3635,7 @@ group_nodes_into_DFAstates (const re_dfa_t *dfa, const re_dfastate_t *state, bitset_clear (accepts, '\n'); if (dfa->syntax & RE_DOT_NOT_NULL) bitset_clear (accepts, '\0'); - } + } #endif else continue; @@ -3836,7 +3840,7 @@ check_node_accept_bytes (const re_dfa_t *dfa, Idx node_idx, if (node->type == OP_PERIOD) { if (char_len <= 1) - return 0; + return 0; /* FIXME: I don't think this if is needed, as both '\n' and '\0' are char_len == 1. */ /* '.' accepts any one character except the following two cases. */ @@ -3949,15 +3953,20 @@ check_node_accept_bytes (const re_dfa_t *dfa, Idx node_idx, _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAMB); indirect = (const int32_t *) _NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTMB); - idx = findidx (&cp); + int32_t idx = findidx (&cp); if (idx > 0) for (i = 0; i < cset->nequiv_classes; ++i) { int32_t equiv_class_idx = cset->equiv_classes[i]; - size_t weight_len = weights[idx]; - if (weight_len == weights[equiv_class_idx]) + size_t weight_len = weights[idx & 0xffffff]; + if (weight_len == weights[equiv_class_idx & 0xffffff] + && (idx >> 24) == (equiv_class_idx >> 24)) { Idx cnt = 0; + + idx &= 0xffffff; + equiv_class_idx &= 0xffffff; + while (cnt <= weight_len && (weights[equiv_class_idx + 1 + cnt] == weights[idx + 1 + cnt])) @@ -4123,7 +4132,7 @@ check_node_accept (const re_match_context_t *mctx, const re_token_t *node, /* Extend the buffers, if the buffers have run out. */ static reg_errcode_t -internal_function +internal_function __attribute_warn_unused_result__ extend_buffers (re_match_context_t *mctx) { reg_errcode_t ret; @@ -4186,7 +4195,7 @@ extend_buffers (re_match_context_t *mctx) /* Initialize MCTX. */ static reg_errcode_t -internal_function +internal_function __attribute_warn_unused_result__ match_ctx_init (re_match_context_t *mctx, int eflags, Idx n) { mctx->eflags = eflags; @@ -4266,7 +4275,7 @@ match_ctx_free (re_match_context_t *mctx) */ static reg_errcode_t -internal_function +internal_function __attribute_warn_unused_result__ match_ctx_add_entry (re_match_context_t *mctx, Idx node, Idx str_idx, Idx from, Idx to) { @@ -4338,7 +4347,7 @@ search_cur_bkref_entry (const re_match_context_t *mctx, Idx str_idx) at STR_IDX. */ static reg_errcode_t -internal_function +internal_function __attribute_warn_unused_result__ match_ctx_add_subtop (re_match_context_t *mctx, Idx node, Idx str_idx) { #ifdef DEBUG diff --git a/lib/posix_wrap/assert.h b/lib/posix_wrap/assert.h new file mode 100644 index 000000000..94cfdd543 --- /dev/null +++ b/lib/posix_wrap/assert.h @@ -0,0 +1,33 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009, 2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_POSIX_ASSERT_H +#define GRUB_POSIX_ASSERT_H 1 + +#include + +#define assert(x) assert_real(__FILE__, __LINE__, x) + +static inline void +assert_real (const char *file, int line, int cond) +{ + if (!cond) + grub_fatal ("Assertion failed at %s:%d\n", file, line); +} + +#endif diff --git a/include/grub/gnulib-wrap.h b/lib/posix_wrap/ctype.h similarity index 51% rename from include/grub/gnulib-wrap.h rename to lib/posix_wrap/ctype.h index e3f7b23b0..2dc3e53e9 100644 --- a/include/grub/gnulib-wrap.h +++ b/lib/posix_wrap/ctype.h @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2009 Free Software Foundation, Inc. + * Copyright (C) 2009, 2010 Free Software Foundation, Inc. * * GRUB is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,48 +16,11 @@ * along with GRUB. If not, see . */ -#ifndef GRUB_GNULIB_WRAP_H -#define GRUB_GNULIB_WRAP_H 1 +#ifndef GRUB_POSIX_CTYPE_H +#define GRUB_POSIX_CTYPE_H 1 -#include #include -#define HAVE_ISBLANK 0 -#define HAVE_LIBINTL_H 0 -#define HAVE_LOCALE_H 0 -#define __STRICT_ANSI__ 0 -#define DEBUG 0 -#define _Restrict_ __restrict -#define _Restrict_arr_ __restrict - -typedef grub_size_t size_t; -typedef int bool; -static const bool true = 1; -static const bool false = 0; - -#define assert(x) assert_real(__FILE__, __LINE__, x) - -static inline void -assert_real (const char *file, int line, int cond) -{ - if (!cond) - grub_fatal ("Assertion failed at %s:%d\n", file, line); -} - -static inline char * -locale_charset (void) -{ - return "UTF-8"; -} - -#define MB_CUR_MAX 6 - -static inline void * -realloc (void *ptr, grub_size_t size) -{ - return grub_realloc (ptr, size); -} - static inline int toupper (int c) { @@ -137,59 +100,4 @@ tolower (int c) return grub_tolower (c); } -static inline grub_size_t -strlen (const char *s) -{ - return grub_strlen (s); -} - -static inline int -strcmp (const char *s1, const char *s2) -{ - return grub_strcmp (s1, s2); -} - -static inline void -abort (void) -{ - grub_abort (); -} - -static inline void -free (void *ptr) -{ - grub_free (ptr); -} - -static inline void * -malloc (grub_size_t size) -{ - return grub_malloc (size); -} - -static inline void * -calloc (grub_size_t size, grub_size_t nelem) -{ - return grub_zalloc (size * nelem); -} - -static inline char *strncpy (char *dest, const char *src, int c) -{ - return grub_strncpy (dest, src, c); -} - - -#define ULONG_MAX GRUB_ULONG_MAX -#define UCHAR_MAX 0xff - -/* UCS-4. */ -typedef grub_uint32_t wchar_t; - -#undef __libc_lock_init -#define __libc_lock_init(x) -#undef __libc_lock_lock -#define __libc_lock_lock(x) -#undef __libc_lock_unlock -#define __libc_lock_unlock(x) - #endif diff --git a/lib/posix_wrap/langinfo.h b/lib/posix_wrap/langinfo.h new file mode 100644 index 000000000..14833c0b8 --- /dev/null +++ b/lib/posix_wrap/langinfo.h @@ -0,0 +1,38 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009, 2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_POSIX_LANGINFO_H +#define GRUB_POSIX_LANGINFO_H 1 + +#include + +typedef enum { CODESET } nl_item; + +static inline char * +nl_langinfo (nl_item item) +{ + switch (item) + { + case CODESET: + return locale_charset (); + default: + return ""; + } +} + +#endif diff --git a/lib/posix_wrap/limits.h b/lib/posix_wrap/limits.h new file mode 100644 index 000000000..e69de29bb diff --git a/lib/posix_wrap/localcharset.h b/lib/posix_wrap/localcharset.h new file mode 100644 index 000000000..92eb815ec --- /dev/null +++ b/lib/posix_wrap/localcharset.h @@ -0,0 +1,28 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009, 2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_POSIX_LOCALCHARSET_H +#define GRUB_POSIX_LOCALCHARSET_H 1 + +static inline char * +locale_charset (void) +{ + return "UTF-8"; +} + +#endif diff --git a/lib/posix_wrap/stdint.h b/lib/posix_wrap/stdint.h new file mode 100644 index 000000000..a12c43b15 --- /dev/null +++ b/lib/posix_wrap/stdint.h @@ -0,0 +1 @@ +#include diff --git a/lib/posix_wrap/stdio.h b/lib/posix_wrap/stdio.h new file mode 100644 index 000000000..31f6d6c60 --- /dev/null +++ b/lib/posix_wrap/stdio.h @@ -0,0 +1,24 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009, 2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_POSIX_STDIO_H +#define GRUB_POSIX_STDIO_H 1 + +#include + +#endif diff --git a/lib/posix_wrap/stdlib.h b/lib/posix_wrap/stdlib.h new file mode 100644 index 000000000..5ef6159ef --- /dev/null +++ b/lib/posix_wrap/stdlib.h @@ -0,0 +1,56 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009, 2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_POSIX_STDLIB_H +#define GRUB_POSIX_STDLIB_H 1 + +#include + +static inline void +free (void *ptr) +{ + grub_free (ptr); +} + +static inline void * +malloc (grub_size_t size) +{ + return grub_malloc (size); +} + +static inline void * +calloc (grub_size_t size, grub_size_t nelem) +{ + return grub_zalloc (size * nelem); +} + +static inline void * +realloc (void *ptr, grub_size_t size) +{ + return grub_realloc (ptr, size); +} + +static inline void +abort (void) +{ + grub_abort (); +} + +#define MB_CUR_MAX 6 + +#endif diff --git a/lib/posix_wrap/string.h b/lib/posix_wrap/string.h new file mode 100644 index 000000000..7bb6f1e6f --- /dev/null +++ b/lib/posix_wrap/string.h @@ -0,0 +1,40 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009, 2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_POSIX_STRING_H +#define GRUB_POSIX_STRING_H 1 + +static inline grub_size_t +strlen (const char *s) +{ + return grub_strlen (s); +} + +static inline int +strcmp (const char *s1, const char *s2) +{ + return grub_strcmp (s1, s2); +} + +static inline int +strcasecmp (const char *s1, const char *s2) +{ + return grub_strcasecmp (s1, s2); +} + +#endif diff --git a/lib/posix_wrap/sys/types.h b/lib/posix_wrap/sys/types.h new file mode 100644 index 000000000..ce3794087 --- /dev/null +++ b/lib/posix_wrap/sys/types.h @@ -0,0 +1,32 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009, 2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_POSIX_SYS_TYPES_H +#define GRUB_POSIX_SYS_TYPES_H 1 + +#include + +typedef grub_size_t size_t; +typedef int bool; +static const bool true = 1; +static const bool false = 0; + +#define ULONG_MAX GRUB_ULONG_MAX +#define UCHAR_MAX 0xff + +#endif diff --git a/lib/posix_wrap/wchar.h b/lib/posix_wrap/wchar.h new file mode 100644 index 000000000..fd56fd332 --- /dev/null +++ b/lib/posix_wrap/wchar.h @@ -0,0 +1,25 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009, 2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_POSIX_WCHAR_H +#define GRUB_POSIX_WCHAR_H 1 + +/* UCS-4. */ +typedef grub_uint32_t wchar_t; + +#endif diff --git a/lib/posix_wrap/wctype.h b/lib/posix_wrap/wctype.h new file mode 100644 index 000000000..e69de29bb From 74f34747b12fc8c451a78bda5c85936f2567af2e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 28 Mar 2010 22:19:06 +0200 Subject: [PATCH 518/738] Fix path to regex.h --- commands/regexp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commands/regexp.c b/commands/regexp.c index 6ceb78f0f..910bb9082 100644 --- a/commands/regexp.c +++ b/commands/regexp.c @@ -21,7 +21,7 @@ #include #include #include -#include +#include static grub_err_t grub_cmd_regexp (grub_command_t cmd __attribute__ ((unused)), From 66bf23d2e7f78c18f14a416a9754f814c97c39c5 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 28 Mar 2010 22:20:32 +0200 Subject: [PATCH 519/738] Use posix wrappers in lexer --- conf/common.rmk | 4 +--- lib/posix_wrap/stdio.h | 5 +++++ script/yylex.l | 22 +++++++--------------- 3 files changed, 13 insertions(+), 18 deletions(-) diff --git a/conf/common.rmk b/conf/common.rmk index b9ed37d26..87ae1e202 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -98,8 +98,6 @@ grub_bin2h_SOURCES = gnulib/progname.c util/bin2h.c # For the lexer. grub_script.yy.c grub_script.yy.h: script/yylex.l $(LEX) -o grub_script.yy.c --header-file=grub_script.yy.h $(srcdir)/script/yylex.l - sed -i 's/^#include.*\(\|\|\|\|\)//g' grub_script.yy.h - sed -i 's/^#include.*\(\|\|\|\|\)//g' grub_script.yy.c DISTCLEANFILES += grub_script.yy.c grub_script.yy.h # For grub-script-check. @@ -655,7 +653,7 @@ normal_mod_LDFLAGS = $(COMMON_LDFLAGS) # For sh.mod. sh_mod_SOURCES = script/main.c script/script.c script/execute.c \ script/function.c script/lexer.c grub_script.tab.c grub_script.yy.c -sh_mod_CFLAGS = $(COMMON_CFLAGS) +sh_mod_CFLAGS = $(COMMON_CFLAGS) $(POSIX_CFLAGS) sh_mod_LDFLAGS = $(COMMON_LDFLAGS) ifneq (, $(FONT_SOURCE)) diff --git a/lib/posix_wrap/stdio.h b/lib/posix_wrap/stdio.h index 31f6d6c60..701fceaa4 100644 --- a/lib/posix_wrap/stdio.h +++ b/lib/posix_wrap/stdio.h @@ -20,5 +20,10 @@ #define GRUB_POSIX_STDIO_H 1 #include +#include + +typedef struct grub_file FILE; + +#define EOF -1 #endif diff --git a/script/yylex.l b/script/yylex.l index db276ef61..4d7c66448 100644 --- a/script/yylex.l +++ b/script/yylex.l @@ -68,31 +68,23 @@ static void copy_string (struct grub_parser_param *, const char *, %top{ +#include + +typedef size_t yy_size_t; +#define YY_TYPEDEF_YY_SIZE_T 1 + /* * Some flex hacks for -nostdinc; XXX We need to fix these when libc * support becomes availble in GRUB. */ -#include - -typedef grub_size_t size_t; -typedef grub_size_t yy_size_t; -#define YY_TYPEDEF_YY_SIZE_T 1 - -#define FILE void +#ifndef GRUB_UTIL #define stdin 0 #define stdout 0 -#define EOF 0 - -#define errno grub_errno -#define EINVAL GRUB_ERR_BAD_NUMBER -#define ENOMEM GRUB_ERR_OUT_OF_MEMORY - -#define strlen grub_strlen -#define memset grub_memset #define fprintf(...) 0 #define exit(...) +#endif #pragma GCC diagnostic warning "-Wunused-variable" #pragma GCC diagnostic warning "-Wunused-function" From af09641e2b01a63316695653bea80902033e37dd Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 30 Mar 2010 11:18:29 +0200 Subject: [PATCH 520/738] * loader/i386/multiboot_mbi2.c (retrieve_video_parameters): Fix compilation on coreboot and qemu --- ChangeLog | 5 +++++ loader/i386/multiboot_mbi2.c | 26 ++++++++++++++++---------- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index aba023c7b..5367493a2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-03-30 Vladimir Serbinenko + + * loader/i386/multiboot_mbi2.c (retrieve_video_parameters): Fix + compilation on coreboot and qemu + 2010-03-28 Vladimir Serbinenko * include/multiboot2.h: Resync with spec. diff --git a/loader/i386/multiboot_mbi2.c b/loader/i386/multiboot_mbi2.c index 436cd0901..1910d656e 100644 --- a/loader/i386/multiboot_mbi2.c +++ b/loader/i386/multiboot_mbi2.c @@ -34,13 +34,9 @@ #if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_QEMU) #include -#define DEFAULT_VIDEO_MODE "text" #define HAS_VGA_TEXT 1 -#define HAS_VBE 1 #else -#define DEFAULT_VIDEO_MODE "auto" #define HAS_VGA_TEXT 0 -#define HAS_VBE 0 #endif struct module @@ -343,14 +339,20 @@ retrieve_video_parameters (grub_uint8_t **ptrorig) if (driv_id == GRUB_VIDEO_DRIVER_NONE) { struct grub_vbe_mode_info_block vbe_mode_info; - grub_vbe_status_t status; grub_uint32_t vbe_mode; - void *scratch = (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR; - status = grub_vbe_bios_get_mode (scratch); - vbe_mode = *(grub_uint32_t *) scratch; - if (status != GRUB_VBE_STATUS_OK) - return GRUB_ERR_NONE; +#if defined (GRUB_MACHINE_PCBIOS) + { + grub_vbe_status_t status; + void *scratch = (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR; + status = grub_vbe_bios_get_mode (scratch); + vbe_mode = *(grub_uint32_t *) scratch; + if (status != GRUB_VBE_STATUS_OK) + return GRUB_ERR_NONE; + } +#else + vbe_mode = 3; +#endif /* get_mode_info isn't available for mode 3. */ if (vbe_mode == 3) @@ -361,14 +363,18 @@ retrieve_video_parameters (grub_uint8_t **ptrorig) vbe_mode_info.x_resolution = 80; vbe_mode_info.y_resolution = 25; } +#if defined (GRUB_MACHINE_PCBIOS) else { + grub_vbe_status_t status; + void *scratch = (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR; status = grub_vbe_bios_get_mode_info (vbe_mode, scratch); if (status != GRUB_VBE_STATUS_OK) return GRUB_ERR_NONE; grub_memcpy (&vbe_mode_info, scratch, sizeof (struct grub_vbe_mode_info_block)); } +#endif if (vbe_mode_info.memory_model == GRUB_VBE_MEMORY_MODEL_TEXT) { From f9fd65df54d5f114a0f33ac30f49c6b2226ded30 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 31 Mar 2010 22:01:37 +0200 Subject: [PATCH 521/738] * kern/ieee1275/openfw.c (grub_children_iterate): Skip device itself if returned by firmware. --- ChangeLog | 5 +++++ kern/ieee1275/openfw.c | 6 ++++++ 2 files changed, 11 insertions(+) diff --git a/ChangeLog b/ChangeLog index 5367493a2..d05dd5a7d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-03-31 Vladimir Serbinenko + + * kern/ieee1275/openfw.c (grub_children_iterate): Skip device itself if + returned by firmware. + 2010-03-30 Vladimir Serbinenko * loader/i386/multiboot_mbi2.c (retrieve_video_parameters): Fix diff --git a/kern/ieee1275/openfw.c b/kern/ieee1275/openfw.c index ae1eb5522..cf9e1a870 100644 --- a/kern/ieee1275/openfw.c +++ b/kern/ieee1275/openfw.c @@ -73,10 +73,16 @@ grub_children_iterate (char *devpath, IEEE1275_MAX_PROP_LEN, &actual)) childtype[0] = 0; + if (dev == child) + continue; + if (grub_ieee1275_package_to_path (child, childpath, IEEE1275_MAX_PATH_LEN, &actual)) continue; + if (grub_strcmp (devpath, childpath) == 0) + continue; + if (grub_ieee1275_get_property (child, "name", childname, IEEE1275_MAX_PROP_LEN, &actual)) continue; From 495442ed025eb218077a5d86777894ffefe46c48 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 31 Mar 2010 22:03:48 +0200 Subject: [PATCH 522/738] * kern/device.c (grub_device_iterate): Clear errors after failed opening device. --- ChangeLog | 5 +++++ kern/device.c | 5 ++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index d05dd5a7d..d35e1ca22 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-03-31 Vladimir Serbinenko + + * kern/device.c (grub_device_iterate): Clear errors after failed + opening device. + 2010-03-31 Vladimir Serbinenko * kern/ieee1275/openfw.c (grub_children_iterate): Skip device itself if diff --git a/kern/device.c b/kern/device.c index cd019fdaf..4273fedfe 100644 --- a/kern/device.c +++ b/kern/device.c @@ -98,7 +98,10 @@ grub_device_iterate (int (*hook) (const char *name)) dev = grub_device_open (disk_name); if (! dev) - return 0; + { + grub_errno = GRUB_ERR_NONE; + return 0; + } if (dev->disk && dev->disk->has_partitions) { From d5631db0f2763746d35bd6ca895610b133f0841d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 2 Apr 2010 21:12:20 +0200 Subject: [PATCH 523/738] grub-mkconfig multiple terminal support. * util/grub-mkconfig.in: Handle multiple terminals correctly. * util/grub.d/00_header.in: Likewise. --- ChangeLog.mtcfg | 6 ++ util/grub-mkconfig.in | 115 ++++++++++++++++++++++----------------- util/grub.d/00_header.in | 76 ++++++++++++++------------ 3 files changed, 110 insertions(+), 87 deletions(-) create mode 100644 ChangeLog.mtcfg diff --git a/ChangeLog.mtcfg b/ChangeLog.mtcfg new file mode 100644 index 000000000..2f246c26a --- /dev/null +++ b/ChangeLog.mtcfg @@ -0,0 +1,6 @@ +2010-04-02 Vladimir Serbinenko + + grub-mkconfig multiple terminal support. + + * util/grub-mkconfig.in: Handle multiple terminals correctly. + * util/grub.d/00_header.in: Likewise. diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in index daa110be7..94cd2e199 100644 --- a/util/grub-mkconfig.in +++ b/util/grub-mkconfig.in @@ -140,60 +140,73 @@ if [ "x${GRUB_TERMINAL}" != "x" ] ; then GRUB_TERMINAL_OUTPUT="${GRUB_TERMINAL}" fi -case x${GRUB_TERMINAL_OUTPUT} in - x | xgfxterm) - # If this platform supports gfxterm, try to use it. - if test -e ${grub_prefix}/gfxterm.mod ; then - # FIXME: this should do something smarter than just loading first - # video backend. - GRUB_VIDEO_BACKEND=$(head -n 1 ${grub_prefix}/video.lst || true) - if [ -n "${GRUB_VIDEO_BACKEND}" ] ; then - GRUB_TERMINAL_OUTPUT=gfxterm - elif [ "${GRUB_TERMINAL_OUTPUT}" = "gfxterm" ] ; then - echo "No suitable backend could be found for gfxterm." >&2 ; exit 1 - fi - fi - ;; - xconsole | xserial | xofconsole) ;; - *) echo "Invalid output terminal \"${GRUB_TERMINAL_OUTPUT}\"" >&2 ; exit 1 ;; -esac +termoutdefault=0 +if [ "x${GRUB_TERMINAL_OUTPUT}" == x ]; then + GRUB_TERMINAL_OUTPUT=gfxterm; + termoutdefault=1; +fi -# check for terminals that require fonts -case ${GRUB_TERMINAL_OUTPUT} in - gfxterm) - if [ -n "$GRUB_FONT" ] ; then - if is_path_readable_by_grub ${GRUB_FONT} > /dev/null ; then - GRUB_FONT_PATH=${GRUB_FONT} - else - echo "No such font or not readable by grub: ${GRUB_FONT}" >&2 - exit 1 +for x in ${GRUB_TERMINAL_OUTPUT}; do + if [ x${x} == xgfxterm ]; then + # If this platform supports gfxterm, try to use it. + if ! test -e ${grub_prefix}/gfxterm.mod ; then + if [ "x$termoutdefault" != "x1" ]; then + echo "gfxterm isn't available on your platform" >&2 ; exit 1 + fi + GRUB_TERMINAL_OUTPUT= + break; + fi + # FIXME: this should do something smarter than just loading first + # video backend. + GRUB_VIDEO_BACKEND=$(head -n 1 ${grub_prefix}/video.lst || true) + if [ -z "${GRUB_VIDEO_BACKEND}" ] ; then + if [ "x$termoutdefault" != "x1" ]; then + echo "No suitable backend could be found for gfxterm." >&2 ; exit 1 + fi + GRUB_TERMINAL_OUTPUT= + fi + if [ -n "$GRUB_FONT" ] ; then + if is_path_readable_by_grub ${GRUB_FONT} > /dev/null ; then + GRUB_FONT_PATH=${GRUB_FONT} + else + echo "No such font or not readable by grub: ${GRUB_FONT}" >&2 + exit 1 + fi + else + for dir in ${pkgdatadir} /boot/grub /usr/share/grub ; do + for basename in unicode unifont ascii; do + path="${dir}/${basename}.pf2" + if is_path_readable_by_grub ${path} > /dev/null ; then + GRUB_FONT_PATH=${path} + else + continue + fi + if [ "${basename}" = "ascii" ] ; then + # make sure all our children behave in conformance with ascii.. + export LANG=C + fi + break 2 + done + done + fi + if [ -z "${GRUB_FONT_PATH}" ] ; then + if [ "x$termoutdefault" != "x1" ]; then + echo "No font for gfxterm found." >&2 ; exit 1 + fi + GRUB_TERMINAL_OUTPUT= fi - else - for dir in ${pkgdatadir} /boot/grub /usr/share/grub ; do - for basename in unicode unifont ascii; do - path="${dir}/${basename}.pf2" - if is_path_readable_by_grub ${path} > /dev/null ; then - GRUB_FONT_PATH=${path} - else - continue - fi - if [ "${basename}" = "ascii" ] ; then - # make sure all our children behave in conformance with ascii.. - export LANG=C - fi - break 2 - done - done fi - if [ -z "${GRUB_FONT_PATH}" ] ; then - # fallback to the native terminal for this platform - unset GRUB_TERMINAL_OUTPUT - fi - ;; - *) - # make sure all our children behave in conformance with ascii.. - export LANG=C -esac +done + +for x in ${GRUB_TERMINAL_OUTPUT}; do + case "x${x}" in + xgfxterm) ;; + xconsole | xserial | xofconsole) + # make sure all our children behave in conformance with ascii.. + export LANG=C;; + *) echo "Invalid output terminal \"${GRUB_TERMINAL_OUTPUT}\"" >&2 ; exit 1 ;; + esac +done # These are defined in this script, export them here so that user can # override them. diff --git a/util/grub.d/00_header.in b/util/grub.d/00_header.in index c86f7b867..81f7a213a 100644 --- a/util/grub.d/00_header.in +++ b/util/grub.d/00_header.in @@ -59,19 +59,52 @@ function savedefault { } EOF -case ${GRUB_TERMINAL_INPUT}:${GRUB_TERMINAL_OUTPUT} in - serial:* | *:serial) +serial=0; +gfxterm=0; +for x in ${GRUB_TERMINAL_INPUT} ${GRUB_TERMINAL_OUTPUT}; do + if [ xserial = "x$x" ]; then + serial=1; + fi + if [ xgfxterm = "x$x" ]; then + gfxterm=1; + fi +done + +if [ "x$serial" = x1 ]; then if ! test -e ${grub_prefix}/serial.mod ; then - echo "Serial terminal not available on this platform." >&2 ; exit 1 + echo "Serial terminal not available on this platform." >&2 ; exit 1 fi if [ "x${GRUB_SERIAL_COMMAND}" = "x" ] ; then - grub_warn "Requested serial terminal but GRUB_SERIAL_COMMAND is unspecified. Default parameters will be used." - GRUB_SERIAL_COMMAND=serial + grub_warn "Requested serial terminal but GRUB_SERIAL_COMMAND is unspecified. Default parameters will be used." + GRUB_SERIAL_COMMAND=serial fi echo "${GRUB_SERIAL_COMMAND}" - ;; -esac +fi + +if [ "x$gfxterm" = x1 ]; then + # Make the font accessible + prepare_grub_to_access_device `${grub_probe} --target=device ${GRUB_FONT_PATH}` + + cat << EOF +if loadfont `make_system_path_relative_to_its_root ${GRUB_FONT_PATH}` ; then + set gfxmode=${GRUB_GFXMODE} + insmod gfxterm + insmod ${GRUB_VIDEO_BACKEND} +EOF + if [ x$GRUB_THEME != x ] && [ -f $GRUB_THEME ] \ + && is_path_readable_by_grub $GRUB_THEME; then + echo "Found theme: $GRUB_THEME" >&2 + prepare_grub_to_access_device `${grub_probe} --target=device $GRUB_THEME` | sed -e "s/^/ /" + cat << EOF + insmod gfxmenu + set theme=(\$root)`make_system_path_relative_to_its_root $GRUB_THEME` +EOF + fi + cat << EOF +fi +EOF +fi case x${GRUB_TERMINAL_INPUT} in x) @@ -89,35 +122,6 @@ EOF esac case x${GRUB_TERMINAL_OUTPUT} in - xgfxterm) - # Make the font accessible - prepare_grub_to_access_device `${grub_probe} --target=device ${GRUB_FONT_PATH}` - - cat << EOF -if loadfont `make_system_path_relative_to_its_root ${GRUB_FONT_PATH}` ; then - set gfxmode=${GRUB_GFXMODE} - insmod gfxterm - insmod ${GRUB_VIDEO_BACKEND} - if terminal_output gfxterm ; then true ; else - # For backward compatibility with versions of terminal.mod that don't - # understand terminal_output - terminal gfxterm - fi -EOF -if [ x$GRUB_THEME != x ] && [ -f $GRUB_THEME ] \ - && is_path_readable_by_grub $GRUB_THEME; then - echo "Found theme: $GRUB_THEME" >&2 - prepare_grub_to_access_device `${grub_probe} --target=device $GRUB_THEME` | sed -e "s/^/ /" - cat << EOF - insmod gfxmenu - set theme=(\$root)`make_system_path_relative_to_its_root $GRUB_THEME` - set menuviewer=gfxmenu -EOF -fi - cat << EOF -fi -EOF - ;; x) # Just use the native terminal ;; From 47674667e367a23bdda0de03ac81ccd0c62fa9ea Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 3 Apr 2010 00:45:01 +0200 Subject: [PATCH 524/738] Import gnulib argp module. * gnulib/argp-ba.c: New file. * gnulib/argp-eexst.c: Likewise. * gnulib/argp-fmtstream.c: Likewise. * gnulib/argp-fmtstream.h: Likewise. * gnulib/argp-fs-xinl.c: Likewise. * gnulib/argp-help.c: Likewise. * gnulib/argp-namefrob.h: Likewise. * gnulib/argp-parse.c: Likewise. * gnulib/argp-pin.c: Likewise. * gnulib/argp-pv.c: Likewise. * gnulib/argp-pvh.c: Likewise. * gnulib/argp-version-etc.c: Likewise. * gnulib/argp-version-etc.h: Likewise. * gnulib/argp-xinl.c: Likewise. * gnulib/argp.h: Likewise. --- ChangeLog | 20 + gnulib/argp-ba.c | 34 + gnulib/argp-eexst.c | 30 + gnulib/argp-fmtstream.c | 435 +++++++++ gnulib/argp-fmtstream.h | 354 +++++++ gnulib/argp-fs-xinl.c | 42 + gnulib/argp-help.c | 1951 +++++++++++++++++++++++++++++++++++++ gnulib/argp-namefrob.h | 157 +++ gnulib/argp-parse.c | 952 ++++++++++++++++++ gnulib/argp-pin.c | 27 + gnulib/argp-pv.c | 34 + gnulib/argp-pvh.c | 31 + gnulib/argp-version-etc.c | 38 + gnulib/argp-version-etc.h | 40 + gnulib/argp-xinl.c | 42 + gnulib/argp.h | 645 ++++++++++++ 16 files changed, 4832 insertions(+) create mode 100644 gnulib/argp-ba.c create mode 100644 gnulib/argp-eexst.c create mode 100644 gnulib/argp-fmtstream.c create mode 100644 gnulib/argp-fmtstream.h create mode 100644 gnulib/argp-fs-xinl.c create mode 100644 gnulib/argp-help.c create mode 100644 gnulib/argp-namefrob.h create mode 100644 gnulib/argp-parse.c create mode 100644 gnulib/argp-pin.c create mode 100644 gnulib/argp-pv.c create mode 100644 gnulib/argp-pvh.c create mode 100644 gnulib/argp-version-etc.c create mode 100644 gnulib/argp-version-etc.h create mode 100644 gnulib/argp-xinl.c create mode 100644 gnulib/argp.h diff --git a/ChangeLog b/ChangeLog index d35e1ca22..86eaedb83 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,23 @@ +2010-04-02 Vladimir Serbinenko + + Import gnulib argp module. + + * gnulib/argp-ba.c: New file. + * gnulib/argp-eexst.c: Likewise. + * gnulib/argp-fmtstream.c: Likewise. + * gnulib/argp-fmtstream.h: Likewise. + * gnulib/argp-fs-xinl.c: Likewise. + * gnulib/argp-help.c: Likewise. + * gnulib/argp-namefrob.h: Likewise. + * gnulib/argp-parse.c: Likewise. + * gnulib/argp-pin.c: Likewise. + * gnulib/argp-pv.c: Likewise. + * gnulib/argp-pvh.c: Likewise. + * gnulib/argp-version-etc.c: Likewise. + * gnulib/argp-version-etc.h: Likewise. + * gnulib/argp-xinl.c: Likewise. + * gnulib/argp.h: Likewise. + 2010-03-31 Vladimir Serbinenko * kern/device.c (grub_device_iterate): Clear errors after failed diff --git a/gnulib/argp-ba.c b/gnulib/argp-ba.c new file mode 100644 index 000000000..95feabb86 --- /dev/null +++ b/gnulib/argp-ba.c @@ -0,0 +1,34 @@ +/* Default definition for ARGP_PROGRAM_BUG_ADDRESS. + Copyright (C) 1996, 1997, 1999, 2009, 2010 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Written by Miles Bader . + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* If set by the user program, it should point to string that is the + bug-reporting address for the program. It will be printed by argp_help if + the ARGP_HELP_BUG_ADDR flag is set (as it is by various standard help + messages), embedded in a sentence that says something like `Report bugs to + ADDR.'. */ +const char *argp_program_bug_address +/* This variable should be zero-initialized. On most systems, putting it into + BSS is sufficient. Not so on MacOS X 10.3 and 10.4, see + + . */ +#if defined __ELF__ + /* On ELF systems, variables in BSS behave well. */ +#else + = (const char *) 0 +#endif + ; diff --git a/gnulib/argp-eexst.c b/gnulib/argp-eexst.c new file mode 100644 index 000000000..115a8cd5d --- /dev/null +++ b/gnulib/argp-eexst.c @@ -0,0 +1,30 @@ +/* Default definition for ARGP_ERR_EXIT_STATUS + Copyright (C) 1997, 2009, 2010 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Written by Miles Bader . + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include "argp.h" + +/* The exit status that argp will use when exiting due to a parsing error. + If not defined or set by the user program, this defaults to EX_USAGE from + . */ +error_t argp_err_exit_status = EX_USAGE; diff --git a/gnulib/argp-fmtstream.c b/gnulib/argp-fmtstream.c new file mode 100644 index 000000000..70bbebc21 --- /dev/null +++ b/gnulib/argp-fmtstream.c @@ -0,0 +1,435 @@ +/* Word-wrapping and line-truncating streams + Copyright (C) 1997-1999, 2001-2003, 2005, 2009-2010 Free Software + Foundation, Inc. + This file is part of the GNU C Library. + Written by Miles Bader . + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* This package emulates glibc `line_wrap_stream' semantics for systems that + don't have that. */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include + +#include "argp-fmtstream.h" +#include "argp-namefrob.h" + +#ifndef ARGP_FMTSTREAM_USE_LINEWRAP + +#ifndef isblank +#define isblank(ch) ((ch)==' ' || (ch)=='\t') +#endif + +#if defined _LIBC && defined USE_IN_LIBIO +# include +# include +# define __vsnprintf(s, l, f, a) _IO_vsnprintf (s, l, f, a) +#endif + +#define INIT_BUF_SIZE 200 +#define PRINTF_SIZE_GUESS 150 + +/* Return an argp_fmtstream that outputs to STREAM, and which prefixes lines + written on it with LMARGIN spaces and limits them to RMARGIN columns + total. If WMARGIN >= 0, words that extend past RMARGIN are wrapped by + replacing the whitespace before them with a newline and WMARGIN spaces. + Otherwise, chars beyond RMARGIN are simply dropped until a newline. + Returns NULL if there was an error. */ +argp_fmtstream_t +__argp_make_fmtstream (FILE *stream, + size_t lmargin, size_t rmargin, ssize_t wmargin) +{ + argp_fmtstream_t fs; + + fs = (struct argp_fmtstream *) malloc (sizeof (struct argp_fmtstream)); + if (fs != NULL) + { + fs->stream = stream; + + fs->lmargin = lmargin; + fs->rmargin = rmargin; + fs->wmargin = wmargin; + fs->point_col = 0; + fs->point_offs = 0; + + fs->buf = (char *) malloc (INIT_BUF_SIZE); + if (! fs->buf) + { + free (fs); + fs = 0; + } + else + { + fs->p = fs->buf; + fs->end = fs->buf + INIT_BUF_SIZE; + } + } + + return fs; +} +#if 0 +/* Not exported. */ +#ifdef weak_alias +weak_alias (__argp_make_fmtstream, argp_make_fmtstream) +#endif +#endif + +/* Flush FS to its stream, and free it (but don't close the stream). */ +void +__argp_fmtstream_free (argp_fmtstream_t fs) +{ + __argp_fmtstream_update (fs); + if (fs->p > fs->buf) + { +#ifdef USE_IN_LIBIO + __fxprintf (fs->stream, "%.*s", (int) (fs->p - fs->buf), fs->buf); +#else + fwrite_unlocked (fs->buf, 1, fs->p - fs->buf, fs->stream); +#endif + } + free (fs->buf); + free (fs); +} +#if 0 +/* Not exported. */ +#ifdef weak_alias +weak_alias (__argp_fmtstream_free, argp_fmtstream_free) +#endif +#endif + +/* Process FS's buffer so that line wrapping is done from POINT_OFFS to the + end of its buffer. This code is mostly from glibc stdio/linewrap.c. */ +void +__argp_fmtstream_update (argp_fmtstream_t fs) +{ + char *buf, *nl; + size_t len; + + /* Scan the buffer for newlines. */ + buf = fs->buf + fs->point_offs; + while (buf < fs->p) + { + size_t r; + + if (fs->point_col == 0 && fs->lmargin != 0) + { + /* We are starting a new line. Print spaces to the left margin. */ + const size_t pad = fs->lmargin; + if (fs->p + pad < fs->end) + { + /* We can fit in them in the buffer by moving the + buffer text up and filling in the beginning. */ + memmove (buf + pad, buf, fs->p - buf); + fs->p += pad; /* Compensate for bigger buffer. */ + memset (buf, ' ', pad); /* Fill in the spaces. */ + buf += pad; /* Don't bother searching them. */ + } + else + { + /* No buffer space for spaces. Must flush. */ + size_t i; + for (i = 0; i < pad; i++) + { +#ifdef USE_IN_LIBIO + if (_IO_fwide (fs->stream, 0) > 0) + putwc_unlocked (L' ', fs->stream); + else +#endif + putc_unlocked (' ', fs->stream); + } + } + fs->point_col = pad; + } + + len = fs->p - buf; + nl = memchr (buf, '\n', len); + + if (fs->point_col < 0) + fs->point_col = 0; + + if (!nl) + { + /* The buffer ends in a partial line. */ + + if (fs->point_col + len < fs->rmargin) + { + /* The remaining buffer text is a partial line and fits + within the maximum line width. Advance point for the + characters to be written and stop scanning. */ + fs->point_col += len; + break; + } + else + /* Set the end-of-line pointer for the code below to + the end of the buffer. */ + nl = fs->p; + } + else if (fs->point_col + (nl - buf) < (ssize_t) fs->rmargin) + { + /* The buffer contains a full line that fits within the maximum + line width. Reset point and scan the next line. */ + fs->point_col = 0; + buf = nl + 1; + continue; + } + + /* This line is too long. */ + r = fs->rmargin - 1; + + if (fs->wmargin < 0) + { + /* Truncate the line by overwriting the excess with the + newline and anything after it in the buffer. */ + if (nl < fs->p) + { + memmove (buf + (r - fs->point_col), nl, fs->p - nl); + fs->p -= buf + (r - fs->point_col) - nl; + /* Reset point for the next line and start scanning it. */ + fs->point_col = 0; + buf += r + 1; /* Skip full line plus \n. */ + } + else + { + /* The buffer ends with a partial line that is beyond the + maximum line width. Advance point for the characters + written, and discard those past the max from the buffer. */ + fs->point_col += len; + fs->p -= fs->point_col - r; + break; + } + } + else + { + /* Do word wrap. Go to the column just past the maximum line + width and scan back for the beginning of the word there. + Then insert a line break. */ + + char *p, *nextline; + int i; + + p = buf + (r + 1 - fs->point_col); + while (p >= buf && !isblank ((unsigned char) *p)) + --p; + nextline = p + 1; /* This will begin the next line. */ + + if (nextline > buf) + { + /* Swallow separating blanks. */ + if (p >= buf) + do + --p; + while (p >= buf && isblank ((unsigned char) *p)); + nl = p + 1; /* The newline will replace the first blank. */ + } + else + { + /* A single word that is greater than the maximum line width. + Oh well. Put it on an overlong line by itself. */ + p = buf + (r + 1 - fs->point_col); + /* Find the end of the long word. */ + if (p < nl) + do + ++p; + while (p < nl && !isblank ((unsigned char) *p)); + if (p == nl) + { + /* It already ends a line. No fussing required. */ + fs->point_col = 0; + buf = nl + 1; + continue; + } + /* We will move the newline to replace the first blank. */ + nl = p; + /* Swallow separating blanks. */ + do + ++p; + while (isblank ((unsigned char) *p)); + /* The next line will start here. */ + nextline = p; + } + + /* Note: There are a bunch of tests below for + NEXTLINE == BUF + LEN + 1; this case is where NL happens to fall + at the end of the buffer, and NEXTLINE is in fact empty (and so + we need not be careful to maintain its contents). */ + + if ((nextline == buf + len + 1 + ? fs->end - nl < fs->wmargin + 1 + : nextline - (nl + 1) < fs->wmargin) + && fs->p > nextline) + { + /* The margin needs more blanks than we removed. */ + if (fs->end - fs->p > fs->wmargin + 1) + /* Make some space for them. */ + { + size_t mv = fs->p - nextline; + memmove (nl + 1 + fs->wmargin, nextline, mv); + nextline = nl + 1 + fs->wmargin; + len = nextline + mv - buf; + *nl++ = '\n'; + } + else + /* Output the first line so we can use the space. */ + { +#ifdef _LIBC + __fxprintf (fs->stream, "%.*s\n", + (int) (nl - fs->buf), fs->buf); +#else + if (nl > fs->buf) + fwrite_unlocked (fs->buf, 1, nl - fs->buf, fs->stream); + putc_unlocked ('\n', fs->stream); +#endif + + len += buf - fs->buf; + nl = buf = fs->buf; + } + } + else + /* We can fit the newline and blanks in before + the next word. */ + *nl++ = '\n'; + + if (nextline - nl >= fs->wmargin + || (nextline == buf + len + 1 && fs->end - nextline >= fs->wmargin)) + /* Add blanks up to the wrap margin column. */ + for (i = 0; i < fs->wmargin; ++i) + *nl++ = ' '; + else + for (i = 0; i < fs->wmargin; ++i) +#ifdef USE_IN_LIBIO + if (_IO_fwide (fs->stream, 0) > 0) + putwc_unlocked (L' ', fs->stream); + else +#endif + putc_unlocked (' ', fs->stream); + + /* Copy the tail of the original buffer into the current buffer + position. */ + if (nl < nextline) + memmove (nl, nextline, buf + len - nextline); + len -= nextline - buf; + + /* Continue the scan on the remaining lines in the buffer. */ + buf = nl; + + /* Restore bufp to include all the remaining text. */ + fs->p = nl + len; + + /* Reset the counter of what has been output this line. If wmargin + is 0, we want to avoid the lmargin getting added, so we set + point_col to a magic value of -1 in that case. */ + fs->point_col = fs->wmargin ? fs->wmargin : -1; + } + } + + /* Remember that we've scanned as far as the end of the buffer. */ + fs->point_offs = fs->p - fs->buf; +} + +/* Ensure that FS has space for AMOUNT more bytes in its buffer, either by + growing the buffer, or by flushing it. True is returned iff we succeed. */ +int +__argp_fmtstream_ensure (struct argp_fmtstream *fs, size_t amount) +{ + if ((size_t) (fs->end - fs->p) < amount) + { + ssize_t wrote; + + /* Flush FS's buffer. */ + __argp_fmtstream_update (fs); + +#ifdef _LIBC + __fxprintf (fs->stream, "%.*s", (int) (fs->p - fs->buf), fs->buf); + wrote = fs->p - fs->buf; +#else + wrote = fwrite_unlocked (fs->buf, 1, fs->p - fs->buf, fs->stream); +#endif + if (wrote == fs->p - fs->buf) + { + fs->p = fs->buf; + fs->point_offs = 0; + } + else + { + fs->p -= wrote; + fs->point_offs -= wrote; + memmove (fs->buf, fs->buf + wrote, fs->p - fs->buf); + return 0; + } + + if ((size_t) (fs->end - fs->buf) < amount) + /* Gotta grow the buffer. */ + { + size_t old_size = fs->end - fs->buf; + size_t new_size = old_size + amount; + char *new_buf; + + if (new_size < old_size || ! (new_buf = realloc (fs->buf, new_size))) + { + __set_errno (ENOMEM); + return 0; + } + + fs->buf = new_buf; + fs->end = new_buf + new_size; + fs->p = fs->buf; + } + } + + return 1; +} + +ssize_t +__argp_fmtstream_printf (struct argp_fmtstream *fs, const char *fmt, ...) +{ + int out; + size_t avail; + size_t size_guess = PRINTF_SIZE_GUESS; /* How much space to reserve. */ + + do + { + va_list args; + + if (! __argp_fmtstream_ensure (fs, size_guess)) + return -1; + + va_start (args, fmt); + avail = fs->end - fs->p; + out = __vsnprintf (fs->p, avail, fmt, args); + va_end (args); + if ((size_t) out >= avail) + size_guess = out + 1; + } + while ((size_t) out >= avail); + + fs->p += out; + + return out; +} +#if 0 +/* Not exported. */ +#ifdef weak_alias +weak_alias (__argp_fmtstream_printf, argp_fmtstream_printf) +#endif +#endif + +#endif /* !ARGP_FMTSTREAM_USE_LINEWRAP */ diff --git a/gnulib/argp-fmtstream.h b/gnulib/argp-fmtstream.h new file mode 100644 index 000000000..b913d1b25 --- /dev/null +++ b/gnulib/argp-fmtstream.h @@ -0,0 +1,354 @@ +/* Word-wrapping and line-truncating streams. + Copyright (C) 1997, 2006-2010 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Written by Miles Bader . + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* This package emulates glibc `line_wrap_stream' semantics for systems that + don't have that. If the system does have it, it is just a wrapper for + that. This header file is only used internally while compiling argp, and + shouldn't be installed. */ + +#ifndef _ARGP_FMTSTREAM_H +#define _ARGP_FMTSTREAM_H + +#include +#include +#include + +#ifndef __attribute__ +/* The __attribute__ feature is available in gcc versions 2.5 and later. + The __-protected variants of the attributes 'format' and 'printf' are + accepted by gcc versions 2.6.4 (effectively 2.7) and later. + We enable __attribute__ only if these are supported too, because + gnulib and libintl do '#define printf __printf__' when they override + the 'printf' function. */ +# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7) +# define __attribute__(Spec) /* empty */ +# endif +#endif + +#if (_LIBC - 0 && !defined (USE_IN_LIBIO)) \ + || (defined (__GNU_LIBRARY__) && defined (HAVE_LINEWRAP_H)) +/* line_wrap_stream is available, so use that. */ +#define ARGP_FMTSTREAM_USE_LINEWRAP +#endif + +#ifdef ARGP_FMTSTREAM_USE_LINEWRAP +/* Just be a simple wrapper for line_wrap_stream; the semantics are + *slightly* different, as line_wrap_stream doesn't actually make a new + object, it just modifies the given stream (reversibly) to do + line-wrapping. Since we control who uses this code, it doesn't matter. */ + +#include + +typedef FILE *argp_fmtstream_t; + +#define argp_make_fmtstream line_wrap_stream +#define __argp_make_fmtstream line_wrap_stream +#define argp_fmtstream_free line_unwrap_stream +#define __argp_fmtstream_free line_unwrap_stream + +#define __argp_fmtstream_putc(fs,ch) putc(ch,fs) +#define argp_fmtstream_putc(fs,ch) putc(ch,fs) +#define __argp_fmtstream_puts(fs,str) fputs(str,fs) +#define argp_fmtstream_puts(fs,str) fputs(str,fs) +#define __argp_fmtstream_write(fs,str,len) fwrite(str,1,len,fs) +#define argp_fmtstream_write(fs,str,len) fwrite(str,1,len,fs) +#define __argp_fmtstream_printf fprintf +#define argp_fmtstream_printf fprintf + +#define __argp_fmtstream_lmargin line_wrap_lmargin +#define argp_fmtstream_lmargin line_wrap_lmargin +#define __argp_fmtstream_set_lmargin line_wrap_set_lmargin +#define argp_fmtstream_set_lmargin line_wrap_set_lmargin +#define __argp_fmtstream_rmargin line_wrap_rmargin +#define argp_fmtstream_rmargin line_wrap_rmargin +#define __argp_fmtstream_set_rmargin line_wrap_set_rmargin +#define argp_fmtstream_set_rmargin line_wrap_set_rmargin +#define __argp_fmtstream_wmargin line_wrap_wmargin +#define argp_fmtstream_wmargin line_wrap_wmargin +#define __argp_fmtstream_set_wmargin line_wrap_set_wmargin +#define argp_fmtstream_set_wmargin line_wrap_set_wmargin +#define __argp_fmtstream_point line_wrap_point +#define argp_fmtstream_point line_wrap_point + +#else /* !ARGP_FMTSTREAM_USE_LINEWRAP */ +/* Guess we have to define our own version. */ + +struct argp_fmtstream +{ + FILE *stream; /* The stream we're outputting to. */ + + size_t lmargin, rmargin; /* Left and right margins. */ + ssize_t wmargin; /* Margin to wrap to, or -1 to truncate. */ + + /* Point in buffer to which we've processed for wrapping, but not output. */ + size_t point_offs; + /* Output column at POINT_OFFS, or -1 meaning 0 but don't add lmargin. */ + ssize_t point_col; + + char *buf; /* Output buffer. */ + char *p; /* Current end of text in BUF. */ + char *end; /* Absolute end of BUF. */ +}; + +typedef struct argp_fmtstream *argp_fmtstream_t; + +/* Return an argp_fmtstream that outputs to STREAM, and which prefixes lines + written on it with LMARGIN spaces and limits them to RMARGIN columns + total. If WMARGIN >= 0, words that extend past RMARGIN are wrapped by + replacing the whitespace before them with a newline and WMARGIN spaces. + Otherwise, chars beyond RMARGIN are simply dropped until a newline. + Returns NULL if there was an error. */ +extern argp_fmtstream_t __argp_make_fmtstream (FILE *__stream, + size_t __lmargin, + size_t __rmargin, + ssize_t __wmargin); +extern argp_fmtstream_t argp_make_fmtstream (FILE *__stream, + size_t __lmargin, + size_t __rmargin, + ssize_t __wmargin); + +/* Flush __FS to its stream, and free it (but don't close the stream). */ +extern void __argp_fmtstream_free (argp_fmtstream_t __fs); +extern void argp_fmtstream_free (argp_fmtstream_t __fs); + +extern ssize_t __argp_fmtstream_printf (argp_fmtstream_t __fs, + const char *__fmt, ...) + __attribute__ ((__format__ (printf, 2, 3))); +extern ssize_t argp_fmtstream_printf (argp_fmtstream_t __fs, + const char *__fmt, ...) + __attribute__ ((__format__ (printf, 2, 3))); + +#if _LIBC || !defined __OPTIMIZE__ +extern int __argp_fmtstream_putc (argp_fmtstream_t __fs, int __ch); +extern int argp_fmtstream_putc (argp_fmtstream_t __fs, int __ch); + +extern int __argp_fmtstream_puts (argp_fmtstream_t __fs, const char *__str); +extern int argp_fmtstream_puts (argp_fmtstream_t __fs, const char *__str); + +extern size_t __argp_fmtstream_write (argp_fmtstream_t __fs, + const char *__str, size_t __len); +extern size_t argp_fmtstream_write (argp_fmtstream_t __fs, + const char *__str, size_t __len); +#endif + +/* Access macros for various bits of state. */ +#define argp_fmtstream_lmargin(__fs) ((__fs)->lmargin) +#define argp_fmtstream_rmargin(__fs) ((__fs)->rmargin) +#define argp_fmtstream_wmargin(__fs) ((__fs)->wmargin) +#define __argp_fmtstream_lmargin argp_fmtstream_lmargin +#define __argp_fmtstream_rmargin argp_fmtstream_rmargin +#define __argp_fmtstream_wmargin argp_fmtstream_wmargin + +#if _LIBC || !defined __OPTIMIZE__ +/* Set __FS's left margin to LMARGIN and return the old value. */ +extern size_t argp_fmtstream_set_lmargin (argp_fmtstream_t __fs, + size_t __lmargin); +extern size_t __argp_fmtstream_set_lmargin (argp_fmtstream_t __fs, + size_t __lmargin); + +/* Set __FS's right margin to __RMARGIN and return the old value. */ +extern size_t argp_fmtstream_set_rmargin (argp_fmtstream_t __fs, + size_t __rmargin); +extern size_t __argp_fmtstream_set_rmargin (argp_fmtstream_t __fs, + size_t __rmargin); + +/* Set __FS's wrap margin to __WMARGIN and return the old value. */ +extern size_t argp_fmtstream_set_wmargin (argp_fmtstream_t __fs, + size_t __wmargin); +extern size_t __argp_fmtstream_set_wmargin (argp_fmtstream_t __fs, + size_t __wmargin); + +/* Return the column number of the current output point in __FS. */ +extern size_t argp_fmtstream_point (argp_fmtstream_t __fs); +extern size_t __argp_fmtstream_point (argp_fmtstream_t __fs); +#endif + +/* Internal routines. */ +extern void _argp_fmtstream_update (argp_fmtstream_t __fs); +extern void __argp_fmtstream_update (argp_fmtstream_t __fs); +extern int _argp_fmtstream_ensure (argp_fmtstream_t __fs, size_t __amount); +extern int __argp_fmtstream_ensure (argp_fmtstream_t __fs, size_t __amount); + +#ifdef __OPTIMIZE__ +/* Inline versions of above routines. */ + +#if !_LIBC +#define __argp_fmtstream_putc argp_fmtstream_putc +#define __argp_fmtstream_puts argp_fmtstream_puts +#define __argp_fmtstream_write argp_fmtstream_write +#define __argp_fmtstream_set_lmargin argp_fmtstream_set_lmargin +#define __argp_fmtstream_set_rmargin argp_fmtstream_set_rmargin +#define __argp_fmtstream_set_wmargin argp_fmtstream_set_wmargin +#define __argp_fmtstream_point argp_fmtstream_point +#define __argp_fmtstream_update _argp_fmtstream_update +#define __argp_fmtstream_ensure _argp_fmtstream_ensure +#endif + +#ifndef ARGP_FS_EI +# ifdef __GNUC__ + /* GCC 4.3 and above with -std=c99 or -std=gnu99 implements ISO C99 + inline semantics, unless -fgnu89-inline is used. It defines a macro + __GNUC_STDC_INLINE__ to indicate this situation or a macro + __GNUC_GNU_INLINE__ to indicate the opposite situation. + + GCC 4.2 with -std=c99 or -std=gnu99 implements the GNU C inline + semantics but warns, unless -fgnu89-inline is used: + warning: C99 inline functions are not supported; using GNU89 + warning: to disable this warning use -fgnu89-inline or the gnu_inline function attribute + It defines a macro __GNUC_GNU_INLINE__ to indicate this situation. + + Whereas Apple GCC 4.0.1 build 5479 without -std=c99 or -std=gnu99 + implements the GNU C inline semantics and defines the macro + __GNUC_GNU_INLINE__, but it does not warn and does not support + __attribute__ ((__gnu_inline__)). + + All in all, these are the possible combinations. For every compiler, + we need to choose ARGP_FS_EI so that the corresponding table cell + contains an "ok". + + \ ARGP_FS_EI inline extern extern + \ inline inline + CC \ __attribute__ + ((gnu_inline)) + + gcc 4.3.0 error ok ok + gcc 4.3.0 -std=gnu99 -fgnu89-inline error ok ok + gcc 4.3.0 -std=gnu99 ok error ok + + gcc 4.2.2 error ok ok + gcc 4.2.2 -std=gnu99 -fgnu89-inline error ok ok + gcc 4.2.2 -std=gnu99 error warning ok + + gcc 4.1.2 error ok warning + gcc 4.1.2 -std=gnu99 error ok warning + + Apple gcc 4.0.1 error ok warning + Apple gcc 4.0.1 -std=gnu99 ok error warning + */ +# if defined __GNUC_STDC_INLINE__ +# define ARGP_FS_EI inline +# elif __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2) +# define ARGP_FS_EI extern inline __attribute__ ((__gnu_inline__)) +# else +# define ARGP_FS_EI extern inline +# endif +# else + /* With other compilers, assume the ISO C99 meaning of 'inline', if + the compiler supports 'inline' at all. */ +# define ARGP_FS_EI inline +# endif +#endif + +ARGP_FS_EI size_t +__argp_fmtstream_write (argp_fmtstream_t __fs, + const char *__str, size_t __len) +{ + if (__fs->p + __len <= __fs->end || __argp_fmtstream_ensure (__fs, __len)) + { + memcpy (__fs->p, __str, __len); + __fs->p += __len; + return __len; + } + else + return 0; +} + +ARGP_FS_EI int +__argp_fmtstream_puts (argp_fmtstream_t __fs, const char *__str) +{ + size_t __len = strlen (__str); + if (__len) + { + size_t __wrote = __argp_fmtstream_write (__fs, __str, __len); + return __wrote == __len ? 0 : -1; + } + else + return 0; +} + +ARGP_FS_EI int +__argp_fmtstream_putc (argp_fmtstream_t __fs, int __ch) +{ + if (__fs->p < __fs->end || __argp_fmtstream_ensure (__fs, 1)) + return *__fs->p++ = __ch; + else + return EOF; +} + +/* Set __FS's left margin to __LMARGIN and return the old value. */ +ARGP_FS_EI size_t +__argp_fmtstream_set_lmargin (argp_fmtstream_t __fs, size_t __lmargin) +{ + size_t __old; + if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs) + __argp_fmtstream_update (__fs); + __old = __fs->lmargin; + __fs->lmargin = __lmargin; + return __old; +} + +/* Set __FS's right margin to __RMARGIN and return the old value. */ +ARGP_FS_EI size_t +__argp_fmtstream_set_rmargin (argp_fmtstream_t __fs, size_t __rmargin) +{ + size_t __old; + if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs) + __argp_fmtstream_update (__fs); + __old = __fs->rmargin; + __fs->rmargin = __rmargin; + return __old; +} + +/* Set FS's wrap margin to __WMARGIN and return the old value. */ +ARGP_FS_EI size_t +__argp_fmtstream_set_wmargin (argp_fmtstream_t __fs, size_t __wmargin) +{ + size_t __old; + if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs) + __argp_fmtstream_update (__fs); + __old = __fs->wmargin; + __fs->wmargin = __wmargin; + return __old; +} + +/* Return the column number of the current output point in __FS. */ +ARGP_FS_EI size_t +__argp_fmtstream_point (argp_fmtstream_t __fs) +{ + if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs) + __argp_fmtstream_update (__fs); + return __fs->point_col >= 0 ? __fs->point_col : 0; +} + +#if !_LIBC +#undef __argp_fmtstream_putc +#undef __argp_fmtstream_puts +#undef __argp_fmtstream_write +#undef __argp_fmtstream_set_lmargin +#undef __argp_fmtstream_set_rmargin +#undef __argp_fmtstream_set_wmargin +#undef __argp_fmtstream_point +#undef __argp_fmtstream_update +#undef __argp_fmtstream_ensure +#endif + +#endif /* __OPTIMIZE__ */ + +#endif /* ARGP_FMTSTREAM_USE_LINEWRAP */ + +#endif /* argp-fmtstream.h */ diff --git a/gnulib/argp-fs-xinl.c b/gnulib/argp-fs-xinl.c new file mode 100644 index 000000000..2c683f914 --- /dev/null +++ b/gnulib/argp-fs-xinl.c @@ -0,0 +1,42 @@ +/* Real definitions for extern inline functions in argp-fmtstream.h + Copyright (C) 1997, 2003, 2004, 2009, 2010 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Written by Miles Bader . + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#define ARGP_FS_EI +#undef __OPTIMIZE__ +#define __OPTIMIZE__ 1 +#include "argp-fmtstream.h" + +#if 0 +/* Not exported. */ +/* Add weak aliases. */ +#if _LIBC - 0 && !defined (ARGP_FMTSTREAM_USE_LINEWRAP) && defined (weak_alias) + +weak_alias (__argp_fmtstream_putc, argp_fmtstream_putc) +weak_alias (__argp_fmtstream_puts, argp_fmtstream_puts) +weak_alias (__argp_fmtstream_write, argp_fmtstream_write) +weak_alias (__argp_fmtstream_set_lmargin, argp_fmtstream_set_lmargin) +weak_alias (__argp_fmtstream_set_rmargin, argp_fmtstream_set_rmargin) +weak_alias (__argp_fmtstream_set_wmargin, argp_fmtstream_set_wmargin) +weak_alias (__argp_fmtstream_point, argp_fmtstream_point) + +#endif +#endif diff --git a/gnulib/argp-help.c b/gnulib/argp-help.c new file mode 100644 index 000000000..5b6d950be --- /dev/null +++ b/gnulib/argp-help.c @@ -0,0 +1,1951 @@ +/* Hierarchial argument parsing help output + Copyright (C) 1995-2005, 2007, 2009-2010 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Written by Miles Bader . + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#ifndef _GNU_SOURCE +# define _GNU_SOURCE 1 +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef USE_IN_LIBIO +# include +#endif + +#ifdef _LIBC +# include +# undef dgettext +# define dgettext(domain, msgid) \ + INTUSE(__dcgettext) (domain, msgid, LC_MESSAGES) +#else +# include "gettext.h" +#endif + +#include "argp.h" +#include "argp-fmtstream.h" +#include "argp-namefrob.h" + +#ifndef SIZE_MAX +# define SIZE_MAX ((size_t) -1) +#endif + +/* User-selectable (using an environment variable) formatting parameters. + + These may be specified in an environment variable called `ARGP_HELP_FMT', + with a contents like: VAR1=VAL1,VAR2=VAL2,BOOLVAR2,no-BOOLVAR2 + Where VALn must be a positive integer. The list of variables is in the + UPARAM_NAMES vector, below. */ + +/* Default parameters. */ +#define DUP_ARGS 0 /* True if option argument can be duplicated. */ +#define DUP_ARGS_NOTE 1 /* True to print a note about duplicate args. */ +#define SHORT_OPT_COL 2 /* column in which short options start */ +#define LONG_OPT_COL 6 /* column in which long options start */ +#define DOC_OPT_COL 2 /* column in which doc options start */ +#define OPT_DOC_COL 29 /* column in which option text starts */ +#define HEADER_COL 1 /* column in which group headers are printed */ +#define USAGE_INDENT 12 /* indentation of wrapped usage lines */ +#define RMARGIN 79 /* right margin used for wrapping */ + +/* User-selectable (using an environment variable) formatting parameters. + They must all be of type `int' for the parsing code to work. */ +struct uparams +{ + /* If true, arguments for an option are shown with both short and long + options, even when a given option has both, e.g. `-x ARG, --longx=ARG'. + If false, then if an option has both, the argument is only shown with + the long one, e.g., `-x, --longx=ARG', and a message indicating that + this really means both is printed below the options. */ + int dup_args; + + /* This is true if when DUP_ARGS is false, and some duplicate arguments have + been suppressed, an explanatory message should be printed. */ + int dup_args_note; + + /* Various output columns. */ + int short_opt_col; /* column in which short options start */ + int long_opt_col; /* column in which long options start */ + int doc_opt_col; /* column in which doc options start */ + int opt_doc_col; /* column in which option text starts */ + int header_col; /* column in which group headers are printed */ + int usage_indent; /* indentation of wrapped usage lines */ + int rmargin; /* right margin used for wrapping */ + + int valid; /* True when the values in here are valid. */ +}; + +/* This is a global variable, as user options are only ever read once. */ +static struct uparams uparams = { + DUP_ARGS, DUP_ARGS_NOTE, + SHORT_OPT_COL, LONG_OPT_COL, DOC_OPT_COL, OPT_DOC_COL, HEADER_COL, + USAGE_INDENT, RMARGIN, + 0 +}; + +/* A particular uparam, and what the user name is. */ +struct uparam_name +{ + const char *name; /* User name. */ + int is_bool; /* Whether it's `boolean'. */ + size_t uparams_offs; /* Location of the (int) field in UPARAMS. */ +}; + +/* The name-field mappings we know about. */ +static const struct uparam_name uparam_names[] = +{ + { "dup-args", 1, offsetof (struct uparams, dup_args) }, + { "dup-args-note", 1, offsetof (struct uparams, dup_args_note) }, + { "short-opt-col", 0, offsetof (struct uparams, short_opt_col) }, + { "long-opt-col", 0, offsetof (struct uparams, long_opt_col) }, + { "doc-opt-col", 0, offsetof (struct uparams, doc_opt_col) }, + { "opt-doc-col", 0, offsetof (struct uparams, opt_doc_col) }, + { "header-col", 0, offsetof (struct uparams, header_col) }, + { "usage-indent", 0, offsetof (struct uparams, usage_indent) }, + { "rmargin", 0, offsetof (struct uparams, rmargin) }, + { 0 } +}; + +static void +validate_uparams (const struct argp_state *state, struct uparams *upptr) +{ + const struct uparam_name *up; + + for (up = uparam_names; up->name; up++) + { + if (up->is_bool + || up->uparams_offs == offsetof (struct uparams, rmargin)) + continue; + if (*(int *)((char *)upptr + up->uparams_offs) >= upptr->rmargin) + { + __argp_failure (state, 0, 0, + dgettext (state->root_argp->argp_domain, + "\ +ARGP_HELP_FMT: %s value is less than or equal to %s"), + "rmargin", up->name); + return; + } + } + uparams = *upptr; + uparams.valid = 1; +} + +/* Read user options from the environment, and fill in UPARAMS appropiately. */ +static void +fill_in_uparams (const struct argp_state *state) +{ + const char *var = getenv ("ARGP_HELP_FMT"); + struct uparams new_params = uparams; + +#define SKIPWS(p) do { while (isspace ((unsigned char) *p)) p++; } while (0); + + if (var) + { + /* Parse var. */ + while (*var) + { + SKIPWS (var); + + if (isalpha ((unsigned char) *var)) + { + size_t var_len; + const struct uparam_name *un; + int unspec = 0, val = 0; + const char *arg = var; + + while (isalnum ((unsigned char) *arg) || *arg == '-' || *arg == '_') + arg++; + var_len = arg - var; + + SKIPWS (arg); + + if (*arg == '\0' || *arg == ',') + unspec = 1; + else if (*arg == '=') + { + arg++; + SKIPWS (arg); + } + + if (unspec) + { + if (var[0] == 'n' && var[1] == 'o' && var[2] == '-') + { + val = 0; + var += 3; + var_len -= 3; + } + else + val = 1; + } + else if (isdigit ((unsigned char) *arg)) + { + val = atoi (arg); + while (isdigit ((unsigned char) *arg)) + arg++; + SKIPWS (arg); + } + + for (un = uparam_names; un->name; un++) + if (strlen (un->name) == var_len + && strncmp (var, un->name, var_len) == 0) + { + if (unspec && !un->is_bool) + __argp_failure (state, 0, 0, + dgettext (state->root_argp->argp_domain, + "\ +%.*s: ARGP_HELP_FMT parameter requires a value"), + (int) var_len, var); + else if (val < 0) + __argp_failure (state, 0, 0, + dgettext (state->root_argp->argp_domain, + "\ +%.*s: ARGP_HELP_FMT parameter must be positive"), + (int) var_len, var); + else + *(int *)((char *)&new_params + un->uparams_offs) = val; + break; + } + if (! un->name) + __argp_failure (state, 0, 0, + dgettext (state->root_argp->argp_domain, "\ +%.*s: Unknown ARGP_HELP_FMT parameter"), + (int) var_len, var); + + var = arg; + if (*var == ',') + var++; + } + else if (*var) + { + __argp_failure (state, 0, 0, + dgettext (state->root_argp->argp_domain, + "Garbage in ARGP_HELP_FMT: %s"), var); + break; + } + } + validate_uparams (state, &new_params); + } +} + +/* Returns true if OPT hasn't been marked invisible. Visibility only affects + whether OPT is displayed or used in sorting, not option shadowing. */ +#define ovisible(opt) (! ((opt)->flags & OPTION_HIDDEN)) + +/* Returns true if OPT is an alias for an earlier option. */ +#define oalias(opt) ((opt)->flags & OPTION_ALIAS) + +/* Returns true if OPT is an documentation-only entry. */ +#define odoc(opt) ((opt)->flags & OPTION_DOC) + +/* Returns true if OPT should not be translated */ +#define onotrans(opt) ((opt)->flags & OPTION_NO_TRANS) + +/* Returns true if OPT is the end-of-list marker for a list of options. */ +#define oend(opt) __option_is_end (opt) + +/* Returns true if OPT has a short option. */ +#define oshort(opt) __option_is_short (opt) + +/* + The help format for a particular option is like: + + -xARG, -yARG, --long1=ARG, --long2=ARG Documentation... + + Where ARG will be omitted if there's no argument, for this option, or + will be surrounded by "[" and "]" appropiately if the argument is + optional. The documentation string is word-wrapped appropiately, and if + the list of options is long enough, it will be started on a separate line. + If there are no short options for a given option, the first long option is + indented slighly in a way that's supposed to make most long options appear + to be in a separate column. + + For example, the following output (from ps): + + -p PID, --pid=PID List the process PID + --pgrp=PGRP List processes in the process group PGRP + -P, -x, --no-parent Include processes without parents + -Q, --all-fields Don't elide unusable fields (normally if there's + some reason ps can't print a field for any + process, it's removed from the output entirely) + -r, --reverse, --gratuitously-long-reverse-option + Reverse the order of any sort + --session[=SID] Add the processes from the session SID (which + defaults to the sid of the current process) + + Here are some more options: + -f ZOT, --foonly=ZOT Glork a foonly + -z, --zaza Snit a zar + + -?, --help Give this help list + --usage Give a short usage message + -V, --version Print program version + + The struct argp_option array for the above could look like: + + { + {"pid", 'p', "PID", 0, "List the process PID"}, + {"pgrp", OPT_PGRP, "PGRP", 0, "List processes in the process group PGRP"}, + {"no-parent", 'P', 0, 0, "Include processes without parents"}, + {0, 'x', 0, OPTION_ALIAS}, + {"all-fields",'Q', 0, 0, "Don't elide unusable fields (normally" + " if there's some reason ps can't" + " print a field for any process, it's" + " removed from the output entirely)" }, + {"reverse", 'r', 0, 0, "Reverse the order of any sort"}, + {"gratuitously-long-reverse-option", 0, 0, OPTION_ALIAS}, + {"session", OPT_SESS, "SID", OPTION_ARG_OPTIONAL, + "Add the processes from the session" + " SID (which defaults to the sid of" + " the current process)" }, + + {0,0,0,0, "Here are some more options:"}, + {"foonly", 'f', "ZOT", 0, "Glork a foonly"}, + {"zaza", 'z', 0, 0, "Snit a zar"}, + + {0} + } + + Note that the last three options are automatically supplied by argp_parse, + unless you tell it not to with ARGP_NO_HELP. + +*/ + +/* Returns true if CH occurs between BEG and END. */ +static int +find_char (char ch, char *beg, char *end) +{ + while (beg < end) + if (*beg == ch) + return 1; + else + beg++; + return 0; +} + +struct hol_cluster; /* fwd decl */ + +struct hol_entry +{ + /* First option. */ + const struct argp_option *opt; + /* Number of options (including aliases). */ + unsigned num; + + /* A pointers into the HOL's short_options field, to the first short option + letter for this entry. The order of the characters following this point + corresponds to the order of options pointed to by OPT, and there are at + most NUM. A short option recorded in a option following OPT is only + valid if it occurs in the right place in SHORT_OPTIONS (otherwise it's + probably been shadowed by some other entry). */ + char *short_options; + + /* Entries are sorted by their group first, in the order: + 1, 2, ..., n, 0, -m, ..., -2, -1 + and then alphabetically within each group. The default is 0. */ + int group; + + /* The cluster of options this entry belongs to, or 0 if none. */ + struct hol_cluster *cluster; + + /* The argp from which this option came. */ + const struct argp *argp; + + /* Position in the array */ + unsigned ord; +}; + +/* A cluster of entries to reflect the argp tree structure. */ +struct hol_cluster +{ + /* A descriptive header printed before options in this cluster. */ + const char *header; + + /* Used to order clusters within the same group with the same parent, + according to the order in which they occurred in the parent argp's child + list. */ + int index; + + /* How to sort this cluster with respect to options and other clusters at the + same depth (clusters always follow options in the same group). */ + int group; + + /* The cluster to which this cluster belongs, or 0 if it's at the base + level. */ + struct hol_cluster *parent; + + /* The argp from which this cluster is (eventually) derived. */ + const struct argp *argp; + + /* The distance this cluster is from the root. */ + int depth; + + /* Clusters in a given hol are kept in a linked list, to make freeing them + possible. */ + struct hol_cluster *next; +}; + +/* A list of options for help. */ +struct hol +{ + /* An array of hol_entry's. */ + struct hol_entry *entries; + /* The number of entries in this hol. If this field is zero, the others + are undefined. */ + unsigned num_entries; + + /* A string containing all short options in this HOL. Each entry contains + pointers into this string, so the order can't be messed with blindly. */ + char *short_options; + + /* Clusters of entries in this hol. */ + struct hol_cluster *clusters; +}; + +/* Create a struct hol from the options in ARGP. CLUSTER is the + hol_cluster in which these entries occur, or 0, if at the root. */ +static struct hol * +make_hol (const struct argp *argp, struct hol_cluster *cluster) +{ + char *so; + const struct argp_option *o; + const struct argp_option *opts = argp->options; + struct hol_entry *entry; + unsigned num_short_options = 0; + struct hol *hol = malloc (sizeof (struct hol)); + + assert (hol); + + hol->num_entries = 0; + hol->clusters = 0; + + if (opts) + { + int cur_group = 0; + + /* The first option must not be an alias. */ + assert (! oalias (opts)); + + /* Calculate the space needed. */ + for (o = opts; ! oend (o); o++) + { + if (! oalias (o)) + hol->num_entries++; + if (oshort (o)) + num_short_options++; /* This is an upper bound. */ + } + + hol->entries = malloc (sizeof (struct hol_entry) * hol->num_entries); + hol->short_options = malloc (num_short_options + 1); + + assert (hol->entries && hol->short_options); + if (SIZE_MAX <= UINT_MAX) + assert (hol->num_entries <= SIZE_MAX / sizeof (struct hol_entry)); + + /* Fill in the entries. */ + so = hol->short_options; + for (o = opts, entry = hol->entries; ! oend (o); entry++) + { + entry->opt = o; + entry->num = 0; + entry->short_options = so; + entry->group = cur_group = + o->group + ? o->group + : ((!o->name && !o->key) + ? cur_group + 1 + : cur_group); + entry->cluster = cluster; + entry->argp = argp; + + do + { + entry->num++; + if (oshort (o) && ! find_char (o->key, hol->short_options, so)) + /* O has a valid short option which hasn't already been used.*/ + *so++ = o->key; + o++; + } + while (! oend (o) && oalias (o)); + } + *so = '\0'; /* null terminated so we can find the length */ + } + + return hol; +} + +/* Add a new cluster to HOL, with the given GROUP and HEADER (taken from the + associated argp child list entry), INDEX, and PARENT, and return a pointer + to it. ARGP is the argp that this cluster results from. */ +static struct hol_cluster * +hol_add_cluster (struct hol *hol, int group, const char *header, int index, + struct hol_cluster *parent, const struct argp *argp) +{ + struct hol_cluster *cl = malloc (sizeof (struct hol_cluster)); + if (cl) + { + cl->group = group; + cl->header = header; + + cl->index = index; + cl->parent = parent; + cl->argp = argp; + cl->depth = parent ? parent->depth + 1 : 0; + + cl->next = hol->clusters; + hol->clusters = cl; + } + return cl; +} + +/* Free HOL and any resources it uses. */ +static void +hol_free (struct hol *hol) +{ + struct hol_cluster *cl = hol->clusters; + + while (cl) + { + struct hol_cluster *next = cl->next; + free (cl); + cl = next; + } + + if (hol->num_entries > 0) + { + free (hol->entries); + free (hol->short_options); + } + + free (hol); +} + +static int +hol_entry_short_iterate (const struct hol_entry *entry, + int (*func)(const struct argp_option *opt, + const struct argp_option *real, + const char *domain, void *cookie), + const char *domain, void *cookie) +{ + unsigned nopts; + int val = 0; + const struct argp_option *opt, *real = entry->opt; + char *so = entry->short_options; + + for (opt = real, nopts = entry->num; nopts > 0 && !val; opt++, nopts--) + if (oshort (opt) && *so == opt->key) + { + if (!oalias (opt)) + real = opt; + if (ovisible (opt)) + val = (*func)(opt, real, domain, cookie); + so++; + } + + return val; +} + +static inline int +__attribute__ ((always_inline)) +hol_entry_long_iterate (const struct hol_entry *entry, + int (*func)(const struct argp_option *opt, + const struct argp_option *real, + const char *domain, void *cookie), + const char *domain, void *cookie) +{ + unsigned nopts; + int val = 0; + const struct argp_option *opt, *real = entry->opt; + + for (opt = real, nopts = entry->num; nopts > 0 && !val; opt++, nopts--) + if (opt->name) + { + if (!oalias (opt)) + real = opt; + if (ovisible (opt)) + val = (*func)(opt, real, domain, cookie); + } + + return val; +} + +/* Iterator that returns true for the first short option. */ +static int +until_short (const struct argp_option *opt, const struct argp_option *real, + const char *domain, void *cookie) +{ + return oshort (opt) ? opt->key : 0; +} + +/* Returns the first valid short option in ENTRY, or 0 if there is none. */ +static char +hol_entry_first_short (const struct hol_entry *entry) +{ + return hol_entry_short_iterate (entry, until_short, + entry->argp->argp_domain, 0); +} + +/* Returns the first valid long option in ENTRY, or 0 if there is none. */ +static const char * +hol_entry_first_long (const struct hol_entry *entry) +{ + const struct argp_option *opt; + unsigned num; + for (opt = entry->opt, num = entry->num; num > 0; opt++, num--) + if (opt->name && ovisible (opt)) + return opt->name; + return 0; +} + +/* Returns the entry in HOL with the long option name NAME, or 0 if there is + none. */ +static struct hol_entry * +hol_find_entry (struct hol *hol, const char *name) +{ + struct hol_entry *entry = hol->entries; + unsigned num_entries = hol->num_entries; + + while (num_entries-- > 0) + { + const struct argp_option *opt = entry->opt; + unsigned num_opts = entry->num; + + while (num_opts-- > 0) + if (opt->name && ovisible (opt) && strcmp (opt->name, name) == 0) + return entry; + else + opt++; + + entry++; + } + + return 0; +} + +/* If an entry with the long option NAME occurs in HOL, set it's special + sort position to GROUP. */ +static void +hol_set_group (struct hol *hol, const char *name, int group) +{ + struct hol_entry *entry = hol_find_entry (hol, name); + if (entry) + entry->group = group; +} + +/* Order by group: 0, 1, 2, ..., n, -m, ..., -2, -1. + EQ is what to return if GROUP1 and GROUP2 are the same. */ +static int +group_cmp (int group1, int group2, int eq) +{ + if (group1 == group2) + return eq; + else if ((group1 < 0 && group2 < 0) || (group1 >= 0 && group2 >= 0)) + return group1 - group2; + else + return group2 - group1; +} + +/* Compare clusters CL1 & CL2 by the order that they should appear in + output. */ +static int +hol_cluster_cmp (const struct hol_cluster *cl1, const struct hol_cluster *cl2) +{ + /* If one cluster is deeper than the other, use its ancestor at the same + level, so that finding the common ancestor is straightforward. + + clN->depth > 0 means that clN->parent != NULL (see hol_add_cluster) */ + while (cl1->depth > cl2->depth) + cl1 = cl1->parent; + while (cl2->depth > cl1->depth) + cl2 = cl2->parent; + + /* Now reduce both clusters to their ancestors at the point where both have + a common parent; these can be directly compared. */ + while (cl1->parent != cl2->parent) + cl1 = cl1->parent, cl2 = cl2->parent; + + return group_cmp (cl1->group, cl2->group, cl2->index - cl1->index); +} + +/* Return the ancestor of CL that's just below the root (i.e., has a parent + of 0). */ +static struct hol_cluster * +hol_cluster_base (struct hol_cluster *cl) +{ + while (cl->parent) + cl = cl->parent; + return cl; +} + +/* Return true if CL1 is a child of CL2. */ +static int +hol_cluster_is_child (const struct hol_cluster *cl1, + const struct hol_cluster *cl2) +{ + while (cl1 && cl1 != cl2) + cl1 = cl1->parent; + return cl1 == cl2; +} + +/* Given the name of a OPTION_DOC option, modifies NAME to start at the tail + that should be used for comparisons, and returns true iff it should be + treated as a non-option. */ +static int +canon_doc_option (const char **name) +{ + int non_opt; + + if (!*name) + non_opt = 1; + else + { + /* Skip initial whitespace. */ + while (isspace ((unsigned char) **name)) + (*name)++; + /* Decide whether this looks like an option (leading `-') or not. */ + non_opt = (**name != '-'); + /* Skip until part of name used for sorting. */ + while (**name && !isalnum ((unsigned char) **name)) + (*name)++; + } + return non_opt; +} + +#define HOL_ENTRY_PTRCMP(a,b) ((a)->ord < (b)->ord ? -1 : 1) + +/* Order ENTRY1 & ENTRY2 by the order which they should appear in a help + listing. */ +static int +hol_entry_cmp (const struct hol_entry *entry1, + const struct hol_entry *entry2) +{ + /* The group numbers by which the entries should be ordered; if either is + in a cluster, then this is just the group within the cluster. */ + int group1 = entry1->group, group2 = entry2->group; + int rc; + + if (entry1->cluster != entry2->cluster) + { + /* The entries are not within the same cluster, so we can't compare them + directly, we have to use the appropiate clustering level too. */ + if (! entry1->cluster) + /* ENTRY1 is at the `base level', not in a cluster, so we have to + compare it's group number with that of the base cluster in which + ENTRY2 resides. Note that if they're in the same group, the + clustered option always comes laster. */ + return group_cmp (group1, hol_cluster_base (entry2->cluster)->group, -1); + else if (! entry2->cluster) + /* Likewise, but ENTRY2's not in a cluster. */ + return group_cmp (hol_cluster_base (entry1->cluster)->group, group2, 1); + else + /* Both entries are in clusters, we can just compare the clusters. */ + return (rc = hol_cluster_cmp (entry1->cluster, entry2->cluster)) ? + rc : HOL_ENTRY_PTRCMP (entry1, entry2); + } + else if (group1 == group2) + /* The entries are both in the same cluster and group, so compare them + alphabetically. */ + { + int short1 = hol_entry_first_short (entry1); + int short2 = hol_entry_first_short (entry2); + int doc1 = odoc (entry1->opt); + int doc2 = odoc (entry2->opt); + const char *long1 = hol_entry_first_long (entry1); + const char *long2 = hol_entry_first_long (entry2); + + if (doc1) + doc1 = canon_doc_option (&long1); + if (doc2) + doc2 = canon_doc_option (&long2); + + if (doc1 != doc2) + /* `documentation' options always follow normal options (or + documentation options that *look* like normal options). */ + return doc1 - doc2; + else if (!short1 && !short2 && long1 && long2) + /* Only long options. */ + return (rc = __strcasecmp (long1, long2)) ? + rc : HOL_ENTRY_PTRCMP (entry1, entry2); + else + /* Compare short/short, long/short, short/long, using the first + character of long options. Entries without *any* valid + options (such as options with OPTION_HIDDEN set) will be put + first, but as they're not displayed, it doesn't matter where + they are. */ + { + unsigned char first1 = short1 ? short1 : long1 ? *long1 : 0; + unsigned char first2 = short2 ? short2 : long2 ? *long2 : 0; + /* Use tolower, not _tolower, since only the former is + guaranteed to work on something already lower case. */ + int lower_cmp = tolower (first1) - tolower (first2); + /* Compare ignoring case, except when the options are both the + same letter, in which case lower-case always comes first. */ + return lower_cmp ? lower_cmp : + (rc = first2 - first1) ? + rc : HOL_ENTRY_PTRCMP (entry1, entry2); + } + } + else + /* Within the same cluster, but not the same group, so just compare + groups. */ + return group_cmp (group1, group2, HOL_ENTRY_PTRCMP (entry1, entry2)); +} + +/* Version of hol_entry_cmp with correct signature for qsort. */ +static int +hol_entry_qcmp (const void *entry1_v, const void *entry2_v) +{ + return hol_entry_cmp (entry1_v, entry2_v); +} + +/* Sort HOL by group and alphabetically by option name (with short options + taking precedence over long). Since the sorting is for display purposes + only, the shadowing of options isn't effected. */ +static void +hol_sort (struct hol *hol) +{ + if (hol->num_entries > 0) + { + unsigned i; + struct hol_entry *e; + for (i = 0, e = hol->entries; i < hol->num_entries; i++, e++) + e->ord = i; + qsort (hol->entries, hol->num_entries, sizeof (struct hol_entry), + hol_entry_qcmp); + } +} + +/* Append MORE to HOL, destroying MORE in the process. Options in HOL shadow + any in MORE with the same name. */ +static void +hol_append (struct hol *hol, struct hol *more) +{ + struct hol_cluster **cl_end = &hol->clusters; + + /* Steal MORE's cluster list, and add it to the end of HOL's. */ + while (*cl_end) + cl_end = &(*cl_end)->next; + *cl_end = more->clusters; + more->clusters = 0; + + /* Merge entries. */ + if (more->num_entries > 0) + { + if (hol->num_entries == 0) + { + hol->num_entries = more->num_entries; + hol->entries = more->entries; + hol->short_options = more->short_options; + more->num_entries = 0; /* Mark MORE's fields as invalid. */ + } + else + /* Append the entries in MORE to those in HOL, taking care to only add + non-shadowed SHORT_OPTIONS values. */ + { + unsigned left; + char *so, *more_so; + struct hol_entry *e; + unsigned num_entries = hol->num_entries + more->num_entries; + struct hol_entry *entries = + malloc (num_entries * sizeof (struct hol_entry)); + unsigned hol_so_len = strlen (hol->short_options); + char *short_options = + malloc (hol_so_len + strlen (more->short_options) + 1); + + assert (entries && short_options); + if (SIZE_MAX <= UINT_MAX) + assert (num_entries <= SIZE_MAX / sizeof (struct hol_entry)); + + __mempcpy (__mempcpy (entries, hol->entries, + hol->num_entries * sizeof (struct hol_entry)), + more->entries, + more->num_entries * sizeof (struct hol_entry)); + + __mempcpy (short_options, hol->short_options, hol_so_len); + + /* Fix up the short options pointers from HOL. */ + for (e = entries, left = hol->num_entries; left > 0; e++, left--) + e->short_options += (short_options - hol->short_options); + + /* Now add the short options from MORE, fixing up its entries + too. */ + so = short_options + hol_so_len; + more_so = more->short_options; + for (left = more->num_entries; left > 0; e++, left--) + { + int opts_left; + const struct argp_option *opt; + + e->short_options = so; + + for (opts_left = e->num, opt = e->opt; opts_left; opt++, opts_left--) + { + int ch = *more_so; + if (oshort (opt) && ch == opt->key) + /* The next short option in MORE_SO, CH, is from OPT. */ + { + if (! find_char (ch, short_options, + short_options + hol_so_len)) + /* The short option CH isn't shadowed by HOL's options, + so add it to the sum. */ + *so++ = ch; + more_so++; + } + } + } + + *so = '\0'; + + free (hol->entries); + free (hol->short_options); + + hol->entries = entries; + hol->num_entries = num_entries; + hol->short_options = short_options; + } + } + + hol_free (more); +} + +/* Inserts enough spaces to make sure STREAM is at column COL. */ +static void +indent_to (argp_fmtstream_t stream, unsigned col) +{ + int needed = col - __argp_fmtstream_point (stream); + while (needed-- > 0) + __argp_fmtstream_putc (stream, ' '); +} + +/* Output to STREAM either a space, or a newline if there isn't room for at + least ENSURE characters before the right margin. */ +static void +space (argp_fmtstream_t stream, size_t ensure) +{ + if (__argp_fmtstream_point (stream) + ensure + >= __argp_fmtstream_rmargin (stream)) + __argp_fmtstream_putc (stream, '\n'); + else + __argp_fmtstream_putc (stream, ' '); +} + +/* If the option REAL has an argument, we print it in using the printf + format REQ_FMT or OPT_FMT depending on whether it's a required or + optional argument. */ +static void +arg (const struct argp_option *real, const char *req_fmt, const char *opt_fmt, + const char *domain, argp_fmtstream_t stream) +{ + if (real->arg) + { + if (real->flags & OPTION_ARG_OPTIONAL) + __argp_fmtstream_printf (stream, opt_fmt, + dgettext (domain, real->arg)); + else + __argp_fmtstream_printf (stream, req_fmt, + dgettext (domain, real->arg)); + } +} + +/* Helper functions for hol_entry_help. */ + +/* State used during the execution of hol_help. */ +struct hol_help_state +{ + /* PREV_ENTRY should contain the previous entry printed, or 0. */ + struct hol_entry *prev_entry; + + /* If an entry is in a different group from the previous one, and SEP_GROUPS + is true, then a blank line will be printed before any output. */ + int sep_groups; + + /* True if a duplicate option argument was suppressed (only ever set if + UPARAMS.dup_args is false). */ + int suppressed_dup_arg; +}; + +/* Some state used while printing a help entry (used to communicate with + helper functions). See the doc for hol_entry_help for more info, as most + of the fields are copied from its arguments. */ +struct pentry_state +{ + const struct hol_entry *entry; + argp_fmtstream_t stream; + struct hol_help_state *hhstate; + + /* True if nothing's been printed so far. */ + int first; + + /* If non-zero, the state that was used to print this help. */ + const struct argp_state *state; +}; + +/* If a user doc filter should be applied to DOC, do so. */ +static const char * +filter_doc (const char *doc, int key, const struct argp *argp, + const struct argp_state *state) +{ + if (argp->help_filter) + /* We must apply a user filter to this output. */ + { + void *input = __argp_input (argp, state); + return (*argp->help_filter) (key, doc, input); + } + else + /* No filter. */ + return doc; +} + +/* Prints STR as a header line, with the margin lines set appropiately, and + notes the fact that groups should be separated with a blank line. ARGP is + the argp that should dictate any user doc filtering to take place. Note + that the previous wrap margin isn't restored, but the left margin is reset + to 0. */ +static void +print_header (const char *str, const struct argp *argp, + struct pentry_state *pest) +{ + const char *tstr = dgettext (argp->argp_domain, str); + const char *fstr = filter_doc (tstr, ARGP_KEY_HELP_HEADER, argp, pest->state); + + if (fstr) + { + if (*fstr) + { + if (pest->hhstate->prev_entry) + /* Precede with a blank line. */ + __argp_fmtstream_putc (pest->stream, '\n'); + indent_to (pest->stream, uparams.header_col); + __argp_fmtstream_set_lmargin (pest->stream, uparams.header_col); + __argp_fmtstream_set_wmargin (pest->stream, uparams.header_col); + __argp_fmtstream_puts (pest->stream, fstr); + __argp_fmtstream_set_lmargin (pest->stream, 0); + __argp_fmtstream_putc (pest->stream, '\n'); + } + + pest->hhstate->sep_groups = 1; /* Separate subsequent groups. */ + } + + if (fstr != tstr) + free ((char *) fstr); +} + +/* Inserts a comma if this isn't the first item on the line, and then makes + sure we're at least to column COL. If this *is* the first item on a line, + prints any pending whitespace/headers that should precede this line. Also + clears FIRST. */ +static void +comma (unsigned col, struct pentry_state *pest) +{ + if (pest->first) + { + const struct hol_entry *pe = pest->hhstate->prev_entry; + const struct hol_cluster *cl = pest->entry->cluster; + + if (pest->hhstate->sep_groups && pe && pest->entry->group != pe->group) + __argp_fmtstream_putc (pest->stream, '\n'); + + if (cl && cl->header && *cl->header + && (!pe + || (pe->cluster != cl + && !hol_cluster_is_child (pe->cluster, cl)))) + /* If we're changing clusters, then this must be the start of the + ENTRY's cluster unless that is an ancestor of the previous one + (in which case we had just popped into a sub-cluster for a bit). + If so, then print the cluster's header line. */ + { + int old_wm = __argp_fmtstream_wmargin (pest->stream); + print_header (cl->header, cl->argp, pest); + __argp_fmtstream_set_wmargin (pest->stream, old_wm); + } + + pest->first = 0; + } + else + __argp_fmtstream_puts (pest->stream, ", "); + + indent_to (pest->stream, col); +} + +/* Print help for ENTRY to STREAM. */ +static void +hol_entry_help (struct hol_entry *entry, const struct argp_state *state, + argp_fmtstream_t stream, struct hol_help_state *hhstate) +{ + unsigned num; + const struct argp_option *real = entry->opt, *opt; + char *so = entry->short_options; + int have_long_opt = 0; /* We have any long options. */ + /* Saved margins. */ + int old_lm = __argp_fmtstream_set_lmargin (stream, 0); + int old_wm = __argp_fmtstream_wmargin (stream); + /* PEST is a state block holding some of our variables that we'd like to + share with helper functions. */ + struct pentry_state pest; + + pest.entry = entry; + pest.stream = stream; + pest.hhstate = hhstate; + pest.first = 1; + pest.state = state; + + if (! odoc (real)) + for (opt = real, num = entry->num; num > 0; opt++, num--) + if (opt->name && ovisible (opt)) + { + have_long_opt = 1; + break; + } + + /* First emit short options. */ + __argp_fmtstream_set_wmargin (stream, uparams.short_opt_col); /* For truly bizarre cases. */ + for (opt = real, num = entry->num; num > 0; opt++, num--) + if (oshort (opt) && opt->key == *so) + /* OPT has a valid (non shadowed) short option. */ + { + if (ovisible (opt)) + { + comma (uparams.short_opt_col, &pest); + __argp_fmtstream_putc (stream, '-'); + __argp_fmtstream_putc (stream, *so); + if (!have_long_opt || uparams.dup_args) + arg (real, " %s", "[%s]", state->root_argp->argp_domain, stream); + else if (real->arg) + hhstate->suppressed_dup_arg = 1; + } + so++; + } + + /* Now, long options. */ + if (odoc (real)) + /* A `documentation' option. */ + { + __argp_fmtstream_set_wmargin (stream, uparams.doc_opt_col); + for (opt = real, num = entry->num; num > 0; opt++, num--) + if (opt->name && *opt->name && ovisible (opt)) + { + comma (uparams.doc_opt_col, &pest); + /* Calling dgettext here isn't quite right, since sorting will + have been done on the original; but documentation options + should be pretty rare anyway... */ + __argp_fmtstream_puts (stream, + onotrans (opt) ? + opt->name : + dgettext (state->root_argp->argp_domain, + opt->name)); + } + } + else + /* A real long option. */ + { + int first_long_opt = 1; + + __argp_fmtstream_set_wmargin (stream, uparams.long_opt_col); + for (opt = real, num = entry->num; num > 0; opt++, num--) + if (opt->name && ovisible (opt)) + { + comma (uparams.long_opt_col, &pest); + __argp_fmtstream_printf (stream, "--%s", opt->name); + if (first_long_opt || uparams.dup_args) + arg (real, "=%s", "[=%s]", state->root_argp->argp_domain, + stream); + else if (real->arg) + hhstate->suppressed_dup_arg = 1; + } + } + + /* Next, documentation strings. */ + __argp_fmtstream_set_lmargin (stream, 0); + + if (pest.first) + { + /* Didn't print any switches, what's up? */ + if (!oshort (real) && !real->name) + /* This is a group header, print it nicely. */ + print_header (real->doc, entry->argp, &pest); + else + /* Just a totally shadowed option or null header; print nothing. */ + goto cleanup; /* Just return, after cleaning up. */ + } + else + { + const char *tstr = real->doc ? dgettext (state->root_argp->argp_domain, + real->doc) : 0; + const char *fstr = filter_doc (tstr, real->key, entry->argp, state); + if (fstr && *fstr) + { + unsigned int col = __argp_fmtstream_point (stream); + + __argp_fmtstream_set_lmargin (stream, uparams.opt_doc_col); + __argp_fmtstream_set_wmargin (stream, uparams.opt_doc_col); + + if (col > (unsigned int) (uparams.opt_doc_col + 3)) + __argp_fmtstream_putc (stream, '\n'); + else if (col >= (unsigned int) uparams.opt_doc_col) + __argp_fmtstream_puts (stream, " "); + else + indent_to (stream, uparams.opt_doc_col); + + __argp_fmtstream_puts (stream, fstr); + } + if (fstr && fstr != tstr) + free ((char *) fstr); + + /* Reset the left margin. */ + __argp_fmtstream_set_lmargin (stream, 0); + __argp_fmtstream_putc (stream, '\n'); + } + + hhstate->prev_entry = entry; + +cleanup: + __argp_fmtstream_set_lmargin (stream, old_lm); + __argp_fmtstream_set_wmargin (stream, old_wm); +} + +/* Output a long help message about the options in HOL to STREAM. */ +static void +hol_help (struct hol *hol, const struct argp_state *state, + argp_fmtstream_t stream) +{ + unsigned num; + struct hol_entry *entry; + struct hol_help_state hhstate = { 0, 0, 0 }; + + for (entry = hol->entries, num = hol->num_entries; num > 0; entry++, num--) + hol_entry_help (entry, state, stream, &hhstate); + + if (hhstate.suppressed_dup_arg && uparams.dup_args_note) + { + const char *tstr = dgettext (state->root_argp->argp_domain, "\ +Mandatory or optional arguments to long options are also mandatory or \ +optional for any corresponding short options."); + const char *fstr = filter_doc (tstr, ARGP_KEY_HELP_DUP_ARGS_NOTE, + state ? state->root_argp : 0, state); + if (fstr && *fstr) + { + __argp_fmtstream_putc (stream, '\n'); + __argp_fmtstream_puts (stream, fstr); + __argp_fmtstream_putc (stream, '\n'); + } + if (fstr && fstr != tstr) + free ((char *) fstr); + } +} + +/* Helper functions for hol_usage. */ + +/* If OPT is a short option without an arg, append its key to the string + pointer pointer to by COOKIE, and advance the pointer. */ +static int +add_argless_short_opt (const struct argp_option *opt, + const struct argp_option *real, + const char *domain, void *cookie) +{ + char **snao_end = cookie; + if (!(opt->arg || real->arg) + && !((opt->flags | real->flags) & OPTION_NO_USAGE)) + *(*snao_end)++ = opt->key; + return 0; +} + +/* If OPT is a short option with an arg, output a usage entry for it to the + stream pointed at by COOKIE. */ +static int +usage_argful_short_opt (const struct argp_option *opt, + const struct argp_option *real, + const char *domain, void *cookie) +{ + argp_fmtstream_t stream = cookie; + const char *arg = opt->arg; + int flags = opt->flags | real->flags; + + if (! arg) + arg = real->arg; + + if (arg && !(flags & OPTION_NO_USAGE)) + { + arg = dgettext (domain, arg); + + if (flags & OPTION_ARG_OPTIONAL) + __argp_fmtstream_printf (stream, " [-%c[%s]]", opt->key, arg); + else + { + /* Manually do line wrapping so that it (probably) won't + get wrapped at the embedded space. */ + space (stream, 6 + strlen (arg)); + __argp_fmtstream_printf (stream, "[-%c %s]", opt->key, arg); + } + } + + return 0; +} + +/* Output a usage entry for the long option opt to the stream pointed at by + COOKIE. */ +static int +usage_long_opt (const struct argp_option *opt, + const struct argp_option *real, + const char *domain, void *cookie) +{ + argp_fmtstream_t stream = cookie; + const char *arg = opt->arg; + int flags = opt->flags | real->flags; + + if (! arg) + arg = real->arg; + + if (! (flags & OPTION_NO_USAGE) && !odoc (opt)) + { + if (arg) + { + arg = dgettext (domain, arg); + if (flags & OPTION_ARG_OPTIONAL) + __argp_fmtstream_printf (stream, " [--%s[=%s]]", opt->name, arg); + else + __argp_fmtstream_printf (stream, " [--%s=%s]", opt->name, arg); + } + else + __argp_fmtstream_printf (stream, " [--%s]", opt->name); + } + + return 0; +} + +/* Print a short usage description for the arguments in HOL to STREAM. */ +static void +hol_usage (struct hol *hol, argp_fmtstream_t stream) +{ + if (hol->num_entries > 0) + { + unsigned nentries; + struct hol_entry *entry; + char *short_no_arg_opts = alloca (strlen (hol->short_options) + 1); + char *snao_end = short_no_arg_opts; + + /* First we put a list of short options without arguments. */ + for (entry = hol->entries, nentries = hol->num_entries + ; nentries > 0 + ; entry++, nentries--) + hol_entry_short_iterate (entry, add_argless_short_opt, + entry->argp->argp_domain, &snao_end); + if (snao_end > short_no_arg_opts) + { + *snao_end++ = 0; + __argp_fmtstream_printf (stream, " [-%s]", short_no_arg_opts); + } + + /* Now a list of short options *with* arguments. */ + for (entry = hol->entries, nentries = hol->num_entries + ; nentries > 0 + ; entry++, nentries--) + hol_entry_short_iterate (entry, usage_argful_short_opt, + entry->argp->argp_domain, stream); + + /* Finally, a list of long options (whew!). */ + for (entry = hol->entries, nentries = hol->num_entries + ; nentries > 0 + ; entry++, nentries--) + hol_entry_long_iterate (entry, usage_long_opt, + entry->argp->argp_domain, stream); + } +} + +/* Make a HOL containing all levels of options in ARGP. CLUSTER is the + cluster in which ARGP's entries should be clustered, or 0. */ +static struct hol * +argp_hol (const struct argp *argp, struct hol_cluster *cluster) +{ + const struct argp_child *child = argp->children; + struct hol *hol = make_hol (argp, cluster); + if (child) + while (child->argp) + { + struct hol_cluster *child_cluster = + ((child->group || child->header) + /* Put CHILD->argp within its own cluster. */ + ? hol_add_cluster (hol, child->group, child->header, + child - argp->children, cluster, argp) + /* Just merge it into the parent's cluster. */ + : cluster); + hol_append (hol, argp_hol (child->argp, child_cluster)) ; + child++; + } + return hol; +} + +/* Calculate how many different levels with alternative args strings exist in + ARGP. */ +static size_t +argp_args_levels (const struct argp *argp) +{ + size_t levels = 0; + const struct argp_child *child = argp->children; + + if (argp->args_doc && strchr (argp->args_doc, '\n')) + levels++; + + if (child) + while (child->argp) + levels += argp_args_levels ((child++)->argp); + + return levels; +} + +/* Print all the non-option args documented in ARGP to STREAM. Any output is + preceded by a space. LEVELS is a pointer to a byte vector the length + returned by argp_args_levels; it should be initialized to zero, and + updated by this routine for the next call if ADVANCE is true. True is + returned as long as there are more patterns to output. */ +static int +argp_args_usage (const struct argp *argp, const struct argp_state *state, + char **levels, int advance, argp_fmtstream_t stream) +{ + char *our_level = *levels; + int multiple = 0; + const struct argp_child *child = argp->children; + const char *tdoc = dgettext (argp->argp_domain, argp->args_doc), *nl = 0; + const char *fdoc = filter_doc (tdoc, ARGP_KEY_HELP_ARGS_DOC, argp, state); + + if (fdoc) + { + const char *cp = fdoc; + nl = __strchrnul (cp, '\n'); + if (*nl != '\0') + /* This is a `multi-level' args doc; advance to the correct position + as determined by our state in LEVELS, and update LEVELS. */ + { + int i; + multiple = 1; + for (i = 0; i < *our_level; i++) + cp = nl + 1, nl = __strchrnul (cp, '\n'); + (*levels)++; + } + + /* Manually do line wrapping so that it (probably) won't get wrapped at + any embedded spaces. */ + space (stream, 1 + nl - cp); + + __argp_fmtstream_write (stream, cp, nl - cp); + } + if (fdoc && fdoc != tdoc) + free ((char *)fdoc); /* Free user's modified doc string. */ + + if (child) + while (child->argp) + advance = !argp_args_usage ((child++)->argp, state, levels, advance, stream); + + if (advance && multiple) + { + /* Need to increment our level. */ + if (*nl) + /* There's more we can do here. */ + { + (*our_level)++; + advance = 0; /* Our parent shouldn't advance also. */ + } + else if (*our_level > 0) + /* We had multiple levels, but used them up; reset to zero. */ + *our_level = 0; + } + + return !advance; +} + +/* Print the documentation for ARGP to STREAM; if POST is false, then + everything preceeding a `\v' character in the documentation strings (or + the whole string, for those with none) is printed, otherwise, everything + following the `\v' character (nothing for strings without). Each separate + bit of documentation is separated a blank line, and if PRE_BLANK is true, + then the first is as well. If FIRST_ONLY is true, only the first + occurrence is output. Returns true if anything was output. */ +static int +argp_doc (const struct argp *argp, const struct argp_state *state, + int post, int pre_blank, int first_only, + argp_fmtstream_t stream) +{ + const char *text; + const char *inp_text; + size_t inp_text_len = 0; + const char *trans_text; + void *input = 0; + int anything = 0; + const struct argp_child *child = argp->children; + + if (argp->doc) + { + char *vt = strchr (argp->doc, '\v'); + if (vt) + { + if (post) + inp_text = vt + 1; + else + { + inp_text_len = vt - argp->doc; + inp_text = __strndup (argp->doc, inp_text_len); + } + } + else + inp_text = post ? 0 : argp->doc; + trans_text = inp_text ? dgettext (argp->argp_domain, inp_text) : NULL; + } + else + trans_text = inp_text = 0; + + if (argp->help_filter) + /* We have to filter the doc strings. */ + { + input = __argp_input (argp, state); + text = + (*argp->help_filter) (post + ? ARGP_KEY_HELP_POST_DOC + : ARGP_KEY_HELP_PRE_DOC, + trans_text, input); + } + else + text = (const char *) trans_text; + + if (text) + { + if (pre_blank) + __argp_fmtstream_putc (stream, '\n'); + + __argp_fmtstream_puts (stream, text); + + if (__argp_fmtstream_point (stream) > __argp_fmtstream_lmargin (stream)) + __argp_fmtstream_putc (stream, '\n'); + + anything = 1; + } + + if (text && text != trans_text) + free ((char *) text); /* Free TEXT returned from the help filter. */ + + if (inp_text && inp_text_len) + free ((char *) inp_text); /* We copied INP_TEXT, so free it now. */ + + if (post && argp->help_filter) + /* Now see if we have to output a ARGP_KEY_HELP_EXTRA text. */ + { + text = (*argp->help_filter) (ARGP_KEY_HELP_EXTRA, 0, input); + if (text) + { + if (anything || pre_blank) + __argp_fmtstream_putc (stream, '\n'); + __argp_fmtstream_puts (stream, text); + free ((char *) text); + if (__argp_fmtstream_point (stream) + > __argp_fmtstream_lmargin (stream)) + __argp_fmtstream_putc (stream, '\n'); + anything = 1; + } + } + + if (child) + while (child->argp && !(first_only && anything)) + anything |= + argp_doc ((child++)->argp, state, + post, anything || pre_blank, first_only, + stream); + + return anything; +} + +/* Output a usage message for ARGP to STREAM. If called from + argp_state_help, STATE is the relevent parsing state. FLAGS are from the + set ARGP_HELP_*. NAME is what to use wherever a `program name' is + needed. */ +static void +_help (const struct argp *argp, const struct argp_state *state, FILE *stream, + unsigned flags, char *name) +{ + int anything = 0; /* Whether we've output anything. */ + struct hol *hol = 0; + argp_fmtstream_t fs; + + if (! stream) + return; + +#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE) + __flockfile (stream); +#endif + + if (! uparams.valid) + fill_in_uparams (state); + + fs = __argp_make_fmtstream (stream, 0, uparams.rmargin, 0); + if (! fs) + { +#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE) + __funlockfile (stream); +#endif + return; + } + + if (flags & (ARGP_HELP_USAGE | ARGP_HELP_SHORT_USAGE | ARGP_HELP_LONG)) + { + hol = argp_hol (argp, 0); + + /* If present, these options always come last. */ + hol_set_group (hol, "help", -1); + hol_set_group (hol, "version", -1); + + hol_sort (hol); + } + + if (flags & (ARGP_HELP_USAGE | ARGP_HELP_SHORT_USAGE)) + /* Print a short `Usage:' message. */ + { + int first_pattern = 1, more_patterns; + size_t num_pattern_levels = argp_args_levels (argp); + char *pattern_levels = alloca (num_pattern_levels); + + memset (pattern_levels, 0, num_pattern_levels); + + do + { + int old_lm; + int old_wm = __argp_fmtstream_set_wmargin (fs, uparams.usage_indent); + char *levels = pattern_levels; + + if (first_pattern) + __argp_fmtstream_printf (fs, "%s %s", + dgettext (argp->argp_domain, "Usage:"), + name); + else + __argp_fmtstream_printf (fs, "%s %s", + dgettext (argp->argp_domain, " or: "), + name); + + /* We set the lmargin as well as the wmargin, because hol_usage + manually wraps options with newline to avoid annoying breaks. */ + old_lm = __argp_fmtstream_set_lmargin (fs, uparams.usage_indent); + + if (flags & ARGP_HELP_SHORT_USAGE) + /* Just show where the options go. */ + { + if (hol->num_entries > 0) + __argp_fmtstream_puts (fs, dgettext (argp->argp_domain, + " [OPTION...]")); + } + else + /* Actually print the options. */ + { + hol_usage (hol, fs); + flags |= ARGP_HELP_SHORT_USAGE; /* But only do so once. */ + } + + more_patterns = argp_args_usage (argp, state, &levels, 1, fs); + + __argp_fmtstream_set_wmargin (fs, old_wm); + __argp_fmtstream_set_lmargin (fs, old_lm); + + __argp_fmtstream_putc (fs, '\n'); + anything = 1; + + first_pattern = 0; + } + while (more_patterns); + } + + if (flags & ARGP_HELP_PRE_DOC) + anything |= argp_doc (argp, state, 0, 0, 1, fs); + + if (flags & ARGP_HELP_SEE) + { + __argp_fmtstream_printf (fs, dgettext (argp->argp_domain, "\ +Try `%s --help' or `%s --usage' for more information.\n"), + name, name); + anything = 1; + } + + if (flags & ARGP_HELP_LONG) + /* Print a long, detailed help message. */ + { + /* Print info about all the options. */ + if (hol->num_entries > 0) + { + if (anything) + __argp_fmtstream_putc (fs, '\n'); + hol_help (hol, state, fs); + anything = 1; + } + } + + if (flags & ARGP_HELP_POST_DOC) + /* Print any documentation strings at the end. */ + anything |= argp_doc (argp, state, 1, anything, 0, fs); + + if ((flags & ARGP_HELP_BUG_ADDR) && argp_program_bug_address) + { + if (anything) + __argp_fmtstream_putc (fs, '\n'); + __argp_fmtstream_printf (fs, dgettext (argp->argp_domain, + "Report bugs to %s.\n"), + argp_program_bug_address); + anything = 1; + } + +#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE) + __funlockfile (stream); +#endif + + if (hol) + hol_free (hol); + + __argp_fmtstream_free (fs); +} + +/* Output a usage message for ARGP to STREAM. FLAGS are from the set + ARGP_HELP_*. NAME is what to use wherever a `program name' is needed. */ +void __argp_help (const struct argp *argp, FILE *stream, + unsigned flags, char *name) +{ + struct argp_state state; + memset (&state, 0, sizeof state); + state.root_argp = argp; + _help (argp, &state, stream, flags, name); +} +#ifdef weak_alias +weak_alias (__argp_help, argp_help) +#endif + +#if ! (defined _LIBC || HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME) +char * +__argp_short_program_name (void) +{ +# if HAVE_DECL_PROGRAM_INVOCATION_NAME + return __argp_base_name (program_invocation_name); +# else + /* FIXME: What now? Miles suggests that it is better to use NULL, + but currently the value is passed on directly to fputs_unlocked, + so that requires more changes. */ +# if __GNUC__ +# warning No reasonable value to return +# endif /* __GNUC__ */ + return ""; +# endif +} +#endif + +/* Output, if appropriate, a usage message for STATE to STREAM. FLAGS are + from the set ARGP_HELP_*. */ +void +__argp_state_help (const struct argp_state *state, FILE *stream, unsigned flags) +{ + if ((!state || ! (state->flags & ARGP_NO_ERRS)) && stream) + { + if (state && (state->flags & ARGP_LONG_ONLY)) + flags |= ARGP_HELP_LONG_ONLY; + + _help (state ? state->root_argp : 0, state, stream, flags, + state ? state->name : __argp_short_program_name ()); + + if (!state || ! (state->flags & ARGP_NO_EXIT)) + { + if (flags & ARGP_HELP_EXIT_ERR) + exit (argp_err_exit_status); + if (flags & ARGP_HELP_EXIT_OK) + exit (0); + } + } +} +#ifdef weak_alias +weak_alias (__argp_state_help, argp_state_help) +#endif + +/* If appropriate, print the printf string FMT and following args, preceded + by the program name and `:', to stderr, and followed by a `Try ... --help' + message, then exit (1). */ +void +__argp_error (const struct argp_state *state, const char *fmt, ...) +{ + if (!state || !(state->flags & ARGP_NO_ERRS)) + { + FILE *stream = state ? state->err_stream : stderr; + + if (stream) + { + va_list ap; + +#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE) + __flockfile (stream); +#endif + + va_start (ap, fmt); + +#ifdef USE_IN_LIBIO + if (_IO_fwide (stream, 0) > 0) + { + char *buf; + + if (__asprintf (&buf, fmt, ap) < 0) + buf = NULL; + + __fwprintf (stream, L"%s: %s\n", + state ? state->name : __argp_short_program_name (), + buf); + + free (buf); + } + else +#endif + { + fputs_unlocked (state + ? state->name : __argp_short_program_name (), + stream); + putc_unlocked (':', stream); + putc_unlocked (' ', stream); + + vfprintf (stream, fmt, ap); + + putc_unlocked ('\n', stream); + } + + __argp_state_help (state, stream, ARGP_HELP_STD_ERR); + + va_end (ap); + +#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE) + __funlockfile (stream); +#endif + } + } +} +#ifdef weak_alias +weak_alias (__argp_error, argp_error) +#endif + +/* Similar to the standard gnu error-reporting function error(), but will + respect the ARGP_NO_EXIT and ARGP_NO_ERRS flags in STATE, and will print + to STATE->err_stream. This is useful for argument parsing code that is + shared between program startup (when exiting is desired) and runtime + option parsing (when typically an error code is returned instead). The + difference between this function and argp_error is that the latter is for + *parsing errors*, and the former is for other problems that occur during + parsing but don't reflect a (syntactic) problem with the input. */ +void +__argp_failure (const struct argp_state *state, int status, int errnum, + const char *fmt, ...) +{ + if (!state || !(state->flags & ARGP_NO_ERRS)) + { + FILE *stream = state ? state->err_stream : stderr; + + if (stream) + { +#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE) + __flockfile (stream); +#endif + +#ifdef USE_IN_LIBIO + if (_IO_fwide (stream, 0) > 0) + __fwprintf (stream, L"%s", + state ? state->name : __argp_short_program_name ()); + else +#endif + fputs_unlocked (state + ? state->name : __argp_short_program_name (), + stream); + + if (fmt) + { + va_list ap; + + va_start (ap, fmt); +#ifdef USE_IN_LIBIO + if (_IO_fwide (stream, 0) > 0) + { + char *buf; + + if (__asprintf (&buf, fmt, ap) < 0) + buf = NULL; + + __fwprintf (stream, L": %s", buf); + + free (buf); + } + else +#endif + { + putc_unlocked (':', stream); + putc_unlocked (' ', stream); + + vfprintf (stream, fmt, ap); + } + + va_end (ap); + } + + if (errnum) + { + char buf[200]; + +#ifdef USE_IN_LIBIO + if (_IO_fwide (stream, 0) > 0) + __fwprintf (stream, L": %s", + __strerror_r (errnum, buf, sizeof (buf))); + else +#endif + { + char const *s = NULL; + putc_unlocked (':', stream); + putc_unlocked (' ', stream); +#if _LIBC || (HAVE_DECL_STRERROR_R && STRERROR_R_CHAR_P) + s = __strerror_r (errnum, buf, sizeof buf); +#elif HAVE_DECL_STRERROR_R + if (__strerror_r (errnum, buf, sizeof buf) == 0) + s = buf; +#endif +#if !_LIBC + if (! s && ! (s = strerror (errnum))) + s = dgettext (state->root_argp->argp_domain, + "Unknown system error"); +#endif + fputs (s, stream); + } + } + +#ifdef USE_IN_LIBIO + if (_IO_fwide (stream, 0) > 0) + putwc_unlocked (L'\n', stream); + else +#endif + putc_unlocked ('\n', stream); + +#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE) + __funlockfile (stream); +#endif + + if (status && (!state || !(state->flags & ARGP_NO_EXIT))) + exit (status); + } + } +} +#ifdef weak_alias +weak_alias (__argp_failure, argp_failure) +#endif diff --git a/gnulib/argp-namefrob.h b/gnulib/argp-namefrob.h new file mode 100644 index 000000000..24581a626 --- /dev/null +++ b/gnulib/argp-namefrob.h @@ -0,0 +1,157 @@ +/* Name frobnication for compiling argp outside of glibc + Copyright (C) 1997, 2003, 2007, 2009, 2010 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Written by Miles Bader . + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#if !_LIBC +/* This code is written for inclusion in gnu-libc, and uses names in the + namespace reserved for libc. If we're not compiling in libc, define those + names to be the normal ones instead. */ + +/* argp-parse functions */ +#undef __argp_parse +#define __argp_parse argp_parse +#undef __option_is_end +#define __option_is_end _option_is_end +#undef __option_is_short +#define __option_is_short _option_is_short +#undef __argp_input +#define __argp_input _argp_input + +/* argp-help functions */ +#undef __argp_help +#define __argp_help argp_help +#undef __argp_error +#define __argp_error argp_error +#undef __argp_failure +#define __argp_failure argp_failure +#undef __argp_state_help +#define __argp_state_help argp_state_help +#undef __argp_usage +#define __argp_usage argp_usage + +/* argp-fmtstream functions */ +#undef __argp_make_fmtstream +#define __argp_make_fmtstream argp_make_fmtstream +#undef __argp_fmtstream_free +#define __argp_fmtstream_free argp_fmtstream_free +#undef __argp_fmtstream_putc +#define __argp_fmtstream_putc argp_fmtstream_putc +#undef __argp_fmtstream_puts +#define __argp_fmtstream_puts argp_fmtstream_puts +#undef __argp_fmtstream_write +#define __argp_fmtstream_write argp_fmtstream_write +#undef __argp_fmtstream_printf +#define __argp_fmtstream_printf argp_fmtstream_printf +#undef __argp_fmtstream_set_lmargin +#define __argp_fmtstream_set_lmargin argp_fmtstream_set_lmargin +#undef __argp_fmtstream_set_rmargin +#define __argp_fmtstream_set_rmargin argp_fmtstream_set_rmargin +#undef __argp_fmtstream_set_wmargin +#define __argp_fmtstream_set_wmargin argp_fmtstream_set_wmargin +#undef __argp_fmtstream_point +#define __argp_fmtstream_point argp_fmtstream_point +#undef __argp_fmtstream_update +#define __argp_fmtstream_update _argp_fmtstream_update +#undef __argp_fmtstream_ensure +#define __argp_fmtstream_ensure _argp_fmtstream_ensure +#undef __argp_fmtstream_lmargin +#define __argp_fmtstream_lmargin argp_fmtstream_lmargin +#undef __argp_fmtstream_rmargin +#define __argp_fmtstream_rmargin argp_fmtstream_rmargin +#undef __argp_fmtstream_wmargin +#define __argp_fmtstream_wmargin argp_fmtstream_wmargin + +/* normal libc functions we call */ +#undef __flockfile +#define __flockfile flockfile +#undef __funlockfile +#define __funlockfile funlockfile +#undef __mempcpy +#define __mempcpy mempcpy +#undef __sleep +#define __sleep sleep +#undef __strcasecmp +#define __strcasecmp strcasecmp +#undef __strchrnul +#define __strchrnul strchrnul +#undef __strerror_r +#define __strerror_r strerror_r +#undef __strndup +#define __strndup strndup +#undef __vsnprintf +#define __vsnprintf vsnprintf + +#if defined(HAVE_DECL_CLEARERR_UNLOCKED) && !HAVE_DECL_CLEARERR_UNLOCKED +# define clearerr_unlocked(x) clearerr (x) +#endif +#if defined(HAVE_DECL_FEOF_UNLOCKED) && !HAVE_DECL_FEOF_UNLOCKED +# define feof_unlocked(x) feof (x) +# endif +#if defined(HAVE_DECL_FERROR_UNLOCKED) && !HAVE_DECL_FERROR_UNLOCKED +# define ferror_unlocked(x) ferror (x) +# endif +#if defined(HAVE_DECL_FFLUSH_UNLOCKED) && !HAVE_DECL_FFLUSH_UNLOCKED +# define fflush_unlocked(x) fflush (x) +# endif +#if defined(HAVE_DECL_FGETS_UNLOCKED) && !HAVE_DECL_FGETS_UNLOCKED +# define fgets_unlocked(x,y,z) fgets (x,y,z) +# endif +#if defined(HAVE_DECL_FPUTC_UNLOCKED) && !HAVE_DECL_FPUTC_UNLOCKED +# define fputc_unlocked(x,y) fputc (x,y) +# endif +#if defined(HAVE_DECL_FPUTS_UNLOCKED) && !HAVE_DECL_FPUTS_UNLOCKED +# define fputs_unlocked(x,y) fputs (x,y) +# endif +#if defined(HAVE_DECL_FREAD_UNLOCKED) && !HAVE_DECL_FREAD_UNLOCKED +# define fread_unlocked(w,x,y,z) fread (w,x,y,z) +# endif +#if defined(HAVE_DECL_FWRITE_UNLOCKED) && !HAVE_DECL_FWRITE_UNLOCKED +# define fwrite_unlocked(w,x,y,z) fwrite (w,x,y,z) +# endif +#if defined(HAVE_DECL_GETC_UNLOCKED) && !HAVE_DECL_GETC_UNLOCKED +# define getc_unlocked(x) getc (x) +# endif +#if defined(HAVE_DECL_GETCHAR_UNLOCKED) && !HAVE_DECL_GETCHAR_UNLOCKED +# define getchar_unlocked() getchar () +# endif +#if defined(HAVE_DECL_PUTC_UNLOCKED) && !HAVE_DECL_PUTC_UNLOCKED +# define putc_unlocked(x,y) putc (x,y) +# endif +#if defined(HAVE_DECL_PUTCHAR_UNLOCKED) && !HAVE_DECL_PUTCHAR_UNLOCKED +# define putchar_unlocked(x) putchar (x) +# endif + +#endif /* !_LIBC */ + +#ifndef __set_errno +#define __set_errno(e) (errno = (e)) +#endif + +#if defined GNULIB_ARGP_DISABLE_DIRNAME +# define __argp_base_name(arg) arg +#elif defined GNULIB_ARGP_EXTERN_BASENAME +extern char *__argp_base_name (const char *arg); +#else +# include "dirname.h" +# define __argp_base_name last_component +#endif + +#if defined _LIBC || HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME +# define __argp_short_program_name() (program_invocation_short_name) +#else +extern char *__argp_short_program_name (void); +#endif diff --git a/gnulib/argp-parse.c b/gnulib/argp-parse.c new file mode 100644 index 000000000..a1cbf884e --- /dev/null +++ b/gnulib/argp-parse.c @@ -0,0 +1,952 @@ +/* Hierarchial argument parsing, layered over getopt + Copyright (C) 1995-2000, 2002-2004, 2009-2010 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Written by Miles Bader . + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef _LIBC +# include +# undef dgettext +# define dgettext(domain, msgid) \ + INTUSE(__dcgettext) (domain, msgid, LC_MESSAGES) +#else +# include "gettext.h" +#endif +#define N_(msgid) msgid + +#include "argp.h" +#include "argp-namefrob.h" + +#define alignof(type) offsetof (struct { char c; type x; }, x) +#define alignto(n, d) ((((n) + (d) - 1) / (d)) * (d)) + +/* Getopt return values. */ +#define KEY_END (-1) /* The end of the options. */ +#define KEY_ARG 1 /* A non-option argument. */ +#define KEY_ERR '?' /* An error parsing the options. */ + +/* The meta-argument used to prevent any further arguments being interpreted + as options. */ +#define QUOTE "--" + +/* The number of bits we steal in a long-option value for our own use. */ +#define GROUP_BITS CHAR_BIT + +/* The number of bits available for the user value. */ +#define USER_BITS ((sizeof ((struct option *)0)->val * CHAR_BIT) - GROUP_BITS) +#define USER_MASK ((1 << USER_BITS) - 1) + +/* EZ alias for ARGP_ERR_UNKNOWN. */ +#define EBADKEY ARGP_ERR_UNKNOWN + +/* Default options. */ + +/* When argp is given the --HANG switch, _ARGP_HANG is set and argp will sleep + for one second intervals, decrementing _ARGP_HANG until it's zero. Thus + you can force the program to continue by attaching a debugger and setting + it to 0 yourself. */ +static volatile int _argp_hang; + +#define OPT_PROGNAME -2 +#define OPT_USAGE -3 +#define OPT_HANG -4 + +static const struct argp_option argp_default_options[] = +{ + {"help", '?', 0, 0, N_("give this help list"), -1}, + {"usage", OPT_USAGE, 0, 0, N_("give a short usage message"), 0}, + {"program-name",OPT_PROGNAME,N_("NAME"), OPTION_HIDDEN, N_("set the program name"), 0}, + {"HANG", OPT_HANG, N_("SECS"), OPTION_ARG_OPTIONAL | OPTION_HIDDEN, + N_("hang for SECS seconds (default 3600)"), 0}, + {NULL, 0, 0, 0, NULL, 0} +}; + +static error_t +argp_default_parser (int key, char *arg, struct argp_state *state) +{ + switch (key) + { + case '?': + __argp_state_help (state, state->out_stream, ARGP_HELP_STD_HELP); + break; + case OPT_USAGE: + __argp_state_help (state, state->out_stream, + ARGP_HELP_USAGE | ARGP_HELP_EXIT_OK); + break; + + case OPT_PROGNAME: /* Set the program name. */ +#if defined _LIBC || HAVE_DECL_PROGRAM_INVOCATION_NAME + program_invocation_name = arg; +#endif + /* [Note that some systems only have PROGRAM_INVOCATION_SHORT_NAME (aka + __PROGNAME), in which case, PROGRAM_INVOCATION_NAME is just defined + to be that, so we have to be a bit careful here.] */ + + /* Update what we use for messages. */ + state->name = __argp_base_name (arg); + +#if defined _LIBC || HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME + program_invocation_short_name = state->name; +#endif + + if ((state->flags & (ARGP_PARSE_ARGV0 | ARGP_NO_ERRS)) + == ARGP_PARSE_ARGV0) + /* Update what getopt uses too. */ + state->argv[0] = arg; + + break; + + case OPT_HANG: + _argp_hang = atoi (arg ? arg : "3600"); + while (_argp_hang-- > 0) + __sleep (1); + break; + + default: + return EBADKEY; + } + return 0; +} + +static const struct argp argp_default_argp = + {argp_default_options, &argp_default_parser, NULL, NULL, NULL, NULL, "libc"}; + + +static const struct argp_option argp_version_options[] = +{ + {"version", 'V', 0, 0, N_("print program version"), -1}, + {NULL, 0, 0, 0, NULL, 0} +}; + +static error_t +argp_version_parser (int key, char *arg, struct argp_state *state) +{ + switch (key) + { + case 'V': + if (argp_program_version_hook) + (*argp_program_version_hook) (state->out_stream, state); + else if (argp_program_version) + fprintf (state->out_stream, "%s\n", argp_program_version); + else + __argp_error (state, dgettext (state->root_argp->argp_domain, + "(PROGRAM ERROR) No version known!?")); + if (! (state->flags & ARGP_NO_EXIT)) + exit (0); + break; + default: + return EBADKEY; + } + return 0; +} + +static const struct argp argp_version_argp = + {argp_version_options, &argp_version_parser, NULL, NULL, NULL, NULL, "libc"}; + +/* Returns the offset into the getopt long options array LONG_OPTIONS of a + long option with called NAME, or -1 if none is found. Passing NULL as + NAME will return the number of options. */ +static int +find_long_option (struct option *long_options, const char *name) +{ + struct option *l = long_options; + while (l->name != NULL) + if (name != NULL && strcmp (l->name, name) == 0) + return l - long_options; + else + l++; + if (name == NULL) + return l - long_options; + else + return -1; +} + + +/* The state of a `group' during parsing. Each group corresponds to a + particular argp structure from the tree of such descending from the top + level argp passed to argp_parse. */ +struct group +{ + /* This group's parsing function. */ + argp_parser_t parser; + + /* Which argp this group is from. */ + const struct argp *argp; + + /* Points to the point in SHORT_OPTS corresponding to the end of the short + options for this group. We use it to determine from which group a + particular short options is from. */ + char *short_end; + + /* The number of non-option args sucessfully handled by this parser. */ + unsigned args_processed; + + /* This group's parser's parent's group. */ + struct group *parent; + unsigned parent_index; /* And the our position in the parent. */ + + /* These fields are swapped into and out of the state structure when + calling this group's parser. */ + void *input, **child_inputs; + void *hook; +}; + +/* Call GROUP's parser with KEY and ARG, swapping any group-specific info + from STATE before calling, and back into state afterwards. If GROUP has + no parser, EBADKEY is returned. */ +static error_t +group_parse (struct group *group, struct argp_state *state, int key, char *arg) +{ + if (group->parser) + { + error_t err; + state->hook = group->hook; + state->input = group->input; + state->child_inputs = group->child_inputs; + state->arg_num = group->args_processed; + err = (*group->parser)(key, arg, state); + group->hook = state->hook; + return err; + } + else + return EBADKEY; +} + +struct parser +{ + const struct argp *argp; + + /* SHORT_OPTS is the getopt short options string for the union of all the + groups of options. */ + char *short_opts; + /* LONG_OPTS is the array of getop long option structures for the union of + all the groups of options. */ + struct option *long_opts; + /* OPT_DATA is the getopt data used for the re-entrant getopt. */ + struct _getopt_data opt_data; + + /* States of the various parsing groups. */ + struct group *groups; + /* The end of the GROUPS array. */ + struct group *egroup; + /* An vector containing storage for the CHILD_INPUTS field in all groups. */ + void **child_inputs; + + /* True if we think using getopt is still useful; if false, then + remaining arguments are just passed verbatim with ARGP_KEY_ARG. This is + cleared whenever getopt returns KEY_END, but may be set again if the user + moves the next argument pointer backwards. */ + int try_getopt; + + /* State block supplied to parsing routines. */ + struct argp_state state; + + /* Memory used by this parser. */ + void *storage; +}; + +/* The next usable entries in the various parser tables being filled in by + convert_options. */ +struct parser_convert_state +{ + struct parser *parser; + char *short_end; + struct option *long_end; + void **child_inputs_end; +}; + +/* Converts all options in ARGP (which is put in GROUP) and ancestors + into getopt options stored in SHORT_OPTS and LONG_OPTS; SHORT_END and + CVT->LONG_END are the points at which new options are added. Returns the + next unused group entry. CVT holds state used during the conversion. */ +static struct group * +convert_options (const struct argp *argp, + struct group *parent, unsigned parent_index, + struct group *group, struct parser_convert_state *cvt) +{ + /* REAL is the most recent non-alias value of OPT. */ + const struct argp_option *real = argp->options; + const struct argp_child *children = argp->children; + + if (real || argp->parser) + { + const struct argp_option *opt; + + if (real) + for (opt = real; !__option_is_end (opt); opt++) + { + if (! (opt->flags & OPTION_ALIAS)) + /* OPT isn't an alias, so we can use values from it. */ + real = opt; + + if (! (real->flags & OPTION_DOC)) + /* A real option (not just documentation). */ + { + if (__option_is_short (opt)) + /* OPT can be used as a short option. */ + { + *cvt->short_end++ = opt->key; + if (real->arg) + { + *cvt->short_end++ = ':'; + if (real->flags & OPTION_ARG_OPTIONAL) + *cvt->short_end++ = ':'; + } + *cvt->short_end = '\0'; /* keep 0 terminated */ + } + + if (opt->name + && find_long_option (cvt->parser->long_opts, opt->name) < 0) + /* OPT can be used as a long option. */ + { + cvt->long_end->name = opt->name; + cvt->long_end->has_arg = + (real->arg + ? (real->flags & OPTION_ARG_OPTIONAL + ? optional_argument + : required_argument) + : no_argument); + cvt->long_end->flag = 0; + /* we add a disambiguating code to all the user's + values (which is removed before we actually call + the function to parse the value); this means that + the user loses use of the high 8 bits in all his + values (the sign of the lower bits is preserved + however)... */ + cvt->long_end->val = + ((opt->key ? opt->key : real->key) & USER_MASK) + + (((group - cvt->parser->groups) + 1) << USER_BITS); + + /* Keep the LONG_OPTS list terminated. */ + (++cvt->long_end)->name = NULL; + } + } + } + + group->parser = argp->parser; + group->argp = argp; + group->short_end = cvt->short_end; + group->args_processed = 0; + group->parent = parent; + group->parent_index = parent_index; + group->input = 0; + group->hook = 0; + group->child_inputs = 0; + + if (children) + /* Assign GROUP's CHILD_INPUTS field some space from + CVT->child_inputs_end.*/ + { + unsigned num_children = 0; + while (children[num_children].argp) + num_children++; + group->child_inputs = cvt->child_inputs_end; + cvt->child_inputs_end += num_children; + } + + parent = group++; + } + else + parent = 0; + + if (children) + { + unsigned index = 0; + while (children->argp) + group = + convert_options (children++->argp, parent, index++, group, cvt); + } + + return group; +} + +/* Find the merged set of getopt options, with keys appropiately prefixed. */ +static void +parser_convert (struct parser *parser, const struct argp *argp, int flags) +{ + struct parser_convert_state cvt; + + cvt.parser = parser; + cvt.short_end = parser->short_opts; + cvt.long_end = parser->long_opts; + cvt.child_inputs_end = parser->child_inputs; + + if (flags & ARGP_IN_ORDER) + *cvt.short_end++ = '-'; + else if (flags & ARGP_NO_ARGS) + *cvt.short_end++ = '+'; + *cvt.short_end = '\0'; + + cvt.long_end->name = NULL; + + parser->argp = argp; + + if (argp) + parser->egroup = convert_options (argp, 0, 0, parser->groups, &cvt); + else + parser->egroup = parser->groups; /* No parsers at all! */ +} + +/* Lengths of various parser fields which we will allocated. */ +struct parser_sizes +{ + size_t short_len; /* Getopt short options string. */ + size_t long_len; /* Getopt long options vector. */ + size_t num_groups; /* Group structures we allocate. */ + size_t num_child_inputs; /* Child input slots. */ +}; + +/* For ARGP, increments the NUM_GROUPS field in SZS by the total number of + argp structures descended from it, and the SHORT_LEN & LONG_LEN fields by + the maximum lengths of the resulting merged getopt short options string and + long-options array, respectively. */ +static void +calc_sizes (const struct argp *argp, struct parser_sizes *szs) +{ + const struct argp_child *child = argp->children; + const struct argp_option *opt = argp->options; + + if (opt || argp->parser) + { + szs->num_groups++; + if (opt) + { + int num_opts = 0; + while (!__option_is_end (opt++)) + num_opts++; + szs->short_len += num_opts * 3; /* opt + up to 2 `:'s */ + szs->long_len += num_opts; + } + } + + if (child) + while (child->argp) + { + calc_sizes ((child++)->argp, szs); + szs->num_child_inputs++; + } +} + +/* Initializes PARSER to parse ARGP in a manner described by FLAGS. */ +static error_t +parser_init (struct parser *parser, const struct argp *argp, + int argc, char **argv, int flags, void *input) +{ + error_t err = 0; + struct group *group; + struct parser_sizes szs; + struct _getopt_data opt_data = _GETOPT_DATA_INITIALIZER; + char *storage; + size_t glen, gsum; + size_t clen, csum; + size_t llen, lsum; + size_t slen, ssum; + + szs.short_len = (flags & ARGP_NO_ARGS) ? 0 : 1; + szs.long_len = 0; + szs.num_groups = 0; + szs.num_child_inputs = 0; + + if (argp) + calc_sizes (argp, &szs); + + /* Lengths of the various bits of storage used by PARSER. */ + glen = (szs.num_groups + 1) * sizeof (struct group); + clen = szs.num_child_inputs * sizeof (void *); + llen = (szs.long_len + 1) * sizeof (struct option); + slen = szs.short_len + 1; + + /* Sums of previous lengths, properly aligned. There's no need to + align gsum, since struct group is aligned at least as strictly as + void * (since it contains a void * member). And there's no need + to align lsum, since struct option is aligned at least as + strictly as char. */ + gsum = glen; + csum = alignto (gsum + clen, alignof (struct option)); + lsum = csum + llen; + ssum = lsum + slen; + + parser->storage = malloc (ssum); + if (! parser->storage) + return ENOMEM; + + storage = parser->storage; + parser->groups = parser->storage; + parser->child_inputs = (void **) (storage + gsum); + parser->long_opts = (struct option *) (storage + csum); + parser->short_opts = storage + lsum; + parser->opt_data = opt_data; + + memset (parser->child_inputs, 0, clen); + parser_convert (parser, argp, flags); + + memset (&parser->state, 0, sizeof (struct argp_state)); + parser->state.root_argp = parser->argp; + parser->state.argc = argc; + parser->state.argv = argv; + parser->state.flags = flags; + parser->state.err_stream = stderr; + parser->state.out_stream = stdout; + parser->state.next = 0; /* Tell getopt to initialize. */ + parser->state.pstate = parser; + + parser->try_getopt = 1; + + /* Call each parser for the first time, giving it a chance to propagate + values to child parsers. */ + if (parser->groups < parser->egroup) + parser->groups->input = input; + for (group = parser->groups; + group < parser->egroup && (!err || err == EBADKEY); + group++) + { + if (group->parent) + /* If a child parser, get the initial input value from the parent. */ + group->input = group->parent->child_inputs[group->parent_index]; + + if (!group->parser + && group->argp->children && group->argp->children->argp) + /* For the special case where no parsing function is supplied for an + argp, propagate its input to its first child, if any (this just + makes very simple wrapper argps more convenient). */ + group->child_inputs[0] = group->input; + + err = group_parse (group, &parser->state, ARGP_KEY_INIT, 0); + } + if (err == EBADKEY) + err = 0; /* Some parser didn't understand. */ + + if (err) + return err; + + if (parser->state.flags & ARGP_NO_ERRS) + { + parser->opt_data.opterr = 0; + if (parser->state.flags & ARGP_PARSE_ARGV0) + /* getopt always skips ARGV[0], so we have to fake it out. As long + as OPTERR is 0, then it shouldn't actually try to access it. */ + parser->state.argv--, parser->state.argc++; + } + else + parser->opt_data.opterr = 1; /* Print error messages. */ + + if (parser->state.argv == argv && argv[0]) + /* There's an argv[0]; use it for messages. */ + parser->state.name = __argp_base_name (argv[0]); + else + parser->state.name = __argp_short_program_name (); + + return 0; +} + +/* Free any storage consumed by PARSER (but not PARSER itself). */ +static error_t +parser_finalize (struct parser *parser, + error_t err, int arg_ebadkey, int *end_index) +{ + struct group *group; + + if (err == EBADKEY && arg_ebadkey) + /* Suppress errors generated by unparsed arguments. */ + err = 0; + + if (! err) + { + if (parser->state.next == parser->state.argc) + /* We successfully parsed all arguments! Call all the parsers again, + just a few more times... */ + { + for (group = parser->groups; + group < parser->egroup && (!err || err==EBADKEY); + group++) + if (group->args_processed == 0) + err = group_parse (group, &parser->state, ARGP_KEY_NO_ARGS, 0); + for (group = parser->egroup - 1; + group >= parser->groups && (!err || err==EBADKEY); + group--) + err = group_parse (group, &parser->state, ARGP_KEY_END, 0); + + if (err == EBADKEY) + err = 0; /* Some parser didn't understand. */ + + /* Tell the user that all arguments are parsed. */ + if (end_index) + *end_index = parser->state.next; + } + else if (end_index) + /* Return any remaining arguments to the user. */ + *end_index = parser->state.next; + else + /* No way to return the remaining arguments, they must be bogus. */ + { + if (!(parser->state.flags & ARGP_NO_ERRS) + && parser->state.err_stream) + fprintf (parser->state.err_stream, + dgettext (parser->argp->argp_domain, + "%s: Too many arguments\n"), + parser->state.name); + err = EBADKEY; + } + } + + /* Okay, we're all done, with either an error or success; call the parsers + to indicate which one. */ + + if (err) + { + /* Maybe print an error message. */ + if (err == EBADKEY) + /* An appropriate message describing what the error was should have + been printed earlier. */ + __argp_state_help (&parser->state, parser->state.err_stream, + ARGP_HELP_STD_ERR); + + /* Since we didn't exit, give each parser an error indication. */ + for (group = parser->groups; group < parser->egroup; group++) + group_parse (group, &parser->state, ARGP_KEY_ERROR, 0); + } + else + /* Notify parsers of success, and propagate back values from parsers. */ + { + /* We pass over the groups in reverse order so that child groups are + given a chance to do there processing before passing back a value to + the parent. */ + for (group = parser->egroup - 1 + ; group >= parser->groups && (!err || err == EBADKEY) + ; group--) + err = group_parse (group, &parser->state, ARGP_KEY_SUCCESS, 0); + if (err == EBADKEY) + err = 0; /* Some parser didn't understand. */ + } + + /* Call parsers once more, to do any final cleanup. Errors are ignored. */ + for (group = parser->egroup - 1; group >= parser->groups; group--) + group_parse (group, &parser->state, ARGP_KEY_FINI, 0); + + if (err == EBADKEY) + err = EINVAL; + + free (parser->storage); + + return err; +} + +/* Call the user parsers to parse the non-option argument VAL, at the current + position, returning any error. The state NEXT pointer is assumed to have + been adjusted (by getopt) to point after this argument; this function will + adjust it correctly to reflect however many args actually end up being + consumed. */ +static error_t +parser_parse_arg (struct parser *parser, char *val) +{ + /* Save the starting value of NEXT, first adjusting it so that the arg + we're parsing is again the front of the arg vector. */ + int index = --parser->state.next; + error_t err = EBADKEY; + struct group *group; + int key = 0; /* Which of ARGP_KEY_ARG[S] we used. */ + + /* Try to parse the argument in each parser. */ + for (group = parser->groups + ; group < parser->egroup && err == EBADKEY + ; group++) + { + parser->state.next++; /* For ARGP_KEY_ARG, consume the arg. */ + key = ARGP_KEY_ARG; + err = group_parse (group, &parser->state, key, val); + + if (err == EBADKEY) + /* This parser doesn't like ARGP_KEY_ARG; try ARGP_KEY_ARGS instead. */ + { + parser->state.next--; /* For ARGP_KEY_ARGS, put back the arg. */ + key = ARGP_KEY_ARGS; + err = group_parse (group, &parser->state, key, 0); + } + } + + if (! err) + { + if (key == ARGP_KEY_ARGS) + /* The default for ARGP_KEY_ARGS is to assume that if NEXT isn't + changed by the user, *all* arguments should be considered + consumed. */ + parser->state.next = parser->state.argc; + + if (parser->state.next > index) + /* Remember that we successfully processed a non-option + argument -- but only if the user hasn't gotten tricky and set + the clock back. */ + (--group)->args_processed += (parser->state.next - index); + else + /* The user wants to reparse some args, give getopt another try. */ + parser->try_getopt = 1; + } + + return err; +} + +/* Call the user parsers to parse the option OPT, with argument VAL, at the + current position, returning any error. */ +static error_t +parser_parse_opt (struct parser *parser, int opt, char *val) +{ + /* The group key encoded in the high bits; 0 for short opts or + group_number + 1 for long opts. */ + int group_key = opt >> USER_BITS; + error_t err = EBADKEY; + + if (group_key == 0) + /* A short option. By comparing OPT's position in SHORT_OPTS to the + various starting positions in each group's SHORT_END field, we can + determine which group OPT came from. */ + { + struct group *group; + char *short_index = strchr (parser->short_opts, opt); + + if (short_index) + for (group = parser->groups; group < parser->egroup; group++) + if (group->short_end > short_index) + { + err = group_parse (group, &parser->state, opt, + parser->opt_data.optarg); + break; + } + } + else + /* A long option. We use shifts instead of masking for extracting + the user value in order to preserve the sign. */ + err = + group_parse (&parser->groups[group_key - 1], &parser->state, + (opt << GROUP_BITS) >> GROUP_BITS, + parser->opt_data.optarg); + + if (err == EBADKEY) + /* At least currently, an option not recognized is an error in the + parser, because we pre-compute which parser is supposed to deal + with each option. */ + { + static const char bad_key_err[] = + N_("(PROGRAM ERROR) Option should have been recognized!?"); + if (group_key == 0) + __argp_error (&parser->state, "-%c: %s", opt, + dgettext (parser->argp->argp_domain, bad_key_err)); + else + { + struct option *long_opt = parser->long_opts; + while (long_opt->val != opt && long_opt->name) + long_opt++; + __argp_error (&parser->state, "--%s: %s", + long_opt->name ? long_opt->name : "???", + dgettext (parser->argp->argp_domain, bad_key_err)); + } + } + + return err; +} + +/* Parse the next argument in PARSER (as indicated by PARSER->state.next). + Any error from the parsers is returned, and *ARGP_EBADKEY indicates + whether a value of EBADKEY is due to an unrecognized argument (which is + generally not fatal). */ +static error_t +parser_parse_next (struct parser *parser, int *arg_ebadkey) +{ + int opt; + error_t err = 0; + + if (parser->state.quoted && parser->state.next < parser->state.quoted) + /* The next argument pointer has been moved to before the quoted + region, so pretend we never saw the quoting `--', and give getopt + another chance. If the user hasn't removed it, getopt will just + process it again. */ + parser->state.quoted = 0; + + if (parser->try_getopt && !parser->state.quoted) + /* Give getopt a chance to parse this. */ + { + /* Put it back in OPTIND for getopt. */ + parser->opt_data.optind = parser->state.next; + /* Distinguish KEY_ERR from a real option. */ + parser->opt_data.optopt = KEY_END; + if (parser->state.flags & ARGP_LONG_ONLY) + opt = _getopt_long_only_r (parser->state.argc, parser->state.argv, + parser->short_opts, parser->long_opts, 0, + &parser->opt_data); + else + opt = _getopt_long_r (parser->state.argc, parser->state.argv, + parser->short_opts, parser->long_opts, 0, + &parser->opt_data); + /* And see what getopt did. */ + parser->state.next = parser->opt_data.optind; + + if (opt == KEY_END) + /* Getopt says there are no more options, so stop using + getopt; we'll continue if necessary on our own. */ + { + parser->try_getopt = 0; + if (parser->state.next > 1 + && strcmp (parser->state.argv[parser->state.next - 1], QUOTE) + == 0) + /* Not only is this the end of the options, but it's a + `quoted' region, which may have args that *look* like + options, so we definitely shouldn't try to use getopt past + here, whatever happens. */ + parser->state.quoted = parser->state.next; + } + else if (opt == KEY_ERR && parser->opt_data.optopt != KEY_END) + /* KEY_ERR can have the same value as a valid user short + option, but in the case of a real error, getopt sets OPTOPT + to the offending character, which can never be KEY_END. */ + { + *arg_ebadkey = 0; + return EBADKEY; + } + } + else + opt = KEY_END; + + if (opt == KEY_END) + { + /* We're past what getopt considers the options. */ + if (parser->state.next >= parser->state.argc + || (parser->state.flags & ARGP_NO_ARGS)) + /* Indicate that we're done. */ + { + *arg_ebadkey = 1; + return EBADKEY; + } + else + /* A non-option arg; simulate what getopt might have done. */ + { + opt = KEY_ARG; + parser->opt_data.optarg = parser->state.argv[parser->state.next++]; + } + } + + if (opt == KEY_ARG) + /* A non-option argument; try each parser in turn. */ + err = parser_parse_arg (parser, parser->opt_data.optarg); + else + err = parser_parse_opt (parser, opt, parser->opt_data.optarg); + + if (err == EBADKEY) + *arg_ebadkey = (opt == KEY_END || opt == KEY_ARG); + + return err; +} + +/* Parse the options strings in ARGC & ARGV according to the argp in ARGP. + FLAGS is one of the ARGP_ flags above. If END_INDEX is non-NULL, the + index in ARGV of the first unparsed option is returned in it. If an + unknown option is present, EINVAL is returned; if some parser routine + returned a non-zero value, it is returned; otherwise 0 is returned. */ +error_t +__argp_parse (const struct argp *argp, int argc, char **argv, unsigned flags, + int *end_index, void *input) +{ + error_t err; + struct parser parser; + + /* If true, then err == EBADKEY is a result of a non-option argument failing + to be parsed (which in some cases isn't actually an error). */ + int arg_ebadkey = 0; + +#ifndef _LIBC + if (!(flags & ARGP_PARSE_ARGV0)) + { +#ifdef HAVE_DECL_PROGRAM_INVOCATION_NAME + if (!program_invocation_name) + program_invocation_name = argv[0]; +#endif +#ifdef HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME + if (!program_invocation_short_name) + program_invocation_short_name = __argp_base_name (argv[0]); +#endif + } +#endif + + if (! (flags & ARGP_NO_HELP)) + /* Add our own options. */ + { + struct argp_child *child = alloca (4 * sizeof (struct argp_child)); + struct argp *top_argp = alloca (sizeof (struct argp)); + + /* TOP_ARGP has no options, it just serves to group the user & default + argps. */ + memset (top_argp, 0, sizeof (*top_argp)); + top_argp->children = child; + + memset (child, 0, 4 * sizeof (struct argp_child)); + + if (argp) + (child++)->argp = argp; + (child++)->argp = &argp_default_argp; + if (argp_program_version || argp_program_version_hook) + (child++)->argp = &argp_version_argp; + child->argp = 0; + + argp = top_argp; + } + + /* Construct a parser for these arguments. */ + err = parser_init (&parser, argp, argc, argv, flags, input); + + if (! err) + /* Parse! */ + { + while (! err) + err = parser_parse_next (&parser, &arg_ebadkey); + err = parser_finalize (&parser, err, arg_ebadkey, end_index); + } + + return err; +} +#ifdef weak_alias +weak_alias (__argp_parse, argp_parse) +#endif + +/* Return the input field for ARGP in the parser corresponding to STATE; used + by the help routines. */ +void * +__argp_input (const struct argp *argp, const struct argp_state *state) +{ + if (state) + { + struct group *group; + struct parser *parser = state->pstate; + + for (group = parser->groups; group < parser->egroup; group++) + if (group->argp == argp) + return group->input; + } + + return 0; +} +#ifdef weak_alias +weak_alias (__argp_input, _argp_input) +#endif diff --git a/gnulib/argp-pin.c b/gnulib/argp-pin.c new file mode 100644 index 000000000..eda4d958e --- /dev/null +++ b/gnulib/argp-pin.c @@ -0,0 +1,27 @@ +/* Full and short program names for argp module + Copyright (C) 2005, 2009, 2010 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#ifndef HAVE_PROGRAM_INVOCATION_SHORT_NAME +char *program_invocation_short_name = 0; +#endif +#ifndef HAVE_PROGRAM_INVOCATION_NAME +char *program_invocation_name = 0; +#endif + diff --git a/gnulib/argp-pv.c b/gnulib/argp-pv.c new file mode 100644 index 000000000..e3227d322 --- /dev/null +++ b/gnulib/argp-pv.c @@ -0,0 +1,34 @@ +/* Default definition for ARGP_PROGRAM_VERSION. + Copyright (C) 1996, 1997, 1999, 2006, 2009, 2010 Free Software Foundation, + Inc. + This file is part of the GNU C Library. + Written by Miles Bader . + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* If set by the user program to a non-zero value, then a default option + --version is added (unless the ARGP_NO_HELP flag is used), which will + print this string followed by a newline and exit (unless the + ARGP_NO_EXIT flag is used). Overridden by ARGP_PROGRAM_VERSION_HOOK. */ +const char *argp_program_version +/* This variable should be zero-initialized. On most systems, putting it into + BSS is sufficient. Not so on MacOS X 10.3 and 10.4, see + + . */ +#if defined __ELF__ + /* On ELF systems, variables in BSS behave well. */ +#else + = (const char *) 0 +#endif + ; diff --git a/gnulib/argp-pvh.c b/gnulib/argp-pvh.c new file mode 100644 index 000000000..fb98fc21c --- /dev/null +++ b/gnulib/argp-pvh.c @@ -0,0 +1,31 @@ +/* Default definition for ARGP_PROGRAM_VERSION_HOOK. + Copyright (C) 1996, 1997, 1999, 2004, 2009, 2010 Free Software Foundation, + Inc. + This file is part of the GNU C Library. + Written by Miles Bader . + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "argp.h" + +/* If set by the user program to a non-zero value, then a default option + --version is added (unless the ARGP_NO_HELP flag is used), which calls + this function with a stream to print the version to and a pointer to the + current parsing state, and then exits (unless the ARGP_NO_EXIT flag is + used). This variable takes precedent over ARGP_PROGRAM_VERSION. */ +void (*argp_program_version_hook) (FILE *stream, struct argp_state *state) = NULL; diff --git a/gnulib/argp-version-etc.c b/gnulib/argp-version-etc.c new file mode 100644 index 000000000..f500a8f56 --- /dev/null +++ b/gnulib/argp-version-etc.c @@ -0,0 +1,38 @@ +/* Version hook for Argp. + Copyright (C) 2009, 2010 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include +#include +#include +#include + +static const char *program_canonical_name; +static const char * const *program_authors; + +static void +version_etc_hook (FILE *stream, struct argp_state *state) +{ + version_etc_ar (stream, program_canonical_name, PACKAGE_NAME, VERSION, + program_authors); +} + +void +argp_version_setup (const char *name, const char * const *authors) +{ + argp_program_version_hook = version_etc_hook; + program_canonical_name = name; + program_authors = authors; +} diff --git a/gnulib/argp-version-etc.h b/gnulib/argp-version-etc.h new file mode 100644 index 000000000..7c12c0181 --- /dev/null +++ b/gnulib/argp-version-etc.h @@ -0,0 +1,40 @@ +/* Version hook for Argp. + Copyright (C) 2009, 2010 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#ifndef _ARGP_VERSION_ETC_H +#define _ARGP_VERSION_ETC_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Setup standard display of the version information for the `--version' + option. NAME is the canonical program name, and AUTHORS is a NULL- + terminated array of author names. At least one author name must be + given. + + If NAME is NULL, the package name (as given by the PACKAGE macro) + is asumed to be the name of the program. + + This function is intended to be called before argp_parse(). +*/ +extern void argp_version_setup (const char *name, const char * const *authors); + +#ifdef __cplusplus +} +#endif + +#endif /* _ARGP_VERSION_ETC_H */ diff --git a/gnulib/argp-xinl.c b/gnulib/argp-xinl.c new file mode 100644 index 000000000..6e7e20bba --- /dev/null +++ b/gnulib/argp-xinl.c @@ -0,0 +1,42 @@ +/* Real definitions for extern inline functions in argp.h + Copyright (C) 1997, 1998, 2004, 2009, 2010 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Written by Miles Bader . + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#if defined _LIBC || defined HAVE_FEATURES_H +# include +#endif + +#ifndef __USE_EXTERN_INLINES +# define __USE_EXTERN_INLINES 1 +#endif +#define ARGP_EI +#undef __OPTIMIZE__ +#define __OPTIMIZE__ 1 +#include "argp.h" + +/* Add weak aliases. */ +#if _LIBC - 0 && defined (weak_alias) + +weak_alias (__argp_usage, argp_usage) +weak_alias (__option_is_short, _option_is_short) +weak_alias (__option_is_end, _option_is_end) + +#endif diff --git a/gnulib/argp.h b/gnulib/argp.h new file mode 100644 index 000000000..3667224a9 --- /dev/null +++ b/gnulib/argp.h @@ -0,0 +1,645 @@ +/* Hierarchial argument parsing, layered over getopt. + Copyright (C) 1995-1999, 2003-2010 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Written by Miles Bader . + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#ifndef _ARGP_H +#define _ARGP_H + +#include +#include +#include +#include + +#define __need_error_t +#include + +#ifndef __THROW +# define __THROW +#endif +#ifndef __NTH +# define __NTH(fct) fct __THROW +#endif + +#ifndef __attribute__ +/* The __attribute__ feature is available in gcc versions 2.5 and later. + The __-protected variants of the attributes 'format' and 'printf' are + accepted by gcc versions 2.6.4 (effectively 2.7) and later. + We enable __attribute__ only if these are supported too, because + gnulib and libintl do '#define printf __printf__' when they override + the 'printf' function. */ +# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7) +# define __attribute__(Spec) /* empty */ +# endif +#endif + +/* GCC 2.95 and later have "__restrict"; C99 compilers have + "restrict", and "configure" may have defined "restrict". + Other compilers use __restrict, __restrict__, and _Restrict, and + 'configure' might #define 'restrict' to those words. */ +#ifndef __restrict +# if ! (2 < __GNUC__ || (2 == __GNUC__ && 95 <= __GNUC_MINOR__)) +# if 199901L <= __STDC_VERSION__ +# define __restrict restrict +# else +# define __restrict +# endif +# endif +#endif + +#ifndef __error_t_defined +typedef int error_t; +# define __error_t_defined +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* A description of a particular option. A pointer to an array of + these is passed in the OPTIONS field of an argp structure. Each option + entry can correspond to one long option and/or one short option; more + names for the same option can be added by following an entry in an option + array with options having the OPTION_ALIAS flag set. */ +struct argp_option +{ + /* The long option name. For more than one name for the same option, you + can use following options with the OPTION_ALIAS flag set. */ + const char *name; + + /* What key is returned for this option. If > 0 and printable, then it's + also accepted as a short option. */ + int key; + + /* If non-NULL, this is the name of the argument associated with this + option, which is required unless the OPTION_ARG_OPTIONAL flag is set. */ + const char *arg; + + /* OPTION_ flags. */ + int flags; + + /* The doc string for this option. If both NAME and KEY are 0, This string + will be printed outdented from the normal option column, making it + useful as a group header (it will be the first thing printed in its + group); in this usage, it's conventional to end the string with a `:'. + + Write the initial value as N_("TEXT") if you want xgettext to collect + it into a POT file. */ + const char *doc; + + /* The group this option is in. In a long help message, options are sorted + alphabetically within each group, and the groups presented in the order + 0, 1, 2, ..., n, -m, ..., -2, -1. Every entry in an options array with + if this field 0 will inherit the group number of the previous entry, or + zero if it's the first one, unless its a group header (NAME and KEY both + 0), in which case, the previous entry + 1 is the default. Automagic + options such as --help are put into group -1. */ + int group; +}; + +/* The argument associated with this option is optional. */ +#define OPTION_ARG_OPTIONAL 0x1 + +/* This option isn't displayed in any help messages. */ +#define OPTION_HIDDEN 0x2 + +/* This option is an alias for the closest previous non-alias option. This + means that it will be displayed in the same help entry, and will inherit + fields other than NAME and KEY from the aliased option. */ +#define OPTION_ALIAS 0x4 + +/* This option isn't actually an option (and so should be ignored by the + actual option parser), but rather an arbitrary piece of documentation that + should be displayed in much the same manner as the options. If this flag + is set, then the option NAME field is displayed unmodified (e.g., no `--' + prefix is added) at the left-margin (where a *short* option would normally + be displayed), and the documentation string in the normal place. The NAME + field will be translated using gettext, unless OPTION_NO_TRANS is set (see + below). For purposes of sorting, any leading whitespace and punctuation is + ignored, except that if the first non-whitespace character is not `-', this + entry is displayed after all options (and OPTION_DOC entries with a leading + `-') in the same group. */ +#define OPTION_DOC 0x8 + +/* This option shouldn't be included in `long' usage messages (but is still + included in help messages). This is mainly intended for options that are + completely documented in an argp's ARGS_DOC field, in which case including + the option in the generic usage list would be redundant. For instance, + if ARGS_DOC is "FOO BAR\n-x BLAH", and the `-x' option's purpose is to + distinguish these two cases, -x should probably be marked + OPTION_NO_USAGE. */ +#define OPTION_NO_USAGE 0x10 + +/* Valid only in conjunction with OPTION_DOC. This option disables translation + of option name. */ +#define OPTION_NO_TRANS 0x20 + + +struct argp; /* fwd declare this type */ +struct argp_state; /* " */ +struct argp_child; /* " */ + +/* The type of a pointer to an argp parsing function. */ +typedef error_t (*argp_parser_t) (int key, char *arg, + struct argp_state *state); + +/* What to return for unrecognized keys. For special ARGP_KEY_ keys, such + returns will simply be ignored. For user keys, this error will be turned + into EINVAL (if the call to argp_parse is such that errors are propagated + back to the user instead of exiting); returning EINVAL itself would result + in an immediate stop to parsing in *all* cases. */ +#define ARGP_ERR_UNKNOWN E2BIG /* Hurd should never need E2BIG. XXX */ + +/* Special values for the KEY argument to an argument parsing function. + ARGP_ERR_UNKNOWN should be returned if they aren't understood. + + The sequence of keys to a parsing function is either (where each + uppercased word should be prefixed by `ARGP_KEY_' and opt is a user key): + + INIT opt... NO_ARGS END SUCCESS -- No non-option arguments at all + or INIT (opt | ARG)... END SUCCESS -- All non-option args parsed + or INIT (opt | ARG)... SUCCESS -- Some non-option arg unrecognized + + The third case is where every parser returned ARGP_KEY_UNKNOWN for an + argument, in which case parsing stops at that argument (returning the + unparsed arguments to the caller of argp_parse if requested, or stopping + with an error message if not). + + If an error occurs (either detected by argp, or because the parsing + function returned an error value), then the parser is called with + ARGP_KEY_ERROR, and no further calls are made. */ + +/* This is not an option at all, but rather a command line argument. If a + parser receiving this key returns success, the fact is recorded, and the + ARGP_KEY_NO_ARGS case won't be used. HOWEVER, if while processing the + argument, a parser function decrements the NEXT field of the state it's + passed, the option won't be considered processed; this is to allow you to + actually modify the argument (perhaps into an option), and have it + processed again. */ +#define ARGP_KEY_ARG 0 +/* There are remaining arguments not parsed by any parser, which may be found + starting at (STATE->argv + STATE->next). If success is returned, but + STATE->next left untouched, it's assumed that all arguments were consume, + otherwise, the parser should adjust STATE->next to reflect any arguments + consumed. */ +#define ARGP_KEY_ARGS 0x1000006 +/* There are no more command line arguments at all. */ +#define ARGP_KEY_END 0x1000001 +/* Because it's common to want to do some special processing if there aren't + any non-option args, user parsers are called with this key if they didn't + successfully process any non-option arguments. Called just before + ARGP_KEY_END (where more general validity checks on previously parsed + arguments can take place). */ +#define ARGP_KEY_NO_ARGS 0x1000002 +/* Passed in before any parsing is done. Afterwards, the values of each + element of the CHILD_INPUT field, if any, in the state structure is + copied to each child's state to be the initial value of the INPUT field. */ +#define ARGP_KEY_INIT 0x1000003 +/* Use after all other keys, including SUCCESS & END. */ +#define ARGP_KEY_FINI 0x1000007 +/* Passed in when parsing has successfully been completed (even if there are + still arguments remaining). */ +#define ARGP_KEY_SUCCESS 0x1000004 +/* Passed in if an error occurs. */ +#define ARGP_KEY_ERROR 0x1000005 + +/* An argp structure contains a set of options declarations, a function to + deal with parsing one, documentation string, a possible vector of child + argp's, and perhaps a function to filter help output. When actually + parsing options, getopt is called with the union of all the argp + structures chained together through their CHILD pointers, with conflicts + being resolved in favor of the first occurrence in the chain. */ +struct argp +{ + /* An array of argp_option structures, terminated by an entry with both + NAME and KEY having a value of 0. */ + const struct argp_option *options; + + /* What to do with an option from this structure. KEY is the key + associated with the option, and ARG is any associated argument (NULL if + none was supplied). If KEY isn't understood, ARGP_ERR_UNKNOWN should be + returned. If a non-zero, non-ARGP_ERR_UNKNOWN value is returned, then + parsing is stopped immediately, and that value is returned from + argp_parse(). For special (non-user-supplied) values of KEY, see the + ARGP_KEY_ definitions below. */ + argp_parser_t parser; + + /* A string describing what other arguments are wanted by this program. It + is only used by argp_usage to print the `Usage:' message. If it + contains newlines, the strings separated by them are considered + alternative usage patterns, and printed on separate lines (lines after + the first are prefix by ` or: ' instead of `Usage:'). */ + const char *args_doc; + + /* If non-NULL, a string containing extra text to be printed before and + after the options in a long help message (separated by a vertical tab + `\v' character). + Write the initial value as N_("BEFORE-TEXT") "\v" N_("AFTER-TEXT") if + you want xgettext to collect the two pieces of text into a POT file. */ + const char *doc; + + /* A vector of argp_children structures, terminated by a member with a 0 + argp field, pointing to child argps should be parsed with this one. Any + conflicts are resolved in favor of this argp, or early argps in the + CHILDREN list. This field is useful if you use libraries that supply + their own argp structure, which you want to use in conjunction with your + own. */ + const struct argp_child *children; + + /* If non-zero, this should be a function to filter the output of help + messages. KEY is either a key from an option, in which case TEXT is + that option's help text, or a special key from the ARGP_KEY_HELP_ + defines, below, describing which other help text TEXT is. The function + should return either TEXT, if it should be used as-is, a replacement + string, which should be malloced, and will be freed by argp, or NULL, + meaning `print nothing'. The value for TEXT is *after* any translation + has been done, so if any of the replacement text also needs translation, + that should be done by the filter function. INPUT is either the input + supplied to argp_parse, or NULL, if argp_help was called directly. */ + char *(*help_filter) (int __key, const char *__text, void *__input); + + /* If non-zero the strings used in the argp library are translated using + the domain described by this string. Otherwise the currently installed + default domain is used. */ + const char *argp_domain; +}; + +/* Possible KEY arguments to a help filter function. */ +#define ARGP_KEY_HELP_PRE_DOC 0x2000001 /* Help text preceeding options. */ +#define ARGP_KEY_HELP_POST_DOC 0x2000002 /* Help text following options. */ +#define ARGP_KEY_HELP_HEADER 0x2000003 /* Option header string. */ +#define ARGP_KEY_HELP_EXTRA 0x2000004 /* After all other documentation; + TEXT is NULL for this key. */ +/* Explanatory note emitted when duplicate option arguments have been + suppressed. */ +#define ARGP_KEY_HELP_DUP_ARGS_NOTE 0x2000005 +#define ARGP_KEY_HELP_ARGS_DOC 0x2000006 /* Argument doc string. */ + +/* When an argp has a non-zero CHILDREN field, it should point to a vector of + argp_child structures, each of which describes a subsidiary argp. */ +struct argp_child +{ + /* The child parser. */ + const struct argp *argp; + + /* Flags for this child. */ + int flags; + + /* If non-zero, an optional header to be printed in help output before the + child options. As a side-effect, a non-zero value forces the child + options to be grouped together; to achieve this effect without actually + printing a header string, use a value of "". */ + const char *header; + + /* Where to group the child options relative to the other (`consolidated') + options in the parent argp; the values are the same as the GROUP field + in argp_option structs, but all child-groupings follow parent options at + a particular group level. If both this field and HEADER are zero, then + they aren't grouped at all, but rather merged with the parent options + (merging the child's grouping levels with the parents). */ + int group; +}; + +/* Parsing state. This is provided to parsing functions called by argp, + which may examine and, as noted, modify fields. */ +struct argp_state +{ + /* The top level ARGP being parsed. */ + const struct argp *root_argp; + + /* The argument vector being parsed. May be modified. */ + int argc; + char **argv; + + /* The index in ARGV of the next arg that to be parsed. May be modified. */ + int next; + + /* The flags supplied to argp_parse. May be modified. */ + unsigned flags; + + /* While calling a parsing function with a key of ARGP_KEY_ARG, this is the + number of the current arg, starting at zero, and incremented after each + such call returns. At all other times, this is the number of such + arguments that have been processed. */ + unsigned arg_num; + + /* If non-zero, the index in ARGV of the first argument following a special + `--' argument (which prevents anything following being interpreted as an + option). Only set once argument parsing has proceeded past this point. */ + int quoted; + + /* An arbitrary pointer passed in from the user. */ + void *input; + /* Values to pass to child parsers. This vector will be the same length as + the number of children for the current parser. */ + void **child_inputs; + + /* For the parser's use. Initialized to 0. */ + void *hook; + + /* The name used when printing messages. This is initialized to ARGV[0], + or PROGRAM_INVOCATION_NAME if that is unavailable. */ + char *name; + + /* Streams used when argp prints something. */ + FILE *err_stream; /* For errors; initialized to stderr. */ + FILE *out_stream; /* For information; initialized to stdout. */ + + void *pstate; /* Private, for use by argp. */ +}; + +/* Flags for argp_parse (note that the defaults are those that are + convenient for program command line parsing): */ + +/* Don't ignore the first element of ARGV. Normally (and always unless + ARGP_NO_ERRS is set) the first element of the argument vector is + skipped for option parsing purposes, as it corresponds to the program name + in a command line. */ +#define ARGP_PARSE_ARGV0 0x01 + +/* Don't print error messages for unknown options to stderr; unless this flag + is set, ARGP_PARSE_ARGV0 is ignored, as ARGV[0] is used as the program + name in the error messages. This flag implies ARGP_NO_EXIT (on the + assumption that silent exiting upon errors is bad behaviour). */ +#define ARGP_NO_ERRS 0x02 + +/* Don't parse any non-option args. Normally non-option args are parsed by + calling the parse functions with a key of ARGP_KEY_ARG, and the actual arg + as the value. Since it's impossible to know which parse function wants to + handle it, each one is called in turn, until one returns 0 or an error + other than ARGP_ERR_UNKNOWN; if an argument is handled by no one, the + argp_parse returns prematurely (but with a return value of 0). If all + args have been parsed without error, all parsing functions are called one + last time with a key of ARGP_KEY_END. This flag needn't normally be set, + as the normal behavior is to stop parsing as soon as some argument can't + be handled. */ +#define ARGP_NO_ARGS 0x04 + +/* Parse options and arguments in the same order they occur on the command + line -- normally they're rearranged so that all options come first. */ +#define ARGP_IN_ORDER 0x08 + +/* Don't provide the standard long option --help, which causes usage and + option help information to be output to stdout, and exit (0) called. */ +#define ARGP_NO_HELP 0x10 + +/* Don't exit on errors (they may still result in error messages). */ +#define ARGP_NO_EXIT 0x20 + +/* Use the gnu getopt `long-only' rules for parsing arguments. */ +#define ARGP_LONG_ONLY 0x40 + +/* Turns off any message-printing/exiting options. */ +#define ARGP_SILENT (ARGP_NO_EXIT | ARGP_NO_ERRS | ARGP_NO_HELP) + +/* Parse the options strings in ARGC & ARGV according to the options in ARGP. + FLAGS is one of the ARGP_ flags above. If ARG_INDEX is non-NULL, the + index in ARGV of the first unparsed option is returned in it. If an + unknown option is present, ARGP_ERR_UNKNOWN is returned; if some parser + routine returned a non-zero value, it is returned; otherwise 0 is + returned. This function may also call exit unless the ARGP_NO_HELP flag + is set. INPUT is a pointer to a value to be passed in to the parser. */ +extern error_t argp_parse (const struct argp *__restrict __argp, + int /*argc*/, char **__restrict /*argv*/, + unsigned __flags, int *__restrict __arg_index, + void *__restrict __input); +extern error_t __argp_parse (const struct argp *__restrict __argp, + int /*argc*/, char **__restrict /*argv*/, + unsigned __flags, int *__restrict __arg_index, + void *__restrict __input); + +/* Global variables. */ + +/* GNULIB makes sure both program_invocation_name and + program_invocation_short_name are available */ +#ifdef GNULIB_PROGRAM_INVOCATION_NAME +extern char *program_invocation_name; +# undef HAVE_DECL_PROGRAM_INVOCATION_NAME +# define HAVE_DECL_PROGRAM_INVOCATION_NAME 1 +#endif + +#ifdef GNULIB_PROGRAM_INVOCATION_SHORT_NAME +extern char *program_invocation_short_name; +# undef HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME +# define HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME 1 +#endif + +/* If defined or set by the user program to a non-zero value, then a default + option --version is added (unless the ARGP_NO_HELP flag is used), which + will print this string followed by a newline and exit (unless the + ARGP_NO_EXIT flag is used). Overridden by ARGP_PROGRAM_VERSION_HOOK. */ +extern const char *argp_program_version; + +/* If defined or set by the user program to a non-zero value, then a default + option --version is added (unless the ARGP_NO_HELP flag is used), which + calls this function with a stream to print the version to and a pointer to + the current parsing state, and then exits (unless the ARGP_NO_EXIT flag is + used). This variable takes precedent over ARGP_PROGRAM_VERSION. */ +extern void (*argp_program_version_hook) (FILE *__restrict __stream, + struct argp_state *__restrict + __state); + +/* If defined or set by the user program, it should point to string that is + the bug-reporting address for the program. It will be printed by + argp_help if the ARGP_HELP_BUG_ADDR flag is set (as it is by various + standard help messages), embedded in a sentence that says something like + `Report bugs to ADDR.'. */ +extern const char *argp_program_bug_address; + +/* The exit status that argp will use when exiting due to a parsing error. + If not defined or set by the user program, this defaults to EX_USAGE from + . */ +extern error_t argp_err_exit_status; + +/* Flags for argp_help. */ +#define ARGP_HELP_USAGE 0x01 /* a Usage: message. */ +#define ARGP_HELP_SHORT_USAGE 0x02 /* " but don't actually print options. */ +#define ARGP_HELP_SEE 0x04 /* a `Try ... for more help' message. */ +#define ARGP_HELP_LONG 0x08 /* a long help message. */ +#define ARGP_HELP_PRE_DOC 0x10 /* doc string preceding long help. */ +#define ARGP_HELP_POST_DOC 0x20 /* doc string following long help. */ +#define ARGP_HELP_DOC (ARGP_HELP_PRE_DOC | ARGP_HELP_POST_DOC) +#define ARGP_HELP_BUG_ADDR 0x40 /* bug report address */ +#define ARGP_HELP_LONG_ONLY 0x80 /* modify output appropriately to + reflect ARGP_LONG_ONLY mode. */ + +/* These ARGP_HELP flags are only understood by argp_state_help. */ +#define ARGP_HELP_EXIT_ERR 0x100 /* Call exit(1) instead of returning. */ +#define ARGP_HELP_EXIT_OK 0x200 /* Call exit(0) instead of returning. */ + +/* The standard thing to do after a program command line parsing error, if an + error message has already been printed. */ +#define ARGP_HELP_STD_ERR \ + (ARGP_HELP_SEE | ARGP_HELP_EXIT_ERR) +/* The standard thing to do after a program command line parsing error, if no + more specific error message has been printed. */ +#define ARGP_HELP_STD_USAGE \ + (ARGP_HELP_SHORT_USAGE | ARGP_HELP_SEE | ARGP_HELP_EXIT_ERR) +/* The standard thing to do in response to a --help option. */ +#define ARGP_HELP_STD_HELP \ + (ARGP_HELP_SHORT_USAGE | ARGP_HELP_LONG | ARGP_HELP_EXIT_OK \ + | ARGP_HELP_DOC | ARGP_HELP_BUG_ADDR) + +/* Output a usage message for ARGP to STREAM. FLAGS are from the set + ARGP_HELP_*. */ +extern void argp_help (const struct argp *__restrict __argp, + FILE *__restrict __stream, + unsigned __flags, char *__restrict __name); +extern void __argp_help (const struct argp *__restrict __argp, + FILE *__restrict __stream, unsigned __flags, + char *__name); + +/* The following routines are intended to be called from within an argp + parsing routine (thus taking an argp_state structure as the first + argument). They may or may not print an error message and exit, depending + on the flags in STATE -- in any case, the caller should be prepared for + them *not* to exit, and should return an appropiate error after calling + them. [argp_usage & argp_error should probably be called argp_state_..., + but they're used often enough that they should be short] */ + +/* Output, if appropriate, a usage message for STATE to STREAM. FLAGS are + from the set ARGP_HELP_*. */ +extern void argp_state_help (const struct argp_state *__restrict __state, + FILE *__restrict __stream, + unsigned int __flags); +extern void __argp_state_help (const struct argp_state *__restrict __state, + FILE *__restrict __stream, + unsigned int __flags); + +#if _LIBC || !defined __USE_EXTERN_INLINES +/* Possibly output the standard usage message for ARGP to stderr and exit. */ +extern void argp_usage (const struct argp_state *__state); +extern void __argp_usage (const struct argp_state *__state); +#endif + +/* If appropriate, print the printf string FMT and following args, preceded + by the program name and `:', to stderr, and followed by a `Try ... --help' + message, then exit (1). */ +extern void argp_error (const struct argp_state *__restrict __state, + const char *__restrict __fmt, ...) + __attribute__ ((__format__ (__printf__, 2, 3))); +extern void __argp_error (const struct argp_state *__restrict __state, + const char *__restrict __fmt, ...) + __attribute__ ((__format__ (__printf__, 2, 3))); + +/* Similar to the standard gnu error-reporting function error(), but will + respect the ARGP_NO_EXIT and ARGP_NO_ERRS flags in STATE, and will print + to STATE->err_stream. This is useful for argument parsing code that is + shared between program startup (when exiting is desired) and runtime + option parsing (when typically an error code is returned instead). The + difference between this function and argp_error is that the latter is for + *parsing errors*, and the former is for other problems that occur during + parsing but don't reflect a (syntactic) problem with the input. */ +extern void argp_failure (const struct argp_state *__restrict __state, + int __status, int __errnum, + const char *__restrict __fmt, ...) + __attribute__ ((__format__ (__printf__, 4, 5))); +extern void __argp_failure (const struct argp_state *__restrict __state, + int __status, int __errnum, + const char *__restrict __fmt, ...) + __attribute__ ((__format__ (__printf__, 4, 5))); + +#if _LIBC || !defined __USE_EXTERN_INLINES +/* Returns true if the option OPT is a valid short option. */ +extern int _option_is_short (const struct argp_option *__opt) __THROW; +extern int __option_is_short (const struct argp_option *__opt) __THROW; + +/* Returns true if the option OPT is in fact the last (unused) entry in an + options array. */ +extern int _option_is_end (const struct argp_option *__opt) __THROW; +extern int __option_is_end (const struct argp_option *__opt) __THROW; +#endif + +/* Return the input field for ARGP in the parser corresponding to STATE; used + by the help routines. */ +extern void *_argp_input (const struct argp *__restrict __argp, + const struct argp_state *__restrict __state) + __THROW; +extern void *__argp_input (const struct argp *__restrict __argp, + const struct argp_state *__restrict __state) + __THROW; + +#ifdef __USE_EXTERN_INLINES + +# if !_LIBC +# define __argp_usage argp_usage +# define __argp_state_help argp_state_help +# define __option_is_short _option_is_short +# define __option_is_end _option_is_end +# endif + +# ifndef ARGP_EI +# ifdef __GNUC__ + /* GCC 4.3 and above with -std=c99 or -std=gnu99 implements ISO C99 + inline semantics, unless -fgnu89-inline is used. It defines a macro + __GNUC_STDC_INLINE__ to indicate this situation or a macro + __GNUC_GNU_INLINE__ to indicate the opposite situation. + GCC 4.2 with -std=c99 or -std=gnu99 implements the GNU C inline + semantics but warns, unless -fgnu89-inline is used: + warning: C99 inline functions are not supported; using GNU89 + warning: to disable this warning use -fgnu89-inline or the gnu_inline function attribute + It defines a macro __GNUC_GNU_INLINE__ to indicate this situation. */ +# if defined __GNUC_STDC_INLINE__ +# define ARGP_EI __inline__ +# elif defined __GNUC_GNU_INLINE__ +# define ARGP_EI extern __inline__ __attribute__ ((__gnu_inline__)) +# else +# define ARGP_EI extern __inline__ +# endif +# else + /* With other compilers, assume the ISO C99 meaning of 'inline', if + the compiler supports 'inline' at all. */ +# define ARGP_EI inline +# endif +# endif + +ARGP_EI void +__argp_usage (const struct argp_state *__state) +{ + __argp_state_help (__state, stderr, ARGP_HELP_STD_USAGE); +} + +ARGP_EI int +__NTH (__option_is_short (const struct argp_option *__opt)) +{ + if (__opt->flags & OPTION_DOC) + return 0; + else + { + int __key = __opt->key; + return __key > 0 && __key <= UCHAR_MAX && isprint (__key); + } +} + +ARGP_EI int +__NTH (__option_is_end (const struct argp_option *__opt)) +{ + return !__opt->key && !__opt->name && !__opt->doc && !__opt->group; +} + +# if !_LIBC +# undef __argp_usage +# undef __argp_state_help +# undef __option_is_short +# undef __option_is_end +# endif +#endif /* Use extern inlines. */ + +#ifdef __cplusplus +} +#endif + +#endif /* argp.h */ From a60f822cb2a0b78fecd92fe311538918871a79e6 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 3 Apr 2010 14:12:43 +0200 Subject: [PATCH 525/738] Add missing id field to grub_video_sm712_adapter --- include/grub/video.h | 13 +++++++------ video/sm712.c | 1 + 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/include/grub/video.h b/include/grub/video.h index 57f2b37f2..782a5281b 100644 --- a/include/grub/video.h +++ b/include/grub/video.h @@ -180,7 +180,8 @@ typedef enum grub_video_driver_id GRUB_VIDEO_DRIVER_NONE, GRUB_VIDEO_DRIVER_VBE, GRUB_VIDEO_DRIVER_EFI_UGA, - GRUB_VIDEO_DRIVER_EFI_GOP + GRUB_VIDEO_DRIVER_EFI_GOP, + GRUB_VIDEO_DRIVER_SM712 } grub_video_driver_id_t; struct grub_video_adapter @@ -272,7 +273,7 @@ grub_err_t EXPORT_FUNC (grub_video_get_info) (struct grub_video_mode_info *mode_ sure that framebuffer address doesn't change. To ensure this abstraction grub_video_get_info_and_fini is the only function supplying framebuffer address. */ -grub_err_t grub_video_get_info_and_fini (struct grub_video_mode_info *mode_info, +grub_err_t EXPORT_FUNC (grub_video_get_info_and_fini) (struct grub_video_mode_info *mode_info, void **framebuffer); enum grub_video_blit_format grub_video_get_blit_format (struct grub_video_mode_info *mode_info); @@ -280,8 +281,9 @@ enum grub_video_blit_format grub_video_get_blit_format (struct grub_video_mode_i grub_err_t grub_video_set_palette (unsigned int start, unsigned int count, struct grub_video_palette_data *palette_data); -grub_err_t grub_video_get_palette (unsigned int start, unsigned int count, - struct grub_video_palette_data *palette_data); +grub_err_t EXPORT_FUNC (grub_video_get_palette) (unsigned int start, + unsigned int count, + struct grub_video_palette_data *palette_data); grub_err_t EXPORT_FUNC (grub_video_set_viewport) (unsigned int x, unsigned int y, @@ -356,7 +358,6 @@ grub_video_check_mode_flag (unsigned int flags, unsigned int mask, return (flag & mask) ? !! (flags & flag) : def; } -grub_video_driver_id_t -grub_video_get_driver_id (void); +grub_video_driver_id_t EXPORT_FUNC (grub_video_get_driver_id) (void); #endif /* ! GRUB_VIDEO_HEADER */ diff --git a/video/sm712.c b/video/sm712.c index a86470b7d..33861beef 100644 --- a/video/sm712.c +++ b/video/sm712.c @@ -191,6 +191,7 @@ grub_video_sm712_get_info_and_fini (struct grub_video_mode_info *mode_info, static struct grub_video_adapter grub_video_sm712_adapter = { .name = "SM712 Video Driver", + .id = GRUB_VIDEO_DRIVER_SM712, .init = grub_video_sm712_video_init, .fini = grub_video_sm712_video_fini, From 8c46a785e3ae8d624b74bf1bc4af80b307466fd3 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 3 Apr 2010 14:14:48 +0200 Subject: [PATCH 526/738] mips multiboot2 support --- conf/mips.rmk | 7 +++++++ include/grub/i386/multiboot.h | 14 ++++++++++++++ include/grub/mips/multiboot.h | 36 +++++++++++++++++++++++++++++++++++ include/multiboot2.h | 3 ++- loader/i386/multiboot.c | 18 ++++++------------ loader/i386/multiboot_elfxx.c | 4 ++-- loader/i386/multiboot_mbi2.c | 3 ++- 7 files changed, 69 insertions(+), 16 deletions(-) create mode 100644 include/grub/mips/multiboot.h diff --git a/conf/mips.rmk b/conf/mips.rmk index face4127d..1776a5d18 100644 --- a/conf/mips.rmk +++ b/conf/mips.rmk @@ -30,4 +30,11 @@ relocator_mod_CFLAGS = $(COMMON_CFLAGS) relocator_mod_ASFLAGS = $(COMMON_ASFLAGS) relocator_mod_LDFLAGS = $(COMMON_LDFLAGS) +pkglib_MODULES += multiboot2.mod +multiboot2_mod_SOURCES = loader/i386/multiboot.c \ + loader/i386/multiboot_mbi2.c +multiboot2_mod_CFLAGS = $(COMMON_CFLAGS) -DGRUB_USE_MULTIBOOT2 +multiboot2_mod_LDFLAGS = $(COMMON_LDFLAGS) +multiboot2_mod_ASFLAGS = $(COMMON_ASFLAGS) + include $(srcdir)/conf/common.mk diff --git a/include/grub/i386/multiboot.h b/include/grub/i386/multiboot.h index 8131e9477..1c711fad4 100644 --- a/include/grub/i386/multiboot.h +++ b/include/grub/i386/multiboot.h @@ -24,4 +24,18 @@ extern char *grub_multiboot_payload_orig; extern grub_addr_t grub_multiboot_payload_dest; extern grub_size_t grub_multiboot_payload_size; +#define MULTIBOOT_INITIAL_STATE { .eax = MULTIBOOT_BOOTLOADER_MAGIC, \ + .ecx = 0, \ + .edx = 0, \ + /* Set esp to some random location in low memory to avoid breaking */ \ + /* non-compliant kernels. */ \ + .esp = 0x7ff00 \ + } +#define MULTIBOOT_ENTRY_REGISTER eip +#define MULTIBOOT_MBI_REGISTER ebx +#define MULTIBOOT_ARCHITECTURE_CURRENT MULTIBOOT_ARCHITECTURE_I386 + +#define MULTIBOOT_ELF32_MACHINE EM_386 +#define MULTIBOOT_ELF64_MACHINE EM_X86_64 + #endif /* ! GRUB_MULTIBOOT_CPU_HEADER */ diff --git a/include/grub/mips/multiboot.h b/include/grub/mips/multiboot.h new file mode 100644 index 000000000..a27229efe --- /dev/null +++ b/include/grub/mips/multiboot.h @@ -0,0 +1,36 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2003,2004,2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_MULTIBOOT_CPU_HEADER +#define GRUB_MULTIBOOT_CPU_HEADER 1 + +extern grub_uint32_t grub_multiboot_payload_eip; +extern char *grub_multiboot_payload_orig; +extern grub_addr_t grub_multiboot_payload_dest; +extern grub_size_t grub_multiboot_payload_size; + +#define MULTIBOOT_INITIAL_STATE { .gpr[4] = MULTIBOOT_BOOTLOADER_MAGIC, \ + .jumpreg = 1 } +#define MULTIBOOT_ENTRY_REGISTER gpr[1] +#define MULTIBOOT_MBI_REGISTER gpr[5] +#define MULTIBOOT_ARCHITECTURE_CURRENT MULTIBOOT_ARCHITECTURE_MIPS32 + +#define MULTIBOOT_ELF32_MACHINE EM_MIPS +#define MULTIBOOT_ELF64_MACHINE EM_MIPS + +#endif /* ! GRUB_MULTIBOOT_CPU_HEADER */ diff --git a/include/multiboot2.h b/include/multiboot2.h index 647109c0b..275debe75 100644 --- a/include/multiboot2.h +++ b/include/multiboot2.h @@ -61,7 +61,8 @@ #define MULTIBOOT_HEADER_TAG_FRAMEBUFFER 5 #define MULTIBOOT_HEADER_TAG_MODULE_ALIGN 6 -#define GRUB_MULTIBOOT_ARCHITECTURE_I386 0 +#define MULTIBOOT_ARCHITECTURE_I386 0 +#define MULTIBOOT_ARCHITECTURE_MIPS32 4 #define MULTIBOOT_HEADER_TAG_OPTIONAL 1 #define MULTIBOOT_CONSOLE_FLAGS_CONSOLE_REQUIRED 1 diff --git a/loader/i386/multiboot.c b/loader/i386/multiboot.c index 99d1cf906..1a22cd3a6 100644 --- a/loader/i386/multiboot.c +++ b/loader/i386/multiboot.c @@ -41,7 +41,7 @@ #include #include #include -#include +#include #include #include #include @@ -121,16 +121,9 @@ grub_multiboot_boot (void) { grub_size_t mbi_size; grub_err_t err; - struct grub_relocator32_state state = - { - .eax = MULTIBOOT_BOOTLOADER_MAGIC, - .ecx = 0, - .edx = 0, - .eip = grub_multiboot_payload_eip, - /* Set esp to some random location in low memory to avoid breaking - non-compliant kernels. */ - .esp = 0x7ff00 - }; + struct grub_relocator32_state state = MULTIBOOT_INITIAL_STATE; + + state.MULTIBOOT_ENTRY_REGISTER = grub_multiboot_payload_eip; mbi_size = grub_multiboot_get_mbi_size (); if (grub_multiboot_alloc_mbi < mbi_size) @@ -143,7 +136,8 @@ grub_multiboot_boot (void) grub_multiboot_alloc_mbi = mbi_size; } - state.ebx = grub_multiboot_payload_dest + grub_multiboot_pure_size; + state.MULTIBOOT_MBI_REGISTER = grub_multiboot_payload_dest + + grub_multiboot_pure_size; err = grub_multiboot_make_mbi (grub_multiboot_payload_orig, grub_multiboot_payload_dest, grub_multiboot_pure_size, mbi_size); diff --git a/loader/i386/multiboot_elfxx.c b/loader/i386/multiboot_elfxx.c index 05fb2c1c1..92a52d3a8 100644 --- a/loader/i386/multiboot_elfxx.c +++ b/loader/i386/multiboot_elfxx.c @@ -18,13 +18,13 @@ #if defined(MULTIBOOT_LOAD_ELF32) # define XX 32 -# define E_MACHINE EM_386 +# define E_MACHINE MULTIBOOT_ELF32_MACHINE # define ELFCLASSXX ELFCLASS32 # define Elf_Ehdr Elf32_Ehdr # define Elf_Phdr Elf32_Phdr #elif defined(MULTIBOOT_LOAD_ELF64) # define XX 64 -# define E_MACHINE EM_X86_64 +# define E_MACHINE MULTIBOOT_ELF64_MACHINE # define ELFCLASSXX ELFCLASS64 # define Elf_Ehdr Elf64_Ehdr # define Elf_Phdr Elf64_Phdr diff --git a/loader/i386/multiboot_mbi2.c b/loader/i386/multiboot_mbi2.c index 1910d656e..8b67f9383 100644 --- a/loader/i386/multiboot_mbi2.c +++ b/loader/i386/multiboot_mbi2.c @@ -90,7 +90,8 @@ grub_multiboot_load (grub_file_t file) { if (header->magic == MULTIBOOT_HEADER_MAGIC && !(header->magic + header->architecture - + header->header_length + header->checksum)) + + header->header_length + header->checksum) + && header->architecture == MULTIBOOT_ARCHITECTURE_CURRENT) break; } From a9cd257a873c889e763a3785efcfa2710ac13f8f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 3 Apr 2010 14:29:11 +0200 Subject: [PATCH 527/738] Move files to appropriate places --- conf/i386.rmk | 6 ++---- conf/mips.rmk | 4 ++-- loader/{i386 => }/multiboot.c | 0 loader/{i386 => }/multiboot_elfxx.c | 0 loader/{i386 => }/multiboot_mbi2.c | 0 5 files changed, 4 insertions(+), 6 deletions(-) rename loader/{i386 => }/multiboot.c (100%) rename loader/{i386 => }/multiboot_elfxx.c (100%) rename loader/{i386 => }/multiboot_mbi2.c (100%) diff --git a/conf/i386.rmk b/conf/i386.rmk index 79a8e430b..3d7f42804 100644 --- a/conf/i386.rmk +++ b/conf/i386.rmk @@ -33,15 +33,13 @@ setpci_mod_CFLAGS = $(COMMON_CFLAGS) setpci_mod_LDFLAGS = $(COMMON_LDFLAGS) pkglib_MODULES += multiboot.mod -multiboot_mod_SOURCES = loader/i386/multiboot.c \ - loader/i386/multiboot_mbi.c +multiboot_mod_SOURCES = loader/multiboot.c loader/i386/multiboot_mbi.c multiboot_mod_CFLAGS = $(COMMON_CFLAGS) multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS) multiboot_mod_ASFLAGS = $(COMMON_ASFLAGS) pkglib_MODULES += multiboot2.mod -multiboot2_mod_SOURCES = loader/i386/multiboot.c \ - loader/i386/multiboot_mbi2.c +multiboot2_mod_SOURCES = loader/multiboot.c loader/multiboot_mbi2.c multiboot2_mod_CFLAGS = $(COMMON_CFLAGS) -DGRUB_USE_MULTIBOOT2 multiboot2_mod_LDFLAGS = $(COMMON_LDFLAGS) multiboot2_mod_ASFLAGS = $(COMMON_ASFLAGS) diff --git a/conf/mips.rmk b/conf/mips.rmk index 1776a5d18..c9d94eb74 100644 --- a/conf/mips.rmk +++ b/conf/mips.rmk @@ -31,8 +31,8 @@ relocator_mod_ASFLAGS = $(COMMON_ASFLAGS) relocator_mod_LDFLAGS = $(COMMON_LDFLAGS) pkglib_MODULES += multiboot2.mod -multiboot2_mod_SOURCES = loader/i386/multiboot.c \ - loader/i386/multiboot_mbi2.c +multiboot2_mod_SOURCES = loader/multiboot.c \ + loader/multiboot_mbi2.c multiboot2_mod_CFLAGS = $(COMMON_CFLAGS) -DGRUB_USE_MULTIBOOT2 multiboot2_mod_LDFLAGS = $(COMMON_LDFLAGS) multiboot2_mod_ASFLAGS = $(COMMON_ASFLAGS) diff --git a/loader/i386/multiboot.c b/loader/multiboot.c similarity index 100% rename from loader/i386/multiboot.c rename to loader/multiboot.c diff --git a/loader/i386/multiboot_elfxx.c b/loader/multiboot_elfxx.c similarity index 100% rename from loader/i386/multiboot_elfxx.c rename to loader/multiboot_elfxx.c diff --git a/loader/i386/multiboot_mbi2.c b/loader/multiboot_mbi2.c similarity index 100% rename from loader/i386/multiboot_mbi2.c rename to loader/multiboot_mbi2.c From 651a6c17fea4dbcd94c06ad8d65380cbff165e59 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 3 Apr 2010 20:07:09 +0200 Subject: [PATCH 528/738] Add missing files --- lib/posix_wrap/errno.h | 28 ++++++++++++++++++++++++++++ lib/posix_wrap/unistd.h | 0 2 files changed, 28 insertions(+) create mode 100644 lib/posix_wrap/errno.h create mode 100644 lib/posix_wrap/unistd.h diff --git a/lib/posix_wrap/errno.h b/lib/posix_wrap/errno.h new file mode 100644 index 000000000..9031722e2 --- /dev/null +++ b/lib/posix_wrap/errno.h @@ -0,0 +1,28 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009, 2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_POSIX_ERRNO_H +#define GRUB_POSIX_ERRNO_H 1 + +#include + +#define errno grub_errno +#define EINVAL GRUB_ERR_BAD_NUMBER +#define ENOMEM GRUB_ERR_OUT_OF_MEMORY + +#endif diff --git a/lib/posix_wrap/unistd.h b/lib/posix_wrap/unistd.h new file mode 100644 index 000000000..e69de29bb From 3db3a82b75ee0cb9dc512852f35000a79535aa36 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 3 Apr 2010 20:12:43 +0200 Subject: [PATCH 529/738] =?UTF-8?q?=09*=20Makefile.in=20(uninstall):=20Rem?= =?UTF-8?q?ove=20a=20leftover=20debug=20echo.=20=09Reported=20by:=20Gr?= =?UTF-8?q?=C3=A9goire=20Sutre?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ChangeLog | 5 +++++ Makefile.in | 1 - 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index e66dbce43..061b24a11 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-04-03 Vladimir Serbinenko + + * Makefile.in (uninstall): Remove a leftover debug echo. + Reported by: Grégoire Sutre + 2010-04-03 Vladimir Serbinenko MIPS multiboot2 support. diff --git a/Makefile.in b/Makefile.in index d640b91d6..f227650c4 100644 --- a/Makefile.in +++ b/Makefile.in @@ -396,7 +396,6 @@ uninstall: @list='$(lib_SCRIPTS)'; \ for file in $$list; do \ dest="`echo $$file | sed 's,.*/,,'`"; \ - echo rm -f $(DESTDIR)$(libdir)/$$dest; \ rm -f $(DESTDIR)$(libdir)/grub/$$dest; \ done @list='$(info_INFOS)'; \ From bd5a6415b0cb4d36145dc493aeffdc69ec6e7bbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Sutre?= Date: Sat, 3 Apr 2010 20:23:21 +0200 Subject: [PATCH 530/738] * util/i386/efi/grub-dumpdevtree: replaced the non-portable `==' by `=' and added double quotes on operands of this equality test. --- ChangeLog | 5 +++++ util/i386/efi/grub-dumpdevtree | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 061b24a11..035cd078a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-04-03 Grégoire Sutre + + * util/i386/efi/grub-dumpdevtree: replaced the non-portable `==' by + `=' and added double quotes on operands of this equality test. + 2010-04-03 Vladimir Serbinenko * Makefile.in (uninstall): Remove a leftover debug echo. diff --git a/util/i386/efi/grub-dumpdevtree b/util/i386/efi/grub-dumpdevtree index 25aa35e23..51004cc85 100644 --- a/util/i386/efi/grub-dumpdevtree +++ b/util/i386/efi/grub-dumpdevtree @@ -15,7 +15,7 @@ # You should have received a copy of the GNU General Public License # along with GRUB. If not, see . -if [ x$1 == x ]; then +if [ "x$1" = "x" ]; then echo "Filename required". fi From b1654fdfe1317a7a9ccc9c50d0f077f26651ccca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Sutre?= Date: Sat, 3 Apr 2010 20:35:13 +0200 Subject: [PATCH 531/738] * Makefile.in (LEX): new variable. --- ChangeLog | 4 ++++ Makefile.in | 1 + 2 files changed, 5 insertions(+) diff --git a/ChangeLog b/ChangeLog index 035cd078a..a1bfc3ef7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-04-03 Grégoire Sutre + + * Makefile.in (LEX): new variable. + 2010-04-03 Grégoire Sutre * util/i386/efi/grub-dumpdevtree: replaced the non-portable `==' by diff --git a/Makefile.in b/Makefile.in index f227650c4..3d832d725 100644 --- a/Makefile.in +++ b/Makefile.in @@ -117,6 +117,7 @@ LIBCURSES = @LIBCURSES@ LIBUSB = @LIBUSB@ LIBSDL = @LIBSDL@ LIBPCIACCESS = @LIBPCIACCESS@ +LEX = @LEX@ YACC = @YACC@ FONT_SOURCE = @FONT_SOURCE@ From 50479febcfd2bbac32fe824b8e8ea52b0f3cccc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Sutre?= Date: Sat, 3 Apr 2010 20:48:36 +0200 Subject: [PATCH 532/738] * util/grub-install.in: Use mkdir -p to create grub directory. * util/i386/efi/grub-install.in: Likewise. * util/ieee1275/grub-install.in: Likewise. --- ChangeLog | 6 ++++++ util/grub-install.in | 3 +-- util/i386/efi/grub-install.in | 3 +-- util/ieee1275/grub-install.in | 3 +-- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index a1bfc3ef7..fbfefad82 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-04-03 Grégoire Sutre + + * util/grub-install.in: Use mkdir -p to create grub directory. + * util/i386/efi/grub-install.in: Likewise. + * util/ieee1275/grub-install.in: Likewise. + 2010-04-03 Grégoire Sutre * Makefile.in (LEX): new variable. diff --git a/util/grub-install.in b/util/grub-install.in index a1671b200..790b56ff6 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -219,8 +219,7 @@ else fi # Create the GRUB directory if it is not present. -test -d "$bootdir" || mkdir "$bootdir" || exit 1 -test -d "$grubdir" || mkdir "$grubdir" || exit 1 +mkdir -p "$grubdir" || exit 1 # If --recheck is specified, remove the device map, if present. if test $recheck = yes; then diff --git a/util/i386/efi/grub-install.in b/util/i386/efi/grub-install.in index 2e9b0ca39..cc4d950d2 100644 --- a/util/i386/efi/grub-install.in +++ b/util/i386/efi/grub-install.in @@ -145,8 +145,7 @@ else fi # Create the GRUB directory if it is not present. -test -d "$bootdir" || mkdir "$bootdir" || exit 1 -test -d "$grubdir" || mkdir "$grubdir" || exit 1 +mkdir -p "$grubdir" || exit 1 # If --recheck is specified, remove the device map, if present. if test $recheck = yes; then diff --git a/util/ieee1275/grub-install.in b/util/ieee1275/grub-install.in index be4053542..363f312db 100644 --- a/util/ieee1275/grub-install.in +++ b/util/ieee1275/grub-install.in @@ -141,8 +141,7 @@ fi # XXX warn on firmware-unreadable filesystems? # Create the GRUB directory if it is not present. -test -d "$bootdir" || mkdir "$bootdir" || exit 1 -test -d "$grubdir" || mkdir "$grubdir" || exit 1 +mkdir -p "$grubdir" || exit 1 # Create the device map file if it is not present. if test -f "$device_map"; then From b9396631bc0a677d2800f1c9eec6b4e006071d07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Sutre?= Date: Sat, 3 Apr 2010 20:52:06 +0200 Subject: [PATCH 533/738] * util/grub-install.in: Add `|| exit 1' to all grub-probe calls for which failure is fatal. --- ChangeLog | 5 +++++ util/grub-install.in | 8 ++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index fbfefad82..d679336aa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-04-03 Grégoire Sutre + + * util/grub-install.in: Add `|| exit 1' to all grub-probe calls + for which failure is fatal. + 2010-04-03 Grégoire Sutre * util/grub-install.in: Use mkdir -p to create grub directory. diff --git a/util/grub-install.in b/util/grub-install.in index 790b56ff6..142d5792f 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -270,7 +270,7 @@ for dir in ${localedir}/*; do done # Write device to a variable so we don't have to traverse /dev every time. -grub_device=`$grub_probe --target=device ${grubdir}` +grub_device=`$grub_probe --target=device ${grubdir}` || exit 1 if ! test -f ${grubdir}/grubenv; then $grub_editenv ${grubdir}/grubenv create @@ -312,11 +312,11 @@ if [ "x${devabstraction_module}" = "x" ] ; then if echo "${install_device}" | grep -qx "(.*)" ; then install_drive="${install_device}" else - install_drive="`$grub_probe --target=drive --device ${install_device}`" + install_drive="`$grub_probe --target=drive --device ${install_device}`" || exit 1 fi install_drive="`echo ${install_drive} | sed -e s/,[0-9]*[a-z]*//g`" fi - grub_drive="`$grub_probe --target=drive --device ${grub_device}`" + grub_drive="`$grub_probe --target=drive --device ${grub_device}`" || exit 1 # Strip partition number grub_drive="`echo ${grub_drive} | sed -e s/,[0-9]*[a-z]*//g`" @@ -343,7 +343,7 @@ if [ "x${devabstraction_module}" = "x" ] ; then modules="$modules search_fs_uuid" fi else - prefix_drive=`$grub_probe --target=drive --device ${grub_device}` + prefix_drive=`$grub_probe --target=drive --device ${grub_device}` || exit 1 fi if [ "${target_cpu}-${platform}" = "i386-pc" ] || [ "${target_cpu}-${platform}" = "sparc64-ieee1275" ] ; then From 187bbe3d9cf392c7cd7fb413bc001909c1f01068 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Sutre?= Date: Sat, 3 Apr 2010 21:00:21 +0200 Subject: [PATCH 534/738] * kern/misc.c: Disable the __enable_execute_stack hack for utilities. * include/grub/misc.h: Likewise. --- ChangeLog | 5 +++++ include/grub/misc.h | 2 +- kern/misc.c | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index d679336aa..1afed06f7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-04-03 Grégoire Sutre + + * kern/misc.c: Disable the __enable_execute_stack hack for utilities. + * include/grub/misc.h: Likewise. + 2010-04-03 Grégoire Sutre * util/grub-install.in: Add `|| exit 1' to all grub-probe calls diff --git a/include/grub/misc.h b/include/grub/misc.h index 5b1477ed4..61174c38d 100644 --- a/include/grub/misc.h +++ b/include/grub/misc.h @@ -261,7 +261,7 @@ grub_size_t EXPORT_FUNC(grub_utf8_to_ucs4) (grub_uint32_t *dest, grub_uint64_t EXPORT_FUNC(grub_divmod64) (grub_uint64_t n, grub_uint32_t d, grub_uint32_t *r); -#ifdef NEED_ENABLE_EXECUTE_STACK +#if defined(NEED_ENABLE_EXECUTE_STACK) && !defined(GRUB_UTIL) void EXPORT_FUNC(__enable_execute_stack) (void *addr); #endif diff --git a/kern/misc.c b/kern/misc.c index 4772e22b0..9d8fc70da 100644 --- a/kern/misc.c +++ b/kern/misc.c @@ -1058,7 +1058,7 @@ grub_abort (void) void abort (void) __attribute__ ((alias ("grub_abort"))); #endif -#ifdef NEED_ENABLE_EXECUTE_STACK +#if defined(NEED_ENABLE_EXECUTE_STACK) && !defined(GRUB_UTIL) /* Some gcc versions generate a call to this function in trampolines for nested functions. */ void __enable_execute_stack (void *addr __attribute__ ((unused))) From a8c3b552a729bf9cf9b1bc13a56fc8ce18b9c416 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 4 Apr 2010 14:12:11 +0200 Subject: [PATCH 535/738] Remove unused grub_vga_get_font. * kern/i386/pc/startup.S (grub_vga_get_font): Removed. * include/grub/i386/pc/vga.h (grub_vga_get_font): Likewise. --- ChangeLog | 7 +++++++ include/grub/i386/pc/vga.h | 3 --- kern/i386/pc/startup.S | 27 --------------------------- 3 files changed, 7 insertions(+), 30 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1afed06f7..de10988c5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-04-04 Vladimir Serbinenko + + Remove unused grub_vga_get_font. + + * kern/i386/pc/startup.S (grub_vga_get_font): Removed. + * include/grub/i386/pc/vga.h (grub_vga_get_font): Likewise. + 2010-04-03 Grégoire Sutre * kern/misc.c: Disable the __enable_execute_stack hack for utilities. diff --git a/include/grub/i386/pc/vga.h b/include/grub/i386/pc/vga.h index b9822395b..2724f6401 100644 --- a/include/grub/i386/pc/vga.h +++ b/include/grub/i386/pc/vga.h @@ -28,7 +28,4 @@ /* Set the video mode to MODE and return the previous mode. */ unsigned char EXPORT_FUNC(grub_vga_set_mode) (unsigned char mode); -/* Return a pointer to the ROM font table. */ -unsigned char *EXPORT_FUNC(grub_vga_get_font) (void); - #endif /* ! GRUB_VGA_MACHINE_HEADER */ diff --git a/kern/i386/pc/startup.S b/kern/i386/pc/startup.S index 0aa420c6c..e78903a45 100644 --- a/kern/i386/pc/startup.S +++ b/kern/i386/pc/startup.S @@ -1539,33 +1539,6 @@ FUNCTION(grub_vga_set_mode) popl %ebp ret - -/* - * unsigned char *grub_vga_get_font (void) - */ -FUNCTION(grub_vga_get_font) - pushl %ebp - pushl %ebx - - call prot_to_real - .code16 - movw $0x1130, %ax - movb $0x06, %bh - int $0x10 - movw %es, %bx - movw %bp, %dx - DATA32 call real_to_prot - .code32 - - movzwl %bx, %ecx - shll $4, %ecx - movw %dx, %ax - addl %ecx, %eax - - popl %ebx - popl %ebp - ret - /* * grub_vbe_bios_status_t grub_vbe_get_controller_info (struct grub_vbe_info_block *controller_info) * From 064cb524ecb9c70d611065a6d3c1b4b3fe0e85a3 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 5 Apr 2010 15:57:40 +0200 Subject: [PATCH 536/738] * include/grub/i386/pc/init.h (grub_get_mmap_entry): Don't export. * conf/i386-pc.rmk (kernel_img_HEADERS): Remove machine/init.h. --- ChangeLog | 5 +++++ conf/i386-pc.rmk | 2 +- include/grub/i386/pc/init.h | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index de10988c5..745bbe423 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-04-05 Vladimir Serbinenko + + * include/grub/i386/pc/init.h (grub_get_mmap_entry): Don't export. + * conf/i386-pc.rmk (kernel_img_HEADERS): Remove machine/init.h. + 2010-04-04 Vladimir Serbinenko Remove unused grub_vga_get_font. diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk index ece88446b..18febc879 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -55,7 +55,7 @@ kernel_img_SOURCES = kern/i386/pc/startup.S \ term/i386/pc/console.c term/i386/vga_common.c \ symlist.c kernel_img_HEADERS += machine/biosdisk.h machine/vga.h machine/vbe.h \ - machine/pxe.h i386/pit.h machine/init.h + machine/pxe.h i386/pit.h kernel_img_CFLAGS = $(COMMON_CFLAGS) $(TARGET_IMG_CFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) kernel_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_KERNEL_MACHINE_LINK_ADDR) $(COMMON_CFLAGS) diff --git a/include/grub/i386/pc/init.h b/include/grub/i386/pc/init.h index 2be80e773..30130d189 100644 --- a/include/grub/i386/pc/init.h +++ b/include/grub/i386/pc/init.h @@ -33,7 +33,7 @@ grub_uint32_t grub_get_eisa_mmap (void); /* Get a memory map entry. Return next continuation value. Zero means the end. */ -grub_uint32_t EXPORT_FUNC(grub_get_mmap_entry) (struct grub_machine_mmap_entry *entry, +grub_uint32_t grub_get_mmap_entry (struct grub_machine_mmap_entry *entry, grub_uint32_t cont); /* Turn on/off Gate A20. */ From 2622c3ffb0fab52f0a00a8096b88ce55afb45198 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 5 Apr 2010 15:59:32 +0200 Subject: [PATCH 537/738] * kern/i386/pc/startup.S (grub_getrtsecs): Removed (dead code). --- ChangeLog | 4 ++++ kern/i386/pc/startup.S | 41 ----------------------------------------- 2 files changed, 4 insertions(+), 41 deletions(-) diff --git a/ChangeLog b/ChangeLog index 745bbe423..de222d1cb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-04-05 Vladimir Serbinenko + + * kern/i386/pc/startup.S (grub_getrtsecs): Removed (dead code). + 2010-04-05 Vladimir Serbinenko * include/grub/i386/pc/init.h (grub_get_mmap_entry): Don't export. diff --git a/kern/i386/pc/startup.S b/kern/i386/pc/startup.S index e78903a45..374277767 100644 --- a/kern/i386/pc/startup.S +++ b/kern/i386/pc/startup.S @@ -1444,47 +1444,6 @@ FUNCTION(grub_console_setcursor) popl %ebp ret -/* - * grub_getrtsecs() - * if a seconds value can be read, read it and return it (BCD), - * otherwise return 0xFF - * BIOS call "INT 1AH Function 02H" to check whether a character is pending - * Call with %ah = 0x2 - * Return: - * If RT Clock can give correct values - * %ch = hour (BCD) - * %cl = minutes (BCD) - * %dh = seconds (BCD) - * %dl = daylight savings time (00h std, 01h daylight) - * Carry flag = clear - * else - * Carry flag = set - * (this indicates that the clock is updating, or - * that it isn't running) - */ -FUNCTION(grub_getrtsecs) - pushl %ebp - - call prot_to_real /* enter real mode */ - .code16 - - clc - movb $0x2, %ah - int $0x1a - - DATA32 jnc gottime - movb $0xff, %dh - -gottime: - DATA32 call real_to_prot - .code32 - - movb %dh, %al - - popl %ebp - ret - - /* * grub_get_rtc() * return the real time in ticks, of which there are about From 974ac4f755edec1d286d6d4b23687083adfedb51 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 5 Apr 2010 16:06:16 +0200 Subject: [PATCH 538/738] * loader/i386/multiboot_mbi.c (grub_multiboot_load): Correctly report unsupported video mode types. --- ChangeLog | 5 +++++ loader/i386/multiboot_mbi.c | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/ChangeLog b/ChangeLog index de222d1cb..5fd6a7c0b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-04-05 Vladimir Serbinenko + + * loader/i386/multiboot_mbi.c (grub_multiboot_load): Correctly report + unsupported video mode types. + 2010-04-05 Vladimir Serbinenko * kern/i386/pc/startup.S (grub_getrtsecs): Removed (dead code). diff --git a/loader/i386/multiboot_mbi.c b/loader/i386/multiboot_mbi.c index 2a7c70f96..3d974f04e 100644 --- a/loader/i386/multiboot_mbi.c +++ b/loader/i386/multiboot_mbi.c @@ -170,6 +170,11 @@ grub_multiboot_load (grub_file_t file) header->width, header->height, header->depth, 0); break; + default: + err = grub_error (GRUB_ERR_BAD_OS, + "unsupported graphical mode type %d", + header->mode_type); + break; } } else From 09220190683cf9170953b09e82759d442dde95c0 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Mon, 5 Apr 2010 21:08:30 +0530 Subject: [PATCH 539/738] added flex version check in configure.ac --- configure.ac | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/configure.ac b/configure.ac index 50edf645c..157a6114c 100644 --- a/configure.ac +++ b/configure.ac @@ -170,11 +170,6 @@ if test "x$CMP" = x; then AC_MSG_ERROR([cmp is not found]) fi -AC_CHECK_PROGS([LEX], [flex]) -if test "x$LEX" = x; then - AC_MSG_ERROR([flex is not found]) -fi - AC_CHECK_PROGS([YACC], [bison]) if test "x$YACC" = x; then AC_MSG_ERROR([bison is not found]) @@ -188,10 +183,23 @@ for file in /usr/src/unifont.bdf /usr/share/fonts/X11/misc/unifont.pcf.gz /usr/s done AC_PROG_INSTALL +AC_PROG_SED AC_PROG_AWK +AC_PROG_LEX AC_PROG_MAKE_SET AC_PROG_MKDIR_P +if test "x$LEX" = x; then + AC_MSG_ERROR([flex is not found]) +else + version=`$LEX --version 2>/dev/null | $SED -e 's/flex //' | $AWK 'BEGIN { FS = "."; } { printf "%d", ($1 * 100 + $2) * 100 + $3;}'` + if test -n "$version" -a test "$version" -ge 205035; then + : + else + AC_MSG_ERROR([flex is too old. GRUB requires 2.5.35 or above]) + fi +fi + # These are not a "must". AC_PATH_PROG(RUBY, ruby) AC_PATH_PROG(MAKEINFO, makeinfo) From b777c18e388b55230058fdae5e0a120307b5430d Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Mon, 5 Apr 2010 21:47:19 +0530 Subject: [PATCH 540/738] fixed version canonicalization --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 157a6114c..1f55a9ca7 100644 --- a/configure.ac +++ b/configure.ac @@ -192,8 +192,8 @@ AC_PROG_MKDIR_P if test "x$LEX" = x; then AC_MSG_ERROR([flex is not found]) else - version=`$LEX --version 2>/dev/null | $SED -e 's/flex //' | $AWK 'BEGIN { FS = "."; } { printf "%d", ($1 * 100 + $2) * 100 + $3;}'` - if test -n "$version" -a test "$version" -ge 205035; then + version=`$LEX --version 2>/dev/null | $SED -e 's/flex //' | $AWK 'BEGIN { FS = "."; } { printf "%d", $1 * 10000 + $2 * 100 + $3;}'` + if test -n "$version" -a "$version" -ge 20535; then : else AC_MSG_ERROR([flex is too old. GRUB requires 2.5.35 or above]) From f9d9068aa720aea0fd25bf4f7033b430d965b926 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Tue, 6 Apr 2010 12:21:11 +0530 Subject: [PATCH 541/738] removed -serial stdio option from qemu cmdline --- tests/util/grub-shell.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/util/grub-shell.in b/tests/util/grub-shell.in index 2b9131547..a41a6f6f4 100644 --- a/tests/util/grub-shell.in +++ b/tests/util/grub-shell.in @@ -135,7 +135,7 @@ fdafile=`mktemp` cp ${isofile} ${fdafile} outfile=`mktemp` -qemu-system-i386 ${qemuopts} -nographic -serial stdio -hda ${hdafile} -fda ${fdafile} -cdrom ${isofile} -boot ${bootdev} | tr -d "\r" >${outfile} +qemu-system-i386 ${qemuopts} -nographic -hda ${hdafile} -fda ${fdafile} -cdrom ${isofile} -boot ${bootdev} | tr -d "\r" >${outfile} cat $outfile From fa09c82e6e0e3aa36c80d8c7b98f80f0da2787ce Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Tue, 6 Apr 2010 12:31:44 +0530 Subject: [PATCH 542/738] updated changelog --- ChangeLog | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ChangeLog b/ChangeLog index 5fb147455..10e9a774d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-04-06 BVK Chaitanya + + Fix unit testing framework for qemu 0.12. + + * tests/util/grub-shell.in: Remove -serial stdio option. + 2010-04-06 Vladimir Serbinenko POSIX header file wrappers. From 4ee717e12b0a98c0763ac87e9fd27ad38a91b3f4 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Tue, 6 Apr 2010 14:39:11 +0530 Subject: [PATCH 543/738] fix freebsd build --- conf/common.rmk | 2 +- configure.ac | 2 +- script/yylex.l | 6 ------ 3 files changed, 2 insertions(+), 8 deletions(-) diff --git a/conf/common.rmk b/conf/common.rmk index 87ae1e202..a83d10662 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -653,7 +653,7 @@ normal_mod_LDFLAGS = $(COMMON_LDFLAGS) # For sh.mod. sh_mod_SOURCES = script/main.c script/script.c script/execute.c \ script/function.c script/lexer.c grub_script.tab.c grub_script.yy.c -sh_mod_CFLAGS = $(COMMON_CFLAGS) $(POSIX_CFLAGS) +sh_mod_CFLAGS = $(COMMON_CFLAGS) $(POSIX_CFLAGS) -Wno-error sh_mod_LDFLAGS = $(COMMON_LDFLAGS) ifneq (, $(FONT_SOURCE)) diff --git a/configure.ac b/configure.ac index 1f55a9ca7..0af597bd3 100644 --- a/configure.ac +++ b/configure.ac @@ -192,7 +192,7 @@ AC_PROG_MKDIR_P if test "x$LEX" = x; then AC_MSG_ERROR([flex is not found]) else - version=`$LEX --version 2>/dev/null | $SED -e 's/flex //' | $AWK 'BEGIN { FS = "."; } { printf "%d", $1 * 10000 + $2 * 100 + $3;}'` + version=`$LEX --version 2>/dev/null | $SED -e 's/flex//' -e 's/version//' | $AWK -F "." '{ printf "%d", $1 * 10000 + $2 * 100 + $3;}'` if test -n "$version" -a "$version" -ge 20535; then : else diff --git a/script/yylex.l b/script/yylex.l index 4d7c66448..0cf33c951 100644 --- a/script/yylex.l +++ b/script/yylex.l @@ -86,12 +86,6 @@ typedef size_t yy_size_t; #define exit(...) #endif -#pragma GCC diagnostic warning "-Wunused-variable" -#pragma GCC diagnostic warning "-Wunused-function" -#pragma GCC diagnostic warning "-Wunused-parameter" -#pragma GCC diagnostic warning "-Wstrict-prototypes" -#pragma GCC diagnostic warning "-Wmissing-prototypes" - } %option ecs From df60998c64afaf0025f59365c172109c6ecab774 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Thu, 8 Apr 2010 10:54:44 +0100 Subject: [PATCH 544/738] * util/grub.d/10_linux.in: Only use the first word of GRUB_DISTRIBUTOR for --class, to avoid problems if somebody puts spaces in GRUB_DISTRIBUTOR. * util/grub.d/10_kfreebsd.in: Likewise. * util/grub.d/10_hurd.in: Likewise. --- ChangeLog | 8 ++++++++ util/grub.d/10_hurd.in | 2 +- util/grub.d/10_kfreebsd.in | 2 +- util/grub.d/10_linux.in | 2 +- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7441af4b3..83825a6c3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2010-04-08 Colin Watson + + * util/grub.d/10_linux.in: Only use the first word of + GRUB_DISTRIBUTOR for --class, to avoid problems if somebody puts + spaces in GRUB_DISTRIBUTOR. + * util/grub.d/10_kfreebsd.in: Likewise. + * util/grub.d/10_hurd.in: Likewise. + 2010-04-06 BVK Chaitanya Fix unit testing framework for Qemu 0.12. diff --git a/util/grub.d/10_hurd.in b/util/grub.d/10_hurd.in index fbb4eb752..5dbb11f22 100644 --- a/util/grub.d/10_hurd.in +++ b/util/grub.d/10_hurd.in @@ -27,7 +27,7 @@ if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then OS=GNU else OS="${GRUB_DISTRIBUTOR} GNU/Hurd" - CLASS="--class $(echo ${GRUB_DISTRIBUTOR} | tr '[A-Z]' '[a-z]') ${CLASS}" + CLASS="--class $(echo ${GRUB_DISTRIBUTOR} | tr '[A-Z]' '[a-z]' | cut -d' ' -f1) ${CLASS}" fi at_least_one=false diff --git a/util/grub.d/10_kfreebsd.in b/util/grub.d/10_kfreebsd.in index dc87d6162..43651c82b 100644 --- a/util/grub.d/10_kfreebsd.in +++ b/util/grub.d/10_kfreebsd.in @@ -30,7 +30,7 @@ CLASS="--class os" case "${GRUB_DISTRIBUTOR}" in Debian) OS="${GRUB_DISTRIBUTOR} GNU/kFreeBSD" - CLASS="--class $(echo ${GRUB_DISTRIBUTOR} | tr '[A-Z]' '[a-z]') --class gnu-kfreebsd --class gnu ${CLASS}" + CLASS="--class $(echo ${GRUB_DISTRIBUTOR} | tr '[A-Z]' '[a-z]' | cut -d' ' -f1) --class gnu-kfreebsd --class gnu ${CLASS}" ;; *) OS="FreeBSD" diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in index 2c60bc681..8dc0df5d9 100644 --- a/util/grub.d/10_linux.in +++ b/util/grub.d/10_linux.in @@ -31,7 +31,7 @@ if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then OS=GNU/Linux else OS="${GRUB_DISTRIBUTOR} GNU/Linux" - CLASS="--class $(echo ${GRUB_DISTRIBUTOR} | tr '[A-Z]' '[a-z]') ${CLASS}" + CLASS="--class $(echo ${GRUB_DISTRIBUTOR} | tr '[A-Z]' '[a-z]' | cut -d' ' -f1) ${CLASS}" fi # loop-AES arranges things so that /dev/loop/X can be our root device, but From b7841cebaafade6c545b7bef66ae2a0a1c7be91f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 9 Apr 2010 16:18:25 +0200 Subject: [PATCH 545/738] 2010-04-09 Vladimir Serbinenko * Makefile.in: Specify files explicitly instead of using $< and $@ since we use cd $(srcdir). --- ChangeLog | 5 +++++ Makefile.in | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 83825a6c3..ee19f60d7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-04-09 Vladimir Serbinenko + + * Makefile.in: Specify files explicitly instead of using $< and $@ since + we use cd $(srcdir). + 2010-04-08 Colin Watson * util/grub.d/10_linux.in: Only use the first word of diff --git a/Makefile.in b/Makefile.in index ed460e4cf..d5eda4be3 100644 --- a/Makefile.in +++ b/Makefile.in @@ -530,8 +530,8 @@ genkernsyms.sh: genkernsyms.sh.in config.status $(SHELL) ./config.status $(srcdir)/po/$(PACKAGE).pot: po/POTFILES po/POTFILES-shell - cd $(srcdir) && $(XGETTEXT) -ctranslate --from-code=utf-8 -o $@ -f $< --keyword=_ --keyword=N_ - cd $(srcdir) && $(XGETTEXT) -ctranslate --from-code=utf-8 -o $@ -f po/POTFILES-shell -j --language=Shell + cd $(srcdir) && $(XGETTEXT) -ctranslate --from-code=utf-8 -o po/$(PACKAGE).pot -f po/POTFILES --keyword=_ --keyword=N_ + cd $(srcdir) && $(XGETTEXT) -ctranslate --from-code=utf-8 -o po/$(PACKAGE).pot -f po/POTFILES-shell -j --language=Shell $(foreach lang, $(LINGUAS), $(srcdir)/po/$(lang).po): po/$(PACKAGE).pot $(MSGMERGE) -U $@ $^ From d64795c0eb35035727f5186535f4b81df0542d99 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 9 Apr 2010 16:56:07 +0200 Subject: [PATCH 546/738] Load fonts and modules for gfxmenu in grub-mkconfig. Idea by: Mario Vasquez * util/grub.d/00_header.in: Load pf2 and image modules. --- ChangeLog | 7 +++++++ util/grub.d/00_header.in | 26 ++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/ChangeLog b/ChangeLog index cbc8ff331..0b77ea6a4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-04-09 Vladimir Serbinenko + + Load fonts and modules for gfxmenu in grub-mkconfig. + Idea by: Mario Vasquez + + * util/grub.d/00_header.in: Load pf2 and image modules. + 2010-04-09 Vladimir Serbinenko grub-mkconfig multiple terminal support. diff --git a/util/grub.d/00_header.in b/util/grub.d/00_header.in index 81f7a213a..f99010d6d 100644 --- a/util/grub.d/00_header.in +++ b/util/grub.d/00_header.in @@ -98,6 +98,32 @@ EOF prepare_grub_to_access_device `${grub_probe} --target=device $GRUB_THEME` | sed -e "s/^/ /" cat << EOF insmod gfxmenu +EOF + themedir="`dirname $GRUB_THEME`" + for x in "$themedir"/*.pf2 "$themedir"/f/*.pf2; do + if [ -f "$x" ]; then + cat << EOF + loadfont (\$root)`make_system_path_relative_to_its_root $x` +EOF + fi + done + if [ x"`echo "$themedir"/*.jpg`" != x"$themedir/*.jpg" ]; then + cat << EOF + insmod jpeg +EOF + fi + if [ x"`echo "$themedir"/*.png`" != x"$themedir/*.png" ]; then + cat << EOF + insmod png +EOF + fi + if [ x"`echo "$themedir"/*.tga`" != x"$themedir/*.tga" ]; then + cat << EOF + insmod tga +EOF + fi + + cat << EOF set theme=(\$root)`make_system_path_relative_to_its_root $GRUB_THEME` EOF fi From d7c43ba1c0e8c2449377c1b3aa43238f985f83da Mon Sep 17 00:00:00 2001 From: Mario Vazquez Date: Fri, 9 Apr 2010 17:37:38 +0200 Subject: [PATCH 547/738] GRUB_BACKGROUND support. * util/grub-mkconfig.in: Export GRUB_BACKGROUND. * util/grub.d/00_header.in: Parse GRUB_BACKGROUND. --- ChangeLog | 9 ++++++++- util/grub-mkconfig.in | 1 + util/grub.d/00_header.in | 14 ++++++++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 0b77ea6a4..1fdd2a21b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,7 +1,14 @@ +2010-04-09 Mario Vazquez + + GRUB_BACKGROUND support. + + * util/grub-mkconfig.in: Export GRUB_BACKGROUND. + * util/grub.d/00_header.in: Parse GRUB_BACKGROUND. + 2010-04-09 Vladimir Serbinenko Load fonts and modules for gfxmenu in grub-mkconfig. - Idea by: Mario Vasquez + Idea by: Mario Vazquez * util/grub.d/00_header.in: Load pf2 and image modules. diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in index 94cd2e199..b98bbc993 100644 --- a/util/grub-mkconfig.in +++ b/util/grub-mkconfig.in @@ -233,6 +233,7 @@ export GRUB_DEFAULT \ GRUB_DISABLE_LINUX_UUID \ GRUB_DISABLE_LINUX_RECOVERY \ GRUB_GFXMODE \ + GRUB_BACKGROUND \ GRUB_THEME \ GRUB_GFXPAYLOAD_LINUX \ GRUB_DISABLE_OS_PROBER \ diff --git a/util/grub.d/00_header.in b/util/grub.d/00_header.in index f99010d6d..beb9653da 100644 --- a/util/grub.d/00_header.in +++ b/util/grub.d/00_header.in @@ -125,6 +125,20 @@ EOF cat << EOF set theme=(\$root)`make_system_path_relative_to_its_root $GRUB_THEME` +EOF + elif [ "x$GRUB_BACKGROUND" != x ] && [ -f "$GRUB_BACKGROUND" ] \ + && is_path_readable_by_grub "$GRUB_BACKGROUND"; then + echo "Found background: $GRUB_BACKGROUND" >&2 + case "$GRUB_BACKGROUND" in + *.png) reader=png ;; + *.tga) reader=tga ;; + *.jpg|*.jpeg) reader=jpeg ;; + *) echo "Unsupported image format" >&2; exit 1 ;; + esac + prepare_grub_to_access_device `${grub_probe} --target=device "$GRUB_BACKGROUND"` | sed -e "s/^/ /" + cat << EOF + insmod $reader + background_image -m stretch `make_system_path_relative_to_its_root "$GRUB_BACKGROUND"` EOF fi cat << EOF From e215d8e02a47435a54f5c014c2ee99b59153d601 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 9 Apr 2010 17:44:03 +0200 Subject: [PATCH 548/738] * util/grub.d/00_header.in: Add few missing quotes. Recognise *.jpeg as *.jpg. --- ChangeLog | 5 +++++ util/grub.d/00_header.in | 14 +++++++------- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1fdd2a21b..1db00bc4d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-04-09 Vladimir Serbinenko + + * util/grub.d/00_header.in: Add few missing quotes. Recognise *.jpeg + as *.jpg. + 2010-04-09 Mario Vazquez GRUB_BACKGROUND support. diff --git a/util/grub.d/00_header.in b/util/grub.d/00_header.in index beb9653da..d181fdffc 100644 --- a/util/grub.d/00_header.in +++ b/util/grub.d/00_header.in @@ -84,22 +84,22 @@ fi if [ "x$gfxterm" = x1 ]; then # Make the font accessible - prepare_grub_to_access_device `${grub_probe} --target=device ${GRUB_FONT_PATH}` + prepare_grub_to_access_device `${grub_probe} --target=device "${GRUB_FONT_PATH}"` cat << EOF -if loadfont `make_system_path_relative_to_its_root ${GRUB_FONT_PATH}` ; then +if loadfont `make_system_path_relative_to_its_root "${GRUB_FONT_PATH}"` ; then set gfxmode=${GRUB_GFXMODE} insmod gfxterm insmod ${GRUB_VIDEO_BACKEND} EOF - if [ x$GRUB_THEME != x ] && [ -f $GRUB_THEME ] \ - && is_path_readable_by_grub $GRUB_THEME; then + if [ "x$GRUB_THEME" != x ] && [ -f "$GRUB_THEME" ] \ + && is_path_readable_by_grub "$GRUB_THEME"; then echo "Found theme: $GRUB_THEME" >&2 - prepare_grub_to_access_device `${grub_probe} --target=device $GRUB_THEME` | sed -e "s/^/ /" + prepare_grub_to_access_device `${grub_probe} --target=device "$GRUB_THEME"` | sed -e "s/^/ /" cat << EOF insmod gfxmenu EOF - themedir="`dirname $GRUB_THEME`" + themedir="`dirname "$GRUB_THEME"`" for x in "$themedir"/*.pf2 "$themedir"/f/*.pf2; do if [ -f "$x" ]; then cat << EOF @@ -107,7 +107,7 @@ EOF EOF fi done - if [ x"`echo "$themedir"/*.jpg`" != x"$themedir/*.jpg" ]; then + if [ x"`echo "$themedir"/*.jpg`" != x"$themedir/*.jpg" ] || [ x"`echo "$themedir"/*.jpeg`" != x"$themedir/*.jpeg" ]; then cat << EOF insmod jpeg EOF From 1118c32ec7cde35f2d6da9f4fb6e41c8aadf6186 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 9 Apr 2010 19:38:23 +0200 Subject: [PATCH 549/738] * font/font.c: Indented. --- ChangeLog | 4 + font/font.c | 462 ++++++++++++++++++++++++++-------------------------- 2 files changed, 233 insertions(+), 233 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1e23de038..d6cdfdbe8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-04-09 Vladimir Serbinenko + + * font/font.c: Indented. + 2010-04-09 BVK Chaitanya Elif support to GRUB script (by Deepak Vankadaru). diff --git a/font/font.c b/font/font.c index 1b3dc6387..9a89cadc5 100644 --- a/font/font.c +++ b/font/font.c @@ -91,25 +91,24 @@ struct font_file_section }; /* Replace unknown glyphs with a rounded question mark. */ -static grub_uint8_t unknown_glyph_bitmap[] = -{ - /* 76543210 */ - 0x7C, /* ooooo */ - 0x82, /* o o */ - 0xBA, /* o ooo o */ - 0xAA, /* o o o o */ - 0xAA, /* o o o o */ - 0x8A, /* o o o */ - 0x9A, /* o oo o */ - 0x92, /* o o o */ - 0x92, /* o o o */ - 0x92, /* o o o */ - 0x92, /* o o o */ - 0x82, /* o o */ - 0x92, /* o o o */ - 0x82, /* o o */ - 0x7C, /* ooooo */ - 0x00 /* */ +static grub_uint8_t unknown_glyph_bitmap[] = { + /* 76543210 */ + 0x7C, /* ooooo */ + 0x82, /* o o */ + 0xBA, /* o ooo o */ + 0xAA, /* o o o o */ + 0xAA, /* o o o o */ + 0x8A, /* o o o */ + 0x9A, /* o oo o */ + 0x92, /* o o o */ + 0x92, /* o o o */ + 0x92, /* o o o */ + 0x92, /* o o o */ + 0x82, /* o o */ + 0x92, /* o o o */ + 0x82, /* o o */ + 0x7C, /* ooooo */ + 0x00 /* */ }; /* The "unknown glyph" glyph, used as a last resort. */ @@ -130,7 +129,7 @@ static struct grub_font_glyph *ascii_font_glyph[0x80]; static struct grub_font_glyph * ascii_glyph_lookup (grub_uint32_t code) { -#ifdef USE_ASCII_FAILBACK +#ifdef USE_ASCII_FAILBACK static int ascii_failback_initialized = 0; if (code >= 0x80) @@ -140,14 +139,14 @@ ascii_glyph_lookup (grub_uint32_t code) { int current; for (current = 0; current < 0x80; current++) - { - ascii_font_glyph[current] = grub_malloc(sizeof(struct grub_font_glyph) - + ASCII_BITMAP_SIZE); + { + ascii_font_glyph[current] = + grub_malloc (sizeof (struct grub_font_glyph) + ASCII_BITMAP_SIZE); - ascii_font_glyph[current]->width = 8; - ascii_font_glyph[current]->height = 16; - ascii_font_glyph[current]->offset_x = 0; - ascii_font_glyph[current]->offset_y = -2; + ascii_font_glyph[current]->width = 8; + ascii_font_glyph[current]->height = 16; + ascii_font_glyph[current]->offset_x = 0; + ascii_font_glyph[current]->offset_y = -2; ascii_font_glyph[current]->device_width = 8; grub_memcpy (ascii_font_glyph[current]->bitmap, @@ -173,9 +172,9 @@ grub_font_loader_init (void) return; /* Make glyph for unknown glyph. */ - unknown_glyph = grub_malloc(sizeof(struct grub_font_glyph) - + sizeof(unknown_glyph_bitmap)); - if (! unknown_glyph) + unknown_glyph = grub_malloc (sizeof (struct grub_font_glyph) + + sizeof (unknown_glyph_bitmap)); + if (!unknown_glyph) return; unknown_glyph->width = 8; @@ -183,13 +182,13 @@ grub_font_loader_init (void) unknown_glyph->offset_x = 0; unknown_glyph->offset_y = -3; unknown_glyph->device_width = 8; - grub_memcpy(unknown_glyph->bitmap, - unknown_glyph_bitmap, sizeof(unknown_glyph_bitmap)); + grub_memcpy (unknown_glyph->bitmap, + unknown_glyph_bitmap, sizeof (unknown_glyph_bitmap)); /* Initialize the null font. */ font_init (&null_font); null_font.name = ""; - null_font.ascent = unknown_glyph->height-3; + null_font.ascent = unknown_glyph->height - 3; null_font.descent = 3; null_font.max_char_width = unknown_glyph->width; null_font.max_char_height = unknown_glyph->height; @@ -247,7 +246,7 @@ open_section (grub_file_t file, struct font_file_section *section) else if (retval < 0) { grub_error (GRUB_ERR_BAD_FONT, - "font format error: can't read section name"); + "font format error: can't read section name"); return 1; } @@ -262,7 +261,7 @@ open_section (grub_file_t file, struct font_file_section *section) else if (retval < 0) { grub_error (GRUB_ERR_BAD_FONT, - "font format error: can't read section length"); + "font format error: can't read section length"); return 1; } @@ -283,22 +282,22 @@ open_section (grub_file_t file, struct font_file_section *section) grub_errno is set appropriately). */ static int load_font_index (grub_file_t file, grub_uint32_t sect_length, struct - grub_font *font) + grub_font *font) { unsigned i; grub_uint32_t last_code; #if FONT_DEBUG >= 2 - grub_printf("load_font_index(sect_length=%d)\n", sect_length); + grub_printf ("load_font_index(sect_length=%d)\n", sect_length); #endif /* Sanity check: ensure section length is divisible by the entry size. */ if ((sect_length % FONT_CHAR_INDEX_ENTRY_SIZE) != 0) { grub_error (GRUB_ERR_BAD_FONT, - "font file format error: character index length %d " - "is not a multiple of the entry size %d", - sect_length, FONT_CHAR_INDEX_ENTRY_SIZE); + "font file format error: character index length %d " + "is not a multiple of the entry size %d", + sect_length, FONT_CHAR_INDEX_ENTRY_SIZE); return 1; } @@ -307,11 +306,11 @@ load_font_index (grub_file_t file, grub_uint32_t sect_length, struct /* Allocate the character index array. */ font->char_index = grub_malloc (font->num_chars - * sizeof (struct char_index_entry)); - if (! font->char_index) + * sizeof (struct char_index_entry)); + if (!font->char_index) return 1; font->bmp_idx = grub_malloc (0x10000 * sizeof (grub_uint16_t)); - if (! font->bmp_idx) + if (!font->bmp_idx) { grub_free (font->char_index); return 1; @@ -320,7 +319,7 @@ load_font_index (grub_file_t file, grub_uint32_t sect_length, struct #if FONT_DEBUG >= 2 - grub_printf("num_chars=%d)\n", font->num_chars); + grub_printf ("num_chars=%d)\n", font->num_chars); #endif last_code = 0; @@ -332,17 +331,17 @@ load_font_index (grub_file_t file, grub_uint32_t sect_length, struct /* Read code point value; convert to native byte order. */ if (grub_file_read (file, &entry->code, 4) != 4) - return 1; + return 1; entry->code = grub_be_to_cpu32 (entry->code); /* Verify that characters are in ascending order. */ if (i != 0 && entry->code <= last_code) - { - grub_error (GRUB_ERR_BAD_FONT, - "font characters not in ascending order: %u <= %u", - entry->code, last_code); - return 1; - } + { + grub_error (GRUB_ERR_BAD_FONT, + "font characters not in ascending order: %u <= %u", + entry->code, last_code); + return 1; + } if (entry->code < 0x10000) font->bmp_idx[entry->code] = i; @@ -351,11 +350,11 @@ load_font_index (grub_file_t file, grub_uint32_t sect_length, struct /* Read storage flags byte. */ if (grub_file_read (file, &entry->storage_flags, 1) != 1) - return 1; + return 1; /* Read glyph data offset; convert to native byte order. */ if (grub_file_read (file, &entry->offset, 4) != 4) - return 1; + return 1; entry->offset = grub_be_to_cpu32 (entry->offset); /* No glyph loaded. Will be loaded on demand and cached thereafter. */ @@ -364,7 +363,7 @@ load_font_index (grub_file_t file, grub_uint32_t sect_length, struct #if FONT_DEBUG >= 5 /* Print the 1st 10 characters. */ if (i < 10) - grub_printf("c=%d o=%d\n", entry->code, entry->offset); + grub_printf ("c=%d o=%d\n", entry->code, entry->offset); #endif } @@ -380,7 +379,7 @@ read_section_as_string (struct font_file_section *section) grub_ssize_t ret; str = grub_malloc (section->length + 1); - if (! str) + if (!str) return 0; ret = grub_file_read (section->file, str, section->length); @@ -398,18 +397,18 @@ read_section_as_string (struct font_file_section *section) which is stored into *VALUE. Returns 0 upon success, nonzero upon failure. */ static int -read_section_as_short (struct font_file_section *section, grub_int16_t *value) +read_section_as_short (struct font_file_section *section, + grub_int16_t * value) { grub_uint16_t raw_value; if (section->length != 2) { grub_error (GRUB_ERR_BAD_FONT, - "font file format error: section %c%c%c%c length " - "is %d but should be 2", - section->name[0], section->name[1], - section->name[2], section->name[3], - section->length); + "font file format error: section %c%c%c%c length " + "is %d but should be 2", + section->name[0], section->name[1], + section->name[2], section->name[3], section->length); return 1; } if (grub_file_read (section->file, &raw_value, 2) != 2) @@ -430,7 +429,7 @@ grub_font_load (const char *filename) grub_font_t font = 0; #if FONT_DEBUG >= 1 - grub_printf("add_font(%s)\n", filename); + grub_printf ("add_font(%s)\n", filename); #endif file = grub_buffile_open (filename, 1024); @@ -438,7 +437,7 @@ grub_font_load (const char *filename) goto fail; #if FONT_DEBUG >= 3 - grub_printf("file opened\n"); + grub_printf ("file opened\n"); #endif /* Read the FILE section. It indicates the file format. */ @@ -446,159 +445,166 @@ grub_font_load (const char *filename) goto fail; #if FONT_DEBUG >= 3 - grub_printf("opened FILE section\n"); + grub_printf ("opened FILE section\n"); #endif if (grub_memcmp (section.name, FONT_FORMAT_SECTION_NAMES_FILE, - sizeof(FONT_FORMAT_SECTION_NAMES_FILE) - 1) != 0) + sizeof (FONT_FORMAT_SECTION_NAMES_FILE) - 1) != 0) { grub_error (GRUB_ERR_BAD_FONT, - "font file format error: 1st section must be FILE"); + "font file format error: 1st section must be FILE"); goto fail; } #if FONT_DEBUG >= 3 - grub_printf("section name ok\n"); + grub_printf ("section name ok\n"); #endif if (section.length != 4) { grub_error (GRUB_ERR_BAD_FONT, - "font file format error (file type ID length is %d " - "but should be 4)", section.length); + "font file format error (file type ID length is %d " + "but should be 4)", section.length); goto fail; } #if FONT_DEBUG >= 3 - grub_printf("section length ok\n"); + grub_printf ("section length ok\n"); #endif /* Check the file format type code. */ if (grub_file_read (file, magic, 4) != 4) goto fail; #if FONT_DEBUG >= 3 - grub_printf("read magic ok\n"); + grub_printf ("read magic ok\n"); #endif if (grub_memcmp (magic, FONT_FORMAT_PFF2_MAGIC, 4) != 0) { grub_error (GRUB_ERR_BAD_FONT, "invalid font magic %x %x %x %x", - magic[0], magic[1], magic[2], magic[3]); + magic[0], magic[1], magic[2], magic[3]); goto fail; } #if FONT_DEBUG >= 3 - grub_printf("compare magic ok\n"); + grub_printf ("compare magic ok\n"); #endif /* Allocate the font object. */ font = (grub_font_t) grub_malloc (sizeof (struct grub_font)); - if (! font) + if (!font) goto fail; font_init (font); font->file = file; #if FONT_DEBUG >= 3 - grub_printf("allocate font ok; loading font info\n"); + grub_printf ("allocate font ok; loading font info\n"); #endif /* Load the font information. */ while (1) { if (open_section (file, §ion) != 0) - { - if (section.eof) - break; /* Done reading the font file. */ - else - goto fail; - } + { + if (section.eof) + break; /* Done reading the font file. */ + else + goto fail; + } #if FONT_DEBUG >= 2 - grub_printf("opened section %c%c%c%c ok\n", - section.name[0], section.name[1], - section.name[2], section.name[3]); + grub_printf ("opened section %c%c%c%c ok\n", + section.name[0], section.name[1], + section.name[2], section.name[3]); #endif if (grub_memcmp (section.name, FONT_FORMAT_SECTION_NAMES_FONT_NAME, - sizeof(FONT_FORMAT_SECTION_NAMES_FONT_NAME) - 1) == 0) - { - font->name = read_section_as_string (§ion); - if (!font->name) - goto fail; - } + sizeof (FONT_FORMAT_SECTION_NAMES_FONT_NAME) - 1) == 0) + { + font->name = read_section_as_string (§ion); + if (!font->name) + goto fail; + } else if (grub_memcmp (section.name, - FONT_FORMAT_SECTION_NAMES_POINT_SIZE, - sizeof(FONT_FORMAT_SECTION_NAMES_POINT_SIZE) - 1) == 0) - { - if (read_section_as_short (§ion, &font->point_size) != 0) - goto fail; - } + FONT_FORMAT_SECTION_NAMES_POINT_SIZE, + sizeof (FONT_FORMAT_SECTION_NAMES_POINT_SIZE) - + 1) == 0) + { + if (read_section_as_short (§ion, &font->point_size) != 0) + goto fail; + } else if (grub_memcmp (section.name, FONT_FORMAT_SECTION_NAMES_WEIGHT, - sizeof(FONT_FORMAT_SECTION_NAMES_WEIGHT) - 1) == 0) - { - char *wt; - wt = read_section_as_string (§ion); - if (!wt) - continue; - /* Convert the weight string 'normal' or 'bold' into a number. */ - if (grub_strcmp (wt, "normal") == 0) - font->weight = FONT_WEIGHT_NORMAL; - else if (grub_strcmp (wt, "bold") == 0) - font->weight = FONT_WEIGHT_BOLD; - grub_free (wt); - } + sizeof (FONT_FORMAT_SECTION_NAMES_WEIGHT) - 1) + == 0) + { + char *wt; + wt = read_section_as_string (§ion); + if (!wt) + continue; + /* Convert the weight string 'normal' or 'bold' into a number. */ + if (grub_strcmp (wt, "normal") == 0) + font->weight = FONT_WEIGHT_NORMAL; + else if (grub_strcmp (wt, "bold") == 0) + font->weight = FONT_WEIGHT_BOLD; + grub_free (wt); + } else if (grub_memcmp (section.name, - FONT_FORMAT_SECTION_NAMES_MAX_CHAR_WIDTH, - sizeof(FONT_FORMAT_SECTION_NAMES_MAX_CHAR_WIDTH) - 1) == 0) - { - if (read_section_as_short (§ion, &font->max_char_width) != 0) - goto fail; - } + FONT_FORMAT_SECTION_NAMES_MAX_CHAR_WIDTH, + sizeof (FONT_FORMAT_SECTION_NAMES_MAX_CHAR_WIDTH) + - 1) == 0) + { + if (read_section_as_short (§ion, &font->max_char_width) != 0) + goto fail; + } else if (grub_memcmp (section.name, - FONT_FORMAT_SECTION_NAMES_MAX_CHAR_HEIGHT, - sizeof(FONT_FORMAT_SECTION_NAMES_MAX_CHAR_HEIGHT) - 1) == 0) - { - if (read_section_as_short (§ion, &font->max_char_height) != 0) - goto fail; - } + FONT_FORMAT_SECTION_NAMES_MAX_CHAR_HEIGHT, + sizeof (FONT_FORMAT_SECTION_NAMES_MAX_CHAR_HEIGHT) + - 1) == 0) + { + if (read_section_as_short (§ion, &font->max_char_height) != 0) + goto fail; + } else if (grub_memcmp (section.name, - FONT_FORMAT_SECTION_NAMES_ASCENT, - sizeof(FONT_FORMAT_SECTION_NAMES_ASCENT) - 1) == 0) - { - if (read_section_as_short (§ion, &font->ascent) != 0) - goto fail; - } + FONT_FORMAT_SECTION_NAMES_ASCENT, + sizeof (FONT_FORMAT_SECTION_NAMES_ASCENT) - 1) + == 0) + { + if (read_section_as_short (§ion, &font->ascent) != 0) + goto fail; + } else if (grub_memcmp (section.name, FONT_FORMAT_SECTION_NAMES_DESCENT, - sizeof(FONT_FORMAT_SECTION_NAMES_DESCENT) - 1) == 0) - { - if (read_section_as_short (§ion, &font->descent) != 0) - goto fail; - } + sizeof (FONT_FORMAT_SECTION_NAMES_DESCENT) - 1) + == 0) + { + if (read_section_as_short (§ion, &font->descent) != 0) + goto fail; + } else if (grub_memcmp (section.name, - FONT_FORMAT_SECTION_NAMES_CHAR_INDEX, - sizeof(FONT_FORMAT_SECTION_NAMES_CHAR_INDEX) - 1) == 0) - { - if (load_font_index (file, section.length, font) != 0) - goto fail; - } + FONT_FORMAT_SECTION_NAMES_CHAR_INDEX, + sizeof (FONT_FORMAT_SECTION_NAMES_CHAR_INDEX) - + 1) == 0) + { + if (load_font_index (file, section.length, font) != 0) + goto fail; + } else if (grub_memcmp (section.name, FONT_FORMAT_SECTION_NAMES_DATA, - sizeof(FONT_FORMAT_SECTION_NAMES_DATA) - 1) == 0) - { - /* When the DATA section marker is reached, we stop reading. */ - break; - } + sizeof (FONT_FORMAT_SECTION_NAMES_DATA) - 1) == 0) + { + /* When the DATA section marker is reached, we stop reading. */ + break; + } else - { - /* Unhandled section type, simply skip past it. */ + { + /* Unhandled section type, simply skip past it. */ #if FONT_DEBUG >= 3 - grub_printf("Unhandled section type, skipping.\n"); + grub_printf ("Unhandled section type, skipping.\n"); #endif - grub_off_t section_end = grub_file_tell (file) + section.length; - if ((int) grub_file_seek (file, section_end) == -1) - goto fail; - } + grub_off_t section_end = grub_file_tell (file) + section.length; + if ((int) grub_file_seek (file, section_end) == -1) + goto fail; + } } - if (! font->name) + if (!font->name) { grub_printf ("Note: Font has no name.\n"); font->name = grub_strdup ("Unknown"); @@ -606,22 +612,19 @@ grub_font_load (const char *filename) #if FONT_DEBUG >= 1 grub_printf ("Loaded font `%s'.\n" - "Ascent=%d Descent=%d MaxW=%d MaxH=%d Number of characters=%d.\n", - font->name, - font->ascent, font->descent, - font->max_char_width, font->max_char_height, - font->num_chars); + "Ascent=%d Descent=%d MaxW=%d MaxH=%d Number of characters=%d.\n", + font->name, + font->ascent, font->descent, + font->max_char_width, font->max_char_height, font->num_chars); #endif if (font->max_char_width == 0 || font->max_char_height == 0 || font->num_chars == 0 - || font->char_index == 0 - || font->ascent == 0 - || font->descent == 0) + || font->char_index == 0 || font->ascent == 0 || font->descent == 0) { grub_error (GRUB_ERR_BAD_FONT, - "invalid font file: missing some required data"); + "invalid font file: missing some required data"); goto fail; } @@ -679,18 +682,18 @@ find_glyph (const grub_font_t font, grub_uint32_t code) lo = 0; hi = font->num_chars - 1; - if (! table) + if (!table) return 0; while (lo <= hi) { mid = lo + (hi - lo) / 2; if (code < table[mid].code) - hi = mid - 1; + hi = mid - 1; else if (code > table[mid].code) - lo = mid + 1; + lo = mid + 1; else - return &table[mid]; + return &table[mid]; } return 0; @@ -716,12 +719,12 @@ grub_font_get_glyph_internal (grub_font_t font, grub_uint32_t code) int len; if (index_entry->glyph) - /* Return cached glyph. */ - return index_entry->glyph; + /* Return cached glyph. */ + return index_entry->glyph; - if (! font->file) - /* No open file, can't load any glyphs. */ - return 0; + if (!font->file) + /* No open file, can't load any glyphs. */ + return 0; /* Make sure we can find glyphs for error messages. Push active error message to error stack and reset error message. */ @@ -730,23 +733,23 @@ grub_font_get_glyph_internal (grub_font_t font, grub_uint32_t code) grub_file_seek (font->file, index_entry->offset); /* Read the glyph width, height, and baseline. */ - if (read_be_uint16(font->file, &width) != 0 - || read_be_uint16(font->file, &height) != 0 - || read_be_int16(font->file, &xoff) != 0 - || read_be_int16(font->file, &yoff) != 0 - || read_be_int16(font->file, &dwidth) != 0) - { - remove_font (font); - return 0; - } + if (read_be_uint16 (font->file, &width) != 0 + || read_be_uint16 (font->file, &height) != 0 + || read_be_int16 (font->file, &xoff) != 0 + || read_be_int16 (font->file, &yoff) != 0 + || read_be_int16 (font->file, &dwidth) != 0) + { + remove_font (font); + return 0; + } len = (width * height + 7) / 8; glyph = grub_malloc (sizeof (struct grub_font_glyph) + len); - if (! glyph) - { - remove_font (font); - return 0; - } + if (!glyph) + { + remove_font (font); + return 0; + } glyph->font = font; glyph->width = width; @@ -757,13 +760,13 @@ grub_font_get_glyph_internal (grub_font_t font, grub_uint32_t code) /* Don't try to read empty bitmaps (e.g., space characters). */ if (len != 0) - { - if (grub_file_read (font->file, glyph->bitmap, len) != len) - { - remove_font (font); - return 0; - } - } + { + if (grub_file_read (font->file, glyph->bitmap, len) != len) + { + remove_font (font); + return 0; + } + } /* Restore old error message. */ grub_error_pop (); @@ -787,7 +790,7 @@ free_font (grub_font_t font) if (font) { if (font->file) - grub_file_close (font->file); + grub_file_close (font->file); grub_free (font->name); grub_free (font->family); grub_free (font->char_index); @@ -804,7 +807,7 @@ register_font (grub_font_t font) struct grub_font_node *node = 0; node = grub_malloc (sizeof (struct grub_font_node)); - if (! node) + if (!node) return 1; node->value = font; @@ -822,18 +825,17 @@ remove_font (grub_font_t font) struct grub_font_node **nextp, *cur; for (nextp = &grub_font_list, cur = *nextp; - cur; - nextp = &cur->next, cur = cur->next) + cur; nextp = &cur->next, cur = cur->next) { if (cur->value == font) - { - *nextp = cur->next; + { + *nextp = cur->next; - /* Free the node, but not the font itself. */ - grub_free (cur); + /* Free the node, but not the font itself. */ + grub_free (cur); - return; - } + return; + } } } @@ -850,7 +852,7 @@ grub_font_get (const char *font_name) { grub_font_t font = node->value; if (grub_strcmp (font->name, font_name) == 0) - return font; + return font; } /* If no font by that name is found, return the first font in the list @@ -927,7 +929,7 @@ grub_font_get_string_width (grub_font_t font, const char *str) const grub_uint8_t *ptr; for (ptr = (const grub_uint8_t *) str, width = 0; - grub_utf8_to_ucs4 (&code, 1, ptr, -1, &ptr) > 0; ) + grub_utf8_to_ucs4 (&code, 1, ptr, -1, &ptr) > 0;) { glyph = grub_font_get_glyph_with_fallback (font, code); width += glyph->device_width; @@ -961,7 +963,7 @@ grub_font_get_glyph (grub_font_t font, grub_uint32_t code) sizes are used so that tiny 8 point glyphs are not mixed into a string of 24 point text unless there is no other choice. */ static int -get_font_diversity(grub_font_t a, grub_font_t b) +get_font_diversity (grub_font_t a, grub_font_t b) { int d; @@ -1011,7 +1013,7 @@ grub_font_get_glyph_with_fallback (grub_font_t font, grub_uint32_t code) /* First try to get the glyph from the specified font. */ glyph = grub_font_get_glyph_internal (font, code); if (glyph) - return glyph; + return glyph; } /* Otherwise, search all loaded fonts for the glyph and use the one from @@ -1028,16 +1030,16 @@ grub_font_get_glyph_with_fallback (grub_font_t font, grub_uint32_t code) glyph = grub_font_get_glyph_internal (curfont, code); if (glyph) - { - int d; + { + int d; - d = get_font_diversity (curfont, font); - if (d < best_diversity) - { - best_diversity = d; - best_glyph = glyph; - } - } + d = get_font_diversity (curfont, font); + if (d < best_diversity) + { + best_diversity = d; + best_glyph = glyph; + } + } } if (best_glyph) @@ -1052,9 +1054,8 @@ grub_font_get_glyph_with_fallback (grub_font_t font, grub_uint32_t code) baseline of the character, while the x coordinate designates the left side location of the character. */ grub_err_t -grub_font_draw_glyph (struct grub_font_glyph *glyph, - grub_video_color_t color, - int left_x, int baseline_y) +grub_font_draw_glyph (struct grub_font_glyph * glyph, + grub_video_color_t color, int left_x, int baseline_y) { struct grub_video_bitmap glyph_bitmap; @@ -1065,8 +1066,7 @@ grub_font_draw_glyph (struct grub_font_glyph *glyph, glyph_bitmap.mode_info.width = glyph->width; glyph_bitmap.mode_info.height = glyph->height; glyph_bitmap.mode_info.mode_type = - (1 << GRUB_VIDEO_MODE_TYPE_DEPTH_POS) - | GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP; + (1 << GRUB_VIDEO_MODE_TYPE_DEPTH_POS) | GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP; glyph_bitmap.mode_info.blit_format = GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED; glyph_bitmap.mode_info.bpp = 1; @@ -1081,11 +1081,11 @@ grub_font_draw_glyph (struct grub_font_glyph *glyph, glyph_bitmap.mode_info.bg_green = 0; glyph_bitmap.mode_info.bg_blue = 0; glyph_bitmap.mode_info.bg_alpha = 0; - grub_video_unmap_color(color, - &glyph_bitmap.mode_info.fg_red, - &glyph_bitmap.mode_info.fg_green, - &glyph_bitmap.mode_info.fg_blue, - &glyph_bitmap.mode_info.fg_alpha); + grub_video_unmap_color (color, + &glyph_bitmap.mode_info.fg_red, + &glyph_bitmap.mode_info.fg_green, + &glyph_bitmap.mode_info.fg_blue, + &glyph_bitmap.mode_info.fg_alpha); glyph_bitmap.data = glyph->bitmap; int bitmap_left = left_x + glyph->offset_x; @@ -1093,9 +1093,8 @@ grub_font_draw_glyph (struct grub_font_glyph *glyph, int bitmap_top = bitmap_bottom - glyph->height; return grub_video_blit_bitmap (&glyph_bitmap, GRUB_VIDEO_BLIT_BLEND, - bitmap_left, bitmap_top, - 0, 0, - glyph->width, glyph->height); + bitmap_left, bitmap_top, + 0, 0, glyph->width, glyph->height); } /* Draw a UTF-8 string of text on the current video render target. @@ -1105,8 +1104,7 @@ grub_font_draw_glyph (struct grub_font_glyph *glyph, a glyph from another loaded font may be used instead. */ grub_err_t grub_font_draw_string (const char *str, grub_font_t font, - grub_video_color_t color, - int left_x, int baseline_y) + grub_video_color_t color, int left_x, int baseline_y) { int x; struct grub_font_glyph *glyph; @@ -1114,15 +1112,13 @@ grub_font_draw_string (const char *str, grub_font_t font, const grub_uint8_t *ptr; for (ptr = (const grub_uint8_t *) str, x = left_x; - grub_utf8_to_ucs4 (&code, 1, ptr, -1, &ptr) > 0; ) + grub_utf8_to_ucs4 (&code, 1, ptr, -1, &ptr) > 0;) { glyph = grub_font_get_glyph_with_fallback (font, code); - if (grub_font_draw_glyph (glyph, color, x, baseline_y) - != GRUB_ERR_NONE) - return grub_errno; + if (grub_font_draw_glyph (glyph, color, x, baseline_y) != GRUB_ERR_NONE) + return grub_errno; x += glyph->device_width; } return GRUB_ERR_NONE; } - From 477797112671d69767fee13f6e6ddb3b08e2ccff Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 9 Apr 2010 20:40:14 +0200 Subject: [PATCH 550/738] * util/grub-mkrescue.in: Fix incorrect path in coreboot part. Reported by: Thomas Schmitt. Add -no-emul-boot to grub-mkisofs parameters. --- ChangeLog | 6 ++++++ util/grub-mkrescue.in | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index d6cdfdbe8..a2a33b2ef 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-04-09 Vladimir Serbinenko + + * util/grub-mkrescue.in: Fix incorrect path in coreboot part. + Reported by: Thomas Schmitt. + Add -no-emul-boot to grub-mkisofs parameters. + 2010-04-09 Vladimir Serbinenko * font/font.c: Indented. diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in index db29b0899..aafdfb059 100644 --- a/util/grub-mkrescue.in +++ b/util/grub-mkrescue.in @@ -156,7 +156,7 @@ EOF echo "insmod $i" done ; \ echo "source /boot/grub/grub.cfg") \ - > ${iso9660_dir}/boot/grub/i386-pc/grub.cfg + > ${iso9660_dir}/boot/grub/i386-coreboot/grub.cfg tar -C ${memdisk_dir} -cf ${memdisk_img} boot rm -rf ${memdisk_dir} @@ -187,7 +187,7 @@ if test -e "${pc_dir}" ; then echo "source /boot/grub/grub.cfg") \ > ${iso9660_dir}/boot/grub/i386-pc/grub.cfg - grub_mkisofs_arguments="${grub_mkisofs_arguments} -b boot/grub/i386-pc/eltorito.img -boot-info-table \ + grub_mkisofs_arguments="${grub_mkisofs_arguments} -b boot/grub/i386-pc/eltorito.img -no-emul-boot -boot-info-table \ --embedded-boot ${embed_img}" fi From 027de555e271b3954fbd749c293ec807cf720405 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 9 Apr 2010 21:07:24 +0200 Subject: [PATCH 551/738] * normal/autofs.c (read_fs_list): New parameter 'prefix'. All users updated. * normal/crypto.c (read_crypto_list): Likewise. * normal/dyncmd.c (read_command_list): Likewise. * normal/term.c (read_terminal_list): Likewise. * normal/main.c (read_lists): Use explicit prefix. (read_lists_hook): Use read_lists. (grub_normal_execute): Likewise. --- ChangeLog | 11 +++++++++++ include/grub/normal.h | 8 ++++---- normal/autofs.c | 5 +---- normal/crypto.c | 4 +--- normal/dyncmd.c | 5 +---- normal/main.c | 25 ++++++++++++++++--------- normal/term.c | 4 +--- 7 files changed, 35 insertions(+), 27 deletions(-) diff --git a/ChangeLog b/ChangeLog index a2a33b2ef..5f3251fcb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2010-04-09 Vladimir Serbinenko + + * normal/autofs.c (read_fs_list): New parameter 'prefix'. + All users updated. + * normal/crypto.c (read_crypto_list): Likewise. + * normal/dyncmd.c (read_command_list): Likewise. + * normal/term.c (read_terminal_list): Likewise. + * normal/main.c (read_lists): Use explicit prefix. + (read_lists_hook): Use read_lists. + (grub_normal_execute): Likewise. + 2010-04-09 Vladimir Serbinenko * util/grub-mkrescue.in: Fix incorrect path in coreboot part. diff --git a/include/grub/normal.h b/include/grub/normal.h index fe45ddf71..35eedf5ae 100644 --- a/include/grub/normal.h +++ b/include/grub/normal.h @@ -96,17 +96,17 @@ void read_handler_list (void); void free_handler_list (void); /* Defined in `dyncmd.c'. */ -void read_command_list (void); +void read_command_list (const char *prefix); /* Defined in `autofs.c'. */ -void read_fs_list (void); +void read_fs_list (const char *prefix); void grub_context_init (void); void grub_context_fini (void); -void read_crypto_list (void); +void read_crypto_list (const char *prefix); -void read_terminal_list (void); +void read_terminal_list (const char *prefix); void grub_set_more (int onoff); diff --git a/normal/autofs.c b/normal/autofs.c index 11b3fc1be..e1d4c017c 100644 --- a/normal/autofs.c +++ b/normal/autofs.c @@ -51,11 +51,8 @@ autoload_fs_module (void) /* Read the file fs.lst for auto-loading. */ void -read_fs_list (void) +read_fs_list (const char *prefix) { - const char *prefix; - - prefix = grub_env_get ("prefix"); if (prefix) { char *filename; diff --git a/normal/crypto.c b/normal/crypto.c index f051e2c4c..465c9f81d 100644 --- a/normal/crypto.c +++ b/normal/crypto.c @@ -66,14 +66,12 @@ grub_crypto_spec_free (void) /* Read the file crypto.lst for auto-loading. */ void -read_crypto_list (void) +read_crypto_list (const char *prefix) { - const char *prefix; char *filename; grub_file_t file; char *buf = NULL; - prefix = grub_env_get ("prefix"); if (!prefix) { grub_errno = GRUB_ERR_NONE; diff --git a/normal/dyncmd.c b/normal/dyncmd.c index ca9a82289..a3cafa514 100644 --- a/normal/dyncmd.c +++ b/normal/dyncmd.c @@ -60,11 +60,8 @@ grub_dyncmd_dispatcher (struct grub_command *cmd, /* Read the file command.lst for auto-loading. */ void -read_command_list (void) +read_command_list (const char *prefix) { - const char *prefix; - - prefix = grub_env_get ("prefix"); if (prefix) { char *filename; diff --git a/normal/main.c b/normal/main.c index 5a5467485..df92e622b 100644 --- a/normal/main.c +++ b/normal/main.c @@ -434,14 +434,20 @@ grub_normal_init_page (struct grub_term_output *term) grub_free (unicode_msg); } -static char * -read_lists (struct grub_env_var *var __attribute__ ((unused)), - const char *val) +static void +read_lists (const char *val) { - read_command_list (); - read_fs_list (); - read_crypto_list (); - read_terminal_list (); + read_command_list (val); + read_fs_list (val); + read_crypto_list (val); + read_terminal_list (val); +} + +static char * +read_lists_hook (struct grub_env_var *var __attribute__ ((unused)), + const char *val) +{ + read_lists (val); return val ? grub_strdup (val) : NULL; } @@ -451,10 +457,11 @@ void grub_normal_execute (const char *config, int nested, int batch) { grub_menu_t menu = 0; + const char *prefix = grub_env_get ("prefix"); - read_lists (NULL, NULL); + read_lists (prefix); read_handler_list (); - grub_register_variable_hook ("prefix", NULL, read_lists); + grub_register_variable_hook ("prefix", NULL, read_lists_hook); grub_command_execute ("parser.grub", 0, 0); if (config) diff --git a/normal/term.c b/normal/term.c index 7bedd6799..688141dab 100644 --- a/normal/term.c +++ b/normal/term.c @@ -167,14 +167,12 @@ grub_terminal_autoload_free (void) /* Read the file terminal.lst for auto-loading. */ void -read_terminal_list (void) +read_terminal_list (const char *prefix) { - const char *prefix; char *filename; grub_file_t file; char *buf = NULL; - prefix = grub_env_get ("prefix"); if (!prefix) { grub_errno = GRUB_ERR_NONE; From 25f4e25287453d430890dbc87c0af5d8f8c38968 Mon Sep 17 00:00:00 2001 From: EFI Coder Date: Fri, 9 Apr 2010 21:16:17 +0200 Subject: [PATCH 552/738] * normal/menu_text.c (print_message): Clean up the message and show the Fn information when on EFI * term/efi/console.c (grub_console_checkkey): Add F4 support. --- ChangeLog | 6 ++++++ normal/menu_text.c | 11 +++++++++-- term/efi/console.c | 3 +++ 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5f3251fcb..e25639a42 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-04-09 EFI Coder + + * normal/menu_text.c (print_message): Clean up the message and show + the Fn information when on EFI + * term/efi/console.c (grub_console_checkkey): Add F4 support. + 2010-04-09 Vladimir Serbinenko * normal/autofs.c (read_fs_list): New parameter 'prefix'. diff --git a/normal/menu_text.c b/normal/menu_text.c index b39f57512..bb0587502 100644 --- a/normal/menu_text.c +++ b/normal/menu_text.c @@ -176,10 +176,17 @@ print_message (int nested, int edit, struct grub_term_output *term) if (edit) { grub_putcode ('\n', term); +#ifdef GRUB_MACHINE_EFI + grub_print_message_indented (_("Minimum Emacs-like screen editing is \ +supported. TAB lists completions. Press F1 to boot, F2=Ctrl-a, F3=Ctrl-e, \ +F4 for a command-line or ESC to discard edits and return to the GRUB menu."), + STANDARD_MARGIN, STANDARD_MARGIN, term); +#else grub_print_message_indented (_("Minimum Emacs-like screen editing is \ supported. TAB lists completions. Press Ctrl-x to boot, Ctrl-c for a \ -command-line or ESC to return menu."), STANDARD_MARGIN, STANDARD_MARGIN, - term); +command-line or ESC to discard edits and return to the GRUB menu."), + STANDARD_MARGIN, STANDARD_MARGIN, term); +#endif } else { diff --git a/term/efi/console.c b/term/efi/console.c index 264770cae..c33cffdfe 100644 --- a/term/efi/console.c +++ b/term/efi/console.c @@ -194,6 +194,9 @@ grub_console_checkkey (void) case 0x0d: read_key = 5; break; + case 0x0e: + read_key = 3; + break; case 0x17: read_key = '\e'; break; From 5d7e744525cd67fca0c2c9508c9f8a480e1ab9a5 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 9 Apr 2010 21:35:52 +0200 Subject: [PATCH 553/738] * term/efi/console.c (grub_console_checkkey): Macroify key contants. --- ChangeLog | 4 ++++ term/efi/console.c | 14 +++++++------- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index e25639a42..820b595ed 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-04-09 Vladimir Serbinenko + + * term/efi/console.c (grub_console_checkkey): Macroify key contants. + 2010-04-09 EFI Coder * normal/menu_text.c (print_message): Clean up the message and show diff --git a/term/efi/console.c b/term/efi/console.c index c33cffdfe..664861398 100644 --- a/term/efi/console.c +++ b/term/efi/console.c @@ -159,27 +159,27 @@ grub_console_checkkey (void) read_key = key.unicode_char; break; case 0x01: - read_key = 16; + read_key = GRUB_TERM_UP; break; case 0x02: - read_key = 14; + read_key = GRUB_TERM_DOWN; break; case 0x03: - read_key = 6; + read_key = GRUB_TERM_RIGHT; break; case 0x04: - read_key = 2; + read_key = GRUB_TERM_LEFT; break; case 0x05: - read_key = 1; + read_key = GRUB_TERM_HOME; break; case 0x06: - read_key = 5; + read_key = GRUB_TERM_END; break; case 0x07: break; case 0x08: - read_key = 4; + read_key = GRUB_TERM_DC; break; case 0x09: break; From 47822096b5f7433456791d82128f2decb3282271 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 9 Apr 2010 23:04:00 +0200 Subject: [PATCH 554/738] * Makefile.in (RMKFILES): Search in srcdir and not current directory. (MAINTAINER_CLEANFILES): Don't add $(srcdir) to MKFILES. Add few missing files. (maintainer-clean): Remove libgcrypt-grub. --- ChangeLog | 7 +++++++ Makefile.in | 8 ++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 820b595ed..3313a4911 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-04-09 Vladimir Serbinenko + + * Makefile.in (RMKFILES): Search in srcdir and not current directory. + (MAINTAINER_CLEANFILES): Don't add $(srcdir) to MKFILES. Add few + missing files. + (maintainer-clean): Remove libgcrypt-grub. + 2010-04-09 Vladimir Serbinenko * term/efi/console.c (grub_console_checkkey): Macroify key contants. diff --git a/Makefile.in b/Makefile.in index d5eda4be3..57af32cfc 100644 --- a/Makefile.in +++ b/Makefile.in @@ -136,7 +136,7 @@ enable_efiemu = @enable_efiemu@ ### General variables. -RMKFILES = $(wildcard conf/*.rmk) +RMKFILES = $(wildcard $(srcdir)/conf/*.rmk) MKFILES = $(patsubst %.rmk,%.mk,$(RMKFILES)) @@ -155,7 +155,9 @@ DISTCLEANFILES = config.status config.cache config.log config.h \ gensymlist.sh genkernsyms.sh build_env.mk \ docs/grub.info docs/version.texi docs/stamp-vti -MAINTAINER_CLEANFILES = $(srcdir)/configure $(addprefix $(srcdir)/,$(MKFILES)) \ +MAINTAINER_CLEANFILES = $(srcdir)/configure $(srcdir)/aclocal.m4 \ + $(MKFILES) $(srcdir)/config.guess \ + $(srcdir)/config.sub $(srcdir)/install-sh $(srcdir)/missing \ $(srcdir)/DISTLIST $(srcdir)/config.h.in $(srcdir)/stamp-h.in $(INFOS) # The default target. @@ -427,6 +429,8 @@ distclean: mostlyclean maintainer-clean: distclean -test -z "$(MAINTAINER_CLEANFILES)" || rm -f $(MAINTAINER_CLEANFILES) + -rmdir $(srcdir)/lib/libgcrypt-grub/cipher + -rmdir $(srcdir)/lib/libgcrypt-grub info: From b3d0fa12aff7cd1a42201fdbce9b67513aad7e36 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 10 Apr 2010 01:56:51 +0200 Subject: [PATCH 555/738] Fix usb support --- ChangeLog.emu-modload | 7 ++++++- conf/any-emu.rmk | 4 +++- include/grub/libusb.h | 29 +++++++++++++++++++++++++++++ 3 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 include/grub/libusb.h diff --git a/ChangeLog.emu-modload b/ChangeLog.emu-modload index dd0ea6bf0..c675021de 100644 --- a/ChangeLog.emu-modload +++ b/ChangeLog.emu-modload @@ -7,10 +7,15 @@ (TARGET_CFLAGS): Add -DGRUB_TARGET_NO_MODULES=1 if applicable. (CFLAGS): Likewise. * conf/any-emu.rmk: Generate symlist. + (kernel_img_HEADERS): Add util/datetime.h. + (kernel_img_HEADERS) [sdl]: Add sdl.h. + (kernel_img_HEADERS) [libusb]: Add libusb.h. + (kernel_img_SOURCES) [TARGET_NO_MODULES = no && !x86]: Add + kern/$(target_cpu)/cache.S. * configure.ac (grub-emu-modules): New option. * genmk.rb: Handle multiple source lists. - * genmoddep.awk: Output all undefined symbols. * include/grub/sdl.h: New file. + * include/grub/libusb.h: Likewise. * util/grub-emu.c (main): Hanle (host) root. * util/hostdisk.c (grub_util_biosdisk_get_grub_dev): Error with GRUB_ERR_UNKNOWN_DEVICE. diff --git a/conf/any-emu.rmk b/conf/any-emu.rmk index e27a6978b..ddc6b0fd4 100644 --- a/conf/any-emu.rmk +++ b/conf/any-emu.rmk @@ -15,7 +15,7 @@ kernel_img_SOURCES = kern/device.c kern/disk.c kern/dl.c kern/env.c \ \ gnulib/progname.c util/hostfs.c disk/host.c kernel_img_HEADERS += datetime.h -kernel_img_CFLAGS = $(CPPFLAGS) $(CFLAGS) -Wno-undef +kernel_img_CFLAGS = $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) -Wno-undef -I$(srcdir)/gnulib kernel_img_LDFLAGS = $(COMMON_LDFLAGS) TARGET_NO_STRIP = yes @@ -46,6 +46,8 @@ endif grub_emu_LDFLAGS = $(LIBCURSES) ifeq ($(enable_grub_emu_usb), yes) +kernel_img_HEADERS += libusb.h + pkglib_MODULES += libusb.mod libusb_mod_SOURCES = util/usb.c libusb_mod_CFLAGS = diff --git a/include/grub/libusb.h b/include/grub/libusb.h new file mode 100644 index 000000000..26548bccb --- /dev/null +++ b/include/grub/libusb.h @@ -0,0 +1,29 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +void EXPORT_FUNC (usb_bulk_write) (void); +void EXPORT_FUNC (usb_find_busses) (void); +void EXPORT_FUNC (usb_init) (void); +void EXPORT_FUNC (usb_find_devices) (void); +void EXPORT_FUNC (usb_open) (void); +void EXPORT_FUNC (usb_get_busses) (void); +void EXPORT_FUNC (usb_control_msg) (void); +void EXPORT_FUNC (usb_release_interface) (void); +void EXPORT_FUNC (usb_close) (void); +void EXPORT_FUNC (usb_bulk_read) (void); +void EXPORT_FUNC (usb_claim_interface) (void); From be124579b1e6e4b1e28a5caccb2caa0c326e9f22 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 10 Apr 2010 02:08:01 +0200 Subject: [PATCH 556/738] * lib/posix_wrap/locale.h: Add missing file. Reported by: Seth Goldberg. --- ChangeLog | 5 +++++ lib/posix_wrap/locale.h | 0 2 files changed, 5 insertions(+) create mode 100644 lib/posix_wrap/locale.h diff --git a/ChangeLog b/ChangeLog index bc2225d2e..813ea512f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-04-10 Vladimir Serbinenko + + * lib/posix_wrap/locale.h: Add missing file. + Reported by: Seth Goldberg. + 2010-04-10 Vladimir Serbinenko grub-emu module load support. diff --git a/lib/posix_wrap/locale.h b/lib/posix_wrap/locale.h new file mode 100644 index 000000000..e69de29bb From f2fd9d2b2bf4c958c3e5b505dd5450e341d2e50c Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 10 Apr 2010 02:45:26 +0200 Subject: [PATCH 557/738] * include/grub/efi/memory.h (grub_machine_mmap_iterate): Remove EXPORT_FUNC. Reported by: Seth Goldberg. --- ChangeLog | 6 ++++++ include/grub/efi/memory.h | 6 +++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 813ea512f..a8d498033 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-04-10 Vladimir Serbinenko + + * include/grub/efi/memory.h (grub_machine_mmap_iterate): Remove + EXPORT_FUNC. + Reported by: Seth Goldberg. + 2010-04-10 Vladimir Serbinenko * lib/posix_wrap/locale.h: Add missing file. diff --git a/include/grub/efi/memory.h b/include/grub/efi/memory.h index e5ea58d67..285be8359 100644 --- a/include/grub/efi/memory.h +++ b/include/grub/efi/memory.h @@ -34,9 +34,9 @@ by firmware. */ #define GRUB_MACHINE_MEMORY_HOLE 6 - -grub_err_t EXPORT_FUNC(grub_machine_mmap_iterate) -(int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t)); +grub_err_t grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, + grub_uint64_t, + grub_uint32_t)); grub_err_t grub_machine_mmap_register (grub_uint64_t start, grub_uint64_t size, int type, int handle); grub_err_t grub_machine_mmap_unregister (int handle); From daea6abdeb9f58dfa0dfe072101d78b540f0a623 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 10 Apr 2010 03:05:03 +0200 Subject: [PATCH 558/738] * loader/multiboot.c (GRUB_MOD_INIT) [GRUB_USE_MULTIBOOT2]: Rename "module" to "module2". Reported by: Seth Goldberg. --- ChangeLog | 6 ++++++ loader/multiboot.c | 6 ++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index a8d498033..d39c0b65a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-04-10 Vladimir Serbinenko + + * loader/multiboot.c (GRUB_MOD_INIT) [GRUB_USE_MULTIBOOT2]: + Rename "module" to "module2". + Reported by: Seth Goldberg. + 2010-04-10 Vladimir Serbinenko * include/grub/efi/memory.h (grub_machine_mmap_iterate): Remove diff --git a/loader/multiboot.c b/loader/multiboot.c index 1a22cd3a6..ce1e75dda 100644 --- a/loader/multiboot.c +++ b/loader/multiboot.c @@ -335,14 +335,16 @@ GRUB_MOD_INIT(multiboot) #ifdef GRUB_USE_MULTIBOOT2 grub_register_command ("multiboot2", grub_cmd_multiboot, 0, N_("Load a multiboot 2 kernel.")); + cmd_module = + grub_register_command ("module2", grub_cmd_module, + 0, N_("Load a multiboot 2 module.")); #else grub_register_command ("multiboot", grub_cmd_multiboot, 0, N_("Load a multiboot kernel.")); -#endif - cmd_module = grub_register_command ("module", grub_cmd_module, 0, N_("Load a multiboot module.")); +#endif my_mod = mod; } From 6734334a53938ea478da447c8ca9414f72fd6cfa Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 10 Apr 2010 12:46:12 +0200 Subject: [PATCH 559/738] * include/grub/util/misc.h (canonicalise_file_name): Add missing prototype. Reported by: Seth Goldberg. --- ChangeLog | 6 ++++++ include/grub/util/misc.h | 2 ++ 2 files changed, 8 insertions(+) diff --git a/ChangeLog b/ChangeLog index d39c0b65a..b1770bf4b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-04-10 Vladimir Serbinenko + + * include/grub/util/misc.h (canonicalise_file_name): Add missing + prototype. + Reported by: Seth Goldberg. + 2010-04-10 Vladimir Serbinenko * loader/multiboot.c (GRUB_MOD_INIT) [GRUB_USE_MULTIBOOT2]: diff --git a/include/grub/util/misc.h b/include/grub/util/misc.h index 373fff8bb..63d4dac6d 100644 --- a/include/grub/util/misc.h +++ b/include/grub/util/misc.h @@ -88,6 +88,8 @@ grub_int64_t grub_util_get_disk_size (char *name); char *make_system_path_relative_to_its_root (const char *path); +char *canonicalize_file_name (const char *path); + void grub_util_init_nls (void); #endif /* ! GRUB_UTIL_MISC_HEADER */ From 2663fb5f046251e7b7e68d55843e28a63de82b18 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Sat, 10 Apr 2010 18:06:45 +0530 Subject: [PATCH 560/738] flex version check is now done by awk alone --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 0af597bd3..08260eae5 100644 --- a/configure.ac +++ b/configure.ac @@ -192,7 +192,7 @@ AC_PROG_MKDIR_P if test "x$LEX" = x; then AC_MSG_ERROR([flex is not found]) else - version=`$LEX --version 2>/dev/null | $SED -e 's/flex//' -e 's/version//' | $AWK -F "." '{ printf "%d", $1 * 10000 + $2 * 100 + $3;}'` + version=`$LEX --version | $AWK '{ split($NF,x,"."); print x[[1]]*10000+x[[2]]*100+x[[3]]; }'` if test -n "$version" -a "$version" -ge 20535; then : else From 2c7031b135ec6bcdbcdcef86b1159bd3742c8d3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Sutre?= Date: Sat, 10 Apr 2010 17:07:33 +0200 Subject: [PATCH 561/738] Add grub-probe support for NetBSD. * util/getroot.c (find_root_device): Convert block device to character device on NetBSD. * util/probe.c (probe): Require character device on NetBSD. * util/hostdisk.c: NetBSD specific headers. (configure_device_driver): new function to tune device driver parameters (currently only for NetBSD floppy driver). (grub_util_biosdisk_open): NetBSD specific code (get disk size via disklabel ioctl). (open_device): call configure_device_driver on NetBSD. (convert_system_partition_to_system_disk): NetBSD specific code. (device_is_wholedisk): Likewise. (grub_util_biosdisk_get_grub_dev): Likewise. (make_device_name): Fixed a typo in bsd_part_str. * configure.ac: check for opendisk() and getrawpartition() on NetBSD and set LIBUTIL. * Makefile.in: add LIBUTIL to LIBS. --- ChangeLog | 21 +++++++ Makefile.in | 5 +- configure.ac | 15 +++++ util/getroot.c | 11 +++- util/hostdisk.c | 156 +++++++++++++++++++++++++++++++++++++++++++----- 5 files changed, 191 insertions(+), 17 deletions(-) diff --git a/ChangeLog b/ChangeLog index 38171b1f0..f71c37ad0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,24 @@ +2010-04-10 Grégoire Sutre + + Add grub-probe support for NetBSD. + + * util/getroot.c (find_root_device): Convert block device to + character device on NetBSD. + * util/probe.c (probe): Require character device on NetBSD. + * util/hostdisk.c: NetBSD specific headers. + (configure_device_driver): new function to tune device driver + parameters (currently only for NetBSD floppy driver). + (grub_util_biosdisk_open): NetBSD specific code (get disk size + via disklabel ioctl). + (open_device): call configure_device_driver on NetBSD. + (convert_system_partition_to_system_disk): NetBSD specific code. + (device_is_wholedisk): Likewise. + (grub_util_biosdisk_get_grub_dev): Likewise. + (make_device_name): Fixed a typo in bsd_part_str. + * configure.ac: check for opendisk() and getrawpartition() on + NetBSD and set LIBUTIL. + * Makefile.in: add LIBUTIL to LIBS. + 2010-04-10 BVK Chaitanya Documentation fix. diff --git a/Makefile.in b/Makefile.in index 898e6b92a..08c25971f 100644 --- a/Makefile.in +++ b/Makefile.in @@ -45,6 +45,9 @@ pkglibdir = $(libdir)/`echo @PACKAGE_TARNAME@/$(target_cpu)-$(platform) | sed ' LIBINTL = @LIBINTL@ TARGET_NO_MODULES = @TARGET_NO_MODULES@ +# Util library. +LIBUTIL = @LIBUTIL@ + XGETTEXT = @XGETTEXT@ MSGMERGE = @MSGMERGE@ MSGFMT = @MSGFMT@ @@ -76,7 +79,7 @@ MKDIR_P = @MKDIR_P@ mkinstalldirs = $(srcdir)/mkinstalldirs -LIBS = @LIBS@ $(LIBINTL) +LIBS = @LIBS@ $(LIBINTL) $(LIBUTIL) CC = @CC@ CFLAGS = @CFLAGS@ diff --git a/configure.ac b/configure.ac index cabae08e3..afdb7b32d 100644 --- a/configure.ac +++ b/configure.ac @@ -130,6 +130,7 @@ case "$host_os" in gnu*) host_kernel=hurd ;; linux*) host_kernel=linux ;; freebsd* | kfreebsd*-gnu) host_kernel=kfreebsd ;; + netbsd*) host_kernel=netbsd ;; cygwin) host_kernel=windows ;; esac @@ -242,6 +243,20 @@ AC_CHECK_FUNCS(memmove sbrk strdup lstat getuid getgid) AC_CHECK_HEADERS(sys/mkdev.h sys/sysmacros.h malloc.h termios.h sys/types.h) AC_CHECK_HEADERS(unistd.h string.h strings.h sys/stat.h sys/fcntl.h limits.h) +# For opendisk() and getrawpartition() on NetBSD. +# Used in util/deviceiter.c and in util/hostdisk.c. +AC_CHECK_HEADER([util.h], [ + AC_CHECK_LIB([util], [opendisk], [ + LIBUTIL="-lutil" + AC_DEFINE(HAVE_OPENDISK, 1, [Define if opendisk() in -lutil can be used]) + ]) + AC_CHECK_LIB([util], [getrawpartition], [ + LIBUTIL="-lutil" + AC_DEFINE(HAVE_GETRAWPARTITION, 1, [Define if getrawpartition() in -lutil can be used]) + ]) +]) +AC_SUBST([LIBUTIL]) + # # Check for target programs. # diff --git a/util/getroot.c b/util/getroot.c index 82393635c..94eadc5e1 100644 --- a/util/getroot.c +++ b/util/getroot.c @@ -264,10 +264,17 @@ find_root_device (const char *dir, dev_t dev) /* Found! */ char *res; char *cwd; +#if defined(__NetBSD__) + /* Convert this block device to its character (raw) device. */ + const char *template = "%s/r%s"; +#else + /* Keep the device name as it is. */ + const char *template = "%s/%s"; +#endif cwd = xgetcwd (); - res = xmalloc (strlen (cwd) + strlen (ent->d_name) + 2); - sprintf (res, "%s/%s", cwd, ent->d_name); + res = xmalloc (strlen (cwd) + strlen (ent->d_name) + 3); + sprintf (res, template, cwd, ent->d_name); strip_extra_slashes (res); free (cwd); diff --git a/util/hostdisk.c b/util/hostdisk.c index 3ecc95391..8a412da55 100644 --- a/util/hostdisk.c +++ b/util/hostdisk.c @@ -98,6 +98,18 @@ struct hd_geometry # include #endif +#if defined(__NetBSD__) +# include +# include /* struct disklabel */ +# ifdef HAVE_GETRAWPARTITION +# include /* getrawpartition */ +# endif /* HAVE_GETRAWPARTITION */ +# include +# ifndef RAW_FLOPPY_MAJOR +# define RAW_FLOPPY_MAJOR 9 +# endif /* ! RAW_FLOPPY_MAJOR */ +#endif /* defined(__NetBSD__) */ + struct { char *drive; @@ -129,6 +141,31 @@ have_devfs (void) } #endif /* __linux__ */ +#if defined(__NetBSD__) +/* Adjust device driver parameters. This function should be called just + after successfully opening the device. For now, it simply prevents the + floppy driver from retrying operations on failure, as otherwise the + driver takes a while to abort when there is no floppy in the drive. */ +static void +configure_device_driver (int fd) +{ + struct stat st; + + if (fstat (fd, &st) < 0 || ! S_ISCHR (st.st_mode)) + return; + if (major(st.st_rdev) == RAW_FLOPPY_MAJOR) + { + int floppy_opts; + + if (ioctl (fd, FDIOCGETOPTS, &floppy_opts) == -1) + return; + floppy_opts |= FDOPT_NORETRY; + if (ioctl (fd, FDIOCSETOPTS, &floppy_opts) == -1) + return; + } +} +#endif /* defined(__NetBSD__) */ + static int find_grub_drive (const char *name) { @@ -204,16 +241,20 @@ grub_util_biosdisk_open (const char *name, grub_disk_t disk) return GRUB_ERR_NONE; } #elif defined(__linux__) || defined(__CYGWIN__) || defined(__FreeBSD__) || \ - defined(__FreeBSD_kernel__) || defined(__APPLE__) + defined(__FreeBSD_kernel__) || defined(__APPLE__) || defined(__NetBSD__) { +# if defined(__NetBSD__) + struct disklabel label; +# else unsigned long long nr; +# endif int fd; fd = open (map[drive].device, O_RDONLY); if (fd == -1) return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "cannot open `%s' while attempting to get disk size", map[drive].device); -# if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__APPLE__) +# if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__APPLE__) || defined(__NetBSD__) if (fstat (fd, &st) < 0 || ! S_ISCHR (st.st_mode)) # else if (fstat (fd, &st) < 0 || ! S_ISBLK (st.st_mode)) @@ -227,6 +268,9 @@ grub_util_biosdisk_open (const char *name, grub_disk_t disk) if (ioctl (fd, DIOCGMEDIASIZE, &nr)) # elif defined(__APPLE__) if (ioctl (fd, DKIOCGETBLOCKCOUNT, &nr)) +# elif defined(__NetBSD__) + configure_device_driver (fd); + if (ioctl (fd, DIOCGDINFO, &label) == -1) # else if (ioctl (fd, BLKGETSIZE64, &nr)) # endif @@ -237,14 +281,16 @@ grub_util_biosdisk_open (const char *name, grub_disk_t disk) close (fd); -#if defined (__APPLE__) +# if defined (__APPLE__) disk->total_sectors = nr; -#else +# elif defined(__NetBSD__) + disk->total_sectors = label.d_secperunit; +# else disk->total_sectors = nr / 512; if (nr % 512) grub_util_error ("unaligned device size"); -#endif +# endif grub_util_info ("the size of %s is %llu", name, disk->total_sectors); @@ -483,6 +529,10 @@ open_device (const grub_disk_t disk, grub_disk_addr_t sector, int flags) } #endif /* ! __linux__ */ +#if defined(__NetBSD__) + configure_device_driver (fd); +#endif /* defined(__NetBSD__) */ + #if defined(__linux__) && (!defined(__GLIBC__) || \ ((__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 1)))) /* Maybe libc doesn't have large file support. */ @@ -811,7 +861,7 @@ make_device_name (int drive, int dos_part, int bsd_part) dos_part_str = xasprintf (",%d", dos_part + 1); if (bsd_part >= 0) - bsd_part_str = xasprintf (",%c", dos_part + 'a'); + bsd_part_str = xasprintf (",%c", bsd_part + 'a'); ret = xasprintf ("%s%s%s", map[drive].drive, dos_part_str ? : "", @@ -981,6 +1031,27 @@ convert_system_partition_to_system_disk (const char *os_dev) } return path; +#elif defined(__NetBSD__) + /* NetBSD uses "/dev/r[wsc]d[0-9]+[a-z]". */ + char *path = xstrdup (os_dev); + if (strncmp ("/dev/rwd", path, 8) == 0 || + strncmp ("/dev/rsd", path, 8) == 0 || + strncmp ("/dev/rcd", path, 8) == 0) + { + char *q; + q = path + strlen(path) - 1; /* last character */ + if (grub_isalpha(*q) && grub_isdigit(*(q-1))) + { + int rawpart = -1; +# ifdef HAVE_GETRAWPARTITION + rawpart = getrawpartition(); +# endif /* HAVE_GETRAWPARTITION */ + if (rawpart >= 0) + *q = 'a' + rawpart; + } + } + return path; + #else # warning "The function `convert_system_partition_to_system_disk' might not work on your OS correctly." return xstrdup (os_dev); @@ -999,6 +1070,26 @@ device_is_wholedisk (const char *os_dev) } #endif +#if defined(__NetBSD__) +/* Try to determine whether a given device name corresponds to a whole disk. + This function should give in most cases a definite answer, but it may + actually give an approximate one in the following sense: if the return + value is 0 then the device name does not correspond to a whole disk. */ +static int +device_is_wholedisk (const char *os_dev) +{ + int len = strlen (os_dev); + int rawpart = -1; + +# ifdef HAVE_GETRAWPARTITION + rawpart = getrawpartition(); +# endif /* HAVE_GETRAWPARTITION */ + if (rawpart < 0) + return 1; + return (os_dev[len - 1] == ('a' + rawpart)); +} +#endif /* defined(__NetBSD__) */ + static int find_system_device (const char *os_dev) { @@ -1051,14 +1142,14 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) == 0) return make_device_name (drive, -1, -1); -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__APPLE__) +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__APPLE__) || defined(__NetBSD__) if (! S_ISCHR (st.st_mode)) #else if (! S_ISBLK (st.st_mode)) #endif return make_device_name (drive, -1, -1); -#if defined(__linux__) || defined(__CYGWIN__) +#if defined(__linux__) || defined(__CYGWIN__) || defined(__NetBSD__) /* Linux counts partitions uniformly, whether a BSD partition or a DOS partition, so mapping them to GRUB devices is not trivial. Here, get the start sector of a partition by HDIO_GETGEO, and @@ -1066,12 +1157,24 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) Cygwin /dev/sdXN emulation uses Windows partition mapping. It does not count the extended partition and missing primary - partitions. Use same method as on Linux here. */ + partitions. Use same method as on Linux here. + + For NetBSD, proceed as for Linux, except that the start sector is + obtained from the disk label. */ { char *name; grub_disk_t disk; int fd; +# if !defined(__NetBSD__) + const char *disk_info_msg = "geometry"; struct hd_geometry hdg; + typeof (hdg.start) p_offset; +# else /* defined(__NetBSD__) */ + const char *disk_info_msg = "label"; + struct disklabel label; + int index; + u_int32_t p_offset; +# endif /* !defined(__NetBSD__) */ int dos_part = -1; int bsd_part = -1; auto int find_partition (grub_disk_t dsk, @@ -1086,7 +1189,7 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) part_start = grub_partition_get_start (partition); - if (hdg.start == part_start) + if (p_offset == part_start) { if (partition->parent) { @@ -1107,21 +1210,33 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) name = make_device_name (drive, -1, -1); +# if !defined(__NetBSD__) if (MAJOR (st.st_rdev) == FLOPPY_MAJOR) return name; +# else /* defined(__NetBSD__) */ + /* Since os_dev and convert_system_partition_to_system_disk (os_dev) are + * different, we know that os_dev is of the form /dev/r[wsc]d[0-9]+[a-z] + * and in particular it cannot be a floppy device. */ + index = os_dev[strlen(os_dev) - 1] - 'a'; +# endif /* !defined(__NetBSD__) */ fd = open (os_dev, O_RDONLY); if (fd == -1) { - grub_error (GRUB_ERR_BAD_DEVICE, "cannot open `%s' while attempting to get disk geometry", os_dev); + grub_error (GRUB_ERR_BAD_DEVICE, "cannot open `%s' while attempting to get disk %s", os_dev, disk_info_msg); free (name); return 0; } +# if !defined(__NetBSD__) if (ioctl (fd, HDIO_GETGEO, &hdg)) +# else /* defined(__NetBSD__) */ + configure_device_driver (fd); + if (ioctl (fd, DIOCGDINFO, &label) == -1) +# endif /* !defined(__NetBSD__) */ { grub_error (GRUB_ERR_BAD_DEVICE, - "cannot get geometry of `%s'", os_dev); + "cannot get disk %s of `%s'", disk_info_msg, os_dev); close (fd); free (name); return 0; @@ -1129,9 +1244,22 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) close (fd); - grub_util_info ("%s starts from %lu", os_dev, hdg.start); +# if !defined(__NetBSD__) + p_offset = hdg.start; +# else /* defined(__NetBSD__) */ + if (index >= label.d_npartitions) + { + grub_error (GRUB_ERR_BAD_DEVICE, + "no disk label entry for `%s'", os_dev); + free (name); + return 0; + } + p_offset = label.d_partitions[index].p_offset; +# endif /* !defined(__NetBSD__) */ - if (hdg.start == 0 && device_is_wholedisk (os_dev)) + grub_util_info ("%s starts from %lu", os_dev, p_offset); + + if (p_offset == 0 && device_is_wholedisk (os_dev)) return name; grub_util_info ("opening the device %s", name); From e0fc9e78c15db91ebaa0f0c2e95573fb83057234 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Sutre?= Date: Sat, 10 Apr 2010 17:09:24 +0200 Subject: [PATCH 562/738] missing part of patch --- util/grub-probe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/grub-probe.c b/util/grub-probe.c index 948f10dcf..bb41480e2 100644 --- a/util/grub-probe.c +++ b/util/grub-probe.c @@ -119,7 +119,7 @@ probe (const char *path, char *device_name) if (path == NULL) { -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) if (! grub_util_check_char_device (device_name)) grub_util_error ("%s is not a character device", device_name); #else From b7f3ac299db3208400d55bd46bd3dee4bdcad123 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 10 Apr 2010 20:28:25 +0200 Subject: [PATCH 563/738] * util/hostdisk.c (grub_util_biosdisk_get_grub_dev): Remove disk_info_msg (conflicts with gettexting into languages with cases). --- ChangeLog | 5 +++++ util/hostdisk.c | 6 ++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index f71c37ad0..91115c2ce 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-04-10 Vladimir Serbinenko + + * util/hostdisk.c (grub_util_biosdisk_get_grub_dev): Remove + disk_info_msg (conflicts with gettexting into languages with cases). + 2010-04-10 Grégoire Sutre Add grub-probe support for NetBSD. diff --git a/util/hostdisk.c b/util/hostdisk.c index 8a412da55..79652625d 100644 --- a/util/hostdisk.c +++ b/util/hostdisk.c @@ -1166,11 +1166,9 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) grub_disk_t disk; int fd; # if !defined(__NetBSD__) - const char *disk_info_msg = "geometry"; struct hd_geometry hdg; typeof (hdg.start) p_offset; # else /* defined(__NetBSD__) */ - const char *disk_info_msg = "label"; struct disklabel label; int index; u_int32_t p_offset; @@ -1223,7 +1221,7 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) fd = open (os_dev, O_RDONLY); if (fd == -1) { - grub_error (GRUB_ERR_BAD_DEVICE, "cannot open `%s' while attempting to get disk %s", os_dev, disk_info_msg); + grub_error (GRUB_ERR_BAD_DEVICE, "cannot open `%s' while attempting to get disk geometry", os_dev); free (name); return 0; } @@ -1236,7 +1234,7 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) # endif /* !defined(__NetBSD__) */ { grub_error (GRUB_ERR_BAD_DEVICE, - "cannot get disk %s of `%s'", disk_info_msg, os_dev); + "cannot get disk geometry of `%s'", os_dev); close (fd); free (name); return 0; From 5d04b11e0ed03f89292b34edf9e44fa6403ce405 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 11 Apr 2010 01:14:31 +0200 Subject: [PATCH 564/738] Unify libgcc processing. * Makefile.in (kernel_img_LDFLAGS): New variable. * conf/common.rmk (kernel_img_HEADERS): Add libgcc.h. * conf/i386-coreboot.rmk (kernel_img_LDFLAGS): Append instead of overwriting. * conf/i386-ieee1275.rmk (kernel_img_LDFLAGS): Likewise. * conf/i386-pc.rmk (kernel_img_LDFLAGS): Likewise. * conf/i386-qemu.rmk (kernel_img_LDFLAGS): Likewise. * conf/x86-efi.rmk (kernel_img_LDFLAGS): Likewise. * conf/mips-qemu-mips.rmk (kernel_img_LDFLAGS): Append instead of overwriting. Remove -lgcc and -static-libgcc * conf/mips-yeeloong.rmk (kernel_img_LDFLAGS): Likewise. * conf/mips.rmk (kernel_img_HEADERS): Remove cpu/libgcc.h * conf/powerpc-ieee1275.rmk (kernel_img_HEADERS): Remove cpu/libgcc.h (kernel_img_LDFLAGS): Append instead of overwriting. Remove -lgcc and -static-libgcc * conf/sparc64-ieee1275.rmk: Likewise. * include/grub/powerpc/libgcc.h: Move to ... * include/grub/libgcc.h: .. this. * include/grub/libgcc.h: Don't export most of the function on x86. (__bswapsi2): New export. (__bswapdi2): Likewise. * include/grub/mips/libgcc.h: Removed. * include/grub/sparc64/libgcc.h: Likewise. --- ChangeLog | 28 +++++++++++++++++++++ Makefile.in | 1 + conf/common.rmk | 2 +- conf/i386-coreboot.rmk | 2 +- conf/i386-ieee1275.rmk | 2 +- conf/i386-pc.rmk | 2 +- conf/i386-qemu.rmk | 2 +- conf/mips-qemu-mips.rmk | 3 +-- conf/mips-yeeloong.rmk | 3 +-- conf/mips.rmk | 2 +- conf/powerpc-ieee1275.rmk | 5 ++-- conf/sparc64-ieee1275.rmk | 4 +-- conf/x86-efi.rmk | 2 +- include/grub/{powerpc => }/libgcc.h | 26 ++++++++++++++------ include/grub/mips/libgcc.h | 38 ----------------------------- include/grub/sparc64/libgcc.h | 29 ---------------------- 16 files changed, 60 insertions(+), 91 deletions(-) rename include/grub/{powerpc => }/libgcc.h (86%) delete mode 100644 include/grub/mips/libgcc.h delete mode 100644 include/grub/sparc64/libgcc.h diff --git a/ChangeLog b/ChangeLog index 91115c2ce..ec4766d44 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,31 @@ +2010-04-11 Vladimir Serbinenko + + Unify libgcc processing. + + * Makefile.in (kernel_img_LDFLAGS): New variable. + * conf/common.rmk (kernel_img_HEADERS): Add libgcc.h. + * conf/i386-coreboot.rmk (kernel_img_LDFLAGS): Append instead of + overwriting. + * conf/i386-ieee1275.rmk (kernel_img_LDFLAGS): Likewise. + * conf/i386-pc.rmk (kernel_img_LDFLAGS): Likewise. + * conf/i386-qemu.rmk (kernel_img_LDFLAGS): Likewise. + * conf/x86-efi.rmk (kernel_img_LDFLAGS): Likewise. + * conf/mips-qemu-mips.rmk (kernel_img_LDFLAGS): Append instead of + overwriting. Remove -lgcc and -static-libgcc + * conf/mips-yeeloong.rmk (kernel_img_LDFLAGS): Likewise. + * conf/mips.rmk (kernel_img_HEADERS): Remove cpu/libgcc.h + * conf/powerpc-ieee1275.rmk (kernel_img_HEADERS): Remove cpu/libgcc.h + (kernel_img_LDFLAGS): Append instead of overwriting. + Remove -lgcc and -static-libgcc + * conf/sparc64-ieee1275.rmk: Likewise. + * include/grub/powerpc/libgcc.h: Move to ... + * include/grub/libgcc.h: .. this. + * include/grub/libgcc.h: Don't export most of the function on x86. + (__bswapsi2): New export. + (__bswapdi2): Likewise. + * include/grub/mips/libgcc.h: Removed. + * include/grub/sparc64/libgcc.h: Likewise. + 2010-04-10 Vladimir Serbinenko * util/hostdisk.c (grub_util_biosdisk_get_grub_dev): Remove diff --git a/Makefile.in b/Makefile.in index 08c25971f..e253af6c9 100644 --- a/Makefile.in +++ b/Makefile.in @@ -103,6 +103,7 @@ TARGET_IMG_LDSCRIPT = @TARGET_IMG_LDSCRIPT@ TARGET_IMG_LDFLAGS = -nostdlib @TARGET_IMG_LDFLAGS@ TARGET_IMG_CFLAGS = @TARGET_IMG_CFLAGS@ TARGET_OBJ2ELF = @TARGET_OBJ2ELF@ +kernel_img_LDFLAGS = -static-libgcc -lgcc EXEEXT = @EXEEXT@ OBJCOPY = @OBJCOPY@ STRIP = @STRIP@ diff --git a/conf/common.rmk b/conf/common.rmk index 952be558c..8df232a0b 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -116,7 +116,7 @@ DEFSYMFILES += kernel_syms.lst kernel_img_HEADERS += boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \ partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \ - list.h handler.h command.h i18n.h env_private.h + list.h handler.h command.h i18n.h env_private.h libgcc.h ifneq ($(platform), emu) kernel_img_HEADERS += machine/memory.h machine/loader.h machine/kernel.h diff --git a/conf/i386-coreboot.rmk b/conf/i386-coreboot.rmk index 3cef9313f..69b8e9a48 100644 --- a/conf/i386-coreboot.rmk +++ b/conf/i386-coreboot.rmk @@ -26,7 +26,7 @@ kernel_img_SOURCES = kern/i386/coreboot/startup.S \ symlist.c kernel_img_CFLAGS = $(COMMON_CFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) -kernel_img_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,$(GRUB_KERNEL_MACHINE_LINK_ADDR),-Bstatic +kernel_img_LDFLAGS += $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,$(GRUB_KERNEL_MACHINE_LINK_ADDR),-Bstatic sbin_SCRIPTS += grub-install grub_install_SOURCES = util/grub-install.in diff --git a/conf/i386-ieee1275.rmk b/conf/i386-ieee1275.rmk index d4a459b3e..05ba38a65 100644 --- a/conf/i386-ieee1275.rmk +++ b/conf/i386-ieee1275.rmk @@ -27,7 +27,7 @@ kernel_img_SOURCES = kern/i386/ieee1275/startup.S \ kernel_img_HEADERS += ieee1275/ieee1275.h kernel_img_CFLAGS = $(COMMON_CFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) -kernel_img_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,0x10000,-Bstatic +kernel_img_LDFLAGS += $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,0x10000,-Bstatic # Scripts. sbin_SCRIPTS = grub-install diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk index c52f6fa45..eace1e2da 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -58,7 +58,7 @@ kernel_img_HEADERS += machine/biosdisk.h machine/vga.h machine/vbe.h \ machine/pxe.h i386/pit.h kernel_img_CFLAGS = $(COMMON_CFLAGS) $(TARGET_IMG_CFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) -kernel_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_KERNEL_MACHINE_LINK_ADDR) $(COMMON_CFLAGS) +kernel_img_LDFLAGS += $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_KERNEL_MACHINE_LINK_ADDR) $(COMMON_CFLAGS) kernel_img_FORMAT = binary # Utilities. diff --git a/conf/i386-qemu.rmk b/conf/i386-qemu.rmk index 97273e1ce..664bef12a 100644 --- a/conf/i386-qemu.rmk +++ b/conf/i386-qemu.rmk @@ -39,7 +39,7 @@ kernel_img_SOURCES = kern/i386/qemu/startup.S \ symlist.c kernel_img_CFLAGS = $(COMMON_CFLAGS) -DGRUB_BOOT_MACHINE_LINK_ADDR=$(GRUB_BOOT_MACHINE_LINK_ADDR) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR) -kernel_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_KERNEL_MACHINE_LINK_ADDR) +kernel_img_LDFLAGS += $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_KERNEL_MACHINE_LINK_ADDR) kernel_img_FORMAT = binary sbin_SCRIPTS += grub-install diff --git a/conf/mips-qemu-mips.rmk b/conf/mips-qemu-mips.rmk index e06370122..af5b26bec 100644 --- a/conf/mips-qemu-mips.rmk +++ b/conf/mips-qemu-mips.rmk @@ -18,6 +18,5 @@ kernel_img_SOURCES = kern/$(target_cpu)/startup.S \ symlist.c kern/$(target_cpu)/cache.S kernel_img_CFLAGS = $(COMMON_CFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) -kernel_img_LDFLAGS = $(COMMON_LDFLAGS) -static-libgcc -lgcc \ - -Wl,-N,-S,-Ttext,$(LINK_BASE),-Bstatic +kernel_img_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,$(LINK_BASE),-Bstatic kernel_img_FORMAT = binary diff --git a/conf/mips-yeeloong.rmk b/conf/mips-yeeloong.rmk index 35cd01b4b..6a96ddfaf 100644 --- a/conf/mips-yeeloong.rmk +++ b/conf/mips-yeeloong.rmk @@ -29,8 +29,7 @@ kernel_img_SOURCES = kern/$(target_cpu)/startup.S \ symlist.c kernel_img_CFLAGS = $(COMMON_CFLAGS) -DUSE_ASCII_FAILBACK kernel_img_ASFLAGS = $(COMMON_ASFLAGS) -kernel_img_LDFLAGS = $(COMMON_LDFLAGS) -static-libgcc -lgcc \ - -Wl,-N,-S,-Ttext,$(LINK_BASE),-Bstatic +kernel_img_LDFLAGS += $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,$(LINK_BASE),-Bstatic kernel_img_FORMAT = binary # For ata.mod. diff --git a/conf/mips.rmk b/conf/mips.rmk index c9d94eb74..4603c219e 100644 --- a/conf/mips.rmk +++ b/conf/mips.rmk @@ -4,7 +4,7 @@ COMMON_CFLAGS += -mexplicit-relocs -mflush-func=grub_cpu_flush_cache # Images. -kernel_img_HEADERS += cpu/libgcc.h cpu/cache.h +kernel_img_HEADERS += cpu/cache.h # Scripts. sbin_SCRIPTS = diff --git a/conf/powerpc-ieee1275.rmk b/conf/powerpc-ieee1275.rmk index 86f6ddcb3..d5968ac8e 100644 --- a/conf/powerpc-ieee1275.rmk +++ b/conf/powerpc-ieee1275.rmk @@ -3,7 +3,7 @@ # Images. -kernel_img_HEADERS += cpu/libgcc.h ieee1275/ieee1275.h +kernel_img_HEADERS += ieee1275/ieee1275.h # Programs pkglib_PROGRAMS = kernel.img @@ -23,8 +23,7 @@ kernel_img_SOURCES = kern/powerpc/ieee1275/startup.S kern/ieee1275/cmain.c \ symlist.c kern/$(target_cpu)/cache.S kernel_img_CFLAGS = $(COMMON_CFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) -kernel_img_LDFLAGS = $(COMMON_LDFLAGS) -static-libgcc -lgcc \ - -Wl,-N,-S,-Ttext,0x200000,-Bstatic +kernel_img_LDFLAGS += $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,0x200000,-Bstatic # Scripts. sbin_SCRIPTS = grub-install diff --git a/conf/sparc64-ieee1275.rmk b/conf/sparc64-ieee1275.rmk index a387b8a96..72f947f6a 100644 --- a/conf/sparc64-ieee1275.rmk +++ b/conf/sparc64-ieee1275.rmk @@ -19,7 +19,7 @@ diskboot_img_ASFLAGS = $(COMMON_ASFLAGS) diskboot_img_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-Ttext,0x4200 diskboot_img_FORMAT = binary -kernel_img_HEADERS += cpu/libgcc.h ieee1275/ieee1275.h cpu/ieee1275/ieee1275.h +kernel_img_HEADERS += ieee1275/ieee1275.h cpu/ieee1275/ieee1275.h kernel_img_SOURCES = kern/sparc64/ieee1275/crt0.S kern/ieee1275/cmain.c \ kern/ieee1275/ieee1275.c kern/main.c kern/device.c \ kern/disk.c kern/dl.c kern/err.c kern/file.c kern/fs.c \ @@ -36,7 +36,7 @@ kernel_img_SOURCES = kern/sparc64/ieee1275/crt0.S kern/ieee1275/cmain.c \ symlist.c kern/$(target_cpu)/cache.S kernel_img_CFLAGS = $(COMMON_CFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) -kernel_img_LDFLAGS = -nostdlib -Wl,-N,-Ttext,0x4400,-Bstatic,-melf64_sparc -static-libgcc -lgcc +kernel_img_LDFLAGS += -nostdlib -Wl,-N,-Ttext,0x4400,-Bstatic,-melf64_sparc kernel_img_FORMAT = binary # Utilities. diff --git a/conf/x86-efi.rmk b/conf/x86-efi.rmk index 5cb472168..46957d933 100644 --- a/conf/x86-efi.rmk +++ b/conf/x86-efi.rmk @@ -40,7 +40,7 @@ endif kernel_img_HEADERS += efi/efi.h efi/time.h efi/disk.h i386/pit.h kernel_img_CFLAGS = $(COMMON_CFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) -kernel_img_LDFLAGS = $(COMMON_LDFLAGS) +kernel_img_LDFLAGS += $(COMMON_LDFLAGS) # For acpi.mod. acpi_mod_SOURCES = commands/acpi.c commands/efi/acpi.c diff --git a/include/grub/powerpc/libgcc.h b/include/grub/libgcc.h similarity index 86% rename from include/grub/powerpc/libgcc.h rename to include/grub/libgcc.h index 6be122308..d0adae8c1 100644 --- a/include/grub/powerpc/libgcc.h +++ b/include/grub/libgcc.h @@ -18,21 +18,31 @@ #include -#ifdef HAVE___ASHLDI3 +/* On x86 these functions aren't really needed. Save some space. */ +#if !defined (__i386__) && !defined (__x86_64__) +# ifdef HAVE___ASHLDI3 void EXPORT_FUNC (__ashldi3) (void); -#endif -#ifdef HAVE___ASHRDI3 +# endif +# ifdef HAVE___ASHRDI3 void EXPORT_FUNC (__ashrdi3) (void); -#endif -#ifdef HAVE___LSHRDI3 +# endif +# ifdef HAVE___LSHRDI3 void EXPORT_FUNC (__lshrdi3) (void); +# endif +# ifdef HAVE___UCMPDI2 +void EXPORT_FUNC (__ucmpdi2) (void); +# endif +# ifdef HAVE___BSWAPSI2 +void EXPORT_FUNC (__bswapsi2) (void); +# endif +# ifdef HAVE___BSWAPDI2 +void EXPORT_FUNC (__bswapdi2) (void); +# endif #endif + #ifdef HAVE___TRAMPOLINE_SETUP void EXPORT_FUNC (__trampoline_setup) (void); #endif -#ifdef HAVE___UCMPDI2 -void EXPORT_FUNC (__ucmpdi2) (void); -#endif #ifdef HAVE__RESTGPR_14_X void EXPORT_FUNC (_restgpr_14_x) (void); diff --git a/include/grub/mips/libgcc.h b/include/grub/mips/libgcc.h deleted file mode 100644 index f06ea1c1c..000000000 --- a/include/grub/mips/libgcc.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2004,2007,2009 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include - -#ifdef HAVE___ASHLDI3 -void EXPORT_FUNC (__ashldi3) (void); -#endif -#ifdef HAVE___ASHRDI3 -void EXPORT_FUNC (__ashrdi3) (void); -#endif -#ifdef HAVE___LSHRDI3 -void EXPORT_FUNC (__lshrdi3) (void); -#endif -#ifdef HAVE___UCMPDI2 -void EXPORT_FUNC (__ucmpdi2) (void); -#endif -#ifdef HAVE___BSWAPSI2 -void EXPORT_FUNC (__bswapsi2) (void); -#endif -#ifdef HAVE___BSWAPDI2 -void EXPORT_FUNC (__bswapdi2) (void); -#endif diff --git a/include/grub/sparc64/libgcc.h b/include/grub/sparc64/libgcc.h deleted file mode 100644 index e73abe29c..000000000 --- a/include/grub/sparc64/libgcc.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2004,2007,2009 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include - -#ifdef HAVE___BSWAPSI2 -typedef int SItype __attribute__ ((mode (SI))); -SItype EXPORT_FUNC (__bswapsi2) (SItype); -#endif - -#ifdef HAVE___BSWAPDI2 -typedef int DItype __attribute__ ((mode (DI))); -DItype EXPORT_FUNC (__bswapdi2) (DItype); -#endif From 01fcf061eadf54a618452be258d4896431c8bba7 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 11 Apr 2010 16:14:51 +0200 Subject: [PATCH 565/738] * configure.ac: Respect grub_cv_asm_uscore when defining dummy symbols. --- ChangeLog | 4 ++++ configure.ac | 10 ++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index ec4766d44..61f1bc20e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-04-11 Vladimir Serbinenko + + * configure.ac: Respect grub_cv_asm_uscore when defining dummy symbols. + 2010-04-11 Vladimir Serbinenko Unify libgcc processing. diff --git a/configure.ac b/configure.ac index afdb7b32d..66e06bc86 100644 --- a/configure.ac +++ b/configure.ac @@ -479,12 +479,19 @@ CC="$TARGET_CC" if test "x$TARGET_APPLE_CC" = x1 ; then CFLAGS="$TARGET_CFLAGS -nostdlib -Wno-error" else -CFLAGS="$TARGET_CFLAGS -nostdlib -Wl,--defsym,___main=0x8100 -Wl,--defsym,abort=main -Wno-error" +CFLAGS="$TARGET_CFLAGS -nostdlib -Wl,--defsym,___main=0x8100 -Wno-error" fi CPPFLAGS="$TARGET_CPPFLAGS" LDFLAGS="$TARGET_LDFLAGS" LIBS=-lgcc +grub_ASM_USCORE +if test x$grub_cv_asm_uscore = xyes; then +CFLAGS="$CFLAGS -Wl,--defsym,_abort=_main" +else +CFLAGS="$CFLAGS -Wl,--defsym,abort=main" +fi + # Check for libgcc symbols AC_CHECK_FUNCS(__bswapsi2 __bswapdi2 __ashldi3 __ashrdi3 __lshrdi3 __trampoline_setup __ucmpdi2 _restgpr_14_x) @@ -501,7 +508,6 @@ if test "x$TARGET_APPLE_CC" != x1 ; then grub_PROG_OBJCOPY_ABSOLUTE fi grub_PROG_LD_BUILD_ID_NONE -grub_ASM_USCORE if test "x$target_cpu" = xi386; then if test ! -z "$TARGET_IMG_LDSCRIPT"; then # Check symbols provided by linker script. From 4b0cd8f81387b5953e8d9f209d5f5d94e6baef2b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 11 Apr 2010 21:24:21 +0200 Subject: [PATCH 566/738] Fix cygwin compilation. * configure.ac: Define NEED_REGISTER_FRAME_INFO. * include/grub/misc.h (__register_frame_info) [NEED_REGISTER_FRAME_INFO && !UTIL]: New export. (__deregister_frame_info) [NEED_REGISTER_FRAME_INFO && !UTIL]: Likewise. * kern/misc.c (__register_frame_info) [NEED_REGISTER_FRAME_INFO && !UTIL]: New empty function. (__deregister_frame_info) [NEED_REGISTER_FRAME_INFO && !UTIL]: Likewise. --- ChangeLog | 12 ++++++++++++ configure.ac | 6 +++++- include/grub/misc.h | 5 +++++ kern/misc.c | 9 +++++++++ 4 files changed, 31 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 61f1bc20e..d766bcd50 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2010-04-11 Vladimir Serbinenko + + Fix cygwin compilation. + + * configure.ac: Define NEED_REGISTER_FRAME_INFO. + * include/grub/misc.h (__register_frame_info) + [NEED_REGISTER_FRAME_INFO && !UTIL]: New export. + (__deregister_frame_info) [NEED_REGISTER_FRAME_INFO && !UTIL]: Likewise. + * kern/misc.c (__register_frame_info) + [NEED_REGISTER_FRAME_INFO && !UTIL]: New empty function. + (__deregister_frame_info) [NEED_REGISTER_FRAME_INFO && !UTIL]: Likewise. + 2010-04-11 Vladimir Serbinenko * configure.ac: Respect grub_cv_asm_uscore when defining dummy symbols. diff --git a/configure.ac b/configure.ac index 66e06bc86..3116d6584 100644 --- a/configure.ac +++ b/configure.ac @@ -376,7 +376,11 @@ AC_SUBST(TARGET_IMG_CFLAGS) # For platforms where ELF is not the default link format. AC_MSG_CHECKING([for command to convert module to ELF format]) case "${host_os}" in - cygwin) TARGET_OBJ2ELF='grub-pe2elf' ;; + cygwin) TARGET_OBJ2ELF='grub-pe2elf'; +# FIXME: put proper test here + AC_DEFINE([NEED_REGISTER_FRAME_INFO], 1, + [Define to 1 if GCC generates calls to __register_frame_info()]) + ;; *) ;; esac AC_SUBST(TARGET_OBJ2ELF) diff --git a/include/grub/misc.h b/include/grub/misc.h index 61174c38d..9bfc6974e 100644 --- a/include/grub/misc.h +++ b/include/grub/misc.h @@ -265,6 +265,11 @@ grub_uint64_t EXPORT_FUNC(grub_divmod64) (grub_uint64_t n, void EXPORT_FUNC(__enable_execute_stack) (void *addr); #endif +#if defined (NEED_REGISTER_FRAME_INFO) && !defined(GRUB_UTIL) +void EXPORT_FUNC (__register_frame_info) (void); +void EXPORT_FUNC (__deregister_frame_info) (void); +#endif + /* Inline functions. */ static inline unsigned int diff --git a/kern/misc.c b/kern/misc.c index 9d8fc70da..ccc01d43f 100644 --- a/kern/misc.c +++ b/kern/misc.c @@ -1066,3 +1066,12 @@ void __enable_execute_stack (void *addr __attribute__ ((unused))) } #endif +#if defined (NEED_REGISTER_FRAME_INFO) && !defined(GRUB_UTIL) +void __register_frame_info (void) +{ +} + +void __deregister_frame_info (void) +{ +} +#endif From ce44826e79a92aaf21e19580d0580d29121d2260 Mon Sep 17 00:00:00 2001 From: Carles Pina i Estany Date: Tue, 13 Apr 2010 13:57:56 +0100 Subject: [PATCH 567/738] Enclose all translated strings in grub.cfg in single quotes, and escape them appropriately (Ubuntu bug #552921). * util/grub-mkconfig_lib.in (gettext_quoted): New function. * util/grub.d/10_hurd.in: Use it. * util/grub.d/10_kfreebsd.in (kfreebsd_entry): Likewise. * util/grub.d/10_linux.in (linux_entry): Likewise. Also-By: Colin Watson --- ChangeLog | 11 +++++++++++ util/grub-mkconfig_lib.in | 4 ++++ util/grub.d/10_hurd.in | 8 ++++---- util/grub.d/10_kfreebsd.in | 6 +++--- util/grub.d/10_linux.in | 10 +++++----- 5 files changed, 27 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index d766bcd50..4be24c1b2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2010-04-13 Carles Pina i Estany +2010-04-13 Colin Watson + + Enclose all translated strings in grub.cfg in single quotes, and + escape them appropriately (Ubuntu bug #552921). + + * util/grub-mkconfig_lib.in (gettext_quoted): New function. + * util/grub.d/10_hurd.in: Use it. + * util/grub.d/10_kfreebsd.in (kfreebsd_entry): Likewise. + * util/grub.d/10_linux.in (linux_entry): Likewise. + 2010-04-11 Vladimir Serbinenko Fix cygwin compilation. diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in index bcd6baffb..a4151348c 100644 --- a/util/grub-mkconfig_lib.in +++ b/util/grub-mkconfig_lib.in @@ -188,3 +188,7 @@ version_find_latest () done echo "$a" } + +gettext_quoted () { + gettext "$@" | sed "s/'/'\\\\''/g" +} diff --git a/util/grub.d/10_hurd.in b/util/grub.d/10_hurd.in index 5dbb11f22..8e16e7d9f 100644 --- a/util/grub.d/10_hurd.in +++ b/util/grub.d/10_hurd.in @@ -76,13 +76,13 @@ menuentry "${OS}" ${CLASS} { EOF prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/" cat << EOF - echo $(gettext "Loading GNU Mach ...") + echo '$(gettext_quoted "Loading GNU Mach ...")' multiboot ${kernel} root=device:${GRUB_DEVICE#/dev/} EOF save_default_entry | sed -e "s/^/\t/" prepare_grub_to_access_device ${GRUB_DEVICE} | sed -e "s/^/\t/" cat << EOF - echo $(gettext "Loading the Hurd ...") + echo '$(gettext_quoted "Loading the Hurd ...")' module /hurd/${hurd_fs}.static ${hurd_fs} --readonly \\ --multiboot-command-line='\${kernel-command-line}' \\ --host-priv-port='\${host-port}' \\ @@ -98,13 +98,13 @@ menuentry "${OS} (recovery mode)" { EOF prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/" cat << EOF - echo $(gettext "Loading GNU Mach ...") + echo '$(gettext_quoted "Loading GNU Mach ...")' multiboot ${kernel} root=device:${GRUB_DEVICE#/dev/} -s EOF save_default_entry | sed -e "s/^/\t/" prepare_grub_to_access_device ${GRUB_DEVICE} | sed -e "s/^/\t/" cat << EOF - echo $(gettext "Loading the Hurd ...") + echo '$(gettext_quoted "Loading the Hurd ...")' module /hurd/${hurd_fs}.static ${hurd_fs} \\ --multiboot-command-line='\${kernel-command-line}' \\ --host-priv-port='\${host-port}' \\ diff --git a/util/grub.d/10_kfreebsd.in b/util/grub.d/10_kfreebsd.in index 43651c82b..5ab546282 100644 --- a/util/grub.d/10_kfreebsd.in +++ b/util/grub.d/10_kfreebsd.in @@ -44,15 +44,15 @@ kfreebsd_entry () version="$2" recovery="$3" # not used yet args="$4" # not used yet - title="$(gettext "%s, with kFreeBSD %s")" - printf "menuentry \"${title}\" ${CLASS} {\n" "${os}" "${version}" + title="$(gettext_quoted "%s, with kFreeBSD %s")" + printf "menuentry '${title}' ${CLASS} {\n" "${os}" "${version}" save_default_entry | sed -e "s/^/\t/" if [ -z "${prepare_boot_cache}" ]; then prepare_boot_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/")" fi printf '%s\n' "${prepare_boot_cache}" cat << EOF - echo $(printf "$(gettext "Loading kernel of FreeBSD %s ...")" ${version}) + echo '$(printf "$(gettext_quoted "Loading kernel of FreeBSD %s ...")" ${version})' kfreebsd ${rel_dirname}/${basename} EOF diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in index 8dc0df5d9..e691cae86 100644 --- a/util/grub.d/10_linux.in +++ b/util/grub.d/10_linux.in @@ -56,11 +56,11 @@ linux_entry () recovery="$3" args="$4" if ${recovery} ; then - title="$(gettext "%s, with Linux %s (recovery mode)")" + title="$(gettext_quoted "%s, with Linux %s (recovery mode)")" else - title="$(gettext "%s, with Linux %s")" + title="$(gettext_quoted "%s, with Linux %s")" fi - printf "menuentry \"${title}\" ${CLASS} {\n" "${os}" "${version}" + printf "menuentry '${title}' ${CLASS} {\n" "${os}" "${version}" save_default_entry | sed -e "s/^/\t/" # Use ELILO's generic "efifb" when it's known to be available. @@ -83,12 +83,12 @@ EOF fi printf '%s\n' "${prepare_boot_cache}" cat << EOF - echo $(printf "$(gettext "Loading Linux %s ...")" ${version}) + echo '$(printf "$(gettext_quoted "Loading Linux %s ...")" ${version})' linux ${rel_dirname}/${basename} root=${linux_root_device_thisversion} ro ${args} EOF if test -n "${initrd}" ; then cat << EOF - echo $(gettext "Loading initial ramdisk ...") + echo '$(gettext_quoted "Loading initial ramdisk ...")' initrd ${rel_dirname}/${initrd} EOF fi From 4e6da157dd218f4d4c262e875d0b7fd55b8048ae Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Tue, 13 Apr 2010 20:58:12 +0530 Subject: [PATCH 568/738] fix and testcase for \$ in grub script dquote strings --- conf/tests.rmk | 5 ++++- script/yylex.l | 11 ++++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/conf/tests.rmk b/conf/tests.rmk index 11e5f2a1a..d48bc3dd9 100644 --- a/conf/tests.rmk +++ b/conf/tests.rmk @@ -65,6 +65,9 @@ grub_script_blanklines_SOURCES = tests/grub_script_blanklines.in check_SCRIPTS += grub_script_final_semicolon grub_script_final_semicolon_SOURCES = tests/grub_script_final_semicolon.in +check_SCRIPTS += grub_script_dollar +grub_script_dollar_SOURCES = tests/grub_script_dollar.in + # List of tests to execute on "make check" # SCRIPTED_TESTS = example_scripted_test # SCRIPTED_TESTS += example_grub_script_test @@ -79,7 +82,7 @@ SCRIPTED_TESTS += grub_script_while1 SCRIPTED_TESTS += grub_script_if SCRIPTED_TESTS += grub_script_blanklines SCRIPTED_TESTS += grub_script_final_semicolon - +SCRIPTED_TESTS += grub_script_dollar # dependencies between tests and testing-tools $(SCRIPTED_TESTS): grub-shell grub-shell-tester diff --git a/script/yylex.l b/script/yylex.l index 0cf33c951..29aa5c2e3 100644 --- a/script/yylex.l +++ b/script/yylex.l @@ -211,7 +211,7 @@ WORD ({CHAR}|{DQSTR}|{SQSTR}|{ESC}|{VARIABLE})+ ARG (GRUB_SCRIPT_ARG_TYPE_TEXT); } \\ | - [^\"\'$\\]+ { COPY (yytext, yyleng); } + [^\"\'\$\\]+ { COPY (yytext, yyleng); } <> { yy_pop_state (yyscanner); yypop_buffer_state (yyscanner); @@ -254,6 +254,11 @@ WORD ({CHAR}|{DQSTR}|{SQSTR}|{ESC}|{VARIABLE})+ } { + \\\$ { COPY ("$", 1); } + \\\\ { COPY ("\\", 1); } + \\\" { COPY ("\"", 1); } + \\\n { /* ignore */ } + [^\"\$\\\n]+ { COPY (yytext, yyleng); } \" { yy_pop_state (yyscanner); ARG (GRUB_SCRIPT_ARG_TYPE_DQSTR); @@ -262,10 +267,6 @@ WORD ({CHAR}|{DQSTR}|{SQSTR}|{ESC}|{VARIABLE})+ yy_push_state (VAR, yyscanner); ARG (GRUB_SCRIPT_ARG_TYPE_DQSTR); } - \\\\ { COPY ("\\", 1); } - \\\" { COPY ("\"", 1); } - \\\n { /* ignore */ } - [^\"$\\\n]+ { COPY (yytext, yyleng); } (.|\n) { COPY (yytext, yyleng); } } From ae45b7bad4a382479344d7d06d97a9132f75ab9c Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Tue, 13 Apr 2010 21:01:56 +0530 Subject: [PATCH 569/738] add missing testcase --- tests/grub_script_dollar.in | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 tests/grub_script_dollar.in diff --git a/tests/grub_script_dollar.in b/tests/grub_script_dollar.in new file mode 100644 index 000000000..3819b8bc9 --- /dev/null +++ b/tests/grub_script_dollar.in @@ -0,0 +1,5 @@ +#! /bin/sh -e + +@builddir@/grub-script-check << EOF +echo "\\\$" +EOF From 851395d8659fc58532797e6b45646e58845d50cf Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Wed, 14 Apr 2010 13:38:05 +0530 Subject: [PATCH 570/738] fix uninitialized warning --- loader/i386/bsdXX.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/loader/i386/bsdXX.c b/loader/i386/bsdXX.c index b4d574821..cd5ba85dc 100644 --- a/loader/i386/bsdXX.c +++ b/loader/i386/bsdXX.c @@ -80,7 +80,7 @@ SUFFIX (grub_freebsd_load_elfmodule_obj) (grub_file_t file, int argc, { Elf_Ehdr e; Elf_Shdr *s; - char *shdr; + char *shdr = 0; grub_addr_t curload, module; grub_err_t err; @@ -148,7 +148,7 @@ SUFFIX (grub_freebsd_load_elfmodule) (grub_file_t file, int argc, char *argv[], { Elf_Ehdr e; Elf_Shdr *s; - char *shdr; + char *shdr = 0; grub_addr_t curload, module; grub_err_t err; @@ -223,7 +223,7 @@ SUFFIX (grub_freebsd_load_elf_meta) (grub_file_t file, grub_addr_t *kern_end) grub_err_t err; Elf_Ehdr e; Elf_Shdr *s; - char *shdr; + char *shdr = 0; unsigned symoff, stroff, symsize, strsize; grub_addr_t curload; grub_freebsd_addr_t symstart, symend, symentsize, dynamic; From 0b45630927f0bb4f48589adbc1011b12b103be19 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 14 Apr 2010 13:59:58 +0100 Subject: [PATCH 571/738] Restore TEXTDOMAINDIR correction from r1889, lost apparently by mistake in r2156. Noticed by Anthony Fok. * util/grub.d/10_kfreebsd.in (TEXTDOMAINDIR): Set to lowercased @localedir@. * util/grub.d/10_linux.in (TEXTDOMAINDIR): Likewise. --- ChangeLog | 9 +++++++++ util/grub.d/10_kfreebsd.in | 2 +- util/grub.d/10_linux.in | 2 +- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9e0f3485d..1ac1ae6ce 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2010-04-14 Colin Watson + + Restore TEXTDOMAINDIR correction from r1889, lost apparently by + mistake in r2156. Noticed by Anthony Fok. + + * util/grub.d/10_kfreebsd.in (TEXTDOMAINDIR): Set to lowercased + @localedir@. + * util/grub.d/10_linux.in (TEXTDOMAINDIR): Likewise. + 2010-04-14 BVK Chaitanya Fix a spurious, uninitialized variable warning. diff --git a/util/grub.d/10_kfreebsd.in b/util/grub.d/10_kfreebsd.in index 5ab546282..f63421617 100644 --- a/util/grub.d/10_kfreebsd.in +++ b/util/grub.d/10_kfreebsd.in @@ -23,7 +23,7 @@ libdir=@libdir@ . ${libdir}/grub/grub-mkconfig_lib export TEXTDOMAIN=@PACKAGE@ -export TEXTDOMAINDIR=@LOCALEDIR@ +export TEXTDOMAINDIR=@localedir@ CLASS="--class os" diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in index e691cae86..802d59f51 100644 --- a/util/grub.d/10_linux.in +++ b/util/grub.d/10_linux.in @@ -23,7 +23,7 @@ libdir=@libdir@ . ${libdir}/grub/grub-mkconfig_lib export TEXTDOMAIN=@PACKAGE@ -export TEXTDOMAINDIR=@LOCALEDIR@ +export TEXTDOMAINDIR=@localedir@ CLASS="--class gnu-linux --class gnu --class os" From d499b1337144d3811410159d466c78ce9bd02657 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 15 Apr 2010 02:13:28 +0200 Subject: [PATCH 572/738] Remove grub/handler.h inclusion. Reported by: Giovanni Toraldo --- util/grub-editenv.c | 1 - 1 file changed, 1 deletion(-) diff --git a/util/grub-editenv.c b/util/grub-editenv.c index f21042c97..4ea97bded 100644 --- a/util/grub-editenv.c +++ b/util/grub-editenv.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include From 260ddb94173888f802d9de8f50603fa4f3c717ae Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 17 Apr 2010 16:43:04 +0200 Subject: [PATCH 573/738] create a fat16 image as efi spec requires --- util/grub-mkrescue.in | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in index b86be39e0..e7dbb45ff 100644 --- a/util/grub-mkrescue.in +++ b/util/grub-mkrescue.in @@ -203,21 +203,31 @@ if test -e "${pc_dir}" ; then --embedded-boot ${embed_img}" fi +if test -e "${efi64_dir}" || test -e "${efi32_dir}"; then + efi_dir=`mktemp -d "$MKTEMP_TEMPLATE"` + mkdir -p "${efi_dir}/efi/boot" +else + efi_dir= +fi + # build bootx64.efi if test -e "${efi64_dir}" ; then echo "Generates bootx64.efi" - mkdir -p ${iso9660_dir}/efi/boot - grub-mkimage -d ${efi64_dir}/ -o ${iso9660_dir}/efi/boot/bootx64.efi --prefix=/boot/grub/x86_64-efi \ + grub-mkimage -d "${efi64_dir}" -o "${efi_dir}"/efi/boot/bootx64.efi --prefix=/boot/grub/x86_64-efi \ search iso9660 configfile sh - modules="$(cat ${efi64_dir}/partmap.lst) ${modules}" + modules="$(cat "${efi64_dir}"/partmap.lst) ${modules}" (for i in ${modules} ; do - if [ "x$i" != xkernel.mod ]; then - echo "insmod $i" - fi + echo "insmod $i" done ; \ echo "source /boot/grub/grub.cfg") \ - > ${iso9660_dir}/boot/grub/x86_64-efi/grub.cfg + > "${iso9660_dir}"/boot/grub/x86_64-efi/grub.cfg +fi + +if test x"${efi_dir}" != x; then + mformat -C -f 2880 -L 16 -i "${iso9660_dir}"/efi.img :: + mcopy -s -i "${iso9660_dir}"/efi.img ${efi_dir}/efi ::/ + grub_mkisofs_arguments="${grub_mkisofs_arguments} --efi-boot efi.img" fi # build iso image From ebfe7eb4dd2467091e7018d6879d1ccf32cdeb6c Mon Sep 17 00:00:00 2001 From: Christian Franke Date: Sat, 17 Apr 2010 17:17:36 +0200 Subject: [PATCH 574/738] * Makefile.in: Add missing localedir setting. --- ChangeLog | 4 ++++ Makefile.in | 1 + 2 files changed, 5 insertions(+) diff --git a/ChangeLog b/ChangeLog index 1ac1ae6ce..a89f7e6cc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-04-17 Christian Franke + + * Makefile.in: Add missing localedir setting. + 2010-04-14 Colin Watson Restore TEXTDOMAINDIR correction from r1889, lost apparently by diff --git a/Makefile.in b/Makefile.in index e253af6c9..29f997213 100644 --- a/Makefile.in +++ b/Makefile.in @@ -35,6 +35,7 @@ sysconfdir = @sysconfdir@ sharedstatedir = @sharedstatedir@ localstatedir = @localstatedir@ libdir = @libdir@ +localedir = @localedir@ infodir = @infodir@ mandir = @mandir@ includedir = @includedir@ From 0973daeb380d6d1ef26a10feb28be4ef5140c861 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 17 Apr 2010 18:58:56 +0200 Subject: [PATCH 575/738] * disk/lvm.c (grub_lvm_memberlist): Issue an error if pv->disk = 0. --- ChangeLog | 4 ++++ disk/lvm.c | 7 +++++++ 2 files changed, 11 insertions(+) diff --git a/ChangeLog b/ChangeLog index a89f7e6cc..87c72cd43 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-04-17 Vladimir Serbinenko + + * disk/lvm.c (grub_lvm_memberlist): Issue an error if pv->disk = 0. + 2010-04-17 Christian Franke * Makefile.in: Add missing localedir setting. diff --git a/disk/lvm.c b/disk/lvm.c index 2c54ca3b3..c2ae82df2 100644 --- a/disk/lvm.c +++ b/disk/lvm.c @@ -24,6 +24,10 @@ #include #include +#ifdef GRUB_UTIL +#include +#endif + static struct grub_lvm_vg *vg_list; static int lv_count; @@ -68,6 +72,9 @@ grub_lvm_memberlist (grub_disk_t disk) if (lv->vg->pvs) for (pv = lv->vg->pvs; pv; pv = pv->next) { + if (!pv->disk) + grub_util_error ("Couldn't find PV %s. Check your device.map", + pv->name); tmp = grub_malloc (sizeof (*tmp)); tmp->disk = pv->disk; tmp->next = list; From 0b830b8f5edf78db51a04ff2d9bde4006057829a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 18 Apr 2010 12:59:04 +0200 Subject: [PATCH 576/738] * util/hostdisk.c (make_device_name): Change to new partition naming. --- ChangeLog | 4 ++++ util/hostdisk.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 87c72cd43..9d2277f28 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-04-18 Vladimir Serbinenko + + * util/hostdisk.c (make_device_name): Change to new partition naming. + 2010-04-17 Vladimir Serbinenko * disk/lvm.c (grub_lvm_memberlist): Issue an error if pv->disk = 0. diff --git a/util/hostdisk.c b/util/hostdisk.c index 79652625d..a8e418046 100644 --- a/util/hostdisk.c +++ b/util/hostdisk.c @@ -861,7 +861,7 @@ make_device_name (int drive, int dos_part, int bsd_part) dos_part_str = xasprintf (",%d", dos_part + 1); if (bsd_part >= 0) - bsd_part_str = xasprintf (",%c", bsd_part + 'a'); + bsd_part_str = xasprintf (",%d", bsd_part + 1); ret = xasprintf ("%s%s%s", map[drive].drive, dos_part_str ? : "", From a9e6ff28d277b5e925b73b2ca6bb4a190a9dac1d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 18 Apr 2010 13:00:06 +0200 Subject: [PATCH 577/738] * po/POTFILES: Renamed multiboot_loader.c to multiboot.c --- ChangeLog | 4 ++++ po/POTFILES | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 9d2277f28..6f39713a2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-04-18 Vladimir Serbinenko + + * po/POTFILES: Renamed multiboot_loader.c to multiboot.c + 2010-04-18 Vladimir Serbinenko * util/hostdisk.c (make_device_name): Change to new partition naming. diff --git a/po/POTFILES b/po/POTFILES index 5fabb0634..0dfc3c041 100644 --- a/po/POTFILES +++ b/po/POTFILES @@ -62,7 +62,7 @@ loader/i386/linux.c loader/i386/pc/chainloader.c loader/i386/pc/linux.c loader/i386/xnu.c -loader/multiboot_loader.c +loader/multiboot.c loader/powerpc/ieee1275/linux.c loader/sparc64/ieee1275/linux.c loader/xnu.c From 6e86896ed8bd6ce55592092c30e0c087d902cae8 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 18 Apr 2010 14:02:13 +0200 Subject: [PATCH 578/738] Use ofpathname in grub-setup on sparc --- conf/powerpc-ieee1275.rmk | 7 ++++ conf/sparc64-ieee1275.rmk | 1 + include/grub/util/hostdisk.h | 3 ++ include/grub/util/ofpath.h | 2 +- util/hostdisk.c | 6 ++++ util/{sparc64 => }/ieee1275/grub-ofpathname.c | 0 util/ieee1275/ofpath.c | 2 +- util/sparc64/ieee1275/grub-setup.c | 34 ++++--------------- 8 files changed, 26 insertions(+), 29 deletions(-) rename util/{sparc64 => }/ieee1275/grub-ofpathname.c (100%) diff --git a/conf/powerpc-ieee1275.rmk b/conf/powerpc-ieee1275.rmk index d5968ac8e..d7d477327 100644 --- a/conf/powerpc-ieee1275.rmk +++ b/conf/powerpc-ieee1275.rmk @@ -25,6 +25,13 @@ kernel_img_CFLAGS = $(COMMON_CFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) kernel_img_LDFLAGS += $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,0x200000,-Bstatic +# Utilities. +sbin_UTILITIES = grub-ofpathname + +# For grub-ofpathname. +grub_ofpathname_SOURCES = util/ieee1275/grub-ofpathname.c \ + util/ieee1275/ofpath.c util/misc.c gnulib/progname.c + # Scripts. sbin_SCRIPTS = grub-install bin_SCRIPTS = grub-mkrescue diff --git a/conf/sparc64-ieee1275.rmk b/conf/sparc64-ieee1275.rmk index 72f947f6a..a92e66a80 100644 --- a/conf/sparc64-ieee1275.rmk +++ b/conf/sparc64-ieee1275.rmk @@ -50,6 +50,7 @@ grub_mkimage_SOURCES = util/grub-mkrawimage.c util/misc.c \ # For grub-setup. util/sparc64/ieee1275/grub-setup.c_DEPENDENCIES = grub_setup_init.h grub_setup_SOURCES = util/sparc64/ieee1275/grub-setup.c util/hostdisk.c \ + util/ieee1275/ofpath.c \ util/misc.c util/getroot.c kern/device.c kern/disk.c \ kern/err.c kern/misc.c kern/parser.c kern/partition.c \ kern/file.c kern/fs.c kern/env.c kern/list.c \ diff --git a/include/grub/util/hostdisk.h b/include/grub/util/hostdisk.h index 21efb0d17..246046ee0 100644 --- a/include/grub/util/hostdisk.h +++ b/include/grub/util/hostdisk.h @@ -20,8 +20,11 @@ #ifndef GRUB_BIOSDISK_MACHINE_UTIL_HEADER #define GRUB_BIOSDISK_MACHINE_UTIL_HEADER 1 +#include + void grub_util_biosdisk_init (const char *dev_map); void grub_util_biosdisk_fini (void); char *grub_util_biosdisk_get_grub_dev (const char *os_dev); +const char *grub_util_biosdisk_get_osdev (grub_disk_t disk); #endif /* ! GRUB_BIOSDISK_MACHINE_UTIL_HEADER */ diff --git a/include/grub/util/ofpath.h b/include/grub/util/ofpath.h index 78f24d784..b43c523cb 100644 --- a/include/grub/util/ofpath.h +++ b/include/grub/util/ofpath.h @@ -1,6 +1,6 @@ #ifndef GRUB_OFPATH_MACHINE_UTIL_HEADER #define GRUB_OFPATH_MACHINE_UTIL_HEADER 1 -char *grub_util_devname_to_ofpath (char *devname); +char *grub_util_devname_to_ofpath (const char *devname); #endif /* ! GRUB_OFPATH_MACHINE_UTIL_HEADER */ diff --git a/util/hostdisk.c b/util/hostdisk.c index a8e418046..8be487461 100644 --- a/util/hostdisk.c +++ b/util/hostdisk.c @@ -1352,3 +1352,9 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) return make_device_name (drive, -1, -1); #endif } + +const char * +grub_util_biosdisk_get_osdev (grub_disk_t disk) +{ + return map[disk->id].device; +} diff --git a/util/sparc64/ieee1275/grub-ofpathname.c b/util/ieee1275/grub-ofpathname.c similarity index 100% rename from util/sparc64/ieee1275/grub-ofpathname.c rename to util/ieee1275/grub-ofpathname.c diff --git a/util/ieee1275/ofpath.c b/util/ieee1275/ofpath.c index 79a0e8be5..fa0d48cf9 100644 --- a/util/ieee1275/ofpath.c +++ b/util/ieee1275/ofpath.c @@ -368,7 +368,7 @@ strip_trailing_digits (const char *p) } char * -grub_util_devname_to_ofpath (char *devname) +grub_util_devname_to_ofpath (const char *devname) { char *name_buf, *device, *devnode, *devicenode, *ofpath; diff --git a/util/sparc64/ieee1275/grub-setup.c b/util/sparc64/ieee1275/grub-setup.c index c39ea853f..cfd58a08f 100644 --- a/util/sparc64/ieee1275/grub-setup.c +++ b/util/sparc64/ieee1275/grub-setup.c @@ -35,6 +35,7 @@ #include #include #include +#include #include @@ -103,28 +104,6 @@ grub_refresh (void) fflush (stdout); } -static char *compute_dest_ofpath (const char *dest) -{ - int len = strlen (dest); - char *res, *p, c; - - res = xmalloc (len); - p = res; - while ((c = *dest++) != '\0') - { - if (c == '\\' && *dest == ',') - { - *p++ = ','; - dest++; - } - else - *p++ = c; - } - *p++ = '\0'; - - return res; -} - static void setup (const char *prefix, const char *dir, const char *boot_file, const char *core_file, @@ -195,8 +174,6 @@ setup (const char *prefix, const char *dir, last_length = length; } - dest_ofpath = compute_dest_ofpath (dest); - /* Read the boot image by the OS service. */ boot_path = grub_util_get_path (dir, boot_file); boot_size = grub_util_get_image_size (boot_path); @@ -229,8 +206,7 @@ setup (const char *prefix, const char *dir, + GRUB_DISK_SECTOR_SIZE - sizeof (*block)); - grub_util_info ("root is `%s', dest is `%s', and dest_ofpath is `%s'", - root, dest, dest_ofpath); + grub_util_info ("root is `%s', dest is `%s'", root, dest); /* Open the root device and the destination device. */ grub_util_info ("Opening root"); @@ -243,6 +219,11 @@ setup (const char *prefix, const char *dir, if (! dest_dev) grub_util_error ("%s", grub_errmsg); + dest_ofpath + = grub_util_devname_to_ofpath (grub_util_biosdisk_get_osdev (dest_dev->disk)); + + grub_util_info ("dest_ofpath is `%s'", dest_ofpath); + grub_util_info ("setting the root device to `%s'", root); if (grub_env_set ("root", root) != GRUB_ERR_NONE) grub_util_error ("%s", grub_errmsg); @@ -449,7 +430,6 @@ init_info (struct grub_setup_info *gp) gp->dev_map = NULL; gp->root_dev = NULL; gp->prefix = NULL; - gp->dest_dev = NULL; } static int From d0faf8a1b3c0a8e21b4ef17e10118a8b336a216c Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 18 Apr 2010 16:31:27 +0200 Subject: [PATCH 579/738] Correct path to grub-ofpathname --- conf/sparc64-ieee1275.rmk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/sparc64-ieee1275.rmk b/conf/sparc64-ieee1275.rmk index a92e66a80..c82bd81f3 100644 --- a/conf/sparc64-ieee1275.rmk +++ b/conf/sparc64-ieee1275.rmk @@ -70,7 +70,7 @@ grub_setup_SOURCES = util/sparc64/ieee1275/grub-setup.c util/hostdisk.c \ grub_setup_init.c # For grub-ofpathname. -grub_ofpathname_SOURCES = util/sparc64/ieee1275/grub-ofpathname.c \ +grub_ofpathname_SOURCES = util/ieee1275/grub-ofpathname.c \ util/ieee1275/ofpath.c util/misc.c gnulib/progname.c # Scripts. From ee9056d097bafe2324d4adaf912364aa9e7fd296 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 18 Apr 2010 16:35:08 +0200 Subject: [PATCH 580/738] Support cross-disk installs. On non-cross-disk retrieve bootpath from chosen/bootpath --- boot/sparc64/ieee1275/boot.S | 16 ++++++++++++++++ include/grub/sparc64/ieee1275/boot.h | 4 ++-- util/sparc64/ieee1275/grub-setup.c | 27 +++++++++++++++++++-------- 3 files changed, 37 insertions(+), 10 deletions(-) diff --git a/boot/sparc64/ieee1275/boot.S b/boot/sparc64/ieee1275/boot.S index 167406017..4008b1b54 100644 --- a/boot/sparc64/ieee1275/boot.S +++ b/boot/sparc64/ieee1275/boot.S @@ -152,6 +152,22 @@ boot_continue: call console_write mov GRUB_NAME_LEN, %o3 + GET_ABS(boot_path, %o3) + ldub [%o3], %o1 + brnz,pn %o1, bootpath_known + mov 4, %g1 + + /* getprop(chosen_node, "bootpath", &buffer, buffer_size) */ + GET_ABS(prom_getprop_name, %o0) + mov 1, %o5 + mov CHOSEN_NODE_REG, %o1 + GET_ABS(prom_bootpath_name, %o2) + mov (kernel_sector - boot_path), %o4 + call prom_call + stx %g1, [%l1 + 256] + +bootpath_known: + /* Open up the boot_path, and use that handle to read the * first block of the GRUB kernel image. * diff --git a/include/grub/sparc64/ieee1275/boot.h b/include/grub/sparc64/ieee1275/boot.h index e1c1aa675..7b2137664 100644 --- a/include/grub/sparc64/ieee1275/boot.h +++ b/include/grub/sparc64/ieee1275/boot.h @@ -43,9 +43,9 @@ #define GRUB_BOOT_MACHINE_BOOT_DEVPATH 0x0a -#define GRUB_BOOT_MACHINE_BOOT_DEVPATH_END 0x80 +#define GRUB_BOOT_MACHINE_BOOT_DEVPATH_END (0x80 - 40) -#define GRUB_BOOT_MACHINE_KERNEL_SECTOR 0x88 +#define GRUB_BOOT_MACHINE_KERNEL_SECTOR (0x80 - 40) #define GRUB_BOOT_MACHINE_CODE_END \ (0x1fc - GRUB_BOOT_AOUT_HEADER_SIZE) diff --git a/util/sparc64/ieee1275/grub-setup.c b/util/sparc64/ieee1275/grub-setup.c index cfd58a08f..97cc89301 100644 --- a/util/sparc64/ieee1275/grub-setup.c +++ b/util/sparc64/ieee1275/grub-setup.c @@ -114,7 +114,7 @@ setup (const char *prefix, const char *dir, size_t boot_size, core_size; grub_uint16_t core_sectors; grub_device_t root_dev, dest_dev; - char *boot_devpath, *dest_ofpath; + char *boot_devpath; grub_disk_addr_t *kernel_sector; struct boot_blocklist *first_block, *block; char *tmp_img; @@ -219,11 +219,6 @@ setup (const char *prefix, const char *dir, if (! dest_dev) grub_util_error ("%s", grub_errmsg); - dest_ofpath - = grub_util_devname_to_ofpath (grub_util_biosdisk_get_osdev (dest_dev->disk)); - - grub_util_info ("dest_ofpath is `%s'", dest_ofpath); - grub_util_info ("setting the root device to `%s'", root); if (grub_env_set ("root", root) != GRUB_ERR_NONE) grub_util_error ("%s", grub_errmsg); @@ -332,6 +327,24 @@ setup (const char *prefix, const char *dir, != (grub_ssize_t) core_size - GRUB_DISK_SECTOR_SIZE) grub_util_error ("failed to read the rest sectors of the core image"); + if (file->device->disk->id != dest_dev->disk->id) + { + const char *dest_ofpath; + dest_ofpath + = grub_util_devname_to_ofpath (grub_util_biosdisk_get_osdev (file->device->disk)); + grub_util_info ("dest_ofpath is `%s'", dest_ofpath); + strncpy (boot_devpath, dest_ofpath, GRUB_BOOT_MACHINE_BOOT_DEVPATH_END + - GRUB_BOOT_MACHINE_BOOT_DEVPATH - 1); + boot_devpath[GRUB_BOOT_MACHINE_BOOT_DEVPATH_END + - GRUB_BOOT_MACHINE_BOOT_DEVPATH - 1] = 0; + } + else + { + grub_util_info ("non cross-disk install"); + memset (boot_devpath, 0, GRUB_BOOT_MACHINE_BOOT_DEVPATH_END + - GRUB_BOOT_MACHINE_BOOT_DEVPATH); + } + grub_file_close (file); free (core_path); @@ -339,8 +352,6 @@ setup (const char *prefix, const char *dir, *kernel_sector = grub_cpu_to_be64 (first_sector); - strcpy(boot_devpath, dest_ofpath); - grub_util_info ("boot device path %s, prefix is %s, dest is %s", boot_devpath, prefix, dest); From b076cdc730408d5d5ae0c6279b2560e3de1582fc Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 18 Apr 2010 18:22:58 +0200 Subject: [PATCH 581/738] Shave off bytes to compensate boot.img size increase --- boot/sparc64/ieee1275/boot.S | 73 +++++++++++++--------------- include/grub/sparc64/ieee1275/boot.h | 4 +- util/sparc64/ieee1275/grub-setup.c | 10 ++-- 3 files changed, 42 insertions(+), 45 deletions(-) diff --git a/boot/sparc64/ieee1275/boot.S b/boot/sparc64/ieee1275/boot.S index 4008b1b54..f08258f47 100644 --- a/boot/sparc64/ieee1275/boot.S +++ b/boot/sparc64/ieee1275/boot.S @@ -45,8 +45,9 @@ boot_version: .byte GRUB_BOOT_VERSION_MAJOR, GRUB_BOOT_VERSION_MINOR * load address plus the size of the prepended A.OUT header (32 bytes). */ boot_path: - . = _start + GRUB_BOOT_MACHINE_KERNEL_SECTOR -kernel_sector: .xword 2 + . = _start + GRUB_BOOT_MACHINE_KERNEL_BYTE +boot_path_end: +kernel_byte: .xword (2 << 9) kernel_address: .word GRUB_BOOT_MACHINE_KERNEL_ADDR prom_finddev_name: .asciz "finddevice" @@ -77,11 +78,23 @@ prom_error: /* %o0: OF call name * %o1: input arg 1 */ -prom_call_1_1: - mov 1, %g1 - ba prom_call - mov 1, %o5 +prom_call_1_1_o2: + clr %o2 + ba prom_call_x_1 + mov 1, %g1 +prom_call_getprop: + mov 4, %g1 + stx %g1, [%l1 + 256] + mov CHOSEN_NODE_REG, %o1 + ba prom_call_x_1 + GET_ABS(prom_getprop_name, %o0) + +prom_call_3_1_o1: + ba prom_call_3_1 + mov BOOTDEV_REG, %o1 + + /* %o2: message string * %o3: message length */ @@ -95,8 +108,9 @@ console_write: * %o2: input arg 2 * %o3: input arg 3 */ -prom_call_3_1: +prom_call_3_1: mov 3, %g1 +prom_call_x_1: mov 1, %o5 /* fallthru */ @@ -126,23 +140,17 @@ boot_continue: * chosen_node = prom_finddevice("/chosen") */ GET_ABS(prom_finddev_name, %o0) - GET_ABS(prom_chosen_path, %o1) - call prom_call_1_1 - clr %o2 + call prom_call_1_1_o2 + GET_ABS(prom_chosen_path, %o1) ldx [%l1 + 0x20], CHOSEN_NODE_REG brz CHOSEN_NODE_REG, prom_error /* getprop(chosen_node, "stdout", &buffer, buffer_size) */ - GET_ABS(prom_getprop_name, %o0) - mov 4, %g1 - mov 1, %o5 - mov CHOSEN_NODE_REG, %o1 - GET_ABS(prom_stdout_name, %o2) + GET_ABS(prom_stdout_name, %o2) add %l1, 256, %o3 - mov 1024, %o4 - call prom_call - stx %g1, [%l1 + 256] + call prom_call_getprop + mov 1024, %o4 lduw [%l1 + 256], STDOUT_NODE_REG brz,pn STDOUT_NODE_REG, prom_error @@ -155,16 +163,11 @@ boot_continue: GET_ABS(boot_path, %o3) ldub [%o3], %o1 brnz,pn %o1, bootpath_known - mov 4, %g1 /* getprop(chosen_node, "bootpath", &buffer, buffer_size) */ - GET_ABS(prom_getprop_name, %o0) - mov 1, %o5 - mov CHOSEN_NODE_REG, %o1 - GET_ABS(prom_bootpath_name, %o2) - mov (kernel_sector - boot_path), %o4 - call prom_call - stx %g1, [%l1 + 256] + GET_ABS(prom_bootpath_name, %o2) + call prom_call_getprop + mov (boot_path_end - boot_path), %o4 bootpath_known: @@ -174,9 +177,8 @@ bootpath_known: * bootdev_handle = open(boot_path) */ GET_ABS(prom_open_name, %o0) - GET_ABS(boot_path, %o1) - call prom_call_1_1 - clr %o2 + call prom_call_1_1_o2 + GET_ABS(boot_path, %o1) ldx [%l1 + 0x20], BOOTDEV_REG brz,pn BOOTDEV_REG, prom_open_error @@ -184,28 +186,23 @@ bootpath_known: /* Since we have 64-bit cells, the high cell of the seek offset * is zero and the low cell is the entire value. * - * seek(bootdev, 0, *kernel_sector << 9) + * seek(bootdev, 0, *kernel_byte) */ GET_ABS(prom_seek_name, %o0) - mov BOOTDEV_REG, %o1 clr %o2 - LDX_ABS(kernel_sector, 0x00, %o3) - call prom_call_3_1 - sllx %o3, 9, %o3 + call prom_call_3_1_o1 + LDX_ABS(kernel_byte, 0x00, %o3) /* read(bootdev, *kernel_address, 512) */ GET_ABS(prom_read_name, %o0) - mov BOOTDEV_REG, %o1 LDUW_ABS(kernel_address, 0x00, %o2) - call prom_call_3_1 + call prom_call_3_1_o1 mov 512, %o3 LDUW_ABS(kernel_address, 0x00, %o2) jmpl %o2, %o7 nop -1: ba,a 1b - . = _start + GRUB_BOOT_MACHINE_CODE_END /* the last 4 bytes in the sector 0 contain the signature */ diff --git a/include/grub/sparc64/ieee1275/boot.h b/include/grub/sparc64/ieee1275/boot.h index 7b2137664..9671c6900 100644 --- a/include/grub/sparc64/ieee1275/boot.h +++ b/include/grub/sparc64/ieee1275/boot.h @@ -43,9 +43,9 @@ #define GRUB_BOOT_MACHINE_BOOT_DEVPATH 0x0a -#define GRUB_BOOT_MACHINE_BOOT_DEVPATH_END (0x80 - 40) +#define GRUB_BOOT_MACHINE_BOOT_DEVPATH_END 0x80 -#define GRUB_BOOT_MACHINE_KERNEL_SECTOR (0x80 - 40) +#define GRUB_BOOT_MACHINE_KERNEL_BYTE 0x80 #define GRUB_BOOT_MACHINE_CODE_END \ (0x1fc - GRUB_BOOT_AOUT_HEADER_SIZE) diff --git a/util/sparc64/ieee1275/grub-setup.c b/util/sparc64/ieee1275/grub-setup.c index 97cc89301..34a006d7f 100644 --- a/util/sparc64/ieee1275/grub-setup.c +++ b/util/sparc64/ieee1275/grub-setup.c @@ -115,7 +115,7 @@ setup (const char *prefix, const char *dir, grub_uint16_t core_sectors; grub_device_t root_dev, dest_dev; char *boot_devpath; - grub_disk_addr_t *kernel_sector; + grub_disk_addr_t *kernel_byte; struct boot_blocklist *first_block, *block; char *tmp_img; int i; @@ -187,9 +187,9 @@ setup (const char *prefix, const char *dir, boot_devpath = (char *) (boot_img + GRUB_BOOT_AOUT_HEADER_SIZE + GRUB_BOOT_MACHINE_BOOT_DEVPATH); - kernel_sector = (grub_disk_addr_t *) (boot_img - + GRUB_BOOT_AOUT_HEADER_SIZE - + GRUB_BOOT_MACHINE_KERNEL_SECTOR); + kernel_byte = (grub_disk_addr_t *) (boot_img + + GRUB_BOOT_AOUT_HEADER_SIZE + + GRUB_BOOT_MACHINE_KERNEL_BYTE); core_path = grub_util_get_path (dir, core_file); core_size = grub_util_get_image_size (core_path); @@ -350,7 +350,7 @@ setup (const char *prefix, const char *dir, free (core_path); free (tmp_img); - *kernel_sector = grub_cpu_to_be64 (first_sector); + *kernel_byte = grub_cpu_to_be64 (first_sector << GRUB_DISK_SECTOR_BITS); grub_util_info ("boot device path %s, prefix is %s, dest is %s", boot_devpath, prefix, dest); From 38e55e905886e905f0a7d966e0a61cb50c86909f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Sutre?= Date: Sun, 18 Apr 2010 19:57:50 +0200 Subject: [PATCH 582/738] TARGET_IMG_LDFLAGS_AC now always expects a number appended to it. Fixed grub_prefix in grub-mkconfig for NetBSD and OpenBSD. --- ChangeLog | 9 +++++++++ acinclude.m4 | 2 +- configure.ac | 4 ++-- util/grub-mkconfig.in | 18 +++++++++++++++--- 4 files changed, 27 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6f39713a2..796d5614d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2010-04-18 Grégoire Sutre + + * util/grub-mkconfig.in: Corrected two == equality tests. + Set grub_prefix as in grub-install for NetBSD and OpenBSD. + * configure.ac: All definitions and uses of TARGET_IMG_LDFLAGS_AC now + expect a number appended to it. + * acinclude.m4 (grub_PROG_OBJCOPY_ABSOLUTE): ${TARGET_IMG_LDFLAGS_AC} + expects a number appended to it. + 2010-04-18 Vladimir Serbinenko * po/POTFILES: Renamed multiboot_loader.c to multiboot.c diff --git a/acinclude.m4 b/acinclude.m4 index 692404e20..72483b5d0 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -93,7 +93,7 @@ else fi grub_cv_prog_objcopy_absolute=yes for link_addr in 0x2000 0x8000 0x7C00; do - if AC_TRY_COMMAND([${CC-cc} ${CFLAGS} -nostdlib ${TARGET_IMG_LDFLAGS_AC} -Wl,-Ttext -Wl,$link_addr conftest.o -o conftest.exec]); then : + if AC_TRY_COMMAND([${CC-cc} ${CFLAGS} -nostdlib ${TARGET_IMG_LDFLAGS_AC}$link_addr conftest.o -o conftest.exec]); then : else AC_MSG_ERROR([${CC-cc} cannot link at address $link_addr]) fi diff --git a/configure.ac b/configure.ac index 3116d6584..5b959fb01 100644 --- a/configure.ac +++ b/configure.ac @@ -360,7 +360,7 @@ else if test -f "${srcdir}/conf/${target_cpu}-${platform}-${host_os}-img-ld.sc"; then TARGET_IMG_LDSCRIPT='$(top_srcdir)'"/conf/${target_cpu}-${platform}-${host_os}-img-ld.sc" TARGET_IMG_LDFLAGS="-Wl,-T${TARGET_IMG_LDSCRIPT} -Wl,-Ttext," - TARGET_IMG_LDFLAGS_AC="-Wl,-T${srcdir}/conf/${target_cpu}-${platform}-${host_os}-img-ld.sc" + TARGET_IMG_LDFLAGS_AC="-Wl,-T${srcdir}/conf/${target_cpu}-${platform}-${host_os}-img-ld.sc -Wl,-Ttext," else TARGET_IMG_LDSCRIPT= TARGET_IMG_LDFLAGS='-Wl,-N -Wl,-Ttext,' @@ -515,7 +515,7 @@ grub_PROG_LD_BUILD_ID_NONE if test "x$target_cpu" = xi386; then if test ! -z "$TARGET_IMG_LDSCRIPT"; then # Check symbols provided by linker script. - CFLAGS="$TARGET_CFLAGS -nostdlib $TARGET_IMG_LDFLAGS_AC -Wl,-Ttext,8000,--defsym,___main=0x8100" + CFLAGS="$TARGET_CFLAGS -nostdlib ${TARGET_IMG_LDFLAGS_AC}8000,--defsym,___main=0x8100" fi if test "x$TARGET_APPLE_CC" != x1 ; then grub_CHECK_BSS_START_SYMBOL diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in index b98bbc993..4e476ae06 100644 --- a/util/grub-mkconfig.in +++ b/util/grub-mkconfig.in @@ -24,10 +24,10 @@ sbindir=@sbindir@ libdir=@libdir@ sysconfdir=@sysconfdir@ package_version=@PACKAGE_VERSION@ +host_os=@host_os@ datarootdir=@datarootdir@ datadir=@datadir@ pkgdatadir=${datadir}/`echo @PACKAGE_TARNAME@ | sed "${transform}"` -grub_prefix=`echo /boot/grub | sed ${transform}` grub_cfg="" grub_mkconfig_dir=${sysconfdir}/grub.d @@ -75,6 +75,18 @@ done . ${libdir}/grub/grub-mkconfig_lib +case "$host_os" in +netbsd* | openbsd*) + # Because /boot is used for the boot block in NetBSD and OpenBSD, use /grub + # instead of /boot/grub. + grub_prefix=`echo /grub | sed ${transform}` + ;; +*) + # Use /boot/grub by default. + grub_prefix=`echo /boot/grub | sed ${transform}` + ;; +esac + if [ "x$EUID" = "x" ] ; then EUID=`id -u` fi @@ -141,13 +153,13 @@ if [ "x${GRUB_TERMINAL}" != "x" ] ; then fi termoutdefault=0 -if [ "x${GRUB_TERMINAL_OUTPUT}" == x ]; then +if [ "x${GRUB_TERMINAL_OUTPUT}" = "x" ]; then GRUB_TERMINAL_OUTPUT=gfxterm; termoutdefault=1; fi for x in ${GRUB_TERMINAL_OUTPUT}; do - if [ x${x} == xgfxterm ]; then + if [ "x${x}" = "xgfxterm" ]; then # If this platform supports gfxterm, try to use it. if ! test -e ${grub_prefix}/gfxterm.mod ; then if [ "x$termoutdefault" != "x1" ]; then From 7428eb2cf6b0b7e5edf250713ae4d8ee65ca598d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 18 Apr 2010 20:38:40 +0200 Subject: [PATCH 583/738] Revert useless and wrong parts --- conf/powerpc-ieee1275.rmk | 7 ------- util/sparc64/ieee1275/grub-setup.c | 1 + 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/conf/powerpc-ieee1275.rmk b/conf/powerpc-ieee1275.rmk index d7d477327..d5968ac8e 100644 --- a/conf/powerpc-ieee1275.rmk +++ b/conf/powerpc-ieee1275.rmk @@ -25,13 +25,6 @@ kernel_img_CFLAGS = $(COMMON_CFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) kernel_img_LDFLAGS += $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,0x200000,-Bstatic -# Utilities. -sbin_UTILITIES = grub-ofpathname - -# For grub-ofpathname. -grub_ofpathname_SOURCES = util/ieee1275/grub-ofpathname.c \ - util/ieee1275/ofpath.c util/misc.c gnulib/progname.c - # Scripts. sbin_SCRIPTS = grub-install bin_SCRIPTS = grub-mkrescue diff --git a/util/sparc64/ieee1275/grub-setup.c b/util/sparc64/ieee1275/grub-setup.c index 34a006d7f..b511a96b2 100644 --- a/util/sparc64/ieee1275/grub-setup.c +++ b/util/sparc64/ieee1275/grub-setup.c @@ -441,6 +441,7 @@ init_info (struct grub_setup_info *gp) gp->dev_map = NULL; gp->root_dev = NULL; gp->prefix = NULL; + gp->dest_dev = NULL; } static int From a6a6609cfc7bc1d605cd16cd36800f5d905a5e22 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 18 Apr 2010 20:38:59 +0200 Subject: [PATCH 584/738] ChangeLog --- ChangeLog.sparcfixes | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 ChangeLog.sparcfixes diff --git a/ChangeLog.sparcfixes b/ChangeLog.sparcfixes new file mode 100644 index 000000000..3e7bcbaf9 --- /dev/null +++ b/ChangeLog.sparcfixes @@ -0,0 +1,19 @@ +2010-04-18 Vladimir Serbinenko + + * boot/sparc64/ieee1275/boot.S: Various size-reducing changes. + Retrieve chosen/bootpath if bootpath isn't hardcoded. + * conf/sparc64-ieee1275.rmk (grub_setup_SOURCES): Add + util/ieee1275/ofpath.c. + * util/sparc64/ieee1275/grub-ofpathname.c: Renamed to ... + * util/ieee1275/grub-ofpathname.c: ... this. All users updated + * include/grub/sparc64/ieee1275/boot.h + (GRUB_BOOT_MACHINE_KERNEL_SECTOR): Renamed to ... + (GRUB_BOOT_MACHINE_KERNEL_BYTE): ...this. Moved 8 bytes lower. + * util/hostdisk.c (grub_util_biosdisk_get_osdev): New function. + * util/ieee1275/ofpath.c (grub_util_devname_to_ofpath): Make argument + const char *. + * util/sparc64/ieee1275/grub-setup.c (compute_dest_ofpath): Removed. + (setup): Use KERNEL_BYTE instead of KERNEL_SECTOR. + Use grub_util_devname_to_ofpath. Zero-fill boot_devpath on same disk + install. + From 189593857c736841fb79cfabbcb280f690c3ab81 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 19 Apr 2010 02:41:48 +0200 Subject: [PATCH 585/738] * fs/udf.c (grub_udf_iterate_dir): Decode the Unicode filenames. --- ChangeLog | 4 ++++ fs/udf.c | 33 ++++++++++++++++++++++++++++----- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index c9c398603..ee2cf4079 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-04-19 Vladimir Serbinenko + + * fs/udf.c (grub_udf_iterate_dir): Decode the Unicode filenames. + 2010-04-18 Vladimir Serbinenko * boot/sparc64/ieee1275/boot.S: Various size-reducing changes. diff --git a/fs/udf.c b/fs/udf.c index cecb6eb78..725468f54 100644 --- a/fs/udf.c +++ b/fs/udf.c @@ -25,6 +25,7 @@ #include #include #include +#include #define GRUB_UDF_MAX_PDS 2 #define GRUB_UDF_MAX_PMS 6 @@ -745,19 +746,41 @@ grub_udf_iterate_dir (grub_fshelp_node_t dir, else { enum grub_fshelp_filetype type; - char filename[dirent.file_ident_length + 1]; + grub_uint8_t raw[dirent.file_ident_length]; + grub_uint16_t utf16[dirent.file_ident_length - 1]; + grub_uint8_t filename[dirent.file_ident_length * 2]; + grub_size_t utf16len; type = ((dirent.characteristics & GRUB_UDF_FID_CHAR_DIRECTORY) ? (GRUB_FSHELP_DIR) : (GRUB_FSHELP_REG)); if ((grub_udf_read_file (dir, 0, offset, - dirent.file_ident_length, filename)) + dirent.file_ident_length, + (char *) raw)) != dirent.file_ident_length) return 0; - filename[dirent.file_ident_length] = 0; - if (hook (&filename[1], type, child)) - return 1; + if (raw[0] == 8) + { + unsigned i; + utf16len = dirent.file_ident_length - 1; + for (i = 0; i < utf16len; i++) + utf16[i] = raw[i + 1]; + } + if (raw[0] == 16) + { + unsigned i; + utf16len = (dirent.file_ident_length - 1) / 2; + for (i = 0; i < utf16len; i++) + utf16[i] = (raw[2 * i + 1] << 8) | raw[2*i + 2]; + } + if (raw[0] == 8 || raw[0] == 16) + { + *grub_utf16_to_utf8 (filename, utf16, utf16len) = '\0'; + + if (hook ((char *) filename, type, child)) + return 1; + } } /* Align to dword boundary. */ From f48c87aae870fd859909d9e79b0d15e2b5db2d80 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 19 Apr 2010 03:28:55 +0200 Subject: [PATCH 586/738] * fs/udf.c (grub_udf_iterate_dir): Silence a spurious warning. --- ChangeLog | 4 ++++ fs/udf.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index ee2cf4079..04e84a415 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-04-19 Vladimir Serbinenko + + * fs/udf.c (grub_udf_iterate_dir): Silence a spurious warning. + 2010-04-19 Vladimir Serbinenko * fs/udf.c (grub_udf_iterate_dir): Decode the Unicode filenames. diff --git a/fs/udf.c b/fs/udf.c index 725468f54..ad109bed9 100644 --- a/fs/udf.c +++ b/fs/udf.c @@ -749,7 +749,7 @@ grub_udf_iterate_dir (grub_fshelp_node_t dir, grub_uint8_t raw[dirent.file_ident_length]; grub_uint16_t utf16[dirent.file_ident_length - 1]; grub_uint8_t filename[dirent.file_ident_length * 2]; - grub_size_t utf16len; + grub_size_t utf16len = 0; type = ((dirent.characteristics & GRUB_UDF_FID_CHAR_DIRECTORY) ? (GRUB_FSHELP_DIR) : (GRUB_FSHELP_REG)); From 454c3001f20d7a6662db39f6e50728833eec3177 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Mon, 19 Apr 2010 15:15:59 +0530 Subject: [PATCH 587/738] fix emu build with grub-emu-pci and grub-emu-modules --- conf/any-emu.rmk | 3 ++- include/grub/libpciaccess.h | 26 ++++++++++++++++++++++++++ include/grub/util/misc.h | 7 ++++--- 3 files changed, 32 insertions(+), 4 deletions(-) create mode 100644 include/grub/libpciaccess.h diff --git a/conf/any-emu.rmk b/conf/any-emu.rmk index ddc6b0fd4..d1e5754dc 100644 --- a/conf/any-emu.rmk +++ b/conf/any-emu.rmk @@ -14,7 +14,7 @@ kernel_img_SOURCES = kern/device.c kern/disk.c kern/dl.c kern/env.c \ util/hostdisk.c util/getroot.c util/mm.c util/time.c \ \ gnulib/progname.c util/hostfs.c disk/host.c -kernel_img_HEADERS += datetime.h +kernel_img_HEADERS += datetime.h util/misc.h kernel_img_CFLAGS = $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) -Wno-undef -I$(srcdir)/gnulib kernel_img_LDFLAGS = $(COMMON_LDFLAGS) TARGET_NO_STRIP = yes @@ -88,6 +88,7 @@ pkglib_MODULES += pci.mod pci_mod_SOURCES = util/pci.c commands/lspci.c pci_mod_LDFLAGS = $(COMMON_LDFLAGS) grub_emu_LDFLAGS += $(LIBPCIACCESS) +kernel_img_HEADERS += libpciaccess.h endif include $(srcdir)/conf/common.mk diff --git a/include/grub/libpciaccess.h b/include/grub/libpciaccess.h new file mode 100644 index 000000000..4d2b3bde5 --- /dev/null +++ b/include/grub/libpciaccess.h @@ -0,0 +1,26 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +void EXPORT_FUNC (pci_slot_match_iterator_create) (void); +void EXPORT_FUNC (pci_system_cleanup) (void); +void EXPORT_FUNC (pci_device_unmap_range) (void); +void EXPORT_FUNC (pci_iterator_destroy) (void); +void EXPORT_FUNC (pci_device_map_range) (void); +void EXPORT_FUNC (pci_device_cfg_read_u32) (void); +void EXPORT_FUNC (pci_device_next) (void); +void EXPORT_FUNC (pci_system_init) (void); diff --git a/include/grub/util/misc.h b/include/grub/util/misc.h index 63d4dac6d..8b78b92ea 100644 --- a/include/grub/util/misc.h +++ b/include/grub/util/misc.h @@ -27,6 +27,7 @@ #include #include +#include #ifdef __NetBSD__ /* NetBSD uses /boot for its boot block. */ @@ -40,9 +41,9 @@ extern char *progname; extern int verbosity; -void grub_util_warn (const char *fmt, ...); -void grub_util_info (const char *fmt, ...); -void grub_util_error (const char *fmt, ...) __attribute__ ((noreturn)); +void EXPORT_FUNC(grub_util_warn) (const char *fmt, ...); +void EXPORT_FUNC(grub_util_info) (const char *fmt, ...); +void EXPORT_FUNC(grub_util_error) (const char *fmt, ...) __attribute__ ((noreturn)); void *xmalloc (size_t size); void *xrealloc (void *ptr, size_t size); From 0d2c20c6f15ec8c7bcc1e7f30c7f9e0f561deb2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Sutre?= Date: Mon, 19 Apr 2010 21:25:41 +0200 Subject: [PATCH 588/738] Add grub-mkconfig support for NetBSD. --- ChangeLog | 9 ++++ po/POTFILES-shell | 1 + util/grub-mkconfig.in | 3 ++ util/grub-mkconfig_lib.in | 8 +++- util/grub.d/10_netbsd.in | 86 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 util/grub.d/10_netbsd.in diff --git a/ChangeLog b/ChangeLog index 57565fcb3..a80606f46 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2010-04-19 Grégoire Sutre + + Add grub-mkconfig support for NetBSD. + + * util/grub.d/10_netbsd.in: grub-mkconfig helper script for NetBSD. + * util/grub-mkconfig.in: export new NetBSD specific variables. + * po/POTFILES-shell: added 10_netbsd.in. + * util/grub-mkconfig_lib.in: check for gettext binary, default to echo. + 2010-04-19 BVK Chaitanya Fix emu build with grub-emu-pci and grub-emu-modules. diff --git a/po/POTFILES-shell b/po/POTFILES-shell index cb28d331b..90d2b978c 100644 --- a/po/POTFILES-shell +++ b/po/POTFILES-shell @@ -2,3 +2,4 @@ # Shell language are included here. util/grub.d/10_kfreebsd.in util/grub.d/10_linux.in +util/grub.d/10_netbsd.in diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in index 4e476ae06..85212f8fc 100644 --- a/util/grub-mkconfig.in +++ b/util/grub-mkconfig.in @@ -239,11 +239,14 @@ export GRUB_DEFAULT \ GRUB_DISTRIBUTOR \ GRUB_CMDLINE_LINUX \ GRUB_CMDLINE_LINUX_DEFAULT \ + GRUB_CMDLINE_NETBSD \ + GRUB_CMDLINE_NETBSD_DEFAULT \ GRUB_TERMINAL_INPUT \ GRUB_TERMINAL_OUTPUT \ GRUB_SERIAL_COMMAND \ GRUB_DISABLE_LINUX_UUID \ GRUB_DISABLE_LINUX_RECOVERY \ + GRUB_DISABLE_NETBSD_RECOVERY \ GRUB_GFXMODE \ GRUB_BACKGROUND \ GRUB_THEME \ diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in index a4151348c..831bef846 100644 --- a/util/grub-mkconfig_lib.in +++ b/util/grub-mkconfig_lib.in @@ -31,6 +31,12 @@ if test "x$grub_mkrelpath" = x; then grub_mkrelpath=${bindir}/`echo grub-mkrelpath | sed ${transform}` fi +if $(which gettext >/dev/null 2>/dev/null) ; then + gettext="gettext" +else + gettext="echo" +fi + grub_warn () { echo "Warning: $@" >&2 @@ -190,5 +196,5 @@ version_find_latest () } gettext_quoted () { - gettext "$@" | sed "s/'/'\\\\''/g" + $gettext "$@" | sed "s/'/'\\\\''/g" } diff --git a/util/grub.d/10_netbsd.in b/util/grub.d/10_netbsd.in new file mode 100644 index 000000000..7e5fb34ad --- /dev/null +++ b/util/grub.d/10_netbsd.in @@ -0,0 +1,86 @@ +#! /bin/sh -e + +# grub-mkconfig helper script. +# Copyright (C) 2006,2007,2008,2009,2010 Free Software Foundation, Inc. +# +# GRUB is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# GRUB is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GRUB. If not, see . + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +bindir=@bindir@ +libdir=@libdir@ +. ${libdir}/grub/grub-mkconfig_lib + +export TEXTDOMAIN=@PACKAGE@ +export TEXTDOMAINDIR=@localedir@ + +if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then + OS=NetBSD +else + OS="${GRUB_DISTRIBUTOR} NetBSD" +fi + +netbsd_entry () +{ + loader="$1" # "knetbsd" or "multiboot" + kernel="$2" # absolute path to the kernel file + recovery="$3" # is this is a recovery entry? + args="$4" # extra arguments appended to loader command + + kroot_device="$(echo ${GRUB_DEVICE} | sed -e 's,^/dev/r,,')" + if ${recovery} ; then + title="$(gettext_quoted "%s, with kernel %s (via %s, recovery mode)")" + else + title="$(gettext_quoted "%s, with kernel %s (via %s)")" + fi + + printf "menuentry \"${title}\" {\n" \ + "${OS}" "$(echo ${kernel} | sed -e 's,^.*/,,')" "${loader}" + printf "%s\n" "${prepare_boot_cache}" + case "${loader}" in + knetbsd) + printf "\tknetbsd %s -r %s %s\n" \ + "${kernel}" "${kroot_device}" "${GRUB_CMDLINE_NETBSD} ${args}" + ;; + multiboot) + printf "\tmultiboot %s %s root=%s %s\n" \ + "${kernel}" "${kernel}" "${kroot_device}" "${GRUB_CMDLINE_NETBSD} ${args}" + ;; + esac + printf "}\n" +} + +prepare_boot_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE} | sed -e 's,^, ,')" + +# We look for NetBSD kernels in / but not in subdirectories. We simply +# pick all statically linked ELF executable files (or links) in / with a +# name that starts with `netbsd'. +pattern="^ELF[^,]*executable.*statically linked" +for k in $(ls -t /netbsd*) ; do + if ! grub_file_is_not_garbage "$k" ; then + continue + fi + if ! ((file -bL "$k" | grep -q "${pattern}") || + (zcat "$k" | file -bL - | grep -q "${pattern}")) 2>/dev/null ; then + continue + fi + + echo "Found NetBSD kernel: $k" >&2 + netbsd_entry "knetbsd" "$k" false "${GRUB_CMDLINE_NETBSD_DEFAULT}" + netbsd_entry "multiboot" "$k" false "${GRUB_CMDLINE_NETBSD_DEFAULT}" + if [ "x${GRUB_DISABLE_NETBSD_RECOVERY}" != "xtrue" ]; then + netbsd_entry "knetbsd" "$k" true "-s" + netbsd_entry "multiboot" "$k" true "-s" + fi +done From 4ba8d3540af50879a797994939c4d8559772215a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 21 Apr 2010 21:26:56 +0200 Subject: [PATCH 589/738] * configure.ac: Refuse to compile for x86_64-efi is mcmodel=large is not supported. --- ChangeLog | 5 +++++ configure.ac | 4 +--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index a80606f46..a8fab4bcc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-04-21 Vladimir Serbinenko + + * configure.ac: Refuse to compile for x86_64-efi is mcmodel=large + is not supported. + 2010-04-19 Grégoire Sutre Add grub-mkconfig support for NetBSD. diff --git a/configure.ac b/configure.ac index 5b959fb01..28b3c1d95 100644 --- a/configure.ac +++ b/configure.ac @@ -413,9 +413,7 @@ if test "$target_cpu"-"$platform" = x86_64-efi; then [grub_cv_cc_mcmodel=no]) ]) if test "x$grub_cv_cc_mcmodel" = xno; then - CFLAGS="$SAVED_CFLAGS -m64 -DMCMODEL_SMALL=1" - TARGET_CFLAGS="$TARGET_CFLAGS -DMCMODEL_SMALL=1" - AC_MSG_WARN([-mcmodel=large not supported. You won't be able to use the memory over 4GiB. Upgrade your gcc]) + AC_MSG_ERROR([-mcmodel=large not supported. Upgrade your gcc.]) else TARGET_CFLAGS="$TARGET_CFLAGS -mcmodel=large" fi From bc05c2cb2c3c77d4bda5900f7cc24c9c00da356f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 24 Apr 2010 21:08:25 +0200 Subject: [PATCH 590/738] Change to xorrisofs. Make message more clear. --- util/grub-mkrescue.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in index e7dbb45ff..057577272 100644 --- a/util/grub-mkrescue.in +++ b/util/grub-mkrescue.in @@ -212,7 +212,7 @@ fi # build bootx64.efi if test -e "${efi64_dir}" ; then - echo "Generates bootx64.efi" + echo "Enabling EFI64 support ..." grub-mkimage -d "${efi64_dir}" -o "${efi_dir}"/efi/boot/bootx64.efi --prefix=/boot/grub/x86_64-efi \ search iso9660 configfile sh @@ -231,7 +231,7 @@ if test x"${efi_dir}" != x; then fi # build iso image -grub-mkisofs ${grub_mkisofs_arguments} --protective-msdos-label -o ${output_image} -r ${iso9660_dir} ${source} +xorrisofs ${grub_mkisofs_arguments} --protective-msdos-label -o ${output_image} -r ${iso9660_dir} ${source} rm -rf ${iso9660_dir} rm -f ${embed_img} From f67dc308f6339cef658747870bfbbe31f4949e48 Mon Sep 17 00:00:00 2001 From: Jiro SEKIBA Date: Sat, 24 Apr 2010 22:09:08 +0200 Subject: [PATCH 591/738] Nilfs2 support. * conf/common.rmk (grub_probe_SOURCES): Add fs/nilfs2.c. (grub_fstest_SOURCES): Likewise. (pkglib_MODULES): Add nilfs2.mod. (nilfs2_mod_SOURCES): New variable. (nilfs2_mod_CFLAGS): Likewise. (nilfs2_mod_LDFLAGS): Likewise. * conf/i386-pc.rmk (grub_setup_SOURCES): Add fs/nilfs2.c. * conf/sparc64-ieee1275.rmk (grub_setup_SOURCES): Add fs/nilfs2.c. * fs/nilfs2.c: New file. --- ChangeLog | 14 + conf/common.rmk | 14 +- conf/i386-pc.rmk | 6 +- conf/sparc64-ieee1275.rmk | 6 +- fs/nilfs2.c | 1133 +++++++++++++++++++++++++++++++++++++ 5 files changed, 1163 insertions(+), 10 deletions(-) create mode 100644 fs/nilfs2.c diff --git a/ChangeLog b/ChangeLog index a8fab4bcc..ca82974e4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2010-04-24 Jiro SEKIBA + + Nilfs2 support. + + * conf/common.rmk (grub_probe_SOURCES): Add fs/nilfs2.c. + (grub_fstest_SOURCES): Likewise. + (pkglib_MODULES): Add nilfs2.mod. + (nilfs2_mod_SOURCES): New variable. + (nilfs2_mod_CFLAGS): Likewise. + (nilfs2_mod_LDFLAGS): Likewise. + * conf/i386-pc.rmk (grub_setup_SOURCES): Add fs/nilfs2.c. + * conf/sparc64-ieee1275.rmk (grub_setup_SOURCES): Add fs/nilfs2.c. + * fs/nilfs2.c: New file. + 2010-04-21 Vladimir Serbinenko * configure.ac: Refuse to compile for x86_64-efi is mcmodel=large diff --git a/conf/common.rmk b/conf/common.rmk index 8df232a0b..4b39e9b71 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -31,9 +31,9 @@ grub_probe_SOURCES = gnulib/progname.c util/grub-probe.c \ \ fs/affs.c fs/cpio.c fs/fat.c fs/ext2.c fs/hfs.c \ fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \ - fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c \ - fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/afs_be.c \ - fs/befs.c fs/befs_be.c fs/tar.c \ + fs/nilfs2.c fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c \ + fs/sfs.c fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c \ + fs/afs_be.c fs/befs.c fs/befs_be.c fs/tar.c \ \ partmap/msdos.c partmap/bsdlabel.c partmap/apple.c \ partmap/sun.c partmap/sunpc.c partmap/gpt.c \ @@ -69,7 +69,7 @@ grub_fstest_SOURCES = gnulib/progname.c util/grub-fstest.c util/hostfs.c \ \ fs/affs.c fs/cpio.c fs/fat.c fs/ext2.c fs/hfs.c \ fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \ - fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c \ + fs/nilfs2.c fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c \ fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/afs_be.c fs/befs.c \ fs/befs_be.c fs/tar.c \ \ @@ -298,6 +298,12 @@ minix_mod_SOURCES = fs/minix.c minix_mod_CFLAGS = $(COMMON_CFLAGS) minix_mod_LDFLAGS = $(COMMON_LDFLAGS) +# For nilfs2.mod. +pkglib_MODULES += nilfs2.mod +nilfs2_mod_SOURCES = fs/nilfs2.c +nilfs2_mod_CFLAGS = $(COMMON_CFLAGS) +nilfs2_mod_LDFLAGS = $(COMMON_LDFLAGS) + # For hfs.mod. hfs_mod_SOURCES = fs/hfs.c hfs_mod_CFLAGS = $(COMMON_CFLAGS) diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk index eace1e2da..a5a1b08ea 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -82,9 +82,9 @@ grub_setup_SOURCES = gnulib/progname.c \ \ fs/affs.c fs/cpio.c fs/ext2.c fs/fat.c fs/hfs.c \ fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \ - fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c \ - fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/afs_be.c \ - fs/befs.c fs/befs_be.c fs/tar.c \ + fs/nilfs2.c fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c \ + fs/sfs.c fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c \ + fs/afs_be.c fs/befs.c fs/befs_be.c fs/tar.c \ \ partmap/msdos.c partmap/bsdlabel.c partmap/sunpc.c \ partmap/gpt.c \ diff --git a/conf/sparc64-ieee1275.rmk b/conf/sparc64-ieee1275.rmk index c82bd81f3..f0c9b0db7 100644 --- a/conf/sparc64-ieee1275.rmk +++ b/conf/sparc64-ieee1275.rmk @@ -58,9 +58,9 @@ grub_setup_SOURCES = util/sparc64/ieee1275/grub-setup.c util/hostdisk.c \ \ fs/affs.c fs/cpio.c fs/ext2.c fs/fat.c fs/hfs.c \ fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \ - fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c \ - fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/afs_be.c \ - fs/befs.c fs/befs_be.c fs/tar.c \ + fs/nilfs2.c fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c \ + fs/sfs.c fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c \ + fs/afs_be.c fs/befs.c fs/befs_be.c fs/tar.c \ \ partmap/amiga.c partmap/apple.c partmap/msdos.c \ partmap/bsdlabel.c partmap/sun.c partmap/acorn.c \ diff --git a/fs/nilfs2.c b/fs/nilfs2.c new file mode 100644 index 000000000..7e0415d12 --- /dev/null +++ b/fs/nilfs2.c @@ -0,0 +1,1133 @@ +/* + * nilfs2.c - New Implementation of Log filesystem + * + * Written by Jiro SEKIBA + * + * Copyright (C) 2003,2004,2005,2007,2008,2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + + +/* Filetype information as used in inodes. */ +#define FILETYPE_INO_MASK 0170000 +#define FILETYPE_INO_REG 0100000 +#define FILETYPE_INO_DIRECTORY 0040000 +#define FILETYPE_INO_SYMLINK 0120000 + +#include +#include +#include +#include +#include +#include +#include +#include + +#define NILFS_INODE_BMAP_SIZE 7 + +#define NILFS_SUPORT_REV 2 + +/* Magic value used to identify an nilfs2 filesystem. */ +#define NILFS2_SUPER_MAGIC 0x3434 +/* nilfs btree node flag. */ +#define NILFS_BTREE_NODE_ROOT 0x01 + +/* nilfs btree node level. */ +#define NILFS_BTREE_LEVEL_DATA 0 +#define NILFS_BTREE_LEVEL_NODE_MIN (NILFS_BTREE_LEVEL_DATA + 1) +#define NILFS_BTREE_LEVEL_MAX 14 + +struct grub_nilfs2_inode +{ + grub_uint64_t i_blocks; + grub_uint64_t i_size; + grub_uint64_t i_ctime; + grub_uint64_t i_mtime; + grub_uint32_t i_ctime_nsec; + grub_uint32_t i_mtime_nsec; + grub_uint32_t i_uid; + grub_uint32_t i_gid; + grub_uint16_t i_mode; + grub_uint16_t i_links_count; + grub_uint32_t i_flags; + grub_uint64_t i_bmap[NILFS_INODE_BMAP_SIZE]; +#define i_device_code i_bmap[0] + grub_uint64_t i_xattr; + grub_uint32_t i_generation; + grub_uint32_t i_pad; +}; + +struct grub_nilfs2_super_root +{ + grub_uint32_t sr_sum; + grub_uint16_t sr_bytes; + grub_uint16_t sr_flags; + grub_uint64_t sr_nongc_ctime; + struct grub_nilfs2_inode sr_dat; + struct grub_nilfs2_inode sr_cpfile; + struct grub_nilfs2_inode sr_sufile; +}; + +struct grub_nilfs2_super_block +{ + grub_uint32_t s_rev_level; + grub_uint16_t s_minor_rev_level; + grub_uint16_t s_magic; + grub_uint16_t s_bytes; + grub_uint16_t s_flags; + grub_uint32_t s_crc_seed; + grub_uint32_t s_sum; + grub_uint32_t s_log_block_size; + grub_uint64_t s_nsegments; + grub_uint64_t s_dev_size; + grub_uint64_t s_first_data_block; + grub_uint32_t s_blocks_per_segment; + grub_uint32_t s_r_segments_percentage; + grub_uint64_t s_last_cno; + grub_uint64_t s_last_pseg; + grub_uint64_t s_last_seq; + grub_uint64_t s_free_blocks_count; + grub_uint64_t s_ctime; + grub_uint64_t s_mtime; + grub_uint64_t s_wtime; + grub_uint16_t s_mnt_count; + grub_uint16_t s_max_mnt_count; + grub_uint16_t s_state; + grub_uint16_t s_errors; + grub_uint64_t s_lastcheck; + grub_uint32_t s_checkinterval; + grub_uint32_t s_creator_os; + grub_uint16_t s_def_resuid; + grub_uint16_t s_def_resgid; + grub_uint32_t s_first_ino; + grub_uint16_t s_inode_size; + grub_uint16_t s_dat_entry_size; + grub_uint16_t s_checkpoint_size; + grub_uint16_t s_segment_usage_size; + grub_uint8_t s_uuid[16]; + char s_volume_name[16]; + char s_last_mounted[64]; + grub_uint32_t s_c_interval; + grub_uint32_t s_c_block_max; + grub_uint32_t s_reserved[192]; +}; + +struct grub_nilfs2_dir_entry +{ + grub_uint64_t inode; + grub_uint16_t rec_len; + grub_uint8_t name_len; + grub_uint8_t file_type; +#if 0 /* followed by file name. */ + char name[NILFS_NAME_LEN]; + char pad; +#endif +} __attribute__ ((packed)); + +enum +{ + NILFS_FT_UNKNOWN, + NILFS_FT_REG_FILE, + NILFS_FT_DIR, + NILFS_FT_CHRDEV, + NILFS_FT_BLKDEV, + NILFS_FT_FIFO, + NILFS_FT_SOCK, + NILFS_FT_SYMLINK, + NILFS_FT_MAX +}; + +struct grub_nilfs2_finfo +{ + grub_uint64_t fi_ino; + grub_uint64_t fi_cno; + grub_uint32_t fi_nblocks; + grub_uint32_t fi_ndatablk; +}; + +struct grub_nilfs2_binfo_v +{ + grub_uint64_t bi_vblocknr; + grub_uint64_t bi_blkoff; +}; + +struct grub_nilfs2_binfo_dat +{ + grub_uint64_t bi_blkoff; + grub_uint8_t bi_level; + grub_uint8_t bi_pad[7]; +}; + +union grub_nilfs2_binfo +{ + struct grub_nilfs2_binfo_v bi_v; + struct grub_nilfs2_binfo_dat bi_dat; +}; + +struct grub_nilfs2_segment_summary +{ + grub_uint32_t ss_datasum; + grub_uint32_t ss_sumsum; + grub_uint32_t ss_magic; + grub_uint16_t ss_bytes; + grub_uint16_t ss_flags; + grub_uint64_t ss_seq; + grub_uint64_t ss_create; + grub_uint64_t ss_next; + grub_uint32_t ss_nblocks; + grub_uint32_t ss_nfinfo; + grub_uint32_t ss_sumbytes; + grub_uint32_t ss_pad; +}; + +struct grub_nilfs2_btree_node +{ + grub_uint8_t bn_flags; + grub_uint8_t bn_level; + grub_uint16_t bn_nchildren; + grub_uint32_t bn_pad; +}; + +struct grub_nilfs2_palloc_group_desc +{ + grub_uint32_t pg_nfrees; +}; + +struct grub_nilfs2_dat_entry +{ + grub_uint64_t de_blocknr; + grub_uint64_t de_start; + grub_uint64_t de_end; + grub_uint64_t de_rsv; +}; + +struct grub_nilfs2_snapshot_list +{ + grub_uint64_t ssl_next; + grub_uint64_t ssl_prev; +}; + +struct grub_nilfs2_cpfile_header +{ + grub_uint64_t ch_ncheckpoints; + grub_uint64_t ch_nsnapshots; + struct grub_nilfs2_snapshot_list ch_snapshot_list; +}; + +struct grub_nilfs2_checkpoint +{ + grub_uint32_t cp_flags; + grub_uint32_t cp_checkpoints_count; + struct grub_nilfs2_snapshot_list cp_snapshot_list; + grub_uint64_t cp_cno; + grub_uint64_t cp_create; + grub_uint64_t cp_nblk_inc; + grub_uint64_t cp_inodes_count; + grub_uint64_t cp_blocks_count; + struct grub_nilfs2_inode cp_ifile_inode; +}; + + +#define NILFS_BMAP_LARGE 0x1 +#define NILFS_BMAP_SIZE (NILFS_INODE_BMAP_SIZE * sizeof(grub_uint64_t)) + +/* nilfs extra padding for nonroot btree node. */ +#define NILFS_BTREE_NODE_EXTRA_PAD_SIZE (sizeof(grub_uint64_t)) +#define NILFS_BTREE_ROOT_SIZE NILFS_BMAP_SIZE +#define NILFS_BTREE_ROOT_NCHILDREN_MAX \ + ((NILFS_BTREE_ROOT_SIZE - sizeof(struct nilfs_btree_node)) / \ + (sizeof(grub_uint64_t) + sizeof(grub_uint64_t)) ) + + +struct grub_fshelp_node +{ + struct grub_nilfs2_data *data; + struct grub_nilfs2_inode inode; + grub_uint64_t ino; + int inode_read; +}; + +struct grub_nilfs2_data +{ + struct grub_nilfs2_super_block sblock; + struct grub_nilfs2_super_root sroot; + struct grub_nilfs2_inode ifile; + grub_disk_t disk; + struct grub_nilfs2_inode *inode; + struct grub_fshelp_node diropen; +}; + +/* Log2 size of nilfs2 block in 512 blocks. */ +#define LOG2_NILFS2_BLOCK_SIZE(data) \ + (grub_le_to_cpu32 (data->sblock.s_log_block_size) + 1) + +/* Log2 size of nilfs2 block in bytes. */ +#define LOG2_BLOCK_SIZE(data) \ + (grub_le_to_cpu32 (data->sblock.s_log_block_size) + 10) + +/* The size of an nilfs2 block in bytes. */ +#define NILFS2_BLOCK_SIZE(data) (1 << LOG2_BLOCK_SIZE (data)) + +static grub_uint64_t +grub_nilfs2_dat_translate (struct grub_nilfs2_data *data, grub_uint64_t key); +static grub_dl_t my_mod; + + + +static inline unsigned long +grub_nilfs2_palloc_entries_per_group (struct grub_nilfs2_data *data) +{ + return 1UL << (LOG2_BLOCK_SIZE (data) + 3); +} + +static inline grub_uint64_t +grub_nilfs2_palloc_group (struct grub_nilfs2_data *data, + grub_uint64_t nr, grub_uint32_t * offset) +{ + return grub_divmod64 (nr, grub_nilfs2_palloc_entries_per_group (data), + offset); +} + +static inline grub_uint32_t +grub_nilfs2_palloc_groups_per_desc_block (struct grub_nilfs2_data *data) +{ + return NILFS2_BLOCK_SIZE (data) / + sizeof (struct grub_nilfs2_palloc_group_desc); +} + +static inline grub_uint32_t +grub_nilfs2_entries_per_block (struct grub_nilfs2_data *data, + unsigned long entry_size) +{ + return NILFS2_BLOCK_SIZE (data) / entry_size; +} + + +static inline grub_uint32_t +grub_nilfs2_blocks_per_group (struct grub_nilfs2_data *data, + unsigned long entry_size) +{ + return grub_div_roundup (grub_nilfs2_palloc_entries_per_group (data), + grub_nilfs2_entries_per_block (data, + entry_size)) + 1; +} + +static inline grub_uint32_t +grub_nilfs2_blocks_per_desc_block (struct grub_nilfs2_data *data, + unsigned long entry_size) +{ + return grub_nilfs2_palloc_groups_per_desc_block (data) * + grub_nilfs2_blocks_per_group (data, entry_size) + 1; +} + +static inline grub_uint32_t +grub_nilfs2_palloc_desc_block_offset (struct grub_nilfs2_data *data, + unsigned long group, + unsigned long entry_size) +{ + grub_uint32_t desc_block = + group / grub_nilfs2_palloc_groups_per_desc_block (data); + return desc_block * grub_nilfs2_blocks_per_desc_block (data, entry_size); +} + +static inline grub_uint32_t +grub_nilfs2_palloc_bitmap_block_offset (struct grub_nilfs2_data *data, + unsigned long group, + unsigned long entry_size) +{ + unsigned long desc_offset = group % + grub_nilfs2_palloc_groups_per_desc_block (data); + + return grub_nilfs2_palloc_desc_block_offset (data, group, entry_size) + 1 + + desc_offset * grub_nilfs2_blocks_per_group (data, entry_size); +} + +static inline grub_uint32_t +grub_nilfs2_palloc_entry_offset (struct grub_nilfs2_data *data, + grub_uint64_t nr, unsigned long entry_size) +{ + unsigned long group; + grub_uint32_t group_offset; + + group = grub_nilfs2_palloc_group (data, nr, &group_offset); + + return grub_nilfs2_palloc_bitmap_block_offset (data, group, + entry_size) + 1 + + group_offset / grub_nilfs2_entries_per_block (data, entry_size); + +} + +static inline struct grub_nilfs2_btree_node * +grub_nilfs2_btree_get_root (struct grub_nilfs2_inode *inode) +{ + return (struct grub_nilfs2_btree_node *) &inode->i_bmap[0]; +} + +static inline int +grub_nilfs2_btree_get_level (struct grub_nilfs2_btree_node *node) +{ + return node->bn_level; +} + +static inline grub_uint64_t * +grub_nilfs2_btree_node_dkeys (struct grub_nilfs2_btree_node *node) +{ + return (grub_uint64_t *) ((char *) (node + 1) + + ((node->bn_flags & NILFS_BTREE_NODE_ROOT) ? + 0 : NILFS_BTREE_NODE_EXTRA_PAD_SIZE)); +} + +static inline grub_uint64_t +grub_nilfs2_btree_node_get_key (struct grub_nilfs2_btree_node *node, + int index) +{ + return grub_le_to_cpu64 (*(grub_nilfs2_btree_node_dkeys (node) + index)); +} + +static inline int +grub_nilfs2_btree_node_lookup (struct grub_nilfs2_btree_node *node, + grub_uint64_t key, int *indexp) +{ + grub_uint64_t nkey; + int index, low, high, s; + + low = 0; + high = grub_le_to_cpu16 (node->bn_nchildren) - 1; + index = 0; + s = 0; + while (low <= high) + { + index = (low + high) / 2; + nkey = grub_nilfs2_btree_node_get_key (node, index); + if (nkey == key) + { + *indexp = index; + return 1; + } + else if (nkey < key) + { + low = index + 1; + s = -1; + } + else + { + high = index - 1; + s = 1; + } + } + + if (node->bn_level > NILFS_BTREE_LEVEL_NODE_MIN) + { + if (s > 0 && index > 0) + index--; + } + else if (s < 0) + index++; + + *indexp = index; + return s == 0; +} + +static inline int +grub_nilfs2_btree_node_nchildren_max (struct grub_nilfs2_data *data, + struct grub_nilfs2_btree_node *node) +{ + int node_children_max = ((NILFS2_BLOCK_SIZE (data) - + sizeof (struct grub_nilfs2_btree_node) - + NILFS_BTREE_NODE_EXTRA_PAD_SIZE) / + (sizeof (grub_uint64_t) + sizeof (grub_uint64_t))); + + return (node->bn_flags & NILFS_BTREE_NODE_ROOT) ? 3 : node_children_max; +} + +static inline grub_uint64_t * +grub_nilfs2_btree_node_dptrs (struct grub_nilfs2_data *data, + struct grub_nilfs2_btree_node *node) +{ + return (grub_uint64_t *) (grub_nilfs2_btree_node_dkeys (node) + + grub_nilfs2_btree_node_nchildren_max (data, + node)); +} + +static inline grub_uint64_t +grub_nilfs2_btree_node_get_ptr (struct grub_nilfs2_data *data, + struct grub_nilfs2_btree_node *node, + int index) +{ + return + grub_le_to_cpu64 (*(grub_nilfs2_btree_node_dptrs (data, node) + index)); +} + +static inline int +grub_nilfs2_btree_get_nonroot_node (struct grub_nilfs2_data *data, + grub_uint64_t ptr, void *block) +{ + grub_disk_t disk = data->disk; + unsigned int nilfs2_block_count = (1 << LOG2_NILFS2_BLOCK_SIZE (data)); + + return grub_disk_read (disk, ptr * nilfs2_block_count, 0, + NILFS2_BLOCK_SIZE (data), block); +} + +static grub_uint64_t +grub_nilfs2_btree_lookup (struct grub_nilfs2_data *data, + struct grub_nilfs2_inode *inode, + grub_uint64_t key, int need_translate) +{ + struct grub_nilfs2_btree_node *node; + unsigned char block[NILFS2_BLOCK_SIZE (data)]; + grub_uint64_t ptr; + int level, found, index; + + node = grub_nilfs2_btree_get_root (inode); + level = grub_nilfs2_btree_get_level (node); + + found = grub_nilfs2_btree_node_lookup (node, key, &index); + ptr = grub_nilfs2_btree_node_get_ptr (data, node, index); + if (need_translate) + ptr = grub_nilfs2_dat_translate (data, ptr); + + for (level--; level >= NILFS_BTREE_LEVEL_NODE_MIN; level--) + { + grub_nilfs2_btree_get_nonroot_node (data, ptr, block); + if (grub_errno) + { + return -1; + } + node = (struct grub_nilfs2_btree_node *) block; + + if (node->bn_level != level) + { + grub_error (GRUB_ERR_BAD_FS, "btree level mismatch\n"); + return -1; + } + + if (!found) + found = grub_nilfs2_btree_node_lookup (node, key, &index); + else + index = 0; + + if (index < grub_nilfs2_btree_node_nchildren_max (data, node)) + { + ptr = grub_nilfs2_btree_node_get_ptr (data, node, index); + if (need_translate) + ptr = grub_nilfs2_dat_translate (data, ptr); + } + else + { + grub_error (GRUB_ERR_BAD_FS, "btree corruption\n"); + return -1; + } + } + + if (!found) + return -1; + + return ptr; +} + +static inline grub_uint64_t +grub_nilfs2_direct_lookup (struct grub_nilfs2_inode *inode, grub_uint64_t key) +{ + return grub_le_to_cpu64 (inode->i_bmap[1 + key]); +} + +static inline grub_uint64_t +grub_nilfs2_bmap_lookup (struct grub_nilfs2_data *data, + struct grub_nilfs2_inode *inode, + grub_uint64_t key, int need_translate) +{ + struct grub_nilfs2_btree_node *root = grub_nilfs2_btree_get_root (inode); + if (root->bn_flags & NILFS_BMAP_LARGE) + return grub_nilfs2_btree_lookup (data, inode, key, need_translate); + else + { + grub_uint64_t ptr; + ptr = grub_nilfs2_direct_lookup (inode, key); + if (need_translate) + ptr = grub_nilfs2_dat_translate (data, ptr); + return ptr; + } +} + +static grub_uint64_t +grub_nilfs2_dat_translate (struct grub_nilfs2_data *data, grub_uint64_t key) +{ + struct grub_nilfs2_dat_entry entry; + grub_disk_t disk = data->disk; + grub_uint64_t pptr; + grub_uint32_t blockno, offset; + unsigned int nilfs2_block_count = (1 << LOG2_NILFS2_BLOCK_SIZE (data)); + + blockno = grub_nilfs2_palloc_entry_offset (data, key, + sizeof (struct + grub_nilfs2_dat_entry)); + + grub_divmod64 (key * sizeof (struct grub_nilfs2_dat_entry), + NILFS2_BLOCK_SIZE (data), &offset); + + pptr = grub_nilfs2_bmap_lookup (data, &data->sroot.sr_dat, blockno, 0); + if (pptr == (grub_uint64_t) - 1) + { + grub_error (GRUB_ERR_BAD_FS, "btree lookup failure"); + return -1; + } + + grub_disk_read (disk, pptr * nilfs2_block_count, offset, + sizeof (struct grub_nilfs2_dat_entry), &entry); + + return grub_le_to_cpu64 (entry.de_blocknr); +} + + +static grub_disk_addr_t +grub_nilfs2_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) +{ + struct grub_nilfs2_data *data = node->data; + struct grub_nilfs2_inode *inode = &node->inode; + grub_uint64_t pptr = -1; + + pptr = grub_nilfs2_bmap_lookup (data, inode, fileblock, 1); + if (pptr == (grub_uint64_t) - 1) + { + grub_error (GRUB_ERR_BAD_FS, "btree lookup failure"); + return -1; + } + + return pptr; +} + +/* Read LEN bytes from the file described by DATA starting with byte + POS. Return the amount of read bytes in READ. */ +static grub_ssize_t +grub_nilfs2_read_file (grub_fshelp_node_t node, + void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t + sector, + unsigned offset, + unsigned length), + int pos, grub_size_t len, char *buf) +{ + return grub_fshelp_read_file (node->data->disk, node, read_hook, + pos, len, buf, grub_nilfs2_read_block, + grub_le_to_cpu64 (node->inode.i_size), + LOG2_NILFS2_BLOCK_SIZE (node->data)); + +} + +static grub_err_t +grub_nilfs2_read_checkpoint (struct grub_nilfs2_data *data, + grub_uint64_t cpno, + struct grub_nilfs2_checkpoint *cpp) +{ + grub_uint64_t blockno; + grub_uint32_t offset; + grub_uint64_t pptr; + grub_disk_t disk = data->disk; + unsigned int nilfs2_block_count = (1 << LOG2_NILFS2_BLOCK_SIZE (data)); + + /* Assume sizeof(struct grub_nilfs2_cpfile_header) < + sizeof(struct grub_nilfs2_checkpoint). + */ + blockno = grub_divmod64 (cpno, NILFS2_BLOCK_SIZE (data) / + sizeof (struct grub_nilfs2_checkpoint), &offset); + + pptr = grub_nilfs2_bmap_lookup (data, &data->sroot.sr_cpfile, blockno, 1); + if (pptr == (grub_uint64_t) - 1) + { + return grub_error (GRUB_ERR_BAD_FS, "btree lookup failure"); + } + + return grub_disk_read (disk, pptr * nilfs2_block_count, + offset * sizeof (struct grub_nilfs2_checkpoint), + sizeof (struct grub_nilfs2_checkpoint), cpp); +} + +static inline grub_err_t +grub_nilfs2_read_last_checkpoint (struct grub_nilfs2_data *data, + struct grub_nilfs2_checkpoint *cpp) +{ + return grub_nilfs2_read_checkpoint (data, + grub_le_to_cpu64 (data-> + sblock.s_last_cno), + cpp); +} + +/* Read the inode INO for the file described by DATA into INODE. */ +static grub_err_t +grub_nilfs2_read_inode (struct grub_nilfs2_data *data, + grub_uint64_t ino, struct grub_nilfs2_inode *inodep) +{ + grub_uint64_t blockno; + unsigned int offset; + grub_uint64_t pptr; + grub_disk_t disk = data->disk; + unsigned int nilfs2_block_count = (1 << LOG2_NILFS2_BLOCK_SIZE (data)); + + blockno = grub_nilfs2_palloc_entry_offset (data, ino, + sizeof (struct + grub_nilfs2_inode)); + + grub_divmod64 (sizeof (struct grub_nilfs2_inode) * ino, + NILFS2_BLOCK_SIZE (data), &offset); + pptr = grub_nilfs2_bmap_lookup (data, &data->ifile, blockno, 1); + if (pptr == (grub_uint64_t) - 1) + { + return grub_error (GRUB_ERR_BAD_FS, "btree lookup failure"); + } + + return grub_disk_read (disk, pptr * nilfs2_block_count, offset, + sizeof (struct grub_nilfs2_inode), inodep); +} + +static int +grub_nilfs2_valid_sb (struct grub_nilfs2_super_block *sbp) +{ + if (grub_le_to_cpu16 (sbp->s_magic) != NILFS2_SUPER_MAGIC) + return 0; + + if (grub_le_to_cpu32 (sbp->s_rev_level) != NILFS_SUPORT_REV) + return 0; + + return 1; +} + +static struct grub_nilfs2_data * +grub_nilfs2_mount (grub_disk_t disk) +{ + struct grub_nilfs2_data *data; + struct grub_nilfs2_segment_summary ss; + struct grub_nilfs2_checkpoint last_checkpoint; + grub_uint64_t last_pseg; + grub_uint32_t nblocks; + unsigned int nilfs2_block_count; + + data = grub_malloc (sizeof (struct grub_nilfs2_data)); + if (!data) + return 0; + + /* Read the superblock. */ + grub_disk_read (disk, 1 * 2, 0, sizeof (struct grub_nilfs2_super_block), + &data->sblock); + if (grub_errno) + goto fail; + + /* Make sure this is an nilfs2 filesystem. */ + if (!grub_nilfs2_valid_sb (&data->sblock)) + { + grub_error (GRUB_ERR_BAD_FS, "not a nilfs2 filesystem"); + goto fail; + } + + nilfs2_block_count = (1 << LOG2_NILFS2_BLOCK_SIZE (data)); + + /* Read the last segment summary. */ + last_pseg = grub_le_to_cpu64 (data->sblock.s_last_pseg); + grub_disk_read (disk, last_pseg * nilfs2_block_count, 0, + sizeof (struct grub_nilfs2_segment_summary), &ss); + + if (grub_errno) + goto fail; + + /* Read the super root block. */ + nblocks = grub_le_to_cpu32 (ss.ss_nblocks); + grub_disk_read (disk, (last_pseg + (nblocks - 1)) * nilfs2_block_count, 0, + sizeof (struct grub_nilfs2_super_root), &data->sroot); + + if (grub_errno) + goto fail; + + data->disk = disk; + + grub_nilfs2_read_last_checkpoint (data, &last_checkpoint); + + if (grub_errno) + goto fail; + + grub_memcpy (&data->ifile, &last_checkpoint.cp_ifile_inode, + sizeof (struct grub_nilfs2_inode)); + + data->diropen.data = data; + data->diropen.ino = 2; + data->diropen.inode_read = 1; + data->inode = &data->diropen.inode; + + grub_nilfs2_read_inode (data, 2, data->inode); + + return data; + +fail: + if (grub_errno == GRUB_ERR_OUT_OF_RANGE) + grub_error (GRUB_ERR_BAD_FS, "not a nilfs2 filesystem"); + + grub_free (data); + return 0; +} + +static char * +grub_nilfs2_read_symlink (grub_fshelp_node_t node) +{ + char *symlink; + struct grub_fshelp_node *diro = node; + + if (!diro->inode_read) + { + grub_nilfs2_read_inode (diro->data, diro->ino, &diro->inode); + if (grub_errno) + return 0; + } + + symlink = grub_malloc (grub_le_to_cpu64 (diro->inode.i_size) + 1); + if (!symlink) + return 0; + + grub_nilfs2_read_file (diro, 0, 0, + grub_le_to_cpu64 (diro->inode.i_size), symlink); + if (grub_errno) + { + grub_free (symlink); + return 0; + } + + symlink[grub_le_to_cpu64 (diro->inode.i_size)] = '\0'; + return symlink; +} + +static int +grub_nilfs2_iterate_dir (grub_fshelp_node_t dir, + int NESTED_FUNC_ATTR + (*hook) (const char *filename, + enum grub_fshelp_filetype filetype, + grub_fshelp_node_t node)) +{ + unsigned int fpos = 0; + struct grub_fshelp_node *diro = (struct grub_fshelp_node *) dir; + + if (!diro->inode_read) + { + grub_nilfs2_read_inode (diro->data, diro->ino, &diro->inode); + if (grub_errno) + return 0; + } + + /* Iterate files. */ + while (fpos < grub_le_to_cpu64 (diro->inode.i_size)) + { + struct grub_nilfs2_dir_entry dirent; + + grub_nilfs2_read_file (diro, 0, fpos, + sizeof (struct grub_nilfs2_dir_entry), + (char *) &dirent); + if (grub_errno) + return 0; + + if (dirent.rec_len == 0) + return 0; + + if (dirent.name_len != 0) + { + char filename[dirent.name_len + 1]; + struct grub_fshelp_node *fdiro; + enum grub_fshelp_filetype type = GRUB_FSHELP_UNKNOWN; + + grub_nilfs2_read_file (diro, 0, + fpos + sizeof (struct grub_nilfs2_dir_entry), + dirent.name_len, filename); + if (grub_errno) + return 0; + + fdiro = grub_malloc (sizeof (struct grub_fshelp_node)); + if (!fdiro) + return 0; + + fdiro->data = diro->data; + fdiro->ino = grub_le_to_cpu64 (dirent.inode); + + filename[dirent.name_len] = '\0'; + + if (dirent.file_type != NILFS_FT_UNKNOWN) + { + fdiro->inode_read = 0; + + if (dirent.file_type == NILFS_FT_DIR) + type = GRUB_FSHELP_DIR; + else if (dirent.file_type == NILFS_FT_SYMLINK) + type = GRUB_FSHELP_SYMLINK; + else if (dirent.file_type == NILFS_FT_REG_FILE) + type = GRUB_FSHELP_REG; + } + else + { + /* The filetype can not be read from the dirent, read + the inode to get more information. */ + grub_nilfs2_read_inode (diro->data, + grub_le_to_cpu64 (dirent.inode), + &fdiro->inode); + if (grub_errno) + { + grub_free (fdiro); + return 0; + } + + fdiro->inode_read = 1; + + if ((grub_le_to_cpu16 (fdiro->inode.i_mode) + & FILETYPE_INO_MASK) == FILETYPE_INO_DIRECTORY) + type = GRUB_FSHELP_DIR; + else if ((grub_le_to_cpu16 (fdiro->inode.i_mode) + & FILETYPE_INO_MASK) == FILETYPE_INO_SYMLINK) + type = GRUB_FSHELP_SYMLINK; + else if ((grub_le_to_cpu16 (fdiro->inode.i_mode) + & FILETYPE_INO_MASK) == FILETYPE_INO_REG) + type = GRUB_FSHELP_REG; + } + + if (hook (filename, type, fdiro)) + return 1; + } + + fpos += grub_le_to_cpu16 (dirent.rec_len); + } + + return 0; +} + +/* Open a file named NAME and initialize FILE. */ +static grub_err_t +grub_nilfs2_open (struct grub_file *file, const char *name) +{ + struct grub_nilfs2_data *data = NULL; + struct grub_fshelp_node *fdiro = 0; + + grub_dl_ref (my_mod); + + data = grub_nilfs2_mount (file->device->disk); + if (!data) + goto fail; + + grub_fshelp_find_file (name, &data->diropen, &fdiro, + grub_nilfs2_iterate_dir, grub_nilfs2_read_symlink, + GRUB_FSHELP_REG); + if (grub_errno) + goto fail; + + if (!fdiro->inode_read) + { + grub_nilfs2_read_inode (data, fdiro->ino, &fdiro->inode); + if (grub_errno) + goto fail; + } + + grub_memcpy (data->inode, &fdiro->inode, sizeof (struct grub_nilfs2_inode)); + grub_free (fdiro); + + file->size = grub_le_to_cpu64 (data->inode->i_size); + file->data = data; + file->offset = 0; + + return 0; + +fail: + if (fdiro != &data->diropen) + grub_free (fdiro); + grub_free (data); + + grub_dl_unref (my_mod); + + return grub_errno; +} + +static grub_err_t +grub_nilfs2_close (grub_file_t file) +{ + grub_free (file->data); + + grub_dl_unref (my_mod); + + return GRUB_ERR_NONE; +} + +/* Read LEN bytes data from FILE into BUF. */ +static grub_ssize_t +grub_nilfs2_read (grub_file_t file, char *buf, grub_size_t len) +{ + struct grub_nilfs2_data *data = (struct grub_nilfs2_data *) file->data; + + return grub_nilfs2_read_file (&data->diropen, file->read_hook, + file->offset, len, buf); +} + +static grub_err_t +grub_nilfs2_dir (grub_device_t device, const char *path, + int (*hook) (const char *filename, + const struct grub_dirhook_info * info)) +{ + struct grub_nilfs2_data *data = 0; + struct grub_fshelp_node *fdiro = 0; + + auto int NESTED_FUNC_ATTR iterate (const char *filename, + enum grub_fshelp_filetype filetype, + grub_fshelp_node_t node); + + int NESTED_FUNC_ATTR iterate (const char *filename, + enum grub_fshelp_filetype filetype, + grub_fshelp_node_t node) + { + struct grub_dirhook_info info; + grub_memset (&info, 0, sizeof (info)); + if (!node->inode_read) + { + grub_nilfs2_read_inode (data, node->ino, &node->inode); + if (!grub_errno) + node->inode_read = 1; + grub_errno = GRUB_ERR_NONE; + } + if (node->inode_read) + { + info.mtimeset = 1; + info.mtime = grub_le_to_cpu64 (node->inode.i_mtime); + } + + info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); + grub_free (node); + return hook (filename, &info); + } + + grub_dl_ref (my_mod); + + data = grub_nilfs2_mount (device->disk); + if (!data) + goto fail; + + grub_fshelp_find_file (path, &data->diropen, &fdiro, + grub_nilfs2_iterate_dir, grub_nilfs2_read_symlink, + GRUB_FSHELP_DIR); + if (grub_errno) + goto fail; + + grub_nilfs2_iterate_dir (fdiro, iterate); + +fail: + if (fdiro != &data->diropen) + grub_free (fdiro); + grub_free (data); + + grub_dl_unref (my_mod); + + return grub_errno; +} + +static grub_err_t +grub_nilfs2_label (grub_device_t device, char **label) +{ + struct grub_nilfs2_data *data; + grub_disk_t disk = device->disk; + + grub_dl_ref (my_mod); + + data = grub_nilfs2_mount (disk); + if (data) + *label = grub_strndup (data->sblock.s_volume_name, 14); + else + *label = NULL; + + grub_dl_unref (my_mod); + + grub_free (data); + + return grub_errno; +} + +static grub_err_t +grub_nilfs2_uuid (grub_device_t device, char **uuid) +{ + struct grub_nilfs2_data *data; + grub_disk_t disk = device->disk; + + grub_dl_ref (my_mod); + + data = grub_nilfs2_mount (disk); + if (data) + { + *uuid = + grub_xasprintf + ("%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%0x-%02x%02x%02x%02x%02x%02x", + data->sblock.s_uuid[0], data->sblock.s_uuid[1], + data->sblock.s_uuid[2], data->sblock.s_uuid[3], + data->sblock.s_uuid[4], data->sblock.s_uuid[5], + data->sblock.s_uuid[6], data->sblock.s_uuid[7], + data->sblock.s_uuid[8], data->sblock.s_uuid[9], + data->sblock.s_uuid[10], data->sblock.s_uuid[11], + data->sblock.s_uuid[12], data->sblock.s_uuid[13], + data->sblock.s_uuid[14], data->sblock.s_uuid[15]); + } + else + *uuid = NULL; + + grub_dl_unref (my_mod); + + grub_free (data); + + return grub_errno; +} + +/* Get mtime. */ +static grub_err_t +grub_nilfs2_mtime (grub_device_t device, grub_int32_t * tm) +{ + struct grub_nilfs2_data *data; + grub_disk_t disk = device->disk; + + grub_dl_ref (my_mod); + + data = grub_nilfs2_mount (disk); + if (!data) + *tm = 0; + else + *tm = (grub_int32_t) grub_le_to_cpu64 (data->sblock.s_mtime); + + grub_dl_unref (my_mod); + + grub_free (data); + + return grub_errno; +} + + + +static struct grub_fs grub_nilfs2_fs = { + .name = "nilfs2", + .dir = grub_nilfs2_dir, + .open = grub_nilfs2_open, + .read = grub_nilfs2_read, + .close = grub_nilfs2_close, + .label = grub_nilfs2_label, + .uuid = grub_nilfs2_uuid, + .mtime = grub_nilfs2_mtime, +#ifdef GRUB_UTIL + .reserved_first_sector = 1, +#endif + .next = 0 +}; + +GRUB_MOD_INIT (nilfs2) +{ + grub_fs_register (&grub_nilfs2_fs); + my_mod = mod; +} + +GRUB_MOD_FINI (nilfs2) +{ + grub_fs_unregister (&grub_nilfs2_fs); +} From 2aec1692d929f28b75242beafaf971d777b78655 Mon Sep 17 00:00:00 2001 From: Christian Franke Date: Sat, 24 Apr 2010 22:41:52 +0200 Subject: [PATCH 592/738] * configure.ac: Do not CHECK_BSS_START_SYMBOL and CHECK_END_SYMBOL if grub-emu is built. Unset TARGET_OBJ2ELF if grub-emu is built without module support. --- ChangeLog | 7 +++++++ configure.ac | 16 +++++++++++----- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index ca82974e4..044b396b3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-04-24 Christian Franke + + * configure.ac: Do not CHECK_BSS_START_SYMBOL + and CHECK_END_SYMBOL if grub-emu is built. + Unset TARGET_OBJ2ELF if grub-emu is built + without module support. + 2010-04-24 Jiro SEKIBA Nilfs2 support. diff --git a/configure.ac b/configure.ac index 28b3c1d95..4bfc5a2b0 100644 --- a/configure.ac +++ b/configure.ac @@ -511,11 +511,11 @@ grub_PROG_OBJCOPY_ABSOLUTE fi grub_PROG_LD_BUILD_ID_NONE if test "x$target_cpu" = xi386; then - if test ! -z "$TARGET_IMG_LDSCRIPT"; then - # Check symbols provided by linker script. - CFLAGS="$TARGET_CFLAGS -nostdlib ${TARGET_IMG_LDFLAGS_AC}8000,--defsym,___main=0x8100" - fi - if test "x$TARGET_APPLE_CC" != x1 ; then + if test "$platform" != emu && test "x$TARGET_APPLE_CC" != x1 ; then + if test ! -z "$TARGET_IMG_LDSCRIPT"; then + # Check symbols provided by linker script. + CFLAGS="$TARGET_CFLAGS -nostdlib ${TARGET_IMG_LDFLAGS_AC}8000 -Wl,--defsym,___main=0x8100" + fi grub_CHECK_BSS_START_SYMBOL grub_CHECK_END_SYMBOL fi @@ -635,6 +635,12 @@ else fi AC_SUBST(TARGET_NO_MODULES) +if test "$TARGET_NO_MODULES" = yes ; then + # Do not convert modules, otherwise linkage may fail (Cygwin only). + # FIXME: Should be checked above before TARGET_OBJ2ELF is set first. + TARGET_OBJ2ELF= +fi + if test x"$enable_grub_emu_usb" = xno ; then grub_emu_usb_excuse="explicitly disabled" fi From 553c01f95813ed7245b4bc3484940843a5e28e30 Mon Sep 17 00:00:00 2001 From: Christian Franke Date: Sat, 24 Apr 2010 23:18:57 +0200 Subject: [PATCH 593/738] * Makefile.in (TARGET_LDFLAGS): Add -static-libgcc. (kernel_img_LDFLAGS): Remove -static-libgcc. --- ChangeLog | 5 +++++ Makefile.in | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 044b396b3..92c8dc53c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-04-24 Christian Franke + + * Makefile.in (TARGET_LDFLAGS): Add -static-libgcc. + (kernel_img_LDFLAGS): Remove -static-libgcc. + 2010-04-24 Christian Franke * configure.ac: Do not CHECK_BSS_START_SYMBOL diff --git a/Makefile.in b/Makefile.in index 29f997213..822a08797 100644 --- a/Makefile.in +++ b/Makefile.in @@ -99,12 +99,12 @@ TARGET_APPLE_CC = @TARGET_APPLE_CC@ OBJCONV = @OBJCONV@ TARGET_CPPFLAGS = @TARGET_CPPFLAGS@ -I$(srcdir)/include -I$(builddir) -I$(builddir)/include \ -Wall -W -TARGET_LDFLAGS = -nostdlib @TARGET_LDFLAGS@ +TARGET_LDFLAGS = -nostdlib -static-libgcc @TARGET_LDFLAGS@ TARGET_IMG_LDSCRIPT = @TARGET_IMG_LDSCRIPT@ TARGET_IMG_LDFLAGS = -nostdlib @TARGET_IMG_LDFLAGS@ TARGET_IMG_CFLAGS = @TARGET_IMG_CFLAGS@ TARGET_OBJ2ELF = @TARGET_OBJ2ELF@ -kernel_img_LDFLAGS = -static-libgcc -lgcc +kernel_img_LDFLAGS = -lgcc EXEEXT = @EXEEXT@ OBJCOPY = @OBJCOPY@ STRIP = @STRIP@ From d31bc9964cd301831055849a21aaa403b297c41b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 25 Apr 2010 01:54:46 +0200 Subject: [PATCH 594/738] migrate kernel.img to elf --- conf/i386-pc.rmk | 5 +- conf/i386-qemu.rmk | 2 +- conf/mips-qemu-mips.rmk | 2 +- conf/mips-yeeloong.rmk | 2 +- conf/sparc64-ieee1275.rmk | 3 +- conf/x86-efi.rmk | 2 +- include/grub/x86_64/efi/boot.h | 0 util/grub-mkrawimage.c | 169 ++++++++++++++++++++++++++++++++- 8 files changed, 172 insertions(+), 13 deletions(-) create mode 100644 include/grub/x86_64/efi/boot.h diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk index a5a1b08ea..f2490ba97 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -5,8 +5,7 @@ GRUB_KERNEL_MACHINE_LINK_ADDR = 0x8200 COMMON_CFLAGS = -mrtd -mregparm=3 # Images. -pkglib_IMAGES = boot.img cdboot.img diskboot.img kernel.img lnxboot.img \ - pxeboot.img +pkglib_IMAGES = boot.img cdboot.img diskboot.img lnxboot.img pxeboot.img # For boot.img. boot_img_SOURCES = boot/i386/pc/boot.S @@ -39,6 +38,7 @@ cdboot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)0x7C00 cdboot_img_FORMAT = binary # For kernel.img. +pkglib_PROGRAMS = kernel.img kernel_img_SOURCES = kern/i386/pc/startup.S \ kern/i386/misc.S \ kern/main.c kern/device.c \ @@ -59,7 +59,6 @@ kernel_img_HEADERS += machine/biosdisk.h machine/vga.h machine/vbe.h \ kernel_img_CFLAGS = $(COMMON_CFLAGS) $(TARGET_IMG_CFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) kernel_img_LDFLAGS += $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_KERNEL_MACHINE_LINK_ADDR) $(COMMON_CFLAGS) -kernel_img_FORMAT = binary # Utilities. bin_UTILITIES = grub-mkimage diff --git a/conf/i386-qemu.rmk b/conf/i386-qemu.rmk index 664bef12a..923231791 100644 --- a/conf/i386-qemu.rmk +++ b/conf/i386-qemu.rmk @@ -19,7 +19,7 @@ grub_mkimage_SOURCES = util/grub-mkrawimage.c util/misc.c \ grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR) util/grub-mkrawimage.c_DEPENDENCIES = Makefile -pkglib_IMAGES += kernel.img +pkglib_PROGRAMS += kernel.img kernel_img_SOURCES = kern/i386/qemu/startup.S \ kern/i386/misc.S \ kern/i386/coreboot/init.c \ diff --git a/conf/mips-qemu-mips.rmk b/conf/mips-qemu-mips.rmk index af5b26bec..2f80ab2e3 100644 --- a/conf/mips-qemu-mips.rmk +++ b/conf/mips-qemu-mips.rmk @@ -5,7 +5,7 @@ COMMON_CFLAGS += -march=mips3 COMMON_ASFLAGS += -march=mips3 include $(srcdir)/conf/mips.mk -pkglib_IMAGES = kernel.img +pkglib_PROGRAMS = kernel.img kernel_img_SOURCES = kern/$(target_cpu)/startup.S \ kern/main.c kern/device.c kern/$(target_cpu)/init.c \ kern/$(target_cpu)/$(target_machine)/init.c \ diff --git a/conf/mips-yeeloong.rmk b/conf/mips-yeeloong.rmk index 6a96ddfaf..5ce8ede9d 100644 --- a/conf/mips-yeeloong.rmk +++ b/conf/mips-yeeloong.rmk @@ -8,7 +8,7 @@ kernel_img_HEADERS += pci.h bitmap.h video.h gfxterm.h font.h bitmap_scale.h buf include $(srcdir)/conf/mips.mk -pkglib_IMAGES = kernel.img +pkglib_PROGRAMS = kernel.img kernel_img_SOURCES = kern/$(target_cpu)/startup.S \ kern/main.c kern/device.c kern/$(target_cpu)/init.c \ kern/$(target_cpu)/$(target_machine)/init.c \ diff --git a/conf/sparc64-ieee1275.rmk b/conf/sparc64-ieee1275.rmk index f0c9b0db7..8e96599aa 100644 --- a/conf/sparc64-ieee1275.rmk +++ b/conf/sparc64-ieee1275.rmk @@ -5,7 +5,8 @@ COMMON_CFLAGS = -mno-app-regs COMMON_LDFLAGS = -melf64_sparc -mno-relax # Images. -pkglib_IMAGES = boot.img diskboot.img kernel.img +pkglib_IMAGES = boot.img diskboot.img +pkglib_PROGRAMS = kernel.img # For boot.img. boot_img_SOURCES = boot/sparc64/ieee1275/boot.S diff --git a/conf/x86-efi.rmk b/conf/x86-efi.rmk index 46957d933..bab561cc4 100644 --- a/conf/x86-efi.rmk +++ b/conf/x86-efi.rmk @@ -4,7 +4,7 @@ bin_UTILITIES = grub-mkimage # For grub-mkimage. -grub_mkimage_SOURCES = gnulib/progname.c util/i386/efi/grub-mkimage.c \ +grub_mkimage_SOURCES = gnulib/progname.c util/grub-mkrawimage.c \ util/misc.c util/resolve.c util/i386/efi/grub-mkimage.c_DEPENDENCIES = Makefile diff --git a/include/grub/x86_64/efi/boot.h b/include/grub/x86_64/efi/boot.h new file mode 100644 index 000000000..e69de29bb diff --git a/util/grub-mkrawimage.c b/util/grub-mkrawimage.c index 20a344d04..dace903a9 100644 --- a/util/grub-mkrawimage.c +++ b/util/grub-mkrawimage.c @@ -36,6 +36,7 @@ #include #include #include +#include #define _GNU_SOURCE 1 #include @@ -44,6 +45,8 @@ #define ALIGN_ADDR(x) (ALIGN_UP((x), GRUB_TARGET_SIZEOF_VOID_P)) +#define SECTION_ALIGN 1 + #ifdef ENABLE_LZMA #include @@ -97,6 +100,162 @@ compress_kernel (char *kernel_img, size_t kernel_size, #endif /* No lzma compression */ +/* Determine if this section is a text section. Return false if this + section is not allocated. */ +static int +is_text_section (Elf_Shdr *s) +{ + if (grub_target_to_host32 (s->sh_type) != SHT_PROGBITS) + return 0; + return ((grub_target_to_host32 (s->sh_flags) & (SHF_EXECINSTR | SHF_ALLOC)) + == (SHF_EXECINSTR | SHF_ALLOC)); +} + +/* Determine if this section is a data section. This assumes that + BSS is also a data section, since the converter initializes BSS + when producing PE32 to avoid a bug in EFI implementations. */ +static int +is_data_section (Elf_Shdr *s) +{ + if (grub_target_to_host32 (s->sh_type) != SHT_PROGBITS) + return 0; + return ((grub_target_to_host32 (s->sh_flags) & (SHF_EXECINSTR | SHF_ALLOC)) + == SHF_ALLOC); +} + +/* Locate section addresses by merging code sections and data sections + into .text and .data, respectively. Return the array of section + addresses. */ +static Elf_Addr * +locate_sections (Elf_Shdr *sections, Elf_Half section_entsize, + Elf_Half num_sections, const char *strtab, + grub_size_t *exec_size, grub_size_t *kernel_sz) +{ + int i; + Elf_Addr current_address; + Elf_Addr *section_addresses; + Elf_Shdr *s; + + section_addresses = xmalloc (sizeof (*section_addresses) * num_sections); + memset (section_addresses, 0, sizeof (*section_addresses) * num_sections); + + current_address = 0; + + /* .text */ + for (i = 0, s = sections; + i < num_sections; + i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + if (is_text_section (s)) + { + Elf_Word align = grub_host_to_target32 (s->sh_addralign); + const char *name = strtab + grub_host_to_target32 (s->sh_name); + + if (align) + current_address = ALIGN_UP (current_address, align); + + grub_util_info ("locating the section %s at 0x%x", + name, current_address); + section_addresses[i] = current_address; + current_address += grub_host_to_target32 (s->sh_size); + } + + current_address = ALIGN_UP (current_address, SECTION_ALIGN); + *exec_size = current_address; + + /* .data */ + for (i = 0, s = sections; + i < num_sections; + i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + if (is_data_section (s)) + { + Elf_Word align = grub_host_to_target32 (s->sh_addralign); + const char *name = strtab + grub_host_to_target32 (s->sh_name); + + if (align) + current_address = ALIGN_UP (current_address, align); + + grub_util_info ("locating the section %s at 0x%x", + name, current_address); + section_addresses[i] = current_address; + current_address += grub_host_to_target32 (s->sh_size); + } + + current_address = ALIGN_UP (current_address, SECTION_ALIGN); + *kernel_sz = current_address; + return section_addresses; +} + +/* Return if the ELF header is valid. */ +static int +check_elf_header (Elf_Ehdr *e, size_t size) +{ + if (size < sizeof (*e) + || e->e_ident[EI_MAG0] != ELFMAG0 + || e->e_ident[EI_MAG1] != ELFMAG1 + || e->e_ident[EI_MAG2] != ELFMAG2 + || e->e_ident[EI_MAG3] != ELFMAG3 + || e->e_ident[EI_VERSION] != EV_CURRENT + || e->e_version != grub_host_to_target32 (EV_CURRENT)) + return 0; + + return 1; +} + +static char * +load_image (const char *kernel_path, grub_size_t *exec_size, + grub_size_t *kernel_sz, grub_size_t total_module_size) +{ + char *kernel_img, *out_img; + const char *strtab; + Elf_Ehdr *e; + Elf_Shdr *sections; + Elf_Addr *section_addresses; + int i; + Elf_Shdr *s; + Elf_Half num_sections; + Elf_Off section_offset; + Elf_Half section_entsize; + grub_size_t kernel_size; + + kernel_size = grub_util_get_image_size (kernel_path); + kernel_img = xmalloc (kernel_size); + grub_util_load_image (kernel_path, kernel_img); + + e = (Elf_Ehdr *) kernel_img; + if (! check_elf_header (e, kernel_size)) + grub_util_error ("invalid ELF header"); + + section_offset = grub_target_to_host32 (e->e_shoff); + section_entsize = grub_target_to_host16 (e->e_shentsize); + num_sections = grub_target_to_host16 (e->e_shnum); + + if (kernel_size < section_offset + section_entsize * num_sections) + grub_util_error ("invalid ELF format"); + + sections = (Elf_Shdr *) (kernel_img + section_offset); + + /* Relocate sections then symbols in the virtual address space. */ + s = (Elf_Shdr *) ((char *) sections + + grub_host_to_target16 (e->e_shstrndx) * section_entsize); + strtab = (char *) e + grub_host_to_target32 (s->sh_offset); + + section_addresses = locate_sections (sections, section_entsize, + num_sections, strtab, + exec_size, kernel_sz); + out_img = xmalloc (*kernel_sz + total_module_size); + + for (i = 0, s = sections; + i < num_sections; + i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + if (is_data_section (s) || is_text_section (s)) + memcpy (out_img + section_addresses[i], + kernel_img + grub_host_to_target32 (s->sh_offset), + grub_host_to_target32 (s->sh_size)); + free (kernel_img); + + return out_img; +} + static void generate_image (const char *dir, char *prefix, FILE *out, char *mods[], char *memdisk_path, char *font_path, char *config_path, @@ -109,17 +268,15 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], ) { char *kernel_img, *core_img; - size_t kernel_size, total_module_size, core_size; + size_t kernel_size, total_module_size, core_size, exec_size; size_t memdisk_size = 0, font_size = 0, config_size = 0, config_size_pure = 0; char *kernel_path; size_t offset; struct grub_util_path_list *path_list, *p, *next; struct grub_module_info *modinfo; - path_list = grub_util_resolve_dependencies (dir, "moddep.lst", mods); kernel_path = grub_util_get_path (dir, "kernel.img"); - kernel_size = grub_util_get_image_size (kernel_path); total_module_size = sizeof (struct grub_module_info); @@ -150,8 +307,8 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], grub_util_info ("the total module size is 0x%x", total_module_size); - kernel_img = xmalloc (kernel_size + total_module_size); - grub_util_load_image (kernel_path, kernel_img); + kernel_img = load_image (kernel_path, &exec_size, &kernel_size, + total_module_size); if (GRUB_KERNEL_MACHINE_PREFIX + strlen (prefix) + 1 > GRUB_KERNEL_MACHINE_DATA_END) grub_util_error (_("prefix is too long")); @@ -237,8 +394,10 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], *((grub_uint32_t *) (core_img + GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE)) = grub_host_to_target32 (total_module_size); #endif +#ifdef GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE *((grub_uint32_t *) (core_img + GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE)) = grub_host_to_target32 (kernel_size); +#endif #ifdef GRUB_KERNEL_MACHINE_COMPRESSED_SIZE *((grub_uint32_t *) (core_img + GRUB_KERNEL_MACHINE_COMPRESSED_SIZE)) = grub_host_to_target32 (core_size - GRUB_KERNEL_MACHINE_RAW_SIZE); From e310b81f6cb8c0ad893e08282a49ef42f69d5c9f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 25 Apr 2010 19:38:12 +0200 Subject: [PATCH 595/738] util/grub-mkrawimage.c working on EFI --- util/grub-mkrawimage.c | 690 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 680 insertions(+), 10 deletions(-) diff --git a/util/grub-mkrawimage.c b/util/grub-mkrawimage.c index dace903a9..30608a932 100644 --- a/util/grub-mkrawimage.c +++ b/util/grub-mkrawimage.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -45,7 +46,19 @@ #define ALIGN_ADDR(x) (ALIGN_UP((x), GRUB_TARGET_SIZEOF_VOID_P)) +#ifdef GRUB_MACHINE_EFI +#define SECTION_ALIGN GRUB_PE32_SECTION_ALIGNMENT +#define VADDR_OFFSET ALIGN_UP (sizeof (struct grub_pe32_header) + 5 * sizeof (struct grub_pe32_section_table), SECTION_ALIGN) +#else #define SECTION_ALIGN 1 +#define VADDR_OFFSET 0 +#endif + +#if GRUB_TARGET_WORDSIZE == 32 +# define grub_target_to_host(val) grub_target_to_host32(val) +#elif GRUB_TARGET_WORDSIZE == 64 +# define grub_target_to_host(val) grub_target_to_host64(val) +#endif #ifdef ENABLE_LZMA #include @@ -100,13 +113,436 @@ compress_kernel (char *kernel_img, size_t kernel_size, #endif /* No lzma compression */ +#ifdef GRUB_MACHINE_EFI + +/* Relocate symbols; note that this function overwrites the symbol table. + Return the address of a start symbol. */ +static Elf_Addr +relocate_symbols (Elf_Ehdr *e, Elf_Shdr *sections, + Elf_Shdr *symtab_section, Elf_Addr *section_addresses, + Elf_Half section_entsize, Elf_Half num_sections) +{ + Elf_Word symtab_size, sym_size, num_syms; + Elf_Off symtab_offset; + Elf_Addr start_address = 0; + Elf_Sym *sym; + Elf_Word i; + Elf_Shdr *strtab_section; + const char *strtab; + + strtab_section + = (Elf_Shdr *) ((char *) sections + + (grub_target_to_host32 (symtab_section->sh_link) + * section_entsize)); + strtab = (char *) e + grub_target_to_host32 (strtab_section->sh_offset); + + symtab_size = grub_target_to_host32 (symtab_section->sh_size); + sym_size = grub_target_to_host32 (symtab_section->sh_entsize); + symtab_offset = grub_target_to_host32 (symtab_section->sh_offset); + num_syms = symtab_size / sym_size; + + for (i = 0, sym = (Elf_Sym *) ((char *) e + symtab_offset); + i < num_syms; + i++, sym = (Elf_Sym *) ((char *) sym + sym_size)) + { + Elf_Section index; + const char *name; + + name = strtab + grub_target_to_host32 (sym->st_name); + + index = grub_target_to_host16 (sym->st_shndx); + if (index == STN_ABS) + { + continue; + } + else if ((index == STN_UNDEF)) + { + if (sym->st_name) + grub_util_error ("undefined symbol %s", name); + else + continue; + } + else if (index >= num_sections) + grub_util_error ("section %d does not exist", index); + + sym->st_value = (grub_target_to_host32 (sym->st_value) + + section_addresses[index]); + grub_util_info ("locating %s at 0x%x", name, sym->st_value); + + if (! start_address) + if (strcmp (name, "_start") == 0 || strcmp (name, "start") == 0) + start_address = sym->st_value; + } + + return start_address; +} + +/* Return the address of a symbol at the index I in the section S. */ +static Elf_Addr +get_symbol_address (Elf_Ehdr *e, Elf_Shdr *s, Elf_Word i) +{ + Elf_Sym *sym; + + sym = (Elf_Sym *) ((char *) e + + grub_target_to_host32 (s->sh_offset) + + i * grub_target_to_host32 (s->sh_entsize)); + return sym->st_value; +} + +/* Return the address of a modified value. */ +static Elf_Addr * +get_target_address (Elf_Ehdr *e, Elf_Shdr *s, Elf_Addr offset) +{ + return (Elf_Addr *) ((char *) e + grub_target_to_host32 (s->sh_offset) + offset); +} + +/* Deal with relocation information. This function relocates addresses + within the virtual address space starting from 0. So only relative + addresses can be fully resolved. Absolute addresses must be relocated + again by a PE32 relocator when loaded. */ +static void +relocate_addresses (Elf_Ehdr *e, Elf_Shdr *sections, + Elf_Addr *section_addresses, + Elf_Half section_entsize, Elf_Half num_sections, + const char *strtab) +{ + Elf_Half i; + Elf_Shdr *s; + + for (i = 0, s = sections; + i < num_sections; + i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + if ((s->sh_type == grub_host_to_target32 (SHT_REL)) || + (s->sh_type == grub_host_to_target32 (SHT_RELA))) + { + Elf_Rela *r; + Elf_Word rtab_size, r_size, num_rs; + Elf_Off rtab_offset; + Elf_Shdr *symtab_section; + Elf_Word target_section_index; + Elf_Addr target_section_addr; + Elf_Shdr *target_section; + Elf_Word j; + + symtab_section = (Elf_Shdr *) ((char *) sections + + (grub_target_to_host32 (s->sh_link) + * section_entsize)); + target_section_index = grub_target_to_host32 (s->sh_info); + target_section_addr = section_addresses[target_section_index]; + target_section = (Elf_Shdr *) ((char *) sections + + (target_section_index + * section_entsize)); + + grub_util_info ("dealing with the relocation section %s for %s", + strtab + grub_target_to_host32 (s->sh_name), + strtab + grub_target_to_host32 (target_section->sh_name)); + + rtab_size = grub_target_to_host32 (s->sh_size); + r_size = grub_target_to_host32 (s->sh_entsize); + rtab_offset = grub_target_to_host32 (s->sh_offset); + num_rs = rtab_size / r_size; + + for (j = 0, r = (Elf_Rela *) ((char *) e + rtab_offset); + j < num_rs; + j++, r = (Elf_Rela *) ((char *) r + r_size)) + { + Elf_Addr info; + Elf_Addr offset; + Elf_Addr sym_addr; + Elf_Addr *target; + Elf_Addr addend; + + offset = grub_target_to_host (r->r_offset); + target = get_target_address (e, target_section, offset); + info = grub_target_to_host (r->r_info); + sym_addr = get_symbol_address (e, symtab_section, + ELF_R_SYM (info)); + + addend = (s->sh_type == grub_target_to_host32 (SHT_RELA)) ? + r->r_addend : 0; + + switch (ELF_R_TYPE (info)) + { +#if GRUB_TARGET_SIZEOF_VOID_P == 4 + case R_386_NONE: + break; + + case R_386_32: + /* This is absolute. */ + *target = grub_host_to_target32 (grub_target_to_host32 (*target) + + addend + sym_addr); + grub_util_info ("relocating an R_386_32 entry to 0x%x at the offset 0x%x", + *target, offset); + break; + + case R_386_PC32: + /* This is relative. */ + *target = grub_host_to_target32 (grub_target_to_host32 (*target) + + addend + sym_addr + - target_section_addr - offset + - VADDR_OFFSET); + grub_util_info ("relocating an R_386_PC32 entry to 0x%x at the offset 0x%x", + *target, offset); + break; + +#else + + case R_X86_64_NONE: + break; + + case R_X86_64_64: + *target = grub_host_to_target64 (grub_target_to_host64 (*target) + + addend + sym_addr); + grub_util_info ("relocating an R_X86_64_64 entry to 0x%llx at the offset 0x%llx", + *target, offset); + break; + + case R_X86_64_PC32: + { + grub_uint32_t *t32 = (grub_uint32_t *) target; + *t32 = grub_host_to_target64 (grub_target_to_host32 (*t32) + + addend + sym_addr + - target_section_addr - offset + - VADDR_OFFSET); + grub_util_info ("relocating an R_X86_64_PC32 entry to 0x%x at the offset 0x%llx", + *t32, offset); + break; + } + + case R_X86_64_32: + case R_X86_64_32S: + { + grub_uint32_t *t32 = (grub_uint32_t *) target; + *t32 = grub_host_to_target64 (grub_target_to_host32 (*t32) + + addend + sym_addr); + grub_util_info ("relocating an R_X86_64_32(S) entry to 0x%x at the offset 0x%llx", + *t32, offset); + break; + } + +#endif + default: + grub_util_error ("unknown relocation type %d", + ELF_R_TYPE (info)); + break; + } + } + } +} + +struct fixup_block_list +{ + struct fixup_block_list *next; + int state; + struct grub_pe32_fixup_block b; +}; + +/* Add a PE32's fixup entry for a relocation. Return the resulting address + after having written to the file OUT. */ +Elf_Addr +add_fixup_entry (struct fixup_block_list **cblock, grub_uint16_t type, + Elf_Addr addr, int flush, Elf_Addr current_address) +{ + struct grub_pe32_fixup_block *b; + + b = &((*cblock)->b); + + /* First, check if it is necessary to write out the current block. */ + if ((*cblock)->state) + { + if (flush || addr < b->page_rva || b->page_rva + 0x1000 <= addr) + { + grub_uint32_t size; + + if (flush) + { + /* Add as much padding as necessary to align the address + with a section boundary. */ + Elf_Addr next_address; + unsigned padding_size; + size_t index; + + next_address = current_address + b->block_size; + padding_size = ((ALIGN_UP (next_address, SECTION_ALIGN) + - next_address) + >> 1); + index = ((b->block_size - sizeof (*b)) >> 1); + grub_util_info ("adding %d padding fixup entries", padding_size); + while (padding_size--) + { + b->entries[index++] = 0; + b->block_size += 2; + } + } + else if (b->block_size & (8 - 1)) + { + /* If not aligned with a 32-bit boundary, add + a padding entry. */ + size_t index; + + grub_util_info ("adding a padding fixup entry"); + index = ((b->block_size - sizeof (*b)) >> 1); + b->entries[index] = 0; + b->block_size += 2; + } + + /* Flush it. */ + grub_util_info ("writing %d bytes of a fixup block starting at 0x%x", + b->block_size, b->page_rva); + size = b->block_size; + current_address += size; + b->page_rva = grub_host_to_target32 (b->page_rva); + b->block_size = grub_host_to_target32 (b->block_size); + (*cblock)->next = xmalloc (sizeof (**cblock) + 2 * 0x1000); + memset ((*cblock)->next, 0, sizeof (**cblock) + 2 * 0x1000); + *cblock = (*cblock)->next; + } + } + + b = &((*cblock)->b); + + if (! flush) + { + grub_uint16_t entry; + size_t index; + + /* If not allocated yet, allocate a block with enough entries. */ + if (! (*cblock)->state) + { + (*cblock)->state = 1; + + /* The spec does not mention the requirement of a Page RVA. + Here, align the address with a 4K boundary for safety. */ + b->page_rva = (addr & ~(0x1000 - 1)); + b->block_size = sizeof (*b); + } + + /* Sanity check. */ + if (b->block_size >= sizeof (*b) + 2 * 0x1000) + grub_util_error ("too many fixup entries"); + + /* Add a new entry. */ + index = ((b->block_size - sizeof (*b)) >> 1); + entry = GRUB_PE32_FIXUP_ENTRY (type, addr - b->page_rva); + b->entries[index] = grub_host_to_target16 (entry); + b->block_size += 2; + } + + return current_address; +} + +/* Make a .reloc section. */ +static Elf_Addr +make_reloc_section (Elf_Ehdr *e, void **out, + Elf_Addr *section_addresses, Elf_Shdr *sections, + Elf_Half section_entsize, Elf_Half num_sections, + const char *strtab) +{ + Elf_Half i; + Elf_Shdr *s; + struct fixup_block_list *lst, *lst0; + Elf_Addr current_address = 0; + + lst = lst0 = xmalloc (sizeof (*lst) + 2 * 0x1000); + memset (lst, 0, sizeof (*lst) + 2 * 0x1000); + + for (i = 0, s = sections; + i < num_sections; + i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + if ((s->sh_type == grub_cpu_to_le32 (SHT_REL)) || + (s->sh_type == grub_cpu_to_le32 (SHT_RELA))) + { + Elf_Rel *r; + Elf_Word rtab_size, r_size, num_rs; + Elf_Off rtab_offset; + Elf_Addr section_address; + Elf_Word j; + + grub_util_info ("translating the relocation section %s", + strtab + grub_le_to_cpu32 (s->sh_name)); + + rtab_size = grub_le_to_cpu32 (s->sh_size); + r_size = grub_le_to_cpu32 (s->sh_entsize); + rtab_offset = grub_le_to_cpu32 (s->sh_offset); + num_rs = rtab_size / r_size; + + section_address = section_addresses[grub_le_to_cpu32 (s->sh_info)]; + + for (j = 0, r = (Elf_Rel *) ((char *) e + rtab_offset); + j < num_rs; + j++, r = (Elf_Rel *) ((char *) r + r_size)) + { + Elf_Addr info; + Elf_Addr offset; + + offset = grub_le_to_cpu32 (r->r_offset); + info = grub_le_to_cpu32 (r->r_info); + + /* Necessary to relocate only absolute addresses. */ +#if GRUB_TARGET_SIZEOF_VOID_P == 4 + if (ELF_R_TYPE (info) == R_386_32) + { + Elf_Addr addr; + + addr = section_address + offset; + grub_util_info ("adding a relocation entry for 0x%x", addr); + current_address = add_fixup_entry (&lst, + GRUB_PE32_REL_BASED_HIGHLOW, + addr, 0, current_address); + } +#else + if ((ELF_R_TYPE (info) == R_X86_64_32) || + (ELF_R_TYPE (info) == R_X86_64_32S)) + { + grub_util_error ("can\'t add fixup entry for R_X86_64_32(S)"); + } + else if (ELF_R_TYPE (info) == R_X86_64_64) + { + Elf_Addr addr; + + addr = section_address + offset; + grub_util_info ("adding a relocation entry for 0x%llx", addr); + current_address = add_fixup_entry (&lst, + GRUB_PE32_REL_BASED_DIR64, + addr, + 0, current_address); + } +#endif + } + } + + current_address = add_fixup_entry (&lst, 0, 0, 1, current_address); + + { + grub_uint8_t *ptr; + ptr = *out = xmalloc (current_address); + for (lst = lst0; lst; lst = lst->next) + if (lst->state) + { + memcpy (ptr, &lst->b, grub_target_to_host32 (lst->b.block_size)); + ptr += grub_target_to_host32 (lst->b.block_size); + } + if (current_address + *out != ptr) + { + grub_util_error ("Bug detected %d != %d\n", ptr - (grub_uint8_t *) *out, + current_address); + } + } + + return current_address; +} + +#endif + /* Determine if this section is a text section. Return false if this section is not allocated. */ static int is_text_section (Elf_Shdr *s) { +#ifndef GRUB_MACHINE_EFI if (grub_target_to_host32 (s->sh_type) != SHT_PROGBITS) return 0; +#endif return ((grub_target_to_host32 (s->sh_flags) & (SHF_EXECINSTR | SHF_ALLOC)) == (SHF_EXECINSTR | SHF_ALLOC)); } @@ -117,8 +553,10 @@ is_text_section (Elf_Shdr *s) static int is_data_section (Elf_Shdr *s) { +#ifndef GRUB_MACHINE_EFI if (grub_target_to_host32 (s->sh_type) != SHT_PROGBITS) return 0; +#endif return ((grub_target_to_host32 (s->sh_flags) & (SHF_EXECINSTR | SHF_ALLOC)) == SHF_ALLOC); } @@ -151,7 +589,8 @@ locate_sections (Elf_Shdr *sections, Elf_Half section_entsize, const char *name = strtab + grub_host_to_target32 (s->sh_name); if (align) - current_address = ALIGN_UP (current_address, align); + current_address = ALIGN_UP (current_address + VADDR_OFFSET, align) + - VADDR_OFFSET; grub_util_info ("locating the section %s at 0x%x", name, current_address); @@ -159,7 +598,8 @@ locate_sections (Elf_Shdr *sections, Elf_Half section_entsize, current_address += grub_host_to_target32 (s->sh_size); } - current_address = ALIGN_UP (current_address, SECTION_ALIGN); + current_address = ALIGN_UP (current_address + VADDR_OFFSET, SECTION_ALIGN) + - VADDR_OFFSET; *exec_size = current_address; /* .data */ @@ -172,7 +612,8 @@ locate_sections (Elf_Shdr *sections, Elf_Half section_entsize, const char *name = strtab + grub_host_to_target32 (s->sh_name); if (align) - current_address = ALIGN_UP (current_address, align); + current_address = ALIGN_UP (current_address + VADDR_OFFSET, align) + - VADDR_OFFSET; grub_util_info ("locating the section %s at 0x%x", name, current_address); @@ -180,7 +621,8 @@ locate_sections (Elf_Shdr *sections, Elf_Half section_entsize, current_address += grub_host_to_target32 (s->sh_size); } - current_address = ALIGN_UP (current_address, SECTION_ALIGN); + current_address = ALIGN_UP (current_address + VADDR_OFFSET, SECTION_ALIGN) + - VADDR_OFFSET; *kernel_sz = current_address; return section_addresses; } @@ -203,19 +645,25 @@ check_elf_header (Elf_Ehdr *e, size_t size) static char * load_image (const char *kernel_path, grub_size_t *exec_size, - grub_size_t *kernel_sz, grub_size_t total_module_size) + grub_size_t *kernel_sz, grub_size_t *bss_size, + grub_size_t total_module_size, Elf_Addr *start, + void **reloc_section, grub_size_t *reloc_size) { char *kernel_img, *out_img; const char *strtab; Elf_Ehdr *e; Elf_Shdr *sections; Elf_Addr *section_addresses; + Elf_Addr *section_vaddresses; int i; Elf_Shdr *s; Elf_Half num_sections; Elf_Off section_offset; Elf_Half section_entsize; grub_size_t kernel_size; + Elf_Shdr *symtab_section; + + *start = 0; kernel_size = grub_util_get_image_size (kernel_path); kernel_img = xmalloc (kernel_size); @@ -242,15 +690,93 @@ load_image (const char *kernel_path, grub_size_t *exec_size, section_addresses = locate_sections (sections, section_entsize, num_sections, strtab, exec_size, kernel_sz); + +#ifdef GRUB_MACHINE_EFI + { + section_vaddresses = xmalloc (sizeof (*section_addresses) * num_sections); + + for (i = 0; i < num_sections; i++) + section_vaddresses[i] = section_addresses[i] + VADDR_OFFSET; + +#if 0 + { + Elf_Addr current_address = *kernel_sz; + + for (i = 0, s = sections; + i < num_sections; + i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + if (grub_target_to_host32 (s->sh_type) == SHT_NOBITS) + { + Elf_Word align = grub_host_to_target32 (s->sh_addralign); + const char *name = strtab + grub_host_to_target32 (s->sh_name); + + if (align) + current_address = ALIGN_UP (current_address + VADDR_OFFSET, align) + - VADDR_OFFSET; + + grub_util_info ("locating the section %s at 0x%x", + name, current_address); + section_vaddresses[i] = current_address + VADDR_OFFSET; + current_address += grub_host_to_target32 (s->sh_size); + } + current_address = ALIGN_UP (current_address + VADDR_OFFSET, SECTION_ALIGN) + - VADDR_OFFSET; + *bss_size = current_address - *kernel_sz; + } +#else + *bss_size = 0; +#endif + + symtab_section = NULL; + for (i = 0, s = sections; + i < num_sections; + i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + if (s->sh_type == grub_host_to_target32 (SHT_SYMTAB)) + { + symtab_section = s; + break; + } + + if (! symtab_section) + grub_util_error ("no symbol table"); + + *start = relocate_symbols (e, sections, symtab_section, + section_vaddresses, section_entsize, + num_sections); + if (*start == 0) + grub_util_error ("start symbol is not defined"); + + /* Resolve addresses in the virtual address space. */ + relocate_addresses (e, sections, section_addresses, section_entsize, + num_sections, strtab); + + *reloc_size = make_reloc_section (e, reloc_section, + section_vaddresses, sections, + section_entsize, num_sections, + strtab); + + } +#else + *bss_size = 0; + *reloc_size = 0; + *reloc_section = NULL; +#endif + out_img = xmalloc (*kernel_sz + total_module_size); for (i = 0, s = sections; i < num_sections; i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) if (is_data_section (s) || is_text_section (s)) - memcpy (out_img + section_addresses[i], - kernel_img + grub_host_to_target32 (s->sh_offset), - grub_host_to_target32 (s->sh_size)); + { + if (grub_target_to_host32 (s->sh_type) == SHT_NOBITS) + memset (out_img + section_addresses[i], 0, + grub_host_to_target32 (s->sh_size)); + else + memcpy (out_img + section_addresses[i], + kernel_img + grub_host_to_target32 (s->sh_offset), + grub_host_to_target32 (s->sh_size)); + } free (kernel_img); return out_img; @@ -274,6 +800,10 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], size_t offset; struct grub_util_path_list *path_list, *p, *next; struct grub_module_info *modinfo; + grub_size_t bss_size; + Elf_Addr start_address; + void *rel_section; + grub_size_t reloc_size; path_list = grub_util_resolve_dependencies (dir, "moddep.lst", mods); kernel_path = grub_util_get_path (dir, "kernel.img"); @@ -307,8 +837,9 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], grub_util_info ("the total module size is 0x%x", total_module_size); - kernel_img = load_image (kernel_path, &exec_size, &kernel_size, - total_module_size); + kernel_img = load_image (kernel_path, &exec_size, &kernel_size, &bss_size, + total_module_size, &start_address, &rel_section, + &reloc_size); if (GRUB_KERNEL_MACHINE_PREFIX + strlen (prefix) + 1 > GRUB_KERNEL_MACHINE_DATA_END) grub_util_error (_("prefix is too long")); @@ -456,6 +987,145 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], free (boot_img); free (boot_path); } +#elif defined(GRUB_MACHINE_EFI) + { + void *pe_img; + size_t pe_size; + struct grub_pe32_header *header; + struct grub_pe32_coff_header *c; + struct grub_pe32_optional_header *o; + struct grub_pe32_section_table *text_section, *data_section; + struct grub_pe32_section_table *mods_section, *reloc_section; + static const grub_uint8_t stub[] = GRUB_PE32_MSDOS_STUB; + int header_size = ALIGN_UP (sizeof (struct grub_pe32_header) + + 5 * sizeof (struct grub_pe32_section_table), + SECTION_ALIGN); + int reloc_addr = ALIGN_UP (header_size + core_size, SECTION_ALIGN); + + pe_size = ALIGN_UP (reloc_addr + reloc_size, SECTION_ALIGN); + pe_img = xmalloc (reloc_addr + reloc_size); + memset (pe_img, 0, header_size); + memcpy (pe_img + header_size, core_img, core_size); + memcpy (pe_img + reloc_addr, rel_section, reloc_size); + header = pe_img; + + /* The magic. */ + memcpy (header->msdos_stub, stub, sizeof (header->msdos_stub)); + memcpy (header->signature, "PE\0\0", sizeof (header->signature)); + + /* The COFF file header. */ + c = &header->coff_header; +#if GRUB_TARGET_SIZEOF_VOID_P == 4 + c->machine = grub_host_to_target16 (GRUB_PE32_MACHINE_I386); +#else + c->machine = grub_host_to_target16 (GRUB_PE32_MACHINE_X86_64); +#endif + + c->num_sections = grub_host_to_target16 (4); + c->time = grub_host_to_target32 (time (0)); + c->optional_header_size = grub_host_to_target16 (sizeof (header->optional_header)); + c->characteristics = grub_host_to_target16 (GRUB_PE32_EXECUTABLE_IMAGE + | GRUB_PE32_LINE_NUMS_STRIPPED +#if GRUB_TARGET_SIZEOF_VOID_P == 4 + | GRUB_PE32_32BIT_MACHINE +#endif + | GRUB_PE32_LOCAL_SYMS_STRIPPED + | GRUB_PE32_DEBUG_STRIPPED); + + /* The PE Optional header. */ + o = &header->optional_header; + o->magic = grub_host_to_target16 (GRUB_PE32_PE32_MAGIC); + o->code_size = grub_host_to_target32 (exec_size); + o->data_size = grub_cpu_to_le32 (reloc_addr - exec_size); + o->bss_size = grub_cpu_to_le32 (bss_size); + o->entry_addr = grub_cpu_to_le32 (start_address); + o->code_base = grub_cpu_to_le32 (header_size); +#if GRUB_TARGET_SIZEOF_VOID_P == 4 + o->data_base = grub_host_to_target32 (header_size + exec_size); +#endif + o->image_base = 0; + o->section_alignment = grub_host_to_target32 (SECTION_ALIGN); + o->file_alignment = grub_host_to_target32 (SECTION_ALIGN); + o->image_size = grub_host_to_target32 (pe_size); + o->header_size = grub_host_to_target32 (header_size); + o->subsystem = grub_host_to_target16 (GRUB_PE32_SUBSYSTEM_EFI_APPLICATION); + + /* Do these really matter? */ + o->stack_reserve_size = grub_host_to_target32 (0x10000); + o->stack_commit_size = grub_host_to_target32 (0x10000); + o->heap_reserve_size = grub_host_to_target32 (0x10000); + o->heap_commit_size = grub_host_to_target32 (0x10000); + + o->num_data_directories = grub_host_to_target32 (GRUB_PE32_NUM_DATA_DIRECTORIES); + + o->base_relocation_table.rva = grub_host_to_target32 (reloc_addr); + o->base_relocation_table.size = grub_host_to_target32 (reloc_size); + + /* The sections. */ + text_section = (struct grub_pe32_section_table *) (header + 1); + strcpy (text_section->name, ".text"); + text_section->virtual_size = grub_cpu_to_le32 (exec_size); + text_section->virtual_address = grub_cpu_to_le32 (header_size); + text_section->raw_data_size = grub_cpu_to_le32 (exec_size); + text_section->raw_data_offset = grub_cpu_to_le32 (header_size); + text_section->characteristics = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_CODE + | GRUB_PE32_SCN_MEM_EXECUTE + | GRUB_PE32_SCN_MEM_READ + | GRUB_PE32_SCN_ALIGN_64BYTES); + + data_section = text_section + 1; + strcpy (data_section->name, ".data"); + data_section->virtual_size = grub_cpu_to_le32 (kernel_size - exec_size); + data_section->virtual_address = grub_cpu_to_le32 (header_size + exec_size); + data_section->raw_data_size = grub_cpu_to_le32 (kernel_size - exec_size); + data_section->raw_data_offset = grub_cpu_to_le32 (header_size + exec_size); + data_section->characteristics + = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_INITIALIZED_DATA + | GRUB_PE32_SCN_MEM_READ + | GRUB_PE32_SCN_MEM_WRITE + | GRUB_PE32_SCN_ALIGN_64BYTES); + +#if 0 + bss_section = data_section + 1; + strcpy (bss_section->name, ".bss"); + bss_section->virtual_size = grub_cpu_to_le32 (bss_size); + bss_section->virtual_address = grub_cpu_to_le32 (header_size + kernel_size); + bss_section->raw_data_size = 0; + bss_section->raw_data_offset = 0; + bss_section->characteristics + = grub_cpu_to_le32 (GRUB_PE32_SCN_MEM_READ + | GRUB_PE32_SCN_MEM_WRITE + | GRUB_PE32_SCN_ALIGN_64BYTES + | GRUB_PE32_SCN_CNT_INITIALIZED_DATA + | 0x80); +#endif + + mods_section = data_section + 1; + strcpy (mods_section->name, "mods"); + mods_section->virtual_size = grub_cpu_to_le32 (reloc_addr - kernel_size - header_size); + mods_section->virtual_address = grub_cpu_to_le32 (header_size + kernel_size + bss_size); + mods_section->raw_data_size = grub_cpu_to_le32 (reloc_addr - kernel_size - header_size); + mods_section->raw_data_offset = grub_cpu_to_le32 (header_size + kernel_size); + mods_section->characteristics + = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_INITIALIZED_DATA + | GRUB_PE32_SCN_MEM_READ + | GRUB_PE32_SCN_MEM_WRITE + | GRUB_PE32_SCN_ALIGN_64BYTES); + + reloc_section = mods_section + 1; + strcpy (reloc_section->name, ".reloc"); + reloc_section->virtual_size = grub_cpu_to_le32 (reloc_size); + reloc_section->virtual_address = grub_cpu_to_le32 (reloc_addr + bss_size); + reloc_section->raw_data_size = grub_cpu_to_le32 (reloc_size); + reloc_section->raw_data_offset = grub_cpu_to_le32 (reloc_addr); + reloc_section->characteristics + = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_INITIALIZED_DATA + | GRUB_PE32_SCN_MEM_DISCARDABLE + | GRUB_PE32_SCN_MEM_READ); + free (core_img); + core_img = pe_img; + core_size = pe_size; + } #elif defined(GRUB_MACHINE_QEMU) { char *rom_img; From 287c2f24265a5e1ca5c4fe5a6322e9f54b4bb996 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 25 Apr 2010 19:39:22 +0200 Subject: [PATCH 596/738] Remove efi/grub-mkimage.c --- util/i386/efi/grub-mkimage.c | 1112 ---------------------------------- 1 file changed, 1112 deletions(-) delete mode 100644 util/i386/efi/grub-mkimage.c diff --git a/util/i386/efi/grub-mkimage.c b/util/i386/efi/grub-mkimage.c deleted file mode 100644 index f8c0f152e..000000000 --- a/util/i386/efi/grub-mkimage.c +++ /dev/null @@ -1,1112 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2004,2005,2006,2007,2008,2009 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "progname.h" - -#if GRUB_TARGET_WORDSIZE == 32 -# define grub_le_to_cpu(val) grub_le_to_cpu32(val) -#elif GRUB_TARGET_WORDSIZE == 64 -# define grub_le_to_cpu(val) grub_le_to_cpu64(val) -#endif - -static const grub_uint8_t stub[] = GRUB_PE32_MSDOS_STUB; - -static inline Elf_Addr -align_address (Elf_Addr addr, unsigned alignment) -{ - return (addr + alignment - 1) & ~(alignment - 1); -} - -static inline Elf_Addr -align_pe32_section (Elf_Addr addr) -{ - return align_address (addr, GRUB_PE32_SECTION_ALIGNMENT); -} - -/* Read the whole kernel image. Return the pointer to a read image, - and store the size in bytes in *SIZE. */ -static char * -read_kernel_image (const char *dir, size_t *size) -{ - char *kernel_image; - char *kernel_path; - - kernel_path = grub_util_get_path (dir, "kernel.img"); - *size = grub_util_get_image_size (kernel_path); - kernel_image = grub_util_read_image (kernel_path); - free (kernel_path); - - return kernel_image; -} - -/* Return if the ELF header is valid. */ -static int -check_elf_header (Elf_Ehdr *e, size_t size) -{ - if (size < sizeof (*e) - || e->e_ident[EI_MAG0] != ELFMAG0 - || e->e_ident[EI_MAG1] != ELFMAG1 - || e->e_ident[EI_MAG2] != ELFMAG2 - || e->e_ident[EI_MAG3] != ELFMAG3 - || e->e_ident[EI_VERSION] != EV_CURRENT - || e->e_version != grub_cpu_to_le32 (EV_CURRENT) - || ((e->e_ident[EI_CLASS] != ELFCLASS32) && - (e->e_ident[EI_CLASS] != ELFCLASS64)) - || e->e_ident[EI_DATA] != ELFDATA2LSB - || ((e->e_machine != grub_cpu_to_le16 (EM_386)) && - (e->e_machine != grub_cpu_to_le16 (EM_X86_64)))) - return 0; - - return 1; -} - -/* Return the starting address right after the header, - aligned by the section alignment. Allocate 4 section tables for - .text, .data, .reloc, and mods. */ -static Elf_Addr -get_starting_section_address (void) -{ - return align_pe32_section (sizeof (struct grub_pe32_header) - + 4 * sizeof (struct grub_pe32_section_table)); -} - -/* Determine if this section is a text section. Return false if this - section is not allocated. */ -static int -is_text_section (Elf_Shdr *s) -{ - return ((s->sh_flags & grub_cpu_to_le32 (SHF_EXECINSTR | SHF_ALLOC)) - == grub_cpu_to_le32 (SHF_EXECINSTR | SHF_ALLOC)); -} - -/* Determine if this section is a data section. This assumes that - BSS is also a data section, since the converter initializes BSS - when producing PE32 to avoid a bug in EFI implementations. */ -static int -is_data_section (Elf_Shdr *s) -{ - return (s->sh_flags & grub_cpu_to_le32 (SHF_ALLOC) - && ! (s->sh_flags & grub_cpu_to_le32 (SHF_EXECINSTR))); -} - -/* Locate section addresses by merging code sections and data sections - into .text and .data, respectively. Return the array of section - addresses. */ -static Elf_Addr * -locate_sections (Elf_Shdr *sections, Elf_Half section_entsize, - Elf_Half num_sections, const char *strtab) -{ - int i; - Elf_Addr current_address; - Elf_Addr *section_addresses; - Elf_Shdr *s; - - section_addresses = xmalloc (sizeof (*section_addresses) * num_sections); - memset (section_addresses, 0, sizeof (*section_addresses) * num_sections); - - current_address = get_starting_section_address (); - - /* .text */ - for (i = 0, s = sections; - i < num_sections; - i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if (is_text_section (s)) - { - Elf_Word align = grub_le_to_cpu32 (s->sh_addralign); - const char *name = strtab + grub_le_to_cpu32 (s->sh_name); - - if (align) - current_address = align_address (current_address, align); - - grub_util_info ("locating the section %s at 0x%x", - name, current_address); - section_addresses[i] = current_address; - current_address += grub_le_to_cpu32 (s->sh_size); - } - - current_address = align_pe32_section (current_address); - - /* .data */ - for (i = 0, s = sections; - i < num_sections; - i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if (is_data_section (s)) - { - Elf_Word align = grub_le_to_cpu32 (s->sh_addralign); - const char *name = strtab + grub_le_to_cpu32 (s->sh_name); - - if (align) - current_address = align_address (current_address, align); - - grub_util_info ("locating the section %s at 0x%x", - name, current_address); - section_addresses[i] = current_address; - current_address += grub_le_to_cpu32 (s->sh_size); - } - - return section_addresses; -} - -/* Return the symbol table section, if any. */ -static Elf_Shdr * -find_symtab_section (Elf_Shdr *sections, - Elf_Half section_entsize, Elf_Half num_sections) -{ - int i; - Elf_Shdr *s; - - for (i = 0, s = sections; - i < num_sections; - i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if (s->sh_type == grub_cpu_to_le32 (SHT_SYMTAB)) - return s; - - return 0; -} - -/* Return the address of the string table. */ -static const char * -find_strtab (Elf_Ehdr *e, Elf_Shdr *sections, Elf_Half section_entsize) -{ - Elf_Shdr *s; - char *strtab; - - s = (Elf_Shdr *) ((char *) sections - + grub_le_to_cpu16 (e->e_shstrndx) * section_entsize); - strtab = (char *) e + grub_le_to_cpu32 (s->sh_offset); - return strtab; -} - -/* Relocate symbols; note that this function overwrites the symbol table. - Return the address of a start symbol. */ -static Elf_Addr -relocate_symbols (Elf_Ehdr *e, Elf_Shdr *sections, - Elf_Shdr *symtab_section, Elf_Addr *section_addresses, - Elf_Half section_entsize, Elf_Half num_sections) -{ - Elf_Word symtab_size, sym_size, num_syms; - Elf_Off symtab_offset; - Elf_Addr start_address = 0; - Elf_Sym *sym; - Elf_Word i; - Elf_Shdr *strtab_section; - const char *strtab; - - strtab_section - = (Elf_Shdr *) ((char *) sections - + (grub_le_to_cpu32 (symtab_section->sh_link) - * section_entsize)); - strtab = (char *) e + grub_le_to_cpu32 (strtab_section->sh_offset); - - symtab_size = grub_le_to_cpu32 (symtab_section->sh_size); - sym_size = grub_le_to_cpu32 (symtab_section->sh_entsize); - symtab_offset = grub_le_to_cpu32 (symtab_section->sh_offset); - num_syms = symtab_size / sym_size; - - for (i = 0, sym = (Elf_Sym *) ((char *) e + symtab_offset); - i < num_syms; - i++, sym = (Elf_Sym *) ((char *) sym + sym_size)) - { - Elf_Section index; - const char *name; - - name = strtab + grub_le_to_cpu32 (sym->st_name); - - index = grub_le_to_cpu16 (sym->st_shndx); - if (index == STN_ABS) - { - continue; - } - else if ((index == STN_UNDEF)) - { - if (sym->st_name) - grub_util_error ("undefined symbol %s", name); - else - continue; - } - else if (index >= num_sections) - grub_util_error ("section %d does not exist", index); - - sym->st_value = (grub_le_to_cpu32 (sym->st_value) - + section_addresses[index]); - grub_util_info ("locating %s at 0x%x", name, sym->st_value); - - if (! start_address) - if (strcmp (name, "_start") == 0 || strcmp (name, "start") == 0) - start_address = sym->st_value; - } - - return start_address; -} - -/* Return the address of a symbol at the index I in the section S. */ -static Elf_Addr -get_symbol_address (Elf_Ehdr *e, Elf_Shdr *s, Elf_Word i) -{ - Elf_Sym *sym; - - sym = (Elf_Sym *) ((char *) e - + grub_le_to_cpu32 (s->sh_offset) - + i * grub_le_to_cpu32 (s->sh_entsize)); - return sym->st_value; -} - -/* Return the address of a modified value. */ -static Elf_Addr * -get_target_address (Elf_Ehdr *e, Elf_Shdr *s, Elf_Addr offset) -{ - return (Elf_Addr *) ((char *) e + grub_le_to_cpu32 (s->sh_offset) + offset); -} - -/* Deal with relocation information. This function relocates addresses - within the virtual address space starting from 0. So only relative - addresses can be fully resolved. Absolute addresses must be relocated - again by a PE32 relocator when loaded. */ -static void -relocate_addresses (Elf_Ehdr *e, Elf_Shdr *sections, - Elf_Addr *section_addresses, - Elf_Half section_entsize, Elf_Half num_sections, - const char *strtab) -{ - Elf_Half i; - Elf_Shdr *s; - - for (i = 0, s = sections; - i < num_sections; - i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if ((s->sh_type == grub_cpu_to_le32 (SHT_REL)) || - (s->sh_type == grub_cpu_to_le32 (SHT_RELA))) - { - Elf_Rela *r; - Elf_Word rtab_size, r_size, num_rs; - Elf_Off rtab_offset; - Elf_Shdr *symtab_section; - Elf_Word target_section_index; - Elf_Addr target_section_addr; - Elf_Shdr *target_section; - Elf_Word j; - - symtab_section = (Elf_Shdr *) ((char *) sections - + (grub_le_to_cpu32 (s->sh_link) - * section_entsize)); - target_section_index = grub_le_to_cpu32 (s->sh_info); - target_section_addr = section_addresses[target_section_index]; - target_section = (Elf_Shdr *) ((char *) sections - + (target_section_index - * section_entsize)); - - grub_util_info ("dealing with the relocation section %s for %s", - strtab + grub_le_to_cpu32 (s->sh_name), - strtab + grub_le_to_cpu32 (target_section->sh_name)); - - rtab_size = grub_le_to_cpu32 (s->sh_size); - r_size = grub_le_to_cpu32 (s->sh_entsize); - rtab_offset = grub_le_to_cpu32 (s->sh_offset); - num_rs = rtab_size / r_size; - - for (j = 0, r = (Elf_Rela *) ((char *) e + rtab_offset); - j < num_rs; - j++, r = (Elf_Rela *) ((char *) r + r_size)) - { - Elf_Addr info; - Elf_Addr offset; - Elf_Addr sym_addr; - Elf_Addr *target; - Elf_Addr addend; - - offset = grub_le_to_cpu (r->r_offset); - target = get_target_address (e, target_section, offset); - info = grub_le_to_cpu (r->r_info); - sym_addr = get_symbol_address (e, symtab_section, - ELF_R_SYM (info)); - - addend = (s->sh_type == grub_cpu_to_le32 (SHT_RELA)) ? - r->r_addend : 0; - - switch (ELF_R_TYPE (info)) - { -#if GRUB_TARGET_SIZEOF_VOID_P == 4 - case R_386_NONE: - break; - - case R_386_32: - /* This is absolute. */ - *target = grub_cpu_to_le32 (grub_le_to_cpu32 (*target) - + addend + sym_addr); - grub_util_info ("relocating an R_386_32 entry to 0x%x at the offset 0x%x", - *target, offset); - break; - - case R_386_PC32: - /* This is relative. */ - *target = grub_cpu_to_le32 (grub_le_to_cpu32 (*target) - + addend + sym_addr - - target_section_addr - offset); - grub_util_info ("relocating an R_386_PC32 entry to 0x%x at the offset 0x%x", - *target, offset); - break; - -#else - - case R_X86_64_NONE: - break; - - case R_X86_64_64: - *target = grub_cpu_to_le64 (grub_le_to_cpu64 (*target) - + addend + sym_addr); - grub_util_info ("relocating an R_X86_64_64 entry to 0x%llx at the offset 0x%llx", - *target, offset); - break; - - case R_X86_64_PC32: - { - grub_uint32_t *t32 = (grub_uint32_t *) target; - *t32 = grub_cpu_to_le64 (grub_le_to_cpu32 (*t32) - + addend + sym_addr - - target_section_addr - offset); - grub_util_info ("relocating an R_X86_64_PC32 entry to 0x%x at the offset 0x%llx", - *t32, offset); - break; - } - - case R_X86_64_32: - case R_X86_64_32S: - { - grub_uint32_t *t32 = (grub_uint32_t *) target; - *t32 = grub_cpu_to_le64 (grub_le_to_cpu32 (*t32) - + addend + sym_addr); - grub_util_info ("relocating an R_X86_64_32(S) entry to 0x%x at the offset 0x%llx", - *t32, offset); - break; - } - -#endif - default: - grub_util_error ("unknown relocation type %d", - ELF_R_TYPE (info)); - break; - } - } - } -} - -void -write_padding (FILE *out, size_t size) -{ - size_t i; - - for (i = 0; i < size; i++) - if (fputc (0, out) == EOF) - grub_util_error ("padding failed"); -} - -/* Add a PE32's fixup entry for a relocation. Return the resulting address - after having written to the file OUT. */ -Elf_Addr -add_fixup_entry (struct grub_pe32_fixup_block **block, grub_uint16_t type, - Elf_Addr addr, int flush, Elf_Addr current_address, - FILE *out) -{ - struct grub_pe32_fixup_block *b = *block; - - /* First, check if it is necessary to write out the current block. */ - if (b) - { - if (flush || addr < b->page_rva || b->page_rva + 0x1000 <= addr) - { - grub_uint32_t size; - - if (flush) - { - /* Add as much padding as necessary to align the address - with a section boundary. */ - Elf_Addr next_address; - unsigned padding_size; - size_t index; - - next_address = current_address + b->block_size; - padding_size = ((align_pe32_section (next_address) - - next_address) - >> 1); - index = ((b->block_size - sizeof (*b)) >> 1); - grub_util_info ("adding %d padding fixup entries", padding_size); - while (padding_size--) - { - b->entries[index++] = 0; - b->block_size += 2; - } - } - else if (b->block_size & (8 - 1)) - { - /* If not aligned with a 32-bit boundary, add - a padding entry. */ - size_t index; - - grub_util_info ("adding a padding fixup entry"); - index = ((b->block_size - sizeof (*b)) >> 1); - b->entries[index] = 0; - b->block_size += 2; - } - - /* Flush it. */ - grub_util_info ("writing %d bytes of a fixup block starting at 0x%x", - b->block_size, b->page_rva); - size = b->block_size; - current_address += size; - b->page_rva = grub_cpu_to_le32 (b->page_rva); - b->block_size = grub_cpu_to_le32 (b->block_size); - if (fwrite (b, size, 1, out) != 1) - grub_util_error ("write failed"); - free (b); - *block = b = 0; - } - } - - if (! flush) - { - grub_uint16_t entry; - size_t index; - - /* If not allocated yet, allocate a block with enough entries. */ - if (! b) - { - *block = b = xmalloc (sizeof (*b) + 2 * 0x1000); - - /* The spec does not mention the requirement of a Page RVA. - Here, align the address with a 4K boundary for safety. */ - b->page_rva = (addr & ~(0x1000 - 1)); - b->block_size = sizeof (*b); - } - - /* Sanity check. */ - if (b->block_size >= sizeof (*b) + 2 * 0x1000) - grub_util_error ("too many fixup entries"); - - /* Add a new entry. */ - index = ((b->block_size - sizeof (*b)) >> 1); - entry = GRUB_PE32_FIXUP_ENTRY (type, addr - b->page_rva); - b->entries[index] = grub_cpu_to_le16 (entry); - b->block_size += 2; - } - - return current_address; -} - -/* Write out zeros to make space for the header. */ -static Elf_Addr -make_header_space (FILE *out) -{ - Elf_Addr addr; - - addr = get_starting_section_address (); - write_padding (out, addr); - - return addr; -} - -/* Write text sections. */ -static Elf_Addr -write_text_sections (FILE *out, Elf_Addr current_address, - Elf_Ehdr *e, Elf_Shdr *sections, - Elf_Half section_entsize, Elf_Half num_sections, - const char *strtab) -{ - Elf_Half i; - Elf_Shdr *s; - Elf_Addr addr; - - for (i = 0, s = sections; - i < num_sections; - i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if (is_text_section (s)) - { - Elf_Word align = grub_le_to_cpu32 (s->sh_addralign); - Elf_Off offset = grub_le_to_cpu32 (s->sh_offset); - Elf_Word size = grub_le_to_cpu32 (s->sh_size); - const char *name = strtab + grub_le_to_cpu32 (s->sh_name); - - if (align) - { - addr = align_address (current_address, align); - if (current_address != addr) - { - grub_util_info ("padding %d bytes for the ELF section alignment", - addr - current_address); - write_padding (out, addr - current_address); - current_address = addr; - } - } - - grub_util_info ("writing the text section %s at 0x%x", - name, current_address); - - if (fwrite ((char *) e + offset, size, 1, out) != 1) - grub_util_error ("write failed"); - - current_address += size; - } - - addr = align_pe32_section (current_address); - if (addr != current_address) - { - grub_util_info ("padding %d bytes for the PE32 section alignment", - addr - current_address); - write_padding (out, addr - current_address); - } - - return addr; -} - -/* Write data sections. */ -static Elf_Addr -write_data_sections (FILE *out, Elf_Addr current_address, - Elf_Ehdr *e, Elf_Shdr *sections, - Elf_Half section_entsize, Elf_Half num_sections, - const char *strtab) -{ - Elf_Half i; - Elf_Shdr *s; - Elf_Addr addr; - - for (i = 0, s = sections; - i < num_sections; - i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if (is_data_section (s)) - { - Elf_Word align = grub_le_to_cpu32 (s->sh_addralign); - Elf_Off offset = grub_le_to_cpu32 (s->sh_offset); - Elf_Word size = grub_le_to_cpu32 (s->sh_size); - const char *name = strtab + grub_le_to_cpu32 (s->sh_name); - - if (align) - { - addr = align_address (current_address, align); - if (current_address != addr) - { - grub_util_info ("padding %d bytes for the ELF section alignment", - addr - current_address); - write_padding (out, addr - current_address); - current_address = addr; - } - } - - grub_util_info ("writing the data section %s at 0x%x", - name, current_address); - - if (s->sh_type == grub_cpu_to_le32 (SHT_NOBITS)) - write_padding (out, size); - else - if (fwrite ((char *) e + offset, size, 1, out) != 1) - grub_util_error ("write failed"); - - current_address += size; - } - - addr = align_pe32_section (current_address); - if (addr != current_address) - { - grub_util_info ("padding %d bytes for the PE32 section alignment", - addr - current_address); - write_padding (out, addr - current_address); - } - - return addr; -} - -/* Write modules. */ -static Elf_Addr -make_mods_section (FILE *out, Elf_Addr current_address, - const char *dir, char *mods[]) -{ - struct grub_util_path_list *path_list; - grub_size_t total_module_size; - struct grub_util_path_list *p; - struct grub_module_info modinfo; - Elf_Addr addr; - - memset (&modinfo, 0, sizeof (modinfo)); - - path_list = grub_util_resolve_dependencies (dir, "moddep.lst", mods); - - total_module_size = sizeof (struct grub_module_info); - for (p = path_list; p; p = p->next) - { - total_module_size += (grub_util_get_image_size (p->name) - + sizeof (struct grub_module_header)); - } - - grub_util_info ("the total module size is 0x%x", total_module_size); - - modinfo.magic = grub_cpu_to_le32 (GRUB_MODULE_MAGIC); - modinfo.offset = grub_cpu_to_le32 (sizeof (modinfo)); - modinfo.size = grub_cpu_to_le32 (total_module_size); - - if (fwrite (&modinfo, sizeof (modinfo), 1, out) != 1) - grub_util_error ("write failed"); - - for (p = path_list; p; p = p->next) - { - struct grub_module_header header; - size_t mod_size; - char *mod_image; - - memset (&header, 0, sizeof (header)); - - grub_util_info ("adding module %s", p->name); - - mod_size = grub_util_get_image_size (p->name); - header.type = OBJ_TYPE_ELF; - header.size = grub_host_to_target32 (mod_size + sizeof (header)); - - mod_image = grub_util_read_image (p->name); - - if (fwrite (&header, sizeof (header), 1, out) != 1 - || fwrite (mod_image, mod_size, 1, out) != 1) - grub_util_error ("write failed"); - - free (mod_image); - } - - for (p = path_list; p; ) - { - struct grub_util_path_list *q; - - q = p->next; - free (p); - p = q; - } - - current_address += total_module_size; - - addr = align_pe32_section (current_address); - if (addr != current_address) - { - grub_util_info ("padding %d bytes for the PE32 section alignment", - addr - current_address); - write_padding (out, addr - current_address); - } - - return addr; -} - -/* Make a .reloc section. */ -static Elf_Addr -make_reloc_section (FILE *out, Elf_Addr current_address, Elf_Ehdr *e, - Elf_Addr *section_addresses, Elf_Shdr *sections, - Elf_Half section_entsize, Elf_Half num_sections, - const char *strtab) -{ - Elf_Half i; - Elf_Shdr *s; - struct grub_pe32_fixup_block *fixup_block = 0; - - for (i = 0, s = sections; - i < num_sections; - i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if ((s->sh_type == grub_cpu_to_le32 (SHT_REL)) || - (s->sh_type == grub_cpu_to_le32 (SHT_RELA))) - { - Elf_Rel *r; - Elf_Word rtab_size, r_size, num_rs; - Elf_Off rtab_offset; - Elf_Addr section_address; - Elf_Word j; - - grub_util_info ("translating the relocation section %s", - strtab + grub_le_to_cpu32 (s->sh_name)); - - rtab_size = grub_le_to_cpu32 (s->sh_size); - r_size = grub_le_to_cpu32 (s->sh_entsize); - rtab_offset = grub_le_to_cpu32 (s->sh_offset); - num_rs = rtab_size / r_size; - - section_address = section_addresses[grub_le_to_cpu32 (s->sh_info)]; - - for (j = 0, r = (Elf_Rel *) ((char *) e + rtab_offset); - j < num_rs; - j++, r = (Elf_Rel *) ((char *) r + r_size)) - { - Elf_Addr info; - Elf_Addr offset; - - offset = grub_le_to_cpu32 (r->r_offset); - info = grub_le_to_cpu32 (r->r_info); - - /* Necessary to relocate only absolute addresses. */ -#if GRUB_TARGET_SIZEOF_VOID_P == 4 - if (ELF_R_TYPE (info) == R_386_32) - { - Elf_Addr addr; - - addr = section_address + offset; - grub_util_info ("adding a relocation entry for 0x%x", addr); - current_address = add_fixup_entry (&fixup_block, - GRUB_PE32_REL_BASED_HIGHLOW, - addr, 0, current_address, - out); - } -#else - if ((ELF_R_TYPE (info) == R_X86_64_32) || - (ELF_R_TYPE (info) == R_X86_64_32S)) - { - grub_util_error ("can\'t add fixup entry for R_X86_64_32(S)"); - } - else if (ELF_R_TYPE (info) == R_X86_64_64) - { - Elf_Addr addr; - - addr = section_address + offset; - grub_util_info ("adding a relocation entry for 0x%llx", addr); - current_address = add_fixup_entry (&fixup_block, - GRUB_PE32_REL_BASED_DIR64, - addr, - 0, current_address, - out); - } -#endif - } - } - - current_address = add_fixup_entry (&fixup_block, 0, 0, 1, - current_address, out); - - return current_address; -} - -/* Create the header. */ -static void -make_header (FILE *out, Elf_Addr text_address, Elf_Addr data_address, - Elf_Addr mods_address, Elf_Addr reloc_address, - Elf_Addr end_address, Elf_Addr start_address) -{ - struct grub_pe32_header header; - struct grub_pe32_coff_header *c; - struct grub_pe32_optional_header *o; - struct grub_pe32_section_table text_section, data_section; - struct grub_pe32_section_table mods_section, reloc_section; - - /* The magic. */ - memset (&header, 0, sizeof (header)); - memcpy (header.msdos_stub, stub, sizeof (header.msdos_stub)); - memcpy (header.signature, "PE\0\0", sizeof (header.signature)); - - /* The COFF file header. */ - c = &header.coff_header; -#if GRUB_TARGET_SIZEOF_VOID_P == 4 - c->machine = grub_cpu_to_le16 (GRUB_PE32_MACHINE_I386); -#else - c->machine = grub_cpu_to_le16 (GRUB_PE32_MACHINE_X86_64); -#endif - - c->num_sections = grub_cpu_to_le16 (4); - c->time = grub_cpu_to_le32 (time (0)); - c->optional_header_size = grub_cpu_to_le16 (sizeof (header.optional_header)); - c->characteristics = grub_cpu_to_le16 (GRUB_PE32_EXECUTABLE_IMAGE - | GRUB_PE32_LINE_NUMS_STRIPPED -#if GRUB_TARGET_SIZEOF_VOID_P == 4 - | GRUB_PE32_32BIT_MACHINE -#endif - | GRUB_PE32_LOCAL_SYMS_STRIPPED - | GRUB_PE32_DEBUG_STRIPPED); - - /* The PE Optional header. */ - o = &header.optional_header; - o->magic = grub_cpu_to_le16 (GRUB_PE32_PE32_MAGIC); - o->code_size = grub_cpu_to_le32 (data_address - text_address); - o->data_size = grub_cpu_to_le32 (reloc_address - data_address); - o->bss_size = 0; - o->entry_addr = grub_cpu_to_le32 (start_address); - o->code_base = grub_cpu_to_le32 (text_address); -#if GRUB_TARGET_SIZEOF_VOID_P == 4 - o->data_base = grub_cpu_to_le32 (data_address); -#endif - o->image_base = 0; - o->section_alignment = grub_cpu_to_le32 (GRUB_PE32_SECTION_ALIGNMENT); - o->file_alignment = grub_cpu_to_le32 (GRUB_PE32_FILE_ALIGNMENT); - o->image_size = grub_cpu_to_le32 (end_address); - o->header_size = grub_cpu_to_le32 (text_address); - o->subsystem = grub_cpu_to_le16 (GRUB_PE32_SUBSYSTEM_EFI_APPLICATION); - - /* Do these really matter? */ - o->stack_reserve_size = grub_cpu_to_le32 (0x10000); - o->stack_commit_size = grub_cpu_to_le32 (0x10000); - o->heap_reserve_size = grub_cpu_to_le32 (0x10000); - o->heap_commit_size = grub_cpu_to_le32 (0x10000); - - o->num_data_directories = grub_cpu_to_le32 (GRUB_PE32_NUM_DATA_DIRECTORIES); - - o->base_relocation_table.rva = grub_cpu_to_le32 (reloc_address); - o->base_relocation_table.size = grub_cpu_to_le32 (end_address - - reloc_address); - - /* The sections. */ - memset (&text_section, 0, sizeof (text_section)); - strcpy (text_section.name, ".text"); - text_section.virtual_size = grub_cpu_to_le32 (data_address - text_address); - text_section.virtual_address = grub_cpu_to_le32 (text_address); - text_section.raw_data_size = grub_cpu_to_le32 (data_address - text_address); - text_section.raw_data_offset = grub_cpu_to_le32 (text_address); - text_section.characteristics = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_CODE - | GRUB_PE32_SCN_MEM_EXECUTE - | GRUB_PE32_SCN_MEM_READ); - - memset (&data_section, 0, sizeof (data_section)); - strcpy (data_section.name, ".data"); - data_section.virtual_size = grub_cpu_to_le32 (mods_address - data_address); - data_section.virtual_address = grub_cpu_to_le32 (data_address); - data_section.raw_data_size = grub_cpu_to_le32 (mods_address - data_address); - data_section.raw_data_offset = grub_cpu_to_le32 (data_address); - data_section.characteristics - = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_INITIALIZED_DATA - | GRUB_PE32_SCN_MEM_READ - | GRUB_PE32_SCN_MEM_WRITE); - - memset (&mods_section, 0, sizeof (mods_section)); - strcpy (mods_section.name, "mods"); - mods_section.virtual_size = grub_cpu_to_le32 (reloc_address - mods_address); - mods_section.virtual_address = grub_cpu_to_le32 (mods_address); - mods_section.raw_data_size = grub_cpu_to_le32 (reloc_address - mods_address); - mods_section.raw_data_offset = grub_cpu_to_le32 (mods_address); - mods_section.characteristics - = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_INITIALIZED_DATA - | GRUB_PE32_SCN_MEM_READ - | GRUB_PE32_SCN_MEM_WRITE); - - memset (&reloc_section, 0, sizeof (reloc_section)); - strcpy (reloc_section.name, ".reloc"); - reloc_section.virtual_size = grub_cpu_to_le32 (end_address - reloc_address); - reloc_section.virtual_address = grub_cpu_to_le32 (reloc_address); - reloc_section.raw_data_size = grub_cpu_to_le32 (end_address - reloc_address); - reloc_section.raw_data_offset = grub_cpu_to_le32 (reloc_address); - reloc_section.characteristics - = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_INITIALIZED_DATA - | GRUB_PE32_SCN_MEM_DISCARDABLE - | GRUB_PE32_SCN_MEM_READ); - - /* Write them out. */ - if (fseeko (out, 0, SEEK_SET) < 0) - grub_util_error ("seek failed"); - - if (fwrite (&header, sizeof (header), 1, out) != 1 - || fwrite (&text_section, sizeof (text_section), 1, out) != 1 - || fwrite (&data_section, sizeof (data_section), 1, out) != 1 - || fwrite (&mods_section, sizeof (mods_section), 1, out) != 1 - || fwrite (&reloc_section, sizeof (reloc_section), 1, out) != 1) - grub_util_error ("write failed"); -} - -/* Convert an ELF relocatable object into an EFI Application (PE32). */ -void -convert_elf (const char *dir, char *prefix, FILE *out, char *mods[]) -{ - char *kernel_image; - size_t kernel_size; - const char *strtab; - Elf_Ehdr *e; - Elf_Shdr *sections; - Elf_Off section_offset; - Elf_Half section_entsize; - Elf_Half num_sections; - Elf_Addr *section_addresses; - Elf_Shdr *symtab_section; - Elf_Addr start_address; - Elf_Addr text_address, data_address, reloc_address, mods_address; - Elf_Addr end_address; - Elf_Shdr *s; - int i; - - /* Get the kernel image and check the format. */ - kernel_image = read_kernel_image (dir, &kernel_size); - e = (Elf_Ehdr *) kernel_image; - if (! check_elf_header (e, kernel_size)) - grub_util_error ("invalid ELF header"); - - section_offset = grub_cpu_to_le32 (e->e_shoff); - section_entsize = grub_cpu_to_le16 (e->e_shentsize); - num_sections = grub_cpu_to_le16 (e->e_shnum); - - if (kernel_size < section_offset + section_entsize * num_sections) - grub_util_error ("invalid ELF format"); - - sections = (Elf_Shdr *) (kernel_image + section_offset); - strtab = find_strtab (e, sections, section_entsize); - - for (i = 0, s = sections; - i < num_sections; - i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if (is_text_section (s)) - { - Elf_Off offset = grub_le_to_cpu32 (s->sh_offset); - - if (GRUB_KERNEL_MACHINE_PREFIX + strlen (prefix) + 1 > GRUB_KERNEL_MACHINE_DATA_END) - grub_util_error ("prefix too long"); - - strcpy (kernel_image + offset + GRUB_KERNEL_MACHINE_PREFIX, prefix); - break; - } - - /* Relocate sections then symbols in the virtual address space. */ - section_addresses = locate_sections (sections, section_entsize, - num_sections, strtab); - - symtab_section = find_symtab_section (sections, - section_entsize, num_sections); - if (! symtab_section) - grub_util_error ("no symbol table"); - - start_address = relocate_symbols (e, sections, symtab_section, - section_addresses, section_entsize, - num_sections); - if (start_address == 0) - grub_util_error ("start symbol is not defined"); - - /* Resolve addresses in the virtual address space. */ - relocate_addresses (e, sections, section_addresses, section_entsize, - num_sections, strtab); - - /* Generate a PE32 image file. The strategy is to dump binary data first, - then fill up the header. */ - text_address = make_header_space (out); - data_address = write_text_sections (out, text_address, e, sections, - section_entsize, num_sections, - strtab); - mods_address = write_data_sections (out, data_address, e, sections, - section_entsize, num_sections, - strtab); - reloc_address = make_mods_section (out, mods_address, dir, mods); - end_address = make_reloc_section (out, reloc_address, e, section_addresses, - sections, section_entsize, num_sections, - strtab); - make_header (out, text_address, data_address, mods_address, - reloc_address, end_address, start_address); - - /* Clean up. */ - free (section_addresses); - free (kernel_image); -} - -static struct option options[] = - { - {"directory", required_argument, 0, 'd'}, - {"prefix", required_argument, 0, 'p'}, - {"output", required_argument, 0, 'o'}, - {"help", no_argument, 0, 'h'}, - {"version", no_argument, 0, 'V'}, - {"verbose", no_argument, 0, 'v'}, - { 0, 0, 0, 0 } - }; - -static void -usage (int status) -{ - if (status) - fprintf (stderr, "Try `%s --help' for more information.\n", program_name); - else - printf ("\ -Usage: %s -o FILE [OPTION]... [MODULES]\n\ -\n\ -Make a bootable image of GRUB.\n\ -\n\ - -d, --directory=DIR use images and modules under DIR [default=%s]\n\ - -p, --prefix=DIR set grub_prefix directory [default=%s]\n\ - -o, --output=FILE output a generated image to FILE\n\ - -h, --help display this message and exit\n\ - -V, --version print version information and exit\n\ - -v, --verbose print verbose messages\n\ -\n\ -Report bugs to <%s>.\n\ -", program_name, GRUB_LIBDIR, DEFAULT_DIRECTORY, PACKAGE_BUGREPORT); - - exit (status); -} - -int -main (int argc, char *argv[]) -{ - FILE *fp; - char *output = NULL; - char *dir = NULL; - char *prefix = NULL; - - program_name = "grub-mkimage"; - - while (1) - { - int c = getopt_long (argc, argv, "d:p:o:hVv", options, 0); - if (c == -1) - break; - - switch (c) - { - case 'd': - if (dir) - free (dir); - dir = xstrdup (optarg); - break; - case 'h': - usage (0); - break; - case 'o': - if (output) - free (output); - output = xstrdup (optarg); - break; - case 'p': - if (prefix) - free (prefix); - prefix = xstrdup (optarg); - break; - case 'V': - printf ("grub-mkimage (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION); - return 0; - case 'v': - verbosity++; - break; - default: - usage (1); - break; - } - } - - if (! output) - usage (1); - - fp = fopen (output, "wb"); - if (! fp) - grub_util_error ("cannot open %s", output); - - convert_elf (dir ? : GRUB_LIBDIR, prefix ? : DEFAULT_DIRECTORY, fp, argv + optind); - - fclose (fp); - - return 0; -} From 2fa6a5dd4431588f98790e052858f3b851e34bac Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 25 Apr 2010 19:41:51 +0200 Subject: [PATCH 597/738] rename grub-mkrawimage to grub-mkimage --- conf/i386-pc.rmk | 4 ++-- conf/i386-qemu.rmk | 4 ++-- conf/mips.rmk | 4 ++-- conf/sparc64-ieee1275.rmk | 2 +- conf/x86-efi.rmk | 2 +- util/{grub-mkrawimage.c => grub-mkimage.c} | 0 6 files changed, 8 insertions(+), 8 deletions(-) rename util/{grub-mkrawimage.c => grub-mkimage.c} (100%) diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk index f2490ba97..2dd874e13 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -65,10 +65,10 @@ bin_UTILITIES = grub-mkimage sbin_UTILITIES = grub-setup # For grub-mkimage. -grub_mkimage_SOURCES = gnulib/progname.c util/grub-mkrawimage.c util/misc.c \ +grub_mkimage_SOURCES = gnulib/progname.c util/grub-mkimage.c util/misc.c \ util/resolve.c lib/LzmaEnc.c lib/LzFind.c grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR) -util/grub-mkrawimage.c_DEPENDENCIES = Makefile +util/grub-mkimage.c_DEPENDENCIES = Makefile # For grub-setup. util/i386/pc/grub-setup.c_DEPENDENCIES = grub_setup_init.h diff --git a/conf/i386-qemu.rmk b/conf/i386-qemu.rmk index 923231791..003f86c33 100644 --- a/conf/i386-qemu.rmk +++ b/conf/i386-qemu.rmk @@ -14,10 +14,10 @@ boot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_BOOT_MACHINE_LI boot_img_FORMAT = binary bin_UTILITIES += grub-mkimage -grub_mkimage_SOURCES = util/grub-mkrawimage.c util/misc.c \ +grub_mkimage_SOURCES = util/grub-mkimage.c util/misc.c \ util/resolve.c gnulib/progname.c grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR) -util/grub-mkrawimage.c_DEPENDENCIES = Makefile +util/grub-mkimage.c_DEPENDENCIES = Makefile pkglib_PROGRAMS += kernel.img kernel_img_SOURCES = kern/i386/qemu/startup.S \ diff --git a/conf/mips.rmk b/conf/mips.rmk index 4603c219e..c748d3945 100644 --- a/conf/mips.rmk +++ b/conf/mips.rmk @@ -12,10 +12,10 @@ bin_SCRIPTS = # For grub-mkimage. bin_UTILITIES += grub-mkimage -grub_mkimage_SOURCES = gnulib/progname.c util/grub-mkrawimage.c util/misc.c \ +grub_mkimage_SOURCES = gnulib/progname.c util/grub-mkimage.c util/misc.c \ util/resolve.c lib/LzmaEnc.c lib/LzFind.c grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(LINK_BASE) -util/grub-mkrawimage.c_DEPENDENCIES = Makefile +util/grub-mkimage.c_DEPENDENCIES = Makefile # For serial.mod. pkglib_MODULES += serial.mod diff --git a/conf/sparc64-ieee1275.rmk b/conf/sparc64-ieee1275.rmk index 8e96599aa..dd1524df1 100644 --- a/conf/sparc64-ieee1275.rmk +++ b/conf/sparc64-ieee1275.rmk @@ -45,7 +45,7 @@ bin_UTILITIES = grub-mkimage sbin_UTILITIES = grub-setup grub-ofpathname # For grub-mkimage. -grub_mkimage_SOURCES = util/grub-mkrawimage.c util/misc.c \ +grub_mkimage_SOURCES = util/grub-mkimage.c util/misc.c \ util/resolve.c gnulib/progname.c # For grub-setup. diff --git a/conf/x86-efi.rmk b/conf/x86-efi.rmk index bab561cc4..8bf0a08d9 100644 --- a/conf/x86-efi.rmk +++ b/conf/x86-efi.rmk @@ -4,7 +4,7 @@ bin_UTILITIES = grub-mkimage # For grub-mkimage. -grub_mkimage_SOURCES = gnulib/progname.c util/grub-mkrawimage.c \ +grub_mkimage_SOURCES = gnulib/progname.c util/grub-mkimage.c \ util/misc.c util/resolve.c util/i386/efi/grub-mkimage.c_DEPENDENCIES = Makefile diff --git a/util/grub-mkrawimage.c b/util/grub-mkimage.c similarity index 100% rename from util/grub-mkrawimage.c rename to util/grub-mkimage.c From 2296410ffbef1c180f3c001dff7abcc39fc6a242 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 25 Apr 2010 22:26:29 +0200 Subject: [PATCH 598/738] initial support for ppc in grub-mkimage (bugs for now) --- conf/common.rmk | 7 ++ conf/i386-pc.rmk | 7 -- conf/i386-qemu.rmk | 6 -- conf/mips.rmk | 7 -- conf/sparc64-ieee1275.rmk | 5 -- conf/x86-efi.rmk | 8 -- include/grub/mips/kernel.h | 2 + include/grub/powerpc/ieee1275/kernel.h | 19 ++++ include/grub/powerpc/kernel.h | 3 - kern/powerpc/ieee1275/startup.S | 6 +- util/elf/grub-mkimage.c | 5 +- util/grub-mkimage.c | 115 +++++++++++++++++++++---- 12 files changed, 133 insertions(+), 57 deletions(-) diff --git a/conf/common.rmk b/conf/common.rmk index 4b39e9b71..011bb2773 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -21,6 +21,13 @@ grub_mkelfimage_SOURCES = gnulib/progname.c \ util/resolve.c util/elf/grub-mkimage.c_DEPENDENCIES = Makefile +# For grub-mkimage. +bin_UTILITIES += grub-mkimage +grub_mkimage_SOURCES = gnulib/progname.c util/grub-mkimage.c util/misc.c \ + util/resolve.c lib/LzmaEnc.c lib/LzFind.c +grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR) +util/grub-mkimage.c_DEPENDENCIES = Makefile + # For grub-probe. sbin_UTILITIES += grub-probe util/grub-probe.c_DEPENDENCIES = grub_probe_init.h diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk index 2dd874e13..1e0a3ff58 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -61,15 +61,8 @@ kernel_img_ASFLAGS = $(COMMON_ASFLAGS) kernel_img_LDFLAGS += $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_KERNEL_MACHINE_LINK_ADDR) $(COMMON_CFLAGS) # Utilities. -bin_UTILITIES = grub-mkimage sbin_UTILITIES = grub-setup -# For grub-mkimage. -grub_mkimage_SOURCES = gnulib/progname.c util/grub-mkimage.c util/misc.c \ - util/resolve.c lib/LzmaEnc.c lib/LzFind.c -grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR) -util/grub-mkimage.c_DEPENDENCIES = Makefile - # For grub-setup. util/i386/pc/grub-setup.c_DEPENDENCIES = grub_setup_init.h grub_setup_SOURCES = gnulib/progname.c \ diff --git a/conf/i386-qemu.rmk b/conf/i386-qemu.rmk index 003f86c33..ff263245d 100644 --- a/conf/i386-qemu.rmk +++ b/conf/i386-qemu.rmk @@ -13,12 +13,6 @@ boot_img_ASFLAGS = $(COMMON_ASFLAGS) -DGRUB_BOOT_MACHINE_LINK_ADDR=$(GRUB_BOOT_M boot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_BOOT_MACHINE_LINK_ADDR) boot_img_FORMAT = binary -bin_UTILITIES += grub-mkimage -grub_mkimage_SOURCES = util/grub-mkimage.c util/misc.c \ - util/resolve.c gnulib/progname.c -grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR) -util/grub-mkimage.c_DEPENDENCIES = Makefile - pkglib_PROGRAMS += kernel.img kernel_img_SOURCES = kern/i386/qemu/startup.S \ kern/i386/misc.S \ diff --git a/conf/mips.rmk b/conf/mips.rmk index c748d3945..7d30f55f1 100644 --- a/conf/mips.rmk +++ b/conf/mips.rmk @@ -10,13 +10,6 @@ kernel_img_HEADERS += cpu/cache.h sbin_SCRIPTS = bin_SCRIPTS = -# For grub-mkimage. -bin_UTILITIES += grub-mkimage -grub_mkimage_SOURCES = gnulib/progname.c util/grub-mkimage.c util/misc.c \ - util/resolve.c lib/LzmaEnc.c lib/LzFind.c -grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(LINK_BASE) -util/grub-mkimage.c_DEPENDENCIES = Makefile - # For serial.mod. pkglib_MODULES += serial.mod serial_mod_SOURCES = term/serial.c diff --git a/conf/sparc64-ieee1275.rmk b/conf/sparc64-ieee1275.rmk index dd1524df1..5b71d4cb2 100644 --- a/conf/sparc64-ieee1275.rmk +++ b/conf/sparc64-ieee1275.rmk @@ -41,13 +41,8 @@ kernel_img_LDFLAGS += -nostdlib -Wl,-N,-Ttext,0x4400,-Bstatic,-melf64_sparc kernel_img_FORMAT = binary # Utilities. -bin_UTILITIES = grub-mkimage sbin_UTILITIES = grub-setup grub-ofpathname -# For grub-mkimage. -grub_mkimage_SOURCES = util/grub-mkimage.c util/misc.c \ - util/resolve.c gnulib/progname.c - # For grub-setup. util/sparc64/ieee1275/grub-setup.c_DEPENDENCIES = grub_setup_init.h grub_setup_SOURCES = util/sparc64/ieee1275/grub-setup.c util/hostdisk.c \ diff --git a/conf/x86-efi.rmk b/conf/x86-efi.rmk index 8bf0a08d9..99a9938ef 100644 --- a/conf/x86-efi.rmk +++ b/conf/x86-efi.rmk @@ -1,13 +1,5 @@ # -*- makefile -*- -# Utilities. -bin_UTILITIES = grub-mkimage - -# For grub-mkimage. -grub_mkimage_SOURCES = gnulib/progname.c util/grub-mkimage.c \ - util/misc.c util/resolve.c -util/i386/efi/grub-mkimage.c_DEPENDENCIES = Makefile - # Scripts. sbin_SCRIPTS = grub-install diff --git a/include/grub/mips/kernel.h b/include/grub/mips/kernel.h index 8b68f7b6b..172c1dbe2 100644 --- a/include/grub/mips/kernel.h +++ b/include/grub/mips/kernel.h @@ -46,6 +46,8 @@ #define GRUB_PLATFORM_IMAGE_DEFAULT GRUB_PLATFORM_IMAGE_RAW +#define EM_TARGET EM_MIPS + #ifndef ASM_FILE typedef enum { diff --git a/include/grub/powerpc/ieee1275/kernel.h b/include/grub/powerpc/ieee1275/kernel.h index a76c2a4df..229416243 100644 --- a/include/grub/powerpc/ieee1275/kernel.h +++ b/include/grub/powerpc/ieee1275/kernel.h @@ -21,8 +21,27 @@ #include +#define GRUB_PLATFORM_IMAGE_FORMATS "raw, elf" +#define GRUB_PLATFORM_IMAGE_DEFAULT_FORMAT "raw" + +#define GRUB_PLATFORM_IMAGE_DEFAULT GRUB_PLATFORM_IMAGE_RAW +#define GRUB_KERNEL_MACHINE_PREFIX 0x4 +#define GRUB_KERNEL_MACHINE_DATA_END 0x44 +#define GRUB_KERNEL_MACHINE_LINK_ALIGN 4 + +#define EM_TARGET EM_PPC +#define GRUB_KERNEL_MACHINE_LINK_ADDR 0x200000 + #ifndef ASM_FILE +typedef enum { + GRUB_PLATFORM_IMAGE_RAW, + GRUB_PLATFORM_IMAGE_ELF +} + grub_platform_image_format_t; +#define GRUB_PLATFORM_IMAGE_RAW GRUB_PLATFORM_IMAGE_RAW +#define GRUB_PLATFORM_IMAGE_ELF GRUB_PLATFORM_IMAGE_ELF + /* The prefix which points to the directory where GRUB modules and its configuration file are located. */ extern char grub_prefix[]; diff --git a/include/grub/powerpc/kernel.h b/include/grub/powerpc/kernel.h index b4687337f..e4ff65174 100644 --- a/include/grub/powerpc/kernel.h +++ b/include/grub/powerpc/kernel.h @@ -26,7 +26,4 @@ rewrite grub-mkimage to generate valid ELF files. */ #define GRUB_MOD_GAP 0x8000 -#define GRUB_KERNEL_CPU_PREFIX 0x4 -#define GRUB_KERNEL_CPU_DATA_END 0x44 - #endif diff --git a/kern/powerpc/ieee1275/startup.S b/kern/powerpc/ieee1275/startup.S index 75e1ed852..979f260f8 100644 --- a/kern/powerpc/ieee1275/startup.S +++ b/kern/powerpc/ieee1275/startup.S @@ -18,7 +18,7 @@ */ #include -#include +#include .extern __bss_start .extern _end @@ -30,7 +30,7 @@ start: _start: b codestart - . = _start + GRUB_KERNEL_CPU_PREFIX + . = _start + GRUB_KERNEL_MACHINE_PREFIX VARIABLE(grub_prefix) /* to be filled by grub-mkelfimage */ @@ -39,7 +39,7 @@ VARIABLE(grub_prefix) * Leave some breathing room for the prefix. */ - . = _start + GRUB_KERNEL_CPU_DATA_END + . = _start + GRUB_KERNEL_MACHINE_DATA_END codestart: li 2, 0 diff --git a/util/elf/grub-mkimage.c b/util/elf/grub-mkimage.c index 04a19bc4e..f37837c19 100644 --- a/util/elf/grub-mkimage.c +++ b/util/elf/grub-mkimage.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include "progname.h" @@ -323,9 +324,9 @@ add_segments (char *dir, char *prefix, FILE *out, int chrp, char *mods[], char * if (prefix) { - if (GRUB_KERNEL_CPU_PREFIX + strlen (prefix) + 1 > GRUB_KERNEL_CPU_DATA_END) + if (GRUB_KERNEL_MACHINE_PREFIX + strlen (prefix) + 1 > GRUB_KERNEL_MACHINE_DATA_END) grub_util_error ("prefix too long"); - grub_util_write_image_at (prefix, strlen (prefix) + 1, first_segment + GRUB_KERNEL_CPU_PREFIX, out); + grub_util_write_image_at (prefix, strlen (prefix) + 1, first_segment + GRUB_KERNEL_MACHINE_PREFIX, out); } free (phdrs); diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index 30608a932..71376eaee 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -46,6 +46,36 @@ #define ALIGN_ADDR(x) (ALIGN_UP((x), GRUB_TARGET_SIZEOF_VOID_P)) +#define GRUB_IEEE1275_NOTE_NAME "PowerPC" +#define GRUB_IEEE1275_NOTE_TYPE 0x1275 + +/* These structures are defined according to the CHRP binding to IEEE1275, + "Client Program Format" section. */ + +struct grub_ieee1275_note_hdr +{ + grub_uint32_t namesz; + grub_uint32_t descsz; + grub_uint32_t type; + char name[sizeof (GRUB_IEEE1275_NOTE_NAME)]; +}; + +struct grub_ieee1275_note_desc +{ + grub_uint32_t real_mode; + grub_uint32_t real_base; + grub_uint32_t real_size; + grub_uint32_t virt_base; + grub_uint32_t virt_size; + grub_uint32_t load_base; +}; + +struct grub_ieee1275_note +{ + struct grub_ieee1275_note_hdr header; + struct grub_ieee1275_note_desc descriptor; +}; + #ifdef GRUB_MACHINE_EFI #define SECTION_ALIGN GRUB_PE32_SECTION_ALIGNMENT #define VADDR_OFFSET ALIGN_UP (sizeof (struct grub_pe32_header) + 5 * sizeof (struct grub_pe32_section_table), SECTION_ALIGN) @@ -786,11 +816,11 @@ static void generate_image (const char *dir, char *prefix, FILE *out, char *mods[], char *memdisk_path, char *font_path, char *config_path, #ifdef GRUB_PLATFORM_IMAGE_DEFAULT - grub_platform_image_format_t format + grub_platform_image_format_t format, #else - int dummy __attribute__ ((unused)) + int dummy __attribute__ ((unused)), #endif - + int note ) { char *kernel_img, *core_img; @@ -1205,7 +1235,7 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], free (boot_img); free (boot_path); } -#elif defined(GRUB_MACHINE_MIPS) +#elif defined(GRUB_MACHINE_MIPS) || defined (GRUB_MACHINE_IEEE1275) if (format == GRUB_PLATFORM_IMAGE_ELF) { char *elf_img; @@ -1213,12 +1243,21 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], Elf32_Ehdr *ehdr; Elf32_Phdr *phdr; grub_uint32_t target_addr; + int header_size, footer_size = 0; + int phnum = 1; + + if (note) + { + phnum++; + footer_size += sizeof (struct grub_ieee1275_note); + } + header_size = ALIGN_ADDR (sizeof (*ehdr) + phnum * sizeof (*phdr)); program_size = ALIGN_ADDR (core_size); - elf_img = xmalloc (program_size + sizeof (*ehdr) + sizeof (*phdr)); - memset (elf_img, 0, program_size + sizeof (*ehdr) + sizeof (*phdr)); - memcpy (elf_img + sizeof (*ehdr) + sizeof (*phdr), core_img, core_size); + elf_img = xmalloc (program_size + header_size + footer_size); + memset (elf_img, 0, program_size + header_size); + memcpy (elf_img + header_size, core_img, core_size); ehdr = (void *) elf_img; phdr = (void *) (elf_img + sizeof (*ehdr)); memcpy (ehdr->e_ident, ELFMAG, SELFMAG); @@ -1231,12 +1270,12 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], ehdr->e_ident[EI_VERSION] = EV_CURRENT; ehdr->e_ident[EI_OSABI] = ELFOSABI_NONE; ehdr->e_type = grub_host_to_target16 (ET_EXEC); - ehdr->e_machine = grub_host_to_target16 (EM_MIPS); + ehdr->e_machine = grub_host_to_target16 (EM_TARGET); ehdr->e_version = grub_host_to_target32 (EV_CURRENT); ehdr->e_phoff = grub_host_to_target32 ((char *) phdr - (char *) ehdr); ehdr->e_phentsize = grub_host_to_target16 (sizeof (*phdr)); - ehdr->e_phnum = grub_host_to_target16 (1); + ehdr->e_phnum = grub_host_to_target16 (phnum); /* No section headers. */ ehdr->e_shoff = grub_host_to_target32 (0); @@ -1247,23 +1286,60 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], ehdr->e_ehsize = grub_host_to_target16 (sizeof (*ehdr)); phdr->p_type = grub_host_to_target32 (PT_LOAD); - phdr->p_offset = grub_host_to_target32 (sizeof (*ehdr) + sizeof (*phdr)); + phdr->p_offset = grub_host_to_target32 (header_size); phdr->p_flags = grub_host_to_target32 (PF_R | PF_W | PF_X); - target_addr = ALIGN_UP (GRUB_KERNEL_MACHINE_LINK_ADDR +#if defined(GRUB_MACHINE_MIPS) + target_addr = ALIGN_UP (GRUB_KERNEL_MACHINE_LINK_ADDR + kernel_size + total_module_size, 32); +#else + target_addr = GRUB_KERNEL_MACHINE_LINK_ADDR; +#endif ehdr->e_entry = grub_host_to_target32 (target_addr); phdr->p_vaddr = grub_host_to_target32 (target_addr); phdr->p_paddr = grub_host_to_target32 (target_addr); phdr->p_align = grub_host_to_target32 (GRUB_KERNEL_MACHINE_LINK_ALIGN); +#if defined(GRUB_MACHINE_MIPS) ehdr->e_flags = grub_host_to_target32 (0x1000 | EF_MIPS_NOREORDER | EF_MIPS_PIC | EF_MIPS_CPIC); +#else + ehdr->e_flags = 0; +#endif phdr->p_filesz = grub_host_to_target32 (core_size); phdr->p_memsz = grub_host_to_target32 (core_size); + if (note) + { + int note_size = sizeof (struct grub_ieee1275_note); + struct grub_ieee1275_note *note = (struct grub_ieee1275_note *) + (elf_img + program_size + header_size); + + grub_util_info ("adding CHRP NOTE segment"); + + note->header.namesz = grub_host_to_target32 (sizeof (GRUB_IEEE1275_NOTE_NAME)); + note->header.descsz = grub_host_to_target32 (note_size); + note->header.type = grub_host_to_target32 (GRUB_IEEE1275_NOTE_TYPE); + strcpy (note->header.name, GRUB_IEEE1275_NOTE_NAME); + note->descriptor.real_mode = grub_host_to_target32 (0xffffffff); + note->descriptor.real_base = grub_host_to_target32 (0x00c00000); + note->descriptor.real_size = grub_host_to_target32 (0xffffffff); + note->descriptor.virt_base = grub_host_to_target32 (0xffffffff); + note->descriptor.virt_size = grub_host_to_target32 (0xffffffff); + note->descriptor.load_base = grub_host_to_target32 (0x00004000); + + phdr[1].p_type = grub_host_to_target32 (PT_NOTE); + phdr[1].p_flags = grub_host_to_target32 (PF_R); + phdr[1].p_align = grub_host_to_target32 (GRUB_TARGET_SIZEOF_LONG); + phdr[1].p_vaddr = 0; + phdr[1].p_paddr = 0; + phdr[1].p_filesz = grub_host_to_target32 (note_size); + phdr[1].p_memsz = 0; + phdr[1].p_offset = grub_host_to_target32 (header_size + program_size); + } + free (core_img); core_img = elf_img; - core_size = program_size + sizeof (*ehdr) + sizeof (*phdr); + core_size = program_size + header_size + footer_size; } #endif @@ -1291,6 +1367,7 @@ static struct option options[] = {"font", required_argument, 0, 'f'}, {"config", required_argument, 0, 'c'}, {"output", required_argument, 0, 'o'}, + {"note", no_argument, 0, 'n'}, #ifdef GRUB_PLATFORM_IMAGE_DEFAULT {"format", required_argument, 0, 'O'}, #endif @@ -1316,6 +1393,7 @@ Make a bootable image of GRUB.\n\ -m, --memdisk=FILE embed FILE as a memdisk image\n\ -f, --font=FILE embed FILE as a boot font\n\ -c, --config=FILE embed FILE as boot config\n\ + -n, --note add NOTE segment for CHRP Open Firmware\n\ -o, --output=FILE output a generated image to FILE [default=stdout]\n" #ifdef GRUB_PLATFORM_IMAGE_DEFAULT "\ @@ -1348,6 +1426,7 @@ main (int argc, char *argv[]) char *font = NULL; char *config = NULL; FILE *fp = stdout; + int note = 0; #ifdef GRUB_PLATFORM_IMAGE_DEFAULT grub_platform_image_format_t format = GRUB_PLATFORM_IMAGE_DEFAULT; #endif @@ -1358,7 +1437,7 @@ main (int argc, char *argv[]) while (1) { - int c = getopt_long (argc, argv, "d:p:m:c:o:O:f:hVv", options, 0); + int c = getopt_long (argc, argv, "d:p:m:c:o:O:f:hVvn", options, 0); if (c == -1) break; @@ -1400,6 +1479,10 @@ main (int argc, char *argv[]) dir = xstrdup (optarg); break; + case 'n': + note = 1; + break; + case 'm': if (memdisk) free (memdisk); @@ -1462,11 +1545,11 @@ main (int argc, char *argv[]) generate_image (dir ? : GRUB_LIBDIR, prefix ? : DEFAULT_DIRECTORY, fp, argv + optind, memdisk, font, config, #ifdef GRUB_PLATFORM_IMAGE_DEFAULT - format + format, #else - 0 + 0, #endif - ); + note); fclose (fp); From 7576adef7cc18df53688e248fcdabb73aa9cb4da Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 25 Apr 2010 23:04:29 +0200 Subject: [PATCH 599/738] Remove grub-mkelfimage --- conf/common.rmk | 7 ------- 1 file changed, 7 deletions(-) diff --git a/conf/common.rmk b/conf/common.rmk index 011bb2773..bab7effb9 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -14,13 +14,6 @@ else grub_mkdevicemap_SOURCES += util/devicemap.c endif -# For grub-mkelfimage. -bin_UTILITIES += grub-mkelfimage -grub_mkelfimage_SOURCES = gnulib/progname.c \ - util/elf/grub-mkimage.c util/misc.c \ - util/resolve.c -util/elf/grub-mkimage.c_DEPENDENCIES = Makefile - # For grub-mkimage. bin_UTILITIES += grub-mkimage grub_mkimage_SOURCES = gnulib/progname.c util/grub-mkimage.c util/misc.c \ From 614be3f11949a6a2e7033e2f2dc4caa3e5a772a3 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 26 Apr 2010 00:45:21 +0200 Subject: [PATCH 600/738] #if-less grub-mkimage --- include/grub/i386/pc/boot.h | 17 +- include/grub/i386/pc/kernel.h | 24 +- include/grub/i386/pc/memory.h | 6 +- include/grub/i386/qemu/boot.h | 3 - include/grub/i386/qemu/kernel.h | 3 - include/grub/sparc64/ieee1275/boot.h | 4 - include/grub/sparc64/ieee1275/kernel.h | 13 - util/grub-mkimage.c | 1378 +++++++++++++----------- util/grub-mkrescue.in | 2 +- 9 files changed, 765 insertions(+), 685 deletions(-) diff --git a/include/grub/i386/pc/boot.h b/include/grub/i386/pc/boot.h index e88c62b71..09d01caee 100644 --- a/include/grub/i386/pc/boot.h +++ b/include/grub/i386/pc/boot.h @@ -19,6 +19,9 @@ #ifndef GRUB_BOOT_MACHINE_HEADER #define GRUB_BOOT_MACHINE_HEADER 1 +#define MACHINE I386_PC +#include + /* The signature for bootloader. */ #define GRUB_BOOT_MACHINE_SIGNATURE 0xaa55 @@ -57,9 +60,6 @@ floppy. */ #define GRUB_BOOT_MACHINE_BIOS_HD_FLAG 0x80 -/* The segment where the kernel is loaded. */ -#define GRUB_BOOT_MACHINE_KERNEL_SEG 0x800 - /* The address where the kernel is loaded. */ #define GRUB_BOOT_MACHINE_KERNEL_ADDR (GRUB_BOOT_MACHINE_KERNEL_SEG << 4) @@ -68,16 +68,7 @@ #define GRUB_BOOT_MACHINE_PXE_DL 0x7f -#ifndef ASM_FILE - /* This is the blocklist used in the diskboot image. */ -struct grub_boot_blocklist -{ - grub_uint64_t start; - grub_uint16_t len; - grub_uint16_t segment; -} __attribute__ ((packed)); - -#endif /* ! ASM_FILE */ +#define grub_boot_blocklist grub_pc_bios_boot_blocklist #endif /* ! BOOT_MACHINE_HEADER */ diff --git a/include/grub/i386/pc/kernel.h b/include/grub/i386/pc/kernel.h index e830afae2..77d5c6e5a 100644 --- a/include/grub/i386/pc/kernel.h +++ b/include/grub/i386/pc/kernel.h @@ -19,29 +19,9 @@ #ifndef KERNEL_MACHINE_HEADER #define KERNEL_MACHINE_HEADER 1 -/* The offset of GRUB_TOTAL_MODULE_SIZE. */ -#define GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE 0x8 +#define MACHINE I386_PC -/* The offset of GRUB_KERNEL_IMAGE_SIZE. */ -#define GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE 0xc - -/* The offset of GRUB_COMPRESSED_SIZE. */ -#define GRUB_KERNEL_MACHINE_COMPRESSED_SIZE 0x10 - -/* The offset of GRUB_INSTALL_DOS_PART. */ -#define GRUB_KERNEL_MACHINE_INSTALL_DOS_PART 0x14 - -/* The offset of GRUB_INSTALL_BSD_PART. */ -#define GRUB_KERNEL_MACHINE_INSTALL_BSD_PART 0x18 - -/* The offset of GRUB_PREFIX. */ -#define GRUB_KERNEL_MACHINE_PREFIX 0x1c - -/* End of the data section. */ -#define GRUB_KERNEL_MACHINE_DATA_END 0x5c - -/* The size of the first region which won't be compressed. */ -#define GRUB_KERNEL_MACHINE_RAW_SIZE (GRUB_KERNEL_MACHINE_DATA_END + 0x5F0) +#include /* Enable LZMA compression */ #define ENABLE_LZMA 1 diff --git a/include/grub/i386/pc/memory.h b/include/grub/i386/pc/memory.h index 841b06164..0b4191734 100644 --- a/include/grub/i386/pc/memory.h +++ b/include/grub/i386/pc/memory.h @@ -29,6 +29,9 @@ #include +#define MACHINE I386_PC +#include + /* The scratch buffer used in real mode code. */ #define GRUB_MEMORY_MACHINE_SCRATCH_ADDR 0x68000 #define GRUB_MEMORY_MACHINE_SCRATCH_SEG (GRUB_MEMORY_MACHINE_SCRATCH_ADDR >> 4) @@ -40,9 +43,6 @@ /* The size of the protect mode stack. */ #define GRUB_MEMORY_MACHINE_PROT_STACK_SIZE 0x8000 -/* The upper memory area (starting at 640 kiB). */ -#define GRUB_MEMORY_MACHINE_UPPER 0xa0000 - /* The protected mode stack. */ #define GRUB_MEMORY_MACHINE_PROT_STACK \ (GRUB_MEMORY_MACHINE_SCRATCH_ADDR + GRUB_MEMORY_MACHINE_SCRATCH_SIZE \ diff --git a/include/grub/i386/qemu/boot.h b/include/grub/i386/qemu/boot.h index 6fbb57750..5f53eabfb 100644 --- a/include/grub/i386/qemu/boot.h +++ b/include/grub/i386/qemu/boot.h @@ -22,7 +22,4 @@ /* The size of boot.img. */ #define GRUB_BOOT_MACHINE_SIZE (0x100000 - GRUB_BOOT_MACHINE_LINK_ADDR) -/* The offset of GRUB_CORE_ENTRY_ADDR. */ -#define GRUB_BOOT_MACHINE_CORE_ENTRY_ADDR 0x4 - #endif diff --git a/include/grub/i386/qemu/kernel.h b/include/grub/i386/qemu/kernel.h index bc0b93d4f..3d22c9d9f 100644 --- a/include/grub/i386/qemu/kernel.h +++ b/include/grub/i386/qemu/kernel.h @@ -19,9 +19,6 @@ #ifndef GRUB_KERNEL_MACHINE_HEADER #define GRUB_KERNEL_MACHINE_HEADER 1 -/* The offset of GRUB_CORE_ENTRY_ADDR. */ -#define GRUB_KERNEL_MACHINE_CORE_ENTRY_ADDR 0x8 - /* The offset of GRUB_KERNEL_IMAGE_SIZE. */ #define GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE 0xc diff --git a/include/grub/sparc64/ieee1275/boot.h b/include/grub/sparc64/ieee1275/boot.h index 9671c6900..bd0a7bf3c 100644 --- a/include/grub/sparc64/ieee1275/boot.h +++ b/include/grub/sparc64/ieee1275/boot.h @@ -50,10 +50,6 @@ #define GRUB_BOOT_MACHINE_CODE_END \ (0x1fc - GRUB_BOOT_AOUT_HEADER_SIZE) -#define GRUB_BOOT_MACHINE_LIST_SIZE 12 - -#define GRUB_BOOT_MACHINE_IMAGE_ADDRESS 0x4400 - #define GRUB_BOOT_MACHINE_KERNEL_ADDR 0x4200 #endif /* ! BOOT_MACHINE_HEADER */ diff --git a/include/grub/sparc64/ieee1275/kernel.h b/include/grub/sparc64/ieee1275/kernel.h index a16fb88e7..2948a8d2f 100644 --- a/include/grub/sparc64/ieee1275/kernel.h +++ b/include/grub/sparc64/ieee1275/kernel.h @@ -42,21 +42,8 @@ #define GRUB_KERNEL_MACHINE_RAW_SIZE 0 #define GRUB_KERNEL_MACHINE_STACK_SIZE 0x40000 -#define GRUB_PLATFORM_IMAGE_FORMATS "raw, aout" -#define GRUB_PLATFORM_IMAGE_DEFAULT_FORMAT "raw" - -#define GRUB_PLATFORM_IMAGE_DEFAULT GRUB_PLATFORM_IMAGE_RAW - #ifndef ASM_FILE -typedef enum { - GRUB_PLATFORM_IMAGE_RAW, - GRUB_PLATFORM_IMAGE_AOUT -} - grub_platform_image_format_t; -#define GRUB_PLATFORM_IMAGE_RAW GRUB_PLATFORM_IMAGE_RAW -#define GRUB_PLATFORM_IMAGE_AOUT GRUB_PLATFORM_IMAGE_AOUT - #include #include diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index 71376eaee..af2988a3f 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -19,9 +19,6 @@ #include #include -#include -#include -#include #include #include #include @@ -30,6 +27,7 @@ #include #include #include +#include #include #include @@ -44,7 +42,144 @@ #include "progname.h" -#define ALIGN_ADDR(x) (ALIGN_UP((x), GRUB_TARGET_SIZEOF_VOID_P)) +#define ALIGN_ADDR(x) (ALIGN_UP((x), image_target->voidp_sizeof)) + +#define TARGET_NO_FIELD 0xffffffff +struct image_target_desc +{ + const char *name; + grub_size_t voidp_sizeof; + int bigendian; + enum { + IMAGE_I386_PC, IMAGE_EFI, IMAGE_COREBOOT, + IMAGE_SPARC64_AOUT, IMAGE_SPARC64_RAW, IMAGE_I386_IEEE1275, + IMAGE_YEELOONG_ELF, IMAGE_QEMU, IMAGE_PPC + } id; + enum {FORMAT_RAW, FORMAT_AOUT, FORMAT_ELF, FORMAT_PE} format; + enum + { + PLATFORM_FLAGS_NONE = 0, + PLATFORM_FLAGS_LZMA = 1 + } flags; + unsigned prefix; + unsigned data_end; + unsigned raw_size; + unsigned total_module_size; + unsigned kernel_image_size; + unsigned compressed_size; + unsigned link_align; + grub_uint16_t elf_target; + unsigned section_align; + signed vaddr_offset; + unsigned install_dos_part, install_bsd_part; +}; + +struct image_target_desc image_targets[] = + { + {"i386-coreboot", 4, 0, IMAGE_COREBOOT, FORMAT_ELF, PLATFORM_FLAGS_NONE, + .section_align = 1, + .vaddr_offset = 0 + }, + {"i386-pc", 4, 0, IMAGE_I386_PC, FORMAT_RAW, PLATFORM_FLAGS_LZMA, + GRUB_KERNEL_I386_PC_PREFIX, GRUB_KERNEL_I386_PC_DATA_END, + GRUB_KERNEL_I386_PC_RAW_SIZE, GRUB_KERNEL_I386_PC_TOTAL_MODULE_SIZE, + GRUB_KERNEL_I386_PC_KERNEL_IMAGE_SIZE, GRUB_KERNEL_I386_PC_COMPRESSED_SIZE, + .section_align = 1, + .vaddr_offset = 0, + GRUB_KERNEL_I386_PC_INSTALL_DOS_PART, GRUB_KERNEL_I386_PC_INSTALL_BSD_PART + }, + {"i386-efi", 4, 0, IMAGE_EFI, FORMAT_PE, PLATFORM_FLAGS_NONE, + .section_align = GRUB_PE32_SECTION_ALIGNMENT, + .vaddr_offset = ALIGN_UP (sizeof (struct grub_pe32_header) + + 5 * sizeof (struct grub_pe32_section_table), + GRUB_PE32_SECTION_ALIGNMENT) + }, + {"i386-ieee1275", 4, 0, IMAGE_I386_IEEE1275, FORMAT_ELF, PLATFORM_FLAGS_NONE, + .section_align = 1, + .vaddr_offset = 0}, + {"i386-qemu", 4, 0, IMAGE_QEMU, FORMAT_RAW, PLATFORM_FLAGS_NONE, + .section_align = 1, + .vaddr_offset = 0}, + {"x86_64-efi", 8, 0, IMAGE_EFI, FORMAT_PE, PLATFORM_FLAGS_NONE, + .section_align = GRUB_PE32_SECTION_ALIGNMENT, + .vaddr_offset = ALIGN_UP (sizeof (struct grub_pe32_header) + + 5 * sizeof (struct grub_pe32_section_table), + GRUB_PE32_SECTION_ALIGNMENT) + }, + {"mipsel-yeeloong-elf", 4, 0, IMAGE_YEELOONG_ELF, FORMAT_ELF, PLATFORM_FLAGS_NONE, + .section_align = 1, + .vaddr_offset = 0}, + {"powerpc-ieee1275", 4, 1, IMAGE_PPC, FORMAT_ELF, PLATFORM_FLAGS_NONE, + .section_align = 1, + .vaddr_offset = 0}, + {"sparc64-ieee1275-raw", 8, 1, IMAGE_SPARC64_RAW, + FORMAT_RAW, PLATFORM_FLAGS_NONE, + .section_align = 1, + .vaddr_offset = 0}, + {"sparc64-ieee1275-aout", 8, 1, IMAGE_SPARC64_AOUT, + FORMAT_AOUT, PLATFORM_FLAGS_NONE, + .section_align = 1, + .vaddr_offset = 0}, + }; + +#define grub_target_to_host32(x) (grub_target_to_host32_real (image_target, (x))) +#define grub_host_to_target32(x) (grub_host_to_target32_real (image_target, (x))) +#define grub_target_to_host16(x) (grub_target_to_host16_real (image_target, (x))) +#define grub_host_to_target16(x) (grub_host_to_target16_real (image_target, (x))) + +static inline grub_uint32_t +grub_target_to_host32_real (struct image_target_desc *image_target, grub_uint32_t in) +{ + if (image_target->bigendian) + return grub_be_to_cpu32 (in); + else + return grub_le_to_cpu32 (in); +} + +static inline grub_uint64_t +grub_target_to_host64_real (struct image_target_desc *image_target, grub_uint64_t in) +{ + if (image_target->bigendian) + return grub_be_to_cpu64 (in); + else + return grub_le_to_cpu64 (in); +} + +static inline grub_uint32_t +grub_target_to_host_real (struct image_target_desc *image_target, grub_uint32_t in) +{ + if (image_target->voidp_sizeof == 8) + return grub_target_to_host64_real (image_target, in); + else + return grub_target_to_host32_real (image_target, in); +} + +static inline grub_uint32_t +grub_host_to_target32_real (struct image_target_desc *image_target, grub_uint32_t in) +{ + if (image_target->bigendian) + return grub_cpu_to_be32 (in); + else + return grub_cpu_to_le32 (in); +} + +static inline grub_uint16_t +grub_target_to_host16_real (struct image_target_desc *image_target, grub_uint16_t in) +{ + if (image_target->bigendian) + return grub_be_to_cpu16 (in); + else + return grub_le_to_cpu16 (in); +} + +static inline grub_uint16_t +grub_host_to_target16_real (struct image_target_desc *image_target, grub_uint16_t in) +{ + if (image_target->bigendian) + return grub_cpu_to_be16 (in); + else + return grub_cpu_to_le16 (in); +} #define GRUB_IEEE1275_NOTE_NAME "PowerPC" #define GRUB_IEEE1275_NOTE_TYPE 0x1275 @@ -76,21 +211,8 @@ struct grub_ieee1275_note struct grub_ieee1275_note_desc descriptor; }; -#ifdef GRUB_MACHINE_EFI -#define SECTION_ALIGN GRUB_PE32_SECTION_ALIGNMENT -#define VADDR_OFFSET ALIGN_UP (sizeof (struct grub_pe32_header) + 5 * sizeof (struct grub_pe32_section_table), SECTION_ALIGN) -#else -#define SECTION_ALIGN 1 -#define VADDR_OFFSET 0 -#endif +#define grub_target_to_host(val) grub_target_to_host_real(image_target, (val)) -#if GRUB_TARGET_WORDSIZE == 32 -# define grub_target_to_host(val) grub_target_to_host32(val) -#elif GRUB_TARGET_WORDSIZE == 64 -# define grub_target_to_host(val) grub_target_to_host64(val) -#endif - -#ifdef ENABLE_LZMA #include static void *SzAlloc(void *p, size_t size) { p = p; return xmalloc(size); } @@ -98,8 +220,8 @@ static void SzFree(void *p, void *address) { p = p; free(address); } static ISzAlloc g_Alloc = { SzAlloc, SzFree }; static void -compress_kernel (char *kernel_img, size_t kernel_size, - char **core_img, size_t *core_size) +compress_kernel_lzma (char *kernel_img, size_t kernel_size, + char **core_img, size_t *core_size, size_t raw_size) { CLzmaEncProps props; unsigned char out_props[5]; @@ -112,45 +234,47 @@ compress_kernel (char *kernel_img, size_t kernel_size, props.pb = 2; props.numThreads = 1; - if (kernel_size < GRUB_KERNEL_MACHINE_RAW_SIZE) + if (kernel_size < raw_size) grub_util_error (_("the core image is too small")); *core_img = xmalloc (kernel_size); - memcpy (*core_img, kernel_img, GRUB_KERNEL_MACHINE_RAW_SIZE); + memcpy (*core_img, kernel_img, raw_size); - *core_size = kernel_size - GRUB_KERNEL_MACHINE_RAW_SIZE; - if (LzmaEncode((unsigned char *) *core_img + GRUB_KERNEL_MACHINE_RAW_SIZE, - core_size, - (unsigned char *) kernel_img + GRUB_KERNEL_MACHINE_RAW_SIZE, - kernel_size - GRUB_KERNEL_MACHINE_RAW_SIZE, - &props, out_props, &out_props_size, - 0, NULL, &g_Alloc, &g_Alloc) != SZ_OK) + *core_size = kernel_size - raw_size; + if (LzmaEncode ((unsigned char *) *core_img + raw_size, core_size, + (unsigned char *) kernel_img + raw_size, + kernel_size - raw_size, + &props, out_props, &out_props_size, + 0, NULL, &g_Alloc, &g_Alloc) != SZ_OK) grub_util_error (_("cannot compress the kernel image")); - *core_size += GRUB_KERNEL_MACHINE_RAW_SIZE; + *core_size += raw_size; } -#else /* No lzma compression */ - static void -compress_kernel (char *kernel_img, size_t kernel_size, - char **core_img, size_t *core_size) +compress_kernel (struct image_target_desc *image_target, char *kernel_img, + size_t kernel_size, char **core_img, size_t *core_size) { + if (image_target->flags & PLATFORM_FLAGS_LZMA) + { + compress_kernel_lzma (kernel_img, kernel_size, core_img, + core_size, image_target->raw_size); + return; + } + *core_img = xmalloc (kernel_size); memcpy (*core_img, kernel_img, kernel_size); *core_size = kernel_size; } -#endif /* No lzma compression */ - -#ifdef GRUB_MACHINE_EFI /* Relocate symbols; note that this function overwrites the symbol table. Return the address of a start symbol. */ static Elf_Addr relocate_symbols (Elf_Ehdr *e, Elf_Shdr *sections, Elf_Shdr *symtab_section, Elf_Addr *section_addresses, - Elf_Half section_entsize, Elf_Half num_sections) + Elf_Half section_entsize, Elf_Half num_sections, + struct image_target_desc *image_target) { Elf_Word symtab_size, sym_size, num_syms; Elf_Off symtab_offset; @@ -209,7 +333,8 @@ relocate_symbols (Elf_Ehdr *e, Elf_Shdr *sections, /* Return the address of a symbol at the index I in the section S. */ static Elf_Addr -get_symbol_address (Elf_Ehdr *e, Elf_Shdr *s, Elf_Word i) +get_symbol_address (Elf_Ehdr *e, Elf_Shdr *s, Elf_Word i, + struct image_target_desc *image_target) { Elf_Sym *sym; @@ -221,7 +346,8 @@ get_symbol_address (Elf_Ehdr *e, Elf_Shdr *s, Elf_Word i) /* Return the address of a modified value. */ static Elf_Addr * -get_target_address (Elf_Ehdr *e, Elf_Shdr *s, Elf_Addr offset) +get_target_address (Elf_Ehdr *e, Elf_Shdr *s, Elf_Addr offset, + struct image_target_desc *image_target) { return (Elf_Addr *) ((char *) e + grub_target_to_host32 (s->sh_offset) + offset); } @@ -234,7 +360,7 @@ static void relocate_addresses (Elf_Ehdr *e, Elf_Shdr *sections, Elf_Addr *section_addresses, Elf_Half section_entsize, Elf_Half num_sections, - const char *strtab) + const char *strtab, struct image_target_desc *image_target) { Elf_Half i; Elf_Shdr *s; @@ -283,79 +409,84 @@ relocate_addresses (Elf_Ehdr *e, Elf_Shdr *sections, Elf_Addr addend; offset = grub_target_to_host (r->r_offset); - target = get_target_address (e, target_section, offset); + target = get_target_address (e, target_section, offset, image_target); info = grub_target_to_host (r->r_info); sym_addr = get_symbol_address (e, symtab_section, - ELF_R_SYM (info)); + ELF_R_SYM (info), image_target); addend = (s->sh_type == grub_target_to_host32 (SHT_RELA)) ? r->r_addend : 0; - switch (ELF_R_TYPE (info)) - { -#if GRUB_TARGET_SIZEOF_VOID_P == 4 - case R_386_NONE: - break; + if (image_target->voidp_sizeof == 4) + switch (ELF_R_TYPE (info)) + { + case R_386_NONE: + break; - case R_386_32: - /* This is absolute. */ - *target = grub_host_to_target32 (grub_target_to_host32 (*target) - + addend + sym_addr); - grub_util_info ("relocating an R_386_32 entry to 0x%x at the offset 0x%x", - *target, offset); - break; + case R_386_32: + /* This is absolute. */ + *target = grub_host_to_target32 (grub_target_to_host32 (*target) + + addend + sym_addr); + grub_util_info ("relocating an R_386_32 entry to 0x%x at the offset 0x%x", + *target, offset); + break; - case R_386_PC32: - /* This is relative. */ - *target = grub_host_to_target32 (grub_target_to_host32 (*target) - + addend + sym_addr - - target_section_addr - offset - - VADDR_OFFSET); - grub_util_info ("relocating an R_386_PC32 entry to 0x%x at the offset 0x%x", - *target, offset); - break; + case R_386_PC32: + /* This is relative. */ + *target = grub_host_to_target32 (grub_target_to_host32 (*target) + + addend + sym_addr + - target_section_addr - offset + - image_target->vaddr_offset); + grub_util_info ("relocating an R_386_PC32 entry to 0x%x at the offset 0x%x", + *target, offset); + break; + default: + grub_util_error ("unknown relocation type %d", + ELF_R_TYPE (info)); + break; + } + else + switch (ELF_R_TYPE (info)) + { -#else + case R_X86_64_NONE: + break; - case R_X86_64_NONE: - break; + case R_X86_64_64: + *target = grub_host_to_target64 (grub_target_to_host64 (*target) + + addend + sym_addr); + grub_util_info ("relocating an R_X86_64_64 entry to 0x%llx at the offset 0x%llx", + *target, offset); + break; - case R_X86_64_64: - *target = grub_host_to_target64 (grub_target_to_host64 (*target) - + addend + sym_addr); - grub_util_info ("relocating an R_X86_64_64 entry to 0x%llx at the offset 0x%llx", - *target, offset); - break; + case R_X86_64_PC32: + { + grub_uint32_t *t32 = (grub_uint32_t *) target; + *t32 = grub_host_to_target64 (grub_target_to_host32 (*t32) + + addend + sym_addr + - target_section_addr - offset + - image_target->vaddr_offset); + grub_util_info ("relocating an R_X86_64_PC32 entry to 0x%x at the offset 0x%llx", + *t32, offset); + break; + } - case R_X86_64_PC32: - { - grub_uint32_t *t32 = (grub_uint32_t *) target; - *t32 = grub_host_to_target64 (grub_target_to_host32 (*t32) - + addend + sym_addr - - target_section_addr - offset - - VADDR_OFFSET); - grub_util_info ("relocating an R_X86_64_PC32 entry to 0x%x at the offset 0x%llx", - *t32, offset); - break; - } + case R_X86_64_32: + case R_X86_64_32S: + { + grub_uint32_t *t32 = (grub_uint32_t *) target; + *t32 = grub_host_to_target64 (grub_target_to_host32 (*t32) + + addend + sym_addr); + grub_util_info ("relocating an R_X86_64_32(S) entry to 0x%x at the offset 0x%llx", + *t32, offset); + break; + } - case R_X86_64_32: - case R_X86_64_32S: - { - grub_uint32_t *t32 = (grub_uint32_t *) target; - *t32 = grub_host_to_target64 (grub_target_to_host32 (*t32) - + addend + sym_addr); - grub_util_info ("relocating an R_X86_64_32(S) entry to 0x%x at the offset 0x%llx", - *t32, offset); - break; - } - -#endif - default: - grub_util_error ("unknown relocation type %d", - ELF_R_TYPE (info)); - break; - } + default: + grub_util_error ("unknown relocation type %d", + ELF_R_TYPE (info)); + break; + } } } } @@ -371,7 +502,8 @@ struct fixup_block_list after having written to the file OUT. */ Elf_Addr add_fixup_entry (struct fixup_block_list **cblock, grub_uint16_t type, - Elf_Addr addr, int flush, Elf_Addr current_address) + Elf_Addr addr, int flush, Elf_Addr current_address, + struct image_target_desc *image_target) { struct grub_pe32_fixup_block *b; @@ -393,7 +525,7 @@ add_fixup_entry (struct fixup_block_list **cblock, grub_uint16_t type, size_t index; next_address = current_address + b->block_size; - padding_size = ((ALIGN_UP (next_address, SECTION_ALIGN) + padding_size = ((ALIGN_UP (next_address, image_target->section_align) - next_address) >> 1); index = ((b->block_size - sizeof (*b)) >> 1); @@ -466,7 +598,7 @@ static Elf_Addr make_reloc_section (Elf_Ehdr *e, void **out, Elf_Addr *section_addresses, Elf_Shdr *sections, Elf_Half section_entsize, Elf_Half num_sections, - const char *strtab) + const char *strtab, struct image_target_desc *image_target) { Elf_Half i; Elf_Shdr *s; @@ -509,39 +641,44 @@ make_reloc_section (Elf_Ehdr *e, void **out, info = grub_le_to_cpu32 (r->r_info); /* Necessary to relocate only absolute addresses. */ -#if GRUB_TARGET_SIZEOF_VOID_P == 4 - if (ELF_R_TYPE (info) == R_386_32) + if (image_target->voidp_sizeof == 4) { - Elf_Addr addr; + if (ELF_R_TYPE (info) == R_386_32) + { + Elf_Addr addr; - addr = section_address + offset; - grub_util_info ("adding a relocation entry for 0x%x", addr); - current_address = add_fixup_entry (&lst, - GRUB_PE32_REL_BASED_HIGHLOW, - addr, 0, current_address); + addr = section_address + offset; + grub_util_info ("adding a relocation entry for 0x%x", addr); + current_address = add_fixup_entry (&lst, + GRUB_PE32_REL_BASED_HIGHLOW, + addr, 0, current_address, + image_target); + } } -#else - if ((ELF_R_TYPE (info) == R_X86_64_32) || - (ELF_R_TYPE (info) == R_X86_64_32S)) + else { - grub_util_error ("can\'t add fixup entry for R_X86_64_32(S)"); - } - else if (ELF_R_TYPE (info) == R_X86_64_64) - { - Elf_Addr addr; + if ((ELF_R_TYPE (info) == R_X86_64_32) || + (ELF_R_TYPE (info) == R_X86_64_32S)) + { + grub_util_error ("can\'t add fixup entry for R_X86_64_32(S)"); + } + else if (ELF_R_TYPE (info) == R_X86_64_64) + { + Elf_Addr addr; - addr = section_address + offset; - grub_util_info ("adding a relocation entry for 0x%llx", addr); - current_address = add_fixup_entry (&lst, - GRUB_PE32_REL_BASED_DIR64, - addr, - 0, current_address); + addr = section_address + offset; + grub_util_info ("adding a relocation entry for 0x%llx", addr); + current_address = add_fixup_entry (&lst, + GRUB_PE32_REL_BASED_DIR64, + addr, + 0, current_address, + image_target); + } } -#endif } } - current_address = add_fixup_entry (&lst, 0, 0, 1, current_address); + current_address = add_fixup_entry (&lst, 0, 0, 1, current_address, image_target); { grub_uint8_t *ptr; @@ -562,17 +699,14 @@ make_reloc_section (Elf_Ehdr *e, void **out, return current_address; } -#endif - /* Determine if this section is a text section. Return false if this section is not allocated. */ static int -is_text_section (Elf_Shdr *s) +is_text_section (Elf_Shdr *s, struct image_target_desc *image_target) { -#ifndef GRUB_MACHINE_EFI - if (grub_target_to_host32 (s->sh_type) != SHT_PROGBITS) + if (image_target->id != IMAGE_EFI + && grub_target_to_host32 (s->sh_type) != SHT_PROGBITS) return 0; -#endif return ((grub_target_to_host32 (s->sh_flags) & (SHF_EXECINSTR | SHF_ALLOC)) == (SHF_EXECINSTR | SHF_ALLOC)); } @@ -581,12 +715,11 @@ is_text_section (Elf_Shdr *s) BSS is also a data section, since the converter initializes BSS when producing PE32 to avoid a bug in EFI implementations. */ static int -is_data_section (Elf_Shdr *s) +is_data_section (Elf_Shdr *s, struct image_target_desc *image_target) { -#ifndef GRUB_MACHINE_EFI - if (grub_target_to_host32 (s->sh_type) != SHT_PROGBITS) + if (image_target->id != IMAGE_EFI + && grub_target_to_host32 (s->sh_type) != SHT_PROGBITS) return 0; -#endif return ((grub_target_to_host32 (s->sh_flags) & (SHF_EXECINSTR | SHF_ALLOC)) == SHF_ALLOC); } @@ -597,7 +730,8 @@ is_data_section (Elf_Shdr *s) static Elf_Addr * locate_sections (Elf_Shdr *sections, Elf_Half section_entsize, Elf_Half num_sections, const char *strtab, - grub_size_t *exec_size, grub_size_t *kernel_sz) + grub_size_t *exec_size, grub_size_t *kernel_sz, + struct image_target_desc *image_target) { int i; Elf_Addr current_address; @@ -613,14 +747,14 @@ locate_sections (Elf_Shdr *sections, Elf_Half section_entsize, for (i = 0, s = sections; i < num_sections; i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if (is_text_section (s)) + if (is_text_section (s, image_target)) { Elf_Word align = grub_host_to_target32 (s->sh_addralign); const char *name = strtab + grub_host_to_target32 (s->sh_name); if (align) - current_address = ALIGN_UP (current_address + VADDR_OFFSET, align) - - VADDR_OFFSET; + current_address = ALIGN_UP (current_address + image_target->vaddr_offset, + align) - image_target->vaddr_offset; grub_util_info ("locating the section %s at 0x%x", name, current_address); @@ -628,22 +762,24 @@ locate_sections (Elf_Shdr *sections, Elf_Half section_entsize, current_address += grub_host_to_target32 (s->sh_size); } - current_address = ALIGN_UP (current_address + VADDR_OFFSET, SECTION_ALIGN) - - VADDR_OFFSET; + current_address = ALIGN_UP (current_address + image_target->vaddr_offset, + image_target->section_align) + - image_target->vaddr_offset; *exec_size = current_address; /* .data */ for (i = 0, s = sections; i < num_sections; i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if (is_data_section (s)) + if (is_data_section (s, image_target)) { Elf_Word align = grub_host_to_target32 (s->sh_addralign); const char *name = strtab + grub_host_to_target32 (s->sh_name); if (align) - current_address = ALIGN_UP (current_address + VADDR_OFFSET, align) - - VADDR_OFFSET; + current_address = ALIGN_UP (current_address + image_target->vaddr_offset, + align) + - image_target->vaddr_offset; grub_util_info ("locating the section %s at 0x%x", name, current_address); @@ -651,15 +787,15 @@ locate_sections (Elf_Shdr *sections, Elf_Half section_entsize, current_address += grub_host_to_target32 (s->sh_size); } - current_address = ALIGN_UP (current_address + VADDR_OFFSET, SECTION_ALIGN) - - VADDR_OFFSET; + current_address = ALIGN_UP (current_address + image_target->vaddr_offset, + image_target->section_align) - image_target->vaddr_offset; *kernel_sz = current_address; return section_addresses; } /* Return if the ELF header is valid. */ static int -check_elf_header (Elf_Ehdr *e, size_t size) +check_elf_header (Elf_Ehdr *e, size_t size, struct image_target_desc *image_target) { if (size < sizeof (*e) || e->e_ident[EI_MAG0] != ELFMAG0 @@ -677,7 +813,8 @@ static char * load_image (const char *kernel_path, grub_size_t *exec_size, grub_size_t *kernel_sz, grub_size_t *bss_size, grub_size_t total_module_size, Elf_Addr *start, - void **reloc_section, grub_size_t *reloc_size) + void **reloc_section, grub_size_t *reloc_size, + struct image_target_desc *image_target) { char *kernel_img, *out_img; const char *strtab; @@ -700,7 +837,7 @@ load_image (const char *kernel_path, grub_size_t *exec_size, grub_util_load_image (kernel_path, kernel_img); e = (Elf_Ehdr *) kernel_img; - if (! check_elf_header (e, kernel_size)) + if (! check_elf_header (e, kernel_size, image_target)) grub_util_error ("invalid ELF header"); section_offset = grub_target_to_host32 (e->e_shoff); @@ -719,85 +856,86 @@ load_image (const char *kernel_path, grub_size_t *exec_size, section_addresses = locate_sections (sections, section_entsize, num_sections, strtab, - exec_size, kernel_sz); + exec_size, kernel_sz, image_target); -#ifdef GRUB_MACHINE_EFI - { - section_vaddresses = xmalloc (sizeof (*section_addresses) * num_sections); + if (image_target->id == IMAGE_EFI) + { + section_vaddresses = xmalloc (sizeof (*section_addresses) * num_sections); - for (i = 0; i < num_sections; i++) - section_vaddresses[i] = section_addresses[i] + VADDR_OFFSET; + for (i = 0; i < num_sections; i++) + section_vaddresses[i] = section_addresses[i] + image_target->vaddr_offset; #if 0 - { - Elf_Addr current_address = *kernel_sz; + { + Elf_Addr current_address = *kernel_sz; + for (i = 0, s = sections; + i < num_sections; + i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + if (grub_target_to_host32 (s->sh_type) == SHT_NOBITS) + { + Elf_Word align = grub_host_to_target32 (s->sh_addralign); + const char *name = strtab + grub_host_to_target32 (s->sh_name); + + if (align) + current_address = ALIGN_UP (current_address + VADDR_OFFSET, align) + - VADDR_OFFSET; + + grub_util_info ("locating the section %s at 0x%x", + name, current_address); + section_vaddresses[i] = current_address + VADDR_OFFSET; + current_address += grub_host_to_target32 (s->sh_size); + } + current_address = ALIGN_UP (current_address + VADDR_OFFSET, SECTION_ALIGN) + - VADDR_OFFSET; + *bss_size = current_address - *kernel_sz; + } +#else + *bss_size = 0; +#endif + + symtab_section = NULL; for (i = 0, s = sections; i < num_sections; i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if (grub_target_to_host32 (s->sh_type) == SHT_NOBITS) + if (s->sh_type == grub_host_to_target32 (SHT_SYMTAB)) { - Elf_Word align = grub_host_to_target32 (s->sh_addralign); - const char *name = strtab + grub_host_to_target32 (s->sh_name); - - if (align) - current_address = ALIGN_UP (current_address + VADDR_OFFSET, align) - - VADDR_OFFSET; - - grub_util_info ("locating the section %s at 0x%x", - name, current_address); - section_vaddresses[i] = current_address + VADDR_OFFSET; - current_address += grub_host_to_target32 (s->sh_size); + symtab_section = s; + break; } - current_address = ALIGN_UP (current_address + VADDR_OFFSET, SECTION_ALIGN) - - VADDR_OFFSET; - *bss_size = current_address - *kernel_sz; + + if (! symtab_section) + grub_util_error ("no symbol table"); + + *start = relocate_symbols (e, sections, symtab_section, + section_vaddresses, section_entsize, + num_sections, image_target); + if (*start == 0) + grub_util_error ("start symbol is not defined"); + + /* Resolve addresses in the virtual address space. */ + relocate_addresses (e, sections, section_addresses, section_entsize, + num_sections, strtab, image_target); + + *reloc_size = make_reloc_section (e, reloc_section, + section_vaddresses, sections, + section_entsize, num_sections, + strtab, image_target); + + } + else + { + *bss_size = 0; + *reloc_size = 0; + *reloc_section = NULL; } -#else - *bss_size = 0; -#endif - - symtab_section = NULL; - for (i = 0, s = sections; - i < num_sections; - i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if (s->sh_type == grub_host_to_target32 (SHT_SYMTAB)) - { - symtab_section = s; - break; - } - - if (! symtab_section) - grub_util_error ("no symbol table"); - - *start = relocate_symbols (e, sections, symtab_section, - section_vaddresses, section_entsize, - num_sections); - if (*start == 0) - grub_util_error ("start symbol is not defined"); - - /* Resolve addresses in the virtual address space. */ - relocate_addresses (e, sections, section_addresses, section_entsize, - num_sections, strtab); - - *reloc_size = make_reloc_section (e, reloc_section, - section_vaddresses, sections, - section_entsize, num_sections, - strtab); - - } -#else - *bss_size = 0; - *reloc_size = 0; - *reloc_section = NULL; -#endif out_img = xmalloc (*kernel_sz + total_module_size); for (i = 0, s = sections; i < num_sections; i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if (is_data_section (s) || is_text_section (s)) + if (is_data_section (s, image_target) || is_text_section (s, image_target)) { if (grub_target_to_host32 (s->sh_type) == SHT_NOBITS) memset (out_img + section_addresses[i], 0, @@ -815,13 +953,7 @@ load_image (const char *kernel_path, grub_size_t *exec_size, static void generate_image (const char *dir, char *prefix, FILE *out, char *mods[], char *memdisk_path, char *font_path, char *config_path, -#ifdef GRUB_PLATFORM_IMAGE_DEFAULT - grub_platform_image_format_t format, -#else - int dummy __attribute__ ((unused)), -#endif - int note -) + struct image_target_desc *image_target, int note) { char *kernel_img, *core_img; size_t kernel_size, total_module_size, core_size, exec_size; @@ -869,11 +1001,11 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], kernel_img = load_image (kernel_path, &exec_size, &kernel_size, &bss_size, total_module_size, &start_address, &rel_section, - &reloc_size); + &reloc_size, image_target); - if (GRUB_KERNEL_MACHINE_PREFIX + strlen (prefix) + 1 > GRUB_KERNEL_MACHINE_DATA_END) + if (image_target->prefix + strlen (prefix) + 1 > image_target->data_end) grub_util_error (_("prefix is too long")); - strcpy (kernel_img + GRUB_KERNEL_MACHINE_PREFIX, prefix); + strcpy (kernel_img + image_target->prefix, prefix); /* Fill in the grub_module_info structure. */ modinfo = (struct grub_module_info *) (kernel_img + kernel_size); @@ -946,402 +1078,401 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], } grub_util_info ("kernel_img=%p, kernel_size=0x%x", kernel_img, kernel_size); - compress_kernel (kernel_img, kernel_size + total_module_size, + compress_kernel (image_target, kernel_img, kernel_size + total_module_size, &core_img, &core_size); grub_util_info ("the core size is 0x%x", core_size); -#ifdef GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE - *((grub_uint32_t *) (core_img + GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE)) - = grub_host_to_target32 (total_module_size); -#endif -#ifdef GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE - *((grub_uint32_t *) (core_img + GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE)) - = grub_host_to_target32 (kernel_size); -#endif -#ifdef GRUB_KERNEL_MACHINE_COMPRESSED_SIZE - *((grub_uint32_t *) (core_img + GRUB_KERNEL_MACHINE_COMPRESSED_SIZE)) - = grub_host_to_target32 (core_size - GRUB_KERNEL_MACHINE_RAW_SIZE); -#endif + if (image_target->total_module_size != TARGET_NO_FIELD) + *((grub_uint32_t *) (core_img + image_target->total_module_size)) + = grub_host_to_target32 (total_module_size); + if (image_target->kernel_image_size != TARGET_NO_FIELD) + *((grub_uint32_t *) (core_img + image_target->kernel_image_size)) + = grub_host_to_target32 (kernel_size); + if (image_target->compressed_size != TARGET_NO_FIELD) + *((grub_uint32_t *) (core_img + image_target->compressed_size)) + = grub_host_to_target32 (core_size - image_target->raw_size); -#if defined(GRUB_KERNEL_MACHINE_INSTALL_DOS_PART) && defined(GRUB_KERNEL_MACHINE_INSTALL_BSD_PART) /* If we included a drive in our prefix, let GRUB know it doesn't have to prepend the drive told by BIOS. */ - if (prefix[0] == '(') + if (image_target->install_dos_part != TARGET_NO_FIELD + && image_target->install_bsd_part != TARGET_NO_FIELD && prefix[0] == '(') { - *((grub_int32_t *) (core_img + GRUB_KERNEL_MACHINE_INSTALL_DOS_PART)) + *((grub_int32_t *) (core_img + image_target->install_dos_part)) = grub_host_to_target32 (-2); - *((grub_int32_t *) (core_img + GRUB_KERNEL_MACHINE_INSTALL_BSD_PART)) + *((grub_int32_t *) (core_img + image_target->install_bsd_part)) = grub_host_to_target32 (-2); } -#endif - -#ifdef GRUB_MACHINE_PCBIOS - if (GRUB_KERNEL_MACHINE_LINK_ADDR + core_size > GRUB_MEMORY_MACHINE_UPPER) - grub_util_error (_("core image is too big (%p > %p)"), - GRUB_KERNEL_MACHINE_LINK_ADDR + core_size, - GRUB_MEMORY_MACHINE_UPPER); -#endif - -#if defined(GRUB_MACHINE_PCBIOS) - { - unsigned num; - char *boot_path, *boot_img; - size_t boot_size; - num = ((core_size + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS); - if (num > 0xffff) - grub_util_error (_("the core image is too big")); - - boot_path = grub_util_get_path (dir, "diskboot.img"); - boot_size = grub_util_get_image_size (boot_path); - if (boot_size != GRUB_DISK_SECTOR_SIZE) - grub_util_error (_("diskboot.img size must be %u bytes"), - GRUB_DISK_SECTOR_SIZE); - - boot_img = grub_util_read_image (boot_path); + switch (image_target->id) { - struct grub_boot_blocklist *block; - block = (struct grub_boot_blocklist *) (boot_img - + GRUB_DISK_SECTOR_SIZE - - sizeof (*block)); - block->len = grub_host_to_target16 (num); + case IMAGE_I386_PC: + { + unsigned num; + char *boot_path, *boot_img; + size_t boot_size; - /* This is filled elsewhere. Verify it just in case. */ - assert (block->segment - == grub_host_to_target16 (GRUB_BOOT_MACHINE_KERNEL_SEG - + (GRUB_DISK_SECTOR_SIZE >> 4))); - } + if (GRUB_KERNEL_MACHINE_LINK_ADDR + core_size > GRUB_MEMORY_I386_PC_UPPER) + grub_util_error (_("core image is too big (%p > %p)"), + GRUB_KERNEL_MACHINE_LINK_ADDR + core_size, + GRUB_MEMORY_I386_PC_UPPER); - grub_util_write_image (boot_img, boot_size, out); - free (boot_img); - free (boot_path); - } -#elif defined(GRUB_MACHINE_EFI) - { - void *pe_img; - size_t pe_size; - struct grub_pe32_header *header; - struct grub_pe32_coff_header *c; - struct grub_pe32_optional_header *o; - struct grub_pe32_section_table *text_section, *data_section; - struct grub_pe32_section_table *mods_section, *reloc_section; - static const grub_uint8_t stub[] = GRUB_PE32_MSDOS_STUB; - int header_size = ALIGN_UP (sizeof (struct grub_pe32_header) - + 5 * sizeof (struct grub_pe32_section_table), - SECTION_ALIGN); - int reloc_addr = ALIGN_UP (header_size + core_size, SECTION_ALIGN); + num = ((core_size + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS); + if (num > 0xffff) + grub_util_error (_("the core image is too big")); - pe_size = ALIGN_UP (reloc_addr + reloc_size, SECTION_ALIGN); - pe_img = xmalloc (reloc_addr + reloc_size); - memset (pe_img, 0, header_size); - memcpy (pe_img + header_size, core_img, core_size); - memcpy (pe_img + reloc_addr, rel_section, reloc_size); - header = pe_img; + boot_path = grub_util_get_path (dir, "diskboot.img"); + boot_size = grub_util_get_image_size (boot_path); + if (boot_size != GRUB_DISK_SECTOR_SIZE) + grub_util_error (_("diskboot.img size must be %u bytes"), + GRUB_DISK_SECTOR_SIZE); - /* The magic. */ - memcpy (header->msdos_stub, stub, sizeof (header->msdos_stub)); - memcpy (header->signature, "PE\0\0", sizeof (header->signature)); + boot_img = grub_util_read_image (boot_path); - /* The COFF file header. */ - c = &header->coff_header; -#if GRUB_TARGET_SIZEOF_VOID_P == 4 - c->machine = grub_host_to_target16 (GRUB_PE32_MACHINE_I386); -#else - c->machine = grub_host_to_target16 (GRUB_PE32_MACHINE_X86_64); -#endif + { + struct grub_pc_bios_boot_blocklist *block; + block = (struct grub_pc_bios_boot_blocklist *) (boot_img + + GRUB_DISK_SECTOR_SIZE + - sizeof (*block)); + block->len = grub_host_to_target16 (num); - c->num_sections = grub_host_to_target16 (4); - c->time = grub_host_to_target32 (time (0)); - c->optional_header_size = grub_host_to_target16 (sizeof (header->optional_header)); - c->characteristics = grub_host_to_target16 (GRUB_PE32_EXECUTABLE_IMAGE - | GRUB_PE32_LINE_NUMS_STRIPPED -#if GRUB_TARGET_SIZEOF_VOID_P == 4 - | GRUB_PE32_32BIT_MACHINE -#endif - | GRUB_PE32_LOCAL_SYMS_STRIPPED - | GRUB_PE32_DEBUG_STRIPPED); + /* This is filled elsewhere. Verify it just in case. */ + assert (block->segment + == grub_host_to_target16 (GRUB_BOOT_I386_PC_KERNEL_SEG + + (GRUB_DISK_SECTOR_SIZE >> 4))); + } - /* The PE Optional header. */ - o = &header->optional_header; - o->magic = grub_host_to_target16 (GRUB_PE32_PE32_MAGIC); - o->code_size = grub_host_to_target32 (exec_size); - o->data_size = grub_cpu_to_le32 (reloc_addr - exec_size); - o->bss_size = grub_cpu_to_le32 (bss_size); - o->entry_addr = grub_cpu_to_le32 (start_address); - o->code_base = grub_cpu_to_le32 (header_size); -#if GRUB_TARGET_SIZEOF_VOID_P == 4 - o->data_base = grub_host_to_target32 (header_size + exec_size); -#endif - o->image_base = 0; - o->section_alignment = grub_host_to_target32 (SECTION_ALIGN); - o->file_alignment = grub_host_to_target32 (SECTION_ALIGN); - o->image_size = grub_host_to_target32 (pe_size); - o->header_size = grub_host_to_target32 (header_size); - o->subsystem = grub_host_to_target16 (GRUB_PE32_SUBSYSTEM_EFI_APPLICATION); + grub_util_write_image (boot_img, boot_size, out); + free (boot_img); + free (boot_path); + } + break; + case IMAGE_EFI: + { + void *pe_img; + size_t pe_size; + struct grub_pe32_header *header; + struct grub_pe32_coff_header *c; + struct grub_pe32_optional_header *o; + struct grub_pe32_section_table *text_section, *data_section; + struct grub_pe32_section_table *mods_section, *reloc_section; + static const grub_uint8_t stub[] = GRUB_PE32_MSDOS_STUB; + int header_size = ALIGN_UP (sizeof (struct grub_pe32_header) + + 5 * sizeof (struct grub_pe32_section_table), + image_target->section_align); + int reloc_addr = ALIGN_UP (header_size + core_size, image_target->section_align); - /* Do these really matter? */ - o->stack_reserve_size = grub_host_to_target32 (0x10000); - o->stack_commit_size = grub_host_to_target32 (0x10000); - o->heap_reserve_size = grub_host_to_target32 (0x10000); - o->heap_commit_size = grub_host_to_target32 (0x10000); + pe_size = ALIGN_UP (reloc_addr + reloc_size, image_target->section_align); + pe_img = xmalloc (reloc_addr + reloc_size); + memset (pe_img, 0, header_size); + memcpy (pe_img + header_size, core_img, core_size); + memcpy (pe_img + reloc_addr, rel_section, reloc_size); + header = pe_img; + + /* The magic. */ + memcpy (header->msdos_stub, stub, sizeof (header->msdos_stub)); + memcpy (header->signature, "PE\0\0", sizeof (header->signature)); + + /* The COFF file header. */ + c = &header->coff_header; + if (image_target->voidp_sizeof == 4) + c->machine = grub_host_to_target16 (GRUB_PE32_MACHINE_I386); + else + c->machine = grub_host_to_target16 (GRUB_PE32_MACHINE_X86_64); + + c->num_sections = grub_host_to_target16 (4); + c->time = grub_host_to_target32 (time (0)); + c->optional_header_size = grub_host_to_target16 (sizeof (header->optional_header)); + c->characteristics = grub_host_to_target16 (GRUB_PE32_EXECUTABLE_IMAGE + | GRUB_PE32_LINE_NUMS_STRIPPED + | ((image_target->voidp_sizeof == 4) + ? GRUB_PE32_32BIT_MACHINE + : 0) + | GRUB_PE32_LOCAL_SYMS_STRIPPED + | GRUB_PE32_DEBUG_STRIPPED); + + /* The PE Optional header. */ + o = &header->optional_header; + o->magic = grub_host_to_target16 (GRUB_PE32_PE32_MAGIC); + o->code_size = grub_host_to_target32 (exec_size); + o->data_size = grub_cpu_to_le32 (reloc_addr - exec_size); + o->bss_size = grub_cpu_to_le32 (bss_size); + o->entry_addr = grub_cpu_to_le32 (start_address); + o->code_base = grub_cpu_to_le32 (header_size); + if (image_target->voidp_sizeof == 4) + o->data_base = grub_host_to_target32 (header_size + exec_size); + o->image_base = 0; + o->section_alignment = grub_host_to_target32 (image_target->section_align); + o->file_alignment = grub_host_to_target32 (image_target->section_align); + o->image_size = grub_host_to_target32 (pe_size); + o->header_size = grub_host_to_target32 (header_size); + o->subsystem = grub_host_to_target16 (GRUB_PE32_SUBSYSTEM_EFI_APPLICATION); + + /* Do these really matter? */ + o->stack_reserve_size = grub_host_to_target32 (0x10000); + o->stack_commit_size = grub_host_to_target32 (0x10000); + o->heap_reserve_size = grub_host_to_target32 (0x10000); + o->heap_commit_size = grub_host_to_target32 (0x10000); - o->num_data_directories = grub_host_to_target32 (GRUB_PE32_NUM_DATA_DIRECTORIES); + o->num_data_directories = grub_host_to_target32 (GRUB_PE32_NUM_DATA_DIRECTORIES); - o->base_relocation_table.rva = grub_host_to_target32 (reloc_addr); - o->base_relocation_table.size = grub_host_to_target32 (reloc_size); + o->base_relocation_table.rva = grub_host_to_target32 (reloc_addr); + o->base_relocation_table.size = grub_host_to_target32 (reloc_size); - /* The sections. */ - text_section = (struct grub_pe32_section_table *) (header + 1); - strcpy (text_section->name, ".text"); - text_section->virtual_size = grub_cpu_to_le32 (exec_size); - text_section->virtual_address = grub_cpu_to_le32 (header_size); - text_section->raw_data_size = grub_cpu_to_le32 (exec_size); - text_section->raw_data_offset = grub_cpu_to_le32 (header_size); - text_section->characteristics = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_CODE - | GRUB_PE32_SCN_MEM_EXECUTE - | GRUB_PE32_SCN_MEM_READ - | GRUB_PE32_SCN_ALIGN_64BYTES); + /* The sections. */ + text_section = (struct grub_pe32_section_table *) (header + 1); + strcpy (text_section->name, ".text"); + text_section->virtual_size = grub_cpu_to_le32 (exec_size); + text_section->virtual_address = grub_cpu_to_le32 (header_size); + text_section->raw_data_size = grub_cpu_to_le32 (exec_size); + text_section->raw_data_offset = grub_cpu_to_le32 (header_size); + text_section->characteristics = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_CODE + | GRUB_PE32_SCN_MEM_EXECUTE + | GRUB_PE32_SCN_MEM_READ + | GRUB_PE32_SCN_ALIGN_64BYTES); - data_section = text_section + 1; - strcpy (data_section->name, ".data"); - data_section->virtual_size = grub_cpu_to_le32 (kernel_size - exec_size); - data_section->virtual_address = grub_cpu_to_le32 (header_size + exec_size); - data_section->raw_data_size = grub_cpu_to_le32 (kernel_size - exec_size); - data_section->raw_data_offset = grub_cpu_to_le32 (header_size + exec_size); - data_section->characteristics - = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_INITIALIZED_DATA - | GRUB_PE32_SCN_MEM_READ - | GRUB_PE32_SCN_MEM_WRITE - | GRUB_PE32_SCN_ALIGN_64BYTES); + data_section = text_section + 1; + strcpy (data_section->name, ".data"); + data_section->virtual_size = grub_cpu_to_le32 (kernel_size - exec_size); + data_section->virtual_address = grub_cpu_to_le32 (header_size + exec_size); + data_section->raw_data_size = grub_cpu_to_le32 (kernel_size - exec_size); + data_section->raw_data_offset = grub_cpu_to_le32 (header_size + exec_size); + data_section->characteristics + = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_INITIALIZED_DATA + | GRUB_PE32_SCN_MEM_READ + | GRUB_PE32_SCN_MEM_WRITE + | GRUB_PE32_SCN_ALIGN_64BYTES); #if 0 - bss_section = data_section + 1; - strcpy (bss_section->name, ".bss"); - bss_section->virtual_size = grub_cpu_to_le32 (bss_size); - bss_section->virtual_address = grub_cpu_to_le32 (header_size + kernel_size); - bss_section->raw_data_size = 0; - bss_section->raw_data_offset = 0; - bss_section->characteristics - = grub_cpu_to_le32 (GRUB_PE32_SCN_MEM_READ - | GRUB_PE32_SCN_MEM_WRITE - | GRUB_PE32_SCN_ALIGN_64BYTES - | GRUB_PE32_SCN_CNT_INITIALIZED_DATA - | 0x80); + bss_section = data_section + 1; + strcpy (bss_section->name, ".bss"); + bss_section->virtual_size = grub_cpu_to_le32 (bss_size); + bss_section->virtual_address = grub_cpu_to_le32 (header_size + kernel_size); + bss_section->raw_data_size = 0; + bss_section->raw_data_offset = 0; + bss_section->characteristics + = grub_cpu_to_le32 (GRUB_PE32_SCN_MEM_READ + | GRUB_PE32_SCN_MEM_WRITE + | GRUB_PE32_SCN_ALIGN_64BYTES + | GRUB_PE32_SCN_CNT_INITIALIZED_DATA + | 0x80); #endif - mods_section = data_section + 1; - strcpy (mods_section->name, "mods"); - mods_section->virtual_size = grub_cpu_to_le32 (reloc_addr - kernel_size - header_size); - mods_section->virtual_address = grub_cpu_to_le32 (header_size + kernel_size + bss_size); - mods_section->raw_data_size = grub_cpu_to_le32 (reloc_addr - kernel_size - header_size); - mods_section->raw_data_offset = grub_cpu_to_le32 (header_size + kernel_size); - mods_section->characteristics - = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_INITIALIZED_DATA - | GRUB_PE32_SCN_MEM_READ - | GRUB_PE32_SCN_MEM_WRITE - | GRUB_PE32_SCN_ALIGN_64BYTES); + mods_section = data_section + 1; + strcpy (mods_section->name, "mods"); + mods_section->virtual_size = grub_cpu_to_le32 (reloc_addr - kernel_size - header_size); + mods_section->virtual_address = grub_cpu_to_le32 (header_size + kernel_size + bss_size); + mods_section->raw_data_size = grub_cpu_to_le32 (reloc_addr - kernel_size - header_size); + mods_section->raw_data_offset = grub_cpu_to_le32 (header_size + kernel_size); + mods_section->characteristics + = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_INITIALIZED_DATA + | GRUB_PE32_SCN_MEM_READ + | GRUB_PE32_SCN_MEM_WRITE + | GRUB_PE32_SCN_ALIGN_64BYTES); - reloc_section = mods_section + 1; - strcpy (reloc_section->name, ".reloc"); - reloc_section->virtual_size = grub_cpu_to_le32 (reloc_size); - reloc_section->virtual_address = grub_cpu_to_le32 (reloc_addr + bss_size); - reloc_section->raw_data_size = grub_cpu_to_le32 (reloc_size); - reloc_section->raw_data_offset = grub_cpu_to_le32 (reloc_addr); - reloc_section->characteristics - = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_INITIALIZED_DATA - | GRUB_PE32_SCN_MEM_DISCARDABLE - | GRUB_PE32_SCN_MEM_READ); - free (core_img); - core_img = pe_img; - core_size = pe_size; - } -#elif defined(GRUB_MACHINE_QEMU) - { - char *rom_img; - size_t rom_size; - char *boot_path, *boot_img; - size_t boot_size; + reloc_section = mods_section + 1; + strcpy (reloc_section->name, ".reloc"); + reloc_section->virtual_size = grub_cpu_to_le32 (reloc_size); + reloc_section->virtual_address = grub_cpu_to_le32 (reloc_addr + bss_size); + reloc_section->raw_data_size = grub_cpu_to_le32 (reloc_size); + reloc_section->raw_data_offset = grub_cpu_to_le32 (reloc_addr); + reloc_section->characteristics + = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_INITIALIZED_DATA + | GRUB_PE32_SCN_MEM_DISCARDABLE + | GRUB_PE32_SCN_MEM_READ); + free (core_img); + core_img = pe_img; + core_size = pe_size; + } + break; + case IMAGE_QEMU: + { + char *rom_img; + size_t rom_size; + char *boot_path, *boot_img; + size_t boot_size; - boot_path = grub_util_get_path (dir, "boot.img"); - boot_size = grub_util_get_image_size (boot_path); - boot_img = grub_util_read_image (boot_path); + boot_path = grub_util_get_path (dir, "boot.img"); + boot_size = grub_util_get_image_size (boot_path); + boot_img = grub_util_read_image (boot_path); - /* Rom sizes must be 64k-aligned. */ - rom_size = ALIGN_UP (core_size + boot_size, 64 * 1024); + /* Rom sizes must be 64k-aligned. */ + rom_size = ALIGN_UP (core_size + boot_size, 64 * 1024); - rom_img = xmalloc (rom_size); - memset (rom_img, 0, rom_size); + rom_img = xmalloc (rom_size); + memset (rom_img, 0, rom_size); - *((grub_int32_t *) (core_img + GRUB_KERNEL_MACHINE_CORE_ENTRY_ADDR)) - = grub_host_to_target32 ((grub_uint32_t) -rom_size); + *((grub_int32_t *) (core_img + GRUB_KERNEL_I386_QEMU_CORE_ENTRY_ADDR)) + = grub_host_to_target32 ((grub_uint32_t) -rom_size); - memcpy (rom_img, core_img, core_size); + memcpy (rom_img, core_img, core_size); - *((grub_int32_t *) (boot_img + GRUB_BOOT_MACHINE_CORE_ENTRY_ADDR)) - = grub_host_to_target32 ((grub_uint32_t) -rom_size); + *((grub_int32_t *) (boot_img + GRUB_BOOT_I386_QEMU_CORE_ENTRY_ADDR)) + = grub_host_to_target32 ((grub_uint32_t) -rom_size); - memcpy (rom_img + rom_size - boot_size, boot_img, boot_size); + memcpy (rom_img + rom_size - boot_size, boot_img, boot_size); - free (core_img); - core_img = rom_img; - core_size = rom_size; + free (core_img); + core_img = rom_img; + core_size = rom_size; - free (boot_img); - free (boot_path); - } -#elif defined (GRUB_MACHINE_SPARC64) - if (format == GRUB_PLATFORM_IMAGE_AOUT) - { - void *aout_img; - size_t aout_size; - struct grub_aout32_header *aout_head; + free (boot_img); + free (boot_path); + } + break; + case IMAGE_SPARC64_AOUT: + { + void *aout_img; + size_t aout_size; + struct grub_aout32_header *aout_head; - aout_size = core_size + sizeof (*aout_head); - aout_img = xmalloc (aout_size); - aout_head = aout_img; - aout_head->a_midmag = grub_host_to_target32 ((AOUT_MID_SUN << 16) - | AOUT32_OMAGIC); - aout_head->a_text = grub_host_to_target32 (core_size); - aout_head->a_entry - = grub_host_to_target32 (GRUB_BOOT_MACHINE_IMAGE_ADDRESS); - memcpy (aout_img + sizeof (*aout_head), core_img, core_size); + aout_size = core_size + sizeof (*aout_head); + aout_img = xmalloc (aout_size); + aout_head = aout_img; + aout_head->a_midmag = grub_host_to_target32 ((AOUT_MID_SUN << 16) + | AOUT32_OMAGIC); + aout_head->a_text = grub_host_to_target32 (core_size); + aout_head->a_entry + = grub_host_to_target32 (GRUB_BOOT_SPARC64_IEEE1275_IMAGE_ADDRESS); + memcpy (aout_img + sizeof (*aout_head), core_img, core_size); - free (core_img); - core_img = aout_img; - core_size = aout_size; + free (core_img); + core_img = aout_img; + core_size = aout_size; + } + break; + case IMAGE_SPARC64_RAW: + { + unsigned int num; + char *boot_path, *boot_img; + size_t boot_size; + + num = ((core_size + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS); + num <<= GRUB_DISK_SECTOR_BITS; + + boot_path = grub_util_get_path (dir, "diskboot.img"); + boot_size = grub_util_get_image_size (boot_path); + if (boot_size != GRUB_DISK_SECTOR_SIZE) + grub_util_error ("diskboot.img is not one sector size"); + + boot_img = grub_util_read_image (boot_path); + + *((grub_uint32_t *) (boot_img + GRUB_DISK_SECTOR_SIZE + - GRUB_BOOT_SPARC64_IEEE1275_LIST_SIZE + 8)) + = grub_host_to_target32 (num); + + grub_util_write_image (boot_img, boot_size, out); + free (boot_img); + free (boot_path); + } + break; + case IMAGE_YEELOONG_ELF: + case IMAGE_PPC: + case IMAGE_COREBOOT: + case IMAGE_I386_IEEE1275: + { + char *elf_img; + size_t program_size; + Elf32_Ehdr *ehdr; + Elf32_Phdr *phdr; + grub_uint32_t target_addr; + int header_size, footer_size = 0; + int phnum = 1; + + if (note) + { + phnum++; + footer_size += sizeof (struct grub_ieee1275_note); + } + header_size = ALIGN_ADDR (sizeof (*ehdr) + phnum * sizeof (*phdr)); + + program_size = ALIGN_ADDR (core_size); + + elf_img = xmalloc (program_size + header_size + footer_size); + memset (elf_img, 0, program_size + header_size); + memcpy (elf_img + header_size, core_img, core_size); + ehdr = (void *) elf_img; + phdr = (void *) (elf_img + sizeof (*ehdr)); + memcpy (ehdr->e_ident, ELFMAG, SELFMAG); + ehdr->e_ident[EI_CLASS] = ELFCLASS32; + if (!image_target->bigendian) + ehdr->e_ident[EI_DATA] = ELFDATA2LSB; + else + ehdr->e_ident[EI_DATA] = ELFDATA2MSB; + ehdr->e_ident[EI_VERSION] = EV_CURRENT; + ehdr->e_ident[EI_OSABI] = ELFOSABI_NONE; + ehdr->e_type = grub_host_to_target16 (ET_EXEC); + ehdr->e_machine = grub_host_to_target16 (image_target->elf_target); + ehdr->e_version = grub_host_to_target32 (EV_CURRENT); + + ehdr->e_phoff = grub_host_to_target32 ((char *) phdr - (char *) ehdr); + ehdr->e_phentsize = grub_host_to_target16 (sizeof (*phdr)); + ehdr->e_phnum = grub_host_to_target16 (phnum); + + /* No section headers. */ + ehdr->e_shoff = grub_host_to_target32 (0); + ehdr->e_shentsize = grub_host_to_target16 (0); + ehdr->e_shnum = grub_host_to_target16 (0); + ehdr->e_shstrndx = grub_host_to_target16 (0); + + ehdr->e_ehsize = grub_host_to_target16 (sizeof (*ehdr)); + + phdr->p_type = grub_host_to_target32 (PT_LOAD); + phdr->p_offset = grub_host_to_target32 (header_size); + phdr->p_flags = grub_host_to_target32 (PF_R | PF_W | PF_X); + + if (image_target->id == IMAGE_YEELOONG_ELF) + target_addr = ALIGN_UP (GRUB_KERNEL_MACHINE_LINK_ADDR + + kernel_size + total_module_size, 32); + else + target_addr = GRUB_KERNEL_MACHINE_LINK_ADDR; + ehdr->e_entry = grub_host_to_target32 (target_addr); + phdr->p_vaddr = grub_host_to_target32 (target_addr); + phdr->p_paddr = grub_host_to_target32 (target_addr); + phdr->p_align = grub_host_to_target32 (image_target->link_align); + if (image_target->id == IMAGE_YEELOONG_ELF) + ehdr->e_flags = grub_host_to_target32 (0x1000 | EF_MIPS_NOREORDER + | EF_MIPS_PIC | EF_MIPS_CPIC); + else + ehdr->e_flags = 0; + phdr->p_filesz = grub_host_to_target32 (core_size); + phdr->p_memsz = grub_host_to_target32 (core_size); + + if (note) + { + int note_size = sizeof (struct grub_ieee1275_note); + struct grub_ieee1275_note *note = (struct grub_ieee1275_note *) + (elf_img + program_size + header_size); + + grub_util_info ("adding CHRP NOTE segment"); + + note->header.namesz = grub_host_to_target32 (sizeof (GRUB_IEEE1275_NOTE_NAME)); + note->header.descsz = grub_host_to_target32 (note_size); + note->header.type = grub_host_to_target32 (GRUB_IEEE1275_NOTE_TYPE); + strcpy (note->header.name, GRUB_IEEE1275_NOTE_NAME); + note->descriptor.real_mode = grub_host_to_target32 (0xffffffff); + note->descriptor.real_base = grub_host_to_target32 (0x00c00000); + note->descriptor.real_size = grub_host_to_target32 (0xffffffff); + note->descriptor.virt_base = grub_host_to_target32 (0xffffffff); + note->descriptor.virt_size = grub_host_to_target32 (0xffffffff); + note->descriptor.load_base = grub_host_to_target32 (0x00004000); + + phdr[1].p_type = grub_host_to_target32 (PT_NOTE); + phdr[1].p_flags = grub_host_to_target32 (PF_R); + phdr[1].p_align = grub_host_to_target32 (GRUB_TARGET_SIZEOF_LONG); + phdr[1].p_vaddr = 0; + phdr[1].p_paddr = 0; + phdr[1].p_filesz = grub_host_to_target32 (note_size); + phdr[1].p_memsz = 0; + phdr[1].p_offset = grub_host_to_target32 (header_size + program_size); + } + + free (core_img); + core_img = elf_img; + core_size = program_size + header_size + footer_size; + } + break; } - else - { - unsigned int num; - char *boot_path, *boot_img; - size_t boot_size; - - num = ((core_size + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS); - num <<= GRUB_DISK_SECTOR_BITS; - - boot_path = grub_util_get_path (dir, "diskboot.img"); - boot_size = grub_util_get_image_size (boot_path); - if (boot_size != GRUB_DISK_SECTOR_SIZE) - grub_util_error ("diskboot.img is not one sector size"); - - boot_img = grub_util_read_image (boot_path); - - *((grub_uint32_t *) (boot_img + GRUB_DISK_SECTOR_SIZE - - GRUB_BOOT_MACHINE_LIST_SIZE + 8)) - = grub_host_to_target32 (num); - - grub_util_write_image (boot_img, boot_size, out); - free (boot_img); - free (boot_path); - } -#elif defined(GRUB_MACHINE_MIPS) || defined (GRUB_MACHINE_IEEE1275) - if (format == GRUB_PLATFORM_IMAGE_ELF) - { - char *elf_img; - size_t program_size; - Elf32_Ehdr *ehdr; - Elf32_Phdr *phdr; - grub_uint32_t target_addr; - int header_size, footer_size = 0; - int phnum = 1; - - if (note) - { - phnum++; - footer_size += sizeof (struct grub_ieee1275_note); - } - header_size = ALIGN_ADDR (sizeof (*ehdr) + phnum * sizeof (*phdr)); - - program_size = ALIGN_ADDR (core_size); - - elf_img = xmalloc (program_size + header_size + footer_size); - memset (elf_img, 0, program_size + header_size); - memcpy (elf_img + header_size, core_img, core_size); - ehdr = (void *) elf_img; - phdr = (void *) (elf_img + sizeof (*ehdr)); - memcpy (ehdr->e_ident, ELFMAG, SELFMAG); - ehdr->e_ident[EI_CLASS] = ELFCLASS32; -#ifdef GRUB_CPU_MIPSEL - ehdr->e_ident[EI_DATA] = ELFDATA2LSB; -#else - ehdr->e_ident[EI_DATA] = ELFDATA2MSB; -#endif - ehdr->e_ident[EI_VERSION] = EV_CURRENT; - ehdr->e_ident[EI_OSABI] = ELFOSABI_NONE; - ehdr->e_type = grub_host_to_target16 (ET_EXEC); - ehdr->e_machine = grub_host_to_target16 (EM_TARGET); - ehdr->e_version = grub_host_to_target32 (EV_CURRENT); - - ehdr->e_phoff = grub_host_to_target32 ((char *) phdr - (char *) ehdr); - ehdr->e_phentsize = grub_host_to_target16 (sizeof (*phdr)); - ehdr->e_phnum = grub_host_to_target16 (phnum); - - /* No section headers. */ - ehdr->e_shoff = grub_host_to_target32 (0); - ehdr->e_shentsize = grub_host_to_target16 (0); - ehdr->e_shnum = grub_host_to_target16 (0); - ehdr->e_shstrndx = grub_host_to_target16 (0); - - ehdr->e_ehsize = grub_host_to_target16 (sizeof (*ehdr)); - - phdr->p_type = grub_host_to_target32 (PT_LOAD); - phdr->p_offset = grub_host_to_target32 (header_size); - phdr->p_flags = grub_host_to_target32 (PF_R | PF_W | PF_X); - -#if defined(GRUB_MACHINE_MIPS) - target_addr = ALIGN_UP (GRUB_KERNEL_MACHINE_LINK_ADDR - + kernel_size + total_module_size, 32); -#else - target_addr = GRUB_KERNEL_MACHINE_LINK_ADDR; -#endif - ehdr->e_entry = grub_host_to_target32 (target_addr); - phdr->p_vaddr = grub_host_to_target32 (target_addr); - phdr->p_paddr = grub_host_to_target32 (target_addr); - phdr->p_align = grub_host_to_target32 (GRUB_KERNEL_MACHINE_LINK_ALIGN); -#if defined(GRUB_MACHINE_MIPS) - ehdr->e_flags = grub_host_to_target32 (0x1000 | EF_MIPS_NOREORDER - | EF_MIPS_PIC | EF_MIPS_CPIC); -#else - ehdr->e_flags = 0; -#endif - phdr->p_filesz = grub_host_to_target32 (core_size); - phdr->p_memsz = grub_host_to_target32 (core_size); - - if (note) - { - int note_size = sizeof (struct grub_ieee1275_note); - struct grub_ieee1275_note *note = (struct grub_ieee1275_note *) - (elf_img + program_size + header_size); - - grub_util_info ("adding CHRP NOTE segment"); - - note->header.namesz = grub_host_to_target32 (sizeof (GRUB_IEEE1275_NOTE_NAME)); - note->header.descsz = grub_host_to_target32 (note_size); - note->header.type = grub_host_to_target32 (GRUB_IEEE1275_NOTE_TYPE); - strcpy (note->header.name, GRUB_IEEE1275_NOTE_NAME); - note->descriptor.real_mode = grub_host_to_target32 (0xffffffff); - note->descriptor.real_base = grub_host_to_target32 (0x00c00000); - note->descriptor.real_size = grub_host_to_target32 (0xffffffff); - note->descriptor.virt_base = grub_host_to_target32 (0xffffffff); - note->descriptor.virt_size = grub_host_to_target32 (0xffffffff); - note->descriptor.load_base = grub_host_to_target32 (0x00004000); - - phdr[1].p_type = grub_host_to_target32 (PT_NOTE); - phdr[1].p_flags = grub_host_to_target32 (PF_R); - phdr[1].p_align = grub_host_to_target32 (GRUB_TARGET_SIZEOF_LONG); - phdr[1].p_vaddr = 0; - phdr[1].p_paddr = 0; - phdr[1].p_filesz = grub_host_to_target32 (note_size); - phdr[1].p_memsz = 0; - phdr[1].p_offset = grub_host_to_target32 (header_size + program_size); - } - - free (core_img); - core_img = elf_img; - core_size = program_size + header_size + footer_size; - } -#endif grub_util_write_image (core_img, core_size, out); free (kernel_img); @@ -1368,9 +1499,7 @@ static struct option options[] = {"config", required_argument, 0, 'c'}, {"output", required_argument, 0, 'o'}, {"note", no_argument, 0, 'n'}, -#ifdef GRUB_PLATFORM_IMAGE_DEFAULT {"format", required_argument, 0, 'O'}, -#endif {"help", no_argument, 0, 'h'}, {"version", no_argument, 0, 'V'}, {"verbose", no_argument, 0, 'v'}, @@ -1383,7 +1512,24 @@ usage (int status) if (status) fprintf (stderr, _("Try `%s --help' for more information.\n"), program_name); else - printf (_("\ + { + int format_len = 0; + char *formats; + char *ptr; + unsigned i; + for (i = 0; i < ARRAY_SIZE (image_targets); i++) + format_len += strlen (image_targets[i].name) + 2; + ptr = formats = xmalloc (format_len); + for (i = 0; i < ARRAY_SIZE (image_targets); i++) + { + strcpy (ptr, image_targets[i].name); + ptr += strlen (image_targets[i].name); + *ptr++ = ','; + *ptr++ = ' '; + } + ptr[-2] = 0; + + printf (_("\ Usage: %s [OPTION]... [MODULES]\n\ \n\ Make a bootable image of GRUB.\n\ @@ -1394,25 +1540,20 @@ Make a bootable image of GRUB.\n\ -f, --font=FILE embed FILE as a boot font\n\ -c, --config=FILE embed FILE as boot config\n\ -n, --note add NOTE segment for CHRP Open Firmware\n\ - -o, --output=FILE output a generated image to FILE [default=stdout]\n" -#ifdef GRUB_PLATFORM_IMAGE_DEFAULT - "\ - -O, --format=FORMAT generate an image in format [default=%s]\n\ - available formats: %s\n" -#endif - "\ + -o, --output=FILE output a generated image to FILE [default=stdout]\n\ + -O, --format=FORMAT generate an image in format\n\ + available formats: %s\n\ -h, --help display this message and exit\n\ -V, --version print version information and exit\n\ -v, --verbose print verbose messages\n\ \n\ Report bugs to <%s>.\n\ "), -program_name, GRUB_LIBDIR, DEFAULT_DIRECTORY, -#ifdef GRUB_PLATFORM_IMAGE_DEFAULT - GRUB_PLATFORM_IMAGE_DEFAULT_FORMAT, GRUB_PLATFORM_IMAGE_FORMATS, -#endif -PACKAGE_BUGREPORT); - + program_name, GRUB_LIBDIR, DEFAULT_DIRECTORY, + formats, + PACKAGE_BUGREPORT); + free (formats); + } exit (status); } @@ -1427,9 +1568,7 @@ main (int argc, char *argv[]) char *config = NULL; FILE *fp = stdout; int note = 0; -#ifdef GRUB_PLATFORM_IMAGE_DEFAULT - grub_platform_image_format_t format = GRUB_PLATFORM_IMAGE_DEFAULT; -#endif + struct image_target_desc *image_target = NULL; set_program_name (argv[0]); @@ -1451,27 +1590,19 @@ main (int argc, char *argv[]) output = xstrdup (optarg); break; -#ifdef GRUB_PLATFORM_IMAGE_DEFAULT case 'O': -#ifdef GRUB_PLATFORM_IMAGE_RAW - if (strcmp (optarg, "raw") == 0) - format = GRUB_PLATFORM_IMAGE_RAW; - else -#endif -#ifdef GRUB_PLATFORM_IMAGE_ELF - if (strcmp (optarg, "elf") == 0) - format = GRUB_PLATFORM_IMAGE_ELF; - else -#endif -#ifdef GRUB_PLATFORM_IMAGE_AOUT - if (strcmp (optarg, "aout") == 0) - format = GRUB_PLATFORM_IMAGE_AOUT; - else -#endif - usage (1); - break; -#endif - + { + unsigned i; + for (i = 0; i < ARRAY_SIZE (image_targets); i++) + if (strcmp (optarg, image_targets[i].name) == 0) + image_target = &image_targets[i]; + if (!image_target) + { + printf ("unknown target %s\n", optarg); + usage (1); + } + break; + } case 'd': if (dir) free (dir); @@ -1534,6 +1665,12 @@ main (int argc, char *argv[]) } } + if (!image_target) + { + printf ("Target not specified.\n"); + usage (1); + } + if (output) { fp = fopen (output, "wb"); @@ -1544,12 +1681,7 @@ main (int argc, char *argv[]) generate_image (dir ? : GRUB_LIBDIR, prefix ? : DEFAULT_DIRECTORY, fp, argv + optind, memdisk, font, config, -#ifdef GRUB_PLATFORM_IMAGE_DEFAULT - format, -#else - 0, -#endif - note); + image_target, note); fclose (fp); diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in index aafdfb059..7d553a767 100644 --- a/util/grub-mkrescue.in +++ b/util/grub-mkrescue.in @@ -171,7 +171,7 @@ fi if test -e "${pc_dir}" ; then echo "Enabling BIOS support ..." core_img=`mktemp "$MKTEMP_TEMPLATE"` - grub-mkimage -d ${pc_dir}/ -o ${core_img} --prefix=/boot/grub/i386-pc \ + grub-mkimage -d ${pc_dir}/ -O i386-pc -o ${core_img} --prefix=/boot/grub/i386-pc \ iso9660 biosdisk cat ${pc_dir}/cdboot.img ${core_img} > ${iso9660_dir}/boot/grub/i386-pc/eltorito.img From 460d8402e033873f16a2ebe32ca490d6cbdb9ebf Mon Sep 17 00:00:00 2001 From: Christian Franke Date: Mon, 26 Apr 2010 03:35:55 +0200 Subject: [PATCH 601/738] * include/grub/util/getroot.h (grub_get_prefix): Remove prototype. * util/getroot.c [__CYGWIN__] (get_win32_path): Remove function. (grub_get_prefix): Remove function. * util/grub-emu.c (main): Replace grub_get_prefix () call by make_system_path_relative_to_its_root (). * util/sparc64/ieee1275/grub-setup.c (main): Likewise. --- ChangeLog | 11 +++- include/grub/util/getroot.h | 1 - util/getroot.c | 97 ------------------------------ util/grub-emu.c | 2 +- util/sparc64/ieee1275/grub-setup.c | 3 +- 5 files changed, 13 insertions(+), 101 deletions(-) diff --git a/ChangeLog b/ChangeLog index 92c8dc53c..29e634bf6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2010-04-26 Christian Franke + + * include/grub/util/getroot.h (grub_get_prefix): Remove prototype. + * util/getroot.c [__CYGWIN__] (get_win32_path): Remove function. + (grub_get_prefix): Remove function. + * util/grub-emu.c (main): Replace grub_get_prefix () call by + make_system_path_relative_to_its_root (). + * util/sparc64/ieee1275/grub-setup.c (main): Likewise. + 2010-04-24 Christian Franke * Makefile.in (TARGET_LDFLAGS): Add -static-libgcc. @@ -95,7 +104,7 @@ * disk/lvm.c (grub_lvm_memberlist): Issue an error if pv->disk = 0. -2010-04-17 Christian Franke +2010-04-17 Christian Franke * Makefile.in: Add missing localedir setting. diff --git a/include/grub/util/getroot.h b/include/grub/util/getroot.h index f9f7f9baa..dff7b4df7 100644 --- a/include/grub/util/getroot.h +++ b/include/grub/util/getroot.h @@ -26,7 +26,6 @@ enum grub_dev_abstraction_types { }; char *grub_guess_root_device (const char *dir); -char *grub_get_prefix (const char *dir); int grub_util_get_dev_abstraction (const char *os_dev); char *grub_util_get_grub_dev (const char *os_dev); const char *grub_util_check_block_device (const char *blk_dev); diff --git a/util/getroot.c b/util/getroot.c index 94eadc5e1..891bd0f10 100644 --- a/util/getroot.c +++ b/util/getroot.c @@ -79,103 +79,6 @@ xgetcwd (void) return path; } -#ifdef __CYGWIN__ -/* Convert POSIX path to Win32 path, - remove drive letter, replace backslashes. */ -static char * -get_win32_path (const char *path) -{ - char winpath[PATH_MAX]; - cygwin_conv_to_full_win32_path (path, winpath); - - int len = strlen (winpath); - if (len > 2 && winpath[1] == ':') - { - len -= 2; - memmove (winpath, winpath + 2, len + 1); - } - - int i; - for (i = 0; i < len; i++) - if (winpath[i] == '\\') - winpath[i] = '/'; - return xstrdup (winpath); -} -#endif - -char * -grub_get_prefix (const char *dir) -{ - char *saved_cwd; - char *abs_dir, *prev_dir; - char *prefix; - struct stat st, prev_st; - - /* Save the current directory. */ - saved_cwd = xgetcwd (); - - if (chdir (dir) < 0) - grub_util_error ("cannot change directory to `%s'", dir); - - abs_dir = xgetcwd (); - strip_extra_slashes (abs_dir); - prev_dir = xstrdup (abs_dir); - - if (stat (".", &prev_st) < 0) - grub_util_error ("cannot stat `%s'", dir); - - if (! S_ISDIR (prev_st.st_mode)) - grub_util_error ("`%s' is not a directory", dir); - - while (1) - { - if (chdir ("..") < 0) - grub_util_error ("cannot change directory to the parent"); - - if (stat (".", &st) < 0) - grub_util_error ("cannot stat current directory"); - - if (! S_ISDIR (st.st_mode)) - grub_util_error ("current directory is not a directory???"); - - if (prev_st.st_dev != st.st_dev || prev_st.st_ino == st.st_ino) - break; - - free (prev_dir); - prev_dir = xgetcwd (); - prev_st = st; - } - - strip_extra_slashes (prev_dir); - prefix = xmalloc (strlen (abs_dir) - strlen (prev_dir) + 2); - prefix[0] = '/'; - strcpy (prefix + 1, abs_dir + strlen (prev_dir)); - strip_extra_slashes (prefix); - - if (chdir (saved_cwd) < 0) - grub_util_error ("cannot change directory to `%s'", dir); - -#ifdef __CYGWIN__ - if (st.st_dev != (DEV_CYGDRIVE_MAJOR << 16)) - { - /* Reached some mount point not below /cygdrive. - GRUB does not know Cygwin's emulated mounts, - convert to Win32 path. */ - grub_util_info ("Cygwin prefix = %s", prefix); - char * wprefix = get_win32_path (prefix); - free (prefix); - prefix = wprefix; - } -#endif - - free (saved_cwd); - free (abs_dir); - free (prev_dir); - - grub_util_info ("prefix = %s", prefix); - return prefix; -} - #ifdef __MINGW32__ static char * diff --git a/util/grub-emu.c b/util/grub-emu.c index 8660f0aa0..8c53b0aca 100644 --- a/util/grub-emu.c +++ b/util/grub-emu.c @@ -242,7 +242,7 @@ main (int argc, char *argv[]) if (strcmp (root_dev, "host") == 0) dir = xstrdup (dir); else - dir = grub_get_prefix (dir); + dir = make_system_path_relative_to_its_root (dir); prefix = xmalloc (strlen (root_dev) + 2 + strlen (dir) + 1); sprintf (prefix, "(%s)%s", root_dev, dir); free (dir); diff --git a/util/sparc64/ieee1275/grub-setup.c b/util/sparc64/ieee1275/grub-setup.c index b511a96b2..06bc16795 100644 --- a/util/sparc64/ieee1275/grub-setup.c +++ b/util/sparc64/ieee1275/grub-setup.c @@ -627,7 +627,8 @@ main (int argc, char *argv[]) find_dest_dev (&ginfo, argv); - ginfo.prefix = grub_get_prefix (ginfo.dir ? : DEFAULT_DIRECTORY); + ginfo.prefix = make_system_path_relative_to_its_root (ginfo.dir ? + : DEFAULT_DIRECTORY); check_root_dev (&ginfo); From 94ac7906451fc65323122507c595b790fb2b4644 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 26 Apr 2010 10:56:12 +0200 Subject: [PATCH 602/738] Fix various issues created by previous commits --- Makefile.in | 4 +- boot/i386/qemu/boot.S | 2 +- boot/sparc64/ieee1275/diskboot.S | 11 +- configure.ac | 1 + include/grub/efi/pe32.h | 60 +++++++-- include/grub/i386/pc/boot.h | 1 - include/grub/i386/pc/kernel.h | 2 - include/grub/i386/pc/memory.h | 1 - include/grub/i386/qemu/kernel.h | 9 +- include/grub/offsets.h | 101 ++++++++++++++++ include/grub/powerpc/ieee1275/kernel.h | 18 +-- kern/i386/qemu/startup.S | 2 +- util/grub-mkimage.c | 161 ++++++++++++++++++------- 13 files changed, 285 insertions(+), 88 deletions(-) create mode 100644 include/grub/offsets.h diff --git a/Makefile.in b/Makefile.in index 822a08797..3df8b1b72 100644 --- a/Makefile.in +++ b/Makefile.in @@ -90,7 +90,7 @@ GNULIB_CFLAGS = $(GNULIB_UTIL_CFLAGS) $(POSIX_CFLAGS) ASFLAGS = @ASFLAGS@ LDFLAGS = @LDFLAGS@ $(LIBS) CPPFLAGS = @CPPFLAGS@ -I$(builddir) -I$(builddir)/include -I$(srcdir)/gnulib -I$(srcdir)/include -Wall -W \ - -DGRUB_LIBDIR=\"$(pkglibdir)\" -DLOCALEDIR=\"$(localedir)\" + -DGRUB_LIBDIR=\"$(libdir)\" -DLOCALEDIR=\"$(localedir)\" TARGET_CC = @TARGET_CC@ TARGET_CFLAGS = -ffreestanding @TARGET_CFLAGS@ TARGET_ASFLAGS = -nostdinc -fno-builtin @TARGET_ASFLAGS@ @@ -287,7 +287,7 @@ build_env.mk: Makefile echo "TARGET_CC=$(TARGET_CC)" ; \ echo "TARGET_CFLAGS=$(TARGET_CFLAGS)" ; \ echo "TARGET_ASFLAGS=$(TARGET_ASFLAGS)" ; \ - echo "TARGET_CPPFLAGS=$(TARGET_CPPFLAGS) -I$(pkglibdir) -I$(includedir)" ; \ + echo "TARGET_CPPFLAGS=$(TARGET_CPPFLAGS) -I$(libdir) -I$(includedir)" ; \ echo "STRIP=$(STRIP)" ; \ echo "OBJCONV=$(OBJCONV)" ; \ echo "TARGET_MODULE_FORMAT=$(TARGET_MODULE_FORMAT)" ; \ diff --git a/boot/i386/qemu/boot.S b/boot/i386/qemu/boot.S index a93fe3943..51039dd69 100644 --- a/boot/i386/qemu/boot.S +++ b/boot/i386/qemu/boot.S @@ -31,7 +31,7 @@ _start: jmp 1f - . = _start + GRUB_BOOT_MACHINE_CORE_ENTRY_ADDR + . = _start + GRUB_BOOT_I386_QEMU_CORE_ENTRY_ADDR VARIABLE(grub_core_entry_addr) .long 0 1: diff --git a/boot/sparc64/ieee1275/diskboot.S b/boot/sparc64/ieee1275/diskboot.S index a4d4b5bf9..a8fd50d87 100644 --- a/boot/sparc64/ieee1275/diskboot.S +++ b/boot/sparc64/ieee1275/diskboot.S @@ -19,6 +19,7 @@ #include #include +#include .text .align 4 @@ -87,8 +88,8 @@ after_info_block: call console_write mov NOTIFICATION_STRING_LEN, %o3 - GET_ABS(firstlist - GRUB_BOOT_MACHINE_LIST_SIZE, %l2) - set GRUB_BOOT_MACHINE_IMAGE_ADDRESS, %l3 + GET_ABS(firstlist - GRUB_BOOT_SPARC64_IEEE1275_LIST_SIZE, %l2) + set GRUB_BOOT_SPARC64_IEEE1275_IMAGE_ADDRESS, %l3 bootloop: lduw [%l2 + 0x08], %o0 brz %o0, bootit @@ -115,7 +116,7 @@ bootloop: mov NOTIFICATION_STEP_LEN, %o3 ba bootloop - sub %l2, GRUB_BOOT_MACHINE_LIST_SIZE, %l2 + sub %l2, GRUB_BOOT_SPARC64_IEEE1275_LIST_SIZE, %l2 bootit: GET_ABS(prom_close_name, %o0) @@ -127,8 +128,8 @@ bootit: GET_ABS(notification_done, %o2) call console_write mov NOTIFICATION_DONE_LEN, %o3 - sethi %hi(GRUB_BOOT_MACHINE_IMAGE_ADDRESS), %o2 - jmpl %o2 + %lo(GRUB_BOOT_MACHINE_IMAGE_ADDRESS), %o7 + sethi %hi(GRUB_BOOT_SPARC64_IEEE1275_IMAGE_ADDRESS), %o2 + jmpl %o2 + %lo(GRUB_BOOT_SPARC64_IEEE1275_IMAGE_ADDRESS), %o7 mov CIF_REG, %o4 1: ba,a 1b diff --git a/configure.ac b/configure.ac index 4bfc5a2b0..e3453b636 100644 --- a/configure.ac +++ b/configure.ac @@ -148,6 +148,7 @@ case "$target_cpu" in mips) machine_CFLAGS="$machine_CFLAGS -DGRUB_MACHINE_MIPS=1" ;; sparc64) machine_CFLAGS="$machine_CFLAGS -DGRUB_MACHINE_SPARC64=1" ;; esac +machine_CFLAGS="$machine_CFLAGS -DMACHINE=`echo ${target_cpu}_$platform | sed y,abcdefghijklmnopqrstuvwxyz,ABCDEFGHIJKLMNOPQRSTUVWXYZ,`" CFLAGS="$CFLAGS $machine_CFLAGS" TARGET_ASFLAGS="$TARGET_ASFLAGS $machine_CFLAGS" diff --git a/include/grub/efi/pe32.h b/include/grub/efi/pe32.h index 21b56ae27..9d9edc220 100644 --- a/include/grub/efi/pe32.h +++ b/include/grub/efi/pe32.h @@ -99,12 +99,8 @@ struct grub_pe32_optional_header grub_uint32_t entry_addr; grub_uint32_t code_base; -#if GRUB_TARGET_SIZEOF_VOID_P == 4 grub_uint32_t data_base; grub_uint32_t image_base; -#else - grub_uint64_t image_base; -#endif grub_uint32_t section_alignment; grub_uint32_t file_alignment; @@ -121,22 +117,66 @@ struct grub_pe32_optional_header grub_uint16_t subsystem; grub_uint16_t dll_characteristics; -#if GRUB_TARGET_SIZEOF_VOID_P == 4 - grub_uint32_t stack_reserve_size; grub_uint32_t stack_commit_size; grub_uint32_t heap_reserve_size; grub_uint32_t heap_commit_size; -#else + grub_uint32_t loader_flags; + grub_uint32_t num_data_directories; + + /* Data directories. */ + struct grub_pe32_data_directory export_table; + struct grub_pe32_data_directory import_table; + struct grub_pe32_data_directory resource_table; + struct grub_pe32_data_directory exception_table; + struct grub_pe32_data_directory certificate_table; + struct grub_pe32_data_directory base_relocation_table; + struct grub_pe32_data_directory debug; + struct grub_pe32_data_directory architecture; + struct grub_pe32_data_directory global_ptr; + struct grub_pe32_data_directory tls_table; + struct grub_pe32_data_directory load_config_table; + struct grub_pe32_data_directory bound_import; + struct grub_pe32_data_directory iat; + struct grub_pe32_data_directory delay_import_descriptor; + struct grub_pe32_data_directory com_runtime_header; + struct grub_pe32_data_directory reserved_entry; +}; + +struct grub_pe64_optional_header +{ + grub_uint16_t magic; + grub_uint8_t major_linker_version; + grub_uint8_t minor_linker_version; + grub_uint32_t code_size; + grub_uint32_t data_size; + grub_uint32_t bss_size; + grub_uint32_t entry_addr; + grub_uint32_t code_base; + + grub_uint64_t image_base; + + grub_uint32_t section_alignment; + grub_uint32_t file_alignment; + grub_uint16_t major_os_version; + grub_uint16_t minor_os_version; + grub_uint16_t major_image_version; + grub_uint16_t minor_image_version; + grub_uint16_t major_subsystem_version; + grub_uint16_t minor_subsystem_version; + grub_uint32_t reserved; + grub_uint32_t image_size; + grub_uint32_t header_size; + grub_uint32_t checksum; + grub_uint16_t subsystem; + grub_uint16_t dll_characteristics; grub_uint64_t stack_reserve_size; grub_uint64_t stack_commit_size; grub_uint64_t heap_reserve_size; grub_uint64_t heap_commit_size; -#endif - grub_uint32_t loader_flags; grub_uint32_t num_data_directories; @@ -221,6 +261,8 @@ struct grub_pe32_header struct grub_pe32_optional_header optional_header; }; +#define GRUB_PE32_SIGNATURE_SIZE 4 + struct grub_pe32_fixup_block { grub_uint32_t page_rva; diff --git a/include/grub/i386/pc/boot.h b/include/grub/i386/pc/boot.h index 09d01caee..a4d42ff3c 100644 --- a/include/grub/i386/pc/boot.h +++ b/include/grub/i386/pc/boot.h @@ -19,7 +19,6 @@ #ifndef GRUB_BOOT_MACHINE_HEADER #define GRUB_BOOT_MACHINE_HEADER 1 -#define MACHINE I386_PC #include /* The signature for bootloader. */ diff --git a/include/grub/i386/pc/kernel.h b/include/grub/i386/pc/kernel.h index 77d5c6e5a..f0a9d4fc2 100644 --- a/include/grub/i386/pc/kernel.h +++ b/include/grub/i386/pc/kernel.h @@ -19,8 +19,6 @@ #ifndef KERNEL_MACHINE_HEADER #define KERNEL_MACHINE_HEADER 1 -#define MACHINE I386_PC - #include /* Enable LZMA compression */ diff --git a/include/grub/i386/pc/memory.h b/include/grub/i386/pc/memory.h index 0b4191734..68f5e8bc9 100644 --- a/include/grub/i386/pc/memory.h +++ b/include/grub/i386/pc/memory.h @@ -29,7 +29,6 @@ #include -#define MACHINE I386_PC #include /* The scratch buffer used in real mode code. */ diff --git a/include/grub/i386/qemu/kernel.h b/include/grub/i386/qemu/kernel.h index 3d22c9d9f..e29f0aeb2 100644 --- a/include/grub/i386/qemu/kernel.h +++ b/include/grub/i386/qemu/kernel.h @@ -19,14 +19,7 @@ #ifndef GRUB_KERNEL_MACHINE_HEADER #define GRUB_KERNEL_MACHINE_HEADER 1 -/* The offset of GRUB_KERNEL_IMAGE_SIZE. */ -#define GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE 0xc - -/* The offset of GRUB_PREFIX. */ -#define GRUB_KERNEL_MACHINE_PREFIX 0x10 - -/* End of the data section. */ -#define GRUB_KERNEL_MACHINE_DATA_END 0x50 +#include #ifndef ASM_FILE diff --git a/include/grub/offsets.h b/include/grub/offsets.h new file mode 100644 index 000000000..a0c2f61f9 --- /dev/null +++ b/include/grub/offsets.h @@ -0,0 +1,101 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2003,2007,2008 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef OFFSETS_HEADER +#define OFFSETS_HEADER 1 + +/* The offset of GRUB_TOTAL_MODULE_SIZE. */ +#define GRUB_KERNEL_I386_PC_TOTAL_MODULE_SIZE 0x8 + +/* The offset of GRUB_KERNEL_IMAGE_SIZE. */ +#define GRUB_KERNEL_I386_PC_KERNEL_IMAGE_SIZE 0xc + +/* The offset of GRUB_COMPRESSED_SIZE. */ +#define GRUB_KERNEL_I386_PC_COMPRESSED_SIZE 0x10 + +/* The offset of GRUB_INSTALL_DOS_PART. */ +#define GRUB_KERNEL_I386_PC_INSTALL_DOS_PART 0x14 + +/* The offset of GRUB_INSTALL_BSD_PART. */ +#define GRUB_KERNEL_I386_PC_INSTALL_BSD_PART 0x18 + +/* The offset of GRUB_PREFIX. */ +#define GRUB_KERNEL_I386_PC_PREFIX 0x1c + +/* End of the data section. */ +#define GRUB_KERNEL_I386_PC_DATA_END 0x5c + +/* The size of the first region which won't be compressed. */ +#define GRUB_KERNEL_I386_PC_RAW_SIZE (GRUB_KERNEL_I386_PC_DATA_END + 0x5F0) + +/* The segment where the kernel is loaded. */ +#define GRUB_BOOT_I386_PC_KERNEL_SEG 0x800 + +/* The upper memory area (starting at 640 kiB). */ +#define GRUB_MEMORY_I386_PC_UPPER 0xa0000 +#define GRUB_MEMORY_I386_QEMU_UPPER GRUB_MEMORY_I386_PC_UPPER + +/* The offset of GRUB_CORE_ENTRY_ADDR. */ +#define GRUB_BOOT_I386_QEMU_CORE_ENTRY_ADDR 0x4 + +/* The offset of GRUB_CORE_ENTRY_ADDR. */ +#define GRUB_KERNEL_I386_QEMU_CORE_ENTRY_ADDR 0x8 + +/* The offset of GRUB_KERNEL_IMAGE_SIZE. */ +#define GRUB_KERNEL_I386_QEMU_KERNEL_IMAGE_SIZE 0xc + +/* The offset of GRUB_PREFIX. */ +#define GRUB_KERNEL_I386_QEMU_PREFIX 0x10 + +/* End of the data section. */ +#define GRUB_KERNEL_I386_QEMU_DATA_END 0x50 + +#define GRUB_BOOT_SPARC64_IEEE1275_LIST_SIZE 12 + +#define GRUB_BOOT_SPARC64_IEEE1275_IMAGE_ADDRESS 0x4400 + +#define GRUB_KERNEL_POWERPC_IEEE1275_PREFIX 0x4 +#define GRUB_KERNEL_POWERPC_IEEE1275_DATA_END 0x44 +#define GRUB_KERNEL_POWERPC_IEEE1275_LINK_ALIGN 4 + +#ifdef MACHINE +#define GRUB_OFFSETS_CONCAT_(a,b,c) a ## b ## c +#define GRUB_OFFSETS_CONCAT(a,b,c) GRUB_OFFSETS_CONCAT_(a,b,c) +#define GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _TOTAL_MODULE_SIZE) +#define GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _KERNEL_IMAGE_SIZE) +#define GRUB_KERNEL_MACHINE_COMPRESSED_SIZE GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _COMPRESSED_SIZE) + +#define GRUB_KERNEL_MACHINE_PREFIX GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _PREFIX) +#define GRUB_KERNEL_MACHINE_DATA_END GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _DATA_END) +#define GRUB_BOOT_MACHINE_KERNEL_SEG GRUB_OFFSETS_CONCAT (GRUB_BOOT_, MACHINE, _KERNEL_SEG) +#define GRUB_MEMORY_MACHINE_UPPER GRUB_OFFSETS_CONCAT (GRUB_MEMORY_, MACHINE, _UPPER) +#define GRUB_KERNEL_MACHINE_RAW_SIZE GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _RAW_SIZE) +#define GRUB_KERNEL_MACHINE_INSTALL_BSD_PART GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _INSTALL_BSD_PART) +#define GRUB_KERNEL_MACHINE_INSTALL_DOS_PART GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _INSTALL_DOS_PART) +#endif + +#ifndef ASM_FILE +struct grub_pc_bios_boot_blocklist +{ + grub_uint64_t start; + grub_uint16_t len; + grub_uint16_t segment; +} __attribute__ ((packed)); +#endif + +#endif diff --git a/include/grub/powerpc/ieee1275/kernel.h b/include/grub/powerpc/ieee1275/kernel.h index 229416243..75d6c62a6 100644 --- a/include/grub/powerpc/ieee1275/kernel.h +++ b/include/grub/powerpc/ieee1275/kernel.h @@ -20,28 +20,12 @@ #define GRUB_KERNEL_MACHINE_HEADER 1 #include +#include -#define GRUB_PLATFORM_IMAGE_FORMATS "raw, elf" -#define GRUB_PLATFORM_IMAGE_DEFAULT_FORMAT "raw" - -#define GRUB_PLATFORM_IMAGE_DEFAULT GRUB_PLATFORM_IMAGE_RAW -#define GRUB_KERNEL_MACHINE_PREFIX 0x4 -#define GRUB_KERNEL_MACHINE_DATA_END 0x44 -#define GRUB_KERNEL_MACHINE_LINK_ALIGN 4 - -#define EM_TARGET EM_PPC #define GRUB_KERNEL_MACHINE_LINK_ADDR 0x200000 #ifndef ASM_FILE -typedef enum { - GRUB_PLATFORM_IMAGE_RAW, - GRUB_PLATFORM_IMAGE_ELF -} - grub_platform_image_format_t; -#define GRUB_PLATFORM_IMAGE_RAW GRUB_PLATFORM_IMAGE_RAW -#define GRUB_PLATFORM_IMAGE_ELF GRUB_PLATFORM_IMAGE_ELF - /* The prefix which points to the directory where GRUB modules and its configuration file are located. */ extern char grub_prefix[]; diff --git a/kern/i386/qemu/startup.S b/kern/i386/qemu/startup.S index 7484650b2..dc40cc4a2 100644 --- a/kern/i386/qemu/startup.S +++ b/kern/i386/qemu/startup.S @@ -27,7 +27,7 @@ _start: jmp codestart - . = _start + GRUB_KERNEL_MACHINE_CORE_ENTRY_ADDR + . = _start + GRUB_KERNEL_I386_QEMU_CORE_ENTRY_ADDR VARIABLE(grub_core_entry_addr) .long 0 VARIABLE(grub_kernel_image_size) diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index af2988a3f..08003a07f 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -72,6 +72,7 @@ struct image_target_desc unsigned section_align; signed vaddr_offset; unsigned install_dos_part, install_bsd_part; + grub_uint64_t link_addr; }; struct image_target_desc image_targets[] = @@ -90,8 +91,11 @@ struct image_target_desc image_targets[] = }, {"i386-efi", 4, 0, IMAGE_EFI, FORMAT_PE, PLATFORM_FLAGS_NONE, .section_align = GRUB_PE32_SECTION_ALIGNMENT, - .vaddr_offset = ALIGN_UP (sizeof (struct grub_pe32_header) - + 5 * sizeof (struct grub_pe32_section_table), + .vaddr_offset = ALIGN_UP (GRUB_PE32_MSDOS_STUB_SIZE + + GRUB_PE32_SIGNATURE_SIZE + + sizeof (struct grub_pe32_coff_header) + + sizeof (struct grub_pe32_optional_header) + + 4 * sizeof (struct grub_pe32_section_table), GRUB_PE32_SECTION_ALIGNMENT) }, {"i386-ieee1275", 4, 0, IMAGE_I386_IEEE1275, FORMAT_ELF, PLATFORM_FLAGS_NONE, @@ -102,8 +106,11 @@ struct image_target_desc image_targets[] = .vaddr_offset = 0}, {"x86_64-efi", 8, 0, IMAGE_EFI, FORMAT_PE, PLATFORM_FLAGS_NONE, .section_align = GRUB_PE32_SECTION_ALIGNMENT, - .vaddr_offset = ALIGN_UP (sizeof (struct grub_pe32_header) - + 5 * sizeof (struct grub_pe32_section_table), + .vaddr_offset = ALIGN_UP (GRUB_PE32_MSDOS_STUB_SIZE + + GRUB_PE32_SIGNATURE_SIZE + + sizeof (struct grub_pe32_coff_header) + + sizeof (struct grub_pe64_optional_header) + + 4 * sizeof (struct grub_pe32_section_table), GRUB_PE32_SECTION_ALIGNMENT) }, {"mipsel-yeeloong-elf", 4, 0, IMAGE_YEELOONG_ELF, FORMAT_ELF, PLATFORM_FLAGS_NONE, @@ -1150,19 +1157,35 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], case IMAGE_EFI: { void *pe_img; + grub_uint8_t *header; size_t pe_size; - struct grub_pe32_header *header; struct grub_pe32_coff_header *c; - struct grub_pe32_optional_header *o; struct grub_pe32_section_table *text_section, *data_section; struct grub_pe32_section_table *mods_section, *reloc_section; static const grub_uint8_t stub[] = GRUB_PE32_MSDOS_STUB; - int header_size = ALIGN_UP (sizeof (struct grub_pe32_header) - + 5 * sizeof (struct grub_pe32_section_table), - image_target->section_align); - int reloc_addr = ALIGN_UP (header_size + core_size, image_target->section_align); + int header_size; + int reloc_addr; - pe_size = ALIGN_UP (reloc_addr + reloc_size, image_target->section_align); + if (image_target->voidp_sizeof == 4) + header_size = ALIGN_UP (GRUB_PE32_MSDOS_STUB_SIZE + + GRUB_PE32_SIGNATURE_SIZE + + sizeof (struct grub_pe32_coff_header) + + sizeof (struct grub_pe32_optional_header) + + 4 * sizeof (struct grub_pe32_section_table), + GRUB_PE32_SECTION_ALIGNMENT); + else + header_size = ALIGN_UP (GRUB_PE32_MSDOS_STUB_SIZE + + GRUB_PE32_SIGNATURE_SIZE + + sizeof (struct grub_pe32_coff_header) + + sizeof (struct grub_pe64_optional_header) + + 4 * sizeof (struct grub_pe32_section_table), + GRUB_PE32_SECTION_ALIGNMENT); + + reloc_addr = ALIGN_UP (header_size + core_size, + image_target->section_align); + + pe_size = ALIGN_UP (reloc_addr + reloc_size, + image_target->section_align); pe_img = xmalloc (reloc_addr + reloc_size); memset (pe_img, 0, header_size); memcpy (pe_img + header_size, core_img, core_size); @@ -1170,11 +1193,12 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], header = pe_img; /* The magic. */ - memcpy (header->msdos_stub, stub, sizeof (header->msdos_stub)); - memcpy (header->signature, "PE\0\0", sizeof (header->signature)); + memcpy (header, stub, GRUB_PE32_MSDOS_STUB_SIZE); + memcpy (header + GRUB_PE32_MSDOS_STUB_SIZE, "PE\0\0", + GRUB_PE32_SIGNATURE_SIZE); /* The COFF file header. */ - c = &header->coff_header; + c = header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE; if (image_target->voidp_sizeof == 4) c->machine = grub_host_to_target16 (GRUB_PE32_MACHINE_I386); else @@ -1182,7 +1206,6 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], c->num_sections = grub_host_to_target16 (4); c->time = grub_host_to_target32 (time (0)); - c->optional_header_size = grub_host_to_target16 (sizeof (header->optional_header)); c->characteristics = grub_host_to_target16 (GRUB_PE32_EXECUTABLE_IMAGE | GRUB_PE32_LINE_NUMS_STRIPPED | ((image_target->voidp_sizeof == 4) @@ -1192,33 +1215,74 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], | GRUB_PE32_DEBUG_STRIPPED); /* The PE Optional header. */ - o = &header->optional_header; - o->magic = grub_host_to_target16 (GRUB_PE32_PE32_MAGIC); - o->code_size = grub_host_to_target32 (exec_size); - o->data_size = grub_cpu_to_le32 (reloc_addr - exec_size); - o->bss_size = grub_cpu_to_le32 (bss_size); - o->entry_addr = grub_cpu_to_le32 (start_address); - o->code_base = grub_cpu_to_le32 (header_size); if (image_target->voidp_sizeof == 4) - o->data_base = grub_host_to_target32 (header_size + exec_size); - o->image_base = 0; - o->section_alignment = grub_host_to_target32 (image_target->section_align); - o->file_alignment = grub_host_to_target32 (image_target->section_align); - o->image_size = grub_host_to_target32 (pe_size); - o->header_size = grub_host_to_target32 (header_size); - o->subsystem = grub_host_to_target16 (GRUB_PE32_SUBSYSTEM_EFI_APPLICATION); + { + struct grub_pe32_optional_header *o; - /* Do these really matter? */ - o->stack_reserve_size = grub_host_to_target32 (0x10000); - o->stack_commit_size = grub_host_to_target32 (0x10000); - o->heap_reserve_size = grub_host_to_target32 (0x10000); - o->heap_commit_size = grub_host_to_target32 (0x10000); + c->optional_header_size = grub_host_to_target16 (sizeof (struct grub_pe32_optional_header)); + + o = header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE + + sizeof (struct grub_pe32_coff_header); + o->magic = grub_host_to_target16 (GRUB_PE32_PE32_MAGIC); + o->code_size = grub_host_to_target32 (exec_size); + o->data_size = grub_cpu_to_le32 (reloc_addr - exec_size); + o->bss_size = grub_cpu_to_le32 (bss_size); + o->entry_addr = grub_cpu_to_le32 (start_address); + o->code_base = grub_cpu_to_le32 (header_size); + + o->data_base = grub_host_to_target32 (header_size + exec_size); + + o->image_base = 0; + o->section_alignment = grub_host_to_target32 (image_target->section_align); + o->file_alignment = grub_host_to_target32 (image_target->section_align); + o->image_size = grub_host_to_target32 (pe_size); + o->header_size = grub_host_to_target32 (header_size); + o->subsystem = grub_host_to_target16 (GRUB_PE32_SUBSYSTEM_EFI_APPLICATION); + + /* Do these really matter? */ + o->stack_reserve_size = grub_host_to_target32 (0x10000); + o->stack_commit_size = grub_host_to_target32 (0x10000); + o->heap_reserve_size = grub_host_to_target32 (0x10000); + o->heap_commit_size = grub_host_to_target32 (0x10000); - o->num_data_directories = grub_host_to_target32 (GRUB_PE32_NUM_DATA_DIRECTORIES); + o->num_data_directories = grub_host_to_target32 (GRUB_PE32_NUM_DATA_DIRECTORIES); - o->base_relocation_table.rva = grub_host_to_target32 (reloc_addr); - o->base_relocation_table.size = grub_host_to_target32 (reloc_size); + o->base_relocation_table.rva = grub_host_to_target32 (reloc_addr); + o->base_relocation_table.size = grub_host_to_target32 (reloc_size); + } + else + { + struct grub_pe64_optional_header *o; + c->optional_header_size = grub_host_to_target16 (sizeof (struct grub_pe32_optional_header)); + + o = header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE + + sizeof (struct grub_pe32_coff_header); + o->magic = grub_host_to_target16 (GRUB_PE32_PE32_MAGIC); + o->code_size = grub_host_to_target32 (exec_size); + o->data_size = grub_cpu_to_le32 (reloc_addr - exec_size); + o->bss_size = grub_cpu_to_le32 (bss_size); + o->entry_addr = grub_cpu_to_le32 (start_address); + o->code_base = grub_cpu_to_le32 (header_size); + o->image_base = 0; + o->section_alignment = grub_host_to_target32 (image_target->section_align); + o->file_alignment = grub_host_to_target32 (image_target->section_align); + o->image_size = grub_host_to_target32 (pe_size); + o->header_size = grub_host_to_target32 (header_size); + o->subsystem = grub_host_to_target16 (GRUB_PE32_SUBSYSTEM_EFI_APPLICATION); + + /* Do these really matter? */ + o->stack_reserve_size = grub_host_to_target32 (0x10000); + o->stack_commit_size = grub_host_to_target32 (0x10000); + o->heap_reserve_size = grub_host_to_target32 (0x10000); + o->heap_commit_size = grub_host_to_target32 (0x10000); + + o->num_data_directories + = grub_host_to_target32 (GRUB_PE32_NUM_DATA_DIRECTORIES); + + o->base_relocation_table.rva = grub_host_to_target32 (reloc_addr); + o->base_relocation_table.size = grub_host_to_target32 (reloc_size); + } /* The sections. */ text_section = (struct grub_pe32_section_table *) (header + 1); strcpy (text_section->name, ".text"); @@ -1422,10 +1486,10 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], phdr->p_flags = grub_host_to_target32 (PF_R | PF_W | PF_X); if (image_target->id == IMAGE_YEELOONG_ELF) - target_addr = ALIGN_UP (GRUB_KERNEL_MACHINE_LINK_ADDR - + kernel_size + total_module_size, 32); + target_addr = ALIGN_UP (image_target->link_addr + + kernel_size + total_module_size, 32); else - target_addr = GRUB_KERNEL_MACHINE_LINK_ADDR; + target_addr = image_target->link_addr; ehdr->e_entry = grub_host_to_target32 (target_addr); phdr->p_vaddr = grub_host_to_target32 (target_addr); phdr->p_paddr = grub_host_to_target32 (target_addr); @@ -1534,7 +1598,7 @@ Usage: %s [OPTION]... [MODULES]\n\ \n\ Make a bootable image of GRUB.\n\ \n\ - -d, --directory=DIR use images and modules under DIR [default=%s]\n\ + -d, --directory=DIR use images and modules under DIR [default=%s/@platform@]\n\ -p, --prefix=DIR set grub_prefix directory [default=%s]\n\ -m, --memdisk=FILE embed FILE as a memdisk image\n\ -f, --font=FILE embed FILE as a boot font\n\ @@ -1679,6 +1743,21 @@ main (int argc, char *argv[]) free (output); } + if (!dir) + { + const char *last; + last = strchr (image_target->name, '-'); + if (last) + last = strchr (last + 1, '-'); + if (!last) + last = image_target->name + strlen (image_target->name); + dir = xmalloc (sizeof (GRUB_LIBDIR) + (last - image_target->name)); + memcpy (dir, GRUB_LIBDIR, sizeof (GRUB_LIBDIR) - 1); + memcpy (dir + sizeof (GRUB_LIBDIR) - 1, image_target->name, + last - image_target->name); + *(dir + sizeof (GRUB_LIBDIR) - 1 + (last - image_target->name)) = 0; + } + generate_image (dir ? : GRUB_LIBDIR, prefix ? : DEFAULT_DIRECTORY, fp, argv + optind, memdisk, font, config, image_target, note); From 0253aeb7a1ae7c4bc03f4fa4f4c34ff73f4d9ff4 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 26 Apr 2010 13:11:43 +0200 Subject: [PATCH 603/738] Unified grub-mkimage achieved --- conf/common.rmk | 1 - conf/i386-pc.rmk | 4 +- include/grub/efi/pe32.h | 9 +- include/grub/kernel.h | 26 +- include/grub/offsets.h | 2 + util/grub-mkimage.c | 767 ++++------------------------------------ util/grub-mkimagexx.c | 741 ++++++++++++++++++++++++++++++++++++++ 7 files changed, 836 insertions(+), 714 deletions(-) create mode 100644 util/grub-mkimagexx.c diff --git a/conf/common.rmk b/conf/common.rmk index bab7effb9..98dca34f9 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -18,7 +18,6 @@ endif bin_UTILITIES += grub-mkimage grub_mkimage_SOURCES = gnulib/progname.c util/grub-mkimage.c util/misc.c \ util/resolve.c lib/LzmaEnc.c lib/LzFind.c -grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR) util/grub-mkimage.c_DEPENDENCIES = Makefile # For grub-probe. diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk index 1e0a3ff58..f0da94b42 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -1,7 +1,5 @@ # -*- makefile -*- -GRUB_KERNEL_MACHINE_LINK_ADDR = 0x8200 - COMMON_CFLAGS = -mrtd -mregparm=3 # Images. @@ -58,7 +56,7 @@ kernel_img_HEADERS += machine/biosdisk.h machine/vga.h machine/vbe.h \ machine/pxe.h i386/pit.h kernel_img_CFLAGS = $(COMMON_CFLAGS) $(TARGET_IMG_CFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) -kernel_img_LDFLAGS += $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_KERNEL_MACHINE_LINK_ADDR) $(COMMON_CFLAGS) +kernel_img_LDFLAGS += $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)0x8200 $(COMMON_CFLAGS) # Utilities. sbin_UTILITIES = grub-setup diff --git a/include/grub/efi/pe32.h b/include/grub/efi/pe32.h index 9d9edc220..90f9c9f5c 100644 --- a/include/grub/efi/pe32.h +++ b/include/grub/efi/pe32.h @@ -199,15 +199,8 @@ struct grub_pe64_optional_header struct grub_pe32_data_directory reserved_entry; }; -#if GRUB_TARGET_SIZEOF_VOID_P == 4 - #define GRUB_PE32_PE32_MAGIC 0x10b - -#else - -#define GRUB_PE32_PE32_MAGIC 0x20b - -#endif +#define GRUB_PE32_PE64_MAGIC 0x20b #define GRUB_PE32_SUBSYSTEM_EFI_APPLICATION 10 diff --git a/include/grub/kernel.h b/include/grub/kernel.h index bf52ffcb4..f7740b2e3 100644 --- a/include/grub/kernel.h +++ b/include/grub/kernel.h @@ -42,19 +42,33 @@ struct grub_module_header /* "gmim" (GRUB Module Info Magic). */ #define GRUB_MODULE_MAGIC 0x676d696d -struct grub_module_info +struct grub_module_info32 { /* Magic number so we know we have modules present. */ grub_uint32_t magic; -#if GRUB_TARGET_SIZEOF_VOID_P == 8 - grub_uint32_t padding; -#endif /* The offset of the modules. */ - grub_target_off_t offset; + grub_uint32_t offset; /* The size of all modules plus this header. */ - grub_target_size_t size; + grub_uint32_t size; }; +struct grub_module_info64 +{ + /* Magic number so we know we have modules present. */ + grub_uint32_t magic; + grub_uint32_t padding; + /* The offset of the modules. */ + grub_uint64_t offset; + /* The size of all modules plus this header. */ + grub_uint64_t size; +}; + +#if GRUB_TARGET_SIZEOF_VOID_P == 8 +#define grub_module_info grub_module_info64 +#else +#define grub_module_info grub_module_info32 +#endif + extern grub_addr_t grub_arch_modules_addr (void); extern void EXPORT_FUNC(grub_module_iterate) (int (*hook) (struct grub_module_header *)); diff --git a/include/grub/offsets.h b/include/grub/offsets.h index a0c2f61f9..2ba6351ca 100644 --- a/include/grub/offsets.h +++ b/include/grub/offsets.h @@ -46,6 +46,8 @@ /* The segment where the kernel is loaded. */ #define GRUB_BOOT_I386_PC_KERNEL_SEG 0x800 +#define GRUB_KERNEL_I386_PC_LINK_ADDR 0x8200 + /* The upper memory area (starting at 640 kiB). */ #define GRUB_MEMORY_I386_PC_UPPER 0xa0000 #define GRUB_MEMORY_I386_QEMU_UPPER GRUB_MEMORY_I386_PC_UPPER diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index 08003a07f..c9bafdd8b 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -131,6 +131,9 @@ struct image_target_desc image_targets[] = #define grub_target_to_host32(x) (grub_target_to_host32_real (image_target, (x))) #define grub_host_to_target32(x) (grub_host_to_target32_real (image_target, (x))) +#define grub_target_to_host64(x) (grub_target_to_host64_real (image_target, (x))) +#define grub_host_to_target64(x) (grub_host_to_target64_real (image_target, (x))) +#define grub_host_to_target_addr(x) (grub_host_to_target_addr_real (image_target, (x))) #define grub_target_to_host16(x) (grub_target_to_host16_real (image_target, (x))) #define grub_host_to_target16(x) (grub_host_to_target16_real (image_target, (x))) @@ -152,13 +155,13 @@ grub_target_to_host64_real (struct image_target_desc *image_target, grub_uint64_ return grub_le_to_cpu64 (in); } -static inline grub_uint32_t -grub_target_to_host_real (struct image_target_desc *image_target, grub_uint32_t in) +static inline grub_uint64_t +grub_host_to_target64_real (struct image_target_desc *image_target, grub_uint64_t in) { - if (image_target->voidp_sizeof == 8) - return grub_target_to_host64_real (image_target, in); + if (image_target->bigendian) + return grub_cpu_to_be64 (in); else - return grub_target_to_host32_real (image_target, in); + return grub_cpu_to_le64 (in); } static inline grub_uint32_t @@ -188,6 +191,24 @@ grub_host_to_target16_real (struct image_target_desc *image_target, grub_uint16_ return grub_cpu_to_le16 (in); } +static inline grub_uint32_t +grub_host_to_target_addr_real (struct image_target_desc *image_target, grub_uint32_t in) +{ + if (image_target->voidp_sizeof == 8) + return grub_host_to_target64_real (image_target, in); + else + return grub_host_to_target32_real (image_target, in); +} + +static inline grub_uint32_t +grub_target_to_host_real (struct image_target_desc *image_target, grub_uint32_t in) +{ + if (image_target->voidp_sizeof == 8) + return grub_target_to_host64_real (image_target, in); + else + return grub_target_to_host32_real (image_target, in); +} + #define GRUB_IEEE1275_NOTE_NAME "PowerPC" #define GRUB_IEEE1275_NOTE_TYPE 0x1275 @@ -274,230 +295,6 @@ compress_kernel (struct image_target_desc *image_target, char *kernel_img, *core_size = kernel_size; } - -/* Relocate symbols; note that this function overwrites the symbol table. - Return the address of a start symbol. */ -static Elf_Addr -relocate_symbols (Elf_Ehdr *e, Elf_Shdr *sections, - Elf_Shdr *symtab_section, Elf_Addr *section_addresses, - Elf_Half section_entsize, Elf_Half num_sections, - struct image_target_desc *image_target) -{ - Elf_Word symtab_size, sym_size, num_syms; - Elf_Off symtab_offset; - Elf_Addr start_address = 0; - Elf_Sym *sym; - Elf_Word i; - Elf_Shdr *strtab_section; - const char *strtab; - - strtab_section - = (Elf_Shdr *) ((char *) sections - + (grub_target_to_host32 (symtab_section->sh_link) - * section_entsize)); - strtab = (char *) e + grub_target_to_host32 (strtab_section->sh_offset); - - symtab_size = grub_target_to_host32 (symtab_section->sh_size); - sym_size = grub_target_to_host32 (symtab_section->sh_entsize); - symtab_offset = grub_target_to_host32 (symtab_section->sh_offset); - num_syms = symtab_size / sym_size; - - for (i = 0, sym = (Elf_Sym *) ((char *) e + symtab_offset); - i < num_syms; - i++, sym = (Elf_Sym *) ((char *) sym + sym_size)) - { - Elf_Section index; - const char *name; - - name = strtab + grub_target_to_host32 (sym->st_name); - - index = grub_target_to_host16 (sym->st_shndx); - if (index == STN_ABS) - { - continue; - } - else if ((index == STN_UNDEF)) - { - if (sym->st_name) - grub_util_error ("undefined symbol %s", name); - else - continue; - } - else if (index >= num_sections) - grub_util_error ("section %d does not exist", index); - - sym->st_value = (grub_target_to_host32 (sym->st_value) - + section_addresses[index]); - grub_util_info ("locating %s at 0x%x", name, sym->st_value); - - if (! start_address) - if (strcmp (name, "_start") == 0 || strcmp (name, "start") == 0) - start_address = sym->st_value; - } - - return start_address; -} - -/* Return the address of a symbol at the index I in the section S. */ -static Elf_Addr -get_symbol_address (Elf_Ehdr *e, Elf_Shdr *s, Elf_Word i, - struct image_target_desc *image_target) -{ - Elf_Sym *sym; - - sym = (Elf_Sym *) ((char *) e - + grub_target_to_host32 (s->sh_offset) - + i * grub_target_to_host32 (s->sh_entsize)); - return sym->st_value; -} - -/* Return the address of a modified value. */ -static Elf_Addr * -get_target_address (Elf_Ehdr *e, Elf_Shdr *s, Elf_Addr offset, - struct image_target_desc *image_target) -{ - return (Elf_Addr *) ((char *) e + grub_target_to_host32 (s->sh_offset) + offset); -} - -/* Deal with relocation information. This function relocates addresses - within the virtual address space starting from 0. So only relative - addresses can be fully resolved. Absolute addresses must be relocated - again by a PE32 relocator when loaded. */ -static void -relocate_addresses (Elf_Ehdr *e, Elf_Shdr *sections, - Elf_Addr *section_addresses, - Elf_Half section_entsize, Elf_Half num_sections, - const char *strtab, struct image_target_desc *image_target) -{ - Elf_Half i; - Elf_Shdr *s; - - for (i = 0, s = sections; - i < num_sections; - i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if ((s->sh_type == grub_host_to_target32 (SHT_REL)) || - (s->sh_type == grub_host_to_target32 (SHT_RELA))) - { - Elf_Rela *r; - Elf_Word rtab_size, r_size, num_rs; - Elf_Off rtab_offset; - Elf_Shdr *symtab_section; - Elf_Word target_section_index; - Elf_Addr target_section_addr; - Elf_Shdr *target_section; - Elf_Word j; - - symtab_section = (Elf_Shdr *) ((char *) sections - + (grub_target_to_host32 (s->sh_link) - * section_entsize)); - target_section_index = grub_target_to_host32 (s->sh_info); - target_section_addr = section_addresses[target_section_index]; - target_section = (Elf_Shdr *) ((char *) sections - + (target_section_index - * section_entsize)); - - grub_util_info ("dealing with the relocation section %s for %s", - strtab + grub_target_to_host32 (s->sh_name), - strtab + grub_target_to_host32 (target_section->sh_name)); - - rtab_size = grub_target_to_host32 (s->sh_size); - r_size = grub_target_to_host32 (s->sh_entsize); - rtab_offset = grub_target_to_host32 (s->sh_offset); - num_rs = rtab_size / r_size; - - for (j = 0, r = (Elf_Rela *) ((char *) e + rtab_offset); - j < num_rs; - j++, r = (Elf_Rela *) ((char *) r + r_size)) - { - Elf_Addr info; - Elf_Addr offset; - Elf_Addr sym_addr; - Elf_Addr *target; - Elf_Addr addend; - - offset = grub_target_to_host (r->r_offset); - target = get_target_address (e, target_section, offset, image_target); - info = grub_target_to_host (r->r_info); - sym_addr = get_symbol_address (e, symtab_section, - ELF_R_SYM (info), image_target); - - addend = (s->sh_type == grub_target_to_host32 (SHT_RELA)) ? - r->r_addend : 0; - - if (image_target->voidp_sizeof == 4) - switch (ELF_R_TYPE (info)) - { - case R_386_NONE: - break; - - case R_386_32: - /* This is absolute. */ - *target = grub_host_to_target32 (grub_target_to_host32 (*target) - + addend + sym_addr); - grub_util_info ("relocating an R_386_32 entry to 0x%x at the offset 0x%x", - *target, offset); - break; - - case R_386_PC32: - /* This is relative. */ - *target = grub_host_to_target32 (grub_target_to_host32 (*target) - + addend + sym_addr - - target_section_addr - offset - - image_target->vaddr_offset); - grub_util_info ("relocating an R_386_PC32 entry to 0x%x at the offset 0x%x", - *target, offset); - break; - default: - grub_util_error ("unknown relocation type %d", - ELF_R_TYPE (info)); - break; - } - else - switch (ELF_R_TYPE (info)) - { - - case R_X86_64_NONE: - break; - - case R_X86_64_64: - *target = grub_host_to_target64 (grub_target_to_host64 (*target) - + addend + sym_addr); - grub_util_info ("relocating an R_X86_64_64 entry to 0x%llx at the offset 0x%llx", - *target, offset); - break; - - case R_X86_64_PC32: - { - grub_uint32_t *t32 = (grub_uint32_t *) target; - *t32 = grub_host_to_target64 (grub_target_to_host32 (*t32) - + addend + sym_addr - - target_section_addr - offset - - image_target->vaddr_offset); - grub_util_info ("relocating an R_X86_64_PC32 entry to 0x%x at the offset 0x%llx", - *t32, offset); - break; - } - - case R_X86_64_32: - case R_X86_64_32S: - { - grub_uint32_t *t32 = (grub_uint32_t *) target; - *t32 = grub_host_to_target64 (grub_target_to_host32 (*t32) - + addend + sym_addr); - grub_util_info ("relocating an R_X86_64_32(S) entry to 0x%x at the offset 0x%llx", - *t32, offset); - break; - } - - default: - grub_util_error ("unknown relocation type %d", - ELF_R_TYPE (info)); - break; - } - } - } -} - struct fixup_block_list { struct fixup_block_list *next; @@ -505,457 +302,13 @@ struct fixup_block_list struct grub_pe32_fixup_block b; }; -/* Add a PE32's fixup entry for a relocation. Return the resulting address - after having written to the file OUT. */ -Elf_Addr -add_fixup_entry (struct fixup_block_list **cblock, grub_uint16_t type, - Elf_Addr addr, int flush, Elf_Addr current_address, - struct image_target_desc *image_target) -{ - struct grub_pe32_fixup_block *b; +#define MKIMAGE_ELF32 1 +#include "grub-mkimagexx.c" +#undef MKIMAGE_ELF32 - b = &((*cblock)->b); - - /* First, check if it is necessary to write out the current block. */ - if ((*cblock)->state) - { - if (flush || addr < b->page_rva || b->page_rva + 0x1000 <= addr) - { - grub_uint32_t size; - - if (flush) - { - /* Add as much padding as necessary to align the address - with a section boundary. */ - Elf_Addr next_address; - unsigned padding_size; - size_t index; - - next_address = current_address + b->block_size; - padding_size = ((ALIGN_UP (next_address, image_target->section_align) - - next_address) - >> 1); - index = ((b->block_size - sizeof (*b)) >> 1); - grub_util_info ("adding %d padding fixup entries", padding_size); - while (padding_size--) - { - b->entries[index++] = 0; - b->block_size += 2; - } - } - else if (b->block_size & (8 - 1)) - { - /* If not aligned with a 32-bit boundary, add - a padding entry. */ - size_t index; - - grub_util_info ("adding a padding fixup entry"); - index = ((b->block_size - sizeof (*b)) >> 1); - b->entries[index] = 0; - b->block_size += 2; - } - - /* Flush it. */ - grub_util_info ("writing %d bytes of a fixup block starting at 0x%x", - b->block_size, b->page_rva); - size = b->block_size; - current_address += size; - b->page_rva = grub_host_to_target32 (b->page_rva); - b->block_size = grub_host_to_target32 (b->block_size); - (*cblock)->next = xmalloc (sizeof (**cblock) + 2 * 0x1000); - memset ((*cblock)->next, 0, sizeof (**cblock) + 2 * 0x1000); - *cblock = (*cblock)->next; - } - } - - b = &((*cblock)->b); - - if (! flush) - { - grub_uint16_t entry; - size_t index; - - /* If not allocated yet, allocate a block with enough entries. */ - if (! (*cblock)->state) - { - (*cblock)->state = 1; - - /* The spec does not mention the requirement of a Page RVA. - Here, align the address with a 4K boundary for safety. */ - b->page_rva = (addr & ~(0x1000 - 1)); - b->block_size = sizeof (*b); - } - - /* Sanity check. */ - if (b->block_size >= sizeof (*b) + 2 * 0x1000) - grub_util_error ("too many fixup entries"); - - /* Add a new entry. */ - index = ((b->block_size - sizeof (*b)) >> 1); - entry = GRUB_PE32_FIXUP_ENTRY (type, addr - b->page_rva); - b->entries[index] = grub_host_to_target16 (entry); - b->block_size += 2; - } - - return current_address; -} - -/* Make a .reloc section. */ -static Elf_Addr -make_reloc_section (Elf_Ehdr *e, void **out, - Elf_Addr *section_addresses, Elf_Shdr *sections, - Elf_Half section_entsize, Elf_Half num_sections, - const char *strtab, struct image_target_desc *image_target) -{ - Elf_Half i; - Elf_Shdr *s; - struct fixup_block_list *lst, *lst0; - Elf_Addr current_address = 0; - - lst = lst0 = xmalloc (sizeof (*lst) + 2 * 0x1000); - memset (lst, 0, sizeof (*lst) + 2 * 0x1000); - - for (i = 0, s = sections; - i < num_sections; - i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if ((s->sh_type == grub_cpu_to_le32 (SHT_REL)) || - (s->sh_type == grub_cpu_to_le32 (SHT_RELA))) - { - Elf_Rel *r; - Elf_Word rtab_size, r_size, num_rs; - Elf_Off rtab_offset; - Elf_Addr section_address; - Elf_Word j; - - grub_util_info ("translating the relocation section %s", - strtab + grub_le_to_cpu32 (s->sh_name)); - - rtab_size = grub_le_to_cpu32 (s->sh_size); - r_size = grub_le_to_cpu32 (s->sh_entsize); - rtab_offset = grub_le_to_cpu32 (s->sh_offset); - num_rs = rtab_size / r_size; - - section_address = section_addresses[grub_le_to_cpu32 (s->sh_info)]; - - for (j = 0, r = (Elf_Rel *) ((char *) e + rtab_offset); - j < num_rs; - j++, r = (Elf_Rel *) ((char *) r + r_size)) - { - Elf_Addr info; - Elf_Addr offset; - - offset = grub_le_to_cpu32 (r->r_offset); - info = grub_le_to_cpu32 (r->r_info); - - /* Necessary to relocate only absolute addresses. */ - if (image_target->voidp_sizeof == 4) - { - if (ELF_R_TYPE (info) == R_386_32) - { - Elf_Addr addr; - - addr = section_address + offset; - grub_util_info ("adding a relocation entry for 0x%x", addr); - current_address = add_fixup_entry (&lst, - GRUB_PE32_REL_BASED_HIGHLOW, - addr, 0, current_address, - image_target); - } - } - else - { - if ((ELF_R_TYPE (info) == R_X86_64_32) || - (ELF_R_TYPE (info) == R_X86_64_32S)) - { - grub_util_error ("can\'t add fixup entry for R_X86_64_32(S)"); - } - else if (ELF_R_TYPE (info) == R_X86_64_64) - { - Elf_Addr addr; - - addr = section_address + offset; - grub_util_info ("adding a relocation entry for 0x%llx", addr); - current_address = add_fixup_entry (&lst, - GRUB_PE32_REL_BASED_DIR64, - addr, - 0, current_address, - image_target); - } - } - } - } - - current_address = add_fixup_entry (&lst, 0, 0, 1, current_address, image_target); - - { - grub_uint8_t *ptr; - ptr = *out = xmalloc (current_address); - for (lst = lst0; lst; lst = lst->next) - if (lst->state) - { - memcpy (ptr, &lst->b, grub_target_to_host32 (lst->b.block_size)); - ptr += grub_target_to_host32 (lst->b.block_size); - } - if (current_address + *out != ptr) - { - grub_util_error ("Bug detected %d != %d\n", ptr - (grub_uint8_t *) *out, - current_address); - } - } - - return current_address; -} - -/* Determine if this section is a text section. Return false if this - section is not allocated. */ -static int -is_text_section (Elf_Shdr *s, struct image_target_desc *image_target) -{ - if (image_target->id != IMAGE_EFI - && grub_target_to_host32 (s->sh_type) != SHT_PROGBITS) - return 0; - return ((grub_target_to_host32 (s->sh_flags) & (SHF_EXECINSTR | SHF_ALLOC)) - == (SHF_EXECINSTR | SHF_ALLOC)); -} - -/* Determine if this section is a data section. This assumes that - BSS is also a data section, since the converter initializes BSS - when producing PE32 to avoid a bug in EFI implementations. */ -static int -is_data_section (Elf_Shdr *s, struct image_target_desc *image_target) -{ - if (image_target->id != IMAGE_EFI - && grub_target_to_host32 (s->sh_type) != SHT_PROGBITS) - return 0; - return ((grub_target_to_host32 (s->sh_flags) & (SHF_EXECINSTR | SHF_ALLOC)) - == SHF_ALLOC); -} - -/* Locate section addresses by merging code sections and data sections - into .text and .data, respectively. Return the array of section - addresses. */ -static Elf_Addr * -locate_sections (Elf_Shdr *sections, Elf_Half section_entsize, - Elf_Half num_sections, const char *strtab, - grub_size_t *exec_size, grub_size_t *kernel_sz, - struct image_target_desc *image_target) -{ - int i; - Elf_Addr current_address; - Elf_Addr *section_addresses; - Elf_Shdr *s; - - section_addresses = xmalloc (sizeof (*section_addresses) * num_sections); - memset (section_addresses, 0, sizeof (*section_addresses) * num_sections); - - current_address = 0; - - /* .text */ - for (i = 0, s = sections; - i < num_sections; - i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if (is_text_section (s, image_target)) - { - Elf_Word align = grub_host_to_target32 (s->sh_addralign); - const char *name = strtab + grub_host_to_target32 (s->sh_name); - - if (align) - current_address = ALIGN_UP (current_address + image_target->vaddr_offset, - align) - image_target->vaddr_offset; - - grub_util_info ("locating the section %s at 0x%x", - name, current_address); - section_addresses[i] = current_address; - current_address += grub_host_to_target32 (s->sh_size); - } - - current_address = ALIGN_UP (current_address + image_target->vaddr_offset, - image_target->section_align) - - image_target->vaddr_offset; - *exec_size = current_address; - - /* .data */ - for (i = 0, s = sections; - i < num_sections; - i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if (is_data_section (s, image_target)) - { - Elf_Word align = grub_host_to_target32 (s->sh_addralign); - const char *name = strtab + grub_host_to_target32 (s->sh_name); - - if (align) - current_address = ALIGN_UP (current_address + image_target->vaddr_offset, - align) - - image_target->vaddr_offset; - - grub_util_info ("locating the section %s at 0x%x", - name, current_address); - section_addresses[i] = current_address; - current_address += grub_host_to_target32 (s->sh_size); - } - - current_address = ALIGN_UP (current_address + image_target->vaddr_offset, - image_target->section_align) - image_target->vaddr_offset; - *kernel_sz = current_address; - return section_addresses; -} - -/* Return if the ELF header is valid. */ -static int -check_elf_header (Elf_Ehdr *e, size_t size, struct image_target_desc *image_target) -{ - if (size < sizeof (*e) - || e->e_ident[EI_MAG0] != ELFMAG0 - || e->e_ident[EI_MAG1] != ELFMAG1 - || e->e_ident[EI_MAG2] != ELFMAG2 - || e->e_ident[EI_MAG3] != ELFMAG3 - || e->e_ident[EI_VERSION] != EV_CURRENT - || e->e_version != grub_host_to_target32 (EV_CURRENT)) - return 0; - - return 1; -} - -static char * -load_image (const char *kernel_path, grub_size_t *exec_size, - grub_size_t *kernel_sz, grub_size_t *bss_size, - grub_size_t total_module_size, Elf_Addr *start, - void **reloc_section, grub_size_t *reloc_size, - struct image_target_desc *image_target) -{ - char *kernel_img, *out_img; - const char *strtab; - Elf_Ehdr *e; - Elf_Shdr *sections; - Elf_Addr *section_addresses; - Elf_Addr *section_vaddresses; - int i; - Elf_Shdr *s; - Elf_Half num_sections; - Elf_Off section_offset; - Elf_Half section_entsize; - grub_size_t kernel_size; - Elf_Shdr *symtab_section; - - *start = 0; - - kernel_size = grub_util_get_image_size (kernel_path); - kernel_img = xmalloc (kernel_size); - grub_util_load_image (kernel_path, kernel_img); - - e = (Elf_Ehdr *) kernel_img; - if (! check_elf_header (e, kernel_size, image_target)) - grub_util_error ("invalid ELF header"); - - section_offset = grub_target_to_host32 (e->e_shoff); - section_entsize = grub_target_to_host16 (e->e_shentsize); - num_sections = grub_target_to_host16 (e->e_shnum); - - if (kernel_size < section_offset + section_entsize * num_sections) - grub_util_error ("invalid ELF format"); - - sections = (Elf_Shdr *) (kernel_img + section_offset); - - /* Relocate sections then symbols in the virtual address space. */ - s = (Elf_Shdr *) ((char *) sections - + grub_host_to_target16 (e->e_shstrndx) * section_entsize); - strtab = (char *) e + grub_host_to_target32 (s->sh_offset); - - section_addresses = locate_sections (sections, section_entsize, - num_sections, strtab, - exec_size, kernel_sz, image_target); - - if (image_target->id == IMAGE_EFI) - { - section_vaddresses = xmalloc (sizeof (*section_addresses) * num_sections); - - for (i = 0; i < num_sections; i++) - section_vaddresses[i] = section_addresses[i] + image_target->vaddr_offset; - -#if 0 - { - Elf_Addr current_address = *kernel_sz; - - for (i = 0, s = sections; - i < num_sections; - i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if (grub_target_to_host32 (s->sh_type) == SHT_NOBITS) - { - Elf_Word align = grub_host_to_target32 (s->sh_addralign); - const char *name = strtab + grub_host_to_target32 (s->sh_name); - - if (align) - current_address = ALIGN_UP (current_address + VADDR_OFFSET, align) - - VADDR_OFFSET; - - grub_util_info ("locating the section %s at 0x%x", - name, current_address); - section_vaddresses[i] = current_address + VADDR_OFFSET; - current_address += grub_host_to_target32 (s->sh_size); - } - current_address = ALIGN_UP (current_address + VADDR_OFFSET, SECTION_ALIGN) - - VADDR_OFFSET; - *bss_size = current_address - *kernel_sz; - } -#else - *bss_size = 0; -#endif - - symtab_section = NULL; - for (i = 0, s = sections; - i < num_sections; - i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if (s->sh_type == grub_host_to_target32 (SHT_SYMTAB)) - { - symtab_section = s; - break; - } - - if (! symtab_section) - grub_util_error ("no symbol table"); - - *start = relocate_symbols (e, sections, symtab_section, - section_vaddresses, section_entsize, - num_sections, image_target); - if (*start == 0) - grub_util_error ("start symbol is not defined"); - - /* Resolve addresses in the virtual address space. */ - relocate_addresses (e, sections, section_addresses, section_entsize, - num_sections, strtab, image_target); - - *reloc_size = make_reloc_section (e, reloc_section, - section_vaddresses, sections, - section_entsize, num_sections, - strtab, image_target); - - } - else - { - *bss_size = 0; - *reloc_size = 0; - *reloc_section = NULL; - } - - out_img = xmalloc (*kernel_sz + total_module_size); - - for (i = 0, s = sections; - i < num_sections; - i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if (is_data_section (s, image_target) || is_text_section (s, image_target)) - { - if (grub_target_to_host32 (s->sh_type) == SHT_NOBITS) - memset (out_img + section_addresses[i], 0, - grub_host_to_target32 (s->sh_size)); - else - memcpy (out_img + section_addresses[i], - kernel_img + grub_host_to_target32 (s->sh_offset), - grub_host_to_target32 (s->sh_size)); - } - free (kernel_img); - - return out_img; -} +#define MKIMAGE_ELF64 1 +#include "grub-mkimagexx.c" +#undef MKIMAGE_ELF64 static void generate_image (const char *dir, char *prefix, FILE *out, char *mods[], @@ -968,16 +321,18 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], char *kernel_path; size_t offset; struct grub_util_path_list *path_list, *p, *next; - struct grub_module_info *modinfo; grub_size_t bss_size; - Elf_Addr start_address; + grub_uint64_t start_address; void *rel_section; grub_size_t reloc_size; path_list = grub_util_resolve_dependencies (dir, "moddep.lst", mods); kernel_path = grub_util_get_path (dir, "kernel.img"); - total_module_size = sizeof (struct grub_module_info); + if (image_target->voidp_sizeof == 8) + total_module_size = sizeof (struct grub_module_info64); + else + total_module_size = sizeof (struct grub_module_info32); if (memdisk_path) { @@ -1006,22 +361,42 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], grub_util_info ("the total module size is 0x%x", total_module_size); - kernel_img = load_image (kernel_path, &exec_size, &kernel_size, &bss_size, - total_module_size, &start_address, &rel_section, - &reloc_size, image_target); + if (image_target->voidp_sizeof == 4) + kernel_img = load_image32 (kernel_path, &exec_size, &kernel_size, &bss_size, + total_module_size, &start_address, &rel_section, + &reloc_size, image_target); + else + kernel_img = load_image64 (kernel_path, &exec_size, &kernel_size, &bss_size, + total_module_size, &start_address, &rel_section, + &reloc_size, image_target); if (image_target->prefix + strlen (prefix) + 1 > image_target->data_end) grub_util_error (_("prefix is too long")); strcpy (kernel_img + image_target->prefix, prefix); - /* Fill in the grub_module_info structure. */ - modinfo = (struct grub_module_info *) (kernel_img + kernel_size); - memset (modinfo, 0, sizeof (struct grub_module_info)); - modinfo->magic = grub_host_to_target32 (GRUB_MODULE_MAGIC); - modinfo->offset = grub_host_to_target_addr (sizeof (struct grub_module_info)); - modinfo->size = grub_host_to_target_addr (total_module_size); + if (image_target->voidp_sizeof == 8) + { + /* Fill in the grub_module_info structure. */ + struct grub_module_info64 *modinfo; + modinfo = (struct grub_module_info64 *) (kernel_img + kernel_size); + memset (modinfo, 0, sizeof (struct grub_module_info64)); + modinfo->magic = grub_host_to_target32 (GRUB_MODULE_MAGIC); + modinfo->offset = grub_host_to_target_addr (sizeof (struct grub_module_info64)); + modinfo->size = grub_host_to_target_addr (total_module_size); + offset = kernel_size + sizeof (struct grub_module_info64); + } + else + { + /* Fill in the grub_module_info structure. */ + struct grub_module_info32 *modinfo; + modinfo = (struct grub_module_info32 *) (kernel_img + kernel_size); + memset (modinfo, 0, sizeof (struct grub_module_info32)); + modinfo->magic = grub_host_to_target32 (GRUB_MODULE_MAGIC); + modinfo->offset = grub_host_to_target_addr (sizeof (struct grub_module_info32)); + modinfo->size = grub_host_to_target_addr (total_module_size); + offset = kernel_size + sizeof (struct grub_module_info32); + } - offset = kernel_size + sizeof (struct grub_module_info); for (p = path_list; p; p = p->next) { struct grub_module_header *header; @@ -1119,9 +494,9 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], char *boot_path, *boot_img; size_t boot_size; - if (GRUB_KERNEL_MACHINE_LINK_ADDR + core_size > GRUB_MEMORY_I386_PC_UPPER) + if (GRUB_KERNEL_I386_PC_LINK_ADDR + core_size > GRUB_MEMORY_I386_PC_UPPER) grub_util_error (_("core image is too big (%p > %p)"), - GRUB_KERNEL_MACHINE_LINK_ADDR + core_size, + GRUB_KERNEL_I386_PC_LINK_ADDR + core_size, GRUB_MEMORY_I386_PC_UPPER); num = ((core_size + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS); @@ -1258,7 +633,7 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], o = header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE + sizeof (struct grub_pe32_coff_header); - o->magic = grub_host_to_target16 (GRUB_PE32_PE32_MAGIC); + o->magic = grub_host_to_target16 (GRUB_PE32_PE64_MAGIC); o->code_size = grub_host_to_target32 (exec_size); o->data_size = grub_cpu_to_le32 (reloc_addr - exec_size); o->bss_size = grub_cpu_to_le32 (bss_size); @@ -1523,7 +898,7 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], phdr[1].p_type = grub_host_to_target32 (PT_NOTE); phdr[1].p_flags = grub_host_to_target32 (PF_R); - phdr[1].p_align = grub_host_to_target32 (GRUB_TARGET_SIZEOF_LONG); + phdr[1].p_align = grub_host_to_target32 (image_target->voidp_sizeof); phdr[1].p_vaddr = 0; phdr[1].p_paddr = 0; phdr[1].p_filesz = grub_host_to_target32 (note_size); diff --git a/util/grub-mkimagexx.c b/util/grub-mkimagexx.c new file mode 100644 index 000000000..eb0c7a514 --- /dev/null +++ b/util/grub-mkimagexx.c @@ -0,0 +1,741 @@ +/* grub-mkimage.c - make a bootable image */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#if defined(MKIMAGE_ELF32) +# define SUFFIX(x) x ## 32 +# define ELFCLASSXX ELFCLASS32 +# define Elf_Ehdr Elf32_Ehdr +# define Elf_Phdr Elf32_Phdr +# define Elf_Addr Elf32_Addr +# define Elf_Sym Elf32_Sym +# define Elf_Off Elf32_Off +# define Elf_Shdr Elf32_Shdr +# define Elf_Rela Elf32_Rela +# define Elf_Rel Elf32_Rel +# define ELF_R_SYM(val) ELF32_R_SYM(val) +# define ELF_R_TYPE(val) ELF32_R_TYPE(val) +#elif defined(MKIMAGE_ELF64) +# define SUFFIX(x) x ## 64 +# define ELFCLASSXX ELFCLASS64 +# define Elf_Ehdr Elf64_Ehdr +# define Elf_Phdr Elf64_Phdr +# define Elf_Addr Elf64_Addr +# define Elf_Sym Elf64_Sym +# define Elf_Off Elf64_Off +# define Elf_Shdr Elf64_Shdr +# define Elf_Rela Elf64_Rela +# define Elf_Rel Elf64_Rel +# define ELF_R_SYM(val) ELF64_R_SYM(val) +# define ELF_R_TYPE(val) ELF64_R_TYPE(val) +#else +#error "I'm confused" +#endif + +/* Relocate symbols; note that this function overwrites the symbol table. + Return the address of a start symbol. */ +static Elf_Addr +SUFFIX (relocate_symbols) (Elf_Ehdr *e, Elf_Shdr *sections, + Elf_Shdr *symtab_section, Elf_Addr *section_addresses, + Elf_Half section_entsize, Elf_Half num_sections, + struct image_target_desc *image_target) +{ + Elf_Word symtab_size, sym_size, num_syms; + Elf_Off symtab_offset; + Elf_Addr start_address = 0; + Elf_Sym *sym; + Elf_Word i; + Elf_Shdr *strtab_section; + const char *strtab; + + strtab_section + = (Elf_Shdr *) ((char *) sections + + (grub_target_to_host32 (symtab_section->sh_link) + * section_entsize)); + strtab = (char *) e + grub_target_to_host32 (strtab_section->sh_offset); + + symtab_size = grub_target_to_host32 (symtab_section->sh_size); + sym_size = grub_target_to_host32 (symtab_section->sh_entsize); + symtab_offset = grub_target_to_host32 (symtab_section->sh_offset); + num_syms = symtab_size / sym_size; + + for (i = 0, sym = (Elf_Sym *) ((char *) e + symtab_offset); + i < num_syms; + i++, sym = (Elf_Sym *) ((char *) sym + sym_size)) + { + Elf_Section index; + const char *name; + + name = strtab + grub_target_to_host32 (sym->st_name); + + index = grub_target_to_host16 (sym->st_shndx); + if (index == STN_ABS) + { + continue; + } + else if ((index == STN_UNDEF)) + { + if (sym->st_name) + grub_util_error ("undefined symbol %s", name); + else + continue; + } + else if (index >= num_sections) + grub_util_error ("section %d does not exist", index); + + sym->st_value = (grub_target_to_host32 (sym->st_value) + + section_addresses[index]); + grub_util_info ("locating %s at 0x%x", name, sym->st_value); + + if (! start_address) + if (strcmp (name, "_start") == 0 || strcmp (name, "start") == 0) + start_address = sym->st_value; + } + + return start_address; +} + +/* Return the address of a symbol at the index I in the section S. */ +static Elf_Addr +SUFFIX (get_symbol_address) (Elf_Ehdr *e, Elf_Shdr *s, Elf_Word i, + struct image_target_desc *image_target) +{ + Elf_Sym *sym; + + sym = (Elf_Sym *) ((char *) e + + grub_target_to_host32 (s->sh_offset) + + i * grub_target_to_host32 (s->sh_entsize)); + return sym->st_value; +} + +/* Return the address of a modified value. */ +static Elf_Addr * +SUFFIX (get_target_address) (Elf_Ehdr *e, Elf_Shdr *s, Elf_Addr offset, + struct image_target_desc *image_target) +{ + return (Elf_Addr *) ((char *) e + grub_target_to_host32 (s->sh_offset) + offset); +} + +/* Deal with relocation information. This function relocates addresses + within the virtual address space starting from 0. So only relative + addresses can be fully resolved. Absolute addresses must be relocated + again by a PE32 relocator when loaded. */ +static void +SUFFIX (relocate_addresses) (Elf_Ehdr *e, Elf_Shdr *sections, + Elf_Addr *section_addresses, + Elf_Half section_entsize, Elf_Half num_sections, + const char *strtab, struct image_target_desc *image_target) +{ + Elf_Half i; + Elf_Shdr *s; + + for (i = 0, s = sections; + i < num_sections; + i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + if ((s->sh_type == grub_host_to_target32 (SHT_REL)) || + (s->sh_type == grub_host_to_target32 (SHT_RELA))) + { + Elf_Rela *r; + Elf_Word rtab_size, r_size, num_rs; + Elf_Off rtab_offset; + Elf_Shdr *symtab_section; + Elf_Word target_section_index; + Elf_Addr target_section_addr; + Elf_Shdr *target_section; + Elf_Word j; + + symtab_section = (Elf_Shdr *) ((char *) sections + + (grub_target_to_host32 (s->sh_link) + * section_entsize)); + target_section_index = grub_target_to_host32 (s->sh_info); + target_section_addr = section_addresses[target_section_index]; + target_section = (Elf_Shdr *) ((char *) sections + + (target_section_index + * section_entsize)); + + grub_util_info ("dealing with the relocation section %s for %s", + strtab + grub_target_to_host32 (s->sh_name), + strtab + grub_target_to_host32 (target_section->sh_name)); + + rtab_size = grub_target_to_host32 (s->sh_size); + r_size = grub_target_to_host32 (s->sh_entsize); + rtab_offset = grub_target_to_host32 (s->sh_offset); + num_rs = rtab_size / r_size; + + for (j = 0, r = (Elf_Rela *) ((char *) e + rtab_offset); + j < num_rs; + j++, r = (Elf_Rela *) ((char *) r + r_size)) + { + Elf_Addr info; + Elf_Addr offset; + Elf_Addr sym_addr; + Elf_Addr *target; + Elf_Addr addend; + + offset = grub_target_to_host (r->r_offset); + target = SUFFIX (get_target_address) (e, target_section, + offset, image_target); + info = grub_target_to_host (r->r_info); + sym_addr = SUFFIX (get_symbol_address) (e, symtab_section, + ELF_R_SYM (info), image_target); + + addend = (s->sh_type == grub_target_to_host32 (SHT_RELA)) ? + r->r_addend : 0; + + if (image_target->voidp_sizeof == 4) + switch (ELF_R_TYPE (info)) + { + case R_386_NONE: + break; + + case R_386_32: + /* This is absolute. */ + *target = grub_host_to_target32 (grub_target_to_host32 (*target) + + addend + sym_addr); + grub_util_info ("relocating an R_386_32 entry to 0x%x at the offset 0x%x", + *target, offset); + break; + + case R_386_PC32: + /* This is relative. */ + *target = grub_host_to_target32 (grub_target_to_host32 (*target) + + addend + sym_addr + - target_section_addr - offset + - image_target->vaddr_offset); + grub_util_info ("relocating an R_386_PC32 entry to 0x%x at the offset 0x%x", + *target, offset); + break; + default: + grub_util_error ("unknown relocation type %d", + ELF_R_TYPE (info)); + break; + } + else + switch (ELF_R_TYPE (info)) + { + + case R_X86_64_NONE: + break; + + case R_X86_64_64: + *target = grub_host_to_target64 (grub_target_to_host64 (*target) + + addend + sym_addr); + grub_util_info ("relocating an R_X86_64_64 entry to 0x%llx at the offset 0x%llx", + *target, offset); + break; + + case R_X86_64_PC32: + { + grub_uint32_t *t32 = (grub_uint32_t *) target; + *t32 = grub_host_to_target64 (grub_target_to_host32 (*t32) + + addend + sym_addr + - target_section_addr - offset + - image_target->vaddr_offset); + grub_util_info ("relocating an R_X86_64_PC32 entry to 0x%x at the offset 0x%llx", + *t32, offset); + break; + } + + case R_X86_64_32: + case R_X86_64_32S: + { + grub_uint32_t *t32 = (grub_uint32_t *) target; + *t32 = grub_host_to_target64 (grub_target_to_host32 (*t32) + + addend + sym_addr); + grub_util_info ("relocating an R_X86_64_32(S) entry to 0x%x at the offset 0x%llx", + *t32, offset); + break; + } + + default: + grub_util_error ("unknown relocation type %d", + ELF_R_TYPE (info)); + break; + } + } + } +} + +/* Add a PE32's fixup entry for a relocation. Return the resulting address + after having written to the file OUT. */ +static Elf_Addr +SUFFIX (add_fixup_entry) (struct fixup_block_list **cblock, grub_uint16_t type, + Elf_Addr addr, int flush, Elf_Addr current_address, + struct image_target_desc *image_target) +{ + struct grub_pe32_fixup_block *b; + + b = &((*cblock)->b); + + /* First, check if it is necessary to write out the current block. */ + if ((*cblock)->state) + { + if (flush || addr < b->page_rva || b->page_rva + 0x1000 <= addr) + { + grub_uint32_t size; + + if (flush) + { + /* Add as much padding as necessary to align the address + with a section boundary. */ + Elf_Addr next_address; + unsigned padding_size; + size_t index; + + next_address = current_address + b->block_size; + padding_size = ((ALIGN_UP (next_address, image_target->section_align) + - next_address) + >> 1); + index = ((b->block_size - sizeof (*b)) >> 1); + grub_util_info ("adding %d padding fixup entries", padding_size); + while (padding_size--) + { + b->entries[index++] = 0; + b->block_size += 2; + } + } + else if (b->block_size & (8 - 1)) + { + /* If not aligned with a 32-bit boundary, add + a padding entry. */ + size_t index; + + grub_util_info ("adding a padding fixup entry"); + index = ((b->block_size - sizeof (*b)) >> 1); + b->entries[index] = 0; + b->block_size += 2; + } + + /* Flush it. */ + grub_util_info ("writing %d bytes of a fixup block starting at 0x%x", + b->block_size, b->page_rva); + size = b->block_size; + current_address += size; + b->page_rva = grub_host_to_target32 (b->page_rva); + b->block_size = grub_host_to_target32 (b->block_size); + (*cblock)->next = xmalloc (sizeof (**cblock) + 2 * 0x1000); + memset ((*cblock)->next, 0, sizeof (**cblock) + 2 * 0x1000); + *cblock = (*cblock)->next; + } + } + + b = &((*cblock)->b); + + if (! flush) + { + grub_uint16_t entry; + size_t index; + + /* If not allocated yet, allocate a block with enough entries. */ + if (! (*cblock)->state) + { + (*cblock)->state = 1; + + /* The spec does not mention the requirement of a Page RVA. + Here, align the address with a 4K boundary for safety. */ + b->page_rva = (addr & ~(0x1000 - 1)); + b->block_size = sizeof (*b); + } + + /* Sanity check. */ + if (b->block_size >= sizeof (*b) + 2 * 0x1000) + grub_util_error ("too many fixup entries"); + + /* Add a new entry. */ + index = ((b->block_size - sizeof (*b)) >> 1); + entry = GRUB_PE32_FIXUP_ENTRY (type, addr - b->page_rva); + b->entries[index] = grub_host_to_target16 (entry); + b->block_size += 2; + } + + return current_address; +} + +/* Make a .reloc section. */ +static Elf_Addr +SUFFIX (make_reloc_section) (Elf_Ehdr *e, void **out, + Elf_Addr *section_addresses, Elf_Shdr *sections, + Elf_Half section_entsize, Elf_Half num_sections, + const char *strtab, struct image_target_desc *image_target) +{ + Elf_Half i; + Elf_Shdr *s; + struct fixup_block_list *lst, *lst0; + Elf_Addr current_address = 0; + + lst = lst0 = xmalloc (sizeof (*lst) + 2 * 0x1000); + memset (lst, 0, sizeof (*lst) + 2 * 0x1000); + + for (i = 0, s = sections; + i < num_sections; + i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + if ((s->sh_type == grub_cpu_to_le32 (SHT_REL)) || + (s->sh_type == grub_cpu_to_le32 (SHT_RELA))) + { + Elf_Rel *r; + Elf_Word rtab_size, r_size, num_rs; + Elf_Off rtab_offset; + Elf_Addr section_address; + Elf_Word j; + + grub_util_info ("translating the relocation section %s", + strtab + grub_le_to_cpu32 (s->sh_name)); + + rtab_size = grub_le_to_cpu32 (s->sh_size); + r_size = grub_le_to_cpu32 (s->sh_entsize); + rtab_offset = grub_le_to_cpu32 (s->sh_offset); + num_rs = rtab_size / r_size; + + section_address = section_addresses[grub_le_to_cpu32 (s->sh_info)]; + + for (j = 0, r = (Elf_Rel *) ((char *) e + rtab_offset); + j < num_rs; + j++, r = (Elf_Rel *) ((char *) r + r_size)) + { + Elf_Addr info; + Elf_Addr offset; + + offset = grub_le_to_cpu32 (r->r_offset); + info = grub_le_to_cpu32 (r->r_info); + + /* Necessary to relocate only absolute addresses. */ + if (image_target->voidp_sizeof == 4) + { + if (ELF_R_TYPE (info) == R_386_32) + { + Elf_Addr addr; + + addr = section_address + offset; + grub_util_info ("adding a relocation entry for 0x%x", addr); + current_address + = SUFFIX (add_fixup_entry) (&lst, + GRUB_PE32_REL_BASED_HIGHLOW, + addr, 0, current_address, + image_target); + } + } + else + { + if ((ELF_R_TYPE (info) == R_X86_64_32) || + (ELF_R_TYPE (info) == R_X86_64_32S)) + { + grub_util_error ("can\'t add fixup entry for R_X86_64_32(S)"); + } + else if (ELF_R_TYPE (info) == R_X86_64_64) + { + Elf_Addr addr; + + addr = section_address + offset; + grub_util_info ("adding a relocation entry for 0x%llx", addr); + current_address + = SUFFIX (add_fixup_entry) (&lst, + GRUB_PE32_REL_BASED_DIR64, + addr, + 0, current_address, + image_target); + } + } + } + } + + current_address = SUFFIX (add_fixup_entry) (&lst, 0, 0, 1, current_address, image_target); + + { + grub_uint8_t *ptr; + ptr = *out = xmalloc (current_address); + for (lst = lst0; lst; lst = lst->next) + if (lst->state) + { + memcpy (ptr, &lst->b, grub_target_to_host32 (lst->b.block_size)); + ptr += grub_target_to_host32 (lst->b.block_size); + } + if (current_address + *out != ptr) + { + grub_util_error ("Bug detected %d != %d\n", ptr - (grub_uint8_t *) *out, + current_address); + } + } + + return current_address; +} + +/* Determine if this section is a text section. Return false if this + section is not allocated. */ +static int +SUFFIX (is_text_section) (Elf_Shdr *s, struct image_target_desc *image_target) +{ + if (image_target->id != IMAGE_EFI + && grub_target_to_host32 (s->sh_type) != SHT_PROGBITS) + return 0; + return ((grub_target_to_host32 (s->sh_flags) & (SHF_EXECINSTR | SHF_ALLOC)) + == (SHF_EXECINSTR | SHF_ALLOC)); +} + +/* Determine if this section is a data section. This assumes that + BSS is also a data section, since the converter initializes BSS + when producing PE32 to avoid a bug in EFI implementations. */ +static int +SUFFIX (is_data_section) (Elf_Shdr *s, struct image_target_desc *image_target) +{ + if (image_target->id != IMAGE_EFI + && grub_target_to_host32 (s->sh_type) != SHT_PROGBITS) + return 0; + return ((grub_target_to_host32 (s->sh_flags) & (SHF_EXECINSTR | SHF_ALLOC)) + == SHF_ALLOC); +} + +/* Return if the ELF header is valid. */ +static int +SUFFIX (check_elf_header) (Elf_Ehdr *e, size_t size, struct image_target_desc *image_target) +{ + if (size < sizeof (*e) + || e->e_ident[EI_MAG0] != ELFMAG0 + || e->e_ident[EI_MAG1] != ELFMAG1 + || e->e_ident[EI_MAG2] != ELFMAG2 + || e->e_ident[EI_MAG3] != ELFMAG3 + || e->e_ident[EI_VERSION] != EV_CURRENT + || e->e_ident[EI_CLASS] != ELFCLASSXX + || e->e_version != grub_host_to_target32 (EV_CURRENT)) + return 0; + + return 1; +} + +/* Locate section addresses by merging code sections and data sections + into .text and .data, respectively. Return the array of section + addresses. */ +static Elf_Addr * +SUFFIX (locate_sections) (Elf_Shdr *sections, Elf_Half section_entsize, + Elf_Half num_sections, const char *strtab, + grub_size_t *exec_size, grub_size_t *kernel_sz, + struct image_target_desc *image_target) +{ + int i; + Elf_Addr current_address; + Elf_Addr *section_addresses; + Elf_Shdr *s; + + section_addresses = xmalloc (sizeof (*section_addresses) * num_sections); + memset (section_addresses, 0, sizeof (*section_addresses) * num_sections); + + current_address = 0; + + /* .text */ + for (i = 0, s = sections; + i < num_sections; + i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + if (SUFFIX (is_text_section) (s, image_target)) + { + Elf_Word align = grub_host_to_target32 (s->sh_addralign); + const char *name = strtab + grub_host_to_target32 (s->sh_name); + + if (align) + current_address = ALIGN_UP (current_address + image_target->vaddr_offset, + align) - image_target->vaddr_offset; + + grub_util_info ("locating the section %s at 0x%x", + name, current_address); + section_addresses[i] = current_address; + current_address += grub_host_to_target32 (s->sh_size); + } + + current_address = ALIGN_UP (current_address + image_target->vaddr_offset, + image_target->section_align) + - image_target->vaddr_offset; + *exec_size = current_address; + + /* .data */ + for (i = 0, s = sections; + i < num_sections; + i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + if (SUFFIX (is_data_section) (s, image_target)) + { + Elf_Word align = grub_host_to_target32 (s->sh_addralign); + const char *name = strtab + grub_host_to_target32 (s->sh_name); + + if (align) + current_address = ALIGN_UP (current_address + image_target->vaddr_offset, + align) + - image_target->vaddr_offset; + + grub_util_info ("locating the section %s at 0x%x", + name, current_address); + section_addresses[i] = current_address; + current_address += grub_host_to_target32 (s->sh_size); + } + + current_address = ALIGN_UP (current_address + image_target->vaddr_offset, + image_target->section_align) - image_target->vaddr_offset; + *kernel_sz = current_address; + return section_addresses; +} + +static char * +SUFFIX (load_image) (const char *kernel_path, grub_size_t *exec_size, + grub_size_t *kernel_sz, grub_size_t *bss_size, + grub_size_t total_module_size, grub_uint64_t *start, + void **reloc_section, grub_size_t *reloc_size, + struct image_target_desc *image_target) +{ + char *kernel_img, *out_img; + const char *strtab; + Elf_Ehdr *e; + Elf_Shdr *sections; + Elf_Addr *section_addresses; + Elf_Addr *section_vaddresses; + int i; + Elf_Shdr *s; + Elf_Half num_sections; + Elf_Off section_offset; + Elf_Half section_entsize; + grub_size_t kernel_size; + Elf_Shdr *symtab_section; + + *start = 0; + + kernel_size = grub_util_get_image_size (kernel_path); + kernel_img = xmalloc (kernel_size); + grub_util_load_image (kernel_path, kernel_img); + + e = (Elf_Ehdr *) kernel_img; + if (! SUFFIX (check_elf_header) (e, kernel_size, image_target)) + grub_util_error ("invalid ELF header"); + + section_offset = grub_target_to_host32 (e->e_shoff); + section_entsize = grub_target_to_host16 (e->e_shentsize); + num_sections = grub_target_to_host16 (e->e_shnum); + + if (kernel_size < section_offset + section_entsize * num_sections) + grub_util_error ("invalid ELF format"); + + sections = (Elf_Shdr *) (kernel_img + section_offset); + + /* Relocate sections then symbols in the virtual address space. */ + s = (Elf_Shdr *) ((char *) sections + + grub_host_to_target16 (e->e_shstrndx) * section_entsize); + strtab = (char *) e + grub_host_to_target32 (s->sh_offset); + + section_addresses = SUFFIX (locate_sections) (sections, section_entsize, + num_sections, strtab, + exec_size, kernel_sz, image_target); + + if (image_target->id == IMAGE_EFI) + { + section_vaddresses = xmalloc (sizeof (*section_addresses) * num_sections); + + for (i = 0; i < num_sections; i++) + section_vaddresses[i] = section_addresses[i] + image_target->vaddr_offset; + +#if 0 + { + Elf_Addr current_address = *kernel_sz; + + for (i = 0, s = sections; + i < num_sections; + i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + if (grub_target_to_host32 (s->sh_type) == SHT_NOBITS) + { + Elf_Word align = grub_host_to_target32 (s->sh_addralign); + const char *name = strtab + grub_host_to_target32 (s->sh_name); + + if (align) + current_address = ALIGN_UP (current_address + VADDR_OFFSET, align) + - VADDR_OFFSET; + + grub_util_info ("locating the section %s at 0x%x", + name, current_address); + section_vaddresses[i] = current_address + VADDR_OFFSET; + current_address += grub_host_to_target32 (s->sh_size); + } + current_address = ALIGN_UP (current_address + VADDR_OFFSET, SECTION_ALIGN) + - VADDR_OFFSET; + *bss_size = current_address - *kernel_sz; + } +#else + *bss_size = 0; +#endif + + symtab_section = NULL; + for (i = 0, s = sections; + i < num_sections; + i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + if (s->sh_type == grub_host_to_target32 (SHT_SYMTAB)) + { + symtab_section = s; + break; + } + + if (! symtab_section) + grub_util_error ("no symbol table"); + + *start = SUFFIX (relocate_symbols) (e, sections, symtab_section, + section_vaddresses, section_entsize, + num_sections, image_target); + if (*start == 0) + grub_util_error ("start symbol is not defined"); + + /* Resolve addresses in the virtual address space. */ + SUFFIX (relocate_addresses) (e, sections, section_addresses, section_entsize, + num_sections, strtab, image_target); + + *reloc_size = SUFFIX (make_reloc_section) (e, reloc_section, + section_vaddresses, sections, + section_entsize, num_sections, + strtab, image_target); + } + else + { + *bss_size = 0; + *reloc_size = 0; + *reloc_section = NULL; + } + + out_img = xmalloc (*kernel_sz + total_module_size); + + for (i = 0, s = sections; + i < num_sections; + i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + if (SUFFIX (is_data_section) (s, image_target) + || SUFFIX (is_text_section) (s, image_target)) + { + if (grub_target_to_host32 (s->sh_type) == SHT_NOBITS) + memset (out_img + section_addresses[i], 0, + grub_host_to_target32 (s->sh_size)); + else + memcpy (out_img + section_addresses[i], + kernel_img + grub_host_to_target32 (s->sh_offset), + grub_host_to_target32 (s->sh_size)); + } + free (kernel_img); + + return out_img; +} + + +#undef SUFFIX +#undef ELFCLASSXX +#undef Elf_Ehdr +#undef Elf_Phdr +#undef Elf_Shdr +#undef Elf_Addr +#undef Elf_Sym +#undef Elf_Off +#undef Elf_Rela +#undef Elf_Rel +#undef ELF_R_TYPE +#undef ELF_R_SYM From 962b15b4c19ba248a7e66ebd9f504c901f917361 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 26 Apr 2010 14:42:40 +0200 Subject: [PATCH 604/738] Fill info tables for qemu, sparc and mips --- boot/sparc64/ieee1275/diskboot.S | 2 +- include/grub/mips/kernel.h | 33 ----- include/grub/offsets.h | 31 ++++ include/grub/sparc64/ieee1275/kernel.h | 16 -- kern/mips/startup.S | 23 +-- kern/sparc64/ieee1275/crt0.S | 1 + util/grub-mkimage.c | 198 ++++++++++++++++++------- util/grub-mkimagexx.c | 27 ++-- 8 files changed, 205 insertions(+), 126 deletions(-) diff --git a/boot/sparc64/ieee1275/diskboot.S b/boot/sparc64/ieee1275/diskboot.S index a8fd50d87..83dfee098 100644 --- a/boot/sparc64/ieee1275/diskboot.S +++ b/boot/sparc64/ieee1275/diskboot.S @@ -137,7 +137,7 @@ lastlist: .word 0 .word 0 - . = _start + (0x200 - GRUB_BOOT_MACHINE_LIST_SIZE) + . = _start + (0x200 - GRUB_BOOT_SPARC64_IEEE1275_LIST_SIZE) blocklist_default_start: .word 0 .word 2 diff --git a/include/grub/mips/kernel.h b/include/grub/mips/kernel.h index 172c1dbe2..bc4d43b2b 100644 --- a/include/grub/mips/kernel.h +++ b/include/grub/mips/kernel.h @@ -23,41 +23,8 @@ /* Non-zero value is only needed for PowerMacs. */ #define GRUB_MOD_GAP 0x0 -#define GRUB_KERNEL_MACHINE_LINK_ALIGN 32 - -#define GRUB_KERNEL_CPU_RAW_SIZE 0x200 -#define GRUB_KERNEL_CPU_COMPRESSED_SIZE 0x8 -#define GRUB_KERNEL_CPU_TOTAL_MODULE_SIZE 0xc -#define GRUB_KERNEL_CPU_KERNEL_IMAGE_SIZE 0x10 - -#define GRUB_KERNEL_CPU_PREFIX GRUB_KERNEL_CPU_RAW_SIZE -#define GRUB_KERNEL_CPU_DATA_END GRUB_KERNEL_CPU_RAW_SIZE + 0x48 - -#define GRUB_KERNEL_MACHINE_RAW_SIZE GRUB_KERNEL_CPU_RAW_SIZE - -#define GRUB_KERNEL_MACHINE_PREFIX GRUB_KERNEL_CPU_PREFIX -#define GRUB_KERNEL_MACHINE_DATA_END GRUB_KERNEL_CPU_DATA_END -#define GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE GRUB_KERNEL_CPU_KERNEL_IMAGE_SIZE -#define GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE GRUB_KERNEL_CPU_TOTAL_MODULE_SIZE -#define GRUB_KERNEL_MACHINE_COMPRESSED_SIZE GRUB_KERNEL_CPU_COMPRESSED_SIZE - -#define GRUB_PLATFORM_IMAGE_FORMATS "raw, elf" -#define GRUB_PLATFORM_IMAGE_DEFAULT_FORMAT "raw" - -#define GRUB_PLATFORM_IMAGE_DEFAULT GRUB_PLATFORM_IMAGE_RAW - -#define EM_TARGET EM_MIPS - #ifndef ASM_FILE -typedef enum { - GRUB_PLATFORM_IMAGE_RAW, - GRUB_PLATFORM_IMAGE_ELF -} - grub_platform_image_format_t; -#define GRUB_PLATFORM_IMAGE_RAW GRUB_PLATFORM_IMAGE_RAW -#define GRUB_PLATFORM_IMAGE_ELF GRUB_PLATFORM_IMAGE_ELF - /* The prefix which points to the directory where GRUB modules and its configuration file are located. */ extern char grub_prefix[]; diff --git a/include/grub/offsets.h b/include/grub/offsets.h index 2ba6351ca..fc4cd0a46 100644 --- a/include/grub/offsets.h +++ b/include/grub/offsets.h @@ -67,14 +67,45 @@ /* End of the data section. */ #define GRUB_KERNEL_I386_QEMU_DATA_END 0x50 +#define GRUB_KERNEL_I386_QEMU_LINK_ADDR 0x8200 + +/* The offset of GRUB_TOTAL_MODULE_SIZE. */ +#define GRUB_KERNEL_SPARC64_IEEE1275_TOTAL_MODULE_SIZE 0x8 + +/* The offset of GRUB_KERNEL_IMAGE_SIZE. */ +#define GRUB_KERNEL_SPARC64_IEEE1275_KERNEL_IMAGE_SIZE 0xc + +/* The offset of GRUB_COMPRESSED_SIZE. */ +#define GRUB_KERNEL_SPARC64_IEEE1275_COMPRESSED_SIZE 0x10 + +/* The offset of GRUB_PREFIX. */ +#define GRUB_KERNEL_SPARC64_IEEE1275_PREFIX 0x14 + +/* End of the data section. */ +#define GRUB_KERNEL_SPARC64_IEEE1275_DATA_END 0x114 + #define GRUB_BOOT_SPARC64_IEEE1275_LIST_SIZE 12 #define GRUB_BOOT_SPARC64_IEEE1275_IMAGE_ADDRESS 0x4400 +#define GRUB_KERNEL_SPARC64_IEEE1275_RAW_SIZE 0 +#define GRUB_KERNEL_SPARC64_IEEE1275_LINK_ADDR 0x4400 #define GRUB_KERNEL_POWERPC_IEEE1275_PREFIX 0x4 #define GRUB_KERNEL_POWERPC_IEEE1275_DATA_END 0x44 #define GRUB_KERNEL_POWERPC_IEEE1275_LINK_ALIGN 4 +#define GRUB_KERNEL_MIPS_YEELOONG_LINK_ADDR 0x80200000 + +#define GRUB_KERNEL_MIPS_YEELOONG_LINK_ALIGN 32 + +#define GRUB_KERNEL_MIPS_YEELOONG_RAW_SIZE 0x200 +#define GRUB_KERNEL_MIPS_YEELOONG_COMPRESSED_SIZE 0x8 +#define GRUB_KERNEL_MIPS_YEELOONG_TOTAL_MODULE_SIZE 0xc +#define GRUB_KERNEL_MIPS_YEELOONG_KERNEL_IMAGE_SIZE 0x10 + +#define GRUB_KERNEL_MIPS_YEELOONG_PREFIX GRUB_KERNEL_MIPS_YEELOONG_RAW_SIZE +#define GRUB_KERNEL_MIPS_YEELOONG_DATA_END GRUB_KERNEL_MIPS_YEELOONG_RAW_SIZE + 0x48 + #ifdef MACHINE #define GRUB_OFFSETS_CONCAT_(a,b,c) a ## b ## c #define GRUB_OFFSETS_CONCAT(a,b,c) GRUB_OFFSETS_CONCAT_(a,b,c) diff --git a/include/grub/sparc64/ieee1275/kernel.h b/include/grub/sparc64/ieee1275/kernel.h index 2948a8d2f..012b5570c 100644 --- a/include/grub/sparc64/ieee1275/kernel.h +++ b/include/grub/sparc64/ieee1275/kernel.h @@ -24,22 +24,6 @@ /* Non-zero value is only needed for PowerMacs. */ #define GRUB_MOD_GAP 0x0 -/* The offset of GRUB_TOTAL_MODULE_SIZE. */ -#define GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE 0x8 - -/* The offset of GRUB_KERNEL_IMAGE_SIZE. */ -#define GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE 0xc - -/* The offset of GRUB_COMPRESSED_SIZE. */ -#define GRUB_KERNEL_MACHINE_COMPRESSED_SIZE 0x10 - -/* The offset of GRUB_PREFIX. */ -#define GRUB_KERNEL_MACHINE_PREFIX 0x14 - -/* End of the data section. */ -#define GRUB_KERNEL_MACHINE_DATA_END 0x114 - -#define GRUB_KERNEL_MACHINE_RAW_SIZE 0 #define GRUB_KERNEL_MACHINE_STACK_SIZE 0x40000 #ifndef ASM_FILE diff --git a/kern/mips/startup.S b/kern/mips/startup.S index 5e3fb7ad5..876b2df71 100644 --- a/kern/mips/startup.S +++ b/kern/mips/startup.S @@ -18,8 +18,9 @@ */ #include -#include +#include #include +#include #define BASE_ADDR 8 @@ -32,13 +33,13 @@ _start: start: bal codestart base: - . = _start + GRUB_KERNEL_CPU_COMPRESSED_SIZE + . = _start + GRUB_KERNEL_MACHINE_COMPRESSED_SIZE compressed_size: .long 0 - . = _start + GRUB_KERNEL_CPU_TOTAL_MODULE_SIZE + . = _start + GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE total_module_size: .long 0 - . = _start + GRUB_KERNEL_CPU_KERNEL_IMAGE_SIZE + . = _start + GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE kernel_image_size: .long 0 codestart: @@ -105,10 +106,10 @@ argdone: #endif /* Decompress the payload. */ - addiu $a0, $s0, GRUB_KERNEL_CPU_RAW_SIZE - BASE_ADDR + addiu $a0, $s0, GRUB_KERNEL_MACHINE_RAW_SIZE - BASE_ADDR lui $a1, %hi(compressed) addiu $a1, %lo(compressed) - lw $a2, (GRUB_KERNEL_CPU_COMPRESSED_SIZE - BASE_ADDR)($s0) + lw $a2, (GRUB_KERNEL_MACHINE_COMPRESSED_SIZE - BASE_ADDR)($s0) move $s1, $a1 /* $a0 contains source compressed address, $a1 is destination, @@ -134,9 +135,9 @@ reloccont: addiu $t1, %lo(cont) jr $t1 - . = _start + GRUB_KERNEL_CPU_RAW_SIZE + . = _start + GRUB_KERNEL_MACHINE_RAW_SIZE compressed: - . = _start + GRUB_KERNEL_CPU_PREFIX + . = _start + GRUB_KERNEL_MACHINE_PREFIX VARIABLE(grub_prefix) @@ -146,7 +147,7 @@ VARIABLE(grub_prefix) * Leave some breathing room for the prefix. */ - . = _start + GRUB_KERNEL_CPU_DATA_END + . = _start + GRUB_KERNEL_MACHINE_DATA_END #ifdef GRUB_MACHINE_MIPS_YEELOONG VARIABLE (grub_arch_busclock) .long 0 @@ -171,7 +172,7 @@ cont: /* Move the modules out of BSS. */ lui $t1, %hi(_start) addiu $t1, %lo(_start) - lw $t2, (GRUB_KERNEL_CPU_KERNEL_IMAGE_SIZE - BASE_ADDR)($s0) + lw $t2, (GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE - BASE_ADDR)($s0) addu $t2, $t1, $t2 lui $t1, %hi(_end) @@ -181,7 +182,7 @@ cont: nor $t3, $t3, $0 and $t1, $t1, $t3 - lw $t3, (GRUB_KERNEL_CPU_TOTAL_MODULE_SIZE - BASE_ADDR)($s0) + lw $t3, (GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE - BASE_ADDR)($s0) /* Backward copy. */ add $t1, $t1, $t3 diff --git a/kern/sparc64/ieee1275/crt0.S b/kern/sparc64/ieee1275/crt0.S index d5a172296..f0f47416d 100644 --- a/kern/sparc64/ieee1275/crt0.S +++ b/kern/sparc64/ieee1275/crt0.S @@ -18,6 +18,7 @@ */ #include #include +#include .text .align 4 diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index c9bafdd8b..7ba9e595e 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -55,7 +55,6 @@ struct image_target_desc IMAGE_SPARC64_AOUT, IMAGE_SPARC64_RAW, IMAGE_I386_IEEE1275, IMAGE_YEELOONG_ELF, IMAGE_QEMU, IMAGE_PPC } id; - enum {FORMAT_RAW, FORMAT_AOUT, FORMAT_ELF, FORMAT_PE} format; enum { PLATFORM_FLAGS_NONE = 0, @@ -77,56 +76,153 @@ struct image_target_desc struct image_target_desc image_targets[] = { - {"i386-coreboot", 4, 0, IMAGE_COREBOOT, FORMAT_ELF, PLATFORM_FLAGS_NONE, - .section_align = 1, - .vaddr_offset = 0 + { + .name = "i386-coreboot", + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_COREBOOT, + .flags = PLATFORM_FLAGS_NONE, + .section_align = 1, + .vaddr_offset = 0 }, - {"i386-pc", 4, 0, IMAGE_I386_PC, FORMAT_RAW, PLATFORM_FLAGS_LZMA, - GRUB_KERNEL_I386_PC_PREFIX, GRUB_KERNEL_I386_PC_DATA_END, - GRUB_KERNEL_I386_PC_RAW_SIZE, GRUB_KERNEL_I386_PC_TOTAL_MODULE_SIZE, - GRUB_KERNEL_I386_PC_KERNEL_IMAGE_SIZE, GRUB_KERNEL_I386_PC_COMPRESSED_SIZE, - .section_align = 1, - .vaddr_offset = 0, - GRUB_KERNEL_I386_PC_INSTALL_DOS_PART, GRUB_KERNEL_I386_PC_INSTALL_BSD_PART + { + .name = "i386-pc", + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_I386_PC, + .flags = PLATFORM_FLAGS_LZMA, + .prefix = GRUB_KERNEL_I386_PC_PREFIX, + .data_end = GRUB_KERNEL_I386_PC_DATA_END, + .raw_size = GRUB_KERNEL_I386_PC_RAW_SIZE, + .total_module_size = GRUB_KERNEL_I386_PC_TOTAL_MODULE_SIZE, + .kernel_image_size = GRUB_KERNEL_I386_PC_KERNEL_IMAGE_SIZE, + .compressed_size = GRUB_KERNEL_I386_PC_COMPRESSED_SIZE, + .section_align = 1, + .vaddr_offset = 0, + .install_dos_part = GRUB_KERNEL_I386_PC_INSTALL_DOS_PART, + .install_bsd_part = GRUB_KERNEL_I386_PC_INSTALL_BSD_PART, + .link_addr = GRUB_KERNEL_I386_PC_LINK_ADDR }, - {"i386-efi", 4, 0, IMAGE_EFI, FORMAT_PE, PLATFORM_FLAGS_NONE, - .section_align = GRUB_PE32_SECTION_ALIGNMENT, - .vaddr_offset = ALIGN_UP (GRUB_PE32_MSDOS_STUB_SIZE - + GRUB_PE32_SIGNATURE_SIZE - + sizeof (struct grub_pe32_coff_header) - + sizeof (struct grub_pe32_optional_header) - + 4 * sizeof (struct grub_pe32_section_table), - GRUB_PE32_SECTION_ALIGNMENT) + { + .name = "i386-efi", + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_EFI, + .flags = PLATFORM_FLAGS_NONE, + .section_align = GRUB_PE32_SECTION_ALIGNMENT, + .vaddr_offset = ALIGN_UP (GRUB_PE32_MSDOS_STUB_SIZE + + GRUB_PE32_SIGNATURE_SIZE + + sizeof (struct grub_pe32_coff_header) + + sizeof (struct grub_pe32_optional_header) + + 4 * sizeof (struct grub_pe32_section_table), + GRUB_PE32_SECTION_ALIGNMENT) }, - {"i386-ieee1275", 4, 0, IMAGE_I386_IEEE1275, FORMAT_ELF, PLATFORM_FLAGS_NONE, - .section_align = 1, - .vaddr_offset = 0}, - {"i386-qemu", 4, 0, IMAGE_QEMU, FORMAT_RAW, PLATFORM_FLAGS_NONE, - .section_align = 1, - .vaddr_offset = 0}, - {"x86_64-efi", 8, 0, IMAGE_EFI, FORMAT_PE, PLATFORM_FLAGS_NONE, - .section_align = GRUB_PE32_SECTION_ALIGNMENT, - .vaddr_offset = ALIGN_UP (GRUB_PE32_MSDOS_STUB_SIZE - + GRUB_PE32_SIGNATURE_SIZE - + sizeof (struct grub_pe32_coff_header) - + sizeof (struct grub_pe64_optional_header) - + 4 * sizeof (struct grub_pe32_section_table), - GRUB_PE32_SECTION_ALIGNMENT) + { + .name = "i386-ieee1275", + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_I386_IEEE1275, + .flags = PLATFORM_FLAGS_NONE, + .section_align = 1, + .vaddr_offset = 0 + }, + { + .name = "i386-qemu", + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_QEMU, + .flags = PLATFORM_FLAGS_NONE, + .prefix = GRUB_KERNEL_I386_QEMU_PREFIX, + .data_end = GRUB_KERNEL_I386_QEMU_DATA_END, + .raw_size = 0, + .total_module_size = TARGET_NO_FIELD, + .compressed_size = TARGET_NO_FIELD, + .kernel_image_size = GRUB_KERNEL_I386_QEMU_KERNEL_IMAGE_SIZE, + .section_align = 1, + .vaddr_offset = 0, + .install_dos_part = TARGET_NO_FIELD, + .install_bsd_part = TARGET_NO_FIELD, + .link_addr = GRUB_KERNEL_I386_QEMU_LINK_ADDR + }, + { + .name = "x86_64-efi", + .voidp_sizeof = 8, + .bigendian = 0, + .id = IMAGE_EFI, + .flags = PLATFORM_FLAGS_NONE, + .section_align = GRUB_PE32_SECTION_ALIGNMENT, + .vaddr_offset = ALIGN_UP (GRUB_PE32_MSDOS_STUB_SIZE + + GRUB_PE32_SIGNATURE_SIZE + + sizeof (struct grub_pe32_coff_header) + + sizeof (struct grub_pe64_optional_header) + + 4 * sizeof (struct grub_pe32_section_table), + GRUB_PE32_SECTION_ALIGNMENT) + }, + { + .name = "mipsel-yeeloong-elf", + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_YEELOONG_ELF, + .flags = PLATFORM_FLAGS_NONE, + .prefix = GRUB_KERNEL_MIPS_YEELOONG_PREFIX, + .data_end = GRUB_KERNEL_MIPS_YEELOONG_DATA_END, + .raw_size = GRUB_KERNEL_MIPS_YEELOONG_RAW_SIZE, + .total_module_size = GRUB_KERNEL_MIPS_YEELOONG_TOTAL_MODULE_SIZE, + .compressed_size = GRUB_KERNEL_MIPS_YEELOONG_COMPRESSED_SIZE, + .kernel_image_size = GRUB_KERNEL_MIPS_YEELOONG_KERNEL_IMAGE_SIZE, + .section_align = 1, + .vaddr_offset = 0, + .install_dos_part = TARGET_NO_FIELD, + .install_bsd_part = TARGET_NO_FIELD, + .link_addr = GRUB_KERNEL_MIPS_YEELOONG_LINK_ADDR, + .elf_target = EM_MIPS, + .link_align = GRUB_KERNEL_MIPS_YEELOONG_LINK_ALIGN + }, + { + .name = "powerpc-ieee1275", + .voidp_sizeof = 4, + .bigendian = 1, + .id = IMAGE_PPC, + .flags = PLATFORM_FLAGS_NONE, + .section_align = 1, + .vaddr_offset = 0 + }, + { + .name = "sparc64-ieee1275-raw", + .voidp_sizeof = 8, + .bigendian = 1, + .id = IMAGE_SPARC64_RAW, + .flags = PLATFORM_FLAGS_NONE, + .prefix = GRUB_KERNEL_SPARC64_IEEE1275_PREFIX, + .data_end = GRUB_KERNEL_SPARC64_IEEE1275_DATA_END, + .raw_size = GRUB_KERNEL_SPARC64_IEEE1275_RAW_SIZE, + .total_module_size = GRUB_KERNEL_SPARC64_IEEE1275_TOTAL_MODULE_SIZE, + .kernel_image_size = GRUB_KERNEL_SPARC64_IEEE1275_KERNEL_IMAGE_SIZE, + .compressed_size = GRUB_KERNEL_SPARC64_IEEE1275_COMPRESSED_SIZE, + .section_align = 1, + .vaddr_offset = 0, + .install_dos_part = TARGET_NO_FIELD, + .install_bsd_part = TARGET_NO_FIELD, + .link_addr = GRUB_KERNEL_SPARC64_IEEE1275_LINK_ADDR + }, + { + .name = "sparc64-ieee1275-aout", + .voidp_sizeof = 8, + .bigendian = 1, + .id = IMAGE_SPARC64_AOUT, + .flags = PLATFORM_FLAGS_NONE, + .prefix = GRUB_KERNEL_SPARC64_IEEE1275_PREFIX, + .data_end = GRUB_KERNEL_SPARC64_IEEE1275_DATA_END, + .raw_size = GRUB_KERNEL_SPARC64_IEEE1275_RAW_SIZE, + .total_module_size = GRUB_KERNEL_SPARC64_IEEE1275_TOTAL_MODULE_SIZE, + .kernel_image_size = GRUB_KERNEL_SPARC64_IEEE1275_KERNEL_IMAGE_SIZE, + .compressed_size = GRUB_KERNEL_SPARC64_IEEE1275_COMPRESSED_SIZE, + .section_align = 1, + .vaddr_offset = 0, + .install_dos_part = TARGET_NO_FIELD, + .install_bsd_part = TARGET_NO_FIELD, + .link_addr = GRUB_KERNEL_SPARC64_IEEE1275_LINK_ADDR }, - {"mipsel-yeeloong-elf", 4, 0, IMAGE_YEELOONG_ELF, FORMAT_ELF, PLATFORM_FLAGS_NONE, - .section_align = 1, - .vaddr_offset = 0}, - {"powerpc-ieee1275", 4, 1, IMAGE_PPC, FORMAT_ELF, PLATFORM_FLAGS_NONE, - .section_align = 1, - .vaddr_offset = 0}, - {"sparc64-ieee1275-raw", 8, 1, IMAGE_SPARC64_RAW, - FORMAT_RAW, PLATFORM_FLAGS_NONE, - .section_align = 1, - .vaddr_offset = 0}, - {"sparc64-ieee1275-aout", 8, 1, IMAGE_SPARC64_AOUT, - FORMAT_AOUT, PLATFORM_FLAGS_NONE, - .section_align = 1, - .vaddr_offset = 0}, }; #define grub_target_to_host32(x) (grub_target_to_host32_real (image_target, (x))) @@ -191,8 +287,8 @@ grub_host_to_target16_real (struct image_target_desc *image_target, grub_uint16_ return grub_cpu_to_le16 (in); } -static inline grub_uint32_t -grub_host_to_target_addr_real (struct image_target_desc *image_target, grub_uint32_t in) +static inline grub_uint64_t +grub_host_to_target_addr_real (struct image_target_desc *image_target, grub_uint64_t in) { if (image_target->voidp_sizeof == 8) return grub_host_to_target64_real (image_target, in); @@ -200,8 +296,8 @@ grub_host_to_target_addr_real (struct image_target_desc *image_target, grub_uint return grub_host_to_target32_real (image_target, in); } -static inline grub_uint32_t -grub_target_to_host_real (struct image_target_desc *image_target, grub_uint32_t in) +static inline grub_uint64_t +grub_target_to_host_real (struct image_target_desc *image_target, grub_uint64_t in) { if (image_target->voidp_sizeof == 8) return grub_target_to_host64_real (image_target, in); diff --git a/util/grub-mkimagexx.c b/util/grub-mkimagexx.c index eb0c7a514..abfe56d42 100644 --- a/util/grub-mkimagexx.c +++ b/util/grub-mkimagexx.c @@ -67,11 +67,11 @@ SUFFIX (relocate_symbols) (Elf_Ehdr *e, Elf_Shdr *sections, = (Elf_Shdr *) ((char *) sections + (grub_target_to_host32 (symtab_section->sh_link) * section_entsize)); - strtab = (char *) e + grub_target_to_host32 (strtab_section->sh_offset); + strtab = (char *) e + grub_target_to_host (strtab_section->sh_offset); - symtab_size = grub_target_to_host32 (symtab_section->sh_size); - sym_size = grub_target_to_host32 (symtab_section->sh_entsize); - symtab_offset = grub_target_to_host32 (symtab_section->sh_offset); + symtab_size = grub_target_to_host (symtab_section->sh_size); + sym_size = grub_target_to_host (symtab_section->sh_entsize); + symtab_offset = grub_target_to_host (symtab_section->sh_offset); num_syms = symtab_size / sym_size; for (i = 0, sym = (Elf_Sym *) ((char *) e + symtab_offset); @@ -482,7 +482,7 @@ SUFFIX (is_text_section) (Elf_Shdr *s, struct image_target_desc *image_target) if (image_target->id != IMAGE_EFI && grub_target_to_host32 (s->sh_type) != SHT_PROGBITS) return 0; - return ((grub_target_to_host32 (s->sh_flags) & (SHF_EXECINSTR | SHF_ALLOC)) + return ((grub_target_to_host (s->sh_flags) & (SHF_EXECINSTR | SHF_ALLOC)) == (SHF_EXECINSTR | SHF_ALLOC)); } @@ -495,7 +495,7 @@ SUFFIX (is_data_section) (Elf_Shdr *s, struct image_target_desc *image_target) if (image_target->id != IMAGE_EFI && grub_target_to_host32 (s->sh_type) != SHT_PROGBITS) return 0; - return ((grub_target_to_host32 (s->sh_flags) & (SHF_EXECINSTR | SHF_ALLOC)) + return ((grub_target_to_host (s->sh_flags) & (SHF_EXECINSTR | SHF_ALLOC)) == SHF_ALLOC); } @@ -543,7 +543,6 @@ SUFFIX (locate_sections) (Elf_Shdr *sections, Elf_Half section_entsize, { Elf_Word align = grub_host_to_target32 (s->sh_addralign); const char *name = strtab + grub_host_to_target32 (s->sh_name); - if (align) current_address = ALIGN_UP (current_address + image_target->vaddr_offset, align) - image_target->vaddr_offset; @@ -551,7 +550,7 @@ SUFFIX (locate_sections) (Elf_Shdr *sections, Elf_Half section_entsize, grub_util_info ("locating the section %s at 0x%x", name, current_address); section_addresses[i] = current_address; - current_address += grub_host_to_target32 (s->sh_size); + current_address += grub_host_to_target_addr (s->sh_size); } current_address = ALIGN_UP (current_address + image_target->vaddr_offset, @@ -576,7 +575,7 @@ SUFFIX (locate_sections) (Elf_Shdr *sections, Elf_Half section_entsize, grub_util_info ("locating the section %s at 0x%x", name, current_address); section_addresses[i] = current_address; - current_address += grub_host_to_target32 (s->sh_size); + current_address += grub_host_to_target_addr (s->sh_size); } current_address = ALIGN_UP (current_address + image_target->vaddr_offset, @@ -616,7 +615,7 @@ SUFFIX (load_image) (const char *kernel_path, grub_size_t *exec_size, if (! SUFFIX (check_elf_header) (e, kernel_size, image_target)) grub_util_error ("invalid ELF header"); - section_offset = grub_target_to_host32 (e->e_shoff); + section_offset = grub_target_to_host (e->e_shoff); section_entsize = grub_target_to_host16 (e->e_shentsize); num_sections = grub_target_to_host16 (e->e_shnum); @@ -660,7 +659,7 @@ SUFFIX (load_image) (const char *kernel_path, grub_size_t *exec_size, grub_util_info ("locating the section %s at 0x%x", name, current_address); section_vaddresses[i] = current_address + VADDR_OFFSET; - current_address += grub_host_to_target32 (s->sh_size); + current_address += grub_host_to_target_addr (s->sh_size); } current_address = ALIGN_UP (current_address + VADDR_OFFSET, SECTION_ALIGN) - VADDR_OFFSET; @@ -715,11 +714,11 @@ SUFFIX (load_image) (const char *kernel_path, grub_size_t *exec_size, { if (grub_target_to_host32 (s->sh_type) == SHT_NOBITS) memset (out_img + section_addresses[i], 0, - grub_host_to_target32 (s->sh_size)); + grub_host_to_target_addr (s->sh_size)); else memcpy (out_img + section_addresses[i], - kernel_img + grub_host_to_target32 (s->sh_offset), - grub_host_to_target32 (s->sh_size)); + kernel_img + grub_host_to_target_addr (s->sh_offset), + grub_host_to_target_addr (s->sh_size)); } free (kernel_img); From bb3208158ab37c8a8f28b946b1e804a1442d0c9a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 26 Apr 2010 17:19:15 +0200 Subject: [PATCH 605/738] Fill info for remaining platforms. Make efi image identical to image of previous grub-mkimage --- conf/i386-coreboot.rmk | 4 +- include/grub/efi/pe32.h | 10 ++-- include/grub/i386/efi/kernel.h | 6 --- include/grub/i386/kernel.h | 3 -- include/grub/offsets.h | 21 ++++++++ include/grub/x86_64/efi/kernel.h | 6 --- kern/i386/coreboot/startup.S | 4 +- kern/i386/ieee1275/startup.S | 4 +- util/grub-mkimage.c | 88 ++++++++++++++++++++++++-------- 9 files changed, 101 insertions(+), 45 deletions(-) diff --git a/conf/i386-coreboot.rmk b/conf/i386-coreboot.rmk index 69b8e9a48..11c3abd2a 100644 --- a/conf/i386-coreboot.rmk +++ b/conf/i386-coreboot.rmk @@ -4,8 +4,6 @@ COMMON_CFLAGS = -mrtd -mregparm=3 # Images. -GRUB_KERNEL_MACHINE_LINK_ADDR = 0x8200 - pkglib_PROGRAMS += kernel.img kernel_img_SOURCES = kern/i386/coreboot/startup.S \ kern/i386/misc.S \ @@ -26,7 +24,7 @@ kernel_img_SOURCES = kern/i386/coreboot/startup.S \ symlist.c kernel_img_CFLAGS = $(COMMON_CFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) -kernel_img_LDFLAGS += $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,$(GRUB_KERNEL_MACHINE_LINK_ADDR),-Bstatic +kernel_img_LDFLAGS += $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,0x8200,-Bstatic sbin_SCRIPTS += grub-install grub_install_SOURCES = util/grub-install.in diff --git a/include/grub/efi/pe32.h b/include/grub/efi/pe32.h index 90f9c9f5c..81a1a5797 100644 --- a/include/grub/efi/pe32.h +++ b/include/grub/efi/pe32.h @@ -238,6 +238,7 @@ struct grub_pe32_section_table #define GRUB_PE32_SCN_ALIGN_SHIFT 20 #define GRUB_PE32_SCN_ALIGN_MASK 7 +#define GRUB_PE32_SIGNATURE_SIZE 4 struct grub_pe32_header { @@ -245,17 +246,20 @@ struct grub_pe32_header grub_uint8_t msdos_stub[GRUB_PE32_MSDOS_STUB_SIZE]; /* This is always PE\0\0. */ - char signature[4]; + char signature[GRUB_PE32_SIGNATURE_SIZE]; /* The COFF file header. */ struct grub_pe32_coff_header coff_header; +#if GRUB_TARGET_SIZEOF_VOID_P == 8 + /* The Optional header. */ + struct grub_pe64_optional_header optional_header; +#else /* The Optional header. */ struct grub_pe32_optional_header optional_header; +#endif }; -#define GRUB_PE32_SIGNATURE_SIZE 4 - struct grub_pe32_fixup_block { grub_uint32_t page_rva; diff --git a/include/grub/i386/efi/kernel.h b/include/grub/i386/efi/kernel.h index c0549f41a..0cb39a215 100644 --- a/include/grub/i386/efi/kernel.h +++ b/include/grub/i386/efi/kernel.h @@ -23,11 +23,5 @@ configuration file are located. */ extern char grub_prefix[]; -/* The offset of GRUB_PREFIX. */ -#define GRUB_KERNEL_MACHINE_PREFIX 0x8 - -/* End of the data section. */ -#define GRUB_KERNEL_MACHINE_DATA_END 0x50 - #endif /* ! GRUB_MACHINE_KERNEL_HEADER */ diff --git a/include/grub/i386/kernel.h b/include/grub/i386/kernel.h index 5514c8ccf..a0d806929 100644 --- a/include/grub/i386/kernel.h +++ b/include/grub/i386/kernel.h @@ -29,7 +29,4 @@ /* Non-zero value is only needed for PowerMacs. */ #define GRUB_MOD_GAP 0x0 -#define GRUB_KERNEL_CPU_PREFIX 0x2 -#define GRUB_KERNEL_CPU_DATA_END 0x42 - #endif diff --git a/include/grub/offsets.h b/include/grub/offsets.h index fc4cd0a46..768e4726a 100644 --- a/include/grub/offsets.h +++ b/include/grub/offsets.h @@ -93,6 +93,7 @@ #define GRUB_KERNEL_POWERPC_IEEE1275_PREFIX 0x4 #define GRUB_KERNEL_POWERPC_IEEE1275_DATA_END 0x44 #define GRUB_KERNEL_POWERPC_IEEE1275_LINK_ALIGN 4 +#define GRUB_KERNEL_POWERPC_IEEE1275_LINK_ADDR 0x200000 #define GRUB_KERNEL_MIPS_YEELOONG_LINK_ADDR 0x80200000 @@ -106,6 +107,26 @@ #define GRUB_KERNEL_MIPS_YEELOONG_PREFIX GRUB_KERNEL_MIPS_YEELOONG_RAW_SIZE #define GRUB_KERNEL_MIPS_YEELOONG_DATA_END GRUB_KERNEL_MIPS_YEELOONG_RAW_SIZE + 0x48 +/* The offset of GRUB_PREFIX. */ +#define GRUB_KERNEL_I386_EFI_PREFIX 0x8 + +/* End of the data section. */ +#define GRUB_KERNEL_I386_EFI_DATA_END 0x50 + +/* The offset of GRUB_PREFIX. */ +#define GRUB_KERNEL_X86_64_EFI_PREFIX 0x8 + +/* End of the data section. */ +#define GRUB_KERNEL_X86_64_EFI_DATA_END 0x50 + +#define GRUB_KERNEL_I386_COREBOOT_PREFIX 0x2 +#define GRUB_KERNEL_I386_COREBOOT_DATA_END 0x42 +#define GRUB_KERNEL_I386_COREBOOT_LINK_ADDR 0x8200 + +#define GRUB_KERNEL_I386_IEEE1275_PREFIX 0x2 +#define GRUB_KERNEL_I386_IEEE1275_DATA_END 0x42 +#define GRUB_KERNEL_I386_IEEE1275_LINK_ADDR 0x10000 + #ifdef MACHINE #define GRUB_OFFSETS_CONCAT_(a,b,c) a ## b ## c #define GRUB_OFFSETS_CONCAT(a,b,c) GRUB_OFFSETS_CONCAT_(a,b,c) diff --git a/include/grub/x86_64/efi/kernel.h b/include/grub/x86_64/efi/kernel.h index c0549f41a..0cb39a215 100644 --- a/include/grub/x86_64/efi/kernel.h +++ b/include/grub/x86_64/efi/kernel.h @@ -23,11 +23,5 @@ configuration file are located. */ extern char grub_prefix[]; -/* The offset of GRUB_PREFIX. */ -#define GRUB_KERNEL_MACHINE_PREFIX 0x8 - -/* End of the data section. */ -#define GRUB_KERNEL_MACHINE_DATA_END 0x50 - #endif /* ! GRUB_MACHINE_KERNEL_HEADER */ diff --git a/kern/i386/coreboot/startup.S b/kern/i386/coreboot/startup.S index e94950aae..ecdc0b61c 100644 --- a/kern/i386/coreboot/startup.S +++ b/kern/i386/coreboot/startup.S @@ -42,7 +42,7 @@ _start: * This is a special data area at a fixed offset from the beginning. */ - . = _start + GRUB_KERNEL_CPU_PREFIX + . = _start + GRUB_KERNEL_MACHINE_PREFIX VARIABLE(grub_prefix) /* to be filled by grub-mkimage */ @@ -51,7 +51,7 @@ VARIABLE(grub_prefix) * Leave some breathing room for the prefix. */ - . = _start + GRUB_KERNEL_CPU_DATA_END + . = _start + GRUB_KERNEL_MACHINE_DATA_END /* * Support for booting GRUB from a Multiboot boot loader (e.g. GRUB itself). diff --git a/kern/i386/ieee1275/startup.S b/kern/i386/ieee1275/startup.S index 35258adb6..ad2ef329b 100644 --- a/kern/i386/ieee1275/startup.S +++ b/kern/i386/ieee1275/startup.S @@ -43,7 +43,7 @@ _start: * This is a special data area at a fixed offset from the beginning. */ - . = _start + GRUB_KERNEL_CPU_PREFIX + . = _start + GRUB_KERNEL_MACHINE_PREFIX VARIABLE(grub_prefix) /* to be filled by grub-mkimage */ @@ -52,7 +52,7 @@ VARIABLE(grub_prefix) * Leave some breathing room for the prefix. */ - . = _start + GRUB_KERNEL_CPU_DATA_END + . = _start + GRUB_KERNEL_MACHINE_DATA_END codestart: movl %eax, EXT_C(grub_ieee1275_entry_fn) diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index 7ba9e595e..25ab5afe4 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -82,8 +82,17 @@ struct image_target_desc image_targets[] = .bigendian = 0, .id = IMAGE_COREBOOT, .flags = PLATFORM_FLAGS_NONE, + .prefix = GRUB_KERNEL_I386_COREBOOT_PREFIX, + .data_end = GRUB_KERNEL_I386_COREBOOT_DATA_END, + .raw_size = 0, + .total_module_size = TARGET_NO_FIELD, + .kernel_image_size = TARGET_NO_FIELD, + .compressed_size = TARGET_NO_FIELD, .section_align = 1, - .vaddr_offset = 0 + .vaddr_offset = 0, + .install_dos_part = TARGET_NO_FIELD, + .install_bsd_part = TARGET_NO_FIELD, + .link_addr = GRUB_KERNEL_I386_COREBOOT_LINK_ADDR }, { .name = "i386-pc", @@ -109,13 +118,21 @@ struct image_target_desc image_targets[] = .bigendian = 0, .id = IMAGE_EFI, .flags = PLATFORM_FLAGS_NONE, + .prefix = GRUB_KERNEL_I386_EFI_PREFIX, + .data_end = GRUB_KERNEL_I386_EFI_DATA_END, + .raw_size = 0, + .total_module_size = TARGET_NO_FIELD, + .kernel_image_size = TARGET_NO_FIELD, + .compressed_size = TARGET_NO_FIELD, .section_align = GRUB_PE32_SECTION_ALIGNMENT, .vaddr_offset = ALIGN_UP (GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE + sizeof (struct grub_pe32_coff_header) + sizeof (struct grub_pe32_optional_header) + 4 * sizeof (struct grub_pe32_section_table), - GRUB_PE32_SECTION_ALIGNMENT) + GRUB_PE32_SECTION_ALIGNMENT), + .install_dos_part = TARGET_NO_FIELD, + .install_bsd_part = TARGET_NO_FIELD, }, { .name = "i386-ieee1275", @@ -123,8 +140,17 @@ struct image_target_desc image_targets[] = .bigendian = 0, .id = IMAGE_I386_IEEE1275, .flags = PLATFORM_FLAGS_NONE, + .prefix = GRUB_KERNEL_I386_IEEE1275_PREFIX, + .data_end = GRUB_KERNEL_I386_IEEE1275_DATA_END, + .raw_size = 0, + .total_module_size = TARGET_NO_FIELD, + .kernel_image_size = TARGET_NO_FIELD, + .compressed_size = TARGET_NO_FIELD, .section_align = 1, - .vaddr_offset = 0 + .vaddr_offset = 0, + .install_dos_part = TARGET_NO_FIELD, + .install_bsd_part = TARGET_NO_FIELD, + .link_addr = GRUB_KERNEL_I386_IEEE1275_LINK_ADDR }, { .name = "i386-qemu", @@ -150,13 +176,21 @@ struct image_target_desc image_targets[] = .bigendian = 0, .id = IMAGE_EFI, .flags = PLATFORM_FLAGS_NONE, + .prefix = GRUB_KERNEL_X86_64_EFI_PREFIX, + .data_end = GRUB_KERNEL_X86_64_EFI_DATA_END, + .raw_size = 0, + .total_module_size = TARGET_NO_FIELD, + .kernel_image_size = TARGET_NO_FIELD, + .compressed_size = TARGET_NO_FIELD, .section_align = GRUB_PE32_SECTION_ALIGNMENT, .vaddr_offset = ALIGN_UP (GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE + sizeof (struct grub_pe32_coff_header) + sizeof (struct grub_pe64_optional_header) + 4 * sizeof (struct grub_pe32_section_table), - GRUB_PE32_SECTION_ALIGNMENT) + GRUB_PE32_SECTION_ALIGNMENT), + .install_dos_part = TARGET_NO_FIELD, + .install_bsd_part = TARGET_NO_FIELD, }, { .name = "mipsel-yeeloong-elf", @@ -184,8 +218,17 @@ struct image_target_desc image_targets[] = .bigendian = 1, .id = IMAGE_PPC, .flags = PLATFORM_FLAGS_NONE, + .prefix = GRUB_KERNEL_POWERPC_IEEE1275_PREFIX, + .data_end = GRUB_KERNEL_POWERPC_IEEE1275_DATA_END, + .raw_size = 0, + .total_module_size = TARGET_NO_FIELD, + .kernel_image_size = TARGET_NO_FIELD, + .compressed_size = TARGET_NO_FIELD, .section_align = 1, - .vaddr_offset = 0 + .vaddr_offset = 0, + .install_dos_part = TARGET_NO_FIELD, + .install_bsd_part = TARGET_NO_FIELD, + .link_addr = GRUB_KERNEL_POWERPC_IEEE1275_LINK_ADDR }, { .name = "sparc64-ieee1275-raw", @@ -629,6 +672,7 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], { void *pe_img; grub_uint8_t *header; + void *sections; size_t pe_size; struct grub_pe32_coff_header *c; struct grub_pe32_section_table *text_section, *data_section; @@ -669,7 +713,8 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], GRUB_PE32_SIGNATURE_SIZE); /* The COFF file header. */ - c = header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE; + c = (struct grub_pe32_coff_header *) (header + GRUB_PE32_MSDOS_STUB_SIZE + + GRUB_PE32_SIGNATURE_SIZE); if (image_target->voidp_sizeof == 4) c->machine = grub_host_to_target16 (GRUB_PE32_MACHINE_I386); else @@ -692,11 +737,13 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], c->optional_header_size = grub_host_to_target16 (sizeof (struct grub_pe32_optional_header)); - o = header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE - + sizeof (struct grub_pe32_coff_header); + o = (struct grub_pe32_optional_header *) + (header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE + + sizeof (struct grub_pe32_coff_header)); o->magic = grub_host_to_target16 (GRUB_PE32_PE32_MAGIC); o->code_size = grub_host_to_target32 (exec_size); - o->data_size = grub_cpu_to_le32 (reloc_addr - exec_size); + o->data_size = grub_cpu_to_le32 (reloc_addr - exec_size + - header_size); o->bss_size = grub_cpu_to_le32 (bss_size); o->entry_addr = grub_cpu_to_le32 (start_address); o->code_base = grub_cpu_to_le32 (header_size); @@ -720,18 +767,21 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], o->base_relocation_table.rva = grub_host_to_target32 (reloc_addr); o->base_relocation_table.size = grub_host_to_target32 (reloc_size); + sections = o + 1; } else { struct grub_pe64_optional_header *o; - c->optional_header_size = grub_host_to_target16 (sizeof (struct grub_pe32_optional_header)); + c->optional_header_size = grub_host_to_target16 (sizeof (struct grub_pe64_optional_header)); - o = header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE - + sizeof (struct grub_pe32_coff_header); + o = (struct grub_pe64_optional_header *) + (header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE + + sizeof (struct grub_pe32_coff_header)); o->magic = grub_host_to_target16 (GRUB_PE32_PE64_MAGIC); o->code_size = grub_host_to_target32 (exec_size); - o->data_size = grub_cpu_to_le32 (reloc_addr - exec_size); + o->data_size = grub_cpu_to_le32 (reloc_addr - exec_size + - header_size); o->bss_size = grub_cpu_to_le32 (bss_size); o->entry_addr = grub_cpu_to_le32 (start_address); o->code_base = grub_cpu_to_le32 (header_size); @@ -753,9 +803,10 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], o->base_relocation_table.rva = grub_host_to_target32 (reloc_addr); o->base_relocation_table.size = grub_host_to_target32 (reloc_size); + sections = o + 1; } /* The sections. */ - text_section = (struct grub_pe32_section_table *) (header + 1); + text_section = sections; strcpy (text_section->name, ".text"); text_section->virtual_size = grub_cpu_to_le32 (exec_size); text_section->virtual_address = grub_cpu_to_le32 (header_size); @@ -763,8 +814,7 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], text_section->raw_data_offset = grub_cpu_to_le32 (header_size); text_section->characteristics = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_CODE | GRUB_PE32_SCN_MEM_EXECUTE - | GRUB_PE32_SCN_MEM_READ - | GRUB_PE32_SCN_ALIGN_64BYTES); + | GRUB_PE32_SCN_MEM_READ); data_section = text_section + 1; strcpy (data_section->name, ".data"); @@ -775,8 +825,7 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], data_section->characteristics = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_INITIALIZED_DATA | GRUB_PE32_SCN_MEM_READ - | GRUB_PE32_SCN_MEM_WRITE - | GRUB_PE32_SCN_ALIGN_64BYTES); + | GRUB_PE32_SCN_MEM_WRITE); #if 0 bss_section = data_section + 1; @@ -802,8 +851,7 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], mods_section->characteristics = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_INITIALIZED_DATA | GRUB_PE32_SCN_MEM_READ - | GRUB_PE32_SCN_MEM_WRITE - | GRUB_PE32_SCN_ALIGN_64BYTES); + | GRUB_PE32_SCN_MEM_WRITE); reloc_section = mods_section + 1; strcpy (reloc_section->name, ".reloc"); From debaf23f7c1ee4cc70a43a7bebc37667e5a4d6e0 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 26 Apr 2010 19:11:38 +0200 Subject: [PATCH 606/738] all images binary identical to the ones from trunk --- include/grub/elf.h | 1 + include/grub/i386/kernel.h | 10 ---- include/grub/offsets.h | 16 +++++++ include/grub/powerpc/kernel.h | 7 --- kern/i386/coreboot/init.c | 2 +- kern/ieee1275/init.c | 2 +- util/grub-mkimage.c | 86 ++++++++++++++++++++++++++-------- util/grub-mkimagexx.c | 87 ++++++++++++++++++++--------------- 8 files changed, 137 insertions(+), 74 deletions(-) diff --git a/include/grub/elf.h b/include/grub/elf.h index e54989cde..b9401f241 100644 --- a/include/grub/elf.h +++ b/include/grub/elf.h @@ -555,6 +555,7 @@ typedef struct #define PT_NUM 8 /* Number of defined types */ #define PT_LOOS 0x60000000 /* Start of OS-specific */ #define PT_GNU_EH_FRAME 0x6474e550 /* GCC .eh_frame_hdr segment */ +#define PT_GNU_STACK 0x6474e551 /* GCC stack segment */ #define PT_LOSUNW 0x6ffffffa #define PT_SUNWBSS 0x6ffffffa /* Sun Specific segment */ #define PT_SUNWSTACK 0x6ffffffb /* Stack segment */ diff --git a/include/grub/i386/kernel.h b/include/grub/i386/kernel.h index a0d806929..45c7abd72 100644 --- a/include/grub/i386/kernel.h +++ b/include/grub/i386/kernel.h @@ -19,14 +19,4 @@ #ifndef GRUB_KERNEL_CPU_HEADER #define GRUB_KERNEL_CPU_HEADER 1 - -#ifdef GRUB_MACHINE_IEEE1275 -#define GRUB_MOD_ALIGN 0x1000 -#else -#define GRUB_MOD_ALIGN 0x1 -#endif - -/* Non-zero value is only needed for PowerMacs. */ -#define GRUB_MOD_GAP 0x0 - #endif diff --git a/include/grub/offsets.h b/include/grub/offsets.h index 768e4726a..a7f252e85 100644 --- a/include/grub/offsets.h +++ b/include/grub/offsets.h @@ -127,9 +127,25 @@ #define GRUB_KERNEL_I386_IEEE1275_DATA_END 0x42 #define GRUB_KERNEL_I386_IEEE1275_LINK_ADDR 0x10000 +#define GRUB_KERNEL_I386_IEEE1275_MOD_ALIGN 0x1000 +#define GRUB_KERNEL_I386_COREBOOT_MOD_ALIGN 0x1 + +/* Non-zero value is only needed for PowerMacs. */ +#define GRUB_KERNEL_I386_IEEE1275_MOD_GAP 0x0 +#define GRUB_KERNEL_I386_COREBOOT_MOD_GAP 0x0 + +#define GRUB_KERNEL_POWERPC_IEEE1275_MOD_ALIGN 0x1000 + +/* Minimal gap between _end and the start of the modules. It's a hack + for PowerMac to prevent "CLAIM failed" error. The real fix is to + rewrite grub-mkimage to generate valid ELF files. */ +#define GRUB_KERNEL_POWERPC_IEEE1275_MOD_GAP 0x8000 + #ifdef MACHINE #define GRUB_OFFSETS_CONCAT_(a,b,c) a ## b ## c #define GRUB_OFFSETS_CONCAT(a,b,c) GRUB_OFFSETS_CONCAT_(a,b,c) +#define GRUB_KERNEL_MACHINE_MOD_ALIGN GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _MOD_ALIGN) +#define GRUB_KERNEL_MACHINE_MOD_GAP GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _MOD_GAP) #define GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _TOTAL_MODULE_SIZE) #define GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _KERNEL_IMAGE_SIZE) #define GRUB_KERNEL_MACHINE_COMPRESSED_SIZE GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _COMPRESSED_SIZE) diff --git a/include/grub/powerpc/kernel.h b/include/grub/powerpc/kernel.h index e4ff65174..3fc0b9e23 100644 --- a/include/grub/powerpc/kernel.h +++ b/include/grub/powerpc/kernel.h @@ -19,11 +19,4 @@ #ifndef GRUB_KERNEL_CPU_HEADER #define GRUB_KERNEL_CPU_HEADER 1 -#define GRUB_MOD_ALIGN 0x1000 - -/* Minimal gap between _end and the start of the modules. It's a hack - for PowerMac to prevent "CLAIM failed" error. The real fix is to - rewrite grub-mkimage to generate valid ELF files. */ -#define GRUB_MOD_GAP 0x8000 - #endif diff --git a/kern/i386/coreboot/init.c b/kern/i386/coreboot/init.c index 5f80f28c1..f367269c4 100644 --- a/kern/i386/coreboot/init.c +++ b/kern/i386/coreboot/init.c @@ -144,6 +144,6 @@ grub_arch_modules_addr (void) #ifdef GRUB_MACHINE_QEMU return grub_core_entry_addr + grub_kernel_image_size; #else - return ALIGN_UP((grub_addr_t) _end, GRUB_MOD_ALIGN); + return ALIGN_UP((grub_addr_t) _end, GRUB_KERNEL_MACHINE_MOD_ALIGN); #endif } diff --git a/kern/ieee1275/init.c b/kern/ieee1275/init.c index 75f261a71..db9583d8b 100644 --- a/kern/ieee1275/init.c +++ b/kern/ieee1275/init.c @@ -284,5 +284,5 @@ grub_get_rtc (void) grub_addr_t grub_arch_modules_addr (void) { - return ALIGN_UP((grub_addr_t) _end + GRUB_MOD_GAP, GRUB_MOD_ALIGN); + return ALIGN_UP((grub_addr_t) _end + GRUB_KERNEL_MACHINE_MOD_GAP, GRUB_KERNEL_MACHINE_MOD_ALIGN); } diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index 25ab5afe4..cc4a225d4 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -72,6 +72,7 @@ struct image_target_desc signed vaddr_offset; unsigned install_dos_part, install_bsd_part; grub_uint64_t link_addr; + unsigned mod_gap, mod_align; }; struct image_target_desc image_targets[] = @@ -92,7 +93,11 @@ struct image_target_desc image_targets[] = .vaddr_offset = 0, .install_dos_part = TARGET_NO_FIELD, .install_bsd_part = TARGET_NO_FIELD, - .link_addr = GRUB_KERNEL_I386_COREBOOT_LINK_ADDR + .link_addr = GRUB_KERNEL_I386_COREBOOT_LINK_ADDR, + .elf_target = EM_386, + .link_align = 4, + .mod_gap = GRUB_KERNEL_I386_COREBOOT_MOD_GAP, + .mod_align = GRUB_KERNEL_I386_COREBOOT_MOD_ALIGN }, { .name = "i386-pc", @@ -150,7 +155,11 @@ struct image_target_desc image_targets[] = .vaddr_offset = 0, .install_dos_part = TARGET_NO_FIELD, .install_bsd_part = TARGET_NO_FIELD, - .link_addr = GRUB_KERNEL_I386_IEEE1275_LINK_ADDR + .link_addr = GRUB_KERNEL_I386_IEEE1275_LINK_ADDR, + .elf_target = EM_386, + .mod_gap = GRUB_KERNEL_I386_IEEE1275_MOD_GAP, + .mod_align = GRUB_KERNEL_I386_IEEE1275_MOD_ALIGN, + .link_align = 4, }, { .name = "i386-qemu", @@ -228,7 +237,11 @@ struct image_target_desc image_targets[] = .vaddr_offset = 0, .install_dos_part = TARGET_NO_FIELD, .install_bsd_part = TARGET_NO_FIELD, - .link_addr = GRUB_KERNEL_POWERPC_IEEE1275_LINK_ADDR + .link_addr = GRUB_KERNEL_POWERPC_IEEE1275_LINK_ADDR, + .elf_target = EM_PPC, + .mod_gap = GRUB_KERNEL_POWERPC_IEEE1275_MOD_GAP, + .mod_align = GRUB_KERNEL_POWERPC_IEEE1275_MOD_ALIGN, + .link_align = 4 }, { .name = "sparc64-ieee1275-raw", @@ -463,7 +476,7 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], grub_size_t bss_size; grub_uint64_t start_address; void *rel_section; - grub_size_t reloc_size; + grub_size_t reloc_size, align; path_list = grub_util_resolve_dependencies (dir, "moddep.lst", mods); kernel_path = grub_util_get_path (dir, "kernel.img"); @@ -503,11 +516,11 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], if (image_target->voidp_sizeof == 4) kernel_img = load_image32 (kernel_path, &exec_size, &kernel_size, &bss_size, total_module_size, &start_address, &rel_section, - &reloc_size, image_target); + &reloc_size, &align, image_target); else kernel_img = load_image64 (kernel_path, &exec_size, &kernel_size, &bss_size, total_module_size, &start_address, &rel_section, - &reloc_size, image_target); + &reloc_size, &align, image_target); if (image_target->prefix + strlen (prefix) + 1 > image_target->data_end) grub_util_error (_("prefix is too long")); @@ -961,6 +974,9 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], grub_uint32_t target_addr; int header_size, footer_size = 0; int phnum = 1; + + if (image_target->id != IMAGE_YEELOONG_ELF) + phnum += 2; if (note) { @@ -994,7 +1010,10 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], /* No section headers. */ ehdr->e_shoff = grub_host_to_target32 (0); - ehdr->e_shentsize = grub_host_to_target16 (0); + if (image_target->id == IMAGE_YEELOONG_ELF) + ehdr->e_shentsize = grub_host_to_target16 (0); + else + ehdr->e_shentsize = grub_host_to_target16 (sizeof (Elf32_Shdr)); ehdr->e_shnum = grub_host_to_target16 (0); ehdr->e_shstrndx = grub_host_to_target16 (0); @@ -1012,14 +1031,44 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], ehdr->e_entry = grub_host_to_target32 (target_addr); phdr->p_vaddr = grub_host_to_target32 (target_addr); phdr->p_paddr = grub_host_to_target32 (target_addr); - phdr->p_align = grub_host_to_target32 (image_target->link_align); + phdr->p_align = grub_host_to_target32 (align > image_target->link_align ? align : image_target->link_align); if (image_target->id == IMAGE_YEELOONG_ELF) ehdr->e_flags = grub_host_to_target32 (0x1000 | EF_MIPS_NOREORDER | EF_MIPS_PIC | EF_MIPS_CPIC); else ehdr->e_flags = 0; - phdr->p_filesz = grub_host_to_target32 (core_size); - phdr->p_memsz = grub_host_to_target32 (core_size); + if (image_target->id == IMAGE_YEELOONG_ELF) + { + phdr->p_filesz = grub_host_to_target32 (core_size); + phdr->p_memsz = grub_host_to_target32 (core_size); + } + else + { + grub_uint32_t target_addr_mods; + phdr->p_filesz = grub_host_to_target32 (kernel_size); + phdr->p_memsz = grub_host_to_target32 (kernel_size + bss_size); + + phdr++; + phdr->p_type = grub_host_to_target32 (PT_GNU_STACK); + phdr->p_offset = grub_host_to_target32 (header_size + kernel_size); + phdr->p_paddr = phdr->p_vaddr = phdr->p_filesz = phdr->p_memsz = 0; + phdr->p_flags = grub_host_to_target32 (PF_R | PF_W | PF_X); + phdr->p_align = grub_host_to_target32 (image_target->link_align); + + phdr++; + phdr->p_type = grub_host_to_target32 (PT_LOAD); + phdr->p_offset = grub_host_to_target32 (header_size + kernel_size); + phdr->p_flags = grub_host_to_target32 (PF_R | PF_W | PF_X); + phdr->p_filesz = phdr->p_memsz + = grub_host_to_target32 (core_size - kernel_size); + + target_addr_mods = ALIGN_UP (target_addr + kernel_size + bss_size + + image_target->mod_gap, + image_target->mod_align); + phdr->p_vaddr = grub_host_to_target32 (target_addr_mods); + phdr->p_paddr = grub_host_to_target32 (target_addr_mods); + phdr->p_align = grub_host_to_target32 (image_target->link_align); + } if (note) { @@ -1040,14 +1089,15 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], note->descriptor.virt_size = grub_host_to_target32 (0xffffffff); note->descriptor.load_base = grub_host_to_target32 (0x00004000); - phdr[1].p_type = grub_host_to_target32 (PT_NOTE); - phdr[1].p_flags = grub_host_to_target32 (PF_R); - phdr[1].p_align = grub_host_to_target32 (image_target->voidp_sizeof); - phdr[1].p_vaddr = 0; - phdr[1].p_paddr = 0; - phdr[1].p_filesz = grub_host_to_target32 (note_size); - phdr[1].p_memsz = 0; - phdr[1].p_offset = grub_host_to_target32 (header_size + program_size); + phdr++; + phdr->p_type = grub_host_to_target32 (PT_NOTE); + phdr->p_flags = grub_host_to_target32 (PF_R); + phdr->p_align = grub_host_to_target32 (image_target->voidp_sizeof); + phdr->p_vaddr = 0; + phdr->p_paddr = 0; + phdr->p_filesz = grub_host_to_target32 (note_size); + phdr->p_memsz = 0; + phdr->p_offset = grub_host_to_target32 (header_size + program_size); } free (core_img); diff --git a/util/grub-mkimagexx.c b/util/grub-mkimagexx.c index abfe56d42..e9fdc7428 100644 --- a/util/grub-mkimagexx.c +++ b/util/grub-mkimagexx.c @@ -523,6 +523,7 @@ static Elf_Addr * SUFFIX (locate_sections) (Elf_Shdr *sections, Elf_Half section_entsize, Elf_Half num_sections, const char *strtab, grub_size_t *exec_size, grub_size_t *kernel_sz, + grub_size_t *all_align, struct image_target_desc *image_target) { int i; @@ -530,11 +531,21 @@ SUFFIX (locate_sections) (Elf_Shdr *sections, Elf_Half section_entsize, Elf_Addr *section_addresses; Elf_Shdr *s; + *all_align = 1; + section_addresses = xmalloc (sizeof (*section_addresses) * num_sections); memset (section_addresses, 0, sizeof (*section_addresses) * num_sections); current_address = 0; + for (i = 0, s = sections; + i < num_sections; + i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + if ((grub_target_to_host (s->sh_flags) & SHF_ALLOC) + && grub_host_to_target32 (s->sh_addralign) > *all_align) + *all_align = grub_host_to_target32 (s->sh_addralign); + + /* .text */ for (i = 0, s = sections; i < num_sections; @@ -546,7 +557,6 @@ SUFFIX (locate_sections) (Elf_Shdr *sections, Elf_Half section_entsize, if (align) current_address = ALIGN_UP (current_address + image_target->vaddr_offset, align) - image_target->vaddr_offset; - grub_util_info ("locating the section %s at 0x%x", name, current_address); section_addresses[i] = current_address; @@ -589,6 +599,7 @@ SUFFIX (load_image) (const char *kernel_path, grub_size_t *exec_size, grub_size_t *kernel_sz, grub_size_t *bss_size, grub_size_t total_module_size, grub_uint64_t *start, void **reloc_section, grub_size_t *reloc_size, + grub_size_t *align, struct image_target_desc *image_target) { char *kernel_img, *out_img; @@ -631,44 +642,47 @@ SUFFIX (load_image) (const char *kernel_path, grub_size_t *exec_size, section_addresses = SUFFIX (locate_sections) (sections, section_entsize, num_sections, strtab, - exec_size, kernel_sz, image_target); + exec_size, kernel_sz, align, + image_target); + + section_vaddresses = xmalloc (sizeof (*section_addresses) * num_sections); + + for (i = 0; i < num_sections; i++) + section_vaddresses[i] = section_addresses[i] + image_target->vaddr_offset; + + if (image_target->id != IMAGE_EFI) + { + Elf_Addr current_address = *kernel_sz; + + for (i = 0, s = sections; + i < num_sections; + i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + if (grub_target_to_host32 (s->sh_type) == SHT_NOBITS) + { + Elf_Word align = grub_host_to_target32 (s->sh_addralign); + const char *name = strtab + grub_host_to_target32 (s->sh_name); + + if (align) + current_address = ALIGN_UP (current_address + + image_target->vaddr_offset, align) + - image_target->vaddr_offset; + + grub_util_info ("locating the section %s at 0x%x", + name, current_address); + section_vaddresses[i] = current_address + + image_target->vaddr_offset; + current_address += grub_host_to_target_addr (s->sh_size); + } + current_address = ALIGN_UP (current_address + image_target->vaddr_offset, + image_target->section_align) + - image_target->vaddr_offset; + *bss_size = current_address - *kernel_sz; + } + else + *bss_size = 0; if (image_target->id == IMAGE_EFI) { - section_vaddresses = xmalloc (sizeof (*section_addresses) * num_sections); - - for (i = 0; i < num_sections; i++) - section_vaddresses[i] = section_addresses[i] + image_target->vaddr_offset; - -#if 0 - { - Elf_Addr current_address = *kernel_sz; - - for (i = 0, s = sections; - i < num_sections; - i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if (grub_target_to_host32 (s->sh_type) == SHT_NOBITS) - { - Elf_Word align = grub_host_to_target32 (s->sh_addralign); - const char *name = strtab + grub_host_to_target32 (s->sh_name); - - if (align) - current_address = ALIGN_UP (current_address + VADDR_OFFSET, align) - - VADDR_OFFSET; - - grub_util_info ("locating the section %s at 0x%x", - name, current_address); - section_vaddresses[i] = current_address + VADDR_OFFSET; - current_address += grub_host_to_target_addr (s->sh_size); - } - current_address = ALIGN_UP (current_address + VADDR_OFFSET, SECTION_ALIGN) - - VADDR_OFFSET; - *bss_size = current_address - *kernel_sz; - } -#else - *bss_size = 0; -#endif - symtab_section = NULL; for (i = 0, s = sections; i < num_sections; @@ -699,7 +713,6 @@ SUFFIX (load_image) (const char *kernel_path, grub_size_t *exec_size, } else { - *bss_size = 0; *reloc_size = 0; *reloc_section = NULL; } From 8ea6ecb36d0df734d1cef2c0290c114b649c703d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 26 Apr 2010 21:11:16 +0200 Subject: [PATCH 607/738] Some cleanups --- conf/common.rmk | 2 +- conf/i386-pc.rmk | 2 +- include/grub/i386/coreboot/kernel.h | 28 -- include/grub/i386/efi/kernel.h | 27 -- include/grub/i386/ieee1275/kernel.h | 1 - include/grub/i386/kernel.h | 22 -- include/grub/i386/pc/kernel.h | 4 - include/grub/i386/qemu/kernel.h | 4 - include/grub/kernel.h | 4 + include/grub/mips/kernel.h | 34 -- include/grub/mips/qemu-mips/boot.h | 0 include/grub/mips/qemu-mips/kernel.h | 4 - include/grub/mips/yeeloong/boot.h | 0 include/grub/mips/yeeloong/kernel.h | 1 - include/grub/offsets.h | 2 + include/grub/powerpc/ieee1275/kernel.h | 35 -- include/grub/sparc64/ieee1275/kernel.h | 9 - include/grub/sparc64/kernel.h | 30 -- include/grub/types.h | 36 -- include/grub/x86_64/efi/kernel.h | 27 -- include/grub/x86_64/kernel.h | 1 - kern/efi/init.c | 1 - kern/i386/coreboot/init.c | 5 +- kern/i386/coreboot/startup.S | 2 +- kern/i386/ieee1275/startup.S | 1 - kern/ieee1275/cmain.c | 1 - kern/ieee1275/init.c | 3 +- kern/ieee1275/openfw.c | 1 - kern/mips/init.c | 1 - kern/mips/startup.S | 6 +- kern/mips/yeeloong/init.c | 1 - kern/powerpc/ieee1275/startup.S | 2 +- util/elf/grub-mkimage.c | 463 ------------------------- util/grub-mkimagexx.c | 3 + util/i386/pc/grub-setup.c | 7 + util/sparc64/ieee1275/grub-setup.c | 7 + 36 files changed, 34 insertions(+), 743 deletions(-) delete mode 100644 include/grub/i386/coreboot/kernel.h delete mode 100644 include/grub/i386/efi/kernel.h delete mode 100644 include/grub/i386/ieee1275/kernel.h delete mode 100644 include/grub/i386/kernel.h delete mode 100644 include/grub/mips/kernel.h delete mode 100644 include/grub/mips/qemu-mips/boot.h delete mode 100644 include/grub/mips/yeeloong/boot.h delete mode 100644 include/grub/powerpc/ieee1275/kernel.h delete mode 100644 include/grub/sparc64/kernel.h delete mode 100644 include/grub/x86_64/efi/kernel.h delete mode 100644 include/grub/x86_64/kernel.h delete mode 100644 util/elf/grub-mkimage.c diff --git a/conf/common.rmk b/conf/common.rmk index 98dca34f9..f9e7eb194 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -118,7 +118,7 @@ kernel_img_HEADERS += boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ list.h handler.h command.h i18n.h env_private.h libgcc.h ifneq ($(platform), emu) -kernel_img_HEADERS += machine/memory.h machine/loader.h machine/kernel.h +kernel_img_HEADERS += machine/memory.h machine/loader.h endif symlist.c: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h gensymlist.sh diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk index f0da94b42..4c55f28f6 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -53,7 +53,7 @@ kernel_img_SOURCES = kern/i386/pc/startup.S \ term/i386/pc/console.c term/i386/vga_common.c \ symlist.c kernel_img_HEADERS += machine/biosdisk.h machine/vga.h machine/vbe.h \ - machine/pxe.h i386/pit.h + machine/pxe.h i386/pit.h machine/kernel.h kernel_img_CFLAGS = $(COMMON_CFLAGS) $(TARGET_IMG_CFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) kernel_img_LDFLAGS += $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)0x8200 $(COMMON_CFLAGS) diff --git a/include/grub/i386/coreboot/kernel.h b/include/grub/i386/coreboot/kernel.h deleted file mode 100644 index fb60668cc..000000000 --- a/include/grub/i386/coreboot/kernel.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2005,2006,2007,2008 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_KERNEL_MACHINE_HEADER -#define GRUB_KERNEL_MACHINE_HEADER 1 - -#include - -#ifndef ASM_FILE -extern char grub_prefix[]; -#endif - -#endif /* ! GRUB_KERNEL_MACHINE_HEADER */ diff --git a/include/grub/i386/efi/kernel.h b/include/grub/i386/efi/kernel.h deleted file mode 100644 index 0cb39a215..000000000 --- a/include/grub/i386/efi/kernel.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2002,2003,2007 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_MACHINE_KERNEL_HEADER -#define GRUB_MACHINE_KERNEL_HEADER 1 - -/* The prefix which points to the directory where GRUB modules and its - configuration file are located. */ -extern char grub_prefix[]; - -#endif /* ! GRUB_MACHINE_KERNEL_HEADER */ - diff --git a/include/grub/i386/ieee1275/kernel.h b/include/grub/i386/ieee1275/kernel.h deleted file mode 100644 index dccf8cbe1..000000000 --- a/include/grub/i386/ieee1275/kernel.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/include/grub/i386/kernel.h b/include/grub/i386/kernel.h deleted file mode 100644 index 45c7abd72..000000000 --- a/include/grub/i386/kernel.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2005,2006,2007,2008,2009 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_KERNEL_CPU_HEADER -#define GRUB_KERNEL_CPU_HEADER 1 - -#endif diff --git a/include/grub/i386/pc/kernel.h b/include/grub/i386/pc/kernel.h index f0a9d4fc2..1de37a5d5 100644 --- a/include/grub/i386/pc/kernel.h +++ b/include/grub/i386/pc/kernel.h @@ -41,10 +41,6 @@ extern grub_int32_t grub_install_dos_part; /* The BSD partition number of the installed partition. */ extern grub_int32_t grub_install_bsd_part; -/* The prefix which points to the directory where GRUB modules and its - configuration file are located. */ -extern char grub_prefix[]; - /* The boot BIOS drive number. */ extern grub_uint8_t EXPORT_VAR(grub_boot_drive); diff --git a/include/grub/i386/qemu/kernel.h b/include/grub/i386/qemu/kernel.h index e29f0aeb2..0aa2b3d09 100644 --- a/include/grub/i386/qemu/kernel.h +++ b/include/grub/i386/qemu/kernel.h @@ -34,10 +34,6 @@ extern grub_int32_t grub_kernel_image_size; /* The total size of module images following the kernel. */ extern grub_int32_t grub_total_module_size; -/* The prefix which points to the directory where GRUB modules and its - configuration file are located. */ -extern char grub_prefix[]; - #endif /* ! ASM_FILE */ #endif /* ! GRUB_KERNEL_MACHINE_HEADER */ diff --git a/include/grub/kernel.h b/include/grub/kernel.h index f7740b2e3..fed875db1 100644 --- a/include/grub/kernel.h +++ b/include/grub/kernel.h @@ -90,4 +90,8 @@ void grub_machine_set_prefix (void); /* Register all the exported symbols. This is automatically generated. */ void grub_register_exported_symbols (void); +#if ! defined (ASM_FILE) && !defined (GRUB_MACHINE_EMU) +extern char grub_prefix[]; +#endif + #endif /* ! GRUB_KERNEL_HEADER */ diff --git a/include/grub/mips/kernel.h b/include/grub/mips/kernel.h deleted file mode 100644 index bc4d43b2b..000000000 --- a/include/grub/mips/kernel.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2005,2006,2007,2008 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_KERNEL_CPU_HEADER -#define GRUB_KERNEL_CPU_HEADER 1 - -#define GRUB_MOD_ALIGN 0x1 -/* Non-zero value is only needed for PowerMacs. */ -#define GRUB_MOD_GAP 0x0 - -#ifndef ASM_FILE - -/* The prefix which points to the directory where GRUB modules and its - configuration file are located. */ -extern char grub_prefix[]; - -#endif - -#endif diff --git a/include/grub/mips/qemu-mips/boot.h b/include/grub/mips/qemu-mips/boot.h deleted file mode 100644 index e69de29bb..000000000 diff --git a/include/grub/mips/qemu-mips/kernel.h b/include/grub/mips/qemu-mips/kernel.h index dbf74c1b2..230455dbf 100644 --- a/include/grub/mips/qemu-mips/kernel.h +++ b/include/grub/mips/qemu-mips/kernel.h @@ -27,10 +27,6 @@ void EXPORT_FUNC (grub_reboot) (void); void EXPORT_FUNC (grub_halt) (void); -/* The prefix which points to the directory where GRUB modules and its - configuration file are located. */ -extern char grub_prefix[]; - #endif #endif /* ! GRUB_KERNEL_MACHINE_HEADER */ diff --git a/include/grub/mips/yeeloong/boot.h b/include/grub/mips/yeeloong/boot.h deleted file mode 100644 index e69de29bb..000000000 diff --git a/include/grub/mips/yeeloong/kernel.h b/include/grub/mips/yeeloong/kernel.h index 230455dbf..c08405e83 100644 --- a/include/grub/mips/yeeloong/kernel.h +++ b/include/grub/mips/yeeloong/kernel.h @@ -20,7 +20,6 @@ #define GRUB_KERNEL_MACHINE_HEADER 1 #include -#include #ifndef ASM_FILE diff --git a/include/grub/offsets.h b/include/grub/offsets.h index a7f252e85..ae0b2557e 100644 --- a/include/grub/offsets.h +++ b/include/grub/offsets.h @@ -136,6 +136,8 @@ #define GRUB_KERNEL_POWERPC_IEEE1275_MOD_ALIGN 0x1000 +#define GRUB_KERNEL_MIPS_YEELOONG_MOD_ALIGN 0x1 + /* Minimal gap between _end and the start of the modules. It's a hack for PowerMac to prevent "CLAIM failed" error. The real fix is to rewrite grub-mkimage to generate valid ELF files. */ diff --git a/include/grub/powerpc/ieee1275/kernel.h b/include/grub/powerpc/ieee1275/kernel.h deleted file mode 100644 index 75d6c62a6..000000000 --- a/include/grub/powerpc/ieee1275/kernel.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2005,2006,2007,2008 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_KERNEL_MACHINE_HEADER -#define GRUB_KERNEL_MACHINE_HEADER 1 - -#include -#include - -#define GRUB_KERNEL_MACHINE_LINK_ADDR 0x200000 - -#ifndef ASM_FILE - -/* The prefix which points to the directory where GRUB modules and its - configuration file are located. */ -extern char grub_prefix[]; - -#endif - -#endif /* ! GRUB_KERNEL_MACHINE_HEADER */ diff --git a/include/grub/sparc64/ieee1275/kernel.h b/include/grub/sparc64/ieee1275/kernel.h index 012b5570c..5aa50b852 100644 --- a/include/grub/sparc64/ieee1275/kernel.h +++ b/include/grub/sparc64/ieee1275/kernel.h @@ -19,11 +19,6 @@ #ifndef GRUB_KERNEL_MACHINE_HEADER #define GRUB_KERNEL_MACHINE_HEADER 1 -#define GRUB_MOD_ALIGN 0x2000 - -/* Non-zero value is only needed for PowerMacs. */ -#define GRUB_MOD_GAP 0x0 - #define GRUB_KERNEL_MACHINE_STACK_SIZE 0x40000 #ifndef ASM_FILE @@ -37,10 +32,6 @@ extern grub_int32_t grub_kernel_image_size; /* The total size of module images following the kernel. */ extern grub_int32_t grub_total_module_size; -/* The prefix which points to the directory where GRUB modules and its - configuration file are located. */ -extern char grub_prefix[]; - #endif /* ! ASM_FILE */ #endif /* ! GRUB_KERNEL_MACHINE_HEADER */ diff --git a/include/grub/sparc64/kernel.h b/include/grub/sparc64/kernel.h deleted file mode 100644 index 9f404b05d..000000000 --- a/include/grub/sparc64/kernel.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2005,2006,2007,2008 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_KERNEL_CPU_HEADER -#define GRUB_KERNEL_CPU_HEADER 1 - -#define GRUB_MOD_ALIGN 0x2000 - -/* Non-zero value is only needed for PowerMacs. */ -#define GRUB_MOD_GAP 0x0 - -#define GRUB_KERNEL_CPU_PREFIX 0x2 -#define GRUB_KERNEL_CPU_DATA_END 0x42 - -#endif diff --git a/include/grub/types.h b/include/grub/types.h index 9eaafd0c1..6e9461f1d 100644 --- a/include/grub/types.h +++ b/include/grub/types.h @@ -178,21 +178,6 @@ static inline grub_uint64_t grub_swap_bytes64(grub_uint64_t x) # define grub_be_to_cpu16(x) ((grub_uint16_t) (x)) # define grub_be_to_cpu32(x) ((grub_uint32_t) (x)) # define grub_be_to_cpu64(x) ((grub_uint64_t) (x)) -# ifdef GRUB_TARGET_WORDS_BIGENDIAN -# define grub_target_to_host16(x) ((grub_uint16_t) (x)) -# define grub_target_to_host32(x) ((grub_uint32_t) (x)) -# define grub_target_to_host64(x) ((grub_uint64_t) (x)) -# define grub_host_to_target16(x) ((grub_uint16_t) (x)) -# define grub_host_to_target32(x) ((grub_uint32_t) (x)) -# define grub_host_to_target64(x) ((grub_uint64_t) (x)) -# else /* ! GRUB_TARGET_WORDS_BIGENDIAN */ -# define grub_target_to_host16(x) grub_swap_bytes16(x) -# define grub_target_to_host32(x) grub_swap_bytes32(x) -# define grub_target_to_host64(x) grub_swap_bytes64(x) -# define grub_host_to_target16(x) grub_swap_bytes16(x) -# define grub_host_to_target32(x) grub_swap_bytes32(x) -# define grub_host_to_target64(x) grub_swap_bytes64(x) -# endif #else /* ! WORDS_BIGENDIAN */ # define grub_cpu_to_le16(x) ((grub_uint16_t) (x)) # define grub_cpu_to_le32(x) ((grub_uint32_t) (x)) @@ -206,27 +191,6 @@ static inline grub_uint64_t grub_swap_bytes64(grub_uint64_t x) # define grub_be_to_cpu16(x) grub_swap_bytes16(x) # define grub_be_to_cpu32(x) grub_swap_bytes32(x) # define grub_be_to_cpu64(x) grub_swap_bytes64(x) -# ifdef GRUB_TARGET_WORDS_BIGENDIAN -# define grub_target_to_host16(x) grub_swap_bytes16(x) -# define grub_target_to_host32(x) grub_swap_bytes32(x) -# define grub_target_to_host64(x) grub_swap_bytes64(x) -# define grub_host_to_target16(x) grub_swap_bytes16(x) -# define grub_host_to_target32(x) grub_swap_bytes32(x) -# define grub_host_to_target64(x) grub_swap_bytes64(x) -# else /* ! GRUB_TARGET_WORDS_BIGENDIAN */ -# define grub_target_to_host16(x) ((grub_uint16_t) (x)) -# define grub_target_to_host32(x) ((grub_uint32_t) (x)) -# define grub_target_to_host64(x) ((grub_uint64_t) (x)) -# define grub_host_to_target16(x) ((grub_uint16_t) (x)) -# define grub_host_to_target32(x) ((grub_uint32_t) (x)) -# define grub_host_to_target64(x) ((grub_uint64_t) (x)) -# endif #endif /* ! WORDS_BIGENDIAN */ -#if GRUB_TARGET_SIZEOF_VOID_P == 8 -# define grub_host_to_target_addr(x) grub_host_to_target64(x) -#else -# define grub_host_to_target_addr(x) grub_host_to_target32(x) -#endif - #endif /* ! GRUB_TYPES_HEADER */ diff --git a/include/grub/x86_64/efi/kernel.h b/include/grub/x86_64/efi/kernel.h deleted file mode 100644 index 0cb39a215..000000000 --- a/include/grub/x86_64/efi/kernel.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2002,2003,2007 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef GRUB_MACHINE_KERNEL_HEADER -#define GRUB_MACHINE_KERNEL_HEADER 1 - -/* The prefix which points to the directory where GRUB modules and its - configuration file are located. */ -extern char grub_prefix[]; - -#endif /* ! GRUB_MACHINE_KERNEL_HEADER */ - diff --git a/include/grub/x86_64/kernel.h b/include/grub/x86_64/kernel.h deleted file mode 100644 index 25ac57e40..000000000 --- a/include/grub/x86_64/kernel.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/kern/efi/init.c b/kern/efi/init.c index a0b4ff779..afd21055d 100644 --- a/kern/efi/init.c +++ b/kern/efi/init.c @@ -24,7 +24,6 @@ #include #include #include -#include void grub_efi_init (void) diff --git a/kern/i386/coreboot/init.c b/kern/i386/coreboot/init.c index f367269c4..08f2cce3a 100644 --- a/kern/i386/coreboot/init.c +++ b/kern/i386/coreboot/init.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include @@ -33,8 +32,10 @@ #include #include #include -#include #include +#ifdef GRUB_MACHINE_QEMU +#include +#endif #define GRUB_FLOPPY_REG_DIGITAL_OUTPUT 0x3f2 diff --git a/kern/i386/coreboot/startup.S b/kern/i386/coreboot/startup.S index ecdc0b61c..bdefb69bc 100644 --- a/kern/i386/coreboot/startup.S +++ b/kern/i386/coreboot/startup.S @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include #include diff --git a/kern/i386/ieee1275/startup.S b/kern/i386/ieee1275/startup.S index ad2ef329b..c0a08a954 100644 --- a/kern/i386/ieee1275/startup.S +++ b/kern/i386/ieee1275/startup.S @@ -19,7 +19,6 @@ #include #include #include -#include #include #include diff --git a/kern/ieee1275/cmain.c b/kern/ieee1275/cmain.c index c1185f82c..cdc8ca051 100644 --- a/kern/ieee1275/cmain.c +++ b/kern/ieee1275/cmain.c @@ -20,7 +20,6 @@ #include #include #include -#include #include int (*grub_ieee1275_entry_fn) (void *); diff --git a/kern/ieee1275/init.c b/kern/ieee1275/init.c index db9583d8b..f79b82776 100644 --- a/kern/ieee1275/init.c +++ b/kern/ieee1275/init.c @@ -29,10 +29,9 @@ #include #include #include -#include -#include #include #include +#include /* The minimal heap size we can live with. */ #define HEAP_MIN_SIZE (unsigned long) (2 * 1024 * 1024) diff --git a/kern/ieee1275/openfw.c b/kern/ieee1275/openfw.c index cf9e1a870..5693f3be0 100644 --- a/kern/ieee1275/openfw.c +++ b/kern/ieee1275/openfw.c @@ -21,7 +21,6 @@ #include #include #include -#include #include enum grub_ieee1275_parse_type diff --git a/kern/mips/init.c b/kern/mips/init.c index 5adcedcbb..f220108d4 100644 --- a/kern/mips/init.c +++ b/kern/mips/init.c @@ -18,7 +18,6 @@ #include #include -#include void grub_machine_set_prefix (void) diff --git a/kern/mips/startup.S b/kern/mips/startup.S index 876b2df71..1d18131be 100644 --- a/kern/mips/startup.S +++ b/kern/mips/startup.S @@ -20,7 +20,7 @@ #include #include #include -#include +#include #define BASE_ADDR 8 @@ -177,8 +177,8 @@ cont: lui $t1, %hi(_end) addiu $t1, %lo(_end) - addiu $t1, (GRUB_MOD_ALIGN-1) - li $t3, (GRUB_MOD_ALIGN-1) + addiu $t1, (GRUB_KERNEL_MACHINE_MOD_ALIGN-1) + li $t3, (GRUB_KERNEL_MACHINE_MOD_ALIGN-1) nor $t3, $t3, $0 and $t1, $t1, $t3 diff --git a/kern/mips/yeeloong/init.c b/kern/mips/yeeloong/init.c index 6bba27b51..47aa774a0 100644 --- a/kern/mips/yeeloong/init.c +++ b/kern/mips/yeeloong/init.c @@ -26,7 +26,6 @@ #include #include #include -#include extern void grub_video_sm712_init (void); extern void grub_video_init (void); diff --git a/kern/powerpc/ieee1275/startup.S b/kern/powerpc/ieee1275/startup.S index 979f260f8..96d153778 100644 --- a/kern/powerpc/ieee1275/startup.S +++ b/kern/powerpc/ieee1275/startup.S @@ -18,7 +18,7 @@ */ #include -#include +#include .extern __bss_start .extern _end diff --git a/util/elf/grub-mkimage.c b/util/elf/grub-mkimage.c deleted file mode 100644 index f37837c19..000000000 --- a/util/elf/grub-mkimage.c +++ /dev/null @@ -1,463 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2004,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "progname.h" - -#define GRUB_IEEE1275_NOTE_NAME "PowerPC" -#define GRUB_IEEE1275_NOTE_TYPE 0x1275 - -/* These structures are defined according to the CHRP binding to IEEE1275, - "Client Program Format" section. */ - -struct grub_ieee1275_note_hdr -{ - grub_uint32_t namesz; - grub_uint32_t descsz; - grub_uint32_t type; - char name[sizeof (GRUB_IEEE1275_NOTE_NAME)]; -}; - -struct grub_ieee1275_note_desc -{ - grub_uint32_t real_mode; - grub_uint32_t real_base; - grub_uint32_t real_size; - grub_uint32_t virt_base; - grub_uint32_t virt_size; - grub_uint32_t load_base; -}; - -struct grub_ieee1275_note -{ - struct grub_ieee1275_note_hdr header; - struct grub_ieee1275_note_desc descriptor; -}; - -void -load_note (Elf32_Phdr *phdr, FILE *out) -{ - struct grub_ieee1275_note note; - int note_size = sizeof (struct grub_ieee1275_note); - - grub_util_info ("adding CHRP NOTE segment"); - - note.header.namesz = grub_host_to_target32 (sizeof (GRUB_IEEE1275_NOTE_NAME)); - note.header.descsz = grub_host_to_target32 (note_size); - note.header.type = grub_host_to_target32 (GRUB_IEEE1275_NOTE_TYPE); - strcpy (note.header.name, GRUB_IEEE1275_NOTE_NAME); - note.descriptor.real_mode = grub_host_to_target32 (0xffffffff); - note.descriptor.real_base = grub_host_to_target32 (0x00c00000); - note.descriptor.real_size = grub_host_to_target32 (0xffffffff); - note.descriptor.virt_base = grub_host_to_target32 (0xffffffff); - note.descriptor.virt_size = grub_host_to_target32 (0xffffffff); - note.descriptor.load_base = grub_host_to_target32 (0x00004000); - - /* Write the note data to the new segment. */ - grub_util_write_image_at (¬e, note_size, - grub_target_to_host32 (phdr->p_offset), out); - - /* Fill in the rest of the segment header. */ - phdr->p_type = grub_host_to_target32 (PT_NOTE); - phdr->p_flags = grub_host_to_target32 (PF_R); - phdr->p_align = grub_host_to_target32 (GRUB_TARGET_SIZEOF_LONG); - phdr->p_vaddr = 0; - phdr->p_paddr = 0; - phdr->p_filesz = grub_host_to_target32 (note_size); - phdr->p_memsz = 0; -} - -void -load_modules (grub_addr_t modbase, Elf32_Phdr *phdr, const char *dir, - char *mods[], FILE *out, char *memdisk_path, char *config_path) -{ - char *module_img; - struct grub_util_path_list *path_list; - struct grub_util_path_list *p; - struct grub_module_info *modinfo; - size_t offset; - size_t total_module_size; - size_t memdisk_size = 0; - size_t config_size = 0; - - path_list = grub_util_resolve_dependencies (dir, "moddep.lst", mods); - - offset = sizeof (struct grub_module_info); - total_module_size = sizeof (struct grub_module_info); - - if (memdisk_path) - { - memdisk_size = ALIGN_UP(grub_util_get_image_size (memdisk_path), 512); - grub_util_info ("the size of memory disk is 0x%x", memdisk_size); - total_module_size += memdisk_size + sizeof (struct grub_module_header); - } - - if (config_path) - { - config_size = ALIGN_UP(grub_util_get_image_size (config_path), 512); - grub_util_info ("the size of memory disk is 0x%x", config_size); - total_module_size += config_size + sizeof (struct grub_module_header); - } - - for (p = path_list; p; p = p->next) - { - total_module_size += (grub_util_get_image_size (p->name) - + sizeof (struct grub_module_header)); - } - - grub_util_info ("the total module size is 0x%x", total_module_size); - - module_img = xmalloc (total_module_size); - modinfo = (struct grub_module_info *) module_img; - modinfo->magic = grub_host_to_target32 (GRUB_MODULE_MAGIC); - modinfo->offset = grub_host_to_target32 (sizeof (struct grub_module_info)); - modinfo->size = grub_host_to_target32 (total_module_size); - - /* Load all the modules, with headers, into module_img. */ - for (p = path_list; p; p = p->next) - { - struct grub_module_header *header; - size_t mod_size; - - grub_util_info ("adding module %s", p->name); - - mod_size = grub_util_get_image_size (p->name); - - header = (struct grub_module_header *) (module_img + offset); - header->type = OBJ_TYPE_ELF; - header->size = grub_host_to_target32 (mod_size + sizeof (*header)); - - grub_util_load_image (p->name, module_img + offset + sizeof (*header)); - - offset += sizeof (*header) + mod_size; - } - - if (memdisk_path) - { - struct grub_module_header *header; - - header = (struct grub_module_header *) (module_img + offset); - header->type = OBJ_TYPE_MEMDISK; - header->size = grub_host_to_target32 (memdisk_size + sizeof (*header)); - offset += sizeof (*header); - - grub_util_load_image (memdisk_path, module_img + offset); - offset += memdisk_size; - } - - if (config_path) - { - struct grub_module_header *header; - - header = (struct grub_module_header *) (module_img + offset); - header->type = OBJ_TYPE_CONFIG; - header->size = grub_host_to_target32 (config_size + sizeof (*header)); - offset += sizeof (*header); - - grub_util_load_image (config_path, module_img + offset); - offset += config_size; - } - - - /* Write the module data to the new segment. */ - grub_util_write_image_at (module_img, total_module_size, - grub_host_to_target32 (phdr->p_offset), out); - - /* Fill in the rest of the segment header. */ - phdr->p_type = grub_host_to_target32 (PT_LOAD); - phdr->p_flags = grub_host_to_target32 (PF_R | PF_W | PF_X); - phdr->p_align = grub_host_to_target32 (GRUB_TARGET_SIZEOF_LONG); - phdr->p_vaddr = grub_host_to_target32 (modbase); - phdr->p_paddr = grub_host_to_target32 (modbase); - phdr->p_filesz = grub_host_to_target32 (total_module_size); - phdr->p_memsz = grub_host_to_target32 (total_module_size); -} - -void -add_segments (char *dir, char *prefix, FILE *out, int chrp, char *mods[], char *memdisk_path, char *config_path) -{ - Elf32_Ehdr ehdr; - Elf32_Phdr *phdrs = NULL; - Elf32_Phdr *phdr; - FILE *in; - char *kernel_path; - grub_addr_t grub_end = 0; - off_t offset, first_segment; - int i, phdr_size; - - /* Read ELF header. */ - kernel_path = grub_util_get_path (dir, "kernel.img"); - in = fopen (kernel_path, "rb"); - if (! in) - grub_util_error ("cannot open %s", kernel_path); - - grub_util_read_at (&ehdr, sizeof (ehdr), 0, in); - - offset = ALIGN_UP (sizeof (ehdr), GRUB_TARGET_SIZEOF_LONG); - ehdr.e_phoff = grub_host_to_target32 (offset); - - phdr_size = (grub_target_to_host16 (ehdr.e_phentsize) * - grub_target_to_host16 (ehdr.e_phnum)); - - if (mods[0] != NULL) - phdr_size += grub_target_to_host16 (ehdr.e_phentsize); - - if (chrp) - phdr_size += grub_target_to_host16 (ehdr.e_phentsize); - - phdrs = xmalloc (phdr_size); - offset += ALIGN_UP (phdr_size, GRUB_TARGET_SIZEOF_LONG); - - first_segment = offset; - - /* Copy all existing segments. */ - for (i = 0; i < grub_target_to_host16 (ehdr.e_phnum); i++) - { - char *segment_img; - grub_size_t segment_end; - - phdr = phdrs + i; - - /* Read segment header. */ - grub_util_read_at (phdr, sizeof (Elf32_Phdr), - (grub_target_to_host32 (ehdr.e_phoff) - + (i * grub_target_to_host16 (ehdr.e_phentsize))), - in); - grub_util_info ("copying segment %d, type %d", i, - grub_target_to_host32 (phdr->p_type)); - - /* Locate _end. */ - segment_end = grub_target_to_host32 (phdr->p_paddr) - + grub_target_to_host32 (phdr->p_memsz); - grub_util_info ("segment %u end 0x%lx", i, segment_end); - if (segment_end > grub_end) - grub_end = segment_end; - - /* Read segment data and write it to new file. */ - segment_img = xmalloc (grub_target_to_host32 (phdr->p_filesz)); - - grub_util_read_at (segment_img, grub_target_to_host32 (phdr->p_filesz), - grub_target_to_host32 (phdr->p_offset), in); - - phdr->p_offset = grub_host_to_target32 (offset); - grub_util_write_image_at (segment_img, grub_target_to_host32 (phdr->p_filesz), - offset, out); - offset += ALIGN_UP (grub_target_to_host32 (phdr->p_filesz), - GRUB_TARGET_SIZEOF_LONG); - - free (segment_img); - } - - if (mods[0] != NULL) - { - grub_addr_t modbase; - - /* Place modules just after grub segment. */ - modbase = ALIGN_UP(grub_end + GRUB_MOD_GAP, GRUB_MOD_ALIGN); - - /* Construct new segment header for modules. */ - phdr = phdrs + grub_target_to_host16 (ehdr.e_phnum); - ehdr.e_phnum = grub_host_to_target16 (grub_target_to_host16 (ehdr.e_phnum) + 1); - - /* Fill in p_offset so the callees know where to write. */ - phdr->p_offset = grub_host_to_target32 (ALIGN_UP (grub_util_get_fp_size (out), - GRUB_TARGET_SIZEOF_LONG)); - - load_modules (modbase, phdr, dir, mods, out, memdisk_path, config_path); - } - - if (chrp) - { - /* Construct new segment header for the CHRP note. */ - phdr = phdrs + grub_target_to_host16 (ehdr.e_phnum); - ehdr.e_phnum = grub_host_to_target16 (grub_target_to_host16 (ehdr.e_phnum) + 1); - - /* Fill in p_offset so the callees know where to write. */ - phdr->p_offset = grub_host_to_target32 (ALIGN_UP (grub_util_get_fp_size (out), - GRUB_TARGET_SIZEOF_LONG)); - - load_note (phdr, out); - } - - /* Don't bother preserving the section headers. */ - ehdr.e_shoff = 0; - ehdr.e_shnum = 0; - ehdr.e_shstrndx = 0; - - /* Write entire segment table to the file. */ - grub_util_write_image_at (phdrs, phdr_size, grub_target_to_host32 (ehdr.e_phoff), out); - - /* Write ELF header. */ - grub_util_write_image_at (&ehdr, sizeof (ehdr), 0, out); - - if (prefix) - { - if (GRUB_KERNEL_MACHINE_PREFIX + strlen (prefix) + 1 > GRUB_KERNEL_MACHINE_DATA_END) - grub_util_error ("prefix too long"); - grub_util_write_image_at (prefix, strlen (prefix) + 1, first_segment + GRUB_KERNEL_MACHINE_PREFIX, out); - } - - free (phdrs); - free (kernel_path); -} - -static struct option options[] = - { - {"directory", required_argument, 0, 'd'}, - {"prefix", required_argument, 0, 'p'}, - {"memdisk", required_argument, 0, 'm'}, - {"config", required_argument, 0, 'c'}, - {"output", required_argument, 0, 'o'}, - {"help", no_argument, 0, 'h'}, - {"note", no_argument, 0, 'n'}, - {"version", no_argument, 0, 'V'}, - {"verbose", no_argument, 0, 'v'}, - { 0, 0, 0, 0 }, - }; - -static void -usage (int status) -{ - if (status) - fprintf (stderr, "Try `%s --help' for more information.\n", program_name); - else - printf ("\ -Usage: %s -o FILE [OPTION]... [MODULES]\n\ -\n\ -Make a bootable image of GRUB.\n\ -\n\ - -d, --directory=DIR use images and modules under DIR [default=%s]\n\ - -p, --prefix=DIR set grub_prefix directory\n\ - -m, --memdisk=FILE embed FILE as a memdisk image\n\ - -c, --config=FILE embed FILE as boot config\n\ - -o, --output=FILE output a generated image to FILE\n\ - -h, --help display this message and exit\n\ - -n, --note add NOTE segment for CHRP Open Firmware\n\ - -V, --version print version information and exit\n\ - -v, --verbose print verbose messages\n\ -\n\ -Report bugs to <%s>.\n\ -", program_name, GRUB_LIBDIR, PACKAGE_BUGREPORT); - - exit (status); -} - -int -main (int argc, char *argv[]) -{ - FILE *fp; - char *output = NULL; - char *dir = NULL; - char *prefix = NULL; - char *memdisk = NULL; - char *config = NULL; - int chrp = 0; - - set_program_name (argv[0]); - - grub_util_init_nls (); - - while (1) - { - int c = getopt_long (argc, argv, "d:p:m:c:o:hVvn", options, 0); - if (c == -1) - break; - - switch (c) - { - case 'd': - if (dir) - free (dir); - dir = xstrdup (optarg); - break; - case 'p': - if (prefix) - free (prefix); - prefix = xstrdup (optarg); - break; - case 'm': - if (memdisk) - free (memdisk); - memdisk = xstrdup (optarg); - - if (prefix) - free (prefix); - prefix = xstrdup ("(memdisk)/boot/grub"); - - break; - case 'c': - if (config) - free (config); - config = xstrdup (optarg); - - break; - - case 'h': - usage (0); - break; - case 'n': - chrp = 1; - break; - case 'o': - if (output) - free (output); - output = xstrdup (optarg); - break; - case 'V': - printf ("grub-mkimage (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION); - return 0; - case 'v': - verbosity++; - break; - default: - usage (1); - break; - } - } - - if (!output) - usage (1); - - fp = fopen (output, "wb"); - if (! fp) - grub_util_error ("cannot open %s", output); - - add_segments (dir ? : GRUB_LIBDIR, prefix, fp, chrp, argv + optind, memdisk, - config); - - fclose (fp); - - return 0; -} diff --git a/util/grub-mkimagexx.c b/util/grub-mkimagexx.c index e9fdc7428..4a257e329 100644 --- a/util/grub-mkimagexx.c +++ b/util/grub-mkimagexx.c @@ -17,6 +17,9 @@ * along with GRUB. If not, see . */ +#undef ELF_R_SYM +#undef ELF_R_TYPE + #if defined(MKIMAGE_ELF32) # define SUFFIX(x) x ## 32 # define ELFCLASSXX ELFCLASS32 diff --git a/util/i386/pc/grub-setup.c b/util/i386/pc/grub-setup.c index 63fa8c328..f479d5090 100644 --- a/util/i386/pc/grub-setup.c +++ b/util/i386/pc/grub-setup.c @@ -57,6 +57,13 @@ static const grub_gpt_part_type_t grub_gpt_partition_type_bios_boot = GRUB_GPT_P #define DEFAULT_BOOT_FILE "boot.img" #define DEFAULT_CORE_FILE "core.img" +#define grub_target_to_host16(x) grub_le_to_cpu16(x) +#define grub_target_to_host32(x) grub_le_to_cpu32(x) +#define grub_target_to_host64(x) grub_le_to_cpu64(x) +#define grub_host_to_target16(x) grub_cpu_to_le16(x) +#define grub_host_to_target32(x) grub_cpu_to_le32(x) +#define grub_host_to_target64(x) grub_cpu_to_le64(x) + void grub_putchar (int c) { diff --git a/util/sparc64/ieee1275/grub-setup.c b/util/sparc64/ieee1275/grub-setup.c index b511a96b2..fbf6ba036 100644 --- a/util/sparc64/ieee1275/grub-setup.c +++ b/util/sparc64/ieee1275/grub-setup.c @@ -76,6 +76,13 @@ #define DEFAULT_BOOT_FILE "boot.img" #define DEFAULT_CORE_FILE "core.img" +#define grub_target_to_host16(x) grub_be_to_cpu16(x) +#define grub_target_to_host32(x) grub_be_to_cpu32(x) +#define grub_target_to_host64(x) grub_be_to_cpu64(x) +#define grub_host_to_target16(x) grub_cpu_to_be16(x) +#define grub_host_to_target32(x) grub_cpu_to_be32(x) +#define grub_host_to_target64(x) grub_cpu_to_be64(x) + /* This is the blocklist used in the diskboot image. */ struct boot_blocklist { From 88d046d01efb74d256ccab953ebe0dbe82b0ee2e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 26 Apr 2010 21:27:41 +0200 Subject: [PATCH 608/738] Switch to new grub-mkimage syntax --- util/grub-install.in | 19 +++++++++++-------- util/grub-mkrescue.in | 4 ++-- util/i386/efi/grub-install.in | 2 +- util/ieee1275/grub-install.in | 4 ++-- util/powerpc/ieee1275/grub-mkrescue.in | 4 ++-- 5 files changed, 18 insertions(+), 15 deletions(-) diff --git a/util/grub-install.in b/util/grub-install.in index 142d5792f..8a93ace8c 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -35,11 +35,7 @@ pkglibdir=${libdir}/`echo ${PACKAGE_TARNAME}/${target_cpu}-${platform} | sed ${t localedir=@datadir@/locale grub_setup=${sbindir}/`echo grub-setup | sed ${transform}` -if [ "${target_cpu}-${platform}" = "i386-pc" ] || [ "${target_cpu}-${platform}" = "sparc64-ieee1275" ] || [ "${target_cpu}-${platform}" = "mips-yeeloong" ] ; then - grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}` -else - grub_mkimage=${bindir}/`echo grub-mkelfimage | sed ${transform}` -fi +grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}` grub_mkdevicemap=${sbindir}/`echo grub-mkdevicemap | sed ${transform}` grub_probe=${sbindir}/`echo grub-probe | sed ${transform}` grub_editenv=${bindir}/`echo grub-editenv | sed ${transform}` @@ -346,16 +342,23 @@ else prefix_drive=`$grub_probe --target=drive --device ${grub_device}` || exit 1 fi +case "${target_cpu}-${platform}" + i386-pc) mkimage_target=i386-pc ;; + sparc64-ieee1275) mkimage_target=sparc64-ieee1275-raw ;; + mips-yeeloong) mkimage_target=mipsel-yeeloong-elf ;; + *) mkimage_target=i386-coreboot; +esac + if [ "${target_cpu}-${platform}" = "i386-pc" ] || [ "${target_cpu}-${platform}" = "sparc64-ieee1275" ] ; then - $grub_mkimage ${config_opt} --output=${grubdir}/core.img --prefix=${prefix_drive}${relative_grubdir} $modules || exit 1 + $grub_mkimage ${config_opt} -O ${mkimage_target} --output=${grubdir}/core.img --prefix=${prefix_drive}${relative_grubdir} $modules || exit 1 # Now perform the installation. $grub_setup ${setup_verbose} ${setup_force} --directory=${grubdir} --device-map=${device_map} \ ${install_device} || exit 1 elif [ "${target_cpu}-${platform}" = "mips-yeeloong" ] ; then - $grub_mkimage ${config_opt} -f ${font} -d ${pkglibdir} -O elf --output=/boot/grub.elf --prefix=${prefix_drive}${relative_grubdir} $modules || exit 1 + $grub_mkimage ${config_opt} -f ${font} -d ${pkglibdir} -O ${mkimage_target} --output=/boot/grub.elf --prefix=${prefix_drive}${relative_grubdir} $modules || exit 1 else - $grub_mkimage ${config_opt} -d ${pkglibdir} --output=/boot/multiboot.img --prefix=${prefix_drive}${relative_grubdir} $modules || exit 1 + $grub_mkimage -O ${mkimage_target} ${config_opt} -d ${pkglibdir} --output=/boot/multiboot.img --prefix=${prefix_drive}${relative_grubdir} $modules || exit 1 fi echo "Installation finished. No error reported." diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in index 7d553a767..a5430534a 100644 --- a/util/grub-mkrescue.in +++ b/util/grub-mkrescue.in @@ -160,7 +160,7 @@ EOF tar -C ${memdisk_dir} -cf ${memdisk_img} boot rm -rf ${memdisk_dir} - grub-mkelfimage -d ${coreboot_dir}/ -m ${memdisk_img} -o ${iso9660_dir}/boot/multiboot.img \ + grub-mkimage -O i386-coreboot -d ${coreboot_dir}/ -m ${memdisk_img} -o ${iso9660_dir}/boot/multiboot.img \ memdisk tar search iso9660 configfile sh \ ata at_keyboard rm -f ${memdisk_img} @@ -171,7 +171,7 @@ fi if test -e "${pc_dir}" ; then echo "Enabling BIOS support ..." core_img=`mktemp "$MKTEMP_TEMPLATE"` - grub-mkimage -d ${pc_dir}/ -O i386-pc -o ${core_img} --prefix=/boot/grub/i386-pc \ + grub-mkimage -O i386-pc -d ${pc_dir}/ -O i386-pc -o ${core_img} --prefix=/boot/grub/i386-pc \ iso9660 biosdisk cat ${pc_dir}/cdboot.img ${core_img} > ${iso9660_dir}/boot/grub/i386-pc/eltorito.img diff --git a/util/i386/efi/grub-install.in b/util/i386/efi/grub-install.in index cc4d950d2..9b4270ff6 100644 --- a/util/i386/efi/grub-install.in +++ b/util/i386/efi/grub-install.in @@ -213,7 +213,7 @@ devabstraction_module=`$grub_probe --target=abstraction --device-map=${device_ma # The order in this list is critical. Be careful when modifying it. modules="$modules $fs_module $partmap_module $devabstraction_module" -$grub_mkimage --output=${grubdir}/grub.efi $modules || exit 1 +$grub_mkimage -O ${target_cpu}-efi --output=${grubdir}/grub.efi $modules || exit 1 # Prompt the user to check if the device map is correct. echo "Installation finished. No error reported." diff --git a/util/ieee1275/grub-install.in b/util/ieee1275/grub-install.in index 363f312db..4d00cc217 100644 --- a/util/ieee1275/grub-install.in +++ b/util/ieee1275/grub-install.in @@ -34,7 +34,7 @@ target_cpu=@target_cpu@ platform=@platform@ pkglibdir=${libdir}/`echo ${PACKAGE_TARNAME}/${target_cpu}-${platform} | sed ${transform}` -grub_mkimage=${bindir}/`echo grub-mkelfimage | sed ${transform}` +grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}` grub_mkdevicemap=${sbindir}/`echo grub-mkdevicemap | sed ${transform}` grub_probe=${sbindir}/`echo grub-probe | sed ${transform}` grub_editenv=${bindir}/`echo grub-editenv | sed ${transform}` @@ -189,7 +189,7 @@ devabstraction_module=`$grub_probe --target=abstraction --device-map=${device_ma modules="$modules $fs_module $partmap_module $devabstraction_module" # Now perform the installation. -"$grub_mkimage" --directory=${pkglibdir} --output=${grubdir}/grub $modules || exit 1 +"$grub_mkimage" -O ${target_cpu}-ieee1275 --directory=${pkglibdir} --output=${grubdir}/grub $modules || exit 1 if test $update_nvram = yes; then set $ofpathname dummy diff --git a/util/powerpc/ieee1275/grub-mkrescue.in b/util/powerpc/ieee1275/grub-mkrescue.in index 0110e799c..16658505b 100644 --- a/util/powerpc/ieee1275/grub-mkrescue.in +++ b/util/powerpc/ieee1275/grub-mkrescue.in @@ -30,7 +30,7 @@ target_cpu=@target_cpu@ platform=@platform@ pkglibdir=${libdir}/`echo ${PACKAGE_TARNAME}/${target_cpu}-${platform} | sed ${transform}` -grub_mkimage=${bindir}/`echo grub-mkelfimage | sed ${transform}` +grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}` # Usage: usage # Print the usage. @@ -104,7 +104,7 @@ boot_dir=${iso_dir}/boot/grub mkdir ${iso_dir}/boot mkdir ${boot_dir} core_img=${boot_dir}/grub.img -${grub_mkimage} -n -d ${input_dir}/ -o ${core_img} ${modules} +${grub_mkimage} -O powerpc-ieee1275 -n -d ${input_dir}/ -o ${core_img} ${modules} genisoimage -hfs -part -no-desktop -r -J -o ${output_image} \ -map ${map_file} -hfs-bless ${boot_dir} -chrp-boot -sysid PPC \ ${iso_dir} From 840b61d8f0fc4919fbfdfb0e8495f2c0da81b715 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Tue, 27 Apr 2010 10:50:28 +0530 Subject: [PATCH 609/738] reorganized grub-emu sources to suite upcoming automake build system --- {util => bus/emu}/pci.c | 0 {util => bus/usb/emu}/usb.c | 0 conf/any-emu.rmk | 19 ++- conf/common.rmk | 4 +- include/grub/{util => emu}/console.h | 0 include/grub/{util => emu}/getroot.h | 0 include/grub/{util => emu}/hostdisk.h | 0 include/grub/emu/misc.h | 31 ++++ kern/emu/cache.S | 17 +++ {util => kern/emu}/console.c | 2 +- kern/emu/dummy/dl.c | 51 +++++++ {util => kern/emu}/getroot.c | 10 +- {util => kern/emu}/hostdisk.c | 4 +- {util => kern/emu}/hostfs.c | 0 kern/emu/lite.c | 16 +++ util/grub-emu.c => kern/emu/main.c | 42 +++++- kern/emu/misc.c | 199 ++++++++++++++++++++++++++ {util => kern/emu}/time.c | 0 util/grub-probe.c | 5 +- {util => video/emu}/sdl.c | 0 20 files changed, 378 insertions(+), 22 deletions(-) rename {util => bus/emu}/pci.c (100%) rename {util => bus/usb/emu}/usb.c (100%) rename include/grub/{util => emu}/console.h (100%) rename include/grub/{util => emu}/getroot.h (100%) rename include/grub/{util => emu}/hostdisk.h (100%) create mode 100644 include/grub/emu/misc.h create mode 100644 kern/emu/cache.S rename {util => kern/emu}/console.c (99%) create mode 100644 kern/emu/dummy/dl.c rename {util => kern/emu}/getroot.c (98%) rename {util => kern/emu}/hostdisk.c (99%) rename {util => kern/emu}/hostfs.c (100%) create mode 100644 kern/emu/lite.c rename util/grub-emu.c => kern/emu/main.c (91%) create mode 100644 kern/emu/misc.c rename {util => kern/emu}/time.c (100%) rename {util => video/emu}/sdl.c (100%) diff --git a/util/pci.c b/bus/emu/pci.c similarity index 100% rename from util/pci.c rename to bus/emu/pci.c diff --git a/util/usb.c b/bus/usb/emu/usb.c similarity index 100% rename from util/usb.c rename to bus/usb/emu/usb.c diff --git a/conf/any-emu.rmk b/conf/any-emu.rmk index d1e5754dc..5f6798d79 100644 --- a/conf/any-emu.rmk +++ b/conf/any-emu.rmk @@ -10,11 +10,11 @@ kernel_img_SOURCES = kern/device.c kern/disk.c kern/dl.c kern/env.c \ kern/parser.c kern/partition.c kern/term.c \ kern/rescue_reader.c kern/rescue_parser.c \ \ - util/console.c util/grub-emu.c util/misc.c \ - util/hostdisk.c util/getroot.c util/mm.c util/time.c \ + kern/emu/misc.c kern/emu/getroot.c kern/emu/time.c \ + kern/emu/hostdisk.c kern/emu/hostfs.c kern/emu/console.c \ \ - gnulib/progname.c util/hostfs.c disk/host.c -kernel_img_HEADERS += datetime.h util/misc.h + gnulib/progname.c disk/host.c +kernel_img_HEADERS += datetime.h emu/misc.h kernel_img_CFLAGS = $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) -Wno-undef -I$(srcdir)/gnulib kernel_img_LDFLAGS = $(COMMON_LDFLAGS) TARGET_NO_STRIP = yes @@ -49,7 +49,7 @@ ifeq ($(enable_grub_emu_usb), yes) kernel_img_HEADERS += libusb.h pkglib_MODULES += libusb.mod -libusb_mod_SOURCES = util/usb.c +libusb_mod_SOURCES = bus/usb/emu/usb.c libusb_mod_CFLAGS = libusb_mod_LDFLAGS = $(COMMON_LDFLAGS) @@ -76,7 +76,7 @@ endif ifeq ($(enable_grub_emu_sdl), yes) pkglib_MODULES += sdl.mod -sdl_mod_SOURCES = util/sdl.c +sdl_mod_SOURCES = video/emu/sdl.c sdl_mod_CFLAGS = sdl_mod_LDFLAGS = $(COMMON_LDFLAGS) grub_emu_LDFLAGS += $(LIBSDL) @@ -106,8 +106,13 @@ ifneq ($(TARGET_NO_MODULES), yes) grub-emu: $(pkglib_PROGRAMS) $(CC) -o $@ $(pkglib_PROGRAMS) $(grub_emu_LDFLAGS) $(LDFLAGS) else + +pkglib_MODULES += emu.mod +emu_mod_SOURCES = kern/emu/main.c +emu_mod_CFLAGS = -I$(srcdir)/gnulib + grub-emu: $(pkglib_MODULES) $(pkglib_PROGRAMS) - $(CC) -o $@ $(pkglib_MODULES) $(pkglib_PROGRAMS) $(grub_emu_LDFLAGS) $(LDFLAGS) + $(CC) -o $@ $^ $(grub_emu_LDFLAGS) $(LDFLAGS) endif GRUB_EMU=grub-emu diff --git a/conf/common.rmk b/conf/common.rmk index 8df232a0b..6267d7818 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -25,7 +25,7 @@ util/elf/grub-mkimage.c_DEPENDENCIES = Makefile sbin_UTILITIES += grub-probe util/grub-probe.c_DEPENDENCIES = grub_probe_init.h grub_probe_SOURCES = gnulib/progname.c util/grub-probe.c \ - util/hostdisk.c util/misc.c util/getroot.c util/mm.c \ + kern/emu/hostdisk.c util/misc.c kern/emu/getroot.c util/mm.c \ kern/device.c kern/disk.c kern/err.c kern/misc.c \ kern/parser.c kern/partition.c kern/file.c kern/list.c \ \ @@ -60,7 +60,7 @@ grub_mkisofs_CFLAGS = -D_FILE_OFFSET_BITS=64 \ # For grub-fstest. util/grub-fstest.c_DEPENDENCIES = grub_fstest_init.h -grub_fstest_SOURCES = gnulib/progname.c util/grub-fstest.c util/hostfs.c \ +grub_fstest_SOURCES = gnulib/progname.c util/grub-fstest.c kern/emu/hostfs.c \ util/misc.c util/mm.c \ kern/file.c kern/device.c kern/disk.c kern/err.c kern/misc.c \ disk/host.c disk/loopback.c kern/list.c kern/command.c \ diff --git a/include/grub/util/console.h b/include/grub/emu/console.h similarity index 100% rename from include/grub/util/console.h rename to include/grub/emu/console.h diff --git a/include/grub/util/getroot.h b/include/grub/emu/getroot.h similarity index 100% rename from include/grub/util/getroot.h rename to include/grub/emu/getroot.h diff --git a/include/grub/util/hostdisk.h b/include/grub/emu/hostdisk.h similarity index 100% rename from include/grub/util/hostdisk.h rename to include/grub/emu/hostdisk.h diff --git a/include/grub/emu/misc.h b/include/grub/emu/misc.h new file mode 100644 index 000000000..e62aeba08 --- /dev/null +++ b/include/grub/emu/misc.h @@ -0,0 +1,31 @@ +#ifndef GRUB_EMU_MISC_H +#define GRUB_EMU_MISC_H 1 + +#include +#include + +#ifdef __NetBSD__ +/* NetBSD uses /boot for its boot block. */ +# define DEFAULT_DIRECTORY "/grub" +#else +# define DEFAULT_DIRECTORY "/boot/grub" +#endif + +#define DEFAULT_DEVICE_MAP DEFAULT_DIRECTORY "/device.map" + +extern int verbosity; +extern const char *program_name; + +void grub_init_all (void); +void grub_fini_all (void); + +void * EXPORT_FUNC(xmalloc) (grub_size_t size); +void * EXPORT_FUNC(xrealloc) (void *ptr, grub_size_t size); +char * EXPORT_FUNC(xstrdup) (const char *str); +char * EXPORT_FUNC(xasprintf) (const char *fmt, ...); + +void EXPORT_FUNC(grub_util_warn) (const char *fmt, ...); +void EXPORT_FUNC(grub_util_info) (const char *fmt, ...); +void EXPORT_FUNC(grub_util_error) (const char *fmt, ...) __attribute__ ((noreturn)); + +#endif /* GRUB_EMU_MISC_H */ diff --git a/kern/emu/cache.S b/kern/emu/cache.S new file mode 100644 index 000000000..087b2b495 --- /dev/null +++ b/kern/emu/cache.S @@ -0,0 +1,17 @@ +#ifndef GRUB_MACHINE_EMU +#error "This source is only meant for grub-emu platform" +#endif + +#if GRUB_CPU_I386 +#elif GRUB_CPU_X86_64 +#elif GRUB_CPU_SPARC64 +#include "../sparc64/cache.S" +#elif GRUB_CPU_MIPS +#include "../mips/cache.S" +#elif GRUB_CPU_MIPSEL +#include "../mips/cache.S" +#elif GRUB_CPU_POWERPC +#include "../powerpc/cache.S" +#else +#error "No target cpu type is defined" +#endif diff --git a/util/console.c b/kern/emu/console.c similarity index 99% rename from util/console.c rename to kern/emu/console.c index 382fd7f89..f7fbc899a 100644 --- a/util/console.c +++ b/kern/emu/console.c @@ -27,7 +27,7 @@ # define A_STANDOUT 0 #endif /* ! A_STANDOUT */ -#include +#include #include #include diff --git a/kern/emu/dummy/dl.c b/kern/emu/dummy/dl.c new file mode 100644 index 000000000..8e9fabfc2 --- /dev/null +++ b/kern/emu/dummy/dl.c @@ -0,0 +1,51 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include + +grub_err_t +grub_arch_dl_check_header (void *ehdr) +{ + (void) ehdr; + + return GRUB_ERR_BAD_MODULE; +} + +grub_err_t +grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) +{ + (void) mod; + (void) ehdr; + + return GRUB_ERR_BAD_MODULE; +} + +/* int */ +/* grub_dl_ref (grub_dl_t mod) */ +/* { */ +/* (void) mod; */ +/* return 0; */ +/* } */ + +/* int */ +/* grub_dl_unref (grub_dl_t mod) */ +/* { */ +/* (void) mod; */ +/* return 0; */ +/* } */ diff --git a/util/getroot.c b/kern/emu/getroot.c similarity index 98% rename from util/getroot.c rename to kern/emu/getroot.c index 94eadc5e1..91799aa8f 100644 --- a/util/getroot.c +++ b/kern/emu/getroot.c @@ -22,6 +22,8 @@ #include #include #include +#include +#include #ifdef __CYGWIN__ # include @@ -36,9 +38,11 @@ #include #endif -#include -#include -#include +#include +#include +#include +#include +#include static void strip_extra_slashes (char *dir) diff --git a/util/hostdisk.c b/kern/emu/hostdisk.c similarity index 99% rename from util/hostdisk.c rename to kern/emu/hostdisk.c index 8be487461..983f101ae 100644 --- a/util/hostdisk.c +++ b/kern/emu/hostdisk.c @@ -22,8 +22,8 @@ #include #include #include -#include -#include +#include +#include #include #include #include diff --git a/util/hostfs.c b/kern/emu/hostfs.c similarity index 100% rename from util/hostfs.c rename to kern/emu/hostfs.c diff --git a/kern/emu/lite.c b/kern/emu/lite.c new file mode 100644 index 000000000..1f06e39dc --- /dev/null +++ b/kern/emu/lite.c @@ -0,0 +1,16 @@ +#include +#include + +/* grub-emu-lite supports dynamic module loading, so it won't have any + embedded modules. */ +void +grub_init_all(void) +{ + return; +} + +void +grub_fini_all(void) +{ + return; +} diff --git a/util/grub-emu.c b/kern/emu/main.c similarity index 91% rename from util/grub-emu.c rename to kern/emu/main.c index 8660f0aa0..978919f2a 100644 --- a/util/grub-emu.c +++ b/kern/emu/main.c @@ -16,7 +16,10 @@ * along with GRUB. If not, see . */ +#include +#include #include +#include #include #include #include @@ -27,13 +30,13 @@ #include #include #include -#include -#include -#include -#include +#include +#include +#include +#include #include #include -#include +#include #include #include #include @@ -261,3 +264,32 @@ main (int argc, char *argv[]) return 0; } + +#ifdef __MINGW32__ + +void +grub_millisleep (grub_uint32_t ms) +{ + Sleep (ms); +} + +#else + +void +grub_millisleep (grub_uint32_t ms) +{ + struct timespec ts; + + ts.tv_sec = ms / 1000; + ts.tv_nsec = (ms % 1000) * 1000000; + nanosleep (&ts, NULL); +} + +#endif + +#if GRUB_NO_MODULES +void +grub_register_exported_symbols (void) +{ +} +#endif diff --git a/kern/emu/misc.c b/kern/emu/misc.c new file mode 100644 index 000000000..d8dfc938d --- /dev/null +++ b/kern/emu/misc.c @@ -0,0 +1,199 @@ +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +int verbosity; + +void +grub_util_warn (const char *fmt, ...) +{ + va_list ap; + + fprintf (stderr, _("%s: warn:"), program_name); + fprintf (stderr, " "); + va_start (ap, fmt); + vfprintf (stderr, fmt, ap); + va_end (ap); + fprintf (stderr, ".\n"); + fflush (stderr); +} + +void +grub_util_info (const char *fmt, ...) +{ + if (verbosity > 0) + { + va_list ap; + + fprintf (stderr, _("%s: info:"), program_name); + fprintf (stderr, " "); + va_start (ap, fmt); + vfprintf (stderr, fmt, ap); + va_end (ap); + fprintf (stderr, ".\n"); + fflush (stderr); + } +} + +void +grub_util_error (const char *fmt, ...) +{ + va_list ap; + + fprintf (stderr, _("%s: error:"), program_name); + fprintf (stderr, " "); + va_start (ap, fmt); + vfprintf (stderr, fmt, ap); + va_end (ap); + fprintf (stderr, ".\n"); + exit (1); +} + +void * +grub_malloc (grub_size_t size) +{ + return malloc (size); +} + +void * +grub_zalloc (grub_size_t size) +{ + void *ret; + + ret = malloc (size); + memset (ret, 0, size); + return ret; +} + +void +grub_free (void *ptr) +{ + free (ptr); +} + +void * +grub_realloc (void *ptr, grub_size_t size) +{ + return realloc (ptr, size); +} + +void * +grub_memalign (grub_size_t align, grub_size_t size) +{ + void *p; + +#if defined(HAVE_POSIX_MEMALIGN) + if (align < sizeof (void *)) + align = sizeof (void *); + + else if (align % sizeof (void *)) + grub_fatal ("bad alignment"); + + if (posix_memalign (&p, align, size) != 0) + p = 0; +#elif defined(HAVE_MEMALIGN) + p = memalign (align, size); +#else + (void) align; + (void) size; + grub_fatal ("grub_memalign is not supported"); +#endif + + if (! p) + grub_fatal ("out of memory"); + + return p; +} + +void * +xmalloc (grub_size_t size) +{ + void *p; + + p = grub_malloc (size); + if (! p) + grub_fatal ("out of memory"); + + return p; +} + +void * +xrealloc (void *ptr, grub_size_t size) +{ + ptr = grub_realloc (ptr, size); + if (! ptr) + grub_fatal ("out of memory"); + + return ptr; +} + +char * +xstrdup (const char *str) +{ + size_t len; + char *newstr; + + len = grub_strlen (str); + newstr = (char *) xmalloc (len + 1); + grub_memcpy (newstr, str, len + 1); + + return newstr; +} + +char * +xasprintf (const char *fmt, ...) +{ + va_list ap; + char *result; + + va_start (ap, fmt); + if (vasprintf (&result, fmt, ap) < 0) + { + if (errno == ENOMEM) + grub_util_error ("out of memory"); + return NULL; + } + + return result; +} + +void +grub_exit (void) +{ + exit (1); +} + +grub_uint64_t +grub_get_time_ms (void) +{ + struct timeval tv; + + gettimeofday (&tv, 0); + + return (tv.tv_sec * 1000 + tv.tv_usec / 1000); +} + +grub_uint32_t +grub_get_rtc (void) +{ + struct timeval tv; + + gettimeofday (&tv, 0); + + return (tv.tv_sec * GRUB_TICKS_PER_SECOND + + (((tv.tv_sec % GRUB_TICKS_PER_SECOND) * 1000000 + tv.tv_usec) + * GRUB_TICKS_PER_SECOND / 1000000)); +} diff --git a/util/time.c b/kern/emu/time.c similarity index 100% rename from util/time.c rename to kern/emu/time.c diff --git a/util/grub-probe.c b/util/grub-probe.c index bb41480e2..1b2606dc7 100644 --- a/util/grub-probe.c +++ b/util/grub-probe.c @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -26,8 +27,8 @@ #include #include #include -#include -#include +#include +#include #include #include #include diff --git a/util/sdl.c b/video/emu/sdl.c similarity index 100% rename from util/sdl.c rename to video/emu/sdl.c From 4c7085f82be6f018c895b9fd871ff8eed1d94be3 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Tue, 27 Apr 2010 13:57:14 +0530 Subject: [PATCH 610/738] added support for --enable-grub-emu-modules build --- conf/any-emu.rmk | 18 +++++++--------- include/grub/dl.h | 15 ------------- kern/dl.c | 8 +++++-- kern/emu/cache.S | 17 --------------- kern/emu/dummy/dl.c | 51 --------------------------------------------- kern/emu/lite.c | 16 -------------- kern/emu/main.c | 1 + util/misc.c | 14 +++++++++++++ 8 files changed, 28 insertions(+), 112 deletions(-) delete mode 100644 kern/emu/cache.S delete mode 100644 kern/emu/dummy/dl.c delete mode 100644 kern/emu/lite.c diff --git a/conf/any-emu.rmk b/conf/any-emu.rmk index 5f6798d79..ffaabcd2f 100644 --- a/conf/any-emu.rmk +++ b/conf/any-emu.rmk @@ -9,10 +9,11 @@ kernel_img_SOURCES = kern/device.c kern/disk.c kern/dl.c kern/env.c \ kern/corecmd.c kern/file.c kern/fs.c kern/main.c kern/misc.c \ kern/parser.c kern/partition.c kern/term.c \ kern/rescue_reader.c kern/rescue_parser.c \ - \ - kern/emu/misc.c kern/emu/getroot.c kern/emu/time.c \ - kern/emu/hostdisk.c kern/emu/hostfs.c kern/emu/console.c \ - \ + \ + kern/emu/main.c kern/emu/misc.c kern/emu/getroot.c \ + kern/emu/time.c kern/emu/hostdisk.c kern/emu/hostfs.c \ + kern/emu/console.c \ + \ gnulib/progname.c disk/host.c kernel_img_HEADERS += datetime.h emu/misc.h kernel_img_CFLAGS = $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) -Wno-undef -I$(srcdir)/gnulib @@ -85,7 +86,7 @@ endif ifeq ($(enable_grub_emu_pci), yes) pkglib_MODULES += pci.mod -pci_mod_SOURCES = util/pci.c commands/lspci.c +pci_mod_SOURCES = bus/emu/pci.c commands/lspci.c pci_mod_LDFLAGS = $(COMMON_LDFLAGS) grub_emu_LDFLAGS += $(LIBPCIACCESS) kernel_img_HEADERS += libpciaccess.h @@ -104,13 +105,8 @@ DISTCLEANFILES += grub_emu_init.c CLEANFILES += grub-emu ifneq ($(TARGET_NO_MODULES), yes) grub-emu: $(pkglib_PROGRAMS) - $(CC) -o $@ $(pkglib_PROGRAMS) $(grub_emu_LDFLAGS) $(LDFLAGS) + $(CC) -o $@ $^ $(grub_emu_LDFLAGS) $(LDFLAGS) else - -pkglib_MODULES += emu.mod -emu_mod_SOURCES = kern/emu/main.c -emu_mod_CFLAGS = -I$(srcdir)/gnulib - grub-emu: $(pkglib_MODULES) $(pkglib_PROGRAMS) $(CC) -o $@ $^ $(grub_emu_LDFLAGS) $(LDFLAGS) endif diff --git a/include/grub/dl.h b/include/grub/dl.h index cfb7c2f99..cf5da7fd5 100644 --- a/include/grub/dl.h +++ b/include/grub/dl.h @@ -96,23 +96,8 @@ void grub_dl_unload_all (void); #else #define GRUB_NO_MODULES 0 #endif -#if GRUB_NO_MODULES -static inline int -grub_dl_ref (grub_dl_t mod) -{ - (void) mod; - return 0; -} -static inline int -grub_dl_unref (grub_dl_t mod) -{ - (void) mod; - return 0; -} -#else int EXPORT_FUNC(grub_dl_ref) (grub_dl_t mod); int EXPORT_FUNC(grub_dl_unref) (grub_dl_t mod); -#endif void EXPORT_FUNC(grub_dl_iterate) (int (*hook) (grub_dl_t mod)); grub_dl_t EXPORT_FUNC(grub_dl_get) (const char *name); grub_err_t grub_dl_register_symbol (const char *name, void *addr, diff --git a/kern/dl.c b/kern/dl.c index 19ee13243..c6a038cfa 100644 --- a/kern/dl.c +++ b/kern/dl.c @@ -469,12 +469,14 @@ grub_dl_resolve_dependencies (grub_dl_t mod, Elf_Ehdr *e) return GRUB_ERR_NONE; } -#if !GRUB_NO_MODULES int grub_dl_ref (grub_dl_t mod) { grub_dl_dep_t dep; + if (!mod) + return 0; + for (dep = mod->dep; dep; dep = dep->next) grub_dl_ref (dep->mod); @@ -486,12 +488,14 @@ grub_dl_unref (grub_dl_t mod) { grub_dl_dep_t dep; + if (!mod) + return 0; + for (dep = mod->dep; dep; dep = dep->next) grub_dl_unref (dep->mod); return --mod->ref_count; } -#endif static void grub_dl_flush_cache (grub_dl_t mod) diff --git a/kern/emu/cache.S b/kern/emu/cache.S deleted file mode 100644 index 087b2b495..000000000 --- a/kern/emu/cache.S +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef GRUB_MACHINE_EMU -#error "This source is only meant for grub-emu platform" -#endif - -#if GRUB_CPU_I386 -#elif GRUB_CPU_X86_64 -#elif GRUB_CPU_SPARC64 -#include "../sparc64/cache.S" -#elif GRUB_CPU_MIPS -#include "../mips/cache.S" -#elif GRUB_CPU_MIPSEL -#include "../mips/cache.S" -#elif GRUB_CPU_POWERPC -#include "../powerpc/cache.S" -#else -#error "No target cpu type is defined" -#endif diff --git a/kern/emu/dummy/dl.c b/kern/emu/dummy/dl.c deleted file mode 100644 index 8e9fabfc2..000000000 --- a/kern/emu/dummy/dl.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2010 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include - -grub_err_t -grub_arch_dl_check_header (void *ehdr) -{ - (void) ehdr; - - return GRUB_ERR_BAD_MODULE; -} - -grub_err_t -grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) -{ - (void) mod; - (void) ehdr; - - return GRUB_ERR_BAD_MODULE; -} - -/* int */ -/* grub_dl_ref (grub_dl_t mod) */ -/* { */ -/* (void) mod; */ -/* return 0; */ -/* } */ - -/* int */ -/* grub_dl_unref (grub_dl_t mod) */ -/* { */ -/* (void) mod; */ -/* return 0; */ -/* } */ diff --git a/kern/emu/lite.c b/kern/emu/lite.c deleted file mode 100644 index 1f06e39dc..000000000 --- a/kern/emu/lite.c +++ /dev/null @@ -1,16 +0,0 @@ -#include -#include - -/* grub-emu-lite supports dynamic module loading, so it won't have any - embedded modules. */ -void -grub_init_all(void) -{ - return; -} - -void -grub_fini_all(void) -{ - return; -} diff --git a/kern/emu/main.c b/kern/emu/main.c index 978919f2a..c9b1d6595 100644 --- a/kern/emu/main.c +++ b/kern/emu/main.c @@ -27,6 +27,7 @@ #include #include +#include #include #include #include diff --git a/util/misc.c b/util/misc.c index 17fa6d5e4..c413352e7 100644 --- a/util/misc.c +++ b/util/misc.c @@ -564,3 +564,17 @@ grub_util_init_nls (void) #endif /* (defined(ENABLE_NLS) && ENABLE_NLS) */ } #endif + +int +grub_dl_ref (grub_dl_t mod) +{ + (void) mod; + return 0; +} + +int +grub_dl_unref (grub_dl_t mod) +{ + (void) mod; + return 0; +} From 13ac43057bcac4644bc50e572c804c7e04470a49 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 27 Apr 2010 11:08:53 +0200 Subject: [PATCH 611/738] use uuids on efi --- kern/efi/init.c | 76 +++++++++++++++++++++++++++---------------- util/grub-mkrescue.in | 24 +++++++++++--- 2 files changed, 67 insertions(+), 33 deletions(-) diff --git a/kern/efi/init.c b/kern/efi/init.c index afd21055d..b79084a6a 100644 --- a/kern/efi/init.c +++ b/kern/efi/init.c @@ -24,6 +24,7 @@ #include #include #include +#include void grub_efi_init (void) @@ -41,39 +42,58 @@ grub_efi_init (void) void grub_efi_set_prefix (void) { - grub_efi_loaded_image_t *image; + grub_efi_loaded_image_t *image = NULL; + char *device = NULL; + char *path = NULL; - image = grub_efi_get_loaded_image (grub_efi_image_handle); - if (image) + { + char *pptr = NULL; + if (grub_prefix[0] == '(') + { + pptr = grub_strrchr (grub_prefix, ')'); + if (pptr) + { + device = grub_strndup (grub_prefix + 1, pptr - grub_prefix - 1); + pptr++; + } + } + if (!pptr) + pptr = grub_prefix; + if (pptr[0]) + path = grub_strdup (pptr); + } + + if (!device || !path) + image = grub_efi_get_loaded_image (grub_efi_image_handle); + if (image && !device) + device = grub_efidisk_get_device_name (image->device_handle); + + if (image && !path) { - char *device; - char *file; + char *p; - device = grub_efidisk_get_device_name (image->device_handle); - file = grub_efi_get_filename (image->file_path); + path = grub_efi_get_filename (image->file_path); - if (device && file) - { - char *p; - char *prefix; - - /* Get the directory. */ - p = grub_strrchr (file, '/'); - if (p) - *p = '\0'; - - prefix = grub_xasprintf ("(%s)%s", device, file); - if (prefix) - { - - grub_env_set ("prefix", prefix); - grub_free (prefix); - } - } - - grub_free (device); - grub_free (file); + /* Get the directory. */ + p = grub_strrchr (path, '/'); + if (p) + *p = '\0'; } + + if (device && path) + { + char *prefix; + + prefix = grub_xasprintf ("(%s)%s", device, path); + if (prefix) + { + grub_env_set ("prefix", prefix); + grub_free (prefix); + } + } + + grub_free (device); + grub_free (path); } void diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in index cf791d108..0265f9b81 100644 --- a/util/grub-mkrescue.in +++ b/util/grub-mkrescue.in @@ -150,14 +150,16 @@ else esac fi +# obtain date-based UUID +iso_uuid=$(date -u +%Y-%m-%d-%H-%M-%S-00) +grub_mkisofs_arguments="${grub_mkisofs_arguments} --modification-date=$(echo ${iso_uuid} | sed -e s/-//g)" + # build coreboot core.img if test -e "${coreboot_dir}" ; then echo "Enabling coreboot support ..." memdisk_img=`mktemp "$MKTEMP_TEMPLATE"` memdisk_dir=`mktemp -d "$MKTEMP_TEMPLATE"` mkdir -p ${memdisk_dir}/boot/grub - # obtain date-based UUID - iso_uuid=$(date -u +%Y-%m-%d-%H-%M-%S-00) modules="$(cat ${coreboot_dir}/partmap.lst) ${modules}" cat << EOF > ${memdisk_dir}/boot/grub/grub.cfg @@ -176,7 +178,6 @@ EOF memdisk tar search iso9660 configfile sh \ ata at_keyboard rm -f ${memdisk_img} - grub_mkisofs_arguments="${grub_mkisofs_arguments} --modification-date=$(echo ${iso_uuid} | sed -e s/-//g)" fi # build BIOS core.img @@ -213,8 +214,21 @@ fi # build bootx64.efi if test -e "${efi64_dir}" ; then echo "Enabling EFI64 support ..." - grub-mkimage -O x86_64-efi -d "${efi64_dir}" -o "${efi_dir}"/efi/boot/bootx64.efi --prefix=/boot/grub/x86_64-efi \ - search iso9660 configfile sh + memdisk_img=`mktemp "$MKTEMP_TEMPLATE"` + memdisk_dir=`mktemp -d "$MKTEMP_TEMPLATE"` + mkdir -p ${memdisk_dir}/boot/grub + + cat << EOF > ${memdisk_dir}/boot/grub/grub.cfg +search --fs-uuid --set ${iso_uuid} +set prefix=(\${root})/boot/grub/${target_cpu}-efi +EOF + + tar -C ${memdisk_dir} -cf ${memdisk_img} boot + rm -rf ${memdisk_dir} + + grub-mkimage -O x86_64-efi -d "${efi64_dir}" -m "${memdisk_img}" -o "${efi_dir}"/efi/boot/bootx64.efi --prefix='(memdisk)/boot/grub' \ + search iso9660 configfile sh memdisk tar + rm -f ${memdisk_img} modules="$(cat "${efi64_dir}"/partmap.lst) ${modules}" (for i in ${modules} ; do From ff6bea78b442acb7e2304d9ae7c78a94237422e2 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 27 Apr 2010 13:22:38 +0200 Subject: [PATCH 612/738] Enable pathspecs --- util/grub-mkrescue.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in index 0265f9b81..9b319ac27 100644 --- a/util/grub-mkrescue.in +++ b/util/grub-mkrescue.in @@ -245,7 +245,7 @@ if test x"${efi_dir}" != x; then fi # build iso image -xorrisofs ${grub_mkisofs_arguments} --protective-msdos-label -o ${output_image} -r ${iso9660_dir} ${source} +xorriso -pathspecs on -as mkisofs ${grub_mkisofs_arguments} --protective-msdos-label -o ${output_image} -r ${iso9660_dir} ${source} rm -rf ${iso9660_dir} rm -f ${embed_img} From 613b1b2c586be4b77e0e4f536e800c8213e4a8fc Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 27 Apr 2010 13:44:39 +0200 Subject: [PATCH 613/738] Include /grub.cfg --- util/grub-mkrescue.in | 2 ++ 1 file changed, 2 insertions(+) diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in index 9b319ac27..4f151ac98 100644 --- a/util/grub-mkrescue.in +++ b/util/grub-mkrescue.in @@ -165,6 +165,7 @@ if test -e "${coreboot_dir}" ; then cat << EOF > ${memdisk_dir}/boot/grub/grub.cfg search --fs-uuid --set ${iso_uuid} set prefix=(\${root})/boot/grub/${target_cpu}-coreboot +source $prefix/grub.cfg EOF (for i in ${modules} ; do echo "insmod $i" @@ -221,6 +222,7 @@ if test -e "${efi64_dir}" ; then cat << EOF > ${memdisk_dir}/boot/grub/grub.cfg search --fs-uuid --set ${iso_uuid} set prefix=(\${root})/boot/grub/${target_cpu}-efi +source $prefix/grub.cfg EOF tar -C ${memdisk_dir} -cf ${memdisk_img} boot From f07ccea799dc9ebc632a44313ad2e94ea55f9efb Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Tue, 27 Apr 2010 20:55:12 +0530 Subject: [PATCH 614/738] removed some duplicate code --- conf/any-emu.rmk | 6 +- conf/common.rmk | 23 +++--- disk/lvm.c | 2 +- include/grub/emu/misc.h | 10 +++ include/grub/util/misc.h | 35 +-------- kern/emu/misc.c | 98 +++++++++--------------- {util => kern/emu}/mm.c | 5 -- util/grub-mkrelpath.c | 1 + util/grub-probe.c | 2 +- util/misc.c | 157 --------------------------------------- 10 files changed, 64 insertions(+), 275 deletions(-) rename {util => kern/emu}/mm.c (92%) diff --git a/conf/any-emu.rmk b/conf/any-emu.rmk index ffaabcd2f..cb0ec873f 100644 --- a/conf/any-emu.rmk +++ b/conf/any-emu.rmk @@ -10,9 +10,9 @@ kernel_img_SOURCES = kern/device.c kern/disk.c kern/dl.c kern/env.c \ kern/parser.c kern/partition.c kern/term.c \ kern/rescue_reader.c kern/rescue_parser.c \ \ - kern/emu/main.c kern/emu/misc.c kern/emu/getroot.c \ - kern/emu/time.c kern/emu/hostdisk.c kern/emu/hostfs.c \ - kern/emu/console.c \ + kern/emu/main.c kern/emu/mm.c kern/emu/misc.c \ + kern/emu/getroot.c kern/emu/time.c kern/emu/hostdisk.c \ + kern/emu/hostfs.c kern/emu/console.c \ \ gnulib/progname.c disk/host.c kernel_img_HEADERS += datetime.h emu/misc.h diff --git a/conf/common.rmk b/conf/common.rmk index 6267d7818..a08e0d3c0 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -6,7 +6,7 @@ script/lexer.c_DEPENDENCIES = grub_script.tab.h sbin_UTILITIES += grub-mkdevicemap grub_mkdevicemap_SOURCES = gnulib/progname.c util/grub-mkdevicemap.c \ util/deviceiter.c \ - util/misc.c + util/misc.c kern/emu/misc.c ifeq ($(target_cpu)-$(platform), sparc64-ieee1275) grub_mkdevicemap_SOURCES += util/ieee1275/ofpath.c util/ieee1275/devicemap.c @@ -16,16 +16,15 @@ endif # For grub-mkelfimage. bin_UTILITIES += grub-mkelfimage -grub_mkelfimage_SOURCES = gnulib/progname.c \ - util/elf/grub-mkimage.c util/misc.c \ - util/resolve.c +grub_mkelfimage_SOURCES = gnulib/progname.c util/elf/grub-mkimage.c \ + util/misc.c kern/emu/misc.c util/resolve.c util/elf/grub-mkimage.c_DEPENDENCIES = Makefile # For grub-probe. sbin_UTILITIES += grub-probe util/grub-probe.c_DEPENDENCIES = grub_probe_init.h grub_probe_SOURCES = gnulib/progname.c util/grub-probe.c \ - kern/emu/hostdisk.c util/misc.c kern/emu/getroot.c util/mm.c \ + kern/emu/hostdisk.c util/misc.c kern/emu/misc.c kern/emu/getroot.c kern/emu/mm.c \ kern/device.c kern/disk.c kern/err.c kern/misc.c \ kern/parser.c kern/partition.c kern/file.c kern/list.c \ \ @@ -61,7 +60,7 @@ grub_mkisofs_CFLAGS = -D_FILE_OFFSET_BITS=64 \ # For grub-fstest. util/grub-fstest.c_DEPENDENCIES = grub_fstest_init.h grub_fstest_SOURCES = gnulib/progname.c util/grub-fstest.c kern/emu/hostfs.c \ - util/misc.c util/mm.c \ + util/misc.c kern/emu/misc.c kern/emu/mm.c \ kern/file.c kern/device.c kern/disk.c kern/err.c kern/misc.c \ disk/host.c disk/loopback.c kern/list.c kern/command.c \ lib/arg.c commands/extcmd.c normal/datetime.c normal/misc.c \ @@ -83,14 +82,14 @@ grub_fstest_SOURCES = gnulib/progname.c util/grub-fstest.c kern/emu/hostfs.c \ # For grub-mkfont. ifeq ($(enable_grub_mkfont), yes) bin_UTILITIES += grub-mkfont -grub_mkfont_SOURCES = gnulib/progname.c util/grub-mkfont.c util/misc.c +grub_mkfont_SOURCES = gnulib/progname.c util/grub-mkfont.c util/misc.c kern/emu/misc.c grub_mkfont_CFLAGS = $(freetype_cflags) grub_mkfont_LDFLAGS = $(freetype_libs) endif # For grub-mkrelpath. bin_UTILITIES += grub-mkrelpath -grub_mkrelpath_SOURCES = gnulib/progname.c util/grub-mkrelpath.c util/misc.c +grub_mkrelpath_SOURCES = gnulib/progname.c util/grub-mkrelpath.c util/misc.c kern/emu/misc.c bin_UTILITIES += grub-bin2h grub_bin2h_SOURCES = gnulib/progname.c util/bin2h.c @@ -104,7 +103,7 @@ DISTCLEANFILES += grub_script.yy.c grub_script.yy.h bin_UTILITIES += grub-script-check util/grub-script-check.c_DEPENDENCIES = grub_script_check_init.h grub_script_check_SOURCES = gnulib/progname.c gnulib/getdelim.c gnulib/getline.c \ - util/grub-script-check.c util/misc.c util/mm.c \ + util/grub-script-check.c util/misc.c kern/emu/misc.c kern/emu/mm.c \ script/main.c script/script.c script/function.c script/lexer.c \ kern/handler.c kern/err.c kern/parser.c kern/list.c \ kern/misc.c kern/env.c grub_script_check_init.c grub_script.tab.c \ @@ -187,7 +186,7 @@ DISTCLEANFILES += grub_fstest_init.c # for grub-editenv bin_UTILITIES += grub-editenv -grub_editenv_SOURCES = gnulib/progname.c util/grub-editenv.c lib/envblk.c util/misc.c util/mm.c kern/misc.c kern/err.c +grub_editenv_SOURCES = gnulib/progname.c util/grub-editenv.c lib/envblk.c util/misc.c kern/emu/misc.c kern/emu/mm.c kern/misc.c kern/err.c CLEANFILES += grub-editenv # Needed for genmk.rb to work @@ -195,7 +194,7 @@ ifeq (0,1) bin_UTILITIES += grub-macho2img grub-pe2elf endif -grub_pe2elf_SOURCES = gnulib/progname.c util/grub-pe2elf.c util/misc.c +grub_pe2elf_SOURCES = gnulib/progname.c util/grub-pe2elf.c util/misc.c kern/emu/misc.c CLEANFILES += grub-pe2elf grub_macho2img_SOURCES = util/grub-macho2img.c @@ -855,7 +854,7 @@ boot_mod_CFLAGS = $(COMMON_CFLAGS) boot_mod_LDFLAGS = $(COMMON_LDFLAGS) bin_UTILITIES += grub-mkpasswd-pbkdf2 -grub_mkpasswd_pbkdf2_SOURCES = gnulib/progname.c gnulib/getdelim.c gnulib/getline.c util/grub-mkpasswd-pbkdf2.c lib/crypto.c lib/libgcrypt-grub/cipher/sha512.c lib/pbkdf2.c util/misc.c util/mm.c kern/err.c +grub_mkpasswd_pbkdf2_SOURCES = gnulib/progname.c gnulib/getdelim.c gnulib/getline.c util/grub-mkpasswd-pbkdf2.c lib/crypto.c lib/libgcrypt-grub/cipher/sha512.c lib/pbkdf2.c util/misc.c kern/emu/misc.c kern/emu/mm.c kern/err.c grub_mkpasswd_pbkdf2_CFLAGS += -Wno-missing-field-initializers -Wno-error -I$(srcdir)/lib/libgcrypt_wrap -DGRUB_MKPASSWD=1 include $(srcdir)/conf/gcry.mk diff --git a/disk/lvm.c b/disk/lvm.c index c2ae82df2..7dde40920 100644 --- a/disk/lvm.c +++ b/disk/lvm.c @@ -25,7 +25,7 @@ #include #ifdef GRUB_UTIL -#include +#include #endif static struct grub_lvm_vg *vg_list; diff --git a/include/grub/emu/misc.h b/include/grub/emu/misc.h index e62aeba08..4e4df2ad2 100644 --- a/include/grub/emu/misc.h +++ b/include/grub/emu/misc.h @@ -28,4 +28,14 @@ void EXPORT_FUNC(grub_util_warn) (const char *fmt, ...); void EXPORT_FUNC(grub_util_info) (const char *fmt, ...); void EXPORT_FUNC(grub_util_error) (const char *fmt, ...) __attribute__ ((noreturn)); +#ifndef HAVE_VASPRINTF +int EXPORT_FUNC(vasprintf) (char **buf, const char *fmt, va_list ap); +#endif + +#ifndef HAVE_ASPRINTF +int EXPORT_FUNC(asprintf) (char **buf, const char *fmt, ...); +#endif + +char * EXPORT_FUNC(xasprintf) (const char *fmt, ...); + #endif /* GRUB_EMU_MISC_H */ diff --git a/include/grub/util/misc.h b/include/grub/util/misc.h index 8b78b92ea..48dfbb868 100644 --- a/include/grub/util/misc.h +++ b/include/grub/util/misc.h @@ -28,26 +28,7 @@ #include #include #include - -#ifdef __NetBSD__ -/* NetBSD uses /boot for its boot block. */ -# define DEFAULT_DIRECTORY "/grub" -#else -# define DEFAULT_DIRECTORY "/boot/grub" -#endif - -#define DEFAULT_DEVICE_MAP DEFAULT_DIRECTORY "/device.map" - -extern char *progname; -extern int verbosity; - -void EXPORT_FUNC(grub_util_warn) (const char *fmt, ...); -void EXPORT_FUNC(grub_util_info) (const char *fmt, ...); -void EXPORT_FUNC(grub_util_error) (const char *fmt, ...) __attribute__ ((noreturn)); - -void *xmalloc (size_t size); -void *xrealloc (void *ptr, size_t size); -char *xstrdup (const char *str); +#include char *grub_util_get_path (const char *dir, const char *file); size_t grub_util_get_fp_size (FILE *fp); @@ -59,20 +40,6 @@ void grub_util_write_image (const char *img, size_t size, FILE *out); void grub_util_write_image_at (const void *img, size_t size, off_t offset, FILE *out); -#ifndef HAVE_VASPRINTF - -int vasprintf (char **buf, const char *fmt, va_list ap); - -#endif - -#ifndef HAVE_ASPRINTF - -int asprintf (char **buf, const char *fmt, ...); - -#endif - -char *xasprintf (const char *fmt, ...); - #ifdef __MINGW32__ #define fseeko fseeko64 diff --git a/kern/emu/misc.c b/kern/emu/misc.c index d8dfc938d..999cdf257 100644 --- a/kern/emu/misc.c +++ b/kern/emu/misc.c @@ -62,70 +62,14 @@ grub_util_error (const char *fmt, ...) exit (1); } -void * -grub_malloc (grub_size_t size) -{ - return malloc (size); -} - -void * -grub_zalloc (grub_size_t size) -{ - void *ret; - - ret = malloc (size); - memset (ret, 0, size); - return ret; -} - -void -grub_free (void *ptr) -{ - free (ptr); -} - -void * -grub_realloc (void *ptr, grub_size_t size) -{ - return realloc (ptr, size); -} - -void * -grub_memalign (grub_size_t align, grub_size_t size) -{ - void *p; - -#if defined(HAVE_POSIX_MEMALIGN) - if (align < sizeof (void *)) - align = sizeof (void *); - - else if (align % sizeof (void *)) - grub_fatal ("bad alignment"); - - if (posix_memalign (&p, align, size) != 0) - p = 0; -#elif defined(HAVE_MEMALIGN) - p = memalign (align, size); -#else - (void) align; - (void) size; - grub_fatal ("grub_memalign is not supported"); -#endif - - if (! p) - grub_fatal ("out of memory"); - - return p; -} - void * xmalloc (grub_size_t size) { void *p; - p = grub_malloc (size); + p = malloc (size); if (! p) - grub_fatal ("out of memory"); + grub_util_error ("out of memory"); return p; } @@ -133,9 +77,9 @@ xmalloc (grub_size_t size) void * xrealloc (void *ptr, grub_size_t size) { - ptr = grub_realloc (ptr, size); + ptr = realloc (ptr, size); if (! ptr) - grub_fatal ("out of memory"); + grub_util_error ("out of memory"); return ptr; } @@ -146,13 +90,43 @@ xstrdup (const char *str) size_t len; char *newstr; - len = grub_strlen (str); + len = strlen (str); newstr = (char *) xmalloc (len + 1); - grub_memcpy (newstr, str, len + 1); + memcpy (newstr, str, len + 1); return newstr; } +#ifndef HAVE_VASPRINTF + +int +vasprintf (char **buf, const char *fmt, va_list ap) +{ + /* Should be large enough. */ + *buf = xmalloc (512); + + return vsprintf (*buf, fmt, ap); +} + +#endif + +#ifndef HAVE_ASPRINTF + +int +asprintf (char **buf, const char *fmt, ...) +{ + int status; + va_list ap; + + va_start (ap, fmt); + status = vasprintf (*buf, fmt, ap); + va_end (ap); + + return status; +} + +#endif + char * xasprintf (const char *fmt, ...) { diff --git a/util/mm.c b/kern/emu/mm.c similarity index 92% rename from util/mm.c rename to kern/emu/mm.c index 0e9e9f3a8..803c1c9aa 100644 --- a/util/mm.c +++ b/kern/emu/mm.c @@ -55,8 +55,6 @@ grub_realloc (void *ptr, grub_size_t size) { void *ret; ret = realloc (ptr, size); - if (!ret) - grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory"); return ret; } @@ -78,8 +76,5 @@ grub_memalign (grub_size_t align, grub_size_t size) grub_util_error ("grub_memalign is not supported"); #endif - if (!p) - grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory"); - return p; } diff --git a/util/grub-mkrelpath.c b/util/grub-mkrelpath.c index 327f0c866..c26fa7b67 100644 --- a/util/grub-mkrelpath.c +++ b/util/grub-mkrelpath.c @@ -17,6 +17,7 @@ * along with GRUB. If not, see . */ +#include #include #include #include diff --git a/util/grub-probe.c b/util/grub-probe.c index 1b2606dc7..add942fb4 100644 --- a/util/grub-probe.c +++ b/util/grub-probe.c @@ -19,7 +19,7 @@ #include #include -#include +#include #include #include #include diff --git a/util/misc.c b/util/misc.c index c413352e7..d26e51bbf 100644 --- a/util/misc.c +++ b/util/misc.c @@ -58,53 +58,6 @@ #include #endif -int verbosity = 0; - -void -grub_util_warn (const char *fmt, ...) -{ - va_list ap; - - fprintf (stderr, _("%s: warn:"), program_name); - fprintf (stderr, " "); - va_start (ap, fmt); - vfprintf (stderr, fmt, ap); - va_end (ap); - fprintf (stderr, ".\n"); - fflush (stderr); -} - -void -grub_util_info (const char *fmt, ...) -{ - if (verbosity > 0) - { - va_list ap; - - fprintf (stderr, _("%s: info:"), program_name); - fprintf (stderr, " "); - va_start (ap, fmt); - vfprintf (stderr, fmt, ap); - va_end (ap); - fprintf (stderr, ".\n"); - fflush (stderr); - } -} - -void -grub_util_error (const char *fmt, ...) -{ - va_list ap; - - fprintf (stderr, _("%s: error:"), program_name); - fprintf (stderr, " "); - va_start (ap, fmt); - vfprintf (stderr, fmt, ap); - va_end (ap); - fprintf (stderr, ".\n"); - exit (1); -} - #ifdef GRUB_UTIL int grub_err_printf (const char *fmt, ...) @@ -120,41 +73,6 @@ grub_err_printf (const char *fmt, ...) } #endif -void * -xmalloc (size_t size) -{ - void *p; - - p = malloc (size); - if (! p) - grub_util_error ("out of memory"); - - return p; -} - -void * -xrealloc (void *ptr, size_t size) -{ - ptr = realloc (ptr, size); - if (! ptr) - grub_util_error ("out of memory"); - - return ptr; -} - -char * -xstrdup (const char *str) -{ - size_t len; - char *newstr; - - len = strlen (str); - newstr = (char *) xmalloc (len + 1); - memcpy (newstr, str, len + 1); - - return newstr; -} - char * grub_util_get_path (const char *dir, const char *file) { @@ -277,34 +195,6 @@ grub_register_exported_symbols (void) } #endif -void -grub_exit (void) -{ - exit (1); -} - -grub_uint32_t -grub_get_rtc (void) -{ - struct timeval tv; - - gettimeofday (&tv, 0); - - return (tv.tv_sec * GRUB_TICKS_PER_SECOND - + (((tv.tv_sec % GRUB_TICKS_PER_SECOND) * 1000000 + tv.tv_usec) - * GRUB_TICKS_PER_SECOND / 1000000)); -} - -grub_uint64_t -grub_get_time_ms (void) -{ - struct timeval tv; - - gettimeofday (&tv, 0); - - return (tv.tv_sec * 1000 + tv.tv_usec / 1000); -} - #ifdef __MINGW32__ void @@ -335,53 +225,6 @@ grub_arch_sync_caches (void *address __attribute__ ((unused)), } #endif -#ifndef HAVE_VASPRINTF - -int -vasprintf (char **buf, const char *fmt, va_list ap) -{ - /* Should be large enough. */ - *buf = xmalloc (512); - - return vsprintf (*buf, fmt, ap); -} - -#endif - -#ifndef HAVE_ASPRINTF - -int -asprintf (char **buf, const char *fmt, ...) -{ - int status; - va_list ap; - - va_start (ap, fmt); - status = vasprintf (*buf, fmt, ap); - va_end (ap); - - return status; -} - -#endif - -char * -xasprintf (const char *fmt, ...) -{ - va_list ap; - char *result; - - va_start (ap, fmt); - if (vasprintf (&result, fmt, ap) < 0) - { - if (errno == ENOMEM) - grub_util_error ("out of memory"); - return NULL; - } - - return result; -} - #ifdef __MINGW32__ void sync (void) From b84cac2a36828b701a3f8125b8f9e4f9a2db0dc0 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Tue, 27 Apr 2010 20:59:45 +0530 Subject: [PATCH 615/738] undo some hunks that were removed by mistake --- kern/emu/mm.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/kern/emu/mm.c b/kern/emu/mm.c index 803c1c9aa..0e9e9f3a8 100644 --- a/kern/emu/mm.c +++ b/kern/emu/mm.c @@ -55,6 +55,8 @@ grub_realloc (void *ptr, grub_size_t size) { void *ret; ret = realloc (ptr, size); + if (!ret) + grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory"); return ret; } @@ -76,5 +78,8 @@ grub_memalign (grub_size_t align, grub_size_t size) grub_util_error ("grub_memalign is not supported"); #endif + if (!p) + grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory"); + return p; } From 54f83682d4c7e4fc519a837fdb9750f519f79a7b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 27 Apr 2010 21:43:16 +0200 Subject: [PATCH 616/738] Add missing escape --- util/grub-mkrescue.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in index 4f151ac98..2ef9aa8bd 100644 --- a/util/grub-mkrescue.in +++ b/util/grub-mkrescue.in @@ -165,7 +165,7 @@ if test -e "${coreboot_dir}" ; then cat << EOF > ${memdisk_dir}/boot/grub/grub.cfg search --fs-uuid --set ${iso_uuid} set prefix=(\${root})/boot/grub/${target_cpu}-coreboot -source $prefix/grub.cfg +source \$prefix/grub.cfg EOF (for i in ${modules} ; do echo "insmod $i" @@ -222,7 +222,7 @@ if test -e "${efi64_dir}" ; then cat << EOF > ${memdisk_dir}/boot/grub/grub.cfg search --fs-uuid --set ${iso_uuid} set prefix=(\${root})/boot/grub/${target_cpu}-efi -source $prefix/grub.cfg +source \$prefix/grub.cfg EOF tar -C ${memdisk_dir} -cf ${memdisk_img} boot From cc9d24254fd1d71a7bfc6e30981cfbd7cf860272 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 27 Apr 2010 22:08:24 +0200 Subject: [PATCH 617/738] * conf/x86-efi.rmk (linux_mod_SOURCES): Write explicitly to avoid autogen issues. --- ChangeLog | 5 +++++ conf/x86-efi.rmk | 10 +++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 29e634bf6..725eb297d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-04-27 Vladimir Serbinenko + + * conf/x86-efi.rmk (linux_mod_SOURCES): Write explicitly to avoid + autogen issues. + 2010-04-26 Christian Franke * include/grub/util/getroot.h (grub_get_prefix): Remove prototype. diff --git a/conf/x86-efi.rmk b/conf/x86-efi.rmk index 46957d933..e29dad645 100644 --- a/conf/x86-efi.rmk +++ b/conf/x86-efi.rmk @@ -64,13 +64,17 @@ appleldr_mod_CFLAGS = $(COMMON_CFLAGS) appleldr_mod_LDFLAGS = $(COMMON_LDFLAGS) # For linux.mod. -linux_mod_SOURCES = loader/i386/efi/linux.c ifeq ($(target_cpu), x86_64) -linux_mod_SOURCES += loader/i386/linux_trampoline.S -endif +linux_mod_SOURCES = loader/i386/efi/linux.c loader/i386/linux_trampoline.S linux_mod_CFLAGS = $(COMMON_CFLAGS) linux_mod_ASFLAGS = $(COMMON_ASFLAGS) linux_mod_LDFLAGS = $(COMMON_LDFLAGS) +else +linux_mod_SOURCES = loader/i386/efi/linux.c +linux_mod_CFLAGS = $(COMMON_CFLAGS) +linux_mod_ASFLAGS = $(COMMON_ASFLAGS) +linux_mod_LDFLAGS = $(COMMON_LDFLAGS) +endif # For halt.mod. halt_mod_SOURCES = commands/halt.c From bb06ba0892dd4d9d2bf838b437e1d2253141c484 Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Wed, 28 Apr 2010 22:59:27 +0200 Subject: [PATCH 618/738] * docs/grub.texi (play): Document that zero pitches produce rests. --- ChangeLog | 4 ++++ docs/grub.texi | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 725eb297d..c06df52d5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-04-28 Samuel Thibault + + * docs/grub.texi (play): Document that zero pitches produce rests. + 2010-04-27 Vladimir Serbinenko * conf/x86-efi.rmk (linux_mod_SOURCES): Write explicitly to avoid diff --git a/docs/grub.texi b/docs/grub.texi index f8a9bc414..704f8b2a3 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -1379,7 +1379,8 @@ pitch and duration pairs. If the arguments are a series of numbers, play the inline tune. The tempo is the base for all note durations. 60 gives a 1-second base, 120 -gives a half-second base, etc. Pitches are Hz. +gives a half-second base, etc. Pitches are Hz. Set pitch to 0 to produce +a rest. @end deffn From c76a18386f45b0bc1dc8ef4d69f1210a4bde60c7 Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Wed, 28 Apr 2010 23:18:16 +0200 Subject: [PATCH 619/738] * commands/i386/pc/play.c (grub_cmd_play): Call 'grub_file_open' only if argc is 1. --- ChangeLog | 2 ++ commands/i386/pc/play.c | 10 +++++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index c06df52d5..4c8f2b2f8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,8 @@ 2010-04-28 Samuel Thibault * docs/grub.texi (play): Document that zero pitches produce rests. + * commands/i386/pc/play.c (grub_cmd_play): Call 'grub_file_open' only + if argc is 1. 2010-04-27 Vladimir Serbinenko diff --git a/commands/i386/pc/play.c b/commands/i386/pc/play.c index 44d98a1f0..4ed937d4a 100644 --- a/commands/i386/pc/play.c +++ b/commands/i386/pc/play.c @@ -177,16 +177,20 @@ static grub_err_t grub_cmd_play (grub_command_t cmd __attribute__ ((unused)), int argc, char **args) { - grub_file_t file; if (argc < 1) return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name or tempo and notes required"); - file = grub_file_open (args[0]); - if (file) + if (argc == 1) { struct note buf; grub_uint32_t tempo; + grub_file_t file; + + file = grub_file_open (args[0]); + + if (! file) + return grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found"); if (grub_file_read (file, &tempo, sizeof (tempo)) != sizeof (tempo)) { From 6fdda85ae6a255458808d4e4042eb51d55eb1380 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Fri, 30 Apr 2010 13:50:41 +0530 Subject: [PATCH 620/738] fix comment and brace handling --- conf/tests.rmk | 4 ++++ script/yylex.l | 4 ++-- tests/grub_script_comments.in | 19 +++++++++++++++++++ 3 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 tests/grub_script_comments.in diff --git a/conf/tests.rmk b/conf/tests.rmk index d48bc3dd9..9af2f8f86 100644 --- a/conf/tests.rmk +++ b/conf/tests.rmk @@ -68,6 +68,9 @@ grub_script_final_semicolon_SOURCES = tests/grub_script_final_semicolon.in check_SCRIPTS += grub_script_dollar grub_script_dollar_SOURCES = tests/grub_script_dollar.in +check_SCRIPTS += grub_script_comments +grub_script_comments_SOURCES = tests/grub_script_comments.in + # List of tests to execute on "make check" # SCRIPTED_TESTS = example_scripted_test # SCRIPTED_TESTS += example_grub_script_test @@ -83,6 +86,7 @@ SCRIPTED_TESTS += grub_script_if SCRIPTED_TESTS += grub_script_blanklines SCRIPTED_TESTS += grub_script_final_semicolon SCRIPTED_TESTS += grub_script_dollar +SCRIPTED_TESTS += grub_script_comments # dependencies between tests and testing-tools $(SCRIPTED_TESTS): grub-shell grub-shell-tester diff --git a/script/yylex.l b/script/yylex.l index 29aa5c2e3..7d4ea9e4e 100644 --- a/script/yylex.l +++ b/script/yylex.l @@ -112,9 +112,9 @@ typedef size_t yy_size_t; %option extra-type="struct grub_parser_param*" BLANK [ \t] -COMMENT ^[ \t]*#.*$ +COMMENT #.*$ -CHAR [^|&$;<> \t\n\'\"\\] +CHAR [^{}|&$;<> \t\n\'\"\\] DIGITS [[:digit:]]+ NAME [[:alpha:]_][[:alnum:][:digit:]_]* diff --git a/tests/grub_script_comments.in b/tests/grub_script_comments.in new file mode 100644 index 000000000..7b3410717 --- /dev/null +++ b/tests/grub_script_comments.in @@ -0,0 +1,19 @@ +#! @builddir@/grub-shell-tester +# +# Copyright (C) 2010 Free Software Foundation, Inc. +# +# GRUB is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# GRUB is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GRUB. If not, see . + +echo a###b +echo a# #b From c548018b7c9e7a61310bcf551238b63df847a76b Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Sat, 1 May 2010 15:39:59 +0530 Subject: [PATCH 621/738] added few more test cases --- tests/grub_script_comments.in | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/grub_script_comments.in b/tests/grub_script_comments.in index 7b3410717..f212cc1e1 100644 --- a/tests/grub_script_comments.in +++ b/tests/grub_script_comments.in @@ -17,3 +17,12 @@ echo a###b echo a# #b + +echo # +echo \# + +echo '#' +echo "#" + +echo '\#' +echo "\#" From 6f8aaf68beb7b6de3ce3d5f39fbab75ffb9bb78d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 1 May 2010 13:20:07 +0200 Subject: [PATCH 622/738] Merge handling of input and output terminals. Fix a hang. * commands/terminal.c (abstract_terminal): New struct. (handle_command): New function. Based on grub_cmd_terminal_input. (grub_cmd_terminal_input): Use handle_command. (grub_cmd_terminal_output): Use handle_command. --- ChangeLog | 9 + commands/terminal.c | 396 +++++++++++++++----------------------------- 2 files changed, 146 insertions(+), 259 deletions(-) diff --git a/ChangeLog b/ChangeLog index 572fade35..530ecf32a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2010-05-01 Vladimir Serbinenko + + MErge handling of input and output terminals. Fix a hang. + + * commands/terminal.c (abstract_terminal): New struct. + (handle_command): New function. Based on grub_cmd_terminal_input. + (grub_cmd_terminal_input): Use handle_command. + (grub_cmd_terminal_output): Use handle_command. + 2010-05-01 BVK Chaitanya Fix comment handling. diff --git a/commands/terminal.c b/commands/terminal.c index e725123b8..c8c1ffe09 100644 --- a/commands/terminal.c +++ b/commands/terminal.c @@ -26,37 +26,48 @@ struct grub_term_autoload *grub_term_input_autoload = NULL; struct grub_term_autoload *grub_term_output_autoload = NULL; +struct abstract_terminal +{ + struct abstract_terminal *next; + const char *name; + grub_err_t (*init) (void); + grub_err_t (*fini) (void); +}; + static grub_err_t -grub_cmd_terminal_input (grub_command_t cmd __attribute__ ((unused)), - int argc, char **args) +handle_command (int argc, char **args, struct abstract_terminal **enabled, + struct abstract_terminal **disabled, + struct grub_term_autoload *autoloads, + const char *active_str, + const char *available_str) { int i; - grub_term_input_t term; + struct abstract_terminal *term; struct grub_term_autoload *aut; if (argc == 0) { - grub_puts_ (N_ ("Active input terminals:")); - FOR_ACTIVE_TERM_INPUTS(term) - grub_printf ("%s ", term->name); + grub_puts_ (active_str); + for (term = *enabled; term; term = term->next) + grub_printf ("%s ", term->name); grub_printf ("\n"); - grub_puts_ (N_ ("Available input terminals:")); - FOR_DISABLED_TERM_INPUTS(term) - grub_printf ("%s ", term->name); + grub_puts_ (available_str); + for (term = *disabled; term; term = term->next) + grub_printf ("%s ", term->name); /* This is quadratic but we don't expect mode than 30 terminal - modules ever. */ - for (aut = grub_term_input_autoload; aut; aut = aut->next) - { - FOR_DISABLED_TERM_INPUTS(term) - if (grub_strcmp (term->name, aut->name) == 0) - break; - if (!term) - FOR_ACTIVE_TERM_INPUTS(term) - if (grub_strcmp (term->name, aut->name) == 0) - break; - if (!term) - grub_printf ("%s ", aut->name); - } + modules ever. */ + for (aut = autoloads; aut; aut = aut->next) + { + for (term = *disabled; term; term = term->next) + if (grub_strcmp (term->name, aut->name) == 0) + break; + if (!term) + for (term = *enabled; term; term = term->next) + if (grub_strcmp (term->name, aut->name) == 0) + break; + if (!term) + grub_printf ("%s ", aut->name); + } grub_printf ("\n"); return GRUB_ERR_NONE; } @@ -73,112 +84,108 @@ grub_cmd_terminal_input (grub_command_t cmd __attribute__ ((unused)), { int again = 0; while (1) - { - FOR_DISABLED_TERM_INPUTS(term) - if (grub_strcmp (args[i], term->name) == 0) - break; - if (term == 0) - FOR_ACTIVE_TERM_INPUTS(term) - if (grub_strcmp (args[i], term->name) == 0) - break; - if (term) - break; - if (again) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminal '%s'\n", - args[i]); - for (aut = grub_term_input_autoload; aut; aut = aut->next) - if (grub_strcmp (args[i], aut->name) == 0) - { - grub_dl_t mod; - mod = grub_dl_load (aut->modname); - if (mod) - grub_dl_ref (mod); - grub_errno = GRUB_ERR_NONE; - break; - } - if (!aut) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminal '%s'\n", - args[i]); - again = 1; - } + { + for (term = *disabled; term; term = term->next) + if (grub_strcmp (args[i], term->name) == 0) + break; + if (term == 0) + for (term = *enabled; term; term = term->next) + if (grub_strcmp (args[i], term->name) == 0) + break; + if (term) + break; + if (again) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminal '%s'\n", + args[i]); + for (aut = autoloads; aut; aut = aut->next) + if (grub_strcmp (args[i], aut->name) == 0) + { + grub_dl_t mod; + mod = grub_dl_load (aut->modname); + if (mod) + grub_dl_ref (mod); + grub_errno = GRUB_ERR_NONE; + break; + } + if (!aut) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminal '%s'\n", + args[i]); + again = 1; + } } if (grub_strcmp (args[0], "--append") == 0) { for (i = 1; i < argc; i++) - { - FOR_DISABLED_TERM_INPUTS(term) - if (grub_strcmp (args[i], term->name) == 0) - break; - if (term) - { + { + for (term = *disabled; term; term = term->next) + if (grub_strcmp (args[i], term->name) == 0) + break; + if (term) + { if (term->init && term->init () != GRUB_ERR_NONE) return grub_errno; - grub_list_remove (GRUB_AS_LIST_P (&(grub_term_inputs_disabled)), - GRUB_AS_LIST (term)); - grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs), - GRUB_AS_LIST (term)); - } - } + grub_list_remove (GRUB_AS_LIST_P (disabled), GRUB_AS_LIST (term)); + grub_list_push (GRUB_AS_LIST_P (enabled), GRUB_AS_LIST (term)); + } + } return GRUB_ERR_NONE; } if (grub_strcmp (args[0], "--remove") == 0) { for (i = 1; i < argc; i++) - { - FOR_ACTIVE_TERM_INPUTS(term) - if (grub_strcmp (args[i], term->name) == 0) - break; - if (term) - { - if (!term->next && term == grub_term_inputs) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - "can't remove the last terminal"); - grub_list_remove (GRUB_AS_LIST_P (&(grub_term_inputs)), - GRUB_AS_LIST (term)); - if (term->fini) - term->fini (); - grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs_disabled), - GRUB_AS_LIST (term)); - } - } + { + for (term = *enabled; term; term = term->next) + if (grub_strcmp (args[i], term->name) == 0) + break; + if (term) + { + if (!term->next && term == *enabled) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "can't remove the last terminal"); + grub_list_remove (GRUB_AS_LIST_P (enabled), GRUB_AS_LIST (term)); + if (term->fini) + term->fini (); + grub_list_push (GRUB_AS_LIST_P (disabled), GRUB_AS_LIST (term)); + } + } return GRUB_ERR_NONE; } for (i = 0; i < argc; i++) { - FOR_DISABLED_TERM_INPUTS(term) - if (grub_strcmp (args[i], term->name) == 0) - break; + for (term = *disabled; term; term = term->next) + if (grub_strcmp (args[i], term->name) == 0) + break; if (term) - { - if (term->init && term->init () != GRUB_ERR_NONE) - return grub_errno; + { + if (term->init && term->init () != GRUB_ERR_NONE) + return grub_errno; - grub_list_remove (GRUB_AS_LIST_P (&(grub_term_inputs_disabled)), - GRUB_AS_LIST (term)); - grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs), - GRUB_AS_LIST (term)); - } + grub_list_remove (GRUB_AS_LIST_P (disabled), GRUB_AS_LIST (term)); + grub_list_push (GRUB_AS_LIST_P (enabled), GRUB_AS_LIST (term)); + } } - - FOR_ACTIVE_TERM_INPUTS(term) + { - for (i = 0; i < argc; i++) - if (grub_strcmp (args[i], term->name) == 0) - break; - if (i == argc) + struct abstract_terminal *next; + for (term = *enabled; term; term = next) { - if (!term->next && term == grub_term_inputs) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - "can't remove the last terminal"); - grub_list_remove (GRUB_AS_LIST_P (&(grub_term_inputs)), - GRUB_AS_LIST (term)); - if (term->fini) - term->fini (); - grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs_disabled), - GRUB_AS_LIST (term)); + next = term->next; + for (i = 0; i < argc; i++) + if (grub_strcmp (args[i], term->name) == 0) + break; + if (i == argc) + { + if (!term->next && term == *enabled) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "can't remove the last terminal"); + grub_list_remove (GRUB_AS_LIST_P (enabled), GRUB_AS_LIST (term)); + if (term->fini) + term->fini (); + grub_list_push (GRUB_AS_LIST_P (disabled), GRUB_AS_LIST (term)); + } } } @@ -186,163 +193,34 @@ grub_cmd_terminal_input (grub_command_t cmd __attribute__ ((unused)), } static grub_err_t -grub_cmd_terminal_output (grub_command_t cmd __attribute__ ((unused)), +grub_cmd_terminal_input (grub_command_t cmd __attribute__ ((unused)), int argc, char **args) { - int i; - grub_term_output_t term; - struct grub_term_autoload *aut; + (void) GRUB_FIELD_MATCH (grub_term_inputs, struct abstract_terminal *, next); + (void) GRUB_FIELD_MATCH (grub_term_inputs, struct abstract_terminal *, name); + (void) GRUB_FIELD_MATCH (grub_term_inputs, struct abstract_terminal *, init); + (void) GRUB_FIELD_MATCH (grub_term_inputs, struct abstract_terminal *, fini); + return handle_command (argc, args, + (struct abstract_terminal **) &grub_term_inputs, + (struct abstract_terminal **) &grub_term_inputs_disabled, + grub_term_input_autoload, + N_ ("Active input terminals:"), + N_ ("Available input terminals:")); +} - if (argc == 0) - { - grub_puts_ (N_ ("Active output terminals:")); - FOR_ACTIVE_TERM_OUTPUTS(term) - grub_printf ("%s ", term->name); - grub_printf ("\n"); - grub_puts_ (N_ ("Available output terminals:")); - FOR_DISABLED_TERM_OUTPUTS(term) - grub_printf ("%s ", term->name); - /* This is quadratic but we don't expect mode than 30 terminal - modules ever. */ - for (aut = grub_term_output_autoload; aut; aut = aut->next) - { - FOR_DISABLED_TERM_OUTPUTS(term) - if (grub_strcmp (term->name, aut->name) == 0) - break; - if (!term) - FOR_ACTIVE_TERM_OUTPUTS(term) - if (grub_strcmp (term->name, aut->name) == 0) - break; - if (!term) - grub_printf ("%s ", aut->name); - } - grub_printf ("\n"); - return GRUB_ERR_NONE; - } - i = 0; - - if (grub_strcmp (args[0], "--append") == 0 - || grub_strcmp (args[0], "--remove") == 0) - i++; - - if (i == argc) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_ ("no terminal specified")); - - for (; i < argc; i++) - { - int again = 0; - while (1) - { - FOR_DISABLED_TERM_OUTPUTS(term) - if (grub_strcmp (args[i], term->name) == 0) - break; - if (term == 0) - FOR_ACTIVE_TERM_OUTPUTS(term) - if (grub_strcmp (args[i], term->name) == 0) - break; - if (term) - break; - if (again) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminal '%s'\n", - args[i]); - for (aut = grub_term_output_autoload; aut; aut = aut->next) - if (grub_strcmp (args[i], aut->name) == 0) - { - grub_dl_t mod; - mod = grub_dl_load (aut->modname); - if (mod) - grub_dl_ref (mod); - grub_errno = GRUB_ERR_NONE; - break; - } - if (!aut) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminal '%s'\n", - args[i]); - again = 1; - } - } - - if (grub_strcmp (args[0], "--append") == 0) - { - for (i = 1; i < argc; i++) - { - FOR_DISABLED_TERM_OUTPUTS(term) - if (grub_strcmp (args[i], term->name) == 0) - break; - if (term) - { - if (term->init && term->init () != GRUB_ERR_NONE) - return grub_errno; - - grub_list_remove (GRUB_AS_LIST_P (&(grub_term_outputs_disabled)), - GRUB_AS_LIST (term)); - grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs), - GRUB_AS_LIST (term)); - } - } - return GRUB_ERR_NONE; - } - - if (grub_strcmp (args[0], "--remove") == 0) - { - for (i = 1; i < argc; i++) - { - FOR_ACTIVE_TERM_OUTPUTS(term) - if (grub_strcmp (args[i], term->name) == 0) - break; - if (term) - { - if (!term->next && term == grub_term_outputs) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - "can't remove the last terminal"); - grub_list_remove (GRUB_AS_LIST_P (&(grub_term_outputs)), - GRUB_AS_LIST (term)); - if (term->fini) - term->fini (); - grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs_disabled), - GRUB_AS_LIST (term)); - } - } - return GRUB_ERR_NONE; - } - - for (i = 0; i < argc; i++) - { - FOR_DISABLED_TERM_OUTPUTS(term) - if (grub_strcmp (args[i], term->name) == 0) - break; - if (term) - { - if (term->init && term->init () != GRUB_ERR_NONE) - return grub_errno; - - grub_list_remove (GRUB_AS_LIST_P (&(grub_term_outputs_disabled)), - GRUB_AS_LIST (term)); - grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs), - GRUB_AS_LIST (term)); - } - } - - FOR_ACTIVE_TERM_OUTPUTS(term) - { - for (i = 0; i < argc; i++) - if (grub_strcmp (args[i], term->name) == 0) - break; - if (i == argc) - { - if (!term->next && term == grub_term_outputs) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - "can't remove the last terminal"); - grub_list_remove (GRUB_AS_LIST_P (&(grub_term_outputs)), - GRUB_AS_LIST (term)); - if (term->fini) - term->fini (); - grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs_disabled), - GRUB_AS_LIST (term)); - } - } - - return GRUB_ERR_NONE; +static grub_err_t +grub_cmd_terminal_output (grub_command_t cmd __attribute__ ((unused)), + int argc, char **args) +{ + (void) GRUB_FIELD_MATCH (grub_term_outputs, struct abstract_terminal *, next); + (void) GRUB_FIELD_MATCH (grub_term_outputs, struct abstract_terminal *, name); + (void) GRUB_FIELD_MATCH (grub_term_outputs, struct abstract_terminal *, init); + (void) GRUB_FIELD_MATCH (grub_term_outputs, struct abstract_terminal *, fini); + return handle_command (argc, args, (struct abstract_terminal **) &grub_term_outputs, + (struct abstract_terminal **) &grub_term_outputs_disabled, + grub_term_output_autoload, + N_ ("Active output terminals:"), + N_ ("Available output terminals:")); } static grub_command_t cmd_terminal_input, cmd_terminal_output; From 3080f7a7bdbcf8713e2ffb1ce7916a7ba48293ba Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 1 May 2010 13:27:13 +0200 Subject: [PATCH 623/738] * kern/parser.c (grub_parser_execute): Cope with read-only config. --- ChangeLog | 6 +++++- kern/parser.c | 7 +++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 530ecf32a..1b53d24f5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,10 @@ 2010-05-01 Vladimir Serbinenko - MErge handling of input and output terminals. Fix a hang. + * kern/parser.c (grub_parser_execute): Cope with read-only config. + +2010-05-01 Vladimir Serbinenko + + Merge handling of input and output terminals. Fix a hang. * commands/terminal.c (abstract_terminal): New struct. (handle_command): New function. Based on grub_cmd_terminal_input. diff --git a/kern/parser.c b/kern/parser.c index 80312b9b4..07597a1a8 100644 --- a/kern/parser.c +++ b/kern/parser.c @@ -249,12 +249,11 @@ grub_parser_execute (char *source) } p = grub_strchr (source, '\n'); - if (p) - *p = 0; - *line = grub_strdup (source); if (p) - *p = '\n'; + *line = grub_strndup (source, p - source); + else + *line = grub_strdup (source); source = p ? p + 1 : 0; return 0; } From 7210dca9426f0540b9a49e006cab59ea1e145c29 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 1 May 2010 14:06:53 +0200 Subject: [PATCH 624/738] Split coreboot and multiboot ports. * conf/i386-multiboot.rmk: New file. * configure.ac: Add multiboot port. * include/grub/i386/multiboot/boot.h: New file. * include/grub/i386/multiboot/console.h: Likewise. * include/grub/i386/multiboot/init.h: Likewise. * include/grub/i386/multiboot/kernel.h: Likewise. * include/grub/i386/multiboot/loader.h: Likewise. * include/grub/i386/multiboot/memory.h: Likewise. * include/grub/i386/multiboot/serial.h: Likewise. * include/grub/i386/multiboot/time.h: Likewise. * include/grub/multiboot.h: Add GRUB_MACHINE_MULTIBOOT to ifdef. * loader/multiboot.c: Likewise. * loader/multiboot_mbi2.c: Likewise. * util/grub-mkrescue.in: Generate multiboot rescue. --- ChangeLog | 19 +++++++ conf/i386-multiboot.rmk | 74 +++++++++++++++++++++++++++ configure.ac | 2 + include/grub/i386/multiboot/boot.h | 1 + include/grub/i386/multiboot/console.h | 1 + include/grub/i386/multiboot/init.h | 1 + include/grub/i386/multiboot/kernel.h | 1 + include/grub/i386/multiboot/loader.h | 1 + include/grub/i386/multiboot/memory.h | 1 + include/grub/i386/multiboot/serial.h | 1 + include/grub/i386/multiboot/time.h | 1 + include/grub/multiboot.h | 2 +- loader/multiboot.c | 2 +- loader/multiboot_mbi2.c | 2 +- util/grub-mkrescue.in | 24 ++++----- 15 files changed, 118 insertions(+), 15 deletions(-) create mode 100644 conf/i386-multiboot.rmk create mode 100644 include/grub/i386/multiboot/boot.h create mode 100644 include/grub/i386/multiboot/console.h create mode 100644 include/grub/i386/multiboot/init.h create mode 100644 include/grub/i386/multiboot/kernel.h create mode 100644 include/grub/i386/multiboot/loader.h create mode 100644 include/grub/i386/multiboot/memory.h create mode 100644 include/grub/i386/multiboot/serial.h create mode 100644 include/grub/i386/multiboot/time.h diff --git a/ChangeLog b/ChangeLog index 1b53d24f5..43f223113 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +2010-05-01 Vladimir Serbinenko + + Split coreboot and multiboot ports. + + * conf/i386-multiboot.rmk: New file. + * configure.ac: Add multiboot port. + * include/grub/i386/multiboot/boot.h: New file. + * include/grub/i386/multiboot/console.h: Likewise. + * include/grub/i386/multiboot/init.h: Likewise. + * include/grub/i386/multiboot/kernel.h: Likewise. + * include/grub/i386/multiboot/loader.h: Likewise. + * include/grub/i386/multiboot/memory.h: Likewise. + * include/grub/i386/multiboot/serial.h: Likewise. + * include/grub/i386/multiboot/time.h: Likewise. + * include/grub/multiboot.h: Add GRUB_MACHINE_MULTIBOOT to ifdef. + * loader/multiboot.c: Likewise. + * loader/multiboot_mbi2.c: Likewise. + * util/grub-mkrescue.in: Generate multiboot rescue. + 2010-05-01 Vladimir Serbinenko * kern/parser.c (grub_parser_execute): Cope with read-only config. diff --git a/conf/i386-multiboot.rmk b/conf/i386-multiboot.rmk new file mode 100644 index 000000000..69b8e9a48 --- /dev/null +++ b/conf/i386-multiboot.rmk @@ -0,0 +1,74 @@ +# -*- makefile -*- + +COMMON_CFLAGS = -mrtd -mregparm=3 + +# Images. + +GRUB_KERNEL_MACHINE_LINK_ADDR = 0x8200 + +pkglib_PROGRAMS += kernel.img +kernel_img_SOURCES = kern/i386/coreboot/startup.S \ + kern/i386/misc.S \ + kern/i386/coreboot/init.c \ + kern/i386/multiboot_mmap.c \ + kern/i386/halt.c \ + kern/main.c kern/device.c \ + kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \ + kern/misc.c kern/mm.c kern/term.c \ + kern/rescue_parser.c kern/rescue_reader.c \ + kern/time.c kern/list.c kern/handler.c kern/command.c kern/corecmd.c \ + kern/$(target_cpu)/dl.c kern/parser.c kern/partition.c \ + kern/i386/tsc.c kern/i386/pit.c \ + kern/generic/rtc_get_time_ms.c \ + kern/generic/millisleep.c \ + kern/env.c \ + term/i386/pc/vga_text.c term/i386/vga_common.c \ + symlist.c +kernel_img_CFLAGS = $(COMMON_CFLAGS) +kernel_img_ASFLAGS = $(COMMON_ASFLAGS) +kernel_img_LDFLAGS += $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,$(GRUB_KERNEL_MACHINE_LINK_ADDR),-Bstatic + +sbin_SCRIPTS += grub-install +grub_install_SOURCES = util/grub-install.in + +bin_SCRIPTS += grub-mkrescue +grub_mkrescue_SOURCES = util/grub-mkrescue.in + +# Modules. +pkglib_MODULES = linux.mod aout.mod halt.mod datetime.mod mmap.mod + +# For mmap.mod. +mmap_mod_SOURCES = mmap/mmap.c mmap/i386/uppermem.c mmap/i386/mmap.c +mmap_mod_CFLAGS = $(COMMON_CFLAGS) +mmap_mod_LDFLAGS = $(COMMON_LDFLAGS) +mmap_mod_ASFLAGS = $(COMMON_ASFLAGS) + +# For linux.mod. +linux_mod_SOURCES = loader/i386/linux.c +linux_mod_CFLAGS = $(COMMON_CFLAGS) +linux_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For halt.mod. +halt_mod_SOURCES = commands/halt.c +halt_mod_CFLAGS = $(COMMON_CFLAGS) +halt_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For aout.mod. +aout_mod_SOURCES = loader/aout.c +aout_mod_CFLAGS = $(COMMON_CFLAGS) +aout_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For bsd.mod +pkglib_MODULES += bsd.mod +bsd_mod_SOURCES = loader/i386/bsd.c loader/i386/bsd32.c loader/i386/bsd64.c loader/i386/bsd_helper.S loader/i386/bsd_trampoline.S +bsd_mod_CFLAGS = $(COMMON_CFLAGS) +bsd_mod_LDFLAGS = $(COMMON_LDFLAGS) +bsd_mod_ASFLAGS = $(COMMON_ASFLAGS) + +# For datetime.mod +datetime_mod_SOURCES = lib/cmos_datetime.c +datetime_mod_CFLAGS = $(COMMON_CFLAGS) +datetime_mod_LDFLAGS = $(COMMON_LDFLAGS) + +include $(srcdir)/conf/i386.mk +include $(srcdir)/conf/common.mk diff --git a/configure.ac b/configure.ac index 4bfc5a2b0..4e1dd41d8 100644 --- a/configure.ac +++ b/configure.ac @@ -102,6 +102,7 @@ case "$target_cpu"-"$platform" in i386-efi) ;; x86_64-efi) ;; i386-pc) ;; + i386-multiboot) ;; i386-coreboot) ;; i386-linuxbios) platform=coreboot ;; i386-ieee1275) ;; @@ -136,6 +137,7 @@ esac case "$platform" in coreboot) machine_CFLAGS="-DGRUB_MACHINE_COREBOOT=1" ;; + multiboot) machine_CFLAGS="-DGRUB_MACHINE_MULTIBOOT=1" ;; efi) machine_CFLAGS="-DGRUB_MACHINE_EFI=1" ;; ieee1275) machine_CFLAGS="-DGRUB_MACHINE_IEEE1275=1" ;; qemu) machine_CFLAGS="-DGRUB_MACHINE_QEMU=1" ;; diff --git a/include/grub/i386/multiboot/boot.h b/include/grub/i386/multiboot/boot.h new file mode 100644 index 000000000..c33f9bac0 --- /dev/null +++ b/include/grub/i386/multiboot/boot.h @@ -0,0 +1 @@ +#include diff --git a/include/grub/i386/multiboot/console.h b/include/grub/i386/multiboot/console.h new file mode 100644 index 000000000..774399a4e --- /dev/null +++ b/include/grub/i386/multiboot/console.h @@ -0,0 +1 @@ +#include diff --git a/include/grub/i386/multiboot/init.h b/include/grub/i386/multiboot/init.h new file mode 100644 index 000000000..fd935c3a2 --- /dev/null +++ b/include/grub/i386/multiboot/init.h @@ -0,0 +1 @@ +#include diff --git a/include/grub/i386/multiboot/kernel.h b/include/grub/i386/multiboot/kernel.h new file mode 100644 index 000000000..b41e86ebb --- /dev/null +++ b/include/grub/i386/multiboot/kernel.h @@ -0,0 +1 @@ +#include diff --git a/include/grub/i386/multiboot/loader.h b/include/grub/i386/multiboot/loader.h new file mode 100644 index 000000000..1c725be19 --- /dev/null +++ b/include/grub/i386/multiboot/loader.h @@ -0,0 +1 @@ +#include diff --git a/include/grub/i386/multiboot/memory.h b/include/grub/i386/multiboot/memory.h new file mode 100644 index 000000000..8dd6f7c8c --- /dev/null +++ b/include/grub/i386/multiboot/memory.h @@ -0,0 +1 @@ +#include diff --git a/include/grub/i386/multiboot/serial.h b/include/grub/i386/multiboot/serial.h new file mode 100644 index 000000000..2d8563414 --- /dev/null +++ b/include/grub/i386/multiboot/serial.h @@ -0,0 +1 @@ +#include diff --git a/include/grub/i386/multiboot/time.h b/include/grub/i386/multiboot/time.h new file mode 100644 index 000000000..7177c7488 --- /dev/null +++ b/include/grub/i386/multiboot/time.h @@ -0,0 +1 @@ +#include diff --git a/include/grub/multiboot.h b/include/grub/multiboot.h index 49d71fa09..63947d1bc 100644 --- a/include/grub/multiboot.h +++ b/include/grub/multiboot.h @@ -49,7 +49,7 @@ void grub_multiboot_set_bootdev (void); grub_uint32_t grub_get_multiboot_mmap_count (void); grub_err_t grub_multiboot_set_video_mode (void); -#if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_QEMU) +#if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_MULTIBOOT) || defined (GRUB_MACHINE_QEMU) #include #define GRUB_MACHINE_HAS_VGA_TEXT 1 #else diff --git a/loader/multiboot.c b/loader/multiboot.c index ce1e75dda..592289c45 100644 --- a/loader/multiboot.c +++ b/loader/multiboot.c @@ -50,7 +50,7 @@ #include #endif -#if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_QEMU) +#if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_MULTIBOOT) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_QEMU) #define DEFAULT_VIDEO_MODE "text" #else #define DEFAULT_VIDEO_MODE "auto" diff --git a/loader/multiboot_mbi2.c b/loader/multiboot_mbi2.c index 8b67f9383..7e9cebe49 100644 --- a/loader/multiboot_mbi2.c +++ b/loader/multiboot_mbi2.c @@ -32,7 +32,7 @@ #include #include -#if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_QEMU) +#if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_MULTIBOOT) || defined (GRUB_MACHINE_QEMU) #include #define HAS_VGA_TEXT 1 #else diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in index aafdfb059..44e80b106 100644 --- a/util/grub-mkrescue.in +++ b/util/grub-mkrescue.in @@ -30,7 +30,7 @@ target_cpu=@target_cpu@ native_platform=@platform@ pkglib_DATA="@pkglib_DATA@" -coreboot_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/${target_cpu}-coreboot +multiboot_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/${target_cpu}-multiboot pc_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/${target_cpu}-pc # Usage: usage @@ -122,45 +122,45 @@ process_input_dir () } if [ "${override_dir}" = "" ] ; then - if test -e "${coreboot_dir}" ; then - process_input_dir ${coreboot_dir} coreboot + if test -e "${multiboot_dir}" ; then + process_input_dir ${multiboot_dir} multiboot fi if test -e "${pc_dir}" ; then process_input_dir ${pc_dir} pc fi else process_input_dir ${override_dir} ${native_platform} - coreboot_dir= + multiboot_dir= pc_dir= case "${native_platform}" in - coreboot) coreboot_dir=${override_dir} ;; + multiboot) multiboot_dir=${override_dir} ;; pc) pc_dir=${override_dir} ;; esac fi -# build coreboot core.img -if test -e "${coreboot_dir}" ; then - echo "Enabling coreboot support ..." +# build multiboot core.img +if test -e "${multiboot_dir}" ; then + echo "Enabling multiboot support ..." memdisk_img=`mktemp "$MKTEMP_TEMPLATE"` memdisk_dir=`mktemp -d "$MKTEMP_TEMPLATE"` mkdir -p ${memdisk_dir}/boot/grub # obtain date-based UUID iso_uuid=$(date -u +%Y-%m-%d-%H-%M-%S-00) - modules="$(cat ${coreboot_dir}/partmap.lst) ${modules}" + modules="$(cat ${multiboot_dir}/partmap.lst) ${modules}" cat << EOF > ${memdisk_dir}/boot/grub/grub.cfg search --fs-uuid --set ${iso_uuid} -set prefix=(\${root})/boot/grub/${target_cpu}-coreboot +set prefix=(\${root})/boot/grub/${target_cpu}-multiboot EOF (for i in ${modules} ; do echo "insmod $i" done ; \ echo "source /boot/grub/grub.cfg") \ - > ${iso9660_dir}/boot/grub/i386-coreboot/grub.cfg + > ${iso9660_dir}/boot/grub/i386-multiboot/grub.cfg tar -C ${memdisk_dir} -cf ${memdisk_img} boot rm -rf ${memdisk_dir} - grub-mkelfimage -d ${coreboot_dir}/ -m ${memdisk_img} -o ${iso9660_dir}/boot/multiboot.img \ + grub-mkelfimage -d ${multiboot_dir}/ -m ${memdisk_img} -o ${iso9660_dir}/boot/multiboot.img \ memdisk tar search iso9660 configfile sh \ ata at_keyboard rm -f ${memdisk_img} From 7819a4562fb8edfaac72607cde8316a69acf20eb Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 1 May 2010 14:32:48 +0200 Subject: [PATCH 625/738] Use LBIO on coreboot. * conf/i386-coreboot.rmk (kernel_img_SOURCES): Change kern/i386/multiboot_mmap.c to kern/i386/coreboot/mmap.c. * include/grub/i386/coreboot/memory.h (GRUB_LINUXBIOS_MEMBER_LINK): New declaration. * kern/i386/coreboot/init.c (grub_machine_init): Don't call grub_machine_mmap_init on coreboot. * kern/i386/coreboot/mmap.c (grub_linuxbios_table_iterate): Handle GRUB_LINUXBIOS_MEMBER_LINK. (grub_machine_mmap_iterate): Fix declaration. * kern/i386/coreboot/startup.S: Don't save mbi location on coreboot. --- ChangeLog | 15 +++++++++++++++ conf/i386-coreboot.rmk | 2 +- include/grub/i386/coreboot/memory.h | 5 +++-- kern/i386/coreboot/init.c | 2 ++ kern/i386/coreboot/mmap.c | 16 +++++++++++++--- kern/i386/coreboot/startup.S | 2 ++ 6 files changed, 36 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 43f223113..9ace29cc2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2010-05-01 Vladimir Serbinenko + + Use LBIO on coreboot. + + * conf/i386-coreboot.rmk (kernel_img_SOURCES): Change + kern/i386/multiboot_mmap.c to kern/i386/coreboot/mmap.c. + * include/grub/i386/coreboot/memory.h (GRUB_LINUXBIOS_MEMBER_LINK): + New declaration. + * kern/i386/coreboot/init.c (grub_machine_init): Don't call + grub_machine_mmap_init on coreboot. + * kern/i386/coreboot/mmap.c (grub_linuxbios_table_iterate): Handle + GRUB_LINUXBIOS_MEMBER_LINK. + (grub_machine_mmap_iterate): Fix declaration. + * kern/i386/coreboot/startup.S: Don't save mbi location on coreboot. + 2010-05-01 Vladimir Serbinenko Split coreboot and multiboot ports. diff --git a/conf/i386-coreboot.rmk b/conf/i386-coreboot.rmk index 69b8e9a48..ca969632a 100644 --- a/conf/i386-coreboot.rmk +++ b/conf/i386-coreboot.rmk @@ -10,7 +10,7 @@ pkglib_PROGRAMS += kernel.img kernel_img_SOURCES = kern/i386/coreboot/startup.S \ kern/i386/misc.S \ kern/i386/coreboot/init.c \ - kern/i386/multiboot_mmap.c \ + kern/i386/coreboot/mmap.c \ kern/i386/halt.c \ kern/main.c kern/device.c \ kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \ diff --git a/include/grub/i386/coreboot/memory.h b/include/grub/i386/coreboot/memory.h index 434ae622e..664086a81 100644 --- a/include/grub/i386/coreboot/memory.h +++ b/include/grub/i386/coreboot/memory.h @@ -44,8 +44,9 @@ typedef struct grub_linuxbios_table_header *grub_linuxbios_table_header_t; struct grub_linuxbios_table_item { -#define GRUB_LINUXBIOS_MEMBER_UNUSED 0 -#define GRUB_LINUXBIOS_MEMBER_MEMORY 1 +#define GRUB_LINUXBIOS_MEMBER_UNUSED 0x00 +#define GRUB_LINUXBIOS_MEMBER_MEMORY 0x01 +#define GRUB_LINUXBIOS_MEMBER_LINK 0x11 grub_uint32_t tag; grub_uint32_t size; }; diff --git a/kern/i386/coreboot/init.c b/kern/i386/coreboot/init.c index 5f80f28c1..b945e623f 100644 --- a/kern/i386/coreboot/init.c +++ b/kern/i386/coreboot/init.c @@ -117,7 +117,9 @@ grub_machine_init (void) return 0; } +#ifdef GRUB_MACHINE_MULTIBOOT grub_machine_mmap_init (); +#endif grub_machine_mmap_iterate (heap_init); grub_tsc_init (); diff --git a/kern/i386/coreboot/mmap.c b/kern/i386/coreboot/mmap.c index b15369ee5..d06627a08 100644 --- a/kern/i386/coreboot/mmap.c +++ b/kern/i386/coreboot/mmap.c @@ -57,13 +57,23 @@ signature_found: (long) table_header->size); for (; table_item->size; table_item = (grub_linuxbios_table_item_t) ((long) table_item + (long) table_item->size)) - if (hook (table_item)) - return 1; + { + if (table_item->tag == GRUB_LINUXBIOS_MEMBER_LINK + && check_signature ((grub_linuxbios_table_header_t) (grub_addr_t) + *(grub_uint64_t *) (table_item + 1))) + { + table_header = (grub_linuxbios_table_header_t) (grub_addr_t) + *(grub_uint64_t *) (table_item + 1); + goto signature_found; + } + if (hook (table_item)) + return 1; + } return 0; } -void +grub_err_t grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t)) { mem_region_t mem_region; diff --git a/kern/i386/coreboot/startup.S b/kern/i386/coreboot/startup.S index e94950aae..2c4a941cf 100644 --- a/kern/i386/coreboot/startup.S +++ b/kern/i386/coreboot/startup.S @@ -66,10 +66,12 @@ multiboot_header: .long -0x1BADB002 - MULTIBOOT_MEMORY_INFO codestart: +#ifdef GRUB_MACHINE_MULTIBOOT cmpl $MULTIBOOT_BOOTLOADER_MAGIC, %eax jne 0f movl %ebx, EXT_C(startup_multiboot_info) 0: +#endif /* initialize the stack */ movl $GRUB_MEMORY_MACHINE_PROT_STACK, %esp From 0359d0062832355f6ffa8801167134ac92d6eedb Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 1 May 2010 14:38:09 +0200 Subject: [PATCH 626/738] * boot/i386/qemu/boot.S: Add a missing .code16. --- ChangeLog | 4 ++++ boot/i386/qemu/boot.S | 3 +++ 2 files changed, 7 insertions(+) diff --git a/ChangeLog b/ChangeLog index 9ace29cc2..eed00a623 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-05-01 Vladimir Serbinenko + + * boot/i386/qemu/boot.S: Add a missing .code16. + 2010-05-01 Vladimir Serbinenko Use LBIO on coreboot. diff --git a/boot/i386/qemu/boot.S b/boot/i386/qemu/boot.S index a93fe3943..03631a22a 100644 --- a/boot/i386/qemu/boot.S +++ b/boot/i386/qemu/boot.S @@ -63,5 +63,8 @@ VARIABLE(grub_core_entry_addr) *right here* and this is why we need this kludge. */ . = GRUB_BOOT_MACHINE_SIZE - 16 + + .code16 + jmp _start . = GRUB_BOOT_MACHINE_SIZE From ce60689c68559c5fd91f904319613eb075b95ff5 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 1 May 2010 16:35:15 +0200 Subject: [PATCH 627/738] * kern/i386/coreboot/init.c (grub_machine_init): Call grub_machine_mmap_init on qemu. --- ChangeLog | 5 +++++ kern/i386/coreboot/init.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index eed00a623..8163ebe70 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-05-01 Vladimir Serbinenko + + * kern/i386/coreboot/init.c (grub_machine_init): Call + grub_machine_mmap_init on qemu. + 2010-05-01 Vladimir Serbinenko * boot/i386/qemu/boot.S: Add a missing .code16. diff --git a/kern/i386/coreboot/init.c b/kern/i386/coreboot/init.c index b945e623f..f7b837044 100644 --- a/kern/i386/coreboot/init.c +++ b/kern/i386/coreboot/init.c @@ -117,7 +117,7 @@ grub_machine_init (void) return 0; } -#ifdef GRUB_MACHINE_MULTIBOOT +#if defined (GRUB_MACHINE_MULTIBOOT) || defined (GRUB_MACHINE_QEMU) grub_machine_mmap_init (); #endif grub_machine_mmap_iterate (heap_init); From d8b5cd40114891a5c672a16db5a9209b575b9f26 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 1 May 2010 20:28:07 +0200 Subject: [PATCH 628/738] * commands/hashsum.c (GRUB_MOD_INIT): Remove duplication of command name and add N_. * commands/i386/pc/drivemap.c (GRUB_MOD_INIT): Likewise. * commands/iorw.c (GRUB_MOD_INIT): Likewise. * commands/password_pbkdf2.c (GRUB_MOD_INIT): Likewise. * commands/regexp.c (GRUB_MOD_INIT): Likewise. * commands/setpci.c (GRUB_MOD_INIT): Likewise. * commands/terminal.c (GRUB_MOD_INIT): Likewise. * efiemu/main.c (GRUB_MOD_INIT): Likewise. * font/font_cmd.c (GRUB_MOD_INIT): Likewise. * kern/corecmd.c (GRUB_MOD_INIT): Likewise. * mmap/mmap.c (GRUB_MOD_INIT): Likewise. * normal/context.c (GRUB_MOD_INIT): Likewise. * normal/main.c (GRUB_MOD_INIT): Likewise. * term/gfxterm.c (GRUB_MOD_INIT): Likewise. * term/serial.c (GRUB_MOD_INIT): Likewise. * term/terminfo.c (GRUB_MOD_INIT): Likewise. --- ChangeLog | 20 ++++++++++++++++++++ commands/hashsum.c | 25 +++++++++++++------------ commands/i386/pc/drivemap.c | 9 ++++----- commands/iorw.c | 22 +++++++++++++--------- commands/password_pbkdf2.c | 5 +++-- commands/regexp.c | 5 +++-- commands/setpci.c | 7 ++++--- commands/terminal.c | 12 ++++++------ efiemu/main.c | 9 +++++---- font/font_cmd.c | 7 ++++--- kern/corecmd.c | 11 +++++++---- mmap/mmap.c | 5 +++-- normal/context.c | 3 ++- normal/main.c | 4 ++-- term/gfxterm.c | 5 +++-- term/serial.c | 4 ++-- term/terminfo.c | 3 ++- 17 files changed, 96 insertions(+), 60 deletions(-) diff --git a/ChangeLog b/ChangeLog index 67910495b..ea576b9d2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,23 @@ +2010-05-01 Vladimir Serbinenko + + * commands/hashsum.c (GRUB_MOD_INIT): Remove duplication of command + name and add N_. + * commands/i386/pc/drivemap.c (GRUB_MOD_INIT): Likewise. + * commands/iorw.c (GRUB_MOD_INIT): Likewise. + * commands/password_pbkdf2.c (GRUB_MOD_INIT): Likewise. + * commands/regexp.c (GRUB_MOD_INIT): Likewise. + * commands/setpci.c (GRUB_MOD_INIT): Likewise. + * commands/terminal.c (GRUB_MOD_INIT): Likewise. + * efiemu/main.c (GRUB_MOD_INIT): Likewise. + * font/font_cmd.c (GRUB_MOD_INIT): Likewise. + * kern/corecmd.c (GRUB_MOD_INIT): Likewise. + * mmap/mmap.c (GRUB_MOD_INIT): Likewise. + * normal/context.c (GRUB_MOD_INIT): Likewise. + * normal/main.c (GRUB_MOD_INIT): Likewise. + * term/gfxterm.c (GRUB_MOD_INIT): Likewise. + * term/serial.c (GRUB_MOD_INIT): Likewise. + * term/terminfo.c (GRUB_MOD_INIT): Likewise. + 2010-05-01 Vladimir Serbinenko * kern/mm.c (grub_real_malloc): Satisfy alignment requirement when diff --git a/commands/hashsum.c b/commands/hashsum.c index 951479fa7..d5f551dbb 100644 --- a/commands/hashsum.c +++ b/commands/hashsum.c @@ -24,13 +24,14 @@ #include #include #include +#include static const struct grub_arg_option options[] = { - {"hash", 'h', 0, "Specify hash to use.", "HASH", ARG_TYPE_STRING}, - {"check", 'c', 0, "Check hash list file.", "FILE", ARG_TYPE_STRING}, - {"prefix", 'p', 0, "Base directory for hash list.", "DIRECTORY", + {"hash", 'h', 0, N_("Specify hash to use."), N_("HASH"), ARG_TYPE_STRING}, + {"check", 'c', 0, N_("Check hash list file."), N_("FILE"), ARG_TYPE_STRING}, + {"prefix", 'p', 0, N_("Base directory for hash list."), N_("DIRECTORY"), ARG_TYPE_STRING}, - {"keep-going", 'k', 0, "Don't stop after first error.", 0, 0}, + {"keep-going", 'k', 0, N_("Don't stop after first error."), 0, 0}, {0, 0, 0, 0, 0, 0} }; @@ -249,21 +250,21 @@ GRUB_MOD_INIT(hashsum) options); cmd_md5 = grub_register_extcmd ("md5sum", grub_cmd_hashsum, GRUB_COMMAND_FLAG_BOTH, - "md5sum [-c FILE [-p PREFIX]] " - "[FILE1 [FILE2 ...]]", - "Compute or check hash checksum.", + N_("[-c FILE [-p PREFIX]] " + "[FILE1 [FILE2 ...]]"), + N_("Compute or check hash checksum."), options); cmd_sha256 = grub_register_extcmd ("sha256sum", grub_cmd_hashsum, GRUB_COMMAND_FLAG_BOTH, - "sha256sum [-c FILE [-p PREFIX]] " - "[FILE1 [FILE2 ...]]", + N_("[-c FILE [-p PREFIX]] " + "[FILE1 [FILE2 ...]]"), "Compute or check hash checksum.", options); cmd_sha512 = grub_register_extcmd ("sha512sum", grub_cmd_hashsum, GRUB_COMMAND_FLAG_BOTH, - "sha512sum [-c FILE [-p PREFIX]] " - "[FILE1 [FILE2 ...]]", - "Compute or check hash checksum.", + N_("[-c FILE [-p PREFIX]] " + "[FILE1 [FILE2 ...]]"), + N_("Compute or check hash checksum."), options); } diff --git a/commands/i386/pc/drivemap.c b/commands/i386/pc/drivemap.c index 3baacba49..4afc43358 100644 --- a/commands/i386/pc/drivemap.c +++ b/commands/i386/pc/drivemap.c @@ -402,11 +402,10 @@ GRUB_MOD_INIT (drivemap) grub_get_root_biosnumber_saved = grub_get_root_biosnumber; grub_get_root_biosnumber = grub_get_root_biosnumber_drivemap; cmd = grub_register_extcmd ("drivemap", grub_cmd_drivemap, - GRUB_COMMAND_FLAG_BOTH, - "drivemap" - N_("-l | -r | [-s] grubdev osdisk."), - N_("Manage the BIOS drive mappings."), - options); + GRUB_COMMAND_FLAG_BOTH, + N_("-l | -r | [-s] grubdev osdisk."), + N_("Manage the BIOS drive mappings."), + options); drivemap_hook = grub_loader_register_preboot_hook (&install_int13_handler, &uninstall_int13_handler, diff --git a/commands/iorw.c b/commands/iorw.c index c356d0e36..474c8712e 100644 --- a/commands/iorw.c +++ b/commands/iorw.c @@ -22,14 +22,15 @@ #include #include #include +#include static grub_extcmd_t cmd_read_byte, cmd_read_word, cmd_read_dword; static grub_command_t cmd_write_byte, cmd_write_word, cmd_write_dword; static const struct grub_arg_option options[] = { - {0, 'v', 0, "Save read value into variable VARNAME.", - "VARNAME", ARG_TYPE_STRING}, + {0, 'v', 0, N_("Save read value into variable VARNAME."), + N_("VARNAME"), ARG_TYPE_STRING}, {0, 0, 0, 0, 0, 0} }; @@ -62,7 +63,7 @@ grub_cmd_read (grub_extcmd_t cmd, int argc, char **argv) if (cmd->state[0].set) { - grub_sprintf (buf, "%x", value); + grub_snprintf (buf, sizeof (buf), "%x", value); grub_env_set (cmd->state[0].arg, buf); } else @@ -117,22 +118,25 @@ GRUB_MOD_INIT(memrw) { cmd_read_byte = grub_register_extcmd ("inb", grub_cmd_read, GRUB_COMMAND_FLAG_BOTH, - "PORT", "Read byte from PORT.", options); + N_("PORT"), N_("Read byte from PORT."), options); cmd_read_word = grub_register_extcmd ("inw", grub_cmd_read, GRUB_COMMAND_FLAG_BOTH, - "PORT", "Read word from PORT.", options); + N_("PORT"), N_("Read word from PORT."), options); cmd_read_dword = grub_register_extcmd ("inl", grub_cmd_read, GRUB_COMMAND_FLAG_BOTH, - "PORT", "Read dword from PORT.", options); + N_("PORT"), N_("Read dword from PORT."), options); cmd_write_byte = grub_register_command ("outb", grub_cmd_write, - "PORT VALUE [MASK]", "Write byte VALUE to PORT."); + N_("PORT VALUE [MASK]"), + N_("Write byte VALUE to PORT.")); cmd_write_word = grub_register_command ("outw", grub_cmd_write, - "PORT VALUE [MASK]", "Write word VALUE to PORT."); + N_("PORT VALUE [MASK]"), + N_("Write word VALUE to PORT.")); cmd_write_dword = grub_register_command ("outl", grub_cmd_write, - "ADDR VALUE [MASK]", "Write dword VALUE to PORT."); + N_("ADDR VALUE [MASK]"), + N_("Write dword VALUE to PORT.")); } GRUB_MOD_FINI(memrw) diff --git a/commands/password_pbkdf2.c b/commands/password_pbkdf2.c index 51c8ea794..6886987da 100644 --- a/commands/password_pbkdf2.c +++ b/commands/password_pbkdf2.c @@ -24,6 +24,7 @@ #include #include #include +#include static grub_dl_t my_mod; @@ -186,8 +187,8 @@ GRUB_MOD_INIT(password_pbkdf2) { my_mod = mod; cmd = grub_register_command ("password_pbkdf2", grub_cmd_password, - "password_pbkdf2 USER PBKDF2_PASSWORD", - "Set user password (PBKDF2). "); + N_("USER PBKDF2_PASSWORD"), + N_("Set user password (PBKDF2). ")); } GRUB_MOD_FINI(password_pbkdf2) diff --git a/commands/regexp.c b/commands/regexp.c index 910bb9082..e8e8243b5 100644 --- a/commands/regexp.c +++ b/commands/regexp.c @@ -21,6 +21,7 @@ #include #include #include +#include #include static grub_err_t @@ -69,8 +70,8 @@ static grub_command_t cmd; GRUB_MOD_INIT(regexp) { cmd = grub_register_command ("regexp", grub_cmd_regexp, - "REGEXP STRING", - "Test if REGEXP matches STRING."); + N_("REGEXP STRING"), + N_("Test if REGEXP matches STRING.")); } GRUB_MOD_FINI(regexp) diff --git a/commands/setpci.c b/commands/setpci.c index f780547a2..fbc7c214e 100644 --- a/commands/setpci.c +++ b/commands/setpci.c @@ -23,6 +23,7 @@ #include #include #include +#include struct pci_register { @@ -329,9 +330,9 @@ static grub_extcmd_t cmd; GRUB_MOD_INIT(setpci) { cmd = grub_register_extcmd ("setpci", grub_cmd_setpci, GRUB_COMMAND_FLAG_BOTH, - "setpci [-s POSITION] [-d DEVICE] [-v VAR] " - "[REGISTER][=VALUE[:MASK]]", - "Manipulate PCI devices.", options); + N_("[-s POSITION] [-d DEVICE] [-v VAR] " + "[REGISTER][=VALUE[:MASK]]"), + N_("Manipulate PCI devices."), options); } GRUB_MOD_FINI(setpci) diff --git a/commands/terminal.c b/commands/terminal.c index c8c1ffe09..1129c39bd 100644 --- a/commands/terminal.c +++ b/commands/terminal.c @@ -229,14 +229,14 @@ GRUB_MOD_INIT(terminal) { cmd_terminal_input = grub_register_command ("terminal_input", grub_cmd_terminal_input, - "[--append|--remove] " - "[TERMINAL1] [TERMINAL2] ...", - "List or select an input terminal."); + N_("[--append|--remove] " + "[TERMINAL1] [TERMINAL2] ..."), + N_("List or select an input terminal.")); cmd_terminal_output = grub_register_command ("terminal_output", grub_cmd_terminal_output, - "[--append|--remove] " - "[TERMINAL1] [TERMINAL2] ...", - "List or select an output terminal."); + N_("[--append|--remove] " + "[TERMINAL1] [TERMINAL2] ..."), + N_("List or select an output terminal.")); } GRUB_MOD_FINI(terminal) diff --git a/efiemu/main.c b/efiemu/main.c index 8a8a508fa..b197a8b2c 100644 --- a/efiemu/main.c +++ b/efiemu/main.c @@ -31,6 +31,7 @@ #include #include #include +#include /* System table. Two version depending on mode */ grub_efi_system_table32_t *grub_efiemu_system_table32 = 0; @@ -327,15 +328,15 @@ GRUB_MOD_INIT(efiemu) { cmd_loadcore = grub_register_command ("efiemu_loadcore", grub_cmd_efiemu_load, - "FILE", - "Load and initialize EFI emulator."); + N_("FILE"), + N_("Load and initialize EFI emulator.")); cmd_prepare = grub_register_command ("efiemu_prepare", grub_cmd_efiemu_prepare, 0, - "Finalize loading of EFI emulator."); + N_("Finalize loading of EFI emulator.")); cmd_unload = grub_register_command ("efiemu_unload", grub_cmd_efiemu_unload, 0, - "Unload EFI emulator."); + N_("Unload EFI emulator.")); } GRUB_MOD_FINI(efiemu) diff --git a/font/font_cmd.c b/font/font_cmd.c index 5515b2cdc..8b00dd8b9 100644 --- a/font/font_cmd.c +++ b/font/font_cmd.c @@ -21,6 +21,7 @@ #include #include #include +#include static grub_err_t loadfont_command (grub_command_t cmd __attribute__ ((unused)), @@ -62,11 +63,11 @@ GRUB_MOD_INIT(font) cmd_loadfont = grub_register_command ("loadfont", loadfont_command, - "FILE...", - "Specify one or more font files to load."); + N_("FILE..."), + N_("Specify one or more font files to load.")); cmd_lsfonts = grub_register_command ("lsfonts", lsfonts_command, - 0, "List the loaded fonts."); + 0, N_("List the loaded fonts.")); } GRUB_MOD_FINI(font) diff --git a/kern/corecmd.c b/kern/corecmd.c index 8b8df63cb..9af706e94 100644 --- a/kern/corecmd.c +++ b/kern/corecmd.c @@ -26,6 +26,7 @@ #include #include #include +#include /* set ENVVAR=VALUE */ static grub_err_t @@ -178,11 +179,13 @@ void grub_register_core_commands (void) { grub_register_command ("set", grub_core_cmd_set, - "[ENVVAR=VALUE]", "Set an environment variable."); + N_("[ENVVAR=VALUE]"), + N_("Set an environment variable.")); grub_register_command ("unset", grub_core_cmd_unset, - "ENVVAR", "Remove an environment variable."); + N_("ENVVAR"), + N_("Remove an environment variable.")); grub_register_command ("ls", grub_core_cmd_ls, - "[ARG]", "List devices or files."); + N_("[ARG]"), N_("List devices or files.")); grub_register_command ("insmod", grub_core_cmd_insmod, - "MODULE", "Insert a module."); + N_("MODULE"), N_("Insert a module.")); } diff --git a/mmap/mmap.c b/mmap/mmap.c index c22be0a56..a1afc8b06 100644 --- a/mmap/mmap.c +++ b/mmap/mmap.c @@ -24,6 +24,7 @@ #include #include #include +#include #ifndef GRUB_MMAP_REGISTER_BY_FIRMWARE @@ -414,8 +415,8 @@ static grub_command_t cmd; GRUB_MOD_INIT(mmap) { cmd = grub_register_command ("badram", grub_cmd_badram, - "ADDR1,MASK1[,ADDR2,MASK2[,...]]", - "Declare memory regions as badram."); + N_("ADDR1,MASK1[,ADDR2,MASK2[,...]]"), + N_("Declare memory regions as badram.")); } GRUB_MOD_FINI(mmap) diff --git a/normal/context.c b/normal/context.c index 08a841699..27adf287a 100644 --- a/normal/context.c +++ b/normal/context.c @@ -23,6 +23,7 @@ #include #include #include +#include struct menu_pointer { @@ -172,7 +173,7 @@ grub_context_init (void) grub_env_export ("prefix"); export_cmd = grub_register_command ("export", grub_cmd_export, - "export ENVVAR", "Export a variable."); + N_("ENVVAR"), N_("Export a variable.")); } void diff --git a/normal/main.c b/normal/main.c index 8e49b540b..4ed17e82c 100644 --- a/normal/main.c +++ b/normal/main.c @@ -705,9 +705,9 @@ GRUB_MOD_INIT(normal) /* Register a command "normal" for the rescue mode. */ grub_register_command ("normal", grub_cmd_normal, - 0, "Enter normal mode."); + 0, N_("Enter normal mode.")); grub_register_command ("normal_exit", grub_cmd_normal_exit, - 0, "Exit from normal mode."); + 0, N_("Exit from normal mode.")); /* Reload terminal colors when these variables are written to. */ grub_register_variable_hook ("color_normal", NULL, grub_env_write_color_normal); diff --git a/term/gfxterm.c b/term/gfxterm.c index a1409980b..ecfe4ff3b 100644 --- a/term/gfxterm.c +++ b/term/gfxterm.c @@ -29,6 +29,7 @@ #include #include #include +#include #define DEFAULT_VIDEO_MODE "auto" #define DEFAULT_BORDER_WIDTH 10 @@ -1187,8 +1188,8 @@ GRUB_MOD_INIT(gfxterm) grub_register_extcmd ("background_image", grub_gfxterm_background_image_cmd, GRUB_COMMAND_FLAG_BOTH, - "[-m (stretch|normal)] FILE", - "Load background image for active terminal.", + N_("[-m (stretch|normal)] FILE"), + N_("Load background image for active terminal."), background_image_cmd_options); } diff --git a/term/serial.c b/term/serial.c index 05497ce40..2347bb3ee 100644 --- a/term/serial.c +++ b/term/serial.c @@ -616,8 +616,8 @@ GRUB_MOD_INIT(serial) { cmd = grub_register_extcmd ("serial", grub_cmd_serial, GRUB_COMMAND_FLAG_BOTH, - "serial [OPTIONS...]", - "Configure serial port.", options); + N_("[OPTIONS...]"), + N_("Configure serial port."), options); /* Set default settings. */ serial_settings.port = serial_hw_get_port (0); diff --git a/term/terminfo.c b/term/terminfo.c index 9a5979b1c..7402d23db 100644 --- a/term/terminfo.c +++ b/term/terminfo.c @@ -31,6 +31,7 @@ #include #include #include +#include struct terminfo { @@ -178,7 +179,7 @@ static grub_command_t cmd; GRUB_MOD_INIT(terminfo) { cmd = grub_register_command ("terminfo", grub_cmd_terminfo, - "[TERM]", "Set terminfo type."); + N_("[TERM]"), N_("Set terminfo type.")); grub_terminfo_set_current ("vt100"); } From f5f3ff9326a27431640bba6e2f8632468029becd Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 1 May 2010 21:31:45 +0200 Subject: [PATCH 629/738] * commands/help.c (grub_cmd_help): Fix a typo. Reported by: Seth Goldberg --- ChangeLog | 5 +++++ commands/help.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index ea576b9d2..9ecc94faf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-05-01 Vladimir Serbinenko + + * commands/help.c (grub_cmd_help): Fix a typo. + Reported by: Seth Goldberg + 2010-05-01 Vladimir Serbinenko * commands/hashsum.c (GRUB_MOD_INIT): Remove duplication of command diff --git a/commands/help.c b/commands/help.c index 1181c3bfb..c2aad03b2 100644 --- a/commands/help.c +++ b/commands/help.c @@ -100,7 +100,7 @@ grub_cmd_help (grub_extcmd_t ext __attribute__ ((unused)), int argc, if (cmd->flags & GRUB_COMMAND_FLAG_EXTCMD) grub_arg_show_help ((grub_extcmd_t) cmd->data); else - grub_printf ("%s %s %s\n%s\b", _("Usage:"), cmd->name, _(cmd->summary), + grub_printf ("%s %s %s\n%s\n", _("Usage:"), cmd->name, _(cmd->summary), _(cmd->description)); } } From 3558c6e93cb8dda8deb63cc9be884d9c6d34b331 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 1 May 2010 21:32:23 +0200 Subject: [PATCH 630/738] * kern/main.c (grub_load_config): Fix copy-pasted comment. Reported by: Seth Goldberg --- ChangeLog | 5 +++++ kern/main.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 9ecc94faf..62252fcfc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-05-01 Vladimir Serbinenko + + * kern/main.c (grub_load_config): Fix copy-pasted comment. + Reported by: Seth Goldberg + 2010-05-01 Vladimir Serbinenko * commands/help.c (grub_cmd_help): Fix a typo. diff --git a/kern/main.c b/kern/main.c index 2f2c951ab..1fdf4ab07 100644 --- a/kern/main.c +++ b/kern/main.c @@ -102,7 +102,7 @@ grub_load_config (void) auto int hook (struct grub_module_header *); int hook (struct grub_module_header *header) { - /* Not an ELF module, skip. */ + /* Not an embedded config, skip. */ if (header->type != OBJ_TYPE_CONFIG) return 0; From d1b61374edb1f77f245317b7ec66909dc8b1a3a3 Mon Sep 17 00:00:00 2001 From: Christian Franke Date: Sat, 1 May 2010 21:39:32 +0200 Subject: [PATCH 631/738] * util/grub-mkconfig_lib.in (make_system_path_relative_to_its_root): Remove broken Cygwin path conversion. * util/misc.c: [__CYGWIN__] Add include and define. [__CYGWIN__] (get_win32_path): Copy function from getroot.c, modify for Cygwin 1.7. (make_system_path_relative_to_its_root): Simplify loop, replace early return by break. [__CYGWIN__] Add conversion to win32 path. Include "/" case in trailing slash removal. --- ChangeLog | 12 ++++++++ util/grub-mkconfig_lib.in | 18 ++---------- util/misc.c | 61 ++++++++++++++++++++++++++++----------- 3 files changed, 58 insertions(+), 33 deletions(-) diff --git a/ChangeLog b/ChangeLog index 62252fcfc..dadecec86 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2010-05-01 Christian Franke + + * util/grub-mkconfig_lib.in (make_system_path_relative_to_its_root): + Remove broken Cygwin path conversion. + * util/misc.c: [__CYGWIN__] Add include and define. + [__CYGWIN__] (get_win32_path): Copy function from getroot.c, modify + for Cygwin 1.7. + (make_system_path_relative_to_its_root): Simplify loop, replace early + return by break. + [__CYGWIN__] Add conversion to win32 path. + Include "/" case in trailing slash removal. + 2010-05-01 Vladimir Serbinenko * kern/main.c (grub_load_config): Fix copy-pasted comment. diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in index 831bef846..f4674b257 100644 --- a/util/grub-mkconfig_lib.in +++ b/util/grub-mkconfig_lib.in @@ -1,5 +1,5 @@ # Helper library for grub-mkconfig -# Copyright (C) 2007,2008,2009 Free Software Foundation, Inc. +# Copyright (C) 2007,2008,2009,2010 Free Software Foundation, Inc. # # GRUB is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -44,21 +44,7 @@ grub_warn () make_system_path_relative_to_its_root () { - path="`${grub_mkrelpath} $1`" - - case "`uname 2>/dev/null`" in - CYGWIN*) - # Cygwin: Check if regular or emulated mount. - if [ -z "$dir" ] || [ "`stat -c %D "$dir/.."`" != 620000 ] ; then - # Reached some mount point not below /cygdrive. - # GRUB does not know Cygwin's emulated mounts, - # convert to Win32 path and remove drive letter. - path=`cygpath -m "$path" | sed -n 's,^[A-Za-z]:,,p'` - test ! -z "$path" || return 1 - fi ;; - esac - - echo "$path" + ${grub_mkrelpath} $1 } is_path_readable_by_grub () diff --git a/util/misc.c b/util/misc.c index 17fa6d5e4..f9d860d9a 100644 --- a/util/misc.c +++ b/util/misc.c @@ -53,6 +53,11 @@ # include #endif +#ifdef __CYGWIN__ +# include +# define DEV_CYGDRIVE_MAJOR 98 +#endif + #ifdef __MINGW32__ #include #include @@ -456,6 +461,27 @@ canonicalize_file_name (const char *path) return ret; } +#ifdef __CYGWIN__ +/* Convert POSIX path to Win32 path, + remove drive letter, replace backslashes. */ +static char * +get_win32_path (const char *path) +{ + char winpath[PATH_MAX]; + if (cygwin_conv_path (CCP_POSIX_TO_WIN_A, path, winpath, sizeof(winpath))) + grub_util_error ("cygwin_conv_path() failed"); + + int len = strlen (winpath); + int offs = (len > 2 && winpath[1] == ':' ? 2 : 0); + + int i; + for (i = offs; i < len; i++) + if (winpath[i] == '\\') + winpath[i] = '/'; + return xstrdup (winpath + offs); +} +#endif + /* This function never prints trailing slashes (so that its output can be appended a slash unconditionally). */ char * @@ -521,30 +547,31 @@ make_system_path_relative_to_its_root (const char *path) /* offset == 1 means root directory. */ if (offset == 1) { - free (buf); - len = strlen (buf2); - while (buf2[len - 1] == '/' && len > 1) - { - buf2[len - 1] = '\0'; - len--; - } - if (len > 1) - return buf2; - else - { - /* This means path given is just a backslash. As above - we have to return an empty string. */ - free (buf2); - return xstrdup (""); - } + /* Include leading slash. */ + offset = 0; + break; } } free (buf); buf3 = xstrdup (buf2 + offset); free (buf2); +#ifdef __CYGWIN__ + if (st.st_dev != (DEV_CYGDRIVE_MAJOR << 16)) + { + /* Reached some mount point not below /cygdrive. + GRUB does not know Cygwin's emulated mounts, + convert to Win32 path. */ + grub_util_info ("Cygwin path = %s\n", buf3); + char * temp = get_win32_path (buf3); + free (buf3); + buf3 = temp; + } +#endif + + /* Remove trailing slashes, return empty string if root directory. */ len = strlen (buf3); - while (buf3[len - 1] == '/' && len > 1) + while (len > 0 && buf3[len - 1] == '/') { buf3[len - 1] = '\0'; len--; From 2589383147fc5b1dbca19428e5ab2dba9ae9c3ac Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 3 May 2010 12:53:32 +0200 Subject: [PATCH 632/738] * kern/mm.c (grub_real_malloc): Fix size calculation when extra == 0. --- ChangeLog | 4 ++++ kern/mm.c | 9 ++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index dadecec86..96cfb2ebf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-05-01 Vladimir Serbinenko + + * kern/mm.c (grub_real_malloc): Fix size calculation when extra == 0. + 2010-05-01 Christian Franke * util/grub-mkconfig_lib.in (make_system_path_relative_to_its_root): diff --git a/kern/mm.c b/kern/mm.c index a903991d6..d79f5ce29 100644 --- a/kern/mm.c +++ b/kern/mm.c @@ -251,13 +251,20 @@ grub_real_malloc (grub_mm_header_t *first, grub_size_t n, grub_size_t align) grub_mm_header_t r; p->magic = GRUB_MM_ALLOC_MAGIC; - p->size = n; r = p + extra + n; r->magic = GRUB_MM_FREE_MAGIC; r->size = p->size - extra - n; r->next = p->next; q->next = r; + + if (q == p) + { + q = r; + r->next = r; + } + + p->size = n; } else { From 9b058d5291fbc0407ac07f8ece0a546317a7e3d4 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 3 May 2010 13:07:31 +0200 Subject: [PATCH 633/738] * kern/mm.c (grub_mm_init_region): Check for region size after aligning pointers. --- ChangeLog | 5 +++++ kern/mm.c | 11 +++++------ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 96cfb2ebf..f06602d53 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-05-01 Vladimir Serbinenko + + * kern/mm.c (grub_mm_init_region): Check for region size after aligning + pointers. + 2010-05-01 Vladimir Serbinenko * kern/mm.c (grub_real_malloc): Fix size calculation when extra == 0. diff --git a/kern/mm.c b/kern/mm.c index d79f5ce29..28802945c 100644 --- a/kern/mm.c +++ b/kern/mm.c @@ -148,15 +148,14 @@ grub_mm_init_region (void *addr, grub_size_t size) grub_printf ("Using memory for heap: start=%p, end=%p\n", addr, addr + (unsigned int) size); #endif - /* If this region is too small, ignore it. */ - if (size < GRUB_MM_ALIGN * 2) - return; - /* Allocate a region from the head. */ - r = (grub_mm_region_t) (((grub_addr_t) addr + GRUB_MM_ALIGN - 1) - & (~(GRUB_MM_ALIGN - 1))); + r = (grub_mm_region_t) ALIGN_UP ((grub_addr_t) addr, GRUB_MM_ALIGN); size -= (char *) r - (char *) addr + sizeof (*r); + /* If this region is too small, ignore it. */ + if (size < GRUB_MM_ALIGN) + return; + h = (grub_mm_header_t) ((char *) r + GRUB_MM_ALIGN); h->next = h; h->magic = GRUB_MM_FREE_MAGIC; From 7dd5a111ba41d1e5332898ba71f834f77292156c Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 3 May 2010 13:12:55 +0200 Subject: [PATCH 634/738] * kern/mm.c (grub_real_malloc): Put magic and size assignment in common part. --- ChangeLog | 5 +++++ kern/mm.c | 12 +++--------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index f06602d53..c52e885ee 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-05-01 Vladimir Serbinenko + + * kern/mm.c (grub_real_malloc): Put magic and size assignment in common + part. + 2010-05-01 Vladimir Serbinenko * kern/mm.c (grub_mm_init_region): Check for region size after aligning diff --git a/kern/mm.c b/kern/mm.c index 28802945c..47324a662 100644 --- a/kern/mm.c +++ b/kern/mm.c @@ -220,7 +220,6 @@ grub_real_malloc (grub_mm_header_t *first, grub_size_t n, grub_size_t align) +---------------+ v */ q->next = p->next; - p->magic = GRUB_MM_ALLOC_MAGIC; } else if (align == 1 || p->size == n + extra) { @@ -242,14 +241,10 @@ grub_real_malloc (grub_mm_header_t *first, grub_size_t n, grub_size_t align) p->size -= n; p += p->size; - p->size = n; - p->magic = GRUB_MM_ALLOC_MAGIC; } else if (extra == 0) { grub_mm_header_t r; - - p->magic = GRUB_MM_ALLOC_MAGIC; r = p + extra + n; r->magic = GRUB_MM_FREE_MAGIC; @@ -262,8 +257,6 @@ grub_real_malloc (grub_mm_header_t *first, grub_size_t n, grub_size_t align) q = r; r->next = r; } - - p->size = n; } else { @@ -296,10 +289,11 @@ grub_real_malloc (grub_mm_header_t *first, grub_size_t n, grub_size_t align) p->size = extra; p->next = r; p += extra; - p->size = n; - p->magic = GRUB_MM_ALLOC_MAGIC; } + p->magic = GRUB_MM_ALLOC_MAGIC; + p->size = n; + /* Mark find as a start marker for next allocation to fasten it. This will have side effect of fragmenting memory as small pieces before this will be un-used. */ From 265d68cd1034e6e6ca6296dcf1c7a29244567d9d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 3 May 2010 13:17:12 +0200 Subject: [PATCH 635/738] * commands/parttool.c (grub_cmd_parttool): Fix #if !GRUB_NO_MODULES condition. --- ChangeLog | 11 ++++++++--- commands/parttool.c | 2 +- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index c52e885ee..2a6d5e12a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,14 +1,19 @@ -2010-05-01 Vladimir Serbinenko +2010-05-03 Vladimir Serbinenko + + * commands/parttool.c (grub_cmd_parttool): Fix #if !GRUB_NO_MODULES + condition. + +2010-05-03 Vladimir Serbinenko * kern/mm.c (grub_real_malloc): Put magic and size assignment in common part. -2010-05-01 Vladimir Serbinenko +2010-05-03 Vladimir Serbinenko * kern/mm.c (grub_mm_init_region): Check for region size after aligning pointers. -2010-05-01 Vladimir Serbinenko +2010-05-03 Vladimir Serbinenko * kern/mm.c (grub_real_malloc): Fix size calculation when extra == 0. diff --git a/commands/parttool.c b/commands/parttool.c index 0850c5e1d..528cf43d7 100644 --- a/commands/parttool.c +++ b/commands/parttool.c @@ -175,7 +175,7 @@ grub_cmd_parttool (grub_command_t cmd __attribute__ ((unused)), } /* Load modules. */ -#if GRUB_NO_MODULES +#if !GRUB_NO_MODULES { const char *prefix; prefix = grub_env_get ("prefix"); From 2bf6012d7f50ad13c5974e9fd137c37016bcffdd Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 5 May 2010 18:42:33 +0200 Subject: [PATCH 636/738] * term/ieee1275/ofconsole.c (grub_ofconsole_readkey): Support C0 code. --- ChangeLog | 4 ++++ term/ieee1275/ofconsole.c | 34 ++++++++++++++++++++-------------- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2a6d5e12a..2cfed5f1e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-05-05 Vladimir Serbinenko + + * term/ieee1275/ofconsole.c (grub_ofconsole_readkey): Support C0 code. + 2010-05-03 Vladimir Serbinenko * commands/parttool.c (grub_cmd_parttool): Fix #if !GRUB_NO_MODULES diff --git a/term/ieee1275/ofconsole.c b/term/ieee1275/ofconsole.c index c0f895a15..26a43bdf4 100644 --- a/term/ieee1275/ofconsole.c +++ b/term/ieee1275/ofconsole.c @@ -194,14 +194,15 @@ grub_ofconsole_getcolor (grub_uint8_t *normal_color, grub_uint8_t *highlight_col *highlight_color = grub_ofconsole_highlight_color; } +#define ANSI_C0 0x9b + static int grub_ofconsole_readkey (int *key) { - char c; + grub_uint8_t c; grub_ssize_t actual = 0; grub_ieee1275_read (stdin_ihandle, &c, 1, &actual); - if (actual > 0) switch(c) { @@ -209,25 +210,30 @@ grub_ofconsole_readkey (int *key) /* Backspace: Ctrl-h. */ c = '\b'; break; + case ANSI_C0: case '\e': { grub_uint64_t start; - grub_ieee1275_read (stdin_ihandle, &c, 1, &actual); - /* On 9600 we have to wait up to 12 milliseconds. */ - start = grub_get_time_ms (); - while (actual <= 0 && grub_get_time_ms () - start < 12) - grub_ieee1275_read (stdin_ihandle, &c, 1, &actual); - - if (actual <= 0) + if (c == '\e') { - *key = '\e'; - return 1; + grub_ieee1275_read (stdin_ihandle, &c, 1, &actual); + + /* On 9600 we have to wait up to 12 milliseconds. */ + start = grub_get_time_ms (); + while (actual <= 0 && grub_get_time_ms () - start < 12) + grub_ieee1275_read (stdin_ihandle, &c, 1, &actual); + + if (actual <= 0) + { + *key = '\e'; + return 1; + } + + if (c != '[') + return 0; } - if (c != '[') - return 0; - grub_ieee1275_read (stdin_ihandle, &c, 1, &actual); /* On 9600 we have to wait up to 12 milliseconds. */ From a7fc080b56efd933a8e301ab074dc7da893247c7 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 5 May 2010 18:44:02 +0200 Subject: [PATCH 637/738] * term/ieee1275/ofconsole.c (grub_ofconsole_getkey): Fix off-by-one error. --- ChangeLog | 5 +++++ term/ieee1275/ofconsole.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 2cfed5f1e..6a8b7af7d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-05-05 Vladimir Serbinenko + + * term/ieee1275/ofconsole.c (grub_ofconsole_getkey): Fix off-by-one + error. + 2010-05-05 Vladimir Serbinenko * term/ieee1275/ofconsole.c (grub_ofconsole_readkey): Support C0 code. diff --git a/term/ieee1275/ofconsole.c b/term/ieee1275/ofconsole.c index 26a43bdf4..898f9ceab 100644 --- a/term/ieee1275/ofconsole.c +++ b/term/ieee1275/ofconsole.c @@ -327,7 +327,7 @@ grub_ofconsole_getkey (void) static grub_uint16_t grub_ofconsole_getxy (void) { - return ((grub_curr_x - 1) << 8) | grub_curr_y; + return (grub_curr_x << 8) | grub_curr_y; } static void From 7e720a9bc1a99411ee12ea561b7ec4bcaeb1dcc6 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 5 May 2010 18:52:13 +0200 Subject: [PATCH 638/738] * include/grub/ieee1275/ieee1275.h (grub_ieee1275_flag): New value GRUB_IEEE1275_FLAG_NO_PRE1_5M_CLAIM. * kern/ieee1275/cmain.c (grub_ieee1275_find_options): Set GRUB_IEEE1275_FLAG_NO_PRE1_5M_CLAIM on qemu. * kern/ieee1275/init.c (grub_claim_heap): Don0t allocate below 1.5MiB if GRUB_IEEE1275_FLAG_NO_PRE1_5M_CLAIM is set. --- ChangeLog | 9 +++++++++ include/grub/ieee1275/ieee1275.h | 3 +++ kern/ieee1275/cmain.c | 10 ++++++++++ kern/ieee1275/init.c | 11 +++++++++++ 4 files changed, 33 insertions(+) diff --git a/ChangeLog b/ChangeLog index 6a8b7af7d..c38bf213d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2010-05-05 Vladimir Serbinenko + + * include/grub/ieee1275/ieee1275.h (grub_ieee1275_flag): New value + GRUB_IEEE1275_FLAG_NO_PRE1_5M_CLAIM. + * kern/ieee1275/cmain.c (grub_ieee1275_find_options): Set + GRUB_IEEE1275_FLAG_NO_PRE1_5M_CLAIM on qemu. + * kern/ieee1275/init.c (grub_claim_heap): Don0t allocate below + 1.5MiB if GRUB_IEEE1275_FLAG_NO_PRE1_5M_CLAIM is set. + 2010-05-05 Vladimir Serbinenko * term/ieee1275/ofconsole.c (grub_ofconsole_getkey): Fix off-by-one diff --git a/include/grub/ieee1275/ieee1275.h b/include/grub/ieee1275/ieee1275.h index 2b2c36f8f..b30909c68 100644 --- a/include/grub/ieee1275/ieee1275.h +++ b/include/grub/ieee1275/ieee1275.h @@ -100,6 +100,9 @@ enum grub_ieee1275_flag /* Open Hack'Ware don't support the ANSI sequence. */ GRUB_IEEE1275_FLAG_NO_ANSI, + + /* OpenFirmware hangs on qemu if one requests any memory below 1.5 MiB. */ + GRUB_IEEE1275_FLAG_NO_PRE1_5M_CLAIM, }; extern int EXPORT_FUNC(grub_ieee1275_test_flag) (enum grub_ieee1275_flag flag); diff --git a/kern/ieee1275/cmain.c b/kern/ieee1275/cmain.c index c1185f82c..e59d43646 100644 --- a/kern/ieee1275/cmain.c +++ b/kern/ieee1275/cmain.c @@ -59,6 +59,7 @@ grub_ieee1275_find_options (void) char tmp[32]; int is_smartfirmware = 0; int is_olpc = 0; + int is_qemu = 0; grub_ieee1275_finddevice ("/", &root); grub_ieee1275_finddevice ("/options", &options); @@ -79,6 +80,11 @@ grub_ieee1275_find_options (void) if (rc >= 0 && !grub_strcmp (tmp, "OLPC")) is_olpc = 1; + rc = grub_ieee1275_get_property (root, "model", + tmp, sizeof (tmp), 0); + if (rc >= 0 && !grub_strcmp (tmp, "Emulated PC")) + is_qemu = 1; + if (is_smartfirmware) { /* Broken in all versions */ @@ -135,6 +141,10 @@ grub_ieee1275_find_options (void) grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_OFDISK_SDCARD_ONLY); } + if (is_qemu) + /* OpenFirmware hangs on qemu if one requests any memory below 1.5 MiB. */ + grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_NO_PRE1_5M_CLAIM); + if (! grub_ieee1275_finddevice ("/rom/boot-rom", &bootrom)) { rc = grub_ieee1275_get_property (bootrom, "model", tmp, sizeof (tmp), 0); diff --git a/kern/ieee1275/init.c b/kern/ieee1275/init.c index 75f261a71..b48df37bc 100644 --- a/kern/ieee1275/init.c +++ b/kern/ieee1275/init.c @@ -133,6 +133,17 @@ static void grub_claim_heap (void) if (type != 1) return 0; + if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_PRE1_5M_CLAIM)) + { + if (addr + len <= 0x180000) + return 0; + + if (addr < 0x180000) + { + len = addr + len - 0x180000; + addr = 0x180000; + } + } len -= 1; /* Required for some firmware. */ /* Never exceed HEAP_MAX_SIZE */ From e5507505467b3e6ac1058dc1c24217240ac1910e Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Wed, 5 May 2010 21:03:59 +0200 Subject: [PATCH 639/738] * video/readers/jpeg.c (grub_jpeg_decode_huff_table): Loop over all tables. Ignore non-last ac bit. (grub_jpeg_decode_quan_table): Likewise. --- ChangeLog | 6 ++++++ video/readers/jpeg.c | 9 ++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index c38bf213d..0efe3c5e2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-05-05 Peter Hurley (tiny change) + + * video/readers/jpeg.c (grub_jpeg_decode_huff_table): Loop over all + tables. Ignore non-last ac bit. + (grub_jpeg_decode_quan_table): Likewise. + 2010-05-05 Vladimir Serbinenko * include/grub/ieee1275/ieee1275.h (grub_ieee1275_flag): New value diff --git a/video/readers/jpeg.c b/video/readers/jpeg.c index 5e749b8fd..c82b30c9c 100644 --- a/video/readers/jpeg.c +++ b/video/readers/jpeg.c @@ -178,8 +178,10 @@ grub_jpeg_decode_huff_table (struct grub_jpeg_data *data) next_marker = data->file->offset; next_marker += grub_jpeg_get_word (data); + while (data->file->offset + sizeof (count) + 1 <= next_marker) + { id = grub_jpeg_get_byte (data); - ac = (id >> 4); + ac = (id >> 4) & 1; id &= 0xF; if (id > 1) return grub_error (GRUB_ERR_BAD_FILE_TYPE, @@ -213,6 +215,7 @@ grub_jpeg_decode_huff_table (struct grub_jpeg_data *data) base <<= 1; } + } if (data->file->offset != next_marker) grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: extra byte in huffman table"); @@ -229,6 +232,8 @@ grub_jpeg_decode_quan_table (struct grub_jpeg_data *data) next_marker = data->file->offset; next_marker += grub_jpeg_get_word (data); + while (data->file->offset + sizeof (data->quan_table[id]) + 1 <= next_marker) + { id = grub_jpeg_get_byte (data); if (id >= 0x10) /* Upper 4-bit is precision. */ return grub_error (GRUB_ERR_BAD_FILE_TYPE, @@ -241,6 +246,8 @@ grub_jpeg_decode_quan_table (struct grub_jpeg_data *data) if (grub_file_read (data->file, &data->quan_table[id], 64) != 64) return grub_errno; + } + if (data->file->offset != next_marker) grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: extra byte in quantization table"); From 09ddcd11fb3b93ce4cec40b84ee806847154fc09 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 5 May 2010 21:18:10 +0200 Subject: [PATCH 640/738] Various jpeg cleanups. * video/readers/jpeg.c (grub_jpeg_get_huff_code): Use ARRAY_SIZE. (grub_jpeg_decode_quan_table): Use sizeof. (grub_jpeg_decode_du): Use ARRAY_SIZE. --- ChangeLog | 8 ++++++++ video/readers/jpeg.c | 21 +++++++++++++-------- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0efe3c5e2..d3b2b44d1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2010-05-05 Vladimir Serbinenko + + Various jpeg cleanups. + + * video/readers/jpeg.c (grub_jpeg_get_huff_code): Use ARRAY_SIZE. + (grub_jpeg_decode_quan_table): Use sizeof. + (grub_jpeg_decode_du): Use ARRAY_SIZE. + 2010-05-05 Peter Hurley (tiny change) * video/readers/jpeg.c (grub_jpeg_decode_huff_table): Loop over all diff --git a/video/readers/jpeg.c b/video/readers/jpeg.c index c82b30c9c..f46b7f83f 100644 --- a/video/readers/jpeg.c +++ b/video/readers/jpeg.c @@ -153,10 +153,11 @@ grub_jpeg_get_number (struct grub_jpeg_data *data, int num) static int grub_jpeg_get_huff_code (struct grub_jpeg_data *data, int id) { - int code, i; + int code; + unsigned i; code = 0; - for (i = 0; i < 16; i++) + for (i = 0; i < ARRAY_SIZE (data->huff_maxval[id]); i++) { code <<= 1; if (grub_jpeg_get_bit (data)) @@ -171,9 +172,10 @@ grub_jpeg_get_huff_code (struct grub_jpeg_data *data, int id) static grub_err_t grub_jpeg_decode_huff_table (struct grub_jpeg_data *data) { - int id, ac, i, n, base, ofs; + int id, ac, n, base, ofs; grub_uint32_t next_marker; grub_uint8_t count[16]; + unsigned i; next_marker = data->file->offset; next_marker += grub_jpeg_get_word (data); @@ -192,7 +194,7 @@ grub_jpeg_decode_huff_table (struct grub_jpeg_data *data) return grub_errno; n = 0; - for (i = 0; i < 16; i++) + for (i = 0; i < ARRAY_SIZE (count); i++) n += count[i]; id += ac * 2; @@ -205,7 +207,7 @@ grub_jpeg_decode_huff_table (struct grub_jpeg_data *data) base = 0; ofs = 0; - for (i = 0; i < 16; i++) + for (i = 0; i < ARRAY_SIZE (count); i++) { base += count[i]; ofs += count[i]; @@ -243,7 +245,9 @@ grub_jpeg_decode_quan_table (struct grub_jpeg_data *data) return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: too many quantization tables"); - if (grub_file_read (data->file, &data->quan_table[id], 64) != 64) + if (grub_file_read (data->file, &data->quan_table[id], + sizeof (data->quan_table[id])) + != sizeof (data->quan_table[id])) return grub_errno; } @@ -451,7 +455,8 @@ grub_jpeg_idct_transform (jpeg_data_unit_t du) static void grub_jpeg_decode_du (struct grub_jpeg_data *data, int id, jpeg_data_unit_t du) { - int pos, h1, h2, qt; + int h1, h2, qt; + unsigned pos; grub_memset (du, 0, sizeof (jpeg_data_unit_t)); @@ -464,7 +469,7 @@ grub_jpeg_decode_du (struct grub_jpeg_data *data, int id, jpeg_data_unit_t du) du[0] = data->dc_value[id] * (int) data->quan_table[qt][0]; pos = 1; - while (pos < 64) + while (pos < ARRAY_SIZE (data->quan_table[qt])) { int num, val; From 2bf61a980bb1a3ef2fafdec1783e3582a75096f3 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 5 May 2010 21:19:55 +0200 Subject: [PATCH 641/738] * video/readers/jpeg.c: Indented. --- ChangeLog | 4 +++ video/readers/jpeg.c | 84 ++++++++++++++++++++++---------------------- 2 files changed, 46 insertions(+), 42 deletions(-) diff --git a/ChangeLog b/ChangeLog index d3b2b44d1..76b1de28f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-05-05 Vladimir Serbinenko + + * video/readers/jpeg.c: Indented. + 2010-05-05 Vladimir Serbinenko Various jpeg cleanups. diff --git a/video/readers/jpeg.c b/video/readers/jpeg.c index f46b7f83f..9d88163bd 100644 --- a/video/readers/jpeg.c +++ b/video/readers/jpeg.c @@ -182,41 +182,41 @@ grub_jpeg_decode_huff_table (struct grub_jpeg_data *data) while (data->file->offset + sizeof (count) + 1 <= next_marker) { - id = grub_jpeg_get_byte (data); + id = grub_jpeg_get_byte (data); ac = (id >> 4) & 1; - id &= 0xF; - if (id > 1) - return grub_error (GRUB_ERR_BAD_FILE_TYPE, - "jpeg: too many huffman tables"); + id &= 0xF; + if (id > 1) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, + "jpeg: too many huffman tables"); - if (grub_file_read (data->file, &count, sizeof (count)) != - sizeof (count)) - return grub_errno; + if (grub_file_read (data->file, &count, sizeof (count)) != + sizeof (count)) + return grub_errno; - n = 0; - for (i = 0; i < ARRAY_SIZE (count); i++) - n += count[i]; + n = 0; + for (i = 0; i < ARRAY_SIZE (count); i++) + n += count[i]; - id += ac * 2; - data->huff_value[id] = grub_malloc (n); - if (grub_errno) - return grub_errno; + id += ac * 2; + data->huff_value[id] = grub_malloc (n); + if (grub_errno) + return grub_errno; - if (grub_file_read (data->file, data->huff_value[id], n) != n) - return grub_errno; + if (grub_file_read (data->file, data->huff_value[id], n) != n) + return grub_errno; - base = 0; - ofs = 0; - for (i = 0; i < ARRAY_SIZE (count); i++) - { - base += count[i]; - ofs += count[i]; + base = 0; + ofs = 0; + for (i = 0; i < ARRAY_SIZE (count); i++) + { + base += count[i]; + ofs += count[i]; - data->huff_maxval[id][i] = base; - data->huff_offset[id][i] = ofs - base; + data->huff_maxval[id][i] = base; + data->huff_offset[id][i] = ofs - base; - base <<= 1; - } + base <<= 1; + } } if (data->file->offset != next_marker) @@ -234,21 +234,22 @@ grub_jpeg_decode_quan_table (struct grub_jpeg_data *data) next_marker = data->file->offset; next_marker += grub_jpeg_get_word (data); - while (data->file->offset + sizeof (data->quan_table[id]) + 1 <= next_marker) + while (data->file->offset + sizeof (data->quan_table[id]) + 1 + <= next_marker) { - id = grub_jpeg_get_byte (data); - if (id >= 0x10) /* Upper 4-bit is precision. */ - return grub_error (GRUB_ERR_BAD_FILE_TYPE, - "jpeg: only 8-bit precision is supported"); + id = grub_jpeg_get_byte (data); + if (id >= 0x10) /* Upper 4-bit is precision. */ + return grub_error (GRUB_ERR_BAD_FILE_TYPE, + "jpeg: only 8-bit precision is supported"); - if (id > 1) - return grub_error (GRUB_ERR_BAD_FILE_TYPE, - "jpeg: too many quantization tables"); + if (id > 1) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, + "jpeg: too many quantization tables"); - if (grub_file_read (data->file, &data->quan_table[id], - sizeof (data->quan_table[id])) - != sizeof (data->quan_table[id])) - return grub_errno; + if (grub_file_read (data->file, &data->quan_table[id], + sizeof (data->quan_table[id])) + != sizeof (data->quan_table[id])) + return grub_errno; } @@ -712,7 +713,7 @@ grub_video_reader_jpeg (struct grub_video_bitmap **bitmap, #if defined(JPEG_DEBUG) static grub_err_t grub_cmd_jpegtest (grub_command_t cmd __attribute__ ((unused)), - int argc, char **args) + int argc, char **args) { struct grub_video_bitmap *bitmap = 0; @@ -747,8 +748,7 @@ GRUB_MOD_INIT (jpeg) grub_video_bitmap_reader_register (&jpeg_reader); #if defined(JPEG_DEBUG) cmd = grub_register_command ("jpegtest", grub_cmd_jpegtest, - "FILE", - "Tests loading of JPEG bitmap."); + "FILE", "Tests loading of JPEG bitmap."); #endif } From da6e6f17f32680314c57f37fd98ce8e836c9bbed Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Thu, 6 May 2010 08:45:39 +0530 Subject: [PATCH 642/738] cygwin emu build fixes --- bus/usb/emu/usb.c | 4 ++-- conf/any-emu.rmk | 2 +- include/grub/emu/misc.h | 7 +++++++ kern/emu/getroot.c | 9 ++------- kern/emu/misc.c | 20 ++++++++++++++++++++ util/misc.c | 26 -------------------------- 6 files changed, 32 insertions(+), 36 deletions(-) diff --git a/bus/usb/emu/usb.c b/bus/usb/emu/usb.c index a687eea9b..187857b5b 100644 --- a/bus/usb/emu/usb.c +++ b/bus/usb/emu/usb.c @@ -105,14 +105,14 @@ grub_usb_root_hub (grub_usb_controller_t controller __attribute__((unused))) grub_usb_err_t grub_usb_control_msg (grub_usb_device_t dev, grub_uint8_t reqtype, grub_uint8_t request, grub_uint16_t value, - grub_uint16_t index, grub_size_t size, char *data) + grub_uint16_t idx, grub_size_t size, char *data) { usb_dev_handle *devh; struct usb_device *d = dev->data; devh = usb_open (d); if (usb_control_msg (devh, reqtype, request, - value, index, data, size, 20) < 0) + value, idx, data, size, 20) < 0) { usb_close (devh); return GRUB_USB_ERR_STALL; diff --git a/conf/any-emu.rmk b/conf/any-emu.rmk index cb0ec873f..3f0df06aa 100644 --- a/conf/any-emu.rmk +++ b/conf/any-emu.rmk @@ -16,7 +16,7 @@ kernel_img_SOURCES = kern/device.c kern/disk.c kern/dl.c kern/env.c \ \ gnulib/progname.c disk/host.c kernel_img_HEADERS += datetime.h emu/misc.h -kernel_img_CFLAGS = $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) -Wno-undef -I$(srcdir)/gnulib +kernel_img_CFLAGS = $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) -Wno-char-subscripts -Wno-unused -Wno-deprecated-declarations -Wno-undef -I$(srcdir)/gnulib kernel_img_LDFLAGS = $(COMMON_LDFLAGS) TARGET_NO_STRIP = yes diff --git a/include/grub/emu/misc.h b/include/grub/emu/misc.h index 146e64aa9..e037e6be7 100644 --- a/include/grub/emu/misc.h +++ b/include/grub/emu/misc.h @@ -4,6 +4,13 @@ #include #include +#ifdef __CYGWIN__ +# include +# include +# include +# define DEV_CYGDRIVE_MAJOR 98 +#endif + #ifdef __NetBSD__ /* NetBSD uses /boot for its boot block. */ # define DEFAULT_DIRECTORY "/grub" diff --git a/kern/emu/getroot.c b/kern/emu/getroot.c index 10a65aa87..6875044da 100644 --- a/kern/emu/getroot.c +++ b/kern/emu/getroot.c @@ -19,6 +19,8 @@ #include #include +#include +#include #include #include #include @@ -27,13 +29,6 @@ #include #include -#ifdef __CYGWIN__ -# include -# include -# include -# define DEV_CYGDRIVE_MAJOR 98 -#endif - #ifdef __GNU__ #include #include diff --git a/kern/emu/misc.c b/kern/emu/misc.c index 56195a851..4888f4a6b 100644 --- a/kern/emu/misc.c +++ b/kern/emu/misc.c @@ -176,6 +176,26 @@ grub_get_rtc (void) * GRUB_TICKS_PER_SECOND / 1000000)); } +#ifdef __CYGWIN__ +/* Convert POSIX path to Win32 path, + remove drive letter, replace backslashes. */ +static char * +get_win32_path (const char *path) +{ + char winpath[PATH_MAX]; + if (cygwin_conv_path (CCP_POSIX_TO_WIN_A, path, winpath, sizeof(winpath))) + grub_util_error ("cygwin_conv_path() failed"); + + int len = strlen (winpath); + int offs = (len > 2 && winpath[1] == ':' ? 2 : 0); + + int i; + for (i = offs; i < len; i++) + if (winpath[i] == '\\') + winpath[i] = '/'; + return xstrdup (winpath + offs); +} +#endif /* This function never prints trailing slashes (so that its output can be appended a slash unconditionally). */ diff --git a/util/misc.c b/util/misc.c index 1656d6b5b..6785eb00f 100644 --- a/util/misc.c +++ b/util/misc.c @@ -53,11 +53,6 @@ # include #endif -#ifdef __CYGWIN__ -# include -# define DEV_CYGDRIVE_MAJOR 98 -#endif - #ifdef __MINGW32__ #include #include @@ -304,27 +299,6 @@ canonicalize_file_name (const char *path) return ret; } -#ifdef __CYGWIN__ -/* Convert POSIX path to Win32 path, - remove drive letter, replace backslashes. */ -static char * -get_win32_path (const char *path) -{ - char winpath[PATH_MAX]; - if (cygwin_conv_path (CCP_POSIX_TO_WIN_A, path, winpath, sizeof(winpath))) - grub_util_error ("cygwin_conv_path() failed"); - - int len = strlen (winpath); - int offs = (len > 2 && winpath[1] == ':' ? 2 : 0); - - int i; - for (i = offs; i < len; i++) - if (winpath[i] == '\\') - winpath[i] = '/'; - return xstrdup (winpath + offs); -} -#endif - #ifdef GRUB_UTIL void grub_util_init_nls (void) From ab4da2cd366dbd9b36542f8870c4a42adccc6df1 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Thu, 6 May 2010 09:33:45 +0530 Subject: [PATCH 643/738] build fixes for real platforms --- conf/i386-pc.rmk | 37 ++++++++++++------------- conf/i386-qemu.rmk | 2 +- conf/mips.rmk | 2 +- conf/sparc64-ieee1275.rmk | 44 +++++++++++++++--------------- conf/x86-efi.rmk | 2 +- util/i386/pc/grub-setup.c | 6 ++-- util/sparc64/ieee1275/grub-setup.c | 4 +-- 7 files changed, 48 insertions(+), 49 deletions(-) diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk index a5a1b08ea..abefb4d84 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -67,30 +67,29 @@ sbin_UTILITIES = grub-setup # For grub-mkimage. grub_mkimage_SOURCES = gnulib/progname.c util/grub-mkrawimage.c util/misc.c \ - util/resolve.c lib/LzmaEnc.c lib/LzFind.c + kern/emu/misc.c util/resolve.c lib/LzmaEnc.c lib/LzFind.c grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR) util/grub-mkrawimage.c_DEPENDENCIES = Makefile # For grub-setup. util/i386/pc/grub-setup.c_DEPENDENCIES = grub_setup_init.h -grub_setup_SOURCES = gnulib/progname.c \ - util/i386/pc/grub-setup.c util/hostdisk.c \ - util/misc.c util/getroot.c kern/device.c kern/disk.c \ - kern/err.c kern/misc.c kern/parser.c kern/partition.c \ - kern/file.c kern/fs.c kern/env.c kern/list.c \ - fs/fshelp.c \ - \ - fs/affs.c fs/cpio.c fs/ext2.c fs/fat.c fs/hfs.c \ - fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \ - fs/nilfs2.c fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c \ - fs/sfs.c fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c \ - fs/afs_be.c fs/befs.c fs/befs_be.c fs/tar.c \ - \ - partmap/msdos.c partmap/bsdlabel.c partmap/sunpc.c \ - partmap/gpt.c \ - \ - disk/raid.c disk/mdraid_linux.c disk/lvm.c \ - util/raid.c util/lvm.c util/mm.c \ +grub_setup_SOURCES = gnulib/progname.c util/i386/pc/grub-setup.c \ + util/misc.c kern/emu/misc.c kern/emu/getroot.c \ + kern/emu/hostdisk.c kern/device.c kern/disk.c kern/err.c \ + kern/misc.c kern/parser.c kern/partition.c kern/file.c \ + kern/emu/mm.c kern/fs.c kern/env.c kern/list.c fs/fshelp.c \ + \ + fs/affs.c fs/cpio.c fs/ext2.c fs/fat.c fs/hfs.c \ + fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \ + fs/nilfs2.c fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c \ + fs/sfs.c fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c \ + fs/afs_be.c fs/befs.c fs/befs_be.c fs/tar.c \ + \ + partmap/msdos.c partmap/bsdlabel.c partmap/sunpc.c \ + partmap/gpt.c \ + \ + disk/raid.c disk/mdraid_linux.c disk/lvm.c \ + util/raid.c util/lvm.c \ grub_setup_init.c sbin_SCRIPTS += grub-install diff --git a/conf/i386-qemu.rmk b/conf/i386-qemu.rmk index 664bef12a..d5a18a78c 100644 --- a/conf/i386-qemu.rmk +++ b/conf/i386-qemu.rmk @@ -14,7 +14,7 @@ boot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_BOOT_MACHINE_LI boot_img_FORMAT = binary bin_UTILITIES += grub-mkimage -grub_mkimage_SOURCES = util/grub-mkrawimage.c util/misc.c \ +grub_mkimage_SOURCES = util/grub-mkrawimage.c util/misc.c kern/emu/misc.c \ util/resolve.c gnulib/progname.c grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR) util/grub-mkrawimage.c_DEPENDENCIES = Makefile diff --git a/conf/mips.rmk b/conf/mips.rmk index 4603c219e..6e13ace29 100644 --- a/conf/mips.rmk +++ b/conf/mips.rmk @@ -13,7 +13,7 @@ bin_SCRIPTS = # For grub-mkimage. bin_UTILITIES += grub-mkimage grub_mkimage_SOURCES = gnulib/progname.c util/grub-mkrawimage.c util/misc.c \ - util/resolve.c lib/LzmaEnc.c lib/LzFind.c + kern/emu/misc.c util/resolve.c lib/LzmaEnc.c lib/LzFind.c grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(LINK_BASE) util/grub-mkrawimage.c_DEPENDENCIES = Makefile diff --git a/conf/sparc64-ieee1275.rmk b/conf/sparc64-ieee1275.rmk index f0c9b0db7..99128f918 100644 --- a/conf/sparc64-ieee1275.rmk +++ b/conf/sparc64-ieee1275.rmk @@ -44,34 +44,34 @@ bin_UTILITIES = grub-mkimage sbin_UTILITIES = grub-setup grub-ofpathname # For grub-mkimage. -grub_mkimage_SOURCES = util/grub-mkrawimage.c util/misc.c \ +grub_mkimage_SOURCES = util/grub-mkrawimage.c util/misc.c kern/emu/misc.c \ util/resolve.c gnulib/progname.c # For grub-setup. util/sparc64/ieee1275/grub-setup.c_DEPENDENCIES = grub_setup_init.h -grub_setup_SOURCES = util/sparc64/ieee1275/grub-setup.c util/hostdisk.c \ - util/ieee1275/ofpath.c \ - util/misc.c util/getroot.c kern/device.c kern/disk.c \ - kern/err.c kern/misc.c kern/parser.c kern/partition.c \ - kern/file.c kern/fs.c kern/env.c kern/list.c \ - fs/fshelp.c \ - \ - fs/affs.c fs/cpio.c fs/ext2.c fs/fat.c fs/hfs.c \ - fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \ - fs/nilfs2.c fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c \ - fs/sfs.c fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c \ - fs/afs_be.c fs/befs.c fs/befs_be.c fs/tar.c \ - \ - partmap/amiga.c partmap/apple.c partmap/msdos.c \ - partmap/bsdlabel.c partmap/sun.c partmap/acorn.c \ - \ - disk/raid.c disk/mdraid_linux.c disk/lvm.c \ - util/raid.c util/lvm.c util/mm.c gnulib/progname.c \ - grub_setup_init.c +grub_setup_SOURCES = util/sparc64/ieee1275/grub-setup.c \ + util/ieee1275/ofpath.c util/misc.c kern/emu/hostdisk.c \ + kern/emu/misc.c kern/emu/getroot.c kern/emu/mm.c kern/device.c \ + kern/disk.c kern/err.c kern/misc.c kern/parser.c \ + kern/partition.c kern/file.c kern/fs.c kern/env.c kern/list.c \ + fs/fshelp.c \ + \ + fs/affs.c fs/cpio.c fs/ext2.c fs/fat.c fs/hfs.c \ + fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \ + fs/nilfs2.c fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c \ + fs/sfs.c fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c \ + fs/afs_be.c fs/befs.c fs/befs_be.c fs/tar.c \ + \ + partmap/amiga.c partmap/apple.c partmap/msdos.c \ + partmap/bsdlabel.c partmap/sun.c partmap/acorn.c \ + \ + disk/raid.c disk/mdraid_linux.c disk/lvm.c util/raid.c \ + util/lvm.c gnulib/progname.c grub_setup_init.c # For grub-ofpathname. -grub_ofpathname_SOURCES = util/ieee1275/grub-ofpathname.c \ - util/ieee1275/ofpath.c util/misc.c gnulib/progname.c +grub_ofpathname_SOURCES = util/ieee1275/grub-ofpathname.c \ + util/ieee1275/ofpath.c util/misc.c kern/emu/misc.c \ + gnulib/progname.c # Scripts. sbin_SCRIPTS = grub-install diff --git a/conf/x86-efi.rmk b/conf/x86-efi.rmk index e29dad645..7d7d9a3e1 100644 --- a/conf/x86-efi.rmk +++ b/conf/x86-efi.rmk @@ -5,7 +5,7 @@ bin_UTILITIES = grub-mkimage # For grub-mkimage. grub_mkimage_SOURCES = gnulib/progname.c util/i386/efi/grub-mkimage.c \ - util/misc.c util/resolve.c + util/misc.c kern/emu/misc.c util/resolve.c util/i386/efi/grub-mkimage.c_DEPENDENCIES = Makefile # Scripts. diff --git a/util/i386/pc/grub-setup.c b/util/i386/pc/grub-setup.c index 63fa8c328..be6224f7f 100644 --- a/util/i386/pc/grub-setup.c +++ b/util/i386/pc/grub-setup.c @@ -28,14 +28,14 @@ #include #include #include -#include +#include #include #include #include #include #include #include -#include +#include static const grub_gpt_part_type_t grub_gpt_partition_type_bios_boot = GRUB_GPT_PARTITION_TYPE_BIOS_BOOT; @@ -423,7 +423,7 @@ unable_to_embed: /* Make sure that GRUB reads the identical image as the OS. */ tmp_img = xmalloc (core_size); core_path_dev_full = grub_util_get_path (dir, core_file); - core_path_dev = make_system_path_relative_to_its_root (core_path_dev_full); + core_path_dev = grub_make_system_path_relative_to_its_root (core_path_dev_full); free (core_path_dev_full); /* It is a Good Thing to sync two times. */ diff --git a/util/sparc64/ieee1275/grub-setup.c b/util/sparc64/ieee1275/grub-setup.c index 06bc16795..a46a22f87 100644 --- a/util/sparc64/ieee1275/grub-setup.c +++ b/util/sparc64/ieee1275/grub-setup.c @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include #include @@ -46,7 +46,7 @@ #include #include #include -#include +#include #define _GNU_SOURCE 1 #include From 60b4a7c45be55b950761bca55475a01a2307b946 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Thu, 6 May 2010 10:16:55 +0530 Subject: [PATCH 644/738] sparc build fix --- util/sparc64/ieee1275/grub-setup.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/util/sparc64/ieee1275/grub-setup.c b/util/sparc64/ieee1275/grub-setup.c index a46a22f87..a758b42e3 100644 --- a/util/sparc64/ieee1275/grub-setup.c +++ b/util/sparc64/ieee1275/grub-setup.c @@ -627,8 +627,8 @@ main (int argc, char *argv[]) find_dest_dev (&ginfo, argv); - ginfo.prefix = make_system_path_relative_to_its_root (ginfo.dir ? - : DEFAULT_DIRECTORY); + ginfo.prefix = grub_make_system_path_relative_to_its_root (ginfo.dir ? + : DEFAULT_DIRECTORY); check_root_dev (&ginfo); From c6e5caab1dd7d7cb611161d62a3954f84d566558 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 9 May 2010 11:00:21 +0200 Subject: [PATCH 645/738] Transform (broken) vga terminal into (working) vga video driver. * conf/i386-pc.rmk (vga_mod_SOURCES): Change term/i386/pc/vga.c to video/i386/pc/vga.c. * include/grub/video.h (grub_video_driver_id): Add GRUB_VIDEO_DRIVER_VGA. * term/i386/pc/vga.c: Renamed to ... * video/i386/pc/vga.c: ...this (DEBUG_VGA): Removed. (CHAR_WIDTH): Likewise. (CHAR_HEIGHT): Likewise. (TEXT_WIDTH): Likewise. (TEXT_HEIGHT): Likewise. (DEFAULT_FG_COLOR): Likewise. (DEFAULT_BG_COLOR): Likewise. (colored_char): Likewise. (xpos): Likewise. (ypos): Likewise. (cursor_state): Likewise. (fg_color): Likewise. (bg_color): Likewise. (text_buf): Likewise. (page): Likewise. (font): Likewise. (framebuffer): New variable. (set_read_map): Disabled. (setup): New variable. (is_target): Likewise. (grub_vga_mod_init): Likewise. (grub_vga_mod_fini): Likewise. (check_vga_mem): Likewise. (write_char): Likewise. (write_cursor): Likewise. (scroll_up): Likewise. (grub_vga_putchar): Likewise. (grub_vga_getcharwidth): Likewise. (grub_vga_getwh): Likewise. (grub_vga_getxy): Likewise. (grub_vga_gotoxy): Likewise. (grub_vga_cls): Likewise. (grub_vga_setcolorstate): Likewise. (grub_vga_setcursor): Likewise. (grub_video_vga_init): New function. (grub_video_vga_setup): Likewise. (grub_video_vga_fini): Likewise. (update_target): Likewise. (grub_video_vga_blit_bitmap): Likewise. (grub_video_vga_blit_render_target): Likewise. (grub_video_vga_set_active_render_target): Likewise. (grub_video_vga_get_active_render_target): Likewise. (grub_video_vga_swap_buffers): Likewise. (grub_video_vga_set_palette): Likewise. (grub_video_vga_get_info_and_fini): Likewise. (grub_vga_term): Removed. (grub_video_vga_adapter): New variable. (GRUB_MOD_INIT): Register a video driver instead of terminal. (GRUB_MOD_FINI): Unrefister a video driver instead of terminal. --- ChangeLog | 60 +++++ conf/i386-pc.rmk | 2 +- include/grub/video.h | 3 +- term/i386/pc/vga.c | 513 ------------------------------------------- video/i386/pc/vga.c | 412 ++++++++++++++++++++++++++++++++++ 5 files changed, 475 insertions(+), 515 deletions(-) delete mode 100644 term/i386/pc/vga.c create mode 100644 video/i386/pc/vga.c diff --git a/ChangeLog b/ChangeLog index 76b1de28f..a388738cb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,63 @@ +2010-05-09 Vladimir Serbinenko + + Transform (broken) vga terminal into (working) vga video driver. + + * conf/i386-pc.rmk (vga_mod_SOURCES): Change term/i386/pc/vga.c to + video/i386/pc/vga.c. + * include/grub/video.h (grub_video_driver_id): + Add GRUB_VIDEO_DRIVER_VGA. + * term/i386/pc/vga.c: Renamed to ... + * video/i386/pc/vga.c: ...this + (DEBUG_VGA): Removed. + (CHAR_WIDTH): Likewise. + (CHAR_HEIGHT): Likewise. + (TEXT_WIDTH): Likewise. + (TEXT_HEIGHT): Likewise. + (DEFAULT_FG_COLOR): Likewise. + (DEFAULT_BG_COLOR): Likewise. + (colored_char): Likewise. + (xpos): Likewise. + (ypos): Likewise. + (cursor_state): Likewise. + (fg_color): Likewise. + (bg_color): Likewise. + (text_buf): Likewise. + (page): Likewise. + (font): Likewise. + (framebuffer): New variable. + (set_read_map): Disabled. + (setup): New variable. + (is_target): Likewise. + (grub_vga_mod_init): Likewise. + (grub_vga_mod_fini): Likewise. + (check_vga_mem): Likewise. + (write_char): Likewise. + (write_cursor): Likewise. + (scroll_up): Likewise. + (grub_vga_putchar): Likewise. + (grub_vga_getcharwidth): Likewise. + (grub_vga_getwh): Likewise. + (grub_vga_getxy): Likewise. + (grub_vga_gotoxy): Likewise. + (grub_vga_cls): Likewise. + (grub_vga_setcolorstate): Likewise. + (grub_vga_setcursor): Likewise. + (grub_video_vga_init): New function. + (grub_video_vga_setup): Likewise. + (grub_video_vga_fini): Likewise. + (update_target): Likewise. + (grub_video_vga_blit_bitmap): Likewise. + (grub_video_vga_blit_render_target): Likewise. + (grub_video_vga_set_active_render_target): Likewise. + (grub_video_vga_get_active_render_target): Likewise. + (grub_video_vga_swap_buffers): Likewise. + (grub_video_vga_set_palette): Likewise. + (grub_video_vga_get_info_and_fini): Likewise. + (grub_vga_term): Removed. + (grub_video_vga_adapter): New variable. + (GRUB_MOD_INIT): Register a video driver instead of terminal. + (GRUB_MOD_FINI): Unrefister a video driver instead of terminal. + 2010-05-05 Vladimir Serbinenko * video/readers/jpeg.c: Indented. diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk index a5a1b08ea..66a6d883c 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -185,7 +185,7 @@ vbetest_mod_CFLAGS = $(COMMON_CFLAGS) vbetest_mod_LDFLAGS = $(COMMON_LDFLAGS) # For vga.mod. -vga_mod_SOURCES = term/i386/pc/vga.c +vga_mod_SOURCES = video/i386/pc/vga.c vga_mod_CFLAGS = $(COMMON_CFLAGS) vga_mod_LDFLAGS = $(COMMON_LDFLAGS) diff --git a/include/grub/video.h b/include/grub/video.h index 782a5281b..5fd7e0c47 100644 --- a/include/grub/video.h +++ b/include/grub/video.h @@ -181,7 +181,8 @@ typedef enum grub_video_driver_id GRUB_VIDEO_DRIVER_VBE, GRUB_VIDEO_DRIVER_EFI_UGA, GRUB_VIDEO_DRIVER_EFI_GOP, - GRUB_VIDEO_DRIVER_SM712 + GRUB_VIDEO_DRIVER_SM712, + GRUB_VIDEO_DRIVER_VGA } grub_video_driver_id_t; struct grub_video_adapter diff --git a/term/i386/pc/vga.c b/term/i386/pc/vga.c deleted file mode 100644 index 402b30fe6..000000000 --- a/term/i386/pc/vga.c +++ /dev/null @@ -1,513 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2000,2001,2002,2003,2004,2005,2007,2008,2009 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -// TODO: Deprecated and broken. Needs to be converted to Video Driver! - -#include -#include -#include -#include -#include -#include -#include -#include - -#define DEBUG_VGA 0 - -#define VGA_WIDTH 640 -#define VGA_HEIGHT 350 -#define CHAR_WIDTH 8 -#define CHAR_HEIGHT 16 -#define TEXT_WIDTH (VGA_WIDTH / CHAR_WIDTH) -#define TEXT_HEIGHT (VGA_HEIGHT / CHAR_HEIGHT) -#define VGA_MEM ((grub_uint8_t *) GRUB_MEMORY_MACHINE_VGA_ADDR) -#define PAGE_OFFSET(x) ((x) * (VGA_WIDTH * VGA_HEIGHT / 8)) - -#define DEFAULT_FG_COLOR 0xa -#define DEFAULT_BG_COLOR 0x0 - -struct colored_char -{ - /* An Unicode codepoint. */ - grub_uint32_t code; - - /* Color indexes. */ - unsigned char fg_color; - unsigned char bg_color; - - /* The width of this character minus one. */ - unsigned char width; - - /* The column index of this character. */ - unsigned char index; -}; - -static unsigned char text_mode; -static unsigned xpos, ypos; -static int cursor_state; -static unsigned char fg_color, bg_color; -static struct colored_char text_buf[TEXT_WIDTH * TEXT_HEIGHT]; -static unsigned char saved_map_mask; -static int page = 0; -static grub_font_t font = 0; - -#define SEQUENCER_ADDR_PORT 0x3C4 -#define SEQUENCER_DATA_PORT 0x3C5 -#define MAP_MASK_REGISTER 0x02 - -#define CRTC_ADDR_PORT 0x3D4 -#define CRTC_DATA_PORT 0x3D5 -#define START_ADDR_HIGH_REGISTER 0x0C -#define START_ADDR_LOW_REGISTER 0x0D - -#define GRAPHICS_ADDR_PORT 0x3CE -#define GRAPHICS_DATA_PORT 0x3CF -#define READ_MAP_REGISTER 0x04 - -#define INPUT_STATUS1_REGISTER 0x3DA -#define INPUT_STATUS1_VERTR_BIT 0x08 - -static inline void -wait_vretrace (void) -{ - /* Wait until there is a vertical retrace. */ - while (! (grub_inb (INPUT_STATUS1_REGISTER) & INPUT_STATUS1_VERTR_BIT)); -} - -/* Get Map Mask Register. */ -static unsigned char -get_map_mask (void) -{ - unsigned char old_addr; - unsigned char old_data; - - old_addr = grub_inb (SEQUENCER_ADDR_PORT); - grub_outb (MAP_MASK_REGISTER, SEQUENCER_ADDR_PORT); - - old_data = grub_inb (SEQUENCER_DATA_PORT); - - grub_outb (old_addr, SEQUENCER_ADDR_PORT); - - return old_data; -} - -/* Set Map Mask Register. */ -static void -set_map_mask (unsigned char mask) -{ - unsigned char old_addr; - - old_addr = grub_inb (SEQUENCER_ADDR_PORT); - grub_outb (MAP_MASK_REGISTER, SEQUENCER_ADDR_PORT); - - grub_outb (mask, SEQUENCER_DATA_PORT); - - grub_outb (old_addr, SEQUENCER_ADDR_PORT); -} - -/* Set Read Map Register. */ -static void -set_read_map (unsigned char map) -{ - unsigned char old_addr; - - old_addr = grub_inb (GRAPHICS_ADDR_PORT); - - grub_outb (READ_MAP_REGISTER, GRAPHICS_ADDR_PORT); - grub_outb (map, GRAPHICS_DATA_PORT); - - grub_outb (old_addr, GRAPHICS_ADDR_PORT); -} - -/* Set start address. */ -static void -set_start_address (unsigned int start) -{ - unsigned char old_addr; - - old_addr = grub_inb (CRTC_ADDR_PORT); - - grub_outb (START_ADDR_LOW_REGISTER, CRTC_ADDR_PORT); - grub_outb (start & 0xFF, CRTC_DATA_PORT); - - grub_outb (START_ADDR_HIGH_REGISTER, CRTC_ADDR_PORT); - grub_outb (start >> 8, CRTC_DATA_PORT); - - grub_outb (old_addr, CRTC_ADDR_PORT); -} - -static grub_err_t -grub_vga_mod_init (void) -{ - text_mode = grub_vga_set_mode (0x10); - cursor_state = 1; - fg_color = DEFAULT_FG_COLOR; - bg_color = DEFAULT_BG_COLOR; - saved_map_mask = get_map_mask (); - set_map_mask (0x0f); - set_start_address (PAGE_OFFSET (page)); - font = grub_font_get (""); /* Choose any font, for now. */ - if (!font) - return grub_error (GRUB_ERR_BAD_FONT, "no font loaded"); - - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_vga_mod_fini (void) -{ - set_map_mask (saved_map_mask); - grub_vga_set_mode (text_mode); - return GRUB_ERR_NONE; -} - -static int -check_vga_mem (void *p) -{ - return (p >= (void *) (VGA_MEM + PAGE_OFFSET (page)) - && p <= (void *) (VGA_MEM + PAGE_OFFSET (page) - + VGA_WIDTH * VGA_HEIGHT / 8)); -} - -static void -write_char (void) -{ - struct colored_char *p = text_buf + xpos + ypos * TEXT_WIDTH; - struct grub_font_glyph *glyph; - unsigned char *mem_base; - unsigned plane; - - mem_base = (VGA_MEM + xpos + - ypos * CHAR_HEIGHT * TEXT_WIDTH + PAGE_OFFSET (page)) - p->index; - p -= p->index; - - /* Get glyph for character. */ - glyph = grub_font_get_glyph (font, p->code); - - for (plane = 0x01; plane <= 0x08; plane <<= 1) - { - unsigned y; - unsigned offset; - unsigned char *mem; - - set_map_mask (plane); - - for (y = 0, offset = 0, mem = mem_base; - y < CHAR_HEIGHT; - y++, mem += TEXT_WIDTH) - { - /* TODO Re-implement glyph drawing for vga module. */ -#if 0 - unsigned i; - - unsigned char_width = 1; /* TODO Figure out wide characters. */ - for (i = 0; i < char_width && offset < 32; i++) - { - unsigned char fg_mask, bg_mask; - - fg_mask = (p->fg_color & plane) ? glyph->bitmap[offset] : 0; - bg_mask = (p->bg_color & plane) ? ~(glyph->bitmap[offset]) : 0; - offset++; - - if (check_vga_mem (mem + i)) - mem[i] = (fg_mask | bg_mask); - } -#endif /* 0 */ - } - } - - set_map_mask (0x0f); -} - -static void -write_cursor (void) -{ - unsigned char *mem = (VGA_MEM + PAGE_OFFSET (page) + xpos - + (ypos * CHAR_HEIGHT + CHAR_HEIGHT - 3) * TEXT_WIDTH); - if (check_vga_mem (mem)) - *mem = 0xff; - - mem += TEXT_WIDTH; - if (check_vga_mem (mem)) - *mem = 0xff; -} - -static void -scroll_up (void) -{ - unsigned i; - unsigned plane; - - /* Do all the work in the other page. */ - grub_memmove (text_buf, text_buf + TEXT_WIDTH, - sizeof (struct colored_char) * TEXT_WIDTH * (TEXT_HEIGHT - 1)); - - for (i = TEXT_WIDTH * (TEXT_HEIGHT - 1); i < TEXT_WIDTH * TEXT_HEIGHT; i++) - { - text_buf[i].code = ' '; - text_buf[i].fg_color = 0; - text_buf[i].bg_color = 0; - text_buf[i].width = 0; - text_buf[i].index = 0; - } - - for (plane = 1; plane <= 4; plane++) - { - set_read_map (plane); - set_map_mask (1 << plane); - grub_memmove (VGA_MEM + PAGE_OFFSET (1 - page), VGA_MEM - + PAGE_OFFSET (page) + VGA_WIDTH * CHAR_HEIGHT / 8, - VGA_WIDTH * (VGA_HEIGHT - CHAR_HEIGHT) / 8); - } - - set_map_mask (0x0f); - grub_memset (VGA_MEM + PAGE_OFFSET (1 - page) - + VGA_WIDTH * (VGA_HEIGHT - CHAR_HEIGHT) / 8, 0, - VGA_WIDTH * CHAR_HEIGHT / 8); - - /* Activate the other page. */ - page = 1 - page; - wait_vretrace (); - set_start_address (PAGE_OFFSET (page)); -} - -static void -grub_vga_putchar (grub_uint32_t c) -{ -#if DEBUG_VGA - static int show = 1; -#endif - - if (c == '\a') - /* FIXME */ - return; - - if (c == '\b' || c == '\n' || c == '\r') - { - /* Erase current cursor, if any. */ - if (cursor_state) - write_char (); - - switch (c) - { - case '\b': - if (xpos > 0) - xpos--; - break; - - case '\n': - if (ypos >= TEXT_HEIGHT - 1) - scroll_up (); - else - ypos++; - break; - - case '\r': - xpos = 0; - break; - } - - if (cursor_state) - write_cursor (); - } - else - { - struct grub_font_glyph *glyph; - struct colored_char *p; - unsigned char_width = 1; - - glyph = grub_font_get_glyph(font, c); - - if (xpos + char_width > TEXT_WIDTH) - grub_putchar ('\n'); - - p = text_buf + xpos + ypos * TEXT_WIDTH; - p->code = c; - p->fg_color = fg_color; - p->bg_color = bg_color; - p->width = char_width - 1; - p->index = 0; - - if (char_width > 1) - { - unsigned i; - - for (i = 1; i < char_width; i++) - { - p[i].code = ' '; - p[i].width = char_width - 1; - p[i].index = i; - } - } - - write_char (); - - xpos += char_width; - if (xpos >= TEXT_WIDTH) - { - xpos = 0; - - if (ypos >= TEXT_HEIGHT - 1) - scroll_up (); - else - ypos++; - } - - if (cursor_state) - write_cursor (); - } - -#if DEBUG_VGA - if (show) - { - grub_uint16_t pos = grub_getxy (); - - show = 0; - grub_gotoxy (0, 0); - grub_printf ("[%u:%u]", (unsigned) (pos >> 8), (unsigned) (pos & 0xff)); - grub_gotoxy (pos >> 8, pos & 0xff); - show = 1; - } -#endif -} - -static grub_ssize_t -grub_vga_getcharwidth (grub_uint32_t c) -{ -#if 0 - struct grub_font_glyph glyph; - - glyph = grub_font_get_glyph (c); - - return glyph.char_width; -#else - (void) c; /* Prevent warning. */ - return 1; /* TODO Fix wide characters? */ -#endif -} - -static grub_uint16_t -grub_vga_getwh (void) -{ - return (TEXT_WIDTH << 8) | TEXT_HEIGHT; -} - -static grub_uint16_t -grub_vga_getxy (void) -{ - return ((xpos << 8) | ypos); -} - -static void -grub_vga_gotoxy (grub_uint8_t x, grub_uint8_t y) -{ - if (x >= TEXT_WIDTH || y >= TEXT_HEIGHT) - { - grub_error (GRUB_ERR_OUT_OF_RANGE, "invalid point (%u,%u)", - (unsigned) x, (unsigned) y); - return; - } - - if (cursor_state) - write_char (); - - xpos = x; - ypos = y; - - if (cursor_state) - write_cursor (); -} - -static void -grub_vga_cls (void) -{ - unsigned i; - - wait_vretrace (); - for (i = 0; i < TEXT_WIDTH * TEXT_HEIGHT; i++) - { - text_buf[i].code = ' '; - text_buf[i].fg_color = 0; - text_buf[i].bg_color = 0; - text_buf[i].width = 0; - text_buf[i].index = 0; - } - - grub_memset (VGA_MEM + PAGE_OFFSET (page), 0, VGA_WIDTH * VGA_HEIGHT / 8); - - xpos = ypos = 0; -} - -static void -grub_vga_setcolorstate (grub_term_color_state state) -{ - switch (state) - { - case GRUB_TERM_COLOR_STANDARD: - case GRUB_TERM_COLOR_NORMAL: - fg_color = DEFAULT_FG_COLOR; - bg_color = DEFAULT_BG_COLOR; - break; - case GRUB_TERM_COLOR_HIGHLIGHT: - fg_color = DEFAULT_BG_COLOR; - bg_color = DEFAULT_FG_COLOR; - break; - default: - break; - } -} - -static void -grub_vga_setcursor (int on) -{ - if (cursor_state != on) - { - if (cursor_state) - write_char (); - else - write_cursor (); - - cursor_state = on; - } -} - -static struct grub_term_output grub_vga_term = - { - .name = "vga", - .init = grub_vga_mod_init, - .fini = grub_vga_mod_fini, - .putchar = grub_vga_putchar, - .getcharwidth = grub_vga_getcharwidth, - .getwh = grub_vga_getwh, - .getxy = grub_vga_getxy, - .gotoxy = grub_vga_gotoxy, - .cls = grub_vga_cls, - .setcolorstate = grub_vga_setcolorstate, - .setcursor = grub_vga_setcursor, - .flags = 0, - }; - -GRUB_MOD_INIT(vga) -{ - grub_term_register_output ("vga", &grub_vga_term); -} - -GRUB_MOD_FINI(vga) -{ - grub_term_unregister_output (&grub_vga_term); -} diff --git a/video/i386/pc/vga.c b/video/i386/pc/vga.c new file mode 100644 index 000000000..222a71272 --- /dev/null +++ b/video/i386/pc/vga.c @@ -0,0 +1,412 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2000,2001,2002,2003,2004,2005,2007,2008,2009,2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#define grub_video_render_target grub_video_fbrender_target + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define VGA_WIDTH 640 +#define VGA_HEIGHT 350 +#define VGA_MEM ((grub_uint8_t *) GRUB_MEMORY_MACHINE_VGA_ADDR) +#define PAGE_OFFSET(x) ((x) * (VGA_WIDTH * VGA_HEIGHT / 8)) + +static unsigned char text_mode; +static unsigned char saved_map_mask; + +static struct +{ + struct grub_video_mode_info mode_info; + struct grub_video_render_target *render_target; + grub_uint8_t *temporary_buffer; + int front_page; + int back_page; +} framebuffer; + +#define SEQUENCER_ADDR_PORT 0x3C4 +#define SEQUENCER_DATA_PORT 0x3C5 +#define MAP_MASK_REGISTER 0x02 + +#define CRTC_ADDR_PORT 0x3D4 +#define CRTC_DATA_PORT 0x3D5 +#define START_ADDR_HIGH_REGISTER 0x0C +#define START_ADDR_LOW_REGISTER 0x0D + +#define GRAPHICS_ADDR_PORT 0x3CE +#define GRAPHICS_DATA_PORT 0x3CF +#define READ_MAP_REGISTER 0x04 + +#define INPUT_STATUS1_REGISTER 0x3DA +#define INPUT_STATUS1_VERTR_BIT 0x08 + +static inline void +wait_vretrace (void) +{ + /* Wait until there is a vertical retrace. */ + while (! (grub_inb (INPUT_STATUS1_REGISTER) & INPUT_STATUS1_VERTR_BIT)); +} + +/* Get Map Mask Register. */ +static unsigned char +get_map_mask (void) +{ + unsigned char old_addr; + unsigned char old_data; + + old_addr = grub_inb (SEQUENCER_ADDR_PORT); + grub_outb (MAP_MASK_REGISTER, SEQUENCER_ADDR_PORT); + + old_data = grub_inb (SEQUENCER_DATA_PORT); + + grub_outb (old_addr, SEQUENCER_ADDR_PORT); + + return old_data; +} + +/* Set Map Mask Register. */ +static void +set_map_mask (unsigned char mask) +{ + unsigned char old_addr; + + old_addr = grub_inb (SEQUENCER_ADDR_PORT); + grub_outb (MAP_MASK_REGISTER, SEQUENCER_ADDR_PORT); + + grub_outb (mask, SEQUENCER_DATA_PORT); + + grub_outb (old_addr, SEQUENCER_ADDR_PORT); +} + +#if 0 +/* Set Read Map Register. */ +static void +set_read_map (unsigned char map) +{ + unsigned char old_addr; + + old_addr = grub_inb (GRAPHICS_ADDR_PORT); + + grub_outb (READ_MAP_REGISTER, GRAPHICS_ADDR_PORT); + grub_outb (map, GRAPHICS_DATA_PORT); + + grub_outb (old_addr, GRAPHICS_ADDR_PORT); +} +#endif + +/* Set start address. */ +static void +set_start_address (unsigned int start) +{ + unsigned char old_addr; + + old_addr = grub_inb (CRTC_ADDR_PORT); + + grub_outb (START_ADDR_LOW_REGISTER, CRTC_ADDR_PORT); + grub_outb (start & 0xFF, CRTC_DATA_PORT); + + grub_outb (START_ADDR_HIGH_REGISTER, CRTC_ADDR_PORT); + grub_outb (start >> 8, CRTC_DATA_PORT); + + grub_outb (old_addr, CRTC_ADDR_PORT); +} + +static int setup = 0; +static int is_target = 0; + +static grub_err_t +grub_video_vga_init (void) +{ + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_video_vga_setup (unsigned int width, unsigned int height, + unsigned int mode_type, unsigned int mode_mask) +{ + grub_err_t err; + + if ((width && width != VGA_WIDTH) || (height && height != VGA_HEIGHT)) + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no matching mode found"); + + framebuffer.temporary_buffer = grub_malloc (VGA_HEIGHT * VGA_WIDTH); + framebuffer.front_page = 0; + framebuffer.back_page = 0; + if (!framebuffer.temporary_buffer) + return grub_errno; + + saved_map_mask = get_map_mask (); + + text_mode = grub_vga_set_mode (0x10); + setup = 1; + set_map_mask (0x0f); + set_start_address (PAGE_OFFSET (framebuffer.front_page)); + + framebuffer.mode_info.width = VGA_WIDTH; + framebuffer.mode_info.height = VGA_HEIGHT; + + framebuffer.mode_info.mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR; + + if (grub_video_check_mode_flag (mode_type, mode_mask, + GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED, 1)) + { + framebuffer.back_page = 1; + framebuffer.mode_info.mode_type |= GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED; + } + + framebuffer.mode_info.bpp = 8; + framebuffer.mode_info.bytes_per_pixel = 1; + framebuffer.mode_info.pitch = VGA_WIDTH; + framebuffer.mode_info.number_of_colors = 16; + framebuffer.mode_info.red_mask_size = 0; + framebuffer.mode_info.red_field_pos = 0; + framebuffer.mode_info.green_mask_size = 0; + framebuffer.mode_info.green_field_pos = 0; + framebuffer.mode_info.blue_mask_size = 0; + framebuffer.mode_info.blue_field_pos = 0; + framebuffer.mode_info.reserved_mask_size = 0; + framebuffer.mode_info.reserved_field_pos = 0; + + framebuffer.mode_info.blit_format + = grub_video_get_blit_format (&framebuffer.mode_info); + + err = grub_video_fb_create_render_target_from_pointer (&framebuffer.render_target, + &framebuffer.mode_info, + framebuffer.temporary_buffer); + + if (err) + { + grub_dprintf ("video", "Couldn't create FB target\n"); + return err; + } + + is_target = 1; + err = grub_video_fb_set_active_render_target (framebuffer.render_target); + + if (err) + return err; + + err = grub_video_fb_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS, + grub_video_fbstd_colors); + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_video_vga_fini (void) +{ + if (setup) + { + set_map_mask (saved_map_mask); + grub_vga_set_mode (text_mode); + } + setup = 0; + grub_free (framebuffer.temporary_buffer); + framebuffer.temporary_buffer = 0; + return GRUB_ERR_NONE; +} + +static inline void +update_target (void) +{ + int plane; + + if (!is_target) + return; + + for (plane = 0x01; plane <= 0x08; plane <<= 1) + { + grub_uint8_t *ptr; + volatile grub_uint8_t *ptr2; + unsigned cbyte = 0; + int shift = 7; + set_map_mask (plane); + for (ptr = framebuffer.temporary_buffer, + ptr2 = VGA_MEM + PAGE_OFFSET (framebuffer.back_page); + ptr < framebuffer.temporary_buffer + VGA_WIDTH * VGA_HEIGHT; ptr++) + { + cbyte |= (!!(plane & *ptr)) << shift; + shift--; + if (shift == -1) + { + *ptr2++ = cbyte; + shift = 7; + cbyte = 0; + } + } + } +} + +static grub_err_t +grub_video_vga_blit_bitmap (struct grub_video_bitmap *bitmap, + enum grub_video_blit_operators oper, int x, int y, + int offset_x, int offset_y, + unsigned int width, unsigned int height) +{ + grub_err_t ret; + ret = grub_video_fb_blit_bitmap (bitmap, oper, x, y, offset_x, offset_y, + width, height); + update_target (); + return ret; +} + +static grub_err_t +grub_video_vga_blit_render_target (struct grub_video_fbrender_target *source, + enum grub_video_blit_operators oper, + int x, int y, int offset_x, int offset_y, + unsigned int width, unsigned int height) +{ + grub_err_t ret; + + ret = grub_video_fb_blit_render_target (source, oper, x, y, + offset_x, offset_y, width, height); + update_target (); + + return ret; +} + +static grub_err_t +grub_video_vga_set_active_render_target (struct grub_video_render_target *target) +{ + if (target == GRUB_VIDEO_RENDER_TARGET_DISPLAY) + { + is_target = 1; + target = framebuffer.render_target; + } + else + is_target = 0; + + return grub_video_fb_set_active_render_target (target); +} + +static grub_err_t +grub_video_vga_get_active_render_target (struct grub_video_render_target **target) +{ + grub_err_t err; + err = grub_video_fb_get_active_render_target (target); + if (err) + return err; + + if (*target == framebuffer.render_target) + *target = GRUB_VIDEO_RENDER_TARGET_DISPLAY; + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_video_vga_swap_buffers (void) +{ + if (!(framebuffer.mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED)) + return GRUB_ERR_NONE; + + /* Activate the other page. */ + framebuffer.front_page = !framebuffer.front_page; + framebuffer.back_page = !framebuffer.back_page; + wait_vretrace (); + set_start_address (PAGE_OFFSET (framebuffer.front_page)); + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_video_vga_set_palette (unsigned int start __attribute__ ((unused)), + unsigned int count __attribute__ ((unused)), + struct grub_video_palette_data *palette_data __attribute__ ((unused))) +{ + return grub_error (GRUB_ERR_IO, "can't change palette"); +} + +static grub_err_t +grub_video_vga_get_info_and_fini (struct grub_video_mode_info *mode_info, + void **framebuf) +{ + set_map_mask (0xf); + + grub_memcpy (mode_info, &(framebuffer.mode_info), sizeof (*mode_info)); + mode_info->bpp = 1; + mode_info->bytes_per_pixel = 0; + mode_info->pitch = VGA_WIDTH / 8; + mode_info->number_of_colors = 1; + + mode_info->bg_red = 0; + mode_info->bg_green = 0; + mode_info->bg_blue = 0; + mode_info->bg_alpha = 255; + + mode_info->fg_red = 255; + mode_info->fg_green = 255; + mode_info->fg_blue = 255; + mode_info->fg_alpha = 255; + + *framebuf = VGA_MEM + PAGE_OFFSET (framebuffer.front_page); + + grub_video_fb_fini (); + grub_free (framebuffer.temporary_buffer); + framebuffer.temporary_buffer = 0; + setup = 0; + + return GRUB_ERR_NONE; +} + + +static struct grub_video_adapter grub_video_vga_adapter = + { + .name = "VGA Video Driver", + .id = GRUB_VIDEO_DRIVER_VGA, + + .init = grub_video_vga_init, + .fini = grub_video_vga_fini, + .setup = grub_video_vga_setup, + .get_info = grub_video_fb_get_info, + .get_info_and_fini = grub_video_vga_get_info_and_fini, + .set_palette = grub_video_vga_set_palette, + .get_palette = grub_video_fb_get_palette, + .set_viewport = grub_video_fb_set_viewport, + .get_viewport = grub_video_fb_get_viewport, + .map_color = grub_video_fb_map_color, + .map_rgb = grub_video_fb_map_rgb, + .map_rgba = grub_video_fb_map_rgba, + .unmap_color = grub_video_fb_unmap_color, + .fill_rect = grub_video_fb_fill_rect, + .blit_bitmap = grub_video_vga_blit_bitmap, + .blit_render_target = grub_video_vga_blit_render_target, + .scroll = grub_video_fb_scroll, + .swap_buffers = grub_video_vga_swap_buffers, + .create_render_target = grub_video_fb_create_render_target, + .delete_render_target = grub_video_fb_delete_render_target, + .set_active_render_target = grub_video_vga_set_active_render_target, + .get_active_render_target = grub_video_vga_get_active_render_target, + + .next = 0 + }; + +GRUB_MOD_INIT(vga) +{ + grub_video_register (&grub_video_vga_adapter); +} + +GRUB_MOD_FINI(vga) +{ + grub_video_unregister (&grub_video_vga_adapter); +} From cced9145fcb1005dfde437b5f835ecfb924477eb Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 13 May 2010 03:56:14 +0200 Subject: [PATCH 646/738] =?UTF-8?q?=09Fix=20gfxmenu=20crash.=20=09Reported?= =?UTF-8?q?=20by:=20Thorsten=20Gr=C3=BCtzmacher.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * gfxmenu/gui_circular_progress.c (circprog_destroy): Unregister timeout hook. (circprog_set_property): Register and unregister timeout hook. * gfxmenu/gui_label.c (grub_gui_label): New fields template and value. (label_destroy): Free template. and unregister hook. (label_set_state): New function. (label_set_property): Handle templates and hooks. * gfxmenu/gui_progress_bar.c (progress_bar_destroy): Unregister timeout hook. (progress_bar_set_property): Register and unregister timeout hook. * gfxmenu/view.c (TIMEOUT_COMPONENT_ID): Move from here ... * include/grub/gui.h (GRUB_GFXMENU_TIMEOUT_COMPONENT_ID): ...to here * gfxmenu/view.c (grub_gfxmenu_timeout_notifications): New variable. (update_timeout_visit): Removed. (update_timeouts): New function. (redraw_timeouts): Likewise. (grub_gfxmenu_print_timeout): Use update_timeouts and redraw_timeouts. (grub_gfxmenu_clear_timeout): Likewise. * include/grub/gui.h (grub_gfxmenu_set_state_t): New type. (grub_gfxmenu_timeout_notify): Likewise. (grub_gfxmenu_timeout_notifications): New external variable. (grub_gfxmenu_timeout_register): New function. (grub_gfxmenu_timeout_unregister): Likewise. --- ChangeLog | 29 +++++++++++ gfxmenu/gui_circular_progress.c | 28 ++++++----- gfxmenu/gui_label.c | 32 +++++++++++- gfxmenu/gui_progress_bar.c | 7 +++ gfxmenu/view.c | 87 ++++++++++----------------------- include/grub/gui.h | 45 +++++++++++++++++ 6 files changed, 155 insertions(+), 73 deletions(-) diff --git a/ChangeLog b/ChangeLog index a388738cb..78eebc11b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,32 @@ +2010-05-13 Vladimir Serbinenko + + Fix gfxmenu crash. + Reported by: Thorsten Grützmacher. + + * gfxmenu/gui_circular_progress.c (circprog_destroy): Unregister + timeout hook. + (circprog_set_property): Register and unregister timeout hook. + * gfxmenu/gui_label.c (grub_gui_label): New fields template and value. + (label_destroy): Free template. and unregister hook. + (label_set_state): New function. + (label_set_property): Handle templates and hooks. + * gfxmenu/gui_progress_bar.c (progress_bar_destroy): Unregister + timeout hook. + (progress_bar_set_property): Register and unregister timeout hook. + * gfxmenu/view.c (TIMEOUT_COMPONENT_ID): Move from here ... + * include/grub/gui.h (GRUB_GFXMENU_TIMEOUT_COMPONENT_ID): ...to here + * gfxmenu/view.c (grub_gfxmenu_timeout_notifications): New variable. + (update_timeout_visit): Removed. + (update_timeouts): New function. + (redraw_timeouts): Likewise. + (grub_gfxmenu_print_timeout): Use update_timeouts and redraw_timeouts. + (grub_gfxmenu_clear_timeout): Likewise. + * include/grub/gui.h (grub_gfxmenu_set_state_t): New type. + (grub_gfxmenu_timeout_notify): Likewise. + (grub_gfxmenu_timeout_notifications): New external variable. + (grub_gfxmenu_timeout_register): New function. + (grub_gfxmenu_timeout_unregister): Likewise. + 2010-05-09 Vladimir Serbinenko Transform (broken) vga terminal into (working) vga video driver. diff --git a/gfxmenu/gui_circular_progress.c b/gfxmenu/gui_circular_progress.c index 9a859ee2e..098ae1c92 100644 --- a/gfxmenu/gui_circular_progress.c +++ b/gfxmenu/gui_circular_progress.c @@ -54,6 +54,7 @@ static void circprog_destroy (void *vself) { circular_progress_t self = vself; + grub_gfxmenu_timeout_unregister ((grub_gui_component_t) self); grub_free (self); } @@ -211,6 +212,17 @@ circprog_get_bounds (void *vself, grub_video_rect_t *bounds) *bounds = self->bounds; } +static void +circprog_set_state (void *vself, int visible, int start, + int current, int end) +{ + circular_progress_t self = vself; + self->visible = visible; + self->start = start; + self->value = current; + self->end = end; +} + static grub_err_t circprog_set_property (void *vself, const char *name, const char *value) { @@ -247,26 +259,20 @@ circprog_set_property (void *vself, const char *name, const char *value) } else if (grub_strcmp (name, "id") == 0) { + grub_gfxmenu_timeout_unregister ((grub_gui_component_t) self); grub_free (self->id); if (value) self->id = grub_strdup (value); else self->id = 0; + if (self->id && grub_strcmp (self->id, GRUB_GFXMENU_TIMEOUT_COMPONENT_ID) + == 0) + grub_gfxmenu_timeout_register ((grub_gui_component_t) self, + circprog_set_state); } return grub_errno; } -static void -circprog_set_state (void *vself, int visible, int start, - int current, int end) -{ - circular_progress_t self = vself; - self->visible = visible; - self->start = start; - self->value = current; - self->end = end; -} - static struct grub_gui_component_ops circprog_ops = { .destroy = circprog_destroy, diff --git a/gfxmenu/gui_label.c b/gfxmenu/gui_label.c index a9dd575ac..15a352f84 100644 --- a/gfxmenu/gui_label.c +++ b/gfxmenu/gui_label.c @@ -46,8 +46,10 @@ struct grub_gui_label char *id; int visible; char *text; + char *template; grub_font_t font; grub_gui_color_t color; + int value; enum align_mode align; }; @@ -57,7 +59,9 @@ static void label_destroy (void *vself) { grub_gui_label_t self = vself; + grub_gfxmenu_timeout_unregister ((grub_gui_component_t) self); grub_free (self->text); + grub_free (self->template); grub_free (self); } @@ -146,6 +150,17 @@ label_get_minimal_size (void *vself, unsigned *width, unsigned *height) + grub_font_get_descent (self->font)); } +static void +label_set_state (void *vself, int visible, int start __attribute__ ((unused)), + int current, int end __attribute__ ((unused))) +{ + grub_gui_label_t self = vself; + self->value = -current; + self->visible = visible; + grub_free (self->text); + self->text = grub_xasprintf (self->template ? : "%d", self->value); +} + static grub_err_t label_set_property (void *vself, const char *name, const char *value) { @@ -153,9 +168,17 @@ label_set_property (void *vself, const char *name, const char *value) if (grub_strcmp (name, "text") == 0) { grub_free (self->text); + grub_free (self->template); if (! value) - value = ""; - self->text = grub_strdup (value); + { + self->template = NULL; + self->text = grub_strdup (""); + } + else + { + self->template = grub_strdup (value); + self->text = grub_xasprintf (value, self->value); + } } else if (grub_strcmp (name, "font") == 0) { @@ -183,11 +206,16 @@ label_set_property (void *vself, const char *name, const char *value) } else if (grub_strcmp (name, "id") == 0) { + grub_gfxmenu_timeout_unregister ((grub_gui_component_t) self); grub_free (self->id); if (value) self->id = grub_strdup (value); else self->id = 0; + if (self->id && grub_strcmp (self->id, GRUB_GFXMENU_TIMEOUT_COMPONENT_ID) + == 0) + grub_gfxmenu_timeout_register ((grub_gui_component_t) self, + label_set_state); } return GRUB_ERR_NONE; } diff --git a/gfxmenu/gui_progress_bar.c b/gfxmenu/gui_progress_bar.c index d786aae31..e1b31794f 100644 --- a/gfxmenu/gui_progress_bar.c +++ b/gfxmenu/gui_progress_bar.c @@ -60,6 +60,7 @@ static void progress_bar_destroy (void *vself) { grub_gui_progress_bar_t self = vself; + grub_gfxmenu_timeout_unregister ((grub_gui_component_t) self); grub_free (self); } @@ -333,11 +334,16 @@ progress_bar_set_property (void *vself, const char *name, const char *value) } else if (grub_strcmp (name, "id") == 0) { + grub_gfxmenu_timeout_unregister ((grub_gui_component_t) self); grub_free (self->id); if (value) self->id = grub_strdup (value); else self->id = 0; + /* if (self->id && grub_strcmp (self->id, GRUB_GFXMENU_TIMEOUT_COMPONENT_ID) + == 0)*/ + grub_gfxmenu_timeout_register ((grub_gui_component_t) self, + progress_bar_set_state); } return grub_errno; } @@ -368,6 +374,7 @@ grub_gui_progress_bar_new (void) self = grub_zalloc (sizeof (*self)); if (! self) return 0; + self->progress.ops = &progress_bar_pb_ops; self->progress.component.ops = &progress_bar_ops; self->visible = 1; diff --git a/gfxmenu/view.c b/gfxmenu/view.c index bf637a96d..9a5671cdd 100644 --- a/gfxmenu/view.c +++ b/gfxmenu/view.c @@ -37,10 +37,6 @@ #include #include -/* The component ID identifying GUI components to be updated as the timeout - status changes. */ -#define TIMEOUT_COMPONENT_ID "__timeout__" - static void init_terminal (grub_gfxmenu_view_t view); static grub_video_rect_t term_rect; @@ -166,16 +162,28 @@ struct progress_value_data int value; }; -static void -update_timeout_visit (grub_gui_component_t component, - void *userdata) -{ - struct progress_value_data *pv; - pv = (struct progress_value_data *) userdata; +struct grub_gfxmenu_timeout_notify *grub_gfxmenu_timeout_notifications; - ((struct grub_gui_progress *) component)->ops - ->set_state ((struct grub_gui_progress *) component, - pv->visible, pv->start, pv->value, pv->end); +static void +update_timeouts (int visible, int start, int value, int end) +{ + struct grub_gfxmenu_timeout_notify *cur; + + for (cur = grub_gfxmenu_timeout_notifications; cur; cur = cur->next) + cur->set_state (cur->self, visible, start, value, end); +} + +static void +redraw_timeouts (struct grub_gfxmenu_view *view) +{ + struct grub_gfxmenu_timeout_notify *cur; + + for (cur = grub_gfxmenu_timeout_notifications; cur; cur = cur->next) + { + grub_video_rect_t bounds; + cur->self->ops->get_bounds (cur->self, &bounds); + grub_gfxmenu_view_redraw (view, &bounds); + } } void @@ -183,67 +191,26 @@ grub_gfxmenu_print_timeout (int timeout, void *data) { struct grub_gfxmenu_view *view = data; - struct progress_value_data pv; - - auto void redraw_timeout_visit (grub_gui_component_t component, - void *userdata __attribute__ ((unused))); - - auto void redraw_timeout_visit (grub_gui_component_t component, - void *userdata __attribute__ ((unused))) - { - grub_video_rect_t bounds; - component->ops->get_bounds (component, &bounds); - grub_gfxmenu_view_redraw (view, &bounds); - } - if (view->first_timeout == -1) view->first_timeout = timeout; - pv.visible = 1; - pv.start = -(view->first_timeout + 1); - pv.end = 0; - pv.value = -timeout; - - grub_gui_find_by_id ((grub_gui_component_t) view->canvas, - TIMEOUT_COMPONENT_ID, update_timeout_visit, &pv); - grub_gui_find_by_id ((grub_gui_component_t) view->canvas, - TIMEOUT_COMPONENT_ID, redraw_timeout_visit, &pv); + update_timeouts (1, -(view->first_timeout + 1), -timeout, 0); + redraw_timeouts (view); grub_video_swap_buffers (); if (view->double_repaint) - grub_gui_find_by_id ((grub_gui_component_t) view->canvas, - TIMEOUT_COMPONENT_ID, redraw_timeout_visit, &pv); + redraw_timeouts (view); } void grub_gfxmenu_clear_timeout (void *data) { - struct progress_value_data pv; struct grub_gfxmenu_view *view = data; - auto void redraw_timeout_visit (grub_gui_component_t component, - void *userdata __attribute__ ((unused))); - - auto void redraw_timeout_visit (grub_gui_component_t component, - void *userdata __attribute__ ((unused))) - { - grub_video_rect_t bounds; - component->ops->get_bounds (component, &bounds); - grub_gfxmenu_view_redraw (view, &bounds); - } - - pv.visible = 0; - pv.start = 1; - pv.end = 0; - pv.value = 0; - - grub_gui_find_by_id ((grub_gui_component_t) view->canvas, - TIMEOUT_COMPONENT_ID, update_timeout_visit, &pv); - grub_gui_find_by_id ((grub_gui_component_t) view->canvas, - TIMEOUT_COMPONENT_ID, redraw_timeout_visit, &pv); + update_timeouts (0, 1, 0, 0); + redraw_timeouts (view); grub_video_swap_buffers (); if (view->double_repaint) - grub_gui_find_by_id ((grub_gui_component_t) view->canvas, - TIMEOUT_COMPONENT_ID, redraw_timeout_visit, &pv); + redraw_timeouts (view); } static void diff --git a/include/grub/gui.h b/include/grub/gui.h index 7bd71acd3..6e4a11cbe 100644 --- a/include/grub/gui.h +++ b/include/grub/gui.h @@ -22,10 +22,15 @@ #include #include #include +#include #ifndef GRUB_GUI_H #define GRUB_GUI_H 1 +/* The component ID identifying GUI components to be updated as the timeout + status changes. */ +#define GRUB_GFXMENU_TIMEOUT_COMPONENT_ID "__timeout__" + /* A representation of a color. Unlike grub_video_color_t, this representation is independent of any video mode specifics. */ typedef struct grub_gui_color @@ -79,6 +84,46 @@ struct grub_gui_progress_ops void (*set_state) (void *self, int visible, int start, int current, int end); }; +typedef void (*grub_gfxmenu_set_state_t) (void *self, int visible, int start, + int current, int end); + +struct grub_gfxmenu_timeout_notify +{ + struct grub_gfxmenu_timeout_notify *next; + grub_gfxmenu_set_state_t set_state; + grub_gui_component_t self; +}; + +extern struct grub_gfxmenu_timeout_notify *grub_gfxmenu_timeout_notifications; + +static inline grub_err_t +grub_gfxmenu_timeout_register (grub_gui_component_t self, + grub_gfxmenu_set_state_t set_state) +{ + struct grub_gfxmenu_timeout_notify *ne = grub_malloc (sizeof (*ne)); + if (!ne) + return grub_errno; + ne->set_state = set_state; + ne->self = self; + ne->next = grub_gfxmenu_timeout_notifications; + grub_gfxmenu_timeout_notifications = ne; + return GRUB_ERR_NONE; +} + +static inline void +grub_gfxmenu_timeout_unregister (grub_gui_component_t self) +{ + struct grub_gfxmenu_timeout_notify **p, *q; + + for (p = &grub_gfxmenu_timeout_notifications, q = *p; + q; p = &(q->next), q = q->next) + if (q->self == self) + { + *p = q->next; + break; + } +} + typedef signed grub_fixed_signed_t; #define GRUB_FIXED_1 0x10000 From 7e70395f9c8cf179832a9d5070d108fdfe3f82ef Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 17 May 2010 21:35:39 +0200 Subject: [PATCH 647/738] Cherrypick bugfixes and coreboot+qemu support from expermental --- util/grub-mkrescue.in | 147 ++++++++++++++++++++++-------------------- 1 file changed, 77 insertions(+), 70 deletions(-) diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in index 993ffe0cb..4e105f125 100644 --- a/util/grub-mkrescue.in +++ b/util/grub-mkrescue.in @@ -30,10 +30,13 @@ target_cpu=@target_cpu@ native_platform=@platform@ pkglib_DATA="@pkglib_DATA@" -multiboot_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/${target_cpu}-multiboot -pc_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/${target_cpu}-pc +multiboot_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/i386-multiboot +coreboot_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/i386-coreboot +qemu_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/i386-qemu +pc_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/i386-pc efi32_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/i386-efi efi64_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/x86_64-efi +rom_directory= # Usage: usage # Print the usage. @@ -44,8 +47,9 @@ Make GRUB rescue image. -h, --help print this message and exit -v, --version print the version information and exit - --modules=MODULES pre-load specified modules MODULES --output=FILE save output in FILE [required] + --modules=MODULES pre-load specified modules MODULES + --rom-directory=DIR save rom images in DIR [optional] $0 generates a bootable rescue image with specified source files or directories. @@ -66,6 +70,8 @@ for option in "$@"; do modules=`echo "$option" | sed 's/--modules=//'` ;; --output=*) output_image=`echo "$option" | sed 's/--output=//'` ;; + --rom-directory=*) + rom_directory=`echo "$option" | sed 's/--rom-directory=//'` ;; # Intentionally undocumented --override-directory=*) override_dir=`echo "${option}/" | sed 's/--override-directory=//'` @@ -103,15 +109,15 @@ process_input_dir () { input_dir="$1" platform="$2" - mkdir -p ${iso9660_dir}/boot/grub/${target_cpu}-${platform} + mkdir -p ${iso9660_dir}/boot/grub/${platform} for file in ${input_dir}/*.mod; do if test -f "$file"; then - cp -f "$file" ${iso9660_dir}/boot/grub/${target_cpu}-${platform}/ + cp -f "$file" ${iso9660_dir}/boot/grub/${platform}/ fi done for file in ${pkglib_DATA}; do if test -f "${input_dir}/${file}"; then - cp -f "${input_dir}/${file}" ${iso9660_dir}/boot/grub/${target_cpu}-${platform}/ + cp -f "${input_dir}/${file}" ${iso9660_dir}/boot/grub/${platform}/ fi done @@ -123,28 +129,71 @@ process_input_dir () done } +make_image () +{ + source_directory="$1" + platform=$2 + if ! test -e "${source_directory}"; then + return; + fi + + echo "Enabling $2 support ..." + + memdisk_img=`mktemp "$MKTEMP_TEMPLATE"` + memdisk_dir=`mktemp -d "$MKTEMP_TEMPLATE"` + mkdir -p ${memdisk_dir}/boot/grub + + modules="$(cat ${source_directory}/partmap.lst) ${modules}" + cat << EOF > ${memdisk_dir}/boot/grub/grub.cfg +search --fs-uuid --set ${iso_uuid} +set prefix=(\${root})/boot/grub/${platform} +source \$prefix/grub.cfg +EOF + (for i in ${modules} ; do + echo "insmod $i" + done ; \ + echo "source /boot/grub/grub.cfg") \ + > ${iso9660_dir}/boot/grub/${platform}/grub.cfg + + tar -C ${memdisk_dir} -cf ${memdisk_img} boot + rm -rf ${memdisk_dir} + grub-mkimage -O ${platform} -d "${source_directory}" -m "${memdisk_img}" -o "$3" --prefix='(memdisk)/boot/grub' \ + search iso9660 configfile normal memdisk tar $4 + rm -rf ${memdisk_img} +} + if [ "${override_dir}" = "" ] ; then if test -e "${multiboot_dir}" ; then - process_input_dir ${multiboot_dir} multiboot + process_input_dir ${multiboot_dir} i386-multiboot + fi + if test -e "${coreboot_dir}" ; then + process_input_dir ${coreboot_dir} i386-coreboot + fi + if test -e "${qemu_dir}" ; then + process_input_dir ${qemu_dir} i386-qemu fi if test -e "${pc_dir}" ; then - process_input_dir ${pc_dir} pc + process_input_dir ${pc_dir} i386-pc fi if test -e "${efi32_dir}" ; then - process_input_dir ${efi32_dir} efi32 + process_input_dir ${efi32_dir} i386-efi fi if test -e "${efi64_dir}" ; then - process_input_dir ${efi64_dir} efi64 + process_input_dir ${efi64_dir} x86_64-efi fi else - process_input_dir ${override_dir} ${native_platform} + process_input_dir ${override_dir} ${target_cpu}-${native_platform} multiboot_dir= pc_dir= efi32_dir= efi64_dir= + coreboot_dir= + qemu_dir= case "${target_cpu}-${native_platform}" in - i386-pc) pc_dir=${override_dir} ;; i386-multiboot) multiboot_dir=${override_dir} ;; + i386-coreboot) coreboot_dir=${override_dir} ;; + i386-qemu) qemu_dir=${override_dir} ;; + i386-pc) pc_dir=${override_dir} ;; i386-efi) efi32_dir=${override_dir} ;; x86_64-efi) efi64_dir=${override_dir} ;; esac @@ -154,33 +203,6 @@ fi iso_uuid=$(date -u +%Y-%m-%d-%H-%M-%S-00) grub_mkisofs_arguments="${grub_mkisofs_arguments} --modification-date=$(echo ${iso_uuid} | sed -e s/-//g)" -# build coreboot multiboot.img -if test -e "${multiboot_dir}" ; then - echo "Enabling multiboot support ..." - memdisk_img=`mktemp "$MKTEMP_TEMPLATE"` - memdisk_dir=`mktemp -d "$MKTEMP_TEMPLATE"` - mkdir -p ${memdisk_dir}/boot/grub - - modules="$(cat ${multiboot_dir}/partmap.lst) ${modules}" - cat << EOF > ${memdisk_dir}/boot/grub/grub.cfg -search --fs-uuid --set ${iso_uuid} -set prefix=(\${root})/boot/grub/${target_cpu}-multiboot -source \$prefix/grub.cfg -EOF - (for i in ${modules} ; do - echo "insmod $i" - done ; \ - echo "source /boot/grub/grub.cfg") \ - > ${iso9660_dir}/boot/grub/i386-multiboot/grub.cfg - - tar -C ${memdisk_dir} -cf ${memdisk_img} boot - rm -rf ${memdisk_dir} - grub-mkimage -O i386-coreboot -d ${multiboot_dir}/ -m ${memdisk_img} -o ${iso9660_dir}/boot/multiboot.img \ - memdisk tar search iso9660 configfile sh \ - ata at_keyboard - rm -f ${memdisk_img} -fi - # build BIOS core.img if test -e "${pc_dir}" ; then echo "Enabling BIOS support ..." @@ -205,47 +227,32 @@ if test -e "${pc_dir}" ; then --embedded-boot ${embed_img}" fi +# build multiboot core.img +make_image "${multiboot_dir}" i386-multiboot "${iso9660_dir}/boot/multiboot.img" "ata at_keyboard" + if test -e "${efi64_dir}" || test -e "${efi32_dir}"; then efi_dir=`mktemp -d "$MKTEMP_TEMPLATE"` mkdir -p "${efi_dir}/efi/boot" -else - efi_dir= -fi -# build bootx64.efi -if test -e "${efi64_dir}" ; then - echo "Enabling EFI64 support ..." - memdisk_img=`mktemp "$MKTEMP_TEMPLATE"` - memdisk_dir=`mktemp -d "$MKTEMP_TEMPLATE"` - mkdir -p ${memdisk_dir}/boot/grub + # build bootx64.efi + make_image "${efi64_dir}" x86_64-efi "${efi_dir}"/efi/boot/bootx64.efi "" + # build bootia32.efi + make_image "${efi32_dir}" i386-efi "${efi_dir}"/efi/boot/bootia32.efi "" - cat << EOF > ${memdisk_dir}/boot/grub/grub.cfg -search --fs-uuid --set ${iso_uuid} -set prefix=(\${root})/boot/grub/${target_cpu}-efi -source \$prefix/grub.cfg -EOF - - tar -C ${memdisk_dir} -cf ${memdisk_img} boot - rm -rf ${memdisk_dir} - - grub-mkimage -O x86_64-efi -d "${efi64_dir}" -m "${memdisk_img}" -o "${efi_dir}"/efi/boot/bootx64.efi --prefix='(memdisk)/boot/grub' \ - search iso9660 configfile sh memdisk tar - rm -f ${memdisk_img} - - modules="$(cat "${efi64_dir}"/partmap.lst) ${modules}" - (for i in ${modules} ; do - echo "insmod $i" - done ; \ - echo "source /boot/grub/grub.cfg") \ - > "${iso9660_dir}"/boot/grub/x86_64-efi/grub.cfg -fi - -if test x"${efi_dir}" != x; then mformat -C -f 2880 -L 16 -i "${iso9660_dir}"/efi.img :: mcopy -s -i "${iso9660_dir}"/efi.img ${efi_dir}/efi ::/ grub_mkisofs_arguments="${grub_mkisofs_arguments} --efi-boot efi.img" fi +make_image "${qemu_dir}" i386-qemu "${iso9660_dir}/boot/qemu.img" "ata at_keyboard" +if [ -e "${iso9660_dir}/boot/qemu.img" ] && [ -d "${rom_directory}" ]; then + cp "${iso9660_dir}/boot/qemu.img" "${rom_directory}/qemu.img" +fi +make_image "${coreboot_dir}" i386-coreboot "${iso9660_dir}/boot/coreboot.elf" "ata at_keyboard" +if [ -e "${iso9660_dir}/boot/coreboot.elf" ] && [ -d "${rom_directory}" ]; then + cp "${iso9660_dir}/boot/coreboot.elf" "${rom_directory}/coreboot.elf" +fi + # build iso image xorriso -pathspecs on -as mkisofs ${grub_mkisofs_arguments} --protective-msdos-label -o ${output_image} -r ${iso9660_dir} ${source} rm -rf ${iso9660_dir} From 8b26d1d30b1a984ac320c37ea7e8c8986ea9ff16 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 17 May 2010 22:23:22 +0200 Subject: [PATCH 648/738] add missing sh.mod --- util/grub-mkrescue.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in index 4e105f125..5f35f084a 100644 --- a/util/grub-mkrescue.in +++ b/util/grub-mkrescue.in @@ -158,7 +158,7 @@ EOF tar -C ${memdisk_dir} -cf ${memdisk_img} boot rm -rf ${memdisk_dir} grub-mkimage -O ${platform} -d "${source_directory}" -m "${memdisk_img}" -o "$3" --prefix='(memdisk)/boot/grub' \ - search iso9660 configfile normal memdisk tar $4 + search iso9660 configfile normal sh memdisk tar $4 rm -rf ${memdisk_img} } From 6198f888c9a9a0f37aac413e16a50198b5843974 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 17 May 2010 22:28:51 +0200 Subject: [PATCH 649/738] Revert spurious change in Makefile.in --- Makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.in b/Makefile.in index 3df8b1b72..26a494518 100644 --- a/Makefile.in +++ b/Makefile.in @@ -287,7 +287,7 @@ build_env.mk: Makefile echo "TARGET_CC=$(TARGET_CC)" ; \ echo "TARGET_CFLAGS=$(TARGET_CFLAGS)" ; \ echo "TARGET_ASFLAGS=$(TARGET_ASFLAGS)" ; \ - echo "TARGET_CPPFLAGS=$(TARGET_CPPFLAGS) -I$(libdir) -I$(includedir)" ; \ + echo "TARGET_CPPFLAGS=$(TARGET_CPPFLAGS) -I$(pkglibdir) -I$(includedir)" ; \ echo "STRIP=$(STRIP)" ; \ echo "OBJCONV=$(OBJCONV)" ; \ echo "TARGET_MODULE_FORMAT=$(TARGET_MODULE_FORMAT)" ; \ From 1d3293d67dabf99bed6dc4e8d22389614821d64c Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 17 May 2010 23:33:03 +0200 Subject: [PATCH 650/738] Remove grub-mkisofs. * conf/common.rmk (bin_UTILITIES): Remove grub-mkisofs. (grub_mkisofs_SOURCES): Removed. (grub_mkisofs_CFLAGS): Removed. * util/mkisofs/defaults.h: Removed. * util/mkisofs/eltorito.c: Likewise. * util/mkisofs/exclude.h: Likewise. * util/mkisofs/hash.c: Likewise. * util/mkisofs/include/: Likewise. * util/mkisofs/include/fctldefs.h: Likewise. * util/mkisofs/include/mconfig.h: Likewise. * util/mkisofs/include/prototyp.h: Likewise. * util/mkisofs/include/statdefs.h: Likewise. * util/mkisofs/iso9660.h: Likewise. * util/mkisofs/joliet.c: Likewise. * util/mkisofs/match.c: Likewise. * util/mkisofs/match.h: Likewise. * util/mkisofs/mkisofs.c: Likewise. * util/mkisofs/mkisofs.h: Likewise. * util/mkisofs/msdos_partition.h: Likewise. * util/mkisofs/multi.c: Likewise. * util/mkisofs/name.c: Likewise. * util/mkisofs/rock.c: Likewise. * util/mkisofs/tree.c: Likewise. * util/mkisofs/write.c: Likewise. --- ChangeLog | 29 + conf/common.rmk | 14 - util/mkisofs/defaults.h | 20 - util/mkisofs/eltorito.c | 343 ------ util/mkisofs/exclude.h | 10 - util/mkisofs/hash.c | 225 ---- util/mkisofs/include/fctldefs.h | 57 - util/mkisofs/include/mconfig.h | 253 ----- util/mkisofs/include/prototyp.h | 74 -- util/mkisofs/include/statdefs.h | 139 --- util/mkisofs/iso9660.h | 174 --- util/mkisofs/joliet.c | 1023 ----------------- util/mkisofs/match.c | 76 -- util/mkisofs/match.h | 29 - util/mkisofs/mkisofs.c | 1422 ----------------------- util/mkisofs/mkisofs.h | 530 --------- util/mkisofs/msdos_partition.h | 75 -- util/mkisofs/multi.c | 1201 -------------------- util/mkisofs/name.c | 394 ------- util/mkisofs/rock.c | 597 ---------- util/mkisofs/tree.c | 1865 ------------------------------- util/mkisofs/write.c | 1483 ------------------------ 22 files changed, 29 insertions(+), 10004 deletions(-) delete mode 100644 util/mkisofs/defaults.h delete mode 100644 util/mkisofs/eltorito.c delete mode 100644 util/mkisofs/exclude.h delete mode 100644 util/mkisofs/hash.c delete mode 100644 util/mkisofs/include/fctldefs.h delete mode 100644 util/mkisofs/include/mconfig.h delete mode 100644 util/mkisofs/include/prototyp.h delete mode 100644 util/mkisofs/include/statdefs.h delete mode 100644 util/mkisofs/iso9660.h delete mode 100644 util/mkisofs/joliet.c delete mode 100644 util/mkisofs/match.c delete mode 100644 util/mkisofs/match.h delete mode 100644 util/mkisofs/mkisofs.c delete mode 100644 util/mkisofs/mkisofs.h delete mode 100644 util/mkisofs/msdos_partition.h delete mode 100644 util/mkisofs/multi.c delete mode 100644 util/mkisofs/name.c delete mode 100644 util/mkisofs/rock.c delete mode 100644 util/mkisofs/tree.c delete mode 100644 util/mkisofs/write.c diff --git a/ChangeLog b/ChangeLog index 5f3410ea1..8258400c0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,32 @@ +2010-05-17 Vladimir Serbinenko + + Remove grub-mkisofs. + + * conf/common.rmk (bin_UTILITIES): Remove grub-mkisofs. + (grub_mkisofs_SOURCES): Removed. + (grub_mkisofs_CFLAGS): Removed. + * util/mkisofs/defaults.h: Removed. + * util/mkisofs/eltorito.c: Likewise. + * util/mkisofs/exclude.h: Likewise. + * util/mkisofs/hash.c: Likewise. + * util/mkisofs/include/: Likewise. + * util/mkisofs/include/fctldefs.h: Likewise. + * util/mkisofs/include/mconfig.h: Likewise. + * util/mkisofs/include/prototyp.h: Likewise. + * util/mkisofs/include/statdefs.h: Likewise. + * util/mkisofs/iso9660.h: Likewise. + * util/mkisofs/joliet.c: Likewise. + * util/mkisofs/match.c: Likewise. + * util/mkisofs/match.h: Likewise. + * util/mkisofs/mkisofs.c: Likewise. + * util/mkisofs/mkisofs.h: Likewise. + * util/mkisofs/msdos_partition.h: Likewise. + * util/mkisofs/multi.c: Likewise. + * util/mkisofs/name.c: Likewise. + * util/mkisofs/rock.c: Likewise. + * util/mkisofs/tree.c: Likewise. + * util/mkisofs/write.c: Likewise. + 2010-05-17 Vladimir Serbinenko Unify grub-mkimage accross platforms. diff --git a/conf/common.rmk b/conf/common.rmk index 00efa78fb..4186c61b2 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -43,20 +43,6 @@ ifeq ($(enable_grub_fstest), yes) bin_UTILITIES += grub-fstest endif -bin_UTILITIES += grub-mkisofs -grub_mkisofs_SOURCES = util/mkisofs/eltorito.c \ - util/mkisofs/hash.c util/mkisofs/joliet.c \ - util/mkisofs/match.c util/mkisofs/mkisofs.c \ - util/mkisofs/multi.c util/mkisofs/name.c \ - util/mkisofs/rock.c util/mkisofs/tree.c \ - util/mkisofs/write.c \ - \ - gnulib/fnmatch.c gnulib/getopt1.c gnulib/getopt.c \ - gnulib/error.c gnulib/progname.c -grub_mkisofs_CFLAGS = -D_FILE_OFFSET_BITS=64 \ - -I$(srcdir)/util/mkisofs/include \ - -Wno-all -Werror $(GNULIB_UTIL_CFLAGS) - # For grub-fstest. util/grub-fstest.c_DEPENDENCIES = grub_fstest_init.h grub_fstest_SOURCES = gnulib/progname.c util/grub-fstest.c kern/emu/hostfs.c \ diff --git a/util/mkisofs/defaults.h b/util/mkisofs/defaults.h deleted file mode 100644 index 2ce9e8d6b..000000000 --- a/util/mkisofs/defaults.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Header file defaults.h - assorted default values for character strings in - * the volume descriptor. - * - * $Id: defaults.h,v 1.8 1999/03/02 03:41:25 eric Exp $ - */ - -#define PREPARER_DEFAULT NULL -#define PUBLISHER_DEFAULT NULL -#ifndef APPID_DEFAULT -#define APPID_DEFAULT PACKAGE_NAME " ISO 9660 filesystem builder" -#endif -#define COPYRIGHT_DEFAULT NULL -#define BIBLIO_DEFAULT NULL -#define ABSTRACT_DEFAULT NULL -#define VOLSET_ID_DEFAULT NULL -#define VOLUME_ID_DEFAULT "CDROM" -#define BOOT_CATALOG_DEFAULT "boot.catalog" -#define BOOT_IMAGE_DEFAULT NULL -#define SYSTEM_ID_DEFAULT "GNU" diff --git a/util/mkisofs/eltorito.c b/util/mkisofs/eltorito.c deleted file mode 100644 index 1d2a715e0..000000000 --- a/util/mkisofs/eltorito.c +++ /dev/null @@ -1,343 +0,0 @@ -/* - * Program eltorito.c - Handle El Torito specific extensions to iso9660. - * - - Written by Michael Fulbright (1996). - - Copyright 1996 RedHat Software, Incorporated - - Copyright (C) 2009 Free Software Foundation, Inc. - - Boot Info Table generation based on code from genisoimage.c - (from cdrkit 1.1.9), which was originally licensed under GPLv2+. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, see . - */ - - -#include -#include -#include -#include -#include -#include -#include - -#include "config.h" -#include "mkisofs.h" -#include "iso9660.h" - -/* used by Win32 for opening binary file - not used by Unix */ -#ifndef O_BINARY -#define O_BINARY 0 -#endif /* O_BINARY */ - -#undef MIN -#define MIN(a, b) (((a) < (b))? (a): (b)) - -static struct eltorito_validation_entry valid_desc; -static struct eltorito_defaultboot_entry default_desc; -static struct eltorito_boot_descriptor gboot_desc; - -static int tvd_write __PR((FILE * outfile)); - -/* - * Check for presence of boot catalog. If it does not exist then make it - */ -void FDECL1(init_boot_catalog, const char *, path) -{ - FILE *bcat; - char * bootpath; /* filename of boot catalog */ - char * buf; - struct stat statbuf; - - bootpath = (char *) e_malloc(strlen(boot_catalog)+strlen(path)+2); - strcpy(bootpath, path); - if (bootpath[strlen(bootpath)-1] != '/') - { - strcat(bootpath,"/"); - } - - strcat(bootpath, boot_catalog); - - /* - * check for the file existing - */ -#ifdef DEBUG_TORITO - fprintf(stderr,"Looking for boot catalog file %s\n",bootpath); -#endif - - if (!stat_filter(bootpath, &statbuf)) - { - /* - * make sure its big enough to hold what we want - */ - if (statbuf.st_size == 2048) - { - /* - * printf("Boot catalog exists, so we do nothing\n"); - */ - free(bootpath); - return; - } - else - { - fprintf (stderr, _("A boot catalog exists and appears corrupted.\n")); - fprintf (stderr, _("Please check the following file: %s.\n"), bootpath); - fprintf (stderr, _("This file must be removed before a bootable CD can be done.\n")); - free (bootpath); - exit (1); - } - } - - /* - * file does not exist, so we create it - * make it one CD sector long - */ - bcat = fopen (bootpath, "wb"); - if (bcat == NULL) - error (1, errno, _("Error creating boot catalog (%s)"), bootpath); - - buf = (char *) e_malloc( 2048 ); - if (fwrite (buf, 1, 2048, bcat) != 2048) - error (1, errno, _("Error writing to boot catalog (%s)"), bootpath); - fclose (bcat); - chmod (bootpath, S_IROTH | S_IRGRP | S_IRWXU); - - free(bootpath); -} /* init_boot_catalog(... */ - -void FDECL1(get_torito_desc, struct eltorito_boot_descriptor *, boot_desc) -{ - FILE *bootcat; - int checksum; - unsigned char * checksum_ptr; - struct directory_entry * de; - struct directory_entry * de2; - unsigned int i; - int nsectors; - - memset(boot_desc, 0, sizeof(*boot_desc)); - boot_desc->id[0] = 0; - memcpy(boot_desc->id2, ISO_STANDARD_ID, sizeof(ISO_STANDARD_ID)); - boot_desc->version[0] = 1; - - memcpy(boot_desc->system_id, EL_TORITO_ID, sizeof(EL_TORITO_ID)); - - /* - * search from root of iso fs to find boot catalog - */ - de2 = search_tree_file(root, boot_catalog); - if (!de2) - { - fprintf (stderr, _("Boot catalog cannot be found!\n")); - exit (1); - } - - set_731(boot_desc->bootcat_ptr, - (unsigned int) get_733(de2->isorec.extent)); - - /* - * now adjust boot catalog - * lets find boot image first - */ - de=search_tree_file(root, boot_image); - if (!de) - { - fprintf (stderr, _("Boot image cannot be found!\n")); - exit (1); - } - - /* - * we have the boot image, so write boot catalog information - * Next we write out the primary descriptor for the disc - */ - memset(&valid_desc, 0, sizeof(valid_desc)); - valid_desc.headerid[0] = 1; - valid_desc.arch[0] = EL_TORITO_ARCH_x86; - - /* - * we'll shove start of publisher id into id field, may get truncated - * but who really reads this stuff! - */ - if (publisher) - memcpy_max(valid_desc.id, publisher, MIN(23, strlen(publisher))); - - valid_desc.key1[0] = 0x55; - valid_desc.key2[0] = 0xAA; - - /* - * compute the checksum - */ - checksum=0; - checksum_ptr = (unsigned char *) &valid_desc; - for (i=0; isize + 511) & ~(511))/512; - fprintf (stderr, _("\nSize of boot image is %d sectors"), nsectors); - fprintf (stderr, " -> "); - - if (! use_eltorito_emul_floppy) - { - default_desc.boot_media[0] = EL_TORITO_MEDIA_NOEMUL; - fprintf (stderr, _("No emulation\n")); - } - else if (nsectors == 2880 ) - /* - * choose size of emulated floppy based on boot image size - */ - { - default_desc.boot_media[0] = EL_TORITO_MEDIA_144FLOP; - fprintf (stderr, _("Emulating a 1.44 meg floppy\n")); - } - else if (nsectors == 5760 ) - { - default_desc.boot_media[0] = EL_TORITO_MEDIA_288FLOP; - fprintf (stderr, _("Emulating a 2.88 meg floppy\n")); - } - else if (nsectors == 2400 ) - { - default_desc.boot_media[0] = EL_TORITO_MEDIA_12FLOP; - fprintf (stderr, _("Emulating a 1.2 meg floppy\n")); - } - else - { - fprintf (stderr, _("\nError - boot image is not the an allowable size.\n")); - exit (1); - } - - /* - * FOR NOW LOAD 1 SECTOR, JUST LIKE FLOPPY BOOT!!! - */ - nsectors = 1; - set_721(default_desc.nsect, (unsigned int) nsectors ); -#ifdef DEBUG_TORITO - fprintf(stderr,"Extent of boot images is %d\n",get_733(de->isorec.extent)); -#endif - set_731(default_desc.bootoff, - (unsigned int) get_733(de->isorec.extent)); - - /* - * now write it to disk - */ - bootcat = fopen (de2->whole_name, "r+b"); - if (bootcat == NULL) - error (1, errno, _("Error opening boot catalog for update")); - - /* - * write out - */ - if (fwrite (&valid_desc, 1, 32, bootcat) != 32) - error (1, errno, _("Error writing to boot catalog")); - if (fwrite (&default_desc, 1, 32, bootcat) != 32) - error (1, errno, _("Error writing to boot catalog")); - fclose (bootcat); - - /* If the user has asked for it, patch the boot image */ - if (use_boot_info_table) - { - FILE *bootimage; - uint32_t bi_checksum; - unsigned int total_len; - static char csum_buffer[SECTOR_SIZE]; - int len; - struct eltorito_boot_info bi_table; - bootimage = fopen (de->whole_name, "r+b"); - if (bootimage == NULL) - error (1, errno, _("Error opening boot image file `%s' for update"), - de->whole_name); - /* Compute checksum of boot image, sans 64 bytes */ - total_len = 0; - bi_checksum = 0; - while ((len = fread (csum_buffer, 1, SECTOR_SIZE, bootimage)) > 0) - { - if (total_len & 3) - error (1, 0, _("Odd alignment at non-end-of-file in boot image `%s'"), - de->whole_name); - if (total_len < 64) - memset (csum_buffer, 0, 64 - total_len); - if (len < SECTOR_SIZE) - memset (csum_buffer + len, 0, SECTOR_SIZE - len); - for (i = 0; i < SECTOR_SIZE; i += 4) - bi_checksum += get_731 (&csum_buffer[i]); - total_len += len; - } - - if (total_len != de->size) - error (1, 0, _("Boot image file `%s' changed unexpectedly"), - de->whole_name); - /* End of file, set position to byte 8 */ - fseeko (bootimage, (off_t) 8, SEEK_SET); - memset (&bi_table, 0, sizeof (bi_table)); - /* Is it always safe to assume PVD is at session_start+16? */ - set_731 (bi_table.pvd_addr, session_start + 16); - set_731 (bi_table.file_addr, de->starting_block); - set_731 (bi_table.file_length, de->size); - set_731 (bi_table.file_checksum, bi_checksum); - - if (fwrite (&bi_table, 1, sizeof (bi_table), bootimage) != sizeof (bi_table)) - error (1, errno, _("Error writing to boot image (%s)"), bootimage); - fclose (bootimage); - } - -} /* get_torito_desc(... */ - -/* - * Function to write the EVD for the disc. - */ -static int FDECL1(tvd_write, FILE *, outfile) -{ - /* - * Next we write out the boot volume descriptor for the disc - */ - get_torito_desc(&gboot_desc); - xfwrite(&gboot_desc, 1, 2048, outfile); - last_extent_written ++; - return 0; -} - -struct output_fragment torito_desc = {NULL, oneblock_size, NULL, tvd_write}; diff --git a/util/mkisofs/exclude.h b/util/mkisofs/exclude.h deleted file mode 100644 index ac1a561ad..000000000 --- a/util/mkisofs/exclude.h +++ /dev/null @@ -1,10 +0,0 @@ -/* - * 9-Dec-93 R.-D. Marzusch, marzusch@odiehh.hanse.de: - * added 'exclude' option (-x) to specify pathnames NOT to be included in - * CD image. - * - * $Id: exclude.h,v 1.2 1999/03/02 03:41:25 eric Exp $ - */ - -void exclude __PR((char * fn)); -int is_excluded __PR((char * fn)); diff --git a/util/mkisofs/hash.c b/util/mkisofs/hash.c deleted file mode 100644 index 41e76b342..000000000 --- a/util/mkisofs/hash.c +++ /dev/null @@ -1,225 +0,0 @@ -/* - * File hash.c - generate hash tables for iso9660 filesystem. - - Written by Eric Youngdale (1993). - - Copyright 1993 Yggdrasil Computing, Incorporated - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#include -#include "config.h" -#include "mkisofs.h" - -#define NR_HASH 1024 - -#define HASH_FN(DEV, INO) ((DEV + INO + (INO >> 2) + (INO << 8)) % NR_HASH) - -static struct file_hash * hash_table[NR_HASH] = {0,}; - -void FDECL1(add_hash, struct directory_entry *, spnt){ - struct file_hash * s_hash; - unsigned int hash_number; - - if(spnt->size == 0 || spnt->starting_block == 0) - if(spnt->size != 0 || spnt->starting_block != 0) { - fprintf(stderr,"Non zero-length file assigned zero extent.\n"); - exit(1); - }; - - if (spnt->dev == (dev_t) UNCACHED_DEVICE || spnt->inode == UNCACHED_INODE) return; - hash_number = HASH_FN((unsigned int) spnt->dev, (unsigned int) spnt->inode); - -#if 0 - if (verbose > 1) fprintf(stderr,"%s ",spnt->name); -#endif - s_hash = (struct file_hash *) e_malloc(sizeof(struct file_hash)); - s_hash->next = hash_table[hash_number]; - s_hash->inode = spnt->inode; - s_hash->dev = spnt->dev; - s_hash->starting_block = spnt->starting_block; - s_hash->size = spnt->size; - hash_table[hash_number] = s_hash; -} - -struct file_hash * FDECL2(find_hash, dev_t, dev, ino_t, inode){ - unsigned int hash_number; - struct file_hash * spnt; - hash_number = HASH_FN((unsigned int) dev, (unsigned int) inode); - if (dev == (dev_t) UNCACHED_DEVICE || inode == UNCACHED_INODE) return NULL; - - spnt = hash_table[hash_number]; - while(spnt){ - if(spnt->inode == inode && spnt->dev == dev) return spnt; - spnt = spnt->next; - }; - return NULL; -} - - -static struct file_hash * directory_hash_table[NR_HASH] = {0,}; - -void FDECL2(add_directory_hash, dev_t, dev, ino_t, inode){ - struct file_hash * s_hash; - unsigned int hash_number; - - if (dev == (dev_t) UNCACHED_DEVICE || inode == UNCACHED_INODE) return; - hash_number = HASH_FN((unsigned int) dev, (unsigned int) inode); - - s_hash = (struct file_hash *) e_malloc(sizeof(struct file_hash)); - s_hash->next = directory_hash_table[hash_number]; - s_hash->inode = inode; - s_hash->dev = dev; - directory_hash_table[hash_number] = s_hash; -} - -struct file_hash * FDECL2(find_directory_hash, dev_t, dev, ino_t, inode){ - unsigned int hash_number; - struct file_hash * spnt; - hash_number = HASH_FN((unsigned int) dev, (unsigned int) inode); - if (dev == (dev_t) UNCACHED_DEVICE || inode == UNCACHED_INODE) return NULL; - - spnt = directory_hash_table[hash_number]; - while(spnt){ - if(spnt->inode == inode && spnt->dev == dev) return spnt; - spnt = spnt->next; - }; - return NULL; -} - -struct name_hash -{ - struct name_hash * next; - struct directory_entry * de; -}; - -#define NR_NAME_HASH 128 - -static struct name_hash * name_hash_table[NR_NAME_HASH] = {0,}; - -/* - * Find the hash bucket for this name. - */ -static unsigned int FDECL1(name_hash, const char *, name) -{ - unsigned int hash = 0; - const char * p; - - p = name; - - while (*p) - { - /* - * Don't hash the iso9660 version number. This way - * we can detect duplicates in cases where we have - * directories (i.e. foo) and non-directories - * (i.e. foo;1). - */ - if( *p == ';' ) - { - break; - } - hash = (hash << 15) + (hash << 3) + (hash >> 3) + *p++; - } - return hash % NR_NAME_HASH; -} - -void FDECL1(add_file_hash, struct directory_entry *, de){ - struct name_hash * new; - int hash; - - new = (struct name_hash *) e_malloc(sizeof(struct name_hash)); - new->de = de; - new->next = NULL; - hash = name_hash(de->isorec.name); - - /* Now insert into the hash table */ - new->next = name_hash_table[hash]; - name_hash_table[hash] = new; -} - -struct directory_entry * FDECL1(find_file_hash, char *, name) -{ - struct name_hash * nh; - char * p1; - char * p2; - - for(nh = name_hash_table[name_hash(name)]; nh; nh = nh->next) - { - p1 = name; - p2 = nh->de->isorec.name; - - /* - * Look for end of string, or a mismatch. - */ - while(1==1) - { - if( (*p1 == '\0' || *p1 == ';') - || (*p2 == '\0' || *p2 == ';') - || (*p1 != *p2) ) - { - break; - } - p1++; - p2++; - } - - /* - * If we are at the end of both strings, then - * we have a match. - */ - if( (*p1 == '\0' || *p1 == ';') - && (*p2 == '\0' || *p2 == ';') ) - { - return nh->de; - } - } - return NULL; -} - -int FDECL1(delete_file_hash, struct directory_entry *, de){ - struct name_hash * nh, *prev; - int hash; - - prev = NULL; - hash = name_hash(de->isorec.name); - for(nh = name_hash_table[hash]; nh; nh = nh->next) { - if(nh->de == de) break; - prev = nh; - } - if(!nh) return 1; - if(!prev) - name_hash_table[hash] = nh->next; - else - prev->next = nh->next; - free(nh); - return 0; -} - -void flush_file_hash(){ - struct name_hash * nh, *nh1; - int i; - - for(i=0; inext; - free(nh); - nh = nh1; - } - name_hash_table[i] = NULL; - - } -} diff --git a/util/mkisofs/include/fctldefs.h b/util/mkisofs/include/fctldefs.h deleted file mode 100644 index de6b6a394..000000000 --- a/util/mkisofs/include/fctldefs.h +++ /dev/null @@ -1,57 +0,0 @@ -/* @(#)fctldefs.h 1.2 98/10/08 Copyright 1996 J. Schilling */ -/* - * Generic header for users of open(), creat() and chmod() - * - * Copyright (c) 1996 J. Schilling - */ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _FCTLDEFS_H -#define _FCTLDEFS_H - -#ifndef _MCONFIG_H -#include -#endif - -#include -#include - -#ifdef HAVE_FCNTL_H - -# include - -#else /* HAVE_FCNTL_H */ - -# include - -#endif /* HAVE_FCNTL_H */ - -/* - * Do not define more than O_RDONLY / O_WRONLY / O_RDWR - * The values may differ. - */ -#ifndef O_RDONLY -#define O_RDONLY 0 -#endif -#ifndef O_WRONLY -#define O_WRONLY 1 -#endif -#ifndef O_RDWR -#define O_RDWR 2 -#endif - -#endif /* _FCTLDEFS_H */ diff --git a/util/mkisofs/include/mconfig.h b/util/mkisofs/include/mconfig.h deleted file mode 100644 index 1891d7ded..000000000 --- a/util/mkisofs/include/mconfig.h +++ /dev/null @@ -1,253 +0,0 @@ -/* @(#)mconfig.h 1.24 98/12/14 Copyright 1995 J. Schilling */ -/* - * definitions for machine configuration - * - * Copyright (c) 1995 J. Schilling - * - * This file must be included before any other file. - * Use only cpp instructions. - * - * NOTE: SING: (Schily Is Not Gnu) - */ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _MCONFIG_H -#define _MCONFIG_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(unix) || defined(__unix) || defined(__unix__) -# define IS_UNIX -#endif - -#ifdef __MSDOS__ -# define IS_MSDOS -#endif - -#if defined(tos) || defined(__tos) -# define IS_TOS -#endif - -#ifdef THINK_C -# define IS_MAC -#endif - -#if defined(sun) || defined(__sun) || defined(__sun__) -# define IS_SUN -#endif - -#if defined(__CYGWIN32__) -# define IS_GCC_WIN32 -#endif - -/*--------------------------------------------------------------------------*/ -/* - * Some magic that cannot (yet) be figured out with autoconf. - */ - -#ifdef sparc -# ifndef HAVE_LDSTUB -# define HAVE_LDSTUB -# endif -# ifndef HAVE_SCANSTACK -# define HAVE_SCANSTACK -# endif -#endif -#if defined(__i386_) || defined(i386) -# ifndef HAVE_XCHG -# define HAVE_XCHG -# endif -# ifndef HAVE_SCANSTACK -# define HAVE_SCANSTACK -# endif -#endif - -#if defined(SOL2) || defined(SOL2) || defined(S5R4) || defined(__S5R4) \ - || defined(SVR4) -# ifndef __SVR4 -# define __SVR4 -# endif -#endif - -#ifdef __SVR4 -# ifndef SVR4 -# define SVR4 -# endif -#endif - -/* - * SunOS 4.x / SunOS 5.x - */ -#if defined(IS_SUN) -# define HAVE_GETAV0 -#endif - -/* - * AIX - */ -#if defined(_IBMR2) || defined(_AIX) -# define IS_UNIX /* ??? really ??? */ -#endif - -/* - * Silicon Graphics (must be before SVR4) - */ -#if defined(sgi) || defined(__sgi) -# define __NOT_SVR4__ /* Not a real SVR4 implementation */ -#endif - -/* - * Data General - */ -#if defined(__DGUX__) -#ifdef XXXXXXX -# undef HAVE_MTGET_DSREG -# undef HAVE_MTGET_RESID -# undef HAVE_MTGET_FILENO -# undef HAVE_MTGET_BLKNO -#endif -# define mt_type mt_model -# define mt_dsreg mt_status1 -# define mt_erreg mt_status2 - /* - * DGUX hides its flock as dg_flock. - */ -# define HAVE_FLOCK -# define flock dg_flock - /* - * Use the BSD style wait on DGUX to get the resource usages of child - * processes. - */ -# define _BSD_WAIT_FLAVOR -#endif - -/* - * Apple Rhapsody - */ -#if defined(__NeXT__) && defined(__TARGET_OSNAME) && __TARGET_OSNAME == rhapsody -# define HAVE_OSDEF /* prevent later definitions to overwrite current */ -#endif - -/* - * NextStep - */ -#if defined(__NeXT__) && !defined(HAVE_OSDEF) -#define NO_PRINT_OVR -#undef HAVE_USG_STDIO /* - * NeXT Step 3.x uses __flsbuf(unsigned char , FILE *) - * instead of __flsbuf(int, FILE *) - */ -#endif - -/* - * NextStep 3.x has a broken linker that does not allow us to override - * these functions. - */ -#ifndef __OPRINTF__ - -#ifdef NO_PRINT_OVR -# define printf Xprintf -# define fprintf Xfprintf -# define sprintf Xsprintf -#endif - -#endif /* __OPRINTF__ */ - -/*--------------------------------------------------------------------------*/ -/* - * If there is no flock defined by the system, use emulation - * through fcntl record locking. - */ -#ifndef HAVE_FLOCK -#define LOCK_SH 1 /* shared lock */ -#define LOCK_EX 2 /* exclusive lock */ -#define LOCK_NB 4 /* don't block when locking */ -#define LOCK_UN 8 /* unlock */ -#endif - -#include - -/* - * gcc 2.x generally implements the long long type. - */ -#ifdef __GNUC__ -# if __GNUC__ > 1 -# ifndef HAVE_LONGLONG -# define HAVE_LONGLONG -# endif -# endif -#endif - -/* - * Convert to GNU name - */ -#ifdef HAVE_STDC_HEADERS -# ifndef STDC_HEADERS -# define STDC_HEADERS -# endif -#endif -/* - * Convert to SCHILY name - */ -#ifdef STDC_HEADERS -# ifndef HAVE_STDC_HEADERS -# define HAVE_STDC_HEADERS -# endif -#endif - -#ifdef IS_UNIX -# define PATH_DELIM '/' -# define PATH_DELIM_STR "/" -# define far -# define near -#endif - -#ifdef IS_GCC_WIN32 -# define PATH_DELIM '/' -# define PATH_DELIM_STR "/" -# define far -# define near -#endif - -#ifdef IS_MSDOS -# define PATH_DELIM '\\' -# define PATH_DELIM_STR "\\" -#endif - -#ifdef IS_TOS -# define PATH_DELIM '\\' -# define PATH_DELIM_STR "\\" -# define far -# define near -#endif - -#ifdef IS_MAC -# define PATH_DELIM ':' -# define PATH_DELIM_STR ":" -# define far -# define near -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* _MCONFIG_H */ diff --git a/util/mkisofs/include/prototyp.h b/util/mkisofs/include/prototyp.h deleted file mode 100644 index c74ae0af8..000000000 --- a/util/mkisofs/include/prototyp.h +++ /dev/null @@ -1,74 +0,0 @@ -/* @(#)prototyp.h 1.7 98/10/08 Copyright 1995 J. Schilling */ -/* - * Definitions for dealing with ANSI / KR C-Compilers - * - * Copyright (c) 1995 J. Schilling - */ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _PROTOTYP_H -#define _PROTOTYP_H - -#ifndef PROTOTYPES - /* - * If this has already been defined, - * someone else knows better than us... - */ -# ifdef __STDC__ -# if __STDC__ /* ANSI C */ -# define PROTOTYPES -# endif -# if defined(sun) && __STDC__ - 0 == 0 /* Sun C */ -# define PROTOTYPES -# endif -# endif -#endif /* PROTOTYPES */ - -/* - * If we have prototypes, we should have stdlib.h string.h stdarg.h - */ -#ifdef PROTOTYPES -#if !(defined(SABER) && defined(sun)) -# ifndef HAVE_STDARG_H -# define HAVE_STDARG_H -# endif -#endif -# ifndef HAVE_STDLIB_H -# define HAVE_STDLIB_H -# endif -# ifndef HAVE_STRING_H -# define HAVE_STRING_H -# endif -# ifndef HAVE_STDC_HEADERS -# define HAVE_STDC_HEADERS -# endif -# ifndef STDC_HEADERS -# define STDC_HEADERS /* GNU name */ -# endif -#endif - -#ifdef NO_PROTOTYPES /* Force not to use prototypes */ -# undef PROTOTYPES -#endif - -#ifdef PROTOTYPES -# define __PR(a) a -#else -# define __PR(a) () -#endif - -#endif /* _PROTOTYP_H */ diff --git a/util/mkisofs/include/statdefs.h b/util/mkisofs/include/statdefs.h deleted file mode 100644 index 0e34805ce..000000000 --- a/util/mkisofs/include/statdefs.h +++ /dev/null @@ -1,139 +0,0 @@ -/* @(#)statdefs.h 1.1 98/11/22 Copyright 1998 J. Schilling */ -/* - * Definitions for stat() file mode - * - * Copyright (c) 1998 J. Schilling - */ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _STATDEFS_H -#define _STATDEFS_H - -#ifndef _MCONFIG_H -#include -#endif - -#ifdef STAT_MACROS_BROKEN -#undef S_ISFIFO /* Named pipe */ -#undef S_ISCHR /* Character special */ -#undef S_ISMPC /* UNUSED multiplexed c */ -#undef S_ISDIR /* Directory */ -#undef S_ISNAM /* Named file (XENIX) */ -#undef S_ISBLK /* Block special */ -#undef S_ISMPB /* UNUSED multiplexed b */ -#undef S_ISREG /* Regular file */ -#undef S_ISCNT /* Contiguous file */ -#undef S_ISLNK /* Symbolic link */ -#undef S_ISSHAD /* Solaris shadow inode */ -#undef S_ISSOCK /* UNIX domain socket */ -#undef S_ISDOOR /* Solaris DOOR */ -#endif - -#ifndef S_ISFIFO /* Named pipe */ -# ifdef S_IFIFO -# define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO) -# else -# define S_ISFIFO(m) (0) -# endif -#endif -#ifndef S_ISCHR /* Character special */ -# ifdef S_IFCHR -# define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR) -# else -# define S_ISCHR(m) (0) -# endif -#endif -#ifndef S_ISMPC /* UNUSED multiplexed c */ -# ifdef S_IFMPC -# define S_ISMPC(m) (((m) & S_IFMT) == S_IFMPC) -# else -# define S_ISMPC(m) (0) -# endif -#endif -#ifndef S_ISDIR /* Directory */ -# ifdef S_IFDIR -# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) -# else -# define S_ISDIR(m) (0) -# endif -#endif -#ifndef S_ISNAM /* Named file (XENIX) */ -# ifdef S_IFNAM -# define S_ISNAM(m) (((m) & S_IFMT) == S_IFNAM) -# else -# define S_ISNAM(m) (0) -# endif -#endif -#ifndef S_ISBLK /* Block special */ -# ifdef S_IFBLK -# define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK) -# else -# define S_ISBLK(m) (0) -# endif -#endif -#ifndef S_ISMPB /* UNUSED multiplexed b */ -# ifdef S_IFMPB -# define S_ISMPB(m) (((m) & S_IFMT) == S_IFMPB) -# else -# define S_ISMPB(m) (0) -# endif -#endif -#ifndef S_ISREG /* Regular file */ -# ifdef S_IFREG -# define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) -# else -# define S_ISREG(m) (0) -# endif -#endif -#ifndef S_ISCNT /* Contiguous file */ -# ifdef S_IFCNT -# define S_ISCNT(m) (((m) & S_IFMT) == S_IFCNT) -# else -# define S_ISCNT(m) (0) -# endif -#endif -#ifndef S_ISLNK /* Symbolic link */ -# ifdef S_IFLNK -# define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) -# else -# define S_ISLNK(m) (0) -# endif -#endif -#ifndef S_ISSHAD /* Solaris shadow inode */ -# ifdef S_IFSHAD -# define S_ISSHAD(m) (((m) & S_IFMT) == S_IFSHAD) -# else -# define S_ISSHAD(m) (0) -# endif -#endif -#ifndef S_ISSOCK /* UNIX domain socket */ -# ifdef S_IFSOCK -# define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK) -# else -# define S_ISSOCK(m) (0) -# endif -#endif -#ifndef S_ISDOOR /* Solaris DOOR */ -# ifdef S_IFDOOR -# define S_ISDOOR(m) (((m) & S_IFMT) == S_IFDOOR) -# else -# define S_ISDOOR(m) (0) -# endif -#endif - -#endif /* _STATDEFS_H */ - diff --git a/util/mkisofs/iso9660.h b/util/mkisofs/iso9660.h deleted file mode 100644 index 78a05db92..000000000 --- a/util/mkisofs/iso9660.h +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Header file iso9660.h - assorted structure definitions and typecasts. - * specific to iso9660 filesystem. - - Written by Eric Youngdale (1993). - - Copyright 1993 Yggdrasil Computing, Incorporated - - Copyright (C) 2009 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, see . - */ - -/* - * $Id: iso9660.h,v 1.2 1997/05/17 15:46:44 eric Exp $ - */ - -#ifndef _ISOFS_FS_H -#define _ISOFS_FS_H - -/* - * The isofs filesystem constants/structures - */ - -/* This part borrowed from the bsd386 isofs */ -#define ISODCL(from, to) (to - from + 1) - -struct iso_volume_descriptor { - char type[ISODCL(1,1)]; /* 711 */ - char id[ISODCL(2,6)]; - char version[ISODCL(7,7)]; - char data[ISODCL(8,2048)]; -}; - -/* volume descriptor types */ -#define ISO_VD_PRIMARY 1 -#define ISO_VD_SUPPLEMENTARY 2 /* Used by Joliet */ -#define ISO_VD_END 255 - -#define ISO_STANDARD_ID "CD001" - -#define EL_TORITO_ID "EL TORITO SPECIFICATION" -#define EL_TORITO_ARCH_x86 0 -#define EL_TORITO_ARCH_PPC 1 -#define EL_TORITO_ARCH_MAC 2 -#define EL_TORITO_BOOTABLE 0x88 -#define EL_TORITO_MEDIA_NOEMUL 0 -#define EL_TORITO_MEDIA_12FLOP 1 -#define EL_TORITO_MEDIA_144FLOP 2 -#define EL_TORITO_MEDIA_288FLOP 3 -#define EL_TORITO_MEDIA_HD 4 - -struct iso_primary_descriptor { - char type [ISODCL ( 1, 1)]; /* 711 */ - char id [ISODCL ( 2, 6)]; - char version [ISODCL ( 7, 7)]; /* 711 */ - char unused1 [ISODCL ( 8, 8)]; - char system_id [ISODCL ( 9, 40)]; /* achars */ - char volume_id [ISODCL ( 41, 72)]; /* dchars */ - char unused2 [ISODCL ( 73, 80)]; - char volume_space_size [ISODCL ( 81, 88)]; /* 733 */ - char escape_sequences [ISODCL ( 89, 120)]; - char volume_set_size [ISODCL (121, 124)]; /* 723 */ - char volume_sequence_number [ISODCL (125, 128)]; /* 723 */ - char logical_block_size [ISODCL (129, 132)]; /* 723 */ - char path_table_size [ISODCL (133, 140)]; /* 733 */ - char type_l_path_table [ISODCL (141, 144)]; /* 731 */ - char opt_type_l_path_table [ISODCL (145, 148)]; /* 731 */ - char type_m_path_table [ISODCL (149, 152)]; /* 732 */ - char opt_type_m_path_table [ISODCL (153, 156)]; /* 732 */ - char root_directory_record [ISODCL (157, 190)]; /* 9.1 */ - char volume_set_id [ISODCL (191, 318)]; /* dchars */ - char publisher_id [ISODCL (319, 446)]; /* achars */ - char preparer_id [ISODCL (447, 574)]; /* achars */ - char application_id [ISODCL (575, 702)]; /* achars */ - char copyright_file_id [ISODCL (703, 739)]; /* 7.5 dchars */ - char abstract_file_id [ISODCL (740, 776)]; /* 7.5 dchars */ - char bibliographic_file_id [ISODCL (777, 813)]; /* 7.5 dchars */ - char creation_date [ISODCL (814, 830)]; /* 8.4.26.1 */ - char modification_date [ISODCL (831, 847)]; /* 8.4.26.1 */ - char expiration_date [ISODCL (848, 864)]; /* 8.4.26.1 */ - char effective_date [ISODCL (865, 881)]; /* 8.4.26.1 */ - char file_structure_version [ISODCL (882, 882)]; /* 711 */ - char unused4 [ISODCL (883, 883)]; - char application_data [ISODCL (884, 1395)]; - char unused5 [ISODCL (1396, 2048)]; -}; - -/* El Torito Boot Record Volume Descriptor */ -struct eltorito_boot_descriptor { - char id [ISODCL ( 1, 1)]; /* 711 */ - char id2 [ISODCL ( 2, 6)]; - char version [ISODCL ( 7, 7)]; /* 711 */ - char system_id [ISODCL ( 8, 39)]; - char unused2 [ISODCL ( 40, 71)]; - char bootcat_ptr [ISODCL ( 72 , 75)]; - char unused5 [ISODCL ( 76, 2048)]; -}; - -/* Validation entry for El Torito */ -struct eltorito_validation_entry { - char headerid [ISODCL ( 1, 1)]; /* 711 */ - char arch [ISODCL ( 2, 2)]; - char pad1 [ISODCL ( 3, 4)]; /* 711 */ - char id [ISODCL ( 5, 28)]; - char cksum [ISODCL ( 29, 30)]; - char key1 [ISODCL ( 31, 31)]; - char key2 [ISODCL ( 32, 32)]; -}; - -/* El Torito initial/default entry in boot catalog */ -struct eltorito_defaultboot_entry { - char boot_id [ISODCL ( 1, 1)]; /* 711 */ - char boot_media [ISODCL ( 2, 2)]; - char loadseg [ISODCL ( 3, 4)]; /* 711 */ - char arch [ISODCL ( 5, 5)]; - char pad1 [ISODCL ( 6, 6)]; - char nsect [ISODCL ( 7, 8)]; - char bootoff [ISODCL ( 9, 12)]; - char pad2 [ISODCL ( 13, 32)]; -}; - -/* El Torito boot information table */ -struct eltorito_boot_info -{ - /* Address of Primary Volume Descriptor. */ - char pvd_addr[ISODCL (1, 4)]; - /* Boot file address. */ - char file_addr[ISODCL (5, 8)]; - /* Boot file length. */ - char file_length[ISODCL (9, 12)]; - /* Boot file checksum. */ - char file_checksum[ISODCL (13, 16)]; - char dummy[ISODCL (17, 56)]; -}; - - -/* We use this to help us look up the parent inode numbers. */ - -struct iso_path_table{ - unsigned char name_len[2]; /* 721 */ - char extent[4]; /* 731 */ - char parent[2]; /* 721 */ - char name[1]; -}; - -struct iso_directory_record { - unsigned char length [ISODCL (1, 1)]; /* 711 */ - char ext_attr_length [ISODCL (2, 2)]; /* 711 */ - char extent [ISODCL (3, 10)]; /* 733 */ - char size [ISODCL (11, 18)]; /* 733 */ - char date [ISODCL (19, 25)]; /* 7 by 711 */ - char flags [ISODCL (26, 26)]; - char file_unit_size [ISODCL (27, 27)]; /* 711 */ - char interleave [ISODCL (28, 28)]; /* 711 */ - char volume_sequence_number [ISODCL (29, 32)]; /* 723 */ - unsigned char name_len [ISODCL (33, 33)]; /* 711 */ - char name [34]; /* Not really, but we need something here */ -}; -#endif - - - diff --git a/util/mkisofs/joliet.c b/util/mkisofs/joliet.c deleted file mode 100644 index b3c755792..000000000 --- a/util/mkisofs/joliet.c +++ /dev/null @@ -1,1023 +0,0 @@ -/* - * File joliet.c - handle Win95/WinNT long file/unicode extensions for iso9660. - - Copyright 1997 Eric Youngdale. - - Copyright (C) 2009 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, see . - */ - -/* - * Joliet extensions for ISO9660. These are spottily documented by - * Microsoft. In their infinite stupidity, they completely ignored - * the possibility of using an SUSP record with the long filename - * in it, and instead wrote out a duplicate directory tree with the - * long filenames in it. - * - * I am not sure why they did this. One reason is that they get the path - * tables with the long filenames in them. - * - * There are two basic principles to Joliet, and the non-Unicode variant - * known as Romeo. Long filenames seem to be the main one, and the second - * is that the character set and a few other things is substantially relaxed. - * - * The SVD is identical to the PVD, except: - * - * Id is 2, not 1 (indicates SVD). - * escape_sequences contains UCS-2 indicator (levels 1, 2 or 3). - * The root directory record points to a different extent (with different - * size). - * There are different path tables for the two sets of directory trees. - * - * The following fields are recorded in Unicode: - * system_id - * volume_id - * volume_set_id - * publisher_id - * preparer_id - * application_id - * copyright_file_id - * abstract_file_id - * bibliographic_file_id - * - * Unicode strings are always encoded in big-endian format. - * - * In a directory record, everything is the same as with iso9660, except - * that the name is recorded in unicode. The name length is specified in - * total bytes, not in number of unicode characters. - * - * The character set used for the names is different with UCS - the - * restrictions are that the following are not allowed: - * - * Characters (00)(00) through (00)(1f) (control chars) - * (00)(2a) '*' - * (00)(2f) '/' - * (00)(3a) ':' - * (00)(3b) ';' - * (00)(3f) '?' - * (00)(5c) '\' - */ -#include "config.h" -#include "mkisofs.h" -#include "iso9660.h" - -#include -#include -#include - -static unsigned int jpath_table_index; -static struct directory ** jpathlist; -static int next_jpath_index = 1; -static int sort_goof; - -static int generate_joliet_path_tables __PR((void)); -static int DECL(joliet_sort_directory, (struct directory_entry ** sort_dir)); -static void DECL(assign_joliet_directory_addresses, (struct directory * node)); -static int jroot_gen __PR((void)); - -/* - * Function: convert_to_unicode - * - * Purpose: Perform a 1/2 assed unicode conversion on a text - * string. - * - * Notes: - */ -static void FDECL3(convert_to_unicode, unsigned char *, buffer, int, size, char *, source ) -{ - unsigned char * tmpbuf; - int i; - int j; - - /* - * If we get a NULL pointer for the source, it means we have an inplace - * copy, and we need to make a temporary working copy first. - */ - if( source == NULL ) - { - tmpbuf = (uint8_t *) e_malloc(size); - memcpy( tmpbuf, buffer, size); - } - else - { - tmpbuf = (uint8_t *)source; - } - - /* - * Now start copying characters. If the size was specified to be 0, then - * assume the input was 0 terminated. - */ - j = 0; - for(i=0; i < size ; i += 2, j++) - { - buffer[i] = 0; - /* - * JS integrated from: Achim_Kaiser@t-online.de - * - * Let all valid unicode characters pass through (assuming ISO-8859-1). - * Others are set to '_' . - */ - if( tmpbuf[j] != 0 && - (tmpbuf[j] <= 0x1f || (tmpbuf[j] >= 0x7F && tmpbuf[j] <= 0xA0)) ) - { - buffer[i+1] = '_'; - } - else - { - switch(tmpbuf[j]) - { - case '*': - case '/': - case ':': - case ';': - case '?': - case '\\': - /* - * Even Joliet has some standards as to what is allowed in a pathname. - * Pretty tame in comparison to what DOS restricts you to. - */ - buffer[i+1] = '_'; - break; - default: - buffer[i+1] = tmpbuf[j]; - break; - } - } - } - - if( source == NULL ) - { - free(tmpbuf); - } -} - -/* - * Function: joliet_strlen - * - * Purpose: Return length in bytes of string after conversion to unicode. - * - * Notes: This is provided mainly as a convenience so that when more intelligent - * Unicode conversion for either Multibyte or 8-bit codes is available that - * we can easily adapt. - */ -static int FDECL1(joliet_strlen, const char *, string) -{ - int rtn; - - rtn = strlen(string) << 1; - - /* - * We do clamp the maximum length of a Joliet string to be the - * maximum path size. This helps to ensure that we don't completely - * bolix things up with very long paths. The Joliet specs say - * that the maximum length is 128 bytes, or 64 unicode characters. - */ - if( rtn > 0x80) - { - rtn = 0x80; - } - return rtn; -} - -/* - * Function: get_joliet_vol_desc - * - * Purpose: generate a Joliet compatible volume desc. - * - * Notes: Assume that we have the non-joliet vol desc - * already present in the buffer. Just modifiy the - * appropriate fields. - */ -static void FDECL1(get_joliet_vol_desc, struct iso_primary_descriptor *, jvol_desc) -{ - jvol_desc->type[0] = ISO_VD_SUPPLEMENTARY; - - /* - * For now, always do Unicode level 3. I don't really know what 1 and 2 - * are - perhaps a more limited Unicode set. - * - * FIXME(eric) - how does Romeo fit in here? As mkisofs just - * "expands" 8 bit character codes to 16 bits and does nothing - * special with the Unicode characters, therefore shouldn't mkisofs - * really be stating that it's using UCS-2 Level 1, not Level 3 for - * the Joliet directory tree. - */ - strcpy(jvol_desc->escape_sequences, "%/@"); - - /* - * Until we have Unicode path tables, leave these unset. - */ - set_733((char *) jvol_desc->path_table_size, jpath_table_size); - set_731(jvol_desc->type_l_path_table, jpath_table[0]); - set_731(jvol_desc->opt_type_l_path_table, jpath_table[1]); - set_732(jvol_desc->type_m_path_table, jpath_table[2]); - set_732(jvol_desc->opt_type_m_path_table, jpath_table[3]); - - /* - * Set this one up. - */ - memcpy(jvol_desc->root_directory_record, &jroot_record, - sizeof(struct iso_directory_record)); - - /* - * Finally, we have a bunch of strings to convert to Unicode. - * FIXME(eric) - I don't know how to do this in general, so we will - * just be really lazy and do a char -> short conversion. We probably - * will want to filter any characters >= 0x80. - */ - convert_to_unicode((uint8_t *)jvol_desc->system_id, sizeof(jvol_desc->system_id), NULL); - convert_to_unicode((uint8_t *)jvol_desc->volume_id, sizeof(jvol_desc->volume_id), NULL); - convert_to_unicode((uint8_t *)jvol_desc->volume_set_id, sizeof(jvol_desc->volume_set_id), NULL); - convert_to_unicode((uint8_t *)jvol_desc->publisher_id, sizeof(jvol_desc->publisher_id), NULL); - convert_to_unicode((uint8_t *)jvol_desc->preparer_id, sizeof(jvol_desc->preparer_id), NULL); - convert_to_unicode((uint8_t *)jvol_desc->application_id, sizeof(jvol_desc->application_id), NULL); - convert_to_unicode((uint8_t *)jvol_desc->copyright_file_id, sizeof(jvol_desc->copyright_file_id), NULL); - convert_to_unicode((uint8_t *)jvol_desc->abstract_file_id, sizeof(jvol_desc->abstract_file_id), NULL); - convert_to_unicode((uint8_t *)jvol_desc->bibliographic_file_id, sizeof(jvol_desc->bibliographic_file_id), NULL); - - -} - -static void FDECL1(assign_joliet_directory_addresses, struct directory *, node) -{ - int dir_size; - struct directory * dpnt; - - dpnt = node; - - while (dpnt) - { - if( (dpnt->dir_flags & INHIBIT_JOLIET_ENTRY) == 0 ) - { - /* - * If we already have an extent for this (i.e. it came from - * a multisession disc), then don't reassign a new extent. - */ - dpnt->jpath_index = next_jpath_index++; - if( dpnt->jextent == 0 ) - { - dpnt->jextent = last_extent; - dir_size = (dpnt->jsize + (SECTOR_SIZE - 1)) >> 11; - last_extent += dir_size; - } - } - - /* skip if hidden - but not for the rr_moved dir */ - if(dpnt->subdir && (!(dpnt->dir_flags & INHIBIT_JOLIET_ENTRY) || dpnt == reloc_dir)) - { - assign_joliet_directory_addresses(dpnt->subdir); - } - dpnt = dpnt->next; - } -} - -static -void FDECL1(build_jpathlist, struct directory *, node) -{ - struct directory * dpnt; - - dpnt = node; - - while (dpnt) - - { - if( (dpnt->dir_flags & INHIBIT_JOLIET_ENTRY) == 0 ) - { - jpathlist[dpnt->jpath_index] = dpnt; - } - if(dpnt->subdir) build_jpathlist(dpnt->subdir); - dpnt = dpnt->next; - } -} /* build_jpathlist(... */ - -static int FDECL2(joliet_compare_paths, void const *, r, void const *, l) -{ - struct directory const *ll = *(struct directory * const *)l; - struct directory const *rr = *(struct directory * const *)r; - int rparent, lparent; - - rparent = rr->parent->jpath_index; - lparent = ll->parent->jpath_index; - if( rr->parent == reloc_dir ) - { - rparent = rr->self->parent_rec->filedir->jpath_index; - } - - if( ll->parent == reloc_dir ) - { - lparent = ll->self->parent_rec->filedir->jpath_index; - } - - if (rparent < lparent) - { - return -1; - } - - if (rparent > lparent) - { - return 1; - } - - return strcmp(rr->self->name, ll->self->name); - -} /* compare_paths(... */ - -static int generate_joliet_path_tables() -{ - struct directory_entry * de; - struct directory * dpnt; - int fix; - int j; - int namelen; - char * npnt; - char * npnt1; - int tablesize; - - /* - * First allocate memory for the tables and initialize the memory - */ - tablesize = jpath_blocks << 11; - jpath_table_m = (char *) e_malloc(tablesize); - jpath_table_l = (char *) e_malloc(tablesize); - memset(jpath_table_l, 0, tablesize); - memset(jpath_table_m, 0, tablesize); - - if( next_jpath_index > 0xffff ) - { - fprintf (stderr, _("Unable to generate sane path tables - too many directories (%d)\n"), - next_jpath_index); - exit (1); - } - /* - * Now start filling in the path tables. Start with root directory - */ - jpath_table_index = 0; - jpathlist = (struct directory **) e_malloc(sizeof(struct directory *) - * next_jpath_index); - memset(jpathlist, 0, sizeof(struct directory *) * next_jpath_index); - build_jpathlist(root); - - do - { - fix = 0; -#ifdef __STDC__ - qsort(&jpathlist[1], next_jpath_index-1, sizeof(struct directory *), - (int (*)(const void *, const void *))joliet_compare_paths); -#else - qsort(&jpathlist[1], next_jpath_index-1, sizeof(struct directory *), - joliet_compare_paths); -#endif - - for(j=1; jjpath_index != j) - { - jpathlist[j]->jpath_index = j; - fix++; - } - } - } while(fix); - - for(j=1; jde_name; - - npnt1 = strrchr(npnt, PATH_SEPARATOR); - if(npnt1) - { - npnt = npnt1 + 1; - } - - de = dpnt->self; - if(!de) - { - fprintf (stderr, _("Fatal goof - directory has amnesia\n")); - exit (1); - } - - namelen = joliet_strlen(de->name); - - if( dpnt == root ) - { - jpath_table_l[jpath_table_index] = 1; - jpath_table_m[jpath_table_index] = 1; - } - else - { - jpath_table_l[jpath_table_index] = namelen; - jpath_table_m[jpath_table_index] = namelen; - } - jpath_table_index += 2; - - set_731(jpath_table_l + jpath_table_index, dpnt->jextent); - set_732(jpath_table_m + jpath_table_index, dpnt->jextent); - jpath_table_index += 4; - - if( dpnt->parent != reloc_dir ) - { - set_721(jpath_table_l + jpath_table_index, - dpnt->parent->jpath_index); - set_722(jpath_table_m + jpath_table_index, - dpnt->parent->jpath_index); - } - else - { - set_721(jpath_table_l + jpath_table_index, - dpnt->self->parent_rec->filedir->jpath_index); - set_722(jpath_table_m + jpath_table_index, - dpnt->self->parent_rec->filedir->jpath_index); - } - - jpath_table_index += 2; - - /* - * The root directory is still represented in non-unicode fashion. - */ - if( dpnt == root ) - { - jpath_table_l[jpath_table_index] = 0; - jpath_table_m[jpath_table_index] = 0; - jpath_table_index ++; - } - else - { - convert_to_unicode((uint8_t *)jpath_table_l + jpath_table_index, - namelen, de->name); - convert_to_unicode((uint8_t *)jpath_table_m + jpath_table_index, - namelen, de->name); - jpath_table_index += namelen; - } - - if(jpath_table_index & 1) - { - jpath_table_index++; /* For odd lengths we pad */ - } - } - - free(jpathlist); - if(jpath_table_index != jpath_table_size) - { - fprintf(stderr, _("Joliet path table lengths do not match %d %d\n"), - jpath_table_index, - jpath_table_size); - } - return 0; -} /* generate_path_tables(... */ - -static void FDECL2(generate_one_joliet_directory, struct directory *, dpnt, FILE *, outfile) -{ - unsigned int dir_index; - char * directory_buffer; - int new_reclen; - struct directory_entry * s_entry; - struct directory_entry * s_entry1; - struct iso_directory_record jrec; - unsigned int total_size; - int cvt_len; - struct directory * finddir; - - total_size = (dpnt->jsize + (SECTOR_SIZE - 1)) & ~(SECTOR_SIZE - 1); - directory_buffer = (char *) e_malloc(total_size); - memset(directory_buffer, 0, total_size); - dir_index = 0; - - s_entry = dpnt->jcontents; - while(s_entry) - { - if(s_entry->de_flags & INHIBIT_JOLIET_ENTRY) { - s_entry = s_entry->jnext; - continue; - } - - /* - * If this entry was a directory that was relocated, we have a bit - * of trouble here. We need to dig out the real thing and put it - * back here. In the Joliet tree, there is no relocated rock - * ridge, as there are no depth limits to a directory tree. - */ - if( (s_entry->de_flags & RELOCATED_DIRECTORY) != 0 ) - { - for(s_entry1 = reloc_dir->contents; s_entry1; s_entry1 = s_entry1->next) - { - if( s_entry1->parent_rec == s_entry ) - { - break; - } - } - if( s_entry1 == NULL ) - { - /* - * We got trouble. - */ - fprintf (stderr, _("Unable to locate relocated directory\n")); - exit (1); - } - } - else - { - s_entry1 = s_entry; - } - - /* - * We do not allow directory entries to cross sector boundaries. - * Simply pad, and then start the next entry at the next sector - */ - new_reclen = s_entry1->jreclen; - if( (dir_index & (SECTOR_SIZE - 1)) + new_reclen >= SECTOR_SIZE ) - { - dir_index = (dir_index + (SECTOR_SIZE - 1)) & - ~(SECTOR_SIZE - 1); - } - - memcpy(&jrec, &s_entry1->isorec, sizeof(struct iso_directory_record) - - sizeof(s_entry1->isorec.name)); - - cvt_len = joliet_strlen(s_entry1->name); - - /* - * Fix the record length - this was the non-Joliet version we - * were seeing. - */ - jrec.name_len[0] = cvt_len; - jrec.length[0] = s_entry1->jreclen; - - /* - * If this is a directory, fix the correct size and extent - * number. - */ - if( (jrec.flags[0] & 2) != 0 ) - { - if(strcmp(s_entry1->name,".") == 0) - { - jrec.name_len[0] = 1; - set_733((char *) jrec.extent, dpnt->jextent); - set_733((char *) jrec.size, ROUND_UP(dpnt->jsize)); - } - else if(strcmp(s_entry1->name,"..") == 0) - { - jrec.name_len[0] = 1; - if( dpnt->parent == reloc_dir ) - { - set_733((char *) jrec.extent, dpnt->self->parent_rec->filedir->jextent); - set_733((char *) jrec.size, ROUND_UP(dpnt->self->parent_rec->filedir->jsize)); - } - else - - { - set_733((char *) jrec.extent, dpnt->parent->jextent); - set_733((char *) jrec.size, ROUND_UP(dpnt->parent->jsize)); - } - } - else - { - if( (s_entry->de_flags & RELOCATED_DIRECTORY) != 0 ) - { - finddir = reloc_dir->subdir; - } - else - { - finddir = dpnt->subdir; - } - while(1==1) - { - if(finddir->self == s_entry1) break; - finddir = finddir->next; - if(!finddir) - { - fprintf (stderr, _("Fatal goof - unable to find directory location\n")); - exit (1); - } - } - set_733((char *) jrec.extent, finddir->jextent); - set_733((char *) jrec.size, ROUND_UP(finddir->jsize)); - } - } - - memcpy(directory_buffer + dir_index, &jrec, - sizeof(struct iso_directory_record) - - sizeof(s_entry1->isorec.name)); - - - dir_index += sizeof(struct iso_directory_record) - - sizeof (s_entry1->isorec.name); - - /* - * Finally dump the Unicode version of the filename. - * Note - . and .. are the same as with non-Joliet discs. - */ - if( (jrec.flags[0] & 2) != 0 - && strcmp(s_entry1->name, ".") == 0 ) - { - directory_buffer[dir_index++] = 0; - } - else if( (jrec.flags[0] & 2) != 0 - && strcmp(s_entry1->name, "..") == 0 ) - { - directory_buffer[dir_index++] = 1; - } - else - { - convert_to_unicode((uint8_t *)directory_buffer + dir_index, - cvt_len, - s_entry1->name); - dir_index += cvt_len; - } - - if(dir_index & 1) - { - directory_buffer[dir_index++] = 0; - } - - s_entry = s_entry->jnext; - } - - if(dpnt->jsize != dir_index) - { - fprintf (stderr, _("Unexpected joliet directory length %d %d %s\n"), - dpnt->jsize, dir_index, dpnt->de_name); - } - - xfwrite(directory_buffer, 1, total_size, outfile); - last_extent_written += total_size >> 11; - free(directory_buffer); -} /* generate_one_joliet_directory(... */ - -static int FDECL1(joliet_sort_n_finish, struct directory *, this_dir) -{ - struct directory_entry * s_entry; - int status = 0; - - /* don't want to skip this directory if it's the reloc_dir at the moment */ - if(this_dir != reloc_dir && this_dir->dir_flags & INHIBIT_JOLIET_ENTRY) - { - return 0; - } - - for(s_entry = this_dir->contents; s_entry; s_entry = s_entry->next) - { - /* skip hidden entries */ - if( (s_entry->de_flags & INHIBIT_JOLIET_ENTRY) != 0 ) - { - continue; - } - - /* - * First update the path table sizes for directories. - * - * Finally, set the length of the directory entry if Joliet is used. - * The name is longer, but no Rock Ridge is ever used here, so - * depending upon the options the entry size might turn out to be about - * the same. The Unicode name is always a multiple of 2 bytes, so - * we always add 1 to make it an even number. - */ - if(s_entry->isorec.flags[0] == 2) - { - if (strcmp(s_entry->name,".") && strcmp(s_entry->name,"..")) - { - jpath_table_size += joliet_strlen(s_entry->name) + sizeof(struct iso_path_table) - 1; - if (jpath_table_size & 1) - { - jpath_table_size++; - } - } - else - { - if (this_dir == root && strlen(s_entry->name) == 1) - { - jpath_table_size += sizeof(struct iso_path_table); - if (jpath_table_size & 1) jpath_table_size++; - } - } - } - - if (strcmp(s_entry->name,".") && strcmp(s_entry->name,"..")) - { - s_entry->jreclen = sizeof(struct iso_directory_record) - - sizeof(s_entry->isorec.name) - + joliet_strlen(s_entry->name) - + 1; - } - else - { - /* - * Special - for '.' and '..' we generate the same records we - * did for non-Joliet discs. - */ - s_entry->jreclen = sizeof(struct iso_directory_record) - - sizeof(s_entry->isorec.name) - + 1; - } - - - } - - if( (this_dir->dir_flags & INHIBIT_JOLIET_ENTRY) != 0 ) - { - return 0; - } - - this_dir->jcontents = this_dir->contents; - status = joliet_sort_directory(&this_dir->jcontents); - - /* - * Now go through the directory and figure out how large this one will be. - * Do not split a directory entry across a sector boundary - */ - s_entry = this_dir->jcontents; -/* - * XXX Is it ok to comment this out? - */ -/*XXX JS this_dir->ce_bytes = 0;*/ - for(s_entry = this_dir->jcontents; s_entry; s_entry = s_entry->jnext) - { - int jreclen; - - if( (s_entry->de_flags & INHIBIT_JOLIET_ENTRY) != 0 ) - { - continue; - } - - jreclen = s_entry->jreclen; - - if ((this_dir->jsize & (SECTOR_SIZE - 1)) + jreclen >= SECTOR_SIZE) - { - this_dir->jsize = (this_dir->jsize + (SECTOR_SIZE - 1)) & - ~(SECTOR_SIZE - 1); - } - this_dir->jsize += jreclen; - } - return status; -} - -/* - * Similar to the iso9660 case, except here we perform a full sort based upon the - * regular name of the file, not the 8.3 version. - */ -static int FDECL2(joliet_compare_dirs, const void *, rr, const void *, ll) -{ - char * rpnt, *lpnt; - struct directory_entry ** r, **l; - - r = (struct directory_entry **) rr; - l = (struct directory_entry **) ll; - rpnt = (*r)->name; - lpnt = (*l)->name; - - /* - * If the entries are the same, this is an error. - */ - if( strcmp(rpnt, lpnt) == 0 ) - { - sort_goof++; - } - - /* - * Put the '.' and '..' entries on the head of the sorted list. - * For normal ASCII, this always happens to be the case, but out of - * band characters cause this not to be the case sometimes. - */ - if( strcmp(rpnt, ".") == 0 ) return -1; - if( strcmp(lpnt, ".") == 0 ) return 1; - - if( strcmp(rpnt, "..") == 0 ) return -1; - if( strcmp(lpnt, "..") == 0 ) return 1; - - while(*rpnt && *lpnt) - { - if(*rpnt == ';' && *lpnt != ';') return -1; - if(*rpnt != ';' && *lpnt == ';') return 1; - - if(*rpnt == ';' && *lpnt == ';') return 0; - - /* - * Extensions are not special here. Don't treat the dot as something that - * must be bumped to the start of the list. - */ -#if 0 - if(*rpnt == '.' && *lpnt != '.') return -1; - if(*rpnt != '.' && *lpnt == '.') return 1; -#endif - - if(*rpnt < *lpnt) return -1; - if(*rpnt > *lpnt) return 1; - rpnt++; lpnt++; - } - if(*rpnt) return 1; - if(*lpnt) return -1; - return 0; -} - - -/* - * Function: sort_directory - * - * Purpose: Sort the directory in the appropriate ISO9660 - * order. - * - * Notes: Returns 0 if OK, returns > 0 if an error occurred. - */ -static int FDECL1(joliet_sort_directory, struct directory_entry **, sort_dir) -{ - int dcount = 0; - int i; - struct directory_entry * s_entry; - struct directory_entry ** sortlist; - - s_entry = *sort_dir; - while(s_entry) - { - /* skip hidden entries */ - if (!(s_entry->de_flags & INHIBIT_JOLIET_ENTRY)) - dcount++; - s_entry = s_entry->next; - } - - /* - * OK, now we know how many there are. Build a vector for sorting. - */ - sortlist = (struct directory_entry **) - e_malloc(sizeof(struct directory_entry *) * dcount); - - dcount = 0; - s_entry = *sort_dir; - while(s_entry) - { - /* skip hidden entries */ - if (!(s_entry->de_flags & INHIBIT_JOLIET_ENTRY)) { - sortlist[dcount] = s_entry; - dcount++; - } - s_entry = s_entry->next; - } - - sort_goof = 0; -#ifdef __STDC__ - qsort(sortlist, dcount, sizeof(struct directory_entry *), - (int (*)(const void *, const void *))joliet_compare_dirs); -#else - qsort(sortlist, dcount, sizeof(struct directory_entry *), - joliet_compare_dirs); -#endif - - /* - * Now reassemble the linked list in the proper sorted order - */ - for(i=0; ijnext = sortlist[i+1]; - } - - sortlist[dcount-1]->jnext = NULL; - *sort_dir = sortlist[0]; - - free(sortlist); - return sort_goof; -} - -int FDECL1(joliet_sort_tree, struct directory *, node) -{ - struct directory * dpnt; - int ret = 0; - - dpnt = node; - - while (dpnt){ - ret = joliet_sort_n_finish(dpnt); - if( ret ) - { - break; - } - if(dpnt->subdir) ret = joliet_sort_tree(dpnt->subdir); - if( ret ) - { - break; - } - dpnt = dpnt->next; - } - return ret; -} - -static void FDECL2(generate_joliet_directories, struct directory *, node, FILE*, outfile){ - struct directory * dpnt; - - dpnt = node; - - while (dpnt) - { - if( (dpnt->dir_flags & INHIBIT_JOLIET_ENTRY) == 0 ) - { - /* - * In theory we should never reuse a directory, so this doesn't - * make much sense. - */ - if( dpnt->jextent > session_start ) - { - generate_one_joliet_directory(dpnt, outfile); - } - } - /* skip if hidden - but not for the rr_moved dir */ - if(dpnt->subdir && (!(dpnt->dir_flags & INHIBIT_JOLIET_ENTRY) || dpnt == reloc_dir)) - generate_joliet_directories(dpnt->subdir, outfile); - dpnt = dpnt->next; - } -} - - -/* - * Function to write the EVD for the disc. - */ -static int FDECL1(jpathtab_write, FILE *, outfile) -{ - /* - * Next we write the path tables - */ - xfwrite(jpath_table_l, 1, jpath_blocks << 11, outfile); - xfwrite(jpath_table_m, 1, jpath_blocks << 11, outfile); - last_extent_written += 2*jpath_blocks; - free(jpath_table_l); - free(jpath_table_m); - jpath_table_l = NULL; - jpath_table_m = NULL; - return 0; -} - -static int FDECL1(jdirtree_size, int, starting_extent) -{ - assign_joliet_directory_addresses(root); - return 0; -} - -static int jroot_gen() -{ - jroot_record.length[0] = 1 + sizeof(struct iso_directory_record) - - sizeof(jroot_record.name); - jroot_record.ext_attr_length[0] = 0; - set_733((char *) jroot_record.extent, root->jextent); - set_733((char *) jroot_record.size, ROUND_UP(root->jsize)); - iso9660_date(jroot_record.date, root_statbuf.st_mtime); - jroot_record.flags[0] = 2; - jroot_record.file_unit_size[0] = 0; - jroot_record.interleave[0] = 0; - set_723(jroot_record.volume_sequence_number, volume_sequence_number); - jroot_record.name_len[0] = 1; - return 0; -} - -static int FDECL1(jdirtree_write, FILE *, outfile) -{ - generate_joliet_directories(root, outfile); - return 0; -} - -/* - * Function to write the EVD for the disc. - */ -static int FDECL1(jvd_write, FILE *, outfile) -{ - struct iso_primary_descriptor jvol_desc; - - /* - * Next we write out the boot volume descriptor for the disc - */ - jvol_desc = vol_desc; - get_joliet_vol_desc(&jvol_desc); - xfwrite(&jvol_desc, 1, 2048, outfile); - last_extent_written ++; - return 0; -} - -/* - * Functions to describe padding block at the start of the disc. - */ -static int FDECL1(jpathtab_size, int, starting_extent) -{ - jpath_table[0] = starting_extent; - jpath_table[1] = 0; - jpath_table[2] = jpath_table[0] + jpath_blocks; - jpath_table[3] = 0; - - last_extent += 2*jpath_blocks; - return 0; -} - -struct output_fragment joliet_desc = {NULL, oneblock_size, jroot_gen,jvd_write}; -struct output_fragment jpathtable_desc= {NULL, jpathtab_size, generate_joliet_path_tables, jpathtab_write}; -struct output_fragment jdirtree_desc = {NULL, jdirtree_size, NULL, jdirtree_write}; diff --git a/util/mkisofs/match.c b/util/mkisofs/match.c deleted file mode 100644 index 0072b504e..000000000 --- a/util/mkisofs/match.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) 2009 Free Software Foundation, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "config.h" - -#include -#include -#include "fnmatch.h" - -#include "match.h" - -struct pattern -{ - char *str; - struct pattern *next; -}; - -static struct pattern *patlist = NULL; -static struct pattern *i_patlist = NULL; /* ISO9660/RR */ -static struct pattern *j_patlist = NULL; /* Joliet */ - -#define DECL_ADD_MATCH(function, list) \ -void \ -function (char *pattern) \ -{ \ - struct pattern *new; \ - new = malloc (sizeof (*new)); \ - new->str = strdup (pattern); \ - new->next = list; \ - list = new; \ -} - -DECL_ADD_MATCH (add_match, patlist) -DECL_ADD_MATCH (i_add_match, i_patlist) -DECL_ADD_MATCH (j_add_match, j_patlist) - -#define DECL_MATCHES(function, list) \ -int \ -function (char *str) \ -{ \ - struct pattern *i; \ - for (i = list; i != NULL; i = i->next) \ - if (fnmatch (i->str, str, FNM_FILE_NAME) != FNM_NOMATCH) \ - return 1; \ - return 0; \ -} - -DECL_MATCHES (matches, patlist) -DECL_MATCHES (i_matches, i_patlist) -DECL_MATCHES (j_matches, j_patlist) - -int -i_ishidden() -{ - return (i_patlist != NULL); -} - - -int j_ishidden() -{ - return (j_patlist != NULL); -} diff --git a/util/mkisofs/match.h b/util/mkisofs/match.h deleted file mode 100644 index ee346a24c..000000000 --- a/util/mkisofs/match.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) 2009 Free Software Foundation, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "config.h" - -extern void add_match (char *); -extern void i_add_match (char *); -extern void j_add_match (char *); - -extern int matches (char *); -extern int i_matches (char *); -extern int j_matches (char *); - -extern int i_ishidden (); -extern int j_ishidden (); diff --git a/util/mkisofs/mkisofs.c b/util/mkisofs/mkisofs.c deleted file mode 100644 index 16e2f0c7d..000000000 --- a/util/mkisofs/mkisofs.c +++ /dev/null @@ -1,1422 +0,0 @@ -/* - * Program mkisofs.c - generate iso9660 filesystem based upon directory - * tree on hard disk. - - Written by Eric Youngdale (1993). - - Copyright 1993 Yggdrasil Computing, Incorporated - - Copyright (C) 2009,2010 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, see . - */ - -#include -#include "config.h" -#include "mkisofs.h" -#include "match.h" -#include "getopt.h" - -#include "iso9660.h" -#include - -#ifndef VMS -#include -#else -#include -#include "vms.h" -#endif - -#include -#include - -#ifndef VMS -#ifdef HAVE_UNISTD_H -#include -#endif -#endif -#include - -#include "exclude.h" - -#ifdef __NetBSD__ -#include -#include -#endif - -struct directory * root = NULL; - -static char version_string[] = "mkisofs 1.12b5"; - -#include "progname.h" - -char * outfile; -FILE * discimage; -uint64_t next_extent = 0; -uint64_t last_extent = 0; -uint64_t session_start = 0; -unsigned int path_table_size = 0; -unsigned int path_table[4] = {0,}; -unsigned int path_blocks = 0; - - -unsigned int jpath_table_size = 0; -unsigned int jpath_table[4] = {0,}; -unsigned int jpath_blocks = 0; - -struct iso_directory_record root_record; -struct iso_directory_record jroot_record; - -char * extension_record = NULL; -int extension_record_extent = 0; -int extension_record_size = 0; - -/* These variables are associated with command line options */ -int use_eltorito = 0; -int use_eltorito_emul_floppy = 0; -int use_embedded_boot = 0; -int use_protective_msdos_label = 0; -int use_boot_info_table = 0; -int use_RockRidge = 0; -int use_Joliet = 0; -int verbose = 1; -int all_files = 0; -int follow_links = 0; -int rationalize = 0; -int generate_tables = 0; -int print_size = 0; -int split_output = 0; -char *preparer = PREPARER_DEFAULT; -char *publisher = PUBLISHER_DEFAULT; -char *appid = APPID_DEFAULT; -char *copyright = COPYRIGHT_DEFAULT; -char *biblio = BIBLIO_DEFAULT; -char *abstract = ABSTRACT_DEFAULT; -char *volset_id = VOLSET_ID_DEFAULT; -char *volume_id = VOLUME_ID_DEFAULT; -char *system_id = SYSTEM_ID_DEFAULT; -char *boot_catalog = BOOT_CATALOG_DEFAULT; -char *boot_image = BOOT_IMAGE_DEFAULT; -char *boot_image_embed = NULL; -int volume_set_size = 1; -int volume_sequence_number = 1; - -int omit_period = 0; /* Violates iso9660, but these are a pain */ -int transparent_compression = 0; /* So far only works with linux */ -int omit_version_number = 0; /* May violate iso9660, but noone uses vers*/ -unsigned int RR_relocation_depth = 6; /* Violates iso9660, but most systems work */ -int full_iso9660_filenames = 0; /* Used with Amiga. Disc will not work with - DOS */ -int allow_leading_dots = 0; /* DOS cannot read names with leading dots */ -int split_SL_component = 1; /* circumvent a bug in the SunOS driver */ -int split_SL_field = 1; /* circumvent a bug in the SunOS */ - -struct rcopts{ - char * tag; - char ** variable; -}; - -struct rcopts rcopt[] = { - {"PREP", &preparer}, - {"PUBL", &publisher}, - {"APPI", &appid}, - {"COPY", ©right}, - {"BIBL", &biblio}, - {"ABST", &abstract}, - {"VOLS", &volset_id}, - {"VOLI", &volume_id}, - {"SYSI", &system_id}, - {NULL, NULL} -}; - -/* - * In case it isn't obvious, the option handling code was ripped off from GNU-ld. - */ -struct ld_option -{ - /* The long option information. */ - struct option opt; - /* The short option with the same meaning ('\0' if none). */ - char shortopt; - /* The name of the argument (NULL if none). */ - const char *arg; - /* The documentation string. If this is NULL, this is a synonym for - the previous option. */ - const char *doc; - enum - { - /* Use one dash before long option name. */ - ONE_DASH, - /* Use two dashes before long option name. */ - TWO_DASHES, - /* Don't mention this option in --help output. */ - NO_HELP - } control; -}; - -/* Codes used for the long options with no short synonyms. 150 isn't - special; it's just an arbitrary non-ASCII char value. */ -#define OPTION_HELP 150 -#define OPTION_QUIET 151 -#define OPTION_NOSPLIT_SL_COMPONENT 152 -#define OPTION_NOSPLIT_SL_FIELD 153 -#define OPTION_PRINT_SIZE 154 -#define OPTION_SPLIT_OUTPUT 155 -#define OPTION_ABSTRACT 156 -#define OPTION_BIBLIO 157 -#define OPTION_COPYRIGHT 158 -#define OPTION_SYSID 159 -#define OPTION_VOLSET 160 -#define OPTION_VOLSET_SIZE 161 -#define OPTION_VOLSET_SEQ_NUM 162 -#define OPTION_I_HIDE 163 -#define OPTION_J_HIDE 164 -#define OPTION_LOG_FILE 165 - -#define OPTION_CREAT_DATE 166 -#define OPTION_MODIF_DATE 167 -#define OPTION_EXPIR_DATE 168 -#define OPTION_EFFEC_DATE 169 - -#define OPTION_BOOT_INFO_TABLE 170 -#define OPTION_NO_EMUL_BOOT 171 -#define OPTION_ELTORITO_EMUL_FLOPPY 172 - -#define OPTION_VERSION 173 - -#define OPTION_PROTECTIVE_MSDOS_LABEL 174 - -static const struct ld_option ld_options[] = -{ - { {"all-files", no_argument, NULL, 'a'}, - 'a', NULL, N_("Process all files (don't skip backup files)"), ONE_DASH }, - { {"abstract", required_argument, NULL, OPTION_ABSTRACT}, - '\0', N_("FILE"), N_("Set Abstract filename"), ONE_DASH }, - { {"appid", required_argument, NULL, 'A'}, - 'A', N_("ID"), N_("Set Application ID"), ONE_DASH }, - { {"biblio", required_argument, NULL, OPTION_BIBLIO}, - '\0', N_("FILE"), N_("Set Bibliographic filename"), ONE_DASH }, - { {"copyright", required_argument, NULL, OPTION_COPYRIGHT}, - '\0', N_("FILE"), N_("Set Copyright filename"), ONE_DASH }, - { {"embedded-boot", required_argument, NULL, 'G'}, - 'G', N_("FILE"), N_("Set embedded boot image name"), TWO_DASHES }, - { {"protective-msdos-label", no_argument, NULL, OPTION_PROTECTIVE_MSDOS_LABEL }, - '\0', NULL, N_("Patch a protective DOS-style label in the image"), TWO_DASHES }, - { {"eltorito-boot", required_argument, NULL, 'b'}, - 'b', N_("FILE"), N_("Set El Torito boot image name"), ONE_DASH }, - { {"eltorito-catalog", required_argument, NULL, 'c'}, - 'c', N_("FILE"), N_("Set El Torito boot catalog name"), ONE_DASH }, - { {"boot-info-table", no_argument, NULL, OPTION_BOOT_INFO_TABLE }, - '\0', NULL, N_("Patch Boot Info Table in El Torito boot image"), ONE_DASH }, - { {"no-emul-boot", no_argument, NULL, OPTION_NO_EMUL_BOOT }, - '\0', NULL, N_("Dummy option for backward compatibility"), ONE_DASH }, - { {"eltorito-emul-floppy", no_argument, NULL, OPTION_ELTORITO_EMUL_FLOPPY }, - '\0', NULL, N_("Enable floppy drive emulation for El Torito"), TWO_DASHES }, - { {"cdwrite-params", required_argument, NULL, 'C'}, - 'C', N_("PARAMS"), N_("Magic parameters from cdrecord"), ONE_DASH }, - { {"omit-period", no_argument, NULL, 'd'}, - 'd', NULL, N_("Omit trailing periods from filenames"), ONE_DASH }, - { {"disable-deep-relocation", no_argument, NULL, 'D'}, - 'D', NULL, N_("Disable deep directory relocation"), ONE_DASH }, - { {"follow-links", no_argument, NULL, 'f'}, - 'f', NULL, N_("Follow symbolic links"), ONE_DASH }, - { {"help", no_argument, NULL, OPTION_HELP}, - '\0', NULL, N_("Print option help"), ONE_DASH }, - { {"help", no_argument, NULL, OPTION_HELP}, - '\0', NULL, N_("Print option help"), TWO_DASHES }, - { {"version", no_argument, NULL, OPTION_VERSION}, - '\0', NULL, N_("Print version information and exit"), TWO_DASHES }, - { {"hide", required_argument, NULL, OPTION_I_HIDE}, - '\0', N_("GLOBFILE"), N_("Hide ISO9660/RR file"), ONE_DASH }, - { {"hide-joliet", required_argument, NULL, OPTION_J_HIDE}, - '\0', N_("GLOBFILE"), N_("Hide Joliet file"), ONE_DASH }, - { {NULL, required_argument, NULL, 'i'}, - 'i', N_("ADD_FILES"), N_("No longer supported"), TWO_DASHES }, - { {"joliet", no_argument, NULL, 'J'}, - 'J', NULL, N_("Generate Joliet directory information"), ONE_DASH }, - { {"full-iso9660-filenames", no_argument, NULL, 'l'}, - 'l', NULL, N_("Allow full 32 character filenames for iso9660 names"), ONE_DASH }, - { {"allow-leading-dots", no_argument, NULL, 'L'}, - 'L', NULL, N_("Allow iso9660 filenames to start with '.'"), ONE_DASH }, - { {"log-file", required_argument, NULL, OPTION_LOG_FILE}, - '\0', N_("LOG_FILE"), N_("Re-direct messages to LOG_FILE"), ONE_DASH }, - { {"exclude", required_argument, NULL, 'm'}, - 'm', N_("GLOBFILE"), N_("Exclude file name"), ONE_DASH }, - { {"prev-session", required_argument, NULL, 'M'}, - 'M', N_("FILE"), N_("Set path to previous session to merge"), ONE_DASH }, - { {"omit-version-number", no_argument, NULL, 'N'}, - 'N', NULL, N_("Omit version number from iso9660 filename"), ONE_DASH }, - { {"no-split-symlink-components", no_argument, NULL, 0}, - 0, NULL, N_("Inhibit splitting symlink components"), ONE_DASH }, - { {"no-split-symlink-fields", no_argument, NULL, 0}, - 0, NULL, N_("Inhibit splitting symlink fields"), ONE_DASH }, - { {"output", required_argument, NULL, 'o'}, - 'o', N_("FILE"), N_("Set output file name"), ONE_DASH }, - { {"preparer", required_argument, NULL, 'p'}, - 'p', N_("PREP"), N_("Set Volume preparer"), ONE_DASH }, - { {"print-size", no_argument, NULL, OPTION_PRINT_SIZE}, - '\0', NULL, N_("Print estimated filesystem size and exit"), ONE_DASH }, - { {"publisher", required_argument, NULL, 'P'}, - 'P', N_("PUB"), N_("Set Volume publisher"), ONE_DASH }, - { {"quiet", no_argument, NULL, OPTION_QUIET}, - '\0', NULL, N_("Run quietly"), ONE_DASH }, - { {"rational-rock", no_argument, NULL, 'r'}, - 'r', NULL, N_("Generate rationalized Rock Ridge directory information"), ONE_DASH }, - { {"rock", no_argument, NULL, 'R'}, - 'R', NULL, N_("Generate Rock Ridge directory information"), ONE_DASH }, - { {"split-output", no_argument, NULL, OPTION_SPLIT_OUTPUT}, - '\0', NULL, N_("Split output into files of approx. 1GB size"), ONE_DASH }, - { {"sysid", required_argument, NULL, OPTION_SYSID}, - '\0', N_("ID"), N_("Set System ID"), ONE_DASH }, - { {"translation-table", no_argument, NULL, 'T'}, - 'T', NULL, N_("Generate translation tables for systems that don't understand long filenames"), ONE_DASH }, - { {"verbose", no_argument, NULL, 'v'}, - 'v', NULL, N_("Verbose"), ONE_DASH }, - { {"volid", required_argument, NULL, 'V'}, - 'V', N_("ID"), N_("Set Volume ID"), ONE_DASH }, - { {"volset", required_argument, NULL, OPTION_VOLSET}, - '\0', N_("ID"), N_("Set Volume set ID"), ONE_DASH }, - { {"volset-size", required_argument, NULL, OPTION_VOLSET_SIZE}, - '\0', "#", N_("Set Volume set size"), ONE_DASH }, - { {"volset-seqno", required_argument, NULL, OPTION_VOLSET_SEQ_NUM}, - '\0', "#", N_("Set Volume set sequence number"), ONE_DASH }, - { {"old-exclude", required_argument, NULL, 'x'}, - 'x', N_("FILE"), N_("Exclude file name (deprecated)"), ONE_DASH }, -#ifdef ERIC_neverdef - { {"transparent-compression", no_argument, NULL, 'z'}, - 'z', NULL, "Enable transparent compression of files", ONE_DASH }, -#endif - { {"creation-date", required_argument, NULL, OPTION_CREAT_DATE }, - '\0', NULL, N_("Override creation date"), TWO_DASHES }, - { {"modification-date", required_argument, NULL, OPTION_MODIF_DATE }, - '\0', NULL, N_("Override modification date"), TWO_DASHES }, - { {"expiration-date", required_argument, NULL, OPTION_EXPIR_DATE }, - '\0', NULL, N_("Override expiration date"), TWO_DASHES }, - { {"effective-date", required_argument, NULL, OPTION_EFFEC_DATE }, - '\0', NULL, N_("Override effective date"), TWO_DASHES }, -}; - -#define OPTION_COUNT (sizeof ld_options / sizeof ld_options[0]) - -#if defined(ultrix) || defined(_AUX_SOURCE) -char *strdup(s) -char *s;{char *c;if(c=(char *)malloc(strlen(s)+1))strcpy(c,s);return c;} -#endif - - void read_rcfile __PR((char * appname)); - void usage __PR((void)); -static void hide_reloc_dir __PR((void)); - -void FDECL1(read_rcfile, char *, appname) -{ - FILE * rcfile; - struct rcopts * rco; - char * pnt, *pnt1; - char linebuffer[256]; - static char rcfn[] = ".mkisofsrc"; - char filename[1000]; - int linum; - - strcpy(filename, rcfn); - rcfile = fopen(filename, "r"); - if (!rcfile && errno != ENOENT) - perror(filename); - - if (!rcfile) - { - pnt = getenv("MKISOFSRC"); - if (pnt && strlen(pnt) <= sizeof(filename)) - { - strcpy(filename, pnt); - rcfile = fopen(filename, "r"); - if (!rcfile && errno != ENOENT) - perror(filename); - } - } - - if (!rcfile) - { - pnt = getenv("HOME"); - if (pnt && strlen(pnt) + strlen(rcfn) + 2 <= sizeof(filename)) - { - strcpy(filename, pnt); - strcat(filename, "/"); - strcat(filename, rcfn); - rcfile = fopen(filename, "r"); - if (!rcfile && errno != ENOENT) - perror(filename); - } - } - if (!rcfile && strlen(appname)+sizeof(rcfn)+2 <= sizeof(filename)) - { - strcpy(filename, appname); - pnt = strrchr(filename, '/'); - if (pnt) - { - strcpy(pnt + 1, rcfn); - rcfile = fopen(filename, "r"); - if (!rcfile && errno != ENOENT) - perror(filename); - } - } - if (!rcfile) - return; - if ( verbose > 0 ) - { - fprintf (stderr, _("Using \"%s\"\n"), filename); - } - - /* OK, we got it. Now read in the lines and parse them */ - linum = 0; - while (fgets(linebuffer, sizeof(linebuffer), rcfile)) - { - char *name; - char *name_end; - ++linum; - /* skip any leading white space */ - pnt = linebuffer; - while (*pnt == ' ' || *pnt == '\t') - ++pnt; - /* If we are looking at a # character, this line is a comment. */ - if (*pnt == '#') - continue; - /* The name should begin in the left margin. Make sure it is in - upper case. Stop when we see white space or a comment. */ - name = pnt; - while (*pnt && isalpha((unsigned char)*pnt)) - { - if(islower((unsigned char)*pnt)) - *pnt = toupper((unsigned char)*pnt); - pnt++; - } - if (name == pnt) - { - fprintf(stderr, _("%s:%d: name required\n"), filename, linum); - continue; - } - name_end = pnt; - /* Skip past white space after the name */ - while (*pnt == ' ' || *pnt == '\t') - pnt++; - /* silently ignore errors in the rc file. */ - if (*pnt != '=') - { - fprintf (stderr, _("%s:%d: equals sign required\n"), filename, linum); - continue; - } - /* Skip pas the = sign, and any white space following it */ - pnt++; /* Skip past '=' sign */ - while (*pnt == ' ' || *pnt == '\t') - pnt++; - - /* now it is safe to NUL terminate the name */ - - *name_end = 0; - - /* Now get rid of trailing newline */ - - pnt1 = pnt; - while (*pnt1) - { - if (*pnt1 == '\n') - { - *pnt1 = 0; - break; - } - pnt1++; - }; - /* OK, now figure out which option we have */ - for(rco = rcopt; rco->tag; rco++) { - if(strcmp(rco->tag, name) == 0) - { - *rco->variable = strdup(pnt); - break; - }; - } - if (rco->tag == NULL) - { - fprintf (stderr, _("%s:%d: field name \"%s\" unknown\n"), filename, linum, - name); - } - } - if (ferror(rcfile)) - perror(filename); - fclose(rcfile); -} - -char * path_table_l = NULL; -char * path_table_m = NULL; - -char * jpath_table_l = NULL; -char * jpath_table_m = NULL; - -int goof = 0; - -#ifndef TRUE -#define TRUE 1 -#endif - -#ifndef FALSE -#define FALSE 0 -#endif - -void usage(){ - unsigned int i; -/* const char **targets, **pp;*/ - - printf (_("Usage: %s [options] file...\n"), program_name); - - printf (_("Options:\n")); - for (i = 0; i < OPTION_COUNT; i++) - { - if (ld_options[i].doc != NULL) - { - int comma; - int len; - unsigned int j; - const char *arg; - - printf (" "); - - comma = FALSE; - len = 2; - - j = i; - do - { - if (ld_options[j].shortopt != '\0' - && ld_options[j].control != NO_HELP) - { - printf ("%s-%c", comma ? ", " : "", ld_options[j].shortopt); - len += (comma ? 2 : 0) + 2; - if (ld_options[j].arg != NULL) - { - if (ld_options[j].opt.has_arg != optional_argument) - { - putchar (' '); - ++len; - } - arg = gettext (ld_options[j].arg); - printf ("%s", arg); - len += strlen (arg); - } - comma = TRUE; - } - ++j; - } - while (j < OPTION_COUNT && ld_options[j].doc == NULL); - - j = i; - do - { - if (ld_options[j].opt.name != NULL - && ld_options[j].control != NO_HELP) - { - printf ("%s-%s%s", - comma ? ", " : "", - ld_options[j].control == TWO_DASHES ? "-" : "", - ld_options[j].opt.name); - len += ((comma ? 2 : 0) - + 1 - + (ld_options[j].control == TWO_DASHES ? 1 : 0) - + strlen (ld_options[j].opt.name)); - if (ld_options[j].arg != NULL) - { - arg = gettext (ld_options[j].arg); - printf (" %s", arg); - len += 1 + strlen (arg); - } - comma = TRUE; - } - ++j; - } - while (j < OPTION_COUNT && ld_options[j].doc == NULL); - - if (len >= 30) - { - printf ("\n"); - len = 0; - } - - for (; len < 30; len++) - putchar (' '); - - printf ("%s\n", gettext (ld_options[i].doc)); - } - } - exit(1); -} - - -/* - * Fill in date in the iso9660 format - * - * The standards state that the timezone offset is in multiples of 15 - * minutes, and is what you add to GMT to get the localtime. The U.S. - * is always at a negative offset, from -5h to -8h (can vary a little - * with DST, I guess). The Linux iso9660 filesystem has had the sign - * of this wrong for ages (mkisofs had it wrong too for the longest time). - */ -int FDECL2(iso9660_date,char *, result, time_t, crtime){ - struct tm *local; - local = localtime(&crtime); - result[0] = local->tm_year; - result[1] = local->tm_mon + 1; - result[2] = local->tm_mday; - result[3] = local->tm_hour; - result[4] = local->tm_min; - result[5] = local->tm_sec; - - /* - * Must recalculate proper timezone offset each time, - * as some files use daylight savings time and some don't... - */ - result[6] = local->tm_yday; /* save yday 'cause gmtime zaps it */ - local = gmtime(&crtime); - local->tm_year -= result[0]; - local->tm_yday -= result[6]; - local->tm_hour -= result[3]; - local->tm_min -= result[4]; - if (local->tm_year < 0) - { - local->tm_yday = -1; - } - else - { - if (local->tm_year > 0) local->tm_yday = 1; - } - - result[6] = -(local->tm_min + 60*(local->tm_hour + 24*local->tm_yday)) / 15; - - return 0; -} - -/* hide "./rr_moved" if all its contents are hidden */ -static void -hide_reloc_dir() -{ - struct directory_entry * s_entry; - - for (s_entry = reloc_dir->contents; s_entry; s_entry = s_entry->next) { - if(strcmp(s_entry->name,".")==0 || strcmp(s_entry->name,"..")==0) - continue; - - if((s_entry->de_flags & INHIBIT_ISO9660_ENTRY) == 0) - return; - } - - /* all entries are hidden, so hide this directory */ - reloc_dir->dir_flags |= INHIBIT_ISO9660_ENTRY; - reloc_dir->self->de_flags |= INHIBIT_ISO9660_ENTRY; -} - -extern char * cdwrite_data; - -int FDECL2(main, int, argc, char **, argv){ - struct directory_entry de; -#ifdef HAVE_SBRK - unsigned long mem_start; -#endif - struct stat statbuf; - char * scan_tree; - char * merge_image = NULL; - struct iso_directory_record * mrootp = NULL; - struct output_fragment * opnt; - int longind; - char shortopts[OPTION_COUNT * 3 + 2]; - struct option longopts[OPTION_COUNT + 1]; - int c; - char *log_file = 0; - - set_program_name (argv[0]); -#if (defined(ENABLE_NLS) && ENABLE_NLS) - setlocale (LC_ALL, ""); - bindtextdomain (PACKAGE, LOCALEDIR); - textdomain (PACKAGE); -#endif /* (defined(ENABLE_NLS) && ENABLE_NLS) */ - - if (argc < 2) - usage(); - - /* Get the defaults from the .mkisofsrc file */ - read_rcfile(argv[0]); - - outfile = NULL; - - /* - * Copy long option initialization from GNU-ld. - */ - /* Starting the short option string with '-' is for programs that - expect options and other ARGV-elements in any order and that care about - the ordering of the two. We describe each non-option ARGV-element - as if it were the argument of an option with character code 1. */ - { - unsigned int i; - int is, il; - shortopts[0] = '-'; - is = 1; - il = 0; - for (i = 0; i < OPTION_COUNT; i++) - { - if (ld_options[i].shortopt != '\0') - { - shortopts[is] = ld_options[i].shortopt; - ++is; - if (ld_options[i].opt.has_arg == required_argument - || ld_options[i].opt.has_arg == optional_argument) - { - shortopts[is] = ':'; - ++is; - if (ld_options[i].opt.has_arg == optional_argument) - { - shortopts[is] = ':'; - ++is; - } - } - } - if (ld_options[i].opt.name != NULL) - { - longopts[il] = ld_options[i].opt; - ++il; - } - } - shortopts[is] = '\0'; - longopts[il].name = NULL; - } - - while ((c = getopt_long_only (argc, argv, shortopts, longopts, &longind)) != EOF) - switch (c) - { - case 1: - /* - * A filename that we take as input. - */ - optind--; - goto parse_input_files; - case 'C': - /* - * This is a temporary hack until cdwrite gets the proper hooks in - * it. - */ - cdwrite_data = optarg; - break; - case 'i': - fprintf (stderr, _("-i option no longer supported.\n")); - exit(1); - break; - case 'J': - use_Joliet++; - break; - case 'a': - all_files++; - break; - case 'b': - use_eltorito++; - boot_image = optarg; /* pathname of the boot image on cd */ - if (boot_image == NULL) - error (1, 0, _("Required boot image pathname missing")); - break; - case 'G': - use_embedded_boot = 1; - boot_image_embed = optarg; /* pathname of the boot image on host filesystem */ - if (boot_image_embed == NULL) - error (1, 0, _("Required boot image pathname missing")); - break; - case OPTION_PROTECTIVE_MSDOS_LABEL: - use_protective_msdos_label = 1; - break; - case 'c': - use_eltorito++; - boot_catalog = optarg; /* pathname of the boot image on cd */ - if (boot_catalog == NULL) - { - fprintf (stderr, _("Required boot catalog pathname missing\n")); - exit (1); - } - break; - case OPTION_BOOT_INFO_TABLE: - use_boot_info_table = 1; - break; - case OPTION_NO_EMUL_BOOT: - fprintf (stderr, _("Ignoring -no-emul-boot (no-emulation is the default behaviour)\n")); - break; - case OPTION_ELTORITO_EMUL_FLOPPY: - use_eltorito_emul_floppy = 1; - break; - case OPTION_ABSTRACT: - abstract = optarg; - if(strlen(abstract) > 37) - { - fprintf (stderr, _("Abstract filename string too long\n")); - exit (1); - }; - break; - case 'A': - appid = optarg; - if(strlen(appid) > 128) - { - fprintf (stderr, _("Application-id string too long\n")); - exit (1); - }; - break; - case OPTION_BIBLIO: - biblio = optarg; - if(strlen(biblio) > 37) - { - fprintf (stderr, _("Bibliographic filename string too long\n")); - exit (1); - }; - break; - case OPTION_COPYRIGHT: - copyright = optarg; - if(strlen(copyright) > 37) - { - fprintf (stderr, _("Copyright filename string too long\n")); - exit (1); - }; - break; - case 'd': - omit_period++; - break; - case 'D': - RR_relocation_depth = 32767; - break; - case 'f': - follow_links++; - break; - case 'l': - full_iso9660_filenames++; - break; - case 'L': - allow_leading_dots++; - break; - case OPTION_LOG_FILE: - log_file = optarg; - break; - case 'M': - merge_image = optarg; - break; - case 'N': - omit_version_number++; - break; - case 'o': - outfile = optarg; - break; - case 'p': - preparer = optarg; - if(strlen(preparer) > 128) - { - fprintf (stderr, _("Preparer string too long\n")); - exit (1); - }; - break; - case OPTION_PRINT_SIZE: - print_size++; - break; - case 'P': - publisher = optarg; - if(strlen(publisher) > 128) - { - fprintf (stderr, _("Publisher string too long\n")); - exit (1); - }; - break; - case OPTION_QUIET: - verbose = 0; - break; - case 'R': - use_RockRidge++; - break; - case 'r': - rationalize++; - use_RockRidge++; - break; - case OPTION_SPLIT_OUTPUT: - split_output++; - break; - case OPTION_SYSID: - system_id = optarg; - if(strlen(system_id) > 32) - { - fprintf (stderr, _("System ID string too long\n")); - exit (1); - }; - break; - case 'T': - generate_tables++; - break; - case 'V': - volume_id = optarg; - if(strlen(volume_id) > 32) - { - fprintf (stderr, _("Volume ID string too long\n")); - exit (1); - }; - break; - case OPTION_VOLSET: - volset_id = optarg; - if(strlen(volset_id) > 128) - { - fprintf (stderr, _("Volume set ID string too long\n")); - exit (1); - }; - break; - case OPTION_VOLSET_SIZE: - volume_set_size = atoi(optarg); - break; - case OPTION_VOLSET_SEQ_NUM: - volume_sequence_number = atoi(optarg); - if (volume_sequence_number > volume_set_size) - { - fprintf (stderr, _("Volume set sequence number too big\n")); - exit (1); - } - break; - case 'v': - verbose++; - break; - case 'z': - transparent_compression++; - break; - case 'x': - case 'm': - /* - * Somehow two options to do basically the same thing got added somewhere along - * the way. The 'match' code supports limited globbing, so this is the one - * that got selected. Unfortunately the 'x' switch is probably more intuitive. - */ - add_match(optarg); - break; - case OPTION_I_HIDE: - i_add_match(optarg); - break; - case OPTION_J_HIDE: - j_add_match(optarg); - break; - case OPTION_HELP: - usage (); - exit (0); - break; - case OPTION_VERSION: - printf ("%s version %s\n", PACKAGE_NAME, PACKAGE_VERSION); - exit (0); - break; - case OPTION_NOSPLIT_SL_COMPONENT: - split_SL_component = 0; - break; - case OPTION_NOSPLIT_SL_FIELD: - split_SL_field = 0; - break; - case OPTION_CREAT_DATE: - if (strlen (optarg) != 16) - { - fprintf (stderr, _("date string must be 16 characters.\n")); - exit (1); - } - if (creation_date) - free(creation_date); - creation_date = strdup(optarg); - break; - case OPTION_MODIF_DATE: - if (strlen (optarg) != 16) - { - fprintf (stderr, _("date string must be 16 characters.\n")); - exit (1); - } - if (modification_date) - free(modification_date); - modification_date = strdup(optarg); - break; - case OPTION_EXPIR_DATE: - if (strlen (optarg) != 16) - { - fprintf (stderr, _("date string must be 16 characters.\n")); - exit (1); - } - if (expiration_date) - free(expiration_date); - expiration_date = strdup(optarg); - break; - case OPTION_EFFEC_DATE: - if (strlen (optarg) != 16) - { - fprintf (stderr, _("date string must be 16 characters.\n")); - exit (1); - } - if (effective_date) - free(effective_date); - effective_date = strdup(optarg); - break; - default: - usage(); - exit(1); - } - -parse_input_files: - -#ifdef __NetBSD__ - { - int resource; - struct rlimit rlp; - if (getrlimit(RLIMIT_DATA,&rlp) == -1) - perror (_("Warning: getrlimit")); - else { - rlp.rlim_cur=33554432; - if (setrlimit(RLIMIT_DATA,&rlp) == -1) - perror (_("Warning: setrlimit")); - } - } -#endif -#ifdef HAVE_SBRK - mem_start = (unsigned long) sbrk(0); -#endif - - /* if the -hide-joliet option has been given, set the Joliet option */ - if (!use_Joliet && j_ishidden()) - use_Joliet++; - - if(verbose > 1) fprintf(stderr,"%s\n", version_string); - - if(cdwrite_data == NULL && merge_image != NULL) - { - fprintf (stderr, _("Multisession usage bug: Must specify -C if -M is used.\n")); - exit (0); - } - - if(cdwrite_data != NULL && merge_image == NULL) - { - fprintf (stderr, _("Warning: -C specified without -M: old session data will not be merged.\n")); - } - - /* The first step is to scan the directory tree, and take some notes */ - - scan_tree = argv[optind]; - - - if(!scan_tree){ - usage(); - exit(1); - }; - -#ifndef VMS - if(scan_tree[strlen(scan_tree)-1] != '/') { - scan_tree = (char *) e_malloc(strlen(argv[optind])+2); - strcpy(scan_tree, argv[optind]); - strcat(scan_tree, "/"); - }; -#endif - - if(use_RockRidge){ -#if 1 - extension_record = generate_rr_extension_record("RRIP_1991A", - "THE ROCK RIDGE INTERCHANGE PROTOCOL PROVIDES SUPPORT FOR POSIX FILE SYSTEM SEMANTICS", - "PLEASE CONTACT DISC PUBLISHER FOR SPECIFICATION SOURCE. SEE PUBLISHER IDENTIFIER IN PRIMARY VOLUME DESCRIPTOR FOR CONTACT INFORMATION.", &extension_record_size); -#else - extension_record = generate_rr_extension_record("IEEE_P1282", - "THE IEEE P1282 PROTOCOL PROVIDES SUPPORT FOR POSIX FILE SYSTEM SEMANTICS", - "PLEASE CONTACT THE IEEE STANDARDS DEPARTMENT, PISCATAWAY, NJ, USA FOR THE P1282 SPECIFICATION.", &extension_record_size); -#endif - } - - if (log_file) { - FILE *lfp; - int i; - - /* open log file - test that we can open OK */ - if ((lfp = fopen(log_file, "w")) == NULL) - error (1, errno, _("can't open logfile: %s"), log_file); - fclose(lfp); - - /* redirect all stderr message to log_file */ - fprintf (stderr, _("re-directing all messages to %s\n"), log_file); - fflush(stderr); - - /* associate stderr with the log file */ - if (freopen(log_file, "w", stderr) == NULL) - error (1, errno, _("can't open logfile: %s\n"), log_file); - if(verbose > 1) { - for (i=0;iextent, 8); - } - - /* - * Create an empty root directory. If we ever scan it for real, we will fill in the - * contents. - */ - find_or_create_directory(NULL, "", &de, TRUE); - - /* - * Scan the actual directory (and any we find below it) - * for files to write out to the output image. Note - we - * take multiple source directories and keep merging them - * onto the image. - */ - while(optind < argc) - { - char * node; - struct directory * graft_dir; - struct stat st; - char * short_name; - int status; - char graft_point[1024]; - - /* - * We would like a syntax like: - * - * /tmp=/usr/tmp/xxx - * - * where the user can specify a place to graft each - * component of the tree. To do this, we may have to create - * directories along the way, of course. - * Secondly, I would like to allow the user to do something - * like: - * - * /home/baz/RMAIL=/u3/users/baz/RMAIL - * - * so that normal files could also be injected into the tree - * at an arbitrary point. - * - * The idea is that the last component of whatever is being - * entered would take the name from the last component of - * whatever the user specifies. - * - * The default will be that the file is injected at the - * root of the image tree. - */ - node = strchr(argv[optind], '='); - short_name = NULL; - - if( node != NULL ) - { - char * pnt; - char * xpnt; - - *node = '\0'; - strcpy(graft_point, argv[optind]); - *node = '='; - node++; - - graft_dir = root; - xpnt = graft_point; - if( *xpnt == PATH_SEPARATOR ) - { - xpnt++; - } - - /* - * Loop down deeper and deeper until we - * find the correct insertion spot. - */ - while(1==1) - { - pnt = strchr(xpnt, PATH_SEPARATOR); - if( pnt == NULL ) - { - if( *xpnt != '\0' ) - { - short_name = xpnt; - } - break; - } - *pnt = '\0'; - graft_dir = find_or_create_directory(graft_dir, - graft_point, - NULL, TRUE); - *pnt = PATH_SEPARATOR; - xpnt = pnt + 1; - } - } - else - { - graft_dir = root; - node = argv[optind]; - } - - /* - * Now see whether the user wants to add a regular file, - * or a directory at this point. - */ - status = stat_filter(node, &st); - if( status != 0 ) - { - /* - * This is a fatal error - the user won't be getting what - * they want if we were to proceed. - */ - error (1, 0, _("Invalid node - %s\n"), node); - } - else - { - if( S_ISDIR(st.st_mode) ) - { - if (!scan_directory_tree(graft_dir, node, &de)) - { - exit(1); - } - } - else - { - if( short_name == NULL ) - { - short_name = strrchr(node, PATH_SEPARATOR); - if( short_name == NULL || short_name < node ) - { - short_name = node; - } - else - { - short_name++; - } - } - if( !insert_file_entry(graft_dir, node, short_name) ) - { - exit(1); - } - } - } - - optind++; - } - - - /* - * Now merge in any previous sessions. This is driven on the source - * side, since we may need to create some additional directories. - */ - if( merge_image != NULL ) - { - merge_previous_session(root, mrootp); - } - - /* hide "./rr_moved" if all its contents have been hidden */ - if (reloc_dir && i_ishidden()) - hide_reloc_dir(); - - /* - * Sort the directories in the required order (by ISO9660). Also, - * choose the names for the 8.3 filesystem if required, and do - * any other post-scan work. - */ - goof += sort_tree(root); - - if( use_Joliet ) - { - goof += joliet_sort_tree(root); - } - - if (goof) - error (1, 0, _("Joliet tree sort failed.\n")); - - /* - * Fix a couple of things in the root directory so that everything - * is self consistent. - */ - root->self = root->contents; /* Fix this up so that the path - tables get done right */ - - /* - * OK, ready to write the file. Open it up, and generate the thing. - */ - if (print_size){ - discimage = fopen("/dev/null", "wb"); - if (!discimage) - error (1, errno, _("Unable to open /dev/null\n")); - } else if (outfile){ - discimage = fopen(outfile, "wb"); - if (!discimage) - error (1, errno, _("Unable to open disc image file\n")); - } else { - discimage = stdout; - -#if defined(__CYGWIN32__) - setmode(fileno(stdout), O_BINARY); -#endif - } - - /* Now assign addresses on the disc for the path table. */ - - path_blocks = (path_table_size + (SECTOR_SIZE - 1)) >> 11; - if (path_blocks & 1) path_blocks++; - - jpath_blocks = (jpath_table_size + (SECTOR_SIZE - 1)) >> 11; - if (jpath_blocks & 1) jpath_blocks++; - - /* - * Start to set up the linked list that we use to track the - * contents of the disc. - */ - outputlist_insert(&padblock_desc); - - /* - * PVD for disc. - */ - outputlist_insert(&voldesc_desc); - - /* - * SVD for El Torito. MUST be immediately after the PVD! - */ - if( use_eltorito) - { - outputlist_insert(&torito_desc); - } - - /* - * SVD for Joliet. - */ - if( use_Joliet) - { - outputlist_insert(&joliet_desc); - } - - /* - * Finally the last volume desctiptor. - */ - outputlist_insert(&end_vol); - - - outputlist_insert(&pathtable_desc); - if( use_Joliet) - { - outputlist_insert(&jpathtable_desc); - } - - outputlist_insert(&dirtree_desc); - if( use_Joliet) - { - outputlist_insert(&jdirtree_desc); - } - - outputlist_insert(&dirtree_clean); - - if(extension_record) - { - outputlist_insert(&extension_desc); - } - - outputlist_insert(&files_desc); - - /* - * Allow room for the various headers we will be writing. There - * will always be a primary and an end volume descriptor. - */ - last_extent = session_start; - - /* - * Calculate the size of all of the components of the disc, and assign - * extent numbers. - */ - for(opnt = out_list; opnt; opnt = opnt->of_next ) - { - if( opnt->of_size != NULL ) - { - (*opnt->of_size)(last_extent); - } - } - - /* - * Generate the contents of any of the sections that we want to generate. - * Not all of the fragments will do anything here - most will generate the - * data on the fly when we get to the write pass. - */ - for(opnt = out_list; opnt; opnt = opnt->of_next ) - { - if( opnt->of_generate != NULL ) - { - (*opnt->of_generate)(); - } - } - - if( in_image != NULL ) - { - fclose(in_image); - } - - /* - * Now go through the list of fragments and write the data that corresponds to - * each one. - */ - for(opnt = out_list; opnt; opnt = opnt->of_next ) - { - if( opnt->of_write != NULL ) - { - (*opnt->of_write)(discimage); - } - } - - if( verbose > 0 ) - { -#ifdef HAVE_SBRK - fprintf (stderr, _("Max brk space used %x\n"), - (unsigned int)(((unsigned long)sbrk(0)) - mem_start)); -#endif - fprintf (stderr, _("%llu extents written (%llu MiB)\n"), last_extent, last_extent >> 9); - } - -#ifdef VMS - return 1; -#else - return 0; -#endif -} - -void * -FDECL1(e_malloc, size_t, size) -{ - void* pt = 0; - if( (size > 0) && ((pt = malloc (size)) == NULL)) - error (1, errno, "malloc"); -return pt; -} diff --git a/util/mkisofs/mkisofs.h b/util/mkisofs/mkisofs.h deleted file mode 100644 index b699516e9..000000000 --- a/util/mkisofs/mkisofs.h +++ /dev/null @@ -1,530 +0,0 @@ -/* - * Header file mkisofs.h - assorted structure definitions and typecasts. - - Written by Eric Youngdale (1993). - - Copyright 1993 Yggdrasil Computing, Incorporated - - Copyright (C) 2009,2010 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, see . - */ - -/* - * $Id: mkisofs.h,v 1.20 1999/03/02 04:16:41 eric Exp $ - */ - -#include -#include -#include -#include - -#if (defined(ENABLE_NLS) && ENABLE_NLS) - -# include -# include - -#else /* ! (defined(ENABLE_NLS) && ENABLE_NLS) */ - -/* Disabled NLS. - The casts to 'const char *' serve the purpose of producing warnings - for invalid uses of the value returned from these functions. - On pre-ANSI systems without 'const', the config.h file is supposed to - contain "#define const". */ -# define gettext(Msgid) ((const char *) (Msgid)) -#endif /* (defined(ENABLE_NLS) && ENABLE_NLS) */ - -#define _(str) gettext(str) -#define N_(str) str - -/* This symbol is used to indicate that we do not have things like - symlinks, devices, and so forth available. Just files and dirs */ - -#ifdef VMS -#define NON_UNIXFS -#endif - -#ifdef DJGPP -#define NON_UNIXFS -#endif - -#ifdef VMS -#include -#define dirent direct -#endif - -#ifdef _WIN32 -#define NON_UNIXFS -#endif /* _WIN32 */ - -#ifndef S_IROTH -#define S_IROTH 0 -#endif - -#ifndef S_IRGRP -#define S_IRGRP 0 -#endif - -#ifndef HAVE_GETUID -static inline int -getuid () -{ - return 0; -} -#endif - -#ifndef HAVE_GETGID -static inline int -getgid () -{ - return 0; -} -#endif - -#ifndef HAVE_LSTAT -static inline int -lstat (const char *filename, struct stat *buf) -{ - return stat (filename, buf); -} -#endif - -#include -#include -#include - -#if defined(HAVE_DIRENT_H) -# include -# define NAMLEN(dirent) strlen((dirent)->d_name) -#else -# define dirent direct -# define NAMLEN(dirent) (dirent)->d_namlen -# if defined(HAVE_SYS_NDIR_H) -# include -# endif -# if defined(HAVE_SYS_DIR_H) -# include -# endif -# if defined(HAVE_NDIR_H) -# include -# endif -#endif - -#if defined(HAVE_STRING_H) -#include -#else -#if defined(HAVE_STRINGS_H) -#include -#endif -#endif - -#ifdef ultrix -extern char *strdup(); -#endif - -#ifdef __STDC__ -#define DECL(NAME,ARGS) NAME ARGS -#define FDECL1(NAME,TYPE0, ARG0) \ - NAME(TYPE0 ARG0) -#define FDECL2(NAME,TYPE0, ARG0,TYPE1, ARG1) \ - NAME(TYPE0 ARG0, TYPE1 ARG1) -#define FDECL3(NAME,TYPE0, ARG0,TYPE1, ARG1, TYPE2, ARG2) \ - NAME(TYPE0 ARG0, TYPE1 ARG1, TYPE2 ARG2) -#define FDECL4(NAME,TYPE0, ARG0,TYPE1, ARG1, TYPE2, ARG2, TYPE3, ARG3) \ - NAME(TYPE0 ARG0, TYPE1 ARG1, TYPE2 ARG2, TYPE3 ARG3) -#define FDECL5(NAME,TYPE0, ARG0,TYPE1, ARG1, TYPE2, ARG2, TYPE3, ARG3, TYPE4, ARG4) \ - NAME(TYPE0 ARG0, TYPE1 ARG1, TYPE2 ARG2, TYPE3 ARG3, TYPE4 ARG4) -#define FDECL6(NAME,TYPE0, ARG0,TYPE1, ARG1, TYPE2, ARG2, TYPE3, ARG3, TYPE4, ARG4, TYPE5, ARG5) \ - NAME(TYPE0 ARG0, TYPE1 ARG1, TYPE2 ARG2, TYPE3 ARG3, TYPE4 ARG4, TYPE5 ARG5) -#else -#define DECL(NAME,ARGS) NAME() -#define FDECL1(NAME,TYPE0, ARG0) NAME(ARG0) TYPE0 ARG0; -#define FDECL2(NAME,TYPE0, ARG0,TYPE1, ARG1) NAME(ARG0, ARG1) TYPE0 ARG0; TYPE1 ARG1; -#define FDECL3(NAME,TYPE0, ARG0,TYPE1, ARG1, TYPE2, ARG2) \ - NAME(ARG0, ARG1, ARG2) TYPE0 ARG0; TYPE1 ARG1; TYPE2 ARG2; -#define FDECL4(NAME,TYPE0, ARG0,TYPE1, ARG1, TYPE2, ARG2, TYPE3, ARG3) \ - NAME(ARG0, ARG1, ARG2, ARG3, ARG4) TYPE0 ARG0; TYPE1 ARG1; TYPE2 ARG2; TYPE3 ARG3; -#define FDECL5(NAME,TYPE0, ARG0,TYPE1, ARG1, TYPE2, ARG2, TYPE3, ARG3, TYPE4, ARG4) \ - NAME(ARG0, ARG1, ARG2, ARG3, ARG4) TYPE0 ARG0; TYPE1 ARG1; TYPE2 ARG2; TYPE3 ARG3; TYPE4 ARG4; -#define FDECL6(NAME,TYPE0, ARG0,TYPE1, ARG1, TYPE2, ARG2, TYPE3, ARG3, TYPE4, ARG4, TYPE5, ARG5) \ - NAME(ARG0, ARG1, ARG2, ARG3, ARG4, ARG5) TYPE0 ARG0; TYPE1 ARG1; TYPE2 ARG2; TYPE3 ARG3; TYPE4 ARG4; TYPE5 ARG5; -#define const -#endif - - -#ifdef __SVR4 -#include -#else -extern int optind; -extern char *optarg; -/* extern int getopt (int __argc, char **__argv, char *__optstring); */ -#endif - -#include "iso9660.h" -#include "defaults.h" - -struct directory_entry{ - struct directory_entry * next; - struct directory_entry * jnext; - struct iso_directory_record isorec; - uint64_t starting_block; - uint64_t size; - unsigned short priority; - unsigned char jreclen; /* Joliet record len */ - char * name; - char * table; - char * whole_name; - struct directory * filedir; - struct directory_entry * parent_rec; - unsigned int de_flags; - ino_t inode; /* Used in the hash table */ - dev_t dev; /* Used in the hash table */ - unsigned char * rr_attributes; - unsigned int rr_attr_size; - unsigned int total_rr_attr_size; - unsigned int got_rr_name; -}; - -struct file_hash{ - struct file_hash * next; - ino_t inode; /* Used in the hash table */ - dev_t dev; /* Used in the hash table */ - unsigned int starting_block; - unsigned int size; -}; - - -/* - * This structure is used to control the output of fragments to the cdrom - * image. Everything that will be written to the output image will eventually - * go through this structure. There are two pieces - first is the sizing where - * we establish extent numbers for everything, and the second is when we actually - * generate the contents and write it to the output image. - * - * This makes it trivial to extend mkisofs to write special things in the image. - * All you need to do is hook an additional structure in the list, and the rest - * works like magic. - * - * The three passes each do the following: - * - * The 'size' pass determines the size of each component and assigns the extent number - * for that component. - * - * The 'generate' pass will adjust the contents and pointers as required now that extent - * numbers are assigned. In some cases, the contents of the record are also generated. - * - * The 'write' pass actually writes the data to the disc. - */ -struct output_fragment -{ - struct output_fragment * of_next; -#ifdef __STDC__ - int (*of_size)(int); - int (*of_generate)(void); - int (*of_write)(FILE *); -#else - int (*of_size)(); - int (*of_generate)(); - int (*of_write)(); -#endif -}; - -extern struct output_fragment * out_list; -extern struct output_fragment * out_tail; - -extern struct output_fragment padblock_desc; -extern struct output_fragment voldesc_desc; -extern struct output_fragment joliet_desc; -extern struct output_fragment torito_desc; -extern struct output_fragment end_vol; -extern struct output_fragment pathtable_desc; -extern struct output_fragment jpathtable_desc; -extern struct output_fragment dirtree_desc; -extern struct output_fragment dirtree_clean; -extern struct output_fragment jdirtree_desc; -extern struct output_fragment extension_desc; -extern struct output_fragment files_desc; - -/* - * This structure describes one complete directory. It has pointers - * to other directories in the overall tree so that it is clear where - * this directory lives in the tree, and it also must contain pointers - * to the contents of the directory. Note that subdirectories of this - * directory exist twice in this stucture. Once in the subdir chain, - * and again in the contents chain. - */ -struct directory{ - struct directory * next; /* Next directory at same level as this one */ - struct directory * subdir; /* First subdirectory in this directory */ - struct directory * parent; - struct directory_entry * contents; - struct directory_entry * jcontents; - struct directory_entry * self; - char * whole_name; /* Entire path */ - char * de_name; /* Entire path */ - unsigned int ce_bytes; /* Number of bytes of CE entries reqd for this dir */ - unsigned int depth; - unsigned int size; - unsigned int extent; - unsigned int jsize; - unsigned int jextent; - unsigned short path_index; - unsigned short jpath_index; - unsigned short dir_flags; - unsigned short dir_nlink; -}; - -extern int goof; -extern struct directory * root; -extern struct directory * reloc_dir; -extern uint64_t next_extent; -extern uint64_t last_extent; -extern uint64_t last_extent_written; -extern uint64_t session_start; - -extern unsigned int path_table_size; -extern unsigned int path_table[4]; -extern unsigned int path_blocks; -extern char * path_table_l; -extern char * path_table_m; - -extern unsigned int jpath_table_size; -extern unsigned int jpath_table[4]; -extern unsigned int jpath_blocks; -extern char * jpath_table_l; -extern char * jpath_table_m; - -extern struct iso_directory_record root_record; -extern struct iso_directory_record jroot_record; - -extern int use_eltorito; -extern int use_embedded_boot; -extern int use_protective_msdos_label; -extern int use_eltorito_emul_floppy; -extern int use_boot_info_table; -extern int use_RockRidge; -extern int use_Joliet; -extern int rationalize; -extern int follow_links; -extern int verbose; -extern int all_files; -extern int generate_tables; -extern int print_size; -extern int split_output; -extern int omit_period; -extern int omit_version_number; -extern int transparent_compression; -extern unsigned int RR_relocation_depth; -extern int full_iso9660_filenames; -extern int split_SL_component; -extern int split_SL_field; - -/* tree.c */ -extern int DECL(stat_filter, (char *, struct stat *)); -extern int DECL(lstat_filter, (char *, struct stat *)); -extern int DECL(sort_tree,(struct directory *)); -extern struct directory * - DECL(find_or_create_directory,(struct directory *, const char *, - struct directory_entry * self, int)); -extern void DECL (finish_cl_pl_entries, (void)); -extern int DECL(scan_directory_tree,(struct directory * this_dir, - char * path, - struct directory_entry * self)); -extern int DECL(insert_file_entry,(struct directory *, char *, - char *)); - -extern void DECL(generate_iso9660_directories,(struct directory *, FILE*)); -extern void DECL(dump_tree,(struct directory * node)); -extern struct directory_entry * DECL(search_tree_file, (struct - directory * node,char * filename)); -extern void DECL(update_nlink_field,(struct directory * node)); -extern void DECL (init_fstatbuf, (void)); -extern struct stat root_statbuf; - -/* eltorito.c */ -extern void DECL(init_boot_catalog, (const char * path )); -extern void DECL(get_torito_desc, (struct eltorito_boot_descriptor * path )); - -/* write.c */ -extern int DECL(get_731,(char *)); -extern int DECL(get_733,(char *)); -extern int DECL(isonum_733,(unsigned char *)); -extern void DECL(set_723,(char *, unsigned int)); -extern void DECL(set_731,(char *, unsigned int)); -extern void DECL(set_721,(char *, unsigned int)); -extern void DECL(set_733,(char *, unsigned int)); -extern int DECL(sort_directory,(struct directory_entry **)); -extern void DECL(generate_one_directory,(struct directory *, FILE*)); -extern void DECL(memcpy_max, (char *, char *, int)); -extern int DECL(oneblock_size, (int starting_extent)); -extern struct iso_primary_descriptor vol_desc; -extern void DECL(xfwrite, (void * buffer, uint64_t count, uint64_t size, FILE * file)); -extern void DECL(set_732, (char * pnt, unsigned int i)); -extern void DECL(set_722, (char * pnt, unsigned int i)); -extern void DECL(outputlist_insert, (struct output_fragment * frag)); - -/* - * Set by user command-line to override default date values - */ - -extern char *creation_date; -extern char *modification_date; -extern char *expiration_date; -extern char *effective_date; - -/* multi.c */ - -extern FILE * in_image; -extern struct iso_directory_record * - DECL(merge_isofs,(char * path)); - -extern int DECL(free_mdinfo, (struct directory_entry **, int len)); - -extern struct directory_entry ** - DECL(read_merging_directory,(struct iso_directory_record *, int*)); -extern void - DECL(merge_remaining_entries, (struct directory *, - struct directory_entry **, int)); -extern int - DECL(merge_previous_session, (struct directory *, - struct iso_directory_record *)); - -extern int DECL(get_session_start, (int *)); - -/* joliet.c */ -int DECL(joliet_sort_tree, (struct directory * node)); - -/* match.c */ -extern int DECL(matches, (char *)); -extern void DECL(add_match, (char *)); - -/* files.c */ -struct dirent * DECL(readdir_add_files, (char **, char *, DIR *)); - -/* */ - -extern int DECL(iso9660_file_length,(const char* name, - struct directory_entry * sresult, int flag)); -extern int DECL(iso9660_date,(char *, time_t)); -extern void DECL(add_hash,(struct directory_entry *)); -extern struct file_hash * DECL(find_hash,(dev_t, ino_t)); -extern void DECL(add_directory_hash,(dev_t, ino_t)); -extern struct file_hash * DECL(find_directory_hash,(dev_t, ino_t)); -extern void DECL (flush_file_hash, (void)); -extern int DECL(delete_file_hash,(struct directory_entry *)); -extern struct directory_entry * DECL(find_file_hash,(char *)); -extern void DECL(add_file_hash,(struct directory_entry *)); -extern int DECL(generate_rock_ridge_attributes,(char *, char *, - struct directory_entry *, - struct stat *, struct stat *, - int deep_flag)); -extern char * DECL(generate_rr_extension_record,(char * id, char * descriptor, - char * source, int * size)); - -extern int DECL(check_prev_session, (struct directory_entry **, int len, - struct directory_entry *, - struct stat *, - struct stat *, - struct directory_entry **)); - -#ifdef USE_SCG -/* scsi.c */ -#ifdef __STDC__ -extern int readsecs(int startsecno, void *buffer, int sectorcount); -extern int scsidev_open(char *path); -#else -extern int readsecs(); -extern int scsidev_open(); -#endif -#endif - -extern char * extension_record; -extern int extension_record_extent; -extern int n_data_extents; - -/* These are a few goodies that can be specified on the command line, and are - filled into the root record */ - -extern char *preparer; -extern char *publisher; -extern char *copyright; -extern char *biblio; -extern char *abstract; -extern char *appid; -extern char *volset_id; -extern char *system_id; -extern char *volume_id; -extern char *boot_catalog; -extern char *boot_image; -extern char *boot_image_embed; -extern int volume_set_size; -extern int volume_sequence_number; - -extern void * DECL(e_malloc,(size_t)); - - -#define SECTOR_SIZE (2048) -#define ROUND_UP(X) ((X + (SECTOR_SIZE - 1)) & ~(SECTOR_SIZE - 1)) - -#define NEED_RE 1 -#define NEED_PL 2 -#define NEED_CL 4 -#define NEED_CE 8 -#define NEED_SP 16 - -#define PREV_SESS_DEV (sizeof(dev_t) >= 4 ? 0x7ffffffd : 0x7ffd) -#define TABLE_INODE (sizeof(ino_t) >= 4 ? 0x7ffffffe : 0x7ffe) -#define UNCACHED_INODE (sizeof(ino_t) >= 4 ? 0x7fffffff : 0x7fff) -#define UNCACHED_DEVICE (sizeof(dev_t) >= 4 ? 0x7fffffff : 0x7fff) - -#ifdef VMS -#define STAT_INODE(X) (X.st_ino[0]) -#define PATH_SEPARATOR ']' -#define SPATH_SEPARATOR "" -#else -#define STAT_INODE(X) (X.st_ino) -#define PATH_SEPARATOR '/' -#define SPATH_SEPARATOR "/" -#endif - -/* - * When using multi-session, indicates that we can reuse the - * TRANS.TBL information for this directory entry. If this flag - * is set for all entries in a directory, it means we can just - * reuse the TRANS.TBL and not generate a new one. - */ -#define SAFE_TO_REUSE_TABLE_ENTRY 0x01 -#define DIR_HAS_DOT 0x02 -#define DIR_HAS_DOTDOT 0x04 -#define INHIBIT_JOLIET_ENTRY 0x08 -#define INHIBIT_RR_ENTRY 0x10 -#define RELOCATED_DIRECTORY 0x20 -#define INHIBIT_ISO9660_ENTRY 0x40 - -/* - * Volume sequence number to use in all of the iso directory records. - */ -#define DEF_VSN 1 - -/* - * Make sure we have a definition for this. If not, take a very conservative - * guess. From what I can tell SunOS is the only one with this trouble. - */ -#ifndef NAME_MAX -#ifdef FILENAME_MAX -#define NAME_MAX FILENAME_MAX -#else -#define NAME_MAX 128 -#endif -#endif diff --git a/util/mkisofs/msdos_partition.h b/util/mkisofs/msdos_partition.h deleted file mode 100644 index 13985f7bb..000000000 --- a/util/mkisofs/msdos_partition.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2004,2007 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#ifndef MSDOS_PARTITION_H -#define MSDOS_PARTITION_H 1 - -#include - -/* The signature. */ -#define MSDOS_PARTITION_SIGNATURE ((0xaa << 8) | 0x55) - -/* This is not a flag actually, but used as if it were a flag. */ -#define MSDOS_PARTITION_TYPE_HIDDEN_FLAG 0x10 - -/* The partition entry. */ -struct msdos_partition_entry -{ - /* If active, 0x80, otherwise, 0x00. */ - uint8_t flag; - - /* The head of the start. */ - uint8_t start_head; - - /* (S | ((C >> 2) & 0xC0)) where S is the sector of the start and C - is the cylinder of the start. Note that S is counted from one. */ - uint8_t start_sector; - - /* (C & 0xFF) where C is the cylinder of the start. */ - uint8_t start_cylinder; - - /* The partition type. */ - uint8_t type; - - /* The end versions of start_head, start_sector and start_cylinder, - respectively. */ - uint8_t end_head; - uint8_t end_sector; - uint8_t end_cylinder; - - /* The start sector. Note that this is counted from zero. */ - uint32_t start; - - /* The length in sector units. */ - uint32_t length; -} __attribute__ ((packed)); - -/* The structure of MBR. */ -struct msdos_partition_mbr -{ - /* The code area (actually, including BPB). */ - uint8_t code[446]; - - /* Four partition entries. */ - struct msdos_partition_entry entries[4]; - - /* The signature 0xaa55. */ - uint16_t signature; -} __attribute__ ((packed)); - -#endif diff --git a/util/mkisofs/multi.c b/util/mkisofs/multi.c deleted file mode 100644 index d92f14530..000000000 --- a/util/mkisofs/multi.c +++ /dev/null @@ -1,1201 +0,0 @@ -/* - * File multi.c - scan existing iso9660 image and merge into - * iso9660 filesystem. Used for multisession support. - * - * Written by Eric Youngdale (1996). - * - * Copyright (C) 2009 Free Software Foundation, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - */ - -#include -#include -#include -#include -#include -#include - -#include "config.h" - -#ifndef VMS - -#ifdef HAVE_UNISTD_H -#include -#endif - -#else -#include -#include -#include "vms.h" -extern char * strdup(const char *); -#endif - -#include "mkisofs.h" -#include "iso9660.h" - -#define TF_CREATE 1 -#define TF_MODIFY 2 -#define TF_ACCESS 4 -#define TF_ATTRIBUTES 8 - -static int isonum_711 __PR((unsigned char * p)); -static int isonum_721 __PR((unsigned char * p)); -static int isonum_723 __PR((unsigned char * p)); -static int isonum_731 __PR((unsigned char * p)); - -static int DECL(merge_old_directory_into_tree, (struct directory_entry *, - struct directory *)); - -#ifdef __STDC__ -static int -isonum_711 (unsigned char * p) -#else -static int -isonum_711 (p) - unsigned char * p; -#endif -{ - return (*p & 0xff); -} - -#ifdef __STDC__ -static int -isonum_721 (unsigned char * p) -#else -static int -isonum_721 (p) - unsigned char * p; -#endif -{ - return ((p[0] & 0xff) | ((p[1] & 0xff) << 8)); -} - -#ifdef __STDC__ -static int -isonum_723 (unsigned char * p) -#else -static int -isonum_723 (p) - unsigned char * p; -#endif -{ -#if 0 - if (p[0] != p[3] || p[1] != p[2]) { - fprintf (stderr, "invalid format 7.2.3 number\n"); - exit (1); - } -#endif - return (isonum_721 (p)); -} - -#ifdef __STDC__ -static int -isonum_731 (unsigned char * p) -#else -static int -isonum_731 (p) - unsigned char * p; -#endif -{ - return ((p[0] & 0xff) - | ((p[1] & 0xff) << 8) - | ((p[2] & 0xff) << 16) - | ((p[3] & 0xff) << 24)); -} - -#ifdef __STDC__ -int -isonum_733 (unsigned char * p) -#else -int -isonum_733 (p) - unsigned char * p; -#endif -{ - return (isonum_731 (p)); -} - -FILE * in_image = NULL; - -#ifndef USE_SCG -/* - * Don't define readsecs if mkisofs is linked with - * the SCSI library. - * readsecs() will be implemented as SCSI command in this case. - * - * Use global var in_image directly in readsecs() - * the SCSI equivalent will not use a FILE* for I/O. - * - * The main point of this pointless abstraction is that Solaris won't let - * you read 2K sectors from the cdrom driver. The fact that 99.9% of the - * discs out there have a 2K sectorsize doesn't seem to matter that much. - * Anyways, this allows the use of a scsi-generics type of interface on - * Solaris. - */ -#ifdef __STDC__ -static int -readsecs(int startsecno, void *buffer, int sectorcount) -#else -static int -readsecs(startsecno, buffer, sectorcount) - int startsecno; - void *buffer; - int sectorcount; -#endif -{ - int f = fileno(in_image); - - if (lseek(f, (off_t)startsecno * SECTOR_SIZE, 0) == (off_t)-1) - error (10, errno, _("Seek error on old image\n")); - return (read(f, buffer, sectorcount * SECTOR_SIZE)); -} -#endif - -/* - * Parse the RR attributes so we can find the file name. - */ -static int -FDECL3(parse_rr, unsigned char *, pnt, int, len, struct directory_entry *,dpnt) -{ - int cont_extent, cont_offset, cont_size; - char name_buf[256]; - - cont_extent = cont_offset = cont_size = 0; - - while(len >= 4){ - if(pnt[3] != 1) { - fprintf (stderr, _("**Bad RR version attribute")); - return -1; - }; - if(strncmp((char *) pnt, "NM", 2) == 0) { - strncpy(name_buf, (char *) pnt+5, pnt[2] - 5); - name_buf[pnt[2] - 5] = 0; - dpnt->name = strdup(name_buf); - dpnt->got_rr_name = 1; - return 0; - } - - if(strncmp((char *) pnt, "CE", 2) == 0) { - cont_extent = isonum_733(pnt+4); - cont_offset = isonum_733(pnt+12); - cont_size = isonum_733(pnt+20); - }; - - len -= pnt[2]; - pnt += pnt[2]; - if(len <= 3 && cont_extent) { - unsigned char sector[SECTOR_SIZE]; - readsecs(cont_extent, sector, 1); - parse_rr(§or[cont_offset], cont_size, dpnt); - }; - }; - - /* Fall back to the iso name if no RR name found */ - if (dpnt->name == NULL) { - char *cp; - - strcpy(name_buf, dpnt->isorec.name); - cp = strchr(name_buf, ';'); - if (cp != NULL) { - *cp = '\0'; - } - - dpnt->name = strdup(name_buf); - } - - return 0; -} /* parse_rr */ - - -static int -FDECL4(check_rr_dates, struct directory_entry *, dpnt, - struct directory_entry *, current, - struct stat *, statbuf, - struct stat *,lstatbuf) -{ - int cont_extent, cont_offset, cont_size; - int offset; - unsigned char * pnt; - int len; - int same_file; - int same_file_type; - mode_t mode; - char time_buf[7]; - - - cont_extent = cont_offset = cont_size = 0; - same_file = 1; - same_file_type = 1; - - pnt = dpnt->rr_attributes; - len = dpnt->rr_attr_size; - /* - * We basically need to parse the rr attributes again, and - * dig out the dates and file types. - */ - while(len >= 4){ - if(pnt[3] != 1) { - fprintf (stderr, _("**Bad RR version attribute")); - return -1; - }; - - /* - * If we have POSIX file modes, make sure that the file type - * is the same. If it isn't, then we must always - * write the new file. - */ - if(strncmp((char *) pnt, "PX", 2) == 0) { - mode = isonum_733(pnt + 4); - if( (lstatbuf->st_mode & S_IFMT) != (mode & S_IFMT) ) - { - same_file_type = 0; - same_file = 0; - } - } - - if(strncmp((char *) pnt, "TF", 2) == 0) { - offset = 5; - if( pnt[4] & TF_CREATE ) - { - iso9660_date((char *) time_buf, lstatbuf->st_ctime); - if(memcmp(time_buf, pnt+offset, 7) == 0) - same_file = 0; - offset += 7; - } - if( pnt[4] & TF_MODIFY ) - { - iso9660_date((char *) time_buf, lstatbuf->st_mtime); - if(memcmp(time_buf, pnt+offset, 7) == 0) - same_file = 0; - offset += 7; - } - } - - if(strncmp((char *) pnt, "CE", 2) == 0) { - cont_extent = isonum_733(pnt+4); - cont_offset = isonum_733(pnt+12); - cont_size = isonum_733(pnt+20); - }; - - len -= pnt[2]; - pnt += pnt[2]; - if(len <= 3 && cont_extent) { - unsigned char sector[SECTOR_SIZE]; - - readsecs(cont_extent, sector, 1); - parse_rr(§or[cont_offset], cont_size, dpnt); - }; - }; - - /* - * If we have the same fundamental file type, then it is clearly - * safe to reuse the TRANS.TBL entry. - */ - if( same_file_type ) - { - current->de_flags |= SAFE_TO_REUSE_TABLE_ENTRY; - } - - return same_file; -} - -struct directory_entry ** -FDECL2(read_merging_directory, struct iso_directory_record *, mrootp, - int *, nent) -{ - unsigned char * cpnt; - unsigned char * cpnt1; - char * dirbuff; - int i; - struct iso_directory_record * idr; - int len; - struct directory_entry **pnt; - int rlen; - struct directory_entry **rtn; - int seen_rockridge; - unsigned char * tt_buf; - int tt_extent; - int tt_size; - - static int warning_given = 0; - - /* - * First, allocate a buffer large enough to read in the entire - * directory. - */ - dirbuff = (char *) e_malloc(isonum_733((unsigned char *)mrootp->size)); - - readsecs(isonum_733((unsigned char *)mrootp->extent), dirbuff, - isonum_733((unsigned char *)mrootp->size)/SECTOR_SIZE); - - /* - * Next look over the directory, and count up how many entries we - * have. - */ - len = isonum_733((unsigned char *)mrootp->size); - i = 0; - *nent = 0; - while(i < len ) - { - idr = (struct iso_directory_record *) &dirbuff[i]; - if(idr->length[0] == 0) - { - i = (i + SECTOR_SIZE - 1) & ~(SECTOR_SIZE - 1); - continue; - } - (*nent)++; - i += idr->length[0]; - } - - /* - * Now allocate the buffer which will hold the array we are - * about to return. - */ - rtn = (struct directory_entry **) e_malloc(*nent * sizeof(*rtn)); - - /* - * Finally, scan the directory one last time, and pick out the - * relevant bits of information, and store it in the relevant - * bits of the structure. - */ - i = 0; - pnt = rtn; - tt_extent = 0; - seen_rockridge = 0; - tt_size = 0; - while(i < len ) - { - idr = (struct iso_directory_record *) &dirbuff[i]; - if(idr->length[0] == 0) - { - i = (i + SECTOR_SIZE - 1) & ~(SECTOR_SIZE - 1); - continue; - } - *pnt = (struct directory_entry *) e_malloc(sizeof(**rtn)); - (*pnt)->next = NULL; - (*pnt)->isorec = *idr; - (*pnt)->starting_block = isonum_733((unsigned char *)idr->extent); - (*pnt)->size = isonum_733((unsigned char *)idr->size); - (*pnt)->priority = 0; - (*pnt)->name = NULL; - (*pnt)->got_rr_name = 0; - (*pnt)->table = NULL; - (*pnt)->whole_name = NULL; - (*pnt)->filedir = NULL; - (*pnt)->parent_rec = NULL; - /* - * Set this information so that we correctly cache previous - * session bits of information. - */ - (*pnt)->inode = (*pnt)->starting_block; - (*pnt)->dev = PREV_SESS_DEV; - (*pnt)->rr_attributes = NULL; - (*pnt)->rr_attr_size = 0; - (*pnt)->total_rr_attr_size = 0; - (*pnt)->de_flags = SAFE_TO_REUSE_TABLE_ENTRY; - - /* - * Check for and parse any RR attributes for the file. - * All we are really looking for here is the original name - * of the file. - */ - rlen = idr->length[0] & 0xff; - cpnt = (unsigned char *) idr; - - rlen -= sizeof(struct iso_directory_record); - cpnt += sizeof(struct iso_directory_record); - - rlen += sizeof(idr->name); - cpnt -= sizeof(idr->name); - - rlen -= idr->name_len[0]; - cpnt += idr->name_len[0]; - - if((idr->name_len[0] & 1) == 0){ - cpnt++; - rlen--; - }; - - if( rlen != 0 ) - { - (*pnt)->total_rr_attr_size = (*pnt)->rr_attr_size = rlen; - (*pnt)->rr_attributes = e_malloc(rlen); - memcpy((*pnt)->rr_attributes, cpnt, rlen); - seen_rockridge = 1; - } - - /* - * Now zero out the remainder of the name field. - */ - cpnt = (unsigned char *) &(*pnt)->isorec.name; - cpnt += idr->name_len[0]; - memset(cpnt, 0, sizeof((*pnt)->isorec.name) - idr->name_len[0]); - - parse_rr((*pnt)->rr_attributes, rlen, *pnt); - - if( ((*pnt)->isorec.name_len[0] == 1) - && ( ((*pnt)->isorec.name[0] == 0) - || ((*pnt)->isorec.name[0] == 1)) ) - { - if( (*pnt)->name != NULL ) - { - free((*pnt)->name); - } - if( (*pnt)->whole_name != NULL ) - { - free((*pnt)->whole_name); - } - if( (*pnt)->isorec.name[0] == 0 ) - { - (*pnt)->name = strdup("."); - } - else - { - (*pnt)->name = strdup(".."); - } - } - -#ifdef DEBUG - fprintf(stderr, "got DE name: %s\n", (*pnt)->name); -#endif - - if( strncmp(idr->name, "TRANS.TBL", 9) == 0) - { - if( (*pnt)->name != NULL ) - { - free((*pnt)->name); - } - if( (*pnt)->whole_name != NULL ) - { - free((*pnt)->whole_name); - } - (*pnt)->name = strdup(""); - tt_extent = isonum_733((unsigned char *)idr->extent); - tt_size = isonum_733((unsigned char *)idr->size); - } - - pnt++; - i += idr->length[0]; - } - - /* - * If there was a TRANS.TBL;1 entry, then grab it, read it, and use it - * to get the filenames of the files. Also, save the table info, just - * in case we need to use it. - */ - if( tt_extent != 0 && tt_size != 0 ) - { - tt_buf = (unsigned char *) e_malloc(tt_size); - readsecs(tt_extent, tt_buf, tt_size/SECTOR_SIZE); - - /* - * Loop through the file, examine each entry, and attempt to - * attach it to the correct entry. - */ - cpnt = tt_buf; - cpnt1 = tt_buf; - while( cpnt - tt_buf < tt_size ) - { - while(*cpnt1 != '\n' && *cpnt1 != '\0') cpnt1++; - *cpnt1 = '\0'; - - for(pnt = rtn, i = 0; i <*nent; i++, pnt++) - { - rlen = isonum_711((*pnt)->isorec.name_len); - if( strncmp((char *) cpnt + 2, (*pnt)->isorec.name, - rlen) == 0 - && cpnt[2+rlen] == ' ') - { - (*pnt)->table = e_malloc(strlen((char*)cpnt) - 33); - sprintf((*pnt)->table, "%c\t%s\n", - *cpnt, cpnt+37); - if( !(*pnt)->got_rr_name ) - { - if ((*pnt)->name != NULL) { - free((*pnt)->name); - } - (*pnt)->name = strdup((char *) cpnt+37); - } - break; - } - } - cpnt = cpnt1 + 1; - cpnt1 = cpnt; - } - - free(tt_buf); - } - else if( !seen_rockridge && !warning_given ) - { - /* - * Warn the user that iso (8.3) names were used because neither - * Rock Ridge (-R) nor TRANS.TBL (-T) name translations were found. - */ - fprintf (stderr, _("Warning: Neither Rock Ridge (-R) nor TRANS.TBL (-T) " - "name translations were found on previous session. " - "ISO (8.3) file names have been used instead.\n")); - warning_given = 1; - } - - if( dirbuff != NULL ) - { - free(dirbuff); - } - - return rtn; -} /* read_merging_directory */ - -/* - * Free any associated data related to the structures. - */ -int -FDECL2(free_mdinfo, struct directory_entry ** , ptr, int, len ) -{ - int i; - struct directory_entry **p; - - p = ptr; - for(i=0; iname != NULL ) - { - free((*p)->name); - } - - if( (*p)->whole_name != NULL ) - { - free((*p)->whole_name); - } - - if( (*p)->rr_attributes != NULL ) - { - free((*p)->rr_attributes); - } - - if( (*p)->table != NULL ) - { - free((*p)->table); - } - - free(*p); - - } - - free(ptr); - return 0; -} - -/* - * Search the list to see if we have any entries from the previous - * session that match this entry. If so, copy the extent number - * over so we don't bother to write it out to the new session. - */ - -int -FDECL6(check_prev_session, struct directory_entry ** , ptr, int, len, - struct directory_entry *, curr_entry, - struct stat *, statbuf, struct stat *, lstatbuf, - struct directory_entry **, odpnt) -{ - int i; - - for( i=0; i < len; i++ ) - { - if( ptr[i] == NULL ) - { - continue; - } - -#if 0 - if( ptr[i]->name != NULL && ptr[i]->isorec.name_len[0] == 1 - && ptr[i]->name[0] == '\0' ) - { - continue; - } - if( ptr[i]->name != NULL && ptr[i]->isorec.name_len[0] == 1 - && ptr[i]->name[0] == 1) - { - continue; - } -#else - if( ptr[i]->name != NULL && strcmp(ptr[i]->name, ".") == 0 ) - { - continue; - } - if( ptr[i]->name != NULL && strcmp(ptr[i]->name, "..") == 0 ) - { - continue; - } -#endif - - if( ptr[i]->name != NULL - && strcmp(ptr[i]->name, curr_entry->name) != 0 ) - { - continue; - } - - /* - * We know that the files have the same name. If they also have - * the same file type (i.e. file, dir, block, etc), then we - * can safely reuse the TRANS.TBL entry for this file. - * The check_rr_dates function will do this for us. - * - * Verify that the file type and dates are consistent. - * If not, we probably have a different file, and we need - * to write it out again. - */ - if( (ptr[i]->rr_attributes != NULL) - && (check_rr_dates(ptr[i], curr_entry, statbuf, lstatbuf)) ) - { - goto found_it; - } - - - /* - * Verify size and timestamp. If rock ridge is in use, we need - * to compare dates from RR too. Directories are special, we - * calculate their size later. - */ - if( (curr_entry->isorec.flags[0] & 2) == 0 - && ptr[i]->size != curr_entry->size ) - { - goto found_it; - } - - if( memcmp(ptr[i]->isorec.date, curr_entry->isorec.date,7) != 0 ) - { - goto found_it; - } - - /* - * Never ever reuse directory extents. See comments in - * tree.c for an explaination of why this must be the case. - */ - if( (curr_entry->isorec.flags[0] & 2) != 0 ) - { - goto found_it; - } - - memcpy(curr_entry->isorec.extent, ptr[i]->isorec.extent, 8); - curr_entry->de_flags |= SAFE_TO_REUSE_TABLE_ENTRY; - goto found_it; - } - return 0; - -found_it: - if( odpnt != NULL ) - { - *odpnt = ptr[i]; - } - else - { - free(ptr[i]); - } - ptr[i] = NULL; - return 0; -} - -/* - * merge_isofs: Scan an existing image, and return a pointer - * to the root directory for this image. - */ -struct iso_directory_record * FDECL1(merge_isofs, char *, path) -{ - char buffer[SECTOR_SIZE]; - int file_addr; - int i; - struct iso_primary_descriptor * pri = NULL; - struct iso_directory_record * rootp; - struct iso_volume_descriptor * vdp; - - /* - * Start by opening up the image and searching for the volume header. - * Ultimately, we need to search for volume headers in multiple places - * because we might be starting with a multisession image. - * FIXME(eric). - */ - -#ifndef USE_SCG - in_image = fopen(path, "rb"); - if( in_image == NULL ) - { - return NULL; - } -#else - if (strchr(path, '/')) { - in_image = fopen(path, "rb"); - if( in_image == NULL ) { - return NULL; - } - } else { - if (scsidev_open(path) < 0) - return NULL; - } -#endif - - get_session_start(&file_addr); - - for(i = 0; i< 100; i++) - { - if (readsecs(file_addr/SECTOR_SIZE, &buffer, - sizeof(buffer)/SECTOR_SIZE) != sizeof(buffer)) - error (10, errno, _("Read error on old image %s\n"), path); - - vdp = (struct iso_volume_descriptor *)buffer; - - if( (strncmp(vdp->id, ISO_STANDARD_ID, sizeof vdp->id) == 0) - && (isonum_711((unsigned char *) vdp->type) == ISO_VD_PRIMARY) ) - { - break; - } - file_addr += SECTOR_SIZE; - } - - if( i == 100 ) - { - return NULL; - } - - pri = (struct iso_primary_descriptor *)vdp; - - /* - * Check the blocksize of the image to make sure it is compatible. - */ - if( (isonum_723 ((unsigned char *) pri->logical_block_size) != SECTOR_SIZE) - || (isonum_723 ((unsigned char *) pri->volume_set_size) != 1) ) - { - return NULL; - } - - /* - * Get the location and size of the root directory. - */ - rootp = (struct iso_directory_record *) - malloc(sizeof(struct iso_directory_record)); - - memcpy(rootp, pri->root_directory_record, sizeof(*rootp)); - - return rootp; -} - -void FDECL3(merge_remaining_entries, struct directory *, this_dir, - struct directory_entry **, pnt, - int, n_orig) -{ - int i; - struct directory_entry * s_entry; - unsigned int ttbl_extent = 0; - unsigned int ttbl_index = 0; - char whole_path[1024]; - - /* - * Whatever is leftover in the list needs to get merged back - * into the directory. - */ - for( i=0; i < n_orig; i++ ) - { - if( pnt[i] == NULL ) - { - continue; - } - - if( pnt[i]->name != NULL && pnt[i]->whole_name == NULL) - { - /* - * Set the name for this directory. - */ - strcpy(whole_path, this_dir->de_name); - strcat(whole_path, SPATH_SEPARATOR); - strcat(whole_path, pnt[i]->name); - - pnt[i]->whole_name = strdup(whole_path); - } - - if( pnt[i]->name != NULL - && strcmp(pnt[i]->name, "") == 0 ) - { - ttbl_extent = isonum_733((unsigned char *) pnt[i]->isorec.extent); - ttbl_index = i; - continue; - } - /* - * Skip directories for now - these need to be treated - * differently. - */ - if( (pnt[i]->isorec.flags[0] & 2) != 0 ) - { - /* - * FIXME - we need to insert this directory into the - * tree, so that the path tables we generate will - * be correct. - */ - if( (strcmp(pnt[i]->name, ".") == 0) - || (strcmp(pnt[i]->name, "..") == 0) ) - { - free(pnt[i]); - pnt[i] = NULL; - continue; - } - else - { - merge_old_directory_into_tree(pnt[i], this_dir); - } - } - pnt[i]->next = this_dir->contents; - pnt[i]->filedir = this_dir; - this_dir->contents = pnt[i]; - pnt[i] = NULL; - } - - - /* - * If we don't have an entry for the translation table, then - * don't bother trying to copy the starting extent over. - * Note that it is possible that if we are copying the entire - * directory, the entry for the translation table will have already - * been inserted into the linked list and removed from the old - * entries list, in which case we want to leave the extent number - * as it was before. - */ - if( ttbl_extent == 0 ) - { - return; - } - - /* - * Finally, check the directory we are creating to see whether - * there are any new entries in it. If there are not, we can - * reuse the same translation table. - */ - for(s_entry = this_dir->contents; s_entry; s_entry = s_entry->next) - { - /* - * Don't care about '.' or '..'. They are never in the table - * anyways. - */ - if( s_entry->name != NULL && strcmp(s_entry->name, ".") == 0 ) - { - continue; - } - if( s_entry->name != NULL && strcmp(s_entry->name, "..") == 0 ) - { - continue; - } - if( strcmp(s_entry->name, "") == 0) - { - continue; - } - if( (s_entry->de_flags & SAFE_TO_REUSE_TABLE_ENTRY) == 0 ) - { - return; - } - } - - /* - * Locate the translation table, and re-use the same extent. - * It isn't clear that there should ever be one in there already - * so for now we try and muddle through the best we can. - */ - for(s_entry = this_dir->contents; s_entry; s_entry = s_entry->next) - { - if( strcmp(s_entry->name, "") == 0) - { - fprintf (stderr, "Should never get here\n"); - set_733(s_entry->isorec.extent, ttbl_extent); - return; - } - } - - pnt[ttbl_index]->next = this_dir->contents; - pnt[ttbl_index]->filedir = this_dir; - this_dir->contents = pnt[ttbl_index]; - pnt[ttbl_index] = NULL; -} - - -/* - * Here we have a case of a directory that has completely disappeared from - * the face of the earth on the tree we are mastering from. Go through and - * merge it into the tree, as well as everything beneath it. - * - * Note that if a directory has been moved for some reason, this will - * incorrectly pick it up and attempt to merge it back into the old - * location. FIXME(eric). - */ -static int -FDECL2(merge_old_directory_into_tree, struct directory_entry *, dpnt, - struct directory *, parent) -{ - struct directory_entry **contents = NULL; - int i; - int n_orig; - struct directory * this_dir, *next_brother; - char whole_path[1024]; - - this_dir = (struct directory *) e_malloc(sizeof(struct directory)); - memset(this_dir, 0, sizeof(struct directory)); - this_dir->next = NULL; - this_dir->subdir = NULL; - this_dir->self = dpnt; - this_dir->contents = NULL; - this_dir->size = 0; - this_dir->extent = 0; - this_dir->depth = parent->depth + 1; - this_dir->parent = parent; - if(!parent->subdir) - parent->subdir = this_dir; - else { - next_brother = parent->subdir; - while(next_brother->next) next_brother = next_brother->next; - next_brother->next = this_dir; - } - - /* - * Set the name for this directory. - */ - strcpy(whole_path, parent->de_name); - strcat(whole_path, SPATH_SEPARATOR); - strcat(whole_path, dpnt->name); - this_dir->de_name = strdup(whole_path); - this_dir->whole_name = strdup(whole_path); - - /* - * Now fill this directory using information from the previous - * session. - */ - contents = read_merging_directory(&dpnt->isorec, &n_orig); - /* - * Start by simply copying the '.', '..' and non-directory - * entries to this directory. Technically we could let - * merge_remaining_entries handle this, but it gets rather confused - * by the '.' and '..' entries. - */ - for(i=0; i < n_orig; i ++ ) - { - /* - * We can always reuse the TRANS.TBL in this particular case. - */ - contents[i]->de_flags |= SAFE_TO_REUSE_TABLE_ENTRY; - - if( ((contents[i]->isorec.flags[0] & 2) != 0) - && (i >= 2) ) - { - continue; - } - - /* - * If we have a directory, don't reuse the extent number. - */ - if( (contents[i]->isorec.flags[0] & 2) != 0 ) - { - memset(contents[i]->isorec.extent, 0, 8); - - if( strcmp(contents[i]->name, ".") == 0 ) - this_dir->dir_flags |= DIR_HAS_DOT; - - if( strcmp(contents[i]->name, "..") == 0 ) - this_dir->dir_flags |= DIR_HAS_DOTDOT; - } - - /* - * Set the whole name for this file. - */ - strcpy(whole_path, this_dir->whole_name); - strcat(whole_path, SPATH_SEPARATOR); - strcat(whole_path, contents[i]->name); - - contents[i]->whole_name = strdup(whole_path); - - contents[i]->next = this_dir->contents; - contents[i]->filedir = this_dir; - this_dir->contents = contents[i]; - contents[i] = NULL; - } - - /* - * Zero the extent number for ourselves. - */ - memset(dpnt->isorec.extent, 0, 8); - - /* - * Anything that is left are other subdirectories that need to be merged. - */ - merge_remaining_entries(this_dir, contents, n_orig); - free_mdinfo(contents, n_orig); -#if 0 - /* - * This is no longer required. The post-scan sort will handle - * all of this for us. - */ - sort_n_finish(this_dir); -#endif - - return 0; -} - - -char * cdwrite_data = NULL; - -int -FDECL1(get_session_start, int *, file_addr) -{ - char * pnt; - -#ifdef CDWRITE_DETERMINES_FIRST_WRITABLE_ADDRESS - /* - * FIXME(eric). We need to coordinate with cdwrite to obtain - * the parameters. For now, we assume we are writing the 2nd session, - * so we start from the session that starts at 0. - */ - - *file_addr = (16 << 11); - - /* - * We need to coordinate with cdwrite to get the next writable address - * from the device. Here is where we use it. - */ - session_start = last_extent = last_extent_written = cdwrite_result(); - -#else - - if( cdwrite_data == NULL ) - error (1, 0, _("Special parameters for cdwrite not specified with -C\n")); - - /* - * Next try and find the ',' in there which delimits the two numbers. - */ - pnt = strchr(cdwrite_data, ','); - if( pnt == NULL ) - error (1, 0, _("Malformed cdwrite parameters\n")); - - *pnt = '\0'; - if (file_addr != NULL) { - *file_addr = atol(cdwrite_data) * SECTOR_SIZE; - } - pnt++; - - session_start = last_extent = last_extent_written = atol(pnt); - - pnt--; - *pnt = ','; - -#endif - return 0; -} - -/* - * This function scans the directory tree, looking for files, and it makes - * note of everything that is found. We also begin to construct the ISO9660 - * directory entries, so that we can determine how large each directory is. - */ - -int -FDECL2(merge_previous_session,struct directory *, this_dir, - struct iso_directory_record *, mrootp) -{ - struct directory_entry **orig_contents = NULL; - struct directory_entry * odpnt = NULL; - int n_orig; - struct directory_entry * s_entry; - int status, lstatus; - struct stat statbuf, lstatbuf; - - /* - * Parse the same directory in the image that we are merging - * for multisession stuff. - */ - orig_contents = read_merging_directory(mrootp, &n_orig); - if( orig_contents == NULL ) - { - return 0; - } - - -/* Now we scan the directory itself, and look at what is inside of it. */ - - for(s_entry = this_dir->contents; s_entry; s_entry = s_entry->next) - { - status = stat_filter(s_entry->whole_name, &statbuf); - lstatus = lstat_filter(s_entry->whole_name, &lstatbuf); - - /* - * We always should create an entirely new directory tree whenever - * we generate a new session, unless there were *no* changes whatsoever - * to any of the directories, in which case it would be kind of pointless - * to generate a new session. - * - * I believe it is possible to rigorously prove that any change anywhere - * in the filesystem will force the entire tree to be regenerated - * because the modified directory will get a new extent number. Since - * each subdirectory of the changed directory has a '..' entry, all of - * them will need to be rewritten too, and since the parent directory - * of the modified directory will have an extent pointer to the directory - * it too will need to be rewritten. Thus we will never be able to reuse - * any directory information when writing new sessions. - * - * We still check the previous session so we can mark off the equivalent - * entry in the list we got from the original disc, however. - */ - - /* - * The check_prev_session function looks for an identical entry in - * the previous session. If we see it, then we copy the extent - * number to s_entry, and cross it off the list. - */ - check_prev_session(orig_contents, n_orig, s_entry, - &statbuf, &lstatbuf, &odpnt); - - if(S_ISDIR(statbuf.st_mode) && odpnt != NULL) - { - int dflag; - - if (strcmp(s_entry->name,".") && strcmp(s_entry->name,"..")) - { - struct directory * child; - - child = find_or_create_directory(this_dir, - s_entry->whole_name, - s_entry, 1); - dflag = merge_previous_session(child, - &odpnt->isorec); - /* If unable to scan directory, mark this as a non-directory */ - if(!dflag) - lstatbuf.st_mode = (lstatbuf.st_mode & ~S_IFMT) | S_IFREG; - free(odpnt); - odpnt = NULL; - } - } - } - - /* - * Whatever is left over, are things which are no longer in the tree - * on disk. We need to also merge these into the tree. - */ - merge_remaining_entries(this_dir, orig_contents, n_orig); - free_mdinfo(orig_contents, n_orig); - - return 1; -} - diff --git a/util/mkisofs/name.c b/util/mkisofs/name.c deleted file mode 100644 index 272471e93..000000000 --- a/util/mkisofs/name.c +++ /dev/null @@ -1,394 +0,0 @@ -/* - * File name.c - map full Unix file names to unique 8.3 names that - * would be valid on DOS. - * - - Written by Eric Youngdale (1993). - - Copyright 1993 Yggdrasil Computing, Incorporated - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#include "config.h" -#include "mkisofs.h" - -#include - -extern int allow_leading_dots; - -/* - * Function: iso9660_file_length - * - * Purpose: Map file name to 8.3 format, return length - * of result. - * - * Arguments: name file name we need to map. - * sresult directory entry structure to contain mapped name. - * dirflag flag indicating whether this is a directory or not. - * - * Notes: This procedure probably needs to be rationalized somehow. - * New options to affect the behavior of this function - * would also be nice to have. - */ -int FDECL3(iso9660_file_length, - const char*, name, - struct directory_entry *, sresult, - int, dirflag) -{ - char * c; - int chars_after_dot = 0; - int chars_before_dot = 0; - int current_length = 0; - int extra = 0; - int ignore = 0; - char * last_dot; - const char * pnt; - int priority = 32767; - char * result; - int seen_dot = 0; - int seen_semic = 0; - int tildes = 0; - - result = sresult->isorec.name; - - /* - * For the '.' entry, generate the correct record, and return - * 1 for the length. - */ - if(strcmp(name,".") == 0) - { - if(result) - { - *result = 0; - } - return 1; - } - - /* - * For the '..' entry, generate the correct record, and return - * 1 for the length. - */ - if(strcmp(name,"..") == 0) - { - if(result) - { - *result++ = 1; - *result++ = 0; - } - return 1; - } - - /* - * Now scan the directory one character at a time, and figure out - * what to do. - */ - pnt = name; - - /* - * Find the '.' that we intend to use for the extension. Usually this - * is the last dot, but if we have . followed by nothing or a ~, we - * would consider this to be unsatisfactory, and we keep searching. - */ - last_dot = strrchr (pnt,'.'); - if( (last_dot != NULL) - && ( (last_dot[1] == '~') - || (last_dot[1] == '\0')) ) - { - c = last_dot; - *c = '\0'; - last_dot = strrchr (pnt,'.'); - *c = '.'; - } - - while(*pnt) - { -#ifdef VMS - if( strcmp(pnt,".DIR;1") == 0 ) - { - break; - } -#endif - - /* - * This character indicates a Unix style of backup file - * generated by some editors. Lower the priority of - * the file. - */ - if(*pnt == '#') - { - priority = 1; - pnt++; - continue; - } - - /* - * This character indicates a Unix style of backup file - * generated by some editors. Lower the priority of - * the file. - */ - if(*pnt == '~') - { - priority = 1; - tildes++; - pnt++; - continue; - } - - /* - * This might come up if we had some joker already try and put - * iso9660 version numbers into the file names. This would be - * a silly thing to do on a Unix box, but we check for it - * anyways. If we see this, then we don't have to add our - * own version number at the end. - * UNLESS the ';' is part of the filename and no version - * number is following. [VK] - */ - if(*pnt == ';') - { - /* [VK] */ - if (pnt[1] != '\0' && (pnt[1] < '0' || pnt[1] > '9')) - { - pnt++; - ignore++; - continue; - } - } - - /* - * If we have a name with multiple '.' characters, we ignore everything - * after we have gotten the extension. - */ - if(ignore) - { - pnt++; - continue; - } - - /* - * Spin past any iso9660 version number we might have. - */ - if(seen_semic) - { - if(*pnt >= '0' && *pnt <= '9') - { - *result++ = *pnt; - } - extra++; - pnt++; - continue; - } - - /* - * If we have full names, the names we generate will not - * work on a DOS machine, since they are not guaranteed - * to be 8.3. Nonetheless, in many cases this is a useful - * option. We still only allow one '.' character in the - * name, however. - */ - if(full_iso9660_filenames) - { - /* Here we allow a more relaxed syntax. */ - if(*pnt == '.') - { - if (seen_dot) - { - ignore++; - continue; - } - seen_dot++; - } - if(current_length < 30) - { - if( !isascii (*pnt)) - { - *result++ = '_'; - } - else - { - *result++ = (islower((unsigned char)*pnt) ? toupper((unsigned char)*pnt) : *pnt); - } - } - } - else - { - /* - * Dos style filenames. We really restrict the - * names here. - */ - /* It would be nice to have .tar.gz transform to .tgz, - * .ps.gz to .psz, ... - */ - if(*pnt == '.') - { - if (!chars_before_dot && !allow_leading_dots) - { - /* DOS can't read files with dot first */ - chars_before_dot++; - if (result) - { - *result++ = '_'; /* Substitute underscore */ - } - } - else if( pnt != last_dot ) - { - /* - * If this isn't the dot that we use for the extension, - * then change the character into a '_' instead. - */ - if(chars_before_dot < 8) - { - chars_before_dot++; - if(result) - { - *result++ = '_'; - } - } - } - else - { - if (seen_dot) - { - ignore++; continue; - } - if(result) - { - *result++ = '.'; - } - seen_dot++; - } - } - else - { - if( (seen_dot && (chars_after_dot < 3) && ++chars_after_dot) - || (!seen_dot && (chars_before_dot < 8) && ++chars_before_dot) ) - { - if(result) - { - switch (*pnt) - { - default: - if( !isascii (*pnt) ) - { - *result++ = '_'; - } - else - { - *result++ = islower((unsigned char)*pnt) ? toupper((unsigned char)*pnt) : *pnt; - } - break; - - /* - * Descriptions of DOS's 'Parse Filename' - * (function 29H) describes V1 and V2.0+ - * separator and terminator characters. - * These characters in a DOS name make - * the file visible but un-manipulable - * (all useful operations error off. - */ - /* separators */ - case '+': - case '=': - case '%': /* not legal DOS filename */ - case ':': - case ';': /* already handled */ - case '.': /* already handled */ - case ',': /* already handled */ - case '\t': - case ' ': - /* V1 only separators */ - case '/': - case '"': - case '[': - case ']': - /* terminators */ - case '>': - case '<': - case '|': - /* Hmm - what to do here? Skip? - * Win95 looks like it substitutes '_' - */ - *result++ = '_'; - break; - } /* switch (*pnt) */ - } /* if (result) */ - } /* if (chars_{after,before}_dot) ... */ - } /* else *pnt == '.' */ - } /* else DOS file names */ - current_length++; - pnt++; - } /* while (*pnt) */ - - /* - * OK, that wraps up the scan of the name. Now tidy up a few other - * things. - */ - - /* - * Look for emacs style of numbered backups, like foo.c.~3~. If - * we see this, convert the version number into the priority - * number. In case of name conflicts, this is what would end - * up being used as the 'extension'. - */ - if(tildes == 2) - { - int prio1 = 0; - pnt = name; - while (*pnt && *pnt != '~') - { - pnt++; - } - if (*pnt) - { - pnt++; - } - while(*pnt && *pnt != '~') - { - prio1 = 10*prio1 + *pnt - '0'; - pnt++; - } - priority = prio1; - } - - /* - * If this is not a directory, force a '.' in case we haven't - * seen one, and add a version number if we haven't seen one - * of those either. - */ - if (!dirflag) - { - if (!seen_dot && !omit_period) - { - if (result) *result++ = '.'; - extra++; - } - if(!omit_version_number && !seen_semic) - { - if(result) - { - *result++ = ';'; - *result++ = '1'; - }; - extra += 2; - } - } - - if(result) - { - *result++ = 0; - } - sresult->priority = priority; - - return (chars_before_dot + chars_after_dot + seen_dot + extra); -} diff --git a/util/mkisofs/rock.c b/util/mkisofs/rock.c deleted file mode 100644 index a7a39f774..000000000 --- a/util/mkisofs/rock.c +++ /dev/null @@ -1,597 +0,0 @@ -/* - * File rock.c - generate RRIP records for iso9660 filesystems. - - Written by Eric Youngdale (1993). - - Copyright 1993 Yggdrasil Computing, Incorporated - - Copyright (C) 2009,2010 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, see . - */ - -#include - -#include "config.h" - -#ifndef VMS -#if defined(MAJOR_IN_SYSMACROS) -#include -#endif - -#ifdef HAVE_UNISTD_H -#include -#endif - -#endif -#if defined(MAJOR_IN_MKDEV) -#include -#include -#endif - -#include "mkisofs.h" -#include "iso9660.h" -#include -#include - -#ifdef DOESNT_WORK - -#ifdef NON_UNIXFS -#define S_ISLNK(m) (0) -#else -#ifndef S_ISLNK -#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) -#endif -#endif - -#else -#include -#endif - -#define SU_VERSION 1 - -#define SL_ROOT 8 -#define SL_PARENT 4 -#define SL_CURRENT 2 -#define SL_CONTINUE 1 - -#define CE_SIZE 28 -#define CL_SIZE 12 -#define ER_SIZE 8 -#define NM_SIZE 5 -#define PL_SIZE 12 -#define PN_SIZE 20 -#define PX_SIZE 36 -#define RE_SIZE 4 -#define SL_SIZE 20 -#define ZZ_SIZE 15 -#ifdef __QNX__ -#define TF_SIZE (5 + 4 * 7) -#else -#define TF_SIZE (5 + 3 * 7) -#endif - -/* If we need to store this number of bytes, make sure we - do not box ourselves in so that we do not have room for - a CE entry for the continuation record */ - -#define MAYBE_ADD_CE_ENTRY(BYTES) \ - ((unsigned) ((BYTES) + CE_SIZE + currlen + ipnt) > (unsigned) (recstart + reclimit) ? 1 : 0) - -/* - * Buffer to build RR attributes - */ - -static unsigned char Rock[16384]; -static unsigned char symlink_buff[256]; -static int ipnt = 0; -static int recstart = 0; -static int currlen = 0; -static int mainrec = 0; -static int reclimit; - -static void add_CE_entry __PR((void)); - -static void add_CE_entry(){ - if(recstart) - set_733((char*)Rock + recstart - 8, ipnt + 28 - recstart); - Rock[ipnt++] ='C'; - Rock[ipnt++] ='E'; - Rock[ipnt++] = CE_SIZE; - Rock[ipnt++] = SU_VERSION; - set_733((char*)Rock + ipnt, 0); - ipnt += 8; - set_733((char*)Rock + ipnt, 0); - ipnt += 8; - set_733((char*)Rock + ipnt, 0); - ipnt += 8; - recstart = ipnt; - currlen = 0; - if(!mainrec) mainrec = ipnt; - reclimit = SECTOR_SIZE - 8; /* Limit to one sector */ -} - -#ifdef __STDC__ -int generate_rock_ridge_attributes (char * whole_name, char * name, - struct directory_entry * s_entry, - struct stat * statbuf, - struct stat * lstatbuf, - int deep_opt) -#else -int generate_rock_ridge_attributes (whole_name, name, - s_entry, - statbuf, - lstatbuf, - deep_opt) -char * whole_name; char * name; struct directory_entry * s_entry; -struct stat * statbuf, *lstatbuf; -int deep_opt; -#endif -{ - int flagpos, flagval; - int need_ce; - - statbuf = statbuf; /* this shuts up unreferenced compiler warnings */ - mainrec = recstart = ipnt = 0; - reclimit = 0xf8; - - /* no need to fill in the RR stuff if we won't see the file */ - if (s_entry->de_flags & INHIBIT_ISO9660_ENTRY) - return 0; - - /* Obtain the amount of space that is currently used for the directory - record. Assume max for name, since name conflicts may cause us - to rename the file later on */ - currlen = sizeof(s_entry->isorec); - - /* Identify that we are using the SUSP protocol */ - if(deep_opt & NEED_SP){ - Rock[ipnt++] ='S'; - Rock[ipnt++] ='P'; - Rock[ipnt++] = 7; - Rock[ipnt++] = SU_VERSION; - Rock[ipnt++] = 0xbe; - Rock[ipnt++] = 0xef; - Rock[ipnt++] = 0; - }; - - /* First build the posix name field */ - Rock[ipnt++] ='R'; - Rock[ipnt++] ='R'; - Rock[ipnt++] = 5; - Rock[ipnt++] = SU_VERSION; - flagpos = ipnt; - flagval = 0; - Rock[ipnt++] = 0; /* We go back and fix this later */ - - if(strcmp(name,".") && strcmp(name,"..")){ - char * npnt; - int remain, use; - - remain = strlen(name); - npnt = name; - - while(remain){ - use = remain; - need_ce = 0; - /* Can we fit this SUSP and a CE entry? */ - if(use + currlen + CE_SIZE + (ipnt - recstart) > reclimit) { - use = reclimit - currlen - CE_SIZE - (ipnt - recstart); - need_ce++; - } - - /* Only room for 256 per SUSP field */ - if(use > 0xf8) use = 0xf8; - - /* First build the posix name field */ - Rock[ipnt++] ='N'; - Rock[ipnt++] ='M'; - Rock[ipnt++] = NM_SIZE + use; - Rock[ipnt++] = SU_VERSION; - Rock[ipnt++] = (remain != use ? 1 : 0); - flagval |= (1<<3); - strncpy((char *)&Rock[ipnt], npnt, use); - npnt += use; - ipnt += use; - remain -= use; - if(remain && need_ce) add_CE_entry(); - }; - }; - - /* - * Add the posix modes - */ - if(MAYBE_ADD_CE_ENTRY(PX_SIZE)) add_CE_entry(); - Rock[ipnt++] ='P'; - Rock[ipnt++] ='X'; - Rock[ipnt++] = PX_SIZE; - Rock[ipnt++] = SU_VERSION; - flagval |= (1<<0); - set_733((char*)Rock + ipnt, lstatbuf->st_mode); - ipnt += 8; - set_733((char*)Rock + ipnt, lstatbuf->st_nlink); - ipnt += 8; - set_733((char*)Rock + ipnt, lstatbuf->st_uid); - ipnt += 8; - set_733((char*)Rock + ipnt, lstatbuf->st_gid); - ipnt += 8; - - /* - * Check for special devices - */ -#ifndef NON_UNIXFS - if (S_ISCHR(lstatbuf->st_mode) || S_ISBLK(lstatbuf->st_mode)) { - if(MAYBE_ADD_CE_ENTRY(PN_SIZE)) add_CE_entry(); - Rock[ipnt++] ='P'; - Rock[ipnt++] ='N'; - Rock[ipnt++] = PN_SIZE; - Rock[ipnt++] = SU_VERSION; - flagval |= (1<<1); -#if defined(MAJOR_IN_SYSMACROS) || defined(MAJOR_IN_MKDEV) - set_733((char*)Rock + ipnt, major(lstatbuf->st_rdev )); - ipnt += 8; - set_733((char*)Rock + ipnt, minor(lstatbuf->st_rdev)); - ipnt += 8; -#else - /* - * If we don't have sysmacros.h, then we have to guess as to how - * best to pick apart the device number for major/minor. - * Note: this may very well be wrong for many systems, so - * it is always best to use the major/minor macros if the - * system supports it. - */ - if(sizeof(dev_t) <= 2) { - set_733((char*)Rock + ipnt, (lstatbuf->st_rdev >> 8)); - ipnt += 8; - set_733((char*)Rock + ipnt, lstatbuf->st_rdev & 0xff); - ipnt += 8; - } - else if(sizeof(dev_t) <= 4) { - set_733((char*)Rock + ipnt, (lstatbuf->st_rdev >> 8) >> 8); - ipnt += 8; - set_733((char*)Rock + ipnt, lstatbuf->st_rdev & 0xffff); - ipnt += 8; - } - else { - set_733((char*)Rock + ipnt, (lstatbuf->st_rdev >> 16) >> 16); - ipnt += 8; - set_733((char*)Rock + ipnt, lstatbuf->st_rdev); - ipnt += 8; - } -#endif - }; -#endif - /* - * Check for and symbolic links. VMS does not have these. - */ - if (S_ISLNK(lstatbuf->st_mode)){ - int lenpos, lenval, j0, j1; - int nchar; - unsigned char * cpnt, *cpnt1; - nchar = readlink(whole_name, (char *)symlink_buff, sizeof(symlink_buff)); - symlink_buff[nchar < 0 ? 0 : nchar] = 0; - nchar = strlen((char *) symlink_buff); - set_733(s_entry->isorec.size, 0); - cpnt = &symlink_buff[0]; - flagval |= (1<<2); - - if (! split_SL_field) - { - int sl_bytes = 0; - for (cpnt1 = cpnt; *cpnt1 != '\0'; cpnt1++) - { - if (*cpnt1 == '/') - { - sl_bytes += 4; - } - else - { - sl_bytes += 1; - } - } - if (sl_bytes > 250) - { - /* - * the symbolic link won't fit into one SL System Use Field - * print an error message and continue with splited one - */ - fprintf (stderr, _("symbolic link `%s' too long for one SL System Use Field, splitting"), cpnt); - } - if(MAYBE_ADD_CE_ENTRY(SL_SIZE + sl_bytes)) add_CE_entry(); - } - - while(nchar){ - if(MAYBE_ADD_CE_ENTRY(SL_SIZE)) add_CE_entry(); - Rock[ipnt++] ='S'; - Rock[ipnt++] ='L'; - lenpos = ipnt; - Rock[ipnt++] = SL_SIZE; - Rock[ipnt++] = SU_VERSION; - Rock[ipnt++] = 0; /* Flags */ - lenval = 5; - while(*cpnt){ - cpnt1 = (unsigned char *) strchr((char *) cpnt, '/'); - if(cpnt1) { - nchar--; - *cpnt1 = 0; - }; - - /* We treat certain components in a special way. */ - if(cpnt[0] == '.' && cpnt[1] == '.' && cpnt[2] == 0){ - if(MAYBE_ADD_CE_ENTRY(2)) add_CE_entry(); - Rock[ipnt++] = SL_PARENT; - Rock[ipnt++] = 0; /* length is zero */ - lenval += 2; - nchar -= 2; - } else if(cpnt[0] == '.' && cpnt[1] == 0){ - if(MAYBE_ADD_CE_ENTRY(2)) add_CE_entry(); - Rock[ipnt++] = SL_CURRENT; - Rock[ipnt++] = 0; /* length is zero */ - lenval += 2; - nchar -= 1; - } else if(cpnt[0] == 0){ - if(MAYBE_ADD_CE_ENTRY(2)) add_CE_entry(); - Rock[ipnt++] = SL_ROOT; - Rock[ipnt++] = 0; /* length is zero */ - lenval += 2; - } else { - /* If we do not have enough room for a component, start - a new continuations segment now */ - if(split_SL_component ? MAYBE_ADD_CE_ENTRY(6) : - MAYBE_ADD_CE_ENTRY(6 + strlen ((char *) cpnt))) - { - add_CE_entry(); - if(cpnt1) - { - *cpnt1 = '/'; - nchar++; - cpnt1 = NULL; /* A kluge so that we can restart properly */ - } - break; - } - j0 = strlen((char *) cpnt); - while(j0) { - j1 = j0; - if(j1 > 0xf8) j1 = 0xf8; - need_ce = 0; - if(j1 + currlen + CE_SIZE + (ipnt - recstart) > reclimit) { - j1 = reclimit - currlen - CE_SIZE - (ipnt - recstart); - need_ce++; - } - Rock[ipnt++] = (j1 != j0 ? SL_CONTINUE : 0); - Rock[ipnt++] = j1; - strncpy((char *) Rock + ipnt, (char *) cpnt, j1); - ipnt += j1; - lenval += j1 + 2; - cpnt += j1; - nchar -= j1; /* Number we processed this time */ - j0 -= j1; - if(need_ce) { - add_CE_entry(); - if(cpnt1) { - *cpnt1 = '/'; - nchar++; - cpnt1 = NULL; /* A kluge so that we can restart properly */ - } - break; - } - } - }; - if(cpnt1) { - cpnt = cpnt1 + 1; - } else - break; - } - Rock[lenpos] = lenval; - if(nchar) Rock[lenpos + 2] = SL_CONTINUE; /* We need another SL entry */ - } /* while nchar */ - } /* Is a symbolic link */ - /* - * Add in the Rock Ridge TF time field - */ - if(MAYBE_ADD_CE_ENTRY(TF_SIZE)) add_CE_entry(); - Rock[ipnt++] ='T'; - Rock[ipnt++] ='F'; - Rock[ipnt++] = TF_SIZE; - Rock[ipnt++] = SU_VERSION; -#ifdef __QNX__ - Rock[ipnt++] = 0x0f; -#else - Rock[ipnt++] = 0x0e; -#endif - flagval |= (1<<7); -#ifdef __QNX__ - iso9660_date((char *) &Rock[ipnt], lstatbuf->st_ftime); - ipnt += 7; -#endif - iso9660_date((char *) &Rock[ipnt], lstatbuf->st_mtime); - ipnt += 7; - iso9660_date((char *) &Rock[ipnt], lstatbuf->st_atime); - ipnt += 7; - iso9660_date((char *) &Rock[ipnt], lstatbuf->st_ctime); - ipnt += 7; - - /* - * Add in the Rock Ridge RE time field - */ - if(deep_opt & NEED_RE){ - if(MAYBE_ADD_CE_ENTRY(RE_SIZE)) add_CE_entry(); - Rock[ipnt++] ='R'; - Rock[ipnt++] ='E'; - Rock[ipnt++] = RE_SIZE; - Rock[ipnt++] = SU_VERSION; - flagval |= (1<<6); - }; - /* - * Add in the Rock Ridge PL record, if required. - */ - if(deep_opt & NEED_PL){ - if(MAYBE_ADD_CE_ENTRY(PL_SIZE)) add_CE_entry(); - Rock[ipnt++] ='P'; - Rock[ipnt++] ='L'; - Rock[ipnt++] = PL_SIZE; - Rock[ipnt++] = SU_VERSION; - set_733((char*)Rock + ipnt, 0); - ipnt += 8; - flagval |= (1<<5); - }; - - /* - * Add in the Rock Ridge CL field, if required. - */ - if(deep_opt & NEED_CL){ - if(MAYBE_ADD_CE_ENTRY(CL_SIZE)) add_CE_entry(); - Rock[ipnt++] ='C'; - Rock[ipnt++] ='L'; - Rock[ipnt++] = CL_SIZE; - Rock[ipnt++] = SU_VERSION; - set_733((char*)Rock + ipnt, 0); - ipnt += 8; - flagval |= (1<<4); - }; - -#ifndef VMS - /* If transparent compression was requested, fill in the correct - field for this file */ - if(transparent_compression && - S_ISREG(lstatbuf->st_mode) && - strlen(name) > 3 && - strcmp(name + strlen(name) - 3,".gZ") == 0){ - FILE * zipfile; - char * checkname; - unsigned int file_size; - unsigned char header[8]; - int OK_flag; - - /* First open file and verify that the correct algorithm was used */ - file_size = 0; - OK_flag = 1; - - zipfile = fopen(whole_name, "rb"); - if (fread (header, 1, sizeof (header), zipfile) != sizeof(header)) - error (1, errno, "fread"); - - /* Check some magic numbers from gzip. */ - if(header[0] != 0x1f || header[1] != 0x8b || header[2] != 8) OK_flag = 0; - /* Make sure file was blocksized. */ - if(((header[3] & 0x40) == 0)) OK_flag = 0; - /* OK, now go to the end of the file and get some more info */ - if(OK_flag){ - int status; - status = (long)lseek(fileno(zipfile), (off_t)(-8), SEEK_END); - if(status == -1) OK_flag = 0; - } - if(OK_flag){ - if(read(fileno(zipfile), (char*)header, sizeof(header)) != sizeof(header)) - OK_flag = 0; - else { - int blocksize; - blocksize = (header[3] << 8) | header[2]; - file_size = ((unsigned int)header[7] << 24) | - ((unsigned int)header[6] << 16) | - ((unsigned int)header[5] << 8) | header[4]; -#if 0 - fprintf(stderr,"Blocksize = %d %d\n", blocksize, file_size); -#endif - if(blocksize != SECTOR_SIZE) OK_flag = 0; - } - } - fclose(zipfile); - - checkname = strdup(whole_name); - checkname[strlen(whole_name)-3] = 0; - zipfile = fopen(checkname, "rb"); - if(zipfile) { - OK_flag = 0; - fprintf (stderr, _("Unable to insert transparent compressed file - name conflict\n")); - fclose(zipfile); - } - - free(checkname); - - if(OK_flag){ - if(MAYBE_ADD_CE_ENTRY(ZZ_SIZE)) add_CE_entry(); - Rock[ipnt++] ='Z'; - Rock[ipnt++] ='Z'; - Rock[ipnt++] = ZZ_SIZE; - Rock[ipnt++] = SU_VERSION; - Rock[ipnt++] = 'g'; /* Identify compression technique used */ - Rock[ipnt++] = 'z'; - Rock[ipnt++] = 3; - set_733((char*)Rock + ipnt, file_size); /* Real file size */ - ipnt += 8; - }; - } -#endif - /* - * Add in the Rock Ridge CE field, if required. We use this for the - * extension record that is stored in the root directory. - */ - if(deep_opt & NEED_CE) add_CE_entry(); - /* - * Done filling in all of the fields. Now copy it back to a buffer for the - * file in question. - */ - - /* Now copy this back to the buffer for the file */ - Rock[flagpos] = flagval; - - /* If there was a CE, fill in the size field */ - if(recstart) - set_733((char*)Rock + recstart - 8, ipnt - recstart); - - s_entry->rr_attributes = (unsigned char *) e_malloc(ipnt); - s_entry->total_rr_attr_size = ipnt; - s_entry->rr_attr_size = (mainrec ? mainrec : ipnt); - memcpy(s_entry->rr_attributes, Rock, ipnt); - return ipnt; -} - -/* Guaranteed to return a single sector with the relevant info */ - -char * FDECL4(generate_rr_extension_record, char *, id, char *, descriptor, - char *, source, int *, size){ - int lipnt = 0; - char * pnt; - int len_id, len_des, len_src; - - len_id = strlen(id); - len_des = strlen(descriptor); - len_src = strlen(source); - Rock[lipnt++] ='E'; - Rock[lipnt++] ='R'; - Rock[lipnt++] = ER_SIZE + len_id + len_des + len_src; - Rock[lipnt++] = 1; - Rock[lipnt++] = len_id; - Rock[lipnt++] = len_des; - Rock[lipnt++] = len_src; - Rock[lipnt++] = 1; - - memcpy(Rock + lipnt, id, len_id); - lipnt += len_id; - - memcpy(Rock + lipnt, descriptor, len_des); - lipnt += len_des; - - memcpy(Rock + lipnt, source, len_src); - lipnt += len_src; - - if(lipnt > SECTOR_SIZE) - error (1, 0, _("Extension record too long\n")); - pnt = (char *) e_malloc(SECTOR_SIZE); - memset(pnt, 0, SECTOR_SIZE); - memcpy(pnt, Rock, lipnt); - *size = lipnt; - return pnt; -} diff --git a/util/mkisofs/tree.c b/util/mkisofs/tree.c deleted file mode 100644 index 0d9cf6143..000000000 --- a/util/mkisofs/tree.c +++ /dev/null @@ -1,1865 +0,0 @@ -/* - * File tree.c - scan directory tree and build memory structures for iso9660 - * filesystem - - Written by Eric Youngdale (1993). - - Copyright 1993 Yggdrasil Computing, Incorporated - - Copyright (C) 2009 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, see . - */ - -/* ADD_FILES changes made by Ross Biro biro@yggdrasil.com 2/23/95 */ - -#include -#include -#include -#include - -#include "config.h" - -#ifndef VMS -#if defined(MAJOR_IN_SYSMACROS) -#include -#endif - -#ifdef HAVE_UNISTD_H -#include -#endif -#include - -#if defined(MAJOR_IN_MKDEV) -#include -#include -#endif -#else -#include -#include -#include "vms.h" -extern char * strdup(const char *); -#endif - -/* - * Autoconf should be able to figure this one out for us and let us know - * whether the system has memmove or not. - */ -# ifndef HAVE_MEMMOVE -# define memmove(d, s, n) bcopy ((s), (d), (n)) -# endif - -#include "mkisofs.h" -#include "iso9660.h" -#include "match.h" - -#include - -#include "exclude.h" - -#ifdef DOESNT_WORK - -#ifdef NON_UNIXFS -#define S_ISLNK(m) (0) -#define S_ISSOCK(m) (0) -#define S_ISFIFO(m) (0) -#else -#ifndef S_ISLNK -#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) -#endif -#ifndef S_ISSOCK -# ifdef S_IFSOCK -# define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK) -# else -# define S_ISSOCK(m) (0) -# endif -#endif -#endif - -#else -#include -#endif - - -#ifdef __SVR4 -extern char * strdup(const char *); -#endif - -static unsigned char symlink_buff[256]; - -static void stat_fix __PR((struct stat * st)); -static void generate_reloc_directory __PR((void)); - -static void DECL(attach_dot_entries, (struct directory * dirnode, - struct stat * parent_stat)); -static void DECL(delete_directory, (struct directory * parent, struct directory * child)); - -extern int verbose; - -struct stat fstatbuf; /* We use this for the artificial entries we create */ - -struct stat root_statbuf; /* Stat buffer for root directory */ - -struct directory * reloc_dir = NULL; - -static void -FDECL1(stat_fix, struct stat *, st) -{ - /* Remove the uid and gid, they will only be useful on the author's - system. */ - st->st_uid = 0; - st->st_gid = 0; - - /* - * Make sure the file modes make sense. Turn on all read bits. Turn - * on all exec/search bits if any exec/search bit is set. Turn off - * all write bits, and all special mode bits (on a r/o fs lock bits - * are useless, and with uid+gid 0 don't want set-id bits, either). - */ - st->st_mode |= 0444; -#ifndef _WIN32 /* make all file "executable" */ - if (st->st_mode & 0111) -#endif /* _WIN32 */ - st->st_mode |= 0111; - st->st_mode &= ~07222; -} - -int -FDECL2(stat_filter, char *, path, struct stat *, st) -{ - int result = stat(path, st); - if (result >= 0 && rationalize) - stat_fix(st); - - if ((unsigned) st->st_size > UINT32_MAX) - result = -1; - - return result; -} - -int -FDECL2(lstat_filter, char *, path, struct stat *, st) -{ - int result = lstat(path, st); - if (result >= 0 && rationalize) - stat_fix(st); - - if ((unsigned) st->st_size > UINT32_MAX) - result = -1; - - return result; -} - -static int FDECL1(sort_n_finish, struct directory *, this_dir) -{ - struct directory_entry * s_entry; - struct directory_entry * s_entry1; - struct directory_entry * table; - int count; - int d1; - int d2; - int d3; - int new_reclen; - char * c; - int status = 0; - int tablesize = 0; - char newname[34]; - char rootname[34]; - - /* Here we can take the opportunity to toss duplicate entries from the - directory. */ - - /* ignore if it's hidden */ - if(this_dir->dir_flags & INHIBIT_ISO9660_ENTRY) - { - return 0; - } - - table = NULL; - - init_fstatbuf(); - - /* - * If we had artificially created this directory, then we might be - * missing the required '.' entries. Create these now if we need - * them. - */ - if( (this_dir->dir_flags & (DIR_HAS_DOT | DIR_HAS_DOTDOT)) != - (DIR_HAS_DOT | DIR_HAS_DOTDOT) ) - { - attach_dot_entries(this_dir, &fstatbuf); - } - - flush_file_hash(); - s_entry = this_dir->contents; - while(s_entry) - { - /* ignore if it's hidden */ - if (s_entry->de_flags & INHIBIT_ISO9660_ENTRY) - { - s_entry = s_entry->next; - continue; - } - - /* - * First assume no conflict, and handle this case - */ - if(!(s_entry1 = find_file_hash(s_entry->isorec.name))) - { - add_file_hash(s_entry); - s_entry = s_entry->next; - continue; - } - - if(s_entry1 == s_entry) - error (1, 0, _("Fatal goof\n")); - - /* - * OK, handle the conflicts. Try substitute names until we come - * up with a winner - */ - strcpy(rootname, s_entry->isorec.name); - if(full_iso9660_filenames) - { - if(strlen(rootname) > 27) rootname[27] = 0; - } - - /* - * Strip off the non-significant part of the name so that we are left - * with a sensible root filename. If we don't find a '.', then try - * a ';'. - */ - c = strchr(rootname, '.'); - if (c) - *c = 0; - else - { - c = strchr(rootname, ';'); - if (c) *c = 0; - } - for(d1 = 0; d1 < 36; d1++) - { - for(d2 = 0; d2 < 36; d2++) - { - for(d3 = 0; d3 < 36; d3++) - { - sprintf(newname,"%s.%c%c%c%s", rootname, - (d1 <= 9 ? '0' + d1 : 'A' + d1 - 10), - (d2 <= 9 ? '0' + d2 : 'A' + d2 - 10), - (d3 <= 9 ? '0' + d3 : 'A' + d3 - 10), - (s_entry->isorec.flags[0] == 2 || - omit_version_number ? "" : ";1")); - -#ifdef VMS - /* Sigh. VAXCRTL seems to be broken here */ - { - int ijk = 0; - while(newname[ijk]) - { - if(newname[ijk] == ' ') newname[ijk] = '0'; - ijk++; - } - } -#endif - - if(!find_file_hash(newname)) goto got_valid_name; - } - } - } - - /* - * If we fell off the bottom here, we were in real trouble. - */ - error (1, 0, _("Unable to generate unique name for file %s\n"), s_entry->name); - -got_valid_name: - /* - * OK, now we have a good replacement name. Now decide which one - * of these two beasts should get the name changed - */ - if(s_entry->priority < s_entry1->priority) - { - if( verbose > 0 ) - { - fprintf (stderr, _("Using %s for %s%s%s (%s)\n"), newname, - this_dir->whole_name, SPATH_SEPARATOR, - s_entry->name, s_entry1->name); - } - s_entry->isorec.name_len[0] = strlen(newname); - new_reclen = sizeof(struct iso_directory_record) - - sizeof(s_entry->isorec.name) + - strlen(newname); - if(use_RockRidge) - { - if (new_reclen & 1) new_reclen++; /* Pad to an even byte */ - new_reclen += s_entry->rr_attr_size; - } - if (new_reclen & 1) new_reclen++; /* Pad to an even byte */ - s_entry->isorec.length[0] = new_reclen; - strcpy(s_entry->isorec.name, newname); - } - else - { - delete_file_hash(s_entry1); - if( verbose > 0 ) - { - fprintf(stderr, _("Using %s for %s%s%s (%s)\n"), newname, - this_dir->whole_name, SPATH_SEPARATOR, - s_entry1->name, s_entry->name); - } - s_entry1->isorec.name_len[0] = strlen(newname); - new_reclen = sizeof(struct iso_directory_record) - - sizeof(s_entry1->isorec.name) + - strlen(newname); - if(use_RockRidge) - { - if (new_reclen & 1) new_reclen++; /* Pad to an even byte */ - new_reclen += s_entry1->rr_attr_size; - } - if (new_reclen & 1) new_reclen++; /* Pad to an even byte */ - s_entry1->isorec.length[0] = new_reclen; - strcpy(s_entry1->isorec.name, newname); - add_file_hash(s_entry1); - } - add_file_hash(s_entry); - s_entry = s_entry->next; - } - - if(generate_tables - && !find_file_hash("TRANS.TBL") - && (reloc_dir != this_dir) - && (this_dir->extent == 0) ) - { - /* - * First we need to figure out how big this table is - */ - for (s_entry = this_dir->contents; s_entry; s_entry = s_entry->next) - { - if(strcmp(s_entry->name, ".") == 0 || - strcmp(s_entry->name, "..") == 0) continue; - if(s_entry->de_flags & INHIBIT_ISO9660_ENTRY) continue; - if(s_entry->table) tablesize += 35 + strlen(s_entry->table); - } - } - - if( tablesize > 0 ) - { - table = (struct directory_entry *) - e_malloc(sizeof (struct directory_entry)); - memset(table, 0, sizeof(struct directory_entry)); - table->table = NULL; - table->next = this_dir->contents; - this_dir->contents = table; - - table->filedir = root; - table->isorec.flags[0] = 0; - table->priority = 32768; - iso9660_date(table->isorec.date, fstatbuf.st_mtime); - table->inode = TABLE_INODE; - table->dev = (dev_t) UNCACHED_DEVICE; - set_723(table->isorec.volume_sequence_number, volume_sequence_number); - set_733((char *) table->isorec.size, tablesize); - table->size = tablesize; - table->filedir = this_dir; -#ifdef ERIC_neverdef - table->de_flags |= INHIBIT_JOLIET_ENTRY; -#endif - table->name = strdup(""); - table->table = (char *) e_malloc(ROUND_UP(tablesize)); - memset(table->table, 0, ROUND_UP(tablesize)); - iso9660_file_length ("TRANS.TBL", table, 0); - - if(use_RockRidge) - { - fstatbuf.st_mode = 0444 | S_IFREG; - fstatbuf.st_nlink = 1; - generate_rock_ridge_attributes("", - "TRANS.TBL", table, - &fstatbuf, &fstatbuf, 0); - } - } - - /* - * We have now chosen the 8.3 names and we should now know the length - * of every entry in the directory. - */ - for(s_entry = this_dir->contents; s_entry; s_entry = s_entry->next) - { - /* skip if it's hidden */ - if (s_entry->de_flags & INHIBIT_ISO9660_ENTRY) - { - continue; - } - - new_reclen = strlen(s_entry->isorec.name); - - /* - * First update the path table sizes for directories. - */ - if(s_entry->isorec.flags[0] == 2) - { - if (strcmp(s_entry->name,".") && strcmp(s_entry->name,"..")) - { - path_table_size += new_reclen + sizeof(struct iso_path_table) - 1; - if (new_reclen & 1) path_table_size++; - } - else - { - new_reclen = 1; - if (this_dir == root && strlen(s_entry->name) == 1) - { - path_table_size += sizeof(struct iso_path_table); - } - } - } - if(path_table_size & 1) path_table_size++; /* For odd lengths we pad */ - s_entry->isorec.name_len[0] = new_reclen; - - new_reclen += - sizeof(struct iso_directory_record) - - sizeof(s_entry->isorec.name); - - if (new_reclen & 1) - new_reclen++; - - new_reclen += s_entry->rr_attr_size; - - if (new_reclen & 1) new_reclen++; - - if(new_reclen > 0xff) - error (1, 0, _("Fatal error - RR overflow for file %s\n"), - s_entry->name); - s_entry->isorec.length[0] = new_reclen; - } - - status = sort_directory(&this_dir->contents); - if( status > 0 ) - { - fprintf (stderr, _("Unable to sort directory %s\n"), - this_dir->whole_name); - } - - /* - * If we are filling out a TRANS.TBL, generate the entries that will - * go in the thing. - */ - if(table) - { - count = 0; - for (s_entry = this_dir->contents; s_entry; s_entry = s_entry->next){ - if(s_entry == table) continue; - if(!s_entry->table) continue; - if(strcmp(s_entry->name, ".") == 0 || - strcmp(s_entry->name, "..") == 0) continue; - if(s_entry->de_flags & INHIBIT_ISO9660_ENTRY) continue; - /* - * Warning: we cannot use the return value of sprintf because - * old BSD based sprintf() implementations will return - * a pointer to the result instead of a count. - */ - sprintf(table->table + count, "%c %-34s%s", - s_entry->table[0], - s_entry->isorec.name, s_entry->table+1); - count += strlen(table->table + count); - free(s_entry->table); - s_entry->table = NULL; - } - - if(count != tablesize) - error (1, 0, _("Translation table size mismatch %d %d\n"), - count, tablesize); - } - - /* - * Now go through the directory and figure out how large this one will be. - * Do not split a directory entry across a sector boundary - */ - s_entry = this_dir->contents; - this_dir->ce_bytes = 0; - while(s_entry) - { - /* skip if it's hidden */ - if (s_entry->de_flags & INHIBIT_ISO9660_ENTRY) { - s_entry = s_entry->next; - continue; - } - - new_reclen = s_entry->isorec.length[0]; - if ((this_dir->size & (SECTOR_SIZE - 1)) + new_reclen >= SECTOR_SIZE) - this_dir->size = (this_dir->size + (SECTOR_SIZE - 1)) & - ~(SECTOR_SIZE - 1); - this_dir->size += new_reclen; - - /* See if continuation entries were used on disc */ - if(use_RockRidge && - s_entry->rr_attr_size != s_entry->total_rr_attr_size) - { - unsigned char * pnt; - int len; - int nbytes; - - pnt = s_entry->rr_attributes; - len = s_entry->total_rr_attr_size; - - /* - * We make sure that each continuation entry record is not - * split across sectors, but each file could in theory have more - * than one CE, so we scan through and figure out what we need. - */ - while(len > 3) - { - if(pnt[0] == 'C' && pnt[1] == 'E') - { - nbytes = get_733((char *) pnt+20); - - if((this_dir->ce_bytes & (SECTOR_SIZE - 1)) + nbytes >= - SECTOR_SIZE) this_dir->ce_bytes = - ROUND_UP(this_dir->ce_bytes); - /* Now store the block in the ce buffer */ - this_dir->ce_bytes += nbytes; - if(this_dir->ce_bytes & 1) this_dir->ce_bytes++; - } - len -= pnt[2]; - pnt += pnt[2]; - } - } - s_entry = s_entry->next; - } - return status; -} - -static void generate_reloc_directory() -{ - time_t current_time; - struct directory_entry *s_entry; - - /* Create an entry for our internal tree */ - time (¤t_time); - reloc_dir = (struct directory *) - e_malloc(sizeof(struct directory)); - memset(reloc_dir, 0, sizeof(struct directory)); - reloc_dir->parent = root; - reloc_dir->next = root->subdir; - root->subdir = reloc_dir; - reloc_dir->depth = 1; - reloc_dir->whole_name = strdup("./rr_moved"); - reloc_dir->de_name = strdup("rr_moved"); - reloc_dir->extent = 0; - - - /* Now create an actual directory entry */ - s_entry = (struct directory_entry *) - e_malloc(sizeof (struct directory_entry)); - memset(s_entry, 0, sizeof(struct directory_entry)); - s_entry->next = root->contents; - reloc_dir->self = s_entry; - - /* - * The rr_moved entry will not appear in the Joliet tree. - */ - reloc_dir->dir_flags |= INHIBIT_JOLIET_ENTRY; - s_entry->de_flags |= INHIBIT_JOLIET_ENTRY; - - root->contents = s_entry; - root->contents->name = strdup(reloc_dir->de_name); - root->contents->filedir = root; - root->contents->isorec.flags[0] = 2; - root->contents->priority = 32768; - iso9660_date(root->contents->isorec.date, current_time); - root->contents->inode = UNCACHED_INODE; - root->contents->dev = (dev_t) UNCACHED_DEVICE; - set_723(root->contents->isorec.volume_sequence_number, volume_sequence_number); - iso9660_file_length (reloc_dir->de_name, root->contents, 1); - - if(use_RockRidge){ - fstatbuf.st_mode = 0555 | S_IFDIR; - fstatbuf.st_nlink = 2; - generate_rock_ridge_attributes("", - "rr_moved", s_entry, - &fstatbuf, &fstatbuf, 0); - }; - - /* Now create the . and .. entries in rr_moved */ - /* Now create an actual directory entry */ - attach_dot_entries(reloc_dir, &root_statbuf); -} - -/* - * Function: attach_dot_entries - * - * Purpose: Create . and .. entries for a new directory. - * - * Notes: Only used for artificial directories that - * we are creating. - */ -static void FDECL2(attach_dot_entries, struct directory *, dirnode, - struct stat *, parent_stat) -{ - struct directory_entry *s_entry; - struct directory_entry *orig_contents; - int deep_flag = 0; - - init_fstatbuf(); - - orig_contents = dirnode->contents; - - if( (dirnode->dir_flags & DIR_HAS_DOTDOT) == 0 ) - { - s_entry = (struct directory_entry *) - e_malloc(sizeof (struct directory_entry)); - memcpy(s_entry, dirnode->self, - sizeof(struct directory_entry)); - s_entry->name = strdup(".."); - s_entry->whole_name = NULL; - s_entry->isorec.name_len[0] = 1; - s_entry->isorec.flags[0] = 2; /* Mark as a directory */ - iso9660_file_length ("..", s_entry, 1); - iso9660_date(s_entry->isorec.date, fstatbuf.st_mtime); - s_entry->filedir = dirnode->parent; - - dirnode->contents = s_entry; - dirnode->contents->next = orig_contents; - orig_contents = s_entry; - - if(use_RockRidge) - { - if( parent_stat == NULL ) - { - parent_stat = &fstatbuf; - } - generate_rock_ridge_attributes("", - "..", s_entry, - parent_stat, - parent_stat, 0); - } - dirnode->dir_flags |= DIR_HAS_DOTDOT; - } - - if( (dirnode->dir_flags & DIR_HAS_DOT) == 0 ) - { - s_entry = (struct directory_entry *) - e_malloc(sizeof (struct directory_entry)); - memcpy(s_entry, dirnode->self, - sizeof(struct directory_entry)); - s_entry->name = strdup("."); - s_entry->whole_name = NULL; - s_entry->isorec.name_len[0] = 1; - s_entry->isorec.flags[0] = 2; /* Mark as a directory */ - iso9660_file_length (".", s_entry, 1); - iso9660_date(s_entry->isorec.date, fstatbuf.st_mtime); - s_entry->filedir = dirnode; - - dirnode->contents = s_entry; - dirnode->contents->next = orig_contents; - - if(use_RockRidge) - { - fstatbuf.st_mode = 0555 | S_IFDIR; - fstatbuf.st_nlink = 2; - - if( dirnode == root ) - { - deep_flag |= NEED_CE | NEED_SP; /* For extension record */ - } - - generate_rock_ridge_attributes("", - ".", s_entry, - &fstatbuf, &fstatbuf, deep_flag); - } - - dirnode->dir_flags |= DIR_HAS_DOT; - } - -} - -static void FDECL2(update_nlink, struct directory_entry *, s_entry, int, value) -{ - unsigned char * pnt; - int len; - - pnt = s_entry->rr_attributes; - len = s_entry->total_rr_attr_size; - while(len) - { - if(pnt[0] == 'P' && pnt[1] == 'X') - { - set_733((char *) pnt+12, value); - break; - } - len -= pnt[2]; - pnt += pnt[2]; - } -} - -static void FDECL1(increment_nlink, struct directory_entry *, s_entry) -{ - unsigned char * pnt; - int len, nlink; - - pnt = s_entry->rr_attributes; - len = s_entry->total_rr_attr_size; - while(len) - { - if(pnt[0] == 'P' && pnt[1] == 'X') - { - nlink = get_733((char *) pnt+12); - set_733((char *) pnt+12, nlink+1); - break; - } - len -= pnt[2]; - pnt += pnt[2]; - } -} - -void finish_cl_pl_entries(){ - struct directory_entry *s_entry, *s_entry1; - struct directory * d_entry; - - /* if the reloc_dir is hidden (empty), then return */ - if (reloc_dir->dir_flags & INHIBIT_ISO9660_ENTRY) - return; - - s_entry = reloc_dir->contents; - s_entry = s_entry->next->next; /* Skip past . and .. */ - for(; s_entry; s_entry = s_entry->next){ - /* skip if it's hidden */ - if(s_entry->de_flags & INHIBIT_ISO9660_ENTRY) { - continue; - } - d_entry = reloc_dir->subdir; - while(d_entry){ - if(d_entry->self == s_entry) break; - d_entry = d_entry->next; - }; - if(!d_entry) - error (1, 0, _("Unable to locate directory parent\n")); - - /* First fix the PL pointer in the directory in the rr_reloc dir */ - s_entry1 = d_entry->contents->next; - set_733((char *) s_entry1->rr_attributes + s_entry1->total_rr_attr_size - 8, - s_entry->filedir->extent); - - /* Now fix the CL pointer */ - s_entry1 = s_entry->parent_rec; - - set_733((char *) s_entry1->rr_attributes + s_entry1->total_rr_attr_size - 8, - d_entry->extent); - - s_entry->filedir = reloc_dir; /* Now we can fix this */ - } - /* Next we need to modify the NLINK terms in the assorted root directory records - to account for the presence of the RR_MOVED directory */ - - increment_nlink(root->self); - increment_nlink(root->self->next); - d_entry = root->subdir; - while(d_entry){ - increment_nlink(d_entry->contents->next); - d_entry = d_entry->next; - }; -} - -/* - * Function: scan_directory_tree - * - * Purpose: Walk through a directory on the local machine - * filter those things we don't want to include - * and build our representation of a dir. - * - * Notes: - */ -int -FDECL3(scan_directory_tree,struct directory *, this_dir, - char *, path, - struct directory_entry *, de) -{ - DIR * current_dir; - char whole_path[1024]; - struct dirent * d_entry; - struct directory * parent; - int dflag; - char * old_path; - - if (verbose > 1) - { - fprintf (stderr, _("Scanning %s\n"), path); - } - - current_dir = opendir(path); - d_entry = NULL; - - /* Apparently NFS sometimes allows you to open the directory, but - then refuses to allow you to read the contents. Allow for this */ - - old_path = path; - - if(current_dir) d_entry = readdir(current_dir); - - if(!current_dir || !d_entry) - { - fprintf (stderr, _("Unable to open directory %s\n"), path); - de->isorec.flags[0] &= ~2; /* Mark as not a directory */ - if(current_dir) closedir(current_dir); - return 0; - } - - parent = de->filedir; - /* Set up the struct for the current directory, and insert it into the - tree */ - -#ifdef VMS - vms_path_fixup(path); -#endif - - /* - * if entry for this sub-directory is hidden, then hide this directory - */ - if (de->de_flags & INHIBIT_ISO9660_ENTRY) - this_dir->dir_flags |= INHIBIT_ISO9660_ENTRY; - - if (de->de_flags & INHIBIT_JOLIET_ENTRY) - this_dir->dir_flags |= INHIBIT_JOLIET_ENTRY; - - /* - * Now we scan the directory itself, and look at what is inside of it. - */ - dflag = 0; - while(1==1){ - - /* The first time through, skip this, since we already asked for - the first entry when we opened the directory. */ - if(dflag) d_entry = readdir(current_dir); - dflag++; - - if(!d_entry) break; - - /* OK, got a valid entry */ - - /* If we do not want all files, then pitch the backups. */ - if(!all_files){ - if( strchr(d_entry->d_name,'~') - || strchr(d_entry->d_name,'#')) - { - if( verbose > 0 ) - { - fprintf (stderr, _("Ignoring file %s\n"), d_entry->d_name); - } - continue; - } - } - - if(strlen(path)+strlen(d_entry->d_name) + 2 > sizeof(whole_path)) - error (1, 0, _("Overflow of stat buffer\n")); - - /* Generate the complete ASCII path for this file */ - strcpy(whole_path, path); -#ifndef VMS - if(whole_path[strlen(whole_path)-1] != '/') - strcat(whole_path, "/"); -#endif - strcat(whole_path, d_entry->d_name); - - /** Should we exclude this file ? */ - if (matches(d_entry->d_name) || matches(whole_path)) { - if (verbose > 1) { - fprintf (stderr, _("Excluded by match: %s\n"), whole_path); - } - continue; - } - - if( generate_tables - && strcmp(d_entry->d_name, "TRANS.TBL") == 0 ) - { - /* - * Ignore this entry. We are going to be generating new - * versions of these files, and we need to ignore any - * originals that we might have found. - */ - if (verbose > 1) - { - fprintf (stderr, _("Excluded: %s\n"), whole_path); - } - continue; - } - - /* - * If we already have a '.' or a '..' entry, then don't - * insert new ones. - */ - if( strcmp(d_entry->d_name, ".") == 0 - && this_dir->dir_flags & DIR_HAS_DOT ) - { - continue; - } - - if( strcmp(d_entry->d_name, "..") == 0 - && this_dir->dir_flags & DIR_HAS_DOTDOT ) - { - continue; - } - -#if 0 - if (verbose > 1) fprintf(stderr, "%s\n",whole_path); -#endif - /* - * This actually adds the entry to the directory in question. - */ - insert_file_entry(this_dir, whole_path, d_entry->d_name); - } - closedir(current_dir); - - return 1; -} - - -/* - * Function: insert_file_entry - * - * Purpose: Insert one entry into our directory node. - * - * Note: - * This function inserts a single entry into the directory. It - * is assumed that all filtering and decision making regarding what - * we want to include has already been made, so the purpose of this - * is to insert one entry (file, link, dir, etc), into this directory. - * Note that if the entry is a dir (or if we are following links, - * and the thing it points to is a dir), then we will scan those - * trees before we return. - */ -int -FDECL3(insert_file_entry,struct directory *, this_dir, - char *, whole_path, - char *, short_name) -{ - struct stat statbuf, lstatbuf; - struct directory_entry * s_entry, *s_entry1; - int lstatus; - int status; - int deep_flag; - - status = stat_filter(whole_path, &statbuf); - - lstatus = lstat_filter(whole_path, &lstatbuf); - - if( (status == -1) && (lstatus == -1) ) - { - /* - * This means that the file doesn't exist, or isn't accessible. - * Sometimes this is because of NFS permissions problems. - */ - fprintf (stderr, _("Non-existant or inaccessible: %s\n"),whole_path); - return 0; - } - - if(this_dir == root && strcmp(short_name, ".") == 0) - root_statbuf = statbuf; /* Save this for later on */ - - /* We do this to make sure that the root entries are consistent */ - if(this_dir == root && strcmp(short_name, "..") == 0) - { - statbuf = root_statbuf; - lstatbuf = root_statbuf; - } - - if(S_ISLNK(lstatbuf.st_mode)) - { - - /* Here we decide how to handle the symbolic links. Here - we handle the general case - if we are not following - links or there is an error, then we must change - something. If RR is in use, it is easy, we let RR - describe the file. If not, then we punt the file. */ - - if((status || !follow_links)) - { - if(use_RockRidge) - { - status = 0; - statbuf.st_size = 0; - STAT_INODE(statbuf) = UNCACHED_INODE; - statbuf.st_dev = (dev_t) UNCACHED_DEVICE; - statbuf.st_mode = (statbuf.st_mode & ~S_IFMT) | S_IFREG; - } else { - if(follow_links) - { - fprintf (stderr, - _("Unable to stat file %s - ignoring and continuing.\n"), - whole_path); - } - else - { - fprintf (stderr, - _("Symlink %s ignored - continuing.\n"), - whole_path); - return 0; /* Non Rock Ridge discs - ignore all symlinks */ - } - } - } - - /* Here we handle a different kind of case. Here we have - a symlink, but we want to follow symlinks. If we run - across a directory loop, then we need to pretend that - we are not following symlinks for this file. If this - is the first time we have seen this, then make this - seem as if there was no symlink there in the first - place */ - - if( follow_links - && S_ISDIR(statbuf.st_mode) ) - { - if( strcmp(short_name, ".") - && strcmp(short_name, "..") ) - { - if(find_directory_hash(statbuf.st_dev, STAT_INODE(statbuf))) - { - if(!use_RockRidge) - { - fprintf (stderr, _("Already cached directory seen (%s)\n"), - whole_path); - return 0; - } - statbuf.st_size = 0; - STAT_INODE(statbuf) = UNCACHED_INODE; - statbuf.st_dev = (dev_t) UNCACHED_DEVICE; - statbuf.st_mode = (statbuf.st_mode & ~S_IFMT) | S_IFREG; - } - else - { - lstatbuf = statbuf; - add_directory_hash(statbuf.st_dev, STAT_INODE(statbuf)); - } - } - } - - /* - * For non-directories, we just copy the stat information over - * so we correctly include this file. - */ - if( follow_links - && !S_ISDIR(statbuf.st_mode) ) - { - lstatbuf = statbuf; - } - } - - /* - * Add directories to the cache so that we don't waste space even - * if we are supposed to be following symlinks. - */ - if( follow_links - && strcmp(short_name, ".") - && strcmp(short_name, "..") - && S_ISDIR(statbuf.st_mode) ) - { - add_directory_hash(statbuf.st_dev, STAT_INODE(statbuf)); - } - - if(S_ISREG(lstatbuf.st_mode) && (status = access(whole_path, R_OK))) - { - fprintf (stderr, _("File %s is not readable (%s) - ignoring\n"), - whole_path, strerror (errno)); - return 0; - } - - /* Add this so that we can detect directory loops with hard links. - If we are set up to follow symlinks, then we skip this checking. */ - if( !follow_links - && S_ISDIR(lstatbuf.st_mode) - && strcmp(short_name, ".") - && strcmp(short_name, "..") ) - { - if(find_directory_hash(statbuf.st_dev, STAT_INODE(statbuf))) - error (1, 0, _("Directory loop - fatal goof (%s %lx %lu).\n"), - whole_path, (unsigned long) statbuf.st_dev, - (unsigned long) STAT_INODE(statbuf)); - add_directory_hash(statbuf.st_dev, STAT_INODE(statbuf)); - } - - if (!S_ISCHR(lstatbuf.st_mode) && !S_ISBLK(lstatbuf.st_mode) && - !S_ISFIFO(lstatbuf.st_mode) && !S_ISSOCK(lstatbuf.st_mode) - && !S_ISLNK(lstatbuf.st_mode) && !S_ISREG(lstatbuf.st_mode) && - !S_ISDIR(lstatbuf.st_mode)) { - fprintf (stderr, _("Unknown file type %s - ignoring and continuing.\n"), - whole_path); - return 0; - } - - /* Who knows what trash this is - ignore and continue */ - - if(status) - { - fprintf (stderr, - _("Unable to stat file %s - ignoring and continuing.\n"), - whole_path); - return 0; - } - - /* - * Check to see if we have already seen this directory node. - * If so, then we don't create a new entry for it, but we do want - * to recurse beneath it and add any new files we do find. - */ - if (S_ISDIR(statbuf.st_mode)) - { - int dflag; - - for( s_entry = this_dir->contents; s_entry; s_entry = s_entry->next) - { - if( strcmp(s_entry->name, short_name) == 0 ) - { - break; - } - } - if ( s_entry != NULL - && strcmp(short_name,".") - && strcmp(short_name,"..")) - { - struct directory * child; - - if ( (s_entry->de_flags & RELOCATED_DIRECTORY) != 0) - { - for( s_entry = reloc_dir->contents; s_entry; s_entry = s_entry->next) - { - if( strcmp(s_entry->name, short_name) == 0 ) - { - break; - } - } - child = find_or_create_directory(reloc_dir, whole_path, - s_entry, 1); - } - else - { - child = find_or_create_directory(this_dir, whole_path, - s_entry, 1); - /* If unable to scan directory, mark this as a non-directory */ - } - dflag = scan_directory_tree(child, whole_path, s_entry); - if(!dflag) - { - lstatbuf.st_mode = (lstatbuf.st_mode & ~S_IFMT) | S_IFREG; - } - return 0; - } - } - - s_entry = (struct directory_entry *) - e_malloc(sizeof (struct directory_entry)); - s_entry->next = this_dir->contents; - memset(s_entry->isorec.extent, 0, 8); - this_dir->contents = s_entry; - deep_flag = 0; - s_entry->table = NULL; - - s_entry->name = strdup(short_name); - s_entry->whole_name = strdup (whole_path); - - s_entry->de_flags = 0; - - /* - * If the current directory is hidden, then hide all it's members - * otherwise check if this entry needs to be hidden as well */ - if (this_dir->dir_flags & INHIBIT_ISO9660_ENTRY) { - s_entry->de_flags |= INHIBIT_ISO9660_ENTRY; - } - else if (strcmp(short_name,".") && strcmp(short_name,"..")) { - if (i_matches(short_name) || i_matches(whole_path)) { - if (verbose > 1) { - fprintf (stderr, _("Hidden from ISO9660 tree: %s\n"), whole_path); - } - s_entry->de_flags |= INHIBIT_ISO9660_ENTRY; - } - } - - if (this_dir != reloc_dir && this_dir->dir_flags & INHIBIT_JOLIET_ENTRY) { - s_entry->de_flags |= INHIBIT_JOLIET_ENTRY; - } - else if (strcmp(short_name,".") && strcmp(short_name,"..")) { - if (j_matches(short_name) || j_matches(whole_path)) { - if (verbose > 1) { - fprintf (stderr, _("Hidden from Joliet tree: %s\n"), whole_path); - } - s_entry->de_flags |= INHIBIT_JOLIET_ENTRY; - } - } - - s_entry->filedir = this_dir; - s_entry->isorec.flags[0] = 0; - s_entry->isorec.ext_attr_length[0] = 0; - iso9660_date(s_entry->isorec.date, statbuf.st_mtime); - s_entry->isorec.file_unit_size[0] = 0; - s_entry->isorec.interleave[0] = 0; - - if( strcmp(short_name, ".") == 0) - { - this_dir->dir_flags |= DIR_HAS_DOT; - } - - if( strcmp(short_name, "..") == 0) - { - this_dir->dir_flags |= DIR_HAS_DOTDOT; - } - - if( this_dir->parent - && this_dir->parent == reloc_dir - && strcmp(short_name, "..") == 0) - { - s_entry->inode = UNCACHED_INODE; - s_entry->dev = (dev_t) UNCACHED_DEVICE; - deep_flag = NEED_PL; - } - else - { - s_entry->inode = STAT_INODE(statbuf); - s_entry->dev = statbuf.st_dev; - } - set_723(s_entry->isorec.volume_sequence_number, volume_sequence_number); - iso9660_file_length(short_name, s_entry, S_ISDIR(statbuf.st_mode)); - s_entry->rr_attr_size = 0; - s_entry->total_rr_attr_size = 0; - s_entry->rr_attributes = NULL; - - /* Directories are assigned sizes later on */ - if (!S_ISDIR(statbuf.st_mode)) - { - if (S_ISCHR(lstatbuf.st_mode) || S_ISBLK(lstatbuf.st_mode) || - S_ISFIFO(lstatbuf.st_mode) || S_ISSOCK(lstatbuf.st_mode) - || S_ISLNK(lstatbuf.st_mode)) - { - s_entry->size = 0; - statbuf.st_size = 0; - } - else - { - s_entry->size = statbuf.st_size; - } - - set_733((char *) s_entry->isorec.size, statbuf.st_size); - } - else - { - s_entry->isorec.flags[0] = 2; - } - - if (strcmp(short_name,".") && strcmp(short_name,"..") && - S_ISDIR(statbuf.st_mode) && this_dir->depth > RR_relocation_depth) - { - struct directory * child; - - if(!reloc_dir) generate_reloc_directory(); - - /* - * Replicate the entry for this directory. The old one will stay where it - * is, and it will be neutered so that it no longer looks like a directory. - * The new one will look like a directory, and it will be put in the reloc_dir. - */ - s_entry1 = (struct directory_entry *) - e_malloc(sizeof (struct directory_entry)); - memcpy(s_entry1, s_entry, sizeof(struct directory_entry)); - s_entry1->table = NULL; - s_entry1->name = strdup(this_dir->contents->name); - s_entry1->whole_name = strdup(this_dir->contents->whole_name); - s_entry1->next = reloc_dir->contents; - reloc_dir->contents = s_entry1; - s_entry1->priority = 32768; - s_entry1->parent_rec = this_dir->contents; - - deep_flag = NEED_RE; - - if(use_RockRidge) - { - generate_rock_ridge_attributes(whole_path, - short_name, s_entry1, - &statbuf, &lstatbuf, deep_flag); - } - - deep_flag = 0; - - /* We need to set this temporarily so that the parent to this - is correctly determined. */ - s_entry1->filedir = reloc_dir; - child = find_or_create_directory(reloc_dir, whole_path, - s_entry1, 0); - scan_directory_tree(child, whole_path, s_entry1); - s_entry1->filedir = this_dir; - - statbuf.st_size = 0; - statbuf.st_mode &= 0777; - set_733((char *) s_entry->isorec.size, 0); - s_entry->size = 0; - s_entry->isorec.flags[0] = 0; - s_entry->inode = UNCACHED_INODE; - s_entry->de_flags |= RELOCATED_DIRECTORY; - deep_flag = NEED_CL; - } - - if(generate_tables - && strcmp(s_entry->name, ".") - && strcmp(s_entry->name, "..")) - { - char buffer[2048]; - int nchar; - switch(lstatbuf.st_mode & S_IFMT) - { - case S_IFDIR: - sprintf(buffer,"D\t%s\n", - s_entry->name); - break; -#ifdef S_IFBLK -/* extra for WIN32 - if it doesn't have the major/minor defined, then - S_IFBLK and S_IFCHR type files are unlikely to exist anyway ... - code similar to that in rock.c */ - -/* for some reason, MAJOR_IN_SYSMACROS isn't defined on a SunOS when - it should be, so see if major() is defined instead */ -/* -#if !(defined(MAJOR_IN_SYSMACROS) || defined(MAJOR_IN_MKDEV)) -*/ -#ifndef major -#define major(dev) (sizeof(dev_t) <= 2 ? ((dev) >> 8) : \ - (sizeof(dev_t) <= 4 ? (((dev) >> 8) >> 8) : \ - (((dev) >> 16) >> 16))) -#define minor(dev) (sizeof(dev_t) <= 2 ? (dev) & 0xff : \ - (sizeof(dev_t) <= 4 ? (dev) & 0xffff : \ - (dev) & 0xffffffff)) -#endif - case S_IFBLK: - sprintf(buffer,"B\t%s\t%lu %lu\n", - s_entry->name, - (unsigned long) major(statbuf.st_rdev), - (unsigned long) minor(statbuf.st_rdev)); - break; -#endif -#ifdef S_IFIFO - case S_IFIFO: - sprintf(buffer,"P\t%s\n", - s_entry->name); - break; -#endif -#ifdef S_IFCHR - case S_IFCHR: - sprintf(buffer,"C\t%s\t%lu %lu\n", - s_entry->name, - (unsigned long) major(statbuf.st_rdev), - (unsigned long) minor(statbuf.st_rdev)); - break; -#endif -#ifdef S_IFLNK - case S_IFLNK: - nchar = readlink(whole_path, - (char *)symlink_buff, - sizeof(symlink_buff)); - symlink_buff[nchar < 0 ? 0 : nchar] = 0; - sprintf(buffer,"L\t%s\t%s\n", - s_entry->name, symlink_buff); - break; -#endif -#ifdef S_IFSOCK - case S_IFSOCK: - sprintf(buffer,"S\t%s\n", - s_entry->name); - break; -#endif - case S_IFREG: - default: - sprintf(buffer,"F\t%s\n", - s_entry->name); - break; - }; - s_entry->table = strdup(buffer); - } - - if(S_ISDIR(statbuf.st_mode)) - { - int dflag; - if (strcmp(short_name,".") && strcmp(short_name,"..")) - { - struct directory * child; - - child = find_or_create_directory(this_dir, whole_path, - s_entry, 1); - dflag = scan_directory_tree(child, whole_path, s_entry); - - if(!dflag) - { - lstatbuf.st_mode = (lstatbuf.st_mode & ~S_IFMT) | S_IFREG; - if( child->contents == NULL ) - { - delete_directory(this_dir, child); - } - } - } - /* If unable to scan directory, mark this as a non-directory */ - } - - if(use_RockRidge && this_dir == root && strcmp(s_entry->name, ".") == 0) - { - deep_flag |= NEED_CE | NEED_SP; /* For extension record */ - } - - /* Now figure out how much room this file will take in the - directory */ - - if(use_RockRidge) - { - generate_rock_ridge_attributes(whole_path, - short_name, s_entry, - &statbuf, &lstatbuf, deep_flag); - - } - - return 1; -} - - -void FDECL2(generate_iso9660_directories, struct directory *, node, FILE*, outfile){ - struct directory * dpnt; - - dpnt = node; - - while (dpnt){ - if( dpnt->extent > session_start ) - { - generate_one_directory(dpnt, outfile); - } - if(dpnt->subdir) generate_iso9660_directories(dpnt->subdir, outfile); - dpnt = dpnt->next; - } -} - -/* - * Function: find_or_create_directory - * - * Purpose: Locate a directory entry in the tree, create if needed. - * - * Arguments: - */ -struct directory * FDECL4(find_or_create_directory, struct directory *, parent, - const char *, path, - struct directory_entry *, de, int, flag) -{ - struct directory * dpnt; - struct directory_entry * orig_de; - struct directory * next_brother; - const char * cpnt; - const char * pnt; - - orig_de = de; - - pnt = strrchr(path, PATH_SEPARATOR); - if( pnt == NULL ) - { - pnt = path; - } - else - { - pnt++; - } - - if( parent != NULL ) - { - dpnt = parent->subdir; - - while (dpnt) - { - /* - * Weird hack time - if there are two directories by the - * same name in the reloc_dir, they are not treated as the - * same thing unless the entire path matches completely. - */ - if( flag && strcmp(dpnt->de_name, pnt) == 0 ) - { - return dpnt; - } - dpnt = dpnt->next; - } - } - - /* - * We don't know if we have a valid directory entry for this one - * yet. If not, we need to create one. - */ - if( de == NULL ) - { - de = (struct directory_entry *) - e_malloc(sizeof (struct directory_entry)); - memset(de, 0, sizeof(struct directory_entry)); - de->next = parent->contents; - parent->contents = de; - de->name = strdup(pnt); - de->filedir = parent; - de->isorec.flags[0] = 2; - de->priority = 32768; - de->inode = UNCACHED_INODE; - de->dev = (dev_t) UNCACHED_DEVICE; - set_723(de->isorec.volume_sequence_number, volume_sequence_number); - iso9660_file_length (pnt, de, 1); - - init_fstatbuf(); - /* - * It doesn't exist for real, so we cannot add any Rock Ridge. - */ - if(use_RockRidge) - { - fstatbuf.st_mode = 0555 | S_IFDIR; - fstatbuf.st_nlink = 2; - generate_rock_ridge_attributes("", - (char *) pnt, de, - &fstatbuf, - &fstatbuf, 0); - } - iso9660_date(de->isorec.date, fstatbuf.st_mtime); - - } - - /* - * If we don't have a directory for this one yet, then allocate it - * now, and patch it into the tree in the appropriate place. - */ - dpnt = (struct directory *) e_malloc(sizeof(struct directory)); - memset(dpnt, 0, sizeof(struct directory)); - dpnt->next = NULL; - dpnt->subdir = NULL; - dpnt->self = de; - dpnt->contents = NULL; - dpnt->whole_name = strdup(path); - cpnt = strrchr(path, PATH_SEPARATOR); - if(cpnt) - cpnt++; - else - cpnt = path; - dpnt->de_name = strdup(cpnt); - dpnt->size = 0; - dpnt->extent = 0; - dpnt->jextent = 0; - dpnt->jsize = 0; - - if( orig_de == NULL ) - { - struct stat xstatbuf; - int sts; - - /* - * Now add a . and .. entry in the directory itself. - * This is a little tricky - if the real directory - * exists, we need to stat it first. Otherwise, we - * use the fictitious fstatbuf which points to the time - * at which mkisofs was started. - */ - sts = stat_filter(parent->whole_name, &xstatbuf); - if( sts == 0 ) - { - attach_dot_entries(dpnt, &xstatbuf); - } - else - { - attach_dot_entries(dpnt, &fstatbuf); - } - } - - if(!parent || parent == root) - { - if (!root) - { - root = dpnt; /* First time through for root directory only */ - root->depth = 0; - root->parent = root; - } else { - dpnt->depth = 1; - if(!root->subdir) - { - root->subdir = dpnt; - } - else - { - next_brother = root->subdir; - while(next_brother->next) next_brother = next_brother->next; - next_brother->next = dpnt; - } - dpnt->parent = parent; - } - } - else - { - /* Come through here for normal traversal of tree */ -#ifdef DEBUG - fprintf(stderr,"%s(%d) ", path, dpnt->depth); -#endif - if(parent->depth > RR_relocation_depth) - error (1, 0, _("Directories too deep %s\n"), path); - - dpnt->parent = parent; - dpnt->depth = parent->depth + 1; - - if(!parent->subdir) - { - parent->subdir = dpnt; - } - else - { - next_brother = parent->subdir; - while(next_brother->next) next_brother = next_brother->next; - next_brother->next = dpnt; - } - } - - return dpnt; -} - -/* - * Function: delete_directory - * - * Purpose: Locate a directory entry in the tree, create if needed. - * - * Arguments: - */ -static void FDECL2(delete_directory, struct directory *, parent, struct directory *, child) -{ - struct directory * tdir; - - if( child->contents != NULL ) - error (1, 0, _("Unable to delete non-empty directory\n")); - - free(child->whole_name); - child->whole_name = NULL; - - free(child->de_name); - child->de_name = NULL; - - if( parent->subdir == child ) - { - parent->subdir = child->next; - } - else - { - for( tdir = parent->subdir; tdir->next != NULL; tdir = tdir->next ) - { - if( tdir->next == child ) - { - tdir->next = child->next; - break; - } - } - if( tdir == NULL ) - error (1, 0, _("Unable to locate child directory in parent list\n")); - } - free(child); - return; -} - -int FDECL1(sort_tree, struct directory *, node){ - struct directory * dpnt; - int ret = 0; - - dpnt = node; - - while (dpnt){ - ret = sort_n_finish(dpnt); - if( ret ) - { - break; - } - - if(dpnt->subdir) sort_tree(dpnt->subdir); - dpnt = dpnt->next; - } - return ret; -} - -void FDECL1(dump_tree, struct directory *, node){ - struct directory * dpnt; - - dpnt = node; - - while (dpnt){ - fprintf(stderr,"%4d %5d %s\n",dpnt->extent, dpnt->size, dpnt->de_name); - if(dpnt->subdir) dump_tree(dpnt->subdir); - dpnt = dpnt->next; - } -} - -void FDECL1(update_nlink_field, struct directory *, node) -{ - struct directory * dpnt; - struct directory * xpnt; - struct directory_entry * s_entry; - int i; - - dpnt = node; - - while (dpnt) - { - if (dpnt->dir_flags & INHIBIT_ISO9660_ENTRY) { - dpnt = dpnt->next; - continue; - } - - /* - * First, count up the number of subdirectories this guy has. - */ - for(i=0, xpnt = dpnt->subdir; xpnt; xpnt = xpnt->next) - if ((xpnt->dir_flags & INHIBIT_ISO9660_ENTRY) == 0) - i++; - /* - * Next check to see if we have any relocated directories - * in this directory. The nlink field will include these - * as real directories when they are properly relocated. - * - * In the non-rockridge disk, the relocated entries appear - * as zero length files. - */ - for(s_entry = dpnt->contents; s_entry; s_entry = s_entry->next) - { - if( (s_entry->de_flags & RELOCATED_DIRECTORY) != 0 && - (s_entry->de_flags & INHIBIT_ISO9660_ENTRY) == 0) - { - i++; - } - } - /* - * Now update the field in the Rock Ridge entry. - */ - update_nlink(dpnt->self, i + 2); - - /* - * Update the '.' entry for this directory. - */ - update_nlink(dpnt->contents, i + 2); - - /* - * Update all of the '..' entries that point to this guy. - */ - for(xpnt = dpnt->subdir; xpnt; xpnt = xpnt->next) - update_nlink(xpnt->contents->next, i + 2); - - if(dpnt->subdir) update_nlink_field(dpnt->subdir); - dpnt = dpnt->next; - } -} - -/* - * something quick and dirty to locate a file given a path - * recursively walks down path in filename until it finds the - * directory entry for the desired file - */ -struct directory_entry * FDECL2(search_tree_file, struct directory *, - node,char *, filename) -{ - struct directory_entry * depnt; - struct directory * dpnt; - char * p1; - char * rest; - char * subdir; - - /* - * strip off next directory name from filename - */ - subdir = strdup(filename); - - if( (p1=strchr(subdir, '/')) == subdir ) - { - fprintf (stderr, _("call to search_tree_file with an absolute path, stripping\n")); - fprintf (stderr, _("initial path separator. Hope this was intended...\n")); - memmove(subdir, subdir+1, strlen(subdir)-1); - p1 = strchr(subdir, '/'); - } - - /* - * do we need to find a subdirectory - */ - if (p1) - { - *p1 = '\0'; - -#ifdef DEBUG_TORITO - fprintf(stderr,"Looking for subdir called %s\n",p1); -#endif - - rest = p1+1; - -#ifdef DEBUG_TORITO - fprintf(stderr,"Remainder of path name is now %s\n", rest); -#endif - - dpnt = node->subdir; - while( dpnt ) - { -#ifdef DEBUG_TORITO - fprintf(stderr,"%4d %5d %s\n", dpnt->extent, dpnt->size, - dpnt->de_name); -#endif - if (!strcmp(subdir, dpnt->de_name)) - { -#ifdef DEBUG_TORITO - fprintf(stderr,"Calling next level with filename = %s", rest); -#endif - return(search_tree_file( dpnt, rest )); - } - dpnt = dpnt->next; - } - - /* if we got here means we couldnt find the subdir */ - return (NULL); - } - else - { - /* - * look for a normal file now - */ - depnt = node->contents; - while (depnt) - { -#ifdef DEBUG_TORITO - fprintf(stderr,"%4d %5d %s\n",depnt->isorec.extent, - depnt->size, depnt->name); -#endif - if (!strcmp(filename, depnt->name)) - { -#ifdef DEBUG_TORITO - fprintf(stderr,"Found our file %s", filename); -#endif - return(depnt); - } - depnt = depnt->next; - } - /* - * if we got here means we couldnt find the subdir - */ - return (NULL); - } - fprintf (stderr, "We cant get here in search_tree_file :-/ \n"); -} - -void init_fstatbuf() -{ - time_t current_time; - - if(fstatbuf.st_ctime == 0) - { - time (¤t_time); - if( rationalize ) - { - fstatbuf.st_uid = 0; - fstatbuf.st_gid = 0; - } - else - { - fstatbuf.st_uid = getuid(); - fstatbuf.st_gid = getgid(); - } - fstatbuf.st_ctime = current_time; - fstatbuf.st_mtime = current_time; - fstatbuf.st_atime = current_time; - } -} diff --git a/util/mkisofs/write.c b/util/mkisofs/write.c deleted file mode 100644 index e1cdd213e..000000000 --- a/util/mkisofs/write.c +++ /dev/null @@ -1,1483 +0,0 @@ -/* - * Program write.c - dump memory structures to file for iso9660 filesystem. - - Written by Eric Youngdale (1993). - - Copyright 1993 Yggdrasil Computing, Incorporated - - Copyright (C) 2009 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, see . - */ - -#include "config.h" - -#include -#include -#include -#include - -#include -#include -#include -#include - -#ifdef HAVE_UNISTD_H -#include -#endif - -#include "mkisofs.h" -#include "iso9660.h" -#include "msdos_partition.h" - -#ifdef __SVR4 -extern char * strdup(const char *); -#endif - -#ifdef VMS -extern char * strdup(const char *); -#endif - - -/* Max number of sectors we will write at one time */ -#define NSECT 16 - -/* Counters for statistics */ - -static int table_size = 0; -static int total_dir_size = 0; -static int rockridge_size = 0; -static struct directory ** pathlist; -static int next_path_index = 1; -static int sort_goof; - -struct output_fragment * out_tail; -struct output_fragment * out_list; - -struct iso_primary_descriptor vol_desc; - -static int root_gen __PR((void)); -static int generate_path_tables __PR((void)); -static int file_gen __PR((void)); -static int dirtree_dump __PR((void)); - -/* Routines to actually write the disc. We write sequentially so that - we could write a tape, or write the disc directly */ - - -#define FILL_SPACE(X) memset(vol_desc.X, ' ', sizeof(vol_desc.X)) - -void FDECL2(set_721, char *, pnt, unsigned int, i) -{ - pnt[0] = i & 0xff; - pnt[1] = (i >> 8) & 0xff; -} - -void FDECL2(set_722, char *, pnt, unsigned int, i) -{ - pnt[0] = (i >> 8) & 0xff; - pnt[1] = i & 0xff; -} - -void FDECL2(set_723, char *, pnt, unsigned int, i) -{ - pnt[3] = pnt[0] = i & 0xff; - pnt[2] = pnt[1] = (i >> 8) & 0xff; -} - -void FDECL2(set_731, char *, pnt, unsigned int, i) -{ - pnt[0] = i & 0xff; - pnt[1] = (i >> 8) & 0xff; - pnt[2] = (i >> 16) & 0xff; - pnt[3] = (i >> 24) & 0xff; -} - -void FDECL2(set_732, char *, pnt, unsigned int, i) -{ - pnt[3] = i & 0xff; - pnt[2] = (i >> 8) & 0xff; - pnt[1] = (i >> 16) & 0xff; - pnt[0] = (i >> 24) & 0xff; -} - -int FDECL1(get_731, char *, p) -{ - return ((p[0] & 0xff) - | ((p[1] & 0xff) << 8) - | ((p[2] & 0xff) << 16) - | ((p[3] & 0xff) << 24)); -} - -int FDECL1(get_733, char *, p) -{ - return ((p[0] & 0xff) - | ((p[1] & 0xff) << 8) - | ((p[2] & 0xff) << 16) - | ((p[3] & 0xff) << 24)); -} - -void FDECL2(set_733, char *, pnt, unsigned int, i) -{ - pnt[7] = pnt[0] = i & 0xff; - pnt[6] = pnt[1] = (i >> 8) & 0xff; - pnt[5] = pnt[2] = (i >> 16) & 0xff; - pnt[4] = pnt[3] = (i >> 24) & 0xff; -} - -void FDECL4(xfwrite, void *, buffer, uint64_t, count, uint64_t, size, FILE *, file) -{ - /* - * This is a hack that could be made better. XXXIs this the only place? - * It is definitely needed on Operating Systems that do not - * allow to write files that are > 2GB. - * If the system is fast enough to be able to feed 1400 KB/s - * writing speed of a DVD-R drive, use stdout. - * If the system cannot do this reliable, you need to use this - * hacky option. - */ - static int idx = 0; - if (split_output != 0 && - (idx == 0 || ftell(file) >= (1024 * 1024 * 1024) )) { - char nbuf[512]; - extern char *outfile; - - if (idx == 0) - unlink(outfile); - sprintf(nbuf, "%s_%02d", outfile, idx++); - file = freopen(nbuf, "wb", file); - if (file == NULL) - error (1, errno, _("Cannot open `%s'"), nbuf); - - } - while(count) - { - size_t got = fwrite (buffer, size, count, file); - - if (got != count) - error (1, errno, _("cannot fwrite %llu*%llu\n"), size, count); - count-=got,*(char**)&buffer+=size*got; - } -} - -struct deferred_write -{ - struct deferred_write * next; - char * table; - uint64_t extent; - uint64_t size; - char * name; -}; - -static struct deferred_write * dw_head = NULL, * dw_tail = NULL; - -uint64_t last_extent_written = 0; -static unsigned int path_table_index; -static time_t begun; - -/* We recursively walk through all of the directories and assign extent - numbers to them. We have already assigned extent numbers to everything that - goes in front of them */ - -static int FDECL1(assign_directory_addresses, struct directory *, node) -{ - int dir_size; - struct directory * dpnt; - - dpnt = node; - - while (dpnt) - { - /* skip if it's hidden */ - if(dpnt->dir_flags & INHIBIT_ISO9660_ENTRY) { - dpnt = dpnt->next; - continue; - } - - /* - * If we already have an extent for this (i.e. it came from - * a multisession disc), then don't reassign a new extent. - */ - dpnt->path_index = next_path_index++; - if( dpnt->extent == 0 ) - { - dpnt->extent = last_extent; - dir_size = (dpnt->size + (SECTOR_SIZE - 1)) >> 11; - - last_extent += dir_size; - - /* - * Leave room for the CE entries for this directory. Keep them - * close to the reference directory so that access will be - * quick. - */ - if(dpnt->ce_bytes) - { - last_extent += ROUND_UP(dpnt->ce_bytes) >> 11; - } - } - - if(dpnt->subdir) - { - assign_directory_addresses(dpnt->subdir); - } - - dpnt = dpnt->next; - } - return 0; -} - -static void FDECL3(write_one_file, char *, filename, - uint64_t, size, FILE *, outfile) -{ - char buffer[SECTOR_SIZE * NSECT]; - FILE * infile; - int64_t remain; - size_t use; - - - if ((infile = fopen(filename, "rb")) == NULL) - error (1, errno, _("cannot open %s\n"), filename); - remain = size; - - while(remain > 0) - { - use = (remain > SECTOR_SIZE * NSECT - 1 ? NSECT*SECTOR_SIZE : remain); - use = ROUND_UP(use); /* Round up to nearest sector boundary */ - memset(buffer, 0, use); - if (fread(buffer, 1, use, infile) == 0) - error (1, errno, _("cannot read %llu bytes from %s"), use, filename); - xfwrite(buffer, 1, use, outfile); - last_extent_written += use/SECTOR_SIZE; -#if 0 - if((last_extent_written % 1000) < use/SECTOR_SIZE) - { - fprintf(stderr,"%d..", last_extent_written); - } -#else - if((last_extent_written % 5000) < use/SECTOR_SIZE) - { - time_t now; - time_t the_end; - double frac; - - time(&now); - frac = last_extent_written / (double)last_extent; - the_end = begun + (now - begun) / frac; - fprintf (stderr, _("%6.2f%% done, estimate finish %s"), - frac * 100., ctime(&the_end)); - } -#endif - remain -= use; - } - fclose(infile); -} /* write_one_file(... */ - -static void FDECL1(write_files, FILE *, outfile) -{ - struct deferred_write * dwpnt, *dwnext; - dwpnt = dw_head; - while(dwpnt) - { - if(dwpnt->table) - { - write_one_file (dwpnt->table, dwpnt->size, outfile); - table_size += dwpnt->size; - free (dwpnt->table); - } - else - { - -#ifdef VMS - vms_write_one_file(dwpnt->name, dwpnt->size, outfile); -#else - write_one_file(dwpnt->name, dwpnt->size, outfile); -#endif - free(dwpnt->name); - } - - dwnext = dwpnt; - dwpnt = dwpnt->next; - free(dwnext); - } -} /* write_files(... */ - -#if 0 -static void dump_filelist() -{ - struct deferred_write * dwpnt; - dwpnt = dw_head; - while(dwpnt) - { - fprintf(stderr, "File %s\n",dwpnt->name); - dwpnt = dwpnt->next; - } - fprintf(stderr,"\n"); -} -#endif - -static int FDECL2(compare_dirs, const void *, rr, const void *, ll) -{ - char * rpnt, *lpnt; - struct directory_entry ** r, **l; - - r = (struct directory_entry **) rr; - l = (struct directory_entry **) ll; - rpnt = (*r)->isorec.name; - lpnt = (*l)->isorec.name; - - /* - * If the entries are the same, this is an error. - */ - if( strcmp(rpnt, lpnt) == 0 ) - { - sort_goof++; - } - - /* - * Put the '.' and '..' entries on the head of the sorted list. - * For normal ASCII, this always happens to be the case, but out of - * band characters cause this not to be the case sometimes. - * - * FIXME(eric) - these tests seem redundant, in taht the name is - * never assigned these values. It will instead be \000 or \001, - * and thus should always be sorted correctly. I need to figure - * out why I thought I needed this in the first place. - */ -#if 0 - if( strcmp(rpnt, ".") == 0 ) return -1; - if( strcmp(lpnt, ".") == 0 ) return 1; - - if( strcmp(rpnt, "..") == 0 ) return -1; - if( strcmp(lpnt, "..") == 0 ) return 1; -#else - /* - * The code above is wrong (as explained in Eric's comment), leading to incorrect - * sort order iff the -L option ("allow leading dots") is in effect and a directory - * contains entries that start with a dot. - * - * (TF, Tue Dec 29 13:49:24 CET 1998) - */ - if((*r)->isorec.name_len[0] == 1 && *rpnt == 0) return -1; /* '.' */ - if((*l)->isorec.name_len[0] == 1 && *lpnt == 0) return 1; - - if((*r)->isorec.name_len[0] == 1 && *rpnt == 1) return -1; /* '..' */ - if((*l)->isorec.name_len[0] == 1 && *lpnt == 1) return 1; -#endif - - while(*rpnt && *lpnt) - { - if(*rpnt == ';' && *lpnt != ';') return -1; - if(*rpnt != ';' && *lpnt == ';') return 1; - - if(*rpnt == ';' && *lpnt == ';') return 0; - - if(*rpnt == '.' && *lpnt != '.') return -1; - if(*rpnt != '.' && *lpnt == '.') return 1; - - if((unsigned char)*rpnt < (unsigned char)*lpnt) return -1; - if((unsigned char)*rpnt > (unsigned char)*lpnt) return 1; - rpnt++; lpnt++; - } - if(*rpnt) return 1; - if(*lpnt) return -1; - return 0; -} - -/* - * Function: sort_directory - * - * Purpose: Sort the directory in the appropriate ISO9660 - * order. - * - * Notes: Returns 0 if OK, returns > 0 if an error occurred. - */ -int FDECL1(sort_directory, struct directory_entry **, sort_dir) -{ - int dcount = 0; - int xcount = 0; - int j; - int i, len; - struct directory_entry * s_entry; - struct directory_entry ** sortlist; - - /* need to keep a count of how many entries are hidden */ - s_entry = *sort_dir; - while(s_entry) - { - if (s_entry->de_flags & INHIBIT_ISO9660_ENTRY) - xcount++; - dcount++; - s_entry = s_entry->next; - } - - if( dcount == 0 ) - { - return 0; - } - - /* - * OK, now we know how many there are. Build a vector for sorting. - */ - sortlist = (struct directory_entry **) - e_malloc(sizeof(struct directory_entry *) * dcount); - - j = dcount - 1; - dcount = 0; - s_entry = *sort_dir; - while(s_entry) - { - if(s_entry->de_flags & INHIBIT_ISO9660_ENTRY) - { - /* put any hidden entries at the end of the vector */ - sortlist[j--] = s_entry; - } - else - { - sortlist[dcount] = s_entry; - dcount++; - } - len = s_entry->isorec.name_len[0]; - s_entry->isorec.name[len] = 0; - s_entry = s_entry->next; - } - - /* - * Each directory is required to contain at least . and .. - */ - if( dcount < 2 ) - { - sort_goof = 1; - - } - else - { - /* only sort the non-hidden entries */ - sort_goof = 0; -#ifdef __STDC__ - qsort(sortlist, dcount, sizeof(struct directory_entry *), - (int (*)(const void *, const void *))compare_dirs); -#else - qsort(sortlist, dcount, sizeof(struct directory_entry *), - compare_dirs); -#endif - - /* - * Now reassemble the linked list in the proper sorted order - * We still need the hidden entries, as they may be used in the - * Joliet tree. - */ - for(i=0; inext = sortlist[i+1]; - } - - sortlist[dcount+xcount-1]->next = NULL; - *sort_dir = sortlist[0]; - } - - free(sortlist); - return sort_goof; -} - -static int root_gen() -{ - init_fstatbuf(); - - root_record.length[0] = 1 + sizeof(struct iso_directory_record) - - sizeof(root_record.name); - root_record.ext_attr_length[0] = 0; - set_733((char *) root_record.extent, root->extent); - set_733((char *) root_record.size, ROUND_UP(root->size)); - iso9660_date(root_record.date, root_statbuf.st_mtime); - root_record.flags[0] = 2; - root_record.file_unit_size[0] = 0; - root_record.interleave[0] = 0; - set_723(root_record.volume_sequence_number, volume_sequence_number); - root_record.name_len[0] = 1; - return 0; -} - -static void FDECL1(assign_file_addresses, struct directory *, dpnt) -{ - struct directory * finddir; - struct directory_entry * s_entry; - struct file_hash *s_hash; - struct deferred_write * dwpnt; - char whole_path[1024]; - - while (dpnt) - { - s_entry = dpnt->contents; - for(s_entry = dpnt->contents; s_entry; s_entry = s_entry->next) - { - /* - * If we already have an extent for this entry, - * then don't assign a new one. It must have come - * from a previous session on the disc. Note that - * we don't end up scheduling the thing for writing - * either. - */ - if( isonum_733((unsigned char *) s_entry->isorec.extent) != 0 ) - { - continue; - } - - /* - * This saves some space if there are symlinks present - */ - s_hash = find_hash(s_entry->dev, s_entry->inode); - if(s_hash) - { - if(verbose > 2) - { - fprintf (stderr, _("Cache hit for %s%s%s\n"), s_entry->filedir->de_name, - SPATH_SEPARATOR, s_entry->name); - } - set_733((char *) s_entry->isorec.extent, s_hash->starting_block); - set_733((char *) s_entry->isorec.size, s_hash->size); - continue; - } - - /* - * If this is for a directory that is not a . or a .. entry, - * then look up the information for the entry. We have already - * assigned extents for directories, so we just need to - * fill in the blanks here. - */ - if (strcmp(s_entry->name,".") && strcmp(s_entry->name,"..") && - s_entry->isorec.flags[0] == 2) - { - finddir = dpnt->subdir; - while(1==1) - { - if(finddir->self == s_entry) break; - finddir = finddir->next; - if (!finddir) - error (1, 0, _("Fatal goof\n")); - } - set_733((char *) s_entry->isorec.extent, finddir->extent); - s_entry->starting_block = finddir->extent; - s_entry->size = ROUND_UP(finddir->size); - total_dir_size += s_entry->size; - add_hash(s_entry); - set_733((char *) s_entry->isorec.size, ROUND_UP(finddir->size)); - continue; - } - - - /* - * If this is . or .., then look up the relevant info from the - * tables. - */ - if(strcmp(s_entry->name,".") == 0) - { - set_733((char *) s_entry->isorec.extent, dpnt->extent); - - /* - * Set these so that the hash table has the - * correct information - */ - s_entry->starting_block = dpnt->extent; - s_entry->size = ROUND_UP(dpnt->size); - - add_hash(s_entry); - s_entry->starting_block = dpnt->extent; - set_733((char *) s_entry->isorec.size, ROUND_UP(dpnt->size)); - continue; - } - - if(strcmp(s_entry->name,"..") == 0) - { - if(dpnt == root) - { - total_dir_size += root->size; - } - set_733((char *) s_entry->isorec.extent, dpnt->parent->extent); - - /* - * Set these so that the hash table has the - * correct information - */ - s_entry->starting_block = dpnt->parent->extent; - s_entry->size = ROUND_UP(dpnt->parent->size); - - add_hash(s_entry); - s_entry->starting_block = dpnt->parent->extent; - set_733((char *) s_entry->isorec.size, ROUND_UP(dpnt->parent->size)); - continue; - } - - /* - * Some ordinary non-directory file. Just schedule the - * file to be written. This is all quite - * straightforward, just make a list and assign extents - * as we go. Once we get through writing all of the - * directories, we should be ready write out these - * files - */ - if(s_entry->size) - { - dwpnt = (struct deferred_write *) - e_malloc(sizeof(struct deferred_write)); - if(dw_tail) - { - dw_tail->next = dwpnt; - dw_tail = dwpnt; - } - else - { - dw_head = dwpnt; - dw_tail = dwpnt; - } - if(s_entry->inode == TABLE_INODE) - { - dwpnt->table = s_entry->table; - dwpnt->name = NULL; - sprintf(whole_path,"%s%sTRANS.TBL", - s_entry->filedir->whole_name, SPATH_SEPARATOR); - } - else - { - dwpnt->table = NULL; - strcpy(whole_path, s_entry->whole_name); - dwpnt->name = strdup(whole_path); - } - dwpnt->next = NULL; - dwpnt->size = s_entry->size; - dwpnt->extent = last_extent; - set_733((char *) s_entry->isorec.extent, last_extent); - s_entry->starting_block = last_extent; - add_hash(s_entry); - last_extent += ROUND_UP(s_entry->size) >> 11; - if(verbose > 2) - { - fprintf(stderr,"%llu %llu %s\n", s_entry->starting_block, - last_extent-1, whole_path); - } -#ifdef DBG_ISO - if((ROUND_UP(s_entry->size) >> 11) > 500) - { - fprintf (stderr, "Warning: large file %s\n", whole_path); - fprintf (stderr, "Starting block is %d\n", s_entry->starting_block); - fprintf (stderr, "Reported file size is %d extents\n", s_entry->size); - - } -#endif -#ifdef NOT_NEEDED /* Never use this code if you like to create a DVD */ - - if(last_extent > (800000000 >> 11)) - { - /* - * More than 800Mb? Punt - */ - fprintf(stderr,"Extent overflow processing file %s\n", whole_path); - fprintf(stderr,"Starting block is %d\n", s_entry->starting_block); - fprintf(stderr,"Reported file size is %d extents\n", s_entry->size); - exit(1); - } -#endif - continue; - } - - /* - * This is for zero-length files. If we leave the extent 0, - * then we get screwed, because many readers simply drop files - * that have an extent of zero. Thus we leave the size 0, - * and just assign the extent number. - */ - set_733((char *) s_entry->isorec.extent, last_extent); - } - if(dpnt->subdir) - { - assign_file_addresses(dpnt->subdir); - } - dpnt = dpnt->next; - } -} /* assign_file_addresses(... */ - -static void FDECL1(free_one_directory, struct directory *, dpnt) -{ - struct directory_entry * s_entry; - struct directory_entry * s_entry_d; - - s_entry = dpnt->contents; - while(s_entry) - { - s_entry_d = s_entry; - s_entry = s_entry->next; - - if( s_entry_d->name != NULL ) - { - free (s_entry_d->name); - } - if( s_entry_d->whole_name != NULL ) - { - free (s_entry_d->whole_name); - } - free (s_entry_d); - } - dpnt->contents = NULL; -} /* free_one_directory(... */ - -static void FDECL1(free_directories, struct directory *, dpnt) -{ - while (dpnt) - { - free_one_directory(dpnt); - if(dpnt->subdir) free_directories(dpnt->subdir); - dpnt = dpnt->next; - } -} - -void FDECL2(generate_one_directory, struct directory *, dpnt, FILE *, outfile) -{ - unsigned int ce_address = 0; - char * ce_buffer; - unsigned int ce_index = 0; - unsigned int ce_size; - unsigned int dir_index; - char * directory_buffer; - int new_reclen; - struct directory_entry * s_entry; - struct directory_entry * s_entry_d; - unsigned int total_size; - - total_size = (dpnt->size + (SECTOR_SIZE - 1)) & ~(SECTOR_SIZE - 1); - directory_buffer = (char *) e_malloc(total_size); - memset(directory_buffer, 0, total_size); - dir_index = 0; - - ce_size = (dpnt->ce_bytes + (SECTOR_SIZE - 1)) & ~(SECTOR_SIZE - 1); - ce_buffer = NULL; - - if(ce_size) - { - ce_buffer = (char *) e_malloc(ce_size); - memset(ce_buffer, 0, ce_size); - - ce_index = 0; - - /* - * Absolute byte address of CE entries for this directory - */ - ce_address = last_extent_written + (total_size >> 11); - ce_address = ce_address << 11; - } - - s_entry = dpnt->contents; - while(s_entry) - { - /* skip if it's hidden */ - if(s_entry->de_flags & INHIBIT_ISO9660_ENTRY) { - s_entry = s_entry->next; - continue; - } - - /* - * We do not allow directory entries to cross sector boundaries. - * Simply pad, and then start the next entry at the next sector - */ - new_reclen = s_entry->isorec.length[0]; - if( (dir_index & (SECTOR_SIZE - 1)) + new_reclen >= SECTOR_SIZE ) - { - dir_index = (dir_index + (SECTOR_SIZE - 1)) & - ~(SECTOR_SIZE - 1); - } - - memcpy(directory_buffer + dir_index, &s_entry->isorec, - sizeof(struct iso_directory_record) - - sizeof(s_entry->isorec.name) + s_entry->isorec.name_len[0]); - dir_index += sizeof(struct iso_directory_record) - - sizeof (s_entry->isorec.name)+ s_entry->isorec.name_len[0]; - - /* - * Add the Rock Ridge attributes, if present - */ - if(s_entry->rr_attr_size) - { - if(dir_index & 1) - { - directory_buffer[dir_index++] = 0; - } - - /* - * If the RR attributes were too long, then write the - * CE records, as required. - */ - if(s_entry->rr_attr_size != s_entry->total_rr_attr_size) - { - unsigned char * pnt; - int len, nbytes; - - /* - * Go through the entire record and fix up the CE entries - * so that the extent and offset are correct - */ - - pnt = s_entry->rr_attributes; - len = s_entry->total_rr_attr_size; - while(len > 3) - { -#ifdef DEBUG - if (!ce_size) - { - fprintf(stderr,"Warning: ce_index(%d) && ce_address(%d) not initialized\n", - ce_index, ce_address); - } -#endif - - if(pnt[0] == 'C' && pnt[1] == 'E') - { - nbytes = get_733( (char *) pnt+20); - - if((ce_index & (SECTOR_SIZE - 1)) + nbytes >= - SECTOR_SIZE) - { - ce_index = ROUND_UP(ce_index); - } - - set_733( (char *) pnt+4, - (ce_address + ce_index) >> 11); - set_733( (char *) pnt+12, - (ce_address + ce_index) & (SECTOR_SIZE - 1)); - - - /* - * Now store the block in the ce buffer - */ - memcpy(ce_buffer + ce_index, - pnt + pnt[2], nbytes); - ce_index += nbytes; - if(ce_index & 1) - { - ce_index++; - } - } - len -= pnt[2]; - pnt += pnt[2]; - } - - } - - rockridge_size += s_entry->total_rr_attr_size; - memcpy(directory_buffer + dir_index, s_entry->rr_attributes, - s_entry->rr_attr_size); - dir_index += s_entry->rr_attr_size; - } - if(dir_index & 1) - { - directory_buffer[dir_index++] = 0; - } - - s_entry_d = s_entry; - s_entry = s_entry->next; - - /* - * Joliet doesn't use the Rock Ridge attributes, so we free it here. - */ - if (s_entry_d->rr_attributes) - { - free(s_entry_d->rr_attributes); - s_entry_d->rr_attributes = NULL; - } - } - - if(dpnt->size != dir_index) - { - fprintf (stderr, _("Unexpected directory length %d %d %s\n"), dpnt->size, - dir_index, dpnt->de_name); - } - - xfwrite(directory_buffer, 1, total_size, outfile); - last_extent_written += total_size >> 11; - free(directory_buffer); - - if(ce_size) - { - if(ce_index != dpnt->ce_bytes) - { - fprintf (stderr, _("Continuation entry record length mismatch (%d %d).\n"), - ce_index, dpnt->ce_bytes); - } - xfwrite(ce_buffer, 1, ce_size, outfile); - last_extent_written += ce_size >> 11; - free(ce_buffer); - } - -} /* generate_one_directory(... */ - -static -void FDECL1(build_pathlist, struct directory *, node) -{ - struct directory * dpnt; - - dpnt = node; - - while (dpnt) - { - /* skip if it's hidden */ - if( (dpnt->dir_flags & INHIBIT_ISO9660_ENTRY) == 0 ) - pathlist[dpnt->path_index] = dpnt; - - if(dpnt->subdir) build_pathlist(dpnt->subdir); - dpnt = dpnt->next; - } -} /* build_pathlist(... */ - -static int FDECL2(compare_paths, void const *, r, void const *, l) -{ - struct directory const *ll = *(struct directory * const *)l; - struct directory const *rr = *(struct directory * const *)r; - - if (rr->parent->path_index < ll->parent->path_index) - { - return -1; - } - - if (rr->parent->path_index > ll->parent->path_index) - { - return 1; - } - - return strcmp(rr->self->isorec.name, ll->self->isorec.name); - -} /* compare_paths(... */ - -static int generate_path_tables() -{ - struct directory_entry * de; - struct directory * dpnt; - int fix; - int i; - int j; - int namelen; - char * npnt; - char * npnt1; - int tablesize; - - /* - * First allocate memory for the tables and initialize the memory - */ - tablesize = path_blocks << 11; - path_table_m = (char *) e_malloc(tablesize); - path_table_l = (char *) e_malloc(tablesize); - memset(path_table_l, 0, tablesize); - memset(path_table_m, 0, tablesize); - - /* - * Now start filling in the path tables. Start with root directory - */ - if( next_path_index > 0xffff ) - { - error (1, 0, _("Unable to generate sane path tables - too many directories (%d)\n"), - next_path_index); - } - - path_table_index = 0; - pathlist = (struct directory **) e_malloc(sizeof(struct directory *) - * next_path_index); - memset(pathlist, 0, sizeof(struct directory *) * next_path_index); - build_pathlist(root); - - do - { - fix = 0; -#ifdef __STDC__ - qsort(&pathlist[1], next_path_index-1, sizeof(struct directory *), - (int (*)(const void *, const void *))compare_paths); -#else - qsort(&pathlist[1], next_path_index-1, sizeof(struct directory *), - compare_paths); -#endif - - for(j=1; jpath_index != j) - { - pathlist[j]->path_index = j; - fix++; - } - } - } while(fix); - - for(j=1; jde_name; - - /* - * So the root comes out OK - */ - if( (*npnt == 0) || (dpnt == root) ) - { - npnt = "."; - } - npnt1 = strrchr(npnt, PATH_SEPARATOR); - if(npnt1) - { - npnt = npnt1 + 1; - } - - de = dpnt->self; - if(!de) - { - error (1, 0, _("Fatal goof\n")); - } - - - namelen = de->isorec.name_len[0]; - - path_table_l[path_table_index] = namelen; - path_table_m[path_table_index] = namelen; - path_table_index += 2; - - set_731(path_table_l + path_table_index, dpnt->extent); - set_732(path_table_m + path_table_index, dpnt->extent); - path_table_index += 4; - - set_721(path_table_l + path_table_index, - dpnt->parent->path_index); - set_722(path_table_m + path_table_index, - dpnt->parent->path_index); - path_table_index += 2; - - for(i =0; iisorec.name[i]; - path_table_m[path_table_index] = de->isorec.name[i]; - path_table_index++; - } - if(path_table_index & 1) - { - path_table_index++; /* For odd lengths we pad */ - } - } - - free(pathlist); - if(path_table_index != path_table_size) - { - fprintf (stderr, _("Path table lengths do not match %d %d\n"), - path_table_index, - path_table_size); - } - return 0; -} /* generate_path_tables(... */ - -void -FDECL3(memcpy_max, char *, to, char *, from, int, max) -{ - int n = strlen(from); - if (n > max) - { - n = max; - } - memcpy(to, from, n); - -} /* memcpy_max(... */ - -void FDECL1(outputlist_insert, struct output_fragment *, frag) -{ - if( out_tail == NULL ) - { - out_list = out_tail = frag; - } - else - { - out_tail->of_next = frag; - out_tail = frag; - } -} - -static int FDECL1(file_write, FILE *, outfile) -{ - int should_write; - - /* - * OK, all done with that crap. Now write out the directories. - * This is where the fur starts to fly, because we need to keep track of - * each file as we find it and keep track of where we put it. - */ - - should_write = last_extent - session_start; - - if( print_size > 0 ) - { - fprintf (stderr, _("Total extents scheduled to be written = %llu\n"), - last_extent - session_start); - exit (0); - } - if( verbose > 2 ) - { -#ifdef DBG_ISO - fprintf(stderr,"Total directory extents being written = %llu\n", last_extent); -#endif - - fprintf (stderr, _("Total extents scheduled to be written = %llu\n"), - last_extent - session_start); - } - - /* - * Now write all of the files that we need. - */ - write_files(outfile); - - /* - * The rest is just fluff. - */ - if( verbose == 0 ) - { - return 0; - } - - fprintf (stderr, _("Total extents actually written = %llu\n"), - last_extent_written - session_start); - - /* - * Hard links throw us off here - */ - assert (last_extent > session_start); - if(should_write + session_start != last_extent) - { - fprintf (stderr, _("Number of extents written different than what was predicted. Please fix.\n")); - fprintf (stderr, _("Predicted = %d, written = %llu\n"), should_write, last_extent); - } - - fprintf (stderr, _("Total translation table size: %d\n"), table_size); - fprintf (stderr, _("Total rockridge attributes bytes: %d\n"), rockridge_size); - fprintf (stderr, _("Total directory bytes: %d\n"), total_dir_size); - fprintf (stderr, _("Path table size(bytes): %d\n"), path_table_size); - -#ifdef DEBUG - fprintf(stderr, "next extent, last_extent, last_extent_written %d %d %d\n", - next_extent, last_extent, last_extent_written); -#endif - - return 0; - -} /* iso_write(... */ - -char *creation_date = NULL; -char *modification_date = NULL; -char *expiration_date = NULL; -char *effective_date = NULL; - -/* - * Function to write the PVD for the disc. - */ -static int FDECL1(pvd_write, FILE *, outfile) -{ - char iso_time[17]; - int should_write; - struct tm local; - struct tm gmt; - - - time(&begun); - - local = *localtime(&begun); - gmt = *gmtime(&begun); - - /* - * This will break in the year 2000, I supose, but there is no good way - * to get the top two digits of the year. - */ - sprintf(iso_time, "%4.4d%2.2d%2.2d%2.2d%2.2d%2.2d00", 1900 + local.tm_year, - local.tm_mon+1, local.tm_mday, - local.tm_hour, local.tm_min, local.tm_sec); - - local.tm_min -= gmt.tm_min; - local.tm_hour -= gmt.tm_hour; - local.tm_yday -= gmt.tm_yday; - iso_time[16] = (local.tm_min + 60*(local.tm_hour + 24*local.tm_yday)) / 15; - - /* - * Next we write out the primary descriptor for the disc - */ - memset(&vol_desc, 0, sizeof(vol_desc)); - vol_desc.type[0] = ISO_VD_PRIMARY; - memcpy(vol_desc.id, ISO_STANDARD_ID, sizeof(ISO_STANDARD_ID)); - vol_desc.version[0] = 1; - - memset(vol_desc.system_id, ' ', sizeof(vol_desc.system_id)); - memcpy_max(vol_desc.system_id, system_id, strlen(system_id)); - - memset(vol_desc.volume_id, ' ', sizeof(vol_desc.volume_id)); - memcpy_max(vol_desc.volume_id, volume_id, strlen(volume_id)); - - should_write = last_extent - session_start; - set_733((char *) vol_desc.volume_space_size, should_write); - set_723(vol_desc.volume_set_size, volume_set_size); - set_723(vol_desc.volume_sequence_number, volume_sequence_number); - set_723(vol_desc.logical_block_size, 2048); - - /* - * The path tables are used by DOS based machines to cache directory - * locations - */ - - set_733((char *) vol_desc.path_table_size, path_table_size); - set_731(vol_desc.type_l_path_table, path_table[0]); - set_731(vol_desc.opt_type_l_path_table, path_table[1]); - set_732(vol_desc.type_m_path_table, path_table[2]); - set_732(vol_desc.opt_type_m_path_table, path_table[3]); - - /* - * Now we copy the actual root directory record - */ - memcpy(vol_desc.root_directory_record, &root_record, - sizeof(struct iso_directory_record) + 1); - - /* - * The rest is just fluff. It looks nice to fill in many of these fields, - * though. - */ - FILL_SPACE(volume_set_id); - if(volset_id) memcpy_max(vol_desc.volume_set_id, volset_id, strlen(volset_id)); - - FILL_SPACE(publisher_id); - if(publisher) memcpy_max(vol_desc.publisher_id, publisher, strlen(publisher)); - - FILL_SPACE(preparer_id); - if(preparer) memcpy_max(vol_desc.preparer_id, preparer, strlen(preparer)); - - FILL_SPACE(application_id); - if(appid) memcpy_max(vol_desc.application_id, appid, strlen(appid)); - - FILL_SPACE(copyright_file_id); - if(copyright) memcpy_max(vol_desc.copyright_file_id, copyright, - strlen(copyright)); - - FILL_SPACE(abstract_file_id); - if(abstract) memcpy_max(vol_desc.abstract_file_id, abstract, - strlen(abstract)); - - FILL_SPACE(bibliographic_file_id); - if(biblio) memcpy_max(vol_desc.bibliographic_file_id, biblio, - strlen(biblio)); - - FILL_SPACE(creation_date); - FILL_SPACE(modification_date); - FILL_SPACE(expiration_date); - FILL_SPACE(effective_date); - vol_desc.file_structure_version[0] = 1; - FILL_SPACE(application_data); - - memcpy(vol_desc.creation_date, creation_date ? creation_date : iso_time, 17); - memcpy(vol_desc.modification_date, modification_date ? modification_date : iso_time, 17); - memcpy(vol_desc.expiration_date, expiration_date ? expiration_date : "0000000000000000", 17); - memcpy(vol_desc.effective_date, effective_date ? effective_date : iso_time, 17); - - /* - * if not a bootable cd do it the old way - */ - xfwrite(&vol_desc, 1, 2048, outfile); - last_extent_written++; - return 0; -} - -/* - * Function to write the EVD for the disc. - */ -static int FDECL1(evd_write, FILE *, outfile) -{ - struct iso_primary_descriptor evol_desc; - - /* - * Now write the end volume descriptor. Much simpler than the other one - */ - memset(&evol_desc, 0, sizeof(evol_desc)); - evol_desc.type[0] = ISO_VD_END; - memcpy(evol_desc.id, ISO_STANDARD_ID, sizeof(ISO_STANDARD_ID)); - evol_desc.version[0] = 1; - xfwrite(&evol_desc, 1, 2048, outfile); - last_extent_written += 1; - return 0; -} - -/* - * Function to write the EVD for the disc. - */ -static int FDECL1(pathtab_write, FILE *, outfile) -{ - /* - * Next we write the path tables - */ - xfwrite(path_table_l, 1, path_blocks << 11, outfile); - xfwrite(path_table_m, 1, path_blocks << 11, outfile); - last_extent_written += 2*path_blocks; - free(path_table_l); - free(path_table_m); - path_table_l = NULL; - path_table_m = NULL; - return 0; -} - -static int FDECL1(exten_write, FILE *, outfile) -{ - xfwrite(extension_record, 1, SECTOR_SIZE, outfile); - last_extent_written++; - return 0; -} - -/* - * Functions to describe padding block at the start of the disc. - */ -int FDECL1(oneblock_size, int, starting_extent) -{ - last_extent++; - return 0; -} - -/* - * Functions to describe padding block at the start of the disc. - */ - -#define PADBLOCK_SIZE 16 - -static int FDECL1(pathtab_size, int, starting_extent) -{ - path_table[0] = starting_extent; - - path_table[1] = 0; - path_table[2] = path_table[0] + path_blocks; - path_table[3] = 0; - last_extent += 2*path_blocks; - return 0; -} - -static int FDECL1(padblock_size, int, starting_extent) -{ - last_extent += PADBLOCK_SIZE; - return 0; -} - -static int file_gen() -{ - assign_file_addresses(root); - return 0; -} - -static int dirtree_dump() -{ - if (verbose > 2) - { - dump_tree(root); - } - return 0; -} - -static int FDECL1(dirtree_fixup, int, starting_extent) -{ - if (use_RockRidge && reloc_dir) - finish_cl_pl_entries(); - - if (use_RockRidge ) - update_nlink_field(root); - return 0; -} - -static int FDECL1(dirtree_size, int, starting_extent) -{ - assign_directory_addresses(root); - return 0; -} - -static int FDECL1(ext_size, int, starting_extent) -{ - extern int extension_record_size; - struct directory_entry * s_entry; - extension_record_extent = starting_extent; - s_entry = root->contents; - set_733((char *) s_entry->rr_attributes + s_entry->rr_attr_size - 24, - extension_record_extent); - set_733((char *) s_entry->rr_attributes + s_entry->rr_attr_size - 8, - extension_record_size); - last_extent++; - return 0; -} - -static int FDECL1(dirtree_write, FILE *, outfile) -{ - generate_iso9660_directories(root, outfile); - return 0; -} - -static int FDECL1(dirtree_cleanup, FILE *, outfile) -{ - free_directories(root); - return 0; -} - -static int FDECL1(padblock_write, FILE *, outfile) -{ - char *buffer; - - buffer = e_malloc (2048 * PADBLOCK_SIZE); - memset (buffer, 0, 2048 * PADBLOCK_SIZE); - - if (use_embedded_boot) - { - FILE *fp = fopen (boot_image_embed, "rb"); - if (! fp) - error (1, errno, _("Unable to open %s"), boot_image_embed); - - if (fread (buffer, 1, 2048 * PADBLOCK_SIZE, fp) == 0) - error (1, errno, _("cannot read %d bytes from %s"), - 2048 * PADBLOCK_SIZE, boot_image_embed); - if (fgetc (fp) != EOF) - error (1, 0, _("%s is too big for embed area"), boot_image_embed); - } - - if (use_protective_msdos_label) - { - struct msdos_partition_mbr *mbr = (void *) buffer; - - memset (mbr->entries, 0, sizeof(mbr->entries)); - - /* Some idiotic BIOSes refuse to boot if they don't find at least - one partition with active bit set. */ - mbr->entries[0].flag = 0x80; - - /* Doesn't really matter, as long as it's non-zero. It seems that - 0xCD is used elsewhere, so we follow suit. */ - mbr->entries[0].type = 0xcd; - - /* Start immediately (sector 1). */ - mbr->entries[0].start = 1; - - /* We don't know yet. Let's keep it safe. */ - mbr->entries[0].length = UINT32_MAX; - - mbr->signature = MSDOS_PARTITION_SIGNATURE; - } - - xfwrite (buffer, 1, 2048 * PADBLOCK_SIZE, outfile); - last_extent_written += PADBLOCK_SIZE; - - return 0; -} - -struct output_fragment padblock_desc = {NULL, padblock_size, NULL, padblock_write}; -struct output_fragment voldesc_desc = {NULL, oneblock_size, root_gen, pvd_write}; -struct output_fragment end_vol = {NULL, oneblock_size, NULL, evd_write}; -struct output_fragment pathtable_desc = {NULL, pathtab_size, generate_path_tables, pathtab_write}; -struct output_fragment dirtree_desc = {NULL, dirtree_size, NULL, dirtree_write}; -struct output_fragment dirtree_clean = {NULL, dirtree_fixup, dirtree_dump, dirtree_cleanup}; -struct output_fragment extension_desc = {NULL, ext_size, NULL, exten_write}; -struct output_fragment files_desc = {NULL, NULL, file_gen, file_write}; From 7fb5c25fd0f02c1b751821915da5d3036f5a5692 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 18 May 2010 11:51:37 +0100 Subject: [PATCH 651/738] * util/grub-mkrescue.in: Sync up with grub-install in terms of how we handle finding grub-mkimage. Default to finding grub-mkimage in ${bindir} with program_transform_name applied, and provide a --grub-mkimage option to override this. --- ChangeLog | 7 +++++++ util/grub-mkrescue.in | 16 ++++++++++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8258400c0..4cfe4c576 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-05-18 Colin Watson + + * util/grub-mkrescue.in: Sync up with grub-install in terms of how + we handle finding grub-mkimage. Default to finding grub-mkimage in + ${bindir} with program_transform_name applied, and provide a + --grub-mkimage option to override this. + 2010-05-17 Vladimir Serbinenko Remove grub-mkisofs. diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in index 5f35f084a..6018816b3 100644 --- a/util/grub-mkrescue.in +++ b/util/grub-mkrescue.in @@ -37,6 +37,7 @@ pc_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/i386-pc efi32_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/i386-efi efi64_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/x86_64-efi rom_directory= +grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}` # Usage: usage # Print the usage. @@ -50,6 +51,7 @@ Make GRUB rescue image. --output=FILE save output in FILE [required] --modules=MODULES pre-load specified modules MODULES --rom-directory=DIR save rom images in DIR [optional] + --grub-mkimage=FILE use FILE as grub-mkimage $0 generates a bootable rescue image with specified source files or directories. @@ -78,6 +80,8 @@ for option in "$@"; do PATH=${override_dir}:$PATH export PATH ;; + --grub-mkimage=*) + grub_mkimage=`echo "$option" | sed 's/--grub-mkimage=//'` ;; -*) echo "Unrecognized option \`$option'" 1>&2 usage @@ -94,6 +98,14 @@ if [ "x${output_image}" = x ] ; then exit 1 fi +set $grub_mkimage dummy +if test -f "$1"; then + : +else + echo "$1: Not found." 1>&2 + exit 1 +fi + if test "x$TMP" != x; then MKTEMP_TEMPLATE="$TMP/grub-mkrescue.XXXXXXXXXX" elif test "x$TEMP" != x; then @@ -157,7 +169,7 @@ EOF tar -C ${memdisk_dir} -cf ${memdisk_img} boot rm -rf ${memdisk_dir} - grub-mkimage -O ${platform} -d "${source_directory}" -m "${memdisk_img}" -o "$3" --prefix='(memdisk)/boot/grub' \ + $grub_mkimage -O ${platform} -d "${source_directory}" -m "${memdisk_img}" -o "$3" --prefix='(memdisk)/boot/grub' \ search iso9660 configfile normal sh memdisk tar $4 rm -rf ${memdisk_img} } @@ -207,7 +219,7 @@ grub_mkisofs_arguments="${grub_mkisofs_arguments} --modification-date=$(echo ${i if test -e "${pc_dir}" ; then echo "Enabling BIOS support ..." core_img=`mktemp "$MKTEMP_TEMPLATE"` - grub-mkimage -O i386-pc -d ${pc_dir}/ -O i386-pc -o ${core_img} --prefix=/boot/grub/i386-pc \ + $grub_mkimage -O i386-pc -d ${pc_dir}/ -O i386-pc -o ${core_img} --prefix=/boot/grub/i386-pc \ iso9660 biosdisk cat ${pc_dir}/cdboot.img ${core_img} > ${iso9660_dir}/boot/grub/i386-pc/eltorito.img From 355b51e9b50174de0254bc97ec7008f70b21855c Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 18 May 2010 11:57:31 +0100 Subject: [PATCH 652/738] Fix build with non-GNU libcs. * util/misc.c (canonicalize_file_name): Move to ... * kern/emu/misc.c (canonicalize_file_name): ... here. Needed by grub_make_system_path_relative_to_its_root. --- ChangeLog | 8 ++++++++ kern/emu/misc.c | 13 +++++++++++++ util/misc.c | 13 ------------- 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4cfe4c576..a3050ee07 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2010-05-18 Colin Watson + + Fix build with non-GNU libcs. + + * util/misc.c (canonicalize_file_name): Move to ... + * kern/emu/misc.c (canonicalize_file_name): ... here. Needed by + grub_make_system_path_relative_to_its_root. + 2010-05-18 Colin Watson * util/grub-mkrescue.in: Sync up with grub-install in terms of how diff --git a/kern/emu/misc.c b/kern/emu/misc.c index 4888f4a6b..54c808a47 100644 --- a/kern/emu/misc.c +++ b/kern/emu/misc.c @@ -176,6 +176,19 @@ grub_get_rtc (void) * GRUB_TICKS_PER_SECOND / 1000000)); } +char * +canonicalize_file_name (const char *path) +{ + char *ret; +#ifdef PATH_MAX + ret = xmalloc (PATH_MAX); + (void) realpath (path, ret); +#else + ret = realpath (path, NULL); +#endif + return ret; +} + #ifdef __CYGWIN__ /* Convert POSIX path to Win32 path, remove drive letter, replace backslashes. */ diff --git a/util/misc.c b/util/misc.c index 6785eb00f..46e5c6093 100644 --- a/util/misc.c +++ b/util/misc.c @@ -286,19 +286,6 @@ fail: #endif /* __MINGW32__ */ -char * -canonicalize_file_name (const char *path) -{ - char *ret; -#ifdef PATH_MAX - ret = xmalloc (PATH_MAX); - (void) realpath (path, ret); -#else - ret = realpath (path, NULL); -#endif - return ret; -} - #ifdef GRUB_UTIL void grub_util_init_nls (void) From 750067477388b5f74bb3cfd343cb0cfe74de26e0 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 18 May 2010 14:20:00 +0200 Subject: [PATCH 653/738] * po/POTFILES: Rename util/grub-mkrawimage.c to util/grub-mkimage.c. --- ChangeLog | 4 ++++ po/POTFILES | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 89526d020..bf375bc64 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-05-18 Vladimir Serbinenko + + * po/POTFILES: Rename util/grub-mkrawimage.c to util/grub-mkimage.c. + 2010-05-18 Colin Watson * configure.ac: Check for Linux device-mapper support. diff --git a/po/POTFILES b/po/POTFILES index 0dfc3c041..d2c579edb 100644 --- a/po/POTFILES +++ b/po/POTFILES @@ -77,5 +77,5 @@ normal/misc.c term/serial.c -util/grub-mkrawimage.c +util/grub-mkimage.c util/i386/pc/grub-setup.c From 26966aeba7259cf38d1ede192c7b34f258d470c2 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 18 May 2010 14:21:15 +0200 Subject: [PATCH 654/738] 2010-05-18 Vladimir Serbinenko * util/grub-mkrescue.in: Remove -O i386-pc duplication. Reported by: Seth Goldberg. --- ChangeLog | 5 +++++ util/grub-mkrescue.in | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index bf375bc64..8e864dddb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-05-18 Vladimir Serbinenko + + * util/grub-mkrescue.in: Remove -O i386-pc duplication. + Reported by: Seth Goldberg. + 2010-05-18 Vladimir Serbinenko * po/POTFILES: Rename util/grub-mkrawimage.c to util/grub-mkimage.c. diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in index 6018816b3..7e7253006 100644 --- a/util/grub-mkrescue.in +++ b/util/grub-mkrescue.in @@ -219,7 +219,7 @@ grub_mkisofs_arguments="${grub_mkisofs_arguments} --modification-date=$(echo ${i if test -e "${pc_dir}" ; then echo "Enabling BIOS support ..." core_img=`mktemp "$MKTEMP_TEMPLATE"` - $grub_mkimage -O i386-pc -d ${pc_dir}/ -O i386-pc -o ${core_img} --prefix=/boot/grub/i386-pc \ + $grub_mkimage -O i386-pc -d ${pc_dir}/ -o ${core_img} --prefix=/boot/grub/i386-pc \ iso9660 biosdisk cat ${pc_dir}/cdboot.img ${core_img} > ${iso9660_dir}/boot/grub/i386-pc/eltorito.img From 654e1d1e0e0943348b4283e14a9f03607ee4df56 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 18 May 2010 13:45:25 +0200 Subject: [PATCH 655/738] * util/grub-install.in: Add missing "in" keyword. --- ChangeLog | 4 ++++ util/grub-install.in | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 8e864dddb..34e7b76dd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-05-18 Vladimir Serbinenko + + * util/grub-install.in: Add missing "in" keyword. + 2010-05-18 Vladimir Serbinenko * util/grub-mkrescue.in: Remove -O i386-pc duplication. diff --git a/util/grub-install.in b/util/grub-install.in index 8a93ace8c..0db216fd5 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -342,7 +342,7 @@ else prefix_drive=`$grub_probe --target=drive --device ${grub_device}` || exit 1 fi -case "${target_cpu}-${platform}" +case "${target_cpu}-${platform}" in i386-pc) mkimage_target=i386-pc ;; sparc64-ieee1275) mkimage_target=sparc64-ieee1275-raw ;; mips-yeeloong) mkimage_target=mipsel-yeeloong-elf ;; From 01b8d2d7870c81d9e6151b3d2f3a936633db296d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 18 May 2010 13:55:26 +0200 Subject: [PATCH 656/738] * Makefile.in (CPPFLAGS): Replace -DGRUB_LIBDIR with -DGRUB_PKGLIBROOTDIR= and prepend @PACKAGE_TARNAME@. All users updated. * util/grub-mkimage.c (image_targets): Add i386-multiboot. (main): Add a slash after pkglibdirroot. --- ChangeLog | 7 +++++++ Makefile.in | 2 +- util/grub-mkimage.c | 36 ++++++++++++++++++++++++++++++------ 3 files changed, 38 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 34e7b76dd..2ce1c23e3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-05-18 Vladimir Serbinenko + + * Makefile.in (CPPFLAGS): Replace -DGRUB_LIBDIR with + -DGRUB_PKGLIBROOTDIR= and prepend @PACKAGE_TARNAME@. All users updated. + * util/grub-mkimage.c (image_targets): Add i386-multiboot. + (main): Add a slash after pkglibdirroot. + 2010-05-18 Vladimir Serbinenko * util/grub-install.in: Add missing "in" keyword. diff --git a/Makefile.in b/Makefile.in index 26a494518..75388e3c8 100644 --- a/Makefile.in +++ b/Makefile.in @@ -90,7 +90,7 @@ GNULIB_CFLAGS = $(GNULIB_UTIL_CFLAGS) $(POSIX_CFLAGS) ASFLAGS = @ASFLAGS@ LDFLAGS = @LDFLAGS@ $(LIBS) CPPFLAGS = @CPPFLAGS@ -I$(builddir) -I$(builddir)/include -I$(srcdir)/gnulib -I$(srcdir)/include -Wall -W \ - -DGRUB_LIBDIR=\"$(libdir)\" -DLOCALEDIR=\"$(localedir)\" + -DGRUB_PKGLIBROOTDIR=\"$(libdir)/`echo @PACKAGE_TARNAME@ | sed '$(transform)'`\" -DLOCALEDIR=\"$(localedir)\" TARGET_CC = @TARGET_CC@ TARGET_CFLAGS = -ffreestanding @TARGET_CFLAGS@ TARGET_ASFLAGS = -nostdinc -fno-builtin @TARGET_ASFLAGS@ diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index cc4a225d4..6366a9803 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -99,6 +99,28 @@ struct image_target_desc image_targets[] = .mod_gap = GRUB_KERNEL_I386_COREBOOT_MOD_GAP, .mod_align = GRUB_KERNEL_I386_COREBOOT_MOD_ALIGN }, + { + .name = "i386-multiboot", + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_COREBOOT, + .flags = PLATFORM_FLAGS_NONE, + .prefix = GRUB_KERNEL_I386_COREBOOT_PREFIX, + .data_end = GRUB_KERNEL_I386_COREBOOT_DATA_END, + .raw_size = 0, + .total_module_size = TARGET_NO_FIELD, + .kernel_image_size = TARGET_NO_FIELD, + .compressed_size = TARGET_NO_FIELD, + .section_align = 1, + .vaddr_offset = 0, + .install_dos_part = TARGET_NO_FIELD, + .install_bsd_part = TARGET_NO_FIELD, + .link_addr = GRUB_KERNEL_I386_COREBOOT_LINK_ADDR, + .elf_target = EM_386, + .link_align = 4, + .mod_gap = GRUB_KERNEL_I386_COREBOOT_MOD_GAP, + .mod_align = GRUB_KERNEL_I386_COREBOOT_MOD_ALIGN + }, { .name = "i386-pc", .voidp_sizeof = 4, @@ -1182,7 +1204,7 @@ Make a bootable image of GRUB.\n\ \n\ Report bugs to <%s>.\n\ "), - program_name, GRUB_LIBDIR, DEFAULT_DIRECTORY, + program_name, GRUB_PKGLIBROOTDIR, DEFAULT_DIRECTORY, formats, PACKAGE_BUGREPORT); free (formats); @@ -1320,14 +1342,16 @@ main (int argc, char *argv[]) last = strchr (last + 1, '-'); if (!last) last = image_target->name + strlen (image_target->name); - dir = xmalloc (sizeof (GRUB_LIBDIR) + (last - image_target->name)); - memcpy (dir, GRUB_LIBDIR, sizeof (GRUB_LIBDIR) - 1); - memcpy (dir + sizeof (GRUB_LIBDIR) - 1, image_target->name, + dir = xmalloc (sizeof (GRUB_PKGLIBROOTDIR) + (last - image_target->name) + + 1); + memcpy (dir, GRUB_PKGLIBROOTDIR, sizeof (GRUB_PKGLIBROOTDIR) - 1); + *(dir + sizeof (GRUB_PKGLIBROOTDIR) - 1) = '/'; + memcpy (dir + sizeof (GRUB_PKGLIBROOTDIR), image_target->name, last - image_target->name); - *(dir + sizeof (GRUB_LIBDIR) - 1 + (last - image_target->name)) = 0; + *(dir + sizeof (GRUB_PKGLIBROOTDIR) + (last - image_target->name)) = 0; } - generate_image (dir ? : GRUB_LIBDIR, prefix ? : DEFAULT_DIRECTORY, fp, + generate_image (dir, prefix ? : DEFAULT_DIRECTORY, fp, argv + optind, memdisk, font, config, image_target, note); From 95b97950e274dc18c16003cd9d5f552c989156a3 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Tue, 18 May 2010 14:00:51 +0200 Subject: [PATCH 657/738] * include/grub/i18n.h (gettext): Inline instead of using #define. (grub_gettext): Likewise. (_): Likewise. --- ChangeLog | 6 ++++++ include/grub/i18n.h | 24 ++++++++++++++++++++---- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2ce1c23e3..4e0f35c1d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-05-18 Vladimir Serbinenko + + * include/grub/i18n.h (gettext): Inline instead of using #define. + (grub_gettext): Likewise. + (_): Likewise. + 2010-05-18 Vladimir Serbinenko * Makefile.in (CPPFLAGS): Replace -DGRUB_LIBDIR with diff --git a/include/grub/i18n.h b/include/grub/i18n.h index 9e7f52d45..57ca1c45b 100644 --- a/include/grub/i18n.h +++ b/include/grub/i18n.h @@ -42,17 +42,33 @@ extern const char *(*EXPORT_VAR(grub_gettext)) (const char *s); On pre-ANSI systems without 'const', the config.h file is supposed to contain "#define const". */ # ifdef GRUB_UTIL -# define gettext(Msgid) ((const char *) (Msgid)) +static inline const char * __attribute__ ((always_inline)) +gettext (const char *str) +{ + return str; +} # else -# define grub_gettext(str) ((const char *) (str)) +static inline const char * __attribute__ ((always_inline)) +grub_gettext (const char *str) +{ + return str; +} # endif /* GRUB_UTIL */ #endif /* (defined(ENABLE_NLS) && ENABLE_NLS) */ #ifdef GRUB_UTIL -# define _(str) gettext(str) +static inline const char * __attribute__ ((always_inline)) +_ (const char *str) +{ + return gettext(str); +} #else -# define _(str) grub_gettext(str) +static inline const char * __attribute__ ((always_inline)) +_ (const char *str) +{ + return grub_gettext(str); +} #endif /* GRUB_UTIL */ #define N_(str) str From 4db50964ad0e96ce4bae73d589160a4b9bd0bd44 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 18 May 2010 13:01:59 +0100 Subject: [PATCH 658/738] Add btrfs probing support, currently only in the single-device case. * kern/emu/getroot.c (find_root_device_from_mountinfo): New function. (grub_guess_root_device): Call find_root_device_from_mountinfo before looking in /dev. --- ChangeLog.btrfs-probe | 8 +++++ kern/emu/getroot.c | 84 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+) create mode 100644 ChangeLog.btrfs-probe diff --git a/ChangeLog.btrfs-probe b/ChangeLog.btrfs-probe new file mode 100644 index 000000000..77c9995c8 --- /dev/null +++ b/ChangeLog.btrfs-probe @@ -0,0 +1,8 @@ +2010-05-18 Colin Watson + + Add btrfs probing support, currently only in the single-device case. + + * kern/emu/getroot.c (find_root_device_from_mountinfo): New + function. + (grub_guess_root_device): Call find_root_device_from_mountinfo + before looking in /dev. diff --git a/kern/emu/getroot.c b/kern/emu/getroot.c index 6875044da..da62089fa 100644 --- a/kern/emu/getroot.c +++ b/kern/emu/getroot.c @@ -80,6 +80,84 @@ xgetcwd (void) return path; } +#ifdef __linux__ + +/* Statting something on a btrfs filesystem always returns a virtual device + major/minor pair rather than the real underlying device, because btrfs + can span multiple underlying devices (and even if it's currently only + using a single device it can be dynamically extended onto another). We + can't deal with the multiple-device case yet, but in the meantime, we can + at least cope with the single-device case by scanning + /proc/self/mountinfo. */ +static char * +find_root_device_from_mountinfo (const char *dir) +{ + FILE *fp; + char buf[1024]; /* XXX */ + char *ret = NULL; + + fp = fopen ("/proc/self/mountinfo", "r"); + if (! fp) + return NULL; /* fall through to other methods */ + + while (fgets (buf, sizeof (buf), fp)) + { + int mnt_id, parent_mnt_id; + unsigned int major, minor; + char enc_root[PATH_MAX], enc_path[PATH_MAX]; + int count; + size_t enc_path_len; + const char *sep; + char fstype[PATH_MAX], device[PATH_MAX]; + struct stat st; + + if (sscanf (buf, "%d %d %u:%u %s %s%n", + &mnt_id, &parent_mnt_id, &major, &minor, enc_root, enc_path, + &count) < 6) + continue; + + if (strcmp (enc_root, "/") != 0) + continue; /* only a subtree is mounted */ + + enc_path_len = strlen (enc_path); + if (strncmp (dir, enc_path, enc_path_len) != 0 || + (dir[enc_path_len] && dir[enc_path_len] != '/')) + continue; + + /* This is a parent of the requested directory. /proc/self/mountinfo + is in mount order, so it must be the closest parent we've + encountered so far. If it's virtual, return its device node; + otherwise, carry on to try to find something closer. */ + + free (ret); + ret = NULL; + + if (major != 0) + continue; /* not a virtual device */ + + sep = strstr (buf + count, " - "); + if (!sep) + continue; + + sep += strlen (" - "); + if (sscanf (sep, "%s %s", fstype, device) != 2) + continue; + + if (stat (device, &st) < 0) + continue; + + if (!S_ISBLK (st.st_mode)) + continue; /* not a block device */ + + ret = strdup (device); + } + + fclose (fp); + return ret; +} + +#endif /* __linux__ */ + #ifdef __MINGW32__ static char * @@ -355,6 +433,12 @@ grub_guess_root_device (const char *dir) #else /* !__GNU__ */ struct stat st; +#ifdef __linux__ + os_dev = find_root_device_from_mountinfo (dir); + if (os_dev) + return os_dev; +#endif /* __linux__ */ + if (stat (dir, &st) < 0) grub_util_error ("cannot stat `%s'", dir); From c4f7b5235917d65f43310c3e0ae895ebfcc663ca Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Tue, 18 May 2010 20:10:37 +0200 Subject: [PATCH 659/738] 2010-05-18 Justus Winter <4winter@informatik.uni-hamburg.de> * util/grub.d/10_hurd.in: Include all gnumach* kernels, not only gnumach and gnumach.gz. --- ChangeLog | 5 +++++ util/grub.d/10_hurd.in | 39 +++++++++++++++++++++++---------------- 2 files changed, 28 insertions(+), 16 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4e0f35c1d..e8bb242bf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-05-18 Justus Winter <4winter@informatik.uni-hamburg.de> + + * util/grub.d/10_hurd.in: Include all gnumach* kernels, not only + gnumach and gnumach.gz. + 2010-05-18 Vladimir Serbinenko * include/grub/i18n.h (gettext): Inline instead of using #define. diff --git a/util/grub.d/10_hurd.in b/util/grub.d/10_hurd.in index 8e16e7d9f..e446f10e8 100644 --- a/util/grub.d/10_hurd.in +++ b/util/grub.d/10_hurd.in @@ -35,13 +35,13 @@ all_of_them=true # FIXME: add l4 here? kernel= -for i in /boot/gnumach.gz /boot/gnumach ; do +for i in /boot/gnumach* ; do if test -e $i ; then basename=`basename $i` dirname=`dirname $i` rel_dirname=`make_system_path_relative_to_its_root $dirname` echo "Found GNU Mach: $i" >&2 - kernel=${rel_dirname}/${basename} + kernels="${kernels} ${rel_dirname}/${basename}" at_least_one=true fi done @@ -71,17 +71,22 @@ if ${all_of_them} && test -e /lib/ld.so.1 ; then : ; else exit 1 fi -cat << EOF -menuentry "${OS}" ${CLASS} { +for kernel in ${kernels} +do + kernel_base="`basename "${kernel}"`" + KERNEL="using ${kernel_base}" + + cat << EOF +menuentry "${OS} ${KERNEL}" ${CLASS} { EOF -prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/" -cat << EOF + prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/" + cat << EOF echo '$(gettext_quoted "Loading GNU Mach ...")' multiboot ${kernel} root=device:${GRUB_DEVICE#/dev/} EOF -save_default_entry | sed -e "s/^/\t/" -prepare_grub_to_access_device ${GRUB_DEVICE} | sed -e "s/^/\t/" -cat << EOF + save_default_entry | sed -e "s/^/\t/" + prepare_grub_to_access_device ${GRUB_DEVICE} | sed -e "s/^/\t/" + cat << EOF echo '$(gettext_quoted "Loading the Hurd ...")' module /hurd/${hurd_fs}.static ${hurd_fs} --readonly \\ --multiboot-command-line='\${kernel-command-line}' \\ @@ -93,17 +98,17 @@ cat << EOF } EOF -cat << EOF -menuentry "${OS} (recovery mode)" { + cat << EOF +menuentry "${OS} ${KERNEL} (recovery mode)" ${CLASS} { EOF -prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/" -cat << EOF + prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/" + cat << EOF echo '$(gettext_quoted "Loading GNU Mach ...")' multiboot ${kernel} root=device:${GRUB_DEVICE#/dev/} -s EOF -save_default_entry | sed -e "s/^/\t/" -prepare_grub_to_access_device ${GRUB_DEVICE} | sed -e "s/^/\t/" -cat << EOF + save_default_entry | sed -e "s/^/\t/" + prepare_grub_to_access_device ${GRUB_DEVICE} | sed -e "s/^/\t/" + cat << EOF echo '$(gettext_quoted "Loading the Hurd ...")' module /hurd/${hurd_fs}.static ${hurd_fs} \\ --multiboot-command-line='\${kernel-command-line}' \\ @@ -114,3 +119,5 @@ cat << EOF module /lib/ld.so.1 exec /hurd/exec '\$(exec-task=task-create)' } EOF + +done From 74276c0df7489cf122c9cc16109291086483f8f3 Mon Sep 17 00:00:00 2001 From: Christian Franke Date: Tue, 18 May 2010 21:58:49 +0200 Subject: [PATCH 660/738] * util/grub.d/10_windows.in: Use path names instead of drive letters to prevent warning from Cygwin 1.7. Add drivemap command to menuentry if needed. --- ChangeLog | 6 ++++++ util/grub.d/10_windows.in | 21 +++++++++++++++------ 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index e8bb242bf..46d9e7c34 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-05-18 Christian Franke + + * util/grub.d/10_windows.in: Use path names instead of + drive letters to prevent warning from Cygwin 1.7. + Add drivemap command to menuentry if needed. + 2010-05-18 Justus Winter <4winter@informatik.uni-hamburg.de> * util/grub.d/10_hurd.in: Include all gnumach* kernels, not only diff --git a/util/grub.d/10_windows.in b/util/grub.d/10_windows.in index 35dd4a4cc..7d221eac9 100644 --- a/util/grub.d/10_windows.in +++ b/util/grub.d/10_windows.in @@ -1,7 +1,7 @@ #! /bin/sh -e # grub-mkconfig helper script. -# Copyright (C) 2008 Free Software Foundation, Inc. +# Copyright (C) 2008,2009,2010 Free Software Foundation, Inc. # # GRUB is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -28,8 +28,8 @@ esac # Try C: even if current system is on other partition. case "$SYSTEMDRIVE" in - [Cc]:) dirlist="C:" ;; - [D-Zd-z]:) dirlist="C: $SYSTEMDRIVE" ;; + [Cc]:) drives="C:" ;; + [D-Zd-z]:) drives="C: $SYSTEMDRIVE" ;; *) exit 0 ;; esac @@ -51,7 +51,13 @@ get_os_name_from_boot_ini () } -for dir in $dirlist ; do +for drv in $drives ; do + + # Convert to Cygwin path. + dir=`cygpath "$drv"` + test -n "$dir" || continue + + needmap= # Check for Vista bootmgr. if [ -f "$dir"/bootmgr -a -f "$dir"/boot/bcd ] ; then @@ -60,6 +66,7 @@ for dir in $dirlist ; do # Check for NTLDR. elif [ -f "$dir"/ntldr -a -f "$dir"/ntdetect.com -a -f "$dir"/boot.ini ] ; then OS=`get_os_name_from_boot_ini "$dir"/boot.ini` || OS="Windows NT/2000/XP loader" + needmap=t else continue @@ -68,14 +75,16 @@ for dir in $dirlist ; do # Get boot /dev/ice. dev=`${grub_probe} -t device "$dir" 2>/dev/null` || continue - echo "Found $OS on $dir ($dev)" >&2 + echo "Found $OS on $drv ($dev)" >&2 cat << EOF menuentry "$OS" { EOF save_default_entry | sed -e 's,^,\t,' prepare_grub_to_access_device "$dev" | sed 's,^,\t,' - + test -z "$needmap" || cat < Date: Wed, 19 May 2010 14:31:43 +0530 Subject: [PATCH 661/738] Fix grub-mkrescue usage unit testing. * tests/util/grub-shell.in: Use --grub-mkimage with grub-mkrescue. --- ChangeLog | 6 ++++++ tests/util/grub-shell.in | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 46d9e7c34..53a664d2f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-05-19 BVK Chaitanya + + Fix grub-mkrescue usage unit testing. + + * tests/util/grub-shell.in: Use --grub-mkimage with grub-mkrescue. + 2010-05-18 Christian Franke * util/grub.d/10_windows.in: Use path names instead of diff --git a/tests/util/grub-shell.in b/tests/util/grub-shell.in index a41a6f6f4..17da6c8c0 100644 --- a/tests/util/grub-shell.in +++ b/tests/util/grub-shell.in @@ -124,7 +124,8 @@ halt EOF isofile=`mktemp` -grub-mkrescue --output=${isofile} --override-directory=${builddir} \ +grub-mkrescue --grub-mkimage=${builddir}/grub-mkimage --output=${isofile} \ + --override-directory=${builddir} \ /boot/grub/grub.cfg=${cfgfile} /boot/grub/testcase.cfg=${source} \ >/dev/null 2>&1 From fa9d256ee45ed71ab9fc02809a0927d740adca86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Sutre?= Date: Thu, 20 May 2010 02:05:43 +0200 Subject: [PATCH 662/738] Fix merge error in NetBSD code. --- ChangeLog | 6 ++++++ kern/emu/hostdisk.c | 7 ++----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 53a664d2f..1348c91c6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-05-20 Grégoire Sutre + + * kern/emu/hostdisk.c (grub_util_biosdisk_get_grub_dev) [__NetBSD__]: + Fix merge error in NetBSD code. + (find_partition_start) [__NetBSD__]: Likewise. + 2010-05-19 BVK Chaitanya Fix grub-mkrescue usage unit testing. diff --git a/kern/emu/hostdisk.c b/kern/emu/hostdisk.c index 0ab25ec7d..9c4697552 100644 --- a/kern/emu/hostdisk.c +++ b/kern/emu/hostdisk.c @@ -412,7 +412,8 @@ devmapper_fail: fd = open (dev, O_RDONLY); if (fd == -1) { - grub_error (GRUB_ERR_BAD_DEVICE, "cannot open `%s' while attempting to get disk geometry", dev); + grub_error (GRUB_ERR_BAD_DEVICE, + "cannot open `%s' while attempting to get disk geometry", dev); return 0; } @@ -434,9 +435,6 @@ devmapper_fail: # if !defined(__NetBSD__) return hdg.start; # else /* defined(__NetBSD__) */ - /* Since dev and convert_system_partition_to_system_disk (dev) are - * different, we know that dev is of the form /dev/r[wsc]d[0-9]+[a-z] - * and in particular it cannot be a floppy device. */ index = dev[strlen(dev) - 1] - 'a'; if (index >= label.d_npartitions) @@ -1433,7 +1431,6 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) /* Since os_dev and convert_system_partition_to_system_disk (os_dev) are * different, we know that os_dev is of the form /dev/r[wsc]d[0-9]+[a-z] * and in particular it cannot be a floppy device. */ - index = os_dev[strlen(os_dev) - 1] - 'a'; # endif /* !defined(__NetBSD__) */ start = find_partition_start (os_dev); From 96779aec8ee4e7edfcb1a09a279db528f6ae8f5e Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Thu, 20 May 2010 23:16:10 +0100 Subject: [PATCH 663/738] * util/misc.c: Move inclusion of to ... * kern/emu/misc.c: ... here. Needed for canonicalize_file_name. --- ChangeLog | 5 +++++ kern/emu/misc.c | 3 +++ util/misc.c | 3 --- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1348c91c6..42b04d1c9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-05-20 Colin Watson + + * util/misc.c: Move inclusion of to ... + * kern/emu/misc.c: ... here. Needed for canonicalize_file_name. + 2010-05-20 Grégoire Sutre * kern/emu/hostdisk.c (grub_util_biosdisk_get_grub_dev) [__NetBSD__]: diff --git a/kern/emu/misc.c b/kern/emu/misc.c index 54c808a47..a3ccb3076 100644 --- a/kern/emu/misc.c +++ b/kern/emu/misc.c @@ -9,6 +9,9 @@ #include #include #include +#ifdef HAVE_LIMITS_H +#include +#endif #include #include diff --git a/util/misc.c b/util/misc.c index 46e5c6093..91bc25a55 100644 --- a/util/misc.c +++ b/util/misc.c @@ -30,9 +30,6 @@ #include #include #include -#ifdef HAVE_LIMITS_H -#include -#endif #include #include From c0f48e654daf3cc9451c267450ab4b617277baf0 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Thu, 20 May 2010 23:27:15 +0100 Subject: [PATCH 664/738] * util/grub-mkrelpath.c (usage): Remove excess apostrophe. --- ChangeLog | 4 ++++ util/grub-mkrelpath.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 42b04d1c9..cdff463e4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-05-20 Colin Watson + + * util/grub-mkrelpath.c (usage): Remove excess apostrophe. + 2010-05-20 Colin Watson * util/misc.c: Move inclusion of to ... diff --git a/util/grub-mkrelpath.c b/util/grub-mkrelpath.c index e771bd873..eccb49cdc 100644 --- a/util/grub-mkrelpath.c +++ b/util/grub-mkrelpath.c @@ -41,7 +41,7 @@ usage (int status) printf ("\ Usage: %s [OPTIONS] PATH\n\ \n\ -Make a system path relative to it's root.\n\ +Make a system path relative to its root.\n\ \n\ Options:\n\ -h, --help display this message and exit\n\ From 21717c8fcaa20b66568b90a296c86b99626b034b Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 21 May 2010 14:17:15 +0100 Subject: [PATCH 665/738] * util/grub-mkconfig.in: Fix handling of -o so that it works when not the first option. --- ChangeLog | 5 +++++ util/grub-mkconfig.in | 14 ++++++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index cdff463e4..02503a90f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-05-21 Colin Watson + + * util/grub-mkconfig.in: Fix handling of -o so that it works when + not the first option. + 2010-05-20 Colin Watson * util/grub-mkrelpath.c (usage): Remove excess apostrophe. diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in index 85212f8fc..d1abfa36a 100644 --- a/util/grub-mkconfig.in +++ b/util/grub-mkconfig.in @@ -50,7 +50,13 @@ EOF } # Check the arguments. +next_grub_cfg=false for option in "$@"; do + if $next_grub_cfg; then + grub_cfg=$option + next_grub_cfg=false + continue + fi case "$option" in -h | --help) usage @@ -59,8 +65,7 @@ for option in "$@"; do echo "$0 (GNU GRUB ${package_version})" exit 0 ;; -o) - shift - grub_cfg=$1 + next_grub_cfg=: ;; --output=*) grub_cfg=`echo "$option" | sed 's/--output=//'` @@ -72,6 +77,11 @@ for option in "$@"; do ;; esac done +if $next_grub_cfg; then + echo "Missing argument to \`-o'" 1>&2 + usage + exit 1 +fi . ${libdir}/grub/grub-mkconfig_lib From 228cfa97caf0a0c907c945bc307f07029439d629 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 21 May 2010 20:08:48 +0200 Subject: [PATCH 666/738] * kern/i386/pc/init.c (make_install_device): Fix a leftover usage of old partition naming style. --- ChangeLog | 5 +++++ kern/i386/pc/init.c | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 02503a90f..090cd645d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-05-21 Vladimir Serbinenko + + * kern/i386/pc/init.c (make_install_device): Fix a leftover usage of old + partition naming style. + 2010-05-21 Colin Watson * util/grub-mkconfig.in: Fix handling of -o so that it works when diff --git a/kern/i386/pc/init.c b/kern/i386/pc/init.c index fa646df19..d81b1e117 100644 --- a/kern/i386/pc/init.c +++ b/kern/i386/pc/init.c @@ -75,8 +75,8 @@ make_install_device (void) ptr += grub_strlen (ptr); if (grub_install_bsd_part >= 0) - grub_snprintf (ptr, sizeof (dev) - (ptr - dev), ",%c", - grub_install_bsd_part + 'a'); + grub_snprintf (ptr, sizeof (dev) - (ptr - dev), ",%u", + grub_install_bsd_part + 1); ptr += grub_strlen (ptr); } From 39fbb79aa15e66e4516588bb2f74c1052218d8e6 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 21 May 2010 20:12:41 +0200 Subject: [PATCH 667/738] * include/grub/i18n.h: Always enable grub_gettext. --- ChangeLog | 4 ++++ include/grub/i18n.h | 14 +++----------- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index 090cd645d..081ea4a1d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-05-21 Vladimir Serbinenko + + * include/grub/i18n.h: Always enable grub_gettext. + 2010-05-21 Vladimir Serbinenko * kern/i386/pc/init.c (make_install_device): Fix a leftover usage of old diff --git a/include/grub/i18n.h b/include/grub/i18n.h index 57ca1c45b..a91d73346 100644 --- a/include/grub/i18n.h +++ b/include/grub/i18n.h @@ -22,10 +22,10 @@ #include #include -extern const char *(*EXPORT_VAR(grub_gettext)) (const char *s); - /* NLS can be disabled through the configure --disable-nls option. */ -#if (defined(ENABLE_NLS) && ENABLE_NLS) +#if (defined(ENABLE_NLS) && ENABLE_NLS) || !defined (GRUB_UTIL) + +extern const char *(*EXPORT_VAR(grub_gettext)) (const char *s); # ifdef GRUB_UTIL @@ -41,19 +41,11 @@ extern const char *(*EXPORT_VAR(grub_gettext)) (const char *s); for invalid uses of the value returned from these functions. On pre-ANSI systems without 'const', the config.h file is supposed to contain "#define const". */ -# ifdef GRUB_UTIL static inline const char * __attribute__ ((always_inline)) gettext (const char *str) { return str; } -# else -static inline const char * __attribute__ ((always_inline)) -grub_gettext (const char *str) -{ - return str; -} -# endif /* GRUB_UTIL */ #endif /* (defined(ENABLE_NLS) && ENABLE_NLS) */ From 9a25f885d3f9aaa8b4725e5fb3fbc4d410b0c39f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 21 May 2010 20:22:29 +0200 Subject: [PATCH 668/738] * kern/i386/pc/mmap.c (grub_machine_mmap_iterate): Zero-fill entry before calling BIOS. --- ChangeLog | 5 +++++ kern/i386/pc/mmap.c | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/ChangeLog b/ChangeLog index 081ea4a1d..02d16e835 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-05-21 Vladimir Serbinenko + + * kern/i386/pc/mmap.c (grub_machine_mmap_iterate): Zero-fill entry + before calling BIOS. + 2010-05-21 Vladimir Serbinenko * include/grub/i18n.h: Always enable grub_gettext. diff --git a/kern/i386/pc/mmap.c b/kern/i386/pc/mmap.c index 52d8fd597..72a6b3539 100644 --- a/kern/i386/pc/mmap.c +++ b/kern/i386/pc/mmap.c @@ -20,6 +20,7 @@ #include #include #include +#include grub_err_t grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t)) @@ -28,6 +29,8 @@ grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uin struct grub_machine_mmap_entry *entry = (struct grub_machine_mmap_entry *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR; + grub_memset (entry, 0, sizeof (entry)); + /* Check if grub_get_mmap_entry works. */ cont = grub_get_mmap_entry (entry, 0); @@ -43,6 +46,8 @@ grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uin if (! cont) break; + grub_memset (entry, 0, sizeof (entry)); + cont = grub_get_mmap_entry (entry, cont); } while (entry->size); From 5f2316c1fe5ad62c3ae5815c256313041e6a559d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 23 May 2010 13:42:16 +0200 Subject: [PATCH 669/738] * gfxmenu/gfxmenu.c (grub_gfxmenu_try): Change viewport on both buffers. * term/gfxterm.c (real_scroll): Likewise. --- ChangeLog | 5 +++++ gfxmenu/gfxmenu.c | 7 +++++++ term/gfxterm.c | 22 +++++++++++++--------- 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index 02d16e835..cdeee7c2b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-05-23 Vladimir Serbinenko + + * gfxmenu/gfxmenu.c (grub_gfxmenu_try): Change viewport on both buffers. + * term/gfxterm.c (real_scroll): Likewise. + 2010-05-21 Vladimir Serbinenko * kern/i386/pc/mmap.c (grub_machine_mmap_iterate): Zero-fill entry diff --git a/gfxmenu/gfxmenu.c b/gfxmenu/gfxmenu.c index a2e765156..1acab9ca7 100644 --- a/gfxmenu/gfxmenu.c +++ b/gfxmenu/gfxmenu.c @@ -110,6 +110,13 @@ grub_gfxmenu_try (int entry, grub_menu_t menu, int nested) view->nested = nested; view->first_timeout = -1; + grub_video_set_viewport (0, 0, mode_info.width, mode_info.height); + if (view->double_repaint) + { + grub_video_swap_buffers (); + grub_video_set_viewport (0, 0, mode_info.width, mode_info.height); + } + grub_gfxmenu_view_draw (view); instance->data = view; diff --git a/term/gfxterm.c b/term/gfxterm.c index ecfe4ff3b..c57d0f0fa 100644 --- a/term/gfxterm.c +++ b/term/gfxterm.c @@ -707,12 +707,6 @@ real_scroll (void) draw_cursor (0); grub_video_set_active_render_target (render_target); - /* Save viewport and set it to our window. */ - grub_video_get_viewport ((unsigned *) &saved_view.x, - (unsigned *) &saved_view.y, - (unsigned *) &saved_view.width, - (unsigned *) &saved_view.height); - grub_video_set_viewport (window.x, window.y, window.width, window.height); i = window.double_repaint ? 2 : 1; @@ -720,6 +714,15 @@ real_scroll (void) while (i--) { + /* Save viewport and set it to our window. */ + grub_video_get_viewport ((unsigned *) &saved_view.x, + (unsigned *) &saved_view.y, + (unsigned *) &saved_view.width, + (unsigned *) &saved_view.height); + + grub_video_set_viewport (window.x, window.y, window.width, + window.height); + /* Clear new border area. */ grub_video_fill_rect (color, virtual_screen.offset_x, @@ -735,6 +738,10 @@ real_scroll (void) grub_video_scroll (color, 0, -virtual_screen.normal_char_height * virtual_screen.total_scroll); + /* Restore saved viewport. */ + grub_video_set_viewport (saved_view.x, saved_view.y, + saved_view.width, saved_view.height); + if (i) grub_video_swap_buffers (); } @@ -746,9 +753,6 @@ real_scroll (void) grub_video_scroll (color, 0, -virtual_screen.normal_char_height * virtual_screen.total_scroll); - /* Restore saved viewport. */ - grub_video_set_viewport (saved_view.x, saved_view.y, - saved_view.width, saved_view.height); grub_video_set_active_render_target (render_target); } From 3ecb080a33a3cb3e15ca7721c00eeb96d9e8ed3e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 23 May 2010 13:43:38 +0200 Subject: [PATCH 670/738] * gfxmenu/view.c (grub_gfxmenu_draw_terminal_box): Apply only to current buffer since gfxterm handles double repaint. --- ChangeLog | 5 +++++ gfxmenu/view.c | 5 ----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index cdeee7c2b..dbf6f23eb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-05-23 Vladimir Serbinenko + + * gfxmenu/view.c (grub_gfxmenu_draw_terminal_box): Apply only to current + buffer since gfxterm handles double repaint. + 2010-05-23 Vladimir Serbinenko * gfxmenu/gfxmenu.c (grub_gfxmenu_try): Change viewport on both buffers. diff --git a/gfxmenu/view.c b/gfxmenu/view.c index 9a5671cdd..518c3ba53 100644 --- a/gfxmenu/view.c +++ b/gfxmenu/view.c @@ -357,11 +357,6 @@ grub_gfxmenu_draw_terminal_box (void) term_box->draw (term_box, term_rect.x - term_box->get_left_pad (term_box), term_rect.y - term_box->get_top_pad (term_box)); - grub_video_swap_buffers (); - if (term_view->double_repaint) - term_box->draw (term_box, - term_rect.x - term_box->get_left_pad (term_box), - term_rect.y - term_box->get_top_pad (term_box)); } static void From ad603f61a5f61677406aad7b7c041ef21de8957f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 23 May 2010 13:59:50 +0200 Subject: [PATCH 671/738] * gfxmenu/gui_list.c (draw_menu): Don't add scrollbar width to padding. Removed drawing_scrollbar argument. All users updated Fixes #29792. Reported by Jo Shields --- ChangeLog | 7 +++++++ gfxmenu/gui_list.c | 15 ++++----------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index dbf6f23eb..65bd6ad03 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-05-23 Vladimir Serbinenko + + * gfxmenu/gui_list.c (draw_menu): Don't add scrollbar width to padding. + Removed drawing_scrollbar argument. All users updated + Fixes #29792. + Reported by Jo Shields + 2010-05-23 Vladimir Serbinenko * gfxmenu/view.c (grub_gfxmenu_draw_terminal_box): Apply only to current diff --git a/gfxmenu/gui_list.c b/gfxmenu/gui_list.c index 0d771413f..8583a214e 100644 --- a/gfxmenu/gui_list.c +++ b/gfxmenu/gui_list.c @@ -210,8 +210,7 @@ draw_scrollbar (list_impl_t self, /* Draw the list of items. */ static void -draw_menu (list_impl_t self, int width, int drawing_scrollbar, - int num_shown_items) +draw_menu (list_impl_t self, int width, int num_shown_items) { if (! self->menu_box || ! self->selected_item_box) return; @@ -226,8 +225,6 @@ draw_menu (list_impl_t self, int width, int drawing_scrollbar, make_selected_item_visible (self); - int scrollbar_h_space = drawing_scrollbar ? self->scrollbar_width : 0; - grub_gfxmenu_box_t selbox = self->selected_item_box; int sel_leftpad = selbox->get_left_pad (selbox); int item_top = boxpad; @@ -244,12 +241,8 @@ draw_menu (list_impl_t self, int width, int drawing_scrollbar, if (is_selected) { int sel_toppad = selbox->get_top_pad (selbox); - selbox->set_content_size (selbox, - (width - 2 * boxpad - - scrollbar_h_space), - item_height); - selbox->draw (selbox, - item_left - sel_leftpad, + selbox->set_content_size (selbox, (width - 2 * boxpad), item_height); + selbox->draw (selbox, item_left - sel_leftpad, item_top - sel_toppad); } @@ -320,7 +313,7 @@ list_paint (void *vself, const grub_video_rect_t *region) box->draw (box, 0, 0); grub_gui_set_viewport (&content_rect, &vpsave2); - draw_menu (self, content_rect.width, drawing_scrollbar, num_shown_items); + draw_menu (self, content_rect.width, num_shown_items); grub_gui_restore_viewport (&vpsave2); if (drawing_scrollbar) From 76e6d0d767b295f2249b8320a719fe0cd8ea66ff Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 23 May 2010 14:11:11 +0200 Subject: [PATCH 672/738] Add default/grub support --- docs/grub.texi | 16 +++++++++++ util/grub-mkconfig.in | 4 +++ util/grub.d/00_header.in | 57 +++++++++++++++++++++++++++++++--------- 3 files changed, 65 insertions(+), 12 deletions(-) diff --git a/docs/grub.texi b/docs/grub.texi index 704f8b2a3..938fedbaf 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -80,6 +80,7 @@ This edition documents version @value{VERSION}. * Configuration:: Writing your own configuration file * Network:: Downloading OS images from a network * Serial terminal:: Using GRUB via a serial line +* Vendor power-on keys:: Changing GRUB behaviour on vendor power-on keys * Preset Menu:: Embedding a configuration file into GRUB * Images:: GRUB image files * Filesystem:: Filesystem syntax and semantics @@ -747,6 +748,21 @@ implements few VT100 escape sequences. If you specify this option then GRUB provides you with an alternative menu interface, because the normal menu requires several fancy features of your terminal. +@node Vendor power-on keys +@chapter Using GRUB with vendor power-on keys +Some laptop vendor provide an additional power-on button which boots another OS. +GRUB supports such buttons with GRUB_TIMEOUT_BUTTON, GRUB_DEFAULT_BUTTON, +GRUB_HIDDEN_TIMEOUT_BUTTON and GRUB_BUTTON_CMOS_ADDRESS variables in +default/grub. GRUB_TIMEOUT_BUTTON, GRUB_DEFAULT_BUTTON and +GRUB_HIDDEN_TIMEOUT_BUTTON are used instead of corresponding variables without +_BUTTON suffix when powered using special button. +GRUB_BUTTON_CMOS_ADDRESS is vendor specific and partially model-specific. +Values known to GRUB team are: + +@table @key +@item Dell XPS M1530 +85:3 +@end table @node Filesystem @chapter Filesystem syntax and semantics diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in index d1abfa36a..0095e1ce8 100644 --- a/util/grub-mkconfig.in +++ b/util/grub-mkconfig.in @@ -246,6 +246,10 @@ export GRUB_DEFAULT \ GRUB_HIDDEN_TIMEOUT \ GRUB_HIDDEN_TIMEOUT_QUIET \ GRUB_TIMEOUT \ + GRUB_DEFAULT_BUTTON \ + GRUB_HIDDEN_TIMEOUT_BUTTON \ + GRUB_TIMEOUT_BUTTON \ + GRUB_BUTTON_CMOS_ADDRESS \ GRUB_DISTRIBUTOR \ GRUB_CMDLINE_LINUX \ GRUB_CMDLINE_LINUX_DEFAULT \ diff --git a/util/grub.d/00_header.in b/util/grub.d/00_header.in index d181fdffc..df8f5dfaa 100644 --- a/util/grub.d/00_header.in +++ b/util/grub.d/00_header.in @@ -38,11 +38,29 @@ if [ "x${GRUB_DEFAULT}" = "xsaved" ] ; then GRUB_DEFAULT='${saved_entry}' ; fi if [ "x${GRUB_TIMEOUT}" = "x" ] ; then GRUB_TIMEOUT=5 ; fi if [ "x${GRUB_GFXMODE}" = "x" ] ; then GRUB_GFXMODE=640x480 ; fi +if [ "x${GRUB_DEFAULT_BUTTON}" = "x" ] ; then GRUB_DEFAULT_BUTTON="$GRUB_DEFAULT" ; fi +if [ "x${GRUB_DEFAULT_BUTTON}" = "xsaved" ] ; then GRUB_DEFAULT_BUTTON='${saved_entry}' ; fi +if [ "x${GRUB_TIMEOUT_BUTTON}" = "x" ] ; then GRUB_TIMEOUT_BUTTON="$GRUB_TIMEOUT" ; fi + cat << EOF if [ -s \$prefix/grubenv ]; then load_env fi +EOF +if [ "x$GRUB_BUTTON_CMOS_ADDRESS" != "x" ]; then + cat < Date: Sun, 23 May 2010 14:37:28 +0200 Subject: [PATCH 673/738] * commands/usbtest.c (grub_usb_get_string): Properly support UTF-16. --- ChangeLog | 4 ++++ commands/usbtest.c | 15 ++++++++++++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 39a658288..01d2dbf7c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-05-23 Vladimir Serbinenko + + * commands/usbtest.c (grub_usb_get_string): Properly support UTF-16. + 2010-05-23 Vladimir Serbinenko cmostest support. diff --git a/commands/usbtest.c b/commands/usbtest.c index b884a93f1..191c4e4df 100644 --- a/commands/usbtest.c +++ b/commands/usbtest.c @@ -83,15 +83,24 @@ grub_usb_get_string (grub_usb_device_t dev, grub_uint8_t index, int langid, 0x06, (3 << 8) | index, langid, descstr.length, (char *) descstrp); - *string = grub_malloc (descstr.length / 2); + if (descstrp->length == 0) + { + grub_free (descstrp); + *string = grub_strdup (""); + if (! *string) + return GRUB_USB_ERR_INTERNAL; + return GRUB_USB_ERR_NONE; + } + + *string = grub_malloc (descstr.length * 2 + 1); if (! *string) { grub_free (descstrp); return GRUB_USB_ERR_INTERNAL; } - grub_utf16_to_utf8 ((grub_uint8_t *) *string, descstrp->str, descstrp->length / 2 - 1); - (*string)[descstr.length / 2 - 1] = '\0'; + *grub_utf16_to_utf8 ((grub_uint8_t *) *string, descstrp->str, + descstrp->length / 2 - 1) = 0; grub_free (descstrp); return GRUB_USB_ERR_NONE; From 7d8c0213538e9954d3b466d91c6c7c3c0f10b300 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Tue, 25 May 2010 18:24:46 +0530 Subject: [PATCH 674/738] * INSTALL: Added flex >= 2.5.35 requirement. --- ChangeLog | 4 ++++ INSTALL | 1 + 2 files changed, 5 insertions(+) diff --git a/ChangeLog b/ChangeLog index 01d2dbf7c..b8e66c7a2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-05-25 BVK Chaitanya + + * INSTALL: Added flex >= 2.5.35 requirement. + 2010-05-23 Vladimir Serbinenko * commands/usbtest.c (grub_usb_get_string): Properly support UTF-16. diff --git a/INSTALL b/INSTALL index 0dd408bcc..7186d20db 100644 --- a/INSTALL +++ b/INSTALL @@ -16,6 +16,7 @@ configuring the GRUB. * GNU Bison 2.3 or later * GNU gettext 0.17 or later * GNU binutils 2.9.1.0.23 or later +* Flex 2.5.35 or later * Other standard GNU/Unix tools If you use a development snapshot or want to hack on GRUB you may From 95ac3c730c58a60ec8a64bf046d235eec95eb790 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Sutre?= Date: Wed, 26 May 2010 23:49:52 +0200 Subject: [PATCH 675/738] Fix -Wshadow warning with emu build on NetBSD. --- ChangeLog | 5 +++++ kern/emu/hostdisk.c | 8 ++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index b8e66c7a2..ff7d02b44 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-05-26 Grégoire Sutre + + * kern/emu/hostdisk.c (find_partition_start) [__NetBSD__]: Renamed + variable index into p_index to suppress a warning with -Wshadow. + 2010-05-25 BVK Chaitanya * INSTALL: Added flex >= 2.5.35 requirement. diff --git a/kern/emu/hostdisk.c b/kern/emu/hostdisk.c index 9c4697552..ae2f7d9ad 100644 --- a/kern/emu/hostdisk.c +++ b/kern/emu/hostdisk.c @@ -338,7 +338,7 @@ find_partition_start (const char *dev) struct hd_geometry hdg; # else /* defined(__NetBSD__) */ struct disklabel label; - int index; + int p_index; # endif /* !defined(__NetBSD__) */ # ifdef HAVE_DEVICE_MAPPER @@ -435,15 +435,15 @@ devmapper_fail: # if !defined(__NetBSD__) return hdg.start; # else /* defined(__NetBSD__) */ - index = dev[strlen(dev) - 1] - 'a'; + p_index = dev[strlen(dev) - 1] - 'a'; - if (index >= label.d_npartitions) + if (p_index >= label.d_npartitions) { grub_error (GRUB_ERR_BAD_DEVICE, "no disk label entry for `%s'", dev); return 0; } - return (grub_disk_addr_t) label.d_partitions[index].p_offset; + return (grub_disk_addr_t) label.d_partitions[p_index].p_offset; # endif /* !defined(__NetBSD__) */ } #endif /* __linux__ || __CYGWIN__ */ From d1d368e426d3a0554ec28f52dafbd644fd21816e Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Thu, 27 May 2010 12:43:22 +0100 Subject: [PATCH 676/738] * util/grub-mkrescue.in: Initialise override_dir rather than assuming that it's unset or empty in the environment. --- ChangeLog | 5 +++++ util/grub-mkrescue.in | 1 + 2 files changed, 6 insertions(+) diff --git a/ChangeLog b/ChangeLog index ff7d02b44..22005fbb9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-05-27 Colin Watson + + * util/grub-mkrescue.in: Initialise override_dir rather than + assuming that it's unset or empty in the environment. + 2010-05-26 Grégoire Sutre * kern/emu/hostdisk.c (find_partition_start) [__NetBSD__]: Renamed diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in index 7e7253006..99b10de7b 100644 --- a/util/grub-mkrescue.in +++ b/util/grub-mkrescue.in @@ -37,6 +37,7 @@ pc_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/i386-pc efi32_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/i386-efi efi64_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/x86_64-efi rom_directory= +override_dir= grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}` # Usage: usage From 5fdba519bb35c64a2c90221f069863cc36e00387 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Thu, 27 May 2010 16:38:16 +0200 Subject: [PATCH 677/738] 2010-05-27 Robert Millan MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * util/grub-mkconfig_lib.in (prepare_grub_to_access_device): Insert partmap module to handle cross-partmap setups. Reported by Orestes Mas. Gràcies! --- ChangeLog | 6 ++++++ util/grub-mkconfig_lib.in | 5 +++++ 2 files changed, 11 insertions(+) diff --git a/ChangeLog b/ChangeLog index 22005fbb9..18c2abeac 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-05-27 Robert Millan + + * util/grub-mkconfig_lib.in (prepare_grub_to_access_device): Insert + partmap module to handle cross-partmap setups. + Reported by Orestes Mas. Gràcies! + 2010-05-27 Colin Watson * util/grub-mkrescue.in: Initialise override_dir rather than diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in index f4674b257..7ec8cb5be 100644 --- a/util/grub-mkconfig_lib.in +++ b/util/grub-mkconfig_lib.in @@ -105,6 +105,11 @@ prepare_grub_to_access_device () echo "insmod ${module}" done + partmap="`${grub_probe} --device ${device} --target=partmap`" + for module in ${partmap} ; do + echo "insmod ${module}" + done + fs="`${grub_probe} --device ${device} --target=fs`" for module in ${fs} ; do echo "insmod ${module}" From db2102a0468e15c76bb369eef728622a9e51683e Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Thu, 27 May 2010 15:45:41 +0100 Subject: [PATCH 678/738] * kern/emu/misc.c (canonicalize_file_name): realpath can still return NULL for various reasons even if it has a maximum-length buffer: for example, there might be a symlink loop, or the path might exceed PATH_MAX. If this happens, return NULL. --- ChangeLog | 7 +++++++ kern/emu/misc.c | 3 ++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 18c2abeac..34bc31bf9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-05-27 Colin Watson + + * kern/emu/misc.c (canonicalize_file_name): realpath can still + return NULL for various reasons even if it has a maximum-length + buffer: for example, there might be a symlink loop, or the path + might exceed PATH_MAX. If this happens, return NULL. + 2010-05-27 Robert Millan * util/grub-mkconfig_lib.in (prepare_grub_to_access_device): Insert diff --git a/kern/emu/misc.c b/kern/emu/misc.c index a3ccb3076..9437169e0 100644 --- a/kern/emu/misc.c +++ b/kern/emu/misc.c @@ -185,7 +185,8 @@ canonicalize_file_name (const char *path) char *ret; #ifdef PATH_MAX ret = xmalloc (PATH_MAX); - (void) realpath (path, ret); + if (!realpath (path, ret)) + return NULL; #else ret = realpath (path, NULL); #endif From d870813427f6e58ddc6877a578ae5b882f6f0898 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Thu, 27 May 2010 15:54:18 +0100 Subject: [PATCH 679/738] * util/grub-script-check.c (main): Ensure defined behaviour on empty input files (in which case exit zero). --- ChangeLog | 5 +++++ util/grub-script-check.c | 6 ++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 34bc31bf9..a8e3e5284 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-05-27 Colin Watson + + * util/grub-script-check.c (main): Ensure defined behaviour on empty + input files (in which case exit zero). + 2010-05-27 Colin Watson * kern/emu/misc.c (canonicalize_file_name): realpath can still diff --git a/util/grub-script-check.c b/util/grub-script-check.c index dc732aa01..e69f787f5 100644 --- a/util/grub-script-check.c +++ b/util/grub-script-check.c @@ -145,7 +145,8 @@ main (int argc, char *argv[]) char *input; FILE *file = 0; int verbose = 0; - struct grub_script *script; + int found_input = 0; + struct grub_script *script = NULL; auto grub_err_t get_config_line (char **line, int cont); grub_err_t get_config_line (char **line, int cont __attribute__ ((unused))) @@ -247,6 +248,7 @@ main (int argc, char *argv[]) get_config_line(&input, 0); if (! input) break; + found_input = 1; script = grub_script_parse (input, get_config_line); if (script) @@ -262,5 +264,5 @@ main (int argc, char *argv[]) grub_fini_all (); if (file) fclose (file); - return (script == 0); + return (found_input && script == 0); } From 15fb2ae896e6aad4ba947a5b4828f938575c9877 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 28 May 2010 11:51:50 +0100 Subject: [PATCH 680/738] Make grub-probe work with symbolic links under /dev/mapper as well as with real block devices. The Linux world seems to be (at best) in transition here, and GRUB shouldn't get caught in the middle. * kern/emu/getroot.c (find_root_device): Follow symbolic links under /dev/mapper. --- ChangeLog.mapper-symlink | 8 ++++++++ kern/emu/getroot.c | 15 +++++++++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 ChangeLog.mapper-symlink diff --git a/ChangeLog.mapper-symlink b/ChangeLog.mapper-symlink new file mode 100644 index 000000000..afcfc6479 --- /dev/null +++ b/ChangeLog.mapper-symlink @@ -0,0 +1,8 @@ +2010-05-28 Colin Watson + + Make grub-probe work with symbolic links under /dev/mapper as well + as with real block devices. The Linux world seems to be (at best) + in transition here, and GRUB shouldn't get caught in the middle. + + * kern/emu/getroot.c (find_root_device): Follow symbolic links under + /dev/mapper. diff --git a/kern/emu/getroot.c b/kern/emu/getroot.c index 6875044da..e62abe089 100644 --- a/kern/emu/getroot.c +++ b/kern/emu/getroot.c @@ -126,9 +126,20 @@ find_root_device (const char *dir, dev_t dev) /* Ignore any error. */ continue; - if (S_ISLNK (st.st_mode)) - /* Don't follow symbolic links. */ + if (S_ISLNK (st.st_mode)) { +#ifdef __linux__ + if (strcmp (dir, "mapper") == 0) { + /* Follow symbolic links under /dev/mapper/; the canonical name + may be something like /dev/dm-0, but the names under + /dev/mapper/ are more human-readable and so we prefer them if + we can get them. */ + if (stat (ent->d_name, &st) < 0) + continue; + } else +#endif /* __linux__ */ + /* Don't follow other symbolic links. */ continue; + } if (S_ISDIR (st.st_mode)) { From fa4b84900afa71ad9fcf498d509e8f0e8abbb6dc Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Fri, 28 May 2010 19:18:45 +0530 Subject: [PATCH 681/738] Fix grub-emu issues on NetBSD, with gcc 4.1.3. * conf/any-emu.rmk: Remove unnecessary COMMON_CFLAGS. * include/grub/emu/misc.h (canonicalize_file_name): New Prototype. * kern/misc.c (__enable_execute_stack): Disable on GRUB_MACHINE_EMU. --- ChangeLog | 9 +++++++++ conf/any-emu.rmk | 2 -- include/grub/emu/misc.h | 1 + kern/misc.c | 3 ++- 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 965848669..e3fb344aa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2010-05-28 BVK Chaitanya + + Fix grub-emu issues on NetBSD, with gcc 4.1.3. + + * conf/any-emu.rmk: Remove unnecessary COMMON_CFLAGS. + * include/grub/emu/misc.h (canonicalize_file_name): New Prototype. + * kern/misc.c (__enable_execute_stack): Disable on + GRUB_MACHINE_EMU. + 2010-05-28 Colin Watson Make grub-probe work with symbolic links under /dev/mapper as well diff --git a/conf/any-emu.rmk b/conf/any-emu.rmk index 3f0df06aa..000996172 100644 --- a/conf/any-emu.rmk +++ b/conf/any-emu.rmk @@ -1,7 +1,5 @@ # -*- makefile -*- -COMMON_CFLAGS += -nostdinc -isystem $(shell $(TARGET_CC) -print-file-name=include) - kernel_img_RELOCATABLE = yes pkglib_PROGRAMS = kernel.img kernel_img_SOURCES = kern/device.c kern/disk.c kern/dl.c kern/env.c \ diff --git a/include/grub/emu/misc.h b/include/grub/emu/misc.h index e037e6be7..0e6ace0e8 100644 --- a/include/grub/emu/misc.h +++ b/include/grub/emu/misc.h @@ -46,5 +46,6 @@ int EXPORT_FUNC(asprintf) (char **buf, const char *fmt, ...); #endif char * EXPORT_FUNC(xasprintf) (const char *fmt, ...); +extern char * canonicalize_file_name (const char *path); #endif /* GRUB_EMU_MISC_H */ diff --git a/kern/misc.c b/kern/misc.c index ccc01d43f..2ba34f235 100644 --- a/kern/misc.c +++ b/kern/misc.c @@ -1058,7 +1058,7 @@ grub_abort (void) void abort (void) __attribute__ ((alias ("grub_abort"))); #endif -#if defined(NEED_ENABLE_EXECUTE_STACK) && !defined(GRUB_UTIL) +#if defined(NEED_ENABLE_EXECUTE_STACK) && !defined(GRUB_UTIL) && !defined(GRUB_MACHINE_EMU) /* Some gcc versions generate a call to this function in trampolines for nested functions. */ void __enable_execute_stack (void *addr __attribute__ ((unused))) @@ -1075,3 +1075,4 @@ void __deregister_frame_info (void) { } #endif + From c7c75cf4cb568889432527f94efc0d971e2cc3b0 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 28 May 2010 18:13:48 +0100 Subject: [PATCH 682/738] * configure.ac: AC_PROG_LEX sets LEX to ":" if lex is missing, not to the empty string. --- ChangeLog | 5 +++++ configure.ac | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index e3fb344aa..5072a6026 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-05-28 Colin Watson + + * configure.ac: AC_PROG_LEX sets LEX to ":" if lex is missing, not + to the empty string. + 2010-05-28 BVK Chaitanya Fix grub-emu issues on NetBSD, with gcc 4.1.3. diff --git a/configure.ac b/configure.ac index ace6bd81d..31b179d46 100644 --- a/configure.ac +++ b/configure.ac @@ -192,7 +192,7 @@ AC_PROG_LEX AC_PROG_MAKE_SET AC_PROG_MKDIR_P -if test "x$LEX" = x; then +if test "x$LEX" = "x:"; then AC_MSG_ERROR([flex is not found]) else version=`$LEX --version | $AWK '{ split($NF,x,"."); print x[[1]]*10000+x[[2]]*100+x[[3]]; }'` From 8b1cf5e87f603a30dbc0e0d13c44c3628d67b2bf Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 31 May 2010 13:58:18 +0200 Subject: [PATCH 683/738] Dedicated DMA allocation functions. CS5536 OHCI support. --- bus/cs5536.c | 215 +++++++++++++++++++++++++++++++ bus/pci.c | 53 ++++++++ bus/usb/ohci.c | 175 +++++++++++++++++-------- bus/usb/uhci.c | 6 +- bus/usb/usbtrans.c | 91 ++++++++++--- conf/i386.rmk | 6 + conf/mips-yeeloong.rmk | 34 ++++- include/grub/cs5536.h | 190 +++++++++++++++++++++++++++ include/grub/i386/pci.h | 2 +- include/grub/mips/yeeloong/pci.h | 32 +++-- include/grub/pci.h | 26 ++++ include/grub/smbus.h | 70 ++++++++++ include/grub/usbtrans.h | 2 +- 13 files changed, 817 insertions(+), 85 deletions(-) create mode 100644 bus/cs5536.c create mode 100644 include/grub/cs5536.h create mode 100644 include/grub/smbus.h diff --git a/bus/cs5536.c b/bus/cs5536.c new file mode 100644 index 000000000..61b0646b4 --- /dev/null +++ b/bus/cs5536.c @@ -0,0 +1,215 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include + +int +grub_cs5536_find (grub_pci_device_t *devp) +{ + int found = 0; + auto int NESTED_FUNC_ATTR hook (grub_pci_device_t dev, + grub_pci_id_t pciid); + + int NESTED_FUNC_ATTR hook (grub_pci_device_t dev, + grub_pci_id_t pciid) + { + if (pciid == GRUB_CS5536_PCIID) + { + *devp = dev; + found = 1; + return 1; + } + return 0; + } + + grub_pci_iterate (hook); + + return found; +} + +grub_uint64_t +grub_cs5536_read_msr (grub_pci_device_t dev, grub_uint32_t addr) +{ + grub_uint64_t ret = 0; + grub_pci_write (grub_pci_make_address (dev, GRUB_CS5536_MSR_MAILBOX_ADDR), + addr); + ret = (grub_uint64_t) + grub_pci_read (grub_pci_make_address (dev, GRUB_CS5536_MSR_MAILBOX_DATA0)); + ret |= (((grub_uint64_t) + grub_pci_read (grub_pci_make_address (dev, + GRUB_CS5536_MSR_MAILBOX_DATA1))) + << 32); + return ret; +} + +void +grub_cs5536_write_msr (grub_pci_device_t dev, grub_uint32_t addr, + grub_uint64_t val) +{ + grub_pci_write (grub_pci_make_address (dev, GRUB_CS5536_MSR_MAILBOX_ADDR), + addr); + grub_pci_write (grub_pci_make_address (dev, GRUB_CS5536_MSR_MAILBOX_DATA0), + val & 0xffffffff); + grub_pci_write (grub_pci_make_address (dev, GRUB_CS5536_MSR_MAILBOX_DATA1), + val >> 32); +} + +grub_err_t +grub_cs5536_smbus_wait (grub_port_t smbbase) +{ + grub_uint64_t start = grub_get_time_ms (); + while (1) + { + grub_uint8_t status; + status = grub_inb (smbbase + GRUB_CS5536_SMB_REG_STATUS); + if (status & GRUB_CS5536_SMB_REG_STATUS_SDAST) + return GRUB_ERR_NONE; + if (status & GRUB_CS5536_SMB_REG_STATUS_BER) + return grub_error (GRUB_ERR_IO, "SM bus error"); + if (status & GRUB_CS5536_SMB_REG_STATUS_NACK) + return grub_error (GRUB_ERR_IO, "NACK received"); + if (grub_get_time_ms () > start + 40) + return grub_error (GRUB_ERR_IO, "SM stalled"); + } + + return GRUB_ERR_NONE; +} + +grub_err_t +grub_cs5536_read_spd_byte (grub_port_t smbbase, grub_uint8_t dev, + grub_uint8_t addr, grub_uint8_t *res) +{ + grub_err_t err; + + /* Send START. */ + grub_outb (grub_inb (smbbase + GRUB_CS5536_SMB_REG_CTRL1) + | GRUB_CS5536_SMB_REG_CTRL1_START, + smbbase + GRUB_CS5536_SMB_REG_CTRL1); + + /* Send device address. */ + err = grub_cs5536_smbus_wait (smbbase); + if (err) + return err; + grub_outb (dev << 1, smbbase + GRUB_CS5536_SMB_REG_DATA); + + /* Send ACK. */ + err = grub_cs5536_smbus_wait (smbbase); + if (err) + return err; + grub_outb (grub_inb (smbbase + GRUB_CS5536_SMB_REG_CTRL1) + | GRUB_CS5536_SMB_REG_CTRL1_ACK, + smbbase + GRUB_CS5536_SMB_REG_CTRL1); + + /* Send byte address. */ + grub_outb (addr, smbbase + GRUB_CS5536_SMB_REG_DATA); + + /* Send START. */ + err = grub_cs5536_smbus_wait (smbbase); + if (err) + return err; + grub_outb (grub_inb (smbbase + GRUB_CS5536_SMB_REG_CTRL1) + | GRUB_CS5536_SMB_REG_CTRL1_START, + smbbase + GRUB_CS5536_SMB_REG_CTRL1); + + /* Send device address. */ + err = grub_cs5536_smbus_wait (smbbase); + if (err) + return err; + grub_outb ((dev << 1) | 1, smbbase + GRUB_CS5536_SMB_REG_DATA); + + /* Send STOP. */ + err = grub_cs5536_smbus_wait (smbbase); + if (err) + return err; + grub_outb (grub_inb (smbbase + GRUB_CS5536_SMB_REG_CTRL1) + | GRUB_CS5536_SMB_REG_CTRL1_STOP, + smbbase + GRUB_CS5536_SMB_REG_CTRL1); + + err = grub_cs5536_smbus_wait (smbbase); + if (err) + return err; + *res = grub_inb (smbbase + GRUB_CS5536_SMB_REG_DATA); + + return GRUB_ERR_NONE; +} + +grub_err_t +grub_cs5536_init_smbus (grub_pci_device_t dev, grub_uint16_t divisor, + grub_port_t *smbbase) +{ + grub_uint64_t smbbar; + + smbbar = grub_cs5536_read_msr (dev, GRUB_CS5536_MSR_SMB_BAR); + + /* FIXME */ + if (!(smbbar & GRUB_CS5536_LBAR_ENABLE)) + return grub_error(GRUB_ERR_IO, "SMB controller not enabled\n"); + *smbbase = (smbbar & GRUB_CS5536_LBAR_ADDR_MASK) + GRUB_MACHINE_PCI_IO_BASE; + + if (divisor < 8) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid divisor"); + + /* Disable SMB. */ + grub_outb (0, *smbbase + GRUB_CS5536_SMB_REG_CTRL2); + + /* Disable interrupts. */ + grub_outb (0, *smbbase + GRUB_CS5536_SMB_REG_CTRL1); + + /* Set as master. */ + grub_outb (GRUB_CS5536_SMB_REG_ADDR_MASTER, + *smbbase + GRUB_CS5536_SMB_REG_ADDR); + + /* Launch. */ + grub_outb (((divisor >> 7) & 0xff), *smbbase + GRUB_CS5536_SMB_REG_CTRL3); + grub_outb (((divisor << 1) & 0xfe) | GRUB_CS5536_SMB_REG_CTRL2_ENABLE, + *smbbase + GRUB_CS5536_SMB_REG_CTRL2); + + return GRUB_ERR_NONE; +} + +grub_err_t +grub_cs5536_read_spd (grub_port_t smbbase, grub_uint8_t dev, + struct grub_smbus_spd *res) +{ + grub_err_t err; + grub_size_t size; + grub_uint8_t b; + grub_size_t ptr; + + err = grub_cs5536_read_spd_byte (smbbase, dev, 0, &b); + if (err) + return err; + if (b == 0) + return grub_error (GRUB_ERR_IO, "no SPD found"); + size = b; + + ((grub_uint8_t *) res)[0] = b; + for (ptr = 1; ptr < size; ptr++) + { + err = grub_cs5536_read_spd_byte (smbbase, dev, ptr, + &((grub_uint8_t *) res)[ptr]); + if (err) + return err; + } + return GRUB_ERR_NONE; +} + diff --git a/bus/pci.c b/bus/pci.c index a08e53446..3e2126962 100644 --- a/bus/pci.c +++ b/bus/pci.c @@ -19,6 +19,49 @@ #include #include +#include + +#if GRUB_TARGET_SIZEOF_VOID_P == 4 +struct grub_pci_dma_chunk * +grub_memalign_dma32 (grub_size_t align, grub_size_t size) +{ + return grub_memalign (align, size); +} + +void +grub_dma_free (struct grub_pci_dma_chunk *ch) +{ + grub_free (ch); +} +#endif + +#ifdef GRUB_MACHINE_MIPS_YEELOONG +volatile void * +grub_dma_get_virt (struct grub_pci_dma_chunk *ch) +{ + return (void *) ((((grub_uint32_t) ch) & 0x1fffffff) | 0xa0000000); +} + +grub_uint32_t +grub_dma_get_phys (struct grub_pci_dma_chunk *ch) +{ + return (((grub_uint32_t) ch) & 0x1fffffff) | 0x80000000; +} +#else + +volatile void * +grub_dma_get_virt (struct grub_pci_dma_chunk *ch) +{ + return (void *) ch; +} + +grub_uint32_t +grub_dma_get_phys (struct grub_pci_dma_chunk *ch) +{ + return (grub_uint32_t) ch; +} + +#endif grub_pci_address_t grub_pci_make_address (grub_pci_device_t dev, int reg) @@ -48,6 +91,16 @@ grub_pci_iterate (grub_pci_iteratefunc_t hook) if (id >> 16 == 0xFFFF) continue; +#ifdef GRUB_MACHINE_MIPS_YEELOONG + /* Skip ghosts. */ + if (id == GRUB_YEELOONG_OHCI_PCIID + && dev.function == GRUB_YEELOONG_OHCI_GHOST_FUNCTION) + continue; + if (id == GRUB_YEELOONG_EHCI_PCIID + && dev.function == GRUB_YEELOONG_EHCI_GHOST_FUNCTION) + continue; +#endif + if (hook (dev, id)) return; diff --git a/bus/usb/ohci.c b/bus/usb/ohci.c index 6d185bc7f..7294fe537 100644 --- a/bus/usb/ohci.c +++ b/bus/usb/ohci.c @@ -24,8 +24,9 @@ #include #include #include -#include +#include #include +#include struct grub_ohci_hcca { @@ -63,13 +64,15 @@ struct grub_ohci_td grub_uint32_t buffer_end; } __attribute__((packed)); -typedef struct grub_ohci_td *grub_ohci_td_t; -typedef struct grub_ohci_ed *grub_ohci_ed_t; +typedef volatile struct grub_ohci_td *grub_ohci_td_t; +typedef volatile struct grub_ohci_ed *grub_ohci_ed_t; struct grub_ohci { volatile grub_uint32_t *iobase; volatile struct grub_ohci_hcca *hcca; + grub_uint32_t hcca_addr; + struct grub_pci_dma_chunk *hcca_chunk; struct grub_ohci *next; }; @@ -91,10 +94,23 @@ typedef enum GRUB_OHCI_REG_BULKCURR, GRUB_OHCI_REG_DONEHEAD, GRUB_OHCI_REG_FRAME_INTERVAL, + GRUB_OHCI_REG_PERIODIC_START = 16, GRUB_OHCI_REG_RHUBA = 18, GRUB_OHCI_REG_RHUBPORT = 21 } grub_ohci_reg_t; +#define GRUB_OHCI_RHUB_PORT_POWER_MASK 0x300 +#define GRUB_OHCI_RHUB_PORT_ALL_POWERED 0x200 + +#define GRUB_OHCI_REG_FRAME_INTERVAL_FSMPS_MASK 0x8fff0000 +#define GRUB_OHCI_REG_FRAME_INTERVAL_FSMPS_SHIFT 16 +#define GRUB_OHCI_REG_FRAME_INTERVAL_FI_SHIFT 0 + +/* XXX: Is this choice of timings sane? */ +#define GRUB_OHCI_FSMPS 0x2778 +#define GRUB_OHCI_PERIODIC_START 0x257f +#define GRUB_OHCI_FRAME_INTERVAL 0x2edf + static grub_uint32_t grub_ohci_readreg32 (struct grub_ohci *o, grub_ohci_reg_t reg) { @@ -114,51 +130,81 @@ grub_ohci_writereg32 (struct grub_ohci *o, controller. If this is the case, initialize it. */ static int NESTED_FUNC_ATTR grub_ohci_pci_iter (grub_pci_device_t dev, - grub_pci_id_t pciid __attribute__((unused))) + grub_pci_id_t pciid) { - grub_uint32_t class_code; - grub_uint32_t class; - grub_uint32_t subclass; grub_uint32_t interf; grub_uint32_t base; grub_pci_address_t addr; struct grub_ohci *o; grub_uint32_t revision; - grub_uint32_t frame_interval; - - addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); - class_code = grub_pci_read (addr) >> 8; - - interf = class_code & 0xFF; - subclass = (class_code >> 8) & 0xFF; - class = class_code >> 16; - - /* If this is not an OHCI controller, just return. */ - if (class != 0x0c || subclass != 0x03 || interf != 0x10) - return 0; + int cs5536; /* Determine IO base address. */ - addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); - base = grub_pci_read (addr); + grub_dprintf ("ohci", "pciid = %x\n", pciid); + + if (pciid == GRUB_CS5536_PCIID) + { + grub_uint64_t basereg; + + cs5536 = 1; + basereg = grub_cs5536_read_msr (dev, GRUB_CS5536_MSR_USB_OHCI_BASE); + if (!(basereg & GRUB_CS5536_MSR_USB_BASE_MEMORY_ENABLE)) + { + /* Shouldn't happen. */ + grub_dprintf ("ohci", "No OHCI address is assigned\n"); + return 0; + } + base = (basereg & GRUB_CS5536_MSR_USB_BASE_ADDR_MASK); + basereg |= GRUB_CS5536_MSR_USB_BASE_BUS_MASTER; + basereg &= ~GRUB_CS5536_MSR_USB_BASE_PME_ENABLED; + basereg &= ~GRUB_CS5536_MSR_USB_BASE_PME_STATUS; + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_USB_OHCI_BASE, basereg); + } + else + { + grub_uint32_t class_code; + grub_uint32_t class; + grub_uint32_t subclass; + + addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); + class_code = grub_pci_read (addr) >> 8; + + interf = class_code & 0xFF; + subclass = (class_code >> 8) & 0xFF; + class = class_code >> 16; + + /* If this is not an OHCI controller, just return. */ + if (class != 0x0c || subclass != 0x03 || interf != 0x10) + return 0; + + addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); + base = grub_pci_read (addr); #if 0 - /* Stop if there is no IO space base address defined. */ - if (! (base & 1)) - return 0; + /* Stop if there is no IO space base address defined. */ + if (! (base & 1)) + return 0; #endif + grub_dprintf ("ohci", "class=0x%02x 0x%02x interface 0x%02x\n", + class, subclass, interf); + } + /* Allocate memory for the controller and register it. */ o = grub_malloc (sizeof (*o)); if (! o) return 1; - o->iobase = (grub_uint32_t *) base; + o->iobase = grub_pci_device_map_range (dev, base, 0x100); + + grub_dprintf ("ohci", "base=%p\n", o->iobase); /* Reserve memory for the HCCA. */ - o->hcca = (struct grub_ohci_hcca *) grub_memalign (256, 256); - - grub_dprintf ("ohci", "class=0x%02x 0x%02x interface 0x%02x base=%p\n", - class, subclass, interf, o->iobase); + o->hcca_chunk = grub_memalign_dma32 (256, 256); + if (! o->hcca_chunk) + return 1; + o->hcca = grub_dma_get_virt (o->hcca_chunk); + o->hcca_addr = grub_dma_get_phys (o->hcca_chunk); /* Check if the OHCI revision is actually 1.0 as supported. */ revision = grub_ohci_readreg32 (o, GRUB_OHCI_REG_REVISION); @@ -166,19 +212,27 @@ grub_ohci_pci_iter (grub_pci_device_t dev, if ((revision & 0xFF) != 0x10) goto fail; - /* Backup the frame interval register. */ - frame_interval = grub_ohci_readreg32 (o, GRUB_OHCI_REG_FRAME_INTERVAL); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBA, + (grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBA) + & ~GRUB_OHCI_RHUB_PORT_POWER_MASK) + | GRUB_OHCI_RHUB_PORT_ALL_POWERED); /* Suspend the OHCI by issuing a reset. */ grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, 1); /* XXX: Magic. */ grub_millisleep (1); grub_dprintf ("ohci", "OHCI reset\n"); - /* Restore the frame interval register. */ - grub_ohci_writereg32 (o, GRUB_OHCI_REG_FRAME_INTERVAL, frame_interval); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_FRAME_INTERVAL, + (GRUB_OHCI_FSMPS + << GRUB_OHCI_REG_FRAME_INTERVAL_FSMPS_SHIFT) + | (GRUB_OHCI_FRAME_INTERVAL + << GRUB_OHCI_REG_FRAME_INTERVAL_FI_SHIFT)); + + grub_ohci_writereg32 (o, GRUB_OHCI_REG_PERIODIC_START, + GRUB_OHCI_PERIODIC_START); /* Setup the HCCA. */ - grub_ohci_writereg32 (o, GRUB_OHCI_REG_HCCA, (grub_uint32_t) o->hcca); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_HCCA, o->hcca_addr); grub_dprintf ("ohci", "OHCI HCCA\n"); /* Enable the OHCI. */ @@ -194,11 +248,13 @@ grub_ohci_pci_iter (grub_pci_device_t dev, return 0; fail: +#ifndef GRUB_MACHINE_MIPS_YEELOONG if (o) grub_free ((void *) o->hcca); +#endif grub_free (o); - return 1; + return 0; } @@ -229,7 +285,7 @@ grub_ohci_iterate (int (*hook) (grub_usb_controller_t dev)) static void grub_ohci_transaction (grub_ohci_td_t td, grub_transfer_type_t type, unsigned int toggle, - grub_size_t size, char *data) + grub_size_t size, grub_uint32_t data) { grub_uint32_t token; grub_uint32_t buffer; @@ -261,7 +317,7 @@ grub_ohci_transaction (grub_ohci_td_t td, token |= toggle << 24; token |= 1 << 25; - buffer = (grub_uint32_t) data; + buffer = data; buffer_end = buffer + size - 1; td->token = grub_cpu_to_le32 (token); @@ -276,7 +332,10 @@ grub_ohci_transfer (grub_usb_controller_t dev, { struct grub_ohci *o = (struct grub_ohci *) dev->data; grub_ohci_ed_t ed; + grub_uint32_t ed_addr; + struct grub_pci_dma_chunk *ed_chunk, *td_list_chunk; grub_ohci_td_t td_list; + grub_uint32_t td_list_addr; grub_uint32_t target; grub_uint32_t td_tail; grub_uint32_t td_head; @@ -286,18 +345,23 @@ grub_ohci_transfer (grub_usb_controller_t dev, int i; /* Allocate an Endpoint Descriptor. */ - ed = grub_memalign (16, sizeof (*ed)); - if (! ed) + ed_chunk = grub_memalign_dma32 (256, sizeof (*ed)); + if (! ed_chunk) return GRUB_USB_ERR_INTERNAL; + ed = grub_dma_get_virt (ed_chunk); + ed_addr = grub_dma_get_phys (ed_chunk); - td_list = grub_memalign (16, sizeof (*td_list) * (transfer->transcnt + 1)); - if (! td_list) + td_list_chunk = grub_memalign_dma32 (256, sizeof (*td_list) + * (transfer->transcnt + 1)); + if (! td_list_chunk) { - grub_free ((void *) ed); + grub_dma_free (ed_chunk); return GRUB_USB_ERR_INTERNAL; } + td_list = grub_dma_get_virt (td_list_chunk); + td_list_addr = grub_dma_get_phys (td_list_chunk); - grub_dprintf ("ohci", "alloc=%p\n", td_list); + grub_dprintf ("ohci", "alloc=%p/0x%x\n", td_list, td_list_addr); /* Setup all Transfer Descriptors. */ for (i = 0; i < transfer->transcnt; i++) @@ -307,7 +371,8 @@ grub_ohci_transfer (grub_usb_controller_t dev, grub_ohci_transaction (&td_list[i], tr->pid, tr->toggle, tr->size, tr->data); - td_list[i].next_td = grub_cpu_to_le32 (&td_list[i + 1]); + td_list[i].next_td = grub_cpu_to_le32 (td_list_addr + + (i + 1) * sizeof (td_list[0])); } /* Setup the Endpoint Descriptor. */ @@ -324,9 +389,9 @@ grub_ohci_transfer (grub_usb_controller_t dev, /* Set the maximum packet size. */ target |= transfer->max << 16; - td_head = (grub_uint32_t) td_list; + td_head = td_list_addr; - td_tail = (grub_uint32_t) &td_list[transfer->transcnt]; + td_tail = td_list_addr + transfer->transcnt * sizeof (*td_list); ed->target = grub_cpu_to_le32 (target); ed->td_head = grub_cpu_to_le32 (td_head); @@ -353,7 +418,7 @@ grub_ohci_transfer (grub_usb_controller_t dev, status &= ~(1 << 2); grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, status); - grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKHEAD, (grub_uint32_t) ed); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKHEAD, ed_addr); /* Enable the Bulk list. */ control |= 1 << 5; @@ -380,10 +445,9 @@ grub_ohci_transfer (grub_usb_controller_t dev, status &= ~(1 << 1); grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, status); - grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD, - (grub_uint32_t) ed); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD, ed_addr); grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD+1, - (grub_uint32_t) ed); + ed_addr); /* Enable the Control list. */ control |= 1 << 4; @@ -424,9 +488,12 @@ grub_ohci_transfer (grub_usb_controller_t dev, { grub_uint8_t errcode; grub_ohci_td_t tderr; + grub_uint32_t td_err_addr; - tderr = (grub_ohci_td_t) grub_ohci_readreg32 (o, - GRUB_OHCI_REG_DONEHEAD); + td_err_addr = grub_ohci_readreg32 (o, GRUB_OHCI_REG_DONEHEAD); + + tderr = (grub_ohci_td_t) ((char *) td_list + + (td_err_addr - td_list_addr)); errcode = tderr->token >> 28; switch (errcode) @@ -519,8 +586,8 @@ grub_ohci_transfer (grub_usb_controller_t dev, grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, status); /* XXX */ - grub_free (td_list); - grub_free (ed); + grub_dma_free (td_list_chunk); + grub_dma_free (ed_chunk); return err; } diff --git a/bus/usb/uhci.c b/bus/usb/uhci.c index 947f2367b..6e47c38ef 100644 --- a/bus/usb/uhci.c +++ b/bus/usb/uhci.c @@ -380,7 +380,7 @@ static grub_uhci_td_t grub_uhci_transaction (struct grub_uhci *u, unsigned int endp, grub_transfer_type_t type, unsigned int addr, unsigned int toggle, grub_size_t size, - char *data) + grub_uint32_t data) { grub_uhci_td_t td; static const unsigned int tf[] = { 0x69, 0xE1, 0x2D }; @@ -398,7 +398,7 @@ grub_uhci_transaction (struct grub_uhci *u, unsigned int endp, } grub_dprintf ("uhci", - "transaction: endp=%d, type=%d, addr=%d, toggle=%d, size=%d data=%p td=%p\n", + "transaction: endp=%d, type=%d, addr=%d, toggle=%d, size=%d data=0x%x td=%p\n", endp, type, addr, toggle, size, data, td); /* Don't point to any TD, just terminate. */ @@ -418,7 +418,7 @@ grub_uhci_transaction (struct grub_uhci *u, unsigned int endp, td->token = ((size << 21) | (toggle << 19) | (endp << 15) | (addr << 8) | tf[type]); - td->buffer = (grub_uint32_t) data; + td->buffer = data; return td; } diff --git a/bus/usb/usbtrans.c b/bus/usb/usbtrans.c index 09e7af83e..f6d3d30f9 100644 --- a/bus/usb/usbtrans.c +++ b/bus/usb/usbtrans.c @@ -18,6 +18,7 @@ */ #include +#include #include #include #include @@ -29,30 +30,59 @@ grub_usb_control_msg (grub_usb_device_t dev, grub_uint8_t request, grub_uint16_t value, grub_uint16_t index, - grub_size_t size, char *data) + grub_size_t size0, char *data_in) { int i; grub_usb_transfer_t transfer; int datablocks; - struct grub_usb_packet_setup setupdata; + volatile struct grub_usb_packet_setup *setupdata; + grub_uint32_t setupdata_addr; grub_usb_err_t err; unsigned int max; + struct grub_pci_dma_chunk *data_chunk, *setupdata_chunk; + volatile char *data; + grub_uint32_t data_addr; + grub_size_t size = size0; + + /* FIXME: avoid allocation any kind of buffer in a first place. */ + data_chunk = grub_memalign_dma32 (128, size ? : 16); + if (!data_chunk) + return GRUB_USB_ERR_INTERNAL; + data = grub_dma_get_virt (data_chunk); + data_addr = grub_dma_get_phys (data_chunk); + grub_memcpy ((char *) data, data_in, size); grub_dprintf ("usb", "control: reqtype=0x%02x req=0x%02x val=0x%02x idx=0x%02x size=%d\n", reqtype, request, value, index, size); /* Create a transfer. */ - transfer = grub_malloc (sizeof (struct grub_usb_transfer)); + transfer = grub_malloc (sizeof (*transfer)); if (! transfer) - return grub_errno; + { + grub_dma_free (data_chunk); + return grub_errno; + } + + setupdata_chunk = grub_memalign_dma32 (32, sizeof (*setupdata)); + if (! setupdata_chunk) + { + grub_free (transfer); + grub_dma_free (data_chunk); + return grub_errno; + } + + setupdata = grub_dma_get_virt (setupdata_chunk); + setupdata_addr = grub_dma_get_phys (setupdata_chunk); /* Determine the maximum packet size. */ - if (dev->initialized) + if (dev->initialized && dev->descdev.maxsize0) max = dev->descdev.maxsize0; else max = 64; + grub_dprintf ("usb", "transfer = %p, dev = %p\n", transfer, dev); + datablocks = (size + max - 1) / max; /* XXX: Discriminate between different types of control @@ -71,18 +101,20 @@ grub_usb_control_msg (grub_usb_device_t dev, if (! transfer->transactions) { grub_free (transfer); + grub_dma_free (setupdata_chunk); + grub_dma_free (data_chunk); return grub_errno; } /* Build a Setup packet. XXX: Endianness. */ - setupdata.reqtype = reqtype; - setupdata.request = request; - setupdata.value = value; - setupdata.index = index; - setupdata.length = size; - transfer->transactions[0].size = sizeof (setupdata); + setupdata->reqtype = reqtype; + setupdata->request = request; + setupdata->value = value; + setupdata->index = index; + setupdata->length = size; + transfer->transactions[0].size = sizeof (*setupdata); transfer->transactions[0].pid = GRUB_USB_TRANSFER_TYPE_SETUP; - transfer->transactions[0].data = (char *) &setupdata; + transfer->transactions[0].data = setupdata_addr; transfer->transactions[0].toggle = 0; /* Now the data... XXX: Is this the right way to transfer control @@ -99,13 +131,13 @@ grub_usb_control_msg (grub_usb_device_t dev, tr->pid = GRUB_USB_TRANSFER_TYPE_IN; else tr->pid = GRUB_USB_TRANSFER_TYPE_OUT; - tr->data = &data[i * max]; + tr->data = data_addr + i * max; size -= max; } /* End with an empty OUT transaction. */ transfer->transactions[datablocks + 1].size = 0; - transfer->transactions[datablocks + 1].data = NULL; + transfer->transactions[datablocks + 1].data = 0; if (reqtype & 128) transfer->transactions[datablocks + 1].pid = GRUB_USB_TRANSFER_TYPE_OUT; else @@ -117,13 +149,17 @@ grub_usb_control_msg (grub_usb_device_t dev, grub_free (transfer->transactions); grub_free (transfer); + grub_dma_free (data_chunk); + grub_dma_free (setupdata_chunk); + + grub_memcpy (data_in, (char *) data, size0); return err; } static grub_usb_err_t grub_usb_bulk_readwrite (grub_usb_device_t dev, - int endpoint, grub_size_t size, char *data, + int endpoint, grub_size_t size0, char *data_in, grub_transfer_type_t type) { int i; @@ -132,6 +168,19 @@ grub_usb_bulk_readwrite (grub_usb_device_t dev, unsigned int max; grub_usb_err_t err; int toggle = dev->toggle[endpoint]; + volatile char *data; + grub_uint32_t data_addr; + struct grub_pci_dma_chunk *data_chunk; + grub_size_t size = size0; + + /* FIXME: avoid allocation any kind of buffer in a first place. */ + data_chunk = grub_memalign_dma32 (128, size); + if (!data_chunk) + return GRUB_USB_ERR_INTERNAL; + data = grub_dma_get_virt (data_chunk); + data_addr = grub_dma_get_phys (data_chunk); + if (type == GRUB_USB_TRANSFER_TYPE_OUT) + grub_memcpy ((char *) data, data_in, size); /* Use the maximum packet size given in the endpoint descriptor. */ if (dev->initialized) @@ -150,7 +199,10 @@ grub_usb_bulk_readwrite (grub_usb_device_t dev, /* Create a transfer. */ transfer = grub_malloc (sizeof (struct grub_usb_transfer)); if (! transfer) - return grub_errno; + { + grub_dma_free (data_chunk); + return grub_errno; + } datablocks = ((size + max - 1) / max); transfer->transcnt = datablocks; @@ -167,6 +219,7 @@ grub_usb_bulk_readwrite (grub_usb_device_t dev, if (! transfer->transactions) { grub_free (transfer); + grub_dma_free (data_chunk); return grub_errno; } @@ -181,7 +234,7 @@ grub_usb_bulk_readwrite (grub_usb_device_t dev, tr->toggle = toggle; toggle = toggle ? 0 : 1; tr->pid = type; - tr->data = &data[i * max]; + tr->data = data_addr + i * max; size -= tr->size; } @@ -191,6 +244,10 @@ grub_usb_bulk_readwrite (grub_usb_device_t dev, grub_free (transfer->transactions); grub_free (transfer); + grub_dma_free (data_chunk); + + if (type == GRUB_USB_TRANSFER_TYPE_IN) + grub_memcpy (data_in, (char *) data, size0); return err; } diff --git a/conf/i386.rmk b/conf/i386.rmk index 02ce39817..73e818f9e 100644 --- a/conf/i386.rmk +++ b/conf/i386.rmk @@ -56,6 +56,12 @@ pci_mod_SOURCES = bus/pci.c pci_mod_CFLAGS = $(COMMON_CFLAGS) pci_mod_LDFLAGS = $(COMMON_LDFLAGS) +# For cs5536.mod +pkglib_MODULES += cs5536.mod +cs5536_mod_SOURCES = bus/cs5536.c +cs5536_mod_CFLAGS = $(COMMON_CFLAGS) +cs5536_mod_LDFLAGS = $(COMMON_LDFLAGS) + # For lspci.mod pkglib_MODULES += lspci.mod lspci_mod_SOURCES = commands/lspci.c diff --git a/conf/mips-yeeloong.rmk b/conf/mips-yeeloong.rmk index 5ce8ede9d..2468985c5 100644 --- a/conf/mips-yeeloong.rmk +++ b/conf/mips-yeeloong.rmk @@ -4,7 +4,8 @@ target_machine=yeeloong COMMON_CFLAGS += -march=mips3 COMMON_ASFLAGS += -march=mips3 -kernel_img_HEADERS += pci.h bitmap.h video.h gfxterm.h font.h bitmap_scale.h bufio.h +kernel_img_HEADERS += pci.h bitmap.h video.h gfxterm.h font.h \ + bitmap_scale.h bufio.h cs5536.h machine/pci.h include $(srcdir)/conf/mips.mk @@ -26,6 +27,7 @@ kernel_img_SOURCES = kern/$(target_cpu)/startup.S \ video/fb/fbfill.c video/fb/fbutil.c video/bitmap.c \ video/bitmap_scale.c video/sm712.c bus/pci.c bus/bonito.c \ term/gfxterm.c commands/extcmd.c lib/arg.c \ + bus/cs5536.c \ symlist.c kernel_img_CFLAGS = $(COMMON_CFLAGS) -DUSE_ASCII_FAILBACK kernel_img_ASFLAGS = $(COMMON_ASFLAGS) @@ -69,5 +71,35 @@ linux_mod_CFLAGS = $(COMMON_CFLAGS) linux_mod_ASFLAGS = $(COMMON_ASFLAGS) linux_mod_LDFLAGS = $(COMMON_LDFLAGS) +# For usb.mod +pkglib_MODULES += usb.mod +usb_mod_SOURCES = bus/usb/usb.c bus/usb/usbtrans.c bus/usb/usbhub.c +usb_mod_CFLAGS = $(COMMON_CFLAGS) +usb_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For usbtest.mod +pkglib_MODULES += usbtest.mod +usbtest_mod_SOURCES = commands/usbtest.c +usbtest_mod_CFLAGS = $(COMMON_CFLAGS) +usbtest_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For ohci.mod +pkglib_MODULES += ohci.mod +ohci_mod_SOURCES = bus/usb/ohci.c +ohci_mod_CFLAGS = $(COMMON_CFLAGS) +ohci_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For usbms.mod +pkglib_MODULES += usbms.mod +usbms_mod_SOURCES = disk/usbms.c +usbms_mod_CFLAGS = $(COMMON_CFLAGS) +usbms_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For usb_keyboard.mod +pkglib_MODULES += usb_keyboard.mod +usb_keyboard_mod_SOURCES = term/usb_keyboard.c +usb_keyboard_mod_CFLAGS = $(COMMON_CFLAGS) +usb_keyboard_mod_LDFLAGS = $(COMMON_LDFLAGS) + sbin_SCRIPTS += grub-install grub_install_SOURCES = util/grub-install.in diff --git a/include/grub/cs5536.h b/include/grub/cs5536.h new file mode 100644 index 000000000..cd17e11fc --- /dev/null +++ b/include/grub/cs5536.h @@ -0,0 +1,190 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_CS5536_HEADER +#define GRUB_CS5536_HEADER 1 + +#ifndef ASM_FILE +#include +#include +#include +#endif + +#define GRUB_CS5536_PCIID 0x208f1022 +#define GRUB_CS5536_MSR_MAILBOX_ADDR 0xf4 +#define GRUB_CS5536_MSR_MAILBOX_DATA0 0xf8 +#define GRUB_CS5536_MSR_MAILBOX_DATA1 0xfc +#define GRUB_CS5536_MSR_IRQ_MAP_BAR 0x80000008 +#define GRUB_CS5536_MSR_SMB_BAR 0x8000000b + +#define GRUB_CS5536_SMBUS_REGS_SIZE 8 +#define GRUB_CS5536_GPIO_REGS_SIZE 256 +#define GRUB_CS5536_MFGPT_REGS_SIZE 64 +#define GRUB_CS5536_IRQ_MAP_REGS_SIZE 32 +#define GRUB_CS5536_PM_REGS_SIZE 128 +#define GRUB_CS5536_ACPI_REGS_SIZE 32 + +#define GRUB_CS5536_USB_OPTION_REGS_SIZE 0x1c +#define GRUB_CS5536_USB_OPTION_REG_UOCMUX 1 +#define GRUB_CS5536_USB_OPTION_REG_UOCMUX_PMUX_MASK 0x03 +#define GRUB_CS5536_USB_OPTION_REG_UOCMUX_PMUX_HC 0x02 + +#define GRUB_CS5536_DESTINATION_GLIU 0 +#define GRUB_CS5536_DESTINATION_GLPCI_SB 1 +#define GRUB_CS5536_DESTINATION_USB 2 +#define GRUB_CS5536_DESTINATION_IDE 3 +#define GRUB_CS5536_DESTINATION_DD 4 +#define GRUB_CS5536_DESTINATION_ACC 5 +#define GRUB_CS5536_DESTINATION_GLCP 7 + +#define GRUB_CS5536_P2D_DEST_SHIFT 61 +#define GRUB_CS5536_P2D_LOG_ALIGN 12 +#define GRUB_CS5536_P2D_ALIGN (1 << GRUB_CS5536_P2D_LOG_ALIGN) +#define GRUB_CS5536_P2D_BASE_SHIFT 20 +#define GRUB_CS5536_P2D_MASK_SHIFT 0 + +#define GRUB_CS5536_MSR_GL_IOD_START 0x000100e0 +#define GRUB_CS5536_IOD_DEST_SHIFT 61 +#define GRUB_CS5536_IOD_BASE_SHIFT 20 +#define GRUB_CS5536_IOD_MASK_SHIFT 0 +#define GRUB_CS5536_IOD_ADDR_MASK 0xfffff + +#define GRUB_CS5536_MSR_GPIO_BAR 0x8000000c +#define GRUB_CS5536_MSR_MFGPT_BAR 0x8000000d +#define GRUB_CS5536_MSR_ACPI_BAR 0x8000000e +#define GRUB_CS5536_MSR_PM_BAR 0x8000000f +#define GRUB_CS5536_MSR_DIVIL_LEG_IO 0x80000014 +#define GRUB_CS5536_MSR_DIVIL_LEG_IO_RTC_ENABLE0 0x00000001 +#define GRUB_CS5536_MSR_DIVIL_LEG_IO_RTC_ENABLE1 0x00000002 +#define GRUB_CS5536_MSR_DIVIL_LEG_IO_MODE_X86 0x10000000 +#define GRUB_CS5536_MSR_DIVIL_LEG_IO_F_REMAP 0x04000000 +#define GRUB_CS5536_MSR_DIVIL_IRQ_MAPPER_PRIMARY_MASK 0x80000024 +#define GRUB_CS5536_MSR_DIVIL_IRQ_MAPPER_LPC_MASK 0x80000025 +#define GRUB_CS5536_DIVIL_LPC_INTERRUPTS 0x1002 +#define GRUB_CS5536_MSR_DIVIL_LPC_SERIAL_IRQ_CONTROL 0x8000004e +#define GRUB_CS5536_MSR_DIVIL_LPC_SERIAL_IRQ_CONTROL_ENABLE 0x80 + +#define GRUB_CS5536_MSR_USB_OHCI_BASE 0x40000008 +#define GRUB_CS5536_MSR_USB_EHCI_BASE 0x40000009 +#define GRUB_CS5536_MSR_USB_CONTROLLER_BASE 0x4000000a +#define GRUB_CS5536_MSR_USB_OPTION_CONTROLLER_BASE 0x4000000b +#define GRUB_CS5536_MSR_USB_BASE_ADDR_MASK 0x00ffffff00ULL +#define GRUB_CS5536_MSR_USB_BASE_BUS_MASTER 0x0400000000ULL +#define GRUB_CS5536_MSR_USB_BASE_MEMORY_ENABLE 0x0200000000ULL +#define GRUB_CS5536_MSR_USB_BASE_PME_ENABLED 0x0800000000ULL +#define GRUB_CS5536_MSR_USB_BASE_PME_STATUS 0x1000000000ULL +#define GRUB_CS5536_MSR_USB_EHCI_BASE_FLDJ_SHIFT 40 + +#define GRUB_CS5536_MSR_IDE_IO_BAR 0x60000008 +#define GRUB_CS5536_MSR_IDE_IO_BAR_UNITS 1 +#define GRUB_CS5536_MSR_IDE_IO_BAR_ADDR_MASK 0xfffffff0 +#define GRUB_CS5536_MSR_IDE_CFG 0x60000010 +#define GRUB_CS5536_MSR_IDE_CFG_CHANNEL_ENABLE 2 +#define GRUB_CS5536_MSR_IDE_TIMING 0x60000012 +#define GRUB_CS5536_MSR_IDE_TIMING_PIO0 0x98 +#define GRUB_CS5536_MSR_IDE_TIMING_DRIVE0_SHIFT 24 +#define GRUB_CS5536_MSR_IDE_TIMING_DRIVE1_SHIFT 16 +#define GRUB_CS5536_MSR_IDE_CAS_TIMING 0x60000013 +#define GRUB_CS5536_MSR_IDE_CAS_TIMING_CMD_PIO0 0x99 +#define GRUB_CS5536_MSR_IDE_CAS_TIMING_CMD_SHIFT 24 +#define GRUB_CS5536_MSR_IDE_CAS_TIMING_DRIVE0_SHIFT 6 +#define GRUB_CS5536_MSR_IDE_CAS_TIMING_DRIVE1_SHIFT 4 +#define GRUB_CS5536_MSR_IDE_CAS_TIMING_PIO0 2 + +#define GRUB_CS5536_MSR_GL_PCI_CTRL 0x00000010 +#define GRUB_CS5536_MSR_GL_PCI_CTRL_MEMORY_ENABLE 1 +#define GRUB_CS5536_MSR_GL_PCI_CTRL_IO_ENABLE 2 +#define GRUB_CS5536_MSR_GL_PCI_CTRL_LATENCY_SHIFT 35 +#define GRUB_CS5536_MSR_GL_PCI_CTRL_OUT_THR_SHIFT 60 +#define GRUB_CS5536_MSR_GL_PCI_CTRL_IN_THR_SHIFT 56 + +#define GRUB_CS5536_MSR_GL_REGIONS_START 0x00000020 +#define GRUB_CS5536_MSR_GL_REGIONS_NUM 16 +#define GRUB_CS5536_MSR_GL_REGION_ENABLE 1 +#define GRUB_CS5536_MSR_GL_REGION_IO 0x100000000ULL +#define GRUB_CS5536_MSR_GL_REGION_BASE_MASK 0xfffff000ULL +#define GRUB_CS5536_MSR_GL_REGION_IO_BASE_SHIFT 12 +#define GRUB_CS5536_MSR_GL_REGION_TOP_MASK 0xfffff00000000000ULL +#define GRUB_CS5536_MSR_GL_REGION_IO_TOP_SHIFT 44 + +#define GRUB_CS5536_MSR_GL_P2D_START 0x00010020 + +#define GRUB_CS5536_SMB_REG_DATA 0x0 +#define GRUB_CS5536_SMB_REG_STATUS 0x1 +#define GRUB_CS5536_SMB_REG_STATUS_SDAST (1 << 6) +#define GRUB_CS5536_SMB_REG_STATUS_BER (1 << 5) +#define GRUB_CS5536_SMB_REG_STATUS_NACK (1 << 4) +#define GRUB_CS5536_SMB_REG_CTRL1 0x3 +#define GRUB_CS5536_SMB_REG_CTRL1_START 0x01 +#define GRUB_CS5536_SMB_REG_CTRL1_STOP 0x02 +#define GRUB_CS5536_SMB_REG_CTRL1_ACK 0x10 +#define GRUB_CS5536_SMB_REG_ADDR 0x4 +#define GRUB_CS5536_SMB_REG_ADDR_MASTER 0x0 +#define GRUB_CS5536_SMB_REG_CTRL2 0x5 +#define GRUB_CS5536_SMB_REG_CTRL2_ENABLE 0x1 +#define GRUB_CS5536_SMB_REG_CTRL3 0x6 + +#ifdef ASM_FILE +#define GRUB_ULL(x) x +#else +#define GRUB_ULL(x) x ## ULL +#endif + +#define GRUB_CS5536_LBAR_ADDR_MASK GRUB_ULL (0x000000000000fff8) +#define GRUB_CS5536_LBAR_ENABLE GRUB_ULL (0x0000000100000000) +#define GRUB_CS5536_LBAR_MASK_MASK GRUB_ULL (0x0000f00000000000) +#define GRUB_CS5536_LBAR_TURN_ON (GRUB_CS5536_LBAR_ENABLE | GRUB_CS5536_LBAR_MASK_MASK) + +/* PMON-compatible LBARs. */ +#define GRUB_CS5536_LBAR_GPIO 0xb000 +#define GRUB_CS5536_LBAR_ACC 0xb200 +#define GRUB_CS5536_LBAR_PM 0xb280 +#define GRUB_CS5536_LBAR_MFGPT 0xb300 +#define GRUB_CS5536_LBAR_ACPI 0xb340 +#define GRUB_CS5536_LBAR_IRQ_MAP 0xb360 +#define GRUB_CS5536_LBAR_IDE 0xb380 +#define GRUB_CS5536_LBAR_SMBUS 0xb390 + +#define GRUB_GPIO_SMBUS_PINS ((1 << 14) | (1 << 15)) +#define GRUB_GPIO_REG_OUT_EN 0x4 +#define GRUB_GPIO_REG_OUT_AUX1 0x10 +#define GRUB_GPIO_REG_IN_EN 0x20 +#define GRUB_GPIO_REG_IN_AUX1 0x34 + +#ifndef ASM_FILE +int EXPORT_FUNC (grub_cs5536_find) (grub_pci_device_t *devp); + +grub_uint64_t EXPORT_FUNC (grub_cs5536_read_msr) (grub_pci_device_t dev, + grub_uint32_t addr); +void EXPORT_FUNC (grub_cs5536_write_msr) (grub_pci_device_t dev, + grub_uint32_t addr, + grub_uint64_t val); +grub_err_t grub_cs5536_read_spd_byte (grub_port_t smbbase, grub_uint8_t dev, + grub_uint8_t addr, grub_uint8_t *res); +grub_err_t EXPORT_FUNC (grub_cs5536_read_spd) (grub_port_t smbbase, + grub_uint8_t dev, + struct grub_smbus_spd *res); +grub_err_t grub_cs5536_smbus_wait (grub_port_t smbbase); +grub_err_t EXPORT_FUNC (grub_cs5536_init_smbus) (grub_pci_device_t dev, + grub_uint16_t divisor, + grub_port_t *smbbase); + +void grub_cs5536_init_geode (grub_pci_device_t dev); +#endif + +#endif diff --git a/include/grub/i386/pci.h b/include/grub/i386/pci.h index bab42adb6..795dec58b 100644 --- a/include/grub/i386/pci.h +++ b/include/grub/i386/pci.h @@ -80,7 +80,7 @@ grub_pci_device_map_range (grub_pci_device_t dev __attribute__ ((unused)), static inline void grub_pci_device_unmap_range (grub_pci_device_t dev __attribute__ ((unused)), - void *mem __attribute__ ((unused)), + volatile void *mem __attribute__ ((unused)), grub_size_t size __attribute__ ((unused))) { } diff --git a/include/grub/mips/yeeloong/pci.h b/include/grub/mips/yeeloong/pci.h index c7bd31d4f..199bac048 100644 --- a/include/grub/mips/yeeloong/pci.h +++ b/include/grub/mips/yeeloong/pci.h @@ -19,16 +19,30 @@ #ifndef GRUB_MACHINE_PCI_H #define GRUB_MACHINE_PCI_H 1 +#ifndef ASM_FILE #include #include +#endif + +#define GRUB_YEELOONG_OHCI_PCIID 0x00351033 +#define GRUB_YEELOONG_EHCI_PCIID 0x00e01033 +#define GRUB_YEELOONG_OHCI_GHOST_FUNCTION 4 +#define GRUB_YEELOONG_EHCI_GHOST_FUNCTION 5 #define GRUB_PCI_NUM_BUS 1 #define GRUB_PCI_NUM_DEVICES 16 -#define GRUB_MACHINE_PCI_IO_BASE 0xbfd00000 -#define GRUB_MACHINE_PCI_CONFSPACE 0xbfe80000 -#define GRUB_MACHINE_PCI_CONF_CTRL_REG (*(volatile grub_uint32_t *) 0xbfe00118) +#define GRUB_MACHINE_PCI_IO_BASE 0xbfd00000 +#define GRUB_MACHINE_PCI_CONFSPACE 0xbfe80000 +#define GRUB_MACHINE_PCI_CONTROLLER_HEADER 0xbfe00000 + +#define GRUB_MACHINE_PCI_CONF_CTRL_REG_ADDR 0xbfe00118 + +#ifndef ASM_FILE +#define GRUB_MACHINE_PCI_CONF_CTRL_REG (*(volatile grub_uint32_t *) \ + GRUB_MACHINE_PCI_CONF_CTRL_REG_ADDR) #define GRUB_MACHINE_PCI_IO_CTRL_REG (*(volatile grub_uint32_t *) 0xbfe00110) +#endif #define GRUB_MACHINE_PCI_WIN_MASK_SIZE 6 #define GRUB_MACHINE_PCI_WIN_MASK ((1 << GRUB_MACHINE_PCI_WIN_MASK_SIZE) - 1) @@ -46,6 +60,7 @@ #define GRUB_MACHINE_PCI_WIN2_ADDR 0xb4000000 #define GRUB_MACHINE_PCI_WIN3_ADDR 0xb8000000 +#ifndef ASM_FILE static inline grub_uint32_t grub_pci_read (grub_pci_address_t addr) { @@ -95,11 +110,12 @@ grub_pci_write_byte (grub_pci_address_t addr, grub_uint8_t data) } volatile void * -grub_pci_device_map_range (grub_pci_device_t dev __attribute__ ((unused)), - grub_addr_t base, grub_size_t size); +EXPORT_FUNC (grub_pci_device_map_range) (grub_pci_device_t dev, + grub_addr_t base, grub_size_t size); void -grub_pci_device_unmap_range (grub_pci_device_t dev __attribute__ ((unused)), - volatile void *mem, - grub_size_t size __attribute__ ((unused))); +EXPORT_FUNC (grub_pci_device_unmap_range) (grub_pci_device_t dev, + volatile void *mem, + grub_size_t size); +#endif #endif /* GRUB_MACHINE_PCI_H */ diff --git a/include/grub/pci.h b/include/grub/pci.h index 89bd1034a..e6d6488f0 100644 --- a/include/grub/pci.h +++ b/include/grub/pci.h @@ -19,8 +19,10 @@ #ifndef GRUB_PCI_H #define GRUB_PCI_H 1 +#ifndef ASM_FILE #include #include +#endif #define GRUB_PCI_ADDR_SPACE_MASK 0x01 #define GRUB_PCI_ADDR_SPACE_MEMORY 0x00 @@ -66,6 +68,20 @@ #define GRUB_PCI_REG_MIN_GNT 0x3e #define GRUB_PCI_REG_MAX_LAT 0x3f +#define GRUB_PCI_COMMAND_IO_ENABLED 0x0001 +#define GRUB_PCI_COMMAND_MEM_ENABLED 0x0002 +#define GRUB_PCI_COMMAND_BUS_MASTER 0x0004 +#define GRUB_PCI_COMMAND_PARITY_ERROR 0x0040 +#define GRUB_PCI_COMMAND_SERR_ENABLE 0x0100 + +#define GRUB_PCI_STATUS_CAPABILITIES 0x0010 +#define GRUB_PCI_STATUS_66MHZ_CAPABLE 0x0020 +#define GRUB_PCI_STATUS_FAST_B2B_CAPABLE 0x0080 + +#define GRUB_PCI_STATUS_DEVSEL_TIMING_SHIFT 9 +#define GRUB_PCI_STATUS_DEVSEL_TIMING_MASK 0x0600 + +#ifndef ASM_FILE typedef grub_uint32_t grub_pci_id_t; #ifdef GRUB_MACHINE_EMU @@ -107,4 +123,14 @@ grub_pci_address_t EXPORT_FUNC(grub_pci_make_address) (grub_pci_device_t dev, void EXPORT_FUNC(grub_pci_iterate) (grub_pci_iteratefunc_t hook); +struct grub_pci_dma_chunk; + +struct grub_pci_dma_chunk *EXPORT_FUNC(grub_memalign_dma32) (grub_size_t align, + grub_size_t size); +void EXPORT_FUNC(grub_dma_free) (struct grub_pci_dma_chunk *ch); +volatile void *EXPORT_FUNC(grub_dma_get_virt) (struct grub_pci_dma_chunk *ch); +grub_uint32_t EXPORT_FUNC(grub_dma_get_phys) (struct grub_pci_dma_chunk *ch); + +#endif + #endif /* GRUB_PCI_H */ diff --git a/include/grub/smbus.h b/include/grub/smbus.h new file mode 100644 index 000000000..0b8e6718f --- /dev/null +++ b/include/grub/smbus.h @@ -0,0 +1,70 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_SMBUS_HEADER +#define GRUB_SMBUS_HEADER 1 + +#define GRUB_SMB_RAM_START_ADDR 0x50 +#define GRUB_SMB_RAM_NUM_MAX 0x08 + +#define GRUB_SMBUS_SPD_MEMORY_TYPE_ADDR 2 +#define GRUB_SMBUS_SPD_MEMORY_TYPE_DDR2 8 +#define GRUB_SMBUS_SPD_MEMORY_NUM_BANKS_ADDR 17 +#define GRUB_SMBUS_SPD_MEMORY_NUM_ROWS_ADDR 3 +#define GRUB_SMBUS_SPD_MEMORY_NUM_COLUMNS_ADDR 4 +#define GRUB_SMBUS_SPD_MEMORY_NUM_OF_RANKS_ADDR 5 +#define GRUB_SMBUS_SPD_MEMORY_NUM_OF_RANKS_MASK 0x7 +#define GRUB_SMBUS_SPD_MEMORY_CAS_LATENCY_ADDR 18 +#define GRUB_SMBUS_SPD_MEMORY_CAS_LATENCY_MIN_VALUE 5 +#define GRUB_SMBUS_SPD_MEMORY_TRAS_ADDR 30 +#define GRUB_SMBUS_SPD_MEMORY_TRTP_ADDR 38 + +#ifndef ASM_FILE + +struct grub_smbus_spd +{ + grub_uint8_t written_size; + grub_uint8_t log_total_flash_size; + grub_uint8_t memory_type; + union + { + grub_uint8_t unknown[253]; + struct { + grub_uint8_t num_rows; + grub_uint8_t num_columns; + grub_uint8_t num_of_ranks; + grub_uint8_t unused1[12]; + grub_uint8_t num_of_banks; + grub_uint8_t unused2[2]; + grub_uint8_t cas_latency; + grub_uint8_t unused3[9]; + grub_uint8_t rank_capacity; + grub_uint8_t unused4[1]; + grub_uint8_t tras; + grub_uint8_t unused5[7]; + grub_uint8_t trtp; + grub_uint8_t unused6[31]; + grub_uint8_t part_number[18]; + grub_uint8_t unused7[165]; + } ddr2; + }; +}; + +#endif + +#endif diff --git a/include/grub/usbtrans.h b/include/grub/usbtrans.h index 7e4a9d7ee..8c739684e 100644 --- a/include/grub/usbtrans.h +++ b/include/grub/usbtrans.h @@ -37,7 +37,7 @@ struct grub_usb_transaction int size; int toggle; grub_transfer_type_t pid; - char *data; + grub_uint32_t data; }; typedef struct grub_usb_transaction *grub_usb_transaction_t; From 7fd08f56ae0d5f76e5f5c7a184414ae8e0e36a91 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 31 May 2010 14:01:38 +0200 Subject: [PATCH 684/738] Shut down OHCI on booting --- bus/usb/ohci.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/bus/usb/ohci.c b/bus/usb/ohci.c index 7294fe537..29ab5332a 100644 --- a/bus/usb/ohci.c +++ b/bus/usb/ohci.c @@ -654,6 +654,39 @@ grub_ohci_hubports (grub_usb_controller_t dev) return portinfo & 0xFF; } +static grub_err_t +grub_ohci_fini_hw (int noreturn __attribute__ ((unused))) +{ + struct grub_ohci *o; + + for (o = ohci; o; o = o->next) + { + int i, nports = grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBA) & 0xff; + for (i = 0; i < nports; i++) + grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + i, + GRUB_OHCI_CLEAR_PORT_ENABLE); + + grub_ohci_writereg32 (o, GRUB_OHCI_REG_HCCA, 0); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD, 0); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLCURR, 0); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKHEAD, 0); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKCURR, 0); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_DONEHEAD, 0); + } + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_ohci_restore_hw (void) +{ + struct grub_ohci *o; + + for (o = ohci; o; o = o->next) + grub_ohci_writereg32 (o, GRUB_OHCI_REG_HCCA, o->hcca_addr); + + return GRUB_ERR_NONE; +} static struct grub_usb_controller_dev usb_controller = @@ -670,9 +703,12 @@ GRUB_MOD_INIT(ohci) { grub_ohci_inithw (); grub_usb_controller_dev_register (&usb_controller); + grub_loader_register_preboot_hook (grub_ohci_fini_hw, grub_ohci_restore_hw, + GRUB_LOADER_PREBOOT_HOOK_PRIO_DISK); } GRUB_MOD_FINI(ohci) { + grub_ohci_fini_hw (0); grub_usb_controller_dev_unregister (&usb_controller); } From 778ff32476c08a69d99e56fbfe9e7494e0c26bdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ale=C5=A1=20Nesrsta?= Date: Mon, 31 May 2010 14:11:41 +0200 Subject: [PATCH 685/738] Fix a bunch of problems with USB. --- bus/usb/ohci.c | 342 +++++++++++++++++++++++++++++++--------- bus/usb/uhci.c | 17 +- bus/usb/usb.c | 12 +- bus/usb/usbtrans.c | 5 +- commands/usbtest.c | 2 + disk/scsi.c | 183 +++++++++++++++++++-- disk/usbms.c | 166 ++++++++++++------- include/grub/scsicmd.h | 62 ++++++-- include/grub/usb.h | 9 +- include/grub/usbtrans.h | 6 +- 10 files changed, 637 insertions(+), 167 deletions(-) diff --git a/bus/usb/ohci.c b/bus/usb/ohci.c index 29ab5332a..03768d39e 100644 --- a/bus/usb/ohci.c +++ b/bus/usb/ohci.c @@ -27,6 +27,7 @@ #include #include #include +#include struct grub_ohci_hcca { @@ -96,7 +97,11 @@ typedef enum GRUB_OHCI_REG_FRAME_INTERVAL, GRUB_OHCI_REG_PERIODIC_START = 16, GRUB_OHCI_REG_RHUBA = 18, - GRUB_OHCI_REG_RHUBPORT = 21 + GRUB_OHCI_REG_RHUBPORT = 21, + GRUB_OHCI_REG_LEGACY_CONTROL = 0x100, + GRUB_OHCI_REG_LEGACY_INPUT = 0x104, + GRUB_OHCI_REG_LEGACY_OUTPUT = 0x108, + GRUB_OHCI_REG_LEGACY_STATUS = 0x10c } grub_ohci_reg_t; #define GRUB_OHCI_RHUB_PORT_POWER_MASK 0x300 @@ -195,7 +200,7 @@ grub_ohci_pci_iter (grub_pci_device_t dev, if (! o) return 1; - o->iobase = grub_pci_device_map_range (dev, base, 0x100); + o->iobase = grub_pci_device_map_range (dev, base, 0x800); grub_dprintf ("ohci", "base=%p\n", o->iobase); @@ -212,10 +217,48 @@ grub_ohci_pci_iter (grub_pci_device_t dev, if ((revision & 0xFF) != 0x10) goto fail; - grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBA, - (grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBA) - & ~GRUB_OHCI_RHUB_PORT_POWER_MASK) - | GRUB_OHCI_RHUB_PORT_ALL_POWERED); + + { + grub_uint32_t control; + /* Check SMM/BIOS ownership of OHCI (SMM = USB Legacy Support driver for BIOS) */ + control = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL); + if ((control & 0x100) != 0) + { + unsigned i; + grub_dprintf("ohci", "OHCI is owned by SMM\n"); + /* Do change of ownership */ + /* Ownership change request */ + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, (1<<3)); /* XXX: Magic. */ + /* Waiting for SMM deactivation */ + for (i=0; i < 10; i++) + { + if ((grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL) & 0x100) == 0) + { + grub_dprintf("ohci", "Ownership changed normally.\n"); + break; + } + grub_millisleep (100); + } + if (i >= 10) + { + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, + grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL) & ~0x100); + grub_dprintf("ohci", "Ownership changing timeout, change forced !\n"); + } + } + else if (((control & 0x100) == 0) && + ((control & 0xc0) != 0)) /* Not owned by SMM nor reset */ + { + grub_dprintf("ohci", "OHCI is owned by BIOS\n"); + /* Do change of ownership - not implemented yet... */ + /* In fact we probably need to do nothing ...? */ + } + else + { + grub_dprintf("ohci", "OHCI is not owned by SMM nor BIOS\n"); + /* We can setup OHCI. */ + } + } /* Suspend the OHCI by issuing a reset. */ grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, 1); /* XXX: Magic. */ @@ -232,15 +275,58 @@ grub_ohci_pci_iter (grub_pci_device_t dev, GRUB_OHCI_PERIODIC_START); /* Setup the HCCA. */ + o->hcca->donehead = 0; grub_ohci_writereg32 (o, GRUB_OHCI_REG_HCCA, o->hcca_addr); grub_dprintf ("ohci", "OHCI HCCA\n"); + /* Misc. pre-sets. */ + o->hcca->donehead = 0; + grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1 << 1)); /* Clears WDH */ + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD, 0); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLCURR, 0); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKHEAD, 0); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKCURR, 0); + + /* Check OHCI Legacy Support */ + if ((revision & 0x100) != 0) + { + grub_dprintf ("ohci", "Legacy Support registers detected\n"); + grub_dprintf ("ohci", "Current state of legacy control reg.: 0x%04x\n", + grub_ohci_readreg32 (o, GRUB_OHCI_REG_LEGACY_CONTROL)); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_LEGACY_CONTROL, + (grub_ohci_readreg32 (o, GRUB_OHCI_REG_LEGACY_CONTROL)) & ~1); + grub_dprintf ("ohci", "OHCI Legacy Support disabled.\n"); + } + /* Enable the OHCI. */ grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, (2 << 6)); grub_dprintf ("ohci", "OHCI enable: 0x%02x\n", (grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL) >> 6) & 3); + /* Power on all ports */ + grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBA, + (grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBA) + & ~GRUB_OHCI_RHUB_PORT_POWER_MASK) + | GRUB_OHCI_RHUB_PORT_ALL_POWERED); + /* Wait for stable power (100ms) and stable attachment (100ms) */ + /* I.e. minimum wait time should be probably 200ms. */ + /* We assume that device is attached when ohci is loaded. */ + /* Some devices take long time to power-on or indicate attach. */ + /* Here is some experimental value which should probably mostly work. */ + /* Cameras with manual USB mode selection and maybe some other similar + * devices will not work in some cases - they are repowered during + * ownership change and then they are starting slowly and mostly they + * are wanting select proper mode again... + * The same situation can be on computers where BIOS not set-up OHCI + * to be at least powered USB bus (maybe it is Yeelong case...?) + * Possible workaround could be for example some prompt + * for user with confirmation of proper USB device connection. + * Another workaround - "rmmod usbms", "rmmod ohci", proper start + * and configuration of USB device and then "insmod ohci" + * and "insmod usbms". */ + grub_millisleep (500); + /* Link to ohci now that initialisation is successful. */ o->next = ohci; ohci = o; @@ -317,13 +403,29 @@ grub_ohci_transaction (grub_ohci_td_t td, token |= toggle << 24; token |= 1 << 25; + /* Set "Not accessed" error code */ + token |= 15 << 28; + buffer = data; buffer_end = buffer + size - 1; + /* Set correct buffer values in TD if zero transfer occurs */ + if (size) + { + buffer = (grub_uint32_t) data; + buffer_end = buffer + size - 1; + td->buffer = grub_cpu_to_le32 (buffer); + td->buffer_end = grub_cpu_to_le32 (buffer_end); + } + else + { + td->buffer = 0; + td->buffer_end = 0; + } + + /* Set the rest of TD */ td->token = grub_cpu_to_le32 (token); - td->buffer = grub_cpu_to_le32 (buffer); td->next_td = 0; - td->buffer_end = grub_cpu_to_le32 (buffer_end); } static grub_usb_err_t @@ -342,7 +444,9 @@ grub_ohci_transfer (grub_usb_controller_t dev, grub_uint32_t status; grub_uint32_t control; grub_usb_err_t err; - int i; + int i, j; + grub_uint64_t maxtime; + int err_timeout = 0; /* Allocate an Endpoint Descriptor. */ ed_chunk = grub_memalign_dma32 (256, sizeof (*ed)); @@ -375,13 +479,25 @@ grub_ohci_transfer (grub_usb_controller_t dev, + (i + 1) * sizeof (td_list[0])); } + /* The last-1 TD token we should change to enable interrupt when TD finishes. + * As OHCI interrupts are disabled, it does only setting of WDH bit in + * HcInterruptStatus register - and that is what we want to safely detect + * normal end of all transactions. */ + td_list[transfer->transcnt - 1].token &= ~(7 << 21); + + td_list[transfer->transcnt].token = 0; + td_list[transfer->transcnt].buffer = 0; + td_list[transfer->transcnt].buffer_end = 0; + td_list[transfer->transcnt].next_td = + (grub_uint32_t) &td_list[transfer->transcnt]; + /* Setup the Endpoint Descriptor. */ /* Set the device address. */ target = transfer->devaddr; - /* Set the endpoint. */ - target |= transfer->endpoint << 7; + /* Set the endpoint. It should be masked, we need 4 bits only. */ + target |= (transfer->endpoint & 15) << 7; /* Set the device speed. */ target |= (transfer->dev->speed == GRUB_USB_SPEED_LOW) << 13; @@ -400,6 +516,30 @@ grub_ohci_transfer (grub_usb_controller_t dev, grub_dprintf ("ohci", "program OHCI\n"); + /* Disable the Control and Bulk lists. */ + control = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL); + control &= ~(3 << 4); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, control); + + /* Clear BulkListFilled and ControlListFilled. */ + status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS); + status &= ~(3 << 1); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, status); + + /* Now we should wait for start of next frame. Because we are not using + * interrupt, we reset SF bit and wait when it goes to 1. */ + /* SF bit reset. (SF bit indicates Start Of Frame (SOF) packet) */ + grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1<<2)); + /* Wait for new SOF */ + while ((grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS) & 0x4) == 0); + /* Now it should be safe to change CONTROL and BULK lists. */ + + /* This we do for safety's sake - it should be done in previous call + * of grub_ohci_transfer and nobody should change it in meantime... + * It should be done before start of control or bulk OHCI list. */ + o->hcca->donehead = 0; + grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1 << 1)); /* Clears WDH */ + /* Program the OHCI to actually transfer. */ switch (transfer->type) { @@ -407,24 +547,17 @@ grub_ohci_transfer (grub_usb_controller_t dev, { grub_dprintf ("ohci", "add to bulk list\n"); - status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS); - control = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL); - - /* Disable the Control and Bulk lists. */ - control &= ~(3 << 4); - grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, control); - - /* Clear BulkListFilled. */ - status &= ~(1 << 2); - grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, status); - + /* Set BulkList Head and Current */ grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKHEAD, ed_addr); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKCURR, 0); /* Enable the Bulk list. */ + control = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL); control |= 1 << 5; grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, control); /* Set BulkListFilled. */ + status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS); status |= 1 << 2; grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, status); @@ -433,21 +566,9 @@ grub_ohci_transfer (grub_usb_controller_t dev, case GRUB_USB_TRANSACTION_TYPE_CONTROL: { - grub_dprintf ("ohci", "add to control list\n"); - status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS); - control = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL); - - /* Disable the Control and Bulk lists. */ - control &= ~(3 << 4); - grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, control); - - /* Clear ControlListFilled. */ - status &= ~(1 << 1); - grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, status); - + /* Set ControlList Head and Current */ grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD, ed_addr); - grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD+1, - ed_addr); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLCURR, 0); /* Enable the Control list. */ control |= 1 << 4; @@ -465,36 +586,77 @@ grub_ohci_transfer (grub_usb_controller_t dev, grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL), grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS)); + /* Safety measure to avoid a hang. */ + maxtime = grub_get_time_ms () + 1000; + /* Wait until the transfer is completed or STALLs. */ - while ((ed->td_head & ~0xf) != (ed->td_tail & ~0xf)) + do { grub_cpu_idle (); - grub_dprintf ("ohci", "head=0x%02x tail=0x%02x\n", ed->td_head, ed->td_tail); + /* Detected a HALT. */ + if (grub_le_to_cpu32 (ed->td_head) & 1) + break; + + if ((grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS) & 0x2) != 0) + { + if ((grub_le_to_cpu32 (o->hcca->donehead) & ~0xf) + == td_list_addr + (transfer->transcnt - 1) * sizeof (td_list[0])) + break; - /* Detected a STALL. */ - if (ed->td_head & 1) + /* Done Head can be updated on some another place if ED is halted. */ + if (grub_le_to_cpu32 (ed->td_head) & 1) + break; + + /* If there is not HALT in ED, it is not correct, so debug it, reset + * donehead and WDH and continue waiting. */ + grub_dprintf ("ohci", "Incorrect HccaDoneHead=0x%08x\n", + o->hcca->donehead); + o->hcca->donehead = 0; + grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1 << 1)); + continue; + } + /* Timeout ? */ + if (grub_get_time_ms () > maxtime) + { + /* Disable the Control and Bulk lists. */ + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, + grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL) & ~(3 << 4)); + err_timeout = 1; + break; + } + + if ((ed->td_head & ~0xf) == (ed->td_tail & ~0xf)) break; } + while (1); - grub_dprintf ("ohci", "complete\n"); - -/* if (ed->td_head & 1) */ -/* err = GRUB_USB_ERR_STALL; */ -/* else if (ed->td */ - - - if (ed->td_head & 1) + if (err_timeout) + { + err = GRUB_ERR_TIMEOUT; + grub_dprintf("ohci", "Timeout, target=%08x, head=%08x\n\t\ttail=%08x, next=%08x\n", + grub_le_to_cpu32(ed->target), + grub_le_to_cpu32(ed->td_head), + grub_le_to_cpu32(ed->td_tail), + grub_le_to_cpu32(ed->next_ed)); + } + else if (grub_le_to_cpu32 (ed->td_head) & 1) { - grub_uint8_t errcode; - grub_ohci_td_t tderr; grub_uint32_t td_err_addr; + grub_uint8_t errcode; + grub_ohci_td_t tderr = NULL; - td_err_addr = grub_ohci_readreg32 (o, GRUB_OHCI_REG_DONEHEAD); + td_err_addr = (grub_ohci_readreg32 (o, GRUB_OHCI_REG_DONEHEAD) & ~0xf); + if (td_err_addr == 0) + /* If DONEHEAD==0 it means that correct address is in HCCA. + * It should be always now! */ + td_err_addr = (grub_le_to_cpu32 (o->hcca->donehead) & ~0xf); tderr = (grub_ohci_td_t) ((char *) td_list + (td_err_addr - td_list_addr)); - errcode = tderr->token >> 28; + + errcode = grub_le_to_cpu32 (tderr->token) >> 28; + grub_dprintf ("ohci", "OHCI errcode=0x%02x\n", errcode); switch (errcode) { @@ -540,11 +702,17 @@ grub_ohci_transfer (grub_usb_controller_t dev, case 8: /* XXX: Data overrun error. */ err = GRUB_USB_ERR_DATA; + j = ((grub_uint32_t)tderr - (grub_uint32_t)td_list) / sizeof (*td_list); + grub_dprintf ("ohci", "Overrun, failed TD address: %p, index: %d\n", tderr, j); break; case 9: /* XXX: Data underrun error. */ err = GRUB_USB_ERR_DATA; + grub_dprintf ("ohci", "Underrun, number of not transferred bytes: %d\n", + 1 + grub_le_to_cpu32 (tderr->buffer_end) - grub_le_to_cpu32 (tderr->buffer)); + j = ((grub_uint32_t)tderr - (grub_uint32_t)td_list) / sizeof (*td_list); + grub_dprintf ("ohci", "Underrun, failed TD address: %p, index: %d\n", tderr, j); break; case 10: @@ -582,43 +750,73 @@ grub_ohci_transfer (grub_usb_controller_t dev, /* Clear BulkListFilled and ControlListFilled. */ status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS); - status &= ~((1 << 2) | (1 << 3)); + status &= ~(3 << 1); grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, status); - - /* XXX */ + + /* Set ED to be skipped - for safety */ + ed->target |= grub_cpu_to_le32 (1 << 14); + + /* Now we should wait for start of next frame. + * It is necessary because we will invalidate pointer to ED and it + * can be on OHCI active till SOF! + * Because we are not using interrupt, we reset SF bit and wait when + * it goes to 1. */ + /* SF bit reset. (SF bit indicates Start Of Frame (SOF) packet) */ + grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1<<2)); + /* Wait for new SOF */ + while ((grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS) & 0x4) == 0); + /* Now it should be safe to change CONTROL and BULK lists. */ + + /* Important cleaning. */ + o->hcca->donehead = 0; + grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1 << 1)); /* Clears WDH */ + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD, 0); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLCURR, 0); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKHEAD, 0); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKCURR, 0); + + grub_dprintf ("ohci", "OHCI finished, freeing, err=0x%02x\n", err); + grub_dma_free (td_list_chunk); grub_dma_free (ed_chunk); return err; } +#define GRUB_OHCI_SET_PORT_ENABLE (1 << 1) +#define GRUB_OHCI_CLEAR_PORT_ENABLE (1 << 0) +#define GRUB_OHCI_SET_PORT_RESET (1 << 4) +#define GRUB_OHCI_SET_PORT_RESET_STATUS_CHANGE (1 << 20) + static grub_err_t grub_ohci_portstatus (grub_usb_controller_t dev, unsigned int port, unsigned int enable) { struct grub_ohci *o = (struct grub_ohci *) dev->data; - grub_uint32_t status; - /* Reset the port. */ - status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port); - status |= (1 << 4); /* XXX: Magic. */ - grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port, status); - grub_millisleep (100); + grub_dprintf ("ohci", "begin of portstatus=0x%02x\n", + grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port)); - /* End the reset signaling. */ - status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port); - status |= (1 << 20); /* XXX: Magic. */ - grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port, status); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port, + GRUB_OHCI_SET_PORT_RESET); + grub_millisleep (50); /* For root hub should be nominaly 50ms */ + + /* End the reset signaling. */ + grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port, + GRUB_OHCI_SET_PORT_RESET_STATUS_CHANGE); grub_millisleep (10); - /* Enable the port. */ - status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port); - status |= (enable << 1); /* XXX: Magic. */ - grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port, status); - - status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port); - grub_dprintf ("ohci", "portstatus=0x%02x\n", status); + if (enable) + grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port, + GRUB_OHCI_SET_PORT_ENABLE); + else + grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port, + GRUB_OHCI_CLEAR_PORT_ENABLE); + grub_millisleep (10); + grub_dprintf ("ohci", "end of portstatus=0x%02x\n", + grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port)); + return GRUB_ERR_NONE; } diff --git a/bus/usb/uhci.c b/bus/usb/uhci.c index 6e47c38ef..eb533c926 100644 --- a/bus/usb/uhci.c +++ b/bus/usb/uhci.c @@ -174,14 +174,15 @@ grub_uhci_pci_iter (grub_pci_device_t dev, return 1; u->iobase = base & GRUB_UHCI_IOMASK; - grub_dprintf ("uhci", "class=0x%02x 0x%02x interface 0x%02x base=0x%x\n", - class, subclass, interf, u->iobase); /* Reserve a page for the frame list. */ u->framelist = grub_memalign (4096, 4096); if (! u->framelist) goto fail; + grub_dprintf ("uhci", "class=0x%02x 0x%02x interface 0x%02x base=0x%x framelist=%p\n", + class, subclass, interf, u->iobase, u->framelist); + /* The framelist pointer of UHCI is only 32 bits, make sure this code works on on 64 bits architectures. */ #if GRUB_CPU_SIZEOF_VOID_P == 8 @@ -221,6 +222,9 @@ grub_uhci_pci_iter (grub_pci_device_t dev, } #endif + grub_dprintf ("uhci", "QH=%p, TD=%p\n", + u->qh, u->td); + /* Link all Transfer Descriptors in a list of available Transfer Descriptors. */ for (i = 0; i < 256; i++) @@ -441,6 +445,8 @@ grub_uhci_transfer (grub_usb_controller_t dev, if (! qh) return grub_errno; + grub_dprintf ("uhci", "transfer, iobase:%08x\n", u->iobase); + for (i = 0; i < transfer->transcnt; i++) { grub_usb_transaction_t tr = &transfer->transactions[i]; @@ -548,7 +554,8 @@ grub_uhci_transfer (grub_usb_controller_t dev, fail: - grub_dprintf ("uhci", "transaction failed\n"); + if (err != GRUB_USB_ERR_NONE) + grub_dprintf ("uhci", "transaction failed\n"); /* Place the QH back in the free list and deallocate the associated TDs. */ @@ -583,6 +590,8 @@ grub_uhci_portstatus (grub_usb_controller_t dev, unsigned int status; grub_uint64_t endtime; + grub_dprintf ("uhci", "portstatus, iobase:%08x\n", u->iobase); + grub_dprintf ("uhci", "enable=%d port=%d\n", enable, port); if (port == 0) @@ -631,6 +640,8 @@ grub_uhci_detect_dev (grub_usb_controller_t dev, int port) int reg; unsigned int status; + grub_dprintf ("uhci", "detect_dev, iobase:%08x\n", u->iobase); + if (port == 0) reg = GRUB_UHCI_REG_PORTSC1; else if (port == 1) diff --git a/bus/usb/usb.c b/bus/usb/usb.c index 8289185da..7df148333 100644 --- a/bus/usb/usb.c +++ b/bus/usb/usb.c @@ -107,7 +107,7 @@ grub_usb_set_configuration (grub_usb_device_t dev, int configuration) { int i; - for (i = 0; i < 16; i++) + for (i = 0; i < 256; i++) dev->toggle[i] = 0; return grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT @@ -163,6 +163,16 @@ grub_usb_device_initialize (grub_usb_device_t dev) grub_usb_err_t err; int i; + /* First we have to read first 8 bytes only and determine + * max. size of packet */ + dev->descdev.maxsize0 = 0; /* invalidating, for safety only, can be removed if it is sure it is zero here */ + err = grub_usb_get_descriptor (dev, GRUB_USB_DESCRIPTOR_DEVICE, + 0, 8, (char *) &dev->descdev); + if (err) + return err; + + /* Now we have valid value in dev->descdev.maxsize0, + * so we can read whole device descriptor */ err = grub_usb_get_descriptor (dev, GRUB_USB_DESCRIPTOR_DEVICE, 0, sizeof (struct grub_usb_desc_device), (char *) &dev->descdev); diff --git a/bus/usb/usbtrans.c b/bus/usb/usbtrans.c index f6d3d30f9..0bf5ee6de 100644 --- a/bus/usb/usbtrans.c +++ b/bus/usb/usbtrans.c @@ -138,7 +138,7 @@ grub_usb_control_msg (grub_usb_device_t dev, /* End with an empty OUT transaction. */ transfer->transactions[datablocks + 1].size = 0; transfer->transactions[datablocks + 1].data = 0; - if (reqtype & 128) + if ((reqtype & 128) && datablocks) transfer->transactions[datablocks + 1].pid = GRUB_USB_TRANSFER_TYPE_OUT; else transfer->transactions[datablocks + 1].pid = GRUB_USB_TRANSFER_TYPE_IN; @@ -148,6 +148,7 @@ grub_usb_control_msg (grub_usb_device_t dev, err = dev->controller.dev->transfer (&dev->controller, transfer); grub_free (transfer->transactions); + grub_free (transfer); grub_dma_free (data_chunk); grub_dma_free (setupdata_chunk); @@ -207,7 +208,7 @@ grub_usb_bulk_readwrite (grub_usb_device_t dev, datablocks = ((size + max - 1) / max); transfer->transcnt = datablocks; transfer->size = size - 1; - transfer->endpoint = endpoint; + transfer->endpoint = endpoint & 15; transfer->devaddr = dev->addr; transfer->type = GRUB_USB_TRANSACTION_TYPE_BULK; transfer->max = max; diff --git a/commands/usbtest.c b/commands/usbtest.c index 191c4e4df..7d1f85cfd 100644 --- a/commands/usbtest.c +++ b/commands/usbtest.c @@ -148,6 +148,8 @@ usb_iterate (grub_usb_device_t dev) grub_printf ("%s speed device\n", usb_devspeed[dev->speed]); + return 0; + for (i = 0; i < descdev->configcnt; i++) { struct grub_usb_desc_config *config; diff --git a/disk/scsi.c b/disk/scsi.c index eba237287..e8bfb6a3f 100644 --- a/disk/scsi.c +++ b/disk/scsi.c @@ -25,6 +25,7 @@ #include #include #include +#include static grub_scsi_dev_t grub_scsi_dev_list; @@ -50,7 +51,62 @@ grub_scsi_dev_unregister (grub_scsi_dev_t dev) } -/* Determine the the device is removable and the type of the device +/* Check result of previous operation. */ +static grub_err_t +grub_scsi_request_sense (grub_scsi_t scsi) +{ + struct grub_scsi_request_sense rs; + struct grub_scsi_request_sense_data rsd; + grub_err_t err; + + rs.opcode = grub_scsi_cmd_request_sense; + rs.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT; + rs.reserved1 = 0; + rs.reserved2 = 0; + rs.alloc_length = 0x12; /* XXX: Hardcoded for now */ + rs.control = 0; + grub_memset (rs.pad, 0, sizeof(rs.pad)); + + err = scsi->dev->read (scsi, sizeof (rs), (char *) &rs, + sizeof (rsd), (char *) &rsd); + if (err) + return err; + + return GRUB_ERR_NONE; +} +/* Self commenting... */ +static grub_err_t +grub_scsi_test_unit_ready (grub_scsi_t scsi) +{ + struct grub_scsi_test_unit_ready tur; + grub_err_t err; + grub_err_t err_sense; + + tur.opcode = grub_scsi_cmd_test_unit_ready; + tur.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT; + tur.reserved1 = 0; + tur.reserved2 = 0; + tur.reserved3 = 0; + tur.control = 0; + grub_memset (tur.pad, 0, sizeof(tur.pad)); + + err = scsi->dev->read (scsi, sizeof (tur), (char *) &tur, + 0, NULL); + + /* Each SCSI command should be followed by Request Sense. + If not so, many devices STALLs or definitely freezes. */ + err_sense = grub_scsi_request_sense (scsi); + if (err_sense != GRUB_ERR_NONE) + grub_errno = err; + /* err_sense is ignored for now and Request Sense Data also... */ + + if (err) + return err; + + return GRUB_ERR_NONE; +} + +/* Determine if the device is removable and the type of the device SCSI. */ static grub_err_t grub_scsi_inquiry (grub_scsi_t scsi) @@ -58,15 +114,26 @@ grub_scsi_inquiry (grub_scsi_t scsi) struct grub_scsi_inquiry iq; struct grub_scsi_inquiry_data iqd; grub_err_t err; + grub_err_t err_sense; iq.opcode = grub_scsi_cmd_inquiry; iq.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT; + iq.page = 0; iq.reserved = 0; iq.alloc_length = 0x24; /* XXX: Hardcoded for now */ - iq.reserved2 = 0; + iq.control = 0; + grub_memset (iq.pad, 0, sizeof(iq.pad)); err = scsi->dev->read (scsi, sizeof (iq), (char *) &iq, sizeof (iqd), (char *) &iqd); + + /* Each SCSI command should be followed by Request Sense. + If not so, many devices STALLs or definitely freezes. */ + err_sense = grub_scsi_request_sense (scsi); + if (err_sense != GRUB_ERR_NONE) + grub_errno = err; + /* err_sense is ignored for now and Request Sense Data also... */ + if (err) return err; @@ -83,13 +150,27 @@ grub_scsi_read_capacity (grub_scsi_t scsi) struct grub_scsi_read_capacity rc; struct grub_scsi_read_capacity_data rcd; grub_err_t err; + grub_err_t err_sense; rc.opcode = grub_scsi_cmd_read_capacity; rc.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT; - grub_memset (rc.reserved, 0, sizeof (rc.reserved)); - + rc.logical_block_addr = 0; + rc.reserved1 = 0; + rc.reserved2 = 0; + rc.PMI = 0; + rc.control = 0; + rc.pad = 0; + err = scsi->dev->read (scsi, sizeof (rc), (char *) &rc, sizeof (rcd), (char *) &rcd); + + /* Each SCSI command should be followed by Request Sense. + If not so, many devices STALLs or definitely freezes. */ + err_sense = grub_scsi_request_sense (scsi); + if (err_sense != GRUB_ERR_NONE) + grub_errno = err; +/* err_sense is ignored for now and Request Sense Data also... */ + if (err) return err; @@ -107,6 +188,8 @@ grub_scsi_read10 (grub_disk_t disk, grub_disk_addr_t sector, { grub_scsi_t scsi; struct grub_scsi_read10 rd; + grub_err_t err; + grub_err_t err_sense; scsi = disk->data; @@ -118,7 +201,16 @@ grub_scsi_read10 (grub_disk_t disk, grub_disk_addr_t sector, rd.reserved2 = 0; rd.pad = 0; - return scsi->dev->read (scsi, sizeof (rd), (char *) &rd, size * scsi->blocksize, buf); + err = scsi->dev->read (scsi, sizeof (rd), (char *) &rd, size * scsi->blocksize, buf); + + /* Each SCSI command should be followed by Request Sense. + If not so, many devices STALLs or definitely freezes. */ + err_sense = grub_scsi_request_sense (scsi); + if (err_sense != GRUB_ERR_NONE) + grub_errno = err; + /* err_sense is ignored for now and Request Sense Data also... */ + + return err; } /* Send a SCSI request for DISK: read SIZE sectors starting with @@ -129,6 +221,8 @@ grub_scsi_read12 (grub_disk_t disk, grub_disk_addr_t sector, { grub_scsi_t scsi; struct grub_scsi_read12 rd; + grub_err_t err; + grub_err_t err_sense; scsi = disk->data; @@ -139,7 +233,16 @@ grub_scsi_read12 (grub_disk_t disk, grub_disk_addr_t sector, rd.reserved = 0; rd.control = 0; - return scsi->dev->read (scsi, sizeof (rd), (char *) &rd, size * scsi->blocksize, buf); + err = scsi->dev->read (scsi, sizeof (rd), (char *) &rd, size * scsi->blocksize, buf); + + /* Each SCSI command should be followed by Request Sense. + If not so, many devices STALLs or definitely freezes. */ + err_sense = grub_scsi_request_sense (scsi); + if (err_sense != GRUB_ERR_NONE) + grub_errno = err; + /* err_sense is ignored for now and Request Sense Data also... */ + + return err; } #if 0 @@ -151,6 +254,8 @@ grub_scsi_write10 (grub_disk_t disk, grub_disk_addr_t sector, { grub_scsi_t scsi; struct grub_scsi_write10 wr; + grub_err_t err; + grub_err_t err_sense; scsi = disk->data; @@ -162,7 +267,16 @@ grub_scsi_write10 (grub_disk_t disk, grub_disk_addr_t sector, wr.reserved2 = 0; wr.pad = 0; - return scsi->dev->write (scsi, sizeof (wr), (char *) &wr, size * scsi->blocksize, buf); + err = scsi->dev->write (scsi, sizeof (wr), (char *) &wr, size * scsi->blocksize, buf); + + /* Each SCSI command should be followed by Request Sense. + If not so, many devices STALLs or definitely freezes. */ + err_sense = grub_scsi_request_sense (scsi); + if (err_sense != GRUB_ERR_NONE) + grub_errno = err; + /* err_sense is ignored for now and Request Sense Data also... */ + + return err; } /* Send a SCSI request for DISK: write the data stored in BUF to SIZE @@ -172,7 +286,9 @@ grub_scsi_write12 (grub_disk_t disk, grub_disk_addr_t sector, grub_size_t size, char *buf) { grub_scsi_t scsi; - struct grub_scsi_write10 wr; + struct grub_scsi_write12 wr; + grub_err_t err; + grub_err_t err_sense; scsi = disk->data; @@ -181,9 +297,18 @@ grub_scsi_write12 (grub_disk_t disk, grub_disk_addr_t sector, wr.lba = grub_cpu_to_be32 (sector); wr.size = grub_cpu_to_be32 (size); wr.reserved = 0; - wr.pad = 0; + wr.control = 0; - return scsi->dev->write (scsi, sizeof (wr), (char *) &wr, size * scsi->blocksize, buf); + err = scsi->dev->write (scsi, sizeof (wr), (char *) &wr, size * scsi->blocksize, buf); + + /* Each SCSI command should be followed by Request Sense. + If not so, many devices STALLs or definitely freezes. */ + err_sense = grub_scsi_request_sense (scsi); + if (err_sense != GRUB_ERR_NONE) + grub_errno = err; + /* err_sense is ignored for now and Request Sense Data also... */ + + return err; } #endif @@ -235,6 +360,7 @@ grub_scsi_open (const char *name, grub_disk_t disk) grub_err_t err; int len; int lun; + grub_uint64_t maxtime; scsi = grub_malloc (sizeof (*scsi)); if (! scsi) @@ -292,6 +418,31 @@ grub_scsi_open (const char *name, grub_disk_t disk) else disk->has_partitions = 1; + + /* According to USB MS tests specification, issue Test Unit Ready + * until OK */ + maxtime = grub_get_time_ms () + 1000; + do + { + /* Timeout is necessary - for example in case when we have + * universal card reader with more LUNs and we have only + * one card inserted (or none), so only one LUN (or none) + * will be ready - and we want not to hang... */ + if (grub_get_time_ms () > maxtime) + { + err = GRUB_ERR_READ_ERROR; + grub_free (scsi); + grub_dprintf ("scsi", "LUN is not ready - timeout\n"); + return err; + } + err = grub_scsi_test_unit_ready (scsi); + } + while (err == GRUB_ERR_READ_ERROR); + /* Reset grub_errno ! + * It is set to some error code in loop before... */ + grub_errno = GRUB_ERR_NONE; + + /* Read capacity of media */ err = grub_scsi_read_capacity (scsi); if (err) { @@ -302,12 +453,14 @@ grub_scsi_open (const char *name, grub_disk_t disk) /* SCSI blocks can be something else than 512, although GRUB wants 512 byte blocks. */ - disk->total_sectors = ((scsi->size * scsi->blocksize) - << GRUB_DISK_SECTOR_BITS); + disk->total_sectors = ((grub_uint64_t)scsi->size + * (grub_uint64_t)scsi->blocksize) + >> GRUB_DISK_SECTOR_BITS; - grub_dprintf ("scsi", "capacity=%llu, blksize=%d\n", - (unsigned long long) disk->total_sectors, - scsi->blocksize); + grub_dprintf ("scsi", "blocks=%u, blocksize=%u\n", + scsi->size, scsi->blocksize); + grub_dprintf ("scsi", "Disk total 512 sectors = %llu\n", + disk->total_sectors); return GRUB_ERR_NONE; } diff --git a/disk/usbms.c b/disk/usbms.c index 8554b224f..7b719fb84 100644 --- a/disk/usbms.c +++ b/disk/usbms.c @@ -84,7 +84,8 @@ grub_usbms_finddevs (void) struct grub_usb_desc_device *descdev = &usbdev->descdev; int i; - if (descdev->class != 0 || descdev->subclass || descdev->protocol != 0) + if (descdev->class != 0 || descdev->subclass || descdev->protocol != 0 + || descdev->configcnt == 0) return 0; /* XXX: Just check configuration 0 for now. */ @@ -93,19 +94,31 @@ grub_usbms_finddevs (void) struct grub_usbms_dev *usbms; struct grub_usb_desc_if *interf; int j; - grub_uint8_t luns; + grub_uint8_t luns = 0; + + grub_dprintf ("usbms", "alive\n"); interf = usbdev->config[0].interf[i].descif; /* If this is not a USB Mass Storage device with a supported protocol, just skip it. */ + grub_dprintf ("usbms", "iterate: interf=%d, class=%d, subclass=%d, protocol=%d\n", + i, interf->class, interf->subclass, interf->protocol); + if (interf->class != GRUB_USB_CLASS_MASS_STORAGE - || interf->subclass != GRUB_USBMS_SUBCLASS_BULK + || ( interf->subclass != GRUB_USBMS_SUBCLASS_BULK && + /* Experimental support of RBC, MMC-2, UFI, SFF-8070i devices */ + interf->subclass != GRUB_USBMS_SUBCLASS_RBC && + interf->subclass != GRUB_USBMS_SUBCLASS_MMC2 && + interf->subclass != GRUB_USBMS_SUBCLASS_UFI && + interf->subclass != GRUB_USBMS_SUBCLASS_SFF8070 ) || interf->protocol != GRUB_USBMS_PROTOCOL_BULK) { continue; } + grub_dprintf ("usbms", "alive\n"); + devcnt++; usbms = grub_zalloc (sizeof (struct grub_usbms_dev)); if (! usbms) @@ -114,6 +127,8 @@ grub_usbms_finddevs (void) usbms->dev = usbdev; usbms->interface = i; + grub_dprintf ("usbms", "alive\n"); + /* Iterate over all endpoints of this interface, at least a IN and OUT bulk endpoint are required. */ for (j = 0; j < interf->endpointcnt; j++) @@ -125,14 +140,16 @@ grub_usbms_finddevs (void) { /* Bulk IN endpoint. */ usbms->in = endp; - grub_usb_clear_halt (usbdev, endp->endp_addr & 128); + /* Clear Halt is not possible yet! */ + /* grub_usb_clear_halt (usbdev, endp->endp_addr); */ usbms->in_maxsz = endp->maxpacket; } else if (!(endp->endp_addr & 128) && (endp->attrib & 3) == 2) { /* Bulk OUT endpoint. */ usbms->out = endp; - grub_usb_clear_halt (usbdev, endp->endp_addr & 128); + /* Clear Halt is not possible yet! */ + /* grub_usb_clear_halt (usbdev, endp->endp_addr); */ usbms->out_maxsz = endp->maxpacket; } } @@ -143,51 +160,63 @@ grub_usbms_finddevs (void) return 0; } + grub_dprintf ("usbms", "alive\n"); + + /* XXX: Activate the first configuration. */ + grub_usb_set_configuration (usbdev, 1); + /* Query the amount of LUNs. */ err = grub_usb_control_msg (usbdev, 0xA1, 254, 0, i, 1, (char *) &luns); + if (err) { /* In case of a stall, clear the stall. */ if (err == GRUB_USB_ERR_STALL) { - grub_usb_clear_halt (usbdev, usbms->in->endp_addr & 3); - grub_usb_clear_halt (usbdev, usbms->out->endp_addr & 3); + grub_usb_clear_halt (usbdev, usbms->in->endp_addr); + grub_usb_clear_halt (usbdev, usbms->out->endp_addr); } - /* Just set the amount of LUNs to one. */ grub_errno = GRUB_ERR_NONE; usbms->luns = 1; } else - usbms->luns = luns; + /* luns = 0 means one LUN with ID 0 present ! */ + /* We get from device not number of LUNs but highest + * LUN number. LUNs are numbered from 0, + * i.e. number of LUNs is luns+1 ! */ + usbms->luns = luns + 1; - /* XXX: Check the magic values, does this really make - sense? */ - grub_usb_control_msg (usbdev, (1 << 6) | 1, 255, - 0, i, 0, 0); - - /* XXX: To make Qemu work? */ - if (usbms->luns == 0) - usbms->luns = 1; + grub_dprintf ("usbms", "alive\n"); usbms->next = grub_usbms_dev_list; grub_usbms_dev_list = usbms; - /* XXX: Activate the first configuration. */ - grub_usb_set_configuration (usbdev, 1); - +#if 0 /* All this part should be probably deleted. + * This make trouble on some devices if they are not in + * Phase Error state - and there they should be not in such state... + * Bulk only mass storage reset procedure should be used only + * on place and in time when it is really necessary. */ + /* Reset recovery procedure */ /* Bulk-Only Mass Storage Reset, after the reset commands will be accepted. */ grub_usbms_reset (usbdev, i); + grub_usb_clear_halt (usbdev, usbms->in->endp_addr); + grub_usb_clear_halt (usbdev, usbms->out->endp_addr); +#endif return 0; } + grub_dprintf ("usbms", "alive\n"); return 0; } + grub_dprintf ("usbms", "alive\n"); grub_usb_iterate (usb_iterate); + grub_dprintf ("usbms", "alive\n"); + } @@ -225,6 +254,7 @@ grub_usbms_transfer (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd, static grub_uint32_t tag = 0; grub_usb_err_t err = GRUB_USB_ERR_NONE; int retrycnt = 3 + 1; + grub_size_t i; retry: retrycnt--; @@ -237,73 +267,89 @@ grub_usbms_transfer (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd, cbw.tag = tag++; cbw.transfer_length = grub_cpu_to_le32 (size); cbw.flags = (!read_write) << GRUB_USBMS_DIRECTION_BIT; - cbw.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT; + cbw.lun = scsi->lun; /* In USB MS CBW are LUN bits on another place than in SCSI CDB, both should be set correctly. */ cbw.length = cmdsize; grub_memcpy (cbw.cbwcb, cmd, cmdsize); + + /* Debug print of CBW content. */ + grub_dprintf ("usb", "CBW: sign=0x%08x tag=0x%08x len=0x%08x\n", + cbw.signature, cbw.tag, cbw.transfer_length); + grub_dprintf ("usb", "CBW: flags=0x%02x lun=0x%02x CB_len=0x%02x\n", + cbw.flags, cbw.lun, cbw.length); + grub_dprintf ("usb", "CBW: cmd:\n %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", + cbw.cbwcb[ 0], cbw.cbwcb[ 1], cbw.cbwcb[ 2], cbw.cbwcb[ 3], + cbw.cbwcb[ 4], cbw.cbwcb[ 5], cbw.cbwcb[ 6], cbw.cbwcb[ 7], + cbw.cbwcb[ 8], cbw.cbwcb[ 9], cbw.cbwcb[10], cbw.cbwcb[11], + cbw.cbwcb[12], cbw.cbwcb[13], cbw.cbwcb[14], cbw.cbwcb[15]); - /* Write the request. */ - err = grub_usb_bulk_write (dev->dev, dev->out->endp_addr & 15, + /* Write the request. + * XXX: Error recovery is maybe still not fully correct. */ + err = grub_usb_bulk_write (dev->dev, dev->out->endp_addr, sizeof (cbw), (char *) &cbw); if (err) { if (err == GRUB_USB_ERR_STALL) { + grub_usb_clear_halt (dev->dev, dev->in->endp_addr); grub_usb_clear_halt (dev->dev, dev->out->endp_addr); goto retry; } return grub_error (GRUB_ERR_IO, "USB Mass Storage request failed"); } - /* Read/write the data. */ - if (read_write == 0) + /* Read/write the data, (maybe) according to specification. */ + if (size && (read_write == 0)) { - err = grub_usb_bulk_read (dev->dev, dev->in->endp_addr & 15, size, buf); - grub_dprintf ("usb", "read: %d %d\n", err, GRUB_USB_ERR_STALL); - if (err) - { - if (err == GRUB_USB_ERR_STALL) - { - grub_usb_clear_halt (dev->dev, dev->in->endp_addr); - goto retry; - } - return grub_error (GRUB_ERR_READ_ERROR, - "can't read from USB Mass Storage device"); - } + err = grub_usb_bulk_read (dev->dev, dev->in->endp_addr, size, buf); + grub_dprintf ("usb", "read: %d %d\n", err, GRUB_USB_ERR_STALL); + if (err) goto CheckCSW; + /* Debug print of received data. */ + grub_dprintf ("usb", "buf:\n"); + if (size <= 64) + for (i=0; idev, dev->in->endp_addr & 15, size, buf); + err = grub_usb_bulk_write (dev->dev, dev->out->endp_addr, size, buf); grub_dprintf ("usb", "write: %d %d\n", err, GRUB_USB_ERR_STALL); - if (err) - { - if (err == GRUB_USB_ERR_STALL) - { - grub_usb_clear_halt (dev->dev, dev->out->endp_addr); - goto retry; - } - return grub_error (GRUB_ERR_WRITE_ERROR, - "can't write to USB Mass Storage device"); - } + grub_dprintf ("usb", "buf:\n"); + /* Debug print of sent data. */ + if (size <= 256) + for (i=0; idev, dev->in->endp_addr & 15, - sizeof (status), (char *) &status); + /* Read the status - (maybe) according to specification. */ +CheckCSW: + err = grub_usb_bulk_read (dev->dev, dev->in->endp_addr, + sizeof (status), (char *) &status); if (err) { - if (err == GRUB_USB_ERR_STALL) - { - grub_usb_clear_halt (dev->dev, dev->in->endp_addr); + grub_usb_clear_halt (dev->dev, dev->in->endp_addr); + err = grub_usb_bulk_read (dev->dev, dev->in->endp_addr, + sizeof (status), (char *) &status); + if (err) + { /* Bulk-only reset device. */ + grub_usbms_reset (dev->dev, dev->interface); + grub_usb_clear_halt (dev->dev, dev->in->endp_addr); + grub_usb_clear_halt (dev->dev, dev->out->endp_addr); goto retry; - } - return grub_error (GRUB_ERR_READ_ERROR, - "can't read status from USB Mass Storage device"); + } } - /* XXX: Magic and check this code. */ + /* Debug print of CSW content. */ + grub_dprintf ("usb", "CSW: sign=0x%08x tag=0x%08x resid=0x%08x\n", + status.signature, status.tag, status.residue); + grub_dprintf ("usb", "CSW: status=0x%02x\n", status.status); + + /* If phase error, do bulk-only reset device. */ if (status.status == 2) { - /* XXX: Phase error, reset device. */ grub_usbms_reset (dev->dev, dev->interface); grub_usb_clear_halt (dev->dev, dev->in->endp_addr); grub_usb_clear_halt (dev->dev, dev->out->endp_addr); diff --git a/include/grub/scsicmd.h b/include/grub/scsicmd.h index 40f237a17..f9a7cb200 100644 --- a/include/grub/scsicmd.h +++ b/include/grub/scsicmd.h @@ -25,14 +25,26 @@ #define GRUB_SCSI_REMOVABLE_BIT 7 #define GRUB_SCSI_LUN_SHIFT 5 +struct grub_scsi_test_unit_ready +{ + grub_uint8_t opcode; + grub_uint8_t lun; /* 7-5 LUN, 4-0 reserved */ + grub_uint8_t reserved1; + grub_uint8_t reserved2; + grub_uint8_t reserved3; + grub_uint8_t control; + grub_uint8_t pad[6]; /* To be ATAPI compatible */ +} __attribute__((packed)); + struct grub_scsi_inquiry { grub_uint8_t opcode; - grub_uint8_t lun; - grub_uint16_t reserved; - grub_uint16_t alloc_length; - grub_uint8_t reserved2; - grub_uint8_t pad[5]; + grub_uint8_t lun; /* 7-5 LUN, 4-1 reserved, 0 EVPD */ + grub_uint8_t page; /* page code if EVPD=1 */ + grub_uint8_t reserved; + grub_uint8_t alloc_length; + grub_uint8_t control; + grub_uint8_t pad[6]; /* To be ATAPI compatible */ } __attribute__((packed)); struct grub_scsi_inquiry_data @@ -47,12 +59,42 @@ struct grub_scsi_inquiry_data char prodrev[4]; } __attribute__((packed)); +struct grub_scsi_request_sense +{ + grub_uint8_t opcode; + grub_uint8_t lun; /* 7-5 LUN, 4-0 reserved */ + grub_uint8_t reserved1; + grub_uint8_t reserved2; + grub_uint8_t alloc_length; + grub_uint8_t control; + grub_uint8_t pad[6]; /* To be ATAPI compatible */ +} __attribute__((packed)); + +struct grub_scsi_request_sense_data +{ + grub_uint8_t error_code; /* 7 Valid, 6-0 Err. code */ + grub_uint8_t segment_number; + grub_uint8_t sense_key; /*7 FileMark, 6 EndOfMedia, 5 ILI, 4-0 sense key */ + grub_uint32_t information; + grub_uint8_t additional_sense_length; + grub_uint32_t cmd_specific_info; + grub_uint8_t additional_sense_code; + grub_uint8_t additional_sense_code_qualifier; + grub_uint8_t field_replaceable_unit_code; + grub_uint8_t sense_key_specific[3]; + /* there can be additional sense field */ +} __attribute__((packed)); + struct grub_scsi_read_capacity { grub_uint8_t opcode; - grub_uint8_t lun; - grub_uint8_t reserved[8]; - grub_uint8_t pad[2]; + grub_uint8_t lun; /* 7-5 LUN, 4-1 reserved, 0 reserved */ + grub_uint32_t logical_block_addr; /* only if PMI=1 */ + grub_uint8_t reserved1; + grub_uint8_t reserved2; + grub_uint8_t PMI; + grub_uint8_t control; + grub_uint16_t pad; /* To be ATAPI compatible */ } __attribute__((packed)); struct grub_scsi_read_capacity_data @@ -106,11 +148,13 @@ struct grub_scsi_write12 typedef enum { grub_scsi_cmd_inquiry = 0x12, + grub_scsi_cmd_test_unit_ready = 0x00, grub_scsi_cmd_read_capacity = 0x25, grub_scsi_cmd_read10 = 0x28, grub_scsi_cmd_write10 = 0x2a, grub_scsi_cmd_read12 = 0xa8, - grub_scsi_cmd_write12 = 0xaa + grub_scsi_cmd_write12 = 0xaa, + grub_scsi_cmd_request_sense = 0x03 } grub_scsi_cmd_t; typedef enum diff --git a/include/grub/usb.h b/include/grub/usb.h index dc90e7879..cbbc39303 100644 --- a/include/grub/usb.h +++ b/include/grub/usb.h @@ -156,7 +156,7 @@ struct grub_usb_device int initialized; /* Data toggle values (used for bulk transfers only). */ - int toggle[16]; + int toggle[256]; /* Device-specific data. */ void *data; @@ -184,7 +184,12 @@ typedef enum typedef enum { - GRUB_USBMS_SUBCLASS_BULK = 0x06 + GRUB_USBMS_SUBCLASS_BULK = 0x06, + /* Experimental support for non-pure SCSI devices */ + GRUB_USBMS_SUBCLASS_RBC = 0x01, + GRUB_USBMS_SUBCLASS_MMC2 = 0x02, + GRUB_USBMS_SUBCLASS_UFI = 0x04, + GRUB_USBMS_SUBCLASS_SFF8070 = 0x05 } grub_usbms_subclass_t; typedef enum diff --git a/include/grub/usbtrans.h b/include/grub/usbtrans.h index 8c739684e..cd818e1fc 100644 --- a/include/grub/usbtrans.h +++ b/include/grub/usbtrans.h @@ -86,9 +86,9 @@ typedef struct grub_usb_transfer *grub_usb_transfer_t; #define GRUB_USB_REQ_HUB_GET_PORT_STATUS 0x00 -#define GRUB_USB_FEATURE_ENDP_HALT 0x01 -#define GRUB_USB_FEATURE_DEV_REMOTE_WU 0x02 -#define GRUB_USB_FEATURE_TEST_MODE 0x04 +#define GRUB_USB_FEATURE_ENDP_HALT 0x00 +#define GRUB_USB_FEATURE_DEV_REMOTE_WU 0x01 +#define GRUB_USB_FEATURE_TEST_MODE 0x02 #define GRUB_USB_HUB_STATUS_CONNECTED (1 << 0) #define GRUB_USB_HUB_STATUS_LOWSPEED (1 << 9) From c837af3f38882470ea30d4392427d17c5132cdea Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 31 May 2010 20:23:51 +0200 Subject: [PATCH 686/738] * loader/multiboot_elfxx.c (grub_multiboot_load_elfXX) [__mips]: Check 64-bit address as signed on MIPS. --- ChangeLog | 5 +++++ loader/multiboot_elfxx.c | 6 +++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 5072a6026..c6edd3ac3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-05-31 Vladimir Serbinenko + + * loader/multiboot_elfxx.c (grub_multiboot_load_elfXX) [__mips]: Check + 64-bit address as signed on MIPS. + 2010-05-28 Colin Watson * configure.ac: AC_PROG_LEX sets LEX to ":" if lex is missing, not diff --git a/loader/multiboot_elfxx.c b/loader/multiboot_elfxx.c index 92a52d3a8..78b7c542c 100644 --- a/loader/multiboot_elfxx.c +++ b/loader/multiboot_elfxx.c @@ -74,7 +74,11 @@ CONCAT(grub_multiboot_load_elf, XX) (grub_file_t file, void *buffer) if (ehdr->e_phoff + ehdr->e_phnum * ehdr->e_phentsize > MULTIBOOT_SEARCH) return grub_error (GRUB_ERR_BAD_OS, "program header at a too high offset"); -#ifdef MULTIBOOT_LOAD_ELF64 +#if defined (MULTIBOOT_LOAD_ELF64) && defined (__mips) + /* We still in 32-bit mode. */ + if (ehdr->e_entry < 0xffffffff80000000ULL) + return grub_error (GRUB_ERR_BAD_OS, "invalid entry point for ELF64"); +#else /* We still in 32-bit mode. */ if (ehdr->e_entry > 0xffffffff) return grub_error (GRUB_ERR_BAD_OS, "invalid entry point for ELF64"); From 7620e7debd2a54cb29bab9f74c49f45ec76dcf9d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 31 May 2010 20:40:42 +0200 Subject: [PATCH 687/738] * commands/setpci.c (grub_setpci_iter): Fix an incorrect function check. Reported by: Seth Goldberg. --- ChangeLog | 5 +++++ commands/setpci.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index c6edd3ac3..5bbb1c12f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-05-31 Vladimir Serbinenko + + * commands/setpci.c (grub_setpci_iter): Fix an incorrect function check. + Reported by: Seth Goldberg. + 2010-05-31 Vladimir Serbinenko * loader/multiboot_elfxx.c (grub_multiboot_load_elfXX) [__mips]: Check diff --git a/commands/setpci.c b/commands/setpci.c index fbc7c214e..aa09f5bbb 100644 --- a/commands/setpci.c +++ b/commands/setpci.c @@ -96,7 +96,7 @@ grub_setpci_iter (grub_pci_device_t dev, grub_pci_id_t pciid) if (check_device && grub_pci_get_device (dev) != device) return 0; - if (check_function && grub_pci_get_function (dev) != device) + if (check_function && grub_pci_get_function (dev) != function) return 0; addr = grub_pci_make_address (dev, regaddr); From 5629316656a33304ac15364bf09b6f1d6800b447 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 31 May 2010 20:43:28 +0200 Subject: [PATCH 688/738] * loader/multiboot_mbi2.c (grub_multiboot_make_mbi): Fix incorrect addition of dest. Reported by: Seth Goldberg. --- ChangeLog | 6 ++++++ loader/multiboot_mbi2.c | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 5bbb1c12f..aa9363dd7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-05-31 Vladimir Serbinenko + + * loader/multiboot_mbi2.c (grub_multiboot_make_mbi): Fix incorrect + addition of dest. + Reported by: Seth Goldberg. + 2010-05-31 Vladimir Serbinenko * commands/setpci.c (grub_setpci_iter): Fix an incorrect function check. diff --git a/loader/multiboot_mbi2.c b/loader/multiboot_mbi2.c index 7e9cebe49..c9e52e51f 100644 --- a/loader/multiboot_mbi2.c +++ b/loader/multiboot_mbi2.c @@ -496,7 +496,7 @@ grub_multiboot_make_mbi (void *orig, grub_uint32_t dest, grub_off_t buf_off, = (struct multiboot_tag_module *) ptrorig; tag->type = MULTIBOOT_TAG_TYPE_MODULE; tag->size = sizeof (struct multiboot_tag_module) + cur->cmdline_size; - tag->mod_start = dest + cur->start; + tag->mod_start = cur->start; tag->mod_end = tag->mod_start + cur->size; grub_memcpy (tag->cmdline, cur->cmdline, cur->cmdline_size); ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN); From c2ffc8e956be5df59fd2fa96c4102e02a78f1799 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 31 May 2010 20:46:16 +0200 Subject: [PATCH 689/738] * normal/main.c (grub_normal_add_menu_entry): Avoid going out of args. Reported by: Seth Goldberg. --- ChangeLog | 5 +++++ normal/main.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index aa9363dd7..2d9015cfb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-05-31 Vladimir Serbinenko + + * normal/main.c (grub_normal_add_menu_entry): Avoid going out of args. + Reported by: Seth Goldberg. + 2010-05-31 Vladimir Serbinenko * loader/multiboot_mbi2.c (grub_multiboot_make_mbi): Fix incorrect diff --git a/normal/main.c b/normal/main.c index 4ed17e82c..14a25032f 100644 --- a/normal/main.c +++ b/normal/main.c @@ -204,7 +204,7 @@ grub_normal_add_menu_entry (int argc, const char **args, for (i = 0; i < argc; i++) { /* Capture arguments. */ - if (grub_strncmp ("--", args[i], 2) == 0) + if (grub_strncmp ("--", args[i], 2) == 0 && i + 1 < argc) { const char *arg = &args[i][2]; From dfbfe00473ad0edb62cc3d0958949578d4a8ecd3 Mon Sep 17 00:00:00 2001 From: Jiro SEKIBA Date: Mon, 31 May 2010 20:49:42 +0200 Subject: [PATCH 690/738] * include/grub/disk.h (GRUB_DISK_SIZE_UNKNOWN): New macro. * fs/nilfs.c: Support 2nd super block in case 1st one is accidently corrupted or not synced properly. --- ChangeLog | 6 ++++ fs/nilfs2.c | 67 +++++++++++++++++++++++++++++++++++++-------- include/grub/disk.h | 3 ++ 3 files changed, 65 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2d9015cfb..a35843554 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-05-31 Jiro SEKIBA + + * include/grub/disk.h (GRUB_DISK_SIZE_UNKNOWN): New macro. + * fs/nilfs.c: Support 2nd super block in case 1st one is accidently + corrupted or not synced properly. + 2010-05-31 Vladimir Serbinenko * normal/main.c (grub_normal_add_menu_entry): Avoid going out of args. diff --git a/fs/nilfs2.c b/fs/nilfs2.c index 7e0415d12..5d32f5f88 100644 --- a/fs/nilfs2.c +++ b/fs/nilfs2.c @@ -49,6 +49,13 @@ #define NILFS_BTREE_LEVEL_NODE_MIN (NILFS_BTREE_LEVEL_DATA + 1) #define NILFS_BTREE_LEVEL_MAX 14 +/* nilfs 1st super block posission from beginning of the partition + in 512 block size */ +#define NILFS_1ST_SUPER_BLOCK 2 +/* nilfs 2nd super block posission from end of the partition + in 512 block size */ +#define NILFS_2ND_SUPER_BLOCK 8 + struct grub_nilfs2_inode { grub_uint64_t i_blocks; @@ -703,6 +710,52 @@ grub_nilfs2_valid_sb (struct grub_nilfs2_super_block *sbp) return 1; } +static grub_err_t +grub_nilfs2_load_sb (struct grub_nilfs2_data *data) +{ + grub_disk_t disk = data->disk; + struct grub_nilfs2_super_block sb2; + grub_uint64_t partition_size; + int valid[2]; + int swp = 0; + + /* Read first super block. */ + grub_disk_read (disk, NILFS_1ST_SUPER_BLOCK, 0, + sizeof (struct grub_nilfs2_super_block), &data->sblock); + /* Make sure if 1st super block is valid. */ + valid[0] = grub_nilfs2_valid_sb (&data->sblock); + + partition_size = grub_disk_get_size (disk); + if (partition_size != GRUB_DISK_SIZE_UNKNOWN) + { + /* Read second super block. */ + grub_disk_read (disk, partition_size - NILFS_2ND_SUPER_BLOCK, 0, + sizeof (struct grub_nilfs2_super_block), &sb2); + /* Make sure if 2nd super block is valid. */ + valid[1] = grub_nilfs2_valid_sb (&sb2); + } + else + /* 2nd super block may not exist, so it's invalid. */ + valid[1] = 0; + + + + if (!valid[0] && !valid[1]) + return grub_error (GRUB_ERR_BAD_FS, "not a nilfs2 filesystem"); + + swp = valid[1] && (!valid[0] || + grub_le_to_cpu64 (data->sblock.s_last_cno) < + grub_le_to_cpu64 (sb2.s_last_cno)); + + /* swap if first super block is invalid or older than second one. */ + if (swp) + grub_memcpy (&data->sblock, &sb2, + sizeof (struct grub_nilfs2_super_block)); + + grub_errno = GRUB_ERR_NONE; + return grub_errno; +} + static struct grub_nilfs2_data * grub_nilfs2_mount (grub_disk_t disk) { @@ -717,19 +770,13 @@ grub_nilfs2_mount (grub_disk_t disk) if (!data) return 0; + data->disk = disk; + /* Read the superblock. */ - grub_disk_read (disk, 1 * 2, 0, sizeof (struct grub_nilfs2_super_block), - &data->sblock); + grub_nilfs2_load_sb (data); if (grub_errno) goto fail; - /* Make sure this is an nilfs2 filesystem. */ - if (!grub_nilfs2_valid_sb (&data->sblock)) - { - grub_error (GRUB_ERR_BAD_FS, "not a nilfs2 filesystem"); - goto fail; - } - nilfs2_block_count = (1 << LOG2_NILFS2_BLOCK_SIZE (data)); /* Read the last segment summary. */ @@ -748,8 +795,6 @@ grub_nilfs2_mount (grub_disk_t disk) if (grub_errno) goto fail; - data->disk = disk; - grub_nilfs2_read_last_checkpoint (data, &last_checkpoint); if (grub_errno) diff --git a/include/grub/disk.h b/include/grub/disk.h index e60b1f3de..e7f807e0e 100644 --- a/include/grub/disk.h +++ b/include/grub/disk.h @@ -138,6 +138,9 @@ typedef struct grub_disk_memberlist *grub_disk_memberlist_t; #define GRUB_DISK_CACHE_SIZE 8 #define GRUB_DISK_CACHE_BITS 3 +/* Return value of grub_disk_get_size() in case disk size is unknown. */ +#define GRUB_DISK_SIZE_UNKNOWN 0xffffffffffffffffULL + /* This is called from the memory manager. */ void grub_disk_cache_invalidate_all (void); From b1d17e10e031a9d3dbbfb2e227509cf8137015bf Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 31 May 2010 21:01:01 +0200 Subject: [PATCH 691/738] * disk/i386/pc/biosdisk.c (grub_biosdisk_open): Use GRUB_DISK_SIZE_UNKNOWN. * disk/ieee1275/ofdisk.c (grub_ofdisk_open): Likewise. --- ChangeLog | 6 ++++++ disk/i386/pc/biosdisk.c | 3 ++- disk/ieee1275/ofdisk.c | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index a35843554..c388ebd27 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-05-31 Vladimir Serbinenko + + * disk/i386/pc/biosdisk.c (grub_biosdisk_open): Use + GRUB_DISK_SIZE_UNKNOWN. + * disk/ieee1275/ofdisk.c (grub_ofdisk_open): Likewise. + 2010-05-31 Jiro SEKIBA * include/grub/disk.h (GRUB_DISK_SIZE_UNKNOWN): New macro. diff --git a/disk/i386/pc/biosdisk.c b/disk/i386/pc/biosdisk.c index 94d0e3708..f82f91ff0 100644 --- a/disk/i386/pc/biosdisk.c +++ b/disk/i386/pc/biosdisk.c @@ -120,7 +120,8 @@ grub_biosdisk_open (const char *name, grub_disk_t disk) { data->flags = GRUB_BIOSDISK_FLAG_LBA | GRUB_BIOSDISK_FLAG_CDROM; data->sectors = 32; - total_sectors = GRUB_ULONG_MAX; /* TODO: get the correct size. */ + /* TODO: get the correct size. */ + total_sectors = GRUB_DISK_SIZE_UNKNOWN; } else if (drive & 0x80) { diff --git a/disk/ieee1275/ofdisk.c b/disk/ieee1275/ofdisk.c index e5a4a67fa..d0d9e894f 100644 --- a/disk/ieee1275/ofdisk.c +++ b/disk/ieee1275/ofdisk.c @@ -204,7 +204,7 @@ grub_ofdisk_open (const char *name, grub_disk_t disk) /* XXX: There is no property to read the number of blocks. There should be a property `#blocks', but it is not there. Perhaps it is possible to use seek for this. */ - disk->total_sectors = 0xFFFFFFFFUL; + disk->total_sectors = GRUB_DISK_SIZE_UNKNOWN; disk->id = (unsigned long) op; From 7d4873c26a80e0d05c0952aa45f4bda59e1e3f86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ale=C5=A1=20Nesrsta?= Date: Tue, 1 Jun 2010 02:10:19 +0200 Subject: [PATCH 692/738] =?UTF-8?q?Merge=20Ale=C5=A1'=20latest=20patch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bus/usb/ohci.c | 156 ++++++++++++++++++++++++++++++---------- bus/usb/uhci.c | 19 +++-- bus/usb/usbtrans.c | 8 +++ disk/scsi.c | 33 ++++++++- disk/usbms.c | 40 ++++++++--- include/grub/usb.h | 3 +- include/grub/usbtrans.h | 3 + term/usb_keyboard.c | 1 - 8 files changed, 206 insertions(+), 57 deletions(-) diff --git a/bus/usb/ohci.c b/bus/usb/ohci.c index 03768d39e..ac6f61ee8 100644 --- a/bus/usb/ohci.c +++ b/bus/usb/ohci.c @@ -116,6 +116,11 @@ typedef enum #define GRUB_OHCI_PERIODIC_START 0x257f #define GRUB_OHCI_FRAME_INTERVAL 0x2edf +#define GRUB_OHCI_SET_PORT_ENABLE (1 << 1) +#define GRUB_OHCI_CLEAR_PORT_ENABLE (1 << 0) +#define GRUB_OHCI_SET_PORT_RESET (1 << 4) +#define GRUB_OHCI_SET_PORT_RESET_STATUS_CHANGE (1 << 20) + static grub_uint32_t grub_ohci_readreg32 (struct grub_ohci *o, grub_ohci_reg_t reg) { @@ -281,7 +286,7 @@ grub_ohci_pci_iter (grub_pci_device_t dev, /* Misc. pre-sets. */ o->hcca->donehead = 0; - grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1 << 1)); /* Clears WDH */ + grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, 0x7f); /* Clears everything */ grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD, 0); grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLCURR, 0); grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKHEAD, 0); @@ -396,8 +401,10 @@ grub_ohci_transaction (grub_ohci_td_t td, break; } +#if 0 /* Always generate interrupt */ /* Generate no interrupts. */ token |= 7 << 21; +#endif /* Set the token. */ token |= toggle << 24; @@ -444,9 +451,12 @@ grub_ohci_transfer (grub_usb_controller_t dev, grub_uint32_t status; grub_uint32_t control; grub_usb_err_t err; - int i, j; + int i; grub_uint64_t maxtime; int err_timeout = 0; + int err_unrec = 0; + grub_uint32_t intstatus; + grub_uint32_t tderr_addr = 0; /* Allocate an Endpoint Descriptor. */ ed_chunk = grub_memalign_dma32 (256, sizeof (*ed)); @@ -479,11 +489,13 @@ grub_ohci_transfer (grub_usb_controller_t dev, + (i + 1) * sizeof (td_list[0])); } +#if 0 /* Better will be enable interrupt on all TDs. */ /* The last-1 TD token we should change to enable interrupt when TD finishes. * As OHCI interrupts are disabled, it does only setting of WDH bit in * HcInterruptStatus register - and that is what we want to safely detect * normal end of all transactions. */ td_list[transfer->transcnt - 1].token &= ~(7 << 21); +#endif td_list[transfer->transcnt].token = 0; td_list[transfer->transcnt].buffer = 0; @@ -582,9 +594,11 @@ grub_ohci_transfer (grub_usb_controller_t dev, } grub_dprintf ("ohci", "wait for completion\n"); - grub_dprintf ("ohci", "control=0x%02x status=0x%02x\n", + grub_dprintf ("ohci", + "begin: control=0x%02x status=0x%02x\n\t\t intstatus=0x%02x\n", grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL), - grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS)); + grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS), + grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS)); /* Safety measure to avoid a hang. */ maxtime = grub_get_time_ms () + 1000; @@ -592,30 +606,34 @@ grub_ohci_transfer (grub_usb_controller_t dev, /* Wait until the transfer is completed or STALLs. */ do { - grub_cpu_idle (); + /* Check transfer status */ + intstatus = grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS); + if ((intstatus & 0x2) != 0) + { + grub_dprintf ("ohci", "Current HccaDoneHead=0x%08x\n", + o->hcca->donehead); + /* Remember last successful TD */ + tderr_addr = grub_le_to_cpu32 (o->hcca->donehead) & ~0xf; + /* Reset DoneHead */ + o->hcca->donehead = 0; + grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1 << 1)); + /* if TD is last, finish */ + if (tderr_addr == td_list_addr + + sizeof (td_list[0]) * (transfer->transcnt - 1)) + break; + continue; + } + + if ((intstatus & 0x10) != 0) + { /* Unrecoverable error - only reset can help...! */ + err_unrec = 1; + break; + } /* Detected a HALT. */ if (grub_le_to_cpu32 (ed->td_head) & 1) break; - - if ((grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS) & 0x2) != 0) - { - if ((grub_le_to_cpu32 (o->hcca->donehead) & ~0xf) - == td_list_addr + (transfer->transcnt - 1) * sizeof (td_list[0])) - break; - /* Done Head can be updated on some another place if ED is halted. */ - if (grub_le_to_cpu32 (ed->td_head) & 1) - break; - - /* If there is not HALT in ED, it is not correct, so debug it, reset - * donehead and WDH and continue waiting. */ - grub_dprintf ("ohci", "Incorrect HccaDoneHead=0x%08x\n", - o->hcca->donehead); - o->hcca->donehead = 0; - grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1 << 1)); - continue; - } /* Timeout ? */ if (grub_get_time_ms () > maxtime) { @@ -628,9 +646,45 @@ grub_ohci_transfer (grub_usb_controller_t dev, if ((ed->td_head & ~0xf) == (ed->td_tail & ~0xf)) break; + + grub_cpu_idle (); } while (1); + grub_dprintf ("ohci", "end: control=0x%02x status=0x%02x\n\t\t intstatus=0x%02x\n", + grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL), + grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS), + grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS)); + + if (!tderr_addr) + { + /* It means that something wrong happened, + * it could be: + * - timeout and no TD processed + * - some or unrecoverable error and no TD processed + * - something unexpected... :-( */ + /* Try look into DONEHEAD reg., but there should be also zero */ + grub_dprintf("ohci", "HCCA DoneHead is zero, something is bad!\n"); + tderr_addr = grub_ohci_readreg32 (o, GRUB_OHCI_REG_DONEHEAD) & ~0xf; + } + + /* Remember last processed transaction (TD) - it is necessary for + * proper setting of toggle bit in next transaction. */ + transfer->last_trans = (tderr_addr - td_list_addr) / sizeof (*td_list); + + /* Check correct value in last_trans */ + /* It could happen if timeout happens and no TD was retired */ + if (transfer->last_trans >= transfer->transcnt || !tderr_addr) + { + grub_dprintf("ohci", "tder==0 or out of TDs range!\n"); + grub_dprintf("ohci", "tderr_addr=0x%x, td_list=%p,\n\t\t last_trans=%d, transcnt=%d\n", + tderr_addr, td_list, transfer->last_trans, transfer->transcnt); + /* We should set something valid... */ + transfer->last_trans = -1; /* Probably no TD done */ + tderr_addr = td_list_addr; + } + + /* In case of timeout do not detect error from TD */ if (err_timeout) { err = GRUB_ERR_TIMEOUT; @@ -640,20 +694,25 @@ grub_ohci_transfer (grub_usb_controller_t dev, grub_le_to_cpu32(ed->td_tail), grub_le_to_cpu32(ed->next_ed)); } + /* In case of unrecoverable error do not detect error from TD */ + else if (err_unrec) + { + err = GRUB_USB_ERR_UNRECOVERABLE; + grub_dprintf("ohci", + "Unrecoverable error, target=%08x, head=%08x\n" + "\t\ttail=%08x, next=%08x\n", + grub_le_to_cpu32(ed->target), + grub_le_to_cpu32(ed->td_head), + grub_le_to_cpu32(ed->td_tail), + grub_le_to_cpu32(ed->next_ed)); + } else if (grub_le_to_cpu32 (ed->td_head) & 1) { - grub_uint32_t td_err_addr; grub_uint8_t errcode; grub_ohci_td_t tderr = NULL; - td_err_addr = (grub_ohci_readreg32 (o, GRUB_OHCI_REG_DONEHEAD) & ~0xf); - if (td_err_addr == 0) - /* If DONEHEAD==0 it means that correct address is in HCCA. - * It should be always now! */ - td_err_addr = (grub_le_to_cpu32 (o->hcca->donehead) & ~0xf); - tderr = (grub_ohci_td_t) ((char *) td_list - + (td_err_addr - td_list_addr)); + + (tderr_addr - td_list_addr)); errcode = grub_le_to_cpu32 (tderr->token) >> 28; grub_dprintf ("ohci", "OHCI errcode=0x%02x\n", errcode); @@ -702,17 +761,17 @@ grub_ohci_transfer (grub_usb_controller_t dev, case 8: /* XXX: Data overrun error. */ err = GRUB_USB_ERR_DATA; - j = ((grub_uint32_t)tderr - (grub_uint32_t)td_list) / sizeof (*td_list); - grub_dprintf ("ohci", "Overrun, failed TD address: %p, index: %d\n", tderr, j); + grub_dprintf ("ohci", "Overrun, failed TD address: %p, index: %d\n", + tderr, transfer->last_trans); break; case 9: /* XXX: Data underrun error. */ err = GRUB_USB_ERR_DATA; + grub_dprintf ("ohci", "Underrun, failed TD address: %p, index: %d\n", + tderr, transfer->last_trans); grub_dprintf ("ohci", "Underrun, number of not transferred bytes: %d\n", 1 + grub_le_to_cpu32 (tderr->buffer_end) - grub_le_to_cpu32 (tderr->buffer)); - j = ((grub_uint32_t)tderr - (grub_uint32_t)td_list) / sizeof (*td_list); - grub_dprintf ("ohci", "Underrun, failed TD address: %p, index: %d\n", tderr, j); break; case 10: @@ -764,7 +823,8 @@ grub_ohci_transfer (grub_usb_controller_t dev, /* SF bit reset. (SF bit indicates Start Of Frame (SOF) packet) */ grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1<<2)); /* Wait for new SOF */ - while ((grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS) & 0x4) == 0); + while (((grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS) & 0x4) == 0) + && !err_unrec); /* Now it should be safe to change CONTROL and BULK lists. */ /* Important cleaning. */ @@ -774,7 +834,29 @@ grub_ohci_transfer (grub_usb_controller_t dev, grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLCURR, 0); grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKHEAD, 0); grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKCURR, 0); - + + if (err_unrec) + { + /* Do OHCI reset in case of unrecoverable error - maybe we will need + * do more - re-enumerate bus etc. (?) */ + + /* Suspend the OHCI by issuing a reset. */ + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, 1); /* XXX: Magic. */ + grub_millisleep (1); + grub_dprintf ("ohci", "Unrecoverable error - OHCI reset\n"); + + /* Misc. resets. */ + o->hcca->donehead = 0; + grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, 0x7f); /* Clears everything */ + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD, 0); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLCURR, 0); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKHEAD, 0); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKCURR, 0); + + /* Enable the OHCI. */ + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, (2 << 6)); + } + grub_dprintf ("ohci", "OHCI finished, freeing, err=0x%02x\n", err); grub_dma_free (td_list_chunk); diff --git a/bus/usb/uhci.c b/bus/usb/uhci.c index eb533c926..1510f98e8 100644 --- a/bus/usb/uhci.c +++ b/bus/usb/uhci.c @@ -332,13 +332,20 @@ grub_free_td (struct grub_uhci *u, grub_uhci_td_t td) } static void -grub_free_queue (struct grub_uhci *u, grub_uhci_td_t td) +grub_free_queue (struct grub_uhci *u, grub_uhci_td_t td, + grub_usb_transfer_t transfer) { - /* Free the TDs in this queue. */ - while (td) + int i; /* Index of TD in transfer */ + + /* Free the TDs in this queue and set last_trans. */ + for (i=0; td; i++) { grub_uhci_td_t tdprev; + /* Check state of TD and possibly set last_trans */ + if (transfer && (td->linkptr & 1)) + transfer->last_trans = i; + /* Unlink the queue. */ tdprev = td; td = (grub_uhci_td_t) td->linkptr2; @@ -461,7 +468,7 @@ grub_uhci_transfer (grub_usb_controller_t dev, td_prev->linkptr = 1; if (td_first) - grub_free_queue (u, td_first); + grub_free_queue (u, td_first, NULL); return GRUB_USB_ERR_INTERNAL; } @@ -560,7 +567,7 @@ grub_uhci_transfer (grub_usb_controller_t dev, /* Place the QH back in the free list and deallocate the associated TDs. */ qh->elinkptr = 1; - grub_free_queue (u, td_first); + grub_free_queue (u, td_first, transfer); return err; } @@ -609,7 +616,7 @@ grub_uhci_portstatus (grub_usb_controller_t dev, grub_uhci_writereg16 (u, reg, enable << 9); /* Wait for the reset to complete. XXX: How long exactly? */ - grub_millisleep (10); + grub_millisleep (50); /* For root hub should be nominaly 50ms */ status = grub_uhci_readreg16 (u, reg); grub_uhci_writereg16 (u, reg, status & ~(1 << 9)); grub_dprintf ("uhci", "reset completed\n"); diff --git a/bus/usb/usbtrans.c b/bus/usb/usbtrans.c index 0bf5ee6de..b3ee167a1 100644 --- a/bus/usb/usbtrans.c +++ b/bus/usb/usbtrans.c @@ -213,6 +213,7 @@ grub_usb_bulk_readwrite (grub_usb_device_t dev, transfer->type = GRUB_USB_TRANSACTION_TYPE_BULK; transfer->max = max; transfer->dev = dev; + transfer->last_trans = -1; /* Reset index of last processed transaction (TD) */ /* Allocate an array of transfer data structures. */ transfer->transactions = grub_malloc (transfer->transcnt @@ -240,6 +241,13 @@ grub_usb_bulk_readwrite (grub_usb_device_t dev, } err = dev->controller.dev->transfer (&dev->controller, transfer); + /* We must remember proper toggle value even if some transactions + * were not processed - correct value should be inversion of last + * processed transaction (TD). */ + if (transfer->last_trans >= 0) + toggle = transfer->transactions[transfer->last_trans].toggle ? 0 : 1; + else + toggle = dev->toggle[endpoint]; /* Nothing done, take original */ grub_dprintf ("usb", "toggle=%d\n", toggle); dev->toggle[endpoint] = toggle; diff --git a/disk/scsi.c b/disk/scsi.c index e8bfb6a3f..dffabc26e 100644 --- a/disk/scsi.c +++ b/disk/scsi.c @@ -421,7 +421,7 @@ grub_scsi_open (const char *name, grub_disk_t disk) /* According to USB MS tests specification, issue Test Unit Ready * until OK */ - maxtime = grub_get_time_ms () + 1000; + maxtime = grub_get_time_ms () + 5000; /* It is safer value */ do { /* Timeout is necessary - for example in case when we have @@ -519,6 +519,37 @@ grub_scsi_read (grub_disk_t disk, grub_disk_addr_t sector, /* XXX: Never reached. */ return GRUB_ERR_NONE; + +#if 0 /* Workaround - it works - but very slowly, from some reason + * unknown to me (specially on OHCI). Do not use it. */ + /* Split transfer requests to device sector size because */ + /* some devices are not able to transfer more than 512-1024 bytes */ + grub_err_t err = GRUB_ERR_NONE; + + for ( ; size; size--) + { + /* Depending on the type, select a read function. */ + switch (scsi->devtype) + { + case grub_scsi_devtype_direct: + err = grub_scsi_read10 (disk, sector, 1, buf); + break; + + case grub_scsi_devtype_cdrom: + err = grub_scsi_read12 (disk, sector, 1, buf); + break; + + default: /* This should not happen */ + return GRUB_ERR_READ_ERROR; + } + if (err) + return err; + sector++; + buf += scsi->blocksize; + } + + return err; +#endif } static grub_err_t diff --git a/disk/usbms.c b/disk/usbms.c index 7b719fb84..a49b30e7e 100644 --- a/disk/usbms.c +++ b/disk/usbms.c @@ -253,6 +253,7 @@ grub_usbms_transfer (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd, struct grub_usbms_csw status; static grub_uint32_t tag = 0; grub_usb_err_t err = GRUB_USB_ERR_NONE; + grub_usb_err_t errCSW = GRUB_USB_ERR_NONE; int retrycnt = 3 + 1; grub_size_t i; @@ -290,9 +291,8 @@ grub_usbms_transfer (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd, { if (err == GRUB_USB_ERR_STALL) { - grub_usb_clear_halt (dev->dev, dev->in->endp_addr); grub_usb_clear_halt (dev->dev, dev->out->endp_addr); - goto retry; + goto CheckCSW; } return grub_error (GRUB_ERR_IO, "USB Mass Storage request failed"); } @@ -302,7 +302,12 @@ grub_usbms_transfer (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd, { err = grub_usb_bulk_read (dev->dev, dev->in->endp_addr, size, buf); grub_dprintf ("usb", "read: %d %d\n", err, GRUB_USB_ERR_STALL); - if (err) goto CheckCSW; + if (err) + { + if (err == GRUB_USB_ERR_STALL) + grub_usb_clear_halt (dev->dev, dev->in->endp_addr); + goto CheckCSW; + } /* Debug print of received data. */ grub_dprintf ("usb", "buf:\n"); if (size <= 64) @@ -316,6 +321,12 @@ grub_usbms_transfer (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd, err = grub_usb_bulk_write (dev->dev, dev->out->endp_addr, size, buf); grub_dprintf ("usb", "write: %d %d\n", err, GRUB_USB_ERR_STALL); grub_dprintf ("usb", "buf:\n"); + if (err) + { + if (err == GRUB_USB_ERR_STALL) + grub_usb_clear_halt (dev->dev, dev->out->endp_addr); + goto CheckCSW; + } /* Debug print of sent data. */ if (size <= 256) for (i=0; idev, dev->in->endp_addr, + errCSW = grub_usb_bulk_read (dev->dev, dev->in->endp_addr, sizeof (status), (char *) &status); - if (err) + if (errCSW) { grub_usb_clear_halt (dev->dev, dev->in->endp_addr); - err = grub_usb_bulk_read (dev->dev, dev->in->endp_addr, + errCSW = grub_usb_bulk_read (dev->dev, dev->in->endp_addr, sizeof (status), (char *) &status); - if (err) + if (errCSW) { /* Bulk-only reset device. */ + grub_dprintf ("usb", "Bulk-only reset device - errCSW\n"); grub_usbms_reset (dev->dev, dev->interface); grub_usb_clear_halt (dev->dev, dev->in->endp_addr); grub_usb_clear_halt (dev->dev, dev->out->endp_addr); @@ -347,9 +359,11 @@ CheckCSW: status.signature, status.tag, status.residue); grub_dprintf ("usb", "CSW: status=0x%02x\n", status.status); - /* If phase error, do bulk-only reset device. */ - if (status.status == 2) - { + /* If phase error or not valid signature, do bulk-only reset device. */ + if ((status.status == 2) || + (status.signature != grub_cpu_to_le32(0x53425355))) + { /* Bulk-only reset device. */ + grub_dprintf ("usb", "Bulk-only reset device - bad status\n"); grub_usbms_reset (dev->dev, dev->interface); grub_usb_clear_halt (dev->dev, dev->in->endp_addr); grub_usb_clear_halt (dev->dev, dev->out->endp_addr); @@ -357,9 +371,13 @@ CheckCSW: goto retry; } - if (status.status) + /* If "command failed" status or data transfer failed -> error */ + if ((status.status || err) && !read_write) return grub_error (GRUB_ERR_READ_ERROR, "error communication with USB Mass Storage device"); + else if ((status.status || err) && read_write) + return grub_error (GRUB_ERR_WRITE_ERROR, + "error communication with USB Mass Storage device"); return GRUB_ERR_NONE; } diff --git a/include/grub/usb.h b/include/grub/usb.h index cbbc39303..64dc78d61 100644 --- a/include/grub/usb.h +++ b/include/grub/usb.h @@ -35,7 +35,8 @@ typedef enum GRUB_USB_ERR_NAK, GRUB_USB_ERR_BABBLE, GRUB_USB_ERR_TIMEOUT, - GRUB_USB_ERR_BITSTUFF + GRUB_USB_ERR_BITSTUFF, + GRUB_USB_ERR_UNRECOVERABLE } grub_usb_err_t; typedef enum diff --git a/include/grub/usbtrans.h b/include/grub/usbtrans.h index cd818e1fc..40fc0dd5f 100644 --- a/include/grub/usbtrans.h +++ b/include/grub/usbtrans.h @@ -58,6 +58,9 @@ struct grub_usb_transfer struct grub_usb_device *dev; struct grub_usb_transaction *transactions; + + int last_trans; + /* Index of last processed transaction in OHCI/UHCI driver. */ }; typedef struct grub_usb_transfer *grub_usb_transfer_t; diff --git a/term/usb_keyboard.c b/term/usb_keyboard.c index 5d76c5e02..69d5709b6 100644 --- a/term/usb_keyboard.c +++ b/term/usb_keyboard.c @@ -18,7 +18,6 @@ */ #include -#include #include #include #include From 0d9ff59345a63087e02bb2415a62ae6cd50a6f42 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 1 Jun 2010 18:05:29 +0100 Subject: [PATCH 693/738] * kern/emu/getroot.c (find_root_device_from_mountinfo): Use getline instead of fgets into a static buffer. Use sizeof instead of strlen on a constant string. Thanks to Vladimir for review. --- ChangeLog.btrfs-probe | 2 +- kern/emu/getroot.c | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/ChangeLog.btrfs-probe b/ChangeLog.btrfs-probe index 77c9995c8..c79e6b6a4 100644 --- a/ChangeLog.btrfs-probe +++ b/ChangeLog.btrfs-probe @@ -1,4 +1,4 @@ -2010-05-18 Colin Watson +2010-06-01 Colin Watson Add btrfs probing support, currently only in the single-device case. diff --git a/kern/emu/getroot.c b/kern/emu/getroot.c index da62089fa..97c24115b 100644 --- a/kern/emu/getroot.c +++ b/kern/emu/getroot.c @@ -93,14 +93,15 @@ static char * find_root_device_from_mountinfo (const char *dir) { FILE *fp; - char buf[1024]; /* XXX */ + char *buf = NULL; + size_t len = 0; char *ret = NULL; fp = fopen ("/proc/self/mountinfo", "r"); if (! fp) return NULL; /* fall through to other methods */ - while (fgets (buf, sizeof (buf), fp)) + while (getline (&buf, &len, fp) > 0) { int mnt_id, parent_mnt_id; unsigned int major, minor; @@ -139,7 +140,7 @@ find_root_device_from_mountinfo (const char *dir) if (!sep) continue; - sep += strlen (" - "); + sep += sizeof (" - ") - 1; if (sscanf (sep, "%s %s", fstype, device) != 2) continue; @@ -152,6 +153,7 @@ find_root_device_from_mountinfo (const char *dir) ret = strdup (device); } + free (buf); fclose (fp); return ret; } From 390b0676c482abcc47c70a530b2bf4edb10f7479 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ale=C5=A1=20Nesrsta?= Date: Wed, 2 Jun 2010 02:04:45 +0200 Subject: [PATCH 694/738] Use dev->descdev.maxsize0 even if dev->initialized isn't set --- bus/usb/usbtrans.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bus/usb/usbtrans.c b/bus/usb/usbtrans.c index b3ee167a1..e1b9097e6 100644 --- a/bus/usb/usbtrans.c +++ b/bus/usb/usbtrans.c @@ -76,7 +76,7 @@ grub_usb_control_msg (grub_usb_device_t dev, setupdata_addr = grub_dma_get_phys (setupdata_chunk); /* Determine the maximum packet size. */ - if (dev->initialized && dev->descdev.maxsize0) + if (dev->descdev.maxsize0) max = dev->descdev.maxsize0; else max = 64; From ab6316112cc0ea4149168972c47f75b57a7b9eeb Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 2 Jun 2010 01:23:34 +0100 Subject: [PATCH 695/738] * conf/any-emu.rmk (kernel_img_SOURCES) [!x86]: Include kern/$(target_cpu)/cache.S even if TARGET_NO_MODULES = yes. --- ChangeLog | 5 +++++ conf/any-emu.rmk | 6 +++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index de0b62f08..d88c510eb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-06-02 Colin Watson + + * conf/any-emu.rmk (kernel_img_SOURCES) [!x86]: Include + kern/$(target_cpu)/cache.S even if TARGET_NO_MODULES = yes. + 2010-06-01 Colin Watson Add btrfs probing support, currently only in the single-device case. diff --git a/conf/any-emu.rmk b/conf/any-emu.rmk index 000996172..21e139a32 100644 --- a/conf/any-emu.rmk +++ b/conf/any-emu.rmk @@ -20,14 +20,14 @@ TARGET_NO_STRIP = yes ifneq ($(TARGET_NO_MODULES), yes) kernel_img_SOURCES += symlist.c kern/$(target_cpu)/dl.c +else +kernel_img_SOURCES += grub_emu_init.c +endif ifneq ($(target_cpu), i386) ifneq ($(target_cpu), x86_64) kernel_img_SOURCES += kern/$(target_cpu)/cache.S endif endif -else -kernel_img_SOURCES += grub_emu_init.c -endif # For halt.mod. pkglib_MODULES += halt.mod From 9121567e16cf77ccd1f4a148580718436101c247 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 2 Jun 2010 02:37:55 +0100 Subject: [PATCH 696/738] * commands/gptsync.c (grub_cmd_gptsync): Fix typos. (GRUB_MOD_INIT): Fix capitalisation. * docs/grub.texi (Command-line and menu entry commands): Document gettext and gptsync commands. --- ChangeLog | 7 +++++++ commands/gptsync.c | 8 ++++---- docs/grub.texi | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index d88c510eb..9c11b2fa9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-06-02 Colin Watson + + * commands/gptsync.c (grub_cmd_gptsync): Fix typos. + (GRUB_MOD_INIT): Fix capitalisation. + * docs/grub.texi (Command-line and menu entry commands): Document + gettext and gptsync commands. + 2010-06-02 Colin Watson * conf/any-emu.rmk (kernel_img_SOURCES) [!x86]: Include diff --git a/commands/gptsync.c b/commands/gptsync.c index d217b5d5c..6364c13f7 100644 --- a/commands/gptsync.c +++ b/commands/gptsync.c @@ -138,8 +138,8 @@ grub_cmd_gptsync (grub_command_t cmd __attribute__ ((unused)), { grub_device_close (dev); return grub_error (GRUB_ERR_OUT_OF_RANGE, - "only partitions resding in the first 2TB " - "can be presen in hybrid MBR"); + "only partitions residing in the first 2TB " + "can be present in hybrid MBR"); } @@ -243,8 +243,8 @@ GRUB_MOD_INIT(gptsync) cmd = grub_register_command ("gptsync", grub_cmd_gptsync, N_("DEVICE [PARTITION[+/-[TYPE]]] ..."), N_("Fill hybrid MBR of GPT drive DEVICE. " - "specified partitions will be a part " - "of hybrid mbr. Up to 3 partitions are " + "Specified partitions will be a part " + "of hybrid MBR. Up to 3 partitions are " "allowed. TYPE is an MBR type. " "+ means that partition is active. " "Only one partition can be active.")); diff --git a/docs/grub.texi b/docs/grub.texi index bcc05c1f8..52aca3fbd 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -1139,6 +1139,8 @@ you forget a command, you can run the command @command{help} * date:: Display or set current date and time * echo:: Display a line of text * export:: Export an environment variable +* gettext:: Translate a string +* gptsync:: Fill an MBR based on GPT entries * halt:: Shut down your computer * help:: Show help messages * insmod:: Insert a module @@ -1320,6 +1322,38 @@ to subsidiary configuration files loaded using @command{configfile}. @end deffn +@node gettext +@subsection gettext + +@deffn Command gettext string +Translate @var{string} into the current language. + +The current language code is stored in the @samp{lang} variable in GRUB's +environment. Translation files in MO format are read from +@samp{locale_dir}, usually @file{/boot/grub/locale}. +@end deffn + + +@node gptsync +@subsection gptsync + +@deffn Command gptsync device [partition[+/-[type]]] @dots{} +Disks using the GUID Partition Table (GPT) also have a legacy Master Boot +Record (MBR) partition table for compatibility with the BIOS and with older +operating systems. The legacy MBR can only represent a limited subset of +GPT partition entries. + +This command populates the legacy MBR with the specified @var{partition} +entries on @var{device}. Up to three partitions may be used. + +@var{type} is an MBR partition type code; prefix with @samp{0x} if you want +to enter this in hexadecimal. The separator between @var{partition} and +@var{type} may be @samp{+} to make the partition active, or @samp{-} to make +it inactive; only one partition may be active. If both the separator and +type are omitted, then the partition will be inactive. +@end deffn + + @node halt @subsection halt From 34c9f0e949cfadddd88a8229f4d10184f3263646 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 2 Jun 2010 02:50:04 +0100 Subject: [PATCH 697/738] * docs/grub.texi (direntry): Remove grub-terminfo reference. (GNU GRUB manual): Likewise. (General commands): Update description of `terminfo' for GRUB 2. --- ChangeLog | 6 ++++++ docs/grub.texi | 21 +++++++++------------ 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9c11b2fa9..8a6f98be1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-06-02 Colin Watson + + * docs/grub.texi (direntry): Remove grub-terminfo reference. + (GNU GRUB manual): Likewise. + (General commands): Update description of `terminfo' for GRUB 2. + 2010-06-02 Colin Watson * commands/gptsync.c (grub_cmd_gptsync): Fix typos. diff --git a/docs/grub.texi b/docs/grub.texi index 52aca3fbd..657a5d146 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -34,9 +34,6 @@ Invariant Sections. @direntry * GRUB: (grub). The GRand Unified Bootloader * grub-install: (grub)Invoking grub-install. Install GRUB on your drive -* grub-terminfo: (grub)Invoking grub-terminfo. Generate a terminfo - command from a - terminfo name @end direntry @setchapternewpage odd @@ -89,7 +86,6 @@ This edition documents version @value{VERSION}. * Troubleshooting:: Error messages produced by GRUB * Invoking the grub shell:: How to use the grub shell * Invoking grub-install:: How to use the GRUB installer -* Invoking grub-terminfo:: How to generate a terminfo command * Obtaining and Building GRUB:: How to obtain and build GRUB * Reporting bugs:: Where you should send a bug report * Future:: Some future plans on GRUB @@ -1076,7 +1072,7 @@ Commands usable anywhere in the menu and in the command-line. @menu * serial:: Set up a serial device -* terminfo:: Define escape sequences for a terminal +* terminfo:: Define terminal type @end menu @@ -1108,15 +1104,16 @@ support. See also @ref{Serial terminal}. @node terminfo @subsection terminfo -@deffn Command terminfo @option{--name=name} @option{--cursor-address=seq} [@option{--clear-screen=seq}] [@option{--enter-standout-mode=seq}] [@option{--exit-standout-mode=seq}] -Define the capabilities of your terminal. Use this command to define -escape sequences, if it is not vt100-compatible. You may use @samp{\e} -for @key{ESC} and @samp{^X} for a control character. +@deffn Command terminfo [term] +Define the capabilities of your terminal by giving the name of an entry in +the terminfo database, which should correspond roughly to a @samp{TERM} +environment variable in Unix. -You can use the utility @command{grub-terminfo} to generate -appropriate arguments to this command. @xref{Invoking grub-terminfo}. +At the moment, only @samp{vt100} is supported in GRUB 2. If you need other +terminal types, please contact us to discuss the best way to include support +for these in GRUB. -If no option is specified, the current settings are printed. +If no option is specified, the current terminal type is printed. @end deffn From a18c78347304d00b521556ccc76d4c8564d417b0 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 2 Jun 2010 04:51:35 +0200 Subject: [PATCH 698/738] Fewstylistic fixes --- bus/usb/ohci.c | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/bus/usb/ohci.c b/bus/usb/ohci.c index ac6f61ee8..de0a4e7ac 100644 --- a/bus/usb/ohci.c +++ b/bus/usb/ohci.c @@ -594,10 +594,10 @@ grub_ohci_transfer (grub_usb_controller_t dev, } grub_dprintf ("ohci", "wait for completion\n"); - grub_dprintf ("ohci", - "begin: control=0x%02x status=0x%02x\n\t\t intstatus=0x%02x\n", + grub_dprintf ("ohci", "begin: control=0x%02x status=0x%02x\n", grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL), - grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS), + grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS)); + grub_dprintf ("ohci","intstatus=0x%02x\n", grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS)); /* Safety measure to avoid a hang. */ @@ -621,7 +621,7 @@ grub_ohci_transfer (grub_usb_controller_t dev, if (tderr_addr == td_list_addr + sizeof (td_list[0]) * (transfer->transcnt - 1)) break; - continue; + continue; } if ((intstatus & 0x10) != 0) @@ -651,9 +651,10 @@ grub_ohci_transfer (grub_usb_controller_t dev, } while (1); - grub_dprintf ("ohci", "end: control=0x%02x status=0x%02x\n\t\t intstatus=0x%02x\n", + grub_dprintf ("ohci", "end: control=0x%02x status=0x%02x\n", grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL), - grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS), + grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS)); + grub_dprintf ("ohci", "intstatus=0x%02x\n", grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS)); if (!tderr_addr) @@ -688,21 +689,22 @@ grub_ohci_transfer (grub_usb_controller_t dev, if (err_timeout) { err = GRUB_ERR_TIMEOUT; - grub_dprintf("ohci", "Timeout, target=%08x, head=%08x\n\t\ttail=%08x, next=%08x\n", - grub_le_to_cpu32(ed->target), - grub_le_to_cpu32(ed->td_head), - grub_le_to_cpu32(ed->td_tail), - grub_le_to_cpu32(ed->next_ed)); + grub_dprintf("ohci", "Timeout, target=%08x, head=%08x\n", + grub_le_to_cpu32(ed->target), + grub_le_to_cpu32(ed->td_head)); + grub_dprintf("ohci", "tail=%08x, next=%08x\n", + grub_le_to_cpu32(ed->td_tail), + grub_le_to_cpu32(ed->next_ed)); } /* In case of unrecoverable error do not detect error from TD */ else if (err_unrec) { err = GRUB_USB_ERR_UNRECOVERABLE; grub_dprintf("ohci", - "Unrecoverable error, target=%08x, head=%08x\n" - "\t\ttail=%08x, next=%08x\n", + "Unrecoverable error, target=%08x, head=%08x\n", grub_le_to_cpu32(ed->target), - grub_le_to_cpu32(ed->td_head), + grub_le_to_cpu32(ed->td_head)); + grub_dprintf("ohci", "tail=%08x, next=%08x\n", grub_le_to_cpu32(ed->td_tail), grub_le_to_cpu32(ed->next_ed)); } From 2325800310ce4ac9a5088f5c3fca68e44155e145 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 2 Jun 2010 04:52:35 +0200 Subject: [PATCH 699/738] Fix last_trans determination --- bus/usb/ohci.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/bus/usb/ohci.c b/bus/usb/ohci.c index de0a4e7ac..4d66df0bc 100644 --- a/bus/usb/ohci.c +++ b/bus/usb/ohci.c @@ -671,15 +671,21 @@ grub_ohci_transfer (grub_usb_controller_t dev, /* Remember last processed transaction (TD) - it is necessary for * proper setting of toggle bit in next transaction. */ - transfer->last_trans = (tderr_addr - td_list_addr) / sizeof (*td_list); - + transfer->last_trans = ((tderr_addr - td_list_addr) / sizeof (*td_list)); + grub_dprintf("ohci", "tderr_addr=0x%x, td_list_addr=0x%x,\n", + tderr_addr, td_list_addr); + + if ((ed->td_head & ~0xf) == (ed->td_tail & ~0xf)) + transfer->last_trans = transfer->transcnt - 1; + /* Check correct value in last_trans */ /* It could happen if timeout happens and no TD was retired */ if (transfer->last_trans >= transfer->transcnt || !tderr_addr) { - grub_dprintf("ohci", "tder==0 or out of TDs range!\n"); - grub_dprintf("ohci", "tderr_addr=0x%x, td_list=%p,\n\t\t last_trans=%d, transcnt=%d\n", - tderr_addr, td_list, transfer->last_trans, transfer->transcnt); + grub_dprintf("ohci", "tderr==0 or out of TDs range!\n"); + grub_dprintf("ohci", "last_trans=%d, transcnt=%d\n", + transfer->last_trans, transfer->transcnt); + /* We should set something valid... */ transfer->last_trans = -1; /* Probably no TD done */ tderr_addr = td_list_addr; @@ -713,6 +719,8 @@ grub_ohci_transfer (grub_usb_controller_t dev, grub_uint8_t errcode; grub_ohci_td_t tderr = NULL; + transfer->last_trans--; + tderr = (grub_ohci_td_t) ((char *) td_list + (tderr_addr - td_list_addr)); From f1cb760c99f77795f1c91f11f8157d6984f4593f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 2 Jun 2010 04:52:52 +0200 Subject: [PATCH 700/738] Disable unused list --- bus/usb/ohci.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/bus/usb/ohci.c b/bus/usb/ohci.c index 4d66df0bc..fd378cc8d 100644 --- a/bus/usb/ohci.c +++ b/bus/usb/ohci.c @@ -563,9 +563,14 @@ grub_ohci_transfer (grub_usb_controller_t dev, grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKHEAD, ed_addr); grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKCURR, 0); +#define GRUB_OHCI_REG_CONTROL_BULK_ENABLE (1 << 5) +#define GRUB_OHCI_REG_CONTROL_CONTROL_ENABLE (1 << 4) + /* Enable the Bulk list. */ control = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL); - control |= 1 << 5; + control |= GRUB_OHCI_REG_CONTROL_BULK_ENABLE; + control &= ~GRUB_OHCI_REG_CONTROL_CONTROL_ENABLE; + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, control); /* Set BulkListFilled. */ @@ -578,12 +583,15 @@ grub_ohci_transfer (grub_usb_controller_t dev, case GRUB_USB_TRANSACTION_TYPE_CONTROL: { + grub_dprintf ("ohci", "add to control list\n"); + /* Set ControlList Head and Current */ grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD, ed_addr); grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLCURR, 0); /* Enable the Control list. */ - control |= 1 << 4; + control |= GRUB_OHCI_REG_CONTROL_CONTROL_ENABLE; + control &= ~GRUB_OHCI_REG_CONTROL_BULK_ENABLE; grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, control); /* Set ControlListFilled. */ From d4955444976a90377d0ff9d8140bb906c2c36f46 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 2 Jun 2010 05:00:54 +0200 Subject: [PATCH 701/738] Shut down PHCI controller harder --- bus/usb/ohci.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/bus/usb/ohci.c b/bus/usb/ohci.c index fd378cc8d..a42d9fee1 100644 --- a/bus/usb/ohci.c +++ b/bus/usb/ohci.c @@ -970,7 +970,10 @@ grub_ohci_fini_hw (int noreturn __attribute__ ((unused))) grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKHEAD, 0); grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKCURR, 0); grub_ohci_writereg32 (o, GRUB_OHCI_REG_DONEHEAD, 0); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, 0); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, 1); } + grub_millisleep (10); return GRUB_ERR_NONE; } From 288dd6ed3d88420e4fcc28a7aeeef0916c673cd5 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 2 Jun 2010 11:14:02 +0100 Subject: [PATCH 702/738] * docs/grub.texi (Configuration): New section, documenting configuration file generation using grub-mkconfig. I've left a slot for documenting the full shell scripting format but have not yet started on writing that up. (Invoking grub-mkconfig): New section. --- ChangeLog | 8 ++ docs/grub.texi | 221 ++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 228 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 8a6f98be1..214be173c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2010-06-02 Colin Watson + + * docs/grub.texi (Configuration): New section, documenting + configuration file generation using grub-mkconfig. I've left a slot + for documenting the full shell scripting format but have not yet + started on writing that up. + (Invoking grub-mkconfig): New section. + 2010-06-02 Colin Watson * docs/grub.texi (direntry): Remove grub-terminfo reference. diff --git a/docs/grub.texi b/docs/grub.texi index 657a5d146..77f151cfc 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -20,7 +20,7 @@ This manual is for GNU GRUB (version @value{VERSION}, @value{UPDATED}). -Copyright @copyright{} 1999,2000,2001,2002,2004,2006,2008,2009 Free Software Foundation, Inc. +Copyright @copyright{} 1999,2000,2001,2002,2004,2006,2008,2009,2010 Free Software Foundation, Inc. @quotation Permission is granted to copy, distribute and/or modify this document @@ -34,6 +34,7 @@ Invariant Sections. @direntry * GRUB: (grub). The GRand Unified Bootloader * grub-install: (grub)Invoking grub-install. Install GRUB on your drive +* grub-mkconfig: (grub)Invoking grub-mkconfig. Generate GRUB configuration @end direntry @setchapternewpage odd @@ -86,6 +87,7 @@ This edition documents version @value{VERSION}. * Troubleshooting:: Error messages produced by GRUB * Invoking the grub shell:: How to use the grub shell * Invoking grub-install:: How to use the GRUB installer +* Invoking grub-mkconfig:: Generate a GRUB configuration file * Obtaining and Building GRUB:: How to obtain and build GRUB * Reporting bugs:: Where you should send a bug report * Future:: Some future plans on GRUB @@ -694,6 +696,197 @@ the size, run the command @command{uppermem} @emph{before} loading the kernel. @xref{uppermem}, for more information. +@node Configuration +@chapter Writing your own configuration file + +GRUB is configured using @file{grub.cfg}, usually located under +@file{/boot/grub}. This file is quite flexible, but most users will not +need to write the whole thing by hand. + +@menu +* Simple configuration:: Recommended for most users +* Shell-like scripting:: For power users and developers +@end menu + + +@node Simple configuration +@section Simple configuration handling + +The program @command{grub-mkconfig} (@pxref{Invoking grub-mkconfig}) +generates @file{grub.cfg} files suitable for most cases. It is suitable for +use when upgrading a distribution, and will discover available kernels and +attempt to generate menu entries for them. + +The file @file{/etc/default/grub} controls the operation of +@command{grub-mkconfig}. It is sourced by a shell script, and so must be +valid POSIX shell input; normally, it will just be a sequence of +@samp{KEY=value} lines, but if the value contains spaces or other special +characters then it must be quoted. For example: + +@example +GRUB_TERMINAL_INPUT="console serial" +@end example + +Valid keys in @file{/etc/default/grub} are as follows: + +@table @samp +@item GRUB_DEFAULT +The default menu entry. This may be a number, in which case it identifies +the Nth entry in the generated menu counted from zero, or the full name of a +menu entry, or the special string @samp{saved}. Using the full name may be +useful if you want to set a menu entry as the default even though there may +be a variable number of entries before it. + +If you set this to @samp{saved}, then the default menu entry will be that +saved by @samp{GRUB_SAVEDEFAULT}, @command{grub-set-default}, or +@command{grub-reboot}. + +The default is @samp{0}. + +@item GRUB_SAVEDEFAULT +If this option is set to @samp{true}, then, when an entry is selected, save +it as a new default entry for use by future runs of GRUB. This is only +useful if @samp{GRUB_DEFAULT=saved}; it is a separate option because +@samp{GRUB_DEFAULT=saved} is useful without this option, in conjunction with +@command{grub-set-default} or @command{grub-reboot}. Unset by default. + +@item GRUB_TIMEOUT +Boot the default entry this many seconds after the menu is displayed, unless +a key is pressed. The default is @samp{5}. Set to @samp{0} to boot +immediately without displaying the menu, or to @samp{-1} to wait +indefinitely. + +@item GRUB_HIDDEN_TIMEOUT +Wait this many seconds for a key to be pressed before displaying the menu. +If no key is pressed during that time, boot immediately. Unset by default. + +@item GRUB_HIDDEN_TIMEOUT_QUIET +In conjunction with @samp{GRUB_HIDDEN_TIMEOUT}, set this to @samp{true} to +suppress the verbose countdown while waiting for a key to be pressed before +displaying the menu. Unset by default. + +@item GRUB_DEFAULT_BUTTON +@itemx GRUB_TIMEOUT_BUTTON +@itemx GRUB_HIDDEN_TIMEOUT_BUTTON +@itemx GRUB_BUTTON_CMOS_ADDRESS +Variants of the corresponding variables without the @samp{_BUTTON} suffix, +used to support vendor-specific power buttons. @xref{Vendor power-on keys}. + +@item GRUB_DISTRIBUTOR +Set by distributors of GRUB to their identifying name. This is used to +generate more informative menu entry titles. + +@item GRUB_TERMINAL_INPUT +Select the terminal input device. You may select multiple devices here, +separated by spaces. + +Valid terminal input names depend on the platform, but may include +@samp{console} (PC BIOS and EFI consoles), @samp{serial} (serial terminal), +@samp{ofconsole} (Open Firmware console), @samp{at_keyboard} (PC AT +keyboard, mainly useful with Coreboot), or @samp{usb_keyboard} (USB keyboard +using the HID Boot Protocol, for cases where the firmware does not handle +this). + +The default is to use the platform's native terminal input. + +@item GRUB_TERMINAL_OUTPUT +Select the terminal output device. You may select multiple devices here, +separated by spaces. + +Valid terminal output names depend on the platform, but may include +@samp{console} (PC BIOS and EFI consoles), @samp{serial} (serial terminal), +@samp{gfxterm} (graphics-mode output), @samp{ofconsole} (Open Firmware +console), or @samp{vga_text} (VGA text output, mainly useful with Coreboot). + +The default is to use the platform's native terminal input. + +@item GRUB_TERMINAL +If this option is set, it overrides both @samp{GRUB_TERMINAL_INPUT} and +@samp{GRUB_TERMINAL_OUTPUT} to the same value. + +@item GRUB_SERIAL_COMMAND +A command to configure the serial port when using the serial console. +@xref{serial}. Defaults to @samp{serial}. + +@item GRUB_CMDLINE_LINUX +Command-line arguments to add to menu entries for the Linux kernel. + +@item GRUB_CMDLINE_LINUX_DEFAULT +Unless @samp{GRUB_DISABLE_LINUX_RECOVERY} is set, two menu entries will be +generated for each Linux kernel: one default entry and one entry for +recovery mode. This option lists command-line arguments to add only to the +default menu entry, after those listed in @samp{GRUB_CMDLINE_LINUX}. + +@item GRUB_CMDLINE_NETBSD +@itemx GRUB_CMDLINE_NETBSD_DEFAULT +As @samp{GRUB_CMDLINE_LINUX} and @samp{GRUB_CMDLINE_LINUX_DEFAULT}, but for +NetBSD. + +@item GRUB_DISABLE_LINUX_UUID +Normally, @command{grub-mkconfig} will generate menu entries that use +universally-unique identifiers (UUIDs) to identify the root filesystem to +the Linux kernel, using a @samp{root=UUID=...} kernel parameter. This is +usually more reliable, but in some cases it may not be appropriate. To +disable the use of UUIDs, set this option to @samp{true}. + +@item GRUB_DISABLE_LINUX_RECOVERY +Disable the generation of recovery mode menu entries for Linux. + +@item GRUB_DISABLE_NETBSD_RECOVERY +Disable the generation of recovery mode menu entries for NetBSD. + +@item GRUB_GFXMODE +Set the resolution used on the @samp{gfxterm} graphical terminal. Note that +you can only use modes which your graphics card supports via VESA BIOS +Extensions (VBE), so for example native LCD panel resolutions may not be +available. The default is @samp{640x480}. + +@item GRUB_BACKGROUND +Set a background image for use with the @samp{gfxterm} graphical terminal. +The value of this option must be a file readable by GRUB at boot time, and +it must end with @file{.png}, @file{.tga}, @file{.jpg}, or @file{.jpeg}. +The image will be scaled if necessary to fit the screen. + +@item GRUB_THEME +Set a theme for use with the @samp{gfxterm} graphical terminal. +@xref{Themes}. + +@item GRUB_GFXPAYLOAD_LINUX +Set to @samp{text} to force the Linux kernel to boot in normal text mode, +@samp{keep} to preserve the graphics mode set using @samp{GRUB_GFXMODE}, +@samp{@var{width}x@var{height}}[@samp{x@var{depth}}] to set a particular +graphics mode, or a sequence of these separated by commas or semicolons to +try several modes in sequence. + +Depending on your kernel, your distribution, your graphics card, and the +phase of the moon, note that using this option may cause GNU/Linux to suffer +from various display problems, particularly during the early part of the +boot sequence. If you have problems, simply unset this option and GRUB will +tell Linux to boot in normal text mode. + +@item GRUB_DISABLE_OS_PROBER +Normally, @command{grub-mkconfig} will try to use the external +@command{os-prober} program, if installed, to discover other operating +systems installed on the same system and generate appropriate menu entries +for them. Set this option to @samp{true} to disable this. + +@item GRUB_INIT_TUNE +Play a tune on the speaker when GRUB starts. This is particularly useful +for users unable to see the screen. The value of this option is passed +directly to @ref{play}. +@end table + +For more detailed customisation of @command{grub-mkconfig}'s output, you may +edit the scripts in @file{/etc/grub.d} directly. +@file{/etc/grub.d/40_custom} is particularly useful for adding entire custom +menu entries; simply type the menu entries you want to add at the end of +that file, making sure to leave at least the first two lines intact. + + +@node Shell-like scripting +@section Writing full configuration files directly + + @node Serial terminal @chapter Using GRUB via a serial line @@ -1499,6 +1692,32 @@ into/from your computer. @end table +@node Invoking grub-mkconfig +@chapter Invoking grub-mkconfig + +The program @command{grub-mkconfig} generates a configuration file for GRUB +(@pxref{Simple configuration}). + +@example +grub-mkconfig -o /boot/grub/grub.cfg +@end example + +@command{grub-mkconfig} accepts the following options: + +@table @option +@item --help +Print a summary of the command-line options and exit. + +@item --version +Print the version number of GRUB and exit. + +@item -o @var{file} +@itemx --output=@var{file} +Send the generated configuration file to @var{file}. The default is to send +it to standard output. +@end table + + @node Obtaining and Building GRUB @appendix How to obtain and build GRUB From bb8ea0f5c324043bd09e024b41a2af262909b659 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 2 Jun 2010 11:26:28 +0100 Subject: [PATCH 703/738] * docs/grub.texi (GNU GRUB manual): Remove reference to `Invoking the grub shell'. (Installation): Add reference to `Making a GRUB bootable CD-ROM'. (Installing GRUB using grub-install): Remove reference to the grub shell; mention `grub-mkimage' and `grub-setup' instead. (Invoking grub-install): Likewise. (Interface): Add reference to `Menu entry editor'. (serial): Remove `--device' option. --- ChangeLog | 11 +++++++++++ docs/grub.texi | 26 ++++++++++++-------------- 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index 214be173c..905e36edf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2010-06-02 Colin Watson + + * docs/grub.texi (GNU GRUB manual): Remove reference to `Invoking + the grub shell'. + (Installation): Add reference to `Making a GRUB bootable CD-ROM'. + (Installing GRUB using grub-install): Remove reference to the grub + shell; mention `grub-mkimage' and `grub-setup' instead. + (Invoking grub-install): Likewise. + (Interface): Add reference to `Menu entry editor'. + (serial): Remove `--device' option. + 2010-06-02 Colin Watson * docs/grub.texi (Configuration): New section, documenting diff --git a/docs/grub.texi b/docs/grub.texi index 77f151cfc..4c903729b 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -85,7 +85,6 @@ This edition documents version @value{VERSION}. * Interface:: The menu and the command-line * Commands:: The list of available builtin commands * Troubleshooting:: Error messages produced by GRUB -* Invoking the grub shell:: How to use the grub shell * Invoking grub-install:: How to use the GRUB installer * Invoking grub-mkconfig:: Generate a GRUB configuration file * Obtaining and Building GRUB:: How to obtain and build GRUB @@ -451,6 +450,7 @@ the @dfn{boot directory}. @menu * Installing GRUB using grub-install:: +* Making a GRUB bootable CD-ROM:: @end menu @@ -530,11 +530,11 @@ quite careful. If the output is wrong, it is unlikely that your computer will be able to boot with no problem. Note that @command{grub-install} is actually just a shell script and the -real task is done by the grub shell @command{grub} (@pxref{Invoking the -grub shell}). Therefore, you may run @command{grub} directly to install -GRUB, without using @command{grub-install}. Don't do that, however, -unless you are very familiar with the internals of GRUB. Installing a -boot loader on a running OS may be extremely dangerous. +real task is done by @command{grub-mkimage} and @command{grub-setup}. +Therefore, you may run those commands directly to install GRUB, without +using @command{grub-install}. Don't do that, however, unless you are very +familiar with the internals of GRUB. Installing a boot loader on a running +OS may be extremely dangerous. @node Making a GRUB bootable CD-ROM @@ -1073,6 +1073,7 @@ the command-line interface. @menu * Command-line interface:: The flexible command-line interface * Menu interface:: The simple menu interface +* Menu entry editor:: Editing a menu entry @end menu @@ -1272,7 +1273,7 @@ Commands usable anywhere in the menu and in the command-line. @node serial @subsection serial -@deffn Command serial [@option{--unit=unit}] [@option{--port=port}] [@option{--speed=speed}] [@option{--word=word}] [@option{--parity=parity}] [@option{--stop=stop}] [@option{--device=dev}] +@deffn Command serial [@option{--unit=unit}] [@option{--port=port}] [@option{--speed=speed}] [@option{--word=word}] [@option{--parity=parity}] [@option{--stop=stop}] Initialize a serial device. @var{unit} is a number in the range 0-3 specifying which serial port to use; default is 0, which corresponds to the port often called COM1. @var{port} is the I/O port where the UART @@ -1281,10 +1282,7 @@ is to be found; if specified it takes precedence over @var{unit}. @var{stop} are the number of data bits and stop bits. Data bits must be in the range 5-8 and stop bits must be 1 or 2. Default is 8 data bits and one stop bit. @var{parity} is one of @samp{no}, @samp{odd}, -@samp{even} and defaults to @samp{no}. The option @option{--device} -can only be used in the grub shell and is used to specify the -tty device to be used in the host operating system (@pxref{Invoking the -grub shell}). +@samp{even} and defaults to @samp{no}. The serial port is not used as a communication channel unless the @command{terminal} command is used (@pxref{terminal}). @@ -1654,9 +1652,9 @@ Unset the environment variable @var{envvar}. @node Invoking grub-install @chapter Invoking grub-install -The program @command{grub-install} installs GRUB on your drive using the -grub shell (@pxref{Invoking the grub shell}). You must specify the -device name on which you want to install GRUB, like this: +The program @command{grub-install} installs GRUB on your drive using +@command{grub-mkimage} and (on some platforms) @command{grub-setup}. You +must specify the device name on which you want to install GRUB, like this: @example grub-install @var{install_device} From 1c41aa7883f3f8ba94e7e0c447f434840a4a0161 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 2 Jun 2010 12:47:11 +0100 Subject: [PATCH 704/738] * docs/grub.texi (Chain-loading): New section. (DOS/Windows): New section, borrowed from GRUB Legacy with details adjusted for GRUB 2. (SCO UnixWare): Likewise. (QNX): Likewise. (chainloader): Add reference to `Block list syntax'. (drivemap): New section. (parttool): New section. --- ChangeLog | 11 +++ docs/grub.texi | 187 +++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 193 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 905e36edf..b0fc06848 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2010-06-02 Colin Watson + + * docs/grub.texi (Chain-loading): New section. + (DOS/Windows): New section, borrowed from GRUB Legacy with details + adjusted for GRUB 2. + (SCO UnixWare): Likewise. + (QNX): Likewise. + (chainloader): Add reference to `Block list syntax'. + (drivemap): New section. + (parttool): New section. + 2010-06-02 Colin Watson * docs/grub.texi (GNU GRUB manual): Remove reference to `Invoking diff --git a/docs/grub.texi b/docs/grub.texi index 4c903729b..5f2e5e36a 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -647,6 +647,35 @@ use more complicated instructions. @xref{DOS/Windows}, for more information. +@node Chain-loading +@subsection Chain-loading an OS + +Operating systems that do not support Multiboot and do not have specific +support in GRUB (specific support is available for Linux, FreeBSD, NetBSD +and OpenBSD) must be chain-loaded, which involves loading another boot +loader and jumping to it in real mode. + +The @command{chainloader} command (@pxref{chainloader}) is used to set this +up. It is normally also necessary to load some GRUB modules and set the +appropriate root device. Putting this together, we get something like this, +for a Windows system on the first partition of the first hard disk: + +@verbatim +menuentry "Windows" { + insmod chain + insmod ntfs + set root=(hd0,1) + chainloader +1 +} +@end verbatim +@c FIXME: document UUIDs. + +On systems with multiple hard disks, an additional workaround may be +required. @xref{DOS/Windows}. + +Chain-loading is only supported on PC BIOS and EFI platforms. + + @node OS-specific notes @section Some caveats on OS-specific issues @@ -655,6 +684,9 @@ Here, we describe some caveats on several operating systems. @menu * GNU/Hurd:: * GNU/Linux:: +* DOS/Windows:: +* SCO UnixWare:: +* QNX:: @end menu @@ -696,6 +728,87 @@ the size, run the command @command{uppermem} @emph{before} loading the kernel. @xref{uppermem}, for more information. +@node DOS/Windows +@subsection DOS/Windows + +GRUB cannot boot DOS or Windows directly, so you must chain-load them +(@pxref{Chain-loading}). However, their boot loaders have some critical +deficiencies, so it may not work to just chain-load them. To overcome +the problems, GRUB provides you with two helper functions. + +If you have installed DOS (or Windows) on a non-first hard disk, you +have to use the disk swapping technique, because that OS cannot boot +from any disks but the first one. The workaround used in GRUB is the +command @command{drivemap} (@pxref{drivemap}), like this: + +@example +drivemap -s (hd0) (hd1) +@end example + +This performs a @dfn{virtual} swap between your first and second hard +drive. + +@strong{Caution:} This is effective only if DOS (or Windows) uses BIOS +to access the swapped disks. If that OS uses a special driver for the +disks, this probably won't work. + +Another problem arises if you installed more than one set of DOS/Windows +onto one disk, because they could be confused if there are more than one +primary partitions for DOS/Windows. Certainly you should avoid doing +this, but there is a solution if you do want to do so. Use the partition +hiding/unhiding technique. + +If GRUB @dfn{hides} a DOS (or Windows) partition (@pxref{parttool}), DOS (or +Windows) will ignore the partition. If GRUB @dfn{unhides} a DOS (or Windows) +partition, DOS (or Windows) will detect the partition. Thus, if you have +installed DOS (or Windows) on the first and the second partition of the +first hard disk, and you want to boot the copy on the first partition, do +the following: + +@example +@group +parttool (hd0,1) hidden- +parttool (hd0,2) hidden+ +set root=(hd0,1) +chainloader +1 +parttool @verb{'${root}'} boot+ +boot +@end group +@end example + + +@node SCO UnixWare +@subsection SCO UnixWare + +It is known that the signature in the boot loader for SCO UnixWare is +wrong, so you will have to specify the option @option{--force} to +@command{chainloader} (@pxref{chainloader}), like this: + +@example +@group +set root=(hd1,1) +chainloader --force +1 +parttool @verb{'${root}'} boot+ +boot +@end group +@end example + + +@node QNX +@subsection QNX + +QNX seems to use a bigger boot loader, so you need to boot it up, like +this: + +@example +@group +set root=(hd1,2) +chainloader +4 +boot +@end group +@end example + + @node Configuration @chapter Writing your own configuration file @@ -1325,6 +1438,7 @@ you forget a command, you can run the command @command{help} * configfile:: Load a configuration file * crc:: Calculate CRC32 checksums * date:: Display or set current date and time +* drivemap:: Map a drive to another * echo:: Display a line of text * export:: Export an environment variable * gettext:: Translate a string @@ -1334,6 +1448,7 @@ you forget a command, you can run the command @command{help} * insmod:: Insert a module * keystatus:: Check key modifier status * ls:: List devices or files +* parttool:: Modify partition table entries * play:: Play a tune * reboot:: Reboot your computer * set:: Set an environment variable @@ -1399,11 +1514,12 @@ grub> @kbd{cat /etc/fstab} @deffn Command chainloader [@option{--force}] file Load @var{file} as a chain-loader. Like any other file loaded by the -filesystem code, it can use the blocklist notation to grab the first -sector of the current partition with @samp{+1}. If you specify the -option @option{--force}, then load @var{file} forcibly, whether it has a -correct signature or not. This is required when you want to load a -defective boot loader, such as SCO UnixWare 7.1 (@pxref{SCO UnixWare}). +filesystem code, it can use the blocklist notation (@pxref{Block list +syntax}) to grab the first sector of the current partition with @samp{+1}. +If you specify the option @option{--force}, then load @var{file} forcibly, +whether it has a correct signature or not. This is required when you want to +load a defective boot loader, such as SCO UnixWare 7.1 (@pxref{SCO +UnixWare}). @end deffn @@ -1458,6 +1574,32 @@ hour, minute, and second unchanged. @end deffn +@node drivemap +@subsection drivemap + +@deffn Command drivemap @option{-l}|@option{-r}|[@option{-s}] @ + from_drive to_drive +Without options, map the drive @var{from_drive} to the drive @var{to_drive}. +This is necessary when you chain-load some operating systems, such as DOS, +if such an OS resides at a non-first drive. For convenience, any partition +suffix on the drive is ignored, so you can safely use @verb{'${root}'} as a +drive specification. + +With the @option{-s} option, perform the reverse mapping as well, swapping +the two drives. + +With the @option{-l} option, list the current mappings. + +With the @option{-r} option, reset all mappings to the default values. + +For example: + +@example +drivemap -s (hd0) (hd1) +@end example +@end deffn + + @node echo @subsection echo @@ -1605,6 +1747,41 @@ name syntax}), then list the contents of that directory. @end deffn +@node parttool +@subsection parttool + +@deffn Command parttool partition commands +Make various modifications to partition table entries. + +Each @var{command} is either a boolean option, in which case it must be +followed with @samp{+} or @samp{-} (with no intervening space) to enable or +disable that option, or else it takes a value in the form +@samp{@var{command}=@var{value}}. + +Currently, @command{parttool} is only useful on DOS partition tables (also +known as Master Boot Record, or MBR). On these partition tables, the +following commands are available: + +@table @asis +@item @samp{boot} (boolean) +When enabled, this makes the selected partition be the active (bootable) +partition on its disk, clearing the active flag on all other partitions. +This command is limited to @emph{primary} partitions. + +@item @samp{type} (value) +Change the type of an existing partition. The value must be a number in the +range 0-0xFF (prefix with @samp{0x} to enter it in hexadecimal). + +@item @samp{hidden} (boolean) +When enabled, this hides the selected partition by setting the @dfn{hidden} +bit in its partition type code; when disabled, unhides the selected +partition by clearing this bit. This is useful only when booting DOS or +Wwindows and multiple primary FAT partitions exist in one disk. See also +@ref{DOS/Windows}. +@end table +@end deffn + + @node play @subsection play From ca0afd5bab02d1e26dae496435b48647e44e08a8 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 2 Jun 2010 13:11:33 +0100 Subject: [PATCH 705/738] * docs/grub.texi (SCO UnixWare): Remove, at Vladimir's request and per the GNU Coding Standards; this is now too obscure to be worth documenting. (QNX): Likewise. (chainloader): Remove cross-reference to `SCO UnixWare'. --- ChangeLog | 8 ++++++++ docs/grub.texi | 37 +------------------------------------ 2 files changed, 9 insertions(+), 36 deletions(-) diff --git a/ChangeLog b/ChangeLog index b0fc06848..61e4ea8ec 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2010-06-02 Colin Watson + + * docs/grub.texi (SCO UnixWare): Remove, at Vladimir's request and + per the GNU Coding Standards; this is now too obscure to be worth + documenting. + (QNX): Likewise. + (chainloader): Remove cross-reference to `SCO UnixWare'. + 2010-06-02 Colin Watson * docs/grub.texi (Chain-loading): New section. diff --git a/docs/grub.texi b/docs/grub.texi index 5f2e5e36a..1f0c2083e 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -685,8 +685,6 @@ Here, we describe some caveats on several operating systems. * GNU/Hurd:: * GNU/Linux:: * DOS/Windows:: -* SCO UnixWare:: -* QNX:: @end menu @@ -777,38 +775,6 @@ boot @end example -@node SCO UnixWare -@subsection SCO UnixWare - -It is known that the signature in the boot loader for SCO UnixWare is -wrong, so you will have to specify the option @option{--force} to -@command{chainloader} (@pxref{chainloader}), like this: - -@example -@group -set root=(hd1,1) -chainloader --force +1 -parttool @verb{'${root}'} boot+ -boot -@end group -@end example - - -@node QNX -@subsection QNX - -QNX seems to use a bigger boot loader, so you need to boot it up, like -this: - -@example -@group -set root=(hd1,2) -chainloader +4 -boot -@end group -@end example - - @node Configuration @chapter Writing your own configuration file @@ -1518,8 +1484,7 @@ filesystem code, it can use the blocklist notation (@pxref{Block list syntax}) to grab the first sector of the current partition with @samp{+1}. If you specify the option @option{--force}, then load @var{file} forcibly, whether it has a correct signature or not. This is required when you want to -load a defective boot loader, such as SCO UnixWare 7.1 (@pxref{SCO -UnixWare}). +load a defective boot loader, such as SCO UnixWare 7.1. @end deffn From 0b35b2a9211feafd80a1a203e793a1e68ccbe5a3 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 2 Jun 2010 13:57:13 +0100 Subject: [PATCH 706/738] * util/grub.d/00_header.in: Add safety check to make sure that ${locale_dir} exists before trying to probe it. --- ChangeLog | 5 +++++ util/grub.d/00_header.in | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 61e4ea8ec..fb73905e2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-06-02 Colin Watson + + * util/grub.d/00_header.in: Add safety check to make sure that + ${locale_dir} exists before trying to probe it. + 2010-06-02 Colin Watson * docs/grub.texi (SCO UnixWare): Remove, at Vladimir's request and diff --git a/util/grub.d/00_header.in b/util/grub.d/00_header.in index df8f5dfaa..0a5cfac18 100644 --- a/util/grub.d/00_header.in +++ b/util/grub.d/00_header.in @@ -195,7 +195,7 @@ EOF esac # Gettext variables and module -if [ "x${LANG}" != "xC" ] ; then +if [ "x${LANG}" != "xC" ] && [ -d "${locale_dir}" ] ; then prepare_grub_to_access_device $(${grub_probe} --target=device ${locale_dir}) cat << EOF set locale_dir=(\$root)$(make_system_path_relative_to_its_root ${locale_dir}) From 11dccbfd4d2ed5e91e5f4f767161a0095ef01025 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 2 Jun 2010 16:45:43 +0200 Subject: [PATCH 707/738] Sort scsi_cmd_t. --- include/grub/scsicmd.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/grub/scsicmd.h b/include/grub/scsicmd.h index f9a7cb200..9cc5afe72 100644 --- a/include/grub/scsicmd.h +++ b/include/grub/scsicmd.h @@ -147,14 +147,14 @@ struct grub_scsi_write12 typedef enum { - grub_scsi_cmd_inquiry = 0x12, grub_scsi_cmd_test_unit_ready = 0x00, + grub_scsi_cmd_request_sense = 0x03, + grub_scsi_cmd_inquiry = 0x12, grub_scsi_cmd_read_capacity = 0x25, grub_scsi_cmd_read10 = 0x28, grub_scsi_cmd_write10 = 0x2a, grub_scsi_cmd_read12 = 0xa8, grub_scsi_cmd_write12 = 0xaa, - grub_scsi_cmd_request_sense = 0x03 } grub_scsi_cmd_t; typedef enum From f0e6cceb813e626d313ae6b15e03683b82b322ca Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 2 Jun 2010 16:46:37 +0200 Subject: [PATCH 708/738] Remove leftover early debug exit. --- commands/usbtest.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/commands/usbtest.c b/commands/usbtest.c index 7d1f85cfd..191c4e4df 100644 --- a/commands/usbtest.c +++ b/commands/usbtest.c @@ -148,8 +148,6 @@ usb_iterate (grub_usb_device_t dev) grub_printf ("%s speed device\n", usb_devspeed[dev->speed]); - return 0; - for (i = 0; i < descdev->configcnt; i++) { struct grub_usb_desc_config *config; From 8bd3a1fb3027c7e05be06d5145bd8d16ee1bcbeb Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 2 Jun 2010 16:46:55 +0200 Subject: [PATCH 709/738] Add necessarry cast --- disk/scsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/disk/scsi.c b/disk/scsi.c index dffabc26e..5d3e50966 100644 --- a/disk/scsi.c +++ b/disk/scsi.c @@ -460,7 +460,7 @@ grub_scsi_open (const char *name, grub_disk_t disk) grub_dprintf ("scsi", "blocks=%u, blocksize=%u\n", scsi->size, scsi->blocksize); grub_dprintf ("scsi", "Disk total 512 sectors = %llu\n", - disk->total_sectors); + (unsigned long long) disk->total_sectors); return GRUB_ERR_NONE; } From f133a8a74b31c085e68831f76a7e78a8c49629da Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 2 Jun 2010 16:48:10 +0200 Subject: [PATCH 710/738] Enable USB on 64-bit (still won't work with >= 4GiB memory). --- bus/pci.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/bus/pci.c b/bus/pci.c index 3e2126962..1635e889b 100644 --- a/bus/pci.c +++ b/bus/pci.c @@ -21,7 +21,8 @@ #include #include -#if GRUB_TARGET_SIZEOF_VOID_P == 4 +/* FIXME: correctly support 64-bit architectures. */ +/* #if GRUB_TARGET_SIZEOF_VOID_P == 4 */ struct grub_pci_dma_chunk * grub_memalign_dma32 (grub_size_t align, grub_size_t size) { @@ -33,7 +34,7 @@ grub_dma_free (struct grub_pci_dma_chunk *ch) { grub_free (ch); } -#endif +/* #endif */ #ifdef GRUB_MACHINE_MIPS_YEELOONG volatile void * From 5d538b8b4a17de54cda284ee1ba081afbef8f978 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 2 Jun 2010 16:49:22 +0200 Subject: [PATCH 711/738] Use memset --- bus/usb/usb.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/bus/usb/usb.c b/bus/usb/usb.c index 7df148333..c872e9276 100644 --- a/bus/usb/usb.c +++ b/bus/usb/usb.c @@ -105,10 +105,7 @@ grub_usb_clear_halt (grub_usb_device_t dev, int endpoint) grub_usb_err_t grub_usb_set_configuration (grub_usb_device_t dev, int configuration) { - int i; - - for (i = 0; i < 256; i++) - dev->toggle[i] = 0; + grub_memset (dev->toggle, 0, sizeof (dev->toggle)); return grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT | GRUB_USB_REQTYPE_STANDARD From 7db51e329b7e8f0cdeaea60b2fd866105406d9c4 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 2 Jun 2010 16:51:54 +0200 Subject: [PATCH 712/738] Remove double defines and use dma_free --- bus/usb/ohci.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/bus/usb/ohci.c b/bus/usb/ohci.c index a42d9fee1..956a27292 100644 --- a/bus/usb/ohci.c +++ b/bus/usb/ohci.c @@ -339,10 +339,8 @@ grub_ohci_pci_iter (grub_pci_device_t dev, return 0; fail: -#ifndef GRUB_MACHINE_MIPS_YEELOONG if (o) - grub_free ((void *) o->hcca); -#endif + grub_dma_free (o->hcca_chunk); grub_free (o); return 0; @@ -883,11 +881,6 @@ grub_ohci_transfer (grub_usb_controller_t dev, return err; } -#define GRUB_OHCI_SET_PORT_ENABLE (1 << 1) -#define GRUB_OHCI_CLEAR_PORT_ENABLE (1 << 0) -#define GRUB_OHCI_SET_PORT_RESET (1 << 4) -#define GRUB_OHCI_SET_PORT_RESET_STATUS_CHANGE (1 << 20) - static grub_err_t grub_ohci_portstatus (grub_usb_controller_t dev, unsigned int port, unsigned int enable) From 49396b4f61726411e4d7bfaefbf2f62e93763102 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 2 Jun 2010 16:52:16 +0200 Subject: [PATCH 713/738] Add ChangeLog --- ChangeLog | 119 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) diff --git a/ChangeLog b/ChangeLog index 5072a6026..a693e4385 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,122 @@ +2010-06-02 Aleš Nesrsta + + Finally make USB usable. + + * bus/usb/ohci.c (grub_ohci_reg_t): Add missing values. + (GRUB_OHCI_RHUB_PORT_POWER_MASK): New macro. + (GRUB_OHCI_RHUB_PORT_ALL_POWERED): Likewise. + (GRUB_OHCI_REG_FRAME_INTERVAL_FSMPS_MASK): Likewise. + (GRUB_OHCI_REG_FRAME_INTERVAL_FSMPS_SHIFT): Likewise. + (GRUB_OHCI_REG_FRAME_INTERVAL_FI_SHIFT): Likewise. + (GRUB_OHCI_FSMPS): Likewise. + (GRUB_OHCI_PERIODIC_START): Likewise. + (GRUB_OHCI_FRAME_INTERVAL): Likewise. + (GRUB_OHCI_SET_PORT_ENABLE): Likewise. + (GRUB_OHCI_CLEAR_PORT_ENABLE): Likewise. + (GRUB_OHCI_SET_PORT_RESET): Likewise. + (GRUB_OHCI_SET_PORT_RESET_STATUS_CHANGE): Likewise. + * bus/usb/ohci.c (grub_ohci_pci_iter): Various important fixups. + (grub_ohci_transaction): Likewise. + (grub_ohci_transfer): Improve condition detection algorithms. + Handle toggle property. Program the transactions correctly. + Improve error handling. Various important fixups. + (grub_ohci_portstatus): Put register writes in right order. + * bus/usb/uhci.c (grub_free_queue): Compute last_trans. + (grub_uhci_transfer): Don't show "failed" message on success. + * bus/usb/usb.c (grub_usb_set_configuration): Zero-fill whole "toggle" + array. + (grub_usb_device_initialize): Read first 8 bytes of descriptor to + determine its size. + * bus/usb/usbtrans.c (grub_usb_control_msg): Use descdev.maxsize0 even + before initialization is completed. Use IN direction for empty + transfers. Use last_trans and compute toggle. + * include/grub/usbtrans.h (grub_usb_transfer): New field last_trans. + (GRUB_USB_FEATURE_ENDP_HALT): Correct the value. + (GRUB_USB_FEATURE_DEV_REMOTE_WU): Likewise. + (GRUB_USB_FEATURE_TEST_MODE): Likewise. + * include/grub/usb.h (grub_usb_err_t): New value GRUB_USB_ERR_UNRECOVERABLE. + (grub_usb_device): Increase toggle to 256. + (grub_usbms_subclass_t): New values GRUB_USBMS_SUBCLASS_RBC, + GRUB_USBMS_SUBCLASS_MMC2, GRUB_USBMS_SUBCLASS_UFI and + GRUB_USBMS_SUBCLASS_SFF8070. + * include/grub/scsicmd.h (grub_scsi_test_unit_ready): New structure. + (grub_scsi_inquiry): New member page and alloc_length. + (grub_scsi_request_sense): New structure. + (grub_scsi_request_sense_data): Likewise. + (grub_scsi_read_capacity): New fields logical_block_addr, PMI and + control. + * disk/scsi.c (grub_scsi_request_sense): New function. + (grub_scsi_test_unit_ready): Likewise. + (grub_scsi_inquiry): Fill new fields. + (grub_scsi_read_capacity): Likewise. + (grub_scsi_read10): Add request sense at the end. + (grub_scsi_read12): Likewise. + (grub_scsi_write10): Likewise. + (grub_scsi_write12): Likewise. + (grub_scsi_open): Add Test Unit Ready. + * disk/usbms.c (grub_usbms_finddevs): Check configcnt. + Support additional subclasses. Con't clear halt yet. Activate the + proper config. Calculate LUNs correctly. + (grub_usbms_transfer): Various important fixups. + +2010-06-02 Vladimir Serbinenko + + * bus/pci.c (grub_pci_iterate) [GRUB_MACHINE_MIPS_YEELOONG]: Skip ghosts. + * bus/usb/ohci.c (grub_ohci_portstatus): Handle R/WC correctly. + (grub_ohci_fini_hw): New function. + (grub_ohci_restore_hw): Likewise. + (GRUB_MOD_INIT(ohci)): Register preboot hook. + (GRUB_MOD_FINI(ohci)): Shutdown OHCI. + * term/usb_keyboard.c: Remove include of grub/machine/console.h. + +2010-06-02 Vladimir Serbinenko + + Dedicated DMA allocations. + + * bus/pci.c (grub_memalign_dma32): New function + (grub_dma_free): Likewise. + (grub_dma_get_virt): Likewise. + (grub_dma_get_phys): Likewise. + * bus/usb/ohci.c (grub_ohci): New members hcca_addr and hcca_chunk. + (grub_ohci_pci_iter): Use dma32_alloc. + (grub_ohci_transfer): Likewise. + * bus/usb/usbtrans.c (grub_usb_control_msg): Likewise. + (grub_usb_bulk_readwrite): Likewise. + * include/grub/pci.h: Add declarations. + +2010-06-02 Vladimir Serbinenko + + CS5536 support. + + * bus/cs5536.c: New file. + * bus/usb/ohci.c (grub_ohci_pci_iter): Check for CS5536. + * conf/i386.rmk (pkglib_MODULES): Add cs5536.mod. + (cs5536_mod_SOURCES): New variable. + (cs5536_mod_CFLAGS): Likewise. + (cs5536_mod_LDFLAGS): Likewise. + * conf/mips-yeeloong.rmk (kernel_img_HEADERS): Add cs5536.h and + machine/pci.h. + (kernel_img_SOURCES): Add bus/cs5536.c. + (pkglib_MODULES): Add usb.mod, usbtest.mod, ohci.mod, usbms.mod and + usb_keyboard.mod. + (usb_mod_SOURCES): New variable. + (usb_mod_CFLAGS): New variable. + (usb_mod_LDFLAGS): New variable. + (usbtest_mod_SOURCES): New variable. + (usbtest_mod_CFLAGS): New variable. + (usbtest_mod_LDFLAGS): New variable. + (ohci_mod_SOURCES): New variable. + (ohci_mod_CFLAGS): New variable. + (ohci_mod_LDFLAGS): New variable. + (usbms_mod_SOURCES): New variable. + (usbms_mod_CFLAGS): New variable. + (usbms_mod_LDFLAGS): New variable. + (usb_keyboard_mod_SOURCES): New variable. + (usb_keyboard_mod_CFLAGS): New variable. + (usb_keyboard_mod_LDFLAGS): New variable. + * include/grub/smbus.h: New file. + * include/grub/cs5536.h: New file. + 2010-05-28 Colin Watson * configure.ac: AC_PROG_LEX sets LEX to ":" if lex is missing, not From 0819fec8a1f8820bfdfac08e9c1e188136bedf29 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 2 Jun 2010 22:48:13 +0100 Subject: [PATCH 714/738] * docs/grub.texi (Simple configuration): Fix copy-and-paste typo. Thanks to Jordan Uggla for spotting this. --- ChangeLog | 5 +++++ docs/grub.texi | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 49583746c..8036c7fdb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-06-02 Colin Watson + + * docs/grub.texi (Simple configuration): Fix copy-and-paste typo. + Thanks to Jordan Uggla for spotting this. + 2010-06-02 Aleš Nesrsta Finally make USB usable. diff --git a/docs/grub.texi b/docs/grub.texi index 1f0c2083e..d73c03d9b 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -877,7 +877,7 @@ Valid terminal output names depend on the platform, but may include @samp{gfxterm} (graphics-mode output), @samp{ofconsole} (Open Firmware console), or @samp{vga_text} (VGA text output, mainly useful with Coreboot). -The default is to use the platform's native terminal input. +The default is to use the platform's native terminal output. @item GRUB_TERMINAL If this option is set, it overrides both @samp{GRUB_TERMINAL_INPUT} and From 9d9b5833508080ef4146e8fd4db3dcbd91fcf194 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Sutre?= Date: Thu, 3 Jun 2010 00:47:22 +0200 Subject: [PATCH 715/738] Handle all possible disk device names for NetBSD. --- ChangeLog | 6 ++++++ kern/emu/hostdisk.c | 41 +++++++++++++++++++++++++++-------------- 2 files changed, 33 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8036c7fdb..7279197ee 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-06-02 Grégoire Sutre + + * kern/emu/hostdisk.c (convert_system_partition_to_system_disk) + [__NetBSD__]: Handle all device names matching /dev/r[a-z]+[0-9][a-z]. + (find_partition_start) [__NetBSD__]: Correct error messages for NetBSD. + 2010-06-02 Colin Watson * docs/grub.texi (Simple configuration): Fix copy-and-paste typo. diff --git a/kern/emu/hostdisk.c b/kern/emu/hostdisk.c index ae2f7d9ad..fc62cca26 100644 --- a/kern/emu/hostdisk.c +++ b/kern/emu/hostdisk.c @@ -413,7 +413,11 @@ devmapper_fail: if (fd == -1) { grub_error (GRUB_ERR_BAD_DEVICE, +# if !defined(__NetBSD__) "cannot open `%s' while attempting to get disk geometry", dev); +# else /* defined(__NetBSD__) */ + "cannot open `%s' while attempting to get disk label", dev); +# endif /* !defined(__NetBSD__) */ return 0; } @@ -425,7 +429,11 @@ devmapper_fail: # endif /* !defined(__NetBSD__) */ { grub_error (GRUB_ERR_BAD_DEVICE, +# if !defined(__NetBSD__) "cannot get disk geometry of `%s'", dev); +# else /* defined(__NetBSD__) */ + "cannot get disk label of `%s'", dev); +# endif /* !defined(__NetBSD__) */ close (fd); return 0; } @@ -1256,22 +1264,28 @@ devmapper_out: return path; #elif defined(__NetBSD__) - /* NetBSD uses "/dev/r[wsc]d[0-9]+[a-z]". */ + /* NetBSD uses "/dev/r[a-z]+[0-9][a-z]". */ char *path = xstrdup (os_dev); - if (strncmp ("/dev/rwd", path, 8) == 0 || - strncmp ("/dev/rsd", path, 8) == 0 || - strncmp ("/dev/rcd", path, 8) == 0) + if (strncmp ("/dev/r", path, sizeof("/dev/r") - 1) == 0 && + (path[sizeof("/dev/r") - 1] >= 'a' && path[sizeof("/dev/r") - 1] <= 'z') && + strncmp ("fd", path + sizeof("/dev/r") - 1, sizeof("fd") - 1) != 0) /* not a floppy device name */ { - char *q; - q = path + strlen(path) - 1; /* last character */ - if (grub_isalpha(*q) && grub_isdigit(*(q-1))) - { - int rawpart = -1; + char *p; + for (p = path + sizeof("/dev/r"); *p >= 'a' && *p <= 'z'; p++); + if (grub_isdigit(*p)) + { + p++; + if ((*p >= 'a' && *p <= 'z') && (*(p+1) == '\0')) + { + /* path matches the required regular expression and + p points to its last character. */ + int rawpart = -1; # ifdef HAVE_GETRAWPARTITION - rawpart = getrawpartition(); + rawpart = getrawpartition(); # endif /* HAVE_GETRAWPARTITION */ - if (rawpart >= 0) - *q = 'a' + rawpart; + if (rawpart >= 0) + *p = 'a' + rawpart; + } } } return path; @@ -1429,8 +1443,7 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) return name; # else /* defined(__NetBSD__) */ /* Since os_dev and convert_system_partition_to_system_disk (os_dev) are - * different, we know that os_dev is of the form /dev/r[wsc]d[0-9]+[a-z] - * and in particular it cannot be a floppy device. */ + * different, we know that os_dev cannot be a floppy device. */ # endif /* !defined(__NetBSD__) */ start = find_partition_start (os_dev); From 795b593a475327352308dfba23aeb2217599c8df Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Thu, 3 Jun 2010 09:48:23 +0100 Subject: [PATCH 716/738] * INSTALL: Document several build requirements for optional features (libdevmapper, ncurses, libusb, SDL, FreeType, GNU Unifont). --- ChangeLog | 5 +++++ INSTALL | 15 +++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/ChangeLog b/ChangeLog index 7279197ee..d67e7efa4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-06-03 Colin Watson + + * INSTALL: Document several build requirements for optional features + (libdevmapper, ncurses, libusb, SDL, FreeType, GNU Unifont). + 2010-06-02 Grégoire Sutre * kern/emu/hostdisk.c (convert_system_partition_to_system_disk) diff --git a/INSTALL b/INSTALL index 7186d20db..44a442253 100644 --- a/INSTALL +++ b/INSTALL @@ -19,6 +19,21 @@ configuring the GRUB. * Flex 2.5.35 or later * Other standard GNU/Unix tools +On GNU/Linux, you also need: + +* libdevmapper (recommended) + +To build grub-emu, you need: + +* ncurses +* libusb (recommended) +* SDL (recommended) + +To build GRUB's graphical terminal (gfxterm), you need: + +* FreeType 2 or later +* GNU Unifont + If you use a development snapshot or want to hack on GRUB you may need the following. From 9cdfe32f0916b227ed0ae1211bc1089684063207 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 4 Jun 2010 13:38:10 +0100 Subject: [PATCH 717/738] * util/grub-mkimage.c: Make target-related error messages slightly more helpful; -O talks about "format". Explicitly point to the use of -O if no target is specified. Reported by: Didier Raboud (Debian bug #584415). --- ChangeLog | 7 +++++++ util/grub-mkimage.c | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index d67e7efa4..fd2f8ae72 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-06-04 Colin Watson + + * util/grub-mkimage.c: Make target-related error messages slightly + more helpful; -O talks about "format". Explicitly point to the use + of -O if no target is specified. + Reported by: Didier Raboud (Debian bug #584415). + 2010-06-03 Colin Watson * INSTALL: Document several build requirements for optional features diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index 6366a9803..4e39450df 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -1253,7 +1253,7 @@ main (int argc, char *argv[]) image_target = &image_targets[i]; if (!image_target) { - printf ("unknown target %s\n", optarg); + printf ("unknown target format %s\n", optarg); usage (1); } break; @@ -1322,7 +1322,7 @@ main (int argc, char *argv[]) if (!image_target) { - printf ("Target not specified.\n"); + printf ("Target format not specified (use the -O option).\n"); usage (1); } From f28a9212b4465c2b106b4abd057779ddc3c69b3b Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 4 Jun 2010 13:53:30 +0100 Subject: [PATCH 718/738] =?UTF-8?q?*=20util/grub-mkconfig=5Flib.in=20(prep?= =?UTF-8?q?are=5Fgrub=5Fto=5Faccess=5Fdevice):=20Prepend=20"part=5F"=20to?= =?UTF-8?q?=20partmap=20module=20names,=20in=20line=20with=20grub-install.?= =?UTF-8?q?=20Reported=20by:=20Jind=C5=99ich=20Makovi=C4=8Dka=20(Debian=20?= =?UTF-8?q?bug=20#584426).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ChangeLog | 6 ++++++ util/grub-mkconfig_lib.in | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index fd2f8ae72..65a3c69b8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-06-04 Colin Watson + + * util/grub-mkconfig_lib.in (prepare_grub_to_access_device): Prepend + "part_" to partmap module names, in line with grub-install. + Reported by: Jindřich Makovička (Debian bug #584426). + 2010-06-04 Colin Watson * util/grub-mkimage.c: Make target-related error messages slightly diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in index 7ec8cb5be..14ea1842f 100644 --- a/util/grub-mkconfig_lib.in +++ b/util/grub-mkconfig_lib.in @@ -107,7 +107,7 @@ prepare_grub_to_access_device () partmap="`${grub_probe} --device ${device} --target=partmap`" for module in ${partmap} ; do - echo "insmod ${module}" + echo "insmod part_${module}" done fs="`${grub_probe} --device ${device} --target=fs`" From 71c3809882f5382ef40e434c7ac1a76d020f3577 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Sat, 5 Jun 2010 20:44:44 +0100 Subject: [PATCH 719/738] * util/grub.d/00_header.in: Quote values assigned to `saved_entry', in case they contain spaces. --- ChangeLog | 5 +++++ util/grub.d/00_header.in | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 65a3c69b8..779973f1e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-06-05 Colin Watson + + * util/grub.d/00_header.in: Quote values assigned to `saved_entry', + in case they contain spaces. + 2010-06-04 Colin Watson * util/grub-mkconfig_lib.in (prepare_grub_to_access_device): Prepend diff --git a/util/grub.d/00_header.in b/util/grub.d/00_header.in index 0a5cfac18..199a1d7af 100644 --- a/util/grub.d/00_header.in +++ b/util/grub.d/00_header.in @@ -62,7 +62,7 @@ EOF fi cat < Date: Mon, 7 Jun 2010 14:15:57 +0100 Subject: [PATCH 720/738] * util/grub-mkpasswd-pbkdf2.c (main): Rename top-level `c' variable to `count', fixing variable shadowing that broke the -c option. --- ChangeLog | 7 ++++++- util/grub-mkpasswd-pbkdf2.c | 9 +++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 779973f1e..07c262dc2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,9 @@ -2010-06-05 Colin Watson +2010-06-07 Colin Watson + + * util/grub-mkpasswd-pbkdf2.c (main): Rename top-level `c' variable + to `count', fixing variable shadowing that broke the -c option. + +2010-06-05 Colin Watson * util/grub.d/00_header.in: Quote values assigned to `saved_entry', in case they contain spaces. diff --git a/util/grub-mkpasswd-pbkdf2.c b/util/grub-mkpasswd-pbkdf2.c index a00b1e990..944c6c46a 100644 --- a/util/grub-mkpasswd-pbkdf2.c +++ b/util/grub-mkpasswd-pbkdf2.c @@ -112,7 +112,7 @@ hexify (char *hex, grub_uint8_t *bin, grub_size_t n) int main (int argc, char *argv[]) { - unsigned int c = 10000, buflen = 64, saltlen = 64; + unsigned int count = 10000, buflen = 64, saltlen = 64; char *pass1, *pass2; char *bufhex, *salthex; gcry_err_code_t gcry_err; @@ -137,7 +137,7 @@ main (int argc, char *argv[]) switch (c) { case 'c': - c = strtoul (optarg, NULL, 0); + count = strtoul (optarg, NULL, 0); break; case 'l': @@ -307,7 +307,7 @@ main (int argc, char *argv[]) gcry_err = grub_crypto_pbkdf2 (GRUB_MD_SHA512, (grub_uint8_t *) pass1, strlen (pass1), salt, saltlen, - c, buf, buflen); + count, buf, buflen); memset (pass1, 0, strlen (pass1)); free (pass1); @@ -327,7 +327,8 @@ main (int argc, char *argv[]) hexify (bufhex, buf, buflen); hexify (salthex, salt, saltlen); - printf ("Your PBKDF2 is grub.pbkdf2.sha512.%d.%s.%s\n", c, salthex, bufhex); + printf ("Your PBKDF2 is grub.pbkdf2.sha512.%d.%s.%s\n", + count, salthex, bufhex); memset (buf, 0, buflen); memset (bufhex, 0, 2 * buflen); free (buf); From e1cbcc40a45e7fe0f5d0dbf42a2815eb7b832efe Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 7 Jun 2010 14:22:40 +0100 Subject: [PATCH 721/738] * util/grub.d/00_header.in: Add some more quoting (of "${prev_saved_entry}" and "${boot_once}") needed to make savedefault work again. Reported by: Mario 'BitKoenig' Holbe (Debian bug #584812). --- ChangeLog | 7 +++++++ util/grub.d/00_header.in | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 07c262dc2..5568cbd3a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-06-07 Colin Watson + + * util/grub.d/00_header.in: Add some more quoting (of + "${prev_saved_entry}" and "${boot_once}") needed to make savedefault + work again. + Reported by: Mario 'BitKoenig' Holbe (Debian bug #584812). + 2010-06-07 Colin Watson * util/grub-mkpasswd-pbkdf2.c (main): Rename top-level `c' variable diff --git a/util/grub.d/00_header.in b/util/grub.d/00_header.in index 199a1d7af..791840a60 100644 --- a/util/grub.d/00_header.in +++ b/util/grub.d/00_header.in @@ -61,7 +61,7 @@ set default="${GRUB_DEFAULT}" EOF fi cat < Date: Mon, 7 Jun 2010 14:32:12 +0100 Subject: [PATCH 722/738] * docs/grub.texi (Filesystem): Refer to `search' instead of `find'. (password): New section. (password_pbkdf2): New section. (search): New section. (Security): New section. (Troubleshooting): New section, currently very incomplete. (Invoking grub-mkpasswd-pbkdf2): New section. (Internals): New section, currently very incomplete. --- ChangeLog | 11 ++ docs/grub.texi | 317 ++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 326 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5568cbd3a..3a3df4c5d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2010-06-07 Colin Watson + + * docs/grub.texi (Filesystem): Refer to `search' instead of `find'. + (password): New section. + (password_pbkdf2): New section. + (search): New section. + (Security): New section. + (Troubleshooting): New section, currently very incomplete. + (Invoking grub-mkpasswd-pbkdf2): New section. + (Internals): New section, currently very incomplete. + 2010-06-07 Colin Watson * util/grub.d/00_header.in: Add some more quoting (of diff --git a/docs/grub.texi b/docs/grub.texi index d73c03d9b..837607d62 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -35,6 +35,7 @@ Invariant Sections. * GRUB: (grub). The GRand Unified Bootloader * grub-install: (grub)Invoking grub-install. Install GRUB on your drive * grub-mkconfig: (grub)Invoking grub-mkconfig. Generate GRUB configuration +* grub-mkpasswd-pbkdf2: (grub)Invoking grub-mkpasswd-pbkdf2. @end direntry @setchapternewpage odd @@ -84,9 +85,12 @@ This edition documents version @value{VERSION}. * Filesystem:: Filesystem syntax and semantics * Interface:: The menu and the command-line * Commands:: The list of available builtin commands +* Security:: Authentication and authorisation * Troubleshooting:: Error messages produced by GRUB * Invoking grub-install:: How to use the GRUB installer * Invoking grub-mkconfig:: Generate a GRUB configuration file +* Invoking grub-mkpasswd-pbkdf2:: + Generate GRUB password hashes * Obtaining and Building GRUB:: How to obtain and build GRUB * Reporting bugs:: Where you should send a bug report * Future:: Some future plans on GRUB @@ -1041,8 +1045,8 @@ GRUB uses a special syntax for specifying disk drives which can be accessed by BIOS. Because of BIOS limitations, GRUB cannot distinguish between IDE, ESDI, SCSI, or others. You must know yourself which BIOS device is equivalent to which OS device. Normally, that will be clear if -you see the files in a device or use the command @command{find} -(@pxref{find}). +you see the files in a device or use the command @command{search} +(@pxref{search}). @menu * Device syntax:: How to specify devices @@ -1415,8 +1419,11 @@ you forget a command, you can run the command @command{help} * keystatus:: Check key modifier status * ls:: List devices or files * parttool:: Modify partition table entries +* password:: Set a clear-text password +* password_pbkdf2:: Set a hashed password * play:: Play a tune * reboot:: Reboot your computer +* search:: Search devices by file, label, or UUID * set:: Set an environment variable * unset:: Unset an environment variable @end menu @@ -1747,6 +1754,25 @@ Wwindows and multiple primary FAT partitions exist in one disk. See also @end deffn +@node password +@subsection password + +@deffn Command password user clear-password +Define a user named @var{user} with password @var{clear-password}. +@xref{Security}. +@end deffn + + +@node password_pbkdf2 +@subsection password_pbkdf2 + +@deffn Command password_pbkdf2 user hashed-password +Define a user named @var{user} with password hash @var{hashed-password}. +Use @command{grub-mkpasswd-pbkdf2} (@pxref{Invoking grub-mkpasswd-pbkdf2}) +to generate password hashes. @xref{Security}. +@end deffn + + @node play @subsection play @@ -1774,6 +1800,29 @@ Reboot the computer. @end deffn +@node search +@subsection search + +@deffn Command search @ + [@option{--file}|@option{--label}|@option{--fs-uuid}] @ + [@option{--set} var] [@option{--no-floppy}] name +Search devices by file (@option{-f}, @option{--file}), filesystem label +(@option{-l}, @option{--label}), or filesystem UUID (@option{-u}, +@option{--fs-uuid}). + +If the @option{--set} option is used, the first device found is set as the +value of environment variable @var{var}. The default variable is +@samp{root}. + +The @option{--no-floppy} option prevents searching floppy devices, which can +be slow. + +The @samp{search.file}, @samp{search.fs_label}, and @samp{search.fs_uuid} +commands are aliases for @samp{search --file}, @samp{search --label}, and +@samp{search --fs-uuid} respectively. +@end deffn + + @node set @subsection set @@ -1791,6 +1840,135 @@ Unset the environment variable @var{envvar}. @end deffn +@node Security +@chapter Authentication and authorisation + +By default, the boot loader interface is accessible to anyone with physical +access to the console: anyone can select and edit any menu entry, and anyone +can get direct access to a GRUB shell prompt. For most systems, this is +reasonable since anyone with direct physical access has a variety of other +ways to gain full access, and requiring authentication at the boot loader +level would only serve to make it difficult to recover broken systems. + +However, in some environments, such as kiosks, it may be appropriate to lock +down the boot loader to require authentication before performing certain +operations. + +The @samp{password} (@pxref{password}) and @samp{password_pbkdf2} +(@pxref{password_pbkdf2}) commands can be used to define users, each of +which has an associated password. @samp{password} sets the password in +plain text, requiring @file{grub.cfg} to be secure; @samp{password_pbkdf2} +sets the password hashed using the Password-Based Key Derivation Function +(RFC 2898), requiring the use of @command{grub-mkpasswd-pbkdf2} +(@pxref{Invoking grub-mkpasswd-pbkdf2}) to generate password hashes. + +In order to enable authentication support, the @samp{superusers} environment +variable must be set to a list of usernames, separated by any of spaces, +commas, semicolons, pipes, or ampersands. Superusers are permitted to use +the GRUB command line, edit menu entries, and execute any menu entry. + +Other users may be given access to specific menu entries by giving a list of +usernames (as above) using the @kbd{--users} option to the @samp{menuentry} +command (@pxref{menuentry}). + +Putting this together, a typical @file{grub.cfg} fragment might look like +this: + +@example +@group +set superusers="root" +password_pbkdf2 root grub.pbkdf2.sha512.10000.biglongstring +password user1 insecure + +menuentry "Superusers only" @{ + set root=(hd0,1) + linux /vmlinuz +@} + +menuentry "May be run by user1" --users user1 @{ + set root=(hd0,2) + chainloader +1 +@} +@end group +@end example + +The @command{grub-mkconfig} program does not yet have built-in support for +generating configuration files with authentication. You can use +@file{/etc/grub.d/40_custom} to add simple superuser authentication, by +adding @kbd{set superusers=} and @kbd{password} or @kbd{password_pbkdf2} +commands. + + +@node Troubleshooting +@chapter Error messages produced by GRUB + +@menu +* GRUB only offers a rescue shell:: +@end menu + + +@node GRUB only offers a rescue shell +@section GRUB only offers a rescue shell + +GRUB's normal start-up procedure involves setting the @samp{prefix} +environment variable to a value set in the core image by +@command{grub-install}, setting the @samp{root} variable to match, loading +the @samp{normal} module from the prefix, and running the @samp{normal} +command. This command is responsible for reading +@file{/boot/grub/grub.cfg}, running the menu, and doing all the useful +things GRUB is supposed to do. + +If, instead, you only get a rescue shell, this usually means that GRUB +failed to load the @samp{normal} module for some reason. It may be possible +to work around this temporarily: for instance, if the reason for the failure +is that @samp{prefix} is wrong (perhaps it refers to the wrong device, or +perhaps the path to @file{/boot/grub} was not correctly made relative to the +device), then you can correct this and enter normal mode manually: + +@example +@group +# Inspect the current prefix: +echo @verb{'${prefix}'} +# Set to the correct value, which might be something like this: +set prefix=(hd0,1)/grub +set root=(hd0,1) +insmod normal +normal +@end group +@end example + +However, any problem that leaves you in the rescue shell probably means that +GRUB was not correctly installed. It may be more useful to try to reinstall +it properly using @kbd{grub-install @var{device}} (@pxref{Invoking +grub-install}). When doing this, there are a few things to remember: + +@itemize @bullet{} +@item +Drive ordering in your operating system may not be the same as the boot +drive ordering used by your firmware. Do not assume that your first hard +drive (e.g. @samp{/dev/sda}) is the one that your firmware will boot from. + +@item +At least on BIOS systems, if you tell @command{grub-install} to install GRUB +to a partition but GRUB has already been installed in the master boot +record, then the GRUB installation in the partition will be ignored. + +@item +If possible, it is generally best to avoid installing GRUB to a partition +(unless it is a special partition for the use of GRUB alone, such as the +BIOS Boot Partition used on GPT). Doing this means that GRUB may stop being +able to read its core image due to a file system moving blocks around, such +as while defragmenting, running checks, or even during normal operation. +Installing to the whole disk device is normally more robust. + +@item +Check that GRUB actually knows how to read from the device and file system +containing @file{/boot/grub}. It will not be able to read from encrypted +devices, nor from file systems for which support has not yet been added to +GRUB. +@end itemize + + @node Invoking grub-install @chapter Invoking grub-install @@ -1858,6 +2036,34 @@ it to standard output. @end table +@node Invoking grub-mkpasswd-pbkdf2 +@chapter Invoking grub-mkpasswd-pbkdf2 + +The program @command{grub-mkpasswd-pbkdf2} generates password hashes for +GRUB (@pxref{Security}). + +@example +grub-mkpasswd-pbkdf2 +@end example + +@command{grub-mkpasswd-pbkdf2} accepts the following options: + +@table @option +@item -c @var{number} +@itemx --iteration-count=@var{number} +Number of iterations of the underlying pseudo-random function. Defaults to +10000. + +@item -l @var{number} +@itemx --buflen=@var{number} +Length of the generated hash. Defaults to 64. + +@item -s @var{number} +@itemx --salt=@var{number} +Length of the salt. Defaults to 64. +@end table + + @node Obtaining and Building GRUB @appendix How to obtain and build GRUB @@ -1976,6 +2182,113 @@ a look at @uref{http://www.gnu.org/software/grub/grub.html, the homepage}. +@node Internals +@appendix Hacking GRUB + +@menu +* Getting the source code:: +* Finding your way around:: +@end menu + + +@node Getting the source code +@section Getting the source code + +GRUB is maintained using the @uref{http://bazaar-vcs.org/, Bazaar revision +control system}. To fetch the primary development branch: + +@example +bzr get http://bzr.savannah.gnu.org/r/grub/trunk/grub +@end example + +The GRUB developers maintain several other branches with work in progress. +Of these, the most interesting is the experimental branch, which is a +staging area for new code which we expect to eventually merge into trunk but +which is not yet ready: + +@example +bzr get http://bzr.savannah.gnu.org/r/grub/branches/experimental +@end example + +Once you have used @kbd{bzr get} to fetch an initial copy of a branch, you +can use @kbd{bzr pull} to keep it up to date. If you have modified your +local version, you may need to resolve conflicts when pulling. + + +@node Finding your way around +@section Finding your way around + +Here is a brief map of the GRUB code base. + +GRUB uses Autoconf, but not (yet) Automake. The top-level build rules are +in @file{configure.ac}, @file{Makefile.in}, and @file{conf/*.rmk}. Each +@file{conf/*.rmk} file represents a particular target configuration, and is +processed into GNU Make rules by @file{genmk.rb} (which you only need to +look at if you are extending the build system). If you are adding a new +module which follows an existing pattern, such as a new command or a new +filesystem implementation, it is usually easiest to grep @file{conf/*.rmk} +for an existing example of that pattern to find out where it should be +added. + +Low-level boot code, such as the MBR implementation on PC BIOS systems, is +in the @file{boot/} directory. + +The GRUB kernel is in @file{kern/}. This contains core facilities such as +the device, disk, and file frameworks, environment variable handling, list +processing, and so on. The kernel should contain enough to get up to a +rescue prompt. Header files for kernel facilities, among others, are in +@file{include/}. + +Terminal implementations are in @file{term/}. + +Disk access code is spread across @file{disk/} (for accessing the disk +devices themselves), @file{partmap/} (for interpreting partition table +data), and @file{fs/} (for accessing filesystems). Note that, with the odd +specialised exception, GRUB only contains code to @emph{read} from +filesystems and tries to avoid containing any code to @emph{write} to +filesystems; this lets us confidently assure users that GRUB cannot be +responsible for filesystem corruption. + +PCI and USB bus handling is in @file{bus/}. + +Video handling code is in @file{video/}. The graphical menu system uses +this heavily, but is in a separate directory, @file{gfxmenu/}. + +Most commands are implemented by files in @file{commands/}, with the +following exceptions: + +@itemize +@item +A few core commands live in @file{kern/corecmd.c}. + +@item +Commands related to normal mode live under @file{normal/}. + +@item +Commands that load and boot kernels live under @file{loader/}. + +@item +The @samp{loopback} command is really a disk device, and so lives in +@file{disk/loopback.c}. + +@item +The @samp{gettext} command lives under @file{gettext/}. + +@item +The @samp{loadfont} and @samp{lsfonts} commands live under @file{font/}. + +@item +The @samp{serial}, @samp{terminfo}, and @samp{background_image} commands +live under @file{term/}. + +@item +The @samp{efiemu_*} commands live under @file{efiemu/}. +@end itemize + +There are a few other special-purpose exceptions; grep for them if they +matter to you. + + @node Copying This Manual @appendix Copying This Manual From a6a700aa52768f6392337ddbb8798f99a895a018 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 7 Jun 2010 21:10:29 +0100 Subject: [PATCH 723/738] * docs/grub.texi (Troubleshooting): `echo' is not usually available in the rescue shell, so recommend using `set' instead. Thanks, Jordan Uggla. --- ChangeLog | 6 ++++++ docs/grub.texi | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3a3df4c5d..ddb55f17a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-06-07 Colin Watson + + * docs/grub.texi (Troubleshooting): `echo' is not usually available + in the rescue shell, so recommend using `set' instead. Thanks, + Jordan Uggla. + 2010-06-07 Colin Watson * docs/grub.texi (Filesystem): Refer to `search' instead of `find'. diff --git a/docs/grub.texi b/docs/grub.texi index 837607d62..f2d0c41bf 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -1927,8 +1927,8 @@ device), then you can correct this and enter normal mode manually: @example @group -# Inspect the current prefix: -echo @verb{'${prefix}'} +# Inspect the current prefix (and other preset variables): +set # Set to the correct value, which might be something like this: set prefix=(hd0,1)/grub set root=(hd0,1) From ee75515e69598e0c4e6f53c24b3b8247e4a83170 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 7 Jun 2010 21:26:30 +0100 Subject: [PATCH 724/738] * docs/grub.texi (Network): New section. (Device syntax): The network device is called `(pxe)' in GRUB 2, not `(nd)' as in GRUB Legacy. (pxe_unload): New section. --- ChangeLog | 7 +++++ docs/grub.texi | 85 +++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 91 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index ddb55f17a..f9a0d2424 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-06-07 Colin Watson + + * docs/grub.texi (Network): New section. + (Device syntax): The network device is called `(pxe)' in GRUB 2, not + `(nd)' as in GRUB Legacy. + (pxe_unload): New section. + 2010-06-07 Colin Watson * docs/grub.texi (Troubleshooting): `echo' is not usually available diff --git a/docs/grub.texi b/docs/grub.texi index f2d0c41bf..37016b175 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -970,6 +970,78 @@ that file, making sure to leave at least the first two lines intact. @section Writing full configuration files directly +@node Network +@chapter Booting GRUB from the network + +The following instructions only work on PC BIOS systems where the Preboot +eXecution Environment (PXE) is available. + +To generate a PXE boot image, run: + +@example +@group +grub-mkimage --format=i386-pc --output=core.img --prefix='(pxe)/boot/grub' pxe pxecmd +cat /boot/grub/pxeboot.img core.img >grub.pxe +@end group +@end example + +Copy @file{grub.pxe}, @file{/boot/grub/*.mod}, and @file{/boot/grub/*.lst} +to the PXE (TFTP) server, ensuring that @file{*.mod} and @file{*.lst} are +accessible via the @file{/boot/grub/} path from the TFTP server root. Set +the DHCP server configuration to offer @file{grub.pxe} as the boot file (the +@samp{filename} option in ISC dhcpd). + +After GRUB has started, files on the TFTP server will be accessible via the +@samp{(pxe)} device. + +The server and gateway IP address can be controlled by changing the +@samp{(pxe)} device name to @samp{(pxe:@var{server-ip})} or +@samp{(pxe:@var{server-ip}:@var{gateway-ip})}. Note that this should be +changed both in the prefix and in any references to the device name in the +configuration file. + +GRUB provides several environment variables which may be used to inspect or +change the behaviour of the PXE device: + +@table @samp +@item net_pxe_ip +The IP address of this machine. Read-only. + +@item net_pxe_mac +The network interface's MAC address. Read-only. + +@item net_pxe_hostname +The client host name provided by DHCP. Read-only. + +@item net_pxe_domain +The client domain name provided by DHCP. Read-only. + +@item net_pxe_rootpath +The path to the client's root disk provided by DHCP. Read-only. + +@item net_pxe_extensionspath +The path to additional DHCP vendor extensions provided by DHCP. Read-only. + +@item net_pxe_boot_file +The boot file name provided by DHCP. Read-only. + +@item net_pxe_dhcp_server_name +The name of the DHCP server responsible for these boot parameters. +Read-only. + +@item net_pxe_blksize +The PXE transfer block size. Read-write, defaults to 512. + +@item pxe_default_server +The default PXE server. Read-write, although setting this is only useful +before opening a PXE device. + +@item pxe_default_gateway +The default gateway to use when contacting the PXE server. Read-write, +although setting this is only useful before opening a PXE device. +@end table + + @node Serial terminal @chapter Using GRUB via a serial line @@ -1094,7 +1166,7 @@ MBR when installing GRUB), while the syntax @samp{(hd0,1)} represents using the first partition of the disk (or the boot sector of the partition when installing GRUB). -If you enabled the network support, the special drive, @samp{(nd)}, is +If you enabled the network support, the special drive @samp{(pxe)} is also available. Before using the network drive, you must initialize the network. @xref{Network}, for more information. @@ -1422,6 +1494,7 @@ you forget a command, you can run the command @command{help} * password:: Set a clear-text password * password_pbkdf2:: Set a hashed password * play:: Play a tune +* pxe_unload:: Unload the PXE environment * reboot:: Reboot your computer * search:: Search devices by file, label, or UUID * set:: Set an environment variable @@ -1792,6 +1865,16 @@ a rest. @end deffn +@node pxe_unload +@subsection pxe_unload + +@deffn Command pxe_unload +Unload the PXE environment (@pxref{Network}). + +This command is only available on PC BIOS systems. +@end deffn + + @node reboot @subsection reboot From 258c2573a659c3b04b2873bcc3da9351a08e8f9a Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 7 Jun 2010 21:29:25 +0100 Subject: [PATCH 725/738] * fs/i386/pc/pxe.c (grub_pxe_open): Fix parsing of gateway_ip. --- ChangeLog | 4 ++++ fs/i386/pc/pxe.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index f9a0d2424..b8f5f80d8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-06-07 Colin Watson + + * fs/i386/pc/pxe.c (grub_pxe_open): Fix parsing of gateway_ip. + 2010-06-07 Colin Watson * docs/grub.texi (Network): New section. diff --git a/fs/i386/pc/pxe.c b/fs/i386/pc/pxe.c index 82d8ee583..e4d481a8e 100644 --- a/fs/i386/pc/pxe.c +++ b/fs/i386/pc/pxe.c @@ -114,7 +114,7 @@ grub_pxe_open (const char *name, grub_disk_t disk) return err; if (*ptr == ':') { - err = parse_ip (ptr + 1, &(data->server_ip), 0); + err = parse_ip (ptr + 1, &(data->gateway_ip), 0); if (err) return err; } From fb55c3acf9adec8a576e35551a8d2f5d6684cb88 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 7 Jun 2010 22:13:26 +0100 Subject: [PATCH 726/738] * normal/completion.c (grub_normal_do_completion): When completing arguments to "set" and the current word contains an equals sign, skip to after the equals sign before starting completion. --- ChangeLog | 6 ++++++ normal/completion.c | 8 ++++++++ 2 files changed, 14 insertions(+) diff --git a/ChangeLog b/ChangeLog index b8f5f80d8..bc1b2686a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-06-07 Colin Watson + + * normal/completion.c (grub_normal_do_completion): When completing + arguments to "set" and the current word contains an equals sign, + skip to after the equals sign before starting completion. + 2010-06-07 Colin Watson * fs/i386/pc/pxe.c (grub_pxe_open): Fix parsing of gateway_ip. diff --git a/normal/completion.c b/normal/completion.c index 13e8f7a6b..334eaea11 100644 --- a/normal/completion.c +++ b/normal/completion.c @@ -414,6 +414,14 @@ grub_normal_do_completion (char *buf, int *restore, else current_word = argv[argc - 1]; + if (argc > 1 && ! grub_strcmp (argv[0], "set")) + { + char *equals = grub_strchr (current_word, '='); + if (equals) + /* Complete the value of the variable. */ + current_word = equals + 1; + } + /* Determine the state the command line is in, depending on the state, it can be determined how to complete. */ cmdline_state = get_state (buf); From da90820083ca2a6ca22877068a9d7262cd5629ac Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 7 Jun 2010 22:18:00 +0100 Subject: [PATCH 727/738] * docs/grub.texi (Naming convention): Use GRUB 2 syntax. (File name syntax): Likewise. (help): --all is no longer supported in GRUB 2. Be more precise about pattern matching. --- ChangeLog | 7 +++++++ docs/grub.texi | 22 ++++++++++------------ 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index bc1b2686a..3a463ab42 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-06-07 Colin Watson + + * docs/grub.texi (Naming convention): Use GRUB 2 syntax. + (File name syntax): Likewise. + (help): --all is no longer supported in GRUB 2. Be more precise + about pattern matching. + 2010-06-07 Colin Watson * normal/completion.c (grub_normal_do_completion): When completing diff --git a/docs/grub.texi b/docs/grub.texi index 37016b175..ffc6b8fe2 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -390,14 +390,14 @@ GRUB searches for the first @sc{pc} slice which has a BSD @samp{a} partition. Of course, to actually access the disks or partitions with GRUB, you -need to use the device specification in a command, like @samp{root -(fd0)} or @samp{unhide (hd0,3)}. To help you find out which number -specifies a partition you want, the GRUB command-line +need to use the device specification in a command, like @samp{set +root=(fd0)} or @samp{parttool (hd0,3) hidden-}. To help you find out +which number specifies a partition you want, the GRUB command-line (@pxref{Command-line interface}) options have argument completion. This means that, for example, you only need to type @example -root ( +set root=( @end example followed by a @key{TAB}, and GRUB will display the list of drives, @@ -1186,8 +1186,8 @@ example is @samp{(hd0,1)/boot/grub/grub.cfg}. This means the file @file{/boot/grub/grub.cfg} in the first partition of the first hard disk. If you omit the device name in an absolute file name, GRUB uses GRUB's @dfn{root device} implicitly. So if you set the root device to, -say, @samp{(hd1,1)} by the command @command{root} (@pxref{root}), then -@code{/boot/kernel} is the same as @code{(hd1,1)/boot/kernel}. +say, @samp{(hd1,1)} by the command @samp{set root=(hd1,1)} (@pxref{set}), +then @code{/boot/kernel} is the same as @code{(hd1,1)/boot/kernel}. @node Block list syntax @@ -1742,15 +1742,13 @@ is shut down using APM. @node help @subsection help -@deffn Command help @option{--all} [pattern @dots{}] +@deffn Command help [pattern @dots{}] Display helpful information about builtin commands. If you do not -specify @var{pattern}, this command shows short descriptions of most of -available commands. If you specify the option @option{--all} to this -command, short descriptions of rarely used commands (such as -@ref{testload}) are displayed as well. +specify @var{pattern}, this command shows short descriptions of all +available commands. If you specify any @var{patterns}, it displays longer information -about each of the commands which match those @var{patterns}. +about each of the commands whose names begin with those @var{patterns}. @end deffn From e0f4c438823f1fa82cac8098469cc138bb1fe37d Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 7 Jun 2010 22:41:55 +0100 Subject: [PATCH 728/738] * kern/emu/misc.c (device_mapper_null_log): New function. (grub_device_mapper_supported): New function. * include/grub/emu/misc.h (grub_device_mapper_supported): Add prototype. * kern/emu/hostdisk.c (find_partition_start): Check whether device-mapper is supported before trying to use it. * util/deviceiter.c (grub_util_iterate_devices): Likewise. --- ChangeLog | 10 +++ include/grub/emu/misc.h | 4 + kern/emu/hostdisk.c | 2 +- kern/emu/misc.c | 39 ++++++++ util/deviceiter.c | 194 ++++++++++++++++++++-------------------- 5 files changed, 152 insertions(+), 97 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3a463ab42..c28f77bc8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2010-06-07 Colin Watson + + * kern/emu/misc.c (device_mapper_null_log): New function. + (grub_device_mapper_supported): New function. + * include/grub/emu/misc.h (grub_device_mapper_supported): Add + prototype. + * kern/emu/hostdisk.c (find_partition_start): Check whether + device-mapper is supported before trying to use it. + * util/deviceiter.c (grub_util_iterate_devices): Likewise. + 2010-06-07 Colin Watson * docs/grub.texi (Naming convention): Use GRUB 2 syntax. diff --git a/include/grub/emu/misc.h b/include/grub/emu/misc.h index 0e6ace0e8..f34cd4287 100644 --- a/include/grub/emu/misc.h +++ b/include/grub/emu/misc.h @@ -48,4 +48,8 @@ int EXPORT_FUNC(asprintf) (char **buf, const char *fmt, ...); char * EXPORT_FUNC(xasprintf) (const char *fmt, ...); extern char * canonicalize_file_name (const char *path); +#ifdef HAVE_DEVICE_MAPPER +int grub_device_mapper_supported (void); +#endif + #endif /* GRUB_EMU_MISC_H */ diff --git a/kern/emu/hostdisk.c b/kern/emu/hostdisk.c index fc62cca26..47389195c 100644 --- a/kern/emu/hostdisk.c +++ b/kern/emu/hostdisk.c @@ -342,7 +342,7 @@ find_partition_start (const char *dev) # endif /* !defined(__NetBSD__) */ # ifdef HAVE_DEVICE_MAPPER - if (device_is_mapped (dev)) { + if (grub_device_mapper_supported () && device_is_mapped (dev)) { struct dm_task *task = NULL; grub_uint64_t start, length; char *target_type, *params, *space; diff --git a/kern/emu/misc.c b/kern/emu/misc.c index 9437169e0..38395fca8 100644 --- a/kern/emu/misc.c +++ b/kern/emu/misc.c @@ -22,6 +22,10 @@ #include #include +#ifdef HAVE_DEVICE_MAPPER +# include +#endif + int verbosity; void @@ -311,3 +315,38 @@ grub_make_system_path_relative_to_its_root (const char *path) return buf3; } + +#ifdef HAVE_DEVICE_MAPPER +static void device_mapper_null_log (int level __attribute__ ((unused)), + const char *file __attribute__ ((unused)), + int line __attribute__ ((unused)), + int dm_errno __attribute__ ((unused)), + const char *f __attribute__ ((unused)), + ...) +{ +} + +int +grub_device_mapper_supported (void) +{ + static int supported = -1; + + if (supported == -1) + { + struct dm_task *dmt; + + /* Suppress annoying log messages. */ + dm_log_with_errno_init (&device_mapper_null_log); + + dmt = dm_task_create (DM_DEVICE_VERSION); + supported = (dmt != NULL); + if (dmt) + dm_task_destroy (dmt); + + /* Restore the original logger. */ + dm_log_with_errno_init (NULL); + } + + return supported; +} +#endif /* HAVE_DEVICE_MAPPER */ diff --git a/util/deviceiter.c b/util/deviceiter.c index 03813bc7d..d7e8f159e 100644 --- a/util/deviceiter.c +++ b/util/deviceiter.c @@ -33,6 +33,7 @@ #include #include #include +#include #ifdef __linux__ # if !defined(__GLIBC__) || \ @@ -676,112 +677,113 @@ grub_util_iterate_devices (int NESTED_FUNC_ATTR (*hook) (const char *, int), } /* DM-RAID. */ - { - struct dm_tree *tree = NULL; - struct dm_task *task = NULL; - struct dm_names *names = NULL; - unsigned int next = 0; - void *top_handle, *second_handle; - struct dm_tree_node *root, *top, *second; - struct dmraid_seen *seen = NULL; + if (grub_device_mapper_supported ()) + { + struct dm_tree *tree = NULL; + struct dm_task *task = NULL; + struct dm_names *names = NULL; + unsigned int next = 0; + void *top_handle, *second_handle; + struct dm_tree_node *root, *top, *second; + struct dmraid_seen *seen = NULL; - /* Build DM tree for all devices. */ - tree = dm_tree_create (); - dmraid_check (tree, "dm_tree_create failed\n"); - task = dm_task_create (DM_DEVICE_LIST); - dmraid_check (task, "dm_task_create failed\n"); - dmraid_check (dm_task_run (task), "dm_task_run failed\n"); - names = dm_task_get_names (task); - dmraid_check (names, "dm_task_get_names failed\n"); - dmraid_check (names->dev, "No DM devices found\n"); - do - { - names = (void *) names + next; - dmraid_check (dm_tree_add_dev (tree, MAJOR (names->dev), - MINOR (names->dev)), - "dm_tree_add_dev (%s) failed\n", names->name); - next = names->next; - } - while (next); + /* Build DM tree for all devices. */ + tree = dm_tree_create (); + dmraid_check (tree, "dm_tree_create failed\n"); + task = dm_task_create (DM_DEVICE_LIST); + dmraid_check (task, "dm_task_create failed\n"); + dmraid_check (dm_task_run (task), "dm_task_run failed\n"); + names = dm_task_get_names (task); + dmraid_check (names, "dm_task_get_names failed\n"); + dmraid_check (names->dev, "No DM devices found\n"); + do + { + names = (void *) names + next; + dmraid_check (dm_tree_add_dev (tree, MAJOR (names->dev), + MINOR (names->dev)), + "dm_tree_add_dev (%s) failed\n", names->name); + next = names->next; + } + while (next); - /* Walk the second-level children of the inverted tree; that is, devices - which are directly composed of non-DM devices such as hard disks. - This class includes all DM-RAID disks and excludes all DM-RAID - partitions. */ - root = dm_tree_find_node (tree, 0, 0); - top_handle = NULL; - top = dm_tree_next_child (&top_handle, root, 1); - while (top) - { - second_handle = NULL; - second = dm_tree_next_child (&second_handle, top, 1); - while (second) - { - const char *node_name, *node_uuid; - char *name; - struct dmraid_seen *seen_elt; + /* Walk the second-level children of the inverted tree; that is, devices + which are directly composed of non-DM devices such as hard disks. + This class includes all DM-RAID disks and excludes all DM-RAID + partitions. */ + root = dm_tree_find_node (tree, 0, 0); + top_handle = NULL; + top = dm_tree_next_child (&top_handle, root, 1); + while (top) + { + second_handle = NULL; + second = dm_tree_next_child (&second_handle, top, 1); + while (second) + { + const char *node_name, *node_uuid; + char *name; + struct dmraid_seen *seen_elt; - node_name = dm_tree_node_get_name (second); - dmraid_check (node_name, "dm_tree_node_get_name failed\n"); - node_uuid = dm_tree_node_get_uuid (second); - dmraid_check (node_uuid, "dm_tree_node_get_uuid failed\n"); - if (strncmp (node_uuid, "DMRAID-", 7) != 0) - { - grub_dprintf ("deviceiter", "%s is not DM-RAID\n", node_name); - goto dmraid_next_child; - } + node_name = dm_tree_node_get_name (second); + dmraid_check (node_name, "dm_tree_node_get_name failed\n"); + node_uuid = dm_tree_node_get_uuid (second); + dmraid_check (node_uuid, "dm_tree_node_get_uuid failed\n"); + if (strncmp (node_uuid, "DMRAID-", 7) != 0) + { + grub_dprintf ("deviceiter", "%s is not DM-RAID\n", node_name); + goto dmraid_next_child; + } - /* Have we already seen this node? There are typically very few - DM-RAID disks, so a list should be fast enough. */ - if (grub_named_list_find (GRUB_AS_NAMED_LIST (seen), node_name)) - { - grub_dprintf ("deviceiter", "Already seen DM device %s\n", - node_name); - goto dmraid_next_child; - } + /* Have we already seen this node? There are typically very few + DM-RAID disks, so a list should be fast enough. */ + if (grub_named_list_find (GRUB_AS_NAMED_LIST (seen), node_name)) + { + grub_dprintf ("deviceiter", "Already seen DM device %s\n", + node_name); + goto dmraid_next_child; + } - name = xasprintf ("/dev/mapper/%s", node_name); - if (check_device (name)) - { - if (hook (name, 0)) - { - free (name); - while (seen) - { - struct dmraid_seen *seen_elt = - grub_list_pop (GRUB_AS_LIST_P (&seen)); - free (seen_elt); - } - if (task) - dm_task_destroy (task); - if (tree) - dm_tree_free (tree); - return; - } - } - free (name); + name = xasprintf ("/dev/mapper/%s", node_name); + if (check_device (name)) + { + if (hook (name, 0)) + { + free (name); + while (seen) + { + struct dmraid_seen *seen_elt = + grub_list_pop (GRUB_AS_LIST_P (&seen)); + free (seen_elt); + } + if (task) + dm_task_destroy (task); + if (tree) + dm_tree_free (tree); + return; + } + } + free (name); - seen_elt = xmalloc (sizeof *seen_elt); - seen_elt->name = node_name; - grub_list_push (GRUB_AS_LIST_P (&seen), GRUB_AS_LIST (seen_elt)); + seen_elt = xmalloc (sizeof *seen_elt); + seen_elt->name = node_name; + grub_list_push (GRUB_AS_LIST_P (&seen), GRUB_AS_LIST (seen_elt)); dmraid_next_child: - second = dm_tree_next_child (&second_handle, top, 1); - } - top = dm_tree_next_child (&top_handle, root, 1); - } + second = dm_tree_next_child (&second_handle, top, 1); + } + top = dm_tree_next_child (&top_handle, root, 1); + } dmraid_end: - while (seen) - { - struct dmraid_seen *seen_elt = grub_list_pop (GRUB_AS_LIST_P (&seen)); - free (seen_elt); - } - if (task) - dm_task_destroy (task); - if (tree) - dm_tree_free (tree); - } + while (seen) + { + struct dmraid_seen *seen_elt = grub_list_pop (GRUB_AS_LIST_P (&seen)); + free (seen_elt); + } + if (task) + dm_task_destroy (task); + if (tree) + dm_tree_free (tree); + } # endif /* HAVE_DEVICE_MAPPER */ #endif /* __linux__ */ } From 6ef0ddb4760e58f5dad51169a42e0c77cb5f41d5 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 8 Jun 2010 10:18:53 +0100 Subject: [PATCH 729/738] * docs/grub.texi (Security): Menu entries are unrestricted by default, not restricted to superusers as I had previously thought. Reword to account for this. --- ChangeLog | 6 ++++++ docs/grub.texi | 18 +++++++++++++----- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index c28f77bc8..ce24487d3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-06-08 Colin Watson + + * docs/grub.texi (Security): Menu entries are unrestricted by + default, not restricted to superusers as I had previously thought. + Reword to account for this. + 2010-06-07 Colin Watson * kern/emu/misc.c (device_mapper_null_log): New function. diff --git a/docs/grub.texi b/docs/grub.texi index ffc6b8fe2..1c23460ea 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -1946,11 +1946,14 @@ sets the password hashed using the Password-Based Key Derivation Function In order to enable authentication support, the @samp{superusers} environment variable must be set to a list of usernames, separated by any of spaces, commas, semicolons, pipes, or ampersands. Superusers are permitted to use -the GRUB command line, edit menu entries, and execute any menu entry. +the GRUB command line, edit menu entries, and execute any menu entry. If +@samp{superusers} is set, then use of the command line is automatically +restricted to superusers. Other users may be given access to specific menu entries by giving a list of -usernames (as above) using the @kbd{--users} option to the @samp{menuentry} -command (@pxref{menuentry}). +usernames (as above) using the @option{--users} option to the +@samp{menuentry} command (@pxref{menuentry}). If the @option{--users} +option is not used for a menu entry, then that entry is unrestricted. Putting this together, a typical @file{grub.cfg} fragment might look like this: @@ -1961,12 +1964,17 @@ set superusers="root" password_pbkdf2 root grub.pbkdf2.sha512.10000.biglongstring password user1 insecure -menuentry "Superusers only" @{ +menuentry "May be run by any user" @{ set root=(hd0,1) linux /vmlinuz @} -menuentry "May be run by user1" --users user1 @{ +menuentry "Superusers only" --users "" @{ + set root=(hd0,1) + linux /vmlinuz single +@} + +menuentry "May be run by user1 or a superuser" --users user1 @{ set root=(hd0,2) chainloader +1 @} From d39f3dec5fefecbc83d64106d39b0a12281efaad Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 8 Jun 2010 10:29:25 +0100 Subject: [PATCH 730/738] * docs/grub.texi (History): Expand to cover GRUB 2. (Serial terminal): Refer to `terminal_input' and `terminal_output' commands, not `terminal'. (serial): Likewise. (terminal_input): New section. (terminal_output): New section. (uppermem): New section (stub). (Obtaining and Building GRUB): Refer to Bazaar, not Subversion. --- ChangeLog | 11 ++++++++ docs/grub.texi | 74 +++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 81 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index ce24487d3..15be02a51 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2010-06-08 Colin Watson + + * docs/grub.texi (History): Expand to cover GRUB 2. + (Serial terminal): Refer to `terminal_input' and `terminal_output' + commands, not `terminal'. + (serial): Likewise. + (terminal_input): New section. + (terminal_output): New section. + (uppermem): New section (stub). + (Obtaining and Building GRUB): Refer to Bazaar, not Subversion. + 2010-06-08 Colin Watson * docs/grub.texi (Security): Menu entries are unrestricted by diff --git a/docs/grub.texi b/docs/grub.texi index 1c23460ea..ac3bc2f90 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -174,6 +174,22 @@ official GNU package, and opened its development by making the latest sources available via anonymous CVS. @xref{Obtaining and Building GRUB}, for more information. +Over the next few years, GRUB was extended to meet many needs, but it +quickly became clear that its design was not keeping up with the extensions +being made to it, and we reached the point where it was very difficult to +make any further changes without breaking existing features. Around 2002, +Yoshinori K. Okuji started work on PUPA (Preliminary Universal Programming +Architecture for GNU GRUB), aiming to rewrite the core of GRUB to make it +cleaner, safer, more robust, and more powerful. PUPA was eventually renamed +to GRUB 2, and the original version of GRUB was renamed to GRUB Legacy. +Small amounts of maintenance continued to be done on GRUB Legacy, but the +last release (0.97) was made in 2005 and at the time of writing it seems +unlikely that there will be another. + +By around 2007, GNU/Linux distributions started to use GRUB 2 to limited +extents, and by the end of 2009 multiple major distributions were installing +it by default. + @node Features @section GRUB features @@ -1078,7 +1094,8 @@ you want to use COM2, you must specify @samp{--unit=1} instead. This command accepts many other options, so please refer to @ref{serial}, for more details. -The command @command{terminal} (@pxref{terminal}) chooses which type of +The commands @command{terminal_input} (@pxref{terminal_input}) and +@command{terminal_output} (@pxref{terminal_output} choose which type of terminal you want to use. In the case above, the terminal will be a serial terminal, but you can also pass @code{console} to the command, as @samp{terminal serial console}. In this case, a terminal in which @@ -1421,6 +1438,8 @@ Commands usable anywhere in the menu and in the command-line. @menu * serial:: Set up a serial device +* terminal_input:: Manage input terminals +* terminal_output:: Manage output terminals * terminfo:: Define terminal type @end menu @@ -1440,13 +1459,52 @@ bits and one stop bit. @var{parity} is one of @samp{no}, @samp{odd}, @samp{even} and defaults to @samp{no}. The serial port is not used as a communication channel unless the -@command{terminal} command is used (@pxref{terminal}). +@command{terminal_input} or @command{terminal_output} command is used +(@pxref{terminal_input}, @pxref{terminal_output}). This command is only available if GRUB is compiled with serial support. See also @ref{Serial terminal}. @end deffn +@node terminal_input +@subsection terminal_input + +@deffn Command terminal_input [@option{--append}|@option{--remove}] @ + [terminal1] [terminal2] @dots{} +List or select an input terminal. + +With no arguments, list the active and available input terminals. + +With @option{--append}, add the named terminals to the list of active input +terminals; any of these may be used to provide input to GRUB. + +With @option{--remove}, remove the named terminals from the active list. + +With no options but a list of terminal names, make only the listed terminal +names active. +@end deffn + + +@node terminal_output +@subsection terminal_output + +@deffn Command terminal_output [@option{--append}|@option{--remove}] @ + [terminal1] [terminal2] @dots{} +List or select an output terminal. + +With no arguments, list the active and available output terminals. + +With @option{--append}, add the named terminals to the list of active output +terminals; all of these will receive output from GRUB. + +With @option{--remove}, remove the named terminals from the active list. + +With no options but a list of terminal names, make only the listed terminal +names active. +@end deffn + + @node terminfo @subsection terminfo @@ -1499,6 +1557,7 @@ you forget a command, you can run the command @command{help} * search:: Search devices by file, label, or UUID * set:: Set an environment variable * unset:: Unset an environment variable +* uppermem:: Set the upper memory size @end menu @@ -1921,6 +1980,12 @@ Unset the environment variable @var{envvar}. @end deffn +@node uppermem +@subsection uppermem + +This command is not yet implemented for GRUB 2, although it is planned. + + @node Security @chapter Authentication and authorisation @@ -2190,8 +2255,9 @@ just do: @end group @end example -Also, the latest version is available from the SVN. See -@uref{http://savannah.gnu.org/svn/?group=grub} for more information. +Also, the latest version is available using Bazaar. See +@uref{http://www.gnu.org/software/grub/grub-download.en.html} for more +information. @node Reporting bugs @appendix Reporting bugs From 50e532ca1a421581c6ea63f77a9cd2a5e8c8548a Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 8 Jun 2010 10:37:16 +0100 Subject: [PATCH 731/738] * .bzrignore: Add ascii.bitmaps, ascii.h, grub_script.yy.c, and grub_script.yy.h. --- .bzrignore | 4 ++++ ChangeLog | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/.bzrignore b/.bzrignore index 46e8637b6..aa9c4ff84 100644 --- a/.bzrignore +++ b/.bzrignore @@ -3,6 +3,8 @@ 30_os-prober 40_custom aclocal.m4 +ascii.bitmaps +ascii.h autom4te.cache build_env.mk .bzrignore @@ -48,6 +50,8 @@ grub_script_check_init.c grub_script_check_init.h grub_script.tab.c grub_script.tab.h +grub_script.yy.c +grub_script.yy.h grub-set-default grub-setup grub_setup_init.c diff --git a/ChangeLog b/ChangeLog index 15be02a51..e9570905e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-06-08 Colin Watson + + * .bzrignore: Add ascii.bitmaps, ascii.h, grub_script.yy.c, and + grub_script.yy.h. + 2010-06-08 Colin Watson * docs/grub.texi (History): Expand to cover GRUB 2. From f4d095d77d9d87a1275de19411656ff8cfe69b92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Sutre?= Date: Tue, 8 Jun 2010 12:09:34 +0200 Subject: [PATCH 732/738] Add . to the directories searched for unifont. --- ChangeLog | 4 ++++ configure.ac | 12 +++++++----- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index e9570905e..b48b79819 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-06-08 Grégoire Sutre + + * configure.ac: Add `.' to the directories searched for unifont. + 2010-06-08 Colin Watson * .bzrignore: Add ascii.bitmaps, ascii.h, grub_script.yy.c, and diff --git a/configure.ac b/configure.ac index 31b179d46..97c493e27 100644 --- a/configure.ac +++ b/configure.ac @@ -179,11 +179,13 @@ if test "x$YACC" = x; then AC_MSG_ERROR([bison is not found]) fi -for file in /usr/src/unifont.bdf /usr/share/fonts/X11/misc/unifont.pcf.gz /usr/share/fonts/unifont/unifont.pcf.gz; do - if test -e $file ; then - AC_SUBST([FONT_SOURCE], [$file]) - break - fi +for ext in pcf pcf.gz bdf bdf.gz ttf ttf.gz; do + for dir in . /usr/src /usr/share/fonts/X11/misc /usr/share/fonts/unifont; do + if test -f "$dir/unifont.$ext"; then + AC_SUBST([FONT_SOURCE], [$dir/unifont.$ext]) + break 2 + fi + done done AC_PROG_INSTALL From e8a6f3b6a5f07e8a63788e33866fa99ed8737297 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Sutre?= Date: Tue, 8 Jun 2010 12:23:30 +0200 Subject: [PATCH 733/738] Use absolute offsets for start of embedding area. --- ChangeLog | 5 +++++ util/i386/pc/grub-setup.c | 10 +++++----- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index b48b79819..45637ac17 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-06-08 Grégoire Sutre + + * util/i386/pc/grub-setup.c (setup): Use absolute offsets for start of + embedding area. Use <= instead of == when checking for non-emptiness. + 2010-06-08 Grégoire Sutre * configure.ac: Add `.' to the directories searched for unifont. diff --git a/util/i386/pc/grub-setup.c b/util/i386/pc/grub-setup.c index 6e6b2e878..08a76f65c 100644 --- a/util/i386/pc/grub-setup.c +++ b/util/i386/pc/grub-setup.c @@ -126,8 +126,8 @@ setup (const char *dir, /* There's always an embed region, and it starts right after the MBR. */ embed_region.start = 1; - if (embed_region.end > p->start) - embed_region.end = p->start; + if (embed_region.end > grub_partition_get_start (p)) + embed_region.end = grub_partition_get_start (p); return 0; } @@ -147,8 +147,8 @@ setup (const char *dir, /* If there's an embed region, it is in a dedicated partition. */ if (! memcmp (&gptdata.type, &grub_gpt_partition_type_bios_boot, 16)) { - embed_region.start = p->start; - embed_region.end = p->start + p->len; + embed_region.start = grub_partition_get_start (p); + embed_region.end = grub_partition_get_start (p) + grub_partition_get_len (p); return 1; } @@ -361,7 +361,7 @@ setup (const char *dir, else grub_util_error (_("No DOS-style partitions found")); - if (embed_region.end == embed_region.start) + if (embed_region.end <= embed_region.start) { if (! strcmp (dest_partmap, "msdos")) grub_util_warn (_("This msdos-style partition label has no post-MBR gap; embedding won't be possible!")); From 0ea7c4f93cdacfd650dfba43ee6e410a2414aca3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Sutre?= Date: Tue, 8 Jun 2010 12:52:42 +0200 Subject: [PATCH 734/738] Make --version uniform and avoid hard-coded program name. --- ChangeLog | 19 +++++++++++++++++++ util/grub-install.in | 10 ++++++---- util/grub-mkconfig.in | 13 ++++++++----- util/grub-mkimage.c | 2 +- util/grub-mkrescue.in | 8 +++++--- util/grub-reboot.in | 8 ++++++-- util/grub-set-default.in | 8 ++++++-- util/i386/efi/grub-install.in | 10 ++++++---- util/i386/pc/grub-setup.c | 2 +- util/ieee1275/grub-install.in | 10 ++++++---- util/powerpc/ieee1275/grub-mkrescue.in | 8 +++++--- util/sparc64/ieee1275/grub-setup.c | 2 +- 12 files changed, 70 insertions(+), 30 deletions(-) diff --git a/ChangeLog b/ChangeLog index 45637ac17..9bbeae6c2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +2010-06-08 Grégoire Sutre + + Make --version uniform and avoid hard-coded program name. + + * util/grub-mkimage.c (main): Use `program_name' instead of + hard-coded string. + * util/i386/pc/grub-setup.c (main): Likewise. + * util/sparc64/ieee1275/grub-setup.c (parse_options): Likewise. + * util/grub-install.in: Save the basename of $0 in $self, and use the + latter in informational messages. Use the same format for --version + as the binary programs. + * util/grub-mkconfig.in: Likewise. + * util/grub-mkrescue.in: Likewise. + * util/grub-reboot.in: Likewise. + * util/grub-set-default.in: Likewise. + * util/i386/efi/grub-install.in: Likewise. + * util/ieee1275/grub-install.in: Likewise. + * util/powerpc/ieee1275/grub-mkrescue.in: Likewise. + 2010-06-08 Grégoire Sutre * util/i386/pc/grub-setup.c (setup): Use absolute offsets for start of diff --git a/util/grub-install.in b/util/grub-install.in index 0db216fd5..1e7fc1f2e 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -34,6 +34,8 @@ font=@datadir@/@PACKAGE_TARNAME@/ascii.pf2 pkglibdir=${libdir}/`echo ${PACKAGE_TARNAME}/${target_cpu}-${platform} | sed ${transform}` localedir=@datadir@/locale +self=`basename $0` + grub_setup=${sbindir}/`echo grub-setup | sed ${transform}` grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}` grub_mkdevicemap=${sbindir}/`echo grub-mkdevicemap | sed ${transform}` @@ -61,7 +63,7 @@ fi # Print the usage. usage () { cat <. @@ -108,7 +110,7 @@ for option in "$@"; do usage exit 0 ;; -v | --version) - echo "grub-install (GNU GRUB ${PACKAGE_VERSION})" + echo "$self (${PACKAGE_NAME}) ${PACKAGE_VERSION}" exit 0 ;; --modules=*) modules=`echo "$option" | sed 's/--modules=//'` ;; diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in index 0095e1ce8..d916459d6 100644 --- a/util/grub-mkconfig.in +++ b/util/grub-mkconfig.in @@ -23,7 +23,8 @@ exec_prefix=@exec_prefix@ sbindir=@sbindir@ libdir=@libdir@ sysconfdir=@sysconfdir@ -package_version=@PACKAGE_VERSION@ +PACKAGE_NAME=@PACKAGE_NAME@ +PACKAGE_VERSION=@PACKAGE_VERSION@ host_os=@host_os@ datarootdir=@datarootdir@ datadir=@datadir@ @@ -31,6 +32,8 @@ pkgdatadir=${datadir}/`echo @PACKAGE_TARNAME@ | sed "${transform}"` grub_cfg="" grub_mkconfig_dir=${sysconfdir}/grub.d +self=`basename $0` + grub_mkdevicemap=${sbindir}/`echo grub-mkdevicemap | sed ${transform}` grub_probe=${sbindir}/`echo grub-probe | sed ${transform}` @@ -38,7 +41,7 @@ grub_probe=${sbindir}/`echo grub-probe | sed ${transform}` # Print the usage. usage () { cat <&2 + echo "$self: You must run this as root" >&2 exit 1 fi fi @@ -284,7 +287,7 @@ cat << EOF # # DO NOT EDIT THIS FILE # -# It is automatically generated by $0 using templates +# It is automatically generated by $self using templates # from ${grub_mkconfig_dir} and settings from ${sysconfdir}/default/grub # EOF diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index 4e39450df..7b03c2fd0 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -1307,7 +1307,7 @@ main (int argc, char *argv[]) break; case 'V': - printf ("grub-mkimage (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION); + printf ("%s (%s) %s\n", program_name, PACKAGE_NAME, PACKAGE_VERSION); return 0; case 'v': diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in index 99b10de7b..61b0c94f7 100644 --- a/util/grub-mkrescue.in +++ b/util/grub-mkrescue.in @@ -30,6 +30,8 @@ target_cpu=@target_cpu@ native_platform=@platform@ pkglib_DATA="@pkglib_DATA@" +self=`basename $0` + multiboot_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/i386-multiboot coreboot_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/i386-coreboot qemu_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/i386-qemu @@ -44,7 +46,7 @@ grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}` # Print the usage. usage () { cat <. EOF @@ -67,7 +69,7 @@ for option in "$@"; do usage exit 0 ;; -v | --version) - echo "$0 (GNU GRUB ${PACKAGE_VERSION})" + echo "$self (${PACKAGE_NAME}) ${PACKAGE_VERSION}" exit 0 ;; --modules=*) modules=`echo "$option" | sed 's/--modules=//'` ;; diff --git a/util/grub-reboot.in b/util/grub-reboot.in index 20f2b10bc..2c49f5e13 100644 --- a/util/grub-reboot.in +++ b/util/grub-reboot.in @@ -22,6 +22,10 @@ transform="@program_transform_name@" prefix=@prefix@ exec_prefix=@exec_prefix@ bindir=@bindir@ +PACKAGE_NAME=@PACKAGE_NAME@ +PACKAGE_VERSION=@PACKAGE_VERSION@ + +self=`basename $0` grub_editenv=${bindir}/`echo grub-editenv | sed ${transform}` rootdir= @@ -30,7 +34,7 @@ rootdir= # Print the usage. usage () { cat <. @@ -78,7 +80,7 @@ for option in "$@"; do usage exit 0 ;; -v | --version) - echo "grub-install (GNU GRUB ${PACKAGE_VERSION})" + echo "$self (${PACKAGE_NAME}) ${PACKAGE_VERSION}" exit 0 ;; --modules=*) modules=`echo "$option" | sed 's/--modules=//'` ;; @@ -219,7 +221,7 @@ $grub_mkimage -O ${target_cpu}-efi --output=${grubdir}/grub.efi $modules || exit echo "Installation finished. No error reported." echo "This is the contents of the device map $device_map." echo "Check if this is correct or not. If any of the lines is incorrect," -echo "fix it and re-run the script \`grub-install'." +echo "fix it and re-run the script \`$self'." echo cat $device_map diff --git a/util/i386/pc/grub-setup.c b/util/i386/pc/grub-setup.c index 08a76f65c..ef0f5a990 100644 --- a/util/i386/pc/grub-setup.c +++ b/util/i386/pc/grub-setup.c @@ -702,7 +702,7 @@ main (int argc, char *argv[]) break; case 'V': - printf ("grub-setup (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION); + printf ("%s (%s) %s\n", program_name, PACKAGE_NAME, PACKAGE_VERSION); return 0; case 'v': diff --git a/util/ieee1275/grub-install.in b/util/ieee1275/grub-install.in index 4d00cc217..72135213d 100644 --- a/util/ieee1275/grub-install.in +++ b/util/ieee1275/grub-install.in @@ -34,6 +34,8 @@ target_cpu=@target_cpu@ platform=@platform@ pkglibdir=${libdir}/`echo ${PACKAGE_TARNAME}/${target_cpu}-${platform} | sed ${transform}` +self=`basename $0` + grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}` grub_mkdevicemap=${sbindir}/`echo grub-mkdevicemap | sed ${transform}` grub_probe=${sbindir}/`echo grub-probe | sed ${transform}` @@ -53,7 +55,7 @@ nvsetenv=`which nvsetenv` # Print the usage. usage () { cat <. EOF @@ -61,7 +63,7 @@ for option in "$@"; do usage exit 0 ;; -v | --version) - echo "grub-mkrescue (GNU GRUB ${PACKAGE_VERSION})" + echo "$self (${PACKAGE_NAME}) ${PACKAGE_VERSION}" exit 0 ;; --modules=*) modules=`echo "$option" | sed 's/--modules=//'` ;; diff --git a/util/sparc64/ieee1275/grub-setup.c b/util/sparc64/ieee1275/grub-setup.c index 8a2d30ba1..93e135eb3 100644 --- a/util/sparc64/ieee1275/grub-setup.c +++ b/util/sparc64/ieee1275/grub-setup.c @@ -503,7 +503,7 @@ parse_options (struct grub_setup_info *gp, int argc, char *argv[]) break; case 'V': - printf ("grub-setup (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION); + printf ("%s (%s) %s\n", program_name, PACKAGE_NAME, PACKAGE_VERSION); return 0; case 'v': From 9146024736865ce501bd750cb1b7a0b286db48e0 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Wed, 9 Jun 2010 20:43:25 +0200 Subject: [PATCH 735/738] 2010-06-09 Robert Millan * util/grub.d/10_linux.in: Prefer compressed images over non-compressed ones, when both are available. --- ChangeLog | 5 +++++ util/grub.d/10_linux.in | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 9bbeae6c2..6158ef4b3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-06-09 Robert Millan + + * util/grub.d/10_linux.in: Prefer compressed images over non-compressed + ones, when both are available. + 2010-06-08 Grégoire Sutre Make --version uniform and avoid hard-coded program name. diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in index 802d59f51..416ab6ed6 100644 --- a/util/grub.d/10_linux.in +++ b/util/grub.d/10_linux.in @@ -97,7 +97,7 @@ EOF EOF } -list=`for i in /boot/vmlinu[xz]-* /vmlinu[xz]-* ; do +list=`for i in /boot/vmlinu[zx]-* /vmlinu[zx]-* ; do if grub_file_is_not_garbage "$i" ; then echo -n "$i " ; fi done` prepare_boot_cache= From 6289c3a71507d8b02d859aa2e59d4e4dc81eb417 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 9 Jun 2010 22:24:12 +0200 Subject: [PATCH 736/738] * docs/grub.texi (Vendor power-on button): Add Asus EeePC 1005PE as reported by Henrique Ferreiro. --- ChangeLog | 5 +++++ docs/grub.texi | 2 ++ 2 files changed, 7 insertions(+) diff --git a/ChangeLog b/ChangeLog index 6158ef4b3..0575e7c5d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-06-09 Vladimir Serbinenko + + * docs/grub.texi (Vendor power-on button): Add Asus EeePC 1005PE as + reported by Henrique Ferreiro. + 2010-06-09 Robert Millan * util/grub.d/10_linux.in: Prefer compressed images over non-compressed diff --git a/docs/grub.texi b/docs/grub.texi index ac3bc2f90..9fe197da2 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -1123,6 +1123,8 @@ Values known to GRUB team are: @table @key @item Dell XPS M1530 85:3 +@item Asus EeePC 1005PE +84:1 (unconfirmed) @end table To take full advantage of this function install GRUB into MBR. From 56a0d956d196be7828d0845aa225a0514c395e37 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 11 Jun 2010 22:12:16 +0100 Subject: [PATCH 737/738] * Makefile.in (install-local): Include $(srcdir)/docs/man/$$dest.h2m when generating manual pages. * docs/man/grub-bin2h.h2m: New file. * docs/man/grub-editenv.h2m: New file. * docs/man/grub-fstest.h2m: New file. * docs/man/grub-install.h2m: New file. * docs/man/grub-macho2img.h2m: New file. * docs/man/grub-mkconfig.h2m: New file. * docs/man/grub-mkdevicemap.h2m: New file. * docs/man/grub-mkfont.h2m: New file. * docs/man/grub-mkimage.h2m: New file. * docs/man/grub-mkpasswd-pbkdf2.h2m: New file. * docs/man/grub-mkrelpath.h2m: New file. * docs/man/grub-mkrescue.h2m: New file. * docs/man/grub-ofpathname.h2m: New file. * docs/man/grub-pe2elf.h2m: New file. * docs/man/grub-probe.h2m: New file. * docs/man/grub-reboot.h2m: New file. * docs/man/grub-script-check.h2m: New file. * docs/man/grub-set-default.h2m: New file. * docs/man/grub-setup.h2m: New file. --- ChangeLog | 24 ++++++++++++++++++++++++ Makefile.in | 8 ++++---- docs/man/grub-bin2h.h2m | 2 ++ docs/man/grub-editenv.h2m | 2 ++ docs/man/grub-fstest.h2m | 2 ++ docs/man/grub-install.h2m | 2 ++ docs/man/grub-macho2img.h2m | 2 ++ docs/man/grub-mkconfig.h2m | 2 ++ docs/man/grub-mkdevicemap.h2m | 2 ++ docs/man/grub-mkfont.h2m | 2 ++ docs/man/grub-mkimage.h2m | 2 ++ docs/man/grub-mkpasswd-pbkdf2.h2m | 2 ++ docs/man/grub-mkrelpath.h2m | 2 ++ docs/man/grub-mkrescue.h2m | 2 ++ docs/man/grub-ofpathname.h2m | 2 ++ docs/man/grub-pe2elf.h2m | 2 ++ docs/man/grub-probe.h2m | 2 ++ docs/man/grub-reboot.h2m | 2 ++ docs/man/grub-script-check.h2m | 2 ++ docs/man/grub-set-default.h2m | 2 ++ docs/man/grub-setup.h2m | 2 ++ 21 files changed, 66 insertions(+), 4 deletions(-) create mode 100644 docs/man/grub-bin2h.h2m create mode 100644 docs/man/grub-editenv.h2m create mode 100644 docs/man/grub-fstest.h2m create mode 100644 docs/man/grub-install.h2m create mode 100644 docs/man/grub-macho2img.h2m create mode 100644 docs/man/grub-mkconfig.h2m create mode 100644 docs/man/grub-mkdevicemap.h2m create mode 100644 docs/man/grub-mkfont.h2m create mode 100644 docs/man/grub-mkimage.h2m create mode 100644 docs/man/grub-mkpasswd-pbkdf2.h2m create mode 100644 docs/man/grub-mkrelpath.h2m create mode 100644 docs/man/grub-mkrescue.h2m create mode 100644 docs/man/grub-ofpathname.h2m create mode 100644 docs/man/grub-pe2elf.h2m create mode 100644 docs/man/grub-probe.h2m create mode 100644 docs/man/grub-reboot.h2m create mode 100644 docs/man/grub-script-check.h2m create mode 100644 docs/man/grub-set-default.h2m create mode 100644 docs/man/grub-setup.h2m diff --git a/ChangeLog b/ChangeLog index c4a6246ee..43cf36b32 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,27 @@ +2010-06-11 Colin Watson + + * Makefile.in (install-local): Include $(srcdir)/docs/man/$$dest.h2m + when generating manual pages. + * docs/man/grub-bin2h.h2m: New file. + * docs/man/grub-editenv.h2m: New file. + * docs/man/grub-fstest.h2m: New file. + * docs/man/grub-install.h2m: New file. + * docs/man/grub-macho2img.h2m: New file. + * docs/man/grub-mkconfig.h2m: New file. + * docs/man/grub-mkdevicemap.h2m: New file. + * docs/man/grub-mkfont.h2m: New file. + * docs/man/grub-mkimage.h2m: New file. + * docs/man/grub-mkpasswd-pbkdf2.h2m: New file. + * docs/man/grub-mkrelpath.h2m: New file. + * docs/man/grub-mkrescue.h2m: New file. + * docs/man/grub-ofpathname.h2m: New file. + * docs/man/grub-pe2elf.h2m: New file. + * docs/man/grub-probe.h2m: New file. + * docs/man/grub-reboot.h2m: New file. + * docs/man/grub-script-check.h2m: New file. + * docs/man/grub-set-default.h2m: New file. + * docs/man/grub-setup.h2m: New file. + 2010-06-10 Vladimir Serbinenko Use FOR_* macros instead of *_iterate whenever possible. diff --git a/Makefile.in b/Makefile.in index 75388e3c8..afe4beb6e 100644 --- a/Makefile.in +++ b/Makefile.in @@ -323,26 +323,26 @@ install-local: all if test -f "$$file"; then dir=; else dir="$(srcdir)/"; fi; \ dest="`echo $$file | sed 's,.*/,,' | sed '$(transform)'`"; \ $(INSTALL_PROGRAM) $$dir$$file $(DESTDIR)$(bindir)/$$dest; \ - $(HELP2MAN) --section=1 -o $(DESTDIR)$(mandir)/man1/$$dest.1 $(builddir)/$$file; \ + $(HELP2MAN) --section=1 -i $(srcdir)/docs/man/$$dest.h2m -o $(DESTDIR)$(mandir)/man1/$$dest.1 $(builddir)/$$file; \ done $(SHELL) $(mkinstalldirs) $(DESTDIR)$(sbindir) $(DESTDIR)$(mandir)/man8 @list='$(sbin_UTILITIES)'; for file in $$list; do \ if test -f "$$file"; then dir=; else dir="$(srcdir)/"; fi; \ dest="`echo $$file | sed 's,.*/,,' | sed '$(transform)'`"; \ $(INSTALL_PROGRAM) $$dir$$file $(DESTDIR)$(sbindir)/$$dest; \ - $(HELP2MAN) --section=8 -o $(DESTDIR)$(mandir)/man8/$$dest.8 $(builddir)/$$file; \ + $(HELP2MAN) --section=8 -i $(srcdir)/docs/man/$$dest.h2m -o $(DESTDIR)$(mandir)/man8/$$dest.8 $(builddir)/$$file; \ done @list='$(bin_SCRIPTS)'; for file in $$list; do \ if test -f "$$file"; then dir=; else dir="$(srcdir)/"; fi; \ dest="`echo $$file | sed 's,.*/,,' | sed '$(transform)'`"; \ $(INSTALL_SCRIPT) $$dir$$file $(DESTDIR)$(bindir)/$$dest; \ - $(HELP2MAN) --section=1 -o $(DESTDIR)$(mandir)/man1/$$dest.1 $(builddir)/$$file; \ + $(HELP2MAN) --section=1 -i $(srcdir)/docs/man/$$dest.h2m -o $(DESTDIR)$(mandir)/man1/$$dest.1 $(builddir)/$$file; \ done @list='$(sbin_SCRIPTS)'; for file in $$list; do \ if test -f "$$file"; then dir=; else dir="$(srcdir)/"; fi; \ dest="`echo $$file | sed 's,.*/,,' | sed '$(transform)'`"; \ $(INSTALL_SCRIPT) $$dir$$file $(DESTDIR)$(sbindir)/$$dest; \ - $(HELP2MAN) --section=8 -o $(DESTDIR)$(mandir)/man8/$$dest.8 $(builddir)/$$file; \ + $(HELP2MAN) --section=8 -i $(srcdir)/docs/man/$$dest.h2m -o $(DESTDIR)$(mandir)/man8/$$dest.8 $(builddir)/$$file; \ done $(SHELL) $(mkinstalldirs) $(DESTDIR)$(sysconfdir)/grub.d @list='$(grub-mkconfig_SCRIPTS)'; for file in $$list; do \ diff --git a/docs/man/grub-bin2h.h2m b/docs/man/grub-bin2h.h2m new file mode 100644 index 000000000..ef463f3d1 --- /dev/null +++ b/docs/man/grub-bin2h.h2m @@ -0,0 +1,2 @@ +[NAME] +grub-bin2h \- convert a binary file to a C header diff --git a/docs/man/grub-editenv.h2m b/docs/man/grub-editenv.h2m new file mode 100644 index 000000000..efbd79070 --- /dev/null +++ b/docs/man/grub-editenv.h2m @@ -0,0 +1,2 @@ +[NAME] +grub-editenv \- edit GRUB environment block diff --git a/docs/man/grub-fstest.h2m b/docs/man/grub-fstest.h2m new file mode 100644 index 000000000..be39429b5 --- /dev/null +++ b/docs/man/grub-fstest.h2m @@ -0,0 +1,2 @@ +[NAME] +grub-fstest \- debug tool for GRUB filesystem drivers diff --git a/docs/man/grub-install.h2m b/docs/man/grub-install.h2m new file mode 100644 index 000000000..65252155c --- /dev/null +++ b/docs/man/grub-install.h2m @@ -0,0 +1,2 @@ +[NAME] +grub-install \- install GRUB to a device diff --git a/docs/man/grub-macho2img.h2m b/docs/man/grub-macho2img.h2m new file mode 100644 index 000000000..412bf926a --- /dev/null +++ b/docs/man/grub-macho2img.h2m @@ -0,0 +1,2 @@ +[NAME] +grub-macho2img \- convert Mach-O to raw image diff --git a/docs/man/grub-mkconfig.h2m b/docs/man/grub-mkconfig.h2m new file mode 100644 index 000000000..b0d33ec61 --- /dev/null +++ b/docs/man/grub-mkconfig.h2m @@ -0,0 +1,2 @@ +[NAME] +grub-mkconfig \- generate a GRUB configuration file diff --git a/docs/man/grub-mkdevicemap.h2m b/docs/man/grub-mkdevicemap.h2m new file mode 100644 index 000000000..8ab34ac86 --- /dev/null +++ b/docs/man/grub-mkdevicemap.h2m @@ -0,0 +1,2 @@ +[NAME] +grub-mkdevicemap \- generate a GRUB device map file automatically diff --git a/docs/man/grub-mkfont.h2m b/docs/man/grub-mkfont.h2m new file mode 100644 index 000000000..d8580186f --- /dev/null +++ b/docs/man/grub-mkfont.h2m @@ -0,0 +1,2 @@ +[NAME] +grub-mkfont \- make GRUB font files diff --git a/docs/man/grub-mkimage.h2m b/docs/man/grub-mkimage.h2m new file mode 100644 index 000000000..71f270940 --- /dev/null +++ b/docs/man/grub-mkimage.h2m @@ -0,0 +1,2 @@ +[NAME] +grub-mkimage \- make a bootable image of GRUB diff --git a/docs/man/grub-mkpasswd-pbkdf2.h2m b/docs/man/grub-mkpasswd-pbkdf2.h2m new file mode 100644 index 000000000..5b2b2ef7f --- /dev/null +++ b/docs/man/grub-mkpasswd-pbkdf2.h2m @@ -0,0 +1,2 @@ +[NAME] +grub-mkpasswd-pbkdf2 \- generate hashed password for GRUB diff --git a/docs/man/grub-mkrelpath.h2m b/docs/man/grub-mkrelpath.h2m new file mode 100644 index 000000000..ccc0880fa --- /dev/null +++ b/docs/man/grub-mkrelpath.h2m @@ -0,0 +1,2 @@ +[NAME] +grub-mkrelpath \- make a system path relative to its root diff --git a/docs/man/grub-mkrescue.h2m b/docs/man/grub-mkrescue.h2m new file mode 100644 index 000000000..5e92e0d99 --- /dev/null +++ b/docs/man/grub-mkrescue.h2m @@ -0,0 +1,2 @@ +[NAME] +grub-mkrescue \- make a GRUB rescue image diff --git a/docs/man/grub-ofpathname.h2m b/docs/man/grub-ofpathname.h2m new file mode 100644 index 000000000..f07158cb3 --- /dev/null +++ b/docs/man/grub-ofpathname.h2m @@ -0,0 +1,2 @@ +[NAME] +grub-ofpathname \- find OpenBOOT path for a device diff --git a/docs/man/grub-pe2elf.h2m b/docs/man/grub-pe2elf.h2m new file mode 100644 index 000000000..3fdb88b43 --- /dev/null +++ b/docs/man/grub-pe2elf.h2m @@ -0,0 +1,2 @@ +[NAME] +grub-pe2elf \- convert PE image to ELF diff --git a/docs/man/grub-probe.h2m b/docs/man/grub-probe.h2m new file mode 100644 index 000000000..817ba8ef6 --- /dev/null +++ b/docs/man/grub-probe.h2m @@ -0,0 +1,2 @@ +[NAME] +grub-probe \- probe device information for GRUB diff --git a/docs/man/grub-reboot.h2m b/docs/man/grub-reboot.h2m new file mode 100644 index 000000000..957e4b797 --- /dev/null +++ b/docs/man/grub-reboot.h2m @@ -0,0 +1,2 @@ +[NAME] +grub-reboot \- set the default boot entry for GRUB, for the next boot only diff --git a/docs/man/grub-script-check.h2m b/docs/man/grub-script-check.h2m new file mode 100644 index 000000000..39c0a3ef6 --- /dev/null +++ b/docs/man/grub-script-check.h2m @@ -0,0 +1,2 @@ +[NAME] +grub-script-check \- check grub.cfg for syntax errors diff --git a/docs/man/grub-set-default.h2m b/docs/man/grub-set-default.h2m new file mode 100644 index 000000000..3ac13d7ed --- /dev/null +++ b/docs/man/grub-set-default.h2m @@ -0,0 +1,2 @@ +[NAME] +grub-set-default \- set the default boot entry for GRUB diff --git a/docs/man/grub-setup.h2m b/docs/man/grub-setup.h2m new file mode 100644 index 000000000..e70e465a4 --- /dev/null +++ b/docs/man/grub-setup.h2m @@ -0,0 +1,2 @@ +[NAME] +grub-setup \- set up a device to boot using GRUB From 283af07aff47fdc234e80da3fa4c5891f0ab9289 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 11 Jun 2010 22:15:35 +0100 Subject: [PATCH 738/738] * include/grub/efi/uga_draw.h (GRUB_EFI_UGA_GLT_MAX): Rename to ... (GRUB_EFI_UGA_BLT_MAX): ... this (typo fix). --- ChangeLog | 5 +++++ include/grub/efi/uga_draw.h | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 43cf36b32..ab9415191 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-06-11 Colin Watson + + * include/grub/efi/uga_draw.h (GRUB_EFI_UGA_GLT_MAX): Rename to ... + (GRUB_EFI_UGA_BLT_MAX): ... this (typo fix). + 2010-06-11 Colin Watson * Makefile.in (install-local): Include $(srcdir)/docs/man/$$dest.h2m diff --git a/include/grub/efi/uga_draw.h b/include/grub/efi/uga_draw.h index 93504307c..a31f2672e 100644 --- a/include/grub/efi/uga_draw.h +++ b/include/grub/efi/uga_draw.h @@ -32,7 +32,7 @@ enum grub_efi_uga_blt_operation GRUB_EFI_UGA_VIDEO_TO_BLT, GRUB_EFI_UGA_BLT_TO_VIDEO, GRUB_EFI_UGA_VIDEO_TO_VIDEO, - GRUB_EFI_UGA_GLT_MAX + GRUB_EFI_UGA_BLT_MAX }; struct grub_efi_uga_pixel