diff --git a/0001-Add-monochrome-text-support-mda_text-aka-hercules-in.patch b/0001-Add-monochrome-text-support-mda_text-aka-hercules-in.patch new file mode 100644 index 0000000..e63a26d --- /dev/null +++ b/0001-Add-monochrome-text-support-mda_text-aka-hercules-in.patch @@ -0,0 +1,612 @@ +From 8c5886df17cdfb148d4e17bddf38143ed65fe674 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Thu, 28 Jun 2012 15:27:54 +0200 +Subject: [PATCH 001/364] Add monochrome text support (mda_text, aka + `hercules' in grub-legacy). + + * grub-core/Makefile.core.def (mda_text): New module. + * grub-core/lib/legacy_parse.c (grub_legacy_parse): Support `hercules'. + * grub-core/term/i386/vga_common.c (grub_console_cur_color): Moved to .. + * grub-core/term/i386/pc/vga_text.c (cur_color): ... here + * grub-core/term/i386/pc/console.c (grub_console_cur_color): ... and + here. + * grub-core/term/i386/vga_common.c (grub_console_getwh): Moved to .. + * grub-core/term/i386/pc/vga_text.c (grub_console_getwh): ... here + * grub-core/term/i386/pc/console.c (grub_console_getwh): ... and + here. + * grub-core/term/i386/vga_common.c (grub_console_setcolorstate): Moved + to .. + * grub-core/term/i386/pc/vga_text.c (grub_console_setcolorstate): + ... here + * grub-core/term/i386/pc/console.c (grub_console_setcolorstate): ... and + here. + * grub-core/term/i386/vga_common.c: Removed. + * include/grub/i386/vga_common.h: Likewise. + * include/grub/vga.h (grub_vga_cr_bw_write): New function. + (grub_vga_cr_bw_read): Likewise. + * include/grub/vgaregs.h (GRUB_VGA_IO_CR_BW_INDEX): New enum value. + (GRUB_VGA_IO_CR_BW_DATA): Likewise. + * grub-core/term/i386/pc/vga_text.c [MODE_MDA]: Call + grub_vga_cr_bw_read/grub_vga_cr_bw_write instead of + grub_vga_cr_read/grub_vga_cr_write. + (grub_vga_text_setcolorstate) [MODE_MDA]: Ignore color. +--- + ChangeLog | 31 +++++++++ + grub-core/Makefile.core.def | 12 ++-- + grub-core/lib/legacy_parse.c | 15 ++-- + grub-core/term/i386/pc/console.c | 27 ++++++++ + grub-core/term/i386/pc/vga_text.c | 141 +++++++++++++++++++++++++++++++++----- + grub-core/term/i386/vga_common.c | 48 ------------- + include/grub/i386/pc/console.h | 1 - + include/grub/i386/vga_common.h | 32 --------- + include/grub/vga.h | 14 ++++ + include/grub/vgaregs.h | 2 + + 10 files changed, 213 insertions(+), 110 deletions(-) + delete mode 100644 grub-core/term/i386/vga_common.c + delete mode 100644 include/grub/i386/vga_common.h + +diff --git a/ChangeLog b/ChangeLog +index 81bdae9..f6e864a 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,34 @@ ++2012-06-28 Vladimir Serbinenko ++ ++ Add monochrome text support (mda_text, aka `hercules' in grub-legacy). ++ ++ * grub-core/Makefile.core.def (mda_text): New module. ++ * grub-core/lib/legacy_parse.c (grub_legacy_parse): Support `hercules'. ++ * grub-core/term/i386/vga_common.c (grub_console_cur_color): Moved to .. ++ * grub-core/term/i386/pc/vga_text.c (cur_color): ... here ++ * grub-core/term/i386/pc/console.c (grub_console_cur_color): ... and ++ here. ++ * grub-core/term/i386/vga_common.c (grub_console_getwh): Moved to .. ++ * grub-core/term/i386/pc/vga_text.c (grub_console_getwh): ... here ++ * grub-core/term/i386/pc/console.c (grub_console_getwh): ... and ++ here. ++ * grub-core/term/i386/vga_common.c (grub_console_setcolorstate): Moved ++ to .. ++ * grub-core/term/i386/pc/vga_text.c (grub_console_setcolorstate): ++ ... here ++ * grub-core/term/i386/pc/console.c (grub_console_setcolorstate): ... and ++ here. ++ * grub-core/term/i386/vga_common.c: Removed. ++ * include/grub/i386/vga_common.h: Likewise. ++ * include/grub/vga.h (grub_vga_cr_bw_write): New function. ++ (grub_vga_cr_bw_read): Likewise. ++ * include/grub/vgaregs.h (GRUB_VGA_IO_CR_BW_INDEX): New enum value. ++ (GRUB_VGA_IO_CR_BW_DATA): Likewise. ++ * grub-core/term/i386/pc/vga_text.c [MODE_MDA]: Call ++ grub_vga_cr_bw_read/grub_vga_cr_bw_write instead of ++ grub_vga_cr_read/grub_vga_cr_write. ++ (grub_vga_text_setcolorstate) [MODE_MDA]: Ignore color. ++ + 2012-06-27 Vladimir Serbinenko + + * configure.ac: Bump version to 2.00. +diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def +index 39e77a4..5c2fcc2 100644 +--- a/grub-core/Makefile.core.def ++++ b/grub-core/Makefile.core.def +@@ -123,9 +123,6 @@ kernel = { + i386_coreboot_multiboot_qemu = kern/i386/coreboot/init.c; + i386_coreboot_multiboot_qemu = term/i386/pc/vga_text.c; + +- i386_coreboot_multiboot_qemu = term/i386/vga_common.c; +- i386_pc = term/i386/vga_common.c; +- + x86 = kern/i386/pit.c; + + efi = disk/efi/efidisk.c; +@@ -175,7 +172,6 @@ kernel = { + mips_qemu_mips = term/at_keyboard.c; + mips_qemu_mips = commands/keylayouts.c; + mips_qemu_mips = term/i386/pc/vga_text.c; +- mips_qemu_mips = term/i386/vga_common.c; + mips_qemu_mips = kern/vga_init.c; + + mips_arc = kern/mips/arc/init.c; +@@ -1591,11 +1587,17 @@ module = { + module = { + name = vga_text; + common = term/i386/pc/vga_text.c; +- common = term/i386/vga_common.c; + enable = i386_pc; + }; + + module = { ++ name = mda_text; ++ common = term/i386/pc/mda_text.c; ++ enable = i386_pc; ++ enable = i386_coreboot_multiboot_qemu; ++}; ++ ++module = { + name = video_cirrus; + x86 = video/cirrus.c; + enable = x86; +diff --git a/grub-core/lib/legacy_parse.c b/grub-core/lib/legacy_parse.c +index 775eaad..14768b8 100644 +--- a/grub-core/lib/legacy_parse.c ++++ b/grub-core/lib/legacy_parse.c +@@ -1,6 +1,6 @@ + /* + * GRUB -- GRand Unified Bootloader +- * Copyright (C) 1999,2000,2001,2002,2003,2004,2010 Free Software Foundation, Inc. ++ * Copyright (C) 1999,2000,2001,2002,2003,2004,2010,2012 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 +@@ -290,7 +290,7 @@ static struct legacy_command legacy_commands[] = + " default values are COM1, 9600, 8N1."}, + /* FIXME: setkey unsupported. */ /* NUL_TERMINATE */ + /* NOTE: setup unsupported. */ +- /* FIXME: --no-echo, --no-edit, hercules unsupported. */ ++ /* FIXME: --no-echo, --no-edit unsupported. */ + /* NOTE: both terminals are activated so --silent and --timeout + are useless. */ + {"terminal", NULL, NULL, 0, 0, {}, FLAG_TERMINAL | FLAG_IGNORE_REST, +@@ -507,8 +507,8 @@ grub_legacy_parse (const char *buf, char **entryname, char **suffix) + int dumb = 0, lines = 24; + #ifdef TODO + int no_echo = 0, no_edit = 0; +- int hercules = 0; + #endif ++ int hercules = 0; + int console = 0, serial = 0; + /* Big enough for any possible resulting command. */ + char outbuf[256] = ""; +@@ -541,10 +541,8 @@ grub_legacy_parse (const char *buf, char **entryname, char **suffix) + + if (grub_memcmp (ptr, "serial", sizeof ("serial") - 1) == 0) + serial = 1; +-#ifdef TODO + if (grub_memcmp (ptr, "hercules", sizeof ("hercules") - 1) == 0) + hercules = 1; +-#endif + while (*ptr && !grub_isspace (*ptr)) + ptr++; + while (*ptr && grub_isspace (*ptr)) +@@ -561,7 +559,7 @@ grub_legacy_parse (const char *buf, char **entryname, char **suffix) + grub_strcpy (outptr, "serial "); + outptr += grub_strlen (outptr); + } +- if (console) ++ if (console || hercules) + { + grub_strcpy (outptr, "console "); + outptr += grub_strlen (outptr); +@@ -578,6 +576,11 @@ grub_legacy_parse (const char *buf, char **entryname, char **suffix) + grub_strcpy (outptr, "console "); + outptr += grub_strlen (outptr); + } ++ if (hercules) ++ { ++ grub_strcpy (outptr, "mda_text "); ++ outptr += grub_strlen (outptr); ++ } + grub_strcpy (outptr, "; "); + outptr += grub_strlen (outptr); + if (serial) +diff --git a/grub-core/term/i386/pc/console.c b/grub-core/term/i386/pc/console.c +index 7cf5ffc..a681435 100644 +--- a/grub-core/term/i386/pc/console.c ++++ b/grub-core/term/i386/pc/console.c +@@ -22,6 +22,8 @@ + #include + #include + ++static grub_uint8_t grub_console_cur_color = 0x7; ++ + static void + int10_9 (grub_uint8_t ch, grub_uint16_t n) + { +@@ -250,6 +252,31 @@ grub_console_getkeystatus (struct grub_term_input *term __attribute__ ((unused)) + return bios_data_area->keyboard_flag_lower & ~0x80; + } + ++static grub_uint16_t ++grub_console_getwh (struct grub_term_output *term __attribute__ ((unused))) ++{ ++ return (80 << 8) | 25; ++} ++ ++static void ++grub_console_setcolorstate (struct grub_term_output *term, ++ grub_term_color_state state) ++{ ++ switch (state) { ++ case GRUB_TERM_COLOR_STANDARD: ++ grub_console_cur_color = GRUB_TERM_DEFAULT_STANDARD_COLOR & 0x7f; ++ break; ++ case GRUB_TERM_COLOR_NORMAL: ++ grub_console_cur_color = term->normal_color & 0x7f; ++ break; ++ case GRUB_TERM_COLOR_HIGHLIGHT: ++ grub_console_cur_color = term->highlight_color & 0x7f; ++ break; ++ default: ++ break; ++ } ++} ++ + static struct grub_term_input grub_console_term_input = + { + .name = "console", +diff --git a/grub-core/term/i386/pc/vga_text.c b/grub-core/term/i386/pc/vga_text.c +index c934c68..d1e4ef9 100644 +--- a/grub-core/term/i386/pc/vga_text.c ++++ b/grub-core/term/i386/pc/vga_text.c +@@ -17,10 +17,17 @@ + */ + + #include +-#include + #include + #include + #include ++#include ++ ++/* MODESET is used for testing to force monochrome or colour mode. ++ You shouldn't use mda_text on vga. ++ */ ++#ifdef MODESET ++#include ++#endif + + #if defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_QEMU) || defined (GRUB_MACHINE_MIPS_QEMU_MIPS) || defined (GRUB_MACHINE_MULTIBOOT) + #include +@@ -35,10 +42,21 @@ static int grub_curr_x, grub_curr_y; + + #ifdef __mips__ + #define VGA_TEXT_SCREEN ((grub_uint16_t *) 0xb00b8000) ++#define cr_read grub_vga_cr_read ++#define cr_write grub_vga_cr_write ++#elif defined (MODE_MDA) ++#define VGA_TEXT_SCREEN ((grub_uint16_t *) 0xb0000) ++#define cr_read grub_vga_cr_bw_read ++#define cr_write grub_vga_cr_bw_write ++static grub_uint8_t cur_color; + #else + #define VGA_TEXT_SCREEN ((grub_uint16_t *) 0xb8000) ++#define cr_read grub_vga_cr_read ++#define cr_write grub_vga_cr_write + #endif + ++static grub_uint8_t cur_color = 0x7; ++ + static void + screen_write_char (int x, int y, short c) + { +@@ -55,8 +73,8 @@ static void + update_cursor (void) + { + unsigned int pos = grub_curr_y * COLS + grub_curr_x; +- grub_vga_cr_write (pos >> 8, GRUB_VGA_CR_CURSOR_ADDR_HIGH); +- grub_vga_cr_write (pos & 0xFF, GRUB_VGA_CR_CURSOR_ADDR_LOW); ++ cr_write (pos >> 8, GRUB_VGA_CR_CURSOR_ADDR_HIGH); ++ cr_write (pos & 0xFF, GRUB_VGA_CR_CURSOR_ADDR_LOW); + } + + static void +@@ -72,7 +90,7 @@ inc_y (void) + for (x = 0; x < COLS; x++) + screen_write_char (x, y, screen_read_char (x, y + 1)); + for (x = 0; x < COLS; x++) +- screen_write_char (x, ROWS - 1, ' ' | (grub_console_cur_color << 8)); ++ screen_write_char (x, ROWS - 1, ' ' | (cur_color << 8)); + } + } + +@@ -103,7 +121,7 @@ grub_vga_text_putchar (struct grub_term_output *term __attribute__ ((unused)), + break; + default: + screen_write_char (grub_curr_x, grub_curr_y, +- c->base | (grub_console_cur_color << 8)); ++ c->base | (cur_color << 8)); + inc_x (); + } + +@@ -130,7 +148,7 @@ grub_vga_text_cls (struct grub_term_output *term) + { + int i; + for (i = 0; i < ROWS * COLS; i++) +- VGA_TEXT_SCREEN[i] = grub_cpu_to_le16 (' ' | (grub_console_cur_color << 8)); ++ VGA_TEXT_SCREEN[i] = grub_cpu_to_le16 (' ' | (cur_color << 8)); + grub_vga_text_gotoxy (term, 0, 0); + } + +@@ -139,49 +157,136 @@ grub_vga_text_setcursor (struct grub_term_output *term __attribute__ ((unused)), + int on) + { + grub_uint8_t old; +- old = grub_vga_cr_read (GRUB_VGA_CR_CURSOR_START); ++ old = cr_read (GRUB_VGA_CR_CURSOR_START); + if (on) +- grub_vga_cr_write (old & ~GRUB_VGA_CR_CURSOR_START_DISABLE, +- GRUB_VGA_CR_CURSOR_START); ++ cr_write (old & ~GRUB_VGA_CR_CURSOR_START_DISABLE, ++ GRUB_VGA_CR_CURSOR_START); + else +- grub_vga_cr_write (old | GRUB_VGA_CR_CURSOR_START_DISABLE, +- GRUB_VGA_CR_CURSOR_START); ++ cr_write (old | GRUB_VGA_CR_CURSOR_START_DISABLE, ++ GRUB_VGA_CR_CURSOR_START); + } + + static grub_err_t +-grub_vga_text_init_fini (struct grub_term_output *term) ++grub_vga_text_init (struct grub_term_output *term) + { ++#ifdef MODESET ++ struct grub_bios_int_registers regs; ++ regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; ++ ++#ifdef MODE_MDA ++ regs.eax = 7; ++#else ++ regs.eax = 3; ++#endif ++ regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; ++ grub_bios_interrupt (0x10, ®s); ++#endif + grub_vga_text_cls (term); + return 0; + } + ++static grub_err_t ++grub_vga_text_fini (struct grub_term_output *term) ++{ ++#ifdef MODESET ++ struct grub_bios_int_registers regs; ++ regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; ++ ++ regs.eax = 3; ++ regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; ++ grub_bios_interrupt (0x10, ®s); ++#endif ++ grub_vga_text_cls (term); ++ return 0; ++} ++ ++static grub_uint16_t ++grub_vga_text_getwh (struct grub_term_output *term __attribute__ ((unused))) ++{ ++ return (80 << 8) | 25; ++} ++ ++#ifndef MODE_MDA ++ ++static void ++grub_vga_text_setcolorstate (struct grub_term_output *term, ++ grub_term_color_state state) ++{ ++ switch (state) { ++ case GRUB_TERM_COLOR_STANDARD: ++ cur_color = GRUB_TERM_DEFAULT_STANDARD_COLOR & 0x7f; ++ break; ++ case GRUB_TERM_COLOR_NORMAL: ++ cur_color = term->normal_color & 0x7f; ++ break; ++ case GRUB_TERM_COLOR_HIGHLIGHT: ++ cur_color = term->highlight_color & 0x7f; ++ break; ++ default: ++ break; ++ } ++} ++ ++#else ++static void ++grub_vga_text_setcolorstate (struct grub_term_output *term __attribute__ ((unused)), ++ grub_term_color_state state) ++{ ++ switch (state) { ++ case GRUB_TERM_COLOR_STANDARD: ++ cur_color = 0x07; ++ break; ++ case GRUB_TERM_COLOR_NORMAL: ++ cur_color = 0x07; ++ break; ++ case GRUB_TERM_COLOR_HIGHLIGHT: ++ cur_color = 0x70; ++ break; ++ default: ++ break; ++ } ++} ++#endif ++ + static struct grub_term_output grub_vga_text_term = + { ++#ifdef MODE_MDA ++ .name = "mda_text", ++#else + .name = "vga_text", +- .init = grub_vga_text_init_fini, +- .fini = grub_vga_text_init_fini, ++#endif ++ .init = grub_vga_text_init, ++ .fini = grub_vga_text_fini, + .putchar = grub_vga_text_putchar, +- .getwh = grub_console_getwh, ++ .getwh = grub_vga_text_getwh, + .getxy = grub_vga_text_getxy, + .gotoxy = grub_vga_text_gotoxy, + .cls = grub_vga_text_cls, +- .setcolorstate = grub_console_setcolorstate, ++ .setcolorstate = grub_vga_text_setcolorstate, + .setcursor = grub_vga_text_setcursor, + .flags = GRUB_TERM_CODE_TYPE_CP437, + .normal_color = GRUB_TERM_DEFAULT_NORMAL_COLOR, + .highlight_color = GRUB_TERM_DEFAULT_HIGHLIGHT_COLOR, + }; + +-#if defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_QEMU) || defined (GRUB_MACHINE_MIPS_QEMU_MIPS) || defined (GRUB_MACHINE_MULTIBOOT) ++#ifdef MODE_MDA ++GRUB_MOD_INIT(mda_text) ++#elif defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_QEMU) || defined (GRUB_MACHINE_MIPS_QEMU_MIPS) || defined (GRUB_MACHINE_MULTIBOOT) + void grub_vga_text_init (void) + #else + GRUB_MOD_INIT(vga_text) + #endif + { ++#ifdef MODE_MDA ++ grub_term_register_output ("mda_text", &grub_vga_text_term); ++#else + grub_term_register_output ("vga_text", &grub_vga_text_term); ++#endif + } + +-#if defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_QEMU) || defined (GRUB_MACHINE_MIPS_QEMU_MIPS) || defined (GRUB_MACHINE_MULTIBOOT) ++#ifdef MODE_MDA ++GRUB_MOD_FINI(mda_text) ++#elif defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_QEMU) || defined (GRUB_MACHINE_MIPS_QEMU_MIPS) || defined (GRUB_MACHINE_MULTIBOOT) + void grub_vga_text_fini (void) + #else + GRUB_MOD_FINI(vga_text) +diff --git a/grub-core/term/i386/vga_common.c b/grub-core/term/i386/vga_common.c +deleted file mode 100644 +index 0c21769..0000000 +--- a/grub-core/term/i386/vga_common.c ++++ /dev/null +@@ -1,48 +0,0 @@ +-/* +- * GRUB -- GRand Unified Bootloader +- * Copyright (C) 2002,2003,2005,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 . +- */ +- +-#include +-#include +-#include +- +-grub_uint8_t grub_console_cur_color = 0x7; +- +-grub_uint16_t +-grub_console_getwh (struct grub_term_output *term __attribute__ ((unused))) +-{ +- return (80 << 8) | 25; +-} +- +-void +-grub_console_setcolorstate (struct grub_term_output *term, +- grub_term_color_state state) +-{ +- switch (state) { +- case GRUB_TERM_COLOR_STANDARD: +- grub_console_cur_color = GRUB_TERM_DEFAULT_STANDARD_COLOR & 0x7f; +- break; +- case GRUB_TERM_COLOR_NORMAL: +- grub_console_cur_color = term->normal_color & 0x7f; +- break; +- case GRUB_TERM_COLOR_HIGHLIGHT: +- grub_console_cur_color = term->highlight_color & 0x7f; +- break; +- default: +- break; +- } +-} +diff --git a/include/grub/i386/pc/console.h b/include/grub/i386/pc/console.h +index f752b9a..191964f 100644 +--- a/include/grub/i386/pc/console.h ++++ b/include/grub/i386/pc/console.h +@@ -24,7 +24,6 @@ + #include + #include + #include +-#include + + /* Initialize the console system. */ + void grub_console_init (void); +diff --git a/include/grub/i386/vga_common.h b/include/grub/i386/vga_common.h +deleted file mode 100644 +index 8727903..0000000 +--- a/include/grub/i386/vga_common.h ++++ /dev/null +@@ -1,32 +0,0 @@ +-/* +- * GRUB -- GRand Unified Bootloader +- * Copyright (C) 2002,2005,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_VGA_COMMON_CPU_HEADER +-#define GRUB_VGA_COMMON_CPU_HEADER 1 +- +-#include +-#include +-#include +- +-extern grub_uint8_t grub_console_cur_color; +- +-grub_uint16_t grub_console_getwh (struct grub_term_output *term); +-void grub_console_setcolorstate (struct grub_term_output *term, +- grub_term_color_state state); +- +-#endif /* ! GRUB_VGA_COMMON_CPU_HEADER */ +diff --git a/include/grub/vga.h b/include/grub/vga.h +index 81d40a1..1d8449c 100644 +--- a/include/grub/vga.h ++++ b/include/grub/vga.h +@@ -57,6 +57,20 @@ grub_vga_cr_read (grub_uint8_t addr) + } + + static inline void ++grub_vga_cr_bw_write (grub_uint8_t val, grub_uint8_t addr) ++{ ++ grub_outb (addr, GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_CR_BW_INDEX); ++ grub_outb (val, GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_CR_BW_DATA); ++} ++ ++static inline grub_uint8_t ++grub_vga_cr_bw_read (grub_uint8_t addr) ++{ ++ grub_outb (addr, GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_CR_BW_INDEX); ++ return grub_inb (GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_CR_BW_DATA); ++} ++ ++static inline void + grub_vga_sr_write (grub_uint8_t val, grub_uint8_t addr) + { + grub_outb (addr, GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_SR_INDEX); +diff --git a/include/grub/vgaregs.h b/include/grub/vgaregs.h +index a7b13ee..1a666a1 100644 +--- a/include/grub/vgaregs.h ++++ b/include/grub/vgaregs.h +@@ -26,6 +26,8 @@ + + enum + { ++ GRUB_VGA_IO_CR_BW_INDEX = 0x3b4, ++ GRUB_VGA_IO_CR_BW_DATA = 0x3b5, + GRUB_VGA_IO_ARX = 0x3c0, + GRUB_VGA_IO_ARX_READ = 0x3c1, + GRUB_VGA_IO_MISC_WRITE = 0x3c2, +-- +1.8.1.4 + diff --git a/0002-missing-file-from-last-commit.patch b/0002-missing-file-from-last-commit.patch new file mode 100644 index 0000000..0bda2fa --- /dev/null +++ b/0002-missing-file-from-last-commit.patch @@ -0,0 +1,22 @@ +From d72015266eb5f1cf712db5edec3aa6926447f668 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Thu, 28 Jun 2012 15:36:48 +0200 +Subject: [PATCH 002/364] missing file from last commit + +--- + grub-core/term/i386/pc/mda_text.c | 3 +++ + 1 file changed, 3 insertions(+) + create mode 100644 grub-core/term/i386/pc/mda_text.c + +diff --git a/grub-core/term/i386/pc/mda_text.c b/grub-core/term/i386/pc/mda_text.c +new file mode 100644 +index 0000000..907a36e +--- /dev/null ++++ b/grub-core/term/i386/pc/mda_text.c +@@ -0,0 +1,3 @@ ++#define MODE_MDA 1 ++#include "vga_text.c" ++ +-- +1.8.1.4 + diff --git a/0003-grub-core-loader-i386-linux.c-find_efi_mmap_size-Don.patch b/0003-grub-core-loader-i386-linux.c-find_efi_mmap_size-Don.patch new file mode 100644 index 0000000..e104d33 --- /dev/null +++ b/0003-grub-core-loader-i386-linux.c-find_efi_mmap_size-Don.patch @@ -0,0 +1,58 @@ +From ec6a8c449294b215a2c4019f42110a0c1f770ac2 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Mon, 2 Jul 2012 11:14:37 +0200 +Subject: [PATCH 003/364] * grub-core/loader/i386/linux.c + (find_efi_mmap_size): Don't decrease efi_mmap_size. Reported by: Stuart + Hayes. + +--- + ChangeLog | 6 ++++++ + grub-core/loader/i386/linux.c | 7 +++++-- + 2 files changed, 11 insertions(+), 2 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index f6e864a..53ad372 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,9 @@ ++2012-07-02 Vladimir Serbinenko ++ ++ * grub-core/loader/i386/linux.c (find_efi_mmap_size): Don't decrease ++ efi_mmap_size. ++ Reported by: Stuart Hayes. ++ + 2012-06-28 Vladimir Serbinenko + + Add monochrome text support (mda_text, aka `hercules' in grub-legacy). +diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c +index 62087cf..d34b2f8 100644 +--- a/grub-core/loader/i386/linux.c ++++ b/grub-core/loader/i386/linux.c +@@ -118,12 +118,13 @@ find_efi_mmap_size (void) + int ret; + grub_efi_memory_descriptor_t *mmap; + grub_efi_uintn_t desc_size; ++ grub_efi_uintn_t cur_mmap_size = mmap_size; + +- mmap = grub_malloc (mmap_size); ++ mmap = grub_malloc (cur_mmap_size); + if (! mmap) + return 0; + +- ret = grub_efi_get_memory_map (&mmap_size, mmap, 0, &desc_size, 0); ++ ret = grub_efi_get_memory_map (&cur_mmap_size, mmap, 0, &desc_size, 0); + grub_free (mmap); + + if (ret < 0) +@@ -134,6 +135,8 @@ find_efi_mmap_size (void) + else if (ret > 0) + break; + ++ if (mmap_size < cur_mmap_size) ++ mmap_size = cur_mmap_size; + mmap_size += (1 << 12); + } + +-- +1.8.1.4 + diff --git a/0004-include-grub-list.h-FOR_LIST_ELEMENTS_SAFE-New-macro.patch b/0004-include-grub-list.h-FOR_LIST_ELEMENTS_SAFE-New-macro.patch new file mode 100644 index 0000000..5ef4a74 --- /dev/null +++ b/0004-include-grub-list.h-FOR_LIST_ELEMENTS_SAFE-New-macro.patch @@ -0,0 +1,61 @@ +From d2ccb3209c62de4292107df4207c02ee59dc11a9 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Mon, 2 Jul 2012 11:19:22 +0200 +Subject: [PATCH 004/364] * include/grub/list.h + (FOR_LIST_ELEMENTS_SAFE): New macro. * include/grub/command.h + (FOR_COMMANDS_SAFE): Likewise. * grub-core/commands/help.c + (grub_cmd_help): Use FOR_COMMANDS_SAFE. + +--- + grub-core/commands/help.c | 5 +++-- + include/grub/command.h | 1 + + include/grub/list.h | 1 + + 3 files changed, 5 insertions(+), 2 deletions(-) + +diff --git a/grub-core/commands/help.c b/grub-core/commands/help.c +index d64c289..f0be89b 100644 +--- a/grub-core/commands/help.c ++++ b/grub-core/commands/help.c +@@ -99,12 +99,13 @@ grub_cmd_help (grub_extcmd_context_t ctxt __attribute__ ((unused)), int argc, + else + { + int i; +- grub_command_t cmd_iter, cmd; ++ grub_command_t cmd_iter, cmd, cmd_next; + + for (i = 0; i < argc; i++) + { + currarg = args[i]; +- FOR_COMMANDS(cmd_iter) ++ ++ FOR_COMMANDS_SAFE (cmd_iter, cmd_next) + { + if (!(cmd_iter->prio & GRUB_COMMAND_FLAG_ACTIVE)) + continue; +diff --git a/include/grub/command.h b/include/grub/command.h +index 6d43499..8705a63 100644 +--- a/include/grub/command.h ++++ b/include/grub/command.h +@@ -121,6 +121,7 @@ grub_command_execute (const char *name, int argc, char **argv) + } + + #define FOR_COMMANDS(var) FOR_LIST_ELEMENTS((var), grub_command_list) ++#define FOR_COMMANDS_SAFE(var, next) FOR_LIST_ELEMENTS_SAFE((var), (next), grub_command_list) + + void grub_register_core_commands (void); + +diff --git a/include/grub/list.h b/include/grub/list.h +index cadb2d9..6f6dec0 100644 +--- a/include/grub/list.h ++++ b/include/grub/list.h +@@ -35,6 +35,7 @@ void EXPORT_FUNC(grub_list_push) (grub_list_t *head, grub_list_t item); + void EXPORT_FUNC(grub_list_remove) (grub_list_t item); + + #define FOR_LIST_ELEMENTS(var, list) for ((var) = (list); (var); (var) = (var)->next) ++#define FOR_LIST_ELEMENTS_SAFE(var, nxt, list) for ((var) = (list), (nxt) = ((var) ? (var)->next : 0); (var); (var) = (nxt), (nxt) = (var)->next) + + static inline void * + grub_bad_type_cast_real (int line, const char *file) +-- +1.8.1.4 + diff --git a/0005-gentpl.py-Make-mans-depend-on-grub-mkconfig_lib.patch b/0005-gentpl.py-Make-mans-depend-on-grub-mkconfig_lib.patch new file mode 100644 index 0000000..0265d2f --- /dev/null +++ b/0005-gentpl.py-Make-mans-depend-on-grub-mkconfig_lib.patch @@ -0,0 +1,47 @@ +From 21c2f856cbdf4a98d015ed05bb6b9b16c021af9c Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Mon, 2 Jul 2012 11:20:51 +0200 +Subject: [PATCH 005/364] * gentpl.py: Make mans depend on + grub-mkconfig_lib. + +--- + ChangeLog | 10 ++++++++++ + gentpl.py | 2 +- + 2 files changed, 11 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index 53ad372..aaeeb05 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,15 @@ + 2012-07-02 Vladimir Serbinenko + ++ * gentpl.py: Make mans depend on grub-mkconfig_lib. ++ ++2012-07-02 Vladimir Serbinenko ++ ++ * include/grub/list.h (FOR_LIST_ELEMENTS_SAFE): New macro. ++ * include/grub/command.h (FOR_COMMANDS_SAFE): Likewise. ++ * grub-core/commands/help.c (grub_cmd_help): Use FOR_COMMANDS_SAFE. ++ ++2012-07-02 Vladimir Serbinenko ++ + * grub-core/loader/i386/linux.c (find_efi_mmap_size): Don't decrease + efi_mmap_size. + Reported by: Stuart Hayes. +diff --git a/gentpl.py b/gentpl.py +index 13a6081..bab4a8a 100644 +--- a/gentpl.py ++++ b/gentpl.py +@@ -487,7 +487,7 @@ def installdir(default="bin"): + def manpage(): + r = "if COND_MAN_PAGES\n" + r += gvar_add("man_MANS", "[+ name +].[+ mansection +]\n") +- r += rule("[+ name +].[+ mansection +]", "[+ name +]", """ ++ r += rule("[+ name +].[+ mansection +]", "[+ name +] grub-mkconfig_lib", """ + chmod a+x [+ name +] + PATH=$(builddir):$$PATH pkgdatadir=$(builddir) $(HELP2MAN) --section=[+ mansection +] -i $(top_srcdir)/docs/man/[+ name +].h2m -o $@ [+ name +] + """) +-- +1.8.1.4 + diff --git a/0006-grub-core-net-tftp.c-ack-Fix-endianness-problem.patch b/0006-grub-core-net-tftp.c-ack-Fix-endianness-problem.patch new file mode 100644 index 0000000..07c6612 --- /dev/null +++ b/0006-grub-core-net-tftp.c-ack-Fix-endianness-problem.patch @@ -0,0 +1,53 @@ +From 8ec34c46a3cc4cacce65e3a2a671e08548c6a95e Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Mon, 2 Jul 2012 11:22:50 +0200 +Subject: [PATCH 006/364] * grub-core/net/tftp.c (ack): Fix endianness + problem. (tftp_receive): Likewise. Reported by: Michael + Davidsaver. + +--- + ChangeLog | 6 ++++++ + grub-core/net/tftp.c | 4 ++-- + 2 files changed, 8 insertions(+), 2 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index aaeeb05..12de11f 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,11 @@ + 2012-07-02 Vladimir Serbinenko + ++ * grub-core/net/tftp.c (ack): Fix endianness problem. ++ (tftp_receive): Likewise. ++ Reported by: Michael Davidsaver. ++ ++2012-07-02 Vladimir Serbinenko ++ + * gentpl.py: Make mans depend on grub-mkconfig_lib. + + 2012-07-02 Vladimir Serbinenko +diff --git a/grub-core/net/tftp.c b/grub-core/net/tftp.c +index 9c70efb..d0f39ea 100644 +--- a/grub-core/net/tftp.c ++++ b/grub-core/net/tftp.c +@@ -143,7 +143,7 @@ ack (tftp_data_t data, grub_uint16_t block) + + tftph_ack = (struct tftphdr *) nb_ack.data; + tftph_ack->opcode = grub_cpu_to_be16 (TFTP_ACK); +- tftph_ack->u.ack.block = block; ++ tftph_ack->u.ack.block = grub_cpu_to_be16 (block); + + err = grub_net_send_udp_packet (data->sock, &nb_ack); + if (err) +@@ -225,7 +225,7 @@ tftp_receive (grub_net_udp_socket_t sock __attribute__ ((unused)), + grub_priority_queue_pop (data->pq); + + if (file->device->net->packs.count < 50) +- err = ack (data, tftph->u.data.block); ++ err = ack (data, data->block + 1); + else + { + file->device->net->stall = 1; +-- +1.8.1.4 + diff --git a/0007-grub-core-fs-ext2.c-Experimental-support-for-64-bit.patch b/0007-grub-core-fs-ext2.c-Experimental-support-for-64-bit.patch new file mode 100644 index 0000000..65055be --- /dev/null +++ b/0007-grub-core-fs-ext2.c-Experimental-support-for-64-bit.patch @@ -0,0 +1,182 @@ +From c545d0bb2fe87b5a8ea6a903e4e9c113595ccfff Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Mon, 2 Jul 2012 11:28:42 +0200 +Subject: [PATCH 007/364] * grub-core/fs/ext2.c: Experimental support + for 64-bit. + +--- + ChangeLog | 4 ++++ + grub-core/fs/ext2.c | 56 +++++++++++++++++++++++++++++++++++++++++------------ + 2 files changed, 48 insertions(+), 12 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 12de11f..93ad0ac 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,9 @@ + 2012-07-02 Vladimir Serbinenko + ++ * grub-core/fs/ext2.c: Experimental support for 64-bit. ++ ++2012-07-02 Vladimir Serbinenko ++ + * grub-core/net/tftp.c (ack): Fix endianness problem. + (tftp_receive): Likewise. + Reported by: Michael Davidsaver. +diff --git a/grub-core/fs/ext2.c b/grub-core/fs/ext2.c +index c50e379..bd1ab24 100644 +--- a/grub-core/fs/ext2.c ++++ b/grub-core/fs/ext2.c +@@ -65,7 +65,8 @@ GRUB_MOD_LICENSE ("GPLv3+"); + + /* The inode size. */ + #define EXT2_INODE_SIZE(data) \ +- (EXT2_REVISION (data) == EXT2_GOOD_OLD_REVISION \ ++ (data->sblock.revision_level \ ++ == grub_cpu_to_le32_compile_time (EXT2_GOOD_OLD_REVISION) \ + ? EXT2_GOOD_OLD_INODE_SIZE \ + : grub_le_to_cpu16 (data->sblock.inode_size)) + +@@ -105,7 +106,8 @@ GRUB_MOD_LICENSE ("GPLv3+"); + * flags here as the related features are implemented into the driver. */ + #define EXT2_DRIVER_SUPPORTED_INCOMPAT ( EXT2_FEATURE_INCOMPAT_FILETYPE \ + | EXT4_FEATURE_INCOMPAT_EXTENTS \ +- | EXT4_FEATURE_INCOMPAT_FLEX_BG ) ++ | EXT4_FEATURE_INCOMPAT_FLEX_BG \ ++ | EXT4_FEATURE_INCOMPAT_64BIT) + /* List of rationales for the ignored "incompatible" features: + * needs_recovery: Not really back-incompatible - was added as such to forbid + * ext2 drivers from mounting an ext3 volume with a dirty +@@ -179,7 +181,7 @@ struct grub_ext2_sblock + grub_uint32_t hash_seed[4]; + grub_uint8_t def_hash_version; + grub_uint8_t jnl_backup_type; +- grub_uint16_t reserved_word_pad; ++ grub_uint16_t group_desc_size; + grub_uint32_t default_mount_opts; + grub_uint32_t first_meta_bg; + grub_uint32_t mkfs_time; +@@ -197,6 +199,14 @@ struct grub_ext2_block_group + grub_uint16_t used_dirs; + grub_uint16_t pad; + grub_uint32_t reserved[3]; ++ grub_uint32_t block_id_hi; ++ grub_uint32_t inode_id_hi; ++ grub_uint32_t inode_table_id_hi; ++ grub_uint16_t free_blocks_hi; ++ grub_uint16_t free_inodes_hi; ++ grub_uint16_t used_dirs_hi; ++ grub_uint16_t pad2; ++ grub_uint32_t reserved2[3]; + }; + + /* The ext2 inode. */ +@@ -310,6 +320,7 @@ struct grub_fshelp_node + struct grub_ext2_data + { + struct grub_ext2_sblock sblock; ++ int log_group_desc_size; + grub_disk_t disk; + struct grub_ext2_inode *inode; + struct grub_fshelp_node diropen; +@@ -328,7 +339,7 @@ grub_ext2_blockgroup (struct grub_ext2_data *data, int group, + return grub_disk_read (data->disk, + ((grub_le_to_cpu32 (data->sblock.first_data_block) + 1) + << LOG2_EXT2_BLOCK_SIZE (data)), +- group * sizeof (struct grub_ext2_block_group), ++ group << data->log_group_desc_size, + sizeof (struct grub_ext2_block_group), blkgrp); + } + +@@ -362,7 +373,7 @@ grub_ext4_find_leaf (struct grub_ext2_data *data, grub_properly_aligned_t *buf, + return 0; + + block = grub_le_to_cpu16 (index[i].leaf_hi); +- block = (block << 32) + grub_le_to_cpu32 (index[i].leaf); ++ block = (block << 32) | grub_le_to_cpu32 (index[i].leaf); + if (grub_disk_read (data->disk, + block << LOG2_EXT2_BLOCK_SIZE (data), + 0, EXT2_BLOCK_SIZE(data), buf)) +@@ -377,11 +388,11 @@ grub_ext2_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) + { + struct grub_ext2_data *data = node->data; + struct grub_ext2_inode *inode = &node->inode; +- int blknr = -1; ++ grub_disk_addr_t blknr = -1; + unsigned int blksz = EXT2_BLOCK_SIZE (data); + int log2_blksz = LOG2_EXT2_BLOCK_SIZE (data); + +- if (grub_le_to_cpu32(inode->flags) & EXT4_EXTENTS_FLAG) ++ if (inode->flags & grub_cpu_to_le32_compile_time (EXT4_EXTENTS_FLAG)) + { + GRUB_PROPERLY_ALIGNED_ARRAY (buf, EXT2_BLOCK_SIZE(data)); + struct grub_ext4_extent_header *leaf; +@@ -535,6 +546,7 @@ grub_ext2_read_inode (struct grub_ext2_data *data, + int inodes_per_block; + unsigned int blkno; + unsigned int blkoff; ++ grub_disk_addr_t base; + + /* It is easier to calculate if the first inode is 0. */ + ino--; +@@ -551,10 +563,14 @@ grub_ext2_read_inode (struct grub_ext2_data *data, + blkoff = (ino % grub_le_to_cpu32 (sblock->inodes_per_group)) + % inodes_per_block; + ++ base = grub_le_to_cpu32 (blkgrp.inode_table_id); ++ if (data->log_group_desc_size >= 6) ++ base |= (((grub_disk_addr_t) grub_le_to_cpu32 (blkgrp.inode_table_id_hi)) ++ << 32); ++ + /* Read the inode. */ + if (grub_disk_read (data->disk, +- (((grub_disk_addr_t) grub_le_to_cpu32 (blkgrp.inode_table_id) + blkno) +- << LOG2_EXT2_BLOCK_SIZE (data)), ++ ((base + blkno) << LOG2_EXT2_BLOCK_SIZE (data)), + EXT2_INODE_SIZE (data) * blkoff, + sizeof (struct grub_ext2_inode), inode)) + return grub_errno; +@@ -578,7 +594,7 @@ grub_ext2_mount (grub_disk_t disk) + goto fail; + + /* Make sure this is an ext2 filesystem. */ +- if (grub_le_to_cpu16 (data->sblock.magic) != EXT2_MAGIC ++ if (data->sblock.magic != grub_cpu_to_le16_compile_time (EXT2_MAGIC) + || grub_le_to_cpu32 (data->sblock.log2_block_size) >= 16) + { + grub_error (GRUB_ERR_BAD_FS, "not an ext2 filesystem"); +@@ -586,13 +602,29 @@ grub_ext2_mount (grub_disk_t disk) + } + + /* Check the FS doesn't have feature bits enabled that we don't support. */ +- if (grub_le_to_cpu32 (data->sblock.feature_incompat) +- & ~(EXT2_DRIVER_SUPPORTED_INCOMPAT | EXT2_DRIVER_IGNORED_INCOMPAT)) ++ if (data->sblock.revision_level != grub_cpu_to_le32_compile_time (EXT2_GOOD_OLD_REVISION) ++ && (data->sblock.feature_incompat ++ & grub_cpu_to_le32_compile_time (~(EXT2_DRIVER_SUPPORTED_INCOMPAT ++ | EXT2_DRIVER_IGNORED_INCOMPAT)))) + { + grub_error (GRUB_ERR_BAD_FS, "filesystem has unsupported incompatible features"); + goto fail; + } + ++ if (data->sblock.revision_level != grub_cpu_to_le32_compile_time (EXT2_GOOD_OLD_REVISION) ++ && (data->sblock.feature_incompat ++ & grub_cpu_to_le32_compile_time (EXT4_FEATURE_INCOMPAT_64BIT)) ++ && data->sblock.group_desc_size != 0 ++ && ((data->sblock.group_desc_size & (data->sblock.group_desc_size - 1)) ++ == 0) ++ && (data->sblock.group_desc_size & grub_cpu_to_le16_compile_time (0x1fe0))) ++ { ++ grub_uint16_t b = grub_le_to_cpu16 (data->sblock.group_desc_size); ++ for (data->log_group_desc_size = 0; b != (1 << data->log_group_desc_size); ++ data->log_group_desc_size++); ++ } ++ else ++ data->log_group_desc_size = 5; + + data->disk = disk; + +-- +1.8.1.4 + diff --git a/0008-grub-core-term-efi-serial.c-Support-1.5-stop-bits.patch b/0008-grub-core-term-efi-serial.c-Support-1.5-stop-bits.patch new file mode 100644 index 0000000..1043813 --- /dev/null +++ b/0008-grub-core-term-efi-serial.c-Support-1.5-stop-bits.patch @@ -0,0 +1,48 @@ +From 2cce795e46cef6c5f057d46bae9a845621ca4a95 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Mon, 2 Jul 2012 11:30:04 +0200 +Subject: [PATCH 008/364] * grub-core/term/efi/serial.c: Support 1.5 + stop bits. + +--- + ChangeLog | 4 ++++ + grub-core/term/efi/serial.c | 2 ++ + 2 files changed, 6 insertions(+) + +diff --git a/ChangeLog b/ChangeLog +index 93ad0ac..5f73c88 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,9 @@ + 2012-07-02 Vladimir Serbinenko + ++ * grub-core/term/efi/serial.c: Support 1.5 stop bits. ++ ++2012-07-02 Vladimir Serbinenko ++ + * grub-core/fs/ext2.c: Experimental support for 64-bit. + + 2012-07-02 Vladimir Serbinenko +diff --git a/grub-core/term/efi/serial.c b/grub-core/term/efi/serial.c +index da8c3ce..dc5f33b 100644 +--- a/grub-core/term/efi/serial.c ++++ b/grub-core/term/efi/serial.c +@@ -44,6 +44,7 @@ do_real_config (struct grub_serial_port *port) + }; + const grub_efi_stop_bits_t stop_bits[] = { + [GRUB_SERIAL_STOP_BITS_1] = GRUB_EFI_SERIAL_1_STOP_BIT, ++ [GRUB_SERIAL_STOP_BITS_1_5] = GRUB_EFI_SERIAL_1_5_STOP_BITS, + [GRUB_SERIAL_STOP_BITS_2] = GRUB_EFI_SERIAL_2_STOP_BITS, + }; + +@@ -111,6 +112,7 @@ serial_hw_configure (struct grub_serial_port *port, + N_("unsupported serial port parity")); + + if (config->stop_bits != GRUB_SERIAL_STOP_BITS_1 ++ && config->stop_bits != GRUB_SERIAL_STOP_BITS_1_5 + && config->stop_bits != GRUB_SERIAL_STOP_BITS_2) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + N_("unsupported serial port stop bits number")); +-- +1.8.1.4 + diff --git a/0009-grub-core-lib-legacy_parse.c-Support-clear-and-testl.patch b/0009-grub-core-lib-legacy_parse.c-Support-clear-and-testl.patch new file mode 100644 index 0000000..6c82c91 --- /dev/null +++ b/0009-grub-core-lib-legacy_parse.c-Support-clear-and-testl.patch @@ -0,0 +1,107 @@ +From 134e4df1335b0498684d093b55332f87c2e8a301 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Mon, 2 Jul 2012 11:31:31 +0200 +Subject: [PATCH 009/364] * grub-core/lib/legacy_parse.c: Support clear + and testload. + +--- + ChangeLog | 4 ++++ + grub-core/lib/legacy_parse.c | 14 +++++++++++++- + 2 files changed, 17 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index 5f73c88..e606116 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,9 @@ + 2012-07-02 Vladimir Serbinenko + ++ * grub-core/lib/legacy_parse.c: Support clear and testload. ++ ++2012-07-02 Vladimir Serbinenko ++ + * grub-core/term/efi/serial.c: Support 1.5 stop bits. + + 2012-07-02 Vladimir Serbinenko +diff --git a/grub-core/lib/legacy_parse.c b/grub-core/lib/legacy_parse.c +index 14768b8..ddfaec4 100644 +--- a/grub-core/lib/legacy_parse.c ++++ b/grub-core/lib/legacy_parse.c +@@ -65,6 +65,7 @@ struct legacy_command + */ + static struct legacy_command legacy_commands[] = + { ++ /* FIXME: background unsupported. */ + {"blocklist", "blocklist '%s'\n", NULL, 0, 1, {TYPE_FILE}, 0, "FILE", + "Print the blocklist notation of the file FILE."}, + {"boot", "boot\n", NULL, 0, 0, {}, 0, 0, +@@ -82,6 +83,8 @@ static struct legacy_command legacy_commands[] = + 2, {TYPE_FORCE_OPTION, TYPE_FILE}, 0, "[--force] FILE", + "Load the chain-loader FILE. If --force is specified, then load it" + " forcibly, whether the boot loader signature is present or not."}, ++ {"clear", "clear\n", NULL, 0, 0, {}, 0, 0, ++ "Clear the screen."}, + {"cmp", "cmp '%s' '%s'\n", NULL, 0, + 2, {TYPE_FILE, TYPE_FILE}, FLAG_IGNORE_REST, "FILE1 FILE2", + "Compare the file FILE1 with the FILE2 and inform the different values" +@@ -125,6 +128,7 @@ static struct legacy_command legacy_commands[] = + {"displaymem", "lsmmap\n", NULL, 0, 0, {}, 0, 0, + "Display what GRUB thinks the system address space map of the" + " machine is, including all regions of physical RAM installed."}, ++ /* FIXME: device and efimap unsupported. */ + /* NOTE: embed unsupported. */ + {"fallback", "set fallback='%s'\n", NULL, 0, + 1, {TYPE_VERBATIM}, 0, "NUM...", +@@ -136,6 +140,8 @@ static struct legacy_command legacy_commands[] = + {"find", "search -f '%s'\n", NULL, 0, 1, {TYPE_FILE}, 0, "FILENAME", + "Search for the filename FILENAME in all of partitions and print the list of" + " the devices which contain the file."}, ++ /* FIXME: findiso unsupported. */ ++ /* FIXME: foreground unsupported. */ + /* FIXME: fstest unsupported. */ + /* NOTE: The obsolete C/H/S geometry isn't shown anymore. */ + {"geometry", "insmod regexp; ls -l (%s*)\n", NULL, 0, 1, {TYPE_VERBATIM}, 0, "DRIVE", +@@ -243,6 +249,7 @@ static struct legacy_command legacy_commands[] = + {"pause", "echo %s; if ! sleep -i 60; then return; fi\n", NULL, 0, 1, + {TYPE_REST_VERBATIM}, 0, + "[MESSAGE ...]", "Print MESSAGE, then wait until a key is pressed."}, ++ /* FIXME: quit unsupported. */ + /* FIXME: rarp unsupported. */ + {"read", "read_dword %s\n", NULL, 0, 1, {TYPE_INT}, 0, "ADDR", + "Read a 32-bit value from memory at address ADDR and" +@@ -288,11 +295,14 @@ static struct legacy_command legacy_commands[] = + " STOP is the length of stop bit(s). The option --device can be used only" + " in the grub shell, which specifies the file name of a tty device. The" + " default values are COM1, 9600, 8N1."}, ++ /* FIXME: silent unsupported. */ ++ /* FIXME: splashimage unsupported. */ + /* FIXME: setkey unsupported. */ /* NUL_TERMINATE */ + /* NOTE: setup unsupported. */ + /* FIXME: --no-echo, --no-edit unsupported. */ + /* NOTE: both terminals are activated so --silent and --timeout + are useless. */ ++ /* FIXME: graphics unsupported. */ + {"terminal", NULL, NULL, 0, 0, {}, FLAG_TERMINAL | FLAG_IGNORE_REST, + "[--dumb] [--no-echo] [--no-edit] [--timeout=SECS] [--lines=LINES] " + "[--silent] [console] [serial] [hercules]", +@@ -307,7 +317,7 @@ static struct legacy_command legacy_commands[] = + " seconds. The option --lines specifies the maximum number of lines." + " The option --silent is used to suppress messages."}, + /* FIXME: terminfo unsupported. */ /* NUL_TERMINATE */ +- {"testload", "cat '%s'\n", NULL, 0, 1, {TYPE_FILE}, 0, "FILE", ++ {"testload", "testload '%s'\n", NULL, 0, 1, {TYPE_FILE}, 0, "FILE", + "Read the entire contents of FILE in several different ways and" + " compares them, to test the filesystem code. " + " If this test succeeds, then a good next" +@@ -334,6 +344,8 @@ static struct legacy_command legacy_commands[] = + " the information about only the mode."}, + {"vbeprobe", "insmod vbe; videoinfo\n", NULL, 0, 0, {}, + FLAG_FALLBACK, NULL, NULL} ++ /* FIXME: verbose unsupported. */ ++ /* FIXME: version unsupported. */ + }; + + char * +-- +1.8.1.4 + diff --git a/0010-grub-core-Makefile.am-Fix-path-to-boot-i386-pc-start.patch b/0010-grub-core-Makefile.am-Fix-path-to-boot-i386-pc-start.patch new file mode 100644 index 0000000..a00745e --- /dev/null +++ b/0010-grub-core-Makefile.am-Fix-path-to-boot-i386-pc-start.patch @@ -0,0 +1,39 @@ +From f1c2b05162cc583ec64ae0b3cdf5ef128d2ca05c Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sat, 7 Jul 2012 14:29:01 +0200 +Subject: [PATCH 010/364] * grub-core/Makefile.am: Fix path to + boot/i386/pc/startup_raw.S. + +--- + ChangeLog | 4 ++++ + grub-core/Makefile.am | 2 +- + 2 files changed, 5 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index e606116..5e54eda 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,7 @@ ++2012-07-07 Vladimir Serbinenko ++ ++ * grub-core/Makefile.am: Fix path to boot/i386/pc/startup_raw.S. ++ + 2012-07-02 Vladimir Serbinenko + + * grub-core/lib/legacy_parse.c: Support clear and testload. +diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am +index 7dc2519..cc4fb68 100644 +--- a/grub-core/Makefile.am ++++ b/grub-core/Makefile.am +@@ -63,7 +63,7 @@ grub_script.yy.c: grub_script.yy.h + rs_decoder.S: $(srcdir)/lib/reed_solomon.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) -Os -I$(top_builddir) -S -DSTANDALONE -o $@ $< -g0 -mregparm=3 -ffreestanding + +-kern/i386/pc/startup.S: $(builddir)/rs_decoder.S ++boot/i386/pc/startup_raw.S: $(builddir)/rs_decoder.S + boot/mips/loongson/fwstart.S: $(builddir)/sm712_start.S + + CLEANFILES += grub_script.yy.c grub_script.yy.h +-- +1.8.1.4 + diff --git a/0011-Fix-coreboot-compilation.patch b/0011-Fix-coreboot-compilation.patch new file mode 100644 index 0000000..6a1d09e --- /dev/null +++ b/0011-Fix-coreboot-compilation.patch @@ -0,0 +1,67 @@ +From a7fa3c8e8c7b2dab5a704493b7965bbc60f84bed Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sun, 22 Jul 2012 16:21:24 +0200 +Subject: [PATCH 011/364] Fix coreboot compilation. + + * grub-core/term/i386/pc/vga_text.c (grub_vga_text_init): Rename to ... + (grub_vga_text_init_real): ... this. + (grub_vga_text_fini): Rename to ... + (grub_vga_text_fini_real): ... this. +--- + ChangeLog | 9 +++++++++ + grub-core/term/i386/pc/vga_text.c | 8 ++++---- + 2 files changed, 13 insertions(+), 4 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 5e54eda..35e76af 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,12 @@ ++2012-07-22 Vladimir Serbinenko ++ ++ Fix coreboot compilation. ++ ++ * grub-core/term/i386/pc/vga_text.c (grub_vga_text_init): Rename to ... ++ (grub_vga_text_init_real): ... this. ++ (grub_vga_text_fini): Rename to ... ++ (grub_vga_text_fini_real): ... this. ++ + 2012-07-07 Vladimir Serbinenko + + * grub-core/Makefile.am: Fix path to boot/i386/pc/startup_raw.S. +diff --git a/grub-core/term/i386/pc/vga_text.c b/grub-core/term/i386/pc/vga_text.c +index d1e4ef9..74c155c 100644 +--- a/grub-core/term/i386/pc/vga_text.c ++++ b/grub-core/term/i386/pc/vga_text.c +@@ -167,7 +167,7 @@ grub_vga_text_setcursor (struct grub_term_output *term __attribute__ ((unused)), + } + + static grub_err_t +-grub_vga_text_init (struct grub_term_output *term) ++grub_vga_text_init_real (struct grub_term_output *term) + { + #ifdef MODESET + struct grub_bios_int_registers regs; +@@ -186,7 +186,7 @@ grub_vga_text_init (struct grub_term_output *term) + } + + static grub_err_t +-grub_vga_text_fini (struct grub_term_output *term) ++grub_vga_text_fini_real (struct grub_term_output *term) + { + #ifdef MODESET + struct grub_bios_int_registers regs; +@@ -255,8 +255,8 @@ static struct grub_term_output grub_vga_text_term = + #else + .name = "vga_text", + #endif +- .init = grub_vga_text_init, +- .fini = grub_vga_text_fini, ++ .init = grub_vga_text_init_real, ++ .fini = grub_vga_text_fini_real, + .putchar = grub_vga_text_putchar, + .getwh = grub_vga_text_getwh, + .getxy = grub_vga_text_getxy, +-- +1.8.1.4 + diff --git a/0012-grub-core-normal-autofs.c-autoload_fs_module-Save-an.patch b/0012-grub-core-normal-autofs.c-autoload_fs_module-Save-an.patch new file mode 100644 index 0000000..9f51a10 --- /dev/null +++ b/0012-grub-core-normal-autofs.c-autoload_fs_module-Save-an.patch @@ -0,0 +1,68 @@ +From 1f75c529d5309defb33c8c216422003eee1248a5 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sun, 22 Jul 2012 16:23:46 +0200 +Subject: [PATCH 012/364] * grub-core/normal/autofs.c + (autoload_fs_module): Save and restore filter state. + +--- + ChangeLog | 5 +++++ + grub-core/normal/autofs.c | 17 +++++++++++++++-- + 2 files changed, 20 insertions(+), 2 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 35e76af..38374a3 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,10 @@ + 2012-07-22 Vladimir Serbinenko + ++ * grub-core/normal/autofs.c (autoload_fs_module): Save and restore ++ filter state. ++ ++2012-07-22 Vladimir Serbinenko ++ + Fix coreboot compilation. + + * grub-core/term/i386/pc/vga_text.c (grub_vga_text_init): Rename to ... +diff --git a/grub-core/normal/autofs.c b/grub-core/normal/autofs.c +index 0b27abf..721b9c3 100644 +--- a/grub-core/normal/autofs.c ++++ b/grub-core/normal/autofs.c +@@ -32,11 +32,21 @@ static int + autoload_fs_module (void) + { + grub_named_list_t p; ++ int ret = 0; ++ grub_file_filter_t grub_file_filters_was[GRUB_FILE_FILTER_MAX]; ++ ++ grub_memcpy (grub_file_filters_was, grub_file_filters_enabled, ++ sizeof (grub_file_filters_enabled)); ++ grub_memcpy (grub_file_filters_enabled, grub_file_filters_all, ++ sizeof (grub_file_filters_enabled)); + + while ((p = fs_module_list) != NULL) + { + if (! grub_dl_get (p->name) && grub_dl_load (p->name)) +- return 1; ++ { ++ ret = 1; ++ break; ++ } + + if (grub_errno) + grub_print_error (); +@@ -46,7 +56,10 @@ autoload_fs_module (void) + grub_free (p); + } + +- return 0; ++ grub_memcpy (grub_file_filters_enabled, grub_file_filters_was, ++ sizeof (grub_file_filters_enabled)); ++ ++ return ret; + } + + /* Read the file fs.lst for auto-loading. */ +-- +1.8.1.4 + diff --git a/0013-grub-core-lib-xzembed-xz_dec_stream.c-hash_validate-.patch b/0013-grub-core-lib-xzembed-xz_dec_stream.c-hash_validate-.patch new file mode 100644 index 0000000..6876f6c --- /dev/null +++ b/0013-grub-core-lib-xzembed-xz_dec_stream.c-hash_validate-.patch @@ -0,0 +1,73 @@ +From 4942f9b133e52828d2441309beea0e9278e8b80c Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sun, 22 Jul 2012 16:27:03 +0200 +Subject: [PATCH 013/364] * grub-core/lib/xzembed/xz_dec_stream.c + (hash_validate): Fix behaviour if hash function is unavailable. + (dec_stream_header): Likewise. + +--- + ChangeLog | 6 ++++++ + grub-core/lib/xzembed/xz_dec_stream.c | 15 ++++++++++----- + 2 files changed, 16 insertions(+), 5 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 38374a3..892d31b 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,11 @@ + 2012-07-22 Vladimir Serbinenko + ++ * grub-core/lib/xzembed/xz_dec_stream.c (hash_validate): Fix behaviour ++ if hash function is unavailable. ++ (dec_stream_header): Likewise. ++ ++2012-07-22 Vladimir Serbinenko ++ + * grub-core/normal/autofs.c (autoload_fs_module): Save and restore + filter state. + +diff --git a/grub-core/lib/xzembed/xz_dec_stream.c b/grub-core/lib/xzembed/xz_dec_stream.c +index 0d79b1f..6170b0c 100644 +--- a/grub-core/lib/xzembed/xz_dec_stream.c ++++ b/grub-core/lib/xzembed/xz_dec_stream.c +@@ -403,18 +403,25 @@ static enum xz_ret hash_validate(struct xz_dec *s, struct xz_buf *b, + } + #endif + +- do { ++ if (b->in_pos == b->in_size) ++ return XZ_OK; ++ ++ if (!crc32 && s->hash_size == 0) ++ s->pos += 8; ++ ++ while (s->pos < (crc32 ? 32 : s->hash_size * 8)) { + if (b->in_pos == b->in_size) + return XZ_OK; + + #ifndef GRUB_EMBED_DECOMPRESSOR +- if (hash && s->hash_value[s->pos / 8] != b->in[b->in_pos++]) ++ if (hash && s->hash_value[s->pos / 8] != b->in[b->in_pos]) + return XZ_DATA_ERROR; + #endif ++ b->in_pos++; + + s->pos += 8; + +- } while (s->pos < (crc32 ? 32 : s->hash_size * 8)); ++ } + + #ifndef GRUB_EMBED_DECOMPRESSOR + if (s->hash) +@@ -529,8 +536,6 @@ static enum xz_ret dec_stream_header(struct xz_dec *s) + s->hash->init(s->index.hash.hash_context); + s->hash->init(s->block.hash.hash_context); + } +- if (!s->hash) +- return XZ_OPTIONS_ERROR; + #endif + } + else +-- +1.8.1.4 + diff --git a/0014-grub-core-loader-i386-bsd.c-grub_bsd_elf32_size_hook.patch b/0014-grub-core-loader-i386-bsd.c-grub_bsd_elf32_size_hook.patch new file mode 100644 index 0000000..0a47578 --- /dev/null +++ b/0014-grub-core-loader-i386-bsd.c-grub_bsd_elf32_size_hook.patch @@ -0,0 +1,83 @@ +From 6a6140eac9a2d0889dcf6d118979d4af242b8060 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sun, 22 Jul 2012 16:30:48 +0200 +Subject: [PATCH 014/364] * grub-core/loader/i386/bsd.c + (grub_bsd_elf32_size_hook): Fix mask. (grub_bsd_elf32_hook): Likewise. + (grub_bsd_elf64_size_hook): Likewise. (grub_bsd_elf64_hook): Likewise. + (grub_bsd_load_elf): Likewise. + +--- + ChangeLog | 8 ++++++++ + grub-core/loader/i386/bsd.c | 10 +++++----- + 2 files changed, 13 insertions(+), 5 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 892d31b..f514465 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,13 @@ + 2012-07-22 Vladimir Serbinenko + ++ * grub-core/loader/i386/bsd.c (grub_bsd_elf32_size_hook): Fix mask. ++ (grub_bsd_elf32_hook): Likewise. ++ (grub_bsd_elf64_size_hook): Likewise. ++ (grub_bsd_elf64_hook): Likewise. ++ (grub_bsd_load_elf): Likewise. ++ ++2012-07-22 Vladimir Serbinenko ++ + * grub-core/lib/xzembed/xz_dec_stream.c (hash_validate): Fix behaviour + if hash function is unavailable. + (dec_stream_header): Likewise. +diff --git a/grub-core/loader/i386/bsd.c b/grub-core/loader/i386/bsd.c +index 0fd4df0..6e024e4 100644 +--- a/grub-core/loader/i386/bsd.c ++++ b/grub-core/loader/i386/bsd.c +@@ -1309,7 +1309,7 @@ grub_bsd_elf32_size_hook (grub_elf_t elf __attribute__ ((unused)), + && phdr->p_type != PT_DYNAMIC) + return 0; + +- paddr = phdr->p_paddr & 0xFFFFFF; ++ paddr = phdr->p_paddr & 0xFFFFFFF; + + if (paddr < kern_start) + kern_start = paddr; +@@ -1333,7 +1333,7 @@ grub_bsd_elf32_hook (Elf32_Phdr * phdr, grub_addr_t * addr, int *do_load) + } + + *do_load = 1; +- phdr->p_paddr &= 0xFFFFFF; ++ phdr->p_paddr &= 0xFFFFFFF; + paddr = phdr->p_paddr; + + *addr = (grub_addr_t) (paddr - kern_start + (grub_uint8_t *) kern_chunk_src); +@@ -1351,7 +1351,7 @@ grub_bsd_elf64_size_hook (grub_elf_t elf __attribute__ ((unused)), + && phdr->p_type != PT_DYNAMIC) + return 0; + +- paddr = phdr->p_paddr & 0xffffff; ++ paddr = phdr->p_paddr & 0xfffffff; + + if (paddr < kern_start) + kern_start = paddr; +@@ -1375,7 +1375,7 @@ grub_bsd_elf64_hook (Elf64_Phdr * phdr, grub_addr_t * addr, int *do_load) + } + + *do_load = 1; +- paddr = phdr->p_paddr & 0xffffff; ++ paddr = phdr->p_paddr & 0xfffffff; + + *addr = (grub_addr_t) (paddr - kern_start + (grub_uint8_t *) kern_chunk_src); + +@@ -1394,7 +1394,7 @@ grub_bsd_load_elf (grub_elf_t elf, const char *filename) + { + grub_relocator_chunk_t ch; + +- entry = elf->ehdr.ehdr32.e_entry & 0xFFFFFF; ++ entry = elf->ehdr.ehdr32.e_entry & 0xFFFFFFF; + err = grub_elf32_phdr_iterate (elf, filename, + grub_bsd_elf32_size_hook, NULL); + if (err) +-- +1.8.1.4 + diff --git a/0015-New-command-lsefi.patch b/0015-New-command-lsefi.patch new file mode 100644 index 0000000..24ca884 --- /dev/null +++ b/0015-New-command-lsefi.patch @@ -0,0 +1,368 @@ +From c0be2c2099805c621f27d5b3ced224db437a582c Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sun, 22 Jul 2012 19:59:06 +0200 +Subject: [PATCH 015/364] New command `lsefi'. + + * grub-core/Makefile.core.def (lsefi): New module. + * grub-core/commands/efi/lsefi.c: New file. + * include/grub/efi/api.h: Add more GUIDs. +--- + ChangeLog | 8 +++ + grub-core/Makefile.core.def | 6 ++ + grub-core/commands/efi/lsefi.c | 153 +++++++++++++++++++++++++++++++++++++++++ + include/grub/efi/api.h | 142 +++++++++++++++++++++++++++++++++++++- + 4 files changed, 308 insertions(+), 1 deletion(-) + create mode 100644 grub-core/commands/efi/lsefi.c + +diff --git a/ChangeLog b/ChangeLog +index f514465..a21708c 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,13 @@ + 2012-07-22 Vladimir Serbinenko + ++ New command `lsefi'. ++ ++ * grub-core/Makefile.core.def (lsefi): New module. ++ * grub-core/commands/efi/lsefi.c: New file. ++ * include/grub/efi/api.h: Add more GUIDs. ++ ++2012-07-22 Vladimir Serbinenko ++ + * grub-core/loader/i386/bsd.c (grub_bsd_elf32_size_hook): Fix mask. + (grub_bsd_elf32_hook): Likewise. + (grub_bsd_elf64_size_hook): Likewise. +diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def +index 5c2fcc2..de702d6 100644 +--- a/grub-core/Makefile.core.def ++++ b/grub-core/Makefile.core.def +@@ -569,6 +569,12 @@ module = { + }; + + module = { ++ name = lsefi; ++ common = commands/efi/lsefi.c; ++ enable = efi; ++}; ++ ++module = { + name = blocklist; + common = commands/blocklist.c; + }; +diff --git a/grub-core/commands/efi/lsefi.c b/grub-core/commands/efi/lsefi.c +new file mode 100644 +index 0000000..8dffbdc +--- /dev/null ++++ b/grub-core/commands/efi/lsefi.c +@@ -0,0 +1,153 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2012 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 ++ ++GRUB_MOD_LICENSE ("GPLv3+"); ++ ++struct known_protocol ++{ ++ grub_efi_guid_t guid; ++ const char *name; ++} known_protocols[] = ++ { ++ { GRUB_EFI_DISK_IO_GUID, "disk" }, ++ { GRUB_EFI_BLOCK_IO_GUID, "block" }, ++ { GRUB_EFI_SERIAL_IO_GUID, "serial" }, ++ { GRUB_EFI_SIMPLE_NETWORK_GUID, "network" }, ++ { GRUB_EFI_PXE_GUID, "pxe" }, ++ { GRUB_EFI_DEVICE_PATH_GUID, "device path" }, ++ { GRUB_EFI_PCI_IO_GUID, "PCI" }, ++ { GRUB_EFI_PCI_ROOT_IO_GUID, "PCI root" }, ++ { GRUB_EFI_EDID_ACTIVE_GUID, "active EDID" }, ++ { GRUB_EFI_EDID_DISCOVERED_GUID, "discovered EDID" }, ++ { GRUB_EFI_EDID_OVERRIDE_GUID, "override EDID" }, ++ { GRUB_EFI_GOP_GUID, "GOP" }, ++ { GRUB_EFI_UGA_DRAW_GUID, "UGA draw" }, ++ { GRUB_EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_GUID, "simple text output" }, ++ { GRUB_EFI_SIMPLE_TEXT_INPUT_PROTOCOL_GUID, "simple text input" }, ++ { GRUB_EFI_SIMPLE_POINTER_PROTOCOL_GUID, "simple pointer" }, ++ { GRUB_EFI_CONSOLE_CONTROL_GUID, "console control" }, ++ { GRUB_EFI_ABSOLUTE_POINTER_PROTOCOL_GUID, "absolute pointer" }, ++ { GRUB_EFI_DRIVER_BINDING_PROTOCOL_GUID, "EFI driver binding" }, ++ { GRUB_EFI_LOAD_FILE_PROTOCOL_GUID, "load file" }, ++ { GRUB_EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID, "simple FS" }, ++ { GRUB_EFI_TAPE_IO_PROTOCOL_GUID, "tape I/O" }, ++ { GRUB_EFI_UNICODE_COLLATION_PROTOCOL_GUID, "unicode collation" }, ++ { GRUB_EFI_SCSI_IO_PROTOCOL_GUID, "SCSI I/O" }, ++ { GRUB_EFI_USB2_HC_PROTOCOL_GUID, "USB host" }, ++ { GRUB_EFI_DEBUG_SUPPORT_PROTOCOL_GUID, "debug support" }, ++ { GRUB_EFI_DEBUGPORT_PROTOCOL_GUID, "debug port" }, ++ { GRUB_EFI_DECOMPRESS_PROTOCOL_GUID, "decompress" }, ++ { GRUB_EFI_LOADED_IMAGE_PROTOCOL_GUID, "loaded image" }, ++ { GRUB_EFI_DEVICE_PATH_TO_TEXT_PROTOCOL_GUID, "device path to text" }, ++ { GRUB_EFI_DEVICE_PATH_UTILITIES_PROTOCOL_GUID, "device path utilities" }, ++ { GRUB_EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL_GUID, "device path from text" }, ++ { GRUB_EFI_HII_CONFIG_ROUTING_PROTOCOL_GUID, "HII config routing" }, ++ { GRUB_EFI_HII_DATABASE_PROTOCOL_GUID, "HII database" }, ++ { GRUB_EFI_HII_STRING_PROTOCOL_GUID, "HII string" }, ++ { GRUB_EFI_HII_IMAGE_PROTOCOL_GUID, "HII image" }, ++ { GRUB_EFI_HII_FONT_PROTOCOL_GUID, "HII font" }, ++ { GRUB_EFI_COMPONENT_NAME2_PROTOCOL_GUID, "component name 2" }, ++ { GRUB_EFI_HII_CONFIGURATION_ACCESS_PROTOCOL_GUID, ++ "HII configuration access" }, ++ { GRUB_EFI_USB_IO_PROTOCOL_GUID, "USB I/O" }, ++ }; ++ ++static grub_err_t ++grub_cmd_lsefi (grub_command_t cmd __attribute__ ((unused)), ++ int argc __attribute__ ((unused)), ++ char **args __attribute__ ((unused))) ++{ ++ grub_efi_handle_t *handles; ++ grub_efi_uintn_t num_handles; ++ unsigned i, j, k; ++ ++ handles = grub_efi_locate_handle (GRUB_EFI_ALL_HANDLES, ++ NULL, NULL, &num_handles); ++ ++ for (i = 0; i < num_handles; i++) ++ { ++ grub_efi_handle_t handle = handles[i]; ++ grub_efi_status_t status; ++ grub_efi_uintn_t num_protocols; ++ grub_efi_guid_t **protocols; ++ grub_efi_device_path_t *dp; ++ ++ grub_printf ("Handle %p\n", handle); ++ ++ dp = grub_efi_get_device_path (handle); ++ if (dp) ++ { ++ grub_printf (" "); ++ grub_efi_print_device_path (dp); ++ } ++ ++ status = efi_call_3 (grub_efi_system_table->boot_services->protocols_per_handle, ++ handle, &protocols, &num_protocols); ++ if (status != GRUB_EFI_SUCCESS) ++ grub_printf ("Unable to retrieve protocols\n"); ++ for (j = 0; j < num_protocols; j++) ++ { ++ for (k = 0; k < ARRAY_SIZE (known_protocols); k++) ++ if (grub_memcmp (protocols[j], &known_protocols[k].guid, ++ sizeof (known_protocols[k].guid)) == 0) ++ break; ++ if (k < ARRAY_SIZE (known_protocols)) ++ grub_printf (" %s\n", known_protocols[k].name); ++ else ++ grub_printf (" %08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x\n", ++ protocols[j]->data1, ++ protocols[j]->data2, ++ protocols[j]->data3, ++ (unsigned) protocols[j]->data4[0], ++ (unsigned) protocols[j]->data4[1], ++ (unsigned) protocols[j]->data4[2], ++ (unsigned) protocols[j]->data4[3], ++ (unsigned) protocols[j]->data4[4], ++ (unsigned) protocols[j]->data4[5], ++ (unsigned) protocols[j]->data4[6], ++ (unsigned) protocols[j]->data4[7]); ++ } ++ ++ } ++ ++ return 0; ++} ++ ++static grub_command_t cmd; ++ ++GRUB_MOD_INIT(lsefi) ++{ ++ cmd = grub_register_command ("lsefi", grub_cmd_lsefi, ++ NULL, "Display EFI handles."); ++} ++ ++GRUB_MOD_FINI(lsefi) ++{ ++ grub_unregister_command (cmd); ++} +diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h +index 26127de..9e7a8d8 100644 +--- a/include/grub/efi/api.h ++++ b/include/grub/efi/api.h +@@ -104,9 +104,149 @@ + { 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \ + } + ++#define GRUB_EFI_SIMPLE_TEXT_INPUT_PROTOCOL_GUID \ ++ { 0x387477c1, 0x69c7, 0x11d2, \ ++ { 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \ ++ } ++ ++#define EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID \ ++ { 0xdd9e7534, 0x7762, 0x4698, \ ++ { 0x8c, 0x14, 0xf5, 0x85, 0x17, 0xa6, 0x25, 0xaa } \ ++ } ++ ++#define GRUB_EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_GUID \ ++ { 0x387477c2, 0x69c7, 0x11d2, \ ++ { 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \ ++ } ++ ++#define GRUB_EFI_SIMPLE_POINTER_PROTOCOL_GUID \ ++ { 0x31878c87, 0xb75, 0x11d5, \ ++ { 0x9a, 0x4f, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ ++ } ++ ++#define GRUB_EFI_ABSOLUTE_POINTER_PROTOCOL_GUID \ ++ { 0x8D59D32B, 0xC655, 0x4AE9, \ ++ { 0x9B, 0x15, 0xF2, 0x59, 0x04, 0x99, 0x2A, 0x43 } \ ++ } ++ ++#define GRUB_EFI_DRIVER_BINDING_PROTOCOL_GUID \ ++ { 0x18A031AB, 0xB443, 0x4D1A, \ ++ { 0xA5, 0xC0, 0x0C, 0x09, 0x26, 0x1E, 0x9F, 0x71 } \ ++ } ++ ++#define GRUB_EFI_LOADED_IMAGE_PROTOCOL_GUID \ ++ { 0x5B1B31A1, 0x9562, 0x11d2, \ ++ { 0x8E, 0x3F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B } \ ++ } ++ ++#define GRUB_EFI_LOAD_FILE_PROTOCOL_GUID \ ++ { 0x56EC3091, 0x954C, 0x11d2, \ ++ { 0x8E, 0x3F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B } \ ++ } ++ ++#define GRUB_EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID \ ++ { 0x0964e5b22, 0x6459, 0x11d2, \ ++ { 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \ ++ } ++ ++#define GRUB_EFI_TAPE_IO_PROTOCOL_GUID \ ++ { 0x1e93e633, 0xd65a, 0x459e, \ ++ { 0xab, 0x84, 0x93, 0xd9, 0xec, 0x26, 0x6d, 0x18 } \ ++ } ++ ++#define GRUB_EFI_UNICODE_COLLATION_PROTOCOL_GUID \ ++ { 0x1d85cd7f, 0xf43d, 0x11d2, \ ++ { 0x9a, 0x0c, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ ++ } ++ ++#define GRUB_EFI_SCSI_IO_PROTOCOL_GUID \ ++ { 0x932f47e6, 0x2362, 0x4002, \ ++ { 0x80, 0x3e, 0x3c, 0xd5, 0x4b, 0x13, 0x8f, 0x85 } \ ++ } ++ ++#define GRUB_EFI_USB2_HC_PROTOCOL_GUID \ ++ { 0x3e745226, 0x9818, 0x45b6, \ ++ { 0xa2, 0xac, 0xd7, 0xcd, 0x0e, 0x8b, 0xa2, 0xbc } \ ++ } ++ ++#define GRUB_EFI_DEBUG_SUPPORT_PROTOCOL_GUID \ ++ { 0x2755590C, 0x6F3C, 0x42FA, \ ++ { 0x9E, 0xA4, 0xA3, 0xBA, 0x54, 0x3C, 0xDA, 0x25 } \ ++ } ++ ++#define GRUB_EFI_DEBUGPORT_PROTOCOL_GUID \ ++ { 0xEBA4E8D2, 0x3858, 0x41EC, \ ++ { 0xA2, 0x81, 0x26, 0x47, 0xBA, 0x96, 0x60, 0xD0 } \ ++ } ++ ++#define GRUB_EFI_DECOMPRESS_PROTOCOL_GUID \ ++ { 0xd8117cfe, 0x94a6, 0x11d4, \ ++ { 0x9a, 0x3a, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ ++ } ++ ++#define GRUB_EFI_DEVICE_PATH_TO_TEXT_PROTOCOL_GUID \ ++ { 0x8b843e20, 0x8132, 0x4852, \ ++ { 0x90, 0xcc, 0x55, 0x1a, 0x4e, 0x4a, 0x7f, 0x1c } \ ++ } ++ ++#define GRUB_EFI_DEVICE_PATH_UTILITIES_PROTOCOL_GUID \ ++ { 0x379be4e, 0xd706, 0x437d, \ ++ { 0xb0, 0x37, 0xed, 0xb8, 0x2f, 0xb7, 0x72, 0xa4 } \ ++ } ++ ++#define GRUB_EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL_GUID \ ++ { 0x5c99a21, 0xc70f, 0x4ad2, \ ++ { 0x8a, 0x5f, 0x35, 0xdf, 0x33, 0x43, 0xf5, 0x1e } \ ++ } ++ ++#define GRUB_EFI_ACPI_TABLE_PROTOCOL_GUID \ ++ { 0xffe06bdd, 0x6107, 0x46a6, \ ++ { 0x7b, 0xb2, 0x5a, 0x9c, 0x7e, 0xc5, 0x27, 0x5c} \ ++ } ++ ++#define GRUB_EFI_HII_CONFIG_ROUTING_PROTOCOL_GUID \ ++ { 0x587e72d7, 0xcc50, 0x4f79, \ ++ { 0x82, 0x09, 0xca, 0x29, 0x1f, 0xc1, 0xa1, 0x0f } \ ++ } ++ ++#define GRUB_EFI_HII_DATABASE_PROTOCOL_GUID \ ++ { 0xef9fc172, 0xa1b2, 0x4693, \ ++ { 0xb3, 0x27, 0x6d, 0x32, 0xfc, 0x41, 0x60, 0x42 } \ ++ } ++ ++#define GRUB_EFI_HII_STRING_PROTOCOL_GUID \ ++ { 0xfd96974, 0x23aa, 0x4cdc, \ ++ { 0xb9, 0xcb, 0x98, 0xd1, 0x77, 0x50, 0x32, 0x2a } \ ++ } ++ ++#define GRUB_EFI_HII_IMAGE_PROTOCOL_GUID \ ++ { 0x31a6406a, 0x6bdf, 0x4e46, \ ++ { 0xb2, 0xa2, 0xeb, 0xaa, 0x89, 0xc4, 0x9, 0x20 } \ ++ } ++ ++#define GRUB_EFI_HII_FONT_PROTOCOL_GUID \ ++ { 0xe9ca4775, 0x8657, 0x47fc, \ ++ { 0x97, 0xe7, 0x7e, 0xd6, 0x5a, 0x8, 0x43, 0x24 } \ ++ } ++ ++#define GRUB_EFI_HII_CONFIGURATION_ACCESS_PROTOCOL_GUID \ ++ { 0x330d4706, 0xf2a0, 0x4e4f, \ ++ { 0xa3, 0x69, 0xb6, 0x6f, 0xa8, 0xd5, 0x43, 0x85 } \ ++ } ++ ++#define GRUB_EFI_COMPONENT_NAME2_PROTOCOL_GUID \ ++ { 0x6a7a5cff, 0xe8d9, 0x4f70, \ ++ { 0xba, 0xda, 0x75, 0xab, 0x30, 0x25, 0xce, 0x14} \ ++ } ++ ++#define GRUB_EFI_USB_IO_PROTOCOL_GUID \ ++ { 0x2B2F68D6, 0x0CD2, 0x44cf, \ ++ { 0x8E, 0x8B, 0xBB, 0xA2, 0x0B, 0x1B, 0x5B, 0x75 } \ ++ } ++ + #define GRUB_EFI_MPS_TABLE_GUID \ + { 0xeb9d2d2f, 0x2d88, 0x11d3, \ +- { 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ ++ { 0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ + } + + #define GRUB_EFI_ACPI_TABLE_GUID \ +-- +1.8.1.4 + diff --git a/0016-util-grub-mkconfig_lib.in-grub_quote-Remove-extra-la.patch b/0016-util-grub-mkconfig_lib.in-grub_quote-Remove-extra-la.patch new file mode 100644 index 0000000..105e7c3 --- /dev/null +++ b/0016-util-grub-mkconfig_lib.in-grub_quote-Remove-extra-la.patch @@ -0,0 +1,162 @@ +From 14589a819717d1d6614687202159a0070bba1f8f Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sun, 22 Jul 2012 20:02:17 +0200 +Subject: [PATCH 016/364] * util/grub-mkconfig_lib.in (grub_quote): + Remove extra layer of escape. * util/grub.d/10_hurd.in: Add missing quoting. + * util/grub.d/10_illumos.in: Likewise. * util/grub.d/10_kfreebsd.in: + Likewise. * util/grub.d/10_linux.in: Likewise. * + util/grub.d/20_linux_xen.in: Likewise. + +--- + ChangeLog | 9 +++++++++ + util/grub-mkconfig_lib.in | 10 +++++----- + util/grub.d/10_hurd.in | 4 ++-- + util/grub.d/10_illumos.in | 1 + + util/grub.d/10_kfreebsd.in | 2 +- + util/grub.d/10_linux.in | 4 ++-- + util/grub.d/20_linux_xen.in | 6 +++--- + 7 files changed, 23 insertions(+), 13 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index a21708c..0db6239 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,14 @@ + 2012-07-22 Vladimir Serbinenko + ++ * util/grub-mkconfig_lib.in (grub_quote): Remove extra layer of escape. ++ * util/grub.d/10_hurd.in: Add missing quoting. ++ * util/grub.d/10_illumos.in: Likewise. ++ * util/grub.d/10_kfreebsd.in: Likewise. ++ * util/grub.d/10_linux.in: Likewise. ++ * util/grub.d/20_linux_xen.in: Likewise. ++ ++2012-07-22 Vladimir Serbinenko ++ + New command `lsefi'. + + * grub-core/Makefile.core.def (lsefi): New module. +diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in +index 76133b4..beb52ee 100644 +--- a/util/grub-mkconfig_lib.in ++++ b/util/grub-mkconfig_lib.in +@@ -255,19 +255,19 @@ version_find_latest () + echo "$version_find_latest_a" + } + +-# One layer of quotation is eaten by "", the second by sed, and the third by +-# printf; so this turns ' into \'. Note that you must use the output of ++# One layer of quotation is eaten by "" and the second by ++# sed; so this turns ' into \'. Note that you must use the output of + # this function in a printf format string. + + grub_quote () { +- sed "s/'/'\\\\\\\\''/g" ++ sed "s/'/'\\\\''/g" + } + + gettext_quoted () { +- gettext "$@" | sed "s/'/'\\\\\\\\''/g" ++ gettext "$@" | grub_quote + } + +-# Run the first argument through gettext_quoted, and then pass that and all ++# Run the first argument through gettext, and then pass that and all + # remaining arguments to printf. This is a useful abbreviation and tends to + # be easier to type. + gettext_printf () { +diff --git a/util/grub.d/10_hurd.in b/util/grub.d/10_hurd.in +index 6451060..45f0ad3 100644 +--- a/util/grub.d/10_hurd.in ++++ b/util/grub.d/10_hurd.in +@@ -117,7 +117,7 @@ EOF + opts= + fi + sed "s/^/$submenu_indentation/" << EOF +- echo '$message' ++ echo '$(echo "$message" | grub_quote)' + multiboot ${kernel} root=device:${GRUB_DEVICE#/dev/} $opts ${GRUB_CMDLINE_GNUMACH} + EOF + +@@ -133,7 +133,7 @@ EOF + fi + + sed "s/^/$submenu_indentation/" << EOF +- echo '$message' ++ echo '$(echo "$message" | grub_quote)' + module /hurd/${hurd_fs}.static ${hurd_fs} $opts \\ + --multiboot-command-line='\${kernel-command-line}' \\ + --host-priv-port='\${host-port}' \\ +diff --git a/util/grub.d/10_illumos.in b/util/grub.d/10_illumos.in +index 422d56f..2477466 100644 +--- a/util/grub.d/10_illumos.in ++++ b/util/grub.d/10_illumos.in +@@ -46,6 +46,7 @@ message="$(gettext_printf "Loading kernel of Illumos ...")" + ISADIR= + fi + zfs-bootfs $($grub_mkrelpath /) ZFS_BOOTFS ++ echo '$(echo "$message" | grub_quote)' + multiboot $($grub_mkrelpath /platform/i86pc/kernel)/\$ISADIR/unix /platform/i86pc/kernel/\$ISADIR/unix -B \$ZFS_BOOTFS,console=text + module $($grub_mkrelpath /platform/i86pc)/\$ISADIR/boot_archive /platform/i86pc/\$ISADIR/boot_archive + } +diff --git a/util/grub.d/10_kfreebsd.in b/util/grub.d/10_kfreebsd.in +index 93405a6..b0e84e2 100644 +--- a/util/grub.d/10_kfreebsd.in ++++ b/util/grub.d/10_kfreebsd.in +@@ -100,7 +100,7 @@ kfreebsd_entry () + printf '%s\n' "${prepare_boot_cache}" | sed "s/^/$submenu_indentation/" + message="$(gettext_printf "Loading kernel of FreeBSD %s ..." ${version})" + sed "s/^/$submenu_indentation/" << EOF +- echo '$message' ++ echo '$(echo "$message" | grub_quote)' + kfreebsd ${rel_dirname}/${basename} ${args} + EOF + +diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in +index 14402e8..35f7a83 100644 +--- a/util/grub.d/10_linux.in ++++ b/util/grub.d/10_linux.in +@@ -134,14 +134,14 @@ linux_entry () + fi + message="$(gettext_printf "Loading Linux %s ..." ${version})" + sed "s/^/$submenu_indentation/" << EOF +- echo '$message' ++ echo '$(echo "$message" | grub_quote)' + linux ${rel_dirname}/${basename} root=${linux_root_device_thisversion} ro ${args} + EOF + if test -n "${initrd}" ; then + # TRANSLATORS: ramdisk isn't identifier. Should be translated. + message="$(gettext_printf "Loading initial ramdisk ...")" + sed "s/^/$submenu_indentation/" << EOF +- echo '$message' ++ echo '$(echo "$message" | grub_quote)' + initrd ${rel_dirname}/${initrd} + EOF + fi +diff --git a/util/grub.d/20_linux_xen.in b/util/grub.d/20_linux_xen.in +index 1d94502..33f1592 100644 +--- a/util/grub.d/20_linux_xen.in ++++ b/util/grub.d/20_linux_xen.in +@@ -120,16 +120,16 @@ linux_entry () + xmessage="$(gettext_printf "Loading Xen %s ..." ${xen_version})" + lmessage="$(gettext_printf "Loading Linux %s ..." ${version})" + sed "s/^/$submenu_indentation/" << EOF +- echo '$xmessage' ++ echo '$(echo "$xmessage" | grub_quote)' + multiboot ${rel_xen_dirname}/${xen_basename} placeholder ${xen_args} +- echo '$lmessage' ++ echo '$(echo "$lmessage" | grub_quote)' + module ${rel_dirname}/${basename} placeholder root=${linux_root_device_thisversion} ro ${args} + EOF + if test -n "${initrd}" ; then + # TRANSLATORS: ramdisk isn't identifier. Should be translated. + message="$(gettext_printf "Loading initial ramdisk ...")" + sed "s/^/$submenu_indentation/" << EOF +- echo '$message' ++ echo '$(echo "$message" | grub_quote)' + module ${rel_dirname}/${initrd} + EOF + fi +-- +1.8.1.4 + diff --git a/0017-EHCI-and-OHCI-PCI-bus-master.patch b/0017-EHCI-and-OHCI-PCI-bus-master.patch new file mode 100644 index 0000000..49c1c9e --- /dev/null +++ b/0017-EHCI-and-OHCI-PCI-bus-master.patch @@ -0,0 +1,59 @@ +From 6054ac4ca1ce5f3e4589bfead3c9c05af89f9ace Mon Sep 17 00:00:00 2001 +From: starous +Date: Sun, 22 Jul 2012 21:09:30 +0200 +Subject: [PATCH 017/364] EHCI and OHCI PCI bus master + +--- + ChangeLog | 5 +++++ + grub-core/bus/usb/ehci.c | 5 +++++ + grub-core/bus/usb/ohci.c | 5 +++++ + 3 files changed, 15 insertions(+) + +diff --git a/ChangeLog b/ChangeLog +index 0db6239..01d4f92 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,8 @@ ++2012-07-22 Ales Nesrsta ++ ++ * grub-core/bus/usb/ehci.c: PCI iter. - added PCI bus master setting. ++ * grub-core/bus/usb/ohci.c: PCI iter. - added PCI bus master setting. ++ + 2012-07-22 Vladimir Serbinenko + + * util/grub-mkconfig_lib.in (grub_quote): Remove extra layer of escape. +diff --git a/grub-core/bus/usb/ehci.c b/grub-core/bus/usb/ehci.c +index b700519..d99a4be 100644 +--- a/grub-core/bus/usb/ehci.c ++++ b/grub-core/bus/usb/ehci.c +@@ -533,6 +533,11 @@ grub_ehci_pci_iter (grub_pci_device_t dev, + "EHCI grub_ehci_pci_iter: registers above 4G are not supported\n"); + return 0; + } ++ ++ /* Set bus master - needed for coreboot, VMware, broken BIOSes etc. */ ++ addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND); ++ grub_pci_write_word(addr, ++ GRUB_PCI_COMMAND_BUS_MASTER | grub_pci_read_word(addr)); + + grub_dprintf ("ehci", "EHCI grub_ehci_pci_iter: 32-bit EHCI OK\n"); + } +diff --git a/grub-core/bus/usb/ohci.c b/grub-core/bus/usb/ohci.c +index 23cf631..6fabb4b 100644 +--- a/grub-core/bus/usb/ohci.c ++++ b/grub-core/bus/usb/ohci.c +@@ -270,6 +270,11 @@ grub_ohci_pci_iter (grub_pci_device_t dev, + return 0; + #endif + ++ /* Set bus master - needed for coreboot, VMware, broken BIOSes etc. */ ++ addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND); ++ grub_pci_write_word(addr, ++ GRUB_PCI_COMMAND_BUS_MASTER | grub_pci_read_word(addr)); ++ + grub_dprintf ("ohci", "class=0x%02x 0x%02x interface 0x%02x\n", + class, subclass, interf); + } +-- +1.8.1.4 + diff --git a/0018-Update-manual-NetBSD-wise.patch b/0018-Update-manual-NetBSD-wise.patch new file mode 100644 index 0000000..3f1cfd2 --- /dev/null +++ b/0018-Update-manual-NetBSD-wise.patch @@ -0,0 +1,115 @@ +From 8d7ed36e113b21de18a1b4a2bf81d218d79114d2 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Gr=C3=A9goire=20Sutre?= +Date: Wed, 1 Aug 2012 00:18:57 +0200 +Subject: [PATCH 018/364] Update manual NetBSD-wise. + +--- + ChangeLog | 5 +++++ + docs/grub.texi | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- + 2 files changed, 67 insertions(+), 2 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 01d4f92..b246d4e 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,8 @@ ++2012-07-31 Grégoire Sutre ++ ++ * docs/grub.texi: Note that NetBSD/i386 is Multiboot-compliant. ++ (NetBSD): New subsection. ++ + 2012-07-22 Ales Nesrsta + + * grub-core/bus/usb/ehci.c: PCI iter. - added PCI bus master setting. +diff --git a/docs/grub.texi b/docs/grub.texi +index b5954da..b0e7f59 100644 +--- a/docs/grub.texi ++++ b/docs/grub.texi +@@ -311,8 +311,10 @@ tables are also loaded. + + @item Support non-Multiboot kernels + Support many of the various free 32-bit kernels that lack Multiboot +-compliance (primarily FreeBSD, NetBSD, OpenBSD, and +-Linux). Chain-loading of other boot loaders is also supported. ++compliance (primarily FreeBSD, NetBSD@footnote{The NetBSD/i386 kernel ++is Multiboot-compliant, but lacks support for Multiboot modules.}, ++OpenBSD, and Linux). Chain-loading of other boot loaders is also ++supported. + + @item Load multiples modules + Fully support the Multiboot feature of loading multiple modules. +@@ -897,6 +899,7 @@ Here, we describe some caveats on several operating systems. + @menu + * GNU/Hurd:: + * GNU/Linux:: ++* NetBSD:: + * DOS/Windows:: + @end menu + +@@ -997,6 +1000,63 @@ the size, run the command @command{uppermem} @emph{before} loading the + kernel. @xref{uppermem}, for more information. + + ++@node NetBSD ++@subsection NetBSD ++ ++Booting a NetBSD kernel from GRUB is also relatively easy: first set ++GRUB's root device, then load the kernel and the modules, and finally ++run @command{boot}. ++ ++@enumerate ++@item ++Set GRUB's root device to the partition holding the NetBSD root file ++system. For a disk with a NetBSD disk label, this is usually the first ++partition (a:). In that case, and assuming that the partition is on the ++first hard disk, set GRUB's root device as follows: ++ ++@example ++grub> @kbd{insmod part_bsd} ++grub> @kbd{set root=(hd0,netbsd1)} ++@end example ++ ++For a disk with a GUID Partition Table (GPT), and assuming that the ++NetBSD root partition is the third GPT partition, do this: ++ ++@example ++grub> @kbd{insmod part_gpt} ++grub> @kbd{set root=(hd0,gpt3)} ++@end example ++ ++@item ++Load the kernel using the command @command{knetbsd}: ++ ++@example ++grub> @kbd{knetbsd /netbsd} ++@end example ++ ++Various options may be given to @command{knetbsd}. These options are, ++for the most part, the same as in the NetBSD boot loader. For instance, ++to boot the system in single-user mode and with verbose messages, do ++this: ++ ++@example ++grub> @kbd{knetbsd /netbsd -s -v} ++@end example ++ ++@item ++If needed, load kernel modules with the command ++@command{knetbsd_module_elf}. A typical example is the module for the ++root file system: ++ ++@example ++grub> @kbd{knetbsd_module_elf /stand/amd64/6.0/modules/ffs/ffs.kmod} ++@end example ++ ++@item ++Finally, run the command @command{boot} (@pxref{boot}). ++@end enumerate ++ ++ + @node DOS/Windows + @subsection DOS/Windows + +-- +1.8.1.4 + diff --git a/0019-Regenerate-po-POTFILES.in-with-the-following-commman.patch b/0019-Regenerate-po-POTFILES.in-with-the-following-commman.patch new file mode 100644 index 0000000..53cad7f --- /dev/null +++ b/0019-Regenerate-po-POTFILES.in-with-the-following-commman.patch @@ -0,0 +1,68 @@ +From 8b2ef54da3e28cf66637a09c2a2afad9ee56a535 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Gr=C3=A9goire=20Sutre?= +Date: Wed, 1 Aug 2012 01:06:53 +0200 +Subject: [PATCH 019/364] Regenerate po/POTFILES.in with the following commmand + in a clean tree: + +export LC_ALL=en_US.UTF-8 +find . -iname '*.[ch]' | sort > po/POTFILES.in +--- + ChangeLog | 4 ++++ + po/POTFILES.in | 5 +++-- + 2 files changed, 7 insertions(+), 2 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index b246d4e..dd1fda8 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,9 @@ + 2012-07-31 Grégoire Sutre + ++ * po/POTFILES.in: Regenerated. ++ ++2012-07-31 Grégoire Sutre ++ + * docs/grub.texi: Note that NetBSD/i386 is Multiboot-compliant. + (NetBSD): New subsection. + +diff --git a/po/POTFILES.in b/po/POTFILES.in +index 987b37a..01cc53c 100644 +--- a/po/POTFILES.in ++++ b/po/POTFILES.in +@@ -32,6 +32,7 @@ + ./grub-core/commands/efi/acpi.c + ./grub-core/commands/efi/fixvideo.c + ./grub-core/commands/efi/loadbios.c ++./grub-core/commands/efi/lsefi.c + ./grub-core/commands/efi/lsefimmap.c + ./grub-core/commands/efi/lsefisystab.c + ./grub-core/commands/efi/lssal.c +@@ -558,8 +559,8 @@ + ./grub-core/term/emu/console.c + ./grub-core/term/gfxterm.c + ./grub-core/term/i386/pc/console.c ++./grub-core/term/i386/pc/mda_text.c + ./grub-core/term/i386/pc/vga_text.c +-./grub-core/term/i386/vga_common.c + ./grub-core/term/ieee1275/console.c + ./grub-core/term/ieee1275/escc.c + ./grub-core/term/ieee1275/serial.c +@@ -730,7 +731,6 @@ + ./include/grub/i386/time.h + ./include/grub/i386/tsc.h + ./include/grub/i386/types.h +-./include/grub/i386/vga_common.h + ./include/grub/i386/xnu.h + ./include/grub/ia64/efi/memory.h + ./include/grub/ia64/efi/time.h +@@ -867,6 +867,7 @@ + ./include/grub/util/ofpath.h + ./include/grub/util/resolve.h + ./include/grub/vga.h ++./include/grub/vgaregs.h + ./include/grub/video_fb.h + ./include/grub/video.h + ./include/grub/x86_64/at_keyboard.h +-- +1.8.1.4 + diff --git a/0020-Strengthen-the-configure-test-for-working-nostdinc-i.patch b/0020-Strengthen-the-configure-test-for-working-nostdinc-i.patch new file mode 100644 index 0000000..05d4694 --- /dev/null +++ b/0020-Strengthen-the-configure-test-for-working-nostdinc-i.patch @@ -0,0 +1,38 @@ +From cb6d50b03d383cae32b0fbe308acc76c9d041fc6 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Gr=C3=A9goire=20Sutre?= +Date: Sun, 5 Aug 2012 16:49:03 +0200 +Subject: [PATCH 020/364] Strengthen the configure test for working -nostdinc + -isystem. + +--- + ChangeLog | 4 ++++ + configure.ac | 1 + + 2 files changed, 5 insertions(+) + +diff --git a/ChangeLog b/ChangeLog +index dd1fda8..a0a81b1 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,7 @@ ++2012-08-05 Grégoire Sutre ++ ++ * configure.ac: Strengthen the test for working -nostdinc -isystem. ++ + 2012-07-31 Grégoire Sutre + + * po/POTFILES.in: Regenerated. +diff --git a/configure.ac b/configure.ac +index 91b36d0..190665d 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -717,6 +717,7 @@ 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 ++#include + int va_arg_func (int fixed, va_list args);]], [[]])], + [grub_cv_cc_isystem=yes], + [grub_cv_cc_isystem=no]) +-- +1.8.1.4 + diff --git a/0021-.bzrignore-Add-grub-bios-setup-grub-ofpathname-and.patch b/0021-.bzrignore-Add-grub-bios-setup-grub-ofpathname-and.patch new file mode 100644 index 0000000..62287d3 --- /dev/null +++ b/0021-.bzrignore-Add-grub-bios-setup-grub-ofpathname-and.patch @@ -0,0 +1,27 @@ +From 96aea00a1794415ecc4f01d3e05569927df19420 Mon Sep 17 00:00:00 2001 +From: Colin Watson +Date: Tue, 4 Sep 2012 18:33:33 +0100 +Subject: [PATCH 021/364] * .bzrignore: Add grub-bios-setup, grub-ofpathname, + and grub-sparc64-setup. + +--- + .bzrignore | 3 +++ + ChangeLog | 5 +++++ + 2 files changed, 8 insertions(+) + +diff --git a/ChangeLog b/ChangeLog +index a0a81b1..ed23d17 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,8 @@ ++2012-09-04 Colin Watson ++ ++ * .bzrignore: Add grub-bios-setup, grub-ofpathname, and ++ grub-sparc64-setup. ++ + 2012-08-05 Grégoire Sutre + + * configure.ac: Strengthen the test for working -nostdinc -isystem. +-- +1.8.1.4 + diff --git a/0022-docs-man-grub-mkdevicemap.h2m-Remove-since-grub-mkde.patch b/0022-docs-man-grub-mkdevicemap.h2m-Remove-since-grub-mkde.patch new file mode 100644 index 0000000..414cede --- /dev/null +++ b/0022-docs-man-grub-mkdevicemap.h2m-Remove-since-grub-mkde.patch @@ -0,0 +1,38 @@ +From cec2f4441396afd4c6abad10e51e5f0fe1dad686 Mon Sep 17 00:00:00 2001 +From: Colin Watson +Date: Tue, 4 Sep 2012 18:39:40 +0100 +Subject: [PATCH 022/364] * docs/man/grub-mkdevicemap.h2m: Remove, since + grub-mkdevicemap is gone. + +--- + ChangeLog | 5 +++++ + docs/man/grub-mkdevicemap.h2m | 4 ---- + 2 files changed, 5 insertions(+), 4 deletions(-) + delete mode 100644 docs/man/grub-mkdevicemap.h2m + +diff --git a/ChangeLog b/ChangeLog +index ed23d17..09ffe65 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,8 @@ ++2012-09-04 Colin Watson ++ ++ * docs/man/grub-mkdevicemap.h2m: Remove, since grub-mkdevicemap is ++ gone. ++ + 2012-09-04 Colin Watson + + * .bzrignore: Add grub-bios-setup, grub-ofpathname, and +diff --git a/docs/man/grub-mkdevicemap.h2m b/docs/man/grub-mkdevicemap.h2m +deleted file mode 100644 +index 3ef8e97..0000000 +--- a/docs/man/grub-mkdevicemap.h2m ++++ /dev/null +@@ -1,4 +0,0 @@ +-[NAME] +-grub-mkdevicemap \- generate a GRUB device map file automatically +-[SEE ALSO] +-.BR grub-install (8) +-- +1.8.1.4 + diff --git a/0023-grub-core-mmap-mips-loongson-Remove-empty-directory.patch b/0023-grub-core-mmap-mips-loongson-Remove-empty-directory.patch new file mode 100644 index 0000000..b30d7c5 --- /dev/null +++ b/0023-grub-core-mmap-mips-loongson-Remove-empty-directory.patch @@ -0,0 +1,27 @@ +From 9023fdb4b0f75d3c8e1d0e1b0199ecd416a18c59 Mon Sep 17 00:00:00 2001 +From: Colin Watson +Date: Tue, 4 Sep 2012 18:56:13 +0100 +Subject: [PATCH 023/364] * grub-core/mmap/mips/loongson: Remove empty + directory. + +--- + ChangeLog | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index 09ffe65..5a938ae 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,4 +1,8 @@ +-2012-09-04 Colin Watson ++2012-09-04 Colin Watson ++ ++ * grub-core/mmap/mips/loongson: Remove empty directory. ++ ++2012-09-04 Colin Watson + + * docs/man/grub-mkdevicemap.h2m: Remove, since grub-mkdevicemap is + gone. +-- +1.8.1.4 + diff --git a/0024-Makefile.am-EXTRA_DIST-Add.patch b/0024-Makefile.am-EXTRA_DIST-Add.patch new file mode 100644 index 0000000..e4e26be --- /dev/null +++ b/0024-Makefile.am-EXTRA_DIST-Add.patch @@ -0,0 +1,46 @@ +From 75887218d652d578af29494dd54cd8733643653b Mon Sep 17 00:00:00 2001 +From: Colin Watson +Date: Tue, 4 Sep 2012 18:59:41 +0100 +Subject: [PATCH 024/364] * Makefile.am (EXTRA_DIST): Add + grub-core/tests/boot/linux.init-mips.S, + grub-core/tests/boot/linux.init-ppc.S, and + grub-core/tests/boot/linux-ppc.cfg. + +--- + ChangeLog | 7 +++++++ + Makefile.am | 2 +- + 2 files changed, 8 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index 5a938ae..b1950ab 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,12 @@ + 2012-09-04 Colin Watson + ++ * Makefile.am (EXTRA_DIST): Add ++ grub-core/tests/boot/linux.init-mips.S, ++ grub-core/tests/boot/linux.init-ppc.S, and ++ grub-core/tests/boot/linux-ppc.cfg. ++ ++2012-09-04 Colin Watson ++ + * grub-core/mmap/mips/loongson: Remove empty directory. + + 2012-09-04 Colin Watson +diff --git a/Makefile.am b/Makefile.am +index db9e930..3bb911c 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -377,7 +377,7 @@ if COND_powerpc_ieee1275 + BOOTCHECKS = bootcheck-linux-ppc + endif + +-EXTRA_DIST += grub-core/tests/boot/kbsd.init-i386.S grub-core/tests/boot/kbsd.init-x86_64.S grub-core/tests/boot/kbsd.spec.txt grub-core/tests/boot/kernel-8086.S grub-core/tests/boot/kernel-i386.S grub-core/tests/boot/kfreebsd-aout.cfg grub-core/tests/boot/kfreebsd.cfg grub-core/tests/boot/kfreebsd.init-i386.S grub-core/tests/boot/kfreebsd.init-x86_64.S grub-core/tests/boot/knetbsd.cfg grub-core/tests/boot/kopenbsd.cfg grub-core/tests/boot/kopenbsdlabel.txt grub-core/tests/boot/linux16.cfg grub-core/tests/boot/linux.cfg grub-core/tests/boot/linux.init-i386.S grub-core/tests/boot/linux.init-x86_64.S grub-core/tests/boot/multiboot2.cfg grub-core/tests/boot/multiboot.cfg grub-core/tests/boot/ntldr.cfg grub-core/tests/boot/pc-chainloader.cfg ++EXTRA_DIST += grub-core/tests/boot/kbsd.init-i386.S grub-core/tests/boot/kbsd.init-x86_64.S grub-core/tests/boot/kbsd.spec.txt grub-core/tests/boot/kernel-8086.S grub-core/tests/boot/kernel-i386.S grub-core/tests/boot/kfreebsd-aout.cfg grub-core/tests/boot/kfreebsd.cfg grub-core/tests/boot/kfreebsd.init-i386.S grub-core/tests/boot/kfreebsd.init-x86_64.S grub-core/tests/boot/knetbsd.cfg grub-core/tests/boot/kopenbsd.cfg grub-core/tests/boot/kopenbsdlabel.txt grub-core/tests/boot/linux16.cfg grub-core/tests/boot/linux.cfg grub-core/tests/boot/linux.init-i386.S grub-core/tests/boot/linux.init-mips.S grub-core/tests/boot/linux.init-ppc.S grub-core/tests/boot/linux.init-x86_64.S grub-core/tests/boot/linux-ppc.cfg grub-core/tests/boot/multiboot2.cfg grub-core/tests/boot/multiboot.cfg grub-core/tests/boot/ntldr.cfg grub-core/tests/boot/pc-chainloader.cfg + + .PHONY: bootcheck-linux-i386 bootcheck-linux-x86_64 \ + bootcheck-kfreebsd-i386 bootcheck-kfreebsd-x86_64 \ +-- +1.8.1.4 + diff --git a/0025-Makefile.am-EXTRA_DIST-Add-linguas.sh.-It-s-only-str.patch b/0025-Makefile.am-EXTRA_DIST-Add-linguas.sh.-It-s-only-str.patch new file mode 100644 index 0000000..85b4070 --- /dev/null +++ b/0025-Makefile.am-EXTRA_DIST-Add-linguas.sh.-It-s-only-str.patch @@ -0,0 +1,45 @@ +From e8ec492c1f16328149e2e2c1eed6c300529bcb7a Mon Sep 17 00:00:00 2001 +From: Colin Watson +Date: Tue, 4 Sep 2012 23:35:38 +0100 +Subject: [PATCH 025/364] * Makefile.am (EXTRA_DIST): Add linguas.sh. It's + only strictly required for checkouts from bzr, but it may be useful for users + or distributors wishing to update translations against a tarball + distribution, and it can be helpful for the tarball to be a superset of + what's in bzr. + +--- + ChangeLog | 8 ++++++++ + Makefile.am | 2 ++ + 2 files changed, 10 insertions(+) + +diff --git a/ChangeLog b/ChangeLog +index b1950ab..fbef0c3 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,13 @@ + 2012-09-04 Colin Watson + ++ * Makefile.am (EXTRA_DIST): Add linguas.sh. It's only strictly ++ required for checkouts from bzr, but it may be useful for users or ++ distributors wishing to update translations against a tarball ++ distribution, and it can be helpful for the tarball to be a superset ++ of what's in bzr. ++ ++2012-09-04 Colin Watson ++ + * Makefile.am (EXTRA_DIST): Add + grub-core/tests/boot/linux.init-mips.S, + grub-core/tests/boot/linux.init-ppc.S, and +diff --git a/Makefile.am b/Makefile.am +index 3bb911c..30aa5a7 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -390,3 +390,5 @@ SUCCESSFUL_BOOT_STRING=3e49994fd5d82b7c9298d672d774080d + BOOTCHECK_TIMEOUT=180 + + bootcheck: $(BOOTCHECKS) ++ ++EXTRA_DIST += linguas.sh +-- +1.8.1.4 + diff --git a/0026-grub-core-fs-xfs.c-grub_xfs_read_block-Make-keys-a-c.patch b/0026-grub-core-fs-xfs.c-grub_xfs_read_block-Make-keys-a-c.patch new file mode 100644 index 0000000..3407d93 --- /dev/null +++ b/0026-grub-core-fs-xfs.c-grub_xfs_read_block-Make-keys-a-c.patch @@ -0,0 +1,39 @@ +From 981361e1db432371d895ac1339cc4a940cd6830e Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Wed, 5 Sep 2012 08:45:07 +0200 +Subject: [PATCH 026/364] * grub-core/fs/xfs.c (grub_xfs_read_block): + Make keys a const pointer. + +--- + ChangeLog | 4 ++++ + grub-core/fs/xfs.c | 2 +- + 2 files changed, 5 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index fbef0c3..0cf6bea 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,7 @@ ++2012-09-05 Vladimir Serbinenko ++ ++ * grub-core/fs/xfs.c (grub_xfs_read_block): Make keys a const pointer. ++ + 2012-09-04 Colin Watson + + * Makefile.am (EXTRA_DIST): Add linguas.sh. It's only strictly +diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c +index 2c6b00c..1ed048f 100644 +--- a/grub-core/fs/xfs.c ++++ b/grub-core/fs/xfs.c +@@ -285,7 +285,7 @@ grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) + + if (node->inode.format == XFS_INODE_FORMAT_BTREE) + { +- grub_uint64_t *keys; ++ const grub_uint64_t *keys; + int recoffset; + + leaf = grub_malloc (node->data->bsize); +-- +1.8.1.4 + diff --git a/0027-grub-core-partmap-dvh.c-grub_dvh_is_valid-Add-missin.patch b/0027-grub-core-partmap-dvh.c-grub_dvh_is_valid-Add-missin.patch new file mode 100644 index 0000000..74823f9 --- /dev/null +++ b/0027-grub-core-partmap-dvh.c-grub_dvh_is_valid-Add-missin.patch @@ -0,0 +1,41 @@ +From 33437c4676de37bf30679b5874813af38e5c00c2 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Wed, 5 Sep 2012 08:47:39 +0200 +Subject: [PATCH 027/364] * grub-core/partmap/dvh.c (grub_dvh_is_valid): + Add missing byteswap. + +--- + ChangeLog | 4 ++++ + grub-core/partmap/dvh.c | 2 +- + 2 files changed, 5 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index 0cf6bea..70f0c86 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,9 @@ + 2012-09-05 Vladimir Serbinenko + ++ * grub-core/partmap/dvh.c (grub_dvh_is_valid): Add missing byteswap. ++ ++2012-09-05 Vladimir Serbinenko ++ + * grub-core/fs/xfs.c (grub_xfs_read_block): Make keys a const pointer. + + 2012-09-04 Colin Watson +diff --git a/grub-core/partmap/dvh.c b/grub-core/partmap/dvh.c +index c8f467e..79ec01b 100644 +--- a/grub-core/partmap/dvh.c ++++ b/grub-core/partmap/dvh.c +@@ -57,7 +57,7 @@ grub_dvh_is_valid (grub_uint32_t *label) + for (pos = label; + pos < (label + sizeof (struct grub_dvh_block) / 4); + pos++) +- sum += *pos; ++ sum += grub_be_to_cpu32 (*pos); + + return ! sum; + } +-- +1.8.1.4 + diff --git a/0028-grub-core-script-yylex.l-Ignore-unused-function-and-.patch b/0028-grub-core-script-yylex.l-Ignore-unused-function-and-.patch new file mode 100644 index 0000000..5f156a5 --- /dev/null +++ b/0028-grub-core-script-yylex.l-Ignore-unused-function-and-.patch @@ -0,0 +1,42 @@ +From b7ae222dae310111f17da6e1fc072237977ac417 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Wed, 5 Sep 2012 08:51:31 +0200 +Subject: [PATCH 028/364] * grub-core/script/yylex.l: Ignore + unused-function and sign-compare warnings. + +--- + ChangeLog | 5 +++++ + grub-core/script/yylex.l | 2 ++ + 2 files changed, 7 insertions(+) + +diff --git a/ChangeLog b/ChangeLog +index 70f0c86..66a0245 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,10 @@ + 2012-09-05 Vladimir Serbinenko + ++ * grub-core/script/yylex.l: Ignore unused-function and sign-compare ++ warnings. ++ ++2012-09-05 Vladimir Serbinenko ++ + * grub-core/partmap/dvh.c (grub_dvh_is_valid): Add missing byteswap. + + 2012-09-05 Vladimir Serbinenko +diff --git a/grub-core/script/yylex.l b/grub-core/script/yylex.l +index f6a39c5..8fdcfef 100644 +--- a/grub-core/script/yylex.l ++++ b/grub-core/script/yylex.l +@@ -29,6 +29,8 @@ + #pragma GCC diagnostic ignored "-Wmissing-prototypes" + #pragma GCC diagnostic ignored "-Wmissing-declarations" + #pragma GCC diagnostic ignored "-Wunsafe-loop-optimizations" ++#pragma GCC diagnostic ignored "-Wunused-function" ++#pragma GCC diagnostic ignored "-Wsign-compare" + + #define yyfree grub_lexer_yyfree + #define yyalloc grub_lexer_yyalloc +-- +1.8.1.4 + diff --git a/0029-grub-core-disk-ieee1275-ofdisk.c-scan-Check-function.patch b/0029-grub-core-disk-ieee1275-ofdisk.c-scan-Check-function.patch new file mode 100644 index 0000000..3485120 --- /dev/null +++ b/0029-grub-core-disk-ieee1275-ofdisk.c-scan-Check-function.patch @@ -0,0 +1,67 @@ +From 41596a656df83fe0bd72944b711c127c68d28a94 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Wed, 5 Sep 2012 08:56:08 +0200 +Subject: [PATCH 029/364] * grub-core/disk/ieee1275/ofdisk.c (scan): + Check function return value. * grub-core/lib/ieee1275/datetime.c + (grub_get_datetime): Likewise. (grub_set_datetime): Likewise. + +--- + ChangeLog | 6 ++++++ + grub-core/disk/ieee1275/ofdisk.c | 2 +- + grub-core/lib/ieee1275/datetime.c | 4 ++-- + 3 files changed, 9 insertions(+), 3 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 66a0245..ff982b3 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,11 @@ + 2012-09-05 Vladimir Serbinenko + ++ * grub-core/disk/ieee1275/ofdisk.c (scan): Check function return value. ++ * grub-core/lib/ieee1275/datetime.c (grub_get_datetime): Likewise. ++ (grub_set_datetime): Likewise. ++ ++2012-09-05 Vladimir Serbinenko ++ + * grub-core/script/yylex.l: Ignore unused-function and sign-compare + warnings. + +diff --git a/grub-core/disk/ieee1275/ofdisk.c b/grub-core/disk/ieee1275/ofdisk.c +index b0aa7ec..c9535a0 100644 +--- a/grub-core/disk/ieee1275/ofdisk.c ++++ b/grub-core/disk/ieee1275/ofdisk.c +@@ -178,7 +178,7 @@ scan (void) + args.table = 0; + args.nentries = 0; + +- if (IEEE1275_CALL_ENTRY_FN (&args) == -1) ++ if (IEEE1275_CALL_ENTRY_FN (&args) == -1 || args.catch_result) + { + grub_ieee1275_close (ihandle); + return 0; +diff --git a/grub-core/lib/ieee1275/datetime.c b/grub-core/lib/ieee1275/datetime.c +index 1947135..8792429 100644 +--- a/grub-core/lib/ieee1275/datetime.c ++++ b/grub-core/lib/ieee1275/datetime.c +@@ -89,7 +89,7 @@ grub_get_datetime (struct grub_datetime *datetime) + + grub_ieee1275_close (ihandle); + +- if (status == -1) ++ if (status == -1 || args.catch_result) + return grub_error (GRUB_ERR_IO, "get-time failed"); + + datetime->year = args.year; +@@ -148,7 +148,7 @@ grub_set_datetime (struct grub_datetime *datetime) + + grub_ieee1275_close (ihandle); + +- if (status == -1) ++ if (status == -1 || args.catch_result) + return grub_error (GRUB_ERR_IO, "set-time failed"); + + return GRUB_ERR_NONE; +-- +1.8.1.4 + diff --git a/0030-util-import_gcry.py-Sort-cipher_files-to-make-build-.patch b/0030-util-import_gcry.py-Sort-cipher_files-to-make-build-.patch new file mode 100644 index 0000000..ccba181 --- /dev/null +++ b/0030-util-import_gcry.py-Sort-cipher_files-to-make-build-.patch @@ -0,0 +1,40 @@ +From 53a8f5760591b14160bc07ef10f083882516ad27 Mon Sep 17 00:00:00 2001 +From: Colin Watson +Date: Wed, 5 Sep 2012 09:00:39 +0100 +Subject: [PATCH 030/364] * util/import_gcry.py: Sort cipher_files, to make + build system generation more deterministic. + +--- + ChangeLog | 5 +++++ + util/import_gcry.py | 2 +- + 2 files changed, 6 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index ff982b3..9124825 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,8 @@ ++2012-09-05 Colin Watson ++ ++ * util/import_gcry.py: Sort cipher_files, to make build system ++ generation more deterministic. ++ + 2012-09-05 Vladimir Serbinenko + + * grub-core/disk/ieee1275/ofdisk.c (scan): Check function return value. +diff --git a/util/import_gcry.py b/util/import_gcry.py +index 18966a6..64c5870 100644 +--- a/util/import_gcry.py ++++ b/util/import_gcry.py +@@ -40,7 +40,7 @@ try: + except: + print ("WARNING: %s already exists" % cipher_dir_out) + +-cipher_files = os.listdir (cipher_dir_in) ++cipher_files = sorted (os.listdir (cipher_dir_in)) + conf = codecs.open (os.path.join ("grub-core", "Makefile.gcry.def"), "w", "utf-8") + conf.write ("AutoGen definitions Makefile.tpl;\n\n") + confutil = codecs.open ("Makefile.utilgcry.def", "w", "utf-8") +-- +1.8.1.4 + diff --git a/0031-NEWS-Fix-typo.patch b/0031-NEWS-Fix-typo.patch new file mode 100644 index 0000000..bc1642c --- /dev/null +++ b/0031-NEWS-Fix-typo.patch @@ -0,0 +1,39 @@ +From f333a71c6c02232151d9af98a8beae3b5e23e102 Mon Sep 17 00:00:00 2001 +From: Colin Watson +Date: Wed, 5 Sep 2012 13:55:54 +0100 +Subject: [PATCH 031/364] * NEWS: Fix typo. + +--- + ChangeLog | 4 ++++ + NEWS | 2 +- + 2 files changed, 5 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index 9124825..9323887 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,9 @@ + 2012-09-05 Colin Watson + ++ * NEWS: Fix typo. ++ ++2012-09-05 Colin Watson ++ + * util/import_gcry.py: Sort cipher_files, to make build system + generation more deterministic. + +diff --git a/NEWS b/NEWS +index f9b06ab..4bb5f98 100644 +--- a/NEWS ++++ b/NEWS +@@ -1,6 +1,6 @@ + New in 2.00: + +-* Appearence: ++* Appearance: + * Official theme for gfxmenu (starfield) + * Menu is organised with submenus. + * Better default video mode selection using EDID. +-- +1.8.1.4 + diff --git a/0032-configure.ac-Add-SuSe-path.patch b/0032-configure.ac-Add-SuSe-path.patch new file mode 100644 index 0000000..ac880eb --- /dev/null +++ b/0032-configure.ac-Add-SuSe-path.patch @@ -0,0 +1,38 @@ +From 4b13dd6c2fe6f75027c51f4b2616509040a5ea33 Mon Sep 17 00:00:00 2001 +From: Jiri Slaby +Date: Wed, 5 Sep 2012 16:09:41 +0200 +Subject: [PATCH 032/364] * configure.ac: Add SuSe path. + +--- + ChangeLog | 4 ++++ + configure.ac | 2 +- + 2 files changed, 5 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index 9323887..10b1ab3 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,7 @@ ++2012-09-05 Jiri Slaby ++ ++ * configure.ac: Add SuSe path. ++ + 2012-09-05 Colin Watson + + * NEWS: Fix typo. +diff --git a/configure.ac b/configure.ac +index 190665d..ea3830a 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -242,7 +242,7 @@ fi + FONT_SOURCE= + + 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 ++ for dir in . /usr/src /usr/share/fonts/X11/misc /usr/share/fonts/unifont /usr/share/fonts/uni; do + if test -f "$dir/unifont.$ext"; then + FONT_SOURCE="$dir/unifont.$ext" + break 2 +-- +1.8.1.4 + diff --git a/0033-grub-core-Makefile.core.def-efifwsetup-New-module.patch b/0033-grub-core-Makefile.core.def-efifwsetup-New-module.patch new file mode 100644 index 0000000..112daae --- /dev/null +++ b/0033-grub-core-Makefile.core.def-efifwsetup-New-module.patch @@ -0,0 +1,222 @@ +From 9e9382ece3511ff530cfb3e1c1e7a7dbaa3416b6 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Sat, 8 Sep 2012 09:40:24 +0200 +Subject: [PATCH 033/364] * grub-core/Makefile.core.def (efifwsetup): + New module. * grub-core/commands/efi/efifwsetup.c: New file. * + grub-core/kern/efi/efi.c (grub_efi_set_variable): New function * + include/grub/efi/api.h (GRUB_EFI_OS_INDICATIONS_BOOT_TO_FW_UI): New + define. * include/grub/efi/efi.h (grub_efi_set_variable): New proto. + +--- + ChangeLog | 9 ++++ + grub-core/Makefile.core.def | 6 +++ + grub-core/commands/efi/efifwsetup.c | 90 +++++++++++++++++++++++++++++++++++++ + grub-core/kern/efi/efi.c | 30 +++++++++++++ + include/grub/efi/api.h | 2 + + include/grub/efi/efi.h | 5 +++ + 6 files changed, 142 insertions(+) + create mode 100644 grub-core/commands/efi/efifwsetup.c + +diff --git a/ChangeLog b/ChangeLog +index 10b1ab3..e8f0577 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,12 @@ ++2012-09-08 Peter Jones ++ ++ * grub-core/Makefile.core.def (efifwsetup): New module. ++ * grub-core/commands/efi/efifwsetup.c: New file. ++ * grub-core/kern/efi/efi.c (grub_efi_set_variable): New function ++ * include/grub/efi/api.h (GRUB_EFI_OS_INDICATIONS_BOOT_TO_FW_UI): ++ New define. ++ * include/grub/efi/efi.h (grub_efi_set_variable): New proto. ++ + 2012-09-05 Jiri Slaby + + * configure.ac: Add SuSe path. +diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def +index de702d6..7a7b97a 100644 +--- a/grub-core/Makefile.core.def ++++ b/grub-core/Makefile.core.def +@@ -575,6 +575,12 @@ module = { + }; + + module = { ++ name = efifwsetup; ++ efi = commands/efi/efifwsetup.c; ++ enable = efi; ++}; ++ ++module = { + name = blocklist; + common = commands/blocklist.c; + }; +diff --git a/grub-core/commands/efi/efifwsetup.c b/grub-core/commands/efi/efifwsetup.c +new file mode 100644 +index 0000000..7a137a7 +--- /dev/null ++++ b/grub-core/commands/efi/efifwsetup.c +@@ -0,0 +1,90 @@ ++/* fwsetup.c - Reboot into firmware setup menu. */ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2012 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 ++ ++GRUB_MOD_LICENSE ("GPLv3+"); ++ ++static grub_err_t ++grub_cmd_fwsetup (grub_command_t cmd __attribute__ ((unused)), ++ int argc __attribute__ ((unused)), ++ char **args __attribute__ ((unused))) ++{ ++ grub_efi_uint64_t *old_os_indications; ++ grub_efi_uint64_t os_indications = GRUB_EFI_OS_INDICATIONS_BOOT_TO_FW_UI; ++ grub_err_t status; ++ grub_size_t oi_size; ++ grub_efi_guid_t global = GRUB_EFI_GLOBAL_VARIABLE_GUID; ++ ++ old_os_indications = grub_efi_get_variable ("OsIndications", &global, ++ &oi_size); ++ ++ if (old_os_indications != NULL && oi_size == sizeof (os_indications)) ++ os_indications |= *old_os_indications; ++ ++ status = grub_efi_set_variable ("OsIndications", &global, &os_indications, ++ sizeof (os_indications)); ++ if (status != GRUB_ERR_NONE) ++ return status; ++ ++ grub_reboot (); ++ ++ return GRUB_ERR_BUG; ++} ++ ++static grub_command_t cmd = NULL; ++ ++static grub_efi_boolean_t ++efifwsetup_is_supported (void) ++{ ++ grub_efi_uint64_t *os_indications_supported = NULL; ++ grub_size_t oi_size = 0; ++ grub_efi_guid_t global = GRUB_EFI_GLOBAL_VARIABLE_GUID; ++ ++ os_indications_supported = grub_efi_get_variable ("OsIndicationsSupported", ++ &global, &oi_size); ++ ++ if (!os_indications_supported) ++ return 0; ++ ++ if (*os_indications_supported & GRUB_EFI_OS_INDICATIONS_BOOT_TO_FW_UI) ++ return 1; ++ ++ return 0; ++} ++ ++GRUB_MOD_INIT (efifwsetup) ++{ ++ if (efifwsetup_is_supported ()) ++ cmd = grub_register_command ("fwsetup", grub_cmd_fwsetup, NULL, ++ N_("Reboot into firmware setup menu.")); ++ ++} ++ ++GRUB_MOD_FINI (efifwsetup) ++{ ++ if (cmd) ++ grub_unregister_command (cmd); ++} +diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c +index 02d2f9a..e8a62ec 100644 +--- a/grub-core/kern/efi/efi.c ++++ b/grub-core/kern/efi/efi.c +@@ -181,6 +181,36 @@ grub_efi_set_virtual_address_map (grub_efi_uintn_t memory_map_size, + return grub_error (GRUB_ERR_IO, "set_virtual_address_map failed"); + } + ++grub_err_t ++grub_efi_set_variable(const char *var, const grub_efi_guid_t *guid, ++ void *data, grub_size_t datasize) ++{ ++ grub_efi_status_t status; ++ grub_efi_runtime_services_t *r; ++ grub_efi_char16_t *var16; ++ grub_size_t len, len16; ++ ++ len = grub_strlen (var); ++ len16 = len * GRUB_MAX_UTF16_PER_UTF8; ++ var16 = grub_malloc ((len16 + 1) * sizeof (var16[0])); ++ if (!var16) ++ return grub_errno; ++ len16 = grub_utf8_to_utf16 (var16, len16, (grub_uint8_t *) var, len, NULL); ++ var16[len16] = 0; ++ ++ r = grub_efi_system_table->runtime_services; ++ ++ status = efi_call_5 (r->set_variable, var16, guid, ++ (GRUB_EFI_VARIABLE_NON_VOLATILE ++ | GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS ++ | GRUB_EFI_VARIABLE_RUNTIME_ACCESS), ++ datasize, data); ++ if (status == GRUB_EFI_SUCCESS) ++ return GRUB_ERR_NONE; ++ ++ return grub_error (GRUB_ERR_IO, "could not set EFI variable `%s'", var); ++} ++ + void * + grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid, + grub_size_t *datasize_out) +diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h +index 9e7a8d8..ae61730 100644 +--- a/include/grub/efi/api.h ++++ b/include/grub/efi/api.h +@@ -58,6 +58,8 @@ + #define GRUB_EFI_OPEN_PROTOCOL_BY_DRIVER 0x00000010 + #define GRUB_EFI_OPEN_PROTOCOL_BY_EXCLUSIVE 0x00000020 + ++#define GRUB_EFI_OS_INDICATIONS_BOOT_TO_FW_UI 0x0000000000000001ULL ++ + #define GRUB_EFI_VARIABLE_NON_VOLATILE 0x0000000000000001 + #define GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS 0x0000000000000002 + #define GRUB_EFI_VARIABLE_RUNTIME_ACCESS 0x0000000000000004 +diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h +index e67d92b..489cf9e 100644 +--- a/include/grub/efi/efi.h ++++ b/include/grub/efi/efi.h +@@ -64,6 +64,11 @@ grub_err_t EXPORT_FUNC (grub_efi_set_virtual_address_map) (grub_efi_uintn_t memo + void *EXPORT_FUNC (grub_efi_get_variable) (const char *variable, + const grub_efi_guid_t *guid, + grub_size_t *datasize_out); ++grub_err_t ++EXPORT_FUNC (grub_efi_set_variable) (const char *var, ++ const grub_efi_guid_t *guid, ++ void *data, ++ grub_size_t datasize); + int + EXPORT_FUNC (grub_efi_compare_device_paths) (const grub_efi_device_path_t *dp1, + const grub_efi_device_path_t *dp2); +-- +1.8.1.4 + diff --git a/0034-grub-core-loader-efi-appleloader.c-devpath_8-New-var.patch b/0034-grub-core-loader-efi-appleloader.c-devpath_8-New-var.patch new file mode 100644 index 0000000..494b11c --- /dev/null +++ b/0034-grub-core-loader-efi-appleloader.c-devpath_8-New-var.patch @@ -0,0 +1,50 @@ +From 8f779ade959a72267dcc045ad71012bf37cb96e0 Mon Sep 17 00:00:00 2001 +From: Benoit Gschwind +Date: Mon, 10 Sep 2012 09:34:29 +0200 +Subject: [PATCH 034/364] * grub-core/loader/efi/appleloader.c + (devpath_8): New var. (devs): Add devpath_8. + +--- + ChangeLog | 5 +++++ + grub-core/loader/efi/appleloader.c | 5 +++++ + 2 files changed, 10 insertions(+) + +diff --git a/ChangeLog b/ChangeLog +index e8f0577..6886bcc 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,8 @@ ++2012-09-10 Benoit Gschwind ++ ++ * grub-core/loader/efi/appleloader.c (devpath_8): New var. ++ (devs): Add devpath_8. ++ + 2012-09-08 Peter Jones + + * grub-core/Makefile.core.def (efifwsetup): New module. +diff --git a/grub-core/loader/efi/appleloader.c b/grub-core/loader/efi/appleloader.c +index e2de89f..56d5538 100644 +--- a/grub-core/loader/efi/appleloader.c ++++ b/grub-core/loader/efi/appleloader.c +@@ -127,6 +127,10 @@ static struct piwg_full_device_path devpath_6 = MAKE_PIWG_PATH (0xffcc4000, + static struct piwg_full_device_path devpath_7 = MAKE_PIWG_PATH (0xff981000, + 0xffc8ffff); + ++/* mid-2012 MBP retina (MacBookPro10,1) */ ++static struct piwg_full_device_path devpath_8 = MAKE_PIWG_PATH (0xff990000, ++ 0xffb2ffff); ++ + struct devdata + { + const char *model; +@@ -142,6 +146,7 @@ struct devdata devs[] = + {"MB NV", (grub_efi_device_path_t *) &devpath_5}, + {"MB NV2", (grub_efi_device_path_t *) &devpath_6}, + {"MBP2011", (grub_efi_device_path_t *) &devpath_7}, ++ {"MBP2012", (grub_efi_device_path_t *) &devpath_8}, + {NULL, NULL}, + }; + +-- +1.8.1.4 + diff --git a/0035-grub-core-disk-diskfilter.c-free_array-GRUB_UTIL-Fix.patch b/0035-grub-core-disk-diskfilter.c-free_array-GRUB_UTIL-Fix.patch new file mode 100644 index 0000000..b9eced0 --- /dev/null +++ b/0035-grub-core-disk-diskfilter.c-free_array-GRUB_UTIL-Fix.patch @@ -0,0 +1,106 @@ +From 56348e90bcc1076de7b2aba73b52fa1bafee4478 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Tue, 11 Sep 2012 07:53:26 +0200 +Subject: [PATCH 035/364] * grub-core/disk/diskfilter.c (free_array) + [GRUB_UTIL]: Fix memory leak. * util/getroot.c (grub_find_device): Likewise. + (get_mdadm_uuid): Likewise. (grub_util_is_imsm): Likewise. + (grub_util_pull_device): Likewise. * util/grub-probe.c (probe): Likewise. + +--- + ChangeLog | 9 +++++++++ + grub-core/disk/diskfilter.c | 3 +++ + util/getroot.c | 13 +++++++++++-- + util/grub-probe.c | 1 + + 4 files changed, 24 insertions(+), 2 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 6886bcc..c697e17 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,12 @@ ++2012-09-11 Vladimir Serbinenko ++ ++ * grub-core/disk/diskfilter.c (free_array) [GRUB_UTIL]: Fix memory leak. ++ * util/getroot.c (grub_find_device): Likewise. ++ (get_mdadm_uuid): Likewise. ++ (grub_util_is_imsm): Likewise. ++ (grub_util_pull_device): Likewise. ++ * util/grub-probe.c (probe): Likewise. ++ + 2012-09-10 Benoit Gschwind + + * grub-core/loader/efi/appleloader.c (devpath_8): New var. +diff --git a/grub-core/disk/diskfilter.c b/grub-core/disk/diskfilter.c +index 6e9745e..ce4c706 100644 +--- a/grub-core/disk/diskfilter.c ++++ b/grub-core/disk/diskfilter.c +@@ -1130,6 +1130,9 @@ free_array (void) + grub_disk_close (pv->disk); + if (pv->id.uuidlen) + grub_free (pv->id.uuid); ++#ifdef GRUB_UTIL ++ grub_free (pv->partmaps); ++#endif + grub_free (pv->internal_id); + grub_free (pv); + } +diff --git a/util/getroot.c b/util/getroot.c +index e103fb6..b97bea6 100644 +--- a/util/getroot.c ++++ b/util/getroot.c +@@ -918,7 +918,10 @@ grub_find_device (const char *dir, dev_t dev) + grub files */ + + if (strcmp(res, "/dev/root") == 0) +- continue; ++ { ++ free (res); ++ continue; ++ } + + if (chdir (saved_cwd) < 0) + grub_util_error ("%s", _("cannot restore the original directory")); +@@ -1363,6 +1366,7 @@ get_mdadm_uuid (const char *os_dev) + out: + close (fd); + waitpid (pid, NULL, 0); ++ free (buf); + + return name; + } +@@ -1437,6 +1441,8 @@ grub_util_is_imsm (const char *os_dev) + } + } + ++ free (buf); ++ + return 0; + + out: +@@ -1577,7 +1583,10 @@ grub_util_pull_device (const char *os_dev) + char **devicelist = grub_util_raid_getmembers (os_dev, 0); + int i; + for (i = 0; devicelist[i];i++) +- grub_util_pull_device (devicelist[i]); ++ { ++ grub_util_pull_device (devicelist[i]); ++ free (devicelist[i]); ++ } + free (devicelist); + } + #endif +diff --git a/util/grub-probe.c b/util/grub-probe.c +index 6dd1073..c2a0f62 100644 +--- a/util/grub-probe.c ++++ b/util/grub-probe.c +@@ -474,6 +474,7 @@ probe (const char *path, char **device_names, char delim) + printf ("%s", label); + putchar (delim); + } ++ grub_device_close (dev); + goto end; + } + +-- +1.8.1.4 + diff --git a/0036-Don-t-require-grub-mkconfig_lib-to-generate-manpages.patch b/0036-Don-t-require-grub-mkconfig_lib-to-generate-manpages.patch new file mode 100644 index 0000000..fc2ae63 --- /dev/null +++ b/0036-Don-t-require-grub-mkconfig_lib-to-generate-manpages.patch @@ -0,0 +1,70 @@ +From c7d45a90490c5f3337a6412a6ebe500e3a41a63b Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Wed, 12 Sep 2012 08:27:26 +0200 +Subject: [PATCH 036/364] Don't require grub-mkconfig_lib to generate + manpages for programs. + + * gentpl.py (manpage): Additional argument adddeps. Add adddeps to + dependencies, don't add grub-mkconfig_lib. + (program): Pass empty adddeps. + (script): Pass grub-mkconfig_lib as adddeps. +--- + ChangeLog | 9 +++++++++ + gentpl.py | 8 ++++---- + 2 files changed, 13 insertions(+), 4 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index c697e17..8576923 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,12 @@ ++2012-09-12 Vladimir Serbinenko ++ ++ Don't require grub-mkconfig_lib to generate manpages for programs. ++ ++ * gentpl.py (manpage): Additional argument adddeps. Add adddeps to ++ dependencies, don't add grub-mkconfig_lib. ++ (program): Pass empty adddeps. ++ (script): Pass grub-mkconfig_lib as adddeps. ++ + 2012-09-11 Vladimir Serbinenko + + * grub-core/disk/diskfilter.c (free_array) [GRUB_UTIL]: Fix memory leak. +diff --git a/gentpl.py b/gentpl.py +index bab4a8a..6d7f613 100644 +--- a/gentpl.py ++++ b/gentpl.py +@@ -484,10 +484,10 @@ def library(platform): + def installdir(default="bin"): + return "[+ IF installdir +][+ installdir +][+ ELSE +]" + default + "[+ ENDIF +]" + +-def manpage(): ++def manpage(adddeps): + r = "if COND_MAN_PAGES\n" + r += gvar_add("man_MANS", "[+ name +].[+ mansection +]\n") +- r += rule("[+ name +].[+ mansection +]", "[+ name +] grub-mkconfig_lib", """ ++ r += rule("[+ name +].[+ mansection +]", "[+ name +] " + adddeps, """ + chmod a+x [+ name +] + PATH=$(builddir):$$PATH pkgdatadir=$(builddir) $(HELP2MAN) --section=[+ mansection +] -i $(top_srcdir)/docs/man/[+ name +].h2m -o $@ [+ name +] + """) +@@ -503,7 +503,7 @@ def program(platform, test=False): + r += gvar_add("TESTS", "[+ name +]") + r += "[+ ELSE +]" + r += var_add(installdir() + "_PROGRAMS", "[+ name +]") +- r += "[+ IF mansection +]" + manpage() + "[+ ENDIF +]" ++ r += "[+ IF mansection +]" + manpage("") + "[+ ENDIF +]" + r += "[+ ENDIF +]" + + r += var_set(cname() + "_SOURCES", platform_sources(platform)) +@@ -532,7 +532,7 @@ def script(platform): + r += gvar_add ("TESTS", "[+ name +]") + r += "[+ ELSE +]" + r += var_add(installdir() + "_SCRIPTS", "[+ name +]") +- r += "[+ IF mansection +]" + manpage() + "[+ ENDIF +]" ++ r += "[+ IF mansection +]" + manpage("grub-mkconfig_lib") + "[+ ENDIF +]" + r += "[+ ENDIF +]" + + r += rule("[+ name +]", platform_sources(platform) + " $(top_builddir)/config.status", """ +-- +1.8.1.4 + diff --git a/0037-include-grub-efi-api.h-grub_efi_runtime_services-Mak.patch b/0037-include-grub-efi-api.h-grub_efi_runtime_services-Mak.patch new file mode 100644 index 0000000..c41af35 --- /dev/null +++ b/0037-include-grub-efi-api.h-grub_efi_runtime_services-Mak.patch @@ -0,0 +1,90 @@ +From 085ef74104c8f1a5d2cc68a0d1a2e0569827d6f4 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Wed, 12 Sep 2012 08:31:05 +0200 +Subject: [PATCH 037/364] * include/grub/efi/api.h + (grub_efi_runtime_services): Make vendor_guid a const pointer. * + grub-core/efiemu/runtime/efiemu.c (efiemu_memcpy): Make from a const + pointer. (efiemu_set_variable): Make vendor_guid a const pointer. + +--- + ChangeLog | 8 ++++++++ + grub-core/efiemu/runtime/efiemu.c | 14 +++++++------- + include/grub/efi/api.h | 2 +- + 3 files changed, 16 insertions(+), 8 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 8576923..527e9d1 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,13 @@ + 2012-09-12 Vladimir Serbinenko + ++ * include/grub/efi/api.h (grub_efi_runtime_services): Make vendor_guid ++ a const pointer. ++ * grub-core/efiemu/runtime/efiemu.c (efiemu_memcpy): Make from a ++ const pointer. ++ (efiemu_set_variable): Make vendor_guid a const pointer. ++ ++2012-09-12 Vladimir Serbinenko ++ + Don't require grub-mkconfig_lib to generate manpages for programs. + + * gentpl.py (manpage): Additional argument adddeps. Add adddeps to +diff --git a/grub-core/efiemu/runtime/efiemu.c b/grub-core/efiemu/runtime/efiemu.c +index 84b02cb..d923e40 100644 +--- a/grub-core/efiemu/runtime/efiemu.c ++++ b/grub-core/efiemu/runtime/efiemu.c +@@ -78,7 +78,7 @@ efiemu_get_next_variable_name (grub_efi_uintn_t *variable_name_size, + + grub_efi_status_t + efiemu_set_variable (grub_efi_char16_t *variable_name, +- grub_efi_guid_t *vendor_guid, ++ const grub_efi_guid_t *vendor_guid, + grub_efi_uint32_t attributes, + grub_efi_uintn_t data_size, + void *data); +@@ -131,11 +131,11 @@ extern grub_uint32_t efiemu_time_accuracy; + + /* Some standard functions because we need to be standalone */ + static void +-efiemu_memcpy (void *to, void *from, int count) ++efiemu_memcpy (void *to, const void *from, int count) + { + int i; + for (i = 0; i < count; i++) +- ((grub_uint8_t *) to)[i] = ((grub_uint8_t *) from)[i]; ++ ((grub_uint8_t *) to)[i] = ((const grub_uint8_t *) from)[i]; + } + + static int +@@ -503,10 +503,10 @@ grub_efi_status_t EFI_FUNC + + grub_efi_status_t + EFI_FUNC (efiemu_set_variable) (grub_efi_char16_t *variable_name, +- grub_efi_guid_t *vendor_guid, +- grub_efi_uint32_t attributes, +- grub_efi_uintn_t data_size, +- void *data) ++ const grub_efi_guid_t *vendor_guid, ++ grub_efi_uint32_t attributes, ++ grub_efi_uintn_t data_size, ++ void *data) + { + struct efi_variable *efivar; + grub_uint8_t *ptr; +diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h +index ae61730..2917d14 100644 +--- a/include/grub/efi/api.h ++++ b/include/grub/efi/api.h +@@ -1208,7 +1208,7 @@ struct grub_efi_runtime_services + + grub_efi_status_t + (*set_variable) (grub_efi_char16_t *variable_name, +- grub_efi_guid_t *vendor_guid, ++ const grub_efi_guid_t *vendor_guid, + grub_efi_uint32_t attributes, + grub_efi_uintn_t data_size, + void *data); +-- +1.8.1.4 + diff --git a/0038-grub-core-term-terminfo.c-Only-fix-up-powerpc-key-re.patch b/0038-grub-core-term-terminfo.c-Only-fix-up-powerpc-key-re.patch new file mode 100644 index 0000000..d155ed0 --- /dev/null +++ b/0038-grub-core-term-terminfo.c-Only-fix-up-powerpc-key-re.patch @@ -0,0 +1,74 @@ +From 5ba7247c064336767ee6b0ad9465b547ac90322a Mon Sep 17 00:00:00 2001 +From: Colin Watson +Date: Fri, 14 Sep 2012 11:23:36 +0100 +Subject: [PATCH 038/364] * grub-core/term/terminfo.c: Only fix up powerpc key + repeat on IEEE1275 machines. Fixes powerpc-emu compilation. * + include/grub/terminfo.h: Likewise. + +--- + ChangeLog | 6 ++++++ + grub-core/term/terminfo.c | 6 +++--- + include/grub/terminfo.h | 2 +- + 3 files changed, 10 insertions(+), 4 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 527e9d1..941ed93 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,9 @@ ++2012-09-14 Colin Watson ++ ++ * grub-core/term/terminfo.c: Only fix up powerpc key repeat on ++ IEEE1275 machines. Fixes powerpc-emu compilation. ++ * include/grub/terminfo.h: Likewise. ++ + 2012-09-12 Vladimir Serbinenko + + * include/grub/efi/api.h (grub_efi_runtime_services): Make vendor_guid +diff --git a/grub-core/term/terminfo.c b/grub-core/term/terminfo.c +index e35563f..d421e4e 100644 +--- a/grub-core/term/terminfo.c ++++ b/grub-core/term/terminfo.c +@@ -33,7 +33,7 @@ + #include + #include + #include +-#ifdef __powerpc__ ++#if defined(__powerpc__) && defined(GRUB_MACHINE_IEEE1275) + #include + #endif + +@@ -563,7 +563,7 @@ grub_terminfo_getkey (struct grub_term_input *termi) + grub_terminfo_readkey (termi, data->input_buf, + &data->npending, data->readkey); + +-#ifdef __powerpc__ ++#if defined(__powerpc__) && defined(GRUB_MACHINE_IEEE1275) + if (data->npending == 1 && data->input_buf[0] == '\e' + && grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_BROKEN_REPEAT) + && grub_get_time_ms () - data->last_key_time < 1000 +@@ -580,7 +580,7 @@ grub_terminfo_getkey (struct grub_term_input *termi) + int ret; + data->npending--; + ret = data->input_buf[0]; +-#ifdef __powerpc__ ++#if defined(__powerpc__) && defined(GRUB_MACHINE_IEEE1275) + if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_BROKEN_REPEAT)) + { + data->last_key = ret; +diff --git a/include/grub/terminfo.h b/include/grub/terminfo.h +index c081a92..20541a9 100644 +--- a/include/grub/terminfo.h ++++ b/include/grub/terminfo.h +@@ -32,7 +32,7 @@ struct grub_terminfo_input_state + { + int input_buf[GRUB_TERMINFO_READKEY_MAX_LEN]; + int npending; +-#ifdef __powerpc__ ++#if defined(__powerpc__) && defined(GRUB_MACHINE_IEEE1275) + int last_key; + grub_uint64_t last_key_time; + #endif +-- +1.8.1.4 + diff --git a/0039-util-grub-mkconfig_lib.in-grub_quote-Remove-outdated.patch b/0039-util-grub-mkconfig_lib.in-grub_quote-Remove-outdated.patch new file mode 100644 index 0000000..06e8739 --- /dev/null +++ b/0039-util-grub-mkconfig_lib.in-grub_quote-Remove-outdated.patch @@ -0,0 +1,44 @@ +From 7efa81764aa812d1f44ff53fb42472befea19f0b Mon Sep 17 00:00:00 2001 +From: Colin Watson +Date: Mon, 17 Sep 2012 16:58:50 +0100 +Subject: [PATCH 039/364] * util/grub-mkconfig_lib.in (grub_quote): Remove + outdated sentence from comment. + +--- + ChangeLog | 5 +++++ + util/grub-mkconfig_lib.in | 6 ++---- + 2 files changed, 7 insertions(+), 4 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 941ed93..de80a94 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,8 @@ ++2012-09-17 Colin Watson ++ ++ * util/grub-mkconfig_lib.in (grub_quote): Remove outdated sentence ++ from comment. ++ + 2012-09-14 Colin Watson + + * grub-core/term/terminfo.c: Only fix up powerpc key repeat on +diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in +index beb52ee..a9f5809 100644 +--- a/util/grub-mkconfig_lib.in ++++ b/util/grub-mkconfig_lib.in +@@ -255,10 +255,8 @@ version_find_latest () + echo "$version_find_latest_a" + } + +-# One layer of quotation is eaten by "" and the second by +-# sed; so this turns ' into \'. Note that you must use the output of +-# this function in a printf format string. +- ++# One layer of quotation is eaten by "" and the second by sed; so this turns ++# ' into \'. + grub_quote () { + sed "s/'/'\\\\''/g" + } +-- +1.8.1.4 + diff --git a/0040-grub-core-loader-i386-linux.c-grub_cmd_linux-Fix-inc.patch b/0040-grub-core-loader-i386-linux.c-grub_cmd_linux-Fix-inc.patch new file mode 100644 index 0000000..7aed109 --- /dev/null +++ b/0040-grub-core-loader-i386-linux.c-grub_cmd_linux-Fix-inc.patch @@ -0,0 +1,42 @@ +From 1f5027bb0ec48851cc2f9c54552a6ec1f1145930 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Tue, 18 Sep 2012 11:44:29 +0200 +Subject: [PATCH 040/364] * grub-core/loader/i386/linux.c + (grub_cmd_linux): Fix incorrect le-conversion. Reported by: BURETTE, + Bernard. + +--- + ChangeLog | 6 ++++++ + grub-core/loader/i386/linux.c | 2 +- + 2 files changed, 7 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index de80a94..b524cf6 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,9 @@ ++2012-09-18 Vladimir Serbinenko ++ ++ * grub-core/loader/i386/linux.c (grub_cmd_linux): Fix incorrect ++ le-conversion. ++ Reported by: BURETTE, Bernard. ++ + 2012-09-17 Colin Watson + + * util/grub-mkconfig_lib.in (grub_quote): Remove outdated sentence +diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c +index d34b2f8..bcb037c 100644 +--- a/grub-core/loader/i386/linux.c ++++ b/grub-core/loader/i386/linux.c +@@ -839,7 +839,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + + #ifdef GRUB_MACHINE_EFI + #ifdef __x86_64__ +- if (grub_le_to_cpu16 (params->version < 0x0208) && ++ if (grub_le_to_cpu16 (params->version) < 0x0208 && + ((grub_addr_t) grub_efi_system_table >> 32) != 0) + return grub_error(GRUB_ERR_BAD_OS, + "kernel does not support 64-bit addressing"); +-- +1.8.1.4 + diff --git a/0041-grub-core-kern-ieee1275-cmain.c-grub_ieee1275_find_o.patch b/0041-grub-core-kern-ieee1275-cmain.c-grub_ieee1275_find_o.patch new file mode 100644 index 0000000..40b75f9 --- /dev/null +++ b/0041-grub-core-kern-ieee1275-cmain.c-grub_ieee1275_find_o.patch @@ -0,0 +1,121 @@ +From 731ae0c1c7c0458a257e75c55b7739881dc2d5ed Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Tue, 18 Sep 2012 11:52:19 +0200 +Subject: [PATCH 041/364] * grub-core/kern/ieee1275/cmain.c + (grub_ieee1275_find_options): Set + GRUB_IEEE1275_FLAG_CURSORONOFF_ANSI_BROKEN on mac. * + grub-core/term/ieee1275/console.c (grub_console_init_lately): Use + ieee1275-nocursor if GRUB_IEEE1275_FLAG_CURSORONOFF_ANSI_BROKEN is set. + * grub-core/term/terminfo.c (grub_terminfo_set_current): Add new type + ieee1275-nocursor. * include/grub/ieee1275/ieee1275.h + (grub_ieee1275_flag): New value + GRUB_IEEE1275_FLAG_CURSORONOFF_ANSI_BROKEN. + +--- + ChangeLog | 11 +++++++++++ + grub-core/kern/ieee1275/cmain.c | 1 + + grub-core/term/ieee1275/console.c | 3 ++- + grub-core/term/terminfo.c | 15 ++++++++++++--- + include/grub/ieee1275/ieee1275.h | 4 +++- + 5 files changed, 29 insertions(+), 5 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index b524cf6..3752a79 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,16 @@ + 2012-09-18 Vladimir Serbinenko + ++ * grub-core/kern/ieee1275/cmain.c (grub_ieee1275_find_options): Set ++ GRUB_IEEE1275_FLAG_CURSORONOFF_ANSI_BROKEN on mac. ++ * grub-core/term/ieee1275/console.c (grub_console_init_lately): Use ++ ieee1275-nocursor if GRUB_IEEE1275_FLAG_CURSORONOFF_ANSI_BROKEN is set. ++ * grub-core/term/terminfo.c (grub_terminfo_set_current): Add new type ++ ieee1275-nocursor. ++ * include/grub/ieee1275/ieee1275.h (grub_ieee1275_flag): New value ++ GRUB_IEEE1275_FLAG_CURSORONOFF_ANSI_BROKEN. ++ ++2012-09-18 Vladimir Serbinenko ++ + * grub-core/loader/i386/linux.c (grub_cmd_linux): Fix incorrect + le-conversion. + Reported by: BURETTE, Bernard. +diff --git a/grub-core/kern/ieee1275/cmain.c b/grub-core/kern/ieee1275/cmain.c +index dd04d39..789669a 100644 +--- a/grub-core/kern/ieee1275/cmain.c ++++ b/grub-core/kern/ieee1275/cmain.c +@@ -117,6 +117,7 @@ grub_ieee1275_find_options (void) + grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_BROKEN_ADDRESS_CELLS); + grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_NO_OFNET_SUFFIX); + grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_VIRT_TO_REAL_BROKEN); ++ grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_CURSORONOFF_ANSI_BROKEN); + break; + } + } +diff --git a/grub-core/term/ieee1275/console.c b/grub-core/term/ieee1275/console.c +index a8dfcff..93b81f4 100644 +--- a/grub-core/term/ieee1275/console.c ++++ b/grub-core/term/ieee1275/console.c +@@ -247,9 +247,10 @@ grub_console_init_lately (void) + + if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_ANSI)) + type = "dumb"; ++ else if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_CURSORONOFF_ANSI_BROKEN)) ++ type = "ieee1275-nocursor"; + else + type = "ieee1275"; +- + grub_terminfo_init (); + grub_terminfo_output_register (&grub_console_term_output, type); + } +diff --git a/grub-core/term/terminfo.c b/grub-core/term/terminfo.c +index d421e4e..a0f8d18 100644 +--- a/grub-core/term/terminfo.c ++++ b/grub-core/term/terminfo.c +@@ -143,7 +143,8 @@ grub_terminfo_set_current (struct grub_term_output *term, + return grub_errno; + } + +- if (grub_strcmp ("ieee1275", str) == 0) ++ if (grub_strcmp ("ieee1275", str) == 0 ++ || grub_strcmp ("ieee1275-nocursor", str) == 0) + { + data->name = grub_strdup ("ieee1275"); + data->gotoxy = grub_strdup ("\e[%i%p1%d;%p2%dH"); +@@ -153,8 +154,16 @@ grub_terminfo_set_current (struct grub_term_output *term, + data->cls = grub_strdup (" \e[2J"); + data->reverse_video_on = grub_strdup ("\e[7m"); + data->reverse_video_off = grub_strdup ("\e[m"); +- data->cursor_on = grub_strdup ("\e[?25h"); +- data->cursor_off = grub_strdup ("\e[?25l"); ++ if (grub_strcmp ("ieee1275", str) == 0) ++ { ++ data->cursor_on = grub_strdup ("\e[?25h"); ++ data->cursor_off = grub_strdup ("\e[?25l"); ++ } ++ else ++ { ++ data->cursor_on = 0; ++ data->cursor_off = 0; ++ } + data->setcolor = grub_strdup ("\e[3%p1%dm\e[4%p2%dm"); + return grub_errno; + } +diff --git a/include/grub/ieee1275/ieee1275.h b/include/grub/ieee1275/ieee1275.h +index 38a75fd..ee9b707 100644 +--- a/include/grub/ieee1275/ieee1275.h ++++ b/include/grub/ieee1275/ieee1275.h +@@ -123,7 +123,9 @@ enum grub_ieee1275_flag + + GRUB_IEEE1275_FLAG_VIRT_TO_REAL_BROKEN, + +- GRUB_IEEE1275_FLAG_BROKEN_REPEAT ++ GRUB_IEEE1275_FLAG_BROKEN_REPEAT, ++ ++ GRUB_IEEE1275_FLAG_CURSORONOFF_ANSI_BROKEN, + }; + + extern int EXPORT_FUNC(grub_ieee1275_test_flag) (enum grub_ieee1275_flag flag); +-- +1.8.1.4 + diff --git a/0042-util-grub-mkconfig_lib.in-grub_tab-New-variable.patch b/0042-util-grub-mkconfig_lib.in-grub_tab-New-variable.patch new file mode 100644 index 0000000..59ca7f4 --- /dev/null +++ b/0042-util-grub-mkconfig_lib.in-grub_tab-New-variable.patch @@ -0,0 +1,360 @@ +From f46ac5e6c44d2fed8dcd8451196e6141d89cd90d Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Tue, 18 Sep 2012 13:04:06 +0200 +Subject: [PATCH 042/364] * util/grub-mkconfig_lib.in (grub_tab): New + variable. (grub_add_tab): New function. * util/grub.d/10_hurd.in: + Replace \t with $grub_tab orgrub_add_tab. * util/grub.d/10_illumos.in: + Likewise. * util/grub.d/10_kfreebsd.in: Likewise. * + util/grub.d/10_linux.in: Likewise. * util/grub.d/10_netbsd.in: Likewise. + * util/grub.d/10_windows.in: Likewise. * util/grub.d/10_xnu.in: + Likewise. * util/grub.d/20_linux_xen.in: Likewise. * + util/grub.d/30_os-prober.in: Likewise. + +--- + ChangeLog | 14 ++++++++++++++ + util/grub-mkconfig_lib.in | 7 +++++++ + util/grub.d/10_hurd.in | 8 ++++---- + util/grub.d/10_illumos.in | 4 ++-- + util/grub.d/10_kfreebsd.in | 8 ++++---- + util/grub.d/10_linux.in | 8 ++++---- + util/grub.d/10_netbsd.in | 10 +++++----- + util/grub.d/10_windows.in | 6 +++--- + util/grub.d/10_xnu.in | 4 ++-- + util/grub.d/20_linux_xen.in | 6 +++--- + util/grub.d/30_os-prober.in | 20 ++++++++++---------- + 11 files changed, 58 insertions(+), 37 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 3752a79..32849c6 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,19 @@ + 2012-09-18 Vladimir Serbinenko + ++ * util/grub-mkconfig_lib.in (grub_tab): New variable. ++ (grub_add_tab): New function. ++ * util/grub.d/10_hurd.in: Replace \t with $grub_tab orgrub_add_tab. ++ * util/grub.d/10_illumos.in: Likewise. ++ * util/grub.d/10_kfreebsd.in: Likewise. ++ * util/grub.d/10_linux.in: Likewise. ++ * util/grub.d/10_netbsd.in: Likewise. ++ * util/grub.d/10_windows.in: Likewise. ++ * util/grub.d/10_xnu.in: Likewise. ++ * util/grub.d/20_linux_xen.in: Likewise. ++ * util/grub.d/30_os-prober.in: Likewise. ++ ++2012-09-18 Vladimir Serbinenko ++ + * grub-core/kern/ieee1275/cmain.c (grub_ieee1275_find_options): Set + GRUB_IEEE1275_FLAG_CURSORONOFF_ANSI_BROKEN on mac. + * grub-core/term/ieee1275/console.c (grub_console_init_lately): Use +diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in +index a9f5809..8f21eb2 100644 +--- a/util/grub-mkconfig_lib.in ++++ b/util/grub-mkconfig_lib.in +@@ -347,3 +347,10 @@ grub_fmt () { + cat + fi + } ++ ++grub_tab=" " ++ ++grub_add_tab () { ++ sed -e "s/^/$grub_tab/" ++} ++ +diff --git a/util/grub.d/10_hurd.in b/util/grub.d/10_hurd.in +index 45f0ad3..00efd68 100644 +--- a/util/grub.d/10_hurd.in ++++ b/util/grub.d/10_hurd.in +@@ -108,7 +108,7 @@ menuentry '$(echo "$OS" | grub_quote)' ${CLASS} \$menuentry_id_option 'gnuhurd-s + EOF + fi + +- prepare_grub_to_access_device "${GRUB_DEVICE_BOOT}" | sed -e "s/^/\t/"|sed "s/^/$submenu_indentation/" ++ prepare_grub_to_access_device "${GRUB_DEVICE_BOOT}" | grub_add_tab|sed "s/^/$submenu_indentation/" + message="$(gettext_printf "Loading GNU Mach ...")" + + if [ x$type = xrecovery ] ; then +@@ -122,9 +122,9 @@ EOF + EOF + + if [ x$type != xrecovery ] ; then +- save_default_entry | sed -e "s/^/\t/"| sed "s/^/$submenu_indentation/" ++ save_default_entry | grub_add_tab| sed "s/^/$submenu_indentation/" + fi +- prepare_grub_to_access_device "${GRUB_DEVICE}" | sed -e "s/^/\t/"| sed "s/^/$submenu_indentation/" ++ prepare_grub_to_access_device "${GRUB_DEVICE}" | grub_add_tab| sed "s/^/$submenu_indentation/" + message="$(gettext_printf "Loading the Hurd ...")" + if [ x$type = xrecovery ] ; then + opts= +@@ -158,7 +158,7 @@ do + + if [ "x$is_first_entry" = xtrue ]; then + hurd_entry "$kernel" simple +- submenu_indentation="\t" ++ submenu_indentation="$grub_tab" + + # TRANSLATORS: %s is replaced with an OS name + echo "submenu '$(gettext_printf "Advanced options for %s" "${OS}" | grub_quote)' \$menuentry_id_option 'gnuhurd-advanced-$(grub_get_device_id "${GRUB_DEVICE_BOOT}")' {" +diff --git a/util/grub.d/10_illumos.in b/util/grub.d/10_illumos.in +index 2477466..0de616e 100644 +--- a/util/grub.d/10_illumos.in ++++ b/util/grub.d/10_illumos.in +@@ -35,8 +35,8 @@ case "${GRUB_DISTRIBUTOR}" in + esac + + echo "menuentry '$(echo "$OS" | grub_quote)' ${CLASS} \$menuentry_id_option 'illumos-$(grub_get_device_id "${GRUB_DEVICE_BOOT}")' {" +-save_default_entry | sed -e "s/^/\t/" +-prepare_grub_to_access_device "${GRUB_DEVICE_BOOT}" | sed -e "s/^/\t/" ++save_default_entry | grub_add_tab ++prepare_grub_to_access_device "${GRUB_DEVICE_BOOT}" | grub_add_tab + message="$(gettext_printf "Loading kernel of Illumos ...")" + cat << EOF + insmod gzio +diff --git a/util/grub.d/10_kfreebsd.in b/util/grub.d/10_kfreebsd.in +index b0e84e2..260dda8 100644 +--- a/util/grub.d/10_kfreebsd.in ++++ b/util/grub.d/10_kfreebsd.in +@@ -54,7 +54,7 @@ load_kfreebsd_module () + fi + + if [ -z "${prepare_module_dir_cache}" ]; then +- prepare_module_dir_cache="$(prepare_grub_to_access_device $(grub-probe -t device "${module_dir}") | sed -e "s/^/\t/")" ++ prepare_module_dir_cache="$(prepare_grub_to_access_device $(grub-probe -t device "${module_dir}") | grub_add_tab)" + fi + + printf '%s\n' "${prepare_module_dir_cache}" +@@ -91,10 +91,10 @@ kfreebsd_entry () + echo "menuentry '$(echo "$OS" | grub_quote)' ${CLASS} \$menuentry_id_option 'kfreebsd-simple-$boot_device_id' {" | sed "s/^/$submenu_indentation/" + fi + if [ x$type != xrecovery ] ; then +- save_default_entry | sed -e "s/^/\t/" | sed "s/^/$submenu_indentation/" ++ save_default_entry | grub_add_tab | sed "s/^/$submenu_indentation/" + fi + if [ -z "${prepare_boot_cache}" ]; then +- prepare_boot_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/")" ++ prepare_boot_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | grub_add_tab)" + fi + + printf '%s\n' "${prepare_boot_cache}" | sed "s/^/$submenu_indentation/" +@@ -213,7 +213,7 @@ while [ "x$list" != "x" ] ; do + + if [ "x$is_first_entry" = xtrue ]; then + kfreebsd_entry "${OS}" "${version}" simple +- submenu_indentation="\t" ++ submenu_indentation="$grub_tab" + + if [ -z "$boot_device_id" ]; then + boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")" +diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in +index 35f7a83..0724e16 100644 +--- a/util/grub.d/10_linux.in ++++ b/util/grub.d/10_linux.in +@@ -101,7 +101,7 @@ linux_entry () + echo "menuentry '$(echo "$os" | grub_quote)' ${CLASS} \$menuentry_id_option 'gnulinux-simple-$boot_device_id' {" | sed "s/^/$submenu_indentation/" + fi + if [ x$type != xrecovery ] ; then +- save_default_entry | sed -e "s/^/\t/" ++ save_default_entry | grub_add_tab + fi + + # Use ELILO's generic "efifb" when it's known to be available. +@@ -123,12 +123,12 @@ linux_entry () + + if [ x$dirname = x/ ]; then + if [ -z "${prepare_root_cache}" ]; then +- prepare_root_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE} | sed -e "s/^/\t/")" ++ prepare_root_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE} | grub_add_tab)" + fi + printf '%s\n' "${prepare_root_cache}" | sed "s/^/$submenu_indentation/" + else + if [ -z "${prepare_boot_cache}" ]; then +- prepare_boot_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/")" ++ prepare_boot_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | grub_add_tab)" + fi + printf '%s\n' "${prepare_boot_cache}" | sed "s/^/$submenu_indentation/" + fi +@@ -230,7 +230,7 @@ while [ "x$list" != "x" ] ; do + linux_entry "${OS}" "${version}" simple \ + "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}" + +- submenu_indentation="\t" ++ submenu_indentation="$grub_tab" + + if [ -z "$boot_device_id" ]; then + boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")" +diff --git a/util/grub.d/10_netbsd.in b/util/grub.d/10_netbsd.in +index 65275d7..b76332b 100644 +--- a/util/grub.d/10_netbsd.in ++++ b/util/grub.d/10_netbsd.in +@@ -77,10 +77,10 @@ netbsd_load_fs_module () + prepare_grub_to_access_device $(${grub_probe} -t device "${kmodule}") | sed -e 's,^, ,' + case "${loader}" in + knetbsd) +- printf "\tknetbsd_module_elf %s\n" "${kmodule_rel}" ++ printf "$grub_tabknetbsd_module_elf %s\n" "${kmodule_rel}" + ;; + multiboot) +- printf "\tmodule %s\n" "${kmodule_rel}" ++ printf "$grub_tabmodule %s\n" "${kmodule_rel}" + ;; + esac + } +@@ -121,11 +121,11 @@ netbsd_entry () + printf "%s\n" "${prepare_boot_cache}" | sed "s/^/$submenu_indentation/" + case "${loader}" in + knetbsd) +- printf "\tknetbsd %s -r %s %s\n" \ ++ printf "$grub_tabknetbsd %s -r %s %s\n" \ + "${kernel}" "${kroot_device}" "${GRUB_CMDLINE_NETBSD} ${args}" | sed "s/^/$submenu_indentation/" + ;; + multiboot) +- printf "\tmultiboot %s %s root=%s %s\n" \ ++ printf "$grub_tabmultiboot %s %s root=%s %s\n" \ + "${kernel}" "${kernel}" "${kroot_device}" "${GRUB_CMDLINE_NETBSD} ${args}" | sed "s/^/$submenu_indentation/" + ;; + esac +@@ -159,7 +159,7 @@ for k in $(ls -t /netbsd*) ; do + + if [ "x$is_first_entry" = xtrue ]; then + netbsd_entry "knetbsd" "$k" simple "${GRUB_CMDLINE_NETBSD_DEFAULT}" +- submenu_indentation="\t" ++ submenu_indentation="$grub_tab" + + if [ -z "$boot_device_id" ]; then + boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")" +diff --git a/util/grub.d/10_windows.in b/util/grub.d/10_windows.in +index e5839cd..9025914 100644 +--- a/util/grub.d/10_windows.in ++++ b/util/grub.d/10_windows.in +@@ -45,7 +45,7 @@ get_os_name_from_boot_ini () + sort | uniq | wc -l`" = 1 || return 1 + + # Search 'default=PARTITION' +- get_os_name_from_boot_ini_part=`sed -n 's,^default=,,p' "$1" | sed 's,\\\\,/,g;s,[ \t\r]*$,,;1q'` ++ get_os_name_from_boot_ini_part=`sed -n 's,^default=,,p' "$1" | sed 's,\\\\,/,g;s,[ $grub_tab\r]*$,,;1q'` + test -n "$get_os_name_from_boot_ini_part" || return 1 + + # Search 'PARTITION="NAME" ...' +@@ -87,8 +87,8 @@ for drv in $drives ; do + menuentry '$(echo "$OS" | grub_quote)' \$menuentry_id_option '$osid-$(grub_get_device_id "${dev}")' { + EOF + +- save_default_entry | sed -e 's,^,\t,' +- prepare_grub_to_access_device "$dev" | sed 's,^,\t,' ++ save_default_entry | sed -e 's,^,$grub_tab,' ++ prepare_grub_to_access_device "$dev" | sed 's,^,$grub_tab,' + test -z "$needmap" || cat < +Date: Wed, 19 Sep 2012 02:41:51 +0100 +Subject: [PATCH 043/364] * util/grub-setup.c (write_rootdev): Remove unused + core_img parameter. Update all callers. (setup): Define core_sectors only if + GRUB_SETUP_BIOS, to appease 'gcc -Wunused-but-set-variable'. Remove + unnecessary nested #ifdef GRUB_SETUP_BIOS. + +--- + ChangeLog | 10 +++++++++- + util/grub-setup.c | 12 +++++++----- + 2 files changed, 16 insertions(+), 6 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 32849c6..1ab401d 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,11 @@ ++2012-09-19 Colin Watson ++ ++ * util/grub-setup.c (write_rootdev): Remove unused core_img ++ parameter. Update all callers. ++ (setup): Define core_sectors only if GRUB_SETUP_BIOS, to appease ++ 'gcc -Wunused-but-set-variable'. Remove unnecessary nested #ifdef ++ GRUB_SETUP_BIOS. ++ + 2012-09-18 Vladimir Serbinenko + + * util/grub-mkconfig_lib.in (grub_tab): New variable. +@@ -29,7 +37,7 @@ + le-conversion. + Reported by: BURETTE, Bernard. + +-2012-09-17 Colin Watson ++2012-09-17 Colin Watson + + * util/grub-mkconfig_lib.in (grub_quote): Remove outdated sentence + from comment. +diff --git a/util/grub-setup.c b/util/grub-setup.c +index 085e8df..de0417f 100644 +--- a/util/grub-setup.c ++++ b/util/grub-setup.c +@@ -105,7 +105,7 @@ + #endif + + static void +-write_rootdev (char *core_img, grub_device_t root_dev, ++write_rootdev (grub_device_t root_dev, + char *boot_img, grub_uint64_t first_sector) + { + #ifdef GRUB_SETUP_BIOS +@@ -148,7 +148,9 @@ setup (const char *dir, + char *boot_img, *core_img; + char *root = 0; + size_t boot_size, core_size; ++#ifdef GRUB_SETUP_BIOS + grub_uint16_t core_sectors; ++#endif + grub_device_t root_dev = 0, dest_dev, core_dev; + struct grub_boot_blocklist *first_block, *block; + char *tmp_img; +@@ -229,8 +231,10 @@ setup (const char *dir, + + core_path = grub_util_get_path (dir, core_file); + core_size = grub_util_get_image_size (core_path); ++#ifdef GRUB_SETUP_BIOS + core_sectors = ((core_size + GRUB_DISK_SECTOR_SIZE - 1) + >> GRUB_DISK_SECTOR_BITS); ++#endif + if (core_size < GRUB_DISK_SECTOR_SIZE) + grub_util_error (_("the size of `%s' is too small"), core_path); + #ifdef GRUB_SETUP_BIOS +@@ -386,7 +390,6 @@ setup (const char *dir, + + is_ldm = grub_util_is_ldm (dest_dev->disk); + +-#ifdef GRUB_SETUP_BIOS + if (fs_probe) + { + if (!fs && !dest_partmap) +@@ -424,7 +427,6 @@ setup (const char *dir, + dest_dev->disk->name, dest_partmap->name); + + } +-#endif + + /* Copy the partition table. */ + if (dest_partmap || +@@ -520,7 +522,7 @@ setup (const char *dir, + block->len = 0; + block->segment = 0; + +- write_rootdev (core_img, root_dev, boot_img, first_sector); ++ write_rootdev (root_dev, boot_img, first_sector); + + core_img = realloc (core_img, nsec * GRUB_DISK_SECTOR_SIZE); + first_block = (struct grub_boot_blocklist *) (core_img +@@ -858,7 +860,7 @@ unable_to_embed: + free (core_path_dev); + free (tmp_img); + +- write_rootdev (core_img, root_dev, boot_img, first_sector); ++ write_rootdev (root_dev, boot_img, first_sector); + + /* Write the first two sectors of the core image onto the disk. */ + grub_util_info ("opening the core image `%s'", core_path); +-- +1.8.1.4 + diff --git a/0044-grub-core-partmap-msdos.c-pc_partition_map_embed-Rev.patch b/0044-grub-core-partmap-msdos.c-pc_partition_map_embed-Rev.patch new file mode 100644 index 0000000..9a1d8cd --- /dev/null +++ b/0044-grub-core-partmap-msdos.c-pc_partition_map_embed-Rev.patch @@ -0,0 +1,52 @@ +From fbc6f5faf45f489125f98a11f3593cd43b4d6b76 Mon Sep 17 00:00:00 2001 +From: Colin Watson +Date: Wed, 19 Sep 2012 02:44:54 +0100 +Subject: [PATCH 044/364] * grub-core/partmap/msdos.c (pc_partition_map_embed): + Revert incorrect off-by-one fix from 2011-02-12. A 62-sector core image + should fit before end == 63. + +--- + ChangeLog | 6 ++++++ + grub-core/partmap/msdos.c | 4 ++-- + 2 files changed, 8 insertions(+), 2 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 1ab401d..5db804e 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,11 @@ + 2012-09-19 Colin Watson + ++ * grub-core/partmap/msdos.c (pc_partition_map_embed): Revert ++ incorrect off-by-one fix from 2011-02-12. A 62-sector core image ++ should fit before end == 63. ++ ++2012-09-19 Colin Watson ++ + * util/grub-setup.c (write_rootdev): Remove unused core_img + parameter. Update all callers. + (setup): Define core_sectors only if GRUB_SETUP_BIOS, to appease +diff --git a/grub-core/partmap/msdos.c b/grub-core/partmap/msdos.c +index 6e54a74..10ca3f0 100644 +--- a/grub-core/partmap/msdos.c ++++ b/grub-core/partmap/msdos.c +@@ -316,14 +316,14 @@ pc_partition_map_embed (struct grub_disk *disk, unsigned int *nsectors, + break; + } + +- if (end >= *nsectors + 2) ++ if (end >= *nsectors + 1) + { + unsigned i, j; + char *embed_signature_check; + unsigned int orig_nsectors, avail_nsectors; + + orig_nsectors = *nsectors; +- *nsectors = end - 2; ++ *nsectors = end - 1; + avail_nsectors = *nsectors; + if (*nsectors > max_nsectors) + *nsectors = max_nsectors; +-- +1.8.1.4 + diff --git a/0045-Fix-grub-emu-build-on-FreeBSD.patch b/0045-Fix-grub-emu-build-on-FreeBSD.patch new file mode 100644 index 0000000..0435e06 --- /dev/null +++ b/0045-Fix-grub-emu-build-on-FreeBSD.patch @@ -0,0 +1,125 @@ +From b37a32bb89c476b0ead4c40900de29fe8d73d27e Mon Sep 17 00:00:00 2001 +From: Colin Watson +Date: Sat, 22 Sep 2012 21:19:58 +0100 +Subject: [PATCH 045/364] Fix grub-emu build on FreeBSD. + +* Makefile.util.def (grub-mount): Add LIBGEOM to ldadd. +* grub-core/net/drivers/emu/emunet.c: Only include Linux-specific +headers on Linux. +(GRUB_MOD_INIT): Return immediately on non-Linux platforms; this +implementation is currently Linux-specific. +* util/getroot.c (exec_pipe): Define only on Linux or when either +libzfs or libnvpair is unavailable. +(find_root_devices_from_poolname): Remove unused path variable. +--- + ChangeLog | 13 +++++++++++++ + Makefile.util.def | 2 +- + grub-core/net/drivers/emu/emunet.c | 11 +++++++++-- + util/getroot.c | 7 ++++++- + 4 files changed, 29 insertions(+), 4 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 5db804e..3eda38f 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,16 @@ ++2012-09-22 Colin Watson ++ ++ Fix grub-emu build on FreeBSD. ++ ++ * Makefile.util.def (grub-mount): Add LIBGEOM to ldadd. ++ * grub-core/net/drivers/emu/emunet.c: Only include Linux-specific ++ headers on Linux. ++ (GRUB_MOD_INIT): Return immediately on non-Linux platforms; this ++ implementation is currently Linux-specific. ++ * util/getroot.c (exec_pipe): Define only on Linux or when either ++ libzfs or libnvpair is unavailable. ++ (find_root_devices_from_poolname): Remove unused path variable. ++ + 2012-09-19 Colin Watson + + * grub-core/partmap/msdos.c (pc_partition_map_embed): Revert +diff --git a/Makefile.util.def b/Makefile.util.def +index b80187c..72057cf 100644 +--- a/Makefile.util.def ++++ b/Makefile.util.def +@@ -266,7 +266,7 @@ program = { + ldadd = libgrubgcry.a; + ldadd = libgrubkern.a; + ldadd = grub-core/gnulib/libgnu.a; +- ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) -lfuse'; ++ ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM) -lfuse'; + condition = COND_GRUB_MOUNT; + }; + +diff --git a/grub-core/net/drivers/emu/emunet.c b/grub-core/net/drivers/emu/emunet.c +index 7a7aeaf..6b533dd 100644 +--- a/grub-core/net/drivers/emu/emunet.c ++++ b/grub-core/net/drivers/emu/emunet.c +@@ -21,8 +21,10 @@ + #include + #include + #include +-#include +-#include ++#ifdef __linux__ ++# include ++# include ++#endif /* __linux__ */ + #include + #include + #include +@@ -97,6 +99,7 @@ static struct grub_net_card emucard = + + GRUB_MOD_INIT(emunet) + { ++#ifdef __linux__ + struct ifreq ifr; + fd = open ("/dev/net/tun", O_RDWR | O_NONBLOCK); + if (fd < 0) +@@ -110,6 +113,10 @@ GRUB_MOD_INIT(emunet) + return; + } + grub_net_card_register (&emucard); ++#else /* !__linux__ */ ++ fd = -1; ++ return; ++#endif /* __linux__ */ + } + + GRUB_MOD_FINI(emunet) +diff --git a/util/getroot.c b/util/getroot.c +index b97bea6..c2a25c9 100644 +--- a/util/getroot.c ++++ b/util/getroot.c +@@ -220,6 +220,9 @@ xgetcwd (void) + + #if !defined (__MINGW32__) && !defined (__CYGWIN__) && !defined (__GNU__) + ++#if (defined (__linux__) || \ ++ !defined (HAVE_LIBZFS) || !defined (HAVE_LIBNVPAIR)) ++ + static pid_t + exec_pipe (char **argv, int *fd) + { +@@ -258,6 +261,8 @@ exec_pipe (char **argv, int *fd) + } + } + ++#endif ++ + static char ** + find_root_devices_from_poolname (char *poolname) + { +@@ -269,7 +274,7 @@ find_root_devices_from_poolname (char *poolname) + zpool_handle_t *zpool; + libzfs_handle_t *libzfs; + nvlist_t *config, *vdev_tree; +- nvlist_t **children, **path; ++ nvlist_t **children; + unsigned int nvlist_count; + unsigned int i; + char *device = 0; +-- +1.8.1.4 + diff --git a/0046-util-grub-install.in-Make-the-error-message-if-sourc.patch b/0046-util-grub-install.in-Make-the-error-message-if-sourc.patch new file mode 100644 index 0000000..18589b3 --- /dev/null +++ b/0046-util-grub-install.in-Make-the-error-message-if-sourc.patch @@ -0,0 +1,40 @@ +From e6f215afa8ff4d586f71276fc12ea14eb1e6cd8b Mon Sep 17 00:00:00 2001 +From: Colin Watson +Date: Mon, 24 Sep 2012 18:50:35 +0100 +Subject: [PATCH 046/364] * util/grub-install.in: Make the error message if + $source_dir doesn't exist more useful. + +--- + ChangeLog | 5 +++++ + util/grub-install.in | 2 +- + 2 files changed, 6 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index 3eda38f..a53c5cc 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,8 @@ ++2012-09-24 Colin Watson ++ ++ * util/grub-install.in: Make the error message if $source_dir ++ doesn't exist more useful. ++ + 2012-09-22 Colin Watson + + Fix grub-emu build on FreeBSD. +diff --git a/util/grub-install.in b/util/grub-install.in +index e19f1cd..56be98f 100644 +--- a/util/grub-install.in ++++ b/util/grub-install.in +@@ -330,7 +330,7 @@ if [ x$source_dir = x ]; then + fi + + if ! [ -d "$source_dir" ]; then +- gettext_printf "%s doesn't exist. Please specify --target or --directory\\n" "source_dir" ++ gettext_printf "%s doesn't exist. Please specify --target or --directory\\n" "$source_dir" + exit 1 + fi + +-- +1.8.1.4 + diff --git a/0047-grub-core-fs-affs.c-grub_affs_mount-Support-AFFS-boo.patch b/0047-grub-core-fs-affs.c-grub_affs_mount-Support-AFFS-boo.patch new file mode 100644 index 0000000..2efb824 --- /dev/null +++ b/0047-grub-core-fs-affs.c-grub_affs_mount-Support-AFFS-boo.patch @@ -0,0 +1,202 @@ +From d36c4c3115977beb5f9247c6c6f0a2a209389f45 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Wed, 26 Sep 2012 09:33:41 +0200 +Subject: [PATCH 047/364] * grub-core/fs/affs.c (grub_affs_mount): + Support AFFS bootblock in sector 1. + +--- + ChangeLog | 5 ++ + grub-core/fs/affs.c | 139 ++++++++++++++++++++++++++-------------------------- + 2 files changed, 74 insertions(+), 70 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index a53c5cc..d81a9a6 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,8 @@ ++2012-09-26 Vladimir Serbinenko ++ ++ * grub-core/fs/affs.c (grub_affs_mount): Support AFFS bootblock in ++ sector 1. ++ + 2012-09-24 Colin Watson + + * util/grub-install.in: Make the error message if $source_dir +diff --git a/grub-core/fs/affs.c b/grub-core/fs/affs.c +index ef65479..848a455 100644 +--- a/grub-core/fs/affs.c ++++ b/grub-core/fs/affs.c +@@ -97,6 +97,7 @@ enum + }; + + #define AFFS_MAX_LOG_BLOCK_SIZE 4 ++#define AFFS_MAX_SUPERBLOCK 1 + + + +@@ -184,94 +185,92 @@ grub_affs_mount (grub_disk_t disk) + { + struct grub_affs_data *data; + grub_uint32_t *rootblock = 0; +- struct grub_affs_rblock *rblock; ++ struct grub_affs_rblock *rblock = 0; + int log_blocksize = 0; ++ int bsnum = 0; + + data = grub_zalloc (sizeof (struct grub_affs_data)); + if (!data) + return 0; + +- /* Read the bootblock. */ +- grub_disk_read (disk, 0, 0, sizeof (struct grub_affs_bblock), +- &data->bblock); +- if (grub_errno) +- goto fail; +- +- /* Make sure this is an affs filesystem. */ +- if (grub_strncmp ((char *) (data->bblock.type), "DOS", 3)) +- { +- grub_error (GRUB_ERR_BAD_FS, "not an AFFS filesystem"); +- goto fail; +- } +- +- /* Test if the filesystem is a OFS filesystem. */ +- if (! (data->bblock.flags & GRUB_AFFS_FLAG_FFS)) +- { +- grub_error (GRUB_ERR_BAD_FS, "OFS not yet supported"); +- goto fail; +- } +- +- /* No sane person uses more than 8KB for a block. At least I hope +- for that person because in that case this won't work. */ +- rootblock = grub_malloc (GRUB_DISK_SECTOR_SIZE << AFFS_MAX_LOG_BLOCK_SIZE); +- if (!rootblock) +- goto fail; +- +- rblock = (struct grub_affs_rblock *) rootblock; +- +- /* The filesystem blocksize is not stored anywhere in the filesystem +- itself. One way to determine it is try reading blocks for the +- rootblock until the checksum is correct. */ +- for (log_blocksize = 0; log_blocksize <= AFFS_MAX_LOG_BLOCK_SIZE; +- log_blocksize++) ++ for (bsnum = 0; bsnum < AFFS_MAX_SUPERBLOCK + 1; bsnum++) + { +- grub_uint32_t *currblock = rootblock; +- unsigned int i; +- grub_uint32_t checksum = 0; +- +- /* Read the rootblock. */ +- grub_disk_read (disk, +- (grub_uint64_t) grub_be_to_cpu32 (data->bblock.rootblock) +- << log_blocksize, 0, +- GRUB_DISK_SECTOR_SIZE << log_blocksize, rootblock); ++ /* Read the bootblock. */ ++ grub_disk_read (disk, bsnum, 0, sizeof (struct grub_affs_bblock), ++ &data->bblock); + if (grub_errno) + goto fail; + +- if (rblock->type != grub_cpu_to_be32_compile_time (2) +- || rblock->htsize == 0 +- || currblock[(GRUB_DISK_SECTOR_SIZE << log_blocksize) +- / sizeof (*currblock) - 1] +- != grub_cpu_to_be32_compile_time (1)) ++ /* Make sure this is an affs filesystem. */ ++ if (grub_strncmp ((char *) (data->bblock.type), "DOS", 3) != 0 ++ /* Test if the filesystem is a OFS filesystem. */ ++ || !(data->bblock.flags & GRUB_AFFS_FLAG_FFS)) + continue; + +- for (i = 0; i < (GRUB_DISK_SECTOR_SIZE << log_blocksize) +- / sizeof (*currblock); +- i++) +- checksum += grub_be_to_cpu32 (currblock[i]); ++ /* No sane person uses more than 8KB for a block. At least I hope ++ for that person because in that case this won't work. */ ++ if (!rootblock) ++ rootblock = grub_malloc (GRUB_DISK_SECTOR_SIZE ++ << AFFS_MAX_LOG_BLOCK_SIZE); ++ if (!rootblock) ++ goto fail; + +- if (checksum == 0) +- break; +- } +- if (log_blocksize > AFFS_MAX_LOG_BLOCK_SIZE) +- { +- grub_error (GRUB_ERR_BAD_FS, "AFFS blocksize couldn't be determined"); +- goto fail; +- } ++ rblock = (struct grub_affs_rblock *) rootblock; ++ ++ /* The filesystem blocksize is not stored anywhere in the filesystem ++ itself. One way to determine it is try reading blocks for the ++ rootblock until the checksum is correct. */ ++ for (log_blocksize = 0; log_blocksize <= AFFS_MAX_LOG_BLOCK_SIZE; ++ log_blocksize++) ++ { ++ grub_uint32_t *currblock = rootblock; ++ unsigned int i; ++ grub_uint32_t checksum = 0; ++ ++ /* Read the rootblock. */ ++ grub_disk_read (disk, ++ (grub_uint64_t) grub_be_to_cpu32 (data->bblock.rootblock) ++ << log_blocksize, 0, ++ GRUB_DISK_SECTOR_SIZE << log_blocksize, rootblock); ++ if (grub_errno == GRUB_ERR_OUT_OF_RANGE) ++ { ++ grub_errno = 0; ++ break; ++ } ++ if (grub_errno) ++ goto fail; + +- data->log_blocksize = log_blocksize; +- data->disk = disk; +- data->htsize = grub_be_to_cpu32 (rblock->htsize); +- data->diropen.data = data; +- data->diropen.block = grub_be_to_cpu32 (data->bblock.rootblock); +- data->diropen.parent = NULL; +- grub_memcpy (&data->diropen.di, rootblock, sizeof (data->diropen.di)); ++ if (rblock->type != grub_cpu_to_be32_compile_time (2) ++ || rblock->htsize == 0 ++ || currblock[(GRUB_DISK_SECTOR_SIZE << log_blocksize) ++ / sizeof (*currblock) - 1] ++ != grub_cpu_to_be32_compile_time (1)) ++ continue; + +- grub_free (rootblock); ++ for (i = 0; i < (GRUB_DISK_SECTOR_SIZE << log_blocksize) ++ / sizeof (*currblock); ++ i++) ++ checksum += grub_be_to_cpu32 (currblock[i]); + +- return data; ++ if (checksum == 0) ++ { ++ data->log_blocksize = log_blocksize; ++ data->disk = disk; ++ data->htsize = grub_be_to_cpu32 (rblock->htsize); ++ data->diropen.data = data; ++ data->diropen.block = grub_be_to_cpu32 (data->bblock.rootblock); ++ data->diropen.parent = NULL; ++ grub_memcpy (&data->diropen.di, rootblock, ++ sizeof (data->diropen.di)); ++ grub_free (rootblock); ++ ++ return data; ++ } ++ } ++ } + + fail: +- if (grub_errno == GRUB_ERR_OUT_OF_RANGE) ++ if (grub_errno == GRUB_ERR_NONE || grub_errno == GRUB_ERR_OUT_OF_RANGE) + grub_error (GRUB_ERR_BAD_FS, "not an AFFS filesystem"); + + grub_free (data); +-- +1.8.1.4 + diff --git a/0048-util-grub-mkconfig_lib.in-is_path_readable_by_grub-R.patch b/0048-util-grub-mkconfig_lib.in-is_path_readable_by_grub-R.patch new file mode 100644 index 0000000..c72e63b --- /dev/null +++ b/0048-util-grub-mkconfig_lib.in-is_path_readable_by_grub-R.patch @@ -0,0 +1,41 @@ +From 9196249442d3d9b360b77a5bd35ffb6c49935c78 Mon Sep 17 00:00:00 2001 +From: Colin Watson +Date: Wed, 26 Sep 2012 13:12:20 +0100 +Subject: [PATCH 048/364] * util/grub-mkconfig_lib.in + (is_path_readable_by_grub): Redirect errors from grub-probe to /dev/null, not + stdout. + +--- + ChangeLog | 5 +++++ + util/grub-mkconfig_lib.in | 2 +- + 2 files changed, 6 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index d81a9a6..c43f8a4 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,8 @@ ++2012-09-26 Colin Watson ++ ++ * util/grub-mkconfig_lib.in (is_path_readable_by_grub): Redirect ++ errors from grub-probe to /dev/null, not stdout. ++ + 2012-09-26 Vladimir Serbinenko + + * grub-core/fs/affs.c (grub_affs_mount): Support AFFS bootblock in +diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in +index 8f21eb2..3574839 100644 +--- a/util/grub-mkconfig_lib.in ++++ b/util/grub-mkconfig_lib.in +@@ -65,7 +65,7 @@ is_path_readable_by_grub () + + # ... or if we can't figure out the abstraction module, for example if + # memberlist fails on an LVM volume group. +- if abstractions="`"${grub_probe}" -t abstraction "$path"`" 2>&1 ; then ++ if abstractions="`"${grub_probe}" -t abstraction "$path"`" 2> /dev/null ; then + : + else + return 1 +-- +1.8.1.4 + diff --git a/0049-Makefile.util.def-grub-mknetdir-Move-to-prefix-bin.patch b/0049-Makefile.util.def-grub-mknetdir-Move-to-prefix-bin.patch new file mode 100644 index 0000000..ef96dbc --- /dev/null +++ b/0049-Makefile.util.def-grub-mknetdir-Move-to-prefix-bin.patch @@ -0,0 +1,44 @@ +From 42593e7230fad9f87732c1687cb5daff918f2fa1 Mon Sep 17 00:00:00 2001 +From: Colin Watson +Date: Wed, 26 Sep 2012 13:51:13 +0100 +Subject: [PATCH 049/364] * Makefile.util.def (grub-mknetdir): Move to + $prefix/bin. Reported by: Daniel Kahn Gillmor. Fixes Debian bug #688799. + +--- + ChangeLog | 5 +++++ + Makefile.util.def | 4 ++-- + 2 files changed, 7 insertions(+), 2 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index c43f8a4..2658573 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,10 @@ + 2012-09-26 Colin Watson + ++ * Makefile.util.def (grub-mknetdir): Move to $prefix/bin. ++ Reported by: Daniel Kahn Gillmor. Fixes Debian bug #688799. ++ ++2012-09-26 Colin Watson ++ + * util/grub-mkconfig_lib.in (is_path_readable_by_grub): Redirect + errors from grub-probe to /dev/null, not stdout. + +diff --git a/Makefile.util.def b/Makefile.util.def +index 72057cf..8324ede 100644 +--- a/Makefile.util.def ++++ b/Makefile.util.def +@@ -487,8 +487,8 @@ script = { + }; + + script = { +- mansection = 8; +- installdir = sbin; ++ mansection = 1; ++ installdir = bin; + name = grub-mknetdir; + + common = util/grub-mknetdir.in; +-- +1.8.1.4 + diff --git a/0050-grub-core-loader-i386-linux.c-allocate_pages-Fix-spe.patch b/0050-grub-core-loader-i386-linux.c-allocate_pages-Fix-spe.patch new file mode 100644 index 0000000..0acc26a --- /dev/null +++ b/0050-grub-core-loader-i386-linux.c-allocate_pages-Fix-spe.patch @@ -0,0 +1,132 @@ +From 8c38cb1283a0cf1c8eae465bff26e0ca966ac43a Mon Sep 17 00:00:00 2001 +From: Colin Watson +Date: Fri, 5 Oct 2012 13:09:19 +0100 +Subject: [PATCH 050/364] * grub-core/loader/i386/linux.c (allocate_pages): Fix + spelling of preferred_address. (grub_cmd_linux): Likewise. * + grub-core/net/icmp6.c (struct prefix_option): Fix spelling of + preferred_lifetime. Update all users. + +--- + ChangeLog | 8 ++++++++ + grub-core/loader/i386/linux.c | 18 +++++++++--------- + grub-core/net/icmp6.c | 6 +++--- + 3 files changed, 20 insertions(+), 12 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 2658573..d0aeab6 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,11 @@ ++2012-10-05 Colin Watson ++ ++ * grub-core/loader/i386/linux.c (allocate_pages): Fix spelling of ++ preferred_address. ++ (grub_cmd_linux): Likewise. ++ * grub-core/net/icmp6.c (struct prefix_option): Fix spelling of ++ preferred_lifetime. Update all users. ++ + 2012-09-26 Colin Watson + + * Makefile.util.def (grub-mknetdir): Move to $prefix/bin. +diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c +index bcb037c..fc0ebe7 100644 +--- a/grub-core/loader/i386/linux.c ++++ b/grub-core/loader/i386/linux.c +@@ -191,7 +191,7 @@ free_pages (void) + static grub_err_t + allocate_pages (grub_size_t prot_size, grub_size_t *align, + grub_size_t min_align, int relocatable, +- grub_uint64_t prefered_address) ++ grub_uint64_t preferred_address) + { + grub_err_t err; + +@@ -215,8 +215,8 @@ allocate_pages (grub_size_t prot_size, grub_size_t *align, + if (relocatable) + { + err = grub_relocator_alloc_chunk_align (relocator, &ch, +- prefered_address, +- prefered_address, ++ preferred_address, ++ preferred_address, + prot_size, 1, + GRUB_RELOCATOR_PREFERENCE_LOW, + 1); +@@ -235,7 +235,7 @@ allocate_pages (grub_size_t prot_size, grub_size_t *align, + } + else + err = grub_relocator_alloc_chunk_addr (relocator, &ch, +- prefered_address, ++ preferred_address, + prot_size); + if (err) + goto fail; +@@ -680,7 +680,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + int i; + grub_size_t align, min_align; + int relocatable; +- grub_uint64_t preffered_address = GRUB_LINUX_BZIMAGE_ADDR; ++ grub_uint64_t preferred_address = GRUB_LINUX_BZIMAGE_ADDR; + + grub_dl_ref (my_mod); + +@@ -775,22 +775,22 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + prot_size = grub_le_to_cpu32 (lh.init_size); + prot_init_space = page_align (prot_size); + if (relocatable) +- preffered_address = grub_le_to_cpu64 (lh.pref_address); ++ preferred_address = grub_le_to_cpu64 (lh.pref_address); + else +- preffered_address = GRUB_LINUX_BZIMAGE_ADDR; ++ preferred_address = GRUB_LINUX_BZIMAGE_ADDR; + } + else + { + min_align = align; + prot_size = prot_file_size; +- preffered_address = GRUB_LINUX_BZIMAGE_ADDR; ++ preferred_address = GRUB_LINUX_BZIMAGE_ADDR; + /* Usually, the compression ratio is about 50%. */ + prot_init_space = page_align (prot_size) * 3; + } + + if (allocate_pages (prot_size, &align, + min_align, relocatable, +- preffered_address)) ++ preferred_address)) + goto fail; + + params = (struct linux_kernel_params *) &linux_params; +diff --git a/grub-core/net/icmp6.c b/grub-core/net/icmp6.c +index 4fc343d..9ded94b 100644 +--- a/grub-core/net/icmp6.c ++++ b/grub-core/net/icmp6.c +@@ -55,7 +55,7 @@ struct prefix_option + grub_uint8_t prefixlen; + grub_uint8_t flags; + grub_uint32_t valid_lifetime; +- grub_uint32_t prefered_lifetime; ++ grub_uint32_t preferred_lifetime; + grub_uint32_t reserved; + grub_uint64_t prefix[2]; + } __attribute__ ((packed)); +@@ -370,14 +370,14 @@ grub_net_recv_icmp6_packet (struct grub_net_buff *nb, + struct grub_net_slaac_mac_list *slaac; + if (!(opt->flags & FLAG_SLAAC) + || (grub_be_to_cpu64 (opt->prefix[0]) >> 48) == 0xfe80 +- || (grub_be_to_cpu32 (opt->prefered_lifetime) ++ || (grub_be_to_cpu32 (opt->preferred_lifetime) + > grub_be_to_cpu32 (opt->valid_lifetime)) + || opt->prefixlen != 64) + { + grub_dprintf ("net", "discarded prefix: %d, %d, %d, %d\n", + !(opt->flags & FLAG_SLAAC), + (grub_be_to_cpu64 (opt->prefix[0]) >> 48) == 0xfe80, +- (grub_be_to_cpu32 (opt->prefered_lifetime) ++ (grub_be_to_cpu32 (opt->preferred_lifetime) + > grub_be_to_cpu32 (opt->valid_lifetime)), + opt->prefixlen != 64); + continue; +-- +1.8.1.4 + diff --git a/0051-grub-core-Makefile.am-moddep.lst-Use-AWK-instead-of-.patch b/0051-grub-core-Makefile.am-moddep.lst-Use-AWK-instead-of-.patch new file mode 100644 index 0000000..afce10c --- /dev/null +++ b/0051-grub-core-Makefile.am-moddep.lst-Use-AWK-instead-of-.patch @@ -0,0 +1,26 @@ +From 331fdad4315282f8e367e291131e048593a3a068 Mon Sep 17 00:00:00 2001 +From: Christoph Junghans +Date: Fri, 12 Oct 2012 15:04:02 +0200 +Subject: [PATCH 051/364] * grub-core/Makefile.am (moddep.lst): Use $(AWK) + instead of awk + +--- + grub-core/Makefile.am | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am +index cc4fb68..9cb14e2 100644 +--- a/grub-core/Makefile.am ++++ b/grub-core/Makefile.am +@@ -349,7 +349,7 @@ syminfo.lst: gensyminfo.sh kernel_syms.lst $(MODULE_FILES) + + # generate global module dependencies list + moddep.lst: syminfo.lst genmoddep.awk video.lst +- cat $< | sort | awk -f $(srcdir)/genmoddep.awk > $@ || (rm -f $@; exit 1) ++ cat $< | sort | $(AWK) -f $(srcdir)/genmoddep.awk > $@ || (rm -f $@; exit 1) + platform_DATA += moddep.lst + CLEANFILES += config.log syminfo.lst moddep.lst + +-- +1.8.1.4 + diff --git a/0052-grub-core-commands-configfile.c-GRUB_MOD_INIT-Correc.patch b/0052-grub-core-commands-configfile.c-GRUB_MOD_INIT-Correc.patch new file mode 100644 index 0000000..733dc9a --- /dev/null +++ b/0052-grub-core-commands-configfile.c-GRUB_MOD_INIT-Correc.patch @@ -0,0 +1,42 @@ +From a940b1492cc0c066725e5e49882602fb0e5c7399 Mon Sep 17 00:00:00 2001 +From: Colin Watson +Date: Fri, 12 Oct 2012 15:34:33 +0100 +Subject: [PATCH 052/364] * grub-core/commands/configfile.c (GRUB_MOD_INIT): + Correct description of extract_entries_configfile. + +--- + ChangeLog | 7 ++++++- + grub-core/commands/configfile.c | 2 +- + 2 files changed, 7 insertions(+), 2 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index d0aeab6..9280dba 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,4 +1,9 @@ +-2012-10-05 Colin Watson ++2012-10-12 Colin Watson ++ ++ * grub-core/commands/configfile.c (GRUB_MOD_INIT): Correct ++ description of extract_entries_configfile. ++ ++2012-10-05 Colin Watson + + * grub-core/loader/i386/linux.c (allocate_pages): Fix spelling of + preferred_address. +diff --git a/grub-core/commands/configfile.c b/grub-core/commands/configfile.c +index 99c0a24..f2d2abb 100644 +--- a/grub-core/commands/configfile.c ++++ b/grub-core/commands/configfile.c +@@ -78,7 +78,7 @@ GRUB_MOD_INIT(configfile) + cmd_extractor_configfile = + grub_register_command ("extract_entries_configfile", grub_cmd_source, + N_("FILE"), +- N_("Load another config file without changing context but take only menu entries.") ++ N_("Load another config file but take only menu entries.") + ); + + cmd_dot = +-- +1.8.1.4 + diff --git a/0053-Fix-ordering-and-tab-indentation-of-NetBSD-boot-menu.patch b/0053-Fix-ordering-and-tab-indentation-of-NetBSD-boot-menu.patch new file mode 100644 index 0000000..b66ea63 --- /dev/null +++ b/0053-Fix-ordering-and-tab-indentation-of-NetBSD-boot-menu.patch @@ -0,0 +1,71 @@ +From 5bf54ea7bf0fc7d1c2b9806a57566ad25179d07c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Gr=C3=A9goire=20Sutre?= +Date: Sun, 28 Oct 2012 11:55:22 +0100 +Subject: [PATCH 053/364] Fix ordering and tab indentation of NetBSD boot menu + entries. + +--- + ChangeLog | 5 +++++ + util/grub.d/10_netbsd.in | 12 ++++++------ + 2 files changed, 11 insertions(+), 6 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index c7b07bb..caea96d 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,8 @@ ++2012-10-28 Grégoire Sutre ++ ++ * util/grub.d/10_netbsd.in: Fix tab indentation and make sure ++ that /netbsd appears first (when it exists). ++ + 2012-10-12 Colin Watson + + * grub-core/commands/configfile.c (GRUB_MOD_INIT): Correct +diff --git a/util/grub.d/10_netbsd.in b/util/grub.d/10_netbsd.in +index b76332b..dead5c1 100644 +--- a/util/grub.d/10_netbsd.in ++++ b/util/grub.d/10_netbsd.in +@@ -74,13 +74,13 @@ netbsd_load_fs_module () + fi + + kmodule_rel=$(make_system_path_relative_to_its_root "$kmodule") || return +- prepare_grub_to_access_device $(${grub_probe} -t device "${kmodule}") | sed -e 's,^, ,' ++ prepare_grub_to_access_device $(${grub_probe} -t device "${kmodule}") | sed -e 's,^, ,' | sed "s/^/$submenu_indentation/" + case "${loader}" in + knetbsd) +- printf "$grub_tabknetbsd_module_elf %s\n" "${kmodule_rel}" ++ printf "${grub_tab}knetbsd_module_elf %s\n" "${kmodule_rel}" | sed "s/^/$submenu_indentation/" + ;; + multiboot) +- printf "$grub_tabmodule %s\n" "${kmodule_rel}" ++ printf "${grub_tab}module %s\n" "${kmodule_rel}" | sed "s/^/$submenu_indentation/" + ;; + esac + } +@@ -121,11 +121,11 @@ netbsd_entry () + printf "%s\n" "${prepare_boot_cache}" | sed "s/^/$submenu_indentation/" + case "${loader}" in + knetbsd) +- printf "$grub_tabknetbsd %s -r %s %s\n" \ ++ printf "${grub_tab}knetbsd %s -r %s %s\n" \ + "${kernel}" "${kroot_device}" "${GRUB_CMDLINE_NETBSD} ${args}" | sed "s/^/$submenu_indentation/" + ;; + multiboot) +- printf "$grub_tabmultiboot %s %s root=%s %s\n" \ ++ printf "${grub_tab}multiboot %s %s root=%s %s\n" \ + "${kernel}" "${kernel}" "${kroot_device}" "${GRUB_CMDLINE_NETBSD} ${args}" | sed "s/^/$submenu_indentation/" + ;; + esac +@@ -147,7 +147,7 @@ pattern="^ELF[^,]*executable.*statically linked" + submenu_indentation="" + + is_first_entry=true +-for k in $(ls -t /netbsd*) ; do ++for k in /netbsd $(ls -t /netbsd?* 2>/dev/null) ; do + if ! grub_file_is_not_garbage "$k" ; then + continue + fi +-- +1.8.1.4 + diff --git a/0054-grub-core-net-bootp.c-parse_dhcp_vendor-Fix-double-i.patch b/0054-grub-core-net-bootp.c-parse_dhcp_vendor-Fix-double-i.patch new file mode 100644 index 0000000..4cb68cc --- /dev/null +++ b/0054-grub-core-net-bootp.c-parse_dhcp_vendor-Fix-double-i.patch @@ -0,0 +1,39 @@ +From ae12080106554c5dd5e2d19799f08a0aa72c9be9 Mon Sep 17 00:00:00 2001 +From: Paulo Flabiano Smorigo +Date: Wed, 28 Nov 2012 14:14:20 +0100 +Subject: [PATCH 054/364] * grub-core/net/bootp.c (parse_dhcp_vendor): + Fix double increment. + +--- + ChangeLog | 4 ++++ + grub-core/net/bootp.c | 2 +- + 2 files changed, 5 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index caea96d..1759da4 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,7 @@ ++2012-11-28 Paulo Flabiano Smorigo ++ ++ * grub-core/net/bootp.c (parse_dhcp_vendor): Fix double increment. ++ + 2012-10-28 Grégoire Sutre + + * util/grub.d/10_netbsd.in: Fix tab indentation and make sure +diff --git a/grub-core/net/bootp.c b/grub-core/net/bootp.c +index bc07d53..f36d4cd 100644 +--- a/grub-core/net/bootp.c ++++ b/grub-core/net/bootp.c +@@ -122,7 +122,7 @@ parse_dhcp_vendor (const char *name, void *vend, int limit, int *mask) + ptr += 4; + } + } +- break; ++ continue; + case GRUB_NET_BOOTP_HOSTNAME: + set_env_limn_ro (name, "hostname", (char *) ptr, taglength); + break; +-- +1.8.1.4 + diff --git a/0055-include-grub-types.h-Fix-functionality-unaffecting-t.patch b/0055-include-grub-types.h-Fix-functionality-unaffecting-t.patch new file mode 100644 index 0000000..2bf5d44 --- /dev/null +++ b/0055-include-grub-types.h-Fix-functionality-unaffecting-t.patch @@ -0,0 +1,40 @@ +From aa3830c409ca40e6f0b71279ddb3409262a7bd96 Mon Sep 17 00:00:00 2001 +From: Leif Lindholm +Date: Wed, 28 Nov 2012 14:18:45 +0100 +Subject: [PATCH 055/364] * include/grub/types.h: Fix functionality + unaffecting typo in GRUB_TARGET_WORDSIZE conditional macro. + +--- + ChangeLog | 5 +++++ + include/grub/types.h | 2 +- + 2 files changed, 6 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index 1759da4..b26bfcb 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,8 @@ ++2012-11-28 Leif Lindholm ++ ++ * include/grub/types.h: Fix functionality unaffecting typo in ++ GRUB_TARGET_WORDSIZE conditional macro. ++ + 2012-11-28 Paulo Flabiano Smorigo + + * grub-core/net/bootp.c (parse_dhcp_vendor): Fix double increment. +diff --git a/include/grub/types.h b/include/grub/types.h +index 3e677c6..22d1be7 100644 +--- a/include/grub/types.h ++++ b/include/grub/types.h +@@ -50,7 +50,7 @@ + # error "This architecture is not supported because sizeof(void *) != 4 and sizeof(void *) != 8" + #endif + +-#if !defined (GRUB_UTIL) & !defined (GRUB_TARGET_WORDSIZE) ++#if !defined (GRUB_UTIL) && !defined (GRUB_TARGET_WORDSIZE) + # if GRUB_TARGET_SIZEOF_VOID_P == 4 + # define GRUB_TARGET_WORDSIZE 32 + # elif GRUB_TARGET_SIZEOF_VOID_P == 8 +-- +1.8.1.4 + diff --git a/0056-Support-big-endian-UFS1.patch b/0056-Support-big-endian-UFS1.patch new file mode 100644 index 0000000..092463f --- /dev/null +++ b/0056-Support-big-endian-UFS1.patch @@ -0,0 +1,307 @@ +From b4ec418af5d77275f3b3cf5e7566eaa4ecd713bd Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sat, 8 Dec 2012 20:56:58 +0100 +Subject: [PATCH 056/364] Support big-endian UFS1. + + * Makefile.util.def (libgrubmods): Add ufs_be.c + * grub-core/Makefile.core.def (ufs1_be): New module. + * grub-core/fs/ufs_be.c: New file. + * grub-core/fs/ufs.c: Declare grub_ufs_to_le* and use them throughout + the file. +--- + ChangeLog | 10 ++++++ + Makefile.util.def | 1 + + grub-core/Makefile.core.def | 5 +++ + grub-core/fs/ufs.c | 83 +++++++++++++++++++++++++++++---------------- + grub-core/fs/ufs_be.c | 2 ++ + 5 files changed, 72 insertions(+), 29 deletions(-) + create mode 100644 grub-core/fs/ufs_be.c + +diff --git a/ChangeLog b/ChangeLog +index b26bfcb..d565547 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,13 @@ ++2012-12-08 Vladimir Serbinenko ++ ++ Support big-endian UFS1. ++ ++ * Makefile.util.def (libgrubmods): Add ufs_be.c ++ * grub-core/Makefile.core.def (ufs1_be): New module. ++ * grub-core/fs/ufs_be.c: New file. ++ * grub-core/fs/ufs.c: Declare grub_ufs_to_le* and use them throughout ++ the file. ++ + 2012-11-28 Leif Lindholm + + * include/grub/types.h: Fix functionality unaffecting typo in +diff --git a/Makefile.util.def b/Makefile.util.def +index 8324ede..01f7456 100644 +--- a/Makefile.util.def ++++ b/Makefile.util.def +@@ -90,6 +90,7 @@ library = { + common = grub-core/fs/udf.c; + common = grub-core/fs/ufs2.c; + common = grub-core/fs/ufs.c; ++ common = grub-core/fs/ufs_be.c; + common = grub-core/fs/xfs.c; + common = grub-core/fs/zfs/zfscrypt.c; + common = grub-core/fs/zfs/zfs.c; +diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def +index 7a7b97a..6752429 100644 +--- a/grub-core/Makefile.core.def ++++ b/grub-core/Makefile.core.def +@@ -1181,6 +1181,11 @@ module = { + }; + + module = { ++ name = ufs1_be; ++ common = fs/ufs_be.c; ++}; ++ ++module = { + name = ufs2; + common = fs/ufs2.c; + }; +diff --git a/grub-core/fs/ufs.c b/grub-core/fs/ufs.c +index bd0cd1f..3f2dba1 100644 +--- a/grub-core/fs/ufs.c ++++ b/grub-core/fs/ufs.c +@@ -49,18 +49,30 @@ GRUB_MOD_LICENSE ("GPLv3+"); + + #define GRUB_UFS_VOLNAME_LEN 32 + ++#ifdef MODE_BIGENDIAN ++#define grub_ufs_to_cpu16 grub_be_to_cpu16 ++#define grub_ufs_to_cpu32 grub_be_to_cpu32 ++#define grub_ufs_to_cpu64 grub_be_to_cpu64 ++#define grub_cpu_to_ufs32_compile_time grub_cpu_to_be32_compile_time ++#else ++#define grub_ufs_to_cpu16 grub_le_to_cpu16 ++#define grub_ufs_to_cpu32 grub_le_to_cpu32 ++#define grub_ufs_to_cpu64 grub_le_to_cpu64 ++#define grub_cpu_to_ufs32_compile_time grub_cpu_to_le32_compile_time ++#endif ++ + /* Calculate in which group the inode can be found. */ +-#define UFS_BLKSZ(sblock) (grub_le_to_cpu32 (sblock->bsize)) ++#define UFS_BLKSZ(sblock) (grub_ufs_to_cpu32 (sblock->bsize)) + #define UFS_LOG_BLKSZ(sblock) (data->log2_blksz) + + #ifdef MODE_UFS2 +-#define INODE_ENDIAN(data,field,bits1,bits2) grub_le_to_cpu##bits2 (data->inode.field) ++#define INODE_ENDIAN(data,field,bits1,bits2) grub_ufs_to_cpu##bits2 (data->inode.field) + #else +-#define INODE_ENDIAN(data,field,bits1,bits2) grub_le_to_cpu##bits1 (data->inode.field) ++#define INODE_ENDIAN(data,field,bits1,bits2) grub_ufs_to_cpu##bits1 (data->inode.field) + #endif + +-#define INODE_SIZE(data) grub_le_to_cpu64 (data->inode.size) +-#define INODE_MODE(data) grub_le_to_cpu16 (data->inode.mode) ++#define INODE_SIZE(data) grub_ufs_to_cpu64 (data->inode.size) ++#define INODE_MODE(data) grub_ufs_to_cpu16 (data->inode.mode) + #ifdef MODE_UFS2 + #define LOG_INODE_BLKSZ 3 + #else +@@ -234,7 +246,7 @@ grub_ufs_get_file_block (struct grub_ufs_data *data, grub_disk_addr_t blk) + if (blk < GRUB_UFS_DIRBLKS) + return INODE_DIRBLOCKS (data, blk); + +- log2_blksz = grub_le_to_cpu32 (data->sblock.log2_blksz); ++ log2_blksz = grub_ufs_to_cpu32 (data->sblock.log2_blksz); + + blk -= GRUB_UFS_DIRBLKS; + +@@ -366,7 +378,7 @@ grub_ufs_read_file (struct grub_ufs_data *data, + { + data->disk->read_hook = read_hook; + grub_disk_read (data->disk, +- blknr << grub_le_to_cpu32 (data->sblock.log2_blksz), ++ blknr << grub_ufs_to_cpu32 (data->sblock.log2_blksz), + skipfirst, blockend, buf); + data->disk->read_hook = 0; + if (grub_errno) +@@ -389,17 +401,17 @@ grub_ufs_read_inode (struct grub_ufs_data *data, int ino, char *inode) + struct grub_ufs_sblock *sblock = &data->sblock; + + /* Determine the group the inode is in. */ +- int group = ino / grub_le_to_cpu32 (sblock->ino_per_group); ++ int group = ino / grub_ufs_to_cpu32 (sblock->ino_per_group); + + /* Determine the inode within the group. */ +- int grpino = ino % grub_le_to_cpu32 (sblock->ino_per_group); ++ int grpino = ino % grub_ufs_to_cpu32 (sblock->ino_per_group); + + /* The first block of the group. */ +- int grpblk = group * (grub_le_to_cpu32 (sblock->frags_per_group)); ++ int grpblk = group * (grub_ufs_to_cpu32 (sblock->frags_per_group)); + + #ifndef MODE_UFS2 +- grpblk += grub_le_to_cpu32 (sblock->cylg_offset) +- * (group & (~grub_le_to_cpu32 (sblock->cylg_mask))); ++ grpblk += grub_ufs_to_cpu32 (sblock->cylg_offset) ++ * (group & (~grub_ufs_to_cpu32 (sblock->cylg_mask))); + #endif + + if (!inode) +@@ -409,8 +421,8 @@ grub_ufs_read_inode (struct grub_ufs_data *data, int ino, char *inode) + } + + grub_disk_read (data->disk, +- ((grub_le_to_cpu32 (sblock->inoblk_offs) + grpblk) +- << grub_le_to_cpu32 (data->sblock.log2_blksz)) ++ ((grub_ufs_to_cpu32 (sblock->inoblk_offs) + grpblk) ++ << grub_ufs_to_cpu32 (data->sblock.log2_blksz)) + + grpino / UFS_INODE_PER_BLOCK, + (grpino % UFS_INODE_PER_BLOCK) + * sizeof (struct grub_ufs_inode), +@@ -501,7 +513,7 @@ grub_ufs_find_file (struct grub_ufs_data *data, const char *path) + #ifdef MODE_UFS2 + namelen = dirent.namelen_bsd; + #else +- namelen = grub_le_to_cpu16 (dirent.namelen); ++ namelen = grub_ufs_to_cpu16 (dirent.namelen); + #endif + { + char filename[namelen + 1]; +@@ -515,7 +527,7 @@ grub_ufs_find_file (struct grub_ufs_data *data, const char *path) + if (!grub_strcmp (name, filename)) + { + dirino = data->ino; +- grub_ufs_read_inode (data, grub_le_to_cpu32 (dirent.ino), 0); ++ grub_ufs_read_inode (data, grub_ufs_to_cpu32 (dirent.ino), 0); + + if ((INODE_MODE(data) & GRUB_UFS_ATTR_TYPE) + == GRUB_UFS_ATTR_LNK) +@@ -547,7 +559,7 @@ grub_ufs_find_file (struct grub_ufs_data *data, const char *path) + } + } + +- pos += grub_le_to_cpu16 (dirent.direntlen); ++ pos += grub_ufs_to_cpu16 (dirent.direntlen); + } while (pos < INODE_SIZE (data)); + + grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file `%s' not found"), path); +@@ -576,12 +588,12 @@ grub_ufs_mount (grub_disk_t disk) + + /* No need to byteswap bsize in this check. It works the same on both + endiannesses. */ +- if (grub_le_to_cpu32 (data->sblock.magic) == GRUB_UFS_MAGIC ++ if (data->sblock.magic == grub_cpu_to_ufs32_compile_time (GRUB_UFS_MAGIC) + && data->sblock.bsize != 0 + && ((data->sblock.bsize & (data->sblock.bsize - 1)) == 0)) + { + for (data->log2_blksz = 0; +- (1U << data->log2_blksz) < grub_le_to_cpu32 (data->sblock.bsize); ++ (1U << data->log2_blksz) < grub_ufs_to_cpu32 (data->sblock.bsize); + data->log2_blksz++); + + data->disk = disk; +@@ -652,7 +664,7 @@ grub_ufs_dir (grub_device_t device, const char *path, + #ifdef MODE_UFS2 + namelen = dirent.namelen_bsd; + #else +- namelen = grub_le_to_cpu16 (dirent.namelen); ++ namelen = grub_ufs_to_cpu16 (dirent.namelen); + #endif + + { +@@ -667,18 +679,19 @@ grub_ufs_dir (grub_device_t device, const char *path, + break; + + filename[namelen] = '\0'; +- grub_ufs_read_inode (data, dirent.ino, (char *) &inode); ++ grub_ufs_read_inode (data, grub_ufs_to_cpu32 (dirent.ino), ++ (char *) &inode); + +- info.dir = ((grub_le_to_cpu16 (inode.mode) & GRUB_UFS_ATTR_TYPE) ++ info.dir = ((grub_ufs_to_cpu16 (inode.mode) & GRUB_UFS_ATTR_TYPE) + == GRUB_UFS_ATTR_DIR); +- info.mtime = grub_le_to_cpu64 (inode.mtime); ++ info.mtime = grub_ufs_to_cpu64 (inode.mtime); + info.mtimeset = 1; + + if (hook (filename, &info)) + break; + } + +- pos += grub_le_to_cpu16 (dirent.direntlen); ++ pos += grub_ufs_to_cpu16 (dirent.direntlen); + } + + fail: +@@ -773,8 +786,8 @@ 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_xasprintf ("%08x%08x", +- (unsigned) grub_le_to_cpu32 (data->sblock.uuidhi), +- (unsigned) grub_le_to_cpu32 (data->sblock.uuidlow)); ++ (unsigned) grub_ufs_to_cpu32 (data->sblock.uuidhi), ++ (unsigned) grub_ufs_to_cpu32 (data->sblock.uuidlow)); + else + *uuid = NULL; + +@@ -799,10 +812,10 @@ grub_ufs_mtime (grub_device_t device, grub_int32_t *tm) + *tm = 0; + else + { +- *tm = grub_le_to_cpu32 (data->sblock.mtime); ++ *tm = grub_ufs_to_cpu32 (data->sblock.mtime); + #ifdef MODE_UFS2 +- if (*tm < (grub_int64_t) grub_le_to_cpu64 (data->sblock.mtime2)) +- *tm = grub_le_to_cpu64 (data->sblock.mtime2); ++ if (*tm < (grub_int64_t) grub_ufs_to_cpu64 (data->sblock.mtime2)) ++ *tm = grub_ufs_to_cpu64 (data->sblock.mtime2); + #endif + } + +@@ -820,8 +833,12 @@ static struct grub_fs grub_ufs_fs = + #ifdef MODE_UFS2 + .name = "ufs2", + #else ++#ifdef MODE_BIGENDIAN ++ .name = "ufs1_be", ++#else + .name = "ufs1", + #endif ++#endif + .dir = grub_ufs_dir, + .open = grub_ufs_open, + .read = grub_ufs_read, +@@ -839,8 +856,12 @@ static struct grub_fs grub_ufs_fs = + #ifdef MODE_UFS2 + GRUB_MOD_INIT(ufs2) + #else ++#ifdef MODE_BIGENDIAN ++GRUB_MOD_INIT(ufs1_be) ++#else + GRUB_MOD_INIT(ufs1) + #endif ++#endif + { + grub_fs_register (&grub_ufs_fs); + my_mod = mod; +@@ -849,8 +870,12 @@ GRUB_MOD_INIT(ufs1) + #ifdef MODE_UFS2 + GRUB_MOD_FINI(ufs2) + #else ++#ifdef MODE_BIGENDIAN ++GRUB_MOD_FINI(ufs1_be) ++#else + GRUB_MOD_FINI(ufs1) + #endif ++#endif + { + grub_fs_unregister (&grub_ufs_fs); + } +diff --git a/grub-core/fs/ufs_be.c b/grub-core/fs/ufs_be.c +new file mode 100644 +index 0000000..a58f75a +--- /dev/null ++++ b/grub-core/fs/ufs_be.c +@@ -0,0 +1,2 @@ ++#define MODE_BIGENDIAN 1 ++#include "ufs.c" +-- +1.8.1.4 + diff --git a/0057-Fix-big-endian-mtime.patch b/0057-Fix-big-endian-mtime.patch new file mode 100644 index 0000000..85ab6ee --- /dev/null +++ b/0057-Fix-big-endian-mtime.patch @@ -0,0 +1,79 @@ +From 32776fea2049a8b8198fdd59d49e18b4f8916d28 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sat, 8 Dec 2012 21:14:08 +0100 +Subject: [PATCH 057/364] Fix big-endian mtime. + + * grub-core/fs/ufs.c (grub_ufs_inode): Split improperly attached + together sec and usec. + (grub_ufs_dir): Use correct byteswapping for UFS time. +--- + ChangeLog | 8 ++++++++ + grub-core/fs/ufs.c | 19 +++++++++++++------ + 2 files changed, 21 insertions(+), 6 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index d565547..9c6dde5 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,13 @@ + 2012-12-08 Vladimir Serbinenko + ++ Fix big-endian mtime. ++ ++ * grub-core/fs/ufs.c (grub_ufs_inode): Split improperly attached ++ together sec and usec. ++ (grub_ufs_dir): Use correct byteswapping for UFS time. ++ ++2012-12-08 Vladimir Serbinenko ++ + Support big-endian UFS1. + + * Makefile.util.def (libgrubmods): Add ufs_be.c +diff --git a/grub-core/fs/ufs.c b/grub-core/fs/ufs.c +index 3f2dba1..c862336 100644 +--- a/grub-core/fs/ufs.c ++++ b/grub-core/fs/ufs.c +@@ -151,9 +151,9 @@ struct grub_ufs_inode + grub_uint64_t mtime; + grub_uint64_t ctime; + grub_uint64_t create_time; +- grub_uint32_t atime_sec; +- grub_uint32_t mtime_sec; +- grub_uint32_t ctime_sec; ++ grub_uint32_t atime_usec; ++ grub_uint32_t mtime_usec; ++ grub_uint32_t ctime_usec; + grub_uint32_t create_time_sec; + grub_uint32_t gen; + grub_uint32_t kernel_flags; +@@ -181,9 +181,12 @@ struct grub_ufs_inode + grub_uint16_t uid; + grub_uint16_t gid; + grub_uint64_t size; +- grub_uint64_t atime; +- grub_uint64_t mtime; +- grub_uint64_t ctime; ++ grub_uint32_t atime; ++ grub_uint32_t atime_usec; ++ grub_uint32_t mtime; ++ grub_uint32_t mtime_usec; ++ grub_uint32_t ctime; ++ grub_uint32_t ctime_usec; + union + { + struct +@@ -684,7 +687,11 @@ grub_ufs_dir (grub_device_t device, const char *path, + + info.dir = ((grub_ufs_to_cpu16 (inode.mode) & GRUB_UFS_ATTR_TYPE) + == GRUB_UFS_ATTR_DIR); ++#ifdef MODE_UFS2 + info.mtime = grub_ufs_to_cpu64 (inode.mtime); ++#else ++ info.mtime = grub_ufs_to_cpu32 (inode.mtime); ++#endif + info.mtimeset = 1; + + if (hook (filename, &info)) +-- +1.8.1.4 + diff --git a/0058-grub-core-fs-ufs.c-grub_ufs_dir-Stop-if-direntlen-is.patch b/0058-grub-core-fs-ufs.c-grub_ufs_dir-Stop-if-direntlen-is.patch new file mode 100644 index 0000000..21f70ef --- /dev/null +++ b/0058-grub-core-fs-ufs.c-grub_ufs_dir-Stop-if-direntlen-is.patch @@ -0,0 +1,41 @@ +From 5361431d3faa4ddbbd5d5c6a1fa10e0cebc60623 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Mon, 10 Dec 2012 09:22:40 +0100 +Subject: [PATCH 058/364] * grub-core/fs/ufs.c (grub_ufs_dir): Stop if + direntlen is 0 to avoid infinite loop on corrupted FS. + +--- + ChangeLog | 5 +++++ + grub-core/fs/ufs.c | 3 +++ + 2 files changed, 8 insertions(+) + +diff --git a/ChangeLog b/ChangeLog +index 9c6dde5..0b1596a 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,8 @@ ++2012-12-10 Vladimir Serbinenko ++ ++ * grub-core/fs/ufs.c (grub_ufs_dir): Stop if direntlen is 0 to avoid ++ infinite loop on corrupted FS. ++ + 2012-12-08 Vladimir Serbinenko + + Fix big-endian mtime. +diff --git a/grub-core/fs/ufs.c b/grub-core/fs/ufs.c +index c862336..74a4a40 100644 +--- a/grub-core/fs/ufs.c ++++ b/grub-core/fs/ufs.c +@@ -664,6 +664,9 @@ grub_ufs_dir (grub_device_t device, const char *path, + (char *) &dirent) < 0) + break; + ++ if (dirent.direntlen == 0) ++ break; ++ + #ifdef MODE_UFS2 + namelen = dirent.namelen_bsd; + #else +-- +1.8.1.4 + diff --git a/0059-util-getroot.c-convert_system_partition_to_system_di.patch b/0059-util-getroot.c-convert_system_partition_to_system_di.patch new file mode 100644 index 0000000..afdb78c --- /dev/null +++ b/0059-util-getroot.c-convert_system_partition_to_system_di.patch @@ -0,0 +1,52 @@ +From d2634650c732823bd304e0413f84d383c2689117 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Mon, 10 Dec 2012 11:12:38 +0100 +Subject: [PATCH 059/364] * util/getroot.c + (convert_system_partition_to_system_disk): Support nbd disks. + +--- + ChangeLog | 5 +++++ + util/getroot.c | 12 ++++++++++++ + 2 files changed, 17 insertions(+) + +diff --git a/ChangeLog b/ChangeLog +index 0b1596a..547f739 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,10 @@ + 2012-12-10 Vladimir Serbinenko + ++ * util/getroot.c (convert_system_partition_to_system_disk): Support ++ nbd disks. ++ ++2012-12-10 Vladimir Serbinenko ++ + * grub-core/fs/ufs.c (grub_ufs_dir): Stop if direntlen is 0 to avoid + infinite loop on corrupted FS. + +diff --git a/util/getroot.c b/util/getroot.c +index c2a25c9..24ce6aa 100644 +--- a/util/getroot.c ++++ b/util/getroot.c +@@ -1796,6 +1796,18 @@ convert_system_partition_to_system_disk (const char *os_dev, struct stat *st, + return path; + } + ++ if (strncmp ("nbd", p, 3) == 0 ++ && p[3] >= '0' && p[3] <= '9') ++ { ++ char *ptr = p + 3; ++ while (*ptr >= '0' && *ptr <= '9') ++ ptr++; ++ if (*ptr) ++ *is_part = 1; ++ *ptr = 0; ++ return path; ++ } ++ + /* If this is an IDE, SCSI or Virtio disk. */ + if (strncmp ("vdisk", p, 5) == 0 + && p[5] >= 'a' && p[5] <= 'z') +-- +1.8.1.4 + diff --git a/0060-util-grub-mkfont.c-argp_parser-Fix-a-typo-which-prev.patch b/0060-util-grub-mkfont.c-argp_parser-Fix-a-typo-which-prev.patch new file mode 100644 index 0000000..827fa43 --- /dev/null +++ b/0060-util-grub-mkfont.c-argp_parser-Fix-a-typo-which-prev.patch @@ -0,0 +1,40 @@ +From 18c470fb212991eea8749327b7baa44ebefc4215 Mon Sep 17 00:00:00 2001 +From: Vladimir Testov +Date: Mon, 10 Dec 2012 11:45:00 +0100 +Subject: [PATCH 060/364] * util/grub-mkfont.c (argp_parser): Fix a typo + which prevented --asce from working. + +--- + ChangeLog | 5 +++++ + util/grub-mkfont.c | 2 +- + 2 files changed, 6 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index 547f739..4204678 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,8 @@ ++2012-12-10 Vladimir Testov ++ ++ * util/grub-mkfont.c (argp_parser): Fix a typo which prevented --asce ++ from working. ++ + 2012-12-10 Vladimir Serbinenko + + * util/getroot.c (convert_system_partition_to_system_disk): Support +diff --git a/util/grub-mkfont.c b/util/grub-mkfont.c +index 4e2c5e4..83fb2d2 100644 +--- a/util/grub-mkfont.c ++++ b/util/grub-mkfont.c +@@ -1101,7 +1101,7 @@ argp_parser (int key, char *arg, struct argp_state *state) + arguments->font_info.desc = strtoul (arg, NULL, 0); + break; + +- case 'e': ++ case 'c': + arguments->font_info.asce = strtoul (arg, NULL, 0); + break; + +-- +1.8.1.4 + diff --git a/0061-grub-core-term-gfxterm.c-grub_virtual_screen_setup-G.patch b/0061-grub-core-term-gfxterm.c-grub_virtual_screen_setup-G.patch new file mode 100644 index 0000000..bc932c3 --- /dev/null +++ b/0061-grub-core-term-gfxterm.c-grub_virtual_screen_setup-G.patch @@ -0,0 +1,148 @@ +From c54df09cdb44ab19f9f7d5ece0f6568f4c19e46f Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Mon, 10 Dec 2012 16:07:33 +0100 +Subject: [PATCH 061/364] * grub-core/term/gfxterm.c + (grub_virtual_screen_setup): Get font as argument rather than font + name. All users updated. (grub_gfxterm_set_window): Likewise. + +--- + ChangeLog | 6 ++++++ + grub-core/gfxmenu/view.c | 11 ++++++++++- + grub-core/term/gfxterm.c | 18 ++++++++++-------- + include/grub/gfxterm.h | 3 ++- + 4 files changed, 28 insertions(+), 10 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 4204678..7617678 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,9 @@ ++2012-12-10 Vladimir Serbinenko ++ ++ * grub-core/term/gfxterm.c (grub_virtual_screen_setup): Get font as ++ argument rather than font name. All users updated. ++ (grub_gfxterm_set_window): Likewise. ++ + 2012-12-10 Vladimir Testov + + * util/grub-mkfont.c (argp_parser): Fix a typo which prevented --asce +diff --git a/grub-core/gfxmenu/view.c b/grub-core/gfxmenu/view.c +index 9023fd3..c005773 100644 +--- a/grub-core/gfxmenu/view.c ++++ b/grub-core/gfxmenu/view.c +@@ -361,6 +361,15 @@ grub_gfxmenu_draw_terminal_box (void) + static void + init_terminal (grub_gfxmenu_view_t view) + { ++ grub_font_t terminal_font; ++ ++ terminal_font = grub_font_get (view->terminal_font_name); ++ if (!terminal_font) ++ { ++ grub_error (GRUB_ERR_BAD_FONT, "no font loaded"); ++ return; ++ } ++ + term_rect.width = view->screen.width * 7 / 10; + term_rect.height = view->screen.height * 7 / 10; + +@@ -375,7 +384,7 @@ init_terminal (grub_gfxmenu_view_t view) + 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); ++ view->double_repaint, terminal_font, 3); + grub_gfxterm_decorator_hook = grub_gfxmenu_draw_terminal_box; + } + +diff --git a/grub-core/term/gfxterm.c b/grub-core/term/gfxterm.c +index c995b84..12567d1 100644 +--- a/grub-core/term/gfxterm.c ++++ b/grub-core/term/gfxterm.c +@@ -201,7 +201,7 @@ grub_virtual_screen_free (void) + static grub_err_t + grub_virtual_screen_setup (unsigned int x, unsigned int y, + unsigned int width, unsigned int height, +- const char *font_name) ++ grub_font_t font) + { + unsigned int i; + +@@ -209,10 +209,7 @@ grub_virtual_screen_setup (unsigned int x, unsigned int y, + grub_virtual_screen_free (); + + /* Initialize with default data. */ +- virtual_screen.font = grub_font_get (font_name); +- if (!virtual_screen.font) +- return grub_error (GRUB_ERR_BAD_FONT, +- "no font loaded"); ++ virtual_screen.font = font; + virtual_screen.width = width; + virtual_screen.height = height; + virtual_screen.offset_x = x; +@@ -282,7 +279,7 @@ 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) ++ grub_font_t font, int border_width) + { + /* Clean up any prior instance. */ + destroy_window (); +@@ -294,7 +291,7 @@ grub_gfxterm_set_window (struct grub_video_render_target *target, + if (grub_virtual_screen_setup (border_width, border_width, + width - 2 * border_width, + height - 2 * border_width, +- font_name) ++ font) + != GRUB_ERR_NONE) + { + return grub_errno; +@@ -321,6 +318,7 @@ grub_gfxterm_fullscreen (void) + grub_video_color_t color; + grub_err_t err; + int double_redraw; ++ grub_font_t font; + + err = grub_video_get_info (&mode_info); + /* Figure out what mode we ended up. */ +@@ -346,12 +344,16 @@ grub_gfxterm_fullscreen (void) + if (! font_name) + font_name = ""; /* Allow fallback to any font. */ + ++ font = grub_font_get (font_name); ++ if (!font) ++ return grub_error (GRUB_ERR_BAD_FONT, "no font loaded"); ++ + grub_gfxterm_decorator_hook = NULL; + + return grub_gfxterm_set_window (GRUB_VIDEO_RENDER_TARGET_DISPLAY, + 0, 0, mode_info.width, mode_info.height, + double_redraw, +- font_name, DEFAULT_BORDER_WIDTH); ++ font, DEFAULT_BORDER_WIDTH); + } + + static grub_err_t +diff --git a/include/grub/gfxterm.h b/include/grub/gfxterm.h +index 3fc8d92..361f73e 100644 +--- a/include/grub/gfxterm.h ++++ b/include/grub/gfxterm.h +@@ -23,12 +23,13 @@ + #include + #include + #include ++#include + + grub_err_t + 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); ++ grub_font_t font, int border_width); + + typedef void (*grub_gfxterm_repaint_callback_t)(int x, int y, + int width, int height); +-- +1.8.1.4 + diff --git a/0062-grub-core-gfxmenu-view.c-init_terminal-Avoid-making-.patch b/0062-grub-core-gfxmenu-view.c-init_terminal-Avoid-making-.patch new file mode 100644 index 0000000..6ece70c --- /dev/null +++ b/0062-grub-core-gfxmenu-view.c-init_terminal-Avoid-making-.patch @@ -0,0 +1,87 @@ +From 592fe36daf0064866bbee740383cbf7bd2156639 Mon Sep 17 00:00:00 2001 +From: "Dr. Tilmann Bubeck" +Date: Mon, 10 Dec 2012 16:14:12 +0100 +Subject: [PATCH 062/364] * grub-core/gfxmenu/view.c (init_terminal): + Avoid making terminal window too small. + +--- + ChangeLog | 5 +++++ + grub-core/gfxmenu/view.c | 31 +++++++++++++++++++++++++++---- + 2 files changed, 32 insertions(+), 4 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 7617678..ce822ee 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,8 @@ ++2012-12-10 Dr. Tilmann Bubeck ++ ++ * grub-core/gfxmenu/view.c (init_terminal): Avoid making terminal ++ window too small. ++ + 2012-12-10 Vladimir Serbinenko + + * grub-core/term/gfxterm.c (grub_virtual_screen_setup): Get font as +diff --git a/grub-core/gfxmenu/view.c b/grub-core/gfxmenu/view.c +index c005773..1918ea4 100644 +--- a/grub-core/gfxmenu/view.c ++++ b/grub-core/gfxmenu/view.c +@@ -361,8 +361,14 @@ grub_gfxmenu_draw_terminal_box (void) + static void + init_terminal (grub_gfxmenu_view_t view) + { ++ const int border_width = 3; ++ + grub_font_t terminal_font; + ++ unsigned int line_width; ++ ++ struct grub_font_glyph *glyph; ++ + terminal_font = grub_font_get (view->terminal_font_name); + if (!terminal_font) + { +@@ -370,11 +376,27 @@ init_terminal (grub_gfxmenu_view_t view) + return; + } + +- term_rect.width = view->screen.width * 7 / 10; ++ glyph = grub_font_get_glyph (terminal_font, 'M'); ++ ++ line_width = ((glyph ? glyph->device_width : 8) * 80 + 2 * border_width); ++ ++ if (view->screen.width <= line_width) ++ /* The screen is too small. Use all space, except a small border ++ to show the user, it is a window and not full screen: */ ++ term_rect.width = view->screen.width - 6 * border_width; ++ else ++ { ++ /* The screen is big enough. Try 70% of the screen width: */ ++ term_rect.width = view->screen.width * 7 / 10; ++ /* Make sure, that we use at least the line_width: */ ++ if ( term_rect.width < line_width ) ++ term_rect.width = line_width; ++ } ++ + term_rect.height = view->screen.height * 7 / 10; + +- 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_rect.x = view->screen.x + (view->screen.width - term_rect.width) / 2; ++ term_rect.y = view->screen.y + (view->screen.height - term_rect.height) / 2; + + term_view = view; + +@@ -384,7 +406,8 @@ init_terminal (grub_gfxmenu_view_t view) + grub_gfxterm_set_window (GRUB_VIDEO_RENDER_TARGET_DISPLAY, term_rect.x, + term_rect.y, + term_rect.width, term_rect.height, +- view->double_repaint, terminal_font, 3); ++ view->double_repaint, terminal_font, ++ border_width); + grub_gfxterm_decorator_hook = grub_gfxmenu_draw_terminal_box; + } + +-- +1.8.1.4 + diff --git a/0063-grub-core-kern-ieee1275-init.c-grub_machine_get_boot.patch b/0063-grub-core-kern-ieee1275-init.c-grub_machine_get_boot.patch new file mode 100644 index 0000000..76e0a6f --- /dev/null +++ b/0063-grub-core-kern-ieee1275-init.c-grub_machine_get_boot.patch @@ -0,0 +1,75 @@ +From acfa4335f7ed7310e7ee2da1f68443785f7f7913 Mon Sep 17 00:00:00 2001 +From: Paulo Flabiano Smorigo +Date: Mon, 10 Dec 2012 16:23:16 +0100 +Subject: [PATCH 063/364] * grub-core/kern/ieee1275/init.c + (grub_machine_get_bootlocation): Use dynamic allocation for the bootpath + buffer. + +--- + ChangeLog | 5 +++++ + grub-core/kern/ieee1275/init.c | 21 +++++++++++++++++---- + 2 files changed, 22 insertions(+), 4 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index ce822ee..8bd581e 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,8 @@ ++2012-12-10 Paulo Flabiano Smorigo ++ ++ * grub-core/kern/ieee1275/init.c (grub_machine_get_bootlocation): Use ++ dynamic allocation for the bootpath buffer. ++ + 2012-12-10 Dr. Tilmann Bubeck + + * grub-core/gfxmenu/view.c (init_terminal): Avoid making terminal +diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c +index 7d03a8a..14dcdf0 100644 +--- a/grub-core/kern/ieee1275/init.c ++++ b/grub-core/kern/ieee1275/init.c +@@ -82,18 +82,30 @@ void (*grub_ieee1275_net_config) (const char *dev, + void + grub_machine_get_bootlocation (char **device, char **path) + { +- char bootpath[64]; /* XXX check length */ ++ char *bootpath; ++ grub_ssize_t bootpath_size; + char *filename; + char *type; +- +- if (grub_ieee1275_get_property (grub_ieee1275_chosen, "bootpath", &bootpath, +- sizeof (bootpath), 0)) ++ ++ if (grub_ieee1275_get_property_length (grub_ieee1275_chosen, "bootpath", ++ &bootpath_size) ++ || bootpath_size <= 0) + { + /* Should never happen. */ + grub_printf ("/chosen/bootpath property missing!\n"); + return; + } + ++ bootpath = (char *) grub_malloc ((grub_size_t) bootpath_size + 64); ++ if (! bootpath) ++ { ++ grub_print_error (); ++ return; ++ } ++ grub_ieee1275_get_property (grub_ieee1275_chosen, "bootpath", bootpath, ++ (grub_size_t) bootpath_size + 1, 0); ++ bootpath[bootpath_size] = '\0'; ++ + /* Transform an OF device path to a GRUB path. */ + + type = grub_ieee1275_get_device_type (bootpath); +@@ -132,6 +144,7 @@ grub_machine_get_bootlocation (char **device, char **path) + *path = filename; + } + } ++ grub_free (bootpath); + } + + /* Claim some available memory in the first /memory node. */ +-- +1.8.1.4 + diff --git a/0064-util-grub-install.in-Remove-stale-TODO.patch b/0064-util-grub-install.in-Remove-stale-TODO.patch new file mode 100644 index 0000000..ba7b24e --- /dev/null +++ b/0064-util-grub-install.in-Remove-stale-TODO.patch @@ -0,0 +1,38 @@ +From b21a644e810f7c20844b828150d24d58ad0b776e Mon Sep 17 00:00:00 2001 +From: Andrey Borzenkov +Date: Mon, 10 Dec 2012 17:00:56 +0100 +Subject: [PATCH 064/364] * util/grub-install.in: Remove stale TODO. + +--- + ChangeLog | 4 ++++ + util/grub-install.in | 2 -- + 2 files changed, 4 insertions(+), 2 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 8bd581e..0b57abf 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,7 @@ ++2012-12-10 Andrey Borzenkov ++ ++ * util/grub-install.in: Remove stale TODO. ++ + 2012-12-10 Paulo Flabiano Smorigo + + * grub-core/kern/ieee1275/init.c (grub_machine_get_bootlocation): Use +diff --git a/util/grub-install.in b/util/grub-install.in +index 56be98f..a2cf07a 100644 +--- a/util/grub-install.in ++++ b/util/grub-install.in +@@ -486,8 +486,6 @@ if [ x"$grub_modinfo_platform" = xefi ]; then + *) + efi_file=grub.efi ;; + esac +- # TODO: We should also use efibootmgr, if available, to add a Boot +- # entry for ourselves. + fi + efidir="$efidir/EFI/$efi_distributor" + mkdir -p "$efidir" || exit 1 +-- +1.8.1.4 + diff --git a/0065-util-grub-install.in-Follow-the-symbolic-link-parame.patch b/0065-util-grub-install.in-Follow-the-symbolic-link-parame.patch new file mode 100644 index 0000000..0560d8e --- /dev/null +++ b/0065-util-grub-install.in-Follow-the-symbolic-link-parame.patch @@ -0,0 +1,40 @@ +From 28e8ed1fc8a89e3d4c71be6b27166b26b4e61570 Mon Sep 17 00:00:00 2001 +From: Paulo Flabiano Smorigo +Date: Mon, 10 Dec 2012 17:07:01 +0100 +Subject: [PATCH 065/364] * util/grub-install.in: Follow the symbolic + link parameter added to the file command. + +--- + ChangeLog | 5 +++++ + util/grub-install.in | 2 +- + 2 files changed, 6 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index 0b57abf..e522078 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,8 @@ ++2012-12-10 Paulo Flabiano Smorigo ++ ++ * util/grub-install.in: Follow the symbolic link parameter added ++ to the file command. ++ + 2012-12-10 Andrey Borzenkov + + * util/grub-install.in: Remove stale TODO. +diff --git a/util/grub-install.in b/util/grub-install.in +index a2cf07a..9dc4e0b 100644 +--- a/util/grub-install.in ++++ b/util/grub-install.in +@@ -748,7 +748,7 @@ elif [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "i386-ieee1275" ] + exit 1 + fi + +- if [ "$(file -s "${install_device}" -b | awk '{ print $1 }')" = ELF ] || [ x$("${grub_probe}" -m "${device_map}" -d "${install_device}" -t zero_check) = xtrue ]; then ++ if [ "$(file -s -b -L "${install_device}" | awk '{ print $1 }')" = ELF ] || [ x$("${grub_probe}" -m "${device_map}" -d "${install_device}" -t zero_check) = xtrue ]; then + dd if="${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/core.${imgext}" of="${install_device}" status=noxfer || { + gettext "Failed to copy Grub to the PReP partition." 1>&2 + echo 1>&2 +-- +1.8.1.4 + diff --git a/0066-grub-core-disk-cryptodisk.c-grub_cmd_cryptomount-Str.patch b/0066-grub-core-disk-cryptodisk.c-grub_cmd_cryptomount-Str.patch new file mode 100644 index 0000000..a25cc6b --- /dev/null +++ b/0066-grub-core-disk-cryptodisk.c-grub_cmd_cryptomount-Str.patch @@ -0,0 +1,54 @@ +From 08a1459a9534fa2337744a32dda511d496e9d6cf Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Mon, 10 Dec 2012 19:15:51 +0100 +Subject: [PATCH 066/364] * grub-core/disk/cryptodisk.c + (grub_cmd_cryptomount): Strip brackets around device name if + necessarry. + +--- + ChangeLog | 5 +++++ + grub-core/disk/cryptodisk.c | 12 +++++++++++- + 2 files changed, 16 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index e522078..8d7d988 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,8 @@ ++2012-12-10 Vladimir Serbinenko ++ ++ * grub-core/disk/cryptodisk.c (grub_cmd_cryptomount): Strip brackets ++ around device name if necessarry. ++ + 2012-12-10 Paulo Flabiano Smorigo + + * util/grub-install.in: Follow the symbolic link parameter added +diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c +index 1ac906d..3de3b86 100644 +--- a/grub-core/disk/cryptodisk.c ++++ b/grub-core/disk/cryptodisk.c +@@ -928,10 +928,20 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args) + grub_err_t err; + grub_disk_t disk; + grub_cryptodisk_t dev; ++ char *devname; ++ char *devlast; + + search_uuid = NULL; + check_boot = state[2].set; +- disk = grub_disk_open (args[0]); ++ devname = args[0]; ++ if (devname[0] == '(' && *(devlast = &devname[grub_strlen (devname) - 1]) == ')') ++ { ++ *devlast = '\0'; ++ disk = grub_disk_open (devname + 1); ++ *devlast = ')'; ++ } ++ else ++ disk = grub_disk_open (devname); + if (!disk) + return grub_errno; + +-- +1.8.1.4 + diff --git a/0067-docs-grub.texi-Network-Update-instructions-on-genera.patch b/0067-docs-grub.texi-Network-Update-instructions-on-genera.patch new file mode 100644 index 0000000..986925e --- /dev/null +++ b/0067-docs-grub.texi-Network-Update-instructions-on-genera.patch @@ -0,0 +1,86 @@ +From 80fa6c9eaeb13ed950d44bae4890c5b2da7ea6f1 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Mon, 10 Dec 2012 22:22:23 +0100 +Subject: [PATCH 067/364] * docs/grub.texi (Network): Update + instructions on generating netboot image. + +--- + ChangeLog | 5 +++++ + docs/grub.texi | 35 ++++++++++++++++++----------------- + 2 files changed, 23 insertions(+), 17 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 8d7d988..04ffaec 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,10 @@ + 2012-12-10 Vladimir Serbinenko + ++ * docs/grub.texi (Network): Update instructions on generating netboot ++ image. ++ ++2012-12-10 Vladimir Serbinenko ++ + * grub-core/disk/cryptodisk.c (grub_cmd_cryptomount): Strip brackets + around device name if necessarry. + +diff --git a/docs/grub.texi b/docs/grub.texi +index b0e7f59..39d9614 100644 +--- a/docs/grub.texi ++++ b/docs/grub.texi +@@ -2080,34 +2080,35 @@ The following properties are supported by all components: + @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. ++The following instructions don't work for *-emu, i386-qemu, i386-coreboot, ++i386-multiboot, mips_loongson, mips-arc and mips_qemu_mips + +-To generate a PXE boot image, run: ++To generate a netbootable directory, run: + + @example + @group +-grub-mkimage --format=i386-pc-pxe --output=grub.pxe --prefix='(pxe)/boot/grub' pxe pxecmd ++grub-mknetdir --net-directory=/srv/tftp --subdir=/boot/grub -d /usr/lib/grub/ + @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). ++E.g. for i386-pc: + +-You can also use the @command{grub-mknetdir} utility to generate an image +-and a GRUB directory tree, rather than copying files around manually. ++@example ++@group ++grub-mknetdir --net-directory=/srv/tftp --subdir=/boot/grub -d /usr/lib/grub/i386-pc ++@end group ++@end example ++ ++Then follow instructions printed out by grub-mknetdir on configuring your DHCP ++server. + + After GRUB has started, files on the TFTP server will be accessible via the +-@samp{(pxe)} device. ++@samp{(tftp)} 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. ++The server IP address can be controlled by changing the ++@samp{(tftp)} device name to @samp{(tftp,@var{server-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: +-- +1.8.1.4 + diff --git a/0068-util-grub.d-20_linux_xen.in-Addmissing-assignment-to.patch b/0068-util-grub.d-20_linux_xen.in-Addmissing-assignment-to.patch new file mode 100644 index 0000000..1cfee0e --- /dev/null +++ b/0068-util-grub.d-20_linux_xen.in-Addmissing-assignment-to.patch @@ -0,0 +1,40 @@ +From 34cb801ec4d1999babf5f7fe65cd70a149746137 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Tue, 11 Dec 2012 17:40:35 +0100 +Subject: [PATCH 068/364] * util/grub.d/20_linux_xen.in: Addmissing + assignment to machine. Reported by: Eriks Latosheks . + +--- + ChangeLog | 5 +++++ + util/grub.d/20_linux_xen.in | 2 ++ + 2 files changed, 7 insertions(+) + +diff --git a/ChangeLog b/ChangeLog +index 04ffaec..9104a46 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,8 @@ ++2012-12-11 Vladimir Serbinenko ++ ++ * util/grub.d/20_linux_xen.in: Addmissing assignment to machine. ++ Reported by: Eriks Latosheks . ++ + 2012-12-10 Vladimir Serbinenko + + * docs/grub.texi (Network): Update instructions on generating netboot +diff --git a/util/grub.d/20_linux_xen.in b/util/grub.d/20_linux_xen.in +index d4d0110..ac05ee4 100644 +--- a/util/grub.d/20_linux_xen.in ++++ b/util/grub.d/20_linux_xen.in +@@ -174,6 +174,8 @@ boot_device_id= + + title_correction_code= + ++machine=`uname -m` ++ + case "$machine" in + i?86) GENKERNEL_ARCH="x86" ;; + mips|mips64) GENKERNEL_ARCH="mips" ;; +-- +1.8.1.4 + diff --git a/0069-Backport-gnulib-fixes-for-C11.-Fixes-Savannah-bug-37.patch b/0069-Backport-gnulib-fixes-for-C11.-Fixes-Savannah-bug-37.patch new file mode 100644 index 0000000..338368f --- /dev/null +++ b/0069-Backport-gnulib-fixes-for-C11.-Fixes-Savannah-bug-37.patch @@ -0,0 +1,66 @@ +From d09689a5a2863043d007c1acb9bf0a8d1d3b776d Mon Sep 17 00:00:00 2001 +From: Colin Watson +Date: Fri, 28 Dec 2012 06:43:35 +0000 +Subject: [PATCH 069/364] Backport gnulib fixes for C11. Fixes Savannah bug + #37738. + +* grub-core/gnulib/stdio.in.h (gets): Warn on use only if +HAVE_RAW_DECL_GETS. +* m4/stdio_h.m4 (gl_STDIO_H): Check for gets. +--- + ChangeLog | 8 ++++++++ + grub-core/gnulib/stdio.in.h | 6 ++++-- + m4/stdio_h.m4 | 2 +- + 3 files changed, 13 insertions(+), 3 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 9104a46..0f04f5c 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,11 @@ ++2012-12-28 Colin Watson ++ ++ Backport gnulib fixes for C11. Fixes Savannah bug #37738. ++ ++ * grub-core/gnulib/stdio.in.h (gets): Warn on use only if ++ HAVE_RAW_DECL_GETS. ++ * m4/stdio_h.m4 (gl_STDIO_H): Check for gets. ++ + 2012-12-11 Vladimir Serbinenko + + * util/grub.d/20_linux_xen.in: Addmissing assignment to machine. +diff --git a/grub-core/gnulib/stdio.in.h b/grub-core/gnulib/stdio.in.h +index 80b9dbf..a8b00c6 100644 +--- a/grub-core/gnulib/stdio.in.h ++++ b/grub-core/gnulib/stdio.in.h +@@ -138,10 +138,12 @@ _GL_WARN_ON_USE (fflush, "fflush is not always POSIX compliant - " + #endif + + /* It is very rare that the developer ever has full control of stdin, +- so any use of gets warrants an unconditional warning. Assume it is +- always declared, since it is required by C89. */ ++ so any use of gets warrants an unconditional warning; besides, C11 ++ removed it. */ + #undef gets ++#if HAVE_RAW_DECL_GETS + _GL_WARN_ON_USE (gets, "gets is a security hole - use fgets instead"); ++#endif + + #if @GNULIB_FOPEN@ + # if @REPLACE_FOPEN@ +diff --git a/m4/stdio_h.m4 b/m4/stdio_h.m4 +index f5650cd..8458bec 100644 +--- a/m4/stdio_h.m4 ++++ b/m4/stdio_h.m4 +@@ -37,7 +37,7 @@ AC_DEFUN([gl_STDIO_H], + dnl corresponding gnulib module is not in use, and which is not + dnl guaranteed by C89. + gl_WARN_ON_USE_PREPARE([[#include +- ]], [dprintf fpurge fseeko ftello getdelim getline popen renameat ++ ]], [dprintf fpurge fseeko ftello getdelim getline gets popen renameat + snprintf tmpfile vdprintf vsnprintf]) + ]) + +-- +1.8.1.4 + diff --git a/0070-Apply-program-name-transformations-at-build-time-rat.patch b/0070-Apply-program-name-transformations-at-build-time-rat.patch new file mode 100644 index 0000000..0525fb6 --- /dev/null +++ b/0070-Apply-program-name-transformations-at-build-time-rat.patch @@ -0,0 +1,516 @@ +From 6db544ab2cdff7e5821558d150ac848c28c3fc93 Mon Sep 17 00:00:00 2001 +From: Colin Watson +Date: Fri, 28 Dec 2012 06:57:17 +0000 +Subject: [PATCH 070/364] Apply program name transformations at build-time + rather than at run-time. Fixes Debian bug #696465. + +* acinclude.m4 (grub_TRANSFORM): New macro. +* configure.ac: Create output variables with transformed names for +most programs. +* util/bash-completion.d/grub-completion.bash.in: Use +pre-transformed variables for program names. +* util/grub-install.in: Likewise. +* util/grub-kbdcomp.in: Likewise. +* util/grub-mkconfig.in: Likewise. +* util/grub-mkconfig_lib.in: Likewise. +* util/grub-mknetdir.in: Likewise. +* util/grub-mkrescue.in: Likewise. +* util/grub-mkstandalone.in: Likewise. +* util/grub-reboot.in: Likewise. +* util/grub-set-default.in: Likewise. +* util/powerpc/ieee1275/grub-mkrescue.in: Likewise. +* tests/util/grub-shell-tester.in: Remove unused assignment. +* tests/util/grub-shell.in: Likewise. +* util/grub.d/00_header.in: Likewise. +--- + ChangeLog | 24 ++++++++++++++++++++++++ + acinclude.m4 | 6 ++++++ + configure.ac | 16 ++++++++++++++++ + tests/util/grub-shell-tester.in | 2 -- + tests/util/grub-shell.in | 2 -- + util/bash-completion.d/grub-completion.bash.in | 24 ++++++++++++------------ + util/grub-install.in | 14 ++++++-------- + util/grub-kbdcomp.in | 4 +--- + util/grub-mkconfig.in | 7 +++---- + util/grub-mkconfig_lib.in | 6 ++---- + util/grub-mknetdir.in | 4 +--- + util/grub-mkrescue.in | 4 +--- + util/grub-mkstandalone.in | 4 +--- + util/grub-reboot.in | 4 +--- + util/grub-set-default.in | 4 +--- + util/grub.d/00_header.in | 2 -- + util/powerpc/ieee1275/grub-mkrescue.in | 4 +--- + 17 files changed, 76 insertions(+), 55 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 0f04f5c..b8bd215 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,29 @@ + 2012-12-28 Colin Watson + ++ Apply program name transformations at build-time rather than at ++ run-time. Fixes Debian bug #696465. ++ ++ * acinclude.m4 (grub_TRANSFORM): New macro. ++ * configure.ac: Create output variables with transformed names for ++ most programs. ++ * util/bash-completion.d/grub-completion.bash.in: Use ++ pre-transformed variables for program names. ++ * util/grub-install.in: Likewise. ++ * util/grub-kbdcomp.in: Likewise. ++ * util/grub-mkconfig.in: Likewise. ++ * util/grub-mkconfig_lib.in: Likewise. ++ * util/grub-mknetdir.in: Likewise. ++ * util/grub-mkrescue.in: Likewise. ++ * util/grub-mkstandalone.in: Likewise. ++ * util/grub-reboot.in: Likewise. ++ * util/grub-set-default.in: Likewise. ++ * util/powerpc/ieee1275/grub-mkrescue.in: Likewise. ++ * tests/util/grub-shell-tester.in: Remove unused assignment. ++ * tests/util/grub-shell.in: Likewise. ++ * util/grub.d/00_header.in: Likewise. ++ ++2012-12-28 Colin Watson ++ + Backport gnulib fixes for C11. Fixes Savannah bug #37738. + + * grub-core/gnulib/stdio.in.h (gets): Warn on use only if +diff --git a/acinclude.m4 b/acinclude.m4 +index 0eb2e2a..49a1a75 100644 +--- a/acinclude.m4 ++++ b/acinclude.m4 +@@ -452,3 +452,9 @@ else + AC_MSG_RESULT([no]) + [fi] + ]) ++ ++dnl Create an output variable with the transformed name of a GRUB utility ++dnl program. ++AC_DEFUN([grub_TRANSFORM],[dnl ++AC_SUBST(AS_TR_SH([$1]), [`AS_ECHO([$1]) | sed "$program_transform_name"`])dnl ++]) +diff --git a/configure.ac b/configure.ac +index ea3830a..a41f117 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -50,6 +50,22 @@ AC_CONFIG_HEADER([config-util.h]) + + # Program name transformations + AC_ARG_PROGRAM ++grub_TRANSFORM([grub-bios-setup]) ++grub_TRANSFORM([grub-editenv]) ++grub_TRANSFORM([grub-install]) ++grub_TRANSFORM([grub-mkconfig]) ++grub_TRANSFORM([grub-mkfont]) ++grub_TRANSFORM([grub-mkimage]) ++grub_TRANSFORM([grub-mklayout]) ++grub_TRANSFORM([grub-mkpasswd-pbkdf2]) ++grub_TRANSFORM([grub-mkrelpath]) ++grub_TRANSFORM([grub-mkrescue]) ++grub_TRANSFORM([grub-probe]) ++grub_TRANSFORM([grub-reboot]) ++grub_TRANSFORM([grub-script-check]) ++grub_TRANSFORM([grub-set-default]) ++grub_TRANSFORM([grub-setup]) ++grub_TRANSFORM([grub-sparc64-setup]) + + # Optimization flag. Allow user to override. + if test "x$TARGET_CFLAGS" = x; then +diff --git a/tests/util/grub-shell-tester.in b/tests/util/grub-shell-tester.in +index 80c8830..5adce0a 100644 +--- a/tests/util/grub-shell-tester.in ++++ b/tests/util/grub-shell-tester.in +@@ -18,8 +18,6 @@ set -e + # along with GRUB. If not, see . + + # Initialize some variables. +-transform="@program_transform_name@" +- + prefix="@prefix@" + exec_prefix="@exec_prefix@" + datarootdir="@datarootdir@" +diff --git a/tests/util/grub-shell.in b/tests/util/grub-shell.in +index f4fa23a..04e64da 100644 +--- a/tests/util/grub-shell.in ++++ b/tests/util/grub-shell.in +@@ -18,8 +18,6 @@ set -e + # along with GRUB. If not, see . + + # Initialize some variables. +-transform="@program_transform_name@" +- + prefix="@prefix@" + exec_prefix="@exec_prefix@" + datarootdir="@datarootdir@" +diff --git a/util/bash-completion.d/grub-completion.bash.in b/util/bash-completion.d/grub-completion.bash.in +index 64d49fe..5f4b249 100644 +--- a/util/bash-completion.d/grub-completion.bash.in ++++ b/util/bash-completion.d/grub-completion.bash.in +@@ -165,12 +165,12 @@ _grub_set_entry () { + fi + } + +-__grub_set_default_program=$( echo grub-set-default | sed "@program_transform_name@" ) ++__grub_set_default_program="@grub_set_default@" + have ${__grub_set_default_program} && \ + complete -F _grub_set_entry -o filenames ${__grub_set_default_program} + unset __grub_set_default_program + +-__grub_reboot_program=$( echo grub-reboot | sed "@program_transform_name@" ) ++__grub_reboot_program="@grub_reboot@" + have ${__grub_reboot_program} && \ + complete -F _grub_set_entry -o filenames ${__grub_reboot_program} + unset __grub_reboot_program +@@ -197,7 +197,7 @@ _grub_editenv () { + create list set unset" + } + +-__grub_editenv_program=$( echo grub-editenv | sed "@program_transform_name@" ) ++__grub_editenv_program="@grub_editenv@" + have ${__grub_editenv_program} && \ + complete -F _grub_editenv -o filenames ${__grub_editenv_program} + unset __grub_editenv_program +@@ -218,7 +218,7 @@ _grub_mkconfig () { + _filedir + fi + } +-__grub_mkconfig_program=$( echo grub-mkconfig | sed "@program_transform_name@" ) ++__grub_mkconfig_program="@grub_mkconfig@" + have ${__grub_mkconfig_program} && \ + complete -F _grub_mkconfig -o filenames ${__grub_mkconfig_program} + unset __grub_mkconfig_program +@@ -252,7 +252,7 @@ _grub_setup () { + _filedir + fi + } +-__grub_setup_program=$( echo grub-setup | sed "@program_transform_name@" ) ++__grub_setup_program="@grub_setup@" + have ${__grub_setup_program} && \ + complete -F _grub_setup -o filenames ${__grub_setup_program} + unset __grub_setup_program +@@ -298,7 +298,7 @@ _grub_install () { + _filedir + fi + } +-__grub_install_program=$( echo grub-install | sed "@program_transform_name@" ) ++__grub_install_program="@grub_install@" + have ${__grub_install_program} && \ + complete -F _grub_install -o filenames ${__grub_install_program} + unset __grub_install_program +@@ -320,7 +320,7 @@ _grub_mkfont () { + _filedir + fi + } +-__grub_mkfont_program=$( echo grub-mkfont | sed "@program_transform_name@" ) ++__grub_mkfont_program="@grub_mkfont@" + have ${__grub_mkfont_program} && \ + complete -F _grub_mkfont -o filenames ${__grub_mkfont_program} + unset __grub_mkfont_program +@@ -351,7 +351,7 @@ _grub_mkrescue () { + _filedir + fi + } +-__grub_mkrescue_program=$( echo grub-mkrescue | sed "@program_transform_name@" ) ++__grub_mkrescue_program="@grub_mkrescue@" + have ${__grub_mkrescue_program} && \ + complete -F _grub_mkrescue -o filenames ${__grub_mkrescue_program} + unset __grub_mkrescue_program +@@ -393,7 +393,7 @@ _grub_mkimage () { + _filedir + fi + } +-__grub_mkimage_program=$( echo grub-mkimage | sed "@program_transform_name@" ) ++__grub_mkimage_program="@grub_mkimage@" + have ${__grub_mkimage_program} && \ + complete -F _grub_mkimage -o filenames ${__grub_mkimage_program} + unset __grub_mkimage_program +@@ -415,7 +415,7 @@ _grub_mkpasswd_pbkdf2 () { + _filedir + fi + } +-__grub_mkpasswd_pbkdf2_program=$( echo grub-mkpasswd-pbkdf2 | sed "@program_transform_name@" ) ++__grub_mkpasswd_pbkdf2_program="@grub_mkpasswd_pbkdf2@" + have ${__grub_mkpasswd_pbkdf2_program} && \ + complete -F _grub_mkpasswd_pbkdf2 -o filenames ${__grub_mkpasswd_pbkdf2_program} + unset __grub_mkpasswd_pbkdf2_program +@@ -453,7 +453,7 @@ _grub_probe () { + _filedir + fi + } +-__grub_probe_program=$( echo grub-probe | sed "@program_transform_name@" ) ++__grub_probe_program="@grub_probe@" + have ${__grub_probe_program} && \ + complete -F _grub_probe -o filenames ${__grub_probe_program} + unset __grub_probe_program +@@ -475,7 +475,7 @@ _grub_script_check () { + _filedir + fi + } +-__grub_script_check_program=$( echo grub-script-check | sed "@program_transform_name@" ) ++__grub_script_check_program="@grub_script_check@" + have ${__grub_script_check_program} && \ + complete -F _grub_script_check -o filenames ${__grub_script_check_program} + +diff --git a/util/grub-install.in b/util/grub-install.in +index 9dc4e0b..218bbd9 100644 +--- a/util/grub-install.in ++++ b/util/grub-install.in +@@ -17,8 +17,6 @@ + # along with GRUB. If not, see . + + # Initialize some variables. +-transform="@program_transform_name@" +- + prefix="@prefix@" + exec_prefix="@exec_prefix@" + datarootdir="@datarootdir@" +@@ -44,10 +42,10 @@ localedir="@datadir@/locale" + + self="`basename $0`" + +-grub_mkimage="${bindir}/`echo grub-mkimage | sed ${transform}`" +-grub_probe="${sbindir}/`echo grub-probe | sed ${transform}`" +-grub_editenv="${bindir}/`echo grub-editenv | sed ${transform}`" +-grub_mkrelpath="${bindir}/`echo grub-mkrelpath | sed ${transform}`" ++grub_mkimage="${bindir}/@grub_mkimage@" ++grub_probe="${sbindir}/@grub_probe@" ++grub_editenv="${bindir}/@grub_editenv@" ++grub_mkrelpath="${bindir}/@grub_mkrelpath@" + rootdir= + bootdir= + grubdir="`echo "/@bootdirname@/@grubdirname@" | sed 's,//*,/,g'`" +@@ -347,11 +345,11 @@ else + fi + + if test "x$grub_setup" = x && [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "i386-pc" ]; then +- grub_setup="${sbindir}/`echo grub-bios-setup | sed ${transform}`" ++ grub_setup="${sbindir}/@grub_bios_setup@" + fi + + if test "x$grub_setup" = x && [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "sparc64-ieee1275" ]; then +- grub_setup="${sbindir}/`echo grub-sparc64-setup | sed ${transform}`" ++ grub_setup="${sbindir}/@grub_sparc64_setup@" + fi + + if test "x$install_device" = x && ([ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "i386-pc" ] \ +diff --git a/util/grub-kbdcomp.in b/util/grub-kbdcomp.in +index 29f0456..715c483 100644 +--- a/util/grub-kbdcomp.in ++++ b/util/grub-kbdcomp.in +@@ -1,7 +1,5 @@ + #!/bin/sh + +-transform="@program_transform_name@" +- + prefix="@prefix@" + exec_prefix="@exec_prefix@" + bindir="@bindir@" +@@ -11,7 +9,7 @@ if [ "x$pkgdatadir" = x ]; then + pkgdatadir="${datadir}/@PACKAGE@" + fi + +-grub_mklayout="${bindir}/`echo grub-mklayout | sed ${transform}`" ++grub_mklayout="${bindir}/@grub_mklayout@" + + ckbcomp_options="" + +diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in +index 516be86..4263367 100644 +--- a/util/grub-mkconfig.in ++++ b/util/grub-mkconfig.in +@@ -17,7 +17,6 @@ set -e + # You should have received a copy of the GNU General Public License + # along with GRUB. If not, see . + +-transform="@program_transform_name@" + prefix="@prefix@" + exec_prefix="@exec_prefix@" + datarootdir="@datarootdir@" +@@ -39,9 +38,9 @@ grub_mkconfig_dir="${sysconfdir}"/grub.d + + self=`basename $0` + +-grub_probe="${sbindir}/`echo grub-probe | sed "${transform}"`" +-grub_editenv="${bindir}/`echo grub-editenv | sed "${transform}"`" +-grub_script_check="${bindir}/`echo grub-script-check | sed "${transform}"`" ++grub_probe="${sbindir}/@grub_probe@" ++grub_editenv="${bindir}/@grub_editenv@" ++grub_script_check="${bindir}/@grub_script_check@" + + export TEXTDOMAIN=@PACKAGE@ + export TEXTDOMAINDIR="@localedir@" +diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in +index 3574839..e560dd7 100644 +--- a/util/grub-mkconfig_lib.in ++++ b/util/grub-mkconfig_lib.in +@@ -14,8 +14,6 @@ + # You should have received a copy of the GNU General Public License + # along with GRUB. If not, see . + +-transform="@program_transform_name@" +- + prefix="@prefix@" + exec_prefix="@exec_prefix@" + datarootdir="@datarootdir@" +@@ -25,10 +23,10 @@ sbindir="@sbindir@" + pkgdatadir="${datadir}/@PACKAGE@" + + if test "x$grub_probe" = x; then +- grub_probe="${sbindir}/`echo grub-probe | sed "${transform}"`" ++ grub_probe="${sbindir}/@grub_probe@" + fi + if test "x$grub_mkrelpath" = x; then +- grub_mkrelpath="${bindir}/`echo grub-mkrelpath | sed "${transform}"`" ++ grub_mkrelpath="${bindir}/@grub_mkrelpath@" + fi + + if which gettext >/dev/null 2>/dev/null; then +diff --git a/util/grub-mknetdir.in b/util/grub-mknetdir.in +index d1ad763..e235af3 100644 +--- a/util/grub-mknetdir.in ++++ b/util/grub-mknetdir.in +@@ -17,8 +17,6 @@ + # along with GRUB. If not, see . + + # Initialize some variables. +-transform="@program_transform_name@" +- + prefix="@prefix@" + exec_prefix="@exec_prefix@" + datarootdir="@datarootdir@" +@@ -36,7 +34,7 @@ fi + + self=`basename $0` + +-grub_mkimage="${bindir}/`echo grub-mkimage | sed ${transform}`" ++grub_mkimage="${bindir}/@grub_mkimage@" + rootdir=/srv/tftp + modules= + +diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in +index f71099e..d279a9d 100644 +--- a/util/grub-mkrescue.in ++++ b/util/grub-mkrescue.in +@@ -19,8 +19,6 @@ set -e + + # Initialize some variables. + +-transform="@program_transform_name@" +- + prefix="@prefix@" + exec_prefix="@exec_prefix@" + datarootdir="@datarootdir@" +@@ -49,7 +47,7 @@ efi64_dir="${libdir}/@PACKAGE@/x86_64-efi" + ia64_dir="${libdir}/@PACKAGE@/ia64-efi" + rom_directory= + override_dir= +-grub_mkimage="${bindir}/`echo grub-mkimage | sed ${transform}`" ++grub_mkimage="${bindir}/@grub_mkimage@" + + xorriso=xorriso + +diff --git a/util/grub-mkstandalone.in b/util/grub-mkstandalone.in +index 87a3b42..78b83e0 100644 +--- a/util/grub-mkstandalone.in ++++ b/util/grub-mkstandalone.in +@@ -19,8 +19,6 @@ set -e + + # Initialize some variables. + +-transform="@program_transform_name@" +- + prefix="@prefix@" + exec_prefix="@exec_prefix@" + datarootdir="@datarootdir@" +@@ -40,7 +38,7 @@ self=`basename $0` + source_directory= + compression=auto + format= +-grub_mkimage="${bindir}/`echo grub-mkimage | sed ${transform}`" ++grub_mkimage="${bindir}/@grub_mkimage@" + source= + + export TEXTDOMAIN=@PACKAGE@ +diff --git a/util/grub-reboot.in b/util/grub-reboot.in +index 93dbe6c..7516a03 100644 +--- a/util/grub-reboot.in ++++ b/util/grub-reboot.in +@@ -17,8 +17,6 @@ + # along with GRUB. If not, see . + + # Initialize some variables. +-transform="@program_transform_name@" +- + prefix=@prefix@ + exec_prefix=@exec_prefix@ + bindir=@bindir@ +@@ -32,7 +30,7 @@ fi + + self=`basename $0` + +-grub_editenv=${bindir}/`echo grub-editenv | sed ${transform}` ++grub_editenv=${bindir}/@grub_editenv@ + rootdir= + bootdir= + grubdir=`echo "/@bootdirname@/@grubdirname@" | sed 's,//*,/,g'` +diff --git a/util/grub-set-default.in b/util/grub-set-default.in +index 3d890be..443e56f 100644 +--- a/util/grub-set-default.in ++++ b/util/grub-set-default.in +@@ -17,8 +17,6 @@ + # along with GRUB. If not, see . + + # Initialize some variables. +-transform="@program_transform_name@" +- + prefix=@prefix@ + exec_prefix=@exec_prefix@ + bindir=@bindir@ +@@ -32,7 +30,7 @@ fi + + self=`basename $0` + +-grub_editenv=${bindir}/`echo grub-editenv | sed ${transform}` ++grub_editenv=${bindir}/@grub_editenv@ + rootdir= + bootdir= + grubdir=`echo "/@bootdirname@/@grubdirname@" | sed 's,//*,/,g'` +diff --git a/util/grub.d/00_header.in b/util/grub.d/00_header.in +index 765bfdc..3da5d12 100644 +--- a/util/grub.d/00_header.in ++++ b/util/grub.d/00_header.in +@@ -17,8 +17,6 @@ set -e + # You should have received a copy of the GNU General Public License + # along with GRUB. If not, see . + +-transform="@program_transform_name@" +- + prefix="@prefix@" + exec_prefix="@exec_prefix@" + datarootdir="@datarootdir@" +diff --git a/util/powerpc/ieee1275/grub-mkrescue.in b/util/powerpc/ieee1275/grub-mkrescue.in +index b3b88f0..2615cab 100644 +--- a/util/powerpc/ieee1275/grub-mkrescue.in ++++ b/util/powerpc/ieee1275/grub-mkrescue.in +@@ -18,8 +18,6 @@ set -e + # along with GRUB. If not, see . + + # Initialize some variables. +-transform="@program_transform_name@" +- + prefix="@prefix@" + exec_prefix="@exec_prefix@" + bindir="@bindir@" +@@ -36,7 +34,7 @@ fi + + self=`basename $0` + +-grub_mkimage="${bindir}/`echo grub-mkimage | sed ${transform}`" ++grub_mkimage="${bindir}/@grub_mkimage@" + + export TEXTDOMAIN=@PACKAGE@ + export TEXTDOMAINDIR="@localedir@" +-- +1.8.1.4 + diff --git a/0071-neater-gnulib-backport.patch b/0071-neater-gnulib-backport.patch new file mode 100644 index 0000000..8ab3a94 --- /dev/null +++ b/0071-neater-gnulib-backport.patch @@ -0,0 +1,25 @@ +From 25b73b33cdaafb3f21c5014b090a71f8449653c5 Mon Sep 17 00:00:00 2001 +From: Colin Watson +Date: Fri, 28 Dec 2012 07:13:34 +0000 +Subject: [PATCH 071/364] neater gnulib backport + +--- + m4/stdio_h.m4 | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/m4/stdio_h.m4 b/m4/stdio_h.m4 +index 8458bec..d3edb42 100644 +--- a/m4/stdio_h.m4 ++++ b/m4/stdio_h.m4 +@@ -35,7 +35,7 @@ AC_DEFUN([gl_STDIO_H], + + dnl Check for declarations of anything we want to poison if the + dnl corresponding gnulib module is not in use, and which is not +- dnl guaranteed by C89. ++ dnl guaranteed by both C89 and C11. + gl_WARN_ON_USE_PREPARE([[#include + ]], [dprintf fpurge fseeko ftello getdelim getline gets popen renameat + snprintf tmpfile vdprintf vsnprintf]) +-- +1.8.1.4 + diff --git a/0072-util-grub-mkconfig.in-Accept-GRUB_TERMINAL_OUTPUT-vg.patch b/0072-util-grub-mkconfig.in-Accept-GRUB_TERMINAL_OUTPUT-vg.patch new file mode 100644 index 0000000..b74c0dd --- /dev/null +++ b/0072-util-grub-mkconfig.in-Accept-GRUB_TERMINAL_OUTPUT-vg.patch @@ -0,0 +1,42 @@ +From 2572b7c6ff8be58b10b3b9d13e35b50a535ee2ac Mon Sep 17 00:00:00 2001 +From: Colin Watson +Date: Fri, 28 Dec 2012 07:21:17 +0000 +Subject: [PATCH 072/364] * util/grub-mkconfig.in: Accept + GRUB_TERMINAL_OUTPUT=vga_text. Fixes Savannah bug #37821. + +--- + ChangeLog | 5 +++++ + util/grub-mkconfig.in | 2 +- + 2 files changed, 6 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index b8bd215..3bca6fd 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,10 @@ + 2012-12-28 Colin Watson + ++ * util/grub-mkconfig.in: Accept GRUB_TERMINAL_OUTPUT=vga_text. ++ Fixes Savannah bug #37821. ++ ++2012-12-28 Colin Watson ++ + Apply program name transformations at build-time rather than at + run-time. Fixes Debian bug #696465. + +diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in +index 4263367..8decc1d 100644 +--- a/util/grub-mkconfig.in ++++ b/util/grub-mkconfig.in +@@ -158,7 +158,7 @@ fi + for x in ${GRUB_TERMINAL_OUTPUT}; do + case "x${x}" in + xgfxterm) ;; +- xconsole | xserial | xofconsole) ++ xconsole | xserial | xofconsole | xvga_text) + # make sure all our children behave in conformance with ascii.. + export LANG=C;; + *) echo "Invalid output terminal \"${GRUB_TERMINAL_OUTPUT}\"" >&2 ; exit 1 ;; +-- +1.8.1.4 + diff --git a/0073-grub-core-bus-usb-ehci.c-grub_ehci_pci_iter-Remove-i.patch b/0073-grub-core-bus-usb-ehci.c-grub_ehci_pci_iter-Remove-i.patch new file mode 100644 index 0000000..f098530 --- /dev/null +++ b/0073-grub-core-bus-usb-ehci.c-grub_ehci_pci_iter-Remove-i.patch @@ -0,0 +1,126 @@ +From a0e1ddf87544a8371fff110c451576016ca81fb3 Mon Sep 17 00:00:00 2001 +From: Colin Watson +Date: Sun, 30 Dec 2012 09:57:58 +0000 +Subject: [PATCH 073/364] * grub-core/bus/usb/ehci.c (grub_ehci_pci_iter): + Remove incorrect __attribute__ ((unused)). * grub-core/video/bochs.c + (find_card): Likewise. * grub-core/video/cirrus.c (find_card): Likewise. * + grub-core/video/radeon_fuloong2e.c (find_card): Likewise. * + grub-core/video/sis315pro.c (find_card): Likewise. * grub-core/video/sm712.c + (find_card): Likewise. + +--- + ChangeLog | 10 ++++++++++ + grub-core/bus/usb/ehci.c | 3 +-- + grub-core/video/bochs.c | 2 +- + grub-core/video/cirrus.c | 2 +- + grub-core/video/radeon_fuloong2e.c | 4 ++-- + grub-core/video/sis315pro.c | 4 ++-- + grub-core/video/sm712.c | 4 ++-- + 7 files changed, 19 insertions(+), 10 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 3bca6fd..36f1bff 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,13 @@ ++2012-12-30 Colin Watson ++ ++ * grub-core/bus/usb/ehci.c (grub_ehci_pci_iter): Remove incorrect ++ __attribute__ ((unused)). ++ * grub-core/video/bochs.c (find_card): Likewise. ++ * grub-core/video/cirrus.c (find_card): Likewise. ++ * grub-core/video/radeon_fuloong2e.c (find_card): Likewise. ++ * grub-core/video/sis315pro.c (find_card): Likewise. ++ * grub-core/video/sm712.c (find_card): Likewise. ++ + 2012-12-28 Colin Watson + + * util/grub-mkconfig.in: Accept GRUB_TERMINAL_OUTPUT=vga_text. +diff --git a/grub-core/bus/usb/ehci.c b/grub-core/bus/usb/ehci.c +index d99a4be..dc5bf71 100644 +--- a/grub-core/bus/usb/ehci.c ++++ b/grub-core/bus/usb/ehci.c +@@ -455,8 +455,7 @@ grub_ehci_reset (struct grub_ehci *e) + + /* PCI iteration function... */ + static int NESTED_FUNC_ATTR +-grub_ehci_pci_iter (grub_pci_device_t dev, +- grub_pci_id_t pciid __attribute__ ((unused))) ++grub_ehci_pci_iter (grub_pci_device_t dev, grub_pci_id_t pciid) + { + grub_uint8_t release; + grub_uint32_t class_code; +diff --git a/grub-core/video/bochs.c b/grub-core/video/bochs.c +index 79cae65..f6db137 100644 +--- a/grub-core/video/bochs.c ++++ b/grub-core/video/bochs.c +@@ -210,7 +210,7 @@ grub_video_bochs_setup (unsigned int width, unsigned int height, + int pitch, bytes_per_pixel; + grub_size_t page_size; /* The size of a page in bytes. */ + +- auto int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid __attribute__ ((unused))); ++ auto int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid); + int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid) + { + grub_pci_address_t addr; +diff --git a/grub-core/video/cirrus.c b/grub-core/video/cirrus.c +index 7fad50e..e711119 100644 +--- a/grub-core/video/cirrus.c ++++ b/grub-core/video/cirrus.c +@@ -245,7 +245,7 @@ grub_video_cirrus_setup (unsigned int width, unsigned int height, + int found = 0; + int pitch, bytes_per_pixel; + +- auto int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid __attribute__ ((unused))); ++ auto int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid); + int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid) + { + grub_pci_address_t addr; +diff --git a/grub-core/video/radeon_fuloong2e.c b/grub-core/video/radeon_fuloong2e.c +index 32f66c7..45a68ed 100644 +--- a/grub-core/video/radeon_fuloong2e.c ++++ b/grub-core/video/radeon_fuloong2e.c +@@ -69,8 +69,8 @@ grub_video_radeon_fuloong2e_setup (unsigned int width, unsigned int height, + int found = 0; + + #ifndef TEST +- 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))) ++ auto int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid); ++ int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid) + { + grub_pci_address_t addr; + grub_uint32_t class; +diff --git a/grub-core/video/sis315pro.c b/grub-core/video/sis315pro.c +index 5d06daa..d213877 100644 +--- a/grub-core/video/sis315pro.c ++++ b/grub-core/video/sis315pro.c +@@ -99,8 +99,8 @@ grub_video_sis315pro_setup (unsigned int width, unsigned int height, + unsigned i; + + #ifndef TEST +- 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))) ++ auto int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid); ++ int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid) + { + grub_pci_address_t addr; + grub_uint32_t class; +diff --git a/grub-core/video/sm712.c b/grub-core/video/sm712.c +index 5f22c40..d780983 100644 +--- a/grub-core/video/sm712.c ++++ b/grub-core/video/sm712.c +@@ -370,8 +370,8 @@ 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))) ++ auto int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid); ++ int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid) + { + grub_pci_address_t addr; + grub_uint32_t class; +-- +1.8.1.4 + diff --git a/0074-Remove-several-trivially-unnecessary-uses-of-nested-.patch b/0074-Remove-several-trivially-unnecessary-uses-of-nested-.patch new file mode 100644 index 0000000..93cd3f5 --- /dev/null +++ b/0074-Remove-several-trivially-unnecessary-uses-of-nested-.patch @@ -0,0 +1,817 @@ +From a3564dd3f793d2677584a93284966b6b9f14ebdb Mon Sep 17 00:00:00 2001 +From: Colin Watson +Date: Mon, 31 Dec 2012 17:31:38 +0000 +Subject: [PATCH 074/364] Remove several trivially-unnecessary uses of nested + functions. + +* grub-core/commands/i386/pc/sendkey.c +(grub_cmd_sendkey: find_key_code, find_ascii_code): Make static +instead of nested. +* grub-core/commands/legacycfg.c (legacy_file: getline): Likewise. +Rename to ... +(legacy_file_getline): ... this. +* grub-core/commands/loadenv.c (grub_cmd_load_env: set_var): +Likewise. +* grub-core/kern/corecmd.c (grub_core_cmd_set: print_env): Likewise. +* grub-core/kern/fs.c (grub_fs_probe: dummy_func): Likewise. Rename +to ... +(probe_dummy_iter): ... this. +* grub-core/kern/i386/coreboot/mmap.c +(grub_linuxbios_table_iterate: check_signature): Likewise. +* grub-core/kern/parser.c (grub_parser_split_cmdline: +check_varstate): Likewise. Mark inline. +* grub-core/lib/arg.c (find_short: fnd_short): Likewise. Pass +an additional parameter. +(find_long: fnd_long): Likewise. Pass two additional parameters. +* grub-core/lib/crc.c (init_crc32c_table: reflect): Likewise. +* grub-core/lib/crc64.c (init_crc64_table: reflect): Likewise. +* grub-core/lib/ieee1275/cmos.c (grub_cmos_find_port: hook): +Likewise. Rename to ... +(grub_cmos_find_port_iter): ... this. +* grub-core/lib/ieee1275/datetime.c (find_rtc: hook): Likewise. +Rename to ... +(find_rtc_iter): ... this. + +* grub-core/normal/menu_entry.c (run): Fold nested editor_getsource +function directly into the function body, since it is only called +once. +--- + ChangeLog | 36 ++++++++++++++++ + grub-core/commands/i386/pc/sendkey.c | 65 ++++++++++++++-------------- + grub-core/commands/legacycfg.c | 20 ++++----- + grub-core/commands/loadenv.c | 15 ++++--- + grub-core/kern/corecmd.c | 16 +++---- + grub-core/kern/fs.c | 20 ++++----- + grub-core/kern/i386/coreboot/mmap.c | 19 +++++---- + grub-core/kern/parser.c | 20 ++++----- + grub-core/lib/arg.c | 58 +++++++++++++------------ + grub-core/lib/crc.c | 31 +++++++------- + grub-core/lib/crc64.c | 31 +++++++------- + grub-core/lib/ieee1275/cmos.c | 82 ++++++++++++++++++------------------ + grub-core/lib/ieee1275/datetime.c | 27 ++++++------ + grub-core/normal/menu_entry.c | 50 +++++++++------------- + 14 files changed, 264 insertions(+), 226 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 36f1bff..8723bfa 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,39 @@ ++2012-12-31 Colin Watson ++ ++ Remove several trivially-unnecessary uses of nested functions. ++ ++ * grub-core/commands/i386/pc/sendkey.c ++ (grub_cmd_sendkey: find_key_code, find_ascii_code): Make static ++ instead of nested. ++ * grub-core/commands/legacycfg.c (legacy_file: getline): Likewise. ++ Rename to ... ++ (legacy_file_getline): ... this. ++ * grub-core/commands/loadenv.c (grub_cmd_load_env: set_var): ++ Likewise. ++ * grub-core/kern/corecmd.c (grub_core_cmd_set: print_env): Likewise. ++ * grub-core/kern/fs.c (grub_fs_probe: dummy_func): Likewise. Rename ++ to ... ++ (probe_dummy_iter): ... this. ++ * grub-core/kern/i386/coreboot/mmap.c ++ (grub_linuxbios_table_iterate: check_signature): Likewise. ++ * grub-core/kern/parser.c (grub_parser_split_cmdline: ++ check_varstate): Likewise. Mark inline. ++ * grub-core/lib/arg.c (find_short: fnd_short): Likewise. Pass ++ an additional parameter. ++ (find_long: fnd_long): Likewise. Pass two additional parameters. ++ * grub-core/lib/crc.c (init_crc32c_table: reflect): Likewise. ++ * grub-core/lib/crc64.c (init_crc64_table: reflect): Likewise. ++ * grub-core/lib/ieee1275/cmos.c (grub_cmos_find_port: hook): ++ Likewise. Rename to ... ++ (grub_cmos_find_port_iter): ... this. ++ * grub-core/lib/ieee1275/datetime.c (find_rtc: hook): Likewise. ++ Rename to ... ++ (find_rtc_iter): ... this. ++ ++ * grub-core/normal/menu_entry.c (run): Fold nested editor_getsource ++ function directly into the function body, since it is only called ++ once. ++ + 2012-12-30 Colin Watson + + * grub-core/bus/usb/ehci.c (grub_ehci_pci_iter): Remove incorrect +diff --git a/grub-core/commands/i386/pc/sendkey.c b/grub-core/commands/i386/pc/sendkey.c +index 17f648d..d985cb3 100644 +--- a/grub-core/commands/i386/pc/sendkey.c ++++ b/grub-core/commands/i386/pc/sendkey.c +@@ -286,47 +286,48 @@ grub_sendkey_preboot (int noret __attribute__ ((unused))) + return GRUB_ERR_NONE; + } + +-static grub_err_t +-grub_cmd_sendkey (grub_extcmd_context_t ctxt, int argc, char **args) ++/* Helper for grub_cmd_sendkey. */ ++static int ++find_key_code (char *key) + { +- struct grub_arg_list *state = ctxt->state; +- +- auto int find_key_code (char *key); +- auto int find_ascii_code (char *key); ++ unsigned i; + +- int find_key_code (char *key) ++ for (i = 0; i < sizeof (keysym_table) / sizeof (keysym_table[0]); i++) + { +- unsigned i; ++ if (keysym_table[i].unshifted_name ++ && grub_strcmp (key, keysym_table[i].unshifted_name) == 0) ++ return keysym_table[i].keycode; ++ else if (keysym_table[i].shifted_name ++ && grub_strcmp (key, keysym_table[i].shifted_name) == 0) ++ return keysym_table[i].keycode; ++ } + +- for (i = 0; i < sizeof (keysym_table) / sizeof (keysym_table[0]); i++) +- { +- if (keysym_table[i].unshifted_name +- && grub_strcmp (key, keysym_table[i].unshifted_name) == 0) +- return keysym_table[i].keycode; +- else if (keysym_table[i].shifted_name +- && grub_strcmp (key, keysym_table[i].shifted_name) == 0) +- return keysym_table[i].keycode; +- } ++ return 0; ++} + +- return 0; +- } ++/* Helper for grub_cmd_sendkey. */ ++static int ++find_ascii_code (char *key) ++{ ++ unsigned i; + +- int find_ascii_code (char *key) ++ for (i = 0; i < sizeof (keysym_table) / sizeof (keysym_table[0]); i++) + { +- unsigned i; ++ if (keysym_table[i].unshifted_name ++ && grub_strcmp (key, keysym_table[i].unshifted_name) == 0) ++ return keysym_table[i].unshifted_ascii; ++ else if (keysym_table[i].shifted_name ++ && grub_strcmp (key, keysym_table[i].shifted_name) == 0) ++ return keysym_table[i].shifted_ascii; ++ } + +- for (i = 0; i < sizeof (keysym_table) / sizeof (keysym_table[0]); i++) +- { +- if (keysym_table[i].unshifted_name +- && grub_strcmp (key, keysym_table[i].unshifted_name) == 0) +- return keysym_table[i].unshifted_ascii; +- else if (keysym_table[i].shifted_name +- && grub_strcmp (key, keysym_table[i].shifted_name) == 0) +- return keysym_table[i].shifted_ascii; +- } ++ return 0; ++} + +- return 0; +- } ++static grub_err_t ++grub_cmd_sendkey (grub_extcmd_context_t ctxt, int argc, char **args) ++{ ++ struct grub_arg_list *state = ctxt->state; + + andmask = 0xffffffff; + ormask = 0; +diff --git a/grub-core/commands/legacycfg.c b/grub-core/commands/legacycfg.c +index 5293acc..e34eed4 100644 +--- a/grub-core/commands/legacycfg.c ++++ b/grub-core/commands/legacycfg.c +@@ -35,6 +35,14 @@ + + GRUB_MOD_LICENSE ("GPLv3+"); + ++/* Helper for legacy_file. */ ++static grub_err_t ++legacy_file_getline (char **line, int cont __attribute__ ((unused))) ++{ ++ *line = 0; ++ return GRUB_ERR_NONE; ++} ++ + static grub_err_t + legacy_file (const char *filename) + { +@@ -43,14 +51,6 @@ legacy_file (const char *filename) + grub_menu_t menu; + char *suffix = grub_strdup (""); + +- auto grub_err_t getline (char **line, int cont); +- grub_err_t getline (char **line, +- int cont __attribute__ ((unused))) +- { +- *line = 0; +- return GRUB_ERR_NONE; +- } +- + if (!suffix) + return grub_errno; + +@@ -134,7 +134,7 @@ legacy_file (const char *filename) + + if (parsed && !entryname) + { +- grub_normal_parse_line (parsed, getline); ++ grub_normal_parse_line (parsed, legacy_file_getline); + grub_print_error (); + grub_free (parsed); + parsed = NULL; +@@ -180,7 +180,7 @@ legacy_file (const char *filename) + grub_free (args); + } + +- grub_normal_parse_line (suffix, getline); ++ grub_normal_parse_line (suffix, legacy_file_getline); + grub_print_error (); + grub_free (suffix); + grub_free (entrysrc); +diff --git a/grub-core/commands/loadenv.c b/grub-core/commands/loadenv.c +index 18ebb7e..9a35550 100644 +--- a/grub-core/commands/loadenv.c ++++ b/grub-core/commands/loadenv.c +@@ -114,6 +114,14 @@ read_envblk_file (grub_file_t file) + return envblk; + } + ++/* Helper for grub_cmd_load_env. */ ++static int ++set_var (const char *name, const char *value) ++{ ++ grub_env_set (name, value); ++ return 0; ++} ++ + static grub_err_t + grub_cmd_load_env (grub_extcmd_context_t ctxt, + int argc __attribute__ ((unused)), +@@ -123,13 +131,6 @@ grub_cmd_load_env (grub_extcmd_context_t ctxt, + grub_file_t file; + grub_envblk_t envblk; + +- auto int set_var (const char *name, const char *value); +- int set_var (const char *name, const char *value) +- { +- grub_env_set (name, value); +- return 0; +- } +- + file = open_envblk_file ((state[0].set) ? state[0].arg : 0); + if (! file) + return grub_errno; +diff --git a/grub-core/kern/corecmd.c b/grub-core/kern/corecmd.c +index eec575c..43240e9 100644 +--- a/grub-core/kern/corecmd.c ++++ b/grub-core/kern/corecmd.c +@@ -28,6 +28,14 @@ + #include + #include + ++/* Helper for grub_core_cmd_set. */ ++static int ++print_env (struct grub_env_var *env) ++{ ++ grub_printf ("%s=%s\n", env->name, env->value); ++ return 0; ++} ++ + /* set ENVVAR=VALUE */ + static grub_err_t + grub_core_cmd_set (struct grub_command *cmd __attribute__ ((unused)), +@@ -36,14 +44,6 @@ grub_core_cmd_set (struct grub_command *cmd __attribute__ ((unused)), + char *var; + char *val; + +- auto int print_env (struct grub_env_var *env); +- +- int print_env (struct grub_env_var *env) +- { +- grub_printf ("%s=%s\n", env->name, env->value); +- return 0; +- } +- + if (argc < 1) + { + grub_env_iterate (print_env); +diff --git a/grub-core/kern/fs.c b/grub-core/kern/fs.c +index 51d89d1..7e150f2 100644 +--- a/grub-core/kern/fs.c ++++ b/grub-core/kern/fs.c +@@ -32,18 +32,18 @@ grub_fs_t grub_fs_list = 0; + + grub_fs_autoload_hook_t grub_fs_autoload_hook = 0; + ++/* Helper for grub_fs_probe. */ ++static int ++probe_dummy_iter (const char *filename __attribute__ ((unused)), ++ const struct grub_dirhook_info *info __attribute__ ((unused))) ++ { ++ return 1; ++ } ++ + grub_fs_t + grub_fs_probe (grub_device_t device) + { + grub_fs_t p; +- auto int dummy_func (const char *filename, +- const struct grub_dirhook_info *info); +- +- int dummy_func (const char *filename __attribute__ ((unused)), +- const struct grub_dirhook_info *info __attribute__ ((unused))) +- { +- return 1; +- } + + if (device->disk) + { +@@ -69,7 +69,7 @@ grub_fs_probe (grub_device_t device) + } + else + #endif +- (p->dir) (device, "/", dummy_func); ++ (p->dir) (device, "/", probe_dummy_iter); + if (grub_errno == GRUB_ERR_NONE) + return p; + +@@ -93,7 +93,7 @@ grub_fs_probe (grub_device_t device) + { + p = grub_fs_list; + +- (p->dir) (device, "/", dummy_func); ++ (p->dir) (device, "/", probe_dummy_iter); + if (grub_errno == GRUB_ERR_NONE) + { + count--; +diff --git a/grub-core/kern/i386/coreboot/mmap.c b/grub-core/kern/i386/coreboot/mmap.c +index 8b0b202..8e15683 100644 +--- a/grub-core/kern/i386/coreboot/mmap.c ++++ b/grub-core/kern/i386/coreboot/mmap.c +@@ -22,21 +22,22 @@ + #include + #include + ++/* Helper for grub_linuxbios_table_iterate. */ ++static int ++check_signature (grub_linuxbios_table_header_t tbl_header) ++{ ++ if (! grub_memcmp (tbl_header->signature, "LBIO", 4)) ++ return 1; ++ ++ return 0; ++} ++ + static grub_err_t + grub_linuxbios_table_iterate (int (*hook) (grub_linuxbios_table_item_t)) + { + grub_linuxbios_table_header_t table_header; + grub_linuxbios_table_item_t table_item; + +- auto int check_signature (grub_linuxbios_table_header_t); +- int check_signature (grub_linuxbios_table_header_t tbl_header) +- { +- if (! grub_memcmp (tbl_header->signature, "LBIO", 4)) +- return 1; +- +- return 0; +- } +- + /* Assuming table_header is aligned to its size (8 bytes). */ + + for (table_header = (grub_linuxbios_table_header_t) 0x500; +diff --git a/grub-core/kern/parser.c b/grub-core/kern/parser.c +index 9213caa..d1be53e 100644 +--- a/grub-core/kern/parser.c ++++ b/grub-core/kern/parser.c +@@ -96,6 +96,16 @@ grub_parser_cmdline_state (grub_parser_state_t state, char c, char *result) + } + + ++/* Helper for grub_parser_split_cmdline. */ ++static inline 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); ++} ++ + grub_err_t + grub_parser_split_cmdline (const char *cmdline, grub_reader_getline_t getline, + int *argc, char ***argv) +@@ -111,16 +121,6 @@ grub_parser_split_cmdline (const char *cmdline, grub_reader_getline_t getline, + char *args; + int i; + +- 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); +- } +- + auto void add_var (grub_parser_state_t newstate); + + void add_var (grub_parser_state_t newstate) +diff --git a/grub-core/lib/arg.c b/grub-core/lib/arg.c +index b341885..a2d9416 100644 +--- a/grub-core/lib/arg.c ++++ b/grub-core/lib/arg.c +@@ -34,25 +34,26 @@ static const struct grub_arg_option help_options[] = + {0, 0, 0, 0, 0, 0} + }; + ++/* Helper for find_short. */ + static struct grub_arg_option * +-find_short (const struct grub_arg_option *options, char c) ++fnd_short (const struct grub_arg_option *opt, char c) + { +- struct grub_arg_option *found = 0; +- auto struct grub_arg_option *fnd_short (const struct grub_arg_option *opt); +- +- struct grub_arg_option *fnd_short (const struct grub_arg_option *opt) ++ while (opt->doc) + { +- while (opt->doc) +- { +- if (opt->shortarg == c) +- return (struct grub_arg_option *) opt; +- opt++; +- } +- return 0; ++ if (opt->shortarg == c) ++ return (struct grub_arg_option *) opt; ++ opt++; + } ++ return 0; ++} ++ ++static struct grub_arg_option * ++find_short (const struct grub_arg_option *options, char c) ++{ ++ struct grub_arg_option *found = 0; + + if (options) +- found = fnd_short (options); ++ found = fnd_short (options, c); + + if (! found) + { +@@ -74,29 +75,30 @@ find_short (const struct grub_arg_option *options, char c) + return found; + } + ++/* Helper for find_long. */ + static struct grub_arg_option * +-find_long (const struct grub_arg_option *options, const char *s, int len) ++fnd_long (const struct grub_arg_option *opt, const char *s, int len) + { +- struct grub_arg_option *found = 0; +- auto struct grub_arg_option *fnd_long (const struct grub_arg_option *opt); +- +- struct grub_arg_option *fnd_long (const struct grub_arg_option *opt) ++ while (opt->doc) + { +- while (opt->doc) +- { +- if (opt->longarg && ! grub_strncmp (opt->longarg, s, len) && +- opt->longarg[len] == '\0') +- return (struct grub_arg_option *) opt; +- opt++; +- } +- return 0; ++ if (opt->longarg && ! grub_strncmp (opt->longarg, s, len) && ++ opt->longarg[len] == '\0') ++ return (struct grub_arg_option *) opt; ++ opt++; + } ++ return 0; ++} ++ ++static struct grub_arg_option * ++find_long (const struct grub_arg_option *options, const char *s, int len) ++{ ++ struct grub_arg_option *found = 0; + + if (options) +- found = fnd_long (options); ++ found = fnd_long (options, s, len); + + if (! found) +- found = fnd_long (help_options); ++ found = fnd_long (help_options, s, len); + + return found; + } +diff --git a/grub-core/lib/crc.c b/grub-core/lib/crc.c +index ffc3ef3..bf97cc6 100644 +--- a/grub-core/lib/crc.c ++++ b/grub-core/lib/crc.c +@@ -22,25 +22,26 @@ + + static grub_uint32_t crc32c_table [256]; + +-static void +-init_crc32c_table (void) ++/* Helper for init_crc32c_table. */ ++static grub_uint32_t ++reflect (grub_uint32_t ref, int len) + { +- auto grub_uint32_t reflect (grub_uint32_t ref, int len); +- grub_uint32_t reflect (grub_uint32_t ref, int len) +- { +- grub_uint32_t result = 0; +- int i; +- +- for (i = 1; i <= len; i++) +- { +- if (ref & 1) +- result |= 1 << (len - i); +- ref >>= 1; +- } ++ grub_uint32_t result = 0; ++ int i; + +- return result; ++ for (i = 1; i <= len; i++) ++ { ++ if (ref & 1) ++ result |= 1 << (len - i); ++ ref >>= 1; + } + ++ return result; ++} ++ ++static void ++init_crc32c_table (void) ++{ + grub_uint32_t polynomial = 0x1edc6f41; + int i, j; + +diff --git a/grub-core/lib/crc64.c b/grub-core/lib/crc64.c +index 4b1c92c..4960f3f 100644 +--- a/grub-core/lib/crc64.c ++++ b/grub-core/lib/crc64.c +@@ -25,25 +25,26 @@ GRUB_MOD_LICENSE ("GPLv3+"); + + static grub_uint64_t crc64_table [256]; + +-static void +-init_crc64_table (void) ++/* Helper for init_crc64_table. */ ++static grub_uint64_t ++reflect (grub_uint64_t ref, int len) + { +- auto grub_uint64_t reflect (grub_uint64_t ref, int len); +- grub_uint64_t reflect (grub_uint64_t ref, int len) +- { +- grub_uint64_t result = 0; +- int i; ++ grub_uint64_t result = 0; ++ int i; + +- for (i = 1; i <= len; i++) +- { +- if (ref & 1) +- result |= 1ULL << (len - i); +- ref >>= 1; +- } +- +- return result; ++ for (i = 1; i <= len; i++) ++ { ++ if (ref & 1) ++ result |= 1ULL << (len - i); ++ ref >>= 1; + } + ++ return result; ++} ++ ++static void ++init_crc64_table (void) ++{ + grub_uint64_t polynomial = 0x42f0e1eba9ea3693ULL; + int i, j; + +diff --git a/grub-core/lib/ieee1275/cmos.c b/grub-core/lib/ieee1275/cmos.c +index fa57db9..328d70a 100644 +--- a/grub-core/lib/ieee1275/cmos.c ++++ b/grub-core/lib/ieee1275/cmos.c +@@ -23,51 +23,53 @@ + #include + + volatile grub_uint8_t *grub_cmos_port = 0; +-grub_err_t +-grub_cmos_find_port (void) ++ ++/* Helper for grub_cmos_find_port. */ ++static int ++grub_cmos_find_port_iter (struct grub_ieee1275_devalias *alias) + { +- auto int hook (struct grub_ieee1275_devalias *alias); +- int hook (struct grub_ieee1275_devalias *alias) +- { +- grub_ieee1275_phandle_t dev; +- grub_uint32_t addr[2]; +- grub_ssize_t actual; +- /* Enough to check if it's "m5819" */ +- char compat[100]; +- if (grub_ieee1275_finddevice (alias->path, &dev)) +- return 0; +- if (grub_ieee1275_get_property (dev, "compatible", compat, sizeof (compat), +- 0)) +- return 0; +- if (grub_strcmp (compat, "m5819") != 0) +- return 0; +- if (grub_ieee1275_get_integer_property (dev, "address", +- addr, sizeof (addr), &actual)) +- return 0; +- if (actual == 4) +- { +- grub_cmos_port = (volatile grub_uint8_t *) (grub_addr_t) addr[0]; +- return 1; +- } ++ grub_ieee1275_phandle_t dev; ++ grub_uint32_t addr[2]; ++ grub_ssize_t actual; ++ /* Enough to check if it's "m5819" */ ++ char compat[100]; ++ if (grub_ieee1275_finddevice (alias->path, &dev)) ++ return 0; ++ if (grub_ieee1275_get_property (dev, "compatible", compat, sizeof (compat), ++ 0)) ++ return 0; ++ if (grub_strcmp (compat, "m5819") != 0) ++ return 0; ++ if (grub_ieee1275_get_integer_property (dev, "address", ++ addr, sizeof (addr), &actual)) ++ return 0; ++ if (actual == 4) ++ { ++ grub_cmos_port = (volatile grub_uint8_t *) (grub_addr_t) addr[0]; ++ return 1; ++ } + + #if GRUB_CPU_SIZEOF_VOID_P == 8 +- if (actual == 8) +- { +- grub_cmos_port = (volatile grub_uint8_t *) +- ((((grub_addr_t) addr[0]) << 32) | addr[1]); +- return 1; +- } ++ if (actual == 8) ++ { ++ grub_cmos_port = (volatile grub_uint8_t *) ++ ((((grub_addr_t) addr[0]) << 32) | addr[1]); ++ return 1; ++ } + #else +- if (actual == 8 && addr[0] == 0) +- { +- grub_cmos_port = (volatile grub_uint8_t *) addr[1]; +- return 1; +- } ++ if (actual == 8 && addr[0] == 0) ++ { ++ grub_cmos_port = (volatile grub_uint8_t *) addr[1]; ++ return 1; ++ } + #endif +- return 0; +- } +- +- grub_ieee1275_devices_iterate (hook); ++ return 0; ++} ++ ++grub_err_t ++grub_cmos_find_port (void) ++{ ++ grub_ieee1275_devices_iterate (grub_cmos_find_port_iter); + if (!grub_cmos_port) + return grub_error (GRUB_ERR_IO, "no cmos found"); + +diff --git a/grub-core/lib/ieee1275/datetime.c b/grub-core/lib/ieee1275/datetime.c +index 8792429..74578f1 100644 +--- a/grub-core/lib/ieee1275/datetime.c ++++ b/grub-core/lib/ieee1275/datetime.c +@@ -30,22 +30,23 @@ GRUB_MOD_LICENSE ("GPLv3+"); + static char *rtc = 0; + static int no_ieee1275_rtc = 0; + ++/* Helper for find_rtc. */ ++static int ++find_rtc_iter (struct grub_ieee1275_devalias *alias) ++{ ++ if (grub_strcmp (alias->type, "rtc") == 0) ++ { ++ grub_dprintf ("datetime", "Found RTC %s\n", alias->path); ++ rtc = grub_strdup (alias->path); ++ return 1; ++ } ++ return 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->path); +- rtc = grub_strdup (alias->path); +- return 1; +- } +- return 0; +- } +- +- grub_ieee1275_devices_iterate (hook); ++ grub_ieee1275_devices_iterate (find_rtc_iter); + if (!rtc) + no_ieee1275_rtc = 1; + } +diff --git a/grub-core/normal/menu_entry.c b/grub-core/normal/menu_entry.c +index 8e2b4da..33b644b 100644 +--- a/grub-core/normal/menu_entry.c ++++ b/grub-core/normal/menu_entry.c +@@ -1205,32 +1205,6 @@ run (struct screen *screen) + grub_menu_t menu = NULL; + char *dummy[1] = { NULL }; + +- auto char * editor_getsource (void); +- char * editor_getsource (void) +- { +- int i; +- grub_size_t size = 0, tot_size = 0; +- char *source; +- +- for (i = 0; i < screen->num_lines; i++) +- tot_size += grub_get_num_of_utf8_bytes (screen->lines[i].buf, +- screen->lines[i].len) + 1; +- +- source = grub_malloc (tot_size + 1); +- if (! source) +- return NULL; +- +- for (i = 0; i < screen->num_lines; i++) +- { +- size += grub_ucs4_to_utf8 (screen->lines[i].buf, screen->lines[i].len, +- (grub_uint8_t *) source + size, +- tot_size - size); +- source[size++] = '\n'; +- } +- source[size] = '\0'; +- return source; +- } +- + grub_cls (); + grub_printf (" "); + grub_printf_ (N_("Booting a command list")); +@@ -1248,9 +1222,27 @@ run (struct screen *screen) + } + + /* Execute the script, line for line. */ +- script = editor_getsource (); +- if (! script) +- return 0; ++ { ++ int i; ++ grub_size_t size = 0, tot_size = 0; ++ ++ for (i = 0; i < screen->num_lines; i++) ++ tot_size += grub_get_num_of_utf8_bytes (screen->lines[i].buf, ++ screen->lines[i].len) + 1; ++ ++ script = grub_malloc (tot_size + 1); ++ if (! script) ++ return 0; ++ ++ for (i = 0; i < screen->num_lines; i++) ++ { ++ size += grub_ucs4_to_utf8 (screen->lines[i].buf, screen->lines[i].len, ++ (grub_uint8_t *) script + size, ++ tot_size - size); ++ script[size++] = '\n'; ++ } ++ script[size] = '\0'; ++ } + grub_script_execute_sourcecode (script, 0, dummy); + grub_free (script); + +-- +1.8.1.4 + diff --git a/0075-docs-grub.texi-configfile-Explain-environment-variab.patch b/0075-docs-grub.texi-configfile-Explain-environment-variab.patch new file mode 100644 index 0000000..81d6b24 --- /dev/null +++ b/0075-docs-grub.texi-configfile-Explain-environment-variab.patch @@ -0,0 +1,73 @@ +From bf9d0c7cfcc093b873d6d4c594cd407dc6bca69c Mon Sep 17 00:00:00 2001 +From: Colin Watson +Date: Wed, 2 Jan 2013 09:29:48 +0000 +Subject: [PATCH 075/364] * docs/grub.texi (configfile): Explain environment + variable handling. (source): New section. Reported by: Arbiel Perlacremaz. + Fixes Savannah bug #35564. + +--- + ChangeLog | 7 +++++++ + docs/grub.texi | 18 +++++++++++++++++- + 2 files changed, 24 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index 8723bfa..68920bf 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,10 @@ ++2013-01-02 Colin Watson ++ ++ * docs/grub.texi (configfile): Explain environment variable ++ handling. ++ (source): New section. ++ Reported by: Arbiel Perlacremaz. Fixes Savannah bug #35564. ++ + 2012-12-31 Colin Watson + + Remove several trivially-unnecessary uses of nested functions. +diff --git a/docs/grub.texi b/docs/grub.texi +index 39d9614..e9af377 100644 +--- a/docs/grub.texi ++++ b/docs/grub.texi +@@ -3303,6 +3303,7 @@ you forget a command, you can run the command @command{help} + * search:: Search devices by file, label, or UUID + * sendkey:: Emulate keystrokes + * set:: Set an environment variable ++* source:: Read a configuration file in same context + * true:: Do nothing, successfully + * unset:: Unset an environment variable + * uppermem:: Set the upper memory size +@@ -3429,7 +3430,9 @@ If they are completely identical, nothing will be printed. + + @deffn Command configfile file + Load @var{file} as a configuration file. If @var{file} defines any menu +-entries, then show a menu containing them immediately. ++entries, then show a menu containing them immediately. Any environment ++variable changes made by the commands in @var{file} will not be preserved ++after @command{configfile} returns. + @end deffn + + +@@ -4069,6 +4072,19 @@ arguments, print all environment variables with their values. + @end deffn + + ++@node source ++@subsection source ++ ++@deffn Command source file ++Read @var{file} as a configuration file, as if its contents had been ++incorporated directly into the sourcing file. Unlike @command{configfile} ++(@pxref{configfile}), this executes the contents of @var{file} without ++changing context: any environment variable changes made by the commands in ++@var{file} will be preserved after @command{source} returns, and the menu ++will not be shown immediately. ++@end deffn ++ ++ + @node true + @subsection true + +-- +1.8.1.4 + diff --git a/0076-Fix-failing-printf-test.patch b/0076-Fix-failing-printf-test.patch new file mode 100644 index 0000000..62898f2 --- /dev/null +++ b/0076-Fix-failing-printf-test.patch @@ -0,0 +1,70 @@ +From bd0f06eea6be3f3e2efb07069f853741867a320f Mon Sep 17 00:00:00 2001 +From: Colin Watson +Date: Wed, 2 Jan 2013 12:48:31 +0000 +Subject: [PATCH 076/364] Fix failing printf test. + +* grub-core/kern/misc.c (grub_vsnprintf_real): Parse '-', '.', and +'$' in the correct order when collecting type information. +--- + ChangeLog | 7 +++++++ + grub-core/kern/misc.c | 17 ++++++++++------- + 2 files changed, 17 insertions(+), 7 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 68920bf..bb263f2 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,12 @@ + 2013-01-02 Colin Watson + ++ Fix failing printf test. ++ ++ * grub-core/kern/misc.c (grub_vsnprintf_real): Parse '-', '.', and ++ '$' in the correct order when collecting type information. ++ ++2013-01-02 Colin Watson ++ + * docs/grub.texi (configfile): Explain environment variable + handling. + (source): New section. +diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c +index 95d4624..c3203a0 100644 +--- a/grub-core/kern/misc.c ++++ b/grub-core/kern/misc.c +@@ -741,23 +741,26 @@ grub_vsnprintf_real (char *str, grub_size_t max_len, const char *fmt0, va_list a + if (*fmt && *fmt =='-') + fmt++; + +- while (*fmt && grub_isdigit (*fmt)) +- fmt++; +- +- if (*fmt && *fmt =='.') +- fmt++; ++ p = fmt; + + while (*fmt && grub_isdigit (*fmt)) + fmt++; + +- p = fmt; +- + if (*fmt && *fmt == '$') + { + curn = grub_strtoull (p, 0, 10) - 1; + fmt++; + } + ++ if (*fmt && *fmt =='-') ++ fmt++; ++ ++ while (*fmt && grub_isdigit (*fmt)) ++ fmt++; ++ ++ if (*fmt && *fmt =='.') ++ fmt++; ++ + while (*fmt && grub_isdigit (*fmt)) + fmt++; + +-- +1.8.1.4 + diff --git a/0077-grub-core-tests-lib-test.c-grub_test_run-Return-non-.patch b/0077-grub-core-tests-lib-test.c-grub_test_run-Return-non-.patch new file mode 100644 index 0000000..7196830 --- /dev/null +++ b/0077-grub-core-tests-lib-test.c-grub_test_run-Return-non-.patch @@ -0,0 +1,55 @@ +From 1fb2a38cdc4278a0c65e9b0cbca6fdaae3343564 Mon Sep 17 00:00:00 2001 +From: Colin Watson +Date: Wed, 2 Jan 2013 16:42:48 +0000 +Subject: [PATCH 077/364] * grub-core/tests/lib/test.c (grub_test_run): Return + non-zero on test failures, so that a failing unit test correctly causes 'make + check' to fail. + +--- + ChangeLog | 6 ++++++ + grub-core/tests/lib/test.c | 14 +++++++++----- + 2 files changed, 15 insertions(+), 5 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index bb263f2..0585437 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,11 @@ + 2013-01-02 Colin Watson + ++ * grub-core/tests/lib/test.c (grub_test_run): Return non-zero on ++ test failures, so that a failing unit test correctly causes 'make ++ check' to fail. ++ ++2013-01-02 Colin Watson ++ + Fix failing printf test. + + * grub-core/kern/misc.c (grub_vsnprintf_real): Parse '-', '.', and +diff --git a/grub-core/tests/lib/test.c b/grub-core/tests/lib/test.c +index aac77e9..1d2cb8c 100644 +--- a/grub-core/tests/lib/test.c ++++ b/grub-core/tests/lib/test.c +@@ -225,10 +225,14 @@ grub_test_run (grub_test_t test) + failure->line, (failure->message ? : "")); + + if (!failure_list) +- grub_printf ("%s: PASS\n", test->name); ++ { ++ grub_printf ("%s: PASS\n", test->name); ++ return GRUB_ERR_NONE; ++ } + else +- grub_printf ("%s: FAIL\n", test->name); +- +- free_failures (); +- return GRUB_ERR_NONE; ++ { ++ grub_printf ("%s: FAIL\n", test->name); ++ free_failures (); ++ return GRUB_ERR_TEST_FAILURE; ++ } + } +-- +1.8.1.4 + diff --git a/0078-docs-grub.texi-Invoking-grub-mount-New-section.patch b/0078-docs-grub.texi-Invoking-grub-mount-New-section.patch new file mode 100644 index 0000000..af5f7f2 --- /dev/null +++ b/0078-docs-grub.texi-Invoking-grub-mount-New-section.patch @@ -0,0 +1,150 @@ +From 9a3cdbccd18ddda45d3e69de75d6c4865da72aae Mon Sep 17 00:00:00 2001 +From: Colin Watson +Date: Thu, 3 Jan 2013 10:32:57 +0000 +Subject: [PATCH 078/364] * docs/grub.texi (Invoking grub-mount): New section. + Reported by: Filipus Klutiero. Fixes Debian bug #666427. + +--- + ChangeLog | 5 ++++ + docs/grub.texi | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- + 2 files changed, 95 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index 0585437..c91fe35 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,8 @@ ++2013-01-03 Colin Watson ++ ++ * docs/grub.texi (Invoking grub-mount): New section. ++ Reported by: Filipus Klutiero. Fixes Debian bug #666427. ++ + 2013-01-02 Colin Watson + + * grub-core/tests/lib/test.c (grub_test_run): Return non-zero on +diff --git a/docs/grub.texi b/docs/grub.texi +index e9af377..60b18b5 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,2010,2011,2012 Free Software Foundation, Inc. ++Copyright @copyright{} 1999,2000,2001,2002,2004,2006,2008,2009,2010,2011,2012,2013 Free Software Foundation, Inc. + + @quotation + Permission is granted to copy, distribute and/or modify this document +@@ -37,6 +37,7 @@ Invariant Sections. + * grub-mkconfig: (grub)Invoking grub-mkconfig. Generate GRUB configuration + * grub-mkpasswd-pbkdf2: (grub)Invoking grub-mkpasswd-pbkdf2. + * grub-mkrescue: (grub)Invoking grub-mkrescue. Make a GRUB rescue image ++* grub-mount: (grub)Invoking grub-mount. Mount a file system using GRUB + * grub-probe: (grub)Invoking grub-probe. Probe device information + @end direntry + +@@ -101,6 +102,7 @@ This edition documents version @value{VERSION}. + * Invoking grub-mkpasswd-pbkdf2:: + Generate GRUB password hashes + * Invoking grub-mkrescue:: Make a GRUB rescue image ++* Invoking grub-mount:: Mount a file system using GRUB + * Invoking grub-probe:: Probe device information for GRUB + * Obtaining and Building GRUB:: How to obtain and build GRUB + * Reporting bugs:: Where you should send a bug report +@@ -4830,6 +4832,93 @@ built-in default. + @end table + + ++@node Invoking grub-mount ++@chapter Invoking grub-mount ++ ++The program @command{grub-mount} performs a read-only mount of any file ++system or file system image that GRUB understands, using GRUB's file system ++drivers via FUSE. (It is only available if FUSE development files were ++present when GRUB was built.) This has a number of uses: ++ ++@itemize @bullet ++@item ++It provides a convenient way to check how GRUB will view a file system at ++boot time. You can use normal command-line tools to compare that view with ++that of your operating system, making it easy to find bugs. ++ ++@item ++It offers true read-only mounts. Linux does not have these for journalling ++file systems, because it will always attempt to replay the journal at mount ++time; while you can temporarily mark the block device read-only to avoid ++this, that causes the mount to fail. Since GRUB intentionally contains no ++code for writing to file systems, it can easily provide a guaranteed ++read-only mount mechanism. ++ ++@item ++It allows you to examine any file system that GRUB understands without ++needing to load additional modules into your running kernel, which may be ++useful in constrained environments such as installers. ++ ++@item ++Since it can examine file system images (contained in regular files) just as ++easily as file systems on block devices, you can use it to inspect any file ++system image that GRUB understands with only enough privileges to use FUSE, ++even if nobody has yet written a FUSE module specifically for that file ++system type. ++@end itemize ++ ++Using @command{grub-mount} is normally as simple as: ++ ++@example ++grub-mount /dev/sda1 /mnt ++@end example ++ ++@command{grub-mount} must be given one or more images and a mount point as ++non-option arguments (if it is given more than one image, it will treat them ++as a RAID set), and also 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 -C ++@itemx --crypto ++Mount encrypted devices, prompting for a passphrase if necessary. ++ ++@item -d @var{string} ++@itemx --debug=@var{string} ++Show debugging output for conditions matching @var{string}. ++ ++@item -K prompt|@var{file} ++@itemx --zfs-key=prompt|@var{file} ++Load a ZFS encryption key. If you use @samp{prompt} as the argument, ++@command{grub-mount} will read a passphrase from the terminal; otherwise, it ++will read key material from the specified file. ++ ++@item -r @var{device} ++@itemx --root=@var{device} ++Set the GRUB root device to @var{device}. You do not normally need to set ++this; @command{grub-mount} will automatically set the root device to the ++root of the supplied file system. ++ ++If @var{device} is just a number, then it will be treated as a partition ++number within the supplied image. This means that, if you have an image of ++an entire disk in @file{disk.img}, then you can use this command to mount ++its second partition: ++ ++@example ++grub-mount -r 2 disk.img mount-point ++@end example ++ ++@item -v ++@itemx --verbose ++Print verbose messages. ++@end table ++ ++ + @node Invoking grub-probe + @chapter Invoking grub-probe + +-- +1.8.1.4 + diff --git a/0079-docs-grub.texi-Invoking-grub-mkrelpath-New-section.patch b/0079-docs-grub.texi-Invoking-grub-mkrelpath-New-section.patch new file mode 100644 index 0000000..95bab20 --- /dev/null +++ b/0079-docs-grub.texi-Invoking-grub-mkrelpath-New-section.patch @@ -0,0 +1,125 @@ +From 3d109c87aec982045fd78e0937589af98eb0ad38 Mon Sep 17 00:00:00 2001 +From: Colin Watson +Date: Thu, 3 Jan 2013 10:53:53 +0000 +Subject: [PATCH 079/364] * docs/grub.texi (Invoking grub-mkrelpath): New + section. (Invoking grub-script-check): Likewise. + +--- + ChangeLog | 5 +++++ + docs/grub.texi | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 63 insertions(+) + +diff --git a/ChangeLog b/ChangeLog +index c91fe35..e530ac3 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,10 @@ + 2013-01-03 Colin Watson + ++ * docs/grub.texi (Invoking grub-mkrelpath): New section. ++ (Invoking grub-script-check): Likewise. ++ ++2013-01-03 Colin Watson ++ + * docs/grub.texi (Invoking grub-mount): New section. + Reported by: Filipus Klutiero. Fixes Debian bug #666427. + +diff --git a/docs/grub.texi b/docs/grub.texi +index 60b18b5..e23cecc 100644 +--- a/docs/grub.texi ++++ b/docs/grub.texi +@@ -36,9 +36,11 @@ Invariant Sections. + * 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. ++* grub-mkrelpath: (grub)Invoking grub-mkrelpath. + * grub-mkrescue: (grub)Invoking grub-mkrescue. Make a GRUB rescue image + * grub-mount: (grub)Invoking grub-mount. Mount a file system using GRUB + * grub-probe: (grub)Invoking grub-probe. Probe device information ++* grub-script-check: (grub)Invoking grub-script-check. + @end direntry + + @setchapternewpage odd +@@ -101,9 +103,11 @@ This edition documents version @value{VERSION}. + * Invoking grub-mkconfig:: Generate a GRUB configuration file + * Invoking grub-mkpasswd-pbkdf2:: + Generate GRUB password hashes ++* Invoking grub-mkrelpath:: Make system path relative to its root + * Invoking grub-mkrescue:: Make a GRUB rescue image + * Invoking grub-mount:: Mount a file system using GRUB + * Invoking grub-probe:: Probe device information for GRUB ++* Invoking grub-script-check:: Check GRUB script file for syntax errors + * 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 +@@ -4774,6 +4778,33 @@ Length of the salt. Defaults to 64. + @end table + + ++@node Invoking grub-mkrelpath ++@chapter Invoking grub-mkrelpath ++ ++The program @command{grub-mkrelpath} makes a file system path relative to ++the root of its containing file system. For instance, if @file{/usr} is a ++mount point, then: ++ ++@example ++$ @kbd{grub-mkrelpath /usr/share/grub/unicode.pf2} ++@samp{/share/grub/unicode.pf2} ++@end example ++ ++This is mainly used internally by other GRUB utilities such as ++@command{grub-mkconfig} (@pxref{Invoking grub-mkconfig}), but may ++occasionally also be useful for debugging. ++ ++@command{grub-mkrelpath} 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. ++@end table ++ ++ + @node Invoking grub-mkrescue + @chapter Invoking grub-mkrescue + +@@ -5005,6 +5036,33 @@ Print verbose messages. + @end table + + ++@node Invoking grub-script-check ++@chapter Invoking grub-script-check ++ ++The program @command{grub-script-check} takes a GRUB script file ++(@pxref{Shell-like scripting}) and checks it for syntax errors, similar to ++commands such as @command{sh -n}. It may take a @var{path} as a non-option ++argument; if none is supplied, it will read from standard input. ++ ++@example ++grub-script-check /boot/grub/grub.cfg ++@end example ++ ++@command{grub-script-check} 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 -v ++@itemx --verbose ++Print each line of input after reading it. ++@end table ++ ++ + @node Obtaining and Building GRUB + @appendix How to obtain and build GRUB + +-- +1.8.1.4 + diff --git a/0080-grub-core-fs-iso9660.c-grub_iso9660_susp_iterate-Avo.patch b/0080-grub-core-fs-iso9660.c-grub_iso9660_susp_iterate-Avo.patch new file mode 100644 index 0000000..e1a84fd --- /dev/null +++ b/0080-grub-core-fs-iso9660.c-grub_iso9660_susp_iterate-Avo.patch @@ -0,0 +1,40 @@ +From 7adc96e903f5581b38ba397a6d4d93f923b2fc5e Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Thu, 3 Jan 2013 21:27:00 +0100 +Subject: [PATCH 080/364] * grub-core/fs/iso9660.c + (grub_iso9660_susp_iterate): Avoid hang if entry->len = 0. + +--- + ChangeLog | 5 +++++ + grub-core/fs/iso9660.c | 2 +- + 2 files changed, 6 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index e530ac3..2717f8a 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,8 @@ ++2013-01-03 Vladimir Serbinenko ++ ++ * grub-core/fs/iso9660.c (grub_iso9660_susp_iterate): Avoid hang if ++ entry->len = 0. ++ + 2013-01-03 Colin Watson + + * docs/grub.texi (Invoking grub-mkrelpath): New section. +diff --git a/grub-core/fs/iso9660.c b/grub-core/fs/iso9660.c +index cd4acc8..547e156 100644 +--- a/grub-core/fs/iso9660.c ++++ b/grub-core/fs/iso9660.c +@@ -295,7 +295,7 @@ grub_iso9660_susp_iterate (grub_fshelp_node_t node, grub_off_t off, + if (load_sua ()) + return grub_errno; + +- for (; (char *) entry < (char *) sua + sua_size - 1; ++ for (; (char *) entry < (char *) sua + sua_size - 1 && entry->len > 0; + entry = (struct grub_iso9660_susp_entry *) + ((char *) entry + entry->len)) + { +-- +1.8.1.4 + diff --git a/0081-configure.ac-Extend-Wno-trampolines-to-host.patch b/0081-configure.ac-Extend-Wno-trampolines-to-host.patch new file mode 100644 index 0000000..fe87f9d --- /dev/null +++ b/0081-configure.ac-Extend-Wno-trampolines-to-host.patch @@ -0,0 +1,56 @@ +From 242ce139276b9de1e5f960070e433111a3ab5194 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Thu, 3 Jan 2013 21:34:34 +0100 +Subject: [PATCH 081/364] * configure.ac: Extend -Wno-trampolines to + host. + +--- + ChangeLog | 4 ++++ + configure.ac | 17 +++++++++++++++++ + 2 files changed, 21 insertions(+) + +diff --git a/ChangeLog b/ChangeLog +index 2717f8a..087b5c3 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,9 @@ + 2013-01-03 Vladimir Serbinenko + ++ * configure.ac: Extend -Wno-trampolines to host. ++ ++2013-01-03 Vladimir Serbinenko ++ + * grub-core/fs/iso9660.c (grub_iso9660_susp_iterate): Avoid hang if + entry->len = 0. + +diff --git a/configure.ac b/configure.ac +index a41f117..dde954e 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -358,6 +358,23 @@ AC_CHECK_HEADER([util.h], [ + ]) + AC_SUBST([LIBUTIL]) + ++AC_CACHE_CHECK([whether -Wno-trampolines work], [grub_cv_host_cc_wnotrampolines], [ ++ SAVED_CFLAGS="$CFLAGS" ++ # Test for -Wtrampolines rather than -Wno-trampolines to reduce confusion ++ # in the event of later failures (since -Wno-* is always accepted, but ++ # produces a diagnostic if something else is wrong). ++ CFLAGS="$HOST_CFLAGS -Wtrampolines" ++ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ++int va_arg_func (int fixed, va_list args);]], [[]])], ++ [grub_cv_host_cc_wnotrampolines=yes], ++ [grub_cv_host_cc_wnotrampolines=no]) ++ CFLAGS="$SAVED_CFLAGS" ++]) ++ ++if test x"$grub_host_cv_cc_wnotrampolines" = xyes ; then ++ HOST_CFLAGS="$HOST_CFLAGS -Wno-trampolines" ++fi ++ + # + # Check for host and build compilers. + # +-- +1.8.1.4 + diff --git a/0082-util-grub.d-10_kfreebsd.in-Fix-improper-references-t.patch b/0082-util-grub.d-10_kfreebsd.in-Fix-improper-references-t.patch new file mode 100644 index 0000000..8792821 --- /dev/null +++ b/0082-util-grub.d-10_kfreebsd.in-Fix-improper-references-t.patch @@ -0,0 +1,58 @@ +From 98701532f45165422f45b8cdf405a7f0abf03fba Mon Sep 17 00:00:00 2001 +From: Yuta Satoh +Date: Thu, 3 Jan 2013 23:06:07 +0100 +Subject: [PATCH 082/364] * util/grub.d/10_kfreebsd.in: Fix improper + references to grub-probe by ${grub_probe} + +--- + ChangeLog | 5 +++++ + util/grub.d/10_kfreebsd.in | 6 +++--- + 2 files changed, 8 insertions(+), 3 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 087b5c3..936af2f 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,8 @@ ++2013-01-03 Yuta Satoh ++ ++ * util/grub.d/10_kfreebsd.in: Fix improper references to grub-probe by ++ ${grub_probe} ++ + 2013-01-03 Vladimir Serbinenko + + * configure.ac: Extend -Wno-trampolines to host. +diff --git a/util/grub.d/10_kfreebsd.in b/util/grub.d/10_kfreebsd.in +index 260dda8..2a48b52 100644 +--- a/util/grub.d/10_kfreebsd.in ++++ b/util/grub.d/10_kfreebsd.in +@@ -54,7 +54,7 @@ load_kfreebsd_module () + fi + + if [ -z "${prepare_module_dir_cache}" ]; then +- prepare_module_dir_cache="$(prepare_grub_to_access_device $(grub-probe -t device "${module_dir}") | grub_add_tab)" ++ prepare_module_dir_cache="$(prepare_grub_to_access_device $(${grub_probe} -t device "${module_dir}") | grub_add_tab)" + fi + + printf '%s\n' "${prepare_module_dir_cache}" +@@ -112,7 +112,7 @@ EOF + + load_kfreebsd_module acpi true + +- for abstraction in dummy $(grub-probe -t abstraction --device ${GRUB_DEVICE}) ; do ++ for abstraction in dummy $(${grub_probe} -t abstraction --device ${GRUB_DEVICE}) ; do + case $abstraction in + lvm) load_kfreebsd_module geom_linux_lvm false ;; + esac +@@ -179,7 +179,7 @@ while [ "x$list" != "x" ] ; do + case ${GRUB_FS} in + zfs) + # zpool name +- kfreebsd_device=$(grub-probe -t fs_label --device ${GRUB_DEVICE}) ++ kfreebsd_device=$(${grub_probe} -t fs_label --device ${GRUB_DEVICE}) + # filesystem name (empty string for the main filesystem) + kfreebsd_device="${kfreebsd_device}$(${grub_mkrelpath} / | sed -e "s,/*@$,,")" + ;; +-- +1.8.1.4 + diff --git a/0083-util-grub.d-10_kfreebsd.in-Correct-the-patch-to-zpoo.patch b/0083-util-grub.d-10_kfreebsd.in-Correct-the-patch-to-zpoo.patch new file mode 100644 index 0000000..adbf885 --- /dev/null +++ b/0083-util-grub.d-10_kfreebsd.in-Correct-the-patch-to-zpoo.patch @@ -0,0 +1,46 @@ +From 40951063e5fd8c4ae34b942039d38bfe69ffecb3 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Thu, 3 Jan 2013 23:19:19 +0100 +Subject: [PATCH 083/364] * util/grub.d/10_kfreebsd.in: Correct the + patch to zpool.cache as it's always in /boot/zfs. Reported by: Yuta + Satoh. + +--- + ChangeLog | 6 ++++++ + util/grub.d/10_kfreebsd.in | 4 ++-- + 2 files changed, 8 insertions(+), 2 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 936af2f..a28a1f7 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,9 @@ ++2013-01-03 Vladimir Serbinenko ++ ++ * util/grub.d/10_kfreebsd.in: Correct the patch to zpool.cache as it's ++ always in /boot/zfs. ++ Reported by: Yuta Satoh. ++ + 2013-01-03 Yuta Satoh + + * util/grub.d/10_kfreebsd.in: Fix improper references to grub-probe by +diff --git a/util/grub.d/10_kfreebsd.in b/util/grub.d/10_kfreebsd.in +index 2a48b52..c123ceb 100644 +--- a/util/grub.d/10_kfreebsd.in ++++ b/util/grub.d/10_kfreebsd.in +@@ -122,10 +122,10 @@ EOF + zfs) + load_kfreebsd_module opensolaris false + +- ls "${dirname}/zfs/zpool.cache" > /dev/null ++ ls "/boot/zfs/zpool.cache" > /dev/null + printf '%s\n' "${prepare_boot_cache}" + sed "s/^/$submenu_indentation/" << EOF +- kfreebsd_module ${rel_dirname}/zfs/zpool.cache type=/boot/zfs/zpool.cache ++ kfreebsd_module $(make_system_path_relative_to_its_root /boot)/zfs/zpool.cache type=/boot/zfs/zpool.cache + EOF + ;; + esac +-- +1.8.1.4 + diff --git a/0084-grub-core-disk-diskfilter.c-grub_diskfilter_write-Ca.patch b/0084-grub-core-disk-diskfilter.c-grub_diskfilter_write-Ca.patch new file mode 100644 index 0000000..4a3b5db --- /dev/null +++ b/0084-grub-core-disk-diskfilter.c-grub_diskfilter_write-Ca.patch @@ -0,0 +1,75 @@ +From d064a7c4f3cc8a5faba4d4bc4f4ba82677c7b1d7 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sat, 5 Jan 2013 15:10:46 +0100 +Subject: [PATCH 084/364] * grub-core/disk/diskfilter.c + (grub_diskfilter_write): Call grub_error properly. * + grub-core/disk/ieee1275/nand.c (grub_nand_write): Likewise. * + grub-core/disk/loopback.c (grub_loopback_write): Likewise. + +--- + ChangeLog | 7 +++++++ + grub-core/disk/diskfilter.c | 3 ++- + grub-core/disk/ieee1275/nand.c | 3 ++- + grub-core/disk/loopback.c | 3 ++- + 4 files changed, 13 insertions(+), 3 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index a28a1f7..f15e098 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,10 @@ ++2013-01-05 Vladimir Serbinenko ++ ++ * grub-core/disk/diskfilter.c (grub_diskfilter_write): Call ++ grub_error properly. ++ * grub-core/disk/ieee1275/nand.c (grub_nand_write): Likewise. ++ * grub-core/disk/loopback.c (grub_loopback_write): Likewise. ++ + 2013-01-03 Vladimir Serbinenko + + * util/grub.d/10_kfreebsd.in: Correct the patch to zpool.cache as it's +diff --git a/grub-core/disk/diskfilter.c b/grub-core/disk/diskfilter.c +index ce4c706..4117b20 100644 +--- a/grub-core/disk/diskfilter.c ++++ b/grub-core/disk/diskfilter.c +@@ -831,7 +831,8 @@ grub_diskfilter_write (grub_disk_t disk __attribute ((unused)), + grub_size_t size __attribute ((unused)), + const char *buf __attribute ((unused))) + { +- return GRUB_ERR_NOT_IMPLEMENTED_YET; ++ return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, ++ "diskfilter writes are not supported"); + } + + struct grub_diskfilter_vg * +diff --git a/grub-core/disk/ieee1275/nand.c b/grub-core/disk/ieee1275/nand.c +index ad30852..3474b3e 100644 +--- a/grub-core/disk/ieee1275/nand.c ++++ b/grub-core/disk/ieee1275/nand.c +@@ -203,7 +203,8 @@ grub_nand_write (grub_disk_t disk __attribute ((unused)), + grub_size_t size __attribute ((unused)), + const char *buf __attribute ((unused))) + { +- return GRUB_ERR_NOT_IMPLEMENTED_YET; ++ return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, ++ "nand write is not supported"); + } + + static struct grub_disk_dev grub_nand_dev = +diff --git a/grub-core/disk/loopback.c b/grub-core/disk/loopback.c +index f3b19ef..fffd1bb 100644 +--- a/grub-core/disk/loopback.c ++++ b/grub-core/disk/loopback.c +@@ -206,7 +206,8 @@ grub_loopback_write (grub_disk_t disk __attribute ((unused)), + grub_size_t size __attribute ((unused)), + const char *buf __attribute ((unused))) + { +- return GRUB_ERR_NOT_IMPLEMENTED_YET; ++ return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, ++ "loopback write is not supported"); + } + + static struct grub_disk_dev grub_loopback_dev = +-- +1.8.1.4 + diff --git a/0085-grub-core-fs-nilfs2.c-grub_nilfs2_palloc_groups_per_.patch b/0085-grub-core-fs-nilfs2.c-grub_nilfs2_palloc_groups_per_.patch new file mode 100644 index 0000000..4ddd0ca --- /dev/null +++ b/0085-grub-core-fs-nilfs2.c-grub_nilfs2_palloc_groups_per_.patch @@ -0,0 +1,93 @@ +From 3ba196532002293027a6a3e96f8eb1960c70e00c Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sat, 5 Jan 2013 16:53:04 +0100 +Subject: [PATCH 085/364] * grub-core/fs/nilfs2.c + (-grub_nilfs2_palloc_groups_per_desc_block): Rename to ... + (grub_nilfs2_palloc_log_groups_per_desc_block): ... this. Return log of + groups_per_block. All users updated. + +--- + ChangeLog | 7 +++++++ + grub-core/fs/nilfs2.c | 20 ++++++++++++-------- + 2 files changed, 19 insertions(+), 8 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index f15e098..ea191b3 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,12 @@ + 2013-01-05 Vladimir Serbinenko + ++ * grub-core/fs/nilfs2.c (-grub_nilfs2_palloc_groups_per_desc_block): ++ Rename to ... ++ (grub_nilfs2_palloc_log_groups_per_desc_block): ... this. Return log ++ of groups_per_block. All users updated. ++ ++2013-01-05 Vladimir Serbinenko ++ + * grub-core/disk/diskfilter.c (grub_diskfilter_write): Call + grub_error properly. + * grub-core/disk/ieee1275/nand.c (grub_nand_write): Likewise. +diff --git a/grub-core/fs/nilfs2.c b/grub-core/fs/nilfs2.c +index f36c513..5b34486 100644 +--- a/grub-core/fs/nilfs2.c ++++ b/grub-core/fs/nilfs2.c +@@ -214,6 +214,8 @@ struct grub_nilfs2_palloc_group_desc + grub_uint32_t pg_nfrees; + }; + ++#define LOG_SIZE_GROUP_DESC 2 ++ + #define LOG_NILFS_DAT_ENTRY_SIZE 5 + struct grub_nilfs2_dat_entry + { +@@ -311,10 +313,12 @@ grub_nilfs2_palloc_group (struct grub_nilfs2_data *data, + } + + static inline grub_uint32_t +-grub_nilfs2_palloc_groups_per_desc_block (struct grub_nilfs2_data *data) ++grub_nilfs2_palloc_log_groups_per_desc_block (struct grub_nilfs2_data *data) + { +- return NILFS2_BLOCK_SIZE (data) / +- sizeof (struct grub_nilfs2_palloc_group_desc); ++ return LOG2_BLOCK_SIZE (data) - LOG_SIZE_GROUP_DESC; ++ ++ COMPILE_TIME_ASSERT (sizeof (struct grub_nilfs2_palloc_group_desc) ++ == (1 << LOG_SIZE_GROUP_DESC)); + } + + static inline grub_uint32_t +@@ -338,8 +342,8 @@ static inline grub_uint32_t + grub_nilfs2_blocks_per_desc_block_log (struct grub_nilfs2_data *data, + unsigned long log_entry_size) + { +- return grub_nilfs2_palloc_groups_per_desc_block (data) * +- grub_nilfs2_blocks_per_group_log (data, log_entry_size) + 1; ++ return(grub_nilfs2_blocks_per_group_log (data, log_entry_size) ++ << grub_nilfs2_palloc_log_groups_per_desc_block (data)) + 1; + } + + static inline grub_uint32_t +@@ -348,7 +352,7 @@ grub_nilfs2_palloc_desc_block_offset_log (struct grub_nilfs2_data *data, + unsigned long log_entry_size) + { + grub_uint32_t desc_block = +- group / grub_nilfs2_palloc_groups_per_desc_block (data); ++ group >> grub_nilfs2_palloc_log_groups_per_desc_block (data); + return desc_block * grub_nilfs2_blocks_per_desc_block_log (data, + log_entry_size); + } +@@ -358,8 +362,8 @@ grub_nilfs2_palloc_bitmap_block_offset (struct grub_nilfs2_data *data, + unsigned long group, + unsigned long log_entry_size) + { +- unsigned long desc_offset = group % +- grub_nilfs2_palloc_groups_per_desc_block (data); ++ unsigned long desc_offset = group ++ & ((1 << grub_nilfs2_palloc_log_groups_per_desc_block (data)) - 1); + + return grub_nilfs2_palloc_desc_block_offset_log (data, group, log_entry_size) + + 1 +-- +1.8.1.4 + diff --git a/0086-grub-core-fs-ntfs.c-Eliminate-useless-divisions-in-f.patch b/0086-grub-core-fs-ntfs.c-Eliminate-useless-divisions-in-f.patch new file mode 100644 index 0000000..127a015 --- /dev/null +++ b/0086-grub-core-fs-ntfs.c-Eliminate-useless-divisions-in-f.patch @@ -0,0 +1,330 @@ +From aa380d4323bcc4dae0f8bafdd074466f8bc5bcf5 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sat, 5 Jan 2013 17:36:04 +0100 +Subject: [PATCH 086/364] * grub-core/fs/ntfs.c: Eliminate useless + divisions in favor of shifts. * grub-core/fs/ntfscomp.c: Likewise. * + include/grub/ntfs.h (grub_ntfs_data): Replace spc with log_spc. + (grub_ntfs_comp): Likewise. + +--- + ChangeLog | 7 +++++++ + grub-core/fs/ntfs.c | 47 ++++++++++++++++++++++++----------------------- + grub-core/fs/ntfscomp.c | 39 ++++++++++++++++++++------------------- + include/grub/ntfs.h | 6 ++++-- + 4 files changed, 55 insertions(+), 44 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index ea191b3..88fd763 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,12 @@ + 2013-01-05 Vladimir Serbinenko + ++ * grub-core/fs/ntfs.c: Eliminate useless divisions in favor of shifts. ++ * grub-core/fs/ntfscomp.c: Likewise. ++ * include/grub/ntfs.h (grub_ntfs_data): Replace spc with log_spc. ++ (grub_ntfs_comp): Likewise. ++ ++2013-01-05 Vladimir Serbinenko ++ + * grub-core/fs/nilfs2.c (-grub_nilfs2_palloc_groups_per_desc_block): + Rename to ... + (grub_nilfs2_palloc_log_groups_per_desc_block): ... this. Return log +diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c +index b9762b6..6004e1f 100644 +--- a/grub-core/fs/ntfs.c ++++ b/grub-core/fs/ntfs.c +@@ -391,7 +391,7 @@ read_data (struct grub_ntfs_attr *at, char *pa, char *dest, + grub_memset (&cc, 0, sizeof (cc)); + ctx = &cc; + ctx->attr = at; +- ctx->comp.spc = at->mft->data->spc; ++ ctx->comp.log_spc = at->mft->data->log_spc; + ctx->comp.disk = at->mft->data->disk; + + if (pa[8] == 0) +@@ -440,11 +440,11 @@ read_data (struct grub_ntfs_attr *at, char *pa, char *dest, + at->save_pos = 1; + } + +- vcn = ctx->target_vcn = (ofs >> GRUB_NTFS_COM_LOG_LEN) * (GRUB_NTFS_COM_SEC / ctx->comp.spc); ++ vcn = ctx->target_vcn = (ofs >> GRUB_NTFS_COM_LOG_LEN) * (GRUB_NTFS_COM_SEC >> ctx->comp.log_spc); + ctx->target_vcn &= ~0xFULL; + } + else +- vcn = ctx->target_vcn = grub_divmod64 (ofs >> GRUB_NTFS_BLK_SHR, ctx->comp.spc, 0); ++ vcn = ctx->target_vcn = ofs >> (GRUB_NTFS_BLK_SHR + ctx->comp.log_spc); + + ctx->next_vcn = u32at (pa, 0x10); + ctx->curr_lcn = 0; +@@ -459,17 +459,17 @@ read_data (struct grub_ntfs_attr *at, char *pa, char *dest, + grub_disk_addr_t st0, st1; + grub_uint64_t m; + +- grub_divmod64 (ofs >> GRUB_NTFS_BLK_SHR, ctx->comp.spc, &m); ++ m = (ofs >> GRUB_NTFS_BLK_SHR) & ((1 << ctx->comp.log_spc) - 1); + + st0 = +- (ctx->target_vcn - ctx->curr_vcn + ctx->curr_lcn) * ctx->comp.spc + m; ++ ((ctx->target_vcn - ctx->curr_vcn + ctx->curr_lcn) << ctx->comp.log_spc) + m; + st1 = st0 + 1; + if (st1 == +- (ctx->next_vcn - ctx->curr_vcn + ctx->curr_lcn) * ctx->comp.spc) ++ (ctx->next_vcn - ctx->curr_vcn + ctx->curr_lcn) << ctx->comp.log_spc) + { + if (grub_ntfs_read_run_list (ctx)) + return grub_errno; +- st1 = ctx->curr_lcn * ctx->comp.spc; ++ st1 = ctx->curr_lcn << ctx->comp.log_spc; + } + grub_set_unaligned32 (dest, grub_cpu_to_le32 (st0)); + grub_set_unaligned32 (dest + 4, grub_cpu_to_le32 (st1)); +@@ -478,12 +478,10 @@ read_data (struct grub_ntfs_attr *at, char *pa, char *dest, + + if (!(ctx->flags & GRUB_NTFS_RF_COMP)) + { +- unsigned int pow; +- +- if (!grub_fshelp_log2blksize (ctx->comp.spc, &pow)) +- grub_fshelp_read_file (ctx->comp.disk, (grub_fshelp_node_t) ctx, +- read_hook, ofs, len, dest, +- grub_ntfs_read_block, ofs + len, pow, 0); ++ grub_fshelp_read_file (ctx->comp.disk, (grub_fshelp_node_t) ctx, ++ read_hook, ofs, len, dest, ++ grub_ntfs_read_block, ofs + len, ++ ctx->comp.log_spc, 0); + return grub_errno; + } + +@@ -515,11 +513,11 @@ read_attr (struct grub_ntfs_attr *at, char *dest, grub_disk_addr_t ofs, + + /* If compression is possible make sure that we include possible + compressed block size. */ +- if (GRUB_NTFS_COM_SEC >= at->mft->data->spc) ++ if (GRUB_NTFS_LOG_COM_SEC >= at->mft->data->log_spc) + vcn = ((ofs >> GRUB_NTFS_COM_LOG_LEN) +- * (GRUB_NTFS_COM_SEC / at->mft->data->spc)) & ~0xFULL; ++ << (GRUB_NTFS_LOG_COM_SEC - at->mft->data->log_spc)) & ~0xFULL; + else +- vcn = grub_divmod64 (ofs, at->mft->data->spc << GRUB_NTFS_BLK_SHR, 0); ++ vcn = ofs >> (at->mft->data->log_spc + GRUB_NTFS_BLK_SHR); + pa = at->attr_nxt + u16at (at->attr_nxt, 4); + while (pa < at->attr_end) + { +@@ -934,6 +932,7 @@ grub_ntfs_mount (grub_disk_t disk) + { + struct grub_ntfs_bpb bpb; + struct grub_ntfs_data *data = 0; ++ grub_uint32_t spc; + + if (!disk) + goto fail; +@@ -955,23 +954,25 @@ grub_ntfs_mount (grub_disk_t disk) + || (bpb.bytes_per_sector & (bpb.bytes_per_sector - 1)) != 0) + goto fail; + +- data->spc = (((grub_uint32_t) bpb.sectors_per_cluster +- * (grub_uint32_t) grub_le_to_cpu16 (bpb.bytes_per_sector)) +- >> GRUB_NTFS_BLK_SHR); +- if (!data->spc) ++ spc = (((grub_uint32_t) bpb.sectors_per_cluster ++ * (grub_uint32_t) grub_le_to_cpu16 (bpb.bytes_per_sector)) ++ >> GRUB_NTFS_BLK_SHR); ++ if (spc == 0 || (spc & (spc - 1))) + goto fail; + ++ for (data->log_spc = 0; (1U << data->log_spc) < spc; data->log_spc++); ++ + if (bpb.clusters_per_mft > 0) +- data->mft_size = data->spc * bpb.clusters_per_mft; ++ data->mft_size = bpb.clusters_per_mft << data->log_spc; + else + data->mft_size = 1 << (-bpb.clusters_per_mft - GRUB_NTFS_BLK_SHR); + + if (bpb.clusters_per_index > 0) +- data->idx_size = data->spc * bpb.clusters_per_index; ++ data->idx_size = bpb.clusters_per_index << data->log_spc; + else + data->idx_size = 1 << (-bpb.clusters_per_index - GRUB_NTFS_BLK_SHR); + +- data->mft_start = grub_le_to_cpu64 (bpb.mft_lcn) * data->spc; ++ data->mft_start = grub_le_to_cpu64 (bpb.mft_lcn) << data->log_spc; + + if ((data->mft_size > GRUB_NTFS_MAX_MFT) || (data->idx_size > GRUB_NTFS_MAX_IDX)) + goto fail; +diff --git a/grub-core/fs/ntfscomp.c b/grub-core/fs/ntfscomp.c +index ec359fa..9b3b75d 100644 +--- a/grub-core/fs/ntfscomp.c ++++ b/grub-core/fs/ntfscomp.c +@@ -33,8 +33,9 @@ decomp_nextvcn (struct grub_ntfs_comp *cc) + if (grub_disk_read + (cc->disk, + (cc->comp_table[cc->comp_head].next_lcn - +- (cc->comp_table[cc->comp_head].next_vcn - cc->cbuf_vcn)) * cc->spc, 0, +- cc->spc << GRUB_NTFS_BLK_SHR, cc->cbuf)) ++ (cc->comp_table[cc->comp_head].next_vcn - cc->cbuf_vcn)) << cc->log_spc, ++ 0, ++ 1 << (cc->log_spc + GRUB_NTFS_BLK_SHR), cc->cbuf)) + return grub_errno; + cc->cbuf_vcn++; + if ((cc->cbuf_vcn >= cc->comp_table[cc->comp_head].next_vcn)) +@@ -46,7 +47,7 @@ decomp_nextvcn (struct grub_ntfs_comp *cc) + static grub_err_t + decomp_getch (struct grub_ntfs_comp *cc, unsigned char *res) + { +- if (cc->cbuf_ofs >= (cc->spc << GRUB_NTFS_BLK_SHR)) ++ if (cc->cbuf_ofs >= (1U << (cc->log_spc + GRUB_NTFS_BLK_SHR))) + { + if (decomp_nextvcn (cc)) + return grub_errno; +@@ -159,7 +160,7 @@ decomp_block (struct grub_ntfs_comp *cc, char *dest) + { + int n; + +- n = (cc->spc << GRUB_NTFS_BLK_SHR) - cc->cbuf_ofs; ++ n = (1 << (cc->log_spc + GRUB_NTFS_BLK_SHR)) - cc->cbuf_ofs; + if (n > cnt) + n = cnt; + if ((dest) && (n)) +@@ -178,7 +179,7 @@ decomp_block (struct grub_ntfs_comp *cc, char *dest) + static grub_err_t + read_block (struct grub_ntfs_rlst *ctx, char *buf, grub_size_t num) + { +- int cpb = GRUB_NTFS_COM_SEC / ctx->comp.spc; ++ int log_cpb = GRUB_NTFS_LOG_COM_SEC - ctx->comp.log_spc; + + while (num) + { +@@ -192,7 +193,7 @@ read_block (struct grub_ntfs_rlst *ctx, char *buf, grub_size_t num) + return grub_error (GRUB_ERR_BAD_FS, "invalid compression block"); + ctx->comp.comp_head = ctx->comp.comp_tail = 0; + ctx->comp.cbuf_vcn = ctx->target_vcn; +- ctx->comp.cbuf_ofs = (ctx->comp.spc << GRUB_NTFS_BLK_SHR); ++ ctx->comp.cbuf_ofs = (1 << (ctx->comp.log_spc + GRUB_NTFS_BLK_SHR)); + if (ctx->target_vcn >= ctx->next_vcn) + { + if (grub_ntfs_read_run_list (ctx)) +@@ -211,14 +212,14 @@ read_block (struct grub_ntfs_rlst *ctx, char *buf, grub_size_t num) + } + } + +- nn = (16 - (unsigned) (ctx->target_vcn & 0xF)) / cpb; ++ nn = (16 - (unsigned) (ctx->target_vcn & 0xF)) >> log_cpb; + if (nn > num) + nn = num; + num -= nn; + + if (ctx->flags & GRUB_NTFS_RF_BLNK) + { +- ctx->target_vcn += nn * cpb; ++ ctx->target_vcn += nn << log_cpb; + if (ctx->comp.comp_tail == 0) + { + if (buf) +@@ -241,7 +242,7 @@ read_block (struct grub_ntfs_rlst *ctx, char *buf, grub_size_t num) + } + else + { +- nn *= cpb; ++ nn <<= log_cpb; + while ((ctx->comp.comp_head < ctx->comp.comp_tail) && (nn)) + { + grub_disk_addr_t tt; +@@ -258,10 +259,10 @@ read_block (struct grub_ntfs_rlst *ctx, char *buf, grub_size_t num) + (ctx->comp.disk, + (ctx->comp.comp_table[ctx->comp.comp_head].next_lcn - + (ctx->comp.comp_table[ctx->comp.comp_head].next_vcn - +- ctx->target_vcn)) * ctx->comp.spc, 0, +- tt * (ctx->comp.spc << GRUB_NTFS_BLK_SHR), buf)) ++ ctx->target_vcn)) << ctx->comp.log_spc, 0, ++ tt << (ctx->comp.log_spc + GRUB_NTFS_BLK_SHR), buf)) + return grub_errno; +- buf += tt * (ctx->comp.spc << GRUB_NTFS_BLK_SHR); ++ buf += tt << (ctx->comp.log_spc + GRUB_NTFS_BLK_SHR); + } + nn -= tt; + if (ctx->target_vcn >= +@@ -275,10 +276,10 @@ read_block (struct grub_ntfs_rlst *ctx, char *buf, grub_size_t num) + if (grub_disk_read + (ctx->comp.disk, + (ctx->target_vcn - ctx->curr_vcn + +- ctx->curr_lcn) * ctx->comp.spc, 0, +- nn * (ctx->comp.spc << GRUB_NTFS_BLK_SHR), buf)) ++ ctx->curr_lcn) << ctx->comp.log_spc, 0, ++ nn << (ctx->comp.log_spc + GRUB_NTFS_BLK_SHR), buf)) + return grub_errno; +- buf += nn * (ctx->comp.spc << GRUB_NTFS_BLK_SHR); ++ buf += nn << (ctx->comp.log_spc + GRUB_NTFS_BLK_SHR); + } + ctx->target_vcn += nn; + } +@@ -294,7 +295,7 @@ ntfscomp (struct grub_ntfs_attr *at, char *dest, grub_disk_addr_t ofs, + grub_err_t ret; + + ctx->comp.comp_head = ctx->comp.comp_tail = 0; +- ctx->comp.cbuf = grub_malloc ((ctx->comp.spc) << GRUB_NTFS_BLK_SHR); ++ ctx->comp.cbuf = grub_malloc (1 << (ctx->comp.log_spc + GRUB_NTFS_BLK_SHR)); + if (!ctx->comp.cbuf) + return 0; + +@@ -304,7 +305,7 @@ ntfscomp (struct grub_ntfs_attr *at, char *dest, grub_disk_addr_t ofs, + + if ((vcn > ctx->target_vcn) && + (read_block +- (ctx, NULL, ((vcn - ctx->target_vcn) * ctx->comp.spc) / GRUB_NTFS_COM_SEC))) ++ (ctx, NULL, (vcn - ctx->target_vcn) >> (GRUB_NTFS_LOG_COM_SEC - ctx->comp.log_spc)))) + { + ret = grub_errno; + goto quit; +@@ -314,7 +315,7 @@ ntfscomp (struct grub_ntfs_attr *at, char *dest, grub_disk_addr_t ofs, + { + grub_uint32_t t, n, o; + +- t = ctx->target_vcn * (ctx->comp.spc << GRUB_NTFS_BLK_SHR); ++ t = ctx->target_vcn << (ctx->comp.log_spc + GRUB_NTFS_BLK_SHR); + if (read_block (ctx, at->sbuf, 1)) + { + ret = grub_errno; +@@ -346,7 +347,7 @@ ntfscomp (struct grub_ntfs_attr *at, char *dest, grub_disk_addr_t ofs, + { + grub_uint32_t t; + +- t = ctx->target_vcn * (ctx->comp.spc << GRUB_NTFS_BLK_SHR); ++ t = ctx->target_vcn << (ctx->comp.log_spc + GRUB_NTFS_BLK_SHR); + if (read_block (ctx, at->sbuf, 1)) + { + ret = grub_errno; +diff --git a/include/grub/ntfs.h b/include/grub/ntfs.h +index 0935342..cc28a01 100644 +--- a/include/grub/ntfs.h ++++ b/include/grub/ntfs.h +@@ -87,6 +87,7 @@ enum + #define GRUB_NTFS_COM_LEN 4096 + #define GRUB_NTFS_COM_LOG_LEN 12 + #define GRUB_NTFS_COM_SEC (GRUB_NTFS_COM_LEN >> GRUB_NTFS_BLK_SHR) ++#define GRUB_NTFS_LOG_COM_SEC (GRUB_NTFS_COM_LOG_LEN - GRUB_NTFS_BLK_SHR) + + enum + { +@@ -156,7 +157,7 @@ struct grub_ntfs_data + grub_disk_t disk; + grub_uint32_t mft_size; + grub_uint32_t idx_size; +- grub_uint32_t spc; ++ int log_spc; + grub_uint32_t mft_start; + grub_uint64_t uuid; + }; +@@ -172,7 +173,8 @@ struct grub_ntfs_comp + grub_disk_t disk; + int comp_head, comp_tail; + struct grub_ntfs_comp_table_element comp_table[16]; +- grub_uint32_t cbuf_ofs, cbuf_vcn, spc; ++ grub_uint32_t cbuf_ofs, cbuf_vcn; ++ int log_spc; + char *cbuf; + }; + +-- +1.8.1.4 + diff --git a/0087-grub-core-fs-ext2.c-grub_ext2_read_block-Use-shifts-.patch b/0087-grub-core-fs-ext2.c-grub_ext2_read_block-Use-shifts-.patch new file mode 100644 index 0000000..ce105fc --- /dev/null +++ b/0087-grub-core-fs-ext2.c-grub_ext2_read_block-Use-shifts-.patch @@ -0,0 +1,103 @@ +From af8a6a082c9ac9fab22f3eff9e81b5e7085debc4 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sat, 5 Jan 2013 18:37:34 +0100 +Subject: [PATCH 087/364] * grub-core/fs/ext2.c (grub_ext2_read_block): + Use shifts rather than divisions. + +--- + ChangeLog | 5 +++++ + grub-core/fs/ext2.c | 30 ++++++++++++++++-------------- + 2 files changed, 21 insertions(+), 14 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 88fd763..af29161 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,10 @@ + 2013-01-05 Vladimir Serbinenko + ++ * grub-core/fs/ext2.c (grub_ext2_read_block): Use shifts rather than ++ divisions. ++ ++2013-01-05 Vladimir Serbinenko ++ + * grub-core/fs/ntfs.c: Eliminate useless divisions in favor of shifts. + * grub-core/fs/ntfscomp.c: Likewise. + * include/grub/ntfs.h (grub_ntfs_data): Replace spc with log_spc. +diff --git a/grub-core/fs/ext2.c b/grub-core/fs/ext2.c +index bd1ab24..cf2e2f4 100644 +--- a/grub-core/fs/ext2.c ++++ b/grub-core/fs/ext2.c +@@ -454,11 +454,12 @@ grub_ext2_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) + blknr = grub_le_to_cpu32 (indir[fileblock - INDIRECT_BLOCKS]); + } + /* Double indirect. */ +- else if (fileblock < INDIRECT_BLOCKS + blksz / 4 * (blksz / 4 + 1)) ++ else if (fileblock < INDIRECT_BLOCKS ++ + blksz / 4 * ((grub_disk_addr_t) blksz / 4 + 1)) + { +- unsigned int perblock = blksz / 4; +- unsigned int rblock = fileblock - (INDIRECT_BLOCKS +- + blksz / 4); ++ int log_perblock = log2_blksz + 9 - 2; ++ grub_disk_addr_t rblock = fileblock - (INDIRECT_BLOCKS ++ + blksz / 4); + grub_uint32_t indir[blksz / 4]; + + if (grub_disk_read (data->disk, +@@ -470,21 +471,22 @@ grub_ext2_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) + + if (grub_disk_read (data->disk, + ((grub_disk_addr_t) +- grub_le_to_cpu32 (indir[rblock / perblock])) ++ grub_le_to_cpu32 (indir[rblock >> log_perblock])) + << log2_blksz, + 0, blksz, indir)) + return grub_errno; + + +- blknr = grub_le_to_cpu32 (indir[rblock % perblock]); ++ blknr = grub_le_to_cpu32 (indir[rblock & ((1 << log_perblock) - 1)]); + } + /* triple indirect. */ +- else if (fileblock < INDIRECT_BLOCKS + blksz / 4 * (blksz / 4 + 1) +- + (blksz / 4) * (blksz / 4) * (blksz / 4 + 1)) ++ else if (fileblock < INDIRECT_BLOCKS + blksz / 4 * ((grub_disk_addr_t) blksz / 4 + 1) ++ + ((grub_disk_addr_t) blksz / 4) * ((grub_disk_addr_t) blksz / 4) ++ * ((grub_disk_addr_t) blksz / 4 + 1)) + { +- unsigned int perblock = blksz / 4; +- unsigned int rblock = fileblock - (INDIRECT_BLOCKS + blksz / 4 +- * (blksz / 4 + 1)); ++ int log_perblock = log2_blksz + 9 - 2; ++ grub_disk_addr_t rblock = fileblock - (INDIRECT_BLOCKS + blksz / 4 ++ * (blksz / 4 + 1)); + grub_uint32_t indir[blksz / 4]; + + if (grub_disk_read (data->disk, +@@ -496,19 +498,19 @@ grub_ext2_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) + + if (grub_disk_read (data->disk, + ((grub_disk_addr_t) +- grub_le_to_cpu32 (indir[(rblock / perblock) / perblock])) ++ grub_le_to_cpu32 (indir[(rblock >> log_perblock) >> log_perblock])) + << log2_blksz, + 0, blksz, indir)) + return grub_errno; + + if (grub_disk_read (data->disk, + ((grub_disk_addr_t) +- grub_le_to_cpu32 (indir[(rblock / perblock) % perblock])) ++ grub_le_to_cpu32 (indir[(rblock >> log_perblock) & ((1 << log_perblock) - 1)])) + << log2_blksz, + 0, blksz, indir)) + return grub_errno; + +- blknr = grub_le_to_cpu32 (indir[rblock % perblock]); ++ blknr = grub_le_to_cpu32 (indir[rblock & ((1 << log_perblock) - 1)]); + } + else + { +-- +1.8.1.4 + diff --git a/0088-grub-core-fs-minix.c-grub_minix_read_file-Simplify-a.patch b/0088-grub-core-fs-minix.c-grub_minix_read_file-Simplify-a.patch new file mode 100644 index 0000000..d0ebda4 --- /dev/null +++ b/0088-grub-core-fs-minix.c-grub_minix_read_file-Simplify-a.patch @@ -0,0 +1,47 @@ +From 8c3fd8eea724a1490d29937b1d23cde259bf63cb Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Mon, 7 Jan 2013 11:27:18 +0100 +Subject: [PATCH 088/364] * grub-core/fs/minix.c (grub_minix_read_file): + Simplify arithmetics. + +--- + ChangeLog | 4 ++++ + grub-core/fs/minix.c | 8 ++++---- + 2 files changed, 8 insertions(+), 4 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index af29161..cdb3f3d 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,7 @@ ++2013-01-07 Vladimir Serbinenko ++ ++ * grub-core/fs/minix.c (grub_minix_read_file): Simplify arithmetics. ++ + 2013-01-05 Vladimir Serbinenko + + * grub-core/fs/ext2.c (grub_ext2_read_block): Use shifts rather than +diff --git a/grub-core/fs/minix.c b/grub-core/fs/minix.c +index 1e1c13b..a622533 100644 +--- a/grub-core/fs/minix.c ++++ b/grub-core/fs/minix.c +@@ -261,12 +261,12 @@ grub_minix_read_file (struct grub_minix_data *data, + /* Adjust len so it we can't read past the end of the file. */ + if (len + pos > GRUB_MINIX_INODE_SIZE (data)) + len = GRUB_MINIX_INODE_SIZE (data) - pos; ++ if (len == 0) ++ return 0; + + /* Files are at most 2G/4G - 1 bytes on minixfs. Avoid 64-bit division. */ +- blockcnt = ((grub_uint32_t) ((len + pos +- + (data->block_size << GRUB_DISK_SECTOR_BITS) +- - 1) +- >> GRUB_DISK_SECTOR_BITS)) / data->block_size; ++ blockcnt = ((grub_uint32_t) ((len + pos - 1) ++ >> GRUB_DISK_SECTOR_BITS)) / data->block_size + 1; + posblock = (((grub_uint32_t) pos) + / (data->block_size << GRUB_DISK_SECTOR_BITS)); + blockoff = (((grub_uint32_t) pos) +-- +1.8.1.4 + diff --git a/0089-docs-grub.texi-grub_cpu-New-subsection.patch b/0089-docs-grub.texi-grub_cpu-New-subsection.patch new file mode 100644 index 0000000..5878960 --- /dev/null +++ b/0089-docs-grub.texi-grub_cpu-New-subsection.patch @@ -0,0 +1,61 @@ +From 05f5634a5c5a66d535962a96635a9c153cf67e8f Mon Sep 17 00:00:00 2001 +From: Colin Watson +Date: Mon, 7 Jan 2013 10:43:00 +0000 +Subject: [PATCH 089/364] * docs/grub.texi (grub_cpu): New subsection. + (grub_platform): Likewise. + +--- + ChangeLog | 5 +++++ + docs/grub.texi | 16 ++++++++++++++++ + 2 files changed, 21 insertions(+) + +diff --git a/ChangeLog b/ChangeLog +index cdb3f3d..097ef0d 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,8 @@ ++2013-01-07 Colin Watson ++ ++ * docs/grub.texi (grub_cpu): New subsection. ++ (grub_platform): Likewise. ++ + 2013-01-07 Vladimir Serbinenko + + * grub-core/fs/minix.c (grub_minix_read_file): Simplify arithmetics. +diff --git a/docs/grub.texi b/docs/grub.texi +index e23cecc..a92bd96 100644 +--- a/docs/grub.texi ++++ b/docs/grub.texi +@@ -2674,6 +2674,8 @@ These variables have special meaning to GRUB. + * gfxmode:: + * gfxpayload:: + * gfxterm_font:: ++* grub_cpu:: ++* grub_platform:: + * icondir:: + * lang:: + * locale_dir:: +@@ -2857,6 +2859,20 @@ If this variable is set, it names a font to use for text on the + available font. + + ++@node grub_cpu ++@subsection grub_cpu ++ ++In normal mode (@pxref{normal}), GRUB sets the @samp{grub_cpu} variable to ++the CPU type for which GRUB was built (e.g. @samp{i386} or @samp{powerpc}). ++ ++ ++@node grub_platform ++@subsection grub_platform ++ ++In normal mode (@pxref{normal}), GRUB sets the @samp{grub_platform} variable ++to the platform for which GRUB was built (e.g. @samp{pc} or @samp{efi}). ++ ++ + @node icondir + @subsection icondir + +-- +1.8.1.4 + diff --git a/0090-grub-core-io-bufio.c-grub_bufio_open-Use-grub_zalloc.patch b/0090-grub-core-io-bufio.c-grub_bufio_open-Use-grub_zalloc.patch new file mode 100644 index 0000000..0428541 --- /dev/null +++ b/0090-grub-core-io-bufio.c-grub_bufio_open-Use-grub_zalloc.patch @@ -0,0 +1,141 @@ +From c86f86069fd8d600ebc4ffbd8a786c58fccff886 Mon Sep 17 00:00:00 2001 +From: Colin Watson +Date: Mon, 7 Jan 2013 10:45:05 +0000 +Subject: [PATCH 090/364] * grub-core/io/bufio.c (grub_bufio_open): Use + grub_zalloc instead of explicitly zeroing elements. * grub-core/io/gzio.c + (grub_gzio_open): Likewise. * grub-core/io/lzopio.c (grub_lzopio_open): + Remove explicit zeroing of elements in a structure already allocated using + grub_zalloc. * grub-core/io/xzio.c (grub_xzio_open): Likewise. + +--- + ChangeLog | 9 +++++++++ + grub-core/io/bufio.c | 8 ++------ + grub-core/io/gzio.c | 4 +--- + grub-core/io/lzopio.c | 2 -- + grub-core/io/xzio.c | 6 ------ + 5 files changed, 12 insertions(+), 17 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 097ef0d..75fb85a 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,14 @@ + 2013-01-07 Colin Watson + ++ * grub-core/io/bufio.c (grub_bufio_open): Use grub_zalloc instead of ++ explicitly zeroing elements. ++ * grub-core/io/gzio.c (grub_gzio_open): Likewise. ++ * grub-core/io/lzopio.c (grub_lzopio_open): Remove explicit zeroing ++ of elements in a structure already allocated using grub_zalloc. ++ * grub-core/io/xzio.c (grub_xzio_open): Likewise. ++ ++2013-01-07 Colin Watson ++ + * docs/grub.texi (grub_cpu): New subsection. + (grub_platform): Likewise. + +diff --git a/grub-core/io/bufio.c b/grub-core/io/bufio.c +index 2a315e2..2243827 100644 +--- a/grub-core/io/bufio.c ++++ b/grub-core/io/bufio.c +@@ -48,7 +48,7 @@ grub_bufio_open (grub_file_t io, int size) + grub_file_t file; + grub_bufio_t bufio = 0; + +- file = (grub_file_t) grub_malloc (sizeof (*file)); ++ file = (grub_file_t) grub_zalloc (sizeof (*file)); + if (! file) + return 0; + +@@ -61,7 +61,7 @@ grub_bufio_open (grub_file_t io, int size) + size = ((io->size > GRUB_BUFIO_MAX_SIZE) ? GRUB_BUFIO_MAX_SIZE : + io->size); + +- bufio = grub_malloc (sizeof (struct grub_bufio) + size); ++ bufio = grub_zalloc (sizeof (struct grub_bufio) + size); + if (! bufio) + { + grub_free (file); +@@ -70,14 +70,10 @@ grub_bufio_open (grub_file_t io, int size) + + bufio->file = io; + bufio->block_size = size; +- bufio->buffer_len = 0; +- bufio->buffer_at = 0; + + file->device = io->device; +- file->offset = 0; + file->size = io->size; + file->data = bufio; +- file->read_hook = 0; + file->fs = &grub_bufio_fs; + file->not_easily_seekable = io->not_easily_seekable; + +diff --git a/grub-core/io/gzio.c b/grub-core/io/gzio.c +index 83c0b64..59f2206 100644 +--- a/grub-core/io/gzio.c ++++ b/grub-core/io/gzio.c +@@ -1130,7 +1130,7 @@ grub_gzio_open (grub_file_t io) + grub_file_t file; + grub_gzio_t gzio = 0; + +- file = (grub_file_t) grub_malloc (sizeof (*file)); ++ file = (grub_file_t) grub_zalloc (sizeof (*file)); + if (! file) + return 0; + +@@ -1144,9 +1144,7 @@ grub_gzio_open (grub_file_t io) + gzio->file = io; + + file->device = io->device; +- file->offset = 0; + file->data = gzio; +- file->read_hook = 0; + file->fs = &grub_gzio_fs; + file->not_easily_seekable = 1; + +diff --git a/grub-core/io/lzopio.c b/grub-core/io/lzopio.c +index 77291d0..7fdb6d4 100644 +--- a/grub-core/io/lzopio.c ++++ b/grub-core/io/lzopio.c +@@ -428,9 +428,7 @@ grub_lzopio_open (grub_file_t io) + lzopio->file = io; + + file->device = io->device; +- file->offset = 0; + file->data = lzopio; +- file->read_hook = 0; + file->fs = &grub_lzopio_fs; + file->size = GRUB_FILE_SIZE_UNKNOWN; + file->not_easily_seekable = 1; +diff --git a/grub-core/io/xzio.c b/grub-core/io/xzio.c +index ae30e6f..27657d8 100644 +--- a/grub-core/io/xzio.c ++++ b/grub-core/io/xzio.c +@@ -186,12 +186,9 @@ grub_xzio_open (grub_file_t io) + } + + xzio->file = io; +- xzio->saved_offset = 0; + + file->device = io->device; +- file->offset = 0; + file->data = xzio; +- file->read_hook = 0; + file->fs = &grub_xzio_fs; + file->size = GRUB_FILE_SIZE_UNKNOWN; + file->not_easily_seekable = 1; +@@ -210,10 +207,7 @@ grub_xzio_open (grub_file_t io) + } + + xzio->buf.in = xzio->inbuf; +- xzio->buf.in_pos = 0; +- xzio->buf.in_size = 0; + xzio->buf.out = xzio->outbuf; +- xzio->buf.out_pos = 0; + xzio->buf.out_size = XZBUFSIZ; + + /* FIXME: don't test footer on not easily seekable files. */ +-- +1.8.1.4 + diff --git a/0091-grub-core-kern-disk.c-grub_disk_write-Fix-sector-num.patch b/0091-grub-core-kern-disk.c-grub_disk_write-Fix-sector-num.patch new file mode 100644 index 0000000..f9f27d1 --- /dev/null +++ b/0091-grub-core-kern-disk.c-grub_disk_write-Fix-sector-num.patch @@ -0,0 +1,59 @@ +From 1ed52ffd389d28a8c1711fedcd9a841258c30e28 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Thu, 10 Jan 2013 08:09:26 +0100 +Subject: [PATCH 091/364] * grub-core/kern/disk.c (grub_disk_write): Fix + sector number on 4K sector devices. + +--- + ChangeLog | 5 +++++ + grub-core/kern/disk.c | 11 ++++++++--- + 2 files changed, 13 insertions(+), 3 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 75fb85a..48d297d 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,8 @@ ++2013-01-10 Vladimir Serbinenko ++ ++ * grub-core/kern/disk.c (grub_disk_write): Fix sector number on 4K ++ sector devices. ++ + 2013-01-07 Colin Watson + + * grub-core/io/bufio.c (grub_bufio_open): Use grub_zalloc instead of +diff --git a/grub-core/kern/disk.c b/grub-core/kern/disk.c +index 1f55f90..94318af 100644 +--- a/grub-core/kern/disk.c ++++ b/grub-core/kern/disk.c +@@ -658,7 +658,8 @@ grub_disk_write (grub_disk_t disk, grub_disk_addr_t sector, + + grub_disk_cache_invalidate (disk->dev->id, disk->id, sector); + +- if ((disk->dev->write) (disk, sector, 1, tmp_buf) != GRUB_ERR_NONE) ++ if ((disk->dev->write) (disk, transform_sector (disk, sector), ++ 1, tmp_buf) != GRUB_ERR_NONE) + goto finish; + + sector += (1 << (disk->log_sector_size - GRUB_DISK_SECTOR_BITS)); +@@ -674,11 +675,15 @@ grub_disk_write (grub_disk_t disk, grub_disk_addr_t sector, + len = size & ~((1 << disk->log_sector_size) - 1); + n = size >> disk->log_sector_size; + +- if ((disk->dev->write) (disk, sector, n, buf) != GRUB_ERR_NONE) ++ if ((disk->dev->write) (disk, transform_sector (disk, sector), ++ n, buf) != GRUB_ERR_NONE) + goto finish; + + while (n--) +- grub_disk_cache_invalidate (disk->dev->id, disk->id, sector++); ++ { ++ grub_disk_cache_invalidate (disk->dev->id, disk->id, sector); ++ sector += (1 << (disk->log_sector_size - GRUB_DISK_SECTOR_BITS)); ++ } + + buf = (const char *) buf + len; + size -= len; +-- +1.8.1.4 + diff --git a/0092-Support-Apple-FAT-binaries-on-non-Apple-platforms.patch b/0092-Support-Apple-FAT-binaries-on-non-Apple-platforms.patch new file mode 100644 index 0000000..ef8a26d --- /dev/null +++ b/0092-Support-Apple-FAT-binaries-on-non-Apple-platforms.patch @@ -0,0 +1,150 @@ +From 474f5d13721ed87fde38bdad282164ee84c1be0a Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Thu, 10 Jan 2013 12:50:01 +0100 +Subject: [PATCH 092/364] Support Apple FAT binaries on non-Apple + platforms. + + * include/grub/macho.h (GRUB_MACHO_FAT_EFI_MAGIC): New define. + * include/grub/i386/macho.h (GRUB_MACHO_CPUTYPE_IS_HOST_CURRENT): + Likewise. + * grub-core/loader/efi/chainloader.c (grub_cmd_chainloader): Parse + Apple FAT binaries. +--- + ChangeLog | 10 ++++++++ + grub-core/loader/efi/chainloader.c | 48 +++++++++++++++++++++++++++++++++++--- + include/grub/i386/macho.h | 5 ++++ + include/grub/macho.h | 1 + + 4 files changed, 61 insertions(+), 3 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 48d297d..4567cae 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,15 @@ + 2013-01-10 Vladimir Serbinenko + ++ Support Apple FAT binaries on non-Apple platforms. ++ ++ * include/grub/macho.h (GRUB_MACHO_FAT_EFI_MAGIC): New define. ++ * include/grub/i386/macho.h (GRUB_MACHO_CPUTYPE_IS_HOST_CURRENT): ++ Likewise. ++ * grub-core/loader/efi/chainloader.c (grub_cmd_chainloader): Parse ++ Apple FAT binaries. ++ ++2013-01-10 Vladimir Serbinenko ++ + * grub-core/kern/disk.c (grub_disk_write): Fix sector number on 4K + sector devices. + +diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c +index 3f3e6e3..c0fed80 100644 +--- a/grub-core/loader/efi/chainloader.c ++++ b/grub-core/loader/efi/chainloader.c +@@ -35,6 +35,10 @@ + #include + #include + #include ++#if defined (__i386__) || defined (__x86_64__) ++#include ++#include ++#endif + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -198,6 +202,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), + grub_efi_device_path_t *dp = 0; + grub_efi_loaded_image_t *loaded_image; + char *filename; ++ void *boot_image = 0; + grub_efi_handle_t dev_handle = 0; + + if (argc == 0) +@@ -278,7 +283,8 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), + goto fail; + } + +- if (grub_file_read (file, (void *) ((grub_addr_t) address), size) != size) ++ boot_image = (void *) ((grub_addr_t) address); ++ if (grub_file_read (file, boot_image, size) != size) + { + if (grub_errno == GRUB_ERR_NONE) + grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), +@@ -287,9 +293,45 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), + goto fail; + } + ++#if defined (__i386__) || defined (__x86_64__) ++ if (size >= (grub_ssize_t) sizeof (struct grub_macho_fat_header)) ++ { ++ struct grub_macho_fat_header *head = boot_image; ++ if (head->magic ++ == grub_cpu_to_le32_compile_time (GRUB_MACHO_FAT_EFI_MAGIC)) ++ { ++ grub_uint32_t i; ++ struct grub_macho_fat_arch *archs ++ = (struct grub_macho_fat_arch *) (head + 1); ++ for (i = 0; i < grub_cpu_to_le32 (head->nfat_arch); i++) ++ { ++ if (GRUB_MACHO_CPUTYPE_IS_HOST_CURRENT (archs[i].cputype)) ++ break; ++ } ++ if (i == grub_cpu_to_le32 (head->nfat_arch)) ++ { ++ grub_error (GRUB_ERR_BAD_OS, "no compatible arch found"); ++ goto fail; ++ } ++ if (grub_cpu_to_le32 (archs[i].offset) ++ > ~grub_cpu_to_le32 (archs[i].size) ++ || grub_cpu_to_le32 (archs[i].offset) ++ + grub_cpu_to_le32 (archs[i].size) ++ > (grub_size_t) size) ++ { ++ grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), ++ filename); ++ goto fail; ++ } ++ boot_image = (char *) boot_image + grub_cpu_to_le32 (archs[i].offset); ++ size = grub_cpu_to_le32 (archs[i].size); ++ } ++ } ++#endif ++ + status = efi_call_6 (b->load_image, 0, grub_efi_image_handle, file_path, +- (void *) ((grub_addr_t) address), size, +- &image_handle); ++ boot_image, size, ++ &image_handle); + if (status != GRUB_EFI_SUCCESS) + { + if (status == GRUB_EFI_OUT_OF_RESOURCES) +diff --git a/include/grub/i386/macho.h b/include/grub/i386/macho.h +index f22c211..5ee9f9e 100644 +--- a/include/grub/i386/macho.h ++++ b/include/grub/i386/macho.h +@@ -23,6 +23,11 @@ + + #define GRUB_MACHO_CPUTYPE_IS_HOST32(x) ((x)==0x00000007) + #define GRUB_MACHO_CPUTYPE_IS_HOST64(x) ((x)==0x01000007) ++#ifdef __x86_64__ ++#define GRUB_MACHO_CPUTYPE_IS_HOST_CURRENT(x) ((x)==0x01000007) ++#else ++#define GRUB_MACHO_CPUTYPE_IS_HOST_CURRENT(x) ((x)==0x00000007) ++#endif + + struct grub_macho_thread32 + { +diff --git a/include/grub/macho.h b/include/grub/macho.h +index 6a98b6e..21f0714 100644 +--- a/include/grub/macho.h ++++ b/include/grub/macho.h +@@ -27,6 +27,7 @@ struct grub_macho_fat_header + grub_uint32_t nfat_arch; + } __attribute__ ((packed)); + #define GRUB_MACHO_FAT_MAGIC 0xcafebabe ++#define GRUB_MACHO_FAT_EFI_MAGIC 0x0ef1fab9 + + typedef grub_uint32_t grub_macho_cpu_type_t; + typedef grub_uint32_t grub_macho_cpu_subtype_t; +-- +1.8.1.4 + diff --git a/0093-grub-core-fs-ntfs.c-Ue-more-appropriate-types.patch b/0093-grub-core-fs-ntfs.c-Ue-more-appropriate-types.patch new file mode 100644 index 0000000..1607a07 --- /dev/null +++ b/0093-grub-core-fs-ntfs.c-Ue-more-appropriate-types.patch @@ -0,0 +1,628 @@ +From 75bd81540fab6830213d51e024b53d51f3fe6dcb Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Fri, 11 Jan 2013 07:41:05 +0100 +Subject: [PATCH 093/364] * grub-core/fs/ntfs.c: Ue more appropriate + types. * grub-core/fs/ntfscomp.c: Likewise. * include/grub/ntfs.h: + Likewise. + +--- + ChangeLog | 6 +++ + grub-core/fs/ntfs.c | 140 +++++++++++++++++++++++++----------------------- + grub-core/fs/ntfscomp.c | 16 +++--- + include/grub/ntfs.h | 20 +++---- + 4 files changed, 96 insertions(+), 86 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 4567cae..41dbadd 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,11 @@ + 2013-01-10 Vladimir Serbinenko + ++ * grub-core/fs/ntfs.c: Ue more appropriate types. ++ * grub-core/fs/ntfscomp.c: Likewise. ++ * include/grub/ntfs.h: Likewise. ++ ++2013-01-10 Vladimir Serbinenko ++ + Support Apple FAT binaries on non-Apple platforms. + + * include/grub/macho.h (GRUB_MACHO_FAT_EFI_MAGIC): New define. +diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c +index 6004e1f..e7861d8 100644 +--- a/grub-core/fs/ntfs.c ++++ b/grub-core/fs/ntfs.c +@@ -55,10 +55,10 @@ u64at (void *ptr, grub_size_t ofs) + grub_ntfscomp_func_t grub_ntfscomp_func; + + static grub_err_t +-fixup (char *buf, int len, const char *magic) ++fixup (grub_uint8_t *buf, grub_size_t len, const grub_uint8_t *magic) + { +- int ss; +- char *pu; ++ grub_uint16_t ss; ++ grub_uint8_t *pu; + grub_uint16_t us; + + COMPILE_TIME_ASSERT ((1 << GRUB_NTFS_BLK_SHR) == GRUB_DISK_SECTOR_SIZE); +@@ -86,9 +86,9 @@ fixup (char *buf, int len, const char *magic) + return 0; + } + +-static grub_err_t read_mft (struct grub_ntfs_data *data, char *buf, ++static grub_err_t read_mft (struct grub_ntfs_data *data, grub_uint8_t *buf, + grub_uint32_t mftno); +-static grub_err_t read_attr (struct grub_ntfs_attr *at, char *dest, ++static grub_err_t read_attr (struct grub_ntfs_attr *at, grub_uint8_t *dest, + grub_disk_addr_t ofs, grub_size_t len, + int cached, + void +@@ -97,7 +97,8 @@ static grub_err_t read_attr (struct grub_ntfs_attr *at, char *dest, + unsigned offset, + unsigned length)); + +-static grub_err_t read_data (struct grub_ntfs_attr *at, char *pa, char *dest, ++static grub_err_t read_data (struct grub_ntfs_attr *at, grub_uint8_t *pa, ++ grub_uint8_t *dest, + grub_disk_addr_t ofs, grub_size_t len, + int cached, + void +@@ -123,8 +124,8 @@ free_attr (struct grub_ntfs_attr *at) + grub_free (at->sbuf); + } + +-static char * +-find_attr (struct grub_ntfs_attr *at, unsigned char attr) ++static grub_uint8_t * ++find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr) + { + if (at->flags & GRUB_NTFS_AF_ALST) + { +@@ -133,9 +134,9 @@ find_attr (struct grub_ntfs_attr *at, unsigned char attr) + { + at->attr_cur = at->attr_nxt; + at->attr_nxt += u16at (at->attr_cur, 4); +- if (((unsigned char) *at->attr_cur == attr) || (attr == 0)) ++ if ((*at->attr_cur == attr) || (attr == 0)) + { +- char *new_pos; ++ grub_uint8_t *new_pos; + + if (at->flags & GRUB_NTFS_AF_MMFT) + { +@@ -148,7 +149,8 @@ find_attr (struct grub_ntfs_attr *at, unsigned char attr) + 512, at->emft_buf + 512))) + return NULL; + +- if (fixup (at->emft_buf, at->mft->data->mft_size, "FILE")) ++ if (fixup (at->emft_buf, at->mft->data->mft_size, ++ (const grub_uint8_t *) "FILE")) + return NULL; + } + else +@@ -159,10 +161,9 @@ find_attr (struct grub_ntfs_attr *at, unsigned char attr) + } + + new_pos = &at->emft_buf[u16at (at->emft_buf, 0x14)]; +- while ((unsigned char) *new_pos != 0xFF) ++ while (*new_pos != 0xFF) + { +- if (((unsigned char) *new_pos == +- (unsigned char) *at->attr_cur) ++ if ((*new_pos == *at->attr_cur) + && (u16at (new_pos, 0xE) == u16at (at->attr_cur, 0x18))) + { + return new_pos; +@@ -178,18 +179,18 @@ find_attr (struct grub_ntfs_attr *at, unsigned char attr) + return NULL; + } + at->attr_cur = at->attr_nxt; +- while ((unsigned char) *at->attr_cur != 0xFF) ++ while (*at->attr_cur != 0xFF) + { + at->attr_nxt += u16at (at->attr_cur, 4); +- if ((unsigned char) *at->attr_cur == GRUB_NTFS_AT_ATTRIBUTE_LIST) ++ if (*at->attr_cur == GRUB_NTFS_AT_ATTRIBUTE_LIST) + at->attr_end = at->attr_cur; +- if (((unsigned char) *at->attr_cur == attr) || (attr == 0)) ++ if ((*at->attr_cur == attr) || (attr == 0)) + return at->attr_cur; + at->attr_cur = at->attr_nxt; + } + if (at->attr_end) + { +- char *pa; ++ grub_uint8_t *pa; + + at->emft_buf = grub_malloc (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR); + if (at->emft_buf == NULL) +@@ -198,7 +199,7 @@ find_attr (struct grub_ntfs_attr *at, unsigned char attr) + pa = at->attr_end; + if (pa[8]) + { +- int n; ++ grub_uint32_t n; + + n = ((u32at (pa, 0x30) + GRUB_DISK_SECTOR_SIZE - 1) + & (~(GRUB_DISK_SECTOR_SIZE - 1))); +@@ -223,7 +224,7 @@ find_attr (struct grub_ntfs_attr *at, unsigned char attr) + at->flags |= GRUB_NTFS_AF_ALST; + while (at->attr_nxt < at->attr_end) + { +- if (((unsigned char) *at->attr_nxt == attr) || (attr == 0)) ++ if ((*at->attr_nxt == attr) || (attr == 0)) + break; + at->attr_nxt += u16at (at->attr_nxt, 4); + } +@@ -243,7 +244,7 @@ find_attr (struct grub_ntfs_attr *at, unsigned char attr) + pa = at->attr_nxt + u16at (pa, 4); + while (pa < at->attr_end) + { +- if ((unsigned char) *pa != attr) ++ if (*pa != attr) + break; + if (read_attr + (at, pa + 0x10, +@@ -260,11 +261,11 @@ find_attr (struct grub_ntfs_attr *at, unsigned char attr) + return NULL; + } + +-static char * ++static grub_uint8_t * + locate_attr (struct grub_ntfs_attr *at, struct grub_ntfs_file *mft, +- unsigned char attr) ++ grub_uint8_t attr) + { +- char *pa; ++ grub_uint8_t *pa; + + init_attr (at, mft); + pa = find_attr (at, attr); +@@ -288,8 +289,8 @@ locate_attr (struct grub_ntfs_attr *at, struct grub_ntfs_file *mft, + return pa; + } + +-static char * +-read_run_data (char *run, int nn, grub_disk_addr_t * val, int sig) ++static grub_uint8_t * ++read_run_data (grub_uint8_t *run, int nn, grub_disk_addr_t * val, int sig) + { + grub_disk_addr_t r, v; + +@@ -298,7 +299,7 @@ read_run_data (char *run, int nn, grub_disk_addr_t * val, int sig) + + while (nn--) + { +- r += v * (*(unsigned char *) (run++)); ++ r += v * (*(run++)); + v <<= 8; + } + +@@ -312,14 +313,14 @@ read_run_data (char *run, int nn, grub_disk_addr_t * val, int sig) + grub_err_t + grub_ntfs_read_run_list (struct grub_ntfs_rlst * ctx) + { +- int c1, c2; ++ grub_uint8_t c1, c2; + grub_disk_addr_t val; +- char *run; ++ grub_uint8_t *run; + + run = ctx->cur_run; + retry: +- c1 = ((unsigned char) (*run) & 0xF); +- c2 = ((unsigned char) (*run) >> 4); ++ c1 = ((*run) & 0xF); ++ c2 = ((*run) >> 4); + if (!c1) + { + if ((ctx->attr) && (ctx->attr->flags & GRUB_NTFS_AF_ALST)) +@@ -330,7 +331,7 @@ retry: + + save_hook = ctx->comp.disk->read_hook; + ctx->comp.disk->read_hook = 0; +- run = find_attr (ctx->attr, (unsigned char) *ctx->attr->attr_cur); ++ run = find_attr (ctx->attr, *ctx->attr->attr_cur); + ctx->comp.disk->read_hook = save_hook; + if (run) + { +@@ -376,7 +377,7 @@ grub_ntfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t block) + } + + static grub_err_t +-read_data (struct grub_ntfs_attr *at, char *pa, char *dest, ++read_data (struct grub_ntfs_attr *at, grub_uint8_t *pa, grub_uint8_t *dest, + grub_disk_addr_t ofs, grub_size_t len, int cached, + void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, + unsigned offset, +@@ -479,7 +480,7 @@ read_data (struct grub_ntfs_attr *at, char *pa, char *dest, + if (!(ctx->flags & GRUB_NTFS_RF_COMP)) + { + grub_fshelp_read_file (ctx->comp.disk, (grub_fshelp_node_t) ctx, +- read_hook, ofs, len, dest, ++ read_hook, ofs, len, (char *) dest, + grub_ntfs_read_block, ofs + len, + ctx->comp.log_spc, 0); + return grub_errno; +@@ -492,23 +493,23 @@ read_data (struct grub_ntfs_attr *at, char *pa, char *dest, + } + + static grub_err_t +-read_attr (struct grub_ntfs_attr *at, char *dest, grub_disk_addr_t ofs, ++read_attr (struct grub_ntfs_attr *at, grub_uint8_t *dest, grub_disk_addr_t ofs, + grub_size_t len, int cached, + void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, + unsigned offset, + unsigned length)) + { +- char *save_cur; +- unsigned char attr; +- char *pp; ++ grub_uint8_t *save_cur; ++ grub_uint8_t attr; ++ grub_uint8_t *pp; + grub_err_t ret; + + save_cur = at->attr_cur; + at->attr_nxt = at->attr_cur; +- attr = (unsigned char) *at->attr_nxt; ++ attr = *at->attr_nxt; + if (at->flags & GRUB_NTFS_AF_ALST) + { +- char *pa; ++ grub_uint8_t *pa; + grub_disk_addr_t vcn; + + /* If compression is possible make sure that we include possible +@@ -521,7 +522,7 @@ read_attr (struct grub_ntfs_attr *at, char *dest, grub_disk_addr_t ofs, + pa = at->attr_nxt + u16at (at->attr_nxt, 4); + while (pa < at->attr_end) + { +- if ((unsigned char) *pa != attr) ++ if (*pa != attr) + break; + if (u32at (pa, 8) > vcn) + break; +@@ -541,13 +542,13 @@ read_attr (struct grub_ntfs_attr *at, char *dest, grub_disk_addr_t ofs, + } + + static grub_err_t +-read_mft (struct grub_ntfs_data *data, char *buf, grub_uint32_t mftno) ++read_mft (struct grub_ntfs_data *data, grub_uint8_t *buf, grub_uint32_t mftno) + { + if (read_attr + (&data->mmft.attr, buf, mftno * ((grub_disk_addr_t) data->mft_size << GRUB_NTFS_BLK_SHR), + data->mft_size << GRUB_NTFS_BLK_SHR, 0, 0)) + return grub_error (GRUB_ERR_BAD_FS, "read MFT 0x%X fails", mftno); +- return fixup (buf, data->mft_size, "FILE"); ++ return fixup (buf, data->mft_size, (const grub_uint8_t *) "FILE"); + } + + static grub_err_t +@@ -570,7 +571,7 @@ init_file (struct grub_ntfs_file *mft, grub_uint32_t mftno) + + if ((flag & 2) == 0) + { +- char *pa; ++ grub_uint8_t *pa; + + pa = locate_attr (&mft->attr, mft, GRUB_NTFS_AT_DATA); + if (pa == NULL) +@@ -598,24 +599,25 @@ free_file (struct grub_ntfs_file *mft) + } + + static int +-list_file (struct grub_ntfs_file *diro, char *pos, ++list_file (struct grub_ntfs_file *diro, grub_uint8_t *pos, + int NESTED_FUNC_ATTR + (*hook) (const char *filename, + enum grub_fshelp_filetype filetype, + grub_fshelp_node_t node)) + { +- char *np; ++ grub_uint8_t *np; + int ns; + + while (1) + { +- char *ustr, namespace; ++ grub_uint8_t namespace; ++ char *ustr; + + if (pos[0xC] & 2) /* end signature */ + break; + + np = pos + 0x50; +- ns = (unsigned char) *(np++); ++ ns = *(np++); + namespace = *(np++); + + /* +@@ -698,7 +700,7 @@ grub_ntfs_read_symlink (grub_fshelp_node_t node) + char *buf, *end; + grub_size_t len; + grub_size_t i; +- char *pa; ++ grub_uint8_t *pa; + grub_size_t off; + + mft = (struct grub_ntfs_file *) node; +@@ -717,7 +719,7 @@ grub_ntfs_read_symlink (grub_fshelp_node_t node) + return NULL; + } + +- err = read_attr (&mft->attr, (char *) &symdesc, 0, ++ err = read_attr (&mft->attr, (grub_uint8_t *) &symdesc, 0, + sizeof (struct symlink_descriptor), 1, 0); + if (err) + return NULL; +@@ -744,7 +746,7 @@ grub_ntfs_read_symlink (grub_fshelp_node_t node) + if (!buf16) + return NULL; + +- err = read_attr (&mft->attr, (char *) buf16, off, len, 1, 0); ++ err = read_attr (&mft->attr, (grub_uint8_t *) buf16, off, len, 1, 0); + if (err) + return NULL; + +@@ -781,9 +783,9 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir, + enum grub_fshelp_filetype filetype, + grub_fshelp_node_t node)) + { +- unsigned char *bitmap; ++ grub_uint8_t *bitmap; + struct grub_ntfs_attr attr, *at; +- char *cur_pos, *indx, *bmp; ++ grub_uint8_t *cur_pos, *indx, *bmp; + int ret = 0; + grub_size_t bitmap_len; + struct grub_ntfs_file *mft; +@@ -834,7 +836,7 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir, + { + int ofs; + +- ofs = (unsigned char) cur_pos[0xA]; ++ ofs = cur_pos[0xA]; + /* Namelen=4, Name="$I30" */ + if ((cur_pos[9] == 4) && + (u32at (cur_pos, ofs) == 0x490024) && +@@ -851,7 +853,7 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir, + + if (is_resident) + { +- grub_memcpy (bmp, (char *) (cur_pos + u16at (cur_pos, 0x14)), ++ grub_memcpy (bmp, cur_pos + u16at (cur_pos, 0x14), + bitmap_len); + } + else +@@ -865,7 +867,7 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir, + bitmap_len = u32at (cur_pos, 0x30); + } + +- bitmap = (unsigned char *) bmp; ++ bitmap = bmp; + break; + } + } +@@ -904,7 +906,8 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir, + if ((read_attr + (at, indx, i * (mft->data->idx_size << GRUB_NTFS_BLK_SHR), + (mft->data->idx_size << GRUB_NTFS_BLK_SHR), 0, 0)) +- || (fixup (indx, mft->data->idx_size, "INDX"))) ++ || (fixup (indx, mft->data->idx_size, ++ (const grub_uint8_t *) "INDX"))) + goto done; + ret = list_file (mft, &indx[0x18 + u16at (indx, 0x18)], hook); + if (ret) +@@ -963,14 +966,15 @@ grub_ntfs_mount (grub_disk_t disk) + for (data->log_spc = 0; (1U << data->log_spc) < spc; data->log_spc++); + + if (bpb.clusters_per_mft > 0) +- data->mft_size = bpb.clusters_per_mft << data->log_spc; ++ data->mft_size = ((grub_disk_addr_t) bpb.clusters_per_mft) << data->log_spc; + else +- data->mft_size = 1 << (-bpb.clusters_per_mft - GRUB_NTFS_BLK_SHR); ++ data->mft_size = 1ULL << (-bpb.clusters_per_mft - GRUB_NTFS_BLK_SHR); + + if (bpb.clusters_per_index > 0) +- data->idx_size = bpb.clusters_per_index << data->log_spc; ++ data->idx_size = (((grub_disk_addr_t) bpb.clusters_per_index) ++ << data->log_spc); + else +- data->idx_size = 1 << (-bpb.clusters_per_index - GRUB_NTFS_BLK_SHR); ++ data->idx_size = 1ULL << (-bpb.clusters_per_index - GRUB_NTFS_BLK_SHR); + + data->mft_start = grub_le_to_cpu64 (bpb.mft_lcn) << data->log_spc; + +@@ -990,7 +994,7 @@ grub_ntfs_mount (grub_disk_t disk) + + data->uuid = grub_le_to_cpu64 (bpb.num_serial); + +- if (fixup (data->mmft.buf, data->mft_size, "FILE")) ++ if (fixup (data->mmft.buf, data->mft_size, (const grub_uint8_t *) "FILE")) + goto fail; + + if (!locate_attr (&data->mmft.attr, &data->mmft, GRUB_NTFS_AT_DATA)) +@@ -1130,7 +1134,8 @@ grub_ntfs_read (grub_file_t file, char *buf, grub_size_t len) + if (file->read_hook) + mft->attr.save_pos = 1; + +- read_attr (&mft->attr, buf, file->offset, len, 1, file->read_hook); ++ read_attr (&mft->attr, (grub_uint8_t *) buf, file->offset, len, 1, ++ file->read_hook); + return (grub_errno) ? -1 : (grub_ssize_t) len; + } + +@@ -1158,7 +1163,7 @@ grub_ntfs_label (grub_device_t device, char **label) + { + struct grub_ntfs_data *data = 0; + struct grub_fshelp_node *mft = 0; +- char *pa; ++ grub_uint8_t *pa; + + grub_dl_ref (my_mod); + +@@ -1188,7 +1193,7 @@ grub_ntfs_label (grub_device_t device, char **label) + pa = find_attr (&mft->attr, GRUB_NTFS_AT_VOLUME_NAME); + if ((pa) && (pa[8] == 0) && (u32at (pa, 0x10))) + { +- char *buf; ++ grub_uint8_t *buf; + int len; + + len = u32at (pa, 0x10) / 2; +@@ -1199,10 +1204,9 @@ grub_ntfs_label (grub_device_t device, char **label) + int i; + for (i = 0; i < len; i++) + tmp[i] = grub_le_to_cpu16 (grub_get_unaligned16 (pa + 2 * i)); +- *grub_utf16_to_utf8 ((grub_uint8_t *) buf, tmp, len) = +- '\0'; ++ *grub_utf16_to_utf8 (buf, tmp, len) = '\0'; + } +- *label = buf; ++ *label = (char *) buf; + } + + fail: +diff --git a/grub-core/fs/ntfscomp.c b/grub-core/fs/ntfscomp.c +index 9b3b75d..02ea9fd 100644 +--- a/grub-core/fs/ntfscomp.c ++++ b/grub-core/fs/ntfscomp.c +@@ -45,21 +45,21 @@ decomp_nextvcn (struct grub_ntfs_comp *cc) + } + + static grub_err_t +-decomp_getch (struct grub_ntfs_comp *cc, unsigned char *res) ++decomp_getch (struct grub_ntfs_comp *cc, grub_uint8_t *res) + { + if (cc->cbuf_ofs >= (1U << (cc->log_spc + GRUB_NTFS_BLK_SHR))) + { + if (decomp_nextvcn (cc)) + return grub_errno; + } +- *res = (unsigned char) cc->cbuf[cc->cbuf_ofs++]; ++ *res = cc->cbuf[cc->cbuf_ofs++]; + return 0; + } + + static grub_err_t + decomp_get16 (struct grub_ntfs_comp *cc, grub_uint16_t * res) + { +- unsigned char c1 = 0, c2 = 0; ++ grub_uint8_t c1 = 0, c2 = 0; + + if ((decomp_getch (cc, &c1)) || (decomp_getch (cc, &c2))) + return grub_errno; +@@ -69,7 +69,7 @@ decomp_get16 (struct grub_ntfs_comp *cc, grub_uint16_t * res) + + /* Decompress a block (4096 bytes) */ + static grub_err_t +-decomp_block (struct grub_ntfs_comp *cc, char *dest) ++decomp_block (struct grub_ntfs_comp *cc, grub_uint8_t *dest) + { + grub_uint16_t flg, cnt; + +@@ -81,7 +81,7 @@ decomp_block (struct grub_ntfs_comp *cc, char *dest) + { + if (flg & 0x8000) + { +- unsigned char tag; ++ grub_uint8_t tag; + grub_uint32_t bits, copied; + + bits = copied = tag = 0; +@@ -136,7 +136,7 @@ decomp_block (struct grub_ntfs_comp *cc, char *dest) + } + else + { +- unsigned char ch = 0; ++ grub_uint8_t ch = 0; + + if (decomp_getch (cc, &ch)) + return grub_errno; +@@ -177,7 +177,7 @@ decomp_block (struct grub_ntfs_comp *cc, char *dest) + } + + static grub_err_t +-read_block (struct grub_ntfs_rlst *ctx, char *buf, grub_size_t num) ++read_block (struct grub_ntfs_rlst *ctx, grub_uint8_t *buf, grub_size_t num) + { + int log_cpb = GRUB_NTFS_LOG_COM_SEC - ctx->comp.log_spc; + +@@ -289,7 +289,7 @@ read_block (struct grub_ntfs_rlst *ctx, char *buf, grub_size_t num) + } + + static grub_err_t +-ntfscomp (struct grub_ntfs_attr *at, char *dest, grub_disk_addr_t ofs, ++ntfscomp (struct grub_ntfs_attr *at, grub_uint8_t *dest, grub_disk_addr_t ofs, + grub_size_t len, struct grub_ntfs_rlst *ctx, grub_disk_addr_t vcn) + { + grub_err_t ret; +diff --git a/include/grub/ntfs.h b/include/grub/ntfs.h +index cc28a01..37983c4 100644 +--- a/include/grub/ntfs.h ++++ b/include/grub/ntfs.h +@@ -132,17 +132,17 @@ struct grub_ntfs_bpb + struct grub_ntfs_attr + { + int flags; +- char *emft_buf, *edat_buf; +- char *attr_cur, *attr_nxt, *attr_end; ++ grub_uint8_t *emft_buf, *edat_buf; ++ grub_uint8_t *attr_cur, *attr_nxt, *attr_end; + grub_uint32_t save_pos; +- char *sbuf; ++ grub_uint8_t *sbuf; + struct grub_ntfs_file *mft; + }; + + struct grub_ntfs_file + { + struct grub_ntfs_data *data; +- char *buf; ++ grub_uint8_t *buf; + grub_uint64_t size; + grub_uint64_t mtime; + grub_uint32_t ino; +@@ -155,10 +155,10 @@ struct grub_ntfs_data + struct grub_ntfs_file cmft; + struct grub_ntfs_file mmft; + grub_disk_t disk; +- grub_uint32_t mft_size; +- grub_uint32_t idx_size; ++ grub_uint64_t mft_size; ++ grub_uint64_t idx_size; + int log_spc; +- grub_uint32_t mft_start; ++ grub_uint64_t mft_start; + grub_uint64_t uuid; + }; + +@@ -175,20 +175,20 @@ struct grub_ntfs_comp + struct grub_ntfs_comp_table_element comp_table[16]; + grub_uint32_t cbuf_ofs, cbuf_vcn; + int log_spc; +- char *cbuf; ++ grub_uint8_t *cbuf; + }; + + struct grub_ntfs_rlst + { + int flags; + grub_disk_addr_t target_vcn, curr_vcn, next_vcn, curr_lcn; +- char *cur_run; ++ grub_uint8_t *cur_run; + struct grub_ntfs_attr *attr; + struct grub_ntfs_comp comp; + }; + + typedef grub_err_t (*grub_ntfscomp_func_t) (struct grub_ntfs_attr * at, +- char *dest, ++ grub_uint8_t *dest, + grub_disk_addr_t ofs, + grub_size_t len, + struct grub_ntfs_rlst * ctx, +-- +1.8.1.4 + diff --git a/0094-Import-gcrypt-public-key-cryptography-and-implement-.patch b/0094-Import-gcrypt-public-key-cryptography-and-implement-.patch new file mode 100644 index 0000000..cf8fd4e --- /dev/null +++ b/0094-Import-gcrypt-public-key-cryptography-and-implement-.patch @@ -0,0 +1,44060 @@ +From 5d27e1e9a4819f8f791a43c968ad49f11615d67a Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Fri, 11 Jan 2013 21:32:42 +0100 +Subject: [PATCH 094/364] Import gcrypt public-key cryptography and + implement signature checking. + +--- + ChangeLog | 4 + + Makefile.util.def | 5 - + autogen.sh | 10 + + conf/Makefile.common | 8 +- + grub-core/Makefile.core.def | 36 + + grub-core/commands/hashsum.c | 2 +- + grub-core/commands/verify.c | 763 +++++++ + grub-core/io/gzio.c | 2 +- + grub-core/io/lzopio.c | 3 +- + grub-core/io/xzio.c | 3 +- + grub-core/kern/file.c | 2 +- + grub-core/lib/crypto.c | 34 + + grub-core/lib/libgcrypt/cipher/ChangeLog | 94 +- + grub-core/lib/libgcrypt/cipher/Makefile.am | 82 + + grub-core/lib/libgcrypt/cipher/Manifest | 73 + + grub-core/lib/libgcrypt/cipher/ac.c | 2 +- + grub-core/lib/libgcrypt/cipher/cipher.c | 737 ++++-- + grub-core/lib/libgcrypt/cipher/crc.c | 1 - + grub-core/lib/libgcrypt/cipher/des.c | 2 +- + grub-core/lib/libgcrypt/cipher/dsa.c | 1 + + grub-core/lib/libgcrypt/cipher/ecc.c | 23 +- + grub-core/lib/libgcrypt/cipher/md.c | 19 +- + grub-core/lib/libgcrypt/cipher/md4.c | 1 - + grub-core/lib/libgcrypt/cipher/md5.c | 1 - + grub-core/lib/libgcrypt/cipher/primegen.c | 4 +- + grub-core/lib/libgcrypt/cipher/pubkey.c | 12 +- + grub-core/lib/libgcrypt/cipher/rfc2268.c | 2 +- + grub-core/lib/libgcrypt/cipher/rmd160.c | 1 - + grub-core/lib/libgcrypt/cipher/rsa.c | 32 +- + grub-core/lib/libgcrypt/cipher/sha1.c | 1 - + grub-core/lib/libgcrypt/cipher/sha256.c | 91 +- + grub-core/lib/libgcrypt/cipher/sha512.c | 98 +- + grub-core/lib/libgcrypt/cipher/test-getrusage.c | 105 + + grub-core/lib/libgcrypt/cipher/tiger.c | 102 +- + grub-core/lib/libgcrypt/cipher/twofish.c | 2 +- + grub-core/lib/libgcrypt/cipher/whirlpool.c | 1 - + grub-core/lib/libgcrypt/mpi/ChangeLog-2011 | 831 +++++++ + grub-core/lib/libgcrypt/mpi/Makefile.am | 177 ++ + grub-core/lib/libgcrypt/mpi/Manifest | 41 + + grub-core/lib/libgcrypt/mpi/alpha/README | 53 + + grub-core/lib/libgcrypt/mpi/alpha/distfiles | 11 + + grub-core/lib/libgcrypt/mpi/alpha/mpih-add1.S | 124 + + grub-core/lib/libgcrypt/mpi/alpha/mpih-lshift.S | 122 + + grub-core/lib/libgcrypt/mpi/alpha/mpih-mul1.S | 90 + + grub-core/lib/libgcrypt/mpi/alpha/mpih-mul2.S | 97 + + grub-core/lib/libgcrypt/mpi/alpha/mpih-mul3.S | 95 + + grub-core/lib/libgcrypt/mpi/alpha/mpih-rshift.S | 118 + + grub-core/lib/libgcrypt/mpi/alpha/mpih-sub1.S | 124 + + grub-core/lib/libgcrypt/mpi/alpha/udiv-qrnnd.S | 159 ++ + grub-core/lib/libgcrypt/mpi/amd64/distfiles | 7 + + grub-core/lib/libgcrypt/mpi/amd64/mpih-add1.S | 63 + + grub-core/lib/libgcrypt/mpi/amd64/mpih-lshift.S | 77 + + grub-core/lib/libgcrypt/mpi/amd64/mpih-mul1.S | 65 + + grub-core/lib/libgcrypt/mpi/amd64/mpih-mul2.S | 107 + + grub-core/lib/libgcrypt/mpi/amd64/mpih-mul3.S | 66 + + grub-core/lib/libgcrypt/mpi/amd64/mpih-rshift.S | 80 + + grub-core/lib/libgcrypt/mpi/amd64/mpih-sub1.S | 61 + + grub-core/lib/libgcrypt/mpi/config.links | 360 +++ + grub-core/lib/libgcrypt/mpi/ec.c | 708 ++++++ + grub-core/lib/libgcrypt/mpi/generic/Manifest | 29 + + grub-core/lib/libgcrypt/mpi/generic/distfiles | 11 + + grub-core/lib/libgcrypt/mpi/generic/mpi-asm-defs.h | 10 + + grub-core/lib/libgcrypt/mpi/generic/mpih-add1.c | 65 + + grub-core/lib/libgcrypt/mpi/generic/mpih-lshift.c | 68 + + grub-core/lib/libgcrypt/mpi/generic/mpih-mul1.c | 62 + + grub-core/lib/libgcrypt/mpi/generic/mpih-mul2.c | 68 + + grub-core/lib/libgcrypt/mpi/generic/mpih-mul3.c | 68 + + grub-core/lib/libgcrypt/mpi/generic/mpih-rshift.c | 67 + + grub-core/lib/libgcrypt/mpi/generic/mpih-sub1.c | 66 + + grub-core/lib/libgcrypt/mpi/generic/udiv-w-sdiv.c | 133 ++ + grub-core/lib/libgcrypt/mpi/hppa/README | 84 + + grub-core/lib/libgcrypt/mpi/hppa/distfiles | 7 + + grub-core/lib/libgcrypt/mpi/hppa/mpih-add1.S | 70 + + grub-core/lib/libgcrypt/mpi/hppa/mpih-lshift.S | 77 + + grub-core/lib/libgcrypt/mpi/hppa/mpih-rshift.S | 73 + + grub-core/lib/libgcrypt/mpi/hppa/mpih-sub1.S | 78 + + grub-core/lib/libgcrypt/mpi/hppa/udiv-qrnnd.S | 297 +++ + grub-core/lib/libgcrypt/mpi/i386/Manifest | 28 + + grub-core/lib/libgcrypt/mpi/i386/distfiles | 10 + + grub-core/lib/libgcrypt/mpi/i386/mpih-add1.S | 116 + + grub-core/lib/libgcrypt/mpi/i386/mpih-lshift.S | 94 + + grub-core/lib/libgcrypt/mpi/i386/mpih-mul1.S | 84 + + grub-core/lib/libgcrypt/mpi/i386/mpih-mul2.S | 86 + + grub-core/lib/libgcrypt/mpi/i386/mpih-mul3.S | 86 + + grub-core/lib/libgcrypt/mpi/i386/mpih-rshift.S | 97 + + grub-core/lib/libgcrypt/mpi/i386/mpih-sub1.S | 117 + + grub-core/lib/libgcrypt/mpi/i386/syntax.h | 68 + + grub-core/lib/libgcrypt/mpi/i586/Manifest | 27 + + grub-core/lib/libgcrypt/mpi/i586/README | 26 + + grub-core/lib/libgcrypt/mpi/i586/distfiles | 10 + + grub-core/lib/libgcrypt/mpi/i586/mpih-add1.S | 135 ++ + grub-core/lib/libgcrypt/mpi/i586/mpih-lshift.S | 229 ++ + grub-core/lib/libgcrypt/mpi/i586/mpih-mul1.S | 89 + + grub-core/lib/libgcrypt/mpi/i586/mpih-mul2.S | 93 + + grub-core/lib/libgcrypt/mpi/i586/mpih-mul3.S | 93 + + grub-core/lib/libgcrypt/mpi/i586/mpih-rshift.S | 228 ++ + grub-core/lib/libgcrypt/mpi/i586/mpih-sub1.S | 142 ++ + grub-core/lib/libgcrypt/mpi/longlong.h | 1578 +++++++++++++ + grub-core/lib/libgcrypt/mpi/m68k/Manifest | 25 + + grub-core/lib/libgcrypt/mpi/m68k/distfiles | 9 + + grub-core/lib/libgcrypt/mpi/m68k/mc68020/Manifest | 23 + + grub-core/lib/libgcrypt/mpi/m68k/mc68020/distfiles | 4 + + .../lib/libgcrypt/mpi/m68k/mc68020/mpih-mul1.S | 104 + + .../lib/libgcrypt/mpi/m68k/mc68020/mpih-mul2.S | 94 + + .../lib/libgcrypt/mpi/m68k/mc68020/mpih-mul3.S | 97 + + grub-core/lib/libgcrypt/mpi/m68k/mpih-add1.S | 92 + + grub-core/lib/libgcrypt/mpi/m68k/mpih-lshift.S | 164 ++ + grub-core/lib/libgcrypt/mpi/m68k/mpih-rshift.S | 162 ++ + grub-core/lib/libgcrypt/mpi/m68k/mpih-sub1.S | 91 + + grub-core/lib/libgcrypt/mpi/m68k/syntax.h | 185 ++ + grub-core/lib/libgcrypt/mpi/mips3/Manifest | 28 + + grub-core/lib/libgcrypt/mpi/mips3/README | 23 + + grub-core/lib/libgcrypt/mpi/mips3/distfiles | 11 + + grub-core/lib/libgcrypt/mpi/mips3/mpi-asm-defs.h | 10 + + grub-core/lib/libgcrypt/mpi/mips3/mpih-add1.S | 124 + + grub-core/lib/libgcrypt/mpi/mips3/mpih-lshift.S | 97 + + grub-core/lib/libgcrypt/mpi/mips3/mpih-mul1.S | 89 + + grub-core/lib/libgcrypt/mpi/mips3/mpih-mul2.S | 101 + + grub-core/lib/libgcrypt/mpi/mips3/mpih-mul3.S | 101 + + grub-core/lib/libgcrypt/mpi/mips3/mpih-rshift.S | 95 + + grub-core/lib/libgcrypt/mpi/mips3/mpih-sub1.S | 125 + + grub-core/lib/libgcrypt/mpi/mpi-add.c | 235 ++ + grub-core/lib/libgcrypt/mpi/mpi-bit.c | 364 +++ + grub-core/lib/libgcrypt/mpi/mpi-cmp.c | 107 + + grub-core/lib/libgcrypt/mpi/mpi-div.c | 355 +++ + grub-core/lib/libgcrypt/mpi/mpi-gcd.c | 51 + + grub-core/lib/libgcrypt/mpi/mpi-inline.c | 35 + + grub-core/lib/libgcrypt/mpi/mpi-inline.h | 154 ++ + grub-core/lib/libgcrypt/mpi/mpi-internal.h | 277 +++ + grub-core/lib/libgcrypt/mpi/mpi-inv.c | 267 +++ + grub-core/lib/libgcrypt/mpi/mpi-mod.c | 184 ++ + grub-core/lib/libgcrypt/mpi/mpi-mpow.c | 223 ++ + grub-core/lib/libgcrypt/mpi/mpi-mul.c | 212 ++ + grub-core/lib/libgcrypt/mpi/mpi-pow.c | 324 +++ + grub-core/lib/libgcrypt/mpi/mpi-scan.c | 130 ++ + grub-core/lib/libgcrypt/mpi/mpicoder.c | 750 ++++++ + grub-core/lib/libgcrypt/mpi/mpih-div.c | 533 +++++ + grub-core/lib/libgcrypt/mpi/mpih-mul.c | 528 +++++ + grub-core/lib/libgcrypt/mpi/mpiutil.c | 460 ++++ + grub-core/lib/libgcrypt/mpi/pa7100/Manifest | 22 + + grub-core/lib/libgcrypt/mpi/pa7100/distfiles | 4 + + grub-core/lib/libgcrypt/mpi/pa7100/mpih-lshift.S | 96 + + grub-core/lib/libgcrypt/mpi/pa7100/mpih-rshift.S | 92 + + grub-core/lib/libgcrypt/mpi/pentium4/README | 115 + + grub-core/lib/libgcrypt/mpi/pentium4/distfiles | 3 + + grub-core/lib/libgcrypt/mpi/pentium4/mmx/distfiles | 2 + + .../lib/libgcrypt/mpi/pentium4/mmx/mpih-lshift.S | 457 ++++ + .../lib/libgcrypt/mpi/pentium4/mmx/mpih-rshift.S | 453 ++++ + .../lib/libgcrypt/mpi/pentium4/sse2/distfiles | 5 + + .../lib/libgcrypt/mpi/pentium4/sse2/mpih-add1.S | 91 + + .../lib/libgcrypt/mpi/pentium4/sse2/mpih-mul1.S | 96 + + .../lib/libgcrypt/mpi/pentium4/sse2/mpih-mul2.S | 136 ++ + .../lib/libgcrypt/mpi/pentium4/sse2/mpih-mul3.S | 127 ++ + .../lib/libgcrypt/mpi/pentium4/sse2/mpih-sub1.S | 112 + + grub-core/lib/libgcrypt/mpi/power/Manifest | 27 + + grub-core/lib/libgcrypt/mpi/power/distfiles | 8 + + grub-core/lib/libgcrypt/mpi/power/mpih-add1.S | 87 + + grub-core/lib/libgcrypt/mpi/power/mpih-lshift.S | 64 + + grub-core/lib/libgcrypt/mpi/power/mpih-mul1.S | 115 + + grub-core/lib/libgcrypt/mpi/power/mpih-mul2.S | 130 ++ + grub-core/lib/libgcrypt/mpi/power/mpih-mul3.S | 135 ++ + grub-core/lib/libgcrypt/mpi/power/mpih-rshift.S | 64 + + grub-core/lib/libgcrypt/mpi/power/mpih-sub1.S | 88 + + grub-core/lib/libgcrypt/mpi/powerpc32/Manifest | 28 + + grub-core/lib/libgcrypt/mpi/powerpc32/distfiles | 10 + + grub-core/lib/libgcrypt/mpi/powerpc32/mpih-add1.S | 136 ++ + .../lib/libgcrypt/mpi/powerpc32/mpih-lshift.S | 198 ++ + grub-core/lib/libgcrypt/mpi/powerpc32/mpih-mul1.S | 120 + + grub-core/lib/libgcrypt/mpi/powerpc32/mpih-mul2.S | 127 ++ + grub-core/lib/libgcrypt/mpi/powerpc32/mpih-mul3.S | 130 ++ + .../lib/libgcrypt/mpi/powerpc32/mpih-rshift.S | 131 ++ + grub-core/lib/libgcrypt/mpi/powerpc32/mpih-sub1.S | 133 ++ + grub-core/lib/libgcrypt/mpi/powerpc32/syntax.h | 75 + + grub-core/lib/libgcrypt/mpi/sparc32/Manifest | 24 + + grub-core/lib/libgcrypt/mpi/sparc32/distfiles | 6 + + grub-core/lib/libgcrypt/mpi/sparc32/mpih-add1.S | 239 ++ + grub-core/lib/libgcrypt/mpi/sparc32/mpih-lshift.S | 97 + + grub-core/lib/libgcrypt/mpi/sparc32/mpih-rshift.S | 93 + + grub-core/lib/libgcrypt/mpi/sparc32/udiv.S | 195 ++ + grub-core/lib/libgcrypt/mpi/sparc32v8/Manifest | 23 + + grub-core/lib/libgcrypt/mpi/sparc32v8/distfiles | 5 + + grub-core/lib/libgcrypt/mpi/sparc32v8/mpih-mul1.S | 109 + + grub-core/lib/libgcrypt/mpi/sparc32v8/mpih-mul2.S | 132 ++ + grub-core/lib/libgcrypt/mpi/sparc32v8/mpih-mul3.S | 67 + + grub-core/lib/libgcrypt/mpi/supersparc/Manifest | 21 + + grub-core/lib/libgcrypt/mpi/supersparc/distfiles | 3 + + grub-core/lib/libgcrypt/mpi/supersparc/udiv.S | 118 + + grub-core/lib/libgcrypt/src/ChangeLog-2011 | 2398 ++++++++++++++++++++ + grub-core/lib/libgcrypt/src/Makefile.am | 143 ++ + grub-core/lib/libgcrypt/src/Manifest | 58 + + grub-core/lib/libgcrypt/src/ath.c | 323 +++ + grub-core/lib/libgcrypt/src/ath.h | 92 + + grub-core/lib/libgcrypt/src/cipher-proto.h | 124 + + grub-core/lib/libgcrypt/src/cipher.h | 181 ++ + grub-core/lib/libgcrypt/src/dumpsexp.c | 766 +++++++ + grub-core/lib/libgcrypt/src/fips.c | 852 +++++++ + grub-core/lib/libgcrypt/src/g10lib.h | 349 +++ + grub-core/lib/libgcrypt/src/gcrypt-module.h | 204 ++ + grub-core/lib/libgcrypt/src/gcrypt.h.in | 1337 +++++++++++ + grub-core/lib/libgcrypt/src/gcryptrnd.c | 680 ++++++ + grub-core/lib/libgcrypt/src/getrandom.c | 326 +++ + grub-core/lib/libgcrypt/src/global.c | 1112 +++++++++ + grub-core/lib/libgcrypt/src/hmac256.c | 795 +++++++ + grub-core/lib/libgcrypt/src/hmac256.h | 36 + + grub-core/lib/libgcrypt/src/hwfeatures.c | 192 ++ + grub-core/lib/libgcrypt/src/libgcrypt-config.in | 189 ++ + grub-core/lib/libgcrypt/src/libgcrypt.def | 213 ++ + grub-core/lib/libgcrypt/src/libgcrypt.m4 | 122 + + grub-core/lib/libgcrypt/src/libgcrypt.vers | 94 + + grub-core/lib/libgcrypt/src/misc.c | 298 +++ + grub-core/lib/libgcrypt/src/missing-string.c | 54 + + grub-core/lib/libgcrypt/src/module.c | 212 ++ + grub-core/lib/libgcrypt/src/mpi.h | 263 +++ + grub-core/lib/libgcrypt/src/secmem.c | 696 ++++++ + grub-core/lib/libgcrypt/src/secmem.h | 39 + + grub-core/lib/libgcrypt/src/sexp.c | 2033 +++++++++++++++++ + grub-core/lib/libgcrypt/src/stdmem.c | 242 ++ + grub-core/lib/libgcrypt/src/stdmem.h | 32 + + grub-core/lib/libgcrypt/src/types.h | 128 ++ + grub-core/lib/libgcrypt/src/versioninfo.rc.in | 51 + + grub-core/lib/libgcrypt/src/visibility.c | 1146 ++++++++++ + grub-core/lib/libgcrypt/src/visibility.h | 565 +++++ + grub-core/lib/libgcrypt_wrap/cipher_wrap.h | 46 +- + grub-core/lib/libgcrypt_wrap/mem.c | 112 + + grub-core/lib/posix_wrap/stdio.h | 3 +- + grub-core/lib/posix_wrap/string.h | 14 +- + grub-core/lib/posix_wrap/sys/types.h | 9 + + include/grub/crypto.h | 91 +- + include/grub/err.h | 3 +- + include/grub/file.h | 27 +- + include/grub/gcry/types.h | 37 + + include/grub/gcrypt/gcrypt.h | 1333 +++++++++++ + include/grub/gcrypt/gpg-error.h | 32 + + include/grub/kernel.h | 5 +- + include/grub/pubkey.h | 38 + + util/grub-mkimage.c | 50 +- + util/import_gcry.py | 211 +- + util/import_gcrypth.sed | 7 + + 238 files changed, 40501 insertions(+), 418 deletions(-) + create mode 100644 grub-core/commands/verify.c + create mode 100644 grub-core/lib/libgcrypt/cipher/Makefile.am + create mode 100644 grub-core/lib/libgcrypt/cipher/Manifest + create mode 100644 grub-core/lib/libgcrypt/cipher/test-getrusage.c + create mode 100644 grub-core/lib/libgcrypt/mpi/ChangeLog-2011 + create mode 100644 grub-core/lib/libgcrypt/mpi/Makefile.am + create mode 100644 grub-core/lib/libgcrypt/mpi/Manifest + create mode 100644 grub-core/lib/libgcrypt/mpi/alpha/README + create mode 100644 grub-core/lib/libgcrypt/mpi/alpha/distfiles + create mode 100644 grub-core/lib/libgcrypt/mpi/alpha/mpih-add1.S + create mode 100644 grub-core/lib/libgcrypt/mpi/alpha/mpih-lshift.S + create mode 100644 grub-core/lib/libgcrypt/mpi/alpha/mpih-mul1.S + create mode 100644 grub-core/lib/libgcrypt/mpi/alpha/mpih-mul2.S + create mode 100644 grub-core/lib/libgcrypt/mpi/alpha/mpih-mul3.S + create mode 100644 grub-core/lib/libgcrypt/mpi/alpha/mpih-rshift.S + create mode 100644 grub-core/lib/libgcrypt/mpi/alpha/mpih-sub1.S + create mode 100644 grub-core/lib/libgcrypt/mpi/alpha/udiv-qrnnd.S + create mode 100644 grub-core/lib/libgcrypt/mpi/amd64/distfiles + create mode 100644 grub-core/lib/libgcrypt/mpi/amd64/mpih-add1.S + create mode 100644 grub-core/lib/libgcrypt/mpi/amd64/mpih-lshift.S + create mode 100644 grub-core/lib/libgcrypt/mpi/amd64/mpih-mul1.S + create mode 100644 grub-core/lib/libgcrypt/mpi/amd64/mpih-mul2.S + create mode 100644 grub-core/lib/libgcrypt/mpi/amd64/mpih-mul3.S + create mode 100644 grub-core/lib/libgcrypt/mpi/amd64/mpih-rshift.S + create mode 100644 grub-core/lib/libgcrypt/mpi/amd64/mpih-sub1.S + create mode 100644 grub-core/lib/libgcrypt/mpi/config.links + create mode 100644 grub-core/lib/libgcrypt/mpi/ec.c + create mode 100644 grub-core/lib/libgcrypt/mpi/generic/Manifest + create mode 100644 grub-core/lib/libgcrypt/mpi/generic/distfiles + create mode 100644 grub-core/lib/libgcrypt/mpi/generic/mpi-asm-defs.h + create mode 100644 grub-core/lib/libgcrypt/mpi/generic/mpih-add1.c + create mode 100644 grub-core/lib/libgcrypt/mpi/generic/mpih-lshift.c + create mode 100644 grub-core/lib/libgcrypt/mpi/generic/mpih-mul1.c + create mode 100644 grub-core/lib/libgcrypt/mpi/generic/mpih-mul2.c + create mode 100644 grub-core/lib/libgcrypt/mpi/generic/mpih-mul3.c + create mode 100644 grub-core/lib/libgcrypt/mpi/generic/mpih-rshift.c + create mode 100644 grub-core/lib/libgcrypt/mpi/generic/mpih-sub1.c + create mode 100644 grub-core/lib/libgcrypt/mpi/generic/udiv-w-sdiv.c + create mode 100644 grub-core/lib/libgcrypt/mpi/hppa/README + create mode 100644 grub-core/lib/libgcrypt/mpi/hppa/distfiles + create mode 100644 grub-core/lib/libgcrypt/mpi/hppa/mpih-add1.S + create mode 100644 grub-core/lib/libgcrypt/mpi/hppa/mpih-lshift.S + create mode 100644 grub-core/lib/libgcrypt/mpi/hppa/mpih-rshift.S + create mode 100644 grub-core/lib/libgcrypt/mpi/hppa/mpih-sub1.S + create mode 100644 grub-core/lib/libgcrypt/mpi/hppa/udiv-qrnnd.S + create mode 100644 grub-core/lib/libgcrypt/mpi/i386/Manifest + create mode 100644 grub-core/lib/libgcrypt/mpi/i386/distfiles + create mode 100644 grub-core/lib/libgcrypt/mpi/i386/mpih-add1.S + create mode 100644 grub-core/lib/libgcrypt/mpi/i386/mpih-lshift.S + create mode 100644 grub-core/lib/libgcrypt/mpi/i386/mpih-mul1.S + create mode 100644 grub-core/lib/libgcrypt/mpi/i386/mpih-mul2.S + create mode 100644 grub-core/lib/libgcrypt/mpi/i386/mpih-mul3.S + create mode 100644 grub-core/lib/libgcrypt/mpi/i386/mpih-rshift.S + create mode 100644 grub-core/lib/libgcrypt/mpi/i386/mpih-sub1.S + create mode 100644 grub-core/lib/libgcrypt/mpi/i386/syntax.h + create mode 100644 grub-core/lib/libgcrypt/mpi/i586/Manifest + create mode 100644 grub-core/lib/libgcrypt/mpi/i586/README + create mode 100644 grub-core/lib/libgcrypt/mpi/i586/distfiles + create mode 100644 grub-core/lib/libgcrypt/mpi/i586/mpih-add1.S + create mode 100644 grub-core/lib/libgcrypt/mpi/i586/mpih-lshift.S + create mode 100644 grub-core/lib/libgcrypt/mpi/i586/mpih-mul1.S + create mode 100644 grub-core/lib/libgcrypt/mpi/i586/mpih-mul2.S + create mode 100644 grub-core/lib/libgcrypt/mpi/i586/mpih-mul3.S + create mode 100644 grub-core/lib/libgcrypt/mpi/i586/mpih-rshift.S + create mode 100644 grub-core/lib/libgcrypt/mpi/i586/mpih-sub1.S + create mode 100644 grub-core/lib/libgcrypt/mpi/longlong.h + create mode 100644 grub-core/lib/libgcrypt/mpi/m68k/Manifest + create mode 100644 grub-core/lib/libgcrypt/mpi/m68k/distfiles + create mode 100644 grub-core/lib/libgcrypt/mpi/m68k/mc68020/Manifest + create mode 100644 grub-core/lib/libgcrypt/mpi/m68k/mc68020/distfiles + create mode 100644 grub-core/lib/libgcrypt/mpi/m68k/mc68020/mpih-mul1.S + create mode 100644 grub-core/lib/libgcrypt/mpi/m68k/mc68020/mpih-mul2.S + create mode 100644 grub-core/lib/libgcrypt/mpi/m68k/mc68020/mpih-mul3.S + create mode 100644 grub-core/lib/libgcrypt/mpi/m68k/mpih-add1.S + create mode 100644 grub-core/lib/libgcrypt/mpi/m68k/mpih-lshift.S + create mode 100644 grub-core/lib/libgcrypt/mpi/m68k/mpih-rshift.S + create mode 100644 grub-core/lib/libgcrypt/mpi/m68k/mpih-sub1.S + create mode 100644 grub-core/lib/libgcrypt/mpi/m68k/syntax.h + create mode 100644 grub-core/lib/libgcrypt/mpi/mips3/Manifest + create mode 100644 grub-core/lib/libgcrypt/mpi/mips3/README + create mode 100644 grub-core/lib/libgcrypt/mpi/mips3/distfiles + create mode 100644 grub-core/lib/libgcrypt/mpi/mips3/mpi-asm-defs.h + create mode 100644 grub-core/lib/libgcrypt/mpi/mips3/mpih-add1.S + create mode 100644 grub-core/lib/libgcrypt/mpi/mips3/mpih-lshift.S + create mode 100644 grub-core/lib/libgcrypt/mpi/mips3/mpih-mul1.S + create mode 100644 grub-core/lib/libgcrypt/mpi/mips3/mpih-mul2.S + create mode 100644 grub-core/lib/libgcrypt/mpi/mips3/mpih-mul3.S + create mode 100644 grub-core/lib/libgcrypt/mpi/mips3/mpih-rshift.S + create mode 100644 grub-core/lib/libgcrypt/mpi/mips3/mpih-sub1.S + create mode 100644 grub-core/lib/libgcrypt/mpi/mpi-add.c + create mode 100644 grub-core/lib/libgcrypt/mpi/mpi-bit.c + create mode 100644 grub-core/lib/libgcrypt/mpi/mpi-cmp.c + create mode 100644 grub-core/lib/libgcrypt/mpi/mpi-div.c + create mode 100644 grub-core/lib/libgcrypt/mpi/mpi-gcd.c + create mode 100644 grub-core/lib/libgcrypt/mpi/mpi-inline.c + create mode 100644 grub-core/lib/libgcrypt/mpi/mpi-inline.h + create mode 100644 grub-core/lib/libgcrypt/mpi/mpi-internal.h + create mode 100644 grub-core/lib/libgcrypt/mpi/mpi-inv.c + create mode 100644 grub-core/lib/libgcrypt/mpi/mpi-mod.c + create mode 100644 grub-core/lib/libgcrypt/mpi/mpi-mpow.c + create mode 100644 grub-core/lib/libgcrypt/mpi/mpi-mul.c + create mode 100644 grub-core/lib/libgcrypt/mpi/mpi-pow.c + create mode 100644 grub-core/lib/libgcrypt/mpi/mpi-scan.c + create mode 100644 grub-core/lib/libgcrypt/mpi/mpicoder.c + create mode 100644 grub-core/lib/libgcrypt/mpi/mpih-div.c + create mode 100644 grub-core/lib/libgcrypt/mpi/mpih-mul.c + create mode 100644 grub-core/lib/libgcrypt/mpi/mpiutil.c + create mode 100644 grub-core/lib/libgcrypt/mpi/pa7100/Manifest + create mode 100644 grub-core/lib/libgcrypt/mpi/pa7100/distfiles + create mode 100644 grub-core/lib/libgcrypt/mpi/pa7100/mpih-lshift.S + create mode 100644 grub-core/lib/libgcrypt/mpi/pa7100/mpih-rshift.S + create mode 100644 grub-core/lib/libgcrypt/mpi/pentium4/README + create mode 100644 grub-core/lib/libgcrypt/mpi/pentium4/distfiles + create mode 100644 grub-core/lib/libgcrypt/mpi/pentium4/mmx/distfiles + create mode 100644 grub-core/lib/libgcrypt/mpi/pentium4/mmx/mpih-lshift.S + create mode 100644 grub-core/lib/libgcrypt/mpi/pentium4/mmx/mpih-rshift.S + create mode 100644 grub-core/lib/libgcrypt/mpi/pentium4/sse2/distfiles + create mode 100644 grub-core/lib/libgcrypt/mpi/pentium4/sse2/mpih-add1.S + create mode 100644 grub-core/lib/libgcrypt/mpi/pentium4/sse2/mpih-mul1.S + create mode 100644 grub-core/lib/libgcrypt/mpi/pentium4/sse2/mpih-mul2.S + create mode 100644 grub-core/lib/libgcrypt/mpi/pentium4/sse2/mpih-mul3.S + create mode 100644 grub-core/lib/libgcrypt/mpi/pentium4/sse2/mpih-sub1.S + create mode 100644 grub-core/lib/libgcrypt/mpi/power/Manifest + create mode 100644 grub-core/lib/libgcrypt/mpi/power/distfiles + create mode 100644 grub-core/lib/libgcrypt/mpi/power/mpih-add1.S + create mode 100644 grub-core/lib/libgcrypt/mpi/power/mpih-lshift.S + create mode 100644 grub-core/lib/libgcrypt/mpi/power/mpih-mul1.S + create mode 100644 grub-core/lib/libgcrypt/mpi/power/mpih-mul2.S + create mode 100644 grub-core/lib/libgcrypt/mpi/power/mpih-mul3.S + create mode 100644 grub-core/lib/libgcrypt/mpi/power/mpih-rshift.S + create mode 100644 grub-core/lib/libgcrypt/mpi/power/mpih-sub1.S + create mode 100644 grub-core/lib/libgcrypt/mpi/powerpc32/Manifest + create mode 100644 grub-core/lib/libgcrypt/mpi/powerpc32/distfiles + create mode 100644 grub-core/lib/libgcrypt/mpi/powerpc32/mpih-add1.S + create mode 100644 grub-core/lib/libgcrypt/mpi/powerpc32/mpih-lshift.S + create mode 100644 grub-core/lib/libgcrypt/mpi/powerpc32/mpih-mul1.S + create mode 100644 grub-core/lib/libgcrypt/mpi/powerpc32/mpih-mul2.S + create mode 100644 grub-core/lib/libgcrypt/mpi/powerpc32/mpih-mul3.S + create mode 100644 grub-core/lib/libgcrypt/mpi/powerpc32/mpih-rshift.S + create mode 100644 grub-core/lib/libgcrypt/mpi/powerpc32/mpih-sub1.S + create mode 100644 grub-core/lib/libgcrypt/mpi/powerpc32/syntax.h + create mode 100644 grub-core/lib/libgcrypt/mpi/sparc32/Manifest + create mode 100644 grub-core/lib/libgcrypt/mpi/sparc32/distfiles + create mode 100644 grub-core/lib/libgcrypt/mpi/sparc32/mpih-add1.S + create mode 100644 grub-core/lib/libgcrypt/mpi/sparc32/mpih-lshift.S + create mode 100644 grub-core/lib/libgcrypt/mpi/sparc32/mpih-rshift.S + create mode 100644 grub-core/lib/libgcrypt/mpi/sparc32/udiv.S + create mode 100644 grub-core/lib/libgcrypt/mpi/sparc32v8/Manifest + create mode 100644 grub-core/lib/libgcrypt/mpi/sparc32v8/distfiles + create mode 100644 grub-core/lib/libgcrypt/mpi/sparc32v8/mpih-mul1.S + create mode 100644 grub-core/lib/libgcrypt/mpi/sparc32v8/mpih-mul2.S + create mode 100644 grub-core/lib/libgcrypt/mpi/sparc32v8/mpih-mul3.S + create mode 100644 grub-core/lib/libgcrypt/mpi/supersparc/Manifest + create mode 100644 grub-core/lib/libgcrypt/mpi/supersparc/distfiles + create mode 100644 grub-core/lib/libgcrypt/mpi/supersparc/udiv.S + create mode 100644 grub-core/lib/libgcrypt/src/ChangeLog-2011 + create mode 100644 grub-core/lib/libgcrypt/src/Makefile.am + create mode 100644 grub-core/lib/libgcrypt/src/Manifest + create mode 100644 grub-core/lib/libgcrypt/src/ath.c + create mode 100644 grub-core/lib/libgcrypt/src/ath.h + create mode 100644 grub-core/lib/libgcrypt/src/cipher-proto.h + create mode 100644 grub-core/lib/libgcrypt/src/cipher.h + create mode 100644 grub-core/lib/libgcrypt/src/dumpsexp.c + create mode 100644 grub-core/lib/libgcrypt/src/fips.c + create mode 100644 grub-core/lib/libgcrypt/src/g10lib.h + create mode 100644 grub-core/lib/libgcrypt/src/gcrypt-module.h + create mode 100644 grub-core/lib/libgcrypt/src/gcrypt.h.in + create mode 100644 grub-core/lib/libgcrypt/src/gcryptrnd.c + create mode 100644 grub-core/lib/libgcrypt/src/getrandom.c + create mode 100644 grub-core/lib/libgcrypt/src/global.c + create mode 100644 grub-core/lib/libgcrypt/src/hmac256.c + create mode 100644 grub-core/lib/libgcrypt/src/hmac256.h + create mode 100644 grub-core/lib/libgcrypt/src/hwfeatures.c + create mode 100644 grub-core/lib/libgcrypt/src/libgcrypt-config.in + create mode 100644 grub-core/lib/libgcrypt/src/libgcrypt.def + create mode 100644 grub-core/lib/libgcrypt/src/libgcrypt.m4 + create mode 100644 grub-core/lib/libgcrypt/src/libgcrypt.vers + create mode 100644 grub-core/lib/libgcrypt/src/misc.c + create mode 100644 grub-core/lib/libgcrypt/src/missing-string.c + create mode 100644 grub-core/lib/libgcrypt/src/module.c + create mode 100644 grub-core/lib/libgcrypt/src/mpi.h + create mode 100644 grub-core/lib/libgcrypt/src/secmem.c + create mode 100644 grub-core/lib/libgcrypt/src/secmem.h + create mode 100644 grub-core/lib/libgcrypt/src/sexp.c + create mode 100644 grub-core/lib/libgcrypt/src/stdmem.c + create mode 100644 grub-core/lib/libgcrypt/src/stdmem.h + create mode 100644 grub-core/lib/libgcrypt/src/types.h + create mode 100644 grub-core/lib/libgcrypt/src/versioninfo.rc.in + create mode 100644 grub-core/lib/libgcrypt/src/visibility.c + create mode 100644 grub-core/lib/libgcrypt/src/visibility.h + create mode 100644 grub-core/lib/libgcrypt_wrap/mem.c + create mode 100644 include/grub/gcry/types.h + create mode 100644 include/grub/gcrypt/gcrypt.h + create mode 100644 include/grub/gcrypt/gpg-error.h + create mode 100644 include/grub/pubkey.h + create mode 100644 util/import_gcrypth.sed + +diff --git a/ChangeLog b/ChangeLog +index 41dbadd..22b18b1 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,7 @@ ++2013-01-11 Vladimir Serbinenko ++ ++ Import gcrypt public-key cryptography and implement signature checking. ++ + 2013-01-10 Vladimir Serbinenko + + * grub-core/fs/ntfs.c: Ue more appropriate types. +diff --git a/Makefile.util.def b/Makefile.util.def +index 01f7456..3ee5e4e 100644 +--- a/Makefile.util.def ++++ b/Makefile.util.def +@@ -213,8 +213,6 @@ program = { + ldadd = libgrubkern.a; + ldadd = grub-core/gnulib/libgnu.a; + ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; +- cflags = '$(CFLAGS_GCRY)'; +- cppflags = '$(CPPFLAGS_GCRY)'; + }; + + program = { +@@ -245,9 +243,6 @@ program = { + common = grub-core/kern/emu/hostfs.c; + common = grub-core/disk/host.c; + +- cflags = '$(CFLAGS_GCRY)'; +- cppflags = '$(CPPFLAGS_GCRY)'; +- + ldadd = libgrubmods.a; + ldadd = libgrubgcry.a; + ldadd = libgrubkern.a; +diff --git a/autogen.sh b/autogen.sh +index db719cd..5524083 100755 +--- a/autogen.sh ++++ b/autogen.sh +@@ -13,6 +13,16 @@ python util/import_unicode.py unicode/UnicodeData.txt unicode/BidiMirroring.txt + + echo "Importing libgcrypt..." + python util/import_gcry.py grub-core/lib/libgcrypt/ grub-core ++sed -n -f util/import_gcrypth.sed < grub-core/lib/libgcrypt/src/gcrypt.h.in > include/grub/gcrypt/gcrypt.h ++rm include/grub/gcrypt/g10lib.h ++rm -rf grub-core/lib/libgcrypt-grub/mpi/generic ++ln -s ../../../grub-core/lib/libgcrypt-grub/src/g10lib.h include/grub/gcrypt/g10lib.h ++cp -R grub-core/lib/libgcrypt/mpi/generic grub-core/lib/libgcrypt-grub/mpi/generic ++ ++for x in mpi-asm-defs.h mpih-add1.c mpih-sub1.c mpih-mul1.c mpih-mul2.c mpih-mul3.c mpih-lshift.c mpih-rshift.c; do ++ rm grub-core/lib/libgcrypt-grub/mpi/"$x" ++ ln -s generic/"$x" grub-core/lib/libgcrypt-grub/mpi/"$x" ++done + + echo "Creating Makefile.tpl..." + python gentpl.py | sed -e '/^$/{N;/^\n$/D;}' > Makefile.tpl +diff --git a/conf/Makefile.common b/conf/Makefile.common +index b5615a1..5b9cd92 100644 +--- a/conf/Makefile.common ++++ b/conf/Makefile.common +@@ -47,6 +47,8 @@ CPPFLAGS_DEFAULT += -I$(top_builddir) + CPPFLAGS_DEFAULT += -I$(top_srcdir) + CPPFLAGS_DEFAULT += -I$(top_srcdir)/include + CPPFLAGS_DEFAULT += -I$(top_builddir)/include ++CPPFLAGS_DEFAULT += -I$(top_srcdir)/grub-core/lib/libgcrypt-grub/include ++CPPFLAGS_DEFAULT += -I$(top_srcdir)/grub-core/lib/libgcrypt-grub/src/ + CCASFLAGS_DEFAULT = -DASM_FILE=1 + + LDADD_KERNEL = +@@ -102,15 +104,15 @@ grubconfdir = $(sysconfdir)/grub.d + platformdir = $(pkglibdir)/$(target_cpu)-$(platform) + starfielddir = $(pkgdatadir)/themes/starfield + +-CFLAGS_GCRY = -Wno-error -Wno-missing-field-initializers +-CPPFLAGS_GCRY = -I$(top_srcdir)/grub-core/lib/libgcrypt_wrap +- + CFLAGS_GNULIB = -Wno-undef -Wno-sign-compare -Wno-unused -Wno-unused-parameter -Wno-redundant-decls -Wno-unreachable-code -Wno-conversion -Wno-old-style-definition -Wno-unsafe-loop-optimizations + CPPFLAGS_GNULIB = -I$(top_builddir)/grub-core/gnulib -I$(top_srcdir)/grub-core/gnulib + + CFLAGS_POSIX = -fno-builtin + CPPFLAGS_POSIX = -I$(top_srcdir)/grub-core/lib/posix_wrap + ++CFLAGS_GCRY = -Wno-error -Wno-missing-field-initializers $(CFLAGS_POSIX) ++CPPFLAGS_GCRY = -I$(top_srcdir)/grub-core/lib/libgcrypt_wrap $(CPPFLAGS_POSIX) -D_GCRYPT_IN_LIBGCRYPT=1 -I$(top_srcdir)/include/grub/gcrypt ++ + CPPFLAGS_EFIEMU = -I$(top_srcdir)/grub-core/efiemu/runtime + + # List file macros for recognizing /interesting/ modules +diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def +index 6752429..588e4cd 100644 +--- a/grub-core/Makefile.core.def ++++ b/grub-core/Makefile.core.def +@@ -687,6 +687,13 @@ module = { + }; + + module = { ++ name = verify; ++ common = commands/verify.c; ++ cflags = '$(CFLAGS_POSIX)'; ++ cppflags = '-I$(srcdir)/lib/posix_wrap'; ++}; ++ ++module = { + name = hdparm; + common = commands/hdparm.c; + common = lib/hexdump.c; +@@ -1845,6 +1852,35 @@ module = { + }; + + module = { ++ name = mpi; ++ common = lib/libgcrypt-grub/mpi/mpiutil.c; ++ common = lib/libgcrypt-grub/mpi/mpi-bit.c; ++ common = lib/libgcrypt-grub/mpi/mpi-add.c; ++ common = lib/libgcrypt-grub/mpi/mpi-mul.c; ++ common = lib/libgcrypt-grub/mpi/mpi-mod.c; ++ common = lib/libgcrypt-grub/mpi/mpi-gcd.c; ++ common = lib/libgcrypt-grub/mpi/mpi-div.c; ++ common = lib/libgcrypt-grub/mpi/mpi-cmp.c; ++ common = lib/libgcrypt-grub/mpi/mpi-inv.c; ++ common = lib/libgcrypt-grub/mpi/mpi-pow.c; ++ common = lib/libgcrypt-grub/mpi/mpi-mpow.c; ++ common = lib/libgcrypt-grub/mpi/mpih-lshift.c; ++ common = lib/libgcrypt-grub/mpi/mpih-mul.c; ++ common = lib/libgcrypt-grub/mpi/mpih-mul1.c; ++ common = lib/libgcrypt-grub/mpi/mpih-mul2.c; ++ common = lib/libgcrypt-grub/mpi/mpih-mul3.c; ++ common = lib/libgcrypt-grub/mpi/mpih-add1.c; ++ common = lib/libgcrypt-grub/mpi/mpih-sub1.c; ++ common = lib/libgcrypt-grub/mpi/mpih-div.c; ++ common = lib/libgcrypt-grub/mpi/mpicoder.c; ++ common = lib/libgcrypt-grub/mpi/mpih-rshift.c; ++ common = lib/libgcrypt_wrap/mem.c; ++ ++ cflags = '$(CFLAGS_GCRY) -Wno-redundant-decls -Wno-sign-compare'; ++ cppflags = '$(CPPFLAGS_GCRY)'; ++}; ++ ++module = { + name = all_video; + common = lib/fake_module.c; + }; +diff --git a/grub-core/commands/hashsum.c b/grub-core/commands/hashsum.c +index ba33ea2..396a427 100644 +--- a/grub-core/commands/hashsum.c ++++ b/grub-core/commands/hashsum.c +@@ -63,7 +63,7 @@ hextoval (char c) + static grub_err_t + hash_file (grub_file_t file, const gcry_md_spec_t *hash, void *result) + { +- grub_uint8_t context[hash->contextsize]; ++ GRUB_PROPERLY_ALIGNED_ARRAY (context, hash->contextsize); + grub_uint8_t readbuf[4096]; + + grub_memset (context, 0, sizeof (context)); +diff --git a/grub-core/commands/verify.c b/grub-core/commands/verify.c +new file mode 100644 +index 0000000..415e4bf +--- /dev/null ++++ b/grub-core/commands/verify.c +@@ -0,0 +1,763 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2011 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 ++ ++GRUB_MOD_LICENSE ("GPLv3+"); ++ ++static grub_err_t ++read_packet_header (grub_file_t sig, grub_uint8_t *out_type, grub_size_t *len) ++{ ++ grub_uint8_t type; ++ grub_uint8_t l; ++ grub_uint16_t l16; ++ grub_uint32_t l32; ++ ++ /* New format. */ ++ switch (grub_file_read (sig, &type, sizeof (type))) ++ { ++ case 1: ++ break; ++ case 0: ++ { ++ *out_type = 0xff; ++ return 0; ++ } ++ default: ++ if (grub_errno) ++ return grub_errno; ++ return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ } ++ ++ if (type == 0) ++ { ++ *out_type = 0xfe; ++ return 0; ++ } ++ ++ if (!(type & 0x80)) ++ return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ if (type & 0x40) ++ { ++ *out_type = (type & 0x3f); ++ if (grub_file_read (sig, &l, sizeof (l)) != 1) ++ return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ if (l < 192) ++ { ++ *len = l; ++ return 0; ++ } ++ if (l < 224) ++ { ++ *len = (l - 192) << 8; ++ if (grub_file_read (sig, &l, sizeof (l)) != 1) ++ return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ *len |= l; ++ return 0; ++ } ++ if (l == 255) ++ { ++ if (grub_file_read (sig, &l32, sizeof (l32)) != sizeof (l32)) ++ return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ *len = grub_be_to_cpu32 (l32); ++ return 0; ++ } ++ return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ } ++ *out_type = ((type >> 2) & 0xf); ++ switch (type & 0x3) ++ { ++ case 0: ++ if (grub_file_read (sig, &l, sizeof (l)) != sizeof (l)) ++ return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ *len = l; ++ return 0; ++ case 1: ++ if (grub_file_read (sig, &l16, sizeof (l16)) != sizeof (l16)) ++ return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ *len = grub_be_to_cpu16 (l16); ++ return 0; ++ case 2: ++ if (grub_file_read (sig, &l32, sizeof (l32)) != sizeof (l32)) ++ return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ *len = grub_be_to_cpu32 (l32); ++ return 0; ++ } ++ return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++} ++ ++struct signature_v4_header ++{ ++ grub_uint8_t type; ++ grub_uint8_t pkeyalgo; ++ grub_uint8_t hash; ++ grub_uint16_t hashed_sub; ++} __attribute__ ((packed)); ++ ++const char *hashes[] = { ++ "md5", "sha1", "ripemd160", ++ [0x0a] = "sha512" ++}; ++ ++struct ++{ ++ const char *name; ++ grub_size_t nmpisig; ++ grub_size_t nmpipub; ++} pkalgos[] = ++ { ++ [1] = { "rsa", 1, 2 }, ++ [3] = { "rsa", 1, 2 }, ++ [17] = { "dsa", 2, 4 }, ++ }; ++ ++struct grub_public_key ++{ ++ struct grub_public_key *next; ++ struct grub_public_subkey *subkeys; ++}; ++ ++struct grub_public_subkey ++{ ++ struct grub_public_subkey *next; ++ grub_uint8_t type; ++ grub_uint32_t fingerprint[5]; ++ gcry_mpi_t mpis[10]; ++}; ++ ++static void ++free_pk (struct grub_public_key *pk) ++{ ++ struct grub_public_subkey *nsk, *sk; ++ for (sk = pk->subkeys; sk; sk = nsk) ++ { ++ nsk = sk->next; ++ grub_free (sk); ++ } ++ grub_free (pk); ++} ++ ++struct grub_public_key * ++grub_load_public_key (grub_file_t f) ++{ ++ grub_err_t err; ++ struct grub_public_key *ret; ++ struct grub_public_subkey **last = 0; ++ ++ ret = grub_zalloc (sizeof (*ret)); ++ if (!ret) ++ return NULL; ++ ++ last = &ret->subkeys; ++ ++ while (1) ++ { ++ grub_uint8_t type; ++ grub_size_t len; ++ grub_uint8_t v, pk; ++ grub_uint32_t creation_time; ++ grub_off_t pend; ++ struct grub_public_subkey *sk; ++ grub_size_t i; ++ grub_uint16_t len_be; ++ GRUB_PROPERLY_ALIGNED_ARRAY (fingerprint_context, GRUB_MD_SHA1->contextsize); ++ ++ err = read_packet_header (f, &type, &len); ++ ++ if (err) ++ goto fail; ++ if (type == 0xfe) ++ continue; ++ if (type == 0xff) ++ return ret; ++ ++ grub_dprintf ("crypt", "len = %x\n", (int) len); ++ ++ pend = grub_file_tell (f) + len; ++ if (type != 6 && type != 14 ++ && type != 5 && type != 7) ++ { ++ grub_file_seek (f, pend); ++ continue; ++ } ++ ++ if (grub_file_read (f, &v, sizeof (v)) != sizeof (v)) ++ { ++ grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ goto fail; ++ } ++ ++ grub_dprintf ("crypt", "v = %x\n", v); ++ ++ if (v != 4) ++ { ++ grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ goto fail; ++ } ++ if (grub_file_read (f, &creation_time, sizeof (creation_time)) != sizeof (creation_time)) ++ { ++ grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ goto fail; ++ } ++ ++ grub_dprintf ("crypt", "time = %x\n", creation_time); ++ ++ if (grub_file_read (f, &pk, sizeof (pk)) != sizeof (pk)) ++ { ++ grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ goto fail; ++ } ++ ++ grub_dprintf ("crypt", "pk = %x\n", pk); ++ ++ if (pk >= ARRAY_SIZE (pkalgos) || pkalgos[pk].name == NULL) ++ { ++ grub_file_seek (f, pend); ++ continue; ++ } ++ ++ sk = grub_zalloc (sizeof (struct grub_public_subkey)); ++ if (!sk) ++ goto fail; ++ ++ grub_memset (fingerprint_context, 0, sizeof (fingerprint_context)); ++ GRUB_MD_SHA1->init (fingerprint_context); ++ GRUB_MD_SHA1->write (fingerprint_context, "\x99", 1); ++ len_be = grub_cpu_to_be16 (len); ++ GRUB_MD_SHA1->write (fingerprint_context, &len_be, sizeof (len_be)); ++ GRUB_MD_SHA1->write (fingerprint_context, &v, sizeof (v)); ++ GRUB_MD_SHA1->write (fingerprint_context, &creation_time, sizeof (creation_time)); ++ GRUB_MD_SHA1->write (fingerprint_context, &pk, sizeof (pk)); ++ ++ for (i = 0; i < pkalgos[pk].nmpipub; i++) ++ { ++ grub_uint16_t l; ++ grub_size_t lb; ++ grub_uint8_t buffer[4096]; ++ if (grub_file_read (f, &l, sizeof (l)) != sizeof (l)) ++ { ++ grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ goto fail; ++ } ++ ++ lb = (grub_be_to_cpu16 (l) + 7) / 8; ++ if (lb > sizeof (buffer) - sizeof (grub_uint16_t)) ++ { ++ grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ goto fail; ++ } ++ if (grub_file_read (f, buffer + sizeof (grub_uint16_t), lb) != (grub_ssize_t) lb) ++ { ++ grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ goto fail; ++ } ++ grub_memcpy (buffer, &l, sizeof (l)); ++ ++ GRUB_MD_SHA1->write (fingerprint_context, buffer, lb + sizeof (grub_uint16_t)); ++ ++ if (gcry_mpi_scan (&sk->mpis[i], GCRYMPI_FMT_PGP, ++ buffer, lb + sizeof (grub_uint16_t), 0)) ++ { ++ grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ goto fail; ++ } ++ } ++ ++ GRUB_MD_SHA1->final (fingerprint_context); ++ ++ grub_memcpy (sk->fingerprint, GRUB_MD_SHA1->read (fingerprint_context), 20); ++ ++ *last = sk; ++ last = &sk->next; ++ ++ for (i = 0; i < 20; i += 2) ++ grub_printf ("%02x%02x ", ((grub_uint8_t *) sk->fingerprint)[i], ((grub_uint8_t *) sk->fingerprint)[i + 1]); ++ grub_printf ("\n"); ++ ++ grub_dprintf ("crypt", "actual pos: %x, expected: %x\n", (int)grub_file_tell (f), (int)pend); ++ ++ grub_file_seek (f, pend); ++ } ++ fail: ++ free_pk (ret); ++ return NULL; ++} ++ ++struct grub_public_key *grub_pk_trusted; ++ ++struct grub_public_subkey * ++grub_crypto_pk_locate_subkey (grub_uint64_t keyid, struct grub_public_key *pkey) ++{ ++ struct grub_public_subkey *sk; ++ for (sk = pkey->subkeys; sk; sk = sk->next) ++ if (grub_memcmp (sk->fingerprint + 3, &keyid, 8) == 0) ++ return sk; ++ return 0; ++} ++ ++struct grub_public_subkey * ++grub_crypto_pk_locate_subkey_in_trustdb (grub_uint64_t keyid) ++{ ++ struct grub_public_key *pkey; ++ struct grub_public_subkey *sk; ++ for (pkey = grub_pk_trusted; pkey; pkey = pkey->next) ++ { ++ sk = grub_crypto_pk_locate_subkey (keyid, pkey); ++ if (sk) ++ return sk; ++ } ++ return 0; ++} ++ ++grub_err_t ++grub_verify_signature (grub_file_t f, grub_file_t sig, ++ struct grub_public_key *pkey) ++{ ++ grub_size_t len; ++ grub_uint8_t v; ++ grub_uint8_t h; ++ grub_uint8_t t; ++ grub_uint8_t pk; ++ const gcry_md_spec_t *hash; ++ struct signature_v4_header v4; ++ grub_err_t err; ++ grub_size_t i; ++ gcry_mpi_t mpis[10]; ++ grub_uint8_t type; ++ ++ err = read_packet_header (sig, &type, &len); ++ if (err) ++ return err; ++ ++ if (type != 0x2) ++ return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ ++ if (grub_file_read (sig, &v, sizeof (v)) != sizeof (v)) ++ return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ ++ if (v != 4) ++ return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ ++ if (grub_file_read (sig, &v4, sizeof (v4)) != sizeof (v4)) ++ return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ ++ h = v4.hash; ++ t = v4.type; ++ pk = v4.pkeyalgo; ++ ++ if (t != 0) ++ return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ ++ if (h >= ARRAY_SIZE (hashes) || hashes[h] == NULL) ++ return grub_error (GRUB_ERR_BAD_SIGNATURE, "unknown hash"); ++ ++ if (pk >= ARRAY_SIZE (pkalgos) || pkalgos[pk].name == NULL) ++ return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ ++ hash = grub_crypto_lookup_md_by_name (hashes[h]); ++ if (!hash) ++ return grub_error (GRUB_ERR_BAD_SIGNATURE, "hash `%s' not loaded", hashes[h]); ++ ++ grub_dprintf ("crypt", "alive\n"); ++ ++ { ++ GRUB_PROPERLY_ALIGNED_ARRAY (context, hash->contextsize); ++ unsigned char *hval; ++ grub_ssize_t rem = grub_be_to_cpu16 (v4.hashed_sub); ++ grub_uint32_t headlen = grub_cpu_to_be32 (rem + 6); ++ grub_uint8_t s; ++ grub_uint16_t unhashed_sub; ++ grub_ssize_t r; ++ grub_uint8_t hash_start[2]; ++ gcry_mpi_t hmpi; ++ grub_uint64_t keyid = 0; ++ struct grub_public_subkey *sk; ++ ++ grub_memset (context, 0, sizeof (context)); ++ hash->init (context); ++ while (1) ++ { ++ grub_uint8_t readbuf[4096]; ++ r = grub_file_read (f, readbuf, sizeof (readbuf)); ++ if (r < 0) ++ return grub_errno; ++ if (r == 0) ++ break; ++ hash->write (context, readbuf, r); ++ } ++ ++ hash->write (context, &v, sizeof (v)); ++ hash->write (context, &v4, sizeof (v4)); ++ while (rem) ++ { ++ grub_uint8_t readbuf[4096]; ++ r = grub_file_read (sig, readbuf, rem < (grub_ssize_t) sizeof (readbuf) ? rem : (grub_ssize_t) sizeof (readbuf)); ++ if (r < 0) ++ return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ if (r == 0) ++ break; ++ hash->write (context, readbuf, r); ++ rem -= r; ++ } ++ hash->write (context, &v, sizeof (v)); ++ s = 0xff; ++ hash->write (context, &s, sizeof (s)); ++ hash->write (context, &headlen, sizeof (headlen)); ++ r = grub_file_read (sig, &unhashed_sub, sizeof (unhashed_sub)); ++ if (r != sizeof (unhashed_sub)) ++ return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ { ++ grub_uint8_t readbuf[4096]; ++ grub_uint8_t *ptr; ++ grub_uint32_t l; ++ rem = grub_be_to_cpu16 (unhashed_sub); ++ if (rem > (int) sizeof (readbuf)) ++ return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ r = grub_file_read (sig, readbuf, rem); ++ if (r != rem) ++ return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ for (ptr = readbuf; ptr < readbuf + rem; ptr += l) ++ { ++ if (*ptr < 192) ++ l = *ptr++; ++ else if (*ptr < 255) ++ { ++ if (ptr + 1 >= readbuf + rem) ++ break; ++ l = (((ptr[0] & ~192) << 8) | ptr[1]) + 192; ++ ptr += 2; ++ } ++ else ++ { ++ if (ptr + 5 >= readbuf + rem) ++ break; ++ l = grub_be_to_cpu32 (grub_get_unaligned32 (ptr + 1)); ++ ptr += 5; ++ } ++ if (*ptr == 0x10 && l >= 8) ++ keyid = grub_get_unaligned64 (ptr + 1); ++ } ++ } ++ ++ hash->final (context); ++ ++ grub_dprintf ("crypt", "alive\n"); ++ ++ hval = hash->read (context); ++ ++ if (grub_file_read (sig, hash_start, sizeof (hash_start)) != sizeof (hash_start)) ++ return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ if (grub_memcmp (hval, hash_start, sizeof (hash_start)) != 0) ++ return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ ++ grub_dprintf ("crypt", "@ %x\n", (int)grub_file_tell (sig)); ++ ++ for (i = 0; i < pkalgos[pk].nmpisig; i++) ++ { ++ grub_uint16_t l; ++ grub_size_t lb; ++ grub_uint8_t buffer[4096]; ++ grub_dprintf ("crypt", "alive\n"); ++ if (grub_file_read (sig, &l, sizeof (l)) != sizeof (l)) ++ return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ grub_dprintf ("crypt", "alive\n"); ++ lb = (grub_be_to_cpu16 (l) + 7) / 8; ++ grub_dprintf ("crypt", "l = 0x%04x\n", grub_be_to_cpu16 (l)); ++ if (lb > sizeof (buffer) - sizeof (grub_uint16_t)) ++ return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ grub_dprintf ("crypt", "alive\n"); ++ if (grub_file_read (sig, buffer + sizeof (grub_uint16_t), lb) != (grub_ssize_t) lb) ++ return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ grub_dprintf ("crypt", "alive\n"); ++ grub_memcpy (buffer, &l, sizeof (l)); ++ grub_dprintf ("crypt", "alive\n"); ++ ++ if (gcry_mpi_scan (&mpis[i], GCRYMPI_FMT_PGP, ++ buffer, lb + sizeof (grub_uint16_t), 0)) ++ return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ grub_dprintf ("crypt", "alive\n"); ++ } ++ ++ if (pkey) ++ sk = grub_crypto_pk_locate_subkey (keyid, pkey); ++ else ++ sk = grub_crypto_pk_locate_subkey_in_trustdb (keyid); ++ if (!sk) ++ return grub_error (GRUB_ERR_BAD_SIGNATURE, "key not found"); ++ ++ int nbits = gcry_mpi_get_nbits (sk->mpis[1]); ++ grub_dprintf ("crypt", "must be %d bits got %d bits\n", (int)nbits, (int)(8 * hash->mdlen)); ++ ++ if (gcry_mpi_scan (&hmpi, GCRYMPI_FMT_USG, hval, nbits / 8 < (int) hash->mdlen ? nbits / 8 : (int) hash->mdlen, 0)) ++ return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ if (!grub_crypto_pk_dsa) ++ return grub_error (GRUB_ERR_BAD_SIGNATURE, "DSA module is not loaded"); ++ if (grub_crypto_pk_dsa->verify (0, hmpi, mpis, sk->mpis, 0, 0)) ++ return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ } ++ ++ return GRUB_ERR_NONE; ++} ++ ++static grub_err_t ++grub_cmd_trust (grub_command_t cmd __attribute__ ((unused)), ++ int argc, char **args) ++{ ++ grub_file_t pkf; ++ struct grub_public_key *pk = NULL; ++ ++ if (argc < 1) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, "one argument required"); ++ ++ grub_file_filter_disable_all (); ++ pkf = grub_file_open (args[0]); ++ if (!pkf) ++ return grub_errno; ++ pk = grub_load_public_key (pkf); ++ if (!pk) ++ { ++ grub_file_close (pkf); ++ return grub_errno; ++ } ++ grub_file_close (pkf); ++ ++ pk->next = grub_pk_trusted; ++ grub_pk_trusted = pk; ++ ++ return GRUB_ERR_NONE; ++} ++ ++static grub_err_t ++grub_cmd_distrust (grub_command_t cmd __attribute__ ((unused)), ++ int argc, char **args) ++{ ++ grub_uint32_t keyid, keyid_be; ++ struct grub_public_key **pkey; ++ struct grub_public_subkey *sk; ++ ++ if (argc < 1) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, "one argument required"); ++ keyid = grub_strtoull (args[0], 0, 16); ++ if (grub_errno) ++ return grub_errno; ++ keyid_be = grub_cpu_to_be32 (keyid); ++ ++ for (pkey = &grub_pk_trusted; *pkey; pkey = &((*pkey)->next)) ++ { ++ struct grub_public_key *next; ++ for (sk = (*pkey)->subkeys; sk; sk = sk->next) ++ if (grub_memcmp (sk->fingerprint + 4, &keyid_be, 4) == 0) ++ break; ++ if (!sk) ++ continue; ++ next = (*pkey)->next; ++ free_pk (*pkey); ++ *pkey = next; ++ return GRUB_ERR_NONE; ++ } ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, "key %08x not found", keyid); ++} ++ ++static grub_err_t ++grub_cmd_verify_signature (grub_command_t cmd __attribute__ ((unused)), ++ int argc, char **args) ++{ ++ grub_file_t f, sig; ++ grub_err_t err; ++ struct grub_public_key *pk = NULL; ++ ++ grub_dprintf ("crypt", "alive\n"); ++ ++ if (argc < 2) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, "two arguments required"); ++ ++ grub_dprintf ("crypt", "alive\n"); ++ ++ if (argc > 2) ++ { ++ grub_file_t pkf; ++ grub_file_filter_disable_all (); ++ pkf = grub_file_open (args[2]); ++ if (!pkf) ++ return grub_errno; ++ pk = grub_load_public_key (pkf); ++ if (!pk) ++ { ++ grub_file_close (pkf); ++ return grub_errno; ++ } ++ grub_file_close (pkf); ++ } ++ ++ grub_file_filter_disable_all (); ++ f = grub_file_open (args[0]); ++ if (!f) ++ return grub_errno; ++ ++ grub_file_filter_disable_all (); ++ sig = grub_file_open (args[1]); ++ if (!sig) ++ { ++ grub_file_close (f); ++ return grub_errno; ++ } ++ ++ err = grub_verify_signature (f, sig, pk); ++ grub_file_close (f); ++ grub_file_close (sig); ++ return err; ++} ++ ++static int sec = 0; ++ ++static grub_file_t ++grub_pubkey_open (grub_file_t io, const char *filename) ++{ ++ grub_file_t sig; ++ char *fsuf, *ptr; ++ grub_err_t err; ++ grub_file_filter_t curfilt[GRUB_FILE_FILTER_MAX]; ++ ++ if (!sec) ++ return io; ++ fsuf = grub_malloc (grub_strlen (filename) + sizeof (".sig")); ++ if (!fsuf) ++ return NULL; ++ ptr = grub_stpcpy (fsuf, filename); ++ grub_memcpy (ptr, ".sig", sizeof (".sig")); ++ ++ grub_memcpy (curfilt, grub_file_filters_enabled, ++ sizeof (curfilt)); ++ grub_file_filter_disable_all (); ++ sig = grub_file_open (fsuf); ++ grub_memcpy (grub_file_filters_enabled, curfilt, ++ sizeof (curfilt)); ++ grub_free (fsuf); ++ if (!sig) ++ return NULL; ++ ++ err = grub_verify_signature (io, sig, NULL); ++ grub_file_close (sig); ++ if (err) ++ return NULL; ++ grub_file_seek (io, 0); ++ return io; ++} ++ ++static char * ++grub_env_write_sec (struct grub_env_var *var __attribute__ ((unused)), ++ const char *val) ++{ ++ sec = (*val == '1') || (*val == 'e'); ++ return grub_strdup (sec ? "enforce" : "no"); ++} ++ ++static grub_ssize_t ++pseudo_read (struct grub_file *file, char *buf, grub_size_t len) ++{ ++ grub_memcpy (buf, (grub_uint8_t *) file->data + file->offset, len); ++ return len; ++} ++ ++ ++/* Filesystem descriptor. */ ++struct grub_fs pseudo_fs = ++ { ++ .name = "pseudo", ++ .read = pseudo_read ++}; ++ ++struct gcry_pk_spec *grub_crypto_pk_dsa; ++struct gcry_pk_spec *grub_crypto_pk_ecdsa; ++struct gcry_pk_spec *grub_crypto_pk_rsa; ++ ++static grub_command_t cmd, cmd_trust, cmd_distrust; ++ ++GRUB_MOD_INIT(verify) ++{ ++ const char *val; ++ struct grub_module_header *header; ++ ++ val = grub_env_get ("check_signatures"); ++ if (val && (val[0] == '1' || val[0] == 'e')) ++ sec = 1; ++ else ++ sec = 0; ++ ++ grub_file_filter_register (GRUB_FILE_FILTER_PUBKEY, grub_pubkey_open); ++ ++ grub_register_variable_hook ("check_signatures", 0, grub_env_write_sec); ++ grub_env_export ("check_signatures"); ++ ++ grub_pk_trusted = 0; ++ FOR_MODULES (header) ++ { ++ struct grub_file pseudo_file; ++ struct grub_public_key *pk = NULL; ++ ++ grub_memset (&pseudo_file, 0, sizeof (pseudo_file)); ++ ++ /* Not an ELF module, skip. */ ++ if (header->type != OBJ_TYPE_PUBKEY) ++ continue; ++ ++ pseudo_file.fs = &pseudo_fs; ++ pseudo_file.size = (header->size - sizeof (struct grub_module_header)); ++ pseudo_file.data = (char *) header + sizeof (struct grub_module_header); ++ ++ pk = grub_load_public_key (&pseudo_file); ++ if (!pk) ++ grub_fatal ("error loading initial key: %s\n", grub_errmsg); ++ ++ pk->next = grub_pk_trusted; ++ grub_pk_trusted = pk; ++ } ++ ++ if (!val) ++ grub_env_set ("check_signatures", grub_pk_trusted ? "enforce" : "no"); ++ ++ cmd = grub_register_command ("verify_detached", grub_cmd_verify_signature, ++ "FILE SIGFILE [PKFILE]", ++ N_("Verify detached signature.")); ++ cmd_trust = grub_register_command ("trust", grub_cmd_trust, ++ "PKFILE", ++ N_("Add PKFILE to trusted keys.")); ++ cmd_distrust = grub_register_command ("distrust", grub_cmd_distrust, ++ "KEYID", ++ N_("Remove KEYID from trusted keys.")); ++} ++ ++GRUB_MOD_FINI(verify) ++{ ++ grub_file_filter_unregister (GRUB_FILE_FILTER_PUBKEY); ++ grub_unregister_command (cmd); ++ grub_unregister_command (cmd_trust); ++ grub_unregister_command (cmd_distrust); ++} +diff --git a/grub-core/io/gzio.c b/grub-core/io/gzio.c +index 59f2206..ef5872a 100644 +--- a/grub-core/io/gzio.c ++++ b/grub-core/io/gzio.c +@@ -1125,7 +1125,7 @@ initialize_tables (grub_gzio_t gzio) + even if IO does not contain data compressed by gzip, return a valid file + object. Note that this function won't close IO, even if an error occurs. */ + static grub_file_t +-grub_gzio_open (grub_file_t io) ++grub_gzio_open (grub_file_t io, const char *name __attribute__ ((unused))) + { + grub_file_t file; + grub_gzio_t gzio = 0; +diff --git a/grub-core/io/lzopio.c b/grub-core/io/lzopio.c +index 7fdb6d4..63bfbad 100644 +--- a/grub-core/io/lzopio.c ++++ b/grub-core/io/lzopio.c +@@ -409,7 +409,8 @@ CORRUPTED: + } + + static grub_file_t +-grub_lzopio_open (grub_file_t io) ++grub_lzopio_open (grub_file_t io, ++ const char *name __attribute__ ((unused))) + { + grub_file_t file; + grub_lzopio_t lzopio; +diff --git a/grub-core/io/xzio.c b/grub-core/io/xzio.c +index 27657d8..bcce242 100644 +--- a/grub-core/io/xzio.c ++++ b/grub-core/io/xzio.c +@@ -169,7 +169,8 @@ ERROR: + } + + static grub_file_t +-grub_xzio_open (grub_file_t io) ++grub_xzio_open (grub_file_t io, ++ const char *name __attribute__ ((unused))) + { + grub_file_t file; + grub_xzio_t xzio; +diff --git a/grub-core/kern/file.c b/grub-core/kern/file.c +index 495326f..d2a6317 100644 +--- a/grub-core/kern/file.c ++++ b/grub-core/kern/file.c +@@ -107,7 +107,7 @@ grub_file_open (const char *name) + if (grub_file_filters_enabled[filter]) + { + last_file = file; +- file = grub_file_filters_enabled[filter] (file); ++ file = grub_file_filters_enabled[filter] (file, name); + } + if (!file) + grub_file_close (last_file); +diff --git a/grub-core/lib/crypto.c b/grub-core/lib/crypto.c +index f4b13ed..dce5eda 100644 +--- a/grub-core/lib/crypto.c ++++ b/grub-core/lib/crypto.c +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include + + #ifdef GRUB_UTIL + #include +@@ -56,6 +57,38 @@ grub_burn_stack (grub_size_t size) + grub_burn_stack (size - sizeof (buf)); + } + ++void ++_gcry_burn_stack (int size) ++{ ++ grub_burn_stack (size); ++} ++ ++void __attribute__ ((noreturn)) ++_gcry_assert_failed (const char *expr, const char *file, int line, ++ const char *func) ++ ++{ ++ grub_fatal ("assertion %s at %s:%d (%s) failed\n", expr, file, line, func); ++} ++ ++ ++void _gcry_log_error (const char *fmt, ...) ++{ ++ va_list args; ++ const char *debug = grub_env_get ("debug"); ++ ++ if (! debug) ++ return; ++ ++ if (grub_strword (debug, "all") || grub_strword (debug, "gcrypt")) ++ { ++ grub_printf ("gcrypt error: "); ++ va_start (args, fmt); ++ grub_vprintf (fmt, args); ++ va_end (args); ++ grub_refresh (); ++ } ++} + + void + grub_cipher_register (gcry_cipher_spec_t *cipher) +@@ -477,3 +510,4 @@ grub_password_get (char buf[], unsigned buf_size) + return (key != '\e'); + #endif + } ++ +diff --git a/grub-core/lib/libgcrypt/cipher/ChangeLog b/grub-core/lib/libgcrypt/cipher/ChangeLog +index 8924f17..1b3694f 100644 +--- a/grub-core/lib/libgcrypt/cipher/ChangeLog ++++ b/grub-core/lib/libgcrypt/cipher/ChangeLog +@@ -1,3 +1,93 @@ ++2010-08-19 Werner Koch ++ ++ * cipher.c (gcry_cipher_open): Remove double release of the module. ++ Fixes bug#1263. ++ ++2010-06-10 Jeff Johnson (wk) ++ ++ * ecc.c (ecc_generate_ext): Parse transient-key flag. ++ (generate_key): Add arg TRANSIENT_KEY and use it to set the random ++ level. ++ ++2010-04-12 Brad Hards (wk) ++ ++ Spelling fixes. ++ ++2010-03-26 Werner Koch ++ ++ * tiger.c (asn): Unfetter the old TIGER from an OID. ++ (TIGER_CONTEXT): Add field VARIANT. ++ (tiger_init): Factor code out to ... ++ (do_init): New. ++ (tiger1_init, tiger2_init): New. ++ (_gcry_digest_spec_tiger1, _gcry_digest_spec_tiger2): New. ++ * md.c (digest_table): Add TIGER1 and TIGER2 variants. ++ ++2009-12-11 Werner Koch ++ ++ * sha256.c (Cho, Maj, Sum0, Sum1): Turn macros into inline ++ functions. ++ (transform): Partly unroll to interweave the chain variables ++ ++ * sha512.c (ROTR, Ch, Maj, Sum0, Sum1): Turn macros into inline ++ functions. ++ (transform): Partly unroll to interweave the chain variables. ++ Suggested by Christian Grothoff. ++ ++2009-12-10 Werner Koch ++ ++ * Makefile.am (o_flag_munging): New. ++ (tiger.o, tiger.lo): Use it. ++ ++ * cipher.c (do_ctr_encrypt): Add arg OUTBUFLEN. Check for ++ suitable value. Add check for valid inputlen. Wipe temporary ++ memory. ++ (do_ctr_decrypt): Likewise. ++ (do_cbc_encrypt, do_cbc_decrypt): Add arg OUTBUFLEN. Check for ++ suitable value. Move check for valid inputlen to here; change ++ returned error from INV_ARG to INV_LENGTH. ++ (do_ecb_encrypt, do_ecb_decrypt): Ditto. ++ (do_cfb_encrypt, do_cfb_decrypt): Ditto. ++ (do_ofb_encrypt, do_ofb_decrypt): Ditto. ++ (cipher_encrypt, cipher_encrypt): Adjust for above changes. ++ (gcry_cipher_encrypt, gcry_cipher_decrypt): Simplify. ++ ++2009-12-09 Werner Koch ++ ++ * cipher.c (gcry_cipher_open): Allow for GCRY_CIPHER_MODE_AESWRAP. ++ (cipher_encrypt, cipher_decrypt): Ditto. ++ (do_aeswrap_encrypt, do_aeswrap_decrypt): New. ++ (struct gcry_cipher_handle): Add field marks. ++ (cipher_setkey, cipher_setiv): Update marks flags. ++ (cipher_reset): Reset marks. ++ (cipher_encrypt, cipher_decrypt): Add new arg OUTBUFLEN. ++ (gcry_cipher_encrypt, gcry_cipher_decrypt): Pass outbuflen to ++ cipher_encrypt. Replace GPG_ERR_TOO_SHORT by ++ GPG_ERR_BUFFER_TOO_SHORT. ++ ++2009-08-21 Werner Koch ++ ++ * dsa.c (dsa_generate_ext): Release retfactors array before ++ setting it to NULL. Reported by Daiko Ueno. ++ ++2009-07-02 Werner Koch ++ ++ * md.c (md_read): Fix incomplete check for NULL. ++ Reported by Fabian Kail. ++ ++2009-03-31 Werner Koch ++ ++ * rsa.c (rsa_check_secret_key): Return GPG_ERR_BAD_SECKEY and not ++ GPG_ERR_PUBKEY_ALGO. ++ ++2009-02-16 Werner Koch ++ ++ * rsa.c (generate_x931): Do not initialize TBL with automatic ++ variables. ++ * whirlpool.c, tiger.c, sha256.c, sha1.c, rmd160.c, md5.c ++ * md4.c, crc.c: Remove memory.h. This is garbage from gnupg. ++ Reported by Dan Fandrich. ++ + 2009-01-22 Werner Koch + + * ecc.c (compute_keygrip): Remove superfluous const. +@@ -3888,8 +3978,8 @@ Mon Feb 16 10:08:47 1998 Werner Koch (wk@isil.d.shuttle.de) + (digest_algo_to_string): New. + + +- Copyright 1998,1999,2000,2001,2002,2003,2004,2005,2006 +- 2007, 2008, 2009 Free Software Foundation, Inc. ++ Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 ++ 2007, 2008, 2009, 2010 Free Software Foundation, Inc. + + This file is free software; as a special exception the author gives + unlimited permission to copy and/or distribute it, with or without +diff --git a/grub-core/lib/libgcrypt/cipher/Makefile.am b/grub-core/lib/libgcrypt/cipher/Makefile.am +new file mode 100644 +index 0000000..4470433 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/cipher/Makefile.am +@@ -0,0 +1,82 @@ ++# Makefile for cipher modules ++# Copyright (C) 1998, 1999, 2000, 2001, 2002, ++# 2003, 2009 Free Software Foundation, Inc. ++# ++# This file is part of Libgcrypt. ++# ++# Libgcrypt is free software; you can redistribute it and/or modify ++# it under the terms of the GNU Lesser General Public License as ++# published by the Free Software Foundation; either version 2.1 of ++# the License, or (at your option) any later version. ++# ++# Libgcrypt 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 Lesser General Public License for more details. ++# ++# You should have received a copy of the GNU Lesser General Public ++# License along with this program; if not, see . ++ ++# Process this file with automake to produce Makefile.in ++ ++EXTRA_DIST = Manifest ++ ++# Need to include ../src in addition to top_srcdir because gcrypt.h is ++# a built header. ++AM_CPPFLAGS = -I../src -I$(top_srcdir)/src ++AM_CFLAGS = $(GPG_ERROR_CFLAGS) ++ ++ ++noinst_LTLIBRARIES = libcipher.la ++ ++GCRYPT_MODULES = @GCRYPT_CIPHERS@ @GCRYPT_PUBKEY_CIPHERS@ @GCRYPT_DIGESTS@ ++ ++libcipher_la_DEPENDENCIES = $(GCRYPT_MODULES) ++libcipher_la_LIBADD = $(GCRYPT_MODULES) ++ ++libcipher_la_SOURCES = \ ++cipher.c pubkey.c ac.c md.c \ ++hmac-tests.c \ ++bithelp.h \ ++primegen.c \ ++hash-common.c hash-common.h \ ++rmd.h ++ ++EXTRA_libcipher_la_SOURCES = \ ++arcfour.c \ ++blowfish.c \ ++cast5.c \ ++crc.c \ ++des.c \ ++dsa.c \ ++elgamal.c \ ++ecc.c \ ++md4.c \ ++md5.c \ ++rijndael.c rijndael-tables.h \ ++rmd160.c \ ++rsa.c \ ++seed.c \ ++serpent.c \ ++sha1.c \ ++sha256.c \ ++sha512.c \ ++tiger.c \ ++whirlpool.c \ ++twofish.c \ ++rfc2268.c \ ++camellia.c camellia.h camellia-glue.c ++ ++if ENABLE_O_FLAG_MUNGING ++o_flag_munging = sed -e 's/-O[2-9s]*/-O1/g' ++else ++o_flag_munging = cat ++endif ++ ++ ++# We need to lower the optimization for this module. ++tiger.o: $(srcdir)/tiger.c ++ `echo $(COMPILE) -c $(srcdir)/tiger.c | $(o_flag_munging) ` ++ ++tiger.lo: $(srcdir)/tiger.c ++ `echo $(LTCOMPILE) -c $(srcdir)/tiger.c | $(o_flag_munging) ` +diff --git a/grub-core/lib/libgcrypt/cipher/Manifest b/grub-core/lib/libgcrypt/cipher/Manifest +new file mode 100644 +index 0000000..0cd64f7 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/cipher/Manifest +@@ -0,0 +1,73 @@ ++# Manifest - checksums of the cipher directory ++# Copyright 2003 Free Software Foundation, Inc. ++# ++# This file is part of Libgcrypt. ++# ++# Libgcrypt is free software; you can redistribute it and/or modify ++# it under the terms of the GNU Lesser general Public License as ++# published by the Free Software Foundation; either version 2.1 of ++# the License, or (at your option) any later version. ++# ++# Libgcrypt 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 Lesser General Public License for more details. ++# ++# You should have received a copy of the GNU Lesser General Public ++# License along with this program; if not, write to the Free Software ++# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ ++# Checksums for all source files in this directory. Format is ++# filename, blanks, base-64 part of an OpenPGP detached signature ++# without the header lines. Blank lines and lines beginning with a ++# hash mark are ignored. A tool to process this file is available by ++# cvs -d :pserver:anoncvs@cvs.gnupg.org:/cvs/wk co misc-scripts/manifest-tool ++# ++# The special entry "$names$" holds a signature over all sorted ++# filenames excluding itself. ++ ++ ++# Algorithm API ++cipher.c iQCVAwUAQDzrVjEAnp832S/7AQIPDgP+OVJ/YNWY5m7c09EBbPAzL/WsGoj6wrBNMmkRlMOqTHeh+OOtjuFHt1f9uhfM2Nzl7sJ5+h4ryZKLEZmQPRMTZTnAqkvGdsrJWJnigUA9QwYdV0ONqC9C63gpuG465gO9TZVOqlQu/FTxSRuTQYUulkaBNG71n8nZEOusBVwV2YA==58xH ++pubkey.c iQCVAwUAP9XQ3jEAnp832S/7AQJ5UgQAyHfEBvPVJ8wTRg8c7ixS2GiVmIgwIo5tvQaiQJTPWASevvYrB+2Z2qa9cATyu50ACjLzbaquGBgPzjJV3dU/qttT1gCqRuN/LCNvXFe5qnIZezejc3RAadFNTw/pOTHq0wxD1Keg66ruei9R36Nba59pEQIWIBXTfubRft2hMYk==E09t ++ac.c iQCVAwUAQDzsOzEAnp832S/7AQJCBQP/WI6EV/dsR4rmha6RVhvkjZo17kQ8z6pIl5J3cXOvqEkIFeD2HYu3HHrWST5l7yXlffhpDkVHkfMih4ruK76q6Fm0dxZ98pO4C/dVtgimlvvcy/wOQjpzsE0fYAe1BYdg81LJ09X33vW5x6C29lunfKROO2tPlV5i8ffeoFvmMF8==j26g ++md.c iQCVAwUAP+NFGjEAnp832S/7AQJs8wP/Qdk0EAKsyr3O1/pmOSN8AG4rPKbd6KDTzvoBPAN4upFwKYY4hWwvy12Q3YU9DmECrzZkRCXHR7mljVQKs6B7CRZJKjFKmOELpcJDtKvu40vTs1bOH4k9iJYZpGgRA83nkQ+ELAcphAbCA+KIpVr2K4mCJAB0FhpC2uOQ50JHAko==BeF6 ++primegen.c iQCVAwUAQDzsoDEAnp832S/7AQKYRwP/TqAQBm1rHTnF0HYE05PqXfWlOqa6EosqVpaOcs/OIW6PaqX0xH1UlrukK7jNOjK3xC4o1qNQ1UKzz2dvQaq1bMvNNizeavxAh10SJZc0hIc/ofc83IbjLh8SZVWQ67JxjsUd3DOXmSmhPZ+Pqd7cUIiw8fDoF+I9EZqy3COu1wY==1ebT ++ ++# Algorithm implementations ++arcfour.c iQCVAwUAP9XR/TEAnp832S/7AQJcRwP6AlvYEx++fpT4mIYo0xRDqKEQeqMQvbaRhIg2eV74JxItpHa3q5YsYIl+n1yUz5g35JRWWXSWmAZBwO5wLKsHii4kRUhgrKWnSoQZoPpl49L5+N3R58ON3S0ru5lsBiEJEze3xplf2vqwrH9v1QHVD+gU7UTlfNqrIJoOUXN+1O4==Tq+x ++blowfish.c iQCVAwUAP9XTETEAnp832S/7AQJaEgQAgiqqfuO+zQtscgTB0rvOzVymIKjRKjYhFuLjVuc79G4z1RCAffvIn/YM2d7kt+Z/QF7zjcTAOgETCQL1XokpX2zz9HPAMi2tlDY5zsDufTNqj0n4WBL9nM7w6XAvsiwP1B3bqCTv9SjJV4KbxJ58vw1yQE+sqW74R/QIHFvC7mU==wZnX ++cast5.c iQCVAwUAP9XT6DEAnp832S/7AQJ3xgP/ehLjEN3GELGudbqeo91Xd+PqitHrkuBbtRIYX7Udd/fyXLN+h8rMJVyIQX2m+mpxbBxudVU3x8/DNT8B0ZHAwK6qqJmEBLLhEYPgIuF76i9LMrP1KqUPhAwRZ2OppjIIugBQ+rP74aD4eLyd/aKQHNuXML8QGWR6KwQShohXM5I==/BRh ++crc.c iQCVAwUAP7ouejEAnp832S/7AQIgwQQApg5Nm63tH5DQkbN+zPzMO9Ygoj3ukxfFTyTBPYSXYKMiTjEbESegaU40uN8jnz2vprcIQWcgZfzO4+opEJMcI35aPwzEk0vKOp0S/PrBLUY2rJfnDVkX5XgJFZa2Q7LLe826UEBzTVYW924utiCCe8oOaOEWVNpg1mqdknu3M9o==kz5D ++des.c iQCVAwUAQCN2oDEAnp832S/7AQL/jwP6Auoq6nZCDBjpgc9tDzuIRwa9DqyuM3gX94uvgEpUwdHszb2bG43dz03kVmcYxtj1MzXbyCeCZOwox0b2SKmLgxIbrNP6yGbzVdTj6592gDYuf/ZXmc1ZNJ1DDldcPQ0n9fXUipUPwyPaNWo3mSZaNcMKSWWzdK0J6ciG6nk7SWI==9k/t ++dsa.c iQCVAwUAP9XZHDEAnp832S/7AQLBRgP/XrBzTEYx5ccMj1MMb6sg37liEHdIyyy49zjvt6jUqxj4RuwVEN8S6v3u4q/QyJkHAi1E0EkREgENlyHW6PKWhYbcrd0vPIAN15yjnl2yqtrCrJImexUCoqJJewK0E4JOicGbabTil8MZjk+mbhEPnjJBqOkyP1w0i31pEDgE/8M==pC8s ++elgamal.c iQCVAwUAP9XbYzEAnp832S/7AQLXagQA3HrvspZfbTGgmUH0IqLQTJ0exUPxJv5DET2TvoIy62trDmMN6lTAj5P+a7jQ8udcu0w+mR2vXUHcxUpNA2PxLaMwGzNSY4zRDNe9r3SFTDrFm6m4y9Ko2e8XtEA+WF6P/XLpck4Jn7vMEDmVGPwkNd22kXFFE8dBGwG6i5Hk1Mk==oBUs ++md4.c iQCVAwUAP9h50DEAnp832S/7AQJhHgQAzNA/B6MWFDlCtPkIVaW8RpP1Eg0ZNMsy0s7SJkopOCBlu6CwXUOKe+8ppcSxhjYKh4i4uQr/QtfipYlBjzKJGnrafoF/NugXNCOHSTGT11TvK7mCiBuUMVgvZGAlOJImk6eTTfUjRrMfaXM/SWl8bdJ4ZpzdjEyVh89r7I5JrGk==x2UD ++md5.c iQCVAwUAP9h7LzEAnp832S/7AQJUGQP/c0cbf6WZXCzmjufHxiE9FAQBzTsA0WtaNqdFcHl7fhmikGtknlaED8n5a7eYd/C481UQW6Wgq/oZdsvgoPWPhG3fOCy2CFP9cZVXITuMSf0ucyZTFUJNO15fnZ+nDfsUv+JPdv1aSeRinAUtfAcSKfkSyR9BCPZvkx+tgU6cphU==Zv+h ++rijndael.c iQCVAwUAP9h9cTEAnp832S/7AQKF1AP+P2L/tPqDJRDg+/fwbOk8Ts0MNxnvvYEm3gE73TKuLt1S+B2+jkrZcKNvM5VGPnVMJbnS0lmIK04nmedHCOftGTOwhGulZAHHIaKGystT3Jql4iPws/JMgAjE7Fyxh5WZMtB9yEljKBpJ5XNqhrMvvxcHpnyP3+YzIXNwzk34V+c==dJ5k ++rmd160.c iQCVAwUAP9h+bTEAnp832S/7AQK1OgP+PNKF6Nzi6X93easVlksdLqKEsArCAw2QjGWDGyxTnbiJM55qAl9JxR1mn3V+oOL7izLLwTt6EYK9evhzfcxY5N5Mni85RAcsLPsuAfQDEzjI6GUWHtQUKPbM+BaorzfhQjYFSZyvum/dZYJ/WfiwwwhqqIKyVU2ZFSqA38YGC/c==9jdA ++rsa.c iQCVAwUAP9iHIzEAnp832S/7AQKAYwQAuWtnMte54QHN+Hij9t4sGuypXogajOb1vQQwGgS0fKsaBZsuSP2amze4o5diIvsQTsFQ4CzjvqoCVuBDoHM3xkSD8wGDizgvtCamAxkdbF7wmzldKFn8SpJqlVwWQMP6kk1IjXHEuYb4IDWGTbVMhfEu+eOlU8+PSK4IhZqNvt4==/3hp ++serpent.c iQCVAwUAP9h/VzEAnp832S/7AQLyCwP/d1zbmb7l/PriZNa9/Z7mo01XFe5MnAqCfIwhl9GjeaMszcoS37jECNq5nLvrTTFIIJpm3rvBePwiCG4Wwx1I18HCxaP198pcSaR+BLOJ3Aj52EZPrxtqlDKuFr38ZOP5giyUqUYVYGVdrz4kRMNWAZQK53GeJnGhXCnhxojLEgA==ck46 ++sha1.c iQCVAwUAP9iATTEAnp832S/7AQKcSwQAwAs/HnNqho3lU1ZUgCPNt5P2/Brm6W21+wWWGKJkSrra/c4NYVKJGDDwlsFE0b9ln1uZt7bHReFkKXK3JnrKTmNVcx/Cy64iCMRNMhaM72Mqy7wWx5yHBAmMBxzFGnNQKbmeY52zeGih5HsNLSibc2pPuOViWo2JPJ5Ci/wIwl8==/wtO ++sha256.c iQCVAwUAP9iAtzEAnp832S/7AQJD2QP/UqvL0hhjG1wEFbGrdkV9tba1sMDXdnnK6X7HdLuRpVAgNiQiFf8JDmntd/dZ2Q71p4Uae2ctqve4WoEijPUZPjACnpuZfx0SEQL0lQBkwxzJp7lz9ujVtwQ2cM/aYexJkXcWgGcloJNLM3JbWPGIJnuYbr/IwJ6RQF9vgj0357o==UWO1 ++sha512.c iQCVAwUAP9iBTDEAnp832S/7AQIPBAQA28CJSUQLiW0s2x9u8/OH2eKnxPjA4sZmb50WP7920Lem66P31C3BrOqwfBot4RLhjL+zh/+Uc4s3HPwApZuj9E4BxNMlqLv+Tqk++DAbdaOeYT4jeUt+mlhQQ6mH/RDsy32rZsNsGQ2bUGxazZmfG++PL3JyhawqCy00SUDr/o0==H+0X ++tiger.c iQCVAwUAP9iCfjEAnp832S/7AQKufwP/fryv3MqSOYY+90325DH7X3/CtekxeooN0scGsHX0fxBakWSMecTNrj33KPddLS46gU/S89zIc2N/Bw/7EVIAXVFA3/3Ip+OrFOuIMO4Py1sCdB8o2Y+5ygv8iXLcsXIq1O0av79i9g774V3uaXa2qN9ZnXe0AEhcy8FHJ2i/wro==5XVB ++twofish.c iQCVAwUAP9iD6TEAnp832S/7AQKUnQP/Rq8FaYeHTG7HbZuqAs9pbPitzjDbkdZddmInWR7NmevBkKvhsJALjVooc0KGQfo2lAAmy3Xi/4QQN8VPn51DVjDIgf7x+DQh/9TFJHMccxI9asUgi4+TNnmMqLU1k3N8S2PjyZ1sjeC8B79fKPpwCzj72WkqPkzZw3l2jArr+dU==NdJT ++rfc2268.c iQCVAwUAQCN+3jEAnp832S/7AQLv1gQA1hJh29hAjKi4uLSGxXvJ6cyYmPdmevdKrbLnuHZWtHe4xvCgy/nTdEojEpxgLp/hL/ogasuWRC1W16Wiz9ryxf7YR0uhZWayO/bQNagpfU5MIkJTLuKqqgpwYumCSQfOugXVAqcgEzj+13eeyJaFVrzwrNa67sh84nmbjOjNjvE==0zBq ++ ++# Random number related ++random.c iQCVAwUAP7nsITEAnp832S/7AQK4SAQAtvfUgrtGOQ2PlxGMla0qJLPHjJacMwgq0ecusiI79elPdDsFfCCk6dK1Ug2kFbNm22nCGHNcUquqbX7noi7ZVQnmPBQXzyLNZd7GmrawRZfdlRerTUDBpSnR8V8ui/5+YYp627E7kKGC0hPSgqXFql6oBMIfno0LZwFJTjIevRY==L419 ++random.h iQCVAwUAP7ovKDEAnp832S/7AQJ3bQQAjnPebnyTC7sphAv2I7uIz+yPgw1ZfbVhLv+OiWDlO9ish+fRyyMpy+HELBOgZjJdgRegqhlZC6qyns5arM/VglYi+PzvdLO3hIqHE/YFfpIFPz8wBrcmlqrYyd3CsGqcYsfjocXNttCBLeSWmoJ09ltKQH8yzJf3oAgN6X1yuc4==eNoU ++rand-internal.h iQCVAwUAP7ouvDEAnp832S/7AQLYnAQAhdI7ERoJVCkV8GiV7MjaUxv1WIL7iZ+jIOvVhv4fNyhCGCGoEtTjkyput/lj7Nsh3FXEqRhypGGrCLf47x/gua5n+BwffogxVyUDqiOyyGhNTPpe3fQcNBvbPCtco8yMK4GJO5G3BqzlPyN+BMeogLymyV6Sm1mvh5LZDyAFbfQ==tZSE ++rndlinux.c iQCVAwUAP9iPYTEAnp832S/7AQL6/AP/ZDrbOkVuB9qJ7sKeX1MImZEsz3mi0xPovJzaBtBU7a0idcUKrWYOvQFWRlLUeq0iCT6+h2l5bniP7q7hepzlKa+VPY9VWaQthqeJm2l5LN6QQ5PyMfBq04QuBncw9BJnCGmEyTLt3RxIXBAPdxmiVxtcRIFUqCBtQvoUXGLvemw==t37k ++rndegd.c iQCVAwUAP9iPRDEAnp832S/7AQImBQP/WHKg+hKXcm1pQvilzML0jZpwK5PAMM4uBnnPJNIXWOYBO6I/Xg9d/tPLg8NlmmtyQCo2Eu0ybDSt+8mu+dWveAys+0LTi0MIqeP9BMzCKz8dnWH6+S8huLXwTF3m0IrqM0JLb6b71GK9SOq6sWQ22yW5vf61hXP8kH9dhIaoMZs==FaHV ++rndunix.c iQCVAwUAP9iQlzEAnp832S/7AQL/KgQA29GnvcD4Xb5qjDMBgW9THEE4+4lfex/6k+Fh0IT61OLJsWVLJ7bJpRntburw4uQm4Tf7CO8vaiDFDYhKKrzXeOF1fmdpcL8hA+fNp9I/MUOc4e9kN9+YJ9wikVa0SZj1OBfhzgcFLd1xOtulkr3ii52HLF9vhrxzkgVwvD10Bi8==2cML ++rndw32.c iQCVAwUAP9iRKDEAnp832S/7AQIuaAQA3AJr3WqnxNDsWCIdvehf8Suotthj+laX8nJsvDfFhXPKcXDpsg0wTTXSnnKgyED53+uYiMDnVRsxeWAyhKwvx1MjjlaSMMjzbH6isWTH8FaWpLgrxEkXoPeNqYf5FXpdUkcUxGX2RkQeuX/cIfiHLNE9CV0usaF2jysjBX2iERY==EEnO ++ ++# Helper ++bithelp.h iQCVAwUAP7ouPTEAnp832S/7AQKXggQAqjcgvihIF3WclOgw1JV2rbARw4ISIDRMFqdaNCqBRx6BwEz3UGsEIlz6+iR1sS/reqN61WvtjLb+D0+tujAkGrgQJhFLG85WtG2tB5UVoI3am1fpkwiRm+bR4rv0rGk0BYk81bC7+l4KrK9o5lVp4lCsrorlUKsd48lNmBHyAXM==mDDN ++rmd.h iQCVAwUAP7oumjEAnp832S/7AQJiJQP/V4bJwjZaYndJzV+KRnIDbl1koHuw+ZK5heMYVu8Qk4ylqv//BGyeRa3jZCcfPHI35q6HilCs2VBm8hiBMjHSqY/VPn2ZQ0yg/lt6qEvl7YjsLmyMICvjG+ncszHoq9pRvnF3vTnM18sPIioXLk8fskuM0XOCNBs0ARBAQjY9UGI==olUN ++ ++# Configuration ++Makefile.am iQCVAwUAQCN33TEAnp832S/7AQKFJAQAz7BDkC814q+QiuE/jnutJHR5qlgbrm3ikGbQwdRzYUscst4bCCWy3uKL/sIPGLg+JQXtF5FnsQy3s4D9BOYhp72cA9ktYK65hhi4pNm/JQ0lXkZMNfk8Go5lNzKezlWwHvkMwRXR0Fep0wPdyeaKW5BfaW2ABvgep6Bp+hHEbyg==zSyi ++$names$ iQCVAwUAQCN3EDEAnp832S/7AQJXLAP8DvHTpm5DkTF35EmzeKpi9ie59AZcZanD19ir/e/7+PaQxr2riuLHDGwFKTju+dcvvBsqrygXOC378GXVWzIF2OZwS4EdDcJ+pgojo9UpsqpKsJHouY4Ugx5cQialxba462kUn8hcihSBnMyc4LzbJ5WQ4puQuqy544d2x94+2ms==G4Ls +diff --git a/grub-core/lib/libgcrypt/cipher/ac.c b/grub-core/lib/libgcrypt/cipher/ac.c +index ee9498b..14569cc 100644 +--- a/grub-core/lib/libgcrypt/cipher/ac.c ++++ b/grub-core/lib/libgcrypt/cipher/ac.c +@@ -2499,7 +2499,7 @@ typedef enum dencode_action + dencode_action_t; + + /* Encode or decode a message according to the the encoding method +- METHOD; ACTION specifies wether the message that is contained in ++ METHOD; ACTION specifies whether the message that is contained in + BUFFER_IN and of length BUFFER_IN_N should be encoded or decoded. + The resulting message will be stored in a newly allocated buffer in + BUFFER_OUT and BUFFER_OUT_N. */ +diff --git a/grub-core/lib/libgcrypt/cipher/cipher.c b/grub-core/lib/libgcrypt/cipher/cipher.c +index 2c33ee9..03455e1 100644 +--- a/grub-core/lib/libgcrypt/cipher/cipher.c ++++ b/grub-core/lib/libgcrypt/cipher/cipher.c +@@ -1,6 +1,6 @@ + /* cipher.c - cipher dispatcher + * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 +- * 2005, 2007, 2008 Free Software Foundation, Inc. ++ * 2005, 2007, 2008, 2009 Free Software Foundation, Inc. + * + * This file is part of Libgcrypt. + * +@@ -118,7 +118,7 @@ static gcry_module_t ciphers_registered; + /* This is the lock protecting CIPHERS_REGISTERED. */ + static ath_mutex_t ciphers_registered_lock = ATH_MUTEX_INITIALIZER; + +-/* Flag to check wether the default ciphers have already been ++/* Flag to check whether the default ciphers have already been + registered. */ + static int default_ciphers_registered; + +@@ -192,6 +192,11 @@ struct gcry_cipher_handle + int mode; + unsigned int flags; + ++ struct { ++ unsigned int key:1; /* Set to 1 if a key has been set. */ ++ unsigned int iv:1; /* Set to 1 if a IV has been set. */ ++ } marks; ++ + /* The initialization vector. To help code optimization we make + sure that it is aligned on an unsigned long and u32 boundary. */ + union { +@@ -681,7 +686,7 @@ gcry_cipher_open (gcry_cipher_hd_t *handle, + + REGISTER_DEFAULT_CIPHERS; + +- /* Fetch the according module and check wether the cipher is marked ++ /* Fetch the according module and check whether the cipher is marked + available for use. */ + ath_mutex_lock (&ciphers_registered_lock); + module = _gcry_module_lookup_id (ciphers_registered, algo); +@@ -693,7 +698,6 @@ gcry_cipher_open (gcry_cipher_hd_t *handle, + { + /* Not available for use. */ + err = GPG_ERR_CIPHER_ALGO; +- _gcry_module_release (module); + } + else + { +@@ -724,6 +728,7 @@ gcry_cipher_open (gcry_cipher_hd_t *handle, + case GCRY_CIPHER_MODE_CFB: + case GCRY_CIPHER_MODE_OFB: + case GCRY_CIPHER_MODE_CTR: ++ case GCRY_CIPHER_MODE_AESWRAP: + if ((cipher->encrypt == dummy_encrypt_block) + || (cipher->decrypt == dummy_decrypt_block)) + err = GPG_ERR_INV_CIPHER_MODE; +@@ -882,7 +887,10 @@ cipher_setkey (gcry_cipher_hd_t c, byte *key, unsigned int keylen) + memcpy ((void *) ((char *) &c->context.c + c->cipher->contextsize), + (void *) &c->context.c, + c->cipher->contextsize); ++ c->marks.key = 1; + } ++ else ++ c->marks.key = 0; + + return gcry_error (ret); + } +@@ -905,7 +913,10 @@ cipher_setiv( gcry_cipher_hd_t c, const byte *iv, unsigned ivlen ) + if (ivlen > c->cipher->blocksize) + ivlen = c->cipher->blocksize; + memcpy (c->u_iv.iv, iv, ivlen); ++ c->marks.iv = 1; + } ++ else ++ c->marks.iv = 0; + c->unused = 0; + } + +@@ -918,54 +929,85 @@ cipher_reset (gcry_cipher_hd_t c) + memcpy (&c->context.c, + (char *) &c->context.c + c->cipher->contextsize, + c->cipher->contextsize); ++ memset (&c->marks, 0, sizeof c->marks); + memset (c->u_iv.iv, 0, c->cipher->blocksize); + memset (c->lastiv, 0, c->cipher->blocksize); + memset (c->ctr, 0, c->cipher->blocksize); + } + + +-static void +-do_ecb_encrypt( gcry_cipher_hd_t c, byte *outbuf, const byte *inbuf, +- unsigned int nblocks ) ++ ++static gcry_err_code_t ++do_ecb_encrypt (gcry_cipher_hd_t c, ++ unsigned char *outbuf, unsigned int outbuflen, ++ const unsigned char *inbuf, unsigned int inbuflen) + { +- unsigned int n; ++ unsigned int blocksize = c->cipher->blocksize; ++ unsigned int n, nblocks; + ++ if (outbuflen < inbuflen) ++ return GPG_ERR_BUFFER_TOO_SHORT; ++ if ((inbuflen % blocksize)) ++ return GPG_ERR_INV_LENGTH; ++ ++ nblocks = inbuflen / c->cipher->blocksize; ++ + for (n=0; n < nblocks; n++ ) + { +- c->cipher->encrypt ( &c->context.c, outbuf, (byte*)/*arggg*/inbuf ); +- inbuf += c->cipher->blocksize; +- outbuf += c->cipher->blocksize; ++ c->cipher->encrypt (&c->context.c, outbuf, (byte*)/*arggg*/inbuf); ++ inbuf += blocksize; ++ outbuf += blocksize; + } ++ return 0; + } + +-static void +-do_ecb_decrypt( gcry_cipher_hd_t c, byte *outbuf, const byte *inbuf, +- unsigned int nblocks ) ++static gcry_err_code_t ++do_ecb_decrypt (gcry_cipher_hd_t c, ++ unsigned char *outbuf, unsigned int outbuflen, ++ const unsigned char *inbuf, unsigned int inbuflen) + { +- unsigned int n; ++ unsigned int blocksize = c->cipher->blocksize; ++ unsigned int n, nblocks; ++ ++ if (outbuflen < inbuflen) ++ return GPG_ERR_BUFFER_TOO_SHORT; ++ if ((inbuflen % blocksize)) ++ return GPG_ERR_INV_LENGTH; ++ nblocks = inbuflen / c->cipher->blocksize; + + for (n=0; n < nblocks; n++ ) + { +- c->cipher->decrypt ( &c->context.c, outbuf, (byte*)/*arggg*/inbuf ); +- inbuf += c->cipher->blocksize; +- outbuf += c->cipher->blocksize; ++ c->cipher->decrypt (&c->context.c, outbuf, (byte*)/*arggg*/inbuf ); ++ inbuf += blocksize; ++ outbuf += blocksize; + } ++ ++ return 0; + } + + +-static void +-do_cbc_encrypt (gcry_cipher_hd_t c, unsigned char *outbuf, +- const unsigned char *inbuf, unsigned int nbytes ) ++static gcry_err_code_t ++do_cbc_encrypt (gcry_cipher_hd_t c, ++ unsigned char *outbuf, unsigned int outbuflen, ++ const unsigned char *inbuf, unsigned int inbuflen) + { + unsigned int n; + unsigned char *ivp; + int i; + size_t blocksize = c->cipher->blocksize; +- unsigned nblocks = nbytes / blocksize; ++ unsigned nblocks = inbuflen / blocksize; ++ ++ if (outbuflen < ((c->flags & GCRY_CIPHER_CBC_MAC)? blocksize : inbuflen)) ++ return GPG_ERR_BUFFER_TOO_SHORT; + +- if ((c->flags & GCRY_CIPHER_CBC_CTS) && nbytes > blocksize) ++ if ((inbuflen % c->cipher->blocksize) ++ && !(inbuflen > c->cipher->blocksize ++ && (c->flags & GCRY_CIPHER_CBC_CTS))) ++ return GPG_ERR_INV_LENGTH; ++ ++ if ((c->flags & GCRY_CIPHER_CBC_CTS) && inbuflen > blocksize) + { +- if ((nbytes % blocksize) == 0) ++ if ((inbuflen % blocksize) == 0) + nblocks--; + } + +@@ -991,17 +1033,17 @@ do_cbc_encrypt (gcry_cipher_hd_t c, unsigned char *outbuf, + } + } + +- if ((c->flags & GCRY_CIPHER_CBC_CTS) && nbytes > blocksize) ++ if ((c->flags & GCRY_CIPHER_CBC_CTS) && inbuflen > blocksize) + { + /* We have to be careful here, since outbuf might be equal to + inbuf. */ + int restbytes; + unsigned char b; + +- if ((nbytes % blocksize) == 0) ++ if ((inbuflen % blocksize) == 0) + restbytes = blocksize; + else +- restbytes = nbytes % blocksize; ++ restbytes = inbuflen % blocksize; + + outbuf -= blocksize; + for (ivp = c->u_iv.iv, i = 0; i < restbytes; i++) +@@ -1016,23 +1058,34 @@ do_cbc_encrypt (gcry_cipher_hd_t c, unsigned char *outbuf, + c->cipher->encrypt (&c->context.c, outbuf, outbuf); + memcpy (c->u_iv.iv, outbuf, blocksize); + } ++ ++ return 0; + } + + +-static void +-do_cbc_decrypt (gcry_cipher_hd_t c, unsigned char *outbuf, +- const unsigned char *inbuf, unsigned int nbytes) ++static gcry_err_code_t ++do_cbc_decrypt (gcry_cipher_hd_t c, ++ unsigned char *outbuf, unsigned int outbuflen, ++ const unsigned char *inbuf, unsigned int inbuflen) + { + unsigned int n; + unsigned char *ivp; + int i; + size_t blocksize = c->cipher->blocksize; +- unsigned int nblocks = nbytes / blocksize; ++ unsigned int nblocks = inbuflen / blocksize; ++ ++ if (outbuflen < inbuflen) ++ return GPG_ERR_BUFFER_TOO_SHORT; + +- if ((c->flags & GCRY_CIPHER_CBC_CTS) && nbytes > blocksize) ++ if ((inbuflen % c->cipher->blocksize) ++ && !(inbuflen > c->cipher->blocksize ++ && (c->flags & GCRY_CIPHER_CBC_CTS))) ++ return GPG_ERR_INV_LENGTH; ++ ++ if ((c->flags & GCRY_CIPHER_CBC_CTS) && inbuflen > blocksize) + { + nblocks--; +- if ((nbytes % blocksize) == 0) ++ if ((inbuflen % blocksize) == 0) + nblocks--; + memcpy (c->lastiv, c->u_iv.iv, blocksize); + } +@@ -1060,14 +1113,14 @@ do_cbc_decrypt (gcry_cipher_hd_t c, unsigned char *outbuf, + } + } + +- if ((c->flags & GCRY_CIPHER_CBC_CTS) && nbytes > blocksize) ++ if ((c->flags & GCRY_CIPHER_CBC_CTS) && inbuflen > blocksize) + { + int restbytes; + +- if ((nbytes % blocksize) == 0) ++ if ((inbuflen % blocksize) == 0) + restbytes = blocksize; + else +- restbytes = nbytes % blocksize; ++ restbytes = inbuflen % blocksize; + + memcpy (c->lastiv, c->u_iv.iv, blocksize ); /* Save Cn-2. */ + memcpy (c->u_iv.iv, inbuf + blocksize, restbytes ); /* Save Cn. */ +@@ -1084,32 +1137,38 @@ do_cbc_decrypt (gcry_cipher_hd_t c, unsigned char *outbuf, + outbuf[i] ^= *ivp++; + /* c->lastiv is now really lastlastiv, does this matter? */ + } ++ ++ return 0; + } + + +-static void +-do_cfb_encrypt( gcry_cipher_hd_t c, unsigned char *outbuf, +- const unsigned char *inbuf, unsigned int nbytes ) ++static gcry_err_code_t ++do_cfb_encrypt (gcry_cipher_hd_t c, ++ unsigned char *outbuf, unsigned int outbuflen, ++ const unsigned char *inbuf, unsigned int inbuflen) + { + unsigned char *ivp; + size_t blocksize = c->cipher->blocksize; + size_t blocksize_x_2 = blocksize + blocksize; + +- if ( nbytes <= c->unused ) ++ if (outbuflen < inbuflen) ++ return GPG_ERR_BUFFER_TOO_SHORT; ++ ++ if ( inbuflen <= c->unused ) + { + /* Short enough to be encoded by the remaining XOR mask. */ + /* XOR the input with the IV and store input into IV. */ + for (ivp=c->u_iv.iv+c->cipher->blocksize - c->unused; +- nbytes; +- nbytes--, c->unused-- ) ++ inbuflen; ++ inbuflen--, c->unused-- ) + *outbuf++ = (*ivp++ ^= *inbuf++); +- return; ++ return 0; + } + + if ( c->unused ) + { + /* XOR the input with the IV and store input into IV */ +- nbytes -= c->unused; ++ inbuflen -= c->unused; + for(ivp=c->u_iv.iv+blocksize - c->unused; c->unused; c->unused-- ) + *outbuf++ = (*ivp++ ^= *inbuf++); + } +@@ -1117,17 +1176,17 @@ do_cfb_encrypt( gcry_cipher_hd_t c, unsigned char *outbuf, + /* Now we can process complete blocks. We use a loop as long as we + have at least 2 blocks and use conditions for the rest. This + also allows to use a bulk encryption function if available. */ +- if (nbytes >= blocksize_x_2 && c->bulk.cfb_enc) ++ if (inbuflen >= blocksize_x_2 && c->bulk.cfb_enc) + { +- unsigned int nblocks = nbytes / blocksize; ++ unsigned int nblocks = inbuflen / blocksize; + c->bulk.cfb_enc (&c->context.c, c->u_iv.iv, outbuf, inbuf, nblocks); + outbuf += nblocks * blocksize; + inbuf += nblocks * blocksize; +- nbytes -= nblocks * blocksize; ++ inbuflen -= nblocks * blocksize; + } + else + { +- while ( nbytes >= blocksize_x_2 ) ++ while ( inbuflen >= blocksize_x_2 ) + { + int i; + /* Encrypt the IV. */ +@@ -1135,11 +1194,11 @@ do_cfb_encrypt( gcry_cipher_hd_t c, unsigned char *outbuf, + /* XOR the input with the IV and store input into IV. */ + for(ivp=c->u_iv.iv,i=0; i < blocksize; i++ ) + *outbuf++ = (*ivp++ ^= *inbuf++); +- nbytes -= blocksize; ++ inbuflen -= blocksize; + } + } + +- if ( nbytes >= blocksize ) ++ if ( inbuflen >= blocksize ) + { + int i; + /* Save the current IV and then encrypt the IV. */ +@@ -1148,25 +1207,27 @@ do_cfb_encrypt( gcry_cipher_hd_t c, unsigned char *outbuf, + /* XOR the input with the IV and store input into IV */ + for(ivp=c->u_iv.iv,i=0; i < blocksize; i++ ) + *outbuf++ = (*ivp++ ^= *inbuf++); +- nbytes -= blocksize; ++ inbuflen -= blocksize; + } +- if ( nbytes ) ++ if ( inbuflen ) + { + /* Save the current IV and then encrypt the IV. */ + memcpy( c->lastiv, c->u_iv.iv, blocksize ); + c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv ); + c->unused = blocksize; + /* Apply the XOR. */ +- c->unused -= nbytes; +- for(ivp=c->u_iv.iv; nbytes; nbytes-- ) ++ c->unused -= inbuflen; ++ for(ivp=c->u_iv.iv; inbuflen; inbuflen-- ) + *outbuf++ = (*ivp++ ^= *inbuf++); + } ++ return 0; + } + + +-static void +-do_cfb_decrypt( gcry_cipher_hd_t c, unsigned char *outbuf, +- const unsigned char *inbuf, unsigned int nbytes ) ++static gcry_err_code_t ++do_cfb_decrypt (gcry_cipher_hd_t c, ++ unsigned char *outbuf, unsigned int outbuflen, ++ const unsigned char *inbuf, unsigned int inbuflen) + { + unsigned char *ivp; + unsigned long temp; +@@ -1174,25 +1235,28 @@ do_cfb_decrypt( gcry_cipher_hd_t c, unsigned char *outbuf, + size_t blocksize = c->cipher->blocksize; + size_t blocksize_x_2 = blocksize + blocksize; + +- if (nbytes <= c->unused) ++ if (outbuflen < inbuflen) ++ return GPG_ERR_BUFFER_TOO_SHORT; ++ ++ if (inbuflen <= c->unused) + { + /* Short enough to be encoded by the remaining XOR mask. */ + /* XOR the input with the IV and store input into IV. */ + for (ivp=c->u_iv.iv+blocksize - c->unused; +- nbytes; +- nbytes--, c->unused--) ++ inbuflen; ++ inbuflen--, c->unused--) + { + temp = *inbuf++; + *outbuf++ = *ivp ^ temp; + *ivp++ = temp; + } +- return; ++ return 0; + } + + if (c->unused) + { + /* XOR the input with the IV and store input into IV. */ +- nbytes -= c->unused; ++ inbuflen -= c->unused; + for (ivp=c->u_iv.iv+blocksize - c->unused; c->unused; c->unused-- ) + { + temp = *inbuf++; +@@ -1204,17 +1268,17 @@ do_cfb_decrypt( gcry_cipher_hd_t c, unsigned char *outbuf, + /* Now we can process complete blocks. We use a loop as long as we + have at least 2 blocks and use conditions for the rest. This + also allows to use a bulk encryption function if available. */ +- if (nbytes >= blocksize_x_2 && c->bulk.cfb_dec) ++ if (inbuflen >= blocksize_x_2 && c->bulk.cfb_dec) + { +- unsigned int nblocks = nbytes / blocksize; ++ unsigned int nblocks = inbuflen / blocksize; + c->bulk.cfb_dec (&c->context.c, c->u_iv.iv, outbuf, inbuf, nblocks); + outbuf += nblocks * blocksize; + inbuf += nblocks * blocksize; +- nbytes -= nblocks * blocksize; ++ inbuflen -= nblocks * blocksize; + } + else + { +- while (nbytes >= blocksize_x_2 ) ++ while (inbuflen >= blocksize_x_2 ) + { + /* Encrypt the IV. */ + c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv ); +@@ -1225,11 +1289,11 @@ do_cfb_decrypt( gcry_cipher_hd_t c, unsigned char *outbuf, + *outbuf++ = *ivp ^ temp; + *ivp++ = temp; + } +- nbytes -= blocksize; ++ inbuflen -= blocksize; + } + } + +- if (nbytes >= blocksize ) ++ if (inbuflen >= blocksize ) + { + /* Save the current IV and then encrypt the IV. */ + memcpy ( c->lastiv, c->u_iv.iv, blocksize); +@@ -1241,54 +1305,59 @@ do_cfb_decrypt( gcry_cipher_hd_t c, unsigned char *outbuf, + *outbuf++ = *ivp ^ temp; + *ivp++ = temp; + } +- nbytes -= blocksize; ++ inbuflen -= blocksize; + } + +- if (nbytes) ++ if (inbuflen) + { + /* Save the current IV and then encrypt the IV. */ + memcpy ( c->lastiv, c->u_iv.iv, blocksize ); + c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv ); + c->unused = blocksize; + /* Apply the XOR. */ +- c->unused -= nbytes; +- for (ivp=c->u_iv.iv; nbytes; nbytes-- ) ++ c->unused -= inbuflen; ++ for (ivp=c->u_iv.iv; inbuflen; inbuflen-- ) + { + temp = *inbuf++; + *outbuf++ = *ivp ^ temp; + *ivp++ = temp; + } + } ++ return 0; + } + + +-static void +-do_ofb_encrypt( gcry_cipher_hd_t c, +- byte *outbuf, const byte *inbuf, unsigned nbytes ) ++static gcry_err_code_t ++do_ofb_encrypt (gcry_cipher_hd_t c, ++ unsigned char *outbuf, unsigned int outbuflen, ++ const unsigned char *inbuf, unsigned int inbuflen) + { +- byte *ivp; ++ unsigned char *ivp; + size_t blocksize = c->cipher->blocksize; + +- if ( nbytes <= c->unused ) ++ if (outbuflen < inbuflen) ++ return GPG_ERR_BUFFER_TOO_SHORT; ++ ++ if ( inbuflen <= c->unused ) + { + /* Short enough to be encoded by the remaining XOR mask. */ + /* XOR the input with the IV */ + for (ivp=c->u_iv.iv+c->cipher->blocksize - c->unused; +- nbytes; +- nbytes--, c->unused-- ) ++ inbuflen; ++ inbuflen--, c->unused-- ) + *outbuf++ = (*ivp++ ^ *inbuf++); +- return; ++ return 0; + } + + if( c->unused ) + { +- nbytes -= c->unused; ++ inbuflen -= c->unused; + for(ivp=c->u_iv.iv+blocksize - c->unused; c->unused; c->unused-- ) + *outbuf++ = (*ivp++ ^ *inbuf++); + } + + /* Now we can process complete blocks. */ +- while ( nbytes >= blocksize ) ++ while ( inbuflen >= blocksize ) + { + int i; + /* Encrypt the IV (and save the current one). */ +@@ -1297,43 +1366,48 @@ do_ofb_encrypt( gcry_cipher_hd_t c, + + for (ivp=c->u_iv.iv,i=0; i < blocksize; i++ ) + *outbuf++ = (*ivp++ ^ *inbuf++); +- nbytes -= blocksize; ++ inbuflen -= blocksize; + } +- if ( nbytes ) ++ if ( inbuflen ) + { /* process the remaining bytes */ + memcpy( c->lastiv, c->u_iv.iv, blocksize ); + c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv ); + c->unused = blocksize; +- c->unused -= nbytes; +- for(ivp=c->u_iv.iv; nbytes; nbytes-- ) ++ c->unused -= inbuflen; ++ for(ivp=c->u_iv.iv; inbuflen; inbuflen-- ) + *outbuf++ = (*ivp++ ^ *inbuf++); + } ++ return 0; + } + +-static void +-do_ofb_decrypt( gcry_cipher_hd_t c, +- byte *outbuf, const byte *inbuf, unsigned int nbytes ) ++static gcry_err_code_t ++do_ofb_decrypt (gcry_cipher_hd_t c, ++ unsigned char *outbuf, unsigned int outbuflen, ++ const unsigned char *inbuf, unsigned int inbuflen) + { +- byte *ivp; ++ unsigned char *ivp; + size_t blocksize = c->cipher->blocksize; + +- if( nbytes <= c->unused ) ++ if (outbuflen < inbuflen) ++ return GPG_ERR_BUFFER_TOO_SHORT; ++ ++ if( inbuflen <= c->unused ) + { + /* Short enough to be encoded by the remaining XOR mask. */ +- for (ivp=c->u_iv.iv+blocksize - c->unused; nbytes; nbytes--,c->unused--) ++ for (ivp=c->u_iv.iv+blocksize - c->unused; inbuflen; inbuflen--,c->unused--) + *outbuf++ = *ivp++ ^ *inbuf++; +- return; ++ return 0; + } + + if ( c->unused ) + { +- nbytes -= c->unused; ++ inbuflen -= c->unused; + for (ivp=c->u_iv.iv+blocksize - c->unused; c->unused; c->unused-- ) + *outbuf++ = *ivp++ ^ *inbuf++; + } + + /* Now we can process complete blocks. */ +- while ( nbytes >= blocksize ) ++ while ( inbuflen >= blocksize ) + { + int i; + /* Encrypt the IV (and save the current one). */ +@@ -1341,36 +1415,45 @@ do_ofb_decrypt( gcry_cipher_hd_t c, + c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv ); + for (ivp=c->u_iv.iv,i=0; i < blocksize; i++ ) + *outbuf++ = *ivp++ ^ *inbuf++; +- nbytes -= blocksize; ++ inbuflen -= blocksize; + } +- if ( nbytes ) ++ if ( inbuflen ) + { /* Process the remaining bytes. */ + /* Encrypt the IV (and save the current one). */ + memcpy( c->lastiv, c->u_iv.iv, blocksize ); + c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv ); + c->unused = blocksize; +- c->unused -= nbytes; +- for (ivp=c->u_iv.iv; nbytes; nbytes-- ) ++ c->unused -= inbuflen; ++ for (ivp=c->u_iv.iv; inbuflen; inbuflen-- ) + *outbuf++ = *ivp++ ^ *inbuf++; + } ++ return 0; + } + + +-static void +-do_ctr_encrypt( gcry_cipher_hd_t c, byte *outbuf, const byte *inbuf, +- unsigned int nbytes ) ++static gcry_err_code_t ++do_ctr_encrypt (gcry_cipher_hd_t c, ++ unsigned char *outbuf, unsigned int outbuflen, ++ const unsigned char *inbuf, unsigned int inbuflen) + { + unsigned int n; +- byte tmp[MAX_BLOCKSIZE]; ++ unsigned char tmp[MAX_BLOCKSIZE]; + int i; ++ unsigned int blocksize = c->cipher->blocksize; + +- for(n=0; n < nbytes; n++) ++ if (outbuflen < inbuflen) ++ return GPG_ERR_BUFFER_TOO_SHORT; ++ ++ if ((inbuflen % blocksize)) ++ return GPG_ERR_INV_LENGTH; ++ ++ for (n=0; n < inbuflen; n++) + { +- if ((n % c->cipher->blocksize) == 0) ++ if ((n % blocksize) == 0) + { + c->cipher->encrypt (&c->context.c, tmp, c->ctr); + +- for (i = c->cipher->blocksize; i > 0; i--) ++ for (i = blocksize; i > 0; i--) + { + c->ctr[i-1]++; + if (c->ctr[i-1] != 0) +@@ -1378,76 +1461,252 @@ do_ctr_encrypt( gcry_cipher_hd_t c, byte *outbuf, const byte *inbuf, + } + } + +- /* XOR input with encrypted counter and store in output. */ +- outbuf[n] = inbuf[n] ^ tmp[n % c->cipher->blocksize]; ++ /* XOR input with encrypted counter and store in output. */ ++ outbuf[n] = inbuf[n] ^ tmp[n % blocksize]; + } ++ ++ wipememory (tmp, sizeof tmp); ++ return 0; + } + +-static void +-do_ctr_decrypt( gcry_cipher_hd_t c, byte *outbuf, const byte *inbuf, +- unsigned int nbytes ) ++static gcry_err_code_t ++do_ctr_decrypt (gcry_cipher_hd_t c, ++ unsigned char *outbuf, unsigned int outbuflen, ++ const unsigned char *inbuf, unsigned int inbuflen) + { +- do_ctr_encrypt (c, outbuf, inbuf, nbytes); ++ return do_ctr_encrypt (c, outbuf, outbuflen, inbuf, inbuflen); ++} ++ ++ ++/* Perform the AES-Wrap algorithm as specified by RFC3394. We ++ implement this as a mode usable with any cipher algorithm of ++ blocksize 128. */ ++static gcry_err_code_t ++do_aeswrap_encrypt (gcry_cipher_hd_t c, byte *outbuf, unsigned int outbuflen, ++ const byte *inbuf, unsigned int inbuflen ) ++{ ++ int j, x; ++ unsigned int n, i; ++ unsigned char *r, *a, *b; ++ unsigned char t[8]; ++ ++#if MAX_BLOCKSIZE < 8 ++#error Invalid block size ++#endif ++ /* We require a cipher with a 128 bit block length. */ ++ if (c->cipher->blocksize != 16) ++ return GPG_ERR_INV_LENGTH; ++ ++ /* The output buffer must be able to hold the input data plus one ++ additional block. */ ++ if (outbuflen < inbuflen + 8) ++ return GPG_ERR_BUFFER_TOO_SHORT; ++ /* Input data must be multiple of 64 bits. */ ++ if (inbuflen % 8) ++ return GPG_ERR_INV_ARG; ++ ++ n = inbuflen / 8; ++ ++ /* We need at least two 64 bit blocks. */ ++ if (n < 2) ++ return GPG_ERR_INV_ARG; ++ ++ r = outbuf; ++ a = outbuf; /* We store A directly in OUTBUF. */ ++ b = c->ctr; /* B is also used to concatenate stuff. */ ++ ++ /* If an IV has been set we use that IV as the Alternative Initial ++ Value; if it has not been set we use the standard value. */ ++ if (c->marks.iv) ++ memcpy (a, c->u_iv.iv, 8); ++ else ++ memset (a, 0xa6, 8); ++ ++ /* Copy the inbuf to the outbuf. */ ++ memmove (r+8, inbuf, inbuflen); ++ ++ memset (t, 0, sizeof t); /* t := 0. */ ++ ++ for (j = 0; j <= 5; j++) ++ { ++ for (i = 1; i <= n; i++) ++ { ++ /* B := AES_k( A | R[i] ) */ ++ memcpy (b, a, 8); ++ memcpy (b+8, r+i*8, 8); ++ c->cipher->encrypt (&c->context.c, b, b); ++ /* t := t + 1 */ ++ for (x = 7; x >= 0; x--) ++ { ++ t[x]++; ++ if (t[x]) ++ break; ++ } ++ /* A := MSB_64(B) ^ t */ ++ for (x=0; x < 8; x++) ++ a[x] = b[x] ^ t[x]; ++ /* R[i] := LSB_64(B) */ ++ memcpy (r+i*8, b+8, 8); ++ } ++ } ++ ++ return 0; ++} ++ ++/* Perform the AES-Unwrap algorithm as specified by RFC3394. We ++ implement this as a mode usable with any cipher algorithm of ++ blocksize 128. */ ++static gcry_err_code_t ++do_aeswrap_decrypt (gcry_cipher_hd_t c, byte *outbuf, unsigned int outbuflen, ++ const byte *inbuf, unsigned int inbuflen) ++{ ++ int j, x; ++ unsigned int n, i; ++ unsigned char *r, *a, *b; ++ unsigned char t[8]; ++ ++#if MAX_BLOCKSIZE < 8 ++#error Invalid block size ++#endif ++ /* We require a cipher with a 128 bit block length. */ ++ if (c->cipher->blocksize != 16) ++ return GPG_ERR_INV_LENGTH; ++ ++ /* The output buffer must be able to hold the input data minus one ++ additional block. Fixme: The caller has more restrictive checks ++ - we may want to fix them for this mode. */ ++ if (outbuflen + 8 < inbuflen) ++ return GPG_ERR_BUFFER_TOO_SHORT; ++ /* Input data must be multiple of 64 bits. */ ++ if (inbuflen % 8) ++ return GPG_ERR_INV_ARG; ++ ++ n = inbuflen / 8; ++ ++ /* We need at least three 64 bit blocks. */ ++ if (n < 3) ++ return GPG_ERR_INV_ARG; ++ ++ r = outbuf; ++ a = c->lastiv; /* We use c->LASTIV as buffer for A. */ ++ b = c->ctr; /* B is also used to concatenate stuff. */ ++ ++ /* Copy the inbuf to the outbuf and save A. */ ++ memcpy (a, inbuf, 8); ++ memmove (r, inbuf+8, inbuflen-8); ++ n--; /* Reduce to actual number of data blocks. */ ++ ++ /* t := 6 * n */ ++ i = n * 6; /* The range is valid because: n = inbuflen / 8 - 1. */ ++ for (x=0; x < 8 && x < sizeof (i); x++) ++ t[7-x] = i >> (8*x); ++ for (; x < 8; x++) ++ t[7-x] = 0; ++ ++ for (j = 5; j >= 0; j--) ++ { ++ for (i = n; i >= 1; i--) ++ { ++ /* B := AES_k^1( (A ^ t)| R[i] ) */ ++ for (x = 0; x < 8; x++) ++ b[x] = a[x] ^ t[x]; ++ memcpy (b+8, r+(i-1)*8, 8); ++ c->cipher->decrypt (&c->context.c, b, b); ++ /* t := t - 1 */ ++ for (x = 7; x >= 0; x--) ++ { ++ t[x]--; ++ if (t[x] != 0xff) ++ break; ++ } ++ /* A := MSB_64(B) */ ++ memcpy (a, b, 8); ++ /* R[i] := LSB_64(B) */ ++ memcpy (r+(i-1)*8, b+8, 8); ++ } ++ } ++ ++ /* If an IV has been set we compare against this Alternative Initial ++ Value; if it has not been set we compare against the standard IV. */ ++ if (c->marks.iv) ++ j = memcmp (a, c->u_iv.iv, 8); ++ else ++ { ++ for (j=0, x=0; x < 8; x++) ++ if (a[x] != 0xa6) ++ { ++ j=1; ++ break; ++ } ++ } ++ return j? GPG_ERR_CHECKSUM : 0; + } + + + /**************** + * Encrypt INBUF to OUTBUF with the mode selected at open. + * inbuf and outbuf may overlap or be the same. +- * Depending on the mode some contraints apply to NBYTES. ++ * Depending on the mode some constraints apply to INBUFLEN. + */ + static gcry_err_code_t +-cipher_encrypt (gcry_cipher_hd_t c, byte *outbuf, +- const byte *inbuf, unsigned int nbytes) ++cipher_encrypt (gcry_cipher_hd_t c, byte *outbuf, unsigned int outbuflen, ++ const byte *inbuf, unsigned int inbuflen) + { +- gcry_err_code_t rc = GPG_ERR_NO_ERROR; ++ gcry_err_code_t rc; + +- switch( c->mode ) { +- case GCRY_CIPHER_MODE_ECB: +- if (!(nbytes%c->cipher->blocksize)) +- do_ecb_encrypt(c, outbuf, inbuf, nbytes/c->cipher->blocksize ); +- else +- rc = GPG_ERR_INV_ARG; +- break; +- case GCRY_CIPHER_MODE_CBC: +- if (!(nbytes%c->cipher->blocksize) +- || (nbytes > c->cipher->blocksize +- && (c->flags & GCRY_CIPHER_CBC_CTS))) +- do_cbc_encrypt(c, outbuf, inbuf, nbytes ); +- else +- rc = GPG_ERR_INV_ARG; +- break; +- case GCRY_CIPHER_MODE_CFB: +- do_cfb_encrypt(c, outbuf, inbuf, nbytes ); +- break; +- case GCRY_CIPHER_MODE_OFB: +- do_ofb_encrypt(c, outbuf, inbuf, nbytes ); +- break; +- case GCRY_CIPHER_MODE_CTR: +- do_ctr_encrypt(c, outbuf, inbuf, nbytes ); +- break; +- case GCRY_CIPHER_MODE_STREAM: +- c->cipher->stencrypt ( &c->context.c, +- outbuf, (byte*)/*arggg*/inbuf, nbytes ); +- break; +- case GCRY_CIPHER_MODE_NONE: +- if (fips_mode () || !_gcry_get_debug_flag (0)) +- { +- fips_signal_error ("cipher mode NONE used"); +- rc = GPG_ERR_INV_CIPHER_MODE; +- } +- else +- { +- if ( inbuf != outbuf ) +- memmove (outbuf, inbuf, nbytes); +- } +- break; +- default: +- log_fatal("cipher_encrypt: invalid mode %d\n", c->mode ); +- rc = GPG_ERR_INV_CIPHER_MODE; +- break; ++ switch (c->mode) ++ { ++ case GCRY_CIPHER_MODE_ECB: ++ rc = do_ecb_encrypt (c, outbuf, outbuflen, inbuf, inbuflen); ++ break; ++ ++ case GCRY_CIPHER_MODE_CBC: ++ rc = do_cbc_encrypt (c, outbuf, outbuflen, inbuf, inbuflen); ++ break; ++ ++ case GCRY_CIPHER_MODE_CFB: ++ rc = do_cfb_encrypt (c, outbuf, outbuflen, inbuf, inbuflen); ++ break; ++ ++ case GCRY_CIPHER_MODE_OFB: ++ rc = do_ofb_encrypt (c, outbuf, outbuflen, inbuf, inbuflen); ++ break; ++ ++ case GCRY_CIPHER_MODE_CTR: ++ rc = do_ctr_encrypt (c, outbuf, outbuflen, inbuf, inbuflen); ++ break; ++ ++ case GCRY_CIPHER_MODE_AESWRAP: ++ rc = do_aeswrap_encrypt (c, outbuf, outbuflen, inbuf, inbuflen); ++ break; ++ ++ case GCRY_CIPHER_MODE_STREAM: ++ c->cipher->stencrypt (&c->context.c, ++ outbuf, (byte*)/*arggg*/inbuf, inbuflen); ++ rc = 0; ++ break; ++ ++ case GCRY_CIPHER_MODE_NONE: ++ if (fips_mode () || !_gcry_get_debug_flag (0)) ++ { ++ fips_signal_error ("cipher mode NONE used"); ++ rc = GPG_ERR_INV_CIPHER_MODE; ++ } ++ else ++ { ++ if (inbuf != outbuf) ++ memmove (outbuf, inbuf, inbuflen); ++ rc = 0; ++ } ++ break; ++ ++ default: ++ log_fatal ("cipher_encrypt: invalid mode %d\n", c->mode ); ++ rc = GPG_ERR_INV_CIPHER_MODE; ++ break; + } +- return rc; ++ ++ return rc; + } + + +@@ -1461,29 +1720,15 @@ gcry_cipher_encrypt (gcry_cipher_hd_t h, void *out, size_t outsize, + { + gcry_err_code_t err; + +- if (!in) +- { +- /* Caller requested in-place encryption. */ +- /* Actually cipher_encrypt() does not need to know about it, but +- * we may change it in the future to get better performance. */ +- err = cipher_encrypt (h, out, out, outsize); +- } +- else if (outsize < ((h->flags & GCRY_CIPHER_CBC_MAC) ? +- h->cipher->blocksize : inlen)) +- err = GPG_ERR_TOO_SHORT; +- else if ((h->mode == GCRY_CIPHER_MODE_ECB +- || (h->mode == GCRY_CIPHER_MODE_CBC +- && (! ((h->flags & GCRY_CIPHER_CBC_CTS) +- && (inlen > h->cipher->blocksize))))) +- && (inlen % h->cipher->blocksize)) +- err = GPG_ERR_INV_ARG; ++ if (!in) /* Caller requested in-place encryption. */ ++ err = cipher_encrypt (h, out, outsize, out, outsize); + else +- err = cipher_encrypt (h, out, in, inlen); ++ err = cipher_encrypt (h, out, outsize, in, inlen); + ++ /* Failsafe: Make sure that the plaintext will never make it into ++ OUT if the encryption returned an error. */ + if (err && out) +- memset (out, 0x42, outsize); /* Failsafe: Make sure that the +- plaintext will never make it into +- OUT. */ ++ memset (out, 0x42, outsize); + + return gcry_error (err); + } +@@ -1493,60 +1738,67 @@ gcry_cipher_encrypt (gcry_cipher_hd_t h, void *out, size_t outsize, + /**************** + * Decrypt INBUF to OUTBUF with the mode selected at open. + * inbuf and outbuf may overlap or be the same. +- * Depending on the mode some some contraints apply to NBYTES. ++ * Depending on the mode some some contraints apply to INBUFLEN. + */ + static gcry_err_code_t +-cipher_decrypt (gcry_cipher_hd_t c, byte *outbuf, const byte *inbuf, +- unsigned int nbytes) ++cipher_decrypt (gcry_cipher_hd_t c, byte *outbuf, unsigned int outbuflen, ++ const byte *inbuf, unsigned int inbuflen) + { +- gcry_err_code_t rc = GPG_ERR_NO_ERROR; ++ gcry_err_code_t rc; + +- switch( c->mode ) { +- case GCRY_CIPHER_MODE_ECB: +- if (!(nbytes%c->cipher->blocksize)) +- do_ecb_decrypt(c, outbuf, inbuf, nbytes/c->cipher->blocksize ); +- else +- rc = GPG_ERR_INV_ARG; +- break; +- case GCRY_CIPHER_MODE_CBC: +- if (!(nbytes%c->cipher->blocksize) +- || (nbytes > c->cipher->blocksize +- && (c->flags & GCRY_CIPHER_CBC_CTS))) +- do_cbc_decrypt(c, outbuf, inbuf, nbytes ); +- else +- rc = GPG_ERR_INV_ARG; +- break; +- case GCRY_CIPHER_MODE_CFB: +- do_cfb_decrypt(c, outbuf, inbuf, nbytes ); +- break; +- case GCRY_CIPHER_MODE_OFB: +- do_ofb_decrypt(c, outbuf, inbuf, nbytes ); +- break; +- case GCRY_CIPHER_MODE_CTR: +- do_ctr_decrypt(c, outbuf, inbuf, nbytes ); +- break; +- case GCRY_CIPHER_MODE_STREAM: +- c->cipher->stdecrypt ( &c->context.c, +- outbuf, (byte*)/*arggg*/inbuf, nbytes ); +- break; +- case GCRY_CIPHER_MODE_NONE: +- if (fips_mode () || !_gcry_get_debug_flag (0)) +- { +- fips_signal_error ("cipher mode NONE used"); +- rc = GPG_ERR_INV_CIPHER_MODE; +- } +- else +- { +- if (inbuf != outbuf) +- memmove (outbuf, inbuf, nbytes); +- } +- break; +- default: +- log_fatal ("cipher_decrypt: invalid mode %d\n", c->mode ); +- rc = GPG_ERR_INV_CIPHER_MODE; +- break; ++ switch (c->mode) ++ { ++ case GCRY_CIPHER_MODE_ECB: ++ rc = do_ecb_decrypt (c, outbuf, outbuflen, inbuf, inbuflen); ++ break; ++ ++ case GCRY_CIPHER_MODE_CBC: ++ rc = do_cbc_decrypt (c, outbuf, outbuflen, inbuf, inbuflen); ++ break; ++ ++ case GCRY_CIPHER_MODE_CFB: ++ rc = do_cfb_decrypt (c, outbuf, outbuflen, inbuf, inbuflen); ++ break; ++ ++ case GCRY_CIPHER_MODE_OFB: ++ rc = do_ofb_decrypt (c, outbuf, outbuflen, inbuf, inbuflen); ++ break; ++ ++ case GCRY_CIPHER_MODE_CTR: ++ rc = do_ctr_decrypt (c, outbuf, outbuflen, inbuf, inbuflen); ++ break; ++ ++ case GCRY_CIPHER_MODE_AESWRAP: ++ rc = do_aeswrap_decrypt (c, outbuf, outbuflen, inbuf, inbuflen); ++ break; ++ ++ case GCRY_CIPHER_MODE_STREAM: ++ c->cipher->stdecrypt (&c->context.c, ++ outbuf, (byte*)/*arggg*/inbuf, inbuflen); ++ rc = 0; ++ break; ++ ++ case GCRY_CIPHER_MODE_NONE: ++ if (fips_mode () || !_gcry_get_debug_flag (0)) ++ { ++ fips_signal_error ("cipher mode NONE used"); ++ rc = GPG_ERR_INV_CIPHER_MODE; ++ } ++ else ++ { ++ if (inbuf != outbuf) ++ memmove (outbuf, inbuf, inbuflen); ++ rc = 0; ++ } ++ break; ++ ++ default: ++ log_fatal ("cipher_decrypt: invalid mode %d\n", c->mode ); ++ rc = GPG_ERR_INV_CIPHER_MODE; ++ break; + } +- return rc; ++ ++ return rc; + } + + +@@ -1554,25 +1806,12 @@ gcry_error_t + gcry_cipher_decrypt (gcry_cipher_hd_t h, void *out, size_t outsize, + const void *in, size_t inlen) + { +- gcry_err_code_t err = 0; ++ gcry_err_code_t err; + +- if (!in) +- { +- /* Caller requested in-place encryption. */ +- /* Actually cipher_encrypt() does not need to know about it, but +- * we may change it in the future to get better performance. */ +- err = cipher_decrypt (h, out, out, outsize); +- } +- else if (outsize < inlen) +- err = GPG_ERR_TOO_SHORT; +- else if (((h->mode == GCRY_CIPHER_MODE_ECB) +- || ((h->mode == GCRY_CIPHER_MODE_CBC) +- && (! ((h->flags & GCRY_CIPHER_CBC_CTS) +- && (inlen > h->cipher->blocksize))))) +- && (inlen % h->cipher->blocksize) != 0) +- err = GPG_ERR_INV_ARG; ++ if (!in) /* Caller requested in-place encryption. */ ++ err = cipher_decrypt (h, out, outsize, out, outsize); + else +- err = cipher_decrypt (h, out, in, inlen); ++ err = cipher_decrypt (h, out, outsize, in, inlen); + + return gcry_error (err); + } +@@ -1732,7 +1971,7 @@ gcry_cipher_ctl( gcry_cipher_hd_t h, int cmd, void *buffer, size_t buflen) + + There are no values for CMD yet defined. + +- The fucntion always returns GPG_ERR_INV_OP. ++ The function always returns GPG_ERR_INV_OP. + + */ + gcry_error_t +@@ -1774,7 +2013,7 @@ gcry_cipher_info (gcry_cipher_hd_t h, int cmd, void *buffer, size_t *nbytes) + Note: Because this function is in most cases used to return an + integer value, we can make it easier for the caller to just look at + the return value. The caller will in all cases consult the value +- and thereby detecting whether a error occured or not (i.e. while ++ and thereby detecting whether a error occurred or not (i.e. while + checking the block size) + */ + gcry_error_t +diff --git a/grub-core/lib/libgcrypt/cipher/crc.c b/grub-core/lib/libgcrypt/cipher/crc.c +index d04fff8..9e406f1 100644 +--- a/grub-core/lib/libgcrypt/cipher/crc.c ++++ b/grub-core/lib/libgcrypt/cipher/crc.c +@@ -25,7 +25,6 @@ + #include + + #include "g10lib.h" +-#include "memory.h" + #include "cipher.h" + + #include "bithelp.h" +diff --git a/grub-core/lib/libgcrypt/cipher/des.c b/grub-core/lib/libgcrypt/cipher/des.c +index f91df77..e7f14fd 100644 +--- a/grub-core/lib/libgcrypt/cipher/des.c ++++ b/grub-core/lib/libgcrypt/cipher/des.c +@@ -106,7 +106,7 @@ + * + * if ( (error_msg = selftest()) ) + * { +- * fprintf(stderr, "An error in the DES/Tripple-DES implementation occured: %s\n", error_msg); ++ * fprintf(stderr, "An error in the DES/Triple-DES implementation occurred: %s\n", error_msg); + * abort(); + * } + */ +diff --git a/grub-core/lib/libgcrypt/cipher/dsa.c b/grub-core/lib/libgcrypt/cipher/dsa.c +index 100710f..ceb9496 100644 +--- a/grub-core/lib/libgcrypt/cipher/dsa.c ++++ b/grub-core/lib/libgcrypt/cipher/dsa.c +@@ -907,6 +907,7 @@ dsa_generate_ext (int algo, unsigned int nbits, unsigned long evalue, + gcry_mpi_release ((*retfactors)[i]); + (*retfactors)[i] = NULL; + } ++ gcry_free (*retfactors); + *retfactors = NULL; + if (ec) + { +diff --git a/grub-core/lib/libgcrypt/cipher/ecc.c b/grub-core/lib/libgcrypt/cipher/ecc.c +index fcbd8e3..bcfab05 100644 +--- a/grub-core/lib/libgcrypt/cipher/ecc.c ++++ b/grub-core/lib/libgcrypt/cipher/ecc.c +@@ -1,5 +1,5 @@ + /* ecc.c - Elliptic Curve Cryptography +- Copyright (C) 2007, 2008 Free Software Foundation, Inc. ++ Copyright (C) 2007, 2008, 2010 Free Software Foundation, Inc. + + This file is part of Libgcrypt. + +@@ -504,6 +504,7 @@ generate_curve (unsigned int nbits, const char *name, + */ + static gpg_err_code_t + generate_key (ECC_secret_key *sk, unsigned int nbits, const char *name, ++ int transient_key, + gcry_mpi_t g_x, gcry_mpi_t g_y, + gcry_mpi_t q_x, gcry_mpi_t q_y) + { +@@ -512,6 +513,7 @@ generate_key (ECC_secret_key *sk, unsigned int nbits, const char *name, + gcry_mpi_t d; + mpi_point_t Q; + mpi_ec_t ctx; ++ gcry_random_level_t random_level; + + err = generate_curve (nbits, name, &E, &nbits); + if (err) +@@ -528,9 +530,11 @@ generate_key (ECC_secret_key *sk, unsigned int nbits, const char *name, + log_mpidump ("ecc generation Gz", E.G.z); + } + ++ random_level = transient_key ? GCRY_STRONG_RANDOM : GCRY_VERY_STRONG_RANDOM; + if (DBG_CIPHER) +- log_debug ("choosing a random x of size %u\n", nbits); +- d = gen_k (E.n, GCRY_VERY_STRONG_RANDOM); ++ log_debug ("choosing a random x of size %u%s\n", nbits, ++ transient_key? " (transient-key)":""); ++ d = gen_k (E.n, random_level); + + /* Compute Q. */ + point_init (&Q); +@@ -962,6 +966,7 @@ ecc_generate_ext (int algo, unsigned int nbits, unsigned long evalue, + gcry_mpi_t g_x, g_y, q_x, q_y; + char *curve_name = NULL; + gcry_sexp_t l1; ++ int transient_key = 0; + + (void)algo; + (void)evalue; +@@ -978,6 +983,14 @@ ecc_generate_ext (int algo, unsigned int nbits, unsigned long evalue, + if (!curve_name) + return GPG_ERR_INV_OBJ; /* No curve name or value too large. */ + } ++ ++ /* Parse the optional transient-key flag. */ ++ l1 = gcry_sexp_find_token (genparms, "transient-key", 0); ++ if (l1) ++ { ++ transient_key = 1; ++ gcry_sexp_release (l1); ++ } + } + + /* NBITS is required if no curve name has been given. */ +@@ -988,7 +1001,7 @@ ecc_generate_ext (int algo, unsigned int nbits, unsigned long evalue, + g_y = mpi_new (0); + q_x = mpi_new (0); + q_y = mpi_new (0); +- ec = generate_key (&sk, nbits, curve_name, g_x, g_y, q_x, q_y); ++ ec = generate_key (&sk, nbits, curve_name, transient_key, g_x, g_y, q_x, q_y); + gcry_free (curve_name); + if (ec) + return ec; +@@ -1266,7 +1279,7 @@ compute_keygrip (gcry_md_hd_t md, gcry_sexp_t keyparam) + } + + /* Check that all parameters are known and normalize all MPIs (that +- should not be required but we use an internal fucntion later and ++ should not be required but we use an internal function later and + thus we better make 100% sure that they are normalized). */ + for (idx = 0; idx < 6; idx++) + if (!values[idx]) +diff --git a/grub-core/lib/libgcrypt/cipher/md.c b/grub-core/lib/libgcrypt/cipher/md.c +index 5dfbbd9..5f12126 100644 +--- a/grub-core/lib/libgcrypt/cipher/md.c ++++ b/grub-core/lib/libgcrypt/cipher/md.c +@@ -87,6 +87,10 @@ static struct digest_table_entry + #if USE_TIGER + { &_gcry_digest_spec_tiger, + &dummy_extra_spec, GCRY_MD_TIGER }, ++ { &_gcry_digest_spec_tiger1, ++ &dummy_extra_spec, GCRY_MD_TIGER1 }, ++ { &_gcry_digest_spec_tiger2, ++ &dummy_extra_spec, GCRY_MD_TIGER2 }, + #endif + #if USE_WHIRLPOOL + { &_gcry_digest_spec_whirlpool, +@@ -101,7 +105,7 @@ static gcry_module_t digests_registered; + /* This is the lock protecting DIGESTS_REGISTERED. */ + static ath_mutex_t digests_registered_lock = ATH_MUTEX_INITIALIZER; + +-/* Flag to check wether the default ciphers have already been ++/* Flag to check whether the default ciphers have already been + registered. */ + static int default_digests_registered; + +@@ -948,10 +952,13 @@ md_read( gcry_md_hd_t a, int algo ) + + if (! algo) + { +- /* return the first algorithm */ +- if (r && r->next) +- log_debug ("more than one algorithm in md_read(0)\n"); +- return r->digest->read( &r->context.c ); ++ /* Return the first algorithm */ ++ if (r) ++ { ++ if (r->next) ++ log_debug ("more than one algorithm in md_read(0)\n"); ++ return r->digest->read (&r->context.c); ++ } + } + else + { +@@ -1135,7 +1142,7 @@ md_asn_oid (int algorithm, size_t *asnlen, size_t *mdlen) + * Note: Because this function is in most cases used to return an + * integer value, we can make it easier for the caller to just look at + * the return value. The caller will in all cases consult the value +- * and thereby detecting whether a error occured or not (i.e. while checking ++ * and thereby detecting whether a error occurred or not (i.e. while checking + * the block size) + */ + gcry_error_t +diff --git a/grub-core/lib/libgcrypt/cipher/md4.c b/grub-core/lib/libgcrypt/cipher/md4.c +index aa180f0..976036c 100644 +--- a/grub-core/lib/libgcrypt/cipher/md4.c ++++ b/grub-core/lib/libgcrypt/cipher/md4.c +@@ -53,7 +53,6 @@ + #include + + #include "g10lib.h" +-#include "memory.h" + #include "cipher.h" + + #include "bithelp.h" +diff --git a/grub-core/lib/libgcrypt/cipher/md5.c b/grub-core/lib/libgcrypt/cipher/md5.c +index 3d3046d..1993368 100644 +--- a/grub-core/lib/libgcrypt/cipher/md5.c ++++ b/grub-core/lib/libgcrypt/cipher/md5.c +@@ -37,7 +37,6 @@ + #include + + #include "g10lib.h" +-#include "memory.h" + #include "cipher.h" + + #include "bithelp.h" +diff --git a/grub-core/lib/libgcrypt/cipher/primegen.c b/grub-core/lib/libgcrypt/cipher/primegen.c +index b869bee..f072775 100644 +--- a/grub-core/lib/libgcrypt/cipher/primegen.c ++++ b/grub-core/lib/libgcrypt/cipher/primegen.c +@@ -988,7 +988,7 @@ is_prime (gcry_mpi_t n, int steps, unsigned int *count) + /* Given ARRAY of size N with M elements set to true produce a + modified array with the next permutation of M elements. Note, that + ARRAY is used in a one-bit-per-byte approach. To detected the last +- permutation it is useful to intialize the array with the first M ++ permutation it is useful to initialize the array with the first M + element set to true and use this test: + m_out_of_n (array, m, n); + for (i = j = 0; i < n && j < m; i++) +@@ -1170,7 +1170,7 @@ gcry_prime_generate (gcry_mpi_t *prime, unsigned int prime_bits, + return gcry_error (err); + } + +-/* Check wether the number X is prime. */ ++/* Check whether the number X is prime. */ + gcry_error_t + gcry_prime_check (gcry_mpi_t x, unsigned int flags) + { +diff --git a/grub-core/lib/libgcrypt/cipher/pubkey.c b/grub-core/lib/libgcrypt/cipher/pubkey.c +index 08abcbf..86693e8 100644 +--- a/grub-core/lib/libgcrypt/cipher/pubkey.c ++++ b/grub-core/lib/libgcrypt/cipher/pubkey.c +@@ -85,7 +85,7 @@ static gcry_module_t pubkeys_registered; + /* This is the lock protecting PUBKEYS_REGISTERED. */ + static ath_mutex_t pubkeys_registered_lock = ATH_MUTEX_INITIALIZER;; + +-/* Flag to check wether the default pubkeys have already been ++/* Flag to check whether the default pubkeys have already been + registered. */ + static int default_pubkeys_registered; + +@@ -1567,7 +1567,7 @@ sexp_data_to_mpi (gcry_sexp_t input, unsigned int nbits, gcry_mpi_t *ret_mpi, + Do a PK encrypt operation + + Caller has to provide a public key as the SEXP pkey and data as a +- SEXP with just one MPI in it. Alternativly S_DATA might be a ++ SEXP with just one MPI in it. Alternatively S_DATA might be a + complex S-Expression, similar to the one used for signature + verification. This provides a flag which allows to handle PKCS#1 + block type 2 padding. The function returns a a sexp which may be +@@ -2357,7 +2357,7 @@ gcry_pk_get_nbits (gcry_sexp_t key) + + + /* Return the so called KEYGRIP which is the SHA-1 hash of the public +- key parameters expressed in a way depended on the algorithm. ++ key parameters expressed in a way depending on the algorithm. + + ARRAY must either be 20 bytes long or NULL; in the latter case a + newly allocated array of that size is returned, otherwise ARRAY or +@@ -2503,15 +2503,15 @@ gcry_pk_ctl (int cmd, void *buffer, size_t buflen) + care or a combination of the GCRY_PK_USAGE_xxx flags; + + GCRYCTL_GET_ALGO_USAGE: +- Return the usage glafs for the give algo. An invalid alog +- does return 0. Disabled algos are ignored here becuase we ++ Return the usage flags for the given algo. An invalid algo ++ returns 0. Disabled algos are ignored here because we + only want to know whether the algo is at all capable of + the usage. + + Note: Because this function is in most cases used to return an + integer value, we can make it easier for the caller to just look at + the return value. The caller will in all cases consult the value +- and thereby detecting whether a error occured or not (i.e. while ++ and thereby detecting whether a error occurred or not (i.e. while + checking the block size) */ + gcry_error_t + gcry_pk_algo_info (int algorithm, int what, void *buffer, size_t *nbytes) +diff --git a/grub-core/lib/libgcrypt/cipher/rfc2268.c b/grub-core/lib/libgcrypt/cipher/rfc2268.c +index 7d63fce..9575ca6 100644 +--- a/grub-core/lib/libgcrypt/cipher/rfc2268.c ++++ b/grub-core/lib/libgcrypt/cipher/rfc2268.c +@@ -22,7 +22,7 @@ + /* This implementation was written by Nikos Mavroyanopoulos for GNUTLS + * as a Libgcrypt module (gnutls/lib/x509/rc2.c) and later adapted for + * direct use by Libgcrypt by Werner Koch. This implementation is +- * only useful for pkcs#12 descryption. ++ * only useful for pkcs#12 decryption. + * + * The implementation here is based on Peter Gutmann's RRC.2 paper. + */ +diff --git a/grub-core/lib/libgcrypt/cipher/rmd160.c b/grub-core/lib/libgcrypt/cipher/rmd160.c +index 73d5337..7223c0f 100644 +--- a/grub-core/lib/libgcrypt/cipher/rmd160.c ++++ b/grub-core/lib/libgcrypt/cipher/rmd160.c +@@ -24,7 +24,6 @@ + #include + + #include "g10lib.h" +-#include "memory.h" + #include "rmd.h" + #include "cipher.h" /* Only used for the rmd160_hash_buffer() prototype. */ + +diff --git a/grub-core/lib/libgcrypt/cipher/rsa.c b/grub-core/lib/libgcrypt/cipher/rsa.c +index cf278c2..6102cc4 100644 +--- a/grub-core/lib/libgcrypt/cipher/rsa.c ++++ b/grub-core/lib/libgcrypt/cipher/rsa.c +@@ -444,18 +444,28 @@ generate_x931 (RSA_secret_key *sk, unsigned int nbits, unsigned long e_value, + else + { + /* Parameters to derive the key are given. */ ++ /* Note that we explicitly need to setup the values of tbl ++ because some compilers (e.g. OpenWatcom, IRIX) don't allow ++ to initialize a structure with automatic variables. */ + struct { const char *name; gcry_mpi_t *value; } tbl[] = { +- { "Xp1", &xp1 }, +- { "Xp2", &xp2 }, +- { "Xp", &xp }, +- { "Xq1", &xq1 }, +- { "Xq2", &xq2 }, +- { "Xq", &xq }, +- { NULL, NULL } ++ { "Xp1" }, ++ { "Xp2" }, ++ { "Xp" }, ++ { "Xq1" }, ++ { "Xq2" }, ++ { "Xq" }, ++ { NULL } + }; + int idx; + gcry_sexp_t oneparm; + ++ tbl[0].value = &xp1; ++ tbl[1].value = &xp2; ++ tbl[2].value = &xp; ++ tbl[3].value = &xq1; ++ tbl[4].value = &xq2; ++ tbl[5].value = &xq; ++ + for (idx=0; tbl[idx].name; idx++) + { + oneparm = gcry_sexp_find_token (deriveparms, tbl[idx].name, 0); +@@ -572,7 +582,7 @@ generate_x931 (RSA_secret_key *sk, unsigned int nbits, unsigned long e_value, + + + /**************** +- * Test wether the secret key is valid. ++ * Test whether the secret key is valid. + * Returns: true if this is a valid key. + */ + static int +@@ -876,7 +886,7 @@ rsa_check_secret_key (int algo, gcry_mpi_t *skey) + err = GPG_ERR_NO_OBJ; /* To check the key we need the optional + parameters. */ + else if (!check_secret_key (&sk)) +- err = GPG_ERR_PUBKEY_ALGO; ++ err = GPG_ERR_BAD_SECKEY; + + return err; + } +@@ -942,7 +952,7 @@ rsa_decrypt (int algo, gcry_mpi_t *result, gcry_mpi_t *data, + gcry_mpi_mod (r, r, sk.n); + + /* Calculate inverse of r. It practically impossible that the +- follwing test fails, thus we do not add code to release ++ following test fails, thus we do not add code to release + allocated resources. */ + if (!gcry_mpi_invm (ri, r, sk.n)) + return GPG_ERR_INTERNAL; +@@ -1053,7 +1063,7 @@ rsa_get_nbits (int algo, gcry_mpi_t *pkey) + (e #010001#)) + + PKCS-15 says that for RSA only the modulus should be hashed - +- however, it is not clear wether this is meant to use the raw bytes ++ however, it is not clear whether this is meant to use the raw bytes + (assuming this is an unsigned integer) or whether the DER required + 0 should be prefixed. We hash the raw bytes. */ + static gpg_err_code_t +diff --git a/grub-core/lib/libgcrypt/cipher/sha1.c b/grub-core/lib/libgcrypt/cipher/sha1.c +index 8862c64..0b5dc43 100644 +--- a/grub-core/lib/libgcrypt/cipher/sha1.c ++++ b/grub-core/lib/libgcrypt/cipher/sha1.c +@@ -37,7 +37,6 @@ + #endif + + #include "g10lib.h" +-#include "memory.h" + #include "bithelp.h" + #include "cipher.h" + #include "hash-common.h" +diff --git a/grub-core/lib/libgcrypt/cipher/sha256.c b/grub-core/lib/libgcrypt/cipher/sha256.c +index 5d61d2f..8063592 100644 +--- a/grub-core/lib/libgcrypt/cipher/sha256.c ++++ b/grub-core/lib/libgcrypt/cipher/sha256.c +@@ -1,5 +1,5 @@ + /* sha256.c - SHA256 hash function +- * Copyright (C) 2003, 2006, 2008 Free Software Foundation, Inc. ++ * Copyright (C) 2003, 2006, 2008, 2009 Free Software Foundation, Inc. + * + * This file is part of Libgcrypt. + * +@@ -41,7 +41,6 @@ + #include + + #include "g10lib.h" +-#include "memory.h" + #include "bithelp.h" + #include "cipher.h" + #include "hash-common.h" +@@ -95,10 +94,6 @@ sha224_init (void *context) + /* + Transform the message X which consists of 16 32-bit-words. See FIPS + 180-2 for details. */ +-#define Cho(x,y,z) (z ^ (x & (y ^ z))) /* (4.2) same as SHA-1's F1 */ +-#define Maj(x,y,z) ((x & y) | (z & (x|y))) /* (4.3) same as SHA-1's F3 */ +-#define Sum0(x) (ror ((x), 2) ^ ror ((x), 13) ^ ror ((x), 22)) /* (4.4) */ +-#define Sum1(x) (ror ((x), 6) ^ ror ((x), 11) ^ ror ((x), 25)) /* (4.5) */ + #define S0(x) (ror ((x), 7) ^ ror ((x), 18) ^ ((x) >> 3)) /* (4.6) */ + #define S1(x) (ror ((x), 17) ^ ror ((x), 19) ^ ((x) >> 10)) /* (4.7) */ + #define R(a,b,c,d,e,f,g,h,k,w) do \ +@@ -114,6 +109,35 @@ sha224_init (void *context) + b = a; \ + a = t1 + t2; \ + } while (0) ++ ++/* (4.2) same as SHA-1's F1. */ ++static inline u32 ++Cho (u32 x, u32 y, u32 z) ++{ ++ return (z ^ (x & (y ^ z))); ++} ++ ++/* (4.3) same as SHA-1's F3 */ ++static inline u32 ++Maj (u32 x, u32 y, u32 z) ++{ ++ return ((x & y) | (z & (x|y))); ++} ++ ++/* (4.4) */ ++static inline u32 ++Sum0 (u32 x) ++{ ++ return (ror (x, 2) ^ ror (x, 13) ^ ror (x, 22)); ++} ++ ++/* (4.5) */ ++static inline u32 ++Sum1 (u32 x) ++{ ++ return (ror (x, 6) ^ ror (x, 11) ^ ror (x, 25)); ++} ++ + + static void + transform (SHA256_CONTEXT *hd, const unsigned char *data) +@@ -172,8 +196,55 @@ transform (SHA256_CONTEXT *hd, const unsigned char *data) + for (; i < 64; i++) + w[i] = S1(w[i-2]) + w[i-7] + S0(w[i-15]) + w[i-16]; + +- for (i=0; i < 64; i++) +- R(a,b,c,d,e,f,g,h,K[i],w[i]); ++ for (i=0; i < 64;) ++ { ++#if 0 ++ R(a,b,c,d,e,f,g,h,K[i],w[i]); ++ i++; ++#else ++ t1 = h + Sum1 (e) + Cho (e, f, g) + K[i] + w[i]; ++ t2 = Sum0 (a) + Maj (a, b, c); ++ d += t1; ++ h = t1 + t2; ++ ++ t1 = g + Sum1 (d) + Cho (d, e, f) + K[i+1] + w[i+1]; ++ t2 = Sum0 (h) + Maj (h, a, b); ++ c += t1; ++ g = t1 + t2; ++ ++ t1 = f + Sum1 (c) + Cho (c, d, e) + K[i+2] + w[i+2]; ++ t2 = Sum0 (g) + Maj (g, h, a); ++ b += t1; ++ f = t1 + t2; ++ ++ t1 = e + Sum1 (b) + Cho (b, c, d) + K[i+3] + w[i+3]; ++ t2 = Sum0 (f) + Maj (f, g, h); ++ a += t1; ++ e = t1 + t2; ++ ++ t1 = d + Sum1 (a) + Cho (a, b, c) + K[i+4] + w[i+4]; ++ t2 = Sum0 (e) + Maj (e, f, g); ++ h += t1; ++ d = t1 + t2; ++ ++ t1 = c + Sum1 (h) + Cho (h, a, b) + K[i+5] + w[i+5]; ++ t2 = Sum0 (d) + Maj (d, e, f); ++ g += t1; ++ c = t1 + t2; ++ ++ t1 = b + Sum1 (g) + Cho (g, h, a) + K[i+6] + w[i+6]; ++ t2 = Sum0 (c) + Maj (c, d, e); ++ f += t1; ++ b = t1 + t2; ++ ++ t1 = a + Sum1 (f) + Cho (f, g, h) + K[i+7] + w[i+7]; ++ t2 = Sum0 (b) + Maj (b, c, d); ++ e += t1; ++ a = t1 + t2; ++ ++ i += 8; ++#endif ++ } + + hd->h0 += a; + hd->h1 += b; +@@ -184,10 +255,6 @@ transform (SHA256_CONTEXT *hd, const unsigned char *data) + hd->h6 += g; + hd->h7 += h; + } +-#undef Cho +-#undef Maj +-#undef Sum0 +-#undef Sum1 + #undef S0 + #undef S1 + #undef R +diff --git a/grub-core/lib/libgcrypt/cipher/sha512.c b/grub-core/lib/libgcrypt/cipher/sha512.c +index bbbd4c5..59c3e65 100644 +--- a/grub-core/lib/libgcrypt/cipher/sha512.c ++++ b/grub-core/lib/libgcrypt/cipher/sha512.c +@@ -1,5 +1,5 @@ + /* sha512.c - SHA384 and SHA512 hash functions +- * Copyright (C) 2003, 2008 Free Software Foundation, Inc. ++ * Copyright (C) 2003, 2008, 2009 Free Software Foundation, Inc. + * + * This file is part of Libgcrypt. + * +@@ -98,6 +98,36 @@ sha384_init (void *context) + } + + ++static inline u64 ++ROTR (u64 x, u64 n) ++{ ++ return ((x >> n) | (x << (64 - n))); ++} ++ ++static inline u64 ++Ch (u64 x, u64 y, u64 z) ++{ ++ return ((x & y) ^ ( ~x & z)); ++} ++ ++static inline u64 ++Maj (u64 x, u64 y, u64 z) ++{ ++ return ((x & y) ^ (x & z) ^ (y & z)); ++} ++ ++static inline u64 ++Sum0 (u64 x) ++{ ++ return (ROTR (x, 28) ^ ROTR (x, 34) ^ ROTR (x, 39)); ++} ++ ++static inline u64 ++Sum1 (u64 x) ++{ ++ return (ROTR (x, 14) ^ ROTR (x, 18) ^ ROTR (x, 41)); ++} ++ + /**************** + * Transform the message W which consists of 16 64-bit-words + */ +@@ -182,21 +212,26 @@ transform (SHA512_CONTEXT *hd, const unsigned char *data) + } + #endif + +-#define ROTR(x,n) (((x)>>(n)) | ((x)<<(64-(n)))) +-#define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z))) +-#define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) +-#define Sum0(x) (ROTR((x),28) ^ ROTR((x),34) ^ ROTR((x),39)) +-#define Sum1(x) (ROTR((x),14) ^ ROTR((x),18) ^ ROTR((x),41)) + #define S0(x) (ROTR((x),1) ^ ROTR((x),8) ^ ((x)>>7)) + #define S1(x) (ROTR((x),19) ^ ROTR((x),61) ^ ((x)>>6)) + + for (t = 16; t < 80; t++) + w[t] = S1 (w[t - 2]) + w[t - 7] + S0 (w[t - 15]) + w[t - 16]; + +- for (t = 0; t < 80; t++) ++ ++ for (t = 0; t < 80; ) + { + u64 t1, t2; + ++ /* Performance on a AMD Athlon(tm) Dual Core Processor 4050e ++ with gcc 4.3.3 using gcry_md_hash_buffer of each 10000 bytes ++ initialized to 0,1,2,3...255,0,... and 1000 iterations: ++ ++ Not unrolled with macros: 440ms ++ Unrolled with macros: 350ms ++ Unrolled with inline: 330ms ++ */ ++#if 0 /* Not unrolled. */ + t1 = h + Sum1 (e) + Ch (e, f, g) + k[t] + w[t]; + t2 = Sum0 (a) + Maj (a, b, c); + h = g; +@@ -207,12 +242,53 @@ transform (SHA512_CONTEXT *hd, const unsigned char *data) + c = b; + b = a; + a = t1 + t2; +- +- /* printf("t=%d a=%016llX b=%016llX c=%016llX d=%016llX " +- "e=%016llX f=%016llX g=%016llX h=%016llX\n",t,a,b,c,d,e,f,g,h); */ ++ t++; ++#else /* Unrolled to interweave the chain variables. */ ++ t1 = h + Sum1 (e) + Ch (e, f, g) + k[t] + w[t]; ++ t2 = Sum0 (a) + Maj (a, b, c); ++ d += t1; ++ h = t1 + t2; ++ ++ t1 = g + Sum1 (d) + Ch (d, e, f) + k[t+1] + w[t+1]; ++ t2 = Sum0 (h) + Maj (h, a, b); ++ c += t1; ++ g = t1 + t2; ++ ++ t1 = f + Sum1 (c) + Ch (c, d, e) + k[t+2] + w[t+2]; ++ t2 = Sum0 (g) + Maj (g, h, a); ++ b += t1; ++ f = t1 + t2; ++ ++ t1 = e + Sum1 (b) + Ch (b, c, d) + k[t+3] + w[t+3]; ++ t2 = Sum0 (f) + Maj (f, g, h); ++ a += t1; ++ e = t1 + t2; ++ ++ t1 = d + Sum1 (a) + Ch (a, b, c) + k[t+4] + w[t+4]; ++ t2 = Sum0 (e) + Maj (e, f, g); ++ h += t1; ++ d = t1 + t2; ++ ++ t1 = c + Sum1 (h) + Ch (h, a, b) + k[t+5] + w[t+5]; ++ t2 = Sum0 (d) + Maj (d, e, f); ++ g += t1; ++ c = t1 + t2; ++ ++ t1 = b + Sum1 (g) + Ch (g, h, a) + k[t+6] + w[t+6]; ++ t2 = Sum0 (c) + Maj (c, d, e); ++ f += t1; ++ b = t1 + t2; ++ ++ t1 = a + Sum1 (f) + Ch (f, g, h) + k[t+7] + w[t+7]; ++ t2 = Sum0 (b) + Maj (b, c, d); ++ e += t1; ++ a = t1 + t2; ++ ++ t += 8; ++#endif + } + +- /* update chaining vars */ ++ /* Update chaining vars. */ + hd->h0 += a; + hd->h1 += b; + hd->h2 += c; +diff --git a/grub-core/lib/libgcrypt/cipher/test-getrusage.c b/grub-core/lib/libgcrypt/cipher/test-getrusage.c +new file mode 100644 +index 0000000..479eaab +--- /dev/null ++++ b/grub-core/lib/libgcrypt/cipher/test-getrusage.c +@@ -0,0 +1,105 @@ ++#include ++#include ++#include ++ ++int ++main (int argc, char **argv) ++{ ++ struct rusage buf; ++ ++ if (argc > 1) ++ { ++ system (argv[1]); ++ ++ if (getrusage (RUSAGE_CHILDREN, &buf )) ++ { ++ perror ("getrusage"); ++ return 1; ++ } ++ } ++ else ++ { ++ if (getrusage (RUSAGE_SELF, &buf )) ++ { ++ perror ("getrusage"); ++ return 1; ++ } ++ } ++ ++ printf ("ru_utime = %ld.%06ld\n", ++ buf.ru_utime.tv_sec, buf.ru_utime.tv_usec); ++ printf ("ru_stime = %ld.%06ld\n", ++ buf.ru_stime.tv_sec, buf.ru_stime.tv_usec); ++ printf ("ru_maxrss = %ld\n", buf.ru_maxrss ); ++ printf ("ru_ixrss = %ld\n", buf.ru_ixrss ); ++ printf ("ru_idrss = %ld\n", buf.ru_idrss ); ++ printf ("ru_isrss = %ld\n", buf.ru_isrss ); ++ printf ("ru_minflt = %ld\n", buf.ru_minflt ); ++ printf ("ru_majflt = %ld\n", buf.ru_majflt ); ++ printf ("ru_nswap = %ld\n", buf.ru_nswap ); ++ printf ("ru_inblock = %ld\n", buf.ru_inblock ); ++ printf ("ru_oublock = %ld\n", buf.ru_oublock ); ++ printf ("ru_msgsnd = %ld\n", buf.ru_msgsnd ); ++ printf ("ru_msgrcv = %ld\n", buf.ru_msgrcv ); ++ printf ("ru_nsignals= %ld\n", buf.ru_nsignals ); ++ printf ("ru_nvcsw = %ld\n", buf.ru_nvcsw ); ++ printf ("ru_nivcsw = %ld\n", buf.ru_nivcsw ); ++ ++ fprintf (stderr, "ru_utime ru_stime ru_minflt ru_nccsw ru_nivcsw\n"); ++ fprintf (stderr, "%ld.%06ld %ld.%06ld %5ld %5ld %5ld\n"); ++ ++ ++ return 0; ++} ++ ++ ++/* Codesnippet for debugging in random.c. */ ++#if 0 ++static void ++collect_rusage_stats (struct rusage *rb) ++{ ++ static int idx; ++ static struct rusage buf[100]; ++ ++ if (!rb) ++ { ++ int i; ++ ++ fprintf (stderr, "ru_utime ru_stime ru_minflt ru_nvcsw ru_nivcsw\n"); ++ for (i=0; i < idx; i++) ++ fprintf (stderr, "%ld.%06ld %ld.%06ld %5ld %5ld %5ld\n", ++ buf[i].ru_utime.tv_sec, buf[i].ru_utime.tv_usec, ++ buf[i].ru_stime.tv_sec, buf[i].ru_stime.tv_usec, ++ buf[i].ru_minflt, ++ buf[i].ru_nvcsw, ++ buf[i].ru_nivcsw); ++ } ++ else if (idx < DIM(buf)) ++ { ++ buf[idx++] = *rb; ++ } ++} ++#endif ++/* ++ void ++ _gcry_random_dump_stats() ++ { ++@@ -233,8 +261,11 @@ ++ rndstats.naddbytes, rndstats.addbytes, ++ rndstats.mixkey, rndstats.ngetbytes1, rndstats.getbytes1, ++ rndstats.ngetbytes2, rndstats.getbytes2 ); +++ +++ collect_rusage_stats (NULL); ++ } ++ ++======== ++ ++ getrusage (RUSAGE_SELF, &buf ); +++ collect_rusage_stats (&buf); ++ add_randomness( &buf, sizeof buf, 1 ); ++ memset( &buf, 0, sizeof buf ); ++ } ++ ++*/ ++ ++ +diff --git a/grub-core/lib/libgcrypt/cipher/tiger.c b/grub-core/lib/libgcrypt/cipher/tiger.c +index a620045..4ad6ce5 100644 +--- a/grub-core/lib/libgcrypt/cipher/tiger.c ++++ b/grub-core/lib/libgcrypt/cipher/tiger.c +@@ -1,5 +1,5 @@ + /* tiger.c - The TIGER hash function +- * Copyright (C) 1998, 2001, 2002, 2003 Free Software Foundation, Inc. ++ * Copyright (C) 1998, 2001, 2002, 2003, 2010 Free Software Foundation, Inc. + * + * This file is part of Libgcrypt. + * +@@ -18,25 +18,26 @@ + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + ++/* See http://www.cs.technion.ac.il/~biham/Reports/Tiger/ */ ++ + #include + #include + #include + #include + + #include "g10lib.h" +-#include "memory.h" + #include "cipher.h" + ++/* We really need a 64 bit type for this code. */ + #ifdef HAVE_U64_TYPEDEF + +-/* we really need it here, but as this is only experiment we +- * can live without Tiger */ +- +-typedef struct { +- u64 a, b, c; +- byte buf[64]; +- int count; +- u32 nblocks; ++typedef struct ++{ ++ u64 a, b, c; ++ byte buf[64]; ++ int count; ++ u32 nblocks; ++ int variant; /* 0 = old code, 1 = fixed code, 2 - TIGER2. */ + } TIGER_CONTEXT; + + +@@ -588,7 +589,7 @@ static u64 sbox4[256] = { + }; + + static void +-tiger_init( void *context ) ++do_init (void *context, int variant) + { + TIGER_CONTEXT *hd = context; + +@@ -597,6 +598,25 @@ tiger_init( void *context ) + hd->c = 0xf096a5b4c3b2e187LL; + hd->nblocks = 0; + hd->count = 0; ++ hd->variant = variant; ++} ++ ++static void ++tiger_init (void *context) ++{ ++ do_init (context, 0); ++} ++ ++static void ++tiger1_init (void *context) ++{ ++ do_init (context, 1); ++} ++ ++static void ++tiger2_init (void *context) ++{ ++ do_init (context, 2); + } + + static void +@@ -763,6 +783,7 @@ tiger_final( void *context ) + TIGER_CONTEXT *hd = context; + u32 t, msb, lsb; + byte *p; ++ byte pad = hd->variant == 2? 0x80 : 0x01; + + tiger_write(hd, NULL, 0); /* flush */; + +@@ -782,13 +803,13 @@ tiger_final( void *context ) + + if( hd->count < 56 ) /* enough room */ + { +- hd->buf[hd->count++] = 0x01; /* pad */ ++ hd->buf[hd->count++] = pad; + while( hd->count < 56 ) + hd->buf[hd->count++] = 0; /* pad */ + } + else /* need one extra block */ + { +- hd->buf[hd->count++] = 0x01; /* pad character */ ++ hd->buf[hd->count++] = pad; /* pad character */ + while( hd->count < 64 ) + hd->buf[hd->count++] = 0; + tiger_write(hd, NULL, 0); /* flush */; +@@ -815,10 +836,24 @@ tiger_final( void *context ) + *p++ = hd->a >> 24; *p++ = hd->a >> 16; \ + *p++ = hd->a >> 8; *p++ = hd->a; } while(0) + #endif +- X(a); +- X(b); +- X(c); ++#define Y(a) do { *p++ = hd->a ; *p++ = hd->a >> 8; \ ++ *p++ = hd->a >> 16; *p++ = hd->a >> 24; \ ++ *p++ = hd->a >> 32; *p++ = hd->a >> 40; \ ++ *p++ = hd->a >> 48; *p++ = hd->a >> 56; } while(0) ++ if (hd->variant == 0) ++ { ++ X(a); ++ X(b); ++ X(c); ++ } ++ else ++ { ++ Y(a); ++ Y(b); ++ Y(c); ++ } + #undef X ++#undef Y + } + + static byte * +@@ -829,22 +864,47 @@ tiger_read( void *context ) + return hd->buf; + } + +-static byte asn[19] = /* Object ID is 1.3.6.1.4.1.11591.12.2 */ ++ ++ ++/* This is the old TIGER variant based on the unfixed reference ++ implementation. IT was used in GnupG up to 1.3.2. We don't provide ++ an OID anymore because that would not be correct. */ ++gcry_md_spec_t _gcry_digest_spec_tiger = ++ { ++ "TIGER192", NULL, 0, NULL, 24, ++ tiger_init, tiger_write, tiger_final, tiger_read, ++ sizeof (TIGER_CONTEXT) ++ }; ++ ++ ++ ++/* This is the fixed TIGER implementation. */ ++static byte asn1[19] = /* Object ID is 1.3.6.1.4.1.11591.12.2 */ + { 0x30, 0x29, 0x30, 0x0d, 0x06, 0x09, 0x2b, 0x06, + 0x01, 0x04, 0x01, 0xda, 0x47, 0x0c, 0x02, + 0x05, 0x00, 0x04, 0x18 }; + +-static gcry_md_oid_spec_t oid_spec_tiger[] = ++static gcry_md_oid_spec_t oid_spec_tiger1[] = + { + /* GNU.digestAlgorithm TIGER */ + { "1.3.6.1.4.1.11591.12.2" }, + { NULL } + }; + +-gcry_md_spec_t _gcry_digest_spec_tiger = ++gcry_md_spec_t _gcry_digest_spec_tiger1 = + { +- "TIGER192", asn, DIM (asn), oid_spec_tiger, 24, +- tiger_init, tiger_write, tiger_final, tiger_read, ++ "TIGER", asn1, DIM (asn1), oid_spec_tiger1, 24, ++ tiger1_init, tiger_write, tiger_final, tiger_read, ++ sizeof (TIGER_CONTEXT) ++ }; ++ ++ ++ ++/* This is TIGER2 which usues a changed padding algorithm. */ ++gcry_md_spec_t _gcry_digest_spec_tiger2 = ++ { ++ "TIGER2", NULL, 0, NULL, 24, ++ tiger2_init, tiger_write, tiger_final, tiger_read, + sizeof (TIGER_CONTEXT) + }; + +diff --git a/grub-core/lib/libgcrypt/cipher/twofish.c b/grub-core/lib/libgcrypt/cipher/twofish.c +index 5274c40..68b2c7a 100644 +--- a/grub-core/lib/libgcrypt/cipher/twofish.c ++++ b/grub-core/lib/libgcrypt/cipher/twofish.c +@@ -522,7 +522,7 @@ static byte calc_sb_tbl[512] = { + * preprocessed through q0 and q1 respectively; for longer keys they are the + * output of previous stages. j is the index of the first key byte to use. + * CALC_K computes a pair of subkeys for 128-bit Twofish, by calling CALC_K_2 +- * twice, doing the Psuedo-Hadamard Transform, and doing the necessary ++ * twice, doing the Pseudo-Hadamard Transform, and doing the necessary + * rotations. Its parameters are: a, the array to write the results into, + * j, the index of the first output entry, k and l, the preprocessed indices + * for index 2i, and m and n, the preprocessed indices for index 2i+1. +diff --git a/grub-core/lib/libgcrypt/cipher/whirlpool.c b/grub-core/lib/libgcrypt/cipher/whirlpool.c +index 9b029ee..e6c226c 100644 +--- a/grub-core/lib/libgcrypt/cipher/whirlpool.c ++++ b/grub-core/lib/libgcrypt/cipher/whirlpool.c +@@ -36,7 +36,6 @@ + + #include "types.h" + #include "g10lib.h" +-#include "memory.h" + #include "cipher.h" + + #include "bithelp.h" +diff --git a/grub-core/lib/libgcrypt/mpi/ChangeLog-2011 b/grub-core/lib/libgcrypt/mpi/ChangeLog-2011 +new file mode 100644 +index 0000000..1e07872 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/ChangeLog-2011 +@@ -0,0 +1,831 @@ ++2011-12-01 Werner Koch ++ ++ NB: ChangeLog files are no longer manually maintained. Starting ++ on December 1st, 2011 we put change information only in the GIT ++ commit log, and generate a top-level ChangeLog file from logs at ++ "make dist". See doc/HACKING for details. ++ ++2011-07-04 Werner Koch ++ ++ * longlong.h (add_ssaaaa) [__arm__]: Do no use asm if thumb code ++ generation is enabled. This is bug#1202. Reported for gpg 1.4. ++ ++2011-03-28 Werner Koch ++ ++ * mpi-pow.c (gcry_mpi_powm): Remove unused var RSEC. ++ ++2011-02-01 Werner Koch ++ ++ * mpi-cmp.c (gcry_mpi_cmp): Allow comparing of opaque MPIs. ++ ++2010-04-12 Brad Hards (wk) ++ ++ Spelling fixes. ++ ++2010-02-22 Aurelien Jarno (wk) ++ ++ * longlong.h (umul_ppmm) [__GNUC__ >= 4.4]: Patch according ++ to recommended gcc 4.4 changes. ++ ++2009-12-09 Werner Koch ++ ++ * config.links: Remove asm modules for all sparc64. This is ++ debian#560028. ++ ++2009-05-26 Werner Koch ++ ++ * mpicoder.c (mpi_read_from_buffer): Allow zero-sized MPIs (i.e a ++ zero). ++ ++2009-02-16 Werner Koch ++ ++ * mpiutil.c: Remove memory.h. ++ ++2008-12-05 Werner Koch ++ ++ * mpicoder.c (mpi_read_from_buffer): Do not bail out if the mpi is ++ larger than the buffer (potential problem). Do not print error ++ messages. ++ (mpi_fromstr): Return an error instead of hitting an assert. ++ (gcry_mpi_scan) : Fix potential double free problem. ++ (gcry_mpi_scan) : Fix potential memory leak. ++ (do_get_buffer): Return NULL on memory allocation failure. ++ (gcry_mpi_print): Check result of do_get_buffer. ++ (gcry_mpi_aprint): Return error on a memory allocation failure. ++ ++ * mpicoder.c: Re-indent. ++ ++2008-12-03 Werner Koch ++ ++ * mpi-pow.c (gcry_mpi_powm): Fix last change. Asserts are really ++ useful! ++ ++2008-12-02 Werner Koch ++ ++ * mpi-pow.c (gcry_mpi_powm): Re-indent. ++ (gcry_mpi_powm): Simplified allocation of the result to fix a ++ double free bug. This is bug#977. Reported by Haakon Ringberg. ++ ++2008-08-20 Werner Koch ++ ++ * mpi-bit.c (gcry_mpi_lshift): Actually implement. ++ ++2008-08-19 Werner Koch ++ ++ * mpi-bit.c (gcry_mpi_lshift): New. ++ ++2007-10-31 Werner Koch ++ ++ * mpi-mod.c (gcry_mpi_mod): Remove ++ * mpi-inv.c (_gcry_mpi_invm): Remove _ prefix. ++ * mpiutil.c (_gcry_mpi_swap): Remove. ++ (_gcry_mpi_new): Remove. ++ (_gcry_mpi_snew): Remove. ++ (gcry_mpi_invm): Remove. ++ (gcry_mpi_copy): Remove and rename _version to this. ++ (gcry_mpi_set, gcry_mpi_set_ui): Merge with _ version. ++ * mpi-inv.c (gcry_mpi_invm): Remove _ prefix and return 1. ++ * mpi-mul.c (gcry_mpi_mul_2exp): Remove and rename _ version to this. ++ ++2007-10-29 Werner Koch ++ ++ * config.links: No Candadian Cross here, thus use $host instead of ++ $target. ++ ++2007-10-26 Werner Koch ++ ++ * config.links (mpi_optional_modules): Special rules for Apple ++ Darwin on ia32 from Gregor Riepl. ++ ++2007-05-09 Marcus Brinkmann ++ ++ * config.links: Rename assembler file links by suffixing "-asm". ++ * Makefile.am (CCASCOMPILE, LTCCASCOMPILE, CLEANFILES, ++ libmpi_la_LIBADD, libmpi_la_DEPENDENCIES, SUFFIXES, .S.o, .S.obj, ++ .S.lo): Removed variables and targets. ++ (mpih_add1, mpih_sub1, mpih_mul1, mpih_mul2, mpih_mul3, ++ mpih_lshift, mpih_rshift, mpih_udiv, mpih_udiv_qrnnd, ++ nodist_libmpi_la_SOURCES): New variables. ++ (DISTCLEANFILES): Rename assembler file links by suffixing "-asm". ++ Add variants for C file links. ++ ++2007-05-04 Werner Koch ++ ++ * config.links (path): Allowthe sue of colons as delimiters. ++ ++2007-05-03 Werner Koch ++ ++ * pentium4/distfiles: Fixed. ++ ++2007-04-30 Werner Koch ++ ++ * config.links: Create a file mod-source-info.h. ++ * Makefile.am (DISTCLEANFILES): Add that file. ++ * mpiutil.c (_gcry_mpi_get_hw_config): New. ++ ++2007-04-28 Marcus Brinkmann ++ ++ * config.links: Add additional assembler search directories. ++ ++2007-03-28 Werner Koch ++ ++ * ec.c: New. ++ ++2007-03-23 Werner Koch ++ ++ * mpi-bit.c (_gcry_mpi_lshift_limbs): Assign AP after the resize. ++ ++ * mpi-div.c (gcry_mpi_mod, _gcry_mpi_mod): Moved to .. ++ * mpi-mod.c: .. new file. ++ (_gcry_mpi_barrett_init, _gcry_mpi_barrett_free): New. ++ (_gcry_mpi_mod_barrett): New. ++ (_gcry_mpi_mul_barrett): New. ++ ++2007-03-22 Werner Koch ++ ++ * mpi-div.c (_gcry_mpi_mod): New. ++ * mpiutil.c (_gcry_mpi_new, _gcry_mpi_snew): New. ++ ++2007-03-13 Werner Dittmann (wk) ++ ++ * amd64/mpih-add1.S, amd64/mpih-add1.S, amd64/mpih-lshift.S ++ * amd64/mpih-mul1.S, amd64/mpih-mul2.S, amd64/mpih-mul3.S ++ * amd64/mpih-rshift.S, amd64/mpih-sub1.S: New. ++ * config.links: Add case for x86_64. ++ ++2007-02-23 Werner Koch ++ ++ * mpi-pow.c (gcry_mpi_powm): Remove unused var ESIGN. ++ ++ * mpiutil.c (gcry_mpi_get_flag): Let it return a value to silent ++ MIPSpro cc warning. ++ ++2007-02-21 Werner Koch ++ ++ * mpicoder.c (_gcry_mpi_set_buffer): Made BUFFER a void*. ++ ++2006-11-15 Werner Koch ++ ++ * Makefile.am (.S.o): Check for srcdir also in in CPP pass. ++ (INCLUDES): Removed. ++ (AM_CPPFLAGS, AM_CFLAGS): New, modified. Merged with Moritz' ++ changes. ++ ++2006-11-05 Moritz Schulte ++ ++ * Makefile.am (AM_CFLAGS): Added -I$(top_builddir)/src so that the ++ new gcrypt.h is used, not the one installed in the system. ++ ++2006-10-23 Werner Koch ++ ++ * config.links (mpi_optional_modules): Make sure that powerpc64 is ++ matched before a generic powerpc. Reported by Andreas Metzler. ++ Should fix Debian bug 284609. ++ ++2006-08-25 Werner Koch ++ ++ * mpi-bit.c (gcry_mpi_rshift): Don't shift if N == 0 but do a ++ plain copy. ++ ++2006-08-04 Werner Koch ++ ++ * mpi-bit.c (gcry_mpi_rshift): Rewritten to remove the limitation ++ on N (which used to be less than BITS_PER_MPI_LIMB). ++ ++2006-08-03 Werner Koch ++ ++ * mpi-bit.c (gcry_mpi_set_bit, gcry_mpi_set_highbit): Fixed ++ allocation. Reported by bpgcrypt at itaparica.org. ++ * mpiutil.c (_gcry_mpi_resize): Clear the new part of the resized ++ limb space. ++ ++2006-07-26 Werner Koch ++ ++ * mpiutil.c (gcry_mpi_randomize): Changed P to unsigned char*. ++ ++ * mpicoder.c (gcry_mpi_scan): Changed arg BUFFER to void*. ++ (mpi_read_from_buffer): Made BUFFER arg const. ++ (gcry_mpi_scan): Removed now needless cast. Add cast for arg to ++ mpi_fromstr. ++ (gcry_mpi_print): Made TMP unsigned. ++ ++ * Makefile.am (AM_CCASFLAGS): New. ++ ++2005-10-09 Moritz Schulte ++ ++ * mpi-cmp.c (gcry_mpi_cmp_ui): Rewritten; correctly handle case of ++ zero limbs in U. ++ ++2005-04-27 Moritz Schulte ++ ++ * mpiutil.c (gcry_mpi_randomize): Store random data in secure ++ memory if the given MPI is secure - not the other way around (argl). ++ ++2005-04-23 Moritz Schulte ++ ++ * Makefile.am: Don't assume the compiler will pre-process the .S ++ files. Some compilers, like those from HP and IBM, don't do ++ this. So, we use the same solution gnupg-1.4.0 does. Preprocess ++ first and then compile. ++ ++ * hppa1.1/mpih-mul3.S: Add "level 1.1" directive to disable ++ warning about using PA-RISC1.1 opcodes. ++ * hppa1.1/mpih-mul2.S: Likewise. ++ * hppa1.1/mpih-mul1.S: Likewise. ++ * hppa1.1/udiv-qrnnd.S: Likewise. ++ ++2005-02-16 Moritz Schulte ++ ++ * mpiutil.c (_gcry_mpi_alloc_limb_space): Rewritten, fixed memory ++ corruption. ++ ++2005-02-06 Moritz Schulte ++ ++ * mpiutil.c (_gcry_mpi_get_ui, gcry_mpi_get_ui): New functions. ++ ++2005-01-05 Werner Koch ++ ++ * hppa1.1/udiv-qrnnd.S: Reverted change of 2004-03-02 but kept the ++ .align directive. ++ ++2004-12-16 Werner Koch ++ ++ * config.links (mpi_optional_modules): Move entry for powerpc64 ++ before generic powerpc. Suggested by Rafael Ávila de Espíndola. ++ ++2004-03-02 Werner Koch ++ ++ * hppa1.1/udiv-qrnnd.S: Alignment fix from Lamont Jones for ++ Debian. Taken from gnupg-1.3. ++ ++ * longlong.h: Added PowerPC 64 bit code from GPM-4.1.2 but didn't ++ enable it yet. Some whitespace changes in HPPA to fix assembler ++ problems on HP-UX. From gnupg 1.3 ++ ++ * mpiutil.c (_gcry_mpi_alloc_limb_space): Better allocate ++ something even if NLIMBS is passed as 0. ++ ++ * config.links: Updated system list to match gnupg 1.3. ++ ++2003-12-19 Werner Koch ++ ++ * mpi-internal.h [M_DEBUG]: Removed this unused code. ++ (struct karatsuba_ctx): Added TSPACE_NLIMBS and TP_NLIMBS. ++ * mpiutil.c (_gcry_mpi_free_limb_space): Add arg NLIMBS and wipe ++ out the memory. Changed all callers. ++ * mpih-mul.c (_gcry_mpih_mul_karatsuba_case): Keep track of ++ allocated limbs. ++ * mpi-div.c (_gcry_mpi_tdiv_qr): Keep track of allocated limbs. ++ * mpi-mul.c (gcry_mpi_mul): Ditto. ++ * mpi-pow.c (gcry_mpi_powm): Ditto. ++ ++ * Manifest: Empty new file. Also add Manifest files to all CPU ++ specific directories. ++ * Makefile.am: Added. ++ ++ * mpiutil.c (gcry_mpi_randomize): Use gcry_create_nonce if WEAK ++ random has been requested. ++ ++2003-10-31 Werner Koch ++ ++ * i386/mpih-rshift.S, i386/mpih-lshift.S: Use %dl and not %edx for ++ testb; this avoids an assembler warning. ++ ++ * mpi-pow.c (gcry_mpi_powm): s/exp/expo/ to avoid shadowing warning. ++ ++2003-08-19 Marcus Brinkmann ++ ++ * Makefile.am (SUFFIXES): New variable. ++ (.S.o, .S.lo, .S.obj): Rewritten. ++ ++2003-07-30 Moritz Schulte ++ ++ * longlong.h (__clz_tab): Renamed to _gcry_clz_tab. ++ * mpi-bit.c (__clz_tab): Likewise. ++ ++2003-07-27 Werner Koch ++ ++ * mpicoder.c (gcry_mpi_scan): New argument BUFLEN to replace the ++ use of the intial value of NBYTES. Changed BUFFER to unsigned. ++ (gcry_mpi_print): Likewise. ++ (gcry_mpi_dump): New. ++ (_gcry_log_mpidump): Make use of gcry_mpi_dump. ++ (mpi_print): Removed. ++ (gcry_mpi_scan): Allocated mpi in secure memory when required. ++ (gcry_mpi_aprint): Changed BUFFER to unsigned char*. ++ ++2003-07-14 Moritz Schulte ++ ++ * mpicoder.c: Used gcry_err* wrappers for libgpg-error symbols. ++ ++2003-06-16 Moritz Schulte ++ ++ * mpi-add.c: Replace last occurences of old type names with newer ++ names (i.e. replace MPI with gcry_mpi_t). ++ * mpi-bit.c: Likewise. ++ * mpi-cmp.c: Likewise. ++ * mpi-div.c: Likewise. ++ * mpi-gcd.c: Likewise. ++ * mpi-internal.h: Likewise. ++ * mpi-inv.c: Likewise. ++ * mpi-mpow.c: Likewise. ++ * mpi-mul.c: Likewise. ++ * mpi-pow.c: Likewise. ++ * mpi-scan.c: Likewise. ++ * mpicoder.c: Likewise. ++ * mpiutil.c: Likewise. ++ ++2003-06-09 Moritz Schulte ++ ++ * mpicoder.c (gcry_mpi_scan): Adjust for libgpg-error. ++ (gcry_mpi_print): Likewise. ++ (gcry_mpi_aprint): Likewise. ++ ++2003-06-07 Moritz Schulte ++ ++ * longlong.h, mpi-add.c, mpi-bit.c, mpi-cmp.c, mpi-div.c, ++ mpi-gcd.c, mpi-inline.c, mpi-inline.h, mpi-internal.h, mpi-inv.c, ++ mpi-mpow.c, mpi-mul.c, mpi-pow.c, mpi-scan.c, mpicoder.c, ++ mpih-div.c, mpih-mul.c, mpiutil.c, generic/mpi-asm-defs.h, ++ generic/mpih-add1.c, generic/mpih-lshift.c, generic/mpih-mul1.c, ++ generic/mpih-mul2.c, generic/mpih-mul3.c, generic/mpih-rshift.c, ++ generic/mpih-sub1.c, generic/udiv-w-sdiv.c, i386/syntax.h, ++ m68k/syntax.h, mips3/mpi-asm-defs.h, powerpc32/syntax.h: Edited ++ all preprocessor instructions to remove whitespace before the '#'. ++ This is not required by C89, but there are some compilers out ++ there that don't like it. Replaced any occurence of the now ++ deprecated type names with the new ones. ++ ++2003-05-21 Moritz Schulte ++ ++ * mpiutil.c (_gcry_mpi_alloc_limb_space): Only try to allocate ++ memory in case the amount of bytes to allocate is non-zero. ++ ++2003-04-27 Moritz Schulte ++ ++ * mpiutil.c (_gcry_mpi_resize): Allocate secure memory, in case ++ bit zero of `flags' is set. ++ ++ * mpi-add.c (gcry_mpi_sub): Simplify function; always use a ++ temporary variable now. ++ ++2003-04-15 Werner Koch ++ ++ * longlong.h (umul_ppmm): Support SH3 and SH4. Thanks to ++ kazuya.s@jp.yokogawa.com. ++ ++2003-04-02 Werner Koch ++ ++ * mpicoder.c (gcry_mpi_print): Fixed testing against possible ++ uninitialized LEN. Valgrinded by Nikos Mavroyanopoulos. ++ ++2003-01-15 Werner Koch ++ ++ * longlong.h: Removed some spaces between backslashes and newlines. ++ ++2002-09-20 Werner Koch ++ ++ * mpi-mul.c (gcry_mpi_mul_2exp): New. This was declared in ++ gcrypt.h but only implemented as internal function. Noted by Timo ++ but a few minutes to late for today's release. ++ ++ * Makefile.am (DISTCLEANFILES): Include mpi-asm-defs.h ++ ++2002-09-18 Werner Koch ++ ++ * Makefile.am (.S.lo): Pass -DPIC. i386, PPC and Sparc code ++ require it. It worked for me because I am using the i586 code. ++ ++2002-08-23 Werner Koch ++ ++ * Makefile.am (.S.lo): Fixed for libtool build with --disable-shared. ++ ++2002-07-24 Werner Koch ++ ++ * longlong.h: Replaced all K&R multiline strings by ISO ones for ++ the sake of modern compilers. Suggested by Marco Parrone. ++ ++2002-06-24 Werner Koch ++ ++ * mpiutil.c (gcry_mpi_swap): New. ++ ++ * mpi-div.c (gcry_mpi_div): New. ++ (gcry_mpi_mod): New. ++ * mpi-inv.c (gcry_mpi_invm): New. ++ ++ * mpicoder.c (do_get_buffer): Make sure that we allocate at least ++ one byte. ++ ++2002-06-12 Werner Koch ++ ++ * hppa1.1/udiv-qrnnd.S: Changes for PIC by Randolph Chung. ++ ++2002-05-15 Werner Koch ++ ++ * config.links: Chnage the way the mpi modules are determined. ++ * Makefile.am: Revamped to better handle modules ++ ++2002-05-14 Werner Koch ++ ++ Changed license of all files to the LGPL. ++ ++2002-04-18 Werner Koch ++ ++ * mpicoder.c (gcry_mpi_scan): Don't use normalize on a NULL MPI. ++ ++2002-03-20 Werner Koch ++ ++ * mpicoder.c (mpi_read_from_buffer): Bail out on a zero length ++ buffer because we can't eventually do an malloc of this size. ++ Reported by Timo. ++ ++2002-01-14 Werner Koch ++ ++ * mpi-inv.c (_gcry_mpi_invm): Typo fixes, noted by Carlo Perassi. ++ ++2001-11-01 Werner Koch ++ ++ * mpicoder.c (gcry_mpi_scan): Allow to pass a nbytes as NULL or ++ with value 0 for format GCRY_FMT_SSH, so that the length is not ++ used for any checks, only the length stored in the bufer is used. ++ This is a nice format becuase we can just pass a buffer around and ++ don't need to care about its length. ++ ++2001-08-03 Werner Koch ++ ++ * config.links: Changed the way the list of files to be ++ symlinked is returned. ++ ++2001-05-31 Werner Koch ++ ++ * mpih-cmp.c: Removed and moved mpihelp_cmp to .. ++ * mpi-inline.h: .. here. ++ ++ Major function renaming. All global functions are now prefixed ++ with _gcry_ or gcry_. Renamed also all mpihelp_ to just mpih_ so ++ that functions names are not getting to long an unreadable and for ++ better matching with the filenames. ++ ++2001-05-28 Werner Koch ++ ++ * mpicoder.c (mpi_fromstr): Made static and assume that all input ++ is in hexformat. ++ ++ Updated all CPU specific code with the one from GnuPG-1.0.5. This ++ is just a change of text formatting and the use of .label ++ instead of labels for hppa and pa7100. ++ ++ * longlong.h: Fixes for ARM by Phil Blundell. ++ ++2001-03-29 Werner Koch ++ ++ * mpi-mul.c (mpi_mul): Make sure that secret temporary results are ++ not stored in w. Suggested by Florian Weimer. ++ ++ * config.links: Use i386 code for i386. According to tests by ++ Kevin Ryde the i586 code runs slow on i386 CPUs. Ditto for i786. ++ ++2001-01-11 Werner Koch ++ ++ * Makefile.am: Removed mpi.h. ++ ++2000-12-19 Werner Koch ++ ++ * mpi-internal.h: Put limb_t definition in an ifdef. ++ ++ Major change: ++ Removed all GnuPG stuff and renamed this piece of software ++ to gcrypt. ++ ++2000-11-14 Werner Koch ++ ++ * mpi-internal.h, mpi.h: Changed the way they are called and ++ introduced DID_MPI_LIMP_TYPEDEF hack. Very ugly, should all be ++ revamped. ++ ++ * Makefile.am (OMIT_DEPENDENCIES): Hack to work around dependency ++ problems. ++ ++2000-10-11 Werner Koch ++ ++ * generic/mpi-asm-defs.h: New. ++ * mips3/mpi-asm-defs.h: New. ++ * config.links: Create a link to one of the above files. ++ ++Fri Jul 28 18:19:11 CEST 2000 Werner Koch ++ ++ * mpicoder.c (gcry_mpi_scan): Normalize the returned MPI. ++ ++Tue Jul 25 17:44:15 CEST 2000 Werner Koch ++ ++ * config.links: Support for powerpc--netbsd by Gabriel Rosenkoetter. ++ ++Mon Jul 17 16:35:47 CEST 2000 Werner Koch ++ ++ * power/: Add all files from GMP for this CPU. Converted comments to ++ CPP comments because some ASes complain about ' in comments. ++ ++ * config.links: Support for BSDI 4.x; by Wayne Chapeskie. Add support ++ for FreeBSD 5 and made the case stmt looking nicer; by Jun Kuriyama. ++ Add support for NetBSD. ++ (sparc8): Made the search path the same as sparc9 ++ (sparc64-unknown-linux-gnu): use udiv module; by Adam Mitchell. ++ ++ * Makefile.am: c/SFLAGS/ASFLAGS/. This has only been used by the ++ powerpc and actually never passed the -Wa,foo to the cc. ++ ++ * mpih-div.c (mpihelp_divrem): The MPN_COPY_DECR copied one element ++ too many. This is a gmp2.0.2p9.txt patch. ++ ++ * longlong.h (umul_ppmm): Fixes for ARM-4. By Sean MacLennan. ++ ++ * mpi-internal.h (karatsuba_ctx): New. ++ * mpih-mul.c (mpihelp_release_karatsuba_ctx): New. ++ (mpihelp_mul_karatsuba_case): New. ++ (mpihelp_mul): Splitted to make use of the new functions. ++ * mpi-pow.c (mpi_powm): Make use of the new splitted function to avoid ++ multiple allocation of temporary memory during the karatsuba operations. ++ * mpi_mpow.c: Removed the unused Barrett code. ++ ++2000-03-21 16:17:30 Werner Koch (wk@habibti.openit.de) ++ ++ * config.links: Add support for FreeBSD 5. ++ ++Mon Jan 24 22:24:38 CET 2000 Werner Koch ++ ++ * mpicoder.c (gcry_mpi_aprint): Now really returns the length. ++ ++Mon Jan 24 13:04:28 CET 2000 Werner Koch ++ ++ * mpiutil.c: Removed all memory debugging code. ++ ++ * mpicoder.c (gcry_mpi_aprint): New. ++ ++ * Replaced all m_ memory functions by g10_ ones. ++ ++Fri Dec 31 14:06:56 CET 1999 Werner Koch ++ ++ * mpi-bit.c (gcry_mpi_get_nbits): New. ++ ++ * mpiutil.c (mpi_set_secure): made static. ++ (gcry_mpi_get_flag): New. ++ (gcry_mpi_set_flag): New. ++ (gcry_mpi_clear_flag): New. ++ (mpi_set_opaque): renamed to gcry_mpi_set_opaque. ++ (mpi_get_opaque): renamed to gcry_mpi_get_opaque. ++ ++Fri Dec 31 12:48:31 CET 1999 Werner Koch ++ ++ * mpicoder.c (mpi_read_from_buffer): Made static. ++ (gcry_mpi_print): A buffer of NULL is now allowed to get the required ++ length back. ++ (mpi_get_keyid): Removed. ++ (mpi_print): Made static - should be removed. ++ ++Wed Dec 8 21:58:32 CET 1999 Werner Koch ++ ++ * Makefile.am (INCLUDES): Add ../gcrypt. ++ ++ * g10m.c : Removed. ++ ++ * mpicoder.c (mpi_write): Removed. ++ (mpi_read): Removed. ++ (gcry_mpi_scan): New. Taken from ../gcrypt/mpiapi.c. ++ (gcry_mpi_print): Ditto. ++ ++ * mpi-pow.c (mpi_powm): Renamed to ... ++ (gcry_mpi_powm): ... this. ++ ++ * mpiutil.c (gcry_mpi_new): New as a wrapper around the old function. ++ Taken from ../gcrypt/mpiapi.c. ++ (gcry_mpi_snew): Ditto. ++ (gcry_mpi_release): Ditto. ++ (gcry_mpi_copy): Ditto. ++ (gcry_mpi_set): Ditto. ++ (gcry_mpi_set_ui): Ditto. ++ (gcry_mpi_cmp): Ditto. ++ (gcry_mpi_cmp_ui): Ditto. ++ (gcry_mpi_randomize): Ditto. ++ ++ * mpicoder.c (mpi_print): Removed the nbit_info kludge. ++ * mpi-bits.c (mpi_get_nbits): Replaced the is_protected stuff by ++ checking whether it is an opaque mpi and then returns it's length ++ in bits. ++ * mpiutil.c (mpi_set_opaque): Changed the interface to take a number ++ of bits for the length. Adjusted all users. ++ (mpi_get_opaque): Ditto. ++ ++Fri Nov 19 17:15:20 CET 1999 Werner Koch ++ ++ * mpicoder.c (g10_log_mpidump): Add a temporary workaround ++ ++ * mpih-mul.c (mpihelp_mul_n): s/m_is_ecure/g10_is_secure/ ++ ++ * mpiutil.c (mpi_alloc): Remved the debug mode because it has turned ++ out, that this feature was not very useful in the past. Use the ++ new alloc functions. ++ (mpi_alloc_secure): Ditto. ++ (mpi_alloc_limb_space): Ditto. ++ (mpi_free_limb_space): Ditto. ++ (mpi_resize): Ditto. ++ (mpi_free): Ditto. ++ (mpi_set_secure): Removed the debug stuff. ++ (mpi_set_opaque): Ditto. ++ (mpi_copy): Ditto. ++ (mpi_alloc_set_ui): Ditto. ++ (mpi_m_check): Use g10_ wrapper. ++ ++Mon Aug 30 20:38:33 CEST 1999 Werner Koch ++ ++ ++ * config.links: Add case label for DJGPP ++ ++Wed Jul 14 19:42:08 CEST 1999 Werner Koch ++ ++ ++ * Makefile.am: Use .s files as temporaries, disabled other .S rules. ++ ++Wed Jul 7 13:08:40 CEST 1999 Werner Koch ++ ++ ++ * mpicoder.c (g10_log_mpidump): New. ++ ++ * Makefile.am: Support for libtool. ++ ++Fri Jul 2 11:45:54 CEST 1999 Werner Koch ++ ++ ++ * mpi-bit.c (mpi_lshift_limbs,mpi_rshift_limbs): New. ++ * mpi-mpow.c (barrett_mulm): New but diabled. ++ ++Tue Jun 1 16:01:46 CEST 1999 Werner Koch ++ ++ * config.links (i[56]86*-*-freebsdelf*): New. ++ ++Sun May 23 14:20:22 CEST 1999 Werner Koch ++ ++ * config.links (sysdep.h): Not any more conditionally created. ++ ++Tue May 4 15:47:53 CEST 1999 Werner Koch ++ ++ * mpiutil.c (mpi_alloc_like): New. ++ ++Mon Apr 26 17:48:15 CEST 1999 Werner Koch ++ ++ * mpih-add.c, mpih-sub.c: Removed ++ * mpi-inline.c: New. ++ * mpi-inline.h: Make it usable by mpi-inline.c. ++ ++Sun Apr 18 10:11:28 CEST 1999 Werner Koch ++ ++ * mpih-mul.c (mpihelp_mul_n): Fixed use of memory region. ++ (mpihelp_mul): Ditto. ++ ++Wed Apr 7 20:51:39 CEST 1999 Werner Koch ++ ++ * Makefile.am: Explicit rules to invoke cpp on *.S ++ ++Mon Mar 8 20:47:17 CET 1999 Werner Koch ++ ++ * config.links: Take advantage of the with_symbol_underscore macro. ++ Add support for freebsd 4. ++ ++Wed Feb 24 11:07:27 CET 1999 Werner Koch ++ ++ * mips3/mpih-sub1.S: Removed left over junk in last line. (Should I ++ blame me or my editor?). ++ ++Sat Feb 13 12:04:43 CET 1999 Werner Koch ++ ++ * Makefile.am: Removed the +=. Add MPI_OPT_FLAGS. ++ ++Sat Jan 9 16:02:23 CET 1999 Werner Koch ++ ++ * mpi-cmp.c (mpi_cmp_ui): Normalized the arg. ++ ++Thu Jan 7 18:00:58 CET 1999 Werner Koch ++ ++ * mpi-bit.c (mpi_normalize): New. ++ (mpi_get_nbits): Normalize the MPI. ++ * mpi-bit.c (mpi_cmp): Normalize the MPI before the compare. ++ ++ ++Tue Dec 8 13:15:16 CET 1998 Werner Koch ++ ++ * config.links: Moved the case for powerpc*linux ++ * powerpcp32/*.S: Removed some underscores. ++ ++Thu Nov 26 07:27:52 1998 Werner Koch ++ ++ * config.links: Support for ppc with ELF ++ * powerpc32/syntax.h: New. ++ * powerpc32/*.S: Applied ELF patches (glibc patches) ++ ++Tue Nov 10 19:31:37 1998 Werner Koch (wk@isil.d.shuttle.de) ++ ++ * power*/ : Started with stuff for PPC ++ * config.links: Some stuff for PPC. ++ * generic/udiv-w-sdiv.c: New but disabled. ++ ++Tue Oct 27 12:37:46 1998 Werner Koch (wk@isil.d.shuttle.de) ++ ++ * config.links (freebsd): Fixes for FreeBSD 3.0 ++ ++Wed Oct 14 09:59:30 1998 Werner Koch (wk@isil.d.shuttle.de) ++ ++ * config.links (freebsd): ELF patches from Jun Kuriyama. ++ ++Thu Oct 8 13:28:17 1998 Werner Koch (wk@isil.d.shuttle.de) ++ ++ * mpi-mpow.c (mpi_mulpowm): Fixed mem leak (m_free/mpi_free). ++ ++Thu Sep 17 18:08:50 1998 Werner Koch (wk@(none)) ++ ++ * hppa1.1/udiv-qrnnd.S: Fix from Steffen Zahn for HPUX 10.20 ++ ++Thu Aug 6 16:39:28 1998 Werner Koch,mobil,,, (wk@tobold) ++ ++ * mpi-bit.c (mpi_set_bytes): Removed. ++ ++Wed Aug 5 15:11:12 1998 Werner Koch (wk@(none)) ++ ++ * mpicoder.c (mpi_read_from_buffer): New. ++ ++ * mpiutil.c (mpi_set_opaque): New. ++ (mpi_get_opaque): New. ++ (mpi_copy): Changed to support opauqe flag ++ (mpi_free): Ditto. ++ ++Sat Jul 4 10:11:11 1998 Werner Koch (wk@isil.d.shuttle.de) ++ ++ * mpiutil.c (mpi_clear): Reset flags. ++ (mpi_set): Ditto. ++ (mpi_alloc_secure): Set flag to 1 and not ored the 1 in, tsss.. ++ ++Fri Jun 26 11:19:06 1998 Werner Koch (wk@isil.d.shuttle.de) ++ ++ * mpiutil.c (mpi_alloc): set nbits to 0. ++ (mpi_alloc_secure): Ditto. ++ (mpi_clear): Ditto. ++ ++Thu Jun 25 11:50:01 1998 Werner Koch (wk@isil.d.shuttle.de) ++ ++ * mips3/*.S: New ++ ++Mon May 18 13:47:06 1998 Werner Koch (wk@isil.d.shuttle.de) ++ ++ * config.links: split mpih-shift into mpih-[lr]shift and ++ changed all implementations. ++ * mpi/alpha: add some new assembler stuff. ++ ++Wed May 13 11:04:29 1998 Werner Koch (wk@isil.d.shuttle.de) ++ ++ * config.links: Add support for MIPS ++ ++Thu Apr 9 11:31:36 1998 Werner Koch (wk@isil.d.shuttle.de) ++ ++ * mpicoder.c (mpi_get_secure_buffer): New. ++ ++Wed Apr 8 09:44:33 1998 Werner Koch (wk@isil.d.shuttle.de) ++ ++ * config.links: Applied small fix from Ulf Möller. ++ ++Mon Apr 6 12:38:52 1998 Werner Koch (wk@isil.d.shuttle.de) ++ ++ * mpicoder.c (mpi_get_buffer): Removed returned leading zeroes ++ and changed all callers. ++ ++Tue Mar 10 13:40:34 1998 Werner Koch (wk@isil.d.shuttle.de) ++ ++ * mpi-bit.c (mpi_clear_highbit): New. ++ ++Mon Mar 2 19:29:00 1998 Werner Koch (wk@isil.d.shuttle.de) ++ ++ * Makefile.am (DISTCLEANFILES): New ++ ++Thu Feb 26 06:48:54 1998 Werner Koch (wk@isil.d.shuttle.de) ++ ++ * config.links (X86_BROKEN_ALIGN): Added for some systems. ++ ++Mon Feb 23 12:21:40 1998 Werner Koch (wk@isil.d.shuttle.de) ++ ++ * mpi/m68k/mpih-shift.S (Lspecial): Changed duplicate symbol. ++ ++Mon Feb 16 13:00:27 1998 Werner Koch (wk@isil.d.shuttle.de) ++ ++ * config.links : Add detection of m68k cpus ++ ++ ++ Copyright 1998,1999,2000,2001,2002,2003 Free Software Foundation, Inc. ++ ++ This file is free software; as a special exception the author gives ++ unlimited permission to copy and/or distribute it, with or without ++ modifications, as long as this notice is preserved. ++ ++ This file 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. ++ ++Local Variables: ++buffer-read-only: t ++End: +diff --git a/grub-core/lib/libgcrypt/mpi/Makefile.am b/grub-core/lib/libgcrypt/mpi/Makefile.am +new file mode 100644 +index 0000000..e900539 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/Makefile.am +@@ -0,0 +1,177 @@ ++## Process this file with automake to produce Makefile.in ++# Copyright (C) 1992, 1999, 2000, 2002 Free Software Foundation, Inc. ++# ++# This file is part of Libgcrypt. ++# ++# Libgcrypt is free software; you can redistribute it and/or modify ++# it under the terms of the GNU Lesser General Public License as ++# published by the Free Software Foundation; either version 2.1 of ++# the License, or (at your option) any later version. ++# ++# Libgcrypt 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 Lesser General Public License for more details. ++# ++# You should have received a copy of the GNU Lesser General Public ++# License along with this program; if not, write to the Free Software ++# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ ++# 1.5 leads to a combinatorial explosion due to all the conditionals ++# I was not able to build it with 64Megs - 1.6 fixes this. ++# not anymore required: AUTOMAKE_OPTIONS = 1.6 ++ ++# Need to include ../src in addition to top_srcdir because gcrypt.h is ++# a built header. ++AM_CPPFLAGS = -I../src -I$(top_srcdir)/src ++AM_CFLAGS = $(GPG_ERROR_CFLAGS) ++ ++AM_ASFLAGS = $(MPI_SFLAGS) ++AM_CCASFLAGS = $(NOEXECSTACK_FLAGS) ++ ++EXTRA_DIST = Manifest config.links ++DISTCLEANFILES = mpi-asm-defs.h \ ++ mpih-add1-asm.S mpih-mul1-asm.S mpih-mul2-asm.S mpih-mul3-asm.S \ ++ mpih-lshift-asm.S mpih-rshift-asm.S mpih-sub1-asm.S asm-syntax.h \ ++ mpih-add1.c mpih-mul1.c mpih-mul2.c mpih-mul3.c \ ++ mpih-lshift.c mpih-rshift.c mpih-sub1.c \ ++ sysdep.h mod-source-info.h ++ ++# Beware: The following list is not a comment but grepped by ++# config.links to get the list of symlinked modules ++# Optional modules are marked with an O in the second column. ++#BEGIN_ASM_LIST ++# mpih-add1 C ++# mpih-sub1 C ++# mpih-mul1 C ++# mpih-mul2 C ++# mpih-mul3 C ++# mpih-lshift C ++# mpih-rshift C ++# udiv O ++# udiv-qrnnd O ++#END_ASM_LIST ++ ++# Note: This function has not yet been implemented. There is only a dummy in ++# generic/ ++# udiv-w-sdiv O ++ ++# And we need to have conditionals for all modules because ++# we don't know whether they are .c or .S. Very ugly; I know. ++# Remember to define them all in configure.ac ++if MPI_MOD_ASM_MPIH_ADD1 ++mpih_add1 = mpih-add1-asm.S ++else ++if MPI_MOD_C_MPIH_ADD1 ++mpih_add1 = mpih-add1.c ++else ++mpih_add1 = ++endif ++endif ++ ++if MPI_MOD_ASM_MPIH_SUB1 ++mpih_sub1 = mpih-sub1-asm.S ++else ++if MPI_MOD_C_MPIH_SUB1 ++mpih_sub1 = mpih-sub1.c ++else ++mpih_sub1 = ++endif ++endif ++ ++if MPI_MOD_ASM_MPIH_MUL1 ++mpih_mul1 = mpih-mul1-asm.S ++else ++if MPI_MOD_C_MPIH_MUL1 ++mpih_mul1 = mpih-mul1.c ++else ++mpih_mul1 = ++endif ++endif ++ ++if MPI_MOD_ASM_MPIH_MUL2 ++mpih_mul2 = mpih-mul2-asm.S ++else ++if MPI_MOD_C_MPIH_MUL2 ++mpih_mul2 = mpih-mul2.c ++else ++mpih_mul2 = ++endif ++endif ++ ++if MPI_MOD_ASM_MPIH_MUL3 ++mpih_mul3 = mpih-mul3-asm.S ++else ++if MPI_MOD_C_MPIH_MUL3 ++mpih_mul3 = mpih-mul3.c ++else ++mpih_mul3 = ++endif ++endif ++ ++if MPI_MOD_ASM_MPIH_LSHIFT ++mpih_lshift = mpih-lshift-asm.S ++else ++if MPI_MOD_C_MPIH_LSHIFT ++mpih_lshift = mpih-lshift.c ++else ++mpih_lshift = ++endif ++endif ++ ++if MPI_MOD_ASM_MPIH_RSHIFT ++mpih_rshift = mpih-rshift-asm.S ++else ++if MPI_MOD_C_MPIH_RSHIFT ++mpih_rshift = mpih-rshift.c ++else ++mpih_rshift = ++endif ++endif ++ ++if MPI_MOD_ASM_UDIV ++udiv = udiv-asm.S ++else ++if MPI_MOD_C_UDIV ++udiv = udiv.c ++else ++udiv = ++endif ++endif ++ ++if MPI_MOD_ASM_UDIV_QRNND ++udiv_qrnnd = udiv-qrnnd-asm.S ++else ++if MPI_MOD_C_UDIV_QRNND ++udiv_qrnnd = udiv-qrnnd.c ++else ++udiv_qrnnd = ++endif ++endif ++ ++noinst_LTLIBRARIES = libmpi.la ++ ++libmpi_la_LDFLAGS = ++nodist_libmpi_la_SOURCES = $(mpih_add1) $(mpih_sub1) $(mpih_mul1) \ ++ $(mpih_mul2) $(mpih_mul3) $(mpih_lshift) $(mpih_rshift) \ ++ $(udiv) $(udiv_qrnnd) ++libmpi_la_SOURCES = longlong.h \ ++ mpi-add.c \ ++ mpi-bit.c \ ++ mpi-cmp.c \ ++ mpi-div.c \ ++ mpi-gcd.c \ ++ mpi-internal.h \ ++ mpi-inline.h \ ++ mpi-inline.c \ ++ mpi-inv.c \ ++ mpi-mul.c \ ++ mpi-mod.c \ ++ mpi-pow.c \ ++ mpi-mpow.c \ ++ mpi-scan.c \ ++ mpicoder.c \ ++ mpih-div.c \ ++ mpih-mul.c \ ++ mpiutil.c \ ++ ec.c +diff --git a/grub-core/lib/libgcrypt/mpi/Manifest b/grub-core/lib/libgcrypt/mpi/Manifest +new file mode 100644 +index 0000000..3b0d673 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/Manifest +@@ -0,0 +1,41 @@ ++# Manifest - checksums of the mpi directory ++# Copyright 2003 Free Software Foundation, Inc. ++# ++# This file is part of Libgcrypt. ++# ++# Libgcrypt is free software; you can redistribute it and/or modify ++# it under the terms of the GNU Lesser general Public License as ++# published by the Free Software Foundation; either version 2.1 of ++# the License, or (at your option) any later version. ++# ++# Libgcrypt 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 Lesser General Public License for more details. ++# ++# You should have received a copy of the GNU Lesser General Public ++# License along with this program; if not, write to the Free Software ++# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ ++Makefile.am ++config.links ++longlong.h ++mpi-add.c ++mpi-bit.c ++mpi-cmp.c ++mpi-div.c ++mpi-gcd.c ++mpi-inline.c ++mpi-inline.h ++mpi-internal.h ++mpi-inv.c ++mpi-mpow.c ++mpi-mul.c ++mpi-pow.c ++mpi-scan.c ++mpicoder.c ++mpih-div.c ++mpih-mul.c ++mpiutil.c ++$names$ iQCVAwUAP+LmfDEAnp832S/7AQKZJQQAkR/gQITUM+6Ygy9WAOAO17btyKAlCtGTXp5XSZ+J3X0o/rYneRdSCW89IJvwFRJjAOcFJd52MXs6ZVFF/RQBC8MvJzuQChbEzvihK8o2VgK34YWjU+6XH9sFgRMIgzkHs/51ZZxeQUOPy1XF7TyKB0WE7YBUVisFiRaqB1qGIOs==Z3qB ++ +diff --git a/grub-core/lib/libgcrypt/mpi/alpha/README b/grub-core/lib/libgcrypt/mpi/alpha/README +new file mode 100644 +index 0000000..55c0a29 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/alpha/README +@@ -0,0 +1,53 @@ ++This directory contains mpn functions optimized for DEC Alpha processors. ++ ++RELEVANT OPTIMIZATION ISSUES ++ ++EV4 ++ ++1. This chip has very limited store bandwidth. The on-chip L1 cache is ++write-through, and a cache line is transfered from the store buffer to the ++off-chip L2 in as much 15 cycles on most systems. This delay hurts ++mpn_add_n, mpn_sub_n, mpn_lshift, and mpn_rshift. ++ ++2. Pairing is possible between memory instructions and integer arithmetic ++instructions. ++ ++3. mulq and umulh is documented to have a latency of 23 cycles, but 2 of ++these cycles are pipelined. Thus, multiply instructions can be issued at a ++rate of one each 21nd cycle. ++ ++EV5 ++ ++1. The memory bandwidth of this chip seems excellent, both for loads and ++stores. Even when the working set is larger than the on-chip L1 and L2 ++caches, the perfromance remain almost unaffected. ++ ++2. mulq has a measured latency of 13 cycles and an issue rate of 1 each 8th ++cycle. umulh has a measured latency of 15 cycles and an issue rate of 1 ++each 10th cycle. But the exact timing is somewhat confusing. ++ ++3. mpn_add_n. With 4-fold unrolling, we need 37 instructions, whereof 12 ++ are memory operations. This will take at least ++ ceil(37/2) [dual issue] + 1 [taken branch] = 20 cycles ++ We have 12 memory cycles, plus 4 after-store conflict cycles, or 16 data ++ cache cycles, which should be completely hidden in the 20 issue cycles. ++ The computation is inherently serial, with these dependencies: ++ addq ++ / \ ++ addq cmpult ++ | | ++ cmpult | ++ \ / ++ or ++ I.e., there is a 4 cycle path for each limb, making 16 cycles the absolute ++ minimum. We could replace the `or' with a cmoveq/cmovne, which would save ++ a cycle on EV5, but that might waste a cycle on EV4. Also, cmov takes 2 ++ cycles. ++ addq ++ / \ ++ addq cmpult ++ | \ ++ cmpult -> cmovne ++ ++STATUS ++ +diff --git a/grub-core/lib/libgcrypt/mpi/alpha/distfiles b/grub-core/lib/libgcrypt/mpi/alpha/distfiles +new file mode 100644 +index 0000000..f2ab9fc +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/alpha/distfiles +@@ -0,0 +1,11 @@ ++README ++mpih-add1.S ++mpih-sub1.S ++mpih-mul1.S ++mpih-mul2.S ++mpih-mul3.S ++mpih-lshift.S ++mpih-rshift.S ++ ++udiv-qrnnd.S ++ +diff --git a/grub-core/lib/libgcrypt/mpi/alpha/mpih-add1.S b/grub-core/lib/libgcrypt/mpi/alpha/mpih-add1.S +new file mode 100644 +index 0000000..50dbb2b +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/alpha/mpih-add1.S +@@ -0,0 +1,124 @@ ++/* alpha add_n -- Add two limb vectors of the same length > 0 and store ++ * sum in a third limb vector. ++ * Copyright (C) 1995, 1998, 2001, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ */ ++ ++ ++ ++/******************* ++ * mpi_limb_t ++ * _gcry_mpih_add_n( mpi_ptr_t res_ptr, ($16) ++ * mpi_ptr_t s1_ptr, ($17) ++ * mpi_ptr_t s2_ptr, ($18) ++ * mpi_size_t size) ($19) ++ */ ++ ++ ++ .set noreorder ++ .set noat ++.text ++ .align 3 ++ .globl _gcry_mpih_add_n ++ .ent _gcry_mpih_add_n ++_gcry_mpih_add_n: ++ .frame $30,0,$26,0 ++ ++ ldq $3,0($17) ++ ldq $4,0($18) ++ ++ subq $19,1,$19 ++ and $19,4-1,$2 # number of limbs in first loop ++ bis $31,$31,$0 ++ beq $2,.L0 # if multiple of 4 limbs, skip first loop ++ ++ subq $19,$2,$19 ++ ++.Loop0: subq $2,1,$2 ++ ldq $5,8($17) ++ addq $4,$0,$4 ++ ldq $6,8($18) ++ cmpult $4,$0,$1 ++ addq $3,$4,$4 ++ cmpult $4,$3,$0 ++ stq $4,0($16) ++ or $0,$1,$0 ++ ++ addq $17,8,$17 ++ addq $18,8,$18 ++ bis $5,$5,$3 ++ bis $6,$6,$4 ++ addq $16,8,$16 ++ bne $2,.Loop0 ++ ++.L0: beq $19,.Lend ++ ++ .align 3 ++.Loop: subq $19,4,$19 ++ ++ ldq $5,8($17) ++ addq $4,$0,$4 ++ ldq $6,8($18) ++ cmpult $4,$0,$1 ++ addq $3,$4,$4 ++ cmpult $4,$3,$0 ++ stq $4,0($16) ++ or $0,$1,$0 ++ ++ ldq $3,16($17) ++ addq $6,$0,$6 ++ ldq $4,16($18) ++ cmpult $6,$0,$1 ++ addq $5,$6,$6 ++ cmpult $6,$5,$0 ++ stq $6,8($16) ++ or $0,$1,$0 ++ ++ ldq $5,24($17) ++ addq $4,$0,$4 ++ ldq $6,24($18) ++ cmpult $4,$0,$1 ++ addq $3,$4,$4 ++ cmpult $4,$3,$0 ++ stq $4,16($16) ++ or $0,$1,$0 ++ ++ ldq $3,32($17) ++ addq $6,$0,$6 ++ ldq $4,32($18) ++ cmpult $6,$0,$1 ++ addq $5,$6,$6 ++ cmpult $6,$5,$0 ++ stq $6,24($16) ++ or $0,$1,$0 ++ ++ addq $17,32,$17 ++ addq $18,32,$18 ++ addq $16,32,$16 ++ bne $19,.Loop ++ ++.Lend: addq $4,$0,$4 ++ cmpult $4,$0,$1 ++ addq $3,$4,$4 ++ cmpult $4,$3,$0 ++ stq $4,0($16) ++ or $0,$1,$0 ++ ret $31,($26),1 ++ ++ .end _gcry_mpih_add_n ++ +diff --git a/grub-core/lib/libgcrypt/mpi/alpha/mpih-lshift.S b/grub-core/lib/libgcrypt/mpi/alpha/mpih-lshift.S +new file mode 100644 +index 0000000..ded4b15 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/alpha/mpih-lshift.S +@@ -0,0 +1,122 @@ ++/* alpha - left shift ++ * ++ * Copyright (C) 1994, 1995, 1998, 2001, ++ * 2002 Free Software Foundation, Inc. ++ * ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ * ++ * Note: This code is heavily based on the GNU MP Library. ++ * Actually it's the same code with only minor changes in the ++ * way the data is stored; this is to support the abstraction ++ * of an optional secure memory allocation which may be used ++ * to avoid revealing of sensitive data due to paging etc. ++ */ ++ ++ ++ ++/******************* ++ * mpi_limb_t ++ * _gcry_mpih_lshift( mpi_ptr_t wp, (r16) ++ * mpi_ptr_t up, (r17) ++ * mpi_size_t usize, (r18) ++ * unsigned cnt) (r19) ++ * ++ * This code runs at 4.8 cycles/limb on the 21064. With infinite unrolling, ++ * it would take 4 cycles/limb. It should be possible to get down to 3 ++ * cycles/limb since both ldq and stq can be paired with the other used ++ * instructions. But there are many restrictions in the 21064 pipeline that ++ * makes it hard, if not impossible, to get down to 3 cycles/limb: ++ * ++ * 1. ldq has a 3 cycle delay, srl and sll have a 2 cycle delay. ++ * 2. Only aligned instruction pairs can be paired. ++ * 3. The store buffer or silo might not be able to deal with the bandwidth. ++ */ ++ ++ .set noreorder ++ .set noat ++.text ++ .align 3 ++ .globl _gcry_mpih_lshift ++ .ent _gcry_mpih_lshift ++_gcry_mpih_lshift: ++ .frame $30,0,$26,0 ++ ++ s8addq $18,$17,$17 # make r17 point at end of s1 ++ ldq $4,-8($17) # load first limb ++ subq $17,8,$17 ++ subq $31,$19,$7 ++ s8addq $18,$16,$16 # make r16 point at end of RES ++ subq $18,1,$18 ++ and $18,4-1,$20 # number of limbs in first loop ++ srl $4,$7,$0 # compute function result ++ ++ beq $20,.L0 ++ subq $18,$20,$18 ++ ++ .align 3 ++.Loop0: ++ ldq $3,-8($17) ++ subq $16,8,$16 ++ subq $17,8,$17 ++ subq $20,1,$20 ++ sll $4,$19,$5 ++ srl $3,$7,$6 ++ bis $3,$3,$4 ++ bis $5,$6,$8 ++ stq $8,0($16) ++ bne $20,.Loop0 ++ ++.L0: beq $18,.Lend ++ ++ .align 3 ++.Loop: ldq $3,-8($17) ++ subq $16,32,$16 ++ subq $18,4,$18 ++ sll $4,$19,$5 ++ srl $3,$7,$6 ++ ++ ldq $4,-16($17) ++ sll $3,$19,$1 ++ bis $5,$6,$8 ++ stq $8,24($16) ++ srl $4,$7,$2 ++ ++ ldq $3,-24($17) ++ sll $4,$19,$5 ++ bis $1,$2,$8 ++ stq $8,16($16) ++ srl $3,$7,$6 ++ ++ ldq $4,-32($17) ++ sll $3,$19,$1 ++ bis $5,$6,$8 ++ stq $8,8($16) ++ srl $4,$7,$2 ++ ++ subq $17,32,$17 ++ bis $1,$2,$8 ++ stq $8,0($16) ++ ++ bgt $18,.Loop ++ ++.Lend: sll $4,$19,$8 ++ stq $8,-8($16) ++ ret $31,($26),1 ++ .end _gcry_mpih_lshift ++ ++ +diff --git a/grub-core/lib/libgcrypt/mpi/alpha/mpih-mul1.S b/grub-core/lib/libgcrypt/mpi/alpha/mpih-mul1.S +new file mode 100644 +index 0000000..cd91b10 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/alpha/mpih-mul1.S +@@ -0,0 +1,90 @@ ++/* Alpha 21064 mpih-mul1.S -- Multiply a limb vector with a limb and store ++ * the result in a second limb vector. ++ * ++ * Copyright (C) 1992, 1994, 1995, 1998, ++ * 2001, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ */ ++ ++ ++/******************* ++ * mpi_limb_t ++ * _gcry_mpih_mul_1( mpi_ptr_t res_ptr, (r16) ++ * mpi_ptr_t s1_ptr, (r17) ++ * mpi_size_t s1_size, (r18) ++ * mpi_limb_t s2_limb) (r19) ++ * ++ * This code runs at 42 cycles/limb on the EV4 and 18 cycles/limb on the EV5. ++ * ++ * To improve performance for long multiplications, we would use ++ * 'fetch' for S1 and 'fetch_m' for RES. It's not obvious how to use ++ * these instructions without slowing down the general code: 1. We can ++ * only have two prefetches in operation at any time in the Alpha ++ * architecture. 2. There will seldom be any special alignment ++ * between RES_PTR and S1_PTR. Maybe we can simply divide the current ++ * loop into an inner and outer loop, having the inner loop handle ++ * exactly one prefetch block? ++ */ ++ ++ .set noreorder ++ .set noat ++.text ++ .align 3 ++ .globl _gcry_mpih_mul_1 ++ .ent _gcry_mpih_mul_1 2 ++_gcry_mpih_mul_1: ++ .frame $30,0,$26 ++ ++ ldq $2,0($17) # $2 = s1_limb ++ subq $18,1,$18 # size-- ++ mulq $2,$19,$3 # $3 = prod_low ++ bic $31,$31,$4 # clear cy_limb ++ umulh $2,$19,$0 # $0 = prod_high ++ beq $18,Lend1 # jump if size was == 1 ++ ldq $2,8($17) # $2 = s1_limb ++ subq $18,1,$18 # size-- ++ stq $3,0($16) ++ beq $18,Lend2 # jump if size was == 2 ++ ++ .align 3 ++Loop: mulq $2,$19,$3 # $3 = prod_low ++ addq $4,$0,$0 # cy_limb = cy_limb + 'cy' ++ subq $18,1,$18 # size-- ++ umulh $2,$19,$4 # $4 = cy_limb ++ ldq $2,16($17) # $2 = s1_limb ++ addq $17,8,$17 # s1_ptr++ ++ addq $3,$0,$3 # $3 = cy_limb + prod_low ++ stq $3,8($16) ++ cmpult $3,$0,$0 # $0 = carry from (cy_limb + prod_low) ++ addq $16,8,$16 # res_ptr++ ++ bne $18,Loop ++ ++Lend2: mulq $2,$19,$3 # $3 = prod_low ++ addq $4,$0,$0 # cy_limb = cy_limb + 'cy' ++ umulh $2,$19,$4 # $4 = cy_limb ++ addq $3,$0,$3 # $3 = cy_limb + prod_low ++ cmpult $3,$0,$0 # $0 = carry from (cy_limb + prod_low) ++ stq $3,8($16) ++ addq $4,$0,$0 # cy_limb = prod_high + cy ++ ret $31,($26),1 ++Lend1: stq $3,0($16) ++ ret $31,($26),1 ++ ++ .end _gcry_mpih_mul_1 ++ ++ +diff --git a/grub-core/lib/libgcrypt/mpi/alpha/mpih-mul2.S b/grub-core/lib/libgcrypt/mpi/alpha/mpih-mul2.S +new file mode 100644 +index 0000000..5eb6b98 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/alpha/mpih-mul2.S +@@ -0,0 +1,97 @@ ++/* Alpha 21064 addmul_1 -- Multiply a limb vector with a limb and add ++ * the result to a second limb vector. ++ * ++ * Copyright (C) 1992, 1994, 1995, 1998, ++ * 2001, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ */ ++ ++ ++/******************* ++ * mpi_limb_t ++ * _gcry_mpih_addmul_1( mpi_ptr_t res_ptr, (r16) ++ * mpi_ptr_t s1_ptr, (r17) ++ * mpi_size_t s1_size, (r18) ++ * mpi_limb_t s2_limb) (r19) ++ * ++ * This code runs at 42 cycles/limb on EV4 and 18 cycles/limb on EV5. ++ */ ++ ++ ++ .set noreorder ++ .set noat ++.text ++ .align 3 ++ .globl _gcry_mpih_addmul_1 ++ .ent _gcry_mpih_addmul_1 2 ++_gcry_mpih_addmul_1: ++ .frame $30,0,$26 ++ ++ ldq $2,0($17) # $2 = s1_limb ++ addq $17,8,$17 # s1_ptr++ ++ subq $18,1,$18 # size-- ++ mulq $2,$19,$3 # $3 = prod_low ++ ldq $5,0($16) # $5 = *res_ptr ++ umulh $2,$19,$0 # $0 = prod_high ++ beq $18,.Lend1 # jump if size was == 1 ++ ldq $2,0($17) # $2 = s1_limb ++ addq $17,8,$17 # s1_ptr++ ++ subq $18,1,$18 # size-- ++ addq $5,$3,$3 ++ cmpult $3,$5,$4 ++ stq $3,0($16) ++ addq $16,8,$16 # res_ptr++ ++ beq $18,.Lend2 # jump if size was == 2 ++ ++ .align 3 ++.Loop: mulq $2,$19,$3 # $3 = prod_low ++ ldq $5,0($16) # $5 = *res_ptr ++ addq $4,$0,$0 # cy_limb = cy_limb + 'cy' ++ subq $18,1,$18 # size-- ++ umulh $2,$19,$4 # $4 = cy_limb ++ ldq $2,0($17) # $2 = s1_limb ++ addq $17,8,$17 # s1_ptr++ ++ addq $3,$0,$3 # $3 = cy_limb + prod_low ++ cmpult $3,$0,$0 # $0 = carry from (cy_limb + prod_low) ++ addq $5,$3,$3 ++ cmpult $3,$5,$5 ++ stq $3,0($16) ++ addq $16,8,$16 # res_ptr++ ++ addq $5,$0,$0 # combine carries ++ bne $18,.Loop ++ ++.Lend2: mulq $2,$19,$3 # $3 = prod_low ++ ldq $5,0($16) # $5 = *res_ptr ++ addq $4,$0,$0 # cy_limb = cy_limb + 'cy' ++ umulh $2,$19,$4 # $4 = cy_limb ++ addq $3,$0,$3 # $3 = cy_limb + prod_low ++ cmpult $3,$0,$0 # $0 = carry from (cy_limb + prod_low) ++ addq $5,$3,$3 ++ cmpult $3,$5,$5 ++ stq $3,0($16) ++ addq $5,$0,$0 # combine carries ++ addq $4,$0,$0 # cy_limb = prod_high + cy ++ ret $31,($26),1 ++.Lend1: addq $5,$3,$3 ++ cmpult $3,$5,$5 ++ stq $3,0($16) ++ addq $0,$5,$0 ++ ret $31,($26),1 ++ ++ .end _gcry_mpih_addmul_1 ++ +diff --git a/grub-core/lib/libgcrypt/mpi/alpha/mpih-mul3.S b/grub-core/lib/libgcrypt/mpi/alpha/mpih-mul3.S +new file mode 100644 +index 0000000..7d5d2af +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/alpha/mpih-mul3.S +@@ -0,0 +1,95 @@ ++/* Alpha 21064 submul_1 -- Multiply a limb vector with a limb and ++ * subtract the result from a second limb vector. ++ * Copyright (C) 1992, 1994, 1995, 1998, ++ * 2001, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ */ ++ ++ ++/******************* ++ * mpi_limb_t ++ * _gcry_mpih_submul_1( mpi_ptr_t res_ptr, (r16 ) ++ * mpi_ptr_t s1_ptr, (r17 ) ++ * mpi_size_t s1_size, (r18 ) ++ * mpi_limb_t s2_limb) (r19 ) ++ * ++ * This code runs at 42 cycles/limb on EV4 and 18 cycles/limb on EV5. ++ */ ++ ++ .set noreorder ++ .set noat ++.text ++ .align 3 ++ .globl _gcry_mpih_submul_1 ++ .ent _gcry_mpih_submul_1 2 ++_gcry_mpih_submul_1: ++ .frame $30,0,$26 ++ ++ ldq $2,0($17) # $2 = s1_limb ++ addq $17,8,$17 # s1_ptr++ ++ subq $18,1,$18 # size-- ++ mulq $2,$19,$3 # $3 = prod_low ++ ldq $5,0($16) # $5 = *res_ptr ++ umulh $2,$19,$0 # $0 = prod_high ++ beq $18,.Lend1 # jump if size was == 1 ++ ldq $2,0($17) # $2 = s1_limb ++ addq $17,8,$17 # s1_ptr++ ++ subq $18,1,$18 # size-- ++ subq $5,$3,$3 ++ cmpult $5,$3,$4 ++ stq $3,0($16) ++ addq $16,8,$16 # res_ptr++ ++ beq $18,.Lend2 # jump if size was == 2 ++ ++ .align 3 ++.Loop: mulq $2,$19,$3 # $3 = prod_low ++ ldq $5,0($16) # $5 = *res_ptr ++ addq $4,$0,$0 # cy_limb = cy_limb + 'cy' ++ subq $18,1,$18 # size-- ++ umulh $2,$19,$4 # $4 = cy_limb ++ ldq $2,0($17) # $2 = s1_limb ++ addq $17,8,$17 # s1_ptr++ ++ addq $3,$0,$3 # $3 = cy_limb + prod_low ++ cmpult $3,$0,$0 # $0 = carry from (cy_limb + prod_low) ++ subq $5,$3,$3 ++ cmpult $5,$3,$5 ++ stq $3,0($16) ++ addq $16,8,$16 # res_ptr++ ++ addq $5,$0,$0 # combine carries ++ bne $18,.Loop ++ ++.Lend2: mulq $2,$19,$3 # $3 = prod_low ++ ldq $5,0($16) # $5 = *res_ptr ++ addq $4,$0,$0 # cy_limb = cy_limb + 'cy' ++ umulh $2,$19,$4 # $4 = cy_limb ++ addq $3,$0,$3 # $3 = cy_limb + prod_low ++ cmpult $3,$0,$0 # $0 = carry from (cy_limb + prod_low) ++ subq $5,$3,$3 ++ cmpult $5,$3,$5 ++ stq $3,0($16) ++ addq $5,$0,$0 # combine carries ++ addq $4,$0,$0 # cy_limb = prod_high + cy ++ ret $31,($26),1 ++.Lend1: subq $5,$3,$3 ++ cmpult $5,$3,$5 ++ stq $3,0($16) ++ addq $0,$5,$0 ++ ret $31,($26),1 ++ ++ .end _gcry_mpih_submul_1 ++ +diff --git a/grub-core/lib/libgcrypt/mpi/alpha/mpih-rshift.S b/grub-core/lib/libgcrypt/mpi/alpha/mpih-rshift.S +new file mode 100644 +index 0000000..f0c9814 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/alpha/mpih-rshift.S +@@ -0,0 +1,118 @@ ++/* alpha rshift ++ * Copyright (C) 1994, 1995, 1998, 1999, ++ * 2000, 2001, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ * ++ * Note: This code is heavily based on the GNU MP Library. ++ * Actually it's the same code with only minor changes in the ++ * way the data is stored; this is to support the abstraction ++ * of an optional secure memory allocation which may be used ++ * to avoid revealing of sensitive data due to paging etc. ++ */ ++ ++ ++ ++ ++/******************* ++ * mpi_limb_t ++ * _gcry_mpih_rshift( mpi_ptr_t wp, (r16) ++ * mpi_ptr_t up, (r17) ++ * mpi_size_t usize, (r18) ++ * unsigned cnt) (r19) ++ * ++ * This code runs at 4.8 cycles/limb on the 21064. With infinite unrolling, ++ * it would take 4 cycles/limb. It should be possible to get down to 3 ++ * cycles/limb since both ldq and stq can be paired with the other used ++ * instructions. But there are many restrictions in the 21064 pipeline that ++ * makes it hard, if not impossible, to get down to 3 cycles/limb: ++ * ++ * 1. ldq has a 3 cycle delay, srl and sll have a 2 cycle delay. ++ * 2. Only aligned instruction pairs can be paired. ++ * 3. The store buffer or silo might not be able to deal with the bandwidth. ++ */ ++ ++ .set noreorder ++ .set noat ++.text ++ .align 3 ++ .globl _gcry_mpih_rshift ++ .ent _gcry_mpih_rshift ++_gcry_mpih_rshift: ++ .frame $30,0,$26,0 ++ ++ ldq $4,0($17) # load first limb ++ addq $17,8,$17 ++ subq $31,$19,$7 ++ subq $18,1,$18 ++ and $18,4-1,$20 # number of limbs in first loop ++ sll $4,$7,$0 # compute function result ++ ++ beq $20,.R0 ++ subq $18,$20,$18 ++ ++ .align 3 ++.Roop0: ++ ldq $3,0($17) ++ addq $16,8,$16 ++ addq $17,8,$17 ++ subq $20,1,$20 ++ srl $4,$19,$5 ++ sll $3,$7,$6 ++ bis $3,$3,$4 ++ bis $5,$6,$8 ++ stq $8,-8($16) ++ bne $20,.Roop0 ++ ++.R0: beq $18,.Rend ++ ++ .align 3 ++.Roop: ldq $3,0($17) ++ addq $16,32,$16 ++ subq $18,4,$18 ++ srl $4,$19,$5 ++ sll $3,$7,$6 ++ ++ ldq $4,8($17) ++ srl $3,$19,$1 ++ bis $5,$6,$8 ++ stq $8,-32($16) ++ sll $4,$7,$2 ++ ++ ldq $3,16($17) ++ srl $4,$19,$5 ++ bis $1,$2,$8 ++ stq $8,-24($16) ++ sll $3,$7,$6 ++ ++ ldq $4,24($17) ++ srl $3,$19,$1 ++ bis $5,$6,$8 ++ stq $8,-16($16) ++ sll $4,$7,$2 ++ ++ addq $17,32,$17 ++ bis $1,$2,$8 ++ stq $8,-8($16) ++ ++ bgt $18,.Roop ++ ++.Rend: srl $4,$19,$8 ++ stq $8,0($16) ++ ret $31,($26),1 ++ .end _gcry_mpih_rshift ++ +diff --git a/grub-core/lib/libgcrypt/mpi/alpha/mpih-sub1.S b/grub-core/lib/libgcrypt/mpi/alpha/mpih-sub1.S +new file mode 100644 +index 0000000..9a64446 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/alpha/mpih-sub1.S +@@ -0,0 +1,124 @@ ++/* Alpha sub_n -- Subtract two limb vectors of the same length > 0 and ++ * store difference in a third limb vector. ++ * Copyright (C) 1995, 1998, ++ * 2001, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ */ ++ ++ ++/******************* ++ * mpi_limb_t ++ * _gcry_mpih_sub_n( mpi_ptr_t res_ptr, (r16) ++ * mpi_ptr_t s1_ptr, (r17) ++ * mpi_ptr_t s2_ptr, (r18) ++ * mpi_size_t size) (r19) ++ */ ++ ++ .set noreorder ++ .set noat ++.text ++ .align 3 ++ .globl _gcry_mpih_sub_n ++ .ent _gcry_mpih_sub_n ++_gcry_mpih_sub_n: ++ .frame $30,0,$26,0 ++ ++ ldq $3,0($17) ++ ldq $4,0($18) ++ ++ subq $19,1,$19 ++ and $19,4-1,$2 # number of limbs in first loop ++ bis $31,$31,$0 ++ beq $2,.L0 # if multiple of 4 limbs, skip first loop ++ ++ subq $19,$2,$19 ++ ++.Loop0: subq $2,1,$2 ++ ldq $5,8($17) ++ addq $4,$0,$4 ++ ldq $6,8($18) ++ cmpult $4,$0,$1 ++ subq $3,$4,$4 ++ cmpult $3,$4,$0 ++ stq $4,0($16) ++ or $0,$1,$0 ++ ++ addq $17,8,$17 ++ addq $18,8,$18 ++ bis $5,$5,$3 ++ bis $6,$6,$4 ++ addq $16,8,$16 ++ bne $2,.Loop0 ++ ++.L0: beq $19,.Lend ++ ++ .align 3 ++.Loop: subq $19,4,$19 ++ ++ ldq $5,8($17) ++ addq $4,$0,$4 ++ ldq $6,8($18) ++ cmpult $4,$0,$1 ++ subq $3,$4,$4 ++ cmpult $3,$4,$0 ++ stq $4,0($16) ++ or $0,$1,$0 ++ ++ ldq $3,16($17) ++ addq $6,$0,$6 ++ ldq $4,16($18) ++ cmpult $6,$0,$1 ++ subq $5,$6,$6 ++ cmpult $5,$6,$0 ++ stq $6,8($16) ++ or $0,$1,$0 ++ ++ ldq $5,24($17) ++ addq $4,$0,$4 ++ ldq $6,24($18) ++ cmpult $4,$0,$1 ++ subq $3,$4,$4 ++ cmpult $3,$4,$0 ++ stq $4,16($16) ++ or $0,$1,$0 ++ ++ ldq $3,32($17) ++ addq $6,$0,$6 ++ ldq $4,32($18) ++ cmpult $6,$0,$1 ++ subq $5,$6,$6 ++ cmpult $5,$6,$0 ++ stq $6,24($16) ++ or $0,$1,$0 ++ ++ addq $17,32,$17 ++ addq $18,32,$18 ++ addq $16,32,$16 ++ bne $19,.Loop ++ ++.Lend: addq $4,$0,$4 ++ cmpult $4,$0,$1 ++ subq $3,$4,$4 ++ cmpult $3,$4,$0 ++ stq $4,0($16) ++ or $0,$1,$0 ++ ret $31,($26),1 ++ ++ .end _gcry_mpih_sub_n ++ ++ +diff --git a/grub-core/lib/libgcrypt/mpi/alpha/udiv-qrnnd.S b/grub-core/lib/libgcrypt/mpi/alpha/udiv-qrnnd.S +new file mode 100644 +index 0000000..dd0c52d +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/alpha/udiv-qrnnd.S +@@ -0,0 +1,159 @@ ++/* Alpha 21064 __udiv_qrnnd ++ * ++ * Copyright (C) 1992, 1994, 1995, 1998, ++ * 2001, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ * ++ * Note: This code is heavily based on the GNU MP Library. ++ * Actually it's the same code with only minor changes in the ++ * way the data is stored; this is to support the abstraction ++ * of an optional secure memory allocation which may be used ++ * to avoid revealing of sensitive data due to paging etc. ++ */ ++ ++ ++ ++ .set noreorder ++ .set noat ++.text ++ .align 3 ++ .globl __udiv_qrnnd ++ .ent __udiv_qrnnd ++__udiv_qrnnd: ++ .frame $30,0,$26,0 ++ .prologue 0 ++#define cnt $2 ++#define tmp $3 ++#define rem_ptr $16 ++#define n1 $17 ++#define n0 $18 ++#define d $19 ++#define qb $20 ++ ++ ldiq cnt,16 ++ blt d,.Largedivisor ++ ++.Loop1: cmplt n0,0,tmp ++ addq n1,n1,n1 ++ bis n1,tmp,n1 ++ addq n0,n0,n0 ++ cmpule d,n1,qb ++ subq n1,d,tmp ++ cmovne qb,tmp,n1 ++ bis n0,qb,n0 ++ cmplt n0,0,tmp ++ addq n1,n1,n1 ++ bis n1,tmp,n1 ++ addq n0,n0,n0 ++ cmpule d,n1,qb ++ subq n1,d,tmp ++ cmovne qb,tmp,n1 ++ bis n0,qb,n0 ++ cmplt n0,0,tmp ++ addq n1,n1,n1 ++ bis n1,tmp,n1 ++ addq n0,n0,n0 ++ cmpule d,n1,qb ++ subq n1,d,tmp ++ cmovne qb,tmp,n1 ++ bis n0,qb,n0 ++ cmplt n0,0,tmp ++ addq n1,n1,n1 ++ bis n1,tmp,n1 ++ addq n0,n0,n0 ++ cmpule d,n1,qb ++ subq n1,d,tmp ++ cmovne qb,tmp,n1 ++ bis n0,qb,n0 ++ subq cnt,1,cnt ++ bgt cnt,.Loop1 ++ stq n1,0(rem_ptr) ++ bis $31,n0,$0 ++ ret $31,($26),1 ++ ++.Largedivisor: ++ and n0,1,$4 ++ ++ srl n0,1,n0 ++ sll n1,63,tmp ++ or tmp,n0,n0 ++ srl n1,1,n1 ++ ++ and d,1,$6 ++ srl d,1,$5 ++ addq $5,$6,$5 ++ ++.Loop2: cmplt n0,0,tmp ++ addq n1,n1,n1 ++ bis n1,tmp,n1 ++ addq n0,n0,n0 ++ cmpule $5,n1,qb ++ subq n1,$5,tmp ++ cmovne qb,tmp,n1 ++ bis n0,qb,n0 ++ cmplt n0,0,tmp ++ addq n1,n1,n1 ++ bis n1,tmp,n1 ++ addq n0,n0,n0 ++ cmpule $5,n1,qb ++ subq n1,$5,tmp ++ cmovne qb,tmp,n1 ++ bis n0,qb,n0 ++ cmplt n0,0,tmp ++ addq n1,n1,n1 ++ bis n1,tmp,n1 ++ addq n0,n0,n0 ++ cmpule $5,n1,qb ++ subq n1,$5,tmp ++ cmovne qb,tmp,n1 ++ bis n0,qb,n0 ++ cmplt n0,0,tmp ++ addq n1,n1,n1 ++ bis n1,tmp,n1 ++ addq n0,n0,n0 ++ cmpule $5,n1,qb ++ subq n1,$5,tmp ++ cmovne qb,tmp,n1 ++ bis n0,qb,n0 ++ subq cnt,1,cnt ++ bgt cnt,.Loop2 ++ ++ addq n1,n1,n1 ++ addq $4,n1,n1 ++ bne $6,.LOdd ++ stq n1,0(rem_ptr) ++ bis $31,n0,$0 ++ ret $31,($26),1 ++ ++.LOdd: ++ /* q' in n0. r' in n1 */ ++ addq n1,n0,n1 ++ cmpult n1,n0,tmp # tmp := carry from addq ++ beq tmp,.LLp6 ++ addq n0,1,n0 ++ subq n1,d,n1 ++.LLp6: cmpult n1,d,tmp ++ bne tmp,.LLp7 ++ addq n0,1,n0 ++ subq n1,d,n1 ++.LLp7: ++ stq n1,0(rem_ptr) ++ bis $31,n0,$0 ++ ret $31,($26),1 ++ ++ .end __udiv_qrnnd +diff --git a/grub-core/lib/libgcrypt/mpi/amd64/distfiles b/grub-core/lib/libgcrypt/mpi/amd64/distfiles +new file mode 100644 +index 0000000..e664c8d +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/amd64/distfiles +@@ -0,0 +1,7 @@ ++mpih-add1.S ++mpih-lshift.S ++mpih-mul1.S ++mpih-mul2.S ++mpih-mul3.S ++mpih-rshift.S ++mpih-sub1.S +diff --git a/grub-core/lib/libgcrypt/mpi/amd64/mpih-add1.S b/grub-core/lib/libgcrypt/mpi/amd64/mpih-add1.S +new file mode 100644 +index 0000000..f0ec89c +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/amd64/mpih-add1.S +@@ -0,0 +1,63 @@ ++/* AMD64 (x86_64) add_n -- Add two limb vectors of the same length > 0 and store ++ * sum in a third limb vector. ++ * ++ * Copyright (C) 1992, 1994, 1995, 1998, ++ * 2001, 2002, 2006 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ * ++ * Note: This code is heavily based on the GNU MP Library. ++ * Actually it's the same code with only minor changes in the ++ * way the data is stored; this is to support the abstraction ++ * of an optional secure memory allocation which may be used ++ * to avoid revealing of sensitive data due to paging etc. ++ */ ++ ++ ++#include "sysdep.h" ++#include "asm-syntax.h" ++ ++ ++/******************* ++ * mpi_limb_t ++ * _gcry_mpih_add_n( mpi_ptr_t res_ptr, rdi ++ * mpi_ptr_t s1_ptr, rsi ++ * mpi_ptr_t s2_ptr, rdx ++ * mpi_size_t size) rcx ++ */ ++ ++.text ++ .globl C_SYMBOL_NAME(_gcry_mpih_add_n) ++C_SYMBOL_NAME(_gcry_mpih_add_n:) ++ leaq (%rsi,%rcx,8), %rsi ++ leaq (%rdi,%rcx,8), %rdi ++ leaq (%rdx,%rcx,8), %rdx ++ negq %rcx ++ xorl %eax, %eax /* clear cy */ ++ ++ ALIGN(4) /* minimal alignment for claimed speed */ ++.Loop: movq (%rsi,%rcx,8), %rax ++ movq (%rdx,%rcx,8), %r10 ++ adcq %r10, %rax ++ movq %rax, (%rdi,%rcx,8) ++ incq %rcx ++ jne .Loop ++ ++ movq %rcx, %rax /* zero %rax */ ++ adcq %rax, %rax ++ ret ++ +\ No newline at end of file +diff --git a/grub-core/lib/libgcrypt/mpi/amd64/mpih-lshift.S b/grub-core/lib/libgcrypt/mpi/amd64/mpih-lshift.S +new file mode 100644 +index 0000000..e87dd1a +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/amd64/mpih-lshift.S +@@ -0,0 +1,77 @@ ++/* AMD64 (x86_64) lshift -- Left shift a limb vector and store ++ * result in a second limb vector. ++ * ++ * Copyright (C) 1992, 1994, 1995, 1998, ++ * 2001, 2002, 2006 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ * ++ * Note: This code is heavily based on the GNU MP Library. ++ * Actually it's the same code with only minor changes in the ++ * way the data is stored; this is to support the abstraction ++ * of an optional secure memory allocation which may be used ++ * to avoid revealing of sensitive data due to paging etc. ++ */ ++ ++ ++#include "sysdep.h" ++#include "asm-syntax.h" ++ ++/******************* ++ * mpi_limb_t ++ * _gcry_mpih_lshift( mpi_ptr_t wp, rdi ++ * mpi_ptr_t up, rsi ++ * mpi_size_t usize, rdx ++ * unsigned cnt) rcx ++ */ ++ ++.text ++ .globl C_SYMBOL_NAME(_gcry_mpih_lshift) ++C_SYMBOL_NAME(_gcry_mpih_lshift:) ++ movq -8(%rsi,%rdx,8), %mm7 ++ movd %ecx, %mm1 ++ movl $64, %eax ++ subl %ecx, %eax ++ movd %eax, %mm0 ++ movq %mm7, %mm3 ++ psrlq %mm0, %mm7 ++ movd %mm7, %rax ++ subq $2, %rdx ++ jl .Lendo ++ ++ ALIGN(4) /* minimal alignment for claimed speed */ ++.Loop: movq (%rsi,%rdx,8), %mm6 ++ movq %mm6, %mm2 ++ psrlq %mm0, %mm6 ++ psllq %mm1, %mm3 ++ por %mm6, %mm3 ++ movq %mm3, 8(%rdi,%rdx,8) ++ je .Lende ++ movq -8(%rsi,%rdx,8), %mm7 ++ movq %mm7, %mm3 ++ psrlq %mm0, %mm7 ++ psllq %mm1, %mm2 ++ por %mm7, %mm2 ++ movq %mm2, (%rdi,%rdx,8) ++ subq $2, %rdx ++ jge .Loop ++ ++.Lendo: movq %mm3, %mm2 ++.Lende: psllq %mm1, %mm2 ++ movq %mm2, (%rdi) ++ emms ++ ret +diff --git a/grub-core/lib/libgcrypt/mpi/amd64/mpih-mul1.S b/grub-core/lib/libgcrypt/mpi/amd64/mpih-mul1.S +new file mode 100644 +index 0000000..54b0ab4 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/amd64/mpih-mul1.S +@@ -0,0 +1,65 @@ ++/* AMD64 mul_1 -- Multiply a limb vector with a limb and store ++ * the result in a second limb vector. ++ * Copyright (C) 1992, 1994, 1998, ++ * 2001, 2002, 2006 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ * ++ * Note: This code is heavily based on the GNU MP Library. ++ * Actually it's the same code with only minor changes in the ++ * way the data is stored; this is to support the abstraction ++ * of an optional secure memory allocation which may be used ++ * to avoid revealing of sensitive data due to paging etc. ++ */ ++ ++ ++#include "sysdep.h" ++#include "asm-syntax.h" ++ ++/******************* ++ * mpi_limb_t ++ * _gcry_mpih_mul_1( mpi_ptr_t res_ptr, (rdi) ++ * mpi_ptr_t s1_ptr, (rsi) ++ * mpi_size_t s1_size, (rdx) ++ * mpi_limb_t s2_limb) (rcx) ++ */ ++ ++ ++ TEXT ++ ALIGN(5) ++ .byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ++ ++ GLOBL C_SYMBOL_NAME(_gcry_mpih_mul_1) ++C_SYMBOL_NAME(_gcry_mpih_mul_1:) ++ ++ movq %rdx, %r11 ++ leaq (%rsi,%rdx,8), %rsi ++ leaq (%rdi,%rdx,8), %rdi ++ negq %r11 ++ xorl %r8d, %r8d ++ ++.Loop: movq (%rsi,%r11,8), %rax ++ mulq %rcx ++ addq %r8, %rax ++ movl $0, %r8d ++ adcq %rdx, %r8 ++ movq %rax, (%rdi,%r11,8) ++ incq %r11 ++ jne .Loop ++ ++ movq %r8, %rax ++ ret +diff --git a/grub-core/lib/libgcrypt/mpi/amd64/mpih-mul2.S b/grub-core/lib/libgcrypt/mpi/amd64/mpih-mul2.S +new file mode 100644 +index 0000000..1180f76 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/amd64/mpih-mul2.S +@@ -0,0 +1,107 @@ ++/* AMD64 addmul2 -- Multiply a limb vector with a limb and add ++ * the result to a second limb vector. ++ * ++ * Copyright (C) 1992, 1994, 1998, ++ * 2001, 2002, 2006 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ * ++ * Note: This code is heavily based on the GNU MP Library. ++ * Actually it's the same code with only minor changes in the ++ * way the data is stored; this is to support the abstraction ++ * of an optional secure memory allocation which may be used ++ * to avoid revealing of sensitive data due to paging etc. ++ */ ++ ++ ++#include "sysdep.h" ++#include "asm-syntax.h" ++ ++ ++/******************* ++ * mpi_limb_t ++ * _gcry_mpih_addmul_2( mpi_ptr_t res_ptr, (sp + 4) ++ * mpi_ptr_t s1_ptr, (sp + 8) ++ * mpi_size_t s1_size, (sp + 12) ++ * mpi_limb_t s2_limb) (sp + 16) ++ */ ++ ++ /* i80386 addmul_1 -- Multiply a limb vector with a limb and add ++ * the result to a second limb vector. ++ * ++ * Copyright (C) 1992, 1994, 1998, ++ * 2001, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ * ++ * Note: This code is heavily based on the GNU MP Library. ++ * Actually it's the same code with only minor changes in the ++ * way the data is stored; this is to support the abstraction ++ * of an optional secure memory allocation which may be used ++ * to avoid revealing of sensitive data due to paging etc. ++ */ ++ ++ ++#include "sysdep.h" ++#include "asm-syntax.h" ++ ++ ++/******************* ++ * mpi_limb_t ++ * _gcry_mpih_addmul_1( mpi_ptr_t res_ptr, (rdi) ++ * mpi_ptr_t s1_ptr, (rsi) ++ * mpi_size_t s1_size, (rdx) ++ * mpi_limb_t s2_limb) (rcx) ++ */ ++ TEXT ++ GLOBL C_SYMBOL_NAME(_gcry_mpih_addmul_1) ++C_SYMBOL_NAME(_gcry_mpih_addmul_1:) ++ movq %rdx, %r11 ++ leaq (%rsi,%rdx,8), %rsi ++ leaq (%rdi,%rdx,8), %rdi ++ negq %r11 ++ xorl %r8d, %r8d ++ xorl %r10d, %r10d ++ ++ ALIGN(3) /* minimal alignment for claimed speed */ ++.Loop: movq (%rsi,%r11,8), %rax ++ mulq %rcx ++ addq (%rdi,%r11,8), %rax ++ adcq %r10, %rdx ++ addq %r8, %rax ++ movq %r10, %r8 ++ movq %rax, (%rdi,%r11,8) ++ adcq %rdx, %r8 ++ incq %r11 ++ jne .Loop ++ ++ movq %r8, %rax ++ ret +diff --git a/grub-core/lib/libgcrypt/mpi/amd64/mpih-mul3.S b/grub-core/lib/libgcrypt/mpi/amd64/mpih-mul3.S +new file mode 100644 +index 0000000..4d458a7 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/amd64/mpih-mul3.S +@@ -0,0 +1,66 @@ ++/* AMD64 submul_1 -- Multiply a limb vector with a limb and add ++ * the result to a second limb vector. ++ * ++ * Copyright (C) 1992, 1994, 1998, ++ * 2001, 2002, 2006 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ * ++ * Note: This code is heavily based on the GNU MP Library. ++ * Actually it's the same code with only minor changes in the ++ * way the data is stored; this is to support the abstraction ++ * of an optional secure memory allocation which may be used ++ * to avoid revealing of sensitive data due to paging etc. ++ */ ++ ++ ++#include "sysdep.h" ++#include "asm-syntax.h" ++ ++ ++/******************* ++ * mpi_limb_t ++ * _gcry_mpih_submul_1( mpi_ptr_t res_ptr, (rdi) ++ * mpi_ptr_t s1_ptr, (rsi) ++ * mpi_size_t s1_size, (rdx) ++ * mpi_limb_t s2_limb) (rcx) ++ */ ++ TEXT ++ GLOBL C_SYMBOL_NAME(_gcry_mpih_submul_1) ++C_SYMBOL_NAME(_gcry_mpih_submul_1:) ++ ++ movq %rdx, %r11 ++ leaq (%rsi,%r11,8), %rsi ++ leaq (%rdi,%r11,8), %rdi ++ negq %r11 ++ xorl %r8d, %r8d ++ ++ ALIGN(3) /* minimal alignment for claimed speed */ ++.Loop: movq (%rsi,%r11,8), %rax ++ movq (%rdi,%r11,8), %r10 ++ mulq %rcx ++ subq %r8, %r10 ++ movl $0, %r8d ++ adcl %r8d, %r8d ++ subq %rax, %r10 ++ adcq %rdx, %r8 ++ movq %r10, (%rdi,%r11,8) ++ incq %r11 ++ jne .Loop ++ ++ movq %r8, %rax ++ ret +diff --git a/grub-core/lib/libgcrypt/mpi/amd64/mpih-rshift.S b/grub-core/lib/libgcrypt/mpi/amd64/mpih-rshift.S +new file mode 100644 +index 0000000..4cfc8f6 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/amd64/mpih-rshift.S +@@ -0,0 +1,80 @@ ++/* AMD64 (x86_64) rshift -- Right shift a limb vector and store ++ * result in a second limb vector. ++ * ++ * Copyright (C) 1992, 1994, 1995, 1998, ++ * 2001, 2002, 2006 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ * ++ * Note: This code is heavily based on the GNU MP Library. ++ * Actually it's the same code with only minor changes in the ++ * way the data is stored; this is to support the abstraction ++ * of an optional secure memory allocation which may be used ++ * to avoid revealing of sensitive data due to paging etc. ++ */ ++ ++ ++#include "sysdep.h" ++#include "asm-syntax.h" ++ ++/******************* ++ * mpi_limb_t ++ * _gcry_mpih_rshift( mpi_ptr_t wp, rdi ++ * mpi_ptr_t up, rsi ++ * mpi_size_t usize, rdx ++ * unsigned cnt) rcx ++ */ ++ ++.text ++ .globl C_SYMBOL_NAME(_gcry_mpih_rshift) ++C_SYMBOL_NAME(_gcry_mpih_rshift:) ++ movq (%rsi), %mm7 ++ movd %ecx, %mm1 ++ movl $64, %eax ++ subl %ecx, %eax ++ movd %eax, %mm0 ++ movq %mm7, %mm3 ++ psllq %mm0, %mm7 ++ movd %mm7, %rax ++ leaq (%rsi,%rdx,8), %rsi ++ leaq (%rdi,%rdx,8), %rdi ++ negq %rdx ++ addq $2, %rdx ++ jg .Lendo ++ ++ ALIGN(8) /* minimal alignment for claimed speed */ ++.Loop: movq -8(%rsi,%rdx,8), %mm6 ++ movq %mm6, %mm2 ++ psllq %mm0, %mm6 ++ psrlq %mm1, %mm3 ++ por %mm6, %mm3 ++ movq %mm3, -16(%rdi,%rdx,8) ++ je .Lende ++ movq (%rsi,%rdx,8), %mm7 ++ movq %mm7, %mm3 ++ psllq %mm0, %mm7 ++ psrlq %mm1, %mm2 ++ por %mm7, %mm2 ++ movq %mm2, -8(%rdi,%rdx,8) ++ addq $2, %rdx ++ jle .Loop ++ ++.Lendo: movq %mm3, %mm2 ++.Lende: psrlq %mm1, %mm2 ++ movq %mm2, -8(%rdi) ++ emms ++ ret +diff --git a/grub-core/lib/libgcrypt/mpi/amd64/mpih-sub1.S b/grub-core/lib/libgcrypt/mpi/amd64/mpih-sub1.S +new file mode 100644 +index 0000000..b3609b0 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/amd64/mpih-sub1.S +@@ -0,0 +1,61 @@ ++/* AMD64 (x86_64) sub_n -- Subtract two limb vectors of the same length > 0 and store ++ * sum in a third limb vector. ++ * ++ * Copyright (C) 1992, 1994, 1995, 1998, ++ * 2001, 2002, 2006 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ * ++ * Note: This code is heavily based on the GNU MP Library. ++ * Actually it's the same code with only minor changes in the ++ * way the data is stored; this is to support the abstraction ++ * of an optional secure memory allocation which may be used ++ * to avoid revealing of sensitive data due to paging etc. ++ */ ++ ++ ++#include "sysdep.h" ++#include "asm-syntax.h" ++ ++ ++/******************* ++ * mpi_limb_t ++ * _gcry_mpih_sub_n( mpi_ptr_t res_ptr, rdi ++ * mpi_ptr_t s1_ptr, rsi ++ * mpi_ptr_t s2_ptr, rdx ++ * mpi_size_t size) rcx ++ */ ++.text ++ .globl C_SYMBOL_NAME(_gcry_mpih_sub_n) ++C_SYMBOL_NAME(_gcry_mpih_sub_n:) ++ leaq (%rsi,%rcx,8), %rsi ++ leaq (%rdi,%rcx,8), %rdi ++ leaq (%rdx,%rcx,8), %rdx ++ negq %rcx ++ xorl %eax, %eax /* clear cy */ ++ ++ ALIGN(4) /* minimal alignment for claimed speed */ ++.Loop: movq (%rsi,%rcx,8), %rax ++ movq (%rdx,%rcx,8), %r10 ++ sbbq %r10, %rax ++ movq %rax, (%rdi,%rcx,8) ++ incq %rcx ++ jne .Loop ++ ++ movq %rcx, %rax /* zero %rax */ ++ adcq %rax, %rax ++ ret +diff --git a/grub-core/lib/libgcrypt/mpi/config.links b/grub-core/lib/libgcrypt/mpi/config.links +new file mode 100644 +index 0000000..7e910ee +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/config.links +@@ -0,0 +1,360 @@ ++# config.links - helper for ../configure -*- mode: sh -*- ++# Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. ++# ++# This file is part of Libgcrypt. ++# ++# Libgcrypt is free software; you can redistribute it and/or modify ++# it under the terms of the GNU Lesser General Public License as ++# published by the Free Software Foundation; either version 2.1 of ++# the License, or (at your option) any later version. ++# ++# Libgcrypt 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 Lesser General Public License for more details. ++# ++# You should have received a copy of the GNU Lesser General Public ++# License along with this program; if not, write to the Free Software ++# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++# ++# sourced by ../configure to get the list of files to link ++# this should set $mpi_ln_list. ++# Note: this is called from the above directory. ++ ++mpi_sflags= ++mpi_extra_modules= ++ ++test -d ./mpi || mkdir ./mpi ++ ++# We grep the list of modules from the Makefile so that ++# we don't need to maintain them here. ++mpi_standard_modules=`$AWK '/^#BEGIN_ASM_LIST/,/^#END_ASM_LIST/ { ++ if( $3 != "O" ) print $2 }' $srcdir/mpi/Makefile.am` ++mpi_optional_modules=`$AWK '/^#BEGIN_ASM_LIST/,/^#END_ASM_LIST/ { ++ if( $3 == "O" ) print $2 }' $srcdir/mpi/Makefile.am` ++ ++ ++echo '/* created by config.links - do not edit */' >./mpi/asm-syntax.h ++echo "/* Host: ${host} */" >>./mpi/asm-syntax.h ++ ++if test "$try_asm_modules" = "yes" ; then ++case "${host}" in ++ powerpc-apple-darwin* | \ ++ i[34567]86*-*-openbsd[12]* | \ ++ i[34567]86*-*-openbsd3.[0123]*) ++ echo '/* No working assembler modules available */' >>./mpi/asm-syntax.h ++ path="" ++ ;; ++ i[3467]86*-*-openbsd* | \ ++ i[3467]86*-*-freebsd*-elf | \ ++ i[3467]86*-*-freebsd[3-9]* | \ ++ i[3467]86*-*-freebsdelf* | \ ++ i[3467]86*-*-netbsd* | \ ++ i[3467]86*-*-k*bsd*) ++ echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h ++ cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h ++ path="i386" ++ ;; ++ i586*-*-openbsd* | \ ++ i586*-*-freebsd*-elf | \ ++ i586*-*-freebsd[3-9]* | \ ++ i586*-*-freebsdelf* | \ ++ i586*-*-netbsd* | \ ++ i586*-*-k*bsd* | \ ++ pentium-*-netbsd* | \ ++ pentiumpro-*-netbsd*) ++ echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h ++ cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h ++ path="i586 i386" ++ ;; ++ i[34]86*-*-bsdi4*) ++ echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h ++ cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h ++ path="i386" ++ ;; ++ i[3467]86*-*-linuxaout* | \ ++ i[3467]86*-*-linuxoldld* | \ ++ i[3467]86*-*-*bsd*) ++ echo '#define BSD_SYNTAX' >>./mpi/asm-syntax.h ++ echo '#define X86_BROKEN_ALIGN' >>./mpi/asm-syntax.h ++ cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h ++ path="i386" ++ ;; ++ i586*-*-linuxaout* | \ ++ i586*-*-linuxoldld* | \ ++ i586*-*-*bsd*) ++ echo '#define BSD_SYNTAX' >>./mpi/asm-syntax.h ++ echo '#define X86_BROKEN_ALIGN' >>./mpi/asm-syntax.h ++ cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h ++ path="i586 i386" ++ ;; ++ i[3467]86*-msdosdjgpp* | \ ++ i[34]86*-apple-darwin*) ++ echo '#define BSD_SYNTAX' >>./mpi/asm-syntax.h ++ cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h ++ path="i386" ++ ;; ++ i586*-msdosdjgpp* | \ ++ i[567]86*-apple-darwin*) ++ echo '#define BSD_SYNTAX' >>./mpi/asm-syntax.h ++ cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h ++ path="i586 i386" ++ ;; ++ i[3467]86*-*-*) ++ echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h ++ cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h ++ path="i386" ++ ;; ++ i586*-*-* | \ ++ pentium-*-* | \ ++ pentiumpro-*-*) ++ echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h ++ cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h ++ path="i586 i386" ++ ;; ++ x86_64-*-*) ++ echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h ++ cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h ++ path="amd64" ++ ;; ++ alpha*-*-*) ++ echo '/* configured for alpha */' >>./mpi/asm-syntax.h ++ path="alpha" ++ mpi_extra_modules="udiv-qrnnd" ++ ;; ++ hppa7000*-*-*) ++ echo '/* configured for HPPA (pa7000) */' >>./mpi/asm-syntax.h ++ path="hppa1.1 hppa" ++ mpi_extra_modules="udiv-qrnnd" ++ ;; ++ hppa1.0*-*-*) ++ echo '/* configured for HPPA 1.0 */' >>./mpi/asm-syntax.h ++ path="hppa" ++ mpi_extra_modules="udiv-qrnnd" ++ ;; ++ hppa*-*-*) # assume pa7100 ++ echo '/* configured for HPPA (pa7100) */' >>./mpi/asm-syntax.h ++ path="pa7100 hppa1.1 hppa" ++ mpi_extra_modules="udiv-qrnnd" ++ ;; ++ sparc64-*-linux-gnu) ++ echo '/* No working assembler modules available */' >>./mpi/asm-syntax.h ++ path="" ++ ;; ++ sparc64-sun-solaris2*) ++ echo '/* No working assembler modules available */' >>./mpi/asm-syntax.h ++ path="" ++ ;; ++ sparc64-*-netbsd* | sparc64-*-freebsd* | sparc64-*-openbsd*) ++ # There are no sparc64 assembler modules that work on the ++ # *BSDs, so use the generic C functions. ++ echo '/* No working assembler modules available */' >>./mpi/asm-syntax.h ++ path="" ++ ;; ++ sparc64*-*-*) ++ echo '/* No working assembler modules available */' >>./mpi/asm-syntax.h ++ path="" ++ ;; ++ sparc9*-*-* | \ ++ ultrasparc*-*-* ) ++ echo '/* configured for sparc9 or higher */' >>./mpi/asm-syntax.h ++ path="sparc32v8 sparc32" ++ ;; ++ sparc8*-*-* | \ ++ microsparc*-*-*) ++ echo '/* configured for sparc8 */' >>./mpi/asm-syntax.h ++ path="sparc32v8 sparc32" ++ ;; ++ supersparc*-*-*) ++ echo '/* configured for supersparc */' >>./mpi/asm-syntax.h ++ path="supersparc sparc32v8 sparc32" ++ mpi_extra_modules="udiv" ++ ;; ++ sparc*-*-*) ++ echo '/* configured for sparc */' >>./mpi/asm-syntax.h ++ path="sparc32" ++ mpi_extra_modules="udiv" ++ ;; ++ mips[34]*-*-* | \ ++ mips*-*-irix6*) ++ echo '/* configured for MIPS3 */' >>./mpi/asm-syntax.h ++ path="mips3" ++ ;; ++ mips*-*-*) ++ echo '/* configured for MIPS2 */' >>./mpi/asm-syntax.h ++ path="mips2" ++ ;; ++ ++ # Motorola 68k configurations. Let m68k mean 68020-68040. ++ # mc68000 or mc68060 configurations need to be specified explicitly ++ m680[234]0*-*-linuxaout* | \ ++ m68k*-*-linuxaout*) ++ echo '#define MIT_SYNTAX' >>./mpi/asm-syntax.h ++ cat $srcdir/mpi/m68k/syntax.h >>./mpi/asm-syntax.h ++ path="m68k/mc68020 m68k" ++ ;; ++ m68060*-*-linuxaout*) ++ echo '#define MIT_SYNTAX' >>./mpi/asm-syntax.h ++ cat $srcdir/mpi/m68k/syntax.h >>./mpi/asm-syntax.h ++ path="m68k" ++ ;; ++ m680[234]0*-*-linux* | \ ++ m68k*-*-linux*) ++ echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h ++ cat $srcdir/mpi/m68k/syntax.h >>./mpi/asm-syntax.h ++ ;; ++ m68060*-*-linux*) ++ echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h ++ cat $srcdir/mpi/m68k/syntax.h >>./mpi/asm-syntax.h ++ path="m68k" ++ ;; ++ m68k-atari-mint) ++ echo '#define MIT_SYNTAX' >>./mpi/asm-syntax.h ++ cat $srcdir/mpi/m68k/syntax.h >>./mpi/asm-syntax.h ++ path="m68k/mc68020 m68k" ++ ;; ++ m68000*-*-* | \ ++ m68060*-*-*) ++ echo '#define MIT_SYNTAX' >>./mpi/asm-syntax.h ++ cat $srcdir/mpi/m68k/syntax.h >>./mpi/asm-syntax.h ++ path="m68k/mc68000" ++ ;; ++ m680[234]0*-*-* | \ ++ m68k*-*-*) ++ echo '#define MIT_SYNTAX' >>./mpi/asm-syntax.h ++ cat $srcdir/mpi/m68k/syntax.h >>./mpi/asm-syntax.h ++ path="m68k/mc68020 m68k" ++ ;; ++ ++ powerpc*-*-netbsd* | powerpc*-*-openbsd*) ++ echo '/* configured {Open,Net}BSD on powerpc */' >>./mpi/asm-syntax.h ++ echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h ++ cat $srcdir/mpi/powerpc32/syntax.h >>./mpi/asm-syntax.h ++ mpi_sflags="-Wa,-mppc" ++ path="powerpc32" ++ ;; ++ ++ ppc620-*-* | \ ++ powerpc64*-*-*) ++ mpi_sflags="-Wa,-mppc" ++ path="powerpc64" ++ ;; ++ powerpc*-*-linux*) ++ echo '/* configured for powerpc/ELF */' >>./mpi/asm-syntax.h ++ echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h ++ cat $srcdir/mpi/powerpc32/syntax.h >>./mpi/asm-syntax.h ++ path="powerpc32" ++ ;; ++ ++ rs6000-*-aix[456789]* | \ ++ rs6000-*-aix3.2.[456789]) ++ mpi_sflags="-Wa,-mpwr" ++ path="power" ++ mpi_extra_modules="udiv-w-sdiv" ++ ;; ++ rs6000-*-* | \ ++ power-*-* | \ ++ power2-*-*) ++ mpi_sflags="-Wa,-mppc" ++ path="power" ++ mpi_extra_modules="udiv-w-sdiv" ++ ;; ++ powerpc-ibm-aix4.2.* ) ++ # I am not sure about this one but a machine identified by ++ # powerpc-ibm-aix4.2.1.0 cannot use the powerpc32 code. ++ mpi_sflags="-Wa,-mpwr" ++ path="power" ++ mpi_extra_modules="udiv-w-sdiv" ++ ;; ++ ppc601-*-*) ++ mpi_sflags="-Wa,-mppc" ++ path="power powerpc32" ++ ;; ++ ppc60[234]*-*-*) ++ mpi_sflags="-Wa,-mppc" ++ path="powerpc32" ++ ;; ++ powerpc*-*-*) ++ mpi_sflags="-Wa,-mppc" ++ path="powerpc32" ++ ;; ++ *) ++ echo '/* No assembler modules configured */' >>./mpi/asm-syntax.h ++ path="" ++ ;; ++esac ++else ++ echo '/* Assembler modules disabled on request */' >>./mpi/asm-syntax.h ++ path="" ++fi ++ ++ ++# Make sysdep.h ++echo '/* created by config.links - do not edit */' >./mpi/sysdep.h ++if test x$ac_cv_sys_symbol_underscore = xyes; then ++ cat <>./mpi/sysdep.h ++#if __STDC__ ++#define C_SYMBOL_NAME(name) _##name ++#else ++#define C_SYMBOL_NAME(name) _/**/name ++#endif ++EOF ++else ++ cat <>./mpi/sysdep.h ++#define C_SYMBOL_NAME(name) name ++EOF ++fi ++ ++ ++# Figure the required modules out ++mpi_required_modules=$mpi_standard_modules ++if test "$mpi_extra_modules" != ""; then ++ for fn in $mpi_extra_modules; do ++ for i in $mpi_optional_modules; do ++ if test "$fn" = "$i" ; then ++ mpi_required_modules="$mpi_required_modules $fn" ++ fi ++ done ++ done ++fi ++ ++# Try to get file to link from the assembler subdirectory and ++# if this fails get it from the generic subdirectory. ++mpi_ln_list= ++mpi_mod_list= ++path=`echo "$mpi_extra_path $path generic" | tr ':' ' '` ++echo '/* Created by config.links - do not edit */' >./mpi/mod-source-info.h ++echo "/* Host: ${host} */" >>./mpi/mod-source-info.h ++echo "static char mod_source_info[] =" >>./mpi/mod-source-info.h ++for fn in $mpi_required_modules ; do ++ fnu=`echo $fn | sed 's/-/_/g'` ++ eval mpi_mod_c_${fnu}=no ++ eval mpi_mod_asm_${fnu}=no ++ for dir in $path ; do ++ rm -f $srcdir/mpi/$fn.[Sc] ++ if test -f $srcdir/mpi/$dir/$fn.S ; then ++ echo " \":$dir/$fn.S\"" >>./mpi/mod-source-info.h ++ mpi_ln_list="$mpi_ln_list mpi/$fn-asm.S:mpi/$dir/$fn.S" ++ eval mpi_mod_asm_${fnu}=yes ++ mpi_mod_list="$mpi_mod_list $fn" ++ break; ++ elif test -f $srcdir/mpi/$dir/$fn.c ; then ++ echo " \":$dir/$fn.c\"" >>./mpi/mod-source-info.h ++ mpi_ln_list="$mpi_ln_list mpi/$fn.c:mpi/$dir/$fn.c" ++ eval mpi_mod_c_${fnu}=yes ++ mpi_mod_list="$mpi_mod_list $fn" ++ break; ++ fi ++ done ++done ++echo " ;" >>./mpi/mod-source-info.h ++ ++# Same thing for the file which defines the limb size ++path=`echo "$path generic" | tr ':' ' '` ++for dir in $path ; do ++ rm -f $srcdir/mpi/mpi-asm-defs.h ++ if test -f $srcdir/mpi/$dir/mpi-asm-defs.h ; then ++ mpi_ln_list="$mpi_ln_list mpi/mpi-asm-defs.h:mpi/$dir/mpi-asm-defs.h" ++ break; ++ fi ++done +diff --git a/grub-core/lib/libgcrypt/mpi/ec.c b/grub-core/lib/libgcrypt/mpi/ec.c +new file mode 100644 +index 0000000..e325358 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/ec.c +@@ -0,0 +1,708 @@ ++/* ec.c - Elliptic Curve functions ++ Copyright (C) 2007 Free Software Foundation, Inc. ++ ++ This file is part of Libgcrypt. ++ ++ Libgcrypt is free software; you can redistribute it and/or modify ++ it under the terms of the GNU Lesser General Public License as ++ published by the Free Software Foundation; either version 2.1 of ++ the License, or (at your option) any later version. ++ ++ Libgcrypt 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 Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser 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 ++#include ++ ++#include "mpi-internal.h" ++#include "longlong.h" ++#include "g10lib.h" ++ ++ ++#define point_init(a) _gcry_mpi_ec_point_init ((a)) ++#define point_free(a) _gcry_mpi_ec_point_free ((a)) ++ ++ ++/* Object to represent a point in projective coordinates. */ ++/* Currently defined in mpi.h */ ++ ++/* This context is used with all our EC functions. */ ++struct mpi_ec_ctx_s ++{ ++ /* Domain parameters. */ ++ gcry_mpi_t p; /* Prime specifying the field GF(p). */ ++ gcry_mpi_t a; /* First coefficient of the Weierstrass equation. */ ++ ++ int a_is_pminus3; /* True if A = P - 3. */ ++ ++ /* Some often used constants. */ ++ gcry_mpi_t one; ++ gcry_mpi_t two; ++ gcry_mpi_t three; ++ gcry_mpi_t four; ++ gcry_mpi_t eight; ++ gcry_mpi_t two_inv_p; ++ ++ /* Scratch variables. */ ++ gcry_mpi_t scratch[11]; ++ ++ /* Helper for fast reduction. */ ++/* int nist_nbits; /\* If this is a NIST curve, the number of bits. *\/ */ ++/* gcry_mpi_t s[10]; */ ++/* gcry_mpi_t c; */ ++ ++}; ++ ++ ++ ++/* Initialized a point object. gcry_mpi_ec_point_free shall be used ++ to release this object. */ ++void ++_gcry_mpi_ec_point_init (mpi_point_t *p) ++{ ++ p->x = mpi_new (0); ++ p->y = mpi_new (0); ++ p->z = mpi_new (0); ++} ++ ++ ++/* Release a point object. */ ++void ++_gcry_mpi_ec_point_free (mpi_point_t *p) ++{ ++ mpi_free (p->x); p->x = NULL; ++ mpi_free (p->y); p->y = NULL; ++ mpi_free (p->z); p->z = NULL; ++} ++ ++/* Set the value from S into D. */ ++static void ++point_set (mpi_point_t *d, mpi_point_t *s) ++{ ++ mpi_set (d->x, s->x); ++ mpi_set (d->y, s->y); ++ mpi_set (d->z, s->z); ++} ++ ++ ++ ++static void ++ec_addm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, mpi_ec_t ctx) ++{ ++ mpi_addm (w, u, v, ctx->p); ++} ++ ++static void ++ec_subm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, mpi_ec_t ctx) ++{ ++ mpi_subm (w, u, v, ctx->p); ++} ++ ++static void ++ec_mulm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, mpi_ec_t ctx) ++{ ++#if 0 ++ /* NOTE: This code works only for limb sizes of 32 bit. */ ++ mpi_limb_t *wp, *sp; ++ ++ if (ctx->nist_nbits == 192) ++ { ++ mpi_mul (w, u, v); ++ mpi_resize (w, 12); ++ wp = w->d; ++ ++ sp = ctx->s[0]->d; ++ sp[0*2+0] = wp[0*2+0]; ++ sp[0*2+1] = wp[0*2+1]; ++ sp[1*2+0] = wp[1*2+0]; ++ sp[1*2+1] = wp[1*2+1]; ++ sp[2*2+0] = wp[2*2+0]; ++ sp[2*2+1] = wp[2*2+1]; ++ ++ sp = ctx->s[1]->d; ++ sp[0*2+0] = wp[3*2+0]; ++ sp[0*2+1] = wp[3*2+1]; ++ sp[1*2+0] = wp[3*2+0]; ++ sp[1*2+1] = wp[3*2+1]; ++ sp[2*2+0] = 0; ++ sp[2*2+1] = 0; ++ ++ sp = ctx->s[2]->d; ++ sp[0*2+0] = 0; ++ sp[0*2+1] = 0; ++ sp[1*2+0] = wp[4*2+0]; ++ sp[1*2+1] = wp[4*2+1]; ++ sp[2*2+0] = wp[4*2+0]; ++ sp[2*2+1] = wp[4*2+1]; ++ ++ sp = ctx->s[3]->d; ++ sp[0*2+0] = wp[5*2+0]; ++ sp[0*2+1] = wp[5*2+1]; ++ sp[1*2+0] = wp[5*2+0]; ++ sp[1*2+1] = wp[5*2+1]; ++ sp[2*2+0] = wp[5*2+0]; ++ sp[2*2+1] = wp[5*2+1]; ++ ++ ctx->s[0]->nlimbs = 6; ++ ctx->s[1]->nlimbs = 6; ++ ctx->s[2]->nlimbs = 6; ++ ctx->s[3]->nlimbs = 6; ++ ++ mpi_add (ctx->c, ctx->s[0], ctx->s[1]); ++ mpi_add (ctx->c, ctx->c, ctx->s[2]); ++ mpi_add (ctx->c, ctx->c, ctx->s[3]); ++ ++ while ( mpi_cmp (ctx->c, ctx->p ) >= 0 ) ++ mpi_sub ( ctx->c, ctx->c, ctx->p ); ++ mpi_set (w, ctx->c); ++ } ++ else if (ctx->nist_nbits == 384) ++ { ++ int i; ++ mpi_mul (w, u, v); ++ mpi_resize (w, 24); ++ wp = w->d; ++ ++#define NEXT(a) do { ctx->s[(a)]->nlimbs = 12; \ ++ sp = ctx->s[(a)]->d; \ ++ i = 0; } while (0) ++#define X(a) do { sp[i++] = wp[(a)];} while (0) ++#define X0(a) do { sp[i++] = 0; } while (0) ++ NEXT(0); ++ X(0);X(1);X(2);X(3);X(4);X(5);X(6);X(7);X(8);X(9);X(10);X(11); ++ NEXT(1); ++ X0();X0();X0();X0();X(21);X(22);X(23);X0();X0();X0();X0();X0(); ++ NEXT(2); ++ X(12);X(13);X(14);X(15);X(16);X(17);X(18);X(19);X(20);X(21);X(22);X(23); ++ NEXT(3); ++ X(21);X(22);X(23);X(12);X(13);X(14);X(15);X(16);X(17);X(18);X(19);X(20); ++ NEXT(4); ++ X0();X(23);X0();X(20);X(12);X(13);X(14);X(15);X(16);X(17);X(18);X(19); ++ NEXT(5); ++ X0();X0();X0();X0();X(20);X(21);X(22);X(23);X0();X0();X0();X0(); ++ NEXT(6); ++ X(20);X0();X0();X(21);X(22);X(23);X0();X0();X0();X0();X0();X0(); ++ NEXT(7); ++ X(23);X(12);X(13);X(14);X(15);X(16);X(17);X(18);X(19);X(20);X(21);X(22); ++ NEXT(8); ++ X0();X(20);X(21);X(22);X(23);X0();X0();X0();X0();X0();X0();X0(); ++ NEXT(9); ++ X0();X0();X0();X(23);X(23);X0();X0();X0();X0();X0();X0();X0(); ++#undef X0 ++#undef X ++#undef NEXT ++ mpi_add (ctx->c, ctx->s[0], ctx->s[1]); ++ mpi_add (ctx->c, ctx->c, ctx->s[1]); ++ mpi_add (ctx->c, ctx->c, ctx->s[2]); ++ mpi_add (ctx->c, ctx->c, ctx->s[3]); ++ mpi_add (ctx->c, ctx->c, ctx->s[4]); ++ mpi_add (ctx->c, ctx->c, ctx->s[5]); ++ mpi_add (ctx->c, ctx->c, ctx->s[6]); ++ mpi_sub (ctx->c, ctx->c, ctx->s[7]); ++ mpi_sub (ctx->c, ctx->c, ctx->s[8]); ++ mpi_sub (ctx->c, ctx->c, ctx->s[9]); ++ ++ while ( mpi_cmp (ctx->c, ctx->p ) >= 0 ) ++ mpi_sub ( ctx->c, ctx->c, ctx->p ); ++ while ( ctx->c->sign ) ++ mpi_add ( ctx->c, ctx->c, ctx->p ); ++ mpi_set (w, ctx->c); ++ } ++ else ++#endif /*0*/ ++ mpi_mulm (w, u, v, ctx->p); ++} ++ ++static void ++ec_powm (gcry_mpi_t w, const gcry_mpi_t b, const gcry_mpi_t e, ++ mpi_ec_t ctx) ++{ ++ mpi_powm (w, b, e, ctx->p); ++} ++ ++static void ++ec_invm (gcry_mpi_t x, gcry_mpi_t a, mpi_ec_t ctx) ++{ ++ mpi_invm (x, a, ctx->p); ++} ++ ++ ++ ++/* This function returns a new context for elliptic curve based on the ++ field GF(p). P is the prime specifying thuis field, A is the first ++ coefficient. ++ ++ This context needs to be released using _gcry_mpi_ec_free. */ ++mpi_ec_t ++_gcry_mpi_ec_init (gcry_mpi_t p, gcry_mpi_t a) ++{ ++ int i; ++ mpi_ec_t ctx; ++ gcry_mpi_t tmp; ++ ++ mpi_normalize (p); ++ mpi_normalize (a); ++ ++ /* Fixme: Do we want to check some constraints? e.g. ++ a < p ++ */ ++ ++ ctx = gcry_xcalloc (1, sizeof *ctx); ++ ++ ctx->p = mpi_copy (p); ++ ctx->a = mpi_copy (a); ++ ++ tmp = mpi_alloc_like (ctx->p); ++ mpi_sub_ui (tmp, ctx->p, 3); ++ ctx->a_is_pminus3 = !mpi_cmp (ctx->a, tmp); ++ mpi_free (tmp); ++ ++ ++ /* Allocate constants. */ ++ ctx->one = mpi_alloc_set_ui (1); ++ ctx->two = mpi_alloc_set_ui (2); ++ ctx->three = mpi_alloc_set_ui (3); ++ ctx->four = mpi_alloc_set_ui (4); ++ ctx->eight = mpi_alloc_set_ui (8); ++ ctx->two_inv_p = mpi_alloc (0); ++ ec_invm (ctx->two_inv_p, ctx->two, ctx); ++ ++ /* Allocate scratch variables. */ ++ for (i=0; i< DIM(ctx->scratch); i++) ++ ctx->scratch[i] = mpi_alloc_like (ctx->p); ++ ++ /* Prepare for fast reduction. */ ++ /* FIXME: need a test for NIST values. However it does not gain us ++ any real advantage, for 384 bits it is actually slower than using ++ mpi_mulm. */ ++/* ctx->nist_nbits = mpi_get_nbits (ctx->p); */ ++/* if (ctx->nist_nbits == 192) */ ++/* { */ ++/* for (i=0; i < 4; i++) */ ++/* ctx->s[i] = mpi_new (192); */ ++/* ctx->c = mpi_new (192*2); */ ++/* } */ ++/* else if (ctx->nist_nbits == 384) */ ++/* { */ ++/* for (i=0; i < 10; i++) */ ++/* ctx->s[i] = mpi_new (384); */ ++/* ctx->c = mpi_new (384*2); */ ++/* } */ ++ ++ return ctx; ++} ++ ++void ++_gcry_mpi_ec_free (mpi_ec_t ctx) ++{ ++ int i; ++ ++ if (!ctx) ++ return; ++ ++ mpi_free (ctx->p); ++ mpi_free (ctx->a); ++ ++ mpi_free (ctx->one); ++ mpi_free (ctx->two); ++ mpi_free (ctx->three); ++ mpi_free (ctx->four); ++ mpi_free (ctx->eight); ++ ++ mpi_free (ctx->two_inv_p); ++ ++ for (i=0; i< DIM(ctx->scratch); i++) ++ mpi_free (ctx->scratch[i]); ++ ++/* if (ctx->nist_nbits == 192) */ ++/* { */ ++/* for (i=0; i < 4; i++) */ ++/* mpi_free (ctx->s[i]); */ ++/* mpi_free (ctx->c); */ ++/* } */ ++/* else if (ctx->nist_nbits == 384) */ ++/* { */ ++/* for (i=0; i < 10; i++) */ ++/* mpi_free (ctx->s[i]); */ ++/* mpi_free (ctx->c); */ ++/* } */ ++ ++ gcry_free (ctx); ++} ++ ++/* Compute the affine coordinates from the projective coordinates in ++ POINT. Set them into X and Y. If one coordinate is not required, ++ X or Y may be passed as NULL. CTX is the usual context. Returns: 0 ++ on success or !0 if POINT is at infinity. */ ++int ++_gcry_mpi_ec_get_affine (gcry_mpi_t x, gcry_mpi_t y, mpi_point_t *point, ++ mpi_ec_t ctx) ++{ ++ gcry_mpi_t z1, z2, z3; ++ ++ if (!mpi_cmp_ui (point->z, 0)) ++ return -1; ++ ++ z1 = mpi_new (0); ++ z2 = mpi_new (0); ++ ec_invm (z1, point->z, ctx); /* z1 = z^(-1) mod p */ ++ ec_mulm (z2, z1, z1, ctx); /* z2 = z^(-2) mod p */ ++ ++ if (x) ++ ec_mulm (x, point->x, z2, ctx); ++ ++ if (y) ++ { ++ z3 = mpi_new (0); ++ ec_mulm (z3, z2, z1, ctx); /* z3 = z^(-3) mod p */ ++ ec_mulm (y, point->y, z3, ctx); ++ mpi_free (z3); ++ } ++ ++ mpi_free (z2); ++ mpi_free (z1); ++ return 0; ++} ++ ++ ++ ++ ++ ++/* RESULT = 2 * POINT */ ++void ++_gcry_mpi_ec_dup_point (mpi_point_t *result, mpi_point_t *point, mpi_ec_t ctx) ++{ ++#define x3 (result->x) ++#define y3 (result->y) ++#define z3 (result->z) ++#define t1 (ctx->scratch[0]) ++#define t2 (ctx->scratch[1]) ++#define t3 (ctx->scratch[2]) ++#define l1 (ctx->scratch[3]) ++#define l2 (ctx->scratch[4]) ++#define l3 (ctx->scratch[5]) ++ ++ if (!mpi_cmp_ui (point->y, 0) || !mpi_cmp_ui (point->z, 0)) ++ { ++ /* P_y == 0 || P_z == 0 => [1:1:0] */ ++ mpi_set_ui (x3, 1); ++ mpi_set_ui (y3, 1); ++ mpi_set_ui (z3, 0); ++ } ++ else ++ { ++ if (ctx->a_is_pminus3) /* Use the faster case. */ ++ { ++ /* L1 = 3(X - Z^2)(X + Z^2) */ ++ /* T1: used for Z^2. */ ++ /* T2: used for the right term. */ ++ ec_powm (t1, point->z, ctx->two, ctx); ++ ec_subm (l1, point->x, t1, ctx); ++ ec_mulm (l1, l1, ctx->three, ctx); ++ ec_addm (t2, point->x, t1, ctx); ++ ec_mulm (l1, l1, t2, ctx); ++ } ++ else /* Standard case. */ ++ { ++ /* L1 = 3X^2 + aZ^4 */ ++ /* T1: used for aZ^4. */ ++ ec_powm (l1, point->x, ctx->two, ctx); ++ ec_mulm (l1, l1, ctx->three, ctx); ++ ec_powm (t1, point->z, ctx->four, ctx); ++ ec_mulm (t1, t1, ctx->a, ctx); ++ ec_addm (l1, l1, t1, ctx); ++ } ++ /* Z3 = 2YZ */ ++ ec_mulm (z3, point->y, point->z, ctx); ++ ec_mulm (z3, z3, ctx->two, ctx); ++ ++ /* L2 = 4XY^2 */ ++ /* T2: used for Y2; required later. */ ++ ec_powm (t2, point->y, ctx->two, ctx); ++ ec_mulm (l2, t2, point->x, ctx); ++ ec_mulm (l2, l2, ctx->four, ctx); ++ ++ /* X3 = L1^2 - 2L2 */ ++ /* T1: used for L2^2. */ ++ ec_powm (x3, l1, ctx->two, ctx); ++ ec_mulm (t1, l2, ctx->two, ctx); ++ ec_subm (x3, x3, t1, ctx); ++ ++ /* L3 = 8Y^4 */ ++ /* T2: taken from above. */ ++ ec_powm (t2, t2, ctx->two, ctx); ++ ec_mulm (l3, t2, ctx->eight, ctx); ++ ++ /* Y3 = L1(L2 - X3) - L3 */ ++ ec_subm (y3, l2, x3, ctx); ++ ec_mulm (y3, y3, l1, ctx); ++ ec_subm (y3, y3, l3, ctx); ++ } ++ ++#undef x3 ++#undef y3 ++#undef z3 ++#undef t1 ++#undef t2 ++#undef t3 ++#undef l1 ++#undef l2 ++#undef l3 ++} ++ ++ ++ ++/* RESULT = P1 + P2 */ ++void ++_gcry_mpi_ec_add_points (mpi_point_t *result, ++ mpi_point_t *p1, mpi_point_t *p2, ++ mpi_ec_t ctx) ++{ ++#define x1 (p1->x ) ++#define y1 (p1->y ) ++#define z1 (p1->z ) ++#define x2 (p2->x ) ++#define y2 (p2->y ) ++#define z2 (p2->z ) ++#define x3 (result->x) ++#define y3 (result->y) ++#define z3 (result->z) ++#define l1 (ctx->scratch[0]) ++#define l2 (ctx->scratch[1]) ++#define l3 (ctx->scratch[2]) ++#define l4 (ctx->scratch[3]) ++#define l5 (ctx->scratch[4]) ++#define l6 (ctx->scratch[5]) ++#define l7 (ctx->scratch[6]) ++#define l8 (ctx->scratch[7]) ++#define l9 (ctx->scratch[8]) ++#define t1 (ctx->scratch[9]) ++#define t2 (ctx->scratch[10]) ++ ++ if ( (!mpi_cmp (x1, x2)) && (!mpi_cmp (y1, y2)) && (!mpi_cmp (z1, z2)) ) ++ { ++ /* Same point; need to call the duplicate function. */ ++ _gcry_mpi_ec_dup_point (result, p1, ctx); ++ } ++ else if (!mpi_cmp_ui (z1, 0)) ++ { ++ /* P1 is at infinity. */ ++ mpi_set (x3, p2->x); ++ mpi_set (y3, p2->y); ++ mpi_set (z3, p2->z); ++ } ++ else if (!mpi_cmp_ui (z2, 0)) ++ { ++ /* P2 is at infinity. */ ++ mpi_set (x3, p1->x); ++ mpi_set (y3, p1->y); ++ mpi_set (z3, p1->z); ++ } ++ else ++ { ++ int z1_is_one = !mpi_cmp_ui (z1, 1); ++ int z2_is_one = !mpi_cmp_ui (z2, 1); ++ ++ /* l1 = x1 z2^2 */ ++ /* l2 = x2 z1^2 */ ++ if (z2_is_one) ++ mpi_set (l1, x1); ++ else ++ { ++ ec_powm (l1, z2, ctx->two, ctx); ++ ec_mulm (l1, l1, x1, ctx); ++ } ++ if (z1_is_one) ++ mpi_set (l2, x1); ++ else ++ { ++ ec_powm (l2, z1, ctx->two, ctx); ++ ec_mulm (l2, l2, x2, ctx); ++ } ++ /* l3 = l1 - l2 */ ++ ec_subm (l3, l1, l2, ctx); ++ /* l4 = y1 z2^3 */ ++ ec_powm (l4, z2, ctx->three, ctx); ++ ec_mulm (l4, l4, y1, ctx); ++ /* l5 = y2 z1^3 */ ++ ec_powm (l5, z1, ctx->three, ctx); ++ ec_mulm (l5, l5, y2, ctx); ++ /* l6 = l4 - l5 */ ++ ec_subm (l6, l4, l5, ctx); ++ ++ if (!mpi_cmp_ui (l3, 0)) ++ { ++ if (!mpi_cmp_ui (l6, 0)) ++ { ++ /* P1 and P2 are the same - use duplicate function. */ ++ _gcry_mpi_ec_dup_point (result, p1, ctx); ++ } ++ else ++ { ++ /* P1 is the inverse of P2. */ ++ mpi_set_ui (x3, 1); ++ mpi_set_ui (y3, 1); ++ mpi_set_ui (z3, 0); ++ } ++ } ++ else ++ { ++ /* l7 = l1 + l2 */ ++ ec_addm (l7, l1, l2, ctx); ++ /* l8 = l4 + l5 */ ++ ec_addm (l8, l4, l5, ctx); ++ /* z3 = z1 z2 l3 */ ++ ec_mulm (z3, z1, z2, ctx); ++ ec_mulm (z3, z3, l3, ctx); ++ /* x3 = l6^2 - l7 l3^2 */ ++ ec_powm (t1, l6, ctx->two, ctx); ++ ec_powm (t2, l3, ctx->two, ctx); ++ ec_mulm (t2, t2, l7, ctx); ++ ec_subm (x3, t1, t2, ctx); ++ /* l9 = l7 l3^2 - 2 x3 */ ++ ec_mulm (t1, x3, ctx->two, ctx); ++ ec_subm (l9, t2, t1, ctx); ++ /* y3 = (l9 l6 - l8 l3^3)/2 */ ++ ec_mulm (l9, l9, l6, ctx); ++ ec_powm (t1, l3, ctx->three, ctx); /* fixme: Use saved value*/ ++ ec_mulm (t1, t1, l8, ctx); ++ ec_subm (y3, l9, t1, ctx); ++ ec_mulm (y3, y3, ctx->two_inv_p, ctx); ++ } ++ } ++ ++#undef x1 ++#undef y1 ++#undef z1 ++#undef x2 ++#undef y2 ++#undef z2 ++#undef x3 ++#undef y3 ++#undef z3 ++#undef l1 ++#undef l2 ++#undef l3 ++#undef l4 ++#undef l5 ++#undef l6 ++#undef l7 ++#undef l8 ++#undef l9 ++#undef t1 ++#undef t2 ++} ++ ++ ++ ++/* Scalar point multiplication - the main function for ECC. If takes ++ an integer SCALAR and a POINT as well as the usual context CTX. ++ RESULT will be set to the resulting point. */ ++void ++_gcry_mpi_ec_mul_point (mpi_point_t *result, ++ gcry_mpi_t scalar, mpi_point_t *point, ++ mpi_ec_t ctx) ++{ ++#if 0 ++ /* Simple left to right binary method. GECC Algorithm 3.27 */ ++ unsigned int nbits; ++ int i; ++ ++ nbits = mpi_get_nbits (scalar); ++ mpi_set_ui (result->x, 1); ++ mpi_set_ui (result->y, 1); ++ mpi_set_ui (result->z, 0); ++ ++ for (i=nbits-1; i >= 0; i--) ++ { ++ _gcry_mpi_ec_dup_point (result, result, ctx); ++ if (mpi_test_bit (scalar, i) == 1) ++ _gcry_mpi_ec_add_points (result, result, point, ctx); ++ } ++ ++#else ++ gcry_mpi_t x1, y1, z1, k, h, yy; ++ unsigned int i, loops; ++ mpi_point_t p1, p2, p1inv; ++ ++ x1 = mpi_alloc_like (ctx->p); ++ y1 = mpi_alloc_like (ctx->p); ++ h = mpi_alloc_like (ctx->p); ++ k = mpi_copy (scalar); ++ yy = mpi_copy (point->y); ++ ++ if ( mpi_is_neg (k) ) ++ { ++ k->sign = 0; ++ ec_invm (yy, yy, ctx); ++ } ++ ++ if (!mpi_cmp_ui (point->z, 1)) ++ { ++ mpi_set (x1, point->x); ++ mpi_set (y1, yy); ++ } ++ else ++ { ++ gcry_mpi_t z2, z3; ++ ++ z2 = mpi_alloc_like (ctx->p); ++ z3 = mpi_alloc_like (ctx->p); ++ ec_mulm (z2, point->z, point->z, ctx); ++ ec_mulm (z3, point->z, z2, ctx); ++ ec_invm (z2, z2, ctx); ++ ec_mulm (x1, point->x, z2, ctx); ++ ec_invm (z3, z3, ctx); ++ ec_mulm (y1, yy, z3, ctx); ++ mpi_free (z2); ++ mpi_free (z3); ++ } ++ z1 = mpi_copy (ctx->one); ++ ++ mpi_mul (h, k, ctx->three); /* h = 3k */ ++ loops = mpi_get_nbits (h); ++ ++ mpi_set (result->x, point->x); ++ mpi_set (result->y, yy); mpi_free (yy); yy = NULL; ++ mpi_set (result->z, point->z); ++ ++ p1.x = x1; x1 = NULL; ++ p1.y = y1; y1 = NULL; ++ p1.z = z1; z1 = NULL; ++ point_init (&p2); ++ point_init (&p1inv); ++ ++ for (i=loops-2; i > 0; i--) ++ { ++ _gcry_mpi_ec_dup_point (result, result, ctx); ++ if (mpi_test_bit (h, i) == 1 && mpi_test_bit (k, i) == 0) ++ { ++ point_set (&p2, result); ++ _gcry_mpi_ec_add_points (result, &p2, &p1, ctx); ++ } ++ if (mpi_test_bit (h, i) == 0 && mpi_test_bit (k, i) == 1) ++ { ++ point_set (&p2, result); ++ /* Invert point: y = p - y mod p */ ++ point_set (&p1inv, &p1); ++ ec_subm (p1inv.y, ctx->p, p1inv.y, ctx); ++ _gcry_mpi_ec_add_points (result, &p2, &p1inv, ctx); ++ } ++ } ++ ++ point_free (&p1); ++ point_free (&p2); ++ point_free (&p1inv); ++ mpi_free (h); ++ mpi_free (k); ++#endif ++} +diff --git a/grub-core/lib/libgcrypt/mpi/generic/Manifest b/grub-core/lib/libgcrypt/mpi/generic/Manifest +new file mode 100644 +index 0000000..c429fde +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/generic/Manifest +@@ -0,0 +1,29 @@ ++# Manifest - checksums ++# Copyright 2003 Free Software Foundation, Inc. ++# ++# This file is part of Libgcrypt. ++# ++# Libgcrypt is free software; you can redistribute it and/or modify ++# it under the terms of the GNU Lesser general Public License as ++# published by the Free Software Foundation; either version 2.1 of ++# the License, or (at your option) any later version. ++# ++# Libgcrypt 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 Lesser General Public License for more details. ++# ++# You should have received a copy of the GNU Lesser General Public ++# License along with this program; if not, write to the Free Software ++# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ ++mpih-add1.c iQCVAwUAP+Lj2DEAnp832S/7AQKn/AQAwQLWggl6zNQ5EZ+lE+jKV8W3FsogW3/6tp9T5rrSR5JnlWyoHQ9/Pu4knOcLjS6nIfVOiAEifu3nuIysQr9jDSSSJA2LylSUBSXKLKDamPsOCwXOLxiZODslJT3CCGAUtLvXJrWDbTZQrkEuwnLnjQFDzuA7iY9JLrG9kAoXD6Q==WoWm ++mpih-mul1.c iQCVAwUAP+LkCTEAnp832S/7AQKFVQP+MhBNjcY73JtnsHZfnaVZq3TiKwN151cWV51nDc1RnTaMhSIFeuNlj3vNML2W0Gn8n+GnyiWE2XXdQEaik6BL02eekUn9aq7I/rdpnTHuOjQPK1uwjuNl8RuJ9YrERBAxq4oB71f+iwMab8dsMSUlVC+NdeAocRqLLgnR/efkdLc==2Tkb ++mpih-mul2.c iQCVAwUAP+LkMjEAnp832S/7AQLPeAQAqmRzxFe/mDqTdZr/pTXT8RVyB1vKB0Ei2THV05BxmI4OPv39uysfFpLMt/INsX7AGqdOlj4jOZ/qNaFXR1ceMrlSXvo8u/epk6rCXFp82kM7Qs983LjoP//PrMCkYkXwblaVrgUGiBUCbuPMliWTK6qKkxxXtEfqZ7nVbEWdBx8==Kwhl ++mpih-mul3.c iQCVAwUAP+LkVDEAnp832S/7AQL91gP/Qd5iZWxRiN5DdEIVHAedoNvl23NPrT2UUdXvnSK49DpplTxkLiMBj0WqCayG/YIET2NpMRCeLvAZNcSt6lOm0bSZDYo1Hv/N+UoqD3V1McjY16REBv/nnPaMWMZcx7rl5yKTVZiX2PgV6oQOL7Yfrt5ZIOlrHBRs9S2/zcCaVz0==9BQe ++mpih-lshift.c iQCVAwUAP+LlATEAnp832S/7AQIACAQAhMrpx0SRXE/LN1NkjMO9n74nMrvmzYJyru0gw2O4BYrUPvD/LWGju2FZaggKV0IBjmi0cDoCrNeK9EGjKOO1lfgODbX2IZ1LUhr9jDuMj0QRqj6T9YkAFYTNUk4GfpwIf7T6Ybo7c78Jx93PidCJt7d39eMMEalooC7LZ4IU3NM==nZ4k ++mpih-rshift.c iQCVAwUAP+LlIjEAnp832S/7AQKiuAP/eYC2ZScd+taBx/kNzRvGjA0eAXvORMkMLV6Ot+OXVzVUi04eoP2yXdxSNFKwUj12p8GWXkdoMG3aOGBKg2a7bY5Q5RUho3hUWb9UsVYVUfXLf7IOTt/3a6MLh2CmV5dFPWJmSlbCyQRcn6n/fLDeJ3A2bWTS/BhqGfpOXUIU1ws==jCf8 ++mpih-sub1.c iQCVAwUAP+LlZzEAnp832S/7AQIEPgP/dLHTDRbPrYJhsLp9SjGstU1M8/IC5XytcDtO3NQeu4mx6vaXjpujtsTvKIbX4QL5IahNntVVKv1xFLEm2yFg7L2ns0uD/mfwGgOhCG1j2o/SaTAWP5KxP7ae5UDcZl2w6NWvEuMj9t32zmziAZjP8W73A37FUspeRDYiL9sQzkI==QQzk ++udiv-w-sdiv.c iQCVAwUAP+Lk0TEAnp832S/7AQICXAQAsxe1SQD4+xZaZTqBC0V9Cyuo0mrdccnRFzthOtm0ARwKFXU2cuLW/ZBOkmeWOVmOFhBp22/I8dEGYnMA3gcfmOMCpNu9i9zk/XHfptdunA1MnOe3GsoWgfHL0rhpAyPhp/X043ICB41NElnnuxADuQQlD4Z1fca5ygYxMr2crJg==EI/6 ++mpi-asm-defs.h iQCVAwUAP+LkgDEAnp832S/7AQK0FgQAxJZ7xvXhoZa33GWe23LRb3asrno/loZSyAIXrntqtVH8M3pEsCY0OyW4ry4hX2RnxpuhRCM/PdRNLG3xXyMSVIhkHU8WVRLqzF2LLjEkyU3cAmHnnTQ9aO/XpUWtJGTZ8q2bv7ZsAEi4aPl0p6KhPXcPgM9vQ2XcyOPn3Dl0d6Q==xpjI ++$names$ iQCVAwUAP+LmNDEAnp832S/7AQJa+gP+KQNJpbNOgc+s2UX+Ya2gDaOFcAROImIllhg3ej8EaBF8xxdHmWT1zaKwTwi3moEEleykMR104YAGWyQeMbFYiuPPBW+ohrT6KxRBVJpIA9auOOqqJMyglZyoR3Hv7gduVYUW1h/DebnqiKXKEfzQDFqYuT0ayuteoOR4B5NICbE==nLSh +diff --git a/grub-core/lib/libgcrypt/mpi/generic/distfiles b/grub-core/lib/libgcrypt/mpi/generic/distfiles +new file mode 100644 +index 0000000..9810eef +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/generic/distfiles +@@ -0,0 +1,11 @@ ++Manifest ++mpih-add1.c ++mpih-mul1.c ++mpih-mul2.c ++mpih-mul3.c ++mpih-lshift.c ++mpih-rshift.c ++mpih-sub1.c ++udiv-w-sdiv.c ++mpi-asm-defs.h ++ +diff --git a/grub-core/lib/libgcrypt/mpi/generic/mpi-asm-defs.h b/grub-core/lib/libgcrypt/mpi/generic/mpi-asm-defs.h +new file mode 100644 +index 0000000..13424e2 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/generic/mpi-asm-defs.h +@@ -0,0 +1,10 @@ ++/* This file defines some basic constants for the MPI machinery. We ++ * need to define the types on a per-CPU basis, so it is done with ++ * this file here. */ ++#define BYTES_PER_MPI_LIMB (SIZEOF_UNSIGNED_LONG) ++ ++ ++ ++ ++ ++ +diff --git a/grub-core/lib/libgcrypt/mpi/generic/mpih-add1.c b/grub-core/lib/libgcrypt/mpi/generic/mpih-add1.c +new file mode 100644 +index 0000000..4a84df6 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/generic/mpih-add1.c +@@ -0,0 +1,65 @@ ++/* mpihelp-add_1.c - MPI helper functions ++ * Copyright (C) 1994, 1996, 1997, 1998, ++ * 2000, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ * ++ * Note: This code is heavily based on the GNU MP Library. ++ * Actually it's the same code with only minor changes in the ++ * way the data is stored; this is to support the abstraction ++ * of an optional secure memory allocation which may be used ++ * to avoid revealing of sensitive data due to paging etc. ++ */ ++ ++#include ++#include ++#include ++#include "mpi-internal.h" ++#include "longlong.h" ++ ++mpi_limb_t ++_gcry_mpih_add_n (mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, ++ mpi_ptr_t s2_ptr, mpi_size_t size) ++{ ++ mpi_limb_t x, y, cy; ++ mpi_size_t j; ++ ++ /* The loop counter and index J goes from -SIZE to -1. This way ++ the loop becomes faster. */ ++ j = -size; ++ ++ /* Offset the base pointers to compensate for the negative indices. */ ++ s1_ptr -= j; ++ s2_ptr -= j; ++ res_ptr -= j; ++ ++ cy = 0; ++ do ++ { ++ y = s2_ptr[j]; ++ x = s1_ptr[j]; ++ y += cy; /* add previous carry to one addend */ ++ cy = y < cy; /* get out carry from that addition */ ++ y += x; /* add other addend */ ++ cy += y < x; /* get out carry from that add, combine */ ++ res_ptr[j] = y; ++ } ++ while ( ++j ); ++ ++ return cy; ++} ++ +diff --git a/grub-core/lib/libgcrypt/mpi/generic/mpih-lshift.c b/grub-core/lib/libgcrypt/mpi/generic/mpih-lshift.c +new file mode 100644 +index 0000000..f48c12c +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/generic/mpih-lshift.c +@@ -0,0 +1,68 @@ ++/* mpi-lshift.c - MPI helper functions ++ * Copyright (C) 1994, 1996, 1998, 2001, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ * ++ * Note: This code is heavily based on the GNU MP Library. ++ * Actually it's the same code with only minor changes in the ++ * way the data is stored; this is to support the abstraction ++ * of an optional secure memory allocation which may be used ++ * to avoid revealing of sensitive data due to paging etc. ++ */ ++ ++#include ++#include ++#include ++#include "mpi-internal.h" ++ ++/* Shift U (pointed to by UP and USIZE digits long) CNT bits to the left ++ * and store the USIZE least significant digits of the result at WP. ++ * Return the bits shifted out from the most significant digit. ++ * ++ * Argument constraints: ++ * 1. 0 < CNT < BITS_PER_MP_LIMB ++ * 2. If the result is to be written over the input, WP must be >= UP. ++ */ ++ ++mpi_limb_t ++_gcry_mpih_lshift( mpi_ptr_t wp, mpi_ptr_t up, mpi_size_t usize, ++ unsigned int cnt) ++{ ++ mpi_limb_t high_limb, low_limb; ++ unsigned sh_1, sh_2; ++ mpi_size_t i; ++ mpi_limb_t retval; ++ ++ sh_1 = cnt; ++ wp += 1; ++ sh_2 = BITS_PER_MPI_LIMB - sh_1; ++ i = usize - 1; ++ low_limb = up[i]; ++ retval = low_limb >> sh_2; ++ high_limb = low_limb; ++ while ( --i >= 0 ) ++ { ++ low_limb = up[i]; ++ wp[i] = (high_limb << sh_1) | (low_limb >> sh_2); ++ high_limb = low_limb; ++ } ++ wp[i] = high_limb << sh_1; ++ ++ return retval; ++} ++ ++ +diff --git a/grub-core/lib/libgcrypt/mpi/generic/mpih-mul1.c b/grub-core/lib/libgcrypt/mpi/generic/mpih-mul1.c +new file mode 100644 +index 0000000..0e8197d +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/generic/mpih-mul1.c +@@ -0,0 +1,62 @@ ++/* mpihelp-mul_1.c - MPI helper functions ++ * Copyright (C) 1994, 1996, 1997, 1998, 2001, ++ * 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ * ++ * Note: This code is heavily based on the GNU MP Library. ++ * Actually it's the same code with only minor changes in the ++ * way the data is stored; this is to support the abstraction ++ * of an optional secure memory allocation which may be used ++ * to avoid revealing of sensitive data due to paging etc. ++ */ ++ ++#include ++#include ++#include ++#include "mpi-internal.h" ++#include "longlong.h" ++ ++mpi_limb_t ++_gcry_mpih_mul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size, ++ mpi_limb_t s2_limb) ++{ ++ mpi_limb_t cy_limb; ++ mpi_size_t j; ++ mpi_limb_t prod_high, prod_low; ++ ++ /* The loop counter and index J goes from -S1_SIZE to -1. This way ++ * the loop becomes faster. */ ++ j = -s1_size; ++ ++ /* Offset the base pointers to compensate for the negative indices. */ ++ s1_ptr -= j; ++ res_ptr -= j; ++ ++ cy_limb = 0; ++ do ++ { ++ umul_ppmm( prod_high, prod_low, s1_ptr[j], s2_limb ); ++ prod_low += cy_limb; ++ cy_limb = (prod_low < cy_limb?1:0) + prod_high; ++ res_ptr[j] = prod_low; ++ } ++ while( ++j ); ++ ++ return cy_limb; ++} ++ +diff --git a/grub-core/lib/libgcrypt/mpi/generic/mpih-mul2.c b/grub-core/lib/libgcrypt/mpi/generic/mpih-mul2.c +new file mode 100644 +index 0000000..3b75496 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/generic/mpih-mul2.c +@@ -0,0 +1,68 @@ ++/* mpih-mul2.c - MPI helper functions ++ * Copyright (C) 1994, 1996, 1997, 1998, 2001, ++ * 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ * ++ * Note: This code is heavily based on the GNU MP Library. ++ * Actually it's the same code with only minor changes in the ++ * way the data is stored; this is to support the abstraction ++ * of an optional secure memory allocation which may be used ++ * to avoid revealing of sensitive data due to paging etc. ++ */ ++ ++#include ++#include ++#include ++#include "mpi-internal.h" ++#include "longlong.h" ++ ++ ++mpi_limb_t ++_gcry_mpih_addmul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, ++ mpi_size_t s1_size, mpi_limb_t s2_limb) ++{ ++ mpi_limb_t cy_limb; ++ mpi_size_t j; ++ mpi_limb_t prod_high, prod_low; ++ mpi_limb_t x; ++ ++ /* The loop counter and index J goes from -SIZE to -1. This way ++ * the loop becomes faster. */ ++ j = -s1_size; ++ res_ptr -= j; ++ s1_ptr -= j; ++ ++ cy_limb = 0; ++ do ++ { ++ umul_ppmm( prod_high, prod_low, s1_ptr[j], s2_limb ); ++ ++ prod_low += cy_limb; ++ cy_limb = (prod_low < cy_limb?1:0) + prod_high; ++ ++ x = res_ptr[j]; ++ prod_low = x + prod_low; ++ cy_limb += prod_low < x?1:0; ++ res_ptr[j] = prod_low; ++ } ++ while ( ++j ); ++ ++ return cy_limb; ++} ++ ++ +diff --git a/grub-core/lib/libgcrypt/mpi/generic/mpih-mul3.c b/grub-core/lib/libgcrypt/mpi/generic/mpih-mul3.c +new file mode 100644 +index 0000000..5e84f94 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/generic/mpih-mul3.c +@@ -0,0 +1,68 @@ ++/* mpih-mul3.c - MPI helper functions ++ * Copyright (C) 1994, 1996, 1997, 1998, 2001, ++ * 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ * ++ * Note: This code is heavily based on the GNU MP Library. ++ * Actually it's the same code with only minor changes in the ++ * way the data is stored; this is to support the abstraction ++ * of an optional secure memory allocation which may be used ++ * to avoid revealing of sensitive data due to paging etc. ++ */ ++ ++#include ++#include ++#include ++#include "mpi-internal.h" ++#include "longlong.h" ++ ++ ++mpi_limb_t ++_gcry_mpih_submul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, ++ mpi_size_t s1_size, mpi_limb_t s2_limb) ++{ ++ mpi_limb_t cy_limb; ++ mpi_size_t j; ++ mpi_limb_t prod_high, prod_low; ++ mpi_limb_t x; ++ ++ /* The loop counter and index J goes from -SIZE to -1. This way ++ * the loop becomes faster. */ ++ j = -s1_size; ++ res_ptr -= j; ++ s1_ptr -= j; ++ ++ cy_limb = 0; ++ do ++ { ++ umul_ppmm( prod_high, prod_low, s1_ptr[j], s2_limb); ++ ++ prod_low += cy_limb; ++ cy_limb = (prod_low < cy_limb?1:0) + prod_high; ++ ++ x = res_ptr[j]; ++ prod_low = x - prod_low; ++ cy_limb += prod_low > x?1:0; ++ res_ptr[j] = prod_low; ++ } ++ while( ++j ); ++ ++ return cy_limb; ++} ++ ++ +diff --git a/grub-core/lib/libgcrypt/mpi/generic/mpih-rshift.c b/grub-core/lib/libgcrypt/mpi/generic/mpih-rshift.c +new file mode 100644 +index 0000000..e40794f +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/generic/mpih-rshift.c +@@ -0,0 +1,67 @@ ++/* mpih-rshift.c - MPI helper functions ++ * Copyright (C) 1994, 1996, 1998, 1999, ++ * 2000, 2001, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ * ++ * Note: This code is heavily based on the GNU MP Library. ++ * Actually it's the same code with only minor changes in the ++ * way the data is stored; this is to support the abstraction ++ * of an optional secure memory allocation which may be used ++ * to avoid revealing of sensitive data due to paging etc. ++ */ ++ ++#include ++#include ++#include ++#include "mpi-internal.h" ++ ++ ++/* Shift U (pointed to by UP and USIZE limbs long) CNT bits to the right ++ * and store the USIZE least significant limbs of the result at WP. ++ * The bits shifted out to the right are returned. ++ * ++ * Argument constraints: ++ * 1. 0 < CNT < BITS_PER_MP_LIMB ++ * 2. If the result is to be written over the input, WP must be <= UP. ++ */ ++ ++mpi_limb_t ++_gcry_mpih_rshift( mpi_ptr_t wp, mpi_ptr_t up, mpi_size_t usize, unsigned cnt) ++{ ++ mpi_limb_t high_limb, low_limb; ++ unsigned sh_1, sh_2; ++ mpi_size_t i; ++ mpi_limb_t retval; ++ ++ sh_1 = cnt; ++ wp -= 1; ++ sh_2 = BITS_PER_MPI_LIMB - sh_1; ++ high_limb = up[0]; ++ retval = high_limb << sh_2; ++ low_limb = high_limb; ++ for (i=1; i < usize; i++) ++ { ++ high_limb = up[i]; ++ wp[i] = (low_limb >> sh_1) | (high_limb << sh_2); ++ low_limb = high_limb; ++ } ++ wp[i] = low_limb >> sh_1; ++ ++ return retval; ++} ++ +diff --git a/grub-core/lib/libgcrypt/mpi/generic/mpih-sub1.c b/grub-core/lib/libgcrypt/mpi/generic/mpih-sub1.c +new file mode 100644 +index 0000000..e88821b +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/generic/mpih-sub1.c +@@ -0,0 +1,66 @@ ++/* mpihelp-add_2.c - MPI helper functions ++ * Copyright (C) 1994, 1996, 1997, 1998, 2001, ++ * 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ * ++ * Note: This code is heavily based on the GNU MP Library. ++ * Actually it's the same code with only minor changes in the ++ * way the data is stored; this is to support the abstraction ++ * of an optional secure memory allocation which may be used ++ * to avoid revealing of sensitive data due to paging etc. ++ */ ++ ++#include ++#include ++#include ++#include "mpi-internal.h" ++#include "longlong.h" ++ ++mpi_limb_t ++_gcry_mpih_sub_n( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, ++ mpi_ptr_t s2_ptr, mpi_size_t size) ++{ ++ mpi_limb_t x, y, cy; ++ mpi_size_t j; ++ ++ /* The loop counter and index J goes from -SIZE to -1. This way ++ the loop becomes faster. */ ++ j = -size; ++ ++ /* Offset the base pointers to compensate for the negative indices. */ ++ s1_ptr -= j; ++ s2_ptr -= j; ++ res_ptr -= j; ++ ++ cy = 0; ++ do ++ { ++ y = s2_ptr[j]; ++ x = s1_ptr[j]; ++ y += cy; /* add previous carry to subtrahend */ ++ cy = y < cy; /* get out carry from that addition */ ++ y = x - y; /* main subtract */ ++ cy += y > x; /* get out carry from the subtract, combine */ ++ res_ptr[j] = y; ++ } ++ while( ++j ); ++ ++ return cy; ++} ++ ++ +diff --git a/grub-core/lib/libgcrypt/mpi/generic/udiv-w-sdiv.c b/grub-core/lib/libgcrypt/mpi/generic/udiv-w-sdiv.c +new file mode 100644 +index 0000000..e80d98b +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/generic/udiv-w-sdiv.c +@@ -0,0 +1,133 @@ ++/* mpih-w-sdiv -- implement udiv_qrnnd on machines with only signed ++ * division. ++ * Copyright (C) 1992, 1994, 1996, 1998, 2002 Free Software Foundation, Inc. ++ * Contributed by Peter L. Montgomery. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ */ ++ ++#include ++#include ++#include ++#include "mpi-internal.h" ++#include "longlong.h" ++ ++ ++#if 0 /* not yet ported to MPI */ ++ ++mpi_limb_t ++mpihelp_udiv_w_sdiv( mpi_limp_t *rp, ++ mpi_limp_t *a1, ++ mpi_limp_t *a0, ++ mpi_limp_t *d ) ++{ ++ mp_limb_t q, r; ++ mp_limb_t c0, c1, b1; ++ ++ if ((mpi_limb_signed_t) d >= 0) ++ { ++ if (a1 < d - a1 - (a0 >> (BITS_PER_MP_LIMB - 1))) ++ { ++ /* dividend, divisor, and quotient are nonnegative */ ++ sdiv_qrnnd (q, r, a1, a0, d); ++ } ++ else ++ { ++ /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */ ++ sub_ddmmss (c1, c0, a1, a0, d >> 1, d << (BITS_PER_MP_LIMB - 1)); ++ /* Divide (c1*2^32 + c0) by d */ ++ sdiv_qrnnd (q, r, c1, c0, d); ++ /* Add 2^31 to quotient */ ++ q += (mp_limb_t) 1 << (BITS_PER_MP_LIMB - 1); ++ } ++ } ++ else ++ { ++ b1 = d >> 1; /* d/2, between 2^30 and 2^31 - 1 */ ++ c1 = a1 >> 1; /* A/2 */ ++ c0 = (a1 << (BITS_PER_MP_LIMB - 1)) + (a0 >> 1); ++ ++ if (a1 < b1) /* A < 2^32*b1, so A/2 < 2^31*b1 */ ++ { ++ sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */ ++ ++ r = 2*r + (a0 & 1); /* Remainder from A/(2*b1) */ ++ if ((d & 1) != 0) ++ { ++ if (r >= q) ++ r = r - q; ++ else if (q - r <= d) ++ { ++ r = r - q + d; ++ q--; ++ } ++ else ++ { ++ r = r - q + 2*d; ++ q -= 2; ++ } ++ } ++ } ++ else if (c1 < b1) /* So 2^31 <= (A/2)/b1 < 2^32 */ ++ { ++ c1 = (b1 - 1) - c1; ++ c0 = ~c0; /* logical NOT */ ++ ++ sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */ ++ ++ q = ~q; /* (A/2)/b1 */ ++ r = (b1 - 1) - r; ++ ++ r = 2*r + (a0 & 1); /* A/(2*b1) */ ++ ++ if ((d & 1) != 0) ++ { ++ if (r >= q) ++ r = r - q; ++ else if (q - r <= d) ++ { ++ r = r - q + d; ++ q--; ++ } ++ else ++ { ++ r = r - q + 2*d; ++ q -= 2; ++ } ++ } ++ } ++ else /* Implies c1 = b1 */ ++ { /* Hence a1 = d - 1 = 2*b1 - 1 */ ++ if (a0 >= -d) ++ { ++ q = -1; ++ r = a0 + d; ++ } ++ else ++ { ++ q = -2; ++ r = a0 + 2*d; ++ } ++ } ++ } ++ ++ *rp = r; ++ return q; ++} ++ ++#endif ++ +diff --git a/grub-core/lib/libgcrypt/mpi/hppa/README b/grub-core/lib/libgcrypt/mpi/hppa/README +new file mode 100644 +index 0000000..5a2d5fd +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/hppa/README +@@ -0,0 +1,84 @@ ++This directory contains mpn functions for various HP PA-RISC chips. Code ++that runs faster on the PA7100 and later implementations, is in the pa7100 ++directory. ++ ++RELEVANT OPTIMIZATION ISSUES ++ ++ Load and Store timing ++ ++On the PA7000 no memory instructions can issue the two cycles after a store. ++For the PA7100, this is reduced to one cycle. ++ ++The PA7100 has a lookup-free cache, so it helps to schedule loads and the ++dependent instruction really far from each other. ++ ++STATUS ++ ++1. mpn_mul_1 could be improved to 6.5 cycles/limb on the PA7100, using the ++ instructions bwlow (but some sw pipelining is needed to avoid the ++ xmpyu-fstds delay): ++ ++ fldds s1_ptr ++ ++ xmpyu ++ fstds N(%r30) ++ xmpyu ++ fstds N(%r30) ++ ++ ldws N(%r30) ++ ldws N(%r30) ++ ldws N(%r30) ++ ldws N(%r30) ++ ++ addc ++ stws res_ptr ++ addc ++ stws res_ptr ++ ++ addib Loop ++ ++2. mpn_addmul_1 could be improved from the current 10 to 7.5 cycles/limb ++ (asymptotically) on the PA7100, using the instructions below. With proper ++ sw pipelining and the unrolling level below, the speed becomes 8 ++ cycles/limb. ++ ++ fldds s1_ptr ++ fldds s1_ptr ++ ++ xmpyu ++ fstds N(%r30) ++ xmpyu ++ fstds N(%r30) ++ xmpyu ++ fstds N(%r30) ++ xmpyu ++ fstds N(%r30) ++ ++ ldws N(%r30) ++ ldws N(%r30) ++ ldws N(%r30) ++ ldws N(%r30) ++ ldws N(%r30) ++ ldws N(%r30) ++ ldws N(%r30) ++ ldws N(%r30) ++ addc ++ addc ++ addc ++ addc ++ addc %r0,%r0,cy-limb ++ ++ ldws res_ptr ++ ldws res_ptr ++ ldws res_ptr ++ ldws res_ptr ++ add ++ stws res_ptr ++ addc ++ stws res_ptr ++ addc ++ stws res_ptr ++ addc ++ stws res_ptr ++ ++ addib +diff --git a/grub-core/lib/libgcrypt/mpi/hppa/distfiles b/grub-core/lib/libgcrypt/mpi/hppa/distfiles +new file mode 100644 +index 0000000..7f24205 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/hppa/distfiles +@@ -0,0 +1,7 @@ ++README ++udiv-qrnnd.S ++mpih-add1.S ++mpih-sub1.S ++mpih-lshift.S ++mpih-rshift.S ++ +diff --git a/grub-core/lib/libgcrypt/mpi/hppa/mpih-add1.S b/grub-core/lib/libgcrypt/mpi/hppa/mpih-add1.S +new file mode 100644 +index 0000000..3bc0e5e +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/hppa/mpih-add1.S +@@ -0,0 +1,70 @@ ++/* hppa add_n -- Add two limb vectors of the same length > 0 and store ++ * sum in a third limb vector. ++ * ++ * Copyright (C) 1992, 1994, 1998, ++ * 2001, 2002 Fee Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ * ++ * Note: This code is heavily based on the GNU MP Library. ++ * Actually it's the same code with only minor changes in the ++ * way the data is stored; this is to support the abstraction ++ * of an optional secure memory allocation which may be used ++ * to avoid revealing of sensitive data due to paging etc. ++ */ ++ ++ ++ ++/******************* ++ * mpi_limb_t ++ * _gcry_mpih_add_n( mpi_ptr_t res_ptr, (gr26) ++ * mpi_ptr_t s1_ptr, (gr25) ++ * mpi_ptr_t s2_ptr, (gr24) ++ * mpi_size_t size) (gr23) ++ * ++ * One might want to unroll this as for other processors, but it turns ++ * out that the data cache contention after a store makes such ++ * unrolling useless. We can't come under 5 cycles/limb anyway. ++ */ ++ ++ .code ++ .export _gcry_mpih_add_n ++ .label _gcry_mpih_add_n ++ .proc ++ .callinfo frame=0,no_calls ++ .entry ++ ++ ldws,ma 4(0,%r25),%r20 ++ ldws,ma 4(0,%r24),%r19 ++ ++ addib,= -1,%r23,L$end ; check for (SIZE == 1) ++ add %r20,%r19,%r28 ; add first limbs ignoring cy ++ ++ .label L$loop ++ ldws,ma 4(0,%r25),%r20 ++ ldws,ma 4(0,%r24),%r19 ++ stws,ma %r28,4(0,%r26) ++ addib,<> -1,%r23,L$loop ++ addc %r20,%r19,%r28 ++ ++ .label L$end ++ stws %r28,0(0,%r26) ++ bv 0(%r2) ++ addc %r0,%r0,%r28 ++ ++ .exit ++ .procend +diff --git a/grub-core/lib/libgcrypt/mpi/hppa/mpih-lshift.S b/grub-core/lib/libgcrypt/mpi/hppa/mpih-lshift.S +new file mode 100644 +index 0000000..91b29bb +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/hppa/mpih-lshift.S +@@ -0,0 +1,77 @@ ++/* hppa lshift ++ * ++ * Copyright (C) 1992, 1994, 1998 ++ * 2001, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ */ ++ ++ ++ ++/******************* ++ * mpi_limb_t ++ * _gcry_mpih_lshift( mpi_ptr_t wp, (gr26) ++ * mpi_ptr_t up, (gr25) ++ * mpi_size_t usize, (gr24) ++ * unsigned cnt) (gr23) ++ */ ++ ++ .code ++ .export _gcry_mpih_lshift ++ .label _gcry_mpih_lshift ++ .proc ++ .callinfo frame=64,no_calls ++ .entry ++ ++ sh2add %r24,%r25,%r25 ++ sh2add %r24,%r26,%r26 ++ ldws,mb -4(0,%r25),%r22 ++ subi 32,%r23,%r1 ++ mtsar %r1 ++ addib,= -1,%r24,L$0004 ++ vshd %r0,%r22,%r28 ; compute carry out limb ++ ldws,mb -4(0,%r25),%r29 ++ addib,= -1,%r24,L$0002 ++ vshd %r22,%r29,%r20 ++ ++ .label L$loop ++ ldws,mb -4(0,%r25),%r22 ++ stws,mb %r20,-4(0,%r26) ++ addib,= -1,%r24,L$0003 ++ vshd %r29,%r22,%r20 ++ ldws,mb -4(0,%r25),%r29 ++ stws,mb %r20,-4(0,%r26) ++ addib,<> -1,%r24,L$loop ++ vshd %r22,%r29,%r20 ++ ++ .label L$0002 ++ stws,mb %r20,-4(0,%r26) ++ vshd %r29,%r0,%r20 ++ bv 0(%r2) ++ stw %r20,-4(0,%r26) ++ .label L$0003 ++ stws,mb %r20,-4(0,%r26) ++ .label L$0004 ++ vshd %r22,%r0,%r20 ++ bv 0(%r2) ++ stw %r20,-4(0,%r26) ++ ++ .exit ++ .procend ++ ++ ++ +diff --git a/grub-core/lib/libgcrypt/mpi/hppa/mpih-rshift.S b/grub-core/lib/libgcrypt/mpi/hppa/mpih-rshift.S +new file mode 100644 +index 0000000..37a9d4e +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/hppa/mpih-rshift.S +@@ -0,0 +1,73 @@ ++/* hppa rshift ++ * ++ * Copyright (C) 1992, 1994, 1998, ++ * 2001, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ */ ++ ++ ++ ++ ++/******************* ++ * mpi_limb_t ++ * _gcry_mpih_rshift( mpi_ptr_t wp, (gr26) ++ * mpi_ptr_t up, (gr25) ++ * mpi_size_t usize, (gr24) ++ * unsigned cnt) (gr23) ++ */ ++ ++ .code ++ .export _gcry_mpih_rshift ++ .label _gcry_mpih_rshift ++ .proc ++ .callinfo frame=64,no_calls ++ .entry ++ ++ ldws,ma 4(0,%r25),%r22 ++ mtsar %r23 ++ addib,= -1,%r24,L$r004 ++ vshd %r22,%r0,%r28 ; compute carry out limb ++ ldws,ma 4(0,%r25),%r29 ++ addib,= -1,%r24,L$r002 ++ vshd %r29,%r22,%r20 ++ ++ .label L$roop ++ ldws,ma 4(0,%r25),%r22 ++ stws,ma %r20,4(0,%r26) ++ addib,= -1,%r24,L$r003 ++ vshd %r22,%r29,%r20 ++ ldws,ma 4(0,%r25),%r29 ++ stws,ma %r20,4(0,%r26) ++ addib,<> -1,%r24,L$roop ++ vshd %r29,%r22,%r20 ++ ++ .label L$r002 ++ stws,ma %r20,4(0,%r26) ++ vshd %r0,%r29,%r20 ++ bv 0(%r2) ++ stw %r20,0(0,%r26) ++ .label L$r003 ++ stws,ma %r20,4(0,%r26) ++ .label L$r004 ++ vshd %r0,%r22,%r20 ++ bv 0(%r2) ++ stw %r20,0(0,%r26) ++ ++ .exit ++ .procend ++ +diff --git a/grub-core/lib/libgcrypt/mpi/hppa/mpih-sub1.S b/grub-core/lib/libgcrypt/mpi/hppa/mpih-sub1.S +new file mode 100644 +index 0000000..8d197e4 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/hppa/mpih-sub1.S +@@ -0,0 +1,78 @@ ++/* hppa sub_n -- Sub two limb vectors of the same length > 0 and store ++ * sum in a third limb vector. ++ * ++ * Copyright (C) 1992, 1994, 1998, ++ * 2001, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ * ++ * Note: This code is heavily based on the GNU MP Library. ++ * Actually it's the same code with only minor changes in the ++ * way the data is stored; this is to support the abstraction ++ * of an optional secure memory allocation which may be used ++ * to avoid revealing of sensitive data due to paging etc. ++ */ ++ ++ ++#include "sysdep.h" ++#include "asm-syntax.h" ++ ++ ++/******************* ++ * mpi_limb_t ++ * _gcry_mpih_sub_n( mpi_ptr_t res_ptr, (gr26) ++ * mpi_ptr_t s1_ptr, (gr25) ++ * mpi_ptr_t s2_ptr, (gr24) ++ * mpi_size_t size) (gr23) ++ * ++ * One might want to unroll this as for other processors, but it turns ++ * out that the data cache contention after a store makes such ++ * unrolling useless. We can't come under 5 cycles/limb anyway. ++ */ ++ ++ ++ .code ++ .export _gcry_mpih_sub_n ++ .label _gcry_mpih_sub_n ++ .proc ++ .callinfo frame=0,no_calls ++ .entry ++ ++ ldws,ma 4(0,%r25),%r20 ++ ldws,ma 4(0,%r24),%r19 ++ ++ addib,= -1,%r23,L$end ; check for (SIZE == 1) ++ sub %r20,%r19,%r28 ; subtract first limbs ignoring cy ++ ++ .label L$loop ++ ldws,ma 4(0,%r25),%r20 ++ ldws,ma 4(0,%r24),%r19 ++ stws,ma %r28,4(0,%r26) ++ addib,<> -1,%r23,L$loop ++ subb %r20,%r19,%r28 ++ ++ .label L$end ++ stws %r28,0(0,%r26) ++ addc %r0,%r0,%r28 ++ bv 0(%r2) ++ subi 1,%r28,%r28 ++ ++ .exit ++ .procend ++ ++ ++ +diff --git a/grub-core/lib/libgcrypt/mpi/hppa/udiv-qrnnd.S b/grub-core/lib/libgcrypt/mpi/hppa/udiv-qrnnd.S +new file mode 100644 +index 0000000..59ebf7a +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/hppa/udiv-qrnnd.S +@@ -0,0 +1,297 @@ ++/* HP-PA __udiv_qrnnd division support, used from longlong.h. ++ * This version runs fast on pre-PA7000 CPUs. ++ * ++ * Copyright (C) 1993, 1994, 1998, 2001, ++ * 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ * ++ * Note: This code is heavily based on the GNU MP Library. ++ * Actually it's the same code with only minor changes in the ++ * way the data is stored; this is to support the abstraction ++ * of an optional secure memory allocation which may be used ++ * to avoid revealing of sensitive data due to paging etc. ++ */ ++ ++ ++ ++/* INPUT PARAMETERS ++ * rem_ptr gr26 ++ * n1 gr25 ++ * n0 gr24 ++ * d gr23 ++ * ++ * The code size is a bit excessive. We could merge the last two ds;addc ++ * sequences by simply moving the "bb,< Odd" instruction down. The only ++ * trouble is the FFFFFFFF code that would need some hacking. ++ */ ++ ++ .code ++ .export __udiv_qrnnd ++ .label __udiv_qrnnd ++ .proc ++ .callinfo frame=0,no_calls ++ .entry ++ ++ comb,< %r23,0,L$largedivisor ++ sub %r0,%r23,%r1 ; clear cy as side-effect ++ ds %r0,%r1,%r0 ++ addc %r24,%r24,%r24 ++ ds %r25,%r23,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r23,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r23,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r23,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r23,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r23,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r23,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r23,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r23,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r23,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r23,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r23,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r23,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r23,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r23,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r23,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r23,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r23,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r23,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r23,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r23,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r23,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r23,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r23,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r23,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r23,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r23,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r23,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r23,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r23,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r23,%r25 ++ addc %r24,%r24,%r28 ++ ds %r25,%r23,%r25 ++ comclr,>= %r25,%r0,%r0 ++ addl %r25,%r23,%r25 ++ stws %r25,0(0,%r26) ++ bv 0(%r2) ++ addc %r28,%r28,%r28 ++ ++ .label L$largedivisor ++ extru %r24,31,1,%r19 ; r19 = n0 & 1 ++ bb,< %r23,31,L$odd ++ extru %r23,30,31,%r22 ; r22 = d >> 1 ++ shd %r25,%r24,1,%r24 ; r24 = new n0 ++ extru %r25,30,31,%r25 ; r25 = new n1 ++ sub %r0,%r22,%r21 ++ ds %r0,%r21,%r0 ++ addc %r24,%r24,%r24 ++ ds %r25,%r22,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r22,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r22,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r22,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r22,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r22,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r22,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r22,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r22,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r22,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r22,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r22,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r22,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r22,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r22,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r22,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r22,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r22,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r22,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r22,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r22,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r22,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r22,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r22,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r22,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r22,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r22,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r22,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r22,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r22,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r22,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r22,%r25 ++ comclr,>= %r25,%r0,%r0 ++ addl %r25,%r22,%r25 ++ sh1addl %r25,%r19,%r25 ++ stws %r25,0(0,%r26) ++ bv 0(%r2) ++ addc %r24,%r24,%r28 ++ ++ .label L$odd ++ addib,sv,n 1,%r22,L$FF.. ; r22 = (d / 2 + 1) ++ shd %r25,%r24,1,%r24 ; r24 = new n0 ++ extru %r25,30,31,%r25 ; r25 = new n1 ++ sub %r0,%r22,%r21 ++ ds %r0,%r21,%r0 ++ addc %r24,%r24,%r24 ++ ds %r25,%r22,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r22,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r22,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r22,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r22,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r22,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r22,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r22,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r22,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r22,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r22,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r22,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r22,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r22,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r22,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r22,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r22,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r22,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r22,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r22,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r22,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r22,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r22,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r22,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r22,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r22,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r22,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r22,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r22,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r22,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r22,%r25 ++ addc %r24,%r24,%r24 ++ ds %r25,%r22,%r25 ++ addc %r24,%r24,%r28 ++ comclr,>= %r25,%r0,%r0 ++ addl %r25,%r22,%r25 ++ sh1addl %r25,%r19,%r25 ++; We have computed (n1,,n0) / (d + 1), q' = r28, r' = r25 ++ add,nuv %r28,%r25,%r25 ++ addl %r25,%r1,%r25 ++ addc %r0,%r28,%r28 ++ sub,<< %r25,%r23,%r0 ++ addl %r25,%r1,%r25 ++ stws %r25,0(0,%r26) ++ bv 0(%r2) ++ addc %r0,%r28,%r28 ++ ++; This is just a special case of the code above. ++; We come here when d == 0xFFFFFFFF ++ .label L$FF.. ++ add,uv %r25,%r24,%r24 ++ sub,<< %r24,%r23,%r0 ++ ldo 1(%r24),%r24 ++ stws %r24,0(0,%r26) ++ bv 0(%r2) ++ addc %r0,%r25,%r28 ++ ++ .exit ++ .procend +diff --git a/grub-core/lib/libgcrypt/mpi/i386/Manifest b/grub-core/lib/libgcrypt/mpi/i386/Manifest +new file mode 100644 +index 0000000..812bc8a +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/i386/Manifest +@@ -0,0 +1,28 @@ ++# Manifest - checksums ++# Copyright 2003 Free Software Foundation, Inc. ++# ++# This file is part of Libgcrypt. ++# ++# Libgcrypt is free software; you can redistribute it and/or modify ++# it under the terms of the GNU Lesser general Public License as ++# published by the Free Software Foundation; either version 2.1 of ++# the License, or (at your option) any later version. ++# ++# Libgcrypt 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 Lesser General Public License for more details. ++# ++# You should have received a copy of the GNU Lesser General Public ++# License along with this program; if not, write to the Free Software ++# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ ++mpih-add1.S ++mpih-mul1.S ++mpih-mul2.S ++mpih-mul3.S ++mpih-lshift.S ++mpih-rshift.S ++mpih-sub1.S ++syntax.h ++$names$ iQCVAwUAP+LmOTEAnp832S/7AQJZmgQA1+GIl7rXiEY00y5xD2kG5Lm2QD6c9aBME8hTl812OEcj0ul/QSpdv8E2NEKooifr4SiLVhEVfLNaLqAgN3cIsttn3rRX3/pMC5JwSKHDJPsUbpN9tzb5dr2YC9GG9m8xngAQrN11IQPnGfvFLJK+oDnEMIAeHDpOnX9NeQPDAQA==bnOy +diff --git a/grub-core/lib/libgcrypt/mpi/i386/distfiles b/grub-core/lib/libgcrypt/mpi/i386/distfiles +new file mode 100644 +index 0000000..22b9979 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/i386/distfiles +@@ -0,0 +1,10 @@ ++Manifest ++mpih-add1.S ++mpih-mul1.S ++mpih-mul2.S ++mpih-mul3.S ++mpih-lshift.S ++mpih-rshift.S ++mpih-sub1.S ++syntax.h ++ +diff --git a/grub-core/lib/libgcrypt/mpi/i386/mpih-add1.S b/grub-core/lib/libgcrypt/mpi/i386/mpih-add1.S +new file mode 100644 +index 0000000..652b232 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/i386/mpih-add1.S +@@ -0,0 +1,116 @@ ++/* i80386 add_n -- Add two limb vectors of the same length > 0 and store ++ * sum in a third limb vector. ++ * ++ * Copyright (C) 1992, 1994, 1995, 1998, ++ * 2001, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ * ++ * Note: This code is heavily based on the GNU MP Library. ++ * Actually it's the same code with only minor changes in the ++ * way the data is stored; this is to support the abstraction ++ * of an optional secure memory allocation which may be used ++ * to avoid revealing of sensitive data due to paging etc. ++ */ ++ ++ ++#include "sysdep.h" ++#include "asm-syntax.h" ++ ++ ++/******************* ++ * mpi_limb_t ++ * _gcry_mpih_add_n( mpi_ptr_t res_ptr, (sp + 4) ++ * mpi_ptr_t s1_ptr, (sp + 8) ++ * mpi_ptr_t s2_ptr, (sp + 12) ++ * mpi_size_t size) (sp + 16) ++ */ ++ ++.text ++ ALIGN (3) ++ .globl C_SYMBOL_NAME(_gcry_mpih_add_n) ++C_SYMBOL_NAME(_gcry_mpih_add_n:) ++ pushl %edi ++ pushl %esi ++ ++ movl 12(%esp),%edi /* res_ptr */ ++ movl 16(%esp),%esi /* s1_ptr */ ++ movl 20(%esp),%edx /* s2_ptr */ ++ movl 24(%esp),%ecx /* size */ ++ ++ movl %ecx,%eax ++ shrl $3,%ecx /* compute count for unrolled loop */ ++ negl %eax ++ andl $7,%eax /* get index where to start loop */ ++ jz Loop /* necessary special case for 0 */ ++ incl %ecx /* adjust loop count */ ++ shll $2,%eax /* adjustment for pointers... */ ++ subl %eax,%edi /* ... since they are offset ... */ ++ subl %eax,%esi /* ... by a constant when we ... */ ++ subl %eax,%edx /* ... enter the loop */ ++ shrl $2,%eax /* restore previous value */ ++#ifdef PIC ++/* Calculate start address in loop for PIC. Due to limitations in some ++ assemblers, Loop-L0-3 cannot be put into the leal */ ++ call L0 ++L0: leal (%eax,%eax,8),%eax ++ addl (%esp),%eax ++ addl $(Loop-L0-3),%eax ++ addl $4,%esp ++#else ++/* Calculate start address in loop for non-PIC. */ ++ leal (Loop - 3)(%eax,%eax,8),%eax ++#endif ++ jmp *%eax /* jump into loop */ ++ ALIGN (3) ++Loop: movl (%esi),%eax ++ adcl (%edx),%eax ++ movl %eax,(%edi) ++ movl 4(%esi),%eax ++ adcl 4(%edx),%eax ++ movl %eax,4(%edi) ++ movl 8(%esi),%eax ++ adcl 8(%edx),%eax ++ movl %eax,8(%edi) ++ movl 12(%esi),%eax ++ adcl 12(%edx),%eax ++ movl %eax,12(%edi) ++ movl 16(%esi),%eax ++ adcl 16(%edx),%eax ++ movl %eax,16(%edi) ++ movl 20(%esi),%eax ++ adcl 20(%edx),%eax ++ movl %eax,20(%edi) ++ movl 24(%esi),%eax ++ adcl 24(%edx),%eax ++ movl %eax,24(%edi) ++ movl 28(%esi),%eax ++ adcl 28(%edx),%eax ++ movl %eax,28(%edi) ++ leal 32(%edi),%edi ++ leal 32(%esi),%esi ++ leal 32(%edx),%edx ++ decl %ecx ++ jnz Loop ++ ++ sbbl %eax,%eax ++ negl %eax ++ ++ popl %esi ++ popl %edi ++ ret ++ +diff --git a/grub-core/lib/libgcrypt/mpi/i386/mpih-lshift.S b/grub-core/lib/libgcrypt/mpi/i386/mpih-lshift.S +new file mode 100644 +index 0000000..bf8ed9d +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/i386/mpih-lshift.S +@@ -0,0 +1,94 @@ ++/* i80386 lshift ++ * Copyright (C) 1992, 1994, 1998, ++ * 2001, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ * ++ * Note: This code is heavily based on the GNU MP Library. ++ * Actually it's the same code with only minor changes in the ++ * way the data is stored; this is to support the abstraction ++ * of an optional secure memory allocation which may be used ++ * to avoid revealing of sensitive data due to paging etc. ++ */ ++ ++ ++#include "sysdep.h" ++#include "asm-syntax.h" ++ ++ ++/******************* ++ * mpi_limb_t ++ * _gcry_mpih_lshift( mpi_ptr_t wp, (sp + 4) ++ * mpi_ptr_t up, (sp + 8) ++ * mpi_size_t usize, (sp + 12) ++ * unsigned cnt) (sp + 16) ++ */ ++ ++.text ++ ALIGN (3) ++ .globl C_SYMBOL_NAME(_gcry_mpih_lshift) ++C_SYMBOL_NAME(_gcry_mpih_lshift:) ++ pushl %edi ++ pushl %esi ++ pushl %ebx ++ ++ movl 16(%esp),%edi /* res_ptr */ ++ movl 20(%esp),%esi /* s_ptr */ ++ movl 24(%esp),%edx /* size */ ++ movl 28(%esp),%ecx /* cnt */ ++ ++ subl $4,%esi /* adjust s_ptr */ ++ ++ movl (%esi,%edx,4),%ebx /* read most significant limb */ ++ xorl %eax,%eax ++ shldl %cl,%ebx,%eax /* compute carry limb */ ++ decl %edx ++ jz Lend ++ pushl %eax /* push carry limb onto stack */ ++ testb $1,%dl ++ jnz L1 /* enter loop in the middle */ ++ movl %ebx,%eax ++ ++ ALIGN (3) ++Loop: movl (%esi,%edx,4),%ebx /* load next lower limb */ ++ shldl %cl,%ebx,%eax /* compute result limb */ ++ movl %eax,(%edi,%edx,4) /* store it */ ++ decl %edx ++L1: movl (%esi,%edx,4),%eax ++ shldl %cl,%eax,%ebx ++ movl %ebx,(%edi,%edx,4) ++ decl %edx ++ jnz Loop ++ ++ shll %cl,%eax /* compute least significant limb */ ++ movl %eax,(%edi) /* store it */ ++ ++ popl %eax /* pop carry limb */ ++ ++ popl %ebx ++ popl %esi ++ popl %edi ++ ret ++ ++Lend: shll %cl,%ebx /* compute least significant limb */ ++ movl %ebx,(%edi) /* store it */ ++ ++ popl %ebx ++ popl %esi ++ popl %edi ++ ret ++ +diff --git a/grub-core/lib/libgcrypt/mpi/i386/mpih-mul1.S b/grub-core/lib/libgcrypt/mpi/i386/mpih-mul1.S +new file mode 100644 +index 0000000..c9760ef +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/i386/mpih-mul1.S +@@ -0,0 +1,84 @@ ++/* i80386 mul_1 -- Multiply a limb vector with a limb and store ++ * the result in a second limb vector. ++ * Copyright (C) 1992, 1994, 1998, ++ * 2001, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ * ++ * Note: This code is heavily based on the GNU MP Library. ++ * Actually it's the same code with only minor changes in the ++ * way the data is stored; this is to support the abstraction ++ * of an optional secure memory allocation which may be used ++ * to avoid revealing of sensitive data due to paging etc. ++ */ ++ ++ ++#include "sysdep.h" ++#include "asm-syntax.h" ++ ++ ++/******************* ++ * mpi_limb_t ++ * _gcry_mpih_mul_1( mpi_ptr_t res_ptr, (sp + 4) ++ * mpi_ptr_t s1_ptr, (sp + 8) ++ * mpi_size_t s1_size, (sp + 12) ++ * mpi_limb_t s2_limb) (sp + 16) ++ */ ++ ++#define res_ptr edi ++#define s1_ptr esi ++#define size ecx ++#define s2_limb ebp ++ ++ TEXT ++ ALIGN (3) ++ GLOBL C_SYMBOL_NAME(_gcry_mpih_mul_1) ++C_SYMBOL_NAME(_gcry_mpih_mul_1:) ++ ++ INSN1(push,l ,R(edi)) ++ INSN1(push,l ,R(esi)) ++ INSN1(push,l ,R(ebx)) ++ INSN1(push,l ,R(ebp)) ++ ++ INSN2(mov,l ,R(res_ptr),MEM_DISP(esp,20)) ++ INSN2(mov,l ,R(s1_ptr),MEM_DISP(esp,24)) ++ INSN2(mov,l ,R(size),MEM_DISP(esp,28)) ++ INSN2(mov,l ,R(s2_limb),MEM_DISP(esp,32)) ++ ++ INSN2(lea,l ,R(res_ptr),MEM_INDEX(res_ptr,size,4)) ++ INSN2(lea,l ,R(s1_ptr),MEM_INDEX(s1_ptr,size,4)) ++ INSN1(neg,l ,R(size)) ++ INSN2(xor,l ,R(ebx),R(ebx)) ++ ALIGN (3) ++Loop: ++ INSN2(mov,l ,R(eax),MEM_INDEX(s1_ptr,size,4)) ++ INSN1(mul,l ,R(s2_limb)) ++ INSN2(add,l ,R(eax),R(ebx)) ++ INSN2(mov,l ,MEM_INDEX(res_ptr,size,4),R(eax)) ++ INSN2(adc,l ,R(edx),$0) ++ INSN2(mov,l ,R(ebx),R(edx)) ++ ++ INSN1(inc,l ,R(size)) ++ INSN1(jnz, ,Loop) ++ INSN2(mov,l ,R(eax),R(ebx)) ++ ++ INSN1(pop,l ,R(ebp)) ++ INSN1(pop,l ,R(ebx)) ++ INSN1(pop,l ,R(esi)) ++ INSN1(pop,l ,R(edi)) ++ ret ++ +diff --git a/grub-core/lib/libgcrypt/mpi/i386/mpih-mul2.S b/grub-core/lib/libgcrypt/mpi/i386/mpih-mul2.S +new file mode 100644 +index 0000000..9794e11 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/i386/mpih-mul2.S +@@ -0,0 +1,86 @@ ++/* i80386 addmul_1 -- Multiply a limb vector with a limb and add ++ * the result to a second limb vector. ++ * ++ * Copyright (C) 1992, 1994, 1998, ++ * 2001, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ * ++ * Note: This code is heavily based on the GNU MP Library. ++ * Actually it's the same code with only minor changes in the ++ * way the data is stored; this is to support the abstraction ++ * of an optional secure memory allocation which may be used ++ * to avoid revealing of sensitive data due to paging etc. ++ */ ++ ++ ++#include "sysdep.h" ++#include "asm-syntax.h" ++ ++ ++/******************* ++ * mpi_limb_t ++ * _gcry_mpih_addmul_1( mpi_ptr_t res_ptr, (sp + 4) ++ * mpi_ptr_t s1_ptr, (sp + 8) ++ * mpi_size_t s1_size, (sp + 12) ++ * mpi_limb_t s2_limb) (sp + 16) ++ */ ++ ++#define res_ptr edi ++#define s1_ptr esi ++#define size ecx ++#define s2_limb ebp ++ ++ TEXT ++ ALIGN (3) ++ GLOBL C_SYMBOL_NAME(_gcry_mpih_addmul_1) ++C_SYMBOL_NAME(_gcry_mpih_addmul_1:) ++ ++ INSN1(push,l ,R(edi)) ++ INSN1(push,l ,R(esi)) ++ INSN1(push,l ,R(ebx)) ++ INSN1(push,l ,R(ebp)) ++ ++ INSN2(mov,l ,R(res_ptr),MEM_DISP(esp,20)) ++ INSN2(mov,l ,R(s1_ptr),MEM_DISP(esp,24)) ++ INSN2(mov,l ,R(size),MEM_DISP(esp,28)) ++ INSN2(mov,l ,R(s2_limb),MEM_DISP(esp,32)) ++ ++ INSN2(lea,l ,R(res_ptr),MEM_INDEX(res_ptr,size,4)) ++ INSN2(lea,l ,R(s1_ptr),MEM_INDEX(s1_ptr,size,4)) ++ INSN1(neg,l ,R(size)) ++ INSN2(xor,l ,R(ebx),R(ebx)) ++ ALIGN (3) ++Loop: ++ INSN2(mov,l ,R(eax),MEM_INDEX(s1_ptr,size,4)) ++ INSN1(mul,l ,R(s2_limb)) ++ INSN2(add,l ,R(eax),R(ebx)) ++ INSN2(adc,l ,R(edx),$0) ++ INSN2(add,l ,MEM_INDEX(res_ptr,size,4),R(eax)) ++ INSN2(adc,l ,R(edx),$0) ++ INSN2(mov,l ,R(ebx),R(edx)) ++ ++ INSN1(inc,l ,R(size)) ++ INSN1(jnz, ,Loop) ++ INSN2(mov,l ,R(eax),R(ebx)) ++ ++ INSN1(pop,l ,R(ebp)) ++ INSN1(pop,l ,R(ebx)) ++ INSN1(pop,l ,R(esi)) ++ INSN1(pop,l ,R(edi)) ++ ret ++ +diff --git a/grub-core/lib/libgcrypt/mpi/i386/mpih-mul3.S b/grub-core/lib/libgcrypt/mpi/i386/mpih-mul3.S +new file mode 100644 +index 0000000..6df2017 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/i386/mpih-mul3.S +@@ -0,0 +1,86 @@ ++/* i80386 submul_1 -- Multiply a limb vector with a limb and add ++ * the result to a second limb vector. ++ * ++ * Copyright (C) 1992, 1994, 1998, ++ * 2001, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ * ++ * Note: This code is heavily based on the GNU MP Library. ++ * Actually it's the same code with only minor changes in the ++ * way the data is stored; this is to support the abstraction ++ * of an optional secure memory allocation which may be used ++ * to avoid revealing of sensitive data due to paging etc. ++ */ ++ ++ ++#include "sysdep.h" ++#include "asm-syntax.h" ++ ++ ++/******************* ++ * mpi_limb_t ++ * _gcry_mpih_submul_1( mpi_ptr_t res_ptr, (sp + 4) ++ * mpi_ptr_t s1_ptr, (sp + 8) ++ * mpi_size_t s1_size, (sp + 12) ++ * mpi_limb_t s2_limb) (sp + 16) ++ */ ++ ++#define res_ptr edi ++#define s1_ptr esi ++#define size ecx ++#define s2_limb ebp ++ ++ TEXT ++ ALIGN (3) ++ GLOBL C_SYMBOL_NAME(_gcry_mpih_submul_1) ++C_SYMBOL_NAME(_gcry_mpih_submul_1:) ++ ++ INSN1(push,l ,R(edi)) ++ INSN1(push,l ,R(esi)) ++ INSN1(push,l ,R(ebx)) ++ INSN1(push,l ,R(ebp)) ++ ++ INSN2(mov,l ,R(res_ptr),MEM_DISP(esp,20)) ++ INSN2(mov,l ,R(s1_ptr),MEM_DISP(esp,24)) ++ INSN2(mov,l ,R(size),MEM_DISP(esp,28)) ++ INSN2(mov,l ,R(s2_limb),MEM_DISP(esp,32)) ++ ++ INSN2(lea,l ,R(res_ptr),MEM_INDEX(res_ptr,size,4)) ++ INSN2(lea,l ,R(s1_ptr),MEM_INDEX(s1_ptr,size,4)) ++ INSN1(neg,l ,R(size)) ++ INSN2(xor,l ,R(ebx),R(ebx)) ++ ALIGN (3) ++Loop: ++ INSN2(mov,l ,R(eax),MEM_INDEX(s1_ptr,size,4)) ++ INSN1(mul,l ,R(s2_limb)) ++ INSN2(add,l ,R(eax),R(ebx)) ++ INSN2(adc,l ,R(edx),$0) ++ INSN2(sub,l ,MEM_INDEX(res_ptr,size,4),R(eax)) ++ INSN2(adc,l ,R(edx),$0) ++ INSN2(mov,l ,R(ebx),R(edx)) ++ ++ INSN1(inc,l ,R(size)) ++ INSN1(jnz, ,Loop) ++ INSN2(mov,l ,R(eax),R(ebx)) ++ ++ INSN1(pop,l ,R(ebp)) ++ INSN1(pop,l ,R(ebx)) ++ INSN1(pop,l ,R(esi)) ++ INSN1(pop,l ,R(edi)) ++ ret ++ +diff --git a/grub-core/lib/libgcrypt/mpi/i386/mpih-rshift.S b/grub-core/lib/libgcrypt/mpi/i386/mpih-rshift.S +new file mode 100644 +index 0000000..2920e55 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/i386/mpih-rshift.S +@@ -0,0 +1,97 @@ ++/* i80386 rshift ++ * ++ * Copyright (C) 1992, 1994, 1998, ++ * 2001, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ * ++ * Note: This code is heavily based on the GNU MP Library. ++ * Actually it's the same code with only minor changes in the ++ * way the data is stored; this is to support the abstraction ++ * of an optional secure memory allocation which may be used ++ * to avoid revealing of sensitive data due to paging etc. ++ */ ++ ++ ++#include "sysdep.h" ++#include "asm-syntax.h" ++ ++ ++/******************* ++ * mpi_limb_t ++ * _gcry_mpih_rshift( mpi_ptr_t wp, (sp + 4) ++ * mpi_ptr_t up, (sp + 8) ++ * mpi_size_t usize, (sp + 12) ++ * unsigned cnt) (sp + 16) ++ */ ++ ++.text ++ ALIGN (3) ++ .globl C_SYMBOL_NAME(_gcry_mpih_rshift) ++C_SYMBOL_NAME(_gcry_mpih_rshift:) ++ pushl %edi ++ pushl %esi ++ pushl %ebx ++ ++ movl 16(%esp),%edi /* wp */ ++ movl 20(%esp),%esi /* up */ ++ movl 24(%esp),%edx /* usize */ ++ movl 28(%esp),%ecx /* cnt */ ++ ++ leal -4(%edi,%edx,4),%edi ++ leal (%esi,%edx,4),%esi ++ negl %edx ++ ++ movl (%esi,%edx,4),%ebx /* read least significant limb */ ++ xorl %eax,%eax ++ shrdl %cl,%ebx,%eax /* compute carry limb */ ++ incl %edx ++ jz Lend2 ++ pushl %eax /* push carry limb onto stack */ ++ testb $1,%dl ++ jnz L2 /* enter loop in the middle */ ++ movl %ebx,%eax ++ ++ ALIGN (3) ++Loop2: movl (%esi,%edx,4),%ebx /* load next higher limb */ ++ shrdl %cl,%ebx,%eax /* compute result limb */ ++ movl %eax,(%edi,%edx,4) /* store it */ ++ incl %edx ++L2: movl (%esi,%edx,4),%eax ++ shrdl %cl,%eax,%ebx ++ movl %ebx,(%edi,%edx,4) ++ incl %edx ++ jnz Loop2 ++ ++ shrl %cl,%eax /* compute most significant limb */ ++ movl %eax,(%edi) /* store it */ ++ ++ popl %eax /* pop carry limb */ ++ ++ popl %ebx ++ popl %esi ++ popl %edi ++ ret ++ ++Lend2: shrl %cl,%ebx /* compute most significant limb */ ++ movl %ebx,(%edi) /* store it */ ++ ++ popl %ebx ++ popl %esi ++ popl %edi ++ ret ++ +diff --git a/grub-core/lib/libgcrypt/mpi/i386/mpih-sub1.S b/grub-core/lib/libgcrypt/mpi/i386/mpih-sub1.S +new file mode 100644 +index 0000000..f447f7a +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/i386/mpih-sub1.S +@@ -0,0 +1,117 @@ ++/* i80386 sub_n -- Sub two limb vectors of the same length > 0 and store ++ * sum in a third limb vector. ++ * ++ * Copyright (C) 1992, 1994, 1995, 1998, ++ * 2001, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ * ++ * Note: This code is heavily based on the GNU MP Library. ++ * Actually it's the same code with only minor changes in the ++ * way the data is stored; this is to support the abstraction ++ * of an optional secure memory allocation which may be used ++ * to avoid revealing of sensitive data due to paging etc. ++ */ ++ ++ ++#include "sysdep.h" ++#include "asm-syntax.h" ++ ++ ++/******************* ++ * mpi_limb_t ++ * _gcry_mpih_sub_n( mpi_ptr_t res_ptr, (sp + 4) ++ * mpi_ptr_t s1_ptr, (sp + 8) ++ * mpi_ptr_t s2_ptr, (sp + 12) ++ * mpi_size_t size) (sp + 16) ++ */ ++ ++ ++.text ++ ALIGN (3) ++ .globl C_SYMBOL_NAME(_gcry_mpih_sub_n) ++C_SYMBOL_NAME(_gcry_mpih_sub_n:) ++ pushl %edi ++ pushl %esi ++ ++ movl 12(%esp),%edi /* res_ptr */ ++ movl 16(%esp),%esi /* s1_ptr */ ++ movl 20(%esp),%edx /* s2_ptr */ ++ movl 24(%esp),%ecx /* size */ ++ ++ movl %ecx,%eax ++ shrl $3,%ecx /* compute count for unrolled loop */ ++ negl %eax ++ andl $7,%eax /* get index where to start loop */ ++ jz Loop /* necessary special case for 0 */ ++ incl %ecx /* adjust loop count */ ++ shll $2,%eax /* adjustment for pointers... */ ++ subl %eax,%edi /* ... since they are offset ... */ ++ subl %eax,%esi /* ... by a constant when we ... */ ++ subl %eax,%edx /* ... enter the loop */ ++ shrl $2,%eax /* restore previous value */ ++#ifdef PIC ++/* Calculate start address in loop for PIC. Due to limitations in some ++ assemblers, Loop-L0-3 cannot be put into the leal */ ++ call L0 ++L0: leal (%eax,%eax,8),%eax ++ addl (%esp),%eax ++ addl $(Loop-L0-3),%eax ++ addl $4,%esp ++#else ++/* Calculate start address in loop for non-PIC. */ ++ leal (Loop - 3)(%eax,%eax,8),%eax ++#endif ++ jmp *%eax /* jump into loop */ ++ ALIGN (3) ++Loop: movl (%esi),%eax ++ sbbl (%edx),%eax ++ movl %eax,(%edi) ++ movl 4(%esi),%eax ++ sbbl 4(%edx),%eax ++ movl %eax,4(%edi) ++ movl 8(%esi),%eax ++ sbbl 8(%edx),%eax ++ movl %eax,8(%edi) ++ movl 12(%esi),%eax ++ sbbl 12(%edx),%eax ++ movl %eax,12(%edi) ++ movl 16(%esi),%eax ++ sbbl 16(%edx),%eax ++ movl %eax,16(%edi) ++ movl 20(%esi),%eax ++ sbbl 20(%edx),%eax ++ movl %eax,20(%edi) ++ movl 24(%esi),%eax ++ sbbl 24(%edx),%eax ++ movl %eax,24(%edi) ++ movl 28(%esi),%eax ++ sbbl 28(%edx),%eax ++ movl %eax,28(%edi) ++ leal 32(%edi),%edi ++ leal 32(%esi),%esi ++ leal 32(%edx),%edx ++ decl %ecx ++ jnz Loop ++ ++ sbbl %eax,%eax ++ negl %eax ++ ++ popl %esi ++ popl %edi ++ ret ++ +diff --git a/grub-core/lib/libgcrypt/mpi/i386/syntax.h b/grub-core/lib/libgcrypt/mpi/i386/syntax.h +new file mode 100644 +index 0000000..39ede98 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/i386/syntax.h +@@ -0,0 +1,68 @@ ++/* syntax.h -- Definitions for x86 syntax variations. ++ * ++ * Copyright (C) 1992, 1994, 1995, 1998, ++ * 2001, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ * ++ * Note: This code is heavily based on the GNU MP Library. ++ * Actually it's the same code with only minor changes in the ++ * way the data is stored; this is to support the abstraction ++ * of an optional secure memory allocation which may be used ++ * to avoid revealing of sensitive data due to paging etc. ++ */ ++ ++#undef ALIGN ++ ++#if defined (BSD_SYNTAX) || defined (ELF_SYNTAX) ++#define R(r) %r ++#define MEM(base)(base) ++#define MEM_DISP(base,displacement)displacement(R(base)) ++#define MEM_INDEX(base,index,size)(R(base),R(index),size) ++#ifdef __STDC__ ++#define INSN1(mnemonic,size_suffix,dst)mnemonic##size_suffix dst ++#define INSN2(mnemonic,size_suffix,dst,src)mnemonic##size_suffix src,dst ++#else ++#define INSN1(mnemonic,size_suffix,dst)mnemonic/**/size_suffix dst ++#define INSN2(mnemonic,size_suffix,dst,src)mnemonic/**/size_suffix src,dst ++#endif ++#define TEXT .text ++#if defined (BSD_SYNTAX) ++#define ALIGN(log) .align log ++#endif ++#if defined (ELF_SYNTAX) ++#define ALIGN(log) .align 1<<(log) ++#endif ++#define GLOBL .globl ++#endif ++ ++#ifdef INTEL_SYNTAX ++#define R(r) r ++#define MEM(base)[base] ++#define MEM_DISP(base,displacement)[base+(displacement)] ++#define MEM_INDEX(base,index,size)[base+index*size] ++#define INSN1(mnemonic,size_suffix,dst)mnemonic dst ++#define INSN2(mnemonic,size_suffix,dst,src)mnemonic dst,src ++#define TEXT .text ++#define ALIGN(log) .align log ++#define GLOBL .globl ++#endif ++ ++#ifdef X86_BROKEN_ALIGN ++#undef ALIGN ++#define ALIGN(log) .align log,0x90 ++#endif +diff --git a/grub-core/lib/libgcrypt/mpi/i586/Manifest b/grub-core/lib/libgcrypt/mpi/i586/Manifest +new file mode 100644 +index 0000000..6d1d7f8 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/i586/Manifest +@@ -0,0 +1,27 @@ ++# Manifest - checksums ++# Copyright 2003 Free Software Foundation, Inc. ++# ++# This file is part of Libgcrypt. ++# ++# Libgcrypt is free software; you can redistribute it and/or modify ++# it under the terms of the GNU Lesser general Public License as ++# published by the Free Software Foundation; either version 2.1 of ++# the License, or (at your option) any later version. ++# ++# Libgcrypt 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 Lesser General Public License for more details. ++# ++# You should have received a copy of the GNU Lesser General Public ++# License along with this program; if not, write to the Free Software ++# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ ++mpih-add1.S ++mpih-mul1.S ++mpih-mul2.S ++mpih-mul3.S ++mpih-lshift.S ++mpih-rshift.S ++mpih-sub1.S ++$names$ iQCVAwUAP+LmQDEAnp832S/7AQKCmgQAhG+E7X0KB4qdVf3sMb6Qr+Iv5Jlehzoub/5vxTRgePKzRuOHidCnTzSSoyzA++UcHrOjHQQDMsXnO6PqpS1d/TKkxjnGN7rE8mvMYlFAT8RsawTozSfh14mCzI0HTDbaKL9Z8pcMJtadB3XqAuqWJNO8kyECJFwurt3DRWXSWS8==Rug5 +diff --git a/grub-core/lib/libgcrypt/mpi/i586/README b/grub-core/lib/libgcrypt/mpi/i586/README +new file mode 100644 +index 0000000..d73b082 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/i586/README +@@ -0,0 +1,26 @@ ++This directory contains mpn functions optimized for Intel Pentium ++processors. ++ ++RELEVANT OPTIMIZATION ISSUES ++ ++1. Pentium doesn't allocate cache lines on writes, unlike most other modern ++processors. Since the functions in the mpn class do array writes, we have to ++handle allocating the destination cache lines by reading a word from it in the ++loops, to achieve the best performance. ++ ++2. Pairing of memory operations requires that the two issued operations refer ++to different cache banks. The simplest way to insure this is to read/write ++two words from the same object. If we make operations on different objects, ++they might or might not be to the same cache bank. ++ ++STATUS ++ ++1. mpn_lshift and mpn_rshift run at about 6 cycles/limb, but the Pentium ++documentation indicates that they should take only 43/8 = 5.375 cycles/limb, ++or 5 cycles/limb asymptotically. ++ ++2. mpn_add_n and mpn_sub_n run at asymptotically 2 cycles/limb. Due to loop ++overhead and other delays (cache refill?), they run at or near 2.5 cycles/limb. ++ ++3. mpn_mul_1, mpn_addmul_1, mpn_submul_1 all run 1 cycle faster than they ++should... +diff --git a/grub-core/lib/libgcrypt/mpi/i586/distfiles b/grub-core/lib/libgcrypt/mpi/i586/distfiles +new file mode 100644 +index 0000000..546f777 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/i586/distfiles +@@ -0,0 +1,10 @@ ++Manifest ++mpih-add1.S ++mpih-mul1.S ++mpih-mul2.S ++mpih-mul3.S ++mpih-lshift.S ++mpih-rshift.S ++mpih-sub1.S ++README ++ +diff --git a/grub-core/lib/libgcrypt/mpi/i586/mpih-add1.S b/grub-core/lib/libgcrypt/mpi/i586/mpih-add1.S +new file mode 100644 +index 0000000..7436d59 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/i586/mpih-add1.S +@@ -0,0 +1,135 @@ ++/* i80586 add_n -- Add two limb vectors of the same length > 0 and store ++ * sum in a third limb vector. ++ * ++ * Copyright (C) 1992, 1994, 1995, 1996, 1998, ++ * 2001, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ */ ++ ++ ++#include "sysdep.h" ++#include "asm-syntax.h" ++ ++ ++/******************* ++ * mpi_limb_t ++ * _gcry_mpih_add_n( mpi_ptr_t res_ptr, (sp + 4) ++ * mpi_ptr_t s1_ptr, (sp + 8) ++ * mpi_ptr_t s2_ptr, (sp + 12) ++ * mpi_size_t size) (sp + 16) ++ */ ++ ++.text ++ ALIGN (3) ++ .globl C_SYMBOL_NAME(_gcry_mpih_add_n) ++C_SYMBOL_NAME(_gcry_mpih_add_n:) ++ pushl %edi ++ pushl %esi ++ pushl %ebx ++ pushl %ebp ++ ++ movl 20(%esp),%edi /* res_ptr */ ++ movl 24(%esp),%esi /* s1_ptr */ ++ movl 28(%esp),%ebp /* s2_ptr */ ++ movl 32(%esp),%ecx /* size */ ++ ++ movl (%ebp),%ebx ++ ++ decl %ecx ++ movl %ecx,%edx ++ shrl $3,%ecx ++ andl $7,%edx ++ testl %ecx,%ecx /* zero carry flag */ ++ jz Lend ++ pushl %edx ++ ++ ALIGN (3) ++Loop: movl 28(%edi),%eax /* fetch destination cache line */ ++ leal 32(%edi),%edi ++ ++L1: movl (%esi),%eax ++ movl 4(%esi),%edx ++ adcl %ebx,%eax ++ movl 4(%ebp),%ebx ++ adcl %ebx,%edx ++ movl 8(%ebp),%ebx ++ movl %eax,-32(%edi) ++ movl %edx,-28(%edi) ++ ++L2: movl 8(%esi),%eax ++ movl 12(%esi),%edx ++ adcl %ebx,%eax ++ movl 12(%ebp),%ebx ++ adcl %ebx,%edx ++ movl 16(%ebp),%ebx ++ movl %eax,-24(%edi) ++ movl %edx,-20(%edi) ++ ++L3: movl 16(%esi),%eax ++ movl 20(%esi),%edx ++ adcl %ebx,%eax ++ movl 20(%ebp),%ebx ++ adcl %ebx,%edx ++ movl 24(%ebp),%ebx ++ movl %eax,-16(%edi) ++ movl %edx,-12(%edi) ++ ++L4: movl 24(%esi),%eax ++ movl 28(%esi),%edx ++ adcl %ebx,%eax ++ movl 28(%ebp),%ebx ++ adcl %ebx,%edx ++ movl 32(%ebp),%ebx ++ movl %eax,-8(%edi) ++ movl %edx,-4(%edi) ++ ++ leal 32(%esi),%esi ++ leal 32(%ebp),%ebp ++ decl %ecx ++ jnz Loop ++ ++ popl %edx ++Lend: ++ decl %edx /* test %edx w/o clobbering carry */ ++ js Lend2 ++ incl %edx ++Loop2: ++ leal 4(%edi),%edi ++ movl (%esi),%eax ++ adcl %ebx,%eax ++ movl 4(%ebp),%ebx ++ movl %eax,-4(%edi) ++ leal 4(%esi),%esi ++ leal 4(%ebp),%ebp ++ decl %edx ++ jnz Loop2 ++Lend2: ++ movl (%esi),%eax ++ adcl %ebx,%eax ++ movl %eax,(%edi) ++ ++ sbbl %eax,%eax ++ negl %eax ++ ++ popl %ebp ++ popl %ebx ++ popl %esi ++ popl %edi ++ ret ++ ++ +diff --git a/grub-core/lib/libgcrypt/mpi/i586/mpih-lshift.S b/grub-core/lib/libgcrypt/mpi/i586/mpih-lshift.S +new file mode 100644 +index 0000000..9d25fe9 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/i586/mpih-lshift.S +@@ -0,0 +1,229 @@ ++/* i80586 lshift ++ * ++ * Copyright (C) 1992, 1994, 1998, ++ * 2001, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ * ++ * Note: This code is heavily based on the GNU MP Library. ++ * Actually it's the same code with only minor changes in the ++ * way the data is stored; this is to support the abstraction ++ * of an optional secure memory allocation which may be used ++ * to avoid revealing of sensitive data due to paging etc. ++ */ ++ ++ ++#include "sysdep.h" ++#include "asm-syntax.h" ++ ++ ++/******************* ++ * mpi_limb_t ++ * _gcry_mpih_lshift( mpi_ptr_t wp, (sp + 4) ++ * mpi_ptr_t up, (sp + 8) ++ * mpi_size_t usize, (sp + 12) ++ * unsigned cnt) (sp + 16) ++ */ ++ ++.text ++ ALIGN (3) ++ .globl C_SYMBOL_NAME(_gcry_mpih_lshift) ++C_SYMBOL_NAME(_gcry_mpih_lshift:) ++ ++ pushl %edi ++ pushl %esi ++ pushl %ebx ++ pushl %ebp ++ ++ movl 20(%esp),%edi /* res_ptr */ ++ movl 24(%esp),%esi /* s_ptr */ ++ movl 28(%esp),%ebp /* size */ ++ movl 32(%esp),%ecx /* cnt */ ++ ++/* We can use faster code for shift-by-1 under certain conditions. */ ++ cmp $1,%ecx ++ jne Lnormal ++ leal 4(%esi),%eax ++ cmpl %edi,%eax ++ jnc Lspecial /* jump if s_ptr + 1 >= res_ptr */ ++ leal (%esi,%ebp,4),%eax ++ cmpl %eax,%edi ++ jnc Lspecial /* jump if res_ptr >= s_ptr + size */ ++ ++Lnormal: ++ leal -4(%edi,%ebp,4),%edi ++ leal -4(%esi,%ebp,4),%esi ++ ++ movl (%esi),%edx ++ subl $4,%esi ++ xorl %eax,%eax ++ shldl %cl,%edx,%eax /* compute carry limb */ ++ pushl %eax /* push carry limb onto stack */ ++ ++ decl %ebp ++ pushl %ebp ++ shrl $3,%ebp ++ jz Lend ++ ++ movl (%edi),%eax /* fetch destination cache line */ ++ ++ ALIGN (2) ++Loop: movl -28(%edi),%eax /* fetch destination cache line */ ++ movl %edx,%ebx ++ ++ movl (%esi),%eax ++ movl -4(%esi),%edx ++ shldl %cl,%eax,%ebx ++ shldl %cl,%edx,%eax ++ movl %ebx,(%edi) ++ movl %eax,-4(%edi) ++ ++ movl -8(%esi),%ebx ++ movl -12(%esi),%eax ++ shldl %cl,%ebx,%edx ++ shldl %cl,%eax,%ebx ++ movl %edx,-8(%edi) ++ movl %ebx,-12(%edi) ++ ++ movl -16(%esi),%edx ++ movl -20(%esi),%ebx ++ shldl %cl,%edx,%eax ++ shldl %cl,%ebx,%edx ++ movl %eax,-16(%edi) ++ movl %edx,-20(%edi) ++ ++ movl -24(%esi),%eax ++ movl -28(%esi),%edx ++ shldl %cl,%eax,%ebx ++ shldl %cl,%edx,%eax ++ movl %ebx,-24(%edi) ++ movl %eax,-28(%edi) ++ ++ subl $32,%esi ++ subl $32,%edi ++ decl %ebp ++ jnz Loop ++ ++Lend: popl %ebp ++ andl $7,%ebp ++ jz Lend2 ++Loop2: movl (%esi),%eax ++ shldl %cl,%eax,%edx ++ movl %edx,(%edi) ++ movl %eax,%edx ++ subl $4,%esi ++ subl $4,%edi ++ decl %ebp ++ jnz Loop2 ++ ++Lend2: shll %cl,%edx /* compute least significant limb */ ++ movl %edx,(%edi) /* store it */ ++ ++ popl %eax /* pop carry limb */ ++ ++ popl %ebp ++ popl %ebx ++ popl %esi ++ popl %edi ++ ret ++ ++/* We loop from least significant end of the arrays, which is only ++ permissable if the source and destination don't overlap, since the ++ function is documented to work for overlapping source and destination. ++*/ ++ ++Lspecial: ++ movl (%esi),%edx ++ addl $4,%esi ++ ++ decl %ebp ++ pushl %ebp ++ shrl $3,%ebp ++ ++ addl %edx,%edx ++ incl %ebp ++ decl %ebp ++ jz LLend ++ ++ movl (%edi),%eax /* fetch destination cache line */ ++ ++ ALIGN (2) ++LLoop: movl 28(%edi),%eax /* fetch destination cache line */ ++ movl %edx,%ebx ++ ++ movl (%esi),%eax ++ movl 4(%esi),%edx ++ adcl %eax,%eax ++ movl %ebx,(%edi) ++ adcl %edx,%edx ++ movl %eax,4(%edi) ++ ++ movl 8(%esi),%ebx ++ movl 12(%esi),%eax ++ adcl %ebx,%ebx ++ movl %edx,8(%edi) ++ adcl %eax,%eax ++ movl %ebx,12(%edi) ++ ++ movl 16(%esi),%edx ++ movl 20(%esi),%ebx ++ adcl %edx,%edx ++ movl %eax,16(%edi) ++ adcl %ebx,%ebx ++ movl %edx,20(%edi) ++ ++ movl 24(%esi),%eax ++ movl 28(%esi),%edx ++ adcl %eax,%eax ++ movl %ebx,24(%edi) ++ adcl %edx,%edx ++ movl %eax,28(%edi) ++ ++ leal 32(%esi),%esi /* use leal not to clobber carry */ ++ leal 32(%edi),%edi ++ decl %ebp ++ jnz LLoop ++ ++LLend: popl %ebp ++ sbbl %eax,%eax /* save carry in %eax */ ++ andl $7,%ebp ++ jz LLend2 ++ addl %eax,%eax /* restore carry from eax */ ++LLoop2: movl %edx,%ebx ++ movl (%esi),%edx ++ adcl %edx,%edx ++ movl %ebx,(%edi) ++ ++ leal 4(%esi),%esi /* use leal not to clobber carry */ ++ leal 4(%edi),%edi ++ decl %ebp ++ jnz LLoop2 ++ ++ jmp LL1 ++LLend2: addl %eax,%eax /* restore carry from eax */ ++LL1: movl %edx,(%edi) /* store last limb */ ++ ++ sbbl %eax,%eax ++ negl %eax ++ ++ popl %ebp ++ popl %ebx ++ popl %esi ++ popl %edi ++ ret ++ ++ +diff --git a/grub-core/lib/libgcrypt/mpi/i586/mpih-mul1.S b/grub-core/lib/libgcrypt/mpi/i586/mpih-mul1.S +new file mode 100644 +index 0000000..3601d96 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/i586/mpih-mul1.S +@@ -0,0 +1,89 @@ ++/* i80586 mul_1 -- Multiply a limb vector with a limb and store ++ * the result in a second limb vector. ++ * ++ * Copyright (C) 1992, 1994, 1996, 1998, ++ * 2001, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ * ++ * Note: This code is heavily based on the GNU MP Library. ++ * Actually it's the same code with only minor changes in the ++ * way the data is stored; this is to support the abstraction ++ * of an optional secure memory allocation which may be used ++ * to avoid revealing of sensitive data due to paging etc. ++ */ ++ ++ ++#include "sysdep.h" ++#include "asm-syntax.h" ++ ++ ++/******************* ++ * mpi_limb_t ++ * _gcry_mpih_mul_1( mpi_ptr_t res_ptr, (sp + 4) ++ * mpi_ptr_t s1_ptr, (sp + 8) ++ * mpi_size_t s1_size, (sp + 12) ++ * mpi_limb_t s2_limb) (sp + 16) ++ */ ++ ++#define res_ptr edi ++#define s1_ptr esi ++#define size ecx ++#define s2_limb ebp ++ ++ TEXT ++ ALIGN (3) ++ GLOBL C_SYMBOL_NAME(_gcry_mpih_mul_1) ++C_SYMBOL_NAME(_gcry_mpih_mul_1:) ++ ++ INSN1(push,l ,R(edi)) ++ INSN1(push,l ,R(esi)) ++ INSN1(push,l ,R(ebx)) ++ INSN1(push,l ,R(ebp)) ++ ++ INSN2(mov,l ,R(res_ptr),MEM_DISP(esp,20)) ++ INSN2(mov,l ,R(s1_ptr),MEM_DISP(esp,24)) ++ INSN2(mov,l ,R(size),MEM_DISP(esp,28)) ++ INSN2(mov,l ,R(s2_limb),MEM_DISP(esp,32)) ++ ++ INSN2(lea,l ,R(res_ptr),MEM_INDEX(res_ptr,size,4)) ++ INSN2(lea,l ,R(s1_ptr),MEM_INDEX(s1_ptr,size,4)) ++ INSN1(neg,l ,R(size)) ++ INSN2(xor,l ,R(ebx),R(ebx)) ++ ALIGN (3) ++ ++Loop: INSN2(adc,l ,R(ebx),$0) ++ INSN2(mov,l ,R(eax),MEM_INDEX(s1_ptr,size,4)) ++ ++ INSN1(mul,l ,R(s2_limb)) ++ ++ INSN2(add,l ,R(ebx),R(eax)) ++ ++ INSN2(mov,l ,MEM_INDEX(res_ptr,size,4),R(ebx)) ++ INSN1(inc,l ,R(size)) ++ ++ INSN2(mov,l ,R(ebx),R(edx)) ++ INSN1(jnz, ,Loop) ++ ++ INSN2(adc,l ,R(ebx),$0) ++ INSN2(mov,l ,R(eax),R(ebx)) ++ INSN1(pop,l ,R(ebp)) ++ INSN1(pop,l ,R(ebx)) ++ INSN1(pop,l ,R(esi)) ++ INSN1(pop,l ,R(edi)) ++ ret ++ +diff --git a/grub-core/lib/libgcrypt/mpi/i586/mpih-mul2.S b/grub-core/lib/libgcrypt/mpi/i586/mpih-mul2.S +new file mode 100644 +index 0000000..f32d363 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/i586/mpih-mul2.S +@@ -0,0 +1,93 @@ ++/* i80586 addmul_1 -- Multiply a limb vector with a limb and add ++ * the result to a second limb vector. ++ * ++ * Copyright (C) 1992, 1994, 1998, ++ * 2001, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ * ++ * Note: This code is heavily based on the GNU MP Library. ++ * Actually it's the same code with only minor changes in the ++ * way the data is stored; this is to support the abstraction ++ * of an optional secure memory allocation which may be used ++ * to avoid revealing of sensitive data due to paging etc. ++ */ ++ ++ ++#include "sysdep.h" ++#include "asm-syntax.h" ++ ++ ++/******************* ++ * mpi_limb_t ++ * _gcry_mpih_addmul_1( mpi_ptr_t res_ptr, (sp + 4) ++ * mpi_ptr_t s1_ptr, (sp + 8) ++ * mpi_size_t s1_size, (sp + 12) ++ * mpi_limb_t s2_limb) (sp + 16) ++ */ ++ ++#define res_ptr edi ++#define s1_ptr esi ++#define size ecx ++#define s2_limb ebp ++ ++ TEXT ++ ALIGN (3) ++ GLOBL C_SYMBOL_NAME(_gcry_mpih_addmul_1) ++C_SYMBOL_NAME(_gcry_mpih_addmul_1:) ++ ++ INSN1(push,l ,R(edi)) ++ INSN1(push,l ,R(esi)) ++ INSN1(push,l ,R(ebx)) ++ INSN1(push,l ,R(ebp)) ++ ++ INSN2(mov,l ,R(res_ptr),MEM_DISP(esp,20)) ++ INSN2(mov,l ,R(s1_ptr),MEM_DISP(esp,24)) ++ INSN2(mov,l ,R(size),MEM_DISP(esp,28)) ++ INSN2(mov,l ,R(s2_limb),MEM_DISP(esp,32)) ++ ++ INSN2(lea,l ,R(res_ptr),MEM_INDEX(res_ptr,size,4)) ++ INSN2(lea,l ,R(s1_ptr),MEM_INDEX(s1_ptr,size,4)) ++ INSN1(neg,l ,R(size)) ++ INSN2(xor,l ,R(ebx),R(ebx)) ++ ALIGN (3) ++ ++Loop: INSN2(adc,l ,R(ebx),$0) ++ INSN2(mov,l ,R(eax),MEM_INDEX(s1_ptr,size,4)) ++ ++ INSN1(mul,l ,R(s2_limb)) ++ ++ INSN2(add,l ,R(eax),R(ebx)) ++ INSN2(mov,l ,R(ebx),MEM_INDEX(res_ptr,size,4)) ++ ++ INSN2(adc,l ,R(edx),$0) ++ INSN2(add,l ,R(ebx),R(eax)) ++ ++ INSN2(mov,l ,MEM_INDEX(res_ptr,size,4),R(ebx)) ++ INSN1(inc,l ,R(size)) ++ ++ INSN2(mov,l ,R(ebx),R(edx)) ++ INSN1(jnz, ,Loop) ++ ++ INSN2(adc,l ,R(ebx),$0) ++ INSN2(mov,l ,R(eax),R(ebx)) ++ INSN1(pop,l ,R(ebp)) ++ INSN1(pop,l ,R(ebx)) ++ INSN1(pop,l ,R(esi)) ++ INSN1(pop,l ,R(edi)) ++ ret ++ +diff --git a/grub-core/lib/libgcrypt/mpi/i586/mpih-mul3.S b/grub-core/lib/libgcrypt/mpi/i586/mpih-mul3.S +new file mode 100644 +index 0000000..fa27d4e +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/i586/mpih-mul3.S +@@ -0,0 +1,93 @@ ++/* i80586 submul_1 -- Multiply a limb vector with a limb and add ++ * the result to a second limb vector. ++ * ++ * Copyright (C) 1992, 1994, 1998, ++ * 2001, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ * ++ * Note: This code is heavily based on the GNU MP Library. ++ * Actually it's the same code with only minor changes in the ++ * way the data is stored; this is to support the abstraction ++ * of an optional secure memory allocation which may be used ++ * to avoid revealing of sensitive data due to paging etc. ++ */ ++ ++ ++#include "sysdep.h" ++#include "asm-syntax.h" ++ ++ ++/******************* ++ * mpi_limb_t ++ * _gcry_mpih_submul_1( mpi_ptr_t res_ptr, (sp + 4) ++ * mpi_ptr_t s1_ptr, (sp + 8) ++ * mpi_size_t s1_size, (sp + 12) ++ * mpi_limb_t s2_limb) (sp + 16) ++ */ ++ ++#define res_ptr edi ++#define s1_ptr esi ++#define size ecx ++#define s2_limb ebp ++ ++ TEXT ++ ALIGN (3) ++ GLOBL C_SYMBOL_NAME(_gcry_mpih_submul_1) ++C_SYMBOL_NAME(_gcry_mpih_submul_1:) ++ ++ INSN1(push,l ,R(edi)) ++ INSN1(push,l ,R(esi)) ++ INSN1(push,l ,R(ebx)) ++ INSN1(push,l ,R(ebp)) ++ ++ INSN2(mov,l ,R(res_ptr),MEM_DISP(esp,20)) ++ INSN2(mov,l ,R(s1_ptr),MEM_DISP(esp,24)) ++ INSN2(mov,l ,R(size),MEM_DISP(esp,28)) ++ INSN2(mov,l ,R(s2_limb),MEM_DISP(esp,32)) ++ ++ INSN2(lea,l ,R(res_ptr),MEM_INDEX(res_ptr,size,4)) ++ INSN2(lea,l ,R(s1_ptr),MEM_INDEX(s1_ptr,size,4)) ++ INSN1(neg,l ,R(size)) ++ INSN2(xor,l ,R(ebx),R(ebx)) ++ ALIGN (3) ++ ++Loop: INSN2(adc,l ,R(ebx),$0) ++ INSN2(mov,l ,R(eax),MEM_INDEX(s1_ptr,size,4)) ++ ++ INSN1(mul,l ,R(s2_limb)) ++ ++ INSN2(add,l ,R(eax),R(ebx)) ++ INSN2(mov,l ,R(ebx),MEM_INDEX(res_ptr,size,4)) ++ ++ INSN2(adc,l ,R(edx),$0) ++ INSN2(sub,l ,R(ebx),R(eax)) ++ ++ INSN2(mov,l ,MEM_INDEX(res_ptr,size,4),R(ebx)) ++ INSN1(inc,l ,R(size)) ++ ++ INSN2(mov,l ,R(ebx),R(edx)) ++ INSN1(jnz, ,Loop) ++ ++ INSN2(adc,l ,R(ebx),$0) ++ INSN2(mov,l ,R(eax),R(ebx)) ++ INSN1(pop,l ,R(ebp)) ++ INSN1(pop,l ,R(ebx)) ++ INSN1(pop,l ,R(esi)) ++ INSN1(pop,l ,R(edi)) ++ ret ++ +diff --git a/grub-core/lib/libgcrypt/mpi/i586/mpih-rshift.S b/grub-core/lib/libgcrypt/mpi/i586/mpih-rshift.S +new file mode 100644 +index 0000000..c661e3d +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/i586/mpih-rshift.S +@@ -0,0 +1,228 @@ ++/* i80586 rshift ++ * ++ * Copyright (C) 1992, 1994, 1998, ++ * 2001, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ * ++ * Note: This code is heavily based on the GNU MP Library. ++ * Actually it's the same code with only minor changes in the ++ * way the data is stored; this is to support the abstraction ++ * of an optional secure memory allocation which may be used ++ * to avoid revealing of sensitive data due to paging etc. ++ */ ++ ++ ++#include "sysdep.h" ++#include "asm-syntax.h" ++ ++ ++ ++/******************* ++ * mpi_limb_t ++ * _gcry_mpih_rshift( mpi_ptr_t wp, (sp + 4) ++ * mpi_ptr_t up, (sp + 8) ++ * mpi_size_t usize, (sp + 12) ++ * unsigned cnt) (sp + 16) ++ */ ++ ++.text ++ ALIGN (3) ++ .globl C_SYMBOL_NAME(_gcry_mpih_rshift) ++C_SYMBOL_NAME(_gcry_mpih_rshift:) ++ pushl %edi ++ pushl %esi ++ pushl %ebx ++ pushl %ebp ++ ++ movl 20(%esp),%edi /* res_ptr */ ++ movl 24(%esp),%esi /* s_ptr */ ++ movl 28(%esp),%ebp /* size */ ++ movl 32(%esp),%ecx /* cnt */ ++ ++/* We can use faster code for shift-by-1 under certain conditions. */ ++ cmp $1,%ecx ++ jne Rnormal ++ leal 4(%edi),%eax ++ cmpl %esi,%eax ++ jnc Rspecial /* jump if res_ptr + 1 >= s_ptr */ ++ leal (%edi,%ebp,4),%eax ++ cmpl %eax,%esi ++ jnc Rspecial /* jump if s_ptr >= res_ptr + size */ ++ ++Rnormal: ++ movl (%esi),%edx ++ addl $4,%esi ++ xorl %eax,%eax ++ shrdl %cl,%edx,%eax /* compute carry limb */ ++ pushl %eax /* push carry limb onto stack */ ++ ++ decl %ebp ++ pushl %ebp ++ shrl $3,%ebp ++ jz Rend ++ ++ movl (%edi),%eax /* fetch destination cache line */ ++ ++ ALIGN (2) ++Roop: movl 28(%edi),%eax /* fetch destination cache line */ ++ movl %edx,%ebx ++ ++ movl (%esi),%eax ++ movl 4(%esi),%edx ++ shrdl %cl,%eax,%ebx ++ shrdl %cl,%edx,%eax ++ movl %ebx,(%edi) ++ movl %eax,4(%edi) ++ ++ movl 8(%esi),%ebx ++ movl 12(%esi),%eax ++ shrdl %cl,%ebx,%edx ++ shrdl %cl,%eax,%ebx ++ movl %edx,8(%edi) ++ movl %ebx,12(%edi) ++ ++ movl 16(%esi),%edx ++ movl 20(%esi),%ebx ++ shrdl %cl,%edx,%eax ++ shrdl %cl,%ebx,%edx ++ movl %eax,16(%edi) ++ movl %edx,20(%edi) ++ ++ movl 24(%esi),%eax ++ movl 28(%esi),%edx ++ shrdl %cl,%eax,%ebx ++ shrdl %cl,%edx,%eax ++ movl %ebx,24(%edi) ++ movl %eax,28(%edi) ++ ++ addl $32,%esi ++ addl $32,%edi ++ decl %ebp ++ jnz Roop ++ ++Rend: popl %ebp ++ andl $7,%ebp ++ jz Rend2 ++Roop2: movl (%esi),%eax ++ shrdl %cl,%eax,%edx /* compute result limb */ ++ movl %edx,(%edi) ++ movl %eax,%edx ++ addl $4,%esi ++ addl $4,%edi ++ decl %ebp ++ jnz Roop2 ++ ++Rend2: shrl %cl,%edx /* compute most significant limb */ ++ movl %edx,(%edi) /* store it */ ++ ++ popl %eax /* pop carry limb */ ++ ++ popl %ebp ++ popl %ebx ++ popl %esi ++ popl %edi ++ ret ++ ++/* We loop from least significant end of the arrays, which is only ++ permissable if the source and destination don't overlap, since the ++ function is documented to work for overlapping source and destination. ++*/ ++ ++Rspecial: ++ leal -4(%edi,%ebp,4),%edi ++ leal -4(%esi,%ebp,4),%esi ++ ++ movl (%esi),%edx ++ subl $4,%esi ++ ++ decl %ebp ++ pushl %ebp ++ shrl $3,%ebp ++ ++ shrl $1,%edx ++ incl %ebp ++ decl %ebp ++ jz RLend ++ ++ movl (%edi),%eax /* fetch destination cache line */ ++ ++ ALIGN (2) ++RLoop: movl -28(%edi),%eax /* fetch destination cache line */ ++ movl %edx,%ebx ++ ++ movl (%esi),%eax ++ movl -4(%esi),%edx ++ rcrl $1,%eax ++ movl %ebx,(%edi) ++ rcrl $1,%edx ++ movl %eax,-4(%edi) ++ ++ movl -8(%esi),%ebx ++ movl -12(%esi),%eax ++ rcrl $1,%ebx ++ movl %edx,-8(%edi) ++ rcrl $1,%eax ++ movl %ebx,-12(%edi) ++ ++ movl -16(%esi),%edx ++ movl -20(%esi),%ebx ++ rcrl $1,%edx ++ movl %eax,-16(%edi) ++ rcrl $1,%ebx ++ movl %edx,-20(%edi) ++ ++ movl -24(%esi),%eax ++ movl -28(%esi),%edx ++ rcrl $1,%eax ++ movl %ebx,-24(%edi) ++ rcrl $1,%edx ++ movl %eax,-28(%edi) ++ ++ leal -32(%esi),%esi /* use leal not to clobber carry */ ++ leal -32(%edi),%edi ++ decl %ebp ++ jnz RLoop ++ ++RLend: popl %ebp ++ sbbl %eax,%eax /* save carry in %eax */ ++ andl $7,%ebp ++ jz RLend2 ++ addl %eax,%eax /* restore carry from eax */ ++RLoop2: movl %edx,%ebx ++ movl (%esi),%edx ++ rcrl $1,%edx ++ movl %ebx,(%edi) ++ ++ leal -4(%esi),%esi /* use leal not to clobber carry */ ++ leal -4(%edi),%edi ++ decl %ebp ++ jnz RLoop2 ++ ++ jmp RL1 ++RLend2: addl %eax,%eax /* restore carry from eax */ ++RL1: movl %edx,(%edi) /* store last limb */ ++ ++ movl $0,%eax ++ rcrl $1,%eax ++ ++ popl %ebp ++ popl %ebx ++ popl %esi ++ popl %edi ++ ret ++ +diff --git a/grub-core/lib/libgcrypt/mpi/i586/mpih-sub1.S b/grub-core/lib/libgcrypt/mpi/i586/mpih-sub1.S +new file mode 100644 +index 0000000..ef2d580 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/i586/mpih-sub1.S +@@ -0,0 +1,142 @@ ++/* i80586 sub_n -- Sub two limb vectors of the same length > 0 and store ++ * sum in a third limb vector. ++ * ++ * Copyright (C) 1992, 1994, 1995, 1998, ++ * 2001, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ * ++ * Note: This code is heavily based on the GNU MP Library. ++ * Actually it's the same code with only minor changes in the ++ * way the data is stored; this is to support the abstraction ++ * of an optional secure memory allocation which may be used ++ * to avoid revealing of sensitive data due to paging etc. ++ */ ++ ++ ++#include "sysdep.h" ++#include "asm-syntax.h" ++ ++ ++/******************* ++ * mpi_limb_t ++ * _gcry_mpih_sub_n( mpi_ptr_t res_ptr, (sp + 4) ++ * mpi_ptr_t s1_ptr, (sp + 8) ++ * mpi_ptr_t s2_ptr, (sp + 12) ++ * mpi_size_t size) (sp + 16) ++ */ ++ ++ ++.text ++ ALIGN (3) ++ .globl C_SYMBOL_NAME(_gcry_mpih_sub_n) ++C_SYMBOL_NAME(_gcry_mpih_sub_n:) ++ ++ pushl %edi ++ pushl %esi ++ pushl %ebx ++ pushl %ebp ++ ++ movl 20(%esp),%edi /* res_ptr */ ++ movl 24(%esp),%esi /* s1_ptr */ ++ movl 28(%esp),%ebp /* s2_ptr */ ++ movl 32(%esp),%ecx /* size */ ++ ++ movl (%ebp),%ebx ++ ++ decl %ecx ++ movl %ecx,%edx ++ shrl $3,%ecx ++ andl $7,%edx ++ testl %ecx,%ecx /* zero carry flag */ ++ jz Lend ++ pushl %edx ++ ++ ALIGN (3) ++Loop: movl 28(%edi),%eax /* fetch destination cache line */ ++ leal 32(%edi),%edi ++ ++L1: movl (%esi),%eax ++ movl 4(%esi),%edx ++ sbbl %ebx,%eax ++ movl 4(%ebp),%ebx ++ sbbl %ebx,%edx ++ movl 8(%ebp),%ebx ++ movl %eax,-32(%edi) ++ movl %edx,-28(%edi) ++ ++L2: movl 8(%esi),%eax ++ movl 12(%esi),%edx ++ sbbl %ebx,%eax ++ movl 12(%ebp),%ebx ++ sbbl %ebx,%edx ++ movl 16(%ebp),%ebx ++ movl %eax,-24(%edi) ++ movl %edx,-20(%edi) ++ ++L3: movl 16(%esi),%eax ++ movl 20(%esi),%edx ++ sbbl %ebx,%eax ++ movl 20(%ebp),%ebx ++ sbbl %ebx,%edx ++ movl 24(%ebp),%ebx ++ movl %eax,-16(%edi) ++ movl %edx,-12(%edi) ++ ++L4: movl 24(%esi),%eax ++ movl 28(%esi),%edx ++ sbbl %ebx,%eax ++ movl 28(%ebp),%ebx ++ sbbl %ebx,%edx ++ movl 32(%ebp),%ebx ++ movl %eax,-8(%edi) ++ movl %edx,-4(%edi) ++ ++ leal 32(%esi),%esi ++ leal 32(%ebp),%ebp ++ decl %ecx ++ jnz Loop ++ ++ popl %edx ++Lend: ++ decl %edx /* test %edx w/o clobbering carry */ ++ js Lend2 ++ incl %edx ++Loop2: ++ leal 4(%edi),%edi ++ movl (%esi),%eax ++ sbbl %ebx,%eax ++ movl 4(%ebp),%ebx ++ movl %eax,-4(%edi) ++ leal 4(%esi),%esi ++ leal 4(%ebp),%ebp ++ decl %edx ++ jnz Loop2 ++Lend2: ++ movl (%esi),%eax ++ sbbl %ebx,%eax ++ movl %eax,(%edi) ++ ++ sbbl %eax,%eax ++ negl %eax ++ ++ popl %ebp ++ popl %ebx ++ popl %esi ++ popl %edi ++ ret ++ +diff --git a/grub-core/lib/libgcrypt/mpi/longlong.h b/grub-core/lib/libgcrypt/mpi/longlong.h +new file mode 100644 +index 0000000..5dba793 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/longlong.h +@@ -0,0 +1,1578 @@ ++/* longlong.h -- definitions for mixed size 32/64 bit arithmetic. ++ Note: I added some stuff for use with gnupg ++ ++Copyright (C) 1991, 1992, 1993, 1994, 1996, 1998, ++ 2000, 2001, 2002, 2003, 2004, 2011 Free Software Foundation, Inc. ++ ++This file is free software; you can redistribute it and/or modify ++it under the terms of the GNU Lesser General Public License as published by ++the Free Software Foundation; either version 2.1 of the License, or (at your ++option) any later version. ++ ++This file 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 Lesser General Public ++License for more details. ++ ++You should have received a copy of the GNU Library General Public License ++along with this file; see the file COPYING.LIB. If not, write to ++the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, ++MA 02111-1307, USA. */ ++ ++/* You have to define the following before including this file: ++ ++ UWtype -- An unsigned type, default type for operations (typically a "word") ++ UHWtype -- An unsigned type, at least half the size of UWtype. ++ UDWtype -- An unsigned type, at least twice as large a UWtype ++ W_TYPE_SIZE -- size in bits of UWtype ++ ++ SItype, USItype -- Signed and unsigned 32 bit types. ++ DItype, UDItype -- Signed and unsigned 64 bit types. ++ ++ On a 32 bit machine UWtype should typically be USItype; ++ on a 64 bit machine, UWtype should typically be UDItype. ++*/ ++ ++#define __BITS4 (W_TYPE_SIZE / 4) ++#define __ll_B ((UWtype) 1 << (W_TYPE_SIZE / 2)) ++#define __ll_lowpart(t) ((UWtype) (t) & (__ll_B - 1)) ++#define __ll_highpart(t) ((UWtype) (t) >> (W_TYPE_SIZE / 2)) ++ ++/* This is used to make sure no undesirable sharing between different libraries ++ that use this file takes place. */ ++#ifndef __MPN ++#define __MPN(x) __##x ++#endif ++ ++/* Define auxiliary asm macros. ++ ++ 1) umul_ppmm(high_prod, low_prod, multipler, multiplicand) multiplies two ++ UWtype integers MULTIPLER and MULTIPLICAND, and generates a two UWtype ++ word product in HIGH_PROD and LOW_PROD. ++ ++ 2) __umulsidi3(a,b) multiplies two UWtype integers A and B, and returns a ++ UDWtype product. This is just a variant of umul_ppmm. ++ ++ 3) udiv_qrnnd(quotient, remainder, high_numerator, low_numerator, ++ denominator) divides a UDWtype, composed by the UWtype integers ++ HIGH_NUMERATOR and LOW_NUMERATOR, by DENOMINATOR and places the quotient ++ in QUOTIENT and the remainder in REMAINDER. HIGH_NUMERATOR must be less ++ than DENOMINATOR for correct operation. If, in addition, the most ++ significant bit of DENOMINATOR must be 1, then the pre-processor symbol ++ UDIV_NEEDS_NORMALIZATION is defined to 1. ++ ++ 4) sdiv_qrnnd(quotient, remainder, high_numerator, low_numerator, ++ denominator). Like udiv_qrnnd but the numbers are signed. The quotient ++ is rounded towards 0. ++ ++ 5) count_leading_zeros(count, x) counts the number of zero-bits from the ++ msb to the first non-zero bit in the UWtype X. This is the number of ++ steps X needs to be shifted left to set the msb. Undefined for X == 0, ++ unless the symbol COUNT_LEADING_ZEROS_0 is defined to some value. ++ ++ 6) count_trailing_zeros(count, x) like count_leading_zeros, but counts ++ from the least significant end. ++ ++ 7) add_ssaaaa(high_sum, low_sum, high_addend_1, low_addend_1, ++ high_addend_2, low_addend_2) adds two UWtype integers, composed by ++ HIGH_ADDEND_1 and LOW_ADDEND_1, and HIGH_ADDEND_2 and LOW_ADDEND_2 ++ respectively. The result is placed in HIGH_SUM and LOW_SUM. Overflow ++ (i.e. carry out) is not stored anywhere, and is lost. ++ ++ 8) sub_ddmmss(high_difference, low_difference, high_minuend, low_minuend, ++ high_subtrahend, low_subtrahend) subtracts two two-word UWtype integers, ++ composed by HIGH_MINUEND_1 and LOW_MINUEND_1, and HIGH_SUBTRAHEND_2 and ++ LOW_SUBTRAHEND_2 respectively. The result is placed in HIGH_DIFFERENCE ++ and LOW_DIFFERENCE. Overflow (i.e. carry out) is not stored anywhere, ++ and is lost. ++ ++ If any of these macros are left undefined for a particular CPU, ++ C macros are used. */ ++ ++/* The CPUs come in alphabetical order below. ++ ++ Please add support for more CPUs here, or improve the current support ++ for the CPUs below! */ ++ ++#ifdef __riscos__ ++#pragma continue_after_hash_error ++#else /* !__riscos__ */ ++#if defined (__GNUC__) && !defined (NO_ASM) ++ ++/* We sometimes need to clobber "cc" with gcc2, but that would not be ++ understood by gcc1. Use cpp to avoid major code duplication. */ ++#if __GNUC__ < 2 ++#define __CLOBBER_CC ++#define __AND_CLOBBER_CC ++#else /* __GNUC__ >= 2 */ ++#define __CLOBBER_CC : "cc" ++#define __AND_CLOBBER_CC , "cc" ++#endif /* __GNUC__ < 2 */ ++ ++ ++/*************************************** ++ ************** A29K ***************** ++ ***************************************/ ++#if (defined (__a29k__) || defined (_AM29K)) && W_TYPE_SIZE == 32 ++#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("add %1,%4,%5\n" \ ++ "addc %0,%2,%3" \ ++ : "=r" ((USItype)(sh)), \ ++ "=&r" ((USItype)(sl)) \ ++ : "%r" ((USItype)(ah)), \ ++ "rI" ((USItype)(bh)), \ ++ "%r" ((USItype)(al)), \ ++ "rI" ((USItype)(bl))) ++#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("sub %1,%4,%5\n" \ ++ "subc %0,%2,%3" \ ++ : "=r" ((USItype)(sh)), \ ++ "=&r" ((USItype)(sl)) \ ++ : "r" ((USItype)(ah)), \ ++ "rI" ((USItype)(bh)), \ ++ "r" ((USItype)(al)), \ ++ "rI" ((USItype)(bl))) ++#define umul_ppmm(xh, xl, m0, m1) \ ++ do { \ ++ USItype __m0 = (m0), __m1 = (m1); \ ++ __asm__ ("multiplu %0,%1,%2" \ ++ : "=r" ((USItype)(xl)) \ ++ : "r" (__m0), \ ++ "r" (__m1)); \ ++ __asm__ ("multmu %0,%1,%2" \ ++ : "=r" ((USItype)(xh)) \ ++ : "r" (__m0), \ ++ "r" (__m1)); \ ++ } while (0) ++#define udiv_qrnnd(q, r, n1, n0, d) \ ++ __asm__ ("dividu %0,%3,%4" \ ++ : "=r" ((USItype)(q)), \ ++ "=q" ((USItype)(r)) \ ++ : "1" ((USItype)(n1)), \ ++ "r" ((USItype)(n0)), \ ++ "r" ((USItype)(d))) ++#define count_leading_zeros(count, x) \ ++ __asm__ ("clz %0,%1" \ ++ : "=r" ((USItype)(count)) \ ++ : "r" ((USItype)(x))) ++#define COUNT_LEADING_ZEROS_0 32 ++#endif /* __a29k__ */ ++ ++ ++#if defined (__alpha) && W_TYPE_SIZE == 64 ++#define umul_ppmm(ph, pl, m0, m1) \ ++ do { \ ++ UDItype __m0 = (m0), __m1 = (m1); \ ++ __asm__ ("umulh %r1,%2,%0" \ ++ : "=r" ((UDItype) ph) \ ++ : "%rJ" (__m0), \ ++ "rI" (__m1)); \ ++ (pl) = __m0 * __m1; \ ++ } while (0) ++#define UMUL_TIME 46 ++#ifndef LONGLONG_STANDALONE ++#define udiv_qrnnd(q, r, n1, n0, d) \ ++ do { UDItype __r; \ ++ (q) = __udiv_qrnnd (&__r, (n1), (n0), (d)); \ ++ (r) = __r; \ ++ } while (0) ++extern UDItype __udiv_qrnnd (); ++#define UDIV_TIME 220 ++#endif /* LONGLONG_STANDALONE */ ++#endif /* __alpha */ ++ ++/*************************************** ++ ************** ARM ****************** ++ ***************************************/ ++#if defined (__arm__) && W_TYPE_SIZE == 32 && !defined (__thumb__) ++#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("adds %1, %4, %5\n" \ ++ "adc %0, %2, %3" \ ++ : "=r" ((USItype)(sh)), \ ++ "=&r" ((USItype)(sl)) \ ++ : "%r" ((USItype)(ah)), \ ++ "rI" ((USItype)(bh)), \ ++ "%r" ((USItype)(al)), \ ++ "rI" ((USItype)(bl))) ++#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("subs %1, %4, %5\n" \ ++ "sbc %0, %2, %3" \ ++ : "=r" ((USItype)(sh)), \ ++ "=&r" ((USItype)(sl)) \ ++ : "r" ((USItype)(ah)), \ ++ "rI" ((USItype)(bh)), \ ++ "r" ((USItype)(al)), \ ++ "rI" ((USItype)(bl))) ++#if defined __ARM_ARCH_2__ || defined __ARM_ARCH_3__ ++#define umul_ppmm(xh, xl, a, b) \ ++ __asm__ ("%@ Inlined umul_ppmm\n" \ ++ "mov %|r0, %2, lsr #16 @ AAAA\n" \ ++ "mov %|r2, %3, lsr #16 @ BBBB\n" \ ++ "bic %|r1, %2, %|r0, lsl #16 @ aaaa\n" \ ++ "bic %0, %3, %|r2, lsl #16 @ bbbb\n" \ ++ "mul %1, %|r1, %|r2 @ aaaa * BBBB\n" \ ++ "mul %|r2, %|r0, %|r2 @ AAAA * BBBB\n" \ ++ "mul %|r1, %0, %|r1 @ aaaa * bbbb\n" \ ++ "mul %0, %|r0, %0 @ AAAA * bbbb\n" \ ++ "adds %|r0, %1, %0 @ central sum\n" \ ++ "addcs %|r2, %|r2, #65536\n" \ ++ "adds %1, %|r1, %|r0, lsl #16\n" \ ++ "adc %0, %|r2, %|r0, lsr #16" \ ++ : "=&r" ((USItype)(xh)), \ ++ "=r" ((USItype)(xl)) \ ++ : "r" ((USItype)(a)), \ ++ "r" ((USItype)(b)) \ ++ : "r0", "r1", "r2") ++#else ++#define umul_ppmm(xh, xl, a, b) \ ++ __asm__ ("%@ Inlined umul_ppmm\n" \ ++ "umull %r1, %r0, %r2, %r3" \ ++ : "=&r" ((USItype)(xh)), \ ++ "=r" ((USItype)(xl)) \ ++ : "r" ((USItype)(a)), \ ++ "r" ((USItype)(b)) \ ++ : "r0", "r1") ++#endif ++#define UMUL_TIME 20 ++#define UDIV_TIME 100 ++#endif /* __arm__ */ ++ ++/*************************************** ++ ************** CLIPPER ************** ++ ***************************************/ ++#if defined (__clipper__) && W_TYPE_SIZE == 32 ++#define umul_ppmm(w1, w0, u, v) \ ++ ({union {UDItype __ll; \ ++ struct {USItype __l, __h;} __i; \ ++ } __xx; \ ++ __asm__ ("mulwux %2,%0" \ ++ : "=r" (__xx.__ll) \ ++ : "%0" ((USItype)(u)), \ ++ "r" ((USItype)(v))); \ ++ (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;}) ++#define smul_ppmm(w1, w0, u, v) \ ++ ({union {DItype __ll; \ ++ struct {SItype __l, __h;} __i; \ ++ } __xx; \ ++ __asm__ ("mulwx %2,%0" \ ++ : "=r" (__xx.__ll) \ ++ : "%0" ((SItype)(u)), \ ++ "r" ((SItype)(v))); \ ++ (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;}) ++#define __umulsidi3(u, v) \ ++ ({UDItype __w; \ ++ __asm__ ("mulwux %2,%0" \ ++ : "=r" (__w) \ ++ : "%0" ((USItype)(u)), \ ++ "r" ((USItype)(v))); \ ++ __w; }) ++#endif /* __clipper__ */ ++ ++ ++/*************************************** ++ ************** GMICRO *************** ++ ***************************************/ ++#if defined (__gmicro__) && W_TYPE_SIZE == 32 ++#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("add.w %5,%1\n" \ ++ "addx %3,%0" \ ++ : "=g" ((USItype)(sh)), \ ++ "=&g" ((USItype)(sl)) \ ++ : "%0" ((USItype)(ah)), \ ++ "g" ((USItype)(bh)), \ ++ "%1" ((USItype)(al)), \ ++ "g" ((USItype)(bl))) ++#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("sub.w %5,%1\n" \ ++ "subx %3,%0" \ ++ : "=g" ((USItype)(sh)), \ ++ "=&g" ((USItype)(sl)) \ ++ : "0" ((USItype)(ah)), \ ++ "g" ((USItype)(bh)), \ ++ "1" ((USItype)(al)), \ ++ "g" ((USItype)(bl))) ++#define umul_ppmm(ph, pl, m0, m1) \ ++ __asm__ ("mulx %3,%0,%1" \ ++ : "=g" ((USItype)(ph)), \ ++ "=r" ((USItype)(pl)) \ ++ : "%0" ((USItype)(m0)), \ ++ "g" ((USItype)(m1))) ++#define udiv_qrnnd(q, r, nh, nl, d) \ ++ __asm__ ("divx %4,%0,%1" \ ++ : "=g" ((USItype)(q)), \ ++ "=r" ((USItype)(r)) \ ++ : "1" ((USItype)(nh)), \ ++ "0" ((USItype)(nl)), \ ++ "g" ((USItype)(d))) ++#define count_leading_zeros(count, x) \ ++ __asm__ ("bsch/1 %1,%0" \ ++ : "=g" (count) \ ++ : "g" ((USItype)(x)), \ ++ "0" ((USItype)0)) ++#endif ++ ++ ++/*************************************** ++ ************** HPPA ***************** ++ ***************************************/ ++#if defined (__hppa) && W_TYPE_SIZE == 32 ++#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ ++ __asm__ (" add %4,%5,%1\n" \ ++ " addc %2,%3,%0" \ ++ : "=r" ((USItype)(sh)), \ ++ "=&r" ((USItype)(sl)) \ ++ : "%rM" ((USItype)(ah)), \ ++ "rM" ((USItype)(bh)), \ ++ "%rM" ((USItype)(al)), \ ++ "rM" ((USItype)(bl))) ++#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ ++ __asm__ (" sub %4,%5,%1\n" \ ++ " subb %2,%3,%0" \ ++ : "=r" ((USItype)(sh)), \ ++ "=&r" ((USItype)(sl)) \ ++ : "rM" ((USItype)(ah)), \ ++ "rM" ((USItype)(bh)), \ ++ "rM" ((USItype)(al)), \ ++ "rM" ((USItype)(bl))) ++#if defined (_PA_RISC1_1) ++#define umul_ppmm(wh, wl, u, v) \ ++ do { \ ++ union {UDItype __ll; \ ++ struct {USItype __h, __l;} __i; \ ++ } __xx; \ ++ __asm__ (" xmpyu %1,%2,%0" \ ++ : "=*f" (__xx.__ll) \ ++ : "*f" ((USItype)(u)), \ ++ "*f" ((USItype)(v))); \ ++ (wh) = __xx.__i.__h; \ ++ (wl) = __xx.__i.__l; \ ++ } while (0) ++#define UMUL_TIME 8 ++#define UDIV_TIME 60 ++#else ++#define UMUL_TIME 40 ++#define UDIV_TIME 80 ++#endif ++#ifndef LONGLONG_STANDALONE ++#define udiv_qrnnd(q, r, n1, n0, d) \ ++ do { USItype __r; \ ++ (q) = __udiv_qrnnd (&__r, (n1), (n0), (d)); \ ++ (r) = __r; \ ++ } while (0) ++extern USItype __udiv_qrnnd (); ++#endif /* LONGLONG_STANDALONE */ ++#define count_leading_zeros(count, x) \ ++ do { \ ++ USItype __tmp; \ ++ __asm__ ( \ ++ " ldi 1,%0 \n" \ ++ " extru,= %1,15,16,%%r0 ; Bits 31..16 zero? \n" \ ++ " extru,tr %1,15,16,%1 ; No. Shift down, skip add.\n" \ ++ " ldo 16(%0),%0 ; Yes. Perform add. \n" \ ++ " extru,= %1,23,8,%%r0 ; Bits 15..8 zero? \n" \ ++ " extru,tr %1,23,8,%1 ; No. Shift down, skip add.\n" \ ++ " ldo 8(%0),%0 ; Yes. Perform add. \n" \ ++ " extru,= %1,27,4,%%r0 ; Bits 7..4 zero? \n" \ ++ " extru,tr %1,27,4,%1 ; No. Shift down, skip add.\n" \ ++ " ldo 4(%0),%0 ; Yes. Perform add. \n" \ ++ " extru,= %1,29,2,%%r0 ; Bits 3..2 zero? \n" \ ++ " extru,tr %1,29,2,%1 ; No. Shift down, skip add.\n" \ ++ " ldo 2(%0),%0 ; Yes. Perform add. \n" \ ++ " extru %1,30,1,%1 ; Extract bit 1. \n" \ ++ " sub %0,%1,%0 ; Subtract it. " \ ++ : "=r" (count), "=r" (__tmp) : "1" (x)); \ ++ } while (0) ++#endif /* hppa */ ++ ++ ++/*************************************** ++ ************** I370 ***************** ++ ***************************************/ ++#if (defined (__i370__) || defined (__mvs__)) && W_TYPE_SIZE == 32 ++#define umul_ppmm(xh, xl, m0, m1) \ ++ do { \ ++ union {UDItype __ll; \ ++ struct {USItype __h, __l;} __i; \ ++ } __xx; \ ++ USItype __m0 = (m0), __m1 = (m1); \ ++ __asm__ ("mr %0,%3" \ ++ : "=r" (__xx.__i.__h), \ ++ "=r" (__xx.__i.__l) \ ++ : "%1" (__m0), \ ++ "r" (__m1)); \ ++ (xh) = __xx.__i.__h; (xl) = __xx.__i.__l; \ ++ (xh) += ((((SItype) __m0 >> 31) & __m1) \ ++ + (((SItype) __m1 >> 31) & __m0)); \ ++ } while (0) ++#define smul_ppmm(xh, xl, m0, m1) \ ++ do { \ ++ union {DItype __ll; \ ++ struct {USItype __h, __l;} __i; \ ++ } __xx; \ ++ __asm__ ("mr %0,%3" \ ++ : "=r" (__xx.__i.__h), \ ++ "=r" (__xx.__i.__l) \ ++ : "%1" (m0), \ ++ "r" (m1)); \ ++ (xh) = __xx.__i.__h; (xl) = __xx.__i.__l; \ ++ } while (0) ++#define sdiv_qrnnd(q, r, n1, n0, d) \ ++ do { \ ++ union {DItype __ll; \ ++ struct {USItype __h, __l;} __i; \ ++ } __xx; \ ++ __xx.__i.__h = n1; __xx.__i.__l = n0; \ ++ __asm__ ("dr %0,%2" \ ++ : "=r" (__xx.__ll) \ ++ : "0" (__xx.__ll), "r" (d)); \ ++ (q) = __xx.__i.__l; (r) = __xx.__i.__h; \ ++ } while (0) ++#endif ++ ++ ++/*************************************** ++ ************** I386 ***************** ++ ***************************************/ ++#if (defined (__i386__) || defined (__i486__)) && W_TYPE_SIZE == 32 ++#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("addl %5,%1\n" \ ++ "adcl %3,%0" \ ++ : "=r" ((USItype)(sh)), \ ++ "=&r" ((USItype)(sl)) \ ++ : "%0" ((USItype)(ah)), \ ++ "g" ((USItype)(bh)), \ ++ "%1" ((USItype)(al)), \ ++ "g" ((USItype)(bl))) ++#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("subl %5,%1\n" \ ++ "sbbl %3,%0" \ ++ : "=r" ((USItype)(sh)), \ ++ "=&r" ((USItype)(sl)) \ ++ : "0" ((USItype)(ah)), \ ++ "g" ((USItype)(bh)), \ ++ "1" ((USItype)(al)), \ ++ "g" ((USItype)(bl))) ++#define umul_ppmm(w1, w0, u, v) \ ++ __asm__ ("mull %3" \ ++ : "=a" ((USItype)(w0)), \ ++ "=d" ((USItype)(w1)) \ ++ : "%0" ((USItype)(u)), \ ++ "rm" ((USItype)(v))) ++#define udiv_qrnnd(q, r, n1, n0, d) \ ++ __asm__ ("divl %4" \ ++ : "=a" ((USItype)(q)), \ ++ "=d" ((USItype)(r)) \ ++ : "0" ((USItype)(n0)), \ ++ "1" ((USItype)(n1)), \ ++ "rm" ((USItype)(d))) ++#define count_leading_zeros(count, x) \ ++ do { \ ++ USItype __cbtmp; \ ++ __asm__ ("bsrl %1,%0" \ ++ : "=r" (__cbtmp) : "rm" ((USItype)(x))); \ ++ (count) = __cbtmp ^ 31; \ ++ } while (0) ++#define count_trailing_zeros(count, x) \ ++ __asm__ ("bsfl %1,%0" : "=r" (count) : "rm" ((USItype)(x))) ++#ifndef UMUL_TIME ++#define UMUL_TIME 40 ++#endif ++#ifndef UDIV_TIME ++#define UDIV_TIME 40 ++#endif ++#endif /* 80x86 */ ++ ++ ++/*************************************** ++ ************** I860 ***************** ++ ***************************************/ ++#if defined (__i860__) && W_TYPE_SIZE == 32 ++#define rshift_rhlc(r,h,l,c) \ ++ __asm__ ("shr %3,r0,r0\n" \ ++ "shrd %1,%2,%0" \ ++ "=r" (r) : "r" (h), "r" (l), "rn" (c)) ++#endif /* i860 */ ++ ++/*************************************** ++ ************** I960 ***************** ++ ***************************************/ ++#if defined (__i960__) && W_TYPE_SIZE == 32 ++#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("cmpo 1,0\n" \ ++ "addc %5,%4,%1\n" \ ++ "addc %3,%2,%0" \ ++ : "=r" ((USItype)(sh)), \ ++ "=&r" ((USItype)(sl)) \ ++ : "%dI" ((USItype)(ah)), \ ++ "dI" ((USItype)(bh)), \ ++ "%dI" ((USItype)(al)), \ ++ "dI" ((USItype)(bl))) ++#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("cmpo 0,0\n" \ ++ "subc %5,%4,%1\n" \ ++ "subc %3,%2,%0" \ ++ : "=r" ((USItype)(sh)), \ ++ "=&r" ((USItype)(sl)) \ ++ : "dI" ((USItype)(ah)), \ ++ "dI" ((USItype)(bh)), \ ++ "dI" ((USItype)(al)), \ ++ "dI" ((USItype)(bl))) ++#define umul_ppmm(w1, w0, u, v) \ ++ ({union {UDItype __ll; \ ++ struct {USItype __l, __h;} __i; \ ++ } __xx; \ ++ __asm__ ("emul %2,%1,%0" \ ++ : "=d" (__xx.__ll) \ ++ : "%dI" ((USItype)(u)), \ ++ "dI" ((USItype)(v))); \ ++ (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;}) ++#define __umulsidi3(u, v) \ ++ ({UDItype __w; \ ++ __asm__ ("emul %2,%1,%0" \ ++ : "=d" (__w) \ ++ : "%dI" ((USItype)(u)), \ ++ "dI" ((USItype)(v))); \ ++ __w; }) ++#define udiv_qrnnd(q, r, nh, nl, d) \ ++ do { \ ++ union {UDItype __ll; \ ++ struct {USItype __l, __h;} __i; \ ++ } __nn; \ ++ __nn.__i.__h = (nh); __nn.__i.__l = (nl); \ ++ __asm__ ("ediv %d,%n,%0" \ ++ : "=d" (__rq.__ll) \ ++ : "dI" (__nn.__ll), \ ++ "dI" ((USItype)(d))); \ ++ (r) = __rq.__i.__l; (q) = __rq.__i.__h; \ ++ } while (0) ++#define count_leading_zeros(count, x) \ ++ do { \ ++ USItype __cbtmp; \ ++ __asm__ ("scanbit %1,%0" \ ++ : "=r" (__cbtmp) \ ++ : "r" ((USItype)(x))); \ ++ (count) = __cbtmp ^ 31; \ ++ } while (0) ++#define COUNT_LEADING_ZEROS_0 (-32) /* sic */ ++#if defined (__i960mx) /* what is the proper symbol to test??? */ ++#define rshift_rhlc(r,h,l,c) \ ++ do { \ ++ union {UDItype __ll; \ ++ struct {USItype __l, __h;} __i; \ ++ } __nn; \ ++ __nn.__i.__h = (h); __nn.__i.__l = (l); \ ++ __asm__ ("shre %2,%1,%0" \ ++ : "=d" (r) : "dI" (__nn.__ll), "dI" (c)); \ ++ } ++#endif /* i960mx */ ++#endif /* i960 */ ++ ++ ++/*************************************** ++ ************** 68000 **************** ++ ***************************************/ ++#if (defined (__mc68000__) || defined (__mc68020__) || defined (__NeXT__) || defined(mc68020)) && W_TYPE_SIZE == 32 ++#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("add%.l %5,%1\n" \ ++ "addx%.l %3,%0" \ ++ : "=d" ((USItype)(sh)), \ ++ "=&d" ((USItype)(sl)) \ ++ : "%0" ((USItype)(ah)), \ ++ "d" ((USItype)(bh)), \ ++ "%1" ((USItype)(al)), \ ++ "g" ((USItype)(bl))) ++#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("sub%.l %5,%1\n" \ ++ "subx%.l %3,%0" \ ++ : "=d" ((USItype)(sh)), \ ++ "=&d" ((USItype)(sl)) \ ++ : "0" ((USItype)(ah)), \ ++ "d" ((USItype)(bh)), \ ++ "1" ((USItype)(al)), \ ++ "g" ((USItype)(bl))) ++#if (defined (__mc68020__) || defined (__NeXT__) || defined(mc68020)) ++#define umul_ppmm(w1, w0, u, v) \ ++ __asm__ ("mulu%.l %3,%1:%0" \ ++ : "=d" ((USItype)(w0)), \ ++ "=d" ((USItype)(w1)) \ ++ : "%0" ((USItype)(u)), \ ++ "dmi" ((USItype)(v))) ++#define UMUL_TIME 45 ++#define udiv_qrnnd(q, r, n1, n0, d) \ ++ __asm__ ("divu%.l %4,%1:%0" \ ++ : "=d" ((USItype)(q)), \ ++ "=d" ((USItype)(r)) \ ++ : "0" ((USItype)(n0)), \ ++ "1" ((USItype)(n1)), \ ++ "dmi" ((USItype)(d))) ++#define UDIV_TIME 90 ++#define sdiv_qrnnd(q, r, n1, n0, d) \ ++ __asm__ ("divs%.l %4,%1:%0" \ ++ : "=d" ((USItype)(q)), \ ++ "=d" ((USItype)(r)) \ ++ : "0" ((USItype)(n0)), \ ++ "1" ((USItype)(n1)), \ ++ "dmi" ((USItype)(d))) ++#define count_leading_zeros(count, x) \ ++ __asm__ ("bfffo %1{%b2:%b2},%0" \ ++ : "=d" ((USItype)(count)) \ ++ : "od" ((USItype)(x)), "n" (0)) ++#define COUNT_LEADING_ZEROS_0 32 ++#else /* not mc68020 */ ++#define umul_ppmm(xh, xl, a, b) \ ++ do { USItype __umul_tmp1, __umul_tmp2; \ ++ __asm__ ("| Inlined umul_ppmm \n" \ ++ " move%.l %5,%3 \n" \ ++ " move%.l %2,%0 \n" \ ++ " move%.w %3,%1 \n" \ ++ " swap %3 \n" \ ++ " swap %0 \n" \ ++ " mulu %2,%1 \n" \ ++ " mulu %3,%0 \n" \ ++ " mulu %2,%3 \n" \ ++ " swap %2 \n" \ ++ " mulu %5,%2 \n" \ ++ " add%.l %3,%2 \n" \ ++ " jcc 1f \n" \ ++ " add%.l %#0x10000,%0 \n" \ ++ "1: move%.l %2,%3 \n" \ ++ " clr%.w %2 \n" \ ++ " swap %2 \n" \ ++ " swap %3 \n" \ ++ " clr%.w %3 \n" \ ++ " add%.l %3,%1 \n" \ ++ " addx%.l %2,%0 \n" \ ++ " | End inlined umul_ppmm" \ ++ : "=&d" ((USItype)(xh)), "=&d" ((USItype)(xl)), \ ++ "=d" (__umul_tmp1), "=&d" (__umul_tmp2) \ ++ : "%2" ((USItype)(a)), "d" ((USItype)(b))); \ ++ } while (0) ++#define UMUL_TIME 100 ++#define UDIV_TIME 400 ++#endif /* not mc68020 */ ++#endif /* mc68000 */ ++ ++ ++/*************************************** ++ ************** 88000 **************** ++ ***************************************/ ++#if defined (__m88000__) && W_TYPE_SIZE == 32 ++#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("addu.co %1,%r4,%r5\n" \ ++ "addu.ci %0,%r2,%r3" \ ++ : "=r" ((USItype)(sh)), \ ++ "=&r" ((USItype)(sl)) \ ++ : "%rJ" ((USItype)(ah)), \ ++ "rJ" ((USItype)(bh)), \ ++ "%rJ" ((USItype)(al)), \ ++ "rJ" ((USItype)(bl))) ++#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("subu.co %1,%r4,%r5\n" \ ++ "subu.ci %0,%r2,%r3" \ ++ : "=r" ((USItype)(sh)), \ ++ "=&r" ((USItype)(sl)) \ ++ : "rJ" ((USItype)(ah)), \ ++ "rJ" ((USItype)(bh)), \ ++ "rJ" ((USItype)(al)), \ ++ "rJ" ((USItype)(bl))) ++#define count_leading_zeros(count, x) \ ++ do { \ ++ USItype __cbtmp; \ ++ __asm__ ("ff1 %0,%1" \ ++ : "=r" (__cbtmp) \ ++ : "r" ((USItype)(x))); \ ++ (count) = __cbtmp ^ 31; \ ++ } while (0) ++#define COUNT_LEADING_ZEROS_0 63 /* sic */ ++#if defined (__m88110__) ++#define umul_ppmm(wh, wl, u, v) \ ++ do { \ ++ union {UDItype __ll; \ ++ struct {USItype __h, __l;} __i; \ ++ } __x; \ ++ __asm__ ("mulu.d %0,%1,%2" : "=r" (__x.__ll) : "r" (u), "r" (v)); \ ++ (wh) = __x.__i.__h; \ ++ (wl) = __x.__i.__l; \ ++ } while (0) ++#define udiv_qrnnd(q, r, n1, n0, d) \ ++ ({union {UDItype __ll; \ ++ struct {USItype __h, __l;} __i; \ ++ } __x, __q; \ ++ __x.__i.__h = (n1); __x.__i.__l = (n0); \ ++ __asm__ ("divu.d %0,%1,%2" \ ++ : "=r" (__q.__ll) : "r" (__x.__ll), "r" (d)); \ ++ (r) = (n0) - __q.__l * (d); (q) = __q.__l; }) ++#define UMUL_TIME 5 ++#define UDIV_TIME 25 ++#else ++#define UMUL_TIME 17 ++#define UDIV_TIME 150 ++#endif /* __m88110__ */ ++#endif /* __m88000__ */ ++ ++/*************************************** ++ ************** MIPS ***************** ++ ***************************************/ ++#if defined (__mips__) && W_TYPE_SIZE == 32 ++#if (__GNUC__ >= 5) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) ++#define umul_ppmm(w1, w0, u, v) \ ++ do { \ ++ UDItype _r; \ ++ _r = (UDItype) u * v; \ ++ (w1) = _r >> 32; \ ++ (w0) = (USItype) _r; \ ++ } while (0) ++#elif __GNUC__ > 2 || __GNUC_MINOR__ >= 7 ++#define umul_ppmm(w1, w0, u, v) \ ++ __asm__ ("multu %2,%3" \ ++ : "=l" ((USItype)(w0)), \ ++ "=h" ((USItype)(w1)) \ ++ : "d" ((USItype)(u)), \ ++ "d" ((USItype)(v))) ++#else ++#define umul_ppmm(w1, w0, u, v) \ ++ __asm__ ("multu %2,%3 \n" \ ++ "mflo %0 \n" \ ++ "mfhi %1" \ ++ : "=d" ((USItype)(w0)), \ ++ "=d" ((USItype)(w1)) \ ++ : "d" ((USItype)(u)), \ ++ "d" ((USItype)(v))) ++#endif ++#define UMUL_TIME 10 ++#define UDIV_TIME 100 ++#endif /* __mips__ */ ++ ++/*************************************** ++ ************** MIPS/64 ************** ++ ***************************************/ ++#if (defined (__mips) && __mips >= 3) && W_TYPE_SIZE == 64 ++#if (__GNUC__ >= 5) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) ++typedef unsigned int UTItype __attribute__ ((mode (TI))); ++#define umul_ppmm(w1, w0, u, v) \ ++ do { \ ++ UTItype _r; \ ++ _r = (UTItype) u * v; \ ++ (w1) = _r >> 64; \ ++ (w0) = (UDItype) _r; \ ++ } while (0) ++#elif __GNUC__ > 2 || __GNUC_MINOR__ >= 7 ++#define umul_ppmm(w1, w0, u, v) \ ++ __asm__ ("dmultu %2,%3" \ ++ : "=l" ((UDItype)(w0)), \ ++ "=h" ((UDItype)(w1)) \ ++ : "d" ((UDItype)(u)), \ ++ "d" ((UDItype)(v))) ++#else ++#define umul_ppmm(w1, w0, u, v) \ ++ __asm__ ("dmultu %2,%3 \n" \ ++ "mflo %0 \n" \ ++ "mfhi %1" \ ++ : "=d" ((UDItype)(w0)), \ ++ "=d" ((UDItype)(w1)) \ ++ : "d" ((UDItype)(u)), \ ++ "d" ((UDItype)(v))) ++#endif ++#define UMUL_TIME 20 ++#define UDIV_TIME 140 ++#endif /* __mips__ */ ++ ++ ++/*************************************** ++ ************** 32000 **************** ++ ***************************************/ ++#if defined (__ns32000__) && W_TYPE_SIZE == 32 ++#define umul_ppmm(w1, w0, u, v) \ ++ ({union {UDItype __ll; \ ++ struct {USItype __l, __h;} __i; \ ++ } __xx; \ ++ __asm__ ("meid %2,%0" \ ++ : "=g" (__xx.__ll) \ ++ : "%0" ((USItype)(u)), \ ++ "g" ((USItype)(v))); \ ++ (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;}) ++#define __umulsidi3(u, v) \ ++ ({UDItype __w; \ ++ __asm__ ("meid %2,%0" \ ++ : "=g" (__w) \ ++ : "%0" ((USItype)(u)), \ ++ "g" ((USItype)(v))); \ ++ __w; }) ++#define udiv_qrnnd(q, r, n1, n0, d) \ ++ ({union {UDItype __ll; \ ++ struct {USItype __l, __h;} __i; \ ++ } __xx; \ ++ __xx.__i.__h = (n1); __xx.__i.__l = (n0); \ ++ __asm__ ("deid %2,%0" \ ++ : "=g" (__xx.__ll) \ ++ : "0" (__xx.__ll), \ ++ "g" ((USItype)(d))); \ ++ (r) = __xx.__i.__l; (q) = __xx.__i.__h; }) ++#define count_trailing_zeros(count,x) \ ++ do { ++ __asm__ ("ffsd %2,%0" \ ++ : "=r" ((USItype) (count)) \ ++ : "0" ((USItype) 0), \ ++ "r" ((USItype) (x))); \ ++ } while (0) ++#endif /* __ns32000__ */ ++ ++ ++/*************************************** ++ ************** PPC ****************** ++ ***************************************/ ++#if (defined (_ARCH_PPC) || defined (_IBMR2)) && W_TYPE_SIZE == 32 ++#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ ++ do { \ ++ if (__builtin_constant_p (bh) && (bh) == 0) \ ++ __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{aze|addze} %0,%2" \ ++ : "=r" ((USItype)(sh)), \ ++ "=&r" ((USItype)(sl)) \ ++ : "%r" ((USItype)(ah)), \ ++ "%r" ((USItype)(al)), \ ++ "rI" ((USItype)(bl))); \ ++ else if (__builtin_constant_p (bh) && (bh) ==~(USItype) 0) \ ++ __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{ame|addme} %0,%2" \ ++ : "=r" ((USItype)(sh)), \ ++ "=&r" ((USItype)(sl)) \ ++ : "%r" ((USItype)(ah)), \ ++ "%r" ((USItype)(al)), \ ++ "rI" ((USItype)(bl))); \ ++ else \ ++ __asm__ ("{a%I5|add%I5c} %1,%4,%5\n\t{ae|adde} %0,%2,%3" \ ++ : "=r" ((USItype)(sh)), \ ++ "=&r" ((USItype)(sl)) \ ++ : "%r" ((USItype)(ah)), \ ++ "r" ((USItype)(bh)), \ ++ "%r" ((USItype)(al)), \ ++ "rI" ((USItype)(bl))); \ ++ } while (0) ++#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ ++ do { \ ++ if (__builtin_constant_p (ah) && (ah) == 0) \ ++ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfze|subfze} %0,%2" \ ++ : "=r" ((USItype)(sh)), \ ++ "=&r" ((USItype)(sl)) \ ++ : "r" ((USItype)(bh)), \ ++ "rI" ((USItype)(al)), \ ++ "r" ((USItype)(bl))); \ ++ else if (__builtin_constant_p (ah) && (ah) ==~(USItype) 0) \ ++ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfme|subfme} %0,%2" \ ++ : "=r" ((USItype)(sh)), \ ++ "=&r" ((USItype)(sl)) \ ++ : "r" ((USItype)(bh)), \ ++ "rI" ((USItype)(al)), \ ++ "r" ((USItype)(bl))); \ ++ else if (__builtin_constant_p (bh) && (bh) == 0) \ ++ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{ame|addme} %0,%2" \ ++ : "=r" ((USItype)(sh)), \ ++ "=&r" ((USItype)(sl)) \ ++ : "r" ((USItype)(ah)), \ ++ "rI" ((USItype)(al)), \ ++ "r" ((USItype)(bl))); \ ++ else if (__builtin_constant_p (bh) && (bh) ==~(USItype) 0) \ ++ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{aze|addze} %0,%2" \ ++ : "=r" ((USItype)(sh)), \ ++ "=&r" ((USItype)(sl)) \ ++ : "r" ((USItype)(ah)), \ ++ "rI" ((USItype)(al)), \ ++ "r" ((USItype)(bl))); \ ++ else \ ++ __asm__ ("{sf%I4|subf%I4c} %1,%5,%4\n\t{sfe|subfe} %0,%3,%2" \ ++ : "=r" ((USItype)(sh)), \ ++ "=&r" ((USItype)(sl)) \ ++ : "r" ((USItype)(ah)), \ ++ "r" ((USItype)(bh)), \ ++ "rI" ((USItype)(al)), \ ++ "r" ((USItype)(bl))); \ ++ } while (0) ++#define count_leading_zeros(count, x) \ ++ __asm__ ("{cntlz|cntlzw} %0,%1" \ ++ : "=r" ((USItype)(count)) \ ++ : "r" ((USItype)(x))) ++#define COUNT_LEADING_ZEROS_0 32 ++#if defined (_ARCH_PPC) ++#define umul_ppmm(ph, pl, m0, m1) \ ++ do { \ ++ USItype __m0 = (m0), __m1 = (m1); \ ++ __asm__ ("mulhwu %0,%1,%2" \ ++ : "=r" ((USItype) ph) \ ++ : "%r" (__m0), \ ++ "r" (__m1)); \ ++ (pl) = __m0 * __m1; \ ++ } while (0) ++#define UMUL_TIME 15 ++#define smul_ppmm(ph, pl, m0, m1) \ ++ do { \ ++ SItype __m0 = (m0), __m1 = (m1); \ ++ __asm__ ("mulhw %0,%1,%2" \ ++ : "=r" ((SItype) ph) \ ++ : "%r" (__m0), \ ++ "r" (__m1)); \ ++ (pl) = __m0 * __m1; \ ++ } while (0) ++#define SMUL_TIME 14 ++#define UDIV_TIME 120 ++#else ++#define umul_ppmm(xh, xl, m0, m1) \ ++ do { \ ++ USItype __m0 = (m0), __m1 = (m1); \ ++ __asm__ ("mul %0,%2,%3" \ ++ : "=r" ((USItype)(xh)), \ ++ "=q" ((USItype)(xl)) \ ++ : "r" (__m0), \ ++ "r" (__m1)); \ ++ (xh) += ((((SItype) __m0 >> 31) & __m1) \ ++ + (((SItype) __m1 >> 31) & __m0)); \ ++ } while (0) ++#define UMUL_TIME 8 ++#define smul_ppmm(xh, xl, m0, m1) \ ++ __asm__ ("mul %0,%2,%3" \ ++ : "=r" ((SItype)(xh)), \ ++ "=q" ((SItype)(xl)) \ ++ : "r" (m0), \ ++ "r" (m1)) ++#define SMUL_TIME 4 ++#define sdiv_qrnnd(q, r, nh, nl, d) \ ++ __asm__ ("div %0,%2,%4" \ ++ : "=r" ((SItype)(q)), "=q" ((SItype)(r)) \ ++ : "r" ((SItype)(nh)), "1" ((SItype)(nl)), "r" ((SItype)(d))) ++#define UDIV_TIME 100 ++#endif ++#endif /* Power architecture variants. */ ++ ++/* Powerpc 64 bit support taken from gmp-4.1.2. */ ++/* We should test _IBMR2 here when we add assembly support for the system ++ vendor compilers. */ ++#if 0 /* Not yet enabled because we don't have hardware for a test. */ ++#if (defined (_ARCH_PPC) || defined (__powerpc__)) && W_TYPE_SIZE == 64 ++#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ ++ do { \ ++ if (__builtin_constant_p (bh) && (bh) == 0) \ ++ __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{aze|addze} %0,%2" \ ++ : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\ ++ else if (__builtin_constant_p (bh) && (bh) == ~(UDItype) 0) \ ++ __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{ame|addme} %0,%2" \ ++ : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\ ++ else \ ++ __asm__ ("{a%I5|add%I5c} %1,%4,%5\n\t{ae|adde} %0,%2,%3" \ ++ : "=r" (sh), "=&r" (sl) \ ++ : "%r" (ah), "r" (bh), "%r" (al), "rI" (bl)); \ ++ } while (0) ++#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ ++ do { \ ++ if (__builtin_constant_p (ah) && (ah) == 0) \ ++ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfze|subfze} %0,%2" \ ++ : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\ ++ else if (__builtin_constant_p (ah) && (ah) == ~(UDItype) 0) \ ++ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfme|subfme} %0,%2" \ ++ : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\ ++ else if (__builtin_constant_p (bh) && (bh) == 0) \ ++ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{ame|addme} %0,%2" \ ++ : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\ ++ else if (__builtin_constant_p (bh) && (bh) == ~(UDItype) 0) \ ++ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{aze|addze} %0,%2" \ ++ : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\ ++ else \ ++ __asm__ ("{sf%I4|subf%I4c} %1,%5,%4\n\t{sfe|subfe} %0,%3,%2" \ ++ : "=r" (sh), "=&r" (sl) \ ++ : "r" (ah), "r" (bh), "rI" (al), "r" (bl)); \ ++ } while (0) ++#define count_leading_zeros(count, x) \ ++ __asm__ ("cntlzd %0,%1" : "=r" (count) : "r" (x)) ++#define COUNT_LEADING_ZEROS_0 64 ++#define umul_ppmm(ph, pl, m0, m1) \ ++ do { \ ++ UDItype __m0 = (m0), __m1 = (m1); \ ++ __asm__ ("mulhdu %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \ ++ (pl) = __m0 * __m1; \ ++ } while (0) ++#define UMUL_TIME 15 ++#define smul_ppmm(ph, pl, m0, m1) \ ++ do { \ ++ DItype __m0 = (m0), __m1 = (m1); \ ++ __asm__ ("mulhd %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \ ++ (pl) = __m0 * __m1; \ ++ } while (0) ++#define SMUL_TIME 14 /* ??? */ ++#define UDIV_TIME 120 /* ??? */ ++#endif /* 64-bit PowerPC. */ ++#endif /* if 0 */ ++ ++/*************************************** ++ ************** PYR ****************** ++ ***************************************/ ++#if defined (__pyr__) && W_TYPE_SIZE == 32 ++#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("addw %5,%1 \n" \ ++ "addwc %3,%0" \ ++ : "=r" ((USItype)(sh)), \ ++ "=&r" ((USItype)(sl)) \ ++ : "%0" ((USItype)(ah)), \ ++ "g" ((USItype)(bh)), \ ++ "%1" ((USItype)(al)), \ ++ "g" ((USItype)(bl))) ++#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("subw %5,%1 \n" \ ++ "subwb %3,%0" \ ++ : "=r" ((USItype)(sh)), \ ++ "=&r" ((USItype)(sl)) \ ++ : "0" ((USItype)(ah)), \ ++ "g" ((USItype)(bh)), \ ++ "1" ((USItype)(al)), \ ++ "g" ((USItype)(bl))) ++/* This insn works on Pyramids with AP, XP, or MI CPUs, but not with SP. */ ++#define umul_ppmm(w1, w0, u, v) \ ++ ({union {UDItype __ll; \ ++ struct {USItype __h, __l;} __i; \ ++ } __xx; \ ++ __asm__ ("movw %1,%R0 \n" \ ++ "uemul %2,%0" \ ++ : "=&r" (__xx.__ll) \ ++ : "g" ((USItype) (u)), \ ++ "g" ((USItype)(v))); \ ++ (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;}) ++#endif /* __pyr__ */ ++ ++ ++/*************************************** ++ ************** RT/ROMP ************** ++ ***************************************/ ++#if defined (__ibm032__) /* RT/ROMP */ && W_TYPE_SIZE == 32 ++#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("a %1,%5 \n" \ ++ "ae %0,%3" \ ++ : "=r" ((USItype)(sh)), \ ++ "=&r" ((USItype)(sl)) \ ++ : "%0" ((USItype)(ah)), \ ++ "r" ((USItype)(bh)), \ ++ "%1" ((USItype)(al)), \ ++ "r" ((USItype)(bl))) ++#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("s %1,%5\n" \ ++ "se %0,%3" \ ++ : "=r" ((USItype)(sh)), \ ++ "=&r" ((USItype)(sl)) \ ++ : "0" ((USItype)(ah)), \ ++ "r" ((USItype)(bh)), \ ++ "1" ((USItype)(al)), \ ++ "r" ((USItype)(bl))) ++#define umul_ppmm(ph, pl, m0, m1) \ ++ do { \ ++ USItype __m0 = (m0), __m1 = (m1); \ ++ __asm__ ( \ ++ "s r2,r2 \n" \ ++ "mts r10,%2 \n" \ ++ "m r2,%3 \n" \ ++ "m r2,%3 \n" \ ++ "m r2,%3 \n" \ ++ "m r2,%3 \n" \ ++ "m r2,%3 \n" \ ++ "m r2,%3 \n" \ ++ "m r2,%3 \n" \ ++ "m r2,%3 \n" \ ++ "m r2,%3 \n" \ ++ "m r2,%3 \n" \ ++ "m r2,%3 \n" \ ++ "m r2,%3 \n" \ ++ "m r2,%3 \n" \ ++ "m r2,%3 \n" \ ++ "m r2,%3 \n" \ ++ "m r2,%3 \n" \ ++ "cas %0,r2,r0 \n" \ ++ "mfs r10,%1" \ ++ : "=r" ((USItype)(ph)), \ ++ "=r" ((USItype)(pl)) \ ++ : "%r" (__m0), \ ++ "r" (__m1) \ ++ : "r2"); \ ++ (ph) += ((((SItype) __m0 >> 31) & __m1) \ ++ + (((SItype) __m1 >> 31) & __m0)); \ ++ } while (0) ++#define UMUL_TIME 20 ++#define UDIV_TIME 200 ++#define count_leading_zeros(count, x) \ ++ do { \ ++ if ((x) >= 0x10000) \ ++ __asm__ ("clz %0,%1" \ ++ : "=r" ((USItype)(count)) \ ++ : "r" ((USItype)(x) >> 16)); \ ++ else \ ++ { \ ++ __asm__ ("clz %0,%1" \ ++ : "=r" ((USItype)(count)) \ ++ : "r" ((USItype)(x))); \ ++ (count) += 16; \ ++ } \ ++ } while (0) ++#endif /* RT/ROMP */ ++ ++ ++/*************************************** ++ ************** SH2 ****************** ++ ***************************************/ ++#if (defined (__sh2__) || defined(__sh3__) || defined(__SH4__) ) \ ++ && W_TYPE_SIZE == 32 ++#define umul_ppmm(w1, w0, u, v) \ ++ __asm__ ( \ ++ "dmulu.l %2,%3\n" \ ++ "sts macl,%1\n" \ ++ "sts mach,%0" \ ++ : "=r" ((USItype)(w1)), \ ++ "=r" ((USItype)(w0)) \ ++ : "r" ((USItype)(u)), \ ++ "r" ((USItype)(v)) \ ++ : "macl", "mach") ++#define UMUL_TIME 5 ++#endif ++ ++/*************************************** ++ ************** SPARC **************** ++ ***************************************/ ++#if defined (__sparc__) && W_TYPE_SIZE == 32 ++#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("addcc %r4,%5,%1\n" \ ++ "addx %r2,%3,%0" \ ++ : "=r" ((USItype)(sh)), \ ++ "=&r" ((USItype)(sl)) \ ++ : "%rJ" ((USItype)(ah)), \ ++ "rI" ((USItype)(bh)), \ ++ "%rJ" ((USItype)(al)), \ ++ "rI" ((USItype)(bl)) \ ++ __CLOBBER_CC) ++#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("subcc %r4,%5,%1\n" \ ++ "subx %r2,%3,%0" \ ++ : "=r" ((USItype)(sh)), \ ++ "=&r" ((USItype)(sl)) \ ++ : "rJ" ((USItype)(ah)), \ ++ "rI" ((USItype)(bh)), \ ++ "rJ" ((USItype)(al)), \ ++ "rI" ((USItype)(bl)) \ ++ __CLOBBER_CC) ++#if defined (__sparc_v8__) ++/* Don't match immediate range because, 1) it is not often useful, ++ 2) the 'I' flag thinks of the range as a 13 bit signed interval, ++ while we want to match a 13 bit interval, sign extended to 32 bits, ++ but INTERPRETED AS UNSIGNED. */ ++#define umul_ppmm(w1, w0, u, v) \ ++ __asm__ ("umul %2,%3,%1;rd %%y,%0" \ ++ : "=r" ((USItype)(w1)), \ ++ "=r" ((USItype)(w0)) \ ++ : "r" ((USItype)(u)), \ ++ "r" ((USItype)(v))) ++#define UMUL_TIME 5 ++#ifndef SUPERSPARC /* SuperSPARC's udiv only handles 53 bit dividends */ ++#define udiv_qrnnd(q, r, n1, n0, d) \ ++ do { \ ++ USItype __q; \ ++ __asm__ ("mov %1,%%y;nop;nop;nop;udiv %2,%3,%0" \ ++ : "=r" ((USItype)(__q)) \ ++ : "r" ((USItype)(n1)), \ ++ "r" ((USItype)(n0)), \ ++ "r" ((USItype)(d))); \ ++ (r) = (n0) - __q * (d); \ ++ (q) = __q; \ ++ } while (0) ++#define UDIV_TIME 25 ++#endif /* SUPERSPARC */ ++#else /* ! __sparc_v8__ */ ++#if defined (__sparclite__) ++/* This has hardware multiply but not divide. It also has two additional ++ instructions scan (ffs from high bit) and divscc. */ ++#define umul_ppmm(w1, w0, u, v) \ ++ __asm__ ("umul %2,%3,%1;rd %%y,%0" \ ++ : "=r" ((USItype)(w1)), \ ++ "=r" ((USItype)(w0)) \ ++ : "r" ((USItype)(u)), \ ++ "r" ((USItype)(v))) ++#define UMUL_TIME 5 ++#define udiv_qrnnd(q, r, n1, n0, d) \ ++ __asm__ ("! Inlined udiv_qrnnd \n" \ ++ " wr %%g0,%2,%%y ! Not a delayed write for sparclite \n" \ ++ " tst %%g0 \n" \ ++ " divscc %3,%4,%%g1 \n" \ ++ " divscc %%g1,%4,%%g1 \n" \ ++ " divscc %%g1,%4,%%g1 \n" \ ++ " divscc %%g1,%4,%%g1 \n" \ ++ " divscc %%g1,%4,%%g1 \n" \ ++ " divscc %%g1,%4,%%g1 \n" \ ++ " divscc %%g1,%4,%%g1 \n" \ ++ " divscc %%g1,%4,%%g1 \n" \ ++ " divscc %%g1,%4,%%g1 \n" \ ++ " divscc %%g1,%4,%%g1 \n" \ ++ " divscc %%g1,%4,%%g1 \n" \ ++ " divscc %%g1,%4,%%g1 \n" \ ++ " divscc %%g1,%4,%%g1 \n" \ ++ " divscc %%g1,%4,%%g1 \n" \ ++ " divscc %%g1,%4,%%g1 \n" \ ++ " divscc %%g1,%4,%%g1 \n" \ ++ " divscc %%g1,%4,%%g1 \n" \ ++ " divscc %%g1,%4,%%g1 \n" \ ++ " divscc %%g1,%4,%%g1 \n" \ ++ " divscc %%g1,%4,%%g1 \n" \ ++ " divscc %%g1,%4,%%g1 \n" \ ++ " divscc %%g1,%4,%%g1 \n" \ ++ " divscc %%g1,%4,%%g1 \n" \ ++ " divscc %%g1,%4,%%g1 \n" \ ++ " divscc %%g1,%4,%%g1 \n" \ ++ " divscc %%g1,%4,%%g1 \n" \ ++ " divscc %%g1,%4,%%g1 \n" \ ++ " divscc %%g1,%4,%%g1 \n" \ ++ " divscc %%g1,%4,%%g1 \n" \ ++ " divscc %%g1,%4,%%g1 \n" \ ++ " divscc %%g1,%4,%%g1 \n" \ ++ " divscc %%g1,%4,%0 \n" \ ++ " rd %%y,%1 \n" \ ++ " bl,a 1f \n" \ ++ " add %1,%4,%1 \n" \ ++ "1: ! End of inline udiv_qrnnd" \ ++ : "=r" ((USItype)(q)), \ ++ "=r" ((USItype)(r)) \ ++ : "r" ((USItype)(n1)), \ ++ "r" ((USItype)(n0)), \ ++ "rI" ((USItype)(d)) \ ++ : "%g1" __AND_CLOBBER_CC) ++#define UDIV_TIME 37 ++#define count_leading_zeros(count, x) \ ++ __asm__ ("scan %1,0,%0" \ ++ : "=r" ((USItype)(x)) \ ++ : "r" ((USItype)(count))) ++/* Early sparclites return 63 for an argument of 0, but they warn that future ++ implementations might change this. Therefore, leave COUNT_LEADING_ZEROS_0 ++ undefined. */ ++#endif /* __sparclite__ */ ++#endif /* __sparc_v8__ */ ++/* Default to sparc v7 versions of umul_ppmm and udiv_qrnnd. */ ++#ifndef umul_ppmm ++#define umul_ppmm(w1, w0, u, v) \ ++ __asm__ ("! Inlined umul_ppmm \n" \ ++ " wr %%g0,%2,%%y ! SPARC has 0-3 delay insn after a wr \n" \ ++ " sra %3,31,%%g2 ! Don't move this insn \n" \ ++ " and %2,%%g2,%%g2 ! Don't move this insn \n" \ ++ " andcc %%g0,0,%%g1 ! Don't move this insn \n" \ ++ " mulscc %%g1,%3,%%g1 \n" \ ++ " mulscc %%g1,%3,%%g1 \n" \ ++ " mulscc %%g1,%3,%%g1 \n" \ ++ " mulscc %%g1,%3,%%g1 \n" \ ++ " mulscc %%g1,%3,%%g1 \n" \ ++ " mulscc %%g1,%3,%%g1 \n" \ ++ " mulscc %%g1,%3,%%g1 \n" \ ++ " mulscc %%g1,%3,%%g1 \n" \ ++ " mulscc %%g1,%3,%%g1 \n" \ ++ " mulscc %%g1,%3,%%g1 \n" \ ++ " mulscc %%g1,%3,%%g1 \n" \ ++ " mulscc %%g1,%3,%%g1 \n" \ ++ " mulscc %%g1,%3,%%g1 \n" \ ++ " mulscc %%g1,%3,%%g1 \n" \ ++ " mulscc %%g1,%3,%%g1 \n" \ ++ " mulscc %%g1,%3,%%g1 \n" \ ++ " mulscc %%g1,%3,%%g1 \n" \ ++ " mulscc %%g1,%3,%%g1 \n" \ ++ " mulscc %%g1,%3,%%g1 \n" \ ++ " mulscc %%g1,%3,%%g1 \n" \ ++ " mulscc %%g1,%3,%%g1 \n" \ ++ " mulscc %%g1,%3,%%g1 \n" \ ++ " mulscc %%g1,%3,%%g1 \n" \ ++ " mulscc %%g1,%3,%%g1 \n" \ ++ " mulscc %%g1,%3,%%g1 \n" \ ++ " mulscc %%g1,%3,%%g1 \n" \ ++ " mulscc %%g1,%3,%%g1 \n" \ ++ " mulscc %%g1,%3,%%g1 \n" \ ++ " mulscc %%g1,%3,%%g1 \n" \ ++ " mulscc %%g1,%3,%%g1 \n" \ ++ " mulscc %%g1,%3,%%g1 \n" \ ++ " mulscc %%g1,%3,%%g1 \n" \ ++ " mulscc %%g1,0,%%g1 \n" \ ++ " add %%g1,%%g2,%0 \n" \ ++ " rd %%y,%1" \ ++ : "=r" ((USItype)(w1)), \ ++ "=r" ((USItype)(w0)) \ ++ : "%rI" ((USItype)(u)), \ ++ "r" ((USItype)(v)) \ ++ : "%g1", "%g2" __AND_CLOBBER_CC) ++#define UMUL_TIME 39 /* 39 instructions */ ++#endif ++#ifndef udiv_qrnnd ++#ifndef LONGLONG_STANDALONE ++#define udiv_qrnnd(q, r, n1, n0, d) \ ++ do { USItype __r; \ ++ (q) = __udiv_qrnnd (&__r, (n1), (n0), (d)); \ ++ (r) = __r; \ ++ } while (0) ++extern USItype __udiv_qrnnd (); ++#define UDIV_TIME 140 ++#endif /* LONGLONG_STANDALONE */ ++#endif /* udiv_qrnnd */ ++#endif /* __sparc__ */ ++ ++ ++/*************************************** ++ ************** VAX ****************** ++ ***************************************/ ++#if defined (__vax__) && W_TYPE_SIZE == 32 ++#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("addl2 %5,%1\n" \ ++ "adwc %3,%0" \ ++ : "=g" ((USItype)(sh)), \ ++ "=&g" ((USItype)(sl)) \ ++ : "%0" ((USItype)(ah)), \ ++ "g" ((USItype)(bh)), \ ++ "%1" ((USItype)(al)), \ ++ "g" ((USItype)(bl))) ++#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("subl2 %5,%1\n" \ ++ "sbwc %3,%0" \ ++ : "=g" ((USItype)(sh)), \ ++ "=&g" ((USItype)(sl)) \ ++ : "0" ((USItype)(ah)), \ ++ "g" ((USItype)(bh)), \ ++ "1" ((USItype)(al)), \ ++ "g" ((USItype)(bl))) ++#define umul_ppmm(xh, xl, m0, m1) \ ++ do { \ ++ union {UDItype __ll; \ ++ struct {USItype __l, __h;} __i; \ ++ } __xx; \ ++ USItype __m0 = (m0), __m1 = (m1); \ ++ __asm__ ("emul %1,%2,$0,%0" \ ++ : "=g" (__xx.__ll) \ ++ : "g" (__m0), \ ++ "g" (__m1)); \ ++ (xh) = __xx.__i.__h; (xl) = __xx.__i.__l; \ ++ (xh) += ((((SItype) __m0 >> 31) & __m1) \ ++ + (((SItype) __m1 >> 31) & __m0)); \ ++ } while (0) ++#define sdiv_qrnnd(q, r, n1, n0, d) \ ++ do { \ ++ union {DItype __ll; \ ++ struct {SItype __l, __h;} __i; \ ++ } __xx; \ ++ __xx.__i.__h = n1; __xx.__i.__l = n0; \ ++ __asm__ ("ediv %3,%2,%0,%1" \ ++ : "=g" (q), "=g" (r) \ ++ : "g" (__xx.__ll), "g" (d)); \ ++ } while (0) ++#endif /* __vax__ */ ++ ++ ++/*************************************** ++ ************** Z8000 **************** ++ ***************************************/ ++#if defined (__z8000__) && W_TYPE_SIZE == 16 ++#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("add %H1,%H5\n\tadc %H0,%H3" \ ++ : "=r" ((unsigned int)(sh)), \ ++ "=&r" ((unsigned int)(sl)) \ ++ : "%0" ((unsigned int)(ah)), \ ++ "r" ((unsigned int)(bh)), \ ++ "%1" ((unsigned int)(al)), \ ++ "rQR" ((unsigned int)(bl))) ++#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("sub %H1,%H5\n\tsbc %H0,%H3" \ ++ : "=r" ((unsigned int)(sh)), \ ++ "=&r" ((unsigned int)(sl)) \ ++ : "0" ((unsigned int)(ah)), \ ++ "r" ((unsigned int)(bh)), \ ++ "1" ((unsigned int)(al)), \ ++ "rQR" ((unsigned int)(bl))) ++#define umul_ppmm(xh, xl, m0, m1) \ ++ do { \ ++ union {long int __ll; \ ++ struct {unsigned int __h, __l;} __i; \ ++ } __xx; \ ++ unsigned int __m0 = (m0), __m1 = (m1); \ ++ __asm__ ("mult %S0,%H3" \ ++ : "=r" (__xx.__i.__h), \ ++ "=r" (__xx.__i.__l) \ ++ : "%1" (__m0), \ ++ "rQR" (__m1)); \ ++ (xh) = __xx.__i.__h; (xl) = __xx.__i.__l; \ ++ (xh) += ((((signed int) __m0 >> 15) & __m1) \ ++ + (((signed int) __m1 >> 15) & __m0)); \ ++ } while (0) ++#endif /* __z8000__ */ ++ ++#endif /* __GNUC__ */ ++#endif /* !__riscos__ */ ++ ++ ++/*************************************** ++ *********** Generic Versions ******** ++ ***************************************/ ++#if !defined (umul_ppmm) && defined (__umulsidi3) ++#define umul_ppmm(ph, pl, m0, m1) \ ++ { \ ++ UDWtype __ll = __umulsidi3 (m0, m1); \ ++ ph = (UWtype) (__ll >> W_TYPE_SIZE); \ ++ pl = (UWtype) __ll; \ ++ } ++#endif ++ ++#if !defined (__umulsidi3) ++#define __umulsidi3(u, v) \ ++ ({UWtype __hi, __lo; \ ++ umul_ppmm (__hi, __lo, u, v); \ ++ ((UDWtype) __hi << W_TYPE_SIZE) | __lo; }) ++#endif ++ ++/* If this machine has no inline assembler, use C macros. */ ++ ++#if !defined (add_ssaaaa) ++#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ ++ do { \ ++ UWtype __x; \ ++ __x = (al) + (bl); \ ++ (sh) = (ah) + (bh) + (__x < (al)); \ ++ (sl) = __x; \ ++ } while (0) ++#endif ++ ++#if !defined (sub_ddmmss) ++#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ ++ do { \ ++ UWtype __x; \ ++ __x = (al) - (bl); \ ++ (sh) = (ah) - (bh) - (__x > (al)); \ ++ (sl) = __x; \ ++ } while (0) ++#endif ++ ++#if !defined (umul_ppmm) ++#define umul_ppmm(w1, w0, u, v) \ ++ do { \ ++ UWtype __x0, __x1, __x2, __x3; \ ++ UHWtype __ul, __vl, __uh, __vh; \ ++ UWtype __u = (u), __v = (v); \ ++ \ ++ __ul = __ll_lowpart (__u); \ ++ __uh = __ll_highpart (__u); \ ++ __vl = __ll_lowpart (__v); \ ++ __vh = __ll_highpart (__v); \ ++ \ ++ __x0 = (UWtype) __ul * __vl; \ ++ __x1 = (UWtype) __ul * __vh; \ ++ __x2 = (UWtype) __uh * __vl; \ ++ __x3 = (UWtype) __uh * __vh; \ ++ \ ++ __x1 += __ll_highpart (__x0);/* this can't give carry */ \ ++ __x1 += __x2; /* but this indeed can */ \ ++ if (__x1 < __x2) /* did we get it? */ \ ++ __x3 += __ll_B; /* yes, add it in the proper pos. */ \ ++ \ ++ (w1) = __x3 + __ll_highpart (__x1); \ ++ (w0) = (__ll_lowpart (__x1) << W_TYPE_SIZE/2) + __ll_lowpart (__x0);\ ++ } while (0) ++#endif ++ ++#if !defined (umul_ppmm) ++#define smul_ppmm(w1, w0, u, v) \ ++ do { \ ++ UWtype __w1; \ ++ UWtype __m0 = (u), __m1 = (v); \ ++ umul_ppmm (__w1, w0, __m0, __m1); \ ++ (w1) = __w1 - (-(__m0 >> (W_TYPE_SIZE - 1)) & __m1) \ ++ - (-(__m1 >> (W_TYPE_SIZE - 1)) & __m0); \ ++ } while (0) ++#endif ++ ++/* Define this unconditionally, so it can be used for debugging. */ ++#define __udiv_qrnnd_c(q, r, n1, n0, d) \ ++ do { \ ++ UWtype __d1, __d0, __q1, __q0, __r1, __r0, __m; \ ++ __d1 = __ll_highpart (d); \ ++ __d0 = __ll_lowpart (d); \ ++ \ ++ __r1 = (n1) % __d1; \ ++ __q1 = (n1) / __d1; \ ++ __m = (UWtype) __q1 * __d0; \ ++ __r1 = __r1 * __ll_B | __ll_highpart (n0); \ ++ if (__r1 < __m) \ ++ { \ ++ __q1--, __r1 += (d); \ ++ if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\ ++ if (__r1 < __m) \ ++ __q1--, __r1 += (d); \ ++ } \ ++ __r1 -= __m; \ ++ \ ++ __r0 = __r1 % __d1; \ ++ __q0 = __r1 / __d1; \ ++ __m = (UWtype) __q0 * __d0; \ ++ __r0 = __r0 * __ll_B | __ll_lowpart (n0); \ ++ if (__r0 < __m) \ ++ { \ ++ __q0--, __r0 += (d); \ ++ if (__r0 >= (d)) \ ++ if (__r0 < __m) \ ++ __q0--, __r0 += (d); \ ++ } \ ++ __r0 -= __m; \ ++ \ ++ (q) = (UWtype) __q1 * __ll_B | __q0; \ ++ (r) = __r0; \ ++ } while (0) ++ ++/* If the processor has no udiv_qrnnd but sdiv_qrnnd, go through ++ __udiv_w_sdiv (defined in libgcc or elsewhere). */ ++#if !defined (udiv_qrnnd) && defined (sdiv_qrnnd) ++#define udiv_qrnnd(q, r, nh, nl, d) \ ++ do { \ ++ UWtype __r; \ ++ (q) = __MPN(udiv_w_sdiv) (&__r, nh, nl, d); \ ++ (r) = __r; \ ++ } while (0) ++#endif ++ ++/* If udiv_qrnnd was not defined for this processor, use __udiv_qrnnd_c. */ ++#if !defined (udiv_qrnnd) ++#define UDIV_NEEDS_NORMALIZATION 1 ++#define udiv_qrnnd __udiv_qrnnd_c ++#endif ++ ++#if !defined (count_leading_zeros) ++extern ++#ifdef __STDC__ ++const ++#endif ++unsigned char _gcry_clz_tab[]; ++#define MPI_INTERNAL_NEED_CLZ_TAB 1 ++#define count_leading_zeros(count, x) \ ++ do { \ ++ UWtype __xr = (x); \ ++ UWtype __a; \ ++ \ ++ if (W_TYPE_SIZE <= 32) \ ++ { \ ++ __a = __xr < ((UWtype) 1 << 2*__BITS4) \ ++ ? (__xr < ((UWtype) 1 << __BITS4) ? 0 : __BITS4) \ ++ : (__xr < ((UWtype) 1 << 3*__BITS4) ? 2*__BITS4 : 3*__BITS4);\ ++ } \ ++ else \ ++ { \ ++ for (__a = W_TYPE_SIZE - 8; __a > 0; __a -= 8) \ ++ if (((__xr >> __a) & 0xff) != 0) \ ++ break; \ ++ } \ ++ \ ++ (count) = W_TYPE_SIZE - (_gcry_clz_tab[__xr >> __a] + __a); \ ++ } while (0) ++/* This version gives a well-defined value for zero. */ ++#define COUNT_LEADING_ZEROS_0 W_TYPE_SIZE ++#endif ++ ++#if !defined (count_trailing_zeros) ++/* Define count_trailing_zeros using count_leading_zeros. The latter might be ++ defined in asm, but if it is not, the C version above is good enough. */ ++#define count_trailing_zeros(count, x) \ ++ do { \ ++ UWtype __ctz_x = (x); \ ++ UWtype __ctz_c; \ ++ count_leading_zeros (__ctz_c, __ctz_x & -__ctz_x); \ ++ (count) = W_TYPE_SIZE - 1 - __ctz_c; \ ++ } while (0) ++#endif ++ ++#ifndef UDIV_NEEDS_NORMALIZATION ++#define UDIV_NEEDS_NORMALIZATION 0 ++#endif +diff --git a/grub-core/lib/libgcrypt/mpi/m68k/Manifest b/grub-core/lib/libgcrypt/mpi/m68k/Manifest +new file mode 100644 +index 0000000..8e0538a +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/m68k/Manifest +@@ -0,0 +1,25 @@ ++# Manifest - checksums ++# Copyright 2003 Free Software Foundation, Inc. ++# ++# This file is part of Libgcrypt. ++# ++# Libgcrypt is free software; you can redistribute it and/or modify ++# it under the terms of the GNU Lesser general Public License as ++# published by the Free Software Foundation; either version 2.1 of ++# the License, or (at your option) any later version. ++# ++# Libgcrypt 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 Lesser General Public License for more details. ++# ++# You should have received a copy of the GNU Lesser General Public ++# License along with this program; if not, write to the Free Software ++# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ ++syntax.h ++mpih-lshift.S ++mpih-rshift.S ++mpih-add1.S ++mpih-sub1.S ++$names$ iQCVAwUAP+LmTDEAnp832S/7AQJHUAP/dxfq2U0pDc5ZLoEizoqgjjcnHIyb9EjMG3YjvgK6jQ62yoAOCuo/jFYlJS+Mdve6bgfdTzYMrnKV7BG2SEcwb263pVnIntS7ZhKQPiMCbFgXWR2VjN3+a1v8yjQDZtgqEgm8OlQ+u7jKBY13Oryiuq5nPNxsXZqJpelG6Zkdg9M==PIee +diff --git a/grub-core/lib/libgcrypt/mpi/m68k/distfiles b/grub-core/lib/libgcrypt/mpi/m68k/distfiles +new file mode 100644 +index 0000000..1e2e36f +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/m68k/distfiles +@@ -0,0 +1,9 @@ ++Manifest ++syntax.h ++mpih-lshift.S ++mpih-rshift.S ++mpih-add1.S ++mpih-sub1.S ++ ++ ++ +diff --git a/grub-core/lib/libgcrypt/mpi/m68k/mc68020/Manifest b/grub-core/lib/libgcrypt/mpi/m68k/mc68020/Manifest +new file mode 100644 +index 0000000..bcb2768 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/m68k/mc68020/Manifest +@@ -0,0 +1,23 @@ ++# Manifest - checksums ++# Copyright 2003 Free Software Foundation, Inc. ++# ++# This file is part of Libgcrypt. ++# ++# Libgcrypt is free software; you can redistribute it and/or modify ++# it under the terms of the GNU Lesser general Public License as ++# published by the Free Software Foundation; either version 2.1 of ++# the License, or (at your option) any later version. ++# ++# Libgcrypt 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 Lesser General Public License for more details. ++# ++# You should have received a copy of the GNU Lesser General Public ++# License along with this program; if not, write to the Free Software ++# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ ++mpih-mul1.S ++mpih-mul2.S ++mpih-mul3.S ++$names$ iQCVAwUAP+LmRTEAnp832S/7AQK3rwP/TyGBbii5HCrjDiLCVJHiDNeOdENx6AicRXnu4vuJmMmPZ0y+i7MPusDaeTbIUA0w6RaJx+Ep41nIvthmNDnFePY5Mw0pIUJcpI7AJR4vYqpwNQA6nlEdn/m1jg6sPLKZXUXNUkhroEzcHzoU+12BPS+nvSXlwSksg6rXEGOJ+Ms==XCXP +diff --git a/grub-core/lib/libgcrypt/mpi/m68k/mc68020/distfiles b/grub-core/lib/libgcrypt/mpi/m68k/mc68020/distfiles +new file mode 100644 +index 0000000..6b96433 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/m68k/mc68020/distfiles +@@ -0,0 +1,4 @@ ++Manifest ++mpih-mul1.S ++mpih-mul2.S ++mpih-mul3.S +diff --git a/grub-core/lib/libgcrypt/mpi/m68k/mc68020/mpih-mul1.S b/grub-core/lib/libgcrypt/mpi/m68k/mc68020/mpih-mul1.S +new file mode 100644 +index 0000000..007c94c +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/m68k/mc68020/mpih-mul1.S +@@ -0,0 +1,104 @@ ++/* mc68020 __mpn_mul_1 -- Multiply a limb vector with a limb and store ++ * the result in a second limb vector. ++ * ++ * Copyright (C) 1992, 1994, 1996, 1998, ++ * 2001, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ * ++ * Note: This code is heavily based on the GNU MP Library. ++ * Actually it's the same code with only minor changes in the ++ * way the data is stored; this is to support the abstraction ++ * of an optional secure memory allocation which may be used ++ * to avoid revealing of sensitive data due to paging etc. ++ */ ++ ++ ++ ++#include "sysdep.h" ++#include "asm-syntax.h" ++ ++ ++/******************* ++ * mpi_limb_t ++ * _gcry_mpih_mul_1( mpi_ptr_t res_ptr, (sp + 4) ++ * mpi_ptr_t s1_ptr, (sp + 8) ++ * mpi_size_t s1_size, (sp + 12) ++ * mpi_limb_t s2_limb) (sp + 16) ++ */ ++ ++ ++ TEXT ++ ALIGN ++ GLOBL C_SYMBOL_NAME(_gcry_mpih_mul_1) ++ ++C_SYMBOL_NAME(_gcry_mpih_mul_1:) ++PROLOG(_gcry_mpih_mul_1) ++ ++#define res_ptr a0 ++#define s1_ptr a1 ++#define s1_size d2 ++#define s2_limb d4 ++ ++/* Save used registers on the stack. */ ++ moveml R(d2)-R(d4),MEM_PREDEC(sp) ++#if 0 ++ movel R(d2),MEM_PREDEC(sp) ++ movel R(d3),MEM_PREDEC(sp) ++ movel R(d4),MEM_PREDEC(sp) ++#endif ++ ++/* Copy the arguments to registers. Better use movem? */ ++ movel MEM_DISP(sp,16),R(res_ptr) ++ movel MEM_DISP(sp,20),R(s1_ptr) ++ movel MEM_DISP(sp,24),R(s1_size) ++ movel MEM_DISP(sp,28),R(s2_limb) ++ ++ eorw #1,R(s1_size) ++ clrl R(d1) ++ lsrl #1,R(s1_size) ++ bcc L(L1) ++ subql #1,R(s1_size) ++ subl R(d0),R(d0) /* (d0,cy) <= (0,0) */ ++ ++L(Loop:) ++ movel MEM_POSTINC(s1_ptr),R(d3) ++ mulul R(s2_limb),R(d1):R(d3) ++ addxl R(d0),R(d3) ++ movel R(d3),MEM_POSTINC(res_ptr) ++L(L1:) movel MEM_POSTINC(s1_ptr),R(d3) ++ mulul R(s2_limb),R(d0):R(d3) ++ addxl R(d1),R(d3) ++ movel R(d3),MEM_POSTINC(res_ptr) ++ ++ dbf R(s1_size),L(Loop) ++ clrl R(d3) ++ addxl R(d3),R(d0) ++ subl #0x10000,R(s1_size) ++ bcc L(Loop) ++ ++/* Restore used registers from stack frame. */ ++ moveml MEM_POSTINC(sp),R(d2)-R(d4) ++#if 0 ++ movel MEM_POSTINC(sp),R(d4) ++ movel MEM_POSTINC(sp),R(d3) ++ movel MEM_POSTINC(sp),R(d2) ++#endif ++ rts ++EPILOG(_gcry_mpih_mul_1) ++ ++ +diff --git a/grub-core/lib/libgcrypt/mpi/m68k/mc68020/mpih-mul2.S b/grub-core/lib/libgcrypt/mpi/m68k/mc68020/mpih-mul2.S +new file mode 100644 +index 0000000..44baa8d +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/m68k/mc68020/mpih-mul2.S +@@ -0,0 +1,94 @@ ++/* mc68020 __mpn_addmul_1 -- Multiply a limb vector with a limb and add ++ * the result to a second limb vector. ++ * ++ * Copyright (C) 1992, 1994, 1996, 1998, ++ * 2001, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ * ++ * Note: This code is heavily based on the GNU MP Library. ++ * Actually it's the same code with only minor changes in the ++ * way the data is stored; this is to support the abstraction ++ * of an optional secure memory allocation which may be used ++ * to avoid revealing of sensitive data due to paging etc. ++ */ ++ ++ ++#include "sysdep.h" ++#include "asm-syntax.h" ++ ++/******************* ++ * mpi_limb_t ++ * _gcry_mpih_addmul_1( mpi_ptr_t res_ptr, (sp + 4) ++ * mpi_ptr_t s1_ptr, (sp + 8) ++ * mpi_size_t s1_size, (sp + 12) ++ * mpi_limb_t s2_limb) (sp + 16) ++ */ ++ ++ ++ TEXT ++ ALIGN ++ GLOBL C_SYMBOL_NAME(_gcry_mpih_addmul_1) ++ ++C_SYMBOL_NAME(_gcry_mpih_addmul_1:) ++PROLOG(_gcry_mpih_addmul_1) ++ ++#define res_ptr a0 ++#define s1_ptr a1 ++#define s1_size d2 ++#define s2_limb d4 ++ ++/* Save used registers on the stack. */ ++ moveml R(d2)-R(d5),MEM_PREDEC(sp) ++ ++/* Copy the arguments to registers. Better use movem? */ ++ movel MEM_DISP(sp,20),R(res_ptr) ++ movel MEM_DISP(sp,24),R(s1_ptr) ++ movel MEM_DISP(sp,28),R(s1_size) ++ movel MEM_DISP(sp,32),R(s2_limb) ++ ++ eorw #1,R(s1_size) ++ clrl R(d1) ++ clrl R(d5) ++ lsrl #1,R(s1_size) ++ bcc L(L1) ++ subql #1,R(s1_size) ++ subl R(d0),R(d0) /* (d0,cy) <= (0,0) */ ++ ++L(Loop:) ++ movel MEM_POSTINC(s1_ptr),R(d3) ++ mulul R(s2_limb),R(d1):R(d3) ++ addxl R(d0),R(d3) ++ addxl R(d5),R(d1) ++ addl R(d3),MEM_POSTINC(res_ptr) ++L(L1:) movel MEM_POSTINC(s1_ptr),R(d3) ++ mulul R(s2_limb),R(d0):R(d3) ++ addxl R(d1),R(d3) ++ addxl R(d5),R(d0) ++ addl R(d3),MEM_POSTINC(res_ptr) ++ ++ dbf R(s1_size),L(Loop) ++ addxl R(d5),R(d0) ++ subl #0x10000,R(s1_size) ++ bcc L(Loop) ++ ++/* Restore used registers from stack frame. */ ++ moveml MEM_POSTINC(sp),R(d2)-R(d5) ++ ++ rts ++EPILOG(_gcry_mpih_addmul_1) ++ +diff --git a/grub-core/lib/libgcrypt/mpi/m68k/mc68020/mpih-mul3.S b/grub-core/lib/libgcrypt/mpi/m68k/mc68020/mpih-mul3.S +new file mode 100644 +index 0000000..e958ef6 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/m68k/mc68020/mpih-mul3.S +@@ -0,0 +1,97 @@ ++/* mc68020 __mpn_submul_1 -- Multiply a limb vector with a limb and subtract ++ * the result from a second limb vector. ++ * ++ * Copyright (C) 1992, 1994, 1996, 1998, ++ * 2001, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ * ++ * Note: This code is heavily based on the GNU MP Library. ++ * Actually it's the same code with only minor changes in the ++ * way the data is stored; this is to support the abstraction ++ * of an optional secure memory allocation which may be used ++ * to avoid revealing of sensitive data due to paging etc. ++ */ ++ ++ ++ ++ ++#include "sysdep.h" ++#include "asm-syntax.h" ++ ++/******************* ++ * mpi_limb_t ++ * _gcry_mpih_submul_1( mpi_ptr_t res_ptr, (sp + 4) ++ * mpi_ptr_t s1_ptr, (sp + 8) ++ * mpi_size_t s1_size, (sp + 12) ++ * mpi_limb_t s2_limb) (sp + 16) ++ */ ++ ++ ++ TEXT ++ ALIGN ++ GLOBL C_SYMBOL_NAME(_gcry_mpih_submul_1) ++ ++C_SYMBOL_NAME(_gcry_mpih_submul_1:) ++PROLOG(_gcry_mpih_submul_1) ++ ++#define res_ptr a0 ++#define s1_ptr a1 ++#define s1_size d2 ++#define s2_limb d4 ++ ++/* Save used registers on the stack. */ ++ moveml R(d2)-R(d5),MEM_PREDEC(sp) ++ ++/* Copy the arguments to registers. Better use movem? */ ++ movel MEM_DISP(sp,20),R(res_ptr) ++ movel MEM_DISP(sp,24),R(s1_ptr) ++ movel MEM_DISP(sp,28),R(s1_size) ++ movel MEM_DISP(sp,32),R(s2_limb) ++ ++ eorw #1,R(s1_size) ++ clrl R(d1) ++ clrl R(d5) ++ lsrl #1,R(s1_size) ++ bcc L(L1) ++ subql #1,R(s1_size) ++ subl R(d0),R(d0) /* (d0,cy) <= (0,0) */ ++ ++L(Loop:) ++ movel MEM_POSTINC(s1_ptr),R(d3) ++ mulul R(s2_limb),R(d1):R(d3) ++ addxl R(d0),R(d3) ++ addxl R(d5),R(d1) ++ subl R(d3),MEM_POSTINC(res_ptr) ++L(L1:) movel MEM_POSTINC(s1_ptr),R(d3) ++ mulul R(s2_limb),R(d0):R(d3) ++ addxl R(d1),R(d3) ++ addxl R(d5),R(d0) ++ subl R(d3),MEM_POSTINC(res_ptr) ++ ++ dbf R(s1_size),L(Loop) ++ addxl R(d5),R(d0) ++ subl #0x10000,R(s1_size) ++ bcc L(Loop) ++ ++/* Restore used registers from stack frame. */ ++ moveml MEM_POSTINC(sp),R(d2)-R(d5) ++ ++ rts ++EPILOG(_gcry_mpih_submul_1) ++ ++ +diff --git a/grub-core/lib/libgcrypt/mpi/m68k/mpih-add1.S b/grub-core/lib/libgcrypt/mpi/m68k/mpih-add1.S +new file mode 100644 +index 0000000..8182d21 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/m68k/mpih-add1.S +@@ -0,0 +1,92 @@ ++/* mc68020 __mpn_add_n -- Add two limb vectors of the same length > 0 and store ++ * sum in a third limb vector. ++ * ++ * Copyright (C) 1992, 1994,1996, 1998, ++ * 2001, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ * ++ * Note: This code is heavily based on the GNU MP Library. ++ * Actually it's the same code with only minor changes in the ++ * way the data is stored; this is to support the abstraction ++ * of an optional secure memory allocation which may be used ++ * to avoid revealing of sensitive data due to paging etc. ++ */ ++ ++ ++#include "sysdep.h" ++#include "asm-syntax.h" ++ ++ ++/******************* ++ * mpi_limb_t ++ * _gcry_mpih_add_n( mpi_ptr_t res_ptr, (sp + 4) ++ * mpi_ptr_t s1_ptr, (sp + 8) ++ * mpi_ptr_t s2_ptr, (sp + 16) ++ * mpi_size_t size) (sp + 12) ++ */ ++ ++ ++ TEXT ++ ALIGN ++ GLOBL C_SYMBOL_NAME(_gcry_mpih_add_n) ++ ++C_SYMBOL_NAME(_gcry_mpih_add_n:) ++PROLOG(_gcry_mpih_add_n) ++ /* Save used registers on the stack. */ ++ movel R(d2),MEM_PREDEC(sp) ++ movel R(a2),MEM_PREDEC(sp) ++ ++ /* Copy the arguments to registers. Better use movem? */ ++ movel MEM_DISP(sp,12),R(a2) ++ movel MEM_DISP(sp,16),R(a0) ++ movel MEM_DISP(sp,20),R(a1) ++ movel MEM_DISP(sp,24),R(d2) ++ ++ eorw #1,R(d2) ++ lsrl #1,R(d2) ++ bcc L(L1) ++ subql #1,R(d2) /* clears cy as side effect */ ++ ++L(Loop:) ++ movel MEM_POSTINC(a0),R(d0) ++ movel MEM_POSTINC(a1),R(d1) ++ addxl R(d1),R(d0) ++ movel R(d0),MEM_POSTINC(a2) ++L(L1:) movel MEM_POSTINC(a0),R(d0) ++ movel MEM_POSTINC(a1),R(d1) ++ addxl R(d1),R(d0) ++ movel R(d0),MEM_POSTINC(a2) ++ ++ dbf R(d2),L(Loop) /* loop until 16 lsb of %4 == -1 */ ++ subxl R(d0),R(d0) /* d0 <= -cy; save cy as 0 or -1 in d0 */ ++ subl #0x10000,R(d2) ++ bcs L(L2) ++ addl R(d0),R(d0) /* restore cy */ ++ bra L(Loop) ++ ++L(L2:) ++ negl R(d0) ++ ++ /* Restore used registers from stack frame. */ ++ movel MEM_POSTINC(sp),R(a2) ++ movel MEM_POSTINC(sp),R(d2) ++ ++ rts ++EPILOG(_gcry_mpih_add_n) ++ ++ +diff --git a/grub-core/lib/libgcrypt/mpi/m68k/mpih-lshift.S b/grub-core/lib/libgcrypt/mpi/m68k/mpih-lshift.S +new file mode 100644 +index 0000000..133d1aa +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/m68k/mpih-lshift.S +@@ -0,0 +1,164 @@ ++/* mc68020 lshift -- Shift left a low-level natural-number integer. ++ * ++ * Copyright (C) 1996, 1998, 2001, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ * ++ * Note: This code is heavily based on the GNU MP Library. ++ * Actually it's the same code with only minor changes in the ++ * way the data is stored; this is to support the abstraction ++ * of an optional secure memory allocation which may be used ++ * to avoid revealing of sensitive data due to paging etc. ++ */ ++ ++ ++#include "sysdep.h" ++#include "asm-syntax.h" ++ ++ ++/******************* ++ * mpi_limb_t ++ * _gcry_mpih_lshift( mpi_ptr_t wp, (sp + 4) ++ * mpi_ptr_t up, (sp + 8) ++ * mpi_size_t usize, (sp + 12) ++ * unsigned cnt) (sp + 16) ++ */ ++ ++#define res_ptr a1 ++#define s_ptr a0 ++#define s_size d6 ++#define cnt d4 ++ ++ TEXT ++ ALIGN ++ GLOBL C_SYMBOL_NAME(_gcry_mpih_lshift) ++ ++C_SYMBOL_NAME(_gcry_mpih_lshift:) ++PROLOG(_gcry_mpih_lshift) ++ ++ /* Save used registers on the stack. */ ++ moveml R(d2)-R(d6)/R(a2),MEM_PREDEC(sp) ++ ++ /* Copy the arguments to registers. */ ++ movel MEM_DISP(sp,28),R(res_ptr) ++ movel MEM_DISP(sp,32),R(s_ptr) ++ movel MEM_DISP(sp,36),R(s_size) ++ movel MEM_DISP(sp,40),R(cnt) ++ ++ moveql #1,R(d5) ++ cmpl R(d5),R(cnt) ++ bne L(Lnormal) ++ cmpl R(s_ptr),R(res_ptr) ++ bls L(Lspecial) /* jump if s_ptr >= res_ptr */ ++#if (defined (__mc68020__) || defined (__NeXT__) || defined(mc68020)) ++ lea MEM_INDX1(s_ptr,s_size,l,4),R(a2) ++#else /* not mc68020 */ ++ movel R(s_size),R(d0) ++ asll #2,R(d0) ++ lea MEM_INDX(s_ptr,d0,l),R(a2) ++#endif ++ cmpl R(res_ptr),R(a2) ++ bls L(Lspecial) /* jump if res_ptr >= s_ptr + s_size */ ++ ++L(Lnormal:) ++ moveql #32,R(d5) ++ subl R(cnt),R(d5) ++ ++#if (defined (__mc68020__) || defined (__NeXT__) || defined(mc68020)) ++ lea MEM_INDX1(s_ptr,s_size,l,4),R(s_ptr) ++ lea MEM_INDX1(res_ptr,s_size,l,4),R(res_ptr) ++#else /* not mc68000 */ ++ movel R(s_size),R(d0) ++ asll #2,R(d0) ++ addl R(s_size),R(s_ptr) ++ addl R(s_size),R(res_ptr) ++#endif ++ movel MEM_PREDEC(s_ptr),R(d2) ++ movel R(d2),R(d0) ++ lsrl R(d5),R(d0) /* compute carry limb */ ++ ++ lsll R(cnt),R(d2) ++ movel R(d2),R(d1) ++ subql #1,R(s_size) ++ beq L(Lend) ++ lsrl #1,R(s_size) ++ bcs L(L1) ++ subql #1,R(s_size) ++ ++L(Loop:) ++ movel MEM_PREDEC(s_ptr),R(d2) ++ movel R(d2),R(d3) ++ lsrl R(d5),R(d3) ++ orl R(d3),R(d1) ++ movel R(d1),MEM_PREDEC(res_ptr) ++ lsll R(cnt),R(d2) ++L(L1:) ++ movel MEM_PREDEC(s_ptr),R(d1) ++ movel R(d1),R(d3) ++ lsrl R(d5),R(d3) ++ orl R(d3),R(d2) ++ movel R(d2),MEM_PREDEC(res_ptr) ++ lsll R(cnt),R(d1) ++ ++ dbf R(s_size),L(Loop) ++ subl #0x10000,R(s_size) ++ bcc L(Loop) ++ ++L(Lend:) ++ movel R(d1),MEM_PREDEC(res_ptr) /* store least significant limb */ ++ ++/* Restore used registers from stack frame. */ ++ moveml MEM_POSTINC(sp),R(d2)-R(d6)/R(a2) ++ rts ++ ++/* We loop from least significant end of the arrays, which is only ++ permissable if the source and destination don't overlap, since the ++ function is documented to work for overlapping source and destination. */ ++ ++L(Lspecial:) ++ clrl R(d0) /* initialize carry */ ++ eorw #1,R(s_size) ++ lsrl #1,R(s_size) ++ bcc L(LL1) ++ subql #1,R(s_size) ++ ++L(LLoop:) ++ movel MEM_POSTINC(s_ptr),R(d2) ++ addxl R(d2),R(d2) ++ movel R(d2),MEM_POSTINC(res_ptr) ++L(LL1:) ++ movel MEM_POSTINC(s_ptr),R(d2) ++ addxl R(d2),R(d2) ++ movel R(d2),MEM_POSTINC(res_ptr) ++ ++ dbf R(s_size),L(LLoop) ++ addxl R(d0),R(d0) /* save cy in lsb */ ++ subl #0x10000,R(s_size) ++ bcs L(LLend) ++ lsrl #1,R(d0) /* restore cy */ ++ bra L(LLoop) ++ ++L(LLend:) ++/* Restore used registers from stack frame. */ ++ moveml MEM_POSTINC(sp),R(d2)-R(d6)/R(a2) ++ rts ++EPILOG(_gcry_mpih_lshift) ++ ++ ++ ++ ++ +diff --git a/grub-core/lib/libgcrypt/mpi/m68k/mpih-rshift.S b/grub-core/lib/libgcrypt/mpi/m68k/mpih-rshift.S +new file mode 100644 +index 0000000..be9f435 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/m68k/mpih-rshift.S +@@ -0,0 +1,162 @@ ++/* mc68020 rshift -- Shift right a low-level natural-number integer. ++ * ++ * Copyright (C) 1996, 1998, 2001, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ * ++ * Note: This code is heavily based on the GNU MP Library. ++ * Actually it's the same code with only minor changes in the ++ * way the data is stored; this is to support the abstraction ++ * of an optional secure memory allocation which may be used ++ * to avoid revealing of sensitive data due to paging etc. ++ */ ++ ++ ++#include "sysdep.h" ++#include "asm-syntax.h" ++ ++ ++/******************* ++ * mpi_limb_t ++ * _gcry_mpih_rshift( mpi_ptr_t wp, (sp + 4) ++ * mpi_ptr_t up, (sp + 8) ++ * mpi_size_t usize, (sp + 12) ++ * unsigned cnt) (sp + 16) ++ */ ++ ++#define res_ptr a1 ++#define s_ptr a0 ++#define s_size d6 ++#define cnt d4 ++ ++ TEXT ++ ALIGN ++ GLOBL C_SYMBOL_NAME(_gcry_mpih_rshift) ++ ++C_SYMBOL_NAME(_gcry_mpih_rshift:) ++PROLOG(_gcry_mpih_rshift) ++ /* Save used registers on the stack. */ ++ moveml R(d2)-R(d6)/R(a2),MEM_PREDEC(sp) ++ ++ /* Copy the arguments to registers. */ ++ movel MEM_DISP(sp,28),R(res_ptr) ++ movel MEM_DISP(sp,32),R(s_ptr) ++ movel MEM_DISP(sp,36),R(s_size) ++ movel MEM_DISP(sp,40),R(cnt) ++ ++ moveql #1,R(d5) ++ cmpl R(d5),R(cnt) ++ bne L(Rnormal) ++ cmpl R(res_ptr),R(s_ptr) ++ bls L(Rspecial) /* jump if res_ptr >= s_ptr */ ++#if (defined (__mc68020__) || defined (__NeXT__) || defined(mc68020)) ++ lea MEM_INDX1(res_ptr,s_size,l,4),R(a2) ++#else /* not mc68020 */ ++ movel R(s_size),R(d0) ++ asll #2,R(d0) ++ lea MEM_INDX(res_ptr,d0,l),R(a2) ++#endif ++ cmpl R(s_ptr),R(a2) ++ bls L(Rspecial) /* jump if s_ptr >= res_ptr + s_size */ ++ ++L(Rnormal:) ++ moveql #32,R(d5) ++ subl R(cnt),R(d5) ++ movel MEM_POSTINC(s_ptr),R(d2) ++ movel R(d2),R(d0) ++ lsll R(d5),R(d0) /* compute carry limb */ ++ ++ lsrl R(cnt),R(d2) ++ movel R(d2),R(d1) ++ subql #1,R(s_size) ++ beq L(Rend) ++ lsrl #1,R(s_size) ++ bcs L(R1) ++ subql #1,R(s_size) ++ ++L(Roop:) ++ movel MEM_POSTINC(s_ptr),R(d2) ++ movel R(d2),R(d3) ++ lsll R(d5),R(d3) ++ orl R(d3),R(d1) ++ movel R(d1),MEM_POSTINC(res_ptr) ++ lsrl R(cnt),R(d2) ++L(R1:) ++ movel MEM_POSTINC(s_ptr),R(d1) ++ movel R(d1),R(d3) ++ lsll R(d5),R(d3) ++ orl R(d3),R(d2) ++ movel R(d2),MEM_POSTINC(res_ptr) ++ lsrl R(cnt),R(d1) ++ ++ dbf R(s_size),L(Roop) ++ subl #0x10000,R(s_size) ++ bcc L(Roop) ++ ++L(Rend:) ++ movel R(d1),MEM(res_ptr) /* store most significant limb */ ++ ++/* Restore used registers from stack frame. */ ++ moveml MEM_POSTINC(sp),R(d2)-R(d6)/R(a2) ++ rts ++ ++/* We loop from most significant end of the arrays, which is only ++ permissable if the source and destination don't overlap, since the ++ function is documented to work for overlapping source and destination. */ ++ ++L(Rspecial:) ++#if (defined (__mc68020__) || defined (__NeXT__) || defined(mc68020)) ++ lea MEM_INDX1(s_ptr,s_size,l,4),R(s_ptr) ++ lea MEM_INDX1(res_ptr,s_size,l,4),R(res_ptr) ++#else /* not mc68000 */ ++ movel R(s_size),R(d0) ++ asll #2,R(d0) ++ addl R(s_size),R(s_ptr) ++ addl R(s_size),R(res_ptr) ++#endif ++ ++ clrl R(d0) /* initialize carry */ ++ eorw #1,R(s_size) ++ lsrl #1,R(s_size) ++ bcc L(LR1) ++ subql #1,R(s_size) ++ ++L(LRoop:) ++ movel MEM_PREDEC(s_ptr),R(d2) ++ roxrl #1,R(d2) ++ movel R(d2),MEM_PREDEC(res_ptr) ++L(LR1:) ++ movel MEM_PREDEC(s_ptr),R(d2) ++ roxrl #1,R(d2) ++ movel R(d2),MEM_PREDEC(res_ptr) ++ ++ dbf R(s_size),L(LRoop) ++ roxrl #1,R(d0) /* save cy in msb */ ++ subl #0x10000,R(s_size) ++ bcs L(LRend) ++ addl R(d0),R(d0) /* restore cy */ ++ bra L(LRoop) ++ ++L(LRend:) ++/* Restore used registers from stack frame. */ ++ moveml MEM_POSTINC(sp),R(d2)-R(d6)/R(a2) ++ rts ++EPILOG(_gcry_mpih_rshift) ++ ++ ++ ++ +diff --git a/grub-core/lib/libgcrypt/mpi/m68k/mpih-sub1.S b/grub-core/lib/libgcrypt/mpi/m68k/mpih-sub1.S +new file mode 100644 +index 0000000..ee7555f +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/m68k/mpih-sub1.S +@@ -0,0 +1,91 @@ ++/* mc68020 __mpn_sub_n -- Subtract two limb vectors of the same length > 0 and ++ * store difference in a third limb vector. ++ * ++ * Copyright (C) 1992, 1994, 1996, 1998, ++ * 2001, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ * ++ * Note: This code is heavily based on the GNU MP Library. ++ * Actually it's the same code with only minor changes in the ++ * way the data is stored; this is to support the abstraction ++ * of an optional secure memory allocation which may be used ++ * to avoid revealing of sensitive data due to paging etc. ++ */ ++ ++#include "sysdep.h" ++#include "asm-syntax.h" ++ ++ ++/******************* ++ * mpi_limb_t ++ * _gcry_mpih_sub_n( mpi_ptr_t res_ptr, (sp + 4) ++ * mpi_ptr_t s1_ptr, (sp + 8) ++ * mpi_ptr_t s2_ptr, (sp + 16) ++ * mpi_size_t size) (sp + 12) ++ */ ++ ++ ++ TEXT ++ ALIGN ++ GLOBL C_SYMBOL_NAME(_gcry_mpih_sub_n) ++ ++C_SYMBOL_NAME(_gcry_mpih_sub_n:) ++PROLOG(_gcry_mpih_sub_n) ++/* Save used registers on the stack. */ ++ movel R(d2),MEM_PREDEC(sp) ++ movel R(a2),MEM_PREDEC(sp) ++ ++/* Copy the arguments to registers. Better use movem? */ ++ movel MEM_DISP(sp,12),R(a2) ++ movel MEM_DISP(sp,16),R(a0) ++ movel MEM_DISP(sp,20),R(a1) ++ movel MEM_DISP(sp,24),R(d2) ++ ++ eorw #1,R(d2) ++ lsrl #1,R(d2) ++ bcc L(L1) ++ subql #1,R(d2) /* clears cy as side effect */ ++ ++L(Loop:) ++ movel MEM_POSTINC(a0),R(d0) ++ movel MEM_POSTINC(a1),R(d1) ++ subxl R(d1),R(d0) ++ movel R(d0),MEM_POSTINC(a2) ++L(L1:) movel MEM_POSTINC(a0),R(d0) ++ movel MEM_POSTINC(a1),R(d1) ++ subxl R(d1),R(d0) ++ movel R(d0),MEM_POSTINC(a2) ++ ++ dbf R(d2),L(Loop) /* loop until 16 lsb of %4 == -1 */ ++ subxl R(d0),R(d0) /* d0 <= -cy; save cy as 0 or -1 in d0 */ ++ subl #0x10000,R(d2) ++ bcs L(L2) ++ addl R(d0),R(d0) /* restore cy */ ++ bra L(Loop) ++ ++L(L2:) ++ negl R(d0) ++ ++/* Restore used registers from stack frame. */ ++ movel MEM_POSTINC(sp),R(a2) ++ movel MEM_POSTINC(sp),R(d2) ++ ++ rts ++EPILOG(_gcry_mpih_sub_n) ++ ++ +diff --git a/grub-core/lib/libgcrypt/mpi/m68k/syntax.h b/grub-core/lib/libgcrypt/mpi/m68k/syntax.h +new file mode 100644 +index 0000000..e27de98 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/m68k/syntax.h +@@ -0,0 +1,185 @@ ++/* asm.h -- Definitions for 68k syntax variations. ++ * ++ * Copyright (C) 1992, 1994, 1996, 1998, ++ * 2001, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ * ++ * Note: This code is heavily based on the GNU MP Library. ++ * Actually it's the same code with only minor changes in the ++ * way the data is stored; this is to support the abstraction ++ * of an optional secure memory allocation which may be used ++ * to avoid revealing of sensitive data due to paging etc. ++ */ ++ ++ ++#undef ALIGN ++ ++#ifdef MIT_SYNTAX ++#define PROLOG(name) ++#define EPILOG(name) ++#define R(r)r ++#define MEM(base)base@ ++#define MEM_DISP(base,displacement)base@(displacement) ++#define MEM_INDX(base,idx,size_suffix)base@(idx:size_suffix) ++#define MEM_INDX1(base,idx,size_suffix,scale)base@(idx:size_suffix:scale) ++#define MEM_PREDEC(memory_base)memory_base@- ++#define MEM_POSTINC(memory_base)memory_base@+ ++#define L(label) label ++#define TEXT .text ++#define ALIGN .even ++#define GLOBL .globl ++#define moveql moveq ++/* Use variable sized opcodes. */ ++#define bcc jcc ++#define bcs jcs ++#define bls jls ++#define beq jeq ++#define bne jne ++#define bra jra ++#endif ++ ++#ifdef SONY_SYNTAX ++#define PROLOG(name) ++#define EPILOG(name) ++#define R(r)r ++#define MEM(base)(base) ++#define MEM_DISP(base,displacement)(displacement,base) ++#define MEM_INDX(base,idx,size_suffix)(base,idx.size_suffix) ++#define MEM_INDX1(base,idx,size_suffix,scale)(base,idx.size_suffix*scale) ++#define MEM_PREDEC(memory_base)-(memory_base) ++#define MEM_POSTINC(memory_base)(memory_base)+ ++#define L(label) label ++#define TEXT .text ++#define ALIGN .even ++#define GLOBL .globl ++#endif ++ ++#ifdef MOTOROLA_SYNTAX ++#define PROLOG(name) ++#define EPILOG(name) ++#define R(r)r ++#define MEM(base)(base) ++#define MEM_DISP(base,displacement)(displacement,base) ++#define MEM_INDX(base,idx,size_suffix)(base,idx.size_suffix) ++#define MEM_INDX1(base,idx,size_suffix,scale)(base,idx.size_suffix*scale) ++#define MEM_PREDEC(memory_base)-(memory_base) ++#define MEM_POSTINC(memory_base)(memory_base)+ ++#define L(label) label ++#define TEXT ++#define ALIGN ++#define GLOBL XDEF ++#define lea LEA ++#define movel MOVE.L ++#define moveml MOVEM.L ++#define moveql MOVEQ.L ++#define cmpl CMP.L ++#define orl OR.L ++#define clrl CLR.L ++#define eorw EOR.W ++#define lsrl LSR.L ++#define lsll LSL.L ++#define roxrl ROXR.L ++#define roxll ROXL.L ++#define addl ADD.L ++#define addxl ADDX.L ++#define addql ADDQ.L ++#define subl SUB.L ++#define subxl SUBX.L ++#define subql SUBQ.L ++#define negl NEG.L ++#define mulul MULU.L ++#define bcc BCC ++#define bcs BCS ++#define bls BLS ++#define beq BEQ ++#define bne BNE ++#define bra BRA ++#define dbf DBF ++#define rts RTS ++#define d0 D0 ++#define d1 D1 ++#define d2 D2 ++#define d3 D3 ++#define d4 D4 ++#define d5 D5 ++#define d6 D6 ++#define d7 D7 ++#define a0 A0 ++#define a1 A1 ++#define a2 A2 ++#define a3 A3 ++#define a4 A4 ++#define a5 A5 ++#define a6 A6 ++#define a7 A7 ++#define sp SP ++#endif ++ ++#ifdef ELF_SYNTAX ++#define PROLOG(name) .type name,@function ++#define EPILOG(name) .size name,.-name ++#define MEM(base)(R(base)) ++#define MEM_DISP(base,displacement)(displacement,R(base)) ++#define MEM_PREDEC(memory_base)-(R(memory_base)) ++#define MEM_POSTINC(memory_base)(R(memory_base))+ ++#ifdef __STDC__ ++#define R_(r)%##r ++#define R(r)R_(r) ++#define MEM_INDX_(base,idx,size_suffix)(R(base),R(idx##.##size_suffix)) ++#define MEM_INDX(base,idx,size_suffix)MEM_INDX_(base,idx,size_suffix) ++#define MEM_INDX1_(base,idx,size_suffix,scale)(R(base),R(idx##.##size_suffix*scale)) ++#define MEM_INDX1(base,idx,size_suffix,scale)MEM_INDX1_(base,idx,size_suffix,scale) ++#define L(label) .##label ++#else ++#define R(r)%/**/r ++#define MEM_INDX(base,idx,size_suffix)(R(base),R(idx).size_suffix) ++#define MEM_INDX1(base,idx,size_suffix,scale)(R(base),R(idx).size_suffix*scale) ++#define L(label) ./**/label ++#endif ++#define TEXT .text ++#define ALIGN .align 2 ++#define GLOBL .globl ++#define bcc jbcc ++#define bcs jbcs ++#define bls jbls ++#define beq jbeq ++#define bne jbne ++#define bra jbra ++#endif ++ ++#if defined (SONY_SYNTAX) || defined (ELF_SYNTAX) ++#define movel move.l ++#define moveml movem.l ++#define moveql moveq.l ++#define cmpl cmp.l ++#define orl or.l ++#define clrl clr.l ++#define eorw eor.w ++#define lsrl lsr.l ++#define lsll lsl.l ++#define roxrl roxr.l ++#define roxll roxl.l ++#define addl add.l ++#define addxl addx.l ++#define addql addq.l ++#define subl sub.l ++#define subxl subx.l ++#define subql subq.l ++#define negl neg.l ++#define mulul mulu.l ++#endif +diff --git a/grub-core/lib/libgcrypt/mpi/mips3/Manifest b/grub-core/lib/libgcrypt/mpi/mips3/Manifest +new file mode 100644 +index 0000000..e191184 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/mips3/Manifest +@@ -0,0 +1,28 @@ ++# Manifest - checksums ++# Copyright 2003 Free Software Foundation, Inc. ++# ++# This file is part of Libgcrypt. ++# ++# Libgcrypt is free software; you can redistribute it and/or modify ++# it under the terms of the GNU Lesser general Public License as ++# published by the Free Software Foundation; either version 2.1 of ++# the License, or (at your option) any later version. ++# ++# Libgcrypt 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 Lesser General Public License for more details. ++# ++# You should have received a copy of the GNU Lesser General Public ++# License along with this program; if not, write to the Free Software ++# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ ++mpih-add1.S ++mpih-sub1.S ++mpih-mul1.S ++mpih-mul2.S ++mpih-mul3.S ++mpih-lshift.S ++mpih-rshift.S ++mpi-asm-defs.h ++$names$ iQCVAwUAP+LmUTEAnp832S/7AQLm/gP/RHR2aLMwHPxsq0mGO5H0kneVn8a9l9yDNEZBefkYcOJMb7MZGKxbGspyENiU04Mc2TFnA1wS9gjNHlRWtUYxxn/wyuV6BIRgfstXt2nXGgEQrK07GIz8ETFcYqcxu7JKiICIuXZgnIgdwBJswbBV1zaMUDXeg5B8vkkEeRWj8hQ==IQVO +diff --git a/grub-core/lib/libgcrypt/mpi/mips3/README b/grub-core/lib/libgcrypt/mpi/mips3/README +new file mode 100644 +index 0000000..e94b2c7 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/mips3/README +@@ -0,0 +1,23 @@ ++This directory contains mpn functions optimized for MIPS3. Example of ++processors that implement MIPS3 are R4000, R4400, R4600, R4700, and R8000. ++ ++RELEVANT OPTIMIZATION ISSUES ++ ++1. On the R4000 and R4400, branches, both the plain and the "likely" ones, ++ take 3 cycles to execute. (The fastest possible loop will take 4 cycles, ++ because of the delay insn.) ++ ++ On the R4600, branches takes a single cycle ++ ++ On the R8000, branches often take no noticable cycles, as they are ++ executed in a separate function unit.. ++ ++2. The R4000 and R4400 have a load latency of 4 cycles. ++ ++3. On the R4000 and R4400, multiplies take a data-dependent number of ++ cycles, contrary to the SGI documentation. There seem to be 3 or 4 ++ possible latencies. ++ ++STATUS ++ ++Good... +diff --git a/grub-core/lib/libgcrypt/mpi/mips3/distfiles b/grub-core/lib/libgcrypt/mpi/mips3/distfiles +new file mode 100644 +index 0000000..ef9b6fe +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/mips3/distfiles +@@ -0,0 +1,11 @@ ++Manifest ++README ++mpih-add1.S ++mpih-sub1.S ++mpih-mul1.S ++mpih-mul2.S ++mpih-mul3.S ++mpih-lshift.S ++mpih-rshift.S ++mpi-asm-defs.h ++ +diff --git a/grub-core/lib/libgcrypt/mpi/mips3/mpi-asm-defs.h b/grub-core/lib/libgcrypt/mpi/mips3/mpi-asm-defs.h +new file mode 100644 +index 0000000..2d9a9c1 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/mips3/mpi-asm-defs.h +@@ -0,0 +1,10 @@ ++/* This file defines some basic constants for the MPI machinery. We ++ * need to define the types on a per-CPU basis, so it is done with ++ * this file here. */ ++#define BYTES_PER_MPI_LIMB 8 ++ ++ ++ ++ ++ ++ +diff --git a/grub-core/lib/libgcrypt/mpi/mips3/mpih-add1.S b/grub-core/lib/libgcrypt/mpi/mips3/mpih-add1.S +new file mode 100644 +index 0000000..f3db029 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/mips3/mpih-add1.S +@@ -0,0 +1,124 @@ ++/* mips3 add_n -- Add two limb vectors of the same length > 0 and store ++ * sum in a third limb vector. ++ * ++ * Copyright (C) 1995, 1998, 2000 ++ * 2001, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ */ ++ ++ ++/******************* ++ * mpi_limb_t ++ * _gcry_mpih_add_n( mpi_ptr_t res_ptr, ($4) ++ * mpi_ptr_t s1_ptr, ($5) ++ * mpi_ptr_t s2_ptr, ($6) ++ * mpi_size_t size) ($7) ++ */ ++ ++ .text ++ .align 2 ++ .globl _gcry_mpih_add_n ++ .ent _gcry_mpih_add_n ++_gcry_mpih_add_n: ++ .set noreorder ++ .set nomacro ++ ++ ld $10,0($5) ++ ld $11,0($6) ++ ++ daddiu $7,$7,-1 ++ and $9,$7,4-1 # number of limbs in first loop ++ beq $9,$0,.L0 # if multiple of 4 limbs, skip first loop ++ move $2,$0 ++ ++ dsubu $7,$7,$9 ++ ++.Loop0: daddiu $9,$9,-1 ++ ld $12,8($5) ++ daddu $11,$11,$2 ++ ld $13,8($6) ++ sltu $8,$11,$2 ++ daddu $11,$10,$11 ++ sltu $2,$11,$10 ++ sd $11,0($4) ++ or $2,$2,$8 ++ ++ daddiu $5,$5,8 ++ daddiu $6,$6,8 ++ move $10,$12 ++ move $11,$13 ++ bne $9,$0,.Loop0 ++ daddiu $4,$4,8 ++ ++.L0: beq $7,$0,.Lend ++ nop ++ ++.Loop: daddiu $7,$7,-4 ++ ++ ld $12,8($5) ++ daddu $11,$11,$2 ++ ld $13,8($6) ++ sltu $8,$11,$2 ++ daddu $11,$10,$11 ++ sltu $2,$11,$10 ++ sd $11,0($4) ++ or $2,$2,$8 ++ ++ ld $10,16($5) ++ daddu $13,$13,$2 ++ ld $11,16($6) ++ sltu $8,$13,$2 ++ daddu $13,$12,$13 ++ sltu $2,$13,$12 ++ sd $13,8($4) ++ or $2,$2,$8 ++ ++ ld $12,24($5) ++ daddu $11,$11,$2 ++ ld $13,24($6) ++ sltu $8,$11,$2 ++ daddu $11,$10,$11 ++ sltu $2,$11,$10 ++ sd $11,16($4) ++ or $2,$2,$8 ++ ++ ld $10,32($5) ++ daddu $13,$13,$2 ++ ld $11,32($6) ++ sltu $8,$13,$2 ++ daddu $13,$12,$13 ++ sltu $2,$13,$12 ++ sd $13,24($4) ++ or $2,$2,$8 ++ ++ daddiu $5,$5,32 ++ daddiu $6,$6,32 ++ ++ bne $7,$0,.Loop ++ daddiu $4,$4,32 ++ ++.Lend: daddu $11,$11,$2 ++ sltu $8,$11,$2 ++ daddu $11,$10,$11 ++ sltu $2,$11,$10 ++ sd $11,0($4) ++ j $31 ++ or $2,$2,$8 ++ ++ .end _gcry_mpih_add_n ++ +diff --git a/grub-core/lib/libgcrypt/mpi/mips3/mpih-lshift.S b/grub-core/lib/libgcrypt/mpi/mips3/mpih-lshift.S +new file mode 100644 +index 0000000..084c109 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/mips3/mpih-lshift.S +@@ -0,0 +1,97 @@ ++/* mips3 lshift ++ * ++ * Copyright (C) 1995, 1998, 2000, ++ * 2001, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ */ ++ ++/******************* ++ * mpi_limb_t ++ * _gcry_mpih_lshift( mpi_ptr_t wp, ($4) ++ * mpi_ptr_t up, ($5) ++ * mpi_size_t usize, ($6) ++ * unsigned cnt) ($7) ++ */ ++ ++ .text ++ .align 2 ++ .globl _gcry_mpih_lshift ++ .ent _gcry_mpih_lshift ++_gcry_mpih_lshift: ++ .set noreorder ++ .set nomacro ++ ++ dsll $2,$6,3 ++ daddu $5,$5,$2 # make r5 point at end of src ++ ld $10,-8($5) # load first limb ++ dsubu $13,$0,$7 ++ daddu $4,$4,$2 # make r4 point at end of res ++ daddiu $6,$6,-1 ++ and $9,$6,4-1 # number of limbs in first loop ++ beq $9,$0,.L0 # if multiple of 4 limbs, skip first loop ++ dsrl $2,$10,$13 # compute function result ++ ++ dsubu $6,$6,$9 ++ ++.Loop0: ld $3,-16($5) ++ daddiu $4,$4,-8 ++ daddiu $5,$5,-8 ++ daddiu $9,$9,-1 ++ dsll $11,$10,$7 ++ dsrl $12,$3,$13 ++ move $10,$3 ++ or $8,$11,$12 ++ bne $9,$0,.Loop0 ++ sd $8,0($4) ++ ++.L0: beq $6,$0,.Lend ++ nop ++ ++.Loop: ld $3,-16($5) ++ daddiu $4,$4,-32 ++ daddiu $6,$6,-4 ++ dsll $11,$10,$7 ++ dsrl $12,$3,$13 ++ ++ ld $10,-24($5) ++ dsll $14,$3,$7 ++ or $8,$11,$12 ++ sd $8,24($4) ++ dsrl $9,$10,$13 ++ ++ ld $3,-32($5) ++ dsll $11,$10,$7 ++ or $8,$14,$9 ++ sd $8,16($4) ++ dsrl $12,$3,$13 ++ ++ ld $10,-40($5) ++ dsll $14,$3,$7 ++ or $8,$11,$12 ++ sd $8,8($4) ++ dsrl $9,$10,$13 ++ ++ daddiu $5,$5,-32 ++ or $8,$14,$9 ++ bgtz $6,.Loop ++ sd $8,0($4) ++ ++.Lend: dsll $8,$10,$7 ++ j $31 ++ sd $8,-8($4) ++ .end _gcry_mpih_lshift +diff --git a/grub-core/lib/libgcrypt/mpi/mips3/mpih-mul1.S b/grub-core/lib/libgcrypt/mpi/mips3/mpih-mul1.S +new file mode 100644 +index 0000000..6c0099d +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/mips3/mpih-mul1.S +@@ -0,0 +1,89 @@ ++/* mips3 mpih-mul1.S -- Multiply a limb vector with a limb and store ++ * the result in a second limb vector. ++ * ++ * Copyright (C) 1992, 1994, 1995, 1998, 2000 ++ * 2001, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ */ ++ ++ ++/******************* ++ * mpi_limb_t ++ * _gcry_mpih_mul_1( mpi_ptr_t res_ptr, (r4) ++ * mpi_ptr_t s1_ptr, (r5) ++ * mpi_size_t s1_size, (r6) ++ * mpi_limb_t s2_limb) (r7) ++ */ ++ ++ .text ++ .align 4 ++ .globl _gcry_mpih_mul_1 ++ .ent _gcry_mpih_mul_1 ++_gcry_mpih_mul_1: ++ .set noreorder ++ .set nomacro ++ ++/* # warm up phase 0 */ ++ ld $8,0($5) ++ ++/* # warm up phase 1 */ ++ daddiu $5,$5,8 ++ dmultu $8,$7 ++ ++ daddiu $6,$6,-1 ++ beq $6,$0,$LC0 ++ move $2,$0 # zero cy2 ++ ++ daddiu $6,$6,-1 ++ beq $6,$0,$LC1 ++ ld $8,0($5) # load new s1 limb as early as possible ++ ++Loop: mflo $10 ++ mfhi $9 ++ daddiu $5,$5,8 ++ daddu $10,$10,$2 # add old carry limb to low product limb ++ dmultu $8,$7 ++ ld $8,0($5) # load new s1 limb as early as possible ++ daddiu $6,$6,-1 # decrement loop counter ++ sltu $2,$10,$2 # carry from previous addition -> $2 ++ sd $10,0($4) ++ daddiu $4,$4,8 ++ bne $6,$0,Loop ++ daddu $2,$9,$2 # add high product limb and carry from addition ++ ++/* # cool down phase 1 */ ++$LC1: mflo $10 ++ mfhi $9 ++ daddu $10,$10,$2 ++ sltu $2,$10,$2 ++ dmultu $8,$7 ++ sd $10,0($4) ++ daddiu $4,$4,8 ++ daddu $2,$9,$2 # add high product limb and carry from addition ++ ++/* # cool down phase 0 */ ++$LC0: mflo $10 ++ mfhi $9 ++ daddu $10,$10,$2 ++ sltu $2,$10,$2 ++ sd $10,0($4) ++ j $31 ++ daddu $2,$9,$2 # add high product limb and carry from addition ++ ++ .end _gcry_mpih_mul_1 ++ +diff --git a/grub-core/lib/libgcrypt/mpi/mips3/mpih-mul2.S b/grub-core/lib/libgcrypt/mpi/mips3/mpih-mul2.S +new file mode 100644 +index 0000000..ca82763 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/mips3/mpih-mul2.S +@@ -0,0 +1,101 @@ ++/* MIPS3 addmul_1 -- Multiply a limb vector with a single limb and ++ * add the product to a second limb vector. ++ * ++ * Copyright (C) 1992, 1994, 1995, 1998, 2000 ++ * 2001, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ */ ++ ++ ++/******************* ++ * mpi_limb_t ++ * _gcry_mpih_addmul_1( mpi_ptr_t res_ptr, (r4) ++ * mpi_ptr_t s1_ptr, (r5) ++ * mpi_size_t s1_size, (r6) ++ * mpi_limb_t s2_limb) (r7) ++ */ ++ ++ .text ++ .align 4 ++ .globl _gcry_mpih_addmul_1 ++ .ent _gcry_mpih_addmul_1 ++_gcry_mpih_addmul_1: ++ .set noreorder ++ .set nomacro ++ ++/* # warm up phase 0 */ ++ ld $8,0($5) ++ ++/* # warm up phase 1 */ ++ daddiu $5,$5,8 ++ dmultu $8,$7 ++ ++ daddiu $6,$6,-1 ++ beq $6,$0,$LC0 ++ move $2,$0 # zero cy2 ++ ++ daddiu $6,$6,-1 ++ beq $6,$0,$LC1 ++ ld $8,0($5) # load new s1 limb as early as possible ++ ++Loop: ld $10,0($4) ++ mflo $3 ++ mfhi $9 ++ daddiu $5,$5,8 ++ daddu $3,$3,$2 # add old carry limb to low product limb ++ dmultu $8,$7 ++ ld $8,0($5) # load new s1 limb as early as possible ++ daddiu $6,$6,-1 # decrement loop counter ++ sltu $2,$3,$2 # carry from previous addition -> $2 ++ daddu $3,$10,$3 ++ sltu $10,$3,$10 ++ daddu $2,$2,$10 ++ sd $3,0($4) ++ daddiu $4,$4,8 ++ bne $6,$0,Loop ++ daddu $2,$9,$2 # add high product limb and carry from addition ++ ++/* # cool down phase 1 */ ++$LC1: ld $10,0($4) ++ mflo $3 ++ mfhi $9 ++ daddu $3,$3,$2 ++ sltu $2,$3,$2 ++ dmultu $8,$7 ++ daddu $3,$10,$3 ++ sltu $10,$3,$10 ++ daddu $2,$2,$10 ++ sd $3,0($4) ++ daddiu $4,$4,8 ++ daddu $2,$9,$2 # add high product limb and carry from addition ++ ++/* # cool down phase 0 */ ++$LC0: ld $10,0($4) ++ mflo $3 ++ mfhi $9 ++ daddu $3,$3,$2 ++ sltu $2,$3,$2 ++ daddu $3,$10,$3 ++ sltu $10,$3,$10 ++ daddu $2,$2,$10 ++ sd $3,0($4) ++ j $31 ++ daddu $2,$9,$2 # add high product limb and carry from addition ++ ++ .end _gcry_mpih_addmul_1 ++ +diff --git a/grub-core/lib/libgcrypt/mpi/mips3/mpih-mul3.S b/grub-core/lib/libgcrypt/mpi/mips3/mpih-mul3.S +new file mode 100644 +index 0000000..be421a6 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/mips3/mpih-mul3.S +@@ -0,0 +1,101 @@ ++/* MIPS3 submul_1 -- Multiply a limb vector with a single limb and ++ * subtract the product from a second limb vector. ++ * ++ * Copyright (C) 1992, 1994, 1995, 1998, 2000 ++ * 2001, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ */ ++ ++ ++/******************* ++ * mpi_limb_t ++ * _gcry_mpih_submul_1( mpi_ptr_t res_ptr, (r4) ++ * mpi_ptr_t s1_ptr, (r5) ++ * mpi_size_t s1_size, (r6) ++ * mpi_limb_t s2_limb) (r7) ++ */ ++ ++ .text ++ .align 4 ++ .globl _gcry_mpih_submul_1 ++ .ent _gcry_mpih_submul_1 ++_gcry_mpih_submul_1: ++ .set noreorder ++ .set nomacro ++ ++/* # warm up phase 0 */ ++ ld $8,0($5) ++ ++/* # warm up phase 1 */ ++ daddiu $5,$5,8 ++ dmultu $8,$7 ++ ++ daddiu $6,$6,-1 ++ beq $6,$0,$LC0 ++ move $2,$0 # zero cy2 ++ ++ daddiu $6,$6,-1 ++ beq $6,$0,$LC1 ++ ld $8,0($5) # load new s1 limb as early as possible ++ ++Loop: ld $10,0($4) ++ mflo $3 ++ mfhi $9 ++ daddiu $5,$5,8 ++ daddu $3,$3,$2 # add old carry limb to low product limb ++ dmultu $8,$7 ++ ld $8,0($5) # load new s1 limb as early as possible ++ daddiu $6,$6,-1 # decrement loop counter ++ sltu $2,$3,$2 # carry from previous addition -> $2 ++ dsubu $3,$10,$3 ++ sgtu $10,$3,$10 ++ daddu $2,$2,$10 ++ sd $3,0($4) ++ daddiu $4,$4,8 ++ bne $6,$0,Loop ++ daddu $2,$9,$2 # add high product limb and carry from addition ++ ++/* # cool down phase 1 */ ++$LC1: ld $10,0($4) ++ mflo $3 ++ mfhi $9 ++ daddu $3,$3,$2 ++ sltu $2,$3,$2 ++ dmultu $8,$7 ++ dsubu $3,$10,$3 ++ sgtu $10,$3,$10 ++ daddu $2,$2,$10 ++ sd $3,0($4) ++ daddiu $4,$4,8 ++ daddu $2,$9,$2 # add high product limb and carry from addition ++ ++/* # cool down phase 0 */ ++$LC0: ld $10,0($4) ++ mflo $3 ++ mfhi $9 ++ daddu $3,$3,$2 ++ sltu $2,$3,$2 ++ dsubu $3,$10,$3 ++ sgtu $10,$3,$10 ++ daddu $2,$2,$10 ++ sd $3,0($4) ++ j $31 ++ daddu $2,$9,$2 # add high product limb and carry from addition ++ ++ .end _gcry_mpih_submul_1 ++ +diff --git a/grub-core/lib/libgcrypt/mpi/mips3/mpih-rshift.S b/grub-core/lib/libgcrypt/mpi/mips3/mpih-rshift.S +new file mode 100644 +index 0000000..e7e035a +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/mips3/mpih-rshift.S +@@ -0,0 +1,95 @@ ++/* mips3 rshift ++ * ++ * Copyright (C) 1995, 1998, 2000 ++ * 2001, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ */ ++ ++/******************* ++ * mpi_limb_t ++ * _gcry_mpih_rshift( mpi_ptr_t wp, ($4) ++ * mpi_ptr_t up, ($5) ++ * mpi_size_t usize, ($6) ++ * unsigned cnt) ($7) ++ */ ++ ++ .text ++ .align 2 ++ .globl _gcry_mpih_rshift ++ .ent _gcry_mpih_rshift ++_gcry_mpih_rshift: ++ .set noreorder ++ .set nomacro ++ ++ ld $10,0($5) # load first limb ++ dsubu $13,$0,$7 ++ daddiu $6,$6,-1 ++ and $9,$6,4-1 # number of limbs in first loop ++ beq $9,$0,.L0 # if multiple of 4 limbs, skip first loop ++ dsll $2,$10,$13 # compute function result ++ ++ dsubu $6,$6,$9 ++ ++.Loop0: ld $3,8($5) ++ daddiu $4,$4,8 ++ daddiu $5,$5,8 ++ daddiu $9,$9,-1 ++ dsrl $11,$10,$7 ++ dsll $12,$3,$13 ++ move $10,$3 ++ or $8,$11,$12 ++ bne $9,$0,.Loop0 ++ sd $8,-8($4) ++ ++.L0: beq $6,$0,.Lend ++ nop ++ ++.Loop: ld $3,8($5) ++ daddiu $4,$4,32 ++ daddiu $6,$6,-4 ++ dsrl $11,$10,$7 ++ dsll $12,$3,$13 ++ ++ ld $10,16($5) ++ dsrl $14,$3,$7 ++ or $8,$11,$12 ++ sd $8,-32($4) ++ dsll $9,$10,$13 ++ ++ ld $3,24($5) ++ dsrl $11,$10,$7 ++ or $8,$14,$9 ++ sd $8,-24($4) ++ dsll $12,$3,$13 ++ ++ ld $10,32($5) ++ dsrl $14,$3,$7 ++ or $8,$11,$12 ++ sd $8,-16($4) ++ dsll $9,$10,$13 ++ ++ daddiu $5,$5,32 ++ or $8,$14,$9 ++ bgtz $6,.Loop ++ sd $8,-8($4) ++ ++.Lend: dsrl $8,$10,$7 ++ j $31 ++ sd $8,0($4) ++ .end _gcry_mpih_rshift ++ +diff --git a/grub-core/lib/libgcrypt/mpi/mips3/mpih-sub1.S b/grub-core/lib/libgcrypt/mpi/mips3/mpih-sub1.S +new file mode 100644 +index 0000000..9fac674 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/mips3/mpih-sub1.S +@@ -0,0 +1,125 @@ ++/* mips3 sub_n -- Subtract two limb vectors of the same length > 0 and ++ * store difference in a third limb vector. ++ * ++ * Copyright (C) 1995, 1998, 1999, 2000, ++ * 2001, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ */ ++ ++ ++/******************* ++ * mpi_limb_t ++ * _gcry_mpih_sub_n( mpi_ptr_t res_ptr, (r4) ++ * mpi_ptr_t s1_ptr, (r5) ++ * mpi_ptr_t s2_ptr, (r6) ++ * mpi_size_t size) (r7) ++ */ ++ ++ ++ .text ++ .align 2 ++ .globl _gcry_mpih_sub_n ++ .ent _gcry_mpih_sub_n ++_gcry_mpih_sub_n: ++ .set noreorder ++ .set nomacro ++ ++ ld $10,0($5) ++ ld $11,0($6) ++ ++ daddiu $7,$7,-1 ++ and $9,$7,4-1 # number of limbs in first loop ++ beq $9,$0,.L0 # if multiple of 4 limbs, skip first loop ++ move $2,$0 ++ ++ dsubu $7,$7,$9 ++ ++.Loop0: daddiu $9,$9,-1 ++ ld $12,8($5) ++ daddu $11,$11,$2 ++ ld $13,8($6) ++ sltu $8,$11,$2 ++ dsubu $11,$10,$11 ++ sltu $2,$10,$11 ++ sd $11,0($4) ++ or $2,$2,$8 ++ ++ daddiu $5,$5,8 ++ daddiu $6,$6,8 ++ move $10,$12 ++ move $11,$13 ++ bne $9,$0,.Loop0 ++ daddiu $4,$4,8 ++ ++.L0: beq $7,$0,.Lend ++ nop ++ ++.Loop: daddiu $7,$7,-4 ++ ++ ld $12,8($5) ++ daddu $11,$11,$2 ++ ld $13,8($6) ++ sltu $8,$11,$2 ++ dsubu $11,$10,$11 ++ sltu $2,$10,$11 ++ sd $11,0($4) ++ or $2,$2,$8 ++ ++ ld $10,16($5) ++ daddu $13,$13,$2 ++ ld $11,16($6) ++ sltu $8,$13,$2 ++ dsubu $13,$12,$13 ++ sltu $2,$12,$13 ++ sd $13,8($4) ++ or $2,$2,$8 ++ ++ ld $12,24($5) ++ daddu $11,$11,$2 ++ ld $13,24($6) ++ sltu $8,$11,$2 ++ dsubu $11,$10,$11 ++ sltu $2,$10,$11 ++ sd $11,16($4) ++ or $2,$2,$8 ++ ++ ld $10,32($5) ++ daddu $13,$13,$2 ++ ld $11,32($6) ++ sltu $8,$13,$2 ++ dsubu $13,$12,$13 ++ sltu $2,$12,$13 ++ sd $13,24($4) ++ or $2,$2,$8 ++ ++ daddiu $5,$5,32 ++ daddiu $6,$6,32 ++ ++ bne $7,$0,.Loop ++ daddiu $4,$4,32 ++ ++.Lend: daddu $11,$11,$2 ++ sltu $8,$11,$2 ++ dsubu $11,$10,$11 ++ sltu $2,$10,$11 ++ sd $11,0($4) ++ j $31 ++ or $2,$2,$8 ++ ++ .end _gcry_mpih_sub_n ++ +diff --git a/grub-core/lib/libgcrypt/mpi/mpi-add.c b/grub-core/lib/libgcrypt/mpi/mpi-add.c +new file mode 100644 +index 0000000..98abc56 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/mpi-add.c +@@ -0,0 +1,235 @@ ++/* mpi-add.c - MPI functions ++ * Copyright (C) 1994, 1996, 1998, 2001, 2002, 2003 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ * ++ * Note: This code is heavily based on the GNU MP Library. ++ * Actually it's the same code with only minor changes in the ++ * way the data is stored; this is to support the abstraction ++ * of an optional secure memory allocation which may be used ++ * to avoid revealing of sensitive data due to paging etc. ++ */ ++ ++#include ++#include ++#include ++ ++#include "mpi-internal.h" ++ ++ ++/**************** ++ * Add the unsigned integer V to the mpi-integer U and store the ++ * result in W. U and V may be the same. ++ */ ++void ++gcry_mpi_add_ui(gcry_mpi_t w, gcry_mpi_t u, unsigned long v ) ++{ ++ mpi_ptr_t wp, up; ++ mpi_size_t usize, wsize; ++ int usign, wsign; ++ ++ usize = u->nlimbs; ++ usign = u->sign; ++ wsign = 0; ++ ++ /* If not space for W (and possible carry), increase space. */ ++ wsize = usize + 1; ++ if( w->alloced < wsize ) ++ mpi_resize(w, wsize); ++ ++ /* These must be after realloc (U may be the same as W). */ ++ up = u->d; ++ wp = w->d; ++ ++ if( !usize ) { /* simple */ ++ wp[0] = v; ++ wsize = v? 1:0; ++ } ++ else if( !usign ) { /* mpi is not negative */ ++ mpi_limb_t cy; ++ cy = _gcry_mpih_add_1(wp, up, usize, v); ++ wp[usize] = cy; ++ wsize = usize + cy; ++ } ++ else { /* The signs are different. Need exact comparison to determine ++ * which operand to subtract from which. */ ++ if( usize == 1 && up[0] < v ) { ++ wp[0] = v - up[0]; ++ wsize = 1; ++ } ++ else { ++ _gcry_mpih_sub_1(wp, up, usize, v); ++ /* Size can decrease with at most one limb. */ ++ wsize = usize - (wp[usize-1]==0); ++ wsign = 1; ++ } ++ } ++ ++ w->nlimbs = wsize; ++ w->sign = wsign; ++} ++ ++ ++void ++gcry_mpi_add(gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v) ++{ ++ mpi_ptr_t wp, up, vp; ++ mpi_size_t usize, vsize, wsize; ++ int usign, vsign, wsign; ++ ++ if( u->nlimbs < v->nlimbs ) { /* Swap U and V. */ ++ usize = v->nlimbs; ++ usign = v->sign; ++ vsize = u->nlimbs; ++ vsign = u->sign; ++ wsize = usize + 1; ++ RESIZE_IF_NEEDED(w, wsize); ++ /* These must be after realloc (u or v may be the same as w). */ ++ up = v->d; ++ vp = u->d; ++ } ++ else { ++ usize = u->nlimbs; ++ usign = u->sign; ++ vsize = v->nlimbs; ++ vsign = v->sign; ++ wsize = usize + 1; ++ RESIZE_IF_NEEDED(w, wsize); ++ /* These must be after realloc (u or v may be the same as w). */ ++ up = u->d; ++ vp = v->d; ++ } ++ wp = w->d; ++ wsign = 0; ++ ++ if( !vsize ) { /* simple */ ++ MPN_COPY(wp, up, usize ); ++ wsize = usize; ++ wsign = usign; ++ } ++ else if( usign != vsign ) { /* different sign */ ++ /* This test is right since USIZE >= VSIZE */ ++ if( usize != vsize ) { ++ _gcry_mpih_sub(wp, up, usize, vp, vsize); ++ wsize = usize; ++ MPN_NORMALIZE(wp, wsize); ++ wsign = usign; ++ } ++ else if( _gcry_mpih_cmp(up, vp, usize) < 0 ) { ++ _gcry_mpih_sub_n(wp, vp, up, usize); ++ wsize = usize; ++ MPN_NORMALIZE(wp, wsize); ++ if( !usign ) ++ wsign = 1; ++ } ++ else { ++ _gcry_mpih_sub_n(wp, up, vp, usize); ++ wsize = usize; ++ MPN_NORMALIZE(wp, wsize); ++ if( usign ) ++ wsign = 1; ++ } ++ } ++ else { /* U and V have same sign. Add them. */ ++ mpi_limb_t cy = _gcry_mpih_add(wp, up, usize, vp, vsize); ++ wp[usize] = cy; ++ wsize = usize + cy; ++ if( usign ) ++ wsign = 1; ++ } ++ ++ w->nlimbs = wsize; ++ w->sign = wsign; ++} ++ ++ ++/**************** ++ * Subtract the unsigned integer V from the mpi-integer U and store the ++ * result in W. ++ */ ++void ++gcry_mpi_sub_ui(gcry_mpi_t w, gcry_mpi_t u, unsigned long v ) ++{ ++ mpi_ptr_t wp, up; ++ mpi_size_t usize, wsize; ++ int usign, wsign; ++ ++ usize = u->nlimbs; ++ usign = u->sign; ++ wsign = 0; ++ ++ /* If not space for W (and possible carry), increase space. */ ++ wsize = usize + 1; ++ if( w->alloced < wsize ) ++ mpi_resize(w, wsize); ++ ++ /* These must be after realloc (U may be the same as W). */ ++ up = u->d; ++ wp = w->d; ++ ++ if( !usize ) { /* simple */ ++ wp[0] = v; ++ wsize = v? 1:0; ++ wsign = 1; ++ } ++ else if( usign ) { /* mpi and v are negative */ ++ mpi_limb_t cy; ++ cy = _gcry_mpih_add_1(wp, up, usize, v); ++ wp[usize] = cy; ++ wsize = usize + cy; ++ } ++ else { /* The signs are different. Need exact comparison to determine ++ * which operand to subtract from which. */ ++ if( usize == 1 && up[0] < v ) { ++ wp[0] = v - up[0]; ++ wsize = 1; ++ wsign = 1; ++ } ++ else { ++ _gcry_mpih_sub_1(wp, up, usize, v); ++ /* Size can decrease with at most one limb. */ ++ wsize = usize - (wp[usize-1]==0); ++ } ++ } ++ ++ w->nlimbs = wsize; ++ w->sign = wsign; ++} ++ ++void ++gcry_mpi_sub(gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v) ++{ ++ gcry_mpi_t vv = mpi_copy (v); ++ vv->sign = ! vv->sign; ++ gcry_mpi_add (w, u, vv); ++ mpi_free (vv); ++} ++ ++ ++void ++gcry_mpi_addm( gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m) ++{ ++ gcry_mpi_add(w, u, v); ++ _gcry_mpi_fdiv_r( w, w, m ); ++} ++ ++void ++gcry_mpi_subm( gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m) ++{ ++ gcry_mpi_sub(w, u, v); ++ _gcry_mpi_fdiv_r( w, w, m ); ++} +diff --git a/grub-core/lib/libgcrypt/mpi/mpi-bit.c b/grub-core/lib/libgcrypt/mpi/mpi-bit.c +new file mode 100644 +index 0000000..cdc6b0b +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/mpi-bit.c +@@ -0,0 +1,364 @@ ++/* mpi-bit.c - MPI bit level functions ++ * Copyright (C) 1998, 1999, 2001, 2002, 2006 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ */ ++ ++#include ++#include ++#include ++#include "mpi-internal.h" ++#include "longlong.h" ++ ++ ++#ifdef MPI_INTERNAL_NEED_CLZ_TAB ++#ifdef __STDC__ ++const ++#endif ++unsigned char ++_gcry_clz_tab[] = ++{ ++ 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, ++ 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, ++ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, ++ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, ++ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, ++ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, ++ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, ++ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, ++}; ++#endif ++ ++ ++#define A_LIMB_1 ((mpi_limb_t)1) ++ ++ ++/**************** ++ * Sometimes we have MSL (most significant limbs) which are 0; ++ * this is for some reasons not good, so this function removes them. ++ */ ++void ++_gcry_mpi_normalize( gcry_mpi_t a ) ++{ ++ if( mpi_is_opaque(a) ) ++ return; ++ ++ for( ; a->nlimbs && !a->d[a->nlimbs-1]; a->nlimbs-- ) ++ ; ++} ++ ++ ++ ++/**************** ++ * Return the number of bits in A. ++ */ ++unsigned int ++gcry_mpi_get_nbits( gcry_mpi_t a ) ++{ ++ unsigned n; ++ ++ if( mpi_is_opaque(a) ) { ++ return a->sign; /* which holds the number of bits */ ++ } ++ ++ _gcry_mpi_normalize( a ); ++ if( a->nlimbs ) { ++ mpi_limb_t alimb = a->d[a->nlimbs-1]; ++ if( alimb ) ++ count_leading_zeros( n, alimb ); ++ else ++ n = BITS_PER_MPI_LIMB; ++ n = BITS_PER_MPI_LIMB - n + (a->nlimbs-1) * BITS_PER_MPI_LIMB; ++ } ++ else ++ n = 0; ++ return n; ++} ++ ++ ++/**************** ++ * Test whether bit N is set. ++ */ ++int ++gcry_mpi_test_bit( gcry_mpi_t a, unsigned int n ) ++{ ++ unsigned int limbno, bitno; ++ mpi_limb_t limb; ++ ++ limbno = n / BITS_PER_MPI_LIMB; ++ bitno = n % BITS_PER_MPI_LIMB; ++ ++ if( limbno >= a->nlimbs ) ++ return 0; /* too far left: this is a 0 */ ++ limb = a->d[limbno]; ++ return (limb & (A_LIMB_1 << bitno))? 1: 0; ++} ++ ++ ++/**************** ++ * Set bit N of A. ++ */ ++void ++gcry_mpi_set_bit( gcry_mpi_t a, unsigned int n ) ++{ ++ unsigned int limbno, bitno; ++ ++ limbno = n / BITS_PER_MPI_LIMB; ++ bitno = n % BITS_PER_MPI_LIMB; ++ ++ if ( limbno >= a->nlimbs ) ++ { ++ mpi_resize (a, limbno+1 ); ++ a->nlimbs = limbno+1; ++ } ++ a->d[limbno] |= (A_LIMB_1<= a->nlimbs ) ++ { ++ mpi_resize (a, limbno+1 ); ++ a->nlimbs = limbno+1; ++ } ++ a->d[limbno] |= (A_LIMB_1<d[limbno] &= ~(A_LIMB_1 << bitno); ++ a->nlimbs = limbno+1; ++} ++ ++/**************** ++ * clear bit N of A and all bits above ++ */ ++void ++gcry_mpi_clear_highbit( gcry_mpi_t a, unsigned int n ) ++{ ++ unsigned int limbno, bitno; ++ ++ limbno = n / BITS_PER_MPI_LIMB; ++ bitno = n % BITS_PER_MPI_LIMB; ++ ++ if( limbno >= a->nlimbs ) ++ return; /* not allocated, therefore no need to clear bits ++ :-) */ ++ ++ for( ; bitno < BITS_PER_MPI_LIMB; bitno++ ) ++ a->d[limbno] &= ~(A_LIMB_1 << bitno); ++ a->nlimbs = limbno+1; ++} ++ ++/**************** ++ * Clear bit N of A. ++ */ ++void ++gcry_mpi_clear_bit( gcry_mpi_t a, unsigned int n ) ++{ ++ unsigned int limbno, bitno; ++ ++ limbno = n / BITS_PER_MPI_LIMB; ++ bitno = n % BITS_PER_MPI_LIMB; ++ ++ if( limbno >= a->nlimbs ) ++ return; /* don't need to clear this bit, it's to far to left */ ++ a->d[limbno] &= ~(A_LIMB_1 << bitno); ++} ++ ++ ++/**************** ++ * Shift A by COUNT limbs to the right ++ * This is used only within the MPI library ++ */ ++void ++_gcry_mpi_rshift_limbs( gcry_mpi_t a, unsigned int count ) ++{ ++ mpi_ptr_t ap = a->d; ++ mpi_size_t n = a->nlimbs; ++ unsigned int i; ++ ++ if( count >= n ) { ++ a->nlimbs = 0; ++ return; ++ } ++ ++ for( i = 0; i < n - count; i++ ) ++ ap[i] = ap[i+count]; ++ ap[i] = 0; ++ a->nlimbs -= count; ++} ++ ++ ++/* ++ * Shift A by N bits to the right. ++ */ ++void ++gcry_mpi_rshift ( gcry_mpi_t x, gcry_mpi_t a, unsigned int n ) ++{ ++ mpi_size_t xsize; ++ unsigned int i; ++ unsigned int nlimbs = (n/BITS_PER_MPI_LIMB); ++ unsigned int nbits = (n%BITS_PER_MPI_LIMB); ++ ++ if ( x == a ) ++ { ++ /* In-place operation. */ ++ if ( nlimbs >= x->nlimbs ) ++ { ++ x->nlimbs = 0; ++ return; ++ } ++ ++ if (nlimbs) ++ { ++ for (i=0; i < x->nlimbs - nlimbs; i++ ) ++ x->d[i] = x->d[i+nlimbs]; ++ x->d[i] = 0; ++ x->nlimbs -= nlimbs; ++ ++ } ++ if ( x->nlimbs && nbits ) ++ _gcry_mpih_rshift ( x->d, x->d, x->nlimbs, nbits ); ++ } ++ else if ( nlimbs ) ++ { ++ /* Copy and shift by more or equal bits than in a limb. */ ++ xsize = a->nlimbs; ++ x->sign = a->sign; ++ RESIZE_IF_NEEDED (x, xsize); ++ x->nlimbs = xsize; ++ for (i=0; i < a->nlimbs; i++ ) ++ x->d[i] = a->d[i]; ++ x->nlimbs = i; ++ ++ if ( nlimbs >= x->nlimbs ) ++ { ++ x->nlimbs = 0; ++ return; ++ } ++ ++ if (nlimbs) ++ { ++ for (i=0; i < x->nlimbs - nlimbs; i++ ) ++ x->d[i] = x->d[i+nlimbs]; ++ x->d[i] = 0; ++ x->nlimbs -= nlimbs; ++ } ++ ++ if ( x->nlimbs && nbits ) ++ _gcry_mpih_rshift ( x->d, x->d, x->nlimbs, nbits ); ++ } ++ else ++ { ++ /* Copy and shift by less than bits in a limb. */ ++ xsize = a->nlimbs; ++ x->sign = a->sign; ++ RESIZE_IF_NEEDED (x, xsize); ++ x->nlimbs = xsize; ++ ++ if ( xsize ) ++ { ++ if (nbits ) ++ _gcry_mpih_rshift (x->d, a->d, x->nlimbs, nbits ); ++ else ++ { ++ /* The rshift helper function is not specified for ++ NBITS==0, thus we do a plain copy here. */ ++ for (i=0; i < x->nlimbs; i++ ) ++ x->d[i] = a->d[i]; ++ } ++ } ++ } ++ MPN_NORMALIZE (x->d, x->nlimbs); ++} ++ ++ ++/**************** ++ * Shift A by COUNT limbs to the left ++ * This is used only within the MPI library ++ */ ++void ++_gcry_mpi_lshift_limbs (gcry_mpi_t a, unsigned int count) ++{ ++ mpi_ptr_t ap; ++ int n = a->nlimbs; ++ int i; ++ ++ if (!count || !n) ++ return; ++ ++ RESIZE_IF_NEEDED (a, n+count); ++ ++ ap = a->d; ++ for (i = n-1; i >= 0; i--) ++ ap[i+count] = ap[i]; ++ for (i=0; i < count; i++ ) ++ ap[i] = 0; ++ a->nlimbs += count; ++} ++ ++ ++/* ++ * Shift A by N bits to the left. ++ */ ++void ++gcry_mpi_lshift ( gcry_mpi_t x, gcry_mpi_t a, unsigned int n ) ++{ ++ unsigned int nlimbs = (n/BITS_PER_MPI_LIMB); ++ unsigned int nbits = (n%BITS_PER_MPI_LIMB); ++ ++ if (x == a && !n) ++ return; /* In-place shift with an amount of zero. */ ++ ++ if ( x != a ) ++ { ++ /* Copy A to X. */ ++ unsigned int alimbs = a->nlimbs; ++ int asign = a->sign; ++ mpi_ptr_t xp, ap; ++ ++ RESIZE_IF_NEEDED (x, alimbs+nlimbs+1); ++ xp = x->d; ++ ap = a->d; ++ MPN_COPY (xp, ap, alimbs); ++ x->nlimbs = alimbs; ++ x->flags = a->flags; ++ x->sign = asign; ++ } ++ ++ if (nlimbs && !nbits) ++ { ++ /* Shift a full number of limbs. */ ++ _gcry_mpi_lshift_limbs (x, nlimbs); ++ } ++ else if (n) ++ { ++ /* We use a very dump approach: Shift left by the number of ++ limbs plus one and than fix it up by an rshift. */ ++ _gcry_mpi_lshift_limbs (x, nlimbs+1); ++ gcry_mpi_rshift (x, x, BITS_PER_MPI_LIMB - nbits); ++ } ++ ++ MPN_NORMALIZE (x->d, x->nlimbs); ++} +diff --git a/grub-core/lib/libgcrypt/mpi/mpi-cmp.c b/grub-core/lib/libgcrypt/mpi/mpi-cmp.c +new file mode 100644 +index 0000000..30e1fce +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/mpi-cmp.c +@@ -0,0 +1,107 @@ ++/* mpi-cmp.c - MPI functions ++ * Copyright (C) 1998, 1999, 2001, 2002, 2005 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ */ ++ ++#include ++#include ++#include ++#include "mpi-internal.h" ++ ++int ++gcry_mpi_cmp_ui (gcry_mpi_t u, unsigned long v) ++{ ++ mpi_limb_t limb = v; ++ ++ _gcry_mpi_normalize (u); ++ ++ /* Handle the case that U contains no limb. */ ++ if (u->nlimbs == 0) ++ return -(limb != 0); ++ ++ /* Handle the case that U is negative. */ ++ if (u->sign) ++ return -1; ++ ++ if (u->nlimbs == 1) ++ { ++ /* Handle the case that U contains exactly one limb. */ ++ ++ if (u->d[0] > limb) ++ return 1; ++ if (u->d[0] < limb) ++ return -1; ++ return 0; ++ } ++ else ++ /* Handle the case that U contains more than one limb. */ ++ return 1; ++} ++ ++ ++int ++gcry_mpi_cmp (gcry_mpi_t u, gcry_mpi_t v) ++{ ++ mpi_size_t usize; ++ mpi_size_t vsize; ++ int cmp; ++ ++ if (mpi_is_opaque (u) || mpi_is_opaque (v)) ++ { ++ if (mpi_is_opaque (u) && !mpi_is_opaque (v)) ++ return -1; ++ if (!mpi_is_opaque (u) && mpi_is_opaque (v)) ++ return 1; ++ if (!u->sign && !v->sign) ++ return 0; /* Empty buffers are identical. */ ++ if (u->sign < v->sign) ++ return -1; ++ if (u->sign > v->sign) ++ return 1; ++ return memcmp (u->d, v->d, (u->sign+7)/8); ++ } ++ else ++ { ++ _gcry_mpi_normalize (u); ++ _gcry_mpi_normalize (v); ++ ++ usize = u->nlimbs; ++ vsize = v->nlimbs; ++ ++ /* Compare sign bits. */ ++ ++ if (!u->sign && v->sign) ++ return 1; ++ if (u->sign && !v->sign) ++ return -1; ++ ++ /* U and V are either both positive or both negative. */ ++ ++ if (usize != vsize && !u->sign && !v->sign) ++ return usize - vsize; ++ if (usize != vsize && u->sign && v->sign) ++ return vsize + usize; ++ if (!usize ) ++ return 0; ++ if (!(cmp = _gcry_mpih_cmp (u->d, v->d, usize))) ++ return 0; ++ if ((cmp < 0?1:0) == (u->sign?1:0)) ++ return 1; ++ } ++ return -1; ++} +diff --git a/grub-core/lib/libgcrypt/mpi/mpi-div.c b/grub-core/lib/libgcrypt/mpi/mpi-div.c +new file mode 100644 +index 0000000..a6ee300 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/mpi-div.c +@@ -0,0 +1,355 @@ ++/* mpi-div.c - MPI functions ++ * Copyright (C) 1994, 1996, 1998, 2001, 2002, ++ * 2003 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ * ++ * Note: This code is heavily based on the GNU MP Library. ++ * Actually it's the same code with only minor changes in the ++ * way the data is stored; this is to support the abstraction ++ * of an optional secure memory allocation which may be used ++ * to avoid revealing of sensitive data due to paging etc. ++ */ ++ ++#include ++#include ++#include ++#include "mpi-internal.h" ++#include "longlong.h" ++#include "g10lib.h" ++ ++ ++void ++_gcry_mpi_fdiv_r( gcry_mpi_t rem, gcry_mpi_t dividend, gcry_mpi_t divisor ) ++{ ++ int divisor_sign = divisor->sign; ++ gcry_mpi_t temp_divisor = NULL; ++ ++ /* We need the original value of the divisor after the remainder has been ++ * preliminary calculated. We have to copy it to temporary space if it's ++ * the same variable as REM. */ ++ if( rem == divisor ) { ++ temp_divisor = mpi_copy( divisor ); ++ divisor = temp_divisor; ++ } ++ ++ _gcry_mpi_tdiv_r( rem, dividend, divisor ); ++ ++ if( ((divisor_sign?1:0) ^ (dividend->sign?1:0)) && rem->nlimbs ) ++ gcry_mpi_add( rem, rem, divisor); ++ ++ if( temp_divisor ) ++ mpi_free(temp_divisor); ++} ++ ++ ++ ++/**************** ++ * Division rounding the quotient towards -infinity. ++ * The remainder gets the same sign as the denominator. ++ * rem is optional ++ */ ++ ++ulong ++_gcry_mpi_fdiv_r_ui( gcry_mpi_t rem, gcry_mpi_t dividend, ulong divisor ) ++{ ++ mpi_limb_t rlimb; ++ ++ rlimb = _gcry_mpih_mod_1( dividend->d, dividend->nlimbs, divisor ); ++ if( rlimb && dividend->sign ) ++ rlimb = divisor - rlimb; ++ ++ if( rem ) { ++ rem->d[0] = rlimb; ++ rem->nlimbs = rlimb? 1:0; ++ } ++ return rlimb; ++} ++ ++ ++void ++_gcry_mpi_fdiv_q( gcry_mpi_t quot, gcry_mpi_t dividend, gcry_mpi_t divisor ) ++{ ++ gcry_mpi_t tmp = mpi_alloc( mpi_get_nlimbs(quot) ); ++ _gcry_mpi_fdiv_qr( quot, tmp, dividend, divisor); ++ mpi_free(tmp); ++} ++ ++void ++_gcry_mpi_fdiv_qr( gcry_mpi_t quot, gcry_mpi_t rem, gcry_mpi_t dividend, gcry_mpi_t divisor ) ++{ ++ int divisor_sign = divisor->sign; ++ gcry_mpi_t temp_divisor = NULL; ++ ++ if( quot == divisor || rem == divisor ) { ++ temp_divisor = mpi_copy( divisor ); ++ divisor = temp_divisor; ++ } ++ ++ _gcry_mpi_tdiv_qr( quot, rem, dividend, divisor ); ++ ++ if( (divisor_sign ^ dividend->sign) && rem->nlimbs ) { ++ gcry_mpi_sub_ui( quot, quot, 1 ); ++ gcry_mpi_add( rem, rem, divisor); ++ } ++ ++ if( temp_divisor ) ++ mpi_free(temp_divisor); ++} ++ ++ ++/* If den == quot, den needs temporary storage. ++ * If den == rem, den needs temporary storage. ++ * If num == quot, num needs temporary storage. ++ * If den has temporary storage, it can be normalized while being copied, ++ * i.e no extra storage should be allocated. ++ */ ++ ++void ++_gcry_mpi_tdiv_r( gcry_mpi_t rem, gcry_mpi_t num, gcry_mpi_t den) ++{ ++ _gcry_mpi_tdiv_qr(NULL, rem, num, den ); ++} ++ ++void ++_gcry_mpi_tdiv_qr( gcry_mpi_t quot, gcry_mpi_t rem, gcry_mpi_t num, gcry_mpi_t den) ++{ ++ mpi_ptr_t np, dp; ++ mpi_ptr_t qp, rp; ++ mpi_size_t nsize = num->nlimbs; ++ mpi_size_t dsize = den->nlimbs; ++ mpi_size_t qsize, rsize; ++ mpi_size_t sign_remainder = num->sign; ++ mpi_size_t sign_quotient = num->sign ^ den->sign; ++ unsigned normalization_steps; ++ mpi_limb_t q_limb; ++ mpi_ptr_t marker[5]; ++ unsigned int marker_nlimbs[5]; ++ int markidx=0; ++ ++ /* Ensure space is enough for quotient and remainder. ++ * We need space for an extra limb in the remainder, because it's ++ * up-shifted (normalized) below. */ ++ rsize = nsize + 1; ++ mpi_resize( rem, rsize); ++ ++ qsize = rsize - dsize; /* qsize cannot be bigger than this. */ ++ if( qsize <= 0 ) { ++ if( num != rem ) { ++ rem->nlimbs = num->nlimbs; ++ rem->sign = num->sign; ++ MPN_COPY(rem->d, num->d, nsize); ++ } ++ if( quot ) { ++ /* This needs to follow the assignment to rem, in case the ++ * numerator and quotient are the same. */ ++ quot->nlimbs = 0; ++ quot->sign = 0; ++ } ++ return; ++ } ++ ++ if( quot ) ++ mpi_resize( quot, qsize); ++ ++ /* Read pointers here, when reallocation is finished. */ ++ np = num->d; ++ dp = den->d; ++ rp = rem->d; ++ ++ /* Optimize division by a single-limb divisor. */ ++ if( dsize == 1 ) { ++ mpi_limb_t rlimb; ++ if( quot ) { ++ qp = quot->d; ++ rlimb = _gcry_mpih_divmod_1( qp, np, nsize, dp[0] ); ++ qsize -= qp[qsize - 1] == 0; ++ quot->nlimbs = qsize; ++ quot->sign = sign_quotient; ++ } ++ else ++ rlimb = _gcry_mpih_mod_1( np, nsize, dp[0] ); ++ rp[0] = rlimb; ++ rsize = rlimb != 0?1:0; ++ rem->nlimbs = rsize; ++ rem->sign = sign_remainder; ++ return; ++ } ++ ++ ++ if( quot ) { ++ qp = quot->d; ++ /* Make sure QP and NP point to different objects. Otherwise the ++ * numerator would be gradually overwritten by the quotient limbs. */ ++ if(qp == np) { /* Copy NP object to temporary space. */ ++ marker_nlimbs[markidx] = nsize; ++ np = marker[markidx++] = mpi_alloc_limb_space(nsize, ++ mpi_is_secure(quot)); ++ MPN_COPY(np, qp, nsize); ++ } ++ } ++ else /* Put quotient at top of remainder. */ ++ qp = rp + dsize; ++ ++ count_leading_zeros( normalization_steps, dp[dsize - 1] ); ++ ++ /* Normalize the denominator, i.e. make its most significant bit set by ++ * shifting it NORMALIZATION_STEPS bits to the left. Also shift the ++ * numerator the same number of steps (to keep the quotient the same!). ++ */ ++ if( normalization_steps ) { ++ mpi_ptr_t tp; ++ mpi_limb_t nlimb; ++ ++ /* Shift up the denominator setting the most significant bit of ++ * the most significant word. Use temporary storage not to clobber ++ * the original contents of the denominator. */ ++ marker_nlimbs[markidx] = dsize; ++ tp = marker[markidx++] = mpi_alloc_limb_space(dsize,mpi_is_secure(den)); ++ _gcry_mpih_lshift( tp, dp, dsize, normalization_steps ); ++ dp = tp; ++ ++ /* Shift up the numerator, possibly introducing a new most ++ * significant word. Move the shifted numerator in the remainder ++ * meanwhile. */ ++ nlimb = _gcry_mpih_lshift(rp, np, nsize, normalization_steps); ++ if( nlimb ) { ++ rp[nsize] = nlimb; ++ rsize = nsize + 1; ++ } ++ else ++ rsize = nsize; ++ } ++ else { ++ /* The denominator is already normalized, as required. Copy it to ++ * temporary space if it overlaps with the quotient or remainder. */ ++ if( dp == rp || (quot && (dp == qp))) { ++ mpi_ptr_t tp; ++ ++ marker_nlimbs[markidx] = dsize; ++ tp = marker[markidx++] = mpi_alloc_limb_space(dsize, ++ mpi_is_secure(den)); ++ MPN_COPY( tp, dp, dsize ); ++ dp = tp; ++ } ++ ++ /* Move the numerator to the remainder. */ ++ if( rp != np ) ++ MPN_COPY(rp, np, nsize); ++ ++ rsize = nsize; ++ } ++ ++ q_limb = _gcry_mpih_divrem( qp, 0, rp, rsize, dp, dsize ); ++ ++ if( quot ) { ++ qsize = rsize - dsize; ++ if(q_limb) { ++ qp[qsize] = q_limb; ++ qsize += 1; ++ } ++ ++ quot->nlimbs = qsize; ++ quot->sign = sign_quotient; ++ } ++ ++ rsize = dsize; ++ MPN_NORMALIZE (rp, rsize); ++ ++ if( normalization_steps && rsize ) { ++ _gcry_mpih_rshift(rp, rp, rsize, normalization_steps); ++ rsize -= rp[rsize - 1] == 0?1:0; ++ } ++ ++ rem->nlimbs = rsize; ++ rem->sign = sign_remainder; ++ while( markidx ) ++ { ++ markidx--; ++ _gcry_mpi_free_limb_space (marker[markidx], marker_nlimbs[markidx]); ++ } ++} ++ ++void ++_gcry_mpi_tdiv_q_2exp( gcry_mpi_t w, gcry_mpi_t u, unsigned int count ) ++{ ++ mpi_size_t usize, wsize; ++ mpi_size_t limb_cnt; ++ ++ usize = u->nlimbs; ++ limb_cnt = count / BITS_PER_MPI_LIMB; ++ wsize = usize - limb_cnt; ++ if( limb_cnt >= usize ) ++ w->nlimbs = 0; ++ else { ++ mpi_ptr_t wp; ++ mpi_ptr_t up; ++ ++ RESIZE_IF_NEEDED( w, wsize ); ++ wp = w->d; ++ up = u->d; ++ ++ count %= BITS_PER_MPI_LIMB; ++ if( count ) { ++ _gcry_mpih_rshift( wp, up + limb_cnt, wsize, count ); ++ wsize -= !wp[wsize - 1]; ++ } ++ else { ++ MPN_COPY_INCR( wp, up + limb_cnt, wsize); ++ } ++ ++ w->nlimbs = wsize; ++ } ++} ++ ++/**************** ++ * Check whether dividend is divisible by divisor ++ * (note: divisor must fit into a limb) ++ */ ++int ++_gcry_mpi_divisible_ui(gcry_mpi_t dividend, ulong divisor ) ++{ ++ return !_gcry_mpih_mod_1( dividend->d, dividend->nlimbs, divisor ); ++} ++ ++ ++void ++gcry_mpi_div (gcry_mpi_t quot, gcry_mpi_t rem, gcry_mpi_t dividend, gcry_mpi_t divisor, int round) ++{ ++ if (!round) ++ { ++ if (!rem) ++ { ++ gcry_mpi_t tmp = mpi_alloc (mpi_get_nlimbs(quot)); ++ _gcry_mpi_tdiv_qr (quot, tmp, dividend, divisor); ++ mpi_free (tmp); ++ } ++ else ++ _gcry_mpi_tdiv_qr (quot, rem, dividend, divisor); ++ } ++ else if (round < 0) ++ { ++ if (!rem) ++ _gcry_mpi_fdiv_q (quot, dividend, divisor); ++ else if (!quot) ++ _gcry_mpi_fdiv_r (rem, dividend, divisor); ++ else ++ _gcry_mpi_fdiv_qr (quot, rem, dividend, divisor); ++ } ++ else ++ log_bug ("mpi rounding to ceiling not yet implemented\n"); ++} +diff --git a/grub-core/lib/libgcrypt/mpi/mpi-gcd.c b/grub-core/lib/libgcrypt/mpi/mpi-gcd.c +new file mode 100644 +index 0000000..5cbefa1 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/mpi-gcd.c +@@ -0,0 +1,51 @@ ++/* mpi-gcd.c - MPI functions ++ * Copyright (C) 1998, 2001, 2002, 2003 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ */ ++ ++#include ++#include ++#include ++#include "mpi-internal.h" ++ ++/**************** ++ * Find the greatest common divisor G of A and B. ++ * Return: true if this 1, false in all other cases ++ */ ++int ++gcry_mpi_gcd( gcry_mpi_t g, gcry_mpi_t xa, gcry_mpi_t xb ) ++{ ++ gcry_mpi_t a, b; ++ ++ a = mpi_copy(xa); ++ b = mpi_copy(xb); ++ ++ /* TAOCP Vol II, 4.5.2, Algorithm A */ ++ a->sign = 0; ++ b->sign = 0; ++ while( gcry_mpi_cmp_ui( b, 0 ) ) { ++ _gcry_mpi_fdiv_r( g, a, b ); /* g used as temorary variable */ ++ mpi_set(a,b); ++ mpi_set(b,g); ++ } ++ mpi_set(g, a); ++ ++ mpi_free(a); ++ mpi_free(b); ++ return !gcry_mpi_cmp_ui( g, 1); ++} +diff --git a/grub-core/lib/libgcrypt/mpi/mpi-inline.c b/grub-core/lib/libgcrypt/mpi/mpi-inline.c +new file mode 100644 +index 0000000..39e2222 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/mpi-inline.c +@@ -0,0 +1,35 @@ ++/* mpi-inline.c ++ * Copyright (C) 1999, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ */ ++ ++#include ++#include ++#include ++ ++/* put the inline functions as real functions into the lib */ ++#define G10_MPI_INLINE_DECL ++ ++#include "mpi-internal.h" ++ ++/* always include the header because it is only ++ * included by mpi-internal if __GCC__ is defined but we ++ * need it here in all cases and the above definition of ++ * of the macro allows us to do so ++ */ ++#include "mpi-inline.h" +diff --git a/grub-core/lib/libgcrypt/mpi/mpi-inline.h b/grub-core/lib/libgcrypt/mpi/mpi-inline.h +new file mode 100644 +index 0000000..88d9f56 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/mpi-inline.h +@@ -0,0 +1,154 @@ ++/* mpi-inline.h - Internal to the Multi Precision Integers ++ * Copyright (C) 1994, 1996, 1998, 1999, ++ * 2001, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ * ++ * Note: This code is heavily based on the GNU MP Library. ++ * Actually it's the same code with only minor changes in the ++ * way the data is stored; this is to support the abstraction ++ * of an optional secure memory allocation which may be used ++ * to avoid revealing of sensitive data due to paging etc. ++ */ ++ ++#ifndef G10_MPI_INLINE_H ++#define G10_MPI_INLINE_H ++ ++#ifndef G10_MPI_INLINE_DECL ++#define G10_MPI_INLINE_DECL extern __inline__ ++#endif ++ ++G10_MPI_INLINE_DECL mpi_limb_t ++_gcry_mpih_add_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, ++ mpi_size_t s1_size, mpi_limb_t s2_limb) ++{ ++ mpi_limb_t x; ++ ++ x = *s1_ptr++; ++ s2_limb += x; ++ *res_ptr++ = s2_limb; ++ if( s2_limb < x ) { /* sum is less than the left operand: handle carry */ ++ while( --s1_size ) { ++ x = *s1_ptr++ + 1; /* add carry */ ++ *res_ptr++ = x; /* and store */ ++ if( x ) /* not 0 (no overflow): we can stop */ ++ goto leave; ++ } ++ return 1; /* return carry (size of s1 to small) */ ++ } ++ ++ leave: ++ if( res_ptr != s1_ptr ) { /* not the same variable */ ++ mpi_size_t i; /* copy the rest */ ++ for( i=0; i < s1_size-1; i++ ) ++ res_ptr[i] = s1_ptr[i]; ++ } ++ return 0; /* no carry */ ++} ++ ++ ++ ++G10_MPI_INLINE_DECL mpi_limb_t ++_gcry_mpih_add(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size, ++ mpi_ptr_t s2_ptr, mpi_size_t s2_size) ++{ ++ mpi_limb_t cy = 0; ++ ++ if( s2_size ) ++ cy = _gcry_mpih_add_n( res_ptr, s1_ptr, s2_ptr, s2_size ); ++ ++ if( s1_size - s2_size ) ++ cy = _gcry_mpih_add_1( res_ptr + s2_size, s1_ptr + s2_size, ++ s1_size - s2_size, cy); ++ return cy; ++} ++ ++ ++G10_MPI_INLINE_DECL mpi_limb_t ++_gcry_mpih_sub_1(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, ++ mpi_size_t s1_size, mpi_limb_t s2_limb ) ++{ ++ mpi_limb_t x; ++ ++ x = *s1_ptr++; ++ s2_limb = x - s2_limb; ++ *res_ptr++ = s2_limb; ++ if( s2_limb > x ) { ++ while( --s1_size ) { ++ x = *s1_ptr++; ++ *res_ptr++ = x - 1; ++ if( x ) ++ goto leave; ++ } ++ return 1; ++ } ++ ++ leave: ++ if( res_ptr != s1_ptr ) { ++ mpi_size_t i; ++ for( i=0; i < s1_size-1; i++ ) ++ res_ptr[i] = s1_ptr[i]; ++ } ++ return 0; ++} ++ ++ ++ ++G10_MPI_INLINE_DECL mpi_limb_t ++_gcry_mpih_sub( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size, ++ mpi_ptr_t s2_ptr, mpi_size_t s2_size) ++{ ++ mpi_limb_t cy = 0; ++ ++ if( s2_size ) ++ cy = _gcry_mpih_sub_n(res_ptr, s1_ptr, s2_ptr, s2_size); ++ ++ if( s1_size - s2_size ) ++ cy = _gcry_mpih_sub_1(res_ptr + s2_size, s1_ptr + s2_size, ++ s1_size - s2_size, cy); ++ return cy; ++} ++ ++/**************** ++ * Compare OP1_PTR/OP1_SIZE with OP2_PTR/OP2_SIZE. ++ * There are no restrictions on the relative sizes of ++ * the two arguments. ++ * Return 1 if OP1 > OP2, 0 if they are equal, and -1 if OP1 < OP2. ++ */ ++G10_MPI_INLINE_DECL int ++_gcry_mpih_cmp( mpi_ptr_t op1_ptr, mpi_ptr_t op2_ptr, mpi_size_t size ) ++{ ++ mpi_size_t i; ++ mpi_limb_t op1_word, op2_word; ++ ++ for( i = size - 1; i >= 0 ; i--) { ++ op1_word = op1_ptr[i]; ++ op2_word = op2_ptr[i]; ++ if( op1_word != op2_word ) ++ goto diff; ++ } ++ return 0; ++ ++ diff: ++ /* This can *not* be simplified to ++ * op2_word - op2_word ++ * since that expression might give signed overflow. */ ++ return (op1_word > op2_word) ? 1 : -1; ++} ++ ++ ++#endif /*G10_MPI_INLINE_H*/ +diff --git a/grub-core/lib/libgcrypt/mpi/mpi-internal.h b/grub-core/lib/libgcrypt/mpi/mpi-internal.h +new file mode 100644 +index 0000000..e75b7c6 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/mpi-internal.h +@@ -0,0 +1,277 @@ ++/* mpi-internal.h - Internal to the Multi Precision Integers ++ * Copyright (C) 1994, 1996, 1998, 2000, 2002, ++ * 2003 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ * ++ * Note: This code is heavily based on the GNU MP Library. ++ * Actually it's the same code with only minor changes in the ++ * way the data is stored; this is to support the abstraction ++ * of an optional secure memory allocation which may be used ++ * to avoid revealing of sensitive data due to paging etc. ++ */ ++ ++#ifndef G10_MPI_INTERNAL_H ++#define G10_MPI_INTERNAL_H ++ ++#include "mpi-asm-defs.h" ++ ++#ifndef BITS_PER_MPI_LIMB ++#if BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_INT ++ typedef unsigned int mpi_limb_t; ++ typedef signed int mpi_limb_signed_t; ++#elif BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_LONG ++ typedef unsigned long int mpi_limb_t; ++ typedef signed long int mpi_limb_signed_t; ++#elif BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_LONG_LONG ++ typedef unsigned long long int mpi_limb_t; ++ typedef signed long long int mpi_limb_signed_t; ++#elif BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_SHORT ++ typedef unsigned short int mpi_limb_t; ++ typedef signed short int mpi_limb_signed_t; ++#else ++#error BYTES_PER_MPI_LIMB does not match any C type ++#endif ++#define BITS_PER_MPI_LIMB (8*BYTES_PER_MPI_LIMB) ++#endif /*BITS_PER_MPI_LIMB*/ ++ ++#include "mpi.h" ++ ++/* If KARATSUBA_THRESHOLD is not already defined, define it to a ++ * value which is good on most machines. */ ++ ++/* tested 4, 16, 32 and 64, where 16 gave the best performance when ++ * checking a 768 and a 1024 bit ElGamal signature. ++ * (wk 22.12.97) */ ++#ifndef KARATSUBA_THRESHOLD ++#define KARATSUBA_THRESHOLD 16 ++#endif ++ ++/* The code can't handle KARATSUBA_THRESHOLD smaller than 2. */ ++#if KARATSUBA_THRESHOLD < 2 ++#undef KARATSUBA_THRESHOLD ++#define KARATSUBA_THRESHOLD 2 ++#endif ++ ++ ++typedef mpi_limb_t *mpi_ptr_t; /* pointer to a limb */ ++typedef int mpi_size_t; /* (must be a signed type) */ ++ ++#define ABS(x) (x >= 0 ? x : -x) ++#define MIN(l,o) ((l) < (o) ? (l) : (o)) ++#define MAX(h,i) ((h) > (i) ? (h) : (i)) ++#define RESIZE_IF_NEEDED(a,b) \ ++ do { \ ++ if( (a)->alloced < (b) ) \ ++ mpi_resize((a), (b)); \ ++ } while(0) ++ ++/* Copy N limbs from S to D. */ ++#define MPN_COPY( d, s, n) \ ++ do { \ ++ mpi_size_t _i; \ ++ for( _i = 0; _i < (n); _i++ ) \ ++ (d)[_i] = (s)[_i]; \ ++ } while(0) ++ ++#define MPN_COPY_INCR( d, s, n) \ ++ do { \ ++ mpi_size_t _i; \ ++ for( _i = 0; _i < (n); _i++ ) \ ++ (d)[_i] = (d)[_i]; \ ++ } while (0) ++ ++#define MPN_COPY_DECR( d, s, n ) \ ++ do { \ ++ mpi_size_t _i; \ ++ for( _i = (n)-1; _i >= 0; _i--) \ ++ (d)[_i] = (s)[_i]; \ ++ } while(0) ++ ++/* Zero N limbs at D */ ++#define MPN_ZERO(d, n) \ ++ do { \ ++ int _i; \ ++ for( _i = 0; _i < (n); _i++ ) \ ++ (d)[_i] = 0; \ ++ } while (0) ++ ++#define MPN_NORMALIZE(d, n) \ ++ do { \ ++ while( (n) > 0 ) { \ ++ if( (d)[(n)-1] ) \ ++ break; \ ++ (n)--; \ ++ } \ ++ } while(0) ++ ++#define MPN_NORMALIZE_NOT_ZERO(d, n) \ ++ do { \ ++ for(;;) { \ ++ if( (d)[(n)-1] ) \ ++ break; \ ++ (n)--; \ ++ } \ ++ } while(0) ++ ++#define MPN_MUL_N_RECURSE(prodp, up, vp, size, tspace) \ ++ do { \ ++ if( (size) < KARATSUBA_THRESHOLD ) \ ++ mul_n_basecase (prodp, up, vp, size); \ ++ else \ ++ mul_n (prodp, up, vp, size, tspace); \ ++ } while (0); ++ ++ ++/* Divide the two-limb number in (NH,,NL) by D, with DI being the largest ++ * limb not larger than (2**(2*BITS_PER_MP_LIMB))/D - (2**BITS_PER_MP_LIMB). ++ * If this would yield overflow, DI should be the largest possible number ++ * (i.e., only ones). For correct operation, the most significant bit of D ++ * has to be set. Put the quotient in Q and the remainder in R. ++ */ ++#define UDIV_QRNND_PREINV(q, r, nh, nl, d, di) \ ++ do { \ ++ mpi_limb_t _q, _ql, _r; \ ++ mpi_limb_t _xh, _xl; \ ++ umul_ppmm (_q, _ql, (nh), (di)); \ ++ _q += (nh); /* DI is 2**BITS_PER_MPI_LIMB too small */ \ ++ umul_ppmm (_xh, _xl, _q, (d)); \ ++ sub_ddmmss (_xh, _r, (nh), (nl), _xh, _xl); \ ++ if( _xh ) { \ ++ sub_ddmmss (_xh, _r, _xh, _r, 0, (d)); \ ++ _q++; \ ++ if( _xh) { \ ++ sub_ddmmss (_xh, _r, _xh, _r, 0, (d)); \ ++ _q++; \ ++ } \ ++ } \ ++ if( _r >= (d) ) { \ ++ _r -= (d); \ ++ _q++; \ ++ } \ ++ (r) = _r; \ ++ (q) = _q; \ ++ } while (0) ++ ++ ++/*-- mpiutil.c --*/ ++#define mpi_alloc_limb_space(n,f) _gcry_mpi_alloc_limb_space((n),(f)) ++mpi_ptr_t _gcry_mpi_alloc_limb_space( unsigned nlimbs, int sec ); ++void _gcry_mpi_free_limb_space( mpi_ptr_t a, unsigned int nlimbs ); ++void _gcry_mpi_assign_limb_space( gcry_mpi_t a, mpi_ptr_t ap, unsigned nlimbs ); ++ ++/*-- mpi-bit.c --*/ ++#define mpi_rshift_limbs(a,n) _gcry_mpi_rshift_limbs ((a), (n)) ++#define mpi_lshift_limbs(a,n) _gcry_mpi_lshift_limbs ((a), (n)) ++ ++void _gcry_mpi_rshift_limbs( gcry_mpi_t a, unsigned int count ); ++void _gcry_mpi_lshift_limbs( gcry_mpi_t a, unsigned int count ); ++ ++ ++/*-- mpih-add.c --*/ ++mpi_limb_t _gcry_mpih_add_1(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, ++ mpi_size_t s1_size, mpi_limb_t s2_limb ); ++mpi_limb_t _gcry_mpih_add_n( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, ++ mpi_ptr_t s2_ptr, mpi_size_t size); ++mpi_limb_t _gcry_mpih_add(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size, ++ mpi_ptr_t s2_ptr, mpi_size_t s2_size); ++ ++/*-- mpih-sub.c --*/ ++mpi_limb_t _gcry_mpih_sub_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, ++ mpi_size_t s1_size, mpi_limb_t s2_limb ); ++mpi_limb_t _gcry_mpih_sub_n( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, ++ mpi_ptr_t s2_ptr, mpi_size_t size); ++mpi_limb_t _gcry_mpih_sub(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size, ++ mpi_ptr_t s2_ptr, mpi_size_t s2_size); ++ ++/*-- mpih-cmp.c --*/ ++int _gcry_mpih_cmp( mpi_ptr_t op1_ptr, mpi_ptr_t op2_ptr, mpi_size_t size ); ++ ++/*-- mpih-mul.c --*/ ++ ++struct karatsuba_ctx { ++ struct karatsuba_ctx *next; ++ mpi_ptr_t tspace; ++ unsigned int tspace_nlimbs; ++ mpi_size_t tspace_size; ++ mpi_ptr_t tp; ++ unsigned int tp_nlimbs; ++ mpi_size_t tp_size; ++}; ++ ++void _gcry_mpih_release_karatsuba_ctx( struct karatsuba_ctx *ctx ); ++ ++mpi_limb_t _gcry_mpih_addmul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, ++ mpi_size_t s1_size, mpi_limb_t s2_limb); ++mpi_limb_t _gcry_mpih_submul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, ++ mpi_size_t s1_size, mpi_limb_t s2_limb); ++void _gcry_mpih_mul_n( mpi_ptr_t prodp, mpi_ptr_t up, mpi_ptr_t vp, ++ mpi_size_t size); ++mpi_limb_t _gcry_mpih_mul( mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t usize, ++ mpi_ptr_t vp, mpi_size_t vsize); ++void _gcry_mpih_sqr_n_basecase( mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t size ); ++void _gcry_mpih_sqr_n( mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t size, ++ mpi_ptr_t tspace); ++ ++void _gcry_mpih_mul_karatsuba_case( mpi_ptr_t prodp, ++ mpi_ptr_t up, mpi_size_t usize, ++ mpi_ptr_t vp, mpi_size_t vsize, ++ struct karatsuba_ctx *ctx ); ++ ++ ++/*-- mpih-mul_1.c (or xxx/cpu/ *.S) --*/ ++mpi_limb_t _gcry_mpih_mul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, ++ mpi_size_t s1_size, mpi_limb_t s2_limb); ++ ++/*-- mpih-div.c --*/ ++mpi_limb_t _gcry_mpih_mod_1(mpi_ptr_t dividend_ptr, mpi_size_t dividend_size, ++ mpi_limb_t divisor_limb); ++mpi_limb_t _gcry_mpih_divrem( mpi_ptr_t qp, mpi_size_t qextra_limbs, ++ mpi_ptr_t np, mpi_size_t nsize, ++ mpi_ptr_t dp, mpi_size_t dsize); ++mpi_limb_t _gcry_mpih_divmod_1( mpi_ptr_t quot_ptr, ++ mpi_ptr_t dividend_ptr, mpi_size_t dividend_size, ++ mpi_limb_t divisor_limb); ++ ++/*-- mpih-shift.c --*/ ++mpi_limb_t _gcry_mpih_lshift( mpi_ptr_t wp, mpi_ptr_t up, mpi_size_t usize, ++ unsigned cnt); ++mpi_limb_t _gcry_mpih_rshift( mpi_ptr_t wp, mpi_ptr_t up, mpi_size_t usize, ++ unsigned cnt); ++ ++ ++/* Define stuff for longlong.h. */ ++#define W_TYPE_SIZE BITS_PER_MPI_LIMB ++ typedef mpi_limb_t UWtype; ++ typedef unsigned int UHWtype; ++#if defined (__GNUC__) ++ typedef unsigned int UQItype __attribute__ ((mode (QI))); ++ typedef int SItype __attribute__ ((mode (SI))); ++ typedef unsigned int USItype __attribute__ ((mode (SI))); ++ typedef int DItype __attribute__ ((mode (DI))); ++ typedef unsigned int UDItype __attribute__ ((mode (DI))); ++#else ++ typedef unsigned char UQItype; ++ typedef long SItype; ++ typedef unsigned long USItype; ++#endif ++ ++#ifdef __GNUC__ ++#include "mpi-inline.h" ++#endif ++ ++#endif /*G10_MPI_INTERNAL_H*/ +diff --git a/grub-core/lib/libgcrypt/mpi/mpi-inv.c b/grub-core/lib/libgcrypt/mpi/mpi-inv.c +new file mode 100644 +index 0000000..5d26946 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/mpi-inv.c +@@ -0,0 +1,267 @@ ++/* mpi-inv.c - MPI functions ++ * Copyright (C) 1998, 2001, 2002, 2003 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, see . ++ */ ++ ++#include ++#include ++#include ++#include "mpi-internal.h" ++#include "g10lib.h" ++ ++/**************** ++ * Calculate the multiplicative inverse X of A mod N ++ * That is: Find the solution x for ++ * 1 = (a*x) mod n ++ */ ++int ++gcry_mpi_invm( gcry_mpi_t x, gcry_mpi_t a, gcry_mpi_t n ) ++{ ++#if 0 ++ gcry_mpi_t u, v, u1, u2, u3, v1, v2, v3, q, t1, t2, t3; ++ gcry_mpi_t ta, tb, tc; ++ ++ u = mpi_copy(a); ++ v = mpi_copy(n); ++ u1 = mpi_alloc_set_ui(1); ++ u2 = mpi_alloc_set_ui(0); ++ u3 = mpi_copy(u); ++ v1 = mpi_alloc_set_ui(0); ++ v2 = mpi_alloc_set_ui(1); ++ v3 = mpi_copy(v); ++ q = mpi_alloc( mpi_get_nlimbs(u)+1 ); ++ t1 = mpi_alloc( mpi_get_nlimbs(u)+1 ); ++ t2 = mpi_alloc( mpi_get_nlimbs(u)+1 ); ++ t3 = mpi_alloc( mpi_get_nlimbs(u)+1 ); ++ while( mpi_cmp_ui( v3, 0 ) ) { ++ mpi_fdiv_q( q, u3, v3 ); ++ mpi_mul(t1, v1, q); mpi_mul(t2, v2, q); mpi_mul(t3, v3, q); ++ mpi_sub(t1, u1, t1); mpi_sub(t2, u2, t2); mpi_sub(t3, u3, t3); ++ mpi_set(u1, v1); mpi_set(u2, v2); mpi_set(u3, v3); ++ mpi_set(v1, t1); mpi_set(v2, t2); mpi_set(v3, t3); ++ } ++ /* log_debug("result:\n"); ++ log_mpidump("q =", q ); ++ log_mpidump("u1=", u1); ++ log_mpidump("u2=", u2); ++ log_mpidump("u3=", u3); ++ log_mpidump("v1=", v1); ++ log_mpidump("v2=", v2); */ ++ mpi_set(x, u1); ++ ++ mpi_free(u1); ++ mpi_free(u2); ++ mpi_free(u3); ++ mpi_free(v1); ++ mpi_free(v2); ++ mpi_free(v3); ++ mpi_free(q); ++ mpi_free(t1); ++ mpi_free(t2); ++ mpi_free(t3); ++ mpi_free(u); ++ mpi_free(v); ++#elif 0 ++ /* Extended Euclid's algorithm (See TAOCP Vol II, 4.5.2, Alg X) ++ * modified according to Michael Penk's solution for Exercise 35 */ ++ ++ /* FIXME: we can simplify this in most cases (see Knuth) */ ++ gcry_mpi_t u, v, u1, u2, u3, v1, v2, v3, t1, t2, t3; ++ unsigned k; ++ int sign; ++ ++ u = mpi_copy(a); ++ v = mpi_copy(n); ++ for(k=0; !mpi_test_bit(u,0) && !mpi_test_bit(v,0); k++ ) { ++ mpi_rshift(u, u, 1); ++ mpi_rshift(v, v, 1); ++ } ++ ++ ++ u1 = mpi_alloc_set_ui(1); ++ u2 = mpi_alloc_set_ui(0); ++ u3 = mpi_copy(u); ++ v1 = mpi_copy(v); /* !-- used as const 1 */ ++ v2 = mpi_alloc( mpi_get_nlimbs(u) ); mpi_sub( v2, u1, u ); ++ v3 = mpi_copy(v); ++ if( mpi_test_bit(u, 0) ) { /* u is odd */ ++ t1 = mpi_alloc_set_ui(0); ++ t2 = mpi_alloc_set_ui(1); t2->sign = 1; ++ t3 = mpi_copy(v); t3->sign = !t3->sign; ++ goto Y4; ++ } ++ else { ++ t1 = mpi_alloc_set_ui(1); ++ t2 = mpi_alloc_set_ui(0); ++ t3 = mpi_copy(u); ++ } ++ do { ++ do { ++ if( mpi_test_bit(t1, 0) || mpi_test_bit(t2, 0) ) { /* one is odd */ ++ mpi_add(t1, t1, v); ++ mpi_sub(t2, t2, u); ++ } ++ mpi_rshift(t1, t1, 1); ++ mpi_rshift(t2, t2, 1); ++ mpi_rshift(t3, t3, 1); ++ Y4: ++ ; ++ } while( !mpi_test_bit( t3, 0 ) ); /* while t3 is even */ ++ ++ if( !t3->sign ) { ++ mpi_set(u1, t1); ++ mpi_set(u2, t2); ++ mpi_set(u3, t3); ++ } ++ else { ++ mpi_sub(v1, v, t1); ++ sign = u->sign; u->sign = !u->sign; ++ mpi_sub(v2, u, t2); ++ u->sign = sign; ++ sign = t3->sign; t3->sign = !t3->sign; ++ mpi_set(v3, t3); ++ t3->sign = sign; ++ } ++ mpi_sub(t1, u1, v1); ++ mpi_sub(t2, u2, v2); ++ mpi_sub(t3, u3, v3); ++ if( t1->sign ) { ++ mpi_add(t1, t1, v); ++ mpi_sub(t2, t2, u); ++ } ++ } while( mpi_cmp_ui( t3, 0 ) ); /* while t3 != 0 */ ++ /* mpi_lshift( u3, k ); */ ++ mpi_set(x, u1); ++ ++ mpi_free(u1); ++ mpi_free(u2); ++ mpi_free(u3); ++ mpi_free(v1); ++ mpi_free(v2); ++ mpi_free(v3); ++ mpi_free(t1); ++ mpi_free(t2); ++ mpi_free(t3); ++#else ++ /* Extended Euclid's algorithm (See TAOCP Vol II, 4.5.2, Alg X) ++ * modified according to Michael Penk's solution for Exercise 35 ++ * with further enhancement */ ++ gcry_mpi_t u, v, u1, u2=NULL, u3, v1, v2=NULL, v3, t1, t2=NULL, t3; ++ unsigned k; ++ int sign; ++ int odd ; ++ ++ u = mpi_copy(a); ++ v = mpi_copy(n); ++ ++ for(k=0; !mpi_test_bit(u,0) && !mpi_test_bit(v,0); k++ ) { ++ mpi_rshift(u, u, 1); ++ mpi_rshift(v, v, 1); ++ } ++ odd = mpi_test_bit(v,0); ++ ++ u1 = mpi_alloc_set_ui(1); ++ if( !odd ) ++ u2 = mpi_alloc_set_ui(0); ++ u3 = mpi_copy(u); ++ v1 = mpi_copy(v); ++ if( !odd ) { ++ v2 = mpi_alloc( mpi_get_nlimbs(u) ); ++ mpi_sub( v2, u1, u ); /* U is used as const 1 */ ++ } ++ v3 = mpi_copy(v); ++ if( mpi_test_bit(u, 0) ) { /* u is odd */ ++ t1 = mpi_alloc_set_ui(0); ++ if( !odd ) { ++ t2 = mpi_alloc_set_ui(1); t2->sign = 1; ++ } ++ t3 = mpi_copy(v); t3->sign = !t3->sign; ++ goto Y4; ++ } ++ else { ++ t1 = mpi_alloc_set_ui(1); ++ if( !odd ) ++ t2 = mpi_alloc_set_ui(0); ++ t3 = mpi_copy(u); ++ } ++ do { ++ do { ++ if( !odd ) { ++ if( mpi_test_bit(t1, 0) || mpi_test_bit(t2, 0) ) { /* one is odd */ ++ mpi_add(t1, t1, v); ++ mpi_sub(t2, t2, u); ++ } ++ mpi_rshift(t1, t1, 1); ++ mpi_rshift(t2, t2, 1); ++ mpi_rshift(t3, t3, 1); ++ } ++ else { ++ if( mpi_test_bit(t1, 0) ) ++ mpi_add(t1, t1, v); ++ mpi_rshift(t1, t1, 1); ++ mpi_rshift(t3, t3, 1); ++ } ++ Y4: ++ ; ++ } while( !mpi_test_bit( t3, 0 ) ); /* while t3 is even */ ++ ++ if( !t3->sign ) { ++ mpi_set(u1, t1); ++ if( !odd ) ++ mpi_set(u2, t2); ++ mpi_set(u3, t3); ++ } ++ else { ++ mpi_sub(v1, v, t1); ++ sign = u->sign; u->sign = !u->sign; ++ if( !odd ) ++ mpi_sub(v2, u, t2); ++ u->sign = sign; ++ sign = t3->sign; t3->sign = !t3->sign; ++ mpi_set(v3, t3); ++ t3->sign = sign; ++ } ++ mpi_sub(t1, u1, v1); ++ if( !odd ) ++ mpi_sub(t2, u2, v2); ++ mpi_sub(t3, u3, v3); ++ if( t1->sign ) { ++ mpi_add(t1, t1, v); ++ if( !odd ) ++ mpi_sub(t2, t2, u); ++ } ++ } while( mpi_cmp_ui( t3, 0 ) ); /* while t3 != 0 */ ++ /* mpi_lshift( u3, k ); */ ++ mpi_set(x, u1); ++ ++ mpi_free(u1); ++ mpi_free(v1); ++ mpi_free(t1); ++ if( !odd ) { ++ mpi_free(u2); ++ mpi_free(v2); ++ mpi_free(t2); ++ } ++ mpi_free(u3); ++ mpi_free(v3); ++ mpi_free(t3); ++ ++ mpi_free(u); ++ mpi_free(v); ++#endif ++ return 1; ++} +diff --git a/grub-core/lib/libgcrypt/mpi/mpi-mod.c b/grub-core/lib/libgcrypt/mpi/mpi-mod.c +new file mode 100644 +index 0000000..7ebfe6d +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/mpi-mod.c +@@ -0,0 +1,184 @@ ++/* mpi-mod.c - Modular reduction ++ Copyright (C) 1998, 1999, 2001, 2002, 2003, ++ 2007 Free Software Foundation, Inc. ++ ++ This file is part of Libgcrypt. ++ ++ Libgcrypt is free software; you can redistribute it and/or modify ++ it under the terms of the GNU Lesser General Public License as ++ published by the Free Software Foundation; either version 2.1 of ++ the License, or (at your option) any later version. ++ ++ Libgcrypt 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 Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser 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 ++#include ++ ++#include "mpi-internal.h" ++#include "longlong.h" ++#include "g10lib.h" ++ ++ ++/* Context used with Barrett reduction. */ ++struct barrett_ctx_s ++{ ++ gcry_mpi_t m; /* The modulus - may not be modified. */ ++ int m_copied; /* If true, M needs to be released. */ ++ int k; ++ gcry_mpi_t y; ++ gcry_mpi_t r1; /* Helper MPI. */ ++ gcry_mpi_t r2; /* Helper MPI. */ ++ gcry_mpi_t r3; /* Helper MPI allocated on demand. */ ++}; ++ ++ ++ ++void ++_gcry_mpi_mod (gcry_mpi_t rem, gcry_mpi_t dividend, gcry_mpi_t divisor) ++{ ++ _gcry_mpi_fdiv_r (rem, dividend, divisor); ++ rem->sign = 0; ++} ++ ++ ++/* This function returns a new context for Barrett based operations on ++ the modulus M. This context needs to be released using ++ _gcry_mpi_barrett_free. If COPY is true M will be transferred to ++ the context and the user may change M. If COPY is false, M may not ++ be changed until gcry_mpi_barrett_free has been called. */ ++mpi_barrett_t ++_gcry_mpi_barrett_init (gcry_mpi_t m, int copy) ++{ ++ mpi_barrett_t ctx; ++ gcry_mpi_t tmp; ++ ++ mpi_normalize (m); ++ ctx = gcry_xcalloc (1, sizeof *ctx); ++ ++ if (copy) ++ { ++ ctx->m = mpi_copy (m); ++ ctx->m_copied = 1; ++ } ++ else ++ ctx->m = m; ++ ++ ctx->k = mpi_get_nlimbs (m); ++ tmp = mpi_alloc (ctx->k + 1); ++ ++ /* Barrett precalculation: y = floor(b^(2k) / m). */ ++ mpi_set_ui (tmp, 1); ++ mpi_lshift_limbs (tmp, 2 * ctx->k); ++ mpi_fdiv_q (tmp, tmp, m); ++ ++ ctx->y = tmp; ++ ctx->r1 = mpi_alloc ( 2 * ctx->k + 1 ); ++ ctx->r2 = mpi_alloc ( 2 * ctx->k + 1 ); ++ ++ return ctx; ++} ++ ++void ++_gcry_mpi_barrett_free (mpi_barrett_t ctx) ++{ ++ if (ctx) ++ { ++ mpi_free (ctx->y); ++ mpi_free (ctx->r1); ++ mpi_free (ctx->r2); ++ if (ctx->r3) ++ mpi_free (ctx->r3); ++ if (ctx->m_copied) ++ mpi_free (ctx->m); ++ gcry_free (ctx); ++ } ++} ++ ++ ++/* R = X mod M ++ ++ Using Barrett reduction. Before using this function ++ _gcry_mpi_barrett_init must have been called to do the ++ precalculations. CTX is the context created by this precalculation ++ and also conveys M. If the Barret reduction could no be done a ++ starightforward reduction method is used. ++ ++ We assume that these conditions are met: ++ Input: x =(x_2k-1 ...x_0)_b ++ m =(m_k-1 ....m_0)_b with m_k-1 != 0 ++ Output: r = x mod m ++ */ ++void ++_gcry_mpi_mod_barrett (gcry_mpi_t r, gcry_mpi_t x, mpi_barrett_t ctx) ++{ ++ gcry_mpi_t m = ctx->m; ++ int k = ctx->k; ++ gcry_mpi_t y = ctx->y; ++ gcry_mpi_t r1 = ctx->r1; ++ gcry_mpi_t r2 = ctx->r2; ++ ++ mpi_normalize (x); ++ if (mpi_get_nlimbs (x) > 2*k ) ++ { ++ mpi_mod (r, x, m); ++ return; ++ } ++ ++ /* 1. q1 = floor( x / b^k-1) ++ * q2 = q1 * y ++ * q3 = floor( q2 / b^k+1 ) ++ * Actually, we don't need qx, we can work direct on r2 ++ */ ++ mpi_set ( r2, x ); ++ mpi_rshift_limbs ( r2, k-1 ); ++ mpi_mul ( r2, r2, y ); ++ mpi_rshift_limbs ( r2, k+1 ); ++ ++ /* 2. r1 = x mod b^k+1 ++ * r2 = q3 * m mod b^k+1 ++ * r = r1 - r2 ++ * 3. if r < 0 then r = r + b^k+1 ++ */ ++ mpi_set ( r1, x ); ++ if ( r1->nlimbs > k+1 ) /* Quick modulo operation. */ ++ r1->nlimbs = k+1; ++ mpi_mul ( r2, r2, m ); ++ if ( r2->nlimbs > k+1 ) /* Quick modulo operation. */ ++ r2->nlimbs = k+1; ++ mpi_sub ( r, r1, r2 ); ++ ++ if ( mpi_is_neg( r ) ) ++ { ++ if (!ctx->r3) ++ { ++ ctx->r3 = mpi_alloc ( k + 2 ); ++ mpi_set_ui (ctx->r3, 1); ++ mpi_lshift_limbs (ctx->r3, k + 1 ); ++ } ++ mpi_add ( r, r, ctx->r3 ); ++ } ++ ++ /* 4. while r >= m do r = r - m */ ++ while ( mpi_cmp( r, m ) >= 0 ) ++ mpi_sub ( r, r, m ); ++ ++} ++ ++ ++void ++_gcry_mpi_mul_barrett (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, ++ mpi_barrett_t ctx) ++{ ++ gcry_mpi_mul (w, u, v); ++ mpi_mod_barrett (w, w, ctx); ++} +diff --git a/grub-core/lib/libgcrypt/mpi/mpi-mpow.c b/grub-core/lib/libgcrypt/mpi/mpi-mpow.c +new file mode 100644 +index 0000000..ca5b3f1 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/mpi-mpow.c +@@ -0,0 +1,223 @@ ++/* mpi-mpow.c - MPI functions ++ * Copyright (C) 1998, 1999, 2001, 2002, 2003 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ */ ++ ++#include ++#include ++#include ++ ++#include "mpi-internal.h" ++#include "longlong.h" ++#include "g10lib.h" ++ ++ ++/* Barrett is slower than the classical way. It can be tweaked by ++ * using partial multiplications ++ */ ++/*#define USE_BARRETT*/ ++ ++ ++ ++#ifdef USE_BARRETT ++static void barrett_mulm( gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m, gcry_mpi_t y, int k, gcry_mpi_t r1, gcry_mpi_t r2 ); ++static gcry_mpi_t init_barrett( gcry_mpi_t m, int *k, gcry_mpi_t *r1, gcry_mpi_t *r2 ); ++static int calc_barrett( gcry_mpi_t r, gcry_mpi_t x, gcry_mpi_t m, gcry_mpi_t y, int k, gcry_mpi_t r1, gcry_mpi_t r2 ); ++#else ++#define barrett_mulm( w, u, v, m, y, k, r1, r2 ) gcry_mpi_mulm( (w), (u), (v), (m) ) ++#endif ++ ++ ++static int ++build_index( gcry_mpi_t *exparray, int k, int i, int t ) ++{ ++ int j, bitno; ++ int idx = 0; ++ ++ bitno = t-i; ++ for(j=k-1; j >= 0; j-- ) { ++ idx <<= 1; ++ if( mpi_test_bit( exparray[j], bitno ) ) ++ idx |= 1; ++ } ++ /*log_debug("t=%d i=%d idx=%d\n", t, i, idx );*/ ++ return idx; ++} ++ ++/**************** ++ * RES = (BASE[0] ^ EXP[0]) * (BASE[1] ^ EXP[1]) * ... * mod M ++ */ ++void ++_gcry_mpi_mulpowm( gcry_mpi_t res, gcry_mpi_t *basearray, gcry_mpi_t *exparray, gcry_mpi_t m) ++{ ++ int k; /* number of elements */ ++ int t; /* bit size of largest exponent */ ++ int i, j, idx; ++ gcry_mpi_t *G; /* table with precomputed values of size 2^k */ ++ gcry_mpi_t tmp; ++#ifdef USE_BARRETT ++ gcry_mpi_t barrett_y, barrett_r1, barrett_r2; ++ int barrett_k; ++#endif ++ ++ for(k=0; basearray[k]; k++ ) ++ ; ++ gcry_assert(k); ++ for(t=0, i=0; (tmp=exparray[i]); i++ ) { ++ /*log_mpidump("exp: ", tmp );*/ ++ j = mpi_get_nbits(tmp); ++ if( j > t ) ++ t = j; ++ } ++ /*log_mpidump("mod: ", m );*/ ++ gcry_assert (i==k); ++ gcry_assert (t); ++ gcry_assert (k < 10); ++ ++ G = gcry_xcalloc( (1<= 0 && idx < (1< 3 ? k-3:0; ++ ++ mpi_normalize( x ); ++ if( mpi_get_nlimbs(x) > 2*k ) ++ return 1; /* can't do it */ ++ ++ /* 1. q1 = floor( x / b^k-1) ++ * q2 = q1 * y ++ * q3 = floor( q2 / b^k+1 ) ++ * Actually, we don't need qx, we can work direct on r2 ++ */ ++ mpi_set( r2, x ); ++ mpi_rshift_limbs( r2, k-1 ); ++ mpi_mul( r2, r2, y ); ++ mpi_rshift_limbs( r2, k+1 ); ++ ++ /* 2. r1 = x mod b^k+1 ++ * r2 = q3 * m mod b^k+1 ++ * r = r1 - r2 ++ * 3. if r < 0 then r = r + b^k+1 ++ */ ++ mpi_set( r1, x ); ++ if( r1->nlimbs > k+1 ) /* quick modulo operation */ ++ r1->nlimbs = k+1; ++ mpi_mul( r2, r2, m ); ++ if( r2->nlimbs > k+1 ) /* quick modulo operation */ ++ r2->nlimbs = k+1; ++ mpi_sub( r, r1, r2 ); ++ ++ if( mpi_is_neg( r ) ) { ++ gcry_mpi_t tmp; ++ ++ tmp = mpi_alloc( k + 2 ); ++ mpi_set_ui( tmp, 1 ); ++ mpi_lshift_limbs( tmp, k+1 ); ++ mpi_add( r, r, tmp ); ++ mpi_free(tmp); ++ } ++ ++ /* 4. while r >= m do r = r - m */ ++ while( mpi_cmp( r, m ) >= 0 ) ++ mpi_sub( r, r, m ); ++ ++ return 0; ++} ++#endif /* USE_BARRETT */ +diff --git a/grub-core/lib/libgcrypt/mpi/mpi-mul.c b/grub-core/lib/libgcrypt/mpi/mpi-mul.c +new file mode 100644 +index 0000000..9aefd21 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/mpi-mul.c +@@ -0,0 +1,212 @@ ++/* mpi-mul.c - MPI functions ++ * Copyright (C) 1994, 1996, 1998, 2001, 2002, 2003 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ * ++ * Note: This code is heavily based on the GNU MP Library. ++ * Actually it's the same code with only minor changes in the ++ * way the data is stored; this is to support the abstraction ++ * of an optional secure memory allocation which may be used ++ * to avoid revealing of sensitive data due to paging etc. ++ */ ++ ++#include ++#include ++#include ++#include "mpi-internal.h" ++ ++ ++void ++gcry_mpi_mul_ui( gcry_mpi_t prod, gcry_mpi_t mult, unsigned long small_mult ) ++{ ++ mpi_size_t size, prod_size; ++ mpi_ptr_t prod_ptr; ++ mpi_limb_t cy; ++ int sign; ++ ++ size = mult->nlimbs; ++ sign = mult->sign; ++ ++ if( !size || !small_mult ) { ++ prod->nlimbs = 0; ++ prod->sign = 0; ++ return; ++ } ++ ++ prod_size = size + 1; ++ if( prod->alloced < prod_size ) ++ mpi_resize( prod, prod_size ); ++ prod_ptr = prod->d; ++ ++ cy = _gcry_mpih_mul_1( prod_ptr, mult->d, size, (mpi_limb_t)small_mult ); ++ if( cy ) ++ prod_ptr[size++] = cy; ++ prod->nlimbs = size; ++ prod->sign = sign; ++} ++ ++ ++void ++gcry_mpi_mul_2exp( gcry_mpi_t w, gcry_mpi_t u, unsigned long cnt) ++{ ++ mpi_size_t usize, wsize, limb_cnt; ++ mpi_ptr_t wp; ++ mpi_limb_t wlimb; ++ int usign, wsign; ++ ++ usize = u->nlimbs; ++ usign = u->sign; ++ ++ if( !usize ) { ++ w->nlimbs = 0; ++ w->sign = 0; ++ return; ++ } ++ ++ limb_cnt = cnt / BITS_PER_MPI_LIMB; ++ wsize = usize + limb_cnt + 1; ++ if( w->alloced < wsize ) ++ mpi_resize(w, wsize ); ++ wp = w->d; ++ wsize = usize + limb_cnt; ++ wsign = usign; ++ ++ cnt %= BITS_PER_MPI_LIMB; ++ if( cnt ) { ++ wlimb = _gcry_mpih_lshift( wp + limb_cnt, u->d, usize, cnt ); ++ if( wlimb ) { ++ wp[wsize] = wlimb; ++ wsize++; ++ } ++ } ++ else { ++ MPN_COPY_DECR( wp + limb_cnt, u->d, usize ); ++ } ++ ++ /* Zero all whole limbs at low end. Do it here and not before calling ++ * mpn_lshift, not to lose for U == W. */ ++ MPN_ZERO( wp, limb_cnt ); ++ ++ w->nlimbs = wsize; ++ w->sign = wsign; ++} ++ ++ ++void ++gcry_mpi_mul( gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v) ++{ ++ mpi_size_t usize, vsize, wsize; ++ mpi_ptr_t up, vp, wp; ++ mpi_limb_t cy; ++ int usign, vsign, usecure, vsecure, sign_product; ++ int assign_wp=0; ++ mpi_ptr_t tmp_limb=NULL; ++ unsigned int tmp_limb_nlimbs = 0; ++ ++ if( u->nlimbs < v->nlimbs ) { /* Swap U and V. */ ++ usize = v->nlimbs; ++ usign = v->sign; ++ usecure = mpi_is_secure(v); ++ up = v->d; ++ vsize = u->nlimbs; ++ vsign = u->sign; ++ vsecure = mpi_is_secure(u); ++ vp = u->d; ++ } ++ else { ++ usize = u->nlimbs; ++ usign = u->sign; ++ usecure = mpi_is_secure(u); ++ up = u->d; ++ vsize = v->nlimbs; ++ vsign = v->sign; ++ vsecure = mpi_is_secure(v); ++ vp = v->d; ++ } ++ sign_product = usign ^ vsign; ++ wp = w->d; ++ ++ /* Ensure W has space enough to store the result. */ ++ wsize = usize + vsize; ++ if ( !mpi_is_secure (w) && (mpi_is_secure (u) || mpi_is_secure (v)) ) { ++ /* w is not allocated in secure space but u or v is. To make sure ++ * that no temporray results are stored in w, we temporary use ++ * a newly allocated limb space for w */ ++ wp = mpi_alloc_limb_space( wsize, 1 ); ++ assign_wp = 2; /* mark it as 2 so that we can later copy it back to ++ * mormal memory */ ++ } ++ else if( w->alloced < wsize ) { ++ if( wp == up || wp == vp ) { ++ wp = mpi_alloc_limb_space( wsize, mpi_is_secure(w) ); ++ assign_wp = 1; ++ } ++ else { ++ mpi_resize(w, wsize ); ++ wp = w->d; ++ } ++ } ++ else { /* Make U and V not overlap with W. */ ++ if( wp == up ) { ++ /* W and U are identical. Allocate temporary space for U. */ ++ tmp_limb_nlimbs = usize; ++ up = tmp_limb = mpi_alloc_limb_space( usize, usecure ); ++ /* Is V identical too? Keep it identical with U. */ ++ if( wp == vp ) ++ vp = up; ++ /* Copy to the temporary space. */ ++ MPN_COPY( up, wp, usize ); ++ } ++ else if( wp == vp ) { ++ /* W and V are identical. Allocate temporary space for V. */ ++ tmp_limb_nlimbs = vsize; ++ vp = tmp_limb = mpi_alloc_limb_space( vsize, vsecure ); ++ /* Copy to the temporary space. */ ++ MPN_COPY( vp, wp, vsize ); ++ } ++ } ++ ++ if( !vsize ) ++ wsize = 0; ++ else { ++ cy = _gcry_mpih_mul( wp, up, usize, vp, vsize ); ++ wsize -= cy? 0:1; ++ } ++ ++ if( assign_wp ) { ++ if (assign_wp == 2) { ++ /* copy the temp wp from secure memory back to normal memory */ ++ mpi_ptr_t tmp_wp = mpi_alloc_limb_space (wsize, 0); ++ MPN_COPY (tmp_wp, wp, wsize); ++ _gcry_mpi_free_limb_space (wp, 0); ++ wp = tmp_wp; ++ } ++ _gcry_mpi_assign_limb_space( w, wp, wsize ); ++ } ++ w->nlimbs = wsize; ++ w->sign = sign_product; ++ if( tmp_limb ) ++ _gcry_mpi_free_limb_space (tmp_limb, tmp_limb_nlimbs); ++} ++ ++ ++void ++gcry_mpi_mulm( gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m) ++{ ++ gcry_mpi_mul(w, u, v); ++ _gcry_mpi_fdiv_r( w, w, m ); ++} +diff --git a/grub-core/lib/libgcrypt/mpi/mpi-pow.c b/grub-core/lib/libgcrypt/mpi/mpi-pow.c +new file mode 100644 +index 0000000..33bbebe +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/mpi-pow.c +@@ -0,0 +1,324 @@ ++/* mpi-pow.c - MPI functions for exponentiation ++ * Copyright (C) 1994, 1996, 1998, 2000, 2002 ++ * 2003 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, see . ++ * ++ * Note: This code is heavily based on the GNU MP Library. ++ * Actually it's the same code with only minor changes in the ++ * way the data is stored; this is to support the abstraction ++ * of an optional secure memory allocation which may be used ++ * to avoid revealing of sensitive data due to paging etc. ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#include "mpi-internal.h" ++#include "longlong.h" ++ ++ ++/**************** ++ * RES = BASE ^ EXPO mod MOD ++ */ ++void ++gcry_mpi_powm (gcry_mpi_t res, ++ gcry_mpi_t base, gcry_mpi_t expo, gcry_mpi_t mod) ++{ ++ /* Pointer to the limbs of the arguments, their size and signs. */ ++ mpi_ptr_t rp, ep, mp, bp; ++ mpi_size_t esize, msize, bsize, rsize; ++ int msign, bsign, rsign; ++ /* Flags telling the secure allocation status of the arguments. */ ++ int esec, msec, bsec; ++ /* Size of the result including space for temporary values. */ ++ mpi_size_t size; ++ /* Helper. */ ++ int mod_shift_cnt; ++ int negative_result; ++ mpi_ptr_t mp_marker = NULL; ++ mpi_ptr_t bp_marker = NULL; ++ mpi_ptr_t ep_marker = NULL; ++ mpi_ptr_t xp_marker = NULL; ++ unsigned int mp_nlimbs = 0; ++ unsigned int bp_nlimbs = 0; ++ unsigned int ep_nlimbs = 0; ++ unsigned int xp_nlimbs = 0; ++ mpi_ptr_t tspace = NULL; ++ mpi_size_t tsize = 0; ++ ++ ++ esize = expo->nlimbs; ++ msize = mod->nlimbs; ++ size = 2 * msize; ++ msign = mod->sign; ++ ++ esec = mpi_is_secure(expo); ++ msec = mpi_is_secure(mod); ++ bsec = mpi_is_secure(base); ++ ++ rp = res->d; ++ ep = expo->d; ++ ++ if (!msize) ++ msize = 1 / msize; /* Provoke a signal. */ ++ ++ if (!esize) ++ { ++ /* Exponent is zero, result is 1 mod MOD, i.e., 1 or 0 depending ++ on if MOD equals 1. */ ++ rp[0] = 1; ++ res->nlimbs = (msize == 1 && mod->d[0] == 1) ? 0 : 1; ++ res->sign = 0; ++ goto leave; ++ } ++ ++ /* Normalize MOD (i.e. make its most significant bit set) as ++ required by mpn_divrem. This will make the intermediate values ++ in the calculation slightly larger, but the correct result is ++ obtained after a final reduction using the original MOD value. */ ++ mp_nlimbs = msec? msize:0; ++ mp = mp_marker = mpi_alloc_limb_space(msize, msec); ++ count_leading_zeros (mod_shift_cnt, mod->d[msize-1]); ++ if (mod_shift_cnt) ++ _gcry_mpih_lshift (mp, mod->d, msize, mod_shift_cnt); ++ else ++ MPN_COPY( mp, mod->d, msize ); ++ ++ bsize = base->nlimbs; ++ bsign = base->sign; ++ if (bsize > msize) ++ { ++ /* The base is larger than the module. Reduce it. ++ ++ Allocate (BSIZE + 1) with space for remainder and quotient. ++ (The quotient is (bsize - msize + 1) limbs.) */ ++ bp_nlimbs = bsec ? (bsize + 1):0; ++ bp = bp_marker = mpi_alloc_limb_space( bsize + 1, bsec ); ++ MPN_COPY ( bp, base->d, bsize ); ++ /* We don't care about the quotient, store it above the ++ * remainder, at BP + MSIZE. */ ++ _gcry_mpih_divrem( bp + msize, 0, bp, bsize, mp, msize ); ++ bsize = msize; ++ /* Canonicalize the base, since we are going to multiply with it ++ quite a few times. */ ++ MPN_NORMALIZE( bp, bsize ); ++ } ++ else ++ bp = base->d; ++ ++ if (!bsize) ++ { ++ res->nlimbs = 0; ++ res->sign = 0; ++ goto leave; ++ } ++ ++ ++ /* Make BASE, EXPO and MOD not overlap with RES. */ ++ if ( rp == bp ) ++ { ++ /* RES and BASE are identical. Allocate temp. space for BASE. */ ++ gcry_assert (!bp_marker); ++ bp_nlimbs = bsec? bsize:0; ++ bp = bp_marker = mpi_alloc_limb_space( bsize, bsec ); ++ MPN_COPY(bp, rp, bsize); ++ } ++ if ( rp == ep ) ++ { ++ /* RES and EXPO are identical. Allocate temp. space for EXPO. */ ++ ep_nlimbs = esec? esize:0; ++ ep = ep_marker = mpi_alloc_limb_space( esize, esec ); ++ MPN_COPY(ep, rp, esize); ++ } ++ if ( rp == mp ) ++ { ++ /* RES and MOD are identical. Allocate temporary space for MOD.*/ ++ gcry_assert (!mp_marker); ++ mp_nlimbs = msec?msize:0; ++ mp = mp_marker = mpi_alloc_limb_space( msize, msec ); ++ MPN_COPY(mp, rp, msize); ++ } ++ ++ /* Copy base to the result. */ ++ if (res->alloced < size) ++ { ++ mpi_resize (res, size); ++ rp = res->d; ++ } ++ MPN_COPY ( rp, bp, bsize ); ++ rsize = bsize; ++ rsign = bsign; ++ ++ /* Main processing. */ ++ { ++ mpi_size_t i; ++ mpi_ptr_t xp; ++ int c; ++ mpi_limb_t e; ++ mpi_limb_t carry_limb; ++ struct karatsuba_ctx karactx; ++ ++ xp_nlimbs = msec? (2 * (msize + 1)):0; ++ xp = xp_marker = mpi_alloc_limb_space( 2 * (msize + 1), msec ); ++ ++ memset( &karactx, 0, sizeof karactx ); ++ negative_result = (ep[0] & 1) && base->sign; ++ ++ i = esize - 1; ++ e = ep[i]; ++ count_leading_zeros (c, e); ++ e = (e << c) << 1; /* Shift the expo bits to the left, lose msb. */ ++ c = BITS_PER_MPI_LIMB - 1 - c; ++ ++ /* Main loop. ++ ++ Make the result be pointed to alternately by XP and RP. This ++ helps us avoid block copying, which would otherwise be ++ necessary with the overlap restrictions of ++ _gcry_mpih_divmod. With 50% probability the result after this ++ loop will be in the area originally pointed by RP (==RES->d), ++ and with 50% probability in the area originally pointed to by XP. */ ++ for (;;) ++ { ++ while (c) ++ { ++ mpi_ptr_t tp; ++ mpi_size_t xsize; ++ ++ /*mpih_mul_n(xp, rp, rp, rsize);*/ ++ if ( rsize < KARATSUBA_THRESHOLD ) ++ _gcry_mpih_sqr_n_basecase( xp, rp, rsize ); ++ else ++ { ++ if ( !tspace ) ++ { ++ tsize = 2 * rsize; ++ tspace = mpi_alloc_limb_space( tsize, 0 ); ++ } ++ else if ( tsize < (2*rsize) ) ++ { ++ _gcry_mpi_free_limb_space (tspace, 0); ++ tsize = 2 * rsize; ++ tspace = mpi_alloc_limb_space (tsize, 0 ); ++ } ++ _gcry_mpih_sqr_n (xp, rp, rsize, tspace); ++ } ++ ++ xsize = 2 * rsize; ++ if ( xsize > msize ) ++ { ++ _gcry_mpih_divrem(xp + msize, 0, xp, xsize, mp, msize); ++ xsize = msize; ++ } ++ ++ tp = rp; rp = xp; xp = tp; ++ rsize = xsize; ++ ++ if ( (mpi_limb_signed_t)e < 0 ) ++ { ++ /*mpih_mul( xp, rp, rsize, bp, bsize );*/ ++ if( bsize < KARATSUBA_THRESHOLD ) ++ _gcry_mpih_mul ( xp, rp, rsize, bp, bsize ); ++ else ++ _gcry_mpih_mul_karatsuba_case (xp, rp, rsize, bp, bsize, ++ &karactx); ++ ++ xsize = rsize + bsize; ++ if ( xsize > msize ) ++ { ++ _gcry_mpih_divrem(xp + msize, 0, xp, xsize, mp, msize); ++ xsize = msize; ++ } ++ ++ tp = rp; rp = xp; xp = tp; ++ rsize = xsize; ++ } ++ e <<= 1; ++ c--; ++ } ++ ++ i--; ++ if ( i < 0 ) ++ break; ++ e = ep[i]; ++ c = BITS_PER_MPI_LIMB; ++ } ++ ++ /* We shifted MOD, the modulo reduction argument, left ++ MOD_SHIFT_CNT steps. Adjust the result by reducing it with the ++ original MOD. ++ ++ Also make sure the result is put in RES->d (where it already ++ might be, see above). */ ++ if ( mod_shift_cnt ) ++ { ++ carry_limb = _gcry_mpih_lshift( res->d, rp, rsize, mod_shift_cnt); ++ rp = res->d; ++ if ( carry_limb ) ++ { ++ rp[rsize] = carry_limb; ++ rsize++; ++ } ++ } ++ else if (res->d != rp) ++ { ++ MPN_COPY (res->d, rp, rsize); ++ rp = res->d; ++ } ++ ++ if ( rsize >= msize ) ++ { ++ _gcry_mpih_divrem(rp + msize, 0, rp, rsize, mp, msize); ++ rsize = msize; ++ } ++ ++ /* Remove any leading zero words from the result. */ ++ if ( mod_shift_cnt ) ++ _gcry_mpih_rshift( rp, rp, rsize, mod_shift_cnt); ++ MPN_NORMALIZE (rp, rsize); ++ ++ _gcry_mpih_release_karatsuba_ctx (&karactx ); ++ } ++ ++ /* Fixup for negative results. */ ++ if ( negative_result && rsize ) ++ { ++ if ( mod_shift_cnt ) ++ _gcry_mpih_rshift( mp, mp, msize, mod_shift_cnt); ++ _gcry_mpih_sub( rp, mp, msize, rp, rsize); ++ rsize = msize; ++ rsign = msign; ++ MPN_NORMALIZE(rp, rsize); ++ } ++ gcry_assert (res->d == rp); ++ res->nlimbs = rsize; ++ res->sign = rsign; ++ ++ leave: ++ if (mp_marker) ++ _gcry_mpi_free_limb_space( mp_marker, mp_nlimbs ); ++ if (bp_marker) ++ _gcry_mpi_free_limb_space( bp_marker, bp_nlimbs ); ++ if (ep_marker) ++ _gcry_mpi_free_limb_space( ep_marker, ep_nlimbs ); ++ if (xp_marker) ++ _gcry_mpi_free_limb_space( xp_marker, xp_nlimbs ); ++ if (tspace) ++ _gcry_mpi_free_limb_space( tspace, 0 ); ++} +diff --git a/grub-core/lib/libgcrypt/mpi/mpi-scan.c b/grub-core/lib/libgcrypt/mpi/mpi-scan.c +new file mode 100644 +index 0000000..2473cd9 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/mpi-scan.c +@@ -0,0 +1,130 @@ ++/* mpi-scan.c - MPI functions ++ * Copyright (C) 1998, 2001, 2002, 2003 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ */ ++ ++#include ++#include ++#include ++#include "mpi-internal.h" ++#include "longlong.h" ++ ++/**************** ++ * Scan through an mpi and return byte for byte. a -1 is returned to indicate ++ * the end of the mpi. Scanning is done from the lsb to the msb, returned ++ * values are in the range of 0 .. 255. ++ * ++ * FIXME: This code is VERY ugly! ++ */ ++int ++_gcry_mpi_getbyte( gcry_mpi_t a, unsigned idx ) ++{ ++ int i, j; ++ unsigned n; ++ mpi_ptr_t ap; ++ mpi_limb_t limb; ++ ++ ap = a->d; ++ for(n=0,i=0; i < a->nlimbs; i++ ) { ++ limb = ap[i]; ++ for( j=0; j < BYTES_PER_MPI_LIMB; j++, n++ ) ++ if( n == idx ) ++ return (limb >> j*8) & 0xff; ++ } ++ return -1; ++} ++ ++ ++/**************** ++ * Put a value at position IDX into A. idx counts from lsb to msb ++ */ ++void ++_gcry_mpi_putbyte( gcry_mpi_t a, unsigned idx, int xc ) ++{ ++ int i, j; ++ unsigned n; ++ mpi_ptr_t ap; ++ mpi_limb_t limb, c; ++ ++ c = xc & 0xff; ++ ap = a->d; ++ for(n=0,i=0; i < a->alloced; i++ ) { ++ limb = ap[i]; ++ for( j=0; j < BYTES_PER_MPI_LIMB; j++, n++ ) ++ if( n == idx ) { ++ #if BYTES_PER_MPI_LIMB == 4 ++ if( j == 0 ) ++ limb = (limb & 0xffffff00) | c; ++ else if( j == 1 ) ++ limb = (limb & 0xffff00ff) | (c<<8); ++ else if( j == 2 ) ++ limb = (limb & 0xff00ffff) | (c<<16); ++ else ++ limb = (limb & 0x00ffffff) | (c<<24); ++ #elif BYTES_PER_MPI_LIMB == 8 ++ if( j == 0 ) ++ limb = (limb & 0xffffffffffffff00) | c; ++ else if( j == 1 ) ++ limb = (limb & 0xffffffffffff00ff) | (c<<8); ++ else if( j == 2 ) ++ limb = (limb & 0xffffffffff00ffff) | (c<<16); ++ else if( j == 3 ) ++ limb = (limb & 0xffffffff00ffffff) | (c<<24); ++ else if( j == 4 ) ++ limb = (limb & 0xffffff00ffffffff) | (c<<32); ++ else if( j == 5 ) ++ limb = (limb & 0xffff00ffffffffff) | (c<<40); ++ else if( j == 6 ) ++ limb = (limb & 0xff00ffffffffffff) | (c<<48); ++ else ++ limb = (limb & 0x00ffffffffffffff) | (c<<56); ++ #else ++ #error please enhance this function, its ugly - i know. ++ #endif ++ if( a->nlimbs <= i ) ++ a->nlimbs = i+1; ++ ap[i] = limb; ++ return; ++ } ++ } ++ abort(); /* index out of range */ ++} ++ ++ ++/**************** ++ * Count the number of zerobits at the low end of A ++ */ ++unsigned ++_gcry_mpi_trailing_zeros( gcry_mpi_t a ) ++{ ++ unsigned n, count = 0; ++ ++ for(n=0; n < a->nlimbs; n++ ) { ++ if( a->d[n] ) { ++ unsigned nn; ++ mpi_limb_t alimb = a->d[n]; ++ ++ count_trailing_zeros( nn, alimb ); ++ count += nn; ++ break; ++ } ++ count += BITS_PER_MPI_LIMB; ++ } ++ return count; ++ ++} +diff --git a/grub-core/lib/libgcrypt/mpi/mpicoder.c b/grub-core/lib/libgcrypt/mpi/mpicoder.c +new file mode 100644 +index 0000000..f499796 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/mpicoder.c +@@ -0,0 +1,750 @@ ++/* mpicoder.c - Coder for the external representation of MPIs ++ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ++ * 2008 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, see . ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#include "mpi-internal.h" ++#include "g10lib.h" ++ ++#define MAX_EXTERN_MPI_BITS 16384 ++ ++/* Helper used to scan PGP style MPIs. Returns NULL on failure. */ ++static gcry_mpi_t ++mpi_read_from_buffer (const unsigned char *buffer, unsigned *ret_nread, ++ int secure) ++{ ++ int i, j; ++ unsigned int nbits, nbytes, nlimbs, nread=0; ++ mpi_limb_t a; ++ gcry_mpi_t val = MPI_NULL; ++ ++ if ( *ret_nread < 2 ) ++ goto leave; ++ nbits = buffer[0] << 8 | buffer[1]; ++ if ( nbits > MAX_EXTERN_MPI_BITS ) ++ { ++/* log_debug ("mpi too large (%u bits)\n", nbits); */ ++ goto leave; ++ } ++ buffer += 2; ++ nread = 2; ++ ++ nbytes = (nbits+7) / 8; ++ nlimbs = (nbytes+BYTES_PER_MPI_LIMB-1) / BYTES_PER_MPI_LIMB; ++ val = secure? mpi_alloc_secure (nlimbs) : mpi_alloc (nlimbs); ++ i = BYTES_PER_MPI_LIMB - nbytes % BYTES_PER_MPI_LIMB; ++ i %= BYTES_PER_MPI_LIMB; ++ j= val->nlimbs = nlimbs; ++ val->sign = 0; ++ for ( ; j > 0; j-- ) ++ { ++ a = 0; ++ for (; i < BYTES_PER_MPI_LIMB; i++ ) ++ { ++ if ( ++nread > *ret_nread ) ++ { ++/* log_debug ("mpi larger than buffer"); */ ++ mpi_free (val); ++ val = NULL; ++ goto leave; ++ } ++ a <<= 8; ++ a |= *buffer++; ++ } ++ i = 0; ++ val->d[j-1] = a; ++ } ++ ++ leave: ++ *ret_nread = nread; ++ return val; ++} ++ ++ ++/**************** ++ * Fill the mpi VAL from the hex string in STR. ++ */ ++static int ++mpi_fromstr (gcry_mpi_t val, const char *str) ++{ ++ int sign = 0; ++ int prepend_zero = 0; ++ int i, j, c, c1, c2; ++ unsigned int nbits, nbytes, nlimbs; ++ mpi_limb_t a; ++ ++ if ( *str == '-' ) ++ { ++ sign = 1; ++ str++; ++ } ++ ++ /* Skip optional hex prefix. */ ++ if ( *str == '0' && str[1] == 'x' ) ++ str += 2; ++ ++ nbits = 4 * strlen (str); ++ if ((nbits % 8)) ++ prepend_zero = 1; ++ ++ nbytes = (nbits+7) / 8; ++ nlimbs = (nbytes+BYTES_PER_MPI_LIMB-1) / BYTES_PER_MPI_LIMB; ++ ++ if ( val->alloced < nlimbs ) ++ mpi_resize (val, nlimbs); ++ ++ i = BYTES_PER_MPI_LIMB - (nbytes % BYTES_PER_MPI_LIMB); ++ i %= BYTES_PER_MPI_LIMB; ++ j = val->nlimbs = nlimbs; ++ val->sign = sign; ++ for (; j > 0; j--) ++ { ++ a = 0; ++ for (; i < BYTES_PER_MPI_LIMB; i++) ++ { ++ if (prepend_zero) ++ { ++ c1 = '0'; ++ prepend_zero = 0; ++ } ++ else ++ c1 = *str++; ++ ++ if (!c1) ++ { ++ mpi_clear (val); ++ return 1; /* Error. */ ++ } ++ c2 = *str++; ++ if (!c2) ++ { ++ mpi_clear (val); ++ return 1; /* Error. */ ++ } ++ if ( c1 >= '0' && c1 <= '9' ) ++ c = c1 - '0'; ++ else if ( c1 >= 'a' && c1 <= 'f' ) ++ c = c1 - 'a' + 10; ++ else if ( c1 >= 'A' && c1 <= 'F' ) ++ c = c1 - 'A' + 10; ++ else ++ { ++ mpi_clear (val); ++ return 1; /* Error. */ ++ } ++ c <<= 4; ++ if ( c2 >= '0' && c2 <= '9' ) ++ c |= c2 - '0'; ++ else if( c2 >= 'a' && c2 <= 'f' ) ++ c |= c2 - 'a' + 10; ++ else if( c2 >= 'A' && c2 <= 'F' ) ++ c |= c2 - 'A' + 10; ++ else ++ { ++ mpi_clear(val); ++ return 1; /* Error. */ ++ } ++ a <<= 8; ++ a |= c; ++ } ++ i = 0; ++ val->d[j-1] = a; ++ } ++ ++ return 0; /* Okay. */ ++} ++ ++ ++/* Dump the value of A in a format suitable for debugging to ++ Libgcrypt's logging stream. Note that one leading space but no ++ trailing space or linefeed will be printed. It is okay to pass ++ NULL for A. */ ++void ++gcry_mpi_dump (const gcry_mpi_t a) ++{ ++ int i; ++ ++ log_printf (" "); ++ if (!a) ++ log_printf ("[MPI_NULL]"); ++ else ++ { ++ if (a->sign) ++ log_printf ( "-"); ++#if BYTES_PER_MPI_LIMB == 2 ++# define X "4" ++#elif BYTES_PER_MPI_LIMB == 4 ++# define X "8" ++#elif BYTES_PER_MPI_LIMB == 8 ++# define X "16" ++#elif BYTES_PER_MPI_LIMB == 16 ++# define X "32" ++#else ++# error please define the format here ++#endif ++ for (i=a->nlimbs; i > 0 ; i-- ) ++ { ++ log_printf (i != a->nlimbs? "%0" X "lX":"%lX", (ulong)a->d[i-1]); ++ } ++#undef X ++ if (!a->nlimbs) ++ log_printf ("0"); ++ } ++} ++ ++/* Convience function used internally. */ ++void ++_gcry_log_mpidump (const char *text, gcry_mpi_t a) ++{ ++ log_printf ("%s:", text); ++ gcry_mpi_dump (a); ++ log_printf ("\n"); ++} ++ ++ ++/* Return an allocated buffer with the MPI (msb first). NBYTES ++ receives the length of this buffer. Caller must free the return ++ string. This function returns an allocated buffer with NBYTES set ++ to zero if the value of A is zero. If sign is not NULL, it will be ++ set to the sign of the A. On error NULL is returned and ERRNO set ++ appropriately. */ ++static unsigned char * ++do_get_buffer (gcry_mpi_t a, unsigned int *nbytes, int *sign, int force_secure) ++{ ++ unsigned char *p, *buffer; ++ mpi_limb_t alimb; ++ int i; ++ size_t n; ++ ++ if (sign) ++ *sign = a->sign; ++ ++ *nbytes = a->nlimbs * BYTES_PER_MPI_LIMB; ++ n = *nbytes? *nbytes:1; /* Allocate at least one byte. */ ++ p = buffer = (force_secure || mpi_is_secure(a))? gcry_malloc_secure (n) ++ : gcry_malloc (n); ++ if (!buffer) ++ return NULL; ++ ++ for (i=a->nlimbs-1; i >= 0; i--) ++ { ++ alimb = a->d[i]; ++#if BYTES_PER_MPI_LIMB == 4 ++ *p++ = alimb >> 24; ++ *p++ = alimb >> 16; ++ *p++ = alimb >> 8; ++ *p++ = alimb ; ++#elif BYTES_PER_MPI_LIMB == 8 ++ *p++ = alimb >> 56; ++ *p++ = alimb >> 48; ++ *p++ = alimb >> 40; ++ *p++ = alimb >> 32; ++ *p++ = alimb >> 24; ++ *p++ = alimb >> 16; ++ *p++ = alimb >> 8; ++ *p++ = alimb ; ++#else ++# error please implement for this limb size. ++#endif ++ } ++ ++ /* This is sub-optimal but we need to do the shift operation because ++ the caller has to free the returned buffer. */ ++ for (p=buffer; !*p && *nbytes; p++, --*nbytes) ++ ; ++ if (p != buffer) ++ memmove (buffer,p, *nbytes); ++ return buffer; ++} ++ ++ ++byte * ++_gcry_mpi_get_buffer (gcry_mpi_t a, unsigned int *nbytes, int *sign) ++{ ++ return do_get_buffer (a, nbytes, sign, 0); ++} ++ ++byte * ++_gcry_mpi_get_secure_buffer (gcry_mpi_t a, unsigned *nbytes, int *sign) ++{ ++ return do_get_buffer (a, nbytes, sign, 1); ++} ++ ++ ++/* ++ * Use the NBYTES at BUFFER_ARG to update A. Set the sign of a to ++ * SIGN. ++ */ ++void ++_gcry_mpi_set_buffer (gcry_mpi_t a, const void *buffer_arg, ++ unsigned int nbytes, int sign) ++{ ++ const unsigned char *buffer = (const unsigned char*)buffer_arg; ++ const unsigned char *p; ++ mpi_limb_t alimb; ++ int nlimbs; ++ int i; ++ ++ nlimbs = (nbytes + BYTES_PER_MPI_LIMB - 1) / BYTES_PER_MPI_LIMB; ++ RESIZE_IF_NEEDED(a, nlimbs); ++ a->sign = sign; ++ ++ for (i=0, p = buffer+nbytes-1; p >= buffer+BYTES_PER_MPI_LIMB; ) ++ { ++#if BYTES_PER_MPI_LIMB == 4 ++ alimb = *p-- ; ++ alimb |= *p-- << 8 ; ++ alimb |= *p-- << 16 ; ++ alimb |= *p-- << 24 ; ++#elif BYTES_PER_MPI_LIMB == 8 ++ alimb = (mpi_limb_t)*p-- ; ++ alimb |= (mpi_limb_t)*p-- << 8 ; ++ alimb |= (mpi_limb_t)*p-- << 16 ; ++ alimb |= (mpi_limb_t)*p-- << 24 ; ++ alimb |= (mpi_limb_t)*p-- << 32 ; ++ alimb |= (mpi_limb_t)*p-- << 40 ; ++ alimb |= (mpi_limb_t)*p-- << 48 ; ++ alimb |= (mpi_limb_t)*p-- << 56 ; ++#else ++# error please implement for this limb size. ++#endif ++ a->d[i++] = alimb; ++ } ++ if ( p >= buffer ) ++ { ++#if BYTES_PER_MPI_LIMB == 4 ++ alimb = *p--; ++ if (p >= buffer) ++ alimb |= *p-- << 8; ++ if (p >= buffer) ++ alimb |= *p-- << 16; ++ if (p >= buffer) ++ alimb |= *p-- << 24; ++#elif BYTES_PER_MPI_LIMB == 8 ++ alimb = (mpi_limb_t)*p--; ++ if (p >= buffer) ++ alimb |= (mpi_limb_t)*p-- << 8; ++ if (p >= buffer) ++ alimb |= (mpi_limb_t)*p-- << 16; ++ if (p >= buffer) ++ alimb |= (mpi_limb_t)*p-- << 24; ++ if (p >= buffer) ++ alimb |= (mpi_limb_t)*p-- << 32; ++ if (p >= buffer) ++ alimb |= (mpi_limb_t)*p-- << 40; ++ if (p >= buffer) ++ alimb |= (mpi_limb_t)*p-- << 48; ++ if (p >= buffer) ++ alimb |= (mpi_limb_t)*p-- << 56; ++#else ++# error please implement for this limb size. ++#endif ++ a->d[i++] = alimb; ++ } ++ a->nlimbs = i; ++ gcry_assert (i == nlimbs); ++} ++ ++ ++/* Convert the external representation of an integer stored in BUFFER ++ with a length of BUFLEN into a newly create MPI returned in ++ RET_MPI. If NBYTES is not NULL, it will receive the number of ++ bytes actually scanned after a successful operation. */ ++gcry_error_t ++gcry_mpi_scan (struct gcry_mpi **ret_mpi, enum gcry_mpi_format format, ++ const void *buffer_arg, size_t buflen, size_t *nscanned) ++{ ++ const unsigned char *buffer = (const unsigned char*)buffer_arg; ++ struct gcry_mpi *a = NULL; ++ unsigned int len; ++ int secure = (buffer && gcry_is_secure (buffer)); ++ ++ if (format == GCRYMPI_FMT_SSH) ++ len = 0; ++ else ++ len = buflen; ++ ++ if (format == GCRYMPI_FMT_STD) ++ { ++ const unsigned char *s = buffer; ++ ++ a = secure? mpi_alloc_secure ((len+BYTES_PER_MPI_LIMB-1) ++ /BYTES_PER_MPI_LIMB) ++ : mpi_alloc ((len+BYTES_PER_MPI_LIMB-1)/BYTES_PER_MPI_LIMB); ++ if (len) ++ { ++ a->sign = !!(*s & 0x80); ++ if (a->sign) ++ { ++ /* FIXME: we have to convert from 2compl to magnitude format */ ++ mpi_free (a); ++ return gcry_error (GPG_ERR_INTERNAL); ++ } ++ else ++ _gcry_mpi_set_buffer (a, s, len, 0); ++ } ++ if (ret_mpi) ++ { ++ mpi_normalize ( a ); ++ *ret_mpi = a; ++ } ++ else ++ mpi_free(a); ++ return 0; ++ } ++ else if (format == GCRYMPI_FMT_USG) ++ { ++ a = secure? mpi_alloc_secure ((len+BYTES_PER_MPI_LIMB-1) ++ /BYTES_PER_MPI_LIMB) ++ : mpi_alloc ((len+BYTES_PER_MPI_LIMB-1)/BYTES_PER_MPI_LIMB); ++ ++ if (len) ++ _gcry_mpi_set_buffer (a, buffer, len, 0); ++ if (ret_mpi) ++ { ++ mpi_normalize ( a ); ++ *ret_mpi = a; ++ } ++ else ++ mpi_free(a); ++ return 0; ++ } ++ else if (format == GCRYMPI_FMT_PGP) ++ { ++ a = mpi_read_from_buffer (buffer, &len, secure); ++ if (nscanned) ++ *nscanned = len; ++ if (ret_mpi && a) ++ { ++ mpi_normalize (a); ++ *ret_mpi = a; ++ } ++ else if (a) ++ { ++ mpi_free(a); ++ a = NULL; ++ } ++ return a? 0 : gcry_error (GPG_ERR_INV_OBJ); ++ } ++ else if (format == GCRYMPI_FMT_SSH) ++ { ++ const unsigned char *s = buffer; ++ size_t n; ++ ++ /* This test is not strictly necessary and an assert (!len) ++ would be sufficient. We keep this test in case we later ++ allow the BUFLEN argument to act as a sanitiy check. Same ++ below. */ ++ if (len && len < 4) ++ return gcry_error (GPG_ERR_TOO_SHORT); ++ ++ n = (s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]); ++ s += 4; ++ if (len) ++ len -= 4; ++ if (len && n > len) ++ return gcry_error (GPG_ERR_TOO_LARGE); ++ ++ a = secure? mpi_alloc_secure ((n+BYTES_PER_MPI_LIMB-1) ++ /BYTES_PER_MPI_LIMB) ++ : mpi_alloc ((n+BYTES_PER_MPI_LIMB-1)/BYTES_PER_MPI_LIMB); ++ if (n) ++ { ++ a->sign = !!(*s & 0x80); ++ if (a->sign) ++ { ++ /* FIXME: we have to convert from 2compl to magnitude format */ ++ mpi_free(a); ++ return gcry_error (GPG_ERR_INTERNAL); ++ } ++ else ++ _gcry_mpi_set_buffer( a, s, n, 0 ); ++ } ++ if (nscanned) ++ *nscanned = n+4; ++ if (ret_mpi) ++ { ++ mpi_normalize ( a ); ++ *ret_mpi = a; ++ } ++ else ++ mpi_free(a); ++ return 0; ++ } ++ else if (format == GCRYMPI_FMT_HEX) ++ { ++ /* We can only handle C strings for now. */ ++ if (buflen) ++ return gcry_error (GPG_ERR_INV_ARG); ++ ++ a = secure? mpi_alloc_secure (0) : mpi_alloc(0); ++ if (mpi_fromstr (a, (const char *)buffer)) ++ { ++ mpi_free (a); ++ return gcry_error (GPG_ERR_INV_OBJ); ++ } ++ if (ret_mpi) ++ { ++ mpi_normalize ( a ); ++ *ret_mpi = a; ++ } ++ else ++ mpi_free(a); ++ return 0; ++ } ++ else ++ return gcry_error (GPG_ERR_INV_ARG); ++} ++ ++ ++/* Convert the big integer A into the external representation ++ described by FORMAT and store it in the provided BUFFER which has ++ been allocated by the user with a size of BUFLEN bytes. NWRITTEN ++ receives the actual length of the external representation unless it ++ has been passed as NULL. BUFFER may be NULL to query the required ++ length. */ ++gcry_error_t ++gcry_mpi_print (enum gcry_mpi_format format, ++ unsigned char *buffer, size_t buflen, ++ size_t *nwritten, struct gcry_mpi *a) ++{ ++ unsigned int nbits = mpi_get_nbits (a); ++ size_t len; ++ size_t dummy_nwritten; ++ ++ if (!nwritten) ++ nwritten = &dummy_nwritten; ++ ++ len = buflen; ++ *nwritten = 0; ++ if (format == GCRYMPI_FMT_STD) ++ { ++ unsigned char *tmp; ++ int extra = 0; ++ unsigned int n; ++ ++ if (a->sign) ++ return gcry_error (GPG_ERR_INTERNAL); /* Can't handle it yet. */ ++ ++ tmp = _gcry_mpi_get_buffer (a, &n, NULL); ++ if (!tmp) ++ return gpg_error_from_syserror (); ++ if (n && (*tmp & 0x80)) ++ { ++ n++; ++ extra=1; ++ } ++ ++ if (buffer && n > len) ++ { ++ /* The provided buffer is too short. */ ++ gcry_free (tmp); ++ return gcry_error (GPG_ERR_TOO_SHORT); ++ } ++ if (buffer) ++ { ++ unsigned char *s = buffer; ++ ++ if (extra) ++ *s++ = 0; ++ memcpy (s, tmp, n-extra); ++ } ++ gcry_free(tmp); ++ *nwritten = n; ++ return 0; ++ } ++ else if (format == GCRYMPI_FMT_USG) ++ { ++ unsigned int n = (nbits + 7)/8; ++ ++ /* Note: We ignore the sign for this format. */ ++ /* FIXME: for performance reasons we should put this into ++ mpi_aprint because we can then use the buffer directly. */ ++ if (buffer && n > len) ++ return gcry_error (GPG_ERR_TOO_SHORT); ++ if (buffer) ++ { ++ unsigned char *tmp; ++ ++ tmp = _gcry_mpi_get_buffer (a, &n, NULL); ++ if (!tmp) ++ return gpg_error_from_syserror (); ++ memcpy (buffer, tmp, n); ++ gcry_free (tmp); ++ } ++ *nwritten = n; ++ return 0; ++ } ++ else if (format == GCRYMPI_FMT_PGP) ++ { ++ unsigned int n = (nbits + 7)/8; ++ ++ /* The PGP format can only handle unsigned integers. */ ++ if( a->sign ) ++ return gcry_error (GPG_ERR_INV_ARG); ++ ++ if (buffer && n+2 > len) ++ return gcry_error (GPG_ERR_TOO_SHORT); ++ ++ if (buffer) ++ { ++ unsigned char *tmp; ++ unsigned char *s = buffer; ++ ++ s[0] = nbits >> 8; ++ s[1] = nbits; ++ ++ tmp = _gcry_mpi_get_buffer (a, &n, NULL); ++ if (!tmp) ++ return gpg_error_from_syserror (); ++ memcpy (s+2, tmp, n); ++ gcry_free (tmp); ++ } ++ *nwritten = n+2; ++ return 0; ++ } ++ else if (format == GCRYMPI_FMT_SSH) ++ { ++ unsigned char *tmp; ++ int extra = 0; ++ unsigned int n; ++ ++ if (a->sign) ++ return gcry_error (GPG_ERR_INTERNAL); /* Can't handle it yet. */ ++ ++ tmp = _gcry_mpi_get_buffer (a, &n, NULL); ++ if (!tmp) ++ return gpg_error_from_syserror (); ++ if (n && (*tmp & 0x80)) ++ { ++ n++; ++ extra=1; ++ } ++ ++ if (buffer && n+4 > len) ++ { ++ gcry_free(tmp); ++ return gcry_error (GPG_ERR_TOO_SHORT); ++ } ++ ++ if (buffer) ++ { ++ unsigned char *s = buffer; ++ ++ *s++ = n >> 24; ++ *s++ = n >> 16; ++ *s++ = n >> 8; ++ *s++ = n; ++ if (extra) ++ *s++ = 0; ++ ++ memcpy (s, tmp, n-extra); ++ } ++ gcry_free (tmp); ++ *nwritten = 4+n; ++ return 0; ++ } ++ else if (format == GCRYMPI_FMT_HEX) ++ { ++ unsigned char *tmp; ++ int i; ++ int extra = 0; ++ unsigned int n = 0; ++ ++ tmp = _gcry_mpi_get_buffer (a, &n, NULL); ++ if (!tmp) ++ return gpg_error_from_syserror (); ++ if (!n || (*tmp & 0x80)) ++ extra = 2; ++ ++ if (buffer && 2*n + extra + !!a->sign + 1 > len) ++ { ++ gcry_free(tmp); ++ return gcry_error (GPG_ERR_TOO_SHORT); ++ } ++ if (buffer) ++ { ++ unsigned char *s = buffer; ++ ++ if (a->sign) ++ *s++ = '-'; ++ if (extra) ++ { ++ *s++ = '0'; ++ *s++ = '0'; ++ } ++ ++ for (i=0; i < n; i++) ++ { ++ unsigned int c = tmp[i]; ++ ++ *s++ = (c >> 4) < 10? '0'+(c>>4) : 'A'+(c>>4)-10 ; ++ c &= 15; ++ *s++ = c < 10? '0'+c : 'A'+c-10 ; ++ } ++ *s++ = 0; ++ *nwritten = s - buffer; ++ } ++ else ++ { ++ *nwritten = 2*n + extra + !!a->sign + 1; ++ } ++ gcry_free (tmp); ++ return 0; ++ } ++ else ++ return gcry_error (GPG_ERR_INV_ARG); ++} ++ ++ ++/* ++ * Like gcry_mpi_print but this function allocates the buffer itself. ++ * The caller has to supply the address of a pointer. NWRITTEN may be ++ * NULL. ++ */ ++gcry_error_t ++gcry_mpi_aprint (enum gcry_mpi_format format, ++ unsigned char **buffer, size_t *nwritten, ++ struct gcry_mpi *a) ++{ ++ size_t n; ++ gcry_error_t rc; ++ ++ *buffer = NULL; ++ rc = gcry_mpi_print (format, NULL, 0, &n, a); ++ if (rc) ++ return rc; ++ ++ *buffer = mpi_is_secure(a) ? gcry_malloc_secure (n) : gcry_malloc (n); ++ if (!*buffer) ++ return gpg_error_from_syserror (); ++ rc = gcry_mpi_print( format, *buffer, n, &n, a ); ++ if (rc) ++ { ++ gcry_free(*buffer); ++ *buffer = NULL; ++ } ++ else if (nwritten) ++ *nwritten = n; ++ return rc; ++} +diff --git a/grub-core/lib/libgcrypt/mpi/mpih-div.c b/grub-core/lib/libgcrypt/mpi/mpih-div.c +new file mode 100644 +index 0000000..224b810 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/mpih-div.c +@@ -0,0 +1,533 @@ ++/* mpih-div.c - MPI helper functions ++ * Copyright (C) 1994, 1996, 1998, 2000, ++ * 2001, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ * ++ * Note: This code is heavily based on the GNU MP Library. ++ * Actually it's the same code with only minor changes in the ++ * way the data is stored; this is to support the abstraction ++ * of an optional secure memory allocation which may be used ++ * to avoid revealing of sensitive data due to paging etc. ++ */ ++ ++#include ++#include ++#include ++#include "mpi-internal.h" ++#include "longlong.h" ++ ++#ifndef UMUL_TIME ++#define UMUL_TIME 1 ++#endif ++#ifndef UDIV_TIME ++#define UDIV_TIME UMUL_TIME ++#endif ++ ++/* FIXME: We should be using invert_limb (or invert_normalized_limb) ++ * here (not udiv_qrnnd). ++ */ ++ ++mpi_limb_t ++_gcry_mpih_mod_1(mpi_ptr_t dividend_ptr, mpi_size_t dividend_size, ++ mpi_limb_t divisor_limb) ++{ ++ mpi_size_t i; ++ mpi_limb_t n1, n0, r; ++ int dummy; ++ ++ /* Botch: Should this be handled at all? Rely on callers? */ ++ if( !dividend_size ) ++ return 0; ++ ++ /* If multiplication is much faster than division, and the ++ * dividend is large, pre-invert the divisor, and use ++ * only multiplications in the inner loop. ++ * ++ * This test should be read: ++ * Does it ever help to use udiv_qrnnd_preinv? ++ * && Does what we save compensate for the inversion overhead? ++ */ ++ if( UDIV_TIME > (2 * UMUL_TIME + 6) ++ && (UDIV_TIME - (2 * UMUL_TIME + 6)) * dividend_size > UDIV_TIME ) { ++ int normalization_steps; ++ ++ count_leading_zeros( normalization_steps, divisor_limb ); ++ if( normalization_steps ) { ++ mpi_limb_t divisor_limb_inverted; ++ ++ divisor_limb <<= normalization_steps; ++ ++ /* Compute (2**2N - 2**N * DIVISOR_LIMB) / DIVISOR_LIMB. The ++ * result is a (N+1)-bit approximation to 1/DIVISOR_LIMB, with the ++ * most significant bit (with weight 2**N) implicit. ++ * ++ * Special case for DIVISOR_LIMB == 100...000. ++ */ ++ if( !(divisor_limb << 1) ) ++ divisor_limb_inverted = ~(mpi_limb_t)0; ++ else ++ udiv_qrnnd(divisor_limb_inverted, dummy, ++ -divisor_limb, 0, divisor_limb); ++ ++ n1 = dividend_ptr[dividend_size - 1]; ++ r = n1 >> (BITS_PER_MPI_LIMB - normalization_steps); ++ ++ /* Possible optimization: ++ * if (r == 0 ++ * && divisor_limb > ((n1 << normalization_steps) ++ * | (dividend_ptr[dividend_size - 2] >> ...))) ++ * ...one division less... ++ */ ++ for( i = dividend_size - 2; i >= 0; i--) { ++ n0 = dividend_ptr[i]; ++ UDIV_QRNND_PREINV(dummy, r, r, ++ ((n1 << normalization_steps) ++ | (n0 >> (BITS_PER_MPI_LIMB - normalization_steps))), ++ divisor_limb, divisor_limb_inverted); ++ n1 = n0; ++ } ++ UDIV_QRNND_PREINV(dummy, r, r, ++ n1 << normalization_steps, ++ divisor_limb, divisor_limb_inverted); ++ return r >> normalization_steps; ++ } ++ else { ++ mpi_limb_t divisor_limb_inverted; ++ ++ /* Compute (2**2N - 2**N * DIVISOR_LIMB) / DIVISOR_LIMB. The ++ * result is a (N+1)-bit approximation to 1/DIVISOR_LIMB, with the ++ * most significant bit (with weight 2**N) implicit. ++ * ++ * Special case for DIVISOR_LIMB == 100...000. ++ */ ++ if( !(divisor_limb << 1) ) ++ divisor_limb_inverted = ~(mpi_limb_t)0; ++ else ++ udiv_qrnnd(divisor_limb_inverted, dummy, ++ -divisor_limb, 0, divisor_limb); ++ ++ i = dividend_size - 1; ++ r = dividend_ptr[i]; ++ ++ if( r >= divisor_limb ) ++ r = 0; ++ else ++ i--; ++ ++ for( ; i >= 0; i--) { ++ n0 = dividend_ptr[i]; ++ UDIV_QRNND_PREINV(dummy, r, r, ++ n0, divisor_limb, divisor_limb_inverted); ++ } ++ return r; ++ } ++ } ++ else { ++ if( UDIV_NEEDS_NORMALIZATION ) { ++ int normalization_steps; ++ ++ count_leading_zeros(normalization_steps, divisor_limb); ++ if( normalization_steps ) { ++ divisor_limb <<= normalization_steps; ++ ++ n1 = dividend_ptr[dividend_size - 1]; ++ r = n1 >> (BITS_PER_MPI_LIMB - normalization_steps); ++ ++ /* Possible optimization: ++ * if (r == 0 ++ * && divisor_limb > ((n1 << normalization_steps) ++ * | (dividend_ptr[dividend_size - 2] >> ...))) ++ * ...one division less... ++ */ ++ for(i = dividend_size - 2; i >= 0; i--) { ++ n0 = dividend_ptr[i]; ++ udiv_qrnnd (dummy, r, r, ++ ((n1 << normalization_steps) ++ | (n0 >> (BITS_PER_MPI_LIMB - normalization_steps))), ++ divisor_limb); ++ n1 = n0; ++ } ++ udiv_qrnnd (dummy, r, r, ++ n1 << normalization_steps, ++ divisor_limb); ++ return r >> normalization_steps; ++ } ++ } ++ /* No normalization needed, either because udiv_qrnnd doesn't require ++ * it, or because DIVISOR_LIMB is already normalized. */ ++ i = dividend_size - 1; ++ r = dividend_ptr[i]; ++ ++ if(r >= divisor_limb) ++ r = 0; ++ else ++ i--; ++ ++ for(; i >= 0; i--) { ++ n0 = dividend_ptr[i]; ++ udiv_qrnnd (dummy, r, r, n0, divisor_limb); ++ } ++ return r; ++ } ++} ++ ++/* Divide num (NP/NSIZE) by den (DP/DSIZE) and write ++ * the NSIZE-DSIZE least significant quotient limbs at QP ++ * and the DSIZE long remainder at NP. If QEXTRA_LIMBS is ++ * non-zero, generate that many fraction bits and append them after the ++ * other quotient limbs. ++ * Return the most significant limb of the quotient, this is always 0 or 1. ++ * ++ * Preconditions: ++ * 0. NSIZE >= DSIZE. ++ * 1. The most significant bit of the divisor must be set. ++ * 2. QP must either not overlap with the input operands at all, or ++ * QP + DSIZE >= NP must hold true. (This means that it's ++ * possible to put the quotient in the high part of NUM, right after the ++ * remainder in NUM. ++ * 3. NSIZE >= DSIZE, even if QEXTRA_LIMBS is non-zero. ++ */ ++ ++mpi_limb_t ++_gcry_mpih_divrem( mpi_ptr_t qp, mpi_size_t qextra_limbs, ++ mpi_ptr_t np, mpi_size_t nsize, ++ mpi_ptr_t dp, mpi_size_t dsize) ++{ ++ mpi_limb_t most_significant_q_limb = 0; ++ ++ switch(dsize) { ++ case 0: ++ /* We are asked to divide by zero, so go ahead and do it! (To make ++ the compiler not remove this statement, return the value.) */ ++ return 1 / dsize; ++ ++ case 1: ++ { ++ mpi_size_t i; ++ mpi_limb_t n1; ++ mpi_limb_t d; ++ ++ d = dp[0]; ++ n1 = np[nsize - 1]; ++ ++ if( n1 >= d ) { ++ n1 -= d; ++ most_significant_q_limb = 1; ++ } ++ ++ qp += qextra_limbs; ++ for( i = nsize - 2; i >= 0; i--) ++ udiv_qrnnd( qp[i], n1, n1, np[i], d ); ++ qp -= qextra_limbs; ++ ++ for( i = qextra_limbs - 1; i >= 0; i-- ) ++ udiv_qrnnd (qp[i], n1, n1, 0, d); ++ ++ np[0] = n1; ++ } ++ break; ++ ++ case 2: ++ { ++ mpi_size_t i; ++ mpi_limb_t n1, n0, n2; ++ mpi_limb_t d1, d0; ++ ++ np += nsize - 2; ++ d1 = dp[1]; ++ d0 = dp[0]; ++ n1 = np[1]; ++ n0 = np[0]; ++ ++ if( n1 >= d1 && (n1 > d1 || n0 >= d0) ) { ++ sub_ddmmss (n1, n0, n1, n0, d1, d0); ++ most_significant_q_limb = 1; ++ } ++ ++ for( i = qextra_limbs + nsize - 2 - 1; i >= 0; i-- ) { ++ mpi_limb_t q; ++ mpi_limb_t r; ++ ++ if( i >= qextra_limbs ) ++ np--; ++ else ++ np[0] = 0; ++ ++ if( n1 == d1 ) { ++ /* Q should be either 111..111 or 111..110. Need special ++ * treatment of this rare case as normal division would ++ * give overflow. */ ++ q = ~(mpi_limb_t)0; ++ ++ r = n0 + d1; ++ if( r < d1 ) { /* Carry in the addition? */ ++ add_ssaaaa( n1, n0, r - d0, np[0], 0, d0 ); ++ qp[i] = q; ++ continue; ++ } ++ n1 = d0 - (d0 != 0?1:0); ++ n0 = -d0; ++ } ++ else { ++ udiv_qrnnd (q, r, n1, n0, d1); ++ umul_ppmm (n1, n0, d0, q); ++ } ++ ++ n2 = np[0]; ++ q_test: ++ if( n1 > r || (n1 == r && n0 > n2) ) { ++ /* The estimated Q was too large. */ ++ q--; ++ sub_ddmmss (n1, n0, n1, n0, 0, d0); ++ r += d1; ++ if( r >= d1 ) /* If not carry, test Q again. */ ++ goto q_test; ++ } ++ ++ qp[i] = q; ++ sub_ddmmss (n1, n0, r, n2, n1, n0); ++ } ++ np[1] = n1; ++ np[0] = n0; ++ } ++ break; ++ ++ default: ++ { ++ mpi_size_t i; ++ mpi_limb_t dX, d1, n0; ++ ++ np += nsize - dsize; ++ dX = dp[dsize - 1]; ++ d1 = dp[dsize - 2]; ++ n0 = np[dsize - 1]; ++ ++ if( n0 >= dX ) { ++ if(n0 > dX || _gcry_mpih_cmp(np, dp, dsize - 1) >= 0 ) { ++ _gcry_mpih_sub_n(np, np, dp, dsize); ++ n0 = np[dsize - 1]; ++ most_significant_q_limb = 1; ++ } ++ } ++ ++ for( i = qextra_limbs + nsize - dsize - 1; i >= 0; i--) { ++ mpi_limb_t q; ++ mpi_limb_t n1, n2; ++ mpi_limb_t cy_limb; ++ ++ if( i >= qextra_limbs ) { ++ np--; ++ n2 = np[dsize]; ++ } ++ else { ++ n2 = np[dsize - 1]; ++ MPN_COPY_DECR (np + 1, np, dsize - 1); ++ np[0] = 0; ++ } ++ ++ if( n0 == dX ) { ++ /* This might over-estimate q, but it's probably not worth ++ * the extra code here to find out. */ ++ q = ~(mpi_limb_t)0; ++ } ++ else { ++ mpi_limb_t r; ++ ++ udiv_qrnnd(q, r, n0, np[dsize - 1], dX); ++ umul_ppmm(n1, n0, d1, q); ++ ++ while( n1 > r || (n1 == r && n0 > np[dsize - 2])) { ++ q--; ++ r += dX; ++ if( r < dX ) /* I.e. "carry in previous addition?" */ ++ break; ++ n1 -= n0 < d1; ++ n0 -= d1; ++ } ++ } ++ ++ /* Possible optimization: We already have (q * n0) and (1 * n1) ++ * after the calculation of q. Taking advantage of that, we ++ * could make this loop make two iterations less. */ ++ cy_limb = _gcry_mpih_submul_1(np, dp, dsize, q); ++ ++ if( n2 != cy_limb ) { ++ _gcry_mpih_add_n(np, np, dp, dsize); ++ q--; ++ } ++ ++ qp[i] = q; ++ n0 = np[dsize - 1]; ++ } ++ } ++ } ++ ++ return most_significant_q_limb; ++} ++ ++ ++/**************** ++ * Divide (DIVIDEND_PTR,,DIVIDEND_SIZE) by DIVISOR_LIMB. ++ * Write DIVIDEND_SIZE limbs of quotient at QUOT_PTR. ++ * Return the single-limb remainder. ++ * There are no constraints on the value of the divisor. ++ * ++ * QUOT_PTR and DIVIDEND_PTR might point to the same limb. ++ */ ++ ++mpi_limb_t ++_gcry_mpih_divmod_1( mpi_ptr_t quot_ptr, ++ mpi_ptr_t dividend_ptr, mpi_size_t dividend_size, ++ mpi_limb_t divisor_limb) ++{ ++ mpi_size_t i; ++ mpi_limb_t n1, n0, r; ++ int dummy; ++ ++ if( !dividend_size ) ++ return 0; ++ ++ /* If multiplication is much faster than division, and the ++ * dividend is large, pre-invert the divisor, and use ++ * only multiplications in the inner loop. ++ * ++ * This test should be read: ++ * Does it ever help to use udiv_qrnnd_preinv? ++ * && Does what we save compensate for the inversion overhead? ++ */ ++ if( UDIV_TIME > (2 * UMUL_TIME + 6) ++ && (UDIV_TIME - (2 * UMUL_TIME + 6)) * dividend_size > UDIV_TIME ) { ++ int normalization_steps; ++ ++ count_leading_zeros( normalization_steps, divisor_limb ); ++ if( normalization_steps ) { ++ mpi_limb_t divisor_limb_inverted; ++ ++ divisor_limb <<= normalization_steps; ++ ++ /* Compute (2**2N - 2**N * DIVISOR_LIMB) / DIVISOR_LIMB. The ++ * result is a (N+1)-bit approximation to 1/DIVISOR_LIMB, with the ++ * most significant bit (with weight 2**N) implicit. ++ */ ++ /* Special case for DIVISOR_LIMB == 100...000. */ ++ if( !(divisor_limb << 1) ) ++ divisor_limb_inverted = ~(mpi_limb_t)0; ++ else ++ udiv_qrnnd(divisor_limb_inverted, dummy, ++ -divisor_limb, 0, divisor_limb); ++ ++ n1 = dividend_ptr[dividend_size - 1]; ++ r = n1 >> (BITS_PER_MPI_LIMB - normalization_steps); ++ ++ /* Possible optimization: ++ * if (r == 0 ++ * && divisor_limb > ((n1 << normalization_steps) ++ * | (dividend_ptr[dividend_size - 2] >> ...))) ++ * ...one division less... ++ */ ++ for( i = dividend_size - 2; i >= 0; i--) { ++ n0 = dividend_ptr[i]; ++ UDIV_QRNND_PREINV( quot_ptr[i + 1], r, r, ++ ((n1 << normalization_steps) ++ | (n0 >> (BITS_PER_MPI_LIMB - normalization_steps))), ++ divisor_limb, divisor_limb_inverted); ++ n1 = n0; ++ } ++ UDIV_QRNND_PREINV( quot_ptr[0], r, r, ++ n1 << normalization_steps, ++ divisor_limb, divisor_limb_inverted); ++ return r >> normalization_steps; ++ } ++ else { ++ mpi_limb_t divisor_limb_inverted; ++ ++ /* Compute (2**2N - 2**N * DIVISOR_LIMB) / DIVISOR_LIMB. The ++ * result is a (N+1)-bit approximation to 1/DIVISOR_LIMB, with the ++ * most significant bit (with weight 2**N) implicit. ++ */ ++ /* Special case for DIVISOR_LIMB == 100...000. */ ++ if( !(divisor_limb << 1) ) ++ divisor_limb_inverted = ~(mpi_limb_t) 0; ++ else ++ udiv_qrnnd(divisor_limb_inverted, dummy, ++ -divisor_limb, 0, divisor_limb); ++ ++ i = dividend_size - 1; ++ r = dividend_ptr[i]; ++ ++ if( r >= divisor_limb ) ++ r = 0; ++ else ++ quot_ptr[i--] = 0; ++ ++ for( ; i >= 0; i-- ) { ++ n0 = dividend_ptr[i]; ++ UDIV_QRNND_PREINV( quot_ptr[i], r, r, ++ n0, divisor_limb, divisor_limb_inverted); ++ } ++ return r; ++ } ++ } ++ else { ++ if(UDIV_NEEDS_NORMALIZATION) { ++ int normalization_steps; ++ ++ count_leading_zeros (normalization_steps, divisor_limb); ++ if( normalization_steps ) { ++ divisor_limb <<= normalization_steps; ++ ++ n1 = dividend_ptr[dividend_size - 1]; ++ r = n1 >> (BITS_PER_MPI_LIMB - normalization_steps); ++ ++ /* Possible optimization: ++ * if (r == 0 ++ * && divisor_limb > ((n1 << normalization_steps) ++ * | (dividend_ptr[dividend_size - 2] >> ...))) ++ * ...one division less... ++ */ ++ for( i = dividend_size - 2; i >= 0; i--) { ++ n0 = dividend_ptr[i]; ++ udiv_qrnnd (quot_ptr[i + 1], r, r, ++ ((n1 << normalization_steps) ++ | (n0 >> (BITS_PER_MPI_LIMB - normalization_steps))), ++ divisor_limb); ++ n1 = n0; ++ } ++ udiv_qrnnd (quot_ptr[0], r, r, ++ n1 << normalization_steps, ++ divisor_limb); ++ return r >> normalization_steps; ++ } ++ } ++ /* No normalization needed, either because udiv_qrnnd doesn't require ++ * it, or because DIVISOR_LIMB is already normalized. */ ++ i = dividend_size - 1; ++ r = dividend_ptr[i]; ++ ++ if(r >= divisor_limb) ++ r = 0; ++ else ++ quot_ptr[i--] = 0; ++ ++ for(; i >= 0; i--) { ++ n0 = dividend_ptr[i]; ++ udiv_qrnnd( quot_ptr[i], r, r, n0, divisor_limb ); ++ } ++ return r; ++ } ++} +diff --git a/grub-core/lib/libgcrypt/mpi/mpih-mul.c b/grub-core/lib/libgcrypt/mpi/mpih-mul.c +new file mode 100644 +index 0000000..b8e0561 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/mpih-mul.c +@@ -0,0 +1,528 @@ ++/* mpih-mul.c - MPI helper functions ++ * Copyright (C) 1994, 1996, 1998, 1999, 2000, ++ * 2001, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ * ++ * Note: This code is heavily based on the GNU MP Library. ++ * Actually it's the same code with only minor changes in the ++ * way the data is stored; this is to support the abstraction ++ * of an optional secure memory allocation which may be used ++ * to avoid revealing of sensitive data due to paging etc. ++ */ ++ ++#include ++#include ++#include ++#include ++#include "mpi-internal.h" ++#include "longlong.h" ++#include "g10lib.h" ++ ++#define MPN_MUL_N_RECURSE(prodp, up, vp, size, tspace) \ ++ do { \ ++ if( (size) < KARATSUBA_THRESHOLD ) \ ++ mul_n_basecase (prodp, up, vp, size); \ ++ else \ ++ mul_n (prodp, up, vp, size, tspace); \ ++ } while (0); ++ ++#define MPN_SQR_N_RECURSE(prodp, up, size, tspace) \ ++ do { \ ++ if ((size) < KARATSUBA_THRESHOLD) \ ++ _gcry_mpih_sqr_n_basecase (prodp, up, size); \ ++ else \ ++ _gcry_mpih_sqr_n (prodp, up, size, tspace); \ ++ } while (0); ++ ++ ++ ++ ++/* Multiply the natural numbers u (pointed to by UP) and v (pointed to by VP), ++ * both with SIZE limbs, and store the result at PRODP. 2 * SIZE limbs are ++ * always stored. Return the most significant limb. ++ * ++ * Argument constraints: ++ * 1. PRODP != UP and PRODP != VP, i.e. the destination ++ * must be distinct from the multiplier and the multiplicand. ++ * ++ * ++ * Handle simple cases with traditional multiplication. ++ * ++ * This is the most critical code of multiplication. All multiplies rely ++ * on this, both small and huge. Small ones arrive here immediately. Huge ++ * ones arrive here as this is the base case for Karatsuba's recursive ++ * algorithm below. ++ */ ++ ++static mpi_limb_t ++mul_n_basecase( mpi_ptr_t prodp, mpi_ptr_t up, ++ mpi_ptr_t vp, mpi_size_t size) ++{ ++ mpi_size_t i; ++ mpi_limb_t cy; ++ mpi_limb_t v_limb; ++ ++ /* Multiply by the first limb in V separately, as the result can be ++ * stored (not added) to PROD. We also avoid a loop for zeroing. */ ++ v_limb = vp[0]; ++ if( v_limb <= 1 ) { ++ if( v_limb == 1 ) ++ MPN_COPY( prodp, up, size ); ++ else ++ MPN_ZERO( prodp, size ); ++ cy = 0; ++ } ++ else ++ cy = _gcry_mpih_mul_1( prodp, up, size, v_limb ); ++ ++ prodp[size] = cy; ++ prodp++; ++ ++ /* For each iteration in the outer loop, multiply one limb from ++ * U with one limb from V, and add it to PROD. */ ++ for( i = 1; i < size; i++ ) { ++ v_limb = vp[i]; ++ if( v_limb <= 1 ) { ++ cy = 0; ++ if( v_limb == 1 ) ++ cy = _gcry_mpih_add_n(prodp, prodp, up, size); ++ } ++ else ++ cy = _gcry_mpih_addmul_1(prodp, up, size, v_limb); ++ ++ prodp[size] = cy; ++ prodp++; ++ } ++ ++ return cy; ++} ++ ++ ++static void ++mul_n( mpi_ptr_t prodp, mpi_ptr_t up, mpi_ptr_t vp, ++ mpi_size_t size, mpi_ptr_t tspace ) ++{ ++ if( size & 1 ) { ++ /* The size is odd, and the code below doesn't handle that. ++ * Multiply the least significant (size - 1) limbs with a recursive ++ * call, and handle the most significant limb of S1 and S2 ++ * separately. ++ * A slightly faster way to do this would be to make the Karatsuba ++ * code below behave as if the size were even, and let it check for ++ * odd size in the end. I.e., in essence move this code to the end. ++ * Doing so would save us a recursive call, and potentially make the ++ * stack grow a lot less. ++ */ ++ mpi_size_t esize = size - 1; /* even size */ ++ mpi_limb_t cy_limb; ++ ++ MPN_MUL_N_RECURSE( prodp, up, vp, esize, tspace ); ++ cy_limb = _gcry_mpih_addmul_1( prodp + esize, up, esize, vp[esize] ); ++ prodp[esize + esize] = cy_limb; ++ cy_limb = _gcry_mpih_addmul_1( prodp + esize, vp, size, up[esize] ); ++ prodp[esize + size] = cy_limb; ++ } ++ else { ++ /* Anatolij Alekseevich Karatsuba's divide-and-conquer algorithm. ++ * ++ * Split U in two pieces, U1 and U0, such that ++ * U = U0 + U1*(B**n), ++ * and V in V1 and V0, such that ++ * V = V0 + V1*(B**n). ++ * ++ * UV is then computed recursively using the identity ++ * ++ * 2n n n n ++ * UV = (B + B )U V + B (U -U )(V -V ) + (B + 1)U V ++ * 1 1 1 0 0 1 0 0 ++ * ++ * Where B = 2**BITS_PER_MP_LIMB. ++ */ ++ mpi_size_t hsize = size >> 1; ++ mpi_limb_t cy; ++ int negflg; ++ ++ /* Product H. ________________ ________________ ++ * |_____U1 x V1____||____U0 x V0_____| ++ * Put result in upper part of PROD and pass low part of TSPACE ++ * as new TSPACE. ++ */ ++ MPN_MUL_N_RECURSE(prodp + size, up + hsize, vp + hsize, hsize, tspace); ++ ++ /* Product M. ________________ ++ * |_(U1-U0)(V0-V1)_| ++ */ ++ if( _gcry_mpih_cmp(up + hsize, up, hsize) >= 0 ) { ++ _gcry_mpih_sub_n(prodp, up + hsize, up, hsize); ++ negflg = 0; ++ } ++ else { ++ _gcry_mpih_sub_n(prodp, up, up + hsize, hsize); ++ negflg = 1; ++ } ++ if( _gcry_mpih_cmp(vp + hsize, vp, hsize) >= 0 ) { ++ _gcry_mpih_sub_n(prodp + hsize, vp + hsize, vp, hsize); ++ negflg ^= 1; ++ } ++ else { ++ _gcry_mpih_sub_n(prodp + hsize, vp, vp + hsize, hsize); ++ /* No change of NEGFLG. */ ++ } ++ /* Read temporary operands from low part of PROD. ++ * Put result in low part of TSPACE using upper part of TSPACE ++ * as new TSPACE. ++ */ ++ MPN_MUL_N_RECURSE(tspace, prodp, prodp + hsize, hsize, tspace + size); ++ ++ /* Add/copy product H. */ ++ MPN_COPY (prodp + hsize, prodp + size, hsize); ++ cy = _gcry_mpih_add_n( prodp + size, prodp + size, ++ prodp + size + hsize, hsize); ++ ++ /* Add product M (if NEGFLG M is a negative number) */ ++ if(negflg) ++ cy -= _gcry_mpih_sub_n(prodp + hsize, prodp + hsize, tspace, size); ++ else ++ cy += _gcry_mpih_add_n(prodp + hsize, prodp + hsize, tspace, size); ++ ++ /* Product L. ________________ ________________ ++ * |________________||____U0 x V0_____| ++ * Read temporary operands from low part of PROD. ++ * Put result in low part of TSPACE using upper part of TSPACE ++ * as new TSPACE. ++ */ ++ MPN_MUL_N_RECURSE(tspace, up, vp, hsize, tspace + size); ++ ++ /* Add/copy Product L (twice) */ ++ ++ cy += _gcry_mpih_add_n(prodp + hsize, prodp + hsize, tspace, size); ++ if( cy ) ++ _gcry_mpih_add_1(prodp + hsize + size, prodp + hsize + size, hsize, cy); ++ ++ MPN_COPY(prodp, tspace, hsize); ++ cy = _gcry_mpih_add_n(prodp + hsize, prodp + hsize, tspace + hsize, hsize); ++ if( cy ) ++ _gcry_mpih_add_1(prodp + size, prodp + size, size, 1); ++ } ++} ++ ++ ++void ++_gcry_mpih_sqr_n_basecase( mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t size ) ++{ ++ mpi_size_t i; ++ mpi_limb_t cy_limb; ++ mpi_limb_t v_limb; ++ ++ /* Multiply by the first limb in V separately, as the result can be ++ * stored (not added) to PROD. We also avoid a loop for zeroing. */ ++ v_limb = up[0]; ++ if( v_limb <= 1 ) { ++ if( v_limb == 1 ) ++ MPN_COPY( prodp, up, size ); ++ else ++ MPN_ZERO(prodp, size); ++ cy_limb = 0; ++ } ++ else ++ cy_limb = _gcry_mpih_mul_1( prodp, up, size, v_limb ); ++ ++ prodp[size] = cy_limb; ++ prodp++; ++ ++ /* For each iteration in the outer loop, multiply one limb from ++ * U with one limb from V, and add it to PROD. */ ++ for( i=1; i < size; i++) { ++ v_limb = up[i]; ++ if( v_limb <= 1 ) { ++ cy_limb = 0; ++ if( v_limb == 1 ) ++ cy_limb = _gcry_mpih_add_n(prodp, prodp, up, size); ++ } ++ else ++ cy_limb = _gcry_mpih_addmul_1(prodp, up, size, v_limb); ++ ++ prodp[size] = cy_limb; ++ prodp++; ++ } ++} ++ ++ ++void ++_gcry_mpih_sqr_n( mpi_ptr_t prodp, ++ mpi_ptr_t up, mpi_size_t size, mpi_ptr_t tspace) ++{ ++ if( size & 1 ) { ++ /* The size is odd, and the code below doesn't handle that. ++ * Multiply the least significant (size - 1) limbs with a recursive ++ * call, and handle the most significant limb of S1 and S2 ++ * separately. ++ * A slightly faster way to do this would be to make the Karatsuba ++ * code below behave as if the size were even, and let it check for ++ * odd size in the end. I.e., in essence move this code to the end. ++ * Doing so would save us a recursive call, and potentially make the ++ * stack grow a lot less. ++ */ ++ mpi_size_t esize = size - 1; /* even size */ ++ mpi_limb_t cy_limb; ++ ++ MPN_SQR_N_RECURSE( prodp, up, esize, tspace ); ++ cy_limb = _gcry_mpih_addmul_1( prodp + esize, up, esize, up[esize] ); ++ prodp[esize + esize] = cy_limb; ++ cy_limb = _gcry_mpih_addmul_1( prodp + esize, up, size, up[esize] ); ++ ++ prodp[esize + size] = cy_limb; ++ } ++ else { ++ mpi_size_t hsize = size >> 1; ++ mpi_limb_t cy; ++ ++ /* Product H. ________________ ________________ ++ * |_____U1 x U1____||____U0 x U0_____| ++ * Put result in upper part of PROD and pass low part of TSPACE ++ * as new TSPACE. ++ */ ++ MPN_SQR_N_RECURSE(prodp + size, up + hsize, hsize, tspace); ++ ++ /* Product M. ________________ ++ * |_(U1-U0)(U0-U1)_| ++ */ ++ if( _gcry_mpih_cmp( up + hsize, up, hsize) >= 0 ) ++ _gcry_mpih_sub_n( prodp, up + hsize, up, hsize); ++ else ++ _gcry_mpih_sub_n (prodp, up, up + hsize, hsize); ++ ++ /* Read temporary operands from low part of PROD. ++ * Put result in low part of TSPACE using upper part of TSPACE ++ * as new TSPACE. */ ++ MPN_SQR_N_RECURSE(tspace, prodp, hsize, tspace + size); ++ ++ /* Add/copy product H */ ++ MPN_COPY(prodp + hsize, prodp + size, hsize); ++ cy = _gcry_mpih_add_n(prodp + size, prodp + size, ++ prodp + size + hsize, hsize); ++ ++ /* Add product M (if NEGFLG M is a negative number). */ ++ cy -= _gcry_mpih_sub_n (prodp + hsize, prodp + hsize, tspace, size); ++ ++ /* Product L. ________________ ________________ ++ * |________________||____U0 x U0_____| ++ * Read temporary operands from low part of PROD. ++ * Put result in low part of TSPACE using upper part of TSPACE ++ * as new TSPACE. */ ++ MPN_SQR_N_RECURSE (tspace, up, hsize, tspace + size); ++ ++ /* Add/copy Product L (twice). */ ++ cy += _gcry_mpih_add_n (prodp + hsize, prodp + hsize, tspace, size); ++ if( cy ) ++ _gcry_mpih_add_1(prodp + hsize + size, prodp + hsize + size, ++ hsize, cy); ++ ++ MPN_COPY(prodp, tspace, hsize); ++ cy = _gcry_mpih_add_n (prodp + hsize, prodp + hsize, tspace + hsize, hsize); ++ if( cy ) ++ _gcry_mpih_add_1 (prodp + size, prodp + size, size, 1); ++ } ++} ++ ++ ++/* This should be made into an inline function in gmp.h. */ ++void ++_gcry_mpih_mul_n( mpi_ptr_t prodp, ++ mpi_ptr_t up, mpi_ptr_t vp, mpi_size_t size) ++{ ++ int secure; ++ ++ if( up == vp ) { ++ if( size < KARATSUBA_THRESHOLD ) ++ _gcry_mpih_sqr_n_basecase( prodp, up, size ); ++ else { ++ mpi_ptr_t tspace; ++ secure = gcry_is_secure( up ); ++ tspace = mpi_alloc_limb_space( 2 * size, secure ); ++ _gcry_mpih_sqr_n( prodp, up, size, tspace ); ++ _gcry_mpi_free_limb_space (tspace, 2 * size ); ++ } ++ } ++ else { ++ if( size < KARATSUBA_THRESHOLD ) ++ mul_n_basecase( prodp, up, vp, size ); ++ else { ++ mpi_ptr_t tspace; ++ secure = gcry_is_secure( up ) || gcry_is_secure( vp ); ++ tspace = mpi_alloc_limb_space( 2 * size, secure ); ++ mul_n (prodp, up, vp, size, tspace); ++ _gcry_mpi_free_limb_space (tspace, 2 * size ); ++ } ++ } ++} ++ ++ ++ ++void ++_gcry_mpih_mul_karatsuba_case( mpi_ptr_t prodp, ++ mpi_ptr_t up, mpi_size_t usize, ++ mpi_ptr_t vp, mpi_size_t vsize, ++ struct karatsuba_ctx *ctx ) ++{ ++ mpi_limb_t cy; ++ ++ if( !ctx->tspace || ctx->tspace_size < vsize ) { ++ if( ctx->tspace ) ++ _gcry_mpi_free_limb_space( ctx->tspace, ctx->tspace_nlimbs ); ++ ctx->tspace_nlimbs = 2 * vsize; ++ ctx->tspace = mpi_alloc_limb_space( 2 * vsize, ++ (gcry_is_secure( up ) ++ || gcry_is_secure( vp )) ); ++ ctx->tspace_size = vsize; ++ } ++ ++ MPN_MUL_N_RECURSE( prodp, up, vp, vsize, ctx->tspace ); ++ ++ prodp += vsize; ++ up += vsize; ++ usize -= vsize; ++ if( usize >= vsize ) { ++ if( !ctx->tp || ctx->tp_size < vsize ) { ++ if( ctx->tp ) ++ _gcry_mpi_free_limb_space( ctx->tp, ctx->tp_nlimbs ); ++ ctx->tp_nlimbs = 2 * vsize; ++ ctx->tp = mpi_alloc_limb_space( 2 * vsize, gcry_is_secure( up ) ++ || gcry_is_secure( vp ) ); ++ ctx->tp_size = vsize; ++ } ++ ++ do { ++ MPN_MUL_N_RECURSE( ctx->tp, up, vp, vsize, ctx->tspace ); ++ cy = _gcry_mpih_add_n( prodp, prodp, ctx->tp, vsize ); ++ _gcry_mpih_add_1( prodp + vsize, ctx->tp + vsize, vsize, cy ); ++ prodp += vsize; ++ up += vsize; ++ usize -= vsize; ++ } while( usize >= vsize ); ++ } ++ ++ if( usize ) { ++ if( usize < KARATSUBA_THRESHOLD ) { ++ _gcry_mpih_mul( ctx->tspace, vp, vsize, up, usize ); ++ } ++ else { ++ if( !ctx->next ) { ++ ctx->next = gcry_xcalloc( 1, sizeof *ctx ); ++ } ++ _gcry_mpih_mul_karatsuba_case( ctx->tspace, ++ vp, vsize, ++ up, usize, ++ ctx->next ); ++ } ++ ++ cy = _gcry_mpih_add_n( prodp, prodp, ctx->tspace, vsize); ++ _gcry_mpih_add_1( prodp + vsize, ctx->tspace + vsize, usize, cy ); ++ } ++} ++ ++ ++void ++_gcry_mpih_release_karatsuba_ctx( struct karatsuba_ctx *ctx ) ++{ ++ struct karatsuba_ctx *ctx2; ++ ++ if( ctx->tp ) ++ _gcry_mpi_free_limb_space( ctx->tp, ctx->tp_nlimbs ); ++ if( ctx->tspace ) ++ _gcry_mpi_free_limb_space( ctx->tspace, ctx->tspace_nlimbs ); ++ for( ctx=ctx->next; ctx; ctx = ctx2 ) { ++ ctx2 = ctx->next; ++ if( ctx->tp ) ++ _gcry_mpi_free_limb_space( ctx->tp, ctx->tp_nlimbs ); ++ if( ctx->tspace ) ++ _gcry_mpi_free_limb_space( ctx->tspace, ctx->tspace_nlimbs ); ++ gcry_free( ctx ); ++ } ++} ++ ++/* Multiply the natural numbers u (pointed to by UP, with USIZE limbs) ++ * and v (pointed to by VP, with VSIZE limbs), and store the result at ++ * PRODP. USIZE + VSIZE limbs are always stored, but if the input ++ * operands are normalized. Return the most significant limb of the ++ * result. ++ * ++ * NOTE: The space pointed to by PRODP is overwritten before finished ++ * with U and V, so overlap is an error. ++ * ++ * Argument constraints: ++ * 1. USIZE >= VSIZE. ++ * 2. PRODP != UP and PRODP != VP, i.e. the destination ++ * must be distinct from the multiplier and the multiplicand. ++ */ ++ ++mpi_limb_t ++_gcry_mpih_mul( mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t usize, ++ mpi_ptr_t vp, mpi_size_t vsize) ++{ ++ mpi_ptr_t prod_endp = prodp + usize + vsize - 1; ++ mpi_limb_t cy; ++ struct karatsuba_ctx ctx; ++ ++ if( vsize < KARATSUBA_THRESHOLD ) { ++ mpi_size_t i; ++ mpi_limb_t v_limb; ++ ++ if( !vsize ) ++ return 0; ++ ++ /* Multiply by the first limb in V separately, as the result can be ++ * stored (not added) to PROD. We also avoid a loop for zeroing. */ ++ v_limb = vp[0]; ++ if( v_limb <= 1 ) { ++ if( v_limb == 1 ) ++ MPN_COPY( prodp, up, usize ); ++ else ++ MPN_ZERO( prodp, usize ); ++ cy = 0; ++ } ++ else ++ cy = _gcry_mpih_mul_1( prodp, up, usize, v_limb ); ++ ++ prodp[usize] = cy; ++ prodp++; ++ ++ /* For each iteration in the outer loop, multiply one limb from ++ * U with one limb from V, and add it to PROD. */ ++ for( i = 1; i < vsize; i++ ) { ++ v_limb = vp[i]; ++ if( v_limb <= 1 ) { ++ cy = 0; ++ if( v_limb == 1 ) ++ cy = _gcry_mpih_add_n(prodp, prodp, up, usize); ++ } ++ else ++ cy = _gcry_mpih_addmul_1(prodp, up, usize, v_limb); ++ ++ prodp[usize] = cy; ++ prodp++; ++ } ++ ++ return cy; ++ } ++ ++ memset( &ctx, 0, sizeof ctx ); ++ _gcry_mpih_mul_karatsuba_case( prodp, up, usize, vp, vsize, &ctx ); ++ _gcry_mpih_release_karatsuba_ctx( &ctx ); ++ return *prod_endp; ++} +diff --git a/grub-core/lib/libgcrypt/mpi/mpiutil.c b/grub-core/lib/libgcrypt/mpi/mpiutil.c +new file mode 100644 +index 0000000..76630a6 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/mpiutil.c +@@ -0,0 +1,460 @@ ++/* mpiutil.ac - Utility functions for MPI ++ * Copyright (C) 1998, 2000, 2001, 2002, 2003, ++ * 2007 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, see . ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#include "g10lib.h" ++#include "mpi-internal.h" ++#include "mod-source-info.h" ++ ++ ++const char * ++_gcry_mpi_get_hw_config (void) ++{ ++ return mod_source_info + 1; ++} ++ ++ ++/**************** ++ * Note: It was a bad idea to use the number of limbs to allocate ++ * because on a alpha the limbs are large but we normally need ++ * integers of n bits - So we should change this to bits (or bytes). ++ * ++ * But mpi_alloc is used in a lot of places :-(. New code ++ * should use mpi_new. ++ */ ++gcry_mpi_t ++_gcry_mpi_alloc( unsigned nlimbs ) ++{ ++ gcry_mpi_t a; ++ ++ a = gcry_xmalloc( sizeof *a ); ++ a->d = nlimbs? mpi_alloc_limb_space( nlimbs, 0 ) : NULL; ++ a->alloced = nlimbs; ++ a->nlimbs = 0; ++ a->sign = 0; ++ a->flags = 0; ++ return a; ++} ++ ++void ++_gcry_mpi_m_check( gcry_mpi_t a ) ++{ ++ _gcry_check_heap(a); ++ _gcry_check_heap(a->d); ++} ++ ++gcry_mpi_t ++_gcry_mpi_alloc_secure( unsigned nlimbs ) ++{ ++ gcry_mpi_t a; ++ ++ a = gcry_xmalloc( sizeof *a ); ++ a->d = nlimbs? mpi_alloc_limb_space( nlimbs, 1 ) : NULL; ++ a->alloced = nlimbs; ++ a->flags = 1; ++ a->nlimbs = 0; ++ a->sign = 0; ++ return a; ++} ++ ++ ++ ++mpi_ptr_t ++_gcry_mpi_alloc_limb_space( unsigned int nlimbs, int secure ) ++{ ++ mpi_ptr_t p; ++ size_t len; ++ ++ len = (nlimbs ? nlimbs : 1) * sizeof (mpi_limb_t); ++ p = secure ? gcry_xmalloc_secure (len) : gcry_xmalloc (len); ++ if (! nlimbs) ++ *p = 0; ++ ++ return p; ++} ++ ++void ++_gcry_mpi_free_limb_space( mpi_ptr_t a, unsigned int nlimbs) ++{ ++ if (a) ++ { ++ size_t len = nlimbs * sizeof(mpi_limb_t); ++ ++ /* If we have information on the number of allocated limbs, we ++ better wipe that space out. This is a failsafe feature if ++ secure memory has been disabled or was not properly ++ implemented in user provided allocation functions. */ ++ if (len) ++ wipememory (a, len); ++ gcry_free(a); ++ } ++} ++ ++ ++void ++_gcry_mpi_assign_limb_space( gcry_mpi_t a, mpi_ptr_t ap, unsigned int nlimbs ) ++{ ++ _gcry_mpi_free_limb_space (a->d, a->alloced); ++ a->d = ap; ++ a->alloced = nlimbs; ++} ++ ++ ++ ++/**************** ++ * Resize the array of A to NLIMBS. The additional space is cleared ++ * (set to 0). ++ */ ++void ++_gcry_mpi_resize (gcry_mpi_t a, unsigned nlimbs) ++{ ++ size_t i; ++ ++ if (nlimbs <= a->alloced) ++ { ++ /* We only need to clear the new space (this is a nop if the ++ limb space is already of the correct size. */ ++ for (i=a->nlimbs; i < a->alloced; i++) ++ a->d[i] = 0; ++ return; ++ } ++ ++ /* Actually resize the limb space. */ ++ if (a->d) ++ { ++ a->d = gcry_xrealloc (a->d, nlimbs * sizeof (mpi_limb_t)); ++ for (i=a->alloced; i < nlimbs; i++) ++ a->d[i] = 0; ++ } ++ else ++ { ++ if (a->flags & 1) ++ /* Secure memory is wanted. */ ++ a->d = gcry_xcalloc_secure (nlimbs , sizeof (mpi_limb_t)); ++ else ++ /* Standard memory. */ ++ a->d = gcry_xcalloc (nlimbs , sizeof (mpi_limb_t)); ++ } ++ a->alloced = nlimbs; ++} ++ ++void ++_gcry_mpi_clear( gcry_mpi_t a ) ++{ ++ a->nlimbs = 0; ++ a->flags = 0; ++} ++ ++ ++void ++_gcry_mpi_free( gcry_mpi_t a ) ++{ ++ if (!a ) ++ return; ++ if ((a->flags & 4)) ++ gcry_free( a->d ); ++ else ++ { ++ _gcry_mpi_free_limb_space(a->d, a->alloced); ++ } ++ if ((a->flags & ~7)) ++ log_bug("invalid flag value in mpi\n"); ++ gcry_free(a); ++} ++ ++static void ++mpi_set_secure( gcry_mpi_t a ) ++{ ++ mpi_ptr_t ap, bp; ++ ++ if ( (a->flags & 1) ) ++ return; ++ a->flags |= 1; ++ ap = a->d; ++ if (!a->nlimbs) ++ { ++ gcry_assert (!ap); ++ return; ++ } ++ bp = mpi_alloc_limb_space (a->nlimbs, 1); ++ MPN_COPY( bp, ap, a->nlimbs ); ++ a->d = bp; ++ _gcry_mpi_free_limb_space (ap, a->alloced); ++} ++ ++ ++gcry_mpi_t ++gcry_mpi_set_opaque( gcry_mpi_t a, void *p, unsigned int nbits ) ++{ ++ if (!a) ++ a = mpi_alloc(0); ++ ++ if( a->flags & 4 ) ++ gcry_free( a->d ); ++ else ++ _gcry_mpi_free_limb_space (a->d, a->alloced); ++ ++ a->d = p; ++ a->alloced = 0; ++ a->nlimbs = 0; ++ a->sign = nbits; ++ a->flags = 4; ++ return a; ++} ++ ++ ++void * ++gcry_mpi_get_opaque( gcry_mpi_t a, unsigned int *nbits ) ++{ ++ if( !(a->flags & 4) ) ++ log_bug("mpi_get_opaque on normal mpi\n"); ++ if( nbits ) ++ *nbits = a->sign; ++ return a->d; ++} ++ ++ ++/**************** ++ * Note: This copy function should not interpret the MPI ++ * but copy it transparently. ++ */ ++gcry_mpi_t ++gcry_mpi_copy( gcry_mpi_t a ) ++{ ++ int i; ++ gcry_mpi_t b; ++ ++ if( a && (a->flags & 4) ) { ++ void *p = gcry_is_secure(a->d)? gcry_xmalloc_secure( (a->sign+7)/8 ) ++ : gcry_xmalloc( (a->sign+7)/8 ); ++ memcpy( p, a->d, (a->sign+7)/8 ); ++ b = gcry_mpi_set_opaque( NULL, p, a->sign ); ++ } ++ else if( a ) { ++ b = mpi_is_secure(a)? mpi_alloc_secure( a->nlimbs ) ++ : mpi_alloc( a->nlimbs ); ++ b->nlimbs = a->nlimbs; ++ b->sign = a->sign; ++ b->flags = a->flags; ++ for(i=0; i < b->nlimbs; i++ ) ++ b->d[i] = a->d[i]; ++ } ++ else ++ b = NULL; ++ return b; ++} ++ ++ ++/**************** ++ * This function allocates an MPI which is optimized to hold ++ * a value as large as the one given in the argument and allocates it ++ * with the same flags as A. ++ */ ++gcry_mpi_t ++_gcry_mpi_alloc_like( gcry_mpi_t a ) ++{ ++ gcry_mpi_t b; ++ ++ if( a && (a->flags & 4) ) { ++ int n = (a->sign+7)/8; ++ void *p = gcry_is_secure(a->d)? gcry_malloc_secure( n ) ++ : gcry_malloc( n ); ++ memcpy( p, a->d, n ); ++ b = gcry_mpi_set_opaque( NULL, p, a->sign ); ++ } ++ else if( a ) { ++ b = mpi_is_secure(a)? mpi_alloc_secure( a->nlimbs ) ++ : mpi_alloc( a->nlimbs ); ++ b->nlimbs = 0; ++ b->sign = 0; ++ b->flags = a->flags; ++ } ++ else ++ b = NULL; ++ return b; ++} ++ ++ ++gcry_mpi_t ++gcry_mpi_set( gcry_mpi_t w, gcry_mpi_t u) ++{ ++ mpi_ptr_t wp, up; ++ mpi_size_t usize = u->nlimbs; ++ int usign = u->sign; ++ ++ if (!w) ++ w = _gcry_mpi_alloc( mpi_get_nlimbs(u) ); ++ RESIZE_IF_NEEDED(w, usize); ++ wp = w->d; ++ up = u->d; ++ MPN_COPY( wp, up, usize ); ++ w->nlimbs = usize; ++ w->flags = u->flags; ++ w->sign = usign; ++ return w; ++} ++ ++ ++gcry_mpi_t ++gcry_mpi_set_ui( gcry_mpi_t w, unsigned long u) ++{ ++ if (!w) ++ w = _gcry_mpi_alloc (1); ++ /* FIXME: If U is 0 we have no need to resize and thus possible ++ allocating the the limbs. */ ++ RESIZE_IF_NEEDED(w, 1); ++ w->d[0] = u; ++ w->nlimbs = u? 1:0; ++ w->sign = 0; ++ w->flags = 0; ++ return w; ++} ++ ++gcry_err_code_t ++_gcry_mpi_get_ui (gcry_mpi_t w, unsigned long *u) ++{ ++ gcry_err_code_t err = GPG_ERR_NO_ERROR; ++ unsigned long x = 0; ++ ++ if (w->nlimbs > 1) ++ err = GPG_ERR_TOO_LARGE; ++ else if (w->nlimbs == 1) ++ x = w->d[0]; ++ else ++ x = 0; ++ ++ if (! err) ++ *u = x; ++ ++ return err; ++} ++ ++gcry_error_t ++gcry_mpi_get_ui (gcry_mpi_t w, unsigned long *u) ++{ ++ gcry_err_code_t err = GPG_ERR_NO_ERROR; ++ ++ err = _gcry_mpi_get_ui (w, u); ++ ++ return gcry_error (err); ++} ++ ++gcry_mpi_t ++_gcry_mpi_alloc_set_ui( unsigned long u) ++{ ++ gcry_mpi_t w = mpi_alloc(1); ++ w->d[0] = u; ++ w->nlimbs = u? 1:0; ++ w->sign = 0; ++ return w; ++} ++ ++void ++gcry_mpi_swap( gcry_mpi_t a, gcry_mpi_t b) ++{ ++ struct gcry_mpi tmp; ++ ++ tmp = *a; *a = *b; *b = tmp; ++} ++ ++ ++gcry_mpi_t ++gcry_mpi_new( unsigned int nbits ) ++{ ++ return _gcry_mpi_alloc ( (nbits+BITS_PER_MPI_LIMB-1) ++ / BITS_PER_MPI_LIMB ); ++} ++ ++ ++gcry_mpi_t ++gcry_mpi_snew( unsigned int nbits ) ++{ ++ return _gcry_mpi_alloc_secure ( (nbits+BITS_PER_MPI_LIMB-1) ++ / BITS_PER_MPI_LIMB ); ++} ++ ++void ++gcry_mpi_release( gcry_mpi_t a ) ++{ ++ _gcry_mpi_free( a ); ++} ++ ++void ++gcry_mpi_randomize( gcry_mpi_t w, ++ unsigned int nbits, enum gcry_random_level level ) ++{ ++ unsigned char *p; ++ size_t nbytes = (nbits+7)/8; ++ ++ if (level == GCRY_WEAK_RANDOM) ++ { ++ p = mpi_is_secure(w) ? gcry_xmalloc_secure (nbytes) ++ : gcry_xmalloc (nbytes); ++ gcry_create_nonce (p, nbytes); ++ } ++ else ++ { ++ p = mpi_is_secure(w) ? gcry_random_bytes_secure (nbytes, level) ++ : gcry_random_bytes (nbytes, level); ++ } ++ _gcry_mpi_set_buffer( w, p, nbytes, 0 ); ++ gcry_free (p); ++} ++ ++ ++void ++gcry_mpi_set_flag( gcry_mpi_t a, enum gcry_mpi_flag flag ) ++{ ++ switch( flag ) { ++ case GCRYMPI_FLAG_SECURE: mpi_set_secure(a); break; ++ case GCRYMPI_FLAG_OPAQUE: ++ default: log_bug("invalid flag value\n"); ++ } ++} ++ ++void ++gcry_mpi_clear_flag( gcry_mpi_t a, enum gcry_mpi_flag flag ) ++{ ++ (void)a; /* Not yet used. */ ++ ++ switch (flag) ++ { ++ case GCRYMPI_FLAG_SECURE: ++ case GCRYMPI_FLAG_OPAQUE: ++ default: log_bug("invalid flag value\n"); ++ } ++} ++ ++int ++gcry_mpi_get_flag( gcry_mpi_t a, enum gcry_mpi_flag flag ) ++{ ++ switch (flag) ++ { ++ case GCRYMPI_FLAG_SECURE: return (a->flags & 1); ++ case GCRYMPI_FLAG_OPAQUE: return (a->flags & 4); ++ default: log_bug("invalid flag value\n"); ++ } ++ /*NOTREACHED*/ ++ return 0; ++} +diff --git a/grub-core/lib/libgcrypt/mpi/pa7100/Manifest b/grub-core/lib/libgcrypt/mpi/pa7100/Manifest +new file mode 100644 +index 0000000..f075ab0 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/pa7100/Manifest +@@ -0,0 +1,22 @@ ++# Manifest - checksums ++# Copyright 2003 Free Software Foundation, Inc. ++# ++# This file is part of Libgcrypt. ++# ++# Libgcrypt is free software; you can redistribute it and/or modify ++# it under the terms of the GNU Lesser General Public License as ++# published by the Free Software Foundation; either version 2.1 of ++# the License, or (at your option) any later version. ++# ++# Libgcrypt 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 Lesser General Public License for more details. ++# ++# You should have received a copy of the GNU Lesser General Public ++# License along with this program; if not, write to the Free Software ++# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ ++mpih-lshift.S ++mpih-rshift.S ++$names$ iQCVAwUAP+LmVjEAnp832S/7AQKlEQQAv2+x/d+Z0t8FwwHlxKpIKOJDr9e+Y2i8y8orcIEa3dnwU5LMOH3EzFoNSD9crc31FMokgm/X5xeLjqRTdcmGHyJJQJDPJVJyuaOm6qHJaFzzfJjrfMW66nJxfNSXIiIm4DgpP20NmumaorLCkiIZ5Z81KGAc8FiRggbRVYx+wxo==Vjh9 +diff --git a/grub-core/lib/libgcrypt/mpi/pa7100/distfiles b/grub-core/lib/libgcrypt/mpi/pa7100/distfiles +new file mode 100644 +index 0000000..e1cde4d +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/pa7100/distfiles +@@ -0,0 +1,4 @@ ++Manifest ++mpih-lshift.S ++mpih-rshift.S ++ +diff --git a/grub-core/lib/libgcrypt/mpi/pa7100/mpih-lshift.S b/grub-core/lib/libgcrypt/mpi/pa7100/mpih-lshift.S +new file mode 100644 +index 0000000..8ade196 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/pa7100/mpih-lshift.S +@@ -0,0 +1,96 @@ ++/* hppa lshift ++ * optimized for the PA7100, where it runs at 3.25 cycles/limb ++ * ++ * Copyright (C) 1992, 1994, 1998, ++ * 2001, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ */ ++ ++ ++ ++/******************* ++ * mpi_limb_t ++ * _gcry_mpih_lshift( mpi_ptr_t wp, (gr26) ++ * mpi_ptr_t up, (gr25) ++ * mpi_size_t usize, (gr24) ++ * unsigned cnt) (gr23) ++ */ ++ ++ .code ++ .export _gcry_mpih_lshift ++ .label _gcry_mpih_lshift ++ .proc ++ .callinfo frame=64,no_calls ++ .entry ++ ++ sh2add %r24,%r25,%r25 ++ sh2add %r24,%r26,%r26 ++ ldws,mb -4(0,%r25),%r22 ++ subi 32,%r23,%r1 ++ mtsar %r1 ++ addib,= -1,%r24,L$0004 ++ vshd %r0,%r22,%r28 ; compute carry out limb ++ ldws,mb -4(0,%r25),%r29 ++ addib,<= -5,%r24,L$rest ++ vshd %r22,%r29,%r20 ++ ++ .label L$loop ++ ldws,mb -4(0,%r25),%r22 ++ stws,mb %r20,-4(0,%r26) ++ vshd %r29,%r22,%r20 ++ ldws,mb -4(0,%r25),%r29 ++ stws,mb %r20,-4(0,%r26) ++ vshd %r22,%r29,%r20 ++ ldws,mb -4(0,%r25),%r22 ++ stws,mb %r20,-4(0,%r26) ++ vshd %r29,%r22,%r20 ++ ldws,mb -4(0,%r25),%r29 ++ stws,mb %r20,-4(0,%r26) ++ addib,> -4,%r24,L$loop ++ vshd %r22,%r29,%r20 ++ ++ .label L$rest ++ addib,= 4,%r24,L$end1 ++ nop ++ .label L$eloop ++ ldws,mb -4(0,%r25),%r22 ++ stws,mb %r20,-4(0,%r26) ++ addib,<= -1,%r24,L$end2 ++ vshd %r29,%r22,%r20 ++ ldws,mb -4(0,%r25),%r29 ++ stws,mb %r20,-4(0,%r26) ++ addib,> -1,%r24,L$eloop ++ vshd %r22,%r29,%r20 ++ ++ .label L$end1 ++ stws,mb %r20,-4(0,%r26) ++ vshd %r29,%r0,%r20 ++ bv 0(%r2) ++ stw %r20,-4(0,%r26) ++ .label L$end2 ++ stws,mb %r20,-4(0,%r26) ++ .label L$0004 ++ vshd %r22,%r0,%r20 ++ bv 0(%r2) ++ stw %r20,-4(0,%r26) ++ ++ .exit ++ .procend ++ ++ ++ +diff --git a/grub-core/lib/libgcrypt/mpi/pa7100/mpih-rshift.S b/grub-core/lib/libgcrypt/mpi/pa7100/mpih-rshift.S +new file mode 100644 +index 0000000..0624202 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/pa7100/mpih-rshift.S +@@ -0,0 +1,92 @@ ++/* hppa rshift ++ * optimized for the PA7100, where it runs at 3.25 cycles/limb ++ * ++ * Copyright (C) 1992, 1994, 1998, ++ * 2001, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ */ ++ ++ ++ ++/******************* ++ * mpi_limb_t ++ * _gcry_mpih_rshift( mpi_ptr_t wp, (gr26) ++ * mpi_ptr_t up, (gr25) ++ * mpi_size_t usize, (gr24) ++ * unsigned cnt) (gr23) ++ */ ++ ++ .code ++ .export _gcry_mpih_rshift ++ .label _gcry_mpih_rshift ++ .proc ++ .callinfo frame=64,no_calls ++ .entry ++ ++ ldws,ma 4(0,%r25),%r22 ++ mtsar %r23 ++ addib,= -1,%r24,L$r004 ++ vshd %r22,%r0,%r28 ; compute carry out limb ++ ldws,ma 4(0,%r25),%r29 ++ addib,<= -5,%r24,L$rrest ++ vshd %r29,%r22,%r20 ++ ++ .label L$roop ++ ldws,ma 4(0,%r25),%r22 ++ stws,ma %r20,4(0,%r26) ++ vshd %r22,%r29,%r20 ++ ldws,ma 4(0,%r25),%r29 ++ stws,ma %r20,4(0,%r26) ++ vshd %r29,%r22,%r20 ++ ldws,ma 4(0,%r25),%r22 ++ stws,ma %r20,4(0,%r26) ++ vshd %r22,%r29,%r20 ++ ldws,ma 4(0,%r25),%r29 ++ stws,ma %r20,4(0,%r26) ++ addib,> -4,%r24,L$roop ++ vshd %r29,%r22,%r20 ++ ++ .label L$rrest ++ addib,= 4,%r24,L$rend1 ++ nop ++ .label L$eroop ++ ldws,ma 4(0,%r25),%r22 ++ stws,ma %r20,4(0,%r26) ++ addib,<= -1,%r24,L$rend2 ++ vshd %r22,%r29,%r20 ++ ldws,ma 4(0,%r25),%r29 ++ stws,ma %r20,4(0,%r26) ++ addib,> -1,%r24,L$eroop ++ vshd %r29,%r22,%r20 ++ ++ .label L$rend1 ++ stws,ma %r20,4(0,%r26) ++ vshd %r0,%r29,%r20 ++ bv 0(%r2) ++ stw %r20,0(0,%r26) ++ .label L$rend2 ++ stws,ma %r20,4(0,%r26) ++ .label L$r004 ++ vshd %r0,%r22,%r20 ++ bv 0(%r2) ++ stw %r20,0(0,%r26) ++ ++ .exit ++ .procend ++ ++ +diff --git a/grub-core/lib/libgcrypt/mpi/pentium4/README b/grub-core/lib/libgcrypt/mpi/pentium4/README +new file mode 100644 +index 0000000..215fc7f +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/pentium4/README +@@ -0,0 +1,115 @@ ++Copyright 2001 Free Software Foundation, Inc. ++ ++This file is part of the GNU MP Library. ++ ++The GNU MP Library is free software; you can redistribute it and/or modify ++it under the terms of the GNU Lesser General Public License as published by ++the Free Software Foundation; either version 2.1 of the License, or (at your ++option) any later version. ++ ++The GNU MP Library 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 Lesser General Public ++License for more details. ++ ++You should have received a copy of the GNU Lesser General Public License ++along with the GNU MP Library; see the file COPYING.LIB. If not, write to ++the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA ++02110-1301, USA. ++ ++ ++ ++ ++ INTEL PENTIUM-4 MPN SUBROUTINES ++ ++ ++This directory contains mpn functions optimized for Intel Pentium-4. ++ ++The mmx subdirectory has routines using MMX instructions, the sse2 ++subdirectory has routines using SSE2 instructions. All P4s have these, the ++separate directories are just so configure can omit that code if the ++assembler doesn't support it. ++ ++ ++STATUS ++ ++ cycles/limb ++ ++ mpn_add_n/sub_n 4 normal, 6 in-place ++ ++ mpn_mul_1 4 normal, 6 in-place ++ mpn_addmul_1 6 ++ mpn_submul_1 7 ++ ++ mpn_mul_basecase 6 cycles/crossproduct (approx) ++ ++ mpn_sqr_basecase 3.5 cycles/crossproduct (approx) ++ or 7.0 cycles/triangleproduct (approx) ++ ++ mpn_l/rshift 1.75 ++ ++ ++ ++The shifts ought to be able to go at 1.5 c/l, but not much effort has been ++applied to them yet. ++ ++In-place operations, and all addmul, submul, mul_basecase and sqr_basecase ++calls, suffer from pipeline anomalies associated with write combining and ++movd reads and writes to the same or nearby locations. The movq ++instructions do not trigger the same hardware problems. Unfortunately, ++using movq and splitting/combining seems to require too many extra ++instructions to help. Perhaps future chip steppings will be better. ++ ++ ++ ++NOTES ++ ++The Pentium-4 pipeline "Netburst", provides for quite a number of surprises. ++Many traditional x86 instructions run very slowly, requiring use of ++alterative instructions for acceptable performance. ++ ++adcl and sbbl are quite slow at 8 cycles for reg->reg. paddq of 32-bits ++within a 64-bit mmx register seems better, though the combination ++paddq/psrlq when propagating a carry is still a 4 cycle latency. ++ ++incl and decl should be avoided, instead use add $1 and sub $1. Apparently ++the carry flag is not separately renamed, so incl and decl depend on all ++previous flags-setting instructions. ++ ++shll and shrl have a 4 cycle latency, or 8 times the latency of the fastest ++integer instructions (addl, subl, orl, andl, and some more). shldl and ++shrdl seem to have 13 and 15 cycles latency, respectively. Bizarre. ++ ++movq mmx -> mmx does have 6 cycle latency, as noted in the documentation. ++pxor/por or similar combination at 2 cycles latency can be used instead. ++The movq however executes in the float unit, thereby saving MMX execution ++resources. With the right juggling, data moves shouldn't be on a dependent ++chain. ++ ++L1 is write-through, but the write-combining sounds like it does enough to ++not require explicit destination prefetching. ++ ++xmm registers so far haven't found a use, but not much effort has been ++expended. A configure test for whether the operating system knows ++fxsave/fxrestor will be needed if they're used. ++ ++ ++ ++REFERENCES ++ ++Intel Pentium-4 processor manuals, ++ ++ http://developer.intel.com/design/pentium4/manuals ++ ++"Intel Pentium 4 Processor Optimization Reference Manual", Intel, 2001, ++order number 248966. Available on-line: ++ ++ http://developer.intel.com/design/pentium4/manuals/248966.htm ++ ++ ++ ++---------------- ++Local variables: ++mode: text ++fill-column: 76 ++End: +diff --git a/grub-core/lib/libgcrypt/mpi/pentium4/distfiles b/grub-core/lib/libgcrypt/mpi/pentium4/distfiles +new file mode 100644 +index 0000000..b419f85 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/pentium4/distfiles +@@ -0,0 +1,3 @@ ++README ++ ++ +diff --git a/grub-core/lib/libgcrypt/mpi/pentium4/mmx/distfiles b/grub-core/lib/libgcrypt/mpi/pentium4/mmx/distfiles +new file mode 100644 +index 0000000..8f0ea42 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/pentium4/mmx/distfiles +@@ -0,0 +1,2 @@ ++mpih-lshift.S ++mpih-rshift.S +diff --git a/grub-core/lib/libgcrypt/mpi/pentium4/mmx/mpih-lshift.S b/grub-core/lib/libgcrypt/mpi/pentium4/mmx/mpih-lshift.S +new file mode 100644 +index 0000000..e2dd184 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/pentium4/mmx/mpih-lshift.S +@@ -0,0 +1,457 @@ ++/* Intel Pentium-4 mpn_lshift -- left shift. ++ * ++ * Copyright 2001, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ * ++ * Note: This code is heavily based on the GNU MP Library. ++ * Actually it's the same code with only minor changes in the ++ * way the data is stored; this is to support the abstraction ++ * of an optional secure memory allocation which may be used ++ * to avoid revealing of sensitive data due to paging etc. ++ */ ++ ++ ++#include "sysdep.h" ++#include "asm-syntax.h" ++ ++ ++/******************* ++ * mpi_limb_t ++ * _gcry_mpih_lshift( mpi_ptr_t wp, (sp + 4) ++ * mpi_ptr_t up, (sp + 8) ++ * mpi_size_t usize, (sp + 12) ++ * unsigned cnt) (sp + 16) ++ * ++ * P4 Willamette, Northwood: 1.75 cycles/limb ++ * P4 Prescott: 2.0 cycles/limb ++ */ ++ ++.text ++ ALIGN (3) ++ .globl C_SYMBOL_NAME(_gcry_mpih_lshift) ++C_SYMBOL_NAME(_gcry_mpih_lshift:) ++ ++ ++ pushl %ebx ++ pushl %edi ++ ++ ++ movl 20(%esp), %eax ++ movl 12(%esp), %edx ++ ++ movl 16(%esp), %ebx ++ movl 24(%esp), %ecx ++ ++ cmp $5, %eax ++ jae .Lunroll ++ ++ movl -4(%ebx,%eax,4), %edi ++ decl %eax ++ ++ jnz .Lsimple ++ ++ shldl %cl, %edi, %eax ++ ++ shll %cl, %edi ++ ++ movl %edi, (%edx) ++ popl %edi ++ ++ popl %ebx ++ ++ ret ++ ++ ++ ++ ++ ++.Lsimple: ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ movd (%ebx,%eax,4), %mm5 ++ ++ movd %ecx, %mm6 ++ negl %ecx ++ ++ psllq %mm6, %mm5 ++ addl $32, %ecx ++ ++ movd %ecx, %mm7 ++ psrlq $32, %mm5 ++ ++ ++.Lsimple_top: ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ movq -4(%ebx,%eax,4), %mm0 ++ decl %eax ++ ++ psrlq %mm7, %mm0 ++ ++ ++ ++ movd %mm0, 4(%edx,%eax,4) ++ jnz .Lsimple_top ++ ++ ++ movd (%ebx), %mm0 ++ ++ movd %mm5, %eax ++ psllq %mm6, %mm0 ++ ++ popl %edi ++ popl %ebx ++ ++ movd %mm0, (%edx) ++ ++ emms ++ ++ ret ++ ++ ++ ++ ++ ++ .align 8, 0x90 ++.Lunroll: ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ movd -4(%ebx,%eax,4), %mm5 ++ leal (%ebx,%eax,4), %edi ++ ++ movd %ecx, %mm6 ++ andl $4, %edi ++ ++ psllq %mm6, %mm5 ++ jz .Lstart_src_aligned ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ movq -8(%ebx,%eax,4), %mm0 ++ ++ psllq %mm6, %mm0 ++ decl %eax ++ ++ psrlq $32, %mm0 ++ ++ ++ ++ movd %mm0, (%edx,%eax,4) ++.Lstart_src_aligned: ++ ++ movq -8(%ebx,%eax,4), %mm1 ++ leal (%edx,%eax,4), %edi ++ ++ andl $4, %edi ++ psrlq $32, %mm5 ++ ++ movq -16(%ebx,%eax,4), %mm3 ++ jz .Lstart_dst_aligned ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ movq %mm1, %mm0 ++ addl $32, %ecx ++ ++ psllq %mm6, %mm0 ++ ++ movd %ecx, %mm6 ++ psrlq $32, %mm0 ++ ++ ++ ++ movd %mm0, -4(%edx,%eax,4) ++ subl $4, %edx ++.Lstart_dst_aligned: ++ ++ ++ psllq %mm6, %mm1 ++ negl %ecx ++ ++ addl $64, %ecx ++ movq %mm3, %mm2 ++ ++ movd %ecx, %mm7 ++ subl $8, %eax ++ ++ psrlq %mm7, %mm3 ++ ++ por %mm1, %mm3 ++ jc .Lfinish ++ ++ ++ ++ ++ .align 8, 0x90 ++.Lunroll_loop: ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ movq 8(%ebx,%eax,4), %mm0 ++ psllq %mm6, %mm2 ++ ++ movq %mm0, %mm1 ++ psrlq %mm7, %mm0 ++ ++ movq %mm3, 24(%edx,%eax,4) ++ por %mm2, %mm0 ++ ++ movq (%ebx,%eax,4), %mm3 ++ psllq %mm6, %mm1 ++ ++ movq %mm0, 16(%edx,%eax,4) ++ movq %mm3, %mm2 ++ ++ psrlq %mm7, %mm3 ++ subl $4, %eax ++ ++ por %mm1, %mm3 ++ jnc .Lunroll_loop ++ ++ ++ ++.Lfinish: ++ ++ ++ testb $2, %al ++ ++ jz .Lfinish_no_two ++ ++ movq 8(%ebx,%eax,4), %mm0 ++ psllq %mm6, %mm2 ++ ++ movq %mm0, %mm1 ++ psrlq %mm7, %mm0 ++ ++ movq %mm3, 24(%edx,%eax,4) ++ por %mm2, %mm0 ++ ++ movq %mm1, %mm2 ++ movq %mm0, %mm3 ++ ++ subl $2, %eax ++.Lfinish_no_two: ++ ++ ++ ++ ++ ++ ++ ++ testb $1, %al ++ movd %mm5, %eax ++ ++ popl %edi ++ jz .Lfinish_zero ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ movd (%ebx), %mm0 ++ psllq %mm6, %mm2 ++ ++ movq %mm3, 12(%edx) ++ psllq $32, %mm0 ++ ++ movq %mm0, %mm1 ++ psrlq %mm7, %mm0 ++ ++ por %mm2, %mm0 ++ psllq %mm6, %mm1 ++ ++ movq %mm0, 4(%edx) ++ psrlq $32, %mm1 ++ ++ andl $32, %ecx ++ popl %ebx ++ ++ jz .Lfinish_one_unaligned ++ ++ movd %mm1, (%edx) ++.Lfinish_one_unaligned: ++ ++ emms ++ ++ ret ++ ++ ++ ++ ++.Lfinish_zero: ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ movq %mm3, 8(%edx) ++ andl $32, %ecx ++ ++ psllq %mm6, %mm2 ++ jz .Lfinish_zero_unaligned ++ ++ movq %mm2, (%edx) ++.Lfinish_zero_unaligned: ++ ++ psrlq $32, %mm2 ++ popl %ebx ++ ++ movd %mm5, %eax ++ ++ movd %mm2, 4(%edx) ++ ++ emms ++ ++ ret +diff --git a/grub-core/lib/libgcrypt/mpi/pentium4/mmx/mpih-rshift.S b/grub-core/lib/libgcrypt/mpi/pentium4/mmx/mpih-rshift.S +new file mode 100644 +index 0000000..e3374e3 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/pentium4/mmx/mpih-rshift.S +@@ -0,0 +1,453 @@ ++/* Intel Pentium-4 mpn_rshift -- right shift. ++ * ++ * Copyright 2001, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ * ++ * Note: This code is heavily based on the GNU MP Library. ++ * Actually it's the same code with only minor changes in the ++ * way the data is stored; this is to support the abstraction ++ * of an optional secure memory allocation which may be used ++ * to avoid revealing of sensitive data due to paging etc. ++ */ ++ ++ ++#include "sysdep.h" ++#include "asm-syntax.h" ++ ++ ++/******************* ++ * mpi_limb_t ++ * _gcry_mpih_rshift( mpi_ptr_t wp, (sp + 4) ++ * mpi_ptr_t up, (sp + 8) ++ * mpi_size_t usize, (sp + 12) ++ * unsigned cnt) (sp + 16) ++ * ++ * P4 Willamette, Northwood: 1.75 cycles/limb ++ * P4 Prescott: 2.0 cycles/limb ++ */ ++ ++.text ++ ALIGN (3) ++ .globl C_SYMBOL_NAME(_gcry_mpih_rshift) ++C_SYMBOL_NAME(_gcry_mpih_rshift:) ++ pushl %ebx ++ pushl %edi ++ ++ ++ movl 20(%esp), %eax ++ movl 12(%esp), %edx ++ ++ movl 16(%esp), %ebx ++ movl 24(%esp), %ecx ++ ++ cmp $5, %eax ++ jae .Lunroll ++ ++ decl %eax ++ movl (%ebx), %edi ++ ++ jnz .Lsimple ++ ++ shrdl %cl, %edi, %eax ++ ++ shrl %cl, %edi ++ ++ movl %edi, (%edx) ++ popl %edi ++ ++ popl %ebx ++ ++ ret ++ ++ ++ ++ ++ ++ .align 8, 0x90 ++.Lsimple: ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ movd (%ebx), %mm5 ++ leal (%ebx,%eax,4), %ebx ++ ++ movd %ecx, %mm6 ++ leal -4(%edx,%eax,4), %edx ++ ++ psllq $32, %mm5 ++ negl %eax ++ ++ ++ ++ ++ ++ ++ ++.Lsimple_top: ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ movq (%ebx,%eax,4), %mm0 ++ incl %eax ++ ++ psrlq %mm6, %mm0 ++ ++ movd %mm0, (%edx,%eax,4) ++ jnz .Lsimple_top ++ ++ ++ movd (%ebx), %mm0 ++ psrlq %mm6, %mm5 ++ ++ psrlq %mm6, %mm0 ++ popl %edi ++ ++ movd %mm5, %eax ++ popl %ebx ++ ++ movd %mm0, 4(%edx) ++ ++ emms ++ ++ ret ++ ++ ++ ++ ++ ++ .align 8, 0x90 ++.Lunroll: ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ movd (%ebx), %mm5 ++ movl $4, %edi ++ ++ movd %ecx, %mm6 ++ testl %edi, %ebx ++ ++ psllq $32, %mm5 ++ jz .Lstart_src_aligned ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ movq (%ebx), %mm0 ++ ++ psrlq %mm6, %mm0 ++ addl $4, %ebx ++ ++ decl %eax ++ ++ movd %mm0, (%edx) ++ addl $4, %edx ++.Lstart_src_aligned: ++ ++ ++ movq (%ebx), %mm1 ++ testl %edi, %edx ++ ++ psrlq %mm6, %mm5 ++ jz .Lstart_dst_aligned ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ movq %mm1, %mm0 ++ addl $32, %ecx ++ ++ psrlq %mm6, %mm0 ++ ++ movd %ecx, %mm6 ++ ++ movd %mm0, (%edx) ++ addl $4, %edx ++.Lstart_dst_aligned: ++ ++ ++ movq 8(%ebx), %mm3 ++ negl %ecx ++ ++ movq %mm3, %mm2 ++ addl $64, %ecx ++ ++ movd %ecx, %mm7 ++ psrlq %mm6, %mm1 ++ ++ leal -12(%ebx,%eax,4), %ebx ++ leal -20(%edx,%eax,4), %edx ++ ++ psllq %mm7, %mm3 ++ subl $7, %eax ++ ++ por %mm1, %mm3 ++ negl %eax ++ ++ jns .Lfinish ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ .align 8, 0x90 ++.Lunroll_loop: ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ movq (%ebx,%eax,4), %mm0 ++ psrlq %mm6, %mm2 ++ ++ movq %mm0, %mm1 ++ psllq %mm7, %mm0 ++ ++ movq %mm3, -8(%edx,%eax,4) ++ por %mm2, %mm0 ++ ++ movq 8(%ebx,%eax,4), %mm3 ++ psrlq %mm6, %mm1 ++ ++ movq %mm0, (%edx,%eax,4) ++ movq %mm3, %mm2 ++ ++ psllq %mm7, %mm3 ++ addl $4, %eax ++ ++ por %mm1, %mm3 ++ js .Lunroll_loop ++ ++ ++.Lfinish: ++ ++ ++ testb $2, %al ++ ++ jnz .Lfinish_no_two ++ ++ movq (%ebx,%eax,4), %mm0 ++ psrlq %mm6, %mm2 ++ ++ movq %mm0, %mm1 ++ psllq %mm7, %mm0 ++ ++ movq %mm3, -8(%edx,%eax,4) ++ por %mm2, %mm0 ++ ++ movq %mm1, %mm2 ++ movq %mm0, %mm3 ++ ++ addl $2, %eax ++.Lfinish_no_two: ++ ++ ++ ++ ++ ++ ++ ++ testb $1, %al ++ popl %edi ++ ++ movd %mm5, %eax ++ jnz .Lfinish_zero ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ movd 8(%ebx), %mm0 ++ psrlq %mm6, %mm2 ++ ++ movq %mm0, %mm1 ++ psllq %mm7, %mm0 ++ ++ movq %mm3, (%edx) ++ por %mm2, %mm0 ++ ++ psrlq %mm6, %mm1 ++ andl $32, %ecx ++ ++ popl %ebx ++ jz .Lfinish_one_unaligned ++ ++ ++ movd %mm1, 16(%edx) ++.Lfinish_one_unaligned: ++ ++ movq %mm0, 8(%edx) ++ ++ emms ++ ++ ret ++ ++ ++ ++ ++.Lfinish_zero: ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ movq %mm3, 4(%edx) ++ psrlq %mm6, %mm2 ++ ++ movd %mm2, 12(%edx) ++ andl $32, %ecx ++ ++ popl %ebx ++ jz .Lfinish_zero_unaligned ++ ++ movq %mm2, 12(%edx) ++.Lfinish_zero_unaligned: ++ ++ emms ++ ++ ret +diff --git a/grub-core/lib/libgcrypt/mpi/pentium4/sse2/distfiles b/grub-core/lib/libgcrypt/mpi/pentium4/sse2/distfiles +new file mode 100644 +index 0000000..7252cd7 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/pentium4/sse2/distfiles +@@ -0,0 +1,5 @@ ++mpih-add1.S ++mpih-mul1.S ++mpih-mul2.S ++mpih-mul3.S ++mpih-sub1.S +diff --git a/grub-core/lib/libgcrypt/mpi/pentium4/sse2/mpih-add1.S b/grub-core/lib/libgcrypt/mpi/pentium4/sse2/mpih-add1.S +new file mode 100644 +index 0000000..55ed663 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/pentium4/sse2/mpih-add1.S +@@ -0,0 +1,91 @@ ++/* Intel Pentium-4 mpn_add_n -- mpn addition. ++ * ++ * Copyright 2001, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ * ++ * Note: This code is heavily based on the GNU MP Library. ++ * Actually it's the same code with only minor changes in the ++ * way the data is stored; this is to support the abstraction ++ * of an optional secure memory allocation which may be used ++ * to avoid revealing of sensitive data due to paging etc. ++ */ ++ ++ ++#include "sysdep.h" ++#include "asm-syntax.h" ++ ++ ++ /******************* ++ * mpi_limb_t ++ * _gcry_mpih_add_n( mpi_ptr_t res_ptr, (sp + 4) ++ * mpi_ptr_t s1_ptr, (sp + 8) ++ * mpi_ptr_t s2_ptr, (sp + 12) ++ * mpi_size_t size) (sp + 16) ++ * ++ * P4 Willamette, Northwood: 4.0 cycles/limb if dst!=src1 and dst!=src2 ++ * 6.0 cycles/limb if dst==src1 or dst==src2 ++ * P4 Prescott: >= 5 cycles/limb ++ * ++ * The 4 c/l achieved here isn't particularly good, but is better than 9 c/l ++ * for a basic adc loop. ++ */ ++ ++ TEXT ++ ALIGN (3) ++ GLOBL C_SYMBOL_NAME(_gcry_mpih_add_n) ++C_SYMBOL_NAME(_gcry_mpih_add_n:) ++ ++ pxor %mm0, %mm0 ++ ++ movl 8(%esp), %eax /* s1_ptr */ ++ movl %ebx, 8(%esp) /* re-use parameter space */ ++ movl 12(%esp), %ebx /* res_ptr */ ++ movl 4(%esp), %edx /* s2_ptr */ ++ movl 16(%esp), %ecx /* size */ ++ ++ leal (%eax,%ecx,4), %eax /* src1 end */ ++ leal (%ebx,%ecx,4), %ebx /* src2 end */ ++ leal (%edx,%ecx,4), %edx /* dst end */ ++ negl %ecx /* -size */ ++ ++Ltop: ++/* ++ C eax src1 end ++ C ebx src2 end ++ C ecx counter, limbs, negative ++ C edx dst end ++ C mm0 carry bit ++*/ ++ ++ movd (%eax,%ecx,4), %mm1 ++ movd (%ebx,%ecx,4), %mm2 ++ paddq %mm2, %mm1 ++ ++ paddq %mm1, %mm0 ++ movd %mm0, (%edx,%ecx,4) ++ ++ psrlq $32, %mm0 ++ ++ addl $1, %ecx ++ jnz Ltop ++ ++ ++ movd %mm0, %eax ++ movl 8(%esp), %ebx /* restore saved EBX */ ++ emms ++ ret +diff --git a/grub-core/lib/libgcrypt/mpi/pentium4/sse2/mpih-mul1.S b/grub-core/lib/libgcrypt/mpi/pentium4/sse2/mpih-mul1.S +new file mode 100644 +index 0000000..a0c98fb +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/pentium4/sse2/mpih-mul1.S +@@ -0,0 +1,96 @@ ++/* Intel Pentium-4 mpn_mul_1 -- Multiply a limb vector with a limb and store ++ * the result in a second limb vector. ++ * ++ * Copyright 2001, 2002, 2003, 2005 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ * ++ * Note: This code is heavily based on the GNU MP Library. ++ * Actually it's the same code with only minor changes in the ++ * way the data is stored; this is to support the abstraction ++ * of an optional secure memory allocation which may be used ++ * to avoid revealing of sensitive data due to paging etc. ++ */ ++ ++ ++#include "sysdep.h" ++#include "asm-syntax.h" ++ ++ ++/******************* ++ * mpi_limb_t ++ * _gcry_mpih_mul_1( mpi_ptr_t res_ptr, (sp + 4) ++ * mpi_ptr_t s1_ptr, (sp + 8) ++ * mpi_size_t s1_size, (sp + 12) ++ * mpi_limb_t s2_limb) (sp + 16) ++ * ++ * src != dst src == dst ++ * P6 model 9 (Banias) ?.? ++ * P6 model 13 (Dothan) 4.75 4.75 ++ * P4 model 0 (Willamette) 4.0 6.0 ++ * P4 model 1 (?) 4.0 6.0 ++ * P4 model 2 (Northwood) 4.0 6.0 ++ * P4 model 3 (Prescott) ?.? ?.? ++ * P4 model 4 (Nocona) ?.? ?.? ++ * Unfortunately when src==dst the write-combining described in ++ * pentium4/README takes us up to 6 c/l. ++ * ++ */ ++ ++ TEXT ++ ALIGN (3) ++ GLOBL C_SYMBOL_NAME(_gcry_mpih_mul_1) ++C_SYMBOL_NAME(_gcry_mpih_mul_1:); ++ ++ pxor %mm0, %mm0 ++ ++.Lstart_1c: ++ movl 8(%esp), %eax ++ movd 16(%esp), %mm7 ++ movl 4(%esp), %edx ++ movl 12(%esp), %ecx ++ ++.Ltop: ++ ++/* ++ C eax src, incrementing ++ C ebx ++ C ecx counter, size iterations ++ C edx dst, incrementing ++ C ++ C mm0 carry limb ++ C mm7 multiplier ++*/ ++ ++ movd (%eax), %mm1 ++ addl $4, %eax ++ pmuludq %mm7, %mm1 ++ ++ paddq %mm1, %mm0 ++ movd %mm0, (%edx) ++ addl $4, %edx ++ ++ psrlq $32, %mm0 ++ ++ subl $1, %ecx ++ jnz .Ltop ++ ++ ++ movd %mm0, %eax ++ emms ++ ret ++ +diff --git a/grub-core/lib/libgcrypt/mpi/pentium4/sse2/mpih-mul2.S b/grub-core/lib/libgcrypt/mpi/pentium4/sse2/mpih-mul2.S +new file mode 100644 +index 0000000..f975adf +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/pentium4/sse2/mpih-mul2.S +@@ -0,0 +1,136 @@ ++/* Intel Pentium-4 mpn_addmul_1 -- Multiply a limb vector with a limb and add ++ * the result to a second limb vector. ++ * ++ * Copyright 2001, 2002, 2004, 2005 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ * ++ * Note: This code is heavily based on the GNU MP Library. ++ * Actually it's the same code with only minor changes in the ++ * way the data is stored; this is to support the abstraction ++ * of an optional secure memory allocation which may be used ++ * to avoid revealing of sensitive data due to paging etc. ++ */ ++ ++ ++#include "sysdep.h" ++#include "asm-syntax.h" ++ ++ ++/******************* ++ * mpi_limb_t ++ * _gcry_mpih_addmul_1( mpi_ptr_t res_ptr, (sp + 4) ++ * mpi_ptr_t s1_ptr, (sp + 8) ++ * mpi_size_t s1_size, (sp + 12) ++ * mpi_limb_t s2_limb) (sp + 16) ++ * ++ * P3 model 9 (Banias) ?.? ++ * P3 model 13 (Dothan) 5.8 ++ * P4 model 0 (Willamette) 5.5 ++ * P4 model 1 (?) 5.5 ++ * P4 model 2 (Northwood) 5.5 ++ * P4 model 3 (Prescott) 6.0 ++ * P4 model 4 (Nocona) ++ * ++ * Only the carry limb propagation is on the dependent chain, but some other ++ * Pentium4 pipeline magic brings down performance to 6 cycles/l from the ++ * ideal 4 cycles/l. ++ */ ++ ++ ++ TEXT ++ ALIGN (4) ++ GLOBL C_SYMBOL_NAME(_gcry_mpih_addmul_1) ++C_SYMBOL_NAME(_gcry_mpih_addmul_1:) ++ ++ pxor %mm4, %mm4 ++.Lstart_1c: ++ movl 8(%esp), %eax ++ movl 12(%esp), %ecx ++ movl 4(%esp), %edx ++ movd 16(%esp), %mm7 ++ ++/* ++ C eax src, incrementing ; 5B ++ C ecx loop counter, decrementing ++ C edx dst, incrementing ++ C ++ C mm4 carry, low 32-bits ++ C mm7 multiplier ++*/ ++ ++ movd (%eax), %mm2 ++ pmuludq %mm7, %mm2 ++ ++ shrl $1, %ecx ++ jnc .Leven ++ ++ leal 4(%eax), %eax ++ movd (%edx), %mm1 ++ paddq %mm2, %mm1 ++ paddq %mm1, %mm4 ++ movd %mm4, (%edx) ++ psrlq $32, %mm4 ++ ++ testl %ecx, %ecx ++ jz .Lrtn ++ leal 4(%edx), %edx ++ ++ movd (%eax), %mm2 ++ pmuludq %mm7, %mm2 ++.Leven: ++ movd 4(%eax), %mm0 ++ movd (%edx), %mm1 ++ pmuludq %mm7, %mm0 ++ ++ subl $1, %ecx ++ jz .Lend ++.Lloop: ++ paddq %mm2, %mm1 ++ movd 8(%eax), %mm2 ++ paddq %mm1, %mm4 ++ movd 4(%edx), %mm3 ++ pmuludq %mm7, %mm2 ++ movd %mm4, (%edx) ++ psrlq $32, %mm4 ++ ++ paddq %mm0, %mm3 ++ movd 12(%eax), %mm0 ++ paddq %mm3, %mm4 ++ movd 8(%edx), %mm1 ++ pmuludq %mm7, %mm0 ++ movd %mm4, 4(%edx) ++ psrlq $32, %mm4 ++ ++ leal 8(%eax), %eax ++ leal 8(%edx), %edx ++ subl $1, %ecx ++ jnz .Lloop ++.Lend: ++ paddq %mm2, %mm1 ++ paddq %mm1, %mm4 ++ movd 4(%edx), %mm3 ++ movd %mm4, (%edx) ++ psrlq $32, %mm4 ++ paddq %mm0, %mm3 ++ paddq %mm3, %mm4 ++ movd %mm4, 4(%edx) ++ psrlq $32, %mm4 ++.Lrtn: ++ movd %mm4, %eax ++ emms ++ ret +diff --git a/grub-core/lib/libgcrypt/mpi/pentium4/sse2/mpih-mul3.S b/grub-core/lib/libgcrypt/mpi/pentium4/sse2/mpih-mul3.S +new file mode 100644 +index 0000000..ebcd2a6 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/pentium4/sse2/mpih-mul3.S +@@ -0,0 +1,127 @@ ++/* Intel Pentium-4 mpn_submul_1 -- Multiply a limb vector with a limb and ++ * subtract the result from a second limb vector. ++ * ++ * Copyright 2001, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ * ++ * Note: This code is heavily based on the GNU MP Library. ++ * Actually it's the same code with only minor changes in the ++ * way the data is stored; this is to support the abstraction ++ * of an optional secure memory allocation which may be used ++ * to avoid revealing of sensitive data due to paging etc. ++ */ ++ ++ ++#include "sysdep.h" ++#include "asm-syntax.h" ++ ++ ++/******************* ++ * mpi_limb_t ++ * _gcry_mpih_submul_1( mpi_ptr_t res_ptr, (sp + 4) ++ * mpi_ptr_t s1_ptr, (sp + 8) ++ * mpi_size_t s1_size, (sp + 12) ++ * mpi_limb_t s2_limb) (sp + 16) ++ * ++ * P4: 7 cycles/limb, unstable timing, at least on early Pentium4 silicon ++ * (stepping 10). ++ * ++ * This code is not particularly good at 7 c/l. The dependent chain is only ++ * 4 c/l and there's only 4 MMX unit instructions, so it's not clear why that ++ * speed isn't achieved. ++ * ++ * The arrangements made here to get a two instruction dependent chain are ++ * slightly subtle. In the loop the carry (or borrow rather) is a negative ++ * so that a paddq can be used to give a low limb ready to store, and a high ++ * limb ready to become the new carry after a psrlq. ++ * ++ * If the carry was a simple twos complement negative then the psrlq shift ++ * would need to bring in 0 bits or 1 bits according to whether the high was ++ * zero or non-zero, since a non-zero value would represent a negative ++ * needing sign extension. That wouldn't be particularly easy to arrange and ++ * certainly would add an instruction to the dependent chain, so instead an ++ * offset is applied so that the high limb will be 0xFFFFFFFF+c. With c in ++ * the range -0xFFFFFFFF to 0, the value 0xFFFFFFFF+c is in the range 0 to ++ * 0xFFFFFFFF and is therefore always positive and can always have 0 bits ++ * shifted in, which is what psrlq does. ++ * ++ * The extra 0xFFFFFFFF must be subtracted before c is used, but that can be ++ * done off the dependent chain. The total adjustment then is to add ++ * 0xFFFFFFFF00000000 to offset the new carry, and subtract ++ * 0x00000000FFFFFFFF to remove the offset from the current carry, for a net ++ * add of 0xFFFFFFFE00000001. In the code this is applied to the destination ++ * limb when fetched. ++ * ++ * It's also possible to view the 0xFFFFFFFF adjustment as a ones-complement ++ * negative, which is how it's undone for the return value, but that doesn't ++ * seem as clear. ++*/ ++ ++ TEXT ++ ALIGN (4) ++ GLOBL C_SYMBOL_NAME(_gcry_mpih_submul_1) ++C_SYMBOL_NAME(_gcry_mpih_submul_1:) ++ ++ pxor %mm1, %mm1 ++ ++.Lstart_1c: ++ movl 8(%esp), %eax ++ pcmpeqd %mm0, %mm0 ++ ++ movd 16(%esp), %mm7 ++ pcmpeqd %mm6, %mm6 ++ ++ movl 4(%esp), %edx ++ psrlq $32, %mm0 ++ ++ movl 12(%esp), %ecx ++ psllq $32, %mm6 ++ ++ psubq %mm0, %mm6 ++ ++ psubq %mm1, %mm0 ++ ++/* ++ C eax src, incrementing ++ C ebx ++ C ecx loop counter, decrementing ++ C edx dst, incrementing ++ C ++ C mm0 0xFFFFFFFF - borrow ++ C mm6 0xFFFFFFFE00000001 ++ C mm7 multiplier ++*/ ++ ++.Lloop: ++ movd (%eax), %mm1 ++ leal 4(%eax), %eax ++ movd (%edx), %mm2 ++ paddq %mm6, %mm2 ++ pmuludq %mm7, %mm1 ++ psubq %mm1, %mm2 ++ paddq %mm2, %mm0 ++ subl $1, %ecx ++ movd %mm0, (%edx) ++ psrlq $32, %mm0 ++ leal 4(%edx), %edx ++ jnz .Lloop ++ ++ movd %mm0, %eax ++ notl %eax ++ emms ++ ret +diff --git a/grub-core/lib/libgcrypt/mpi/pentium4/sse2/mpih-sub1.S b/grub-core/lib/libgcrypt/mpi/pentium4/sse2/mpih-sub1.S +new file mode 100644 +index 0000000..33900c7 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/pentium4/sse2/mpih-sub1.S +@@ -0,0 +1,112 @@ ++/* Intel Pentium-4 mpn_sub_n -- mpn subtraction. ++ * ++ * Copyright 2001, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ * ++ * Note: This code is heavily based on the GNU MP Library. ++ * Actually it's the same code with only minor changes in the ++ * way the data is stored; this is to support the abstraction ++ * of an optional secure memory allocation which may be used ++ * to avoid revealing of sensitive data due to paging etc. ++ */ ++ ++ ++#include "sysdep.h" ++#include "asm-syntax.h" ++ ++ ++/******************* ++ * mpi_limb_t ++ * _gcry_mpih_sub_n( mpi_ptr_t res_ptr, (sp + 4) ++ * mpi_ptr_t s1_ptr, (sp + 8) ++ * mpi_ptr_t s2_ptr, (sp + 12) ++ * mpi_size_t size) (sp + 16) ++ * ++ * P4 Willamette, Northwood: 4.0 cycles/limb if dst!=src1 and dst!=src2 ++ * 6.0 cycles/limb if dst==src1 or dst==src2 ++ * P4 Prescott: >= 5 cycles/limb ++ * ++ * The main loop code is 2x unrolled so that the carry bit can alternate ++ * between mm0 and mm1. ++ */ ++ ++ ++.text ++ ALIGN (3) ++ .globl C_SYMBOL_NAME(_gcry_mpih_sub_n) ++C_SYMBOL_NAME(_gcry_mpih_sub_n:) ++ ++ pxor %mm0, %mm0 ++.Lstart_nc: ++ movl 8(%esp), %eax ++ movl %ebx, 8(%esp) ++ movl 12(%esp), %ebx ++ movl 4(%esp), %edx ++ movl 16(%esp), %ecx ++ ++ leal (%eax,%ecx,4), %eax ++ leal (%ebx,%ecx,4), %ebx ++ leal (%edx,%ecx,4), %edx ++ negl %ecx ++ ++.Ltop: ++/* ++ C eax src1 end ++ C ebx src2 end ++ C ecx counter, limbs, negative ++ C edx dst end ++ C mm0 carry bit ++*/ ++ ++ movd (%eax,%ecx,4), %mm1 ++ movd (%ebx,%ecx,4), %mm2 ++ psubq %mm2, %mm1 ++ ++ psubq %mm0, %mm1 ++ movd %mm1, (%edx,%ecx,4) ++ ++ psrlq $63, %mm1 ++ ++ addl $1, %ecx ++ jz .Ldone_mm1 ++ ++ movd (%eax,%ecx,4), %mm0 ++ movd (%ebx,%ecx,4), %mm2 ++ psubq %mm2, %mm0 ++ ++ psubq %mm1, %mm0 ++ movd %mm0, (%edx,%ecx,4) ++ ++ psrlq $63, %mm0 ++ ++ addl $1, %ecx ++ jnz .Ltop ++ ++ ++ movd %mm0, %eax ++ movl 8(%esp), %ebx ++ emms ++ ret ++ ++ ++ ++.Ldone_mm1: ++ movd %mm1, %eax ++ movl 8(%esp), %ebx ++ emms ++ ret +diff --git a/grub-core/lib/libgcrypt/mpi/power/Manifest b/grub-core/lib/libgcrypt/mpi/power/Manifest +new file mode 100644 +index 0000000..c60fc23 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/power/Manifest +@@ -0,0 +1,27 @@ ++# Manifest - checksums ++# Copyright 2003 Free Software Foundation, Inc. ++# ++# This file is part of Libgcrypt. ++# ++# Libgcrypt is free software; you can redistribute it and/or modify ++# it under the terms of the GNU Lesser General Public License as ++# published by the Free Software Foundation; either version 2.1 of ++# the License, or (at your option) any later version. ++# ++# Libgcrypt 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 Lesser General Public License for more details. ++# ++# You should have received a copy of the GNU Lesser General Public ++# License along with this program; if not, write to the Free Software ++# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ ++mpih-add1.S ++mpih-lshift.S ++mpih-mul1.S ++mpih-mul2.S ++mpih-mul3.S ++mpih-rshift.S ++mpih-sub1.S ++$names$ iQCVAwUAP+LmXTEAnp832S/7AQJ+ngP/XYr5Fvl/8WGVHcIKaehxvnKcSD2ILTWZNGubgnWp8ebIxVijjQCxYneTTy+zO0sNaB002neyscyiwaJj/JQIwZXfr06uGweIqlSpwpj9ndkoJc8E4/FZu+5NTO+E3RaBDAD+Tpo+MTfbC1s18p5i+an93VrSTgNck5PPYQrUcPA==sl3t +diff --git a/grub-core/lib/libgcrypt/mpi/power/distfiles b/grub-core/lib/libgcrypt/mpi/power/distfiles +new file mode 100644 +index 0000000..e1bc008 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/power/distfiles +@@ -0,0 +1,8 @@ ++Manifest ++mpih-add1.S ++mpih-lshift.S ++mpih-mul1.S ++mpih-mul2.S ++mpih-mul3.S ++mpih-rshift.S ++mpih-sub1.S +diff --git a/grub-core/lib/libgcrypt/mpi/power/mpih-add1.S b/grub-core/lib/libgcrypt/mpi/power/mpih-add1.S +new file mode 100644 +index 0000000..876b56c +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/power/mpih-add1.S +@@ -0,0 +1,87 @@ ++/* IBM POWER add_n -- Add two limb vectors of equal, non-zero length. ++ * ++ * Copyright (C) 1992, 1994, 1996, 1999, ++ * 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ */ ++ ++#include "sysdep.h" ++#include "asm-syntax.h" ++ ++/* ++# INPUT PARAMETERS ++# res_ptr r3 ++# s1_ptr r4 ++# s2_ptr r5 ++# size r6 ++ */ ++ ++ .toc ++ .extern _gcry_mpih_add_n[DS] ++ .extern ._gcry_mpih_add_n ++.csect [PR] ++ .align 2 ++ .globl _gcry_mpih_add_n ++ .globl ._gcry_mpih_add_n ++ .csect _gcry_mpih_add_n[DS] ++_gcry_mpih_add_n: ++ .long ._gcry_mpih_add_n, TOC[tc0], 0 ++ .csect [PR] ++._gcry_mpih_add_n: ++ andil. 10,6,1 # odd or even number of limbs? ++ l 8,0(4) # load least significant s1 limb ++ l 0,0(5) # load least significant s2 limb ++ cal 3,-4(3) # offset res_ptr, it's updated before it's used ++ sri 10,6,1 # count for unrolled loop ++ a 7,0,8 # add least significant limbs, set cy ++ mtctr 10 # copy count into CTR ++ beq 0,Leven # branch if even # of limbs (# of limbs >= 2) ++ ++# We have an odd # of limbs. Add the first limbs separately. ++ cmpi 1,10,0 # is count for unrolled loop zero? ++ bne 1,L1 # branch if not ++ st 7,4(3) ++ aze 3,10 # use the fact that r10 is zero... ++ br # return ++ ++# We added least significant limbs. Now reload the next limbs to enter loop. ++L1: lu 8,4(4) # load s1 limb and update s1_ptr ++ lu 0,4(5) # load s2 limb and update s2_ptr ++ stu 7,4(3) ++ ae 7,0,8 # add limbs, set cy ++Leven: lu 9,4(4) # load s1 limb and update s1_ptr ++ lu 10,4(5) # load s2 limb and update s2_ptr ++ bdz Lend # If done, skip loop ++ ++Loop: lu 8,4(4) # load s1 limb and update s1_ptr ++ lu 0,4(5) # load s2 limb and update s2_ptr ++ ae 11,9,10 # add previous limbs with cy, set cy ++ stu 7,4(3) # ++ lu 9,4(4) # load s1 limb and update s1_ptr ++ lu 10,4(5) # load s2 limb and update s2_ptr ++ ae 7,0,8 # add previous limbs with cy, set cy ++ stu 11,4(3) # ++ bdn Loop # decrement CTR and loop back ++ ++Lend: ae 11,9,10 # add limbs with cy, set cy ++ st 7,4(3) # ++ st 11,8(3) # ++ lil 3,0 # load cy into ... ++ aze 3,3 # ... return value register ++ br ++ +diff --git a/grub-core/lib/libgcrypt/mpi/power/mpih-lshift.S b/grub-core/lib/libgcrypt/mpi/power/mpih-lshift.S +new file mode 100644 +index 0000000..d9e42da +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/power/mpih-lshift.S +@@ -0,0 +1,64 @@ ++/* IBM POWER lshift ++ * ++ * Copyright (C) 1992, 1994, 1999, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ */ ++ ++#include "sysdep.h" ++#include "asm-syntax.h" ++ ++/* ++# INPUT PARAMETERS ++# res_ptr r3 ++# s_ptr r4 ++# size r5 ++# cnt r6 ++ */ ++ ++ .toc ++ .extern _gcry_mpih_lshift[DS] ++ .extern ._gcry_mpih_lshift ++.csect [PR] ++ .align 2 ++ .globl _gcry_mpih_lshift ++ .globl ._gcry_mpih_lshift ++ .csect _gcry_mpih_lshift[DS] ++_gcry_mpih_lshift: ++ .long ._gcry_mpih_lshift, TOC[tc0], 0 ++ .csect [PR] ++._gcry_mpih_lshift: ++ sli 0,5,2 ++ cax 9,3,0 ++ cax 4,4,0 ++ sfi 8,6,32 ++ mtctr 5 # put limb count in CTR loop register ++ lu 0,-4(4) # read most significant limb ++ sre 3,0,8 # compute carry out limb, and init MQ register ++ bdz Lend2 # if just one limb, skip loop ++ lu 0,-4(4) # read 2:nd most significant limb ++ sreq 7,0,8 # compute most significant limb of result ++ bdz Lend # if just two limb, skip loop ++Loop: lu 0,-4(4) # load next lower limb ++ stu 7,-4(9) # store previous result during read latency ++ sreq 7,0,8 # compute result limb ++ bdn Loop # loop back until CTR is zero ++Lend: stu 7,-4(9) # store 2:nd least significant limb ++Lend2: sle 7,0,6 # compute least significant limb ++ st 7,-4(9) # store it ++ br ++ +diff --git a/grub-core/lib/libgcrypt/mpi/power/mpih-mul1.S b/grub-core/lib/libgcrypt/mpi/power/mpih-mul1.S +new file mode 100644 +index 0000000..35034fa +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/power/mpih-mul1.S +@@ -0,0 +1,115 @@ ++/* IBM POWER mul_1 -- Multiply a limb vector with a limb and store ++ * the result in a second limb vector. ++ * ++ * Copyright (C) 1992, 1994, 1999, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ */ ++ ++#include "sysdep.h" ++#include "asm-syntax.h" ++ ++/* ++# INPUT PARAMETERS ++# res_ptr r3 ++# s1_ptr r4 ++# size r5 ++# s2_limb r6 ++ ++# The RS/6000 has no unsigned 32x32->64 bit multiplication instruction. To ++# obtain that operation, we have to use the 32x32->64 signed multiplication ++# instruction, and add the appropriate compensation to the high limb of the ++# result. We add the multiplicand if the multiplier has its most significant ++# bit set, and we add the multiplier if the multiplicand has its most ++# significant bit set. We need to preserve the carry flag between each ++# iteration, so we have to compute the compensation carefully (the natural, ++# srai+and doesn't work). Since the POWER architecture has a branch unit ++# we can branch in zero cycles, so that's how we perform the additions. ++ */ ++ ++ .toc ++ .csect ._gcry_mpih_mul_1[PR] ++ .align 2 ++ .globl _gcry_mpih_mul_1 ++ .globl ._gcry_mpih_mul_1 ++ .csect _gcry_mpih_mul_1[DS] ++_gcry_mpih_mul_1: ++ .long ._gcry_mpih_mul_1[PR], TOC[tc0], 0 ++ .csect ._gcry_mpih_mul_1[PR] ++._gcry_mpih_mul_1: ++ ++ cal 3,-4(3) ++ l 0,0(4) ++ cmpi 0,6,0 ++ mtctr 5 ++ mul 9,0,6 ++ srai 7,0,31 ++ and 7,7,6 ++ mfmq 8 ++ ai 0,0,0 # reset carry ++ cax 9,9,7 ++ blt Lneg ++Lpos: bdz Lend ++Lploop: lu 0,4(4) ++ stu 8,4(3) ++ cmpi 0,0,0 ++ mul 10,0,6 ++ mfmq 0 ++ ae 8,0,9 ++ bge Lp0 ++ cax 10,10,6 # adjust high limb for negative limb from s1 ++Lp0: bdz Lend0 ++ lu 0,4(4) ++ stu 8,4(3) ++ cmpi 0,0,0 ++ mul 9,0,6 ++ mfmq 0 ++ ae 8,0,10 ++ bge Lp1 ++ cax 9,9,6 # adjust high limb for negative limb from s1 ++Lp1: bdn Lploop ++ b Lend ++ ++Lneg: cax 9,9,0 ++ bdz Lend ++Lnloop: lu 0,4(4) ++ stu 8,4(3) ++ cmpi 0,0,0 ++ mul 10,0,6 ++ cax 10,10,0 # adjust high limb for negative s2_limb ++ mfmq 0 ++ ae 8,0,9 ++ bge Ln0 ++ cax 10,10,6 # adjust high limb for negative limb from s1 ++Ln0: bdz Lend0 ++ lu 0,4(4) ++ stu 8,4(3) ++ cmpi 0,0,0 ++ mul 9,0,6 ++ cax 9,9,0 # adjust high limb for negative s2_limb ++ mfmq 0 ++ ae 8,0,10 ++ bge Ln1 ++ cax 9,9,6 # adjust high limb for negative limb from s1 ++Ln1: bdn Lnloop ++ b Lend ++ ++Lend0: cal 9,0(10) ++Lend: st 8,4(3) ++ aze 3,9 ++ br ++ +diff --git a/grub-core/lib/libgcrypt/mpi/power/mpih-mul2.S b/grub-core/lib/libgcrypt/mpi/power/mpih-mul2.S +new file mode 100644 +index 0000000..d056e8f +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/power/mpih-mul2.S +@@ -0,0 +1,130 @@ ++/* IBM POWER addmul_1 -- Multiply a limb vector with a limb and add ++ * the result to a second limb vector. ++ * ++ * Copyright (C) 1992, 1994, 1999, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ */ ++ ++#include "sysdep.h" ++#include "asm-syntax.h" ++ ++ ++ ++/* ++# INPUT PARAMETERS ++# res_ptr r3 ++# s1_ptr r4 ++# size r5 ++# s2_limb r6 ++ ++# The RS/6000 has no unsigned 32x32->64 bit multiplication instruction. To ++# obtain that operation, we have to use the 32x32->64 signed multiplication ++# instruction, and add the appropriate compensation to the high limb of the ++# result. We add the multiplicand if the multiplier has its most significant ++# bit set, and we add the multiplier if the multiplicand has its most ++# significant bit set. We need to preserve the carry flag between each ++# iteration, so we have to compute the compensation carefully (the natural, ++# srai+and doesn't work). Since the POWER architecture has a branch unit ++# we can branch in zero cycles, so that's how we perform the additions. ++ */ ++ ++ .toc ++ .csect ._gcry_mpih_addmul_1[PR] ++ .align 2 ++ .globl _gcry_mpih_addmul_1 ++ .globl ._gcry_mpih_addmul_1 ++ .csect _gcry_mpih_addmul_1[DS] ++_gcry_mpih_addmul_1: ++ .long ._gcry_mpih_addmul_1[PR], TOC[tc0], 0 ++ .csect ._gcry_mpih_addmul_1[PR] ++._gcry_mpih_addmul_1: ++ ++ cal 3,-4(3) ++ l 0,0(4) ++ cmpi 0,6,0 ++ mtctr 5 ++ mul 9,0,6 ++ srai 7,0,31 ++ and 7,7,6 ++ mfmq 8 ++ cax 9,9,7 ++ l 7,4(3) ++ a 8,8,7 # add res_limb ++ blt Lneg ++Lpos: bdz Lend ++ ++Lploop: lu 0,4(4) ++ stu 8,4(3) ++ cmpi 0,0,0 ++ mul 10,0,6 ++ mfmq 0 ++ ae 8,0,9 # low limb + old_cy_limb + old cy ++ l 7,4(3) ++ aze 10,10 # propagate cy to new cy_limb ++ a 8,8,7 # add res_limb ++ bge Lp0 ++ cax 10,10,6 # adjust high limb for negative limb from s1 ++Lp0: bdz Lend0 ++ lu 0,4(4) ++ stu 8,4(3) ++ cmpi 0,0,0 ++ mul 9,0,6 ++ mfmq 0 ++ ae 8,0,10 ++ l 7,4(3) ++ aze 9,9 ++ a 8,8,7 ++ bge Lp1 ++ cax 9,9,6 # adjust high limb for negative limb from s1 ++Lp1: bdn Lploop ++ ++ b Lend ++ ++Lneg: cax 9,9,0 ++ bdz Lend ++Lnloop: lu 0,4(4) ++ stu 8,4(3) ++ cmpi 0,0,0 ++ mul 10,0,6 ++ mfmq 7 ++ ae 8,7,9 ++ l 7,4(3) ++ ae 10,10,0 # propagate cy to new cy_limb ++ a 8,8,7 # add res_limb ++ bge Ln0 ++ cax 10,10,6 # adjust high limb for negative limb from s1 ++Ln0: bdz Lend0 ++ lu 0,4(4) ++ stu 8,4(3) ++ cmpi 0,0,0 ++ mul 9,0,6 ++ mfmq 7 ++ ae 8,7,10 ++ l 7,4(3) ++ ae 9,9,0 # propagate cy to new cy_limb ++ a 8,8,7 # add res_limb ++ bge Ln1 ++ cax 9,9,6 # adjust high limb for negative limb from s1 ++Ln1: bdn Lnloop ++ b Lend ++ ++Lend0: cal 9,0(10) ++Lend: st 8,4(3) ++ aze 3,9 ++ br ++ +diff --git a/grub-core/lib/libgcrypt/mpi/power/mpih-mul3.S b/grub-core/lib/libgcrypt/mpi/power/mpih-mul3.S +new file mode 100644 +index 0000000..8bc317b +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/power/mpih-mul3.S +@@ -0,0 +1,135 @@ ++/* IBM POWER submul_1 -- Multiply a limb vector with a limb and subtract ++ * the result from a second limb vector. ++ * ++ * Copyright (C) 1992, 1994, 1999, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ */ ++ ++#include "sysdep.h" ++#include "asm-syntax.h" ++ ++ ++/* ++ ++# INPUT PARAMETERS ++# res_ptr r3 ++# s1_ptr r4 ++# size r5 ++# s2_limb r6 ++ ++# The RS/6000 has no unsigned 32x32->64 bit multiplication instruction. To ++# obtain that operation, we have to use the 32x32->64 signed multiplication ++# instruction, and add the appropriate compensation to the high limb of the ++# result. We add the multiplicand if the multiplier has its most significant ++# bit set, and we add the multiplier if the multiplicand has its most ++# significant bit set. We need to preserve the carry flag between each ++# iteration, so we have to compute the compensation carefully (the natural, ++# srai+and doesn't work). Since the POWER architecture has a branch unit ++# we can branch in zero cycles, so that's how we perform the additions. ++ */ ++ ++ .toc ++ .csect ._gcry_mpih_submul_1[PR] ++ .align 2 ++ .globl _gcry_mpih_submul_1 ++ .globl ._gcry_mpih_submul_1 ++ .csect _gcry_mpih_submul_1[DS] ++_gcry_mpih_submul_1: ++ .long ._gcry_mpih_submul_1[PR], TOC[tc0], 0 ++ .csect ._gcry_mpih_submul_1[PR] ++._gcry_mpih_submul_1: ++ ++ cal 3,-4(3) ++ l 0,0(4) ++ cmpi 0,6,0 ++ mtctr 5 ++ mul 9,0,6 ++ srai 7,0,31 ++ and 7,7,6 ++ mfmq 11 ++ cax 9,9,7 ++ l 7,4(3) ++ sf 8,11,7 # add res_limb ++ a 11,8,11 # invert cy (r11 is junk) ++ blt Lneg ++Lpos: bdz Lend ++ ++Lploop: lu 0,4(4) ++ stu 8,4(3) ++ cmpi 0,0,0 ++ mul 10,0,6 ++ mfmq 0 ++ ae 11,0,9 # low limb + old_cy_limb + old cy ++ l 7,4(3) ++ aze 10,10 # propagate cy to new cy_limb ++ sf 8,11,7 # add res_limb ++ a 11,8,11 # invert cy (r11 is junk) ++ bge Lp0 ++ cax 10,10,6 # adjust high limb for negative limb from s1 ++Lp0: bdz Lend0 ++ lu 0,4(4) ++ stu 8,4(3) ++ cmpi 0,0,0 ++ mul 9,0,6 ++ mfmq 0 ++ ae 11,0,10 ++ l 7,4(3) ++ aze 9,9 ++ sf 8,11,7 ++ a 11,8,11 # invert cy (r11 is junk) ++ bge Lp1 ++ cax 9,9,6 # adjust high limb for negative limb from s1 ++Lp1: bdn Lploop ++ ++ b Lend ++ ++Lneg: cax 9,9,0 ++ bdz Lend ++Lnloop: lu 0,4(4) ++ stu 8,4(3) ++ cmpi 0,0,0 ++ mul 10,0,6 ++ mfmq 7 ++ ae 11,7,9 ++ l 7,4(3) ++ ae 10,10,0 # propagate cy to new cy_limb ++ sf 8,11,7 # add res_limb ++ a 11,8,11 # invert cy (r11 is junk) ++ bge Ln0 ++ cax 10,10,6 # adjust high limb for negative limb from s1 ++Ln0: bdz Lend0 ++ lu 0,4(4) ++ stu 8,4(3) ++ cmpi 0,0,0 ++ mul 9,0,6 ++ mfmq 7 ++ ae 11,7,10 ++ l 7,4(3) ++ ae 9,9,0 # propagate cy to new cy_limb ++ sf 8,11,7 # add res_limb ++ a 11,8,11 # invert cy (r11 is junk) ++ bge Ln1 ++ cax 9,9,6 # adjust high limb for negative limb from s1 ++Ln1: bdn Lnloop ++ b Lend ++ ++Lend0: cal 9,0(10) ++Lend: st 8,4(3) ++ aze 3,9 ++ br ++ +diff --git a/grub-core/lib/libgcrypt/mpi/power/mpih-rshift.S b/grub-core/lib/libgcrypt/mpi/power/mpih-rshift.S +new file mode 100644 +index 0000000..f131a86 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/power/mpih-rshift.S +@@ -0,0 +1,64 @@ ++/* IBM POWER rshift ++ * ++ * Copyright (C) 1992, 1994, 1999, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ */ ++ ++#include "sysdep.h" ++#include "asm-syntax.h" ++ ++ ++/* ++# INPUT PARAMETERS ++# res_ptr r3 ++# s_ptr r4 ++# size r5 ++# cnt r6 ++*/ ++ ++ .toc ++ .extern _gcry_mpih_rshift[DS] ++ .extern ._gcry_mpih_rshift ++.csect [PR] ++ .align 2 ++ .globl _gcry_mpih_rshift ++ .globl ._gcry_mpih_rshift ++ .csect _gcry_mpih_rshift[DS] ++_gcry_mpih_rshift: ++ .long ._gcry_mpih_rshift, TOC[tc0], 0 ++ .csect [PR] ++._gcry_mpih_rshift: ++ sfi 8,6,32 ++ mtctr 5 # put limb count in CTR loop register ++ l 0,0(4) # read least significant limb ++ ai 9,3,-4 # adjust res_ptr since it's offset in the stu:s ++ sle 3,0,8 # compute carry limb, and init MQ register ++ bdz Lend2 # if just one limb, skip loop ++ lu 0,4(4) # read 2:nd least significant limb ++ sleq 7,0,8 # compute least significant limb of result ++ bdz Lend # if just two limb, skip loop ++Loop: lu 0,4(4) # load next higher limb ++ stu 7,4(9) # store previous result during read latency ++ sleq 7,0,8 # compute result limb ++ bdn Loop # loop back until CTR is zero ++Lend: stu 7,4(9) # store 2:nd most significant limb ++Lend2: sre 7,0,6 # compute most significant limb ++ st 7,4(9) # store it ++ br ++ ++ +diff --git a/grub-core/lib/libgcrypt/mpi/power/mpih-sub1.S b/grub-core/lib/libgcrypt/mpi/power/mpih-sub1.S +new file mode 100644 +index 0000000..02748fc +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/power/mpih-sub1.S +@@ -0,0 +1,88 @@ ++/* IBM POWER sub_n -- Subtract two limb vectors of equal, non-zero length. ++ * ++ * Copyright (C) 1992, 1994, 1995, 1996, 1999, ++ * 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ */ ++ ++#include "sysdep.h" ++#include "asm-syntax.h" ++ ++/* ++# INPUT PARAMETERS ++# res_ptr r3 ++# s1_ptr r4 ++# s2_ptr r5 ++# size r6 ++ */ ++ ++ .toc ++ .extern _gcry_mpih_sub_n[DS] ++ .extern ._gcry_mpih_sub_n ++.csect [PR] ++ .align 2 ++ .globl _gcry_mpih_sub_n ++ .globl ._gcry_mpih_sub_n ++ .csect _gcry_mpih_sub_n[DS] ++_gcry_mpih_sub_n: ++ .long ._gcry_mpih_sub_n, TOC[tc0], 0 ++ .csect [PR] ++._gcry_mpih_sub_n: ++ andil. 10,6,1 # odd or even number of limbs? ++ l 8,0(4) # load least significant s1 limb ++ l 0,0(5) # load least significant s2 limb ++ cal 3,-4(3) # offset res_ptr, it's updated before it's used ++ sri 10,6,1 # count for unrolled loop ++ sf 7,0,8 # subtract least significant limbs, set cy ++ mtctr 10 # copy count into CTR ++ beq 0,Leven # branch if even # of limbs (# of limbs >= 2) ++ ++# We have an odd # of limbs. Add the first limbs separately. ++ cmpi 1,10,0 # is count for unrolled loop zero? ++ bne 1,L1 # branch if not ++ st 7,4(3) ++ sfe 3,0,0 # load !cy into ... ++ sfi 3,3,0 # ... return value register ++ br # return ++ ++# We added least significant limbs. Now reload the next limbs to enter loop. ++L1: lu 8,4(4) # load s1 limb and update s1_ptr ++ lu 0,4(5) # load s2 limb and update s2_ptr ++ stu 7,4(3) ++ sfe 7,0,8 # subtract limbs, set cy ++Leven: lu 9,4(4) # load s1 limb and update s1_ptr ++ lu 10,4(5) # load s2 limb and update s2_ptr ++ bdz Lend # If done, skip loop ++ ++Loop: lu 8,4(4) # load s1 limb and update s1_ptr ++ lu 0,4(5) # load s2 limb and update s2_ptr ++ sfe 11,10,9 # subtract previous limbs with cy, set cy ++ stu 7,4(3) # ++ lu 9,4(4) # load s1 limb and update s1_ptr ++ lu 10,4(5) # load s2 limb and update s2_ptr ++ sfe 7,0,8 # subtract previous limbs with cy, set cy ++ stu 11,4(3) # ++ bdn Loop # decrement CTR and loop back ++ ++Lend: sfe 11,10,9 # subtract limbs with cy, set cy ++ st 7,4(3) # ++ st 11,8(3) # ++ sfe 3,0,0 # load !cy into ... ++ sfi 3,3,0 # ... return value register ++ br ++ +diff --git a/grub-core/lib/libgcrypt/mpi/powerpc32/Manifest b/grub-core/lib/libgcrypt/mpi/powerpc32/Manifest +new file mode 100644 +index 0000000..26ab6ea +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/powerpc32/Manifest +@@ -0,0 +1,28 @@ ++# Manifest - checksums ++# Copyright 2003 Free Software Foundation, Inc. ++# ++# This file is part of Libgcrypt. ++# ++# Libgcrypt is free software; you can redistribute it and/or modify ++# it under the terms of the GNU Lesser General Public License as ++# published by the Free Software Foundation; either version 2.1 of ++# the License, or (at your option) any later version. ++# ++# Libgcrypt 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 Lesser General Public License for more details. ++# ++# You should have received a copy of the GNU Lesser General Public ++# License along with this program; if not, write to the Free Software ++# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ ++mpih-add1.S ++mpih-sub1.S ++mpih-mul1.S ++mpih-mul2.S ++mpih-mul3.S ++mpih-lshift.S ++mpih-rshift.S ++syntax.h ++$names$ iQCVAwUAP+LmYzEAnp832S/7AQI/cQP+Mcg9rF/c/bJTY48PE1/ARt7vCMtpIlv9alZSSSrU3WHzCtv9nVczFmwHU3DdKFawigY2DljQcK92dZ5ZlOfpFNMz4PKlVMWaKDk+jKlqm2dxvlHuqEvXPpjFAE2gHrhq5qLXS5ZHeMLJIEK84GYC6fjfLUMdZU3altXTUBvoXhA==Yax+ +diff --git a/grub-core/lib/libgcrypt/mpi/powerpc32/distfiles b/grub-core/lib/libgcrypt/mpi/powerpc32/distfiles +new file mode 100644 +index 0000000..a086614 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/powerpc32/distfiles +@@ -0,0 +1,10 @@ ++Manifest ++mpih-add1.S ++mpih-sub1.S ++mpih-mul1.S ++mpih-mul2.S ++mpih-mul3.S ++mpih-lshift.S ++mpih-rshift.S ++syntax.h ++ +diff --git a/grub-core/lib/libgcrypt/mpi/powerpc32/mpih-add1.S b/grub-core/lib/libgcrypt/mpi/powerpc32/mpih-add1.S +new file mode 100644 +index 0000000..1661f5e +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/powerpc32/mpih-add1.S +@@ -0,0 +1,136 @@ ++/* PowerPC-32 add_n -- Add two limb vectors of equal, non-zero length. ++ * ++ * Copyright (C) 1992, 1994, 1995, 1998, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ */ ++ ++#include "sysdep.h" ++#include "asm-syntax.h" ++ ++ ++#ifndef USE_PPC_PATCHES ++ ++/******************* ++ * mpi_limb_t ++ * _gcry_mpih_add_n( mpi_ptr_t res_ptr, (r3) ++ * mpi_ptr_t s1_ptr, (r4) ++ * mpi_ptr_t s2_ptr, (r5) ++ * mpi_size_t size) (r6) ++ */ ++ ++ .toc ++ .extern _gcry_mpih_add_n[DS] ++ .extern ._gcry_mpih_add_n ++.csect [PR] ++ .align 2 ++ .globl _gcry_mpih_add_n ++ .globl ._gcry_mpih_add_n ++ .csect _gcry_mpih_add_n[DS] ++_gcry_mpih_add_n: ++ .long ._gcry_mpih_add_n, TOC[tc0], 0 ++ .csect [PR] ++._gcry_mpih_add_n: ++ mtctr 6 # copy size into CTR ++ lwz 8,0(4) # load least significant s1 limb ++ lwz 0,0(5) # load least significant s2 limb ++ addi 3,3,-4 # offset res_ptr, it is updated before used ++ addc 7,0,8 # add least significant limbs, set cy ++ bdz Lend # If done, skip loop ++Loop: lwzu 8,4(4) # load s1 limb and update s1_ptr ++ lwzu 0,4(5) # load s2 limb and update s2_ptr ++ stwu 7,4(3) # store previous limb in load latency slot ++ adde 7,0,8 # add new limbs with cy, set cy ++ bdnz Loop # decrement CTR and loop back ++Lend: stw 7,4(3) # store ultimate result limb ++ li 3,0 # load cy into ... ++ addze 3,3 # ... return value register ++ blr ++ ++#else ++/* Add two limb vectors of equal, non-zero length for PowerPC. ++ Copyright (C) 1997 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Library General Public License as ++ published by the Free Software Foundation; either version 2 of the ++ License, or (at your option) any later version. ++ ++ The GNU C Library 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 ++ Library General Public License for more details. ++ ++ You should have received a copy of the GNU Library General Public ++ License along with the GNU C Library; see the file COPYING.LIB. If not, ++ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, ++ Boston, MA 02111-1307, USA. */ ++ ++#include "sysdep.h" ++#include "asm-syntax.h" ++ ++ ++/* mp_limb_t mpn_add_n (mp_ptr res_ptr, mp_srcptr s1_ptr, mp_srcptr s2_ptr, ++ mp_size_t size) ++ Calculate s1+s2 and put result in res_ptr; return carry, 0 or 1. */ ++ ++/* Note on optimisation: This code is optimal for the 601. Almost every other ++ possible 2-unrolled inner loop will not be. Also, watch out for the ++ alignment... */ ++ ++EALIGN(_gcry_mpih_add_n,3,0) ++/* Set up for loop below. */ ++ mtcrf 0x01,%r6 ++ srwi. %r7,%r6,1 ++ li %r10,0 ++ mtctr %r7 ++ bt 31,2f ++ ++/* Clear the carry. */ ++ addic %r0,%r0,0 ++/* Adjust pointers for loop. */ ++ addi %r3,%r3,-4 ++ addi %r4,%r4,-4 ++ addi %r5,%r5,-4 ++ b 0f ++ ++2: lwz %r7,0(%r5) ++ lwz %r6,0(%r4) ++ addc %r6,%r6,%r7 ++ stw %r6,0(%r3) ++ beq 1f ++ ++/* The loop. */ ++ ++/* Align start of loop to an odd word boundary to guarantee that the ++ last two words can be fetched in one access (for 601). */ ++0: lwz %r9,4(%r4) ++ lwz %r8,4(%r5) ++ lwzu %r6,8(%r4) ++ lwzu %r7,8(%r5) ++ adde %r8,%r9,%r8 ++ stw %r8,4(%r3) ++ adde %r6,%r6,%r7 ++ stwu %r6,8(%r3) ++ bdnz 0b ++/* Return the carry. */ ++1: addze %r3,%r10 ++ blr ++END(_gcry_mpih_add_n) ++#endif ++ +diff --git a/grub-core/lib/libgcrypt/mpi/powerpc32/mpih-lshift.S b/grub-core/lib/libgcrypt/mpi/powerpc32/mpih-lshift.S +new file mode 100644 +index 0000000..6231095 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/powerpc32/mpih-lshift.S +@@ -0,0 +1,198 @@ ++/* PowerPC-32 lshift ++ * ++ * Copyright (C) 1995, 1998, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ */ ++ ++#include "sysdep.h" ++#include "asm-syntax.h" ++ ++ ++#ifndef USE_PPC_PATCHES ++ ++/******************* ++ * mpi_limb_t ++ * _gcry_mpih_lshift( mpi_ptr_t wp, (r3) ++ * mpi_ptr_t up, (r4) ++ * mpi_size_t usize, (r5) ++ * unsigned cnt) (r6) ++ */ ++ ++ .toc ++.csect .text[PR] ++ .align 2 ++ .globl _gcry_mpih_lshift ++ .globl ._gcry_mpih_lshift ++ .csect _gcry_mpih_lshift[DS] ++_gcry_mpih_lshift: ++ .long ._gcry_mpih_lshift, TOC[tc0], 0 ++ .csect .text[PR] ++._gcry_mpih_lshift: ++ mtctr 5 # copy size into CTR ++ slwi 0,5,2 ++ add 7,3,0 # make r7 point at end of res ++ add 4,4,0 # make r4 point at end of s1 ++ subfic 8,6,32 ++ lwzu 11,-4(4) # load first s1 limb ++ srw 3,11,8 # compute function return value ++ bdz Lend1 ++ ++Loop: lwzu 10,-4(4) ++ slw 9,11,6 ++ srw 12,10,8 ++ or 9,9,12 ++ stwu 9,-4(7) ++ bdz Lend2 ++ lwzu 11,-4(4) ++ slw 9,10,6 ++ srw 12,11,8 ++ or 9,9,12 ++ stwu 9,-4(7) ++ bdnz Loop ++ ++Lend1: slw 0,11,6 ++ stw 0,-4(7) ++ blr ++ ++Lend2: slw 0,10,6 ++ stw 0,-4(7) ++ blr ++ ++#else ++/* Shift a limb left, low level routine. ++ Copyright (C) 1996, 1997 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Library General Public License as ++ published by the Free Software Foundation; either version 2 of the ++ License, or (at your option) any later version. ++ ++ The GNU C Library 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 ++ Library General Public License for more details. ++ ++ You should have received a copy of the GNU Library General Public ++ License along with the GNU C Library; see the file COPYING.LIB. If not, ++ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, ++ Boston, MA 02111-1307, USA. */ ++ ++/* mp_limb_t mpn_lshift (mp_ptr wp, mp_srcptr up, mp_size_t usize, ++ unsigned int cnt) */ ++ ++EALIGN(_gcry_mpih_lshift,3,0) ++ mtctr %r5 # copy size into CTR ++ cmplwi %cr0,%r5,16 # is size < 16 ++ slwi %r0,%r5,2 ++ add %r7,%r3,%r0 # make r7 point at end of res ++ add %r4,%r4,%r0 # make r4 point at end of s1 ++ lwzu %r11,-4(%r4) # load first s1 limb ++ subfic %r8,%r6,32 ++ srw %r3,%r11,%r8 # compute function return value ++ bge %cr0,L(big) # branch if size >= 16 ++ ++ bdz L(end1) ++ ++0: lwzu %r10,-4(%r4) ++ slw %r9,%r11,%r6 ++ srw %r12,%r10,%r8 ++ or %r9,%r9,%r12 ++ stwu %r9,-4(%r7) ++ bdz L(end2) ++ lwzu %r11,-4(%r4) ++ slw %r9,%r10,%r6 ++ srw %r12,%r11,%r8 ++ or %r9,%r9,%r12 ++ stwu %r9,-4(%r7) ++ bdnz 0b ++ ++L(end1):slw %r0,%r11,%r6 ++ stw %r0,-4(%r7) ++ blr ++ ++ ++/* Guaranteed not to succeed. */ ++L(boom): tweq %r0,%r0 ++ ++/* We imitate a case statement, by using (yuk!) fixed-length code chunks, ++ of size 4*12 bytes. We have to do this (or something) to make this PIC. */ ++L(big): mflr %r9 ++ bltl- %cr0,L(boom) # Never taken, only used to set LR. ++ slwi %r10,%r6,4 ++ mflr %r12 ++ add %r10,%r12,%r10 ++ slwi %r8,%r6,5 ++ add %r10,%r8,%r10 ++ mtctr %r10 ++ addi %r5,%r5,-1 ++ mtlr %r9 ++ bctr ++ ++L(end2):slw %r0,%r10,%r6 ++ stw %r0,-4(%r7) ++ blr ++ ++#define DO_LSHIFT(n) \ ++ mtctr %r5; \ ++0: lwzu %r10,-4(%r4); \ ++ slwi %r9,%r11,n; \ ++ inslwi %r9,%r10,n,32-n; \ ++ stwu %r9,-4(%r7); \ ++ bdz- L(end2); \ ++ lwzu %r11,-4(%r4); \ ++ slwi %r9,%r10,n; \ ++ inslwi %r9,%r11,n,32-n; \ ++ stwu %r9,-4(%r7); \ ++ bdnz 0b; \ ++ b L(end1) ++ ++ DO_LSHIFT(1) ++ DO_LSHIFT(2) ++ DO_LSHIFT(3) ++ DO_LSHIFT(4) ++ DO_LSHIFT(5) ++ DO_LSHIFT(6) ++ DO_LSHIFT(7) ++ DO_LSHIFT(8) ++ DO_LSHIFT(9) ++ DO_LSHIFT(10) ++ DO_LSHIFT(11) ++ DO_LSHIFT(12) ++ DO_LSHIFT(13) ++ DO_LSHIFT(14) ++ DO_LSHIFT(15) ++ DO_LSHIFT(16) ++ DO_LSHIFT(17) ++ DO_LSHIFT(18) ++ DO_LSHIFT(19) ++ DO_LSHIFT(20) ++ DO_LSHIFT(21) ++ DO_LSHIFT(22) ++ DO_LSHIFT(23) ++ DO_LSHIFT(24) ++ DO_LSHIFT(25) ++ DO_LSHIFT(26) ++ DO_LSHIFT(27) ++ DO_LSHIFT(28) ++ DO_LSHIFT(29) ++ DO_LSHIFT(30) ++ DO_LSHIFT(31) ++ ++END(_gcry_mpih_lshift) ++#endif +diff --git a/grub-core/lib/libgcrypt/mpi/powerpc32/mpih-mul1.S b/grub-core/lib/libgcrypt/mpi/powerpc32/mpih-mul1.S +new file mode 100644 +index 0000000..bd418f7 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/powerpc32/mpih-mul1.S +@@ -0,0 +1,120 @@ ++/* PowerPC-32 mul_1 -- Multiply a limb vector with a limb and store ++ * the result in a second limb vector. ++ * ++ * Copyright (C) 1992, 1993, 1994, 1995, ++ * 1998, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ */ ++ ++#include "sysdep.h" ++#include "asm-syntax.h" ++ ++ ++#ifndef USE_PPC_PATCHES ++ ++/******************* ++ * mpi_limb_t ++ * _gcry_mpih_mul_1( mpi_ptr_t res_ptr, (r3) ++ * mpi_ptr_t s1_ptr, (r4) ++ * mpi_size_t s1_size, (r5) ++ * mpi_limb_t s2_limb) (r6) ++ * ++ * This is a fairly straightforward implementation. The timing of the PC601 ++ * is hard to understand, so I will wait to optimize this until I have some ++ * hardware to play with. ++ * ++ * The code trivially generalizes to 64 bit limbs for the PC620. ++ */ ++ ++ .toc ++ .csect ._gcry_mpih_mul_1[PR] ++ .align 2 ++ .globl _gcry_mpih_mul_1 ++ .globl ._gcry_mpih_mul_1 ++ .csect _gcry_mpih_mul_1[DS] ++_gcry_mpih_mul_1: ++ .long ._gcry_mpih_mul_1[PR], TOC[tc0], 0 ++ .csect ._gcry_mpih_mul_1[PR] ++._gcry_mpih_mul_1: ++ mtctr 5 ++ ++ lwz 0,0(4) ++ mullw 7,0,6 ++ mulhwu 10,0,6 ++ addi 3,3,-4 # adjust res_ptr ++ addic 5,5,0 # clear cy with dummy insn ++ bdz Lend ++ ++Loop: lwzu 0,4(4) ++ stwu 7,4(3) ++ mullw 8,0,6 ++ adde 7,8,10 ++ mulhwu 10,0,6 ++ bdnz Loop ++ ++Lend: stw 7,4(3) ++ addze 3,10 ++ blr ++ ++#else ++/* Multiply a limb vector by a limb, for PowerPC. ++ Copyright (C) 1993, 1994, 1995, 1997 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Library General Public License as ++ published by the Free Software Foundation; either version 2 of the ++ License, or (at your option) any later version. ++ ++ The GNU C Library 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 ++ Library General Public License for more details. ++ ++ You should have received a copy of the GNU Library General Public ++ License along with the GNU C Library; see the file COPYING.LIB. If not, ++ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, ++ Boston, MA 02111-1307, USA. */ ++ ++ ++/* mp_limb_t mpn_mul_1 (mp_ptr res_ptr, mp_srcptr s1_ptr, ++ mp_size_t s1_size, mp_limb_t s2_limb) ++ Calculate s1*s2 and put result in res_ptr; return carry. */ ++ ++ENTRY(_gcry_mpih_mul_1) ++ mtctr %r5 ++ ++ lwz %r0,0(%r4) ++ mullw %r7,%r0,%r6 ++ mulhwu %r10,%r0,%r6 ++ addi %r3,%r3,-4 # adjust res_ptr ++ addic %r5,%r5,0 # clear cy with dummy insn ++ bdz 1f ++ ++0: lwzu %r0,4(%r4) ++ stwu %r7,4(%r3) ++ mullw %r8,%r0,%r6 ++ adde %r7,%r8,%r10 ++ mulhwu %r10,%r0,%r6 ++ bdnz 0b ++ ++1: stw %r7,4(%r3) ++ addze %r3,%r10 ++ blr ++END(_gcry_mpih_mul_1) ++#endif +diff --git a/grub-core/lib/libgcrypt/mpi/powerpc32/mpih-mul2.S b/grub-core/lib/libgcrypt/mpi/powerpc32/mpih-mul2.S +new file mode 100644 +index 0000000..1d97b81 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/powerpc32/mpih-mul2.S +@@ -0,0 +1,127 @@ ++/* PowerPC-32 addmul_1 -- Multiply a limb vector with a limb and add ++ * the result to a second limb vector. ++ * ++ * Copyright (C) 1995, 1998, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ */ ++ ++#include "sysdep.h" ++#include "asm-syntax.h" ++ ++ ++#ifndef USE_PPC_PATCHES ++ ++/******************* ++ * mpi_limb_t ++ * _gcry_mpih_addmul_1( mpi_ptr_t res_ptr, (r3) ++ * mpi_ptr_t s1_ptr, (r4) ++ * mpi_size_t s1_size, (r5) ++ * mpi_limb_t s2_limb) (r6) ++ * ++ * This is a fairly straightforward implementation. The timing of the PC601 ++ * is hard to understand, so I will wait to optimize this until I have some ++ * hardware to play with. ++ * ++ * The code trivially generalizes to 64 bit limbs for the PC620. ++ */ ++ ++ ++ .toc ++ .csect ._gcry_mpih_addmul_1[PR] ++ .align 2 ++ .globl _gcry_mpih_addmul_1 ++ .globl ._gcry_mpih_addmul_1 ++ .csect _gcry_mpih_addmul_1[DS] ++_gcry_mpih_addmul_1: ++ .long ._gcry_mpih_addmul_1[PR], TOC[tc0], 0 ++ .csect ._gcry_mpih_addmul_1[PR] ++._gcry_mpih_addmul_1: ++ mtctr 5 ++ ++ lwz 0,0(4) ++ mullw 7,0,6 ++ mulhwu 10,0,6 ++ lwz 9,0(3) ++ addc 8,7,9 ++ addi 3,3,-4 ++ bdz Lend ++ ++Loop: lwzu 0,4(4) ++ stwu 8,4(3) ++ mullw 8,0,6 ++ adde 7,8,10 ++ mulhwu 10,0,6 ++ lwz 9,4(3) ++ addze 10,10 ++ addc 8,7,9 ++ bdnz Loop ++ ++Lend: stw 8,4(3) ++ addze 3,10 ++ blr ++ ++#else ++/* Multiply a limb vector by a single limb, for PowerPC. ++ Copyright (C) 1993, 1994, 1995, 1997 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Library General Public License as ++ published by the Free Software Foundation; either version 2 of the ++ License, or (at your option) any later version. ++ ++ The GNU C Library 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 ++ Library General Public License for more details. ++ ++ You should have received a copy of the GNU Library General Public ++ License along with the GNU C Library; see the file COPYING.LIB. If not, ++ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, ++ Boston, MA 02111-1307, USA. */ ++ ++ ++/* mp_limb_t mpn_addmul_1 (mp_ptr res_ptr, mp_srcptr s1_ptr, ++ mp_size_t s1_size, mp_limb_t s2_limb) ++ Calculate res+s1*s2 and put result back in res; return carry. */ ++ENTRY(_gcry_mpih_addmul_1) ++ mtctr %r5 ++ ++ lwz %r0,0(%r4) ++ mullw %r7,%r0,%r6 ++ mulhwu %r10,%r0,%r6 ++ lwz %r9,0(%r3) ++ addc %r8,%r7,%r9 ++ addi %r3,%r3,-4 /* adjust res_ptr */ ++ bdz 1f ++ ++0: lwzu %r0,4(%r4) ++ stwu %r8,4(%r3) ++ mullw %r8,%r0,%r6 ++ adde %r7,%r8,%r10 ++ mulhwu %r10,%r0,%r6 ++ lwz %r9,4(%r3) ++ addze %r10,%r10 ++ addc %r8,%r7,%r9 ++ bdnz 0b ++ ++1: stw %r8,4(%r3) ++ addze %r3,%r10 ++ blr ++END(_gcry_mpih_addmul_1) ++#endif +diff --git a/grub-core/lib/libgcrypt/mpi/powerpc32/mpih-mul3.S b/grub-core/lib/libgcrypt/mpi/powerpc32/mpih-mul3.S +new file mode 100644 +index 0000000..c410dbb +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/powerpc32/mpih-mul3.S +@@ -0,0 +1,130 @@ ++/* PowerPC-32 submul_1 -- Multiply a limb vector with a limb and subtract ++ * the result from a second limb vector. ++ * ++ * Copyright (C) 1995, 1998, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ */ ++ ++#include "sysdep.h" ++#include "asm-syntax.h" ++ ++ ++#ifndef USE_PPC_PATCHES ++ ++/******************* ++ * mpi_limb_t ++ * _gcry_mpih_submul_1( mpi_ptr_t res_ptr, (r3) ++ * mpi_ptr_t s1_ptr, (r4) ++ * mpi_size_t s1_size, (r5) ++ * mpi_limb_t s2_limb) (r6) ++ * ++ * This is a fairly straightforward implementation. The timing of the PC601 ++ * is hard to understand, so I will wait to optimize this until I have some ++ * hardware to play with. ++ * ++ * The code trivially generalizes to 64 bit limbs for the PC620. ++ */ ++ ++ .toc ++ .csect ._gcry_mpih_submul_1[PR] ++ .align 2 ++ .globl _gcry_mpih_submul_1 ++ .globl ._gcry_mpih_submul_1 ++ .csect _gcry_mpih_submul_1[DS] ++_gcry_mpih_submul_1: ++ .long ._gcry_mpih_submul_1[PR], TOC[tc0], 0 ++ .csect ._gcry_mpih_submul_1[PR] ++._gcry_mpih_submul_1: ++ mtctr 5 ++ ++ lwz 0,0(4) ++ mullw 7,0,6 ++ mulhwu 10,0,6 ++ lwz 9,0(3) ++ subfc 8,7,9 ++ addc 7,7,8 # invert cy (r7 is junk) ++ addi 3,3,-4 ++ bdz Lend ++ ++Loop: lwzu 0,4(4) ++ stwu 8,4(3) ++ mullw 8,0,6 ++ adde 7,8,10 ++ mulhwu 10,0,6 ++ lwz 9,4(3) ++ addze 10,10 ++ subfc 8,7,9 ++ addc 7,7,8 # invert cy (r7 is junk) ++ bdnz Loop ++ ++Lend: stw 8,4(3) ++ addze 3,10 ++ blr ++ ++#else ++/* Multiply a limb vector by a single limb, for PowerPC. ++ Copyright (C) 1993, 1994, 1995, 1997 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Library General Public License as ++ published by the Free Software Foundation; either version 2 of the ++ License, or (at your option) any later version. ++ ++ The GNU C Library 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 ++ Library General Public License for more details. ++ ++ You should have received a copy of the GNU Library General Public ++ License along with the GNU C Library; see the file COPYING.LIB. If not, ++ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, ++ Boston, MA 02111-1307, USA. */ ++ ++/* mp_limb_t mpn_submul_1 (mp_ptr res_ptr, mp_srcptr s1_ptr, ++ mp_size_t s1_size, mp_limb_t s2_limb) ++ Calculate res-s1*s2 and put result back in res; return carry. */ ++ ++ENTRY(_gcry_mpih_submul_1) ++ mtctr %r5 ++ ++ lwz %r0,0(%r4) ++ mullw %r7,%r0,%r6 ++ mulhwu %r10,%r0,%r6 ++ lwz %r9,0(%r3) ++ subf %r8,%r7,%r9 ++ addc %r7,%r7,%r8 # invert cy (r7 is junk) ++ addi %r3,%r3,-4 # adjust res_ptr ++ bdz 1f ++ ++0: lwzu %r0,4(%r4) ++ stwu %r8,4(%r3) ++ mullw %r8,%r0,%r6 ++ adde %r7,%r8,%r10 ++ mulhwu %r10,%r0,%r6 ++ lwz %r9,4(%r3) ++ addze %r10,%r10 ++ subf %r8,%r7,%r9 ++ addc %r7,%r7,%r8 # invert cy (r7 is junk) ++ bdnz 0b ++ ++1: stw %r8,4(%r3) ++ addze %r3,%r10 ++ blr ++END(_gcry_mpih_submul_1) ++#endif +diff --git a/grub-core/lib/libgcrypt/mpi/powerpc32/mpih-rshift.S b/grub-core/lib/libgcrypt/mpi/powerpc32/mpih-rshift.S +new file mode 100644 +index 0000000..98349ed +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/powerpc32/mpih-rshift.S +@@ -0,0 +1,131 @@ ++/* PowerPC-32 rshift ++ * ++ * Copyright (C) 1995, 1998, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ */ ++ ++ ++#include "sysdep.h" ++#include "asm-syntax.h" ++ ++ ++#ifndef USE_PPC_PATCHES ++ ++/******************* ++ * mpi_limb_t ++ * _gcry_mpih_rshift( mpi_ptr_t wp, (r3) ++ * mpi_ptr_t up, (r4) ++ * mpi_size_t usize, (r5) ++ * unsigned cnt) (r6) ++ */ ++ ++ .toc ++.csect .text[PR] ++ .align 2 ++ .globl _gcry_mpih_rshift ++ .globl ._gcry_mpih_rshift ++ .csect _gcry_mpih_rshift[DS] ++_gcry_mpih_rshift: ++ .long ._gcry_mpih_rshift, TOC[tc0], 0 ++ .csect .text[PR] ++._gcry_mpih_rshift: ++ mtctr 5 # copy size into CTR ++ addi 7,3,-4 # move adjusted res_ptr to free return reg ++ subfic 8,6,32 ++ lwz 11,0(4) # load first s1 limb ++ slw 3,11,8 # compute function return value ++ bdz Lend1 ++ ++Loop: lwzu 10,4(4) ++ srw 9,11,6 ++ slw 12,10,8 ++ or 9,9,12 ++ stwu 9,4(7) ++ bdz Lend2 ++ lwzu 11,4(4) ++ srw 9,10,6 ++ slw 12,11,8 ++ or 9,9,12 ++ stwu 9,4(7) ++ bdnz Loop ++ ++Lend1: srw 0,11,6 ++ stw 0,4(7) ++ blr ++ ++Lend2: srw 0,10,6 ++ stw 0,4(7) ++ blr ++ ++#else ++/* Shift a limb right, low level routine. ++ Copyright (C) 1995, 1997 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Library General Public License as ++ published by the Free Software Foundation; either version 2 of the ++ License, or (at your option) any later version. ++ ++ The GNU C Library 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 ++ Library General Public License for more details. ++ ++ You should have received a copy of the GNU Library General Public ++ License along with the GNU C Library; see the file COPYING.LIB. If not, ++ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, ++ Boston, MA 02111-1307, USA. */ ++ ++ ++/* INPUT PARAMETERS ++ res_ptr r3 ++ s1_ptr r4 ++ size r5 ++ cnt r6 */ ++ ++ENTRY(_gcry_mpih_rshift) ++ mtctr 5 # copy size into CTR ++ addi 7,3,-4 # move adjusted res_ptr to free return reg ++ subfic 8,6,32 ++ lwz 11,0(4) # load first s1 limb ++ slw 3,11,8 # compute function return value ++ bdz 1f ++ ++0: lwzu 10,4(4) ++ srw 9,11,6 ++ slw 12,10,8 ++ or 9,9,12 ++ stwu 9,4(7) ++ bdz 2f ++ lwzu 11,4(4) ++ srw 9,10,6 ++ slw 12,11,8 ++ or 9,9,12 ++ stwu 9,4(7) ++ bdnz 0b ++ ++1: srw 0,11,6 ++ stw 0,4(7) ++ blr ++ ++2: srw 0,10,6 ++ stw 0,4(7) ++ blr ++END(_gcry_mpih_rshift) ++#endif +diff --git a/grub-core/lib/libgcrypt/mpi/powerpc32/mpih-sub1.S b/grub-core/lib/libgcrypt/mpi/powerpc32/mpih-sub1.S +new file mode 100644 +index 0000000..d612ea8 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/powerpc32/mpih-sub1.S +@@ -0,0 +1,133 @@ ++/* PowerPC-32 sub_n -- Subtract two limb vectors of the same length > 0 ++ * and store difference in a third limb vector. ++ * ++ * Copyright (C) 1992, 1994, 1995, 1998, ++ * 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ */ ++ ++#include "sysdep.h" ++#include "asm-syntax.h" ++ ++ ++#ifndef USE_PPC_PATCHES ++ ++/******************* ++ * mpi_limb_t ++ * _gcry_mpih_sub_n( mpi_ptr_t res_ptr, (r3) ++ * mpi_ptr_t s1_ptr, (r4) ++ * mpi_ptr_t s2_ptr, (r5) ++ * mpi_size_t size) (r6) ++ */ ++ ++ .toc ++ .extern _gcry_mpih_sub_n[DS] ++ .extern ._gcry_mpih_sub_n ++.csect [PR] ++ .align 2 ++ .globl _gcry_mpih_sub_n ++ .globl ._gcry_mpih_sub_n ++ .csect _gcry_mpih_sub_n[DS] ++_gcry_mpih_sub_n: ++ .long ._gcry_mpih_sub_n, TOC[tc0], 0 ++ .csect [PR] ++._gcry_mpih_sub_n: ++ mtctr 6 # copy size into CTR ++ lwz 8,0(4) # load least significant s1 limb ++ lwz 0,0(5) # load least significant s2 limb ++ addi 3,3,-4 # offset res_ptr, it is updated before used ++ subfc 7,0,8 # add least significant limbs, set cy ++ bdz Lend # If done, skip loop ++Loop: lwzu 8,4(4) # load s1 limb and update s1_ptr ++ lwzu 0,4(5) # load s2 limb and update s2_ptr ++ stwu 7,4(3) # store previous limb in load latency slot ++ subfe 7,0,8 # add new limbs with cy, set cy ++ bdnz Loop # decrement CTR and loop back ++Lend: stw 7,4(3) # store ultimate result limb ++ subfe 3,0,0 # load !cy into ... ++ subfic 3,3,0 # ... return value register ++ blr ++ ++#else ++/* Subtract two limb vectors of equal, non-zero length for PowerPC. ++ Copyright (C) 1997 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Library General Public License as ++ published by the Free Software Foundation; either version 2 of the ++ License, or (at your option) any later version. ++ ++ The GNU C Library 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 ++ Library General Public License for more details. ++ ++ You should have received a copy of the GNU Library General Public ++ License along with the GNU C Library; see the file COPYING.LIB. If not, ++ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, ++ Boston, MA 02111-1307, USA. */ ++ ++/* mp_limb_t mpn_sub_n (mp_ptr res_ptr, mp_srcptr s1_ptr, mp_srcptr s2_ptr, ++ mp_size_t size) ++ Calculate s1-s2 and put result in res_ptr; return borrow, 0 or 1. */ ++ ++/* Note on optimisation: This code is optimal for the 601. Almost every other ++ possible 2-unrolled inner loop will not be. Also, watch out for the ++ alignment... */ ++ ++EALIGN(_gcry_mpih_sub_n,3,1) ++/* Set up for loop below. */ ++ mtcrf 0x01,%r6 ++ srwi. %r7,%r6,1 ++ mtctr %r7 ++ bt 31,2f ++ ++/* Set the carry (clear the borrow). */ ++ subfc %r0,%r0,%r0 ++/* Adjust pointers for loop. */ ++ addi %r3,%r3,-4 ++ addi %r4,%r4,-4 ++ addi %r5,%r5,-4 ++ b 0f ++ ++2: lwz %r7,0(%r5) ++ lwz %r6,0(%r4) ++ subfc %r6,%r7,%r6 ++ stw %r6,0(%r3) ++ beq 1f ++ ++/* Align start of loop to an odd word boundary to guarantee that the ++ last two words can be fetched in one access (for 601). This turns ++ out to be important. */ ++0: ++ lwz %r9,4(%r4) ++ lwz %r8,4(%r5) ++ lwzu %r6,8(%r4) ++ lwzu %r7,8(%r5) ++ subfe %r8,%r8,%r9 ++ stw %r8,4(%r3) ++ subfe %r6,%r7,%r6 ++ stwu %r6,8(%r3) ++ bdnz 0b ++/* Return the borrow. */ ++1: subfe %r3,%r3,%r3 ++ neg %r3,%r3 ++ blr ++END(_gcry_mpih_sub_n) ++#endif +diff --git a/grub-core/lib/libgcrypt/mpi/powerpc32/syntax.h b/grub-core/lib/libgcrypt/mpi/powerpc32/syntax.h +new file mode 100644 +index 0000000..5d4af9f +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/powerpc32/syntax.h +@@ -0,0 +1,75 @@ ++/* gmp2-2.0.2-ppc/mpn/powerpc-linux/syntax.h Tue Oct 6 19:27:01 1998 */ ++/* From glibc's sysdeps/unix/sysv/linux/powerpc/sysdep.h */ ++ ++/* Copyright (C) 1992, 1997, 1998 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Library General Public License as ++ published by the Free Software Foundation; either version 2 of the ++ License, or (at your option) any later version. ++ ++ The GNU C Library 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 ++ Library General Public License for more details. ++ ++ You should have received a copy of the GNU Library General Public ++ License along with the GNU C Library; see the file COPYING.LIB. If not, ++ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, ++ Boston, MA 02111-1307, USA. */ ++ ++ ++#define USE_PPC_PATCHES 1 ++ ++/* This seems to always be the case on PPC. */ ++#define ALIGNARG(log2) log2 ++/* For ELF we need the `.type' directive to make shared libs work right. */ ++#define ASM_TYPE_DIRECTIVE(name,typearg) .type name,typearg; ++#define ASM_SIZE_DIRECTIVE(name) .size name,.-name ++#define ASM_GLOBAL_DIRECTIVE .globl ++ ++#ifdef __STDC__ ++#define C_LABEL(name) C_SYMBOL_NAME(name)##: ++#else ++#define C_LABEL(name) C_SYMBOL_NAME(name)/**/: ++#endif ++ ++#ifdef __STDC__ ++#define L(body) .L##body ++#else ++#define L(body) .L/**/body ++#endif ++ ++/* No profiling of gmp's assembly for now... */ ++#define CALL_MCOUNT /* no profiling */ ++ ++#define ENTRY(name) \ ++ ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \ ++ ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function) \ ++ .align ALIGNARG(2); \ ++ C_LABEL(name) \ ++ CALL_MCOUNT ++ ++#define EALIGN_W_0 /* No words to insert. */ ++#define EALIGN_W_1 nop ++#define EALIGN_W_2 nop;nop ++#define EALIGN_W_3 nop;nop;nop ++#define EALIGN_W_4 EALIGN_W_3;nop ++#define EALIGN_W_5 EALIGN_W_4;nop ++#define EALIGN_W_6 EALIGN_W_5;nop ++#define EALIGN_W_7 EALIGN_W_6;nop ++ ++/* EALIGN is like ENTRY, but does alignment to 'words'*4 bytes ++ past a 2^align boundary. */ ++#define EALIGN(name, alignt, words) \ ++ ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \ ++ ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function) \ ++ .align ALIGNARG(alignt); \ ++ EALIGN_W_##words; \ ++ C_LABEL(name) ++ ++#undef END ++#define END(name) \ ++ ASM_SIZE_DIRECTIVE(name) ++ +diff --git a/grub-core/lib/libgcrypt/mpi/sparc32/Manifest b/grub-core/lib/libgcrypt/mpi/sparc32/Manifest +new file mode 100644 +index 0000000..d279229 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/sparc32/Manifest +@@ -0,0 +1,24 @@ ++# Manifest - checksums ++# Copyright 2003 Free Software Foundation, Inc. ++# ++# This file is part of Libgcrypt. ++# ++# Libgcrypt is free software; you can redistribute it and/or modify ++# it under the terms of the GNU Lesser General Public License as ++# published by the Free Software Foundation; either version 2.1 of ++# the License, or (at your option) any later version. ++# ++# Libgcrypt 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 Lesser General Public License for more details. ++# ++# You should have received a copy of the GNU Lesser General Public ++# License along with this program; if not, write to the Free Software ++# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ ++mpih-lshift.S ++mpih-rshift.S ++mpih-add1.S ++udiv.S ++$names$ iQCVAwUAP+LmaDEAnp832S/7AQISHgP/Z5orU+CPKBeRFCogSQDm4p7J2VpDovU6mtfMTdjhqWuZG0U6y8WqH0aj3USfziOhtc8YjQHQ+97g3+EnIWZgLjKacWC6pScY/QbATEpF1D0Wrcea5rk3qR1t7isdBVVOrxedZ5vuj5Op2zx/0OlPI+wt6fTtW88BdG/a6w/ZU/8==Py6h +diff --git a/grub-core/lib/libgcrypt/mpi/sparc32/distfiles b/grub-core/lib/libgcrypt/mpi/sparc32/distfiles +new file mode 100644 +index 0000000..a20f18e +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/sparc32/distfiles +@@ -0,0 +1,6 @@ ++Manifest ++mpih-lshift.S ++mpih-rshift.S ++mpih-add1.S ++udiv.S ++ +diff --git a/grub-core/lib/libgcrypt/mpi/sparc32/mpih-add1.S b/grub-core/lib/libgcrypt/mpi/sparc32/mpih-add1.S +new file mode 100644 +index 0000000..61a80ca +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/sparc32/mpih-add1.S +@@ -0,0 +1,239 @@ ++/* SPARC _add_n -- Add two limb vectors of the same length > 0 and store ++ * sum in a third limb vector. ++ * ++ * Copyright (C) 1995, 1996, 1998, ++ * 2001, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ */ ++ ++ ++ ++/******************* ++ * mpi_limb_t ++ * _gcry_mpih_add_n( mpi_ptr_t res_ptr, ++ * mpi_ptr_t s1_ptr, ++ * mpi_ptr_t s2_ptr, ++ * mpi_size_t size) ++ */ ++ ++! INPUT PARAMETERS ++#define res_ptr %o0 ++#define s1_ptr %o1 ++#define s2_ptr %o2 ++#define size %o3 ++ ++#include "sysdep.h" ++ ++ .text ++ .align 4 ++ .global C_SYMBOL_NAME(_gcry_mpih_add_n) ++C_SYMBOL_NAME(_gcry_mpih_add_n): ++ xor s2_ptr,res_ptr,%g1 ++ andcc %g1,4,%g0 ++ bne L1 ! branch if alignment differs ++ nop ++! ** V1a ** ++L0: andcc res_ptr,4,%g0 ! res_ptr unaligned? Side effect: cy=0 ++ be L_v1 ! if no, branch ++ nop ++/* Add least significant limb separately to align res_ptr and s2_ptr */ ++ ld [s1_ptr],%g4 ++ add s1_ptr,4,s1_ptr ++ ld [s2_ptr],%g2 ++ add s2_ptr,4,s2_ptr ++ add size,-1,size ++ addcc %g4,%g2,%o4 ++ st %o4,[res_ptr] ++ add res_ptr,4,res_ptr ++L_v1: addx %g0,%g0,%o4 ! save cy in register ++ cmp size,2 ! if size < 2 ... ++ bl Lend2 ! ... branch to tail code ++ subcc %g0,%o4,%g0 ! restore cy ++ ++ ld [s1_ptr+0],%g4 ++ addcc size,-10,size ++ ld [s1_ptr+4],%g1 ++ ldd [s2_ptr+0],%g2 ++ blt Lfin1 ++ subcc %g0,%o4,%g0 ! restore cy ++/* Add blocks of 8 limbs until less than 8 limbs remain */ ++Loop1: addxcc %g4,%g2,%o4 ++ ld [s1_ptr+8],%g4 ++ addxcc %g1,%g3,%o5 ++ ld [s1_ptr+12],%g1 ++ ldd [s2_ptr+8],%g2 ++ std %o4,[res_ptr+0] ++ addxcc %g4,%g2,%o4 ++ ld [s1_ptr+16],%g4 ++ addxcc %g1,%g3,%o5 ++ ld [s1_ptr+20],%g1 ++ ldd [s2_ptr+16],%g2 ++ std %o4,[res_ptr+8] ++ addxcc %g4,%g2,%o4 ++ ld [s1_ptr+24],%g4 ++ addxcc %g1,%g3,%o5 ++ ld [s1_ptr+28],%g1 ++ ldd [s2_ptr+24],%g2 ++ std %o4,[res_ptr+16] ++ addxcc %g4,%g2,%o4 ++ ld [s1_ptr+32],%g4 ++ addxcc %g1,%g3,%o5 ++ ld [s1_ptr+36],%g1 ++ ldd [s2_ptr+32],%g2 ++ std %o4,[res_ptr+24] ++ addx %g0,%g0,%o4 ! save cy in register ++ addcc size,-8,size ++ add s1_ptr,32,s1_ptr ++ add s2_ptr,32,s2_ptr ++ add res_ptr,32,res_ptr ++ bge Loop1 ++ subcc %g0,%o4,%g0 ! restore cy ++ ++Lfin1: addcc size,8-2,size ++ blt Lend1 ++ subcc %g0,%o4,%g0 ! restore cy ++/* Add blocks of 2 limbs until less than 2 limbs remain */ ++Loope1: addxcc %g4,%g2,%o4 ++ ld [s1_ptr+8],%g4 ++ addxcc %g1,%g3,%o5 ++ ld [s1_ptr+12],%g1 ++ ldd [s2_ptr+8],%g2 ++ std %o4,[res_ptr+0] ++ addx %g0,%g0,%o4 ! save cy in register ++ addcc size,-2,size ++ add s1_ptr,8,s1_ptr ++ add s2_ptr,8,s2_ptr ++ add res_ptr,8,res_ptr ++ bge Loope1 ++ subcc %g0,%o4,%g0 ! restore cy ++Lend1: addxcc %g4,%g2,%o4 ++ addxcc %g1,%g3,%o5 ++ std %o4,[res_ptr+0] ++ addx %g0,%g0,%o4 ! save cy in register ++ ++ andcc size,1,%g0 ++ be Lret1 ++ subcc %g0,%o4,%g0 ! restore cy ++/* Add last limb */ ++ ld [s1_ptr+8],%g4 ++ ld [s2_ptr+8],%g2 ++ addxcc %g4,%g2,%o4 ++ st %o4,[res_ptr+8] ++ ++Lret1: retl ++ addx %g0,%g0,%o0 ! return carry-out from most sign. limb ++ ++L1: xor s1_ptr,res_ptr,%g1 ++ andcc %g1,4,%g0 ++ bne L2 ++ nop ++! ** V1b ** ++ mov s2_ptr,%g1 ++ mov s1_ptr,s2_ptr ++ b L0 ++ mov %g1,s1_ptr ++ ++! ** V2 ** ++/* If we come here, the alignment of s1_ptr and res_ptr as well as the ++ alignment of s2_ptr and res_ptr differ. Since there are only two ways ++ things can be aligned (that we care about) we now know that the alignment ++ of s1_ptr and s2_ptr are the same. */ ++ ++L2: cmp size,1 ++ be Ljone ++ nop ++ andcc s1_ptr,4,%g0 ! s1_ptr unaligned? Side effect: cy=0 ++ be L_v2 ! if no, branch ++ nop ++/* Add least significant limb separately to align s1_ptr and s2_ptr */ ++ ld [s1_ptr],%g4 ++ add s1_ptr,4,s1_ptr ++ ld [s2_ptr],%g2 ++ add s2_ptr,4,s2_ptr ++ add size,-1,size ++ addcc %g4,%g2,%o4 ++ st %o4,[res_ptr] ++ add res_ptr,4,res_ptr ++ ++L_v2: addx %g0,%g0,%o4 ! save cy in register ++ addcc size,-8,size ++ blt Lfin2 ++ subcc %g0,%o4,%g0 ! restore cy ++/* Add blocks of 8 limbs until less than 8 limbs remain */ ++Loop2: ldd [s1_ptr+0],%g2 ++ ldd [s2_ptr+0],%o4 ++ addxcc %g2,%o4,%g2 ++ st %g2,[res_ptr+0] ++ addxcc %g3,%o5,%g3 ++ st %g3,[res_ptr+4] ++ ldd [s1_ptr+8],%g2 ++ ldd [s2_ptr+8],%o4 ++ addxcc %g2,%o4,%g2 ++ st %g2,[res_ptr+8] ++ addxcc %g3,%o5,%g3 ++ st %g3,[res_ptr+12] ++ ldd [s1_ptr+16],%g2 ++ ldd [s2_ptr+16],%o4 ++ addxcc %g2,%o4,%g2 ++ st %g2,[res_ptr+16] ++ addxcc %g3,%o5,%g3 ++ st %g3,[res_ptr+20] ++ ldd [s1_ptr+24],%g2 ++ ldd [s2_ptr+24],%o4 ++ addxcc %g2,%o4,%g2 ++ st %g2,[res_ptr+24] ++ addxcc %g3,%o5,%g3 ++ st %g3,[res_ptr+28] ++ addx %g0,%g0,%o4 ! save cy in register ++ addcc size,-8,size ++ add s1_ptr,32,s1_ptr ++ add s2_ptr,32,s2_ptr ++ add res_ptr,32,res_ptr ++ bge Loop2 ++ subcc %g0,%o4,%g0 ! restore cy ++ ++Lfin2: addcc size,8-2,size ++ blt Lend2 ++ subcc %g0,%o4,%g0 ! restore cy ++Loope2: ldd [s1_ptr+0],%g2 ++ ldd [s2_ptr+0],%o4 ++ addxcc %g2,%o4,%g2 ++ st %g2,[res_ptr+0] ++ addxcc %g3,%o5,%g3 ++ st %g3,[res_ptr+4] ++ addx %g0,%g0,%o4 ! save cy in register ++ addcc size,-2,size ++ add s1_ptr,8,s1_ptr ++ add s2_ptr,8,s2_ptr ++ add res_ptr,8,res_ptr ++ bge Loope2 ++ subcc %g0,%o4,%g0 ! restore cy ++Lend2: andcc size,1,%g0 ++ be Lret2 ++ subcc %g0,%o4,%g0 ! restore cy ++/* Add last limb */ ++Ljone: ld [s1_ptr],%g4 ++ ld [s2_ptr],%g2 ++ addxcc %g4,%g2,%o4 ++ st %o4,[res_ptr] ++ ++Lret2: retl ++ addx %g0,%g0,%o0 ! return carry-out from most sign. limb ++ ++ ++ +diff --git a/grub-core/lib/libgcrypt/mpi/sparc32/mpih-lshift.S b/grub-core/lib/libgcrypt/mpi/sparc32/mpih-lshift.S +new file mode 100644 +index 0000000..3422ab0 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/sparc32/mpih-lshift.S +@@ -0,0 +1,97 @@ ++/* sparc lshift ++ * ++ * Copyright (C) 1995, 1996, 1998, ++ * 2001, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ */ ++ ++ ++! INPUT PARAMETERS ++! res_ptr %o0 ++! src_ptr %o1 ++! size %o2 ++! cnt %o3 ++ ++#include "sysdep.h" ++ ++ .text ++ .align 4 ++ .global C_SYMBOL_NAME(_gcry_mpih_lshift) ++C_SYMBOL_NAME(_gcry_mpih_lshift): ++ sll %o2,2,%g1 ++ add %o1,%g1,%o1 ! make %o1 point at end of src ++ ld [%o1-4],%g2 ! load first limb ++ sub %g0,%o3,%o5 ! negate shift count ++ add %o0,%g1,%o0 ! make %o0 point at end of res ++ add %o2,-1,%o2 ++ andcc %o2,4-1,%g4 ! number of limbs in first loop ++ srl %g2,%o5,%g1 ! compute function result ++ be L0 ! if multiple of 4 limbs, skip first loop ++ st %g1,[%sp+80] ++ ++ sub %o2,%g4,%o2 ! adjust count for main loop ++ ++Loop0: ld [%o1-8],%g3 ++ add %o0,-4,%o0 ++ add %o1,-4,%o1 ++ addcc %g4,-1,%g4 ++ sll %g2,%o3,%o4 ++ srl %g3,%o5,%g1 ++ mov %g3,%g2 ++ or %o4,%g1,%o4 ++ bne Loop0 ++ st %o4,[%o0+0] ++ ++L0: tst %o2 ++ be Lend ++ nop ++ ++Loop: ld [%o1-8],%g3 ++ add %o0,-16,%o0 ++ addcc %o2,-4,%o2 ++ sll %g2,%o3,%o4 ++ srl %g3,%o5,%g1 ++ ++ ld [%o1-12],%g2 ++ sll %g3,%o3,%g4 ++ or %o4,%g1,%o4 ++ st %o4,[%o0+12] ++ srl %g2,%o5,%g1 ++ ++ ld [%o1-16],%g3 ++ sll %g2,%o3,%o4 ++ or %g4,%g1,%g4 ++ st %g4,[%o0+8] ++ srl %g3,%o5,%g1 ++ ++ ld [%o1-20],%g2 ++ sll %g3,%o3,%g4 ++ or %o4,%g1,%o4 ++ st %o4,[%o0+4] ++ srl %g2,%o5,%g1 ++ ++ add %o1,-16,%o1 ++ or %g4,%g1,%g4 ++ bne Loop ++ st %g4,[%o0+0] ++ ++Lend: sll %g2,%o3,%g2 ++ st %g2,[%o0-4] ++ retl ++ ld [%sp+80],%o0 ++ +diff --git a/grub-core/lib/libgcrypt/mpi/sparc32/mpih-rshift.S b/grub-core/lib/libgcrypt/mpi/sparc32/mpih-rshift.S +new file mode 100644 +index 0000000..cd3db41 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/sparc32/mpih-rshift.S +@@ -0,0 +1,93 @@ ++/* sparc rshift ++ * ++ * Copyright (C) 1995, 1996, 1998, ++ * 2001, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ */ ++ ++! INPUT PARAMETERS ++! res_ptr %o0 ++! src_ptr %o1 ++! size %o2 ++! cnt %o3 ++ ++#include "sysdep.h" ++ ++ .text ++ .align 4 ++ .global C_SYMBOL_NAME(_gcry_mpih_rshift) ++C_SYMBOL_NAME(_gcry_mpih_rshift): ++ ld [%o1],%g2 ! load first limb ++ sub %g0,%o3,%o5 ! negate shift count ++ add %o2,-1,%o2 ++ andcc %o2,4-1,%g4 ! number of limbs in first loop ++ sll %g2,%o5,%g1 ! compute function result ++ be L0 ! if multiple of 4 limbs, skip first loop ++ st %g1,[%sp+80] ++ ++ sub %o2,%g4,%o2 ! adjust count for main loop ++ ++Loop0: ld [%o1+4],%g3 ++ add %o0,4,%o0 ++ add %o1,4,%o1 ++ addcc %g4,-1,%g4 ++ srl %g2,%o3,%o4 ++ sll %g3,%o5,%g1 ++ mov %g3,%g2 ++ or %o4,%g1,%o4 ++ bne Loop0 ++ st %o4,[%o0-4] ++ ++L0: tst %o2 ++ be Lend ++ nop ++ ++Loop: ld [%o1+4],%g3 ++ add %o0,16,%o0 ++ addcc %o2,-4,%o2 ++ srl %g2,%o3,%o4 ++ sll %g3,%o5,%g1 ++ ++ ld [%o1+8],%g2 ++ srl %g3,%o3,%g4 ++ or %o4,%g1,%o4 ++ st %o4,[%o0-16] ++ sll %g2,%o5,%g1 ++ ++ ld [%o1+12],%g3 ++ srl %g2,%o3,%o4 ++ or %g4,%g1,%g4 ++ st %g4,[%o0-12] ++ sll %g3,%o5,%g1 ++ ++ ld [%o1+16],%g2 ++ srl %g3,%o3,%g4 ++ or %o4,%g1,%o4 ++ st %o4,[%o0-8] ++ sll %g2,%o5,%g1 ++ ++ add %o1,16,%o1 ++ or %g4,%g1,%g4 ++ bne Loop ++ st %g4,[%o0-4] ++ ++Lend: srl %g2,%o3,%g2 ++ st %g2,[%o0-0] ++ retl ++ ld [%sp+80],%o0 ++ +diff --git a/grub-core/lib/libgcrypt/mpi/sparc32/udiv.S b/grub-core/lib/libgcrypt/mpi/sparc32/udiv.S +new file mode 100644 +index 0000000..006b5c1 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/sparc32/udiv.S +@@ -0,0 +1,195 @@ ++/* SPARC v7 __udiv_qrnnd division support, used from longlong.h. ++ * This is for v7 CPUs without a floating-point unit. ++ * ++ * Copyright (C) 1993, 1994, 1996, 1998, ++ * 2001, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ * ++ * Note: This code is heavily based on the GNU MP Library. ++ * Actually it's the same code with only minor changes in the ++ * way the data is stored; this is to support the abstraction ++ * of an optional secure memory allocation which may be used ++ * to avoid revealing of sensitive data due to paging etc. ++ */ ++ ++ ++! INPUT PARAMETERS ++! rem_ptr o0 ++! n1 o1 ++! n0 o2 ++! d o3 ++ ++#include "sysdep.h" ++ ++ .text ++ .align 4 ++ .global C_SYMBOL_NAME(__udiv_qrnnd) ++C_SYMBOL_NAME(__udiv_qrnnd): ++ tst %o3 ++ bneg Largedivisor ++ mov 8,%g1 ++ ++ b Lp1 ++ addxcc %o2,%o2,%o2 ++ ++Lplop: bcc Ln1 ++ addxcc %o2,%o2,%o2 ++Lp1: addx %o1,%o1,%o1 ++ subcc %o1,%o3,%o4 ++ bcc Ln2 ++ addxcc %o2,%o2,%o2 ++Lp2: addx %o1,%o1,%o1 ++ subcc %o1,%o3,%o4 ++ bcc Ln3 ++ addxcc %o2,%o2,%o2 ++Lp3: addx %o1,%o1,%o1 ++ subcc %o1,%o3,%o4 ++ bcc Ln4 ++ addxcc %o2,%o2,%o2 ++Lp4: addx %o1,%o1,%o1 ++ addcc %g1,-1,%g1 ++ bne Lplop ++ subcc %o1,%o3,%o4 ++ bcc Ln5 ++ addxcc %o2,%o2,%o2 ++Lp5: st %o1,[%o0] ++ retl ++ xnor %g0,%o2,%o0 ++ ++Lnlop: bcc Lp1 ++ addxcc %o2,%o2,%o2 ++Ln1: addx %o4,%o4,%o4 ++ subcc %o4,%o3,%o1 ++ bcc Lp2 ++ addxcc %o2,%o2,%o2 ++Ln2: addx %o4,%o4,%o4 ++ subcc %o4,%o3,%o1 ++ bcc Lp3 ++ addxcc %o2,%o2,%o2 ++Ln3: addx %o4,%o4,%o4 ++ subcc %o4,%o3,%o1 ++ bcc Lp4 ++ addxcc %o2,%o2,%o2 ++Ln4: addx %o4,%o4,%o4 ++ addcc %g1,-1,%g1 ++ bne Lnlop ++ subcc %o4,%o3,%o1 ++ bcc Lp5 ++ addxcc %o2,%o2,%o2 ++Ln5: st %o4,[%o0] ++ retl ++ xnor %g0,%o2,%o0 ++ ++Largedivisor: ++ and %o2,1,%o5 ! %o5 = n0 & 1 ++ ++ srl %o2,1,%o2 ++ sll %o1,31,%g2 ++ or %g2,%o2,%o2 ! %o2 = lo(n1n0 >> 1) ++ srl %o1,1,%o1 ! %o1 = hi(n1n0 >> 1) ++ ++ and %o3,1,%g2 ++ srl %o3,1,%g3 ! %g3 = floor(d / 2) ++ add %g3,%g2,%g3 ! %g3 = ceil(d / 2) ++ ++ b LLp1 ++ addxcc %o2,%o2,%o2 ++ ++LLplop: bcc LLn1 ++ addxcc %o2,%o2,%o2 ++LLp1: addx %o1,%o1,%o1 ++ subcc %o1,%g3,%o4 ++ bcc LLn2 ++ addxcc %o2,%o2,%o2 ++LLp2: addx %o1,%o1,%o1 ++ subcc %o1,%g3,%o4 ++ bcc LLn3 ++ addxcc %o2,%o2,%o2 ++LLp3: addx %o1,%o1,%o1 ++ subcc %o1,%g3,%o4 ++ bcc LLn4 ++ addxcc %o2,%o2,%o2 ++LLp4: addx %o1,%o1,%o1 ++ addcc %g1,-1,%g1 ++ bne LLplop ++ subcc %o1,%g3,%o4 ++ bcc LLn5 ++ addxcc %o2,%o2,%o2 ++LLp5: add %o1,%o1,%o1 ! << 1 ++ tst %g2 ++ bne Oddp ++ add %o5,%o1,%o1 ++ st %o1,[%o0] ++ retl ++ xnor %g0,%o2,%o0 ++ ++LLnlop: bcc LLp1 ++ addxcc %o2,%o2,%o2 ++LLn1: addx %o4,%o4,%o4 ++ subcc %o4,%g3,%o1 ++ bcc LLp2 ++ addxcc %o2,%o2,%o2 ++LLn2: addx %o4,%o4,%o4 ++ subcc %o4,%g3,%o1 ++ bcc LLp3 ++ addxcc %o2,%o2,%o2 ++LLn3: addx %o4,%o4,%o4 ++ subcc %o4,%g3,%o1 ++ bcc LLp4 ++ addxcc %o2,%o2,%o2 ++LLn4: addx %o4,%o4,%o4 ++ addcc %g1,-1,%g1 ++ bne LLnlop ++ subcc %o4,%g3,%o1 ++ bcc LLp5 ++ addxcc %o2,%o2,%o2 ++LLn5: add %o4,%o4,%o4 ! << 1 ++ tst %g2 ++ bne Oddn ++ add %o5,%o4,%o4 ++ st %o4,[%o0] ++ retl ++ xnor %g0,%o2,%o0 ++ ++Oddp: xnor %g0,%o2,%o2 ++ ! q' in %o2. r' in %o1 ++ addcc %o1,%o2,%o1 ++ bcc LLp6 ++ addx %o2,0,%o2 ++ sub %o1,%o3,%o1 ++LLp6: subcc %o1,%o3,%g0 ++ bcs LLp7 ++ subx %o2,-1,%o2 ++ sub %o1,%o3,%o1 ++LLp7: st %o1,[%o0] ++ retl ++ mov %o2,%o0 ++ ++Oddn: xnor %g0,%o2,%o2 ++ ! q' in %o2. r' in %o4 ++ addcc %o4,%o2,%o4 ++ bcc LLn6 ++ addx %o2,0,%o2 ++ sub %o4,%o3,%o4 ++LLn6: subcc %o4,%o3,%g0 ++ bcs LLn7 ++ subx %o2,-1,%o2 ++ sub %o4,%o3,%o4 ++LLn7: st %o4,[%o0] ++ retl ++ mov %o2,%o0 +diff --git a/grub-core/lib/libgcrypt/mpi/sparc32v8/Manifest b/grub-core/lib/libgcrypt/mpi/sparc32v8/Manifest +new file mode 100644 +index 0000000..dc1ce6a +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/sparc32v8/Manifest +@@ -0,0 +1,23 @@ ++# Manifest - checksums ++# Copyright 2003 Free Software Foundation, Inc. ++# ++# This file is part of Libgcrypt. ++# ++# Libgcrypt is free software; you can redistribute it and/or modify ++# it under the terms of the GNU Lesser General Public License as ++# published by the Free Software Foundation; either version 2.1 of ++# the License, or (at your option) any later version. ++# ++# Libgcrypt 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 Lesser General Public License for more details. ++# ++# You should have received a copy of the GNU Lesser General Public ++# License along with this program; if not, write to the Free Software ++# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ ++mpih-mul1.S ++mpih-mul2.S ++mpih-mul3.S ++$names$ iQCVAwUAP+LmbjEAnp832S/7AQKQ2gQAotpCpY9rOJUCdZHbDLXXB9i1UUMraRKbVWimtKq493Y2d2wcqXCK2WaGs1AePK3K6Qk6msxZ0PL5Ho7KgHMkzsZ+wG0EUziiuX0yZRTWNm0r3TYerP6SdWH5GOVdSXn7ckkppk2sVOokfQTy+Tmrnah3+dlYJoujan+fmXWN6Us==DolM +diff --git a/grub-core/lib/libgcrypt/mpi/sparc32v8/distfiles b/grub-core/lib/libgcrypt/mpi/sparc32v8/distfiles +new file mode 100644 +index 0000000..6e9a530 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/sparc32v8/distfiles +@@ -0,0 +1,5 @@ ++Manifest ++mpih-mul1.S ++mpih-mul2.S ++mpih-mul3.S ++ +diff --git a/grub-core/lib/libgcrypt/mpi/sparc32v8/mpih-mul1.S b/grub-core/lib/libgcrypt/mpi/sparc32v8/mpih-mul1.S +new file mode 100644 +index 0000000..03fcdda +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/sparc32v8/mpih-mul1.S +@@ -0,0 +1,109 @@ ++/* SPARC v8 __mpn_mul_1 -- Multiply a limb vector with a single limb and ++ * store the product in a second limb vector. ++ * ++ * Copyright (C) 1992, 1994, 1995, 1998, ++ * 2001, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ * ++ * Note: This code is heavily based on the GNU MP Library. ++ * Actually it's the same code with only minor changes in the ++ * way the data is stored; this is to support the abstraction ++ * of an optional secure memory allocation which may be used ++ * to avoid revealing of sensitive data due to paging etc. ++ */ ++ ++ ++ ++! INPUT PARAMETERS ++! res_ptr o0 ++! s1_ptr o1 ++! size o2 ++! s2_limb o3 ++ ++#include "sysdep.h" ++ ++.text ++ .align 8 ++ .global C_SYMBOL_NAME(_gcry_mpih_mul_1) ++C_SYMBOL_NAME(_gcry_mpih_mul_1): ++ sll %o2,4,%g1 ++ and %g1,(4-1)<<4,%g1 ++#if PIC ++ mov %o7,%g4 ! Save return address register ++ call 1f ++ add %o7,LL-1f,%g3 ++1: mov %g4,%o7 ! Restore return address register ++#else ++ sethi %hi(LL),%g3 ++ or %g3,%lo(LL),%g3 ++#endif ++ jmp %g3+%g1 ++ ld [%o1+0],%o4 ! 1 ++LL: ++LL00: add %o0,-4,%o0 ++ add %o1,-4,%o1 ++ b Loop00 /* 4, 8, 12, ... */ ++ orcc %g0,%g0,%g2 ++LL01: b Loop01 /* 1, 5, 9, ... */ ++ orcc %g0,%g0,%g2 ++ nop ++ nop ++LL10: add %o0,-12,%o0 /* 2, 6, 10, ... */ ++ add %o1,4,%o1 ++ b Loop10 ++ orcc %g0,%g0,%g2 ++ nop ++LL11: add %o0,-8,%o0 /* 3, 7, 11, ... */ ++ add %o1,-8,%o1 ++ b Loop11 ++ orcc %g0,%g0,%g2 ++ ++Loop: addcc %g3,%g2,%g3 ! 1 ++ ld [%o1+4],%o4 ! 2 ++ st %g3,[%o0+0] ! 1 ++ rd %y,%g2 ! 1 ++Loop00: umul %o4,%o3,%g3 ! 2 ++ addxcc %g3,%g2,%g3 ! 2 ++ ld [%o1+8],%o4 ! 3 ++ st %g3,[%o0+4] ! 2 ++ rd %y,%g2 ! 2 ++Loop11: umul %o4,%o3,%g3 ! 3 ++ addxcc %g3,%g2,%g3 ! 3 ++ ld [%o1+12],%o4 ! 4 ++ add %o1,16,%o1 ++ st %g3,[%o0+8] ! 3 ++ rd %y,%g2 ! 3 ++Loop10: umul %o4,%o3,%g3 ! 4 ++ addxcc %g3,%g2,%g3 ! 4 ++ ld [%o1+0],%o4 ! 1 ++ st %g3,[%o0+12] ! 4 ++ add %o0,16,%o0 ++ rd %y,%g2 ! 4 ++ addx %g0,%g2,%g2 ++Loop01: addcc %o2,-4,%o2 ++ bg Loop ++ umul %o4,%o3,%g3 ! 1 ++ ++ addcc %g3,%g2,%g3 ! 4 ++ st %g3,[%o0+0] ! 4 ++ rd %y,%g2 ! 4 ++ ++ retl ++ addx %g0,%g2,%o0 ++ ++ +diff --git a/grub-core/lib/libgcrypt/mpi/sparc32v8/mpih-mul2.S b/grub-core/lib/libgcrypt/mpi/sparc32v8/mpih-mul2.S +new file mode 100644 +index 0000000..6f5cc43 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/sparc32v8/mpih-mul2.S +@@ -0,0 +1,132 @@ ++/* SPARC v8 __mpn_addmul_1 -- Multiply a limb vector with a limb and ++ * add the result to a second limb vector. ++ * ++ * Copyright (C) 1992, 1993, 1994, 1995, 1998, ++ * 2001, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ * ++ * Note: This code is heavily based on the GNU MP Library. ++ * Actually it's the same code with only minor changes in the ++ * way the data is stored; this is to support the abstraction ++ * of an optional secure memory allocation which may be used ++ * to avoid revealing of sensitive data due to paging etc. ++ */ ++ ++ ++ ++! INPUT PARAMETERS ++! res_ptr o0 ++! s1_ptr o1 ++! size o2 ++! s2_limb o3 ++ ++#include "sysdep.h" ++ ++.text ++ .align 4 ++ .global C_SYMBOL_NAME(_gcry_mpih_addmul_1) ++C_SYMBOL_NAME(_gcry_mpih_addmul_1): ++ orcc %g0,%g0,%g2 ++ ld [%o1+0],%o4 ! 1 ++ ++ sll %o2,4,%g1 ++ and %g1,(4-1)<<4,%g1 ++#if PIC ++ mov %o7,%g4 ! Save return address register ++ call 1f ++ add %o7,LL-1f,%g3 ++1: mov %g4,%o7 ! Restore return address register ++#else ++ sethi %hi(LL),%g3 ++ or %g3,%lo(LL),%g3 ++#endif ++ jmp %g3+%g1 ++ nop ++LL: ++LL00: add %o0,-4,%o0 ++ b Loop00 /* 4, 8, 12, ... */ ++ add %o1,-4,%o1 ++ nop ++LL01: b Loop01 /* 1, 5, 9, ... */ ++ nop ++ nop ++ nop ++LL10: add %o0,-12,%o0 /* 2, 6, 10, ... */ ++ b Loop10 ++ add %o1,4,%o1 ++ nop ++LL11: add %o0,-8,%o0 /* 3, 7, 11, ... */ ++ b Loop11 ++ add %o1,-8,%o1 ++ nop ++ ++1: addcc %g3,%g2,%g3 ! 1 ++ ld [%o1+4],%o4 ! 2 ++ rd %y,%g2 ! 1 ++ addx %g0,%g2,%g2 ++ ld [%o0+0],%g1 ! 2 ++ addcc %g1,%g3,%g3 ++ st %g3,[%o0+0] ! 1 ++Loop00: umul %o4,%o3,%g3 ! 2 ++ ld [%o0+4],%g1 ! 2 ++ addxcc %g3,%g2,%g3 ! 2 ++ ld [%o1+8],%o4 ! 3 ++ rd %y,%g2 ! 2 ++ addx %g0,%g2,%g2 ++ nop ++ addcc %g1,%g3,%g3 ++ st %g3,[%o0+4] ! 2 ++Loop11: umul %o4,%o3,%g3 ! 3 ++ addxcc %g3,%g2,%g3 ! 3 ++ ld [%o1+12],%o4 ! 4 ++ rd %y,%g2 ! 3 ++ add %o1,16,%o1 ++ addx %g0,%g2,%g2 ++ ld [%o0+8],%g1 ! 2 ++ addcc %g1,%g3,%g3 ++ st %g3,[%o0+8] ! 3 ++Loop10: umul %o4,%o3,%g3 ! 4 ++ addxcc %g3,%g2,%g3 ! 4 ++ ld [%o1+0],%o4 ! 1 ++ rd %y,%g2 ! 4 ++ addx %g0,%g2,%g2 ++ ld [%o0+12],%g1 ! 2 ++ addcc %g1,%g3,%g3 ++ st %g3,[%o0+12] ! 4 ++ add %o0,16,%o0 ++ addx %g0,%g2,%g2 ++Loop01: addcc %o2,-4,%o2 ++ bg 1b ++ umul %o4,%o3,%g3 ! 1 ++ ++ addcc %g3,%g2,%g3 ! 4 ++ rd %y,%g2 ! 4 ++ addx %g0,%g2,%g2 ++ ld [%o0+0],%g1 ! 2 ++ addcc %g1,%g3,%g3 ++ st %g3,[%o0+0] ! 4 ++ addx %g0,%g2,%o0 ++ ++ retl ++ nop ++ ++ ++! umul, ld, addxcc, rd, st ++ ++! umul, ld, addxcc, rd, ld, addcc, st, addx ++ +diff --git a/grub-core/lib/libgcrypt/mpi/sparc32v8/mpih-mul3.S b/grub-core/lib/libgcrypt/mpi/sparc32v8/mpih-mul3.S +new file mode 100644 +index 0000000..93bb194 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/sparc32v8/mpih-mul3.S +@@ -0,0 +1,67 @@ ++/* SPARC v8 __mpn_submul_1 -- Multiply a limb vector with a limb and ++ * subtract the result from a second limb vector. ++ * ++ * Copyright (C) 1992, 1993, 1994, 1998, ++ * 2001, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ * ++ * Note: This code is heavily based on the GNU MP Library. ++ * Actually it's the same code with only minor changes in the ++ * way the data is stored; this is to support the abstraction ++ * of an optional secure memory allocation which may be used ++ * to avoid revealing of sensitive data due to paging etc. ++ */ ++ ++ ++! INPUT PARAMETERS ++! res_ptr o0 ++! s1_ptr o1 ++! size o2 ++! s2_limb o3 ++ ++#include "sysdep.h" ++ ++.text ++ .align 4 ++ .global C_SYMBOL_NAME(_gcry_mpih_submul_1) ++C_SYMBOL_NAME(_gcry_mpih_submul_1): ++ sub %g0,%o2,%o2 ! negate ... ++ sll %o2,2,%o2 ! ... and scale size ++ sub %o1,%o2,%o1 ! o1 is offset s1_ptr ++ sub %o0,%o2,%g1 ! g1 is offset res_ptr ++ ++ mov 0,%o0 ! clear cy_limb ++ ++Loop: ld [%o1+%o2],%o4 ++ ld [%g1+%o2],%g2 ++ umul %o4,%o3,%o5 ++ rd %y,%g3 ++ addcc %o5,%o0,%o5 ++ addx %g3,0,%o0 ++ subcc %g2,%o5,%g2 ++ addx %o0,0,%o0 ++ st %g2,[%g1+%o2] ++ ++ addcc %o2,4,%o2 ++ bne Loop ++ nop ++ ++ retl ++ nop ++ ++ +diff --git a/grub-core/lib/libgcrypt/mpi/supersparc/Manifest b/grub-core/lib/libgcrypt/mpi/supersparc/Manifest +new file mode 100644 +index 0000000..869b97b +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/supersparc/Manifest +@@ -0,0 +1,21 @@ ++# Manifest - checksums ++# Copyright 2003 Free Software Foundation, Inc. ++# ++# This file is part of Libgcrypt. ++# ++# Libgcrypt is free software; you can redistribute it and/or modify ++# it under the terms of the GNU Lesser General Public License as ++# published by the Free Software Foundation; either version 2.1 of ++# the License, or (at your option) any later version. ++# ++# Libgcrypt 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 Lesser General Public License for more details. ++# ++# You should have received a copy of the GNU Lesser General Public ++# License along with this program; if not, write to the Free Software ++# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ ++udiv.S ++$names$ iQCVAwUAP+LmdjEAnp832S/7AQIrUgQA3YmurZhK7r20DqRvg0gwNe9jMDcFfUY4ZPhW5HkGzMbmrxXtj5Dx50RIPteum72bXE+IhcngljQb/cskiN5Hi9oc2a2CPhyTqVFEeGyF+kJ170GI1pVfFOfzbVG0F4nEwm5lGHgv/nvFsvrjmmAXVW1v/yk5N35wbiLviOFrLOQ==byFc +diff --git a/grub-core/lib/libgcrypt/mpi/supersparc/distfiles b/grub-core/lib/libgcrypt/mpi/supersparc/distfiles +new file mode 100644 +index 0000000..ef7c0a5 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/supersparc/distfiles +@@ -0,0 +1,3 @@ ++Manifest ++udiv.S ++ +diff --git a/grub-core/lib/libgcrypt/mpi/supersparc/udiv.S b/grub-core/lib/libgcrypt/mpi/supersparc/udiv.S +new file mode 100644 +index 0000000..79e506a +--- /dev/null ++++ b/grub-core/lib/libgcrypt/mpi/supersparc/udiv.S +@@ -0,0 +1,118 @@ ++/* SuperSPARC __udiv_qrnnd division support, used from longlong.h. ++ * This is for SuperSPARC only, to compensate for its ++ * semi-functional udiv instruction. ++ * ++ * Copyright (C) 1993, 1994, 1996, 1998, ++ * 2001, 2002 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ * ++ * Note: This code is heavily based on the GNU MP Library. ++ * Actually it's the same code with only minor changes in the ++ * way the data is stored; this is to support the abstraction ++ * of an optional secure memory allocation which may be used ++ * to avoid revealing of sensitive data due to paging etc. ++ */ ++ ++ ++ ++! INPUT PARAMETERS ++! rem_ptr i0 ++! n1 i1 ++! n0 i2 ++! d i3 ++ ++#include "sysdep.h" ++#undef ret /* Kludge for glibc */ ++ ++ .text ++ .align 8 ++LC0: .double 0r4294967296 ++LC1: .double 0r2147483648 ++ ++ .align 4 ++ .global C_SYMBOL_NAME(__udiv_qrnnd) ++C_SYMBOL_NAME(__udiv_qrnnd): ++ !#PROLOGUE# 0 ++ save %sp,-104,%sp ++ !#PROLOGUE# 1 ++ st %i1,[%fp-8] ++ ld [%fp-8],%f10 ++ sethi %hi(LC0),%o7 ++ fitod %f10,%f4 ++ ldd [%o7+%lo(LC0)],%f8 ++ cmp %i1,0 ++ bge L248 ++ mov %i0,%i5 ++ faddd %f4,%f8,%f4 ++L248: ++ st %i2,[%fp-8] ++ ld [%fp-8],%f10 ++ fmuld %f4,%f8,%f6 ++ cmp %i2,0 ++ bge L249 ++ fitod %f10,%f2 ++ faddd %f2,%f8,%f2 ++L249: ++ st %i3,[%fp-8] ++ faddd %f6,%f2,%f2 ++ ld [%fp-8],%f10 ++ cmp %i3,0 ++ bge L250 ++ fitod %f10,%f4 ++ faddd %f4,%f8,%f4 ++L250: ++ fdivd %f2,%f4,%f2 ++ sethi %hi(LC1),%o7 ++ ldd [%o7+%lo(LC1)],%f4 ++ fcmped %f2,%f4 ++ nop ++ fbge,a L251 ++ fsubd %f2,%f4,%f2 ++ fdtoi %f2,%f2 ++ st %f2,[%fp-8] ++ b L252 ++ ld [%fp-8],%i4 ++L251: ++ fdtoi %f2,%f2 ++ st %f2,[%fp-8] ++ ld [%fp-8],%i4 ++ sethi %hi(-2147483648),%g2 ++ xor %i4,%g2,%i4 ++L252: ++ umul %i3,%i4,%g3 ++ rd %y,%i0 ++ subcc %i2,%g3,%o7 ++ subxcc %i1,%i0,%g0 ++ be L253 ++ cmp %o7,%i3 ++ ++ add %i4,-1,%i0 ++ add %o7,%i3,%o7 ++ st %o7,[%i5] ++ ret ++ restore ++L253: ++ blu L246 ++ mov %i4,%i0 ++ add %i4,1,%i0 ++ sub %o7,%i3,%o7 ++L246: ++ st %o7,[%i5] ++ ret ++ restore ++ +diff --git a/grub-core/lib/libgcrypt/src/ChangeLog-2011 b/grub-core/lib/libgcrypt/src/ChangeLog-2011 +new file mode 100644 +index 0000000..3571fb1 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/src/ChangeLog-2011 +@@ -0,0 +1,2398 @@ ++2011-12-01 Werner Koch ++ ++ NB: ChangeLog files are no longer manually maintained. Starting ++ on December 1st, 2011 we put change information only in the GIT ++ commit log, and generate a top-level ChangeLog file from logs at ++ "make dist". See doc/HACKING for details. ++ ++2011-09-16 Werner Koch ++ ++ Change ATH code and turn the thread initialization callbacks in ++ the API into dummy functions. ++ ++ * global.c (global_init): Call _gcry_pimegen_init. ++ ++ * gcrypt.h.in (GCRY_THREAD_OPTI ON_VERSION): Bump to 1. ++ (GCRY_THREAD_OPTION_PTH_IMPL): Simplify. ++ (GCRY_THREAD_OPTION_PTHREAD_IMPL): Simplify. ++ ++ * ath.c (ath_read, ath_write): Remove. They are only used in the ++ optional random-daemon. ++ (ath_select, ath_waitpid, ath_accept, ath_connect, ath_sendmsg) ++ (ath_recvmsg): Remove. They are not used. ++ * ath.h: Remove prototypes and corresponding structure fields. ++ ++2011-03-11 Werner Koch ++ ++ * ath.c (mutex_init): Rename second arg to FORCE and invert ++ logic. Change all callers. ++ ++2011-09-15 Werner Koch ++ ++ * gcrypt.h.in (enum gcry_thread_option): Remove deprecated enum. ++ (gcry_md_start_debug, gcry_md_stop_debug): Remove deprecated these ++ macros. ++ ++2011-09-15 Werner Koch ++ ++ Removal of the gcry_ac and the module register interfaces. ++ ++ * Makefile.am (include_HEADERS): Remove gcrypt-module.h. ++ (libgcrypt_la_SOURCES): Add gcrypt-module.h which is now internal ++ header. ++ * gcrypt-module.h (gcry_md_register, gcry_md_unregister): Remove. ++ (gcry_pk_register, gcry_pk_unregister): Remove. ++ (gcry_cipher_register, gcry_cipher_unregister): Remove. ++ * visibility.h: Include gcrypt-module.h. ++ * gcrypt.h.in: Do not include gcrypt-module.h. ++ * gcrypt.h.in: Remove all gcry_ac symbols. ++ (gcry_pk_list, gcry_md_list, gcry_cipher_list): Remove. ++ * visibility.h: Remove all gcry_ac symbols. ++ (gcry_pk_list, gcry_md_list, gcry_cipher_list): Remove. ++ (gcry_cipher_register, gcry_cipher_unregister, gcry_pk_register) ++ (gcry_pk_unregister, gcry_md_register, gcry_md_unregister): Remove. ++ * visibility.c: Remove all gcry_ac wrappers. ++ (gcry_pk_list, gcry_cipher_list, gcry_md_list): Remove. ++ (gcry_cipher_register, gcry_cipher_unregister, gcry_pk_register) ++ (gcry_pk_unregister, gcry_md_register, gcry_md_unregister): Remove. ++ * libgcrypt.vers: Remove all gcry_ac symbols. ++ (GCRYPT_1.2): Rename to GCRYPT_1.6. ++ (gcry_pk_list, gcry_md_list, gcry_cipher_list): Remove. ++ * libgcrypt.def: Remove all gcry_ac symbols. ++ (gcry_pk_list, gcry_md_list, gcry_cipher_list): Remove. ++ * global.c (global_init): Remove comment code with a call to ++ _gcry_ac_init. ++ ++2011-09-15 Werner Koch ++ ++ * hmac256.c (main): Fix endless loop when using pipe input and ++ option --binary. ++ ++2011-06-10 Werner Koch ++ ++ * sexp.c (vsexp_sscan): Add new format specifiers 'M' and 'u'. ++ ++2011-05-24 Daiki Ueno ++ ++ * cipher.h (pk_operation): New. ++ (pk_encoding_ctx): Add new fields: op, nbits, flags, verify_cmp, ++ and verify_arg. ++ ++2011-05-19 Daiki Ueno ++ ++ * Makefile.am (gcryptrnd_LDADD): Supply $(GPG_ERROR_LIBS) for ++ gpg_strerror. ++ ++2011-05-18 Daiki Ueno ++ ++ * cipher.h: Remove PUBKEY_FLAG_UNPAD. ++ ++2011-05-11 Daiki Ueno ++ ++ * cipher.h (PUBKEY_FLAG_UNPAD): New. ++ (enum pk_encoding): New. ++ (struct pk_encoding_ctx): New. ++ ++2011-04-19 Werner Koch ++ ++ * stdmem.c (_gcry_private_malloc_secure, _gcry_private_malloc): ++ Set ERRNO on failure. ++ * secmem.c (mb_get_new): Set ERRNO on failure. ++ (_gcry_secmem_malloc_internal): Ditto. ++ ++2011-04-01 Werner Koch ++ ++ * global.c (gcry_realloc): Divert to gcry_malloc or gcry_free. ++ ++2011-03-09 Werner Koch ++ ++ * gcrypt.h.in (gcry_kdf_algos): New. ++ (gcry_kdf_derive): New. ++ * visibility.c (gcry_kdf_derive): New. ++ * visibility.h, libgcrypt.vers, libgcrypt.def: Add gcry_kdf_derive. ++ ++2011-02-23 Werner Koch ++ ++ * libgcrypt-config.in: Add option --host. ++ * libgcrypt.m4: Use AC_PROG_TOOL to find the config script. Print ++ a warning is the config scripts does not match the configure host. ++ ++2011-02-21 Werner Koch ++ ++ * global.c (gcry_check_version): Do not take the patchlevel in ++ account; it is not well defined. ++ ++2011-02-17 Werner Koch ++ ++ * gcrypt-module.h (gcry_cipher_register, gcry_cipher_unregister) ++ (gcry_pk_register, gcry_pk_unregister, gcry_md_register) ++ (gcry_md_unregister): Mark as deprecated by the API; in a future ++ version the module register feature will be removed. ++ ++ * gcrypt.h.in: Attribute all _ac_ functions and types as ++ deprecated by the API. ++ ++ * hwfeatures.c (detect_ia32_gnuc): Fix AES-NI detection. Use AND ++ instead of SUB for bit testing. ++ ++2011-02-16 Werner Koch ++ ++ * gcrypt.h.in (GCRYCTL_DISABLE_HWF): New. ++ * global.c (_gcry_vcontrol): Support new control code. ++ (print_config): Factor list of hwfeatures out to ... ++ (hwflist): new. ++ (disabled_hw_features): New. ++ (global_init): Pass new variable to _gcry_detect_hw_features. ++ * hwfeatures.c (_gcry_detect_hw_features): Add arg ++ DISABLED_FEATURES and disable detected features. ++ ++2011-02-11 Werner Koch ++ ++ * g10lib.h (HWF_INTEL_AES): Rename to HWF_INTEL_AESNI. ++ * hwfeatures.c (detect_ia32_gnuc): Fix setting of this flag. ++ ++2011-02-01 Werner Koch ++ ++ * gcrypt.h.in (gcry_pk_get_curve, gcry_pk_get_param): New. ++ * libgcrypt.vers (gcry_pk_get_curve, gcry_pk_get_param): Add. ++ * libgcrypt.def (gcry_pk_get_curve, gcry_pk_get_param): Add. ++ * visibility.c (gcry_pk_get_curve, gcry_pk_get_param): New. ++ * cipher-proto.h (pk_extra_spec): Add fields GET_CURVE and ++ GET_CURVE_PARM. ++ ++2011-01-31 Werner Koch ++ ++ * sexp.c (vsexp_sscan): Allow opaque MPIs in "%m". ++ ++2010-08-27 Werner Koch ++ ++ * g10lib.h (HWF_INTEL_AES): New. ++ * global.c (print_config): Print new flag. ++ * hwfeatures.c (detect_ia32_gnuc): Detect this flag. ++ ++2010-08-16 Werner Koch ++ ++ * gcrypt.h.in [!WIN32]: Add INSERT_SYS_SELECT_H autoconf substitute. ++ ++2010-07-09 Werner Koch ++ ++ * gcrypt.h.in [!__GNUC__ && W32]: Typedef ssize_t and pid_t to ++ help building with MSVC. ++ ++2010-06-24 Werner Koch ++ ++ * gcrypt.h.in [W32]: Include time.h and not sys/time.h. ++ ++2010-04-19 Marcus Brinkmann ++ ++ * misc.c (write2stderr): Dummy variable to silence gcc warning. ++ ++2010-04-16 Marcus Brinkmann ++ ++ * sexp.c: (sexp_sscan): Make it variable length, and rename the ++ old version to ... ++ (vsexp_sscan): ... this new function. Also swap last two arguments. ++ (gcry_sexp_create): Remove dummy va_list. ++ (gcry_sexp_build): Use vsexp_sscan instead of sexp_sscan. ++ (_gcry_sexp_vbuild): Likewise. ++ (gcry_sexp_build_array): Remove dummy va_list. ++ (gcry_sexp_sscan): Likewise. ++ ++2010-04-12 Brad Hards (wk) ++ ++ Spelling fixes. ++ ++2010-03-15 Werner Koch ++ ++ * gcrypt.h.in: Add autoconf template to set generated file to ++ read-only in an Emacs buffer. ++ ++2010-01-21 Werner Koch ++ ++ * Makefile.am (arch_gpg_error_cflags, arch_gpg_error_libs): New. ++ (dumpsexp_CFLAGS): New. ++ (dumpsexp_LDADD): Add arch_gpg_error_libs. ++ (hmac256_CFLAGS, hmac256_LDADD): Add the arch variables. ++ (libgcrypt_la_DEPENDENCIES): Add libcompat. ++ * secmem.c (lock_pool): Mark unused args. ++ * global.c (do_malloc, gcry_realloc, gcry_free, gcry_calloc) ++ (gcry_calloc_secure, gcry_xcalloc, gcry_xcalloc_secure): Use ++ gpg_err_set_errno. ++ (_gcry_vcontrol): Call _gcry_compat_identification. ++ * hmac256.c [__MINGW32CE__]: Include gpg-error.h. ++ (_gcry_hmac256_file): Use gpg_err_set_errno. ++ (gpg_err_set_errno) [!GPG_ERR_INLINE]: Add macro. ++ * g10lib.h: Include libcompat.h. ++ ++2010-01-05 Werner Koch ++ ++ * gcrypt.h.in (GCRY_PK_ECDH): New. ++ ++2009-12-08 Werner Koch ++ ++ * gcrypt.h.in (GCRY_CIPHER_MODE_AESWRAP): New. ++ ++2009-12-08 Marcus Brinkmann ++ ++ * Makefile.am (LTRCCOMPILE): Refactor with ... ++ (RCCOMPILE): ... this new macro. Add $(libgcrypt_la_CPPFLAGS). ++ (SUFFIXES): Add .lo. ++ (.rc.o): Change to ... ++ (.rc.lo): ... this implicit rule. ++ (gcrypt_res_ldflag): Removed. ++ (gcrypt_res): Use libtool object file name here. ++ (libgcrypt_la_LDFLAGS): Remove gcrypt_res_ldflag usage. ++ (libgcrypt_la_LIBADD): Add gcrypt_res. ++ ++2009-11-29 Werner Koch ++ ++ * hwfeatures.c (detect_ia32_gnuc): Repalce "=r" by "+r" so that ++ HAS-CPUDID is always initialized. Thanks to Ben Hutchings for ++ pointing out this problem. ++ ++2009-08-05 Werner Koch ++ ++ * ath.h: Include sys/msg.h. ++ ++2009-07-02 Werner Koch ++ ++ * fips.c (_gcry_initialize_fips_mode): Do not use FIPS mode if ++ /proc/.../fips_enabled has insufficient permissions. ++ ++ * dumpsexp.c (main): Fix handling multiple files. ++ (parse_and_print): Implement hex and octal escaping. ++ ++ * sexp.c (unquote_string): Remove superfluous clearing of ESC. ++ * dumpsexp.c (parse_and_print): Add missing break. ++ (main): Fix return value. ++ Reported by Fabian Keil. ++ ++2009-02-16 Werner Koch ++ ++ * ath.h [HAVE_SYS_SELECT_H]: Include for fd_set. ++ [!HAVE_SYS_SELECT_H]: Include . Move inclusion of ++ config.h to the top. The actual configure check was already ++ there. ++ ++ * sexp.c: Remove memory.h. ++ * mpi.h: Remove memory.h. Add string.h. ++ ++2009-02-02 Werner Koch ++ ++ * ath.h: Include sys/time.h. Fixes bug#993. ++ ++2009-01-22 Werner Koch ++ ++ * fips.c (_gcry_initialize_fips_mode): Remove superfluous const ++ from static string. Reported by Albert Chin. ++ * hmac256.c (selftest): Ditto and change to unsigned char. ++ ++2008-12-10 Werner Koch ++ ++ * hmac256.c (finalize): Fix for big endian hosts. ++ ++2008-12-05 Werner Koch ++ ++ * global.c (gcry_free): Save and restore ERRNO if set. ++ ++2008-11-24 Werner Koch ++ ++ * sexp.c (get_internal_buffer): New. ++ (sexp_sscan): Add format character S. ++ * cipher-proto.h (pk_ext_generate_t): Add field EXTRAINFO changed ++ all implementors. ++ ++ * cipher-proto.h (pk_ext_generate_t): Simplify. ++ (pk_get_param): New. ++ (pk_extra_spec_t): Add field GET_PARAM. ++ * cipher.h (PUBKEY_FLAG_TRANSIENT_KEY): Remove. ++ (_gcry_pubkey_extraspec_elg): New. ++ ++2008-11-05 Werner Koch ++ ++ * cipher.h (CIPHER_INFO_NO_WEAK_KEY): New. ++ ++ * cipher-proto.h (cipher_set_extra_info_t): New. ++ (cipher_extra_spec): Add field SET_EXTRA_INFO. ++ ++2008-10-30 Werner Koch ++ ++ * g10lib.h (GCC_ATTR_FORMAT_ARG): New. ++ (_gcry_gettext): Use it. ++ ++2008-10-24 Werner Koch ++ ++ * global.c (inactive_fips_mode): Move to fips.c. ++ (gcry_set_allocation_handler): Factor code out to ... ++ * fips.c (_gcry_inactivate_fips_mode): New. ++ (_gcry_is_fips_mode_inactive): New. ++ ++2008-09-29 Werner Koch ++ ++ * gcrypt-module.h (GCRY_MODULE_ID_USER, GCRY_MODULE_ID_USER_LAST): ++ New. ++ * module.c (MODULE_ID_USER, MODULE_ID_USER_LAST): Define using new ++ macros. ++ ++2008-09-20 Werner Koch ++ ++ * hmac256.c (finalize) [WORDS_BIGENDIAN]: Fix sigbus problem. ++ ++2008-09-18 Werner Koch ++ ++ * cipher-proto.h (pk_ext_generate_t): Add args QBITS, NAME, DOMAIN. ++ ++ * fips.c (fips_new_state): Allow Error => Error transition. ++ ++2008-09-18 Werner Koch ++ ++ * gcrypt.h.in (gcry_fips_mode_active): New. ++ ++ * secmem.c (_gcry_secmem_init): Factor most code out to .. ++ (secmem_init): .. new. ++ (DEFAULT_POOL_SIZE): Rename to MINIMUM_POOL_SIZE. ++ (STANDARD_POOL_SIZE): New. ++ (_gcry_secmem_malloc_internal): Don't abort if the pool is not ++ initialized but try to out intialize it first and only then print ++ an error message and return NULL. If the pool is not locked while ++ in FIPS mode, return NULL. ++ ++ * fips.c (FIPS_FORCE_FILE): New constant. Change the file name to ++ "/etc/gcrypt/fips_enabled". ++ (enforced_fips_mode): New. ++ (_gcry_initialize_fips_mode): Set that flag. ++ (_gcry_enforced_fips_mode): New. ++ * global.c (inactive_fips_mode): New. ++ (_gcry_vcontrol): Take that flag in account for GCRYCTL_FIPS_MODE_P. ++ (gcry_set_allocation_handler): Take care of the enforced fips mdoe ++ flag. ++ (get_no_secure_memory): New. ++ (do_malloc, gcry_is_secure): Use it. ++ ++2008-09-16 Werner Koch ++ ++ * global.c (print_config): Use y/n for fips mode. ++ ++ * fips.c (fips_new_state): Allow transition to Error and ++ Fatal-error from Init. ++ ++2008-09-15 Werner Koch ++ ++ * fips.c [HAVE_SYSLOG]: Include syslog.h. ++ (_gcry_initialize_fips_mode, lock_fsm, unlock_fsm) ++ (_gcry_fips_signal_error, fips_new_state) ++ (_gcry_fips_noreturn) [HAVE_SYSLOG]: Also log via syslog. ++ (check_binary_integrity) [HAVE_SYSLOG]: Log failure. ++ * global.h [HAVE_SYSLOG]: Include syslog.h. ++ (_gcry_global_is_operational) [HAVE_SYSLOG]: Print warning. ++ ++ * global.c (_gcry_vcontrol): Use GCRYCTL_INITIALIZATION_FINISHED ++ to run power-up tests. Add unpublished control commands 58-60. ++ ++ * global.c (_gcry_global_is_operational): New. ++ * g10lib.h (fips_is_operational): Change to call this function. ++ ++2008-09-12 Werner Koch ++ ++ * fips.c (_gcry_fips_run_selftests): Add arg EXTENDED. ++ (run_cipher_selftests, run_digest_selftests, run_hmac_selftests) ++ (run_pubkey_selftests): Ditto. ++ * cipher-proto.h (selftest_func_t): Add arg EXTENDED ++ ++2008-09-11 Werner Koch ++ ++ * fips.c: Include string.h. ++ (loxtoi_1, loxtoi_2, loxdigit_p): New. ++ (check_binary_integrity): Change the format of the expected file. ++ ++ * fips.c (_gcry_fips_run_selftests): Run random tests before the ++ pubkey tests. ++ ++2008-09-05 Werner Koch ++ ++ * gcrypt.h.in (GCYRCTL_SELFTEST): New. ++ * global.c (_gcry_vcontrol): Implement. ++ * fips.c (_gcry_fips_run_selftests): Do state transitions only if ++ in fips mode. Return an error code. ++ ++2008-09-01 Werner Koch ++ ++ * stdmem.c: Re-indented. ++ ++2008-08-29 Werner Koch ++ ++ * fips.c (_gcry_initialize_fips_mode): Changed /proc file to test ++ for FIPS mode. ++ ++ * cipher-proto.h (pk_compute_keygrip_t): New. ++ (pk_extra_spec): Add field comp_keygrip. ++ ++2008-08-28 Werner Koch ++ ++ * hwfeatures.c (_gcry_detect_hw_features): Disable hardware ++ detection in FIPS mode. ++ ++2008-08-27 Werner Koch ++ ++ * global.c (_gcry_vcontrol): Allow running selftests from error ++ state. ++ (gcry_set_outofcore_handler): Only print a warning if used in FIPS ++ mode. ++ (gcry_xmalloc, gcry_xrealloc, gcry_xmalloc_secure, gcry_xstrdup): ++ Ignore an outofcore handler in FIPS mode. ++ ++ * fips.c (_gcry_fips_test_error_or_operational): New. ++ (fips_new_state): Allow transition from error into selftest. ++ Disallow error to init. ++ ++2008-08-26 Werner Koch ++ ++ * fips.c (fips_new_state): Print state transitions only at ++ verbosity level of 2. ++ (reporter): Likewise. ++ ++ * cipher-proto.h (pk_ext_generate_t): New. ++ (pk_extra_spec): Add member ext_generate. ++ * cipher.h (PUBKEY_FLAG_TRANSIENT_KEY): New. ++ ++2008-08-22 Werner Koch ++ ++ * hmac256.c (_gcry_hmac256_file): New. ++ (main): New option --binary. ++ * fips.c (check_binary_integrity): New. ++ (_gcry_fips_run_selftests): Run it. ++ ++ * global.c (_gcry_vcontrol) : ++ Check for fips operational state. ++ (_gcry_vcontrol) : Ditt. ++ ++2008-08-21 Werner Koch ++ ++ * misc.c (_gcry_log_printhex): New. ++ ++2008-08-20 Werner Koch ++ ++ * g10lib.h (gcry_assert): New. use this at almost all places ++ where we used a plain assert. ++ * misc.c (_gcry_assert_failed): New. ++ (_gcry_bug): Also use func variant for ISO-C99. ++ ++2008-08-19 Werner Koch ++ ++ * visibility.c, visibility.h (gcry_mpi_lshift): New. ++ * libgcrypt.vers, libgcrypt.def, gcrypt.h.in: Ditto. ++ ++2008-08-15 Werner Koch ++ ++ * gcrypt.h.in (gcry_cipher_setkey): Replace macro by function. ++ (gcry_cipher_setiv): Ditto. ++ (gcry_cipher_setctr): Ditto. ++ * visibility.c (gcry_cipher_setkey, gcry_cipher_setiv) ++ (gcry_cipher_setctr): New. ++ * visibility.h (gcry_cipher_setkey, gcry_cipher_setiv) ++ (gcry_cipher_setctr): New. ++ * libgcrypt.vers (gcry_cipher_setkey, gcry_cipher_setiv) ++ (gcry_cipher_setctr): New. ++ * libgcrypt.def (gcry_cipher_setkey, gcry_cipher_setiv) ++ (gcry_cipher_setctr): New. ++ ++ * hmac256.h, hmac256.c: New. ++ * Makefile.am (hmac256_SOURCES): New. ++ * Makefile.am (bin_PROGRAMS): Add hmac256. ++ ++ * gcrypt.h.in (struct gcry_thread_cbs): Change type of OPTION to ++ unsigned int. Although this is a type change it does not make a ++ difference. ++ * ath.c (ath_install): Take the version of the option field in ++ account. ++ ++ * visibility.c (gcry_pk_encrypt, gcry_pk_decrypt, gcry_pk_sign) ++ (gcry_pk_verify, gcry_pk_testkey, gcry_pk_genkey) ++ (gcry_pk_get_nbits, gcry_pk_get_keygrip) ++ (gcry_md_open, gcry_md_copy, gcry_md_enable) ++ (gcry_md_write, md_final, gcry_md_ctl, gcry_md_setkey) ++ (gcry_md_hash_buffer, gcry_md_get_algo, gcry_md_info) ++ (gcry_md_is_enabled) ++ (gcry_cipher_open, gcry_cipher_encrypt) ++ (gcry_cipher_decrypt, gcry_cipher_ctl) ++ (gcry_cipher_algo_info): Check whether the library is operational. ++ ++ * cipher-proto.h: New. ++ * cipher.h: Include cipher-proto.h. ++ * visibility.h: Remove duplicate macro definitions. Remove ++ gcry_cipher_register, gcry_md_register, gcry_pk_register macros. ++ * visibility.c: Include cipher-proto.h. ++ (gcry_cipher_register): Pass dummy extra args to the internal ++ register function. ++ (gcry_md_register, gcry_pk_register): Ditto. ++ * g10lib.h (struct gcry_module): Add field EXTRASPEC. ++ * module.c (_gcry_module_add): Add arg EXTRASPEC. Changed all ++ callers to pass NULL. ++ ++ * fips.c: New. ++ * gcrypt.h.in (GCRYCTL_FIPS_MODE_P): New. ++ * global.c (global_init): Call fips initialization. ++ (_gcry_vcontrol): Add GCRYCTL_FIPS_MODE_P code. ++ (print_config): Add config item fips-mode. ++ (gcry_set_allocation_handler): Do not allow the use of custom ++ allocation handlers. ++ (gcry_set_outofcore_handler): Ditto. ++ (_gcry_get_debug_flag): Do not return any debug flags in fips mode. ++ * misc.c (_gcry_logv): Signal fips error on BUG or FATAL. ++ (_gcry_fatal_error): Ditto. ++ ++2008-07-05 Werner Koch ++ ++ * Makefile.am: Include librandom.la. ++ ++2008-04-18 Werner Koch ++ ++ * missing-string.c (vasprintf): Remove. It is not used. Reported ++ by Simon Josefsson. ++ ++2008-03-11 Werner Koch ++ ++ * gcrypt.h.in (gcry_ac_em_t, gcry_ac_scheme_t): Remove trailing ++ comma for full C-89 compatibility. ++ ++2008-01-21 Marcus Brinkmann ++ ++ * hwfeatures.c (detect_ia32_gnuc): Fix inline asm. ++ ++2007-12-11 Werner Koch ++ ++ * visibility.c (gcry_md_hash_buffer): Don't use return vor a void ++ function. Hey, why does gcc not complain about this? ++ (gcry_ac_io_init_va): Ditto. ++ ++2007-12-05 Werner Koch ++ ++ * hwfeatures.c (detect_ia32_gnuc): Depend on ENABLE_PADLOCK_SUPPORT. ++ ++2007-12-03 Werner Koch ++ ++ * misc.c (_gcry_logv): Use abort for error levels fatal and bug as ++ this is more approriate for a library. Terminate the secmem ++ before doing so. ++ (_gcry_fatal_error): Terminate secmem before abort. ++ * secmem.c (_gcry_secmem_malloc_internal): Use log_bug instead of ++ exit. ++ ++2007-11-29 Werner Koch ++ ++ * hwfeatures.c (detect_ia32_gnuc): Detect Padlock engine. ++ ++2007-11-13 Werner Koch ++ ++ * gcrypt.h.in (_GCRY_GCC_ATTR_MALLOC): Fixed gcc version check. ++ Reported by Gabriele Monti. ++ ++2007-10-31 Werner Koch ++ ++ * global.c (gcry_control): Factor most code out to .. ++ (_gcry_vcontrol): .. new. ++ * sexp.c (_gcry_sexp_vbuild): New. ++ * mpi.h (_gcry_mpi_set, _gcry_mpi_set_ui, _gcry_mpi_invm): Remove ++ prototypes as they are already in gcrypt.h. ++ ++2007-10-30 Werner Koch ++ ++ * sexp.c (gcry_sexp_nth_string): Replace by _gcry_sexp_nth_string. ++ ++ * visibility.h, visibility.c: New. ++ * g10lib.h: Include visibility.h instead of gcrypt.h. ++ * globals.c (_gcry_malloc): Rename to .. ++ (do_malloc): .. this. ++ ++ * hwfeatures.c: New. ++ * global.c (global_init): Detect features. ++ (print_config): Print them. ++ ++2007-08-22 Werner Koch ++ ++ * dumpsexp.c: New. ++ * Makefile.am (bin_PROGRAMS): Install it. ++ ++ * getrandom.c (print_version): Use new standard license line. ++ * gcryptrnd.c (print_version): Ditto. ++ ++2007-06-06 Werner Koch ++ ++ * gcrypt.h.in (GCRY_THREAD_OPTION_PTH_IMPL): Factror network ++ related code out so that the prototypes can be adjusted for W32. ++ (_GCRY_THREAD_OPTION_PTH_IMPL_NET): New. ++ ++2007-05-09 Werner Koch ++ ++ * libgcrypt.m4: Print found version on success. ++ ++2007-05-09 Marcus Brinkmann ++ ++ * gcrypt.h.in (gcry_ac_io_t): Add name for anonymous union, and mark ++ all members as internal (actually: deprecated). ++ ++2007-05-04 Werner Koch ++ ++ * Makefile.am (.rc.lo): New to replace gmake specific suffix rule. ++ ++2007-05-03 Werner Koch ++ ++ * libgcrypt.def (gcry_sexp_nth_string): New. ++ * Makefile.am (EXTRA_DIST): Add libgcrypt.def. ++ ++2007-05-02 Werner Koch ++ ++ * global.c (print_config): Print ciphers, digests and pubkeys. ++ ++2007-05-02 David Shaw ++ ++ * cipher.h, gcrypt.h.in: Add Camellia. ++ ++2007-04-30 Werner Koch ++ ++ * gcrypt.h.in (GCRYCTL_PRINT_CONFIG): New. ++ (GCRYCTL_SET_RNDEGD_SOCKET): New. ++ * global.c (gcry_control): Add GCRYCTL_PRINT_CONFIG and ++ GCRYCTL_SET_RNDEGD_SOCKET. ++ (print_config): New. ++ * misc.c (_gcry_log_info_with_dummy_fp): New. ++ ++2007-04-18 Werner Koch ++ ++ * gcrypt.h.in (gcry_sexp_nth_string): New. ++ ++ * sexp.c (gcry_sexp_nth_data): Factored code out to ... ++ (sexp_nth_data): ... new. ++ (gcry_sexp_nth_string): New. ++ (gcry_sexp_nth_mpi): Reimplemented in terms of sexp_ntd_data. ++ ++2007-04-16 Werner Koch ++ ++ * secmem.c (init_pool): Use sysconf() if available to determine ++ page size. ++ ++2007-03-22 Werner Koch ++ ++ * mpi.h (mpi_mod): New. ++ (mpi_new, mpi_snew): New. ++ ++ * gcrypt.h.in: Add GCRY_PK_ECDSA. ++ ++2007-03-16 Werner Koch ++ ++ * gcrypt.h.in (GCRY_THREAD_OPTION_PTHREAD_IMPL): Fixed typo ++ introduced by me on 2006-10-23. ++ ++2007-02-22 Werner Koch ++ ++ * gcrypt.h.in (gcry_ac_id_to_name, gcry_ac_name_to_id): Mark as ++ deprecated. ++ ++ * libgcrypt.def (gcry_fast_random_poll): Removed - it is a macro. ++ (gcry_cipher_register, gcry_cipher_unregister): New. ++ (gcry_md_register, gcry_md_unregister): New. ++ (gcry_pk_register, gcry_pk_unregister): New. ++ (gcry_ac_data_from_sexp, gcry_ac_data_to_sexp): New. ++ (gcry_ac_io_init, gcry_ac_io_init_va): New. ++ (gcry_ac_data_encrypt_scheme, gcry_ac_data_decrypt_scheme): New. ++ (gcry_ac_data_sign_scheme, gcry_ac_data_verify_scheme): New. ++ ++ * missing-string.c: Include stdio.h for the vsprintf prototype. ++ ++ * ath.h (struct ath_ops) [_WIN32]: Use int instead of socklen_t. ++ ++2007-02-21 Werner Koch ++ ++ * libgcrypt.def (gcry_create_nonce, gcry_fast_random_poll) ++ (gcry_md_debug): New. ++ ++ * libgcrypt-config.in: Remove duplicates from --cflags and --libs. ++ Print a error for option --thread. ++ ++ * gcrypt.h.in (gcry_sexp_sprint): Change BUFFER from char* to void*. ++ (gcry_md_ctl): Change BUFFER from unsigned char* to void*. ++ (gcry_md_debug): New. ++ (gcry_cipher_encrypt, gcry_cipher_decrypt): Change buffer args to ++ void*. ++ (gcry_randomize): Change BUFFER to void. ++ (gcry_create_nonce): Ditto. ++ ++ * libgcrypt.vers (gcry_md_debug): New. ++ ++ * sexp.c (gcry_sexp_sprint): Ditto. ++ (normalize): Make P unsigned. ++ (gcry_sexp_nth_data): Cast return value to char*. ++ (sexp_sscan): Fix sign/unsigned conflicts. ++ (whitespacep): Change P to char*. ++ (unquote_string): Change STRING to char*. ++ (convert_to_hex): Change DEST to char*. ++ (convert_to_string): Change DEST and P to char*. ++ (convert_to_token): Chnage DEST to char*. ++ (gcry_sexp_canon_len): Change DISPHINT to unsigned char*. ++ ++ * gcrypt-module.h (gcry_pk_spec): Made ALIASES a const. ++ (gcry_md_write_t): Changed BUF to a const void*. ++ ++2007-02-12 Werner Koch ++ ++ * gcrypt.h.in: Include stdlib.h for the sake fo the trheading ++ macros. Suggested by Andreas Metzler. ++ ++ * secmem.c (ptr_into_pool_p): New. ++ (_gcry_private_is_secure): Implement in terms of new function. ++ (BLOCK_VALID): Removed. Replaced all users by new function. ++ ++2007-01-31 Werner Koch ++ ++ * secmem.c (_gcry_private_is_secure): Fixed severe implementation ++ flaw. Might be the reason for some of the more obscure bugs. ++ (MB_WIPE_OUT): Use wipememory2. ++ ++2006-10-23 Werner Koch ++ ++ * gcrypt.h.in (GCRY_THREAD_OPTION_PTHREAD_IMPL): Add some cast for ++ use by C-doubleplus. In general I don't like this but due to ++ public demand I give up ;-) ++ ++2006-10-19 Werner Koch ++ ++ * global.c (gcry_control) : Return an error ++ if the memory could not be locked. ++ * secmem.c (not_locked): New. ++ (_gcry_secmem_get_flags): Return that flag. ++ * secmem.h (GCRY_SECMEM_FLAG_NOT_LOCKED): New. ++ ++2006-10-05 Werner Koch ++ ++ * module.c (_gcry_module_id_new): Don't assign modules in the range ++ the range of 1024..4096. ++ * gcrypt.h (GCRY_MD_USER, GCRY_MD_USER_LAST): New ++ (GCRY_PK_USER, GCRY_PK_USER_LAST): New. ++ (GCRY_CIPHER_USER, GCRY_CIPHER_USER_LAST): New. ++ ++2006-10-12 Marcus Brinkmann ++ ++ * gcrypt.h.in: Replace socklen_t with gcry_socklen_t. ++ ++2006-10-11 Marcus Brinkmann ++ ++ * gcrypt.h.in: Replace version by @VERSION@. ++ ++2006-10-10 Marcus Brinkmann ++ ++ * gcrypt.h: Add fallback type for socklen_t. Move to ... ++ * gcrypt.h.in: ... this file. ++ * Makefile.am (EXTRA_DIST): Add gcrypt.h.in. ++ ++2006-09-04 Werner Koch ++ ++ * gcrypt.h: Removed some trailing comma in enums. ++ ++2006-08-29 Werner Koch ++ ++ * global.c (gcry_xrealloc): Pass secure flag to outofcore handler. ++ ++ * gcrypt.h (GCRY_CIPHER_SEED): New. ++ ++2006-08-21 Werner Koch ++ ++ * gcrypt.h (GCRYCTL_FAKED_RANDOM_P): New. ++ ++2006-07-29 Marcus Brinkmann ++ ++ * secmem.c (init_pool): Close FD after establishing the mapping. ++ ++2006-07-12 Marcus Brinkmann ++ ++ * ath.c (ath_mutex_destroy): Microoptimize destruction of unused ++ statitically initialized mutexes. Suggested by Victor Stinner ++ . ++ ++ * gcrypt.h (GCRY_THREAD_OPTION_PTHREAD_IMPL, ++ (GCRY_THREAD_OPTION_PTH_IMPL): Add missing initializers to ++ suppress gcc warning. ++ Submitted by Victor Stinner . ++ ++2006-07-04 Marcus Brinkmann ++ ++ * ath.c: Avoid warning about double defined type byte and other ++ hacks to let it build for W32 (backported from LIBGCRYPT-1-2-BRANCH). ++ * ath.h, gcrypt.h, tests/benchmark.c, src/types.h: Likewise. ++ ++ * gcrypt.h: Revert last change, and instead: ++ [_WIN32 || __WIN32__]: Do not include , but ++ and . ++ Suggested by Simon Josefsson . ++ ++ * Makefile.am (install-data-local, uninstall-local, %.lo, ++ (install-def-file, uninstall-def-file): New targets. ++ (LTRCCOMPILE, gcrypt_res, gcrypt_res_ldflag, no_undefined, ++ (export_symbols, gcrypt_deps): New variables. ++ * versioninfo.rc.in: New file. ++ * libgcrypt.def: New file from ../w32-dll/libgcrypt.def. ++ ++ * gcrypt.h [!HAVE_SYS_SOCKET_H]: Do not include sys/socket.h, but ++ the appropriate windows socket header. ++ ++2006-06-21 Werner Koch ++ ++ * global.c (gcry_xcalloc, gcry_xcalloc_secure): Made safe against ++ integer overflow. ++ ++ * sexp.c (make_space): Return an error on out of core. ++ (sexp_sscan): Remove all xmalloc style calls and return proper ++ error codes on allocation failures. ++ (gcry_sexp_find_token): Ditto. ++ (gcry_sexp_nth): ++ ++ * sexp.c (gcry_sexp_find_token): Re-indented and removed a cruft ++ "while(level);" which fortunately had no effect. ++ ++2006-04-28 Werner Koch ++ ++ * gcrypt.h (GCRY_MD_SHA224): Change value from 306 to 11 to match ++ the use in OpenPGP. There has been no release yet, so we can ++ safely do it. ++ ++2006-04-22 Moritz Schulte ++ ++ * gcrypt.h (gcry_ctl_cmds): New commands: ++ GCRYCTL_SET_RANDOM_DAEMON_SOCKET, GCRYCTL_USE_RANDOM_DAEMON. ++ * global.c (gcry_control): Handle new commands, calling ++ _gcry_set_random_daemon_socket() and _gcry_use_random_daemon(). ++ ++2006-04-18 Werner Koch ++ ++ * gcrypt.h (GCRY_PK_USAGE_CERT, GCRY_PK_USAGE_AUTH) ++ (GCRY_PK_USAGE_UNKN): New. ++ ++2006-04-01 Moritz Schulte ++ ++ * gcrypt.h (gcry_ac_eme_pkcs_v1_5): Removed members: key, handle; ++ added member: key_size. ++ ++ * secmem.c (MB_FLAG_ACTIVE): Write braces around MB_FLAG_ACTIVE ++ definition. ++ ++2006-03-15 Werner Koch ++ ++ * getrandom.c: New. ++ ++2006-03-14 Werner Koch ++ ++ * gcryptrnd.c: New. ++ ++2006-03-10 Werner Koch ++ ++ * gcrypt.h: Add GCRY_MD_SHA224. ++ ++2005-11-02 Moritz Schulte ++ ++ * gcrypt.h: Update comments for functions: gcry_cipher_algo_name, ++ gcry_pk_algo_name. ++ ++2005-10-31 Moritz Schulte ++ ++ * global.c: Added documentation. ++ ++2005-10-16 Moritz Schulte ++ ++ * global.c (global_init): Use gcry_error_t instead of ++ gcry_err_code_t; use goto instead of if constructs. ++ ++ * stdmem.c: Inserted description of the layered memory management ++ in Libgcrypt. ++ ++ * g10lib.h: Removed G10_I18N_H related check; it seems to be a ++ GnuPG relict (Libgcrypt does not define this symbol anywhere). ++ (FLAG_MODULE_DISABLED): Don't forget parantheses around shifted ++ value. ++ ++ Removed GCC_ATTR_PURE macro definitions, since gcrypt.h does ++ already contain such a macro named _GCRY_GCC_ATTR_PURE, which we ++ can use here as well. ++ ++ Likewise for GCC_ATTR_MALLOC and _GCRY_GCC_ATTR_MALLOC. ++ ++ * stdmem.h: Use _GCRY_GCC_ATTR_MALLOC instead of GCC_ATTR_MALLOC. ++ * secmem.h: Likewise. ++ ++2005-10-09 Moritz Schulte ++ ++ * global.c (gcry_control): Call global_init() after passing thread ++ cbs to ath. global_init() MUST to be called AFTER passing the cbs ++ to ath and BEFORE calling library functions, which make use of ++ ath. This change combines cbs installing with ath initialization ++ and thus removes the need to call other library initialization ++ functions inbetween like e.g. gcry_check_version(). ++ ++2005-10-01 Moritz Schulte ++ ++ * ath.c: Assign copyright to FSF. ++ * ath.h: Likewise. ++ ++2005-06-25 Moritz Schulte ++ ++ * Makefile.am (pkgconfigdir, pkgconfig_DATA): Removed variables. ++ * libgcrypt.pc.in: Removed file - we do not want to support a ++ second, foreign configuration system. ++ ++2005-06-17 Moritz Schulte ++ ++ * global.c (gcry_xstrdup): Removed superfluous strcpy call. ++ ++2005-04-22 Moritz Schulte ++ ++ * Makefile.am (pkgconfigdir, pkgconfig_DATA): New; support for ++ pkgconfig provided by Albert Chin. ++ * libgcrypt.pc.in (Cflags): New file. ++ ++2005-04-16 Moritz Schulte ++ ++ * g10lib.h (_gcry_ac_init): Declare. ++ * global.c (global_init): Call _gcry_ac_init; don't forget to set ++ err. ++ ++2005-04-14 Werner Koch ++ ++ * sexp.c (whitespacep): New. ++ (sexp_sscan): Replaced isdigit and isspace by whitespacep and ++ digitp. ++ ++2005-04-11 Moritz Schulte ++ ++ * gcrypt.h (gcry_md_algos): Added: GCRY_MD_WHIRLPOOL. ++ * cipher.h (_gcry_digest_spec_whirlpool): Declare. ++ ++2005-03-30 Moritz Schulte ++ ++ * libgcrypt.vers: Added: gcry_ac_io_init, gry_ac_io_init_va. ++ ++ * gcrypt.h (gcry_ac_data_read_cb_t, gcry_ac_data_write_cb_t, ++ gcry_ac_io_mode_t, gcry_ac_io_type_t, gcry_ac_io_t): New types. ++ (gcry_ac_io_init_va): Declare function. ++ (gcry_ac_data_encode, gcry_ac_data_decode, ++ gcry_ac_data_encrypt_scheme, gcry_ac_data_decrypt_scheme, ++ gcry_ac_data_sign_scheme, gcry_ac_data_verify_scheme): Use ++ gcry_ac_io_type_t objects instead of memory strings directly. ++ ++2005-03-03 Moritz Schulte ++ ++ * libgcrypt.vers: Added: gcry_ac_data_to_sexp() and ++ gcry_ac_data_from_sexp(). ++ ++2005-02-22 Werner Koch ++ ++ * global.c (_gcry_malloc): Make sure ERRNO is set if we return ++ NULL. Remove unneeded initialization of M to allow the compiler ++ to catch errors. ++ (gcry_realloc): Make sure ERRNO is set if we return NULL> ++ ++2005-02-13 Moritz Schulte ++ ++ * gcrypt.h: Declare new functions: gcry_ac_data_encrypt_scheme, ++ gcry_ac_data_decrypt_scheme, gcry_ac_data_sign_scheme, ++ gcry_ac_data_verify_scheme, gcry_ac_data_encode, ++ gcry_ac_data_decode, gcry_ac_data_to_sexp, gcry_ac_data_from_sexp. ++ New types: gcry_ac_emsa_pkcs_v1_5_t, gcry_ac_ssa_pkcs_v1_5_t, ++ gcry_md_algo_t. ++ New enumeration lists: gcry_ac_scheme_t, gcry_ac_em_t. ++ * libgcrypt.vers: Added new ac functions. ++ * g10lib.h: Declare function: _gcry_pk_get_elements. ++ * mpi.h (mpi_get_ui): New macro. ++ Declare function: _gcry_mpi_get_ui. ++ ++2004-11-09 Werner Koch ++ ++ * gcrypt.h: Removed 3 trailing commas from enums. Noted by Heiko ++ Stamer. ++ ++2004-09-21 Werner Koch ++ ++ * sexp.c (sexp_sscan): Removed C++ style comments. Noted by Yoann ++ Vandoorselaere. ++ ++2004-08-23 Moritz Schulte ++ ++ * global.c: Do not include . ++ * sexp.c: Likewise. ++ * module.c: Likewise. ++ * misc.c: Likewise. ++ ++2004-08-18 Moritz Schulte ++ ++ * secmem.c (_gcry_secmem_init): Try to lock pool into core not ++ only when running with root privileges. ++ ++2004-08-16 Werner Koch ++ ++ * secmem.h (_gcry_secmem_set_flags,_gcry_secmem_get_flags): ++ Removed __pure__. ++ (GCRY_SECMEM_FLAG_NO_WARNING): Put macro value into parens. ++ ++ * secmem.c (_gcry_secmem_init): Defer printing of the warning. ++ ++2004-08-10 Moritz Schulte ++ ++ * gcrypt.h: Include , thanks to Simon Josefsson. ++ ++2004-05-07 Werner Koch ++ ++ * gcrypt.h: Added GCRYCTL_FAST_POLL. ++ (gcry_fast_random_poll): New. ++ * global.c (gcry_control) : Do only basic ++ random subsystem init. ++ (gcry_control) : New. ++ ++2004-04-22 Marcus Brinkmann ++ ++ * libgcrypt.m4: Quote first argument to AC_DEFUN. ++ ++2004-04-15 Werner Koch ++ ++ * secmem.c (_gcry_secmem_malloc_internal): Removed old extra info ++ error output. ++ (_gcry_secmem_term): Use wipememory2 here. ++ ++ * misc.c (_gcry_burn_stack): Use wipememory to avoid optimizations. ++ ++ * string.c: Removed. Was never used. ++ * global.c (gcry_strdup): Replaced by the version from string.c ++ (gcry_xstrdup): Rewritten. ++ * gcrypt.h: Removed duplicate prototype for gcry_strdup. ++ ++2004-03-29 Werner Koch ++ ++ * secmem.c (_gcry_secmem_realloc): Fixed double unlock; bug ++ manifested itself due to the more rigorous checking in the changed ++ ath.h ++ ++ * libgcrypt-config.in (Options): Ignore the obsolete --threads ++ option for now. ++ ++2004-03-17 Marcus Brinkmann ++ ++ * libgcrypt-config.in (includedir, libdir): Quote'em. Use ++ $gpg_error_cflags and $gpg_error_libs. Fix construction of ++ $includes. ++ ++2004-03-14 Marcus Brinkmann ++ ++ * libgcrypt-config.in (includedir, libdir): New variables. For ++ --cflags, don't test $cflags. Also check against /include for the ++ GNU/Hurd. Don't overwrite but extend $cflags_final. Likewise for ++ --libs. ++ ++2004-03-10 Marcus Brinkmann ++ ++ * Makefile.am (ltlib_libgcrypt_pthread, ltlib_libgcrypt_pth): Removed. ++ (lib_LTLIBRARIES): Remove those variables from here. ++ (libgcrypt_pthread_la_SOURCES, libgcrypt_pthread_la_LDFLAGS, ++ (libgcrypt_pthread_la_DEPENDENCIES, libgcrypt_pthread_la_LIBADD, ++ (libgcrypt_pth_la_SOURCES, libgcrypt_pth_la_LDFLAGS, ++ (libgcrypt_pth_la_DEPENDENCIES, libgcrypt_pth_la_LIBADD, ++ (noinst_LTLIBRARIES): Removed. ++ (libgcrypt_real_la_SOURCES): Merge with ... ++ (libgcrypt_la_SOURCES): ... likewise. ++ (libgcrypt_real_la_DEPENDENCIES): Merge with ... ++ (libgcrypt_la_DEPENDENCIES): ... this. ++ (libgcrypt_real_la_LIBADD): Merge with ... ++ (libgcrypt_la_LIBADD): ... this. ++ * libgcrypt-config.in (libs_pthread, libs_pth, cflags_pth) ++ (cflags_pthread, thread_module, thread_modules): Removed. ++ (Options): Remove --thread option from help output. If the option ++ is specified, output an error and exit. ++ For --cflags and --libs option, remove pth and pthread from output. ++ * gcrypt.h: Include and . ++ (enum gcry_ctl_cmds): Add GCRYCTL_SET_THREAD_CBS. ++ (gcry_thread_cbs): New struct. ++ * global.c (gcry_control): Implement GCRYCTL_SET_THREAD_CBS. ++ (global_init): Don't call ath_init here. ++ * ath.h: Rewritten. ++ * ath.c: Rewritten. ++ ++2004-03-06 Werner Koch ++ ++ * libgcrypt-config.in: s/--soname-number/--api-version/ ++ * libgcrypt.m4: Changed test for API version. ++ ++2004-03-05 Werner Koch ++ ++ * libgcrypt.m4: Optionally check the SONAME number. ++ ++ * libgcrypt-config.in: Add option --soname-number ++ ++2004-03-01 Marcus Brinkmann ++ ++ * Makefile.am (libgcrypt_la_SOURCES): Add ath.c. ++ * ath.c (ath_init): Add missing function. ++ ++ * Makefile.am (ath_pth_src): Removed. ++ (ath_pthread_src): Removed. ++ (libgcrypt_la_SOURCES): Remove ath-compat, $(ath_pth_src) and ++ $(ath_pthread_src). ++ * ath-compat.c, ath-pth-compat.c, ath-pthread-compat.c: Files ++ removed. ++ ++2004-02-20 Werner Koch ++ ++ * gcrypt.h (GCRY_PRIME_CHECK_AT_GOT_PRIME) ++ (GCRY_PRIME_CHECK_AT_FINISH), ++ (GCRY_PRIME_CHECK_AT_MAYBE_PRIME): New. ++ ++2004-02-18 Werner Koch ++ ++ * libgcrypt-config.in: Ignore setting of --prefix. ++ ++2004-02-13 Werner Koch ++ ++ * gcrypt.h: Added GCRY_CIPHER_RFC2268_128, alsthough not yet ++ supported. ++ ++2004-02-06 Werner Koch ++ ++ * gcrypt.h: Added GCRY_CIPHER_RFC2268_40. ++ ++2004-02-03 Werner Koch ++ ++ * secmem.c (_gcry_secmem_init): Do not print the "not locked into ++ core warning" if the NO_WARNING flag has been set. ++ ++ * sexp.c (sexp_sscan): Allocate result in secure memory if BUFFER ++ is in secure memory. Switch to secure memory for the a secure %b ++ format item. Extra paranoid wipe on error. ++ (gcry_sexp_release): Added paranoid wiping for securely allocated ++ S-expressions. ++ ++2004-01-25 Moritz Schulte ++ ++ * ath.h: Include . ++ ++2004-01-12 Moritz Schulte ++ ++ * gcrypt.h: Adjusted declarations of: gcry_ac_data_set, ++ gcry_ac_data_get_name, gcry_ac_data_get_index, ++ gcry_ac_key_pair_generate, gcry_ac_key_test, ++ gcry_ac_key_get_nbits, gcry_ac_key_get_grip. ++ ++ * gcrypt.h (GCRY_AC_FLAG_DATA_NO_BLINDING): Removed symbol. ++ (GCRY_AC_FLAG_DEALLOC, GCRY_AC_FLAG_COPY) ++ (GCRY_AC_FLAG_NO_BLINDING): New symbols. ++ ++ * global.c (gcry_strdup): Removed function. ++ * string.c: New file. ++ * Makefile.am (libgcrypt_real_la_SOURCES): Added: string.c. ++ * string.c (gcry_strdup): New function. ++ * gcrypt.h (gcry_strdup): Declare. ++ ++2003-12-19 Werner Koch ++ ++ * g10lib.h (wipememory, wipememory2): New; taken from gnupg. ++ ++2003-11-14 Werner Koch ++ ++ * global.c (gcry_strdup): Don't copy the string after a malloc ++ error. ++ ++2003-11-11 Werner Koch ++ ++ * sexp.c (sexp_sscan): Implemented "%b" format specifier. ++ ++2003-11-11 Moritz Schulte ++ ++ * libgcrypt.m4: Do not set prefix when calling libgcrypt-config. ++ Thanks to Nikos Mavroyanopoulos. ++ ++2003-11-08 Moritz Schulte ++ ++ * cipher.h (small_prime_numbers): Removed declaration. ++ (PUBKEY_FLAG_NO_BLINDING): Put braces around shift. ++ ++2003-11-04 Werner Koch ++ ++ * cipher.h (_gcry_sha1_has_buffer): New. ++ ++ * gcrypt.h (gcry_create_nonce): New. ++ ++2003-10-31 Werner Koch ++ ++ * libgcrypt.vers (_gcry_generate_elg_prime): Removed this symbol; ++ gnutls does not need it anymore. ++ ++ * secmem.c (mb_get_new): s/pool/block/ due to global pool. ++ ++ * misc.c (gcry_set_log_handler): s/logf/f/ to avoid shadowing ++ warning against a builtin. ++ ++ * ath-pth-compat.c: cast pth_connect to get rid of the const ++ prototype. ++ ++2003-10-27 Werner Koch ++ ++ * ath.h (ATH_MUTEX_INITIALIZER): Removed spurious semicolon. ++ ++2003-10-27 Moritz Schulte ++ ++ * libgcrypt-config.in: Include libs/cflags of libgpg-error. ++ ++ * sexp.c (sexp_sscan): Cleaned up, deallocate scanned sexp on ++ error. ++ ++ * module.c (MODULE_ID_MIN): New symbol, use it. ++ ++2003-10-27 Werner Koch ++ ++ * gcrypt.h (gcry_pk_testkey): Doc fix. ++ ++2003-09-29 Moritz Schulte ++ ++ * libgcrypt-config.in: Fix --algorithms option. ++ ++2003-10-23 Werner Koch ++ ++ * gcrypt.h (gcry_err_code): Use GPG_ERR_INLINE instead of ++ __inline__. ++ ++ * secmem.c (lock_pool): Don't print the warning for certain ++ systems, handle ENOMEM. ++ ++2003-10-21 Werner Koch ++ ++ * secmem.c (_gcry_secmem_dump_stats): Fixed format sepcifier for a ++ size_t. Reported by Stephane Corthesy. ++ ++2003-10-10 Werner Koch ++ ++ * global.c (_gcry_malloc): Handle the no_secure_memory option. ++ ++ * gcrypt.h (gcry_prime_group_generator): New. ++ (gcry_prime_release_factors): New. ++ ++2003-10-07 Werner Koch ++ ++ * sexp.c (sexp_sscan): Check that parenthesis are matching. ++ ++2003-09-28 Moritz Schulte ++ ++ * g10lib.h: Declare: _gcry_malloc. ++ (GCRY_ALLOC_FLAG_SECURE): New symbol. ++ ++ * global.c (_gcry_malloc): New function... ++ (gcry_malloc): ... use it. ++ (gcry_malloc_secure): Likewise. ++ ++ * ath.c: Change License to LGPL. ++ * ath-pthread-compat.c: Likewise. ++ * ath-pthread.c: Likewise. ++ * ath-pth-compat.c: Likewise. ++ * ath-pth.c: Likewise. ++ * ath.h: Likewise. ++ * ath-compat.c: Likewise. ++ ++ * secmem.c (_gcry_secmem_realloc): Do not forget to release secmem ++ lock. Thanks to low halo for triggering this bug. ++ ++2003-09-04 Werner Koch ++ ++ * gcrypt.h (_GCRY_ERR_SOURCE_DEFAULT): Removed cruft. ++ (gcry_prime_check_func_t): Renamed arg for clarity. ++ ++2003-09-02 Moritz Schulte ++ ++ * gcrypt.h (GCRY_PRIME_FLAG_SPECIAL_FACTOR): New symbol. ++ ++2003-09-01 Moritz Schulte ++ ++ * gcrypt.h (gcry_random_level_t): New type. ++ (gcry_prime_check_func_t): Likewise. ++ (GCRY_PRIME_FLAG_SECRET): New symbol. ++ (gcry_prime_generate, gcry_prime_check): Declare functions. ++ ++2003-08-28 Werner Koch ++ ++ * Makefile.am (libgcrypt_pth_la_LDFLAGS): Removed PTH_CFLAGS cruft. ++ ++2003-08-27 Moritz Schulte ++ ++ * global.c (gcry_control): Remove call to ath_deinit. ++ ++ * Makefile.am (libgcrypt_real_la_DEPENDENCIES): Fixed. ++ (libgcrypt_real_la_LIBADD): Fixed. ++ Removed unecessary variables. ++ ++ * libgcrypt-config.in: Adjusted script for new thread handling. ++ ++ * Makefile.am: New version, based on GPGMEs Makefile.am. ++ ++ * ath.c, ath-compat.c, ath.h, ath-pth.c, ath-pth-compat.c, ++ ath-pthread.c, ath-pthread-compat.c: New files, merged from GPGME. ++ * ath.c, ath.h, ath-pthread.c, ath-pth.c: Removed files. ++ ++2003-08-08 Moritz Schulte ++ ++ * global.c (gcry_realloc): Remove FIXME about `clearing out ++ realloced memory', since _gcry_secmem_realloc takes care of ++ overwriting old memory. ++ ++2003-08-07 Werner Koch ++ ++ * module.c (_gcry_module_release): Don't act if module is NULL. ++ ++2003-07-30 Moritz Schulte ++ ++ * gcrypt.h (enum gcry_ac_id): Added: GCRY_AC_ELG_E. ++ Reverted change: use gcry_md_flags enumeration list instead of ++ defines. ++ ++2003-07-29 Werner Koch ++ ++ * global.c (gcry_control): Add GCRYCTL_SET_RANDOM_SEED_FILE and ++ GCRYCTL_UPDATE_RANDOM_SEED_FILE. ++ * gcrypt.h: Ditto. Renamed index to idx, so avoid warning ++ related to the old index function. ++ ++2003-07-28 Moritz Schulte ++ ++ * global.c (gcry_err_code_from_errno, gcry_err_code_to_errno) ++ (gcry_err_make_from_errno, gcry_error_from_errno): New functions. ++ ++ * gcrypt.h: Declared: gcry_err_code_from_errno, ++ gcry_err_code_to_errno, gcry_err_make_from_errno, ++ gcry_error_from_errno. ++ ++ * Makefile.am (include_HEADERS): Added: gcrypt-module.h. ++ ++ * gcrypt.h: Include . ++ ++ * gcrypt-module.h: New file. ++ ++2003-07-27 Werner Koch ++ ++ * gcrypt.h (gcry_mpi_scan, gcry_mpi_print): API change. ++ (gcry_mpi_dump): New. ++ ++2003-07-21 Moritz Schulte ++ ++ * gcrypt.h: Declared: gcry_ac_key_data_get. ++ (gcry_pk_spec): Renamed member `sexp_names' into `aliases'. ++ ++2003-07-20 Moritz Schulte ++ ++ * gcrypt.h (gcry_md_oid_spec_t): New type. ++ (gcry_md_spec): New member: oids. ++ ++2003-07-19 Moritz Schulte ++ ++ * gcrypt.h (gcry_cipher_oid_spec_t): New type. ++ (gcry_cipher_spec): New member: oids; ++ ++2003-07-18 Werner Koch ++ ++ * gcrypt.h (gcry_mpi_set_opaque): Add a warning comment. ++ ++2003-07-15 Moritz Schulte ++ ++ * secmem.c (compress_pool): Remove function, since unused blocks ++ are automatically concatenad. ++ ++ * gcrypt.h: Bumped version number up to 1.1.42-cvs. ++ ++2003-07-14 Moritz Schulte ++ ++ * gcrypt.h (gcry_cipher_spec): New member: aliases. ++ ++ * Makefile.am (noinst_PROGRAMS, testapi_SOURCES, testapai_LDADD, ++ benchmark_SOURCES, benchmark_LDADD): Removed. ++ ++ * benchmark.c, testapi.c: Removed files. ++ ++ * mpi.h: Removed disabled typedef. ++ * g10lib.h: Likewise. ++ ++ * benchmark.c, g10lib.h, gcrypt.h, global.c, module.c, sexp.c: ++ Used gcry_err* wrappers for libgpg-error symbols. ++ ++2003-07-12 Moritz Schulte ++ ++ * global.c: Likewise. ++ ++ * gcrypt.h: New type: gcry_error_t, gcry_err_code_t and ++ gcry_err_source_t. ++ (gcry_err_make, gcry_error, gcry_err_code, gcry_err_source): New ++ functions. ++ ++ * global.c (gcry_strerror): New function. ++ (gcry_strsource): New function. ++ ++ * gcrypt.h: New symbol: GCRY_CIPHER_TWOFISH128. ++ ++2003-07-09 Moritz Schulte ++ ++ * gcrypt.h (enum gcry_md_flags): Removed, used define instead, ++ since that is more common than an enumeration list when it comes ++ to flags that can be bitwise ORed. ++ ++2003-07-08 Moritz Schulte ++ ++ * global.c: Use new types for handlers. ++ ++ * gcrypt.h: Declare: gcry_ac_data_copy. ++ ++2003-07-07 Moritz Schulte ++ ++ * sexp.c (gcry_sexp_build_array): Use dummy argument pointer. ++ Thanks to Simon Josefsson . ++ ++ * gcrypt.h: Declare: gcry_cipher_list, gcry_pk_list, gcry_md_list. ++ ++2003-07-05 Moritz Schulte ++ ++ * gcrypt.h: Declare: gcry_cipher_register, gcry_cipher_unregister, ++ gcry_md_register, gcry_md_unregister, gcry_pk_register, ++ gcry_pk_unregister. ++ (gcry_cipher_spec): Removed member: algorithm. ++ (gcry_pk_spec): Likewise. ++ (gcry_md_spec): Likewise. ++ Adjusted declarations: gcry_cipher_register, gcry_pk_register, ++ gcry_md_register. ++ ++ * module.c: Replaced all occurences of `id' with `mod_id', since ++ `id' is a keyword in obj-c. ++ ++ * gcrypt.h (gcry_cipher_spec): Renamed member `id' to `algorithm'. ++ (gcry_pk_spec): Likewise. ++ (gcry_md_spec): Likewise. ++ ++ * cipher.h: Removed types: gcry_pubkey_generate_t, ++ gcry_pubkey_check_secret_key_t, gcry_pubkey_encrypt_t, ++ gcry_pubkey_decrypt_t, gcry_pubkey_sign_t, gcry_pubkey_verify_t, ++ gcry_pubkey_get_nbits_t, gcry_pk_spec_t, gcry_digest_init_t, ++ gcry_digest_write_t, gcry_digest_final_t, gcry_digest_read_t, ++ gcry_digest_spec_t, gcry_cipher_setkey_t, gcry_cipher_encrypt_t, ++ gcry_cipher_decrypt_t, gcry_cipher_stencrypt_t, ++ gcry_cipher_stdecrypt_t, gcry_cipher_spec_t. ++ ++ * gcrypt.h: New types: gcry_pk_generate_t, ++ gcry_pk_check_secret_key_t, gcry_pk_encrypt_t, gcry_pk_decrypt_t, ++ gcry_pk_sign_t, gcry_pk_verify_t, gcry_pk_get_nbits_t, ++ gcry_pk_spec_t, gcry_md_init_t, gcry_md_write_t, gcry_md_final_t, ++ gcry_md_read_t, gcry_md_spec_t, gcry_cipher_setkey_t, ++ gcry_cipher_encrypt_t, gcry_cipher_decrypt_t, ++ gcry_cipher_stencrypt_t, gcry_cipher_stdecrypt_t, ++ gcry_cipher_spec_t, gcry_module_t. ++ ++2003-07-04 Moritz Schulte ++ ++ * module.c (_gcry_module_list): New function. ++ ++2003-07-02 Moritz Schulte ++ ++ * module.c (_gcry_module_lookup): Fixed typo. ++ ++ * gcrypt.h: Added all definitions and declarations necessary for ++ the new ac interface. ++ ++2003-06-30 Moritz Schulte ++ ++ * g10lib.h: Added declarations: _gcry_pk_module_lookup, ++ _gcry_pk_module_release. ++ ++2003-06-18 Werner Koch ++ ++ * benchmark.c (cipher_bench): Adjusted for new API of get_blklen ++ and get_keylen. ++ ++ * gcrypt.h (gcry_cipher_get_algo_blklen) ++ (gcry_cipher_get_algo_keylen): Replaced macro by funcion. ++ ++2003-06-18 Moritz Schulte ++ ++ * cipher.h: Renamed types GcryDigestSpec, GcryCipherSpec and ++ GcryPubkeySpec into: gcry_digest_spec_t, gcry_cipher_spec_t and ++ gcry_pubkey_spec_t. ++ (gcry_pubkey_spec): Defined member `id' as unsigned. ++ (gcry_digest_spec): Likewise. ++ (gcry_cipher_spec): Likewise. ++ ++ * module.c (_gcry_module_id_new): New function. ++ (_gcry_module_add): Generate a new ID via _gcry_module_id_new in ++ case `id' is zero. ++ ++ * g10lib.h, module.c: Replace old type GcryModule with newer one: ++ gcry_module_t. ++ ++ * module.c (_gcry_module_add): Added argument `id', use it. ++ ++ * g10lib.h: Added declaration: _gcry_module_lookup_id. ++ (_gcry_module_add): Added argument `id'. ++ ++ * module.c (_gcry_module_lookup_id): New function. ++ ++ * g10lib.h (struct gcry_module): New member: id. ++ ++ * gcrypt.h: New type: gcry_handler_progress_t, ++ gcry_handler_alloc_t, gcry_haandler_secure_check_t, ++ gcry_handler_realloc_t, gcry_handler_free_t, ++ gcry_handler_no_mem_t, gcry_handler_error_t, gcry_handler_log_t. ++ Use new types. ++ ++ * cipher.h: Include . ++ New types: gcry_pk_generate_t, gcry_pk_check_secret_key_t, ++ gcry_pk_encrypt_t, gcry_pk_decrypt_t, gcry_pk_sign_t, ++ gcry_pk_verify_t, gcry_pk_get_nbits_t, gcry_md_init_t, ++ gcry_md_write_t, gcry_md_final_t, gcry_md_read_t, ++ gcry_cipher_setkey_t, gcry_cipher_encrypt_t, ++ gcry_cipher_decrypt_t, gcry_cipher_stencrypt_t, ++ gcry_cipher_stdecrypt_t. ++ Use new types. ++ ++2003-06-17 Moritz Schulte ++ ++ * Makefile.am (AM_CFLAGS): Added: @GPG_ERROR_CFLAGS@. ++ ++2003-06-16 Moritz Schulte ++ ++ * g10lib.h: Replace last occurences of old type names with newer ++ names (i.e. replace MPI with gcry_mpi_t). ++ * mpi.h: Likewise. ++ * sexp.c: Likewise. ++ ++2003-06-15 Moritz Schulte ++ ++ * testapi.c (test_genkey): Use gpg_strerror instead of ++ gcry_strerror. ++ ++ * global.c (gcry_control): Fixed typo. ++ ++ * misc.c (_gcry_fatal_error): Use gpg_strerror instead of ++ gcry_strerror. ++ ++ * types.h (STRLIST): Removed type since it is not used. ++ ++2003-06-11 Moritz Schulte ++ ++ * global.c (global_init): Call: _gcry_cipher_init, _gcry_md_init, ++ _gcry_pk_init. ++ ++ * g10lib.h: Declare: _gcry_cipher_init, _gcry_md_init, ++ _gcry_pk_init. ++ ++ * global.c (gcry_strerror): Remove compatibility code. ++ ++ * Makefile.am: Remove support libgpg-error special handling. ++ (AM_CPPFLAGS): Add @GPG_ERROR_CFLAGS@ ++ ++ * gcrypt.h: Likewise. ++ ++2003-06-13 Werner Koch ++ ++ * gcrypt.h (gcry_md_get_algo): Reverted to old API. This is a ++ convenience function anyway and error checking is not approriate. ++ (gcry_md_is_enabled): New. ++ (gcry_md_is_secure): Replaced macro by function and reverted to old ++ API. ++ ++2003-06-11 Werner Koch ++ ++ * gcrypt.h (GCRYERR): Define _GCRY_ERR_SOURCE_DEFAULT instead of ++ GPG_ERR_SOURCE_DEFAULT, so that libgpg-error still works despite ++ the use of the old gcrypt error codes. ++ (gcry_md_copy): Swapped arguments. ++ ++2003-06-09 Moritz Schulte ++ ++ * Makefile.am: Support for libgpg-error. ++ ++2003-06-08 Moritz Schulte ++ ++ * sexp.c (gcry_sexp_create): Expect sane error values from ++ gcry_sexp_canon_len instead of the `historical' values. ++ ++2003-06-07 Moritz Schulte ++ ++ * ath.c, ath.c, ath-pth.c, ath-pthread.c, benchmark.c, cipher.h, ++ g10lib.h, gcrypt.h, global.c, misc.c, missing-string.c, module.c, ++ mpi.h, secmem.c, secmem.h, sexp.c, stdmem.c, stdmem.h, testapi.c, ++ types.h: Edited all preprocessor instructions to remove whitespace ++ before the '#'. This is not required by C89, but there are some ++ compilers out there that don't like it. Replaced any occurence of ++ the now deprecated type names with the new ones. ++ ++ * gcrypt.h: Re-organized checking for gcc features; New macro: ++ _GCRY_GCC_ATTR_DEPRECATED. ++ Include copy of libgpg-error's gpg-error.h in order to make it ++ easy to build libgcrypt without needing libgpg-error.h. ++ ++ (GCRY_MPI, GcryMPI, GCRY_SEXP, GcrySexp, GCRY_CIPHER_HD, ++ GcryCipherHd, GCRY_MD_HD, GcryMDHd): Declared deprecated. ++ (gcry_mpi_t, gcry_sexp_t, gcry_cipher_hd_t, gcry_md_hd_t): New ++ types. ++ ++2003-06-04 Moritz Schulte ++ ++ * sexp.c (sexp_sscan): New argument: arg_list, adjusted all ++ callers. ++ (ARG_NEXT): New macro. ++ (sexp_sscan): Use ARG_NEXT for receiving format string arguments. ++ (gcry_sexp_build_array): New function. ++ ++2003-06-02 Moritz Schulte ++ ++ * gcrypt.h: Added some comments describing the gcry_sexp_* ++ functions. ++ Include instead of . ++ ++2003-06-01 Moritz Schulte ++ ++ * sexp.c (OLDPARSECODE): Removed macro... ++ (gcry_sexp_canon_len): ... and do not use it. ++ ++ * gcrypt.h (gcry_errno): Removed declaration. ++ ++ * g10lib.h (string_to_pubkey_algo, pubkey_algo_to_string, ++ pubkey_nbits): Removed declarations for non-existing functions. ++ ++2003-05-31 Moritz Schulte ++ ++ * cipher.h (is_RSA, is_ELGAMAL): Removed macros. ++ ++ * g10lib.h (set_lasterr): Removed macro. ++ (_gcry_set_lasterr): Removed declaration. ++ ++ * gcrypt.h: Changed declarations for: gcry_pk_algo_info, ++ gcry_md_open, gcry_md_copy, gcry_md_algo_info, gcry_md_info, ++ gcry_md_get_algo, gcry_random_add_bytes. ++ ++ (gcry_md_is_secure): Adjust macro for new API. ++ ++2003-05-29 Moritz Schulte ++ ++ * gcrypt.h: Changed declarations for: gcry_cipher_open, ++ gcry_cipher_info, gcry_cipher_algo_info. ++ (gcry_cipher_get_algo_keylen): Adjuster for new ++ gcry_cipher_algo_info interface. ++ (gcry_cipher_get_algo_blklen): Likewise. ++ ++ * global.c (gcry_errno): Removed function. ++ (gcry_strerror): Do not use gcry_errno. ++ (_gcry_set_lasterr): Removed function. ++ (last_ec): Removed variable. ++ ++2003-05-27 Moritz Schulte ++ ++ * gcrypt.h (enum gcry_cipher_algos): Make Serpent IDs do not ++ conflict with OpenPGP. Reported by Timo Schulz. ++ ++ * global.c (gcry_control): Fixed name of enum list. ++ ++2003-05-25 Moritz Schulte ++ ++ * cipher.h (gcry_cipher_spec): Adjust return type of `setkey' for ++ libgpg-error. ++ (gcry_pubkey_spec): Adjust return type of `generate', ++ `check_secret_key', `encrypt', `decrypt', `sign' and `verify' for ++ libgpg-error. ++ ++ * sexp.c (gcry_sexp_canon_len): Adjusted for libgpg-error. ++ (gcry_sexp_create): Likewise. ++ (gcry_sexp_new): Likewise. ++ (sexp_sscan): Likewise. ++ (gcry_sexp_build): Likewise. ++ (gcry_sexp_sscan): Likewise. ++ ++ * module.c (_gcry_module_add): Likewise. ++ ++ * global.c (last_ec): Change type to gpg_error_t. ++ (gcry_control): Adjust for libgpg-error. ++ (gcry_errno): Likewise. ++ (gcry_strerror): Likewise. ++ (_gcry_set_lasterr): Likewise. ++ (gcry_xmalloc): Likewise. ++ (gcry_xrealloc): Likewise. ++ ++2003-05-22 Moritz Schulte ++ ++ * types.h: Merged code from GnuPG regarding U64_C. ++ ++ * missing-string.c (strsep): Removed function. ++ ++ * g10lib.h: Removed declarations: strsep, strlwr. ++ ++ * secmem.c (secmem_lock): New variable. ++ (SECMEM_LOCK, SECMEM_UNLOCK): New macros. ++ (_gcry_secmem_set_flags): Use SECMEM_LOCK and SECMEM_UNLOCK. ++ (_gcry_secmem_get_flags): Likewise. ++ (_gcry_secmem_init): Likewie. ++ (_gcry_secmem_malloc): Likewise. ++ (_gcry_secmem_free): Likewise. ++ (_gcry_secmem_malloc): Renamed to ... ++ (_gcry_secmem_malloc_internal): ... this. ++ (_gcry_secmem_malloc): New function, use SECMEM_LOCK, ++ SECMEM_UNLOCK, call _gcry_secmem_malloc_internal. ++ (_gcry_secmem_free): Renamed to ... ++ (_gcry_secmem_free_internal): ... this. ++ (_gcry_secmem_free): New function, use SECMEM_LOCK, SECMEM_UNLOCK, ++ call _gcry_secmem_free_internal. ++ (_gcry_secmem_realloc): Use SECMEM_LOCK, SECMEM_UNLOCK, call ++ _gcry_secmem_malloc_internal and _gcry_secmem_free_internal. ++ (_gcry_private_is_secure): Use SECMEM_LOCK, SECMEM_UNLOCK. ++ (_gcry_secmem_dump_stats): Likewise. ++ (_gcry_secmem_malloc_internal): Removed unused variable: ++ compressed. ++ Include "ath.h". ++ ++2003-05-21 Moritz Schulte ++ ++ * gcrypt.h (GCRY_CIPHER_SERPENT128, GCRY_CIPHER_SERPENT192, ++ GCRY_CIPHER_SERPENT256): New symbols. ++ ++2003-05-19 Moritz Schulte ++ ++ * gcrypt.h: Reversed changes from 2003-03-03 since they would have ++ been an unnecessary ABI break. ++ ++2003-05-13 Moritz Schulte ++ ++ * secmem.c (stats_update): New function. ++ (BLOCK_HEAD_SIZE): New symbol. ++ (MB_FLAG_ACTIVE): New symbol. ++ (ADDR_TO_BLOCK, BLOCK_VALID): New macros. ++ (mb_get_next): New function. ++ (mb_get_prev): New function. ++ (mb_merge): New function. ++ (mb_get_new): New function. ++ (unused_blocks): Removed variable. ++ (init_pool): Initialize new memory pool. ++ (_gcry_secmem_malloc): Use new heap management code. ++ (_gcry_secmem_free): Likewise. ++ (_gcry_secmem_realloc): Likewise. ++ Renamed type MEMBLOCK to memblock_t. ++ ++2003-04-27 Moritz Schulte ++ ++ * cipher.h (gcry_pubkey_spec): New member: sexp_names. ++ ++2003-04-23 Moritz Schulte ++ ++ * cipher.h (gcry_pubkey_spec): Removed members: npkey, nskey, ++ nenc, nsig. ++ (gcry_pubkey_spec): Added members: elements_pkey, elements_skey, ++ elements_enc, elements_sig, elements_grip. ++ ++2003-04-17 Moritz Schulte ++ ++ * g10lib.h (GcryModule): New typedef. ++ ++ * gcrypt.h (gcry_cipher_register, gcry_cipher_unregister, ++ gcry_digest_register, gcry_digest_unregister, ++ gcry_pubkey_register, gcry_pubkey_unregister): Function ++ declarations removed - for now. ++ ++ * gcrypt.h (GcryModule): Declaration removed. ++ * gcrypt.h (GcryPubkeySpec, GcryDigestSpec, GcryCipherSpec): ++ Types Moved... ++ * cipher.h: ... here. ++ ++2003-04-17 Moritz Schulte ++ ++ * cipher.h: Declare digest_spec_sha512 and digest_spec_384. ++ ++2003-04-16 Moritz Schulte ++ ++ * module.c (_gcry_module_use): New function. ++ * g10lib.h (_gcry_module_use): Declare function. ++ ++ * libgcrypt-config.in: Support for --algorithms switch, which ++ prints the algorithms included in the built libgcrypt. ++ ++ * global.c (gcry_set_progress_handler): Register progress ++ functions depending on the enabled algorithms. ++ ++2003-04-07 Moritz Schulte ++ ++ * Makefile.am (libgcrypt_la_SOURCES): Added module.c ++ ++ * module.c: New file. ++ (_gcry_module_add): New function. ++ (_gcry_module_drop): New function. ++ (_gcry_module_lookup): New function. ++ (_gcry_module_release): New function. ++ ++ * g10lib.h (GcryModule): New types. ++ (FLAG_MODULE_DISABLED): New symbol. ++ Added declarations for _gcry_module_add, _gcry_module_release and ++ _gcry_module_lookup. ++ ++ * gcrypt.h: New types: GcryPubkeySpec, GcryDigestSpec, ++ GcryCipherSpec. ++ Added declarations for: gcry_cipher_register, ++ gcry_cipher_unregister, gcry_digest_register, ++ gcry_digest_unregister, gcry_pubkey_register and ++ gcry_pubkey_unregister. ++ ++ * cipher.h: Removed symbols: CIPHER_ALGO_NONE, CIPHER_ALGO_IDEA, ++ CIPHER_ALGO_3DES, CIPHER_ALGO_CAST5, CIPHER_ALGO_BLOWFISH, ++ CIPHER_ALGO_SAFER_SK128, CIPHER_ALGO_DES_SK, CIPHER_ALGO_TWOFISH, ++ CIPHER_ALGO_TWOFISH_OLD, CIPHER_ALGO_DUMMY, PUBKEY_USAGE_SIG, ++ PUBKEY_USAGE_ENC, DIGEST_ALGO_MD5, DIGEST_ALGO_SHA1, ++ DIGEST_ALGO_RMD160, DIGEST_ALGO_TIGER, PUBKEY_ALGO_RSA, ++ PUBKEY_ALGO_RSA_E, PUBKEY_ALGO_RSA_S, PUBKEY_ALGO_DSA, ++ PUBKEY_ALGO_ELGAMAL, PUBKEY_ALGO_ELGAMAL_E. ++ ++2003-04-02 Moritz Schulte ++ ++ * benchmark.c (md_bench): Fix error message. ++ ++2003-03-31 Moritz Schulte ++ ++ * benchmark.c (cipher_bench): Added CTR mode. ++ ++2003-03-30 Simon Josefsson ++ ++ * gcrypt.h (enum gcry_control_cmds): Add GCRY_SET_CTR. ++ (enum gcry_cipher_modes): Add GCRY_CIPHER_MODE_CTR. ++ (gcry_cipher_setctr): New macro to set counter. ++ ++2003-03-19 Moritz Schulte ++ ++ * cipher.h (PUBKEY_FLAG_NO_BLINDING): New symbol. ++ ++2003-03-22 Simon Josefsson ++ ++ * gcrypt.h: Add GCRYCTL_SET_CBC_MAC and GCRY_CIPHER_CBC_MAC. ++ ++2003-03-19 Werner Koch ++ ++ * g10lib.h: Adjusted primegen.c prototypes. ++ ++2003-03-12 Werner Koch ++ ++ * sexp.c (sexp_sscan): Initialize NM. Thanks to Ian Peters for ++ valgrinding this. ++ ++2003-03-06 Moritz Schulte ++ ++ * secmem.h (GCRY_SECMEM_FLAG_NO_WARNING, ++ GCRY_SECMEM_FLAG_SUSPEND_WARNING): New symbols. ++ ++ * global.c (gcry_control): Use ++ GCRY_SECMEM_FLAG_{NO,SUSPEND}_WARNING, instead of hard-coded ++ values. ++ * secmem.c (_gcry_secmem_set_flags): Likewise. ++ * secmem.c (_gcry_secmem_get_flags): Likewise. ++ ++2003-03-03 Moritz Schulte ++ ++ * misc.c: Removed old FIXME, since there is already a function to ++ set the value of `verbosity_level'. ++ ++ * gcrypt.h: Removed enumeration list: gcry_ctl_cmds. ++ New enumeration lists: gcry_global_control_cmds, ++ gcry_control_cmds, gcry_info_cmds, gcry_algo_info_cmds. ++ ++2003-03-02 Moritz Schulte ++ ++ * gcrypt.h (gcry_cipher_reset): New macro for resetting a handle. ++ ++2003-02-28 Moritz Schulte ++ ++ * secmem.c (DEFAULT_PAGESIZE): New symbol. ++ (init_pool): Use DEFAULT_PAGESIZE. ++ ++2003-02-23 Moritz Schulte ++ ++ * secmem.h: Fix typo in declaration of _gcry_secmem_term. ++ ++ * sexp.c: Move macro definitions of `digitp', `octdigit', `alphap' ++ and `hexdigit' ... ++ * g10lib.h: ... here. ++ ++ * misc.c (_gcry_burn_stack): New function (former name: ++ burn_stack). ++ ++ * g10lib.h (burn_stack): Declare _gcry_burn_stack(). ++ ++2003-01-24 Werner Koch ++ ++ * global.c (gcry_set_progress_handler): Register a random progress ++ handler. ++ ++2003-01-23 Werner Koch ++ ++ * gcrypt.h (GCRY_ENABLE_QUICK_RANDOM): New. ++ * global.c (gcry_control): Make use of it. ++ ++2003-01-21 Werner Koch ++ ++ * gcrypt.h (gcry_random_add_bytes): Add QUALITY argument. ++ ++2003-01-21 Timo Schulz ++ ++ * gcrypt.h (gcry_random_add_bytes): New. ++ ++2003-01-20 Simon Josefsson ++ ++ * gcrypt.h (gcry_md_algos): Add GCRY_MD_CRC32, ++ GCRY_MD_CRC32_RFC1510, GCRY_MD_CRC24_RFC2440. ++ ++2003-01-16 Werner Koch ++ ++ * gcrypt.h (gcry_md_write): Changed type of 2nd argument to void*. ++ (gcry_md_hash_buffer): Changed type of both buffers to void*. ++ (gcry_md_setkey): Changed type of 2nd argument to void*. ++ (gcry_md_get_asnoid): New. ++ ++2003-01-15 Werner Koch ++ ++ * sexp.c (gcry_sexp_length): Fixed. This was seriously broken. ++ ++2003-01-14 Werner Koch ++ ++ * gcrypt.h (GCRYERR_INV_FLAG), global.c (gcry_strerror): New. ++ ++2003-01-02 Werner Koch ++ ++ * libgcrypt.vers: Temporary export _gcry_generate_elg_prime for ++ use by GNUTLS. ++ ++2002-12-21 Werner Koch ++ ++ * gcrypt.h: Make use of gcc's pure and malloc attributes ++ (gcry_md_putc): Use a helper variable to avoid multiple ++ evaluation of H. ++ * g10lib.h, stdmem.h, secmem.h: Use gcc attributes pure and malloc. ++ ++ * stdmem.c (use_m_guard): Don't default to yes. ++ ++2002-12-19 Werner Koch ++ ++ * global.c (global_init): The meat was never run due to a faulty ++ check. Thanks to Nikos for pointing this out. ++ ++ * global.c (gcry_control): Return 1 and not -1 for the ++ initialization tests. ++ ++ * libgcrypt.vers: New. ++ * Makefile.am: Use this instead of the build symbol file. ++ ++ * global.c (gcry_control) : Call the random module ++ initializer to make sure that the pool lock flag has been ++ initialized. ++ ++2002-12-09 Werner Koch ++ ++ * global.c (gcry_calloc,gcry_calloc_secure): Check for overflow. ++ Noted by Florian Weimer. ++ ++2002-11-10 Simon Josefsson ++ ++ * gcrypt.h (gcry_ctl_cmds): New GCRYCTL_SET_CBC_CTS control flag. ++ (gcry_cipher_flags): New GCRY_CIPHER_CBC_CTS gcry_cipher_open() flag. ++ (gcry_cipher_cts): New macro for toggling CTS. ++ ++2002-11-10 Werner Koch ++ ++ * gcrypt.h (GCRY_MD_MD4): New. We use a non OpenPGP value here. ++ ++2002-09-20 Werner Koch ++ ++ * ath.c: Include sys.time.h if sys/select.h does not exist. ++ (ath_select, ath_waitpid): Shortcut for Windows. ++ * ath.h: Include some Windows headers. By Timo. ++ ++2002-09-18 Werner Koch ++ ++ * ath.h: Prefix ath_deinit. ++ ++2002-09-17 Werner Koch ++ ++ * benchmark.c: New. ++ (mpi_bench, do_powm): Add a a simple test for RSA. ++ ++ * global.c (global_init): New. Use it instead of the setting ++ any_init_done. Initialize the ATH system. ++ (gcry_check_version): Hook global_init in. This is the suggested ++ way to initialize the library. ++ (_gcry_no_internal_locking): Removed. We simply call a ath_deinit ++ and leave it to ATH to disbale the locking. ++ ++ * ath.c, ath.h, ath-pth.c, ath-pthread.c: New. Taken from GPGME. ++ * mutex.h: Removed. ++ * Makefile.am (ath_components): New. ++ ++2002-09-16 Werner Koch ++ ++ * secmem.c (_gcry_secmem_dump_stats): Replaced fprintf by log_*. ++ ++2002-08-23 Werner Koch ++ ++ * missing-string.c: Removed unneeded strlwr. ++ ++ * libgcrypt.m4: Made much more simple. ++ * libgcrypt-config.in: Made --prefix work for --libs. ++ ++2002-08-14 Werner Koch ++ ++ * gcrypt.h: Add GCRY_CIPGER_DES. Included string.h for size_t. ++ Suggested by Simon Josefsson. ++ ++2002-07-25 Werner Koch ++ ++ * cipher.h: Added prototypes for progress functions. ++ * global.c: Include cipher.h for those prototypes. ++ ++ * stdmem.c (_gcry_private_realloc): Replaced void* by char * for ++ pointer arithmetic reasons. Noted by Stephan Austermuehle. ++ ++2002-06-24 Werner Koch ++ ++ * missing-string.c: Include ctype.h. ++ ++ * gcrypt.h (gcry_mpi_invm, gcry_mpi_div, gcry_mpi_mod) ++ (gcry_mpi_swap): New. ++ ++2002-06-18 Werner Koch ++ ++ * gcrypt.h: Added a bunch of brief function descriptions. ++ ++2002-05-21 Werner Koch ++ ++ * misc.c (_gcry_log_printf): Don't initialize a va_list. Noted by ++ Jeff Johnson. ++ ++ * global.c (gcry_set_progress_handler): New. ++ ++ * gcrypt.h: Replaced the typedef for byte. ++ ++2002-05-16 Werner Koch ++ ++ * missing-string.c: New. ++ ++ * gcrypt.h: Add new error codes GCRYERR_SEXP_ and typedefs ++ GcryMPI, GcrySexp, GcryCipherHd, GcryMDHd as aliases for the old ++ ones using an underscore. ++ ++ * global.c (gcry_strerror): Add strings fro the new error codes. ++ * sexp.c (gcry_sexp_canon_len): Use a macro to convert from new to ++ old error codes. ++ (gcry_sexp_create,gcry_sexp_new): New. ++ ++2002-05-15 Werner Koch ++ ++ * mutex.h (DEFINE_LOCAL_MUTEX): Macro to define a mutex and ++ initialize it so that we can detect an unitialized mutex and don't ++ read from stdin. ++ ++2002-05-14 Werner Koch ++ ++ Changed license of all files to the LGPL. ++ ++2002-05-07 Werner Koch ++ ++ * global.c (gcry_control): Add commands ++ GCRYCTL_ANY_INITIALIZATION_P and GCRYCTL_INITIALIZATION_FINISHED_P ++ so that other libraries are able to check for required ++ initializations. ++ ++2002-05-02 Werner Koch ++ ++ * gcrypt.h (GCRYCTL_DISABLE_INTERNAL_LOCKING): New. ++ * global.c (gcry_control): Implement it. ++ (_gcry_no_internal_locking): New. ++ * mutex.h: Prefixed all fucntions with _gcry_. Bypass all ++ functions when desired. ++ ++ * gcrypt.h (GCRYCTL_DISABLE_SECMEM): New. ++ * global.c (gcry_control,gcry_malloc_secure,gcry_is_secure): ++ Implement it here. ++ * secmem.c (_gcry_private_is_secure): Return false if the pool is ++ not initialized. ++ ++ * gcrypt.h (GCRYCTL_INITIALIZATION_FINISHED): New. ++ ++ * gcrypt.h (gcry_cipher_algos): Replaced RINDAEL by AES and change ++ the macros to expand from rijdael to aes. ++ ++ * stdmem.c (_gcry_private_malloc): Return NULL for 0 byte allocation. ++ (_gcry_private_malloc_secure): Ditto. ++ ++ * g10lib.h: Copied the JNLIB_GCC macros from ../jnlib/mischelp.h ++ and removed the inclusion of that file. ++ ++2002-04-15 Werner Koch ++ ++ * global.c (gcry_strdup): New. ++ ++2002-03-18 Werner Koch ++ ++ * mutex.h: New file with a portable thread mutex implementation ++ written by Marcus Brinkmann. Taken from GPGME. ++ ++2002-02-18 Werner Koch ++ ++ * sexp.c (gcry_sexp_sscan): Don't initialize the dummy ++ variable. Suggested by Jordi Mallach. ++ ++2002-01-31 Werner Koch ++ ++ * sexp.c (suitable_encoding,convert_to_hex,convert_to_string) ++ (convert_to_token): New. ++ (gcry_sexp_sprint): Better formatting of advanced encoding, does ++ now insert LFs and escapes all unprintable characters. ++ (unquote_string): New. ++ (sexp_sscan): Implemented the missing conversion of quoted strings. ++ ++2002-01-26 Werner Koch ++ ++ * libgcrypt-config.in: Add copyright notice. ++ ++2002-01-11 Werner Koch ++ ++ * sexp.c (gcry_sexp_canon_len): Fixed last change. ++ ++2002-01-01 Timo Schulz ++ ++ * stdmem.c (_gcry_private_realloc): If pointer is NULL now realloc ++ behaves like malloc. ++ ++2001-12-20 Werner Koch ++ ++ * sexp.c (gcry_sexp_canon_len): Describe the error codes and ++ return an error if this is not a S-Exp; i.e. it does not start ++ with an open parenthesis. ++ ++2001-12-18 Werner Koch ++ ++ * sexp.c (gcry_sexp_canon_len): Fixed the test on NULL buffer. ++ ++ * Makefile.am (DISTCLEANFILES): Include libgcrypt.sym ++ ++ * sexp.c: Removed the commented test code because we now have a ++ test in ../tests/ ++ ++2001-12-17 Werner Koch ++ ++ * sexp.c (gcry_sexp_canon_len): New. ++ ++2001-12-11 Werner Koch ++ ++ * gcrypt.h: Fixed AES128 macro, add enum for OFB mode. ++ ++2001-12-05 Werner Koch ++ ++ * misc.c (_gcry_log_printf): New. ++ * sexp.c (dump_string,gcry_sexp_dump): Use logging functions ++ instead of stderr. ++ ++2001-11-16 Werner Koch ++ ++ * gcrypt.h: New constant GCRYCTL_IS_ALGO_ENABLED. ++ ++2001-10-02 Werner Koch ++ ++ * gcrypt.h: Removed a couple of trailing commas. ++ ++2001-08-28 Werner Koch ++ ++ * sexp.c (sexp_sscan): Add an argument to enable the ++ arg_ptr. Changed all callers. Suggested by Tom Holroyd. ++ ++2001-08-03 Werner Koch ++ ++ * global.c (gcry_strerror): Updated list of error codes. ++ ++2001-07-23 Werner Koch ++ ++ * gcrypt.h: Replaced the last ulong. Noted by Rami Lehti. ++ ++2001-05-31 Werner Koch ++ ++ * gcrypt.h, mpi.h: Made some mpi functions public. ++ ++ * wrapper.c: Removed. ++ * global.c: Renamed all g10_ prefixed functions which had wrappers ++ to gcry_xxx. So we now use the exported memory functions inernally. ++ ++ Renamed all g10_ prefixed functions to _gcry_ prefixed ones. ++ ++ * g10lib.h (_GCRYPT_IN_LIBGCRYPT): Replace defintion by a test on it. ++ ++2001-05-28 Werner Koch ++ ++ * libgcrypt.m4: Check GCRYPT_VERSION macro and not LIBGCRYPT_VERSION. ++ ++ * mpi.h: Removed mpi_fromstr prototype. ++ ++2001-01-11 Werner Koch ++ ++ * Makefile.am (libgcrypt_la_SOURCES): Add mpi.h ++ ++2000-12-19 Werner Koch ++ ++ * types.h: Moved from ../include to here. ++ ++ Major change: ++ Removed all GnuPG stuff and renamed this piece of software ++ to gcrypt. ++ ++2000-11-14 Werner Koch ++ ++ * mpi.h: Moved to ../mpi. ++ ++ * Makefile.am (OMIT_DEPENDENCIES): Hack to work around dependency ++ problems. ++ ++2000-10-11 Werner Koch ++ ++ * mpi.h: Changed the way mpi_limb_t is defined. ++ ++2000-10-10 Werner Koch ++ ++ * Makefile.am: Take version-info from configure. ++ ++2000-10-09 Werner Koch ++ ++ * gcrypt.h: New cipher mode, new algo Arcfour and new error code ++ GCRYERR_INV_CIPHER_MODE. ++ * global.c (gcry_strerror): New errorcode. ++ ++Wed Oct 4 13:16:18 CEST 2000 Werner Koch ++ ++ * gcrypt.h (gcry_md_setkey): Replaced macro by function prototype. ++ ++Mon Sep 18 16:35:45 CEST 2000 Werner Koch ++ ++ * gcrypt.h (GCRYCTL_GET_ALGO_USAGE): New. ++ ++ * secmem.c (secmem_realloc): check for failed secmem_malloc. By ++ Matt Kraai. ++ ++Mon Jul 31 10:04:47 CEST 2000 Werner Koch ++ ++ * sexp.c: Removed the datalen fields from list tags. ++ (gcry_sexp_car_data,gcry_sexp_cdr_data,gcry_sexp_car_mpi, ++ gcry_sexp_cdr_mpi): Removed. ++ (gcry_sexp_nth,gcry_sexp_nth_data,gcry_sexp_nth_mpi): New. ++ ++Fri Jul 28 18:19:11 CEST 2000 Werner Koch ++ ++ * sexp.c (sexp_sscan): Fixed reallocation to secure memory. ++ (new_empty_list): Removed ++ (gcry_sexp_length): New. ++ (gcry_sexp_enum): Removed. ++ (normalize): New. Reworked the whole thing to use NULL for an empty list. ++ (make_space): New instead of the macro. ++ ++Tue Jul 25 17:44:15 CEST 2000 Werner Koch ++ ++ * sexp.c: Major rewrite. ++ (gcry_sexp_sscan): Reordered arguments. Moved functionality to .. ++ (sexp_sscan): .. this. ++ (gcry_sexp_build): New. ++ (gcry_sexp_new_name_mpi, gcry_sexp_new_name_data, gcry_sexp_new_data, ++ gcry_sexp_new_mpi): Removed. ++ ++Fri Jul 14 19:38:23 CEST 2000 Werner Koch ++ ++ * gcrypt.h (gcry_md_start_debug, gcry_md_stop_debug): New. ++ (gcry_ctl_cmds): New control values ++ ++ * sexp.c (gcry_sexp_sscan): Add hex format parsing. ++ ++ * secmem.c (lock_pool): Check for ENOSYS return my mlock() on old SCOs. ++ (pool_is_mmapped): Made volatile. ++ (lock_pool): No more warning for QNX. By Sam Roberts. ++ (lock_pool,secmem_init): Additional check for dropped privs. ++ ++2000-03-21 09:18:48 Werner Koch (wk@habibti.gnupg.de) ++ ++ * gcrypt.h (gcry_md_setkey): New. ++ (GCRY_MD_FLAG_HMAC): New. ++ ++Mon Jan 31 16:37:34 CET 2000 Werner Koch ++ ++ * Makefile.am: Add g10lib.h ++ ++Thu Jan 27 18:00:44 CET 2000 Werner Koch ++ ++ * sexp.c (gcry_sexp_sscan): Allow NULL for erroff. ++ ++Mon Jan 24 22:24:38 CET 2000 Werner Koch ++ ++ * sexp.c (gcry_sexp_alist): New. ++ ++Mon Jan 24 13:04:28 CET 2000 Werner Koch ++ ++ * secmem.c: Moved from ../util to here. ++ * secmem.h: New. ++ * stdmem.c: New. Based on the old ../util/memory.c. ++ * stdmem.h: New. ++ ++Wed Dec 8 21:58:32 CET 1999 Werner Koch ++ ++ * gcrypt.m4: New. ++ * gcrypt-config: New. ++ ++ * mpi.h (mpi_get_nbit_info): Removed ++ (mpi_set_nbit_info): Removed. ++ (struct gcry_mpi): Removed the nbits field. ++ ++ * misc.c (g10_log_verbosity): New. ++ ++ * global.c (g10_xstrdup): New. ++ ++ * mpiapi.c: Removed. ++ ++ * mpi.h: Moved from ../include to here. Removed some obsolete ++ prototypes and the iobuf.h header. ++ * cipher.h: Moved from ../include to here. Removed the mpi.h header. ++ * g10lib.h: Moved from ../include to here. ++ ++Fri Nov 19 17:15:20 CET 1999 Werner Koch ++ ++ * sexp.c (dump_string): New. Taken from gnupg/util/miscutil.c. ++ (do_dump_list): s/print_string/dump_string/. ++ ++ * testapi.c: New. ++ ++ * mpiapi.c (gcry_mpi_randomize): Use new random API. ++ ++Sat Nov 13 17:44:23 CET 1999 Werner Koch ++ ++ * gloabl.c (gcry_control): Add cases for dumping random ++ and secmem stats. ++ ++Tue Oct 26 14:10:21 CEST 1999 Werner Koch ++ ++ * pkapi.c: Removed. ++ ++ * symapi.c: Removed. ++ ++ * g10lib.h: Moved to ../include. ++ ++ * mdapi.c: Removed. ++ ++Wed Jul 7 13:08:40 CEST 1999 Werner Koch ++ ++ * sexp.c: New. ++ ++Tue Dec 8 13:15:16 CET 1998 Werner Koch ++ ++ * gcrypt.h: New ++ * mpiapi.c: New ++ ++ ++ Copyright (C) 1998,1999,2000,2001,2002,2003 ++ 2004,2005,2008,2009,2011 Free Software Foundation, Inc. ++ ++ This file is free software; as a special exception the author gives ++ unlimited permission to copy and/or distribute it, with or without ++ modifications, as long as this notice is preserved. ++ ++ This file 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. ++ ++Local Variables: ++buffer-read-only: t ++End: +diff --git a/grub-core/lib/libgcrypt/src/Makefile.am b/grub-core/lib/libgcrypt/src/Makefile.am +new file mode 100644 +index 0000000..2a07067 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/src/Makefile.am +@@ -0,0 +1,143 @@ ++# Makefile.am - for gcrypt/src ++# Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, ++# 2006, 2007 Free Software Foundation, Inc. ++# ++# This file is part of Libgcrypt. ++# ++# Libgcrypt is free software; you can redistribute it and/or modify ++# it under the terms of the GNU Lesser General Public License as ++# published by the Free Software Foundation; either version 2.1 of ++# the License, or (at your option) any later version. ++# ++# Libgcrypt 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 Lesser 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 . ++ ++ ++## Process this file with automake to produce Makefile.in ++ ++EXTRA_DIST = Manifest libgcrypt-config.in libgcrypt.m4 libgcrypt.vers \ ++ gcrypt.h.in libgcrypt.def ++ ++bin_SCRIPTS = libgcrypt-config ++m4datadir = $(datadir)/aclocal ++m4data_DATA = libgcrypt.m4 ++include_HEADERS = gcrypt.h ++ ++lib_LTLIBRARIES = libgcrypt.la ++bin_PROGRAMS = dumpsexp hmac256 ++if USE_RANDOM_DAEMON ++sbin_PROGRAMS = gcryptrnd ++bin_PROGRAMS += getrandom ++endif USE_RANDOM_DAEMON ++ ++# Depending on the architecture some targets require libgpg-error. ++if HAVE_W32CE_SYSTEM ++arch_gpg_error_cflags = $(GPG_ERROR_CFLAGS) ++arch_gpg_error_libs = $(GPG_ERROR_LIBS) ++else ++arch_gpg_error_cflags = ++arch_gpg_error_libs = ++endif ++ ++ ++if HAVE_LD_VERSION_SCRIPT ++ libgcrypt_version_script_cmd = -Wl,--version-script=$(srcdir)/libgcrypt.vers ++else ++ libgcrypt_version_script_cmd = ++endif ++ ++libgcrypt_la_CFLAGS = $(GPG_ERROR_CFLAGS) ++libgcrypt_la_SOURCES = g10lib.h visibility.c visibility.h types.h \ ++ cipher.h cipher-proto.h gcrypt-module.h \ ++ misc.c global.c sexp.c hwfeatures.c \ ++ stdmem.c stdmem.h secmem.c secmem.h \ ++ mpi.h missing-string.c module.c fips.c \ ++ hmac256.c hmac256.h \ ++ ath.h ath.c ++ ++if HAVE_W32_SYSTEM ++ ++RCCOMPILE = $(RC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ ++ $(libgcrypt_la_CPPFLAGS) $(AM_CPPFLAGS) $(CPPFLAGS) ++LTRCCOMPILE = $(LIBTOOL) --mode=compile --tag=RC $(RCCOMPILE) ++ ++SUFFIXES = .rc .lo ++ ++.rc.lo: ++ $(LTRCCOMPILE) -i "$<" -o "$@" ++ ++gcrypt_res = versioninfo.lo ++no_undefined = -no-undefined ++export_symbols = -export-symbols $(srcdir)/libgcrypt.def ++ ++install-def-file: ++ $(INSTALL) $(srcdir)/libgcrypt.def $(DESTDIR)$(libdir)/libgcrypt.def ++ ++uninstall-def-file: ++ -rm $(DESTDIR)$(libdir)/libgcrypt.def ++ ++gcrypt_deps = $(gcrypt_res) libgcrypt.def ++ ++else !HAVE_W32_SYSTEM ++ ++gcrypt_res = ++gcrypt_res_ldflag = ++no_undefined = ++export_symbols = ++install-def-file: ++uninstall-def-file: ++ ++gcrypt_deps = ++ ++endif !HAVE_W32_SYSTEM ++ ++ ++libgcrypt_la_LDFLAGS = $(no_undefined) $(export_symbols) \ ++ $(libgcrypt_version_script_cmd) -version-info \ ++ @LIBGCRYPT_LT_CURRENT@:@LIBGCRYPT_LT_REVISION@:@LIBGCRYPT_LT_AGE@ ++libgcrypt_la_DEPENDENCIES = \ ++ ../cipher/libcipher.la \ ++ ../random/librandom.la \ ++ ../mpi/libmpi.la \ ++ ../compat/libcompat.la \ ++ $(srcdir)/libgcrypt.vers $(gcrypt_deps) ++libgcrypt_la_LIBADD = $(gcrypt_res) \ ++ ../cipher/libcipher.la \ ++ ../random/librandom.la \ ++ ../mpi/libmpi.la \ ++ ../compat/libcompat.la $(GPG_ERROR_LIBS) ++ ++ ++dumpsexp_SOURCES = dumpsexp.c ++dumpsexp_CFLAGS = $(arch_gpg_error_cflags) ++dumpsexp_LDADD = $(arch_gpg_error_libs) ++ ++hmac256_SOURCES = hmac256.c ++hmac256_CFLAGS = -DSTANDALONE $(arch_gpg_error_cflags) ++hmac256_LDADD = $(arch_gpg_error_libs) ++ ++if USE_RANDOM_DAEMON ++gcryptrnd_SOURCES = gcryptrnd.c ++gcryptrnd_CFLAGS = $(GPG_ERROR_CFLAGS) $(PTH_CFLAGS) ++gcryptrnd_LDADD = libgcrypt.la $(GPG_ERROR_LIBS) $(PTH_LIBS) ++ ++getrandom_SOURCES = getrandom.c ++endif USE_RANDOM_DAEMON ++ ++ ++install-data-local: install-def-file ++ ++uninstall-local: uninstall-def-file ++ ++# FIXME: We need to figure out how to get the actual name (parsing ++# libgcrypt.la?) and how to create the hmac file already at link time ++# so that it can be used without installing libgcrypt first. ++#install-exec-hook: ++# ./hmac256 "What am I, a doctor or a moonshuttle conductor?" \ ++# < $(DESTDIR)$(libdir)/libgcrypt.so.11.5.0 \ ++# > $(DESTDIR)$(libdir)/.libgcrypt.so.11.5.0.hmac +diff --git a/grub-core/lib/libgcrypt/src/Manifest b/grub-core/lib/libgcrypt/src/Manifest +new file mode 100644 +index 0000000..2d003d8 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/src/Manifest +@@ -0,0 +1,58 @@ ++# Manifest - checksums of the src directory ++# Copyright 2004 Free Software Foundation, Inc. ++# ++# This file is part of Libgcrypt. ++# ++# Libgcrypt is free software; you can redistribute it and/or modify ++# it under the terms of the GNU Lesser general Public License as ++# published by the Free Software Foundation; either version 2.1 of ++# the License, or (at your option) any later version. ++# ++# Libgcrypt 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 Lesser General Public License for more details. ++# ++# You should have received a copy of the GNU Lesser General Public ++# License along with this program; if not, write to the Free Software ++# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ ++# Checksums for all source files in this directory. Format is ++# filename, blanks, base-64 part of an OpenPGP detached signature ++# without the header lines. Blank lines and lines beginning with a ++# hash mark are ignored. A tool to process this file is available by ++# cvs -d :pserver:anoncvs@cvs.gnupg.org:/cvs/wk co misc-scripts/manifest-tool ++# ++# The special entry "$names$" holds a signature over all sorted ++# filenames excluding itself. ++ ++gcrypt.h iQCVAwUAQH5RsTEAnp832S/7AQK7xgP+Kc3NY9lipZkaAMrnHDkQVLdHYwTbZWuGOYdTLp8Xy7Auh9wtWV9hrWVUqs+kxDzT/2iF6XkO3WT3rf/PmQ/Q0TIGfOyjE3c/qvB/jVippaxoGda3tnGpODytdI3XPhfPS0Ss8nDzfCStPBGAEq0OVU7imnExrFzhRXt+Gljr0o0==Yagz ++gcrypt-module.h iQCVAwUAQH5UXzEAnp832S/7AQJMQgQAzumz9aaZelhw+FxTCeVadphBxt1bbNQvMrnddYYblyJv+AcxZ9ZxGz2oPeusN58Qg54DQcaW3lYhTgnWfXultsi+Ruxlz7400OUrzSXOl3At7KssdODAoscFzZIgh94G9lzQxEBr9lTXI9R3LsPFJP6muNG4frcNBAA42yckK7w==BBp5 ++ ++ath.c iQCVAwUAQH5E+DEAnp832S/7AQKFpgP+KSZHtVcnh9FFggIyHKbALUljW2FXauasZvFyN8Sk/mIMgKxyXFOG1THBAUzWLaKWIEWU+WkYU7uThqBtpnEImM5AenWzbQuJjftPC3gVHO8yjjmBWD4zmJj28htoKDoa/xDsoqumrHxae3FYcaCWtYGVjM/Pbl+OMRMOFAhp0ho==lQZ3 ++ath.h iQCVAwUAQH5FODEAnp832S/7AQKiuQQAg4K+KOAn1LWBZN32MAhms4FeZKoce0fAuZW7BpyY4cCxIVgxqrtUC90CDykw8XegFfOyyYrgd0NmaMVdY7HZDncNOvIPxpgFQPCZrycsMOoAtoVwjK704RDeNo3zmeyxTKeDH+3M1J7JmLiafaEdSbOC8flX/W0icaV0Ol4dmBc==Ll6w ++ ++cipher.h iQCVAwUAQH5FUzEAnp832S/7AQJKLgP9GSSk9f7EINIRqSQH1XKX+dYzt3phDHdqFTUGIfYNh7YzGdy0drvgFhG4k15nqDouKRuFVM/hKY3ZVY7JccmKXKGAH6+ZYShoG6LMFfIGgDX8zne0dNxc72PLfns3fVxNn/RlHmHBkrQ+ppjR9HnSthFmOqzbQaW1BKmc3Z2x5GU==lIeW ++g10lib.h iQCVAwUAQH5FejEAnp832S/7AQJ75wP/ZjOybwRix5eoXdfVeXPjoPygejzpYJJdMUGN3Y5UtkfBu9mPREsKfvZ6tH+Evjx+3xfeAb4bU/k2mRMp0tiWnk2koToS08vI9uxnioKQr9oulZH6r28S+NLSgMQuEGN1JNUky6RQ9TTNRndeTjKKSrEjZ7V6bv+rb8A1bYCKChs==P5mk ++mpi.h iQCVAwUAQH5FwzEAnp832S/7AQJJ4wP9E3jVkcO9M0YtSBHIbjG3hDWKWXzi86AlUh51qiE8/2XP0FfjA4TosyvmicZs7j48HitAByr9tHOSxnbeo7NBf17ICwAo6Eqty+wKDg+eyLeEGUy7VpVK3RJRQAA4H+kl3S2l3YMTKf3WJlbc7qkWSXZspdy5c9sAxeodCKrAubU==oALf ++ ++global.c iQCVAwUAQH5HFzEAnp832S/7AQJc+QQAvi53ZkMCzLnVULHvhI6W+EX537zi9n8cplYguvIJqUhAZrP68yGAIyqyCONbZVDyB7wqeXdUMLzMk7W8fg+xuk5JSDpppAQf2m/bdQyze6XVqJso682eYBM8+b9z/IVEvLaFwhZcOKO1bcXudBlBCcJgVDpupfTtAWgPnewil9Q==Xwy1 ++misc.c iQCVAwUAQH5IIjEAnp832S/7AQKNJAQAkEpyY3fCG7tvADJFAW9xA7DEQwLCa8YmiUhHvrEsWOI4YgvS7LUbWWc7VqK+ryORvXLKRAVieznbnHAuy0TKtqdnmA/kUmiurS0ah5SWqR/iuAeJtt0RGsmZaZ6oa2m4PZ2Y2GCHSTZqcclvwsetS9eq5AipxHxYFUltu5wGZNI==twM2 ++missing-string.c iQCVAwUAQH5JfjEAnp832S/7AQI3ZQQAg55eEJbGQQHyBEJGxvt/FXpQiXcoDit3ZHzvdaQn/NUgdLjCHiWVzhyCXACGivLWMNModDaSaZk073NXxVkWfPcX9vkF//Wugwzidd5P3Bfu5k35o+Xxz82fsk5KuFGGq1mBUZ07xUYQ8KkKkhADUkr0QiQAuypp079Yq0uUC7Q==zvKn ++module.c iQCVAwUAQH5JvjEAnp832S/7AQKlMgQAjZYTXMpWb5kHxCMXzRi069Ku/4/xnWsD+S0dje1LiKzCnRpwTTxARzc/y10Y8OcygkMuR4unEaWedO+9syjjty3fBCcue/j7YlLitq5EC9UE4o23poWvWCuX9Tadm2DK5qf4p7smMJ22O22cLTYTVCyAoYTQ2xC8ajzBsBRkX80==yRRD ++secmem.c iQCVAwUAQH5LLDEAnp832S/7AQKtFwQAwY2wBr6WJC1cwqp/1DQoKzHx9C3plONxbZMazwR7VMI83NUbBAbv1mcxpeZWXmb2dRrnsR1VBbNPDSbJLN5T6czLQ2nIb6mnq9u8Ip4SAa+GCWfDV4AUtAJ4hN/yvWo8iEKu+KD5iJ6xJh31NdXjt5yk6vnk46SA6R4FkHdIEXc==UKVr ++secmem.h iQCVAwUAQH5LTDEAnp832S/7AQIsJwQAkZUu4hvmh9NXCLNm98+tGZFzWYvZO/NffC2wdPE8Q/OTa/m3g+oBbEhaV1ze3oY4t1F/p7ZHFx5CsIp4zVjyPkxlni8AAVMUOQr/LopyxouHn2OjKO+dVqecWQf01+nPWjklbL2FZ3mQ99k2qeWZlVSkz0nm8u39F3v7z3OTCss==AJqE ++sexp.c iQCVAwUAQH5LojEAnp832S/7AQKCTQQArlrj1KGwR2x93fcyN3M0iXuGkBq5R9KNu+1Bq04G4SLlpZ1RRY0OjV3L9To1BHTd01lXlO8MNz7NpRxWlG1Sw5FohbBlhWZQRcW8GdAawJPcfIY2Y8Ek6Yx8quZKbk9uD3bcBmStmg0P+TIA0nr20bmtfB3uX2KQVHQqWZQT5qU==P8FE ++stdmem.c iQCVAwUAQH5LzjEAnp832S/7AQLOUAP9FU16itXBBrkfRDGmhUjAOeEEKdd+brQ3XdT8xoLvP/IH/6U1Kq3ampP2/xcL4kwVdz2rw6NRzP7jlL/yM3tW722lSS/JPJkH+2+qUkcb0fYNoql/WYPMYp1/Mzu6ttXnjag1cQGlKIyYAD+G6h3FtpLwQy0hEJopnF9+Ovd8U7A==CkiZ ++stdmem.h iQCVAwUAQH5L8jEAnp832S/7AQIH0wP+Lyqh0tj++s2L79Tmf/gqgCK+HLMxTddcewF3XbsYf9T5FmLez1gz6Ggti4Ss9VjozOA3ti3trCiA/YNRmV9AYw4zLUPm+MsjJuveL/AgB9HdoD2v+RfJm0WwgSKiysp+8iyjg3Plopmhba4cGuOP5MJ3CWTqYwPmJVscUKC6g38==02MN ++ ++types.h iQCVAwUAQH5MKTEAnp832S/7AQLqTAP6A3mUMD5MMkBkebq4bRY6Bq0KsgdKfZ8TLhc2o87gFay8YD0Uom3YJNG2LF/rAIct2ih4jYJaIb5dRfJ0KJoPi2ETd462J8OFCL4fjq9TaSjB2pXcB+kWoxzPasGNg2Ukk0dQ6lvF1tSYrtt32PVI7q/UaPsjTylgRmzLfX/VxrU==OMu3 ++ ++ ++# Configuration ++Makefile.am iQCVAwUAQH5WVjEAnp832S/7AQLmsQP/bbI8/UWAC5yITVhGcCOCbN/FaMqXVKjxESzo6GTs02jxK1y3RuuaoNU1ssQZGAxpFiMJW8u933V3yTHFMxWpwHemDnEyv/a8YACxJBQ0tQgpgHS716BjMbHOfcuOis2WlCOOm0ErjhAYNa4NQ1q3jwkOvTDLFpdnqaWI2wWn08U==Yjun ++libgcrypt.m4 iQCVAwUAQH5MbTEAnp832S/7AQJ1uAQA1C6xI7qXiKVtUeXawhPytAldosrzcXmqz34xi7JklQqw83d68WtWHFMBEUa7MKfi4WCbuQb7FjGUvMRw5z/T9ez7CoDekHc63+cIIZLQ23weUK8GaA1uQLoD0scmT41J5RkBlJbH7ck1zRd3d04o75rWNEUNit6KBvrQ4Pd8oQ8==uMgB ++libgcrypt-config.in iQCVAwUAQH5UbzEAnp832S/7AQJISgP+Nbd2AQnDM/k8sQLbvz8YZjwX3LigZM+AkF1VAwyAm6YOU3nrXnz5t+cXkQD2dkz4L2F0AAsIkFiJsrgmZgCp2h1L6LeFnH+hoId9RhbYw4NkDaHb+MC9JcalpcfFvvxq6vM/W37bSFimM78P+5RLKypXCytVQNAAaIRgZjVfXY8==IGDS ++libgcrypt.vers iQCVAwUAQH5MjTEAnp832S/7AQKCdQQAotG6Z3zdcePI0V33YY2sh91uYkLBNhQw+PzyE3BRRAVhMGLOBD1nSWJHJvE3eyCVOqFY0ZmvpVex51Fa0D/TwsJOO4RVxf1L9bbAncu9OuEXaGXKytLZp54TliDTAWGDq0lvtx1TvDDgtM8TbbaXvMbjfQ4wXBxdLvaenFCTlR4==kgHq ++ ++$names$ iQCVAwUAQH5UhDEAnp832S/7AQK/jwP9H7A3mI99M1NGuhD+16C+2gJIITB8GJeYeUd3vm8kWQ5n76WyMCdeA62qn0JUddIBjAbagtfvTL5aesnD9MlhEGaNlHauU7SINTIJ8njKf87EAAfDZrhS/tGDziC2nakMPweRxXQCLDWHkBPjYfrspSLLohjdegqBvTNyVM76+KE==3p9Z +diff --git a/grub-core/lib/libgcrypt/src/ath.c b/grub-core/lib/libgcrypt/src/ath.c +new file mode 100644 +index 0000000..4834a52 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/src/ath.c +@@ -0,0 +1,323 @@ ++/* ath.c - A Thread-safeness library. ++ * Copyright (C) 2002, 2003, 2004, 2011 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser general Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, see . ++ */ ++ ++#ifdef HAVE_CONFIG_H ++#include ++#endif ++ ++#include ++#include ++#include ++#if USE_POSIX_THREADS_WEAK ++# include ++#endif ++ ++#include "ath.h" ++ ++ ++ ++/* On an ELF system it is easy to use pthreads using weak references. ++ Take care not to test the address of a weak referenced function we ++ actually use; some GCC versions have a bug were &foo != NULL is ++ always evaluated to true in PIC mode. USING_PTHREAD_AS_DEFAULT is ++ used by ath_install to detect the default usage of pthread. */ ++#if USE_POSIX_THREADS_WEAK ++# pragma weak pthread_cancel ++# pragma weak pthread_mutex_init ++# pragma weak pthread_mutex_lock ++# pragma weak pthread_mutex_unlock ++# pragma weak pthread_mutex_destroy ++#endif ++ ++/* For the dummy interface. The MUTEX_NOTINIT value is used to check ++ that a mutex has been initialized. Because its value is there is ++ no need to explicit initialized a mutex variable because it is ++ anyway static and we store a pointer to allocated memory there ++ after initialization. The same thing works with other thread ++ models. */ ++#define MUTEX_NOTINIT ((ath_mutex_t) 0) ++#define MUTEX_UNLOCKED ((ath_mutex_t) 1) ++#define MUTEX_LOCKED ((ath_mutex_t) 2) ++#define MUTEX_DESTROYED ((ath_mutex_t) 3) ++ ++ ++/* Return the thread type from the option field. */ ++#define GET_OPTION(a) ((a) & 0xff) ++ ++ ++ ++enum ath_thread_model { ++ ath_model_undefined = 0, ++ ath_model_none, /* No thread support. */ ++ ath_model_pthreads_weak, /* POSIX threads using weak symbols. */ ++ ath_model_pthreads, /* POSIX threads directly linked. */ ++ ath_model_w32 /* Microsoft Windows threads. */ ++}; ++ ++ ++/* The thread model in use. */ ++static enum ath_thread_model thread_model; ++ ++ ++/* Initialize the ath subsystem. This is called as part of the ++ Libgcrypt initialization. It's purpose is to initialize the ++ locking system. It returns 0 on sucess or an ERRNO value on error. ++ In the latter case it is not defined whether ERRNO was changed. ++ ++ Note: This should be called as early as possible because it is not ++ always possible to detect the thread model to use while already ++ running multi threaded. */ ++int ++ath_init (void) ++{ ++ int err = 0; ++ ++ if (thread_model) ++ return 0; /* Already initialized - no error. */ ++ ++ if (0) ++ ; ++#if USE_POSIX_THREADS_WEAK ++ else if (pthread_cancel) ++ { ++ thread_model = ath_model_pthreads_weak; ++ } ++#endif ++ else ++ { ++ /* Assume a single threaded application. */ ++ thread_model = ath_model_none; ++ } ++ ++ return err; ++} ++ ++ ++/* Return the used thread model as string for display purposes an if ++ R_MODEL is not null store its internal number at R_MODEL. */ ++const char * ++ath_get_model (int *r_model) ++{ ++ if (r_model) ++ *r_model = thread_model; ++ switch (thread_model) ++ { ++ case ath_model_undefined: return "undefined"; ++ case ath_model_none: return "none"; ++ case ath_model_pthreads_weak: return "pthread(weak)"; ++ case ath_model_pthreads: return "pthread"; ++ case ath_model_w32: return "w32"; ++ default: return "?"; ++ } ++} ++ ++ ++/* This function was used in old Libgcrypt versions (via ++ GCRYCTL_SET_THREAD_CBS) to register the thread callback functions. ++ It is not anymore required. However to allow existing code to ++ continue to work, we keep this function and check that no user ++ defined callbacks are used and that the requested thread system ++ matches the one Libgcrypt is using. */ ++gpg_err_code_t ++ath_install (struct ath_ops *ath_ops) ++{ ++ unsigned int thread_option; ++ ++ /* Check if the requested thread option is compatible to the ++ thread option we are already committed to. */ ++ thread_option = ath_ops? GET_OPTION (ath_ops->option) : 0; ++ ++ /* Return an error if the requested thread model does not match the ++ configured one. */ ++ if (0) ++ ; ++#if USE_POSIX_THREADS_WEAK ++ else if (thread_model == ath_model_pthreads_weak) ++ { ++ if (thread_option == ATH_THREAD_OPTION_PTHREAD) ++ return 0; /* Okay - compatible. */ ++ } ++#endif /*USE_POSIX_THREADS_WEAK*/ ++ else if (thread_option == ATH_THREAD_OPTION_DEFAULT) ++ return 0; /* No thread support requested. */ ++ ++ return GPG_ERR_NOT_SUPPORTED; ++} ++ ++ ++/* Initialize a new mutex. This function returns 0 on success or an ++ system error code (i.e. an ERRNO value). ERRNO may or may not be ++ changed on error. */ ++int ++ath_mutex_init (ath_mutex_t *lock) ++{ ++ int err; ++ ++ switch (thread_model) ++ { ++ case ath_model_none: ++ *lock = MUTEX_UNLOCKED; ++ err = 0; ++ break; ++ ++#if USE_POSIX_THREADS_WEAK ++ case ath_model_pthreads_weak: ++ { ++ pthread_mutex_t *plck; ++ ++ plck = malloc (sizeof *plck); ++ if (!plck) ++ err = errno? errno : ENOMEM; ++ else ++ { ++ err = pthread_mutex_init (plck, NULL); ++ if (err) ++ free (plck); ++ else ++ *lock = (void*)plck; ++ } ++ } ++ break; ++#endif /*USE_POSIX_THREADS_WEAK*/ ++ ++ default: ++ err = EINVAL; ++ break; ++ } ++ ++ return err; ++} ++ ++ ++/* Destroy a mutex. This function is a NOP if LOCK is NULL. If the ++ mutex is still locked it can't be destroyed and the function ++ returns EBUSY. ERRNO may or may not be changed on error. */ ++int ++ath_mutex_destroy (ath_mutex_t *lock) ++{ ++ int err; ++ ++ if (!*lock) ++ return 0; ++ ++ switch (thread_model) ++ { ++ case ath_model_none: ++ if (*lock != MUTEX_UNLOCKED) ++ err = EBUSY; ++ else ++ { ++ *lock = MUTEX_DESTROYED; ++ err = 0; ++ } ++ break; ++ ++#if USE_POSIX_THREADS_WEAK ++ case ath_model_pthreads_weak: ++ { ++ pthread_mutex_t *plck = (pthread_mutex_t*)lock; ++ ++ err = pthread_mutex_destroy (plck); ++ if (!err) ++ { ++ free (plck); ++ lock = NULL; ++ } ++ } ++ break; ++#endif /*USE_POSIX_THREADS_WEAK*/ ++ ++ default: ++ err = EINVAL; ++ break; ++ } ++ ++ return err; ++} ++ ++ ++/* Lock the mutex LOCK. On success the function returns 0; on error ++ an error code. ERRNO may or may not be changed on error. */ ++int ++ath_mutex_lock (ath_mutex_t *lock) ++{ ++ int err; ++ ++ switch (thread_model) ++ { ++ case ath_model_none: ++ if (*lock == MUTEX_NOTINIT) ++ err = EINVAL; ++ else if (*lock == MUTEX_UNLOCKED) ++ { ++ *lock = MUTEX_LOCKED; ++ err = 0; ++ } ++ else ++ err = EDEADLK; ++ break; ++ ++#if USE_POSIX_THREADS_WEAK ++ case ath_model_pthreads_weak: ++ err = pthread_mutex_lock ((pthread_mutex_t*)lock); ++ break; ++#endif /*USE_POSIX_THREADS_WEAK*/ ++ ++ default: ++ err = EINVAL; ++ break; ++ } ++ ++ return err; ++} ++ ++/* Unlock the mutex LOCK. On success the function returns 0; on error ++ an error code. ERRNO may or may not be changed on error. */ ++int ++ath_mutex_unlock (ath_mutex_t *lock) ++{ ++ int err; ++ ++ switch (thread_model) ++ { ++ case ath_model_none: ++ if (*lock == MUTEX_NOTINIT) ++ err = EINVAL; ++ else if (*lock == MUTEX_LOCKED) ++ { ++ *lock = MUTEX_UNLOCKED; ++ err = 0; ++ } ++ else ++ err = EPERM; ++ break; ++ ++#if USE_POSIX_THREADS_WEAK ++ case ath_model_pthreads_weak: ++ err = pthread_mutex_unlock ((pthread_mutex_t*)lock); ++ break; ++#endif /*USE_POSIX_THREADS_WEAK*/ ++ ++ default: ++ err = EINVAL; ++ break; ++ } ++ ++ return err; ++} +diff --git a/grub-core/lib/libgcrypt/src/ath.h b/grub-core/lib/libgcrypt/src/ath.h +new file mode 100644 +index 0000000..6ffa928 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/src/ath.h +@@ -0,0 +1,92 @@ ++/* ath.h - Thread-safeness library. ++ * Copyright (C) 2002, 2003, 2004, 2011 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser general Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, see . ++ */ ++ ++#ifndef ATH_H ++#define ATH_H ++ ++#include ++ ++#ifdef _WIN32 ++# include ++#else /* !_WIN32 */ ++# ifdef HAVE_SYS_SELECT_H ++# include ++# else ++# include ++# endif ++# include ++# ifdef HAVE_SYS_MSG_H ++# include /* (e.g. for zOS) */ ++# endif ++# include ++#endif /* !_WIN32 */ ++#include ++ ++ ++ ++/* Define _ATH_EXT_SYM_PREFIX if you want to give all external symbols ++ a prefix. */ ++#define _ATH_EXT_SYM_PREFIX _gcry_ ++ ++#ifdef _ATH_EXT_SYM_PREFIX ++#define _ATH_PREFIX1(x,y) x ## y ++#define _ATH_PREFIX2(x,y) _ATH_PREFIX1(x,y) ++#define _ATH_PREFIX(x) _ATH_PREFIX2(_ATH_EXT_SYM_PREFIX,x) ++#define ath_install _ATH_PREFIX(ath_install) ++#define ath_init _ATH_PREFIX(ath_init) ++#define ath_get_model _ATH_PREFIX(ath_get_model) ++#define ath_mutex_init _ATH_PREFIX(ath_mutex_init) ++#define ath_mutex_destroy _ATH_PREFIX(ath_mutex_destroy) ++#define ath_mutex_lock _ATH_PREFIX(ath_mutex_lock) ++#define ath_mutex_unlock _ATH_PREFIX(ath_mutex_unlock) ++#endif ++ ++ ++enum ath_thread_option ++ { ++ ATH_THREAD_OPTION_DEFAULT = 0, ++ ATH_THREAD_OPTION_USER = 1, ++ ATH_THREAD_OPTION_PTH = 2, ++ ATH_THREAD_OPTION_PTHREAD = 3 ++ }; ++ ++struct ath_ops ++{ ++ /* The OPTION field encodes the thread model and the version number ++ of this structure. ++ Bits 7 - 0 are used for the thread model ++ Bits 15 - 8 are used for the version number. ++ */ ++ unsigned int option; ++ ++}; ++ ++gpg_err_code_t ath_install (struct ath_ops *ath_ops); ++int ath_init (void); ++const char *ath_get_model (int *r_model); ++ ++/* Functions for mutual exclusion. */ ++typedef void *ath_mutex_t; ++ ++int ath_mutex_init (ath_mutex_t *mutex); ++int ath_mutex_destroy (ath_mutex_t *mutex); ++int ath_mutex_lock (ath_mutex_t *mutex); ++int ath_mutex_unlock (ath_mutex_t *mutex); ++ ++#endif /* ATH_H */ +diff --git a/grub-core/lib/libgcrypt/src/cipher-proto.h b/grub-core/lib/libgcrypt/src/cipher-proto.h +new file mode 100644 +index 0000000..347681f +--- /dev/null ++++ b/grub-core/lib/libgcrypt/src/cipher-proto.h +@@ -0,0 +1,124 @@ ++/* cipher-proto.h - Internal declarations ++ * Copyright (C) 2008, 2011 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser general Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, see . ++ */ ++ ++/* This file has been factored out from cipher.h so that it can be ++ used standalone in visibility.c . */ ++ ++#ifndef G10_CIPHER_PROTO_H ++#define G10_CIPHER_PROTO_H ++ ++/* Definition of a function used to report selftest failures. ++ DOMAIN is a string describing the function block: ++ "cipher", "digest", "pubkey or "random", ++ ALGO is the algorithm under test, ++ WHAT is a string describing what has been tested, ++ DESC is a string describing the error. */ ++typedef void (*selftest_report_func_t)(const char *domain, ++ int algo, ++ const char *what, ++ const char *errdesc); ++ ++/* Definition of the selftest functions. */ ++typedef gpg_err_code_t (*selftest_func_t) ++ (int algo, int extended, selftest_report_func_t report); ++ ++ ++/* An extended type of the generate function. */ ++typedef gcry_err_code_t (*pk_ext_generate_t) ++ (int algo, ++ unsigned int nbits, ++ unsigned long evalue, ++ gcry_sexp_t genparms, ++ gcry_mpi_t *skey, ++ gcry_mpi_t **retfactors, ++ gcry_sexp_t *extrainfo); ++ ++/* The type used to compute the keygrip. */ ++typedef gpg_err_code_t (*pk_comp_keygrip_t) ++ (gcry_md_hd_t md, gcry_sexp_t keyparm); ++ ++/* The type used to query ECC curve parameters. */ ++typedef gcry_err_code_t (*pk_get_param_t) ++ (const char *name, gcry_mpi_t *pkey); ++ ++/* The type used to query an ECC curve name. */ ++typedef const char *(*pk_get_curve_t)(gcry_mpi_t *pkey, int iterator, ++ unsigned int *r_nbits); ++ ++/* The type used to query ECC curve parameters by name. */ ++typedef gcry_sexp_t (*pk_get_curve_param_t)(const char *name); ++ ++/* The type used to convey additional information to a cipher. */ ++typedef gpg_err_code_t (*cipher_set_extra_info_t) ++ (void *c, int what, const void *buffer, size_t buflen); ++ ++ ++/* Extra module specification structures. These are used for internal ++ modules which provide more functions than available through the ++ public algorithm register APIs. */ ++typedef struct cipher_extra_spec ++{ ++ selftest_func_t selftest; ++ cipher_set_extra_info_t set_extra_info; ++} cipher_extra_spec_t; ++ ++typedef struct md_extra_spec ++{ ++ selftest_func_t selftest; ++} md_extra_spec_t; ++ ++typedef struct pk_extra_spec ++{ ++ selftest_func_t selftest; ++ pk_ext_generate_t ext_generate; ++ pk_comp_keygrip_t comp_keygrip; ++ pk_get_param_t get_param; ++ pk_get_curve_t get_curve; ++ pk_get_curve_param_t get_curve_param; ++} pk_extra_spec_t; ++ ++ ++ ++/* The private register functions. */ ++gcry_error_t _gcry_cipher_register (gcry_cipher_spec_t *cipher, ++ cipher_extra_spec_t *extraspec, ++ int *algorithm_id, ++ gcry_module_t *module); ++gcry_error_t _gcry_md_register (gcry_md_spec_t *cipher, ++ md_extra_spec_t *extraspec, ++ unsigned int *algorithm_id, ++ gcry_module_t *module); ++gcry_error_t _gcry_pk_register (gcry_pk_spec_t *cipher, ++ pk_extra_spec_t *extraspec, ++ unsigned int *algorithm_id, ++ gcry_module_t *module); ++ ++/* The selftest functions. */ ++gcry_error_t _gcry_cipher_selftest (int algo, int extended, ++ selftest_report_func_t report); ++gcry_error_t _gcry_md_selftest (int algo, int extended, ++ selftest_report_func_t report); ++gcry_error_t _gcry_pk_selftest (int algo, int extended, ++ selftest_report_func_t report); ++gcry_error_t _gcry_hmac_selftest (int algo, int extended, ++ selftest_report_func_t report); ++ ++gcry_error_t _gcry_random_selftest (selftest_report_func_t report); ++ ++#endif /*G10_CIPHER_PROTO_H*/ +diff --git a/grub-core/lib/libgcrypt/src/cipher.h b/grub-core/lib/libgcrypt/src/cipher.h +new file mode 100644 +index 0000000..0f923d7 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/src/cipher.h +@@ -0,0 +1,181 @@ ++/* cipher.h ++ * Copyright (C) 1998, 2002, 2003, 2009 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser general Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ */ ++#ifndef G10_CIPHER_H ++#define G10_CIPHER_H ++ ++#include ++ ++#define DBG_CIPHER _gcry_get_debug_flag( 1 ) ++ ++#include "../random/random.h" ++ ++#define PUBKEY_FLAG_NO_BLINDING (1 << 0) ++ ++enum pk_operation ++ { ++ PUBKEY_OP_ENCRYPT, ++ PUBKEY_OP_DECRYPT, ++ PUBKEY_OP_SIGN, ++ PUBKEY_OP_VERIFY ++ }; ++ ++enum pk_encoding ++ { ++ PUBKEY_ENC_RAW, ++ PUBKEY_ENC_PKCS1, ++ PUBKEY_ENC_OAEP, ++ PUBKEY_ENC_PSS, ++ PUBKEY_ENC_UNKNOWN ++ }; ++ ++struct pk_encoding_ctx ++{ ++ enum pk_operation op; ++ unsigned int nbits; ++ ++ enum pk_encoding encoding; ++ int flags; ++ ++ int hash_algo; ++ ++ /* for OAEP */ ++ unsigned char *label; ++ size_t labellen; ++ ++ /* for PSS */ ++ size_t saltlen; ++ ++ int (* verify_cmp) (void *opaque, gcry_mpi_t tmp); ++ void *verify_arg; ++}; ++ ++#define CIPHER_INFO_NO_WEAK_KEY 1 ++ ++#include "cipher-proto.h" ++ ++ ++/*-- rmd160.c --*/ ++void _gcry_rmd160_hash_buffer (void *outbuf, ++ const void *buffer, size_t length); ++/*-- sha1.c --*/ ++void _gcry_sha1_hash_buffer (void *outbuf, ++ const void *buffer, size_t length); ++ ++/*-- rijndael.c --*/ ++void _gcry_aes_cfb_enc (void *context, unsigned char *iv, ++ void *outbuf, const void *inbuf, ++ unsigned int nblocks); ++void _gcry_aes_cfb_dec (void *context, unsigned char *iv, ++ void *outbuf_arg, const void *inbuf_arg, ++ unsigned int nblocks); ++void _gcry_aes_cbc_enc (void *context, unsigned char *iv, ++ void *outbuf_arg, const void *inbuf_arg, ++ unsigned int nblocks, int cbc_mac); ++void _gcry_aes_cbc_dec (void *context, unsigned char *iv, ++ void *outbuf_arg, const void *inbuf_arg, ++ unsigned int nblocks); ++void _gcry_aes_ctr_enc (void *context, unsigned char *ctr, ++ void *outbuf_arg, const void *inbuf_arg, ++ unsigned int nblocks); ++ ++ ++/*-- dsa.c --*/ ++void _gcry_register_pk_dsa_progress (gcry_handler_progress_t cbc, void *cb_data); ++ ++/*-- elgamal.c --*/ ++void _gcry_register_pk_elg_progress (gcry_handler_progress_t cb, ++ void *cb_data); ++ ++ ++/*-- ecc.c --*/ ++void _gcry_register_pk_ecc_progress (gcry_handler_progress_t cbc, ++ void *cb_data); ++ ++ ++/*-- primegen.c --*/ ++void _gcry_register_primegen_progress (gcry_handler_progress_t cb, ++ void *cb_data); ++ ++/*-- pubkey.c --*/ ++const char * _gcry_pk_aliased_algo_name (int algorithm); ++ ++/* Declarations for the cipher specifications. */ ++extern gcry_cipher_spec_t _gcry_cipher_spec_blowfish; ++extern gcry_cipher_spec_t _gcry_cipher_spec_des; ++extern gcry_cipher_spec_t _gcry_cipher_spec_tripledes; ++extern gcry_cipher_spec_t _gcry_cipher_spec_arcfour; ++extern gcry_cipher_spec_t _gcry_cipher_spec_cast5; ++extern gcry_cipher_spec_t _gcry_cipher_spec_aes; ++extern gcry_cipher_spec_t _gcry_cipher_spec_aes192; ++extern gcry_cipher_spec_t _gcry_cipher_spec_aes256; ++extern gcry_cipher_spec_t _gcry_cipher_spec_twofish; ++extern gcry_cipher_spec_t _gcry_cipher_spec_twofish128; ++extern gcry_cipher_spec_t _gcry_cipher_spec_serpent128; ++extern gcry_cipher_spec_t _gcry_cipher_spec_serpent192; ++extern gcry_cipher_spec_t _gcry_cipher_spec_serpent256; ++extern gcry_cipher_spec_t _gcry_cipher_spec_rfc2268_40; ++extern gcry_cipher_spec_t _gcry_cipher_spec_seed; ++extern gcry_cipher_spec_t _gcry_cipher_spec_camellia128; ++extern gcry_cipher_spec_t _gcry_cipher_spec_camellia192; ++extern gcry_cipher_spec_t _gcry_cipher_spec_camellia256; ++ ++extern cipher_extra_spec_t _gcry_cipher_extraspec_tripledes; ++extern cipher_extra_spec_t _gcry_cipher_extraspec_aes; ++extern cipher_extra_spec_t _gcry_cipher_extraspec_aes192; ++extern cipher_extra_spec_t _gcry_cipher_extraspec_aes256; ++ ++ ++/* Declarations for the digest specifications. */ ++extern gcry_md_spec_t _gcry_digest_spec_crc32; ++extern gcry_md_spec_t _gcry_digest_spec_crc32_rfc1510; ++extern gcry_md_spec_t _gcry_digest_spec_crc24_rfc2440; ++extern gcry_md_spec_t _gcry_digest_spec_md4; ++extern gcry_md_spec_t _gcry_digest_spec_md5; ++extern gcry_md_spec_t _gcry_digest_spec_rmd160; ++extern gcry_md_spec_t _gcry_digest_spec_sha1; ++extern gcry_md_spec_t _gcry_digest_spec_sha224; ++extern gcry_md_spec_t _gcry_digest_spec_sha256; ++extern gcry_md_spec_t _gcry_digest_spec_sha512; ++extern gcry_md_spec_t _gcry_digest_spec_sha384; ++extern gcry_md_spec_t _gcry_digest_spec_tiger; ++extern gcry_md_spec_t _gcry_digest_spec_tiger1; ++extern gcry_md_spec_t _gcry_digest_spec_tiger2; ++extern gcry_md_spec_t _gcry_digest_spec_whirlpool; ++ ++extern md_extra_spec_t _gcry_digest_extraspec_sha1; ++extern md_extra_spec_t _gcry_digest_extraspec_sha224; ++extern md_extra_spec_t _gcry_digest_extraspec_sha256; ++extern md_extra_spec_t _gcry_digest_extraspec_sha384; ++extern md_extra_spec_t _gcry_digest_extraspec_sha512; ++ ++/* Declarations for the pubkey cipher specifications. */ ++extern gcry_pk_spec_t _gcry_pubkey_spec_rsa; ++extern gcry_pk_spec_t _gcry_pubkey_spec_elg; ++extern gcry_pk_spec_t _gcry_pubkey_spec_dsa; ++extern gcry_pk_spec_t _gcry_pubkey_spec_ecdsa; ++extern gcry_pk_spec_t _gcry_pubkey_spec_ecdh; ++ ++extern pk_extra_spec_t _gcry_pubkey_extraspec_rsa; ++extern pk_extra_spec_t _gcry_pubkey_extraspec_dsa; ++extern pk_extra_spec_t _gcry_pubkey_extraspec_elg; ++extern pk_extra_spec_t _gcry_pubkey_extraspec_ecdsa; ++ ++ ++#endif /*G10_CIPHER_H*/ +diff --git a/grub-core/lib/libgcrypt/src/dumpsexp.c b/grub-core/lib/libgcrypt/src/dumpsexp.c +new file mode 100644 +index 0000000..f6384d7 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/src/dumpsexp.c +@@ -0,0 +1,766 @@ ++/* dumpsexp.c - Dump S-expressions. ++ * Copyright (C) 2007, 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 ++#include ++#include ++#include ++/* For a native WindowsCE binary we need to include gpg-error.h to ++ provide a replacement for strerror. */ ++#ifdef __MINGW32CE__ ++# include ++#endif ++ ++#define PGM "dumpsexp" ++#define MYVERSION_LINE PGM " (Libgcrypt) " VERSION ++#define BUGREPORT_LINE "\nReport bugs to .\n" ++ ++ ++static int verbose; /* Verbose mode. */ ++static int decimal; /* Print addresses in decimal. */ ++static int assume_hex; /* Assume input is hexencoded. */ ++static int advanced; /* Advanced format output. */ ++ ++static void ++print_version (int with_help) ++{ ++ fputs (MYVERSION_LINE "\n" ++ "Copyright (C) 2010 Free Software Foundation, Inc.\n" ++ "License GPLv3+: GNU GPL version 3 or later " ++ "\n" ++ "This is free software: you are free to change and redistribute it.\n" ++ "There is NO WARRANTY, to the extent permitted by law.\n", ++ stdout); ++ ++ if (with_help) ++ fputs ("\n" ++ "Usage: " PGM " [OPTIONS] [file]\n" ++ "Debug tool for S-expressions\n" ++ "\n" ++ " --decimal Print offsets using decimal notation\n" ++ " --assume-hex Assume input is a hex dump\n" ++ " --advanced Print file in advanced format\n" ++ " --verbose Show what we are doing\n" ++ " --version Print version of the program and exit\n" ++ " --help Display this help and exit\n" ++ BUGREPORT_LINE, stdout ); ++ ++ exit (0); ++} ++ ++static int ++print_usage (void) ++{ ++ fputs ("usage: " PGM " [OPTIONS] NBYTES\n", stderr); ++ fputs (" (use --help to display options)\n", stderr); ++ exit (1); ++} ++ ++ ++#define space_p(a) ((a)==' ' || (a)=='\n' || (a)=='\r' || (a)=='\t') ++#define digit_p(a) ((a) >= '0' && (a) <= '9') ++#define octdigit_p(a) ((a) >= '0' && (a) <= '7') ++#define alpha_p(a) ( ((a) >= 'A' && (a) <= 'Z') \ ++ || ((a) >= 'a' && (a) <= 'z')) ++#define hexdigit_p(a) (digit_p (a) \ ++ || ((a) >= 'A' && (a) <= 'F') \ ++ || ((a) >= 'a' && (a) <= 'f')) ++#define xtoi_1(a) ((a) <= '9'? ((a)- '0'): \ ++ (a) <= 'F'? ((a)-'A'+10):((a)-'a'+10)) ++ ++ ++/* Return true if P points to a byte containing a whitespace according ++ to the S-expressions definition. */ ++static inline int ++whitespace_p (int c) ++{ ++ switch (c) ++ { ++ case ' ': case '\t': case '\v': case '\f': case '\r': case '\n': return 1; ++ default: return 0; ++ } ++} ++ ++static void ++logit (const char *format, ...) ++{ ++ va_list arg_ptr; ++ ++ va_start (arg_ptr, format) ; ++ fputs (PGM ": ", stderr); ++ vfprintf (stderr, format, arg_ptr); ++ putc ('\n', stderr); ++ va_end (arg_ptr); ++} ++ ++/* The raw data buffer and its current length */ ++static unsigned char databuffer[16]; ++static int databufferlen; ++/* The number of bytes in databuffer which should be skipped at a flush. */ ++static int skipdatabufferlen; ++/* The number of raw bytes printed on the last line. */ ++static int nbytesprinted; ++/* The file offset of the current data buffer . */ ++static unsigned long databufferoffset; ++ ++ ++ ++static int ++my_getc (FILE *fp) ++{ ++ int c1, c2; ++ ++ if (!assume_hex) ++ return getc (fp); ++ ++ while ( (c1=getc (fp)) != EOF && space_p (c1) ) ++ ; ++ if (c1 == EOF) ++ return EOF; ++ ++ if (!hexdigit_p (c1)) ++ { ++ logit ("non hex-digit encountered\n"); ++ return EOF; ++ } ++ ++ while ( (c2=getc (fp)) != EOF && space_p (c2) ) ++ ; ++ if (c2 == EOF) ++ { ++ logit ("error reading second hex nibble\n"); ++ return EOF; ++ } ++ if (!hexdigit_p (c2)) ++ { ++ logit ("second hex nibble is not a hex-digit\n"); ++ return EOF; ++ } ++ return xtoi_1 (c1) * 16 + xtoi_1 (c2); ++} ++ ++ ++ ++ ++ ++/* Flush the raw data buffer. */ ++static void ++flushdatabuffer (void) ++{ ++ int i; ++ ++ if (!databufferlen) ++ return; ++ nbytesprinted = 0; ++ if (decimal) ++ printf ("%08lu ", databufferoffset); ++ else ++ printf ("%08lx ", databufferoffset); ++ for (i=0; i < databufferlen; i++) ++ { ++ if (i == 8) ++ putchar (' '); ++ if (i < skipdatabufferlen) ++ fputs (" ", stdout); ++ else ++ { ++ printf (" %02x", databuffer[i]); ++ databufferoffset++; ++ } ++ nbytesprinted++; ++ } ++ for (; i < sizeof (databuffer); i++) ++ { ++ if (i == 8) ++ putchar (' '); ++ fputs (" ", stdout); ++ } ++ fputs (" |", stdout); ++ for (i=0; i < databufferlen; i++) ++ { ++ if (i < skipdatabufferlen) ++ putchar (' '); ++ else if (databuffer[i] >= ' ' && databuffer[i] <= '~' ++ && databuffer[i] != '|') ++ putchar (databuffer[i]); ++ else ++ putchar ('.'); ++ } ++ putchar ('|'); ++ putchar ('\n'); ++ databufferlen = 0; ++ skipdatabufferlen = 0; ++} ++ ++ ++/* Add C to the raw data buffer and flush as needed. */ ++static void ++addrawdata (int c) ++{ ++ if ( databufferlen >= sizeof databuffer ) ++ flushdatabuffer (); ++ databuffer[databufferlen++] = c; ++} ++ ++ ++static void ++printcursor (int both) ++{ ++ int i; ++ ++ flushdatabuffer (); ++ printf ("%8s ", ""); ++ for (i=0; i < sizeof (databuffer); i++) ++ { ++ if (i == 8) ++ putchar (' '); ++ if (i+1 == nbytesprinted) ++ { ++ fputs (" ^ ", stdout); ++ if (!both) ++ break; ++ } ++ else ++ fputs (" ", stdout); ++ } ++ if (both) ++ { ++ fputs (" ", stdout); ++ for (i=0; i < nbytesprinted-1; i++) ++ putchar (' '); ++ putchar ('^'); ++ } ++ databufferlen = skipdatabufferlen = nbytesprinted; ++} ++ ++static void ++printerr (const char *text) ++{ ++ printcursor (1); ++ printf ("\n Error: %s\n", text); ++} ++ ++static void ++printctl (const char *text) ++{ ++ if (verbose && !advanced) ++ { ++ printcursor (0); ++ printf ("%s\n", text); ++ } ++} ++ ++static void ++printchr (int c) ++{ ++ putchar (c); ++} ++ ++/* static void */ ++/* printhex (int c) */ ++/* { */ ++/* printf ("\\x%02x", c); */ ++/* } */ ++ ++ ++#if 0 ++/**************** ++ * Print SEXP to buffer using the MODE. Returns the length of the ++ * SEXP in buffer or 0 if the buffer is too short (We have at least an ++ * empty list consisting of 2 bytes). If a buffer of NULL is provided, ++ * the required length is returned. ++ */ ++size_t ++gcry_sexp_sprint (const gcry_sexp_t list, ++ void *buffer, size_t maxlength ) ++{ ++ static unsigned char empty[3] = { ST_OPEN, ST_CLOSE, ST_STOP }; ++ const unsigned char *s; ++ char *d; ++ DATALEN n; ++ char numbuf[20]; ++ int i, indent = 0; ++ ++ s = list? list->d : empty; ++ d = buffer; ++ while ( *s != ST_STOP ) ++ { ++ switch ( *s ) ++ { ++ case ST_OPEN: ++ s++; ++ if (indent) ++ putchar ('\n'); ++ for (i=0; i < indent; i++) ++ putchar (' '); ++ putchar ('('); ++ indent++; ++ break; ++ case ST_CLOSE: ++ s++; ++ putchar (')'); ++ indent--; ++ if (*s != ST_OPEN && *s != ST_STOP) ++ { ++ putchar ('\n'); ++ for (i=0; i < indent; i++) ++ putchar (' '); ++ } ++ break; ++ case ST_DATA: ++ s++; ++ memcpy (&n, s, sizeof n); ++ s += sizeof n; ++ { ++ int type; ++ size_t nn; ++ ++ switch ( (type=suitable_encoding (s, n))) ++ { ++ case 1: nn = convert_to_string (s, n, NULL); break; ++ case 2: nn = convert_to_token (s, n, NULL); break; ++ default: nn = convert_to_hex (s, n, NULL); break; ++ } ++ switch (type) ++ { ++ case 1: convert_to_string (s, n, d); break; ++ case 2: convert_to_token (s, n, d); break; ++ default: convert_to_hex (s, n, d); break; ++ } ++ d += nn; ++ if (s[n] != ST_CLOSE) ++ putchar (' '); ++ } ++ else ++ { ++ snprintf (numbuf, sizeof numbuf, "%u:", (unsigned int)n ); ++ d = stpcpy (d, numbuf); ++ memcpy (d, s, n); ++ d += n; ++ } ++ s += n; ++ break; ++ default: ++ BUG (); ++ } ++ } ++ putchar ('\n'); ++ return len; ++} ++#endif ++ ++ ++/* Prepare for saving a chunk of data. */ ++static void ++init_data (void) ++{ ++ ++} ++ ++/* Push C on the current data chunk. */ ++static void ++push_data (int c) ++{ ++ (void)c; ++} ++ ++/* Flush and thus print the current data chunk. */ ++static void ++flush_data (void) ++{ ++ ++} ++ ++ ++/* Returns 0 on success. */ ++static int ++parse_and_print (FILE *fp) ++{ ++ static const char tokenchars[] = ++ "abcdefghijklmnopqrstuvwxyz" ++ "ABCDEFGHIJKLMNOPQRSTUVWXYZ" ++ "0123456789-./_:*+="; ++ int c; ++ int level = 0; ++ int tokenc = 0; ++ int hexcount = 0; ++ int disphint = 0; ++ unsigned long datalen = 0; ++ char quote_buf[10]; ++ int quote_idx = 0; ++ enum ++ { ++ INIT_STATE = 0, IN_NUMBER, PRE_DATA, IN_DATA, IN_STRING, ++ IN_ESCAPE, IN_OCT_ESC, IN_HEX_ESC, ++ CR_ESC, LF_ESC, IN_HEXFMT, IN_BASE64 ++ } ++ state = INIT_STATE; ++ ++ ++ while ((c = my_getc (fp)) != EOF ) ++ { ++ addrawdata (c); ++ switch (state) ++ { ++ case INIT_STATE: ++ if (tokenc) ++ { ++ if (strchr (tokenchars, c)) ++ { ++ printchr (c); ++ continue; ++ } ++ tokenc = 0; ++ } ++ parse_init_state: ++ if (c == '(') ++ { ++ if (disphint) ++ { ++ printerr ("unmatched display hint"); ++ disphint = 0; ++ } ++ printctl ("open"); ++ level++; ++ } ++ else if (c == ')') ++ { ++ if (disphint) ++ { ++ printerr ("unmatched display hint"); ++ disphint = 0; ++ } ++ printctl ("close"); ++ level--; ++ } ++ else if (c == '\"') ++ { ++ state = IN_STRING; ++ printctl ("beginstring"); ++ init_data (); ++ } ++ else if (c == '#') ++ { ++ state = IN_HEXFMT; ++ hexcount = 0; ++ printctl ("beginhex"); ++ init_data (); ++ } ++ else if (c == '|') ++ { ++ state = IN_BASE64; ++ printctl ("beginbase64"); ++ init_data (); ++ } ++ else if (c == '[') ++ { ++ if (disphint) ++ printerr ("nested display hint"); ++ disphint = c; ++ } ++ else if (c == ']') ++ { ++ if (!disphint) ++ printerr ("no open display hint"); ++ disphint = 0; ++ } ++ else if (c >= '0' && c <= '9') ++ { ++ if (c == '0') ++ printerr ("zero prefixed length"); ++ state = IN_NUMBER; ++ datalen = (c - '0'); ++ } ++ else if (strchr (tokenchars, c)) ++ { ++ printchr (c); ++ tokenc = c; ++ } ++ else if (whitespace_p (c)) ++ ; ++ else if (c == '{') ++ { ++ printerr ("rescanning is not supported"); ++ } ++ else if (c == '&' || c == '\\') ++ { ++ printerr ("reserved punctuation detected"); ++ } ++ else ++ { ++ printerr ("bad character detected"); ++ } ++ break; ++ ++ case IN_NUMBER: ++ if (digit_p (c)) ++ { ++ unsigned long tmp = datalen * 10 + (c - '0'); ++ if (tmp < datalen) ++ { ++ printerr ("overflow in data length"); ++ state = INIT_STATE; ++ datalen = 0; ++ } ++ else ++ datalen = tmp; ++ } ++ else if (c == ':') ++ { ++ if (!datalen) ++ { ++ printerr ("no data length"); ++ state = INIT_STATE; ++ } ++ else ++ state = PRE_DATA; ++ } ++ else if (c == '\"' || c == '#' || c == '|' ) ++ { ++ /* We ignore the optional length and divert to the init ++ state parser code. */ ++ goto parse_init_state; ++ } ++ else ++ printerr ("invalid length specification"); ++ break; ++ ++ case PRE_DATA: ++ state = IN_DATA; ++ printctl ("begindata"); ++ init_data (); ++ case IN_DATA: ++ if (datalen) ++ { ++ push_data (c); ++ datalen--; ++ } ++ if (!datalen) ++ { ++ state = INIT_STATE; ++ printctl ("enddata"); ++ flush_data (); ++ } ++ break; ++ ++ case IN_STRING: ++ if (c == '\"') ++ { ++ printctl ("endstring"); ++ flush_data (); ++ state = INIT_STATE; ++ } ++ else if (c == '\\') ++ state = IN_ESCAPE; ++ else ++ push_data (c); ++ break; ++ ++ case IN_ESCAPE: ++ switch (c) ++ { ++ case 'b': push_data ('\b'); state = IN_STRING; break; ++ case 't': push_data ('\t'); state = IN_STRING; break; ++ case 'v': push_data ('\v'); state = IN_STRING; break; ++ case 'n': push_data ('\n'); state = IN_STRING; break; ++ case 'f': push_data ('\f'); state = IN_STRING; break; ++ case 'r': push_data ('\r'); state = IN_STRING; break; ++ case '"': push_data ('"'); state = IN_STRING; break; ++ case '\'': push_data ('\''); state = IN_STRING; break; ++ case '\\': push_data ('\\'); state = IN_STRING; break; ++ ++ case '0': case '1': case '2': case '3': case '4': ++ case '5': case '6': case '7': ++ state = IN_OCT_ESC; ++ quote_idx = 0; ++ quote_buf[quote_idx++] = c; ++ break; ++ ++ case 'x': ++ state = IN_HEX_ESC; ++ quote_idx = 0; ++ break; ++ ++ case '\r': ++ state = CR_ESC; ++ break; ++ ++ case '\n': ++ state = LF_ESC; ++ break; ++ ++ default: ++ printerr ("invalid escape sequence"); ++ state = IN_STRING; ++ break; ++ } ++ break; ++ ++ case IN_OCT_ESC: ++ if (quote_idx < 3 && strchr ("01234567", c)) ++ { ++ quote_buf[quote_idx++] = c; ++ if (quote_idx == 3) ++ { ++ push_data ((unsigned int)quote_buf[0] * 8 * 8 ++ + (unsigned int)quote_buf[1] * 8 ++ + (unsigned int)quote_buf[2]); ++ state = IN_STRING; ++ } ++ } ++ else ++ state = IN_STRING; ++ break; ++ case IN_HEX_ESC: ++ if (quote_idx < 2 && strchr ("0123456789abcdefABCDEF", c)) ++ { ++ quote_buf[quote_idx++] = c; ++ if (quote_idx == 2) ++ { ++ push_data (xtoi_1 (quote_buf[0]) * 16 ++ + xtoi_1 (quote_buf[1])); ++ state = IN_STRING; ++ } ++ } ++ else ++ state = IN_STRING; ++ break; ++ case CR_ESC: ++ state = IN_STRING; ++ break; ++ case LF_ESC: ++ state = IN_STRING; ++ break; ++ ++ case IN_HEXFMT: ++ if (hexdigit_p (c)) ++ { ++ push_data (c); ++ hexcount++; ++ } ++ else if (c == '#') ++ { ++ if ((hexcount & 1)) ++ printerr ("odd number of hex digits"); ++ printctl ("endhex"); ++ flush_data (); ++ state = INIT_STATE; ++ } ++ else if (!whitespace_p (c)) ++ printerr ("bad hex character"); ++ break; ++ ++ case IN_BASE64: ++ if (c == '|') ++ { ++ printctl ("endbase64"); ++ flush_data (); ++ state = INIT_STATE; ++ } ++ else ++ push_data (c); ++ break; ++ ++ default: ++ logit ("invalid state %d detected", state); ++ exit (1); ++ } ++ } ++ flushdatabuffer (); ++ if (ferror (fp)) ++ { ++ logit ("error reading input: %s\n", strerror (errno)); ++ return -1; ++ } ++ return 0; ++} ++ ++ ++ ++int ++main (int argc, char **argv) ++{ ++ int rc; ++ ++ if (argc) ++ { ++ argc--; argv++; ++ } ++ while (argc && **argv == '-' && (*argv)[1] == '-') ++ { ++ if (!(*argv)[2]) ++ { ++ argc--; argv++; ++ break; ++ } ++ else if (!strcmp (*argv, "--version")) ++ print_version (0); ++ else if (!strcmp (*argv, "--help")) ++ print_version (1); ++ else if (!strcmp (*argv, "--verbose")) ++ { ++ argc--; argv++; ++ verbose = 1; ++ } ++ else if (!strcmp (*argv, "--decimal")) ++ { ++ argc--; argv++; ++ decimal = 1; ++ } ++ else if (!strcmp (*argv, "--assume-hex")) ++ { ++ argc--; argv++; ++ assume_hex = 1; ++ } ++ else if (!strcmp (*argv, "--advanced")) ++ { ++ argc--; argv++; ++ advanced = 1; ++ } ++ else ++ print_usage (); ++ } ++ ++ if (!argc) ++ { ++ rc = parse_and_print (stdin); ++ } ++ else ++ { ++ rc = 0; ++ for (; argc; argv++, argc--) ++ { ++ FILE *fp = fopen (*argv, "rb"); ++ if (!fp) ++ { ++ logit ("can't open `%s': %s\n", *argv, strerror (errno)); ++ rc = 1; ++ } ++ else ++ { ++ if (parse_and_print (fp)) ++ rc = 1; ++ fclose (fp); ++ } ++ } ++ } ++ ++ return !!rc; ++} +diff --git a/grub-core/lib/libgcrypt/src/fips.c b/grub-core/lib/libgcrypt/src/fips.c +new file mode 100644 +index 0000000..a3445eb +--- /dev/null ++++ b/grub-core/lib/libgcrypt/src/fips.c +@@ -0,0 +1,852 @@ ++/* fips.c - FIPS mode management ++ * Copyright (C) 2008 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, see . ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#ifdef ENABLE_HMAC_BINARY_CHECK ++# include ++#endif ++#ifdef HAVE_SYSLOG ++# include ++#endif /*HAVE_SYSLOG*/ ++ ++#include "g10lib.h" ++#include "ath.h" ++#include "cipher-proto.h" ++#include "hmac256.h" ++ ++ ++/* The name of the file used to foce libgcrypt into fips mode. */ ++#define FIPS_FORCE_FILE "/etc/gcrypt/fips_enabled" ++ ++ ++/* The states of the finite state machine used in fips mode. */ ++enum module_states ++ { ++ /* POWEROFF cannot be represented. */ ++ STATE_POWERON = 0, ++ STATE_INIT, ++ STATE_SELFTEST, ++ STATE_OPERATIONAL, ++ STATE_ERROR, ++ STATE_FATALERROR, ++ STATE_SHUTDOWN ++ }; ++ ++ ++/* Flag telling whether we are in fips mode. It uses inverse logic so ++ that fips mode is the default unless changed by the initialization ++ code. To check whether fips mode is enabled, use the function ++ fips_mode()! */ ++static int no_fips_mode_required; ++ ++/* Flag to indicate that we are in the enforced FIPS mode. */ ++static int enforced_fips_mode; ++ ++/* If this flag is set, the application may no longer assume that the ++ process is running in FIPS mode. This flag is protected by the ++ FSM_LOCK. */ ++static int inactive_fips_mode; ++ ++/* This is the lock we use to protect the FSM. */ ++static ath_mutex_t fsm_lock; ++ ++/* The current state of the FSM. The whole state machinery is only ++ used while in fips mode. Change this only while holding fsm_lock. */ ++static enum module_states current_state; ++ ++ ++ ++ ++ ++static void fips_new_state (enum module_states new_state); ++ ++ ++ ++/* Convert lowercase hex digits; assumes valid hex digits. */ ++#define loxtoi_1(p) (*(p) <= '9'? (*(p)- '0'): (*(p)-'a'+10)) ++#define loxtoi_2(p) ((loxtoi_1(p) * 16) + loxtoi_1((p)+1)) ++ ++/* Returns true if P points to a lowercase hex digit. */ ++#define loxdigit_p(p) !!strchr ("01234567890abcdef", *(p)) ++ ++ ++ ++/* Check whether the OS is in FIPS mode and record that in a module ++ local variable. If FORCE is passed as true, fips mode will be ++ enabled anyway. Note: This function is not thread-safe and should ++ be called before any threads are created. This function may only ++ be called once. */ ++void ++_gcry_initialize_fips_mode (int force) ++{ ++ static int done; ++ gpg_error_t err; ++ ++ /* Make sure we are not accidently called twice. */ ++ if (done) ++ { ++ if ( fips_mode () ) ++ { ++ fips_new_state (STATE_FATALERROR); ++ fips_noreturn (); ++ } ++ /* If not in fips mode an assert is sufficient. */ ++ gcry_assert (!done); ++ } ++ done = 1; ++ ++ /* If the calling application explicitly requested fipsmode, do so. */ ++ if (force) ++ { ++ gcry_assert (!no_fips_mode_required); ++ goto leave; ++ } ++ ++ /* For testing the system it is useful to override the system ++ provided detection of the FIPS mode and force FIPS mode using a ++ file. The filename is hardwired so that there won't be any ++ confusion on whether /etc/gcrypt/ or /usr/local/etc/gcrypt/ is ++ actually used. The file itself may be empty. */ ++ if ( !access (FIPS_FORCE_FILE, F_OK) ) ++ { ++ gcry_assert (!no_fips_mode_required); ++ goto leave; ++ } ++ ++ /* Checking based on /proc file properties. */ ++ { ++ static const char procfname[] = "/proc/sys/crypto/fips_enabled"; ++ FILE *fp; ++ int saved_errno; ++ ++ fp = fopen (procfname, "r"); ++ if (fp) ++ { ++ char line[256]; ++ ++ if (fgets (line, sizeof line, fp) && atoi (line)) ++ { ++ /* System is in fips mode. */ ++ fclose (fp); ++ gcry_assert (!no_fips_mode_required); ++ goto leave; ++ } ++ fclose (fp); ++ } ++ else if ((saved_errno = errno) != ENOENT ++ && saved_errno != EACCES ++ && !access ("/proc/version", F_OK) ) ++ { ++ /* Problem reading the fips file despite that we have the proc ++ file system. We better stop right away. */ ++ log_info ("FATAL: error reading `%s' in libgcrypt: %s\n", ++ procfname, strerror (saved_errno)); ++#ifdef HAVE_SYSLOG ++ syslog (LOG_USER|LOG_ERR, "Libgcrypt error: " ++ "reading `%s' failed: %s - abort", ++ procfname, strerror (saved_errno)); ++#endif /*HAVE_SYSLOG*/ ++ abort (); ++ } ++ } ++ ++ /* Fips not not requested, set flag. */ ++ no_fips_mode_required = 1; ++ ++ leave: ++ if (!no_fips_mode_required) ++ { ++ /* Yes, we are in FIPS mode. */ ++ FILE *fp; ++ ++ /* Intitialize the lock to protect the FSM. */ ++ err = ath_mutex_init (&fsm_lock); ++ if (err) ++ { ++ /* If that fails we can't do anything but abort the ++ process. We need to use log_info so that the FSM won't ++ get involved. */ ++ log_info ("FATAL: failed to create the FSM lock in libgcrypt: %s\n", ++ strerror (err)); ++#ifdef HAVE_SYSLOG ++ syslog (LOG_USER|LOG_ERR, "Libgcrypt error: " ++ "creating FSM lock failed: %s - abort", ++ strerror (err)); ++#endif /*HAVE_SYSLOG*/ ++ abort (); ++ } ++ ++ ++ /* If the FIPS force files exists, is readable and has a number ++ != 0 on its first line, we enable the enforced fips mode. */ ++ fp = fopen (FIPS_FORCE_FILE, "r"); ++ if (fp) ++ { ++ char line[256]; ++ ++ if (fgets (line, sizeof line, fp) && atoi (line)) ++ enforced_fips_mode = 1; ++ fclose (fp); ++ } ++ ++ /* Now get us into the INIT state. */ ++ fips_new_state (STATE_INIT); ++ ++ } ++ return; ++} ++ ++static void ++lock_fsm (void) ++{ ++ gpg_error_t err; ++ ++ err = ath_mutex_lock (&fsm_lock); ++ if (err) ++ { ++ log_info ("FATAL: failed to acquire the FSM lock in libgrypt: %s\n", ++ strerror (err)); ++#ifdef HAVE_SYSLOG ++ syslog (LOG_USER|LOG_ERR, "Libgcrypt error: " ++ "acquiring FSM lock failed: %s - abort", ++ strerror (err)); ++#endif /*HAVE_SYSLOG*/ ++ abort (); ++ } ++} ++ ++static void ++unlock_fsm (void) ++{ ++ gpg_error_t err; ++ ++ err = ath_mutex_unlock (&fsm_lock); ++ if (err) ++ { ++ log_info ("FATAL: failed to release the FSM lock in libgrypt: %s\n", ++ strerror (err)); ++#ifdef HAVE_SYSLOG ++ syslog (LOG_USER|LOG_ERR, "Libgcrypt error: " ++ "releasing FSM lock failed: %s - abort", ++ strerror (err)); ++#endif /*HAVE_SYSLOG*/ ++ abort (); ++ } ++} ++ ++ ++/* This function returns true if fips mode is enabled. This is ++ independent of the fips required finite state machine and only used ++ to enable fips specific code. Please use the fips_mode macro ++ instead of calling this function directly. */ ++int ++_gcry_fips_mode (void) ++{ ++ /* No locking is required because we have the requirement that this ++ variable is only initialized once with no other threads ++ existing. */ ++ return !no_fips_mode_required; ++} ++ ++ ++/* Return a flag telling whether we are in the enforced fips mode. */ ++int ++_gcry_enforced_fips_mode (void) ++{ ++ return enforced_fips_mode; ++} ++ ++ ++/* If we do not want to enforce the fips mode, we can set a flag so ++ that the application may check whether it is still in fips mode. ++ TEXT will be printed as part of a syslog message. This function ++ may only be be called if in fips mode. */ ++void ++_gcry_inactivate_fips_mode (const char *text) ++{ ++ gcry_assert (_gcry_fips_mode ()); ++ ++ if (_gcry_enforced_fips_mode () ) ++ { ++ /* Get us into the error state. */ ++ fips_signal_error (text); ++ return; ++ } ++ ++ lock_fsm (); ++ if (!inactive_fips_mode) ++ { ++ inactive_fips_mode = 1; ++ unlock_fsm (); ++#ifdef HAVE_SYSLOG ++ syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: " ++ "%s - FIPS mode inactivated", text); ++#endif /*HAVE_SYSLOG*/ ++ } ++ else ++ unlock_fsm (); ++} ++ ++ ++/* Return the FIPS mode inactive flag. If it is true the FIPS mode is ++ not anymore active. */ ++int ++_gcry_is_fips_mode_inactive (void) ++{ ++ int flag; ++ ++ if (!_gcry_fips_mode ()) ++ return 0; ++ lock_fsm (); ++ flag = inactive_fips_mode; ++ unlock_fsm (); ++ return flag; ++} ++ ++ ++ ++static const char * ++state2str (enum module_states state) ++{ ++ const char *s; ++ ++ switch (state) ++ { ++ case STATE_POWERON: s = "Power-On"; break; ++ case STATE_INIT: s = "Init"; break; ++ case STATE_SELFTEST: s = "Self-Test"; break; ++ case STATE_OPERATIONAL: s = "Operational"; break; ++ case STATE_ERROR: s = "Error"; break; ++ case STATE_FATALERROR: s = "Fatal-Error"; break; ++ case STATE_SHUTDOWN: s = "Shutdown"; break; ++ default: s = "?"; break; ++ } ++ return s; ++} ++ ++ ++/* Return true if the library is in the operational state. */ ++int ++_gcry_fips_is_operational (void) ++{ ++ int result; ++ ++ if (!fips_mode ()) ++ result = 1; ++ else ++ { ++ lock_fsm (); ++ if (current_state == STATE_INIT) ++ { ++ /* If we are still in the INIT state, we need to run the ++ selftests so that the FSM can eventually get into ++ operational state. Given that we would need a 2-phase ++ initialization of libgcrypt, but that has traditionally ++ not been enforced, we use this on demand self-test ++ checking. Note that Proper applications would do the ++ application specific libgcrypt initialization between a ++ gcry_check_version() and gcry_control ++ (GCRYCTL_INITIALIZATION_FINISHED) where the latter will ++ run the selftests. The drawback of these on-demand ++ self-tests are a small chance that self-tests are ++ performed by severeal threads; that is no problem because ++ our FSM make sure that we won't oversee any error. */ ++ unlock_fsm (); ++ _gcry_fips_run_selftests (0); ++ lock_fsm (); ++ } ++ ++ result = (current_state == STATE_OPERATIONAL); ++ unlock_fsm (); ++ } ++ return result; ++} ++ ++ ++/* This is test on whether the library is in the operational state. In ++ contrast to _gcry_fips_is_operational this function won't do a ++ state transition on the fly. */ ++int ++_gcry_fips_test_operational (void) ++{ ++ int result; ++ ++ if (!fips_mode ()) ++ result = 1; ++ else ++ { ++ lock_fsm (); ++ result = (current_state == STATE_OPERATIONAL); ++ unlock_fsm (); ++ } ++ return result; ++} ++ ++ ++/* This is a test on whether the library is in the error or ++ operational state. */ ++int ++_gcry_fips_test_error_or_operational (void) ++{ ++ int result; ++ ++ if (!fips_mode ()) ++ result = 1; ++ else ++ { ++ lock_fsm (); ++ result = (current_state == STATE_OPERATIONAL ++ || current_state == STATE_ERROR); ++ unlock_fsm (); ++ } ++ return result; ++} ++ ++ ++static void ++reporter (const char *domain, int algo, const char *what, const char *errtxt) ++{ ++ if (!errtxt && !_gcry_log_verbosity (2)) ++ return; ++ ++ log_info ("libgcrypt selftest: %s %s%s (%d): %s%s%s%s\n", ++ !strcmp (domain, "hmac")? "digest":domain, ++ !strcmp (domain, "hmac")? "HMAC-":"", ++ !strcmp (domain, "cipher")? _gcry_cipher_algo_name (algo) : ++ !strcmp (domain, "digest")? _gcry_md_algo_name (algo) : ++ !strcmp (domain, "hmac")? _gcry_md_algo_name (algo) : ++ !strcmp (domain, "pubkey")? _gcry_pk_algo_name (algo) : "", ++ algo, errtxt? errtxt:"Okay", ++ what?" (":"", what? what:"", what?")":""); ++} ++ ++/* Run self-tests for all required cipher algorithms. Return 0 on ++ success. */ ++static int ++run_cipher_selftests (int extended) ++{ ++ static int algos[] = ++ { ++ GCRY_CIPHER_3DES, ++ GCRY_CIPHER_AES128, ++ GCRY_CIPHER_AES192, ++ GCRY_CIPHER_AES256, ++ 0 ++ }; ++ int idx; ++ gpg_error_t err; ++ int anyerr = 0; ++ ++ for (idx=0; algos[idx]; idx++) ++ { ++ err = _gcry_cipher_selftest (algos[idx], extended, reporter); ++ reporter ("cipher", algos[idx], NULL, ++ err? gpg_strerror (err):NULL); ++ if (err) ++ anyerr = 1; ++ } ++ return anyerr; ++} ++ ++ ++/* Run self-tests for all required hash algorithms. Return 0 on ++ success. */ ++static int ++run_digest_selftests (int extended) ++{ ++ static int algos[] = ++ { ++ GCRY_MD_SHA1, ++ GCRY_MD_SHA224, ++ GCRY_MD_SHA256, ++ GCRY_MD_SHA384, ++ GCRY_MD_SHA512, ++ 0 ++ }; ++ int idx; ++ gpg_error_t err; ++ int anyerr = 0; ++ ++ for (idx=0; algos[idx]; idx++) ++ { ++ err = _gcry_md_selftest (algos[idx], extended, reporter); ++ reporter ("digest", algos[idx], NULL, ++ err? gpg_strerror (err):NULL); ++ if (err) ++ anyerr = 1; ++ } ++ return anyerr; ++} ++ ++ ++/* Run self-tests for all HMAC algorithms. Return 0 on success. */ ++static int ++run_hmac_selftests (int extended) ++{ ++ static int algos[] = ++ { ++ GCRY_MD_SHA1, ++ GCRY_MD_SHA224, ++ GCRY_MD_SHA256, ++ GCRY_MD_SHA384, ++ GCRY_MD_SHA512, ++ 0 ++ }; ++ int idx; ++ gpg_error_t err; ++ int anyerr = 0; ++ ++ for (idx=0; algos[idx]; idx++) ++ { ++ err = _gcry_hmac_selftest (algos[idx], extended, reporter); ++ reporter ("hmac", algos[idx], NULL, ++ err? gpg_strerror (err):NULL); ++ if (err) ++ anyerr = 1; ++ } ++ return anyerr; ++} ++ ++ ++/* Run self-tests for all required public key algorithms. Return 0 on ++ success. */ ++static int ++run_pubkey_selftests (int extended) ++{ ++ static int algos[] = ++ { ++ GCRY_PK_RSA, ++ GCRY_PK_DSA, ++ /* GCRY_PK_ECDSA is not enabled in fips mode. */ ++ 0 ++ }; ++ int idx; ++ gpg_error_t err; ++ int anyerr = 0; ++ ++ for (idx=0; algos[idx]; idx++) ++ { ++ err = _gcry_pk_selftest (algos[idx], extended, reporter); ++ reporter ("pubkey", algos[idx], NULL, ++ err? gpg_strerror (err):NULL); ++ if (err) ++ anyerr = 1; ++ } ++ return anyerr; ++} ++ ++ ++/* Run self-tests for the random number generator. Returns 0 on ++ success. */ ++static int ++run_random_selftests (void) ++{ ++ gpg_error_t err; ++ ++ err = _gcry_random_selftest (reporter); ++ reporter ("random", 0, NULL, err? gpg_strerror (err):NULL); ++ ++ return !!err; ++} ++ ++/* Run an integrity check on the binary. Returns 0 on success. */ ++static int ++check_binary_integrity (void) ++{ ++#ifdef ENABLE_HMAC_BINARY_CHECK ++ gpg_error_t err; ++ Dl_info info; ++ unsigned char digest[32]; ++ int dlen; ++ char *fname = NULL; ++ const char key[] = "What am I, a doctor or a moonshuttle conductor?"; ++ ++ if (!dladdr ("gcry_check_version", &info)) ++ err = gpg_error_from_syserror (); ++ else ++ { ++ dlen = _gcry_hmac256_file (digest, sizeof digest, info.dli_fname, ++ key, strlen (key)); ++ if (dlen < 0) ++ err = gpg_error_from_syserror (); ++ else if (dlen != 32) ++ err = gpg_error (GPG_ERR_INTERNAL); ++ else ++ { ++ fname = gcry_malloc (strlen (info.dli_fname) + 1 + 5 + 1 ); ++ if (!fname) ++ err = gpg_error_from_syserror (); ++ else ++ { ++ FILE *fp; ++ char *p; ++ ++ /* Prefix the basename with a dot. */ ++ strcpy (fname, info.dli_fname); ++ p = strrchr (fname, '/'); ++ if (p) ++ p++; ++ else ++ p = fname; ++ memmove (p+1, p, strlen (p)+1); ++ *p = '.'; ++ strcat (fname, ".hmac"); ++ ++ /* Open the file. */ ++ fp = fopen (fname, "r"); ++ if (!fp) ++ err = gpg_error_from_syserror (); ++ else ++ { ++ /* A buffer of 64 bytes plus one for a LF and one to ++ detect garbage. */ ++ unsigned char buffer[64+1+1]; ++ const unsigned char *s; ++ int n; ++ ++ /* The HMAC files consists of lowercase hex digits ++ only with an optional trailing linefeed. Fail if ++ there is any garbage. */ ++ err = gpg_error (GPG_ERR_SELFTEST_FAILED); ++ n = fread (buffer, 1, sizeof buffer, fp); ++ if (n == 64 || (n == 65 && buffer[64] == '\n')) ++ { ++ buffer[64] = 0; ++ for (n=0, s= buffer; ++ n < 32 && loxdigit_p (s) && loxdigit_p (s+1); ++ n++, s += 2) ++ buffer[n] = loxtoi_2 (s); ++ if ( n == 32 && !memcmp (digest, buffer, 32) ) ++ err = 0; ++ } ++ fclose (fp); ++ } ++ } ++ } ++ } ++ reporter ("binary", 0, fname, err? gpg_strerror (err):NULL); ++#ifdef HAVE_SYSLOG ++ if (err) ++ syslog (LOG_USER|LOG_ERR, "Libgcrypt error: " ++ "integrity check using `%s' failed: %s", ++ fname? fname:"[?]", gpg_strerror (err)); ++#endif /*HAVE_SYSLOG*/ ++ gcry_free (fname); ++ return !!err; ++#else ++ return 0; ++#endif ++} ++ ++ ++/* Run the self-tests. If EXTENDED is true, extended versions of the ++ selftest are run, that is more tests than required by FIPS. */ ++gpg_err_code_t ++_gcry_fips_run_selftests (int extended) ++{ ++ enum module_states result = STATE_ERROR; ++ gcry_err_code_t ec = GPG_ERR_SELFTEST_FAILED; ++ ++ if (fips_mode ()) ++ fips_new_state (STATE_SELFTEST); ++ ++ if (run_cipher_selftests (extended)) ++ goto leave; ++ ++ if (run_digest_selftests (extended)) ++ goto leave; ++ ++ if (run_hmac_selftests (extended)) ++ goto leave; ++ ++ /* Run random tests before the pubkey tests because the latter ++ require random. */ ++ if (run_random_selftests ()) ++ goto leave; ++ ++ if (run_pubkey_selftests (extended)) ++ goto leave; ++ ++ /* Now check the integrity of the binary. We do this this after ++ having checked the HMAC code. */ ++ if (check_binary_integrity ()) ++ goto leave; ++ ++ /* All selftests passed. */ ++ result = STATE_OPERATIONAL; ++ ec = 0; ++ ++ leave: ++ if (fips_mode ()) ++ fips_new_state (result); ++ ++ return ec; ++} ++ ++ ++/* This function is used to tell the FSM about errors in the library. ++ The FSM will be put into an error state. This function should not ++ be called directly but by one of the macros ++ ++ fips_signal_error (description) ++ fips_signal_fatal_error (description) ++ ++ where DESCRIPTION is a string describing the error. */ ++void ++_gcry_fips_signal_error (const char *srcfile, int srcline, const char *srcfunc, ++ int is_fatal, const char *description) ++{ ++ if (!fips_mode ()) ++ return; /* Not required. */ ++ ++ /* Set new state before printing an error. */ ++ fips_new_state (is_fatal? STATE_FATALERROR : STATE_ERROR); ++ ++ /* Print error. */ ++ log_info ("%serror in libgcrypt, file %s, line %d%s%s: %s\n", ++ is_fatal? "fatal ":"", ++ srcfile, srcline, ++ srcfunc? ", function ":"", srcfunc? srcfunc:"", ++ description? description : "no description available"); ++#ifdef HAVE_SYSLOG ++ syslog (LOG_USER|LOG_ERR, "Libgcrypt error: " ++ "%serror in file %s, line %d%s%s: %s", ++ is_fatal? "fatal ":"", ++ srcfile, srcline, ++ srcfunc? ", function ":"", srcfunc? srcfunc:"", ++ description? description : "no description available"); ++#endif /*HAVE_SYSLOG*/ ++} ++ ++ ++/* Perform a state transition to NEW_STATE. If this is an invalid ++ transition, the module will go into a fatal error state. */ ++static void ++fips_new_state (enum module_states new_state) ++{ ++ int ok = 0; ++ enum module_states last_state; ++ ++ lock_fsm (); ++ ++ last_state = current_state; ++ switch (current_state) ++ { ++ case STATE_POWERON: ++ if (new_state == STATE_INIT ++ || new_state == STATE_ERROR ++ || new_state == STATE_FATALERROR) ++ ok = 1; ++ break; ++ ++ case STATE_INIT: ++ if (new_state == STATE_SELFTEST ++ || new_state == STATE_ERROR ++ || new_state == STATE_FATALERROR) ++ ok = 1; ++ break; ++ ++ case STATE_SELFTEST: ++ if (new_state == STATE_OPERATIONAL ++ || new_state == STATE_ERROR ++ || new_state == STATE_FATALERROR) ++ ok = 1; ++ break; ++ ++ case STATE_OPERATIONAL: ++ if (new_state == STATE_SHUTDOWN ++ || new_state == STATE_SELFTEST ++ || new_state == STATE_ERROR ++ || new_state == STATE_FATALERROR) ++ ok = 1; ++ break; ++ ++ case STATE_ERROR: ++ if (new_state == STATE_SHUTDOWN ++ || new_state == STATE_ERROR ++ || new_state == STATE_FATALERROR ++ || new_state == STATE_SELFTEST) ++ ok = 1; ++ break; ++ ++ case STATE_FATALERROR: ++ if (new_state == STATE_SHUTDOWN ) ++ ok = 1; ++ break; ++ ++ case STATE_SHUTDOWN: ++ /* We won't see any transition *from* Shutdown because the only ++ allowed new state is Power-Off and that one can't be ++ represented. */ ++ break; ++ ++ } ++ ++ if (ok) ++ { ++ current_state = new_state; ++ } ++ ++ unlock_fsm (); ++ ++ if (!ok || _gcry_log_verbosity (2)) ++ log_info ("libgcrypt state transition %s => %s %s\n", ++ state2str (last_state), state2str (new_state), ++ ok? "granted":"denied"); ++ ++ if (!ok) ++ { ++ /* Invalid state transition. Halting library. */ ++#ifdef HAVE_SYSLOG ++ syslog (LOG_USER|LOG_ERR, ++ "Libgcrypt error: invalid state transition %s => %s", ++ state2str (last_state), state2str (new_state)); ++#endif /*HAVE_SYSLOG*/ ++ fips_noreturn (); ++ } ++ else if (new_state == STATE_ERROR || new_state == STATE_FATALERROR) ++ { ++#ifdef HAVE_SYSLOG ++ syslog (LOG_USER|LOG_WARNING, ++ "Libgcrypt notice: state transition %s => %s", ++ state2str (last_state), state2str (new_state)); ++#endif /*HAVE_SYSLOG*/ ++ } ++} ++ ++ ++ ++ ++/* This function should be called to ensure that the execution shall ++ not continue. */ ++void ++_gcry_fips_noreturn (void) ++{ ++#ifdef HAVE_SYSLOG ++ syslog (LOG_USER|LOG_ERR, "Libgcrypt terminated the application"); ++#endif /*HAVE_SYSLOG*/ ++ fflush (NULL); ++ abort (); ++ /*NOTREACHED*/ ++} +diff --git a/grub-core/lib/libgcrypt/src/g10lib.h b/grub-core/lib/libgcrypt/src/g10lib.h +new file mode 100644 +index 0000000..9ef45ec +--- /dev/null ++++ b/grub-core/lib/libgcrypt/src/g10lib.h +@@ -0,0 +1,349 @@ ++/* g10lib.h - Internal definitions for libgcrypt ++ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005 ++ * 2007, 2011 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser general Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, see . ++ */ ++ ++/* This header is to be used inside of libgcrypt in place of gcrypt.h. ++ This way we can better distinguish between internal and external ++ usage of gcrypt.h. */ ++ ++#ifndef G10LIB_H ++#define G10LIB_H 1 ++ ++#ifdef _GCRYPT_H ++#error gcrypt.h already included ++#endif ++ ++#ifndef _GCRYPT_IN_LIBGCRYPT ++#error something is wrong with config.h ++#endif ++ ++#include ++#include ++ ++#include "visibility.h" ++#include "types.h" ++ ++ ++ ++ ++/* Attribute handling macros. */ ++ ++#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 ) ++#define JNLIB_GCC_M_FUNCTION 1 ++#define JNLIB_GCC_A_NR __attribute__ ((noreturn)) ++#define JNLIB_GCC_A_PRINTF( f, a ) __attribute__ ((format (printf,f,a))) ++#define JNLIB_GCC_A_NR_PRINTF( f, a ) \ ++ __attribute__ ((noreturn, format (printf,f,a))) ++#define GCC_ATTR_NORETURN __attribute__ ((__noreturn__)) ++#else ++#define JNLIB_GCC_A_NR ++#define JNLIB_GCC_A_PRINTF( f, a ) ++#define JNLIB_GCC_A_NR_PRINTF( f, a ) ++#define GCC_ATTR_NORETURN ++#endif ++ ++#if __GNUC__ >= 3 ++/* According to glibc this attribute is available since 2.8 however we ++ better play safe and use it only with gcc 3 or newer. */ ++#define GCC_ATTR_FORMAT_ARG(a) __attribute__ ((format_arg (a))) ++#else ++#define GCC_ATTR_FORMAT_ARG(a) ++#endif ++ ++ ++/* Gettext macros. */ ++ ++#define _(a) _gcry_gettext(a) ++ ++/* Some handy macros */ ++#ifndef STR ++#define STR(v) #v ++#endif ++#define STR2(v) STR(v) ++#define DIM(v) (sizeof(v)/sizeof((v)[0])) ++#define DIMof(type,member) DIM(((type *)0)->member) ++ ++ ++ ++/*-- src/global.c -*/ ++int _gcry_global_is_operational (void); ++gcry_error_t _gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr); ++void _gcry_check_heap (const void *a); ++int _gcry_get_debug_flag (unsigned int mask); ++ ++ ++/*-- src/misc.c --*/ ++ ++#if defined(JNLIB_GCC_M_FUNCTION) || __STDC_VERSION__ >= 199901L ++void _gcry_bug (const char *file, int line, ++ const char *func) GCC_ATTR_NORETURN; ++void _gcry_assert_failed (const char *expr, const char *file, int line, ++ const char *func) GCC_ATTR_NORETURN; ++#else ++void _gcry_bug (const char *file, int line); ++void _gcry_assert_failed (const char *expr, const char *file, int line); ++#endif ++ ++const char *_gcry_gettext (const char *key) GCC_ATTR_FORMAT_ARG(1); ++void _gcry_fatal_error(int rc, const char *text ) JNLIB_GCC_A_NR; ++void _gcry_log( int level, const char *fmt, ... ) JNLIB_GCC_A_PRINTF(2,3); ++void _gcry_log_bug( const char *fmt, ... ) JNLIB_GCC_A_NR_PRINTF(1,2); ++void _gcry_log_fatal( const char *fmt, ... ) JNLIB_GCC_A_NR_PRINTF(1,2); ++void _gcry_log_error( const char *fmt, ... ) JNLIB_GCC_A_PRINTF(1,2); ++void _gcry_log_info( const char *fmt, ... ) JNLIB_GCC_A_PRINTF(1,2); ++int _gcry_log_info_with_dummy_fp (FILE *fp, const char *fmt, ... ) ++ JNLIB_GCC_A_PRINTF(2,3); ++void _gcry_log_debug( const char *fmt, ... ) JNLIB_GCC_A_PRINTF(1,2); ++void _gcry_log_printf ( const char *fmt, ... ) JNLIB_GCC_A_PRINTF(1,2); ++void _gcry_log_printhex (const char *text, const void *buffer, size_t length); ++ ++void _gcry_set_log_verbosity( int level ); ++int _gcry_log_verbosity( int level ); ++ ++#define BUG() _gcry_bug( __FILE__ , __LINE__, __func__ ) ++#define gcry_assert(expr) ((expr)? (void)0 \ ++ : _gcry_assert_failed (STR(expr), __FILE__, __LINE__, __func__)) ++ ++#define log_bug _gcry_log_bug ++#define log_fatal _gcry_log_fatal ++#define log_error _gcry_log_error ++#define log_info _gcry_log_info ++#define log_debug _gcry_log_debug ++#define log_printf _gcry_log_printf ++#define log_printhex _gcry_log_printhex ++ ++ ++/*-- src/hwfeatures.c --*/ ++/* (Do not change these values unless synced with the asm code.) */ ++#define HWF_PADLOCK_RNG 1 ++#define HWF_PADLOCK_AES 2 ++#define HWF_PADLOCK_SHA 4 ++#define HWF_PADLOCK_MMUL 8 ++ ++#define HWF_INTEL_AESNI 256 ++ ++ ++unsigned int _gcry_get_hw_features (void); ++void _gcry_detect_hw_features (unsigned int); ++ ++ ++/*-- mpi/mpiutil.c --*/ ++const char *_gcry_mpi_get_hw_config (void); ++ ++ ++/*-- cipher/pubkey.c --*/ ++ ++/* FIXME: shouldn't this go into mpi.h? */ ++#ifndef mpi_powm ++#define mpi_powm(w,b,e,m) gcry_mpi_powm( (w), (b), (e), (m) ) ++#endif ++ ++/*-- primegen.c --*/ ++gcry_err_code_t _gcry_primegen_init (void); ++gcry_mpi_t _gcry_generate_secret_prime (unsigned int nbits, ++ gcry_random_level_t random_level, ++ int (*extra_check)(void*, gcry_mpi_t), ++ void *extra_check_arg); ++gcry_mpi_t _gcry_generate_public_prime (unsigned int nbits, ++ gcry_random_level_t random_level, ++ int (*extra_check)(void*, gcry_mpi_t), ++ void *extra_check_arg); ++gcry_mpi_t _gcry_generate_elg_prime (int mode, ++ unsigned int pbits, unsigned int qbits, ++ gcry_mpi_t g, gcry_mpi_t **factors); ++gcry_mpi_t _gcry_derive_x931_prime (const gcry_mpi_t xp, ++ const gcry_mpi_t xp1, const gcry_mpi_t xp2, ++ const gcry_mpi_t e, ++ gcry_mpi_t *r_p1, gcry_mpi_t *r_p2); ++gpg_err_code_t _gcry_generate_fips186_2_prime ++ (unsigned int pbits, unsigned int qbits, ++ const void *seed, size_t seedlen, ++ gcry_mpi_t *r_q, gcry_mpi_t *r_p, ++ int *r_counter, ++ void **r_seed, size_t *r_seedlen); ++gpg_err_code_t _gcry_generate_fips186_3_prime ++ (unsigned int pbits, unsigned int qbits, ++ const void *seed, size_t seedlen, ++ gcry_mpi_t *r_q, gcry_mpi_t *r_p, ++ int *r_counter, ++ void **r_seed, size_t *r_seedlen, int *r_hashalgo); ++ ++ ++/* Replacements of missing functions (missing-string.c). */ ++#ifndef HAVE_STPCPY ++char *stpcpy (char *a, const char *b); ++#endif ++#ifndef HAVE_STRCASECMP ++int strcasecmp (const char *a, const char *b) _GCRY_GCC_ATTR_PURE; ++#endif ++ ++ ++/* Macros used to rename missing functions. */ ++#ifndef HAVE_STRTOUL ++#define strtoul(a,b,c) ((unsigned long)strtol((a),(b),(c))) ++#endif ++#ifndef HAVE_MEMMOVE ++#define memmove(d, s, n) bcopy((s), (d), (n)) ++#endif ++#ifndef HAVE_STRICMP ++#define stricmp(a,b) strcasecmp( (a), (b) ) ++#endif ++#ifndef HAVE_ATEXIT ++#define atexit(a) (on_exit((a),0)) ++#endif ++#ifndef HAVE_RAISE ++#define raise(a) kill(getpid(), (a)) ++#endif ++ ++ ++/* Stack burning. */ ++ ++void _gcry_burn_stack (int bytes); ++ ++ ++/* To avoid that a compiler optimizes certain memset calls away, these ++ macros may be used instead. */ ++#define wipememory2(_ptr,_set,_len) do { \ ++ volatile char *_vptr=(volatile char *)(_ptr); \ ++ size_t _vlen=(_len); \ ++ while(_vlen) { *_vptr=(_set); _vptr++; _vlen--; } \ ++ } while(0) ++#define wipememory(_ptr,_len) wipememory2(_ptr,0,_len) ++ ++ ++ ++/* Digit predicates. */ ++ ++#define digitp(p) (*(p) >= '0' && *(p) <= '9') ++#define octdigitp(p) (*(p) >= '0' && *(p) <= '7') ++#define alphap(a) ( (*(a) >= 'A' && *(a) <= 'Z') \ ++ || (*(a) >= 'a' && *(a) <= 'z')) ++#define hexdigitp(a) (digitp (a) \ ++ || (*(a) >= 'A' && *(a) <= 'F') \ ++ || (*(a) >= 'a' && *(a) <= 'f')) ++ ++/* Management for ciphers/digests/pubkey-ciphers. */ ++ ++/* Structure for each registered `module'. */ ++struct gcry_module ++{ ++ struct gcry_module *next; /* List pointers. */ ++ struct gcry_module **prevp; ++ void *spec; /* Pointer to the subsystem-specific ++ specification structure. */ ++ void *extraspec; /* Pointer to the subsystem-specific ++ extra specification structure. */ ++ int flags; /* Associated flags. */ ++ int counter; /* Use counter. */ ++ unsigned int mod_id; /* ID of this module. */ ++}; ++ ++typedef struct gcry_module gcry_module_t; ++ ++/* Flags for the `flags' member of gcry_module_t. */ ++#define FLAG_MODULE_DISABLED (1 << 0) ++ ++gcry_err_code_t _gcry_module_add (gcry_module_t *entries, ++ unsigned int id, ++ void *spec, ++ void *extraspec, ++ gcry_module_t *module); ++ ++typedef int (*gcry_module_lookup_t) (void *spec, void *data); ++ ++/* Lookup a module specification by it's ID. After a successful ++ lookup, the module has it's resource counter incremented. */ ++gcry_module_t _gcry_module_lookup_id (gcry_module_t entries, ++ unsigned int id); ++ ++/* Internal function. Lookup a module specification. */ ++gcry_module_t _gcry_module_lookup (gcry_module_t entries, void *data, ++ gcry_module_lookup_t func); ++ ++/* Release a module. In case the use-counter reaches zero, destroy ++ the module. */ ++void _gcry_module_release (gcry_module_t entry); ++ ++/* Add a reference to a module. */ ++void _gcry_module_use (gcry_module_t module); ++ ++/* Return a list of module IDs. */ ++gcry_err_code_t _gcry_module_list (gcry_module_t modules, ++ int *list, int *list_length); ++ ++gcry_err_code_t _gcry_cipher_init (void); ++gcry_err_code_t _gcry_md_init (void); ++gcry_err_code_t _gcry_pk_init (void); ++ ++gcry_err_code_t _gcry_pk_module_lookup (int id, gcry_module_t *module); ++void _gcry_pk_module_release (gcry_module_t module); ++gcry_err_code_t _gcry_pk_get_elements (int algo, char **enc, char **sig); ++ ++/* Memory management. */ ++#define GCRY_ALLOC_FLAG_SECURE (1 << 0) ++ ++ ++/*-- sexp.c --*/ ++gcry_error_t _gcry_sexp_vbuild (gcry_sexp_t *retsexp, size_t *erroff, ++ const char *format, va_list arg_ptr); ++char *_gcry_sexp_nth_string (const gcry_sexp_t list, int number); ++ ++ ++/*-- fips.c --*/ ++ ++void _gcry_initialize_fips_mode (int force); ++ ++int _gcry_enforced_fips_mode (void); ++ ++void _gcry_inactivate_fips_mode (const char *text); ++int _gcry_is_fips_mode_inactive (void); ++ ++ ++void _gcry_fips_signal_error (const char *srcfile, ++ int srcline, ++ const char *srcfunc, ++ int is_fatal, ++ const char *description); ++#ifdef JNLIB_GCC_M_FUNCTION ++# define fips_signal_error(a) \ ++ _gcry_fips_signal_error (__FILE__, __LINE__, __FUNCTION__, 0, (a)) ++# define fips_signal_fatal_error(a) \ ++ _gcry_fips_signal_error (__FILE__, __LINE__, __FUNCTION__, 1, (a)) ++#else ++# define fips_signal_error(a) \ ++ _gcry_fips_signal_error (__FILE__, __LINE__, NULL, 0, (a)) ++# define fips_signal_fatal_error(a) \ ++ _gcry_fips_signal_error (__FILE__, __LINE__, NULL, 1, (a)) ++#endif ++ ++int _gcry_fips_is_operational (void); ++#define fips_is_operational() (_gcry_global_is_operational ()) ++#define fips_not_operational() (GCRY_GPG_ERR_NOT_OPERATIONAL) ++ ++int _gcry_fips_test_operational (void); ++int _gcry_fips_test_error_or_operational (void); ++ ++gpg_err_code_t _gcry_fips_run_selftests (int extended); ++ ++void _gcry_fips_noreturn (void); ++#define fips_noreturn() (_gcry_fips_noreturn ()) ++ ++ ++ ++#endif /* G10LIB_H */ +diff --git a/grub-core/lib/libgcrypt/src/gcrypt-module.h b/grub-core/lib/libgcrypt/src/gcrypt-module.h +new file mode 100644 +index 0000000..93f6162 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/src/gcrypt-module.h +@@ -0,0 +1,204 @@ ++/* gcrypt-module.h - GNU Cryptographic Library Interface ++ Copyright (C) 2003, 2007 Free Software Foundation, Inc. ++ ++ This file is part of Libgcrypt. ++ ++ Libgcrypt is free software; you can redistribute it and/or modify ++ it under the terms of the GNU Lesser General Public License as ++ published by the Free Software Foundation; either version 2.1 of ++ the License, or (at your option) any later version. ++ ++ Libgcrypt 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 Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with this program; if not, see . ++ */ ++ ++/* ++ This file contains the necessary declarations/definitions for ++ working with Libgcrypt modules. Since 1.6 this is an internal ++ interface and will eventually be merged into another header or ++ entirely removed. ++ */ ++ ++#ifndef GCRYPT_MODULE_H ++#define GCRYPT_MODULE_H ++ ++#ifdef __cplusplus ++extern "C" { ++#if 0 /* keep Emacsens's auto-indent happy */ ++} ++#endif ++#endif ++ ++/* The interfaces using the module system reserve a certain range of ++ IDs for application use. These IDs are not valid within Libgcrypt ++ but Libgcrypt makes sure never to allocate such a module ID. */ ++#define GCRY_MODULE_ID_USER 1024 ++#define GCRY_MODULE_ID_USER_LAST 4095 ++ ++ ++/* This type represents a `module'. */ ++typedef struct gcry_module *gcry_module_t; ++ ++/* Check that the library fulfills the version requirement. */ ++ ++/* Type for the cipher_setkey function. */ ++typedef gcry_err_code_t (*gcry_cipher_setkey_t) (void *c, ++ const unsigned char *key, ++ unsigned keylen); ++ ++/* Type for the cipher_encrypt function. */ ++typedef void (*gcry_cipher_encrypt_t) (void *c, ++ unsigned char *outbuf, ++ const unsigned char *inbuf); ++ ++/* Type for the cipher_decrypt function. */ ++typedef void (*gcry_cipher_decrypt_t) (void *c, ++ unsigned char *outbuf, ++ const unsigned char *inbuf); ++ ++/* Type for the cipher_stencrypt function. */ ++typedef void (*gcry_cipher_stencrypt_t) (void *c, ++ unsigned char *outbuf, ++ const unsigned char *inbuf, ++ unsigned int n); ++ ++/* Type for the cipher_stdecrypt function. */ ++typedef void (*gcry_cipher_stdecrypt_t) (void *c, ++ unsigned char *outbuf, ++ const unsigned char *inbuf, ++ unsigned int n); ++ ++typedef struct gcry_cipher_oid_spec ++{ ++ const char *oid; ++ int mode; ++} gcry_cipher_oid_spec_t; ++ ++/* Module specification structure for ciphers. */ ++typedef struct gcry_cipher_spec ++{ ++ const char *name; ++ const char **aliases; ++ gcry_cipher_oid_spec_t *oids; ++ size_t blocksize; ++ size_t keylen; ++ size_t contextsize; ++ gcry_cipher_setkey_t setkey; ++ gcry_cipher_encrypt_t encrypt; ++ gcry_cipher_decrypt_t decrypt; ++ gcry_cipher_stencrypt_t stencrypt; ++ gcry_cipher_stdecrypt_t stdecrypt; ++} gcry_cipher_spec_t; ++ ++ ++/* ********************** */ ++ ++/* Type for the pk_generate function. */ ++typedef gcry_err_code_t (*gcry_pk_generate_t) (int algo, ++ unsigned int nbits, ++ unsigned long use_e, ++ gcry_mpi_t *skey, ++ gcry_mpi_t **retfactors); ++ ++/* Type for the pk_check_secret_key function. */ ++typedef gcry_err_code_t (*gcry_pk_check_secret_key_t) (int algo, ++ gcry_mpi_t *skey); ++ ++/* Type for the pk_encrypt function. */ ++typedef gcry_err_code_t (*gcry_pk_encrypt_t) (int algo, ++ gcry_mpi_t *resarr, ++ gcry_mpi_t data, ++ gcry_mpi_t *pkey, ++ int flags); ++ ++/* Type for the pk_decrypt function. */ ++typedef gcry_err_code_t (*gcry_pk_decrypt_t) (int algo, ++ gcry_mpi_t *result, ++ gcry_mpi_t *data, ++ gcry_mpi_t *skey, ++ int flags); ++ ++/* Type for the pk_sign function. */ ++typedef gcry_err_code_t (*gcry_pk_sign_t) (int algo, ++ gcry_mpi_t *resarr, ++ gcry_mpi_t data, ++ gcry_mpi_t *skey); ++ ++/* Type for the pk_verify function. */ ++typedef gcry_err_code_t (*gcry_pk_verify_t) (int algo, ++ gcry_mpi_t hash, ++ gcry_mpi_t *data, ++ gcry_mpi_t *pkey, ++ int (*cmp) (void *, gcry_mpi_t), ++ void *opaquev); ++ ++/* Type for the pk_get_nbits function. */ ++typedef unsigned (*gcry_pk_get_nbits_t) (int algo, gcry_mpi_t *pkey); ++ ++/* Module specification structure for message digests. */ ++typedef struct gcry_pk_spec ++{ ++ const char *name; ++ const char **aliases; ++ const char *elements_pkey; ++ const char *elements_skey; ++ const char *elements_enc; ++ const char *elements_sig; ++ const char *elements_grip; ++ int use; ++ gcry_pk_generate_t generate; ++ gcry_pk_check_secret_key_t check_secret_key; ++ gcry_pk_encrypt_t encrypt; ++ gcry_pk_decrypt_t decrypt; ++ gcry_pk_sign_t sign; ++ gcry_pk_verify_t verify; ++ gcry_pk_get_nbits_t get_nbits; ++} gcry_pk_spec_t; ++ ++ ++/* ********************** */ ++ ++/* Type for the md_init function. */ ++typedef void (*gcry_md_init_t) (void *c); ++ ++/* Type for the md_write function. */ ++typedef void (*gcry_md_write_t) (void *c, const void *buf, size_t nbytes); ++ ++/* Type for the md_final function. */ ++typedef void (*gcry_md_final_t) (void *c); ++ ++/* Type for the md_read function. */ ++typedef unsigned char *(*gcry_md_read_t) (void *c); ++ ++typedef struct gcry_md_oid_spec ++{ ++ const char *oidstring; ++} gcry_md_oid_spec_t; ++ ++/* Module specification structure for message digests. */ ++typedef struct gcry_md_spec ++{ ++ const char *name; ++ unsigned char *asnoid; ++ int asnlen; ++ gcry_md_oid_spec_t *oids; ++ int mdlen; ++ gcry_md_init_t init; ++ gcry_md_write_t write; ++ gcry_md_final_t final; ++ gcry_md_read_t read; ++ size_t contextsize; /* allocate this amount of context */ ++} gcry_md_spec_t; ++ ++#if 0 /* keep Emacsens's auto-indent happy */ ++{ ++#endif ++#ifdef __cplusplus ++} ++#endif ++#endif /*GCRYPT_MODULE_H*/ +diff --git a/grub-core/lib/libgcrypt/src/gcrypt.h.in b/grub-core/lib/libgcrypt/src/gcrypt.h.in +new file mode 100644 +index 0000000..8e23ec4 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/src/gcrypt.h.in +@@ -0,0 +1,1337 @@ ++/* gcrypt.h - GNU Cryptographic Library Interface -*- c -*- ++ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006 ++ 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. ++ ++ This file is part of Libgcrypt. ++ ++ Libgcrypt is free software; you can redistribute it and/or modify ++ it under the terms of the GNU Lesser General Public License as ++ published by the Free Software Foundation; either version 2.1 of ++ the License, or (at your option) any later version. ++ ++ Libgcrypt 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 Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with this program; if not, see . ++ ++ File: @configure_input@ */ ++ ++#ifndef _GCRYPT_H ++#define _GCRYPT_H ++ ++#include ++#include ++#include ++ ++#include ++ ++#include ++ ++#if defined _WIN32 || defined __WIN32__ ++# include ++# include ++# include ++# ifndef __GNUC__ ++ typedef long ssize_t; ++ typedef int pid_t; ++# endif /*!__GNUC__*/ ++#else ++# include ++# include ++#@INSERT_SYS_SELECT_H@ ++#endif /*!_WIN32*/ ++ ++@FALLBACK_SOCKLEN_T@ ++ ++/* This is required for error code compatibility. */ ++#define _GCRY_ERR_SOURCE_DEFAULT GPG_ERR_SOURCE_GCRYPT ++ ++#ifdef __cplusplus ++extern "C" { ++#if 0 /* (Keep Emacsens' auto-indent happy.) */ ++} ++#endif ++#endif ++ ++/* The version of this header should match the one of the library. It ++ should not be used by a program because gcry_check_version() should ++ return the same version. The purpose of this macro is to let ++ autoconf (using the AM_PATH_GCRYPT macro) check that this header ++ matches the installed library. */ ++#define GCRYPT_VERSION "@VERSION@" ++ ++/* Internal: We can't use the convenience macros for the multi ++ precision integer functions when building this library. */ ++#ifdef _GCRYPT_IN_LIBGCRYPT ++#ifndef GCRYPT_NO_MPI_MACROS ++#define GCRYPT_NO_MPI_MACROS 1 ++#endif ++#endif ++ ++/* We want to use gcc attributes when possible. Warning: Don't use ++ these macros in your programs: As indicated by the leading ++ underscore they are subject to change without notice. */ ++#ifdef __GNUC__ ++ ++#define _GCRY_GCC_VERSION (__GNUC__ * 10000 \ ++ + __GNUC_MINOR__ * 100 \ ++ + __GNUC_PATCHLEVEL__) ++ ++#if _GCRY_GCC_VERSION >= 30100 ++#define _GCRY_GCC_ATTR_DEPRECATED __attribute__ ((__deprecated__)) ++#endif ++ ++#if _GCRY_GCC_VERSION >= 29600 ++#define _GCRY_GCC_ATTR_PURE __attribute__ ((__pure__)) ++#endif ++ ++#if _GCRY_GCC_VERSION >= 30200 ++#define _GCRY_GCC_ATTR_MALLOC __attribute__ ((__malloc__)) ++#endif ++ ++#endif /*__GNUC__*/ ++ ++#ifndef _GCRY_GCC_ATTR_DEPRECATED ++#define _GCRY_GCC_ATTR_DEPRECATED ++#endif ++#ifndef _GCRY_GCC_ATTR_PURE ++#define _GCRY_GCC_ATTR_PURE ++#endif ++#ifndef _GCRY_GCC_ATTR_MALLOC ++#define _GCRY_GCC_ATTR_MALLOC ++#endif ++ ++/* Make up an attribute to mark functions and types as deprecated but ++ allow internal use by Libgcrypt. */ ++#ifdef _GCRYPT_IN_LIBGCRYPT ++#define _GCRY_ATTR_INTERNAL ++#else ++#define _GCRY_ATTR_INTERNAL _GCRY_GCC_ATTR_DEPRECATED ++#endif ++ ++/* Wrappers for the libgpg-error library. */ ++ ++typedef gpg_error_t gcry_error_t; ++typedef gpg_err_code_t gcry_err_code_t; ++typedef gpg_err_source_t gcry_err_source_t; ++ ++static GPG_ERR_INLINE gcry_error_t ++gcry_err_make (gcry_err_source_t source, gcry_err_code_t code) ++{ ++ return gpg_err_make (source, code); ++} ++ ++/* The user can define GPG_ERR_SOURCE_DEFAULT before including this ++ file to specify a default source for gpg_error. */ ++#ifndef GCRY_ERR_SOURCE_DEFAULT ++#define GCRY_ERR_SOURCE_DEFAULT GPG_ERR_SOURCE_USER_1 ++#endif ++ ++static GPG_ERR_INLINE gcry_error_t ++gcry_error (gcry_err_code_t code) ++{ ++ return gcry_err_make (GCRY_ERR_SOURCE_DEFAULT, code); ++} ++ ++static GPG_ERR_INLINE gcry_err_code_t ++gcry_err_code (gcry_error_t err) ++{ ++ return gpg_err_code (err); ++} ++ ++ ++static GPG_ERR_INLINE gcry_err_source_t ++gcry_err_source (gcry_error_t err) ++{ ++ return gpg_err_source (err); ++} ++ ++/* Return a pointer to a string containing a description of the error ++ code in the error value ERR. */ ++const char *gcry_strerror (gcry_error_t err); ++ ++/* Return a pointer to a string containing a description of the error ++ source in the error value ERR. */ ++const char *gcry_strsource (gcry_error_t err); ++ ++/* Retrieve the error code for the system error ERR. This returns ++ GPG_ERR_UNKNOWN_ERRNO if the system error is not mapped (report ++ this). */ ++gcry_err_code_t gcry_err_code_from_errno (int err); ++ ++/* Retrieve the system error for the error code CODE. This returns 0 ++ if CODE is not a system error code. */ ++int gcry_err_code_to_errno (gcry_err_code_t code); ++ ++/* Return an error value with the error source SOURCE and the system ++ error ERR. */ ++gcry_error_t gcry_err_make_from_errno (gcry_err_source_t source, int err); ++ ++/* Return an error value with the system error ERR. */ ++gcry_err_code_t gcry_error_from_errno (int err); ++ ++ ++/* NOTE: Since Libgcrypt 1.6 the thread callbacks are not anymore ++ used. However we keep it to allow for some source code ++ compatibility if used in the standard way. */ ++ ++/* Constants defining the thread model to use. Used with the OPTION ++ field of the struct gcry_thread_cbs. */ ++#define GCRY_THREAD_OPTION_DEFAULT 0 ++#define GCRY_THREAD_OPTION_USER 1 ++#define GCRY_THREAD_OPTION_PTH 2 ++#define GCRY_THREAD_OPTION_PTHREAD 3 ++ ++/* The version number encoded in the OPTION field of the struct ++ gcry_thread_cbs. */ ++#define GCRY_THREAD_OPTION_VERSION 1 ++ ++/* Wrapper for struct ath_ops. */ ++struct gcry_thread_cbs ++{ ++ /* The OPTION field encodes the thread model and the version number ++ of this structure. ++ Bits 7 - 0 are used for the thread model ++ Bits 15 - 8 are used for the version number. */ ++ unsigned int option; ++} _GCRY_ATTR_INTERNAL; ++ ++#define GCRY_THREAD_OPTION_PTH_IMPL \ ++ static struct gcry_thread_cbs gcry_threads_pth = { \ ++ (GCRY_THREAD_OPTION_PTH | (GCRY_THREAD_OPTION_VERSION << 8))} ++ ++#define GCRY_THREAD_OPTION_PTHREAD_IMPL \ ++ static struct gcry_thread_cbs gcry_threads_pthread = { \ ++ (GCRY_THREAD_OPTION_PTHREAD | (GCRY_THREAD_OPTION_VERSION << 8))} ++ ++ ++ ++/* The data object used to hold a multi precision integer. */ ++struct gcry_mpi; ++typedef struct gcry_mpi *gcry_mpi_t; ++ ++#ifndef GCRYPT_NO_DEPRECATED ++typedef struct gcry_mpi *GCRY_MPI _GCRY_GCC_ATTR_DEPRECATED; ++typedef struct gcry_mpi *GcryMPI _GCRY_GCC_ATTR_DEPRECATED; ++#endif ++ ++ ++ ++/* Check that the library fulfills the version requirement. */ ++const char *gcry_check_version (const char *req_version); ++ ++/* Codes for function dispatchers. */ ++ ++/* Codes used with the gcry_control function. */ ++enum gcry_ctl_cmds ++ { ++ GCRYCTL_SET_KEY = 1, ++ GCRYCTL_SET_IV = 2, ++ GCRYCTL_CFB_SYNC = 3, ++ GCRYCTL_RESET = 4, /* e.g. for MDs */ ++ GCRYCTL_FINALIZE = 5, ++ GCRYCTL_GET_KEYLEN = 6, ++ GCRYCTL_GET_BLKLEN = 7, ++ GCRYCTL_TEST_ALGO = 8, ++ GCRYCTL_IS_SECURE = 9, ++ GCRYCTL_GET_ASNOID = 10, ++ GCRYCTL_ENABLE_ALGO = 11, ++ GCRYCTL_DISABLE_ALGO = 12, ++ GCRYCTL_DUMP_RANDOM_STATS = 13, ++ GCRYCTL_DUMP_SECMEM_STATS = 14, ++ GCRYCTL_GET_ALGO_NPKEY = 15, ++ GCRYCTL_GET_ALGO_NSKEY = 16, ++ GCRYCTL_GET_ALGO_NSIGN = 17, ++ GCRYCTL_GET_ALGO_NENCR = 18, ++ GCRYCTL_SET_VERBOSITY = 19, ++ GCRYCTL_SET_DEBUG_FLAGS = 20, ++ GCRYCTL_CLEAR_DEBUG_FLAGS = 21, ++ GCRYCTL_USE_SECURE_RNDPOOL= 22, ++ GCRYCTL_DUMP_MEMORY_STATS = 23, ++ GCRYCTL_INIT_SECMEM = 24, ++ GCRYCTL_TERM_SECMEM = 25, ++ GCRYCTL_DISABLE_SECMEM_WARN = 27, ++ GCRYCTL_SUSPEND_SECMEM_WARN = 28, ++ GCRYCTL_RESUME_SECMEM_WARN = 29, ++ GCRYCTL_DROP_PRIVS = 30, ++ GCRYCTL_ENABLE_M_GUARD = 31, ++ GCRYCTL_START_DUMP = 32, ++ GCRYCTL_STOP_DUMP = 33, ++ GCRYCTL_GET_ALGO_USAGE = 34, ++ GCRYCTL_IS_ALGO_ENABLED = 35, ++ GCRYCTL_DISABLE_INTERNAL_LOCKING = 36, ++ GCRYCTL_DISABLE_SECMEM = 37, ++ GCRYCTL_INITIALIZATION_FINISHED = 38, ++ GCRYCTL_INITIALIZATION_FINISHED_P = 39, ++ GCRYCTL_ANY_INITIALIZATION_P = 40, ++ GCRYCTL_SET_CBC_CTS = 41, ++ GCRYCTL_SET_CBC_MAC = 42, ++ GCRYCTL_SET_CTR = 43, ++ GCRYCTL_ENABLE_QUICK_RANDOM = 44, ++ GCRYCTL_SET_RANDOM_SEED_FILE = 45, ++ GCRYCTL_UPDATE_RANDOM_SEED_FILE = 46, ++ GCRYCTL_SET_THREAD_CBS = 47, ++ GCRYCTL_FAST_POLL = 48, ++ GCRYCTL_SET_RANDOM_DAEMON_SOCKET = 49, ++ GCRYCTL_USE_RANDOM_DAEMON = 50, ++ GCRYCTL_FAKED_RANDOM_P = 51, ++ GCRYCTL_SET_RNDEGD_SOCKET = 52, ++ GCRYCTL_PRINT_CONFIG = 53, ++ GCRYCTL_OPERATIONAL_P = 54, ++ GCRYCTL_FIPS_MODE_P = 55, ++ GCRYCTL_FORCE_FIPS_MODE = 56, ++ GCRYCTL_SELFTEST = 57, ++ /* Note: 58 .. 62 are used internally. */ ++ GCRYCTL_DISABLE_HWF = 63 ++ }; ++ ++/* Perform various operations defined by CMD. */ ++gcry_error_t gcry_control (enum gcry_ctl_cmds CMD, ...); ++ ++ ++/* S-expression management. */ ++ ++/* The object to represent an S-expression as used with the public key ++ functions. */ ++struct gcry_sexp; ++typedef struct gcry_sexp *gcry_sexp_t; ++ ++#ifndef GCRYPT_NO_DEPRECATED ++typedef struct gcry_sexp *GCRY_SEXP _GCRY_GCC_ATTR_DEPRECATED; ++typedef struct gcry_sexp *GcrySexp _GCRY_GCC_ATTR_DEPRECATED; ++#endif ++ ++/* The possible values for the S-expression format. */ ++enum gcry_sexp_format ++ { ++ GCRYSEXP_FMT_DEFAULT = 0, ++ GCRYSEXP_FMT_CANON = 1, ++ GCRYSEXP_FMT_BASE64 = 2, ++ GCRYSEXP_FMT_ADVANCED = 3 ++ }; ++ ++/* Create an new S-expression object from BUFFER of size LENGTH and ++ return it in RETSEXP. With AUTODETECT set to 0 the data in BUFFER ++ is expected to be in canonized format. */ ++gcry_error_t gcry_sexp_new (gcry_sexp_t *retsexp, ++ const void *buffer, size_t length, ++ int autodetect); ++ ++ /* Same as gcry_sexp_new but allows to pass a FREEFNC which has the ++ effect to transfer ownership of BUFFER to the created object. */ ++gcry_error_t gcry_sexp_create (gcry_sexp_t *retsexp, ++ void *buffer, size_t length, ++ int autodetect, void (*freefnc) (void *)); ++ ++/* Scan BUFFER and return a new S-expression object in RETSEXP. This ++ function expects a printf like string in BUFFER. */ ++gcry_error_t gcry_sexp_sscan (gcry_sexp_t *retsexp, size_t *erroff, ++ const char *buffer, size_t length); ++ ++/* Same as gcry_sexp_sscan but expects a string in FORMAT and can thus ++ only be used for certain encodings. */ ++gcry_error_t gcry_sexp_build (gcry_sexp_t *retsexp, size_t *erroff, ++ const char *format, ...); ++ ++/* Like gcry_sexp_build, but uses an array instead of variable ++ function arguments. */ ++gcry_error_t gcry_sexp_build_array (gcry_sexp_t *retsexp, size_t *erroff, ++ const char *format, void **arg_list); ++ ++/* Release the S-expression object SEXP */ ++void gcry_sexp_release (gcry_sexp_t sexp); ++ ++/* Calculate the length of an canonized S-expresion in BUFFER and ++ check for a valid encoding. */ ++size_t gcry_sexp_canon_len (const unsigned char *buffer, size_t length, ++ size_t *erroff, gcry_error_t *errcode); ++ ++/* Copies the S-expression object SEXP into BUFFER using the format ++ specified in MODE. */ ++size_t gcry_sexp_sprint (gcry_sexp_t sexp, int mode, void *buffer, ++ size_t maxlength); ++ ++/* Dumps the S-expression object A in a format suitable for debugging ++ to Libgcrypt's logging stream. */ ++void gcry_sexp_dump (const gcry_sexp_t a); ++ ++gcry_sexp_t gcry_sexp_cons (const gcry_sexp_t a, const gcry_sexp_t b); ++gcry_sexp_t gcry_sexp_alist (const gcry_sexp_t *array); ++gcry_sexp_t gcry_sexp_vlist (const gcry_sexp_t a, ...); ++gcry_sexp_t gcry_sexp_append (const gcry_sexp_t a, const gcry_sexp_t n); ++gcry_sexp_t gcry_sexp_prepend (const gcry_sexp_t a, const gcry_sexp_t n); ++ ++/* Scan the S-expression for a sublist with a type (the car of the ++ list) matching the string TOKEN. If TOKLEN is not 0, the token is ++ assumed to be raw memory of this length. The function returns a ++ newly allocated S-expression consisting of the found sublist or ++ `NULL' when not found. */ ++gcry_sexp_t gcry_sexp_find_token (gcry_sexp_t list, ++ const char *tok, size_t toklen); ++/* Return the length of the LIST. For a valid S-expression this ++ should be at least 1. */ ++int gcry_sexp_length (const gcry_sexp_t list); ++ ++/* Create and return a new S-expression from the element with index ++ NUMBER in LIST. Note that the first element has the index 0. If ++ there is no such element, `NULL' is returned. */ ++gcry_sexp_t gcry_sexp_nth (const gcry_sexp_t list, int number); ++ ++/* Create and return a new S-expression from the first element in ++ LIST; this called the "type" and should always exist and be a ++ string. `NULL' is returned in case of a problem. */ ++gcry_sexp_t gcry_sexp_car (const gcry_sexp_t list); ++ ++/* Create and return a new list form all elements except for the first ++ one. Note, that this function may return an invalid S-expression ++ because it is not guaranteed, that the type exists and is a string. ++ However, for parsing a complex S-expression it might be useful for ++ intermediate lists. Returns `NULL' on error. */ ++gcry_sexp_t gcry_sexp_cdr (const gcry_sexp_t list); ++ ++gcry_sexp_t gcry_sexp_cadr (const gcry_sexp_t list); ++ ++ ++/* This function is used to get data from a LIST. A pointer to the ++ actual data with index NUMBER is returned and the length of this ++ data will be stored to DATALEN. If there is no data at the given ++ index or the index represents another list, `NULL' is returned. ++ *Note:* The returned pointer is valid as long as LIST is not ++ modified or released. */ ++const char *gcry_sexp_nth_data (const gcry_sexp_t list, int number, ++ size_t *datalen); ++ ++/* This function is used to get and convert data from a LIST. The ++ data is assumed to be a Nul terminated string. The caller must ++ release the returned value using `gcry_free'. If there is no data ++ at the given index, the index represents a list or the value can't ++ be converted to a string, `NULL' is returned. */ ++char *gcry_sexp_nth_string (gcry_sexp_t list, int number); ++ ++/* This function is used to get and convert data from a LIST. This ++ data is assumed to be an MPI stored in the format described by ++ MPIFMT and returned as a standard Libgcrypt MPI. The caller must ++ release this returned value using `gcry_mpi_release'. If there is ++ no data at the given index, the index represents a list or the ++ value can't be converted to an MPI, `NULL' is returned. */ ++gcry_mpi_t gcry_sexp_nth_mpi (gcry_sexp_t list, int number, int mpifmt); ++ ++ ++ ++/******************************************* ++ * * ++ * Multi Precision Integer Functions * ++ * * ++ *******************************************/ ++ ++/* Different formats of external big integer representation. */ ++enum gcry_mpi_format ++ { ++ GCRYMPI_FMT_NONE= 0, ++ GCRYMPI_FMT_STD = 1, /* Twos complement stored without length. */ ++ GCRYMPI_FMT_PGP = 2, /* As used by OpenPGP (unsigned only). */ ++ GCRYMPI_FMT_SSH = 3, /* As used by SSH (like STD but with length). */ ++ GCRYMPI_FMT_HEX = 4, /* Hex format. */ ++ GCRYMPI_FMT_USG = 5 /* Like STD but unsigned. */ ++ }; ++ ++/* Flags used for creating big integers. */ ++enum gcry_mpi_flag ++ { ++ GCRYMPI_FLAG_SECURE = 1, /* Allocate the number in "secure" memory. */ ++ GCRYMPI_FLAG_OPAQUE = 2 /* The number is not a real one but just ++ a way to store some bytes. This is ++ useful for encrypted big integers. */ ++ }; ++ ++ ++/* Allocate a new big integer object, initialize it with 0 and ++ initially allocate memory for a number of at least NBITS. */ ++gcry_mpi_t gcry_mpi_new (unsigned int nbits); ++ ++/* Same as gcry_mpi_new() but allocate in "secure" memory. */ ++gcry_mpi_t gcry_mpi_snew (unsigned int nbits); ++ ++/* Release the number A and free all associated resources. */ ++void gcry_mpi_release (gcry_mpi_t a); ++ ++/* Create a new number with the same value as A. */ ++gcry_mpi_t gcry_mpi_copy (const gcry_mpi_t a); ++ ++/* Store the big integer value U in W. */ ++gcry_mpi_t gcry_mpi_set (gcry_mpi_t w, const gcry_mpi_t u); ++ ++/* Store the unsigned integer value U in W. */ ++gcry_mpi_t gcry_mpi_set_ui (gcry_mpi_t w, unsigned long u); ++ ++/* Swap the values of A and B. */ ++void gcry_mpi_swap (gcry_mpi_t a, gcry_mpi_t b); ++ ++/* Compare the big integer number U and V returning 0 for equality, a ++ positive value for U > V and a negative for U < V. */ ++int gcry_mpi_cmp (const gcry_mpi_t u, const gcry_mpi_t v); ++ ++/* Compare the big integer number U with the unsigned integer V ++ returning 0 for equality, a positive value for U > V and a negative ++ for U < V. */ ++int gcry_mpi_cmp_ui (const gcry_mpi_t u, unsigned long v); ++ ++/* Convert the external representation of an integer stored in BUFFER ++ with a length of BUFLEN into a newly create MPI returned in ++ RET_MPI. If NSCANNED is not NULL, it will receive the number of ++ bytes actually scanned after a successful operation. */ ++gcry_error_t gcry_mpi_scan (gcry_mpi_t *ret_mpi, enum gcry_mpi_format format, ++ const void *buffer, size_t buflen, ++ size_t *nscanned); ++ ++/* Convert the big integer A into the external representation ++ described by FORMAT and store it in the provided BUFFER which has ++ been allocated by the user with a size of BUFLEN bytes. NWRITTEN ++ receives the actual length of the external representation unless it ++ has been passed as NULL. */ ++gcry_error_t gcry_mpi_print (enum gcry_mpi_format format, ++ unsigned char *buffer, size_t buflen, ++ size_t *nwritten, ++ const gcry_mpi_t a); ++ ++/* Convert the big integer A int the external representation described ++ by FORMAT and store it in a newly allocated buffer which address ++ will be put into BUFFER. NWRITTEN receives the actual lengths of the ++ external representation. */ ++gcry_error_t gcry_mpi_aprint (enum gcry_mpi_format format, ++ unsigned char **buffer, size_t *nwritten, ++ const gcry_mpi_t a); ++ ++/* Dump the value of A in a format suitable for debugging to ++ Libgcrypt's logging stream. Note that one leading space but no ++ trailing space or linefeed will be printed. It is okay to pass ++ NULL for A. */ ++void gcry_mpi_dump (const gcry_mpi_t a); ++ ++ ++/* W = U + V. */ ++void gcry_mpi_add (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v); ++ ++/* W = U + V. V is an unsigned integer. */ ++void gcry_mpi_add_ui (gcry_mpi_t w, gcry_mpi_t u, unsigned long v); ++ ++/* W = U + V mod M. */ ++void gcry_mpi_addm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m); ++ ++/* W = U - V. */ ++void gcry_mpi_sub (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v); ++ ++/* W = U - V. V is an unsigned integer. */ ++void gcry_mpi_sub_ui (gcry_mpi_t w, gcry_mpi_t u, unsigned long v ); ++ ++/* W = U - V mod M */ ++void gcry_mpi_subm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m); ++ ++/* W = U * V. */ ++void gcry_mpi_mul (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v); ++ ++/* W = U * V. V is an unsigned integer. */ ++void gcry_mpi_mul_ui (gcry_mpi_t w, gcry_mpi_t u, unsigned long v ); ++ ++/* W = U * V mod M. */ ++void gcry_mpi_mulm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m); ++ ++/* W = U * (2 ^ CNT). */ ++void gcry_mpi_mul_2exp (gcry_mpi_t w, gcry_mpi_t u, unsigned long cnt); ++ ++/* Q = DIVIDEND / DIVISOR, R = DIVIDEND % DIVISOR, ++ Q or R may be passed as NULL. ROUND should be negative or 0. */ ++void gcry_mpi_div (gcry_mpi_t q, gcry_mpi_t r, ++ gcry_mpi_t dividend, gcry_mpi_t divisor, int round); ++ ++/* R = DIVIDEND % DIVISOR */ ++void gcry_mpi_mod (gcry_mpi_t r, gcry_mpi_t dividend, gcry_mpi_t divisor); ++ ++/* W = B ^ E mod M. */ ++void gcry_mpi_powm (gcry_mpi_t w, ++ const gcry_mpi_t b, const gcry_mpi_t e, ++ const gcry_mpi_t m); ++ ++/* Set G to the greatest common divisor of A and B. ++ Return true if the G is 1. */ ++int gcry_mpi_gcd (gcry_mpi_t g, gcry_mpi_t a, gcry_mpi_t b); ++ ++/* Set X to the multiplicative inverse of A mod M. ++ Return true if the value exists. */ ++int gcry_mpi_invm (gcry_mpi_t x, gcry_mpi_t a, gcry_mpi_t m); ++ ++ ++/* Return the number of bits required to represent A. */ ++unsigned int gcry_mpi_get_nbits (gcry_mpi_t a); ++ ++/* Return true when bit number N (counting from 0) is set in A. */ ++int gcry_mpi_test_bit (gcry_mpi_t a, unsigned int n); ++ ++/* Set bit number N in A. */ ++void gcry_mpi_set_bit (gcry_mpi_t a, unsigned int n); ++ ++/* Clear bit number N in A. */ ++void gcry_mpi_clear_bit (gcry_mpi_t a, unsigned int n); ++ ++/* Set bit number N in A and clear all bits greater than N. */ ++void gcry_mpi_set_highbit (gcry_mpi_t a, unsigned int n); ++ ++/* Clear bit number N in A and all bits greater than N. */ ++void gcry_mpi_clear_highbit (gcry_mpi_t a, unsigned int n); ++ ++/* Shift the value of A by N bits to the right and store the result in X. */ ++void gcry_mpi_rshift (gcry_mpi_t x, gcry_mpi_t a, unsigned int n); ++ ++/* Shift the value of A by N bits to the left and store the result in X. */ ++void gcry_mpi_lshift (gcry_mpi_t x, gcry_mpi_t a, unsigned int n); ++ ++/* Store NBITS of the value P points to in A and mark A as an opaque ++ value. WARNING: Never use an opaque MPI for anything thing else then ++ gcry_mpi_release, gcry_mpi_get_opaque. */ ++gcry_mpi_t gcry_mpi_set_opaque (gcry_mpi_t a, void *p, unsigned int nbits); ++ ++/* Return a pointer to an opaque value stored in A and return its size ++ in NBITS. Note that the returned pointer is still owned by A and ++ that the function should never be used for an non-opaque MPI. */ ++void *gcry_mpi_get_opaque (gcry_mpi_t a, unsigned int *nbits); ++ ++/* Set the FLAG for the big integer A. Currently only the flag ++ GCRYMPI_FLAG_SECURE is allowed to convert A into an big intger ++ stored in "secure" memory. */ ++void gcry_mpi_set_flag (gcry_mpi_t a, enum gcry_mpi_flag flag); ++ ++/* Clear FLAG for the big integer A. Note that this function is ++ currently useless as no flags are allowed. */ ++void gcry_mpi_clear_flag (gcry_mpi_t a, enum gcry_mpi_flag flag); ++ ++/* Return true when the FLAG is set for A. */ ++int gcry_mpi_get_flag (gcry_mpi_t a, enum gcry_mpi_flag flag); ++ ++/* Unless the GCRYPT_NO_MPI_MACROS is used, provide a couple of ++ convenience macros for the big integer functions. */ ++#ifndef GCRYPT_NO_MPI_MACROS ++#define mpi_new(n) gcry_mpi_new( (n) ) ++#define mpi_secure_new( n ) gcry_mpi_snew( (n) ) ++#define mpi_release(a) \ ++ do \ ++ { \ ++ gcry_mpi_release ((a)); \ ++ (a) = NULL; \ ++ } \ ++ while (0) ++ ++#define mpi_copy( a ) gcry_mpi_copy( (a) ) ++#define mpi_set( w, u) gcry_mpi_set( (w), (u) ) ++#define mpi_set_ui( w, u) gcry_mpi_set_ui( (w), (u) ) ++#define mpi_cmp( u, v ) gcry_mpi_cmp( (u), (v) ) ++#define mpi_cmp_ui( u, v ) gcry_mpi_cmp_ui( (u), (v) ) ++ ++#define mpi_add_ui(w,u,v) gcry_mpi_add_ui((w),(u),(v)) ++#define mpi_add(w,u,v) gcry_mpi_add ((w),(u),(v)) ++#define mpi_addm(w,u,v,m) gcry_mpi_addm ((w),(u),(v),(m)) ++#define mpi_sub_ui(w,u,v) gcry_mpi_sub_ui ((w),(u),(v)) ++#define mpi_sub(w,u,v) gcry_mpi_sub ((w),(u),(v)) ++#define mpi_subm(w,u,v,m) gcry_mpi_subm ((w),(u),(v),(m)) ++#define mpi_mul_ui(w,u,v) gcry_mpi_mul_ui ((w),(u),(v)) ++#define mpi_mul_2exp(w,u,v) gcry_mpi_mul_2exp ((w),(u),(v)) ++#define mpi_mul(w,u,v) gcry_mpi_mul ((w),(u),(v)) ++#define mpi_mulm(w,u,v,m) gcry_mpi_mulm ((w),(u),(v),(m)) ++#define mpi_powm(w,b,e,m) gcry_mpi_powm ( (w), (b), (e), (m) ) ++#define mpi_tdiv(q,r,a,m) gcry_mpi_div ( (q), (r), (a), (m), 0) ++#define mpi_fdiv(q,r,a,m) gcry_mpi_div ( (q), (r), (a), (m), -1) ++#define mpi_mod(r,a,m) gcry_mpi_mod ((r), (a), (m)) ++#define mpi_gcd(g,a,b) gcry_mpi_gcd ( (g), (a), (b) ) ++#define mpi_invm(g,a,b) gcry_mpi_invm ( (g), (a), (b) ) ++ ++#define mpi_get_nbits(a) gcry_mpi_get_nbits ((a)) ++#define mpi_test_bit(a,b) gcry_mpi_test_bit ((a),(b)) ++#define mpi_set_bit(a,b) gcry_mpi_set_bit ((a),(b)) ++#define mpi_set_highbit(a,b) gcry_mpi_set_highbit ((a),(b)) ++#define mpi_clear_bit(a,b) gcry_mpi_clear_bit ((a),(b)) ++#define mpi_clear_highbit(a,b) gcry_mpi_clear_highbit ((a),(b)) ++#define mpi_rshift(a,b,c) gcry_mpi_rshift ((a),(b),(c)) ++#define mpi_lshift(a,b,c) gcry_mpi_lshift ((a),(b),(c)) ++ ++#define mpi_set_opaque(a,b,c) gcry_mpi_set_opaque( (a), (b), (c) ) ++#define mpi_get_opaque(a,b) gcry_mpi_get_opaque( (a), (b) ) ++#endif /* GCRYPT_NO_MPI_MACROS */ ++ ++ ++ ++/************************************ ++ * * ++ * Symmetric Cipher Functions * ++ * * ++ ************************************/ ++ ++/* The data object used to hold a handle to an encryption object. */ ++struct gcry_cipher_handle; ++typedef struct gcry_cipher_handle *gcry_cipher_hd_t; ++ ++#ifndef GCRYPT_NO_DEPRECATED ++typedef struct gcry_cipher_handle *GCRY_CIPHER_HD _GCRY_GCC_ATTR_DEPRECATED; ++typedef struct gcry_cipher_handle *GcryCipherHd _GCRY_GCC_ATTR_DEPRECATED; ++#endif ++ ++/* All symmetric encryption algorithms are identified by their IDs. ++ More IDs may be registered at runtime. */ ++enum gcry_cipher_algos ++ { ++ GCRY_CIPHER_NONE = 0, ++ GCRY_CIPHER_IDEA = 1, ++ GCRY_CIPHER_3DES = 2, ++ GCRY_CIPHER_CAST5 = 3, ++ GCRY_CIPHER_BLOWFISH = 4, ++ GCRY_CIPHER_SAFER_SK128 = 5, ++ GCRY_CIPHER_DES_SK = 6, ++ GCRY_CIPHER_AES = 7, ++ GCRY_CIPHER_AES192 = 8, ++ GCRY_CIPHER_AES256 = 9, ++ GCRY_CIPHER_TWOFISH = 10, ++ ++ /* Other cipher numbers are above 300 for OpenPGP reasons. */ ++ GCRY_CIPHER_ARCFOUR = 301, /* Fully compatible with RSA's RC4 (tm). */ ++ GCRY_CIPHER_DES = 302, /* Yes, this is single key 56 bit DES. */ ++ GCRY_CIPHER_TWOFISH128 = 303, ++ GCRY_CIPHER_SERPENT128 = 304, ++ GCRY_CIPHER_SERPENT192 = 305, ++ GCRY_CIPHER_SERPENT256 = 306, ++ GCRY_CIPHER_RFC2268_40 = 307, /* Ron's Cipher 2 (40 bit). */ ++ GCRY_CIPHER_RFC2268_128 = 308, /* Ron's Cipher 2 (128 bit). */ ++ GCRY_CIPHER_SEED = 309, /* 128 bit cipher described in RFC4269. */ ++ GCRY_CIPHER_CAMELLIA128 = 310, ++ GCRY_CIPHER_CAMELLIA192 = 311, ++ GCRY_CIPHER_CAMELLIA256 = 312 ++ }; ++ ++/* The Rijndael algorithm is basically AES, so provide some macros. */ ++#define GCRY_CIPHER_AES128 GCRY_CIPHER_AES ++#define GCRY_CIPHER_RIJNDAEL GCRY_CIPHER_AES ++#define GCRY_CIPHER_RIJNDAEL128 GCRY_CIPHER_AES128 ++#define GCRY_CIPHER_RIJNDAEL192 GCRY_CIPHER_AES192 ++#define GCRY_CIPHER_RIJNDAEL256 GCRY_CIPHER_AES256 ++ ++/* The supported encryption modes. Note that not all of them are ++ supported for each algorithm. */ ++enum gcry_cipher_modes ++ { ++ GCRY_CIPHER_MODE_NONE = 0, /* Not yet specified. */ ++ GCRY_CIPHER_MODE_ECB = 1, /* Electronic codebook. */ ++ GCRY_CIPHER_MODE_CFB = 2, /* Cipher feedback. */ ++ GCRY_CIPHER_MODE_CBC = 3, /* Cipher block chaining. */ ++ GCRY_CIPHER_MODE_STREAM = 4, /* Used with stream ciphers. */ ++ GCRY_CIPHER_MODE_OFB = 5, /* Outer feedback. */ ++ GCRY_CIPHER_MODE_CTR = 6, /* Counter. */ ++ GCRY_CIPHER_MODE_AESWRAP= 7 /* AES-WRAP algorithm. */ ++ }; ++ ++/* Flags used with the open function. */ ++enum gcry_cipher_flags ++ { ++ GCRY_CIPHER_SECURE = 1, /* Allocate in secure memory. */ ++ GCRY_CIPHER_ENABLE_SYNC = 2, /* Enable CFB sync mode. */ ++ GCRY_CIPHER_CBC_CTS = 4, /* Enable CBC cipher text stealing (CTS). */ ++ GCRY_CIPHER_CBC_MAC = 8 /* Enable CBC message auth. code (MAC). */ ++ }; ++ ++ ++/* Create a handle for algorithm ALGO to be used in MODE. FLAGS may ++ be given as an bitwise OR of the gcry_cipher_flags values. */ ++gcry_error_t gcry_cipher_open (gcry_cipher_hd_t *handle, ++ int algo, int mode, unsigned int flags); ++ ++/* Close the cioher handle H and release all resource. */ ++void gcry_cipher_close (gcry_cipher_hd_t h); ++ ++/* Perform various operations on the cipher object H. */ ++gcry_error_t gcry_cipher_ctl (gcry_cipher_hd_t h, int cmd, void *buffer, ++ size_t buflen); ++ ++/* Retrieve various information about the cipher object H. */ ++gcry_error_t gcry_cipher_info (gcry_cipher_hd_t h, int what, void *buffer, ++ size_t *nbytes); ++ ++/* Retrieve various information about the cipher algorithm ALGO. */ ++gcry_error_t gcry_cipher_algo_info (int algo, int what, void *buffer, ++ size_t *nbytes); ++ ++/* Map the cipher algorithm whose ID is contained in ALGORITHM to a ++ string representation of the algorithm name. For unknown algorithm ++ IDs this function returns "?". */ ++const char *gcry_cipher_algo_name (int algorithm) _GCRY_GCC_ATTR_PURE; ++ ++/* Map the algorithm name NAME to an cipher algorithm ID. Return 0 if ++ the algorithm name is not known. */ ++int gcry_cipher_map_name (const char *name) _GCRY_GCC_ATTR_PURE; ++ ++/* Given an ASN.1 object identifier in standard IETF dotted decimal ++ format in STRING, return the encryption mode associated with that ++ OID or 0 if not known or applicable. */ ++int gcry_cipher_mode_from_oid (const char *string) _GCRY_GCC_ATTR_PURE; ++ ++/* Encrypt the plaintext of size INLEN in IN using the cipher handle H ++ into the buffer OUT which has an allocated length of OUTSIZE. For ++ most algorithms it is possible to pass NULL for in and 0 for INLEN ++ and do a in-place decryption of the data provided in OUT. */ ++gcry_error_t gcry_cipher_encrypt (gcry_cipher_hd_t h, ++ void *out, size_t outsize, ++ const void *in, size_t inlen); ++ ++/* The counterpart to gcry_cipher_encrypt. */ ++gcry_error_t gcry_cipher_decrypt (gcry_cipher_hd_t h, ++ void *out, size_t outsize, ++ const void *in, size_t inlen); ++ ++/* Set KEY of length KEYLEN bytes for the cipher handle HD. */ ++gcry_error_t gcry_cipher_setkey (gcry_cipher_hd_t hd, ++ const void *key, size_t keylen); ++ ++ ++/* Set initialization vector IV of length IVLEN for the cipher handle HD. */ ++gcry_error_t gcry_cipher_setiv (gcry_cipher_hd_t hd, ++ const void *iv, size_t ivlen); ++ ++ ++/* Reset the handle to the state after open. */ ++#define gcry_cipher_reset(h) gcry_cipher_ctl ((h), GCRYCTL_RESET, NULL, 0) ++ ++/* Perform the OpenPGP sync operation if this is enabled for the ++ cipher handle H. */ ++#define gcry_cipher_sync(h) gcry_cipher_ctl( (h), GCRYCTL_CFB_SYNC, NULL, 0) ++ ++/* Enable or disable CTS in future calls to gcry_encrypt(). CBC mode only. */ ++#define gcry_cipher_cts(h,on) gcry_cipher_ctl( (h), GCRYCTL_SET_CBC_CTS, \ ++ NULL, on ) ++ ++/* Set counter for CTR mode. (CTR,CTRLEN) must denote a buffer of ++ block size length, or (NULL,0) to set the CTR to the all-zero block. */ ++gpg_error_t gcry_cipher_setctr (gcry_cipher_hd_t hd, ++ const void *ctr, size_t ctrlen); ++ ++/* Retrieve the key length in bytes used with algorithm A. */ ++size_t gcry_cipher_get_algo_keylen (int algo); ++ ++/* Retrieve the block length in bytes used with algorithm A. */ ++size_t gcry_cipher_get_algo_blklen (int algo); ++ ++/* Return 0 if the algorithm A is available for use. */ ++#define gcry_cipher_test_algo(a) \ ++ gcry_cipher_algo_info( (a), GCRYCTL_TEST_ALGO, NULL, NULL ) ++ ++ ++/************************************ ++ * * ++ * Asymmetric Cipher Functions * ++ * * ++ ************************************/ ++ ++/* The algorithms and their IDs we support. */ ++enum gcry_pk_algos ++ { ++ GCRY_PK_RSA = 1, ++ GCRY_PK_RSA_E = 2, /* (deprecated) */ ++ GCRY_PK_RSA_S = 3, /* (deprecated) */ ++ GCRY_PK_ELG_E = 16, ++ GCRY_PK_DSA = 17, ++ GCRY_PK_ELG = 20, ++ GCRY_PK_ECDSA = 301, ++ GCRY_PK_ECDH = 302 ++ }; ++ ++/* Flags describing usage capabilities of a PK algorithm. */ ++#define GCRY_PK_USAGE_SIGN 1 /* Good for signatures. */ ++#define GCRY_PK_USAGE_ENCR 2 /* Good for encryption. */ ++#define GCRY_PK_USAGE_CERT 4 /* Good to certify other keys. */ ++#define GCRY_PK_USAGE_AUTH 8 /* Good for authentication. */ ++#define GCRY_PK_USAGE_UNKN 128 /* Unknown usage flag. */ ++ ++/* Encrypt the DATA using the public key PKEY and store the result as ++ a newly created S-expression at RESULT. */ ++gcry_error_t gcry_pk_encrypt (gcry_sexp_t *result, ++ gcry_sexp_t data, gcry_sexp_t pkey); ++ ++/* Decrypt the DATA using the private key SKEY and store the result as ++ a newly created S-expression at RESULT. */ ++gcry_error_t gcry_pk_decrypt (gcry_sexp_t *result, ++ gcry_sexp_t data, gcry_sexp_t skey); ++ ++/* Sign the DATA using the private key SKEY and store the result as ++ a newly created S-expression at RESULT. */ ++gcry_error_t gcry_pk_sign (gcry_sexp_t *result, ++ gcry_sexp_t data, gcry_sexp_t skey); ++ ++/* Check the signature SIGVAL on DATA using the public key PKEY. */ ++gcry_error_t gcry_pk_verify (gcry_sexp_t sigval, ++ gcry_sexp_t data, gcry_sexp_t pkey); ++ ++/* Check that private KEY is sane. */ ++gcry_error_t gcry_pk_testkey (gcry_sexp_t key); ++ ++/* Generate a new key pair according to the parameters given in ++ S_PARMS. The new key pair is returned in as an S-expression in ++ R_KEY. */ ++gcry_error_t gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms); ++ ++/* Catch all function for miscellaneous operations. */ ++gcry_error_t gcry_pk_ctl (int cmd, void *buffer, size_t buflen); ++ ++/* Retrieve information about the public key algorithm ALGO. */ ++gcry_error_t gcry_pk_algo_info (int algo, int what, ++ void *buffer, size_t *nbytes); ++ ++/* Map the public key algorithm whose ID is contained in ALGORITHM to ++ a string representation of the algorithm name. For unknown ++ algorithm IDs this functions returns "?". */ ++const char *gcry_pk_algo_name (int algorithm) _GCRY_GCC_ATTR_PURE; ++ ++/* Map the algorithm NAME to a public key algorithm Id. Return 0 if ++ the algorithm name is not known. */ ++int gcry_pk_map_name (const char* name) _GCRY_GCC_ATTR_PURE; ++ ++/* Return what is commonly referred as the key length for the given ++ public or private KEY. */ ++unsigned int gcry_pk_get_nbits (gcry_sexp_t key) _GCRY_GCC_ATTR_PURE; ++ ++/* Please note that keygrip is still experimental and should not be ++ used without contacting the author. */ ++unsigned char *gcry_pk_get_keygrip (gcry_sexp_t key, unsigned char *array); ++ ++/* Return the name of the curve matching KEY. */ ++const char *gcry_pk_get_curve (gcry_sexp_t key, int iterator, ++ unsigned int *r_nbits); ++ ++/* Return an S-expression with the parameters of the named ECC curve ++ NAME. ALGO must be set to an ECC algorithm. */ ++gcry_sexp_t gcry_pk_get_param (int algo, const char *name); ++ ++/* Return 0 if the public key algorithm A is available for use. */ ++#define gcry_pk_test_algo(a) \ ++ gcry_pk_algo_info( (a), GCRYCTL_TEST_ALGO, NULL, NULL ) ++ ++ ++ ++ ++/************************************ ++ * * ++ * Cryptograhic Hash Functions * ++ * * ++ ************************************/ ++ ++/* Algorithm IDs for the hash functions we know about. Not all of them ++ are implemnted. */ ++enum gcry_md_algos ++ { ++ GCRY_MD_NONE = 0, ++ GCRY_MD_MD5 = 1, ++ GCRY_MD_SHA1 = 2, ++ GCRY_MD_RMD160 = 3, ++ GCRY_MD_MD2 = 5, ++ GCRY_MD_TIGER = 6, /* TIGER/192 as used by gpg <= 1.3.2. */ ++ GCRY_MD_HAVAL = 7, /* HAVAL, 5 pass, 160 bit. */ ++ GCRY_MD_SHA256 = 8, ++ GCRY_MD_SHA384 = 9, ++ GCRY_MD_SHA512 = 10, ++ GCRY_MD_SHA224 = 11, ++ GCRY_MD_MD4 = 301, ++ GCRY_MD_CRC32 = 302, ++ GCRY_MD_CRC32_RFC1510 = 303, ++ GCRY_MD_CRC24_RFC2440 = 304, ++ GCRY_MD_WHIRLPOOL = 305, ++ GCRY_MD_TIGER1 = 306, /* TIGER fixed. */ ++ GCRY_MD_TIGER2 = 307 /* TIGER2 variant. */ ++ }; ++ ++/* Flags used with the open function. */ ++enum gcry_md_flags ++ { ++ GCRY_MD_FLAG_SECURE = 1, /* Allocate all buffers in "secure" memory. */ ++ GCRY_MD_FLAG_HMAC = 2 /* Make an HMAC out of this algorithm. */ ++ }; ++ ++/* (Forward declaration.) */ ++struct gcry_md_context; ++ ++/* This object is used to hold a handle to a message digest object. ++ This structure is private - only to be used by the public gcry_md_* ++ macros. */ ++typedef struct gcry_md_handle ++{ ++ /* Actual context. */ ++ struct gcry_md_context *ctx; ++ ++ /* Buffer management. */ ++ int bufpos; ++ int bufsize; ++ unsigned char buf[1]; ++} *gcry_md_hd_t; ++ ++/* Compatibility types, do not use them. */ ++#ifndef GCRYPT_NO_DEPRECATED ++typedef struct gcry_md_handle *GCRY_MD_HD _GCRY_GCC_ATTR_DEPRECATED; ++typedef struct gcry_md_handle *GcryMDHd _GCRY_GCC_ATTR_DEPRECATED; ++#endif ++ ++/* Create a message digest object for algorithm ALGO. FLAGS may be ++ given as an bitwise OR of the gcry_md_flags values. ALGO may be ++ given as 0 if the algorithms to be used are later set using ++ gcry_md_enable. */ ++gcry_error_t gcry_md_open (gcry_md_hd_t *h, int algo, unsigned int flags); ++ ++/* Release the message digest object HD. */ ++void gcry_md_close (gcry_md_hd_t hd); ++ ++/* Add the message digest algorithm ALGO to the digest object HD. */ ++gcry_error_t gcry_md_enable (gcry_md_hd_t hd, int algo); ++ ++/* Create a new digest object as an exact copy of the object HD. */ ++gcry_error_t gcry_md_copy (gcry_md_hd_t *bhd, gcry_md_hd_t ahd); ++ ++/* Reset the digest object HD to its initial state. */ ++void gcry_md_reset (gcry_md_hd_t hd); ++ ++/* Perform various operations on the digest object HD. */ ++gcry_error_t gcry_md_ctl (gcry_md_hd_t hd, int cmd, ++ void *buffer, size_t buflen); ++ ++/* Pass LENGTH bytes of data in BUFFER to the digest object HD so that ++ it can update the digest values. This is the actual hash ++ function. */ ++void gcry_md_write (gcry_md_hd_t hd, const void *buffer, size_t length); ++ ++/* Read out the final digest from HD return the digest value for ++ algorithm ALGO. */ ++unsigned char *gcry_md_read (gcry_md_hd_t hd, int algo); ++ ++/* Convenience function to calculate the hash from the data in BUFFER ++ of size LENGTH using the algorithm ALGO avoiding the creating of a ++ hash object. The hash is returned in the caller provided buffer ++ DIGEST which must be large enough to hold the digest of the given ++ algorithm. */ ++void gcry_md_hash_buffer (int algo, void *digest, ++ const void *buffer, size_t length); ++ ++/* Retrieve the algorithm used with HD. This does not work reliable ++ if more than one algorithm is enabled in HD. */ ++int gcry_md_get_algo (gcry_md_hd_t hd); ++ ++/* Retrieve the length in bytes of the digest yielded by algorithm ++ ALGO. */ ++unsigned int gcry_md_get_algo_dlen (int algo); ++ ++/* Return true if the the algorithm ALGO is enabled in the digest ++ object A. */ ++int gcry_md_is_enabled (gcry_md_hd_t a, int algo); ++ ++/* Return true if the digest object A is allocated in "secure" memory. */ ++int gcry_md_is_secure (gcry_md_hd_t a); ++ ++/* Retrieve various information about the object H. */ ++gcry_error_t gcry_md_info (gcry_md_hd_t h, int what, void *buffer, ++ size_t *nbytes); ++ ++/* Retrieve various information about the algorithm ALGO. */ ++gcry_error_t gcry_md_algo_info (int algo, int what, void *buffer, ++ size_t *nbytes); ++ ++/* Map the digest algorithm id ALGO to a string representation of the ++ algorithm name. For unknown algorithms this function returns ++ "?". */ ++const char *gcry_md_algo_name (int algo) _GCRY_GCC_ATTR_PURE; ++ ++/* Map the algorithm NAME to a digest algorithm Id. Return 0 if ++ the algorithm name is not known. */ ++int gcry_md_map_name (const char* name) _GCRY_GCC_ATTR_PURE; ++ ++/* For use with the HMAC feature, the set MAC key to the KEY of ++ KEYLEN bytes. */ ++gcry_error_t gcry_md_setkey (gcry_md_hd_t hd, const void *key, size_t keylen); ++ ++/* Start or stop debugging for digest handle HD; i.e. create a file ++ named dbgmd-. while hashing. If SUFFIX is NULL, ++ debugging stops and the file will be closed. */ ++void gcry_md_debug (gcry_md_hd_t hd, const char *suffix); ++ ++ ++/* Update the hash(s) of H with the character C. This is a buffered ++ version of the gcry_md_write function. */ ++#define gcry_md_putc(h,c) \ ++ do { \ ++ gcry_md_hd_t h__ = (h); \ ++ if( (h__)->bufpos == (h__)->bufsize ) \ ++ gcry_md_write( (h__), NULL, 0 ); \ ++ (h__)->buf[(h__)->bufpos++] = (c) & 0xff; \ ++ } while(0) ++ ++/* Finalize the digest calculation. This is not really needed because ++ gcry_md_read() does this implicitly. */ ++#define gcry_md_final(a) \ ++ gcry_md_ctl ((a), GCRYCTL_FINALIZE, NULL, 0) ++ ++/* Return 0 if the algorithm A is available for use. */ ++#define gcry_md_test_algo(a) \ ++ gcry_md_algo_info( (a), GCRYCTL_TEST_ALGO, NULL, NULL ) ++ ++/* Return an DER encoded ASN.1 OID for the algorithm A in buffer B. N ++ must point to size_t variable with the available size of buffer B. ++ After return it will receive the actual size of the returned ++ OID. */ ++#define gcry_md_get_asnoid(a,b,n) \ ++ gcry_md_algo_info((a), GCRYCTL_GET_ASNOID, (b), (n)) ++ ++ ++ ++/****************************** ++ * * ++ * Key Derivation Functions * ++ * * ++ ******************************/ ++ ++/* Algorithm IDs for the KDFs. */ ++enum gcry_kdf_algos ++ { ++ GCRY_KDF_NONE = 0, ++ GCRY_KDF_SIMPLE_S2K = 16, ++ GCRY_KDF_SALTED_S2K = 17, ++ GCRY_KDF_ITERSALTED_S2K = 19, ++ GCRY_KDF_PBKDF1 = 33, ++ GCRY_KDF_PBKDF2 = 34 ++ }; ++ ++/* Derive a key from a passphrase. */ ++gpg_error_t gcry_kdf_derive (const void *passphrase, size_t passphraselen, ++ int algo, int subalgo, ++ const void *salt, size_t saltlen, ++ unsigned long iterations, ++ size_t keysize, void *keybuffer); ++ ++ ++ ++ ++/************************************ ++ * * ++ * Random Generating Functions * ++ * * ++ ************************************/ ++ ++/* The possible values for the random quality. The rule of thumb is ++ to use STRONG for session keys and VERY_STRONG for key material. ++ WEAK is usually an alias for STRONG and should not be used anymore ++ (except with gcry_mpi_randomize); use gcry_create_nonce instead. */ ++typedef enum gcry_random_level ++ { ++ GCRY_WEAK_RANDOM = 0, ++ GCRY_STRONG_RANDOM = 1, ++ GCRY_VERY_STRONG_RANDOM = 2 ++ } ++gcry_random_level_t; ++ ++/* Fill BUFFER with LENGTH bytes of random, using random numbers of ++ quality LEVEL. */ ++void gcry_randomize (void *buffer, size_t length, ++ enum gcry_random_level level); ++ ++/* Add the external random from BUFFER with LENGTH bytes into the ++ pool. QUALITY should either be -1 for unknown or in the range of 0 ++ to 100 */ ++gcry_error_t gcry_random_add_bytes (const void *buffer, size_t length, ++ int quality); ++ ++/* If random numbers are used in an application, this macro should be ++ called from time to time so that new stuff gets added to the ++ internal pool of the RNG. */ ++#define gcry_fast_random_poll() gcry_control (GCRYCTL_FAST_POLL, NULL) ++ ++ ++/* Return NBYTES of allocated random using a random numbers of quality ++ LEVEL. */ ++void *gcry_random_bytes (size_t nbytes, enum gcry_random_level level) ++ _GCRY_GCC_ATTR_MALLOC; ++ ++/* Return NBYTES of allocated random using a random numbers of quality ++ LEVEL. The random numbers are created returned in "secure" ++ memory. */ ++void *gcry_random_bytes_secure (size_t nbytes, enum gcry_random_level level) ++ _GCRY_GCC_ATTR_MALLOC; ++ ++ ++/* Set the big integer W to a random value of NBITS using a random ++ generator with quality LEVEL. Note that by using a level of ++ GCRY_WEAK_RANDOM gcry_create_nonce is used internally. */ ++void gcry_mpi_randomize (gcry_mpi_t w, ++ unsigned int nbits, enum gcry_random_level level); ++ ++ ++/* Create an unpredicable nonce of LENGTH bytes in BUFFER. */ ++void gcry_create_nonce (void *buffer, size_t length); ++ ++ ++ ++ ++ ++/*******************************/ ++/* */ ++/* Prime Number Functions */ ++/* */ ++/*******************************/ ++ ++/* Mode values passed to a gcry_prime_check_func_t. */ ++#define GCRY_PRIME_CHECK_AT_FINISH 0 ++#define GCRY_PRIME_CHECK_AT_GOT_PRIME 1 ++#define GCRY_PRIME_CHECK_AT_MAYBE_PRIME 2 ++ ++/* The function should return 1 if the operation shall continue, 0 to ++ reject the prime candidate. */ ++typedef int (*gcry_prime_check_func_t) (void *arg, int mode, ++ gcry_mpi_t candidate); ++ ++/* Flags for gcry_prime_generate(): */ ++ ++/* Allocate prime numbers and factors in secure memory. */ ++#define GCRY_PRIME_FLAG_SECRET (1 << 0) ++ ++/* Make sure that at least one prime factor is of size ++ `FACTOR_BITS'. */ ++#define GCRY_PRIME_FLAG_SPECIAL_FACTOR (1 << 1) ++ ++/* Generate a new prime number of PRIME_BITS bits and store it in ++ PRIME. If FACTOR_BITS is non-zero, one of the prime factors of ++ (prime - 1) / 2 must be FACTOR_BITS bits long. If FACTORS is ++ non-zero, allocate a new, NULL-terminated array holding the prime ++ factors and store it in FACTORS. FLAGS might be used to influence ++ the prime number generation process. */ ++gcry_error_t gcry_prime_generate (gcry_mpi_t *prime, ++ unsigned int prime_bits, ++ unsigned int factor_bits, ++ gcry_mpi_t **factors, ++ gcry_prime_check_func_t cb_func, ++ void *cb_arg, ++ gcry_random_level_t random_level, ++ unsigned int flags); ++ ++/* Find a generator for PRIME where the factorization of (prime-1) is ++ in the NULL terminated array FACTORS. Return the generator as a ++ newly allocated MPI in R_G. If START_G is not NULL, use this as ++ teh start for the search. */ ++gcry_error_t gcry_prime_group_generator (gcry_mpi_t *r_g, ++ gcry_mpi_t prime, ++ gcry_mpi_t *factors, ++ gcry_mpi_t start_g); ++ ++ ++/* Convenience function to release the FACTORS array. */ ++void gcry_prime_release_factors (gcry_mpi_t *factors); ++ ++ ++/* Check wether the number X is prime. */ ++gcry_error_t gcry_prime_check (gcry_mpi_t x, unsigned int flags); ++ ++ ++ ++/************************************ ++ * * ++ * Miscellaneous Stuff * ++ * * ++ ************************************/ ++ ++/* Log levels used by the internal logging facility. */ ++enum gcry_log_levels ++ { ++ GCRY_LOG_CONT = 0, /* (Continue the last log line.) */ ++ GCRY_LOG_INFO = 10, ++ GCRY_LOG_WARN = 20, ++ GCRY_LOG_ERROR = 30, ++ GCRY_LOG_FATAL = 40, ++ GCRY_LOG_BUG = 50, ++ GCRY_LOG_DEBUG = 100 ++ }; ++ ++/* Type for progress handlers. */ ++typedef void (*gcry_handler_progress_t) (void *, const char *, int, int, int); ++ ++/* Type for memory allocation handlers. */ ++typedef void *(*gcry_handler_alloc_t) (size_t n); ++ ++/* Type for secure memory check handlers. */ ++typedef int (*gcry_handler_secure_check_t) (const void *); ++ ++/* Type for memory reallocation handlers. */ ++typedef void *(*gcry_handler_realloc_t) (void *p, size_t n); ++ ++/* Type for memory free handlers. */ ++typedef void (*gcry_handler_free_t) (void *); ++ ++/* Type for out-of-memory handlers. */ ++typedef int (*gcry_handler_no_mem_t) (void *, size_t, unsigned int); ++ ++/* Type for fatal error handlers. */ ++typedef void (*gcry_handler_error_t) (void *, int, const char *); ++ ++/* Type for logging handlers. */ ++typedef void (*gcry_handler_log_t) (void *, int, const char *, va_list); ++ ++/* Certain operations can provide progress information. This function ++ is used to register a handler for retrieving these information. */ ++void gcry_set_progress_handler (gcry_handler_progress_t cb, void *cb_data); ++ ++ ++/* Register a custom memory allocation functions. */ ++void gcry_set_allocation_handler ( ++ gcry_handler_alloc_t func_alloc, ++ gcry_handler_alloc_t func_alloc_secure, ++ gcry_handler_secure_check_t func_secure_check, ++ gcry_handler_realloc_t func_realloc, ++ gcry_handler_free_t func_free); ++ ++/* Register a function used instead of the internal out of memory ++ handler. */ ++void gcry_set_outofcore_handler (gcry_handler_no_mem_t h, void *opaque); ++ ++/* Register a function used instead of the internal fatal error ++ handler. */ ++void gcry_set_fatalerror_handler (gcry_handler_error_t fnc, void *opaque); ++ ++/* Register a function used instead of the internal logging ++ facility. */ ++void gcry_set_log_handler (gcry_handler_log_t f, void *opaque); ++ ++/* Reserved for future use. */ ++void gcry_set_gettext_handler (const char *(*f)(const char*)); ++ ++/* Libgcrypt uses its own memory allocation. It is important to use ++ gcry_free () to release memory allocated by libgcrypt. */ ++void *gcry_malloc (size_t n) _GCRY_GCC_ATTR_MALLOC; ++void *gcry_calloc (size_t n, size_t m) _GCRY_GCC_ATTR_MALLOC; ++void *gcry_malloc_secure (size_t n) _GCRY_GCC_ATTR_MALLOC; ++void *gcry_calloc_secure (size_t n, size_t m) _GCRY_GCC_ATTR_MALLOC; ++void *gcry_realloc (void *a, size_t n); ++char *gcry_strdup (const char *string) _GCRY_GCC_ATTR_MALLOC; ++void *gcry_xmalloc (size_t n) _GCRY_GCC_ATTR_MALLOC; ++void *gcry_xcalloc (size_t n, size_t m) _GCRY_GCC_ATTR_MALLOC; ++void *gcry_xmalloc_secure (size_t n) _GCRY_GCC_ATTR_MALLOC; ++void *gcry_xcalloc_secure (size_t n, size_t m) _GCRY_GCC_ATTR_MALLOC; ++void *gcry_xrealloc (void *a, size_t n); ++char *gcry_xstrdup (const char * a) _GCRY_GCC_ATTR_MALLOC; ++void gcry_free (void *a); ++ ++/* Return true if A is allocated in "secure" memory. */ ++int gcry_is_secure (const void *a) _GCRY_GCC_ATTR_PURE; ++ ++/* Return true if Libgcrypt is in FIPS mode. */ ++#define gcry_fips_mode_active() !!gcry_control (GCRYCTL_FIPS_MODE_P, 0) ++ ++ ++#if 0 /* (Keep Emacsens' auto-indent happy.) */ ++{ ++#endif ++#ifdef __cplusplus ++} ++#endif ++#endif /* _GCRYPT_H */ ++/* ++@emacs_local_vars_begin@ ++@emacs_local_vars_read_only@ ++@emacs_local_vars_end@ ++*/ +diff --git a/grub-core/lib/libgcrypt/src/gcryptrnd.c b/grub-core/lib/libgcrypt/src/gcryptrnd.c +new file mode 100644 +index 0000000..b13931b +--- /dev/null ++++ b/grub-core/lib/libgcrypt/src/gcryptrnd.c +@@ -0,0 +1,680 @@ ++/* gcryptrnd.c - Libgcrypt Random Number Daemon ++ * Copyright (C) 2006 Free Software Foundation, Inc. ++ * ++ * Gcryptend 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 of the License, ++ * or (at your option) any later version. ++ * ++ * Gcryptrnd 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. ++ */ ++ ++/* We require vsyslog pth ++ We need to test for: setrlimit ++ ++ We should also prioritize requests. This is best done by putting ++ the requests into queues and have a main thread processing these ++ queues. ++ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define PGM "gcryptrnd" ++#define MYVERSION_LINE PGM " (Libgcrypt) " VERSION ++#define BUGREPORT_LINE "\nReport bugs to .\n" ++ ++/* Pth wrapper function definitions. */ ++GCRY_THREAD_OPTION_PTH_IMPL; ++ ++ ++/* Flag set to true if we have been daemonized. */ ++static int running_detached; ++/* Flag indicating that a shutdown has been requested. */ ++static int shutdown_pending; ++/* Counter for active connections. */ ++static int active_connections; ++ ++ ++ ++/* Local prototypes. */ ++static void serve (int listen_fd); ++ ++ ++ ++ ++ ++/* To avoid that a compiler optimizes certain memset calls away, these ++ macros may be used instead. */ ++#define wipememory2(_ptr,_set,_len) do { \ ++ volatile char *_vptr=(volatile char *)(_ptr); \ ++ size_t _vlen=(_len); \ ++ while(_vlen) { *_vptr=(_set); _vptr++; _vlen--; } \ ++ } while(0) ++#define wipememory(_ptr,_len) wipememory2(_ptr,0,_len) ++ ++ ++ ++ ++/* Error printing utility. PRIORITY should be one of syslog's ++ priority levels. This functions prints to the stderr or syslog ++ depending on whether we are already daemonized. */ ++static void ++logit (int priority, const char *format, ...) ++{ ++ va_list arg_ptr; ++ ++ va_start (arg_ptr, format) ; ++ if (running_detached) ++ { ++ vsyslog (priority, format, arg_ptr); ++ } ++ else ++ { ++ fputs (PGM ": ", stderr); ++ vfprintf (stderr, format, arg_ptr); ++ putc ('\n', stderr); ++ } ++ va_end (arg_ptr); ++} ++ ++/* Callback used by libgcrypt for logging. */ ++static void ++my_gcry_logger (void *dummy, int level, const char *format, va_list arg_ptr) ++{ ++ (void)dummy; ++ ++ /* Map the log levels. */ ++ switch (level) ++ { ++ case GCRY_LOG_CONT: level = LOG_INFO /* FIXME */; break; ++ case GCRY_LOG_INFO: level = LOG_INFO; break; ++ case GCRY_LOG_WARN: level = LOG_WARNING; break; ++ case GCRY_LOG_ERROR:level = LOG_ERR; break; ++ case GCRY_LOG_FATAL:level = LOG_CRIT; break; ++ case GCRY_LOG_BUG: level = LOG_CRIT; break; ++ case GCRY_LOG_DEBUG:level = LOG_DEBUG; break; ++ default: level = LOG_ERR; break; ++ } ++ if (running_detached) ++ { ++ vsyslog (level, format, arg_ptr); ++ } ++ else ++ { ++ fputs (PGM ": ", stderr); ++ vfprintf (stderr, format, arg_ptr); ++ if (!*format || format[strlen (format)-1] != '\n') ++ putc ('\n', stderr); ++ } ++} ++ ++ ++/* The cleanup handler - used to wipe out the secure memory. */ ++static void ++cleanup (void) ++{ ++ gcry_control (GCRYCTL_TERM_SECMEM ); ++} ++ ++ ++/* Make us a daemon and open the syslog. */ ++static void ++daemonize (void) ++{ ++ int i; ++ pid_t pid; ++ ++ fflush (NULL); ++ ++ pid = fork (); ++ if (pid == (pid_t)-1) ++ { ++ logit (LOG_CRIT, "fork failed: %s", strerror (errno)); ++ exit (1); ++ } ++ if (pid) ++ exit (0); ++ ++ if (setsid() == -1) ++ { ++ logit (LOG_CRIT, "setsid() failed: %s", strerror(errno)); ++ exit (1); ++ } ++ ++ signal (SIGHUP, SIG_IGN); ++ ++ pid = fork (); ++ if (pid == (pid_t)-1) ++ { ++ logit (LOG_CRIT, PGM ": second fork failed: %s", strerror (errno)); ++ exit (1); ++ } ++ if (pid) ++ exit (0); /* First child exits. */ ++ ++ running_detached = 1; ++ ++ if (chdir("/")) ++ { ++ logit (LOG_CRIT, "chdir(\"/\") failed: %s", strerror (errno)); ++ exit (1); ++ } ++ umask (0); ++ ++ for (i=0; i <= 2; i++) ++ close (i); ++ ++ openlog (PGM, LOG_PID, LOG_DAEMON); ++} ++ ++ ++static void ++disable_core_dumps (void) ++{ ++#ifdef HAVE_SETRLIMIT ++ struct rlimit limit; ++ ++ if (getrlimit (RLIMIT_CORE, &limit)) ++ limit.rlim_max = 0; ++ limit.rlim_cur = 0; ++ if( !setrlimit (RLIMIT_CORE, &limit) ) ++ return 0; ++ if (errno != EINVAL && errno != ENOSYS) ++ logit (LOG_ERR, "can't disable core dumps: %s\n", strerror (errno)); ++#endif /* HAVE_SETRLIMIT */ ++} ++ ++ ++ ++static void ++print_version (int with_help) ++{ ++ fputs (MYVERSION_LINE "\n" ++ "Copyright (C) 2006 Free Software Foundation, Inc.\n" ++ "License GPLv2+: GNU GPL version 2 or later " ++ "\n" ++ "This is free software: you are free to change and redistribute it.\n" ++ "There is NO WARRANTY, to the extent permitted by law.\n", ++ stdout); ++ ++ if (with_help) ++ fputs ("\n" ++ "Usage: " PGM " [OPTIONS] [SOCKETNAME]\n" ++ "Start Libgcrypt's random number daemon listening" ++ " on socket SOCKETNAME\n" ++ "SOCKETNAME defaults to XXX\n" ++ "\n" ++ " --no-detach do not deatach from the console\n" ++ " --version print version of the program and exit\n" ++ " --help display this help and exit\n" ++ BUGREPORT_LINE, stdout ); ++ ++ exit (0); ++} ++ ++static int ++print_usage (void) ++{ ++ fputs ("usage: " PGM " [OPTIONS] [SOCKETNAME]\n", stderr); ++ fputs (" (use --help to display options)\n", stderr); ++ exit (1); ++} ++ ++ ++int ++main (int argc, char **argv) ++{ ++ int no_detach = 0; ++ gpg_error_t err; ++ struct sockaddr_un *srvr_addr; ++ socklen_t addrlen; ++ int fd; ++ int rc; ++ const char *socketname = "/var/run/libgcrypt/S.gcryptrnd"; ++ ++ ++ if (argc) ++ { ++ argc--; argv++; ++ } ++ while (argc && **argv == '-' && (*argv)[1] == '-') ++ { ++ if (!(*argv)[2]) ++ { ++ argc--; argv++; ++ break; ++ } ++ else if (!strcmp (*argv, "--version")) ++ print_version (0); ++ else if (!strcmp (*argv, "--help")) ++ print_version (1); ++ else if (!strcmp (*argv, "--no-detach")) ++ { ++ no_detach = 1; ++ argc--; argv++; ++ } ++ else ++ print_usage (); ++ } ++ ++ if (argc == 1) ++ socketname = argv[0]; ++ else if (argc > 1) ++ print_usage (); ++ ++ if (!no_detach) ++ daemonize (); ++ ++ signal (SIGPIPE, SIG_IGN); ++ ++ logit (LOG_NOTICE, "started version " VERSION ); ++ ++ /* Libgcrypt requires us to register the threading model before we ++ do anything else with it. Note that this also calls pth_init. We ++ do the initialization while already running as a daemon to avoid ++ overhead with double initialization of Libgcrypt. */ ++ err = gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pth); ++ if (err) ++ { ++ logit (LOG_CRIT, "can't register GNU Pth with Libgcrypt: %s", ++ gpg_strerror (err)); ++ exit (1); ++ } ++ ++ /* Check that the libgcrypt version is sufficient. */ ++ if (!gcry_check_version (VERSION) ) ++ { ++ logit (LOG_CRIT, "libgcrypt is too old (need %s, have %s)", ++ VERSION, gcry_check_version (NULL) ); ++ exit (1); ++ } ++ ++ /* Register the logging callback and tell Libcgrypt to put the ++ random pool into secure memory. */ ++ gcry_set_log_handler (my_gcry_logger, NULL); ++ gcry_control (GCRYCTL_USE_SECURE_RNDPOOL); ++ ++ /* Obviously we don't want to allow any core dumps. */ ++ disable_core_dumps (); ++ ++ /* Initialize the secure memory stuff which will also drop any extra ++ privileges we have. */ ++ gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0); ++ ++ /* Register a cleanup handler. */ ++ atexit (cleanup); ++ ++ /* Create and listen on the socket. */ ++ fd = socket (AF_UNIX, SOCK_STREAM, 0); ++ if (fd == -1) ++ { ++ logit (LOG_CRIT, "can't create socket: %s", strerror (errno)); ++ exit (1); ++ } ++ srvr_addr = gcry_xmalloc (sizeof *srvr_addr); ++ memset (srvr_addr, 0, sizeof *srvr_addr); ++ srvr_addr->sun_family = AF_UNIX; ++ if (strlen (socketname) + 1 >= sizeof (srvr_addr->sun_path)) ++ { ++ logit (LOG_CRIT, "socket name `%s' too long", socketname); ++ exit (1); ++ } ++ strcpy (srvr_addr->sun_path, socketname); ++ addrlen = (offsetof (struct sockaddr_un, sun_path) ++ + strlen (srvr_addr->sun_path) + 1); ++ rc = bind (fd, (struct sockaddr*) srvr_addr, addrlen); ++ if (rc == -1 && errno == EADDRINUSE) ++ { ++ remove (socketname); ++ rc = bind (fd, (struct sockaddr*) srvr_addr, addrlen); ++ } ++ if (rc == -1) ++ { ++ logit (LOG_CRIT, "error binding socket to `%s': %s", ++ srvr_addr->sun_path, strerror (errno)); ++ close (fd); ++ exit (1); ++ } ++ ++ if (listen (fd, 5 ) == -1) ++ { ++ logit (LOG_CRIT, "listen() failed: %s", strerror (errno)); ++ close (fd); ++ exit (1); ++ } ++ ++ logit (LOG_INFO, "listening on socket `%s', fd=%d", ++ srvr_addr->sun_path, fd); ++ ++ serve (fd); ++ close (fd); ++ ++ logit (LOG_NOTICE, "stopped version " VERSION ); ++ return 0; ++} ++ ++ ++/* Send LENGTH bytes of BUFFER to file descriptor FD. Returns 0 on ++ success or another value on write error. */ ++static int ++writen (int fd, const void *buffer, size_t length) ++{ ++ while (length) ++ { ++ ssize_t n = pth_write (fd, buffer, length); ++ if (n < 0) ++ { ++ logit (LOG_ERR, "connection %d: write error: %s", ++ fd, strerror (errno)); ++ return -1; /* write error */ ++ } ++ length -= n; ++ buffer = (const char*)buffer + n; ++ } ++ return 0; /* Okay */ ++} ++ ++ ++/* Send an error response back. Returns 0 on success. */ ++static int ++send_error (int fd, int errcode) ++{ ++ unsigned char buf[2]; ++ ++ buf[0] = errcode; ++ buf[1] = 0; ++ return writen (fd, buf, 2 ); ++} ++ ++/* Send a pong response back. Returns 0 on success or another value ++ on write error. */ ++static int ++send_pong (int fd) ++{ ++ return writen (fd, "\x00\x04pong", 6); ++} ++ ++/* Send a nonce of size LENGTH back. Return 0 on success. */ ++static int ++send_nonce (int fd, int length) ++{ ++ unsigned char buf[2+255]; ++ int rc; ++ ++ assert (length >= 0 && length <= 255); ++ buf[0] = 0; ++ buf[1] = length; ++ gcry_create_nonce (buf+2, length); ++ rc = writen (fd, buf, 2+length ); ++ wipememory (buf+2, length); ++ return rc; ++} ++ ++/* Send a random of size LENGTH with quality LEVEL back. Return 0 on ++ success. */ ++static int ++send_random (int fd, int length, int level) ++{ ++ unsigned char buf[2+255]; ++ int rc; ++ ++ assert (length >= 0 && length <= 255); ++ assert (level == GCRY_STRONG_RANDOM || level == GCRY_VERY_STRONG_RANDOM); ++ buf[0] = 0; ++ buf[1] = length; ++ /* Note that we don't bother putting the random stuff into secure ++ memory because this daemon is anyway intended to be run under ++ root and it is questionable whether the kernel buffers etc. are ++ equally well protected. */ ++ gcry_randomize (buf+2, length, level); ++ rc = writen (fd, buf, 2+length ); ++ wipememory (buf+2, length); ++ return rc; ++} ++ ++/* Main processing loop for a connection. ++ ++ A request is made up of: ++ ++ 1 byte Total length of request; must be 3 ++ 1 byte Command ++ 0 = Ping ++ 10 = GetNonce ++ 11 = GetStrongRandom ++ 12 = GetVeryStrongRandom ++ (all other values are reserved) ++ 1 byte Number of requested bytes. ++ This is ignored for command Ping. ++ ++ A response is made up of: ++ ++ 1 byte Error Code ++ 0 = Everything is fine ++ 1 = Bad Command ++ 0xff = Other error. ++ (For a bad request the connection will simply be closed) ++ 1 byte Length of data ++ n byte data ++ ++ The requests are read as long as the connection is open. ++ ++ ++ */ ++static void ++connection_loop (int fd) ++{ ++ unsigned char request[3]; ++ unsigned char *p; ++ int nleft, n; ++ int rc; ++ ++ for (;;) ++ { ++ for (nleft=3, p=request; nleft > 0; ) ++ { ++ n = pth_read (fd, p, nleft); ++ if (!n && p == request) ++ return; /* Client terminated connection. */ ++ if (n <= 0) ++ { ++ logit (LOG_ERR, "connection %d: read error: %s", ++ fd, n? strerror (errno) : "Unexpected EOF"); ++ return; ++ } ++ p += n; ++ nleft -= n; ++ } ++ if (request[0] != 3) ++ { ++ logit (LOG_ERR, "connection %d: invalid length (%d) of request", ++ fd, request[0]); ++ return; ++ } ++ ++ switch (request[1]) ++ { ++ case 0: /* Ping */ ++ rc = send_pong (fd); ++ break; ++ case 10: /* GetNonce */ ++ rc = send_nonce (fd, request[2]); ++ break; ++ case 11: /* GetStrongRandom */ ++ rc = send_random (fd, request[2], GCRY_STRONG_RANDOM); ++ break; ++ case 12: /* GetVeryStrongRandom */ ++ rc = send_random (fd, request[2], GCRY_VERY_STRONG_RANDOM); ++ break; ++ ++ default: /* Invalid command */ ++ rc = send_error (fd, 1); ++ break; ++ } ++ if (rc) ++ break; /* A write error occurred while sending the response. */ ++ } ++} ++ ++ ++ ++/* Entry point for a connection's thread. */ ++static void * ++connection_thread (void *arg) ++{ ++ int fd = (int)arg; ++ ++ active_connections++; ++ logit (LOG_INFO, "connection handler for fd %d started", fd); ++ ++ connection_loop (fd); ++ ++ close (fd); ++ logit (LOG_INFO, "connection handler for fd %d terminated", fd); ++ active_connections--; ++ ++ return NULL; ++} ++ ++ ++/* This signal handler is called from the main loop between acepting ++ connections. It is called on the regular stack, thus no special ++ caution needs to be taken. It returns true to indicate that the ++ process should terminate. */ ++static int ++handle_signal (int signo) ++{ ++ switch (signo) ++ { ++ case SIGHUP: ++ logit (LOG_NOTICE, "SIGHUP received - re-reading configuration"); ++ break; ++ ++ case SIGUSR1: ++ logit (LOG_NOTICE, "SIGUSR1 received - no action defined"); ++ break; ++ ++ case SIGUSR2: ++ logit (LOG_NOTICE, "SIGUSR2 received - no action defined"); ++ break; ++ ++ case SIGTERM: ++ if (!shutdown_pending) ++ logit (LOG_NOTICE, "SIGTERM received - shutting down ..."); ++ else ++ logit (LOG_NOTICE, "SIGTERM received - still %d active connections", ++ active_connections); ++ shutdown_pending++; ++ if (shutdown_pending > 2) ++ { ++ logit (LOG_NOTICE, "shutdown forced"); ++ return 1; ++ } ++ break; ++ ++ case SIGINT: ++ logit (LOG_NOTICE, "SIGINT received - immediate shutdown"); ++ return 1; ++ ++ default: ++ logit (LOG_NOTICE, "signal %d received - no action defined\n", signo); ++ } ++ return 0; ++} ++ ++ ++ ++/* Main server loop. This is called with the FD of the listening ++ socket. */ ++static void ++serve (int listen_fd) ++{ ++ pth_attr_t tattr; ++ pth_event_t ev; ++ sigset_t sigs; ++ int signo; ++ struct sockaddr_un paddr; ++ socklen_t plen = sizeof (paddr); ++ int fd; ++ ++ tattr = pth_attr_new(); ++ pth_attr_set (tattr, PTH_ATTR_JOINABLE, 0); ++ pth_attr_set (tattr, PTH_ATTR_STACK_SIZE, 256*1024); ++ pth_attr_set (tattr, PTH_ATTR_NAME, "connection"); ++ ++ sigemptyset (&sigs); ++ sigaddset (&sigs, SIGHUP); ++ sigaddset (&sigs, SIGUSR1); ++ sigaddset (&sigs, SIGUSR2); ++ sigaddset (&sigs, SIGINT); ++ sigaddset (&sigs, SIGTERM); ++ ev = pth_event (PTH_EVENT_SIGS, &sigs, &signo); ++ ++ for (;;) ++ { ++ if (shutdown_pending) ++ { ++ if (!active_connections) ++ break; /* Ready. */ ++ ++ /* Do not accept anymore connections but wait for existing ++ connections to terminate. */ ++ signo = 0; ++ pth_wait (ev); ++ if (pth_event_occurred (ev) && signo) ++ if (handle_signal (signo)) ++ break; /* Stop the loop. */ ++ continue; ++ } ++ ++ gcry_fast_random_poll (); ++ fd = pth_accept_ev (listen_fd, (struct sockaddr *)&paddr, &plen, ev); ++ if (fd == -1) ++ { ++ if (pth_event_occurred (ev)) ++ { ++ if (handle_signal (signo)) ++ break; /* Stop the loop. */ ++ continue; ++ } ++ logit (LOG_WARNING, "accept failed: %s - waiting 1s\n", ++ strerror (errno)); ++ gcry_fast_random_poll (); ++ pth_sleep (1); ++ continue; ++ } ++ ++ if (!pth_spawn (tattr, connection_thread, (void*)fd)) ++ { ++ logit (LOG_ERR, "error spawning connection handler: %s\n", ++ strerror (errno) ); ++ close (fd); ++ } ++ } ++ ++ pth_event_free (ev, PTH_FREE_ALL); ++} +diff --git a/grub-core/lib/libgcrypt/src/getrandom.c b/grub-core/lib/libgcrypt/src/getrandom.c +new file mode 100644 +index 0000000..f9bb5c0 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/src/getrandom.c +@@ -0,0 +1,326 @@ ++/* getrandom.c - Libgcrypt Random Number client ++ * Copyright (C) 2006 Free Software Foundation, Inc. ++ * ++ * Getrandom 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 of the License, ++ * or (at your option) any later version. ++ * ++ * Getrandom 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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define PGM "getrandom" ++#define MYVERSION_LINE PGM " (Libgcrypt) " VERSION ++#define BUGREPORT_LINE "\nReport bugs to .\n" ++ ++ ++static void ++logit (const char *format, ...) ++{ ++ va_list arg_ptr; ++ ++ va_start (arg_ptr, format) ; ++ fputs (PGM ": ", stderr); ++ vfprintf (stderr, format, arg_ptr); ++ putc ('\n', stderr); ++ va_end (arg_ptr); ++} ++ ++ ++/* Send LENGTH bytes of BUFFER to file descriptor FD. Returns 0 on ++ success or another value on write error. */ ++static int ++writen (int fd, const void *buffer, size_t length) ++{ ++ while (length) ++ { ++ ssize_t n; ++ ++ do ++ n = write (fd, buffer, length); ++ while (n < 0 && errno == EINTR); ++ if (n < 0) ++ { ++ logit ("write error: %s", strerror (errno)); ++ return -1; /* write error */ ++ } ++ length -= n; ++ buffer = (const char *)buffer + n; ++ } ++ return 0; /* Okay */ ++} ++ ++ ++ ++ ++static void ++print_version (int with_help) ++{ ++ fputs (MYVERSION_LINE "\n" ++ "Copyright (C) 2006 Free Software Foundation, Inc.\n" ++ "License GPLv2+: GNU GPL version 2 or later " ++ "\n" ++ "This is free software: you are free to change and redistribute it.\n" ++ "There is NO WARRANTY, to the extent permitted by law.\n", ++ stdout); ++ ++ if (with_help) ++ fputs ("\n" ++ "Usage: " PGM " [OPTIONS] NBYTES\n" ++ "Connect to libgcrypt's random number daemon and " ++ "return random numbers" ++ "\n" ++ " --nonce Return weak random suitable for a nonce\n" ++ " --very-strong Return very strong random\n" ++ " --ping Send a ping\n" ++ " --socket NAME Name of sockket to connect to\n" ++ " --hex Return result as a hex dump\n" ++ " --verbose Show what we are doing\n" ++ " --version Print version of the program and exit\n" ++ " --help Display this help and exit\n" ++ BUGREPORT_LINE, stdout ); ++ ++ exit (0); ++} ++ ++static int ++print_usage (void) ++{ ++ fputs ("usage: " PGM " [OPTIONS] NBYTES\n", stderr); ++ fputs (" (use --help to display options)\n", stderr); ++ exit (1); ++} ++ ++ ++int ++main (int argc, char **argv) ++{ ++ struct sockaddr_un *srvr_addr; ++ socklen_t addrlen; ++ int fd; ++ int rc; ++ unsigned char buffer[300]; ++ int nleft, nread; ++ const char *socketname = "/var/run/libgcrypt/S.gcryptrnd"; ++ int do_ping = 0; ++ int get_nonce = 0; ++ int get_very_strong = 0; ++ int req_nbytes, nbytes, n; ++ int verbose = 0; ++ int fail = 0; ++ int do_hex = 0; ++ ++ if (argc) ++ { ++ argc--; argv++; ++ } ++ while (argc && **argv == '-' && (*argv)[1] == '-') ++ { ++ if (!(*argv)[2]) ++ { ++ argc--; argv++; ++ break; ++ } ++ else if (!strcmp (*argv, "--version")) ++ print_version (0); ++ else if (!strcmp (*argv, "--help")) ++ print_version (1); ++ else if (!strcmp (*argv, "--socket") && argc > 1 ) ++ { ++ argc--; argv++; ++ socketname = *argv; ++ argc--; argv++; ++ } ++ else if (!strcmp (*argv, "--nonce")) ++ { ++ argc--; argv++; ++ get_nonce = 1; ++ } ++ else if (!strcmp (*argv, "--very-strong")) ++ { ++ argc--; argv++; ++ get_very_strong = 1; ++ } ++ else if (!strcmp (*argv, "--ping")) ++ { ++ argc--; argv++; ++ do_ping = 1; ++ } ++ else if (!strcmp (*argv, "--hex")) ++ { ++ argc--; argv++; ++ do_hex = 1; ++ } ++ else if (!strcmp (*argv, "--verbose")) ++ { ++ argc--; argv++; ++ verbose = 1; ++ } ++ else ++ print_usage (); ++ } ++ ++ ++ if (!argc && do_ping) ++ ; /* This is allowed. */ ++ else if (argc != 1) ++ print_usage (); ++ req_nbytes = argc? atoi (*argv) : 0; ++ ++ if (req_nbytes < 0) ++ print_usage (); ++ ++ /* Create a socket. */ ++ fd = socket (AF_UNIX, SOCK_STREAM, 0); ++ if (fd == -1) ++ { ++ logit ("can't create socket: %s", strerror (errno)); ++ exit (1); ++ } ++ srvr_addr = malloc (sizeof *srvr_addr); ++ if (!srvr_addr) ++ { ++ logit ("malloc failed: %s", strerror (errno)); ++ exit (1); ++ } ++ memset (srvr_addr, 0, sizeof *srvr_addr); ++ srvr_addr->sun_family = AF_UNIX; ++ if (strlen (socketname) + 1 >= sizeof (srvr_addr->sun_path)) ++ { ++ logit ("socket name `%s' too long", socketname); ++ exit (1); ++ } ++ strcpy (srvr_addr->sun_path, socketname); ++ addrlen = (offsetof (struct sockaddr_un, sun_path) ++ + strlen (srvr_addr->sun_path) + 1); ++ rc = connect (fd, (struct sockaddr*) srvr_addr, addrlen); ++ if (rc == -1) ++ { ++ logit ("error connecting socket `%s': %s", ++ srvr_addr->sun_path, strerror (errno)); ++ close (fd); ++ exit (1); ++ } ++ ++ do ++ { ++ nbytes = req_nbytes > 255? 255 : req_nbytes; ++ req_nbytes -= nbytes; ++ ++ buffer[0] = 3; ++ if (do_ping) ++ buffer[1] = 0; ++ else if (get_nonce) ++ buffer[1] = 10; ++ else if (get_very_strong) ++ buffer[1] = 12; ++ else ++ buffer[1] = 11; ++ buffer[2] = nbytes; ++ if (writen (fd, buffer, 3)) ++ fail = 1; ++ else ++ { ++ for (nleft=2, nread=0; nleft > 0; ) ++ { ++ do ++ n = read (fd, buffer+nread, nleft); ++ while (n < 0 && errno == EINTR); ++ if (n < 0) ++ { ++ logit ("read error: %s", strerror (errno)); ++ exit (1); ++ } ++ nleft -= n; ++ nread += n; ++ if (nread && buffer[0]) ++ { ++ logit ("server returned error code %d", buffer[0]); ++ exit (1); ++ } ++ } ++ if (verbose) ++ logit ("received response with %d bytes of data", buffer[1]); ++ if (buffer[1] < nbytes) ++ { ++ logit ("warning: server returned less bytes than requested"); ++ fail = 1; ++ } ++ else if (buffer[1] > nbytes && !do_ping) ++ { ++ logit ("warning: server returned more bytes than requested"); ++ fail = 1; ++ } ++ nbytes = buffer[1]; ++ if (nbytes > sizeof buffer) ++ { ++ logit ("buffer too short to receive data"); ++ exit (1); ++ } ++ ++ for (nleft=nbytes, nread=0; nleft > 0; ) ++ { ++ do ++ n = read (fd, buffer+nread, nleft); ++ while (n < 0 && errno == EINTR); ++ if (n < 0) ++ { ++ logit ("read error: %s", strerror (errno)); ++ exit (1); ++ } ++ nleft -= n; ++ nread += n; ++ } ++ ++ if (do_hex) ++ { ++ for (n=0; n < nbytes; n++) ++ { ++ if (!n) ++ ; ++ else if (!(n % 16)) ++ putchar ('\n'); ++ else ++ putchar (' '); ++ printf ("%02X", buffer[n]); ++ } ++ if (nbytes) ++ putchar ('\n'); ++ } ++ else ++ { ++ if (fwrite (buffer, nbytes, 1, stdout) != 1) ++ { ++ logit ("error writing to stdout: %s", strerror (errno)); ++ fail = 1; ++ } ++ } ++ } ++ } ++ while (!fail && req_nbytes); ++ ++ close (fd); ++ free (srvr_addr); ++ return fail? 1 : 0; ++} +diff --git a/grub-core/lib/libgcrypt/src/global.c b/grub-core/lib/libgcrypt/src/global.c +new file mode 100644 +index 0000000..36d6646 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/src/global.c +@@ -0,0 +1,1112 @@ ++/* global.c - global control functions ++ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ++ * 2004, 2005, 2006, 2008, 2011 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser general Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, see . ++ */ ++ ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#ifdef HAVE_SYSLOG ++# include ++#endif /*HAVE_SYSLOG*/ ++ ++#include "g10lib.h" ++#include "cipher.h" ++#include "stdmem.h" /* our own memory allocator */ ++#include "secmem.h" /* our own secmem allocator */ ++#include "ath.h" ++ ++ ++ ++/**************** ++ * flag bits: 0 : general cipher debug ++ * 1 : general MPI debug ++ */ ++static unsigned int debug_flags; ++ ++/* gcry_control (GCRYCTL_SET_FIPS_MODE), sets this flag so that the ++ initialization code switched fips mode on. */ ++static int force_fips_mode; ++ ++/* Controlled by global_init(). */ ++static int any_init_done; ++ ++/* A table to map hardware features to a string. */ ++static struct ++{ ++ unsigned int flag; ++ const char *desc; ++} hwflist[] = ++ { ++ { HWF_PADLOCK_RNG, "padlock-rng" }, ++ { HWF_PADLOCK_AES, "padlock-aes" }, ++ { HWF_PADLOCK_SHA, "padlock-sha" }, ++ { HWF_PADLOCK_MMUL,"padlock-mmul"}, ++ { HWF_INTEL_AESNI, "intel-aesni" }, ++ { 0, NULL} ++ }; ++ ++/* A bit vector with the hardware features which shall not be used. ++ This variable must be set prior to any initialization. */ ++static unsigned int disabled_hw_features; ++ ++ ++/* Memory management. */ ++ ++static gcry_handler_alloc_t alloc_func; ++static gcry_handler_alloc_t alloc_secure_func; ++static gcry_handler_secure_check_t is_secure_func; ++static gcry_handler_realloc_t realloc_func; ++static gcry_handler_free_t free_func; ++static gcry_handler_no_mem_t outofcore_handler; ++static void *outofcore_handler_value; ++static int no_secure_memory; ++ ++ ++ ++ ++ ++/* This is our handmade constructor. It gets called by any function ++ likely to be called at startup. The suggested way for an ++ application to make sure that this has been called is by using ++ gcry_check_version. */ ++static void ++global_init (void) ++{ ++ gcry_error_t err = 0; ++ ++ if (any_init_done) ++ return; ++ any_init_done = 1; ++ ++ /* Initialize our portable thread/mutex wrapper. */ ++ err = ath_init (); ++ if (err) ++ { ++ err = gpg_error_from_errno (err); ++ goto fail; ++ } ++ ++ /* See whether the system is in FIPS mode. This needs to come as ++ early as possible but after ATH has been initialized. */ ++ _gcry_initialize_fips_mode (force_fips_mode); ++ ++ /* Before we do any other initialization we need to test available ++ hardware features. */ ++ _gcry_detect_hw_features (disabled_hw_features); ++ ++ /* Initialize the modules - this is mainly allocating some memory and ++ creating mutexes. */ ++ err = _gcry_cipher_init (); ++ if (err) ++ goto fail; ++ err = _gcry_md_init (); ++ if (err) ++ goto fail; ++ err = _gcry_pk_init (); ++ if (err) ++ goto fail; ++ err = _gcry_primegen_init (); ++ if (err) ++ goto fail; ++ ++ return; ++ ++ fail: ++ BUG (); ++} ++ ++ ++/* This function is called by the macro fips_is_operational and makes ++ sure that the minimal initialization has been done. This is far ++ from a perfect solution and hides problems with an improper ++ initialization but at least in single-threaded mode it should work ++ reliable. ++ ++ The reason we need this is that a lot of applications don't use ++ Libgcrypt properly by not running any initialization code at all. ++ They just call a Libgcrypt function and that is all what they want. ++ Now with the FIPS mode, that has the side effect of entering FIPS ++ mode (for security reasons, FIPS mode is the default if no ++ initialization has been done) and bailing out immediately because ++ the FSM is in the wrong state. If we always run the init code, ++ Libgcrypt can test for FIPS mode and at least if not in FIPS mode, ++ it will behave as before. Note that this on-the-fly initialization ++ is only done for the cryptographic functions subject to FIPS mode ++ and thus not all API calls will do such an initialization. */ ++int ++_gcry_global_is_operational (void) ++{ ++ if (!any_init_done) ++ { ++#ifdef HAVE_SYSLOG ++ syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: " ++ "missing initialization - please fix the application"); ++#endif /*HAVE_SYSLOG*/ ++ global_init (); ++ } ++ return _gcry_fips_is_operational (); ++} ++ ++ ++ ++ ++/* Version number parsing. */ ++ ++/* This function parses the first portion of the version number S and ++ stores it in *NUMBER. On success, this function returns a pointer ++ into S starting with the first character, which is not part of the ++ initial number portion; on failure, NULL is returned. */ ++static const char* ++parse_version_number( const char *s, int *number ) ++{ ++ int val = 0; ++ ++ if( *s == '0' && isdigit(s[1]) ) ++ return NULL; /* leading zeros are not allowed */ ++ for ( ; isdigit(*s); s++ ) { ++ val *= 10; ++ val += *s - '0'; ++ } ++ *number = val; ++ return val < 0? NULL : s; ++} ++ ++/* This function breaks up the complete string-representation of the ++ version number S, which is of the following struture: ... The major, ++ minor and micro number components will be stored in *MAJOR, *MINOR ++ and *MICRO. ++ ++ On success, the last component, the patch level, will be returned; ++ in failure, NULL will be returned. */ ++ ++static const char * ++parse_version_string( const char *s, int *major, int *minor, int *micro ) ++{ ++ s = parse_version_number( s, major ); ++ if( !s || *s != '.' ) ++ return NULL; ++ s++; ++ s = parse_version_number( s, minor ); ++ if( !s || *s != '.' ) ++ return NULL; ++ s++; ++ s = parse_version_number( s, micro ); ++ if( !s ) ++ return NULL; ++ return s; /* patchlevel */ ++} ++ ++/* If REQ_VERSION is non-NULL, check that the version of the library ++ is at minimum the requested one. Returns the string representation ++ of the library version if the condition is satisfied; return NULL ++ if the requested version is newer than that of the library. ++ ++ If a NULL is passed to this function, no check is done, but the ++ string representation of the library is simply returned. */ ++const char * ++gcry_check_version( const char *req_version ) ++{ ++ const char *ver = VERSION; ++ int my_major, my_minor, my_micro; ++ int rq_major, rq_minor, rq_micro; ++ const char *my_plvl; ++ ++ /* Initialize library. */ ++ global_init (); ++ ++ if ( !req_version ) ++ /* Caller wants our version number. */ ++ return ver; ++ ++ /* Parse own version number. */ ++ my_plvl = parse_version_string( ver, &my_major, &my_minor, &my_micro ); ++ if ( !my_plvl ) ++ /* very strange our own version is bogus. Shouldn't we use ++ assert() here and bail out in case this happens? -mo. */ ++ return NULL; ++ ++ /* Parse requested version number. */ ++ if (!parse_version_string (req_version, &rq_major, &rq_minor, &rq_micro)) ++ return NULL; /* req version string is invalid, this can happen. */ ++ ++ /* Compare version numbers. */ ++ if ( my_major > rq_major ++ || (my_major == rq_major && my_minor > rq_minor) ++ || (my_major == rq_major && my_minor == rq_minor && my_micro > rq_micro) ++ || (my_major == rq_major && my_minor == rq_minor ++ && my_micro == rq_micro)) ++ { ++ return ver; ++ } ++ ++ return NULL; ++} ++ ++ ++static void ++print_config ( int (*fnc)(FILE *fp, const char *format, ...), FILE *fp) ++{ ++ unsigned int hwf; ++ int i; ++ ++ fnc (fp, "version:%s:\n", VERSION); ++ fnc (fp, "ciphers:%s:\n", LIBGCRYPT_CIPHERS); ++ fnc (fp, "pubkeys:%s:\n", LIBGCRYPT_PUBKEY_CIPHERS); ++ fnc (fp, "digests:%s:\n", LIBGCRYPT_DIGESTS); ++ fnc (fp, "rnd-mod:" ++#if USE_RNDEGD ++ "egd:" ++#endif ++#if USE_RNDLINUX ++ "linux:" ++#endif ++#if USE_RNDUNIX ++ "unix:" ++#endif ++#if USE_RNDW32 ++ "w32:" ++#endif ++ "\n"); ++ fnc (fp, "mpi-asm:%s:\n", _gcry_mpi_get_hw_config ()); ++ fnc (fp, "threads:%s:\n", ath_get_model (NULL)); ++ hwf = _gcry_get_hw_features (); ++ fnc (fp, "hwflist:"); ++ for (i=0; hwflist[i].desc; i++) ++ if ( (hwf & hwflist[i].flag) ) ++ fnc (fp, "%s:", hwflist[i].desc); ++ fnc (fp, "\n"); ++ /* We use y/n instead of 1/0 for the simple reason that Emacsen's ++ compile error parser would accidently flag that line when printed ++ during "make check" as an error. */ ++ fnc (fp, "fips-mode:%c:%c:\n", ++ fips_mode ()? 'y':'n', ++ _gcry_enforced_fips_mode ()? 'y':'n' ); ++} ++ ++ ++ ++ ++/* Command dispatcher function, acting as general control ++ function. */ ++gcry_error_t ++_gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr) ++{ ++ static int init_finished = 0; ++ gcry_err_code_t err = 0; ++ ++ switch (cmd) ++ { ++ case GCRYCTL_ENABLE_M_GUARD: ++ _gcry_private_enable_m_guard (); ++ break; ++ ++ case GCRYCTL_ENABLE_QUICK_RANDOM: ++ _gcry_enable_quick_random_gen (); ++ break; ++ ++ case GCRYCTL_FAKED_RANDOM_P: ++ /* Return an error if the RNG is faked one (e.g. enabled by ++ ENABLE_QUICK_RANDOM. */ ++ if (_gcry_random_is_faked ()) ++ err = GPG_ERR_GENERAL; /* Use as TRUE value. */ ++ break; ++ ++ case GCRYCTL_DUMP_RANDOM_STATS: ++ _gcry_random_dump_stats (); ++ break; ++ ++ case GCRYCTL_DUMP_MEMORY_STATS: ++ /*m_print_stats("[fixme: prefix]");*/ ++ break; ++ ++ case GCRYCTL_DUMP_SECMEM_STATS: ++ _gcry_secmem_dump_stats (); ++ break; ++ ++ case GCRYCTL_DROP_PRIVS: ++ global_init (); ++ _gcry_secmem_init (0); ++ break; ++ ++ case GCRYCTL_DISABLE_SECMEM: ++ global_init (); ++ no_secure_memory = 1; ++ break; ++ ++ case GCRYCTL_INIT_SECMEM: ++ global_init (); ++ _gcry_secmem_init (va_arg (arg_ptr, unsigned int)); ++ if ((_gcry_secmem_get_flags () & GCRY_SECMEM_FLAG_NOT_LOCKED)) ++ err = GPG_ERR_GENERAL; ++ break; ++ ++ case GCRYCTL_TERM_SECMEM: ++ global_init (); ++ _gcry_secmem_term (); ++ break; ++ ++ case GCRYCTL_DISABLE_SECMEM_WARN: ++ _gcry_secmem_set_flags ((_gcry_secmem_get_flags () ++ | GCRY_SECMEM_FLAG_NO_WARNING)); ++ break; ++ ++ case GCRYCTL_SUSPEND_SECMEM_WARN: ++ _gcry_secmem_set_flags ((_gcry_secmem_get_flags () ++ | GCRY_SECMEM_FLAG_SUSPEND_WARNING)); ++ break; ++ ++ case GCRYCTL_RESUME_SECMEM_WARN: ++ _gcry_secmem_set_flags ((_gcry_secmem_get_flags () ++ & ~GCRY_SECMEM_FLAG_SUSPEND_WARNING)); ++ break; ++ ++ case GCRYCTL_USE_SECURE_RNDPOOL: ++ global_init (); ++ _gcry_secure_random_alloc (); /* Put random number into secure memory. */ ++ break; ++ ++ case GCRYCTL_SET_RANDOM_SEED_FILE: ++ _gcry_set_random_seed_file (va_arg (arg_ptr, const char *)); ++ break; ++ ++ case GCRYCTL_UPDATE_RANDOM_SEED_FILE: ++ if ( fips_is_operational () ) ++ _gcry_update_random_seed_file (); ++ break; ++ ++ case GCRYCTL_SET_VERBOSITY: ++ _gcry_set_log_verbosity (va_arg (arg_ptr, int)); ++ break; ++ ++ case GCRYCTL_SET_DEBUG_FLAGS: ++ debug_flags |= va_arg (arg_ptr, unsigned int); ++ break; ++ ++ case GCRYCTL_CLEAR_DEBUG_FLAGS: ++ debug_flags &= ~va_arg (arg_ptr, unsigned int); ++ break; ++ ++ case GCRYCTL_DISABLE_INTERNAL_LOCKING: ++ /* Not used anymore. */ ++ global_init (); ++ break; ++ ++ case GCRYCTL_ANY_INITIALIZATION_P: ++ if (any_init_done) ++ err = GPG_ERR_GENERAL; ++ break; ++ ++ case GCRYCTL_INITIALIZATION_FINISHED_P: ++ if (init_finished) ++ err = GPG_ERR_GENERAL; /* Yes. */ ++ break; ++ ++ case GCRYCTL_INITIALIZATION_FINISHED: ++ /* This is a hook which should be used by an application after ++ all initialization has been done and right before any threads ++ are started. It is not really needed but the only way to be ++ really sure that all initialization for thread-safety has ++ been done. */ ++ if (! init_finished) ++ { ++ global_init (); ++ /* Do only a basic random initialization, i.e. init the ++ mutexes. */ ++ _gcry_random_initialize (0); ++ init_finished = 1; ++ /* Force us into operational state if in FIPS mode. */ ++ (void)fips_is_operational (); ++ } ++ break; ++ ++ case GCRYCTL_SET_THREAD_CBS: ++ err = ath_install (va_arg (arg_ptr, void *)); ++ if (!err) ++ global_init (); ++ break; ++ ++ case GCRYCTL_FAST_POLL: ++ /* We need to do make sure that the random pool is really ++ initialized so that the poll function is not a NOP. */ ++ _gcry_random_initialize (1); ++ ++ if ( fips_is_operational () ) ++ _gcry_fast_random_poll (); ++ break; ++ ++ case GCRYCTL_SET_RNDEGD_SOCKET: ++#if USE_RNDEGD ++ err = _gcry_rndegd_set_socket_name (va_arg (arg_ptr, const char *)); ++#else ++ err = gpg_error (GPG_ERR_NOT_SUPPORTED); ++#endif ++ break; ++ ++ case GCRYCTL_SET_RANDOM_DAEMON_SOCKET: ++ _gcry_set_random_daemon_socket (va_arg (arg_ptr, const char *)); ++ break; ++ ++ case GCRYCTL_USE_RANDOM_DAEMON: ++ /* We need to do make sure that the random pool is really ++ initialized so that the poll function is not a NOP. */ ++ _gcry_random_initialize (1); ++ _gcry_use_random_daemon (!! va_arg (arg_ptr, int)); ++ break; ++ ++ /* This command dumps information pertaining to the ++ configuration of libgcrypt to the given stream. It may be ++ used before the initialization has been finished but not ++ before a gcry_version_check. */ ++ case GCRYCTL_PRINT_CONFIG: ++ { ++ FILE *fp = va_arg (arg_ptr, FILE *); ++ print_config (fp?fprintf:_gcry_log_info_with_dummy_fp, fp); ++ } ++ break; ++ ++ case GCRYCTL_OPERATIONAL_P: ++ /* Returns true if the library is in an operational state. This ++ is always true for non-fips mode. */ ++ if (_gcry_fips_test_operational ()) ++ err = GPG_ERR_GENERAL; /* Used as TRUE value */ ++ break; ++ ++ case GCRYCTL_FIPS_MODE_P: ++ if (fips_mode () ++ && !_gcry_is_fips_mode_inactive () ++ && !no_secure_memory) ++ err = GPG_ERR_GENERAL; /* Used as TRUE value */ ++ break; ++ ++ case GCRYCTL_FORCE_FIPS_MODE: ++ /* Performing this command puts the library into fips mode. If ++ the library has already been initialized into fips mode, a ++ selftest is triggered. It is not possible to put the libraty ++ into fips mode after having passed the initialization. */ ++ if (!any_init_done) ++ { ++ /* Not yet intialized at all. Set a flag so that we are put ++ into fips mode during initialization. */ ++ force_fips_mode = 1; ++ } ++ else ++ { ++ /* Already initialized. If we are already operational we ++ run a selftest. If not we use the is_operational call to ++ force us into operational state if possible. */ ++ if (_gcry_fips_test_error_or_operational ()) ++ _gcry_fips_run_selftests (1); ++ if (_gcry_fips_is_operational ()) ++ err = GPG_ERR_GENERAL; /* Used as TRUE value */ ++ } ++ break; ++ ++ case GCRYCTL_SELFTEST: ++ /* Run a selftest. This works in fips mode as well as in ++ standard mode. In contrast to the power-up tests, we use an ++ extended version of the selftests. Returns 0 on success or an ++ error code. */ ++ global_init (); ++ err = _gcry_fips_run_selftests (1); ++ break; ++ ++#if _GCRY_GCC_VERSION >= 40600 ++# pragma GCC diagnostic push ++# pragma GCC diagnostic ignored "-Wswitch" ++#endif ++ case 58: /* Init external random test. */ ++ { ++ void **rctx = va_arg (arg_ptr, void **); ++ unsigned int flags = va_arg (arg_ptr, unsigned int); ++ const void *key = va_arg (arg_ptr, const void *); ++ size_t keylen = va_arg (arg_ptr, size_t); ++ const void *seed = va_arg (arg_ptr, const void *); ++ size_t seedlen = va_arg (arg_ptr, size_t); ++ const void *dt = va_arg (arg_ptr, const void *); ++ size_t dtlen = va_arg (arg_ptr, size_t); ++ if (!fips_is_operational ()) ++ err = fips_not_operational (); ++ else ++ err = _gcry_random_init_external_test (rctx, flags, key, keylen, ++ seed, seedlen, dt, dtlen); ++ } ++ break; ++ case 59: /* Run external random test. */ ++ { ++ void *ctx = va_arg (arg_ptr, void *); ++ void *buffer = va_arg (arg_ptr, void *); ++ size_t buflen = va_arg (arg_ptr, size_t); ++ if (!fips_is_operational ()) ++ err = fips_not_operational (); ++ else ++ err = _gcry_random_run_external_test (ctx, buffer, buflen); ++ } ++ break; ++ case 60: /* Deinit external random test. */ ++ { ++ void *ctx = va_arg (arg_ptr, void *); ++ _gcry_random_deinit_external_test (ctx); ++ } ++ break; ++ case 61: /* RFU */ ++ break; ++ case 62: /* RFU */ ++ break; ++#if _GCRY_GCC_VERSION >= 40600 ++# pragma GCC diagnostic pop ++#endif ++ ++ case GCRYCTL_DISABLE_HWF: ++ { ++ const char *name = va_arg (arg_ptr, const char *); ++ int i; ++ ++ for (i=0; hwflist[i].desc; i++) ++ if (!strcmp (hwflist[i].desc, name)) ++ { ++ disabled_hw_features |= hwflist[i].flag; ++ break; ++ } ++ if (!hwflist[i].desc) ++ err = GPG_ERR_INV_NAME; ++ } ++ break; ++ ++ default: ++ /* A call to make sure that the dummy code is linked in. */ ++ _gcry_compat_identification (); ++ err = GPG_ERR_INV_OP; ++ } ++ ++ return gcry_error (err); ++} ++ ++ ++/* Command dispatcher function, acting as general control ++ function. */ ++gcry_error_t ++gcry_control (enum gcry_ctl_cmds cmd, ...) ++{ ++ gcry_error_t err; ++ va_list arg_ptr; ++ ++ va_start (arg_ptr, cmd); ++ err = _gcry_vcontrol (cmd, arg_ptr); ++ va_end(arg_ptr); ++ return err; ++} ++ ++ ++ ++/* Return a pointer to a string containing a description of the error ++ code in the error value ERR. */ ++const char * ++gcry_strerror (gcry_error_t err) ++{ ++ return gpg_strerror (err); ++} ++ ++/* Return a pointer to a string containing a description of the error ++ source in the error value ERR. */ ++const char * ++gcry_strsource (gcry_error_t err) ++{ ++ return gpg_strsource (err); ++} ++ ++/* Retrieve the error code for the system error ERR. This returns ++ GPG_ERR_UNKNOWN_ERRNO if the system error is not mapped (report ++ this). */ ++gcry_err_code_t ++gcry_err_code_from_errno (int err) ++{ ++ return gpg_err_code_from_errno (err); ++} ++ ++ ++/* Retrieve the system error for the error code CODE. This returns 0 ++ if CODE is not a system error code. */ ++int ++gcry_err_code_to_errno (gcry_err_code_t code) ++{ ++ return gpg_err_code_from_errno (code); ++} ++ ++ ++/* Return an error value with the error source SOURCE and the system ++ error ERR. */ ++gcry_error_t ++gcry_err_make_from_errno (gpg_err_source_t source, int err) ++{ ++ return gpg_err_make_from_errno (source, err); ++} ++ ++ ++/* Return an error value with the system error ERR. */ ++gcry_err_code_t ++gcry_error_from_errno (int err) ++{ ++ return gcry_error (gpg_err_code_from_errno (err)); ++} ++ ++ ++/* Set custom allocation handlers. This is in general not useful ++ * because the libgcrypt allocation functions are guaranteed to ++ * provide proper allocation handlers which zeroize memory if needed. ++ * NOTE: All 5 functions should be set. */ ++void ++gcry_set_allocation_handler (gcry_handler_alloc_t new_alloc_func, ++ gcry_handler_alloc_t new_alloc_secure_func, ++ gcry_handler_secure_check_t new_is_secure_func, ++ gcry_handler_realloc_t new_realloc_func, ++ gcry_handler_free_t new_free_func) ++{ ++ global_init (); ++ ++ if (fips_mode ()) ++ { ++ /* We do not want to enforce the fips mode, but merely set a ++ flag so that the application may check whether it is still in ++ fips mode. */ ++ _gcry_inactivate_fips_mode ("custom allocation handler"); ++ } ++ ++ alloc_func = new_alloc_func; ++ alloc_secure_func = new_alloc_secure_func; ++ is_secure_func = new_is_secure_func; ++ realloc_func = new_realloc_func; ++ free_func = new_free_func; ++} ++ ++ ++ ++/**************** ++ * Set an optional handler which is called in case the xmalloc functions ++ * ran out of memory. This handler may do one of these things: ++ * o free some memory and return true, so that the xmalloc function ++ * tries again. ++ * o Do whatever it like and return false, so that the xmalloc functions ++ * use the default fatal error handler. ++ * o Terminate the program and don't return. ++ * ++ * The handler function is called with 3 arguments: The opaque value set with ++ * this function, the requested memory size, and a flag with these bits ++ * currently defined: ++ * bit 0 set = secure memory has been requested. ++ */ ++void ++gcry_set_outofcore_handler( int (*f)( void*, size_t, unsigned int ), ++ void *value ) ++{ ++ global_init (); ++ ++ if (fips_mode () ) ++ { ++ log_info ("out of core handler ignored in FIPS mode\n"); ++ return; ++ } ++ ++ outofcore_handler = f; ++ outofcore_handler_value = value; ++} ++ ++/* Return the no_secure_memory flag. */ ++static int ++get_no_secure_memory (void) ++{ ++ if (!no_secure_memory) ++ return 0; ++ if (_gcry_enforced_fips_mode ()) ++ { ++ no_secure_memory = 0; ++ return 0; ++ } ++ return no_secure_memory; ++} ++ ++ ++static gcry_err_code_t ++do_malloc (size_t n, unsigned int flags, void **mem) ++{ ++ gcry_err_code_t err = 0; ++ void *m; ++ ++ if ((flags & GCRY_ALLOC_FLAG_SECURE) && !get_no_secure_memory ()) ++ { ++ if (alloc_secure_func) ++ m = (*alloc_secure_func) (n); ++ else ++ m = _gcry_private_malloc_secure (n); ++ } ++ else ++ { ++ if (alloc_func) ++ m = (*alloc_func) (n); ++ else ++ m = _gcry_private_malloc (n); ++ } ++ ++ if (!m) ++ { ++ /* Make sure that ERRNO has been set in case a user supplied ++ memory handler didn't it correctly. */ ++ if (!errno) ++ gpg_err_set_errno (ENOMEM); ++ err = gpg_err_code_from_errno (errno); ++ } ++ else ++ *mem = m; ++ ++ return err; ++} ++ ++void * ++gcry_malloc (size_t n) ++{ ++ void *mem = NULL; ++ ++ do_malloc (n, 0, &mem); ++ ++ return mem; ++} ++ ++void * ++gcry_malloc_secure (size_t n) ++{ ++ void *mem = NULL; ++ ++ do_malloc (n, GCRY_ALLOC_FLAG_SECURE, &mem); ++ ++ return mem; ++} ++ ++int ++gcry_is_secure (const void *a) ++{ ++ if (get_no_secure_memory ()) ++ return 0; ++ if (is_secure_func) ++ return is_secure_func (a) ; ++ return _gcry_private_is_secure (a); ++} ++ ++void ++_gcry_check_heap( const void *a ) ++{ ++ (void)a; ++ ++ /* FIXME: implement this*/ ++#if 0 ++ if( some_handler ) ++ some_handler(a) ++ else ++ _gcry_private_check_heap(a) ++#endif ++} ++ ++void * ++gcry_realloc (void *a, size_t n) ++{ ++ void *p; ++ ++ /* To avoid problems with non-standard realloc implementations and ++ our own secmem_realloc, we divert to malloc and free here. */ ++ if (!a) ++ return gcry_malloc (n); ++ if (!n) ++ { ++ gcry_free (a); ++ return NULL; ++ } ++ ++ if (realloc_func) ++ p = realloc_func (a, n); ++ else ++ p = _gcry_private_realloc (a, n); ++ if (!p && !errno) ++ gpg_err_set_errno (ENOMEM); ++ return p; ++} ++ ++void ++gcry_free (void *p) ++{ ++ int save_errno; ++ ++ if (!p) ++ return; ++ ++ /* In case ERRNO is set we better save it so that the free machinery ++ may not accidently change ERRNO. We restore it only if it was ++ already set to comply with the usual C semantic for ERRNO. */ ++ save_errno = errno; ++ if (free_func) ++ free_func (p); ++ else ++ _gcry_private_free (p); ++ ++ if (save_errno) ++ gpg_err_set_errno (save_errno); ++} ++ ++void * ++gcry_calloc (size_t n, size_t m) ++{ ++ size_t bytes; ++ void *p; ++ ++ bytes = n * m; /* size_t is unsigned so the behavior on overflow is ++ defined. */ ++ if (m && bytes / m != n) ++ { ++ gpg_err_set_errno (ENOMEM); ++ return NULL; ++ } ++ ++ p = gcry_malloc (bytes); ++ if (p) ++ memset (p, 0, bytes); ++ return p; ++} ++ ++void * ++gcry_calloc_secure (size_t n, size_t m) ++{ ++ size_t bytes; ++ void *p; ++ ++ bytes = n * m; /* size_t is unsigned so the behavior on overflow is ++ defined. */ ++ if (m && bytes / m != n) ++ { ++ gpg_err_set_errno (ENOMEM); ++ return NULL; ++ } ++ ++ p = gcry_malloc_secure (bytes); ++ if (p) ++ memset (p, 0, bytes); ++ return p; ++} ++ ++ ++/* Create and return a copy of the null-terminated string STRING. If ++ it is contained in secure memory, the copy will be contained in ++ secure memory as well. In an out-of-memory condition, NULL is ++ returned. */ ++char * ++gcry_strdup (const char *string) ++{ ++ char *string_cp = NULL; ++ size_t string_n = 0; ++ ++ string_n = strlen (string); ++ ++ if (gcry_is_secure (string)) ++ string_cp = gcry_malloc_secure (string_n + 1); ++ else ++ string_cp = gcry_malloc (string_n + 1); ++ ++ if (string_cp) ++ strcpy (string_cp, string); ++ ++ return string_cp; ++} ++ ++ ++void * ++gcry_xmalloc( size_t n ) ++{ ++ void *p; ++ ++ while ( !(p = gcry_malloc( n )) ) ++ { ++ if ( fips_mode () ++ || !outofcore_handler ++ || !outofcore_handler (outofcore_handler_value, n, 0) ) ++ { ++ _gcry_fatal_error (gpg_err_code_from_errno (errno), NULL); ++ } ++ } ++ return p; ++} ++ ++void * ++gcry_xrealloc( void *a, size_t n ) ++{ ++ void *p; ++ ++ while ( !(p = gcry_realloc( a, n )) ) ++ { ++ if ( fips_mode () ++ || !outofcore_handler ++ || !outofcore_handler (outofcore_handler_value, n, ++ gcry_is_secure(a)? 3:2 ) ) ++ { ++ _gcry_fatal_error (gpg_err_code_from_errno (errno), NULL ); ++ } ++ } ++ return p; ++} ++ ++void * ++gcry_xmalloc_secure( size_t n ) ++{ ++ void *p; ++ ++ while ( !(p = gcry_malloc_secure( n )) ) ++ { ++ if ( fips_mode () ++ || !outofcore_handler ++ || !outofcore_handler (outofcore_handler_value, n, 1) ) ++ { ++ _gcry_fatal_error (gpg_err_code_from_errno (errno), ++ _("out of core in secure memory")); ++ } ++ } ++ return p; ++} ++ ++ ++void * ++gcry_xcalloc( size_t n, size_t m ) ++{ ++ size_t nbytes; ++ void *p; ++ ++ nbytes = n * m; ++ if (m && nbytes / m != n) ++ { ++ gpg_err_set_errno (ENOMEM); ++ _gcry_fatal_error(gpg_err_code_from_errno (errno), NULL ); ++ } ++ ++ p = gcry_xmalloc ( nbytes ); ++ memset ( p, 0, nbytes ); ++ return p; ++} ++ ++void * ++gcry_xcalloc_secure( size_t n, size_t m ) ++{ ++ size_t nbytes; ++ void *p; ++ ++ nbytes = n * m; ++ if (m && nbytes / m != n) ++ { ++ gpg_err_set_errno (ENOMEM); ++ _gcry_fatal_error(gpg_err_code_from_errno (errno), NULL ); ++ } ++ ++ p = gcry_xmalloc_secure ( nbytes ); ++ memset ( p, 0, nbytes ); ++ return p; ++} ++ ++char * ++gcry_xstrdup (const char *string) ++{ ++ char *p; ++ ++ while ( !(p = gcry_strdup (string)) ) ++ { ++ size_t n = strlen (string); ++ int is_sec = !!gcry_is_secure (string); ++ ++ if (fips_mode () ++ || !outofcore_handler ++ || !outofcore_handler (outofcore_handler_value, n, is_sec) ) ++ { ++ _gcry_fatal_error (gpg_err_code_from_errno (errno), ++ is_sec? _("out of core in secure memory"):NULL); ++ } ++ } ++ ++ return p; ++} ++ ++ ++int ++_gcry_get_debug_flag (unsigned int mask) ++{ ++ if ( fips_mode () ) ++ return 0; ++ return (debug_flags & mask); ++} ++ ++ ++ ++/* It is often useful to get some feedback of long running operations. ++ This function may be used to register a handler for this. ++ The callback function CB is used as: ++ ++ void cb (void *opaque, const char *what, int printchar, ++ int current, int total); ++ ++ Where WHAT is a string identifying the the type of the progress ++ output, PRINTCHAR the character usually printed, CURRENT the amount ++ of progress currently done and TOTAL the expected amount of ++ progress. A value of 0 for TOTAL indicates that there is no ++ estimation available. ++ ++ Defined values for WHAT: ++ ++ "need_entropy" X 0 number-of-bytes-required ++ When running low on entropy ++ "primegen" '\n' 0 0 ++ Prime generated ++ '!' ++ Need to refresh the prime pool ++ '<','>' ++ Number of bits adjusted ++ '^' ++ Looking for a generator ++ '.' ++ Fermat tests on 10 candidates failed ++ ':' ++ Restart with a new random value ++ '+' ++ Rabin Miller test passed ++ "pk_elg" '+','-','.','\n' 0 0 ++ Only used in debugging mode. ++ "pk_dsa" ++ Only used in debugging mode. ++*/ ++void ++gcry_set_progress_handler (void (*cb)(void *,const char*,int, int, int), ++ void *cb_data) ++{ ++#if USE_DSA ++ _gcry_register_pk_dsa_progress (cb, cb_data); ++#endif ++#if USE_ELGAMAL ++ _gcry_register_pk_elg_progress (cb, cb_data); ++#endif ++ _gcry_register_primegen_progress (cb, cb_data); ++ _gcry_register_random_progress (cb, cb_data); ++} +diff --git a/grub-core/lib/libgcrypt/src/hmac256.c b/grub-core/lib/libgcrypt/src/hmac256.c +new file mode 100644 +index 0000000..34def76 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/src/hmac256.c +@@ -0,0 +1,795 @@ ++/* hmac256.c - Standalone HMAC implementation ++ * Copyright (C) 2003, 2006, 2008 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, see . ++ */ ++ ++/* ++ This is a standalone HMAC-SHA-256 implementation based on the code ++ from ../cipher/sha256.c. It is a second implementation to allow ++ comparing against the standard implementations and to be used for ++ internal consistency checks. It should not be used for sensitive ++ data because no mechanisms to clear the stack etc are used. ++ ++ This module may be used standalone and requires only a few ++ standard definitions to be provided in a config.h file. ++ ++ Types: ++ ++ u32 - unsigned 32 bit type. ++ ++ Constants: ++ ++ WORDS_BIGENDIAN Defined to 1 on big endian systems. ++ inline If defined, it should yield the keyword used ++ to inline a function. ++ HAVE_U32_TYPEDEF Defined if the u32 type is available. ++ SIZEOF_UNSIGNED_INT Defined to the size in bytes of an unsigned int. ++ SIZEOF_UNSIGNED_LONG Defined to the size in bytes of an unsigned long. ++ ++ STANDALONE Compile a test driver similar to the ++ sha1sum tool. This driver uses a self-test ++ identically to the one used by Libcgrypt ++ for testing this included module. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#if defined(__WIN32) && defined(STANDALONE) ++# include /* We need setmode(). */ ++#endif ++ ++/* For a native WindowsCE binary we need to include gpg-error.h to ++ provide a replacement for strerror. In other cases we need a ++ replacement macro for gpg_err_set_errno. */ ++#ifdef __MINGW32CE__ ++# include ++#else ++# define gpg_err_set_errno(a) (errno = (a)) ++#endif ++ ++#include "hmac256.h" ++ ++ ++ ++#ifndef HAVE_U32_TYPEDEF ++# undef u32 /* Undef a possible macro with that name. */ ++# if SIZEOF_UNSIGNED_INT == 4 ++ typedef unsigned int u32; ++# elif SIZEOF_UNSIGNED_LONG == 4 ++ typedef unsigned long u32; ++# else ++# error no typedef for u32 ++# endif ++# define HAVE_U32_TYPEDEF ++#endif ++ ++ ++ ++ ++/* The context used by this module. */ ++struct hmac256_context ++{ ++ u32 h0, h1, h2, h3, h4, h5, h6, h7; ++ u32 nblocks; ++ int count; ++ int finalized:1; ++ int use_hmac:1; ++ unsigned char buf[64]; ++ unsigned char opad[64]; ++}; ++ ++ ++/* Rotate a 32 bit word. */ ++#if defined(__GNUC__) && defined(__i386__) ++static inline u32 ++ror(u32 x, int n) ++{ ++ __asm__("rorl %%cl,%0" ++ :"=r" (x) ++ :"0" (x),"c" (n)); ++ return x; ++} ++#else ++#define ror(x,n) ( ((x) >> (n)) | ((x) << (32-(n))) ) ++#endif ++ ++#define my_wipememory2(_ptr,_set,_len) do { \ ++ volatile char *_vptr=(volatile char *)(_ptr); \ ++ size_t _vlen=(_len); \ ++ while(_vlen) { *_vptr=(_set); _vptr++; _vlen--; } \ ++ } while(0) ++#define my_wipememory(_ptr,_len) my_wipememory2(_ptr,0,_len) ++ ++ ++ ++ ++/* ++ The SHA-256 core: Transform the message X which consists of 16 ++ 32-bit-words. See FIPS 180-2 for details. ++ */ ++static void ++transform (hmac256_context_t hd, const void *data_arg) ++{ ++ const unsigned char *data = data_arg; ++ ++#define Cho(x,y,z) (z ^ (x & (y ^ z))) /* (4.2) same as SHA-1's F1 */ ++#define Maj(x,y,z) ((x & y) | (z & (x|y))) /* (4.3) same as SHA-1's F3 */ ++#define Sum0(x) (ror ((x), 2) ^ ror ((x), 13) ^ ror ((x), 22)) /* (4.4) */ ++#define Sum1(x) (ror ((x), 6) ^ ror ((x), 11) ^ ror ((x), 25)) /* (4.5) */ ++#define S0(x) (ror ((x), 7) ^ ror ((x), 18) ^ ((x) >> 3)) /* (4.6) */ ++#define S1(x) (ror ((x), 17) ^ ror ((x), 19) ^ ((x) >> 10)) /* (4.7) */ ++#define R(a,b,c,d,e,f,g,h,k,w) do \ ++ { \ ++ t1 = (h) + Sum1((e)) + Cho((e),(f),(g)) + (k) + (w); \ ++ t2 = Sum0((a)) + Maj((a),(b),(c)); \ ++ h = g; \ ++ g = f; \ ++ f = e; \ ++ e = d + t1; \ ++ d = c; \ ++ c = b; \ ++ b = a; \ ++ a = t1 + t2; \ ++ } while (0) ++ ++ static const u32 K[64] = ++ { ++ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, ++ 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, ++ 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, ++ 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, ++ 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, ++ 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, ++ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, ++ 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, ++ 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, ++ 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, ++ 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, ++ 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, ++ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, ++ 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, ++ 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, ++ 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 ++ }; ++ ++ u32 a, b, c, d, e, f, g, h, t1, t2; ++ u32 x[16]; ++ u32 w[64]; ++ int i; ++ ++ a = hd->h0; ++ b = hd->h1; ++ c = hd->h2; ++ d = hd->h3; ++ e = hd->h4; ++ f = hd->h5; ++ g = hd->h6; ++ h = hd->h7; ++ ++#ifdef WORDS_BIGENDIAN ++ memcpy (x, data, 64); ++#else /*!WORDS_BIGENDIAN*/ ++ { ++ unsigned char *p2; ++ ++ for (i=0, p2=(unsigned char*)x; i < 16; i++, p2 += 4 ) ++ { ++ p2[3] = *data++; ++ p2[2] = *data++; ++ p2[1] = *data++; ++ p2[0] = *data++; ++ } ++ } ++#endif /*!WORDS_BIGENDIAN*/ ++ ++ for (i=0; i < 16; i++) ++ w[i] = x[i]; ++ for (; i < 64; i++) ++ w[i] = S1(w[i-2]) + w[i-7] + S0(w[i-15]) + w[i-16]; ++ ++ for (i=0; i < 64; i++) ++ R(a,b,c,d,e,f,g,h,K[i],w[i]); ++ ++ hd->h0 += a; ++ hd->h1 += b; ++ hd->h2 += c; ++ hd->h3 += d; ++ hd->h4 += e; ++ hd->h5 += f; ++ hd->h6 += g; ++ hd->h7 += h; ++} ++#undef Cho ++#undef Maj ++#undef Sum0 ++#undef Sum1 ++#undef S0 ++#undef S1 ++#undef R ++ ++ ++/* Finalize the current SHA256 calculation. */ ++static void ++finalize (hmac256_context_t hd) ++{ ++ u32 t, msb, lsb; ++ unsigned char *p; ++ ++ if (hd->finalized) ++ return; /* Silently ignore a finalized context. */ ++ ++ _gcry_hmac256_update (hd, NULL, 0); /* Flush. */ ++ ++ t = hd->nblocks; ++ /* Multiply by 64 to make a byte count. */ ++ lsb = t << 6; ++ msb = t >> 26; ++ /* Add the count. */ ++ t = lsb; ++ if ((lsb += hd->count) < t) ++ msb++; ++ /* Multiply by 8 to make a bit count. */ ++ t = lsb; ++ lsb <<= 3; ++ msb <<= 3; ++ msb |= t >> 29; ++ ++ if (hd->count < 56) ++ { /* Enough room. */ ++ hd->buf[hd->count++] = 0x80; /* pad */ ++ while (hd->count < 56) ++ hd->buf[hd->count++] = 0; /* pad */ ++ } ++ else ++ { /* Need one extra block. */ ++ hd->buf[hd->count++] = 0x80; /* pad character */ ++ while (hd->count < 64) ++ hd->buf[hd->count++] = 0; ++ _gcry_hmac256_update (hd, NULL, 0); /* Flush. */; ++ memset (hd->buf, 0, 56 ); /* Zero out next next block. */ ++ } ++ /* Append the 64 bit count. */ ++ hd->buf[56] = msb >> 24; ++ hd->buf[57] = msb >> 16; ++ hd->buf[58] = msb >> 8; ++ hd->buf[59] = msb; ++ hd->buf[60] = lsb >> 24; ++ hd->buf[61] = lsb >> 16; ++ hd->buf[62] = lsb >> 8; ++ hd->buf[63] = lsb; ++ transform (hd, hd->buf); ++ ++ /* Store the digest into hd->buf. */ ++ p = hd->buf; ++#define X(a) do { *p++ = hd->h##a >> 24; *p++ = hd->h##a >> 16; \ ++ *p++ = hd->h##a >> 8; *p++ = hd->h##a; } while(0) ++ X(0); ++ X(1); ++ X(2); ++ X(3); ++ X(4); ++ X(5); ++ X(6); ++ X(7); ++#undef X ++ hd->finalized = 1; ++} ++ ++ ++ ++/* Create a new context. On error NULL is returned and errno is set ++ appropriately. If KEY is given the function computes HMAC using ++ this key; with KEY given as NULL, a plain SHA-256 digest is ++ computed. */ ++hmac256_context_t ++_gcry_hmac256_new (const void *key, size_t keylen) ++{ ++ hmac256_context_t hd; ++ ++ hd = malloc (sizeof *hd); ++ if (!hd) ++ return NULL; ++ ++ hd->h0 = 0x6a09e667; ++ hd->h1 = 0xbb67ae85; ++ hd->h2 = 0x3c6ef372; ++ hd->h3 = 0xa54ff53a; ++ hd->h4 = 0x510e527f; ++ hd->h5 = 0x9b05688c; ++ hd->h6 = 0x1f83d9ab; ++ hd->h7 = 0x5be0cd19; ++ hd->nblocks = 0; ++ hd->count = 0; ++ hd->finalized = 0; ++ hd->use_hmac = 0; ++ ++ if (key) ++ { ++ int i; ++ unsigned char ipad[64]; ++ ++ memset (ipad, 0, 64); ++ memset (hd->opad, 0, 64); ++ if (keylen <= 64) ++ { ++ memcpy (ipad, key, keylen); ++ memcpy (hd->opad, key, keylen); ++ } ++ else ++ { ++ hmac256_context_t tmphd; ++ ++ tmphd = _gcry_hmac256_new (NULL, 0); ++ if (!tmphd) ++ { ++ free (hd); ++ return NULL; ++ } ++ _gcry_hmac256_update (tmphd, key, keylen); ++ finalize (tmphd); ++ memcpy (ipad, tmphd->buf, 32); ++ memcpy (hd->opad, tmphd->buf, 32); ++ _gcry_hmac256_release (tmphd); ++ } ++ for (i=0; i < 64; i++) ++ { ++ ipad[i] ^= 0x36; ++ hd->opad[i] ^= 0x5c; ++ } ++ hd->use_hmac = 1; ++ _gcry_hmac256_update (hd, ipad, 64); ++ my_wipememory (ipad, 64); ++ } ++ ++ return hd; ++} ++ ++/* Release a context created by _gcry_hmac256_new. CTX may be NULL ++ in which case the function does nothing. */ ++void ++_gcry_hmac256_release (hmac256_context_t ctx) ++{ ++ if (ctx) ++ { ++ /* Note: We need to take care not to modify errno. */ ++ if (ctx->use_hmac) ++ my_wipememory (ctx->opad, 64); ++ free (ctx); ++ } ++} ++ ++ ++/* Update the message digest with the contents of BUFFER containing ++ LENGTH bytes. */ ++void ++_gcry_hmac256_update (hmac256_context_t hd, ++ const void *buffer, size_t length) ++{ ++ const unsigned char *inbuf = buffer; ++ ++ if (hd->finalized) ++ return; /* Silently ignore a finalized context. */ ++ ++ if (hd->count == 64) ++ { ++ /* Flush the buffer. */ ++ transform (hd, hd->buf); ++ hd->count = 0; ++ hd->nblocks++; ++ } ++ if (!inbuf) ++ return; /* Only flushing was requested. */ ++ if (hd->count) ++ { ++ for (; length && hd->count < 64; length--) ++ hd->buf[hd->count++] = *inbuf++; ++ _gcry_hmac256_update (hd, NULL, 0); /* Flush. */ ++ if (!length) ++ return; ++ } ++ ++ ++ while (length >= 64) ++ { ++ transform (hd, inbuf); ++ hd->count = 0; ++ hd->nblocks++; ++ length -= 64; ++ inbuf += 64; ++ } ++ for (; length && hd->count < 64; length--) ++ hd->buf[hd->count++] = *inbuf++; ++} ++ ++ ++/* Finalize an operation and return the digest. If R_DLEN is not NULL ++ the length of the digest will be stored at that address. The ++ returned value is valid as long as the context exists. On error ++ NULL is returned. */ ++const void * ++_gcry_hmac256_finalize (hmac256_context_t hd, size_t *r_dlen) ++{ ++ finalize (hd); ++ if (hd->use_hmac) ++ { ++ hmac256_context_t tmphd; ++ ++ tmphd = _gcry_hmac256_new (NULL, 0); ++ if (!tmphd) ++ { ++ free (hd); ++ return NULL; ++ } ++ _gcry_hmac256_update (tmphd, hd->opad, 64); ++ _gcry_hmac256_update (tmphd, hd->buf, 32); ++ finalize (tmphd); ++ memcpy (hd->buf, tmphd->buf, 32); ++ _gcry_hmac256_release (tmphd); ++ } ++ if (r_dlen) ++ *r_dlen = 32; ++ return (void*)hd->buf; ++} ++ ++ ++/* Convenience function to compute the HMAC-SHA256 of one file. The ++ user needs to provide a buffer RESULT of at least 32 bytes, he ++ needs to put the size of the buffer into RESULTSIZE and the ++ FILENAME. KEY and KEYLEN are as described for _gcry_hmac256_new. ++ On success the function returns the valid length of the result ++ buffer (which will be 32) or -1 on error. On error ERRNO is set ++ appropriate. */ ++int ++_gcry_hmac256_file (void *result, size_t resultsize, const char *filename, ++ const void *key, size_t keylen) ++{ ++ FILE *fp; ++ hmac256_context_t hd; ++ size_t buffer_size, nread, digestlen; ++ char *buffer; ++ const unsigned char *digest; ++ ++ fp = fopen (filename, "rb"); ++ if (!fp) ++ return -1; ++ ++ hd = _gcry_hmac256_new (key, keylen); ++ if (!hd) ++ { ++ fclose (fp); ++ return -1; ++ } ++ ++ buffer_size = 32768; ++ buffer = malloc (buffer_size); ++ if (!buffer) ++ { ++ fclose (fp); ++ _gcry_hmac256_release (hd); ++ return -1; ++ } ++ ++ while ( (nread = fread (buffer, 1, buffer_size, fp))) ++ _gcry_hmac256_update (hd, buffer, nread); ++ ++ free (buffer); ++ ++ if (ferror (fp)) ++ { ++ fclose (fp); ++ _gcry_hmac256_release (hd); ++ return -1; ++ } ++ ++ fclose (fp); ++ ++ digest = _gcry_hmac256_finalize (hd, &digestlen); ++ if (!digest) ++ { ++ _gcry_hmac256_release (hd); ++ return -1; ++ } ++ ++ if (digestlen > resultsize) ++ { ++ _gcry_hmac256_release (hd); ++ gpg_err_set_errno (EINVAL); ++ return -1; ++ } ++ memcpy (result, digest, digestlen); ++ _gcry_hmac256_release (hd); ++ ++ return digestlen; ++} ++ ++ ++ ++#ifdef STANDALONE ++static int ++selftest (void) ++{ ++ static struct ++ { ++ const char * const desc; ++ const char * const data; ++ const char * const key; ++ const unsigned char expect[32]; ++ } tv[] = ++ { ++ { "data-28 key-4", ++ "what do ya want for nothing?", ++ "Jefe", ++ { 0x5b, 0xdc, 0xc1, 0x46, 0xbf, 0x60, 0x75, 0x4e, ++ 0x6a, 0x04, 0x24, 0x26, 0x08, 0x95, 0x75, 0xc7, ++ 0x5a, 0x00, 0x3f, 0x08, 0x9d, 0x27, 0x39, 0x83, ++ 0x9d, 0xec, 0x58, 0xb9, 0x64, 0xec, 0x38, 0x43 } }, ++ ++ { "data-9 key-20", ++ "Hi There", ++ "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b" ++ "\x0b\x0b\x0b\x0b", ++ { 0xb0, 0x34, 0x4c, 0x61, 0xd8, 0xdb, 0x38, 0x53, ++ 0x5c, 0xa8, 0xaf, 0xce, 0xaf, 0x0b, 0xf1, 0x2b, ++ 0x88, 0x1d, 0xc2, 0x00, 0xc9, 0x83, 0x3d, 0xa7, ++ 0x26, 0xe9, 0x37, 0x6c, 0x2e, 0x32, 0xcf, 0xf7 } }, ++ ++ { "data-50 key-20", ++ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" ++ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" ++ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" ++ "\xdd\xdd", ++ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" ++ "\xaa\xaa\xaa\xaa", ++ { 0x77, 0x3e, 0xa9, 0x1e, 0x36, 0x80, 0x0e, 0x46, ++ 0x85, 0x4d, 0xb8, 0xeb, 0xd0, 0x91, 0x81, 0xa7, ++ 0x29, 0x59, 0x09, 0x8b, 0x3e, 0xf8, 0xc1, 0x22, ++ 0xd9, 0x63, 0x55, 0x14, 0xce, 0xd5, 0x65, 0xfe } }, ++ ++ { "data-50 key-26", ++ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" ++ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" ++ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" ++ "\xcd\xcd", ++ "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10" ++ "\x11\x12\x13\x14\x15\x16\x17\x18\x19", ++ { 0x82, 0x55, 0x8a, 0x38, 0x9a, 0x44, 0x3c, 0x0e, ++ 0xa4, 0xcc, 0x81, 0x98, 0x99, 0xf2, 0x08, 0x3a, ++ 0x85, 0xf0, 0xfa, 0xa3, 0xe5, 0x78, 0xf8, 0x07, ++ 0x7a, 0x2e, 0x3f, 0xf4, 0x67, 0x29, 0x66, 0x5b } }, ++ ++ { "data-54 key-131", ++ "Test Using Larger Than Block-Size Key - Hash Key First", ++ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" ++ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" ++ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" ++ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" ++ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" ++ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" ++ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" ++ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" ++ "\xaa\xaa\xaa", ++ { 0x60, 0xe4, 0x31, 0x59, 0x1e, 0xe0, 0xb6, 0x7f, ++ 0x0d, 0x8a, 0x26, 0xaa, 0xcb, 0xf5, 0xb7, 0x7f, ++ 0x8e, 0x0b, 0xc6, 0x21, 0x37, 0x28, 0xc5, 0x14, ++ 0x05, 0x46, 0x04, 0x0f, 0x0e, 0xe3, 0x7f, 0x54 } }, ++ ++ { "data-152 key-131", ++ "This is a test using a larger than block-size key and a larger " ++ "than block-size data. The key needs to be hashed before being " ++ "used by the HMAC algorithm.", ++ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" ++ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" ++ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" ++ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" ++ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" ++ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" ++ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" ++ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" ++ "\xaa\xaa\xaa", ++ { 0x9b, 0x09, 0xff, 0xa7, 0x1b, 0x94, 0x2f, 0xcb, ++ 0x27, 0x63, 0x5f, 0xbc, 0xd5, 0xb0, 0xe9, 0x44, ++ 0xbf, 0xdc, 0x63, 0x64, 0x4f, 0x07, 0x13, 0x93, ++ 0x8a, 0x7f, 0x51, 0x53, 0x5c, 0x3a, 0x35, 0xe2 } }, ++ ++ { NULL } ++ }; ++ int tvidx; ++ ++ for (tvidx=0; tv[tvidx].desc; tvidx++) ++ { ++ hmac256_context_t hmachd; ++ const unsigned char *digest; ++ size_t dlen; ++ ++ hmachd = _gcry_hmac256_new (tv[tvidx].key, strlen (tv[tvidx].key)); ++ if (!hmachd) ++ return -1; ++ _gcry_hmac256_update (hmachd, tv[tvidx].data, strlen (tv[tvidx].data)); ++ digest = _gcry_hmac256_finalize (hmachd, &dlen); ++ if (!digest) ++ { ++ _gcry_hmac256_release (hmachd); ++ return -1; ++ } ++ if (dlen != sizeof (tv[tvidx].expect) ++ || memcmp (digest, tv[tvidx].expect, sizeof (tv[tvidx].expect))) ++ { ++ _gcry_hmac256_release (hmachd); ++ return -1; ++ } ++ _gcry_hmac256_release (hmachd); ++ } ++ ++ return 0; /* Succeeded. */ ++} ++ ++ ++int ++main (int argc, char **argv) ++{ ++ const char *pgm; ++ int last_argc = -1; ++ const char *key; ++ size_t keylen; ++ FILE *fp; ++ hmac256_context_t hd; ++ const unsigned char *digest; ++ char buffer[4096]; ++ size_t n, dlen, idx; ++ int use_stdin = 0; ++ int use_binary = 0; ++ ++ assert (sizeof (u32) == 4); ++#ifdef __WIN32 ++ setmode (fileno (stdin), O_BINARY); ++#endif ++ ++ if (argc) ++ { ++ pgm = strrchr (*argv, '/'); ++ if (pgm) ++ pgm++; ++ else ++ pgm = *argv; ++ argc--; argv++; ++ } ++ else ++ pgm = "?"; ++ ++ while (argc && last_argc != argc ) ++ { ++ last_argc = argc; ++ if (!strcmp (*argv, "--")) ++ { ++ argc--; argv++; ++ break; ++ } ++ else if (!strcmp (*argv, "--version")) ++ { ++ fputs ("hmac256 (Libgcrypt) " VERSION "\n" ++ "Copyright (C) 2008 Free Software Foundation, Inc.\n" ++ "License LGPLv2.1+: GNU LGPL version 2.1 or later " ++ "\n" ++ "This is free software: you are free to change and " ++ "redistribute it.\n" ++ "There is NO WARRANTY, to the extent permitted by law.\n", ++ stdout); ++ exit (0); ++ } ++ else if (!strcmp (*argv, "--binary")) ++ { ++ argc--; argv++; ++ use_binary = 1; ++ } ++ } ++ ++ if (argc < 1) ++ { ++ fprintf (stderr, "usage: %s [--binary] key [filename]\n", pgm); ++ exit (1); ++ } ++ ++#ifdef __WIN32 ++ if (use_binary) ++ setmode (fileno (stdout), O_BINARY); ++#endif ++ ++ key = *argv; ++ argc--, argv++; ++ keylen = strlen (key); ++ use_stdin = !argc; ++ ++ if (selftest ()) ++ { ++ fprintf (stderr, "%s: fatal error: self-test failed\n", pgm); ++ exit (2); ++ } ++ ++ for (; argc || use_stdin; argv++, argc--) ++ { ++ const char *fname = use_stdin? "-" : *argv; ++ fp = use_stdin? stdin : fopen (fname, "rb"); ++ if (!fp) ++ { ++ fprintf (stderr, "%s: can't open `%s': %s\n", ++ pgm, fname, strerror (errno)); ++ exit (1); ++ } ++ hd = _gcry_hmac256_new (key, keylen); ++ if (!hd) ++ { ++ fprintf (stderr, "%s: can't allocate context: %s\n", ++ pgm, strerror (errno)); ++ exit (1); ++ } ++ while ( (n = fread (buffer, 1, sizeof buffer, fp))) ++ _gcry_hmac256_update (hd, buffer, n); ++ if (ferror (fp)) ++ { ++ fprintf (stderr, "%s: error reading `%s': %s\n", ++ pgm, fname, strerror (errno)); ++ exit (1); ++ } ++ if (!use_stdin) ++ fclose (fp); ++ ++ digest = _gcry_hmac256_finalize (hd, &dlen); ++ if (!digest) ++ { ++ fprintf (stderr, "%s: error computing HMAC: %s\n", ++ pgm, strerror (errno)); ++ exit (1); ++ } ++ if (use_binary) ++ { ++ if (fwrite (digest, dlen, 1, stdout) != 1) ++ { ++ fprintf (stderr, "%s: error writing output: %s\n", ++ pgm, strerror (errno)); ++ exit (1); ++ } ++ if (use_stdin) ++ break; ++ } ++ else ++ { ++ for (idx=0; idx < dlen; idx++) ++ printf ("%02x", digest[idx]); ++ _gcry_hmac256_release (hd); ++ if (use_stdin) ++ { ++ putchar ('\n'); ++ break; ++ } ++ printf (" %s\n", fname); ++ } ++ } ++ ++ return 0; ++} ++#endif /*STANDALONE*/ ++ ++ ++/* ++Local Variables: ++compile-command: "cc -Wall -g -I.. -DSTANDALONE -o hmac256 hmac256.c" ++End: ++*/ +diff --git a/grub-core/lib/libgcrypt/src/hmac256.h b/grub-core/lib/libgcrypt/src/hmac256.h +new file mode 100644 +index 0000000..df28e72 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/src/hmac256.h +@@ -0,0 +1,36 @@ ++/* hmac256.h - Declarations for _gcry_hmac256 ++ * Copyright (C) 2008 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser general Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, see . ++ */ ++ ++#ifndef HMAC256_H ++#define HMAC256_H ++ ++ ++struct hmac256_context; ++typedef struct hmac256_context *hmac256_context_t; ++ ++hmac256_context_t _gcry_hmac256_new (const void *key, size_t keylen); ++void _gcry_hmac256_update (hmac256_context_t hd, const void *buf, size_t len); ++const void *_gcry_hmac256_finalize (hmac256_context_t hd, size_t *r_dlen); ++void _gcry_hmac256_release (hmac256_context_t hd); ++ ++int _gcry_hmac256_file (void *result, size_t resultsize, const char *filename, ++ const void *key, size_t keylen); ++ ++ ++#endif /*HMAC256_H*/ +diff --git a/grub-core/lib/libgcrypt/src/hwfeatures.c b/grub-core/lib/libgcrypt/src/hwfeatures.c +new file mode 100644 +index 0000000..c356798 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/src/hwfeatures.c +@@ -0,0 +1,192 @@ ++/* hwfeatures.c - Detect hardware features. ++ * Copyright (C) 2007, 2011 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, see . ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "g10lib.h" ++ ++/* A bit vector describing the hardware features currently ++ available. */ ++static unsigned int hw_features; ++ ++ ++/* Return a bit vector describing the available hardware features. ++ The HWF_ constants are used to test for them. */ ++unsigned int ++_gcry_get_hw_features (void) ++{ ++ return hw_features; ++} ++ ++ ++#if defined (__i386__) && SIZEOF_UNSIGNED_LONG == 4 && defined (__GNUC__) ++static void ++detect_ia32_gnuc (void) ++{ ++ /* The code here is only useful for the PadLock engine thus we don't ++ build it if that support has been disabled. */ ++ int has_cpuid = 0; ++ char vendor_id[12+1]; ++ ++ /* Detect the CPUID feature by testing some undefined behaviour (16 ++ vs 32 bit pushf/popf). */ ++ asm volatile ++ ("pushf\n\t" /* Copy flags to EAX. */ ++ "popl %%eax\n\t" ++ "movl %%eax, %%ecx\n\t" /* Save flags into ECX. */ ++ "xorl $0x200000, %%eax\n\t" /* Toggle ID bit and copy it to the flags. */ ++ "pushl %%eax\n\t" ++ "popf\n\t" ++ "pushf\n\t" /* Copy changed flags again to EAX. */ ++ "popl %%eax\n\t" ++ "pushl %%ecx\n\t" /* Restore flags from ECX. */ ++ "popf\n\t" ++ "xorl %%eax, %%ecx\n\t" /* Compare flags against saved flags. */ ++ "jz .Lno_cpuid%=\n\t" /* Toggling did not work, thus no CPUID. */ ++ "movl $1, %0\n" /* Worked. true -> HAS_CPUID. */ ++ ".Lno_cpuid%=:\n\t" ++ : "+r" (has_cpuid) ++ : ++ : "%eax", "%ecx", "cc" ++ ); ++ ++ if (!has_cpuid) ++ return; /* No way. */ ++ ++ asm volatile ++ ("pushl %%ebx\n\t" /* Save GOT register. */ ++ "xorl %%eax, %%eax\n\t" /* 0 -> EAX. */ ++ "cpuid\n\t" /* Get vendor ID. */ ++ "movl %%ebx, (%0)\n\t" /* EBX,EDX,ECX -> VENDOR_ID. */ ++ "movl %%edx, 4(%0)\n\t" ++ "movl %%ecx, 8(%0)\n\t" ++ "popl %%ebx\n" ++ : ++ : "S" (&vendor_id[0]) ++ : "%eax", "%ecx", "%edx", "cc" ++ ); ++ vendor_id[12] = 0; ++ ++ if (0) ++ ; /* Just to make "else if" and ifdef macros look pretty. */ ++#ifdef ENABLE_PADLOCK_SUPPORT ++ else if (!strcmp (vendor_id, "CentaurHauls")) ++ { ++ /* This is a VIA CPU. Check what PadLock features we have. */ ++ asm volatile ++ ("pushl %%ebx\n\t" /* Save GOT register. */ ++ "movl $0xC0000000, %%eax\n\t" /* Check for extended centaur */ ++ "cpuid\n\t" /* feature flags. */ ++ "popl %%ebx\n\t" /* Restore GOT register. */ ++ "cmpl $0xC0000001, %%eax\n\t" ++ "jb .Lready%=\n\t" /* EAX < 0xC0000000 => no padlock. */ ++ ++ "pushl %%ebx\n\t" /* Save GOT register. */ ++ "movl $0xC0000001, %%eax\n\t" /* Ask for the extended */ ++ "cpuid\n\t" /* feature flags. */ ++ "popl %%ebx\n\t" /* Restore GOT register. */ ++ ++ "movl %%edx, %%eax\n\t" /* Take copy of feature flags. */ ++ "andl $0x0C, %%eax\n\t" /* Test bits 2 and 3 to see whether */ ++ "cmpl $0x0C, %%eax\n\t" /* the RNG exists and is enabled. */ ++ "jnz .Lno_rng%=\n\t" ++ "orl $1, %0\n" /* Set our HWF_PADLOCK_RNG bit. */ ++ ++ ".Lno_rng%=:\n\t" ++ "movl %%edx, %%eax\n\t" /* Take copy of feature flags. */ ++ "andl $0xC0, %%eax\n\t" /* Test bits 6 and 7 to see whether */ ++ "cmpl $0xC0, %%eax\n\t" /* the ACE exists and is enabled. */ ++ "jnz .Lno_ace%=\n\t" ++ "orl $2, %0\n" /* Set our HWF_PADLOCK_AES bit. */ ++ ++ ".Lno_ace%=:\n\t" ++ "movl %%edx, %%eax\n\t" /* Take copy of feature flags. */ ++ "andl $0xC00, %%eax\n\t" /* Test bits 10, 11 to see whether */ ++ "cmpl $0xC00, %%eax\n\t" /* the PHE exists and is enabled. */ ++ "jnz .Lno_phe%=\n\t" ++ "orl $4, %0\n" /* Set our HWF_PADLOCK_SHA bit. */ ++ ++ ".Lno_phe%=:\n\t" ++ "movl %%edx, %%eax\n\t" /* Take copy of feature flags. */ ++ "andl $0x3000, %%eax\n\t" /* Test bits 12, 13 to see whether */ ++ "cmpl $0x3000, %%eax\n\t" /* MONTMUL exists and is enabled. */ ++ "jnz .Lready%=\n\t" ++ "orl $8, %0\n" /* Set our HWF_PADLOCK_MMUL bit. */ ++ ++ ".Lready%=:\n" ++ : "+r" (hw_features) ++ : ++ : "%eax", "%edx", "cc" ++ ); ++ } ++#endif /*ENABLE_PADLOCK_SUPPORT*/ ++ else if (!strcmp (vendor_id, "GenuineIntel")) ++ { ++ /* This is an Intel CPU. */ ++ asm volatile ++ ("pushl %%ebx\n\t" /* Save GOT register. */ ++ "movl $1, %%eax\n\t" /* Get CPU info and feature flags. */ ++ "cpuid\n" ++ "popl %%ebx\n\t" /* Restore GOT register. */ ++ "testl $0x02000000, %%ecx\n\t" /* Test bit 25. */ ++ "jz .Lno_aes%=\n\t" /* No AES support. */ ++ "orl $256, %0\n" /* Set our HWF_INTEL_AES bit. */ ++ ++ ".Lno_aes%=:\n" ++ : "+r" (hw_features) ++ : ++ : "%eax", "%ecx", "%edx", "cc" ++ ); ++ } ++ else if (!strcmp (vendor_id, "AuthenticAMD")) ++ { ++ /* This is an AMD CPU. */ ++ ++ } ++} ++#endif /* __i386__ && SIZEOF_UNSIGNED_LONG == 4 && __GNUC__ */ ++ ++ ++/* Detect the available hardware features. This function is called ++ once right at startup and we assume that no other threads are ++ running. */ ++void ++_gcry_detect_hw_features (unsigned int disabled_features) ++{ ++ hw_features = 0; ++ ++ if (fips_mode ()) ++ return; /* Hardware support is not to be evaluated. */ ++ ++#if defined (__i386__) && SIZEOF_UNSIGNED_LONG == 4 ++#ifdef __GNUC__ ++ detect_ia32_gnuc (); ++#endif ++#elif defined (__i386__) && SIZEOF_UNSIGNED_LONG == 8 ++#ifdef __GNUC__ ++#endif ++#endif ++ ++ hw_features &= ~disabled_features; ++} +diff --git a/grub-core/lib/libgcrypt/src/libgcrypt-config.in b/grub-core/lib/libgcrypt/src/libgcrypt-config.in +new file mode 100644 +index 0000000..c052638 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/src/libgcrypt-config.in +@@ -0,0 +1,189 @@ ++#!/bin/sh ++# Copyright (C) 1999, 2002, 2003, 2004, 2011 Free Software Foundation, Inc. ++# ++# This file is free software; as a special exception the author gives ++# unlimited permission to copy and/or distribute it, with or without ++# modifications, as long as this notice is preserved. ++# ++# This file 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. ++# ++# File: @configure_input@ ++ ++# General. ++prefix="@prefix@" ++exec_prefix="@exec_prefix@" ++version="@VERSION@" ++includedir="@includedir@" ++libdir="@libdir@" ++gpg_error_libs="@GPG_ERROR_LIBS@" ++gpg_error_cflags="@GPG_ERROR_CFLAGS@" ++ ++# libgcrypt values. ++libs="@LIBGCRYPT_CONFIG_LIBS@" ++cflags="@LIBGCRYPT_CONFIG_CFLAGS@" ++ ++# API info ++api_version="@LIBGCRYPT_CONFIG_API_VERSION@" ++ ++# Configured for host ++my_host="@LIBGCRYPT_CONFIG_HOST@" ++ ++# Misc information. ++symmetric_ciphers="@LIBGCRYPT_CIPHERS@" ++asymmetric_ciphers="@LIBGCRYPT_PUBKEY_CIPHERS@" ++digests="@LIBGCRYPT_DIGESTS@" ++ ++# State variables. ++echo_libs=no ++echo_cflags=no ++echo_prefix=no ++echo_algorithms=no ++echo_exec_prefix=no ++echo_version=no ++echo_api_version=no ++echo_host=no ++ ++# Prints usage information. ++usage() ++{ ++ cat <&2 ++fi ++ ++while test $# -gt 0; do ++ case "$1" in ++ # Set up `optarg'. ++ --*=*) ++ optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ++ ;; ++ *) ++ optarg="" ++ ;; ++ esac ++ ++ case $1 in ++ --thread=*) ++ echo "$0: --thread option obsolete: use the thread callback interface" 1>&2 ++ exit 1 ++ ;; ++ --prefix=*) ++ # For compatibility reasons with old M4 macros, we ignore ++ # setting of prefix. ++ ;; ++ --prefix) ++ echo_prefix=yes ++ ;; ++ --exec-prefix=*) ++ ;; ++ --exec-prefix) ++ echo_exec_prefix=yes ++ ;; ++ --version) ++ echo_version=yes ++ ;; ++ --api-version) ++ echo_api_version=yes ++ ;; ++ --cflags) ++ echo_cflags=yes ++ ;; ++ --libs) ++ echo_libs=yes ++ ;; ++ --algorithms) ++ echo_algorithms=yes ++ ;; ++ --host) ++ echo_host=yes ++ ;; ++ *) ++ usage 1 1>&2 ++ ;; ++ esac ++ shift ++done ++ ++if test "$echo_prefix" = "yes"; then ++ echo "$prefix" ++fi ++ ++if test "$echo_exec_prefix" = "yes"; then ++ echo "$exec_prefix" ++fi ++ ++if test "$echo_cflags" = "yes"; then ++ includes="" ++ cflags_final="$cflags" ++ ++ # Set up `includes'. ++ if test "x$includedir" != "x/usr/include" -a "x$includedir" != "x/include"; then ++ includes="-I$includedir" ++ fi ++ # Set up `cflags_final'. ++ cflags_final="$cflags_final $gpg_error_cflags" ++ ++ tmp="" ++ for i in $includes $cflags_final; do ++ if echo "$tmp" | fgrep -v -- "$i" >/dev/null; then ++ tmp="$tmp $i" ++ fi ++ done ++ echo $tmp ++fi ++ ++if test "$echo_libs" = "yes"; then ++ libdirs="" ++ libs_final="$libs" ++ ++ # Set up `libdirs'. ++ if test "x$libdir" != "x/usr/lib" -a "x$libdir" != "x/lib"; then ++ libdirs="-L$libdir" ++ fi ++ ++ # Set up `libs_final'. ++ libs_final="$libs_final $gpg_error_libs" ++ ++ tmp="" ++ for i in $libdirs $libs_final; do ++ if echo "$tmp" | fgrep -v -- "$i" >/dev/null; then ++ tmp="$tmp $i" ++ fi ++ done ++ echo $tmp ++fi ++ ++if test "$echo_version" = "yes"; then ++ echo "$version" ++fi ++ ++if test "$echo_api_version" = "yes"; then ++ echo "$api_version" ++fi ++ ++if test "$echo_host" = "yes"; then ++ echo "$my_host" ++fi ++ ++if test "$echo_algorithms" = "yes"; then ++ echo "Symmetric cipher algorithms: $symmetric_ciphers" ++ echo "Public-key cipher algorithms: $asymmetric_ciphers" ++ echo "Message digest algorithms: $digests" ++fi +diff --git a/grub-core/lib/libgcrypt/src/libgcrypt.def b/grub-core/lib/libgcrypt/src/libgcrypt.def +new file mode 100644 +index 0000000..9bf0167 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/src/libgcrypt.def +@@ -0,0 +1,213 @@ ++;; libgcrypt.defs - Exported symbols for W32 ++;; Copyright (C) 2003, 2007 Free Software Foundation, Inc. ++;; ++;; This file is part of Libgcrypt. ++;; ++;; Libgcrypt is free software; you can redistribute it and/or modify ++;; it under the terms of the GNU Lesser General Public License as ++;; published by the Free Software Foundation; either version 2.1 of ++;; the License, or (at your option) any later version. ++;; ++;; Libgcrypt 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 Lesser General Public License for more details. ++;; ++;; You should have received a copy of the GNU Lesser General Public ++;; License along with this program; if not, write to the Free Software ++;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++;; ++ ++;; Note: This file should be updated manually and the ordinals shall ++;; never be changed. Also check libgcrypt.vers and visibility.h. ++ ++ ++EXPORTS ++ gcry_check_version @1 ++ gcry_control @2 ++ ++ gcry_malloc @3 ++ gcry_calloc @4 ++ gcry_malloc_secure @5 ++ gcry_calloc_secure @6 ++ gcry_realloc @7 ++ gcry_strdup @8 ++ gcry_xmalloc @9 ++ gcry_xcalloc @10 ++ gcry_xmalloc_secure @11 ++ gcry_xcalloc_secure @12 ++ gcry_xrealloc @13 ++ gcry_xstrdup @14 ++ gcry_is_secure @15 ++ gcry_free @16 ++ ++ gcry_set_progress_handler @17 ++ gcry_set_allocation_handler @18 ++ gcry_set_outofcore_handler @19 ++ gcry_set_fatalerror_handler @20 ++ gcry_set_log_handler @21 ++ gcry_set_gettext_handler @22 ++ ++ gcry_strerror @23 ++ gcry_strsource @24 ++ gcry_err_code_from_errno @25 ++ gcry_err_code_to_errno @26 ++ gcry_err_make_from_errno @27 ++ gcry_error_from_errno @28 ++ ++ gcry_sexp_new @29 ++ gcry_sexp_create @30 ++ gcry_sexp_sscan @31 ++ gcry_sexp_build @32 ++ gcry_sexp_build_array @33 ++ gcry_sexp_release @34 ++ gcry_sexp_canon_len @35 ++ gcry_sexp_sprint @36 ++ gcry_sexp_dump @37 ++ gcry_sexp_cons @38 ++ gcry_sexp_alist @39 ++ gcry_sexp_vlist @40 ++ gcry_sexp_append @41 ++ gcry_sexp_prepend @42 ++ gcry_sexp_find_token @43 ++ gcry_sexp_length @44 ++ gcry_sexp_nth @45 ++ gcry_sexp_car @46 ++ gcry_sexp_cdr @47 ++ gcry_sexp_cadr @48 ++ gcry_sexp_nth_data @49 ++ gcry_sexp_nth_mpi @50 ++ ++ gcry_mpi_new @51 ++ gcry_mpi_snew @52 ++ gcry_mpi_release @53 ++ gcry_mpi_copy @54 ++ gcry_mpi_set @55 ++ gcry_mpi_set_ui @56 ++ gcry_mpi_swap @57 ++ gcry_mpi_cmp @58 ++ gcry_mpi_cmp_ui @59 ++ gcry_mpi_scan @60 ++ gcry_mpi_print @61 ++ gcry_mpi_aprint @62 ++ gcry_mpi_dump @63 ++ gcry_mpi_add @64 ++ gcry_mpi_add_ui @65 ++ gcry_mpi_addm @66 ++ gcry_mpi_sub @67 ++ gcry_mpi_sub_ui @68 ++ gcry_mpi_subm @69 ++ gcry_mpi_mul @70 ++ gcry_mpi_mul_ui @71 ++ gcry_mpi_mulm @72 ++ gcry_mpi_mul_2exp @73 ++ gcry_mpi_div @74 ++ gcry_mpi_mod @75 ++ gcry_mpi_powm @76 ++ gcry_mpi_gcd @77 ++ gcry_mpi_invm @78 ++ gcry_mpi_get_nbits @79 ++ gcry_mpi_test_bit @80 ++ gcry_mpi_set_bit @81 ++ gcry_mpi_clear_bit @82 ++ gcry_mpi_set_highbit @83 ++ gcry_mpi_clear_highbit @84 ++ gcry_mpi_rshift @85 ++ gcry_mpi_set_opaque @86 ++ gcry_mpi_get_opaque @87 ++ gcry_mpi_set_flag @88 ++ gcry_mpi_clear_flag @89 ++ gcry_mpi_get_flag @90 ++ ++ ++ gcry_cipher_open @92 ++ gcry_cipher_close @93 ++ gcry_cipher_ctl @94 ++ gcry_cipher_info @95 ++ gcry_cipher_algo_info @96 ++ gcry_cipher_algo_name @97 ++ gcry_cipher_map_name @98 ++ gcry_cipher_mode_from_oid @99 ++ gcry_cipher_encrypt @100 ++ gcry_cipher_decrypt @101 ++ gcry_cipher_get_algo_keylen @102 ++ gcry_cipher_get_algo_blklen @103 ++ ++;; @104 used to be part of the module register interface ++ ++ gcry_pk_encrypt @105 ++ gcry_pk_decrypt @106 ++ gcry_pk_sign @107 ++ gcry_pk_verify @108 ++ gcry_pk_testkey @109 ++ gcry_pk_genkey @110 ++ gcry_pk_ctl @111 ++ gcry_pk_algo_info @112 ++ gcry_pk_algo_name @113 ++ gcry_pk_map_name @114 ++ gcry_pk_get_nbits @115 ++ gcry_pk_get_keygrip @116 ++ ++;; @117 used to be part of the module register interface ++ ++;; ++;; 118 to 142 were used in previous Libgcrypt versions for the gcry_ac ++;; interface ++;; ++ ++ gcry_md_open @143 ++ gcry_md_close @144 ++ gcry_md_enable @145 ++ gcry_md_copy @146 ++ gcry_md_reset @147 ++ gcry_md_ctl @148 ++ gcry_md_write @149 ++ gcry_md_read @150 ++ gcry_md_hash_buffer @151 ++ gcry_md_get_algo @152 ++ gcry_md_get_algo_dlen @153 ++ gcry_md_is_enabled @154 ++ gcry_md_is_secure @155 ++ gcry_md_info @156 ++ gcry_md_algo_info @157 ++ gcry_md_algo_name @158 ++ gcry_md_map_name @159 ++ gcry_md_setkey @160 ++;; @161 used to be part of the module register interface ++ gcry_randomize @162 ++ gcry_random_add_bytes @163 ++ gcry_random_bytes @164 ++ gcry_random_bytes_secure @165 ++ gcry_mpi_randomize @166 ++ ++ gcry_prime_generate @167 ++ gcry_prime_group_generator @168 ++ gcry_prime_release_factors @169 ++ gcry_prime_check @170 ++ ++ gcry_create_nonce @171 ++ ++ gcry_md_debug @172 ++ ++;; @173 used to be part of the module register interface ++;; @174 used to be part of the module register interface ++;; @175 used to be part of the module register interface ++;; @176 used to be part of the module register interface ++;; @177 used to be part of the module register interface ++;; @178 used to be part of the module register interface ++;; ++;; @179 to @186 used to be part of the removed gcry_ac interface ++;; ++ ++ gcry_sexp_nth_string @187 ++ ++ gcry_cipher_setkey @188 ++ gcry_cipher_setiv @189 ++ gcry_cipher_setctr @190 ++ ++ gcry_mpi_lshift @191 ++ ++ gcry_pk_get_curve @192 ++ gcry_pk_get_param @193 ++ ++ gcry_kdf_derive @194 +diff --git a/grub-core/lib/libgcrypt/src/libgcrypt.m4 b/grub-core/lib/libgcrypt/src/libgcrypt.m4 +new file mode 100644 +index 0000000..6cf482f +--- /dev/null ++++ b/grub-core/lib/libgcrypt/src/libgcrypt.m4 +@@ -0,0 +1,122 @@ ++dnl Autoconf macros for libgcrypt ++dnl Copyright (C) 2002, 2004, 2011 Free Software Foundation, Inc. ++dnl ++dnl This file is free software; as a special exception the author gives ++dnl unlimited permission to copy and/or distribute it, with or without ++dnl modifications, as long as this notice is preserved. ++dnl ++dnl This file is distributed in the hope that it will be useful, but ++dnl WITHOUT ANY WARRANTY, to the extent permitted by law; without even the ++dnl implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++ ++ ++dnl AM_PATH_LIBGCRYPT([MINIMUM-VERSION, ++dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]]) ++dnl Test for libgcrypt and define LIBGCRYPT_CFLAGS and LIBGCRYPT_LIBS. ++dnl MINIMUN-VERSION is a string with the version number optionalliy prefixed ++dnl with the API version to also check the API compatibility. Example: ++dnl a MINIMUN-VERSION of 1:1.2.5 won't pass the test unless the installed ++dnl version of libgcrypt is at least 1.2.5 *and* the API number is 1. Using ++dnl this features allows to prevent build against newer versions of libgcrypt ++dnl with a changed API. ++dnl ++AC_DEFUN([AM_PATH_LIBGCRYPT], ++[ AC_REQUIRE([AC_CANONICAL_HOST]) ++ AC_ARG_WITH(libgcrypt-prefix, ++ AC_HELP_STRING([--with-libgcrypt-prefix=PFX], ++ [prefix where LIBGCRYPT is installed (optional)]), ++ libgcrypt_config_prefix="$withval", libgcrypt_config_prefix="") ++ if test x$libgcrypt_config_prefix != x ; then ++ if test x${LIBGCRYPT_CONFIG+set} != xset ; then ++ LIBGCRYPT_CONFIG=$libgcrypt_config_prefix/bin/libgcrypt-config ++ fi ++ fi ++ ++ AC_PATH_TOOL(LIBGCRYPT_CONFIG, libgcrypt-config, no) ++ tmp=ifelse([$1], ,1:1.2.0,$1) ++ if echo "$tmp" | grep ':' >/dev/null 2>/dev/null ; then ++ req_libgcrypt_api=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\1/'` ++ min_libgcrypt_version=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\2/'` ++ else ++ req_libgcrypt_api=0 ++ min_libgcrypt_version="$tmp" ++ fi ++ ++ AC_MSG_CHECKING(for LIBGCRYPT - version >= $min_libgcrypt_version) ++ ok=no ++ if test "$LIBGCRYPT_CONFIG" != "no" ; then ++ req_major=`echo $min_libgcrypt_version | \ ++ sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\1/'` ++ req_minor=`echo $min_libgcrypt_version | \ ++ sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\2/'` ++ req_micro=`echo $min_libgcrypt_version | \ ++ sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\3/'` ++ libgcrypt_config_version=`$LIBGCRYPT_CONFIG --version` ++ major=`echo $libgcrypt_config_version | \ ++ sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\1/'` ++ minor=`echo $libgcrypt_config_version | \ ++ sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\2/'` ++ micro=`echo $libgcrypt_config_version | \ ++ sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\3/'` ++ if test "$major" -gt "$req_major"; then ++ ok=yes ++ else ++ if test "$major" -eq "$req_major"; then ++ if test "$minor" -gt "$req_minor"; then ++ ok=yes ++ else ++ if test "$minor" -eq "$req_minor"; then ++ if test "$micro" -ge "$req_micro"; then ++ ok=yes ++ fi ++ fi ++ fi ++ fi ++ fi ++ fi ++ if test $ok = yes; then ++ AC_MSG_RESULT([yes ($libgcrypt_config_version)]) ++ else ++ AC_MSG_RESULT(no) ++ fi ++ if test $ok = yes; then ++ # If we have a recent libgcrypt, we should also check that the ++ # API is compatible ++ if test "$req_libgcrypt_api" -gt 0 ; then ++ tmp=`$LIBGCRYPT_CONFIG --api-version 2>/dev/null || echo 0` ++ if test "$tmp" -gt 0 ; then ++ AC_MSG_CHECKING([LIBGCRYPT API version]) ++ if test "$req_libgcrypt_api" -eq "$tmp" ; then ++ AC_MSG_RESULT([okay]) ++ else ++ ok=no ++ AC_MSG_RESULT([does not match. want=$req_libgcrypt_api got=$tmp]) ++ fi ++ fi ++ fi ++ fi ++ if test $ok = yes; then ++ LIBGCRYPT_CFLAGS=`$LIBGCRYPT_CONFIG --cflags` ++ LIBGCRYPT_LIBS=`$LIBGCRYPT_CONFIG --libs` ++ ifelse([$2], , :, [$2]) ++ libgcrypt_config_host=`$LIBGCRYPT_CONFIG --host 2>/dev/null || echo none` ++ if test x"$libgcrypt_config_host" != xnone ; then ++ if test x"$libgcrypt_config_host" != x"$host" ; then ++ AC_MSG_WARN([[ ++*** ++*** The config script $LIBGCRYPT_CONFIG was ++*** built for $libgcrypt_config_host and thus may not match the ++*** used host $host. ++*** You may want to use the configure option --with-libgcrypt-prefix ++*** to specify a matching config script. ++***]]) ++ fi ++ fi ++ else ++ LIBGCRYPT_CFLAGS="" ++ LIBGCRYPT_LIBS="" ++ ifelse([$3], , :, [$3]) ++ fi ++ AC_SUBST(LIBGCRYPT_CFLAGS) ++ AC_SUBST(LIBGCRYPT_LIBS) ++]) +diff --git a/grub-core/lib/libgcrypt/src/libgcrypt.vers b/grub-core/lib/libgcrypt/src/libgcrypt.vers +new file mode 100644 +index 0000000..dcb3749 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/src/libgcrypt.vers +@@ -0,0 +1,94 @@ ++# libgcrypt.vers - What symbols to export -*- std -*- ++# Copyright (C) 2002, 2004, 2008, 2011 Free Software Foundation, Inc. ++# ++# This file is part of Libgcrypt. ++# ++# Libgcrypt is free software; you can redistribute it and/or modify ++# it under the terms of the GNU Lesser general Public License as ++# published by the Free Software Foundation; either version 2.1 of ++# the License, or (at your option) any later version. ++# ++# Libgcrypt 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 Lesser General Public License for more details. ++# ++# You should have received a copy of the GNU Lesser General Public ++# License along with this program; if not, write to the Free Software ++# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ ++# NOTE: When adding new functions, please make sure to add them to ++# visibility.h and libgcrypt.def as well. ++ ++GCRYPT_1.6 { ++ global: ++ gcry_check_version; gcry_control; ++ gcry_set_allocation_handler; gcry_set_fatalerror_handler; ++ gcry_set_gettext_handler; gcry_set_log_handler; ++ gcry_set_outofcore_handler; gcry_set_progress_handler; ++ ++ gcry_err_code_from_errno; gcry_err_code_to_errno; ++ gcry_err_make_from_errno; gcry_error_from_errno; ++ gcry_strerror; gcry_strsource; ++ ++ gcry_free; gcry_malloc; gcry_malloc_secure; gcry_calloc; ++ gcry_calloc_secure; gcry_realloc; gcry_strdup; gcry_is_secure; ++ gcry_xcalloc; gcry_xcalloc_secure; gcry_xmalloc; ++ gcry_xmalloc_secure; gcry_xrealloc; gcry_xstrdup; ++ ++ gcry_md_algo_info; gcry_md_algo_name; gcry_md_close; ++ gcry_md_copy; gcry_md_ctl; gcry_md_enable; gcry_md_get; ++ gcry_md_get_algo; gcry_md_get_algo_dlen; gcry_md_hash_buffer; ++ gcry_md_info; gcry_md_is_enabled; gcry_md_is_secure; ++ gcry_md_map_name; gcry_md_open; gcry_md_read; ++ gcry_md_reset; gcry_md_setkey; ++ gcry_md_write; gcry_md_debug; ++ ++ gcry_cipher_algo_info; gcry_cipher_algo_name; gcry_cipher_close; ++ gcry_cipher_ctl; gcry_cipher_decrypt; gcry_cipher_encrypt; ++ gcry_cipher_get_algo_blklen; gcry_cipher_get_algo_keylen; ++ gcry_cipher_info; gcry_cipher_map_name; ++ gcry_cipher_mode_from_oid; gcry_cipher_open; ++ gcry_cipher_setkey; gcry_cipher_setiv; gcry_cipher_setctr; ++ ++ gcry_pk_algo_info; gcry_pk_algo_name; gcry_pk_ctl; ++ gcry_pk_decrypt; gcry_pk_encrypt; gcry_pk_genkey; ++ gcry_pk_get_keygrip; gcry_pk_get_nbits; ++ gcry_pk_map_name; gcry_pk_register; gcry_pk_sign; ++ gcry_pk_testkey; gcry_pk_verify; ++ gcry_pk_get_curve; gcry_pk_get_param; ++ ++ gcry_kdf_derive; ++ ++ gcry_prime_check; gcry_prime_generate; ++ gcry_prime_group_generator; gcry_prime_release_factors; ++ ++ gcry_random_add_bytes; gcry_random_bytes; gcry_random_bytes_secure; ++ gcry_randomize; gcry_create_nonce; ++ ++ gcry_sexp_alist; gcry_sexp_append; gcry_sexp_build; ++ gcry_sexp_build_array; gcry_sexp_cadr; gcry_sexp_canon_len; ++ gcry_sexp_car; gcry_sexp_cdr; gcry_sexp_cons; gcry_sexp_create; ++ gcry_sexp_dump; gcry_sexp_find_token; gcry_sexp_length; ++ gcry_sexp_new; gcry_sexp_nth; gcry_sexp_nth_data; ++ gcry_sexp_nth_mpi; gcry_sexp_prepend; gcry_sexp_release; ++ gcry_sexp_sprint; gcry_sexp_sscan; gcry_sexp_vlist; ++ gcry_sexp_nth_string; ++ ++ gcry_mpi_add; gcry_mpi_add_ui; gcry_mpi_addm; gcry_mpi_aprint; ++ gcry_mpi_clear_bit; gcry_mpi_clear_flag; gcry_mpi_clear_highbit; ++ gcry_mpi_cmp; gcry_mpi_cmp_ui; gcry_mpi_copy; gcry_mpi_div; ++ gcry_mpi_dump; gcry_mpi_gcd; gcry_mpi_get_flag; gcry_mpi_get_nbits; ++ gcry_mpi_get_opaque; gcry_mpi_invm; gcry_mpi_mod; gcry_mpi_mul; ++ gcry_mpi_mul_2exp; gcry_mpi_mul_ui; gcry_mpi_mulm; gcry_mpi_new; ++ gcry_mpi_powm; gcry_mpi_print; gcry_mpi_randomize; gcry_mpi_release; ++ gcry_mpi_rshift; gcry_mpi_scan; gcry_mpi_set; gcry_mpi_set_bit; ++ gcry_mpi_set_flag; gcry_mpi_set_highbit; gcry_mpi_set_opaque; ++ gcry_mpi_set_ui; gcry_mpi_snew; gcry_mpi_sub; gcry_mpi_sub_ui; ++ gcry_mpi_subm; gcry_mpi_swap; gcry_mpi_test_bit; ++ gcry_mpi_lshift; ++ ++ local: ++ *; ++ ++}; +diff --git a/grub-core/lib/libgcrypt/src/misc.c b/grub-core/lib/libgcrypt/src/misc.c +new file mode 100644 +index 0000000..17bd546 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/src/misc.c +@@ -0,0 +1,298 @@ ++/* misc.c ++ * Copyright (C) 1999, 2001, 2002, 2003, 2007, ++ * 2008 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, see . ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "g10lib.h" ++#include "secmem.h" ++ ++static int verbosity_level = 0; ++ ++static void (*fatal_error_handler)(void*,int, const char*) = NULL; ++static void *fatal_error_handler_value = 0; ++static void (*log_handler)(void*,int, const char*, va_list) = NULL; ++static void *log_handler_value = 0; ++ ++static const char *(*user_gettext_handler)( const char * ) = NULL; ++ ++void ++gcry_set_gettext_handler( const char *(*f)(const char*) ) ++{ ++ user_gettext_handler = f; ++} ++ ++ ++const char * ++_gcry_gettext( const char *key ) ++{ ++ if( user_gettext_handler ) ++ return user_gettext_handler( key ); ++ /* FIXME: switch the domain to gnupg and restore later */ ++ return key; ++} ++ ++void ++gcry_set_fatalerror_handler( void (*fnc)(void*,int, const char*), void *value) ++{ ++ fatal_error_handler_value = value; ++ fatal_error_handler = fnc; ++} ++ ++static void ++write2stderr( const char *s ) ++{ ++ /* Dummy variable to silence gcc warning. */ ++ int res = write( 2, s, strlen(s) ); ++ (void) res; ++} ++ ++/* ++ * This function is called for fatal errors. A caller might want to ++ * set his own handler because this function simply calls abort(). ++ */ ++void ++_gcry_fatal_error (int rc, const char *text) ++{ ++ if ( !text ) /* get a default text */ ++ text = gpg_strerror (rc); ++ ++ if (fatal_error_handler && !fips_mode () ) ++ fatal_error_handler (fatal_error_handler_value, rc, text); ++ ++ fips_signal_fatal_error (text); ++ write2stderr("\nFatal error: "); ++ write2stderr(text); ++ write2stderr("\n"); ++ _gcry_secmem_term (); ++ abort (); ++} ++ ++void ++gcry_set_log_handler( void (*f)(void*,int, const char*, va_list ), ++ void *opaque ) ++{ ++ log_handler = f; ++ log_handler_value = opaque; ++} ++ ++void ++_gcry_set_log_verbosity( int level ) ++{ ++ verbosity_level = level; ++} ++ ++int ++_gcry_log_verbosity( int level ) ++{ ++ return verbosity_level >= level; ++} ++ ++/**************** ++ * This is our log function which prints all log messages to stderr or ++ * using the function defined with gcry_set_log_handler(). ++ */ ++static void ++_gcry_logv( int level, const char *fmt, va_list arg_ptr ) ++{ ++ if (log_handler) ++ log_handler (log_handler_value, level, fmt, arg_ptr); ++ else ++ { ++ switch (level) ++ { ++ case GCRY_LOG_CONT: break; ++ case GCRY_LOG_INFO: break; ++ case GCRY_LOG_WARN: break; ++ case GCRY_LOG_ERROR: break; ++ case GCRY_LOG_FATAL: fputs("Fatal: ",stderr ); break; ++ case GCRY_LOG_BUG: fputs("Ohhhh jeeee: ", stderr); break; ++ case GCRY_LOG_DEBUG: fputs("DBG: ", stderr ); break; ++ default: fprintf(stderr,"[Unknown log level %d]: ", level ); break; ++ } ++ vfprintf(stderr,fmt,arg_ptr) ; ++ } ++ ++ if ( level == GCRY_LOG_FATAL || level == GCRY_LOG_BUG ) ++ { ++ fips_signal_fatal_error ("internal error (fatal or bug)"); ++ _gcry_secmem_term (); ++ abort (); ++ } ++} ++ ++ ++void ++_gcry_log( int level, const char *fmt, ... ) ++{ ++ va_list arg_ptr ; ++ ++ va_start( arg_ptr, fmt ) ; ++ _gcry_logv( level, fmt, arg_ptr ); ++ va_end(arg_ptr); ++} ++ ++ ++#if defined(JNLIB_GCC_M_FUNCTION) || __STDC_VERSION__ >= 199901L ++void ++_gcry_bug( const char *file, int line, const char *func ) ++{ ++ _gcry_log( GCRY_LOG_BUG, ++ ("... this is a bug (%s:%d:%s)\n"), file, line, func ); ++ abort(); /* never called, but it makes the compiler happy */ ++} ++void ++_gcry_assert_failed (const char *expr, const char *file, int line, ++ const char *func) ++{ ++ _gcry_log (GCRY_LOG_BUG, ++ ("Assertion `%s' failed (%s:%d:%s)\n"), expr, file, line, func ); ++ abort(); /* Never called, but it makes the compiler happy. */ ++} ++#else ++void ++_gcry_bug( const char *file, int line ) ++{ ++ _gcry_log( GCRY_LOG_BUG, ++ _("you found a bug ... (%s:%d)\n"), file, line); ++ abort(); /* never called, but it makes the compiler happy */ ++} ++void ++_gcry_assert_failed (const char *expr, const char *file, int line) ++{ ++ _gcry_log (GCRY_LOG_BUG, ++ ("Assertion `%s' failed (%s:%d)\n"), expr, file, line); ++ abort(); /* Never called, but it makes the compiler happy. */ ++} ++#endif ++ ++void ++_gcry_log_info( const char *fmt, ... ) ++{ ++ va_list arg_ptr ; ++ ++ va_start( arg_ptr, fmt ) ; ++ _gcry_logv( GCRY_LOG_INFO, fmt, arg_ptr ); ++ va_end(arg_ptr); ++} ++ ++int ++_gcry_log_info_with_dummy_fp (FILE *fp, const char *fmt, ... ) ++{ ++ va_list arg_ptr; ++ ++ (void)fp; ++ va_start( arg_ptr, fmt ) ; ++ _gcry_logv( GCRY_LOG_INFO, fmt, arg_ptr ); ++ va_end(arg_ptr); ++ return 0; ++} ++ ++void ++_gcry_log_error( const char *fmt, ... ) ++{ ++ va_list arg_ptr ; ++ ++ va_start( arg_ptr, fmt ) ; ++ _gcry_logv( GCRY_LOG_ERROR, fmt, arg_ptr ); ++ va_end(arg_ptr); ++} ++ ++ ++void ++_gcry_log_fatal( const char *fmt, ... ) ++{ ++ va_list arg_ptr ; ++ ++ va_start( arg_ptr, fmt ) ; ++ _gcry_logv( GCRY_LOG_FATAL, fmt, arg_ptr ); ++ va_end(arg_ptr); ++ abort(); /* never called, but it makes the compiler happy */ ++} ++ ++void ++_gcry_log_bug( const char *fmt, ... ) ++{ ++ va_list arg_ptr ; ++ ++ va_start( arg_ptr, fmt ) ; ++ _gcry_logv( GCRY_LOG_BUG, fmt, arg_ptr ); ++ va_end(arg_ptr); ++ abort(); /* never called, but it makes the compiler happy */ ++} ++ ++void ++_gcry_log_debug( const char *fmt, ... ) ++{ ++ va_list arg_ptr ; ++ ++ va_start( arg_ptr, fmt ) ; ++ _gcry_logv( GCRY_LOG_DEBUG, fmt, arg_ptr ); ++ va_end(arg_ptr); ++} ++ ++ ++void ++_gcry_log_printf (const char *fmt, ...) ++{ ++ va_list arg_ptr; ++ ++ if (fmt) ++ { ++ va_start( arg_ptr, fmt ) ; ++ _gcry_logv (GCRY_LOG_CONT, fmt, arg_ptr); ++ va_end(arg_ptr); ++ } ++} ++ ++/* Print a hexdump of BUFFER. With TEXT of NULL print just the raw ++ dump, with TEXT an empty string, print a trailing linefeed, ++ otherwise print an entire debug line. */ ++void ++_gcry_log_printhex (const char *text, const void *buffer, size_t length) ++{ ++ if (text && *text) ++ log_debug ("%s ", text); ++ if (length) ++ { ++ const unsigned char *p = buffer; ++ log_printf ("%02X", *p); ++ for (length--, p++; length--; p++) ++ log_printf (" %02X", *p); ++ } ++ if (text) ++ log_printf ("\n"); ++} ++ ++ ++void ++_gcry_burn_stack (int bytes) ++{ ++ char buf[64]; ++ ++ wipememory (buf, sizeof buf); ++ bytes -= sizeof buf; ++ if (bytes > 0) ++ _gcry_burn_stack (bytes); ++} +diff --git a/grub-core/lib/libgcrypt/src/missing-string.c b/grub-core/lib/libgcrypt/src/missing-string.c +new file mode 100644 +index 0000000..4756c00 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/src/missing-string.c +@@ -0,0 +1,54 @@ ++/* missing-string.c - missing string utilities ++ * Copyright (C) 1994, 1998, 1999, 2000, 2001, ++ * 2003 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include "g10lib.h" ++ ++ ++#ifndef HAVE_STPCPY ++char * ++stpcpy(char *a,const char *b) ++{ ++ while( *b ) ++ *a++ = *b++; ++ *a = 0; ++ ++ return (char*)a; ++} ++#endif ++ ++ ++#ifndef HAVE_STRCASECMP ++int ++strcasecmp( const char *a, const char *b ) ++{ ++ for( ; *a && *b; a++, b++ ) { ++ if( *a != *b && toupper(*a) != toupper(*b) ) ++ break; ++ } ++ return *(const byte*)a - *(const byte*)b; ++} ++#endif +diff --git a/grub-core/lib/libgcrypt/src/module.c b/grub-core/lib/libgcrypt/src/module.c +new file mode 100644 +index 0000000..32f668d +--- /dev/null ++++ b/grub-core/lib/libgcrypt/src/module.c +@@ -0,0 +1,212 @@ ++/* module.c - Module management for libgcrypt. ++ * Copyright (C) 2003, 2008 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser general Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, see . ++ */ ++ ++#include ++#include ++#include "g10lib.h" ++ ++/* Please match these numbers with the allocated algorithm ++ numbers. */ ++#define MODULE_ID_MIN 600 ++#define MODULE_ID_LAST 65500 ++#define MODULE_ID_USER GCRY_MODULE_ID_USER ++#define MODULE_ID_USER_LAST GCRY_MODULE_ID_USER_LAST ++ ++#if MODULE_ID_MIN >= MODULE_ID_USER ++#error Need to implement a different search strategy ++#endif ++ ++/* Internal function. Generate a new, unique module ID for a module ++ that should be inserted into the module chain starting at ++ MODULES. */ ++static gcry_err_code_t ++_gcry_module_id_new (gcry_module_t modules, unsigned int *id_new) ++{ ++ unsigned int mod_id; ++ gcry_err_code_t err = GPG_ERR_NO_ERROR; ++ gcry_module_t module; ++ ++ /* Search for unused ID. */ ++ for (mod_id = MODULE_ID_MIN; mod_id < MODULE_ID_LAST; mod_id++) ++ { ++ if (mod_id == MODULE_ID_USER) ++ { ++ mod_id = MODULE_ID_USER_LAST; ++ continue; ++ } ++ ++ /* Search for a module with the current ID. */ ++ for (module = modules; module; module = module->next) ++ if (mod_id == module->mod_id) ++ break; ++ ++ if (! module) ++ /* None found -> the ID is available for use. */ ++ break; ++ } ++ ++ if (mod_id < MODULE_ID_LAST) ++ /* Done. */ ++ *id_new = mod_id; ++ else ++ /* No free ID found. */ ++ err = GPG_ERR_INTERNAL; ++ ++ return err; ++} ++ ++/* Add a module specification to the list ENTRIES. The new module has ++ it's use-counter set to one. */ ++gcry_err_code_t ++_gcry_module_add (gcry_module_t *entries, unsigned int mod_id, ++ void *spec, void *extraspec, gcry_module_t *module) ++{ ++ gcry_err_code_t err = 0; ++ gcry_module_t entry; ++ ++ if (! mod_id) ++ err = _gcry_module_id_new (*entries, &mod_id); ++ ++ if (! err) ++ { ++ entry = gcry_malloc (sizeof (struct gcry_module)); ++ if (! entry) ++ err = gpg_err_code_from_errno (errno); ++ } ++ ++ if (! err) ++ { ++ /* Fill new module entry. */ ++ entry->flags = 0; ++ entry->counter = 1; ++ entry->spec = spec; ++ entry->extraspec = extraspec; ++ entry->mod_id = mod_id; ++ ++ /* Link it into the list. */ ++ entry->next = *entries; ++ entry->prevp = entries; ++ if (*entries) ++ (*entries)->prevp = &entry->next; ++ *entries = entry; ++ ++ /* And give it to the caller. */ ++ if (module) ++ *module = entry; ++ } ++ return err; ++} ++ ++/* Internal function. Unlink CIPHER_ENTRY from the list of registered ++ ciphers and destroy it. */ ++static void ++_gcry_module_drop (gcry_module_t entry) ++{ ++ *entry->prevp = entry->next; ++ if (entry->next) ++ entry->next->prevp = entry->prevp; ++ ++ gcry_free (entry); ++} ++ ++/* Lookup a module specification by it's ID. After a successful ++ lookup, the module has it's resource counter incremented. */ ++gcry_module_t ++_gcry_module_lookup_id (gcry_module_t entries, unsigned int mod_id) ++{ ++ gcry_module_t entry; ++ ++ for (entry = entries; entry; entry = entry->next) ++ if (entry->mod_id == mod_id) ++ { ++ entry->counter++; ++ break; ++ } ++ ++ return entry; ++} ++ ++/* Lookup a module specification. After a successful lookup, the ++ module has it's resource counter incremented. FUNC is a function ++ provided by the caller, which is responsible for identifying the ++ wanted module. */ ++gcry_module_t ++_gcry_module_lookup (gcry_module_t entries, void *data, ++ gcry_module_lookup_t func) ++{ ++ gcry_module_t entry; ++ ++ for (entry = entries; entry; entry = entry->next) ++ if ((*func) (entry->spec, data)) ++ { ++ entry->counter++; ++ break; ++ } ++ ++ return entry; ++} ++ ++/* Release a module. In case the use-counter reaches zero, destroy ++ the module. Passing MODULE as NULL is a dummy operation (similar ++ to free()). */ ++void ++_gcry_module_release (gcry_module_t module) ++{ ++ if (module && ! --module->counter) ++ _gcry_module_drop (module); ++} ++ ++/* Add a reference to a module. */ ++void ++_gcry_module_use (gcry_module_t module) ++{ ++ ++module->counter; ++} ++ ++/* If LIST is zero, write the number of modules identified by MODULES ++ to LIST_LENGTH and return. If LIST is non-zero, the first ++ *LIST_LENGTH algorithm IDs are stored in LIST, which must be of ++ according size. In case there are less cipher modules than ++ *LIST_LENGTH, *LIST_LENGTH is updated to the correct number. */ ++gcry_err_code_t ++_gcry_module_list (gcry_module_t modules, ++ int *list, int *list_length) ++{ ++ gcry_err_code_t err = GPG_ERR_NO_ERROR; ++ gcry_module_t module; ++ int length, i; ++ ++ for (module = modules, length = 0; module; module = module->next, length++); ++ ++ if (list) ++ { ++ if (length > *list_length) ++ length = *list_length; ++ ++ for (module = modules, i = 0; i < length; module = module->next, i++) ++ list[i] = module->mod_id; ++ ++ if (length < *list_length) ++ *list_length = length; ++ } ++ else ++ *list_length = length; ++ ++ return err; ++} +diff --git a/grub-core/lib/libgcrypt/src/mpi.h b/grub-core/lib/libgcrypt/src/mpi.h +new file mode 100644 +index 0000000..7eebc12 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/src/mpi.h +@@ -0,0 +1,263 @@ ++/* mpi.h - Multi Precision Integers ++ * Copyright (C) 1994, 1996, 1998, ++ * 2001, 2002, 2003, 2005 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser general Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ * ++ * Note: This code is heavily based on the GNU MP Library. ++ * Actually it's the same code with only minor changes in the ++ * way the data is stored; this is to support the abstraction ++ * of an optional secure memory allocation which may be used ++ * to avoid revealing of sensitive data due to paging etc. ++ */ ++ ++#ifndef G10_MPI_H ++#define G10_MPI_H ++ ++#include ++#include ++#include ++ ++#include "types.h" ++#include "../mpi/mpi-asm-defs.h" ++ ++#include "g10lib.h" ++ ++#ifndef _GCRYPT_IN_LIBGCRYPT ++#error this file should only be used inside libgcrypt ++#endif ++ ++#ifndef BITS_PER_MPI_LIMB ++#if BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_INT ++ typedef unsigned int mpi_limb_t; ++ typedef signed int mpi_limb_signed_t; ++#elif BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_LONG ++ typedef unsigned long int mpi_limb_t; ++ typedef signed long int mpi_limb_signed_t; ++#elif BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_LONG_LONG ++ typedef unsigned long long int mpi_limb_t; ++ typedef signed long long int mpi_limb_signed_t; ++#elif BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_SHORT ++ typedef unsigned short int mpi_limb_t; ++ typedef signed short int mpi_limb_signed_t; ++#else ++#error BYTES_PER_MPI_LIMB does not match any C type ++#endif ++#define BITS_PER_MPI_LIMB (8*BYTES_PER_MPI_LIMB) ++#endif /*BITS_PER_MPI_LIMB*/ ++ ++#define DBG_MPI _gcry_get_debug_flag( 2 ); ++ ++struct gcry_mpi ++{ ++ int alloced; /* Array size (# of allocated limbs). */ ++ int nlimbs; /* Number of valid limbs. */ ++ int sign; /* Indicates a negative number and is also used ++ for opaque MPIs to store the length. */ ++ unsigned int flags; /* Bit 0: Array to be allocated in secure memory space.*/ ++ /* Bit 2: the limb is a pointer to some m_alloced data.*/ ++ mpi_limb_t *d; /* Array with the limbs */ ++}; ++ ++#define MPI_NULL NULL ++ ++#define mpi_get_nlimbs(a) ((a)->nlimbs) ++#define mpi_is_neg(a) ((a)->sign) ++ ++/*-- mpiutil.c --*/ ++ ++#ifdef M_DEBUG ++# define mpi_alloc(n) _gcry_mpi_debug_alloc((n), M_DBGINFO( __LINE__ ) ) ++# define mpi_alloc_secure(n) _gcry_mpi_debug_alloc_secure((n), M_DBGINFO( __LINE__ ) ) ++# define mpi_free(a) _gcry_mpi_debug_free((a), M_DBGINFO(__LINE__) ) ++# define mpi_resize(a,b) _gcry_mpi_debug_resize((a),(b), M_DBGINFO(__LINE__) ) ++# define mpi_copy(a) _gcry_mpi_debug_copy((a), M_DBGINFO(__LINE__) ) ++ gcry_mpi_t _gcry_mpi_debug_alloc( unsigned nlimbs, const char *info ); ++ gcry_mpi_t _gcry_mpi_debug_alloc_secure( unsigned nlimbs, const char *info ); ++ void _gcry_mpi_debug_free( gcry_mpi_t a, const char *info ); ++ void _gcry_mpi_debug_resize( gcry_mpi_t a, unsigned nlimbs, const char *info ); ++ gcry_mpi_t _gcry_mpi_debug_copy( gcry_mpi_t a, const char *info ); ++#else ++# define mpi_alloc(n) _gcry_mpi_alloc((n) ) ++# define mpi_alloc_secure(n) _gcry_mpi_alloc_secure((n) ) ++# define mpi_free(a) _gcry_mpi_free((a) ) ++# define mpi_resize(a,b) _gcry_mpi_resize((a),(b)) ++# define mpi_copy(a) gcry_mpi_copy((a)) ++ gcry_mpi_t _gcry_mpi_alloc( unsigned nlimbs ); ++ gcry_mpi_t _gcry_mpi_alloc_secure( unsigned nlimbs ); ++ void _gcry_mpi_free( gcry_mpi_t a ); ++ void _gcry_mpi_resize( gcry_mpi_t a, unsigned nlimbs ); ++ gcry_mpi_t _gcry_mpi_copy( gcry_mpi_t a ); ++#endif ++ ++#define mpi_is_opaque(a) ((a) && ((a)->flags&4)) ++#define mpi_is_secure(a) ((a) && ((a)->flags&1)) ++#define mpi_clear(a) _gcry_mpi_clear ((a)) ++#define mpi_alloc_like(a) _gcry_mpi_alloc_like((a)) ++#define mpi_set(a,b) gcry_mpi_set ((a),(b)) ++#define mpi_set_ui(a,b) gcry_mpi_set_ui ((a),(b)) ++#define mpi_get_ui(a,b) _gcry_mpi_get_ui ((a),(b)) ++#define mpi_alloc_set_ui(a) _gcry_mpi_alloc_set_ui ((a)) ++#define mpi_m_check(a) _gcry_mpi_m_check ((a)) ++#define mpi_swap(a,b) _gcry_mpi_swap ((a),(b)) ++#define mpi_new(n) gcry_mpi_new ((n)) ++#define mpi_snew(n) _gcry_mpi_snew ((n)) ++ ++void _gcry_mpi_clear( gcry_mpi_t a ); ++gcry_mpi_t _gcry_mpi_alloc_like( gcry_mpi_t a ); ++gcry_mpi_t _gcry_mpi_alloc_set_ui( unsigned long u); ++gcry_err_code_t _gcry_mpi_get_ui (gcry_mpi_t w, ulong *u); ++void _gcry_mpi_m_check( gcry_mpi_t a ); ++void _gcry_mpi_swap( gcry_mpi_t a, gcry_mpi_t b); ++gcry_mpi_t _gcry_mpi_new (unsigned int nbits); ++gcry_mpi_t _gcry_mpi_snew (unsigned int nbits); ++ ++/*-- mpicoder.c --*/ ++void _gcry_log_mpidump( const char *text, gcry_mpi_t a ); ++u32 _gcry_mpi_get_keyid( gcry_mpi_t a, u32 *keyid ); ++byte *_gcry_mpi_get_buffer( gcry_mpi_t a, unsigned *nbytes, int *sign ); ++byte *_gcry_mpi_get_secure_buffer( gcry_mpi_t a, unsigned *nbytes, int *sign ); ++void _gcry_mpi_set_buffer ( gcry_mpi_t a, const void *buffer, ++ unsigned int nbytes, int sign ); ++ ++#define log_mpidump _gcry_log_mpidump ++ ++/*-- mpi-add.c --*/ ++#define mpi_add_ui(w,u,v) gcry_mpi_add_ui((w),(u),(v)) ++#define mpi_add(w,u,v) gcry_mpi_add ((w),(u),(v)) ++#define mpi_addm(w,u,v,m) gcry_mpi_addm ((w),(u),(v),(m)) ++#define mpi_sub_ui(w,u,v) gcry_mpi_sub_ui ((w),(u),(v)) ++#define mpi_sub(w,u,v) gcry_mpi_sub ((w),(u),(v)) ++#define mpi_subm(w,u,v,m) gcry_mpi_subm ((w),(u),(v),(m)) ++ ++ ++/*-- mpi-mul.c --*/ ++#define mpi_mul_ui(w,u,v) gcry_mpi_mul_ui ((w),(u),(v)) ++#define mpi_mul_2exp(w,u,v) gcry_mpi_mul_2exp ((w),(u),(v)) ++#define mpi_mul(w,u,v) gcry_mpi_mul ((w),(u),(v)) ++#define mpi_mulm(w,u,v,m) gcry_mpi_mulm ((w),(u),(v),(m)) ++ ++ ++/*-- mpi-div.c --*/ ++#define mpi_fdiv_r_ui(a,b,c) _gcry_mpi_fdiv_r_ui((a),(b),(c)) ++#define mpi_fdiv_r(a,b,c) _gcry_mpi_fdiv_r((a),(b),(c)) ++#define mpi_fdiv_q(a,b,c) _gcry_mpi_fdiv_q((a),(b),(c)) ++#define mpi_fdiv_qr(a,b,c,d) _gcry_mpi_fdiv_qr((a),(b),(c),(d)) ++#define mpi_tdiv_r(a,b,c) _gcry_mpi_tdiv_r((a),(b),(c)) ++#define mpi_tdiv_qr(a,b,c,d) _gcry_mpi_tdiv_qr((a),(b),(c),(d)) ++#define mpi_tdiv_q_2exp(a,b,c) _gcry_mpi_tdiv_q_2exp((a),(b),(c)) ++#define mpi_divisible_ui(a,b) _gcry_mpi_divisible_ui((a),(b)) ++ ++ulong _gcry_mpi_fdiv_r_ui( gcry_mpi_t rem, gcry_mpi_t dividend, ulong divisor ); ++void _gcry_mpi_fdiv_r( gcry_mpi_t rem, gcry_mpi_t dividend, gcry_mpi_t divisor ); ++void _gcry_mpi_fdiv_q( gcry_mpi_t quot, gcry_mpi_t dividend, gcry_mpi_t divisor ); ++void _gcry_mpi_fdiv_qr( gcry_mpi_t quot, gcry_mpi_t rem, gcry_mpi_t dividend, gcry_mpi_t divisor ); ++void _gcry_mpi_tdiv_r( gcry_mpi_t rem, gcry_mpi_t num, gcry_mpi_t den); ++void _gcry_mpi_tdiv_qr( gcry_mpi_t quot, gcry_mpi_t rem, gcry_mpi_t num, gcry_mpi_t den); ++void _gcry_mpi_tdiv_q_2exp( gcry_mpi_t w, gcry_mpi_t u, unsigned count ); ++int _gcry_mpi_divisible_ui(gcry_mpi_t dividend, ulong divisor ); ++ ++ ++/*-- mpi-mod.c --*/ ++#define mpi_mod(r,a,m) _gcry_mpi_mod ((r), (a), (m)) ++#define mpi_barrett_init(m,f) _gcry_mpi_barrett_init ((m),(f)) ++#define mpi_barrett_free(c) _gcry_mpi_barrett_free ((c)) ++#define mpi_mod_barrett(r,a,c) _gcry_mpi_mod_barrett ((r), (a), (c)) ++#define mpi_mul_barrett(r,u,v,c) _gcry_mpi_mul_barrett ((r), (u), (v), (c)) ++ ++void _gcry_mpi_mod (gcry_mpi_t r, gcry_mpi_t dividend, gcry_mpi_t divisor); ++ ++/* Context used with Barrett reduction. */ ++struct barrett_ctx_s; ++typedef struct barrett_ctx_s *mpi_barrett_t; ++ ++mpi_barrett_t _gcry_mpi_barrett_init (gcry_mpi_t m, int copy); ++void _gcry_mpi_barrett_free (mpi_barrett_t ctx); ++void _gcry_mpi_mod_barrett (gcry_mpi_t r, gcry_mpi_t x, mpi_barrett_t ctx); ++void _gcry_mpi_mul_barrett (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, ++ mpi_barrett_t ctx); ++ ++ ++ ++/*-- mpi-gcd.c --*/ ++ ++/*-- mpi-mpow.c --*/ ++#define mpi_mulpowm(a,b,c,d) _gcry_mpi_mulpowm ((a),(b),(c),(d)) ++void _gcry_mpi_mulpowm( gcry_mpi_t res, gcry_mpi_t *basearray, gcry_mpi_t *exparray, gcry_mpi_t mod); ++ ++/*-- mpi-cmp.c --*/ ++#define mpi_cmp_ui(a,b) gcry_mpi_cmp_ui ((a),(b)) ++#define mpi_cmp(a,b) gcry_mpi_cmp ((a),(b)) ++int gcry_mpi_cmp_ui( gcry_mpi_t u, ulong v ); ++int gcry_mpi_cmp( gcry_mpi_t u, gcry_mpi_t v ); ++ ++/*-- mpi-scan.c --*/ ++#define mpi_trailing_zeros(a) _gcry_mpi_trailing_zeros ((a)) ++int _gcry_mpi_getbyte( gcry_mpi_t a, unsigned idx ); ++void _gcry_mpi_putbyte( gcry_mpi_t a, unsigned idx, int value ); ++unsigned _gcry_mpi_trailing_zeros( gcry_mpi_t a ); ++ ++/*-- mpi-bit.c --*/ ++#define mpi_normalize(a) _gcry_mpi_normalize ((a)) ++#define mpi_get_nbits(a) gcry_mpi_get_nbits ((a)) ++#define mpi_test_bit(a,b) gcry_mpi_test_bit ((a),(b)) ++#define mpi_set_bit(a,b) gcry_mpi_set_bit ((a),(b)) ++#define mpi_set_highbit(a,b) gcry_mpi_set_highbit ((a),(b)) ++#define mpi_clear_bit(a,b) gcry_mpi_clear_bit ((a),(b)) ++#define mpi_clear_highbit(a,b) gcry_mpi_clear_highbit ((a),(b)) ++#define mpi_rshift(a,b,c) gcry_mpi_rshift ((a),(b),(c)) ++#define mpi_lshift(a,b,c) gcry_mpi_lshift ((a),(b),(c)) ++ ++void _gcry_mpi_normalize( gcry_mpi_t a ); ++ ++/*-- mpi-inv.c --*/ ++#define mpi_invm(a,b,c) gcry_mpi_invm ((a),(b),(c)) ++ ++/*-- ec.c --*/ ++ ++/* Object to represent a point in projective coordinates. */ ++struct mpi_point_s; ++typedef struct mpi_point_s mpi_point_t; ++struct mpi_point_s ++{ ++ gcry_mpi_t x; ++ gcry_mpi_t y; ++ gcry_mpi_t z; ++}; ++ ++/* Context used with elliptic curve functions. */ ++struct mpi_ec_ctx_s; ++typedef struct mpi_ec_ctx_s *mpi_ec_t; ++ ++void _gcry_mpi_ec_point_init (mpi_point_t *p); ++void _gcry_mpi_ec_point_free (mpi_point_t *p); ++mpi_ec_t _gcry_mpi_ec_init (gcry_mpi_t p, gcry_mpi_t a); ++void _gcry_mpi_ec_free (mpi_ec_t ctx); ++int _gcry_mpi_ec_get_affine (gcry_mpi_t x, gcry_mpi_t y, mpi_point_t *point, ++ mpi_ec_t ctx); ++void _gcry_mpi_ec_dup_point (mpi_point_t *result, ++ mpi_point_t *point, mpi_ec_t ctx); ++void _gcry_mpi_ec_add_points (mpi_point_t *result, ++ mpi_point_t *p1, mpi_point_t *p2, ++ mpi_ec_t ctx); ++void _gcry_mpi_ec_mul_point (mpi_point_t *result, ++ gcry_mpi_t scalar, mpi_point_t *point, ++ mpi_ec_t ctx); ++ ++ ++ ++#endif /*G10_MPI_H*/ +diff --git a/grub-core/lib/libgcrypt/src/secmem.c b/grub-core/lib/libgcrypt/src/secmem.c +new file mode 100644 +index 0000000..2beb234 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/src/secmem.c +@@ -0,0 +1,696 @@ ++/* secmem.c - memory allocation from a secure heap ++ * Copyright (C) 1998, 1999, 2000, 2001, 2002, ++ * 2003, 2007 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser general Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, see . ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#if defined(HAVE_MLOCK) || defined(HAVE_MMAP) ++#include ++#include ++#include ++#ifdef USE_CAPABILITIES ++#include ++#endif ++#endif ++ ++#include "ath.h" ++#include "g10lib.h" ++#include "secmem.h" ++ ++#if defined (MAP_ANON) && ! defined (MAP_ANONYMOUS) ++#define MAP_ANONYMOUS MAP_ANON ++#endif ++ ++#define MINIMUM_POOL_SIZE 16384 ++#define STANDARD_POOL_SIZE 32768 ++#define DEFAULT_PAGE_SIZE 4096 ++ ++typedef struct memblock ++{ ++ unsigned size; /* Size of the memory available to the ++ user. */ ++ int flags; /* See below. */ ++ PROPERLY_ALIGNED_TYPE aligned; ++} memblock_t; ++ ++/* This flag specifies that the memory block is in use. */ ++#define MB_FLAG_ACTIVE (1 << 0) ++ ++/* The pool of secure memory. */ ++static void *pool; ++ ++/* Size of POOL in bytes. */ ++static size_t pool_size; ++ ++/* True, if the memory pool is ready for use. May be checked in an ++ atexit function. */ ++static volatile int pool_okay; ++ ++/* True, if the memory pool is mmapped. */ ++static volatile int pool_is_mmapped; ++ ++/* FIXME? */ ++static int disable_secmem; ++static int show_warning; ++static int not_locked; ++static int no_warning; ++static int suspend_warning; ++ ++/* Stats. */ ++static unsigned int cur_alloced, cur_blocks; ++ ++/* Lock protecting accesses to the memory pool. */ ++static ath_mutex_t secmem_lock; ++ ++/* Convenient macros. */ ++#define SECMEM_LOCK ath_mutex_lock (&secmem_lock) ++#define SECMEM_UNLOCK ath_mutex_unlock (&secmem_lock) ++ ++/* The size of the memblock structure; this does not include the ++ memory that is available to the user. */ ++#define BLOCK_HEAD_SIZE \ ++ offsetof (memblock_t, aligned) ++ ++/* Convert an address into the according memory block structure. */ ++#define ADDR_TO_BLOCK(addr) \ ++ (memblock_t *) ((char *) addr - BLOCK_HEAD_SIZE) ++ ++/* Check whether P points into the pool. */ ++static int ++ptr_into_pool_p (const void *p) ++{ ++ /* We need to convert pointers to addresses. This is required by ++ C-99 6.5.8 to avoid undefined behaviour. Using size_t is at ++ least only implementation defined. See also ++ http://lists.gnupg.org/pipermail/gcrypt-devel/2007-February/001102.html ++ */ ++ size_t p_addr = (size_t)p; ++ size_t pool_addr = (size_t)pool; ++ ++ return p_addr >= pool_addr && p_addr < pool_addr+pool_size; ++} ++ ++/* Update the stats. */ ++static void ++stats_update (size_t add, size_t sub) ++{ ++ if (add) ++ { ++ cur_alloced += add; ++ cur_blocks++; ++ } ++ if (sub) ++ { ++ cur_alloced -= sub; ++ cur_blocks--; ++ } ++} ++ ++/* Return the block following MB or NULL, if MB is the last block. */ ++static memblock_t * ++mb_get_next (memblock_t *mb) ++{ ++ memblock_t *mb_next; ++ ++ mb_next = (memblock_t *) ((char *) mb + BLOCK_HEAD_SIZE + mb->size); ++ ++ if (! ptr_into_pool_p (mb_next)) ++ mb_next = NULL; ++ ++ return mb_next; ++} ++ ++/* Return the block preceding MB or NULL, if MB is the first ++ block. */ ++static memblock_t * ++mb_get_prev (memblock_t *mb) ++{ ++ memblock_t *mb_prev, *mb_next; ++ ++ if (mb == pool) ++ mb_prev = NULL; ++ else ++ { ++ mb_prev = (memblock_t *) pool; ++ while (1) ++ { ++ mb_next = mb_get_next (mb_prev); ++ if (mb_next == mb) ++ break; ++ else ++ mb_prev = mb_next; ++ } ++ } ++ ++ return mb_prev; ++} ++ ++/* If the preceding block of MB and/or the following block of MB ++ exist and are not active, merge them to form a bigger block. */ ++static void ++mb_merge (memblock_t *mb) ++{ ++ memblock_t *mb_prev, *mb_next; ++ ++ mb_prev = mb_get_prev (mb); ++ mb_next = mb_get_next (mb); ++ ++ if (mb_prev && (! (mb_prev->flags & MB_FLAG_ACTIVE))) ++ { ++ mb_prev->size += BLOCK_HEAD_SIZE + mb->size; ++ mb = mb_prev; ++ } ++ if (mb_next && (! (mb_next->flags & MB_FLAG_ACTIVE))) ++ mb->size += BLOCK_HEAD_SIZE + mb_next->size; ++} ++ ++/* Return a new block, which can hold SIZE bytes. */ ++static memblock_t * ++mb_get_new (memblock_t *block, size_t size) ++{ ++ memblock_t *mb, *mb_split; ++ ++ for (mb = block; ptr_into_pool_p (mb); mb = mb_get_next (mb)) ++ if (! (mb->flags & MB_FLAG_ACTIVE) && mb->size >= size) ++ { ++ /* Found a free block. */ ++ mb->flags |= MB_FLAG_ACTIVE; ++ ++ if (mb->size - size > BLOCK_HEAD_SIZE) ++ { ++ /* Split block. */ ++ ++ mb_split = (memblock_t *) (((char *) mb) + BLOCK_HEAD_SIZE + size); ++ mb_split->size = mb->size - size - BLOCK_HEAD_SIZE; ++ mb_split->flags = 0; ++ ++ mb->size = size; ++ ++ mb_merge (mb_split); ++ ++ } ++ ++ break; ++ } ++ ++ if (! ptr_into_pool_p (mb)) ++ { ++ gpg_err_set_errno (ENOMEM); ++ mb = NULL; ++ } ++ ++ return mb; ++} ++ ++/* Print a warning message. */ ++static void ++print_warn (void) ++{ ++ if (!no_warning) ++ log_info (_("Warning: using insecure memory!\n")); ++} ++ ++/* Lock the memory pages into core and drop privileges. */ ++static void ++lock_pool (void *p, size_t n) ++{ ++#if defined(USE_CAPABILITIES) && defined(HAVE_MLOCK) ++ int err; ++ ++ cap_set_proc (cap_from_text ("cap_ipc_lock+ep")); ++ err = mlock (p, n); ++ if (err && errno) ++ err = errno; ++ cap_set_proc (cap_from_text ("cap_ipc_lock+p")); ++ ++ if (err) ++ { ++ if (errno != EPERM ++#ifdef EAGAIN /* OpenBSD returns this */ ++ && errno != EAGAIN ++#endif ++#ifdef ENOSYS /* Some SCOs return this (function not implemented) */ ++ && errno != ENOSYS ++#endif ++#ifdef ENOMEM /* Linux might return this. */ ++ && errno != ENOMEM ++#endif ++ ) ++ log_error ("can't lock memory: %s\n", strerror (err)); ++ show_warning = 1; ++ not_locked = 1; ++ } ++ ++#elif defined(HAVE_MLOCK) ++ uid_t uid; ++ int err; ++ ++ uid = getuid (); ++ ++#ifdef HAVE_BROKEN_MLOCK ++ /* Under HP/UX mlock segfaults if called by non-root. Note, we have ++ noch checked whether mlock does really work under AIX where we ++ also detected a broken nlock. Note further, that using plock () ++ is not a good idea under AIX. */ ++ if (uid) ++ { ++ errno = EPERM; ++ err = errno; ++ } ++ else ++ { ++ err = mlock (p, n); ++ if (err && errno) ++ err = errno; ++ } ++#else /* !HAVE_BROKEN_MLOCK */ ++ err = mlock (p, n); ++ if (err && errno) ++ err = errno; ++#endif /* !HAVE_BROKEN_MLOCK */ ++ ++ if (uid && ! geteuid ()) ++ { ++ /* check that we really dropped the privs. ++ * Note: setuid(0) should always fail */ ++ if (setuid (uid) || getuid () != geteuid () || !setuid (0)) ++ log_fatal ("failed to reset uid: %s\n", strerror (errno)); ++ } ++ ++ if (err) ++ { ++ if (errno != EPERM ++#ifdef EAGAIN /* OpenBSD returns this. */ ++ && errno != EAGAIN ++#endif ++#ifdef ENOSYS /* Some SCOs return this (function not implemented). */ ++ && errno != ENOSYS ++#endif ++#ifdef ENOMEM /* Linux might return this. */ ++ && errno != ENOMEM ++#endif ++ ) ++ log_error ("can't lock memory: %s\n", strerror (err)); ++ show_warning = 1; ++ not_locked = 1; ++ } ++ ++#elif defined ( __QNX__ ) ++ /* QNX does not page at all, so the whole secure memory stuff does ++ * not make much sense. However it is still of use because it ++ * wipes out the memory on a free(). ++ * Therefore it is sufficient to suppress the warning. */ ++ (void)p; ++ (void)n; ++#elif defined (HAVE_DOSISH_SYSTEM) || defined (__CYGWIN__) ++ /* It does not make sense to print such a warning, given the fact that ++ * this whole Windows !@#$% and their user base are inherently insecure. */ ++ (void)p; ++ (void)n; ++#elif defined (__riscos__) ++ /* No virtual memory on RISC OS, so no pages are swapped to disc, ++ * besides we don't have mmap, so we don't use it! ;-) ++ * But don't complain, as explained above. */ ++ (void)p; ++ (void)n; ++#else ++ (void)p; ++ (void)n; ++ log_info ("Please note that you don't have secure memory on this system\n"); ++#endif ++} ++ ++/* Initialize POOL. */ ++static void ++init_pool (size_t n) ++{ ++ size_t pgsize; ++ long int pgsize_val; ++ memblock_t *mb; ++ ++ pool_size = n; ++ ++ if (disable_secmem) ++ log_bug ("secure memory is disabled"); ++ ++#if defined(HAVE_SYSCONF) && defined(_SC_PAGESIZE) ++ pgsize_val = sysconf (_SC_PAGESIZE); ++#elif defined(HAVE_GETPAGESIZE) ++ pgsize_val = getpagesize (); ++#else ++ pgsize_val = -1; ++#endif ++ pgsize = (pgsize_val != -1 && pgsize_val > 0)? pgsize_val:DEFAULT_PAGE_SIZE; ++ ++ ++#if HAVE_MMAP ++ pool_size = (pool_size + pgsize - 1) & ~(pgsize - 1); ++#ifdef MAP_ANONYMOUS ++ pool = mmap (0, pool_size, PROT_READ | PROT_WRITE, ++ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); ++#else /* map /dev/zero instead */ ++ { ++ int fd; ++ ++ fd = open ("/dev/zero", O_RDWR); ++ if (fd == -1) ++ { ++ log_error ("can't open /dev/zero: %s\n", strerror (errno)); ++ pool = (void *) -1; ++ } ++ else ++ { ++ pool = mmap (0, pool_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); ++ close (fd); ++ } ++ } ++#endif ++ if (pool == (void *) -1) ++ log_info ("can't mmap pool of %u bytes: %s - using malloc\n", ++ (unsigned) pool_size, strerror (errno)); ++ else ++ { ++ pool_is_mmapped = 1; ++ pool_okay = 1; ++ } ++ ++#endif ++ if (!pool_okay) ++ { ++ pool = malloc (pool_size); ++ if (!pool) ++ log_fatal ("can't allocate memory pool of %u bytes\n", ++ (unsigned) pool_size); ++ else ++ pool_okay = 1; ++ } ++ ++ /* Initialize first memory block. */ ++ mb = (memblock_t *) pool; ++ mb->size = pool_size; ++ mb->flags = 0; ++} ++ ++void ++_gcry_secmem_set_flags (unsigned flags) ++{ ++ int was_susp; ++ ++ SECMEM_LOCK; ++ ++ was_susp = suspend_warning; ++ no_warning = flags & GCRY_SECMEM_FLAG_NO_WARNING; ++ suspend_warning = flags & GCRY_SECMEM_FLAG_SUSPEND_WARNING; ++ ++ /* and now issue the warning if it is not longer suspended */ ++ if (was_susp && !suspend_warning && show_warning) ++ { ++ show_warning = 0; ++ print_warn (); ++ } ++ ++ SECMEM_UNLOCK; ++} ++ ++unsigned int ++_gcry_secmem_get_flags (void) ++{ ++ unsigned flags; ++ ++ SECMEM_LOCK; ++ ++ flags = no_warning ? GCRY_SECMEM_FLAG_NO_WARNING : 0; ++ flags |= suspend_warning ? GCRY_SECMEM_FLAG_SUSPEND_WARNING : 0; ++ flags |= not_locked ? GCRY_SECMEM_FLAG_NOT_LOCKED : 0; ++ ++ SECMEM_UNLOCK; ++ ++ return flags; ++} ++ ++ ++/* See _gcry_secmem_init. This function is expected to be called with ++ the secmem lock held. */ ++static void ++secmem_init (size_t n) ++{ ++ if (!n) ++ { ++#ifdef USE_CAPABILITIES ++ /* drop all capabilities */ ++ cap_set_proc (cap_from_text ("all-eip")); ++ ++#elif !defined(HAVE_DOSISH_SYSTEM) ++ uid_t uid; ++ ++ disable_secmem = 1; ++ uid = getuid (); ++ if (uid != geteuid ()) ++ { ++ if (setuid (uid) || getuid () != geteuid () || !setuid (0)) ++ log_fatal ("failed to drop setuid\n"); ++ } ++#endif ++ } ++ else ++ { ++ if (n < MINIMUM_POOL_SIZE) ++ n = MINIMUM_POOL_SIZE; ++ if (! pool_okay) ++ { ++ init_pool (n); ++ lock_pool (pool, n); ++ } ++ else ++ log_error ("Oops, secure memory pool already initialized\n"); ++ } ++} ++ ++ ++ ++/* Initialize the secure memory system. If running with the necessary ++ privileges, the secure memory pool will be locked into the core in ++ order to prevent page-outs of the data. Furthermore allocated ++ secure memory will be wiped out when released. */ ++void ++_gcry_secmem_init (size_t n) ++{ ++ SECMEM_LOCK; ++ ++ secmem_init (n); ++ ++ SECMEM_UNLOCK; ++} ++ ++ ++static void * ++_gcry_secmem_malloc_internal (size_t size) ++{ ++ memblock_t *mb; ++ ++ if (!pool_okay) ++ { ++ /* Try to initialize the pool if the user forgot about it. */ ++ secmem_init (STANDARD_POOL_SIZE); ++ if (!pool_okay) ++ { ++ log_info (_("operation is not possible without " ++ "initialized secure memory\n")); ++ gpg_err_set_errno (ENOMEM); ++ return NULL; ++ } ++ } ++ if (not_locked && fips_mode ()) ++ { ++ log_info (_("secure memory pool is not locked while in FIPS mode\n")); ++ gpg_err_set_errno (ENOMEM); ++ return NULL; ++ } ++ if (show_warning && !suspend_warning) ++ { ++ show_warning = 0; ++ print_warn (); ++ } ++ ++ /* Blocks are always a multiple of 32. */ ++ size = ((size + 31) / 32) * 32; ++ ++ mb = mb_get_new ((memblock_t *) pool, size); ++ if (mb) ++ stats_update (size, 0); ++ ++ return mb ? &mb->aligned.c : NULL; ++} ++ ++void * ++_gcry_secmem_malloc (size_t size) ++{ ++ void *p; ++ ++ SECMEM_LOCK; ++ p = _gcry_secmem_malloc_internal (size); ++ SECMEM_UNLOCK; ++ ++ return p; ++} ++ ++static void ++_gcry_secmem_free_internal (void *a) ++{ ++ memblock_t *mb; ++ int size; ++ ++ if (!a) ++ return; ++ ++ mb = ADDR_TO_BLOCK (a); ++ size = mb->size; ++ ++ /* This does not make much sense: probably this memory is held in the ++ * cache. We do it anyway: */ ++#define MB_WIPE_OUT(byte) \ ++ wipememory2 ((memblock_t *) ((char *) mb + BLOCK_HEAD_SIZE), (byte), size); ++ ++ MB_WIPE_OUT (0xff); ++ MB_WIPE_OUT (0xaa); ++ MB_WIPE_OUT (0x55); ++ MB_WIPE_OUT (0x00); ++ ++ stats_update (0, size); ++ ++ mb->flags &= ~MB_FLAG_ACTIVE; ++ ++ /* Update stats. */ ++ ++ mb_merge (mb); ++} ++ ++/* Wipe out and release memory. */ ++void ++_gcry_secmem_free (void *a) ++{ ++ SECMEM_LOCK; ++ _gcry_secmem_free_internal (a); ++ SECMEM_UNLOCK; ++} ++ ++/* Realloc memory. */ ++void * ++_gcry_secmem_realloc (void *p, size_t newsize) ++{ ++ memblock_t *mb; ++ size_t size; ++ void *a; ++ ++ SECMEM_LOCK; ++ ++ mb = (memblock_t *) ((char *) p - ((size_t) &((memblock_t *) 0)->aligned.c)); ++ size = mb->size; ++ if (newsize < size) ++ { ++ /* It is easier to not shrink the memory. */ ++ a = p; ++ } ++ else ++ { ++ a = _gcry_secmem_malloc_internal (newsize); ++ if (a) ++ { ++ memcpy (a, p, size); ++ memset ((char *) a + size, 0, newsize - size); ++ _gcry_secmem_free_internal (p); ++ } ++ } ++ ++ SECMEM_UNLOCK; ++ ++ return a; ++} ++ ++ ++/* Return true if P points into the secure memory area. */ ++int ++_gcry_private_is_secure (const void *p) ++{ ++ return pool_okay && ptr_into_pool_p (p); ++} ++ ++ ++/**************** ++ * Warning: This code might be called by an interrupt handler ++ * and frankly, there should really be such a handler, ++ * to make sure that the memory is wiped out. ++ * We hope that the OS wipes out mlocked memory after ++ * receiving a SIGKILL - it really should do so, otherwise ++ * there is no chance to get the secure memory cleaned. ++ */ ++void ++_gcry_secmem_term () ++{ ++ if (!pool_okay) ++ return; ++ ++ wipememory2 (pool, 0xff, pool_size); ++ wipememory2 (pool, 0xaa, pool_size); ++ wipememory2 (pool, 0x55, pool_size); ++ wipememory2 (pool, 0x00, pool_size); ++#if HAVE_MMAP ++ if (pool_is_mmapped) ++ munmap (pool, pool_size); ++#endif ++ pool = NULL; ++ pool_okay = 0; ++ pool_size = 0; ++ not_locked = 0; ++} ++ ++ ++void ++_gcry_secmem_dump_stats () ++{ ++#if 1 ++ SECMEM_LOCK; ++ ++ if (pool_okay) ++ log_info ("secmem usage: %u/%lu bytes in %u blocks\n", ++ cur_alloced, (unsigned long)pool_size, cur_blocks); ++ SECMEM_UNLOCK; ++#else ++ memblock_t *mb; ++ int i; ++ ++ SECMEM_LOCK; ++ ++ for (i = 0, mb = (memblock_t *) pool; ++ ptr_into_pool_p (mb); ++ mb = mb_get_next (mb), i++) ++ log_info ("SECMEM: [%s] block: %i; size: %i\n", ++ (mb->flags & MB_FLAG_ACTIVE) ? "used" : "free", ++ i, ++ mb->size); ++ SECMEM_UNLOCK; ++#endif ++} +diff --git a/grub-core/lib/libgcrypt/src/secmem.h b/grub-core/lib/libgcrypt/src/secmem.h +new file mode 100644 +index 0000000..29e151a +--- /dev/null ++++ b/grub-core/lib/libgcrypt/src/secmem.h +@@ -0,0 +1,39 @@ ++/* secmem.h - internal definitions for secmem ++ * Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser general Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ */ ++ ++#ifndef G10_SECMEM_H ++#define G10_SECMEM_H 1 ++ ++void _gcry_secmem_init (size_t npool); ++void _gcry_secmem_term (void); ++void *_gcry_secmem_malloc (size_t size) _GCRY_GCC_ATTR_MALLOC; ++void *_gcry_secmem_realloc (void *a, size_t newsize); ++void _gcry_secmem_free (void *a); ++void _gcry_secmem_dump_stats (void); ++void _gcry_secmem_set_flags (unsigned flags); ++unsigned _gcry_secmem_get_flags(void); ++int _gcry_private_is_secure (const void *p); ++ ++/* Flags for _gcry_secmem_{set,get}_flags. */ ++#define GCRY_SECMEM_FLAG_NO_WARNING (1 << 0) ++#define GCRY_SECMEM_FLAG_SUSPEND_WARNING (1 << 1) ++#define GCRY_SECMEM_FLAG_NOT_LOCKED (1 << 2) ++ ++#endif /* G10_SECMEM_H */ +diff --git a/grub-core/lib/libgcrypt/src/sexp.c b/grub-core/lib/libgcrypt/src/sexp.c +new file mode 100644 +index 0000000..0877773 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/src/sexp.c +@@ -0,0 +1,2033 @@ ++/* sexp.c - S-Expression handling ++ * Copyright (C) 1999, 2000, 2001, 2002, 2003, ++ * 2004, 2006, 2007, 2008, 2011 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser general Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ */ ++ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define GCRYPT_NO_MPI_MACROS 1 ++#include "g10lib.h" ++ ++typedef struct gcry_sexp *NODE; ++typedef unsigned short DATALEN; ++ ++struct gcry_sexp ++{ ++ byte d[1]; ++}; ++ ++#define ST_STOP 0 ++#define ST_DATA 1 /* datalen follows */ ++#define ST_HINT 2 /* datalen follows */ ++#define ST_OPEN 3 ++#define ST_CLOSE 4 ++ ++/* the atoi macros assume that the buffer has only valid digits */ ++#define atoi_1(p) (*(p) - '0' ) ++#define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \ ++ *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10)) ++#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1)) ++ ++#define TOKEN_SPECIALS "-./_:*+=" ++ ++static gcry_error_t ++vsexp_sscan (gcry_sexp_t *retsexp, size_t *erroff, ++ const char *buffer, size_t length, int argflag, ++ void **arg_list, va_list arg_ptr); ++ ++static gcry_error_t ++sexp_sscan (gcry_sexp_t *retsexp, size_t *erroff, ++ const char *buffer, size_t length, int argflag, ++ void **arg_list, ...); ++ ++/* Return true if P points to a byte containing a whitespace according ++ to the S-expressions definition. */ ++#undef whitespacep ++static GPG_ERR_INLINE int ++whitespacep (const char *p) ++{ ++ switch (*p) ++ { ++ case ' ': case '\t': case '\v': case '\f': case '\r': case '\n': return 1; ++ default: return 0; ++ } ++} ++ ++ ++#if 0 ++static void ++dump_mpi( gcry_mpi_t a ) ++{ ++ char buffer[1000]; ++ size_t n = 1000; ++ ++ if( !a ) ++ fputs("[no MPI]", stderr ); ++ else if( gcry_mpi_print( GCRYMPI_FMT_HEX, buffer, &n, a ) ) ++ fputs("[MPI too large to print]", stderr ); ++ else ++ fputs( buffer, stderr ); ++} ++#endif ++ ++static void ++dump_string (const byte *p, size_t n, int delim ) ++{ ++ for (; n; n--, p++ ) ++ { ++ if ((*p & 0x80) || iscntrl( *p ) || *p == delim ) ++ { ++ if( *p == '\n' ) ++ log_printf ("\\n"); ++ else if( *p == '\r' ) ++ log_printf ("\\r"); ++ else if( *p == '\f' ) ++ log_printf ("\\f"); ++ else if( *p == '\v' ) ++ log_printf ("\\v"); ++ else if( *p == '\b' ) ++ log_printf ("\\b"); ++ else if( !*p ) ++ log_printf ("\\0"); ++ else ++ log_printf ("\\x%02x", *p ); ++ } ++ else ++ log_printf ("%c", *p); ++ } ++} ++ ++ ++void ++gcry_sexp_dump (const gcry_sexp_t a) ++{ ++ const byte *p; ++ int indent = 0; ++ int type; ++ ++ if (!a) ++ { ++ log_printf ( "[nil]\n"); ++ return; ++ } ++ ++ p = a->d; ++ while ( (type = *p) != ST_STOP ) ++ { ++ p++; ++ switch ( type ) ++ { ++ case ST_OPEN: ++ log_printf ("%*s[open]\n", 2*indent, ""); ++ indent++; ++ break; ++ case ST_CLOSE: ++ if( indent ) ++ indent--; ++ log_printf ("%*s[close]\n", 2*indent, ""); ++ break; ++ case ST_DATA: { ++ DATALEN n; ++ memcpy ( &n, p, sizeof n ); ++ p += sizeof n; ++ log_printf ("%*s[data=\"", 2*indent, "" ); ++ dump_string (p, n, '\"' ); ++ log_printf ("\"]\n"); ++ p += n; ++ } ++ break; ++ default: ++ log_printf ("%*s[unknown tag %d]\n", 2*indent, "", type); ++ break; ++ } ++ } ++} ++ ++/**************** ++ * Pass list through except when it is an empty list - in that case ++ * return NULL and release the passed list. ++ */ ++static gcry_sexp_t ++normalize ( gcry_sexp_t list ) ++{ ++ unsigned char *p; ++ ++ if ( !list ) ++ return NULL; ++ p = list->d; ++ if ( *p == ST_STOP ) ++ { ++ /* this is "" */ ++ gcry_sexp_release ( list ); ++ return NULL; ++ } ++ if ( *p == ST_OPEN && p[1] == ST_CLOSE ) ++ { ++ /* this is "()" */ ++ gcry_sexp_release ( list ); ++ return NULL; ++ } ++ ++ return list; ++} ++ ++/* Create a new S-expression object by reading LENGTH bytes from ++ BUFFER, assuming it is canonical encoded or autodetected encoding ++ when AUTODETECT is set to 1. With FREEFNC not NULL, ownership of ++ the buffer is transferred to the newly created object. FREEFNC ++ should be the freefnc used to release BUFFER; there is no guarantee ++ at which point this function is called; most likey you want to use ++ free() or gcry_free(). ++ ++ Passing LENGTH and AUTODETECT as 0 is allowed to indicate that ++ BUFFER points to a valid canonical encoded S-expression. A LENGTH ++ of 0 and AUTODETECT 1 indicates that buffer points to a ++ null-terminated string. ++ ++ This function returns 0 and and the pointer to the new object in ++ RETSEXP or an error code in which case RETSEXP is set to NULL. */ ++gcry_error_t ++gcry_sexp_create (gcry_sexp_t *retsexp, void *buffer, size_t length, ++ int autodetect, void (*freefnc)(void*) ) ++{ ++ gcry_error_t errcode; ++ gcry_sexp_t se; ++ ++ if (!retsexp) ++ return gcry_error (GPG_ERR_INV_ARG); ++ *retsexp = NULL; ++ if (autodetect < 0 || autodetect > 1 || !buffer) ++ return gcry_error (GPG_ERR_INV_ARG); ++ ++ if (!length && !autodetect) ++ { /* What a brave caller to assume that there is really a canonical ++ encoded S-expression in buffer */ ++ length = gcry_sexp_canon_len (buffer, 0, NULL, &errcode); ++ if (!length) ++ return errcode; ++ } ++ else if (!length && autodetect) ++ { /* buffer is a string */ ++ length = strlen ((char *)buffer); ++ } ++ ++ errcode = sexp_sscan (&se, NULL, buffer, length, 0, NULL); ++ if (errcode) ++ return errcode; ++ ++ *retsexp = se; ++ if (freefnc) ++ { ++ /* For now we release the buffer immediately. As soon as we ++ have changed the internal represenation of S-expression to ++ the canoncial format - which has the advantage of faster ++ parsing - we will use this function as a closure in our ++ GCRYSEXP object and use the BUFFER directly. */ ++ freefnc (buffer); ++ } ++ return gcry_error (GPG_ERR_NO_ERROR); ++} ++ ++/* Same as gcry_sexp_create but don't transfer ownership */ ++gcry_error_t ++gcry_sexp_new (gcry_sexp_t *retsexp, const void *buffer, size_t length, ++ int autodetect) ++{ ++ return gcry_sexp_create (retsexp, (void *)buffer, length, autodetect, NULL); ++} ++ ++ ++/**************** ++ * Release resource of the given SEXP object. ++ */ ++void ++gcry_sexp_release( gcry_sexp_t sexp ) ++{ ++ if (sexp) ++ { ++ if (gcry_is_secure (sexp)) ++ { ++ /* Extra paranoid wiping. */ ++ const byte *p = sexp->d; ++ int type; ++ ++ while ( (type = *p) != ST_STOP ) ++ { ++ p++; ++ switch ( type ) ++ { ++ case ST_OPEN: ++ break; ++ case ST_CLOSE: ++ break; ++ case ST_DATA: ++ { ++ DATALEN n; ++ memcpy ( &n, p, sizeof n ); ++ p += sizeof n; ++ p += n; ++ } ++ break; ++ default: ++ break; ++ } ++ } ++ wipememory (sexp->d, p - sexp->d); ++ } ++ gcry_free ( sexp ); ++ } ++} ++ ++ ++/**************** ++ * Make a pair from lists a and b, don't use a or b later on. ++ * Special behaviour: If one is a single element list we put the ++ * element straight into the new pair. ++ */ ++gcry_sexp_t ++gcry_sexp_cons( const gcry_sexp_t a, const gcry_sexp_t b ) ++{ ++ (void)a; ++ (void)b; ++ ++ /* NYI: Implementation should be quite easy with our new data ++ representation */ ++ BUG (); ++ return NULL; ++} ++ ++ ++/**************** ++ * Make a list from all items in the array the end of the array is marked ++ * with a NULL. ++ */ ++gcry_sexp_t ++gcry_sexp_alist( const gcry_sexp_t *array ) ++{ ++ (void)array; ++ ++ /* NYI: Implementation should be quite easy with our new data ++ representation. */ ++ BUG (); ++ return NULL; ++} ++ ++/**************** ++ * Make a list from all items, the end of list is indicated by a NULL ++ */ ++gcry_sexp_t ++gcry_sexp_vlist( const gcry_sexp_t a, ... ) ++{ ++ (void)a; ++ /* NYI: Implementation should be quite easy with our new data ++ representation. */ ++ BUG (); ++ return NULL; ++} ++ ++ ++/**************** ++ * Append n to the list a ++ * Returns: a new ist (which maybe a) ++ */ ++gcry_sexp_t ++gcry_sexp_append( const gcry_sexp_t a, const gcry_sexp_t n ) ++{ ++ (void)a; ++ (void)n; ++ /* NYI: Implementation should be quite easy with our new data ++ representation. */ ++ BUG (); ++ return NULL; ++} ++ ++gcry_sexp_t ++gcry_sexp_prepend( const gcry_sexp_t a, const gcry_sexp_t n ) ++{ ++ (void)a; ++ (void)n; ++ /* NYI: Implementation should be quite easy with our new data ++ representation. */ ++ BUG (); ++ return NULL; ++} ++ ++ ++ ++/**************** ++ * Locate token in a list. The token must be the car of a sublist. ++ * Returns: A new list with this sublist or NULL if not found. ++ */ ++gcry_sexp_t ++gcry_sexp_find_token( const gcry_sexp_t list, const char *tok, size_t toklen ) ++{ ++ const byte *p; ++ DATALEN n; ++ ++ if ( !list ) ++ return NULL; ++ ++ if ( !toklen ) ++ toklen = strlen(tok); ++ ++ p = list->d; ++ while ( *p != ST_STOP ) ++ { ++ if ( *p == ST_OPEN && p[1] == ST_DATA ) ++ { ++ const byte *head = p; ++ ++ p += 2; ++ memcpy ( &n, p, sizeof n ); ++ p += sizeof n; ++ if ( n == toklen && !memcmp( p, tok, toklen ) ) ++ { /* found it */ ++ gcry_sexp_t newlist; ++ byte *d; ++ int level = 1; ++ ++ /* Look for the end of the list. */ ++ for ( p += n; level; p++ ) ++ { ++ if ( *p == ST_DATA ) ++ { ++ memcpy ( &n, ++p, sizeof n ); ++ p += sizeof n + n; ++ p--; /* Compensate for later increment. */ ++ } ++ else if ( *p == ST_OPEN ) ++ { ++ level++; ++ } ++ else if ( *p == ST_CLOSE ) ++ { ++ level--; ++ } ++ else if ( *p == ST_STOP ) ++ { ++ BUG (); ++ } ++ } ++ n = p - head; ++ ++ newlist = gcry_malloc ( sizeof *newlist + n ); ++ if (!newlist) ++ { ++ /* No way to return an error code, so we can only ++ return Not Found. */ ++ return NULL; ++ } ++ d = newlist->d; ++ memcpy ( d, head, n ); d += n; ++ *d++ = ST_STOP; ++ return normalize ( newlist ); ++ } ++ p += n; ++ } ++ else if ( *p == ST_DATA ) ++ { ++ memcpy ( &n, ++p, sizeof n ); p += sizeof n; ++ p += n; ++ } ++ else ++ p++; ++ } ++ return NULL; ++} ++ ++/**************** ++ * Return the length of the given list ++ */ ++int ++gcry_sexp_length( const gcry_sexp_t list ) ++{ ++ const byte *p; ++ DATALEN n; ++ int type; ++ int length = 0; ++ int level = 0; ++ ++ if ( !list ) ++ return 0; ++ ++ p = list->d; ++ while ( (type=*p) != ST_STOP ) { ++ p++; ++ if ( type == ST_DATA ) { ++ memcpy ( &n, p, sizeof n ); ++ p += sizeof n + n; ++ if ( level == 1 ) ++ length++; ++ } ++ else if ( type == ST_OPEN ) { ++ if ( level == 1 ) ++ length++; ++ level++; ++ } ++ else if ( type == ST_CLOSE ) { ++ level--; ++ } ++ } ++ return length; ++} ++ ++ ++/* Return the internal lengths offset of LIST. That is the size of ++ the buffer from the first ST_OPEN, which is retruned at R_OFF, to ++ the corresponding ST_CLOSE inclusive. */ ++static size_t ++get_internal_buffer (const gcry_sexp_t list, size_t *r_off) ++{ ++ const unsigned char *p; ++ DATALEN n; ++ int type; ++ int level = 0; ++ ++ *r_off = 0; ++ if (list) ++ { ++ p = list->d; ++ while ( (type=*p) != ST_STOP ) ++ { ++ p++; ++ if (type == ST_DATA) ++ { ++ memcpy (&n, p, sizeof n); ++ p += sizeof n + n; ++ } ++ else if (type == ST_OPEN) ++ { ++ if (!level) ++ *r_off = (p-1) - list->d; ++ level++; ++ } ++ else if ( type == ST_CLOSE ) ++ { ++ level--; ++ if (!level) ++ return p - list->d; ++ } ++ } ++ } ++ return 0; /* Not a proper list. */ ++} ++ ++ ++ ++/* Extract the CAR of the given list. May return NULL for bad lists ++ or memory failure. */ ++gcry_sexp_t ++gcry_sexp_nth( const gcry_sexp_t list, int number ) ++{ ++ const byte *p; ++ DATALEN n; ++ gcry_sexp_t newlist; ++ byte *d; ++ int level = 0; ++ ++ if ( !list || list->d[0] != ST_OPEN ) ++ return NULL; ++ p = list->d; ++ ++ while ( number > 0 ) { ++ p++; ++ if ( *p == ST_DATA ) { ++ memcpy ( &n, ++p, sizeof n ); ++ p += sizeof n + n; ++ p--; ++ if ( !level ) ++ number--; ++ } ++ else if ( *p == ST_OPEN ) { ++ level++; ++ } ++ else if ( *p == ST_CLOSE ) { ++ level--; ++ if ( !level ) ++ number--; ++ } ++ else if ( *p == ST_STOP ) { ++ return NULL; ++ } ++ } ++ p++; ++ ++ if ( *p == ST_DATA ) { ++ memcpy ( &n, p, sizeof n ); p += sizeof n; ++ newlist = gcry_malloc ( sizeof *newlist + n + 1 ); ++ if (!newlist) ++ return NULL; ++ d = newlist->d; ++ memcpy ( d, p, n ); d += n; ++ *d++ = ST_STOP; ++ } ++ else if ( *p == ST_OPEN ) { ++ const byte *head = p; ++ ++ level = 1; ++ do { ++ p++; ++ if ( *p == ST_DATA ) { ++ memcpy ( &n, ++p, sizeof n ); ++ p += sizeof n + n; ++ p--; ++ } ++ else if ( *p == ST_OPEN ) { ++ level++; ++ } ++ else if ( *p == ST_CLOSE ) { ++ level--; ++ } ++ else if ( *p == ST_STOP ) { ++ BUG (); ++ } ++ } while ( level ); ++ n = p + 1 - head; ++ ++ newlist = gcry_malloc ( sizeof *newlist + n ); ++ if (!newlist) ++ return NULL; ++ d = newlist->d; ++ memcpy ( d, head, n ); d += n; ++ *d++ = ST_STOP; ++ } ++ else ++ newlist = NULL; ++ ++ return normalize (newlist); ++} ++ ++gcry_sexp_t ++gcry_sexp_car( const gcry_sexp_t list ) ++{ ++ return gcry_sexp_nth ( list, 0 ); ++} ++ ++ ++/* Helper to get data from the car. The returned value is valid as ++ long as the list is not modified. */ ++static const char * ++sexp_nth_data (const gcry_sexp_t list, int number, size_t *datalen) ++{ ++ const byte *p; ++ DATALEN n; ++ int level = 0; ++ ++ *datalen = 0; ++ if ( !list ) ++ return NULL; ++ ++ p = list->d; ++ if ( *p == ST_OPEN ) ++ p++; /* Yep, a list. */ ++ else if (number) ++ return NULL; /* Not a list but N > 0 requested. */ ++ ++ /* Skip over N elements. */ ++ while ( number > 0 ) ++ { ++ if ( *p == ST_DATA ) ++ { ++ memcpy ( &n, ++p, sizeof n ); ++ p += sizeof n + n; ++ p--; ++ if ( !level ) ++ number--; ++ } ++ else if ( *p == ST_OPEN ) ++ { ++ level++; ++ } ++ else if ( *p == ST_CLOSE ) ++ { ++ level--; ++ if ( !level ) ++ number--; ++ } ++ else if ( *p == ST_STOP ) ++ { ++ return NULL; ++ } ++ p++; ++ } ++ ++ /* If this is data, return it. */ ++ if ( *p == ST_DATA ) ++ { ++ memcpy ( &n, ++p, sizeof n ); ++ *datalen = n; ++ return (const char*)p + sizeof n; ++ } ++ ++ return NULL; ++} ++ ++ ++/* Get data from the car. The returned value is valid as long as the ++ list is not modified. */ ++const char * ++gcry_sexp_nth_data (const gcry_sexp_t list, int number, size_t *datalen ) ++{ ++ return sexp_nth_data (list, number, datalen); ++} ++ ++ ++/* Get a string from the car. The returned value is a malloced string ++ and needs to be freed by the caller. */ ++char * ++gcry_sexp_nth_string (const gcry_sexp_t list, int number) ++{ ++ const char *s; ++ size_t n; ++ char *buf; ++ ++ s = sexp_nth_data (list, number, &n); ++ if (!s || n < 1 || (n+1) < 1) ++ return NULL; ++ buf = gcry_malloc (n+1); ++ if (!buf) ++ return NULL; ++ memcpy (buf, s, n); ++ buf[n] = 0; ++ return buf; ++} ++ ++/* ++ * Get a MPI from the car ++ */ ++gcry_mpi_t ++gcry_sexp_nth_mpi( gcry_sexp_t list, int number, int mpifmt ) ++{ ++ const char *s; ++ size_t n; ++ gcry_mpi_t a; ++ ++ if ( !mpifmt ) ++ mpifmt = GCRYMPI_FMT_STD; ++ ++ s = sexp_nth_data (list, number, &n); ++ if (!s) ++ return NULL; ++ ++ if ( gcry_mpi_scan ( &a, mpifmt, s, n, NULL ) ) ++ return NULL; ++ ++ return a; ++} ++ ++ ++/**************** ++ * Get the CDR ++ */ ++gcry_sexp_t ++gcry_sexp_cdr( const gcry_sexp_t list ) ++{ ++ const byte *p; ++ const byte *head; ++ DATALEN n; ++ gcry_sexp_t newlist; ++ byte *d; ++ int level = 0; ++ int skip = 1; ++ ++ if ( !list || list->d[0] != ST_OPEN ) ++ return NULL; ++ p = list->d; ++ ++ while ( skip > 0 ) { ++ p++; ++ if ( *p == ST_DATA ) { ++ memcpy ( &n, ++p, sizeof n ); ++ p += sizeof n + n; ++ p--; ++ if ( !level ) ++ skip--; ++ } ++ else if ( *p == ST_OPEN ) { ++ level++; ++ } ++ else if ( *p == ST_CLOSE ) { ++ level--; ++ if ( !level ) ++ skip--; ++ } ++ else if ( *p == ST_STOP ) { ++ return NULL; ++ } ++ } ++ p++; ++ ++ head = p; ++ level = 0; ++ do { ++ if ( *p == ST_DATA ) { ++ memcpy ( &n, ++p, sizeof n ); ++ p += sizeof n + n; ++ p--; ++ } ++ else if ( *p == ST_OPEN ) { ++ level++; ++ } ++ else if ( *p == ST_CLOSE ) { ++ level--; ++ } ++ else if ( *p == ST_STOP ) { ++ return NULL; ++ } ++ p++; ++ } while ( level ); ++ n = p - head; ++ ++ newlist = gcry_malloc ( sizeof *newlist + n + 2 ); ++ if (!newlist) ++ return NULL; ++ d = newlist->d; ++ *d++ = ST_OPEN; ++ memcpy ( d, head, n ); d += n; ++ *d++ = ST_CLOSE; ++ *d++ = ST_STOP; ++ ++ return normalize (newlist); ++} ++ ++gcry_sexp_t ++gcry_sexp_cadr ( const gcry_sexp_t list ) ++{ ++ gcry_sexp_t a, b; ++ ++ a = gcry_sexp_cdr ( list ); ++ b = gcry_sexp_car ( a ); ++ gcry_sexp_release ( a ); ++ return b; ++} ++ ++ ++ ++static int ++hextobyte( const byte *s ) ++{ ++ int c=0; ++ ++ if( *s >= '0' && *s <= '9' ) ++ c = 16 * (*s - '0'); ++ else if( *s >= 'A' && *s <= 'F' ) ++ c = 16 * (10 + *s - 'A'); ++ else if( *s >= 'a' && *s <= 'f' ) { ++ c = 16 * (10 + *s - 'a'); ++ } ++ s++; ++ if( *s >= '0' && *s <= '9' ) ++ c += *s - '0'; ++ else if( *s >= 'A' && *s <= 'F' ) ++ c += 10 + *s - 'A'; ++ else if( *s >= 'a' && *s <= 'f' ) { ++ c += 10 + *s - 'a'; ++ } ++ return c; ++} ++ ++struct make_space_ctx { ++ gcry_sexp_t sexp; ++ size_t allocated; ++ byte *pos; ++}; ++ ++static gpg_err_code_t ++make_space ( struct make_space_ctx *c, size_t n ) ++{ ++ size_t used = c->pos - c->sexp->d; ++ ++ if ( used + n + sizeof(DATALEN) + 1 >= c->allocated ) ++ { ++ gcry_sexp_t newsexp; ++ byte *newhead; ++ size_t newsize; ++ ++ newsize = c->allocated + 2*(n+sizeof(DATALEN)+1); ++ if (newsize <= c->allocated) ++ return GPG_ERR_TOO_LARGE; ++ newsexp = gcry_realloc ( c->sexp, sizeof *newsexp + newsize - 1); ++ if (!newsexp) ++ return gpg_err_code_from_errno (errno); ++ c->allocated = newsize; ++ newhead = newsexp->d; ++ c->pos = newhead + used; ++ c->sexp = newsexp; ++ } ++ return 0; ++} ++ ++ ++/* Unquote STRING of LENGTH and store it into BUF. The surrounding ++ quotes are must already be removed from STRING. We assume that the ++ quoted string is syntacillay correct. */ ++static size_t ++unquote_string (const char *string, size_t length, unsigned char *buf) ++{ ++ int esc = 0; ++ const unsigned char *s = (const unsigned char*)string; ++ unsigned char *d = buf; ++ size_t n = length; ++ ++ for (; n; n--, s++) ++ { ++ if (esc) ++ { ++ switch (*s) ++ { ++ case 'b': *d++ = '\b'; break; ++ case 't': *d++ = '\t'; break; ++ case 'v': *d++ = '\v'; break; ++ case 'n': *d++ = '\n'; break; ++ case 'f': *d++ = '\f'; break; ++ case 'r': *d++ = '\r'; break; ++ case '"': *d++ = '\"'; break; ++ case '\'': *d++ = '\''; break; ++ case '\\': *d++ = '\\'; break; ++ ++ case '\r': /* ignore CR[,LF] */ ++ if (n>1 && s[1] == '\n') ++ { ++ s++; n--; ++ } ++ break; ++ ++ case '\n': /* ignore LF[,CR] */ ++ if (n>1 && s[1] == '\r') ++ { ++ s++; n--; ++ } ++ break; ++ ++ case 'x': /* hex value */ ++ if (n>2 && hexdigitp (s+1) && hexdigitp (s+2)) ++ { ++ s++; n--; ++ *d++ = xtoi_2 (s); ++ s++; n--; ++ } ++ break; ++ ++ default: ++ if (n>2 && octdigitp (s) && octdigitp (s+1) && octdigitp (s+2)) ++ { ++ *d++ = (atoi_1 (s)*64) + (atoi_1 (s+1)*8) + atoi_1 (s+2); ++ s += 2; ++ n -= 2; ++ } ++ break; ++ } ++ esc = 0; ++ } ++ else if( *s == '\\' ) ++ esc = 1; ++ else ++ *d++ = *s; ++ } ++ ++ return d - buf; ++} ++ ++/**************** ++ * Scan the provided buffer and return the S expression in our internal ++ * format. Returns a newly allocated expression. If erroff is not NULL and ++ * a parsing error has occurred, the offset into buffer will be returned. ++ * If ARGFLAG is true, the function supports some printf like ++ * expressions. ++ * These are: ++ * %m - MPI ++ * %s - string (no autoswitch to secure allocation) ++ * %d - integer stored as string (no autoswitch to secure allocation) ++ * %b - memory buffer; this takes _two_ arguments: an integer with the ++ * length of the buffer and a pointer to the buffer. ++ * %S - Copy an gcry_sexp_t here. The S-expression needs to be a ++ * regular one, starting with a parenthesis. ++ * (no autoswitch to secure allocation) ++ * all other format elements are currently not defined and return an error. ++ * this includes the "%%" sequence becauce the percent sign is not an ++ * allowed character. ++ * FIXME: We should find a way to store the secure-MPIs not in the string ++ * but as reference to somewhere - this can help us to save huge amounts ++ * of secure memory. The problem is, that if only one element is secure, all ++ * other elements are automagicaly copied to secure memory too, so the most ++ * common operation gcry_sexp_cdr_mpi() will always return a secure MPI ++ * regardless whether it is needed or not. ++ */ ++static gcry_error_t ++vsexp_sscan (gcry_sexp_t *retsexp, size_t *erroff, ++ const char *buffer, size_t length, int argflag, ++ void **arg_list, va_list arg_ptr) ++{ ++ gcry_err_code_t err = 0; ++ static const char tokenchars[] = ++ "abcdefghijklmnopqrstuvwxyz" ++ "ABCDEFGHIJKLMNOPQRSTUVWXYZ" ++ "0123456789-./_:*+="; ++ const char *p; ++ size_t n; ++ const char *digptr = NULL; ++ const char *quoted = NULL; ++ const char *tokenp = NULL; ++ const char *hexfmt = NULL; ++ const char *base64 = NULL; ++ const char *disphint = NULL; ++ const char *percent = NULL; ++ int hexcount = 0; ++ int quoted_esc = 0; ++ int datalen = 0; ++ size_t dummy_erroff; ++ struct make_space_ctx c; ++ int arg_counter = 0; ++ int level = 0; ++ ++ if (!erroff) ++ erroff = &dummy_erroff; ++ ++ /* Depending on whether ARG_LIST is non-zero or not, this macro gives ++ us the next argument, either from the variable argument list as ++ specified by ARG_PTR or from the argument array ARG_LIST. */ ++#define ARG_NEXT(storage, type) \ ++ do \ ++ { \ ++ if (!arg_list) \ ++ storage = va_arg (arg_ptr, type); \ ++ else \ ++ storage = *((type *) (arg_list[arg_counter++])); \ ++ } \ ++ while (0) ++ ++ /* The MAKE_SPACE macro is used before each store operation to ++ ensure that the buffer is large enough. It requires a global ++ context named C and jumps out to the label LEAVE on error! It ++ also sets ERROFF using the variables BUFFER and P. */ ++#define MAKE_SPACE(n) do { \ ++ gpg_err_code_t _ms_err = make_space (&c, (n)); \ ++ if (_ms_err) \ ++ { \ ++ err = _ms_err; \ ++ *erroff = p - buffer; \ ++ goto leave; \ ++ } \ ++ } while (0) ++ ++ /* The STORE_LEN macro is used to store the length N at buffer P. */ ++#define STORE_LEN(p,n) do { \ ++ DATALEN ashort = (n); \ ++ memcpy ( (p), &ashort, sizeof(ashort) ); \ ++ (p) += sizeof (ashort); \ ++ } while (0) ++ ++ /* We assume that the internal representation takes less memory than ++ the provided one. However, we add space for one extra datalen so ++ that the code which does the ST_CLOSE can use MAKE_SPACE */ ++ c.allocated = length + sizeof(DATALEN); ++ if (buffer && length && gcry_is_secure (buffer)) ++ c.sexp = gcry_malloc_secure (sizeof *c.sexp + c.allocated - 1); ++ else ++ c.sexp = gcry_malloc (sizeof *c.sexp + c.allocated - 1); ++ if (!c.sexp) ++ { ++ err = gpg_err_code_from_errno (errno); ++ *erroff = 0; ++ goto leave; ++ } ++ c.pos = c.sexp->d; ++ ++ for (p = buffer, n = length; n; p++, n--) ++ { ++ if (tokenp && !hexfmt) ++ { ++ if (strchr (tokenchars, *p)) ++ continue; ++ else ++ { ++ datalen = p - tokenp; ++ MAKE_SPACE (datalen); ++ *c.pos++ = ST_DATA; ++ STORE_LEN (c.pos, datalen); ++ memcpy (c.pos, tokenp, datalen); ++ c.pos += datalen; ++ tokenp = NULL; ++ } ++ } ++ ++ if (quoted) ++ { ++ if (quoted_esc) ++ { ++ switch (*p) ++ { ++ case 'b': case 't': case 'v': case 'n': case 'f': ++ case 'r': case '"': case '\'': case '\\': ++ quoted_esc = 0; ++ break; ++ ++ case '0': case '1': case '2': case '3': case '4': ++ case '5': case '6': case '7': ++ if (!((n > 2) ++ && (p[1] >= '0') && (p[1] <= '7') ++ && (p[2] >= '0') && (p[2] <= '7'))) ++ { ++ *erroff = p - buffer; ++ /* Invalid octal value. */ ++ err = GPG_ERR_SEXP_BAD_QUOTATION; ++ goto leave; ++ } ++ p += 2; ++ n -= 2; ++ quoted_esc = 0; ++ break; ++ ++ case 'x': ++ if (!((n > 2) && hexdigitp (p+1) && hexdigitp (p+2))) ++ { ++ *erroff = p - buffer; ++ /* Invalid hex value. */ ++ err = GPG_ERR_SEXP_BAD_QUOTATION; ++ goto leave; ++ } ++ p += 2; ++ n -= 2; ++ quoted_esc = 0; ++ break; ++ ++ case '\r': ++ /* ignore CR[,LF] */ ++ if (n && (p[1] == '\n')) ++ { ++ p++; ++ n--; ++ } ++ quoted_esc = 0; ++ break; ++ ++ case '\n': ++ /* ignore LF[,CR] */ ++ if (n && (p[1] == '\r')) ++ { ++ p++; ++ n--; ++ } ++ quoted_esc = 0; ++ break; ++ ++ default: ++ *erroff = p - buffer; ++ /* Invalid quoted string escape. */ ++ err = GPG_ERR_SEXP_BAD_QUOTATION; ++ goto leave; ++ } ++ } ++ else if (*p == '\\') ++ quoted_esc = 1; ++ else if (*p == '\"') ++ { ++ /* Keep it easy - we know that the unquoted string will ++ never be larger. */ ++ unsigned char *save; ++ size_t len; ++ ++ quoted++; /* Skip leading quote. */ ++ MAKE_SPACE (p - quoted); ++ *c.pos++ = ST_DATA; ++ save = c.pos; ++ STORE_LEN (c.pos, 0); /* Will be fixed up later. */ ++ len = unquote_string (quoted, p - quoted, c.pos); ++ c.pos += len; ++ STORE_LEN (save, len); ++ quoted = NULL; ++ } ++ } ++ else if (hexfmt) ++ { ++ if (isxdigit (*p)) ++ hexcount++; ++ else if (*p == '#') ++ { ++ if ((hexcount & 1)) ++ { ++ *erroff = p - buffer; ++ err = GPG_ERR_SEXP_ODD_HEX_NUMBERS; ++ goto leave; ++ } ++ ++ datalen = hexcount / 2; ++ MAKE_SPACE (datalen); ++ *c.pos++ = ST_DATA; ++ STORE_LEN (c.pos, datalen); ++ for (hexfmt++; hexfmt < p; hexfmt++) ++ { ++ if (whitespacep (hexfmt)) ++ continue; ++ *c.pos++ = hextobyte ((const unsigned char*)hexfmt); ++ hexfmt++; ++ } ++ hexfmt = NULL; ++ } ++ else if (!whitespacep (p)) ++ { ++ *erroff = p - buffer; ++ err = GPG_ERR_SEXP_BAD_HEX_CHAR; ++ goto leave; ++ } ++ } ++ else if (base64) ++ { ++ if (*p == '|') ++ base64 = NULL; ++ } ++ else if (digptr) ++ { ++ if (digitp (p)) ++ ; ++ else if (*p == ':') ++ { ++ datalen = atoi (digptr); /* FIXME: check for overflow. */ ++ digptr = NULL; ++ if (datalen > n - 1) ++ { ++ *erroff = p - buffer; ++ /* Buffer too short. */ ++ err = GPG_ERR_SEXP_STRING_TOO_LONG; ++ goto leave; ++ } ++ /* Make a new list entry. */ ++ MAKE_SPACE (datalen); ++ *c.pos++ = ST_DATA; ++ STORE_LEN (c.pos, datalen); ++ memcpy (c.pos, p + 1, datalen); ++ c.pos += datalen; ++ n -= datalen; ++ p += datalen; ++ } ++ else if (*p == '\"') ++ { ++ digptr = NULL; /* We ignore the optional length. */ ++ quoted = p; ++ quoted_esc = 0; ++ } ++ else if (*p == '#') ++ { ++ digptr = NULL; /* We ignore the optional length. */ ++ hexfmt = p; ++ hexcount = 0; ++ } ++ else if (*p == '|') ++ { ++ digptr = NULL; /* We ignore the optional length. */ ++ base64 = p; ++ } ++ else ++ { ++ *erroff = p - buffer; ++ err = GPG_ERR_SEXP_INV_LEN_SPEC; ++ goto leave; ++ } ++ } ++ else if (percent) ++ { ++ if (*p == 'm' || *p == 'M') ++ { ++ /* Insert an MPI. */ ++ gcry_mpi_t m; ++ size_t nm = 0; ++ int mpifmt = *p == 'm'? GCRYMPI_FMT_STD: GCRYMPI_FMT_USG; ++ ++ ARG_NEXT (m, gcry_mpi_t); ++ ++ if (gcry_mpi_get_flag (m, GCRYMPI_FLAG_OPAQUE)) ++ { ++ void *mp; ++ unsigned int nbits; ++ ++ mp = gcry_mpi_get_opaque (m, &nbits); ++ nm = (nbits+7)/8; ++ if (mp && nm) ++ { ++ MAKE_SPACE (nm); ++ if (!gcry_is_secure (c.sexp->d) ++ && gcry_mpi_get_flag (m, GCRYMPI_FLAG_SECURE)) ++ { ++ /* We have to switch to secure allocation. */ ++ gcry_sexp_t newsexp; ++ byte *newhead; ++ ++ newsexp = gcry_malloc_secure (sizeof *newsexp ++ + c.allocated - 1); ++ if (!newsexp) ++ { ++ err = gpg_err_code_from_errno (errno); ++ goto leave; ++ } ++ newhead = newsexp->d; ++ memcpy (newhead, c.sexp->d, (c.pos - c.sexp->d)); ++ c.pos = newhead + (c.pos - c.sexp->d); ++ gcry_free (c.sexp); ++ c.sexp = newsexp; ++ } ++ ++ *c.pos++ = ST_DATA; ++ STORE_LEN (c.pos, nm); ++ memcpy (c.pos, mp, nm); ++ c.pos += nm; ++ } ++ } ++ else ++ { ++ if (gcry_mpi_print (mpifmt, NULL, 0, &nm, m)) ++ BUG (); ++ ++ MAKE_SPACE (nm); ++ if (!gcry_is_secure (c.sexp->d) ++ && gcry_mpi_get_flag ( m, GCRYMPI_FLAG_SECURE)) ++ { ++ /* We have to switch to secure allocation. */ ++ gcry_sexp_t newsexp; ++ byte *newhead; ++ ++ newsexp = gcry_malloc_secure (sizeof *newsexp ++ + c.allocated - 1); ++ if (!newsexp) ++ { ++ err = gpg_err_code_from_errno (errno); ++ goto leave; ++ } ++ newhead = newsexp->d; ++ memcpy (newhead, c.sexp->d, (c.pos - c.sexp->d)); ++ c.pos = newhead + (c.pos - c.sexp->d); ++ gcry_free (c.sexp); ++ c.sexp = newsexp; ++ } ++ ++ *c.pos++ = ST_DATA; ++ STORE_LEN (c.pos, nm); ++ if (gcry_mpi_print (mpifmt, c.pos, nm, &nm, m)) ++ BUG (); ++ c.pos += nm; ++ } ++ } ++ else if (*p == 's') ++ { ++ /* Insert an string. */ ++ const char *astr; ++ size_t alen; ++ ++ ARG_NEXT (astr, const char *); ++ alen = strlen (astr); ++ ++ MAKE_SPACE (alen); ++ *c.pos++ = ST_DATA; ++ STORE_LEN (c.pos, alen); ++ memcpy (c.pos, astr, alen); ++ c.pos += alen; ++ } ++ else if (*p == 'b') ++ { ++ /* Insert a memory buffer. */ ++ const char *astr; ++ int alen; ++ ++ ARG_NEXT (alen, int); ++ ARG_NEXT (astr, const char *); ++ ++ MAKE_SPACE (alen); ++ if (alen ++ && !gcry_is_secure (c.sexp->d) ++ && gcry_is_secure (astr)) ++ { ++ /* We have to switch to secure allocation. */ ++ gcry_sexp_t newsexp; ++ byte *newhead; ++ ++ newsexp = gcry_malloc_secure (sizeof *newsexp ++ + c.allocated - 1); ++ if (!newsexp) ++ { ++ err = gpg_err_code_from_errno (errno); ++ goto leave; ++ } ++ newhead = newsexp->d; ++ memcpy (newhead, c.sexp->d, (c.pos - c.sexp->d)); ++ c.pos = newhead + (c.pos - c.sexp->d); ++ gcry_free (c.sexp); ++ c.sexp = newsexp; ++ } ++ ++ *c.pos++ = ST_DATA; ++ STORE_LEN (c.pos, alen); ++ memcpy (c.pos, astr, alen); ++ c.pos += alen; ++ } ++ else if (*p == 'd') ++ { ++ /* Insert an integer as string. */ ++ int aint; ++ size_t alen; ++ char buf[35]; ++ ++ ARG_NEXT (aint, int); ++ sprintf (buf, "%d", aint); ++ alen = strlen (buf); ++ MAKE_SPACE (alen); ++ *c.pos++ = ST_DATA; ++ STORE_LEN (c.pos, alen); ++ memcpy (c.pos, buf, alen); ++ c.pos += alen; ++ } ++ else if (*p == 'u') ++ { ++ /* Insert an unsigned integer as string. */ ++ unsigned int aint; ++ size_t alen; ++ char buf[35]; ++ ++ ARG_NEXT (aint, unsigned int); ++ sprintf (buf, "%u", aint); ++ alen = strlen (buf); ++ MAKE_SPACE (alen); ++ *c.pos++ = ST_DATA; ++ STORE_LEN (c.pos, alen); ++ memcpy (c.pos, buf, alen); ++ c.pos += alen; ++ } ++ else if (*p == 'S') ++ { ++ /* Insert a gcry_sexp_t. */ ++ gcry_sexp_t asexp; ++ size_t alen, aoff; ++ ++ ARG_NEXT (asexp, gcry_sexp_t); ++ alen = get_internal_buffer (asexp, &aoff); ++ if (alen) ++ { ++ MAKE_SPACE (alen); ++ memcpy (c.pos, asexp->d + aoff, alen); ++ c.pos += alen; ++ } ++ } ++ else ++ { ++ *erroff = p - buffer; ++ /* Invalid format specifier. */ ++ err = GPG_ERR_SEXP_INV_LEN_SPEC; ++ goto leave; ++ } ++ percent = NULL; ++ } ++ else if (*p == '(') ++ { ++ if (disphint) ++ { ++ *erroff = p - buffer; ++ /* Open display hint. */ ++ err = GPG_ERR_SEXP_UNMATCHED_DH; ++ goto leave; ++ } ++ MAKE_SPACE (0); ++ *c.pos++ = ST_OPEN; ++ level++; ++ } ++ else if (*p == ')') ++ { ++ /* Walk up. */ ++ if (disphint) ++ { ++ *erroff = p - buffer; ++ /* Open display hint. */ ++ err = GPG_ERR_SEXP_UNMATCHED_DH; ++ goto leave; ++ } ++ MAKE_SPACE (0); ++ *c.pos++ = ST_CLOSE; ++ level--; ++ } ++ else if (*p == '\"') ++ { ++ quoted = p; ++ quoted_esc = 0; ++ } ++ else if (*p == '#') ++ { ++ hexfmt = p; ++ hexcount = 0; ++ } ++ else if (*p == '|') ++ base64 = p; ++ else if (*p == '[') ++ { ++ if (disphint) ++ { ++ *erroff = p - buffer; ++ /* Open display hint. */ ++ err = GPG_ERR_SEXP_NESTED_DH; ++ goto leave; ++ } ++ disphint = p; ++ } ++ else if (*p == ']') ++ { ++ if (!disphint) ++ { ++ *erroff = p - buffer; ++ /* Open display hint. */ ++ err = GPG_ERR_SEXP_UNMATCHED_DH; ++ goto leave; ++ } ++ disphint = NULL; ++ } ++ else if (digitp (p)) ++ { ++ if (*p == '0') ++ { ++ /* A length may not begin with zero. */ ++ *erroff = p - buffer; ++ err = GPG_ERR_SEXP_ZERO_PREFIX; ++ goto leave; ++ } ++ digptr = p; ++ } ++ else if (strchr (tokenchars, *p)) ++ tokenp = p; ++ else if (whitespacep (p)) ++ ; ++ else if (*p == '{') ++ { ++ /* fixme: handle rescanning: we can do this by saving our ++ current state and start over at p+1 -- Hmmm. At this ++ point here we are in a well defined state, so we don't ++ need to save it. Great. */ ++ *erroff = p - buffer; ++ err = GPG_ERR_SEXP_UNEXPECTED_PUNC; ++ goto leave; ++ } ++ else if (strchr ("&\\", *p)) ++ { ++ /* Reserved punctuation. */ ++ *erroff = p - buffer; ++ err = GPG_ERR_SEXP_UNEXPECTED_PUNC; ++ goto leave; ++ } ++ else if (argflag && (*p == '%')) ++ percent = p; ++ else ++ { ++ /* Bad or unavailable. */ ++ *erroff = p - buffer; ++ err = GPG_ERR_SEXP_BAD_CHARACTER; ++ goto leave; ++ } ++ } ++ MAKE_SPACE (0); ++ *c.pos++ = ST_STOP; ++ ++ if (level && !err) ++ err = GPG_ERR_SEXP_UNMATCHED_PAREN; ++ ++ leave: ++ if (err) ++ { ++ /* Error -> deallocate. */ ++ if (c.sexp) ++ { ++ /* Extra paranoid wipe on error. */ ++ if (gcry_is_secure (c.sexp)) ++ wipememory (c.sexp, sizeof (struct gcry_sexp) + c.allocated - 1); ++ gcry_free (c.sexp); ++ } ++ /* This might be expected by existing code... */ ++ *retsexp = NULL; ++ } ++ else ++ *retsexp = normalize (c.sexp); ++ ++ return gcry_error (err); ++#undef MAKE_SPACE ++#undef STORE_LEN ++} ++ ++ ++static gcry_error_t ++sexp_sscan (gcry_sexp_t *retsexp, size_t *erroff, ++ const char *buffer, size_t length, int argflag, ++ void **arg_list, ...) ++{ ++ gcry_error_t rc; ++ va_list arg_ptr; ++ ++ va_start (arg_ptr, arg_list); ++ rc = vsexp_sscan (retsexp, erroff, buffer, length, argflag, ++ arg_list, arg_ptr); ++ va_end (arg_ptr); ++ ++ return rc; ++} ++ ++ ++gcry_error_t ++gcry_sexp_build (gcry_sexp_t *retsexp, size_t *erroff, const char *format, ...) ++{ ++ gcry_error_t rc; ++ va_list arg_ptr; ++ ++ va_start (arg_ptr, format); ++ rc = vsexp_sscan (retsexp, erroff, format, strlen(format), 1, ++ NULL, arg_ptr); ++ va_end (arg_ptr); ++ ++ return rc; ++} ++ ++ ++gcry_error_t ++_gcry_sexp_vbuild (gcry_sexp_t *retsexp, size_t *erroff, ++ const char *format, va_list arg_ptr) ++{ ++ return vsexp_sscan (retsexp, erroff, format, strlen(format), 1, ++ NULL, arg_ptr); ++} ++ ++ ++/* Like gcry_sexp_build, but uses an array instead of variable ++ function arguments. */ ++gcry_error_t ++gcry_sexp_build_array (gcry_sexp_t *retsexp, size_t *erroff, ++ const char *format, void **arg_list) ++{ ++ return sexp_sscan (retsexp, erroff, format, strlen(format), 1, arg_list); ++} ++ ++ ++gcry_error_t ++gcry_sexp_sscan (gcry_sexp_t *retsexp, size_t *erroff, ++ const char *buffer, size_t length) ++{ ++ return sexp_sscan (retsexp, erroff, buffer, length, 0, NULL); ++} ++ ++ ++/* Figure out a suitable encoding for BUFFER of LENGTH. ++ Returns: 0 = Binary ++ 1 = String possible ++ 2 = Token possible ++*/ ++static int ++suitable_encoding (const unsigned char *buffer, size_t length) ++{ ++ const unsigned char *s; ++ int maybe_token = 1; ++ ++ if (!length) ++ return 1; ++ ++ for (s=buffer; length; s++, length--) ++ { ++ if ( (*s < 0x20 || (*s >= 0x7f && *s <= 0xa0)) ++ && !strchr ("\b\t\v\n\f\r\"\'\\", *s)) ++ return 0; /*binary*/ ++ if ( maybe_token ++ && !alphap (s) && !digitp (s) && !strchr (TOKEN_SPECIALS, *s)) ++ maybe_token = 0; ++ } ++ s = buffer; ++ if ( maybe_token && !digitp (s) ) ++ return 2; ++ return 1; ++} ++ ++ ++static int ++convert_to_hex (const unsigned char *src, size_t len, char *dest) ++{ ++ int i; ++ ++ if (dest) ++ { ++ *dest++ = '#'; ++ for (i=0; i < len; i++, dest += 2 ) ++ sprintf (dest, "%02X", src[i]); ++ *dest++ = '#'; ++ } ++ return len*2+2; ++} ++ ++static int ++convert_to_string (const unsigned char *s, size_t len, char *dest) ++{ ++ if (dest) ++ { ++ char *p = dest; ++ *p++ = '\"'; ++ for (; len; len--, s++ ) ++ { ++ switch (*s) ++ { ++ case '\b': *p++ = '\\'; *p++ = 'b'; break; ++ case '\t': *p++ = '\\'; *p++ = 't'; break; ++ case '\v': *p++ = '\\'; *p++ = 'v'; break; ++ case '\n': *p++ = '\\'; *p++ = 'n'; break; ++ case '\f': *p++ = '\\'; *p++ = 'f'; break; ++ case '\r': *p++ = '\\'; *p++ = 'r'; break; ++ case '\"': *p++ = '\\'; *p++ = '\"'; break; ++ case '\'': *p++ = '\\'; *p++ = '\''; break; ++ case '\\': *p++ = '\\'; *p++ = '\\'; break; ++ default: ++ if ( (*s < 0x20 || (*s >= 0x7f && *s <= 0xa0))) ++ { ++ sprintf (p, "\\x%02x", *s); ++ p += 4; ++ } ++ else ++ *p++ = *s; ++ } ++ } ++ *p++ = '\"'; ++ return p - dest; ++ } ++ else ++ { ++ int count = 2; ++ for (; len; len--, s++ ) ++ { ++ switch (*s) ++ { ++ case '\b': ++ case '\t': ++ case '\v': ++ case '\n': ++ case '\f': ++ case '\r': ++ case '\"': ++ case '\'': ++ case '\\': count += 2; break; ++ default: ++ if ( (*s < 0x20 || (*s >= 0x7f && *s <= 0xa0))) ++ count += 4; ++ else ++ count++; ++ } ++ } ++ return count; ++ } ++} ++ ++ ++ ++static int ++convert_to_token (const unsigned char *src, size_t len, char *dest) ++{ ++ if (dest) ++ memcpy (dest, src, len); ++ return len; ++} ++ ++ ++/**************** ++ * Print SEXP to buffer using the MODE. Returns the length of the ++ * SEXP in buffer or 0 if the buffer is too short (We have at least an ++ * empty list consisting of 2 bytes). If a buffer of NULL is provided, ++ * the required length is returned. ++ */ ++size_t ++gcry_sexp_sprint (const gcry_sexp_t list, int mode, ++ void *buffer, size_t maxlength ) ++{ ++ static unsigned char empty[3] = { ST_OPEN, ST_CLOSE, ST_STOP }; ++ const unsigned char *s; ++ char *d; ++ DATALEN n; ++ char numbuf[20]; ++ size_t len = 0; ++ int i, indent = 0; ++ ++ s = list? list->d : empty; ++ d = buffer; ++ while ( *s != ST_STOP ) ++ { ++ switch ( *s ) ++ { ++ case ST_OPEN: ++ s++; ++ if ( mode != GCRYSEXP_FMT_CANON ) ++ { ++ if (indent) ++ len++; ++ len += indent; ++ } ++ len++; ++ if ( buffer ) ++ { ++ if ( len >= maxlength ) ++ return 0; ++ if ( mode != GCRYSEXP_FMT_CANON ) ++ { ++ if (indent) ++ *d++ = '\n'; ++ for (i=0; i < indent; i++) ++ *d++ = ' '; ++ } ++ *d++ = '('; ++ } ++ indent++; ++ break; ++ case ST_CLOSE: ++ s++; ++ len++; ++ if ( buffer ) ++ { ++ if ( len >= maxlength ) ++ return 0; ++ *d++ = ')'; ++ } ++ indent--; ++ if (*s != ST_OPEN && *s != ST_STOP && mode != GCRYSEXP_FMT_CANON) ++ { ++ len++; ++ len += indent; ++ if (buffer) ++ { ++ if (len >= maxlength) ++ return 0; ++ *d++ = '\n'; ++ for (i=0; i < indent; i++) ++ *d++ = ' '; ++ } ++ } ++ break; ++ case ST_DATA: ++ s++; ++ memcpy ( &n, s, sizeof n ); s += sizeof n; ++ if (mode == GCRYSEXP_FMT_ADVANCED) ++ { ++ int type; ++ size_t nn; ++ ++ switch ( (type=suitable_encoding (s, n))) ++ { ++ case 1: nn = convert_to_string (s, n, NULL); break; ++ case 2: nn = convert_to_token (s, n, NULL); break; ++ default: nn = convert_to_hex (s, n, NULL); break; ++ } ++ len += nn; ++ if (buffer) ++ { ++ if (len >= maxlength) ++ return 0; ++ switch (type) ++ { ++ case 1: convert_to_string (s, n, d); break; ++ case 2: convert_to_token (s, n, d); break; ++ default: convert_to_hex (s, n, d); break; ++ } ++ d += nn; ++ } ++ if (s[n] != ST_CLOSE) ++ { ++ len++; ++ if (buffer) ++ { ++ if (len >= maxlength) ++ return 0; ++ *d++ = ' '; ++ } ++ } ++ } ++ else ++ { ++ sprintf (numbuf, "%u:", (unsigned int)n ); ++ len += strlen (numbuf) + n; ++ if ( buffer ) ++ { ++ if ( len >= maxlength ) ++ return 0; ++ d = stpcpy ( d, numbuf ); ++ memcpy ( d, s, n ); d += n; ++ } ++ } ++ s += n; ++ break; ++ default: ++ BUG (); ++ } ++ } ++ if ( mode != GCRYSEXP_FMT_CANON ) ++ { ++ len++; ++ if (buffer) ++ { ++ if ( len >= maxlength ) ++ return 0; ++ *d++ = '\n'; ++ } ++ } ++ if (buffer) ++ { ++ if ( len >= maxlength ) ++ return 0; ++ *d++ = 0; /* for convenience we make a C string */ ++ } ++ else ++ len++; /* we need one byte more for this */ ++ ++ return len; ++} ++ ++ ++/* Scan a canonical encoded buffer with implicit length values and ++ return the actual length this S-expression uses. For a valid S-Exp ++ it should never return 0. If LENGTH is not zero, the maximum ++ length to scan is given - this can be used for syntax checks of ++ data passed from outside. errorcode and erroff may both be passed as ++ NULL. */ ++size_t ++gcry_sexp_canon_len (const unsigned char *buffer, size_t length, ++ size_t *erroff, gcry_error_t *errcode) ++{ ++ const unsigned char *p; ++ const unsigned char *disphint = NULL; ++ unsigned int datalen = 0; ++ size_t dummy_erroff; ++ gcry_error_t dummy_errcode; ++ size_t count = 0; ++ int level = 0; ++ ++ if (!erroff) ++ erroff = &dummy_erroff; ++ if (!errcode) ++ errcode = &dummy_errcode; ++ ++ *errcode = gcry_error (GPG_ERR_NO_ERROR); ++ *erroff = 0; ++ if (!buffer) ++ return 0; ++ if (*buffer != '(') ++ { ++ *errcode = gcry_error (GPG_ERR_SEXP_NOT_CANONICAL); ++ return 0; ++ } ++ ++ for (p=buffer; ; p++, count++ ) ++ { ++ if (length && count >= length) ++ { ++ *erroff = count; ++ *errcode = gcry_error (GPG_ERR_SEXP_STRING_TOO_LONG); ++ return 0; ++ } ++ ++ if (datalen) ++ { ++ if (*p == ':') ++ { ++ if (length && (count+datalen) >= length) ++ { ++ *erroff = count; ++ *errcode = gcry_error (GPG_ERR_SEXP_STRING_TOO_LONG); ++ return 0; ++ } ++ count += datalen; ++ p += datalen; ++ datalen = 0; ++ } ++ else if (digitp(p)) ++ datalen = datalen*10 + atoi_1(p); ++ else ++ { ++ *erroff = count; ++ *errcode = gcry_error (GPG_ERR_SEXP_INV_LEN_SPEC); ++ return 0; ++ } ++ } ++ else if (*p == '(') ++ { ++ if (disphint) ++ { ++ *erroff = count; ++ *errcode = gcry_error (GPG_ERR_SEXP_UNMATCHED_DH); ++ return 0; ++ } ++ level++; ++ } ++ else if (*p == ')') ++ { /* walk up */ ++ if (!level) ++ { ++ *erroff = count; ++ *errcode = gcry_error (GPG_ERR_SEXP_UNMATCHED_PAREN); ++ return 0; ++ } ++ if (disphint) ++ { ++ *erroff = count; ++ *errcode = gcry_error (GPG_ERR_SEXP_UNMATCHED_DH); ++ return 0; ++ } ++ if (!--level) ++ return ++count; /* ready */ ++ } ++ else if (*p == '[') ++ { ++ if (disphint) ++ { ++ *erroff = count; ++ *errcode = gcry_error (GPG_ERR_SEXP_NESTED_DH); ++ return 0; ++ } ++ disphint = p; ++ } ++ else if (*p == ']') ++ { ++ if ( !disphint ) ++ { ++ *erroff = count; ++ *errcode = gcry_error (GPG_ERR_SEXP_UNMATCHED_DH); ++ return 0; ++ } ++ disphint = NULL; ++ } ++ else if (digitp (p) ) ++ { ++ if (*p == '0') ++ { ++ *erroff = count; ++ *errcode = gcry_error (GPG_ERR_SEXP_ZERO_PREFIX); ++ return 0; ++ } ++ datalen = atoi_1 (p); ++ } ++ else if (*p == '&' || *p == '\\') ++ { ++ *erroff = count; ++ *errcode = gcry_error (GPG_ERR_SEXP_UNEXPECTED_PUNC); ++ return 0; ++ } ++ else ++ { ++ *erroff = count; ++ *errcode = gcry_error (GPG_ERR_SEXP_BAD_CHARACTER); ++ return 0; ++ } ++ } ++} +diff --git a/grub-core/lib/libgcrypt/src/stdmem.c b/grub-core/lib/libgcrypt/src/stdmem.c +new file mode 100644 +index 0000000..189da37 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/src/stdmem.c +@@ -0,0 +1,242 @@ ++/* stdmem.c - private memory allocator ++ * Copyright (C) 1998, 2000, 2002, 2005, 2008 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser general Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, see . ++ */ ++ ++/* ++ * Description of the layered memory management in Libgcrypt: ++ * ++ * [User] ++ * | ++ * | ++ * \ / ++ * global.c: [MM entrance points] -----> [user callbacks] ++ * | | ++ * | | ++ * \ / \ / ++ * ++ * stdmem.c: [non-secure handlers] [secure handlers] ++ * ++ * | | ++ * | | ++ * \ / \ / ++ * ++ * stdmem.c: [ memory guard ] ++ * ++ * | | ++ * | | ++ * \ / \ / ++ * ++ * libc: [ MM functions ] secmem.c: [ secure MM functions] ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "g10lib.h" ++#include "stdmem.h" ++#include "secmem.h" ++ ++ ++ ++#define MAGIC_NOR_BYTE 0x55 ++#define MAGIC_SEC_BYTE 0xcc ++#define MAGIC_END_BYTE 0xaa ++ ++#if SIZEOF_UNSIGNED_LONG == 8 ++#define EXTRA_ALIGN 4 ++#else ++#define EXTRA_ALIGN 0 ++#endif ++ ++ ++static int use_m_guard = 0; ++ ++/**************** ++ * Warning: Never use this function after any of the functions ++ * here have been used. ++ */ ++void ++_gcry_private_enable_m_guard (void) ++{ ++ use_m_guard = 1; ++} ++ ++ ++/* ++ * Allocate memory of size n. ++ * Return NULL if we are out of memory. ++ */ ++void * ++_gcry_private_malloc (size_t n) ++{ ++ if (!n) ++ { ++ gpg_err_set_errno (EINVAL); ++ return NULL; /* Allocating 0 bytes is undefined - we better return ++ an error to detect such coding errors. */ ++ } ++ ++ if (use_m_guard) ++ { ++ char *p; ++ ++ if ( !(p = malloc (n + EXTRA_ALIGN+5)) ) ++ return NULL; ++ ((byte*)p)[EXTRA_ALIGN+0] = n; ++ ((byte*)p)[EXTRA_ALIGN+1] = n >> 8 ; ++ ((byte*)p)[EXTRA_ALIGN+2] = n >> 16 ; ++ ((byte*)p)[EXTRA_ALIGN+3] = MAGIC_NOR_BYTE; ++ p[4+EXTRA_ALIGN+n] = MAGIC_END_BYTE; ++ return p+EXTRA_ALIGN+4; ++ } ++ else ++ { ++ return malloc( n ); ++ } ++} ++ ++ ++/* ++ * Allocate memory of size N from the secure memory pool. Return NULL ++ * if we are out of memory. ++ */ ++void * ++_gcry_private_malloc_secure (size_t n) ++{ ++ if (!n) ++ { ++ gpg_err_set_errno (EINVAL); ++ return NULL; /* Allocating 0 bytes is undefined - better return an ++ error to detect such coding errors. */ ++ } ++ ++ if (use_m_guard) ++ { ++ char *p; ++ ++ if ( !(p = _gcry_secmem_malloc (n +EXTRA_ALIGN+ 5)) ) ++ return NULL; ++ ((byte*)p)[EXTRA_ALIGN+0] = n; ++ ((byte*)p)[EXTRA_ALIGN+1] = n >> 8 ; ++ ((byte*)p)[EXTRA_ALIGN+2] = n >> 16 ; ++ ((byte*)p)[EXTRA_ALIGN+3] = MAGIC_SEC_BYTE; ++ p[4+EXTRA_ALIGN+n] = MAGIC_END_BYTE; ++ return p+EXTRA_ALIGN+4; ++ } ++ else ++ { ++ return _gcry_secmem_malloc( n ); ++ } ++} ++ ++ ++/* ++ * Realloc and clear the old space ++ * Return NULL if there is not enough memory. ++ */ ++void * ++_gcry_private_realloc ( void *a, size_t n ) ++{ ++ if (use_m_guard) ++ { ++ unsigned char *p = a; ++ char *b; ++ size_t len; ++ ++ if (!a) ++ return _gcry_private_malloc(n); ++ ++ _gcry_private_check_heap(p); ++ len = p[-4]; ++ len |= p[-3] << 8; ++ len |= p[-2] << 16; ++ if( len >= n ) /* We don't shrink for now. */ ++ return a; ++ if (p[-1] == MAGIC_SEC_BYTE) ++ b = _gcry_private_malloc_secure(n); ++ else ++ b = _gcry_private_malloc(n); ++ if (!b) ++ return NULL; ++ memcpy (b, a, len); ++ memset (b+len, 0, n-len); ++ _gcry_private_free (p); ++ return b; ++ } ++ else if ( _gcry_private_is_secure(a) ) ++ { ++ return _gcry_secmem_realloc( a, n ); ++ } ++ else ++ { ++ return realloc( a, n ); ++ } ++} ++ ++ ++void ++_gcry_private_check_heap (const void *a) ++{ ++ if (use_m_guard) ++ { ++ const byte *p = a; ++ size_t len; ++ ++ if (!p) ++ return; ++ ++ if ( !(p[-1] == MAGIC_NOR_BYTE || p[-1] == MAGIC_SEC_BYTE) ) ++ _gcry_log_fatal ("memory at %p corrupted (underflow=%02x)\n", p, p[-1]); ++ len = p[-4]; ++ len |= p[-3] << 8; ++ len |= p[-2] << 16; ++ if ( p[len] != MAGIC_END_BYTE ) ++ _gcry_log_fatal ("memory at %p corrupted (overflow=%02x)\n", p, p[-1]); ++ } ++} ++ ++ ++/* ++ * Free a memory block allocated by this or the secmem module ++ */ ++void ++_gcry_private_free (void *a) ++{ ++ unsigned char *p = a; ++ ++ if (!p) ++ return; ++ if (use_m_guard ) ++ { ++ _gcry_private_check_heap(p); ++ if ( _gcry_private_is_secure(a) ) ++ _gcry_secmem_free(p-EXTRA_ALIGN-4); ++ else ++ { ++ free(p-EXTRA_ALIGN-4); ++ } ++ } ++ else if ( _gcry_private_is_secure(a) ) ++ _gcry_secmem_free(p); ++ else ++ free(p); ++} +diff --git a/grub-core/lib/libgcrypt/src/stdmem.h b/grub-core/lib/libgcrypt/src/stdmem.h +new file mode 100644 +index 0000000..b476e7e +--- /dev/null ++++ b/grub-core/lib/libgcrypt/src/stdmem.h +@@ -0,0 +1,32 @@ ++/* stdmem.h - internal definitions for stdmem ++ * Copyright (C) 2000, 2002, 2005 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser general Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ */ ++ ++#ifndef G10_STDMEM_H ++#define G10_STDMEM_H 1 ++ ++void _gcry_private_enable_m_guard(void); ++ ++void *_gcry_private_malloc (size_t n) _GCRY_GCC_ATTR_MALLOC; ++void *_gcry_private_malloc_secure (size_t n) _GCRY_GCC_ATTR_MALLOC; ++void *_gcry_private_realloc (void *a, size_t n); ++void _gcry_private_check_heap (const void *a); ++void _gcry_private_free (void *a); ++ ++#endif /* G10_STDMEM_H */ +diff --git a/grub-core/lib/libgcrypt/src/types.h b/grub-core/lib/libgcrypt/src/types.h +new file mode 100644 +index 0000000..ee0a62b +--- /dev/null ++++ b/grub-core/lib/libgcrypt/src/types.h +@@ -0,0 +1,128 @@ ++/* types.h - some common typedefs ++ * Copyright (C) 1998, 2000, 2002, 2003 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser general Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ */ ++ ++#ifndef GCRYPT_TYPES_H ++#define GCRYPT_TYPES_H ++ ++ ++/* The AC_CHECK_SIZEOF() in configure fails for some machines. ++ * we provide some fallback values here */ ++#if !SIZEOF_UNSIGNED_SHORT ++#undef SIZEOF_UNSIGNED_SHORT ++#define SIZEOF_UNSIGNED_SHORT 2 ++#endif ++#if !SIZEOF_UNSIGNED_INT ++#undef SIZEOF_UNSIGNED_INT ++#define SIZEOF_UNSIGNED_INT 4 ++#endif ++#if !SIZEOF_UNSIGNED_LONG ++#undef SIZEOF_UNSIGNED_LONG ++#define SIZEOF_UNSIGNED_LONG 4 ++#endif ++ ++ ++#include ++ ++ ++#ifndef HAVE_BYTE_TYPEDEF ++#undef byte /* maybe there is a macro with this name */ ++/* Windows typedefs byte in the rpc headers. Avoid warning about ++ double definition. */ ++#if !(defined(_WIN32) && defined(cbNDRContext)) ++ typedef unsigned char byte; ++#endif ++#define HAVE_BYTE_TYPEDEF ++#endif ++ ++#ifndef HAVE_USHORT_TYPEDEF ++#undef ushort /* maybe there is a macro with this name */ ++ typedef unsigned short ushort; ++#define HAVE_USHORT_TYPEDEF ++#endif ++ ++#ifndef HAVE_ULONG_TYPEDEF ++#undef ulong /* maybe there is a macro with this name */ ++ typedef unsigned long ulong; ++#define HAVE_ULONG_TYPEDEF ++#endif ++ ++#ifndef HAVE_U16_TYPEDEF ++#undef u16 /* maybe there is a macro with this name */ ++#if SIZEOF_UNSIGNED_INT == 2 ++ typedef unsigned int u16; ++#elif SIZEOF_UNSIGNED_SHORT == 2 ++ typedef unsigned short u16; ++#else ++#error no typedef for u16 ++#endif ++#define HAVE_U16_TYPEDEF ++#endif ++ ++#ifndef HAVE_U32_TYPEDEF ++#undef u32 /* maybe there is a macro with this name */ ++#if SIZEOF_UNSIGNED_INT == 4 ++ typedef unsigned int u32; ++#elif SIZEOF_UNSIGNED_LONG == 4 ++ typedef unsigned long u32; ++#else ++#error no typedef for u32 ++#endif ++#define HAVE_U32_TYPEDEF ++#endif ++ ++/**************** ++ * Warning: Some systems segfault when this u64 typedef and ++ * the dummy code in cipher/md.c is not available. Examples are ++ * Solaris and IRIX. ++ */ ++#ifndef HAVE_U64_TYPEDEF ++#undef u64 /* maybe there is a macro with this name */ ++#if SIZEOF_UNSIGNED_INT == 8 ++ typedef unsigned int u64; ++#define U64_C(c) (c ## U) ++#define HAVE_U64_TYPEDEF ++#elif SIZEOF_UNSIGNED_LONG == 8 ++ typedef unsigned long u64; ++#define U64_C(c) (c ## UL) ++#define HAVE_U64_TYPEDEF ++#elif SIZEOF_UNSIGNED_LONG_LONG == 8 ++ typedef unsigned long long u64; ++#define U64_C(c) (c ## ULL) ++#define HAVE_U64_TYPEDEF ++#elif SIZEOF_UINT64_T == 8 ++ typedef uint64_t u64; ++#define U64_C(c) (UINT64_C(c)) ++#define HAVE_U64_TYPEDEF ++#endif ++#endif ++ ++typedef union { ++ int a; ++ short b; ++ char c[1]; ++ long d; ++#ifdef HAVE_U64_TYPEDEF ++ u64 e; ++#endif ++ float f; ++ double g; ++} PROPERLY_ALIGNED_TYPE; ++ ++#endif /*GCRYPT_TYPES_H*/ +diff --git a/grub-core/lib/libgcrypt/src/versioninfo.rc.in b/grub-core/lib/libgcrypt/src/versioninfo.rc.in +new file mode 100644 +index 0000000..401851e +--- /dev/null ++++ b/grub-core/lib/libgcrypt/src/versioninfo.rc.in +@@ -0,0 +1,51 @@ ++/* versioninfo.rc.in - for libgcrypt ++ * Copyright (C) 2005, 2006 g10 Code GmbH ++ * ++ * This file is free software; as a special exception 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. ++ */ ++ ++/* This file is processed by configure to create versioninfo.rc */ ++ ++#line __LINE__ "versioninfo.rc.in" ++ ++#include ++ ++ ++VS_VERSION_INFO VERSIONINFO ++ FILEVERSION @LIBGCRYPT_LT_CURRENT@,@LIBGCRYPT_LT_AGE@,@LIBGCRYPT_LT_REVISION@,@BUILD_REVISION@ ++ PRODUCTVERSION @BUILD_FILEVERSION@ ++ FILEFLAGSMASK 0x3fL ++#ifdef _DEBUG ++ FILEFLAGS 0x21L ++#else ++ FILEFLAGS 0x20L ++#endif ++ FILEOS 0x40004L ++ FILETYPE 0x1L ++ FILESUBTYPE 0x0L ++BEGIN ++ BLOCK "StringFileInfo" ++ BEGIN ++ BLOCK "040904b0" ++ BEGIN ++ VALUE "Comments", "Provided under the terms of the GNU Lesser General Public License (LGPLv2.1+).\0" ++ VALUE "CompanyName", "g10 Code GmbH\0" ++ VALUE "FileDescription", "Libgcrypt - The GNU Crypto Library\0" ++ VALUE "FileVersion", "@LIBGCRYPT_LT_CURRENT@.@LIBGCRYPT_LT_AGE@.@LIBGCRYPT_LT_REVISION@.@BUILD_REVISION@\0" ++ VALUE "InternalName", "libgcrypt\0" ++ VALUE "LegalCopyright", "Copyright � 2011 Free Software Foundation, Inc.\0" ++ VALUE "LegalTrademarks", "\0" ++ VALUE "OriginalFilename", "libgcrypt.dll\0" ++ VALUE "PrivateBuild", "\0" ++ VALUE "ProductName", "libgcrypt\0" ++ VALUE "ProductVersion", "@VERSION@\0" ++ VALUE "SpecialBuild", "@BUILD_TIMESTAMP@\0" ++ END ++ END ++END +diff --git a/grub-core/lib/libgcrypt/src/visibility.c b/grub-core/lib/libgcrypt/src/visibility.c +new file mode 100644 +index 0000000..2d3edbc +--- /dev/null ++++ b/grub-core/lib/libgcrypt/src/visibility.c +@@ -0,0 +1,1146 @@ ++/* visibility.c - Wrapper for all public functions. ++ * Copyright (C) 2007, 2008, 2011 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, see . ++ */ ++ ++#include ++#include ++ ++#define _GCRY_INCLUDED_BY_VISIBILITY_C ++#include "g10lib.h" ++#include "cipher-proto.h" ++ ++ ++ ++const char * ++gcry_strerror (gcry_error_t err) ++{ ++ return _gcry_strerror (err); ++} ++ ++const char * ++gcry_strsource (gcry_error_t err) ++{ ++ return _gcry_strsource (err); ++} ++ ++gcry_err_code_t ++gcry_err_code_from_errno (int err) ++{ ++ return _gcry_err_code_from_errno (err); ++} ++ ++int ++gcry_err_code_to_errno (gcry_err_code_t code) ++{ ++ return _gcry_err_code_to_errno (code); ++} ++ ++gcry_error_t ++gcry_err_make_from_errno (gcry_err_source_t source, int err) ++{ ++ return _gcry_err_make_from_errno (source, err); ++} ++ ++gcry_err_code_t ++gcry_error_from_errno (int err) ++{ ++ return _gcry_error_from_errno (err); ++} ++ ++const char * ++gcry_check_version (const char *req_version) ++{ ++ return _gcry_check_version (req_version); ++} ++ ++gcry_error_t ++gcry_control (enum gcry_ctl_cmds cmd, ...) ++{ ++ gcry_error_t err; ++ va_list arg_ptr; ++ ++ va_start (arg_ptr, cmd); ++ err = _gcry_vcontrol (cmd, arg_ptr); ++ va_end(arg_ptr); ++ return err; ++} ++ ++gcry_error_t ++gcry_sexp_new (gcry_sexp_t *retsexp, ++ const void *buffer, size_t length, ++ int autodetect) ++{ ++ return _gcry_sexp_new (retsexp, buffer, length, autodetect); ++} ++ ++gcry_error_t ++gcry_sexp_create (gcry_sexp_t *retsexp, ++ void *buffer, size_t length, ++ int autodetect, void (*freefnc) (void *)) ++{ ++ return _gcry_sexp_create (retsexp, buffer, length, ++ autodetect, freefnc); ++} ++ ++gcry_error_t ++gcry_sexp_sscan (gcry_sexp_t *retsexp, size_t *erroff, ++ const char *buffer, size_t length) ++{ ++ return _gcry_sexp_sscan (retsexp, erroff, buffer, length); ++} ++ ++gcry_error_t ++gcry_sexp_build (gcry_sexp_t *retsexp, size_t *erroff, ++ const char *format, ...) ++{ ++ gcry_error_t err; ++ va_list arg_ptr; ++ ++ va_start (arg_ptr, format); ++ err = _gcry_sexp_vbuild (retsexp, erroff, format, arg_ptr); ++ va_end (arg_ptr); ++ return err; ++} ++ ++gcry_error_t ++gcry_sexp_build_array (gcry_sexp_t *retsexp, size_t *erroff, ++ const char *format, void **arg_list) ++{ ++ return _gcry_sexp_build_array (retsexp, erroff, format, arg_list); ++} ++ ++void ++gcry_sexp_release (gcry_sexp_t sexp) ++{ ++ _gcry_sexp_release (sexp); ++} ++ ++size_t ++gcry_sexp_canon_len (const unsigned char *buffer, size_t length, ++ size_t *erroff, gcry_error_t *errcode) ++{ ++ return _gcry_sexp_canon_len (buffer, length, erroff, errcode); ++} ++ ++size_t ++gcry_sexp_sprint (gcry_sexp_t sexp, int mode, void *buffer, size_t maxlength) ++{ ++ return _gcry_sexp_sprint (sexp, mode, buffer, maxlength); ++} ++ ++void ++gcry_sexp_dump (const gcry_sexp_t a) ++{ ++ _gcry_sexp_dump (a); ++} ++ ++gcry_sexp_t ++gcry_sexp_cons (const gcry_sexp_t a, const gcry_sexp_t b) ++{ ++ return _gcry_sexp_cons (a, b); ++} ++ ++gcry_sexp_t ++gcry_sexp_alist (const gcry_sexp_t *array) ++{ ++ return _gcry_sexp_alist (array); ++} ++ ++gcry_sexp_t ++gcry_sexp_vlist (const gcry_sexp_t a, ...) ++{ ++ /* This is not yet implemented in sexp.c. */ ++ (void)a; ++ BUG (); ++ return NULL; ++} ++ ++gcry_sexp_t ++gcry_sexp_append (const gcry_sexp_t a, const gcry_sexp_t n) ++{ ++ return _gcry_sexp_append (a, n); ++} ++ ++gcry_sexp_t ++gcry_sexp_prepend (const gcry_sexp_t a, const gcry_sexp_t n) ++{ ++ return _gcry_sexp_prepend (a, n); ++} ++ ++ ++gcry_sexp_t ++gcry_sexp_find_token (gcry_sexp_t list, const char *tok, size_t toklen) ++{ ++ return _gcry_sexp_find_token (list, tok, toklen); ++} ++ ++int ++gcry_sexp_length (const gcry_sexp_t list) ++{ ++ return _gcry_sexp_length (list); ++} ++ ++gcry_sexp_t ++gcry_sexp_nth (const gcry_sexp_t list, int number) ++{ ++ return _gcry_sexp_nth (list, number); ++} ++ ++gcry_sexp_t ++gcry_sexp_car (const gcry_sexp_t list) ++{ ++ return _gcry_sexp_car (list); ++} ++ ++gcry_sexp_t ++gcry_sexp_cdr (const gcry_sexp_t list) ++{ ++ return _gcry_sexp_cdr (list); ++} ++ ++gcry_sexp_t ++gcry_sexp_cadr (const gcry_sexp_t list) ++{ ++ return _gcry_sexp_cadr (list); ++} ++ ++const char * ++gcry_sexp_nth_data (const gcry_sexp_t list, int number, size_t *datalen) ++{ ++ return _gcry_sexp_nth_data (list, number, datalen); ++} ++ ++char * ++gcry_sexp_nth_string (gcry_sexp_t list, int number) ++{ ++ return _gcry_sexp_nth_string (list, number); ++} ++ ++gcry_mpi_t ++gcry_sexp_nth_mpi (gcry_sexp_t list, int number, int mpifmt) ++{ ++ return _gcry_sexp_nth_mpi (list, number, mpifmt); ++} ++ ++gcry_mpi_t ++gcry_mpi_new (unsigned int nbits) ++{ ++ return _gcry_mpi_new (nbits); ++} ++ ++gcry_mpi_t ++gcry_mpi_snew (unsigned int nbits) ++{ ++ return _gcry_mpi_snew (nbits); ++} ++ ++void ++gcry_mpi_release (gcry_mpi_t a) ++{ ++ _gcry_mpi_release (a); ++} ++ ++gcry_mpi_t ++gcry_mpi_copy (const gcry_mpi_t a) ++{ ++ return _gcry_mpi_copy (a); ++} ++ ++gcry_mpi_t ++gcry_mpi_set (gcry_mpi_t w, const gcry_mpi_t u) ++{ ++ return _gcry_mpi_set (w, u); ++} ++ ++gcry_mpi_t ++gcry_mpi_set_ui (gcry_mpi_t w, unsigned long u) ++{ ++ return _gcry_mpi_set_ui (w, u); ++} ++ ++void ++gcry_mpi_swap (gcry_mpi_t a, gcry_mpi_t b) ++{ ++ _gcry_mpi_swap (a, b); ++} ++ ++int ++gcry_mpi_cmp (const gcry_mpi_t u, const gcry_mpi_t v) ++{ ++ return _gcry_mpi_cmp (u, v); ++} ++ ++int ++gcry_mpi_cmp_ui (const gcry_mpi_t u, unsigned long v) ++{ ++ return _gcry_mpi_cmp_ui (u, v); ++} ++ ++gcry_error_t ++gcry_mpi_scan (gcry_mpi_t *ret_mpi, enum gcry_mpi_format format, ++ const void *buffer, size_t buflen, ++ size_t *nscanned) ++{ ++ return _gcry_mpi_scan (ret_mpi, format, buffer, buflen, nscanned); ++} ++ ++gcry_error_t ++gcry_mpi_print (enum gcry_mpi_format format, ++ unsigned char *buffer, size_t buflen, ++ size_t *nwritten, ++ const gcry_mpi_t a) ++{ ++ return _gcry_mpi_print (format, buffer, buflen, nwritten, a); ++} ++ ++gcry_error_t ++gcry_mpi_aprint (enum gcry_mpi_format format, ++ unsigned char **buffer, size_t *nwritten, ++ const gcry_mpi_t a) ++{ ++ return _gcry_mpi_aprint (format, buffer, nwritten, a); ++} ++ ++void ++gcry_mpi_dump (const gcry_mpi_t a) ++{ ++ _gcry_mpi_dump (a); ++} ++ ++void ++gcry_mpi_add (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v) ++{ ++ _gcry_mpi_add (w, u, v); ++} ++ ++void ++gcry_mpi_add_ui (gcry_mpi_t w, gcry_mpi_t u, unsigned long v) ++{ ++ _gcry_mpi_add_ui (w, u, v); ++} ++ ++void ++gcry_mpi_addm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m) ++{ ++ _gcry_mpi_addm (w, u, v, m); ++} ++ ++void ++gcry_mpi_sub (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v) ++{ ++ _gcry_mpi_sub (w, u, v); ++} ++ ++void ++gcry_mpi_sub_ui (gcry_mpi_t w, gcry_mpi_t u, unsigned long v ) ++{ ++ _gcry_mpi_sub_ui (w, u, v); ++} ++ ++void ++gcry_mpi_subm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m) ++{ ++ _gcry_mpi_subm (w, u, v, m); ++} ++ ++void ++gcry_mpi_mul (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v) ++{ ++ _gcry_mpi_mul (w, u, v); ++} ++ ++void ++gcry_mpi_mul_ui (gcry_mpi_t w, gcry_mpi_t u, unsigned long v ) ++{ ++ _gcry_mpi_mul_ui (w, u, v); ++} ++ ++void ++gcry_mpi_mulm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m) ++{ ++ _gcry_mpi_mulm (w, u, v, m); ++} ++ ++void ++gcry_mpi_mul_2exp (gcry_mpi_t w, gcry_mpi_t u, unsigned long cnt) ++{ ++ _gcry_mpi_mul_2exp (w, u, cnt); ++} ++ ++void ++gcry_mpi_div (gcry_mpi_t q, gcry_mpi_t r, ++ gcry_mpi_t dividend, gcry_mpi_t divisor, int round) ++{ ++ _gcry_mpi_div (q, r, dividend, divisor, round); ++} ++ ++void ++gcry_mpi_mod (gcry_mpi_t r, gcry_mpi_t dividend, gcry_mpi_t divisor) ++{ ++ _gcry_mpi_mod (r, dividend, divisor); ++} ++ ++void ++gcry_mpi_powm (gcry_mpi_t w, const gcry_mpi_t b, const gcry_mpi_t e, ++ const gcry_mpi_t m) ++{ ++ _gcry_mpi_powm (w, b, e, m); ++} ++ ++int ++gcry_mpi_gcd (gcry_mpi_t g, gcry_mpi_t a, gcry_mpi_t b) ++{ ++ return _gcry_mpi_gcd (g, a, b); ++} ++ ++int ++gcry_mpi_invm (gcry_mpi_t x, gcry_mpi_t a, gcry_mpi_t m) ++{ ++ return _gcry_mpi_invm (x, a, m); ++} ++ ++ ++unsigned int ++gcry_mpi_get_nbits (gcry_mpi_t a) ++{ ++ return _gcry_mpi_get_nbits (a); ++} ++ ++int ++gcry_mpi_test_bit (gcry_mpi_t a, unsigned int n) ++{ ++ return _gcry_mpi_test_bit (a, n); ++} ++ ++void ++gcry_mpi_set_bit (gcry_mpi_t a, unsigned int n) ++{ ++ _gcry_mpi_set_bit (a, n); ++} ++ ++void ++gcry_mpi_clear_bit (gcry_mpi_t a, unsigned int n) ++{ ++ _gcry_mpi_clear_bit (a, n); ++} ++ ++void ++gcry_mpi_set_highbit (gcry_mpi_t a, unsigned int n) ++{ ++ _gcry_mpi_set_highbit (a, n); ++} ++ ++void ++gcry_mpi_clear_highbit (gcry_mpi_t a, unsigned int n) ++{ ++ _gcry_mpi_clear_highbit (a, n); ++} ++ ++void ++gcry_mpi_rshift (gcry_mpi_t x, gcry_mpi_t a, unsigned int n) ++{ ++ _gcry_mpi_rshift (x, a, n); ++} ++ ++void ++gcry_mpi_lshift (gcry_mpi_t x, gcry_mpi_t a, unsigned int n) ++{ ++ _gcry_mpi_lshift (x, a, n); ++} ++ ++gcry_mpi_t ++gcry_mpi_set_opaque (gcry_mpi_t a, void *p, unsigned int nbits) ++{ ++ return _gcry_mpi_set_opaque (a, p, nbits); ++} ++ ++void * ++gcry_mpi_get_opaque (gcry_mpi_t a, unsigned int *nbits) ++{ ++ return _gcry_mpi_get_opaque (a, nbits); ++} ++ ++void ++gcry_mpi_set_flag (gcry_mpi_t a, enum gcry_mpi_flag flag) ++{ ++ _gcry_mpi_set_flag (a, flag); ++} ++ ++void ++gcry_mpi_clear_flag (gcry_mpi_t a, enum gcry_mpi_flag flag) ++{ ++ _gcry_mpi_clear_flag (a, flag); ++} ++ ++int ++gcry_mpi_get_flag (gcry_mpi_t a, enum gcry_mpi_flag flag) ++{ ++ return _gcry_mpi_get_flag (a, flag); ++} ++ ++gcry_error_t ++gcry_cipher_open (gcry_cipher_hd_t *handle, ++ int algo, int mode, unsigned int flags) ++{ ++ if (!fips_is_operational ()) ++ { ++ *handle = NULL; ++ return gpg_error (fips_not_operational ()); ++ } ++ ++ return _gcry_cipher_open (handle, algo, mode, flags); ++} ++ ++void ++gcry_cipher_close (gcry_cipher_hd_t h) ++{ ++ _gcry_cipher_close (h); ++} ++ ++gcry_error_t ++gcry_cipher_setkey (gcry_cipher_hd_t hd, const void *key, size_t keylen) ++{ ++ if (!fips_is_operational ()) ++ return gpg_error (fips_not_operational ()); ++ ++ return _gcry_cipher_setkey (hd, key, keylen); ++} ++ ++gcry_error_t ++gcry_cipher_setiv (gcry_cipher_hd_t hd, const void *iv, size_t ivlen) ++{ ++ if (!fips_is_operational ()) ++ return gpg_error (fips_not_operational ()); ++ ++ return _gcry_cipher_setiv (hd, iv, ivlen); ++} ++ ++gpg_error_t ++gcry_cipher_setctr (gcry_cipher_hd_t hd, const void *ctr, size_t ctrlen) ++{ ++ if (!fips_is_operational ()) ++ return gpg_error (fips_not_operational ()); ++ ++ return _gcry_cipher_setctr (hd, ctr, ctrlen); ++} ++ ++ ++gcry_error_t ++gcry_cipher_ctl (gcry_cipher_hd_t h, int cmd, void *buffer, size_t buflen) ++{ ++ if (!fips_is_operational ()) ++ return gpg_error (fips_not_operational ()); ++ ++ return _gcry_cipher_ctl (h, cmd, buffer, buflen); ++} ++ ++gcry_error_t ++gcry_cipher_info (gcry_cipher_hd_t h, int what, void *buffer, size_t *nbytes) ++{ ++ return _gcry_cipher_info (h, what, buffer, nbytes); ++} ++ ++gcry_error_t ++gcry_cipher_algo_info (int algo, int what, void *buffer, size_t *nbytes) ++{ ++ if (!fips_is_operational ()) ++ return gpg_error (fips_not_operational ()); ++ ++ return _gcry_cipher_algo_info (algo, what, buffer, nbytes); ++} ++ ++const char * ++gcry_cipher_algo_name (int algorithm) ++{ ++ return _gcry_cipher_algo_name (algorithm); ++} ++ ++int ++gcry_cipher_map_name (const char *name) ++{ ++ return _gcry_cipher_map_name (name); ++} ++ ++int ++gcry_cipher_mode_from_oid (const char *string) ++{ ++ return _gcry_cipher_mode_from_oid (string); ++} ++ ++gcry_error_t ++gcry_cipher_encrypt (gcry_cipher_hd_t h, ++ void *out, size_t outsize, ++ const void *in, size_t inlen) ++{ ++ if (!fips_is_operational ()) ++ { ++ /* Make sure that the plaintext will never make it to OUT. */ ++ if (out) ++ memset (out, 0x42, outsize); ++ return gpg_error (fips_not_operational ()); ++ } ++ ++ return _gcry_cipher_encrypt (h, out, outsize, in, inlen); ++} ++ ++gcry_error_t ++gcry_cipher_decrypt (gcry_cipher_hd_t h, ++ void *out, size_t outsize, ++ const void *in, size_t inlen) ++{ ++ if (!fips_is_operational ()) ++ return gpg_error (fips_not_operational ()); ++ ++ return _gcry_cipher_decrypt (h, out, outsize, in, inlen); ++} ++ ++size_t ++gcry_cipher_get_algo_keylen (int algo) ++{ ++ return _gcry_cipher_get_algo_keylen (algo); ++} ++ ++size_t ++gcry_cipher_get_algo_blklen (int algo) ++{ ++ return _gcry_cipher_get_algo_blklen (algo); ++} ++ ++gcry_error_t ++gcry_pk_encrypt (gcry_sexp_t *result, gcry_sexp_t data, gcry_sexp_t pkey) ++{ ++ if (!fips_is_operational ()) ++ { ++ *result = NULL; ++ return gpg_error (fips_not_operational ()); ++ } ++ return _gcry_pk_encrypt (result, data, pkey); ++} ++ ++gcry_error_t ++gcry_pk_decrypt (gcry_sexp_t *result, gcry_sexp_t data, gcry_sexp_t skey) ++{ ++ if (!fips_is_operational ()) ++ { ++ *result = NULL; ++ return gpg_error (fips_not_operational ()); ++ } ++ return _gcry_pk_decrypt (result, data, skey); ++} ++ ++gcry_error_t ++gcry_pk_sign (gcry_sexp_t *result, gcry_sexp_t data, gcry_sexp_t skey) ++{ ++ if (!fips_is_operational ()) ++ { ++ *result = NULL; ++ return gpg_error (fips_not_operational ()); ++ } ++ return _gcry_pk_sign (result, data, skey); ++} ++ ++gcry_error_t ++gcry_pk_verify (gcry_sexp_t sigval, gcry_sexp_t data, gcry_sexp_t pkey) ++{ ++ if (!fips_is_operational ()) ++ return gpg_error (fips_not_operational ()); ++ return _gcry_pk_verify (sigval, data, pkey); ++} ++ ++gcry_error_t ++gcry_pk_testkey (gcry_sexp_t key) ++{ ++ if (!fips_is_operational ()) ++ return gpg_error (fips_not_operational ()); ++ return _gcry_pk_testkey (key); ++} ++ ++gcry_error_t ++gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms) ++{ ++ if (!fips_is_operational ()) ++ { ++ *r_key = NULL; ++ return gpg_error (fips_not_operational ()); ++ } ++ return _gcry_pk_genkey (r_key, s_parms); ++} ++ ++gcry_error_t ++gcry_pk_ctl (int cmd, void *buffer, size_t buflen) ++{ ++ return _gcry_pk_ctl (cmd, buffer, buflen); ++} ++ ++gcry_error_t ++gcry_pk_algo_info (int algo, int what, void *buffer, size_t *nbytes) ++{ ++ if (!fips_is_operational ()) ++ return gpg_error (fips_not_operational ()); ++ ++ return _gcry_pk_algo_info (algo, what, buffer, nbytes); ++} ++ ++const char * ++gcry_pk_algo_name (int algorithm) ++{ ++ return _gcry_pk_algo_name (algorithm); ++} ++ ++int ++gcry_pk_map_name (const char *name) ++{ ++ return _gcry_pk_map_name (name); ++} ++ ++unsigned int ++gcry_pk_get_nbits (gcry_sexp_t key) ++{ ++ if (!fips_is_operational ()) ++ { ++ (void)fips_not_operational (); ++ return 0; ++ } ++ ++ return _gcry_pk_get_nbits (key); ++} ++ ++unsigned char * ++gcry_pk_get_keygrip (gcry_sexp_t key, unsigned char *array) ++{ ++ if (!fips_is_operational ()) ++ { ++ (void)fips_not_operational (); ++ return NULL; ++ } ++ return _gcry_pk_get_keygrip (key, array); ++} ++ ++const char * ++gcry_pk_get_curve (gcry_sexp_t key, int iterator, unsigned int *r_nbits) ++{ ++ if (!fips_is_operational ()) ++ { ++ (void)fips_not_operational (); ++ return NULL; ++ } ++ return _gcry_pk_get_curve (key, iterator, r_nbits); ++} ++ ++gcry_sexp_t ++gcry_pk_get_param (int algo, const char *name) ++{ ++ if (!fips_is_operational ()) ++ { ++ (void)fips_not_operational (); ++ return NULL; ++ } ++ return _gcry_pk_get_param (algo, name); ++} ++ ++gcry_error_t ++gcry_md_open (gcry_md_hd_t *h, int algo, unsigned int flags) ++{ ++ if (!fips_is_operational ()) ++ { ++ *h = NULL; ++ return gpg_error (fips_not_operational ()); ++ } ++ ++ return _gcry_md_open (h, algo, flags); ++} ++ ++void ++gcry_md_close (gcry_md_hd_t hd) ++{ ++ _gcry_md_close (hd); ++} ++ ++gcry_error_t ++gcry_md_enable (gcry_md_hd_t hd, int algo) ++{ ++ if (!fips_is_operational ()) ++ return gpg_error (fips_not_operational ()); ++ return _gcry_md_enable (hd, algo); ++} ++ ++gcry_error_t ++gcry_md_copy (gcry_md_hd_t *bhd, gcry_md_hd_t ahd) ++{ ++ if (!fips_is_operational ()) ++ { ++ *bhd = NULL; ++ return gpg_error (fips_not_operational ()); ++ } ++ return _gcry_md_copy (bhd, ahd); ++} ++ ++void ++gcry_md_reset (gcry_md_hd_t hd) ++{ ++ _gcry_md_reset (hd); ++} ++ ++gcry_error_t ++gcry_md_ctl (gcry_md_hd_t hd, int cmd, void *buffer, size_t buflen) ++{ ++ if (!fips_is_operational ()) ++ return gpg_error (fips_not_operational ()); ++ return _gcry_md_ctl (hd, cmd, buffer, buflen); ++} ++ ++void ++gcry_md_write (gcry_md_hd_t hd, const void *buffer, size_t length) ++{ ++ if (!fips_is_operational ()) ++ { ++ (void)fips_not_operational (); ++ return; ++ } ++ _gcry_md_write (hd, buffer, length); ++} ++ ++unsigned char * ++gcry_md_read (gcry_md_hd_t hd, int algo) ++{ ++ return _gcry_md_read (hd, algo); ++} ++ ++void ++gcry_md_hash_buffer (int algo, void *digest, ++ const void *buffer, size_t length) ++{ ++ if (!fips_is_operational ()) ++ { ++ (void)fips_not_operational (); ++ fips_signal_error ("called in non-operational state"); ++ } ++ _gcry_md_hash_buffer (algo, digest, buffer, length); ++} ++ ++int ++gcry_md_get_algo (gcry_md_hd_t hd) ++{ ++ if (!fips_is_operational ()) ++ { ++ (void)fips_not_operational (); ++ fips_signal_error ("used in non-operational state"); ++ return 0; ++ } ++ return _gcry_md_get_algo (hd); ++} ++ ++unsigned int ++gcry_md_get_algo_dlen (int algo) ++{ ++ return _gcry_md_get_algo_dlen (algo); ++} ++ ++int ++gcry_md_is_enabled (gcry_md_hd_t a, int algo) ++{ ++ if (!fips_is_operational ()) ++ { ++ (void)fips_not_operational (); ++ return 0; ++ } ++ ++ return _gcry_md_is_enabled (a, algo); ++} ++ ++int ++gcry_md_is_secure (gcry_md_hd_t a) ++{ ++ return _gcry_md_is_secure (a); ++} ++ ++gcry_error_t ++gcry_md_info (gcry_md_hd_t h, int what, void *buffer, size_t *nbytes) ++{ ++ if (!fips_is_operational ()) ++ return gpg_error (fips_not_operational ()); ++ ++ return _gcry_md_info (h, what, buffer, nbytes); ++} ++ ++gcry_error_t ++gcry_md_algo_info (int algo, int what, void *buffer, size_t *nbytes) ++{ ++ return _gcry_md_algo_info (algo, what, buffer, nbytes); ++} ++ ++const char * ++gcry_md_algo_name (int algo) ++{ ++ return _gcry_md_algo_name (algo); ++} ++ ++int ++gcry_md_map_name (const char* name) ++{ ++ return _gcry_md_map_name (name); ++} ++ ++gcry_error_t ++gcry_md_setkey (gcry_md_hd_t hd, const void *key, size_t keylen) ++{ ++ if (!fips_is_operational ()) ++ return gpg_error (fips_not_operational ()); ++ return _gcry_md_setkey (hd, key, keylen); ++} ++ ++void ++gcry_md_debug (gcry_md_hd_t hd, const char *suffix) ++{ ++ _gcry_md_debug (hd, suffix); ++} ++ ++gpg_error_t ++gcry_kdf_derive (const void *passphrase, size_t passphraselen, ++ int algo, int hashalgo, ++ const void *salt, size_t saltlen, ++ unsigned long iterations, ++ size_t keysize, void *keybuffer) ++{ ++ return _gcry_kdf_derive (passphrase, passphraselen, algo, hashalgo, ++ salt, saltlen, iterations, keysize, keybuffer); ++} ++ ++void ++gcry_randomize (void *buffer, size_t length, enum gcry_random_level level) ++{ ++ if (!fips_is_operational ()) ++ { ++ (void)fips_not_operational (); ++ fips_signal_fatal_error ("called in non-operational state"); ++ fips_noreturn (); ++ } ++ _gcry_randomize (buffer, length, level); ++} ++ ++gcry_error_t ++gcry_random_add_bytes (const void *buffer, size_t length, int quality) ++{ ++ if (!fips_is_operational ()) ++ return gpg_error (fips_not_operational ()); ++ return _gcry_random_add_bytes (buffer, length, quality); ++} ++ ++void * ++gcry_random_bytes (size_t nbytes, enum gcry_random_level level) ++{ ++ if (!fips_is_operational ()) ++ { ++ (void)fips_not_operational (); ++ fips_signal_fatal_error ("called in non-operational state"); ++ fips_noreturn (); ++ } ++ ++ return _gcry_random_bytes (nbytes,level); ++} ++ ++void * ++gcry_random_bytes_secure (size_t nbytes, enum gcry_random_level level) ++{ ++ if (!fips_is_operational ()) ++ { ++ (void)fips_not_operational (); ++ fips_signal_fatal_error ("called in non-operational state"); ++ fips_noreturn (); ++ } ++ ++ return _gcry_random_bytes_secure (nbytes, level); ++} ++ ++void ++gcry_mpi_randomize (gcry_mpi_t w, ++ unsigned int nbits, enum gcry_random_level level) ++{ ++ _gcry_mpi_randomize (w, nbits, level); ++} ++ ++void ++gcry_create_nonce (void *buffer, size_t length) ++{ ++ if (!fips_is_operational ()) ++ { ++ (void)fips_not_operational (); ++ fips_signal_fatal_error ("called in non-operational state"); ++ fips_noreturn (); ++ } ++ _gcry_create_nonce (buffer, length); ++} ++ ++gcry_error_t ++gcry_prime_generate (gcry_mpi_t *prime, ++ unsigned int prime_bits, ++ unsigned int factor_bits, ++ gcry_mpi_t **factors, ++ gcry_prime_check_func_t cb_func, ++ void *cb_arg, ++ gcry_random_level_t random_level, ++ unsigned int flags) ++{ ++ return _gcry_prime_generate (prime, prime_bits, factor_bits, factors, ++ cb_func, cb_arg, random_level, flags); ++} ++ ++gcry_error_t ++gcry_prime_group_generator (gcry_mpi_t *r_g, ++ gcry_mpi_t prime, gcry_mpi_t *factors, ++ gcry_mpi_t start_g) ++{ ++ return _gcry_prime_group_generator (r_g, prime, factors, start_g); ++} ++ ++void ++gcry_prime_release_factors (gcry_mpi_t *factors) ++{ ++ _gcry_prime_release_factors (factors); ++} ++ ++gcry_error_t ++gcry_prime_check (gcry_mpi_t x, unsigned int flags) ++{ ++ return _gcry_prime_check (x, flags); ++} ++ ++void ++gcry_set_progress_handler (gcry_handler_progress_t cb, void *cb_data) ++{ ++ _gcry_set_progress_handler (cb, cb_data); ++} ++ ++void ++gcry_set_allocation_handler (gcry_handler_alloc_t func_alloc, ++ gcry_handler_alloc_t func_alloc_secure, ++ gcry_handler_secure_check_t func_secure_check, ++ gcry_handler_realloc_t func_realloc, ++ gcry_handler_free_t func_free) ++{ ++ _gcry_set_allocation_handler (func_alloc, func_alloc_secure, ++ func_secure_check, func_realloc, func_free); ++} ++ ++void ++gcry_set_outofcore_handler (gcry_handler_no_mem_t h, void *opaque) ++{ ++ _gcry_set_outofcore_handler (h, opaque); ++} ++ ++void ++gcry_set_fatalerror_handler (gcry_handler_error_t fnc, void *opaque) ++{ ++ _gcry_set_fatalerror_handler (fnc, opaque); ++} ++ ++void ++gcry_set_log_handler (gcry_handler_log_t f, void *opaque) ++{ ++ _gcry_set_log_handler (f, opaque); ++} ++ ++void ++gcry_set_gettext_handler (const char *(*f)(const char*)) ++{ ++ _gcry_set_gettext_handler (f); ++} ++ ++void * ++gcry_malloc (size_t n) ++{ ++ return _gcry_malloc (n); ++} ++ ++void * ++gcry_calloc (size_t n, size_t m) ++{ ++ return _gcry_calloc (n, m); ++} ++ ++void * ++gcry_malloc_secure (size_t n) ++{ ++ return _gcry_malloc_secure (n); ++} ++ ++void * ++gcry_calloc_secure (size_t n, size_t m) ++{ ++ return _gcry_calloc_secure (n,m); ++} ++ ++void * ++gcry_realloc (void *a, size_t n) ++{ ++ return _gcry_realloc (a, n); ++} ++ ++char * ++gcry_strdup (const char *string) ++{ ++ return _gcry_strdup (string); ++} ++ ++void * ++gcry_xmalloc (size_t n) ++{ ++ return _gcry_xmalloc (n); ++} ++ ++void * ++gcry_xcalloc (size_t n, size_t m) ++{ ++ return _gcry_xcalloc (n, m); ++} ++ ++void * ++gcry_xmalloc_secure (size_t n) ++{ ++ return _gcry_xmalloc_secure (n); ++} ++ ++void * ++gcry_xcalloc_secure (size_t n, size_t m) ++{ ++ return _gcry_xcalloc_secure (n, m); ++} ++ ++void * ++gcry_xrealloc (void *a, size_t n) ++{ ++ return _gcry_xrealloc (a, n); ++} ++ ++char * ++gcry_xstrdup (const char *a) ++{ ++ return _gcry_xstrdup (a); ++} ++ ++void ++gcry_free (void *a) ++{ ++ _gcry_free (a); ++} ++ ++int ++gcry_is_secure (const void *a) ++{ ++ return _gcry_is_secure (a); ++} +diff --git a/grub-core/lib/libgcrypt/src/visibility.h b/grub-core/lib/libgcrypt/src/visibility.h +new file mode 100644 +index 0000000..4606a20 +--- /dev/null ++++ b/grub-core/lib/libgcrypt/src/visibility.h +@@ -0,0 +1,565 @@ ++/* visibility.h - Set visibility attribute ++ * Copyright (C) 2007 Free Software Foundation, Inc. ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. ++ * ++ * Libgcrypt 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program; if not, see . ++ */ ++ ++#ifndef GCRY_VISIBILITY_H ++#define GCRY_VISIBILITY_H ++ ++/* Redefine all public symbols with an underscore unless we already ++ use the underscore prefixed version internally. */ ++#define gcry_check_version _gcry_check_version ++#define gcry_control _gcry_control ++ ++#define gcry_set_allocation_handler _gcry_set_allocation_handler ++#define gcry_set_fatalerror_handler _gcry_set_fatalerror_handler ++#define gcry_set_gettext_handler _gcry_set_gettext_handler ++#define gcry_set_log_handler _gcry_set_log_handler ++#define gcry_set_outofcore_handler _gcry_set_outofcore_handler ++#define gcry_set_progress_handler _gcry_set_progress_handler ++#define gcry_err_code_from_errno _gcry_err_code_from_errno ++#define gcry_err_code_to_errno _gcry_err_code_to_errno ++#define gcry_err_make_from_errno _gcry_err_make_from_errno ++#define gcry_error_from_errno _gcry_error_from_errno ++#define gcry_strerror _gcry_strerror ++#define gcry_strsource _gcry_strsource ++ ++#define gcry_free _gcry_free ++#define gcry_malloc _gcry_malloc ++#define gcry_malloc_secure _gcry_malloc_secure ++#define gcry_calloc _gcry_calloc ++#define gcry_calloc_secure _gcry_calloc_secure ++#define gcry_realloc _gcry_realloc ++#define gcry_strdup _gcry_strdup ++#define gcry_is_secure _gcry_is_secure ++#define gcry_xcalloc _gcry_xcalloc ++#define gcry_xcalloc_secure _gcry_xcalloc_secure ++#define gcry_xmalloc _gcry_xmalloc ++#define gcry_xmalloc_secure _gcry_xmalloc_secure ++#define gcry_xrealloc _gcry_xrealloc ++#define gcry_xstrdup _gcry_xstrdup ++ ++#define gcry_md_algo_info _gcry_md_algo_info ++#define gcry_md_algo_name _gcry_md_algo_name ++#define gcry_md_close _gcry_md_close ++#define gcry_md_copy _gcry_md_copy ++#define gcry_md_ctl _gcry_md_ctl ++#define gcry_md_enable _gcry_md_enable ++#define gcry_md_get _gcry_md_get ++#define gcry_md_get_algo _gcry_md_get_algo ++#define gcry_md_get_algo_dlen _gcry_md_get_algo_dlen ++#define gcry_md_hash_buffer _gcry_md_hash_buffer ++#define gcry_md_info _gcry_md_info ++#define gcry_md_is_enabled _gcry_md_is_enabled ++#define gcry_md_is_secure _gcry_md_is_secure ++#define gcry_md_map_name _gcry_md_map_name ++#define gcry_md_open _gcry_md_open ++#define gcry_md_read _gcry_md_read ++#define gcry_md_reset _gcry_md_reset ++#define gcry_md_setkey _gcry_md_setkey ++#define gcry_md_write _gcry_md_write ++#define gcry_md_debug _gcry_md_debug ++ ++#define gcry_cipher_algo_info _gcry_cipher_algo_info ++#define gcry_cipher_algo_name _gcry_cipher_algo_name ++#define gcry_cipher_close _gcry_cipher_close ++#define gcry_cipher_setkey _gcry_cipher_setkey ++#define gcry_cipher_setiv _gcry_cipher_setiv ++#define gcry_cipher_setctr _gcry_cipher_setctr ++#define gcry_cipher_ctl _gcry_cipher_ctl ++#define gcry_cipher_decrypt _gcry_cipher_decrypt ++#define gcry_cipher_encrypt _gcry_cipher_encrypt ++#define gcry_cipher_get_algo_blklen _gcry_cipher_get_algo_blklen ++#define gcry_cipher_get_algo_keylen _gcry_cipher_get_algo_keylen ++#define gcry_cipher_info _gcry_cipher_info ++#define gcry_cipher_map_name _gcry_cipher_map_name ++#define gcry_cipher_mode_from_oid _gcry_cipher_mode_from_oid ++#define gcry_cipher_open _gcry_cipher_open ++ ++#define gcry_pk_algo_info _gcry_pk_algo_info ++#define gcry_pk_algo_name _gcry_pk_algo_name ++#define gcry_pk_ctl _gcry_pk_ctl ++#define gcry_pk_decrypt _gcry_pk_decrypt ++#define gcry_pk_encrypt _gcry_pk_encrypt ++#define gcry_pk_genkey _gcry_pk_genkey ++#define gcry_pk_get_keygrip _gcry_pk_get_keygrip ++#define gcry_pk_get_curve _gcry_pk_get_curve ++#define gcry_pk_get_param _gcry_pk_get_param ++#define gcry_pk_get_nbits _gcry_pk_get_nbits ++#define gcry_pk_map_name _gcry_pk_map_name ++#define gcry_pk_sign _gcry_pk_sign ++#define gcry_pk_testkey _gcry_pk_testkey ++#define gcry_pk_verify _gcry_pk_verify ++ ++#define gcry_kdf_derive _gcry_kdf_derive ++ ++#define gcry_prime_check _gcry_prime_check ++#define gcry_prime_generate _gcry_prime_generate ++#define gcry_prime_group_generator _gcry_prime_group_generator ++#define gcry_prime_release_factors _gcry_prime_release_factors ++ ++#define gcry_random_add_bytes _gcry_random_add_bytes ++#define gcry_random_bytes _gcry_random_bytes ++#define gcry_random_bytes_secure _gcry_random_bytes_secure ++#define gcry_randomize _gcry_randomize ++#define gcry_create_nonce _gcry_create_nonce ++ ++#define gcry_sexp_alist _gcry_sexp_alist ++#define gcry_sexp_append _gcry_sexp_append ++#define gcry_sexp_build _gcry_sexp_build ++#define gcry_sexp_build_array _gcry_sexp_build_array ++#define gcry_sexp_cadr _gcry_sexp_cadr ++#define gcry_sexp_canon_len _gcry_sexp_canon_len ++#define gcry_sexp_car _gcry_sexp_car ++#define gcry_sexp_cdr _gcry_sexp_cdr ++#define gcry_sexp_cons _gcry_sexp_cons ++#define gcry_sexp_create _gcry_sexp_create ++#define gcry_sexp_dump _gcry_sexp_dump ++#define gcry_sexp_find_token _gcry_sexp_find_token ++#define gcry_sexp_length _gcry_sexp_length ++#define gcry_sexp_new _gcry_sexp_new ++#define gcry_sexp_nth _gcry_sexp_nth ++#define gcry_sexp_nth_data _gcry_sexp_nth_data ++#define gcry_sexp_nth_mpi _gcry_sexp_nth_mpi ++#define gcry_sexp_prepend _gcry_sexp_prepend ++#define gcry_sexp_release _gcry_sexp_release ++#define gcry_sexp_sprint _gcry_sexp_sprint ++#define gcry_sexp_sscan _gcry_sexp_sscan ++#define gcry_sexp_vlist _gcry_sexp_vlist ++#define gcry_sexp_nth_string _gcry_sexp_nth_string ++ ++#define gcry_mpi_add _gcry_mpi_add ++#define gcry_mpi_add_ui _gcry_mpi_add_ui ++#define gcry_mpi_addm _gcry_mpi_addm ++#define gcry_mpi_aprint _gcry_mpi_aprint ++#define gcry_mpi_clear_bit _gcry_mpi_clear_bit ++#define gcry_mpi_clear_flag _gcry_mpi_clear_flag ++#define gcry_mpi_clear_highbit _gcry_mpi_clear_highbit ++#define gcry_mpi_cmp _gcry_mpi_cmp ++#define gcry_mpi_cmp_ui _gcry_mpi_cmp_ui ++#define gcry_mpi_copy _gcry_mpi_copy ++#define gcry_mpi_div _gcry_mpi_div ++#define gcry_mpi_dump _gcry_mpi_dump ++#define gcry_mpi_gcd _gcry_mpi_gcd ++#define gcry_mpi_get_flag _gcry_mpi_get_flag ++#define gcry_mpi_get_nbits _gcry_mpi_get_nbits ++#define gcry_mpi_get_opaque _gcry_mpi_get_opaque ++#define gcry_mpi_invm _gcry_mpi_invm ++#define gcry_mpi_mod _gcry_mpi_mod ++#define gcry_mpi_mul _gcry_mpi_mul ++#define gcry_mpi_mul_2exp _gcry_mpi_mul_2exp ++#define gcry_mpi_mul_ui _gcry_mpi_mul_ui ++#define gcry_mpi_mulm _gcry_mpi_mulm ++#define gcry_mpi_new _gcry_mpi_new ++#define gcry_mpi_powm _gcry_mpi_powm ++#define gcry_mpi_print _gcry_mpi_print ++#define gcry_mpi_randomize _gcry_mpi_randomize ++#define gcry_mpi_release _gcry_mpi_release ++#define gcry_mpi_rshift _gcry_mpi_rshift ++#define gcry_mpi_lshift _gcry_mpi_lshift ++#define gcry_mpi_scan _gcry_mpi_scan ++#define gcry_mpi_set _gcry_mpi_set ++#define gcry_mpi_set_bit _gcry_mpi_set_bit ++#define gcry_mpi_set_flag _gcry_mpi_set_flag ++#define gcry_mpi_set_highbit _gcry_mpi_set_highbit ++#define gcry_mpi_set_opaque _gcry_mpi_set_opaque ++#define gcry_mpi_set_ui _gcry_mpi_set_ui ++#define gcry_mpi_snew _gcry_mpi_snew ++#define gcry_mpi_sub _gcry_mpi_sub ++#define gcry_mpi_sub_ui _gcry_mpi_sub_ui ++#define gcry_mpi_subm _gcry_mpi_subm ++#define gcry_mpi_swap _gcry_mpi_swap ++#define gcry_mpi_test_bit _gcry_mpi_test_bit ++ ++ ++/* Include the main header here so that public symbols are mapped to ++ the internal underscored ones. */ ++#ifdef _GCRY_INCLUDED_BY_VISIBILITY_C ++ /* We need to redeclare the deprecated functions without the ++ deprecated attribute. */ ++# define GCRYPT_NO_DEPRECATED ++# include "gcrypt.h" ++ /* None in this version. */ ++#else ++# include "gcrypt.h" ++#endif ++#include "gcrypt-module.h" ++ ++/* Prototypes of functions exported but not ready for use. */ ++gcry_err_code_t gcry_md_get (gcry_md_hd_t hd, int algo, ++ unsigned char *buffer, int buflen); ++ ++ ++/* Our use of the ELF visibility feature works by passing ++ -fvisibiliy=hidden on the command line and by explicitly marking ++ all exported functions as visible. ++ ++ NOTE: When adding new functions, please make sure to add them to ++ libgcrypt.vers and libgcrypt.def as well. */ ++ ++#ifdef _GCRY_INCLUDED_BY_VISIBILITY_C ++ ++/* A macro to flag a function as visible. Note that we take the ++ definition from the mapped name. */ ++#ifdef GCRY_USE_VISIBILITY ++# define MARK_VISIBLE(name) \ ++ extern __typeof__ (_##name) name __attribute__ ((visibility("default"))); ++# define MARK_VISIBLEX(name) \ ++ extern __typeof__ (name) name __attribute__ ((visibility("default"))); ++#else ++# define MARK_VISIBLE(name) /* */ ++# define MARK_VISIBLEX(name) /* */ ++#endif ++ ++ ++/* First undef all redefined symbols so that we set the attribute on ++ the correct version name. */ ++#undef gcry_check_version ++#undef gcry_control ++ ++#undef gcry_set_allocation_handler ++#undef gcry_set_fatalerror_handler ++#undef gcry_set_gettext_handler ++#undef gcry_set_log_handler ++#undef gcry_set_outofcore_handler ++#undef gcry_set_progress_handler ++#undef gcry_err_code_from_errno ++#undef gcry_err_code_to_errno ++#undef gcry_err_make_from_errno ++#undef gcry_error_from_errno ++#undef gcry_strerror ++#undef gcry_strsource ++ ++#undef gcry_free ++#undef gcry_malloc ++#undef gcry_malloc_secure ++#undef gcry_calloc ++#undef gcry_calloc_secure ++#undef gcry_realloc ++#undef gcry_strdup ++#undef gcry_is_secure ++#undef gcry_xcalloc ++#undef gcry_xcalloc_secure ++#undef gcry_xmalloc ++#undef gcry_xmalloc_secure ++#undef gcry_xrealloc ++#undef gcry_xstrdup ++ ++#undef gcry_md_algo_info ++#undef gcry_md_algo_name ++#undef gcry_md_close ++#undef gcry_md_copy ++#undef gcry_md_ctl ++#undef gcry_md_enable ++#undef gcry_md_get ++#undef gcry_md_get_algo ++#undef gcry_md_get_algo_dlen ++#undef gcry_md_hash_buffer ++#undef gcry_md_info ++#undef gcry_md_is_enabled ++#undef gcry_md_is_secure ++#undef gcry_md_map_name ++#undef gcry_md_open ++#undef gcry_md_read ++#undef gcry_md_reset ++#undef gcry_md_setkey ++#undef gcry_md_write ++#undef gcry_md_debug ++ ++#undef gcry_cipher_algo_info ++#undef gcry_cipher_algo_name ++#undef gcry_cipher_close ++#undef gcry_cipher_setkey ++#undef gcry_cipher_setiv ++#undef gcry_cipher_setctr ++#undef gcry_cipher_ctl ++#undef gcry_cipher_decrypt ++#undef gcry_cipher_encrypt ++#undef gcry_cipher_get_algo_blklen ++#undef gcry_cipher_get_algo_keylen ++#undef gcry_cipher_info ++#undef gcry_cipher_map_name ++#undef gcry_cipher_mode_from_oid ++#undef gcry_cipher_open ++ ++#undef gcry_pk_algo_info ++#undef gcry_pk_algo_name ++#undef gcry_pk_ctl ++#undef gcry_pk_decrypt ++#undef gcry_pk_encrypt ++#undef gcry_pk_genkey ++#undef gcry_pk_get_keygrip ++#undef gcry_pk_get_curve ++#undef gcry_pk_get_param ++#undef gcry_pk_get_nbits ++#undef gcry_pk_map_name ++#undef gcry_pk_sign ++#undef gcry_pk_testkey ++#undef gcry_pk_verify ++ ++#undef gcry_kdf_derive ++ ++#undef gcry_prime_check ++#undef gcry_prime_generate ++#undef gcry_prime_group_generator ++#undef gcry_prime_release_factors ++ ++#undef gcry_random_add_bytes ++#undef gcry_random_bytes ++#undef gcry_random_bytes_secure ++#undef gcry_randomize ++#undef gcry_create_nonce ++ ++#undef gcry_sexp_alist ++#undef gcry_sexp_append ++#undef gcry_sexp_build ++#undef gcry_sexp_build_array ++#undef gcry_sexp_cadr ++#undef gcry_sexp_canon_len ++#undef gcry_sexp_car ++#undef gcry_sexp_cdr ++#undef gcry_sexp_cons ++#undef gcry_sexp_create ++#undef gcry_sexp_dump ++#undef gcry_sexp_find_token ++#undef gcry_sexp_length ++#undef gcry_sexp_new ++#undef gcry_sexp_nth ++#undef gcry_sexp_nth_data ++#undef gcry_sexp_nth_mpi ++#undef gcry_sexp_prepend ++#undef gcry_sexp_release ++#undef gcry_sexp_sprint ++#undef gcry_sexp_sscan ++#undef gcry_sexp_vlist ++#undef gcry_sexp_nth_string ++ ++#undef gcry_mpi_add ++#undef gcry_mpi_add_ui ++#undef gcry_mpi_addm ++#undef gcry_mpi_aprint ++#undef gcry_mpi_clear_bit ++#undef gcry_mpi_clear_flag ++#undef gcry_mpi_clear_highbit ++#undef gcry_mpi_cmp ++#undef gcry_mpi_cmp_ui ++#undef gcry_mpi_copy ++#undef gcry_mpi_div ++#undef gcry_mpi_dump ++#undef gcry_mpi_gcd ++#undef gcry_mpi_get_flag ++#undef gcry_mpi_get_nbits ++#undef gcry_mpi_get_opaque ++#undef gcry_mpi_invm ++#undef gcry_mpi_mod ++#undef gcry_mpi_mul ++#undef gcry_mpi_mul_2exp ++#undef gcry_mpi_mul_ui ++#undef gcry_mpi_mulm ++#undef gcry_mpi_new ++#undef gcry_mpi_powm ++#undef gcry_mpi_print ++#undef gcry_mpi_randomize ++#undef gcry_mpi_release ++#undef gcry_mpi_rshift ++#undef gcry_mpi_lshift ++#undef gcry_mpi_scan ++#undef gcry_mpi_set ++#undef gcry_mpi_set_bit ++#undef gcry_mpi_set_flag ++#undef gcry_mpi_set_highbit ++#undef gcry_mpi_set_opaque ++#undef gcry_mpi_set_ui ++#undef gcry_mpi_snew ++#undef gcry_mpi_sub ++#undef gcry_mpi_sub_ui ++#undef gcry_mpi_subm ++#undef gcry_mpi_swap ++#undef gcry_mpi_test_bit ++ ++ ++/* Now mark all symbols. */ ++ ++MARK_VISIBLE (gcry_check_version) ++MARK_VISIBLE (gcry_control) ++ ++MARK_VISIBLE (gcry_set_allocation_handler) ++MARK_VISIBLE (gcry_set_fatalerror_handler) ++MARK_VISIBLE (gcry_set_gettext_handler) ++MARK_VISIBLE (gcry_set_log_handler) ++MARK_VISIBLE (gcry_set_outofcore_handler) ++MARK_VISIBLE (gcry_set_progress_handler) ++MARK_VISIBLE (gcry_err_code_from_errno) ++MARK_VISIBLE (gcry_err_code_to_errno) ++MARK_VISIBLE (gcry_err_make_from_errno) ++MARK_VISIBLE (gcry_error_from_errno) ++MARK_VISIBLE (gcry_strerror) ++MARK_VISIBLE (gcry_strsource) ++ ++MARK_VISIBLE (gcry_free) ++MARK_VISIBLE (gcry_malloc) ++MARK_VISIBLE (gcry_malloc_secure) ++MARK_VISIBLE (gcry_calloc) ++MARK_VISIBLE (gcry_calloc_secure) ++MARK_VISIBLE (gcry_realloc) ++MARK_VISIBLE (gcry_strdup) ++MARK_VISIBLE (gcry_is_secure) ++MARK_VISIBLE (gcry_xcalloc) ++MARK_VISIBLE (gcry_xcalloc_secure) ++MARK_VISIBLE (gcry_xmalloc) ++MARK_VISIBLE (gcry_xmalloc_secure) ++MARK_VISIBLE (gcry_xrealloc) ++MARK_VISIBLE (gcry_xstrdup) ++ ++MARK_VISIBLE (gcry_md_algo_info) ++MARK_VISIBLE (gcry_md_algo_name) ++MARK_VISIBLE (gcry_md_close) ++MARK_VISIBLE (gcry_md_copy) ++MARK_VISIBLE (gcry_md_ctl) ++MARK_VISIBLE (gcry_md_enable) ++MARK_VISIBLE (gcry_md_get) ++MARK_VISIBLE (gcry_md_get_algo) ++MARK_VISIBLE (gcry_md_get_algo_dlen) ++MARK_VISIBLE (gcry_md_hash_buffer) ++MARK_VISIBLE (gcry_md_info) ++MARK_VISIBLE (gcry_md_is_enabled) ++MARK_VISIBLE (gcry_md_is_secure) ++MARK_VISIBLE (gcry_md_map_name) ++MARK_VISIBLE (gcry_md_open) ++MARK_VISIBLE (gcry_md_read) ++MARK_VISIBLE (gcry_md_reset) ++MARK_VISIBLE (gcry_md_setkey) ++MARK_VISIBLE (gcry_md_write) ++MARK_VISIBLE (gcry_md_debug) ++ ++MARK_VISIBLE (gcry_cipher_algo_info) ++MARK_VISIBLE (gcry_cipher_algo_name) ++MARK_VISIBLE (gcry_cipher_close) ++MARK_VISIBLE (gcry_cipher_setkey) ++MARK_VISIBLE (gcry_cipher_setiv) ++MARK_VISIBLE (gcry_cipher_setctr) ++MARK_VISIBLE (gcry_cipher_ctl) ++MARK_VISIBLE (gcry_cipher_decrypt) ++MARK_VISIBLE (gcry_cipher_encrypt) ++MARK_VISIBLE (gcry_cipher_get_algo_blklen) ++MARK_VISIBLE (gcry_cipher_get_algo_keylen) ++MARK_VISIBLE (gcry_cipher_info) ++MARK_VISIBLE (gcry_cipher_map_name) ++MARK_VISIBLE (gcry_cipher_mode_from_oid) ++MARK_VISIBLE (gcry_cipher_open) ++ ++MARK_VISIBLE (gcry_pk_algo_info) ++MARK_VISIBLE (gcry_pk_algo_name) ++MARK_VISIBLE (gcry_pk_ctl) ++MARK_VISIBLE (gcry_pk_decrypt) ++MARK_VISIBLE (gcry_pk_encrypt) ++MARK_VISIBLE (gcry_pk_genkey) ++MARK_VISIBLE (gcry_pk_get_keygrip) ++MARK_VISIBLE (gcry_pk_get_curve) ++MARK_VISIBLE (gcry_pk_get_param) ++MARK_VISIBLE (gcry_pk_get_nbits) ++MARK_VISIBLE (gcry_pk_map_name) ++MARK_VISIBLE (gcry_pk_sign) ++MARK_VISIBLE (gcry_pk_testkey) ++MARK_VISIBLE (gcry_pk_verify) ++ ++MARK_VISIBLE (gcry_kdf_derive) ++ ++MARK_VISIBLE (gcry_prime_check) ++MARK_VISIBLE (gcry_prime_generate) ++MARK_VISIBLE (gcry_prime_group_generator) ++MARK_VISIBLE (gcry_prime_release_factors) ++ ++MARK_VISIBLE (gcry_random_add_bytes) ++MARK_VISIBLE (gcry_random_bytes) ++MARK_VISIBLE (gcry_random_bytes_secure) ++MARK_VISIBLE (gcry_randomize) ++MARK_VISIBLE (gcry_create_nonce) ++ ++MARK_VISIBLE (gcry_sexp_alist) ++MARK_VISIBLE (gcry_sexp_append) ++MARK_VISIBLE (gcry_sexp_build) ++MARK_VISIBLE (gcry_sexp_build_array) ++MARK_VISIBLE (gcry_sexp_cadr) ++MARK_VISIBLE (gcry_sexp_canon_len) ++MARK_VISIBLE (gcry_sexp_car) ++MARK_VISIBLE (gcry_sexp_cdr) ++MARK_VISIBLE (gcry_sexp_cons) ++MARK_VISIBLE (gcry_sexp_create) ++MARK_VISIBLE (gcry_sexp_dump) ++MARK_VISIBLE (gcry_sexp_find_token) ++MARK_VISIBLE (gcry_sexp_length) ++MARK_VISIBLE (gcry_sexp_new) ++MARK_VISIBLE (gcry_sexp_nth) ++MARK_VISIBLE (gcry_sexp_nth_data) ++MARK_VISIBLE (gcry_sexp_nth_mpi) ++MARK_VISIBLE (gcry_sexp_prepend) ++MARK_VISIBLE (gcry_sexp_release) ++MARK_VISIBLE (gcry_sexp_sprint) ++MARK_VISIBLE (gcry_sexp_sscan) ++MARK_VISIBLE (gcry_sexp_vlist) ++MARK_VISIBLE (gcry_sexp_nth_string) ++ ++MARK_VISIBLE (gcry_mpi_add) ++MARK_VISIBLE (gcry_mpi_add_ui) ++MARK_VISIBLE (gcry_mpi_addm) ++MARK_VISIBLE (gcry_mpi_aprint) ++MARK_VISIBLE (gcry_mpi_clear_bit) ++MARK_VISIBLE (gcry_mpi_clear_flag) ++MARK_VISIBLE (gcry_mpi_clear_highbit) ++MARK_VISIBLE (gcry_mpi_cmp) ++MARK_VISIBLE (gcry_mpi_cmp_ui) ++MARK_VISIBLE (gcry_mpi_copy) ++MARK_VISIBLE (gcry_mpi_div) ++MARK_VISIBLE (gcry_mpi_dump) ++MARK_VISIBLE (gcry_mpi_gcd) ++MARK_VISIBLE (gcry_mpi_get_flag) ++MARK_VISIBLE (gcry_mpi_get_nbits) ++MARK_VISIBLE (gcry_mpi_get_opaque) ++MARK_VISIBLE (gcry_mpi_invm) ++MARK_VISIBLE (gcry_mpi_mod) ++MARK_VISIBLE (gcry_mpi_mul) ++MARK_VISIBLE (gcry_mpi_mul_2exp) ++MARK_VISIBLE (gcry_mpi_mul_ui) ++MARK_VISIBLE (gcry_mpi_mulm) ++MARK_VISIBLE (gcry_mpi_new) ++MARK_VISIBLE (gcry_mpi_powm) ++MARK_VISIBLE (gcry_mpi_print) ++MARK_VISIBLE (gcry_mpi_randomize) ++MARK_VISIBLE (gcry_mpi_release) ++MARK_VISIBLE (gcry_mpi_rshift) ++MARK_VISIBLE (gcry_mpi_lshift) ++MARK_VISIBLE (gcry_mpi_scan) ++MARK_VISIBLE (gcry_mpi_set) ++MARK_VISIBLE (gcry_mpi_set_bit) ++MARK_VISIBLE (gcry_mpi_set_flag) ++MARK_VISIBLE (gcry_mpi_set_highbit) ++MARK_VISIBLE (gcry_mpi_set_opaque) ++MARK_VISIBLE (gcry_mpi_set_ui) ++MARK_VISIBLE (gcry_mpi_snew) ++MARK_VISIBLE (gcry_mpi_sub) ++MARK_VISIBLE (gcry_mpi_sub_ui) ++MARK_VISIBLE (gcry_mpi_subm) ++MARK_VISIBLE (gcry_mpi_swap) ++MARK_VISIBLE (gcry_mpi_test_bit) ++ ++ ++ ++#undef MARK_VISIBLE ++#endif /*_GCRY_INCLUDED_BY_VISIBILITY_C*/ ++ ++#endif /*GCRY_VISIBILITY_H*/ +diff --git a/grub-core/lib/libgcrypt_wrap/cipher_wrap.h b/grub-core/lib/libgcrypt_wrap/cipher_wrap.h +index 70c0fb4..d7ae274 100644 +--- a/grub-core/lib/libgcrypt_wrap/cipher_wrap.h ++++ b/grub-core/lib/libgcrypt_wrap/cipher_wrap.h +@@ -34,8 +34,6 @@ + #undef __GNU_LIBRARY__ + #define __GNU_LIBRARY__ 1 + +-#define DIM ARRAY_SIZE +- + typedef grub_uint64_t u64; + typedef grub_uint32_t u32; + typedef grub_uint16_t u16; +@@ -44,37 +42,12 @@ typedef grub_size_t size_t; + + #define U64_C(c) (c ## ULL) + +-#define _gcry_burn_stack grub_burn_stack +-#define log_error(fmt, args...) grub_dprintf ("crypto", fmt, ## args) +- +- + #define PUBKEY_FLAG_NO_BLINDING (1 << 0) + + #define CIPHER_INFO_NO_WEAK_KEY 1 + + #define HAVE_U64_TYPEDEF 1 + +-typedef union { +- int a; +- short b; +- char c[1]; +- long d; +-#ifdef HAVE_U64_TYPEDEF +- u64 e; +-#endif +- float f; +- double g; +-} PROPERLY_ALIGNED_TYPE; +- +-#define gcry_assert(x) grub_assert_real(GRUB_FILE, __LINE__, x) +- +-static inline void +-grub_assert_real (const char *file, int line, int cond) +-{ +- if (!cond) +- grub_fatal ("Assertion failed at %s:%d\n", file, line); +-} +- + /* Selftests are in separate modules. */ + static inline char * + selftest (void) +@@ -90,11 +63,6 @@ fips_mode (void) + + #ifdef GRUB_UTIL + #pragma GCC diagnostic ignored "-Wshadow" +-static inline void * +-memcpy (void *dest, const void *src, grub_size_t n) +-{ +- return grub_memcpy (dest, src, n); +-} + + static inline void * + memset (void *s, int c, grub_size_t n) +@@ -102,13 +70,17 @@ memset (void *s, int c, grub_size_t n) + return grub_memset (s, c, n); + } + +-static inline int +-memcmp (const void *s1, const void *s2, grub_size_t n) +-{ +- return grub_memcmp (s1, s2, n); +-} + #pragma GCC diagnostic error "-Wshadow" + #endif + + ++#define DBG_CIPHER 0 ++ ++#include ++#pragma GCC diagnostic ignored "-Wredundant-decls" ++#include ++#include ++ ++#define gcry_mpi_mod _gcry_mpi_mod ++ + #endif +diff --git a/grub-core/lib/libgcrypt_wrap/mem.c b/grub-core/lib/libgcrypt_wrap/mem.c +new file mode 100644 +index 0000000..a9f0aff +--- /dev/null ++++ b/grub-core/lib/libgcrypt_wrap/mem.c +@@ -0,0 +1,112 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++GRUB_MOD_LICENSE ("GPLv3+"); ++ ++void * ++gcry_malloc (size_t n) ++{ ++ return grub_malloc (n); ++} ++ ++void * ++gcry_malloc_secure (size_t n) ++{ ++ return grub_malloc (n); ++} ++ ++void ++gcry_free (void *a) ++{ ++ grub_free (a); ++} ++ ++int ++gcry_is_secure (const void *a __attribute__ ((unused))) ++{ ++ return 0; ++} ++ ++/* FIXME: implement "exit". */ ++void * ++gcry_xcalloc (size_t n, size_t m) ++{ ++ return grub_zalloc (n * m); ++} ++ ++void * ++gcry_xmalloc_secure (size_t n) ++{ ++ return grub_malloc (n); ++} ++ ++void * ++gcry_xcalloc_secure (size_t n, size_t m) ++{ ++ return grub_zalloc (n * m); ++} ++ ++void * ++gcry_xmalloc (size_t n) ++{ ++ return grub_malloc (n); ++} ++ ++void * ++gcry_xrealloc (void *a, size_t n) ++{ ++ return grub_realloc (a, n); ++} ++ ++void ++_gcry_check_heap (const void *a __attribute__ ((unused))) ++{ ++ ++} ++ ++void _gcry_log_printf (const char *fmt, ...) ++{ ++ va_list args; ++ const char *debug = grub_env_get ("debug"); ++ ++ if (! debug) ++ return; ++ ++ if (grub_strword (debug, "all") || grub_strword (debug, "gcrypt")) ++ { ++ grub_printf ("gcrypt: "); ++ va_start (args, fmt); ++ grub_vprintf (fmt, args); ++ va_end (args); ++ grub_refresh (); ++ } ++} ++ ++void _gcry_log_bug (const char *fmt, ...) ++{ ++ va_list args; ++ ++ grub_printf ("gcrypt bug: "); ++ va_start (args, fmt); ++ grub_vprintf (fmt, args); ++ va_end (args); ++ grub_refresh (); ++} ++ ++gcry_err_code_t ++gpg_error_from_syserror (void) ++{ ++ switch (grub_errno) ++ { ++ case GRUB_ERR_NONE: ++ return GPG_ERR_NO_ERROR; ++ case GRUB_ERR_OUT_OF_MEMORY: ++ return GPG_ERR_OUT_OF_MEMORY; ++ default: ++ return GPG_ERR_GENERAL; ++ } ++} +diff --git a/grub-core/lib/posix_wrap/stdio.h b/grub-core/lib/posix_wrap/stdio.h +index e6b1178..d5a8b75 100644 +--- a/grub-core/lib/posix_wrap/stdio.h ++++ b/grub-core/lib/posix_wrap/stdio.h +@@ -21,13 +21,14 @@ + + #include + #include ++#include + + typedef struct grub_file FILE; + + #define EOF -1 + + static inline int +-snprintf (char *str, size_t n, const char *fmt, ...) ++snprintf (char *str, grub_size_t n, const char *fmt, ...) + { + va_list ap; + int ret; +diff --git a/grub-core/lib/posix_wrap/string.h b/grub-core/lib/posix_wrap/string.h +index 77fbe38..885845b 100644 +--- a/grub-core/lib/posix_wrap/string.h ++++ b/grub-core/lib/posix_wrap/string.h +@@ -21,6 +21,8 @@ + + #include + ++#define HAVE_STRCASECMP 1 ++ + static inline grub_size_t + strlen (const char *s) + { +@@ -54,6 +56,12 @@ memcmp (const void *s1, const void *s2, size_t n) + + #endif + ++static inline void ++bcopy (const void *src, void *dest, grub_size_t n) ++{ ++ grub_memcpy (dest, src, n); ++} ++ + static inline char * + strcpy (char *dest, const char *src) + { +@@ -73,7 +81,7 @@ strchr (const char *s, int c) + } + + static inline char * +-strncpy (char *dest, const char *src, size_t n) ++strncpy (char *dest, const char *src, grub_size_t n) + { + return grub_strncpy (dest, src, n); + } +@@ -85,7 +93,7 @@ strcat (char *dest, const char *src) + } + + static inline char * +-strncat (char *dest, const char *src, size_t n) ++strncat (char *dest, const char *src, grub_size_t n) + { + return grub_strncat (dest, src, n); + } +@@ -97,7 +105,7 @@ strcoll (const char *s1, const char *s2) + } + + static inline void * +-memchr (const void *s, int c, size_t n) ++memchr (const void *s, int c, grub_size_t n) + { + return grub_memchr (s, c, n); + } +diff --git a/grub-core/lib/posix_wrap/sys/types.h b/grub-core/lib/posix_wrap/sys/types.h +index 0e61b72..fe75d8d 100644 +--- a/grub-core/lib/posix_wrap/sys/types.h ++++ b/grub-core/lib/posix_wrap/sys/types.h +@@ -42,6 +42,15 @@ typedef grub_int16_t int16_t; + typedef grub_int32_t int32_t; + typedef grub_int64_t int64_t; + ++#define HAVE_U64_TYPEDEF 1 ++typedef grub_uint64_t u64; ++ ++#define SIZEOF_UNSIGNED_LONG GRUB_CPU_SIZEOF_LONG ++#define SIZEOF_UNSIGNED_INT 4 ++#define SIZEOF_UNSIGNED_LONG_LONG 8 ++#define SIZEOF_UNSIGNED_SHORT 2 ++#define SIZEOF_UINT64_T 8 ++ + #ifdef GRUB_CPU_WORDS_BIGENDIAN + #define WORDS_BIGENDIAN + #else +diff --git a/include/grub/crypto.h b/include/grub/crypto.h +index 67e0a1b..557b944 100644 +--- a/include/grub/crypto.h ++++ b/include/grub/crypto.h +@@ -64,11 +64,13 @@ typedef enum + GPG_ERR_WEAK_KEY, + GPG_ERR_WRONG_KEY_USAGE, + GPG_ERR_WRONG_PUBKEY_ALGO, +- GPG_ERR_OUT_OF_MEMORY ++ GPG_ERR_OUT_OF_MEMORY, ++ GPG_ERR_TOO_LARGE + } gcry_err_code_t; + #define gpg_err_code_t gcry_err_code_t + #define gpg_error_t gcry_err_code_t +- ++#define gcry_error_t gcry_err_code_t ++#if 0 + enum gcry_cipher_modes + { + GCRY_CIPHER_MODE_NONE = 0, /* Not yet specified. */ +@@ -79,6 +81,7 @@ enum gcry_cipher_modes + GCRY_CIPHER_MODE_OFB = 5, /* Outer feedback. */ + GCRY_CIPHER_MODE_CTR = 6 /* Counter. */ + }; ++#endif + + /* Type for the cipher_setkey function. */ + typedef gcry_err_code_t (*gcry_cipher_setkey_t) (void *c, +@@ -171,6 +174,73 @@ typedef struct gcry_md_spec + struct gcry_md_spec *next; + } gcry_md_spec_t; + ++typedef struct gcry_mpi *gcry_mpi_t; ++ ++/* Type for the pk_generate function. */ ++typedef gcry_err_code_t (*gcry_pk_generate_t) (int algo, ++ unsigned int nbits, ++ unsigned long use_e, ++ gcry_mpi_t *skey, ++ gcry_mpi_t **retfactors); ++ ++/* Type for the pk_check_secret_key function. */ ++typedef gcry_err_code_t (*gcry_pk_check_secret_key_t) (int algo, ++ gcry_mpi_t *skey); ++ ++/* Type for the pk_encrypt function. */ ++typedef gcry_err_code_t (*gcry_pk_encrypt_t) (int algo, ++ gcry_mpi_t *resarr, ++ gcry_mpi_t data, ++ gcry_mpi_t *pkey, ++ int flags); ++ ++/* Type for the pk_decrypt function. */ ++typedef gcry_err_code_t (*gcry_pk_decrypt_t) (int algo, ++ gcry_mpi_t *result, ++ gcry_mpi_t *data, ++ gcry_mpi_t *skey, ++ int flags); ++ ++/* Type for the pk_sign function. */ ++typedef gcry_err_code_t (*gcry_pk_sign_t) (int algo, ++ gcry_mpi_t *resarr, ++ gcry_mpi_t data, ++ gcry_mpi_t *skey); ++ ++/* Type for the pk_verify function. */ ++typedef gcry_err_code_t (*gcry_pk_verify_t) (int algo, ++ gcry_mpi_t hash, ++ gcry_mpi_t *data, ++ gcry_mpi_t *pkey, ++ int (*cmp) (void *, gcry_mpi_t), ++ void *opaquev); ++ ++/* Type for the pk_get_nbits function. */ ++typedef unsigned (*gcry_pk_get_nbits_t) (int algo, gcry_mpi_t *pkey); ++ ++/* Module specification structure for message digests. */ ++typedef struct gcry_pk_spec ++{ ++ const char *name; ++ const char **aliases; ++ const char *elements_pkey; ++ const char *elements_skey; ++ const char *elements_enc; ++ const char *elements_sig; ++ const char *elements_grip; ++ int use; ++ gcry_pk_generate_t generate; ++ gcry_pk_check_secret_key_t check_secret_key; ++ gcry_pk_encrypt_t encrypt; ++ gcry_pk_decrypt_t decrypt; ++ gcry_pk_sign_t sign; ++ gcry_pk_verify_t verify; ++ gcry_pk_get_nbits_t get_nbits; ++#ifdef GRUB_UTIL ++ const char *modname; ++#endif ++} gcry_pk_spec_t; ++ + struct grub_crypto_cipher_handle + { + const struct gcry_cipher_spec *cipher; +@@ -256,6 +326,11 @@ void + grub_md_register (gcry_md_spec_t *digest); + void + grub_md_unregister (gcry_md_spec_t *cipher); ++ ++extern struct gcry_pk_spec *grub_crypto_pk_dsa; ++extern struct gcry_pk_spec *grub_crypto_pk_ecdsa; ++extern struct gcry_pk_spec *grub_crypto_pk_rsa; ++ + void + grub_crypto_hash (const gcry_md_spec_t *hash, void *out, const void *in, + grub_size_t inlen); +@@ -319,10 +394,20 @@ grub_password_get (char buf[], unsigned buf_size); + + extern void (*grub_crypto_autoload_hook) (const char *name); + ++void _gcry_assert_failed (const char *expr, const char *file, int line, ++ const char *func) __attribute__ ((noreturn)); ++ ++void _gcry_burn_stack (int bytes); ++void _gcry_log_error( const char *fmt, ... ) __attribute__ ((format (printf, 1, 2))); ++void _gcry_log_bug( const char *fmt, ... ) __attribute__ ((format (printf, 1, 2))); ++void _gcry_log_printf( const char *fmt, ... ) __attribute__ ((format (printf, 1, 2))); ++void ++_gcry_check_heap (const void *a __attribute__ ((unused))); ++ ++ + #ifdef GRUB_UTIL + void grub_gcry_init_all (void); + void grub_gcry_fini_all (void); + #endif + +- + #endif +diff --git a/include/grub/err.h b/include/grub/err.h +index 2edc514..0f9b208 100644 +--- a/include/grub/err.h ++++ b/include/grub/err.h +@@ -69,7 +69,8 @@ typedef enum + GRUB_ERR_NET_UNKNOWN_ERROR, + GRUB_ERR_NET_PACKET_TOO_BIG, + GRUB_ERR_NET_NO_DOMAIN, +- GRUB_ERR_EOF ++ GRUB_ERR_EOF, ++ GRUB_ERR_BAD_SIGNATURE + } + grub_err_t; + +diff --git a/include/grub/file.h b/include/grub/file.h +index e08ac2e..ae86401 100644 +--- a/include/grub/file.h ++++ b/include/grub/file.h +@@ -54,6 +54,7 @@ typedef struct grub_file *grub_file_t; + /* Filters with lower ID are executed first. */ + typedef enum grub_file_filter_id + { ++ GRUB_FILE_FILTER_PUBKEY, + GRUB_FILE_FILTER_GZIO, + GRUB_FILE_FILTER_XZIO, + GRUB_FILE_FILTER_LZOPIO, +@@ -62,7 +63,7 @@ typedef enum grub_file_filter_id + GRUB_FILE_FILTER_COMPRESSION_LAST = GRUB_FILE_FILTER_LZOPIO, + } grub_file_filter_id_t; + +-typedef grub_file_t (*grub_file_filter_t) (grub_file_t in); ++typedef grub_file_t (*grub_file_filter_t) (grub_file_t in, const char *filename); + + extern grub_file_filter_t EXPORT_VAR(grub_file_filters_all)[GRUB_FILE_FILTER_MAX]; + extern grub_file_filter_t EXPORT_VAR(grub_file_filters_enabled)[GRUB_FILE_FILTER_MAX]; +@@ -72,20 +73,20 @@ grub_file_filter_register (grub_file_filter_id_t id, grub_file_filter_t filter) + { + grub_file_filters_all[id] = filter; + grub_file_filters_enabled[id] = filter; +-}; ++} + + static inline void + grub_file_filter_unregister (grub_file_filter_id_t id) + { + grub_file_filters_all[id] = 0; + grub_file_filters_enabled[id] = 0; +-}; ++} + + static inline void + grub_file_filter_disable (grub_file_filter_id_t id) + { + grub_file_filters_enabled[id] = 0; +-}; ++} + + static inline void + grub_file_filter_disable_compression (void) +@@ -95,7 +96,23 @@ grub_file_filter_disable_compression (void) + for (id = GRUB_FILE_FILTER_COMPRESSION_FIRST; + id <= GRUB_FILE_FILTER_COMPRESSION_LAST; id++) + grub_file_filters_enabled[id] = 0; +-}; ++} ++ ++static inline void ++grub_file_filter_disable_all (void) ++{ ++ grub_file_filter_id_t id; ++ ++ for (id = 0; ++ id < GRUB_FILE_FILTER_MAX; id++) ++ grub_file_filters_enabled[id] = 0; ++} ++ ++static inline void ++grub_file_filter_disable_pubkey (void) ++{ ++ grub_file_filters_enabled[GRUB_FILE_FILTER_PUBKEY] = 0; ++} + + /* Get a device name from NAME. */ + char *EXPORT_FUNC(grub_file_get_device_name) (const char *name); +diff --git a/include/grub/gcry/types.h b/include/grub/gcry/types.h +new file mode 100644 +index 0000000..892a204 +--- /dev/null ++++ b/include/grub/gcry/types.h +@@ -0,0 +1,37 @@ ++/* ++ * 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_GCRY_TYPES_HEADER ++#define GRUB_GCRY_TYPES_HEADER 1 ++ ++#include ++#include ++ ++#ifdef GRUB_CPU_WORDS_BIGENDIAN ++#define WORDS_BIGENDIAN ++#else ++#undef WORDS_BIGENDIAN ++#endif ++ ++typedef grub_uint64_t u64; ++typedef grub_uint32_t u32; ++typedef grub_uint16_t u16; ++typedef grub_uint8_t byte; ++typedef grub_size_t size_t; ++ ++#endif +diff --git a/include/grub/gcrypt/gcrypt.h b/include/grub/gcrypt/gcrypt.h +new file mode 100644 +index 0000000..fc83571 +--- /dev/null ++++ b/include/grub/gcrypt/gcrypt.h +@@ -0,0 +1,1333 @@ ++/* gcrypt.h - GNU Cryptographic Library Interface -*- c -*- ++ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006 ++ 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. ++ ++ This file is part of Libgcrypt. ++ ++ Libgcrypt is free software; you can redistribute it and/or modify ++ it under the terms of the GNU Lesser General Public License as ++ published by the Free Software Foundation; either version 2.1 of ++ the License, or (at your option) any later version. ++ ++ Libgcrypt 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 Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with this program; if not, see . ++ ++ File: @configure_input@ */ ++ ++#ifndef _GCRYPT_H ++#define _GCRYPT_H ++ ++#include ++ ++#include ++ ++#include ++ ++#if defined _WIN32 || defined __WIN32__ ++# include ++# include ++# include ++# ifndef __GNUC__ ++ typedef long ssize_t; ++ typedef int pid_t; ++# endif /*!__GNUC__*/ ++#else ++# include ++# include ++#endif /*!_WIN32*/ ++ ++ ++/* This is required for error code compatibility. */ ++#define _GCRY_ERR_SOURCE_DEFAULT GPG_ERR_SOURCE_GCRYPT ++ ++#ifdef __cplusplus ++extern "C" { ++#if 0 /* (Keep Emacsens' auto-indent happy.) */ ++} ++#endif ++#endif ++ ++/* The version of this header should match the one of the library. It ++ should not be used by a program because gcry_check_version() should ++ return the same version. The purpose of this macro is to let ++ autoconf (using the AM_PATH_GCRYPT macro) check that this header ++ matches the installed library. */ ++#define GCRYPT_VERSION "@VERSION@" ++ ++/* Internal: We can't use the convenience macros for the multi ++ precision integer functions when building this library. */ ++#ifdef _GCRYPT_IN_LIBGCRYPT ++#ifndef GCRYPT_NO_MPI_MACROS ++#define GCRYPT_NO_MPI_MACROS 1 ++#endif ++#endif ++ ++/* We want to use gcc attributes when possible. Warning: Don't use ++ these macros in your programs: As indicated by the leading ++ underscore they are subject to change without notice. */ ++#ifdef __GNUC__ ++ ++#define _GCRY_GCC_VERSION (__GNUC__ * 10000 \ ++ + __GNUC_MINOR__ * 100 \ ++ + __GNUC_PATCHLEVEL__) ++ ++#if _GCRY_GCC_VERSION >= 30100 ++#define _GCRY_GCC_ATTR_DEPRECATED __attribute__ ((__deprecated__)) ++#endif ++ ++#if _GCRY_GCC_VERSION >= 29600 ++#define _GCRY_GCC_ATTR_PURE __attribute__ ((__pure__)) ++#endif ++ ++#if _GCRY_GCC_VERSION >= 30200 ++#define _GCRY_GCC_ATTR_MALLOC __attribute__ ((__malloc__)) ++#endif ++ ++#endif /*__GNUC__*/ ++ ++#ifndef _GCRY_GCC_ATTR_DEPRECATED ++#define _GCRY_GCC_ATTR_DEPRECATED ++#endif ++#ifndef _GCRY_GCC_ATTR_PURE ++#define _GCRY_GCC_ATTR_PURE ++#endif ++#ifndef _GCRY_GCC_ATTR_MALLOC ++#define _GCRY_GCC_ATTR_MALLOC ++#endif ++ ++/* Make up an attribute to mark functions and types as deprecated but ++ allow internal use by Libgcrypt. */ ++#ifdef _GCRYPT_IN_LIBGCRYPT ++#define _GCRY_ATTR_INTERNAL ++#else ++#define _GCRY_ATTR_INTERNAL _GCRY_GCC_ATTR_DEPRECATED ++#endif ++ ++/* Wrappers for the libgpg-error library. */ ++ ++typedef gpg_error_t gcry_error_t; ++typedef gpg_err_code_t gcry_err_code_t; ++typedef gpg_err_source_t gcry_err_source_t; ++ ++static GPG_ERR_INLINE gcry_error_t ++gcry_err_make (gcry_err_source_t source, gcry_err_code_t code) ++{ ++ return gpg_err_make (source, code); ++} ++ ++/* The user can define GPG_ERR_SOURCE_DEFAULT before including this ++ file to specify a default source for gpg_error. */ ++#ifndef GCRY_ERR_SOURCE_DEFAULT ++#define GCRY_ERR_SOURCE_DEFAULT GPG_ERR_SOURCE_USER_1 ++#endif ++ ++static GPG_ERR_INLINE gcry_error_t ++gcry_error (gcry_err_code_t code) ++{ ++ return gcry_err_make (GCRY_ERR_SOURCE_DEFAULT, code); ++} ++ ++static GPG_ERR_INLINE gcry_err_code_t ++gcry_err_code (gcry_error_t err) ++{ ++ return gpg_err_code (err); ++} ++ ++ ++static GPG_ERR_INLINE gcry_err_source_t ++gcry_err_source (gcry_error_t err) ++{ ++ return gpg_err_source (err); ++} ++ ++/* Return a pointer to a string containing a description of the error ++ code in the error value ERR. */ ++const char *gcry_strerror (gcry_error_t err); ++ ++/* Return a pointer to a string containing a description of the error ++ source in the error value ERR. */ ++const char *gcry_strsource (gcry_error_t err); ++ ++/* Retrieve the error code for the system error ERR. This returns ++ GPG_ERR_UNKNOWN_ERRNO if the system error is not mapped (report ++ this). */ ++gcry_err_code_t gcry_err_code_from_errno (int err); ++ ++/* Retrieve the system error for the error code CODE. This returns 0 ++ if CODE is not a system error code. */ ++int gcry_err_code_to_errno (gcry_err_code_t code); ++ ++/* Return an error value with the error source SOURCE and the system ++ error ERR. */ ++gcry_error_t gcry_err_make_from_errno (gcry_err_source_t source, int err); ++ ++/* Return an error value with the system error ERR. */ ++gcry_err_code_t gcry_error_from_errno (int err); ++ ++ ++/* NOTE: Since Libgcrypt 1.6 the thread callbacks are not anymore ++ used. However we keep it to allow for some source code ++ compatibility if used in the standard way. */ ++ ++/* Constants defining the thread model to use. Used with the OPTION ++ field of the struct gcry_thread_cbs. */ ++#define GCRY_THREAD_OPTION_DEFAULT 0 ++#define GCRY_THREAD_OPTION_USER 1 ++#define GCRY_THREAD_OPTION_PTH 2 ++#define GCRY_THREAD_OPTION_PTHREAD 3 ++ ++/* The version number encoded in the OPTION field of the struct ++ gcry_thread_cbs. */ ++#define GCRY_THREAD_OPTION_VERSION 1 ++ ++/* Wrapper for struct ath_ops. */ ++struct gcry_thread_cbs ++{ ++ /* The OPTION field encodes the thread model and the version number ++ of this structure. ++ Bits 7 - 0 are used for the thread model ++ Bits 15 - 8 are used for the version number. */ ++ unsigned int option; ++} _GCRY_ATTR_INTERNAL; ++ ++#define GCRY_THREAD_OPTION_PTH_IMPL \ ++ static struct gcry_thread_cbs gcry_threads_pth = { \ ++ (GCRY_THREAD_OPTION_PTH | (GCRY_THREAD_OPTION_VERSION << 8))} ++ ++#define GCRY_THREAD_OPTION_PTHREAD_IMPL \ ++ static struct gcry_thread_cbs gcry_threads_pthread = { \ ++ (GCRY_THREAD_OPTION_PTHREAD | (GCRY_THREAD_OPTION_VERSION << 8))} ++ ++ ++ ++/* The data object used to hold a multi precision integer. */ ++struct gcry_mpi; ++typedef struct gcry_mpi *gcry_mpi_t; ++ ++#ifndef GCRYPT_NO_DEPRECATED ++typedef struct gcry_mpi *GCRY_MPI _GCRY_GCC_ATTR_DEPRECATED; ++typedef struct gcry_mpi *GcryMPI _GCRY_GCC_ATTR_DEPRECATED; ++#endif ++ ++ ++ ++/* Check that the library fulfills the version requirement. */ ++const char *gcry_check_version (const char *req_version); ++ ++/* Codes for function dispatchers. */ ++ ++/* Codes used with the gcry_control function. */ ++enum gcry_ctl_cmds ++ { ++ GCRYCTL_SET_KEY = 1, ++ GCRYCTL_SET_IV = 2, ++ GCRYCTL_CFB_SYNC = 3, ++ GCRYCTL_RESET = 4, /* e.g. for MDs */ ++ GCRYCTL_FINALIZE = 5, ++ GCRYCTL_GET_KEYLEN = 6, ++ GCRYCTL_GET_BLKLEN = 7, ++ GCRYCTL_TEST_ALGO = 8, ++ GCRYCTL_IS_SECURE = 9, ++ GCRYCTL_GET_ASNOID = 10, ++ GCRYCTL_ENABLE_ALGO = 11, ++ GCRYCTL_DISABLE_ALGO = 12, ++ GCRYCTL_DUMP_RANDOM_STATS = 13, ++ GCRYCTL_DUMP_SECMEM_STATS = 14, ++ GCRYCTL_GET_ALGO_NPKEY = 15, ++ GCRYCTL_GET_ALGO_NSKEY = 16, ++ GCRYCTL_GET_ALGO_NSIGN = 17, ++ GCRYCTL_GET_ALGO_NENCR = 18, ++ GCRYCTL_SET_VERBOSITY = 19, ++ GCRYCTL_SET_DEBUG_FLAGS = 20, ++ GCRYCTL_CLEAR_DEBUG_FLAGS = 21, ++ GCRYCTL_USE_SECURE_RNDPOOL= 22, ++ GCRYCTL_DUMP_MEMORY_STATS = 23, ++ GCRYCTL_INIT_SECMEM = 24, ++ GCRYCTL_TERM_SECMEM = 25, ++ GCRYCTL_DISABLE_SECMEM_WARN = 27, ++ GCRYCTL_SUSPEND_SECMEM_WARN = 28, ++ GCRYCTL_RESUME_SECMEM_WARN = 29, ++ GCRYCTL_DROP_PRIVS = 30, ++ GCRYCTL_ENABLE_M_GUARD = 31, ++ GCRYCTL_START_DUMP = 32, ++ GCRYCTL_STOP_DUMP = 33, ++ GCRYCTL_GET_ALGO_USAGE = 34, ++ GCRYCTL_IS_ALGO_ENABLED = 35, ++ GCRYCTL_DISABLE_INTERNAL_LOCKING = 36, ++ GCRYCTL_DISABLE_SECMEM = 37, ++ GCRYCTL_INITIALIZATION_FINISHED = 38, ++ GCRYCTL_INITIALIZATION_FINISHED_P = 39, ++ GCRYCTL_ANY_INITIALIZATION_P = 40, ++ GCRYCTL_SET_CBC_CTS = 41, ++ GCRYCTL_SET_CBC_MAC = 42, ++ GCRYCTL_SET_CTR = 43, ++ GCRYCTL_ENABLE_QUICK_RANDOM = 44, ++ GCRYCTL_SET_RANDOM_SEED_FILE = 45, ++ GCRYCTL_UPDATE_RANDOM_SEED_FILE = 46, ++ GCRYCTL_SET_THREAD_CBS = 47, ++ GCRYCTL_FAST_POLL = 48, ++ GCRYCTL_SET_RANDOM_DAEMON_SOCKET = 49, ++ GCRYCTL_USE_RANDOM_DAEMON = 50, ++ GCRYCTL_FAKED_RANDOM_P = 51, ++ GCRYCTL_SET_RNDEGD_SOCKET = 52, ++ GCRYCTL_PRINT_CONFIG = 53, ++ GCRYCTL_OPERATIONAL_P = 54, ++ GCRYCTL_FIPS_MODE_P = 55, ++ GCRYCTL_FORCE_FIPS_MODE = 56, ++ GCRYCTL_SELFTEST = 57, ++ /* Note: 58 .. 62 are used internally. */ ++ GCRYCTL_DISABLE_HWF = 63 ++ }; ++ ++/* Perform various operations defined by CMD. */ ++gcry_error_t gcry_control (enum gcry_ctl_cmds CMD, ...); ++ ++ ++/* S-expression management. */ ++ ++/* The object to represent an S-expression as used with the public key ++ functions. */ ++struct gcry_sexp; ++typedef struct gcry_sexp *gcry_sexp_t; ++ ++#ifndef GCRYPT_NO_DEPRECATED ++typedef struct gcry_sexp *GCRY_SEXP _GCRY_GCC_ATTR_DEPRECATED; ++typedef struct gcry_sexp *GcrySexp _GCRY_GCC_ATTR_DEPRECATED; ++#endif ++ ++/* The possible values for the S-expression format. */ ++enum gcry_sexp_format ++ { ++ GCRYSEXP_FMT_DEFAULT = 0, ++ GCRYSEXP_FMT_CANON = 1, ++ GCRYSEXP_FMT_BASE64 = 2, ++ GCRYSEXP_FMT_ADVANCED = 3 ++ }; ++ ++/* Create an new S-expression object from BUFFER of size LENGTH and ++ return it in RETSEXP. With AUTODETECT set to 0 the data in BUFFER ++ is expected to be in canonized format. */ ++gcry_error_t gcry_sexp_new (gcry_sexp_t *retsexp, ++ const void *buffer, size_t length, ++ int autodetect); ++ ++ /* Same as gcry_sexp_new but allows to pass a FREEFNC which has the ++ effect to transfer ownership of BUFFER to the created object. */ ++gcry_error_t gcry_sexp_create (gcry_sexp_t *retsexp, ++ void *buffer, size_t length, ++ int autodetect, void (*freefnc) (void *)); ++ ++/* Scan BUFFER and return a new S-expression object in RETSEXP. This ++ function expects a printf like string in BUFFER. */ ++gcry_error_t gcry_sexp_sscan (gcry_sexp_t *retsexp, size_t *erroff, ++ const char *buffer, size_t length); ++ ++/* Same as gcry_sexp_sscan but expects a string in FORMAT and can thus ++ only be used for certain encodings. */ ++gcry_error_t gcry_sexp_build (gcry_sexp_t *retsexp, size_t *erroff, ++ const char *format, ...); ++ ++/* Like gcry_sexp_build, but uses an array instead of variable ++ function arguments. */ ++gcry_error_t gcry_sexp_build_array (gcry_sexp_t *retsexp, size_t *erroff, ++ const char *format, void **arg_list); ++ ++/* Release the S-expression object SEXP */ ++void gcry_sexp_release (gcry_sexp_t sexp); ++ ++/* Calculate the length of an canonized S-expresion in BUFFER and ++ check for a valid encoding. */ ++size_t gcry_sexp_canon_len (const unsigned char *buffer, size_t length, ++ size_t *erroff, gcry_error_t *errcode); ++ ++/* Copies the S-expression object SEXP into BUFFER using the format ++ specified in MODE. */ ++size_t gcry_sexp_sprint (gcry_sexp_t sexp, int mode, void *buffer, ++ size_t maxlength); ++ ++/* Dumps the S-expression object A in a format suitable for debugging ++ to Libgcrypt's logging stream. */ ++void gcry_sexp_dump (const gcry_sexp_t a); ++ ++gcry_sexp_t gcry_sexp_cons (const gcry_sexp_t a, const gcry_sexp_t b); ++gcry_sexp_t gcry_sexp_alist (const gcry_sexp_t *array); ++gcry_sexp_t gcry_sexp_vlist (const gcry_sexp_t a, ...); ++gcry_sexp_t gcry_sexp_append (const gcry_sexp_t a, const gcry_sexp_t n); ++gcry_sexp_t gcry_sexp_prepend (const gcry_sexp_t a, const gcry_sexp_t n); ++ ++/* Scan the S-expression for a sublist with a type (the car of the ++ list) matching the string TOKEN. If TOKLEN is not 0, the token is ++ assumed to be raw memory of this length. The function returns a ++ newly allocated S-expression consisting of the found sublist or ++ `NULL' when not found. */ ++gcry_sexp_t gcry_sexp_find_token (gcry_sexp_t list, ++ const char *tok, size_t toklen); ++/* Return the length of the LIST. For a valid S-expression this ++ should be at least 1. */ ++int gcry_sexp_length (const gcry_sexp_t list); ++ ++/* Create and return a new S-expression from the element with index ++ NUMBER in LIST. Note that the first element has the index 0. If ++ there is no such element, `NULL' is returned. */ ++gcry_sexp_t gcry_sexp_nth (const gcry_sexp_t list, int number); ++ ++/* Create and return a new S-expression from the first element in ++ LIST; this called the "type" and should always exist and be a ++ string. `NULL' is returned in case of a problem. */ ++gcry_sexp_t gcry_sexp_car (const gcry_sexp_t list); ++ ++/* Create and return a new list form all elements except for the first ++ one. Note, that this function may return an invalid S-expression ++ because it is not guaranteed, that the type exists and is a string. ++ However, for parsing a complex S-expression it might be useful for ++ intermediate lists. Returns `NULL' on error. */ ++gcry_sexp_t gcry_sexp_cdr (const gcry_sexp_t list); ++ ++gcry_sexp_t gcry_sexp_cadr (const gcry_sexp_t list); ++ ++ ++/* This function is used to get data from a LIST. A pointer to the ++ actual data with index NUMBER is returned and the length of this ++ data will be stored to DATALEN. If there is no data at the given ++ index or the index represents another list, `NULL' is returned. ++ *Note:* The returned pointer is valid as long as LIST is not ++ modified or released. */ ++const char *gcry_sexp_nth_data (const gcry_sexp_t list, int number, ++ size_t *datalen); ++ ++/* This function is used to get and convert data from a LIST. The ++ data is assumed to be a Nul terminated string. The caller must ++ release the returned value using `gcry_free'. If there is no data ++ at the given index, the index represents a list or the value can't ++ be converted to a string, `NULL' is returned. */ ++char *gcry_sexp_nth_string (gcry_sexp_t list, int number); ++ ++/* This function is used to get and convert data from a LIST. This ++ data is assumed to be an MPI stored in the format described by ++ MPIFMT and returned as a standard Libgcrypt MPI. The caller must ++ release this returned value using `gcry_mpi_release'. If there is ++ no data at the given index, the index represents a list or the ++ value can't be converted to an MPI, `NULL' is returned. */ ++gcry_mpi_t gcry_sexp_nth_mpi (gcry_sexp_t list, int number, int mpifmt); ++ ++ ++ ++/******************************************* ++ * * ++ * Multi Precision Integer Functions * ++ * * ++ *******************************************/ ++ ++/* Different formats of external big integer representation. */ ++enum gcry_mpi_format ++ { ++ GCRYMPI_FMT_NONE= 0, ++ GCRYMPI_FMT_STD = 1, /* Twos complement stored without length. */ ++ GCRYMPI_FMT_PGP = 2, /* As used by OpenPGP (unsigned only). */ ++ GCRYMPI_FMT_SSH = 3, /* As used by SSH (like STD but with length). */ ++ GCRYMPI_FMT_HEX = 4, /* Hex format. */ ++ GCRYMPI_FMT_USG = 5 /* Like STD but unsigned. */ ++ }; ++ ++/* Flags used for creating big integers. */ ++enum gcry_mpi_flag ++ { ++ GCRYMPI_FLAG_SECURE = 1, /* Allocate the number in "secure" memory. */ ++ GCRYMPI_FLAG_OPAQUE = 2 /* The number is not a real one but just ++ a way to store some bytes. This is ++ useful for encrypted big integers. */ ++ }; ++ ++ ++/* Allocate a new big integer object, initialize it with 0 and ++ initially allocate memory for a number of at least NBITS. */ ++gcry_mpi_t gcry_mpi_new (unsigned int nbits); ++ ++/* Same as gcry_mpi_new() but allocate in "secure" memory. */ ++gcry_mpi_t gcry_mpi_snew (unsigned int nbits); ++ ++/* Release the number A and free all associated resources. */ ++void gcry_mpi_release (gcry_mpi_t a); ++ ++/* Create a new number with the same value as A. */ ++gcry_mpi_t gcry_mpi_copy (const gcry_mpi_t a); ++ ++/* Store the big integer value U in W. */ ++gcry_mpi_t gcry_mpi_set (gcry_mpi_t w, const gcry_mpi_t u); ++ ++/* Store the unsigned integer value U in W. */ ++gcry_mpi_t gcry_mpi_set_ui (gcry_mpi_t w, unsigned long u); ++ ++/* Swap the values of A and B. */ ++void gcry_mpi_swap (gcry_mpi_t a, gcry_mpi_t b); ++ ++/* Compare the big integer number U and V returning 0 for equality, a ++ positive value for U > V and a negative for U < V. */ ++int gcry_mpi_cmp (const gcry_mpi_t u, const gcry_mpi_t v); ++ ++/* Compare the big integer number U with the unsigned integer V ++ returning 0 for equality, a positive value for U > V and a negative ++ for U < V. */ ++int gcry_mpi_cmp_ui (const gcry_mpi_t u, unsigned long v); ++ ++/* Convert the external representation of an integer stored in BUFFER ++ with a length of BUFLEN into a newly create MPI returned in ++ RET_MPI. If NSCANNED is not NULL, it will receive the number of ++ bytes actually scanned after a successful operation. */ ++gcry_error_t gcry_mpi_scan (gcry_mpi_t *ret_mpi, enum gcry_mpi_format format, ++ const void *buffer, size_t buflen, ++ size_t *nscanned); ++ ++/* Convert the big integer A into the external representation ++ described by FORMAT and store it in the provided BUFFER which has ++ been allocated by the user with a size of BUFLEN bytes. NWRITTEN ++ receives the actual length of the external representation unless it ++ has been passed as NULL. */ ++gcry_error_t gcry_mpi_print (enum gcry_mpi_format format, ++ unsigned char *buffer, size_t buflen, ++ size_t *nwritten, ++ const gcry_mpi_t a); ++ ++/* Convert the big integer A int the external representation described ++ by FORMAT and store it in a newly allocated buffer which address ++ will be put into BUFFER. NWRITTEN receives the actual lengths of the ++ external representation. */ ++gcry_error_t gcry_mpi_aprint (enum gcry_mpi_format format, ++ unsigned char **buffer, size_t *nwritten, ++ const gcry_mpi_t a); ++ ++/* Dump the value of A in a format suitable for debugging to ++ Libgcrypt's logging stream. Note that one leading space but no ++ trailing space or linefeed will be printed. It is okay to pass ++ NULL for A. */ ++void gcry_mpi_dump (const gcry_mpi_t a); ++ ++ ++/* W = U + V. */ ++void gcry_mpi_add (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v); ++ ++/* W = U + V. V is an unsigned integer. */ ++void gcry_mpi_add_ui (gcry_mpi_t w, gcry_mpi_t u, unsigned long v); ++ ++/* W = U + V mod M. */ ++void gcry_mpi_addm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m); ++ ++/* W = U - V. */ ++void gcry_mpi_sub (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v); ++ ++/* W = U - V. V is an unsigned integer. */ ++void gcry_mpi_sub_ui (gcry_mpi_t w, gcry_mpi_t u, unsigned long v ); ++ ++/* W = U - V mod M */ ++void gcry_mpi_subm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m); ++ ++/* W = U * V. */ ++void gcry_mpi_mul (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v); ++ ++/* W = U * V. V is an unsigned integer. */ ++void gcry_mpi_mul_ui (gcry_mpi_t w, gcry_mpi_t u, unsigned long v ); ++ ++/* W = U * V mod M. */ ++void gcry_mpi_mulm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m); ++ ++/* W = U * (2 ^ CNT). */ ++void gcry_mpi_mul_2exp (gcry_mpi_t w, gcry_mpi_t u, unsigned long cnt); ++ ++/* Q = DIVIDEND / DIVISOR, R = DIVIDEND % DIVISOR, ++ Q or R may be passed as NULL. ROUND should be negative or 0. */ ++void gcry_mpi_div (gcry_mpi_t q, gcry_mpi_t r, ++ gcry_mpi_t dividend, gcry_mpi_t divisor, int round); ++ ++/* R = DIVIDEND % DIVISOR */ ++void gcry_mpi_mod (gcry_mpi_t r, gcry_mpi_t dividend, gcry_mpi_t divisor); ++ ++/* W = B ^ E mod M. */ ++void gcry_mpi_powm (gcry_mpi_t w, ++ const gcry_mpi_t b, const gcry_mpi_t e, ++ const gcry_mpi_t m); ++ ++/* Set G to the greatest common divisor of A and B. ++ Return true if the G is 1. */ ++int gcry_mpi_gcd (gcry_mpi_t g, gcry_mpi_t a, gcry_mpi_t b); ++ ++/* Set X to the multiplicative inverse of A mod M. ++ Return true if the value exists. */ ++int gcry_mpi_invm (gcry_mpi_t x, gcry_mpi_t a, gcry_mpi_t m); ++ ++ ++/* Return the number of bits required to represent A. */ ++unsigned int gcry_mpi_get_nbits (gcry_mpi_t a); ++ ++/* Return true when bit number N (counting from 0) is set in A. */ ++int gcry_mpi_test_bit (gcry_mpi_t a, unsigned int n); ++ ++/* Set bit number N in A. */ ++void gcry_mpi_set_bit (gcry_mpi_t a, unsigned int n); ++ ++/* Clear bit number N in A. */ ++void gcry_mpi_clear_bit (gcry_mpi_t a, unsigned int n); ++ ++/* Set bit number N in A and clear all bits greater than N. */ ++void gcry_mpi_set_highbit (gcry_mpi_t a, unsigned int n); ++ ++/* Clear bit number N in A and all bits greater than N. */ ++void gcry_mpi_clear_highbit (gcry_mpi_t a, unsigned int n); ++ ++/* Shift the value of A by N bits to the right and store the result in X. */ ++void gcry_mpi_rshift (gcry_mpi_t x, gcry_mpi_t a, unsigned int n); ++ ++/* Shift the value of A by N bits to the left and store the result in X. */ ++void gcry_mpi_lshift (gcry_mpi_t x, gcry_mpi_t a, unsigned int n); ++ ++/* Store NBITS of the value P points to in A and mark A as an opaque ++ value. WARNING: Never use an opaque MPI for anything thing else then ++ gcry_mpi_release, gcry_mpi_get_opaque. */ ++gcry_mpi_t gcry_mpi_set_opaque (gcry_mpi_t a, void *p, unsigned int nbits); ++ ++/* Return a pointer to an opaque value stored in A and return its size ++ in NBITS. Note that the returned pointer is still owned by A and ++ that the function should never be used for an non-opaque MPI. */ ++void *gcry_mpi_get_opaque (gcry_mpi_t a, unsigned int *nbits); ++ ++/* Set the FLAG for the big integer A. Currently only the flag ++ GCRYMPI_FLAG_SECURE is allowed to convert A into an big intger ++ stored in "secure" memory. */ ++void gcry_mpi_set_flag (gcry_mpi_t a, enum gcry_mpi_flag flag); ++ ++/* Clear FLAG for the big integer A. Note that this function is ++ currently useless as no flags are allowed. */ ++void gcry_mpi_clear_flag (gcry_mpi_t a, enum gcry_mpi_flag flag); ++ ++/* Return true when the FLAG is set for A. */ ++int gcry_mpi_get_flag (gcry_mpi_t a, enum gcry_mpi_flag flag); ++ ++/* Unless the GCRYPT_NO_MPI_MACROS is used, provide a couple of ++ convenience macros for the big integer functions. */ ++#ifndef GCRYPT_NO_MPI_MACROS ++#define mpi_new(n) gcry_mpi_new( (n) ) ++#define mpi_secure_new( n ) gcry_mpi_snew( (n) ) ++#define mpi_release(a) \ ++ do \ ++ { \ ++ gcry_mpi_release ((a)); \ ++ (a) = NULL; \ ++ } \ ++ while (0) ++ ++#define mpi_copy( a ) gcry_mpi_copy( (a) ) ++#define mpi_set( w, u) gcry_mpi_set( (w), (u) ) ++#define mpi_set_ui( w, u) gcry_mpi_set_ui( (w), (u) ) ++#define mpi_cmp( u, v ) gcry_mpi_cmp( (u), (v) ) ++#define mpi_cmp_ui( u, v ) gcry_mpi_cmp_ui( (u), (v) ) ++ ++#define mpi_add_ui(w,u,v) gcry_mpi_add_ui((w),(u),(v)) ++#define mpi_add(w,u,v) gcry_mpi_add ((w),(u),(v)) ++#define mpi_addm(w,u,v,m) gcry_mpi_addm ((w),(u),(v),(m)) ++#define mpi_sub_ui(w,u,v) gcry_mpi_sub_ui ((w),(u),(v)) ++#define mpi_sub(w,u,v) gcry_mpi_sub ((w),(u),(v)) ++#define mpi_subm(w,u,v,m) gcry_mpi_subm ((w),(u),(v),(m)) ++#define mpi_mul_ui(w,u,v) gcry_mpi_mul_ui ((w),(u),(v)) ++#define mpi_mul_2exp(w,u,v) gcry_mpi_mul_2exp ((w),(u),(v)) ++#define mpi_mul(w,u,v) gcry_mpi_mul ((w),(u),(v)) ++#define mpi_mulm(w,u,v,m) gcry_mpi_mulm ((w),(u),(v),(m)) ++#define mpi_powm(w,b,e,m) gcry_mpi_powm ( (w), (b), (e), (m) ) ++#define mpi_tdiv(q,r,a,m) gcry_mpi_div ( (q), (r), (a), (m), 0) ++#define mpi_fdiv(q,r,a,m) gcry_mpi_div ( (q), (r), (a), (m), -1) ++#define mpi_mod(r,a,m) gcry_mpi_mod ((r), (a), (m)) ++#define mpi_gcd(g,a,b) gcry_mpi_gcd ( (g), (a), (b) ) ++#define mpi_invm(g,a,b) gcry_mpi_invm ( (g), (a), (b) ) ++ ++#define mpi_get_nbits(a) gcry_mpi_get_nbits ((a)) ++#define mpi_test_bit(a,b) gcry_mpi_test_bit ((a),(b)) ++#define mpi_set_bit(a,b) gcry_mpi_set_bit ((a),(b)) ++#define mpi_set_highbit(a,b) gcry_mpi_set_highbit ((a),(b)) ++#define mpi_clear_bit(a,b) gcry_mpi_clear_bit ((a),(b)) ++#define mpi_clear_highbit(a,b) gcry_mpi_clear_highbit ((a),(b)) ++#define mpi_rshift(a,b,c) gcry_mpi_rshift ((a),(b),(c)) ++#define mpi_lshift(a,b,c) gcry_mpi_lshift ((a),(b),(c)) ++ ++#define mpi_set_opaque(a,b,c) gcry_mpi_set_opaque( (a), (b), (c) ) ++#define mpi_get_opaque(a,b) gcry_mpi_get_opaque( (a), (b) ) ++#endif /* GCRYPT_NO_MPI_MACROS */ ++ ++ ++ ++/************************************ ++ * * ++ * Symmetric Cipher Functions * ++ * * ++ ************************************/ ++ ++/* The data object used to hold a handle to an encryption object. */ ++struct gcry_cipher_handle; ++typedef struct gcry_cipher_handle *gcry_cipher_hd_t; ++ ++#ifndef GCRYPT_NO_DEPRECATED ++typedef struct gcry_cipher_handle *GCRY_CIPHER_HD _GCRY_GCC_ATTR_DEPRECATED; ++typedef struct gcry_cipher_handle *GcryCipherHd _GCRY_GCC_ATTR_DEPRECATED; ++#endif ++ ++/* All symmetric encryption algorithms are identified by their IDs. ++ More IDs may be registered at runtime. */ ++enum gcry_cipher_algos ++ { ++ GCRY_CIPHER_NONE = 0, ++ GCRY_CIPHER_IDEA = 1, ++ GCRY_CIPHER_3DES = 2, ++ GCRY_CIPHER_CAST5 = 3, ++ GCRY_CIPHER_BLOWFISH = 4, ++ GCRY_CIPHER_SAFER_SK128 = 5, ++ GCRY_CIPHER_DES_SK = 6, ++ GCRY_CIPHER_AES = 7, ++ GCRY_CIPHER_AES192 = 8, ++ GCRY_CIPHER_AES256 = 9, ++ GCRY_CIPHER_TWOFISH = 10, ++ ++ /* Other cipher numbers are above 300 for OpenPGP reasons. */ ++ GCRY_CIPHER_ARCFOUR = 301, /* Fully compatible with RSA's RC4 (tm). */ ++ GCRY_CIPHER_DES = 302, /* Yes, this is single key 56 bit DES. */ ++ GCRY_CIPHER_TWOFISH128 = 303, ++ GCRY_CIPHER_SERPENT128 = 304, ++ GCRY_CIPHER_SERPENT192 = 305, ++ GCRY_CIPHER_SERPENT256 = 306, ++ GCRY_CIPHER_RFC2268_40 = 307, /* Ron's Cipher 2 (40 bit). */ ++ GCRY_CIPHER_RFC2268_128 = 308, /* Ron's Cipher 2 (128 bit). */ ++ GCRY_CIPHER_SEED = 309, /* 128 bit cipher described in RFC4269. */ ++ GCRY_CIPHER_CAMELLIA128 = 310, ++ GCRY_CIPHER_CAMELLIA192 = 311, ++ GCRY_CIPHER_CAMELLIA256 = 312 ++ }; ++ ++/* The Rijndael algorithm is basically AES, so provide some macros. */ ++#define GCRY_CIPHER_AES128 GCRY_CIPHER_AES ++#define GCRY_CIPHER_RIJNDAEL GCRY_CIPHER_AES ++#define GCRY_CIPHER_RIJNDAEL128 GCRY_CIPHER_AES128 ++#define GCRY_CIPHER_RIJNDAEL192 GCRY_CIPHER_AES192 ++#define GCRY_CIPHER_RIJNDAEL256 GCRY_CIPHER_AES256 ++ ++/* The supported encryption modes. Note that not all of them are ++ supported for each algorithm. */ ++enum gcry_cipher_modes ++ { ++ GCRY_CIPHER_MODE_NONE = 0, /* Not yet specified. */ ++ GCRY_CIPHER_MODE_ECB = 1, /* Electronic codebook. */ ++ GCRY_CIPHER_MODE_CFB = 2, /* Cipher feedback. */ ++ GCRY_CIPHER_MODE_CBC = 3, /* Cipher block chaining. */ ++ GCRY_CIPHER_MODE_STREAM = 4, /* Used with stream ciphers. */ ++ GCRY_CIPHER_MODE_OFB = 5, /* Outer feedback. */ ++ GCRY_CIPHER_MODE_CTR = 6, /* Counter. */ ++ GCRY_CIPHER_MODE_AESWRAP= 7 /* AES-WRAP algorithm. */ ++ }; ++ ++/* Flags used with the open function. */ ++enum gcry_cipher_flags ++ { ++ GCRY_CIPHER_SECURE = 1, /* Allocate in secure memory. */ ++ GCRY_CIPHER_ENABLE_SYNC = 2, /* Enable CFB sync mode. */ ++ GCRY_CIPHER_CBC_CTS = 4, /* Enable CBC cipher text stealing (CTS). */ ++ GCRY_CIPHER_CBC_MAC = 8 /* Enable CBC message auth. code (MAC). */ ++ }; ++ ++ ++/* Create a handle for algorithm ALGO to be used in MODE. FLAGS may ++ be given as an bitwise OR of the gcry_cipher_flags values. */ ++gcry_error_t gcry_cipher_open (gcry_cipher_hd_t *handle, ++ int algo, int mode, unsigned int flags); ++ ++/* Close the cioher handle H and release all resource. */ ++void gcry_cipher_close (gcry_cipher_hd_t h); ++ ++/* Perform various operations on the cipher object H. */ ++gcry_error_t gcry_cipher_ctl (gcry_cipher_hd_t h, int cmd, void *buffer, ++ size_t buflen); ++ ++/* Retrieve various information about the cipher object H. */ ++gcry_error_t gcry_cipher_info (gcry_cipher_hd_t h, int what, void *buffer, ++ size_t *nbytes); ++ ++/* Retrieve various information about the cipher algorithm ALGO. */ ++gcry_error_t gcry_cipher_algo_info (int algo, int what, void *buffer, ++ size_t *nbytes); ++ ++/* Map the cipher algorithm whose ID is contained in ALGORITHM to a ++ string representation of the algorithm name. For unknown algorithm ++ IDs this function returns "?". */ ++const char *gcry_cipher_algo_name (int algorithm) _GCRY_GCC_ATTR_PURE; ++ ++/* Map the algorithm name NAME to an cipher algorithm ID. Return 0 if ++ the algorithm name is not known. */ ++int gcry_cipher_map_name (const char *name) _GCRY_GCC_ATTR_PURE; ++ ++/* Given an ASN.1 object identifier in standard IETF dotted decimal ++ format in STRING, return the encryption mode associated with that ++ OID or 0 if not known or applicable. */ ++int gcry_cipher_mode_from_oid (const char *string) _GCRY_GCC_ATTR_PURE; ++ ++/* Encrypt the plaintext of size INLEN in IN using the cipher handle H ++ into the buffer OUT which has an allocated length of OUTSIZE. For ++ most algorithms it is possible to pass NULL for in and 0 for INLEN ++ and do a in-place decryption of the data provided in OUT. */ ++gcry_error_t gcry_cipher_encrypt (gcry_cipher_hd_t h, ++ void *out, size_t outsize, ++ const void *in, size_t inlen); ++ ++/* The counterpart to gcry_cipher_encrypt. */ ++gcry_error_t gcry_cipher_decrypt (gcry_cipher_hd_t h, ++ void *out, size_t outsize, ++ const void *in, size_t inlen); ++ ++/* Set KEY of length KEYLEN bytes for the cipher handle HD. */ ++gcry_error_t gcry_cipher_setkey (gcry_cipher_hd_t hd, ++ const void *key, size_t keylen); ++ ++ ++/* Set initialization vector IV of length IVLEN for the cipher handle HD. */ ++gcry_error_t gcry_cipher_setiv (gcry_cipher_hd_t hd, ++ const void *iv, size_t ivlen); ++ ++ ++/* Reset the handle to the state after open. */ ++#define gcry_cipher_reset(h) gcry_cipher_ctl ((h), GCRYCTL_RESET, NULL, 0) ++ ++/* Perform the OpenPGP sync operation if this is enabled for the ++ cipher handle H. */ ++#define gcry_cipher_sync(h) gcry_cipher_ctl( (h), GCRYCTL_CFB_SYNC, NULL, 0) ++ ++/* Enable or disable CTS in future calls to gcry_encrypt(). CBC mode only. */ ++#define gcry_cipher_cts(h,on) gcry_cipher_ctl( (h), GCRYCTL_SET_CBC_CTS, \ ++ NULL, on ) ++ ++/* Set counter for CTR mode. (CTR,CTRLEN) must denote a buffer of ++ block size length, or (NULL,0) to set the CTR to the all-zero block. */ ++gpg_error_t gcry_cipher_setctr (gcry_cipher_hd_t hd, ++ const void *ctr, size_t ctrlen); ++ ++/* Retrieve the key length in bytes used with algorithm A. */ ++size_t gcry_cipher_get_algo_keylen (int algo); ++ ++/* Retrieve the block length in bytes used with algorithm A. */ ++size_t gcry_cipher_get_algo_blklen (int algo); ++ ++/* Return 0 if the algorithm A is available for use. */ ++#define gcry_cipher_test_algo(a) \ ++ gcry_cipher_algo_info( (a), GCRYCTL_TEST_ALGO, NULL, NULL ) ++ ++ ++/************************************ ++ * * ++ * Asymmetric Cipher Functions * ++ * * ++ ************************************/ ++ ++/* The algorithms and their IDs we support. */ ++enum gcry_pk_algos ++ { ++ GCRY_PK_RSA = 1, ++ GCRY_PK_RSA_E = 2, /* (deprecated) */ ++ GCRY_PK_RSA_S = 3, /* (deprecated) */ ++ GCRY_PK_ELG_E = 16, ++ GCRY_PK_DSA = 17, ++ GCRY_PK_ELG = 20, ++ GCRY_PK_ECDSA = 301, ++ GCRY_PK_ECDH = 302 ++ }; ++ ++/* Flags describing usage capabilities of a PK algorithm. */ ++#define GCRY_PK_USAGE_SIGN 1 /* Good for signatures. */ ++#define GCRY_PK_USAGE_ENCR 2 /* Good for encryption. */ ++#define GCRY_PK_USAGE_CERT 4 /* Good to certify other keys. */ ++#define GCRY_PK_USAGE_AUTH 8 /* Good for authentication. */ ++#define GCRY_PK_USAGE_UNKN 128 /* Unknown usage flag. */ ++ ++/* Encrypt the DATA using the public key PKEY and store the result as ++ a newly created S-expression at RESULT. */ ++gcry_error_t gcry_pk_encrypt (gcry_sexp_t *result, ++ gcry_sexp_t data, gcry_sexp_t pkey); ++ ++/* Decrypt the DATA using the private key SKEY and store the result as ++ a newly created S-expression at RESULT. */ ++gcry_error_t gcry_pk_decrypt (gcry_sexp_t *result, ++ gcry_sexp_t data, gcry_sexp_t skey); ++ ++/* Sign the DATA using the private key SKEY and store the result as ++ a newly created S-expression at RESULT. */ ++gcry_error_t gcry_pk_sign (gcry_sexp_t *result, ++ gcry_sexp_t data, gcry_sexp_t skey); ++ ++/* Check the signature SIGVAL on DATA using the public key PKEY. */ ++gcry_error_t gcry_pk_verify (gcry_sexp_t sigval, ++ gcry_sexp_t data, gcry_sexp_t pkey); ++ ++/* Check that private KEY is sane. */ ++gcry_error_t gcry_pk_testkey (gcry_sexp_t key); ++ ++/* Generate a new key pair according to the parameters given in ++ S_PARMS. The new key pair is returned in as an S-expression in ++ R_KEY. */ ++gcry_error_t gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms); ++ ++/* Catch all function for miscellaneous operations. */ ++gcry_error_t gcry_pk_ctl (int cmd, void *buffer, size_t buflen); ++ ++/* Retrieve information about the public key algorithm ALGO. */ ++gcry_error_t gcry_pk_algo_info (int algo, int what, ++ void *buffer, size_t *nbytes); ++ ++/* Map the public key algorithm whose ID is contained in ALGORITHM to ++ a string representation of the algorithm name. For unknown ++ algorithm IDs this functions returns "?". */ ++const char *gcry_pk_algo_name (int algorithm) _GCRY_GCC_ATTR_PURE; ++ ++/* Map the algorithm NAME to a public key algorithm Id. Return 0 if ++ the algorithm name is not known. */ ++int gcry_pk_map_name (const char* name) _GCRY_GCC_ATTR_PURE; ++ ++/* Return what is commonly referred as the key length for the given ++ public or private KEY. */ ++unsigned int gcry_pk_get_nbits (gcry_sexp_t key) _GCRY_GCC_ATTR_PURE; ++ ++/* Please note that keygrip is still experimental and should not be ++ used without contacting the author. */ ++unsigned char *gcry_pk_get_keygrip (gcry_sexp_t key, unsigned char *array); ++ ++/* Return the name of the curve matching KEY. */ ++const char *gcry_pk_get_curve (gcry_sexp_t key, int iterator, ++ unsigned int *r_nbits); ++ ++/* Return an S-expression with the parameters of the named ECC curve ++ NAME. ALGO must be set to an ECC algorithm. */ ++gcry_sexp_t gcry_pk_get_param (int algo, const char *name); ++ ++/* Return 0 if the public key algorithm A is available for use. */ ++#define gcry_pk_test_algo(a) \ ++ gcry_pk_algo_info( (a), GCRYCTL_TEST_ALGO, NULL, NULL ) ++ ++ ++ ++ ++/************************************ ++ * * ++ * Cryptograhic Hash Functions * ++ * * ++ ************************************/ ++ ++/* Algorithm IDs for the hash functions we know about. Not all of them ++ are implemnted. */ ++enum gcry_md_algos ++ { ++ GCRY_MD_NONE = 0, ++ GCRY_MD_MD5 = 1, ++ GCRY_MD_SHA1 = 2, ++ GCRY_MD_RMD160 = 3, ++ GCRY_MD_MD2 = 5, ++ GCRY_MD_TIGER = 6, /* TIGER/192 as used by gpg <= 1.3.2. */ ++ GCRY_MD_HAVAL = 7, /* HAVAL, 5 pass, 160 bit. */ ++ GCRY_MD_SHA256 = 8, ++ GCRY_MD_SHA384 = 9, ++ GCRY_MD_SHA512 = 10, ++ GCRY_MD_SHA224 = 11, ++ GCRY_MD_MD4 = 301, ++ GCRY_MD_CRC32 = 302, ++ GCRY_MD_CRC32_RFC1510 = 303, ++ GCRY_MD_CRC24_RFC2440 = 304, ++ GCRY_MD_WHIRLPOOL = 305, ++ GCRY_MD_TIGER1 = 306, /* TIGER fixed. */ ++ GCRY_MD_TIGER2 = 307 /* TIGER2 variant. */ ++ }; ++ ++/* Flags used with the open function. */ ++enum gcry_md_flags ++ { ++ GCRY_MD_FLAG_SECURE = 1, /* Allocate all buffers in "secure" memory. */ ++ GCRY_MD_FLAG_HMAC = 2 /* Make an HMAC out of this algorithm. */ ++ }; ++ ++/* (Forward declaration.) */ ++struct gcry_md_context; ++ ++/* This object is used to hold a handle to a message digest object. ++ This structure is private - only to be used by the public gcry_md_* ++ macros. */ ++typedef struct gcry_md_handle ++{ ++ /* Actual context. */ ++ struct gcry_md_context *ctx; ++ ++ /* Buffer management. */ ++ int bufpos; ++ int bufsize; ++ unsigned char buf[1]; ++} *gcry_md_hd_t; ++ ++/* Compatibility types, do not use them. */ ++#ifndef GCRYPT_NO_DEPRECATED ++typedef struct gcry_md_handle *GCRY_MD_HD _GCRY_GCC_ATTR_DEPRECATED; ++typedef struct gcry_md_handle *GcryMDHd _GCRY_GCC_ATTR_DEPRECATED; ++#endif ++ ++/* Create a message digest object for algorithm ALGO. FLAGS may be ++ given as an bitwise OR of the gcry_md_flags values. ALGO may be ++ given as 0 if the algorithms to be used are later set using ++ gcry_md_enable. */ ++gcry_error_t gcry_md_open (gcry_md_hd_t *h, int algo, unsigned int flags); ++ ++/* Release the message digest object HD. */ ++void gcry_md_close (gcry_md_hd_t hd); ++ ++/* Add the message digest algorithm ALGO to the digest object HD. */ ++gcry_error_t gcry_md_enable (gcry_md_hd_t hd, int algo); ++ ++/* Create a new digest object as an exact copy of the object HD. */ ++gcry_error_t gcry_md_copy (gcry_md_hd_t *bhd, gcry_md_hd_t ahd); ++ ++/* Reset the digest object HD to its initial state. */ ++void gcry_md_reset (gcry_md_hd_t hd); ++ ++/* Perform various operations on the digest object HD. */ ++gcry_error_t gcry_md_ctl (gcry_md_hd_t hd, int cmd, ++ void *buffer, size_t buflen); ++ ++/* Pass LENGTH bytes of data in BUFFER to the digest object HD so that ++ it can update the digest values. This is the actual hash ++ function. */ ++void gcry_md_write (gcry_md_hd_t hd, const void *buffer, size_t length); ++ ++/* Read out the final digest from HD return the digest value for ++ algorithm ALGO. */ ++unsigned char *gcry_md_read (gcry_md_hd_t hd, int algo); ++ ++/* Convenience function to calculate the hash from the data in BUFFER ++ of size LENGTH using the algorithm ALGO avoiding the creating of a ++ hash object. The hash is returned in the caller provided buffer ++ DIGEST which must be large enough to hold the digest of the given ++ algorithm. */ ++void gcry_md_hash_buffer (int algo, void *digest, ++ const void *buffer, size_t length); ++ ++/* Retrieve the algorithm used with HD. This does not work reliable ++ if more than one algorithm is enabled in HD. */ ++int gcry_md_get_algo (gcry_md_hd_t hd); ++ ++/* Retrieve the length in bytes of the digest yielded by algorithm ++ ALGO. */ ++unsigned int gcry_md_get_algo_dlen (int algo); ++ ++/* Return true if the the algorithm ALGO is enabled in the digest ++ object A. */ ++int gcry_md_is_enabled (gcry_md_hd_t a, int algo); ++ ++/* Return true if the digest object A is allocated in "secure" memory. */ ++int gcry_md_is_secure (gcry_md_hd_t a); ++ ++/* Retrieve various information about the object H. */ ++gcry_error_t gcry_md_info (gcry_md_hd_t h, int what, void *buffer, ++ size_t *nbytes); ++ ++/* Retrieve various information about the algorithm ALGO. */ ++gcry_error_t gcry_md_algo_info (int algo, int what, void *buffer, ++ size_t *nbytes); ++ ++/* Map the digest algorithm id ALGO to a string representation of the ++ algorithm name. For unknown algorithms this function returns ++ "?". */ ++const char *gcry_md_algo_name (int algo) _GCRY_GCC_ATTR_PURE; ++ ++/* Map the algorithm NAME to a digest algorithm Id. Return 0 if ++ the algorithm name is not known. */ ++int gcry_md_map_name (const char* name) _GCRY_GCC_ATTR_PURE; ++ ++/* For use with the HMAC feature, the set MAC key to the KEY of ++ KEYLEN bytes. */ ++gcry_error_t gcry_md_setkey (gcry_md_hd_t hd, const void *key, size_t keylen); ++ ++/* Start or stop debugging for digest handle HD; i.e. create a file ++ named dbgmd-. while hashing. If SUFFIX is NULL, ++ debugging stops and the file will be closed. */ ++void gcry_md_debug (gcry_md_hd_t hd, const char *suffix); ++ ++ ++/* Update the hash(s) of H with the character C. This is a buffered ++ version of the gcry_md_write function. */ ++#define gcry_md_putc(h,c) \ ++ do { \ ++ gcry_md_hd_t h__ = (h); \ ++ if( (h__)->bufpos == (h__)->bufsize ) \ ++ gcry_md_write( (h__), NULL, 0 ); \ ++ (h__)->buf[(h__)->bufpos++] = (c) & 0xff; \ ++ } while(0) ++ ++/* Finalize the digest calculation. This is not really needed because ++ gcry_md_read() does this implicitly. */ ++#define gcry_md_final(a) \ ++ gcry_md_ctl ((a), GCRYCTL_FINALIZE, NULL, 0) ++ ++/* Return 0 if the algorithm A is available for use. */ ++#define gcry_md_test_algo(a) \ ++ gcry_md_algo_info( (a), GCRYCTL_TEST_ALGO, NULL, NULL ) ++ ++/* Return an DER encoded ASN.1 OID for the algorithm A in buffer B. N ++ must point to size_t variable with the available size of buffer B. ++ After return it will receive the actual size of the returned ++ OID. */ ++#define gcry_md_get_asnoid(a,b,n) \ ++ gcry_md_algo_info((a), GCRYCTL_GET_ASNOID, (b), (n)) ++ ++ ++ ++/****************************** ++ * * ++ * Key Derivation Functions * ++ * * ++ ******************************/ ++ ++/* Algorithm IDs for the KDFs. */ ++enum gcry_kdf_algos ++ { ++ GCRY_KDF_NONE = 0, ++ GCRY_KDF_SIMPLE_S2K = 16, ++ GCRY_KDF_SALTED_S2K = 17, ++ GCRY_KDF_ITERSALTED_S2K = 19, ++ GCRY_KDF_PBKDF1 = 33, ++ GCRY_KDF_PBKDF2 = 34 ++ }; ++ ++/* Derive a key from a passphrase. */ ++gpg_error_t gcry_kdf_derive (const void *passphrase, size_t passphraselen, ++ int algo, int subalgo, ++ const void *salt, size_t saltlen, ++ unsigned long iterations, ++ size_t keysize, void *keybuffer); ++ ++ ++ ++ ++/************************************ ++ * * ++ * Random Generating Functions * ++ * * ++ ************************************/ ++ ++/* The possible values for the random quality. The rule of thumb is ++ to use STRONG for session keys and VERY_STRONG for key material. ++ WEAK is usually an alias for STRONG and should not be used anymore ++ (except with gcry_mpi_randomize); use gcry_create_nonce instead. */ ++typedef enum gcry_random_level ++ { ++ GCRY_WEAK_RANDOM = 0, ++ GCRY_STRONG_RANDOM = 1, ++ GCRY_VERY_STRONG_RANDOM = 2 ++ } ++gcry_random_level_t; ++ ++/* Fill BUFFER with LENGTH bytes of random, using random numbers of ++ quality LEVEL. */ ++void gcry_randomize (void *buffer, size_t length, ++ enum gcry_random_level level); ++ ++/* Add the external random from BUFFER with LENGTH bytes into the ++ pool. QUALITY should either be -1 for unknown or in the range of 0 ++ to 100 */ ++gcry_error_t gcry_random_add_bytes (const void *buffer, size_t length, ++ int quality); ++ ++/* If random numbers are used in an application, this macro should be ++ called from time to time so that new stuff gets added to the ++ internal pool of the RNG. */ ++#define gcry_fast_random_poll() gcry_control (GCRYCTL_FAST_POLL, NULL) ++ ++ ++/* Return NBYTES of allocated random using a random numbers of quality ++ LEVEL. */ ++void *gcry_random_bytes (size_t nbytes, enum gcry_random_level level) ++ _GCRY_GCC_ATTR_MALLOC; ++ ++/* Return NBYTES of allocated random using a random numbers of quality ++ LEVEL. The random numbers are created returned in "secure" ++ memory. */ ++void *gcry_random_bytes_secure (size_t nbytes, enum gcry_random_level level) ++ _GCRY_GCC_ATTR_MALLOC; ++ ++ ++/* Set the big integer W to a random value of NBITS using a random ++ generator with quality LEVEL. Note that by using a level of ++ GCRY_WEAK_RANDOM gcry_create_nonce is used internally. */ ++void gcry_mpi_randomize (gcry_mpi_t w, ++ unsigned int nbits, enum gcry_random_level level); ++ ++ ++/* Create an unpredicable nonce of LENGTH bytes in BUFFER. */ ++void gcry_create_nonce (void *buffer, size_t length); ++ ++ ++ ++ ++ ++/*******************************/ ++/* */ ++/* Prime Number Functions */ ++/* */ ++/*******************************/ ++ ++/* Mode values passed to a gcry_prime_check_func_t. */ ++#define GCRY_PRIME_CHECK_AT_FINISH 0 ++#define GCRY_PRIME_CHECK_AT_GOT_PRIME 1 ++#define GCRY_PRIME_CHECK_AT_MAYBE_PRIME 2 ++ ++/* The function should return 1 if the operation shall continue, 0 to ++ reject the prime candidate. */ ++typedef int (*gcry_prime_check_func_t) (void *arg, int mode, ++ gcry_mpi_t candidate); ++ ++/* Flags for gcry_prime_generate(): */ ++ ++/* Allocate prime numbers and factors in secure memory. */ ++#define GCRY_PRIME_FLAG_SECRET (1 << 0) ++ ++/* Make sure that at least one prime factor is of size ++ `FACTOR_BITS'. */ ++#define GCRY_PRIME_FLAG_SPECIAL_FACTOR (1 << 1) ++ ++/* Generate a new prime number of PRIME_BITS bits and store it in ++ PRIME. If FACTOR_BITS is non-zero, one of the prime factors of ++ (prime - 1) / 2 must be FACTOR_BITS bits long. If FACTORS is ++ non-zero, allocate a new, NULL-terminated array holding the prime ++ factors and store it in FACTORS. FLAGS might be used to influence ++ the prime number generation process. */ ++gcry_error_t gcry_prime_generate (gcry_mpi_t *prime, ++ unsigned int prime_bits, ++ unsigned int factor_bits, ++ gcry_mpi_t **factors, ++ gcry_prime_check_func_t cb_func, ++ void *cb_arg, ++ gcry_random_level_t random_level, ++ unsigned int flags); ++ ++/* Find a generator for PRIME where the factorization of (prime-1) is ++ in the NULL terminated array FACTORS. Return the generator as a ++ newly allocated MPI in R_G. If START_G is not NULL, use this as ++ teh start for the search. */ ++gcry_error_t gcry_prime_group_generator (gcry_mpi_t *r_g, ++ gcry_mpi_t prime, ++ gcry_mpi_t *factors, ++ gcry_mpi_t start_g); ++ ++ ++/* Convenience function to release the FACTORS array. */ ++void gcry_prime_release_factors (gcry_mpi_t *factors); ++ ++ ++/* Check wether the number X is prime. */ ++gcry_error_t gcry_prime_check (gcry_mpi_t x, unsigned int flags); ++ ++ ++ ++/************************************ ++ * * ++ * Miscellaneous Stuff * ++ * * ++ ************************************/ ++ ++/* Log levels used by the internal logging facility. */ ++enum gcry_log_levels ++ { ++ GCRY_LOG_CONT = 0, /* (Continue the last log line.) */ ++ GCRY_LOG_INFO = 10, ++ GCRY_LOG_WARN = 20, ++ GCRY_LOG_ERROR = 30, ++ GCRY_LOG_FATAL = 40, ++ GCRY_LOG_BUG = 50, ++ GCRY_LOG_DEBUG = 100 ++ }; ++ ++/* Type for progress handlers. */ ++typedef void (*gcry_handler_progress_t) (void *, const char *, int, int, int); ++ ++/* Type for memory allocation handlers. */ ++typedef void *(*gcry_handler_alloc_t) (size_t n); ++ ++/* Type for secure memory check handlers. */ ++typedef int (*gcry_handler_secure_check_t) (const void *); ++ ++/* Type for memory reallocation handlers. */ ++typedef void *(*gcry_handler_realloc_t) (void *p, size_t n); ++ ++/* Type for memory free handlers. */ ++typedef void (*gcry_handler_free_t) (void *); ++ ++/* Type for out-of-memory handlers. */ ++typedef int (*gcry_handler_no_mem_t) (void *, size_t, unsigned int); ++ ++/* Type for fatal error handlers. */ ++typedef void (*gcry_handler_error_t) (void *, int, const char *); ++ ++/* Type for logging handlers. */ ++typedef void (*gcry_handler_log_t) (void *, int, const char *, va_list); ++ ++/* Certain operations can provide progress information. This function ++ is used to register a handler for retrieving these information. */ ++void gcry_set_progress_handler (gcry_handler_progress_t cb, void *cb_data); ++ ++ ++/* Register a custom memory allocation functions. */ ++void gcry_set_allocation_handler ( ++ gcry_handler_alloc_t func_alloc, ++ gcry_handler_alloc_t func_alloc_secure, ++ gcry_handler_secure_check_t func_secure_check, ++ gcry_handler_realloc_t func_realloc, ++ gcry_handler_free_t func_free); ++ ++/* Register a function used instead of the internal out of memory ++ handler. */ ++void gcry_set_outofcore_handler (gcry_handler_no_mem_t h, void *opaque); ++ ++/* Register a function used instead of the internal fatal error ++ handler. */ ++void gcry_set_fatalerror_handler (gcry_handler_error_t fnc, void *opaque); ++ ++/* Register a function used instead of the internal logging ++ facility. */ ++void gcry_set_log_handler (gcry_handler_log_t f, void *opaque); ++ ++/* Reserved for future use. */ ++void gcry_set_gettext_handler (const char *(*f)(const char*)); ++ ++/* Libgcrypt uses its own memory allocation. It is important to use ++ gcry_free () to release memory allocated by libgcrypt. */ ++void *gcry_malloc (size_t n) _GCRY_GCC_ATTR_MALLOC; ++void *gcry_calloc (size_t n, size_t m) _GCRY_GCC_ATTR_MALLOC; ++void *gcry_malloc_secure (size_t n) _GCRY_GCC_ATTR_MALLOC; ++void *gcry_calloc_secure (size_t n, size_t m) _GCRY_GCC_ATTR_MALLOC; ++void *gcry_realloc (void *a, size_t n); ++char *gcry_strdup (const char *string) _GCRY_GCC_ATTR_MALLOC; ++void *gcry_xmalloc (size_t n) _GCRY_GCC_ATTR_MALLOC; ++void *gcry_xcalloc (size_t n, size_t m) _GCRY_GCC_ATTR_MALLOC; ++void *gcry_xmalloc_secure (size_t n) _GCRY_GCC_ATTR_MALLOC; ++void *gcry_xcalloc_secure (size_t n, size_t m) _GCRY_GCC_ATTR_MALLOC; ++void *gcry_xrealloc (void *a, size_t n); ++char *gcry_xstrdup (const char * a) _GCRY_GCC_ATTR_MALLOC; ++void gcry_free (void *a); ++ ++/* Return true if A is allocated in "secure" memory. */ ++int gcry_is_secure (const void *a) _GCRY_GCC_ATTR_PURE; ++ ++/* Return true if Libgcrypt is in FIPS mode. */ ++#define gcry_fips_mode_active() !!gcry_control (GCRYCTL_FIPS_MODE_P, 0) ++ ++ ++#if 0 /* (Keep Emacsens' auto-indent happy.) */ ++{ ++#endif ++#ifdef __cplusplus ++} ++#endif ++#endif /* _GCRYPT_H */ ++/* ++@emacs_local_vars_begin@ ++@emacs_local_vars_read_only@ ++@emacs_local_vars_end@ ++*/ +diff --git a/include/grub/gcrypt/gpg-error.h b/include/grub/gcrypt/gpg-error.h +new file mode 100644 +index 0000000..1e42502 +--- /dev/null ++++ b/include/grub/gcrypt/gpg-error.h +@@ -0,0 +1,32 @@ ++#ifndef GRUB_GPG_ERROR_H ++#define GRUB_GPG_ERROR_H 1 ++ ++#include ++typedef enum ++ { ++ GPG_ERR_SOURCE_USER_1 ++ } ++ gpg_err_source_t; ++#define GPG_ERR_INLINE inline ++static inline int ++gpg_err_make (gpg_err_source_t source __attribute__ ((unused)), gpg_err_code_t code) ++{ ++ return code; ++} ++ ++static inline gpg_err_code_t ++gpg_err_code (gpg_error_t err) ++{ ++ return err; ++} ++ ++static inline gpg_err_source_t ++gpg_err_source (gpg_error_t err __attribute__ ((unused))) ++{ ++ return GPG_ERR_SOURCE_USER_1; ++} ++ ++gcry_err_code_t ++gpg_error_from_syserror (void); ++ ++#endif +diff --git a/include/grub/kernel.h b/include/grub/kernel.h +index eef4c3f..033479e 100644 +--- a/include/grub/kernel.h ++++ b/include/grub/kernel.h +@@ -27,7 +27,8 @@ enum + OBJ_TYPE_ELF, + OBJ_TYPE_MEMDISK, + OBJ_TYPE_CONFIG, +- OBJ_TYPE_PREFIX ++ OBJ_TYPE_PREFIX, ++ OBJ_TYPE_PUBKEY + }; + + /* The module header. */ +@@ -77,7 +78,7 @@ extern grub_addr_t EXPORT_VAR (grub_modbase); + var && (grub_addr_t) var \ + < (grub_modbase + (((struct grub_module_info *) grub_modbase)->size)); \ + var = (struct grub_module_header *) \ +- ((grub_uint32_t *) var + ((struct grub_module_header *) var)->size / 4)) ++ ((void **) var + (((struct grub_module_header *) var)->size + sizeof (void *) - 1) / sizeof (void *))) + + grub_addr_t grub_modules_get_end (void); + +diff --git a/include/grub/pubkey.h b/include/grub/pubkey.h +new file mode 100644 +index 0000000..4a9d04b +--- /dev/null ++++ b/include/grub/pubkey.h +@@ -0,0 +1,38 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2013 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_PUBKEY_HEADER ++#define GRUB_PUBKEY_HEADER 1 ++ ++#include ++ ++struct grub_public_key * ++grub_load_public_key (grub_file_t f); ++ ++grub_err_t ++grub_verify_signature (grub_file_t f, grub_file_t sig, ++ struct grub_public_key *pk); ++ ++ ++struct grub_public_subkey * ++grub_crypto_pk_locate_subkey (grub_uint64_t keyid, struct grub_public_key *pkey); ++ ++struct grub_public_subkey * ++grub_crypto_pk_locate_subkey_in_trustdb (grub_uint64_t keyid); ++ ++#endif +diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c +index a551bbb..23a9970 100644 +--- a/util/grub-mkimage.c ++++ b/util/grub-mkimage.c +@@ -701,8 +701,8 @@ struct fixup_block_list + static void + generate_image (const char *dir, const char *prefix, + FILE *out, const char *outname, char *mods[], +- char *memdisk_path, char *config_path, +- struct image_target_desc *image_target, int note, ++ char *memdisk_path, char **pubkey_paths, size_t npubkeys, ++ char *config_path, struct image_target_desc *image_target, int note, + grub_compression_t comp) + { + char *kernel_img, *core_img; +@@ -734,6 +734,18 @@ generate_image (const char *dir, const char *prefix, + else + total_module_size = sizeof (struct grub_module_info32); + ++ { ++ size_t i; ++ for (i = 0; i < npubkeys; i++) ++ { ++ size_t curs; ++ curs = ALIGN_ADDR (grub_util_get_image_size (pubkey_paths[i])); ++ grub_util_info ("the size of public key is 0x%llx", ++ (unsigned long long) pubkey_paths[i]); ++ total_module_size += curs + sizeof (struct grub_module_header); ++ } ++ } ++ + if (memdisk_path) + { + memdisk_size = ALIGN_UP(grub_util_get_image_size (memdisk_path), 512); +@@ -835,6 +847,26 @@ generate_image (const char *dir, const char *prefix, + offset += mod_size; + } + ++ { ++ size_t i; ++ for (i = 0; i < npubkeys; i++) ++ { ++ size_t curs; ++ struct grub_module_header *header; ++ ++ curs = grub_util_get_image_size (pubkey_paths[i]); ++ ++ header = (struct grub_module_header *) (kernel_img + offset); ++ memset (header, 0, sizeof (struct grub_module_header)); ++ header->type = grub_host_to_target32 (OBJ_TYPE_PUBKEY); ++ header->size = grub_host_to_target32 (curs + sizeof (*header)); ++ offset += sizeof (*header); ++ ++ grub_util_load_image (pubkey_paths[i], kernel_img + offset); ++ offset += ALIGN_ADDR (curs); ++ } ++ } ++ + if (memdisk_path) + { + struct grub_module_header *header; +@@ -1654,6 +1686,8 @@ static struct argp_option options[] = { + N_("embed FILE as a memdisk image"), 0}, + /* TRANSLATORS: "embed" is a verb (command description). "*/ + {"config", 'c', N_("FILE"), 0, N_("embed FILE as an early config"), 0}, ++ /* TRANSLATORS: "embed" is a verb (command description). "*/ ++ {"pubkey", 'k', N_("FILE"), 0, N_("embed FILE as public key for signature checking"), 0}, + /* TRANSLATORS: NOTE is a name of segment. */ + {"note", 'n', 0, 0, N_("add NOTE segment for CHRP IEEE1275"), 0}, + {"output", 'o', N_("FILE"), 0, N_("output a generated image to FILE [default=stdout]"), 0}, +@@ -1709,6 +1743,8 @@ struct arguments + char *dir; + char *prefix; + char *memdisk; ++ char **pubkeys; ++ size_t npubkeys; + char *font; + char *config; + int note; +@@ -1771,6 +1807,13 @@ argp_parser (int key, char *arg, struct argp_state *state) + arguments->prefix = xstrdup ("(memdisk)/boot/grub"); + break; + ++ case 'k': ++ arguments->pubkeys = xrealloc (arguments->pubkeys, ++ sizeof (arguments->pubkeys[0]) ++ * (arguments->npubkeys + 1)); ++ arguments->pubkeys[arguments->npubkeys++] = xstrdup (arg); ++ break; ++ + case 'c': + if (arguments->config) + free (arguments->config); +@@ -1879,7 +1922,8 @@ main (int argc, char *argv[]) + + generate_image (arguments.dir, arguments.prefix ? : DEFAULT_DIRECTORY, fp, + arguments.output, +- arguments.modules, arguments.memdisk, arguments.config, ++ arguments.modules, arguments.memdisk, arguments.pubkeys, ++ arguments.npubkeys, arguments.config, + arguments.image_target, arguments.note, arguments.comp); + + fflush (fp); +diff --git a/util/import_gcry.py b/util/import_gcry.py +index 64c5870..18f5253 100644 +--- a/util/import_gcry.py ++++ b/util/import_gcry.py +@@ -39,6 +39,17 @@ try: + os.makedirs (cipher_dir_out) + except: + print ("WARNING: %s already exists" % cipher_dir_out) ++mpidir = os.path.join (basedir, "mpi") ++try: ++ os.makedirs (mpidir) ++except: ++ print ("WARNING: %s already exists" % mpidir) ++ ++srcdir = os.path.join (basedir, "src") ++try: ++ os.makedirs (srcdir) ++except: ++ print ("WARNING: %s already exists" % srcdir) + + cipher_files = sorted (os.listdir (cipher_dir_in)) + conf = codecs.open (os.path.join ("grub-core", "Makefile.gcry.def"), "w", "utf-8") +@@ -52,7 +63,7 @@ confutil.write (" cppflags = '$(CPPFLAGS_GCRY)';\n"); + confutil.write (" extra_dist = grub-core/lib/libgcrypt-grub/cipher/ChangeLog;\n"); + confutil.write ("\n"); + chlog = "" +-modules = [] ++modules_sym_md = [] + + # Strictly speaking CRC32/CRC24 work on bytes so this value should be 1 + # But libgcrypt uses 64. Let's keep the value for compatibility. Since +@@ -69,6 +80,8 @@ mdblocksizes = {"_gcry_digest_spec_crc32" : 64, + "_gcry_digest_spec_sha384" : 128, + "_gcry_digest_spec_sha512" : 128, + "_gcry_digest_spec_tiger" : 64, ++ "_gcry_digest_spec_tiger1" : 64, ++ "_gcry_digest_spec_tiger2" : 64, + "_gcry_digest_spec_whirlpool" : 64} + + cryptolist = codecs.open (os.path.join (cipher_dir_out, "crypto.lst"), "w", "utf-8") +@@ -92,7 +105,7 @@ for cipher_file in cipher_files: + if cipher_file == "ChangeLog": + continue + chlognew = " * %s" % cipher_file +- if re.match ("(Manifest|Makefile\.am|ac\.c|cipher\.c|hash-common\.c|hmac-tests\.c|md\.c|pubkey\.c)$", cipher_file): ++ if re.match ("(Manifest|Makefile\.am|ac\.c|cipher\.c|hash-common\.c|hmac-tests\.c|md\.c|pubkey\.c)$", cipher_file) or cipher_file == "elgamal.c" or cipher_file == "primegen.c" or cipher_file == "test-getrusage.c": + chlog = "%s%s: Removed\n" % (chlog, chlognew) + continue + # Autogenerated files. Not even worth mentionning in ChangeLog +@@ -124,10 +137,12 @@ for cipher_file in cipher_files: + + ciphernames = [] + mdnames = [] ++ pknames = [] + hold = False + skip = False + skip2 = False + ismd = False ++ ispk = False + iscipher = False + iscryptostart = False + iscomma = False +@@ -159,7 +174,7 @@ for cipher_file in cipher_files: + sg = s.groups()[0] + cryptolist.write (("%s: %s\n") % (sg, modname)) + iscryptostart = False +- if ismd or iscipher: ++ if ismd or iscipher or ispk: + if not re.search (" *};", line) is None: + if not iscomma: + fw.write (" ,\n") +@@ -175,6 +190,7 @@ for cipher_file in cipher_files: + % mdblocksizes [mdname]) + ismd = False + iscipher = False ++ ispk = False + iscomma = not re.search (",$", line) is None + # Used only for selftests. + m = re.match ("(static byte|static unsigned char) (weak_keys_chksum)\[[0-9]*\] =", line) +@@ -190,18 +206,33 @@ for cipher_file in cipher_files: + continue + if hold: + hold = False +- # We're optimising for size. +- if not re.match ("(run_selftests|selftest|_gcry_aes_c.._..c|_gcry_[a-z0-9]*_hash_buffer|tripledes_set2keys|do_tripledes_set_extra_info|_gcry_rmd160_mixblock|serpent_test)", line) is None: ++ # We're optimising for size and exclude anything needing good ++ # randomness. ++ if not re.match ("(run_selftests|selftest|_gcry_aes_c.._..c|_gcry_[a-z0-9]*_hash_buffer|tripledes_set2keys|do_tripledes_set_extra_info|_gcry_rmd160_mixblock|serpent_test|dsa_generate_ext|test_keys|gen_k|sign|gen_x931_parm_xp|generate_x931|generate_key|dsa_generate|dsa_sign|ecc_sign|generate|generate_fips186|_gcry_register_pk_dsa_progress|_gcry_register_pk_ecc_progress|progress|scanval|ec2os|ecc_generate_ext|ecc_generate|compute_keygrip|ecc_get_param|_gcry_register_pk_dsa_progress|gen_x931_parm_xp|gen_x931_parm_xi|rsa_decrypt|rsa_sign|rsa_generate_ext|rsa_generate|secret|check_exponent|rsa_blind|rsa_unblind|extract_a_from_sexp|curve_free|curve_copy|point_set)", line) is None: + skip = True + if not re.match ("serpent_test", line) is None: + fw.write ("static const char *serpent_test (void) { return 0; }\n"); ++ if not re.match ("dsa_generate", line) is None: ++ fw.write ("#define dsa_generate 0"); ++ if not re.match ("ecc_generate", line) is None: ++ fw.write ("#define ecc_generate 0"); ++ if not re.match ("rsa_generate ", line) is None: ++ fw.write ("#define rsa_generate 0"); ++ if not re.match ("rsa_sign", line) is None: ++ fw.write ("#define rsa_sign 0"); ++ if not re.match ("rsa_decrypt", line) is None: ++ fw.write ("#define rsa_decrypt 0"); ++ if not re.match ("dsa_sign", line) is None: ++ fw.write ("#define dsa_sign 0"); ++ if not re.match ("ecc_sign", line) is None: ++ fw.write ("#define ecc_sign 0"); + fname = re.match ("[a-zA-Z0-9_]*", line).group () + chmsg = "(%s): Removed." % fname + if nch: + chlognew = "%s\n %s" % (chlognew, chmsg) + else: + chlognew = "%s %s" % (chlognew, chmsg) +- nch = True ++ nch = True + continue + else: + fw.write (holdline) +@@ -216,7 +247,8 @@ for cipher_file in cipher_files: + continue + m = re.match ("gcry_cipher_spec_t", line) + if isc and not m is None: +- assert (not iscryptostart) ++ assert (not ismd) ++ assert (not ispk) + assert (not iscipher) + assert (not iscryptostart) + ciphername = line [len ("gcry_cipher_spec_t"):].strip () +@@ -224,9 +256,23 @@ for cipher_file in cipher_files: + ciphernames.append (ciphername) + iscipher = True + iscryptostart = True ++ ++ m = re.match ("gcry_pk_spec_t", line) ++ if isc and not m is None: ++ assert (not ismd) ++ assert (not ispk) ++ assert (not iscipher) ++ assert (not iscryptostart) ++ pkname = line [len ("gcry_pk_spec_t"):].strip () ++ pkname = re.match("[a-zA-Z0-9_]*",pkname).group () ++ pknames.append (pkname) ++ ispk = True ++ iscryptostart = True ++ + m = re.match ("gcry_md_spec_t", line) + if isc and not m is None: + assert (not ismd) ++ assert (not ispk) + assert (not iscipher) + assert (not iscryptostart) + mdname = line [len ("gcry_md_spec_t"):].strip () +@@ -245,7 +291,53 @@ for cipher_file in cipher_files: + chlognew = "%s %s" % (chlognew, chmsg) + nch = True + continue +- m = re.match ("(static const char( |)\*|static gpg_err_code_t|void|static int|static gcry_err_code_t)$", line) ++ m = re.match ("static gcry_mpi_t gen_k .*;$", line) ++ if not m is None: ++ chmsg = "(gen_k): Removed declaration." ++ if nch: ++ chlognew = "%s\n %s" % (chlognew, chmsg) ++ else: ++ chlognew = "%s %s" % (chlognew, chmsg) ++ nch = True ++ continue ++ m = re.match ("static (int|void) test_keys .*;$", line) ++ if not m is None: ++ chmsg = "(test_keys): Removed declaration." ++ if nch: ++ chlognew = "%s\n %s" % (chlognew, chmsg) ++ else: ++ chlognew = "%s %s" % (chlognew, chmsg) ++ nch = True ++ continue ++ m = re.match ("static void secret .*;$", line) ++ if not m is None: ++ chmsg = "(secret): Removed declaration." ++ if nch: ++ chlognew = "%s\n %s" % (chlognew, chmsg) ++ else: ++ chlognew = "%s %s" % (chlognew, chmsg) ++ nch = True ++ continue ++ m = re.match ("static void \(\*progress_cb\).*;$", line) ++ if not m is None: ++ chmsg = "(progress_cb): Removed declaration." ++ if nch: ++ chlognew = "%s\n %s" % (chlognew, chmsg) ++ else: ++ chlognew = "%s %s" % (chlognew, chmsg) ++ nch = True ++ continue ++ m = re.match ("static void \*progress_cb_data.*;$", line) ++ if not m is None: ++ chmsg = "(progress_cb): Removed declaration." ++ if nch: ++ chlognew = "%s\n %s" % (chlognew, chmsg) ++ else: ++ chlognew = "%s %s" % (chlognew, chmsg) ++ nch = True ++ continue ++ ++ m = re.match ("(static const char( |)\*|static gpg_err_code_t|void|static int|static gcry_err_code_t|static gcry_mpi_t|static void|void|static elliptic_curve_t) *$", line) + if not m is None: + hold = True + holdline = line +@@ -257,6 +349,12 @@ for cipher_file in cipher_files: + if not m is None: + skip_statement = True + continue ++ m = re.match ("static void sign|static gpg_err_code_t sign|static gpg_err_code_t generate", ++ line) ++ if not m is None: ++ skip_statement = True ++ continue ++ + m = re.match ("cipher_extra_spec_t", line) + if isc and not m is None: + skip2 = True +@@ -269,6 +367,18 @@ for cipher_file in cipher_files: + chlognew = "%s %s" % (chlognew, chmsg) + nch = True + continue ++ m = re.match ("pk_extra_spec_t", line) ++ if isc and not m is None: ++ skip2 = True ++ fname = line[len ("pk_extra_spec_t "):] ++ fname = re.match ("[a-zA-Z0-9_]*", fname).group () ++ chmsg = "(%s): Removed." % fname ++ if nch: ++ chlognew = "%s\n %s" % (chlognew, chmsg) ++ else: ++ chlognew = "%s %s" % (chlognew, chmsg) ++ nch = True ++ continue + m = re.match ("md_extra_spec_t", line) + if isc and not m is None: + skip2 = True +@@ -282,13 +392,14 @@ for cipher_file in cipher_files: + nch = True + continue + fw.write (line) +- if len (ciphernames) > 0 or len (mdnames) > 0: ++ if len (ciphernames) > 0 or len (mdnames) > 0 or len (pknames) > 0: + if isglue: + modfiles = "lib/libgcrypt-grub/cipher/%s lib/libgcrypt-grub/cipher/%s" \ + % (cipher_file, cipher_file.replace ("-glue.c", ".c")) + else: + modfiles = "lib/libgcrypt-grub/cipher/%s" % cipher_file +- modules.append (modname) ++ if len (ciphernames) > 0 or len (mdnames) > 0: ++ modules_sym_md.append (modname) + chmsg = "(GRUB_MOD_INIT(%s)): New function\n" % modname + if nch: + chlognew = "%s\n %s" % (chlognew, chmsg) +@@ -305,6 +416,11 @@ for cipher_file in cipher_files: + chmsg = "Register digest %s" % mdname + chlognew = "%s\n %s" % (chlognew, chmsg) + fw.write (" grub_md_register (&%s);\n" % mdname) ++ for pkname in pknames: ++ chmsg = "Register pk %s" % mdname ++ chlognew = "%s\n %s" % (chlognew, chmsg) ++ fw.write (" grub_crypto_pk_%s = &%s;\n" ++ % (pkname.replace ("_gcry_pubkey_spec_", ""), pkname)) + fw.write ("}") + chmsg = "(GRUB_MOD_FINI(%s)): New function\n" % modname + chlognew = "%s\n %s" % (chlognew, chmsg) +@@ -318,13 +434,22 @@ for cipher_file in cipher_files: + chmsg = "Unregister MD %s" % mdname + chlognew = "%s\n %s" % (chlognew, chmsg) + fw.write (" grub_md_unregister (&%s);\n" % mdname) ++ for pkname in pknames: ++ chmsg = "Unregister pk %s" % mdname ++ chlognew = "%s\n %s" % (chlognew, chmsg) ++ fw.write (" grub_crypto_pk_%s = 0;\n" ++ % (pkname.replace ("_gcry_pubkey_spec_", ""))) + fw.write ("}\n") + conf.write ("module = {\n") + conf.write (" name = %s;\n" % modname) + for src in modfiles.split(): + conf.write (" common = %s;\n" % src) +- confutil.write (" common = grub-core/%s;\n" % src) +- if modname == "gcry_rijndael" or modname == "gcry_md4" or modname == "gcry_md5" or modname == "gcry_rmd160" or modname == "gcry_sha1" or modname == "gcry_sha256" or modname == "gcry_sha512" or modname == "gcry_tiger": ++ if len (ciphernames) > 0 or len (mdnames) > 0: ++ confutil.write (" common = grub-core/%s;\n" % src) ++ if modname == "gcry_ecc": ++ conf.write (" common = lib/libgcrypt-grub/mpi/ec.c;\n") ++ conf.write (" cflags = '$(CFLAGS_GCRY) -Wno-redundant-decls -Wno-sign-compare';\n") ++ elif modname == "gcry_rijndael" or modname == "gcry_md4" or modname == "gcry_md5" or modname == "gcry_rmd160" or modname == "gcry_sha1" or modname == "gcry_sha256" or modname == "gcry_sha512" or modname == "gcry_tiger": + # Alignment checked by hand + conf.write (" cflags = '$(CFLAGS_GCRY) -Wno-cast-align -Wno-strict-aliasing';\n"); + else: +@@ -346,6 +471,62 @@ for cipher_file in cipher_files: + print ("WARNING: unknown file %s" % cipher_file) + + cryptolist.close () ++ ++for src in sorted (os.listdir (os.path.join (indir, "src"))): ++ if src == "versioninfo.rc.in": ++ continue ++ outfile = os.path.join (basedir, "src", src) ++ infile = os.path.join (indir, "src", src) ++ if os.path.isdir (infile): ++ continue ++ fw = codecs.open (outfile, "w", "utf-8") ++ if src == "gcrypt-module.h": ++ fw.close () ++ continue ++ if src == "visibility.h": ++ fw.write ("# include ") ++ fw.close () ++ continue ++ f = codecs.open (infile, "r", "utf-8") ++ fw.write (f.read ()) ++ f.close () ++ fw.close () ++ ++for src in sorted (os.listdir (os.path.join (indir, "mpi"))): ++ infile = os.path.join (indir, "mpi", src) ++ outfile = os.path.join (basedir, "mpi", src) ++ if os.path.isdir (infile): ++ continue ++ f = codecs.open (infile, "r", "utf-8") ++ fw = codecs.open (outfile, "w", "utf-8") ++ fw.write ("/* This file was automatically imported with \n") ++ fw.write (" import_gcry.py. Please don't modify it */\n") ++ hold = False ++ skip = False ++ for line in f: ++ if skip: ++ if line[0] == "}": ++ skip = False ++ continue ++ if hold: ++ hold = False ++ # We're optimising for size and exclude anything needing good ++ # randomness. ++ if not re.match ("(_gcry_mpi_get_hw_config|gcry_mpi_randomize)", line) is None: ++ skip = True ++ continue ++ else: ++ fw.write (holdline) ++ m = re.match ("(const char( |)\*|void) *$", line) ++ if not m is None: ++ hold = True ++ holdline = line ++ continue ++ m = re.match ("#include \"mod-source-info\.h\"", line) ++ if not m is None: ++ continue ++ fw.write (line) ++ + chlog = "%s * crypto.lst: New file.\n" % chlog + + outfile = os.path.join (cipher_dir_out, "types.h") +@@ -382,21 +563,21 @@ conf.close (); + + initfile = codecs.open (os.path.join (cipher_dir_out, "init.c"), "w", "utf-8") + initfile.write ("#include \n") +-for module in modules: ++for module in modules_sym_md: + initfile.write ("extern void grub_%s_init (void);\n" % module) + initfile.write ("extern void grub_%s_fini (void);\n" % module) + initfile.write ("\n") + initfile.write ("void\n") + initfile.write ("grub_gcry_init_all (void)\n") + initfile.write ("{\n") +-for module in modules: ++for module in modules_sym_md: + initfile.write (" grub_%s_init ();\n" % module) + initfile.write ("}\n") + initfile.write ("\n") + initfile.write ("void\n") + initfile.write ("grub_gcry_fini_all (void)\n") + initfile.write ("{\n") +-for module in modules: ++for module in modules_sym_md: + initfile.write (" grub_%s_fini ();\n" % module) + initfile.write ("}\n") + initfile.close () +diff --git a/util/import_gcrypth.sed b/util/import_gcrypth.sed +new file mode 100644 +index 0000000..1cf31bd +--- /dev/null ++++ b/util/import_gcrypth.sed +@@ -0,0 +1,7 @@ ++/^#@INSERT_SYS_SELECT_H@/ d ++/^@FALLBACK_SOCKLEN_T@/ d ++/^#include / d ++/^#include / d ++/^#include / s,#include ,#include , ++s,_gcry_mpi_invm,gcry_mpi_invm,g ++p +\ No newline at end of file +-- +1.8.1.4 + diff --git a/0095-Clean-up-dangling-references-to-grub-setup.patch b/0095-Clean-up-dangling-references-to-grub-setup.patch new file mode 100644 index 0000000..631ecfd --- /dev/null +++ b/0095-Clean-up-dangling-references-to-grub-setup.patch @@ -0,0 +1,224 @@ +From d803dd359dd431cad08e95952f90c3f4f5acc9b7 Mon Sep 17 00:00:00 2001 +From: Colin Watson +Date: Sat, 12 Jan 2013 13:30:37 +0000 +Subject: [PATCH 095/364] Clean up dangling references to grub-setup. Fixes + Ubuntu bug #1082045. + +* docs/grub.texi (Images): Refer generally to grub-install rather +than directly to grub-setup. +(Installing GRUB using grub-install): Remove direct reference to +grub-setup. +(Device map) Likewise. +(Invoking grub-install): Likewise. +* docs/man/grub-install.h2m (SEE ALSO): Likewise. +* docs/man/grub-mkimage.h2m (SEE ALSO): Likewise. +* util/grub-install.in (usage): Likewise. + +* util/bash-completion.d/grub-completion.bash.in (_grub_setup): +Apply to grub-bios-setup and grub-sparc64-setup rather than to +grub-setup. +* configure.ac: Remove grub_setup output variable. + +* docs/man/grub-bios-setup.h2m (NAME): Change name from grub-setup +to grub-bios-setup. +* docs/man/grub-sparc64-setup.h2m (NAME): Change name from +grub-setup to grub-sparc64-setup. +--- + ChangeLog | 25 +++++++++++++++++++++++++ + configure.ac | 1 - + docs/grub.texi | 24 ++++++++++++------------ + docs/man/grub-bios-setup.h2m | 2 +- + docs/man/grub-install.h2m | 1 - + docs/man/grub-mkimage.h2m | 1 - + docs/man/grub-sparc64-setup.h2m | 2 +- + util/bash-completion.d/grub-completion.bash.in | 14 ++++++++++---- + util/grub-install.in | 4 ++-- + 9 files changed, 51 insertions(+), 23 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 22b18b1..61bf8e7 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,28 @@ ++2013-01-12 Colin Watson ++ ++ Clean up dangling references to grub-setup. ++ Fixes Ubuntu bug #1082045. ++ ++ * docs/grub.texi (Images): Refer generally to grub-install rather ++ than directly to grub-setup. ++ (Installing GRUB using grub-install): Remove direct reference to ++ grub-setup. ++ (Device map) Likewise. ++ (Invoking grub-install): Likewise. ++ * docs/man/grub-install.h2m (SEE ALSO): Likewise. ++ * docs/man/grub-mkimage.h2m (SEE ALSO): Likewise. ++ * util/grub-install.in (usage): Likewise. ++ ++ * util/bash-completion.d/grub-completion.bash.in (_grub_setup): ++ Apply to grub-bios-setup and grub-sparc64-setup rather than to ++ grub-setup. ++ * configure.ac: Remove grub_setup output variable. ++ ++ * docs/man/grub-bios-setup.h2m (NAME): Change name from grub-setup ++ to grub-bios-setup. ++ * docs/man/grub-sparc64-setup.h2m (NAME): Change name from ++ grub-setup to grub-sparc64-setup. ++ + 2013-01-11 Vladimir Serbinenko + + Import gcrypt public-key cryptography and implement signature checking. +diff --git a/configure.ac b/configure.ac +index dde954e..92b550a 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -64,7 +64,6 @@ grub_TRANSFORM([grub-probe]) + grub_TRANSFORM([grub-reboot]) + grub_TRANSFORM([grub-script-check]) + grub_TRANSFORM([grub-set-default]) +-grub_TRANSFORM([grub-setup]) + grub_TRANSFORM([grub-sparc64-setup]) + + # Optimization flag. Allow user to override. +diff --git a/docs/grub.texi b/docs/grub.texi +index a92bd96..e75bae9 100644 +--- a/docs/grub.texi ++++ b/docs/grub.texi +@@ -622,11 +622,11 @@ This install doesn't conflict with standard install as long as they are in + separate directories. + + Note that @command{grub-install} is actually just a shell script and the +-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. ++real task is done by other tools such as @command{grub-mkimage}. 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 + @section Making a GRUB bootable CD-ROM +@@ -688,8 +688,8 @@ storage devices. + @section The map between BIOS drives and OS devices + + If the device map file exists, the GRUB utilities (@command{grub-probe}, +-@command{grub-setup}, etc.) read it to map BIOS drives to OS devices. This +-file consists of lines like this: ++etc.) read it to map BIOS drives to OS devices. This file consists of lines ++like this: + + @example + (@var{device}) @var{file} +@@ -2283,8 +2283,8 @@ bytes. + The sole function of @file{boot.img} is to read the first sector of the core + image from a local disk and jump to it. Because of the size restriction, + @file{boot.img} cannot understand any file system structure, so +-@command{grub-setup} hardcodes the location of the first sector of the core +-image into @file{boot.img} when installing GRUB. ++@command{grub-install} hardcodes the location of the first sector of the ++core image into @file{boot.img} when installing GRUB. + + @item diskboot.img + This image is used as the first sector of the core image when booting from a +@@ -4689,9 +4689,9 @@ GRUB. + @node Invoking grub-install + @chapter Invoking grub-install + +-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: ++The program @command{grub-install} generates a GRUB core image using ++@command{grub-mkimage} and installs it on your system. You must specify the ++device name on which you want to install GRUB, like this: + + @example + grub-install @var{install_device} +diff --git a/docs/man/grub-bios-setup.h2m b/docs/man/grub-bios-setup.h2m +index eebe3ef..ac6ede3 100644 +--- a/docs/man/grub-bios-setup.h2m ++++ b/docs/man/grub-bios-setup.h2m +@@ -1,5 +1,5 @@ + [NAME] +-grub-setup \- set up a device to boot using GRUB ++grub-bios-setup \- set up a device to boot using GRUB + [SEE ALSO] + .BR grub-install (8), + .BR grub-mkimage (1), +diff --git a/docs/man/grub-install.h2m b/docs/man/grub-install.h2m +index 2de371a..8cbbc87 100644 +--- a/docs/man/grub-install.h2m ++++ b/docs/man/grub-install.h2m +@@ -3,5 +3,4 @@ grub-install \- install GRUB to a device + [SEE ALSO] + .BR grub-mkconfig (8), + .BR grub-mkimage (1), +-.BR grub-setup (8), + .BR grub-mkrescue (1) +diff --git a/docs/man/grub-mkimage.h2m b/docs/man/grub-mkimage.h2m +index ca08b0c..f0fbc2b 100644 +--- a/docs/man/grub-mkimage.h2m ++++ b/docs/man/grub-mkimage.h2m +@@ -2,6 +2,5 @@ + grub-mkimage \- make a bootable image of GRUB + [SEE ALSO] + .BR grub-install (8), +-.BR grub-setup (8), + .BR grub-mkrescue (1), + .BR grub-mknetdir (8) +diff --git a/docs/man/grub-sparc64-setup.h2m b/docs/man/grub-sparc64-setup.h2m +index eebe3ef..18f803a 100644 +--- a/docs/man/grub-sparc64-setup.h2m ++++ b/docs/man/grub-sparc64-setup.h2m +@@ -1,5 +1,5 @@ + [NAME] +-grub-setup \- set up a device to boot using GRUB ++grub-sparc64-setup \- set up a device to boot using GRUB + [SEE ALSO] + .BR grub-install (8), + .BR grub-mkimage (1), +diff --git a/util/bash-completion.d/grub-completion.bash.in b/util/bash-completion.d/grub-completion.bash.in +index 5f4b249..44bf135 100644 +--- a/util/bash-completion.d/grub-completion.bash.in ++++ b/util/bash-completion.d/grub-completion.bash.in +@@ -252,10 +252,16 @@ _grub_setup () { + _filedir + fi + } +-__grub_setup_program="@grub_setup@" +-have ${__grub_setup_program} && \ +- complete -F _grub_setup -o filenames ${__grub_setup_program} +-unset __grub_setup_program ++ ++__grub_bios_setup_program="@grub_bios_setup@" ++have ${__grub_bios_setup_program} && \ ++ complete -F _grub_setup -o filenames ${__grub_bios_setup_program} ++unset __grub_bios_setup_program ++ ++__grub_sparc64_setup_program="@grub_sparc64_setup@" ++have ${__grub_sparc64_setup_program} && \ ++ complete -F _grub_setup -o filenames ${__grub_sparc64_setup_program} ++unset __grub_sparc64_setup_program + + + # +diff --git a/util/grub-install.in b/util/grub-install.in +index 218bbd9..aac27c7 100644 +--- a/util/grub-install.in ++++ b/util/grub-install.in +@@ -114,8 +114,8 @@ echo + gettext "INSTALL_DEVICE must be system device filename.";echo + echo + +-gettext_printf "%s copies GRUB images into %s, and uses grub-setup +-to install grub into the boot sector.\n" "$self" "$grubdir";echo ++gettext_printf "%s copies GRUB images into %s. On some platforms, it ++may also install GRUB into the boot sector.\n" "$self" "$grubdir";echo + echo + gettext "Report bugs to ."; echo + } +-- +1.8.1.4 + diff --git a/0096-autogen.sh-Do-not-try-to-delete-nonexistant-files.patch b/0096-autogen.sh-Do-not-try-to-delete-nonexistant-files.patch new file mode 100644 index 0000000..a3f830e --- /dev/null +++ b/0096-autogen.sh-Do-not-try-to-delete-nonexistant-files.patch @@ -0,0 +1,76 @@ +From dc00947d8ca3b793b23cf0c3c3c3af24ae57e043 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sat, 12 Jan 2013 16:14:09 +0100 +Subject: [PATCH 096/364] * autogen.sh: Do not try to delete nonexistant + files. * util/import_gcrypth.sed: Add some missing header removals. + +--- + ChangeLog | 5 +++++ + autogen.sh | 12 +++++++++--- + util/import_gcrypth.sed | 11 ++++++++--- + 3 files changed, 22 insertions(+), 6 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 61bf8e7..d83d10a 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,8 @@ ++2013-01-11 Vladimir Serbinenko ++ ++ * autogen.sh: Do not try to delete nonexistant files. ++ * util/import_gcrypth.sed: Add some missing header removals. ++ + 2013-01-12 Colin Watson + + Clean up dangling references to grub-setup. +diff --git a/autogen.sh b/autogen.sh +index 5524083..7a4b5c8 100755 +--- a/autogen.sh ++++ b/autogen.sh +@@ -14,13 +14,19 @@ python util/import_unicode.py unicode/UnicodeData.txt unicode/BidiMirroring.txt + echo "Importing libgcrypt..." + python util/import_gcry.py grub-core/lib/libgcrypt/ grub-core + sed -n -f util/import_gcrypth.sed < grub-core/lib/libgcrypt/src/gcrypt.h.in > include/grub/gcrypt/gcrypt.h +-rm include/grub/gcrypt/g10lib.h +-rm -rf grub-core/lib/libgcrypt-grub/mpi/generic ++if [ -f include/grub/gcrypt/g10lib.h ]; then ++ rm include/grub/gcrypt/g10lib.h ++fi ++if [ -d grub-core/lib/libgcrypt-grub/mpi/generic ]; then ++ rm -rf grub-core/lib/libgcrypt-grub/mpi/generic ++fi + ln -s ../../../grub-core/lib/libgcrypt-grub/src/g10lib.h include/grub/gcrypt/g10lib.h + cp -R grub-core/lib/libgcrypt/mpi/generic grub-core/lib/libgcrypt-grub/mpi/generic + + for x in mpi-asm-defs.h mpih-add1.c mpih-sub1.c mpih-mul1.c mpih-mul2.c mpih-mul3.c mpih-lshift.c mpih-rshift.c; do +- rm grub-core/lib/libgcrypt-grub/mpi/"$x" ++ if [ -f grub-core/lib/libgcrypt-grub/mpi/"$x" ]; then ++ rm grub-core/lib/libgcrypt-grub/mpi/"$x" ++ fi + ln -s generic/"$x" grub-core/lib/libgcrypt-grub/mpi/"$x" + done + +diff --git a/util/import_gcrypth.sed b/util/import_gcrypth.sed +index 1cf31bd..dead8e6 100644 +--- a/util/import_gcrypth.sed ++++ b/util/import_gcrypth.sed +@@ -1,7 +1,12 @@ + /^#@INSERT_SYS_SELECT_H@/ d + /^@FALLBACK_SOCKLEN_T@/ d +-/^#include / d +-/^#include / d +-/^#include / s,#include ,#include , ++/^# *include / d ++/^# *include / d ++/^# *include / d ++/^# *include / d ++/^# *include / d ++/^# *include / d ++/^# *include / d ++/^# *include / s,#include ,#include , + s,_gcry_mpi_invm,gcry_mpi_invm,g + p +\ No newline at end of file +-- +1.8.1.4 + diff --git a/0097-Remove-autogenerated-files-from-VCS.patch b/0097-Remove-autogenerated-files-from-VCS.patch new file mode 100644 index 0000000..9537908 --- /dev/null +++ b/0097-Remove-autogenerated-files-from-VCS.patch @@ -0,0 +1,1353 @@ +From 1a2fd466e880636d53969b1c614d223ed94cf35b Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sat, 12 Jan 2013 16:17:31 +0100 +Subject: [PATCH 097/364] Remove autogenerated files from VCS + +--- + .bzrignore | 2 + + include/grub/gcrypt/gcrypt.h | 1333 ------------------------------------------ + 2 files changed, 2 insertions(+), 1333 deletions(-) + delete mode 100644 include/grub/gcrypt/gcrypt.h + +diff --git a/include/grub/gcrypt/gcrypt.h b/include/grub/gcrypt/gcrypt.h +deleted file mode 100644 +index fc83571..0000000 +--- a/include/grub/gcrypt/gcrypt.h ++++ /dev/null +@@ -1,1333 +0,0 @@ +-/* gcrypt.h - GNU Cryptographic Library Interface -*- c -*- +- Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006 +- 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. +- +- This file is part of Libgcrypt. +- +- Libgcrypt is free software; you can redistribute it and/or modify +- it under the terms of the GNU Lesser General Public License as +- published by the Free Software Foundation; either version 2.1 of +- the License, or (at your option) any later version. +- +- Libgcrypt 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 Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with this program; if not, see . +- +- File: @configure_input@ */ +- +-#ifndef _GCRYPT_H +-#define _GCRYPT_H +- +-#include +- +-#include +- +-#include +- +-#if defined _WIN32 || defined __WIN32__ +-# include +-# include +-# include +-# ifndef __GNUC__ +- typedef long ssize_t; +- typedef int pid_t; +-# endif /*!__GNUC__*/ +-#else +-# include +-# include +-#endif /*!_WIN32*/ +- +- +-/* This is required for error code compatibility. */ +-#define _GCRY_ERR_SOURCE_DEFAULT GPG_ERR_SOURCE_GCRYPT +- +-#ifdef __cplusplus +-extern "C" { +-#if 0 /* (Keep Emacsens' auto-indent happy.) */ +-} +-#endif +-#endif +- +-/* The version of this header should match the one of the library. It +- should not be used by a program because gcry_check_version() should +- return the same version. The purpose of this macro is to let +- autoconf (using the AM_PATH_GCRYPT macro) check that this header +- matches the installed library. */ +-#define GCRYPT_VERSION "@VERSION@" +- +-/* Internal: We can't use the convenience macros for the multi +- precision integer functions when building this library. */ +-#ifdef _GCRYPT_IN_LIBGCRYPT +-#ifndef GCRYPT_NO_MPI_MACROS +-#define GCRYPT_NO_MPI_MACROS 1 +-#endif +-#endif +- +-/* We want to use gcc attributes when possible. Warning: Don't use +- these macros in your programs: As indicated by the leading +- underscore they are subject to change without notice. */ +-#ifdef __GNUC__ +- +-#define _GCRY_GCC_VERSION (__GNUC__ * 10000 \ +- + __GNUC_MINOR__ * 100 \ +- + __GNUC_PATCHLEVEL__) +- +-#if _GCRY_GCC_VERSION >= 30100 +-#define _GCRY_GCC_ATTR_DEPRECATED __attribute__ ((__deprecated__)) +-#endif +- +-#if _GCRY_GCC_VERSION >= 29600 +-#define _GCRY_GCC_ATTR_PURE __attribute__ ((__pure__)) +-#endif +- +-#if _GCRY_GCC_VERSION >= 30200 +-#define _GCRY_GCC_ATTR_MALLOC __attribute__ ((__malloc__)) +-#endif +- +-#endif /*__GNUC__*/ +- +-#ifndef _GCRY_GCC_ATTR_DEPRECATED +-#define _GCRY_GCC_ATTR_DEPRECATED +-#endif +-#ifndef _GCRY_GCC_ATTR_PURE +-#define _GCRY_GCC_ATTR_PURE +-#endif +-#ifndef _GCRY_GCC_ATTR_MALLOC +-#define _GCRY_GCC_ATTR_MALLOC +-#endif +- +-/* Make up an attribute to mark functions and types as deprecated but +- allow internal use by Libgcrypt. */ +-#ifdef _GCRYPT_IN_LIBGCRYPT +-#define _GCRY_ATTR_INTERNAL +-#else +-#define _GCRY_ATTR_INTERNAL _GCRY_GCC_ATTR_DEPRECATED +-#endif +- +-/* Wrappers for the libgpg-error library. */ +- +-typedef gpg_error_t gcry_error_t; +-typedef gpg_err_code_t gcry_err_code_t; +-typedef gpg_err_source_t gcry_err_source_t; +- +-static GPG_ERR_INLINE gcry_error_t +-gcry_err_make (gcry_err_source_t source, gcry_err_code_t code) +-{ +- return gpg_err_make (source, code); +-} +- +-/* The user can define GPG_ERR_SOURCE_DEFAULT before including this +- file to specify a default source for gpg_error. */ +-#ifndef GCRY_ERR_SOURCE_DEFAULT +-#define GCRY_ERR_SOURCE_DEFAULT GPG_ERR_SOURCE_USER_1 +-#endif +- +-static GPG_ERR_INLINE gcry_error_t +-gcry_error (gcry_err_code_t code) +-{ +- return gcry_err_make (GCRY_ERR_SOURCE_DEFAULT, code); +-} +- +-static GPG_ERR_INLINE gcry_err_code_t +-gcry_err_code (gcry_error_t err) +-{ +- return gpg_err_code (err); +-} +- +- +-static GPG_ERR_INLINE gcry_err_source_t +-gcry_err_source (gcry_error_t err) +-{ +- return gpg_err_source (err); +-} +- +-/* Return a pointer to a string containing a description of the error +- code in the error value ERR. */ +-const char *gcry_strerror (gcry_error_t err); +- +-/* Return a pointer to a string containing a description of the error +- source in the error value ERR. */ +-const char *gcry_strsource (gcry_error_t err); +- +-/* Retrieve the error code for the system error ERR. This returns +- GPG_ERR_UNKNOWN_ERRNO if the system error is not mapped (report +- this). */ +-gcry_err_code_t gcry_err_code_from_errno (int err); +- +-/* Retrieve the system error for the error code CODE. This returns 0 +- if CODE is not a system error code. */ +-int gcry_err_code_to_errno (gcry_err_code_t code); +- +-/* Return an error value with the error source SOURCE and the system +- error ERR. */ +-gcry_error_t gcry_err_make_from_errno (gcry_err_source_t source, int err); +- +-/* Return an error value with the system error ERR. */ +-gcry_err_code_t gcry_error_from_errno (int err); +- +- +-/* NOTE: Since Libgcrypt 1.6 the thread callbacks are not anymore +- used. However we keep it to allow for some source code +- compatibility if used in the standard way. */ +- +-/* Constants defining the thread model to use. Used with the OPTION +- field of the struct gcry_thread_cbs. */ +-#define GCRY_THREAD_OPTION_DEFAULT 0 +-#define GCRY_THREAD_OPTION_USER 1 +-#define GCRY_THREAD_OPTION_PTH 2 +-#define GCRY_THREAD_OPTION_PTHREAD 3 +- +-/* The version number encoded in the OPTION field of the struct +- gcry_thread_cbs. */ +-#define GCRY_THREAD_OPTION_VERSION 1 +- +-/* Wrapper for struct ath_ops. */ +-struct gcry_thread_cbs +-{ +- /* The OPTION field encodes the thread model and the version number +- of this structure. +- Bits 7 - 0 are used for the thread model +- Bits 15 - 8 are used for the version number. */ +- unsigned int option; +-} _GCRY_ATTR_INTERNAL; +- +-#define GCRY_THREAD_OPTION_PTH_IMPL \ +- static struct gcry_thread_cbs gcry_threads_pth = { \ +- (GCRY_THREAD_OPTION_PTH | (GCRY_THREAD_OPTION_VERSION << 8))} +- +-#define GCRY_THREAD_OPTION_PTHREAD_IMPL \ +- static struct gcry_thread_cbs gcry_threads_pthread = { \ +- (GCRY_THREAD_OPTION_PTHREAD | (GCRY_THREAD_OPTION_VERSION << 8))} +- +- +- +-/* The data object used to hold a multi precision integer. */ +-struct gcry_mpi; +-typedef struct gcry_mpi *gcry_mpi_t; +- +-#ifndef GCRYPT_NO_DEPRECATED +-typedef struct gcry_mpi *GCRY_MPI _GCRY_GCC_ATTR_DEPRECATED; +-typedef struct gcry_mpi *GcryMPI _GCRY_GCC_ATTR_DEPRECATED; +-#endif +- +- +- +-/* Check that the library fulfills the version requirement. */ +-const char *gcry_check_version (const char *req_version); +- +-/* Codes for function dispatchers. */ +- +-/* Codes used with the gcry_control function. */ +-enum gcry_ctl_cmds +- { +- GCRYCTL_SET_KEY = 1, +- GCRYCTL_SET_IV = 2, +- GCRYCTL_CFB_SYNC = 3, +- GCRYCTL_RESET = 4, /* e.g. for MDs */ +- GCRYCTL_FINALIZE = 5, +- GCRYCTL_GET_KEYLEN = 6, +- GCRYCTL_GET_BLKLEN = 7, +- GCRYCTL_TEST_ALGO = 8, +- GCRYCTL_IS_SECURE = 9, +- GCRYCTL_GET_ASNOID = 10, +- GCRYCTL_ENABLE_ALGO = 11, +- GCRYCTL_DISABLE_ALGO = 12, +- GCRYCTL_DUMP_RANDOM_STATS = 13, +- GCRYCTL_DUMP_SECMEM_STATS = 14, +- GCRYCTL_GET_ALGO_NPKEY = 15, +- GCRYCTL_GET_ALGO_NSKEY = 16, +- GCRYCTL_GET_ALGO_NSIGN = 17, +- GCRYCTL_GET_ALGO_NENCR = 18, +- GCRYCTL_SET_VERBOSITY = 19, +- GCRYCTL_SET_DEBUG_FLAGS = 20, +- GCRYCTL_CLEAR_DEBUG_FLAGS = 21, +- GCRYCTL_USE_SECURE_RNDPOOL= 22, +- GCRYCTL_DUMP_MEMORY_STATS = 23, +- GCRYCTL_INIT_SECMEM = 24, +- GCRYCTL_TERM_SECMEM = 25, +- GCRYCTL_DISABLE_SECMEM_WARN = 27, +- GCRYCTL_SUSPEND_SECMEM_WARN = 28, +- GCRYCTL_RESUME_SECMEM_WARN = 29, +- GCRYCTL_DROP_PRIVS = 30, +- GCRYCTL_ENABLE_M_GUARD = 31, +- GCRYCTL_START_DUMP = 32, +- GCRYCTL_STOP_DUMP = 33, +- GCRYCTL_GET_ALGO_USAGE = 34, +- GCRYCTL_IS_ALGO_ENABLED = 35, +- GCRYCTL_DISABLE_INTERNAL_LOCKING = 36, +- GCRYCTL_DISABLE_SECMEM = 37, +- GCRYCTL_INITIALIZATION_FINISHED = 38, +- GCRYCTL_INITIALIZATION_FINISHED_P = 39, +- GCRYCTL_ANY_INITIALIZATION_P = 40, +- GCRYCTL_SET_CBC_CTS = 41, +- GCRYCTL_SET_CBC_MAC = 42, +- GCRYCTL_SET_CTR = 43, +- GCRYCTL_ENABLE_QUICK_RANDOM = 44, +- GCRYCTL_SET_RANDOM_SEED_FILE = 45, +- GCRYCTL_UPDATE_RANDOM_SEED_FILE = 46, +- GCRYCTL_SET_THREAD_CBS = 47, +- GCRYCTL_FAST_POLL = 48, +- GCRYCTL_SET_RANDOM_DAEMON_SOCKET = 49, +- GCRYCTL_USE_RANDOM_DAEMON = 50, +- GCRYCTL_FAKED_RANDOM_P = 51, +- GCRYCTL_SET_RNDEGD_SOCKET = 52, +- GCRYCTL_PRINT_CONFIG = 53, +- GCRYCTL_OPERATIONAL_P = 54, +- GCRYCTL_FIPS_MODE_P = 55, +- GCRYCTL_FORCE_FIPS_MODE = 56, +- GCRYCTL_SELFTEST = 57, +- /* Note: 58 .. 62 are used internally. */ +- GCRYCTL_DISABLE_HWF = 63 +- }; +- +-/* Perform various operations defined by CMD. */ +-gcry_error_t gcry_control (enum gcry_ctl_cmds CMD, ...); +- +- +-/* S-expression management. */ +- +-/* The object to represent an S-expression as used with the public key +- functions. */ +-struct gcry_sexp; +-typedef struct gcry_sexp *gcry_sexp_t; +- +-#ifndef GCRYPT_NO_DEPRECATED +-typedef struct gcry_sexp *GCRY_SEXP _GCRY_GCC_ATTR_DEPRECATED; +-typedef struct gcry_sexp *GcrySexp _GCRY_GCC_ATTR_DEPRECATED; +-#endif +- +-/* The possible values for the S-expression format. */ +-enum gcry_sexp_format +- { +- GCRYSEXP_FMT_DEFAULT = 0, +- GCRYSEXP_FMT_CANON = 1, +- GCRYSEXP_FMT_BASE64 = 2, +- GCRYSEXP_FMT_ADVANCED = 3 +- }; +- +-/* Create an new S-expression object from BUFFER of size LENGTH and +- return it in RETSEXP. With AUTODETECT set to 0 the data in BUFFER +- is expected to be in canonized format. */ +-gcry_error_t gcry_sexp_new (gcry_sexp_t *retsexp, +- const void *buffer, size_t length, +- int autodetect); +- +- /* Same as gcry_sexp_new but allows to pass a FREEFNC which has the +- effect to transfer ownership of BUFFER to the created object. */ +-gcry_error_t gcry_sexp_create (gcry_sexp_t *retsexp, +- void *buffer, size_t length, +- int autodetect, void (*freefnc) (void *)); +- +-/* Scan BUFFER and return a new S-expression object in RETSEXP. This +- function expects a printf like string in BUFFER. */ +-gcry_error_t gcry_sexp_sscan (gcry_sexp_t *retsexp, size_t *erroff, +- const char *buffer, size_t length); +- +-/* Same as gcry_sexp_sscan but expects a string in FORMAT and can thus +- only be used for certain encodings. */ +-gcry_error_t gcry_sexp_build (gcry_sexp_t *retsexp, size_t *erroff, +- const char *format, ...); +- +-/* Like gcry_sexp_build, but uses an array instead of variable +- function arguments. */ +-gcry_error_t gcry_sexp_build_array (gcry_sexp_t *retsexp, size_t *erroff, +- const char *format, void **arg_list); +- +-/* Release the S-expression object SEXP */ +-void gcry_sexp_release (gcry_sexp_t sexp); +- +-/* Calculate the length of an canonized S-expresion in BUFFER and +- check for a valid encoding. */ +-size_t gcry_sexp_canon_len (const unsigned char *buffer, size_t length, +- size_t *erroff, gcry_error_t *errcode); +- +-/* Copies the S-expression object SEXP into BUFFER using the format +- specified in MODE. */ +-size_t gcry_sexp_sprint (gcry_sexp_t sexp, int mode, void *buffer, +- size_t maxlength); +- +-/* Dumps the S-expression object A in a format suitable for debugging +- to Libgcrypt's logging stream. */ +-void gcry_sexp_dump (const gcry_sexp_t a); +- +-gcry_sexp_t gcry_sexp_cons (const gcry_sexp_t a, const gcry_sexp_t b); +-gcry_sexp_t gcry_sexp_alist (const gcry_sexp_t *array); +-gcry_sexp_t gcry_sexp_vlist (const gcry_sexp_t a, ...); +-gcry_sexp_t gcry_sexp_append (const gcry_sexp_t a, const gcry_sexp_t n); +-gcry_sexp_t gcry_sexp_prepend (const gcry_sexp_t a, const gcry_sexp_t n); +- +-/* Scan the S-expression for a sublist with a type (the car of the +- list) matching the string TOKEN. If TOKLEN is not 0, the token is +- assumed to be raw memory of this length. The function returns a +- newly allocated S-expression consisting of the found sublist or +- `NULL' when not found. */ +-gcry_sexp_t gcry_sexp_find_token (gcry_sexp_t list, +- const char *tok, size_t toklen); +-/* Return the length of the LIST. For a valid S-expression this +- should be at least 1. */ +-int gcry_sexp_length (const gcry_sexp_t list); +- +-/* Create and return a new S-expression from the element with index +- NUMBER in LIST. Note that the first element has the index 0. If +- there is no such element, `NULL' is returned. */ +-gcry_sexp_t gcry_sexp_nth (const gcry_sexp_t list, int number); +- +-/* Create and return a new S-expression from the first element in +- LIST; this called the "type" and should always exist and be a +- string. `NULL' is returned in case of a problem. */ +-gcry_sexp_t gcry_sexp_car (const gcry_sexp_t list); +- +-/* Create and return a new list form all elements except for the first +- one. Note, that this function may return an invalid S-expression +- because it is not guaranteed, that the type exists and is a string. +- However, for parsing a complex S-expression it might be useful for +- intermediate lists. Returns `NULL' on error. */ +-gcry_sexp_t gcry_sexp_cdr (const gcry_sexp_t list); +- +-gcry_sexp_t gcry_sexp_cadr (const gcry_sexp_t list); +- +- +-/* This function is used to get data from a LIST. A pointer to the +- actual data with index NUMBER is returned and the length of this +- data will be stored to DATALEN. If there is no data at the given +- index or the index represents another list, `NULL' is returned. +- *Note:* The returned pointer is valid as long as LIST is not +- modified or released. */ +-const char *gcry_sexp_nth_data (const gcry_sexp_t list, int number, +- size_t *datalen); +- +-/* This function is used to get and convert data from a LIST. The +- data is assumed to be a Nul terminated string. The caller must +- release the returned value using `gcry_free'. If there is no data +- at the given index, the index represents a list or the value can't +- be converted to a string, `NULL' is returned. */ +-char *gcry_sexp_nth_string (gcry_sexp_t list, int number); +- +-/* This function is used to get and convert data from a LIST. This +- data is assumed to be an MPI stored in the format described by +- MPIFMT and returned as a standard Libgcrypt MPI. The caller must +- release this returned value using `gcry_mpi_release'. If there is +- no data at the given index, the index represents a list or the +- value can't be converted to an MPI, `NULL' is returned. */ +-gcry_mpi_t gcry_sexp_nth_mpi (gcry_sexp_t list, int number, int mpifmt); +- +- +- +-/******************************************* +- * * +- * Multi Precision Integer Functions * +- * * +- *******************************************/ +- +-/* Different formats of external big integer representation. */ +-enum gcry_mpi_format +- { +- GCRYMPI_FMT_NONE= 0, +- GCRYMPI_FMT_STD = 1, /* Twos complement stored without length. */ +- GCRYMPI_FMT_PGP = 2, /* As used by OpenPGP (unsigned only). */ +- GCRYMPI_FMT_SSH = 3, /* As used by SSH (like STD but with length). */ +- GCRYMPI_FMT_HEX = 4, /* Hex format. */ +- GCRYMPI_FMT_USG = 5 /* Like STD but unsigned. */ +- }; +- +-/* Flags used for creating big integers. */ +-enum gcry_mpi_flag +- { +- GCRYMPI_FLAG_SECURE = 1, /* Allocate the number in "secure" memory. */ +- GCRYMPI_FLAG_OPAQUE = 2 /* The number is not a real one but just +- a way to store some bytes. This is +- useful for encrypted big integers. */ +- }; +- +- +-/* Allocate a new big integer object, initialize it with 0 and +- initially allocate memory for a number of at least NBITS. */ +-gcry_mpi_t gcry_mpi_new (unsigned int nbits); +- +-/* Same as gcry_mpi_new() but allocate in "secure" memory. */ +-gcry_mpi_t gcry_mpi_snew (unsigned int nbits); +- +-/* Release the number A and free all associated resources. */ +-void gcry_mpi_release (gcry_mpi_t a); +- +-/* Create a new number with the same value as A. */ +-gcry_mpi_t gcry_mpi_copy (const gcry_mpi_t a); +- +-/* Store the big integer value U in W. */ +-gcry_mpi_t gcry_mpi_set (gcry_mpi_t w, const gcry_mpi_t u); +- +-/* Store the unsigned integer value U in W. */ +-gcry_mpi_t gcry_mpi_set_ui (gcry_mpi_t w, unsigned long u); +- +-/* Swap the values of A and B. */ +-void gcry_mpi_swap (gcry_mpi_t a, gcry_mpi_t b); +- +-/* Compare the big integer number U and V returning 0 for equality, a +- positive value for U > V and a negative for U < V. */ +-int gcry_mpi_cmp (const gcry_mpi_t u, const gcry_mpi_t v); +- +-/* Compare the big integer number U with the unsigned integer V +- returning 0 for equality, a positive value for U > V and a negative +- for U < V. */ +-int gcry_mpi_cmp_ui (const gcry_mpi_t u, unsigned long v); +- +-/* Convert the external representation of an integer stored in BUFFER +- with a length of BUFLEN into a newly create MPI returned in +- RET_MPI. If NSCANNED is not NULL, it will receive the number of +- bytes actually scanned after a successful operation. */ +-gcry_error_t gcry_mpi_scan (gcry_mpi_t *ret_mpi, enum gcry_mpi_format format, +- const void *buffer, size_t buflen, +- size_t *nscanned); +- +-/* Convert the big integer A into the external representation +- described by FORMAT and store it in the provided BUFFER which has +- been allocated by the user with a size of BUFLEN bytes. NWRITTEN +- receives the actual length of the external representation unless it +- has been passed as NULL. */ +-gcry_error_t gcry_mpi_print (enum gcry_mpi_format format, +- unsigned char *buffer, size_t buflen, +- size_t *nwritten, +- const gcry_mpi_t a); +- +-/* Convert the big integer A int the external representation described +- by FORMAT and store it in a newly allocated buffer which address +- will be put into BUFFER. NWRITTEN receives the actual lengths of the +- external representation. */ +-gcry_error_t gcry_mpi_aprint (enum gcry_mpi_format format, +- unsigned char **buffer, size_t *nwritten, +- const gcry_mpi_t a); +- +-/* Dump the value of A in a format suitable for debugging to +- Libgcrypt's logging stream. Note that one leading space but no +- trailing space or linefeed will be printed. It is okay to pass +- NULL for A. */ +-void gcry_mpi_dump (const gcry_mpi_t a); +- +- +-/* W = U + V. */ +-void gcry_mpi_add (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v); +- +-/* W = U + V. V is an unsigned integer. */ +-void gcry_mpi_add_ui (gcry_mpi_t w, gcry_mpi_t u, unsigned long v); +- +-/* W = U + V mod M. */ +-void gcry_mpi_addm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m); +- +-/* W = U - V. */ +-void gcry_mpi_sub (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v); +- +-/* W = U - V. V is an unsigned integer. */ +-void gcry_mpi_sub_ui (gcry_mpi_t w, gcry_mpi_t u, unsigned long v ); +- +-/* W = U - V mod M */ +-void gcry_mpi_subm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m); +- +-/* W = U * V. */ +-void gcry_mpi_mul (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v); +- +-/* W = U * V. V is an unsigned integer. */ +-void gcry_mpi_mul_ui (gcry_mpi_t w, gcry_mpi_t u, unsigned long v ); +- +-/* W = U * V mod M. */ +-void gcry_mpi_mulm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m); +- +-/* W = U * (2 ^ CNT). */ +-void gcry_mpi_mul_2exp (gcry_mpi_t w, gcry_mpi_t u, unsigned long cnt); +- +-/* Q = DIVIDEND / DIVISOR, R = DIVIDEND % DIVISOR, +- Q or R may be passed as NULL. ROUND should be negative or 0. */ +-void gcry_mpi_div (gcry_mpi_t q, gcry_mpi_t r, +- gcry_mpi_t dividend, gcry_mpi_t divisor, int round); +- +-/* R = DIVIDEND % DIVISOR */ +-void gcry_mpi_mod (gcry_mpi_t r, gcry_mpi_t dividend, gcry_mpi_t divisor); +- +-/* W = B ^ E mod M. */ +-void gcry_mpi_powm (gcry_mpi_t w, +- const gcry_mpi_t b, const gcry_mpi_t e, +- const gcry_mpi_t m); +- +-/* Set G to the greatest common divisor of A and B. +- Return true if the G is 1. */ +-int gcry_mpi_gcd (gcry_mpi_t g, gcry_mpi_t a, gcry_mpi_t b); +- +-/* Set X to the multiplicative inverse of A mod M. +- Return true if the value exists. */ +-int gcry_mpi_invm (gcry_mpi_t x, gcry_mpi_t a, gcry_mpi_t m); +- +- +-/* Return the number of bits required to represent A. */ +-unsigned int gcry_mpi_get_nbits (gcry_mpi_t a); +- +-/* Return true when bit number N (counting from 0) is set in A. */ +-int gcry_mpi_test_bit (gcry_mpi_t a, unsigned int n); +- +-/* Set bit number N in A. */ +-void gcry_mpi_set_bit (gcry_mpi_t a, unsigned int n); +- +-/* Clear bit number N in A. */ +-void gcry_mpi_clear_bit (gcry_mpi_t a, unsigned int n); +- +-/* Set bit number N in A and clear all bits greater than N. */ +-void gcry_mpi_set_highbit (gcry_mpi_t a, unsigned int n); +- +-/* Clear bit number N in A and all bits greater than N. */ +-void gcry_mpi_clear_highbit (gcry_mpi_t a, unsigned int n); +- +-/* Shift the value of A by N bits to the right and store the result in X. */ +-void gcry_mpi_rshift (gcry_mpi_t x, gcry_mpi_t a, unsigned int n); +- +-/* Shift the value of A by N bits to the left and store the result in X. */ +-void gcry_mpi_lshift (gcry_mpi_t x, gcry_mpi_t a, unsigned int n); +- +-/* Store NBITS of the value P points to in A and mark A as an opaque +- value. WARNING: Never use an opaque MPI for anything thing else then +- gcry_mpi_release, gcry_mpi_get_opaque. */ +-gcry_mpi_t gcry_mpi_set_opaque (gcry_mpi_t a, void *p, unsigned int nbits); +- +-/* Return a pointer to an opaque value stored in A and return its size +- in NBITS. Note that the returned pointer is still owned by A and +- that the function should never be used for an non-opaque MPI. */ +-void *gcry_mpi_get_opaque (gcry_mpi_t a, unsigned int *nbits); +- +-/* Set the FLAG for the big integer A. Currently only the flag +- GCRYMPI_FLAG_SECURE is allowed to convert A into an big intger +- stored in "secure" memory. */ +-void gcry_mpi_set_flag (gcry_mpi_t a, enum gcry_mpi_flag flag); +- +-/* Clear FLAG for the big integer A. Note that this function is +- currently useless as no flags are allowed. */ +-void gcry_mpi_clear_flag (gcry_mpi_t a, enum gcry_mpi_flag flag); +- +-/* Return true when the FLAG is set for A. */ +-int gcry_mpi_get_flag (gcry_mpi_t a, enum gcry_mpi_flag flag); +- +-/* Unless the GCRYPT_NO_MPI_MACROS is used, provide a couple of +- convenience macros for the big integer functions. */ +-#ifndef GCRYPT_NO_MPI_MACROS +-#define mpi_new(n) gcry_mpi_new( (n) ) +-#define mpi_secure_new( n ) gcry_mpi_snew( (n) ) +-#define mpi_release(a) \ +- do \ +- { \ +- gcry_mpi_release ((a)); \ +- (a) = NULL; \ +- } \ +- while (0) +- +-#define mpi_copy( a ) gcry_mpi_copy( (a) ) +-#define mpi_set( w, u) gcry_mpi_set( (w), (u) ) +-#define mpi_set_ui( w, u) gcry_mpi_set_ui( (w), (u) ) +-#define mpi_cmp( u, v ) gcry_mpi_cmp( (u), (v) ) +-#define mpi_cmp_ui( u, v ) gcry_mpi_cmp_ui( (u), (v) ) +- +-#define mpi_add_ui(w,u,v) gcry_mpi_add_ui((w),(u),(v)) +-#define mpi_add(w,u,v) gcry_mpi_add ((w),(u),(v)) +-#define mpi_addm(w,u,v,m) gcry_mpi_addm ((w),(u),(v),(m)) +-#define mpi_sub_ui(w,u,v) gcry_mpi_sub_ui ((w),(u),(v)) +-#define mpi_sub(w,u,v) gcry_mpi_sub ((w),(u),(v)) +-#define mpi_subm(w,u,v,m) gcry_mpi_subm ((w),(u),(v),(m)) +-#define mpi_mul_ui(w,u,v) gcry_mpi_mul_ui ((w),(u),(v)) +-#define mpi_mul_2exp(w,u,v) gcry_mpi_mul_2exp ((w),(u),(v)) +-#define mpi_mul(w,u,v) gcry_mpi_mul ((w),(u),(v)) +-#define mpi_mulm(w,u,v,m) gcry_mpi_mulm ((w),(u),(v),(m)) +-#define mpi_powm(w,b,e,m) gcry_mpi_powm ( (w), (b), (e), (m) ) +-#define mpi_tdiv(q,r,a,m) gcry_mpi_div ( (q), (r), (a), (m), 0) +-#define mpi_fdiv(q,r,a,m) gcry_mpi_div ( (q), (r), (a), (m), -1) +-#define mpi_mod(r,a,m) gcry_mpi_mod ((r), (a), (m)) +-#define mpi_gcd(g,a,b) gcry_mpi_gcd ( (g), (a), (b) ) +-#define mpi_invm(g,a,b) gcry_mpi_invm ( (g), (a), (b) ) +- +-#define mpi_get_nbits(a) gcry_mpi_get_nbits ((a)) +-#define mpi_test_bit(a,b) gcry_mpi_test_bit ((a),(b)) +-#define mpi_set_bit(a,b) gcry_mpi_set_bit ((a),(b)) +-#define mpi_set_highbit(a,b) gcry_mpi_set_highbit ((a),(b)) +-#define mpi_clear_bit(a,b) gcry_mpi_clear_bit ((a),(b)) +-#define mpi_clear_highbit(a,b) gcry_mpi_clear_highbit ((a),(b)) +-#define mpi_rshift(a,b,c) gcry_mpi_rshift ((a),(b),(c)) +-#define mpi_lshift(a,b,c) gcry_mpi_lshift ((a),(b),(c)) +- +-#define mpi_set_opaque(a,b,c) gcry_mpi_set_opaque( (a), (b), (c) ) +-#define mpi_get_opaque(a,b) gcry_mpi_get_opaque( (a), (b) ) +-#endif /* GCRYPT_NO_MPI_MACROS */ +- +- +- +-/************************************ +- * * +- * Symmetric Cipher Functions * +- * * +- ************************************/ +- +-/* The data object used to hold a handle to an encryption object. */ +-struct gcry_cipher_handle; +-typedef struct gcry_cipher_handle *gcry_cipher_hd_t; +- +-#ifndef GCRYPT_NO_DEPRECATED +-typedef struct gcry_cipher_handle *GCRY_CIPHER_HD _GCRY_GCC_ATTR_DEPRECATED; +-typedef struct gcry_cipher_handle *GcryCipherHd _GCRY_GCC_ATTR_DEPRECATED; +-#endif +- +-/* All symmetric encryption algorithms are identified by their IDs. +- More IDs may be registered at runtime. */ +-enum gcry_cipher_algos +- { +- GCRY_CIPHER_NONE = 0, +- GCRY_CIPHER_IDEA = 1, +- GCRY_CIPHER_3DES = 2, +- GCRY_CIPHER_CAST5 = 3, +- GCRY_CIPHER_BLOWFISH = 4, +- GCRY_CIPHER_SAFER_SK128 = 5, +- GCRY_CIPHER_DES_SK = 6, +- GCRY_CIPHER_AES = 7, +- GCRY_CIPHER_AES192 = 8, +- GCRY_CIPHER_AES256 = 9, +- GCRY_CIPHER_TWOFISH = 10, +- +- /* Other cipher numbers are above 300 for OpenPGP reasons. */ +- GCRY_CIPHER_ARCFOUR = 301, /* Fully compatible with RSA's RC4 (tm). */ +- GCRY_CIPHER_DES = 302, /* Yes, this is single key 56 bit DES. */ +- GCRY_CIPHER_TWOFISH128 = 303, +- GCRY_CIPHER_SERPENT128 = 304, +- GCRY_CIPHER_SERPENT192 = 305, +- GCRY_CIPHER_SERPENT256 = 306, +- GCRY_CIPHER_RFC2268_40 = 307, /* Ron's Cipher 2 (40 bit). */ +- GCRY_CIPHER_RFC2268_128 = 308, /* Ron's Cipher 2 (128 bit). */ +- GCRY_CIPHER_SEED = 309, /* 128 bit cipher described in RFC4269. */ +- GCRY_CIPHER_CAMELLIA128 = 310, +- GCRY_CIPHER_CAMELLIA192 = 311, +- GCRY_CIPHER_CAMELLIA256 = 312 +- }; +- +-/* The Rijndael algorithm is basically AES, so provide some macros. */ +-#define GCRY_CIPHER_AES128 GCRY_CIPHER_AES +-#define GCRY_CIPHER_RIJNDAEL GCRY_CIPHER_AES +-#define GCRY_CIPHER_RIJNDAEL128 GCRY_CIPHER_AES128 +-#define GCRY_CIPHER_RIJNDAEL192 GCRY_CIPHER_AES192 +-#define GCRY_CIPHER_RIJNDAEL256 GCRY_CIPHER_AES256 +- +-/* The supported encryption modes. Note that not all of them are +- supported for each algorithm. */ +-enum gcry_cipher_modes +- { +- GCRY_CIPHER_MODE_NONE = 0, /* Not yet specified. */ +- GCRY_CIPHER_MODE_ECB = 1, /* Electronic codebook. */ +- GCRY_CIPHER_MODE_CFB = 2, /* Cipher feedback. */ +- GCRY_CIPHER_MODE_CBC = 3, /* Cipher block chaining. */ +- GCRY_CIPHER_MODE_STREAM = 4, /* Used with stream ciphers. */ +- GCRY_CIPHER_MODE_OFB = 5, /* Outer feedback. */ +- GCRY_CIPHER_MODE_CTR = 6, /* Counter. */ +- GCRY_CIPHER_MODE_AESWRAP= 7 /* AES-WRAP algorithm. */ +- }; +- +-/* Flags used with the open function. */ +-enum gcry_cipher_flags +- { +- GCRY_CIPHER_SECURE = 1, /* Allocate in secure memory. */ +- GCRY_CIPHER_ENABLE_SYNC = 2, /* Enable CFB sync mode. */ +- GCRY_CIPHER_CBC_CTS = 4, /* Enable CBC cipher text stealing (CTS). */ +- GCRY_CIPHER_CBC_MAC = 8 /* Enable CBC message auth. code (MAC). */ +- }; +- +- +-/* Create a handle for algorithm ALGO to be used in MODE. FLAGS may +- be given as an bitwise OR of the gcry_cipher_flags values. */ +-gcry_error_t gcry_cipher_open (gcry_cipher_hd_t *handle, +- int algo, int mode, unsigned int flags); +- +-/* Close the cioher handle H and release all resource. */ +-void gcry_cipher_close (gcry_cipher_hd_t h); +- +-/* Perform various operations on the cipher object H. */ +-gcry_error_t gcry_cipher_ctl (gcry_cipher_hd_t h, int cmd, void *buffer, +- size_t buflen); +- +-/* Retrieve various information about the cipher object H. */ +-gcry_error_t gcry_cipher_info (gcry_cipher_hd_t h, int what, void *buffer, +- size_t *nbytes); +- +-/* Retrieve various information about the cipher algorithm ALGO. */ +-gcry_error_t gcry_cipher_algo_info (int algo, int what, void *buffer, +- size_t *nbytes); +- +-/* Map the cipher algorithm whose ID is contained in ALGORITHM to a +- string representation of the algorithm name. For unknown algorithm +- IDs this function returns "?". */ +-const char *gcry_cipher_algo_name (int algorithm) _GCRY_GCC_ATTR_PURE; +- +-/* Map the algorithm name NAME to an cipher algorithm ID. Return 0 if +- the algorithm name is not known. */ +-int gcry_cipher_map_name (const char *name) _GCRY_GCC_ATTR_PURE; +- +-/* Given an ASN.1 object identifier in standard IETF dotted decimal +- format in STRING, return the encryption mode associated with that +- OID or 0 if not known or applicable. */ +-int gcry_cipher_mode_from_oid (const char *string) _GCRY_GCC_ATTR_PURE; +- +-/* Encrypt the plaintext of size INLEN in IN using the cipher handle H +- into the buffer OUT which has an allocated length of OUTSIZE. For +- most algorithms it is possible to pass NULL for in and 0 for INLEN +- and do a in-place decryption of the data provided in OUT. */ +-gcry_error_t gcry_cipher_encrypt (gcry_cipher_hd_t h, +- void *out, size_t outsize, +- const void *in, size_t inlen); +- +-/* The counterpart to gcry_cipher_encrypt. */ +-gcry_error_t gcry_cipher_decrypt (gcry_cipher_hd_t h, +- void *out, size_t outsize, +- const void *in, size_t inlen); +- +-/* Set KEY of length KEYLEN bytes for the cipher handle HD. */ +-gcry_error_t gcry_cipher_setkey (gcry_cipher_hd_t hd, +- const void *key, size_t keylen); +- +- +-/* Set initialization vector IV of length IVLEN for the cipher handle HD. */ +-gcry_error_t gcry_cipher_setiv (gcry_cipher_hd_t hd, +- const void *iv, size_t ivlen); +- +- +-/* Reset the handle to the state after open. */ +-#define gcry_cipher_reset(h) gcry_cipher_ctl ((h), GCRYCTL_RESET, NULL, 0) +- +-/* Perform the OpenPGP sync operation if this is enabled for the +- cipher handle H. */ +-#define gcry_cipher_sync(h) gcry_cipher_ctl( (h), GCRYCTL_CFB_SYNC, NULL, 0) +- +-/* Enable or disable CTS in future calls to gcry_encrypt(). CBC mode only. */ +-#define gcry_cipher_cts(h,on) gcry_cipher_ctl( (h), GCRYCTL_SET_CBC_CTS, \ +- NULL, on ) +- +-/* Set counter for CTR mode. (CTR,CTRLEN) must denote a buffer of +- block size length, or (NULL,0) to set the CTR to the all-zero block. */ +-gpg_error_t gcry_cipher_setctr (gcry_cipher_hd_t hd, +- const void *ctr, size_t ctrlen); +- +-/* Retrieve the key length in bytes used with algorithm A. */ +-size_t gcry_cipher_get_algo_keylen (int algo); +- +-/* Retrieve the block length in bytes used with algorithm A. */ +-size_t gcry_cipher_get_algo_blklen (int algo); +- +-/* Return 0 if the algorithm A is available for use. */ +-#define gcry_cipher_test_algo(a) \ +- gcry_cipher_algo_info( (a), GCRYCTL_TEST_ALGO, NULL, NULL ) +- +- +-/************************************ +- * * +- * Asymmetric Cipher Functions * +- * * +- ************************************/ +- +-/* The algorithms and their IDs we support. */ +-enum gcry_pk_algos +- { +- GCRY_PK_RSA = 1, +- GCRY_PK_RSA_E = 2, /* (deprecated) */ +- GCRY_PK_RSA_S = 3, /* (deprecated) */ +- GCRY_PK_ELG_E = 16, +- GCRY_PK_DSA = 17, +- GCRY_PK_ELG = 20, +- GCRY_PK_ECDSA = 301, +- GCRY_PK_ECDH = 302 +- }; +- +-/* Flags describing usage capabilities of a PK algorithm. */ +-#define GCRY_PK_USAGE_SIGN 1 /* Good for signatures. */ +-#define GCRY_PK_USAGE_ENCR 2 /* Good for encryption. */ +-#define GCRY_PK_USAGE_CERT 4 /* Good to certify other keys. */ +-#define GCRY_PK_USAGE_AUTH 8 /* Good for authentication. */ +-#define GCRY_PK_USAGE_UNKN 128 /* Unknown usage flag. */ +- +-/* Encrypt the DATA using the public key PKEY and store the result as +- a newly created S-expression at RESULT. */ +-gcry_error_t gcry_pk_encrypt (gcry_sexp_t *result, +- gcry_sexp_t data, gcry_sexp_t pkey); +- +-/* Decrypt the DATA using the private key SKEY and store the result as +- a newly created S-expression at RESULT. */ +-gcry_error_t gcry_pk_decrypt (gcry_sexp_t *result, +- gcry_sexp_t data, gcry_sexp_t skey); +- +-/* Sign the DATA using the private key SKEY and store the result as +- a newly created S-expression at RESULT. */ +-gcry_error_t gcry_pk_sign (gcry_sexp_t *result, +- gcry_sexp_t data, gcry_sexp_t skey); +- +-/* Check the signature SIGVAL on DATA using the public key PKEY. */ +-gcry_error_t gcry_pk_verify (gcry_sexp_t sigval, +- gcry_sexp_t data, gcry_sexp_t pkey); +- +-/* Check that private KEY is sane. */ +-gcry_error_t gcry_pk_testkey (gcry_sexp_t key); +- +-/* Generate a new key pair according to the parameters given in +- S_PARMS. The new key pair is returned in as an S-expression in +- R_KEY. */ +-gcry_error_t gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms); +- +-/* Catch all function for miscellaneous operations. */ +-gcry_error_t gcry_pk_ctl (int cmd, void *buffer, size_t buflen); +- +-/* Retrieve information about the public key algorithm ALGO. */ +-gcry_error_t gcry_pk_algo_info (int algo, int what, +- void *buffer, size_t *nbytes); +- +-/* Map the public key algorithm whose ID is contained in ALGORITHM to +- a string representation of the algorithm name. For unknown +- algorithm IDs this functions returns "?". */ +-const char *gcry_pk_algo_name (int algorithm) _GCRY_GCC_ATTR_PURE; +- +-/* Map the algorithm NAME to a public key algorithm Id. Return 0 if +- the algorithm name is not known. */ +-int gcry_pk_map_name (const char* name) _GCRY_GCC_ATTR_PURE; +- +-/* Return what is commonly referred as the key length for the given +- public or private KEY. */ +-unsigned int gcry_pk_get_nbits (gcry_sexp_t key) _GCRY_GCC_ATTR_PURE; +- +-/* Please note that keygrip is still experimental and should not be +- used without contacting the author. */ +-unsigned char *gcry_pk_get_keygrip (gcry_sexp_t key, unsigned char *array); +- +-/* Return the name of the curve matching KEY. */ +-const char *gcry_pk_get_curve (gcry_sexp_t key, int iterator, +- unsigned int *r_nbits); +- +-/* Return an S-expression with the parameters of the named ECC curve +- NAME. ALGO must be set to an ECC algorithm. */ +-gcry_sexp_t gcry_pk_get_param (int algo, const char *name); +- +-/* Return 0 if the public key algorithm A is available for use. */ +-#define gcry_pk_test_algo(a) \ +- gcry_pk_algo_info( (a), GCRYCTL_TEST_ALGO, NULL, NULL ) +- +- +- +- +-/************************************ +- * * +- * Cryptograhic Hash Functions * +- * * +- ************************************/ +- +-/* Algorithm IDs for the hash functions we know about. Not all of them +- are implemnted. */ +-enum gcry_md_algos +- { +- GCRY_MD_NONE = 0, +- GCRY_MD_MD5 = 1, +- GCRY_MD_SHA1 = 2, +- GCRY_MD_RMD160 = 3, +- GCRY_MD_MD2 = 5, +- GCRY_MD_TIGER = 6, /* TIGER/192 as used by gpg <= 1.3.2. */ +- GCRY_MD_HAVAL = 7, /* HAVAL, 5 pass, 160 bit. */ +- GCRY_MD_SHA256 = 8, +- GCRY_MD_SHA384 = 9, +- GCRY_MD_SHA512 = 10, +- GCRY_MD_SHA224 = 11, +- GCRY_MD_MD4 = 301, +- GCRY_MD_CRC32 = 302, +- GCRY_MD_CRC32_RFC1510 = 303, +- GCRY_MD_CRC24_RFC2440 = 304, +- GCRY_MD_WHIRLPOOL = 305, +- GCRY_MD_TIGER1 = 306, /* TIGER fixed. */ +- GCRY_MD_TIGER2 = 307 /* TIGER2 variant. */ +- }; +- +-/* Flags used with the open function. */ +-enum gcry_md_flags +- { +- GCRY_MD_FLAG_SECURE = 1, /* Allocate all buffers in "secure" memory. */ +- GCRY_MD_FLAG_HMAC = 2 /* Make an HMAC out of this algorithm. */ +- }; +- +-/* (Forward declaration.) */ +-struct gcry_md_context; +- +-/* This object is used to hold a handle to a message digest object. +- This structure is private - only to be used by the public gcry_md_* +- macros. */ +-typedef struct gcry_md_handle +-{ +- /* Actual context. */ +- struct gcry_md_context *ctx; +- +- /* Buffer management. */ +- int bufpos; +- int bufsize; +- unsigned char buf[1]; +-} *gcry_md_hd_t; +- +-/* Compatibility types, do not use them. */ +-#ifndef GCRYPT_NO_DEPRECATED +-typedef struct gcry_md_handle *GCRY_MD_HD _GCRY_GCC_ATTR_DEPRECATED; +-typedef struct gcry_md_handle *GcryMDHd _GCRY_GCC_ATTR_DEPRECATED; +-#endif +- +-/* Create a message digest object for algorithm ALGO. FLAGS may be +- given as an bitwise OR of the gcry_md_flags values. ALGO may be +- given as 0 if the algorithms to be used are later set using +- gcry_md_enable. */ +-gcry_error_t gcry_md_open (gcry_md_hd_t *h, int algo, unsigned int flags); +- +-/* Release the message digest object HD. */ +-void gcry_md_close (gcry_md_hd_t hd); +- +-/* Add the message digest algorithm ALGO to the digest object HD. */ +-gcry_error_t gcry_md_enable (gcry_md_hd_t hd, int algo); +- +-/* Create a new digest object as an exact copy of the object HD. */ +-gcry_error_t gcry_md_copy (gcry_md_hd_t *bhd, gcry_md_hd_t ahd); +- +-/* Reset the digest object HD to its initial state. */ +-void gcry_md_reset (gcry_md_hd_t hd); +- +-/* Perform various operations on the digest object HD. */ +-gcry_error_t gcry_md_ctl (gcry_md_hd_t hd, int cmd, +- void *buffer, size_t buflen); +- +-/* Pass LENGTH bytes of data in BUFFER to the digest object HD so that +- it can update the digest values. This is the actual hash +- function. */ +-void gcry_md_write (gcry_md_hd_t hd, const void *buffer, size_t length); +- +-/* Read out the final digest from HD return the digest value for +- algorithm ALGO. */ +-unsigned char *gcry_md_read (gcry_md_hd_t hd, int algo); +- +-/* Convenience function to calculate the hash from the data in BUFFER +- of size LENGTH using the algorithm ALGO avoiding the creating of a +- hash object. The hash is returned in the caller provided buffer +- DIGEST which must be large enough to hold the digest of the given +- algorithm. */ +-void gcry_md_hash_buffer (int algo, void *digest, +- const void *buffer, size_t length); +- +-/* Retrieve the algorithm used with HD. This does not work reliable +- if more than one algorithm is enabled in HD. */ +-int gcry_md_get_algo (gcry_md_hd_t hd); +- +-/* Retrieve the length in bytes of the digest yielded by algorithm +- ALGO. */ +-unsigned int gcry_md_get_algo_dlen (int algo); +- +-/* Return true if the the algorithm ALGO is enabled in the digest +- object A. */ +-int gcry_md_is_enabled (gcry_md_hd_t a, int algo); +- +-/* Return true if the digest object A is allocated in "secure" memory. */ +-int gcry_md_is_secure (gcry_md_hd_t a); +- +-/* Retrieve various information about the object H. */ +-gcry_error_t gcry_md_info (gcry_md_hd_t h, int what, void *buffer, +- size_t *nbytes); +- +-/* Retrieve various information about the algorithm ALGO. */ +-gcry_error_t gcry_md_algo_info (int algo, int what, void *buffer, +- size_t *nbytes); +- +-/* Map the digest algorithm id ALGO to a string representation of the +- algorithm name. For unknown algorithms this function returns +- "?". */ +-const char *gcry_md_algo_name (int algo) _GCRY_GCC_ATTR_PURE; +- +-/* Map the algorithm NAME to a digest algorithm Id. Return 0 if +- the algorithm name is not known. */ +-int gcry_md_map_name (const char* name) _GCRY_GCC_ATTR_PURE; +- +-/* For use with the HMAC feature, the set MAC key to the KEY of +- KEYLEN bytes. */ +-gcry_error_t gcry_md_setkey (gcry_md_hd_t hd, const void *key, size_t keylen); +- +-/* Start or stop debugging for digest handle HD; i.e. create a file +- named dbgmd-. while hashing. If SUFFIX is NULL, +- debugging stops and the file will be closed. */ +-void gcry_md_debug (gcry_md_hd_t hd, const char *suffix); +- +- +-/* Update the hash(s) of H with the character C. This is a buffered +- version of the gcry_md_write function. */ +-#define gcry_md_putc(h,c) \ +- do { \ +- gcry_md_hd_t h__ = (h); \ +- if( (h__)->bufpos == (h__)->bufsize ) \ +- gcry_md_write( (h__), NULL, 0 ); \ +- (h__)->buf[(h__)->bufpos++] = (c) & 0xff; \ +- } while(0) +- +-/* Finalize the digest calculation. This is not really needed because +- gcry_md_read() does this implicitly. */ +-#define gcry_md_final(a) \ +- gcry_md_ctl ((a), GCRYCTL_FINALIZE, NULL, 0) +- +-/* Return 0 if the algorithm A is available for use. */ +-#define gcry_md_test_algo(a) \ +- gcry_md_algo_info( (a), GCRYCTL_TEST_ALGO, NULL, NULL ) +- +-/* Return an DER encoded ASN.1 OID for the algorithm A in buffer B. N +- must point to size_t variable with the available size of buffer B. +- After return it will receive the actual size of the returned +- OID. */ +-#define gcry_md_get_asnoid(a,b,n) \ +- gcry_md_algo_info((a), GCRYCTL_GET_ASNOID, (b), (n)) +- +- +- +-/****************************** +- * * +- * Key Derivation Functions * +- * * +- ******************************/ +- +-/* Algorithm IDs for the KDFs. */ +-enum gcry_kdf_algos +- { +- GCRY_KDF_NONE = 0, +- GCRY_KDF_SIMPLE_S2K = 16, +- GCRY_KDF_SALTED_S2K = 17, +- GCRY_KDF_ITERSALTED_S2K = 19, +- GCRY_KDF_PBKDF1 = 33, +- GCRY_KDF_PBKDF2 = 34 +- }; +- +-/* Derive a key from a passphrase. */ +-gpg_error_t gcry_kdf_derive (const void *passphrase, size_t passphraselen, +- int algo, int subalgo, +- const void *salt, size_t saltlen, +- unsigned long iterations, +- size_t keysize, void *keybuffer); +- +- +- +- +-/************************************ +- * * +- * Random Generating Functions * +- * * +- ************************************/ +- +-/* The possible values for the random quality. The rule of thumb is +- to use STRONG for session keys and VERY_STRONG for key material. +- WEAK is usually an alias for STRONG and should not be used anymore +- (except with gcry_mpi_randomize); use gcry_create_nonce instead. */ +-typedef enum gcry_random_level +- { +- GCRY_WEAK_RANDOM = 0, +- GCRY_STRONG_RANDOM = 1, +- GCRY_VERY_STRONG_RANDOM = 2 +- } +-gcry_random_level_t; +- +-/* Fill BUFFER with LENGTH bytes of random, using random numbers of +- quality LEVEL. */ +-void gcry_randomize (void *buffer, size_t length, +- enum gcry_random_level level); +- +-/* Add the external random from BUFFER with LENGTH bytes into the +- pool. QUALITY should either be -1 for unknown or in the range of 0 +- to 100 */ +-gcry_error_t gcry_random_add_bytes (const void *buffer, size_t length, +- int quality); +- +-/* If random numbers are used in an application, this macro should be +- called from time to time so that new stuff gets added to the +- internal pool of the RNG. */ +-#define gcry_fast_random_poll() gcry_control (GCRYCTL_FAST_POLL, NULL) +- +- +-/* Return NBYTES of allocated random using a random numbers of quality +- LEVEL. */ +-void *gcry_random_bytes (size_t nbytes, enum gcry_random_level level) +- _GCRY_GCC_ATTR_MALLOC; +- +-/* Return NBYTES of allocated random using a random numbers of quality +- LEVEL. The random numbers are created returned in "secure" +- memory. */ +-void *gcry_random_bytes_secure (size_t nbytes, enum gcry_random_level level) +- _GCRY_GCC_ATTR_MALLOC; +- +- +-/* Set the big integer W to a random value of NBITS using a random +- generator with quality LEVEL. Note that by using a level of +- GCRY_WEAK_RANDOM gcry_create_nonce is used internally. */ +-void gcry_mpi_randomize (gcry_mpi_t w, +- unsigned int nbits, enum gcry_random_level level); +- +- +-/* Create an unpredicable nonce of LENGTH bytes in BUFFER. */ +-void gcry_create_nonce (void *buffer, size_t length); +- +- +- +- +- +-/*******************************/ +-/* */ +-/* Prime Number Functions */ +-/* */ +-/*******************************/ +- +-/* Mode values passed to a gcry_prime_check_func_t. */ +-#define GCRY_PRIME_CHECK_AT_FINISH 0 +-#define GCRY_PRIME_CHECK_AT_GOT_PRIME 1 +-#define GCRY_PRIME_CHECK_AT_MAYBE_PRIME 2 +- +-/* The function should return 1 if the operation shall continue, 0 to +- reject the prime candidate. */ +-typedef int (*gcry_prime_check_func_t) (void *arg, int mode, +- gcry_mpi_t candidate); +- +-/* Flags for gcry_prime_generate(): */ +- +-/* Allocate prime numbers and factors in secure memory. */ +-#define GCRY_PRIME_FLAG_SECRET (1 << 0) +- +-/* Make sure that at least one prime factor is of size +- `FACTOR_BITS'. */ +-#define GCRY_PRIME_FLAG_SPECIAL_FACTOR (1 << 1) +- +-/* Generate a new prime number of PRIME_BITS bits and store it in +- PRIME. If FACTOR_BITS is non-zero, one of the prime factors of +- (prime - 1) / 2 must be FACTOR_BITS bits long. If FACTORS is +- non-zero, allocate a new, NULL-terminated array holding the prime +- factors and store it in FACTORS. FLAGS might be used to influence +- the prime number generation process. */ +-gcry_error_t gcry_prime_generate (gcry_mpi_t *prime, +- unsigned int prime_bits, +- unsigned int factor_bits, +- gcry_mpi_t **factors, +- gcry_prime_check_func_t cb_func, +- void *cb_arg, +- gcry_random_level_t random_level, +- unsigned int flags); +- +-/* Find a generator for PRIME where the factorization of (prime-1) is +- in the NULL terminated array FACTORS. Return the generator as a +- newly allocated MPI in R_G. If START_G is not NULL, use this as +- teh start for the search. */ +-gcry_error_t gcry_prime_group_generator (gcry_mpi_t *r_g, +- gcry_mpi_t prime, +- gcry_mpi_t *factors, +- gcry_mpi_t start_g); +- +- +-/* Convenience function to release the FACTORS array. */ +-void gcry_prime_release_factors (gcry_mpi_t *factors); +- +- +-/* Check wether the number X is prime. */ +-gcry_error_t gcry_prime_check (gcry_mpi_t x, unsigned int flags); +- +- +- +-/************************************ +- * * +- * Miscellaneous Stuff * +- * * +- ************************************/ +- +-/* Log levels used by the internal logging facility. */ +-enum gcry_log_levels +- { +- GCRY_LOG_CONT = 0, /* (Continue the last log line.) */ +- GCRY_LOG_INFO = 10, +- GCRY_LOG_WARN = 20, +- GCRY_LOG_ERROR = 30, +- GCRY_LOG_FATAL = 40, +- GCRY_LOG_BUG = 50, +- GCRY_LOG_DEBUG = 100 +- }; +- +-/* Type for progress handlers. */ +-typedef void (*gcry_handler_progress_t) (void *, const char *, int, int, int); +- +-/* Type for memory allocation handlers. */ +-typedef void *(*gcry_handler_alloc_t) (size_t n); +- +-/* Type for secure memory check handlers. */ +-typedef int (*gcry_handler_secure_check_t) (const void *); +- +-/* Type for memory reallocation handlers. */ +-typedef void *(*gcry_handler_realloc_t) (void *p, size_t n); +- +-/* Type for memory free handlers. */ +-typedef void (*gcry_handler_free_t) (void *); +- +-/* Type for out-of-memory handlers. */ +-typedef int (*gcry_handler_no_mem_t) (void *, size_t, unsigned int); +- +-/* Type for fatal error handlers. */ +-typedef void (*gcry_handler_error_t) (void *, int, const char *); +- +-/* Type for logging handlers. */ +-typedef void (*gcry_handler_log_t) (void *, int, const char *, va_list); +- +-/* Certain operations can provide progress information. This function +- is used to register a handler for retrieving these information. */ +-void gcry_set_progress_handler (gcry_handler_progress_t cb, void *cb_data); +- +- +-/* Register a custom memory allocation functions. */ +-void gcry_set_allocation_handler ( +- gcry_handler_alloc_t func_alloc, +- gcry_handler_alloc_t func_alloc_secure, +- gcry_handler_secure_check_t func_secure_check, +- gcry_handler_realloc_t func_realloc, +- gcry_handler_free_t func_free); +- +-/* Register a function used instead of the internal out of memory +- handler. */ +-void gcry_set_outofcore_handler (gcry_handler_no_mem_t h, void *opaque); +- +-/* Register a function used instead of the internal fatal error +- handler. */ +-void gcry_set_fatalerror_handler (gcry_handler_error_t fnc, void *opaque); +- +-/* Register a function used instead of the internal logging +- facility. */ +-void gcry_set_log_handler (gcry_handler_log_t f, void *opaque); +- +-/* Reserved for future use. */ +-void gcry_set_gettext_handler (const char *(*f)(const char*)); +- +-/* Libgcrypt uses its own memory allocation. It is important to use +- gcry_free () to release memory allocated by libgcrypt. */ +-void *gcry_malloc (size_t n) _GCRY_GCC_ATTR_MALLOC; +-void *gcry_calloc (size_t n, size_t m) _GCRY_GCC_ATTR_MALLOC; +-void *gcry_malloc_secure (size_t n) _GCRY_GCC_ATTR_MALLOC; +-void *gcry_calloc_secure (size_t n, size_t m) _GCRY_GCC_ATTR_MALLOC; +-void *gcry_realloc (void *a, size_t n); +-char *gcry_strdup (const char *string) _GCRY_GCC_ATTR_MALLOC; +-void *gcry_xmalloc (size_t n) _GCRY_GCC_ATTR_MALLOC; +-void *gcry_xcalloc (size_t n, size_t m) _GCRY_GCC_ATTR_MALLOC; +-void *gcry_xmalloc_secure (size_t n) _GCRY_GCC_ATTR_MALLOC; +-void *gcry_xcalloc_secure (size_t n, size_t m) _GCRY_GCC_ATTR_MALLOC; +-void *gcry_xrealloc (void *a, size_t n); +-char *gcry_xstrdup (const char * a) _GCRY_GCC_ATTR_MALLOC; +-void gcry_free (void *a); +- +-/* Return true if A is allocated in "secure" memory. */ +-int gcry_is_secure (const void *a) _GCRY_GCC_ATTR_PURE; +- +-/* Return true if Libgcrypt is in FIPS mode. */ +-#define gcry_fips_mode_active() !!gcry_control (GCRYCTL_FIPS_MODE_P, 0) +- +- +-#if 0 /* (Keep Emacsens' auto-indent happy.) */ +-{ +-#endif +-#ifdef __cplusplus +-} +-#endif +-#endif /* _GCRYPT_H */ +-/* +-@emacs_local_vars_begin@ +-@emacs_local_vars_read_only@ +-@emacs_local_vars_end@ +-*/ +-- +1.8.1.4 + diff --git a/0098-grub-core-lib-libgcrypt_wrap-mem.c-_gcry_log_bug-Mak.patch b/0098-grub-core-lib-libgcrypt_wrap-mem.c-_gcry_log_bug-Mak.patch new file mode 100644 index 0000000..cf4af16 --- /dev/null +++ b/0098-grub-core-lib-libgcrypt_wrap-mem.c-_gcry_log_bug-Mak.patch @@ -0,0 +1,41 @@ +From a718c4254f78dd96e9fa1c1e704ba337f8e009e0 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sat, 12 Jan 2013 16:21:06 +0100 +Subject: [PATCH 098/364] * grub-core/lib/libgcrypt_wrap/mem.c + (_gcry_log_bug): Make gcrypt bugs fatal. + +--- + ChangeLog | 7 ++++++- + grub-core/lib/libgcrypt_wrap/mem.c | 1 + + 2 files changed, 7 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index d83d10a..8a16591 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,4 +1,9 @@ +-2013-01-11 Vladimir Serbinenko ++2013-01-12 Vladimir Serbinenko ++ ++ * grub-core/lib/libgcrypt_wrap/mem.c (_gcry_log_bug): Make gcrypt bugs ++ fatal. ++ ++2013-01-12 Vladimir Serbinenko + + * autogen.sh: Do not try to delete nonexistant files. + * util/import_gcrypth.sed: Add some missing header removals. +diff --git a/grub-core/lib/libgcrypt_wrap/mem.c b/grub-core/lib/libgcrypt_wrap/mem.c +index a9f0aff..64e8b62 100644 +--- a/grub-core/lib/libgcrypt_wrap/mem.c ++++ b/grub-core/lib/libgcrypt_wrap/mem.c +@@ -95,6 +95,7 @@ void _gcry_log_bug (const char *fmt, ...) + grub_vprintf (fmt, args); + va_end (args); + grub_refresh (); ++ grub_abort (); + } + + gcry_err_code_t +-- +1.8.1.4 + diff --git a/0099-grub-core-lib-libgcrypt_wrap-mem.c-gcry_x-alloc-Make.patch b/0099-grub-core-lib-libgcrypt_wrap-mem.c-gcry_x-alloc-Make.patch new file mode 100644 index 0000000..7a7670f --- /dev/null +++ b/0099-grub-core-lib-libgcrypt_wrap-mem.c-gcry_x-alloc-Make.patch @@ -0,0 +1,90 @@ +From 076ad04668ff689b023166931edca6fa03530bf9 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sat, 12 Jan 2013 16:27:37 +0100 +Subject: [PATCH 099/364] * grub-core/lib/libgcrypt_wrap/mem.c + (gcry_x*alloc): Make out of memory fatal. + +--- + ChangeLog | 5 +++++ + grub-core/lib/libgcrypt_wrap/mem.c | 30 +++++++++++++++++++++++++----- + 2 files changed, 30 insertions(+), 5 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 8a16591..4ac0aa6 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,10 @@ + 2013-01-12 Vladimir Serbinenko + ++ * grub-core/lib/libgcrypt_wrap/mem.c (gcry_x*alloc): Make out of memory ++ fatal. ++ ++2013-01-12 Vladimir Serbinenko ++ + * grub-core/lib/libgcrypt_wrap/mem.c (_gcry_log_bug): Make gcrypt bugs + fatal. + +diff --git a/grub-core/lib/libgcrypt_wrap/mem.c b/grub-core/lib/libgcrypt_wrap/mem.c +index 64e8b62..94f9d65 100644 +--- a/grub-core/lib/libgcrypt_wrap/mem.c ++++ b/grub-core/lib/libgcrypt_wrap/mem.c +@@ -35,31 +35,51 @@ gcry_is_secure (const void *a __attribute__ ((unused))) + void * + gcry_xcalloc (size_t n, size_t m) + { +- return grub_zalloc (n * m); ++ void *ret; ++ ret = grub_zalloc (n * m); ++ if (!ret) ++ grub_fatal ("gcry_xcalloc failed"); ++ return ret; + } + + void * + gcry_xmalloc_secure (size_t n) + { +- return grub_malloc (n); ++ void *ret; ++ ret = grub_malloc (n); ++ if (!ret) ++ grub_fatal ("gcry_xmalloc failed"); ++ return ret; + } + + void * + gcry_xcalloc_secure (size_t n, size_t m) + { +- return grub_zalloc (n * m); ++ void *ret; ++ ret = grub_zalloc (n * m); ++ if (!ret) ++ grub_fatal ("gcry_xcalloc failed"); ++ return ret; + } + + void * + gcry_xmalloc (size_t n) + { +- return grub_malloc (n); ++ void *ret; ++ ret = grub_malloc (n); ++ if (!ret) ++ grub_fatal ("gcry_xmalloc failed"); ++ return ret; + } + + void * + gcry_xrealloc (void *a, size_t n) + { +- return grub_realloc (a, n); ++ void *ret; ++ ret = grub_realloc (a, n); ++ if (!ret) ++ grub_fatal ("gcry_xrealloc failed"); ++ return ret; + } + + void +-- +1.8.1.4 + diff --git a/0100-grub-core-commands-verify.c-Mark-messages-for-transl.patch b/0100-grub-core-commands-verify.c-Mark-messages-for-transl.patch new file mode 100644 index 0000000..29eb178 --- /dev/null +++ b/0100-grub-core-commands-verify.c-Mark-messages-for-transl.patch @@ -0,0 +1,351 @@ +From 3db3ccbf0ad7a5c4593f94ea9660552ab82f6f08 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sat, 12 Jan 2013 16:31:17 +0100 +Subject: [PATCH 100/364] * grub-core/commands/verify.c: Mark messages + for translating. + +--- + ChangeLog | 4 ++ + grub-core/commands/verify.c | 93 +++++++++++++++++++++++---------------------- + 2 files changed, 52 insertions(+), 45 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 4ac0aa6..b527f7a 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,9 @@ + 2013-01-12 Vladimir Serbinenko + ++ * grub-core/commands/verify.c: Mark messages for translating. ++ ++2013-01-12 Vladimir Serbinenko ++ + * grub-core/lib/libgcrypt_wrap/mem.c (gcry_x*alloc): Make out of memory + fatal. + +diff --git a/grub-core/commands/verify.c b/grub-core/commands/verify.c +index 415e4bf..66a027f 100644 +--- a/grub-core/commands/verify.c ++++ b/grub-core/commands/verify.c +@@ -53,7 +53,8 @@ read_packet_header (grub_file_t sig, grub_uint8_t *out_type, grub_size_t *len) + default: + if (grub_errno) + return grub_errno; +- return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ /* TRANSLATORS: it's about GNUPG signatures. */ ++ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); + } + + if (type == 0) +@@ -63,12 +64,12 @@ read_packet_header (grub_file_t sig, grub_uint8_t *out_type, grub_size_t *len) + } + + if (!(type & 0x80)) +- return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); + if (type & 0x40) + { + *out_type = (type & 0x3f); + if (grub_file_read (sig, &l, sizeof (l)) != 1) +- return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); + if (l < 192) + { + *len = l; +@@ -78,39 +79,39 @@ read_packet_header (grub_file_t sig, grub_uint8_t *out_type, grub_size_t *len) + { + *len = (l - 192) << 8; + if (grub_file_read (sig, &l, sizeof (l)) != 1) +- return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); + *len |= l; + return 0; + } + if (l == 255) + { + if (grub_file_read (sig, &l32, sizeof (l32)) != sizeof (l32)) +- return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); + *len = grub_be_to_cpu32 (l32); + return 0; + } +- return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); + } + *out_type = ((type >> 2) & 0xf); + switch (type & 0x3) + { + case 0: + if (grub_file_read (sig, &l, sizeof (l)) != sizeof (l)) +- return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); + *len = l; + return 0; + case 1: + if (grub_file_read (sig, &l16, sizeof (l16)) != sizeof (l16)) +- return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); + *len = grub_be_to_cpu16 (l16); + return 0; + case 2: + if (grub_file_read (sig, &l32, sizeof (l32)) != sizeof (l32)) +- return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); + *len = grub_be_to_cpu32 (l32); + return 0; + } +- return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); + } + + struct signature_v4_header +@@ -210,7 +211,7 @@ grub_load_public_key (grub_file_t f) + + if (grub_file_read (f, &v, sizeof (v)) != sizeof (v)) + { +- grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); + goto fail; + } + +@@ -218,12 +219,12 @@ grub_load_public_key (grub_file_t f) + + if (v != 4) + { +- grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); + goto fail; + } + if (grub_file_read (f, &creation_time, sizeof (creation_time)) != sizeof (creation_time)) + { +- grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); + goto fail; + } + +@@ -231,7 +232,7 @@ grub_load_public_key (grub_file_t f) + + if (grub_file_read (f, &pk, sizeof (pk)) != sizeof (pk)) + { +- grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); + goto fail; + } + +@@ -263,19 +264,19 @@ grub_load_public_key (grub_file_t f) + grub_uint8_t buffer[4096]; + if (grub_file_read (f, &l, sizeof (l)) != sizeof (l)) + { +- grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); + goto fail; + } + + lb = (grub_be_to_cpu16 (l) + 7) / 8; + if (lb > sizeof (buffer) - sizeof (grub_uint16_t)) + { +- grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); + goto fail; + } + if (grub_file_read (f, buffer + sizeof (grub_uint16_t), lb) != (grub_ssize_t) lb) + { +- grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); + goto fail; + } + grub_memcpy (buffer, &l, sizeof (l)); +@@ -285,7 +286,7 @@ grub_load_public_key (grub_file_t f) + if (gcry_mpi_scan (&sk->mpis[i], GCRYMPI_FMT_PGP, + buffer, lb + sizeof (grub_uint16_t), 0)) + { +- grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); + goto fail; + } + } +@@ -357,29 +358,29 @@ grub_verify_signature (grub_file_t f, grub_file_t sig, + return err; + + if (type != 0x2) +- return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); + + if (grub_file_read (sig, &v, sizeof (v)) != sizeof (v)) +- return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); + + if (v != 4) +- return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); + + if (grub_file_read (sig, &v4, sizeof (v4)) != sizeof (v4)) +- return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); + + h = v4.hash; + t = v4.type; + pk = v4.pkeyalgo; + + if (t != 0) +- return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); + + if (h >= ARRAY_SIZE (hashes) || hashes[h] == NULL) + return grub_error (GRUB_ERR_BAD_SIGNATURE, "unknown hash"); + + if (pk >= ARRAY_SIZE (pkalgos) || pkalgos[pk].name == NULL) +- return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); + + hash = grub_crypto_lookup_md_by_name (hashes[h]); + if (!hash) +@@ -420,7 +421,7 @@ grub_verify_signature (grub_file_t f, grub_file_t sig, + grub_uint8_t readbuf[4096]; + r = grub_file_read (sig, readbuf, rem < (grub_ssize_t) sizeof (readbuf) ? rem : (grub_ssize_t) sizeof (readbuf)); + if (r < 0) +- return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); + if (r == 0) + break; + hash->write (context, readbuf, r); +@@ -432,17 +433,17 @@ grub_verify_signature (grub_file_t f, grub_file_t sig, + hash->write (context, &headlen, sizeof (headlen)); + r = grub_file_read (sig, &unhashed_sub, sizeof (unhashed_sub)); + if (r != sizeof (unhashed_sub)) +- return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); + { + grub_uint8_t readbuf[4096]; + grub_uint8_t *ptr; + grub_uint32_t l; + rem = grub_be_to_cpu16 (unhashed_sub); + if (rem > (int) sizeof (readbuf)) +- return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); + r = grub_file_read (sig, readbuf, rem); + if (r != rem) +- return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); + for (ptr = readbuf; ptr < readbuf + rem; ptr += l) + { + if (*ptr < 192) +@@ -473,9 +474,9 @@ grub_verify_signature (grub_file_t f, grub_file_t sig, + hval = hash->read (context); + + if (grub_file_read (sig, hash_start, sizeof (hash_start)) != sizeof (hash_start)) +- return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); + if (grub_memcmp (hval, hash_start, sizeof (hash_start)) != 0) +- return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); + + grub_dprintf ("crypt", "@ %x\n", (int)grub_file_tell (sig)); + +@@ -486,22 +487,22 @@ grub_verify_signature (grub_file_t f, grub_file_t sig, + grub_uint8_t buffer[4096]; + grub_dprintf ("crypt", "alive\n"); + if (grub_file_read (sig, &l, sizeof (l)) != sizeof (l)) +- return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); + grub_dprintf ("crypt", "alive\n"); + lb = (grub_be_to_cpu16 (l) + 7) / 8; + grub_dprintf ("crypt", "l = 0x%04x\n", grub_be_to_cpu16 (l)); + if (lb > sizeof (buffer) - sizeof (grub_uint16_t)) +- return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); + grub_dprintf ("crypt", "alive\n"); + if (grub_file_read (sig, buffer + sizeof (grub_uint16_t), lb) != (grub_ssize_t) lb) +- return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); + grub_dprintf ("crypt", "alive\n"); + grub_memcpy (buffer, &l, sizeof (l)); + grub_dprintf ("crypt", "alive\n"); + + if (gcry_mpi_scan (&mpis[i], GCRYMPI_FMT_PGP, + buffer, lb + sizeof (grub_uint16_t), 0)) +- return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); + grub_dprintf ("crypt", "alive\n"); + } + +@@ -510,17 +511,18 @@ grub_verify_signature (grub_file_t f, grub_file_t sig, + else + sk = grub_crypto_pk_locate_subkey_in_trustdb (keyid); + if (!sk) +- return grub_error (GRUB_ERR_BAD_SIGNATURE, "key not found"); ++ /* TRANSLATORS: %08x is 32-bit key id. */ ++ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("public key %08x not found"), keyid); + + int nbits = gcry_mpi_get_nbits (sk->mpis[1]); + grub_dprintf ("crypt", "must be %d bits got %d bits\n", (int)nbits, (int)(8 * hash->mdlen)); + + if (gcry_mpi_scan (&hmpi, GCRYMPI_FMT_USG, hval, nbits / 8 < (int) hash->mdlen ? nbits / 8 : (int) hash->mdlen, 0)) +- return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); + if (!grub_crypto_pk_dsa) +- return grub_error (GRUB_ERR_BAD_SIGNATURE, "DSA module is not loaded"); ++ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("module `%s' isn't loaded"), "gcry_dsa"); + if (grub_crypto_pk_dsa->verify (0, hmpi, mpis, sk->mpis, 0, 0)) +- return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature"); ++ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); + } + + return GRUB_ERR_NONE; +@@ -534,7 +536,7 @@ grub_cmd_trust (grub_command_t cmd __attribute__ ((unused)), + struct grub_public_key *pk = NULL; + + if (argc < 1) +- return grub_error (GRUB_ERR_BAD_ARGUMENT, "one argument required"); ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); + + grub_file_filter_disable_all (); + pkf = grub_file_open (args[0]); +@@ -563,7 +565,7 @@ grub_cmd_distrust (grub_command_t cmd __attribute__ ((unused)), + struct grub_public_subkey *sk; + + if (argc < 1) +- return grub_error (GRUB_ERR_BAD_ARGUMENT, "one argument required"); ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); + keyid = grub_strtoull (args[0], 0, 16); + if (grub_errno) + return grub_errno; +@@ -582,7 +584,8 @@ grub_cmd_distrust (grub_command_t cmd __attribute__ ((unused)), + *pkey = next; + return GRUB_ERR_NONE; + } +- return grub_error (GRUB_ERR_BAD_ARGUMENT, "key %08x not found", keyid); ++ /* TRANSLATORS: %08x is 32-bit key id. */ ++ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("public key %08x not found"), keyid); + } + + static grub_err_t +@@ -596,7 +599,7 @@ grub_cmd_verify_signature (grub_command_t cmd __attribute__ ((unused)), + grub_dprintf ("crypt", "alive\n"); + + if (argc < 2) +- return grub_error (GRUB_ERR_BAD_ARGUMENT, "two arguments required"); ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("two arguments expected")); + + grub_dprintf ("crypt", "alive\n"); + +@@ -744,13 +747,13 @@ GRUB_MOD_INIT(verify) + grub_env_set ("check_signatures", grub_pk_trusted ? "enforce" : "no"); + + cmd = grub_register_command ("verify_detached", grub_cmd_verify_signature, +- "FILE SIGFILE [PKFILE]", ++ N_("FILE SIGNATURE_FILE [PUBKEY_FILE]"), + N_("Verify detached signature.")); + cmd_trust = grub_register_command ("trust", grub_cmd_trust, +- "PKFILE", ++ N_("PUBKEY_FILE"), + N_("Add PKFILE to trusted keys.")); + cmd_distrust = grub_register_command ("distrust", grub_cmd_distrust, +- "KEYID", ++ N_("PUBKEY_ID"), + N_("Remove KEYID from trusted keys.")); + } + +-- +1.8.1.4 + diff --git a/0101-Remove-nested-functions-from-PCI-iterators.patch b/0101-Remove-nested-functions-from-PCI-iterators.patch new file mode 100644 index 0000000..dc8583a --- /dev/null +++ b/0101-Remove-nested-functions-from-PCI-iterators.patch @@ -0,0 +1,1214 @@ +From ded88969f8361b022582023d32e0a8e9f30eafe0 Mon Sep 17 00:00:00 2001 +From: Colin Watson +Date: Sun, 13 Jan 2013 01:10:41 +0000 +Subject: [PATCH 101/364] Remove nested functions from PCI iterators. + +* grub-core/bus/pci.c (grub_pci_iterate): Add hook_data argument, +passed to hook. Update all callers to pass appropriate hook data. +* grub-core/bus/emu/pci.c (grub_pci_iterate): Likewise. +* include/grub/pci.h (grub_pci_iteratefunc_t): Add data argument. +Remove NESTED_FUNC_ATTR from here and from all users. +(grub_pci_iterate): Update prototype. +* grub-core/bus/cs5536.c (grub_cs5536_find: hook): Make static +instead of nested. Rename to ... +(grub_cs5536_find_iter): ... this. +* grub-core/kern/efi/mm.c (stop_broadcom: find_card): Likewise. +* grub-core/kern/mips/loongson/init.c (init_pci: set_card): +Likewise. +* grub-core/kern/vga_init.c (grub_qemu_init_cirrus: find_card): +Likewise. +* grub-core/video/bochs.c (grub_video_bochs_setup: find_card): +Likewise. +* grub-core/video/cirrus.c (grub_video_cirrus_setup: find_card): +Likewise. +* grub-core/video/efi_uga.c (find_framebuf: find_card): Likewise. +* grub-core/video/radeon_fuloong2e.c +(grub_video_radeon_fuloong2e_setup: find_card): Likewise. +* grub-core/video/sis315pro.c (grub_video_sis315pro_setup: +find_card): Likewise. +* grub-core/video/sm712.c (grub_video_sm712_setup: find_card): +Likewise. +--- + ChangeLog | 30 +++++++++ + grub-core/bus/cs5536.c | 45 ++++++++------ + grub-core/bus/emu/pci.c | 4 +- + grub-core/bus/pci.c | 4 +- + grub-core/bus/usb/ehci.c | 7 ++- + grub-core/bus/usb/ohci.c | 8 +-- + grub-core/bus/usb/uhci.c | 7 ++- + grub-core/commands/efi/fixvideo.c | 8 ++- + grub-core/commands/lspci.c | 8 ++- + grub-core/commands/setpci.c | 7 ++- + grub-core/disk/ahci.c | 7 ++- + grub-core/disk/pata.c | 7 ++- + grub-core/kern/efi/mm.c | 53 ++++++++-------- + grub-core/kern/mips/loongson/init.c | 74 +++++++++++----------- + grub-core/kern/vga_init.c | 61 +++++++++--------- + grub-core/video/bochs.c | 46 +++++++------- + grub-core/video/cirrus.c | 46 +++++++------- + grub-core/video/efi_uga.c | 119 ++++++++++++++++++++---------------- + grub-core/video/radeon_fuloong2e.c | 50 ++++++++------- + grub-core/video/sis315pro.c | 60 +++++++++--------- + grub-core/video/sm712.c | 50 ++++++++------- + include/grub/pci.h | 7 ++- + 22 files changed, 396 insertions(+), 312 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index b527f7a..14bff81 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,33 @@ ++2013-01-13 Colin Watson ++ ++ Remove nested functions from PCI iterators. ++ ++ * grub-core/bus/pci.c (grub_pci_iterate): Add hook_data argument, ++ passed to hook. Update all callers to pass appropriate hook data. ++ * grub-core/bus/emu/pci.c (grub_pci_iterate): Likewise. ++ * include/grub/pci.h (grub_pci_iteratefunc_t): Add data argument. ++ Remove NESTED_FUNC_ATTR from here and from all users. ++ (grub_pci_iterate): Update prototype. ++ * grub-core/bus/cs5536.c (grub_cs5536_find: hook): Make static ++ instead of nested. Rename to ... ++ (grub_cs5536_find_iter): ... this. ++ * grub-core/kern/efi/mm.c (stop_broadcom: find_card): Likewise. ++ * grub-core/kern/mips/loongson/init.c (init_pci: set_card): ++ Likewise. ++ * grub-core/kern/vga_init.c (grub_qemu_init_cirrus: find_card): ++ Likewise. ++ * grub-core/video/bochs.c (grub_video_bochs_setup: find_card): ++ Likewise. ++ * grub-core/video/cirrus.c (grub_video_cirrus_setup: find_card): ++ Likewise. ++ * grub-core/video/efi_uga.c (find_framebuf: find_card): Likewise. ++ * grub-core/video/radeon_fuloong2e.c ++ (grub_video_radeon_fuloong2e_setup: find_card): Likewise. ++ * grub-core/video/sis315pro.c (grub_video_sis315pro_setup: ++ find_card): Likewise. ++ * grub-core/video/sm712.c (grub_video_sm712_setup: find_card): ++ Likewise. ++ + 2013-01-12 Vladimir Serbinenko + + * grub-core/commands/verify.c: Mark messages for translating. +diff --git a/grub-core/bus/cs5536.c b/grub-core/bus/cs5536.c +index 9e7796e..bb9aa27 100644 +--- a/grub-core/bus/cs5536.c ++++ b/grub-core/bus/cs5536.c +@@ -29,28 +29,39 @@ + + GRUB_MOD_LICENSE ("GPLv3+"); + ++/* Context for grub_cs5536_find. */ ++struct grub_cs5536_find_ctx ++{ ++ grub_pci_device_t *devp; ++ int found; ++}; ++ ++/* Helper for grub_cs5536_find. */ ++static int ++grub_cs5536_find_iter (grub_pci_device_t dev, grub_pci_id_t pciid, void *data) ++{ ++ struct grub_cs5536_find_ctx *ctx = data; ++ ++ if (pciid == GRUB_CS5536_PCIID) ++ { ++ *ctx->devp = dev; ++ ctx->found = 1; ++ return 1; ++ } ++ return 0; ++} ++ + 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; +- } ++ struct grub_cs5536_find_ctx ctx = { ++ .devp = devp, ++ .found = 0 ++ }; + +- grub_pci_iterate (hook); ++ grub_pci_iterate (grub_cs5536_find_iter, &ctx); + +- return found; ++ return ctx.found; + } + + grub_uint64_t +diff --git a/grub-core/bus/emu/pci.c b/grub-core/bus/emu/pci.c +index d1beb56..9d32963 100644 +--- a/grub-core/bus/emu/pci.c ++++ b/grub-core/bus/emu/pci.c +@@ -32,7 +32,7 @@ grub_pci_make_address (grub_pci_device_t dev, int reg) + } + + void +-grub_pci_iterate (grub_pci_iteratefunc_t hook) ++grub_pci_iterate (grub_pci_iteratefunc_t hook, void *hook_data) + { + struct pci_device_iterator *iter; + struct pci_slot_match slot; +@@ -43,7 +43,7 @@ grub_pci_iterate (grub_pci_iteratefunc_t hook) + slot.func = PCI_MATCH_ANY; + iter = pci_slot_match_iterator_create (&slot); + while ((dev = pci_device_next (iter))) +- hook (dev, dev->vendor_id | (dev->device_id << 16)); ++ hook (dev, dev->vendor_id | (dev->device_id << 16), hook_data); + pci_iterator_destroy (iter); + } + +diff --git a/grub-core/bus/pci.c b/grub-core/bus/pci.c +index 17dea30..b388ce5 100644 +--- a/grub-core/bus/pci.c ++++ b/grub-core/bus/pci.c +@@ -98,7 +98,7 @@ grub_pci_make_address (grub_pci_device_t dev, int reg) + } + + void +-grub_pci_iterate (grub_pci_iteratefunc_t hook) ++grub_pci_iterate (grub_pci_iteratefunc_t hook, void *hook_data) + { + grub_pci_device_t dev; + grub_pci_address_t addr; +@@ -125,7 +125,7 @@ grub_pci_iterate (grub_pci_iteratefunc_t hook) + continue; + } + +- if (hook (dev, id)) ++ if (hook (dev, id, hook_data)) + return; + + /* Probe only func = 0 if the device if not multifunction */ +diff --git a/grub-core/bus/usb/ehci.c b/grub-core/bus/usb/ehci.c +index dc5bf71..b9872b6 100644 +--- a/grub-core/bus/usb/ehci.c ++++ b/grub-core/bus/usb/ehci.c +@@ -454,8 +454,9 @@ grub_ehci_reset (struct grub_ehci *e) + } + + /* PCI iteration function... */ +-static int NESTED_FUNC_ATTR +-grub_ehci_pci_iter (grub_pci_device_t dev, grub_pci_id_t pciid) ++static int ++grub_ehci_pci_iter (grub_pci_device_t dev, grub_pci_id_t pciid, ++ void *data __attribute__ ((unused))) + { + grub_uint8_t release; + grub_uint32_t class_code; +@@ -1814,7 +1815,7 @@ grub_ehci_detect_dev (grub_usb_controller_t dev, int port, int *changed) + static void + grub_ehci_inithw (void) + { +- grub_pci_iterate (grub_ehci_pci_iter); ++ grub_pci_iterate (grub_ehci_pci_iter, NULL); + } + + static grub_err_t +diff --git a/grub-core/bus/usb/ohci.c b/grub-core/bus/usb/ohci.c +index 6fabb4b..b10a9a3 100644 +--- a/grub-core/bus/usb/ohci.c ++++ b/grub-core/bus/usb/ohci.c +@@ -213,9 +213,9 @@ grub_ohci_writereg32 (struct grub_ohci *o, + + /* Iterate over all PCI devices. Determine if a device is an OHCI + 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) ++static int ++grub_ohci_pci_iter (grub_pci_device_t dev, grub_pci_id_t pciid, ++ void *data __attribute__ ((unused))) + { + grub_uint32_t interf; + grub_uint32_t base; +@@ -477,7 +477,7 @@ grub_ohci_pci_iter (grub_pci_device_t dev, + static void + grub_ohci_inithw (void) + { +- grub_pci_iterate (grub_ohci_pci_iter); ++ grub_pci_iterate (grub_ohci_pci_iter, NULL); + } + + +diff --git a/grub-core/bus/usb/uhci.c b/grub-core/bus/usb/uhci.c +index 8f60850..e405b33 100644 +--- a/grub-core/bus/usb/uhci.c ++++ b/grub-core/bus/usb/uhci.c +@@ -185,9 +185,10 @@ grub_uhci_portstatus (grub_usb_controller_t dev, + + /* Iterate over all PCI devices. Determine if a device is an UHCI + controller. If this is the case, initialize it. */ +-static int NESTED_FUNC_ATTR ++static int + grub_uhci_pci_iter (grub_pci_device_t dev, +- grub_pci_id_t pciid __attribute__((unused))) ++ grub_pci_id_t pciid __attribute__((unused)), ++ void *data __attribute__ ((unused))) + { + grub_uint32_t class_code; + grub_uint32_t class; +@@ -351,7 +352,7 @@ grub_uhci_pci_iter (grub_pci_device_t dev, + static void + grub_uhci_inithw (void) + { +- grub_pci_iterate (grub_uhci_pci_iter); ++ grub_pci_iterate (grub_uhci_pci_iter, NULL); + } + + static grub_uhci_td_t +diff --git a/grub-core/commands/efi/fixvideo.c b/grub-core/commands/efi/fixvideo.c +index 3ed40b3..d9d54a2 100644 +--- a/grub-core/commands/efi/fixvideo.c ++++ b/grub-core/commands/efi/fixvideo.c +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -40,8 +41,9 @@ static struct grub_video_patch + {0, 0, 0, 0, 0} + }; + +-static int NESTED_FUNC_ATTR +-scan_card (grub_pci_device_t dev, grub_pci_id_t pciid) ++static int ++scan_card (grub_pci_device_t dev, grub_pci_id_t pciid, ++ void *data __attribute__ ((unused))) + { + grub_pci_address_t addr; + +@@ -93,7 +95,7 @@ grub_cmd_fixvideo (grub_command_t cmd __attribute__ ((unused)), + int argc __attribute__ ((unused)), + char *argv[] __attribute__ ((unused))) + { +- grub_pci_iterate (scan_card); ++ grub_pci_iterate (scan_card, NULL); + return 0; + } + +diff --git a/grub-core/commands/lspci.c b/grub-core/commands/lspci.c +index 9f83629..65213a3 100644 +--- a/grub-core/commands/lspci.c ++++ b/grub-core/commands/lspci.c +@@ -22,6 +22,7 @@ + #include + #include + #include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -126,8 +127,9 @@ static const struct grub_arg_option options[] = + + static int iospace; + +-static int NESTED_FUNC_ATTR +-grub_lspci_iter (grub_pci_device_t dev, grub_pci_id_t pciid) ++static int ++grub_lspci_iter (grub_pci_device_t dev, grub_pci_id_t pciid, ++ void *data __attribute__ ((unused))) + { + grub_uint32_t class; + const char *sclass; +@@ -218,7 +220,7 @@ grub_cmd_lspci (grub_extcmd_context_t ctxt, + char **args __attribute__ ((unused))) + { + iospace = ctxt->state[0].set; +- grub_pci_iterate (grub_lspci_iter); ++ grub_pci_iterate (grub_lspci_iter, NULL); + return GRUB_ERR_NONE; + } + +diff --git a/grub-core/commands/setpci.c b/grub-core/commands/setpci.c +index fcfec40..6fdf0e0 100644 +--- a/grub-core/commands/setpci.c ++++ b/grub-core/commands/setpci.c +@@ -83,8 +83,9 @@ 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) ++static int ++grub_setpci_iter (grub_pci_device_t dev, grub_pci_id_t pciid, ++ void *data __attribute__ ((unused))) + { + grub_uint32_t regval = 0; + grub_pci_address_t addr; +@@ -320,7 +321,7 @@ grub_cmd_setpci (grub_extcmd_context_t ctxt, int argc, char **argv) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "option -v isn't valid for writes"); + +- grub_pci_iterate (grub_setpci_iter); ++ grub_pci_iterate (grub_setpci_iter, NULL); + return GRUB_ERR_NONE; + } + +diff --git a/grub-core/disk/ahci.c b/grub-core/disk/ahci.c +index 4ab2d18..f229ff1 100644 +--- a/grub-core/disk/ahci.c ++++ b/grub-core/disk/ahci.c +@@ -254,9 +254,10 @@ init_port (struct grub_ahci_device *dev) + return 1; + } + +-static int NESTED_FUNC_ATTR ++static int + grub_ahci_pciinit (grub_pci_device_t dev, +- grub_pci_id_t pciid __attribute__ ((unused))) ++ grub_pci_id_t pciid __attribute__ ((unused)), ++ void *data __attribute__ ((unused))) + { + grub_pci_address_t addr; + grub_uint32_t class; +@@ -394,7 +395,7 @@ grub_ahci_pciinit (grub_pci_device_t dev, + static grub_err_t + grub_ahci_initialize (void) + { +- grub_pci_iterate (grub_ahci_pciinit); ++ grub_pci_iterate (grub_ahci_pciinit, NULL); + return grub_errno; + } + +diff --git a/grub-core/disk/pata.c b/grub-core/disk/pata.c +index 00b04e2..07c3d7f 100644 +--- a/grub-core/disk/pata.c ++++ b/grub-core/disk/pata.c +@@ -338,9 +338,10 @@ grub_pata_device_initialize (int port, int device, int addr) + } + + #ifndef GRUB_MACHINE_MIPS_QEMU_MIPS +-static int NESTED_FUNC_ATTR ++static int + grub_pata_pciinit (grub_pci_device_t dev, +- grub_pci_id_t pciid) ++ grub_pci_id_t pciid, ++ void *data __attribute__ ((unused))) + { + static int compat_use[2] = { 0 }; + grub_pci_address_t addr; +@@ -446,7 +447,7 @@ grub_pata_pciinit (grub_pci_device_t dev, + static grub_err_t + grub_pata_initialize (void) + { +- grub_pci_iterate (grub_pata_pciinit); ++ grub_pci_iterate (grub_pata_pciinit, NULL); + return 0; + } + #else +diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c +index a2edc84..351317b 100644 +--- a/grub-core/kern/efi/mm.c ++++ b/grub-core/kern/efi/mm.c +@@ -109,37 +109,36 @@ grub_efi_free_pages (grub_efi_physical_address_t address, + + #if defined (__i386__) || defined (__x86_64__) + +-static void +-stop_broadcom (void) ++/* Helper for stop_broadcom. */ ++static int ++find_card (grub_pci_device_t dev, grub_pci_id_t pciid, ++ void *data __attribute__ ((unused))) + { +- auto int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, +- grub_pci_id_t pciid); +- +- int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, +- grub_pci_id_t pciid) +- { +- grub_pci_address_t addr; +- grub_uint8_t cap; +- grub_uint16_t pm_state; ++ grub_pci_address_t addr; ++ grub_uint8_t cap; ++ grub_uint16_t pm_state; + +- if ((pciid & 0xffff) != GRUB_PCI_VENDOR_BROADCOM) +- return 0; ++ if ((pciid & 0xffff) != GRUB_PCI_VENDOR_BROADCOM) ++ return 0; + +- addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); +- if (grub_pci_read (addr) >> 24 != GRUB_PCI_CLASS_NETWORK) +- return 0; +- cap = grub_pci_find_capability (dev, GRUB_PCI_CAP_POWER_MANAGEMENT); +- if (!cap) +- return 0; +- addr = grub_pci_make_address (dev, cap + 4); +- pm_state = grub_pci_read_word (addr); +- pm_state = pm_state | 0x03; +- grub_pci_write_word (addr, pm_state); +- grub_pci_read_word (addr); +- return 0; +- } ++ addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); ++ if (grub_pci_read (addr) >> 24 != GRUB_PCI_CLASS_NETWORK) ++ return 0; ++ cap = grub_pci_find_capability (dev, GRUB_PCI_CAP_POWER_MANAGEMENT); ++ if (!cap) ++ return 0; ++ addr = grub_pci_make_address (dev, cap + 4); ++ pm_state = grub_pci_read_word (addr); ++ pm_state = pm_state | 0x03; ++ grub_pci_write_word (addr, pm_state); ++ grub_pci_read_word (addr); ++ return 0; ++} + +- grub_pci_iterate (find_card); ++static void ++stop_broadcom (void) ++{ ++ grub_pci_iterate (find_card, NULL); + } + + #endif +diff --git a/grub-core/kern/mips/loongson/init.c b/grub-core/kern/mips/loongson/init.c +index 19f2d63..2109a67 100644 +--- a/grub-core/kern/mips/loongson/init.c ++++ b/grub-core/kern/mips/loongson/init.c +@@ -49,45 +49,47 @@ grub_machine_mmap_iterate (grub_memory_hook_t hook) + return GRUB_ERR_NONE; + } + +-static void +-init_pci (void) ++/* Helper for init_pci. */ ++static int ++set_card (grub_pci_device_t dev, grub_pci_id_t pciid, ++ void *data __attribute__ ((unused))) + { +- auto int NESTED_FUNC_ATTR set_card (grub_pci_device_t dev, grub_pci_id_t pciid); +- int NESTED_FUNC_ATTR set_card (grub_pci_device_t dev, grub_pci_id_t pciid) +- { +- grub_pci_address_t addr; +- /* FIXME: autoscan for BARs and devices. */ +- switch (pciid) +- { +- case GRUB_LOONGSON_OHCI_PCIID: +- addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); +- grub_pci_write (addr, 0x5025000); +- addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND); +- grub_pci_write_word (addr, GRUB_PCI_COMMAND_SERR_ENABLE +- | GRUB_PCI_COMMAND_PARITY_ERROR +- | GRUB_PCI_COMMAND_BUS_MASTER +- | GRUB_PCI_COMMAND_MEM_ENABLED); ++ grub_pci_address_t addr; ++ /* FIXME: autoscan for BARs and devices. */ ++ switch (pciid) ++ { ++ case GRUB_LOONGSON_OHCI_PCIID: ++ addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); ++ grub_pci_write (addr, 0x5025000); ++ addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND); ++ grub_pci_write_word (addr, GRUB_PCI_COMMAND_SERR_ENABLE ++ | GRUB_PCI_COMMAND_PARITY_ERROR ++ | GRUB_PCI_COMMAND_BUS_MASTER ++ | GRUB_PCI_COMMAND_MEM_ENABLED); + +- addr = grub_pci_make_address (dev, GRUB_PCI_REG_STATUS); +- grub_pci_write_word (addr, 0x0200 | GRUB_PCI_STATUS_CAPABILITIES); +- break; +- case GRUB_LOONGSON_EHCI_PCIID: +- addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); +- grub_pci_write (addr, 0x5026000); +- addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND); +- grub_pci_write_word (addr, GRUB_PCI_COMMAND_SERR_ENABLE +- | GRUB_PCI_COMMAND_PARITY_ERROR +- | GRUB_PCI_COMMAND_BUS_MASTER +- | GRUB_PCI_COMMAND_MEM_ENABLED); ++ addr = grub_pci_make_address (dev, GRUB_PCI_REG_STATUS); ++ grub_pci_write_word (addr, 0x0200 | GRUB_PCI_STATUS_CAPABILITIES); ++ break; ++ case GRUB_LOONGSON_EHCI_PCIID: ++ addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); ++ grub_pci_write (addr, 0x5026000); ++ addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND); ++ grub_pci_write_word (addr, GRUB_PCI_COMMAND_SERR_ENABLE ++ | GRUB_PCI_COMMAND_PARITY_ERROR ++ | GRUB_PCI_COMMAND_BUS_MASTER ++ | GRUB_PCI_COMMAND_MEM_ENABLED); + +- addr = grub_pci_make_address (dev, GRUB_PCI_REG_STATUS); +- grub_pci_write_word (addr, (1 << GRUB_PCI_STATUS_DEVSEL_TIMING_SHIFT) +- | GRUB_PCI_STATUS_CAPABILITIES); +- break; +- } +- return 0; +- } ++ addr = grub_pci_make_address (dev, GRUB_PCI_REG_STATUS); ++ grub_pci_write_word (addr, (1 << GRUB_PCI_STATUS_DEVSEL_TIMING_SHIFT) ++ | GRUB_PCI_STATUS_CAPABILITIES); ++ break; ++ } ++ return 0; ++} + ++static void ++init_pci (void) ++{ + *((volatile grub_uint32_t *) GRUB_CPU_LOONGSON_PCI_HIT1_SEL_LO) = 0x8000000c; + *((volatile grub_uint32_t *) GRUB_CPU_LOONGSON_PCI_HIT1_SEL_HI) = 0xffffffff; + +@@ -110,7 +112,7 @@ init_pci (void) + *((volatile grub_uint32_t *) (GRUB_MACHINE_PCI_CONTROLLER_HEADER + + GRUB_PCI_REG_ADDRESS_REG1)) = 0; + +- grub_pci_iterate (set_card); ++ grub_pci_iterate (set_card, NULL); + } + + void +diff --git a/grub-core/kern/vga_init.c b/grub-core/kern/vga_init.c +index 889d012..1119bb3 100644 +--- a/grub-core/kern/vga_init.c ++++ b/grub-core/kern/vga_init.c +@@ -18,6 +18,7 @@ + + #ifndef __mips__ + #include ++#include + #endif + #include + #include +@@ -87,38 +88,42 @@ load_palette (void) + grub_vga_palette_write (i, colors[i].r, colors[i].g, colors[i].b); + } + ++#ifndef __mips__ ++/* Helper for grub_qemu_init_cirrus. */ ++static int ++find_card (grub_pci_device_t dev, grub_pci_id_t pciid __attribute__ ((unused)), ++ void *data __attribute__ ((unused))) ++{ ++ grub_pci_address_t addr; ++ grub_uint32_t class; ++ ++ addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); ++ class = grub_pci_read (addr); ++ ++ if (((class >> 16) & 0xffff) != GRUB_PCI_CLASS_SUBCLASS_VGA) ++ return 0; ++ ++ /* FIXME: chooose addresses dynamically. */ ++ addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); ++ grub_pci_write (addr, 0xf0000000 | GRUB_PCI_ADDR_MEM_PREFETCH ++ | GRUB_PCI_ADDR_SPACE_MEMORY | GRUB_PCI_ADDR_MEM_TYPE_32); ++ addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG1); ++ grub_pci_write (addr, 0xf2000000 ++ | GRUB_PCI_ADDR_SPACE_MEMORY | GRUB_PCI_ADDR_MEM_TYPE_32); ++ ++ addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND); ++ grub_pci_write (addr, GRUB_PCI_COMMAND_MEM_ENABLED ++ | GRUB_PCI_COMMAND_IO_ENABLED); ++ ++ return 1; ++} ++#endif ++ + void + grub_qemu_init_cirrus (void) + { + #ifndef __mips__ +- auto int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid); +- 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, GRUB_PCI_REG_CLASS); +- class = grub_pci_read (addr); +- +- if (((class >> 16) & 0xffff) != GRUB_PCI_CLASS_SUBCLASS_VGA) +- return 0; +- +- /* FIXME: chooose addresses dynamically. */ +- addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); +- grub_pci_write (addr, 0xf0000000 | GRUB_PCI_ADDR_MEM_PREFETCH +- | GRUB_PCI_ADDR_SPACE_MEMORY | GRUB_PCI_ADDR_MEM_TYPE_32); +- addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG1); +- grub_pci_write (addr, 0xf2000000 +- | GRUB_PCI_ADDR_SPACE_MEMORY | GRUB_PCI_ADDR_MEM_TYPE_32); +- +- addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND); +- grub_pci_write (addr, GRUB_PCI_COMMAND_MEM_ENABLED +- | GRUB_PCI_COMMAND_IO_ENABLED); +- +- return 1; +- } +- +- grub_pci_iterate (find_card); ++ grub_pci_iterate (find_card, NULL); + #endif + + grub_outb (GRUB_VGA_IO_MISC_COLOR, +diff --git a/grub-core/video/bochs.c b/grub-core/video/bochs.c +index f6db137..aea486c 100644 +--- a/grub-core/video/bochs.c ++++ b/grub-core/video/bochs.c +@@ -199,6 +199,29 @@ grub_video_bochs_set_palette (unsigned int start, unsigned int count, + return grub_video_fb_set_palette (start, count, palette_data); + } + ++/* Helper for grub_video_bochs_setup. */ ++static int ++find_card (grub_pci_device_t dev, grub_pci_id_t pciid, void *data) ++{ ++ int *found = data; ++ grub_pci_address_t addr; ++ grub_uint32_t class; ++ ++ addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); ++ class = grub_pci_read (addr); ++ ++ if (((class >> 16) & 0xffff) != 0x0300 || pciid != 0x11111234) ++ return 0; ++ ++ *found = 1; ++ ++ addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); ++ framebuffer.base = grub_pci_read (addr) & GRUB_PCI_ADDR_MEM_MASK; ++ framebuffer.dev = dev; ++ ++ return 1; ++} ++ + static grub_err_t + grub_video_bochs_setup (unsigned int width, unsigned int height, + grub_video_mode_type_t mode_type, +@@ -210,27 +233,6 @@ grub_video_bochs_setup (unsigned int width, unsigned int height, + int pitch, bytes_per_pixel; + grub_size_t page_size; /* The size of a page in bytes. */ + +- auto int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid); +- int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid) +- { +- grub_pci_address_t addr; +- grub_uint32_t class; +- +- addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); +- class = grub_pci_read (addr); +- +- if (((class >> 16) & 0xffff) != 0x0300 || pciid != 0x11111234) +- return 0; +- +- found = 1; +- +- addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); +- framebuffer.base = grub_pci_read (addr) & GRUB_PCI_ADDR_MEM_MASK; +- 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) + >> GRUB_VIDEO_MODE_TYPE_DEPTH_POS; +@@ -280,7 +282,7 @@ grub_video_bochs_setup (unsigned int width, unsigned int height, + if (page_size > BOCHS_APERTURE_SIZE) + return grub_error (GRUB_ERR_IO, "Not enough video memory for this mode"); + +- grub_pci_iterate (find_card); ++ grub_pci_iterate (find_card, &found); + if (!found) + return grub_error (GRUB_ERR_IO, "Couldn't find graphics card"); + +diff --git a/grub-core/video/cirrus.c b/grub-core/video/cirrus.c +index e711119..073c54e 100644 +--- a/grub-core/video/cirrus.c ++++ b/grub-core/video/cirrus.c +@@ -235,6 +235,29 @@ grub_video_cirrus_set_palette (unsigned int start, unsigned int count, + return grub_video_fb_set_palette (start, count, palette_data); + } + ++/* Helper for grub_video_cirrus_setup. */ ++static int ++find_card (grub_pci_device_t dev, grub_pci_id_t pciid, void *data) ++{ ++ int *found = data; ++ grub_pci_address_t addr; ++ grub_uint32_t class; ++ ++ addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); ++ class = grub_pci_read (addr); ++ ++ if (((class >> 16) & 0xffff) != 0x0300 || pciid != 0x00b81013) ++ return 0; ++ ++ *found = 1; ++ ++ addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); ++ framebuffer.base = grub_pci_read (addr) & GRUB_PCI_ADDR_MEM_MASK; ++ framebuffer.dev = dev; ++ ++ return 1; ++} ++ + static grub_err_t + grub_video_cirrus_setup (unsigned int width, unsigned int height, + grub_video_mode_type_t mode_type, +@@ -245,27 +268,6 @@ grub_video_cirrus_setup (unsigned int width, unsigned int height, + int found = 0; + int pitch, bytes_per_pixel; + +- auto int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid); +- int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid) +- { +- grub_pci_address_t addr; +- grub_uint32_t class; +- +- addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); +- class = grub_pci_read (addr); +- +- if (((class >> 16) & 0xffff) != 0x0300 || pciid != 0x00b81013) +- return 0; +- +- found = 1; +- +- addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); +- framebuffer.base = grub_pci_read (addr) & GRUB_PCI_ADDR_MEM_MASK; +- 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) + >> GRUB_VIDEO_MODE_TYPE_DEPTH_POS; +@@ -314,7 +316,7 @@ grub_video_cirrus_setup (unsigned int width, unsigned int height, + if (framebuffer.page_size > CIRRUS_APERTURE_SIZE) + return grub_error (GRUB_ERR_IO, "Not enough video memory for this mode"); + +- grub_pci_iterate (find_card); ++ grub_pci_iterate (find_card, &found); + if (!found) + return grub_error (GRUB_ERR_IO, "Couldn't find graphics card"); + +diff --git a/grub-core/video/efi_uga.c b/grub-core/video/efi_uga.c +index 016adbb..695f015 100644 +--- a/grub-core/video/efi_uga.c ++++ b/grub-core/video/efi_uga.c +@@ -81,77 +81,88 @@ find_line_len (grub_uint32_t *fb_base, grub_uint32_t *line_len) + return 0; + } + +-static int +-find_framebuf (grub_uint32_t *fb_base, grub_uint32_t *line_len) ++/* Context for find_framebuf. */ ++struct find_framebuf_ctx + { +- int found = 0; ++ grub_uint32_t *fb_base; ++ grub_uint32_t *line_len; ++ int found; ++}; + +- auto int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, +- grub_pci_id_t pciid); ++/* Helper for find_framebuf. */ ++static int ++find_card (grub_pci_device_t dev, grub_pci_id_t pciid, void *data) ++{ ++ struct find_framebuf_ctx *ctx = data; ++ grub_pci_address_t addr; + +- int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, +- grub_pci_id_t pciid) ++ addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); ++ if (grub_pci_read (addr) >> 24 == 0x3) + { +- grub_pci_address_t addr; ++ int i; + +- addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); +- if (grub_pci_read (addr) >> 24 == 0x3) ++ grub_dprintf ("fb", "Display controller: %d:%d.%d\nDevice id: %x\n", ++ grub_pci_get_bus (dev), grub_pci_get_device (dev), ++ grub_pci_get_function (dev), pciid); ++ addr += 8; ++ for (i = 0; i < 6; i++, addr += 4) + { +- int i; +- +- grub_dprintf ("fb", "Display controller: %d:%d.%d\nDevice id: %x\n", +- grub_pci_get_bus (dev), grub_pci_get_device (dev), +- grub_pci_get_function (dev), pciid); +- addr += 8; +- for (i = 0; i < 6; i++, addr += 4) +- { +- grub_uint32_t old_bar1, old_bar2, type; +- grub_uint64_t base64; ++ grub_uint32_t old_bar1, old_bar2, type; ++ grub_uint64_t base64; + +- old_bar1 = grub_pci_read (addr); +- if ((! old_bar1) || (old_bar1 & GRUB_PCI_ADDR_SPACE_IO)) +- continue; ++ old_bar1 = grub_pci_read (addr); ++ if ((! old_bar1) || (old_bar1 & GRUB_PCI_ADDR_SPACE_IO)) ++ continue; + +- type = old_bar1 & GRUB_PCI_ADDR_MEM_TYPE_MASK; +- if (type == GRUB_PCI_ADDR_MEM_TYPE_64) +- { +- if (i == 5) +- break; ++ type = old_bar1 & GRUB_PCI_ADDR_MEM_TYPE_MASK; ++ if (type == GRUB_PCI_ADDR_MEM_TYPE_64) ++ { ++ if (i == 5) ++ break; + +- old_bar2 = grub_pci_read (addr + 4); +- } +- else +- old_bar2 = 0; ++ old_bar2 = grub_pci_read (addr + 4); ++ } ++ else ++ old_bar2 = 0; + +- base64 = old_bar2; +- base64 <<= 32; +- base64 |= (old_bar1 & GRUB_PCI_ADDR_MEM_MASK); ++ base64 = old_bar2; ++ base64 <<= 32; ++ base64 |= (old_bar1 & GRUB_PCI_ADDR_MEM_MASK); + +- grub_dprintf ("fb", "%s(%d): 0x%llx\n", +- ((old_bar1 & GRUB_PCI_ADDR_MEM_PREFETCH) ? +- "VMEM" : "MMIO"), i, +- (unsigned long long) base64); ++ grub_dprintf ("fb", "%s(%d): 0x%llx\n", ++ ((old_bar1 & GRUB_PCI_ADDR_MEM_PREFETCH) ? ++ "VMEM" : "MMIO"), i, ++ (unsigned long long) base64); + +- if ((old_bar1 & GRUB_PCI_ADDR_MEM_PREFETCH) && (! found)) +- { +- *fb_base = base64; +- if (find_line_len (fb_base, line_len)) +- found++; +- } ++ if ((old_bar1 & GRUB_PCI_ADDR_MEM_PREFETCH) && (! ctx->found)) ++ { ++ *ctx->fb_base = base64; ++ if (find_line_len (ctx->fb_base, ctx->line_len)) ++ ctx->found++; ++ } + +- if (type == GRUB_PCI_ADDR_MEM_TYPE_64) +- { +- i++; +- addr += 4; +- } ++ if (type == GRUB_PCI_ADDR_MEM_TYPE_64) ++ { ++ i++; ++ addr += 4; + } + } +- +- return found; + } + +- grub_pci_iterate (find_card); +- return found; ++ return ctx->found; ++} ++ ++static int ++find_framebuf (grub_uint32_t *fb_base, grub_uint32_t *line_len) ++{ ++ struct find_framebuf_ctx ctx = { ++ .fb_base = fb_base, ++ .line_len = line_len, ++ .found = 0 ++ }; ++ ++ grub_pci_iterate (find_card, &ctx); ++ return ctx.found; + } + + static int +diff --git a/grub-core/video/radeon_fuloong2e.c b/grub-core/video/radeon_fuloong2e.c +index 45a68ed..c3d65f1 100644 +--- a/grub-core/video/radeon_fuloong2e.c ++++ b/grub-core/video/radeon_fuloong2e.c +@@ -60,6 +60,32 @@ grub_video_radeon_fuloong2e_video_fini (void) + return grub_video_fb_fini (); + } + ++#ifndef TEST ++/* Helper for grub_video_radeon_fuloong2e_setup. */ ++static int ++find_card (grub_pci_device_t dev, grub_pci_id_t pciid, void *data) ++{ ++ int *found = data; ++ grub_pci_address_t addr; ++ grub_uint32_t class; ++ ++ addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); ++ class = grub_pci_read (addr); ++ ++ if (((class >> 16) & 0xffff) != GRUB_PCI_CLASS_SUBCLASS_VGA ++ || pciid != 0x515a1002) ++ return 0; ++ ++ *found = 1; ++ ++ addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); ++ framebuffer.base = grub_pci_read (addr); ++ framebuffer.dev = dev; ++ ++ return 1; ++} ++#endif ++ + static grub_err_t + grub_video_radeon_fuloong2e_setup (unsigned int width, unsigned int height, + unsigned int mode_type, unsigned int mode_mask __attribute__ ((unused))) +@@ -69,28 +95,6 @@ grub_video_radeon_fuloong2e_setup (unsigned int width, unsigned int height, + int found = 0; + + #ifndef TEST +- auto int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid); +- int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid) +- { +- grub_pci_address_t addr; +- grub_uint32_t class; +- +- addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); +- class = grub_pci_read (addr); +- +- if (((class >> 16) & 0xffff) != GRUB_PCI_CLASS_SUBCLASS_VGA +- || pciid != 0x515a1002) +- return 0; +- +- found = 1; +- +- addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); +- 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) + >> GRUB_VIDEO_MODE_TYPE_DEPTH_POS; +@@ -100,7 +104,7 @@ grub_video_radeon_fuloong2e_setup (unsigned int width, unsigned int height, + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "Only 640x480x16 is supported"); + +- grub_pci_iterate (find_card); ++ grub_pci_iterate (find_card, &found); + if (!found) + return grub_error (GRUB_ERR_IO, "Couldn't find graphics card"); + #endif +diff --git a/grub-core/video/sis315pro.c b/grub-core/video/sis315pro.c +index d213877..a986669 100644 +--- a/grub-core/video/sis315pro.c ++++ b/grub-core/video/sis315pro.c +@@ -88,6 +88,37 @@ grub_video_sis315pro_video_fini (void) + + #include "sis315_init.c" + ++#ifndef TEST ++/* Helper for grub_video_sis315pro_setup. */ ++static int ++find_card (grub_pci_device_t dev, grub_pci_id_t pciid, void *data) ++{ ++ int *found = data; ++ grub_pci_address_t addr; ++ grub_uint32_t class; ++ ++ addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); ++ class = grub_pci_read (addr); ++ ++ if (((class >> 16) & 0xffff) != GRUB_PCI_CLASS_SUBCLASS_VGA ++ || pciid != GRUB_SIS315PRO_PCIID) ++ return 0; ++ ++ *found = 1; ++ ++ addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); ++ framebuffer.base = grub_pci_read (addr) & GRUB_PCI_ADDR_MEM_MASK; ++ addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG1); ++ framebuffer.mmiobase = grub_pci_read (addr) & GRUB_PCI_ADDR_MEM_MASK; ++ addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG2); ++ framebuffer.io = (grub_pci_read (addr) & GRUB_PCI_ADDR_IO_MASK) ++ + GRUB_MACHINE_PCI_IO_BASE; ++ framebuffer.dev = dev; ++ ++ return 1; ++} ++#endif ++ + static grub_err_t + grub_video_sis315pro_setup (unsigned int width, unsigned int height, + unsigned int mode_type, +@@ -99,33 +130,6 @@ grub_video_sis315pro_setup (unsigned int width, unsigned int height, + unsigned i; + + #ifndef TEST +- auto int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid); +- int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid) +- { +- grub_pci_address_t addr; +- grub_uint32_t class; +- +- addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); +- class = grub_pci_read (addr); +- +- if (((class >> 16) & 0xffff) != GRUB_PCI_CLASS_SUBCLASS_VGA +- || pciid != GRUB_SIS315PRO_PCIID) +- return 0; +- +- found = 1; +- +- addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); +- framebuffer.base = grub_pci_read (addr) & GRUB_PCI_ADDR_MEM_MASK; +- addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG1); +- framebuffer.mmiobase = grub_pci_read (addr) & GRUB_PCI_ADDR_MEM_MASK; +- addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG2); +- framebuffer.io = (grub_pci_read (addr) & GRUB_PCI_ADDR_IO_MASK) +- + GRUB_MACHINE_PCI_IO_BASE; +- 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) + >> GRUB_VIDEO_MODE_TYPE_DEPTH_POS; +@@ -135,7 +139,7 @@ grub_video_sis315pro_setup (unsigned int width, unsigned int height, + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "Only 640x480x8 is supported"); + +- grub_pci_iterate (find_card); ++ grub_pci_iterate (find_card, &found); + if (!found) + return grub_error (GRUB_ERR_IO, "Couldn't find graphics card"); + #endif +diff --git a/grub-core/video/sm712.c b/grub-core/video/sm712.c +index d780983..fb40d64 100644 +--- a/grub-core/video/sm712.c ++++ b/grub-core/video/sm712.c +@@ -360,6 +360,32 @@ grub_sm712_write_dda_lookup (int idx, grub_uint8_t compare, grub_uint16_t dda, + GRUB_SM712_CR_DDA_LOOKUP_REG1_START + idx); + } + ++#if !defined (TEST) && !defined(GENINIT) ++/* Helper for grub_video_sm712_setup. */ ++static int ++find_card (grub_pci_device_t dev, grub_pci_id_t pciid, void *data) ++{ ++ int *found = data; ++ grub_pci_address_t addr; ++ grub_uint32_t class; ++ ++ addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); ++ class = grub_pci_read (addr); ++ ++ if (((class >> 16) & 0xffff) != GRUB_PCI_CLASS_SUBCLASS_VGA ++ || pciid != GRUB_SM712_PCIID) ++ return 0; ++ ++ *found = 1; ++ ++ addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); ++ framebuffer.base = grub_pci_read (addr); ++ framebuffer.dev = dev; ++ ++ return 1; ++} ++#endif ++ + static grub_err_t + grub_video_sm712_setup (unsigned int width, unsigned int height, + unsigned int mode_type, unsigned int mode_mask __attribute__ ((unused))) +@@ -370,28 +396,6 @@ 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); +- int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid) +- { +- grub_pci_address_t addr; +- grub_uint32_t class; +- +- addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); +- class = grub_pci_read (addr); +- +- if (((class >> 16) & 0xffff) != GRUB_PCI_CLASS_SUBCLASS_VGA +- || pciid != GRUB_SM712_PCIID) +- return 0; +- +- found = 1; +- +- addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); +- 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) + >> GRUB_VIDEO_MODE_TYPE_DEPTH_POS; +@@ -401,7 +405,7 @@ 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); ++ grub_pci_iterate (find_card, &found); + if (!found) + return grub_error (GRUB_ERR_IO, "Couldn't find graphics card"); + /* Fill mode info details. */ +diff --git a/include/grub/pci.h b/include/grub/pci.h +index aaf0101..e163d47 100644 +--- a/include/grub/pci.h ++++ b/include/grub/pci.h +@@ -132,13 +132,14 @@ grub_pci_get_function (grub_pci_device_t dev) + #include + #endif + +-typedef int NESTED_FUNC_ATTR (*grub_pci_iteratefunc_t) +- (grub_pci_device_t dev, grub_pci_id_t pciid); ++typedef int (*grub_pci_iteratefunc_t) ++ (grub_pci_device_t dev, grub_pci_id_t pciid, void *data); + + grub_pci_address_t EXPORT_FUNC(grub_pci_make_address) (grub_pci_device_t dev, + int reg); + +-void EXPORT_FUNC(grub_pci_iterate) (grub_pci_iteratefunc_t hook); ++void EXPORT_FUNC(grub_pci_iterate) (grub_pci_iteratefunc_t hook, ++ void *hook_data); + + struct grub_pci_dma_chunk; + +-- +1.8.1.4 + diff --git a/0102-util-grub-mkimage.c-generate_image-Fix-size-of-publi.patch b/0102-util-grub-mkimage.c-generate_image-Fix-size-of-publi.patch new file mode 100644 index 0000000..4aba9d6 --- /dev/null +++ b/0102-util-grub-mkimage.c-generate_image-Fix-size-of-publi.patch @@ -0,0 +1,44 @@ +From e482ffb0dcaa5a0b5d69aeaa178ece164cf9ba8c Mon Sep 17 00:00:00 2001 +From: Colin Watson +Date: Sun, 13 Jan 2013 01:47:46 +0000 +Subject: [PATCH 102/364] * util/grub-mkimage.c (generate_image): Fix "size of + public key" info message. + +--- + ChangeLog | 5 +++++ + util/grub-mkimage.c | 4 ++-- + 2 files changed, 7 insertions(+), 2 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 14bff81..784d737 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,10 @@ + 2013-01-13 Colin Watson + ++ * util/grub-mkimage.c (generate_image): Fix "size of public key" ++ info message. ++ ++2013-01-13 Colin Watson ++ + Remove nested functions from PCI iterators. + + * grub-core/bus/pci.c (grub_pci_iterate): Add hook_data argument, +diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c +index 23a9970..d0eecf2 100644 +--- a/util/grub-mkimage.c ++++ b/util/grub-mkimage.c +@@ -740,8 +740,8 @@ generate_image (const char *dir, const char *prefix, + { + size_t curs; + curs = ALIGN_ADDR (grub_util_get_image_size (pubkey_paths[i])); +- grub_util_info ("the size of public key is 0x%llx", +- (unsigned long long) pubkey_paths[i]); ++ grub_util_info ("the size of public key %zd is 0x%llx", ++ i, (unsigned long long) curs); + total_module_size += curs + sizeof (struct grub_module_header); + } + } +-- +1.8.1.4 + diff --git a/0103-New-command-list_trusted.patch b/0103-New-command-list_trusted.patch new file mode 100644 index 0000000..eaa43de --- /dev/null +++ b/0103-New-command-list_trusted.patch @@ -0,0 +1,97 @@ +From 350332f3a15fa7968366cea163a1c88753af80ac Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sun, 13 Jan 2013 17:49:05 +0100 +Subject: [PATCH 103/364] New command list_trusted. + + * grub-core/commands/verify.c (grub_cmd_list): New function. +--- + ChangeLog | 6 ++++++ + grub-core/commands/verify.c | 31 ++++++++++++++++++++++++++----- + 2 files changed, 32 insertions(+), 5 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 784d737..6bb855b 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,9 @@ ++2013-01-13 Vladimir Serbinenko ++ ++ New command list_trusted. ++ ++ * grub-core/commands/verify.c (grub_cmd_list): New function. ++ + 2013-01-13 Colin Watson + + * util/grub-mkimage.c (generate_image): Fix "size of public key" +diff --git a/grub-core/commands/verify.c b/grub-core/commands/verify.c +index 66a027f..d399d0f 100644 +--- a/grub-core/commands/verify.c ++++ b/grub-core/commands/verify.c +@@ -298,10 +298,6 @@ grub_load_public_key (grub_file_t f) + *last = sk; + last = &sk->next; + +- for (i = 0; i < 20; i += 2) +- grub_printf ("%02x%02x ", ((grub_uint8_t *) sk->fingerprint)[i], ((grub_uint8_t *) sk->fingerprint)[i + 1]); +- grub_printf ("\n"); +- + grub_dprintf ("crypt", "actual pos: %x, expected: %x\n", (int)grub_file_tell (f), (int)pend); + + grub_file_seek (f, pend); +@@ -557,6 +553,27 @@ grub_cmd_trust (grub_command_t cmd __attribute__ ((unused)), + } + + static grub_err_t ++grub_cmd_list (grub_command_t cmd __attribute__ ((unused)), ++ int argc __attribute__ ((unused)), ++ char **args __attribute__ ((unused))) ++{ ++ struct grub_public_key *pk = NULL; ++ struct grub_public_subkey *sk = NULL; ++ ++ for (pk = grub_pk_trusted; pk; pk = pk->next) ++ for (sk = pk->subkeys; sk; sk = sk->next) ++ { ++ unsigned i; ++ for (i = 0; i < 20; i += 2) ++ grub_printf ("%02x%02x ", ((grub_uint8_t *) sk->fingerprint)[i], ++ ((grub_uint8_t *) sk->fingerprint)[i + 1]); ++ grub_printf ("\n"); ++ } ++ ++ return GRUB_ERR_NONE; ++} ++ ++static grub_err_t + grub_cmd_distrust (grub_command_t cmd __attribute__ ((unused)), + int argc, char **args) + { +@@ -701,7 +718,7 @@ struct gcry_pk_spec *grub_crypto_pk_dsa; + struct gcry_pk_spec *grub_crypto_pk_ecdsa; + struct gcry_pk_spec *grub_crypto_pk_rsa; + +-static grub_command_t cmd, cmd_trust, cmd_distrust; ++static grub_command_t cmd, cmd_trust, cmd_distrust, cmd_list; + + GRUB_MOD_INIT(verify) + { +@@ -752,6 +769,9 @@ GRUB_MOD_INIT(verify) + cmd_trust = grub_register_command ("trust", grub_cmd_trust, + N_("PUBKEY_FILE"), + N_("Add PKFILE to trusted keys.")); ++ cmd_list = grub_register_command ("list_trusted", grub_cmd_list, ++ 0, ++ N_("List trusted keys.")); + cmd_distrust = grub_register_command ("distrust", grub_cmd_distrust, + N_("PUBKEY_ID"), + N_("Remove KEYID from trusted keys.")); +@@ -762,5 +782,6 @@ GRUB_MOD_FINI(verify) + grub_file_filter_unregister (GRUB_FILE_FILTER_PUBKEY); + grub_unregister_command (cmd); + grub_unregister_command (cmd_trust); ++ grub_unregister_command (cmd_list); + grub_unregister_command (cmd_distrust); + } +-- +1.8.1.4 + diff --git a/0104-Fix-compilation-with-older-compilers.patch b/0104-Fix-compilation-with-older-compilers.patch new file mode 100644 index 0000000..252ebbb --- /dev/null +++ b/0104-Fix-compilation-with-older-compilers.patch @@ -0,0 +1,208 @@ +From 6ac2ef1dc40513b7c2eb2e0d3026e6d6d86cae1d Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sun, 13 Jan 2013 21:06:25 +0100 +Subject: [PATCH 104/364] Fix compilation with older compilers. + + * grub-core/Makefile.core.def (mpi): Add mpi-inline.c. + * grub-core/lib/libgcrypt_wrap/cipher_wrap.h: Remove redundant + declarations. + * grub-core/lib/posix_wrap/string.h: Include sys/types.h. + * grub-core/lib/posix_wrap/sys/types.h: Add common types. + * grub-core/lib/xzembed/xz_dec_lzma2.c (dict_put): Replace byte + identifier with b. + * grub-core/lib/xzembed/xz_dec_stream.c (dec_vli): Likewise. + * include/grub/crypto.h: Add type defines. + * util/import_gcrypth.sed: Remove duplicate type defines. +--- + ChangeLog | 15 +++++++++++++++ + grub-core/Makefile.core.def | 1 + + grub-core/lib/libgcrypt_wrap/cipher_wrap.h | 6 ------ + grub-core/lib/posix_wrap/string.h | 3 ++- + grub-core/lib/posix_wrap/sys/types.h | 6 ++++++ + grub-core/lib/xzembed/xz_dec_lzma2.c | 4 ++-- + grub-core/lib/xzembed/xz_dec_stream.c | 10 +++++----- + include/grub/crypto.h | 8 +++++--- + util/import_gcrypth.sed | 3 +++ + 9 files changed, 39 insertions(+), 17 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 6bb855b..ea90383 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,20 @@ + 2013-01-13 Vladimir Serbinenko + ++ Fix compilation with older compilers. ++ ++ * grub-core/Makefile.core.def (mpi): Add mpi-inline.c. ++ * grub-core/lib/libgcrypt_wrap/cipher_wrap.h: Remove redundant ++ declarations. ++ * grub-core/lib/posix_wrap/string.h: Include sys/types.h. ++ * grub-core/lib/posix_wrap/sys/types.h: Add common types. ++ * grub-core/lib/xzembed/xz_dec_lzma2.c (dict_put): Replace byte ++ identifier with b. ++ * grub-core/lib/xzembed/xz_dec_stream.c (dec_vli): Likewise. ++ * include/grub/crypto.h: Add type defines. ++ * util/import_gcrypth.sed: Remove duplicate type defines. ++ ++2013-01-13 Vladimir Serbinenko ++ + New command list_trusted. + + * grub-core/commands/verify.c (grub_cmd_list): New function. +diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def +index 588e4cd..f4dd645 100644 +--- a/grub-core/Makefile.core.def ++++ b/grub-core/Makefile.core.def +@@ -1874,6 +1874,7 @@ module = { + common = lib/libgcrypt-grub/mpi/mpih-div.c; + common = lib/libgcrypt-grub/mpi/mpicoder.c; + common = lib/libgcrypt-grub/mpi/mpih-rshift.c; ++ common = lib/libgcrypt-grub/mpi/mpi-inline.c; + common = lib/libgcrypt_wrap/mem.c; + + cflags = '$(CFLAGS_GCRY) -Wno-redundant-decls -Wno-sign-compare'; +diff --git a/grub-core/lib/libgcrypt_wrap/cipher_wrap.h b/grub-core/lib/libgcrypt_wrap/cipher_wrap.h +index d7ae274..118b2f1 100644 +--- a/grub-core/lib/libgcrypt_wrap/cipher_wrap.h ++++ b/grub-core/lib/libgcrypt_wrap/cipher_wrap.h +@@ -34,12 +34,6 @@ + #undef __GNU_LIBRARY__ + #define __GNU_LIBRARY__ 1 + +-typedef grub_uint64_t u64; +-typedef grub_uint32_t u32; +-typedef grub_uint16_t u16; +-typedef grub_uint8_t byte; +-typedef grub_size_t size_t; +- + #define U64_C(c) (c ## ULL) + + #define PUBKEY_FLAG_NO_BLINDING (1 << 0) +diff --git a/grub-core/lib/posix_wrap/string.h b/grub-core/lib/posix_wrap/string.h +index 885845b..53ef0a9 100644 +--- a/grub-core/lib/posix_wrap/string.h ++++ b/grub-core/lib/posix_wrap/string.h +@@ -20,6 +20,7 @@ + #define GRUB_POSIX_STRING_H 1 + + #include ++#include + + #define HAVE_STRCASECMP 1 + +@@ -49,7 +50,7 @@ memcpy (void *dest, const void *src, grub_size_t n) + } + + static inline int +-memcmp (const void *s1, const void *s2, size_t n) ++memcmp (const void *s1, const void *s2, grub_size_t n) + { + return grub_memcmp (s1, s2, n); + } +diff --git a/grub-core/lib/posix_wrap/sys/types.h b/grub-core/lib/posix_wrap/sys/types.h +index fe75d8d..62a2672 100644 +--- a/grub-core/lib/posix_wrap/sys/types.h ++++ b/grub-core/lib/posix_wrap/sys/types.h +@@ -44,6 +44,12 @@ typedef grub_int64_t int64_t; + + #define HAVE_U64_TYPEDEF 1 + typedef grub_uint64_t u64; ++#define HAVE_U32_TYPEDEF 1 ++typedef grub_uint32_t u32; ++#define HAVE_U16_TYPEDEF 1 ++typedef grub_uint16_t u16; ++#define HAVE_BYTE_TYPEDEF 1 ++typedef grub_uint8_t byte; + + #define SIZEOF_UNSIGNED_LONG GRUB_CPU_SIZEOF_LONG + #define SIZEOF_UNSIGNED_INT 4 +diff --git a/grub-core/lib/xzembed/xz_dec_lzma2.c b/grub-core/lib/xzembed/xz_dec_lzma2.c +index 7899e9e..4f4fb85 100644 +--- a/grub-core/lib/xzembed/xz_dec_lzma2.c ++++ b/grub-core/lib/xzembed/xz_dec_lzma2.c +@@ -327,9 +327,9 @@ static inline uint32_t dict_get( + /* + * Put one byte into the dictionary. It is assumed that there is space for it. + */ +-static inline void dict_put(struct dictionary *dict, uint8_t byte) ++static inline void dict_put(struct dictionary *dict, uint8_t b) + { +- dict->buf[dict->pos++] = byte; ++ dict->buf[dict->pos++] = b; + + if (dict->full < dict->pos) + dict->full = dict->pos; +diff --git a/grub-core/lib/xzembed/xz_dec_stream.c b/grub-core/lib/xzembed/xz_dec_stream.c +index 6170b0c..f5a86eb 100644 +--- a/grub-core/lib/xzembed/xz_dec_stream.c ++++ b/grub-core/lib/xzembed/xz_dec_stream.c +@@ -197,20 +197,20 @@ static bool fill_temp(struct xz_dec *s, struct xz_buf *b) + static enum xz_ret dec_vli(struct xz_dec *s, + const uint8_t *in, size_t *in_pos, size_t in_size) + { +- uint8_t byte; ++ uint8_t b; + + if (s->pos == 0) + s->vli = 0; + + while (*in_pos < in_size) { +- byte = in[*in_pos]; ++ b = in[*in_pos]; + ++*in_pos; + +- s->vli |= (vli_type)(byte & 0x7F) << s->pos; ++ s->vli |= (vli_type)(b & 0x7F) << s->pos; + +- if ((byte & 0x80) == 0) { ++ if ((b & 0x80) == 0) { + /* Don't allow non-minimal encodings. */ +- if (byte == 0 && s->pos != 0) ++ if (b == 0 && s->pos != 0) + return XZ_DATA_ERROR; + + s->pos = 0; +diff --git a/include/grub/crypto.h b/include/grub/crypto.h +index 557b944..ea2f13e 100644 +--- a/include/grub/crypto.h ++++ b/include/grub/crypto.h +@@ -66,9 +66,10 @@ typedef enum + GPG_ERR_WRONG_PUBKEY_ALGO, + GPG_ERR_OUT_OF_MEMORY, + GPG_ERR_TOO_LARGE +- } gcry_err_code_t; +-#define gpg_err_code_t gcry_err_code_t +-#define gpg_error_t gcry_err_code_t ++ } gpg_err_code_t; ++typedef gpg_err_code_t gpg_error_t; ++typedef gpg_error_t gcry_error_t; ++typedef gpg_err_code_t gcry_err_code_t; + #define gcry_error_t gcry_err_code_t + #if 0 + enum gcry_cipher_modes +@@ -174,6 +175,7 @@ typedef struct gcry_md_spec + struct gcry_md_spec *next; + } gcry_md_spec_t; + ++struct gcry_mpi; + typedef struct gcry_mpi *gcry_mpi_t; + + /* Type for the pk_generate function. */ +diff --git a/util/import_gcrypth.sed b/util/import_gcrypth.sed +index dead8e6..6cb53cf 100644 +--- a/util/import_gcrypth.sed ++++ b/util/import_gcrypth.sed +@@ -8,5 +8,8 @@ + /^# *include / d + /^# *include / d + /^# *include / s,#include ,#include , ++/^typedef gpg_error_t gcry_error_t;/ d ++/^typedef gpg_err_code_t gcry_err_code_t;/ d ++/^typedef struct gcry_mpi \*gcry_mpi_t;/ d + s,_gcry_mpi_invm,gcry_mpi_invm,g + p +\ No newline at end of file +-- +1.8.1.4 + diff --git a/0105-grub-core-kern-emu-hostdisk.c-read_device_map-Explic.patch b/0105-grub-core-kern-emu-hostdisk.c-read_device_map-Explic.patch new file mode 100644 index 0000000..b8bba8e --- /dev/null +++ b/0105-grub-core-kern-emu-hostdisk.c-read_device_map-Explic.patch @@ -0,0 +1,111 @@ +From 423468a725a578a1829dac2278fd68da52843106 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sun, 13 Jan 2013 22:45:16 +0100 +Subject: [PATCH 105/364] * grub-core/kern/emu/hostdisk.c + (read_device_map): Explicitly delimit path in strings using quotes. * + util/getroot.c (grub_guess_root_devices): Likewise. + (grub_make_system_path_relative_to_its_root): Likewise. * + util/grub-probe.c (probe): Likewise. * util/ieee1275/ofpath.c + (find_obppath): Likewise. (xrealpath): Likewise. + +--- + ChangeLog | 10 ++++++++++ + grub-core/kern/emu/hostdisk.c | 2 +- + util/getroot.c | 4 ++-- + util/grub-probe.c | 2 +- + util/ieee1275/ofpath.c | 4 ++-- + 5 files changed, 16 insertions(+), 6 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index ea90383..1c0e633 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,15 @@ + 2013-01-13 Vladimir Serbinenko + ++ * grub-core/kern/emu/hostdisk.c (read_device_map): Explicitly ++ delimit path in strings using quotes. ++ * util/getroot.c (grub_guess_root_devices): Likewise. ++ (grub_make_system_path_relative_to_its_root): Likewise. ++ * util/grub-probe.c (probe): Likewise. ++ * util/ieee1275/ofpath.c (find_obppath): Likewise. ++ (xrealpath): Likewise. ++ ++2013-01-13 Vladimir Serbinenko ++ + Fix compilation with older compilers. + + * grub-core/Makefile.core.def (mpi): Add mpi-inline.c. +diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c +index b8c3766..ccd2417 100644 +--- a/grub-core/kern/emu/hostdisk.c ++++ b/grub-core/kern/emu/hostdisk.c +@@ -1339,7 +1339,7 @@ read_device_map (const char *dev_map) + { + map[drive].device = xmalloc (PATH_MAX); + if (! realpath (p, map[drive].device)) +- grub_util_error (_("failed to get canonical path of %s"), p); ++ grub_util_error (_("failed to get canonical path of `%s'"), p); + } + else + #endif +diff --git a/util/getroot.c b/util/getroot.c +index 24ce6aa..3b5b0f6 100644 +--- a/util/getroot.c ++++ b/util/getroot.c +@@ -1065,7 +1065,7 @@ grub_guess_root_devices (const char *dir) + { + *cur = canonicalize_file_name (tmp); + if (*cur == NULL) +- grub_util_error (_("failed to get canonical path of %s"), tmp); ++ grub_util_error (_("failed to get canonical path of `%s'"), tmp); + free (tmp); + } + root = (strcmp (*cur, "/dev/root") == 0); +@@ -2778,7 +2778,7 @@ grub_make_system_path_relative_to_its_root (const char *path) + /* canonicalize. */ + p = canonicalize_file_name (path); + if (p == NULL) +- grub_util_error (_("failed to get canonical path of %s"), path); ++ grub_util_error (_("failed to get canonical path of `%s'"), path); + + /* For ZFS sub-pool filesystems, could be extended to others (btrfs?). */ + #if !defined (__MINGW32__) && !defined (__CYGWIN__) +diff --git a/util/grub-probe.c b/util/grub-probe.c +index c2a0f62..b66cbea 100644 +--- a/util/grub-probe.c ++++ b/util/grub-probe.c +@@ -327,7 +327,7 @@ probe (const char *path, char **device_names, char delim) + { + grub_path = canonicalize_file_name (path); + if (! grub_path) +- grub_util_error (_("failed to get canonical path of %s"), path); ++ grub_util_error (_("failed to get canonical path of `%s'"), path); + device_names = grub_guess_root_devices (grub_path); + free (grub_path); + } +diff --git a/util/ieee1275/ofpath.c b/util/ieee1275/ofpath.c +index 9de9ffc..f0a34b5 100644 +--- a/util/ieee1275/ofpath.c ++++ b/util/ieee1275/ofpath.c +@@ -131,7 +131,7 @@ find_obppath (const char *sysfs_path_orig) + kill_trailing_dir(sysfs_path); + if (!strcmp(sysfs_path, "/sys")) + { +- grub_util_info (_("'obppath' not found in parent dirs of %s," ++ grub_util_info (_("`obppath' not found in parent dirs of `%s'," + " no IEEE1275 name discovery"), + sysfs_path_orig); + free (path); +@@ -164,7 +164,7 @@ xrealpath (const char *in) + out = realpath (in, NULL); + #endif + if (!out) +- grub_util_error (_("failed to get canonical path of %s"), in); ++ grub_util_error (_("failed to get canonical path of `%s'"), in); + return out; + } + +-- +1.8.1.4 + diff --git a/0106-Remove-nested-functions-from-memory-map-iterators.patch b/0106-Remove-nested-functions-from-memory-map-iterators.patch new file mode 100644 index 0000000..0aacd5a --- /dev/null +++ b/0106-Remove-nested-functions-from-memory-map-iterators.patch @@ -0,0 +1,3556 @@ +From adab1994c1bbc38744a4631c7d1df08f3439c471 Mon Sep 17 00:00:00 2001 +From: Colin Watson +Date: Tue, 15 Jan 2013 12:02:35 +0000 +Subject: [PATCH 106/364] Remove nested functions from memory map iterators. + +* grub-core/efiemu/mm.c (grub_efiemu_mmap_iterate): Add hook_data +argument, passed to hook. +* grub-core/kern/i386/coreboot/mmap.c +(grub_linuxbios_table_iterate): Likewise. +(grub_machine_mmap_iterate: iterate_linuxbios_table): Make static +instead of nested. +(grub_machine_mmap_iterate): Add hook_data argument. +* grub-core/kern/i386/multiboot_mmap.c (grub_machine_mmap_iterate): +Add hook_data argument, passed to hook. +* grub-core/kern/i386/pc/mmap.c (grub_machine_mmap_iterate): +Likewise. +* grub-core/kern/i386/qemu/mmap.c (grub_machine_mmap_iterate): +Likewise. +* grub-core/kern/ieee1275/mmap.c (grub_machine_mmap_iterate): +Likewise. +* grub-core/kern/mips/arc/init.c (grub_machine_mmap_iterate): +Likewise. +* grub-core/kern/mips/loongson/init.c (grub_machine_mmap_iterate): +Likewise. +* grub-core/kern/mips/qemu_mips/init.c (grub_machine_mmap_iterate): +Likewise. +* grub-core/mmap/efi/mmap.c (grub_efi_mmap_iterate): Likewise. +(grub_machine_mmap_iterate): Likewise. +* grub-core/mmap/mmap.c (grub_mmap_iterate): Likewise. +* include/grub/efiemu/efiemu.h (grub_efiemu_mmap_iterate): Update +prototype. +* include/grub/memory.h (grub_memory_hook_t): Add data argument. +Remove NESTED_FUNC_ATTR from here and from all users. +(grub_mmap_iterate): Update prototype. +(grub_efi_mmap_iterate): Update prototype. Update all callers to +pass appropriate hook data. +(grub_machine_mmap_iterate): Likewise. + +* grub-core/commands/acpi.c (grub_acpi_create_ebda: find_hook): Make +static instead of nested. +* grub-core/commands/lsmmap.c (grub_cmd_lsmmap: hook): Likewise. +Rename to ... +(lsmmap_hook): ... this. +* grub-core/efiemu/mm.c (grub_efiemu_mmap_init: bounds_hook): +Likewise. +(grub_efiemu_mmap_fill: fill_hook): Likewise. +* grub-core/kern/i386/coreboot/init.c (grub_machine_init: +heap_init): Likewise. +* grub-core/kern/i386/pc/init.c (grub_machine_init: hook): Likewise. +Rename to ... +(mmap_iterate_hook): ... this. +* grub-core/kern/ieee1275/init.c (grub_claim_heap: heap_init): +Likewise. +* grub-core/lib/ieee1275/relocator.c +(grub_relocator_firmware_get_max_events: count): Likewise. +(grub_relocator_firmware_fill_events: fill): Likewise. Rename +to ... +(grub_relocator_firmware_fill_events_iter): ... this. +* grub-core/lib/relocator.c (grub_relocator_alloc_chunk_align: +hook): Likewise. Rename to ... +(grub_relocator_alloc_chunk_align_iter): ... this. +* grub-core/loader/i386/bsd.c (generate_e820_mmap: hook): Likewise. +Rename to ... +(generate_e820_mmap_iter): ... this. +* grub-core/loader/i386/linux.c (find_mmap_size: hook): Likewise. +Rename to ... +(count_hook): ... this. +(grub_linux_boot: hook): Likewise. Rename to ... +(grub_linux_boot_mmap_find): ... this. +(grub_linux_boot: hook_fill): Likewise. Rename to ... +(grub_linux_boot_mmap_fill): ... this. +* grub-core/loader/i386/multiboot_mbi.c (grub_fill_multiboot_mmap: +hook): Likewise. Rename to ... +(grub_fill_multiboot_mmap_iter): ... this. +* grub-core/loader/multiboot.c (grub_get_multiboot_mmap_count: +hook): Likewise. Rename to ... +(count_hook): ... this. +* grub-core/loader/multiboot_mbi2.c (grub_fill_multiboot_mmap: +hook): Likewise. Rename to ... +(grub_fill_multiboot_mmap_iter): ... this. +* grub-core/loader/powerpc/ieee1275/linux.c +(grub_linux_claimmap_iterate: alloc_mem): Likewise. +* grub-core/loader/sparc64/ieee1275/linux.c (alloc_phys: choose): +Likewise. Rename to ... +(alloc_phys_choose): ... this. +(determine_phys_base: get_physbase): Likewise. +* grub-core/mmap/i386/mmap.c (grub_mmap_malign_and_register: +find_hook): Likewise. +* grub-core/mmap/i386/pc/mmap.c (preboot: fill_hook): Likewise. +(malloc_hook: count_hook): Likewise. +* grub-core/mmap/i386/uppermem.c (grub_mmap_get_lower: hook): +Likewise. Rename to ... +(lower_hook): ... this. +(grub_mmap_get_upper: hook): Likewise. Rename to ... +(upper_hook): ... this. +(grub_mmap_get_post64: hook): Likewise. Rename to ... +(post64_hook): ... this. +* grub-core/mmap/mips/uppermem.c (grub_mmap_get_lower: hook): +Likewise. Rename to ... +(lower_hook): ... this. +(grub_mmap_get_upper: hook): Likewise. Rename to ... +(upper_hook): ... this. +* grub-core/mmap/mmap.c (grub_mmap_iterate: count_hook): Likewise. +(grub_mmap_iterate: fill_hook): Likewise. +(fill_mask): Pass addr and mask within a single struct. +(grub_cmd_badram: hook): Make static instead of nested. Rename +to ... +(badram_iter): ... this. +(grub_cmd_cutmem: hook): Likewise. Rename to ... +(cutmem_iter): ... this. +--- + ChangeLog | 110 +++++++++ + grub-core/commands/acpi.c | 55 +++-- + grub-core/commands/lsmmap.c | 31 ++- + grub-core/efiemu/mm.c | 97 ++++---- + grub-core/kern/i386/coreboot/init.c | 68 +++--- + grub-core/kern/i386/coreboot/mmap.c | 66 +++-- + grub-core/kern/i386/multiboot_mmap.c | 4 +- + grub-core/kern/i386/pc/init.c | 61 ++--- + grub-core/kern/i386/pc/mmap.c | 14 +- + grub-core/kern/i386/qemu/mmap.c | 14 +- + grub-core/kern/ieee1275/init.c | 124 +++++----- + grub-core/kern/ieee1275/mmap.c | 4 +- + grub-core/kern/mips/arc/init.c | 4 +- + grub-core/kern/mips/loongson/init.c | 6 +- + grub-core/kern/mips/qemu_mips/init.c | 4 +- + grub-core/lib/ieee1275/relocator.c | 102 ++++---- + grub-core/lib/relocator.c | 143 ++++++----- + grub-core/loader/i386/bsd.c | 136 ++++++----- + grub-core/loader/i386/linux.c | 256 ++++++++++---------- + grub-core/loader/i386/multiboot_mbi.c | 74 +++--- + grub-core/loader/multiboot.c | 23 +- + grub-core/loader/multiboot_mbi2.c | 66 ++--- + grub-core/loader/powerpc/ieee1275/linux.c | 76 +++--- + grub-core/loader/sparc64/ieee1275/linux.c | 129 +++++----- + grub-core/mmap/efi/mmap.c | 23 +- + grub-core/mmap/i386/mmap.c | 52 ++-- + grub-core/mmap/i386/pc/mmap.c | 49 ++-- + grub-core/mmap/i386/uppermem.c | 83 ++++--- + grub-core/mmap/mips/uppermem.c | 58 ++--- + grub-core/mmap/mmap.c | 388 ++++++++++++++++-------------- + include/grub/efiemu/efiemu.h | 2 +- + include/grub/memory.h | 18 +- + 32 files changed, 1305 insertions(+), 1035 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 1c0e633..d07f235 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,113 @@ ++2013-01-15 Colin Watson ++ ++ Remove nested functions from memory map iterators. ++ ++ * grub-core/efiemu/mm.c (grub_efiemu_mmap_iterate): Add hook_data ++ argument, passed to hook. ++ * grub-core/kern/i386/coreboot/mmap.c ++ (grub_linuxbios_table_iterate): Likewise. ++ (grub_machine_mmap_iterate: iterate_linuxbios_table): Make static ++ instead of nested. ++ (grub_machine_mmap_iterate): Add hook_data argument. ++ * grub-core/kern/i386/multiboot_mmap.c (grub_machine_mmap_iterate): ++ Add hook_data argument, passed to hook. ++ * grub-core/kern/i386/pc/mmap.c (grub_machine_mmap_iterate): ++ Likewise. ++ * grub-core/kern/i386/qemu/mmap.c (grub_machine_mmap_iterate): ++ Likewise. ++ * grub-core/kern/ieee1275/mmap.c (grub_machine_mmap_iterate): ++ Likewise. ++ * grub-core/kern/mips/arc/init.c (grub_machine_mmap_iterate): ++ Likewise. ++ * grub-core/kern/mips/loongson/init.c (grub_machine_mmap_iterate): ++ Likewise. ++ * grub-core/kern/mips/qemu_mips/init.c (grub_machine_mmap_iterate): ++ Likewise. ++ * grub-core/mmap/efi/mmap.c (grub_efi_mmap_iterate): Likewise. ++ (grub_machine_mmap_iterate): Likewise. ++ * grub-core/mmap/mmap.c (grub_mmap_iterate): Likewise. ++ * include/grub/efiemu/efiemu.h (grub_efiemu_mmap_iterate): Update ++ prototype. ++ * include/grub/memory.h (grub_memory_hook_t): Add data argument. ++ Remove NESTED_FUNC_ATTR from here and from all users. ++ (grub_mmap_iterate): Update prototype. ++ (grub_efi_mmap_iterate): Update prototype. Update all callers to ++ pass appropriate hook data. ++ (grub_machine_mmap_iterate): Likewise. ++ ++ * grub-core/commands/acpi.c (grub_acpi_create_ebda: find_hook): Make ++ static instead of nested. ++ * grub-core/commands/lsmmap.c (grub_cmd_lsmmap: hook): Likewise. ++ Rename to ... ++ (lsmmap_hook): ... this. ++ * grub-core/efiemu/mm.c (grub_efiemu_mmap_init: bounds_hook): ++ Likewise. ++ (grub_efiemu_mmap_fill: fill_hook): Likewise. ++ * grub-core/kern/i386/coreboot/init.c (grub_machine_init: ++ heap_init): Likewise. ++ * grub-core/kern/i386/pc/init.c (grub_machine_init: hook): Likewise. ++ Rename to ... ++ (mmap_iterate_hook): ... this. ++ * grub-core/kern/ieee1275/init.c (grub_claim_heap: heap_init): ++ Likewise. ++ * grub-core/lib/ieee1275/relocator.c ++ (grub_relocator_firmware_get_max_events: count): Likewise. ++ (grub_relocator_firmware_fill_events: fill): Likewise. Rename ++ to ... ++ (grub_relocator_firmware_fill_events_iter): ... this. ++ * grub-core/lib/relocator.c (grub_relocator_alloc_chunk_align: ++ hook): Likewise. Rename to ... ++ (grub_relocator_alloc_chunk_align_iter): ... this. ++ * grub-core/loader/i386/bsd.c (generate_e820_mmap: hook): Likewise. ++ Rename to ... ++ (generate_e820_mmap_iter): ... this. ++ * grub-core/loader/i386/linux.c (find_mmap_size: hook): Likewise. ++ Rename to ... ++ (count_hook): ... this. ++ (grub_linux_boot: hook): Likewise. Rename to ... ++ (grub_linux_boot_mmap_find): ... this. ++ (grub_linux_boot: hook_fill): Likewise. Rename to ... ++ (grub_linux_boot_mmap_fill): ... this. ++ * grub-core/loader/i386/multiboot_mbi.c (grub_fill_multiboot_mmap: ++ hook): Likewise. Rename to ... ++ (grub_fill_multiboot_mmap_iter): ... this. ++ * grub-core/loader/multiboot.c (grub_get_multiboot_mmap_count: ++ hook): Likewise. Rename to ... ++ (count_hook): ... this. ++ * grub-core/loader/multiboot_mbi2.c (grub_fill_multiboot_mmap: ++ hook): Likewise. Rename to ... ++ (grub_fill_multiboot_mmap_iter): ... this. ++ * grub-core/loader/powerpc/ieee1275/linux.c ++ (grub_linux_claimmap_iterate: alloc_mem): Likewise. ++ * grub-core/loader/sparc64/ieee1275/linux.c (alloc_phys: choose): ++ Likewise. Rename to ... ++ (alloc_phys_choose): ... this. ++ (determine_phys_base: get_physbase): Likewise. ++ * grub-core/mmap/i386/mmap.c (grub_mmap_malign_and_register: ++ find_hook): Likewise. ++ * grub-core/mmap/i386/pc/mmap.c (preboot: fill_hook): Likewise. ++ (malloc_hook: count_hook): Likewise. ++ * grub-core/mmap/i386/uppermem.c (grub_mmap_get_lower: hook): ++ Likewise. Rename to ... ++ (lower_hook): ... this. ++ (grub_mmap_get_upper: hook): Likewise. Rename to ... ++ (upper_hook): ... this. ++ (grub_mmap_get_post64: hook): Likewise. Rename to ... ++ (post64_hook): ... this. ++ * grub-core/mmap/mips/uppermem.c (grub_mmap_get_lower: hook): ++ Likewise. Rename to ... ++ (lower_hook): ... this. ++ (grub_mmap_get_upper: hook): Likewise. Rename to ... ++ (upper_hook): ... this. ++ * grub-core/mmap/mmap.c (grub_mmap_iterate: count_hook): Likewise. ++ (grub_mmap_iterate: fill_hook): Likewise. ++ (fill_mask): Pass addr and mask within a single struct. ++ (grub_cmd_badram: hook): Make static instead of nested. Rename ++ to ... ++ (badram_iter): ... this. ++ (grub_cmd_cutmem: hook): Likewise. Rename to ... ++ (cutmem_iter): ... this. ++ + 2013-01-13 Vladimir Serbinenko + + * grub-core/kern/emu/hostdisk.c (read_device_map): Explicitly +diff --git a/grub-core/commands/acpi.c b/grub-core/commands/acpi.c +index c6be5e1..891e392 100644 +--- a/grub-core/commands/acpi.c ++++ b/grub-core/commands/acpi.c +@@ -142,49 +142,58 @@ iszero (grub_uint8_t *reg, int size) + } + + #if defined (__i386__) || defined (__x86_64__) ++/* Context for grub_acpi_create_ebda. */ ++struct grub_acpi_create_ebda_ctx { ++ int ebda_len; ++ grub_uint64_t highestlow; ++}; ++ ++/* Helper for grub_acpi_create_ebda. */ ++static int ++find_hook (grub_uint64_t start, grub_uint64_t size, grub_memory_type_t type, ++ void *data) ++{ ++ struct grub_acpi_create_ebda_ctx *ctx = data; ++ grub_uint64_t end = start + size; ++ if (type != GRUB_MEMORY_AVAILABLE) ++ return 0; ++ if (end > 0x100000) ++ end = 0x100000; ++ if (end > start + ctx->ebda_len ++ && ctx->highestlow < ((end - ctx->ebda_len) & (~0xf)) ) ++ ctx->highestlow = (end - ctx->ebda_len) & (~0xf); ++ return 0; ++} ++ + grub_err_t + grub_acpi_create_ebda (void) + { ++ struct grub_acpi_create_ebda_ctx ctx = { ++ .highestlow = 0 ++ }; + int ebda_kb_len; +- int ebda_len; + int mmapregion = 0; + grub_uint8_t *ebda, *v1inebda = 0, *v2inebda = 0; +- grub_uint64_t highestlow = 0; + grub_uint8_t *targetebda, *target; + struct grub_acpi_rsdp_v10 *v1; + struct grub_acpi_rsdp_v20 *v2; +- auto int NESTED_FUNC_ATTR find_hook (grub_uint64_t, grub_uint64_t, +- grub_uint32_t); +- int NESTED_FUNC_ATTR find_hook (grub_uint64_t start, grub_uint64_t size, +- grub_memory_type_t type) +- { +- grub_uint64_t end = start + size; +- if (type != GRUB_MEMORY_AVAILABLE) +- return 0; +- if (end > 0x100000) +- end = 0x100000; +- if (end > start + ebda_len +- && highestlow < ((end - ebda_len) & (~0xf)) ) +- highestlow = (end - ebda_len) & (~0xf); +- return 0; +- } + + ebda = (grub_uint8_t *) (grub_addr_t) ((*((grub_uint16_t *)0x40e)) << 4); + ebda_kb_len = *(grub_uint16_t *) ebda; + if (! ebda || ebda_kb_len > 16) + ebda_kb_len = 0; +- ebda_len = (ebda_kb_len + 1) << 10; ++ ctx.ebda_len = (ebda_kb_len + 1) << 10; + + /* FIXME: use low-memory mm allocation once it's available. */ +- grub_mmap_iterate (find_hook); +- targetebda = (grub_uint8_t *) (grub_addr_t) highestlow; ++ grub_mmap_iterate (find_hook, &ctx); ++ targetebda = (grub_uint8_t *) (grub_addr_t) ctx.highestlow; + grub_dprintf ("acpi", "creating ebda @%llx\n", +- (unsigned long long) highestlow); +- if (! highestlow) ++ (unsigned long long) ctx.highestlow); ++ if (! ctx.highestlow) + return grub_error (GRUB_ERR_OUT_OF_MEMORY, + "couldn't find space for the new EBDA"); + +- mmapregion = grub_mmap_register ((grub_addr_t) targetebda, ebda_len, ++ mmapregion = grub_mmap_register ((grub_addr_t) targetebda, ctx.ebda_len, + GRUB_MEMORY_RESERVED); + if (! mmapregion) + return grub_errno; +diff --git a/grub-core/commands/lsmmap.c b/grub-core/commands/lsmmap.c +index bd32c33..8e7f2a5 100644 +--- a/grub-core/commands/lsmmap.c ++++ b/grub-core/commands/lsmmap.c +@@ -21,6 +21,7 @@ + #include + #include + #include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -39,26 +40,30 @@ static const char *names[] = + [GRUB_MEMORY_HOLE] = N_("Address range not associated with RAM") + }; + ++#ifndef GRUB_MACHINE_EMU ++/* Helper for grub_cmd_lsmmap. */ ++static int ++lsmmap_hook (grub_uint64_t addr, grub_uint64_t size, grub_memory_type_t type, ++ void *data __attribute__ ((unused))) ++{ ++ if (type < ARRAY_SIZE (names) && names[type]) ++ grub_printf_ (N_("base_addr = 0x%llx, length = 0x%llx, %s\n"), ++ (long long) addr, (long long) size, _(names[type])); ++ else ++ grub_printf_ (N_("base_addr = 0x%llx, length = 0x%llx, type = 0x%x\n"), ++ (long long) addr, (long long) size, type); ++ return 0; ++} ++#endif ++ + static grub_err_t + grub_cmd_lsmmap (grub_command_t cmd __attribute__ ((unused)), + int argc __attribute__ ((unused)), + char **args __attribute__ ((unused))) + + { +- auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_memory_type_t); +- int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, +- grub_memory_type_t type) +- { +- if (type < ARRAY_SIZE (names) && names[type]) +- grub_printf_ (N_("base_addr = 0x%llx, length = 0x%llx, %s\n"), +- (long long) addr, (long long) size, _(names[type])); +- else +- grub_printf_ (N_("base_addr = 0x%llx, length = 0x%llx, type = 0x%x\n"), +- (long long) addr, (long long) size, type); +- return 0; +- } + #ifndef GRUB_MACHINE_EMU +- grub_machine_mmap_iterate (hook); ++ grub_machine_mmap_iterate (lsmmap_hook, NULL); + #endif + + return 0; +diff --git a/grub-core/efiemu/mm.c b/grub-core/efiemu/mm.c +index 10cbc68..d4a4f3a 100644 +--- a/grub-core/efiemu/mm.c ++++ b/grub-core/efiemu/mm.c +@@ -268,26 +268,26 @@ grub_efiemu_mm_return_request (int handle) + } + } + ++/* Helper for grub_efiemu_mmap_init. */ ++static int ++bounds_hook (grub_uint64_t addr __attribute__ ((unused)), ++ grub_uint64_t size __attribute__ ((unused)), ++ grub_memory_type_t type __attribute__ ((unused)), ++ void *data __attribute__ ((unused))) ++{ ++ mmap_reserved_size++; ++ return 0; ++} ++ + /* Reserve space for memory map */ + static grub_err_t + grub_efiemu_mmap_init (void) + { +- auto int NESTED_FUNC_ATTR bounds_hook (grub_uint64_t, grub_uint64_t, +- grub_memory_type_t); +- int NESTED_FUNC_ATTR bounds_hook (grub_uint64_t addr __attribute__ ((unused)), +- grub_uint64_t size __attribute__ ((unused)), +- grub_memory_type_t type +- __attribute__ ((unused))) +- { +- mmap_reserved_size++; +- return 0; +- } +- + // the place for memory used by efiemu itself + mmap_reserved_size = GRUB_EFI_MAX_MEMORY_TYPE + 1; + + #ifndef GRUB_MACHINE_EMU +- grub_machine_mmap_iterate (bounds_hook); ++ grub_machine_mmap_iterate (bounds_hook, NULL); + #endif + + return GRUB_ERR_NONE; +@@ -383,48 +383,47 @@ grub_efiemu_mm_init (void) + return GRUB_ERR_NONE; + } + ++/* Helper for grub_efiemu_mmap_fill. */ ++static int ++fill_hook (grub_uint64_t addr, grub_uint64_t size, grub_memory_type_t type, ++ void *data __attribute__ ((unused))) ++ { ++ switch (type) ++ { ++ case GRUB_MEMORY_AVAILABLE: ++ return grub_efiemu_add_to_mmap (addr, size, ++ GRUB_EFI_CONVENTIONAL_MEMORY); ++ ++ case GRUB_MEMORY_ACPI: ++ return grub_efiemu_add_to_mmap (addr, size, ++ GRUB_EFI_ACPI_RECLAIM_MEMORY); ++ ++ case GRUB_MEMORY_NVS: ++ return grub_efiemu_add_to_mmap (addr, size, ++ GRUB_EFI_ACPI_MEMORY_NVS); ++ ++ default: ++ grub_dprintf ("efiemu", ++ "Unknown memory type %d. Assuming unusable\n", type); ++ case GRUB_MEMORY_RESERVED: ++ return grub_efiemu_add_to_mmap (addr, size, ++ GRUB_EFI_UNUSABLE_MEMORY); ++ } ++ } ++ + /* Copy host memory map */ + static grub_err_t + grub_efiemu_mmap_fill (void) + { +- auto int NESTED_FUNC_ATTR fill_hook (grub_uint64_t, grub_uint64_t, +- grub_memory_type_t); +- int NESTED_FUNC_ATTR fill_hook (grub_uint64_t addr, +- grub_uint64_t size, +- grub_memory_type_t type) +- { +- switch (type) +- { +- case GRUB_MEMORY_AVAILABLE: +- return grub_efiemu_add_to_mmap (addr, size, +- GRUB_EFI_CONVENTIONAL_MEMORY); +- +- case GRUB_MEMORY_ACPI: +- return grub_efiemu_add_to_mmap (addr, size, +- GRUB_EFI_ACPI_RECLAIM_MEMORY); +- +- case GRUB_MEMORY_NVS: +- return grub_efiemu_add_to_mmap (addr, size, +- GRUB_EFI_ACPI_MEMORY_NVS); +- +- default: +- grub_dprintf ("efiemu", +- "Unknown memory type %d. Assuming unusable\n", type); +- case GRUB_MEMORY_RESERVED: +- return grub_efiemu_add_to_mmap (addr, size, +- GRUB_EFI_UNUSABLE_MEMORY); +- } +- } +- + #ifndef GRUB_MACHINE_EMU +- grub_machine_mmap_iterate (fill_hook); ++ grub_machine_mmap_iterate (fill_hook, NULL); + #endif + + return GRUB_ERR_NONE; + } + + grub_err_t +-grub_efiemu_mmap_iterate (grub_memory_hook_t hook) ++grub_efiemu_mmap_iterate (grub_memory_hook_t hook, void *hook_data) + { + unsigned i; + +@@ -433,12 +432,12 @@ grub_efiemu_mmap_iterate (grub_memory_hook_t hook) + { + case GRUB_EFI_RUNTIME_SERVICES_CODE: + hook (efiemu_mmap[i].physical_start, efiemu_mmap[i].num_pages * 4096, +- GRUB_MEMORY_CODE); ++ GRUB_MEMORY_CODE, hook_data); + break; + + case GRUB_EFI_UNUSABLE_MEMORY: + hook (efiemu_mmap[i].physical_start, efiemu_mmap[i].num_pages * 4096, +- GRUB_MEMORY_BADRAM); ++ GRUB_MEMORY_BADRAM, hook_data); + break; + + case GRUB_EFI_RESERVED_MEMORY_TYPE: +@@ -448,7 +447,7 @@ grub_efiemu_mmap_iterate (grub_memory_hook_t hook) + case GRUB_EFI_PAL_CODE: + case GRUB_EFI_MAX_MEMORY_TYPE: + hook (efiemu_mmap[i].physical_start, efiemu_mmap[i].num_pages * 4096, +- GRUB_MEMORY_RESERVED); ++ GRUB_MEMORY_RESERVED, hook_data); + break; + + case GRUB_EFI_LOADER_CODE: +@@ -457,17 +456,17 @@ grub_efiemu_mmap_iterate (grub_memory_hook_t hook) + case GRUB_EFI_BOOT_SERVICES_DATA: + case GRUB_EFI_CONVENTIONAL_MEMORY: + hook (efiemu_mmap[i].physical_start, efiemu_mmap[i].num_pages * 4096, +- GRUB_MEMORY_AVAILABLE); ++ GRUB_MEMORY_AVAILABLE, hook_data); + break; + + case GRUB_EFI_ACPI_RECLAIM_MEMORY: + hook (efiemu_mmap[i].physical_start, efiemu_mmap[i].num_pages * 4096, +- GRUB_MEMORY_ACPI); ++ GRUB_MEMORY_ACPI, hook_data); + break; + + case GRUB_EFI_ACPI_MEMORY_NVS: + hook (efiemu_mmap[i].physical_start, efiemu_mmap[i].num_pages * 4096, +- GRUB_MEMORY_NVS); ++ GRUB_MEMORY_NVS, hook_data); + break; + } + +diff --git a/grub-core/kern/i386/coreboot/init.c b/grub-core/kern/i386/coreboot/init.c +index 52fbba4..48fd1a6 100644 +--- a/grub-core/kern/i386/coreboot/init.c ++++ b/grub-core/kern/i386/coreboot/init.c +@@ -57,6 +57,39 @@ grub_addr_t grub_modbase; + grub_addr_t grub_modbase = ALIGN_UP((grub_addr_t) _end, GRUB_KERNEL_MACHINE_MOD_ALIGN); + #endif + ++/* Helper for grub_machine_init. */ ++static int ++heap_init (grub_uint64_t addr, grub_uint64_t size, grub_memory_type_t type, ++ void *data __attribute__ ((unused))) ++{ ++#if GRUB_CPU_SIZEOF_VOID_P == 4 ++ /* Restrict ourselves to 32-bit memory space. */ ++ if (addr > GRUB_ULONG_MAX) ++ return 0; ++ if (addr + size > GRUB_ULONG_MAX) ++ size = GRUB_ULONG_MAX - addr; ++#endif ++ ++ if (type != GRUB_MEMORY_AVAILABLE) ++ return 0; ++ ++ /* Avoid the lower memory. */ ++ if (addr < GRUB_MEMORY_MACHINE_LOWER_SIZE) ++ { ++ if (addr + size <= GRUB_MEMORY_MACHINE_LOWER_SIZE) ++ return 0; ++ else ++ { ++ size -= GRUB_MEMORY_MACHINE_LOWER_SIZE - addr; ++ addr = GRUB_MEMORY_MACHINE_LOWER_SIZE; ++ } ++ } ++ ++ grub_mm_init_region ((void *) (grub_addr_t) addr, (grub_size_t) size); ++ ++ return 0; ++} ++ + void + grub_machine_init (void) + { +@@ -68,43 +101,10 @@ grub_machine_init (void) + /* Initialize the console as early as possible. */ + grub_vga_text_init (); + +- auto int NESTED_FUNC_ATTR heap_init (grub_uint64_t, grub_uint64_t, +- grub_memory_type_t); +- int NESTED_FUNC_ATTR heap_init (grub_uint64_t addr, grub_uint64_t size, +- grub_memory_type_t type) +- { +-#if GRUB_CPU_SIZEOF_VOID_P == 4 +- /* Restrict ourselves to 32-bit memory space. */ +- if (addr > GRUB_ULONG_MAX) +- return 0; +- if (addr + size > GRUB_ULONG_MAX) +- size = GRUB_ULONG_MAX - addr; +-#endif +- +- if (type != GRUB_MEMORY_AVAILABLE) +- return 0; +- +- /* Avoid the lower memory. */ +- if (addr < GRUB_MEMORY_MACHINE_LOWER_SIZE) +- { +- if (addr + size <= GRUB_MEMORY_MACHINE_LOWER_SIZE) +- return 0; +- else +- { +- size -= GRUB_MEMORY_MACHINE_LOWER_SIZE - addr; +- addr = GRUB_MEMORY_MACHINE_LOWER_SIZE; +- } +- } +- +- grub_mm_init_region ((void *) (grub_addr_t) addr, (grub_size_t) size); +- +- return 0; +- } +- + #if defined (GRUB_MACHINE_MULTIBOOT) || defined (GRUB_MACHINE_QEMU) + grub_machine_mmap_init (); + #endif +- grub_machine_mmap_iterate (heap_init); ++ grub_machine_mmap_iterate (heap_init, NULL); + + grub_tsc_init (); + } +diff --git a/grub-core/kern/i386/coreboot/mmap.c b/grub-core/kern/i386/coreboot/mmap.c +index 8e15683..ae4af08 100644 +--- a/grub-core/kern/i386/coreboot/mmap.c ++++ b/grub-core/kern/i386/coreboot/mmap.c +@@ -33,7 +33,9 @@ check_signature (grub_linuxbios_table_header_t tbl_header) + } + + static grub_err_t +-grub_linuxbios_table_iterate (int (*hook) (grub_linuxbios_table_item_t)) ++grub_linuxbios_table_iterate (int (*hook) (grub_linuxbios_table_item_t, ++ void *), ++ void *hook_data) + { + grub_linuxbios_table_header_t table_header; + grub_linuxbios_table_item_t table_item; +@@ -68,42 +70,54 @@ signature_found: + *(grub_uint64_t *) (table_item + 1); + goto signature_found; + } +- if (hook (table_item)) ++ if (hook (table_item, hook_data)) + return 1; + } + + return 0; + } + +-grub_err_t +-grub_machine_mmap_iterate (grub_memory_hook_t hook) ++/* Context for grub_machine_mmap_iterate. */ ++struct grub_machine_mmap_iterate_ctx + { +- mem_region_t mem_region; ++ grub_memory_hook_t hook; ++ void *hook_data; ++}; + +- auto int iterate_linuxbios_table (grub_linuxbios_table_item_t); +- int iterate_linuxbios_table (grub_linuxbios_table_item_t table_item) +- { +- if (table_item->tag != GRUB_LINUXBIOS_MEMBER_MEMORY) +- return 0; +- +- mem_region = +- (mem_region_t) ((long) table_item + +- sizeof (struct grub_linuxbios_table_item)); +- while ((long) mem_region < (long) table_item + (long) table_item->size) +- { +- if (hook (mem_region->addr, mem_region->size, +- /* Multiboot mmaps match with the coreboot mmap definition. +- Therefore, we can just pass type through. */ +- mem_region->type)) +- return 1; +- +- mem_region++; +- } ++/* Helper for grub_machine_mmap_iterate. */ ++static int ++iterate_linuxbios_table (grub_linuxbios_table_item_t table_item, void *data) ++{ ++ struct grub_machine_mmap_iterate_ctx *ctx = data; ++ mem_region_t mem_region; + ++ if (table_item->tag != GRUB_LINUXBIOS_MEMBER_MEMORY) + return 0; +- } + +- grub_linuxbios_table_iterate (iterate_linuxbios_table); ++ mem_region = ++ (mem_region_t) ((long) table_item + ++ sizeof (struct grub_linuxbios_table_item)); ++ while ((long) mem_region < (long) table_item + (long) table_item->size) ++ { ++ if (ctx->hook (mem_region->addr, mem_region->size, ++ /* Multiboot mmaps match with the coreboot mmap ++ definition. Therefore, we can just pass type ++ through. */ ++ mem_region->type, ctx->hook_data)) ++ return 1; ++ ++ mem_region++; ++ } ++ ++ return 0; ++} ++ ++grub_err_t ++grub_machine_mmap_iterate (grub_memory_hook_t hook, void *hook_data) ++{ ++ struct grub_machine_mmap_iterate_ctx ctx = { hook, hook_data }; ++ ++ grub_linuxbios_table_iterate (iterate_linuxbios_table, &ctx); + + return 0; + } +diff --git a/grub-core/kern/i386/multiboot_mmap.c b/grub-core/kern/i386/multiboot_mmap.c +index 1cb422f..e8f4f34 100644 +--- a/grub-core/kern/i386/multiboot_mmap.c ++++ b/grub-core/kern/i386/multiboot_mmap.c +@@ -57,13 +57,13 @@ grub_machine_mmap_init (void) + } + + grub_err_t +-grub_machine_mmap_iterate (grub_memory_hook_t hook) ++grub_machine_mmap_iterate (grub_memory_hook_t hook, void *hook_data) + { + struct multiboot_mmap_entry *entry = (void *) kern_multiboot_info.mmap_addr; + + while ((unsigned long) entry < kern_multiboot_info.mmap_addr + kern_multiboot_info.mmap_length) + { +- if (hook (entry->addr, entry->len, entry->type)) ++ if (hook (entry->addr, entry->len, entry->type, hook_data)) + break; + + entry = (void *) ((grub_addr_t) entry + entry->size + sizeof (entry->size)); +diff --git a/grub-core/kern/i386/pc/init.c b/grub-core/kern/i386/pc/init.c +index 0841d8b..7d8b12c 100644 +--- a/grub-core/kern/i386/pc/init.c ++++ b/grub-core/kern/i386/pc/init.c +@@ -154,6 +154,36 @@ compact_mem_regions (void) + grub_addr_t grub_modbase; + extern grub_uint8_t _start[], _edata[]; + ++/* Helper for grub_machine_init. */ ++static int ++mmap_iterate_hook (grub_uint64_t addr, grub_uint64_t size, ++ grub_memory_type_t type, ++ void *data __attribute__ ((unused))) ++{ ++ /* Avoid the lower memory. */ ++ if (addr < 0x100000) ++ { ++ if (size <= 0x100000 - addr) ++ return 0; ++ ++ size -= 0x100000 - addr; ++ addr = 0x100000; ++ } ++ ++ /* Ignore >4GB. */ ++ if (addr <= 0xFFFFFFFF && type == GRUB_MEMORY_AVAILABLE) ++ { ++ grub_size_t len; ++ ++ len = (grub_size_t) ((addr + size > 0xFFFFFFFF) ++ ? 0xFFFFFFFF - addr ++ : size); ++ add_mem_region (addr, len); ++ } ++ ++ return 0; ++} ++ + void + grub_machine_init (void) + { +@@ -188,36 +218,7 @@ grub_machine_init (void) + grub_lower_mem - GRUB_MEMORY_MACHINE_RESERVED_END); + #endif + +- auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, +- grub_memory_type_t); +- int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, +- grub_memory_type_t type) +- { +- /* Avoid the lower memory. */ +- if (addr < 0x100000) +- { +- if (size <= 0x100000 - addr) +- return 0; +- +- size -= 0x100000 - addr; +- addr = 0x100000; +- } +- +- /* Ignore >4GB. */ +- if (addr <= 0xFFFFFFFF && type == GRUB_MEMORY_AVAILABLE) +- { +- grub_size_t len; +- +- len = (grub_size_t) ((addr + size > 0xFFFFFFFF) +- ? 0xFFFFFFFF - addr +- : size); +- add_mem_region (addr, len); +- } +- +- return 0; +- } +- +- grub_machine_mmap_iterate (hook); ++ grub_machine_mmap_iterate (mmap_iterate_hook, NULL); + + compact_mem_regions (); + +diff --git a/grub-core/kern/i386/pc/mmap.c b/grub-core/kern/i386/pc/mmap.c +index 480ffa9..7e5feea 100644 +--- a/grub-core/kern/i386/pc/mmap.c ++++ b/grub-core/kern/i386/pc/mmap.c +@@ -139,7 +139,7 @@ grub_get_mmap_entry (struct grub_machine_mmap_entry *entry, + } + + grub_err_t +-grub_machine_mmap_iterate (grub_memory_hook_t hook) ++grub_machine_mmap_iterate (grub_memory_hook_t hook, void *hook_data) + { + grub_uint32_t cont; + struct grub_machine_mmap_entry *entry +@@ -156,7 +156,8 @@ grub_machine_mmap_iterate (grub_memory_hook_t hook) + if (hook (entry->addr, entry->len, + /* GRUB mmaps have been defined to match with the E820 definition. + Therefore, we can just pass type through. */ +- ((entry->type <= GRUB_MACHINE_MEMORY_BADRAM) && (entry->type >= GRUB_MACHINE_MEMORY_AVAILABLE)) ? entry->type : GRUB_MEMORY_RESERVED)) ++ ((entry->type <= GRUB_MACHINE_MEMORY_BADRAM) && (entry->type >= GRUB_MACHINE_MEMORY_AVAILABLE)) ? entry->type : GRUB_MEMORY_RESERVED, ++ hook_data)) + break; + + if (! cont) +@@ -172,18 +173,19 @@ grub_machine_mmap_iterate (grub_memory_hook_t hook) + grub_uint32_t eisa_mmap = grub_get_eisa_mmap (); + + if (hook (0x0, ((grub_uint32_t) grub_get_conv_memsize ()) << 10, +- GRUB_MEMORY_AVAILABLE)) ++ GRUB_MEMORY_AVAILABLE, hook_data)) + return 0; + + if (eisa_mmap) + { + if (hook (0x100000, (eisa_mmap & 0xFFFF) << 10, +- GRUB_MEMORY_AVAILABLE) == 0) +- hook (0x1000000, eisa_mmap & ~0xFFFF, GRUB_MEMORY_AVAILABLE); ++ GRUB_MEMORY_AVAILABLE, hook_data) == 0) ++ hook (0x1000000, eisa_mmap & ~0xFFFF, GRUB_MEMORY_AVAILABLE, ++ hook_data); + } + else + hook (0x100000, ((grub_uint32_t) grub_get_ext_memsize ()) << 10, +- GRUB_MEMORY_AVAILABLE); ++ GRUB_MEMORY_AVAILABLE, hook_data); + } + + return 0; +diff --git a/grub-core/kern/i386/qemu/mmap.c b/grub-core/kern/i386/qemu/mmap.c +index ffb61a4..f449637 100644 +--- a/grub-core/kern/i386/qemu/mmap.c ++++ b/grub-core/kern/i386/qemu/mmap.c +@@ -69,38 +69,38 @@ grub_machine_mmap_init (void) + } + + grub_err_t +-grub_machine_mmap_iterate (grub_memory_hook_t hook) ++grub_machine_mmap_iterate (grub_memory_hook_t hook, void *hook_data) + { + if (hook (0x0, + (grub_addr_t) _start, +- GRUB_MEMORY_AVAILABLE)) ++ GRUB_MEMORY_AVAILABLE, hook_data)) + return 1; + + if (hook ((grub_addr_t) _end, + 0xa0000 - (grub_addr_t) _end, +- GRUB_MEMORY_AVAILABLE)) ++ GRUB_MEMORY_AVAILABLE, hook_data)) + return 1; + + if (hook (GRUB_MEMORY_MACHINE_UPPER, + 0x100000 - GRUB_MEMORY_MACHINE_UPPER, +- GRUB_MEMORY_RESERVED)) ++ GRUB_MEMORY_RESERVED, hook_data)) + return 1; + + /* Everything else is free. */ + if (hook (0x100000, + min (mem_size, (grub_uint32_t) -GRUB_BOOT_MACHINE_SIZE) - 0x100000, +- GRUB_MEMORY_AVAILABLE)) ++ GRUB_MEMORY_AVAILABLE, hook_data)) + return 1; + + /* Protect boot.img, which contains the gdt. It is mapped at the top of memory + (it is also mapped below 0x100000, but we already reserved that area). */ + if (hook ((grub_uint32_t) -GRUB_BOOT_MACHINE_SIZE, + GRUB_BOOT_MACHINE_SIZE, +- GRUB_MEMORY_RESERVED)) ++ GRUB_MEMORY_RESERVED, hook_data)) + return 1; + + if (above_4g != 0 && hook (0x100000000ULL, above_4g, +- GRUB_MEMORY_AVAILABLE)) ++ GRUB_MEMORY_AVAILABLE, hook_data)) + return 1; + + return 0; +diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c +index 14dcdf0..0894cb6 100644 +--- a/grub-core/kern/ieee1275/init.c ++++ b/grub-core/kern/ieee1275/init.c +@@ -156,74 +156,76 @@ grub_claim_heap (void) + + GRUB_KERNEL_MACHINE_STACK_SIZE), 0x200000); + } + #else ++/* Helper for grub_claim_heap. */ ++static int ++heap_init (grub_uint64_t addr, grub_uint64_t len, grub_memory_type_t type, ++ void *data) ++{ ++ unsigned long *total = data; ++ ++ 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 */ ++ if (*total + len > HEAP_MAX_SIZE) ++ len = HEAP_MAX_SIZE - *total; ++ ++ /* Avoid claiming anything above HEAP_MAX_ADDR, if possible. */ ++ if ((addr < HEAP_MAX_ADDR) && /* if it's too late, don't bother */ ++ (addr + len > HEAP_MAX_ADDR) && /* if it wasn't available anyway, don't bother */ ++ (*total + (HEAP_MAX_ADDR - addr) > HEAP_MIN_SIZE)) /* only limit ourselves when we can afford to */ ++ len = HEAP_MAX_ADDR - addr; ++ ++ /* In theory, firmware should already prevent this from happening by not ++ listing our own image in /memory/available. The check below is intended ++ as a safeguard in case that doesn't happen. However, it doesn't protect ++ us from corrupting our module area, which extends up to a ++ yet-undetermined region above _end. */ ++ if ((addr < (grub_addr_t) _end) && ((addr + len) > (grub_addr_t) _start)) ++ { ++ grub_printf ("Warning: attempt to claim over our own code!\n"); ++ len = 0; ++ } ++ ++ if (len) ++ { ++ grub_err_t err; ++ /* Claim and use it. */ ++ err = grub_claimmap (addr, len); ++ if (err) ++ return err; ++ grub_mm_init_region ((void *) (grub_addr_t) addr, len); ++ } ++ ++ *total += len; ++ if (*total >= HEAP_MAX_SIZE) ++ return 1; ++ ++ return 0; ++} ++ + static void + grub_claim_heap (void) + { + unsigned long total = 0; + +- auto int NESTED_FUNC_ATTR heap_init (grub_uint64_t addr, grub_uint64_t len, +- grub_memory_type_t type); +- int NESTED_FUNC_ATTR heap_init (grub_uint64_t addr, grub_uint64_t len, +- grub_memory_type_t type) +- { +- 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 */ +- if (total + len > HEAP_MAX_SIZE) +- len = HEAP_MAX_SIZE - total; +- +- /* Avoid claiming anything above HEAP_MAX_ADDR, if possible. */ +- if ((addr < HEAP_MAX_ADDR) && /* if it's too late, don't bother */ +- (addr + len > HEAP_MAX_ADDR) && /* if it wasn't available anyway, don't bother */ +- (total + (HEAP_MAX_ADDR - addr) > HEAP_MIN_SIZE)) /* only limit ourselves when we can afford to */ +- len = HEAP_MAX_ADDR - addr; +- +- /* In theory, firmware should already prevent this from happening by not +- listing our own image in /memory/available. The check below is intended +- as a safeguard in case that doesn't happen. However, it doesn't protect +- us from corrupting our module area, which extends up to a +- yet-undetermined region above _end. */ +- if ((addr < (grub_addr_t) _end) && ((addr + len) > (grub_addr_t) _start)) +- { +- grub_printf ("Warning: attempt to claim over our own code!\n"); +- len = 0; +- } +- +- if (len) +- { +- grub_err_t err; +- /* Claim and use it. */ +- err = grub_claimmap (addr, len); +- if (err) +- return err; +- grub_mm_init_region ((void *) (grub_addr_t) addr, len); +- } +- +- total += len; +- if (total >= HEAP_MAX_SIZE) +- return 1; +- +- return 0; +- } +- + if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_CANNOT_INTERPRET)) +- heap_init (HEAP_MAX_ADDR - HEAP_MIN_SIZE, HEAP_MIN_SIZE, 1); ++ heap_init (HEAP_MAX_ADDR - HEAP_MIN_SIZE, HEAP_MIN_SIZE, 1, &total); + else +- grub_machine_mmap_iterate (heap_init); ++ grub_machine_mmap_iterate (heap_init, &total); + } + #endif + +diff --git a/grub-core/kern/ieee1275/mmap.c b/grub-core/kern/ieee1275/mmap.c +index 2e4e085..911bb00 100644 +--- a/grub-core/kern/ieee1275/mmap.c ++++ b/grub-core/kern/ieee1275/mmap.c +@@ -21,7 +21,7 @@ + #include + + grub_err_t +-grub_machine_mmap_iterate (grub_memory_hook_t hook) ++grub_machine_mmap_iterate (grub_memory_hook_t hook, void *hook_data) + { + grub_ieee1275_phandle_t root; + grub_ieee1275_phandle_t memory; +@@ -72,7 +72,7 @@ grub_machine_mmap_iterate (grub_memory_hook_t hook) + if (size_cells == 2) + size = (size << 32) | available[i++]; + +- if (hook (address, size, GRUB_MEMORY_AVAILABLE)) ++ if (hook (address, size, GRUB_MEMORY_AVAILABLE, hook_data)) + break; + } + +diff --git a/grub-core/kern/mips/arc/init.c b/grub-core/kern/mips/arc/init.c +index 44b4171..4d680ed 100644 +--- a/grub-core/kern/mips/arc/init.c ++++ b/grub-core/kern/mips/arc/init.c +@@ -91,7 +91,7 @@ grub_arc_iterate_devs (int (*hook) (const char *name, + } + + grub_err_t +-grub_machine_mmap_iterate (grub_memory_hook_t hook) ++grub_machine_mmap_iterate (grub_memory_hook_t hook, void *hook_data) + { + struct grub_arc_memory_descriptor *cur = NULL; + while (1) +@@ -120,7 +120,7 @@ grub_machine_mmap_iterate (grub_memory_hook_t hook) + break; + } + if (hook (((grub_uint64_t) cur->start_page) << 12, +- ((grub_uint64_t) cur->num_pages) << 12, type)) ++ ((grub_uint64_t) cur->num_pages) << 12, type, hook_data)) + return GRUB_ERR_NONE; + } + } +diff --git a/grub-core/kern/mips/loongson/init.c b/grub-core/kern/mips/loongson/init.c +index 2109a67..756439b 100644 +--- a/grub-core/kern/mips/loongson/init.c ++++ b/grub-core/kern/mips/loongson/init.c +@@ -40,12 +40,12 @@ + #include + + grub_err_t +-grub_machine_mmap_iterate (grub_memory_hook_t hook) ++grub_machine_mmap_iterate (grub_memory_hook_t hook, void *hook_data) + { + hook (GRUB_ARCH_LOWMEMPSTART, grub_arch_memsize << 20, +- GRUB_MEMORY_AVAILABLE); ++ GRUB_MEMORY_AVAILABLE, hook_data); + hook (GRUB_ARCH_HIGHMEMPSTART, grub_arch_highmemsize << 20, +- GRUB_MEMORY_AVAILABLE); ++ GRUB_MEMORY_AVAILABLE, hook_data); + return GRUB_ERR_NONE; + } + +diff --git a/grub-core/kern/mips/qemu_mips/init.c b/grub-core/kern/mips/qemu_mips/init.c +index 782f17f..aa414eb 100644 +--- a/grub-core/kern/mips/qemu_mips/init.c ++++ b/grub-core/kern/mips/qemu_mips/init.c +@@ -92,9 +92,9 @@ grub_halt (void) + } + + grub_err_t +-grub_machine_mmap_iterate (grub_memory_hook_t hook) ++grub_machine_mmap_iterate (grub_memory_hook_t hook, void *hook_data) + { +- hook (0, grub_arch_memsize, GRUB_MEMORY_AVAILABLE); ++ hook (0, grub_arch_memsize, GRUB_MEMORY_AVAILABLE, hook_data); + return GRUB_ERR_NONE; + } + +diff --git a/grub-core/lib/ieee1275/relocator.c b/grub-core/lib/ieee1275/relocator.c +index 021f0ce..f6ecadd 100644 +--- a/grub-core/lib/ieee1275/relocator.c ++++ b/grub-core/lib/ieee1275/relocator.c +@@ -21,65 +21,81 @@ + #include + #include + ++/* Helper for grub_relocator_firmware_get_max_events. */ ++static int ++count (grub_uint64_t addr __attribute__ ((unused)), ++ grub_uint64_t len __attribute__ ((unused)), ++ grub_memory_type_t type __attribute__ ((unused)), void *data) ++{ ++ int *counter = data; ++ ++ (*counter)++; ++ return 0; ++} ++ + unsigned + grub_relocator_firmware_get_max_events (void) + { + int counter = 0; +- auto int NESTED_FUNC_ATTR count (grub_uint64_t addr __attribute__ ((unused)), +- grub_uint64_t len __attribute__ ((unused)), +- grub_memory_type_t type __attribute__ ((unused))); +- int NESTED_FUNC_ATTR count (grub_uint64_t addr __attribute__ ((unused)), +- grub_uint64_t len __attribute__ ((unused)), +- grub_memory_type_t type __attribute__ ((unused))) +- { +- counter++; +- return 0; +- } + + if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_CANNOT_INTERPRET)) + return 0; +- grub_machine_mmap_iterate (count); ++ grub_machine_mmap_iterate (count, &counter); + return 2 * counter; + } + +-unsigned +-grub_relocator_firmware_fill_events (struct grub_relocator_mmap_event *events) ++/* Context for grub_relocator_firmware_fill_events. */ ++struct grub_relocator_firmware_fill_events_ctx + { +- int counter = 0; +- auto int NESTED_FUNC_ATTR fill (grub_uint64_t addr, grub_uint64_t len, +- grub_memory_type_t type); +- int NESTED_FUNC_ATTR fill (grub_uint64_t addr, grub_uint64_t len, +- grub_memory_type_t type) +- { +- if (type != GRUB_MEMORY_AVAILABLE) +- 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; +- } +- } +- +- events[counter].type = REG_FIRMWARE_START; +- events[counter].pos = addr; +- counter++; +- events[counter].type = REG_FIRMWARE_END; +- events[counter].pos = addr + len; +- counter++; ++ struct grub_relocator_mmap_event *events; ++ int counter; ++}; ++ ++/* Helper for grub_relocator_firmware_fill_events. */ ++static int ++grub_relocator_firmware_fill_events_iter (grub_uint64_t addr, ++ grub_uint64_t len, ++ grub_memory_type_t type, void *data) ++{ ++ struct grub_relocator_firmware_fill_events_ctx *ctx = data; + ++ if (type != GRUB_MEMORY_AVAILABLE) + 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; ++ } ++ } ++ ++ ctx->events[ctx->counter].type = REG_FIRMWARE_START; ++ ctx->events[ctx->counter].pos = addr; ++ ctx->counter++; ++ ctx->events[ctx->counter].type = REG_FIRMWARE_END; ++ ctx->events[ctx->counter].pos = addr + len; ++ ctx->counter++; ++ ++ return 0; ++} ++ ++unsigned ++grub_relocator_firmware_fill_events (struct grub_relocator_mmap_event *events) ++{ ++ struct grub_relocator_firmware_fill_events_ctx ctx = { ++ .events = events, ++ .counter = 0 ++ }; + + if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_CANNOT_INTERPRET)) + return 0; +- grub_machine_mmap_iterate (fill); +- return counter; ++ grub_machine_mmap_iterate (grub_relocator_firmware_fill_events_iter, &ctx); ++ return ctx.counter; + } + + int +diff --git a/grub-core/lib/relocator.c b/grub-core/lib/relocator.c +index a45040a..350066d 100644 +--- a/grub-core/lib/relocator.c ++++ b/grub-core/lib/relocator.c +@@ -1313,6 +1313,45 @@ grub_relocator_alloc_chunk_addr (struct grub_relocator *rel, + return GRUB_ERR_NONE; + } + ++/* Context for grub_relocator_alloc_chunk_align. */ ++struct grub_relocator_alloc_chunk_align_ctx ++{ ++ grub_phys_addr_t min_addr, max_addr; ++ grub_size_t size, align; ++ int preference; ++ struct grub_relocator_chunk *chunk; ++ int found; ++}; ++ ++/* Helper for grub_relocator_alloc_chunk_align. */ ++static int ++grub_relocator_alloc_chunk_align_iter (grub_uint64_t addr, grub_uint64_t sz, ++ grub_memory_type_t type, void *data) ++{ ++ struct grub_relocator_alloc_chunk_align_ctx *ctx = data; ++ grub_uint64_t candidate; ++ ++ if (type != GRUB_MEMORY_AVAILABLE) ++ return 0; ++ candidate = ALIGN_UP (addr, ctx->align); ++ if (candidate < ctx->min_addr) ++ candidate = ALIGN_UP (ctx->min_addr, ctx->align); ++ if (candidate + ctx->size > addr + sz ++ || candidate > ALIGN_DOWN (ctx->max_addr, ctx->align)) ++ return 0; ++ if (ctx->preference == GRUB_RELOCATOR_PREFERENCE_HIGH) ++ candidate = ALIGN_DOWN (min (addr + sz - ctx->size, ctx->max_addr), ++ ctx->align); ++ if (!ctx->found || (ctx->preference == GRUB_RELOCATOR_PREFERENCE_HIGH ++ && candidate > ctx->chunk->target)) ++ ctx->chunk->target = candidate; ++ if (!ctx->found || (ctx->preference == GRUB_RELOCATOR_PREFERENCE_LOW ++ && candidate < ctx->chunk->target)) ++ ctx->chunk->target = candidate; ++ ctx->found = 1; ++ return 0; ++} ++ + grub_err_t + grub_relocator_alloc_chunk_align (struct grub_relocator *rel, + grub_relocator_chunk_t *out, +@@ -1322,8 +1361,15 @@ grub_relocator_alloc_chunk_align (struct grub_relocator *rel, + int preference, + int avoid_efi_boot_services) + { ++ struct grub_relocator_alloc_chunk_align_ctx ctx = { ++ .min_addr = min_addr, ++ .max_addr = max_addr, ++ .size = size, ++ .align = align, ++ .preference = preference, ++ .found = 0 ++ }; + grub_addr_t min_addr2 = 0, max_addr2; +- struct grub_relocator_chunk *chunk; + + if (max_addr > ~size) + max_addr = ~size; +@@ -1335,24 +1381,24 @@ grub_relocator_alloc_chunk_align (struct grub_relocator *rel, + + grub_dprintf ("relocator", "chunks = %p\n", rel->chunks); + +- chunk = grub_malloc (sizeof (struct grub_relocator_chunk)); +- if (!chunk) ++ ctx.chunk = grub_malloc (sizeof (struct grub_relocator_chunk)); ++ if (!ctx.chunk) + return grub_errno; + + if (malloc_in_range (rel, min_addr, max_addr, align, +- size, chunk, ++ size, ctx.chunk, + preference != GRUB_RELOCATOR_PREFERENCE_HIGH, 1)) + { + grub_dprintf ("relocator", "allocated 0x%llx/0x%llx\n", +- (unsigned long long) chunk->src, +- (unsigned long long) chunk->src); ++ (unsigned long long) ctx.chunk->src, ++ (unsigned long long) ctx.chunk->src); + grub_dprintf ("relocator", "chunks = %p\n", rel->chunks); +- chunk->target = chunk->src; +- chunk->size = size; +- chunk->next = rel->chunks; +- rel->chunks = chunk; +- chunk->srcv = grub_map_memory (chunk->src, chunk->size); +- *out = chunk; ++ ctx.chunk->target = ctx.chunk->src; ++ ctx.chunk->size = size; ++ ctx.chunk->next = rel->chunks; ++ rel->chunks = ctx.chunk; ++ ctx.chunk->srcv = grub_map_memory (ctx.chunk->src, ctx.chunk->size); ++ *out = ctx.chunk; + return GRUB_ERR_NONE; + } + +@@ -1364,14 +1410,14 @@ grub_relocator_alloc_chunk_align (struct grub_relocator *rel, + do + { + if (malloc_in_range (rel, min_addr2, max_addr2, align, +- size, chunk, 1, 1)) ++ size, ctx.chunk, 1, 1)) + break; + + if (malloc_in_range (rel, rel->highestnonpostaddr, ~(grub_addr_t)0, 1, +- size, chunk, 0, 1)) ++ size, ctx.chunk, 0, 1)) + { +- if (rel->postchunks > chunk->src) +- rel->postchunks = chunk->src; ++ if (rel->postchunks > ctx.chunk->src) ++ rel->postchunks = ctx.chunk->src; + break; + } + +@@ -1380,58 +1426,33 @@ grub_relocator_alloc_chunk_align (struct grub_relocator *rel, + while (0); + + { +- int found = 0; +- auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, +- grub_memory_type_t); +- int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t sz, +- grub_memory_type_t type) +- { +- grub_uint64_t candidate; +- if (type != GRUB_MEMORY_AVAILABLE) +- return 0; +- candidate = ALIGN_UP (addr, align); +- if (candidate < min_addr) +- candidate = ALIGN_UP (min_addr, align); +- if (candidate + size > addr + sz +- || candidate > ALIGN_DOWN (max_addr, align)) +- return 0; +- if (preference == GRUB_RELOCATOR_PREFERENCE_HIGH) +- candidate = ALIGN_DOWN (min (addr + sz - size, max_addr), align); +- if (!found || (preference == GRUB_RELOCATOR_PREFERENCE_HIGH +- && candidate > chunk->target)) +- chunk->target = candidate; +- if (!found || (preference == GRUB_RELOCATOR_PREFERENCE_LOW +- && candidate < chunk->target)) +- chunk->target = candidate; +- found = 1; +- return 0; +- } +- + #ifdef GRUB_MACHINE_EFI +- grub_efi_mmap_iterate (hook, avoid_efi_boot_services); ++ grub_efi_mmap_iterate (grub_relocator_alloc_chunk_align_iter, &ctx, ++ avoid_efi_boot_services); + #elif defined (__powerpc__) + (void) avoid_efi_boot_services; +- grub_machine_mmap_iterate (hook); ++ grub_machine_mmap_iterate (grub_relocator_alloc_chunk_align_iter, &ctx); + #else + (void) avoid_efi_boot_services; +- grub_mmap_iterate (hook); ++ grub_mmap_iterate (grub_relocator_alloc_chunk_align_iter, &ctx); + #endif +- if (!found) ++ if (!ctx.found) + return grub_error (GRUB_ERR_BAD_OS, "couldn't find suitable memory target"); + } + while (1) + { + struct grub_relocator_chunk *chunk2; + for (chunk2 = rel->chunks; chunk2; chunk2 = chunk2->next) +- if ((chunk2->target <= chunk->target +- && chunk->target < chunk2->target + chunk2->size) +- || (chunk->target <= chunk2->target && chunk2->target +- < chunk->target + size)) ++ if ((chunk2->target <= ctx.chunk->target ++ && ctx.chunk->target < chunk2->target + chunk2->size) ++ || (ctx.chunk->target <= chunk2->target && chunk2->target ++ < ctx.chunk->target + size)) + { + if (preference == GRUB_RELOCATOR_PREFERENCE_HIGH) +- chunk->target = ALIGN_DOWN (chunk2->target, align); ++ ctx.chunk->target = ALIGN_DOWN (chunk2->target, align); + else +- chunk->target = ALIGN_UP (chunk2->target + chunk2->size, align); ++ ctx.chunk->target = ALIGN_UP (chunk2->target + chunk2->size, ++ align); + break; + } + if (!chunk2) +@@ -1441,23 +1462,23 @@ grub_relocator_alloc_chunk_align (struct grub_relocator *rel, + grub_dprintf ("relocator", "relocators_size=%ld\n", + (unsigned long) rel->relocators_size); + +- if (chunk->src < chunk->target) ++ if (ctx.chunk->src < ctx.chunk->target) + rel->relocators_size += grub_relocator_backward_size; +- if (chunk->src > chunk->target) ++ if (ctx.chunk->src > ctx.chunk->target) + rel->relocators_size += grub_relocator_forward_size; + + grub_dprintf ("relocator", "relocators_size=%ld\n", + (unsigned long) rel->relocators_size); + +- chunk->size = size; +- chunk->next = rel->chunks; +- rel->chunks = chunk; ++ ctx.chunk->size = size; ++ ctx.chunk->next = rel->chunks; ++ rel->chunks = ctx.chunk; + grub_dprintf ("relocator", "cur = %p, next = %p\n", rel->chunks, + rel->chunks->next); +- chunk->srcv = grub_map_memory (chunk->src, chunk->size); +- *out = chunk; ++ ctx.chunk->srcv = grub_map_memory (ctx.chunk->src, ctx.chunk->size); ++ *out = ctx.chunk; + #ifdef DEBUG_RELOCATOR +- grub_memset (chunk->srcv, 0xfa, chunk->size); ++ grub_memset (ctx.chunk->srcv, 0xfa, ctx.chunk->size); + grub_mm_check (); + #endif + return GRUB_ERR_NONE; +diff --git a/grub-core/loader/i386/bsd.c b/grub-core/loader/i386/bsd.c +index 6e024e4..871cf04 100644 +--- a/grub-core/loader/i386/bsd.c ++++ b/grub-core/loader/i386/bsd.c +@@ -269,81 +269,93 @@ struct grub_e820_mmap + #define GRUB_E820_NVS 4 + #define GRUB_E820_BADRAM 5 + +-static void +-generate_e820_mmap (grub_size_t *len, grub_size_t *cnt, void *buf) ++/* Context for generate_e820_mmap. */ ++struct generate_e820_mmap_ctx + { +- int count = 0; +- struct grub_e820_mmap *mmap = buf; ++ int count; ++ struct grub_e820_mmap *mmap; + struct grub_e820_mmap prev, cur; ++}; + +- auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, +- grub_memory_type_t); +- int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, +- grub_memory_type_t type) +- { +- cur.addr = addr; +- cur.size = size; +- switch (type) +- { +- case GRUB_MEMORY_AVAILABLE: +- cur.type = GRUB_E820_RAM; +- break; +- +- case GRUB_MEMORY_ACPI: +- cur.type = GRUB_E820_ACPI; +- break; ++/* Helper for generate_e820_mmap. */ ++static int ++generate_e820_mmap_iter (grub_uint64_t addr, grub_uint64_t size, ++ grub_memory_type_t type, void *data) ++{ ++ struct generate_e820_mmap_ctx *ctx = data; + +- case GRUB_MEMORY_NVS: +- cur.type = GRUB_E820_NVS; +- break; ++ ctx->cur.addr = addr; ++ ctx->cur.size = size; ++ switch (type) ++ { ++ case GRUB_MEMORY_AVAILABLE: ++ ctx->cur.type = GRUB_E820_RAM; ++ break; ++ ++ case GRUB_MEMORY_ACPI: ++ ctx->cur.type = GRUB_E820_ACPI; ++ break; ++ ++ case GRUB_MEMORY_NVS: ++ ctx->cur.type = GRUB_E820_NVS; ++ break; ++ ++ default: ++ case GRUB_MEMORY_CODE: ++ case GRUB_MEMORY_RESERVED: ++ ctx->cur.type = GRUB_E820_RESERVED; ++ break; ++ } + +- default: +- case GRUB_MEMORY_CODE: +- case GRUB_MEMORY_RESERVED: +- cur.type = GRUB_E820_RESERVED; +- break; +- } ++ /* Merge regions if possible. */ ++ if (ctx->count && ctx->cur.type == ctx->prev.type ++ && ctx->cur.addr == ctx->prev.addr + ctx->prev.size) ++ { ++ ctx->prev.size += ctx->cur.size; ++ if (ctx->mmap) ++ ctx->mmap[-1] = ctx->prev; ++ } ++ else ++ { ++ if (ctx->mmap) ++ *ctx->mmap++ = ctx->cur; ++ ctx->prev = ctx->cur; ++ ctx->count++; ++ } + +- /* Merge regions if possible. */ +- if (count && cur.type == prev.type && cur.addr == prev.addr + prev.size) +- { +- prev.size += cur.size; +- if (mmap) +- mmap[-1] = prev; +- } +- else ++ if (kernel_type == KERNEL_TYPE_OPENBSD && ctx->prev.addr < 0x100000 ++ && ctx->prev.addr + ctx->prev.size > 0x100000) ++ { ++ ctx->cur.addr = 0x100000; ++ ctx->cur.size = ctx->prev.addr + ctx->prev.size - 0x100000; ++ ctx->cur.type = ctx->prev.type; ++ ctx->prev.size = 0x100000 - ctx->prev.addr; ++ if (ctx->mmap) + { +- if (mmap) +- *mmap++ = cur; +- prev = cur; +- count++; ++ ctx->mmap[-1] = ctx->prev; ++ ctx->mmap[0] = ctx->cur; ++ ctx->mmap++; + } ++ ctx->prev = ctx->cur; ++ ctx->count++; ++ } + +- if (kernel_type == KERNEL_TYPE_OPENBSD && prev.addr < 0x100000 +- && prev.addr + prev.size > 0x100000) +- { +- cur.addr = 0x100000; +- cur.size = prev.addr + prev.size - 0x100000; +- cur.type = prev.type; +- prev.size = 0x100000 - prev.addr; +- if (mmap) +- { +- mmap[-1] = prev; +- mmap[0] = cur; +- mmap++; +- } +- prev = cur; +- count++; +- } ++ return 0; ++} + +- return 0; +- } ++static void ++generate_e820_mmap (grub_size_t *len, grub_size_t *cnt, void *buf) ++{ ++ struct generate_e820_mmap_ctx ctx = { ++ .count = 0, ++ .mmap = buf ++ }; + +- grub_mmap_iterate (hook); ++ grub_mmap_iterate (generate_e820_mmap_iter, &ctx); + + if (len) +- *len = count * sizeof (struct grub_e820_mmap); +- *cnt = count; ++ *len = ctx.count * sizeof (struct grub_e820_mmap); ++ *cnt = ctx.count; + + return; + } +diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c +index fc0ebe7..41357a5 100644 +--- a/grub-core/loader/i386/linux.c ++++ b/grub-core/loader/i386/linux.c +@@ -150,23 +150,25 @@ find_efi_mmap_size (void) + + #endif + ++/* Helper for find_mmap_size. */ ++static int ++count_hook (grub_uint64_t addr __attribute__ ((unused)), ++ grub_uint64_t size __attribute__ ((unused)), ++ grub_memory_type_t type __attribute__ ((unused)), void *data) ++{ ++ grub_size_t *count = data; ++ ++ (*count)++; ++ return 0; ++} ++ + /* Find the optimal number of pages for the memory map. */ + static grub_size_t + find_mmap_size (void) + { + grub_size_t count = 0, mmap_size; + +- auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, +- grub_memory_type_t); +- int NESTED_FUNC_ATTR hook (grub_uint64_t addr __attribute__ ((unused)), +- grub_uint64_t size __attribute__ ((unused)), +- grub_memory_type_t type __attribute__ ((unused))) +- { +- count++; +- return 0; +- } +- +- grub_mmap_iterate (hook); ++ grub_mmap_iterate (count_hook, &count); + + mmap_size = count * sizeof (struct grub_e820_mmap); + +@@ -372,17 +374,96 @@ grub_linux_setup_video (struct linux_kernel_params *params) + return GRUB_ERR_NONE; + } + ++/* Context for grub_linux_boot. */ ++struct grub_linux_boot_ctx ++{ ++ grub_addr_t real_mode_target; ++ grub_size_t real_size; ++ struct linux_kernel_params *params; ++ int e820_num; ++}; ++ ++/* Helper for grub_linux_boot. */ ++static int ++grub_linux_boot_mmap_find (grub_uint64_t addr, grub_uint64_t size, ++ grub_memory_type_t type, void *data) ++{ ++ struct grub_linux_boot_ctx *ctx = data; ++ ++ /* We must put real mode code in the traditional space. */ ++ if (type != GRUB_MEMORY_AVAILABLE || addr > 0x90000) ++ return 0; ++ ++ if (addr + size < 0x10000) ++ return 0; ++ ++ if (addr < 0x10000) ++ { ++ size += addr - 0x10000; ++ addr = 0x10000; ++ } ++ ++ if (addr + size > 0x90000) ++ size = 0x90000 - addr; ++ ++ if (ctx->real_size + efi_mmap_size > size) ++ return 0; ++ ++ grub_dprintf ("linux", "addr = %lx, size = %x, need_size = %x\n", ++ (unsigned long) addr, ++ (unsigned) size, ++ (unsigned) (ctx->real_size + efi_mmap_size)); ++ ctx->real_mode_target = ((addr + size) - (ctx->real_size + efi_mmap_size)); ++ return 1; ++} ++ ++static int ++grub_linux_boot_mmap_fill (grub_uint64_t addr, grub_uint64_t size, ++ grub_memory_type_t type, void *data) ++{ ++ struct grub_linux_boot_ctx *ctx = data; ++ ++ grub_uint32_t e820_type; ++ switch (type) ++ { ++ case GRUB_MEMORY_AVAILABLE: ++ e820_type = GRUB_E820_RAM; ++ break; ++ ++ case GRUB_MEMORY_ACPI: ++ e820_type = GRUB_E820_ACPI; ++ break; ++ ++ case GRUB_MEMORY_NVS: ++ e820_type = GRUB_E820_NVS; ++ break; ++ ++ case GRUB_MEMORY_BADRAM: ++ e820_type = GRUB_E820_BADRAM; ++ break; ++ ++ default: ++ e820_type = GRUB_E820_RESERVED; ++ } ++ if (grub_e820_add_region (ctx->params->e820_map, &ctx->e820_num, ++ addr, size, e820_type)) ++ return 1; ++ ++ return 0; ++} ++ + static grub_err_t + grub_linux_boot (void) + { +- int e820_num; + grub_err_t err = 0; + const char *modevar; + char *tmp; + struct grub_relocator32_state state; + void *real_mode_mem; +- grub_addr_t real_mode_target = 0; +- grub_size_t real_size, mmap_size; ++ struct grub_linux_boot_ctx ctx = { ++ .real_mode_target = 0 ++ }; ++ grub_size_t mmap_size; + grub_size_t cl_offset; + + #ifdef GRUB_MACHINE_IEEE1275 +@@ -484,7 +565,7 @@ grub_linux_boot (void) + if (cl_offset < ((grub_size_t) linux_params.setup_sects << GRUB_DISK_SECTOR_BITS)) + cl_offset = ALIGN_UP ((grub_size_t) (linux_params.setup_sects + << GRUB_DISK_SECTOR_BITS), 4096); +- real_size = ALIGN_UP (cl_offset + maximal_cmdline_size, 4096); ++ ctx.real_size = ALIGN_UP (cl_offset + maximal_cmdline_size, 4096); + + #ifdef GRUB_MACHINE_EFI + efi_mmap_size = find_efi_mmap_size (); +@@ -493,118 +574,51 @@ grub_linux_boot (void) + #endif + + grub_dprintf ("linux", "real_size = %x, mmap_size = %x\n", +- (unsigned) real_size, (unsigned) mmap_size); +- +- auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, +- grub_memory_type_t); +- int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, +- grub_memory_type_t type) +- { +- /* We must put real mode code in the traditional space. */ +- if (type != GRUB_MEMORY_AVAILABLE || addr > 0x90000) +- return 0; +- +- if (addr + size < 0x10000) +- return 0; +- +- if (addr < 0x10000) +- { +- size += addr - 0x10000; +- addr = 0x10000; +- } ++ (unsigned) ctx.real_size, (unsigned) mmap_size); + +- if (addr + size > 0x90000) +- size = 0x90000 - addr; +- +- if (real_size + efi_mmap_size > size) +- return 0; +- +- grub_dprintf ("linux", "addr = %lx, size = %x, need_size = %x\n", +- (unsigned long) addr, +- (unsigned) size, +- (unsigned) (real_size + efi_mmap_size)); +- real_mode_target = ((addr + size) - (real_size + efi_mmap_size)); +- return 1; +- } + #ifdef GRUB_MACHINE_EFI +- grub_efi_mmap_iterate (hook, 1); +- if (! real_mode_target) +- grub_efi_mmap_iterate (hook, 0); ++ grub_efi_mmap_iterate (grub_linux_boot_mmap_find, &ctx, 1); ++ if (! ctx.real_mode_target) ++ grub_efi_mmap_iterate (grub_linux_boot_mmap_find, &ctx, 0); + #else +- grub_mmap_iterate (hook); ++ grub_mmap_iterate (grub_linux_boot_mmap_find, &ctx); + #endif + grub_dprintf ("linux", "real_mode_target = %lx, real_size = %x, efi_mmap_size = %x\n", +- (unsigned long) real_mode_target, +- (unsigned) real_size, ++ (unsigned long) ctx.real_mode_target, ++ (unsigned) ctx.real_size, + (unsigned) efi_mmap_size); + +- if (! real_mode_target) ++ if (! ctx.real_mode_target) + return grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate real mode pages"); + + { + grub_relocator_chunk_t ch; + err = grub_relocator_alloc_chunk_addr (relocator, &ch, +- real_mode_target, +- (real_size + efi_mmap_size)); ++ ctx.real_mode_target, ++ (ctx.real_size + efi_mmap_size)); + if (err) + return err; + real_mode_mem = get_virtual_current_address (ch); + } +- efi_mmap_buf = (grub_uint8_t *) real_mode_mem + real_size; ++ efi_mmap_buf = (grub_uint8_t *) real_mode_mem + ctx.real_size; + + grub_dprintf ("linux", "real_mode_mem = %lx\n", + (unsigned long) real_mode_mem); + +- struct linux_kernel_params *params; +- +- params = real_mode_mem; ++ ctx.params = real_mode_mem; + +- *params = linux_params; +- params->cmd_line_ptr = real_mode_target + cl_offset; +- grub_memcpy ((char *) params + cl_offset, linux_cmdline, ++ *ctx.params = linux_params; ++ ctx.params->cmd_line_ptr = ctx.real_mode_target + cl_offset; ++ grub_memcpy ((char *) ctx.params + cl_offset, linux_cmdline, + maximal_cmdline_size); + + grub_dprintf ("linux", "code32_start = %x\n", +- (unsigned) params->code32_start); +- +- auto int NESTED_FUNC_ATTR hook_fill (grub_uint64_t, grub_uint64_t, +- grub_memory_type_t); +- int NESTED_FUNC_ATTR hook_fill (grub_uint64_t addr, grub_uint64_t size, +- grub_memory_type_t type) +- { +- grub_uint32_t e820_type; +- switch (type) +- { +- case GRUB_MEMORY_AVAILABLE: +- e820_type = GRUB_E820_RAM; +- break; +- +- case GRUB_MEMORY_ACPI: +- e820_type = GRUB_E820_ACPI; +- break; +- +- case GRUB_MEMORY_NVS: +- e820_type = GRUB_E820_NVS; +- break; +- +- case GRUB_MEMORY_BADRAM: +- e820_type = GRUB_E820_BADRAM; +- break; +- +- default: +- e820_type = GRUB_E820_RESERVED; +- } +- if (grub_e820_add_region (params->e820_map, &e820_num, +- addr, size, e820_type)) +- return 1; +- +- return 0; +- } ++ (unsigned) ctx.params->code32_start); + +- e820_num = 0; +- if (grub_mmap_iterate (hook_fill)) ++ ctx.e820_num = 0; ++ if (grub_mmap_iterate (grub_linux_boot_mmap_fill, &ctx)) + return grub_errno; +- params->mmap_size = e820_num; ++ ctx.params->mmap_size = ctx.e820_num; + + #ifdef GRUB_MACHINE_EFI + { +@@ -617,33 +631,33 @@ grub_linux_boot (void) + return err; + + /* Note that no boot services are available from here. */ +- efi_mmap_target = real_mode_target ++ efi_mmap_target = ctx.real_mode_target + + ((grub_uint8_t *) efi_mmap_buf - (grub_uint8_t *) real_mode_mem); + /* Pass EFI parameters. */ +- if (grub_le_to_cpu16 (params->version) >= 0x0208) ++ if (grub_le_to_cpu16 (ctx.params->version) >= 0x0208) + { +- params->v0208.efi_mem_desc_size = efi_desc_size; +- params->v0208.efi_mem_desc_version = efi_desc_version; +- params->v0208.efi_mmap = efi_mmap_target; +- params->v0208.efi_mmap_size = efi_mmap_size; ++ ctx.params->v0208.efi_mem_desc_size = efi_desc_size; ++ ctx.params->v0208.efi_mem_desc_version = efi_desc_version; ++ ctx.params->v0208.efi_mmap = efi_mmap_target; ++ ctx.params->v0208.efi_mmap_size = efi_mmap_size; + + #ifdef __x86_64__ +- params->v0208.efi_mmap_hi = (efi_mmap_target >> 32); ++ ctx.params->v0208.efi_mmap_hi = (efi_mmap_target >> 32); + #endif + } +- else if (grub_le_to_cpu16 (params->version) >= 0x0206) ++ else if (grub_le_to_cpu16 (ctx.params->version) >= 0x0206) + { +- params->v0206.efi_mem_desc_size = efi_desc_size; +- params->v0206.efi_mem_desc_version = efi_desc_version; +- params->v0206.efi_mmap = efi_mmap_target; +- params->v0206.efi_mmap_size = efi_mmap_size; ++ ctx.params->v0206.efi_mem_desc_size = efi_desc_size; ++ ctx.params->v0206.efi_mem_desc_version = efi_desc_version; ++ ctx.params->v0206.efi_mmap = efi_mmap_target; ++ ctx.params->v0206.efi_mmap_size = efi_mmap_size; + } +- else if (grub_le_to_cpu16 (params->version) >= 0x0204) ++ else if (grub_le_to_cpu16 (ctx.params->version) >= 0x0204) + { +- params->v0204.efi_mem_desc_size = efi_desc_size; +- params->v0204.efi_mem_desc_version = efi_desc_version; +- params->v0204.efi_mmap = efi_mmap_target; +- params->v0204.efi_mmap_size = efi_mmap_size; ++ ctx.params->v0204.efi_mem_desc_size = efi_desc_size; ++ ctx.params->v0204.efi_mem_desc_version = efi_desc_version; ++ ctx.params->v0204.efi_mmap = efi_mmap_target; ++ ctx.params->v0204.efi_mmap_size = efi_mmap_size; + } + } + #endif +@@ -651,9 +665,9 @@ grub_linux_boot (void) + /* FIXME. */ + /* asm volatile ("lidt %0" : : "m" (idt_desc)); */ + state.ebp = state.edi = state.ebx = 0; +- state.esi = real_mode_target; +- state.esp = real_mode_target; +- state.eip = params->code32_start; ++ state.esi = ctx.real_mode_target; ++ state.esp = ctx.real_mode_target; ++ state.eip = ctx.params->code32_start; + return grub_relocator32_boot (relocator, state, 0); + } + +diff --git a/grub-core/loader/i386/multiboot_mbi.c b/grub-core/loader/i386/multiboot_mbi.c +index 8fc40d7..18fd367 100644 +--- a/grub-core/loader/i386/multiboot_mbi.c ++++ b/grub-core/loader/i386/multiboot_mbi.c +@@ -224,48 +224,50 @@ grub_multiboot_get_mbi_size (void) + return ret; + } + ++/* Helper for grub_fill_multiboot_mmap. */ ++static int ++grub_fill_multiboot_mmap_iter (grub_uint64_t addr, grub_uint64_t size, ++ grub_memory_type_t type, void *data) ++{ ++ struct multiboot_mmap_entry **mmap_entry = data; ++ ++ (*mmap_entry)->addr = addr; ++ (*mmap_entry)->len = size; ++ switch (type) ++ { ++ case GRUB_MEMORY_AVAILABLE: ++ (*mmap_entry)->type = MULTIBOOT_MEMORY_AVAILABLE; ++ break; ++ ++ case GRUB_MEMORY_ACPI: ++ (*mmap_entry)->type = MULTIBOOT_MEMORY_ACPI_RECLAIMABLE; ++ break; ++ ++ case GRUB_MEMORY_NVS: ++ (*mmap_entry)->type = MULTIBOOT_MEMORY_NVS; ++ break; ++ ++ case GRUB_MEMORY_BADRAM: ++ (*mmap_entry)->type = MULTIBOOT_MEMORY_BADRAM; ++ 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; ++} ++ + /* 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_memory_type_t); +- int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, +- grub_memory_type_t type) +- { +- mmap_entry->addr = addr; +- mmap_entry->len = size; +- switch (type) +- { +- case GRUB_MEMORY_AVAILABLE: +- mmap_entry->type = MULTIBOOT_MEMORY_AVAILABLE; +- break; +- +- case GRUB_MEMORY_ACPI: +- mmap_entry->type = MULTIBOOT_MEMORY_ACPI_RECLAIMABLE; +- break; +- +- case GRUB_MEMORY_NVS: +- mmap_entry->type = MULTIBOOT_MEMORY_NVS; +- break; +- +- case GRUB_MEMORY_BADRAM: +- mmap_entry->type = MULTIBOOT_MEMORY_BADRAM; +- 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_mmap_iterate (grub_fill_multiboot_mmap_iter, &mmap_entry); + } + + #if GRUB_MACHINE_HAS_VBE || GRUB_MACHINE_HAS_VGA_TEXT +diff --git a/grub-core/loader/multiboot.c b/grub-core/loader/multiboot.c +index fcdf5ff..496e54c 100644 +--- a/grub-core/loader/multiboot.c ++++ b/grub-core/loader/multiboot.c +@@ -63,6 +63,18 @@ static int console_required; + static grub_dl_t my_mod; + + ++/* Helper for grub_get_multiboot_mmap_count. */ ++static int ++count_hook (grub_uint64_t addr __attribute__ ((unused)), ++ grub_uint64_t size __attribute__ ((unused)), ++ grub_memory_type_t type __attribute__ ((unused)), void *data) ++{ ++ grub_size_t *count = data; ++ ++ (*count)++; ++ return 0; ++} ++ + /* Return the length of the Multiboot mmap that will be needed to allocate + our platform's map. */ + grub_uint32_t +@@ -70,16 +82,7 @@ grub_get_multiboot_mmap_count (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_memory_type_t type __attribute__ ((unused))) +- { +- count++; +- return 0; +- } +- +- grub_mmap_iterate (hook); ++ grub_mmap_iterate (count_hook, &count); + + return count; + } +diff --git a/grub-core/loader/multiboot_mbi2.c b/grub-core/loader/multiboot_mbi2.c +index a48f020..900793a 100644 +--- a/grub-core/loader/multiboot_mbi2.c ++++ b/grub-core/loader/multiboot_mbi2.c +@@ -322,45 +322,47 @@ grub_multiboot_get_mbi_size (void) + + sizeof (struct multiboot_tag_apm) + MULTIBOOT_TAG_ALIGN - 1; + } + +-/* Fill previously allocated Multiboot mmap. */ +-static void +-grub_fill_multiboot_mmap (struct multiboot_tag_mmap *tag) ++/* Helper for grub_fill_multiboot_mmap. */ ++static int ++grub_fill_multiboot_mmap_iter (grub_uint64_t addr, grub_uint64_t size, ++ grub_memory_type_t type, void *data) + { +- struct multiboot_mmap_entry *mmap_entry = tag->entries; ++ struct multiboot_mmap_entry **mmap_entry = data; + +- auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, +- grub_memory_type_t); +- int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, +- grub_memory_type_t type) ++ (*mmap_entry)->addr = addr; ++ (*mmap_entry)->len = size; ++ switch (type) + { +- mmap_entry->addr = addr; +- mmap_entry->len = size; +- switch (type) +- { +- case GRUB_MEMORY_AVAILABLE: +- mmap_entry->type = MULTIBOOT_MEMORY_AVAILABLE; +- break; +- +- case GRUB_MEMORY_ACPI: +- mmap_entry->type = MULTIBOOT_MEMORY_ACPI_RECLAIMABLE; +- break; ++ case GRUB_MEMORY_AVAILABLE: ++ (*mmap_entry)->type = MULTIBOOT_MEMORY_AVAILABLE; ++ break; + +- case GRUB_MEMORY_NVS: +- mmap_entry->type = MULTIBOOT_MEMORY_NVS; +- break; ++ case GRUB_MEMORY_ACPI: ++ (*mmap_entry)->type = MULTIBOOT_MEMORY_ACPI_RECLAIMABLE; ++ break; + +- case GRUB_MEMORY_BADRAM: +- mmap_entry->type = MULTIBOOT_MEMORY_BADRAM; +- break; ++ case GRUB_MEMORY_NVS: ++ (*mmap_entry)->type = MULTIBOOT_MEMORY_NVS; ++ break; + +- default: +- mmap_entry->type = MULTIBOOT_MEMORY_RESERVED; +- break; +- } +- mmap_entry++; ++ case GRUB_MEMORY_BADRAM: ++ (*mmap_entry)->type = MULTIBOOT_MEMORY_BADRAM; ++ break; + +- return 0; ++ default: ++ (*mmap_entry)->type = MULTIBOOT_MEMORY_RESERVED; ++ break; + } ++ (*mmap_entry)++; ++ ++ return 0; ++} ++ ++/* Fill previously allocated Multiboot mmap. */ ++static void ++grub_fill_multiboot_mmap (struct multiboot_tag_mmap *tag) ++{ ++ struct multiboot_mmap_entry *mmap_entry = tag->entries; + + tag->type = MULTIBOOT_TAG_TYPE_MMAP; + tag->size = sizeof (struct multiboot_tag_mmap) +@@ -368,7 +370,7 @@ grub_fill_multiboot_mmap (struct multiboot_tag_mmap *tag) + tag->entry_size = sizeof (struct multiboot_mmap_entry); + tag->entry_version = 0; + +- grub_mmap_iterate (hook); ++ grub_mmap_iterate (grub_fill_multiboot_mmap_iter, &mmap_entry); + } + + #if defined (GRUB_MACHINE_PCBIOS) +diff --git a/grub-core/loader/powerpc/ieee1275/linux.c b/grub-core/loader/powerpc/ieee1275/linux.c +index 70e288c..b150904 100644 +--- a/grub-core/loader/powerpc/ieee1275/linux.c ++++ b/grub-core/loader/powerpc/ieee1275/linux.c +@@ -51,49 +51,51 @@ static char *linux_args; + typedef void (*kernel_entry_t) (void *, unsigned long, int (void *), + unsigned long, unsigned long); + ++/* Helper for grub_linux_claimmap_iterate. */ ++static int ++alloc_mem (grub_uint64_t addr, grub_uint64_t len, grub_memory_type_t type, ++ void *data) ++{ ++ grub_addr_t *found_addr = data; ++ ++ grub_uint64_t end = addr + len; ++ addr = ALIGN_UP (addr, align); ++ target = ALIGN_UP (target, align); ++ ++ /* Target above the memory chunk. */ ++ if (type != GRUB_MEMORY_AVAILABLE || target > end) ++ return 0; ++ ++ /* Target inside the memory chunk. */ ++ if (target >= addr && target < end && size <= end - target) ++ { ++ if (grub_claimmap (target, size) == GRUB_ERR_NONE) ++ { ++ *found_addr = target; ++ return 1; ++ } ++ grub_print_error (); ++ } ++ /* Target below the memory chunk. */ ++ if (target < addr && addr + size <= end) ++ { ++ if (grub_claimmap (addr, size) == GRUB_ERR_NONE) ++ { ++ *found_addr = addr; ++ return 1; ++ } ++ grub_print_error (); ++ } ++ return 0; ++} ++ + static grub_addr_t + grub_linux_claimmap_iterate (grub_addr_t target, grub_size_t size, + grub_size_t align) + { + grub_addr_t found_addr = (grub_addr_t) -1; + +- auto int NESTED_FUNC_ATTR alloc_mem (grub_uint64_t addr, grub_uint64_t len, +- grub_memory_type_t type); +- int NESTED_FUNC_ATTR alloc_mem (grub_uint64_t addr, grub_uint64_t len, +- grub_memory_type_t type) +- { +- grub_uint64_t end = addr + len; +- addr = ALIGN_UP (addr, align); +- target = ALIGN_UP (target, align); +- +- /* Target above the memory chunk. */ +- if (type != GRUB_MEMORY_AVAILABLE || target > end) +- return 0; +- +- /* Target inside the memory chunk. */ +- if (target >= addr && target < end && size <= end - target) +- { +- if (grub_claimmap (target, size) == GRUB_ERR_NONE) +- { +- found_addr = target; +- return 1; +- } +- grub_print_error (); +- } +- /* Target below the memory chunk. */ +- if (target < addr && addr + size <= end) +- { +- if (grub_claimmap (addr, size) == GRUB_ERR_NONE) +- { +- found_addr = addr; +- return 1; +- } +- grub_print_error (); +- } +- return 0; +- } +- +- grub_machine_mmap_iterate (alloc_mem); ++ grub_machine_mmap_iterate (alloc_mem, &found_addr); + + return found_addr; + } +diff --git a/grub-core/loader/sparc64/ieee1275/linux.c b/grub-core/loader/sparc64/ieee1275/linux.c +index 06d1df6..a485284 100644 +--- a/grub-core/loader/sparc64/ieee1275/linux.c ++++ b/grub-core/loader/sparc64/ieee1275/linux.c +@@ -180,63 +180,64 @@ grub_linux_unload (void) + + #define FOUR_MB (4 * 1024 * 1024) + +-static grub_addr_t +-alloc_phys (grub_addr_t size) ++/* Helper for alloc_phys. */ ++static int ++alloc_phys_choose (grub_uint64_t addr, grub_uint64_t len, ++ grub_memory_type_t type, void *data) + { +- grub_addr_t ret = (grub_addr_t) -1; ++ grub_addr_t *ret = data; ++ grub_addr_t end = addr + len; + +- auto int NESTED_FUNC_ATTR choose (grub_uint64_t addr, grub_uint64_t len, +- grub_memory_type_t type); +- int NESTED_FUNC_ATTR choose (grub_uint64_t addr, grub_uint64_t len, +- grub_memory_type_t type) +- { +- grub_addr_t end = addr + len; ++ if (type != 1) ++ return 0; + +- if (type != 1) +- return 0; ++ addr = ALIGN_UP (addr, FOUR_MB); ++ if (addr + size >= end) ++ return 0; + +- addr = ALIGN_UP (addr, FOUR_MB); +- if (addr + size >= end) +- return 0; ++ if (addr >= grub_phys_start && addr < grub_phys_end) ++ { ++ 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_UP (grub_phys_end, FOUR_MB); ++ if (addr + size >= end) ++ return 0; ++ } + +- if (addr >= grub_phys_start && addr < grub_phys_end) +- { +- 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_UP (grub_phys_end, FOUR_MB); +- if (addr + size >= end) +- return 0; +- } +- +- if (loaded) +- { +- grub_addr_t linux_end = ALIGN_UP (linux_paddr + linux_size, FOUR_MB); +- +- if (addr >= linux_paddr && addr < linux_end) +- { +- addr = linux_end; +- if (addr + size >= end) +- return 0; +- } +- if ((addr + size) >= linux_paddr +- && (addr + size) < linux_end) +- { +- addr = linux_end; +- if (addr + size >= end) +- return 0; +- } +- } +- +- ret = addr; +- return 1; +- } +- +- grub_machine_mmap_iterate (choose); ++ if (loaded) ++ { ++ grub_addr_t linux_end = ALIGN_UP (linux_paddr + linux_size, FOUR_MB); ++ ++ if (addr >= linux_paddr && addr < linux_end) ++ { ++ addr = linux_end; ++ if (addr + size >= end) ++ return 0; ++ } ++ if ((addr + size) >= linux_paddr ++ && (addr + size) < linux_end) ++ { ++ addr = linux_end; ++ if (addr + size >= end) ++ return 0; ++ } ++ } ++ ++ *ret = addr; ++ return 1; ++} ++ ++static grub_addr_t ++alloc_phys (grub_addr_t size) ++{ ++ grub_addr_t ret = (grub_addr_t) -1; ++ ++ grub_machine_mmap_iterate (alloc_phys_choose, &ret); + + return ret; + } +@@ -454,21 +455,23 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), + return grub_errno; + } + +-static void +-determine_phys_base (void) ++/* Helper for determine_phys_base. */ ++static int ++get_physbase (grub_uint64_t addr, grub_uint64_t len __attribute__ ((unused)), ++ grub_uint32_t type, void *data __attribute__ ((unused))) + { +- auto int NESTED_FUNC_ATTR get_physbase (grub_uint64_t addr, grub_uint64_t len __attribute__((unused)), grub_uint32_t type); +- int NESTED_FUNC_ATTR get_physbase (grub_uint64_t addr, grub_uint64_t len __attribute__((unused)), grub_uint32_t type) +- { +- if (type != 1) +- return 0; +- if (addr < phys_base) +- phys_base = addr; ++ if (type != 1) + return 0; +- } ++ if (addr < phys_base) ++ phys_base = addr; ++ return 0; ++} + ++static void ++determine_phys_base (void) ++{ + phys_base = ~(grub_uint64_t) 0; +- grub_machine_mmap_iterate (get_physbase); ++ grub_machine_mmap_iterate (get_physbase, NULL); + } + + static void +diff --git a/grub-core/mmap/efi/mmap.c b/grub-core/mmap/efi/mmap.c +index c71adad..4f17c8b 100644 +--- a/grub-core/mmap/efi/mmap.c ++++ b/grub-core/mmap/efi/mmap.c +@@ -29,7 +29,8 @@ + ((grub_efi_memory_descriptor_t *) ((char *) (desc) + (size))) + + grub_err_t +-grub_efi_mmap_iterate (grub_memory_hook_t hook, int avoid_efi_boot_services) ++grub_efi_mmap_iterate (grub_memory_hook_t hook, void *hook_data, ++ int avoid_efi_boot_services) + { + grub_efi_uintn_t mmap_size = 0; + grub_efi_memory_descriptor_t *map_buf = 0; +@@ -69,17 +70,17 @@ grub_efi_mmap_iterate (grub_memory_hook_t hook, int avoid_efi_boot_services) + if (!avoid_efi_boot_services) + { + hook (desc->physical_start, desc->num_pages * 4096, +- GRUB_MEMORY_AVAILABLE); ++ GRUB_MEMORY_AVAILABLE, hook_data); + break; + } + case GRUB_EFI_RUNTIME_SERVICES_CODE: + hook (desc->physical_start, desc->num_pages * 4096, +- GRUB_MEMORY_CODE); ++ GRUB_MEMORY_CODE, hook_data); + break; + + case GRUB_EFI_UNUSABLE_MEMORY: + hook (desc->physical_start, desc->num_pages * 4096, +- GRUB_MEMORY_BADRAM); ++ GRUB_MEMORY_BADRAM, hook_data); + break; + + default: +@@ -90,7 +91,7 @@ grub_efi_mmap_iterate (grub_memory_hook_t hook, int avoid_efi_boot_services) + if (!avoid_efi_boot_services) + { + hook (desc->physical_start, desc->num_pages * 4096, +- GRUB_MEMORY_AVAILABLE); ++ GRUB_MEMORY_AVAILABLE, hook_data); + break; + } + case GRUB_EFI_RESERVED_MEMORY_TYPE: +@@ -99,24 +100,24 @@ grub_efi_mmap_iterate (grub_memory_hook_t hook, int avoid_efi_boot_services) + case GRUB_EFI_MEMORY_MAPPED_IO_PORT_SPACE: + case GRUB_EFI_PAL_CODE: + hook (desc->physical_start, desc->num_pages * 4096, +- GRUB_MEMORY_RESERVED); ++ GRUB_MEMORY_RESERVED, hook_data); + break; + + case GRUB_EFI_LOADER_CODE: + case GRUB_EFI_LOADER_DATA: + case GRUB_EFI_CONVENTIONAL_MEMORY: + hook (desc->physical_start, desc->num_pages * 4096, +- GRUB_MEMORY_AVAILABLE); ++ GRUB_MEMORY_AVAILABLE, hook_data); + break; + + case GRUB_EFI_ACPI_RECLAIM_MEMORY: + hook (desc->physical_start, desc->num_pages * 4096, +- GRUB_MEMORY_ACPI); ++ GRUB_MEMORY_ACPI, hook_data); + break; + + case GRUB_EFI_ACPI_MEMORY_NVS: + hook (desc->physical_start, desc->num_pages * 4096, +- GRUB_MEMORY_NVS); ++ GRUB_MEMORY_NVS, hook_data); + break; + } + } +@@ -125,9 +126,9 @@ grub_efi_mmap_iterate (grub_memory_hook_t hook, int avoid_efi_boot_services) + } + + grub_err_t +-grub_machine_mmap_iterate (grub_memory_hook_t hook) ++grub_machine_mmap_iterate (grub_memory_hook_t hook, void *hook_data) + { +- return grub_efi_mmap_iterate (hook, 0); ++ return grub_efi_mmap_iterate (hook, hook_data, 0); + } + + static inline grub_efi_memory_type_t +diff --git a/grub-core/mmap/i386/mmap.c b/grub-core/mmap/i386/mmap.c +index 648a7df..ac45f70 100644 +--- a/grub-core/mmap/i386/mmap.c ++++ b/grub-core/mmap/i386/mmap.c +@@ -27,34 +27,48 @@ + + #ifndef GRUB_MMAP_REGISTER_BY_FIRMWARE + ++/* Context for grub_mmap_malign_and_register. */ ++struct grub_mmap_malign_and_register_ctx ++{ ++ grub_uint64_t align, size, highestlow; ++}; ++ ++/* Helper for grub_mmap_malign_and_register. */ ++static int ++find_hook (grub_uint64_t start, grub_uint64_t rangesize, ++ grub_memory_type_t memtype, void *data) ++{ ++ struct grub_mmap_malign_and_register_ctx *ctx = data; ++ grub_uint64_t end = start + rangesize; ++ ++ if (memtype != GRUB_MEMORY_AVAILABLE) ++ return 0; ++ if (end > 0x100000) ++ end = 0x100000; ++ if (end > start + ctx->size ++ && ctx->highestlow < ((end - ctx->size) ++ - ((end - ctx->size) & (ctx->align - 1)))) ++ ctx->highestlow = (end - ctx->size) ++ - ((end - ctx->size) & (ctx->align - 1)); ++ return 0; ++} ++ + void * + grub_mmap_malign_and_register (grub_uint64_t align, grub_uint64_t size, + int *handle, int type, int flags) + { +- grub_uint64_t highestlow = 0; +- +- auto int NESTED_FUNC_ATTR find_hook (grub_uint64_t, grub_uint64_t, +- grub_memory_type_t); +- int NESTED_FUNC_ATTR find_hook (grub_uint64_t start, grub_uint64_t rangesize, +- grub_memory_type_t memtype) +- { +- grub_uint64_t end = start + rangesize; +- if (memtype != GRUB_MEMORY_AVAILABLE) +- return 0; +- if (end > 0x100000) +- end = 0x100000; +- if (end > start + size +- && highestlow < ((end - size) - ((end - size) & (align - 1)))) +- highestlow = (end - size) - ((end - size) & (align - 1)); +- return 0; +- } ++ struct grub_mmap_malign_and_register_ctx ctx = { ++ .align = align, ++ .size = size, ++ .highestlow = 0 ++ }; + + void *ret; + if (flags & GRUB_MMAP_MALLOC_LOW) + { + /* FIXME: use low-memory mm allocation once it's available. */ +- grub_mmap_iterate (find_hook); +- ret = (void *) (grub_addr_t) highestlow; ++ grub_mmap_iterate (find_hook, &ctx); ++ ret = (void *) (grub_addr_t) ctx.highestlow; + } + else + ret = grub_memalign (align, size); +diff --git a/grub-core/mmap/i386/pc/mmap.c b/grub-core/mmap/i386/pc/mmap.c +index 12ae4a4..983e220 100644 +--- a/grub-core/mmap/i386/pc/mmap.c ++++ b/grub-core/mmap/i386/pc/mmap.c +@@ -50,22 +50,23 @@ struct grub_e820_mmap_entry + } __attribute__((packed)); + + ++/* Helper for preboot. */ ++static int fill_hook (grub_uint64_t addr, grub_uint64_t size, ++ grub_memory_type_t type, void *data) ++{ ++ struct grub_e820_mmap_entry **hookmmapcur = data; ++ grub_dprintf ("mmap", "mmap chunk %llx-%llx:%x\n", addr, addr + size, type); ++ (*hookmmapcur)->addr = addr; ++ (*hookmmapcur)->len = size; ++ (*hookmmapcur)->type = type; ++ (*hookmmapcur)++; ++ return 0; ++} ++ + static grub_err_t + preboot (int noreturn __attribute__ ((unused))) + { + struct grub_e820_mmap_entry *hookmmap, *hookmmapcur; +- auto int NESTED_FUNC_ATTR fill_hook (grub_uint64_t, grub_uint64_t, +- grub_uint32_t); +- int NESTED_FUNC_ATTR fill_hook (grub_uint64_t addr, grub_uint64_t size, +- grub_memory_type_t type) +- { +- grub_dprintf ("mmap", "mmap chunk %llx-%llx:%x\n", addr, addr + size, type); +- hookmmapcur->addr = addr; +- hookmmapcur->len = size; +- hookmmapcur->type = type; +- hookmmapcur++; +- return 0; +- } + + if (! hooktarget) + return grub_error (GRUB_ERR_OUT_OF_MEMORY, +@@ -77,7 +78,7 @@ preboot (int noreturn __attribute__ ((unused))) + ((grub_uint8_t *) hooktarget + (&grub_machine_mmaphook_end + - &grub_machine_mmaphook_start)); + +- grub_mmap_iterate (fill_hook); ++ grub_mmap_iterate (fill_hook, &hookmmapcur); + grub_machine_mmaphook_mmap_num = hookmmapcur - hookmmap; + + grub_machine_mmaphook_kblow = grub_mmap_get_lower () >> 10; +@@ -123,6 +124,17 @@ preboot_rest (void) + return GRUB_ERR_NONE; + } + ++/* Helper for malloc_hook. */ ++static int ++count_hook (grub_uint64_t addr __attribute__ ((unused)), ++ grub_uint64_t size __attribute__ ((unused)), ++ grub_memory_type_t type __attribute__ ((unused)), void *data) ++{ ++ int *regcount = data; ++ (*regcount)++; ++ return 0; ++} ++ + static grub_err_t + malloc_hook (void) + { +@@ -131,22 +143,13 @@ malloc_hook (void) + static int slots_available = 0; + int hooksize; + int regcount = 0; +- auto int NESTED_FUNC_ATTR count_hook (grub_uint64_t, grub_uint64_t, +- grub_uint32_t); +- int NESTED_FUNC_ATTR count_hook (grub_uint64_t addr __attribute__ ((unused)), +- grub_uint64_t size __attribute__ ((unused)), +- grub_memory_type_t type __attribute__ ((unused))) +- { +- regcount++; +- return 0; +- } + + if (reentry) + return GRUB_ERR_NONE; + + grub_dprintf ("mmap", "registering\n"); + +- grub_mmap_iterate (count_hook); ++ grub_mmap_iterate (count_hook, ®count); + + /* Mapping hook itself may introduce up to 2 additional regions. */ + regcount += 2; +diff --git a/grub-core/mmap/i386/uppermem.c b/grub-core/mmap/i386/uppermem.c +index 2aa4301..bd8b429 100644 +--- a/grub-core/mmap/i386/uppermem.c ++++ b/grub-core/mmap/i386/uppermem.c +@@ -22,68 +22,73 @@ + #include + #include + ++/* Helper for grub_mmap_get_lower. */ ++static int ++lower_hook (grub_uint64_t addr, grub_uint64_t size, grub_memory_type_t type, ++ void *data) ++{ ++ grub_uint64_t *lower = data; ++ ++ if (type != GRUB_MEMORY_AVAILABLE) ++ return 0; ++ if (addr == 0) ++ *lower = size; ++ return 0; ++} ++ + 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_memory_type_t); +- int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, +- grub_memory_type_t type) +- { +- if (type != GRUB_MEMORY_AVAILABLE) +- return 0; +- if (addr == 0) +- lower = size; +- return 0; +- } +- +- grub_mmap_iterate (hook); ++ grub_mmap_iterate (lower_hook, &lower); + if (lower > 0x100000) + lower = 0x100000; + return lower; + } + ++/* Helper for grub_mmap_get_upper. */ ++static int ++upper_hook (grub_uint64_t addr, grub_uint64_t size, grub_memory_type_t type, ++ void *data) ++{ ++ grub_uint64_t *upper = data; ++ ++ if (type != GRUB_MEMORY_AVAILABLE) ++ return 0; ++ if (addr <= 0x100000 && addr + size > 0x100000) ++ *upper = addr + size - 0x100000; ++ return 0; ++} ++ + 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_memory_type_t); +- int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, +- grub_memory_type_t type) +- { +- if (type != GRUB_MEMORY_AVAILABLE) +- return 0; +- if (addr <= 0x100000 && addr + size > 0x100000) +- upper = addr + size - 0x100000; +- return 0; +- } +- +- grub_mmap_iterate (hook); ++ grub_mmap_iterate (upper_hook, &upper); + return upper; + } + ++/* Helper for grub_mmap_get_post64. */ ++static int ++post64_hook (grub_uint64_t addr, grub_uint64_t size, grub_memory_type_t type, ++ void *data) ++{ ++ grub_uint64_t *post64 = data; ++ if (type != GRUB_MEMORY_AVAILABLE) ++ return 0; ++ if (addr <= 0x4000000 && addr + size > 0x4000000) ++ *post64 = addr + size - 0x4000000; ++ return 0; ++} ++ + /* Count the continuous bytes after 64 MiB. */ + grub_uint64_t + grub_mmap_get_post64 (void) + { + grub_uint64_t post64 = 0; + +- auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, +- grub_memory_type_t); +- int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, +- grub_memory_type_t type) +- { +- if (type != GRUB_MEMORY_AVAILABLE) +- return 0; +- if (addr <= 0x4000000 && addr + size > 0x4000000) +- post64 = addr + size - 0x4000000; +- return 0; +- } +- +- grub_mmap_iterate (hook); ++ grub_mmap_iterate (post64_hook, &post64); + return post64; + } +diff --git a/grub-core/mmap/mips/uppermem.c b/grub-core/mmap/mips/uppermem.c +index 8326185..a980e07 100644 +--- a/grub-core/mmap/mips/uppermem.c ++++ b/grub-core/mmap/mips/uppermem.c +@@ -22,47 +22,51 @@ + #include + #include + ++/* Helper for grub_mmap_get_lower. */ ++static int ++lower_hook (grub_uint64_t addr, grub_uint64_t size, grub_memory_type_t type, ++ void *data) ++{ ++ grub_uint64_t *lower = data; ++ ++ if (type != GRUB_MEMORY_AVAILABLE) ++ return 0; ++ if (addr == 0) ++ *lower = size; ++ return 0; ++} ++ + 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_memory_type_t); +- int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, +- grub_memory_type_t type) +- { +- if (type != GRUB_MEMORY_AVAILABLE) +- return 0; +- if (addr == 0) +- lower = size; +- return 0; +- } +- +- grub_mmap_iterate (hook); ++ grub_mmap_iterate (lower_hook, &lower); + if (lower > GRUB_ARCH_LOWMEMMAXSIZE) + lower = GRUB_ARCH_LOWMEMMAXSIZE; + return lower; + } + ++/* Helper for grub_mmap_get_upper. */ ++static int ++upper_hook (grub_uint64_t addr, grub_uint64_t size, grub_memory_type_t type, ++ void *data) ++{ ++ grub_uint64_t *upper = data; ++ ++ if (type != GRUB_MEMORY_AVAILABLE) ++ return 0; ++ if (addr <= GRUB_ARCH_HIGHMEMPSTART && addr + size ++ > GRUB_ARCH_HIGHMEMPSTART) ++ *upper = addr + size - GRUB_ARCH_HIGHMEMPSTART; ++ return 0; ++} ++ + 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_memory_type_t); +- int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, +- grub_memory_type_t type) +- { +- if (type != GRUB_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); ++ grub_mmap_iterate (upper_hook, &upper); + return upper; + } +diff --git a/grub-core/mmap/mmap.c b/grub-core/mmap/mmap.c +index 0b734dd..40ffb2e 100644 +--- a/grub-core/mmap/mmap.c ++++ b/grub-core/mmap/mmap.c +@@ -35,43 +35,90 @@ static int curhandle = 1; + + #endif + +-grub_err_t +-grub_mmap_iterate (grub_memory_hook_t hook) ++/* If same page is used by multiple types it's resolved ++ according to priority: ++ 1 - free memory ++ 2 - memory usable by firmware-aware code ++ 3 - unusable memory ++ 4 - a range deliberately empty ++*/ ++static const int priority[] = ++{ ++ [GRUB_MEMORY_AVAILABLE] = 1, ++ [GRUB_MEMORY_RESERVED] = 3, ++ [GRUB_MEMORY_ACPI] = 2, ++ [GRUB_MEMORY_CODE] = 3, ++ [GRUB_MEMORY_NVS] = 3, ++ [GRUB_MEMORY_HOLE] = 4, ++}; ++ ++/* Scanline events. */ ++struct grub_mmap_scan ++{ ++ /* At which memory address. */ ++ grub_uint64_t pos; ++ /* 0 = region starts, 1 = region ends. */ ++ int type; ++ /* Which type of memory region? */ ++ int memtype; ++}; ++ ++/* Context for grub_mmap_iterate. */ ++struct grub_mmap_iterate_ctx ++{ ++ struct grub_mmap_scan *scanline_events; ++ int i; ++}; ++ ++/* Helper for grub_mmap_iterate. */ ++static int ++count_hook (grub_uint64_t addr __attribute__ ((unused)), ++ grub_uint64_t size __attribute__ ((unused)), ++ grub_memory_type_t type __attribute__ ((unused)), void *data) ++{ ++ int *mmap_num = data; ++ ++ (*mmap_num)++; ++ return 0; ++} ++ ++/* Helper for grub_mmap_iterate. */ ++static int ++fill_hook (grub_uint64_t addr, grub_uint64_t size, grub_memory_type_t type, ++ void *data) + { ++ struct grub_mmap_iterate_ctx *ctx = data; + ++ ctx->scanline_events[ctx->i].pos = addr; ++ ctx->scanline_events[ctx->i].type = 0; ++ if (type < ARRAY_SIZE (priority) && priority[type]) ++ ctx->scanline_events[ctx->i].memtype = type; ++ else ++ { ++ grub_dprintf ("mmap", "Unknown memory type %d. Assuming unusable\n", ++ type); ++ ctx->scanline_events[ctx->i].memtype = GRUB_MEMORY_RESERVED; ++ } ++ ctx->i++; ++ ++ ctx->scanline_events[ctx->i].pos = addr + size; ++ ctx->scanline_events[ctx->i].type = 1; ++ ctx->scanline_events[ctx->i].memtype = ++ ctx->scanline_events[ctx->i - 1].memtype; ++ ctx->i++; ++ ++ return 0; ++} ++ ++grub_err_t ++grub_mmap_iterate (grub_memory_hook_t hook, void *hook_data) ++{ + /* This function resolves overlapping regions and sorts the memory map. + It uses scanline (sweeping) algorithm. + */ +- /* If same page is used by multiple types it's resolved +- according to priority: +- 1 - free memory +- 2 - memory usable by firmware-aware code +- 3 - unusable memory +- 4 - a range deliberately empty +- */ +- int priority[] = +- { +- [GRUB_MEMORY_AVAILABLE] = 1, +- [GRUB_MEMORY_RESERVED] = 3, +- [GRUB_MEMORY_ACPI] = 2, +- [GRUB_MEMORY_CODE] = 3, +- [GRUB_MEMORY_NVS] = 3, +- [GRUB_MEMORY_HOLE] = 4, +- }; +- ++ struct grub_mmap_iterate_ctx ctx; + int i, done; + +- /* Scanline events. */ +- struct grub_mmap_scan +- { +- /* At which memory address. */ +- grub_uint64_t pos; +- /* 0 = region starts, 1 = region ends. */ +- int type; +- /* Which type of memory region? */ +- int memtype; +- }; +- struct grub_mmap_scan *scanline_events; + struct grub_mmap_scan t; + + /* Previous scanline event. */ +@@ -88,42 +135,6 @@ grub_mmap_iterate (grub_memory_hook_t hook) + struct grub_mmap_region *cur; + #endif + +- auto int NESTED_FUNC_ATTR count_hook (grub_uint64_t, grub_uint64_t, +- grub_uint32_t); +- int NESTED_FUNC_ATTR count_hook (grub_uint64_t addr __attribute__ ((unused)), +- grub_uint64_t size __attribute__ ((unused)), +- grub_memory_type_t type __attribute__ ((unused))) +- { +- mmap_num++; +- return 0; +- } +- +- auto int NESTED_FUNC_ATTR fill_hook (grub_uint64_t, grub_uint64_t, +- grub_uint32_t); +- int NESTED_FUNC_ATTR fill_hook (grub_uint64_t addr, +- grub_uint64_t size, +- grub_memory_type_t type) +- { +- scanline_events[i].pos = addr; +- scanline_events[i].type = 0; +- if (type < ARRAY_SIZE (priority) && priority[type]) +- scanline_events[i].memtype = type; +- else +- { +- grub_dprintf ("mmap", "Unknown memory type %d. Assuming unusable\n", +- type); +- scanline_events[i].memtype = GRUB_MEMORY_RESERVED; +- } +- i++; +- +- scanline_events[i].pos = addr + size; +- scanline_events[i].type = 1; +- scanline_events[i].memtype = scanline_events[i - 1].memtype; +- i++; +- +- return 0; +- } +- + mmap_num = 0; + + #ifndef GRUB_MMAP_REGISTER_BY_FIRMWARE +@@ -131,37 +142,38 @@ grub_mmap_iterate (grub_memory_hook_t hook) + mmap_num++; + #endif + +- grub_machine_mmap_iterate (count_hook); ++ grub_machine_mmap_iterate (count_hook, &mmap_num); + + /* Initialize variables. */ + grub_memset (present, 0, sizeof (present)); +- scanline_events = (struct grub_mmap_scan *) ++ ctx.scanline_events = (struct grub_mmap_scan *) + grub_malloc (sizeof (struct grub_mmap_scan) * 2 * mmap_num); + +- if (! scanline_events) ++ if (! ctx.scanline_events) + return grub_errno; + +- i = 0; ++ ctx.i = 0; + #ifndef GRUB_MMAP_REGISTER_BY_FIRMWARE + /* Register scanline events. */ + for (cur = grub_mmap_overlays; cur; cur = cur->next) + { +- scanline_events[i].pos = cur->start; +- scanline_events[i].type = 0; ++ ctx.scanline_events[ctx.i].pos = cur->start; ++ ctx.scanline_events[ctx.i].type = 0; + if (cur->type < ARRAY_SIZE (priority) && priority[cur->type]) +- scanline_events[i].memtype = cur->type; ++ ctx.scanline_events[ctx.i].memtype = cur->type; + else +- scanline_events[i].memtype = GRUB_MEMORY_RESERVED; +- i++; +- +- scanline_events[i].pos = cur->end; +- scanline_events[i].type = 1; +- scanline_events[i].memtype = scanline_events[i - 1].memtype; +- i++; ++ ctx.scanline_events[ctx.i].memtype = GRUB_MEMORY_RESERVED; ++ ctx.i++; ++ ++ ctx.scanline_events[ctx.i].pos = cur->end; ++ ctx.scanline_events[ctx.i].type = 1; ++ ctx.scanline_events[ctx.i].memtype = ++ ctx.scanline_events[ctx.i - 1].memtype; ++ ctx.i++; + } + #endif /* ! GRUB_MMAP_REGISTER_BY_FIRMWARE */ + +- grub_machine_mmap_iterate (fill_hook); ++ grub_machine_mmap_iterate (fill_hook, &ctx); + + /* Primitive bubble sort. It has complexity O(n^2) but since we're + unlikely to have more than 100 chunks it's probably one of the +@@ -171,28 +183,28 @@ grub_mmap_iterate (grub_memory_hook_t hook) + { + done = 0; + for (i = 0; i < 2 * mmap_num - 1; i++) +- if (scanline_events[i + 1].pos < scanline_events[i].pos +- || (scanline_events[i + 1].pos == scanline_events[i].pos +- && scanline_events[i + 1].type == 0 +- && scanline_events[i].type == 1)) ++ if (ctx.scanline_events[i + 1].pos < ctx.scanline_events[i].pos ++ || (ctx.scanline_events[i + 1].pos == ctx.scanline_events[i].pos ++ && ctx.scanline_events[i + 1].type == 0 ++ && ctx.scanline_events[i].type == 1)) + { +- t = scanline_events[i + 1]; +- scanline_events[i + 1] = scanline_events[i]; +- scanline_events[i] = t; ++ t = ctx.scanline_events[i + 1]; ++ ctx.scanline_events[i + 1] = ctx.scanline_events[i]; ++ ctx.scanline_events[i] = t; + done = 1; + } + } + +- lastaddr = scanline_events[0].pos; +- lasttype = scanline_events[0].memtype; ++ lastaddr = ctx.scanline_events[0].pos; ++ lasttype = ctx.scanline_events[0].memtype; + for (i = 0; i < 2 * mmap_num; i++) + { + unsigned k; + /* Process event. */ +- if (scanline_events[i].type) +- present[scanline_events[i].memtype]--; ++ if (ctx.scanline_events[i].type) ++ present[ctx.scanline_events[i].memtype]--; + else +- present[scanline_events[i].memtype]++; ++ present[ctx.scanline_events[i].memtype]++; + + /* Determine current region type. */ + curtype = -1; +@@ -202,12 +214,13 @@ grub_mmap_iterate (grub_memory_hook_t hook) + + /* Announce region to the hook if necessary. */ + if ((curtype == -1 || curtype != lasttype) +- && lastaddr != scanline_events[i].pos ++ && lastaddr != ctx.scanline_events[i].pos + && lasttype != -1 + && lasttype != GRUB_MEMORY_HOLE +- && hook (lastaddr, scanline_events[i].pos - lastaddr, lasttype)) ++ && hook (lastaddr, ctx.scanline_events[i].pos - lastaddr, lasttype, ++ hook_data)) + { +- grub_free (scanline_events); ++ grub_free (ctx.scanline_events); + return GRUB_ERR_NONE; + } + +@@ -215,11 +228,11 @@ grub_mmap_iterate (grub_memory_hook_t hook) + if (curtype == -1 || curtype != lasttype) + { + lasttype = curtype; +- lastaddr = scanline_events[i].pos; ++ lastaddr = ctx.scanline_events[i].pos; + } + } + +- grub_free (scanline_events); ++ grub_free (ctx.scanline_events); + return GRUB_ERR_NONE; + } + +@@ -280,19 +293,23 @@ grub_mmap_unregister (int handle) + + #define CHUNK_SIZE 0x400 + ++struct badram_entry { ++ grub_uint64_t addr, mask; ++}; ++ + static inline grub_uint64_t +-fill_mask (grub_uint64_t addr, grub_uint64_t mask, grub_uint64_t iterator) ++fill_mask (struct badram_entry *entry, grub_uint64_t iterator) + { + int i, j; +- grub_uint64_t ret = (addr & mask); ++ grub_uint64_t ret = (entry->addr & entry->mask); + + /* Find first fixed bit. */ + for (i = 0; i < 64; i++) +- if ((mask & (1ULL << i)) != 0) ++ if ((entry->mask & (1ULL << i)) != 0) + break; + j = 0; + for (; i < 64; i++) +- if ((mask & (1ULL << i)) == 0) ++ if ((entry->mask & (1ULL << i)) == 0) + { + if ((iterator & (1ULL << j)) != 0) + ret |= 1ULL << i; +@@ -301,64 +318,64 @@ fill_mask (grub_uint64_t addr, grub_uint64_t mask, grub_uint64_t iterator) + return ret; + } + ++/* Helper for grub_cmd_badram. */ ++static int ++badram_iter (grub_uint64_t addr, grub_uint64_t size, ++ grub_memory_type_t type __attribute__ ((unused)), void *data) ++{ ++ struct badram_entry *entry = data; ++ grub_uint64_t iterator, low, high, cur; ++ int tail, var; ++ int i; ++ grub_dprintf ("badram", "hook %llx+%llx\n", (unsigned long long) addr, ++ (unsigned long long) size); ++ ++ /* How many trailing zeros? */ ++ for (tail = 0; ! (entry->mask & (1ULL << tail)); tail++); ++ ++ /* How many zeros in mask? */ ++ var = 0; ++ for (i = 0; i < 64; i++) ++ if (! (entry->mask & (1ULL << i))) ++ var++; ++ ++ if (fill_mask (entry, 0) >= addr) ++ iterator = 0; ++ else ++ { ++ low = 0; ++ high = ~0ULL; ++ /* Find starting value. Keep low and high such that ++ fill_mask (low) < addr and fill_mask (high) >= addr; ++ */ ++ while (high - low > 1) ++ { ++ cur = (low + high) / 2; ++ if (fill_mask (entry, cur) >= addr) ++ high = cur; ++ else ++ low = cur; ++ } ++ iterator = high; ++ } ++ ++ for (; iterator < (1ULL << (var - tail)) ++ && (cur = fill_mask (entry, iterator)) < addr + size; ++ iterator++) ++ { ++ grub_dprintf ("badram", "%llx (size %llx) is a badram range\n", ++ (unsigned long long) cur, (1ULL << tail)); ++ grub_mmap_register (cur, (1ULL << tail), GRUB_MEMORY_HOLE); ++ } ++ return 0; ++} ++ + static grub_err_t + grub_cmd_badram (grub_command_t cmd __attribute__ ((unused)), + int argc, char **args) + { + char * str; +- grub_uint64_t badaddr, badmask; +- +- auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, +- grub_memory_type_t); +- int NESTED_FUNC_ATTR hook (grub_uint64_t addr, +- grub_uint64_t size, +- grub_memory_type_t type __attribute__ ((unused))) +- { +- grub_uint64_t iterator, low, high, cur; +- int tail, var; +- int i; +- grub_dprintf ("badram", "hook %llx+%llx\n", (unsigned long long) addr, +- (unsigned long long) size); +- +- /* How many trailing zeros? */ +- for (tail = 0; ! (badmask & (1ULL << tail)); tail++); +- +- /* How many zeros in mask? */ +- var = 0; +- for (i = 0; i < 64; i++) +- if (! (badmask & (1ULL << i))) +- var++; +- +- if (fill_mask (badaddr, badmask, 0) >= addr) +- iterator = 0; +- else +- { +- low = 0; +- high = ~0ULL; +- /* Find starting value. Keep low and high such that +- fill_mask (low) < addr and fill_mask (high) >= addr; +- */ +- while (high - low > 1) +- { +- cur = (low + high) / 2; +- if (fill_mask (badaddr, badmask, cur) >= addr) +- high = cur; +- else +- low = cur; +- } +- iterator = high; +- } +- +- for (; iterator < (1ULL << (var - tail)) +- && (cur = fill_mask (badaddr, badmask, iterator)) < addr + size; +- iterator++) +- { +- grub_dprintf ("badram", "%llx (size %llx) is a badram range\n", +- (unsigned long long) cur, (1ULL << tail)); +- grub_mmap_register (cur, (1ULL << tail), GRUB_MEMORY_HOLE); +- } +- return 0; +- } ++ struct badram_entry entry; + + if (argc != 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); +@@ -370,10 +387,10 @@ grub_cmd_badram (grub_command_t cmd __attribute__ ((unused)), + while (1) + { + /* Parse address and mask. */ +- badaddr = grub_strtoull (str, &str, 16); ++ entry.addr = grub_strtoull (str, &str, 16); + if (*str == ',') + str++; +- badmask = grub_strtoull (str, &str, 16); ++ entry.mask = grub_strtoull (str, &str, 16); + if (*str == ',') + str++; + +@@ -385,12 +402,13 @@ grub_cmd_badram (grub_command_t cmd __attribute__ ((unused)), + + /* When part of a page is tainted, we discard the whole of it. There's + no point in providing sub-page chunks. */ +- badmask &= ~(CHUNK_SIZE - 1); ++ entry.mask &= ~(CHUNK_SIZE - 1); + + grub_dprintf ("badram", "badram %llx:%llx\n", +- (unsigned long long) badaddr, (unsigned long long) badmask); ++ (unsigned long long) entry.addr, ++ (unsigned long long) entry.mask); + +- grub_mmap_iterate (hook); ++ grub_mmap_iterate (badram_iter, &entry); + } + } + +@@ -416,44 +434,48 @@ parsemem (const char *str) + return ret; + } + +-static grub_err_t +-grub_cmd_cutmem (grub_command_t cmd __attribute__ ((unused)), +- int argc, char **args) +-{ ++struct cutmem_range { + grub_uint64_t from, to; ++}; + +- auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, +- grub_memory_type_t); +- int NESTED_FUNC_ATTR hook (grub_uint64_t addr, +- grub_uint64_t size, +- grub_memory_type_t type __attribute__ ((unused))) +- { +- grub_uint64_t end = addr + size; +- +- if (addr <= from) +- addr = from; +- if (end >= to) +- end = to; ++/* Helper for grub_cmd_cutmem. */ ++static int ++cutmem_iter (grub_uint64_t addr, grub_uint64_t size, ++ grub_memory_type_t type __attribute__ ((unused)), void *data) ++{ ++ struct cutmem_range *range = data; ++ grub_uint64_t end = addr + size; + +- if (end <= addr) +- return 0; ++ if (addr <= range->from) ++ addr = range->from; ++ if (end >= range->to) ++ end = range->to; + +- grub_mmap_register (addr, end - addr, GRUB_MEMORY_HOLE); ++ if (end <= addr) + return 0; +- } ++ ++ grub_mmap_register (addr, end - addr, GRUB_MEMORY_HOLE); ++ return 0; ++} ++ ++static grub_err_t ++grub_cmd_cutmem (grub_command_t cmd __attribute__ ((unused)), ++ int argc, char **args) ++{ ++ struct cutmem_range range; + + if (argc != 2) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("two arguments expected")); + +- from = parsemem (args[0]); ++ range.from = parsemem (args[0]); + if (grub_errno) + return grub_errno; + +- to = parsemem (args[1]); ++ range.to = parsemem (args[1]); + if (grub_errno) + return grub_errno; + +- grub_mmap_iterate (hook); ++ grub_mmap_iterate (cutmem_iter, &range); + + return GRUB_ERR_NONE; + } +diff --git a/include/grub/efiemu/efiemu.h b/include/grub/efiemu/efiemu.h +index 4ce3fc9..f241e75 100644 +--- a/include/grub/efiemu/efiemu.h ++++ b/include/grub/efiemu/efiemu.h +@@ -226,7 +226,7 @@ grub_efiemu_finish_boot_services (grub_efi_uintn_t *memory_map_size, + grub_efi_uint32_t *descriptor_version); + + grub_err_t +-grub_efiemu_mmap_iterate (grub_memory_hook_t hook); ++grub_efiemu_mmap_iterate (grub_memory_hook_t hook, void *hook_data); + int grub_efiemu_sizeof_uintn_t (void); + grub_err_t + grub_efiemu_get_lower_upper_memory (grub_uint64_t *lower, grub_uint64_t *upper); +diff --git a/include/grub/memory.h b/include/grub/memory.h +index 61470d7..3311fcb 100644 +--- a/include/grub/memory.h ++++ b/include/grub/memory.h +@@ -36,21 +36,25 @@ typedef enum grub_memory_type + GRUB_MEMORY_HOLE = 21 + } grub_memory_type_t; + +-typedef int NESTED_FUNC_ATTR (*grub_memory_hook_t) (grub_uint64_t, +- grub_uint64_t, +- grub_memory_type_t); ++typedef int (*grub_memory_hook_t) (grub_uint64_t, ++ grub_uint64_t, ++ grub_memory_type_t, ++ void *); + +-grub_err_t grub_mmap_iterate (grub_memory_hook_t hook); ++grub_err_t grub_mmap_iterate (grub_memory_hook_t hook, void *hook_data); + + #ifdef GRUB_MACHINE_EFI + grub_err_t +-grub_efi_mmap_iterate (grub_memory_hook_t hook, int avoid_efi_boot_services); ++grub_efi_mmap_iterate (grub_memory_hook_t hook, void *hook_data, ++ int avoid_efi_boot_services); + #endif + + #if !defined (GRUB_MACHINE_EMU) && !defined (GRUB_MACHINE_EFI) +-grub_err_t EXPORT_FUNC(grub_machine_mmap_iterate) (grub_memory_hook_t hook); ++grub_err_t EXPORT_FUNC(grub_machine_mmap_iterate) (grub_memory_hook_t hook, ++ void *hook_data); + #else +-grub_err_t grub_machine_mmap_iterate (grub_memory_hook_t hook); ++grub_err_t grub_machine_mmap_iterate (grub_memory_hook_t hook, ++ void *hook_data); + #endif + + int grub_mmap_register (grub_uint64_t start, grub_uint64_t size, int type); +-- +1.8.1.4 + diff --git a/0107-Remove-nested-functions-from-script-reading-and-pars.patch b/0107-Remove-nested-functions-from-script-reading-and-pars.patch new file mode 100644 index 0000000..220f58a --- /dev/null +++ b/0107-Remove-nested-functions-from-script-reading-and-pars.patch @@ -0,0 +1,816 @@ +From 14b058a0b48a201ce5d139e36b64ee6590075845 Mon Sep 17 00:00:00 2001 +From: Colin Watson +Date: Tue, 15 Jan 2013 12:03:25 +0000 +Subject: [PATCH 107/364] Remove nested functions from script reading and + parsing. + +* grub-core/kern/parser.c (grub_parser_split_cmdline): Add +getline_data argument, passed to getline. +* grub-core/kern/rescue_parser.c (grub_rescue_parse_line): Add +getline_data argument, passed to grub_parser_split_cmdline. +* grub-core/script/lexer.c (grub_script_lexer_yywrap): Pass +lexerstate->getline_data to lexerstate->getline. +(grub_script_lexer_init): Add getline_data argument, saved in +lexerstate->getline_data. +* grub-core/script/main.c (grub_normal_parse_line): Add getline_data +argument, passed to grub_script_parse. +* grub-core/script/script.c (grub_script_parse): Add getline_data +argument, passed to grub_script_lexer_init. +* include/grub/parser.h (grub_parser_split_cmdline): Update +prototype. Update all callers to pass appropriate getline data. +(struct grub_parser.parse_line): Likewise. +(grub_rescue_parse_line): Likewise. +* include/grub/reader.h (grub_reader_getline_t): Add void * +argument. +* include/grub/script_sh.h (struct grub_lexer_param): Add +getline_data member. +(grub_script_parse): Update prototype. Update all callers to pass +appropriate getline data. +(grub_script_lexer_init): Likewise. +(grub_normal_parse_line): Likewise. + +* grub-core/commands/legacycfg.c (legacy_file_getline): Add unused +data argument. +* grub-core/kern/parser.c (grub_parser_execute: getline): Make +static instead of nested. Rename to ... +(grub_parser_execute_getline): ... this. +* grub-core/kern/rescue_reader.c (grub_rescue_read_line): Add unused +data argument. +* grub-core/normal/main.c (read_config_file: getline): Make static +instead of nested. Rename to ... +(read_config_file_getline): ... this. +(grub_normal_read_line): Add unused data argument. +* grub-core/script/execute.c (grub_script_execute_sourcecode: +getline): Make static instead of nested. Rename to ... +(grub_script_execute_sourcecode_getline): ... this. +* util/grub-script-check.c (main: get_config_line): Make static +instead of nested. +--- + ChangeLog | 46 ++++++++++++++++ + grub-core/commands/legacycfg.c | 7 +-- + grub-core/kern/parser.c | 54 ++++++++++--------- + grub-core/kern/rescue_parser.c | 6 ++- + grub-core/kern/rescue_reader.c | 7 +-- + grub-core/normal/completion.c | 2 +- + grub-core/normal/main.c | 53 +++++++++--------- + grub-core/script/execute.c | 51 ++++++++++-------- + grub-core/script/lexer.c | 9 ++-- + grub-core/script/main.c | 5 +- + grub-core/script/script.c | 6 ++- + include/grub/parser.h | 7 ++- + include/grub/reader.h | 2 +- + include/grub/script_sh.h | 12 +++-- + util/grub-script-check.c | 119 ++++++++++++++++++++++------------------- + 15 files changed, 238 insertions(+), 148 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index d07f235..d02749b 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,51 @@ + 2013-01-15 Colin Watson + ++ Remove nested functions from script reading and parsing. ++ ++ * grub-core/kern/parser.c (grub_parser_split_cmdline): Add ++ getline_data argument, passed to getline. ++ * grub-core/kern/rescue_parser.c (grub_rescue_parse_line): Add ++ getline_data argument, passed to grub_parser_split_cmdline. ++ * grub-core/script/lexer.c (grub_script_lexer_yywrap): Pass ++ lexerstate->getline_data to lexerstate->getline. ++ (grub_script_lexer_init): Add getline_data argument, saved in ++ lexerstate->getline_data. ++ * grub-core/script/main.c (grub_normal_parse_line): Add getline_data ++ argument, passed to grub_script_parse. ++ * grub-core/script/script.c (grub_script_parse): Add getline_data ++ argument, passed to grub_script_lexer_init. ++ * include/grub/parser.h (grub_parser_split_cmdline): Update ++ prototype. Update all callers to pass appropriate getline data. ++ (struct grub_parser.parse_line): Likewise. ++ (grub_rescue_parse_line): Likewise. ++ * include/grub/reader.h (grub_reader_getline_t): Add void * ++ argument. ++ * include/grub/script_sh.h (struct grub_lexer_param): Add ++ getline_data member. ++ (grub_script_parse): Update prototype. Update all callers to pass ++ appropriate getline data. ++ (grub_script_lexer_init): Likewise. ++ (grub_normal_parse_line): Likewise. ++ ++ * grub-core/commands/legacycfg.c (legacy_file_getline): Add unused ++ data argument. ++ * grub-core/kern/parser.c (grub_parser_execute: getline): Make ++ static instead of nested. Rename to ... ++ (grub_parser_execute_getline): ... this. ++ * grub-core/kern/rescue_reader.c (grub_rescue_read_line): Add unused ++ data argument. ++ * grub-core/normal/main.c (read_config_file: getline): Make static ++ instead of nested. Rename to ... ++ (read_config_file_getline): ... this. ++ (grub_normal_read_line): Add unused data argument. ++ * grub-core/script/execute.c (grub_script_execute_sourcecode: ++ getline): Make static instead of nested. Rename to ... ++ (grub_script_execute_sourcecode_getline): ... this. ++ * util/grub-script-check.c (main: get_config_line): Make static ++ instead of nested. ++ ++2013-01-15 Colin Watson ++ + Remove nested functions from memory map iterators. + + * grub-core/efiemu/mm.c (grub_efiemu_mmap_iterate): Add hook_data +diff --git a/grub-core/commands/legacycfg.c b/grub-core/commands/legacycfg.c +index e34eed4..a3ad5c6 100644 +--- a/grub-core/commands/legacycfg.c ++++ b/grub-core/commands/legacycfg.c +@@ -37,7 +37,8 @@ GRUB_MOD_LICENSE ("GPLv3+"); + + /* Helper for legacy_file. */ + static grub_err_t +-legacy_file_getline (char **line, int cont __attribute__ ((unused))) ++legacy_file_getline (char **line, int cont __attribute__ ((unused)), ++ void *data __attribute__ ((unused))) + { + *line = 0; + return GRUB_ERR_NONE; +@@ -134,7 +135,7 @@ legacy_file (const char *filename) + + if (parsed && !entryname) + { +- grub_normal_parse_line (parsed, legacy_file_getline); ++ grub_normal_parse_line (parsed, legacy_file_getline, NULL); + grub_print_error (); + grub_free (parsed); + parsed = NULL; +@@ -180,7 +181,7 @@ legacy_file (const char *filename) + grub_free (args); + } + +- grub_normal_parse_line (suffix, legacy_file_getline); ++ grub_normal_parse_line (suffix, legacy_file_getline, NULL); + grub_print_error (); + grub_free (suffix); + grub_free (entrysrc); +diff --git a/grub-core/kern/parser.c b/grub-core/kern/parser.c +index d1be53e..b261fa0 100644 +--- a/grub-core/kern/parser.c ++++ b/grub-core/kern/parser.c +@@ -107,7 +107,8 @@ check_varstate (grub_parser_state_t s) + } + + grub_err_t +-grub_parser_split_cmdline (const char *cmdline, grub_reader_getline_t getline, ++grub_parser_split_cmdline (const char *cmdline, ++ grub_reader_getline_t getline, void *getline_data, + int *argc, char ***argv) + { + grub_parser_state_t state = GRUB_PARSER_STATE_TEXT; +@@ -149,7 +150,7 @@ grub_parser_split_cmdline (const char *cmdline, grub_reader_getline_t getline, + if (!rd || !*rd) + { + if (getline) +- getline (&rd, 1); ++ getline (&rd, 1, getline_data); + else + break; + } +@@ -232,36 +233,39 @@ grub_parser_split_cmdline (const char *cmdline, grub_reader_getline_t getline, + return 0; + } + ++/* Helper for grub_parser_execute. */ ++static grub_err_t ++grub_parser_execute_getline (char **line, int cont __attribute__ ((unused)), ++ void *data) ++{ ++ char **source = data; ++ char *p; ++ ++ if (!*source) ++ { ++ *line = 0; ++ return 0; ++ } ++ ++ p = grub_strchr (*source, '\n'); ++ ++ if (p) ++ *line = grub_strndup (*source, p - *source); ++ else ++ *line = grub_strdup (*source); ++ *source = p ? p + 1 : 0; ++ return 0; ++} ++ + 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; +- +- if (!source) +- { +- *line = 0; +- return 0; +- } +- +- p = grub_strchr (source, '\n'); +- +- if (p) +- *line = grub_strndup (source, p - source); +- else +- *line = grub_strdup (source); +- source = p ? p + 1 : 0; +- return 0; +- } +- + while (source) + { + char *line; + +- getline (&line, 0); +- grub_rescue_parse_line (line, getline); ++ grub_parser_execute_getline (&line, 0, &source); ++ grub_rescue_parse_line (line, grub_parser_execute_getline, &source); + grub_free (line); + } + +diff --git a/grub-core/kern/rescue_parser.c b/grub-core/kern/rescue_parser.c +index 656342d..ab3d041 100644 +--- a/grub-core/kern/rescue_parser.c ++++ b/grub-core/kern/rescue_parser.c +@@ -26,14 +26,16 @@ + #include + + grub_err_t +-grub_rescue_parse_line (char *line, grub_reader_getline_t getline) ++grub_rescue_parse_line (char *line, ++ grub_reader_getline_t getline, void *getline_data) + { + char *name; + int n; + grub_command_t cmd; + char **args; + +- if (grub_parser_split_cmdline (line, getline, &n, &args) || n < 0) ++ if (grub_parser_split_cmdline (line, getline, getline_data, &n, &args) ++ || n < 0) + return grub_errno; + + if (n == 0) +diff --git a/grub-core/kern/rescue_reader.c b/grub-core/kern/rescue_reader.c +index 4587b94..dcd7d44 100644 +--- a/grub-core/kern/rescue_reader.c ++++ b/grub-core/kern/rescue_reader.c +@@ -30,7 +30,8 @@ static char linebuf[GRUB_RESCUE_BUF_SIZE]; + + /* Prompt to input a command and read the line. */ + static grub_err_t +-grub_rescue_read_line (char **line, int cont) ++grub_rescue_read_line (char **line, int cont, ++ void *data __attribute__ ((unused))) + { + int c; + int pos = 0; +@@ -87,11 +88,11 @@ grub_rescue_run (void) + grub_print_error (); + grub_errno = GRUB_ERR_NONE; + +- grub_rescue_read_line (&line, 0); ++ grub_rescue_read_line (&line, 0, NULL); + if (! line || line[0] == '\0') + continue; + +- grub_rescue_parse_line (line, grub_rescue_read_line); ++ grub_rescue_parse_line (line, grub_rescue_read_line, NULL); + grub_free (line); + } + } +diff --git a/grub-core/normal/completion.c b/grub-core/normal/completion.c +index cae78f1..805f002 100644 +--- a/grub-core/normal/completion.c ++++ b/grub-core/normal/completion.c +@@ -418,7 +418,7 @@ grub_normal_do_completion (char *buf, int *restore, + + *restore = 1; + +- if (grub_parser_split_cmdline (buf, 0, &argc, &argv)) ++ if (grub_parser_split_cmdline (buf, 0, 0, &argc, &argv)) + return 0; + + if (argc == 0) +diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c +index 13473ec..07f337d 100644 +--- a/grub-core/normal/main.c ++++ b/grub-core/normal/main.c +@@ -134,33 +134,37 @@ grub_normal_free_menu (grub_menu_t menu) + grub_env_unset_menu (); + } + +-static grub_menu_t +-read_config_file (const char *config) ++/* Helper for read_config_file. */ ++static grub_err_t ++read_config_file_getline (char **line, int cont __attribute__ ((unused)), ++ void *data) + { +- grub_file_t file; +- const char *old_file, *old_dir; +- char *config_dir, *ptr = 0; ++ grub_file_t file = data; + +- auto grub_err_t getline (char **line, int cont); +- grub_err_t getline (char **line, int cont __attribute__ ((unused))) ++ while (1) + { +- while (1) +- { +- char *buf; ++ char *buf; + +- *line = buf = grub_file_getline (file); +- if (! buf) +- return grub_errno; ++ *line = buf = grub_file_getline (file); ++ if (! buf) ++ return grub_errno; + +- if (buf[0] == '#') +- grub_free (*line); +- else +- break; +- } +- +- return GRUB_ERR_NONE; ++ if (buf[0] == '#') ++ grub_free (*line); ++ else ++ break; + } + ++ return GRUB_ERR_NONE; ++} ++ ++static grub_menu_t ++read_config_file (const char *config) ++{ ++ grub_file_t file; ++ const char *old_file, *old_dir; ++ char *config_dir, *ptr = 0; ++ + grub_menu_t newmenu; + + newmenu = grub_env_get_menu (); +@@ -199,10 +203,10 @@ read_config_file (const char *config) + grub_print_error (); + grub_errno = GRUB_ERR_NONE; + +- if ((getline (&line, 0)) || (! line)) ++ if ((read_config_file_getline (&line, 0, file)) || (! line)) + break; + +- grub_normal_parse_line (line, getline); ++ grub_normal_parse_line (line, read_config_file_getline, file); + grub_free (line); + } + +@@ -427,7 +431,8 @@ grub_normal_read_line_real (char **line, int cont, int nested) + } + + static grub_err_t +-grub_normal_read_line (char **line, int cont) ++grub_normal_read_line (char **line, int cont, ++ void *data __attribute__ ((unused))) + { + return grub_normal_read_line_real (line, cont, 0); + } +@@ -463,7 +468,7 @@ grub_cmdline_run (int nested) + if (! line) + break; + +- grub_normal_parse_line (line, grub_normal_read_line); ++ grub_normal_parse_line (line, grub_normal_read_line, NULL); + grub_free (line); + } + } +diff --git a/grub-core/script/execute.c b/grub-core/script/execute.c +index b5e6eb0..6619c2e 100644 +--- a/grub-core/script/execute.c ++++ b/grub-core/script/execute.c +@@ -783,6 +783,31 @@ grub_script_function_call (grub_script_function_t func, int argc, char **args) + return ret; + } + ++/* Helper for grub_script_execute_sourcecode. */ ++static grub_err_t ++grub_script_execute_sourcecode_getline (char **line, ++ int cont __attribute__ ((unused)), ++ void *data) ++{ ++ const char **source = data; ++ const char *p; ++ ++ if (! *source) ++ { ++ *line = 0; ++ return 0; ++ } ++ ++ p = grub_strchr (*source, '\n'); ++ ++ if (p) ++ *line = grub_strndup (*source, p - *source); ++ else ++ *line = grub_strdup (*source); ++ *source = p ? p + 1 : 0; ++ return 0; ++} ++ + /* Execute a source script. */ + grub_err_t + grub_script_execute_sourcecode (const char *source, int argc, char **args) +@@ -792,27 +817,6 @@ grub_script_execute_sourcecode (const char *source, int argc, char **args) + struct grub_script_scope new_scope; + struct grub_script_scope *old_scope; + +- auto grub_err_t getline (char **line, int cont); +- grub_err_t getline (char **line, int cont __attribute__ ((unused))) +- { +- const char *p; +- +- if (! source) +- { +- *line = 0; +- return 0; +- } +- +- p = grub_strchr (source, '\n'); +- +- if (p) +- *line = grub_strndup (source, p - source); +- else +- *line = grub_strdup (source); +- source = p ? p + 1 : 0; +- return 0; +- } +- + new_scope.argv.argc = argc; + new_scope.argv.args = args; + new_scope.flags = 0; +@@ -824,8 +828,9 @@ grub_script_execute_sourcecode (const char *source, int argc, char **args) + { + char *line; + +- getline (&line, 0); +- parsed_script = grub_script_parse (line, getline); ++ grub_script_execute_sourcecode_getline (&line, 0, &source); ++ parsed_script = grub_script_parse ++ (line, grub_script_execute_sourcecode_getline, &source); + if (! parsed_script) + { + ret = grub_errno; +diff --git a/grub-core/script/lexer.c b/grub-core/script/lexer.c +index 396d512..cb9d6b0 100644 +--- a/grub-core/script/lexer.c ++++ b/grub-core/script/lexer.c +@@ -147,7 +147,7 @@ grub_script_lexer_yywrap (struct grub_parser_param *parserstate, + + line = 0; + if (! input) +- lexerstate->getline (&line, 1); ++ lexerstate->getline (&line, 1, lexerstate->getline_data); + else + line = grub_strdup (input); + +@@ -216,7 +216,7 @@ grub_script_lexer_yywrap (struct grub_parser_param *parserstate, + + struct grub_lexer_param * + grub_script_lexer_init (struct grub_parser_param *parser, char *script, +- grub_reader_getline_t arg_getline) ++ grub_reader_getline_t getline, void *getline_data) + { + struct grub_lexer_param *lexerstate; + +@@ -232,7 +232,10 @@ grub_script_lexer_init (struct grub_parser_param *parser, char *script, + return 0; + } + +- lexerstate->getline = arg_getline; /* rest are all zeros already */ ++ lexerstate->getline = getline; ++ lexerstate->getline_data = getline_data; ++ /* The other elements of lexerstate are all zeros already. */ ++ + if (yylex_init (&lexerstate->yyscanner)) + { + grub_free (lexerstate->text); +diff --git a/grub-core/script/main.c b/grub-core/script/main.c +index aa24d16..854a25a 100644 +--- a/grub-core/script/main.c ++++ b/grub-core/script/main.c +@@ -22,12 +22,13 @@ + #include + + grub_err_t +-grub_normal_parse_line (char *line, grub_reader_getline_t getline) ++grub_normal_parse_line (char *line, ++ grub_reader_getline_t getline, void *getline_data) + { + struct grub_script *parsed_script; + + /* Parse the script. */ +- parsed_script = grub_script_parse (line, getline); ++ parsed_script = grub_script_parse (line, getline, getline_data); + + if (parsed_script) + { +diff --git a/grub-core/script/script.c b/grub-core/script/script.c +index ad30183..ec4d433 100644 +--- a/grub-core/script/script.c ++++ b/grub-core/script/script.c +@@ -340,7 +340,8 @@ grub_script_create (struct grub_script_cmd *cmd, struct grub_script_mem *mem) + /* Parse the script passed in SCRIPT and return the parsed + datastructure that is ready to be interpreted. */ + struct grub_script * +-grub_script_parse (char *script, grub_reader_getline_t getline) ++grub_script_parse (char *script, ++ grub_reader_getline_t getline, void *getline_data) + { + struct grub_script *parsed; + struct grub_script_mem *membackup; +@@ -359,7 +360,8 @@ grub_script_parse (char *script, grub_reader_getline_t getline) + } + + /* Initialize the lexer. */ +- lexstate = grub_script_lexer_init (parsestate, script, getline); ++ lexstate = grub_script_lexer_init (parsestate, script, ++ getline, getline_data); + if (!lexstate) + { + grub_free (parsed); +diff --git a/include/grub/parser.h b/include/grub/parser.h +index de4da05..bf9c7c6 100644 +--- a/include/grub/parser.h ++++ b/include/grub/parser.h +@@ -63,6 +63,7 @@ EXPORT_FUNC (grub_parser_cmdline_state) (grub_parser_state_t state, + grub_err_t + EXPORT_FUNC (grub_parser_split_cmdline) (const char *cmdline, + grub_reader_getline_t getline, ++ void *getline_data, + int *argc, char ***argv); + + struct grub_parser +@@ -79,13 +80,15 @@ struct grub_parser + /* Clean up the parser. */ + grub_err_t (*fini) (void); + +- grub_err_t (*parse_line) (char *line, grub_reader_getline_t getline); ++ grub_err_t (*parse_line) (char *line, ++ grub_reader_getline_t getline, void *getline_data); + }; + typedef struct grub_parser *grub_parser_t; + + grub_err_t grub_parser_execute (char *source); + + grub_err_t +-grub_rescue_parse_line (char *line, grub_reader_getline_t getline); ++grub_rescue_parse_line (char *line, ++ grub_reader_getline_t getline, void *getline_data); + + #endif /* ! GRUB_PARSER_HEADER */ +diff --git a/include/grub/reader.h b/include/grub/reader.h +index cd92df8..fd86b20 100644 +--- a/include/grub/reader.h ++++ b/include/grub/reader.h +@@ -22,7 +22,7 @@ + + #include + +-typedef grub_err_t (*grub_reader_getline_t) (char **, int); ++typedef grub_err_t (*grub_reader_getline_t) (char **, int, void *); + + void grub_rescue_run (void) __attribute__ ((noreturn)); + +diff --git a/include/grub/script_sh.h b/include/grub/script_sh.h +index d99cbf7..78602e4 100644 +--- a/include/grub/script_sh.h ++++ b/include/grub/script_sh.h +@@ -161,6 +161,9 @@ struct grub_lexer_param + expected, but not available. */ + grub_reader_getline_t getline; + ++ /* Caller-supplied data passed to `getline'. */ ++ void *getline_data; ++ + /* A reference counter. If this is >0 it means that the parser + expects more tokens and `getline' should be called to fetch more. + Otherwise the lexer can stop processing if the current buffer is +@@ -287,14 +290,16 @@ grub_script_arg_add (struct grub_parser_param *state, + grub_script_arg_type_t type, char *str); + + struct grub_script *grub_script_parse (char *script, +- grub_reader_getline_t getline); ++ grub_reader_getline_t getline, ++ void *getline_data); + 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 (struct grub_parser_param *parser, + char *script, +- grub_reader_getline_t getline); ++ grub_reader_getline_t getline, ++ void *getline_data); + 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 *); +@@ -380,7 +385,8 @@ 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); ++grub_normal_parse_line (char *line, ++ grub_reader_getline_t getline, void *getline_data); + + static inline struct grub_script * + grub_script_ref (struct grub_script *script) +diff --git a/util/grub-script-check.c b/util/grub-script-check.c +index 73d51f0..203a3ff 100644 +--- a/util/grub-script-check.c ++++ b/util/grub-script-check.c +@@ -85,81 +85,92 @@ static struct argp argp = { + NULL, NULL, NULL + }; + ++/* Context for main. */ ++struct main_ctx ++{ ++ int lineno; ++ FILE *file; ++ struct arguments arguments; ++}; ++ ++/* Helper for main. */ ++static grub_err_t ++get_config_line (char **line, int cont __attribute__ ((unused)), void *data) ++{ ++ struct main_ctx *ctx = data; ++ int i; ++ char *cmdline = 0; ++ size_t len = 0; ++ ssize_t curread; ++ ++ curread = getline (&cmdline, &len, (ctx->file ?: stdin)); ++ if (curread == -1) ++ { ++ *line = 0; ++ grub_errno = GRUB_ERR_READ_ERROR; ++ ++ if (cmdline) ++ free (cmdline); ++ return grub_errno; ++ } ++ ++ if (ctx->arguments.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'; ++ } ++ ++ ctx->lineno++; ++ *line = grub_strdup (cmdline); ++ ++ free (cmdline); ++ return 0; ++} ++ + int + main (int argc, char *argv[]) + { ++ struct main_ctx ctx = { ++ .lineno = 0, ++ .file = 0 ++ }; + char *input; +- int lineno = 0; +- FILE *file = 0; +- struct arguments arguments; + 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))) +- { +- int i; +- char *cmdline = 0; +- size_t len = 0; +- ssize_t curread; +- +- curread = getline(&cmdline, &len, (file ?: stdin)); +- if (curread == -1) +- { +- *line = 0; +- grub_errno = GRUB_ERR_READ_ERROR; +- +- if (cmdline) +- free (cmdline); +- return grub_errno; +- } +- +- if (arguments.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'; +- } +- +- lineno++; +- *line = grub_strdup (cmdline); +- +- free (cmdline); +- return 0; +- } +- + set_program_name (argv[0]); + grub_util_init_nls (); + +- memset (&arguments, 0, sizeof (struct arguments)); ++ memset (&ctx.arguments, 0, sizeof (struct arguments)); + + /* Check for options. */ +- if (argp_parse (&argp, argc, argv, 0, 0, &arguments) != 0) ++ if (argp_parse (&argp, argc, argv, 0, 0, &ctx.arguments) != 0) + { + fprintf (stderr, "%s", _("Error in parsing command line arguments\n")); + exit(1); + } + + /* Obtain ARGUMENT. */ +- if (!arguments.filename) ++ if (!ctx.arguments.filename) + { +- file = 0; /* read from stdin */ ++ ctx.file = 0; /* read from stdin */ + } + else + { +- file = fopen (arguments.filename, "r"); +- if (! file) ++ ctx.file = fopen (ctx.arguments.filename, "r"); ++ if (! ctx.file) + { + char *program = xstrdup(program_name); + fprintf (stderr, "%s: %s: %s\n", program_name, +- arguments.filename, strerror(errno)); ++ ctx.arguments.filename, strerror (errno)); + argp_help (&argp, stderr, ARGP_HELP_STD_USAGE, program); + free(program); + exit(1); +@@ -169,12 +180,12 @@ main (int argc, char *argv[]) + do + { + input = 0; +- get_config_line(&input, 0); ++ get_config_line (&input, 0, &ctx); + if (! input) + break; + found_input = 1; + +- script = grub_script_parse (input, get_config_line); ++ script = grub_script_parse (input, get_config_line, &ctx); + if (script) + { + grub_script_execute (script); +@@ -184,11 +195,11 @@ main (int argc, char *argv[]) + grub_free (input); + } while (script != 0); + +- if (file) fclose (file); ++ if (ctx.file) fclose (ctx.file); + + if (found_input && script == 0) + { +- fprintf (stderr, _("Syntax error at line %u\n"), lineno); ++ fprintf (stderr, _("Syntax error at line %u\n"), ctx.lineno); + return 1; + } + +-- +1.8.1.4 + diff --git a/0108-grub-core-script-lexer.c-grub_script_lexer_init-Rena.patch b/0108-grub-core-script-lexer.c-grub_script_lexer_init-Rena.patch new file mode 100644 index 0000000..066d901 --- /dev/null +++ b/0108-grub-core-script-lexer.c-grub_script_lexer_init-Rena.patch @@ -0,0 +1,50 @@ +From 60c3912bdb7a4dcc6fed286d18d8ce83d4f9b132 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Wed, 16 Jan 2013 09:06:11 +0100 +Subject: [PATCH 108/364] * grub-core/script/lexer.c + (grub_script_lexer_init): Rename getline argument to prevent name + collision. + +--- + ChangeLog | 5 +++++ + grub-core/script/lexer.c | 4 ++-- + 2 files changed, 7 insertions(+), 2 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index d02749b..76a9f68 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,8 @@ ++2013-01-16 Vladimir Serbinenko ++ ++ * grub-core/script/lexer.c (grub_script_lexer_init): Rename getline ++ argument to prevent name collision. ++ + 2013-01-15 Colin Watson + + Remove nested functions from script reading and parsing. +diff --git a/grub-core/script/lexer.c b/grub-core/script/lexer.c +index cb9d6b0..128d238 100644 +--- a/grub-core/script/lexer.c ++++ b/grub-core/script/lexer.c +@@ -216,7 +216,7 @@ grub_script_lexer_yywrap (struct grub_parser_param *parserstate, + + struct grub_lexer_param * + grub_script_lexer_init (struct grub_parser_param *parser, char *script, +- grub_reader_getline_t getline, void *getline_data) ++ grub_reader_getline_t arg_getline, void *getline_data) + { + struct grub_lexer_param *lexerstate; + +@@ -232,7 +232,7 @@ grub_script_lexer_init (struct grub_parser_param *parser, char *script, + return 0; + } + +- lexerstate->getline = getline; ++ lexerstate->getline = arg_getline; + lexerstate->getline_data = getline_data; + /* The other elements of lexerstate are all zeros already. */ + +-- +1.8.1.4 + diff --git a/0109-Improve-bidi-handling-in-entry-editor.patch b/0109-Improve-bidi-handling-in-entry-editor.patch new file mode 100644 index 0000000..aff2d73 --- /dev/null +++ b/0109-Improve-bidi-handling-in-entry-editor.patch @@ -0,0 +1,1372 @@ +From c9b4dc3d736299b64bf79c87cef9b745d041c6ec Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Wed, 16 Jan 2013 13:41:16 +0100 +Subject: [PATCH 109/364] Improve bidi handling in entry editor. + +--- + ChangeLog | 4 + + grub-core/gfxmenu/font.c | 2 +- + grub-core/normal/charset.c | 98 ++++++++++- + grub-core/normal/menu_entry.c | 394 ++++++++++++++++++------------------------ + grub-core/normal/term.c | 186 +++++++++++++++++--- + include/grub/normal.h | 8 + + include/grub/term.h | 6 +- + include/grub/unicode.h | 22 ++- + 8 files changed, 453 insertions(+), 267 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 76a9f68..96aca66 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,9 @@ + 2013-01-16 Vladimir Serbinenko + ++ Improve bidi handling in entry editor. ++ ++2013-01-16 Vladimir Serbinenko ++ + * grub-core/script/lexer.c (grub_script_lexer_init): Rename getline + argument to prevent name collision. + +diff --git a/grub-core/gfxmenu/font.c b/grub-core/gfxmenu/font.c +index 3c15e19..81a689d 100644 +--- a/grub-core/gfxmenu/font.c ++++ b/grub-core/gfxmenu/font.c +@@ -52,7 +52,7 @@ grub_font_draw_string (const char *str, grub_font_t font, + return grub_errno; + + visual_len = grub_bidi_logical_to_visual (logical, logical_len, &visual, +- 0, 0, 0); ++ 0, 0, 0, 0, 0, 0); + grub_free (logical); + if (visual_len < 0) + return grub_errno; +diff --git a/grub-core/normal/charset.c b/grub-core/normal/charset.c +index 25593ce..bd9fbf4 100644 +--- a/grub-core/normal/charset.c ++++ b/grub-core/normal/charset.c +@@ -513,7 +513,10 @@ bidi_line_wrap (struct grub_unicode_glyph *visual_out, + struct grub_unicode_glyph *visual, + grub_size_t visual_len, unsigned *levels, + grub_ssize_t (*getcharwidth) (const struct grub_unicode_glyph *visual), +- grub_size_t maxwidth, grub_size_t startwidth) ++ grub_size_t maxwidth, grub_size_t startwidth, ++ grub_uint32_t contchar, ++ struct grub_term_pos *pos, int primitive_wrap, ++ grub_size_t log_end) + { + struct grub_unicode_glyph *outptr = visual_out; + unsigned line_start = 0; +@@ -521,17 +524,30 @@ bidi_line_wrap (struct grub_unicode_glyph *visual_out, + unsigned k; + grub_ssize_t last_space = -1; + grub_ssize_t last_space_width = 0; ++ int lines = 0; + + auto void revert (unsigned start, unsigned end); + void revert (unsigned start, unsigned end) + { + struct grub_unicode_glyph t; + unsigned i, tl; ++ int a, b; ++ if (pos) ++ { ++ a = pos[visual[start].orig_pos].x; ++ b = pos[visual[end].orig_pos].x; ++ } + for (i = 0; i < (end - start) / 2 + 1; i++) + { + t = visual[start + i]; + visual[start + i] = visual[end - i]; + visual[end - i] = t; ++ ++ if (pos) ++ { ++ pos[visual[start + i].orig_pos].x = a + b - pos[visual[start + i].orig_pos].x; ++ pos[visual[end - i].orig_pos].x = a + b - pos[visual[end - i].orig_pos].x; ++ } + tl = levels[start + i]; + levels[start + i] = levels[end - i]; + levels[end - i] = tl; +@@ -545,11 +561,27 @@ bidi_line_wrap (struct grub_unicode_glyph *visual_out, + { + grub_ssize_t last_width = 0; + ++ ++ if (pos && k != visual_len) ++ { ++ pos[visual[k].orig_pos].x = line_width; ++ pos[visual[k].orig_pos].y = lines; ++ pos[visual[k].orig_pos].valid = 1; ++ } ++ ++ if (k == visual_len && pos) ++ { ++ pos[log_end].x = line_width; ++ pos[log_end].y = lines; ++ pos[log_end].valid = 1; ++ } ++ + if (getcharwidth && k != visual_len) + line_width += last_width = getcharwidth (&visual[k]); + + if (k != visual_len && (visual[k].base == ' ' +- || visual[k].base == '\t')) ++ || visual[k].base == '\t') ++ && !primitive_wrap) + { + last_space = k; + last_space_width = line_width; +@@ -561,9 +593,12 @@ bidi_line_wrap (struct grub_unicode_glyph *visual_out, + unsigned min_odd_level = 0xffffffff; + unsigned max_level = 0; + ++ lines++; ++ + if (k != visual_len && last_space > (signed) line_start) + k = last_space; +- else if (k != visual_len && line_start == 0 && startwidth != 0) ++ else if (k != visual_len && line_start == 0 && startwidth != 0 ++ && !primitive_wrap) + { + k = 0; + last_space_width = startwidth; +@@ -685,6 +720,12 @@ bidi_line_wrap (struct grub_unicode_glyph *visual_out, + outptr += k - line_start; + if (k != visual_len) + { ++ if (contchar) ++ { ++ grub_memset (outptr, 0, sizeof (visual[0])); ++ outptr->base = contchar; ++ outptr++; ++ } + grub_memset (outptr, 0, sizeof (visual[0])); + outptr->base = '\n'; + outptr++; +@@ -695,6 +736,11 @@ bidi_line_wrap (struct grub_unicode_glyph *visual_out, + + line_start = k; + line_width -= last_space_width; ++ if (pos && k != visual_len) ++ { ++ pos[visual[k].orig_pos].x = 0; ++ pos[visual[k].orig_pos].y = lines; ++ } + } + } + +@@ -707,7 +753,11 @@ grub_bidi_line_logical_to_visual (const grub_uint32_t *logical, + grub_size_t logical_len, + struct grub_unicode_glyph *visual_out, + grub_ssize_t (*getcharwidth) (const struct grub_unicode_glyph *visual), +- grub_size_t maxwidth, grub_size_t startwidth) ++ grub_size_t maxwidth, grub_size_t startwidth, ++ grub_uint32_t contchar, ++ struct grub_term_pos *pos, ++ int primitive_wrap, ++ grub_size_t log_end) + { + enum grub_bidi_type type = GRUB_BIDI_TYPE_L; + enum override_status {OVERRIDE_NEUTRAL = 0, OVERRIDE_R, OVERRIDE_L}; +@@ -832,7 +882,7 @@ grub_bidi_line_logical_to_visual (const grub_uint32_t *logical, + + p = grub_unicode_aglomerate_comb (lptr, logical + logical_len - lptr, + &visual[visual_len]); +- ++ visual[visual_len].orig_pos = lptr - logical; + type = get_bidi_type (visual[visual_len].base); + switch (type) + { +@@ -1066,7 +1116,8 @@ grub_bidi_line_logical_to_visual (const grub_uint32_t *logical, + { + grub_ssize_t ret; + ret = bidi_line_wrap (visual_out, visual, visual_len, levels, +- getcharwidth, maxwidth, startwidth); ++ getcharwidth, maxwidth, startwidth, contchar, ++ pos, primitive_wrap, log_end); + grub_free (levels); + grub_free (visual); + return ret; +@@ -1078,11 +1129,12 @@ grub_bidi_logical_to_visual (const grub_uint32_t *logical, + grub_size_t logical_len, + struct grub_unicode_glyph **visual_out, + grub_ssize_t (*getcharwidth) (const struct grub_unicode_glyph *visual), +- grub_size_t max_length, grub_size_t startwidth) ++ grub_size_t max_length, grub_size_t startwidth, ++ grub_uint32_t contchar, struct grub_term_pos *pos, int primitive_wrap) + { + const grub_uint32_t *line_start = logical, *ptr; + struct grub_unicode_glyph *visual_ptr; +- *visual_out = visual_ptr = grub_malloc (2 * sizeof (visual_ptr[0]) ++ *visual_out = visual_ptr = grub_malloc (3 * sizeof (visual_ptr[0]) + * logical_len); + if (!visual_ptr) + return -1; +@@ -1096,7 +1148,11 @@ grub_bidi_logical_to_visual (const grub_uint32_t *logical, + visual_ptr, + getcharwidth, + max_length, +- startwidth); ++ startwidth, ++ contchar, ++ pos, ++ primitive_wrap, ++ logical_len); + startwidth = 0; + + if (ret < 0) +@@ -1188,3 +1244,27 @@ grub_unicode_get_comb_start (const grub_uint32_t *str, + return str; + } + ++const grub_uint32_t * ++grub_unicode_get_comb_end (const grub_uint32_t *end, ++ const grub_uint32_t *cur) ++{ ++ const grub_uint32_t *ptr; ++ for (ptr = cur; ptr < end; ptr++) ++ { ++ if (*ptr >= GRUB_UNICODE_VARIATION_SELECTOR_1 ++ && *ptr <= GRUB_UNICODE_VARIATION_SELECTOR_16) ++ continue; ++ ++ if (*ptr >= GRUB_UNICODE_VARIATION_SELECTOR_17 ++ && *ptr <= GRUB_UNICODE_VARIATION_SELECTOR_256) ++ continue; ++ ++ enum grub_comb_type comb_type; ++ comb_type = grub_unicode_get_comb_type (*ptr); ++ if (comb_type) ++ continue; ++ return ptr; ++ } ++ return end; ++} ++ +diff --git a/grub-core/normal/menu_entry.c b/grub-core/normal/menu_entry.c +index 33b644b..7cd67f3 100644 +--- a/grub-core/normal/menu_entry.c ++++ b/grub-core/normal/menu_entry.c +@@ -43,15 +43,12 @@ struct line + int len; + /* The maximum length of the line. */ + int max_len; ++ struct grub_term_pos **pos; + }; + + struct per_term_screen + { + struct grub_term_output *term; +- /* The X coordinate. */ +- int x; +- /* The Y coordinate. */ +- int y; + int y_line_start; + /* Number of entries. */ + int num_entries; +@@ -90,13 +87,18 @@ static int completion_type; + + /* Initialize a line. */ + static int +-init_line (struct line *linep) ++init_line (struct screen *screen, struct line *linep) + { + linep->len = 0; + linep->max_len = 80; + linep->buf = grub_malloc ((linep->max_len + 1) * sizeof (linep->buf[0])); +- if (! linep->buf) +- return 0; ++ linep->pos = grub_zalloc (screen->nterms * sizeof (linep->pos[0])); ++ if (! linep->buf || !linep->pos) ++ { ++ grub_free (linep->buf); ++ grub_free (linep->pos); ++ return 0; ++ } + + return 1; + } +@@ -126,93 +128,16 @@ get_logical_num_lines (struct line *linep, struct per_term_screen *term_screen) + } + + static void +-advance (struct screen *screen) +-{ +- unsigned i; +- struct grub_unicode_glyph glyph; +- +- screen->column += grub_unicode_aglomerate_comb (screen->lines[screen->line].buf + screen->column, +- screen->lines[screen->line].len - screen->column, +- &glyph); +- +- for (i = 0; i < screen->nterms; i++) +- { +- grub_ssize_t width; +- width = grub_term_getcharwidth (screen->terms[i].term, &glyph); +- screen->terms[i].x += width; +- if (screen->terms[i].x +- == grub_term_entry_width (screen->terms[i].term)) +- { +- screen->terms[i].x = 0; +- screen->terms[i].y++; +- } +- if (screen->terms[i].x +- > grub_term_entry_width (screen->terms[i].term)) +- { +- screen->terms[i].x = width; +- screen->terms[i].y++; +- } +- } +- grub_free (glyph.combining); +-} +- +-static void + advance_to (struct screen *screen, int c) + { + if (c > screen->lines[screen->line].len) + c = screen->lines[screen->line].len; + +- while (screen->column < c) +- advance (screen); +-} +- +-/* Print a line. */ +-static int +-print_line (struct line *linep, int offset, int y, +- struct per_term_screen *term_screen, int dry_run) +-{ +- int x; +- int i; +- +- grub_term_gotoxy (term_screen->term, +- GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN + 1, +- y + GRUB_TERM_FIRST_ENTRY_Y); +- +- x = 0; +- for (i = 0; i + offset < (int) linep->len;) +- { +- grub_ssize_t width; +- grub_size_t delta = 0; +- struct grub_unicode_glyph glyph; +- +- delta = grub_unicode_aglomerate_comb (linep->buf + offset + i, +- linep->len - offset - i, +- &glyph); +- width = grub_term_getcharwidth (term_screen->term, &glyph); +- grub_free (glyph.combining); +- +- if (x + width > grub_term_entry_width (term_screen->term) && x != 0) +- break; +- x += width; +- i += delta; +- } +- +- if (dry_run) +- return i; +- +- grub_print_ucs4 (linep->buf + offset, +- linep->buf + offset + i, 0, 0, term_screen->term); +- +- if (i + offset != linep->len) +- grub_putcode ('\\', term_screen->term); +- else +- { +- for (; +- x <= (int) grub_term_entry_width (term_screen->term); +- x++) +- grub_putcode (' ', term_screen->term); +- } +- return i; ++ screen->column = grub_unicode_get_comb_end (screen->lines[screen->line].buf ++ + screen->lines[screen->line].len, ++ screen->lines[screen->line].buf ++ + c) ++ - screen->lines[screen->line].buf; + } + + /* Print an empty line. */ +@@ -225,7 +150,7 @@ print_empty_line (int y, struct per_term_screen *term_screen) + GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN + 1, + y + GRUB_TERM_FIRST_ENTRY_Y); + +- for (i = 0; i < grub_term_entry_width (term_screen->term) + 1; i++) ++ for (i = 0; i < grub_term_entry_width (term_screen->term); i++) + grub_putcode (' ', term_screen->term); + } + +@@ -261,7 +186,7 @@ print_down (int flag, struct per_term_screen *term_screen) + /* Draw the lines of the screen SCREEN. */ + static void + update_screen (struct screen *screen, struct per_term_screen *term_screen, +- int region_start, int region_column, ++ int region_start, int region_column __attribute__ ((unused)), + int up, int down, enum update_mode mode) + { + int up_flag = 0; +@@ -270,19 +195,26 @@ update_screen (struct screen *screen, struct per_term_screen *term_screen, + int i; + struct line *linep; + ++ y = term_screen->y_line_start; ++ linep = screen->lines; ++ ++ for (i = 0; i < screen->line; i++, linep++) ++ y += get_logical_num_lines (linep, term_screen); ++ linep = screen->lines + screen->line; ++ y += grub_getstringwidth (linep->buf, linep->buf + screen->column, ++ term_screen->term) / grub_term_entry_width (term_screen->term); ++ + /* Check if scrolling is necessary. */ +- if (term_screen->y < 0 || term_screen->y >= term_screen->num_entries) ++ if (y < 0 || y >= term_screen->num_entries) + { + int delta; +- if (term_screen->y < 0) +- delta = -term_screen->y; ++ if (y < 0) ++ delta = -y; + else +- delta = term_screen->num_entries - 1 - term_screen->y; +- term_screen->y += delta; ++ delta = term_screen->num_entries - 1 - y; + term_screen->y_line_start += delta; + + region_start = 0; +- region_column = 0; + up = 1; + down = 1; + mode = ALL_LINES; +@@ -293,58 +225,81 @@ update_screen (struct screen *screen, struct per_term_screen *term_screen, + /* Draw lines. This code is tricky, because this must calculate logical + positions. */ + y = term_screen->y_line_start; +- i = screen->line; +- linep = screen->lines + i; +- while (y > 0) +- { +- i--; +- linep--; +- y -= get_logical_num_lines (linep, term_screen); +- } ++ i = 0; ++ linep = screen->lines; ++ while (1) ++ { ++ int add; ++ add = get_logical_num_lines (linep, term_screen); ++ if (y + add > 0) ++ break; ++ i++; ++ linep++; ++ y += add; ++ } + + if (y < 0 || i > 0) + up_flag = 1; + + do + { +- int column; + int off = 0; +- int full_len; ++ struct grub_term_pos **pos; + + if (linep >= screen->lines + screen->num_lines) + break; + +- full_len = grub_getstringwidth (linep->buf, linep->buf + linep->len, +- term_screen->term); ++ pos = linep->pos + (term_screen - screen->terms); + +- for (column = 0; +- column <= full_len +- && y < term_screen->num_entries; +- column += grub_term_entry_width (term_screen->term), y++) ++ if (!*pos) ++ *pos = grub_zalloc ((linep->len + 1) * sizeof (**pos)); ++ ++ if (i == region_start || linep == screen->lines + screen->line) ++ { ++ int sp; ++ grub_term_gotoxy (term_screen->term, GRUB_TERM_LEFT_BORDER_X ++ + GRUB_TERM_MARGIN + 1, (y < 0 ? 0 : y) ++ + GRUB_TERM_FIRST_ENTRY_Y); ++ grub_print_ucs4_menu (linep->buf, ++ linep->buf + linep->len, ++ GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN ++ + 1, ++ GRUB_TERM_MARGIN ++ + GRUB_TERM_SCROLL_WIDTH + 2, ++ term_screen->term, ++ (y < 0) ? -y : 0, ++ term_screen->num_entries ++ - ((y > 0) ? y : 0), '\\', ++ *pos); ++ sp = grub_term_entry_width (term_screen->term) ++ - (*pos)[linep->len].x; ++ if (sp > 0) ++ grub_print_spaces (term_screen->term, sp); ++ } ++ else if (i > region_start && mode == ALL_LINES) + { +- if (y < 0) +- { +- off += print_line (linep, off, y, term_screen, 1); +- continue; +- } +- +- if (i == region_start) +- { +- if (region_column >= column +- && region_column +- < (column +- + grub_term_entry_width (term_screen->term))) +- off += print_line (linep, off, y, term_screen, 0); +- else if (region_column < column) +- off += print_line (linep, off, y, term_screen, 0); +- else +- off += print_line (linep, off, y, term_screen, 1); +- } +- else if (i > region_start && mode == ALL_LINES) +- off += print_line (linep, off, y, term_screen, 0); ++ int sp; ++ grub_term_gotoxy (term_screen->term, GRUB_TERM_LEFT_BORDER_X ++ + GRUB_TERM_MARGIN + 1, (y < 0 ? 0 : y) ++ + GRUB_TERM_FIRST_ENTRY_Y); ++ grub_print_ucs4_menu (linep->buf, ++ linep->buf + linep->len, ++ GRUB_TERM_LEFT_BORDER_X ++ + GRUB_TERM_MARGIN + 1, ++ GRUB_TERM_MARGIN ++ + GRUB_TERM_SCROLL_WIDTH + 2, ++ term_screen->term, ++ (y < 0) ? -y : 0, ++ term_screen->num_entries ++ - ((y > 0) ? y : 0), '\\', ++ *pos); ++ sp = grub_term_entry_width (term_screen->term) ++ - (*pos)[linep->len].x; ++ if (sp > 0) ++ grub_print_spaces (term_screen->term, sp); + } +- +- if (y == term_screen->num_entries) ++ y += get_logical_num_lines (linep, term_screen); ++ if (y >= term_screen->num_entries) + { + if (off <= linep->len || i + 1 < screen->num_lines) + down_flag = 1; +@@ -367,10 +322,30 @@ update_screen (struct screen *screen, struct per_term_screen *term_screen, + } + + /* Place the cursor. */ +- grub_term_gotoxy (term_screen->term, +- GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN + 1 +- + term_screen->x, +- GRUB_TERM_FIRST_ENTRY_Y + term_screen->y); ++ if (screen->lines[screen->line].pos[term_screen - screen->terms]) ++ { ++ const struct grub_term_pos *cpos; ++ for (cpos = &(screen->lines[screen->line].pos[term_screen - screen->terms])[screen->column]; ++ cpos >= &(screen->lines[screen->line].pos[term_screen - screen->terms])[0]; ++ cpos--) ++ if (cpos->valid) ++ break; ++ y = term_screen->y_line_start; ++ for (i = 0; i < screen->line; i++) ++ y += get_logical_num_lines (screen->lines + i, term_screen); ++ if (cpos >= &(screen->lines[screen->line].pos[term_screen - screen->terms])[0]) ++ grub_term_gotoxy (term_screen->term, ++ cpos->x + GRUB_TERM_LEFT_BORDER_X ++ + GRUB_TERM_MARGIN + 1, ++ cpos->y + y ++ + GRUB_TERM_FIRST_ENTRY_Y); ++ else ++ grub_term_gotoxy (term_screen->term, ++ GRUB_TERM_LEFT_BORDER_X ++ + GRUB_TERM_MARGIN + 1, ++ y + GRUB_TERM_FIRST_ENTRY_Y); ++ ++ } + + grub_term_refresh (term_screen->term); + } +@@ -424,7 +399,7 @@ insert_string (struct screen *screen, const char *s, int update) + ((screen->num_lines - screen->line - 2) + * sizeof (struct line))); + +- if (! init_line (screen->lines + screen->line + 1)) ++ if (! init_line (screen, screen->lines + screen->line + 1)) + return 0; + + /* Fold the line. */ +@@ -439,6 +414,11 @@ insert_string (struct screen *screen, const char *s, int update) + current_linep->buf + screen->column, + size * sizeof (next_linep->buf[0])); + current_linep->len = screen->column; ++ for (i = 0; i < screen->nterms; i++) ++ { ++ grub_free (current_linep->pos[i]); ++ current_linep->pos[i] = 0; ++ } + next_linep->len = size; + + /* Update a dirty region. */ +@@ -457,12 +437,6 @@ insert_string (struct screen *screen, const char *s, int update) + /* Move the cursor. */ + screen->column = screen->real_column = 0; + screen->line++; +- for (i = 0; i < screen->nterms; i++) +- { +- screen->terms[i].x = 0; +- screen->terms[i].y++; +- screen->terms[i].y_line_start = screen->terms[i].y; +- } + s++; + } + else +@@ -502,6 +476,12 @@ insert_string (struct screen *screen, const char *s, int update) + grub_free (unicode_msg); + + for (i = 0; i < screen->nterms; i++) ++ { ++ grub_free (current_linep->pos[i]); ++ current_linep->pos[i] = 0; ++ } ++ ++ for (i = 0; i < screen->nterms; i++) + orig_num[i] = get_logical_num_lines (current_linep, + &screen->terms[i]); + current_linep->len += size; +@@ -582,7 +562,7 @@ make_screen (grub_menu_entry_t entry) + goto fail; + + /* Initialize the first line which must be always present. */ +- if (! init_line (screen->lines)) ++ if (! init_line (screen, screen->lines)) + goto fail; + + insert_string (screen, (char *) entry->sourcecode, 0); +@@ -593,9 +573,7 @@ make_screen (grub_menu_entry_t entry) + screen->line = 0; + for (i = 0; i < screen->nterms; i++) + { +- screen->terms[i].x = 0; +- screen->terms[i].y = 0; +- screen->terms[i].y_line_start = screen->terms[i].y; ++ screen->terms[i].y_line_start = 0; + } + + return screen; +@@ -609,21 +587,20 @@ static int + forward_char (struct screen *screen, int update) + { + struct line *linep; +- unsigned i; + + linep = screen->lines + screen->line; + if (screen->column < linep->len) +- advance (screen); ++ { ++ screen->column = grub_unicode_get_comb_end (screen->lines[screen->line].buf ++ + screen->lines[screen->line].len, ++ screen->lines[screen->line].buf ++ + screen->column + 1) ++ - screen->lines[screen->line].buf; ++ } + else if (screen->num_lines > screen->line + 1) + { + screen->column = 0; + screen->line++; +- for (i = 0; i < screen->nterms; i++) +- { +- screen->terms[i].x = 0; +- screen->terms[i].y++; +- screen->terms[i].y_line_start = screen->terms[i].y; +- } + } + + screen->real_column = screen->column; +@@ -636,8 +613,6 @@ forward_char (struct screen *screen, int update) + static int + backward_char (struct screen *screen, int update) + { +- unsigned i; +- + if (screen->column > 0) + { + struct grub_unicode_glyph glyph; +@@ -653,36 +628,16 @@ backward_char (struct screen *screen, int update) + grub_unicode_aglomerate_comb (screen->lines[screen->line].buf + screen->column, + screen->lines[screen->line].len - screen->column, + &glyph); ++ screen->column = grub_unicode_get_comb_start (linep->buf, ++ linep->buf + screen->column) ++ - linep->buf; + +- for (i = 0; i < screen->nterms; i++) +- { +- grub_ssize_t width; +- width = grub_term_getcharwidth (screen->terms[i].term, &glyph); +- screen->terms[i].x -= width; +- if (screen->terms[i].x < 0) +- { +- screen->terms[i].x +- = grub_term_entry_width (screen->terms[i].term) - 1; +- screen->terms[i].y--; +- } +- } + grub_free (glyph.combining); + } + else if (screen->line > 0) + { +- struct line *linep; +- +- screen->column = 0; + screen->line--; +- linep = screen->lines + screen->line; +- +- for (i = 0; i < screen->nterms; i++) +- { +- screen->terms[i].y_line_start -= get_logical_num_lines (linep, &screen->terms[i]); +- screen->terms[i].y = screen->terms[i].y_line_start; +- screen->terms[i].x = 0; +- } +- advance_to (screen, screen->lines[screen->line].len); ++ screen->column = screen->lines[screen->line].len; + } + + screen->real_column = screen->column; +@@ -696,8 +651,6 @@ backward_char (struct screen *screen, int update) + static int + previous_line (struct screen *screen, int update) + { +- unsigned i; +- + if (screen->line > 0) + { + struct line *linep; +@@ -712,22 +665,10 @@ previous_line (struct screen *screen, int update) + col = screen->real_column; + + screen->column = 0; +- +- for (i = 0; i < screen->nterms; i++) +- { +- screen->terms[i].y_line_start -= get_logical_num_lines (linep, &screen->terms[i]); +- screen->terms[i].y = screen->terms[i].y_line_start; +- screen->terms[i].x = 0; +- } + advance_to (screen, col); + } + else + { +- for (i = 0; i < screen->nterms; i++) +- { +- screen->terms[i].y = screen->terms[i].y_line_start; +- screen->terms[i].x = 0; +- } + screen->column = 0; + } + +@@ -740,8 +681,6 @@ previous_line (struct screen *screen, int update) + static int + next_line (struct screen *screen, int update) + { +- unsigned i; +- + if (screen->line < screen->num_lines - 1) + { + struct line *linep; +@@ -758,12 +697,6 @@ next_line (struct screen *screen, int update) + c = screen->real_column; + screen->column = 0; + +- for (i = 0; i < screen->nterms; i++) +- { +- screen->terms[i].y_line_start += get_logical_num_lines (linep, &screen->terms[i]); +- screen->terms[i].x = 0; +- screen->terms[i].y = screen->terms[i].y_line_start; +- } + advance_to (screen, c); + } + else +@@ -778,14 +711,7 @@ next_line (struct screen *screen, int update) + static int + beginning_of_line (struct screen *screen, int update) + { +- unsigned i; +- + screen->column = screen->real_column = 0; +- for (i = 0; i < screen->nterms; i++) +- { +- screen->terms[i].x = 0; +- screen->terms[i].y = screen->terms[i].y_line_start; +- } + + if (update) + update_screen_all (screen, screen->num_lines, 0, 0, 0, NO_LINE); +@@ -826,6 +752,11 @@ delete_char (struct screen *screen, int update) + * sizeof (linep->buf[0])); + linep->len--; + ++ for (i = 0; i < screen->nterms; i++) ++ { ++ grub_free (linep->pos[i]); ++ linep->pos[i] = 0; ++ } + start = screen->line; + column = screen->column; + +@@ -848,6 +779,7 @@ delete_char (struct screen *screen, int update) + else if (screen->num_lines > screen->line + 1) + { + struct line *next_linep; ++ unsigned i; + + next_linep = linep + 1; + if (! ensure_space (linep, next_linep->len)) +@@ -856,6 +788,11 @@ delete_char (struct screen *screen, int update) + grub_memmove (linep->buf + linep->len, next_linep->buf, + next_linep->len * sizeof (linep->buf[0])); + linep->len += next_linep->len; ++ for (i = 0; i < screen->nterms; i++) ++ { ++ grub_free (linep->pos[i]); ++ linep->pos[i] = 0; ++ } + + grub_free (next_linep->buf); + grub_memmove (next_linep, +@@ -975,24 +912,12 @@ yank (struct screen *screen, int update) + static int + open_line (struct screen *screen, int update) + { +- int saved_y[screen->nterms]; +- unsigned i; +- +- for (i = 0; i < screen->nterms; i++) +- saved_y[i] = screen->terms[i].y; +- + if (! insert_string (screen, "\n", 0)) + return 0; + + if (! backward_char (screen, 0)) + return 0; + +- for (i = 0; i < screen->nterms; i++) +- { +- screen->terms[i].y = saved_y[i]; +- screen->terms[i].y_line_start = screen->terms[i].y; +- } +- + if (update) + update_screen_all (screen, screen->line, screen->column, 0, 1, ALL_LINES); + +@@ -1303,7 +1228,20 @@ grub_menu_entry_run (grub_menu_entry_t entry) + screen->nterms = 0; + FOR_ACTIVE_TERM_OUTPUTS(term) + screen->nterms++; +- screen->terms = grub_malloc (screen->nterms * sizeof (screen->terms[0])); ++ ++ for (i = 0; i < (unsigned) screen->num_lines; i++) ++ { ++ grub_free (screen->lines[i].pos); ++ screen->lines[i].pos = grub_zalloc (screen->nterms * sizeof (screen->lines[i].pos[0])); ++ if (! screen->lines[i].pos) ++ { ++ grub_print_error (); ++ grub_errno = GRUB_ERR_NONE; ++ return; ++ } ++ } ++ ++ screen->terms = grub_zalloc (screen->nterms * sizeof (screen->terms[0])); + if (!screen->terms) + { + grub_print_error (); +@@ -1314,9 +1252,7 @@ grub_menu_entry_run (grub_menu_entry_t entry) + FOR_ACTIVE_TERM_OUTPUTS(term) + { + screen->terms[i].term = term; +- screen->terms[i].x = 0; +- screen->terms[i].y = 0; +- screen->terms[i].y_line_start = screen->terms[i].y; ++ screen->terms[i].y_line_start = 0; + i++; + } + /* Draw the screen. */ +diff --git a/grub-core/normal/term.c b/grub-core/normal/term.c +index dc5fdcb..43622be 100644 +--- a/grub-core/normal/term.c ++++ b/grub-core/normal/term.c +@@ -34,6 +34,10 @@ struct term_state + int backlog_fixed_tab; + grub_size_t backlog_len; + ++ int bidi_stack_depth; ++ grub_uint8_t bidi_stack[GRUB_BIDI_MAX_EXPLICIT_LEVEL]; ++ int invalid_pushes; ++ + void *free; + int num_lines; + char *term_name; +@@ -44,7 +48,9 @@ print_ucs4_real (const grub_uint32_t * str, + const grub_uint32_t * last_position, + int margin_left, int margin_right, + struct grub_term_output *term, int backlog, +- int dry_run, int fixed_tab); ++ int dry_run, int fixed_tab, unsigned skip_lines, ++ unsigned max_lines, ++ grub_uint32_t contchar, struct grub_term_pos *pos); + + static struct term_state *term_states = NULL; + +@@ -243,7 +249,8 @@ grub_puts_terminal (const char *str, struct grub_term_output *term) + return; + } + +- print_ucs4_real (unicode_str, unicode_last_position, 0, 0, term, 0, 0, 0); ++ print_ucs4_real (unicode_str, unicode_last_position, 0, 0, term, ++ 0, 0, 0, 0, -1, 0, 0); + grub_free (unicode_str); + } + +@@ -541,13 +548,25 @@ get_startwidth (struct grub_term_output *term, + return ((term->getxy (term) >> 8) & 0xff) - margin_left; + } + ++static void ++fill_margin (struct grub_term_output *term, int r) ++{ ++ int sp = (term->getwh (term) >> 8) ++ - (term->getxy (term) >> 8) - r; ++ if (sp > 0) ++ grub_print_spaces (term, sp); ++} ++ + static int + print_ucs4_terminal (const grub_uint32_t * str, + const grub_uint32_t * last_position, + int margin_left, int margin_right, + struct grub_term_output *term, + struct term_state *state, +- int dry_run, int fixed_tab) ++ int dry_run, int fixed_tab, unsigned skip_lines, ++ unsigned max_lines, ++ grub_uint32_t contchar, ++ int primitive_wrap, struct grub_term_pos *pos) + { + const grub_uint32_t *ptr; + grub_ssize_t startwidth = dry_run ? 0 : get_startwidth (term, margin_left); +@@ -556,10 +575,40 @@ print_ucs4_terminal (const grub_uint32_t * str, + grub_ssize_t max_width = get_maxwidth (term, margin_left, margin_right); + const grub_uint32_t *line_start = str, *last_space = str - 1; + int lines = 0; ++ int i; ++ struct term_state local_state; ++ ++ if (!state) ++ { ++ grub_memset (&local_state, 0, sizeof (local_state)); ++ state = &local_state; ++ } ++ ++ for (i = 0; i < state->bidi_stack_depth; i++) ++ putcode_real (state->bidi_stack[i] | (GRUB_UNICODE_LRE & ~0xff), ++ term, fixed_tab); + + for (ptr = str; ptr < last_position; ptr++) + { + grub_ssize_t last_width = 0; ++ switch (*ptr) ++ { ++ case GRUB_UNICODE_LRE: ++ case GRUB_UNICODE_RLE: ++ case GRUB_UNICODE_LRO: ++ case GRUB_UNICODE_RLO: ++ if (state->bidi_stack_depth >= (int) ARRAY_SIZE (state->bidi_stack)) ++ state->invalid_pushes++; ++ else ++ state->bidi_stack[state->bidi_stack_depth++] = *ptr; ++ break; ++ case GRUB_UNICODE_PDF: ++ if (state->invalid_pushes) ++ state->invalid_pushes--; ++ else if (state->bidi_stack_depth) ++ state->bidi_stack_depth--; ++ break; ++ } + if (grub_unicode_get_comb_type (*ptr) == GRUB_UNICODE_COMB_NONE) + { + struct grub_unicode_glyph c = { +@@ -569,10 +618,16 @@ print_ucs4_terminal (const grub_uint32_t * str, + .combining = 0 + }; + c.base = *ptr; ++ if (pos) ++ { ++ pos[ptr - str].x = line_width; ++ pos[ptr - str].y = lines; ++ pos[ptr - str].valid = 1; ++ } + line_width += last_width = grub_term_getcharwidth (term, &c); + } + +- if (*ptr == ' ') ++ if (*ptr == ' ' && !primitive_wrap) + { + lastspacewidth = line_width; + last_space = ptr; +@@ -581,6 +636,13 @@ print_ucs4_terminal (const grub_uint32_t * str, + if (line_width > max_width || *ptr == '\n') + { + const grub_uint32_t *ptr2; ++ int wasn = (*ptr == '\n'); ++ ++ if (wasn) ++ { ++ state->bidi_stack_depth = 0; ++ state->invalid_pushes = 0; ++ } + + if (line_width > max_width && last_space > line_start) + ptr = last_space; +@@ -595,7 +657,7 @@ print_ucs4_terminal (const grub_uint32_t * str, + + lines++; + +- if (!dry_run) ++ if (!skip_lines && !dry_run) + { + for (ptr2 = line_start; ptr2 < ptr; ptr2++) + { +@@ -608,9 +670,12 @@ print_ucs4_terminal (const grub_uint32_t * str, + putcode_real (*ptr2, term, fixed_tab); + } + +- grub_print_spaces (term, margin_right); ++ if (!wasn && contchar) ++ putcode_real (contchar, term, fixed_tab); ++ fill_margin (term, contchar ? margin_right : 1); ++ + grub_putcode ('\n', term); +- if (state && ++state->num_lines ++ if (state != &local_state && ++state->num_lines + >= (grub_ssize_t) grub_term_height (term) - 2) + { + state->backlog_ucs4 = (ptr == last_space || *ptr == '\n') +@@ -622,17 +687,42 @@ print_ucs4_terminal (const grub_uint32_t * str, + } + + line_width -= lastspacewidth; +- if (!dry_run) +- grub_print_spaces (term, margin_left); + if (ptr == last_space || *ptr == '\n') + ptr++; + line_start = ptr; ++ ++ if (skip_lines) ++ skip_lines--; ++ else if (max_lines != (unsigned) -1) ++ { ++ max_lines--; ++ if (!max_lines) ++ break; ++ } ++ if (!skip_lines && !dry_run) ++ { ++ if (!contchar) ++ grub_print_spaces (term, margin_left); ++ else ++ grub_term_gotoxy (term, margin_left, ++ grub_term_getxy (term) & 0xff); ++ for (i = 0; i < state->bidi_stack_depth; i++) ++ putcode_real (state->bidi_stack[i] | (GRUB_UNICODE_LRE & ~0xff), ++ term, fixed_tab); ++ } + } + } + ++ if (pos) ++ { ++ pos[ptr - str].x = line_width; ++ pos[ptr - str].y = lines; ++ pos[ptr - str].valid = 1; ++ } ++ + if (line_start < last_position) + lines++; +- if (!dry_run) ++ if (!dry_run && !skip_lines && max_lines) + { + const grub_uint32_t *ptr2; + for (ptr2 = line_start; ptr2 < last_position; ptr2++) +@@ -717,7 +807,8 @@ print_backlog (struct grub_term_output *term, + ret = print_ucs4_terminal (state->backlog_ucs4, + state->backlog_ucs4 + state->backlog_len, + margin_left, margin_right, term, state, 0, +- state->backlog_fixed_tab); ++ state->backlog_fixed_tab, 0, -1, 0, 0, ++ 0); + if (!ret) + { + grub_free (state->free); +@@ -753,17 +844,28 @@ print_ucs4_real (const grub_uint32_t * str, + const grub_uint32_t * last_position, + int margin_left, int margin_right, + struct grub_term_output *term, int backlog, +- int dry_run, int fixed_tab) ++ int dry_run, int fixed_tab, unsigned skip_lines, ++ unsigned max_lines, ++ grub_uint32_t contchar, struct grub_term_pos *pos) + { + struct term_state *state = NULL; + + if (!dry_run) + { ++ int xy; + if (backlog) + state = find_term_state (term); + +- if (((term->getxy (term) >> 8) & 0xff) < margin_left) +- grub_print_spaces (term, margin_left - ((term->getxy (term) >> 8) & 0xff)); ++ xy = term->getxy (term); ++ ++ if (((xy >> 8) & 0xff) < margin_left) ++ { ++ if (!contchar) ++ grub_print_spaces (term, margin_left - ((xy >> 8) & 0xff)); ++ else ++ grub_term_gotoxy (term, margin_left, ++ xy & 0xff); ++ } + } + + if ((term->flags & GRUB_TERM_CODE_TYPE_MASK) +@@ -773,7 +875,10 @@ print_ucs4_real (const grub_uint32_t * str, + { + grub_ssize_t visual_len; + struct grub_unicode_glyph *visual; ++ grub_ssize_t visual_len_show; ++ struct grub_unicode_glyph *visual_show; + int ret; ++ struct grub_unicode_glyph *vptr; + + auto grub_ssize_t getcharwidth (const struct grub_unicode_glyph *c); + grub_ssize_t getcharwidth (const struct grub_unicode_glyph *c) +@@ -787,27 +892,45 @@ print_ucs4_real (const grub_uint32_t * str, + margin_left, + margin_right), + get_startwidth (term, +- margin_left)); ++ margin_left), ++ contchar, pos, !!contchar); + if (visual_len < 0) + { + grub_print_error (); + return 0; + } ++ visual_show = visual; ++ for (; skip_lines && visual_show < visual + visual_len; visual_show++) ++ if (visual_show->base == '\n') ++ skip_lines--; ++ if (max_lines != (unsigned) -1) ++ { ++ for (vptr = visual_show; ++ max_lines && vptr < visual + visual_len; vptr++) ++ if (visual_show->base == '\n') ++ max_lines--; ++ ++ visual_len_show = vptr - visual_show; ++ } ++ else ++ visual_len_show = visual + visual_len - visual_show; ++ + if (dry_run) + { +- struct grub_unicode_glyph *vptr; + ret = 0; +- for (vptr = visual; vptr < visual + visual_len; vptr++) ++ for (vptr = visual_show; vptr < visual_show + visual_len_show; vptr++) + if (vptr->base == '\n') + ret++; +- if (visual_len && visual[visual_len - 1].base != '\n') ++ if (visual_len_show && visual[visual_len_show - 1].base != '\n') + ret++; + grub_free (visual); + } + else + { +- ret = put_glyphs_terminal (visual, visual_len, margin_left, +- margin_right, term, state, fixed_tab); ++ ret = put_glyphs_terminal (visual_show, visual_len_show, margin_left, ++ contchar ? margin_right : 1, ++ term, state, fixed_tab); ++ + if (!ret) + grub_free (visual); + else +@@ -816,7 +939,22 @@ print_ucs4_real (const grub_uint32_t * str, + return ret; + } + return print_ucs4_terminal (str, last_position, margin_left, margin_right, +- term, state, dry_run, fixed_tab); ++ term, state, dry_run, fixed_tab, skip_lines, ++ max_lines, contchar, !!contchar, pos); ++} ++ ++void ++grub_print_ucs4_menu (const grub_uint32_t * str, ++ const grub_uint32_t * last_position, ++ int margin_left, int margin_right, ++ struct grub_term_output *term, ++ int skip_lines, int max_lines, ++ grub_uint32_t contchar, ++ struct grub_term_pos *pos) ++{ ++ print_ucs4_real (str, last_position, margin_left, margin_right, ++ term, 0, 0, 1, skip_lines, max_lines, ++ contchar, pos); + } + + void +@@ -826,7 +964,7 @@ grub_print_ucs4 (const grub_uint32_t * str, + struct grub_term_output *term) + { + print_ucs4_real (str, last_position, margin_left, margin_right, +- term, 0, 0, 1); ++ term, 0, 0, 1, 0, -1, 0, 0); + } + + int +@@ -836,7 +974,7 @@ grub_ucs4_count_lines (const grub_uint32_t * str, + struct grub_term_output *term) + { + return print_ucs4_real (str, last_position, margin_left, margin_right, +- term, 0, 1, 1); ++ term, 0, 1, 1, 0, -1, 0, 0); + } + + void +@@ -886,7 +1024,7 @@ grub_xputs_normal (const char *str) + { + int cur; + cur = print_ucs4_real (unicode_str, unicode_last_position, 0, 0, +- term, grub_more, 0, 0); ++ term, grub_more, 0, 0, 0, -1, 0, 0); + if (cur) + backlog = 1; + } +diff --git a/include/grub/normal.h b/include/grub/normal.h +index e88cd26..416faa4 100644 +--- a/include/grub/normal.h ++++ b/include/grub/normal.h +@@ -77,6 +77,14 @@ grub_print_ucs4 (const grub_uint32_t * str, + const grub_uint32_t * last_position, + int margin_left, int margin_right, + struct grub_term_output *term); ++ ++void ++grub_print_ucs4_menu (const grub_uint32_t * str, ++ const grub_uint32_t * last_position, ++ int margin_left, int margin_right, ++ struct grub_term_output *term, ++ int skip_lines, int max_lines, grub_uint32_t contchar, ++ struct grub_term_pos *pos); + int + grub_ucs4_count_lines (const grub_uint32_t * str, + const grub_uint32_t * last_position, +diff --git a/include/grub/term.h b/include/grub/term.h +index bf4dcb4..39c3d5a 100644 +--- a/include/grub/term.h ++++ b/include/grub/term.h +@@ -104,7 +104,7 @@ grub_term_color_state; + #define GRUB_TERM_CODE_TYPE_CP437 (1 << GRUB_TERM_CODE_TYPE_SHIFT) + /* UTF-8 stream in logical order. Usually used for terminals + which just forward the stream to another computer. */ +-#define GRUB_TERM_CODE_TYPE_UTF8_LOGICAL (2 << GRUB_TERM_CODE_TYPE_SHIFT) ++#define GRUB_TERM_CODE_TYPE_UTF8_LOGICAL (2 << GRUB_TERM_CODE_TYPE_SHIFT) + /* UTF-8 in visual order. Like UTF-8 logical but for buggy endpoints. */ + #define GRUB_TERM_CODE_TYPE_UTF8_VISUAL (3 << GRUB_TERM_CODE_TYPE_SHIFT) + /* Glyph description in visual order. */ +@@ -344,7 +344,7 @@ static inline unsigned grub_term_height (struct grub_term_output *term) + static inline unsigned + grub_term_border_width (struct grub_term_output *term) + { +- return grub_term_width (term) - GRUB_TERM_MARGIN * 3 - GRUB_TERM_SCROLL_WIDTH; ++ return grub_term_width (term) - GRUB_TERM_MARGIN * 2; + } + + /* The max column number of an entry. The last "-1" is for a +@@ -352,7 +352,7 @@ grub_term_border_width (struct grub_term_output *term) + static inline int + grub_term_entry_width (struct grub_term_output *term) + { +- return grub_term_border_width (term) - 2 - GRUB_TERM_MARGIN * 2 - 1; ++ return grub_term_border_width (term) - GRUB_TERM_MARGIN * 2 - 1; + } + + static inline grub_uint16_t +diff --git a/include/grub/unicode.h b/include/grub/unicode.h +index 763e25e..eb5051a 100644 +--- a/include/grub/unicode.h ++++ b/include/grub/unicode.h +@@ -139,6 +139,7 @@ struct grub_unicode_glyph + grub_uint16_t variant:9; + grub_uint8_t attributes:5; + grub_size_t ncomb; ++ grub_size_t orig_pos; + struct grub_unicode_combining { + grub_uint32_t code; + enum grub_comb_type type; +@@ -186,6 +187,13 @@ enum + GRUB_UNICODE_THAANA_SUKUN = 0x07b0, + GRUB_UNICODE_ZWNJ = 0x200c, + GRUB_UNICODE_ZWJ = 0x200d, ++ GRUB_UNICODE_LRM = 0x200e, ++ GRUB_UNICODE_RLM = 0x200f, ++ GRUB_UNICODE_LRE = 0x202a, ++ GRUB_UNICODE_RLE = 0x202b, ++ GRUB_UNICODE_PDF = 0x202c, ++ GRUB_UNICODE_LRO = 0x202d, ++ GRUB_UNICODE_RLO = 0x202e, + GRUB_UNICODE_LEFTARROW = 0x2190, + GRUB_UNICODE_UPARROW = 0x2191, + GRUB_UNICODE_RIGHTARROW = 0x2192, +@@ -222,13 +230,21 @@ extern struct grub_unicode_bidi_pair grub_unicode_bidi_pairs[]; + /* Unicode mandates an arbitrary limit. */ + #define GRUB_BIDI_MAX_EXPLICIT_LEVEL 61 + ++struct grub_term_pos ++{ ++ unsigned valid:1; ++ unsigned x:15, y:16; ++}; ++ + grub_ssize_t + grub_bidi_logical_to_visual (const grub_uint32_t *logical, + grub_size_t logical_len, + struct grub_unicode_glyph **visual_out, + grub_ssize_t (*getcharwidth) (const struct grub_unicode_glyph *visual), + grub_size_t max_width, +- grub_size_t start_width); ++ grub_size_t start_width, grub_uint32_t codechar, ++ struct grub_term_pos *pos, ++ int primitive_wrap); + + enum grub_comb_type + grub_unicode_get_comb_type (grub_uint32_t c); +@@ -275,4 +291,8 @@ grub_unicode_mirror_code (grub_uint32_t in); + grub_uint32_t + grub_unicode_shape_code (grub_uint32_t in, grub_uint8_t attr); + ++const grub_uint32_t * ++grub_unicode_get_comb_end (const grub_uint32_t *end, ++ const grub_uint32_t *cur); ++ + #endif +-- +1.8.1.4 + diff --git a/0110-New-terminal-outputs-using-serial-morse-and-spkmodem.patch b/0110-New-terminal-outputs-using-serial-morse-and-spkmodem.patch new file mode 100644 index 0000000..777fae9 --- /dev/null +++ b/0110-New-terminal-outputs-using-serial-morse-and-spkmodem.patch @@ -0,0 +1,805 @@ +From ec44b444dcdb795834b085825341771296f469ad Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Wed, 16 Jan 2013 20:39:54 +0100 +Subject: [PATCH 110/364] New terminal outputs using serial: morse and + spkmodem. + +--- + ChangeLog | 4 ++ + docs/grub.texi | 24 +++++-- + grub-core/Makefile.core.def | 12 ++++ + grub-core/commands/i386/pc/play.c | 109 ++----------------------------- + grub-core/kern/i386/pit.c | 35 ++++------ + grub-core/term/morse.c | 131 ++++++++++++++++++++++++++++++++++++++ + grub-core/term/spkmodem.c | 106 ++++++++++++++++++++++++++++++ + include/grub/i386/pit.h | 78 +++++++++++++++++++++++ + include/grub/speaker.h | 47 ++++++++++++++ + util/spkmodem-recv.c | 98 ++++++++++++++++++++++++++++ + 10 files changed, 512 insertions(+), 132 deletions(-) + create mode 100644 grub-core/term/morse.c + create mode 100644 grub-core/term/spkmodem.c + create mode 100644 include/grub/speaker.h + create mode 100644 util/spkmodem-recv.c + +diff --git a/ChangeLog b/ChangeLog +index 96aca66..f1c53e3 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,9 @@ + 2013-01-16 Vladimir Serbinenko + ++ New terminal outputs using serial: morse and spkmodem. ++ ++2013-01-16 Vladimir Serbinenko ++ + Improve bidi handling in entry editor. + + 2013-01-16 Vladimir Serbinenko +diff --git a/docs/grub.texi b/docs/grub.texi +index e75bae9..efedd27 100644 +--- a/docs/grub.texi ++++ b/docs/grub.texi +@@ -1229,9 +1229,9 @@ 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 ++@samp{console} (native platform console), @samp{serial} (serial terminal), ++@samp{serial_} (serial terminal with explicit port selection), ++@samp{at_keyboard} (PC AT keyboard), or @samp{usb_keyboard} (USB keyboard + using the HID Boot Protocol, for cases where the firmware does not handle + this). + +@@ -1242,9 +1242,21 @@ 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). ++@samp{console} (native platform console), @samp{serial} (serial terminal), ++@samp{serial_} (serial terminal with explicit port selection), ++@samp{gfxterm} (graphics-mode output), @samp{vga_text} (VGA text output), ++@samp{mda_text} (MDA text output), @samp{morse} (Morse-coding using system ++beeper) or @samp{spkmodem} (simple data protocol using system speaker). ++ ++@samp{spkmodem} is useful when no serial port is available. Connect the output ++of sending system (where GRUB is running) to line-in of receiving system ++(usually developper machine). ++On receiving system compile @samp{spkmodem-recv} from ++@samp{util/spkmodem-recv.c} and run: ++ ++@example ++parecord --channels=1 --rate=48000 --format=s16le | ./spkmodem-recv ++@end example + + The default is to use the platform's native terminal output. + +diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def +index f4dd645..baf80b8 100644 +--- a/grub-core/Makefile.core.def ++++ b/grub-core/Makefile.core.def +@@ -779,6 +779,18 @@ module = { + }; + + module = { ++ name = spkmodem; ++ x86 = term/spkmodem.c; ++ enable = x86; ++}; ++ ++module = { ++ name = morse; ++ x86 = term/morse.c; ++ enable = x86; ++}; ++ ++module = { + name = probe; + common = commands/probe.c; + }; +diff --git a/grub-core/commands/i386/pc/play.c b/grub-core/commands/i386/pc/play.c +index 10a0181..40798c9 100644 +--- a/grub-core/commands/i386/pc/play.c ++++ b/grub-core/commands/i386/pc/play.c +@@ -28,80 +28,12 @@ + #include + #include + #include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + + #define BASE_TEMPO (60 * 1000) + +-/* The speaker port. */ +-#define SPEAKER 0x61 +- +-/* If 0, follow state of SPEAKER_DATA bit, otherwise enable output +- from timer 2. */ +-#define SPEAKER_TMR2 0x01 +- +-/* If SPEAKER_TMR2 is not set, this provides direct input into the +- speaker. Otherwise, this enables or disables the output from the +- timer. */ +-#define SPEAKER_DATA 0x02 +- +-/* The PIT channel value ports. You can write to and read from them. +- Do not mess with timer 0 or 1. */ +-#define PIT_COUNTER_0 0x40 +-#define PIT_COUNTER_1 0x41 +-#define PIT_COUNTER_2 0x42 +- +-/* The frequency of the PIT clock. */ +-#define PIT_FREQUENCY 0x1234dd +- +-/* The PIT control port. You can only write to it. Do not mess with +- timer 0 or 1. */ +-#define PIT_CTRL 0x43 +-#define PIT_CTRL_SELECT_MASK 0xc0 +-#define PIT_CTRL_SELECT_0 0x00 +-#define PIT_CTRL_SELECT_1 0x40 +-#define PIT_CTRL_SELECT_2 0x80 +- +-/* Read and load control. */ +-#define PIT_CTRL_READLOAD_MASK 0x30 +-#define PIT_CTRL_COUNTER_LATCH 0x00 /* Hold timer value until read. */ +-#define PIT_CTRL_READLOAD_LSB 0x10 /* Read/load the LSB. */ +-#define PIT_CTRL_READLOAD_MSB 0x20 /* Read/load the MSB. */ +-#define PIT_CTRL_READLOAD_WORD 0x30 /* Read/load the LSB then the MSB. */ +- +-/* Mode control. */ +-#define PIT_CTRL_MODE_MASK 0x0e +- +-/* Interrupt on terminal count. Setting the mode sets output to low. +- When counter is set and terminated, output is set to high. */ +-#define PIT_CTRL_INTR_ON_TERM 0x00 +- +-/* Programmable one-shot. When loading counter, output is set to +- high. When counter terminated, output is set to low. Can be +- triggered again from that point on by setting the gate pin to +- high. */ +-#define PIT_CTRL_PROGR_ONE_SHOT 0x02 +- +-/* Rate generator. Output is low for one period of the counter, and +- high for the other. */ +-#define PIT_CTRL_RATE_GEN 0x04 +- +-/* Square wave generator. Output is low for one half of the period, +- and high for the other half. */ +-#define PIT_CTRL_SQUAREWAVE_GEN 0x06 +- +-/* Software triggered strobe. Setting the mode sets output to high. +- When counter is set and terminated, output is set to low. */ +-#define PIT_CTRL_SOFTSTROBE 0x08 +- +-/* Hardware triggered strobe. Like software triggered strobe, but +- only starts the counter when the gate pin is set to high. */ +-#define PIT_CTRL_HARDSTROBE 0x0a +- +-/* Count mode. */ +-#define PIT_CTRL_COUNT_MASK 0x01 +-#define PIT_CTRL_COUNT_BINARY 0x00 /* 16-bit binary counter. */ +-#define PIT_CTRL_COUNT_BCD 0x01 /* 4-decade BCD counter. */ + + #define T_REST ((grub_uint16_t) 0) + #define T_FINE ((grub_uint16_t) -1) +@@ -112,39 +44,6 @@ struct note + grub_uint16_t duration; + }; + +-static void +-beep_off (void) +-{ +- unsigned char status; +- +- status = grub_inb (SPEAKER); +- grub_outb (status & ~(SPEAKER_TMR2 | SPEAKER_DATA), SPEAKER); +-} +- +-static void +-beep_on (grub_uint16_t pitch) +-{ +- unsigned char status; +- unsigned int counter; +- +- if (pitch < 20) +- pitch = 20; +- else if (pitch > 20000) +- pitch = 20000; +- +- counter = PIT_FREQUENCY / pitch; +- +- /* Program timer 2. */ +- grub_outb (PIT_CTRL_SELECT_2 | PIT_CTRL_READLOAD_WORD +- | PIT_CTRL_SQUAREWAVE_GEN | PIT_CTRL_COUNT_BINARY, PIT_CTRL); +- grub_outb (counter & 0xff, PIT_COUNTER_2); /* LSB */ +- grub_outb ((counter >> 8) & 0xff, PIT_COUNTER_2); /* MSB */ +- +- /* Start speaker. */ +- status = grub_inb (SPEAKER); +- grub_outb (status | SPEAKER_TMR2 | SPEAKER_DATA, SPEAKER); +-} +- + /* Returns whether playing should continue. */ + static int + play (unsigned tempo, struct note *note) +@@ -160,11 +59,11 @@ play (unsigned tempo, struct note *note) + switch (note->pitch) + { + case T_REST: +- beep_off (); ++ grub_speaker_beep_off (); + break; + + default: +- beep_on (note->pitch); ++ grub_speaker_beep_on (note->pitch); + break; + } + +@@ -263,7 +162,7 @@ grub_cmd_play (grub_command_t cmd __attribute__ ((unused)), + } + } + +- beep_off (); ++ grub_speaker_beep_off (); + + return 0; + } +diff --git a/grub-core/kern/i386/pit.c b/grub-core/kern/i386/pit.c +index 82a17d3..092481a 100644 +--- a/grub-core/kern/i386/pit.c ++++ b/grub-core/kern/i386/pit.c +@@ -20,37 +20,30 @@ + #include + #include + +-#define TIMER2_REG_CONTROL 0x42 +-#define TIMER_REG_COMMAND 0x43 +-#define TIMER2_REG_LATCH 0x61 +- +-#define TIMER2_SELECT 0x80 +-#define TIMER_ENABLE_LSB 0x20 +-#define TIMER_ENABLE_MSB 0x10 +-#define TIMER2_LATCH 0x20 +-#define TIMER2_SPEAKER 0x02 +-#define TIMER2_GATE 0x01 +- + void + grub_pit_wait (grub_uint16_t tics) + { + /* Disable timer2 gate and speaker. */ +- grub_outb (grub_inb (TIMER2_REG_LATCH) & ~ (TIMER2_SPEAKER | TIMER2_GATE), +- TIMER2_REG_LATCH); ++ grub_outb (grub_inb (GRUB_PIT_SPEAKER_PORT) ++ & ~ (GRUB_PIT_SPK_DATA | GRUB_PIT_SPK_TMR2), ++ GRUB_PIT_SPEAKER_PORT); + + /* Set tics. */ +- grub_outb (TIMER2_SELECT | TIMER_ENABLE_LSB | TIMER_ENABLE_MSB, TIMER_REG_COMMAND); +- grub_outb (tics & 0xff, TIMER2_REG_CONTROL); +- grub_outb (tics >> 8, TIMER2_REG_CONTROL); ++ grub_outb (GRUB_PIT_CTRL_SELECT_2 | GRUB_PIT_CTRL_READLOAD_WORD, ++ GRUB_PIT_CTRL); ++ grub_outb (tics & 0xff, GRUB_PIT_COUNTER_2); ++ grub_outb (tics >> 8, GRUB_PIT_COUNTER_2); + + /* Enable timer2 gate, keep speaker disabled. */ +- grub_outb ((grub_inb (TIMER2_REG_LATCH) & ~ TIMER2_SPEAKER) | TIMER2_GATE, +- TIMER2_REG_LATCH); ++ grub_outb ((grub_inb (GRUB_PIT_SPEAKER_PORT) & ~ GRUB_PIT_SPK_DATA) ++ | GRUB_PIT_SPK_TMR2, ++ GRUB_PIT_SPEAKER_PORT); + + /* Wait. */ +- while ((grub_inb (TIMER2_REG_LATCH) & TIMER2_LATCH) == 0x00); ++ while ((grub_inb (GRUB_PIT_SPEAKER_PORT) & GRUB_PIT_SPK_TMR2_LATCH) == 0x00); + + /* Disable timer2 gate and speaker. */ +- grub_outb (grub_inb (TIMER2_REG_LATCH) & ~ (TIMER2_SPEAKER | TIMER2_GATE), +- TIMER2_REG_LATCH); ++ grub_outb (grub_inb (GRUB_PIT_SPEAKER_PORT) ++ & ~ (GRUB_PIT_SPK_DATA | GRUB_PIT_SPK_TMR2), ++ GRUB_PIT_SPEAKER_PORT); + } +diff --git a/grub-core/term/morse.c b/grub-core/term/morse.c +new file mode 100644 +index 0000000..3d6c650 +--- /dev/null ++++ b/grub-core/term/morse.c +@@ -0,0 +1,131 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2011,2012,2013 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 ++ ++GRUB_MOD_LICENSE ("GPLv3+"); ++ ++#define BASE_TIME 250 ++ ++static const char codes[0x80][6] = ++ { ++ ['0'] = { 3, 3, 3, 3, 3, 0 }, ++ ['1'] = { 1, 3, 3, 3, 3, 0 }, ++ ['2'] = { 1, 1, 3, 3, 3, 0 }, ++ ['3'] = { 1, 1, 1, 3, 3, 0 }, ++ ['4'] = { 1, 1, 1, 1, 3, 0 }, ++ ['5'] = { 1, 1, 1, 1, 1, 0 }, ++ ['6'] = { 3, 1, 1, 1, 1, 0 }, ++ ['7'] = { 3, 3, 1, 1, 1, 0 }, ++ ['8'] = { 3, 3, 3, 1, 1, 0 }, ++ ['9'] = { 3, 3, 3, 3, 1, 0 }, ++ ['a'] = { 1, 3, 0 }, ++ ['b'] = { 3, 1, 1, 1, 0 }, ++ ['c'] = { 3, 1, 3, 1, 0 }, ++ ['d'] = { 3, 1, 1, 0 }, ++ ['e'] = { 1, 0 }, ++ ['f'] = { 1, 1, 3, 1, 0 }, ++ ['g'] = { 3, 3, 1, 0 }, ++ ['h'] = { 1, 1, 1, 1, 0 }, ++ ['i'] = { 1, 1, 0 }, ++ ['j'] = { 1, 3, 3, 3, 0 }, ++ ['k'] = { 3, 1, 3, 0 }, ++ ['l'] = { 1, 3, 1, 1, 0 }, ++ ['m'] = { 3, 3, 0 }, ++ ['n'] = { 3, 1, 0 }, ++ ['o'] = { 3, 3, 3, 0 }, ++ ['p'] = { 1, 3, 3, 1, 0 }, ++ ['q'] = { 3, 3, 1, 3, 0 }, ++ ['r'] = { 1, 3, 1, 0 }, ++ ['s'] = { 1, 1, 1, 0 }, ++ ['t'] = { 3, 0 }, ++ ['u'] = { 1, 1, 3, 0 }, ++ ['v'] = { 1, 1, 1, 3, 0 }, ++ ['w'] = { 1, 3, 3, 0 }, ++ ['x'] = { 3, 1, 1, 3, 0 }, ++ ['y'] = { 3, 1, 3, 3, 0 }, ++ ['z'] = { 3, 3, 1, 1, 0 } ++ }; ++ ++static void ++grub_audio_tone (int length) ++{ ++ grub_speaker_beep_on (1000); ++ grub_millisleep (length); ++ grub_speaker_beep_off (); ++} ++ ++static void ++grub_audio_putchar (struct grub_term_output *term __attribute__ ((unused)), ++ const struct grub_unicode_glyph *c_in) ++{ ++ grub_uint8_t c; ++ int i; ++ ++ /* For now, do not try to use a surrogate pair. */ ++ if (c_in->base > 0x7f) ++ c = '?'; ++ else ++ c = grub_tolower (c_in->base); ++ for (i = 0; codes[c][i]; i++) ++ { ++ grub_audio_tone (codes[c][i] * BASE_TIME); ++ grub_millisleep (BASE_TIME); ++ } ++ grub_millisleep (2 * BASE_TIME); ++} ++ ++ ++static int ++dummy (void) ++{ ++ return 0; ++} ++ ++static struct grub_term_output grub_audio_term_output = ++ { ++ .name = "morse", ++ .init = (void *) dummy, ++ .fini = (void *) dummy, ++ .putchar = grub_audio_putchar, ++ .getwh = (void *) dummy, ++ .getxy = (void *) dummy, ++ .gotoxy = (void *) dummy, ++ .cls = (void *) dummy, ++ .setcolorstate = (void *) dummy, ++ .setcursor = (void *) dummy, ++ .normal_color = GRUB_TERM_DEFAULT_NORMAL_COLOR, ++ .highlight_color = GRUB_TERM_DEFAULT_HIGHLIGHT_COLOR, ++ .flags = GRUB_TERM_CODE_TYPE_ASCII | GRUB_TERM_DUMB ++ }; ++ ++GRUB_MOD_INIT (morse) ++{ ++ grub_term_register_output ("audio", &grub_audio_term_output); ++} ++ ++GRUB_MOD_FINI (morse) ++{ ++ grub_term_unregister_output (&grub_audio_term_output); ++} +diff --git a/grub-core/term/spkmodem.c b/grub-core/term/spkmodem.c +new file mode 100644 +index 0000000..31dab65 +--- /dev/null ++++ b/grub-core/term/spkmodem.c +@@ -0,0 +1,106 @@ ++/* console.c -- Open Firmware console for GRUB. */ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 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 ++#include ++#include ++#include ++#include ++#include ++#include ++ ++GRUB_MOD_LICENSE ("GPLv3+"); ++ ++extern struct grub_terminfo_output_state grub_spkmodem_terminfo_output; ++ ++static void ++put (struct grub_term_output *term __attribute__ ((unused)), const int c) ++{ ++ int i; ++ ++ for (i = 7; i >= 0; i--) ++ { ++ if ((c >> i) & 1) ++ grub_speaker_beep_on (2000); ++ else ++ grub_speaker_beep_on (4000); ++ grub_millisleep (10); ++ grub_speaker_beep_on (1000); ++ grub_millisleep (10); ++ } ++ grub_speaker_beep_on (50); ++} ++ ++static grub_err_t ++grub_spkmodem_init_output (struct grub_term_output *term) ++{ ++ grub_speaker_beep_on (50); ++ grub_millisleep (50); ++ ++ grub_terminfo_output_init (term); ++ ++ return 0; ++} ++ ++static grub_err_t ++grub_spkmodem_fini_output (struct grub_term_output *term __attribute__ ((unused))) ++{ ++ grub_speaker_beep_off (); ++ return 0; ++} ++ ++ ++ ++ ++struct grub_terminfo_output_state grub_spkmodem_terminfo_output = ++ { ++ .put = put, ++ .width = 80, ++ .height = 24 ++ }; ++ ++static struct grub_term_output grub_spkmodem_term_output = ++ { ++ .name = "spkmodem", ++ .init = grub_spkmodem_init_output, ++ .fini = grub_spkmodem_fini_output, ++ .putchar = grub_terminfo_putchar, ++ .getxy = grub_terminfo_getxy, ++ .getwh = grub_terminfo_getwh, ++ .gotoxy = grub_terminfo_gotoxy, ++ .cls = grub_terminfo_cls, ++ .setcolorstate = grub_terminfo_setcolorstate, ++ .setcursor = grub_terminfo_setcursor, ++ .flags = GRUB_TERM_CODE_TYPE_ASCII, ++ .data = &grub_spkmodem_terminfo_output, ++ .normal_color = GRUB_TERM_DEFAULT_NORMAL_COLOR, ++ .highlight_color = GRUB_TERM_DEFAULT_HIGHLIGHT_COLOR, ++ }; ++ ++GRUB_MOD_INIT (spkmodem) ++{ ++ grub_term_register_output ("spkmodem", &grub_spkmodem_term_output); ++} ++ ++ ++GRUB_MOD_FINI (spkmodem) ++{ ++ grub_term_unregister_output (&grub_spkmodem_term_output); ++} +diff --git a/include/grub/i386/pit.h b/include/grub/i386/pit.h +index ff9b9a6..e1c92cd 100644 +--- a/include/grub/i386/pit.h ++++ b/include/grub/i386/pit.h +@@ -22,6 +22,84 @@ + #include + #include + ++enum ++ { ++ /* The PIT channel value ports. You can write to and read from them. ++ Do not mess with timer 0 or 1. */ ++ GRUB_PIT_COUNTER_0 = 0x40, ++ GRUB_PIT_COUNTER_1 = 0x41, ++ GRUB_PIT_COUNTER_2 = 0x42, ++ /* The PIT control port. You can only write to it. Do not mess with ++ timer 0 or 1. */ ++ GRUB_PIT_CTRL = 0x43, ++ /* The speaker port. */ ++ GRUB_PIT_SPEAKER_PORT = 0x61, ++ }; ++ ++ ++/* The speaker port. */ ++enum ++ { ++ /* If 0, follow state of SPEAKER_DATA bit, otherwise enable output ++ from timer 2. */ ++ GRUB_PIT_SPK_TMR2 = 0x01, ++ /* If SPEAKER_TMR2 is not set, this provides direct input into the ++ speaker. Otherwise, this enables or disables the output from the ++ timer. */ ++ GRUB_PIT_SPK_DATA = 0x02, ++ ++ GRUB_PIT_SPK_TMR2_LATCH = 0x20 ++ }; ++ ++/* The PIT control port. You can only write to it. Do not mess with ++ timer 0 or 1. */ ++enum ++ { ++ GRUB_PIT_CTRL_SELECT_MASK = 0xc0, ++ GRUB_PIT_CTRL_SELECT_0 = 0x00, ++ GRUB_PIT_CTRL_SELECT_1 = 0x40, ++ GRUB_PIT_CTRL_SELECT_2 = 0x80, ++ ++ /* Read and load control. */ ++ GRUB_PIT_CTRL_READLOAD_MASK= 0x30, ++ GRUB_PIT_CTRL_COUNTER_LATCH = 0x00, /* Hold timer value until read. */ ++ GRUB_PIT_CTRL_READLOAD_LSB = 0x10, /* Read/load the LSB. */ ++ GRUB_PIT_CTRL_READLOAD_MSB = 0x20, /* Read/load the MSB. */ ++ GRUB_PIT_CTRL_READLOAD_WORD = 0x30, /* Read/load the LSB then the MSB. */ ++ ++ /* Mode control. */ ++ GRUB_PIT_CTRL_MODE_MASK = 0x0e, ++ /* Interrupt on terminal count. Setting the mode sets output to low. ++ When counter is set and terminated, output is set to high. */ ++ GRUB_PIT_CTRL_INTR_ON_TERM = 0x00, ++ /* Programmable one-shot. When loading counter, output is set to ++ high. When counter terminated, output is set to low. Can be ++ triggered again from that point on by setting the gate pin to ++ high. */ ++ GRUB_PIT_CTRL_PROGR_ONE_SHOT = 0x02, ++ ++ /* Rate generator. Output is low for one period of the counter, and ++ high for the other. */ ++ GRUB_PIT_CTRL_RATE_GEN = 0x04, ++ ++ /* Square wave generator. Output is low for one half of the period, ++ and high for the other half. */ ++ GRUB_PIT_CTRL_SQUAREWAVE_GEN = 0x06, ++ /* Software triggered strobe. Setting the mode sets output to high. ++ When counter is set and terminated, output is set to low. */ ++ GRUB_PIT_CTRL_SOFTSTROBE = 0x08, ++ ++ /* Hardware triggered strobe. Like software triggered strobe, but ++ only starts the counter when the gate pin is set to high. */ ++ GRUB_PIT_CTRL_HARDSTROBE = 0x0a, ++ ++ ++ /* Count mode. */ ++ GRUB_PIT_CTRL_COUNT_MASK = 0x01, ++ GRUB_PIT_CTRL_COUNT_BINARY = 0x00, /* 16-bit binary counter. */ ++ GRUB_PIT_CTRL_COUNT_BCD = 0x01 /* 4-decade BCD counter. */ ++ }; ++ + void EXPORT_FUNC(grub_pit_wait) (grub_uint16_t tics); + + #endif /* ! KERNEL_CPU_PIT_HEADER */ +diff --git a/include/grub/speaker.h b/include/grub/speaker.h +new file mode 100644 +index 0000000..a076fcf +--- /dev/null ++++ b/include/grub/speaker.h +@@ -0,0 +1,47 @@ ++#ifndef GRUB_SPEAKER_HEADER ++#define GRUB_SPEAKER_HEADER 1 ++ ++#include ++#include ++ ++/* The frequency of the PIT clock. */ ++#define GRUB_SPEAKER_PIT_FREQUENCY 0x1234dd ++ ++static inline void ++grub_speaker_beep_off (void) ++{ ++ unsigned char status; ++ ++ status = grub_inb (GRUB_PIT_SPEAKER_PORT); ++ grub_outb (status & ~(GRUB_PIT_SPK_TMR2 | GRUB_PIT_SPK_DATA), ++ GRUB_PIT_SPEAKER_PORT); ++} ++ ++static inline void ++grub_speaker_beep_on (grub_uint16_t pitch) ++{ ++ unsigned char status; ++ unsigned int counter; ++ ++ if (pitch < 20) ++ pitch = 20; ++ else if (pitch > 20000) ++ pitch = 20000; ++ ++ counter = GRUB_SPEAKER_PIT_FREQUENCY / pitch; ++ ++ /* Program timer 2. */ ++ grub_outb (GRUB_PIT_CTRL_SELECT_2 ++ | GRUB_PIT_CTRL_READLOAD_WORD ++ | GRUB_PIT_CTRL_SQUAREWAVE_GEN ++ | GRUB_PIT_CTRL_COUNT_BINARY, GRUB_PIT_CTRL); ++ grub_outb (counter & 0xff, GRUB_PIT_COUNTER_2); /* LSB */ ++ grub_outb ((counter >> 8) & 0xff, GRUB_PIT_COUNTER_2); /* MSB */ ++ ++ /* Start speaker. */ ++ status = grub_inb (GRUB_PIT_SPEAKER_PORT); ++ grub_outb (status | GRUB_PIT_SPK_TMR2 | GRUB_PIT_SPK_DATA, ++ GRUB_PIT_SPEAKER_PORT); ++} ++ ++#endif +diff --git a/util/spkmodem-recv.c b/util/spkmodem-recv.c +new file mode 100644 +index 0000000..cbec3af +--- /dev/null ++++ b/util/spkmodem-recv.c +@@ -0,0 +1,98 @@ ++#include ++#include ++#include ++ ++/* Compilation: gcc -o spkmodem-recv spkmodem-recv */ ++/* Usage: parecord --channels=1 --rate=48000 --format=s16le | ./spkmodem-recv */ ++ ++#define RATE 48000 ++#define SAMPLES_PER_TRAME 480 ++#define AMPLITUDE_THRESHOLD 100000 ++#define FREQ_SEP_MIN 15 ++#define FREQ_SEP_NOM 20 ++#define FREQ_SEP_MAX 25 ++ ++#define FREQ_DATA_MIN 10 ++#define FREQ_DATA_THRESHOLD 60 ++#define FREQ_DATA_MAX 120 ++#define AMPLITUDE_SAMPLES 2 * SAMPLES_PER_TRAME ++ ++#define THRESHOLD 1000 ++ ++#define DEBUG 0 ++ ++static signed short trame[2 * SAMPLES_PER_TRAME]; ++static signed short pulse[2 * SAMPLES_PER_TRAME]; ++static int ringpos = 0; ++static int pos, f1, f2; ++static int amplitude = 0; ++static int lp = 0; ++ ++static void ++read_sample (void) ++{ ++ amplitude -= abs (trame[ringpos]); ++ f1 -= pulse[ringpos]; ++ f1 += pulse[(ringpos + SAMPLES_PER_TRAME) % (2 * SAMPLES_PER_TRAME)]; ++ f2 -= pulse[(ringpos + SAMPLES_PER_TRAME) % (2 * SAMPLES_PER_TRAME)]; ++ fread (trame + ringpos, 1, sizeof (trame[0]), stdin); ++ amplitude += abs (trame[ringpos]); ++ ++ if (pos ? (trame[ringpos] < -THRESHOLD) ++ : (trame[ringpos] > +THRESHOLD)) ++ { ++ pulse[ringpos] = 1; ++ pos = !pos; ++ f2++; ++ } ++ else ++ pulse[ringpos] = 0; ++ ringpos++; ++ ringpos %= 2 * SAMPLES_PER_TRAME; ++ lp++; ++} ++ ++int ++main () ++{ ++ int bitn = 7; ++ char c = 0; ++ int i; ++ while (!feof (stdin)) ++ { ++ if (lp > 20000) ++ { ++ fflush (stdout); ++ bitn = 7; ++ c = 0; ++ lp = 0; ++ } ++ if (f2 > 12 && f2 < 25 ++ && f1 > 5 && f1 < 120) ++ { ++#if DEBUG ++ printf ("%d %d %d @%d\n", f1, f2, FREQ_DATA_THRESHOLD, ++ ftell (stdin) - sizeof (trame)); ++#endif ++ if (f1 < 60) ++ c |= (1 << bitn); ++ bitn--; ++ if (bitn < 0) ++ { ++#if DEBUG ++ printf ("<%c, %x>", c, c); ++#else ++ printf ("%c", c); ++#endif ++ bitn = 7; ++ c = 0; ++ } ++ lp = 0; ++ for (i = 0; i < SAMPLES_PER_TRAME; i++) ++ read_sample (); ++ continue; ++ } ++ read_sample (); ++ } ++ return 0; ++} +-- +1.8.1.4 + diff --git a/0111-Add-new-command-pcidump.patch b/0111-Add-new-command-pcidump.patch new file mode 100644 index 0000000..0ca82c1 --- /dev/null +++ b/0111-Add-new-command-pcidump.patch @@ -0,0 +1,231 @@ +From d230dcf6c99b852adcee4a26c4c81dd15b83ce56 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Wed, 16 Jan 2013 20:44:11 +0100 +Subject: [PATCH 111/364] Add new command pcidump. + +--- + ChangeLog | 4 ++ + grub-core/Makefile.core.def | 6 ++ + grub-core/commands/pcidump.c | 165 +++++++++++++++++++++++++++++++++++++++++++ + grub-core/commands/setpci.c | 2 +- + 4 files changed, 176 insertions(+), 1 deletion(-) + create mode 100644 grub-core/commands/pcidump.c + +diff --git a/ChangeLog b/ChangeLog +index f1c53e3..9922c06 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,9 @@ + 2013-01-16 Vladimir Serbinenko + ++ Add new command pcidump. ++ ++2013-01-16 Vladimir Serbinenko ++ + New terminal outputs using serial: morse and spkmodem. + + 2013-01-16 Vladimir Serbinenko +diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def +index baf80b8..4609a4b 100644 +--- a/grub-core/Makefile.core.def ++++ b/grub-core/Makefile.core.def +@@ -828,6 +828,12 @@ module = { + }; + + module = { ++ name = pcidump; ++ common = commands/pcidump.c; ++ enable = pci; ++}; ++ ++module = { + name = sleep; + common = commands/sleep.c; + }; +diff --git a/grub-core/commands/pcidump.c b/grub-core/commands/pcidump.c +new file mode 100644 +index 0000000..a49cf93 +--- /dev/null ++++ b/grub-core/commands/pcidump.c +@@ -0,0 +1,165 @@ ++/* lspci.c - List PCI devices. */ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2013 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 ++ ++GRUB_MOD_LICENSE ("GPLv3+"); ++ ++static grub_uint32_t pciid_check_mask, pciid_check_value; ++static int bus, device, function; ++static int check_bus, check_device, check_function; ++ ++static const struct grub_arg_option options[] = ++ { ++ {0, 'd', 0, N_("Select device by vendor and device IDs."), ++ N_("[vendor]:[device]"), ARG_TYPE_STRING}, ++ {0, 's', 0, N_("Select device by its position on the bus."), ++ N_("[bus]:[slot][.func]"), ARG_TYPE_STRING}, ++ {0, 0, 0, 0, 0, 0} ++ }; ++ ++static int ++grub_pcidump_iter (grub_pci_device_t dev, grub_pci_id_t pciid, ++ void *data __attribute__ ((unused))) ++{ ++ grub_pci_address_t addr; ++ int i; ++ ++ 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) != function) ++ return 0; ++ ++ for (i = 0; i < 256; i += 4) ++ { ++ addr = grub_pci_make_address (dev, i); ++ grub_printf ("%08x ", grub_pci_read (addr)); ++ if ((i & 0xc) == 0xc) ++ grub_printf ("\n"); ++ } ++ ++ return 0; ++} ++ ++static grub_err_t ++grub_cmd_pcidump (grub_extcmd_context_t ctxt, ++ int argc __attribute__ ((unused)), ++ char **argv __attribute__ ((unused))) ++{ ++ const char *ptr; ++ ++ pciid_check_value = 0; ++ pciid_check_mask = 0; ++ ++ if (ctxt->state[0].set) ++ { ++ ptr = ctxt->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 = ctxt->state[0].arg; ++ } ++ else ++ pciid_check_mask |= 0xffff; ++ if (grub_errno) ++ return grub_errno; ++ if (*ptr != ':') ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("missing `%c' symbol"), ':'); ++ 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 (ctxt->state[1].set) ++ { ++ const char *optr; ++ ++ ptr = ctxt->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, N_("missing `%c' symbol"), ':'); ++ 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; ++ } ++ } ++ ++ grub_pci_iterate (grub_pcidump_iter, NULL); ++ return GRUB_ERR_NONE; ++} ++ ++static grub_extcmd_t cmd; ++ ++GRUB_MOD_INIT(setpci) ++{ ++ cmd = grub_register_extcmd ("pcidump", grub_cmd_pcidump, 0, ++ N_("[-s POSITION] [-d DEVICE]"), ++ N_("Dump PCI configuration space."), options); ++} ++ ++GRUB_MOD_FINI(setpci) ++{ ++ grub_unregister_extcmd (cmd); ++} +diff --git a/grub-core/commands/setpci.c b/grub-core/commands/setpci.c +index 6fdf0e0..4eaba7c 100644 +--- a/grub-core/commands/setpci.c ++++ b/grub-core/commands/setpci.c +@@ -331,7 +331,7 @@ GRUB_MOD_INIT(setpci) + { + cmd = grub_register_extcmd ("setpci", grub_cmd_setpci, 0, + N_("[-s POSITION] [-d DEVICE] [-v VAR] " +- "[REGISTER][=VALUE[:MASK]]"), ++ "REGISTER[=VALUE[:MASK]]"), + N_("Manipulate PCI devices."), options); + } + +-- +1.8.1.4 + diff --git a/0112-Rewrite-spkmodem-to-use-PIT-for-timing.-Double-the-s.patch b/0112-Rewrite-spkmodem-to-use-PIT-for-timing.-Double-the-s.patch new file mode 100644 index 0000000..41e4579 --- /dev/null +++ b/0112-Rewrite-spkmodem-to-use-PIT-for-timing.-Double-the-s.patch @@ -0,0 +1,177 @@ +From e04d3c4daab9688ee2ccfb222be4cbb57e02184f Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Thu, 17 Jan 2013 20:06:52 +0100 +Subject: [PATCH 112/364] Rewrite spkmodem to use PIT for timing. Double + the speed. + +--- + ChangeLog | 4 ++++ + grub-core/commands/setpci.c | 2 +- + grub-core/term/spkmodem.c | 55 +++++++++++++++++++++++++++++++++++++-------- + util/spkmodem-recv.c | 26 +++++++++------------ + 4 files changed, 61 insertions(+), 26 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 9922c06..f8129ae 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,7 @@ ++2013-01-17 Vladimir Serbinenko ++ ++ Rewrite spkmodem to use PIT for timing. Double the speed. ++ + 2013-01-16 Vladimir Serbinenko + + Add new command pcidump. +diff --git a/grub-core/commands/setpci.c b/grub-core/commands/setpci.c +index 4eaba7c..d5bc97d 100644 +--- a/grub-core/commands/setpci.c ++++ b/grub-core/commands/setpci.c +@@ -129,7 +129,7 @@ grub_setpci_iter (grub_pci_device_t dev, grub_pci_id_t pciid, + + if (!write_mask) + { +- grub_printf (_("Register %x of %d:%d.%d is %x\n"), regaddr, ++ grub_printf (_("Register %x of %x:%02x.%x is %x\n"), regaddr, + grub_pci_get_bus (dev), + grub_pci_get_device (dev), + grub_pci_get_function (dev), +diff --git a/grub-core/term/spkmodem.c b/grub-core/term/spkmodem.c +index 31dab65..b6e7a04 100644 +--- a/grub-core/term/spkmodem.c ++++ b/grub-core/term/spkmodem.c +@@ -31,29 +31,65 @@ GRUB_MOD_LICENSE ("GPLv3+"); + extern struct grub_terminfo_output_state grub_spkmodem_terminfo_output; + + static void ++make_tone (grub_uint16_t freq_count, unsigned int duration) ++{ ++ /* Program timer 2. */ ++ grub_outb (GRUB_PIT_CTRL_SELECT_2 ++ | GRUB_PIT_CTRL_READLOAD_WORD ++ | GRUB_PIT_CTRL_SQUAREWAVE_GEN ++ | GRUB_PIT_CTRL_COUNT_BINARY, GRUB_PIT_CTRL); ++ grub_outb (freq_count & 0xff, GRUB_PIT_COUNTER_2); /* LSB */ ++ grub_outb ((freq_count >> 8) & 0xff, GRUB_PIT_COUNTER_2); /* MSB */ ++ ++ /* Start speaker. */ ++ grub_outb (grub_inb (GRUB_PIT_SPEAKER_PORT) ++ | GRUB_PIT_SPK_TMR2 | GRUB_PIT_SPK_DATA, ++ GRUB_PIT_SPEAKER_PORT); ++ ++ for (; duration; duration--) ++ { ++ unsigned short counter, previous_counter = 0xffff; ++ while (1) ++ { ++ counter = grub_inb (GRUB_PIT_COUNTER_2); ++ counter |= ((grub_uint16_t) grub_inb (GRUB_PIT_COUNTER_2)) << 8; ++ if (counter > previous_counter) ++ { ++ previous_counter = counter; ++ break; ++ } ++ previous_counter = counter; ++ } ++ } ++} ++ ++static int inited; ++ ++static void + put (struct grub_term_output *term __attribute__ ((unused)), const int c) + { + int i; + ++ if (!inited) ++ { ++ make_tone (GRUB_SPEAKER_PIT_FREQUENCY / 50, 20); ++ inited = 1; ++ } ++ + for (i = 7; i >= 0; i--) + { + if ((c >> i) & 1) +- grub_speaker_beep_on (2000); ++ make_tone (GRUB_SPEAKER_PIT_FREQUENCY / 2000, 20); + else +- grub_speaker_beep_on (4000); +- grub_millisleep (10); +- grub_speaker_beep_on (1000); +- grub_millisleep (10); ++ make_tone (GRUB_SPEAKER_PIT_FREQUENCY / 4000, 40); ++ make_tone (GRUB_SPEAKER_PIT_FREQUENCY / 1000, 10); + } +- grub_speaker_beep_on (50); ++ make_tone (GRUB_SPEAKER_PIT_FREQUENCY / 50, 0); + } + + static grub_err_t + grub_spkmodem_init_output (struct grub_term_output *term) + { +- grub_speaker_beep_on (50); +- grub_millisleep (50); +- + grub_terminfo_output_init (term); + + return 0; +@@ -63,6 +99,7 @@ static grub_err_t + grub_spkmodem_fini_output (struct grub_term_output *term __attribute__ ((unused))) + { + grub_speaker_beep_off (); ++ inited = 0; + return 0; + } + +diff --git a/util/spkmodem-recv.c b/util/spkmodem-recv.c +index cbec3af..4cc88b8 100644 +--- a/util/spkmodem-recv.c ++++ b/util/spkmodem-recv.c +@@ -5,19 +5,13 @@ + /* Compilation: gcc -o spkmodem-recv spkmodem-recv */ + /* Usage: parecord --channels=1 --rate=48000 --format=s16le | ./spkmodem-recv */ + +-#define RATE 48000 +-#define SAMPLES_PER_TRAME 480 +-#define AMPLITUDE_THRESHOLD 100000 +-#define FREQ_SEP_MIN 15 +-#define FREQ_SEP_NOM 20 +-#define FREQ_SEP_MAX 25 +- +-#define FREQ_DATA_MIN 10 +-#define FREQ_DATA_THRESHOLD 60 +-#define FREQ_DATA_MAX 120 +-#define AMPLITUDE_SAMPLES 2 * SAMPLES_PER_TRAME +- +-#define THRESHOLD 1000 ++#define SAMPLES_PER_TRAME 240 ++#define FREQ_SEP_MIN 6 ++#define FREQ_SEP_MAX 15 ++#define FREQ_DATA_MIN 15 ++#define FREQ_DATA_THRESHOLD 25 ++#define FREQ_DATA_MAX 60 ++#define THRESHOLD 500 + + #define DEBUG 0 + +@@ -67,14 +61,14 @@ main () + c = 0; + lp = 0; + } +- if (f2 > 12 && f2 < 25 +- && f1 > 5 && f1 < 120) ++ if (f2 > FREQ_SEP_MIN && f2 < FREQ_SEP_MAX ++ && f1 > FREQ_DATA_MIN && f1 < FREQ_DATA_MAX) + { + #if DEBUG + printf ("%d %d %d @%d\n", f1, f2, FREQ_DATA_THRESHOLD, + ftell (stdin) - sizeof (trame)); + #endif +- if (f1 < 60) ++ if (f1 < FREQ_DATA_THRESHOLD) + c |= (1 << bitn); + bitn--; + if (bitn < 0) +-- +1.8.1.4 + diff --git a/0113-Add-license-header-to-spkmodem-recv.c.patch b/0113-Add-license-header-to-spkmodem-recv.c.patch new file mode 100644 index 0000000..cec9fc0 --- /dev/null +++ b/0113-Add-license-header-to-spkmodem-recv.c.patch @@ -0,0 +1,51 @@ +From 9c17bace090e3609df7bea42e840ecfeb2eb39e1 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Fri, 18 Jan 2013 11:54:28 +0100 +Subject: [PATCH 113/364] Add license header to spkmodem-recv.c. + +--- + ChangeLog | 4 ++++ + util/spkmodem-recv.c | 18 ++++++++++++++++++ + 2 files changed, 22 insertions(+) + +diff --git a/ChangeLog b/ChangeLog +index f8129ae..df311cf 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,7 @@ ++2013-01-18 Vladimir Serbinenko ++ ++ Add license header to spkmodem-recv.c. ++ + 2013-01-17 Vladimir Serbinenko + + Rewrite spkmodem to use PIT for timing. Double the speed. +diff --git a/util/spkmodem-recv.c b/util/spkmodem-recv.c +index 4cc88b8..9075f9a 100644 +--- a/util/spkmodem-recv.c ++++ b/util/spkmodem-recv.c +@@ -1,3 +1,21 @@ ++/* spkmodem-recv.c - decode spkmodem signals */ ++/* ++ * Copyright (C) 2013 Free Software Foundation, Inc. ++ * ++ * spkmodem-recv 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 of the License, or ++ * (at your option) any later version. ++ * ++ * spkmodem-recv 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 spkmodem-recv. If not, see . ++ */ ++ + #include + #include + #include +-- +1.8.1.4 + diff --git a/0114-Fix-typos-for-developer-and-development.patch b/0114-Fix-typos-for-developer-and-development.patch new file mode 100644 index 0000000..6af4c92 --- /dev/null +++ b/0114-Fix-typos-for-developer-and-development.patch @@ -0,0 +1,61 @@ +From 3597696bb12a2de057ab658596eb5c6d1b2aab66 Mon Sep 17 00:00:00 2001 +From: Colin Watson +Date: Sun, 20 Jan 2013 13:24:47 +0000 +Subject: [PATCH 114/364] Fix typos for "developer" and "development". + +--- + ChangeLog | 4 ++++ + docs/grub.texi | 4 ++-- + grub-core/net/bootp.c | 2 +- + 3 files changed, 7 insertions(+), 3 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index df311cf..1c816d6 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,7 @@ ++2013-01-20 Colin Watson ++ ++ Fix typos for "developer" and "development". ++ + 2013-01-18 Vladimir Serbinenko + + Add license header to spkmodem-recv.c. +diff --git a/docs/grub.texi b/docs/grub.texi +index efedd27..2dc0cbe 100644 +--- a/docs/grub.texi ++++ b/docs/grub.texi +@@ -1250,7 +1250,7 @@ beeper) or @samp{spkmodem} (simple data protocol using system speaker). + + @samp{spkmodem} is useful when no serial port is available. Connect the output + of sending system (where GRUB is running) to line-in of receiving system +-(usually developper machine). ++(usually developer machine). + On receiving system compile @samp{spkmodem-recv} from + @samp{util/spkmodem-recv.c} and run: + +@@ -4204,7 +4204,7 @@ and tonal writing (2e5-2e9). GRUB also ignores deprecated (as specified + in Unicode) characters (e.g. tags). GRUB also doesn't handle so called + ``annotation characters'' If you can complete either of + two lists or, better, propose a patch to improve rendering, please contact +-developper team. ++developer team. + + @chapter Input terminal + Firmware console on BIOS, IEEE1275 and ARC doesn't allow you to enter non-ASCII +diff --git a/grub-core/net/bootp.c b/grub-core/net/bootp.c +index f36d4cd..33f860a 100644 +--- a/grub-core/net/bootp.c ++++ b/grub-core/net/bootp.c +@@ -140,7 +140,7 @@ parse_dhcp_vendor (const char *name, void *vend, int limit, int *mask) + break; + + /* If you need any other options please contact GRUB +- developpement team. */ ++ development team. */ + } + + ptr += taglength; +-- +1.8.1.4 + diff --git a/0115-Remove-nested-functions-from-device-iterators.patch b/0115-Remove-nested-functions-from-device-iterators.patch new file mode 100644 index 0000000..2d92860 --- /dev/null +++ b/0115-Remove-nested-functions-from-device-iterators.patch @@ -0,0 +1,4099 @@ +From ba97422da261d8d41d61af28af5344c47a723cff Mon Sep 17 00:00:00 2001 +From: Colin Watson +Date: Sun, 20 Jan 2013 15:52:15 +0000 +Subject: [PATCH 115/364] Remove nested functions from device iterators. + +* include/grub/arc/arc.h (grub_arc_iterate_devs_hook_t): New type. +(grub_arc_iterate_devs): Add hook_data argument. +* include/grub/ata.h (grub_ata_dev_iterate_hook_t): New type. +(struct grub_ata_dev.iterate): Add hook_data argument. +* include/grub/device.h (grub_device_iterate_hook_t): New type. +(grub_device_iterate): Add hook_data argument. +* include/grub/disk.h (grub_disk_dev_iterate_hook_t): New type. +(struct grub_disk_dev.iterate): Add hook_data argument. +(grub_disk_dev_iterate): Likewise. +* include/grub/gpt_partition.h (grub_gpt_partition_map_iterate): +Likewise. +* include/grub/msdos_partition.h (grub_partition_msdos_iterate): +Likewise. +* include/grub/partition.h (grub_partition_iterate_hook_t): New +type. +(struct grub_partition_map.iterate): Add hook_data argument. +(grub_partition_iterate): Likewise. +* include/grub/scsi.h (grub_scsi_dev_iterate_hook_t): New type. +(struct grub_scsi_dev.iterate): Add hook_data argument. + +Update all callers. +--- + ChangeLog | 26 ++ + grub-core/commands/arc/lsdev.c | 18 +- + grub-core/commands/ls.c | 27 +- + grub-core/commands/search.c | 398 +++++++++++++++-------------- + grub-core/commands/wildcard.c | 84 ++++--- + grub-core/disk/ahci.c | 6 +- + grub-core/disk/arc/arcdisk.c | 34 ++- + grub-core/disk/ata.c | 118 +++++---- + grub-core/disk/cryptodisk.c | 13 +- + grub-core/disk/diskfilter.c | 113 +++++---- + grub-core/disk/efi/efidisk.c | 69 ++--- + grub-core/disk/host.c | 4 +- + grub-core/disk/i386/pc/biosdisk.c | 15 +- + grub-core/disk/ieee1275/nand.c | 4 +- + grub-core/disk/ieee1275/ofdisk.c | 4 +- + grub-core/disk/ldm.c | 50 ++-- + grub-core/disk/loopback.c | 6 +- + grub-core/disk/memdisk.c | 4 +- + grub-core/disk/pata.c | 5 +- + grub-core/disk/scsi.c | 81 +++--- + grub-core/disk/usbms.c | 5 +- + grub-core/fs/btrfs.c | 101 ++++---- + grub-core/fs/zfs/zfs.c | 72 +++--- + grub-core/kern/corecmd.c | 4 +- + grub-core/kern/device.c | 145 ++++++----- + grub-core/kern/emu/hostdisk.c | 4 +- + grub-core/kern/mips/arc/init.c | 14 +- + grub-core/kern/partition.c | 156 +++++++----- + grub-core/loader/i386/pc/plan9.c | 513 ++++++++++++++++++++------------------ + grub-core/normal/completion.c | 11 +- + grub-core/partmap/acorn.c | 6 +- + grub-core/partmap/amiga.c | 6 +- + grub-core/partmap/apple.c | 6 +- + grub-core/partmap/bsdlabel.c | 103 ++++---- + grub-core/partmap/dvh.c | 5 +- + grub-core/partmap/gpt.c | 88 ++++--- + grub-core/partmap/msdos.c | 6 +- + grub-core/partmap/plan.c | 6 +- + grub-core/partmap/sun.c | 5 +- + grub-core/partmap/sunpc.c | 6 +- + include/grub/arc/arc.h | 7 +- + include/grub/ata.h | 4 +- + include/grub/device.h | 5 +- + include/grub/disk.h | 8 +- + include/grub/gpt_partition.h | 4 +- + include/grub/msdos_partition.h | 4 +- + include/grub/partition.h | 11 +- + include/grub/scsi.h | 5 +- + util/getroot.c | 72 +++--- + util/grub-setup.c | 125 ++++++---- + 50 files changed, 1438 insertions(+), 1148 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 1c816d6..733b212 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,31 @@ + 2013-01-20 Colin Watson + ++ Remove nested functions from device iterators. ++ ++ * include/grub/arc/arc.h (grub_arc_iterate_devs_hook_t): New type. ++ (grub_arc_iterate_devs): Add hook_data argument. ++ * include/grub/ata.h (grub_ata_dev_iterate_hook_t): New type. ++ (struct grub_ata_dev.iterate): Add hook_data argument. ++ * include/grub/device.h (grub_device_iterate_hook_t): New type. ++ (grub_device_iterate): Add hook_data argument. ++ * include/grub/disk.h (grub_disk_dev_iterate_hook_t): New type. ++ (struct grub_disk_dev.iterate): Add hook_data argument. ++ (grub_disk_dev_iterate): Likewise. ++ * include/grub/gpt_partition.h (grub_gpt_partition_map_iterate): ++ Likewise. ++ * include/grub/msdos_partition.h (grub_partition_msdos_iterate): ++ Likewise. ++ * include/grub/partition.h (grub_partition_iterate_hook_t): New ++ type. ++ (struct grub_partition_map.iterate): Add hook_data argument. ++ (grub_partition_iterate): Likewise. ++ * include/grub/scsi.h (grub_scsi_dev_iterate_hook_t): New type. ++ (struct grub_scsi_dev.iterate): Add hook_data argument. ++ ++ Update all callers. ++ ++2013-01-20 Colin Watson ++ + Fix typos for "developer" and "development". + + 2013-01-18 Vladimir Serbinenko +diff --git a/grub-core/commands/arc/lsdev.c b/grub-core/commands/arc/lsdev.c +index 5d4b0cd..27ed0a2 100644 +--- a/grub-core/commands/arc/lsdev.c ++++ b/grub-core/commands/arc/lsdev.c +@@ -24,18 +24,22 @@ + + GRUB_MOD_LICENSE ("GPLv3+"); + ++/* Helper for grub_cmd_lsdev. */ ++static int ++grub_cmd_lsdev_iter (const char *name, ++ const struct grub_arc_component *comp __attribute__ ((unused)), ++ void *data __attribute__ ((unused))) ++{ ++ grub_printf ("%s\n", name); ++ return 0; ++} ++ + static grub_err_t + grub_cmd_lsdev (grub_command_t cmd __attribute__ ((unused)), + int argc __attribute__ ((unused)), + char **args __attribute__ ((unused))) + { +- auto int hook (const char *name, const struct grub_arc_component *comp); +- int hook (const char *name, const struct grub_arc_component *comp __attribute__ ((unused))) +- { +- grub_printf ("%s\n", name); +- return 0; +- } +- grub_arc_iterate_devs (hook, 0); ++ grub_arc_iterate_devs (grub_cmd_lsdev_iter, 0, 0); + return 0; + } + +diff --git a/grub-core/commands/ls.c b/grub-core/commands/ls.c +index 913bb65..7929747 100644 +--- a/grub-core/commands/ls.c ++++ b/grub-core/commands/ls.c +@@ -45,21 +45,24 @@ static const struct grub_arg_option options[] = + + static const char grub_human_sizes[] = {' ', 'K', 'M', 'G', 'T'}; + +-static grub_err_t +-grub_ls_list_devices (int longlist) ++/* Helper for grub_ls_list_devices. */ ++static int ++grub_ls_print_devices (const char *name, void *data) + { +- auto int grub_ls_print_devices (const char *name); +- int grub_ls_print_devices (const char *name) +- { +- if (longlist) +- grub_normal_print_device_info (name); +- else +- grub_printf ("(%s) ", name); ++ int *longlist = data; + +- return 0; +- } ++ if (longlist) ++ grub_normal_print_device_info (name); ++ else ++ grub_printf ("(%s) ", name); ++ ++ return 0; ++} + +- grub_device_iterate (grub_ls_print_devices); ++static grub_err_t ++grub_ls_list_devices (int longlist) ++{ ++ grub_device_iterate (grub_ls_print_devices, &longlist); + grub_xputs ("\n"); + + #if 0 +diff --git a/grub-core/commands/search.c b/grub-core/commands/search.c +index 5e9b7e3..16143a3 100644 +--- a/grub-core/commands/search.c ++++ b/grub-core/commands/search.c +@@ -42,23 +42,29 @@ struct cache_entry + + static struct cache_entry *cache; + +-void +-FUNC_NAME (const char *key, const char *var, int no_floppy, +- char **hints, unsigned nhints) ++/* Context for FUNC_NAME. */ ++struct search_ctx + { +- int count = 0; +- int is_cache = 0; +- grub_fs_autoload_hook_t saved_autoload; ++ const char *key; ++ const char *var; ++ int no_floppy; ++ char **hints; ++ unsigned nhints; ++ int count; ++ int is_cache; ++}; + +- auto int iterate_device (const char *name); +- int iterate_device (const char *name) +- { +- int found = 0; ++/* Helper for FUNC_NAME. */ ++static int ++iterate_device (const char *name, void *data) ++{ ++ struct search_ctx *ctx = data; ++ int found = 0; + +- /* Skip floppy drives when requested. */ +- if (no_floppy && +- name[0] == 'f' && name[1] == 'd' && name[2] >= '0' && name[2] <= '9') +- return 0; ++ /* Skip floppy drives when requested. */ ++ if (ctx->no_floppy && ++ name[0] == 'f' && name[1] == 'd' && name[2] >= '0' && name[2] <= '9') ++ return 0; + + #ifdef DO_SEARCH_FS_UUID + #define compare_fn grub_strcasecmp +@@ -67,34 +73,34 @@ FUNC_NAME (const char *key, const char *var, int no_floppy, + #endif + + #ifdef DO_SEARCH_FILE +- { +- char *buf; +- grub_file_t file; +- +- buf = grub_xasprintf ("(%s)%s", name, key); +- if (! buf) +- return 1; +- +- grub_file_filter_disable_compression (); +- file = grub_file_open (buf); +- if (file) +- { +- found = 1; +- grub_file_close (file); +- } +- grub_free (buf); +- } ++ { ++ char *buf; ++ grub_file_t file; ++ ++ buf = grub_xasprintf ("(%s)%s", name, ctx->key); ++ if (! buf) ++ return 1; ++ ++ grub_file_filter_disable_compression (); ++ file = grub_file_open (buf); ++ if (file) ++ { ++ found = 1; ++ grub_file_close (file); ++ } ++ grub_free (buf); ++ } + #else +- { +- /* SEARCH_FS_UUID or SEARCH_LABEL */ +- grub_device_t dev; +- grub_fs_t fs; +- char *quid; ++ { ++ /* SEARCH_FS_UUID or SEARCH_LABEL */ ++ grub_device_t dev; ++ grub_fs_t fs; ++ char *quid; + +- dev = grub_device_open (name); +- if (dev) +- { +- fs = grub_fs_probe (dev); ++ dev = grub_device_open (name); ++ if (dev) ++ { ++ fs = grub_fs_probe (dev); + + #ifdef DO_SEARCH_FS_UUID + #define read_fn uuid +@@ -102,173 +108,191 @@ FUNC_NAME (const char *key, const char *var, int no_floppy, + #define read_fn label + #endif + +- if (fs && fs->read_fn) +- { +- fs->read_fn (dev, &quid); ++ if (fs && fs->read_fn) ++ { ++ fs->read_fn (dev, &quid); + +- if (grub_errno == GRUB_ERR_NONE && quid) +- { +- if (compare_fn (quid, key) == 0) +- found = 1; ++ if (grub_errno == GRUB_ERR_NONE && quid) ++ { ++ if (compare_fn (quid, ctx->key) == 0) ++ found = 1; + +- grub_free (quid); +- } +- } ++ grub_free (quid); ++ } ++ } + +- grub_device_close (dev); +- } +- } ++ grub_device_close (dev); ++ } ++ } + #endif + +- if (!is_cache && found && count == 0) +- { +- struct cache_entry *cache_ent; +- cache_ent = grub_malloc (sizeof (*cache_ent)); +- if (cache_ent) +- { +- cache_ent->key = grub_strdup (key); +- cache_ent->value = grub_strdup (name); +- if (cache_ent->value && cache_ent->key) +- { +- cache_ent->next = cache; +- cache = cache_ent; +- } +- else +- { +- grub_free (cache_ent->value); +- grub_free (cache_ent->key); +- grub_free (cache_ent); +- grub_errno = GRUB_ERR_NONE; +- } +- } +- else +- grub_errno = GRUB_ERR_NONE; +- } +- +- if (found) +- { +- count++; +- if (var) +- grub_env_set (var, name); +- else +- grub_printf (" %s", name); +- } +- +- grub_errno = GRUB_ERR_NONE; +- return (found && var); +- } +- +- auto int part_hook (grub_disk_t disk, const grub_partition_t partition); +- int part_hook (grub_disk_t disk, const grub_partition_t partition) +- { +- char *partition_name, *devname; +- int ret; +- +- partition_name = grub_partition_get_name (partition); +- if (! partition_name) +- return 1; +- +- devname = grub_xasprintf ("%s,%s", disk->name, partition_name); +- grub_free (partition_name); +- if (!devname) +- return 1; +- ret = iterate_device (devname); +- grub_free (devname); +- +- return ret; +- } +- +- auto void try (void); +- void try (void) +- { +- unsigned i; +- struct cache_entry **prev; +- struct cache_entry *cache_ent; +- +- for (prev = &cache, cache_ent = *prev; cache_ent; +- prev = &cache_ent->next, cache_ent = *prev) +- if (compare_fn (cache_ent->key, key) == 0) +- break; +- if (cache_ent) +- { +- is_cache = 1; +- if (iterate_device (cache_ent->value)) +- { +- is_cache = 0; +- return; +- } +- is_cache = 0; +- /* Cache entry was outdated. Remove it. */ +- if (!count) +- { +- grub_free (cache_ent->key); +- grub_free (cache_ent->value); +- grub_free (cache_ent); +- *prev = cache_ent->next; +- } +- } +- +- for (i = 0; i < nhints; i++) +- { +- char *end; +- if (!hints[i][0]) +- continue; +- end = hints[i] + grub_strlen (hints[i]) - 1; +- if (*end == ',') +- *end = 0; +- if (iterate_device (hints[i])) +- { +- if (!*end) +- *end = ','; ++ if (!ctx->is_cache && found && ctx->count == 0) ++ { ++ struct cache_entry *cache_ent; ++ cache_ent = grub_malloc (sizeof (*cache_ent)); ++ if (cache_ent) ++ { ++ cache_ent->key = grub_strdup (ctx->key); ++ cache_ent->value = grub_strdup (name); ++ if (cache_ent->value && cache_ent->key) ++ { ++ cache_ent->next = cache; ++ cache = cache_ent; ++ } ++ else ++ { ++ grub_free (cache_ent->value); ++ grub_free (cache_ent->key); ++ grub_free (cache_ent); ++ grub_errno = GRUB_ERR_NONE; ++ } ++ } ++ else ++ grub_errno = GRUB_ERR_NONE; ++ } ++ ++ if (found) ++ { ++ ctx->count++; ++ if (ctx->var) ++ grub_env_set (ctx->var, name); ++ else ++ grub_printf (" %s", name); ++ } ++ ++ grub_errno = GRUB_ERR_NONE; ++ return (found && ctx->var); ++} ++ ++/* Helper for FUNC_NAME. */ ++static int ++part_hook (grub_disk_t disk, const grub_partition_t partition, void *data) ++{ ++ struct search_ctx *ctx = data; ++ char *partition_name, *devname; ++ int ret; ++ ++ partition_name = grub_partition_get_name (partition); ++ if (! partition_name) ++ return 1; ++ ++ devname = grub_xasprintf ("%s,%s", disk->name, partition_name); ++ grub_free (partition_name); ++ if (!devname) ++ return 1; ++ ret = iterate_device (devname, ctx); ++ grub_free (devname); ++ ++ return ret; ++} ++ ++/* Helper for FUNC_NAME. */ ++static void ++try (struct search_ctx *ctx) ++{ ++ unsigned i; ++ struct cache_entry **prev; ++ struct cache_entry *cache_ent; ++ ++ for (prev = &cache, cache_ent = *prev; cache_ent; ++ prev = &cache_ent->next, cache_ent = *prev) ++ if (compare_fn (cache_ent->key, ctx->key) == 0) ++ break; ++ if (cache_ent) ++ { ++ ctx->is_cache = 1; ++ if (iterate_device (cache_ent->value, ctx)) ++ { ++ ctx->is_cache = 0; ++ return; ++ } ++ ctx->is_cache = 0; ++ /* Cache entry was outdated. Remove it. */ ++ if (!ctx->count) ++ { ++ grub_free (cache_ent->key); ++ grub_free (cache_ent->value); ++ grub_free (cache_ent); ++ *prev = cache_ent->next; ++ } ++ } ++ ++ for (i = 0; i < ctx->nhints; i++) ++ { ++ char *end; ++ if (!ctx->hints[i][0]) ++ continue; ++ end = ctx->hints[i] + grub_strlen (ctx->hints[i]) - 1; ++ if (*end == ',') ++ *end = 0; ++ if (iterate_device (ctx->hints[i], ctx)) ++ { ++ if (!*end) ++ *end = ','; ++ return; ++ } ++ if (!*end) ++ { ++ grub_device_t dev; ++ int ret; ++ dev = grub_device_open (ctx->hints[i]); ++ if (!dev) ++ { ++ if (!*end) ++ *end = ','; ++ continue; ++ } ++ if (!dev->disk) ++ { ++ grub_device_close (dev); ++ if (!*end) ++ *end = ','; ++ continue; ++ } ++ ret = grub_partition_iterate (dev->disk, part_hook, ctx); ++ if (!*end) ++ *end = ','; ++ grub_device_close (dev); ++ if (ret) + return; +- } +- if (!*end) +- { +- grub_device_t dev; +- int ret; +- dev = grub_device_open (hints[i]); +- if (!dev) +- { +- if (!*end) +- *end = ','; +- continue; +- } +- if (!dev->disk) +- { +- grub_device_close (dev); +- if (!*end) +- *end = ','; +- continue; +- } +- ret = grub_partition_iterate (dev->disk, part_hook); +- if (!*end) +- *end = ','; +- grub_device_close (dev); +- if (ret) +- return; +- } +- } +- grub_device_iterate (iterate_device); +- } ++ } ++ } ++ grub_device_iterate (iterate_device, ctx); ++} ++ ++void ++FUNC_NAME (const char *key, const char *var, int no_floppy, ++ char **hints, unsigned nhints) ++{ ++ struct search_ctx ctx = { ++ .key = key, ++ .var = var, ++ .no_floppy = no_floppy, ++ .hints = hints, ++ .nhints = nhints, ++ .count = 0, ++ .is_cache = 0 ++ }; ++ grub_fs_autoload_hook_t saved_autoload; + + /* First try without autoloading if we're setting variable. */ + if (var) + { + saved_autoload = grub_fs_autoload_hook; + grub_fs_autoload_hook = 0; +- try (); ++ try (&ctx); + + /* Restore autoload hook. */ + grub_fs_autoload_hook = saved_autoload; + + /* Retry with autoload if nothing found. */ +- if (grub_errno == GRUB_ERR_NONE && count == 0) +- try (); ++ if (grub_errno == GRUB_ERR_NONE && ctx.count == 0) ++ try (&ctx); + } + else +- try (); ++ try (&ctx); + +- if (grub_errno == GRUB_ERR_NONE && count == 0) ++ if (grub_errno == GRUB_ERR_NONE && ctx.count == 0) + grub_error (GRUB_ERR_FILE_NOT_FOUND, "no such device: %s", key); + } + +diff --git a/grub-core/commands/wildcard.c b/grub-core/commands/wildcard.c +index 2b73d9a..633de51 100644 +--- a/grub-core/commands/wildcard.c ++++ b/grub-core/commands/wildcard.c +@@ -210,59 +210,71 @@ split_path (const char *str, const char **noregexop, const char **regexop) + *noregexop = split; + } + +-static char ** +-match_devices (const regex_t *regexp, int noparts) ++/* Context for match_devices. */ ++struct match_devices_ctx + { +- int i; ++ const regex_t *regexp; ++ int noparts; + int ndev; + char **devs; ++}; + +- auto int match (const char *name); +- int match (const char *name) +- { +- char **t; +- char *buffer; ++/* Helper for match_devices. */ ++static int ++match_devices_iter (const char *name, void *data) ++{ ++ struct match_devices_ctx *ctx = data; ++ char **t; ++ char *buffer; + +- /* skip partitions if asked to. */ +- if (noparts && grub_strchr(name, ',')) +- return 0; ++ /* skip partitions if asked to. */ ++ if (ctx->noparts && grub_strchr (name, ',')) ++ return 0; + +- buffer = grub_xasprintf ("(%s)", name); +- if (! buffer) +- return 1; ++ buffer = grub_xasprintf ("(%s)", name); ++ if (! buffer) ++ return 1; + +- grub_dprintf ("expand", "matching: %s\n", buffer); +- if (regexec (regexp, buffer, 0, 0, 0)) +- { +- grub_dprintf ("expand", "not matched\n"); +- grub_free (buffer); +- return 0; +- } ++ grub_dprintf ("expand", "matching: %s\n", buffer); ++ if (regexec (ctx->regexp, buffer, 0, 0, 0)) ++ { ++ grub_dprintf ("expand", "not matched\n"); ++ grub_free (buffer); ++ return 0; ++ } + +- t = grub_realloc (devs, sizeof (char*) * (ndev + 2)); +- if (! t) +- return 1; ++ t = grub_realloc (ctx->devs, sizeof (char*) * (ctx->ndev + 2)); ++ if (! t) ++ return 1; + +- devs = t; +- devs[ndev++] = buffer; +- devs[ndev] = 0; +- return 0; +- } ++ ctx->devs = t; ++ ctx->devs[ctx->ndev++] = buffer; ++ ctx->devs[ctx->ndev] = 0; ++ return 0; ++} + +- ndev = 0; +- devs = 0; ++static char ** ++match_devices (const regex_t *regexp, int noparts) ++{ ++ struct match_devices_ctx ctx = { ++ .regexp = regexp, ++ .noparts = noparts, ++ .ndev = 0, ++ .devs = 0 ++ }; ++ int i; + +- if (grub_device_iterate (match)) ++ if (grub_device_iterate (match_devices_iter, &ctx)) + goto fail; + +- return devs; ++ return ctx.devs; + + fail: + +- for (i = 0; devs && devs[i]; i++) +- grub_free (devs[i]); ++ for (i = 0; ctx.devs && ctx.devs[i]; i++) ++ grub_free (ctx.devs[i]); + +- grub_free (devs); ++ grub_free (ctx.devs); + + return 0; + } +diff --git a/grub-core/disk/ahci.c b/grub-core/disk/ahci.c +index f229ff1..f9258fd 100644 +--- a/grub-core/disk/ahci.c ++++ b/grub-core/disk/ahci.c +@@ -455,8 +455,8 @@ grub_ahci_restore_hw (void) + + + static int +-grub_ahci_iterate (int (*hook) (int id, int bus), +- grub_disk_pull_t pull) ++grub_ahci_iterate (grub_ata_dev_iterate_hook_t hook, void *hook_data, ++ grub_disk_pull_t pull) + { + struct grub_ahci_device *dev; + +@@ -464,7 +464,7 @@ grub_ahci_iterate (int (*hook) (int id, int bus), + return 0; + + FOR_LIST_ELEMENTS(dev, grub_ahci_devices) +- if (hook (GRUB_SCSI_SUBSYSTEM_AHCI, dev->num)) ++ if (hook (GRUB_SCSI_SUBSYSTEM_AHCI, dev->num, hook_data)) + return 1; + + return 0; +diff --git a/grub-core/disk/arc/arcdisk.c b/grub-core/disk/arc/arcdisk.c +index 10cbc87..37c0ac3 100644 +--- a/grub-core/disk/arc/arcdisk.c ++++ b/grub-core/disk/arc/arcdisk.c +@@ -80,23 +80,37 @@ arcdisk_hash_add (char *devpath) + } + + ++/* Context for grub_arcdisk_iterate. */ ++struct grub_arcdisk_iterate_ctx ++{ ++ grub_disk_dev_iterate_hook_t hook; ++ void *hook_data; ++}; ++ ++/* Helper for grub_arcdisk_iterate. */ ++static int ++grub_arcdisk_iterate_iter (const char *name, ++ const struct grub_arc_component *comp, void *data) ++{ ++ struct grub_arcdisk_iterate_ctx *ctx = data; ++ ++ if (!(comp->type == GRUB_ARC_COMPONENT_TYPE_DISK ++ || comp->type == GRUB_ARC_COMPONENT_TYPE_DISK ++ || comp->type == GRUB_ARC_COMPONENT_TYPE_TAPE)) ++ return 0; ++ return ctx->hook (name, ctx->hook_data); ++} ++ + static int + grub_arcdisk_iterate (int (*hook_in) (const char *name), + grub_disk_pull_t pull) + { +- auto int hook (const char *name, const struct grub_arc_component *comp); +- int hook (const char *name, const struct grub_arc_component *comp) +- { +- if (!(comp->type == GRUB_ARC_COMPONENT_TYPE_DISK +- || comp->type == GRUB_ARC_COMPONENT_TYPE_DISK +- || comp->type == GRUB_ARC_COMPONENT_TYPE_TAPE)) +- return 0; +- return hook_in (name); +- } ++ struct grub_arcdisk_iterate_ctx ctx = { hook, hook_data }; ++ + if (pull != GRUB_DISK_PULL_NONE) + return 0; + +- return grub_arc_iterate_devs (hook, 1); ++ return grub_arc_iterate_devs (grub_arcdisk_iterate_iter, &ctx, 1); + } + + #define RAW_SUFFIX "partition(10)" +diff --git a/grub-core/disk/ata.c b/grub-core/disk/ata.c +index c0d378c..c84d316 100644 +--- a/grub-core/disk/ata.c ++++ b/grub-core/disk/ata.c +@@ -392,40 +392,50 @@ grub_ata_real_open (int id, int bus) + return NULL; + } + ++/* Context for grub_ata_iterate. */ ++struct grub_ata_iterate_ctx ++{ ++ grub_disk_dev_iterate_hook_t hook; ++ void *hook_data; ++}; ++ ++/* Helper for grub_ata_iterate. */ + static int +-grub_ata_iterate (int (*hook_in) (const char *name), +- grub_disk_pull_t pull) ++grub_ata_iterate_iter (int id, int bus, void *data) + { +- auto int hook (int id, int bus); +- int hook (int id, int bus) +- { +- struct grub_ata *ata; +- int ret; +- char devname[40]; ++ struct grub_ata_iterate_ctx *ctx = data; ++ struct grub_ata *ata; ++ int ret; ++ char devname[40]; + +- ata = grub_ata_real_open (id, bus); ++ ata = grub_ata_real_open (id, bus); + +- if (!ata) +- { +- grub_errno = GRUB_ERR_NONE; +- return 0; +- } +- if (ata->atapi) +- { +- grub_ata_real_close (ata); +- return 0; +- } +- grub_snprintf (devname, sizeof (devname), +- "%s%d", grub_scsi_names[id], bus); +- ret = hook_in (devname); +- grub_ata_real_close (ata); +- return ret; +- } ++ if (!ata) ++ { ++ grub_errno = GRUB_ERR_NONE; ++ return 0; ++ } ++ if (ata->atapi) ++ { ++ grub_ata_real_close (ata); ++ return 0; ++ } ++ grub_snprintf (devname, sizeof (devname), ++ "%s%d", grub_scsi_names[id], bus); ++ ret = ctx->hook (devname, ctx->hook_data); ++ grub_ata_real_close (ata); ++ return ret; ++} + ++static int ++grub_ata_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data, ++ grub_disk_pull_t pull) ++{ ++ struct grub_ata_iterate_ctx ctx = { hook, hook_data }; + grub_ata_dev_t p; + + for (p = grub_ata_dev_list; p; p = p->next) +- if (p->iterate && p->iterate (hook, pull)) ++ if (p->iterate && p->iterate (grub_ata_iterate_iter, &ctx, pull)) + return 1; + return 0; + } +@@ -561,37 +571,47 @@ grub_atapi_open (int id, int bus, struct grub_scsi *scsi) + return GRUB_ERR_NONE; + } + ++/* Context for grub_atapi_iterate. */ ++struct grub_atapi_iterate_ctx ++{ ++ grub_scsi_dev_iterate_hook_t hook; ++ void *hook_data; ++}; ++ ++/* Helper for grub_atapi_iterate. */ + static int +-grub_atapi_iterate (int NESTED_FUNC_ATTR (*hook_in) (int id, int bus, int luns), +- grub_disk_pull_t pull) ++grub_atapi_iterate_iter (int id, int bus, void *data) + { +- auto int hook (int id, int bus); +- int hook (int id, int bus) +- { +- struct grub_ata *ata; +- int ret; ++ struct grub_atapi_iterate_ctx *ctx = data; ++ struct grub_ata *ata; ++ int ret; + +- ata = grub_ata_real_open (id, bus); ++ ata = grub_ata_real_open (id, bus); + +- if (!ata) +- { +- grub_errno = GRUB_ERR_NONE; +- return 0; +- } +- if (!ata->atapi) +- { +- grub_ata_real_close (ata); +- return 0; +- } +- ret = hook_in (id, bus, 1); +- grub_ata_real_close (ata); +- return ret; +- } ++ if (!ata) ++ { ++ grub_errno = GRUB_ERR_NONE; ++ return 0; ++ } ++ if (!ata->atapi) ++ { ++ grub_ata_real_close (ata); ++ return 0; ++ } ++ ret = ctx->hook (id, bus, 1, ctx->hook_data); ++ grub_ata_real_close (ata); ++ return ret; ++} + ++static int ++grub_atapi_iterate (grub_scsi_dev_iterate_hook_t hook, void *hook_data, ++ grub_disk_pull_t pull) ++{ ++ struct grub_atapi_iterate_ctx ctx = { hook, hook_data }; + grub_ata_dev_t p; + + for (p = grub_ata_dev_list; p; p = p->next) +- if (p->iterate && p->iterate (hook, pull)) ++ if (p->iterate && p->iterate (grub_atapi_iterate_iter, &ctx, pull)) + return 1; + return 0; + } +diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c +index 3de3b86..ce755c3 100644 +--- a/grub-core/disk/cryptodisk.c ++++ b/grub-core/disk/cryptodisk.c +@@ -448,8 +448,8 @@ grub_cryptodisk_setkey (grub_cryptodisk_t dev, grub_uint8_t *key, grub_size_t ke + } + + static int +-grub_cryptodisk_iterate (int (*hook) (const char *name), +- grub_disk_pull_t pull) ++grub_cryptodisk_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data, ++ grub_disk_pull_t pull) + { + grub_cryptodisk_t i; + +@@ -460,7 +460,7 @@ grub_cryptodisk_iterate (int (*hook) (const char *name), + { + char buf[30]; + grub_snprintf (buf, sizeof (buf), "crypto%lu", i->id); +- if (hook (buf)) ++ if (hook (buf, hook_data)) + return 1; + } + +@@ -866,7 +866,8 @@ grub_cryptodisk_cheat_mount (const char *sourcedev, const char *cheat) + #endif + + static int +-grub_cryptodisk_scan_device (const char *name) ++grub_cryptodisk_scan_device (const char *name, ++ void *data __attribute__ ((unused))) + { + grub_err_t err; + grub_disk_t source; +@@ -908,7 +909,7 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args) + + check_boot = state[2].set; + search_uuid = args[0]; +- grub_device_iterate (&grub_cryptodisk_scan_device); ++ grub_device_iterate (&grub_cryptodisk_scan_device, NULL); + search_uuid = NULL; + + if (!have_it) +@@ -919,7 +920,7 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args) + { + search_uuid = NULL; + check_boot = state[2].set; +- grub_device_iterate (&grub_cryptodisk_scan_device); ++ grub_device_iterate (&grub_cryptodisk_scan_device, NULL); + search_uuid = NULL; + return GRUB_ERR_NONE; + } +diff --git a/grub-core/disk/diskfilter.c b/grub-core/disk/diskfilter.c +index 4117b20..2ff47e9 100644 +--- a/grub-core/disk/diskfilter.c ++++ b/grub-core/disk/diskfilter.c +@@ -120,65 +120,68 @@ is_valid_diskfilter_name (const char *name) + || grub_memcmp (name, "ldm/", sizeof ("ldm/") - 1) == 0); + } + ++/* Helper for scan_disk. */ + static int +-scan_disk (const char *name, int accept_diskfilter) ++scan_disk_partition_iter (grub_disk_t disk, grub_partition_t p, void *data) + { +- auto int hook (grub_disk_t disk, grub_partition_t p); +- int hook (grub_disk_t disk, grub_partition_t p) +- { +- struct grub_diskfilter_vg *arr; +- grub_disk_addr_t start_sector; +- struct grub_diskfilter_pv_id id; +- grub_diskfilter_t diskfilter; +- +- grub_dprintf ("diskfilter", "Scanning for DISKFILTER devices on disk %s\n", +- name); ++ const char *name = data; ++ struct grub_diskfilter_vg *arr; ++ grub_disk_addr_t start_sector; ++ struct grub_diskfilter_pv_id id; ++ grub_diskfilter_t diskfilter; ++ ++ grub_dprintf ("diskfilter", "Scanning for DISKFILTER devices on disk %s\n", ++ name); + #ifdef GRUB_UTIL +- grub_util_info ("Scanning for DISKFILTER devices on disk %s", name); ++ grub_util_info ("Scanning for DISKFILTER devices on disk %s", name); + #endif + +- disk->partition = p; +- +- for (arr = array_list; arr != NULL; arr = arr->next) +- { +- struct grub_diskfilter_pv *m; +- for (m = arr->pvs; m; m = m->next) +- if (m->disk && m->disk->id == disk->id +- && m->disk->dev->id == disk->dev->id +- && m->part_start == grub_partition_get_start (disk->partition) +- && m->part_size == grub_disk_get_size (disk)) +- return 0; +- } ++ disk->partition = p; ++ ++ for (arr = array_list; arr != NULL; arr = arr->next) ++ { ++ struct grub_diskfilter_pv *m; ++ for (m = arr->pvs; m; m = m->next) ++ if (m->disk && m->disk->id == disk->id ++ && m->disk->dev->id == disk->dev->id ++ && m->part_start == grub_partition_get_start (disk->partition) ++ && m->part_size == grub_disk_get_size (disk)) ++ return 0; ++ } + +- for (diskfilter = grub_diskfilter_list; diskfilter; diskfilter = diskfilter->next) +- { ++ for (diskfilter = grub_diskfilter_list; diskfilter; diskfilter = diskfilter->next) ++ { + #ifdef GRUB_UTIL +- grub_util_info ("Scanning for %s devices on disk %s", +- diskfilter->name, name); ++ grub_util_info ("Scanning for %s devices on disk %s", ++ diskfilter->name, name); + #endif +- id.uuid = 0; +- id.uuidlen = 0; +- arr = diskfilter->detect (disk, &id, &start_sector); +- if (arr && +- (! insert_array (disk, &id, arr, start_sector, diskfilter))) +- { +- if (id.uuidlen) +- grub_free (id.uuid); +- return 0; +- } +- if (arr && id.uuidlen) ++ id.uuid = 0; ++ id.uuidlen = 0; ++ arr = diskfilter->detect (disk, &id, &start_sector); ++ if (arr && ++ (! insert_array (disk, &id, arr, start_sector, diskfilter))) ++ { ++ if (id.uuidlen) + grub_free (id.uuid); +- +- /* This error usually means it's not diskfilter, no need to display +- it. */ +- if (grub_errno != GRUB_ERR_OUT_OF_RANGE) +- grub_print_error (); +- +- grub_errno = GRUB_ERR_NONE; ++ return 0; + } ++ if (arr && id.uuidlen) ++ grub_free (id.uuid); + +- return 0; ++ /* This error usually means it's not diskfilter, no need to display ++ it. */ ++ if (grub_errno != GRUB_ERR_OUT_OF_RANGE) ++ grub_print_error (); ++ ++ grub_errno = GRUB_ERR_NONE; + } ++ ++ return 0; ++} ++ ++static int ++scan_disk (const char *name, int accept_diskfilter) ++{ + grub_disk_t disk; + static int scan_depth = 0; + +@@ -196,12 +199,12 @@ scan_disk (const char *name, int accept_diskfilter) + scan_depth--; + return 0; + } +- if (hook (disk, 0)) ++ if (scan_disk_partition_iter (disk, 0, (void *) name)) + { + scan_depth--; + return 1; + } +- if (grub_partition_iterate (disk, hook)) ++ if (grub_partition_iterate (disk, scan_disk_partition_iter, (void *) name)) + { + scan_depth--; + return 1; +@@ -212,7 +215,7 @@ scan_disk (const char *name, int accept_diskfilter) + } + + static int +-scan_disk_hook (const char *name) ++scan_disk_hook (const char *name, void *data __attribute__ ((unused))) + { + return scan_disk (name, 0); + } +@@ -230,7 +233,7 @@ scan_devices (const char *arname) + if (p->id != GRUB_DISK_DEVICE_DISKFILTER_ID + && p->iterate) + { +- if ((p->iterate) (scan_disk_hook, pull)) ++ if ((p->iterate) (scan_disk_hook, NULL, pull)) + return; + if (arname && is_lv_readable (find_lv (arname), 1)) + return; +@@ -249,8 +252,8 @@ scan_devices (const char *arname) + } + + static int +-grub_diskfilter_iterate (int (*hook) (const char *name), +- grub_disk_pull_t pull) ++grub_diskfilter_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data, ++ grub_disk_pull_t pull) + { + struct grub_diskfilter_vg *array; + int islcnt = 0; +@@ -271,7 +274,7 @@ grub_diskfilter_iterate (int (*hook) (const char *name), + for (lv = array->lvs; lv; lv = lv->next) + if (lv->visible && lv->fullname && lv->became_readable_at >= islcnt) + { +- if (hook (lv->fullname)) ++ if (hook (lv->fullname, hook_data)) + return 1; + } + } +@@ -303,7 +306,7 @@ grub_diskfilter_memberlist (grub_disk_t disk) + if (p->id != GRUB_DISK_DEVICE_DISKFILTER_ID + && p->iterate) + { +- (p->iterate) (scan_disk_hook, pull); ++ (p->iterate) (scan_disk_hook, NULL, pull); + while (pv && pv->disk) + pv = pv->next; + } +diff --git a/grub-core/disk/efi/efidisk.c b/grub-core/disk/efi/efidisk.c +index d9d788c..98cd226 100644 +--- a/grub-core/disk/efi/efidisk.c ++++ b/grub-core/disk/efi/efidisk.c +@@ -404,7 +404,7 @@ enumerate_disks (void) + } + + static int +-grub_efidisk_iterate (int (*hook) (const char *name), ++grub_efidisk_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data, + grub_disk_pull_t pull) + { + struct grub_efidisk_data *d; +@@ -418,7 +418,7 @@ grub_efidisk_iterate (int (*hook) (const char *name), + { + grub_snprintf (buf, sizeof (buf), "hd%d", count); + grub_dprintf ("efidisk", "iterating %s\n", buf); +- if (hook (buf)) ++ if (hook (buf, hook_data)) + return 1; + } + break; +@@ -427,7 +427,7 @@ grub_efidisk_iterate (int (*hook) (const char *name), + { + grub_snprintf (buf, sizeof (buf), "fd%d", count); + grub_dprintf ("efidisk", "iterating %s\n", buf); +- if (hook (buf)) ++ if (hook (buf, hook_data)) + return 1; + } + +@@ -435,7 +435,7 @@ grub_efidisk_iterate (int (*hook) (const char *name), + { + grub_snprintf (buf, sizeof (buf), "cd%d", count); + grub_dprintf ("efidisk", "iterating %s\n", buf); +- if (hook (buf)) ++ if (hook (buf, hook_data)) + return 1; + } + break; +@@ -736,6 +736,31 @@ get_diskname_from_path (const grub_efi_device_path_t *path, + return 0; + } + ++/* Context for grub_efidisk_get_device_name. */ ++struct grub_efidisk_get_device_name_ctx ++{ ++ char *partition_name; ++ grub_efi_hard_drive_device_path_t hd; ++}; ++ ++/* Helper for grub_efidisk_get_device_name. ++ Find the identical partition. */ ++static int ++grub_efidisk_get_device_name_iter (grub_disk_t disk __attribute__ ((unused)), ++ const grub_partition_t part, void *data) ++{ ++ struct grub_efidisk_get_device_name_ctx *ctx = data; ++ ++ if (grub_partition_get_start (part) == ctx->hd.partition_start ++ && grub_partition_get_len (part) == ctx->hd.partition_size) ++ { ++ ctx->partition_name = grub_partition_get_name (part); ++ return 1; ++ } ++ ++ return 0; ++} ++ + char * + grub_efidisk_get_device_name (grub_efi_handle_t *handle) + { +@@ -754,28 +779,11 @@ grub_efidisk_get_device_name (grub_efi_handle_t *handle) + && (GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) + == GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE)) + { +- char *partition_name = NULL; ++ struct grub_efidisk_get_device_name_ctx ctx; + char *dev_name; + grub_efi_device_path_t *dup_dp, *dup_ldp; +- grub_efi_hard_drive_device_path_t hd; + grub_disk_t parent = 0; + +- auto int find_partition (grub_disk_t disk, const grub_partition_t part); +- +- /* Find the identical partition. */ +- int find_partition (grub_disk_t disk __attribute__ ((unused)), +- const grub_partition_t part) +- { +- if (grub_partition_get_start (part) == hd.partition_start +- && grub_partition_get_len (part) == hd.partition_size) +- { +- partition_name = grub_partition_get_name (part); +- return 1; +- } +- +- return 0; +- } +- + /* It is necessary to duplicate the device path so that GRUB + can overwrite it. */ + dup_dp = duplicate_device_path (dp); +@@ -797,24 +805,27 @@ grub_efidisk_get_device_name (grub_efi_handle_t *handle) + return 0; + + /* Find a partition which matches the hard drive device path. */ +- grub_memcpy (&hd, ldp, sizeof (hd)); +- if (hd.partition_start == 0 +- && hd.partition_size == grub_disk_get_size (parent)) ++ ctx.partition_name = NULL; ++ grub_memcpy (&ctx.hd, ldp, sizeof (ctx.hd)); ++ if (ctx.hd.partition_start == 0 ++ && ctx.hd.partition_size == grub_disk_get_size (parent)) + { + dev_name = grub_strdup (parent->name); + } + else + { +- grub_partition_iterate (parent, find_partition); ++ grub_partition_iterate (parent, grub_efidisk_get_device_name_iter, ++ &ctx); + +- if (! partition_name) ++ if (! ctx.partition_name) + { + grub_disk_close (parent); + return 0; + } + +- dev_name = grub_xasprintf ("%s,%s", parent->name, partition_name); +- grub_free (partition_name); ++ dev_name = grub_xasprintf ("%s,%s", parent->name, ++ ctx.partition_name); ++ grub_free (ctx.partition_name); + } + grub_disk_close (parent); + +diff --git a/grub-core/disk/host.c b/grub-core/disk/host.c +index 5ee0d2e..959211b 100644 +--- a/grub-core/disk/host.c ++++ b/grub-core/disk/host.c +@@ -27,13 +27,13 @@ + int grub_disk_host_i_want_a_reference; + + static int +-grub_host_iterate (int (*hook) (const char *name), ++grub_host_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data, + grub_disk_pull_t pull) + { + if (pull != GRUB_DISK_PULL_NONE) + return 0; + +- if (hook ("host")) ++ if (hook ("host", hook_data)) + return 1; + return 0; + } +diff --git a/grub-core/disk/i386/pc/biosdisk.c b/grub-core/disk/i386/pc/biosdisk.c +index 7ca89e3..7c8dca3 100644 +--- a/grub-core/disk/i386/pc/biosdisk.c ++++ b/grub-core/disk/i386/pc/biosdisk.c +@@ -272,20 +272,21 @@ grub_biosdisk_get_drive (const char *name) + } + + static int +-grub_biosdisk_call_hook (int (*hook) (const char *name), int drive) ++grub_biosdisk_call_hook (grub_disk_dev_iterate_hook_t hook, void *hook_data, ++ int drive) + { + char name[10]; + + if (cd_drive && drive == cd_drive) +- return hook ("cd"); ++ return hook ("cd", hook_data); + + grub_snprintf (name, sizeof (name), + (drive & 0x80) ? "hd%d" : "fd%d", drive & (~0x80)); +- return hook (name); ++ return hook (name, hook_data); + } + + static int +-grub_biosdisk_iterate (int (*hook) (const char *name), ++grub_biosdisk_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data, + grub_disk_pull_t pull __attribute__ ((unused))) + { + int num_floppies; +@@ -304,7 +305,7 @@ grub_biosdisk_iterate (int (*hook) (const char *name), + break; + } + +- if (grub_biosdisk_call_hook (hook, drive)) ++ if (grub_biosdisk_call_hook (hook, hook_data, drive)) + return 1; + } + return 0; +@@ -312,14 +313,14 @@ grub_biosdisk_iterate (int (*hook) (const char *name), + case GRUB_DISK_PULL_REMOVABLE: + if (cd_drive) + { +- if (grub_biosdisk_call_hook (hook, cd_drive)) ++ if (grub_biosdisk_call_hook (hook, hook_data, cd_drive)) + return 1; + } + + /* For floppy disks, we can get the number safely. */ + num_floppies = grub_biosdisk_get_num_floppies (); + for (drive = 0; drive < num_floppies; drive++) +- if (grub_biosdisk_call_hook (hook, drive)) ++ if (grub_biosdisk_call_hook (hook, hook_data, drive)) + return 1; + return 0; + default: +diff --git a/grub-core/disk/ieee1275/nand.c b/grub-core/disk/ieee1275/nand.c +index 3474b3e..b2844b1 100644 +--- a/grub-core/disk/ieee1275/nand.c ++++ b/grub-core/disk/ieee1275/nand.c +@@ -33,7 +33,7 @@ struct grub_nand_data + }; + + static int +-grub_nand_iterate (int (*hook) (const char *name), ++grub_nand_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data, + grub_disk_pull_t pull) + { + auto int dev_iterate (struct grub_ieee1275_devalias *alias); +@@ -41,7 +41,7 @@ grub_nand_iterate (int (*hook) (const char *name), + { + if (grub_strcmp (alias->name, "nand") == 0) + { +- hook (alias->name); ++ hook (alias->name, hook_data); + return 1; + } + +diff --git a/grub-core/disk/ieee1275/ofdisk.c b/grub-core/disk/ieee1275/ofdisk.c +index c9535a0..644bbd2 100644 +--- a/grub-core/disk/ieee1275/ofdisk.c ++++ b/grub-core/disk/ieee1275/ofdisk.c +@@ -218,7 +218,7 @@ scan (void) + } + + static int +-grub_ofdisk_iterate (int (*hook) (const char *name), ++grub_ofdisk_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data, + grub_disk_pull_t pull) + { + unsigned i; +@@ -276,7 +276,7 @@ grub_ofdisk_iterate (int (*hook) (const char *name), + *optr++ = *iptr++; + } + *optr = 0; +- if (hook (buffer)) ++ if (hook (buffer, hook_data)) + return 1; + } + } +diff --git a/grub-core/disk/ldm.c b/grub-core/disk/ldm.c +index 0e4761b..b92433d 100644 +--- a/grub-core/disk/ldm.c ++++ b/grub-core/disk/ldm.c +@@ -105,35 +105,39 @@ read_int (grub_uint8_t *in, grub_size_t s) + + static const grub_gpt_part_type_t ldm_type = GRUB_GPT_PARTITION_TYPE_LDM; + ++/* Helper for gpt_ldm_sector. */ ++static int ++gpt_ldm_sector_iter (grub_disk_t disk, const grub_partition_t p, void *data) ++{ ++ grub_disk_addr_t *sector = data; ++ struct grub_gpt_partentry gptdata; ++ grub_partition_t p2; ++ ++ p2 = disk->partition; ++ disk->partition = p->parent; ++ if (grub_disk_read (disk, p->offset, p->index, ++ sizeof (gptdata), &gptdata)) ++ { ++ disk->partition = p2; ++ return 0; ++ } ++ disk->partition = p2; ++ ++ if (! grub_memcmp (&gptdata.type, &ldm_type, 16)) ++ { ++ *sector = p->start + p->len - 1; ++ return 1; ++ } ++ return 0; ++} ++ + static grub_disk_addr_t + gpt_ldm_sector (grub_disk_t dsk) + { + grub_disk_addr_t sector = 0; + grub_err_t err; +- auto int hook (grub_disk_t disk, const grub_partition_t p); +- int hook (grub_disk_t disk, const grub_partition_t p) +- { +- struct grub_gpt_partentry gptdata; +- grub_partition_t p2; +- +- p2 = disk->partition; +- disk->partition = p->parent; +- if (grub_disk_read (disk, p->offset, p->index, +- sizeof (gptdata), &gptdata)) +- { +- disk->partition = p2; +- return 0; +- } +- disk->partition = p2; + +- if (! grub_memcmp (&gptdata.type, &ldm_type, 16)) +- { +- sector = p->start + p->len - 1; +- return 1; +- } +- return 0; +- } +- err = grub_gpt_partition_map_iterate (dsk, hook); ++ err = grub_gpt_partition_map_iterate (dsk, gpt_ldm_sector_iter, §or); + if (err) + { + grub_errno = GRUB_ERR_NONE; +diff --git a/grub-core/disk/loopback.c b/grub-core/disk/loopback.c +index fffd1bb..fed88de 100644 +--- a/grub-core/disk/loopback.c ++++ b/grub-core/disk/loopback.c +@@ -135,15 +135,15 @@ fail: + + + static int +-grub_loopback_iterate (int (*hook) (const char *name), +- grub_disk_pull_t pull) ++grub_loopback_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data, ++ grub_disk_pull_t pull) + { + struct grub_loopback *d; + if (pull != GRUB_DISK_PULL_NONE) + return 0; + for (d = loopback_list; d; d = d->next) + { +- if (hook (d->devname)) ++ if (hook (d->devname, hook_data)) + return 1; + } + return 0; +diff --git a/grub-core/disk/memdisk.c b/grub-core/disk/memdisk.c +index 4de0971..4ad1cb1 100644 +--- a/grub-core/disk/memdisk.c ++++ b/grub-core/disk/memdisk.c +@@ -30,13 +30,13 @@ static char *memdisk_addr; + static grub_off_t memdisk_size = 0; + + static int +-grub_memdisk_iterate (int (*hook) (const char *name), ++grub_memdisk_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data, + grub_disk_pull_t pull) + { + if (pull != GRUB_DISK_PULL_NONE) + return 0; + +- return hook ("memdisk"); ++ return hook ("memdisk", hook_data); + } + + static grub_err_t +diff --git a/grub-core/disk/pata.c b/grub-core/disk/pata.c +index 07c3d7f..75e5deb 100644 +--- a/grub-core/disk/pata.c ++++ b/grub-core/disk/pata.c +@@ -501,7 +501,7 @@ grub_pata_open (int id, int devnum, struct grub_ata *ata) + } + + static int +-grub_pata_iterate (int (*hook) (int id, int bus), ++grub_pata_iterate (grub_ata_dev_iterate_hook_t hook, void *hook_data, + grub_disk_pull_t pull) + { + struct grub_pata_device *dev; +@@ -510,7 +510,8 @@ grub_pata_iterate (int (*hook) (int id, int bus), + return 0; + + for (dev = grub_pata_devices; dev; dev = dev->next) +- if (hook (GRUB_SCSI_SUBSYSTEM_PATA, dev->port * 2 + dev->device)) ++ if (hook (GRUB_SCSI_SUBSYSTEM_PATA, dev->port * 2 + dev->device, ++ hook_data)) + return 1; + + return 0; +diff --git a/grub-core/disk/scsi.c b/grub-core/disk/scsi.c +index 29dd0d3..90ac379 100644 +--- a/grub-core/disk/scsi.c ++++ b/grub-core/disk/scsi.c +@@ -423,50 +423,59 @@ grub_scsi_write16 (grub_disk_t disk, grub_disk_addr_t sector, + + + +-static int +-grub_scsi_iterate (int (*hook) (const char *name), +- grub_disk_pull_t pull) ++/* Context for grub_scsi_iterate. */ ++struct grub_scsi_iterate_ctx + { +- grub_scsi_dev_t p; ++ grub_disk_dev_iterate_hook_t hook; ++ void *hook_data; ++}; + +- auto int NESTED_FUNC_ATTR scsi_iterate (int id, int bus, int luns); ++/* Helper for grub_scsi_iterate. */ ++static int ++scsi_iterate (int id, int bus, int luns, void *data) ++{ ++ struct grub_scsi_iterate_ctx *ctx = data; ++ int i; + +- int NESTED_FUNC_ATTR scsi_iterate (int id, int bus, int luns) ++ /* In case of a single LUN, just return `usbX'. */ ++ if (luns == 1) + { +- int i; +- +- /* In case of a single LUN, just return `usbX'. */ +- if (luns == 1) +- { +- char *sname; +- int ret; +- sname = grub_xasprintf ("%s%d", grub_scsi_names[id], bus); +- if (!sname) +- return 1; +- ret = hook (sname); +- grub_free (sname); +- return ret; +- } ++ char *sname; ++ int ret; ++ sname = grub_xasprintf ("%s%d", grub_scsi_names[id], bus); ++ if (!sname) ++ return 1; ++ ret = ctx->hook (sname, ctx->hook_data); ++ grub_free (sname); ++ return ret; ++ } + +- /* In case of multiple LUNs, every LUN will get a prefix to +- distinguish it. */ +- for (i = 0; i < luns; i++) +- { +- char *sname; +- int ret; +- sname = grub_xasprintf ("%s%d%c", grub_scsi_names[id], bus, 'a' + i); +- if (!sname) +- return 1; +- ret = hook (sname); +- grub_free (sname); +- if (ret) +- return 1; +- } +- return 0; ++ /* In case of multiple LUNs, every LUN will get a prefix to ++ distinguish it. */ ++ for (i = 0; i < luns; i++) ++ { ++ char *sname; ++ int ret; ++ sname = grub_xasprintf ("%s%d%c", grub_scsi_names[id], bus, 'a' + i); ++ if (!sname) ++ return 1; ++ ret = ctx->hook (sname, ctx->hook_data); ++ grub_free (sname); ++ if (ret) ++ return 1; + } ++ return 0; ++} ++ ++static int ++grub_scsi_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data, ++ grub_disk_pull_t pull) ++{ ++ struct grub_scsi_iterate_ctx ctx = { hook, hook_data }; ++ grub_scsi_dev_t p; + + for (p = grub_scsi_dev_list; p; p = p->next) +- if (p->iterate && (p->iterate) (scsi_iterate, pull)) ++ if (p->iterate && (p->iterate) (scsi_iterate, &ctx, pull)) + return 1; + + return 0; +diff --git a/grub-core/disk/usbms.c b/grub-core/disk/usbms.c +index 52cc33e..50f0caf 100644 +--- a/grub-core/disk/usbms.c ++++ b/grub-core/disk/usbms.c +@@ -265,7 +265,7 @@ grub_usbms_attach (grub_usb_device_t usbdev, int configno, int interfno) + + + static int +-grub_usbms_iterate (int NESTED_FUNC_ATTR (*hook) (int id, int bus, int luns), ++grub_usbms_iterate (grub_scsi_dev_iterate_hook_t hook, void *hook_data, + grub_disk_pull_t pull) + { + unsigned i; +@@ -278,7 +278,8 @@ grub_usbms_iterate (int NESTED_FUNC_ATTR (*hook) (int id, int bus, int luns), + for (i = 0; i < ARRAY_SIZE (grub_usbms_devices); i++) + if (grub_usbms_devices[i]) + { +- if (hook (GRUB_SCSI_SUBSYSTEM_USBMS, i, grub_usbms_devices[i]->luns)) ++ if (hook (GRUB_SCSI_SUBSYSTEM_USBMS, i, grub_usbms_devices[i]->luns, ++ hook_data)) + return 1; + } + +diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c +index a993f07..bcc75ba 100644 +--- a/grub-core/fs/btrfs.c ++++ b/grub-core/fs/btrfs.c +@@ -538,56 +538,71 @@ lower_bound (struct grub_btrfs_data *data, + } + } + +-static grub_device_t +-find_device (struct grub_btrfs_data *data, grub_uint64_t id, int do_rescan) ++/* Context for find_device. */ ++struct find_device_ctx + { +- grub_device_t dev_found = NULL; +- auto int hook (const char *name); +- int hook (const char *name) +- { +- grub_device_t dev; +- grub_err_t err; +- struct grub_btrfs_superblock sb; +- dev = grub_device_open (name); +- if (!dev) ++ struct grub_btrfs_data *data; ++ grub_uint64_t id; ++ grub_device_t dev_found; ++}; ++ ++/* Helper for find_device. */ ++static int ++find_device_iter (const char *name, void *data) ++{ ++ struct find_device_ctx *ctx = data; ++ grub_device_t dev; ++ grub_err_t err; ++ struct grub_btrfs_superblock sb; ++ ++ dev = grub_device_open (name); ++ if (!dev) ++ return 0; ++ if (!dev->disk) ++ { ++ grub_device_close (dev); + return 0; +- if (!dev->disk) +- { +- grub_device_close (dev); +- return 0; +- } +- err = read_sblock (dev->disk, &sb); +- if (err == GRUB_ERR_BAD_FS) +- { +- grub_device_close (dev); +- grub_errno = GRUB_ERR_NONE; +- return 0; +- } +- if (err) +- { +- grub_device_close (dev); +- grub_print_error (); +- return 0; +- } +- if (grub_memcmp (data->sblock.uuid, sb.uuid, sizeof (sb.uuid)) != 0 +- || sb.this_device.device_id != id) +- { +- grub_device_close (dev); +- return 0; +- } ++ } ++ err = read_sblock (dev->disk, &sb); ++ if (err == GRUB_ERR_BAD_FS) ++ { ++ grub_device_close (dev); ++ grub_errno = GRUB_ERR_NONE; ++ return 0; ++ } ++ if (err) ++ { ++ grub_device_close (dev); ++ grub_print_error (); ++ return 0; ++ } ++ if (grub_memcmp (ctx->data->sblock.uuid, sb.uuid, sizeof (sb.uuid)) != 0 ++ || sb.this_device.device_id != ctx->id) ++ { ++ grub_device_close (dev); ++ return 0; ++ } + +- dev_found = dev; +- return 1; +- } ++ ctx->dev_found = dev; ++ return 1; ++} + ++static grub_device_t ++find_device (struct grub_btrfs_data *data, grub_uint64_t id, int do_rescan) ++{ ++ struct find_device_ctx ctx = { ++ .data = data, ++ .id = id, ++ .dev_found = NULL ++ }; + unsigned i; + + for (i = 0; i < data->n_devices_attached; i++) + if (id == data->devices_attached[i].id) + return data->devices_attached[i].dev; + if (do_rescan) +- grub_device_iterate (hook); +- if (!dev_found) ++ grub_device_iterate (find_device_iter, &ctx); ++ if (!ctx.dev_found) + { + grub_error (GRUB_ERR_BAD_FS, + N_("couldn't find a necessary member device " +@@ -605,14 +620,14 @@ find_device (struct grub_btrfs_data *data, grub_uint64_t id, int do_rescan) + * sizeof (data->devices_attached[0])); + if (!data->devices_attached) + { +- grub_device_close (dev_found); ++ grub_device_close (ctx.dev_found); + data->devices_attached = tmp; + return NULL; + } + } + data->devices_attached[data->n_devices_attached - 1].id = id; +- data->devices_attached[data->n_devices_attached - 1].dev = dev_found; +- return dev_found; ++ data->devices_attached[data->n_devices_attached - 1].dev = ctx.dev_found; ++ return ctx.dev_found; + } + + static grub_err_t +diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c +index ba0554a..6ef6db3 100644 +--- a/grub-core/fs/zfs/zfs.c ++++ b/grub-core/fs/zfs/zfs.c +@@ -988,43 +988,47 @@ scan_disk (grub_device_t dev, struct grub_zfs_data *data, + return grub_error (GRUB_ERR_BAD_FS, "couldn't find a valid label"); + } + +-static grub_err_t +-scan_devices (struct grub_zfs_data *data) ++/* Helper for scan_devices. */ ++static int ++scan_devices_iter (const char *name, void *hook_data) + { +- auto int hook (const char *name); +- int hook (const char *name) +- { +- grub_device_t dev; +- grub_err_t err; +- int inserted; +- dev = grub_device_open (name); +- if (!dev) +- return 0; +- if (!dev->disk) +- { +- grub_device_close (dev); +- return 0; +- } +- err = scan_disk (dev, data, 0, &inserted); +- if (err == GRUB_ERR_BAD_FS) +- { +- grub_device_close (dev); +- grub_errno = GRUB_ERR_NONE; +- return 0; +- } +- if (err) +- { +- grub_device_close (dev); +- grub_print_error (); +- return 0; +- } ++ struct grub_zfs_data *data = hook_data; ++ grub_device_t dev; ++ grub_err_t err; ++ int inserted; + +- if (!inserted) +- grub_device_close (dev); +- ++ dev = grub_device_open (name); ++ if (!dev) + return 0; +- } +- grub_device_iterate (hook); ++ if (!dev->disk) ++ { ++ grub_device_close (dev); ++ return 0; ++ } ++ err = scan_disk (dev, data, 0, &inserted); ++ if (err == GRUB_ERR_BAD_FS) ++ { ++ grub_device_close (dev); ++ grub_errno = GRUB_ERR_NONE; ++ return 0; ++ } ++ if (err) ++ { ++ grub_device_close (dev); ++ grub_print_error (); ++ return 0; ++ } ++ ++ if (!inserted) ++ grub_device_close (dev); ++ ++ return 0; ++} ++ ++static grub_err_t ++scan_devices (struct grub_zfs_data *data) ++{ ++ grub_device_iterate (scan_devices_iter, data); + return GRUB_ERR_NONE; + } + +diff --git a/grub-core/kern/corecmd.c b/grub-core/kern/corecmd.c +index 43240e9..3441ccb 100644 +--- a/grub-core/kern/corecmd.c ++++ b/grub-core/kern/corecmd.c +@@ -96,7 +96,7 @@ grub_core_cmd_insmod (struct grub_command *cmd __attribute__ ((unused)), + } + + static int +-grub_mini_print_devices (const char *name) ++grub_mini_print_devices (const char *name, void *data __attribute__ ((unused))) + { + grub_printf ("(%s) ", name); + +@@ -119,7 +119,7 @@ grub_core_cmd_ls (struct grub_command *cmd __attribute__ ((unused)), + { + if (argc < 1) + { +- grub_device_iterate (grub_mini_print_devices); ++ grub_device_iterate (grub_mini_print_devices, NULL); + grub_xputs ("\n"); + grub_refresh (); + } +diff --git a/grub-core/kern/device.c b/grub-core/kern/device.c +index 1261564..73b8ecc 100644 +--- a/grub-core/kern/device.c ++++ b/grub-core/kern/device.c +@@ -85,94 +85,107 @@ grub_device_close (grub_device_t device) + return grub_errno; + } + +-int +-grub_device_iterate (int (*hook) (const char *name)) ++struct part_ent + { +- auto int iterate_disk (const char *disk_name); +- auto int iterate_partition (grub_disk_t disk, +- const grub_partition_t partition); ++ struct part_ent *next; ++ char *name; ++}; + +- struct part_ent +- { +- struct part_ent *next; +- char *name; +- } *ents; ++/* Context for grub_device_iterate. */ ++struct grub_device_iterate_ctx ++{ ++ grub_device_iterate_hook_t hook; ++ void *hook_data; ++ struct part_ent *ents; ++}; ++ ++/* Helper for grub_device_iterate. */ ++static int ++iterate_partition (grub_disk_t disk, const grub_partition_t partition, ++ void *data) ++{ ++ struct grub_device_iterate_ctx *ctx = data; ++ struct part_ent *p; ++ char *part_name; + +- int iterate_disk (const char *disk_name) ++ p = grub_malloc (sizeof (*p)); ++ if (!p) + { +- grub_device_t dev; +- +- if (hook (disk_name)) +- return 1; +- +- dev = grub_device_open (disk_name); +- if (! dev) +- { +- grub_errno = GRUB_ERR_NONE; +- return 0; +- } +- +- if (dev->disk) +- { +- struct part_ent *p; +- int ret = 0; ++ return 1; ++ } + +- ents = NULL; +- (void) grub_partition_iterate (dev->disk, iterate_partition); +- grub_device_close (dev); ++ part_name = grub_partition_get_name (partition); ++ if (!part_name) ++ { ++ grub_free (p); ++ return 1; ++ } ++ p->name = grub_xasprintf ("%s,%s", disk->name, part_name); ++ grub_free (part_name); ++ if (!p->name) ++ { ++ grub_free (p); ++ return 1; ++ } + +- grub_errno = GRUB_ERR_NONE; ++ p->next = ctx->ents; ++ ctx->ents = p; + +- p = ents; +- while (p != NULL) +- { +- struct part_ent *next = p->next; ++ return 0; ++} + +- if (!ret) +- ret = hook (p->name); +- grub_free (p->name); +- grub_free (p); +- p = next; +- } ++/* Helper for grub_device_iterate. */ ++static int ++iterate_disk (const char *disk_name, void *data) ++{ ++ struct grub_device_iterate_ctx *ctx = data; ++ grub_device_t dev; + +- return ret; +- } ++ if (ctx->hook (disk_name, ctx->hook_data)) ++ return 1; + +- grub_device_close (dev); ++ dev = grub_device_open (disk_name); ++ if (! dev) ++ { ++ grub_errno = GRUB_ERR_NONE; + return 0; + } + +- int iterate_partition (grub_disk_t disk, const grub_partition_t partition) ++ if (dev->disk) + { + struct part_ent *p; +- char *part_name; ++ int ret = 0; + +- p = grub_malloc (sizeof (*p)); +- if (!p) +- { +- return 1; +- } ++ ctx->ents = NULL; ++ (void) grub_partition_iterate (dev->disk, iterate_partition, ctx); ++ grub_device_close (dev); + +- part_name = grub_partition_get_name (partition); +- if (!part_name) +- { +- grub_free (p); +- return 1; +- } +- p->name = grub_xasprintf ("%s,%s", disk->name, part_name); +- grub_free (part_name); +- if (!p->name) ++ grub_errno = GRUB_ERR_NONE; ++ ++ p = ctx->ents; ++ while (p != NULL) + { ++ struct part_ent *next = p->next; ++ ++ if (!ret) ++ ret = ctx->hook (p->name, ctx->hook_data); ++ grub_free (p->name); + grub_free (p); +- return 1; ++ p = next; + } + +- p->next = ents; +- ents = p; +- +- return 0; ++ return ret; + } + ++ grub_device_close (dev); ++ return 0; ++} ++ ++int ++grub_device_iterate (grub_device_iterate_hook_t hook, void *hook_data) ++{ ++ struct grub_device_iterate_ctx ctx = { hook, hook_data, NULL }; ++ + /* Only disk devices are supported at the moment. */ +- return grub_disk_dev_iterate (iterate_disk); ++ return grub_disk_dev_iterate (iterate_disk, &ctx); + } +diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c +index ccd2417..92ce1d9 100644 +--- a/grub-core/kern/emu/hostdisk.c ++++ b/grub-core/kern/emu/hostdisk.c +@@ -223,7 +223,7 @@ find_free_slot (void) + } + + static int +-grub_util_biosdisk_iterate (int (*hook) (const char *name), ++grub_util_biosdisk_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data, + grub_disk_pull_t pull) + { + unsigned i; +@@ -232,7 +232,7 @@ grub_util_biosdisk_iterate (int (*hook) (const char *name), + return 0; + + for (i = 0; i < sizeof (map) / sizeof (map[0]); i++) +- if (map[i].drive && hook (map[i].drive)) ++ if (map[i].drive && hook (map[i].drive, hook_data)) + return 1; + + return 0; +diff --git a/grub-core/kern/mips/arc/init.c b/grub-core/kern/mips/arc/init.c +index 4d680ed..f63ac6d 100644 +--- a/grub-core/kern/mips/arc/init.c ++++ b/grub-core/kern/mips/arc/init.c +@@ -48,8 +48,7 @@ const char *type_names[] = { + + static int + iterate_rec (const char *prefix, const struct grub_arc_component *parent, +- int (*hook) (const char *name, +- const struct grub_arc_component *comp), ++ grub_arc_iterate_devs_hook_t hook, void *hook_data, + int alt_names) + { + const struct grub_arc_component *comp; +@@ -67,12 +66,13 @@ iterate_rec (const char *prefix, const struct grub_arc_component *parent, + name = grub_xasprintf ("%s%s(%lu)", prefix, cname, comp->key); + if (!name) + return 1; +- if (hook (name, comp)) ++ if (hook (name, comp, hook_data)) + { + grub_free (name); + return 1; + } +- if (iterate_rec ((parent ? name : prefix), comp, hook, alt_names)) ++ if (iterate_rec ((parent ? name : prefix), comp, hook, hook_data, ++ alt_names)) + { + grub_free (name); + return 1; +@@ -83,11 +83,11 @@ iterate_rec (const char *prefix, const struct grub_arc_component *parent, + } + + int +-grub_arc_iterate_devs (int (*hook) (const char *name, +- const struct grub_arc_component *comp), ++grub_arc_iterate_devs (grub_arc_iterate_devs_hook_t hook, void *hook_data, + int alt_names) + { +- return iterate_rec ((alt_names ? "arc" : ""), NULL, hook, alt_names); ++ return iterate_rec ((alt_names ? "arc" : ""), NULL, hook, hook_data, ++ alt_names); + } + + grub_err_t +diff --git a/grub-core/kern/partition.c b/grub-core/kern/partition.c +index 82ae9c8..e499147 100644 +--- a/grub-core/kern/partition.c ++++ b/grub-core/kern/partition.c +@@ -59,39 +59,50 @@ grub_partition_check_containment (const grub_disk_t disk, + return 1; + } + +-static grub_partition_t +-grub_partition_map_probe (const grub_partition_map_t partmap, +- grub_disk_t disk, int partnum) ++/* Context for grub_partition_map_probe. */ ++struct grub_partition_map_probe_ctx + { +- grub_partition_t p = 0; ++ int partnum; ++ grub_partition_t p; ++}; + +- auto int find_func (grub_disk_t d, const grub_partition_t partition); ++/* Helper for grub_partition_map_probe. */ ++static int ++probe_iter (grub_disk_t dsk, const grub_partition_t partition, void *data) ++{ ++ struct grub_partition_map_probe_ctx *ctx = data; + +- int find_func (grub_disk_t dsk, +- const grub_partition_t partition) +- { +- if (partnum != partition->number) +- return 0; ++ if (ctx->partnum != partition->number) ++ return 0; + +- if (!(grub_partition_check_containment (dsk, partition))) +- return 0; ++ if (!(grub_partition_check_containment (dsk, partition))) ++ return 0; + +- p = (grub_partition_t) grub_malloc (sizeof (*p)); +- if (! p) +- return 1; ++ ctx->p = (grub_partition_t) grub_malloc (sizeof (*ctx->p)); ++ if (! ctx->p) ++ return 1; + +- grub_memcpy (p, partition, sizeof (*p)); +- return 1; +- } ++ grub_memcpy (ctx->p, partition, sizeof (*ctx->p)); ++ return 1; ++} + +- partmap->iterate (disk, find_func); ++static grub_partition_t ++grub_partition_map_probe (const grub_partition_map_t partmap, ++ grub_disk_t disk, int partnum) ++{ ++ struct grub_partition_map_probe_ctx ctx = { ++ .partnum = partnum, ++ .p = 0 ++ }; ++ ++ partmap->iterate (disk, probe_iter, &ctx); + if (grub_errno) + goto fail; + +- return p; ++ return ctx.p; + + fail: +- grub_free (p); ++ grub_free (ctx.p); + return 0; + } + +@@ -162,62 +173,71 @@ grub_partition_probe (struct grub_disk *disk, const char *str) + return part; + } + +-int +-grub_partition_iterate (struct grub_disk *disk, +- int (*hook) (grub_disk_t disk, +- const grub_partition_t partition)) ++/* Context for grub_partition_iterate. */ ++struct grub_partition_iterate_ctx + { +- int ret = 0; +- +- auto int part_iterate (grub_disk_t dsk, const grub_partition_t p); ++ int ret; ++ grub_partition_iterate_hook_t hook; ++ void *hook_data; ++}; + +- int part_iterate (grub_disk_t dsk, +- const grub_partition_t partition) +- { +- struct grub_partition p = *partition; ++/* Helper for grub_partition_iterate. */ ++static int ++part_iterate (grub_disk_t dsk, const grub_partition_t partition, void *data) ++{ ++ struct grub_partition_iterate_ctx *ctx = data; ++ struct grub_partition p = *partition; + +- if (!(grub_partition_check_containment (dsk, partition))) +- return 0; ++ if (!(grub_partition_check_containment (dsk, partition))) ++ return 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; +- 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; ++ p.parent = dsk->partition; ++ dsk->partition = 0; ++ if (ctx->hook (dsk, &p, ctx->hook_data)) ++ { ++ ctx->ret = 1; ++ return 1; + } +- +- { +- const struct grub_partition_map *partmap; +- FOR_PARTITION_MAPS(partmap) ++ if (p.start != 0) + { +- grub_err_t err; +- err = partmap->iterate (disk, part_iterate); +- if (err) +- grub_errno = GRUB_ERR_NONE; +- if (ret) +- break; ++ const struct grub_partition_map *partmap; ++ dsk->partition = &p; ++ FOR_PARTITION_MAPS(partmap) ++ { ++ grub_err_t err; ++ err = partmap->iterate (dsk, part_iterate, ctx); ++ if (err) ++ grub_errno = GRUB_ERR_NONE; ++ if (ctx->ret) ++ break; ++ } + } ++ dsk->partition = p.parent; ++ return ctx->ret; ++} ++ ++int ++grub_partition_iterate (struct grub_disk *disk, ++ grub_partition_iterate_hook_t hook, void *hook_data) ++{ ++ struct grub_partition_iterate_ctx ctx = { ++ .ret = 0, ++ .hook = hook, ++ .hook_data = hook_data ++ }; ++ const struct grub_partition_map *partmap; ++ ++ FOR_PARTITION_MAPS(partmap) ++ { ++ grub_err_t err; ++ err = partmap->iterate (disk, part_iterate, &ctx); ++ if (err) ++ grub_errno = GRUB_ERR_NONE; ++ if (ctx.ret) ++ break; + } + +- return ret; ++ return ctx.ret; + } + + char * +diff --git a/grub-core/loader/i386/pc/plan9.c b/grub-core/loader/i386/pc/plan9.c +index b41dfd2..7dc12a8 100644 +--- a/grub-core/loader/i386/pc/plan9.c ++++ b/grub-core/loader/i386/pc/plan9.c +@@ -102,248 +102,281 @@ grub_plan9_unload (void) + return GRUB_ERR_NONE; + } + +-static grub_err_t +-grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[]) ++/* Context for grub_cmd_plan9. */ ++struct grub_cmd_plan9_ctx + { +- grub_file_t file = 0; +- void *mem; +- grub_size_t memsize, padsize; +- struct grub_plan9_header hdr; +- char *config, *configptr; +- grub_size_t configsize; +- char *pmap = NULL; +- grub_size_t pmapalloc = 256; +- grub_size_t pmapptr = 0; +- int noslash = 1; +- char prefixes[5][10] = {"dos", "plan9", "ntfs", "linux", "linuxswap"}; ++ grub_extcmd_context_t ctxt; ++ grub_file_t file; ++ char *pmap; ++ grub_size_t pmapalloc; ++ grub_size_t pmapptr; ++ int noslash; + int prefixescnt[5]; +- char *bootdisk = NULL, *bootpart = NULL, *bootpath = NULL; ++ char *bootdisk, *bootpart; ++}; + +- auto int fill_partition (grub_disk_t disk, +- const grub_partition_t partition); +- int fill_partition (grub_disk_t disk, +- const grub_partition_t partition) +- { +- int file_disk = 0; +- int pstart, pend; +- if (!noslash) +- { +- if (grub_extend_alloc (pmapptr + 1, &pmapalloc, (void **) &pmap)) +- return 1; +- pmap[pmapptr++] = '/'; +- } +- noslash = 0; ++static const char prefixes[5][10] = { ++ "dos", "plan9", "ntfs", "linux", "linuxswap" ++}; + +- file_disk = file->device->disk && disk->id == file->device->disk->id +- && disk->dev->id == file->device->disk->dev->id; ++/* Helper for grub_cmd_plan9. */ ++static int ++fill_partition (grub_disk_t disk, const grub_partition_t partition, void *data) ++{ ++ struct grub_cmd_plan9_ctx *fill_ctx = data; ++ int file_disk = 0; ++ int pstart, pend; + +- pstart = pmapptr; +- if (grub_strcmp (partition->partmap->name, "plan") == 0) +- { +- unsigned ptr = partition->index + sizeof ("part ") - 1; +- grub_err_t err; +- disk->partition = partition->parent; +- do +- { +- if (grub_extend_alloc (pmapptr + 1, &pmapalloc, (void **) &pmap)) +- return 1; +- err = grub_disk_read (disk, 1, ptr, 1, pmap + pmapptr); +- if (err) +- { +- disk->partition = 0; +- return err; +- } +- ptr++; +- pmapptr++; +- } +- while (grub_isalpha (pmap[pmapptr - 1]) +- || grub_isdigit (pmap[pmapptr - 1])); +- pmapptr--; +- } +- else +- { +- char name[50]; +- int c = 0; +- if (grub_strcmp (partition->partmap->name, "msdos") == 0) +- { +- switch (partition->msdostype) +- { +- case GRUB_PC_PARTITION_TYPE_PLAN9: +- c = 1; +- break; +- case GRUB_PC_PARTITION_TYPE_NTFS: +- c = 2; +- break; +- case GRUB_PC_PARTITION_TYPE_MINIX: +- case GRUB_PC_PARTITION_TYPE_LINUX_MINIX: +- case GRUB_PC_PARTITION_TYPE_EXT2FS: +- c = 3; +- break; +- case GRUB_PC_PARTITION_TYPE_LINUX_SWAP: +- c = 4; +- break; +- } +- } ++ if (!fill_ctx->noslash) ++ { ++ if (grub_extend_alloc (fill_ctx->pmapptr + 1, &fill_ctx->pmapalloc, ++ (void **) &fill_ctx->pmap)) ++ return 1; ++ fill_ctx->pmap[fill_ctx->pmapptr++] = '/'; ++ } ++ fill_ctx->noslash = 0; + +- if (prefixescnt[c] == 0) +- grub_strcpy (name, prefixes[c]); +- else +- grub_snprintf (name, sizeof (name), "%s.%d", prefixes[c], +- prefixescnt[c]); +- prefixescnt[c]++; +- if (grub_extend_alloc (pmapptr + grub_strlen (name) + 1, +- &pmapalloc, (void **) &pmap)) +- return 1; +- grub_strcpy (pmap + pmapptr, name); +- pmapptr += grub_strlen (name); +- } +- pend = pmapptr; +- if (grub_extend_alloc (pmapptr + 2 + 25 + 5 + 25, &pmapalloc, +- (void **) &pmap)) +- return 1; +- pmap[pmapptr++] = ' '; +- grub_snprintf (pmap + pmapptr, 25 + 5 + 25, +- "%" PRIuGRUB_UINT64_T " %" PRIuGRUB_UINT64_T, +- grub_partition_get_start (partition), +- grub_partition_get_start (partition) +- + grub_partition_get_len (partition)); +- if (file_disk && grub_partition_get_start (partition) +- == grub_partition_get_start (file->device->disk->partition) +- && grub_partition_get_len (partition) +- == grub_partition_get_len (file->device->disk->partition)) +- { +- grub_free (bootpart); +- bootpart = grub_strndup (pmap + pstart, pend - pstart); +- } ++ file_disk = fill_ctx->file->device->disk ++ && disk->id == fill_ctx->file->device->disk->id ++ && disk->dev->id == fill_ctx->file->device->disk->dev->id; + +- pmapptr += grub_strlen (pmap + pmapptr); +- return 0; +- } ++ pstart = fill_ctx->pmapptr; ++ if (grub_strcmp (partition->partmap->name, "plan") == 0) ++ { ++ unsigned ptr = partition->index + sizeof ("part ") - 1; ++ grub_err_t err; ++ disk->partition = partition->parent; ++ do ++ { ++ if (grub_extend_alloc (fill_ctx->pmapptr + 1, &fill_ctx->pmapalloc, ++ (void **) &fill_ctx->pmap)) ++ return 1; ++ err = grub_disk_read (disk, 1, ptr, 1, ++ fill_ctx->pmap + fill_ctx->pmapptr); ++ if (err) ++ { ++ disk->partition = 0; ++ return err; ++ } ++ ptr++; ++ fill_ctx->pmapptr++; ++ } ++ while (grub_isalpha (fill_ctx->pmap[fill_ctx->pmapptr - 1]) ++ || grub_isdigit (fill_ctx->pmap[fill_ctx->pmapptr - 1])); ++ fill_ctx->pmapptr--; ++ } ++ else ++ { ++ char name[50]; ++ int c = 0; ++ if (grub_strcmp (partition->partmap->name, "msdos") == 0) ++ { ++ switch (partition->msdostype) ++ { ++ case GRUB_PC_PARTITION_TYPE_PLAN9: ++ c = 1; ++ break; ++ case GRUB_PC_PARTITION_TYPE_NTFS: ++ c = 2; ++ break; ++ case GRUB_PC_PARTITION_TYPE_MINIX: ++ case GRUB_PC_PARTITION_TYPE_LINUX_MINIX: ++ case GRUB_PC_PARTITION_TYPE_EXT2FS: ++ c = 3; ++ break; ++ case GRUB_PC_PARTITION_TYPE_LINUX_SWAP: ++ c = 4; ++ break; ++ } ++ } + +- auto int fill_disk (const char *name); +- int fill_disk (const char *name) +- { +- grub_device_t dev; +- char *plan9name = NULL; +- unsigned i; +- int file_disk = 0; ++ if (fill_ctx->prefixescnt[c] == 0) ++ grub_strcpy (name, prefixes[c]); ++ else ++ grub_snprintf (name, sizeof (name), "%s.%d", prefixes[c], ++ fill_ctx->prefixescnt[c]); ++ fill_ctx->prefixescnt[c]++; ++ if (grub_extend_alloc (fill_ctx->pmapptr + grub_strlen (name) + 1, ++ &fill_ctx->pmapalloc, (void **) &fill_ctx->pmap)) ++ return 1; ++ grub_strcpy (fill_ctx->pmap + fill_ctx->pmapptr, name); ++ fill_ctx->pmapptr += grub_strlen (name); ++ } ++ pend = fill_ctx->pmapptr; ++ if (grub_extend_alloc (fill_ctx->pmapptr + 2 + 25 + 5 + 25, ++ &fill_ctx->pmapalloc, (void **) &fill_ctx->pmap)) ++ return 1; ++ fill_ctx->pmap[fill_ctx->pmapptr++] = ' '; ++ grub_snprintf (fill_ctx->pmap + fill_ctx->pmapptr, 25 + 5 + 25, ++ "%" PRIuGRUB_UINT64_T " %" PRIuGRUB_UINT64_T, ++ grub_partition_get_start (partition), ++ grub_partition_get_start (partition) ++ + grub_partition_get_len (partition)); ++ if (file_disk && grub_partition_get_start (partition) ++ == grub_partition_get_start (fill_ctx->file->device->disk->partition) ++ && grub_partition_get_len (partition) ++ == grub_partition_get_len (fill_ctx->file->device->disk->partition)) ++ { ++ grub_free (fill_ctx->bootpart); ++ fill_ctx->bootpart = grub_strndup (fill_ctx->pmap + pstart, ++ pend - pstart); ++ } + +- dev = grub_device_open (name); +- if (!dev) +- { +- grub_print_error (); +- return 0; +- } +- if (!dev->disk) ++ fill_ctx->pmapptr += grub_strlen (fill_ctx->pmap + fill_ctx->pmapptr); ++ return 0; ++} ++ ++/* Helper for grub_cmd_plan9. */ ++static int ++fill_disk (const char *name, void *data) ++{ ++ struct grub_cmd_plan9_ctx *fill_ctx = data; ++ grub_device_t dev; ++ char *plan9name = NULL; ++ unsigned i; ++ int file_disk = 0; ++ ++ dev = grub_device_open (name); ++ if (!dev) ++ { ++ grub_print_error (); ++ return 0; ++ } ++ if (!dev->disk) ++ { ++ grub_device_close (dev); ++ return 0; ++ } ++ file_disk = fill_ctx->file->device->disk ++ && dev->disk->id == fill_ctx->file->device->disk->id ++ && dev->disk->dev->id == fill_ctx->file->device->disk->dev->id; ++ for (i = 0; ++ fill_ctx->ctxt->state[0].args && fill_ctx->ctxt->state[0].args[i]; i++) ++ if (grub_strncmp (name, fill_ctx->ctxt->state[0].args[i], ++ grub_strlen (name)) == 0 ++ && fill_ctx->ctxt->state[0].args[i][grub_strlen (name)] == '=') ++ break; ++ if (fill_ctx->ctxt->state[0].args && fill_ctx->ctxt->state[0].args[i]) ++ plan9name = grub_strdup (fill_ctx->ctxt->state[0].args[i] ++ + grub_strlen (name) + 1); ++ else ++ switch (dev->disk->dev->id) + { +- grub_device_close (dev); +- return 0; +- } +- file_disk = file->device->disk && dev->disk->id == file->device->disk->id +- && dev->disk->dev->id == file->device->disk->dev->id; +- for (i = 0; ctxt->state[0].args && ctxt->state[0].args[i]; i++) +- if (grub_strncmp (name, ctxt->state[0].args[i], grub_strlen (name)) == 0 +- && ctxt->state[0].args[i][grub_strlen (name)] == '=') ++ case GRUB_DISK_DEVICE_BIOSDISK_ID: ++ if (dev->disk->id & 0x80) ++ plan9name = grub_xasprintf ("sdB%u", ++ (unsigned) (dev->disk->id & 0x7f)); ++ else ++ plan9name = grub_xasprintf ("fd%u", ++ (unsigned) (dev->disk->id & 0x7f)); + break; +- if (ctxt->state[0].args && ctxt->state[0].args[i]) +- plan9name = grub_strdup (ctxt->state[0].args[i] + grub_strlen (name) + 1); +- else +- switch (dev->disk->dev->id) ++ /* Shouldn't happen as Plan9 doesn't work on these platforms. */ ++ case GRUB_DISK_DEVICE_OFDISK_ID: ++ case GRUB_DISK_DEVICE_EFIDISK_ID: ++ ++ /* Plan9 doesn't see those. */ ++ default: ++ ++ /* Not sure how to handle those. */ ++ case GRUB_DISK_DEVICE_NAND_ID: ++ if (!file_disk) ++ { ++ grub_device_close (dev); ++ return 0; ++ } ++ ++ /* if it's the disk the kernel is loaded from we need to name ++ it nevertheless. */ ++ plan9name = grub_strdup ("sdZ0"); ++ break; ++ ++ case GRUB_DISK_DEVICE_ATA_ID: + { +- case GRUB_DISK_DEVICE_BIOSDISK_ID: +- if (dev->disk->id & 0x80) +- plan9name = grub_xasprintf ("sdB%u", +- (unsigned) (dev->disk->id & 0x7f)); ++ int unit; ++ if (grub_strlen (dev->disk->name) < sizeof ("ata0") - 1) ++ unit = 0; + else +- plan9name = grub_xasprintf ("fd%u", +- (unsigned) (dev->disk->id & 0x7f)); +- break; +- /* Shouldn't happen as Plan9 doesn't work on these platforms. */ +- case GRUB_DISK_DEVICE_OFDISK_ID: +- case GRUB_DISK_DEVICE_EFIDISK_ID: +- +- /* Plan9 doesn't see those. */ +- default: +- +- /* Not sure how to handle those. */ +- case GRUB_DISK_DEVICE_NAND_ID: +- if (!file_disk) +- { +- grub_device_close (dev); +- return 0; +- } +- +- /* if it's the disk the kernel is loaded from we need to name +- it nevertheless. */ +- plan9name = grub_strdup ("sdZ0"); +- break; +- +- case GRUB_DISK_DEVICE_ATA_ID: ++ unit = grub_strtoul (dev->disk->name + sizeof ("ata0") - 1, 0, 0); ++ plan9name = grub_xasprintf ("sd%c%d", 'C' + unit / 2, unit % 2); ++ } ++ break; ++ case GRUB_DISK_DEVICE_SCSI_ID: ++ if (((dev->disk->id >> GRUB_SCSI_ID_SUBSYSTEM_SHIFT) & 0xff) ++ == GRUB_SCSI_SUBSYSTEM_PATA) + { + int unit; + if (grub_strlen (dev->disk->name) < sizeof ("ata0") - 1) + unit = 0; + else +- unit = grub_strtoul (dev->disk->name + sizeof ("ata0") - 1, 0, 0); ++ unit = grub_strtoul (dev->disk->name + sizeof ("ata0") - 1, ++ 0, 0); + plan9name = grub_xasprintf ("sd%c%d", 'C' + unit / 2, unit % 2); ++ break; + } +- break; +- case GRUB_DISK_DEVICE_SCSI_ID: +- if (((dev->disk->id >> GRUB_SCSI_ID_SUBSYSTEM_SHIFT) & 0xff) +- == GRUB_SCSI_SUBSYSTEM_PATA) +- { +- int unit; +- if (grub_strlen (dev->disk->name) < sizeof ("ata0") - 1) +- unit = 0; +- else +- unit = grub_strtoul (dev->disk->name + sizeof ("ata0") - 1, +- 0, 0); +- plan9name = grub_xasprintf ("sd%c%d", 'C' + unit / 2, unit % 2); +- break; +- } +- +- /* FIXME: how does Plan9 number controllers? +- We probably need save the SCSI devices and sort them */ +- plan9name +- = grub_xasprintf ("sd0%u", (unsigned) +- ((dev->disk->id >> GRUB_SCSI_ID_BUS_SHIFT) +- & 0xf)); +- break; +- } +- if (!plan9name) +- { +- grub_print_error (); +- return 0; +- } +- if (grub_extend_alloc (pmapptr + grub_strlen (plan9name) +- + sizeof ("part="), &pmapalloc, +- (void **) &pmap)) +- { +- grub_free (plan9name); +- return 1; ++ ++ /* FIXME: how does Plan9 number controllers? ++ We probably need save the SCSI devices and sort them */ ++ plan9name ++ = grub_xasprintf ("sd0%u", (unsigned) ++ ((dev->disk->id >> GRUB_SCSI_ID_BUS_SHIFT) ++ & 0xf)); ++ break; + } +- grub_strcpy (pmap + pmapptr, plan9name); +- pmapptr += grub_strlen (plan9name); +- if (!file_disk) ++ if (!plan9name) ++ { ++ grub_print_error (); ++ return 0; ++ } ++ if (grub_extend_alloc (fill_ctx->pmapptr + grub_strlen (plan9name) ++ + sizeof ("part="), &fill_ctx->pmapalloc, ++ (void **) &fill_ctx->pmap)) ++ { + grub_free (plan9name); +- else +- { +- grub_free (bootdisk); +- bootdisk = plan9name; +- } +- grub_strcpy (pmap + pmapptr, "part="); +- pmapptr += sizeof ("part=") - 1; +- +- noslash = 1; +- grub_memset (prefixescnt, 0, sizeof (prefixescnt)); +- if (grub_partition_iterate (dev->disk, fill_partition)) +- return 1; +- if (grub_extend_alloc (pmapptr + 1, &pmapalloc, (void **) &pmap)) + return 1; +- pmap[pmapptr++] = '\n'; ++ } ++ grub_strcpy (fill_ctx->pmap + fill_ctx->pmapptr, plan9name); ++ fill_ctx->pmapptr += grub_strlen (plan9name); ++ if (!file_disk) ++ grub_free (plan9name); ++ else ++ { ++ grub_free (fill_ctx->bootdisk); ++ fill_ctx->bootdisk = plan9name; ++ } ++ grub_strcpy (fill_ctx->pmap + fill_ctx->pmapptr, "part="); ++ fill_ctx->pmapptr += sizeof ("part=") - 1; ++ ++ fill_ctx->noslash = 1; ++ grub_memset (fill_ctx->prefixescnt, 0, sizeof (fill_ctx->prefixescnt)); ++ if (grub_partition_iterate (dev->disk, fill_partition, fill_ctx)) ++ return 1; ++ if (grub_extend_alloc (fill_ctx->pmapptr + 1, &fill_ctx->pmapalloc, ++ (void **) &fill_ctx->pmap)) ++ return 1; ++ fill_ctx->pmap[fill_ctx->pmapptr++] = '\n'; ++ ++ return 0; ++} + +- return 0; +- } ++static grub_err_t ++grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[]) ++{ ++ struct grub_cmd_plan9_ctx fill_ctx = { ++ .ctxt = ctxt, ++ .file = 0, ++ .pmap = NULL, ++ .pmapalloc = 256, ++ .pmapptr = 0, ++ .noslash = 1, ++ .bootdisk = NULL, ++ .bootpart = NULL ++ }; ++ void *mem; ++ grub_size_t memsize, padsize; ++ struct grub_plan9_header hdr; ++ char *config, *configptr; ++ grub_size_t configsize; ++ char *bootpath = NULL; + + if (argc == 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); +@@ -354,21 +387,21 @@ grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[]) + if (!rel) + goto fail; + +- file = grub_file_open (argv[0]); +- if (! file) ++ fill_ctx.file = grub_file_open (argv[0]); ++ if (! fill_ctx.file) + goto fail; + +- pmap = grub_malloc (pmapalloc); +- if (!pmap) ++ fill_ctx.pmap = grub_malloc (fill_ctx.pmapalloc); ++ if (!fill_ctx.pmap) + goto fail; + +- if (grub_disk_dev_iterate (fill_disk)) ++ if (grub_disk_dev_iterate (fill_disk, &fill_ctx)) + goto fail; + +- if (grub_extend_alloc (pmapptr + 1, &pmapalloc, +- (void **) &pmap)) ++ if (grub_extend_alloc (fill_ctx.pmapptr + 1, &fill_ctx.pmapalloc, ++ (void **) &fill_ctx.pmap)) + goto fail; +- pmap[pmapptr] = 0; ++ fill_ctx.pmap[fill_ctx.pmapptr] = 0; + + { + char *file_name = grub_strchr (argv[0], ')'); +@@ -379,17 +412,19 @@ grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[]) + if (*file_name) + file_name++; + +- if (bootpart) +- bootpath = grub_xasprintf ("%s!%s!%s", bootdisk, bootpart, file_name); ++ if (fill_ctx.bootpart) ++ bootpath = grub_xasprintf ("%s!%s!%s", fill_ctx.bootdisk, ++ fill_ctx.bootpart, file_name); + else +- bootpath = grub_xasprintf ("%s!%s", bootdisk, file_name); +- grub_free (bootdisk); +- grub_free (bootpart); ++ bootpath = grub_xasprintf ("%s!%s", fill_ctx.bootdisk, file_name); ++ grub_free (fill_ctx.bootdisk); ++ grub_free (fill_ctx.bootpart); + } + if (!bootpath) + goto fail; + +- if (grub_file_read (file, &hdr, sizeof (hdr)) != (grub_ssize_t) sizeof (hdr)) ++ if (grub_file_read (fill_ctx.file, &hdr, ++ sizeof (hdr)) != (grub_ssize_t) sizeof (hdr)) + { + if (!grub_errno) + grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), +@@ -420,7 +455,7 @@ grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[]) + configsize += grub_strlen (argv[i]) + 1; + } + configsize += (sizeof ("bootfile=") - 1) + grub_strlen (bootpath) + 1; +- configsize += pmapptr; ++ configsize += fill_ctx.pmapptr; + /* Terminating \0. */ + configsize++; + +@@ -452,7 +487,7 @@ grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[]) + *configptr++ = '\n'; + } + } +- configptr = grub_stpcpy (configptr, pmap); ++ configptr = grub_stpcpy (configptr, fill_ctx.pmap); + + { + grub_relocator_chunk_t ch; +@@ -471,7 +506,7 @@ grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[]) + grub_memcpy (ptr, &hdr, sizeof (hdr)); + ptr += sizeof (hdr); + +- if (grub_file_read (file, ptr, grub_be_to_cpu32 (hdr.text_size)) ++ if (grub_file_read (fill_ctx.file, ptr, grub_be_to_cpu32 (hdr.text_size)) + != (grub_ssize_t) grub_be_to_cpu32 (hdr.text_size)) + { + if (!grub_errno) +@@ -487,7 +522,7 @@ grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[]) + grub_memset (ptr, 0, padsize); + ptr += padsize; + +- if (grub_file_read (file, ptr, grub_be_to_cpu32 (hdr.data_size)) ++ if (grub_file_read (fill_ctx.file, ptr, grub_be_to_cpu32 (hdr.data_size)) + != (grub_ssize_t) grub_be_to_cpu32 (hdr.data_size)) + { + if (!grub_errno) +@@ -508,10 +543,10 @@ grub_cmd_plan9 (grub_extcmd_context_t ctxt, int argc, char *argv[]) + return GRUB_ERR_NONE; + + fail: +- grub_free (pmap); ++ grub_free (fill_ctx.pmap); + +- if (file) +- grub_file_close (file); ++ if (fill_ctx.file) ++ grub_file_close (fill_ctx.file); + + grub_plan9_unload (); + +diff --git a/grub-core/normal/completion.c b/grub-core/normal/completion.c +index 805f002..367a2b7 100644 +--- a/grub-core/normal/completion.c ++++ b/grub-core/normal/completion.c +@@ -99,7 +99,8 @@ add_completion (const char *completion, const char *extra, + } + + static int +-iterate_partition (grub_disk_t disk, const grub_partition_t p) ++iterate_partition (grub_disk_t disk, const grub_partition_t p, ++ void *data __attribute__ ((unused))) + { + const char *disk_name = disk->name; + char *name; +@@ -154,7 +155,7 @@ iterate_dir (const char *filename, const struct grub_dirhook_info *info) + } + + static int +-iterate_dev (const char *devname) ++iterate_dev (const char *devname, void *data __attribute__ ((unused))) + { + grub_device_t dev; + +@@ -180,7 +181,7 @@ iterate_dev (const char *devname) + } + + if (dev->disk) +- if (grub_partition_iterate (dev->disk, iterate_partition)) ++ if (grub_partition_iterate (dev->disk, iterate_partition, NULL)) + { + grub_device_close (dev); + return 1; +@@ -213,7 +214,7 @@ complete_device (void) + if (! p) + { + /* Complete the disk part. */ +- if (grub_disk_dev_iterate (iterate_dev)) ++ if (grub_disk_dev_iterate (iterate_dev, NULL)) + return 1; + } + else +@@ -228,7 +229,7 @@ complete_device (void) + { + if (dev->disk) + { +- if (grub_partition_iterate (dev->disk, iterate_partition)) ++ if (grub_partition_iterate (dev->disk, iterate_partition, NULL)) + { + grub_device_close (dev); + return 1; +diff --git a/grub-core/partmap/acorn.c b/grub-core/partmap/acorn.c +index 341b8ac..4d7f500 100644 +--- a/grub-core/partmap/acorn.c ++++ b/grub-core/partmap/acorn.c +@@ -101,8 +101,8 @@ fail: + + static grub_err_t + acorn_partition_map_iterate (grub_disk_t disk, +- int (*hook) (grub_disk_t disk, +- const grub_partition_t partition)) ++ grub_partition_iterate_hook_t hook, ++ void *hook_data) + { + struct grub_partition part; + struct linux_part map[LINUX_MAP_ENTRIES]; +@@ -127,7 +127,7 @@ acorn_partition_map_iterate (grub_disk_t disk, + part.offset = 6; + part.number = part.index = i; + +- if (hook (disk, &part)) ++ if (hook (disk, &part, hook_data)) + return grub_errno; + } + +diff --git a/grub-core/partmap/amiga.c b/grub-core/partmap/amiga.c +index 0b89cdc..213d707 100644 +--- a/grub-core/partmap/amiga.c ++++ b/grub-core/partmap/amiga.c +@@ -87,8 +87,8 @@ amiga_partition_map_checksum (void *buf, grub_size_t sz) + + static grub_err_t + amiga_partition_map_iterate (grub_disk_t disk, +- int (*hook) (grub_disk_t disk, +- const grub_partition_t partition)) ++ grub_partition_iterate_hook_t hook, ++ void *hook_data) + { + struct grub_partition part; + struct grub_amiga_rdsk rdsk; +@@ -145,7 +145,7 @@ amiga_partition_map_iterate (grub_disk_t disk, + part.index = 0; + part.partmap = &grub_amiga_partition_map; + +- if (hook (disk, &part)) ++ if (hook (disk, &part, hook_data)) + return grub_errno; + + next = grub_be_to_cpu32 (apart.next); +diff --git a/grub-core/partmap/apple.c b/grub-core/partmap/apple.c +index c08cae5..f4e608f 100644 +--- a/grub-core/partmap/apple.c ++++ b/grub-core/partmap/apple.c +@@ -101,8 +101,8 @@ static struct grub_partition_map grub_apple_partition_map; + + static grub_err_t + apple_partition_map_iterate (grub_disk_t disk, +- int (*hook) (grub_disk_t disk, +- const grub_partition_t partition)) ++ grub_partition_iterate_hook_t hook, ++ void *hook_data) + { + struct grub_partition part; + struct grub_apple_header aheader; +@@ -163,7 +163,7 @@ apple_partition_map_iterate (grub_disk_t disk, + grub_be_to_cpu32 (apart.first_phys_block), + grub_be_to_cpu32 (apart.blockcnt)); + +- if (hook (disk, &part)) ++ if (hook (disk, &part, hook_data)) + return grub_errno; + + pos += grub_be_to_cpu16 (aheader.blocksize); +diff --git a/grub-core/partmap/bsdlabel.c b/grub-core/partmap/bsdlabel.c +index c806f19..16b9c87 100644 +--- a/grub-core/partmap/bsdlabel.c ++++ b/grub-core/partmap/bsdlabel.c +@@ -41,8 +41,7 @@ static struct grub_partition_map grub_openbsdlabel_partition_map; + static grub_err_t + iterate_real (grub_disk_t disk, grub_disk_addr_t sector, int freebsd, + struct grub_partition_map *pmap, +- int (*hook) (grub_disk_t disk, +- const grub_partition_t partition)) ++ grub_partition_iterate_hook_t hook, void *hook_data) + { + struct grub_partition_bsd_disk_label label; + struct grub_partition p; +@@ -116,7 +115,7 @@ iterate_real (grub_disk_t disk, grub_disk_addr_t sector, int freebsd, + + p.start -= delta; + +- if (hook (disk, &p)) ++ if (hook (disk, &p, hook_data)) + return grub_errno; + } + return GRUB_ERR_NONE; +@@ -124,14 +123,14 @@ iterate_real (grub_disk_t disk, grub_disk_addr_t sector, int freebsd, + + static grub_err_t + bsdlabel_partition_map_iterate (grub_disk_t disk, +- int (*hook) (grub_disk_t disk, +- const grub_partition_t partition)) ++ grub_partition_iterate_hook_t hook, ++ void *hook_data) + { + + if (disk->partition && grub_strcmp (disk->partition->partmap->name, "msdos") + == 0 && disk->partition->msdostype == GRUB_PC_PARTITION_TYPE_FREEBSD) + return iterate_real (disk, GRUB_PC_PARTITION_BSD_LABEL_SECTOR, 1, +- &grub_bsdlabel_partition_map, hook); ++ &grub_bsdlabel_partition_map, hook, hook_data); + + if (disk->partition + && (grub_strcmp (disk->partition->partmap->name, "msdos") == 0 +@@ -141,7 +140,44 @@ bsdlabel_partition_map_iterate (grub_disk_t disk, + return grub_error (GRUB_ERR_BAD_PART_TABLE, "no embedding supported"); + + return iterate_real (disk, GRUB_PC_PARTITION_BSD_LABEL_SECTOR, 0, +- &grub_bsdlabel_partition_map, hook); ++ &grub_bsdlabel_partition_map, hook, hook_data); ++} ++ ++/* Context for netopenbsdlabel_partition_map_iterate. */ ++struct netopenbsdlabel_ctx ++{ ++ grub_uint8_t type; ++ struct grub_partition_map *pmap; ++ grub_partition_iterate_hook_t hook; ++ void *hook_data; ++ int count; ++}; ++ ++/* Helper for netopenbsdlabel_partition_map_iterate. */ ++static int ++check_msdos (grub_disk_t dsk, const grub_partition_t partition, void *data) ++{ ++ struct netopenbsdlabel_ctx *ctx = data; ++ grub_err_t err; ++ ++ if (partition->msdostype != ctx->type) ++ return 0; ++ ++ err = iterate_real (dsk, partition->start ++ + GRUB_PC_PARTITION_BSD_LABEL_SECTOR, 0, ctx->pmap, ++ ctx->hook, ctx->hook_data); ++ if (err == GRUB_ERR_NONE) ++ { ++ ctx->count++; ++ return 1; ++ } ++ if (err == GRUB_ERR_BAD_PART_TABLE) ++ { ++ grub_errno = GRUB_ERR_NONE; ++ return 0; ++ } ++ grub_print_error (); ++ return 0; + } + + /* This is a total breakage. Even when net-/openbsd label is inside partition +@@ -150,45 +186,26 @@ bsdlabel_partition_map_iterate (grub_disk_t disk, + static grub_err_t + netopenbsdlabel_partition_map_iterate (grub_disk_t disk, grub_uint8_t type, + struct grub_partition_map *pmap, +- int (*hook) (grub_disk_t disk, +- const grub_partition_t partition)) ++ grub_partition_iterate_hook_t hook, ++ void *hook_data) + { + int count = 0; + +- auto int check_msdos (grub_disk_t dsk, +- const grub_partition_t partition); +- +- int check_msdos (grub_disk_t dsk, +- const grub_partition_t partition) +- { +- grub_err_t err; +- +- if (partition->msdostype != type) +- return 0; +- +- err = iterate_real (dsk, partition->start +- + GRUB_PC_PARTITION_BSD_LABEL_SECTOR, 0, pmap, hook); +- if (err == GRUB_ERR_NONE) +- { +- count++; +- return 1; +- } +- if (err == GRUB_ERR_BAD_PART_TABLE) +- { +- grub_errno = GRUB_ERR_NONE; +- return 0; +- } +- grub_print_error (); +- return 0; +- } +- + if (disk->partition && grub_strcmp (disk->partition->partmap->name, "msdos") + == 0) + return grub_error (GRUB_ERR_BAD_PART_TABLE, "no embedding supported"); + + { ++ struct netopenbsdlabel_ctx ctx = { ++ .type = type, ++ .pmap = pmap, ++ .hook = hook, ++ .hook_data = hook_data, ++ .count = count ++ }; + grub_err_t err; +- err = grub_partition_msdos_iterate (disk, check_msdos); ++ ++ err = grub_partition_msdos_iterate (disk, check_msdos, &ctx); + + if (err) + return err; +@@ -200,24 +217,24 @@ netopenbsdlabel_partition_map_iterate (grub_disk_t disk, grub_uint8_t type, + + static grub_err_t + netbsdlabel_partition_map_iterate (grub_disk_t disk, +- int (*hook) (grub_disk_t disk, +- const grub_partition_t partition)) ++ grub_partition_iterate_hook_t hook, ++ void *hook_data) + { + return netopenbsdlabel_partition_map_iterate (disk, + GRUB_PC_PARTITION_TYPE_NETBSD, + &grub_netbsdlabel_partition_map, +- hook); ++ hook, hook_data); + } + + static grub_err_t + openbsdlabel_partition_map_iterate (grub_disk_t disk, +- int (*hook) (grub_disk_t disk, +- const grub_partition_t partition)) ++ grub_partition_iterate_hook_t hook, ++ void *hook_data) + { + return netopenbsdlabel_partition_map_iterate (disk, + GRUB_PC_PARTITION_TYPE_OPENBSD, + &grub_openbsdlabel_partition_map, +- hook); ++ hook, hook_data); + } + + +diff --git a/grub-core/partmap/dvh.c b/grub-core/partmap/dvh.c +index 79ec01b..5b464da 100644 +--- a/grub-core/partmap/dvh.c ++++ b/grub-core/partmap/dvh.c +@@ -64,8 +64,7 @@ grub_dvh_is_valid (grub_uint32_t *label) + + static grub_err_t + dvh_partition_map_iterate (grub_disk_t disk, +- int (*hook) (grub_disk_t disk, +- const grub_partition_t partition)) ++ grub_partition_iterate_hook_t hook, void *hook_data) + { + struct grub_partition p; + union +@@ -101,7 +100,7 @@ dvh_partition_map_iterate (grub_disk_t disk, + p.start = grub_be_to_cpu32 (block.dvh.parts[partnum].start); + p.len = grub_be_to_cpu32 (block.dvh.parts[partnum].length); + p.number = p.index = partnum; +- if (hook (disk, &p)) ++ if (hook (disk, &p, hook_data)) + break; + } + +diff --git a/grub-core/partmap/gpt.c b/grub-core/partmap/gpt.c +index 17f242d..38df7b3 100644 +--- a/grub-core/partmap/gpt.c ++++ b/grub-core/partmap/gpt.c +@@ -48,8 +48,8 @@ static struct grub_partition_map grub_gpt_partition_map; + + grub_err_t + grub_gpt_partition_map_iterate (grub_disk_t disk, +- int (*hook) (grub_disk_t disk, +- const grub_partition_t partition)) ++ grub_partition_iterate_hook_t hook, ++ void *hook_data) + { + struct grub_partition part; + struct grub_gpt_header gpt; +@@ -113,7 +113,7 @@ grub_gpt_partition_map_iterate (grub_disk_t disk, + (unsigned long long) part.start, + (unsigned long long) part.len); + +- if (hook (disk, &part)) ++ if (hook (disk, &part, hook_data)) + return grub_errno; + } + +@@ -129,71 +129,81 @@ grub_gpt_partition_map_iterate (grub_disk_t disk, + } + + #ifdef GRUB_UTIL ++/* Context for gpt_partition_map_embed. */ ++struct gpt_partition_map_embed_ctx ++{ ++ grub_disk_addr_t start, len; ++}; ++ ++/* Helper for gpt_partition_map_embed. */ ++static int ++find_usable_region (grub_disk_t disk __attribute__ ((unused)), ++ const grub_partition_t p, void *data) ++{ ++ struct gpt_partition_map_embed_ctx *ctx = data; ++ struct grub_gpt_partentry gptdata; ++ grub_partition_t p2; ++ ++ p2 = disk->partition; ++ disk->partition = p->parent; ++ if (grub_disk_read (disk, p->offset, p->index, ++ sizeof (gptdata), &gptdata)) ++ { ++ disk->partition = p2; ++ return 0; ++ } ++ disk->partition = p2; ++ ++ /* If there's an embed region, it is in a dedicated partition. */ ++ if (! grub_memcmp (&gptdata.type, &grub_gpt_partition_type_bios_boot, 16)) ++ { ++ ctx->start = p->start; ++ ctx->len = p->len; ++ return 1; ++ } ++ ++ return 0; ++} ++ + static grub_err_t +-gpt_partition_map_embed (struct grub_disk *disk_, unsigned int *nsectors, ++gpt_partition_map_embed (struct grub_disk *disk, unsigned int *nsectors, + unsigned int max_nsectors, + grub_embed_type_t embed_type, + grub_disk_addr_t **sectors) + { +- grub_disk_addr_t start = 0, len = 0; ++ struct gpt_partition_map_embed_ctx ctx = { ++ .start = 0, ++ .len = 0 ++ }; + unsigned i; + grub_err_t err; + +- auto int NESTED_FUNC_ATTR find_usable_region (grub_disk_t disk, +- const grub_partition_t p); +- int NESTED_FUNC_ATTR find_usable_region (grub_disk_t disk __attribute__ ((unused)), +- const grub_partition_t p) +- { +- struct grub_gpt_partentry gptdata; +- grub_partition_t p2; +- +- p2 = disk->partition; +- disk->partition = p->parent; +- if (grub_disk_read (disk, p->offset, p->index, +- sizeof (gptdata), &gptdata)) +- { +- disk->partition = p2; +- return 0; +- } +- disk->partition = p2; +- +- /* If there's an embed region, it is in a dedicated partition. */ +- if (! grub_memcmp (&gptdata.type, &grub_gpt_partition_type_bios_boot, 16)) +- { +- start = p->start; +- len = p->len; +- return 1; +- } +- +- return 0; +- } +- + if (embed_type != GRUB_EMBED_PCBIOS) + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "GPT currently supports only PC-BIOS embedding"); + +- err = grub_gpt_partition_map_iterate (disk_, find_usable_region); ++ err = grub_gpt_partition_map_iterate (disk, find_usable_region, &ctx); + if (err) + return err; + +- if (len == 0) ++ if (ctx.len == 0) + return grub_error (GRUB_ERR_FILE_NOT_FOUND, + N_("this GPT partition label contains no BIOS Boot Partition;" + " embedding won't be possible")); + +- if (len < *nsectors) ++ if (ctx.len < *nsectors) + return grub_error (GRUB_ERR_OUT_OF_RANGE, + N_("your BIOS Boot Partition is too small;" + " embedding won't be possible")); + +- *nsectors = len; ++ *nsectors = ctx.len; + if (*nsectors > max_nsectors) + *nsectors = max_nsectors; + *sectors = grub_malloc (*nsectors * sizeof (**sectors)); + if (!*sectors) + return grub_errno; + for (i = 0; i < *nsectors; i++) +- (*sectors)[i] = start + i; ++ (*sectors)[i] = ctx.start + i; + + return GRUB_ERR_NONE; + } +diff --git a/grub-core/partmap/msdos.c b/grub-core/partmap/msdos.c +index 10ca3f0..47527c3 100644 +--- a/grub-core/partmap/msdos.c ++++ b/grub-core/partmap/msdos.c +@@ -100,8 +100,8 @@ struct embed_signature embed_signatures[] = + + grub_err_t + grub_partition_msdos_iterate (grub_disk_t disk, +- int (*hook) (grub_disk_t disk, +- const grub_partition_t partition)) ++ grub_partition_iterate_hook_t hook, ++ void *hook_data) + { + struct grub_partition p; + struct grub_msdos_partition_mbr mbr; +@@ -186,7 +186,7 @@ grub_partition_msdos_iterate (grub_disk_t disk, + { + p.number++; + +- if (hook (disk, &p)) ++ if (hook (disk, &p, hook_data)) + return grub_errno; + } + else if (p.number < 4) +diff --git a/grub-core/partmap/plan.c b/grub-core/partmap/plan.c +index e6e3113..83db224 100644 +--- a/grub-core/partmap/plan.c ++++ b/grub-core/partmap/plan.c +@@ -31,8 +31,8 @@ static struct grub_partition_map grub_plan_partition_map; + + static grub_err_t + plan_partition_map_iterate (grub_disk_t disk, +- int (*hook) (grub_disk_t disk, +- const grub_partition_t partition)) ++ grub_partition_iterate_hook_t hook, ++ void *hook_data) + { + struct grub_partition p; + int ptr = 0; +@@ -92,7 +92,7 @@ plan_partition_map_iterate (grub_disk_t disk, + if (c != '\n') + break; + p.len -= p.start; +- if (hook (disk, &p)) ++ if (hook (disk, &p, hook_data)) + return grub_errno; + } + if (p.number == 0) +diff --git a/grub-core/partmap/sun.c b/grub-core/partmap/sun.c +index dfe51f3..cff09ae 100644 +--- a/grub-core/partmap/sun.c ++++ b/grub-core/partmap/sun.c +@@ -86,8 +86,7 @@ grub_sun_is_valid (grub_uint16_t *label) + + static grub_err_t + sun_partition_map_iterate (grub_disk_t disk, +- int (*hook) (grub_disk_t disk, +- const grub_partition_t partition)) ++ grub_partition_iterate_hook_t hook, void *hook_data) + { + struct grub_partition p; + union +@@ -128,7 +127,7 @@ sun_partition_map_iterate (grub_disk_t disk, + p.number = p.index = partnum; + if (p.len) + { +- if (hook (disk, &p)) ++ if (hook (disk, &p, hook_data)) + partnum = GRUB_PARTMAP_SUN_MAX_PARTS; + } + } +diff --git a/grub-core/partmap/sunpc.c b/grub-core/partmap/sunpc.c +index 1c1fdce..7034272 100644 +--- a/grub-core/partmap/sunpc.c ++++ b/grub-core/partmap/sunpc.c +@@ -68,8 +68,8 @@ grub_sun_is_valid (grub_uint16_t *label) + + 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_iterate_hook_t hook, ++ void *hook_data) + { + grub_partition_t p; + union +@@ -122,7 +122,7 @@ sun_pc_partition_map_iterate (grub_disk_t disk, + p->number = partnum; + if (p->len) + { +- if (hook (disk, p)) ++ if (hook (disk, p, hook_data)) + partnum = GRUB_PARTMAP_SUN_PC_MAX_PARTS; + } + } +diff --git a/include/grub/arc/arc.h b/include/grub/arc/arc.h +index a825a98..739926f 100644 +--- a/include/grub/arc/arc.h ++++ b/include/grub/arc/arc.h +@@ -255,7 +255,12 @@ struct grub_arc_system_parameter_block + #define GRUB_ARC_STDIN 0 + #define GRUB_ARC_STDOUT 1 + +-int EXPORT_FUNC (grub_arc_iterate_devs) (int (*hook) (const char *name, const struct grub_arc_component *comp), int alt_names); ++typedef int (*grub_arc_iterate_devs_hook_t) ++ (const char *name, const struct grub_arc_component *comp, void *data); ++ ++int EXPORT_FUNC (grub_arc_iterate_devs) (grub_arc_iterate_devs_hook_t hook, ++ void *hook_data, ++ int alt_names); + + #define FOR_ARC_CHILDREN(comp, parent) for (comp = GRUB_ARC_FIRMWARE_VECTOR->getchild (parent); comp; comp = GRUB_ARC_FIRMWARE_VECTOR->getpeer (comp)) + +diff --git a/include/grub/ata.h b/include/grub/ata.h +index efba7b7..e8a84b8 100644 +--- a/include/grub/ata.h ++++ b/include/grub/ata.h +@@ -193,10 +193,12 @@ struct grub_ata + + typedef struct grub_ata *grub_ata_t; + ++typedef int (*grub_ata_dev_iterate_hook_t) (int id, int bus, void *data); ++ + struct grub_ata_dev + { + /* Call HOOK with each device name, until HOOK returns non-zero. */ +- int (*iterate) (int (*hook) (int id, int bus), ++ int (*iterate) (grub_ata_dev_iterate_hook_t hook, void *hook_data, + grub_disk_pull_t pull); + + /* Open the device named NAME, and set up SCSI. */ +diff --git a/include/grub/device.h b/include/grub/device.h +index f3e43bf..1d1a239 100644 +--- a/include/grub/device.h ++++ b/include/grub/device.h +@@ -33,8 +33,11 @@ struct grub_device + }; + typedef struct grub_device *grub_device_t; + ++typedef int (*grub_device_iterate_hook_t) (const char *name, void *data); ++ + grub_device_t EXPORT_FUNC(grub_device_open) (const char *name); + grub_err_t EXPORT_FUNC(grub_device_close) (grub_device_t device); +-int EXPORT_FUNC(grub_device_iterate) (int (*hook) (const char *name)); ++int EXPORT_FUNC(grub_device_iterate) (grub_device_iterate_hook_t hook, ++ void *hook_data); + + #endif /* ! GRUB_DEVICE_HEADER */ +diff --git a/include/grub/disk.h b/include/grub/disk.h +index 096173d..013ca1f 100644 +--- a/include/grub/disk.h ++++ b/include/grub/disk.h +@@ -56,6 +56,8 @@ typedef enum + GRUB_DISK_PULL_MAX + } grub_disk_pull_t; + ++typedef int (*grub_disk_dev_iterate_hook_t) (const char *name, void *data); ++ + /* Disk device. */ + struct grub_disk_dev + { +@@ -66,7 +68,7 @@ struct grub_disk_dev + enum grub_disk_dev_id id; + + /* Call HOOK with each device name, until HOOK returns non-zero. */ +- int (*iterate) (int (*hook) (const char *name), ++ int (*iterate) (grub_disk_dev_iterate_hook_t hook, void *hook_data, + grub_disk_pull_t pull); + + /* Open the device named NAME, and set up DISK. */ +@@ -158,14 +160,14 @@ void grub_disk_cache_invalidate_all (void); + void EXPORT_FUNC(grub_disk_dev_register) (grub_disk_dev_t dev); + void EXPORT_FUNC(grub_disk_dev_unregister) (grub_disk_dev_t dev); + static inline int +-grub_disk_dev_iterate (int (*hook) (const char *name)) ++grub_disk_dev_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data) + { + grub_disk_dev_t p; + grub_disk_pull_t pull; + + for (pull = 0; pull < GRUB_DISK_PULL_MAX; pull++) + for (p = grub_disk_dev_list; p; p = p->next) +- if (p->iterate && (p->iterate) (hook, pull)) ++ if (p->iterate && (p->iterate) (hook, hook_data, pull)) + return 1; + + return 0; +diff --git a/include/grub/gpt_partition.h b/include/grub/gpt_partition.h +index 83e3b31..4aaf1c4 100644 +--- a/include/grub/gpt_partition.h ++++ b/include/grub/gpt_partition.h +@@ -80,8 +80,8 @@ struct grub_gpt_partentry + + grub_err_t + grub_gpt_partition_map_iterate (grub_disk_t disk, +- int (*hook) (grub_disk_t disk, +- const grub_partition_t partition)); ++ grub_partition_iterate_hook_t hook, ++ void *hook_data); + + + #endif /* ! GRUB_GPT_PARTITION_HEADER */ +diff --git a/include/grub/msdos_partition.h b/include/grub/msdos_partition.h +index 9c8ac3e..1e9b65e 100644 +--- a/include/grub/msdos_partition.h ++++ b/include/grub/msdos_partition.h +@@ -120,7 +120,7 @@ grub_msdos_partition_is_extended (int type) + + grub_err_t + grub_partition_msdos_iterate (grub_disk_t disk, +- int (*hook) (grub_disk_t disk, +- const grub_partition_t partition)); ++ grub_partition_iterate_hook_t hook, ++ void *hook_data); + + #endif /* ! GRUB_PC_PARTITION_HEADER */ +diff --git a/include/grub/partition.h b/include/grub/partition.h +index ec0a667..7adb7ec 100644 +--- a/include/grub/partition.h ++++ b/include/grub/partition.h +@@ -33,6 +33,10 @@ typedef enum + } grub_embed_type_t; + #endif + ++typedef int (*grub_partition_iterate_hook_t) (struct grub_disk *disk, ++ const grub_partition_t partition, ++ void *data); ++ + /* Partition map type. */ + struct grub_partition_map + { +@@ -45,8 +49,7 @@ struct grub_partition_map + + /* Call HOOK with each partition, until HOOK returns non-zero. */ + grub_err_t (*iterate) (struct grub_disk *disk, +- int (*hook) (struct grub_disk *disk, +- const grub_partition_t partition)); ++ grub_partition_iterate_hook_t hook, void *hook_data); + #ifdef GRUB_UTIL + /* Determine sectors available for embedding. */ + grub_err_t (*embed) (struct grub_disk *disk, unsigned int *nsectors, +@@ -89,8 +92,8 @@ struct grub_partition + grub_partition_t EXPORT_FUNC(grub_partition_probe) (struct grub_disk *disk, + const char *str); + int EXPORT_FUNC(grub_partition_iterate) (struct grub_disk *disk, +- int (*hook) (struct grub_disk *disk, +- const grub_partition_t partition)); ++ grub_partition_iterate_hook_t hook, ++ void *hook_data); + char *EXPORT_FUNC(grub_partition_get_name) (const grub_partition_t partition); + + +diff --git a/include/grub/scsi.h b/include/grub/scsi.h +index 13300ca..a919a7c 100644 +--- a/include/grub/scsi.h ++++ b/include/grub/scsi.h +@@ -49,10 +49,13 @@ grub_make_scsi_id (int subsystem, int bus, int lun) + | (bus << GRUB_SCSI_ID_BUS_SHIFT) | (lun << GRUB_SCSI_ID_LUN_SHIFT); + } + ++typedef int (*grub_scsi_dev_iterate_hook_t) (int id, int bus, int luns, ++ void *data); ++ + struct grub_scsi_dev + { + /* Call HOOK with each device name, until HOOK returns non-zero. */ +- int (*iterate) (int NESTED_FUNC_ATTR (*hook) (int id, int bus, int luns), ++ int (*iterate) (grub_scsi_dev_iterate_hook_t hook, void *hook_data, + grub_disk_pull_t pull); + + /* Open the device named NAME, and set up SCSI. */ +diff --git a/util/getroot.c b/util/getroot.c +index 3b5b0f6..654d1e1 100644 +--- a/util/getroot.c ++++ b/util/getroot.c +@@ -2198,6 +2198,36 @@ grub_util_get_os_disk (const char *os_dev) + return convert_system_partition_to_system_disk (os_dev, &st, &is_part); + } + ++#if defined(__linux__) || defined(__CYGWIN__) || defined(HAVE_DIOCGDINFO) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined (__sun__) ++/* Context for grub_util_biosdisk_get_grub_dev. */ ++struct grub_util_biosdisk_get_grub_dev_ctx ++{ ++ char *partname; ++ grub_disk_addr_t start; ++}; ++ ++/* Helper for grub_util_biosdisk_get_grub_dev. */ ++static int ++find_partition (grub_disk_t dsk __attribute__ ((unused)), ++ const grub_partition_t partition, void *data) ++{ ++ struct grub_util_biosdisk_get_grub_dev_ctx *ctx = data; ++ grub_disk_addr_t part_start = 0; ++ grub_util_info ("Partition %d starts from %" PRIuGRUB_UINT64_T, ++ partition->number, partition->start); ++ ++ part_start = grub_partition_get_start (partition); ++ ++ if (ctx->start == part_start) ++ { ++ ctx->partname = grub_partition_get_name (partition); ++ return 1; ++ } ++ ++ return 0; ++} ++#endif ++ + char * + grub_util_biosdisk_get_grub_dev (const char *os_dev) + { +@@ -2250,29 +2280,9 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) + For NetBSD and FreeBSD, proceed as for Linux, except that the start + sector is obtained from the disk label. */ + { +- char *name, *partname; ++ char *name; + grub_disk_t disk; +- grub_disk_addr_t start; +- auto int find_partition (grub_disk_t dsk, +- const grub_partition_t partition); +- +- int find_partition (grub_disk_t dsk __attribute__ ((unused)), +- const grub_partition_t partition) +- { +- grub_disk_addr_t part_start = 0; +- grub_util_info ("Partition %d starts from %" PRIuGRUB_UINT64_T, +- partition->number, partition->start); +- +- part_start = grub_partition_get_start (partition); +- +- if (start == part_start) +- { +- partname = grub_partition_get_name (partition); +- return 1; +- } +- +- return 0; +- } ++ struct grub_util_biosdisk_get_grub_dev_ctx ctx; + + name = make_device_name (drive, -1, -1); + +@@ -2284,16 +2294,16 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) + * different, we know that os_dev cannot be a floppy device. */ + # endif /* !defined(HAVE_DIOCGDINFO) */ + +- start = grub_hostdisk_find_partition_start (os_dev); ++ ctx.start = grub_hostdisk_find_partition_start (os_dev); + if (grub_errno != GRUB_ERR_NONE) + { + free (name); + return 0; + } + +- grub_util_info ("%s starts from %" PRIuGRUB_UINT64_T, os_dev, start); ++ grub_util_info ("%s starts from %" PRIuGRUB_UINT64_T, os_dev, ctx.start); + +- if (start == 0 && !is_part) ++ if (ctx.start == 0 && !is_part) + return name; + + grub_util_info ("opening the device %s", name); +@@ -2325,20 +2335,20 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) + return 0; + } + +- name = grub_util_get_ldm (disk, start); ++ name = grub_util_get_ldm (disk, ctx.start); + if (name) + return name; + +- partname = NULL; ++ ctx.partname = NULL; + +- grub_partition_iterate (disk, find_partition); ++ grub_partition_iterate (disk, find_partition, &ctx); + if (grub_errno != GRUB_ERR_NONE) + { + grub_disk_close (disk); + return 0; + } + +- if (partname == NULL) ++ if (ctx.partname == NULL) + { + grub_disk_close (disk); + grub_util_info ("cannot find the partition of `%s'", os_dev); +@@ -2347,8 +2357,8 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) + return 0; + } + +- name = grub_xasprintf ("%s,%s", disk->name, partname); +- free (partname); ++ name = grub_xasprintf ("%s,%s", disk->name, ctx.partname); ++ free (ctx.partname); + grub_disk_close (disk); + return name; + } +diff --git a/util/grub-setup.c b/util/grub-setup.c +index de0417f..187345a 100644 +--- a/util/grub-setup.c ++++ b/util/grub-setup.c +@@ -138,6 +138,44 @@ write_rootdev (grub_device_t root_dev, + #define BOOT_SECTOR 0 + #endif + ++#ifdef GRUB_SETUP_BIOS ++/* Context for setup/identify_partmap. */ ++struct identify_partmap_ctx ++{ ++ grub_partition_map_t dest_partmap; ++ grub_partition_t container; ++ int multiple_partmaps; ++}; ++ ++/* Helper for setup/identify_partmap. ++ Unlike root_dev, with dest_dev we're interested in the partition map even ++ if dest_dev itself is a whole disk. */ ++static int ++identify_partmap (grub_disk_t disk __attribute__ ((unused)), ++ const grub_partition_t p, void *data) ++{ ++ struct identify_partmap_ctx *ctx = data; ++ ++ if (p->parent != ctx->container) ++ return 0; ++ /* NetBSD and OpenBSD subpartitions have metadata inside a partition, ++ so they are safe to ignore. ++ */ ++ if (grub_strcmp (p->partmap->name, "netbsd") == 0 ++ || grub_strcmp (p->partmap->name, "openbsd") == 0) ++ return 0; ++ if (ctx->dest_partmap == NULL) ++ { ++ ctx->dest_partmap = p->partmap; ++ return 0; ++ } ++ if (ctx->dest_partmap == p->partmap) ++ return 0; ++ ctx->multiple_partmaps = 1; ++ return 1; ++} ++#endif ++ + static void + setup (const char *dir, + const char *boot_file, const char *core_file, +@@ -337,9 +375,11 @@ setup (const char *dir, + + #ifdef GRUB_SETUP_BIOS + { +- grub_partition_map_t dest_partmap = NULL; +- grub_partition_t container = dest_dev->disk->partition; +- int multiple_partmaps = 0; ++ struct identify_partmap_ctx ctx = { ++ .dest_partmap = NULL, ++ .container = dest_dev->disk->partition, ++ .multiple_partmaps = 0 ++ }; + int is_ldm; + grub_err_t err; + grub_disk_addr_t *sectors; +@@ -347,38 +387,13 @@ setup (const char *dir, + grub_fs_t fs; + unsigned int nsec, maxsec; + +- /* Unlike root_dev, with dest_dev we're interested in the partition map even +- if dest_dev itself is a whole disk. */ +- auto int NESTED_FUNC_ATTR identify_partmap (grub_disk_t disk, +- const grub_partition_t p); +- int NESTED_FUNC_ATTR identify_partmap (grub_disk_t disk __attribute__ ((unused)), +- const grub_partition_t p) +- { +- if (p->parent != container) +- return 0; +- /* NetBSD and OpenBSD subpartitions have metadata inside a partition, +- so they are safe to ignore. +- */ +- if (grub_strcmp (p->partmap->name, "netbsd") == 0 +- || grub_strcmp (p->partmap->name, "openbsd") == 0) +- return 0; +- if (dest_partmap == NULL) +- { +- dest_partmap = p->partmap; +- return 0; +- } +- if (dest_partmap == p->partmap) +- return 0; +- multiple_partmaps = 1; +- return 1; +- } +- +- grub_partition_iterate (dest_dev->disk, identify_partmap); ++ grub_partition_iterate (dest_dev->disk, identify_partmap, &ctx); + +- if (container && grub_strcmp (container->partmap->name, "msdos") == 0 +- && dest_partmap +- && (container->msdostype == GRUB_PC_PARTITION_TYPE_NETBSD +- || container->msdostype == GRUB_PC_PARTITION_TYPE_OPENBSD)) ++ if (ctx.container ++ && grub_strcmp (ctx.container->partmap->name, "msdos") == 0 ++ && ctx.dest_partmap ++ && (ctx.container->msdostype == GRUB_PC_PARTITION_TYPE_NETBSD ++ || ctx.container->msdostype == GRUB_PC_PARTITION_TYPE_OPENBSD)) + { + grub_util_warn ("%s", _("Attempting to install GRUB to a disk with multiple partition labels or both partition label and filesystem. This is not supported yet.")); + goto unable_to_embed; +@@ -392,7 +407,7 @@ setup (const char *dir, + + if (fs_probe) + { +- if (!fs && !dest_partmap) ++ if (!fs && !ctx.dest_partmap) + grub_util_error (_("unable to identify a filesystem in %s; safety check can't be performed"), + dest_dev->disk->name); + if (fs && !fs->reserved_first_sector) +@@ -403,20 +418,20 @@ setup (const char *dir, + "by grub-setup (--skip-fs-probe disables this " + "check, use at your own risk)"), dest_dev->disk->name, fs->name); + +- if (dest_partmap && strcmp (dest_partmap->name, "msdos") != 0 +- && strcmp (dest_partmap->name, "gpt") != 0 +- && strcmp (dest_partmap->name, "bsd") != 0 +- && strcmp (dest_partmap->name, "netbsd") != 0 +- && strcmp (dest_partmap->name, "openbsd") != 0 +- && strcmp (dest_partmap->name, "sunpc") != 0) ++ if (ctx.dest_partmap && strcmp (ctx.dest_partmap->name, "msdos") != 0 ++ && strcmp (ctx.dest_partmap->name, "gpt") != 0 ++ && strcmp (ctx.dest_partmap->name, "bsd") != 0 ++ && strcmp (ctx.dest_partmap->name, "netbsd") != 0 ++ && strcmp (ctx.dest_partmap->name, "openbsd") != 0 ++ && strcmp (ctx.dest_partmap->name, "sunpc") != 0) + /* TRANSLATORS: Partition map may reserve the space just GRUB isn't sure about it. */ + grub_util_error (_("%s appears to contain a %s partition map which isn't known to " + "reserve space for DOS-style boot. Installing GRUB there could " + "result in FILESYSTEM DESTRUCTION if valuable data is overwritten " + "by grub-setup (--skip-fs-probe disables this " +- "check, use at your own risk)"), dest_dev->disk->name, dest_partmap->name); +- if (is_ldm && dest_partmap && strcmp (dest_partmap->name, "msdos") != 0 +- && strcmp (dest_partmap->name, "gpt") != 0) ++ "check, use at your own risk)"), dest_dev->disk->name, ctx.dest_partmap->name); ++ if (is_ldm && ctx.dest_partmap && strcmp (ctx.dest_partmap->name, "msdos") != 0 ++ && strcmp (ctx.dest_partmap->name, "gpt") != 0) + grub_util_error (_("%s appears to contain a %s partition map and " + "LDM which isn't known to be a safe combination." + " Installing GRUB there could " +@@ -424,12 +439,12 @@ setup (const char *dir, + " is overwritten " + "by grub-setup (--skip-fs-probe disables this " + "check, use at your own risk)"), +- dest_dev->disk->name, dest_partmap->name); ++ dest_dev->disk->name, ctx.dest_partmap->name); + + } + + /* Copy the partition table. */ +- if (dest_partmap || ++ if (ctx.dest_partmap || + (!allow_floppy && !grub_util_biosdisk_is_floppy (dest_dev->disk))) + memcpy (boot_img + GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC, + tmp_img + GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC, +@@ -437,21 +452,21 @@ setup (const char *dir, + + free (tmp_img); + +- if (! dest_partmap && ! fs && !is_ldm) ++ if (! ctx.dest_partmap && ! fs && !is_ldm) + { + grub_util_warn ("%s", _("Attempting to install GRUB to a partitionless disk or to a partition. This is a BAD idea.")); + goto unable_to_embed; + } +- if (multiple_partmaps || (dest_partmap && fs) || (is_ldm && fs)) ++ if (ctx.multiple_partmaps || (ctx.dest_partmap && fs) || (is_ldm && fs)) + { + grub_util_warn ("%s", _("Attempting to install GRUB to a disk with multiple partition labels. This is not supported yet.")); + goto unable_to_embed; + } + +- if (dest_partmap && !dest_partmap->embed) ++ if (ctx.dest_partmap && !ctx.dest_partmap->embed) + { + grub_util_warn (_("Partition style `%s' doesn't support embedding"), +- dest_partmap->name); ++ ctx.dest_partmap->name); + goto unable_to_embed; + } + +@@ -473,9 +488,9 @@ setup (const char *dir, + if (is_ldm) + err = grub_util_ldm_embed (dest_dev->disk, &nsec, maxsec, + GRUB_EMBED_PCBIOS, §ors); +- else if (dest_partmap) +- err = dest_partmap->embed (dest_dev->disk, &nsec, maxsec, +- GRUB_EMBED_PCBIOS, §ors); ++ else if (ctx.dest_partmap) ++ err = ctx.dest_partmap->embed (dest_dev->disk, &nsec, maxsec, ++ GRUB_EMBED_PCBIOS, §ors); + else + err = fs->embed (dest_dev, &nsec, maxsec, + GRUB_EMBED_PCBIOS, §ors); +@@ -507,12 +522,12 @@ setup (const char *dir, + grub_util_error ("%s", _("no terminator in the core image")); + } + +- save_first_sector (sectors[0] + grub_partition_get_start (container), ++ save_first_sector (sectors[0] + grub_partition_get_start (ctx.container), + 0, GRUB_DISK_SECTOR_SIZE); + + block = first_block; + for (i = 1; i < nsec; i++) +- save_blocklists (sectors[i] + grub_partition_get_start (container), ++ save_blocklists (sectors[i] + grub_partition_get_start (ctx.container), + 0, GRUB_DISK_SECTOR_SIZE); + + /* Make sure that the last blocklist is a terminator. */ +-- +1.8.1.4 + diff --git a/0116-Remove-nested-functions-from-ELF-iterators.patch b/0116-Remove-nested-functions-from-ELF-iterators.patch new file mode 100644 index 0000000..409206b --- /dev/null +++ b/0116-Remove-nested-functions-from-ELF-iterators.patch @@ -0,0 +1,563 @@ +From 01b48ebb8a7fcf2b6dd29517726f173da0d42048 Mon Sep 17 00:00:00 2001 +From: Colin Watson +Date: Sun, 20 Jan 2013 15:54:09 +0000 +Subject: [PATCH 116/364] Remove nested functions from ELF iterators. + +--- + ChangeLog | 4 + + grub-core/kern/elf.c | 373 ++++++++++++++++++++++++-------------------- + grub-core/loader/i386/bsd.c | 4 +- + include/grub/elfload.h | 11 +- + 4 files changed, 219 insertions(+), 173 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 733b212..3ac8171 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,9 @@ + 2013-01-20 Colin Watson + ++ Remove nested functions from ELF iterators. ++ ++2013-01-20 Colin Watson ++ + Remove nested functions from device iterators. + + * include/grub/arc/arc.h (grub_arc_iterate_devs_hook_t): New type. +diff --git a/grub-core/kern/elf.c b/grub-core/kern/elf.c +index 682cfbd..f52ca21 100644 +--- a/grub-core/kern/elf.c ++++ b/grub-core/kern/elf.c +@@ -149,8 +149,7 @@ grub_elf32_load_phdrs (grub_elf_t elf, const char *filename) + grub_err_t + grub_elf32_phdr_iterate (grub_elf_t elf, + const char *filename, +- int NESTED_FUNC_ATTR (*hook) (grub_elf_t, Elf32_Phdr *, void *), +- void *hook_arg) ++ grub_elf32_phdr_iterate_hook_t hook, void *hook_arg) + { + Elf32_Phdr *phdrs; + unsigned int i; +@@ -177,48 +176,58 @@ grub_elf32_phdr_iterate (grub_elf_t elf, + return grub_errno; + } + ++struct grub_elf32_size_ctx ++{ ++ Elf32_Addr segments_start, segments_end; ++ int nr_phdrs; ++ grub_uint32_t curr_align; ++}; ++ ++/* Run through the program headers to calculate the total memory size we ++ * should claim. */ ++static int ++grub_elf32_calcsize (grub_elf_t _elf __attribute__ ((unused)), ++ Elf32_Phdr *phdr, void *data) ++{ ++ struct grub_elf32_size_ctx *ctx = data; ++ ++ /* Only consider loadable segments. */ ++ if (phdr->p_type != PT_LOAD) ++ return 0; ++ ctx->nr_phdrs++; ++ if (phdr->p_paddr < ctx->segments_start) ++ ctx->segments_start = phdr->p_paddr; ++ if (phdr->p_paddr + phdr->p_memsz > ctx->segments_end) ++ ctx->segments_end = phdr->p_paddr + phdr->p_memsz; ++ if (ctx->curr_align < phdr->p_align) ++ ctx->curr_align = phdr->p_align; ++ return 0; ++} ++ + /* Calculate the amount of memory spanned by the segments. */ + grub_size_t + grub_elf32_size (grub_elf_t elf, const char *filename, + Elf32_Addr *base, grub_uint32_t *max_align) + { +- Elf32_Addr segments_start = (Elf32_Addr) -1; +- Elf32_Addr segments_end = 0; +- int nr_phdrs = 0; +- grub_uint32_t curr_align = 1; +- +- /* 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 _elf __attribute__ ((unused)), +- Elf32_Phdr *phdr, +- void *_arg __attribute__ ((unused))) +- { +- /* Only consider loadable segments. */ +- if (phdr->p_type != PT_LOAD) +- return 0; +- nr_phdrs++; +- if (phdr->p_paddr < segments_start) +- segments_start = phdr->p_paddr; +- if (phdr->p_paddr + phdr->p_memsz > segments_end) +- segments_end = phdr->p_paddr + phdr->p_memsz; +- if (curr_align < phdr->p_align) +- curr_align = phdr->p_align; +- return 0; +- } ++ struct grub_elf32_size_ctx ctx = { ++ .segments_start = (Elf32_Addr) -1, ++ .segments_end = 0, ++ .nr_phdrs = 0, ++ .curr_align = 1 ++ }; + +- grub_elf32_phdr_iterate (elf, filename, calcsize, 0); ++ grub_elf32_phdr_iterate (elf, filename, grub_elf32_calcsize, &ctx); + + if (base) + *base = 0; + +- if (nr_phdrs == 0) ++ if (ctx.nr_phdrs == 0) + { + grub_error (GRUB_ERR_BAD_OS, "no program headers present"); + return 0; + } + +- if (segments_end < segments_start) ++ if (ctx.segments_end < ctx.segments_start) + { + /* Very bad addresses. */ + grub_error (GRUB_ERR_BAD_OS, "bad program header load addresses"); +@@ -226,76 +235,87 @@ grub_elf32_size (grub_elf_t elf, const char *filename, + } + + if (base) +- *base = segments_start; ++ *base = ctx.segments_start; + if (max_align) +- *max_align = curr_align; +- return segments_end - segments_start; ++ *max_align = ctx.curr_align; ++ return ctx.segments_end - ctx.segments_start; + } + +-/* Load every loadable segment into memory specified by `_load_hook'. */ +-grub_err_t +-grub_elf32_load (grub_elf_t _elf, const char *filename, +- grub_elf32_load_hook_t _load_hook, +- grub_addr_t *base, grub_size_t *size) ++struct grub_elf32_load_ctx + { +- grub_addr_t load_base = (grub_addr_t) -1ULL; +- grub_size_t load_size = 0; +- grub_err_t err; ++ const char *filename; ++ grub_elf32_load_hook_t load_hook; ++ grub_addr_t load_base; ++ grub_size_t load_size; ++}; ++ ++static int ++grub_elf32_load_segment (grub_elf_t elf, Elf32_Phdr *phdr, void *data) ++{ ++ struct grub_elf32_load_ctx *ctx = data; ++ grub_addr_t load_addr; ++ int do_load = 1; + +- auto int NESTED_FUNC_ATTR grub_elf32_load_segment (grub_elf_t elf, Elf32_Phdr *phdr, void *hook); +- int NESTED_FUNC_ATTR grub_elf32_load_segment (grub_elf_t elf, Elf32_Phdr *phdr, void *hook) +- { +- grub_elf32_load_hook_t load_hook = (grub_elf32_load_hook_t) hook; +- grub_addr_t load_addr; +- int do_load = 1; ++ load_addr = phdr->p_paddr; ++ if (ctx->load_hook && ctx->load_hook (phdr, &load_addr, &do_load)) ++ return 1; + +- load_addr = phdr->p_paddr; +- if (load_hook && load_hook (phdr, &load_addr, &do_load)) +- return 1; ++ if (! do_load) ++ return 0; + +- if (! do_load) +- return 0; ++ if (load_addr < ctx->load_base) ++ ctx->load_base = load_addr; + +- if (load_addr < load_base) +- load_base = load_addr; ++ grub_dprintf ("elf", "Loading segment at 0x%llx, size 0x%llx\n", ++ (unsigned long long) load_addr, ++ (unsigned long long) phdr->p_memsz); + +- grub_dprintf ("elf", "Loading segment at 0x%llx, size 0x%llx\n", +- (unsigned long long) load_addr, +- (unsigned long long) phdr->p_memsz); ++ if (grub_file_seek (elf->file, phdr->p_offset) == (grub_off_t) -1) ++ return grub_errno; + +- if (grub_file_seek (elf->file, phdr->p_offset) == (grub_off_t) -1) +- return grub_errno; ++ if (phdr->p_filesz) ++ { ++ grub_ssize_t read; ++ read = grub_file_read (elf->file, (void *) load_addr, phdr->p_filesz); ++ if (read != (grub_ssize_t) phdr->p_filesz) ++ { ++ /* XXX How can we free memory from `ctx->load_hook'? */ ++ if (!grub_errno) ++ grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"), ++ ctx->filename); ++ return grub_errno; ++ } ++ } + +- if (phdr->p_filesz) +- { +- grub_ssize_t read; +- read = grub_file_read (elf->file, (void *) load_addr, phdr->p_filesz); +- if (read != (grub_ssize_t) phdr->p_filesz) +- { +- /* XXX How can we free memory from `load_hook'? */ +- if (!grub_errno) +- grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"), +- filename); +- return grub_errno; +- } +- } +- +- if (phdr->p_filesz < phdr->p_memsz) +- grub_memset ((void *) (long) (load_addr + phdr->p_filesz), +- 0, phdr->p_memsz - phdr->p_filesz); +- +- load_size += phdr->p_memsz; ++ if (phdr->p_filesz < phdr->p_memsz) ++ grub_memset ((void *) (long) (load_addr + phdr->p_filesz), ++ 0, phdr->p_memsz - phdr->p_filesz); + +- return 0; +- } ++ ctx->load_size += phdr->p_memsz; ++ ++ return 0; ++} ++ ++/* Load every loadable segment into memory specified by `_load_hook'. */ ++grub_err_t ++grub_elf32_load (grub_elf_t elf, const char *filename, ++ grub_elf32_load_hook_t load_hook, ++ grub_addr_t *base, grub_size_t *size) ++{ ++ struct grub_elf32_load_ctx ctx = { ++ .filename = filename, ++ .load_hook = load_hook, ++ .load_base = (grub_addr_t) -1ULL, ++ .load_size = 0 ++ }; ++ grub_err_t err; + +- err = grub_elf32_phdr_iterate (_elf, filename, +- grub_elf32_load_segment, _load_hook); ++ err = grub_elf32_phdr_iterate (elf, filename, grub_elf32_load_segment, &ctx); + + if (base) +- *base = load_base; ++ *base = ctx.load_base; + if (size) +- *size = load_size; ++ *size = ctx.load_size; + + return err; + } +@@ -339,8 +359,7 @@ grub_elf64_load_phdrs (grub_elf_t elf, const char *filename) + grub_err_t + grub_elf64_phdr_iterate (grub_elf_t elf, + const char *filename, +- int NESTED_FUNC_ATTR (*hook) (grub_elf_t, Elf64_Phdr *, void *), +- void *hook_arg) ++ grub_elf64_phdr_iterate_hook_t hook, void *hook_arg) + { + Elf64_Phdr *phdrs; + unsigned int i; +@@ -367,48 +386,58 @@ grub_elf64_phdr_iterate (grub_elf_t elf, + return grub_errno; + } + ++struct grub_elf64_size_ctx ++{ ++ Elf64_Addr segments_start, segments_end; ++ int nr_phdrs; ++ grub_uint64_t curr_align; ++}; ++ ++/* Run through the program headers to calculate the total memory size we ++ * should claim. */ ++static int ++grub_elf64_calcsize (grub_elf_t _elf __attribute__ ((unused)), ++ Elf64_Phdr *phdr, void *data) ++{ ++ struct grub_elf64_size_ctx *ctx = data; ++ ++ /* Only consider loadable segments. */ ++ if (phdr->p_type != PT_LOAD) ++ return 0; ++ ctx->nr_phdrs++; ++ if (phdr->p_paddr < ctx->segments_start) ++ ctx->segments_start = phdr->p_paddr; ++ if (phdr->p_paddr + phdr->p_memsz > ctx->segments_end) ++ ctx->segments_end = phdr->p_paddr + phdr->p_memsz; ++ if (ctx->curr_align < phdr->p_align) ++ ctx->curr_align = phdr->p_align; ++ return 0; ++} ++ + /* Calculate the amount of memory spanned by the segments. */ + grub_size_t + grub_elf64_size (grub_elf_t elf, const char *filename, + Elf64_Addr *base, grub_uint64_t *max_align) + { +- Elf64_Addr segments_start = (Elf64_Addr) -1; +- Elf64_Addr segments_end = 0; +- int nr_phdrs = 0; +- grub_uint64_t curr_align = 1; +- +- /* 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 _elf __attribute__ ((unused)), +- Elf64_Phdr *phdr, +- void *_arg __attribute__ ((unused))) +- { +- /* Only consider loadable segments. */ +- if (phdr->p_type != PT_LOAD) +- return 0; +- nr_phdrs++; +- if (phdr->p_paddr < segments_start) +- segments_start = phdr->p_paddr; +- if (phdr->p_paddr + phdr->p_memsz > segments_end) +- segments_end = phdr->p_paddr + phdr->p_memsz; +- if (curr_align < phdr->p_align) +- curr_align = phdr->p_align; +- return 0; +- } ++ struct grub_elf64_size_ctx ctx = { ++ .segments_start = (Elf64_Addr) -1, ++ .segments_end = 0, ++ .nr_phdrs = 0, ++ .curr_align = 1 ++ }; + +- grub_elf64_phdr_iterate (elf, filename, calcsize, 0); ++ grub_elf64_phdr_iterate (elf, filename, grub_elf64_calcsize, &ctx); + + if (base) + *base = 0; + +- if (nr_phdrs == 0) ++ if (ctx.nr_phdrs == 0) + { + grub_error (GRUB_ERR_BAD_OS, "no program headers present"); + return 0; + } + +- if (segments_end < segments_start) ++ if (ctx.segments_end < ctx.segments_start) + { + /* Very bad addresses. */ + grub_error (GRUB_ERR_BAD_OS, "bad program header load addresses"); +@@ -416,77 +445,87 @@ grub_elf64_size (grub_elf_t elf, const char *filename, + } + + if (base) +- *base = segments_start; ++ *base = ctx.segments_start; + if (max_align) +- *max_align = curr_align; +- return segments_end - segments_start; ++ *max_align = ctx.curr_align; ++ return ctx.segments_end - ctx.segments_start; + } + +-/* Load every loadable segment into memory specified by `_load_hook'. */ +-grub_err_t +-grub_elf64_load (grub_elf_t _elf, const char *filename, +- grub_elf64_load_hook_t _load_hook, +- grub_addr_t *base, grub_size_t *size) ++struct grub_elf64_load_ctx + { +- grub_addr_t load_base = (grub_addr_t) -1ULL; +- grub_size_t load_size = 0; +- grub_err_t err; ++ const char *filename; ++ grub_elf64_load_hook_t load_hook; ++ grub_addr_t load_base; ++ grub_size_t load_size; ++}; ++ ++static int ++grub_elf64_load_segment (grub_elf_t elf, Elf64_Phdr *phdr, void *data) ++{ ++ struct grub_elf64_load_ctx *ctx = data; ++ grub_addr_t load_addr; ++ int do_load = 1; + +- auto int NESTED_FUNC_ATTR grub_elf64_load_segment (grub_elf_t elf, Elf64_Phdr *phdr, +- void *hook); +- int NESTED_FUNC_ATTR grub_elf64_load_segment (grub_elf_t elf, Elf64_Phdr *phdr, void *hook) +- { +- grub_elf64_load_hook_t load_hook = (grub_elf64_load_hook_t) hook; +- grub_addr_t load_addr; +- int do_load = 1; ++ load_addr = phdr->p_paddr; ++ if (ctx->load_hook && ctx->load_hook (phdr, &load_addr, &do_load)) ++ return 1; + +- load_addr = phdr->p_paddr; +- if (load_hook && load_hook (phdr, &load_addr, &do_load)) +- return 1; ++ if (! do_load) ++ return 0; + +- if (! do_load) +- return 0; ++ if (load_addr < ctx->load_base) ++ ctx->load_base = load_addr; + +- if (load_addr < load_base) +- load_base = load_addr; ++ grub_dprintf ("elf", "Loading segment at 0x%llx, size 0x%llx\n", ++ (unsigned long long) load_addr, ++ (unsigned long long) phdr->p_memsz); + +- grub_dprintf ("elf", "Loading segment at 0x%llx, size 0x%llx\n", +- (unsigned long long) load_addr, +- (unsigned long long) phdr->p_memsz); ++ if (grub_file_seek (elf->file, phdr->p_offset) == (grub_off_t) -1) ++ return grub_errno; + +- if (grub_file_seek (elf->file, phdr->p_offset) == (grub_off_t) -1) +- return grub_errno; ++ if (phdr->p_filesz) ++ { ++ grub_ssize_t read; ++ read = grub_file_read (elf->file, (void *) load_addr, phdr->p_filesz); ++ if (read != (grub_ssize_t) phdr->p_filesz) ++ { ++ /* XXX How can we free memory from `ctx->load_hook'? */ ++ if (!grub_errno) ++ grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"), ++ ctx->filename); ++ return grub_errno; ++ } ++ } + +- if (phdr->p_filesz) +- { +- grub_ssize_t read; +- read = grub_file_read (elf->file, (void *) load_addr, phdr->p_filesz); +- if (read != (grub_ssize_t) phdr->p_filesz) +- { +- /* XXX How can we free memory from `load_hook'? */ +- if (!grub_errno) +- grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"), +- filename); +- return grub_errno; +- } +- } +- +- if (phdr->p_filesz < phdr->p_memsz) +- grub_memset ((void *) (long) (load_addr + phdr->p_filesz), +- 0, phdr->p_memsz - phdr->p_filesz); +- +- load_size += phdr->p_memsz; ++ if (phdr->p_filesz < phdr->p_memsz) ++ grub_memset ((void *) (long) (load_addr + phdr->p_filesz), ++ 0, phdr->p_memsz - phdr->p_filesz); + +- return 0; +- } ++ ctx->load_size += phdr->p_memsz; ++ ++ return 0; ++} ++ ++/* Load every loadable segment into memory specified by `_load_hook'. */ ++grub_err_t ++grub_elf64_load (grub_elf_t elf, const char *filename, ++ grub_elf64_load_hook_t load_hook, ++ grub_addr_t *base, grub_size_t *size) ++{ ++ struct grub_elf64_load_ctx ctx = { ++ .filename = filename, ++ .load_hook = load_hook, ++ .load_base = (grub_addr_t) -1ULL, ++ .load_size = 0 ++ }; ++ grub_err_t err; + +- err = grub_elf64_phdr_iterate (_elf, filename, +- grub_elf64_load_segment, _load_hook); ++ err = grub_elf64_phdr_iterate (elf, filename, grub_elf64_load_segment, &ctx); + + if (base) +- *base = load_base; ++ *base = ctx.load_base; + if (size) +- *size = load_size; ++ *size = ctx.load_size; + + return err; + } +diff --git a/grub-core/loader/i386/bsd.c b/grub-core/loader/i386/bsd.c +index 871cf04..9b86158 100644 +--- a/grub-core/loader/i386/bsd.c ++++ b/grub-core/loader/i386/bsd.c +@@ -1311,7 +1311,7 @@ grub_bsd_load_aout (grub_file_t file, const char *filename) + bss_size); + } + +-static int NESTED_FUNC_ATTR ++static int + grub_bsd_elf32_size_hook (grub_elf_t elf __attribute__ ((unused)), + Elf32_Phdr *phdr, void *arg __attribute__ ((unused))) + { +@@ -1353,7 +1353,7 @@ grub_bsd_elf32_hook (Elf32_Phdr * phdr, grub_addr_t * addr, int *do_load) + return GRUB_ERR_NONE; + } + +-static int NESTED_FUNC_ATTR ++static int + grub_bsd_elf64_size_hook (grub_elf_t elf __attribute__ ((unused)), + Elf64_Phdr *phdr, void *arg __attribute__ ((unused))) + { +diff --git a/include/grub/elfload.h b/include/grub/elfload.h +index aae95f5..d1a8d54 100644 +--- a/include/grub/elfload.h ++++ b/include/grub/elfload.h +@@ -41,6 +41,11 @@ typedef grub_err_t (*grub_elf32_load_hook_t) + typedef grub_err_t (*grub_elf64_load_hook_t) + (Elf64_Phdr *phdr, grub_addr_t *addr, int *load); + ++typedef int (*grub_elf32_phdr_iterate_hook_t) ++ (grub_elf_t elf, Elf32_Phdr *phdr, void *arg); ++typedef int (*grub_elf64_phdr_iterate_hook_t) ++ (grub_elf_t elf, Elf64_Phdr *phdr, void *arg); ++ + grub_elf_t grub_elf_open (const char *); + grub_elf_t grub_elf_file (grub_file_t file, const char *filename); + grub_err_t grub_elf_close (grub_elf_t); +@@ -63,12 +68,10 @@ grub_err_t grub_elf64_load (grub_elf_t, const char *filename, + grub_err_t + grub_elf32_phdr_iterate (grub_elf_t elf, + const char *filename, +- int NESTED_FUNC_ATTR (*hook) (grub_elf_t, Elf32_Phdr *, void *), +- void *hook_arg); ++ grub_elf32_phdr_iterate_hook_t hook, void *hook_arg); + grub_err_t + grub_elf64_phdr_iterate (grub_elf_t elf, + const char *filename, +- int NESTED_FUNC_ATTR (*hook) (grub_elf_t, Elf64_Phdr *, void *), +- void *hook_arg); ++ grub_elf64_phdr_iterate_hook_t hook, void *hook_arg); + + #endif /* ! GRUB_ELFLOAD_HEADER */ +-- +1.8.1.4 + diff --git a/0117-util-grub-script-check.c-main-Uniform-the-error-mess.patch b/0117-util-grub-script-check.c-main-Uniform-the-error-mess.patch new file mode 100644 index 0000000..ae5db17 --- /dev/null +++ b/0117-util-grub-script-check.c-main-Uniform-the-error-mess.patch @@ -0,0 +1,39 @@ +From 0b5d3a484eb1e0f2289065366f329b25906dfbbf Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sun, 20 Jan 2013 22:05:55 +0100 +Subject: [PATCH 117/364] * util/grub-script-check.c (main): Uniform the + error message. + +--- + ChangeLog | 4 ++++ + util/grub-script-check.c | 2 +- + 2 files changed, 5 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index 3ac8171..8eab442 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,7 @@ ++2013-01-20 Vladimir Serbinenko ++ ++ * util/grub-script-check.c (main): Uniform the error message. ++ + 2013-01-20 Colin Watson + + Remove nested functions from ELF iterators. +diff --git a/util/grub-script-check.c b/util/grub-script-check.c +index 203a3ff..48c772a 100644 +--- a/util/grub-script-check.c ++++ b/util/grub-script-check.c +@@ -169,7 +169,7 @@ main (int argc, char *argv[]) + if (! ctx.file) + { + char *program = xstrdup(program_name); +- fprintf (stderr, "%s: %s: %s\n", program_name, ++ fprintf (stderr, _("cannot open `%s': %s"), + ctx.arguments.filename, strerror (errno)); + argp_help (&argp, stderr, ARGP_HELP_STD_USAGE, program); + free(program); +-- +1.8.1.4 + diff --git a/0118-docs-grub.texi-Simple-configuration-Clarify-GRUB_HID.patch b/0118-docs-grub.texi-Simple-configuration-Clarify-GRUB_HID.patch new file mode 100644 index 0000000..c0f9407 --- /dev/null +++ b/0118-docs-grub.texi-Simple-configuration-Clarify-GRUB_HID.patch @@ -0,0 +1,47 @@ +From 652031cd423e0c17b40fb63e6882809ee85167fc Mon Sep 17 00:00:00 2001 +From: Andrey Borzenkov +Date: Sun, 20 Jan 2013 22:42:08 +0100 +Subject: [PATCH 118/364] * docs/grub.texi (Simple configuration): + Clarify GRUB_HIDDEN_TIMEOUT is interrupted by ESC. + +--- + ChangeLog | 5 +++++ + docs/grub.texi | 7 ++++--- + 2 files changed, 9 insertions(+), 3 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 8eab442..4d09825 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,8 @@ ++2013-01-20 Andrey Borzenkov ++ ++ * docs/grub.texi (Simple configuration): Clarify GRUB_HIDDEN_TIMEOUT ++ is interrupted by ESC. ++ + 2013-01-20 Vladimir Serbinenko + + * util/grub-script-check.c (main): Uniform the error message. +diff --git a/docs/grub.texi b/docs/grub.texi +index 2dc0cbe..fbbcfb9 100644 +--- a/docs/grub.texi ++++ b/docs/grub.texi +@@ -1201,11 +1201,12 @@ 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, display the menu for the number of ++Wait this many seconds for @key{ESC} to be pressed before displaying the menu. ++If no @key{ESC} is pressed during that time, display the menu for the number of + seconds specified in GRUB_TIMEOUT before booting the default entry. We expect + that most people who use GRUB_HIDDEN_TIMEOUT will want to have GRUB_TIMEOUT set +-to @samp{0} so that the menu is not displayed at all unless a key is pressed. ++to @samp{0} so that the menu is not displayed at all unless @key{ESC} is ++pressed. + Unset by default. + + @item GRUB_HIDDEN_TIMEOUT_QUIET +-- +1.8.1.4 + diff --git a/0119-Split-long-USB-transfers-into-short-ones.patch b/0119-Split-long-USB-transfers-into-short-ones.patch new file mode 100644 index 0000000..0232a87 --- /dev/null +++ b/0119-Split-long-USB-transfers-into-short-ones.patch @@ -0,0 +1,71 @@ +From 1e5b1dd686ca089f9b4034ec26541e7515c9fa58 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sun, 20 Jan 2013 22:45:53 +0100 +Subject: [PATCH 119/364] Split long USB transfers into short ones. + +--- + ChangeLog | 4 ++++ + grub-core/bus/usb/usbtrans.c | 20 ++++++++++++++++---- + include/grub/usbtrans.h | 2 ++ + 3 files changed, 22 insertions(+), 4 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 4d09825..c8edf73 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,7 @@ ++2013-01-20 Aleš Nesrsta ++ ++ Split long USB transfers into short ones. ++ + 2013-01-20 Andrey Borzenkov + + * docs/grub.texi (Simple configuration): Clarify GRUB_HIDDEN_TIMEOUT +diff --git a/grub-core/bus/usb/usbtrans.c b/grub-core/bus/usb/usbtrans.c +index 167fae5..154c72d 100644 +--- a/grub-core/bus/usb/usbtrans.c ++++ b/grub-core/bus/usb/usbtrans.c +@@ -351,11 +351,23 @@ grub_usb_err_t + grub_usb_bulk_read (grub_usb_device_t dev, + int endpoint, grub_size_t size, char *data) + { +- grub_size_t actual; ++ grub_size_t actual, transferred; + grub_usb_err_t err; +- err = grub_usb_bulk_readwrite (dev, endpoint, size, data, +- GRUB_USB_TRANSFER_TYPE_IN, 1000, &actual); +- if (!err && actual != size) ++ grub_size_t current_size, position; ++ ++ for (position = 0, transferred = 0; ++ position < size; position += MAX_USB_TRANSFER_LEN) ++ { ++ current_size = size - position; ++ if (current_size >= MAX_USB_TRANSFER_LEN) ++ current_size = MAX_USB_TRANSFER_LEN; ++ err = grub_usb_bulk_readwrite (dev, endpoint, current_size, ++ &data[position], GRUB_USB_TRANSFER_TYPE_IN, 1000, &actual); ++ transferred += actual; ++ if (err || (current_size != actual) ) break; ++ } ++ ++ if (!err && transferred != size) + err = GRUB_USB_ERR_DATA; + return err; + } +diff --git a/include/grub/usbtrans.h b/include/grub/usbtrans.h +index 5ee276d..5429007 100644 +--- a/include/grub/usbtrans.h ++++ b/include/grub/usbtrans.h +@@ -19,6 +19,8 @@ + #ifndef GRUB_USBTRANS_H + #define GRUB_USBTRANS_H 1 + ++#define MAX_USB_TRANSFER_LEN 0x0800 ++ + typedef enum + { + GRUB_USB_TRANSFER_TYPE_IN, +-- +1.8.1.4 + diff --git a/0120-include-grub-elf.h-Update-ARM-definitions-based-on-b.patch b/0120-include-grub-elf.h-Update-ARM-definitions-based-on-b.patch new file mode 100644 index 0000000..9ac3926 --- /dev/null +++ b/0120-include-grub-elf.h-Update-ARM-definitions-based-on-b.patch @@ -0,0 +1,153 @@ +From 9775ebe3966c84e7b86ea66bc5cc7a828391c7f2 Mon Sep 17 00:00:00 2001 +From: Leif Lindholm +Date: Sun, 20 Jan 2013 23:01:47 +0100 +Subject: [PATCH 120/364] * include/grub/elf.h: Update ARM definitions + based on binutils. + +--- + ChangeLog | 4 ++++ + include/grub/elf.h | 65 +++++++++++++++++++++++++++++++++++++++++++++--------- + 2 files changed, 58 insertions(+), 11 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index c8edf73..e82ee8d 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,7 @@ ++2013-01-20 Leif Lindholm ++ ++ * include/grub/elf.h: Update ARM definitions based on binutils. ++ + 2013-01-20 Aleš Nesrsta + + Split long USB transfers into short ones. +diff --git a/include/grub/elf.h b/include/grub/elf.h +index 9a75b52..d4a2a5f 100644 +--- a/include/grub/elf.h ++++ b/include/grub/elf.h +@@ -145,6 +145,7 @@ typedef struct + #define ELFOSABI_TRU64 10 /* Compaq TRU64 UNIX. */ + #define ELFOSABI_MODESTO 11 /* Novell Modesto. */ + #define ELFOSABI_OPENBSD 12 /* OpenBSD. */ ++#define ELFOSABI_ARM_AEABI 64 /* ARM EABI */ + #define ELFOSABI_ARM 97 /* ARM */ + #define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */ + +@@ -2005,15 +2006,18 @@ typedef Elf32_Addr Elf32_Conflict; + /* ARM specific declarations */ + + /* Processor specific flags for the ELF header e_flags field. */ +-#define EF_ARM_RELEXEC 0x01 +-#define EF_ARM_HASENTRY 0x02 +-#define EF_ARM_INTERWORK 0x04 +-#define EF_ARM_APCS_26 0x08 +-#define EF_ARM_APCS_FLOAT 0x10 +-#define EF_ARM_PIC 0x20 +-#define EF_ARM_ALIGN8 0x40 /* 8-bit structure alignment is in use */ +-#define EF_ARM_NEW_ABI 0x80 +-#define EF_ARM_OLD_ABI 0x100 ++#define EF_ARM_RELEXEC 0x01 ++#define EF_ARM_HASENTRY 0x02 ++#define EF_ARM_INTERWORK 0x04 ++#define EF_ARM_APCS_26 0x08 ++#define EF_ARM_APCS_FLOAT 0x10 ++#define EF_ARM_PIC 0x20 ++#define EF_ARM_ALIGN8 0x40 /* 8-bit structure alignment is in use */ ++#define EF_ARM_NEW_ABI 0x80 ++#define EF_ARM_OLD_ABI 0x100 ++#define EF_ARM_SOFT_FLOAT 0x200 ++#define EF_ARM_VFP_FLOAT 0x400 ++#define EF_ARM_MAVERICK_FLOAT 0x800 + + /* Other constants defined in the ARM ELF spec. version B-01. */ + /* NB. These conflict with values defined above. */ +@@ -2022,13 +2026,21 @@ typedef Elf32_Addr Elf32_Conflict; + #define EF_ARM_MAPSYMSFIRST 0x10 + #define EF_ARM_EABIMASK 0XFF000000 + ++/* Constants defined in AAELF. */ ++#define EF_ARM_BE8 0x00800000 ++#define EF_ARM_LE8 0x00400000 ++ + #define EF_ARM_EABI_VERSION(flags) ((flags) & EF_ARM_EABIMASK) + #define EF_ARM_EABI_UNKNOWN 0x00000000 + #define EF_ARM_EABI_VER1 0x01000000 + #define EF_ARM_EABI_VER2 0x02000000 ++#define EF_ARM_EABI_VER3 0x03000000 ++#define EF_ARM_EABI_VER4 0x04000000 ++#define EF_ARM_EABI_VER5 0x05000000 + + /* Additional symbol types for Thumb */ +-#define STT_ARM_TFUNC 0xd ++#define STT_ARM_TFUNC STT_LOPROC /* A Thumb function. */ ++#define STT_ARM_16BIT STT_HIPROC /* A Thumb label. */ + + /* ARM-specific values for sh_flags */ + #define SHF_ARM_ENTRYSECT 0x10000000 /* Section contains an entry point */ +@@ -2038,6 +2050,17 @@ typedef Elf32_Addr Elf32_Conflict; + /* ARM-specific program header flags */ + #define PF_ARM_SB 0x10000000 /* Segment contains the location + addressed by the static base */ ++#define PF_ARM_PI 0x20000000 /* Position-independent segment. */ ++#define PF_ARM_ABS 0x40000000 /* Absolute segment. */ ++ ++/* Processor specific values for the Phdr p_type field. */ ++#define PT_ARM_EXIDX (PT_LOPROC + 1) /* ARM unwind segment. */ ++ ++/* Processor specific values for the Shdr sh_type field. */ ++#define SHT_ARM_EXIDX (SHT_LOPROC + 1) /* ARM unwind section. */ ++#define SHT_ARM_PREEMPTMAP (SHT_LOPROC + 2) /* Preemption details. */ ++#define SHT_ARM_ATTRIBUTES (SHT_LOPROC + 3) /* ARM attributes section. */ ++ + + /* ARM relocs. */ + #define R_ARM_NONE 0 /* No reloc */ +@@ -2050,7 +2073,7 @@ typedef Elf32_Addr Elf32_Conflict; + #define R_ARM_THM_ABS5 7 + #define R_ARM_ABS8 8 /* Direct 8 bit */ + #define R_ARM_SBREL32 9 +-#define R_ARM_THM_PC22 10 ++#define R_ARM_THM_CALL 10 + #define R_ARM_THM_PC8 11 + #define R_ARM_AMP_VCALL9 12 + #define R_ARM_SWI24 13 +@@ -2065,16 +2088,36 @@ typedef Elf32_Addr Elf32_Conflict; + #define R_ARM_GOTPC 25 /* 32 bit PC relative offset to GOT */ + #define R_ARM_GOT32 26 /* 32 bit GOT entry */ + #define R_ARM_PLT32 27 /* 32 bit PLT address */ ++#define R_ARM_CALL 28 ++#define R_ARM_JUMP24 29 ++#define R_ARM_THM_JUMP24 30 ++#define R_ARM_BASE_ABS 31 + #define R_ARM_ALU_PCREL_7_0 32 + #define R_ARM_ALU_PCREL_15_8 33 + #define R_ARM_ALU_PCREL_23_15 34 + #define R_ARM_LDR_SBREL_11_0 35 + #define R_ARM_ALU_SBREL_19_12 36 + #define R_ARM_ALU_SBREL_27_20 37 ++#define R_ARM_TLS_GOTDESC 90 ++#define R_ARM_TLS_CALL 91 ++#define R_ARM_TLS_DESCSEQ 92 ++#define R_ARM_THM_TLS_CALL 93 + #define R_ARM_GNU_VTENTRY 100 + #define R_ARM_GNU_VTINHERIT 101 + #define R_ARM_THM_PC11 102 /* thumb unconditional branch */ + #define R_ARM_THM_PC9 103 /* thumb conditional branch */ ++#define R_ARM_TLS_GD32 104 /* PC-rel 32 bit for global dynamic ++ thread local data */ ++#define R_ARM_TLS_LDM32 105 /* PC-rel 32 bit for local dynamic ++ thread local data */ ++#define R_ARM_TLS_LDO32 106 /* 32 bit offset relative to TLS ++ block */ ++#define R_ARM_TLS_IE32 107 /* PC-rel 32 bit for GOT entry of ++ static TLS block offset */ ++#define R_ARM_TLS_LE32 108 /* 32 bit offset relative to static ++ TLS block */ ++#define R_ARM_THM_TLS_DESCSEQ 129 ++#define R_ARM_IRELATIVE 160 + #define R_ARM_RXPC25 249 + #define R_ARM_RSBREL32 250 + #define R_ARM_THM_RPC22 251 +-- +1.8.1.4 + diff --git a/0121-conf-Makefile.common-Fix-autogen-rules-to-pass-defin.patch b/0121-conf-Makefile.common-Fix-autogen-rules-to-pass-defin.patch new file mode 100644 index 0000000..35aa12e --- /dev/null +++ b/0121-conf-Makefile.common-Fix-autogen-rules-to-pass-defin.patch @@ -0,0 +1,48 @@ +From e07d75a6383eee9001fe03500dea921ca257bbf7 Mon Sep 17 00:00:00 2001 +From: Andrey Borzenkov +Date: Sun, 20 Jan 2013 23:44:42 +0100 +Subject: [PATCH 121/364] * conf/Makefile.common: Fix autogen rules to + pass definition files on stdin; Makefile.util.am needs + Makefile.utilgcry.def + +--- + ChangeLog | 5 +++++ + conf/Makefile.common | 6 +++--- + 2 files changed, 8 insertions(+), 3 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index e82ee8d..4c21ea0 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,8 @@ ++2013-01-20 Andrey Borzenkov ++ ++ * conf/Makefile.common: Fix autogen rules to pass definition ++ files on stdin; Makefile.util.am needs Makefile.utilgcry.def ++ + 2013-01-20 Leif Lindholm + + * include/grub/elf.h: Update ARM definitions based on binutils. +diff --git a/conf/Makefile.common b/conf/Makefile.common +index 5b9cd92..75c0a5e 100644 +--- a/conf/Makefile.common ++++ b/conf/Makefile.common +@@ -169,12 +169,12 @@ $(top_srcdir)/Makefile.tpl: $(top_srcdir)/gentpl.py + mv $@.new $@ + + .PRECIOUS: $(top_srcdir)/Makefile.util.am +-$(top_srcdir)/Makefile.util.am: $(top_srcdir)/Makefile.util.def $(top_srcdir)/Makefile.tpl +- autogen -T $(top_srcdir)/Makefile.tpl $< | sed -e '/^$$/{N;/^\\n$$/D;}' > $@.new || (rm -f $@.new; exit 1) ++$(top_srcdir)/Makefile.util.am: $(top_srcdir)/Makefile.util.def $(top_srcdir)/Makefile.utilgcry.def $(top_srcdir)/Makefile.tpl ++ cat $(top_srcdir)/Makefile.util.def $(top_srcdir)/Makefile.utilgcry.def | autogen -T $(top_srcdir)/Makefile.tpl | sed -e '/^$$/{N;/^\\n$$/D;}' > $@.new || (rm -f $@.new; exit 1) + mv $@.new $@ + + .PRECIOUS: $(top_srcdir)/grub-core/Makefile.core.am + $(top_srcdir)/grub-core/Makefile.core.am: $(top_srcdir)/grub-core/Makefile.core.def $(top_srcdir)/grub-core/Makefile.gcry.def $(top_srcdir)/Makefile.tpl + if [ "x$$GRUB_CONTRIB" != x ]; then echo "You need to run ./autogen.sh manually." >&2; exit 1; fi +- autogen -T $(top_srcdir)/Makefile.tpl $(top_srcdir)/grub-core/Makefile.core.def $(top_srcdir)/grub-core/Makefile.gcry.def | sed -e '/^$$/{N;/^\\n$$/D;}' > $@.new || (rm -f $@.new; exit 1) ++ cat $(top_srcdir)/grub-core/Makefile.core.def $(top_srcdir)/grub-core/Makefile.gcry.def | autogen -T $(top_srcdir)/Makefile.tpl | sed -e '/^$$/{N;/^\\n$$/D;}' > $@.new || (rm -f $@.new; exit 1) + mv $@.new $@ +-- +1.8.1.4 + diff --git a/0122-grub-core-loader-i386-linux.c-grub_cmd_initrd-Don-t-.patch b/0122-grub-core-loader-i386-linux.c-grub_cmd_initrd-Don-t-.patch new file mode 100644 index 0000000..66f3f6c --- /dev/null +++ b/0122-grub-core-loader-i386-linux.c-grub_cmd_initrd-Don-t-.patch @@ -0,0 +1,43 @@ +From 092f6d440ed6015b5216e4eda1e8adeb9922d064 Mon Sep 17 00:00:00 2001 +From: Colin Watson +Date: Sun, 20 Jan 2013 23:03:35 +0000 +Subject: [PATCH 122/364] * grub-core/loader/i386/linux.c (grub_cmd_initrd): + Don't add the initrd size to addr_min, since the initrd will be allocated + after this address. + +--- + ChangeLog | 6 ++++++ + grub-core/loader/i386/linux.c | 3 +-- + 2 files changed, 7 insertions(+), 2 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 4c21ea0..6886f29 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,9 @@ ++2013-01-20 Colin Watson ++ ++ * grub-core/loader/i386/linux.c (grub_cmd_initrd): Don't add the ++ initrd size to addr_min, since the initrd will be allocated after ++ this address. ++ + 2013-01-20 Andrey Borzenkov + + * conf/Makefile.common: Fix autogen rules to pass definition +diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c +index 41357a5..92cabfb 100644 +--- a/grub-core/loader/i386/linux.c ++++ b/grub-core/loader/i386/linux.c +@@ -1115,8 +1115,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), + worse than that of Linux 2.3.xx, so avoid the last 64kb. */ + addr_max -= 0x10000; + +- addr_min = (grub_addr_t) prot_mode_target + prot_init_space +- + page_align (size); ++ addr_min = (grub_addr_t) prot_mode_target + prot_init_space; + + /* Put the initrd as high as possible, 4KiB aligned. */ + addr = (addr_max - size) & ~0xFFF; +-- +1.8.1.4 + diff --git a/0123-util-grub-mkimage.c-main-Postpone-freeing-arguments..patch b/0123-util-grub-mkimage.c-main-Postpone-freeing-arguments..patch new file mode 100644 index 0000000..0384809 --- /dev/null +++ b/0123-util-grub-mkimage.c-main-Postpone-freeing-arguments..patch @@ -0,0 +1,48 @@ +From 1696cf18731d8be3262fb35137dc9b463caf6c4f Mon Sep 17 00:00:00 2001 +From: Leif Lindholm +Date: Sun, 20 Jan 2013 23:16:34 +0000 +Subject: [PATCH 123/364] * util/grub-mkimage.c (main): Postpone freeing + arguments.output until after its use in generate_image. + +--- + ChangeLog | 5 +++++ + util/grub-mkimage.c | 4 +++- + 2 files changed, 8 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index 6886f29..10c094b 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,8 @@ ++2013-01-20 Leif Lindholm ++ ++ * util/grub-mkimage.c (main): Postpone freeing arguments.output ++ until after its use in generate_image. ++ + 2013-01-20 Colin Watson + + * grub-core/loader/i386/linux.c (grub_cmd_initrd): Don't add the +diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c +index d0eecf2..29bda17 100644 +--- a/util/grub-mkimage.c ++++ b/util/grub-mkimage.c +@@ -1905,7 +1905,6 @@ main (int argc, char *argv[]) + if (! fp) + grub_util_error (_("cannot open `%s': %s"), arguments.output, + strerror (errno)); +- free (arguments.output); + } + + if (!arguments.dir) +@@ -1933,5 +1932,8 @@ main (int argc, char *argv[]) + if (arguments.dir) + free (arguments.dir); + ++ if (arguments.output) ++ free (arguments.output); ++ + return 0; + } +-- +1.8.1.4 + diff --git a/0124-docs-grub.texi-Multi-boot-manual-config-Fix-typo-for.patch b/0124-docs-grub.texi-Multi-boot-manual-config-Fix-typo-for.patch new file mode 100644 index 0000000..bd07ee9 --- /dev/null +++ b/0124-docs-grub.texi-Multi-boot-manual-config-Fix-typo-for.patch @@ -0,0 +1,40 @@ +From f65b9f8567fcad44f9dbcedba0a5e03a9ddaa70d Mon Sep 17 00:00:00 2001 +From: Colin Watson +Date: Mon, 21 Jan 2013 00:05:41 +0000 +Subject: [PATCH 124/364] * docs/grub.texi (Multi-boot manual config): Fix typo + for "recommended". + +--- + ChangeLog | 5 +++++ + docs/grub.texi | 2 +- + 2 files changed, 6 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index 10c094b..afc2d38 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,8 @@ ++2013-01-21 Colin Watson ++ ++ * docs/grub.texi (Multi-boot manual config): Fix typo for ++ "recommended". ++ + 2013-01-20 Leif Lindholm + + * util/grub-mkimage.c (main): Postpone freeing arguments.output +diff --git a/docs/grub.texi b/docs/grub.texi +index fbbcfb9..b177111 100644 +--- a/docs/grub.texi ++++ b/docs/grub.texi +@@ -1657,7 +1657,7 @@ menuentry "Debian sid installer" @{ + + Notes: + @itemize +-@item Argument to search after --label is FS LABEL. You can also use UUIDs with --fs-uuid UUID instead of --label LABEL. You could also use direct @code{root=hd0,msdosX} but this is not recommened due to device name instability. ++@item Argument to search after --label is FS LABEL. You can also use UUIDs with --fs-uuid UUID instead of --label LABEL. You could also use direct @code{root=hd0,msdosX} but this is not recommended due to device name instability. + @end itemize + + @node Embedded configuration +-- +1.8.1.4 + diff --git a/0125-Remove-nested-functions-from-filesystem-directory-it.patch b/0125-Remove-nested-functions-from-filesystem-directory-it.patch new file mode 100644 index 0000000..064a4b7 --- /dev/null +++ b/0125-Remove-nested-functions-from-filesystem-directory-it.patch @@ -0,0 +1,4777 @@ +From 2bef9aff563a9d988b8203e53d715890c7ca9095 Mon Sep 17 00:00:00 2001 +From: Colin Watson +Date: Mon, 21 Jan 2013 01:33:46 +0000 +Subject: [PATCH 125/364] Remove nested functions from filesystem directory + iterators. + +* include/grub/fs.h (grub_fs_dir_hook_t): New type. +(struct grub_fs.dir): Add hook_data argument. + +Update all implementations and callers. +--- + ChangeLog | 9 + + grub-core/commands/ls.c | 204 +++++++++++---------- + grub-core/commands/test.c | 305 ++++++++++++++++--------------- + grub-core/commands/wildcard.c | 158 +++++++++------- + grub-core/fs/affs.c | 201 ++++++++++---------- + grub-core/fs/bfs.c | 95 ++++++---- + grub-core/fs/btrfs.c | 5 +- + grub-core/fs/cpio.c | 5 +- + grub-core/fs/ext2.c | 91 ++++----- + grub-core/fs/fat.c | 16 +- + grub-core/fs/fshelp.c | 307 ++++++++++++++++--------------- + grub-core/fs/hfs.c | 9 +- + grub-core/fs/hfsplus.c | 60 +++--- + grub-core/fs/iso9660.c | 54 +++--- + grub-core/fs/jfs.c | 5 +- + grub-core/fs/minix.c | 5 +- + grub-core/fs/nilfs2.c | 90 ++++----- + grub-core/fs/ntfs.c | 67 +++---- + grub-core/fs/reiserfs.c | 54 +++--- + grub-core/fs/romfs.c | 51 +++--- + grub-core/fs/sfs.c | 137 +++++++------- + grub-core/fs/squash4.c | 57 +++--- + grub-core/fs/udf.c | 109 +++++------ + grub-core/fs/ufs.c | 5 +- + grub-core/fs/xfs.c | 140 +++++++------- + grub-core/fs/zfs/zfs.c | 416 +++++++++++++++++++++++------------------- + grub-core/kern/corecmd.c | 5 +- + grub-core/kern/emu/hostfs.c | 5 +- + grub-core/kern/fs.c | 13 +- + grub-core/loader/xnu.c | 205 ++++++++++++--------- + grub-core/net/net.c | 4 +- + grub-core/normal/completion.c | 5 +- + include/grub/fs.h | 7 +- + include/grub/fshelp.h | 15 +- + util/grub-mount.c | 142 ++++++++------ + 35 files changed, 1664 insertions(+), 1392 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index afc2d38..c975de1 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,14 @@ + 2013-01-21 Colin Watson + ++ Remove nested functions from filesystem directory iterators. ++ ++ * include/grub/fs.h (grub_fs_dir_hook_t): New type. ++ (struct grub_fs.dir): Add hook_data argument. ++ ++ Update all implementations and callers. ++ ++2013-01-21 Colin Watson ++ + * docs/grub.texi (Multi-boot manual config): Fix typo for + "recommended". + +diff --git a/grub-core/commands/ls.c b/grub-core/commands/ls.c +index 7929747..0b86619 100644 +--- a/grub-core/commands/ls.c ++++ b/grub-core/commands/ls.c +@@ -85,114 +85,126 @@ grub_ls_list_devices (int longlist) + return 0; + } + +-static grub_err_t +-grub_ls_list_files (char *dirname, int longlist, int all, int human) ++/* Context for grub_ls_list_files. */ ++struct grub_ls_list_files_ctx + { +- char *device_name; +- grub_fs_t fs; +- const char *path; +- grub_device_t dev; ++ char *dirname; ++ int all; ++ int human; ++}; ++ ++/* Helper for grub_ls_list_files. */ ++static int ++print_files (const char *filename, const struct grub_dirhook_info *info, ++ void *data) ++{ ++ struct grub_ls_list_files_ctx *ctx = data; + +- auto int print_files (const char *filename, +- const struct grub_dirhook_info *info); +- auto int print_files_long (const char *filename, +- const struct grub_dirhook_info *info); ++ if (ctx->all || filename[0] != '.') ++ grub_printf ("%s%s ", filename, info->dir ? "/" : ""); + +- int print_files (const char *filename, const struct grub_dirhook_info *info) +- { +- if (all || filename[0] != '.') +- grub_printf ("%s%s ", filename, info->dir ? "/" : ""); ++ return 0; ++} + +- return 0; +- } ++/* Helper for grub_ls_list_files. */ ++static int ++print_files_long (const char *filename, const struct grub_dirhook_info *info, ++ void *data) ++{ ++ struct grub_ls_list_files_ctx *ctx = data; ++ ++ if ((! ctx->all) && (filename[0] == '.')) ++ return 0; + +- int print_files_long (const char *filename, +- const struct grub_dirhook_info *info) ++ if (! info->dir) + { +- if ((! all) && (filename[0] == '.')) +- return 0; ++ grub_file_t file; ++ char *pathname; + +- if (! info->dir) +- { +- grub_file_t file; +- char *pathname; ++ if (ctx->dirname[grub_strlen (ctx->dirname) - 1] == '/') ++ pathname = grub_xasprintf ("%s%s", ctx->dirname, filename); ++ else ++ pathname = grub_xasprintf ("%s/%s", ctx->dirname, filename); + +- if (dirname[grub_strlen (dirname) - 1] == '/') +- pathname = grub_xasprintf ("%s%s", dirname, filename); +- else +- pathname = grub_xasprintf ("%s/%s", dirname, filename); ++ if (!pathname) ++ return 1; + +- if (!pathname) +- return 1; ++ /* XXX: For ext2fs symlinks are detected as files while they ++ should be reported as directories. */ ++ grub_file_filter_disable_compression (); ++ file = grub_file_open (pathname); ++ if (! file) ++ { ++ grub_errno = 0; ++ grub_free (pathname); ++ return 0; ++ } + +- /* XXX: For ext2fs symlinks are detected as files while they +- should be reported as directories. */ +- grub_file_filter_disable_compression (); +- file = grub_file_open (pathname); +- if (! file) ++ if (! ctx->human) ++ grub_printf ("%-12llu", (unsigned long long) file->size); ++ else ++ { ++ grub_uint64_t fsize = file->size * 100ULL; ++ grub_uint64_t fsz = file->size; ++ int units = 0; ++ char buf[20]; ++ ++ while (fsz / 1024) + { +- grub_errno = 0; +- grub_free (pathname); +- return 0; ++ fsize = (fsize + 512) / 1024; ++ fsz /= 1024; ++ units++; + } + +- if (! human) +- grub_printf ("%-12llu", (unsigned long long) file->size); +- else ++ if (units) + { +- grub_uint64_t fsize = file->size * 100ULL; +- grub_uint64_t fsz = file->size; +- int units = 0; +- char buf[20]; +- +- while (fsz / 1024) +- { +- fsize = (fsize + 512) / 1024; +- fsz /= 1024; +- units++; +- } +- +- if (units) +- { +- grub_uint64_t whole, fraction; +- +- whole = grub_divmod64 (fsize, 100, &fraction); +- grub_snprintf (buf, sizeof (buf), +- "%" PRIuGRUB_UINT64_T +- ".%02" PRIuGRUB_UINT64_T "%c", whole, fraction, +- grub_human_sizes[units]); +- grub_printf ("%-12s", buf); +- } +- else +- grub_printf ("%-12llu", (unsigned long long) file->size); +- ++ grub_uint64_t whole, fraction; ++ ++ whole = grub_divmod64 (fsize, 100, &fraction); ++ grub_snprintf (buf, sizeof (buf), ++ "%" PRIuGRUB_UINT64_T ++ ".%02" PRIuGRUB_UINT64_T "%c", whole, fraction, ++ grub_human_sizes[units]); ++ grub_printf ("%-12s", buf); + } +- grub_file_close (file); +- grub_free (pathname); +- } +- else +- grub_printf ("%-12s", _("DIR")); +- +- if (info->mtimeset) +- { +- struct grub_datetime datetime; +- grub_unixtime2datetime (info->mtime, &datetime); +- if (human) +- grub_printf (" %d-%02d-%02d %02d:%02d:%02d %-11s ", +- datetime.year, datetime.month, datetime.day, +- datetime.hour, datetime.minute, +- datetime.second, +- grub_get_weekday_name (&datetime)); + else +- grub_printf (" %04d%02d%02d%02d%02d%02d ", +- datetime.year, datetime.month, +- datetime.day, datetime.hour, +- datetime.minute, datetime.second); ++ grub_printf ("%-12llu", (unsigned long long) file->size); ++ + } +- grub_printf ("%s%s\n", filename, info->dir ? "/" : ""); ++ grub_file_close (file); ++ grub_free (pathname); ++ } ++ else ++ grub_printf ("%-12s", _("DIR")); + +- return 0; ++ if (info->mtimeset) ++ { ++ struct grub_datetime datetime; ++ grub_unixtime2datetime (info->mtime, &datetime); ++ if (ctx->human) ++ grub_printf (" %d-%02d-%02d %02d:%02d:%02d %-11s ", ++ datetime.year, datetime.month, datetime.day, ++ datetime.hour, datetime.minute, ++ datetime.second, ++ grub_get_weekday_name (&datetime)); ++ else ++ grub_printf (" %04d%02d%02d%02d%02d%02d ", ++ datetime.year, datetime.month, ++ datetime.day, datetime.hour, ++ datetime.minute, datetime.second); + } ++ grub_printf ("%s%s\n", filename, info->dir ? "/" : ""); ++ ++ return 0; ++} ++ ++static grub_err_t ++grub_ls_list_files (char *dirname, int longlist, int all, int human) ++{ ++ char *device_name; ++ grub_fs_t fs; ++ const char *path; ++ grub_device_t dev; + + device_name = grub_file_get_device_name (dirname); + dev = grub_device_open (device_name); +@@ -221,10 +233,16 @@ grub_ls_list_files (char *dirname, int longlist, int all, int human) + } + else if (fs) + { ++ struct grub_ls_list_files_ctx ctx = { ++ .dirname = dirname, ++ .all = all, ++ .human = human ++ }; ++ + if (longlist) +- (fs->dir) (dev, path, print_files_long); ++ (fs->dir) (dev, path, print_files_long, &ctx); + else +- (fs->dir) (dev, path, print_files); ++ (fs->dir) (dev, path, print_files, &ctx); + + if (grub_errno == GRUB_ERR_BAD_FILE_TYPE + && path[grub_strlen (path) - 1] != '/') +@@ -250,9 +268,9 @@ grub_ls_list_files (char *dirname, int longlist, int all, int human) + all = 1; + grub_memset (&info, 0, sizeof (info)); + if (longlist) +- print_files_long (p, &info); ++ print_files_long (p, &info, &ctx); + else +- print_files (p, &info); ++ print_files (p, &info, &ctx); + + grub_free (dirname); + } +diff --git a/grub-core/commands/test.c b/grub-core/commands/test.c +index 3a0e0e0..e3347ee 100644 +--- a/grub-core/commands/test.c ++++ b/grub-core/commands/test.c +@@ -38,114 +38,125 @@ grub_strtosl (char *arg, char **end, int base) + return grub_strtoul (arg, end, base); + } + +-/* Parse a test expression starting from *argn. */ +-static int +-test_parse (char **args, int *argn, int argc) ++/* Context for test_parse. */ ++struct test_parse_ctx + { +- int ret = 0, discard = 0, invert = 0; ++ int ret, discard, invert; + int file_exists; + struct grub_dirhook_info file_info; ++ char *filename; ++}; ++ ++/* Take care of discarding and inverting. */ ++static void ++update_val (int val, struct test_parse_ctx *ctx) ++{ ++ if (! ctx->discard) ++ ctx->ret = ctx->invert ? ! val : val; ++ ctx->invert = ctx->discard = 0; ++} ++ ++/* A hook for iterating directories. */ ++static int ++find_file (const char *cur_filename, const struct grub_dirhook_info *info, ++ void *data) ++{ ++ struct test_parse_ctx *ctx = data; ++ ++ if ((info->case_insensitive ? grub_strcasecmp (cur_filename, ctx->filename) ++ : grub_strcmp (cur_filename, ctx->filename)) == 0) ++ { ++ ctx->file_info = *info; ++ ctx->file_exists = 1; ++ return 1; ++ } ++ return 0; ++} ++ ++/* Check if file exists and fetch its information. */ ++static void ++get_fileinfo (char *path, struct test_parse_ctx *ctx) ++{ ++ char *pathname; ++ char *device_name; ++ grub_fs_t fs; ++ grub_device_t dev; ++ ++ ctx->file_exists = 0; ++ device_name = grub_file_get_device_name (path); ++ dev = grub_device_open (device_name); ++ if (! dev) ++ { ++ grub_free (device_name); ++ return; ++ } + +- auto void update_val (int val); +- auto void get_fileinfo (char *pathname); +- +- /* Take care of discarding and inverting. */ +- void update_val (int val) +- { +- if (! discard) +- ret = invert ? ! val : val; +- invert = discard = 0; +- } +- +- /* Check if file exists and fetch its information. */ +- void get_fileinfo (char *path) +- { +- char *filename, *pathname; +- char *device_name; +- grub_fs_t fs; +- grub_device_t dev; +- +- /* A hook for iterating directories. */ +- auto int find_file (const char *cur_filename, +- const struct grub_dirhook_info *info); +- int find_file (const char *cur_filename, +- const struct grub_dirhook_info *info) ++ fs = grub_fs_probe (dev); ++ if (! fs) + { +- if ((info->case_insensitive ? grub_strcasecmp (cur_filename, filename) +- : grub_strcmp (cur_filename, filename)) == 0) ++ grub_free (device_name); ++ grub_device_close (dev); ++ return; ++ } ++ ++ pathname = grub_strchr (path, ')'); ++ if (! pathname) ++ pathname = path; ++ else ++ pathname++; ++ ++ /* Remove trailing '/'. */ ++ while (*pathname && pathname[grub_strlen (pathname) - 1] == '/') ++ pathname[grub_strlen (pathname) - 1] = 0; ++ ++ /* Split into path and filename. */ ++ ctx->filename = grub_strrchr (pathname, '/'); ++ if (! ctx->filename) ++ { ++ path = grub_strdup ("/"); ++ ctx->filename = pathname; ++ } ++ else ++ { ++ ctx->filename++; ++ path = grub_strdup (pathname); ++ path[ctx->filename - pathname] = 0; ++ } ++ ++ /* It's the whole device. */ ++ if (! *pathname) ++ { ++ ctx->file_exists = 1; ++ grub_memset (&ctx->file_info, 0, sizeof (ctx->file_info)); ++ /* Root is always a directory. */ ++ ctx->file_info.dir = 1; ++ ++ /* Fetch writing time. */ ++ ctx->file_info.mtimeset = 0; ++ if (fs->mtime) + { +- file_info = *info; +- file_exists = 1; +- return 1; ++ if (! fs->mtime (dev, &ctx->file_info.mtime)) ++ ctx->file_info.mtimeset = 1; ++ grub_errno = GRUB_ERR_NONE; + } +- return 0; + } ++ else ++ (fs->dir) (dev, path, find_file, ctx); ++ ++ grub_device_close (dev); ++ grub_free (path); ++ grub_free (device_name); ++} + +- file_exists = 0; +- device_name = grub_file_get_device_name (path); +- dev = grub_device_open (device_name); +- if (! dev) +- { +- grub_free (device_name); +- return; +- } +- +- fs = grub_fs_probe (dev); +- if (! fs) +- { +- grub_free (device_name); +- grub_device_close (dev); +- return; +- } +- +- pathname = grub_strchr (path, ')'); +- if (! pathname) +- pathname = path; +- else +- pathname++; +- +- /* Remove trailing '/'. */ +- while (*pathname && pathname[grub_strlen (pathname) - 1] == '/') +- pathname[grub_strlen (pathname) - 1] = 0; +- +- /* Split into path and filename. */ +- filename = grub_strrchr (pathname, '/'); +- if (! filename) +- { +- path = grub_strdup ("/"); +- filename = pathname; +- } +- else +- { +- filename++; +- path = grub_strdup (pathname); +- path[filename - pathname] = 0; +- } +- +- /* It's the whole device. */ +- if (! *pathname) +- { +- file_exists = 1; +- grub_memset (&file_info, 0, sizeof (file_info)); +- /* Root is always a directory. */ +- file_info.dir = 1; +- +- /* Fetch writing time. */ +- file_info.mtimeset = 0; +- if (fs->mtime) +- { +- if (! fs->mtime (dev, &file_info.mtime)) +- file_info.mtimeset = 1; +- grub_errno = GRUB_ERR_NONE; +- } +- } +- else +- (fs->dir) (dev, path, find_file); +- +- grub_device_close (dev); +- grub_free (path); +- grub_free (device_name); +- } ++/* Parse a test expression starting from *argn. */ ++static int ++test_parse (char **args, int *argn, int argc) ++{ ++ struct test_parse_ctx ctx = { ++ .ret = 0, ++ .discard = 0, ++ .invert = 0 ++ }; + + /* Here we have the real parsing. */ + while (*argn < argc) +@@ -157,14 +168,16 @@ test_parse (char **args, int *argn, int argc) + if (grub_strcmp (args[*argn + 1], "=") == 0 + || grub_strcmp (args[*argn + 1], "==") == 0) + { +- update_val (grub_strcmp (args[*argn], args[*argn + 2]) == 0); ++ update_val (grub_strcmp (args[*argn], args[*argn + 2]) == 0, ++ &ctx); + (*argn) += 3; + continue; + } + + if (grub_strcmp (args[*argn + 1], "!=") == 0) + { +- update_val (grub_strcmp (args[*argn], args[*argn + 2]) != 0); ++ update_val (grub_strcmp (args[*argn], args[*argn + 2]) != 0, ++ &ctx); + (*argn) += 3; + continue; + } +@@ -172,28 +185,32 @@ test_parse (char **args, int *argn, int argc) + /* GRUB extension: lexicographical sorting. */ + if (grub_strcmp (args[*argn + 1], "<") == 0) + { +- update_val (grub_strcmp (args[*argn], args[*argn + 2]) < 0); ++ update_val (grub_strcmp (args[*argn], args[*argn + 2]) < 0, ++ &ctx); + (*argn) += 3; + continue; + } + + if (grub_strcmp (args[*argn + 1], "<=") == 0) + { +- update_val (grub_strcmp (args[*argn], args[*argn + 2]) <= 0); ++ update_val (grub_strcmp (args[*argn], args[*argn + 2]) <= 0, ++ &ctx); + (*argn) += 3; + continue; + } + + if (grub_strcmp (args[*argn + 1], ">") == 0) + { +- update_val (grub_strcmp (args[*argn], args[*argn + 2]) > 0); ++ update_val (grub_strcmp (args[*argn], args[*argn + 2]) > 0, ++ &ctx); + (*argn) += 3; + continue; + } + + if (grub_strcmp (args[*argn + 1], ">=") == 0) + { +- update_val (grub_strcmp (args[*argn], args[*argn + 2]) >= 0); ++ update_val (grub_strcmp (args[*argn], args[*argn + 2]) >= 0, ++ &ctx); + (*argn) += 3; + continue; + } +@@ -202,7 +219,7 @@ test_parse (char **args, int *argn, int argc) + if (grub_strcmp (args[*argn + 1], "-eq") == 0) + { + update_val (grub_strtosl (args[*argn], 0, 0) +- == grub_strtosl (args[*argn + 2], 0, 0)); ++ == grub_strtosl (args[*argn + 2], 0, 0), &ctx); + (*argn) += 3; + continue; + } +@@ -210,7 +227,7 @@ test_parse (char **args, int *argn, int argc) + if (grub_strcmp (args[*argn + 1], "-ge") == 0) + { + update_val (grub_strtosl (args[*argn], 0, 0) +- >= grub_strtosl (args[*argn + 2], 0, 0)); ++ >= grub_strtosl (args[*argn + 2], 0, 0), &ctx); + (*argn) += 3; + continue; + } +@@ -218,7 +235,7 @@ test_parse (char **args, int *argn, int argc) + if (grub_strcmp (args[*argn + 1], "-gt") == 0) + { + update_val (grub_strtosl (args[*argn], 0, 0) +- > grub_strtosl (args[*argn + 2], 0, 0)); ++ > grub_strtosl (args[*argn + 2], 0, 0), &ctx); + (*argn) += 3; + continue; + } +@@ -226,7 +243,7 @@ test_parse (char **args, int *argn, int argc) + if (grub_strcmp (args[*argn + 1], "-le") == 0) + { + update_val (grub_strtosl (args[*argn], 0, 0) +- <= grub_strtosl (args[*argn + 2], 0, 0)); ++ <= grub_strtosl (args[*argn + 2], 0, 0), &ctx); + (*argn) += 3; + continue; + } +@@ -234,7 +251,7 @@ test_parse (char **args, int *argn, int argc) + if (grub_strcmp (args[*argn + 1], "-lt") == 0) + { + update_val (grub_strtosl (args[*argn], 0, 0) +- < grub_strtosl (args[*argn + 2], 0, 0)); ++ < grub_strtosl (args[*argn + 2], 0, 0), &ctx); + (*argn) += 3; + continue; + } +@@ -242,7 +259,7 @@ test_parse (char **args, int *argn, int argc) + if (grub_strcmp (args[*argn + 1], "-ne") == 0) + { + update_val (grub_strtosl (args[*argn], 0, 0) +- != grub_strtosl (args[*argn + 2], 0, 0)); ++ != grub_strtosl (args[*argn + 2], 0, 0), &ctx); + (*argn) += 3; + continue; + } +@@ -265,10 +282,10 @@ test_parse (char **args, int *argn, int argc) + + if (grub_strcmp (args[*argn + 1], "-pgt") == 0) + update_val (grub_strtoul (args[*argn] + i, 0, 0) +- > grub_strtoul (args[*argn + 2] + i, 0, 0)); ++ > grub_strtoul (args[*argn + 2] + i, 0, 0), &ctx); + else + update_val (grub_strtoul (args[*argn] + i, 0, 0) +- < grub_strtoul (args[*argn + 2] + i, 0, 0)); ++ < grub_strtoul (args[*argn + 2] + i, 0, 0), &ctx); + (*argn) += 3; + continue; + } +@@ -283,22 +300,24 @@ test_parse (char **args, int *argn, int argc) + int bias = 0; + + /* Fetch fileinfo. */ +- get_fileinfo (args[*argn]); +- file1 = file_info; +- file1exists = file_exists; +- get_fileinfo (args[*argn + 2]); ++ get_fileinfo (args[*argn], &ctx); ++ file1 = ctx.file_info; ++ file1exists = ctx.file_exists; ++ get_fileinfo (args[*argn + 2], &ctx); + + if (args[*argn + 1][3]) + bias = grub_strtosl (args[*argn + 1] + 3, 0, 0); + + if (grub_memcmp (args[*argn + 1], "-nt", 3) == 0) +- update_val ((file1exists && ! file_exists) +- || (file1.mtimeset && file_info.mtimeset +- && file1.mtime + bias > file_info.mtime)); ++ update_val ((file1exists && ! ctx.file_exists) ++ || (file1.mtimeset && ctx.file_info.mtimeset ++ && file1.mtime + bias > ctx.file_info.mtime), ++ &ctx); + else +- update_val ((! file1exists && file_exists) +- || (file1.mtimeset && file_info.mtimeset +- && file1.mtime + bias < file_info.mtime)); ++ update_val ((! file1exists && ctx.file_exists) ++ || (file1.mtimeset && ctx.file_info.mtimeset ++ && file1.mtime + bias < ctx.file_info.mtime), ++ &ctx); + (*argn) += 3; + continue; + } +@@ -310,27 +329,27 @@ test_parse (char **args, int *argn, int argc) + /* File tests. */ + if (grub_strcmp (args[*argn], "-d") == 0) + { +- get_fileinfo (args[*argn + 1]); +- update_val (file_exists && file_info.dir); ++ get_fileinfo (args[*argn + 1], &ctx); ++ update_val (ctx.file_exists && ctx.file_info.dir, &ctx); + (*argn) += 2; +- return ret; ++ return ctx.ret; + } + + if (grub_strcmp (args[*argn], "-e") == 0) + { +- get_fileinfo (args[*argn + 1]); +- update_val (file_exists); ++ get_fileinfo (args[*argn + 1], &ctx); ++ update_val (ctx.file_exists, &ctx); + (*argn) += 2; +- return ret; ++ return ctx.ret; + } + + if (grub_strcmp (args[*argn], "-f") == 0) + { +- get_fileinfo (args[*argn + 1]); ++ get_fileinfo (args[*argn + 1], &ctx); + /* FIXME: check for other types. */ +- update_val (file_exists && ! file_info.dir); ++ update_val (ctx.file_exists && ! ctx.file_info.dir, &ctx); + (*argn) += 2; +- return ret; ++ return ctx.ret; + } + + if (grub_strcmp (args[*argn], "-s") == 0) +@@ -338,25 +357,25 @@ test_parse (char **args, int *argn, int argc) + grub_file_t file; + grub_file_filter_disable_compression (); + file = grub_file_open (args[*argn + 1]); +- update_val (file && (grub_file_size (file) != 0)); ++ update_val (file && (grub_file_size (file) != 0), &ctx); + if (file) + grub_file_close (file); + grub_errno = GRUB_ERR_NONE; + (*argn) += 2; +- return ret; ++ return ctx.ret; + } + + /* String tests. */ + if (grub_strcmp (args[*argn], "-n") == 0) + { +- update_val (args[*argn + 1][0]); ++ update_val (args[*argn + 1][0], &ctx); + + (*argn) += 2; + continue; + } + if (grub_strcmp (args[*argn], "-z") == 0) + { +- update_val (! args[*argn + 1][0]); ++ update_val (! args[*argn + 1][0], &ctx); + (*argn) += 2; + continue; + } +@@ -368,42 +387,42 @@ test_parse (char **args, int *argn, int argc) + if (grub_strcmp (args[*argn], ")") == 0) + { + (*argn)++; +- return ret; ++ return ctx.ret; + } + /* Recursively invoke if parenthesis. */ + if (grub_strcmp (args[*argn], "(") == 0) + { + (*argn)++; +- update_val (test_parse (args, argn, argc)); ++ update_val (test_parse (args, argn, argc), &ctx); + continue; + } + + if (grub_strcmp (args[*argn], "!") == 0) + { +- invert = ! invert; ++ ctx.invert = ! ctx.invert; + (*argn)++; + continue; + } + if (grub_strcmp (args[*argn], "-a") == 0) + { + /* If current value is 0 second value is to be discarded. */ +- discard = ! ret; ++ ctx.discard = ! ctx.ret; + (*argn)++; + continue; + } + if (grub_strcmp (args[*argn], "-o") == 0) + { + /* If current value is 1 second value is to be discarded. */ +- discard = ret; ++ ctx.discard = ctx.ret; + (*argn)++; + continue; + } + + /* No test found. Interpret if as just a string. */ +- update_val (args[*argn][0]); ++ update_val (args[*argn][0], &ctx); + (*argn)++; + } +- return ret; ++ return ctx.ret; + } + + static grub_err_t +diff --git a/grub-core/commands/wildcard.c b/grub-core/commands/wildcard.c +index 633de51..2807f80 100644 +--- a/grub-core/commands/wildcard.c ++++ b/grub-core/commands/wildcard.c +@@ -279,63 +279,75 @@ match_devices (const regex_t *regexp, int noparts) + return 0; + } + +-static char ** +-match_files (const char *prefix, const char *suffix, const char *end, +- const regex_t *regexp) ++/* Context for match_files. */ ++struct match_files_ctx + { +- int i; ++ const regex_t *regexp; + char **files; + unsigned nfile; + char *dir; +- const char *path; +- char *device_name; +- grub_fs_t fs; +- grub_device_t dev; ++}; + +- auto int match (const char *name, const struct grub_dirhook_info *info); +- int match (const char *name, const struct grub_dirhook_info *info) +- { +- char **t; +- char *buffer; ++/* Helper for match_files. */ ++static int ++match_files_iter (const char *name, const struct grub_dirhook_info *info, ++ void *data) ++{ ++ struct match_files_ctx *ctx = data; ++ char **t; ++ char *buffer; + +- /* skip . and .. names */ +- if (grub_strcmp(".", name) == 0 || grub_strcmp("..", name) == 0) +- return 0; ++ /* skip . and .. names */ ++ if (grub_strcmp(".", name) == 0 || grub_strcmp("..", name) == 0) ++ return 0; + +- grub_dprintf ("expand", "matching: %s in %s\n", name, dir); +- if (regexec (regexp, name, 0, 0, 0)) +- return 0; ++ grub_dprintf ("expand", "matching: %s in %s\n", name, ctx->dir); ++ if (regexec (ctx->regexp, name, 0, 0, 0)) ++ return 0; + +- grub_dprintf ("expand", "matched\n"); ++ grub_dprintf ("expand", "matched\n"); + +- buffer = grub_xasprintf ("%s%s", dir, name); +- if (! buffer) ++ buffer = grub_xasprintf ("%s%s", ctx->dir, name); ++ if (! buffer) ++ return 1; ++ ++ t = grub_realloc (ctx->files, sizeof (char*) * (ctx->nfile + 2)); ++ if (! t) ++ { ++ grub_free (buffer); + return 1; ++ } + +- t = grub_realloc (files, sizeof (char*) * (nfile + 2)); +- if (! t) +- { +- grub_free (buffer); +- return 1; +- } ++ ctx->files = t; ++ ctx->files[ctx->nfile++] = buffer; ++ ctx->files[ctx->nfile] = 0; ++ return 0; ++} + +- files = t; +- files[nfile++] = buffer; +- files[nfile] = 0; +- return 0; +- } ++static char ** ++match_files (const char *prefix, const char *suffix, const char *end, ++ const regex_t *regexp) ++{ ++ struct match_files_ctx ctx = { ++ .regexp = regexp, ++ .nfile = 0, ++ .files = 0 ++ }; ++ int i; ++ const char *path; ++ char *device_name; ++ grub_fs_t fs; ++ grub_device_t dev; + +- nfile = 0; +- files = 0; + dev = 0; + device_name = 0; + grub_error_push (); + +- dir = make_dir (prefix, suffix, end); +- if (! dir) ++ ctx.dir = make_dir (prefix, suffix, end); ++ if (! ctx.dir) + goto fail; + +- device_name = grub_file_get_device_name (dir); ++ device_name = grub_file_get_device_name (ctx.dir); + dev = grub_device_open (device_name); + if (! dev) + goto fail; +@@ -344,33 +356,33 @@ match_files (const char *prefix, const char *suffix, const char *end, + if (! fs) + goto fail; + +- if (dir[0] == '(') ++ if (ctx.dir[0] == '(') + { +- path = grub_strchr (dir, ')'); ++ path = grub_strchr (ctx.dir, ')'); + if (!path) + goto fail; + path++; + } + else +- path = dir; ++ path = ctx.dir; + +- if (fs->dir (dev, path, match)) ++ if (fs->dir (dev, path, match_files_iter, &ctx)) + goto fail; + +- grub_free (dir); ++ grub_free (ctx.dir); + grub_device_close (dev); + grub_free (device_name); + grub_error_pop (); +- return files; ++ return ctx.files; + + fail: + +- grub_free (dir); ++ grub_free (ctx.dir); + +- for (i = 0; files && files[i]; i++) +- grub_free (files[i]); ++ for (i = 0; ctx.files && ctx.files[i]; i++) ++ grub_free (ctx.files[i]); + +- grub_free (files); ++ grub_free (ctx.files); + + if (dev) + grub_device_close (dev); +@@ -381,28 +393,42 @@ match_files (const char *prefix, const char *suffix, const char *end, + return 0; + } + ++/* Context for check_file. */ ++struct check_file_ctx ++{ ++ const char *basename; ++ int found; ++}; ++ ++/* Helper for check_file. */ ++static int ++check_file_iter (const char *name, const struct grub_dirhook_info *info, ++ void *data) ++{ ++ struct check_file_ctx *ctx = data; ++ ++ if (ctx->basename[0] == 0 ++ || (info->case_insensitive ? grub_strcasecmp (name, ctx->basename) == 0 ++ : grub_strcmp (name, ctx->basename) == 0)) ++ { ++ ctx->found = 1; ++ return 1; ++ } ++ ++ return 0; ++} ++ + static int + check_file (const char *dir, const char *basename) + { ++ struct check_file_ctx ctx = { ++ .basename = basename, ++ .found = 0 ++ }; + grub_fs_t fs; + grub_device_t dev; +- int found = 0; + const char *device_name, *path; + +- auto int match (const char *name, const struct grub_dirhook_info *info); +- int match (const char *name, const struct grub_dirhook_info *info) +- { +- if (basename[0] == 0 +- || (info->case_insensitive ? grub_strcasecmp (name, basename) == 0 +- : grub_strcmp (name, basename) == 0)) +- { +- found = 1; +- return 1; +- } +- +- return 0; +- } +- + device_name = grub_file_get_device_name (dir); + dev = grub_device_open (device_name); + if (! dev) +@@ -422,14 +448,14 @@ check_file (const char *dir, const char *basename) + else + path = dir; + +- fs->dir (dev, path[0] ? path : "/", match); ++ fs->dir (dev, path[0] ? path : "/", check_file_iter, &ctx); + if (grub_errno == 0 && basename[0] == 0) +- found = 1; ++ ctx.found = 1; + + fail: + grub_errno = 0; + +- return found; ++ return ctx.found; + } + + static void +diff --git a/grub-core/fs/affs.c b/grub-core/fs/affs.c +index 848a455..6c49e5d 100644 +--- a/grub-core/fs/affs.c ++++ b/grub-core/fs/affs.c +@@ -316,93 +316,93 @@ grub_affs_read_symlink (grub_fshelp_node_t node) + } + + ++/* Helper for grub_affs_iterate_dir. */ + static int +-grub_affs_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)) ++grub_affs_create_node (grub_fshelp_node_t dir, ++ grub_fshelp_iterate_dir_hook_t hook, void *hook_data, ++ struct grub_fshelp_node **node, ++ grub_uint32_t **hashtable, ++ grub_uint32_t block, const struct grub_affs_file *fil) + { +- unsigned int i; +- struct grub_affs_file file; +- struct grub_fshelp_node *node = 0; + struct grub_affs_data *data = dir->data; +- grub_uint32_t *hashtable; +- +- auto int NESTED_FUNC_ATTR grub_affs_create_node (grub_uint32_t block, +- const struct grub_affs_file *fil); ++ int type; ++ grub_uint8_t name_u8[sizeof (fil->name) * GRUB_MAX_UTF8_PER_LATIN1 + 1]; ++ grub_size_t len; ++ unsigned int nest; + +- int NESTED_FUNC_ATTR grub_affs_create_node (grub_uint32_t block, +- const struct grub_affs_file *fil) ++ *node = grub_zalloc (sizeof (**node)); ++ if (!*node) + { +- int type; +- grub_uint8_t name_u8[sizeof (fil->name) * GRUB_MAX_UTF8_PER_LATIN1 + 1]; +- grub_size_t len; +- unsigned int nest; +- +- node = grub_zalloc (sizeof (*node)); +- if (!node) +- { +- grub_free (hashtable); +- return 1; +- } ++ grub_free (*hashtable); ++ return 1; ++ } + +- node->data = data; +- node->block = block; +- node->parent = dir; +- +- len = fil->namelen; +- if (len > sizeof (fil->name)) +- len = sizeof (fil->name); +- *grub_latin1_to_utf8 (name_u8, fil->name, len) = '\0'; +- +- node->di = *fil; +- for (nest = 0; nest < 8; nest++) ++ (*node)->data = data; ++ (*node)->block = block; ++ (*node)->parent = dir; ++ ++ len = fil->namelen; ++ if (len > sizeof (fil->name)) ++ len = sizeof (fil->name); ++ *grub_latin1_to_utf8 (name_u8, fil->name, len) = '\0'; ++ ++ (*node)->di = *fil; ++ for (nest = 0; nest < 8; nest++) ++ { ++ switch ((*node)->di.type) + { +- switch (node->di.type) +- { +- case grub_cpu_to_be32_compile_time (GRUB_AFFS_FILETYPE_REG): +- type = GRUB_FSHELP_REG; +- break; +- case grub_cpu_to_be32_compile_time (GRUB_AFFS_FILETYPE_DIR): +- type = GRUB_FSHELP_DIR; +- break; +- case grub_cpu_to_be32_compile_time (GRUB_AFFS_FILETYPE_SYMLINK): +- type = GRUB_FSHELP_SYMLINK; +- break; +- case grub_cpu_to_be32_compile_time (GRUB_AFFS_FILETYPE_HARDLINK): +- { +- grub_err_t err; +- node->block = grub_be_to_cpu32 (node->di.hardlink); +- err = grub_disk_read (data->disk, +- (((grub_uint64_t) node->block + 1) << data->log_blocksize) +- - 1, +- GRUB_DISK_SECTOR_SIZE - GRUB_AFFS_FILE_LOCATION, +- sizeof (node->di), (char *) &node->di); +- if (err) +- return 1; +- continue; +- } +- default: +- return 0; +- } ++ case grub_cpu_to_be32_compile_time (GRUB_AFFS_FILETYPE_REG): ++ type = GRUB_FSHELP_REG; ++ break; ++ case grub_cpu_to_be32_compile_time (GRUB_AFFS_FILETYPE_DIR): ++ type = GRUB_FSHELP_DIR; ++ break; ++ case grub_cpu_to_be32_compile_time (GRUB_AFFS_FILETYPE_SYMLINK): ++ type = GRUB_FSHELP_SYMLINK; + break; ++ case grub_cpu_to_be32_compile_time (GRUB_AFFS_FILETYPE_HARDLINK): ++ { ++ grub_err_t err; ++ (*node)->block = grub_be_to_cpu32 ((*node)->di.hardlink); ++ err = grub_disk_read (data->disk, ++ (((grub_uint64_t) (*node)->block + 1) << data->log_blocksize) ++ - 1, ++ GRUB_DISK_SECTOR_SIZE - GRUB_AFFS_FILE_LOCATION, ++ sizeof ((*node)->di), (char *) &(*node)->di); ++ if (err) ++ return 1; ++ continue; ++ } ++ default: ++ return 0; + } ++ break; ++ } + +- if (nest == 8) +- return 0; ++ if (nest == 8) ++ return 0; + +- type |= GRUB_FSHELP_CASE_INSENSITIVE; ++ type |= GRUB_FSHELP_CASE_INSENSITIVE; + +- if (hook ((char *) name_u8, type, node)) +- { +- grub_free (hashtable); +- node = 0; +- return 1; +- } +- node = 0; +- return 0; ++ if (hook ((char *) name_u8, type, *node, hook_data)) ++ { ++ grub_free (*hashtable); ++ *node = 0; ++ return 1; + } ++ *node = 0; ++ return 0; ++} ++ ++static int ++grub_affs_iterate_dir (grub_fshelp_node_t dir, ++ grub_fshelp_iterate_dir_hook_t hook, void *hook_data) ++{ ++ unsigned int i; ++ struct grub_affs_file file; ++ struct grub_fshelp_node *node = 0; ++ struct grub_affs_data *data = dir->data; ++ grub_uint32_t *hashtable; + + /* Create the directory entries for `.' and `..'. */ + node = grub_zalloc (sizeof (*node)); +@@ -410,7 +410,7 @@ grub_affs_iterate_dir (grub_fshelp_node_t dir, + return 1; + + *node = *dir; +- if (hook (".", GRUB_FSHELP_DIR, node)) ++ if (hook (".", GRUB_FSHELP_DIR, node, hook_data)) + return 1; + if (dir->parent) + { +@@ -418,7 +418,7 @@ grub_affs_iterate_dir (grub_fshelp_node_t dir, + if (!node) + return 1; + *node = *dir->parent; +- if (hook ("..", GRUB_FSHELP_DIR, node)) ++ if (hook ("..", GRUB_FSHELP_DIR, node, hook_data)) + return 1; + } + +@@ -454,7 +454,8 @@ grub_affs_iterate_dir (grub_fshelp_node_t dir, + if (grub_errno) + goto fail; + +- if (grub_affs_create_node (next, &file)) ++ if (grub_affs_create_node (dir, hook, hook_data, &node, &hashtable, ++ next, &file)) + return 1; + + next = grub_be_to_cpu32 (file.next); +@@ -545,31 +546,37 @@ aftime2ctime (const struct grub_affs_time *t) + + 8 * 365 * 86400 + 86400 * 2; + } + ++/* Context for grub_affs_dir. */ ++struct grub_affs_dir_ctx ++{ ++ grub_fs_dir_hook_t hook; ++ void *hook_data; ++}; ++ ++/* Helper for grub_affs_dir. */ ++static int ++grub_affs_dir_iter (const char *filename, enum grub_fshelp_filetype filetype, ++ grub_fshelp_node_t node, void *data) ++{ ++ struct grub_affs_dir_ctx *ctx = data; ++ struct grub_dirhook_info info; ++ ++ grub_memset (&info, 0, sizeof (info)); ++ info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); ++ info.mtimeset = 1; ++ info.mtime = aftime2ctime (&node->di.mtime); ++ grub_free (node); ++ return ctx->hook (filename, &info, ctx->hook_data); ++} ++ + static grub_err_t + grub_affs_dir (grub_device_t device, const char *path, +- int (*hook) (const char *filename, +- const struct grub_dirhook_info *info)) ++ grub_fs_dir_hook_t hook, void *hook_data) + { ++ struct grub_affs_dir_ctx ctx = { hook, hook_data }; + struct grub_affs_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)); +- info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); +- info.mtimeset = 1; +- info.mtime = aftime2ctime (&node->di.mtime); +- grub_free (node); +- return hook (filename, &info); +- } +- + grub_dl_ref (my_mod); + + data = grub_affs_mount (device->disk); +@@ -581,7 +588,7 @@ grub_affs_dir (grub_device_t device, const char *path, + if (grub_errno) + goto fail; + +- grub_affs_iterate_dir (fdiro, iterate); ++ grub_affs_iterate_dir (fdiro, grub_affs_dir_iter, &ctx); + + fail: + if (data && fdiro != &data->diropen) +diff --git a/grub-core/fs/bfs.c b/grub-core/fs/bfs.c +index 318dc3e..fa2fc3f 100644 +--- a/grub-core/fs/bfs.c ++++ b/grub-core/fs/bfs.c +@@ -173,6 +173,15 @@ struct grub_bfs_data + struct grub_bfs_inode ino[0]; + }; + ++/* Context for grub_bfs_dir. */ ++struct grub_bfs_dir_ctx ++{ ++ grub_device_t device; ++ grub_fs_dir_hook_t hook; ++ void *hook_data; ++ struct grub_bfs_superblock sb; ++}; ++ + static grub_err_t + read_extent (grub_disk_t disk, + const struct grub_bfs_superblock *sb, +@@ -413,7 +422,9 @@ static int + iterate_in_b_tree (grub_disk_t disk, + const struct grub_bfs_superblock *sb, + const struct grub_bfs_inode *ino, +- int NESTED_FUNC_ATTR (*hook) (const char *name, grub_uint64_t value)) ++ int (*hook) (const char *name, grub_uint64_t value, ++ struct grub_bfs_dir_ctx *ctx), ++ struct grub_bfs_dir_ctx *ctx) + { + struct grub_bfs_btree_header head; + grub_err_t err; +@@ -496,7 +507,8 @@ iterate_in_b_tree (grub_disk_t disk, + end = grub_bfs_to_cpu_treehead (node.total_key_len); + c = key_data[end]; + key_data[end] = 0; +- if (hook (key_data + start, grub_bfs_to_cpu64 (key_values[i]))) ++ if (hook (key_data + start, grub_bfs_to_cpu64 (key_values[i]), ++ ctx)) + return 1; + key_data[end] = c; + } +@@ -844,46 +856,52 @@ mount (grub_disk_t disk, struct grub_bfs_superblock *sb) + return GRUB_ERR_NONE; + } + +-static grub_err_t +-grub_bfs_dir (grub_device_t device, const char *path, +- int (*hook_in) (const char *filename, +- const struct grub_dirhook_info * info)) ++/* Helper for grub_bfs_dir. */ ++static int ++grub_bfs_dir_iter (const char *name, grub_uint64_t value, ++ struct grub_bfs_dir_ctx *ctx) + { +- struct grub_bfs_superblock sb; +- grub_err_t err; +- auto int NESTED_FUNC_ATTR hook (const char *name, grub_uint64_t value); +- +- int NESTED_FUNC_ATTR hook (const char *name, grub_uint64_t value) ++ grub_err_t err2; ++ union + { +- grub_err_t err2; +- union +- { +- struct grub_bfs_inode ino; +- grub_uint8_t raw[grub_bfs_to_cpu32 (sb.bsize)]; +- } ino; +- struct grub_dirhook_info info; ++ struct grub_bfs_inode ino; ++ grub_uint8_t raw[grub_bfs_to_cpu32 (ctx->sb.bsize)]; ++ } ino; ++ struct grub_dirhook_info info; + +- err2 = grub_disk_read (device->disk, value +- << (grub_bfs_to_cpu32 (sb.log2_bsize) +- - GRUB_DISK_SECTOR_BITS), 0, +- grub_bfs_to_cpu32 (sb.bsize), (char *) ino.raw); +- if (err2) +- { +- grub_print_error (); +- return 0; +- } ++ err2 = grub_disk_read (ctx->device->disk, value ++ << (grub_bfs_to_cpu32 (ctx->sb.log2_bsize) ++ - GRUB_DISK_SECTOR_BITS), 0, ++ grub_bfs_to_cpu32 (ctx->sb.bsize), (char *) ino.raw); ++ if (err2) ++ { ++ grub_print_error (); ++ return 0; ++ } + +- info.mtimeset = 1; ++ info.mtimeset = 1; + #ifdef MODE_AFS +- info.mtime = +- grub_divmod64 (grub_bfs_to_cpu64 (ino.ino.mtime), 1000000, 0); ++ info.mtime = ++ grub_divmod64 (grub_bfs_to_cpu64 (ino.ino.mtime), 1000000, 0); + #else +- info.mtime = grub_bfs_to_cpu64 (ino.ino.mtime) >> 16; ++ info.mtime = grub_bfs_to_cpu64 (ino.ino.mtime) >> 16; + #endif +- info.dir = ((grub_bfs_to_cpu32 (ino.ino.mode) & ATTR_TYPE) == ATTR_DIR); +- return hook_in (name, &info); +- } +- err = mount (device->disk, &sb); ++ info.dir = ((grub_bfs_to_cpu32 (ino.ino.mode) & ATTR_TYPE) == ATTR_DIR); ++ return ctx->hook (name, &info, ctx->hook_data); ++} ++ ++static grub_err_t ++grub_bfs_dir (grub_device_t device, const char *path, ++ grub_fs_dir_hook_t hook, void *hook_data) ++{ ++ struct grub_bfs_dir_ctx ctx = { ++ .device = device, ++ .hook = hook, ++ .hook_data = hook_data ++ }; ++ grub_err_t err; ++ ++ err = mount (device->disk, &ctx.sb); + if (err) + return err; + +@@ -891,14 +909,15 @@ grub_bfs_dir (grub_device_t device, const char *path, + union + { + struct grub_bfs_inode ino; +- grub_uint8_t raw[grub_bfs_to_cpu32 (sb.bsize)]; ++ grub_uint8_t raw[grub_bfs_to_cpu32 (ctx.sb.bsize)]; + } ino; +- err = find_file (path, device->disk, &sb, &ino.ino); ++ err = find_file (path, device->disk, &ctx.sb, &ino.ino); + if (err) + return err; + if (((grub_bfs_to_cpu32 (ino.ino.mode) & ATTR_TYPE) != ATTR_DIR)) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a directory")); +- iterate_in_b_tree (device->disk, &sb, &ino.ino, hook); ++ iterate_in_b_tree (device->disk, &ctx.sb, &ino.ino, grub_bfs_dir_iter, ++ &ctx); + } + + return grub_errno; +diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c +index bcc75ba..196f301 100644 +--- a/grub-core/fs/btrfs.c ++++ b/grub-core/fs/btrfs.c +@@ -1491,8 +1491,7 @@ find_path (struct grub_btrfs_data *data, + + static grub_err_t + grub_btrfs_dir (grub_device_t device, const char *path, +- int (*hook) (const char *filename, +- const struct grub_dirhook_info *info)) ++ grub_fs_dir_hook_t hook, void *hook_data) + { + struct grub_btrfs_data *data = grub_btrfs_mount (device); + struct grub_btrfs_key key_in, key_out; +@@ -1586,7 +1585,7 @@ grub_btrfs_dir (grub_device_t device, const char *path, + c = cdirel->name[grub_le_to_cpu16 (cdirel->n)]; + cdirel->name[grub_le_to_cpu16 (cdirel->n)] = 0; + info.dir = (cdirel->type == GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY); +- if (hook (cdirel->name, &info)) ++ if (hook (cdirel->name, &info, hook_data)) + goto out; + cdirel->name[grub_le_to_cpu16 (cdirel->n)] = c; + } +diff --git a/grub-core/fs/cpio.c b/grub-core/fs/cpio.c +index e9236cd..71d7fa4 100644 +--- a/grub-core/fs/cpio.c ++++ b/grub-core/fs/cpio.c +@@ -513,8 +513,7 @@ handle_symlink (struct grub_cpio_data *data, + + static grub_err_t + grub_cpio_dir (grub_device_t device, const char *path_in, +- int (*hook) (const char *filename, +- const struct grub_dirhook_info *info)) ++ grub_fs_dir_hook_t hook, void *hook_data) + { + struct grub_cpio_data *data; + grub_disk_addr_t ofs; +@@ -575,7 +574,7 @@ grub_cpio_dir (grub_device_t device, const char *path_in, + info.mtime = mtime; + info.mtimeset = 1; + +- if (hook (n, &info)) ++ if (hook (n, &info, hook_data)) + { + grub_free (name); + goto fail; +diff --git a/grub-core/fs/ext2.c b/grub-core/fs/ext2.c +index cf2e2f4..0ebde35 100644 +--- a/grub-core/fs/ext2.c ++++ b/grub-core/fs/ext2.c +@@ -692,10 +692,7 @@ grub_ext2_read_symlink (grub_fshelp_node_t node) + + static int + grub_ext2_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)) ++ grub_fshelp_iterate_dir_hook_t hook, void *hook_data) + { + unsigned int fpos = 0; + struct grub_fshelp_node *diro = (struct grub_fshelp_node *) dir; +@@ -777,7 +774,7 @@ grub_ext2_iterate_dir (grub_fshelp_node_t dir, + type = GRUB_FSHELP_REG; + } + +- if (hook (filename, type, fdiro)) ++ if (hook (filename, type, fdiro, hook_data)) + return 1; + } + +@@ -858,59 +855,69 @@ grub_ext2_read (grub_file_t file, char *buf, grub_size_t len) + } + + +-static grub_err_t +-grub_ext2_dir (grub_device_t device, const char *path, +- int (*hook) (const char *filename, +- const struct grub_dirhook_info *info)) ++/* Context for grub_ext2_dir. */ ++struct grub_ext2_dir_ctx + { +- struct grub_ext2_data *data = 0; +- struct grub_fshelp_node *fdiro = 0; ++ grub_fs_dir_hook_t hook; ++ void *hook_data; ++ struct grub_ext2_data *data; ++}; + +- auto int NESTED_FUNC_ATTR iterate (const char *filename, +- enum grub_fshelp_filetype filetype, +- grub_fshelp_node_t node); ++/* Helper for grub_ext2_dir. */ ++static int ++grub_ext2_dir_iter (const char *filename, enum grub_fshelp_filetype filetype, ++ grub_fshelp_node_t node, void *data) ++{ ++ struct grub_ext2_dir_ctx *ctx = data; ++ struct grub_dirhook_info info; + +- int NESTED_FUNC_ATTR iterate (const char *filename, +- enum grub_fshelp_filetype filetype, +- grub_fshelp_node_t node) ++ grub_memset (&info, 0, sizeof (info)); ++ if (! node->inode_read) + { +- struct grub_dirhook_info info; +- grub_memset (&info, 0, sizeof (info)); +- if (! node->inode_read) +- { +- grub_ext2_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_cpu32 (node->inode.mtime); +- } +- +- info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); +- grub_free (node); +- return hook (filename, &info); ++ grub_ext2_read_inode (ctx->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_cpu32 (node->inode.mtime); ++ } ++ ++ info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); ++ grub_free (node); ++ return ctx->hook (filename, &info, ctx->hook_data); ++} ++ ++static grub_err_t ++grub_ext2_dir (grub_device_t device, const char *path, grub_fs_dir_hook_t hook, ++ void *hook_data) ++{ ++ struct grub_ext2_dir_ctx ctx = { ++ .hook = hook, ++ .hook_data = hook_data ++ }; ++ struct grub_fshelp_node *fdiro = 0; + + grub_dl_ref (my_mod); + +- data = grub_ext2_mount (device->disk); +- if (! data) ++ ctx.data = grub_ext2_mount (device->disk); ++ if (! ctx.data) + goto fail; + +- grub_fshelp_find_file (path, &data->diropen, &fdiro, grub_ext2_iterate_dir, +- grub_ext2_read_symlink, GRUB_FSHELP_DIR); ++ grub_fshelp_find_file (path, &ctx.data->diropen, &fdiro, ++ grub_ext2_iterate_dir, grub_ext2_read_symlink, ++ GRUB_FSHELP_DIR); + if (grub_errno) + goto fail; + +- grub_ext2_iterate_dir (fdiro, iterate); ++ grub_ext2_iterate_dir (fdiro, grub_ext2_dir_iter, &ctx); + + fail: +- if (fdiro != &data->diropen) ++ if (fdiro != &ctx.data->diropen) + grub_free (fdiro); +- grub_free (data); ++ grub_free (ctx.data); + + grub_dl_unref (my_mod); + +diff --git a/grub-core/fs/fat.c b/grub-core/fs/fat.c +index 119fc94..7664153 100644 +--- a/grub-core/fs/fat.c ++++ b/grub-core/fs/fat.c +@@ -844,8 +844,7 @@ grub_fat_iterate_dir_next (grub_disk_t disk, struct grub_fat_data *data, + static char * + grub_fat_find_dir (grub_disk_t disk, struct grub_fat_data *data, + const char *path, const char *origpath, +- int (*hook) (const char *filename, +- const struct grub_dirhook_info *info)) ++ grub_fs_dir_hook_t hook, void *hook_data) + { + char *dirname, *dirp; + int call_hook; +@@ -905,7 +904,7 @@ grub_fat_find_dir (grub_disk_t disk, struct grub_fat_data *data, + #endif + if (*dirname == '\0' && call_hook) + { +- if (hook (ctxt.filename, &info)) ++ if (hook (ctxt.filename, &info, hook_data)) + break; + else + continue; +@@ -926,7 +925,7 @@ grub_fat_find_dir (grub_disk_t disk, struct grub_fat_data *data, + data->cur_cluster_num = ~0U; + + if (call_hook) +- hook (ctxt.filename, &info); ++ hook (ctxt.filename, &info, hook_data); + + break; + } +@@ -946,9 +945,8 @@ grub_fat_find_dir (grub_disk_t disk, struct grub_fat_data *data, + } + + static grub_err_t +-grub_fat_dir (grub_device_t device, const char *path, +- int (*hook) (const char *filename, +- const struct grub_dirhook_info *info)) ++grub_fat_dir (grub_device_t device, const char *path, grub_fs_dir_hook_t hook, ++ void *hook_data) + { + struct grub_fat_data *data = 0; + grub_disk_t disk = device->disk; +@@ -976,7 +974,7 @@ grub_fat_dir (grub_device_t device, const char *path, + + do + { +- p = grub_fat_find_dir (disk, data, p, path, hook); ++ p = grub_fat_find_dir (disk, data, p, path, hook, hook_data); + } + while (p && grub_errno == GRUB_ERR_NONE); + +@@ -1004,7 +1002,7 @@ grub_fat_open (grub_file_t file, const char *name) + + do + { +- p = grub_fat_find_dir (file->device->disk, data, p, name, 0); ++ p = grub_fat_find_dir (file->device->disk, data, p, name, 0, 0); + if (grub_errno != GRUB_ERR_NONE) + goto fail; + } +diff --git a/grub-core/fs/fshelp.c b/grub-core/fs/fshelp.c +index 21a72de..7e557c3 100644 +--- a/grub-core/fs/fshelp.c ++++ b/grub-core/fs/fshelp.c +@@ -27,199 +27,214 @@ + + GRUB_MOD_LICENSE ("GPLv3+"); + +-/* Lookup the node PATH. The node ROOTNODE describes the root of the +- directory tree. The node found is returned in FOUNDNODE, which is +- either a ROOTNODE or a new malloc'ed node. ITERATE_DIR is used to +- iterate over all directory entries in the current node. +- READ_SYMLINK is used to read the symlink if a node is a symlink. +- EXPECTTYPE is the type node that is expected by the called, an +- error is generated if the node is not of the expected type. Make +- sure you use the NESTED_FUNC_ATTR macro for HOOK, this is required +- because GCC has a nasty bug when using regparm=3. */ +-grub_err_t +-grub_fshelp_find_file (const char *path, grub_fshelp_node_t rootnode, +- grub_fshelp_node_t *foundnode, +- int (*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)), +- char *(*read_symlink) (grub_fshelp_node_t node), +- enum grub_fshelp_filetype expecttype) ++typedef int (*iterate_dir_func) (grub_fshelp_node_t dir, ++ grub_fshelp_iterate_dir_hook_t hook, ++ void *data); ++typedef char *(*read_symlink_func) (grub_fshelp_node_t node); ++ ++/* Context for grub_fshelp_find_file. */ ++struct grub_fshelp_find_file_ctx + { +- grub_err_t err; +- enum grub_fshelp_filetype foundtype = GRUB_FSHELP_DIR; +- int symlinknest = 0; ++ const char *path; ++ grub_fshelp_node_t rootnode, currroot, currnode, oldnode; ++ enum grub_fshelp_filetype foundtype; ++ int symlinknest; ++ char *name; ++ enum grub_fshelp_filetype type; ++}; ++ ++/* Helper for find_file_iter. */ ++static void ++free_node (grub_fshelp_node_t node, struct grub_fshelp_find_file_ctx *ctx) ++{ ++ if (node != ctx->rootnode && node != ctx->currroot) ++ grub_free (node); ++} + +- auto grub_err_t NESTED_FUNC_ATTR find_file (const char *currpath, +- grub_fshelp_node_t currroot, +- grub_fshelp_node_t *currfound); ++/* Helper for grub_fshelp_find_file. */ ++static int ++find_file_iter (const char *filename, enum grub_fshelp_filetype filetype, ++ grub_fshelp_node_t node, void *data) ++{ ++ struct grub_fshelp_find_file_ctx *ctx = data; + +- grub_err_t NESTED_FUNC_ATTR find_file (const char *currpath, +- grub_fshelp_node_t currroot, +- grub_fshelp_node_t *currfound) ++ if (filetype == GRUB_FSHELP_UNKNOWN || ++ (grub_strcmp (ctx->name, filename) && ++ (! (filetype & GRUB_FSHELP_CASE_INSENSITIVE) || ++ grub_strcasecmp (ctx->name, filename)))) + { +- char fpath[grub_strlen (currpath) + 1]; +- char *name = fpath; +- char *next; +- enum grub_fshelp_filetype type = GRUB_FSHELP_DIR; +- grub_fshelp_node_t currnode = currroot; +- grub_fshelp_node_t oldnode = currroot; ++ grub_free (node); ++ return 0; ++ } + +- auto int NESTED_FUNC_ATTR iterate (const char *filename, +- enum grub_fshelp_filetype filetype, +- grub_fshelp_node_t node); ++ /* The node is found, stop iterating over the nodes. */ ++ ctx->type = filetype & ~GRUB_FSHELP_CASE_INSENSITIVE; ++ ctx->oldnode = ctx->currnode; ++ ctx->currnode = node; + +- auto void free_node (grub_fshelp_node_t node); ++ return 1; ++} + +- void free_node (grub_fshelp_node_t node) +- { +- if (node != rootnode && node != currroot) +- grub_free (node); +- } ++static grub_err_t ++find_file (const char *currpath, grub_fshelp_node_t currroot, ++ grub_fshelp_node_t *currfound, ++ iterate_dir_func iterate_dir, read_symlink_func read_symlink, ++ struct grub_fshelp_find_file_ctx *ctx) ++{ ++ char fpath[grub_strlen (currpath) + 1]; ++ char *next; + +- int NESTED_FUNC_ATTR iterate (const char *filename, +- enum grub_fshelp_filetype filetype, +- grub_fshelp_node_t node) +- { +- if (filetype == GRUB_FSHELP_UNKNOWN || +- (grub_strcmp (name, filename) && +- (! (filetype & GRUB_FSHELP_CASE_INSENSITIVE) || +- grub_strcasecmp (name, filename)))) +- { +- grub_free (node); +- return 0; +- } ++ ctx->currroot = currroot; ++ ctx->name = fpath; ++ ctx->type = GRUB_FSHELP_DIR; ++ ctx->currnode = currroot; ++ ctx->oldnode = currroot; + +- /* The node is found, stop iterating over the nodes. */ +- type = filetype & ~GRUB_FSHELP_CASE_INSENSITIVE; +- oldnode = currnode; +- currnode = node; ++ grub_strncpy (fpath, currpath, grub_strlen (currpath) + 1); + +- return 1; +- } ++ /* Remove all leading slashes. */ ++ while (*ctx->name == '/') ++ ctx->name++; + +- grub_strncpy (fpath, currpath, grub_strlen (currpath) + 1); ++ if (! *ctx->name) ++ { ++ *currfound = ctx->currnode; ++ return 0; ++ } + +- /* Remove all leading slashes. */ +- while (*name == '/') +- name++; ++ for (;;) ++ { ++ int found; + +- if (! *name) ++ /* Extract the actual part from the pathname. */ ++ next = grub_strchr (ctx->name, '/'); ++ if (next) + { +- *currfound = currnode; +- return 0; ++ /* Remove all leading slashes. */ ++ while (*next == '/') ++ *(next++) = '\0'; + } + +- for (;;) ++ /* At this point it is expected that the current node is a ++ directory, check if this is true. */ ++ if (ctx->type != GRUB_FSHELP_DIR) + { +- int found; ++ free_node (ctx->currnode, ctx); ++ ctx->currnode = 0; ++ return grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a directory")); ++ } + +- /* Extract the actual part from the pathname. */ +- next = grub_strchr (name, '/'); +- if (next) +- { +- /* Remove all leading slashes. */ +- while (*next == '/') +- *(next++) = '\0'; +- } ++ /* Iterate over the directory. */ ++ found = iterate_dir (ctx->currnode, find_file_iter, ctx); ++ if (! found) ++ { ++ free_node (ctx->currnode, ctx); ++ ctx->currnode = 0; ++ if (grub_errno) ++ return grub_errno; ++ ++ break; ++ } ++ ++ /* Read in the symlink and follow it. */ ++ if (ctx->type == GRUB_FSHELP_SYMLINK) ++ { ++ char *symlink; + +- /* At this point it is expected that the current node is a +- directory, check if this is true. */ +- if (type != GRUB_FSHELP_DIR) ++ /* Test if the symlink does not loop. */ ++ if (++ctx->symlinknest == 8) + { +- free_node (currnode); +- currnode = 0; +- return grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a directory")); ++ free_node (ctx->currnode, ctx); ++ free_node (ctx->oldnode, ctx); ++ ctx->currnode = 0; ++ return grub_error (GRUB_ERR_SYMLINK_LOOP, ++ N_("too deep nesting of symlinks")); + } + +- /* Iterate over the directory. */ +- found = iterate_dir (currnode, iterate); +- if (! found) +- { +- free_node (currnode); +- currnode = 0; +- if (grub_errno) +- return grub_errno; ++ symlink = read_symlink (ctx->currnode); ++ free_node (ctx->currnode, ctx); ++ ctx->currnode = 0; + +- break; ++ if (!symlink) ++ { ++ free_node (ctx->oldnode, ctx); ++ return grub_errno; + } + +- /* Read in the symlink and follow it. */ +- if (type == GRUB_FSHELP_SYMLINK) ++ /* The symlink is an absolute path, go back to the root inode. */ ++ if (symlink[0] == '/') + { +- char *symlink; +- +- /* Test if the symlink does not loop. */ +- if (++symlinknest == 8) +- { +- free_node (currnode); +- free_node (oldnode); +- currnode = 0; +- return grub_error (GRUB_ERR_SYMLINK_LOOP, +- N_("too deep nesting of symlinks")); +- } +- +- symlink = read_symlink (currnode); +- free_node (currnode); +- currnode = 0; +- +- if (!symlink) +- { +- free_node (oldnode); +- return grub_errno; +- } +- +- /* The symlink is an absolute path, go back to the root inode. */ +- if (symlink[0] == '/') +- { +- free_node (oldnode); +- oldnode = rootnode; +- } +- +- /* Lookup the node the symlink points to. */ +- find_file (symlink, oldnode, &currnode); +- type = foundtype; +- grub_free (symlink); +- +- if (grub_errno) +- { +- free_node (oldnode); +- return grub_errno; +- } ++ free_node (ctx->oldnode, ctx); ++ ctx->oldnode = ctx->rootnode; + } + +- if (oldnode != currnode) +- free_node (oldnode); ++ /* Lookup the node the symlink points to. */ ++ find_file (symlink, ctx->oldnode, &ctx->currnode, ++ iterate_dir, read_symlink, ctx); ++ ctx->type = ctx->foundtype; ++ grub_free (symlink); + +- /* Found the node! */ +- if (! next || *next == '\0') ++ if (grub_errno) + { +- *currfound = currnode; +- foundtype = type; +- return 0; ++ free_node (ctx->oldnode, ctx); ++ return grub_errno; + } ++ } ++ ++ if (ctx->oldnode != ctx->currnode) ++ free_node (ctx->oldnode, ctx); + +- name = next; ++ /* Found the node! */ ++ if (! next || *next == '\0') ++ { ++ *currfound = ctx->currnode; ++ ctx->foundtype = ctx->type; ++ return 0; + } + +- return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file `%s' not found"), path); ++ ctx->name = next; + } + ++ return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file `%s' not found"), ++ ctx->path); ++} ++ ++/* Lookup the node PATH. The node ROOTNODE describes the root of the ++ directory tree. The node found is returned in FOUNDNODE, which is ++ either a ROOTNODE or a new malloc'ed node. ITERATE_DIR is used to ++ iterate over all directory entries in the current node. ++ READ_SYMLINK is used to read the symlink if a node is a symlink. ++ EXPECTTYPE is the type node that is expected by the called, an ++ error is generated if the node is not of the expected type. */ ++grub_err_t ++grub_fshelp_find_file (const char *path, grub_fshelp_node_t rootnode, ++ grub_fshelp_node_t *foundnode, ++ iterate_dir_func iterate_dir, ++ read_symlink_func read_symlink, ++ enum grub_fshelp_filetype expecttype) ++{ ++ struct grub_fshelp_find_file_ctx ctx = { ++ .path = path, ++ .rootnode = rootnode, ++ .foundtype = GRUB_FSHELP_DIR, ++ .symlinknest = 0 ++ }; ++ grub_err_t err; ++ + if (!path || path[0] != '/') + { + grub_error (GRUB_ERR_BAD_FILENAME, N_("invalid file name `%s'"), path); + return grub_errno; + } + +- err = find_file (path, rootnode, foundnode); ++ err = find_file (path, rootnode, foundnode, iterate_dir, read_symlink, &ctx); + if (err) + return err; + + /* Check if the node that was found was of the expected type. */ +- if (expecttype == GRUB_FSHELP_REG && foundtype != expecttype) ++ if (expecttype == GRUB_FSHELP_REG && ctx.foundtype != expecttype) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a regular file")); +- else if (expecttype == GRUB_FSHELP_DIR && foundtype != expecttype) ++ else if (expecttype == GRUB_FSHELP_DIR && ctx.foundtype != expecttype) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a directory")); + + return 0; +diff --git a/grub-core/fs/hfs.c b/grub-core/fs/hfs.c +index 0a249cc..9ed3330 100644 +--- a/grub-core/fs/hfs.c ++++ b/grub-core/fs/hfs.c +@@ -1151,9 +1151,8 @@ grub_hfs_find_dir (struct grub_hfs_data *data, const char *path, + + + static grub_err_t +-grub_hfs_dir (grub_device_t device, const char *path, +- int (*hook) (const char *filename, +- const struct grub_dirhook_info *info)) ++grub_hfs_dir (grub_device_t device, const char *path, grub_fs_dir_hook_t hook, ++ void *hook_data) + { + int inode; + +@@ -1184,14 +1183,14 @@ grub_hfs_dir (grub_device_t device, const char *path, + info.dir = 1; + info.mtimeset = 1; + info.mtime = grub_be_to_cpu32 (drec->mtime) - 2082844800; +- return hook (fname, &info); ++ return hook (fname, &info, hook_data); + } + if (frec->type == GRUB_HFS_FILETYPE_FILE) + { + info.dir = 0; + info.mtimeset = 1; + info.mtime = grub_be_to_cpu32 (frec->mtime) - 2082844800; +- return hook (fname, &info); ++ return hook (fname, &info, hook_data); + } + + return 0; +diff --git a/grub-core/fs/hfsplus.c b/grub-core/fs/hfsplus.c +index 9812464..dcca581 100644 +--- a/grub-core/fs/hfsplus.c ++++ b/grub-core/fs/hfsplus.c +@@ -766,10 +766,7 @@ grub_hfsplus_btree_search (struct grub_hfsplus_btree *btree, + + static int + grub_hfsplus_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)) ++ grub_fshelp_iterate_dir_hook_t hook, void *hook_data) + { + int ret = 0; + +@@ -825,7 +822,7 @@ grub_hfsplus_iterate_dir (grub_fshelp_node_t dir, + node->size = 0; + node->fileid = grub_be_to_cpu32 (fileinfo->parentid); + +- ret = hook ("..", GRUB_FSHELP_DIR, node); ++ ret = hook ("..", GRUB_FSHELP_DIR, node, hook_data); + return ret; + } + +@@ -878,7 +875,7 @@ grub_hfsplus_iterate_dir (grub_fshelp_node_t dir, + node->size = grub_be_to_cpu64 (fileinfo->data.size); + node->fileid = grub_be_to_cpu32 (fileinfo->fileid); + +- ret = hook (filename, type, node); ++ ret = hook (filename, type, node, hook_data); + + grub_free (filename); + +@@ -895,7 +892,7 @@ grub_hfsplus_iterate_dir (grub_fshelp_node_t dir, + if (!fsnode) + return 1; + *fsnode = *dir; +- if (hook (".", GRUB_FSHELP_DIR, fsnode)) ++ if (hook (".", GRUB_FSHELP_DIR, fsnode, hook_data)) + return 1; + } + +@@ -978,32 +975,39 @@ grub_hfsplus_read (grub_file_t file, char *buf, grub_size_t len) + file->offset, len, buf); + } + ++/* Context for grub_hfsplus_dir. */ ++struct grub_hfsplus_dir_ctx ++{ ++ grub_fs_dir_hook_t hook; ++ void *hook_data; ++}; ++ ++/* Helper for grub_hfsplus_dir. */ ++static int ++grub_hfsplus_dir_iter (const char *filename, ++ enum grub_fshelp_filetype filetype, ++ grub_fshelp_node_t node, void *data) ++{ ++ struct grub_hfsplus_dir_ctx *ctx = data; ++ struct grub_dirhook_info info; ++ ++ grub_memset (&info, 0, sizeof (info)); ++ info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); ++ info.mtimeset = 1; ++ info.mtime = node->mtime; ++ info.case_insensitive = !! (filetype & GRUB_FSHELP_CASE_INSENSITIVE); ++ grub_free (node); ++ return ctx->hook (filename, &info, ctx->hook_data); ++} ++ + static grub_err_t + grub_hfsplus_dir (grub_device_t device, const char *path, +- int (*hook) (const char *filename, +- const struct grub_dirhook_info *info)) ++ grub_fs_dir_hook_t hook, void *hook_data) + { ++ struct grub_hfsplus_dir_ctx ctx = { hook, hook_data }; + struct grub_hfsplus_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)); +- info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); +- info.mtimeset = 1; +- info.mtime = node->mtime; +- info.case_insensitive = !! (filetype & GRUB_FSHELP_CASE_INSENSITIVE); +- grub_free (node); +- return hook (filename, &info); +- } +- + grub_dl_ref (my_mod); + + data = grub_hfsplus_mount (device->disk); +@@ -1018,7 +1022,7 @@ grub_hfsplus_dir (grub_device_t device, const char *path, + goto fail; + + /* Iterate over all entries in this directory. */ +- grub_hfsplus_iterate_dir (fdiro, iterate); ++ grub_hfsplus_iterate_dir (fdiro, grub_hfsplus_dir_iter, &ctx); + + fail: + if (data && fdiro != &data->dirroot) +diff --git a/grub-core/fs/iso9660.c b/grub-core/fs/iso9660.c +index 547e156..e37553d 100644 +--- a/grub-core/fs/iso9660.c ++++ b/grub-core/fs/iso9660.c +@@ -521,10 +521,7 @@ get_node_size (grub_fshelp_node_t node) + + static int + grub_iso9660_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)) ++ grub_fshelp_iterate_dir_hook_t hook, void *hook_data) + { + struct grub_iso9660_dir dirent; + grub_off_t offset = 0; +@@ -828,7 +825,7 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir, + symlink = 0; + was_continue = 0; + } +- if (hook (filename, type, node)) ++ if (hook (filename, type, node, hook_data)) + { + if (filename_alloc) + grub_free (filename); +@@ -844,32 +841,39 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir, + + + ++/* Context for grub_iso9660_dir. */ ++struct grub_iso9660_dir_ctx ++{ ++ grub_fs_dir_hook_t hook; ++ void *hook_data; ++}; ++ ++/* Helper for grub_iso9660_dir. */ ++static int ++grub_iso9660_dir_iter (const char *filename, ++ enum grub_fshelp_filetype filetype, ++ grub_fshelp_node_t node, void *data) ++{ ++ struct grub_iso9660_dir_ctx *ctx = data; ++ struct grub_dirhook_info info; ++ ++ grub_memset (&info, 0, sizeof (info)); ++ info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); ++ info.mtimeset = !!iso9660_to_unixtime2 (&node->dirents[0].mtime, &info.mtime); ++ ++ grub_free (node); ++ return ctx->hook (filename, &info, ctx->hook_data); ++} ++ + static grub_err_t + grub_iso9660_dir (grub_device_t device, const char *path, +- int (*hook) (const char *filename, +- const struct grub_dirhook_info *info)) ++ grub_fs_dir_hook_t hook, void *hook_data) + { ++ struct grub_iso9660_dir_ctx ctx = { hook, hook_data }; + struct grub_iso9660_data *data = 0; + struct grub_fshelp_node rootnode; + struct grub_fshelp_node *foundnode; + +- 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)); +- info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); +- info.mtimeset = !!iso9660_to_unixtime2 (&node->dirents[0].mtime, &info.mtime); +- +- grub_free (node); +- return hook (filename, &info); +- } +- + grub_dl_ref (my_mod); + + data = grub_iso9660_mount (device->disk); +@@ -891,7 +895,7 @@ grub_iso9660_dir (grub_device_t device, const char *path, + goto fail; + + /* List the files in the directory. */ +- grub_iso9660_iterate_dir (foundnode, iterate); ++ grub_iso9660_iterate_dir (foundnode, grub_iso9660_dir_iter, &ctx); + + if (foundnode != &rootnode) + grub_free (foundnode); +diff --git a/grub-core/fs/jfs.c b/grub-core/fs/jfs.c +index b98a5a3..7c17192 100644 +--- a/grub-core/fs/jfs.c ++++ b/grub-core/fs/jfs.c +@@ -799,8 +799,7 @@ grub_jfs_lookup_symlink (struct grub_jfs_data *data, grub_uint32_t ino) + + static grub_err_t + grub_jfs_dir (grub_device_t device, const char *path, +- int (*hook) (const char *filename, +- const struct grub_dirhook_info *info)) ++ grub_fs_dir_hook_t hook, void *hook_data) + { + struct grub_jfs_data *data = 0; + struct grub_jfs_diropen *diro = 0; +@@ -832,7 +831,7 @@ grub_jfs_dir (grub_device_t device, const char *path, + & GRUB_JFS_FILETYPE_MASK) == GRUB_JFS_FILETYPE_DIR; + info.mtimeset = 1; + info.mtime = grub_le_to_cpu32 (inode.mtime.sec); +- if (hook (diro->name, &info)) ++ if (hook (diro->name, &info, hook_data)) + goto fail; + } + +diff --git a/grub-core/fs/minix.c b/grub-core/fs/minix.c +index a622533..9655211 100644 +--- a/grub-core/fs/minix.c ++++ b/grub-core/fs/minix.c +@@ -536,8 +536,7 @@ grub_minix_mount (grub_disk_t disk) + + static grub_err_t + grub_minix_dir (grub_device_t device, const char *path, +- int (*hook) (const char *filename, +- const struct grub_dirhook_info *info)) ++ grub_fs_dir_hook_t hook, void *hook_data) + { + struct grub_minix_data *data = 0; + unsigned int pos = 0; +@@ -590,7 +589,7 @@ grub_minix_dir (grub_device_t device, const char *path, + info.mtimeset = 1; + info.mtime = grub_minix_to_cpu32 (data->inode.mtime); + +- if (hook (filename, &info) ? 1 : 0) ++ if (hook (filename, &info, hook_data) ? 1 : 0) + break; + + /* Load the old inode back in. */ +diff --git a/grub-core/fs/nilfs2.c b/grub-core/fs/nilfs2.c +index 5b34486..9bd4444 100644 +--- a/grub-core/fs/nilfs2.c ++++ b/grub-core/fs/nilfs2.c +@@ -870,10 +870,7 @@ grub_nilfs2_read_symlink (grub_fshelp_node_t node) + + 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)) ++ grub_fshelp_iterate_dir_hook_t hook, void *hook_data) + { + grub_off_t fpos = 0; + struct grub_fshelp_node *diro = (struct grub_fshelp_node *) dir; +@@ -957,7 +954,7 @@ grub_nilfs2_iterate_dir (grub_fshelp_node_t dir, + type = GRUB_FSHELP_REG; + } + +- if (hook (filename, type, fdiro)) ++ if (hook (filename, type, fdiro, hook_data)) + return 1; + } + +@@ -1032,60 +1029,69 @@ grub_nilfs2_read (grub_file_t file, char *buf, grub_size_t len) + file->offset, len, buf); + } + ++/* Context for grub_nilfs2_dir. */ ++struct grub_nilfs2_dir_ctx ++{ ++ grub_fs_dir_hook_t hook; ++ void *hook_data; ++ struct grub_nilfs2_data *data; ++}; ++ ++/* Helper for grub_nilfs2_dir. */ ++static int ++grub_nilfs2_dir_iter (const char *filename, enum grub_fshelp_filetype filetype, ++ grub_fshelp_node_t node, void *data) ++{ ++ struct grub_nilfs2_dir_ctx *ctx = data; ++ struct grub_dirhook_info info; ++ ++ grub_memset (&info, 0, sizeof (info)); ++ if (!node->inode_read) ++ { ++ grub_nilfs2_read_inode (ctx->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 ctx->hook (filename, &info, ctx->hook_data); ++} ++ + 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)) ++ grub_fs_dir_hook_t hook, void *hook_data) + { +- struct grub_nilfs2_data *data = 0; ++ struct grub_nilfs2_dir_ctx ctx = { ++ .hook = hook, ++ .hook_data = hook_data ++ }; + 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) ++ ctx.data = grub_nilfs2_mount (device->disk); ++ if (!ctx.data) + goto fail; + +- grub_fshelp_find_file (path, &data->diropen, &fdiro, ++ grub_fshelp_find_file (path, &ctx.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); ++ grub_nilfs2_iterate_dir (fdiro, grub_nilfs2_dir_iter, &ctx); + + fail: +- if (fdiro != &data->diropen) ++ if (fdiro != &ctx.data->diropen) + grub_free (fdiro); +- grub_free (data); ++ grub_free (ctx.data); + + grub_dl_unref (my_mod); + +diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c +index e7861d8..7ac46f9 100644 +--- a/grub-core/fs/ntfs.c ++++ b/grub-core/fs/ntfs.c +@@ -600,10 +600,7 @@ free_file (struct grub_ntfs_file *mft) + + static int + list_file (struct grub_ntfs_file *diro, grub_uint8_t *pos, +- int NESTED_FUNC_ATTR +- (*hook) (const char *filename, +- enum grub_fshelp_filetype filetype, +- grub_fshelp_node_t node)) ++ grub_fshelp_iterate_dir_hook_t hook, void *hook_data) + { + grub_uint8_t *np; + int ns; +@@ -667,7 +664,7 @@ list_file (struct grub_ntfs_file *diro, grub_uint8_t *pos, + if (namespace) + type |= GRUB_FSHELP_CASE_INSENSITIVE; + +- if (hook (ustr, type, fdiro)) ++ if (hook (ustr, type, fdiro, hook_data)) + { + grub_free (ustr); + return 1; +@@ -778,10 +775,7 @@ grub_ntfs_read_symlink (grub_fshelp_node_t node) + + static int + grub_ntfs_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)) ++ grub_fshelp_iterate_dir_hook_t hook, void *hook_data) + { + grub_uint8_t *bitmap; + struct grub_ntfs_attr attr, *at; +@@ -824,7 +818,7 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir, + } + + cur_pos += 0x10; /* Skip index root */ +- ret = list_file (mft, cur_pos + u16at (cur_pos, 0), hook); ++ ret = list_file (mft, cur_pos + u16at (cur_pos, 0), hook, hook_data); + if (ret) + goto done; + +@@ -909,7 +903,8 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir, + || (fixup (indx, mft->data->idx_size, + (const grub_uint8_t *) "INDX"))) + goto done; +- ret = list_file (mft, &indx[0x18 + u16at (indx, 0x18)], hook); ++ ret = list_file (mft, &indx[0x18 + u16at (indx, 0x18)], ++ hook, hook_data); + if (ret) + goto done; + } +@@ -1017,33 +1012,39 @@ fail: + return 0; + } + ++/* Context for grub_ntfs_dir. */ ++struct grub_ntfs_dir_ctx ++{ ++ grub_fs_dir_hook_t hook; ++ void *hook_data; ++}; ++ ++/* Helper for grub_ntfs_dir. */ ++static int ++grub_ntfs_dir_iter (const char *filename, enum grub_fshelp_filetype filetype, ++ grub_fshelp_node_t node, void *data) ++{ ++ struct grub_ntfs_dir_ctx *ctx = data; ++ struct grub_dirhook_info info; ++ ++ grub_memset (&info, 0, sizeof (info)); ++ info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); ++ info.mtimeset = 1; ++ info.mtime = grub_divmod64 (node->mtime, 10000000, 0) ++ - 86400ULL * 365 * (1970 - 1601) ++ - 86400ULL * ((1970 - 1601) / 4) + 86400ULL * ((1970 - 1601) / 100); ++ grub_free (node); ++ return ctx->hook (filename, &info, ctx->hook_data); ++} ++ + static grub_err_t + grub_ntfs_dir (grub_device_t device, const char *path, +- int (*hook) (const char *filename, +- const struct grub_dirhook_info *info)) ++ grub_fs_dir_hook_t hook, void *hook_data) + { ++ struct grub_ntfs_dir_ctx ctx = { hook, hook_data }; + struct grub_ntfs_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)); +- info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); +- info.mtimeset = 1; +- info.mtime = grub_divmod64 (node->mtime, 10000000, 0) +- - 86400ULL * 365 * (1970 - 1601) +- - 86400ULL * ((1970 - 1601) / 4) + 86400ULL * ((1970 - 1601) / 100); +- grub_free (node); +- return hook (filename, &info); +- } +- + grub_dl_ref (my_mod); + + data = grub_ntfs_mount (device->disk); +@@ -1056,7 +1057,7 @@ grub_ntfs_dir (grub_device_t device, const char *path, + if (grub_errno) + goto fail; + +- grub_ntfs_iterate_dir (fdiro, iterate); ++ grub_ntfs_iterate_dir (fdiro, grub_ntfs_dir_iter, &ctx); + + fail: + if ((fdiro) && (fdiro != &data->cmft)) +diff --git a/grub-core/fs/reiserfs.c b/grub-core/fs/reiserfs.c +index 26adf23..686e4da 100644 +--- a/grub-core/fs/reiserfs.c ++++ b/grub-core/fs/reiserfs.c +@@ -718,10 +718,8 @@ grub_reiserfs_mount (grub_disk_t disk) + /* Call HOOK for each file in directory ITEM. */ + static int + grub_reiserfs_iterate_dir (grub_fshelp_node_t item, +- int NESTED_FUNC_ATTR +- (*hook) (const char *filename, +- enum grub_fshelp_filetype filetype, +- grub_fshelp_node_t node)) ++ grub_fshelp_iterate_dir_hook_t hook, ++ void *hook_data) + { + struct grub_reiserfs_data *data = item->data; + struct grub_reiserfs_block_header *block_header = 0; +@@ -946,7 +944,7 @@ grub_reiserfs_iterate_dir (grub_fshelp_node_t item, + goto next; + } + } +- if (hook (entry_name, entry_type, entry_item)) ++ if (hook (entry_name, entry_type, entry_item, hook_data)) + { + grub_dprintf ("reiserfs", "Found : %s, type=%d\n", + entry_name, entry_type); +@@ -1254,32 +1252,40 @@ grub_reiserfs_close (grub_file_t file) + return GRUB_ERR_NONE; + } + ++/* Context for grub_reiserfs_dir. */ ++struct grub_reiserfs_dir_ctx ++{ ++ grub_fs_dir_hook_t hook; ++ void *hook_data; ++}; ++ ++/* Helper for grub_reiserfs_dir. */ ++static int ++grub_reiserfs_dir_iter (const char *filename, ++ enum grub_fshelp_filetype filetype, ++ grub_fshelp_node_t node, void *data) ++{ ++ struct grub_reiserfs_dir_ctx *ctx = data; ++ struct grub_dirhook_info info; ++ ++ grub_memset (&info, 0, sizeof (info)); ++ info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); ++ info.mtimeset = 1; ++ info.mtime = node->mtime; ++ grub_free (node); ++ return ctx->hook (filename, &info, ctx->hook_data); ++} ++ + /* Call HOOK with each file under DIR. */ + static grub_err_t + grub_reiserfs_dir (grub_device_t device, const char *path, +- int (*hook) (const char *filename, +- const struct grub_dirhook_info *info)) ++ grub_fs_dir_hook_t hook, void *hook_data) + { ++ struct grub_reiserfs_dir_ctx ctx = { hook, hook_data }; + struct grub_reiserfs_data *data = 0; + struct grub_fshelp_node root, *found; + struct grub_reiserfs_key root_key; + +- 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)); +- info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); +- info.mtimeset = 1; +- info.mtime = node->mtime; +- grub_free (node); +- return hook (filename, &info); +- } + grub_dl_ref (my_mod); + data = grub_reiserfs_mount (device->disk); + if (! data) +@@ -1300,7 +1306,7 @@ grub_reiserfs_dir (grub_device_t device, const char *path, + grub_reiserfs_read_symlink, GRUB_FSHELP_DIR); + if (grub_errno) + goto fail; +- grub_reiserfs_iterate_dir (found, iterate); ++ grub_reiserfs_iterate_dir (found, grub_reiserfs_dir_iter, &ctx); + grub_free (data); + grub_dl_unref (my_mod); + return GRUB_ERR_NONE; +diff --git a/grub-core/fs/romfs.c b/grub-core/fs/romfs.c +index b30caef..b79b1e1 100644 +--- a/grub-core/fs/romfs.c ++++ b/grub-core/fs/romfs.c +@@ -171,10 +171,7 @@ grub_romfs_read_symlink (grub_fshelp_node_t node) + + static int + grub_romfs_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)) ++ grub_fshelp_iterate_dir_hook_t hook, void *hook_data) + { + grub_disk_addr_t caddr; + struct grub_romfs_file_header hdr; +@@ -306,7 +303,7 @@ grub_romfs_iterate_dir (grub_fshelp_node_t dir, + } + } + +- if (hook ((char *) name, filetype, node)) ++ if (hook ((char *) name, filetype, node, hook_data)) + { + grub_free (name); + return 1; +@@ -316,30 +313,36 @@ grub_romfs_iterate_dir (grub_fshelp_node_t dir, + return 0; + } + ++/* Context for grub_romfs_dir. */ ++struct grub_romfs_dir_ctx ++{ ++ grub_fs_dir_hook_t hook; ++ void *hook_data; ++}; ++ ++/* Helper for grub_romfs_dir. */ ++static int ++grub_romfs_dir_iter (const char *filename, enum grub_fshelp_filetype filetype, ++ grub_fshelp_node_t node, void *data) ++{ ++ struct grub_romfs_dir_ctx *ctx = data; ++ struct grub_dirhook_info info; ++ ++ grub_memset (&info, 0, sizeof (info)); ++ ++ info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); ++ grub_free (node); ++ return ctx->hook (filename, &info, ctx->hook_data); ++} ++ + static grub_err_t + grub_romfs_dir (grub_device_t device, const char *path, +- int (*hook) (const char *filename, +- const struct grub_dirhook_info *info)) ++ grub_fs_dir_hook_t hook, void *hook_data) + { ++ struct grub_romfs_dir_ctx ctx = { hook, hook_data }; + struct grub_romfs_data *data = 0; + struct grub_fshelp_node *fdiro = 0, start; + +- 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)); +- +- info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); +- grub_free (node); +- return hook (filename, &info); +- } +- + data = grub_romfs_mount (device); + if (! data) + goto fail; +@@ -352,7 +355,7 @@ grub_romfs_dir (grub_device_t device, const char *path, + if (grub_errno) + goto fail; + +- grub_romfs_iterate_dir (fdiro, iterate); ++ grub_romfs_iterate_dir (fdiro, grub_romfs_dir_iter, &ctx); + + fail: + grub_free (data); +diff --git a/grub-core/fs/sfs.c b/grub-core/fs/sfs.c +index f7cdb08..fed17d3 100644 +--- a/grub-core/fs/sfs.c ++++ b/grub-core/fs/sfs.c +@@ -460,12 +460,48 @@ grub_sfs_read_symlink (grub_fshelp_node_t node) + return symlink; + } + ++/* Helper for grub_sfs_iterate_dir. */ ++static int ++grub_sfs_create_node (struct grub_fshelp_node **node, ++ struct grub_sfs_data *data, ++ const char *name, ++ grub_uint32_t block, grub_uint32_t size, int type, ++ grub_uint32_t mtime, ++ grub_fshelp_iterate_dir_hook_t hook, void *hook_data) ++{ ++ grub_size_t len = grub_strlen (name); ++ grub_uint8_t *name_u8; ++ int ret; ++ *node = grub_malloc (sizeof (**node)); ++ if (!*node) ++ return 1; ++ name_u8 = grub_malloc (len * GRUB_MAX_UTF8_PER_LATIN1 + 1); ++ if (!name_u8) ++ { ++ grub_free (*node); ++ return 1; ++ } ++ ++ (*node)->data = data; ++ (*node)->size = size; ++ (*node)->block = block; ++ (*node)->mtime = mtime; ++ (*node)->cache = 0; ++ (*node)->cache_off = 0; ++ (*node)->next_extent = block; ++ (*node)->cache_size = 0; ++ (*node)->cache_allocated = 0; ++ ++ *grub_latin1_to_utf8 (name_u8, (const grub_uint8_t *) name, len) = '\0'; ++ ++ ret = hook ((char *) name_u8, type | data->fshelp_flags, *node, hook_data); ++ grub_free (name_u8); ++ return ret; ++} ++ + static int + grub_sfs_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)) ++ grub_fshelp_iterate_dir_hook_t hook, void *hook_data) + { + struct grub_fshelp_node *node = 0; + struct grub_sfs_data *data = dir->data; +@@ -474,46 +510,6 @@ grub_sfs_iterate_dir (grub_fshelp_node_t dir, + unsigned int next = dir->block; + grub_uint32_t pos; + +- auto int NESTED_FUNC_ATTR grub_sfs_create_node (const char *name, +- grub_uint32_t block, +- grub_uint32_t size, int type, +- grub_uint32_t mtime); +- +- int NESTED_FUNC_ATTR grub_sfs_create_node (const char *name, +- grub_uint32_t block, +- grub_uint32_t size, int type, +- grub_uint32_t mtime) +- { +- grub_size_t len = grub_strlen (name); +- grub_uint8_t *name_u8; +- int ret; +- node = grub_malloc (sizeof (*node)); +- if (!node) +- return 1; +- name_u8 = grub_malloc (len * GRUB_MAX_UTF8_PER_LATIN1 + 1); +- if (!name_u8) +- { +- grub_free (node); +- return 1; +- } +- +- node->data = data; +- node->size = size; +- node->block = block; +- node->mtime = mtime; +- node->cache = 0; +- node->cache_off = 0; +- node->next_extent = block; +- node->cache_size = 0; +- node->cache_allocated = 0; +- +- *grub_latin1_to_utf8 (name_u8, (const grub_uint8_t *) name, len) = '\0'; +- +- ret = hook ((char *) name_u8, type | data->fshelp_flags, node); +- grub_free (name_u8); +- return ret; +- } +- + objc_data = grub_malloc (GRUB_DISK_SECTOR_SIZE << data->log_blocksize); + if (!objc_data) + goto fail; +@@ -570,9 +566,10 @@ grub_sfs_iterate_dir (grub_fshelp_node_t dir, + else + block = grub_be_to_cpu32 (obj->file_dir.file.first_block); + +- if (grub_sfs_create_node (filename, block, ++ if (grub_sfs_create_node (&node, data, filename, block, + grub_be_to_cpu32 (obj->file_dir.file.size), +- type, grub_be_to_cpu32 (obj->mtime))) ++ type, grub_be_to_cpu32 (obj->mtime), ++ hook, hook_data)) + { + grub_free (objc_data); + return 1; +@@ -654,32 +651,38 @@ grub_sfs_read (grub_file_t file, char *buf, grub_size_t len) + } + + ++/* Context for grub_sfs_dir. */ ++struct grub_sfs_dir_ctx ++{ ++ grub_fs_dir_hook_t hook; ++ void *hook_data; ++}; ++ ++/* Helper for grub_sfs_dir. */ ++static int ++grub_sfs_dir_iter (const char *filename, enum grub_fshelp_filetype filetype, ++ grub_fshelp_node_t node, void *data) ++{ ++ struct grub_sfs_dir_ctx *ctx = data; ++ struct grub_dirhook_info info; ++ ++ grub_memset (&info, 0, sizeof (info)); ++ info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); ++ info.mtime = node->mtime + 8 * 365 * 86400 + 86400 * 2; ++ info.mtimeset = 1; ++ grub_free (node->cache); ++ grub_free (node); ++ return ctx->hook (filename, &info, ctx->hook_data); ++} ++ + static grub_err_t + grub_sfs_dir (grub_device_t device, const char *path, +- int (*hook) (const char *filename, +- const struct grub_dirhook_info *info)) ++ grub_fs_dir_hook_t hook, void *hook_data) + { ++ struct grub_sfs_dir_ctx ctx = { hook, hook_data }; + struct grub_sfs_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)); +- info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); +- info.mtime = node->mtime + 8 * 365 * 86400 + 86400 * 2; +- info.mtimeset = 1; +- grub_free (node->cache); +- grub_free (node); +- return hook (filename, &info); +- } +- + grub_dl_ref (my_mod); + + data = grub_sfs_mount (device->disk); +@@ -691,7 +694,7 @@ grub_sfs_dir (grub_device_t device, const char *path, + if (grub_errno) + goto fail; + +- grub_sfs_iterate_dir (fdiro, iterate); ++ grub_sfs_iterate_dir (fdiro, grub_sfs_dir_iter, &ctx); + + fail: + if (data && fdiro != &data->diropen) +diff --git a/grub-core/fs/squash4.c b/grub-core/fs/squash4.c +index 44af0f8..cb3cc3a 100644 +--- a/grub-core/fs/squash4.c ++++ b/grub-core/fs/squash4.c +@@ -478,10 +478,7 @@ grub_squash_read_symlink (grub_fshelp_node_t node) + + static int + grub_squash_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)) ++ grub_fshelp_iterate_dir_hook_t hook, void *hook_data) + { + grub_uint32_t off; + grub_uint32_t endoff; +@@ -514,7 +511,7 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir, + return 0; + grub_memcpy (node, dir, + sizeof (*node) + dir->stsize * sizeof (dir->stack[0])); +- if (hook (".", GRUB_FSHELP_DIR, node)) ++ if (hook (".", GRUB_FSHELP_DIR, node, hook_data)) + return 1; + + if (dir->stsize != 1) +@@ -536,7 +533,7 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir, + if (err) + return 0; + +- if (hook ("..", GRUB_FSHELP_DIR, node)) ++ if (hook ("..", GRUB_FSHELP_DIR, node, hook_data)) + return 1; + } + } +@@ -604,7 +601,7 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir, + node->stack[node->stsize].ino_chunk = grub_le_to_cpu32 (dh.ino_chunk); + node->stack[node->stsize].ino_offset = grub_le_to_cpu16 (di.ino_offset); + node->stsize++; +- r = hook (buf, filetype, node); ++ r = hook (buf, filetype, node, hook_data); + + grub_free (buf); + if (r) +@@ -640,28 +637,34 @@ squash_unmount (struct grub_squash_data *data) + } + + +-static grub_err_t +-grub_squash_dir (grub_device_t device, const char *path, +- int (*hook) (const char *filename, +- const struct grub_dirhook_info *info)) ++/* Context for grub_squash_dir. */ ++struct grub_squash_dir_ctx + { +- auto int NESTED_FUNC_ATTR iterate (const char *filename, +- enum grub_fshelp_filetype filetype, +- grub_fshelp_node_t node); ++ grub_fs_dir_hook_t hook; ++ void *hook_data; ++}; + +- 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)); +- info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); +- info.mtimeset = 1; +- info.mtime = grub_le_to_cpu32 (node->ino.mtime); +- grub_free (node); +- return hook (filename, &info); +- } ++/* Helper for grub_squash_dir. */ ++static int ++grub_squash_dir_iter (const char *filename, enum grub_fshelp_filetype filetype, ++ grub_fshelp_node_t node, void *data) ++{ ++ struct grub_squash_dir_ctx *ctx = data; ++ struct grub_dirhook_info info; ++ ++ grub_memset (&info, 0, sizeof (info)); ++ info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); ++ info.mtimeset = 1; ++ info.mtime = grub_le_to_cpu32 (node->ino.mtime); ++ grub_free (node); ++ return ctx->hook (filename, &info, ctx->hook_data); ++} + ++static grub_err_t ++grub_squash_dir (grub_device_t device, const char *path, ++ grub_fs_dir_hook_t hook, void *hook_data) ++{ ++ struct grub_squash_dir_ctx ctx = { hook, hook_data }; + struct grub_squash_data *data = 0; + struct grub_fshelp_node *fdiro = 0; + struct grub_fshelp_node root; +@@ -678,7 +681,7 @@ grub_squash_dir (grub_device_t device, const char *path, + grub_fshelp_find_file (path, &root, &fdiro, grub_squash_iterate_dir, + grub_squash_read_symlink, GRUB_FSHELP_DIR); + if (!grub_errno) +- grub_squash_iterate_dir (fdiro, iterate); ++ grub_squash_iterate_dir (fdiro, grub_squash_dir_iter, &ctx); + + squash_unmount (data); + +diff --git a/grub-core/fs/udf.c b/grub-core/fs/udf.c +index 8e28d41..b7f3afb 100644 +--- a/grub-core/fs/udf.c ++++ b/grub-core/fs/udf.c +@@ -843,10 +843,7 @@ read_string (const grub_uint8_t *raw, grub_size_t sz, char *outbuf) + + static int + grub_udf_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)) ++ grub_fshelp_iterate_dir_hook_t hook, void *hook_data) + { + grub_fshelp_node_t child; + struct grub_udf_file_ident dirent; +@@ -859,7 +856,7 @@ grub_udf_iterate_dir (grub_fshelp_node_t dir, + /* The current directory is not stored. */ + grub_memcpy (child, dir, get_fshelp_size (dir->data)); + +- if (hook (".", GRUB_FSHELP_DIR, child)) ++ if (hook (".", GRUB_FSHELP_DIR, child, hook_data)) + return 1; + + while (offset < U64 (dir->block.fe.file_size)) +@@ -887,7 +884,7 @@ grub_udf_iterate_dir (grub_fshelp_node_t dir, + if (dirent.characteristics & GRUB_UDF_FID_CHAR_PARENT) + { + /* This is the parent directory. */ +- if (hook ("..", GRUB_FSHELP_DIR, child)) ++ if (hook ("..", GRUB_FSHELP_DIR, child, hook_data)) + return 1; + } + else +@@ -911,7 +908,7 @@ grub_udf_iterate_dir (grub_fshelp_node_t dir, + if (!filename) + grub_print_error (); + +- if (filename && hook (filename, type, child)) ++ if (filename && hook (filename, type, child, hook_data)) + { + grub_free (filename); + return 1; +@@ -1012,58 +1009,64 @@ grub_udf_read_symlink (grub_fshelp_node_t node) + return NULL; + } + ++/* Context for grub_udf_dir. */ ++struct grub_udf_dir_ctx ++{ ++ grub_fs_dir_hook_t hook; ++ void *hook_data; ++}; ++ ++/* Helper for grub_udf_dir. */ ++static int ++grub_udf_dir_iter (const char *filename, enum grub_fshelp_filetype filetype, ++ grub_fshelp_node_t node, void *data) ++{ ++ struct grub_udf_dir_ctx *ctx = data; ++ struct grub_dirhook_info info; ++ const struct grub_udf_timestamp *tstamp = NULL; ++ ++ grub_memset (&info, 0, sizeof (info)); ++ info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); ++ if (U16 (node->block.fe.tag.tag_ident) == GRUB_UDF_TAG_IDENT_FE) ++ tstamp = &node->block.fe.modification_time; ++ else if (U16 (node->block.fe.tag.tag_ident) == GRUB_UDF_TAG_IDENT_EFE) ++ tstamp = &node->block.efe.modification_time; ++ ++ if (tstamp && (U16 (tstamp->type_and_timezone) & 0xf000) == 0x1000) ++ { ++ grub_int16_t tz; ++ struct grub_datetime datetime; ++ ++ datetime.year = U16 (tstamp->year); ++ datetime.month = tstamp->month; ++ datetime.day = tstamp->day; ++ datetime.hour = tstamp->hour; ++ datetime.minute = tstamp->minute; ++ datetime.second = tstamp->second; ++ ++ tz = U16 (tstamp->type_and_timezone) & 0xfff; ++ if (tz & 0x800) ++ tz |= 0xf000; ++ if (tz == -2047) ++ tz = 0; ++ ++ info.mtimeset = !!grub_datetime2unixtime (&datetime, &info.mtime); ++ ++ info.mtime -= 60 * tz; ++ } ++ grub_free (node); ++ return ctx->hook (filename, &info, ctx->hook_data); ++} ++ + static grub_err_t + grub_udf_dir (grub_device_t device, const char *path, +- int (*hook) (const char *filename, +- const struct grub_dirhook_info *info)) ++ grub_fs_dir_hook_t hook, void *hook_data) + { ++ struct grub_udf_dir_ctx ctx = { hook, hook_data }; + struct grub_udf_data *data = 0; + struct grub_fshelp_node *rootnode = 0; + struct grub_fshelp_node *foundnode = 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; +- const struct grub_udf_timestamp *tstamp = NULL; +- grub_memset (&info, 0, sizeof (info)); +- info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); +- if (U16 (node->block.fe.tag.tag_ident) == GRUB_UDF_TAG_IDENT_FE) +- tstamp = &node->block.fe.modification_time; +- else if (U16 (node->block.fe.tag.tag_ident) == GRUB_UDF_TAG_IDENT_EFE) +- tstamp = &node->block.efe.modification_time; +- +- if (tstamp && (U16 (tstamp->type_and_timezone) & 0xf000) == 0x1000) +- { +- grub_int16_t tz; +- struct grub_datetime datetime; +- +- datetime.year = U16 (tstamp->year); +- datetime.month = tstamp->month; +- datetime.day = tstamp->day; +- datetime.hour = tstamp->hour; +- datetime.minute = tstamp->minute; +- datetime.second = tstamp->second; +- +- tz = U16 (tstamp->type_and_timezone) & 0xfff; +- if (tz & 0x800) +- tz |= 0xf000; +- if (tz == -2047) +- tz = 0; +- +- info.mtimeset = !!grub_datetime2unixtime (&datetime, &info.mtime); +- +- info.mtime -= 60 * tz; +- } +- grub_free (node); +- return hook (filename, &info); +- } +- + grub_dl_ref (my_mod); + + data = grub_udf_mount (device->disk); +@@ -1083,7 +1086,7 @@ grub_udf_dir (grub_device_t device, const char *path, + GRUB_FSHELP_DIR)) + goto fail; + +- grub_udf_iterate_dir (foundnode, iterate); ++ grub_udf_iterate_dir (foundnode, grub_udf_dir_iter, &ctx); + + if (foundnode != rootnode) + grub_free (foundnode); +diff --git a/grub-core/fs/ufs.c b/grub-core/fs/ufs.c +index 74a4a40..089a5c6 100644 +--- a/grub-core/fs/ufs.c ++++ b/grub-core/fs/ufs.c +@@ -625,8 +625,7 @@ grub_ufs_mount (grub_disk_t disk) + + static grub_err_t + grub_ufs_dir (grub_device_t device, const char *path, +- int (*hook) (const char *filename, +- const struct grub_dirhook_info *info)) ++ grub_fs_dir_hook_t hook, void *hook_data) + { + struct grub_ufs_data *data; + unsigned int pos = 0; +@@ -697,7 +696,7 @@ grub_ufs_dir (grub_device_t device, const char *path, + #endif + info.mtimeset = 1; + +- if (hook (filename, &info)) ++ if (hook (filename, &info, hook_data)) + break; + } + +diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c +index 1ed048f..49d2a89 100644 +--- a/grub-core/fs/xfs.c ++++ b/grub-core/fs/xfs.c +@@ -443,47 +443,57 @@ grub_xfs_mode_to_filetype (grub_uint16_t mode) + } + + +-static int +-grub_xfs_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)) ++/* Context for grub_xfs_iterate_dir. */ ++struct grub_xfs_iterate_dir_ctx + { +- struct grub_fshelp_node *diro = (struct grub_fshelp_node *) dir; +- auto int NESTED_FUNC_ATTR call_hook (grub_uint64_t ino, const char *filename); ++ grub_fshelp_iterate_dir_hook_t hook; ++ void *hook_data; ++ struct grub_fshelp_node *diro; ++}; + +- int NESTED_FUNC_ATTR call_hook (grub_uint64_t ino, const char *filename) +- { +- struct grub_fshelp_node *fdiro; +- grub_err_t err; +- +- fdiro = grub_malloc (sizeof (struct grub_fshelp_node) +- - sizeof (struct grub_xfs_inode) +- + (1 << diro->data->sblock.log2_inode)); +- if (!fdiro) +- { +- grub_print_error (); +- return 0; +- } ++/* Helper for grub_xfs_iterate_dir. */ ++static int iterate_dir_call_hook (grub_uint64_t ino, const char *filename, ++ struct grub_xfs_iterate_dir_ctx *ctx) ++{ ++ struct grub_fshelp_node *fdiro; ++ grub_err_t err; + +- /* The inode should be read, otherwise the filetype can +- not be determined. */ +- fdiro->ino = ino; +- fdiro->inode_read = 1; +- fdiro->data = diro->data; +- err = grub_xfs_read_inode (diro->data, ino, &fdiro->inode); +- if (err) +- { +- grub_print_error (); +- return 0; +- } ++ fdiro = grub_malloc (sizeof (struct grub_fshelp_node) ++ - sizeof (struct grub_xfs_inode) ++ + (1 << ctx->diro->data->sblock.log2_inode)); ++ if (!fdiro) ++ { ++ grub_print_error (); ++ return 0; ++ } + +- return hook (filename, +- grub_xfs_mode_to_filetype (fdiro->inode.mode), +- fdiro); ++ /* The inode should be read, otherwise the filetype can ++ not be determined. */ ++ fdiro->ino = ino; ++ fdiro->inode_read = 1; ++ fdiro->data = ctx->diro->data; ++ err = grub_xfs_read_inode (ctx->diro->data, ino, &fdiro->inode); ++ if (err) ++ { ++ grub_print_error (); ++ return 0; + } + ++ return ctx->hook (filename, grub_xfs_mode_to_filetype (fdiro->inode.mode), ++ fdiro, ctx->hook_data); ++} ++ ++static int ++grub_xfs_iterate_dir (grub_fshelp_node_t dir, ++ grub_fshelp_iterate_dir_hook_t hook, void *hook_data) ++{ ++ struct grub_fshelp_node *diro = (struct grub_fshelp_node *) dir; ++ struct grub_xfs_iterate_dir_ctx ctx = { ++ .hook = hook, ++ .hook_data = hook_data, ++ .diro = diro ++ }; ++ + switch (diro->inode.format) + { + case XFS_INODE_FORMAT_INO: +@@ -508,10 +518,10 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir, + } + + /* Synthesize the direntries for `.' and `..'. */ +- if (call_hook (diro->ino, ".")) ++ if (iterate_dir_call_hook (diro->ino, ".", &ctx)) + return 1; + +- if (call_hook (parent, "..")) ++ if (iterate_dir_call_hook (parent, "..", &ctx)) + return 1; + + for (i = 0; i < diro->inode.data.dir.dirhead.count; i++) +@@ -541,7 +551,7 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir, + + grub_memcpy (name, de->name, de->len); + name[de->len] = '\0'; +- if (call_hook (ino, name)) ++ if (iterate_dir_call_hook (ino, name, &ctx)) + return 1; + + de = ((struct grub_xfs_dir_entry *) +@@ -619,7 +629,7 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir, + is not used by GRUB. So it can be overwritten. */ + filename[direntry->len] = '\0'; + +- if (call_hook (direntry->inode, filename)) ++ if (iterate_dir_call_hook (direntry->inode, filename, &ctx)) + { + grub_free (dirblock); + return 1; +@@ -703,33 +713,39 @@ grub_xfs_mount (grub_disk_t disk) + } + + +-static grub_err_t +-grub_xfs_dir (grub_device_t device, const char *path, +- int (*hook) (const char *filename, +- const struct grub_dirhook_info *info)) ++/* Context for grub_xfs_dir. */ ++struct grub_xfs_dir_ctx + { +- struct grub_xfs_data *data = 0; +- struct grub_fshelp_node *fdiro = 0; ++ grub_fs_dir_hook_t hook; ++ void *hook_data; ++}; + +- auto int NESTED_FUNC_ATTR iterate (const char *filename, +- enum grub_fshelp_filetype filetype, +- grub_fshelp_node_t node); ++/* Helper for grub_xfs_dir. */ ++static int ++grub_xfs_dir_iter (const char *filename, enum grub_fshelp_filetype filetype, ++ grub_fshelp_node_t node, void *data) ++{ ++ struct grub_xfs_dir_ctx *ctx = data; ++ struct grub_dirhook_info info; + +- int NESTED_FUNC_ATTR iterate (const char *filename, +- enum grub_fshelp_filetype filetype, +- grub_fshelp_node_t node) ++ grub_memset (&info, 0, sizeof (info)); ++ if (node->inode_read) + { +- struct grub_dirhook_info info; +- grub_memset (&info, 0, sizeof (info)); +- if (node->inode_read) +- { +- info.mtimeset = 1; +- info.mtime = grub_be_to_cpu32 (node->inode.mtime.sec); +- } +- info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); +- grub_free (node); +- return hook (filename, &info); ++ info.mtimeset = 1; ++ info.mtime = grub_be_to_cpu32 (node->inode.mtime.sec); + } ++ info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); ++ grub_free (node); ++ return ctx->hook (filename, &info, ctx->hook_data); ++} ++ ++static grub_err_t ++grub_xfs_dir (grub_device_t device, const char *path, ++ grub_fs_dir_hook_t hook, void *hook_data) ++{ ++ struct grub_xfs_dir_ctx ctx = { hook, hook_data }; ++ struct grub_xfs_data *data = 0; ++ struct grub_fshelp_node *fdiro = 0; + + grub_dl_ref (my_mod); + +@@ -742,7 +758,7 @@ grub_xfs_dir (grub_device_t device, const char *path, + if (grub_errno) + goto fail; + +- grub_xfs_iterate_dir (fdiro, iterate); ++ grub_xfs_iterate_dir (fdiro, grub_xfs_dir_iter, &ctx); + + fail: + if (fdiro != &data->diropen) +diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c +index 6ef6db3..822d65b 100644 +--- a/grub-core/fs/zfs/zfs.c ++++ b/grub-core/fs/zfs/zfs.c +@@ -253,6 +253,14 @@ struct grub_zfs_data + grub_uint64_t guid; + }; + ++/* Context for grub_zfs_dir. */ ++struct grub_zfs_dir_ctx ++{ ++ grub_fs_dir_hook_t hook; ++ void *hook_data; ++ struct grub_zfs_data *data; ++}; ++ + grub_err_t (*grub_zfs_decrypt) (grub_crypto_cipher_handle_t cipher, + grub_uint64_t algo, + void *nonce, +@@ -1790,8 +1798,9 @@ mzap_lookup (mzap_phys_t * zapobj, grub_zfs_endian_t endian, + + static int + mzap_iterate (mzap_phys_t * zapobj, grub_zfs_endian_t endian, int objsize, +- int NESTED_FUNC_ATTR (*hook) (const char *name, +- grub_uint64_t val)) ++ int (*hook) (const char *name, grub_uint64_t val, ++ struct grub_zfs_dir_ctx *ctx), ++ struct grub_zfs_dir_ctx *ctx) + { + int i, chunks; + mzap_ent_phys_t *mzap_ent = zapobj->mz_chunk; +@@ -1803,7 +1812,7 @@ mzap_iterate (mzap_phys_t * zapobj, grub_zfs_endian_t endian, int objsize, + mzap_ent[i].mze_name, (long long)mzap_ent[i].mze_value, + (int)mzap_ent[i].mze_cd); + if (hook (mzap_ent[i].mze_name, +- grub_zfs_to_cpu64 (mzap_ent[i].mze_value, endian))) ++ grub_zfs_to_cpu64 (mzap_ent[i].mze_value, endian), ctx)) + return 1; + } + +@@ -2054,12 +2063,11 @@ fzap_lookup (dnode_end_t * zap_dnode, zap_phys_t * zap, + static int + fzap_iterate (dnode_end_t * zap_dnode, zap_phys_t * zap, + grub_size_t name_elem_length, +- int NESTED_FUNC_ATTR (*hook) (const void *name, +- grub_size_t name_length, +- const void *val_in, +- grub_size_t nelem, +- grub_size_t elemsize), +- struct grub_zfs_data *data) ++ int (*hook) (const void *name, grub_size_t name_length, ++ const void *val_in, ++ grub_size_t nelem, grub_size_t elemsize, ++ void *data), ++ void *hook_data, struct grub_zfs_data *data) + { + zap_leaf_phys_t *l; + void *l_in; +@@ -2158,7 +2166,7 @@ fzap_iterate (dnode_end_t * zap_dnode, zap_phys_t * zap, + } + + if (hook (buf, le->le_name_length, +- val, le->le_value_length, le->le_int_size)) ++ val, le->le_value_length, le->le_int_size, hook_data)) + { + grub_free (l); + return 1; +@@ -2221,11 +2229,35 @@ zap_lookup (dnode_end_t * zap_dnode, const char *name, grub_uint64_t *val, + return grub_error (GRUB_ERR_BAD_FS, "unknown ZAP type"); + } + ++/* Context for zap_iterate_u64. */ ++struct zap_iterate_u64_ctx ++{ ++ int (*hook) (const char *, grub_uint64_t, struct grub_zfs_dir_ctx *); ++ struct grub_zfs_dir_ctx *dir_ctx; ++}; ++ ++/* Helper for zap_iterate_u64. */ ++static int ++zap_iterate_u64_transform (const void *name, ++ grub_size_t namelen __attribute__ ((unused)), ++ const void *val_in, ++ grub_size_t nelem, ++ grub_size_t elemsize, ++ void *data) ++{ ++ struct zap_iterate_u64_ctx *ctx = data; ++ ++ if (elemsize != sizeof (grub_uint64_t) || nelem != 1) ++ return 0; ++ return ctx->hook (name, grub_be_to_cpu64 (*(const grub_uint64_t *) val_in), ++ ctx->dir_ctx); ++} ++ + static int + zap_iterate_u64 (dnode_end_t * zap_dnode, +- int NESTED_FUNC_ATTR (*hook) (const char *name, +- grub_uint64_t val), +- struct grub_zfs_data *data) ++ int (*hook) (const char *name, grub_uint64_t val, ++ struct grub_zfs_dir_ctx *ctx), ++ struct grub_zfs_data *data, struct grub_zfs_dir_ctx *ctx) + { + grub_uint64_t block_type; + int size; +@@ -2234,23 +2266,6 @@ zap_iterate_u64 (dnode_end_t * zap_dnode, + int ret; + grub_zfs_endian_t endian; + +- auto int NESTED_FUNC_ATTR transform (const void *name, +- grub_size_t namelen, +- const void *val_in, +- grub_size_t nelem, +- grub_size_t elemsize); +- +- int NESTED_FUNC_ATTR transform (const void *name, +- grub_size_t namelen __attribute__ ((unused)), +- const void *val_in, +- grub_size_t nelem, +- grub_size_t elemsize) +- { +- if (elemsize != sizeof (grub_uint64_t) || nelem != 1) +- return 0; +- return hook (name, grub_be_to_cpu64 (*(const grub_uint64_t *) val_in)); +- } +- + /* Read in the first block of the zap object data. */ + size = grub_zfs_to_cpu16 (zap_dnode->dn.dn_datablkszsec, zap_dnode->endian) << SPA_MINBLOCKSHIFT; + err = dmu_read (zap_dnode, 0, &zapbuf, &endian, data); +@@ -2263,15 +2278,21 @@ zap_iterate_u64 (dnode_end_t * zap_dnode, + if (block_type == ZBT_MICRO) + { + grub_dprintf ("zfs", "micro zap\n"); +- ret = mzap_iterate (zapbuf, endian, size, hook); ++ ret = mzap_iterate (zapbuf, endian, size, hook, ctx); + grub_free (zapbuf); + return ret; + } + else if (block_type == ZBT_HEADER) + { ++ struct zap_iterate_u64_ctx transform_ctx = { ++ .hook = hook, ++ .dir_ctx = ctx ++ }; ++ + grub_dprintf ("zfs", "fat zap\n"); + /* this is a fat zap */ +- ret = fzap_iterate (zap_dnode, zapbuf, 1, transform, data); ++ ret = fzap_iterate (zap_dnode, zapbuf, 1, ++ zap_iterate_u64_transform, &transform_ctx, data); + grub_free (zapbuf); + return ret; + } +@@ -2282,12 +2303,11 @@ zap_iterate_u64 (dnode_end_t * zap_dnode, + static int + zap_iterate (dnode_end_t * zap_dnode, + grub_size_t nameelemlen, +- int NESTED_FUNC_ATTR (*hook) (const void *name, +- grub_size_t namelen, +- const void *val_in, +- grub_size_t nelem, +- grub_size_t elemsize), +- struct grub_zfs_data *data) ++ int (*hook) (const void *name, grub_size_t namelen, ++ const void *val_in, ++ grub_size_t nelem, grub_size_t elemsize, ++ void *data), ++ void *hook_data, struct grub_zfs_data *data) + { + grub_uint64_t block_type; + void *zapbuf; +@@ -2312,7 +2332,8 @@ zap_iterate (dnode_end_t * zap_dnode, + { + grub_dprintf ("zfs", "fat zap\n"); + /* this is a fat zap */ +- ret = fzap_iterate (zap_dnode, zapbuf, nameelemlen, hook, data); ++ ret = fzap_iterate (zap_dnode, zapbuf, nameelemlen, hook, hook_data, ++ data); + grub_free (zapbuf); + return ret; + } +@@ -2826,6 +2847,61 @@ make_mdn (dnode_end_t * mdn, struct grub_zfs_data *data) + return GRUB_ERR_NONE; + } + ++/* Context for dnode_get_fullpath. */ ++struct dnode_get_fullpath_ctx ++{ ++ struct subvolume *subvol; ++ grub_uint64_t salt; ++ int keyn; ++}; ++ ++/* Helper for dnode_get_fullpath. */ ++static int ++count_zap_keys (const void *name __attribute__ ((unused)), ++ grub_size_t namelen __attribute__ ((unused)), ++ const void *val_in __attribute__ ((unused)), ++ grub_size_t nelem __attribute__ ((unused)), ++ grub_size_t elemsize __attribute__ ((unused)), ++ void *data) ++{ ++ struct dnode_get_fullpath_ctx *ctx = data; ++ ++ ctx->subvol->nkeys++; ++ return 0; ++} ++ ++/* Helper for dnode_get_fullpath. */ ++static int ++load_zap_key (const void *name, grub_size_t namelen, const void *val_in, ++ grub_size_t nelem, grub_size_t elemsize, void *data) ++{ ++ struct dnode_get_fullpath_ctx *ctx = data; ++ ++ if (namelen != 1) ++ { ++ grub_dprintf ("zfs", "Unexpected key index size %" PRIuGRUB_SIZE "\n", ++ namelen); ++ return 0; ++ } ++ ++ if (elemsize != 1) ++ { ++ grub_dprintf ("zfs", "Unexpected key element size %" PRIuGRUB_SIZE "\n", ++ elemsize); ++ return 0; ++ } ++ ++ ctx->subvol->keyring[ctx->keyn].txg = ++ grub_be_to_cpu64 (*(grub_uint64_t *) name); ++ ctx->subvol->keyring[ctx->keyn].algo = ++ grub_le_to_cpu64 (*(grub_uint64_t *) val_in); ++ ctx->subvol->keyring[ctx->keyn].cipher = ++ grub_zfs_load_key (val_in, nelem, ctx->salt, ++ ctx->subvol->keyring[ctx->keyn].algo); ++ ctx->keyn++; ++ return 0; ++} ++ + static grub_err_t + dnode_get_fullpath (const char *fullpath, struct subvolume *subvol, + dnode_end_t * dn, int *isfs, +@@ -2835,57 +2911,7 @@ dnode_get_fullpath (const char *fullpath, struct subvolume *subvol, + const char *ptr_at, *filename; + grub_uint64_t headobj; + grub_uint64_t keychainobj; +- grub_uint64_t salt; + grub_err_t err; +- int keyn = 0; +- +- auto int NESTED_FUNC_ATTR count_zap_keys (const void *name, +- grub_size_t namelen, +- const void *val_in, +- grub_size_t nelem, +- grub_size_t elemsize); +- int NESTED_FUNC_ATTR count_zap_keys (const void *name __attribute__ ((unused)), +- grub_size_t namelen __attribute__ ((unused)), +- const void *val_in __attribute__ ((unused)), +- grub_size_t nelem __attribute__ ((unused)), +- grub_size_t elemsize __attribute__ ((unused))) +- { +- subvol->nkeys++; +- return 0; +- } +- +- auto int NESTED_FUNC_ATTR load_zap_key (const void *name, +- grub_size_t namelen, +- const void *val_in, +- grub_size_t nelem, +- grub_size_t elemsize); +- int NESTED_FUNC_ATTR load_zap_key (const void *name, +- grub_size_t namelen, +- const void *val_in, +- grub_size_t nelem, +- grub_size_t elemsize) +- { +- if (namelen != 1) +- { +- grub_dprintf ("zfs", "Unexpected key index size %" PRIuGRUB_SIZE "\n", +- namelen); +- return 0; +- } +- +- if (elemsize != 1) +- { +- grub_dprintf ("zfs", "Unexpected key element size %" PRIuGRUB_SIZE "\n", +- elemsize); +- return 0; +- } +- +- subvol->keyring[keyn].txg = grub_be_to_cpu64 (*(grub_uint64_t *) name); +- subvol->keyring[keyn].algo = grub_le_to_cpu64 (*(grub_uint64_t *) val_in); +- subvol->keyring[keyn].cipher = grub_zfs_load_key (val_in, nelem, salt, +- subvol->keyring[keyn].algo); +- keyn++; +- return 0; +- } + + ptr_at = grub_strchr (fullpath, '@'); + if (! ptr_at) +@@ -2953,6 +2979,10 @@ dnode_get_fullpath (const char *fullpath, struct subvolume *subvol, + keychainobj = grub_zfs_to_cpu64 (((dsl_dir_phys_t *) DN_BONUS (&dn->dn))->keychain, dn->endian); + if (grub_zfs_load_key && keychainobj) + { ++ struct dnode_get_fullpath_ctx ctx = { ++ .subvol = subvol, ++ .keyn = 0 ++ }; + dnode_end_t keychain_dn, props_dn; + grub_uint64_t propsobj; + propsobj = grub_zfs_to_cpu64 (((dsl_dir_phys_t *) DN_BONUS (&dn->dn))->dd_props_zapobj, dn->endian); +@@ -2966,12 +2996,12 @@ dnode_get_fullpath (const char *fullpath, struct subvolume *subvol, + return err; + } + +- err = zap_lookup (&props_dn, "salt", &salt, data, 0); ++ err = zap_lookup (&props_dn, "salt", &ctx.salt, data, 0); + if (err == GRUB_ERR_FILE_NOT_FOUND) + { + err = 0; + grub_errno = 0; +- salt = 0; ++ ctx.salt = 0; + } + if (err) + { +@@ -2988,7 +3018,7 @@ dnode_get_fullpath (const char *fullpath, struct subvolume *subvol, + return err; + } + subvol->nkeys = 0; +- zap_iterate (&keychain_dn, 8, count_zap_keys, data); ++ zap_iterate (&keychain_dn, 8, count_zap_keys, &ctx, data); + subvol->keyring = grub_zalloc (subvol->nkeys * sizeof (subvol->keyring[0])); + if (!subvol->keyring) + { +@@ -2996,7 +3026,7 @@ dnode_get_fullpath (const char *fullpath, struct subvolume *subvol, + grub_free (snapname); + return err; + } +- zap_iterate (&keychain_dn, 8, load_zap_key, data); ++ zap_iterate (&keychain_dn, 8, load_zap_key, &ctx, data); + } + + if (snapname) +@@ -3748,108 +3778,122 @@ fill_fs_info (struct grub_dirhook_info *info, + return; + } + +-static grub_err_t +-grub_zfs_dir (grub_device_t device, const char *path, +- int (*hook) (const char *, const struct grub_dirhook_info *)) ++/* Helper for grub_zfs_dir. */ ++static int ++iterate_zap (const char *name, grub_uint64_t val, struct grub_zfs_dir_ctx *ctx) + { +- struct grub_zfs_data *data; + grub_err_t err; +- int isfs; +- auto int NESTED_FUNC_ATTR iterate_zap (const char *name, grub_uint64_t val); +- auto int NESTED_FUNC_ATTR iterate_zap_fs (const char *name, +- grub_uint64_t val); +- auto int NESTED_FUNC_ATTR iterate_zap_snap (const char *name, +- grub_uint64_t val); ++ struct grub_dirhook_info info; + +- int NESTED_FUNC_ATTR iterate_zap (const char *name, grub_uint64_t val) +- { +- struct grub_dirhook_info info; +- dnode_end_t dn; +- grub_memset (&info, 0, sizeof (info)); ++ dnode_end_t dn; ++ grub_memset (&info, 0, sizeof (info)); + +- dnode_get (&(data->subvol.mdn), val, 0, &dn, data); ++ dnode_get (&(ctx->data->subvol.mdn), val, 0, &dn, ctx->data); + +- if (dn.dn.dn_bonustype == DMU_OT_SA) +- { +- void *sahdrp; +- int hdrsize; ++ if (dn.dn.dn_bonustype == DMU_OT_SA) ++ { ++ void *sahdrp; ++ int hdrsize; + +- if (dn.dn.dn_bonuslen != 0) +- { +- sahdrp = (sa_hdr_phys_t *) DN_BONUS (&data->dnode.dn); +- } +- else if (dn.dn.dn_flags & DNODE_FLAG_SPILL_BLKPTR) +- { +- blkptr_t *bp = &dn.dn.dn_spill; ++ if (dn.dn.dn_bonuslen != 0) ++ { ++ sahdrp = (sa_hdr_phys_t *) DN_BONUS (&ctx->data->dnode.dn); ++ } ++ else if (dn.dn.dn_flags & DNODE_FLAG_SPILL_BLKPTR) ++ { ++ blkptr_t *bp = &dn.dn.dn_spill; + +- err = zio_read (bp, dn.endian, &sahdrp, NULL, data); +- if (err) +- { +- grub_print_error (); +- return 0; +- } +- } +- else +- { +- grub_error (GRUB_ERR_BAD_FS, "filesystem is corrupt"); +- grub_print_error (); +- return 0; +- } ++ err = zio_read (bp, dn.endian, &sahdrp, NULL, ctx->data); ++ if (err) ++ { ++ grub_print_error (); ++ return 0; ++ } ++ } ++ else ++ { ++ grub_error (GRUB_ERR_BAD_FS, "filesystem is corrupt"); ++ grub_print_error (); ++ return 0; ++ } + +- hdrsize = SA_HDR_SIZE (((sa_hdr_phys_t *) sahdrp)); +- info.mtimeset = 1; +- info.mtime = grub_zfs_to_cpu64 (grub_get_unaligned64 ((char *) sahdrp + hdrsize + SA_MTIME_OFFSET), dn.endian); +- info.case_insensitive = data->subvol.case_insensitive; +- } +- +- if (dn.dn.dn_bonustype == DMU_OT_ZNODE) +- { +- info.mtimeset = 1; +- info.mtime = grub_zfs_to_cpu64 (((znode_phys_t *) DN_BONUS (&dn.dn))->zp_mtime[0], +- dn.endian); +- } +- info.dir = (dn.dn.dn_type == DMU_OT_DIRECTORY_CONTENTS); +- grub_dprintf ("zfs", "type=%d, name=%s\n", +- (int)dn.dn.dn_type, (char *)name); +- return hook (name, &info); +- } ++ hdrsize = SA_HDR_SIZE (((sa_hdr_phys_t *) sahdrp)); ++ info.mtimeset = 1; ++ info.mtime = grub_zfs_to_cpu64 (grub_get_unaligned64 ((char *) sahdrp + hdrsize + SA_MTIME_OFFSET), dn.endian); ++ info.case_insensitive = ctx->data->subvol.case_insensitive; ++ } ++ ++ if (dn.dn.dn_bonustype == DMU_OT_ZNODE) ++ { ++ info.mtimeset = 1; ++ info.mtime = grub_zfs_to_cpu64 (((znode_phys_t *) DN_BONUS (&dn.dn))->zp_mtime[0], ++ dn.endian); ++ } ++ info.dir = (dn.dn.dn_type == DMU_OT_DIRECTORY_CONTENTS); ++ grub_dprintf ("zfs", "type=%d, name=%s\n", ++ (int)dn.dn.dn_type, (char *)name); ++ return ctx->hook (name, &info, ctx->hook_data); ++} + +- int NESTED_FUNC_ATTR iterate_zap_fs (const char *name, grub_uint64_t val) +- { +- struct grub_dirhook_info info; +- dnode_end_t mdn; +- err = dnode_get (&(data->mos), val, 0, &mdn, data); +- if (err) +- return 0; +- if (mdn.dn.dn_type != DMU_OT_DSL_DIR) +- return 0; ++/* Helper for grub_zfs_dir. */ ++static int ++iterate_zap_fs (const char *name, grub_uint64_t val, ++ struct grub_zfs_dir_ctx *ctx) ++{ ++ grub_err_t err; ++ struct grub_dirhook_info info; + +- fill_fs_info (&info, mdn, data); +- return hook (name, &info); +- } +- int NESTED_FUNC_ATTR iterate_zap_snap (const char *name, grub_uint64_t val) +- { +- struct grub_dirhook_info info; +- char *name2; +- int ret; +- dnode_end_t mdn; ++ dnode_end_t mdn; ++ err = dnode_get (&(ctx->data->mos), val, 0, &mdn, ctx->data); ++ if (err) ++ return 0; ++ if (mdn.dn.dn_type != DMU_OT_DSL_DIR) ++ return 0; + +- err = dnode_get (&(data->mos), val, 0, &mdn, data); +- if (err) +- return 0; ++ fill_fs_info (&info, mdn, ctx->data); ++ return ctx->hook (name, &info, ctx->hook_data); ++} + +- if (mdn.dn.dn_type != DMU_OT_DSL_DATASET) +- return 0; ++/* Helper for grub_zfs_dir. */ ++static int ++iterate_zap_snap (const char *name, grub_uint64_t val, ++ struct grub_zfs_dir_ctx *ctx) ++{ ++ grub_err_t err; ++ struct grub_dirhook_info info; ++ char *name2; ++ int ret; ++ ++ dnode_end_t mdn; + +- fill_fs_info (&info, mdn, data); ++ err = dnode_get (&(ctx->data->mos), val, 0, &mdn, ctx->data); ++ if (err) ++ return 0; + +- name2 = grub_malloc (grub_strlen (name) + 2); +- name2[0] = '@'; +- grub_memcpy (name2 + 1, name, grub_strlen (name) + 1); +- ret = hook (name2, &info); +- grub_free (name2); +- return ret; +- } ++ if (mdn.dn.dn_type != DMU_OT_DSL_DATASET) ++ return 0; ++ ++ fill_fs_info (&info, mdn, ctx->data); ++ ++ name2 = grub_malloc (grub_strlen (name) + 2); ++ name2[0] = '@'; ++ grub_memcpy (name2 + 1, name, grub_strlen (name) + 1); ++ ret = ctx->hook (name2, &info, ctx->hook_data); ++ grub_free (name2); ++ return ret; ++} ++ ++static grub_err_t ++grub_zfs_dir (grub_device_t device, const char *path, ++ grub_fs_dir_hook_t hook, void *hook_data) ++{ ++ struct grub_zfs_dir_ctx ctx = { ++ .hook = hook, ++ .hook_data = hook_data ++ }; ++ struct grub_zfs_data *data; ++ grub_err_t err; ++ int isfs; + + data = zfs_mount (device); + if (! data) +@@ -3860,6 +3904,8 @@ grub_zfs_dir (grub_device_t device, const char *path, + zfs_unmount (data); + return err; + } ++ ctx.data = data; ++ + if (isfs) + { + grub_uint64_t childobj, headobj; +@@ -3868,7 +3914,7 @@ grub_zfs_dir (grub_device_t device, const char *path, + struct grub_dirhook_info info; + + fill_fs_info (&info, data->dnode, data); +- hook ("@", &info); ++ hook ("@", &info, hook_data); + + childobj = grub_zfs_to_cpu64 (((dsl_dir_phys_t *) DN_BONUS (&data->dnode.dn))->dd_child_dir_zapobj, data->dnode.endian); + headobj = grub_zfs_to_cpu64 (((dsl_dir_phys_t *) DN_BONUS (&data->dnode.dn))->dd_head_dataset_obj, data->dnode.endian); +@@ -3880,7 +3926,7 @@ grub_zfs_dir (grub_device_t device, const char *path, + return err; + } + +- zap_iterate_u64 (&dn, iterate_zap_fs, data); ++ zap_iterate_u64 (&dn, iterate_zap_fs, data, &ctx); + + err = dnode_get (&(data->mos), headobj, DMU_OT_DSL_DATASET, &dn, data); + if (err) +@@ -3899,7 +3945,7 @@ grub_zfs_dir (grub_device_t device, const char *path, + return err; + } + +- zap_iterate_u64 (&dn, iterate_zap_snap, data); ++ zap_iterate_u64 (&dn, iterate_zap_snap, data, &ctx); + } + else + { +@@ -3908,7 +3954,7 @@ grub_zfs_dir (grub_device_t device, const char *path, + zfs_unmount (data); + return grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a directory")); + } +- zap_iterate_u64 (&(data->dnode), iterate_zap, data); ++ zap_iterate_u64 (&(data->dnode), iterate_zap, data, &ctx); + } + zfs_unmount (data); + return grub_errno; +diff --git a/grub-core/kern/corecmd.c b/grub-core/kern/corecmd.c +index 3441ccb..0dc4d00 100644 +--- a/grub-core/kern/corecmd.c ++++ b/grub-core/kern/corecmd.c +@@ -105,7 +105,8 @@ grub_mini_print_devices (const char *name, void *data __attribute__ ((unused))) + + static int + grub_mini_print_files (const char *filename, +- const struct grub_dirhook_info *info) ++ const struct grub_dirhook_info *info, ++ void *data __attribute__ ((unused))) + { + grub_printf ("%s%s ", filename, info->dir ? "/" : ""); + +@@ -160,7 +161,7 @@ grub_core_cmd_ls (struct grub_command *cmd __attribute__ ((unused)), + } + else if (fs) + { +- (fs->dir) (dev, path, grub_mini_print_files); ++ (fs->dir) (dev, path, grub_mini_print_files, NULL); + grub_xputs ("\n"); + grub_refresh (); + } +diff --git a/grub-core/kern/emu/hostfs.c b/grub-core/kern/emu/hostfs.c +index 3cb089c..46bf5e8 100644 +--- a/grub-core/kern/emu/hostfs.c ++++ b/grub-core/kern/emu/hostfs.c +@@ -65,8 +65,7 @@ struct grub_hostfs_data + + static grub_err_t + grub_hostfs_dir (grub_device_t device, const char *path, +- int (*hook) (const char *filename, +- const struct grub_dirhook_info *info)) ++ grub_fs_dir_hook_t hook, void *hook_data) + { + DIR *dir; + +@@ -91,7 +90,7 @@ grub_hostfs_dir (grub_device_t device, const char *path, + break; + + info.dir = !! is_dir (path, de->d_name); +- hook (de->d_name, &info); ++ hook (de->d_name, &info, hook_data); + + } + +diff --git a/grub-core/kern/fs.c b/grub-core/kern/fs.c +index 7e150f2..9085895 100644 +--- a/grub-core/kern/fs.c ++++ b/grub-core/kern/fs.c +@@ -35,10 +35,11 @@ grub_fs_autoload_hook_t grub_fs_autoload_hook = 0; + /* Helper for grub_fs_probe. */ + static int + probe_dummy_iter (const char *filename __attribute__ ((unused)), +- const struct grub_dirhook_info *info __attribute__ ((unused))) +- { +- return 1; +- } ++ const struct grub_dirhook_info *info __attribute__ ((unused)), ++ void *data __attribute__ ((unused))) ++{ ++ return 1; ++} + + grub_fs_t + grub_fs_probe (grub_device_t device) +@@ -69,7 +70,7 @@ grub_fs_probe (grub_device_t device) + } + else + #endif +- (p->dir) (device, "/", probe_dummy_iter); ++ (p->dir) (device, "/", probe_dummy_iter, NULL); + if (grub_errno == GRUB_ERR_NONE) + return p; + +@@ -93,7 +94,7 @@ grub_fs_probe (grub_device_t device) + { + p = grub_fs_list; + +- (p->dir) (device, "/", probe_dummy_iter); ++ (p->dir) (device, "/", probe_dummy_iter, NULL); + if (grub_errno == GRUB_ERR_NONE) + { + count--; +diff --git a/grub-core/loader/xnu.c b/grub-core/loader/xnu.c +index ed3fc72..8c522f5 100644 +--- a/grub-core/loader/xnu.c ++++ b/grub-core/loader/xnu.c +@@ -1017,49 +1017,66 @@ grub_xnu_check_os_bundle_required (char *plistname, + return ret; + } + ++/* Context for grub_xnu_scan_dir_for_kexts. */ ++struct grub_xnu_scan_dir_for_kexts_ctx ++{ ++ char *dirname; ++ const char *osbundlerequired; ++ int maxrecursion; ++}; ++ ++/* Helper for grub_xnu_scan_dir_for_kexts. */ ++static int ++grub_xnu_scan_dir_for_kexts_load (const char *filename, ++ const struct grub_dirhook_info *info, ++ void *data) ++{ ++ struct grub_xnu_scan_dir_for_kexts_ctx *ctx = data; ++ char *newdirname; ++ ++ if (! info->dir) ++ return 0; ++ if (filename[0] == '.') ++ return 0; ++ ++ if (grub_strlen (filename) < 5 || ++ grub_memcmp (filename + grub_strlen (filename) - 5, ".kext", 5) != 0) ++ return 0; ++ ++ newdirname ++ = grub_malloc (grub_strlen (ctx->dirname) + grub_strlen (filename) + 2); ++ ++ /* It's a .kext. Try to load it. */ ++ if (newdirname) ++ { ++ grub_strcpy (newdirname, ctx->dirname); ++ newdirname[grub_strlen (newdirname) + 1] = 0; ++ newdirname[grub_strlen (newdirname)] = '/'; ++ grub_strcpy (newdirname + grub_strlen (newdirname), filename); ++ grub_xnu_load_kext_from_dir (newdirname, ctx->osbundlerequired, ++ ctx->maxrecursion); ++ if (grub_errno == GRUB_ERR_BAD_OS) ++ grub_errno = GRUB_ERR_NONE; ++ grub_free (newdirname); ++ } ++ return 0; ++} ++ + /* Load all loadable kexts placed under DIRNAME and matching OSBUNDLEREQUIRED */ + grub_err_t + grub_xnu_scan_dir_for_kexts (char *dirname, const char *osbundlerequired, + int maxrecursion) + { ++ struct grub_xnu_scan_dir_for_kexts_ctx ctx = { ++ .dirname = dirname, ++ .osbundlerequired = osbundlerequired, ++ .maxrecursion = maxrecursion ++ }; + grub_device_t dev; + char *device_name; + grub_fs_t fs; + const char *path; + +- auto int load_hook (const char *filename, +- const struct grub_dirhook_info *info); +- int load_hook (const char *filename, const struct grub_dirhook_info *info) +- { +- char *newdirname; +- if (! info->dir) +- return 0; +- if (filename[0] == '.') +- return 0; +- +- if (grub_strlen (filename) < 5 || +- grub_memcmp (filename + grub_strlen (filename) - 5, ".kext", 5) != 0) +- return 0; +- +- newdirname +- = grub_malloc (grub_strlen (dirname) + grub_strlen (filename) + 2); +- +- /* It's a .kext. Try to load it. */ +- if (newdirname) +- { +- grub_strcpy (newdirname, dirname); +- newdirname[grub_strlen (newdirname) + 1] = 0; +- newdirname[grub_strlen (newdirname)] = '/'; +- grub_strcpy (newdirname + grub_strlen (newdirname), filename); +- grub_xnu_load_kext_from_dir (newdirname, osbundlerequired, +- maxrecursion); +- if (grub_errno == GRUB_ERR_BAD_OS) +- grub_errno = GRUB_ERR_NONE; +- grub_free (newdirname); +- } +- return 0; +- } +- + if (! grub_xnu_heap_size) + return grub_error (GRUB_ERR_BAD_OS, N_("you need to load the kernel first")); + +@@ -1075,7 +1092,7 @@ grub_xnu_scan_dir_for_kexts (char *dirname, const char *osbundlerequired, + path++; + + if (fs) +- (fs->dir) (dev, path, load_hook); ++ (fs->dir) (dev, path, grub_xnu_scan_dir_for_kexts_load, &ctx); + grub_device_close (dev); + } + grub_free (device_name); +@@ -1083,60 +1100,78 @@ grub_xnu_scan_dir_for_kexts (char *dirname, const char *osbundlerequired, + return GRUB_ERR_NONE; + } + ++/* Context for grub_xnu_load_kext_from_dir. */ ++struct grub_xnu_load_kext_from_dir_ctx ++{ ++ char *dirname; ++ const char *osbundlerequired; ++ int maxrecursion; ++ char *plistname; ++ char *newdirname; ++ int usemacos; ++}; ++ ++/* Helper for grub_xnu_load_kext_from_dir. */ ++static int ++grub_xnu_load_kext_from_dir_load (const char *filename, ++ const struct grub_dirhook_info *info, ++ void *data) ++{ ++ struct grub_xnu_load_kext_from_dir_ctx *ctx = data; ++ ++ if (grub_strlen (filename) > 15) ++ return 0; ++ grub_strcpy (ctx->newdirname + grub_strlen (ctx->dirname) + 1, filename); ++ ++ /* If the kext contains directory "Contents" all real stuff is in ++ this directory. */ ++ if (info->dir && grub_strcasecmp (filename, "Contents") == 0) ++ grub_xnu_load_kext_from_dir (ctx->newdirname, ctx->osbundlerequired, ++ ctx->maxrecursion - 1); ++ ++ /* Directory "Plugins" contains nested kexts. */ ++ if (info->dir && grub_strcasecmp (filename, "Plugins") == 0) ++ grub_xnu_scan_dir_for_kexts (ctx->newdirname, ctx->osbundlerequired, ++ ctx->maxrecursion - 1); ++ ++ /* Directory "MacOS" contains executable, otherwise executable is ++ on the top. */ ++ if (info->dir && grub_strcasecmp (filename, "MacOS") == 0) ++ ctx->usemacos = 1; ++ ++ /* Info.plist is the file which governs our future actions. */ ++ if (! info->dir && grub_strcasecmp (filename, "Info.plist") == 0 ++ && ! ctx->plistname) ++ ctx->plistname = grub_strdup (ctx->newdirname); ++ return 0; ++} ++ + /* Load extension DIRNAME. (extensions are directories in xnu) */ + grub_err_t + grub_xnu_load_kext_from_dir (char *dirname, const char *osbundlerequired, + int maxrecursion) + { ++ struct grub_xnu_load_kext_from_dir_ctx ctx = { ++ .dirname = dirname, ++ .osbundlerequired = osbundlerequired, ++ .maxrecursion = maxrecursion, ++ .plistname = 0, ++ .usemacos = 0 ++ }; + grub_device_t dev; +- char *plistname = 0; +- char *newdirname; + char *newpath; + char *device_name; + grub_fs_t fs; + const char *path; + char *binsuffix; +- int usemacos = 0; + grub_file_t binfile; + +- auto int load_hook (const char *filename, +- const struct grub_dirhook_info *info); +- +- int load_hook (const char *filename, const struct grub_dirhook_info *info) +- { +- if (grub_strlen (filename) > 15) +- return 0; +- grub_strcpy (newdirname + grub_strlen (dirname) + 1, filename); +- +- /* If the kext contains directory "Contents" all real stuff is in +- this directory. */ +- if (info->dir && grub_strcasecmp (filename, "Contents") == 0) +- grub_xnu_load_kext_from_dir (newdirname, osbundlerequired, +- maxrecursion - 1); +- +- /* Directory "Plugins" contains nested kexts. */ +- if (info->dir && grub_strcasecmp (filename, "Plugins") == 0) +- grub_xnu_scan_dir_for_kexts (newdirname, osbundlerequired, +- maxrecursion - 1); +- +- /* Directory "MacOS" contains executable, otherwise executable is +- on the top. */ +- if (info->dir && grub_strcasecmp (filename, "MacOS") == 0) +- usemacos = 1; +- +- /* Info.plist is the file which governs our future actions. */ +- if (! info->dir && grub_strcasecmp (filename, "Info.plist") == 0 +- && ! plistname) +- plistname = grub_strdup (newdirname); +- return 0; +- } +- +- newdirname = grub_malloc (grub_strlen (dirname) + 20); +- if (! newdirname) ++ ctx.newdirname = grub_malloc (grub_strlen (dirname) + 20); ++ if (! ctx.newdirname) + return grub_errno; +- grub_strcpy (newdirname, dirname); +- newdirname[grub_strlen (dirname)] = '/'; +- newdirname[grub_strlen (dirname) + 1] = 0; ++ grub_strcpy (ctx.newdirname, dirname); ++ ctx.newdirname[grub_strlen (dirname)] = '/'; ++ ctx.newdirname[grub_strlen (dirname) + 1] = 0; + device_name = grub_file_get_device_name (dirname); + dev = grub_device_open (device_name); + if (dev) +@@ -1148,18 +1183,18 @@ grub_xnu_load_kext_from_dir (char *dirname, const char *osbundlerequired, + else + path++; + +- newpath = grub_strchr (newdirname, ')'); ++ newpath = grub_strchr (ctx.newdirname, ')'); + if (! newpath) +- newpath = newdirname; ++ newpath = ctx.newdirname; + else + newpath++; + + /* Look at the directory. */ + if (fs) +- (fs->dir) (dev, path, load_hook); ++ (fs->dir) (dev, path, grub_xnu_load_kext_from_dir_load, &ctx); + +- if (plistname && grub_xnu_check_os_bundle_required +- (plistname, osbundlerequired, &binsuffix)) ++ if (ctx.plistname && grub_xnu_check_os_bundle_required ++ (ctx.plistname, osbundlerequired, &binsuffix)) + { + if (binsuffix) + { +@@ -1168,29 +1203,29 @@ grub_xnu_load_kext_from_dir (char *dirname, const char *osbundlerequired, + + grub_strlen (binsuffix) + + sizeof ("/MacOS/")); + grub_strcpy (binname, dirname); +- if (usemacos) ++ if (ctx.usemacos) + grub_strcpy (binname + grub_strlen (binname), "/MacOS/"); + else + grub_strcpy (binname + grub_strlen (binname), "/"); + grub_strcpy (binname + grub_strlen (binname), binsuffix); +- grub_dprintf ("xnu", "%s:%s\n", plistname, binname); ++ grub_dprintf ("xnu", "%s:%s\n", ctx.plistname, binname); + binfile = grub_file_open (binname); + if (! binfile) + grub_errno = GRUB_ERR_NONE; + + /* Load the extension. */ +- grub_xnu_load_driver (plistname, binfile, ++ grub_xnu_load_driver (ctx.plistname, binfile, + binname); + grub_free (binname); + grub_free (binsuffix); + } + else + { +- grub_dprintf ("xnu", "%s:0\n", plistname); +- grub_xnu_load_driver (plistname, 0, 0); ++ grub_dprintf ("xnu", "%s:0\n", ctx.plistname); ++ grub_xnu_load_driver (ctx.plistname, 0, 0); + } + } +- grub_free (plistname); ++ grub_free (ctx.plistname); + grub_device_close (dev); + } + grub_free (device_name); +diff --git a/grub-core/net/net.c b/grub-core/net/net.c +index 01c5d32..aebbe4b 100644 +--- a/grub-core/net/net.c ++++ b/grub-core/net/net.c +@@ -1253,8 +1253,8 @@ grub_net_open_real (const char *name) + + static grub_err_t + grub_net_fs_dir (grub_device_t device, const char *path __attribute__ ((unused)), +- int (*hook) (const char *filename, +- const struct grub_dirhook_info *info) __attribute__ ((unused))) ++ grub_fs_dir_hook_t hook __attribute__ ((unused)), ++ void *hook_data __attribute__ ((unused))) + { + if (!device->net) + return grub_error (GRUB_ERR_BUG, "invalid net device"); +diff --git a/grub-core/normal/completion.c b/grub-core/normal/completion.c +index 367a2b7..71c083c 100644 +--- a/grub-core/normal/completion.c ++++ b/grub-core/normal/completion.c +@@ -123,7 +123,8 @@ iterate_partition (grub_disk_t disk, const grub_partition_t p, + } + + static int +-iterate_dir (const char *filename, const struct grub_dirhook_info *info) ++iterate_dir (const char *filename, const struct grub_dirhook_info *info, ++ void *data __attribute__ ((unused))) + { + if (! info->dir) + { +@@ -295,7 +296,7 @@ complete_file (void) + dirfile[1] = '\0'; + + /* Iterate the directory. */ +- (fs->dir) (dev, dir, iterate_dir); ++ (fs->dir) (dev, dir, iterate_dir, NULL); + + grub_free (dir); + +diff --git a/include/grub/fs.h b/include/grub/fs.h +index 503d1a9..e451797 100644 +--- a/include/grub/fs.h ++++ b/include/grub/fs.h +@@ -41,6 +41,10 @@ struct grub_dirhook_info + grub_int32_t mtime; + }; + ++typedef int (*grub_fs_dir_hook_t) (const char *filename, ++ const struct grub_dirhook_info *info, ++ void *data); ++ + /* Filesystem descriptor. */ + struct grub_fs + { +@@ -53,8 +57,7 @@ struct grub_fs + + /* Call HOOK with each file under DIR. */ + grub_err_t (*dir) (grub_device_t device, const char *path, +- int (*hook) (const char *filename, +- const struct grub_dirhook_info *info)); ++ grub_fs_dir_hook_t hook, void *hook_data); + + /* Open a file named NAME and initialize FILE. */ + grub_err_t (*open) (struct grub_file *file, const char *name); +diff --git a/include/grub/fshelp.h b/include/grub/fshelp.h +index 4838fca..e437d4c 100644 +--- a/include/grub/fshelp.h ++++ b/include/grub/fshelp.h +@@ -38,24 +38,25 @@ enum grub_fshelp_filetype + GRUB_FSHELP_SYMLINK + }; + ++typedef int (*grub_fshelp_iterate_dir_hook_t) (const char *filename, ++ enum grub_fshelp_filetype filetype, ++ grub_fshelp_node_t node, ++ void *data); ++ + /* Lookup the node PATH. The node ROOTNODE describes the root of the + directory tree. The node found is returned in FOUNDNODE, which is + either a ROOTNODE or a new malloc'ed node. ITERATE_DIR is used to + iterate over all directory entries in the current node. + READ_SYMLINK is used to read the symlink if a node is a symlink. + EXPECTTYPE is the type node that is expected by the called, an +- error is generated if the node is not of the expected type. Make +- sure you use the NESTED_FUNC_ATTR macro for HOOK, this is required +- because GCC has a nasty bug when using regparm=3. */ ++ error is generated if the node is not of the expected type. */ + grub_err_t + EXPORT_FUNC(grub_fshelp_find_file) (const char *path, + grub_fshelp_node_t rootnode, + grub_fshelp_node_t *foundnode, + int (*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)), ++ grub_fshelp_iterate_dir_hook_t hook, ++ void *hook_data), + char *(*read_symlink) (grub_fshelp_node_t node), + enum grub_fshelp_filetype expect); + +diff --git a/util/grub-mount.c b/util/grub-mount.c +index e3eb1d7..d0ab6a2 100644 +--- a/util/grub-mount.c ++++ b/util/grub-mount.c +@@ -116,30 +116,38 @@ translate_error (void) + return ret; + } + ++/* Context for fuse_getattr. */ ++struct fuse_getattr_ctx ++{ ++ char *filename; ++ struct grub_dirhook_info file_info; ++ int file_exists; ++}; ++ ++/* A hook for iterating directories. */ ++static int ++fuse_getattr_find_file (const char *cur_filename, ++ const struct grub_dirhook_info *info, void *data) ++{ ++ struct fuse_getattr_ctx *ctx = data; ++ ++ if ((info->case_insensitive ? grub_strcasecmp (cur_filename, ctx->filename) ++ : grub_strcmp (cur_filename, ctx->filename)) == 0) ++ { ++ ctx->file_info = *info; ++ ctx->file_exists = 1; ++ return 1; ++ } ++ return 0; ++} ++ + static int + fuse_getattr (const char *path, struct stat *st) + { +- char *filename, *pathname, *path2; ++ struct fuse_getattr_ctx ctx; ++ char *pathname, *path2; + const char *pathname_t; +- struct grub_dirhook_info file_info; +- int file_exists = 0; + +- /* A hook for iterating directories. */ +- auto int find_file (const char *cur_filename, +- const struct grub_dirhook_info *info); +- int find_file (const char *cur_filename, +- const struct grub_dirhook_info *info) +- { +- if ((info->case_insensitive ? grub_strcasecmp (cur_filename, filename) +- : grub_strcmp (cur_filename, filename)) == 0) +- { +- file_info = *info; +- file_exists = 1; +- return 1; +- } +- return 0; +- } +- + if (path[0] == '/' && path[1] == 0) + { + st->st_dev = 0; +@@ -155,7 +163,7 @@ fuse_getattr (const char *path, struct stat *st) + return 0; + } + +- file_exists = 0; ++ ctx.file_exists = 0; + + pathname_t = grub_strchr (path, ')'); + if (! pathname_t) +@@ -169,35 +177,35 @@ fuse_getattr (const char *path, struct stat *st) + pathname[grub_strlen (pathname) - 1] = 0; + + /* Split into path and filename. */ +- filename = grub_strrchr (pathname, '/'); +- if (! filename) ++ ctx.filename = grub_strrchr (pathname, '/'); ++ if (! ctx.filename) + { + path2 = grub_strdup ("/"); +- filename = pathname; ++ ctx.filename = pathname; + } + else + { +- filename++; ++ ctx.filename++; + path2 = grub_strdup (pathname); +- path2[filename - pathname] = 0; ++ path2[ctx.filename - pathname] = 0; + } + + /* It's the whole device. */ +- (fs->dir) (dev, path2, find_file); ++ (fs->dir) (dev, path2, fuse_getattr_find_file, &ctx); + + grub_free (path2); +- if (!file_exists) ++ if (!ctx.file_exists) + { + grub_errno = GRUB_ERR_NONE; + return -ENOENT; + } + st->st_dev = 0; + st->st_ino = 0; +- st->st_mode = file_info.dir ? (0555 | S_IFDIR) : (0444 | S_IFREG); ++ st->st_mode = ctx.file_info.dir ? (0555 | S_IFDIR) : (0444 | S_IFREG); + st->st_uid = 0; + st->st_gid = 0; + st->st_rdev = 0; +- if (!file_info.dir) ++ if (!ctx.file_info.dir) + { + grub_file_t file; + file = grub_file_open (path); +@@ -210,8 +218,8 @@ fuse_getattr (const char *path, struct stat *st) + st->st_size = 0; + st->st_blksize = 512; + st->st_blocks = (st->st_size + 511) >> 9; +- st->st_atime = st->st_mtime = st->st_ctime = file_info.mtimeset +- ? file_info.mtime : 0; ++ st->st_atime = st->st_mtime = st->st_ctime = ctx.file_info.mtimeset ++ ? ctx.file_info.mtime : 0; + grub_errno = GRUB_ERR_NONE; + return 0; + } +@@ -271,39 +279,55 @@ fuse_release (const char *path, struct fuse_file_info *fi) + return 0; + } + ++/* Context for fuse_readdir. */ ++struct fuse_readdir_ctx ++{ ++ const char *path; ++ void *buf; ++ fuse_fill_dir_t fill; ++}; ++ ++/* Helper for fuse_readdir. */ ++static int ++fuse_readdir_call_fill (const char *filename, ++ const struct grub_dirhook_info *info, void *data) ++{ ++ struct fuse_readdir_ctx *ctx = data; ++ struct stat st; ++ ++ grub_memset (&st, 0, sizeof (st)); ++ st.st_mode = info->dir ? (0555 | S_IFDIR) : (0444 | S_IFREG); ++ if (!info->dir) ++ { ++ grub_file_t file; ++ char *tmp; ++ tmp = xasprintf ("%s/%s", ctx->path, filename); ++ file = grub_file_open (tmp); ++ free (tmp); ++ if (! file) ++ return translate_error (); ++ st.st_size = file->size; ++ grub_file_close (file); ++ } ++ st.st_blksize = 512; ++ st.st_blocks = (st.st_size + 511) >> 9; ++ st.st_atime = st.st_mtime = st.st_ctime ++ = info->mtimeset ? info->mtime : 0; ++ ctx->fill (ctx->buf, filename, &st, 0); ++ return 0; ++} ++ + static int + fuse_readdir (const char *path, void *buf, + fuse_fill_dir_t fill, off_t off, struct fuse_file_info *fi) + { ++ struct fuse_readdir_ctx ctx = { ++ .path = path, ++ .buf = buf, ++ .fill = fill ++ }; + char *pathname; + +- auto int call_fill (const char *filename, +- const struct grub_dirhook_info *info); +- int call_fill (const char *filename, const struct grub_dirhook_info *info) +- { +- struct stat st; +- grub_memset (&st, 0, sizeof (st)); +- st.st_mode = info->dir ? (0555 | S_IFDIR) : (0444 | S_IFREG); +- if (!info->dir) +- { +- grub_file_t file; +- char *tmp; +- tmp = xasprintf ("%s/%s", path, filename); +- file = grub_file_open (tmp); +- free (tmp); +- if (! file) +- return translate_error (); +- st.st_size = file->size; +- grub_file_close (file); +- } +- st.st_blksize = 512; +- st.st_blocks = (st.st_size + 511) >> 9; +- st.st_atime = st.st_mtime = st.st_ctime +- = info->mtimeset ? info->mtime : 0; +- fill (buf, filename, &st, 0); +- return 0; +- } +- + pathname = xstrdup (path); + + /* Remove trailing '/'. */ +@@ -311,7 +335,7 @@ fuse_readdir (const char *path, void *buf, + && pathname[grub_strlen (pathname) - 1] == '/') + pathname[grub_strlen (pathname) - 1] = 0; + +- (fs->dir) (dev, pathname, call_fill); ++ (fs->dir) (dev, pathname, fuse_readdir_call_fill, &ctx); + free (pathname); + grub_errno = GRUB_ERR_NONE; + return 0; +-- +1.8.1.4 + diff --git a/0126-grub-core-partmap-msdos.c-embed_signatures-Add-the-s.patch b/0126-grub-core-partmap-msdos.c-embed_signatures-Add-the-s.patch new file mode 100644 index 0000000..1685d22 --- /dev/null +++ b/0126-grub-core-partmap-msdos.c-embed_signatures-Add-the-s.patch @@ -0,0 +1,49 @@ +From a2102b2ce0666edcfef953fac2215221ba1a35bd Mon Sep 17 00:00:00 2001 +From: Colin Watson +Date: Mon, 21 Jan 2013 11:10:25 +0000 +Subject: [PATCH 126/364] * grub-core/partmap/msdos.c (embed_signatures): Add + the signature of an Acer registration utility with several sightings in the + wild. Reported by: Rickard Westman. Fixes Ubuntu bug #987022. + +--- + ChangeLog | 6 ++++++ + grub-core/partmap/msdos.c | 7 +++++++ + 2 files changed, 13 insertions(+) + +diff --git a/ChangeLog b/ChangeLog +index c975de1..ff29177 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,11 @@ + 2013-01-21 Colin Watson + ++ * grub-core/partmap/msdos.c (embed_signatures): Add the signature of ++ an Acer registration utility with several sightings in the wild. ++ Reported by: Rickard Westman. Fixes Ubuntu bug #987022. ++ ++2013-01-21 Colin Watson ++ + Remove nested functions from filesystem directory iterators. + + * include/grub/fs.h (grub_fs_dir_hook_t): New type. +diff --git a/grub-core/partmap/msdos.c b/grub-core/partmap/msdos.c +index 47527c3..b0e11c4 100644 +--- a/grub-core/partmap/msdos.c ++++ b/grub-core/partmap/msdos.c +@@ -94,6 +94,13 @@ struct embed_signature embed_signatures[] = + .signature = "ycgl", + .signature_len = 4, + .type = TYPE_RAID ++ }, ++ { ++ /* https://bugs.launchpad.net/bugs/987022 */ ++ .name = "Acer registration utility (?)", ++ .signature = "GREGRegDone.Tag\x00", ++ .signature_len = 16, ++ .type = TYPE_SOFTWARE + } + }; + #endif +-- +1.8.1.4 + diff --git a/0127-Improve-spkmomdem-reliability-by-adding-a-separator-.patch b/0127-Improve-spkmomdem-reliability-by-adding-a-separator-.patch new file mode 100644 index 0000000..62fcb08 --- /dev/null +++ b/0127-Improve-spkmomdem-reliability-by-adding-a-separator-.patch @@ -0,0 +1,76 @@ +From 966ef4a54d21d846304a7eafa125574a28f68caf Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Mon, 21 Jan 2013 14:55:30 +0100 +Subject: [PATCH 127/364] Improve spkmomdem reliability by adding a + separator between bytes. + +--- + ChangeLog | 4 ++++ + util/spkmodem-recv.c | 11 ++++++++--- + 2 files changed, 12 insertions(+), 3 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index ff29177..3c7552b 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,7 @@ ++2013-01-21 Vladimir Serbinenko ++ ++ Improve spkmomdem reliability by adding a separator between bytes. ++ + 2013-01-21 Colin Watson + + * grub-core/partmap/msdos.c (embed_signatures): Add the signature of +diff --git a/util/spkmodem-recv.c b/util/spkmodem-recv.c +index 9075f9a..9083c1a 100644 +--- a/util/spkmodem-recv.c ++++ b/util/spkmodem-recv.c +@@ -24,7 +24,7 @@ + /* Usage: parecord --channels=1 --rate=48000 --format=s16le | ./spkmodem-recv */ + + #define SAMPLES_PER_TRAME 240 +-#define FREQ_SEP_MIN 6 ++#define FREQ_SEP_MIN 5 + #define FREQ_SEP_MAX 15 + #define FREQ_DATA_MIN 15 + #define FREQ_DATA_THRESHOLD 25 +@@ -32,6 +32,7 @@ + #define THRESHOLD 500 + + #define DEBUG 0 ++#define FLUSH_TIMEOUT 1 + + static signed short trame[2 * SAMPLES_PER_TRAME]; + static signed short pulse[2 * SAMPLES_PER_TRAME]; +@@ -70,15 +71,18 @@ main () + int bitn = 7; + char c = 0; + int i; ++ int llp = 0; + while (!feof (stdin)) + { +- if (lp > 20000) ++ if (lp > 3 * SAMPLES_PER_TRAME) + { +- fflush (stdout); + bitn = 7; + c = 0; + lp = 0; ++ llp++; + } ++ if (llp == FLUSH_TIMEOUT) ++ fflush (stdout); + if (f2 > FREQ_SEP_MIN && f2 < FREQ_SEP_MAX + && f1 > FREQ_DATA_MIN && f1 < FREQ_DATA_MAX) + { +@@ -100,6 +104,7 @@ main () + c = 0; + } + lp = 0; ++ llp = 0; + for (i = 0; i < SAMPLES_PER_TRAME; i++) + read_sample (); + continue; +-- +1.8.1.4 + diff --git a/0128-grub-core-commands-lsmmap.c-Fix-unused-variable-on-e.patch b/0128-grub-core-commands-lsmmap.c-Fix-unused-variable-on-e.patch new file mode 100644 index 0000000..22db0cf --- /dev/null +++ b/0128-grub-core-commands-lsmmap.c-Fix-unused-variable-on-e.patch @@ -0,0 +1,48 @@ +From 891878c304ebb9da65969fd53a576305e8c880ab Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Mon, 21 Jan 2013 14:57:35 +0100 +Subject: [PATCH 128/364] * grub-core/commands/lsmmap.c: Fix unused + variable on emu. + +--- + ChangeLog | 4 ++++ + grub-core/commands/lsmmap.c | 2 +- + 2 files changed, 5 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index 3c7552b..18f350e 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,9 @@ + 2013-01-21 Vladimir Serbinenko + ++ * grub-core/commands/lsmmap.c: Fix unused variable on emu. ++ ++2013-01-21 Vladimir Serbinenko ++ + Improve spkmomdem reliability by adding a separator between bytes. + + 2013-01-21 Colin Watson +diff --git a/grub-core/commands/lsmmap.c b/grub-core/commands/lsmmap.c +index 8e7f2a5..c1a05d8 100644 +--- a/grub-core/commands/lsmmap.c ++++ b/grub-core/commands/lsmmap.c +@@ -25,6 +25,7 @@ + + GRUB_MOD_LICENSE ("GPLv3+"); + ++#ifndef GRUB_MACHINE_EMU + static const char *names[] = + { + [GRUB_MEMORY_AVAILABLE] = N_("available RAM"), +@@ -40,7 +41,6 @@ static const char *names[] = + [GRUB_MEMORY_HOLE] = N_("Address range not associated with RAM") + }; + +-#ifndef GRUB_MACHINE_EMU + /* Helper for grub_cmd_lsmmap. */ + static int + lsmmap_hook (grub_uint64_t addr, grub_uint64_t size, grub_memory_type_t type, +-- +1.8.1.4 + diff --git a/0129-grub-core-disk-arc-arcdisk.c-grub_arcdisk_iterate-Fi.patch b/0129-grub-core-disk-arc-arcdisk.c-grub_arcdisk_iterate-Fi.patch new file mode 100644 index 0000000..7bde89c --- /dev/null +++ b/0129-grub-core-disk-arc-arcdisk.c-grub_arcdisk_iterate-Fi.patch @@ -0,0 +1,40 @@ +From b9711c98bf23241a2cf73d01fe4ffc266171f27f Mon Sep 17 00:00:00 2001 +From: Colin Watson +Date: Mon, 21 Jan 2013 13:59:28 +0000 +Subject: [PATCH 129/364] * grub-core/disk/arc/arcdisk.c + (grub_arcdisk_iterate): Fix parameter declarations. + +--- + ChangeLog | 5 +++++ + grub-core/disk/arc/arcdisk.c | 2 +- + 2 files changed, 6 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index 18f350e..1c3958f 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,8 @@ ++2013-01-21 Colin Watson ++ ++ * grub-core/disk/arc/arcdisk.c (grub_arcdisk_iterate): Fix ++ parameter declarations. ++ + 2013-01-21 Vladimir Serbinenko + + * grub-core/commands/lsmmap.c: Fix unused variable on emu. +diff --git a/grub-core/disk/arc/arcdisk.c b/grub-core/disk/arc/arcdisk.c +index 37c0ac3..5d12128 100644 +--- a/grub-core/disk/arc/arcdisk.c ++++ b/grub-core/disk/arc/arcdisk.c +@@ -102,7 +102,7 @@ grub_arcdisk_iterate_iter (const char *name, + } + + static int +-grub_arcdisk_iterate (int (*hook_in) (const char *name), ++grub_arcdisk_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data, + grub_disk_pull_t pull) + { + struct grub_arcdisk_iterate_ctx ctx = { hook, hook_data }; +-- +1.8.1.4 + diff --git a/0130-Fix-powerpc-and-sparc64-build-failures-caused-by-un-.patch b/0130-Fix-powerpc-and-sparc64-build-failures-caused-by-un-.patch new file mode 100644 index 0000000..663c3cb --- /dev/null +++ b/0130-Fix-powerpc-and-sparc64-build-failures-caused-by-un-.patch @@ -0,0 +1,204 @@ +From 9a854b2d6f1c40dc029d74a46af934908bf1cd5f Mon Sep 17 00:00:00 2001 +From: Colin Watson +Date: Mon, 21 Jan 2013 14:41:06 +0000 +Subject: [PATCH 130/364] Fix powerpc and sparc64 build failures caused by + un-nesting memory map iterators. + +--- + ChangeLog | 5 ++++ + grub-core/loader/powerpc/ieee1275/linux.c | 41 +++++++++++++++++++++---------- + grub-core/loader/sparc64/ieee1275/linux.c | 38 +++++++++++++++++----------- + 3 files changed, 57 insertions(+), 27 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 1c3958f..04572d2 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,10 @@ + 2013-01-21 Colin Watson + ++ Fix powerpc and sparc64 build failures caused by un-nesting memory ++ map iterators. ++ ++2013-01-21 Colin Watson ++ + * grub-core/disk/arc/arcdisk.c (grub_arcdisk_iterate): Fix + parameter declarations. + +diff --git a/grub-core/loader/powerpc/ieee1275/linux.c b/grub-core/loader/powerpc/ieee1275/linux.c +index b150904..c977941 100644 +--- a/grub-core/loader/powerpc/ieee1275/linux.c ++++ b/grub-core/loader/powerpc/ieee1275/linux.c +@@ -51,37 +51,47 @@ static char *linux_args; + typedef void (*kernel_entry_t) (void *, unsigned long, int (void *), + unsigned long, unsigned long); + ++/* Context for grub_linux_claimmap_iterate. */ ++struct grub_linux_claimmap_iterate_ctx ++{ ++ grub_addr_t target; ++ grub_size_t size; ++ grub_size_t align; ++ grub_addr_t found_addr; ++}; ++ + /* Helper for grub_linux_claimmap_iterate. */ + static int + alloc_mem (grub_uint64_t addr, grub_uint64_t len, grub_memory_type_t type, + void *data) + { +- grub_addr_t *found_addr = data; ++ struct grub_linux_claimmap_iterate_ctx *ctx = data; + + grub_uint64_t end = addr + len; +- addr = ALIGN_UP (addr, align); +- target = ALIGN_UP (target, align); ++ addr = ALIGN_UP (addr, ctx->align); ++ ctx->target = ALIGN_UP (ctx->target, ctx->align); + + /* Target above the memory chunk. */ +- if (type != GRUB_MEMORY_AVAILABLE || target > end) ++ if (type != GRUB_MEMORY_AVAILABLE || ctx->target > end) + return 0; + + /* Target inside the memory chunk. */ +- if (target >= addr && target < end && size <= end - target) ++ if (ctx->target >= addr && ctx->target < end && ++ ctx->size <= end - ctx->target) + { +- if (grub_claimmap (target, size) == GRUB_ERR_NONE) ++ if (grub_claimmap (ctx->target, ctx->size) == GRUB_ERR_NONE) + { +- *found_addr = target; ++ ctx->found_addr = ctx->target; + return 1; + } + grub_print_error (); + } + /* Target below the memory chunk. */ +- if (target < addr && addr + size <= end) ++ if (ctx->target < addr && addr + ctx->size <= end) + { +- if (grub_claimmap (addr, size) == GRUB_ERR_NONE) ++ if (grub_claimmap (addr, ctx->size) == GRUB_ERR_NONE) + { +- *found_addr = addr; ++ ctx->found_addr = addr; + return 1; + } + grub_print_error (); +@@ -93,11 +103,16 @@ static grub_addr_t + grub_linux_claimmap_iterate (grub_addr_t target, grub_size_t size, + grub_size_t align) + { +- grub_addr_t found_addr = (grub_addr_t) -1; ++ struct grub_linux_claimmap_iterate_ctx ctx = { ++ .target = target, ++ .size = size, ++ .align = align, ++ .found_addr = (grub_addr_t) -1 ++ }; + +- grub_machine_mmap_iterate (alloc_mem, &found_addr); ++ grub_machine_mmap_iterate (alloc_mem, &ctx); + +- return found_addr; ++ return ctx.found_addr; + } + + static grub_err_t +diff --git a/grub-core/loader/sparc64/ieee1275/linux.c b/grub-core/loader/sparc64/ieee1275/linux.c +index a485284..c85fcfd 100644 +--- a/grub-core/loader/sparc64/ieee1275/linux.c ++++ b/grub-core/loader/sparc64/ieee1275/linux.c +@@ -180,32 +180,39 @@ grub_linux_unload (void) + + #define FOUR_MB (4 * 1024 * 1024) + ++/* Context for alloc_phys. */ ++struct alloc_phys_ctx ++{ ++ grub_addr_t size; ++ grub_addr_t ret; ++}; ++ + /* Helper for alloc_phys. */ + static int + alloc_phys_choose (grub_uint64_t addr, grub_uint64_t len, + grub_memory_type_t type, void *data) + { +- grub_addr_t *ret = data; ++ struct alloc_phys_ctx *ctx = data; + grub_addr_t end = addr + len; + + if (type != 1) + return 0; + + addr = ALIGN_UP (addr, FOUR_MB); +- if (addr + size >= end) ++ if (addr + ctx->size >= end) + return 0; + + if (addr >= grub_phys_start && addr < grub_phys_end) + { + addr = ALIGN_UP (grub_phys_end, FOUR_MB); +- if (addr + size >= end) ++ if (addr + ctx->size >= end) + return 0; + } +- if ((addr + size) >= grub_phys_start +- && (addr + size) < grub_phys_end) ++ if ((addr + ctx->size) >= grub_phys_start ++ && (addr + ctx->size) < grub_phys_end) + { + addr = ALIGN_UP (grub_phys_end, FOUR_MB); +- if (addr + size >= end) ++ if (addr + ctx->size >= end) + return 0; + } + +@@ -216,30 +223,33 @@ alloc_phys_choose (grub_uint64_t addr, grub_uint64_t len, + if (addr >= linux_paddr && addr < linux_end) + { + addr = linux_end; +- if (addr + size >= end) ++ if (addr + ctx->size >= end) + return 0; + } +- if ((addr + size) >= linux_paddr +- && (addr + size) < linux_end) ++ if ((addr + ctx->size) >= linux_paddr ++ && (addr + ctx->size) < linux_end) + { + addr = linux_end; +- if (addr + size >= end) ++ if (addr + ctx->size >= end) + return 0; + } + } + +- *ret = addr; ++ ctx->ret = addr; + return 1; + } + + static grub_addr_t + alloc_phys (grub_addr_t size) + { +- grub_addr_t ret = (grub_addr_t) -1; ++ struct alloc_phys_ctx ctx = { ++ .size = size, ++ .ret = (grub_addr_t) -1 ++ }; + +- grub_machine_mmap_iterate (alloc_phys_choose, &ret); ++ grub_machine_mmap_iterate (alloc_phys_choose, &ctx); + +- return ret; ++ return ctx.ret; + } + + static grub_err_t +-- +1.8.1.4 + diff --git a/0131-grub-core-commands-ls.c-grub_ls_print_devices-Add-mi.patch b/0131-grub-core-commands-ls.c-grub_ls_print_devices-Add-mi.patch new file mode 100644 index 0000000..84e6551 --- /dev/null +++ b/0131-grub-core-commands-ls.c-grub_ls_print_devices-Add-mi.patch @@ -0,0 +1,44 @@ +From 3181e3e2ffb3ee423962aeae12eb30ab51b09721 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Mon, 21 Jan 2013 17:46:24 +0100 +Subject: [PATCH 131/364] * grub-core/commands/ls.c + (grub_ls_print_devices): Add missing asterisk. + +--- + ChangeLog | 9 +++++++++ + grub-core/commands/ls.c | 2 +- + 2 files changed, 10 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index 04572d2..35267f5 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,12 @@ ++2013-01-21 Vladimir Serbinenko ++ ++ * grub-core/commands/ls.c (grub_ls_print_devices): Add missing ++ asterisk. ++ ++2013-01-21 Vladimir Serbinenko ++ ++ Make color variables global instead of it being per-terminal. ++ + 2013-01-21 Colin Watson + + Fix powerpc and sparc64 build failures caused by un-nesting memory +diff --git a/grub-core/commands/ls.c b/grub-core/commands/ls.c +index 0b86619..83930aa 100644 +--- a/grub-core/commands/ls.c ++++ b/grub-core/commands/ls.c +@@ -51,7 +51,7 @@ grub_ls_print_devices (const char *name, void *data) + { + int *longlist = data; + +- if (longlist) ++ if (*longlist) + grub_normal_print_device_info (name); + else + grub_printf ("(%s) ", name); +-- +1.8.1.4 + diff --git a/0132-Make-color-variables-global-instead-of-it-being-per-.patch b/0132-Make-color-variables-global-instead-of-it-being-per-.patch new file mode 100644 index 0000000..5cf7d45 --- /dev/null +++ b/0132-Make-color-variables-global-instead-of-it-being-per-.patch @@ -0,0 +1,547 @@ +From 6f069a71e2664086c5c4d662014d5c43e484da97 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Mon, 21 Jan 2013 17:53:41 +0100 +Subject: [PATCH 132/364] Make color variables global instead of it + being per-terminal. + +--- + ChangeLog | 6 +++--- + docs/grub.texi | 33 +++++++++++++++++++++++++++++++++ + grub-core/kern/term.c | 4 ++++ + grub-core/normal/color.c | 9 ++------- + grub-core/normal/menu_text.c | 24 +++++++++++++++--------- + grub-core/term/arc/console.c | 2 -- + grub-core/term/efi/console.c | 9 ++++----- + grub-core/term/emu/console.c | 4 ++-- + grub-core/term/gfxterm.c | 8 +++----- + grub-core/term/i386/pc/console.c | 9 ++++----- + grub-core/term/i386/pc/vga_text.c | 10 ++++------ + grub-core/term/ieee1275/console.c | 2 -- + grub-core/term/morse.c | 2 -- + grub-core/term/serial.c | 2 -- + grub-core/term/spkmodem.c | 2 -- + grub-core/term/terminfo.c | 8 ++++---- + include/grub/term.h | 26 ++++---------------------- + 17 files changed, 82 insertions(+), 78 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 35267f5..32b891a 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,11 +1,11 @@ + 2013-01-21 Vladimir Serbinenko + +- * grub-core/commands/ls.c (grub_ls_print_devices): Add missing +- asterisk. ++ Make color variables global instead of it being per-terminal. + + 2013-01-21 Vladimir Serbinenko + +- Make color variables global instead of it being per-terminal. ++ * grub-core/commands/ls.c (grub_ls_print_devices): Add missing ++ asterisk. + + 2013-01-21 Colin Watson + +diff --git a/docs/grub.texi b/docs/grub.texi +index b177111..9941b47 100644 +--- a/docs/grub.texi ++++ b/docs/grub.texi +@@ -2776,6 +2776,33 @@ those colors. Each color must be a name from the following list: + + The default is @samp{white/black}. + ++The color support support varies from terminal to terminal. ++ ++@samp{morse} has no color support at all. ++ ++@samp{mda_text} color support is limited to highlighting by ++black/white reversal. ++ ++@samp{console} on ARC and IEEE1275, @samp{serial_*} and ++@samp{spkmodem} are governed by terminfo and support ++only 8 colors if in modes @samp{vt100-color}, @samp{arc} ++(default for console on ARC), @samp{ieee1275} (default ++for console on IEEE1275). When in mode @samp{vt100} ++then the color support is limited to highlighting by black/white ++reversal. When in mode @samp{dumb} there is no color support. ++ ++@samp{console} on EMU supports 8 colors. ++ ++When console supports no colors this setting is ignored. ++When console supports 8 colors, then the colors from the ++second half of the previous list are mapped to the ++matching colors of first half. ++ ++@samp{console} on EFI and BIOS and @samp{vga_text} support all 16 colors. ++ ++@samp{gfxterm} supports all 16 colors and would be theoretically extendable ++to support whole rgb24 palette but currently there is no compelling reason ++to go beyond the current 16 colors. + + @node debug + @subsection debug +@@ -4355,6 +4382,8 @@ AT keyboard support allows keyboard layout remapping and support for keys not + available through firmware. It isn't needed for normal operation except + baremetal ports. + ++Speaker allows morse and spkmodem communication. ++ + USB support provides benefits similar to ATA (for USB disks) or AT (for USB + keyboards). In addition it allows USBserial. + +@@ -4376,6 +4405,7 @@ and mips-qemu_mips can use only memory up to first hole. + @item network @tab yes (*) @tab no @tab no @tab no + @item ATA/AHCI @tab yes @tab yes @tab yes @tab yes + @item AT keyboard @tab yes @tab yes @tab yes @tab yes ++@item Speaker @tab yes @tab yes @tab yes @tab yes + @item USB @tab yes @tab yes @tab yes @tab yes + @item chainloader @tab local @tab yes @tab yes @tab no + @item cpuid @tab partial @tab partial @tab partial @tab partial +@@ -4393,6 +4423,7 @@ and mips-qemu_mips can use only memory up to first hole. + @item network @tab yes @tab yes @tab yes @tab yes + @item ATA/AHCI @tab yes @tab yes @tab yes @tab no + @item AT keyboard @tab yes @tab yes @tab yes @tab no ++@item Speaker @tab yes @tab yes @tab yes @tab no + @item USB @tab yes @tab yes @tab yes @tab no + @item chainloader @tab local @tab local @tab no @tab local + @item cpuid @tab partial @tab partial @tab partial @tab no +@@ -4410,6 +4441,7 @@ and mips-qemu_mips can use only memory up to first hole. + @item network @tab no @tab yes (*) @tab yes @tab no + @item ATA/AHCI @tab yes @tab no @tab no @tab no + @item AT keyboard @tab yes @tab no @tab no @tab no ++@item Speaker @tab no @tab no @tab no @tab no + @item USB @tab yes @tab no @tab no @tab no + @item chainloader @tab yes @tab no @tab no @tab no + @item cpuid @tab no @tab no @tab no @tab no +@@ -4427,6 +4459,7 @@ and mips-qemu_mips can use only memory up to first hole. + @item network @tab no @tab yes + @item ATA/AHCI @tab yes @tab no + @item AT keyboard @tab yes @tab no ++@item Speaker @tab no @tab no + @item USB @tab N/A @tab yes + @item chainloader @tab yes @tab no + @item cpuid @tab no @tab no +diff --git a/grub-core/kern/term.c b/grub-core/kern/term.c +index 5014caf..34096bc 100644 +--- a/grub-core/kern/term.c ++++ b/grub-core/kern/term.c +@@ -28,6 +28,10 @@ struct grub_term_input *grub_term_inputs_disabled; + struct grub_term_output *grub_term_outputs; + struct grub_term_input *grub_term_inputs; + ++/* Current color state. */ ++grub_uint8_t grub_term_normal_color; ++grub_uint8_t grub_term_highlight_color; ++ + void (*grub_term_poll_usb) (void) = NULL; + void (*grub_net_poll_cards_idle) (void) = NULL; + +diff --git a/grub-core/normal/color.c b/grub-core/normal/color.c +index 06f1a87..c265423 100644 +--- a/grub-core/normal/color.c ++++ b/grub-core/normal/color.c +@@ -106,8 +106,6 @@ free_and_return: + return result; + } + +-static grub_uint8_t color_normal, color_highlight; +- + static void + set_colors (void) + { +@@ -115,9 +113,6 @@ set_colors (void) + + FOR_ACTIVE_TERM_OUTPUTS(term) + { +- /* Reloads terminal `normal' and `highlight' colors. */ +- grub_term_setcolor (term, color_normal, color_highlight); +- + /* Propagates `normal' color to terminal current color. */ + grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL); + } +@@ -128,7 +123,7 @@ char * + grub_env_write_color_normal (struct grub_env_var *var __attribute__ ((unused)), + const char *val) + { +- if (grub_parse_color_name_pair (&color_normal, val)) ++ if (grub_parse_color_name_pair (&grub_term_normal_color, val)) + return NULL; + + set_colors (); +@@ -141,7 +136,7 @@ char * + grub_env_write_color_highlight (struct grub_env_var *var __attribute__ ((unused)), + const char *val) + { +- if (grub_parse_color_name_pair (&color_highlight, val)) ++ if (grub_parse_color_name_pair (&grub_term_highlight_color, val)) + return NULL; + + set_colors (); +diff --git a/grub-core/normal/menu_text.c b/grub-core/normal/menu_text.c +index 1687c28..80a7cd9 100644 +--- a/grub-core/normal/menu_text.c ++++ b/grub-core/normal/menu_text.c +@@ -225,8 +225,10 @@ print_entry (int y, int highlight, grub_menu_entry_t entry, + return; + } + +- grub_term_getcolor (term, &old_color_normal, &old_color_highlight); +- grub_term_setcolor (term, grub_color_menu_normal, grub_color_menu_highlight); ++ old_color_normal = grub_term_normal_color; ++ old_color_highlight = grub_term_highlight_color; ++ grub_term_normal_color = grub_color_menu_normal; ++ grub_term_highlight_color = grub_color_menu_highlight; + grub_term_setcolorstate (term, highlight + ? GRUB_TERM_COLOR_HIGHLIGHT + : GRUB_TERM_COLOR_NORMAL); +@@ -293,7 +295,9 @@ print_entry (int y, int highlight, grub_menu_entry_t entry, + + grub_term_gotoxy (term, grub_term_cursor_x (term), y); + +- grub_term_setcolor (term, old_color_normal, old_color_highlight); ++ grub_term_normal_color = old_color_normal; ++ grub_term_highlight_color = old_color_highlight; ++ + grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL); + grub_free (unicode_title); + } +@@ -349,11 +353,11 @@ grub_menu_init_page (int nested, int edit, int *num_entries, + *num_entries = grub_term_height (term) - GRUB_TERM_TOP_BORDER_Y + - (print_message (nested, edit, term, 1) + 3) - 2; + +- grub_term_getcolor (term, &old_color_normal, &old_color_highlight); +- + /* By default, use the same colors for the menu. */ +- grub_color_menu_normal = old_color_normal; +- grub_color_menu_highlight = old_color_highlight; ++ old_color_normal = grub_term_normal_color; ++ old_color_highlight = grub_term_highlight_color; ++ grub_color_menu_normal = grub_term_normal_color; ++ grub_color_menu_highlight = grub_color_menu_highlight; + + /* Then give user a chance to replace them. */ + grub_parse_color_name_pair (&grub_color_menu_normal, +@@ -362,9 +366,11 @@ grub_menu_init_page (int nested, int edit, int *num_entries, + grub_env_get ("menu_color_highlight")); + + grub_normal_init_page (term); +- grub_term_setcolor (term, grub_color_menu_normal, grub_color_menu_highlight); ++ grub_term_normal_color = grub_color_menu_normal; ++ grub_term_highlight_color = grub_color_menu_highlight; + draw_border (term, *num_entries); +- grub_term_setcolor (term, old_color_normal, old_color_highlight); ++ grub_term_normal_color = old_color_normal; ++ grub_term_highlight_color = old_color_highlight; + print_message (nested, edit, term, 0); + } + +diff --git a/grub-core/term/arc/console.c b/grub-core/term/arc/console.c +index 45ff267..0ccaebe 100644 +--- a/grub-core/term/arc/console.c ++++ b/grub-core/term/arc/console.c +@@ -102,8 +102,6 @@ static struct grub_term_output grub_console_term_output = + .setcursor = grub_terminfo_setcursor, + .flags = GRUB_TERM_CODE_TYPE_ASCII, + .data = &grub_console_terminfo_output, +- .normal_color = GRUB_TERM_DEFAULT_NORMAL_COLOR, +- .highlight_color = GRUB_TERM_DEFAULT_HIGHLIGHT_COLOR, + }; + + void +diff --git a/grub-core/term/efi/console.c b/grub-core/term/efi/console.c +index e57a815..2d6c6f9 100644 +--- a/grub-core/term/efi/console.c ++++ b/grub-core/term/efi/console.c +@@ -192,7 +192,8 @@ grub_console_cls (struct grub_term_output *term __attribute__ ((unused))) + } + + static void +-grub_console_setcolorstate (struct grub_term_output *term, ++grub_console_setcolorstate (struct grub_term_output *term ++ __attribute__ ((unused)), + grub_term_color_state state) + { + grub_efi_simple_text_output_interface_t *o; +@@ -208,10 +209,10 @@ grub_console_setcolorstate (struct grub_term_output *term, + & 0x7f); + break; + case GRUB_TERM_COLOR_NORMAL: +- efi_call_2 (o->set_attributes, o, term->normal_color & 0x7f); ++ efi_call_2 (o->set_attributes, o, grub_term_normal_color & 0x7f); + break; + case GRUB_TERM_COLOR_HIGHLIGHT: +- efi_call_2 (o->set_attributes, o, term->highlight_color & 0x7f); ++ efi_call_2 (o->set_attributes, o, grub_term_highlight_color & 0x7f); + break; + default: + break; +@@ -265,8 +266,6 @@ static struct grub_term_output grub_console_term_output = + .cls = grub_console_cls, + .setcolorstate = grub_console_setcolorstate, + .setcursor = grub_console_setcursor, +- .normal_color = GRUB_TERM_DEFAULT_NORMAL_COLOR, +- .highlight_color = GRUB_TERM_DEFAULT_HIGHLIGHT_COLOR, + .flags = GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS + }; + +diff --git a/grub-core/term/emu/console.c b/grub-core/term/emu/console.c +index 55e3a6b..5bd5db1 100644 +--- a/grub-core/term/emu/console.c ++++ b/grub-core/term/emu/console.c +@@ -82,11 +82,11 @@ grub_ncurses_setcolorstate (struct grub_term_output *term, + grub_console_attr = A_NORMAL; + break; + case GRUB_TERM_COLOR_NORMAL: +- grub_console_cur_color = term->normal_color; ++ grub_console_cur_color = grub_term_normal_color; + grub_console_attr = A_NORMAL; + break; + case GRUB_TERM_COLOR_HIGHLIGHT: +- grub_console_cur_color = term->highlight_color; ++ grub_console_cur_color = grub_term_highlight_color; + grub_console_attr = A_STANDOUT; + break; + default: +diff --git a/grub-core/term/gfxterm.c b/grub-core/term/gfxterm.c +index 12567d1..a168e01 100644 +--- a/grub-core/term/gfxterm.c ++++ b/grub-core/term/gfxterm.c +@@ -1036,7 +1036,7 @@ grub_gfxterm_cls (struct grub_term_output *term) + } + + static void +-grub_virtual_screen_setcolorstate (struct grub_term_output *term, ++grub_virtual_screen_setcolorstate (struct grub_term_output *term __attribute__ ((unused)), + grub_term_color_state state) + { + switch (state) +@@ -1046,11 +1046,11 @@ grub_virtual_screen_setcolorstate (struct grub_term_output *term, + break; + + case GRUB_TERM_COLOR_NORMAL: +- virtual_screen.term_color = term->normal_color; ++ virtual_screen.term_color = grub_term_normal_color; + break; + + case GRUB_TERM_COLOR_HIGHLIGHT: +- virtual_screen.term_color = term->highlight_color; ++ virtual_screen.term_color = grub_term_highlight_color; + break; + + default: +@@ -1246,8 +1246,6 @@ static struct grub_term_output grub_video_term = + .refresh = grub_gfxterm_refresh, + .fullscreen = grub_gfxterm_fullscreen, + .flags = GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS, +- .normal_color = GRUB_TERM_DEFAULT_NORMAL_COLOR, +- .highlight_color = GRUB_TERM_DEFAULT_HIGHLIGHT_COLOR, + .next = 0 + }; + +diff --git a/grub-core/term/i386/pc/console.c b/grub-core/term/i386/pc/console.c +index a681435..2aa1943 100644 +--- a/grub-core/term/i386/pc/console.c ++++ b/grub-core/term/i386/pc/console.c +@@ -259,7 +259,8 @@ grub_console_getwh (struct grub_term_output *term __attribute__ ((unused))) + } + + static void +-grub_console_setcolorstate (struct grub_term_output *term, ++grub_console_setcolorstate (struct grub_term_output *term ++ __attribute__ ((unused)), + grub_term_color_state state) + { + switch (state) { +@@ -267,10 +268,10 @@ grub_console_setcolorstate (struct grub_term_output *term, + grub_console_cur_color = GRUB_TERM_DEFAULT_STANDARD_COLOR & 0x7f; + break; + case GRUB_TERM_COLOR_NORMAL: +- grub_console_cur_color = term->normal_color & 0x7f; ++ grub_console_cur_color = grub_term_normal_color & 0x7f; + break; + case GRUB_TERM_COLOR_HIGHLIGHT: +- grub_console_cur_color = term->highlight_color & 0x7f; ++ grub_console_cur_color = grub_term_highlight_color & 0x7f; + break; + default: + break; +@@ -295,8 +296,6 @@ static struct grub_term_output grub_console_term_output = + .setcolorstate = grub_console_setcolorstate, + .setcursor = grub_console_setcursor, + .flags = GRUB_TERM_CODE_TYPE_CP437, +- .normal_color = GRUB_TERM_DEFAULT_NORMAL_COLOR, +- .highlight_color = GRUB_TERM_DEFAULT_HIGHLIGHT_COLOR, + }; + + void +diff --git a/grub-core/term/i386/pc/vga_text.c b/grub-core/term/i386/pc/vga_text.c +index 74c155c..e976aec 100644 +--- a/grub-core/term/i386/pc/vga_text.c ++++ b/grub-core/term/i386/pc/vga_text.c +@@ -209,18 +209,18 @@ grub_vga_text_getwh (struct grub_term_output *term __attribute__ ((unused))) + #ifndef MODE_MDA + + static void +-grub_vga_text_setcolorstate (struct grub_term_output *term, +- grub_term_color_state state) ++grub_vga_text_setcolorstate (struct grub_term_output *term __attribute__ ((unused)), ++ grub_term_color_state state) + { + switch (state) { + case GRUB_TERM_COLOR_STANDARD: + cur_color = GRUB_TERM_DEFAULT_STANDARD_COLOR & 0x7f; + break; + case GRUB_TERM_COLOR_NORMAL: +- cur_color = term->normal_color & 0x7f; ++ cur_color = grub_term_normal_color & 0x7f; + break; + case GRUB_TERM_COLOR_HIGHLIGHT: +- cur_color = term->highlight_color & 0x7f; ++ cur_color = grub_term_highlight_color & 0x7f; + break; + default: + break; +@@ -265,8 +265,6 @@ static struct grub_term_output grub_vga_text_term = + .setcolorstate = grub_vga_text_setcolorstate, + .setcursor = grub_vga_text_setcursor, + .flags = GRUB_TERM_CODE_TYPE_CP437, +- .normal_color = GRUB_TERM_DEFAULT_NORMAL_COLOR, +- .highlight_color = GRUB_TERM_DEFAULT_HIGHLIGHT_COLOR, + }; + + #ifdef MODE_MDA +diff --git a/grub-core/term/ieee1275/console.c b/grub-core/term/ieee1275/console.c +index 93b81f4..3a80864 100644 +--- a/grub-core/term/ieee1275/console.c ++++ b/grub-core/term/ieee1275/console.c +@@ -229,8 +229,6 @@ static struct grub_term_output grub_console_term_output = + .setcursor = grub_console_setcursor, + .flags = GRUB_TERM_CODE_TYPE_ASCII, + .data = &grub_console_terminfo_output, +- .normal_color = GRUB_TERM_DEFAULT_NORMAL_COLOR, +- .highlight_color = GRUB_TERM_DEFAULT_HIGHLIGHT_COLOR, + }; + + void +diff --git a/grub-core/term/morse.c b/grub-core/term/morse.c +index 3d6c650..0fdc3b4 100644 +--- a/grub-core/term/morse.c ++++ b/grub-core/term/morse.c +@@ -115,8 +115,6 @@ static struct grub_term_output grub_audio_term_output = + .cls = (void *) dummy, + .setcolorstate = (void *) dummy, + .setcursor = (void *) dummy, +- .normal_color = GRUB_TERM_DEFAULT_NORMAL_COLOR, +- .highlight_color = GRUB_TERM_DEFAULT_HIGHLIGHT_COLOR, + .flags = GRUB_TERM_CODE_TYPE_ASCII | GRUB_TERM_DUMB + }; + +diff --git a/grub-core/term/serial.c b/grub-core/term/serial.c +index e1469e5..cfcfe84 100644 +--- a/grub-core/term/serial.c ++++ b/grub-core/term/serial.c +@@ -121,8 +121,6 @@ static struct grub_term_output grub_serial_term_output = + .setcursor = grub_terminfo_setcursor, + .flags = GRUB_TERM_CODE_TYPE_ASCII, + .data = &grub_serial_terminfo_output, +- .normal_color = GRUB_TERM_DEFAULT_NORMAL_COLOR, +- .highlight_color = GRUB_TERM_DEFAULT_HIGHLIGHT_COLOR, + }; + + +diff --git a/grub-core/term/spkmodem.c b/grub-core/term/spkmodem.c +index b6e7a04..5bff429 100644 +--- a/grub-core/term/spkmodem.c ++++ b/grub-core/term/spkmodem.c +@@ -127,8 +127,6 @@ static struct grub_term_output grub_spkmodem_term_output = + .setcursor = grub_terminfo_setcursor, + .flags = GRUB_TERM_CODE_TYPE_ASCII, + .data = &grub_spkmodem_terminfo_output, +- .normal_color = GRUB_TERM_DEFAULT_NORMAL_COLOR, +- .highlight_color = GRUB_TERM_DEFAULT_HIGHLIGHT_COLOR, + }; + + GRUB_MOD_INIT (spkmodem) +diff --git a/grub-core/term/terminfo.c b/grub-core/term/terminfo.c +index a0f8d18..eb0ef00 100644 +--- a/grub-core/term/terminfo.c ++++ b/grub-core/term/terminfo.c +@@ -303,12 +303,12 @@ grub_terminfo_setcolorstate (struct grub_term_output *term, + { + case GRUB_TERM_COLOR_STANDARD: + case GRUB_TERM_COLOR_NORMAL: +- fg = term->normal_color & 0x0f; +- bg = term->normal_color >> 4; ++ fg = grub_term_normal_color & 0x0f; ++ bg = grub_term_normal_color >> 4; + break; + case GRUB_TERM_COLOR_HIGHLIGHT: +- fg = term->highlight_color & 0x0f; +- bg = term->highlight_color >> 4; ++ fg = grub_term_highlight_color & 0x0f; ++ bg = grub_term_highlight_color >> 4; + break; + default: + return; +diff --git a/include/grub/term.h b/include/grub/term.h +index 39c3d5a..84f5766 100644 +--- a/include/grub/term.h ++++ b/include/grub/term.h +@@ -221,10 +221,6 @@ struct grub_term_output + /* The feature flags defined above. */ + grub_uint32_t flags; + +- /* Current color state. */ +- grub_uint8_t normal_color; +- grub_uint8_t highlight_color; +- + void *data; + }; + typedef struct grub_term_output *grub_term_output_t; +@@ -233,6 +229,10 @@ typedef struct grub_term_output *grub_term_output_t; + #define GRUB_TERM_DEFAULT_HIGHLIGHT_COLOR 0x70 + #define GRUB_TERM_DEFAULT_STANDARD_COLOR 0x07 + ++/* Current color state. */ ++extern grub_uint8_t EXPORT_VAR(grub_term_normal_color); ++extern grub_uint8_t EXPORT_VAR(grub_term_highlight_color); ++ + extern struct grub_term_output *EXPORT_VAR(grub_term_outputs_disabled); + extern struct grub_term_input *EXPORT_VAR(grub_term_inputs_disabled); + extern struct grub_term_output *EXPORT_VAR(grub_term_outputs); +@@ -391,16 +391,6 @@ grub_setcolorstate (grub_term_color_state state) + grub_term_setcolorstate (term, state); + } + +-/* Set the normal color and the highlight color. The format of each +- color is VGA's. */ +-static inline void +-grub_term_setcolor (struct grub_term_output *term, +- grub_uint8_t normal_color, grub_uint8_t highlight_color) +-{ +- term->normal_color = normal_color; +- term->highlight_color = highlight_color; +-} +- + /* Turn on/off the cursor. */ + static inline void + grub_term_setcursor (struct grub_term_output *term, int on) +@@ -460,14 +450,6 @@ grub_term_getcharwidth (struct grub_term_output *term, + return 1; + } + +-static inline void +-grub_term_getcolor (struct grub_term_output *term, +- grub_uint8_t *normal_color, grub_uint8_t *highlight_color) +-{ +- *normal_color = term->normal_color; +- *highlight_color = term->highlight_color; +-} +- + struct grub_term_autoload + { + struct grub_term_autoload *next; +-- +1.8.1.4 + diff --git a/0133-Improve-spkmomdem-reliability-by-adding-a-separator-.patch b/0133-Improve-spkmomdem-reliability-by-adding-a-separator-.patch new file mode 100644 index 0000000..7ce4f38 --- /dev/null +++ b/0133-Improve-spkmomdem-reliability-by-adding-a-separator-.patch @@ -0,0 +1,27 @@ +From bd8b317a9f59463b5fc668985df739075bf97ee6 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Mon, 21 Jan 2013 20:03:15 +0100 +Subject: [PATCH 133/364] Improve spkmomdem reliability by adding a + separator between bytes. + +--- + grub-core/normal/term.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/grub-core/normal/term.c b/grub-core/normal/term.c +index 43622be..dc03268 100644 +--- a/grub-core/normal/term.c ++++ b/grub-core/normal/term.c +@@ -672,7 +672,8 @@ print_ucs4_terminal (const grub_uint32_t * str, + + if (!wasn && contchar) + putcode_real (contchar, term, fixed_tab); +- fill_margin (term, contchar ? margin_right : 1); ++ if (contchar) ++ fill_margin (term, margin_right); + + grub_putcode ('\n', term); + if (state != &local_state && ++state->num_lines +-- +1.8.1.4 + diff --git a/0134-grub-core-normal-term.c-print_ucs4_terminal-Don-t-ou.patch b/0134-grub-core-normal-term.c-print_ucs4_terminal-Don-t-ou.patch new file mode 100644 index 0000000..394c3ae --- /dev/null +++ b/0134-grub-core-normal-term.c-print_ucs4_terminal-Don-t-ou.patch @@ -0,0 +1,28 @@ +From 139e527e2b46b84c8a57a03dcce9383612a2b589 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Mon, 21 Jan 2013 20:33:38 +0100 +Subject: [PATCH 134/364] * grub-core/normal/term.c + (print_ucs4_terminal): Don't output right margin when not needed. + +--- + ChangeLog | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/ChangeLog b/ChangeLog +index 32b891a..cf7a777 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,10 @@ + 2013-01-21 Vladimir Serbinenko + ++ * grub-core/normal/term.c (print_ucs4_terminal): Don't output right ++ margin when not needed. ++ ++2013-01-21 Vladimir Serbinenko ++ + Make color variables global instead of it being per-terminal. + + 2013-01-21 Vladimir Serbinenko +-- +1.8.1.4 + diff --git a/0135-Improve-spkmodem-reliability-by-adding-a-separator-b.patch b/0135-Improve-spkmodem-reliability-by-adding-a-separator-b.patch new file mode 100644 index 0000000..1ad4a08 --- /dev/null +++ b/0135-Improve-spkmodem-reliability-by-adding-a-separator-b.patch @@ -0,0 +1,50 @@ +From c769c9030bec4ec97310bf93e440020b83d8f100 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Mon, 21 Jan 2013 21:05:33 +0100 +Subject: [PATCH 135/364] Improve spkmodem reliability by adding a separator + between bytes. + +--- + grub-core/term/spkmodem.c | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +diff --git a/grub-core/term/spkmodem.c b/grub-core/term/spkmodem.c +index 5bff429..f20a27d 100644 +--- a/grub-core/term/spkmodem.c ++++ b/grub-core/term/spkmodem.c +@@ -70,12 +70,7 @@ put (struct grub_term_output *term __attribute__ ((unused)), const int c) + { + int i; + +- if (!inited) +- { +- make_tone (GRUB_SPEAKER_PIT_FREQUENCY / 50, 20); +- inited = 1; +- } +- ++ make_tone (GRUB_SPEAKER_PIT_FREQUENCY / 200, 4); + for (i = 7; i >= 0; i--) + { + if ((c >> i) & 1) +@@ -84,12 +79,17 @@ put (struct grub_term_output *term __attribute__ ((unused)), const int c) + make_tone (GRUB_SPEAKER_PIT_FREQUENCY / 4000, 40); + make_tone (GRUB_SPEAKER_PIT_FREQUENCY / 1000, 10); + } +- make_tone (GRUB_SPEAKER_PIT_FREQUENCY / 50, 0); ++ make_tone (GRUB_SPEAKER_PIT_FREQUENCY / 200, 0); + } + + static grub_err_t + grub_spkmodem_init_output (struct grub_term_output *term) + { ++ /* Some models shutdown sound when not in use and it takes for it ++ around 30 ms to come back on which loses 3 bits. So generate a base ++ 200 Hz continously. */ ++ ++ make_tone (GRUB_SPEAKER_PIT_FREQUENCY / 200, 0); + grub_terminfo_output_init (term); + + return 0; +-- +1.8.1.4 + diff --git a/0136-Remove-nested-functions-from-USB-iterators.patch b/0136-Remove-nested-functions-from-USB-iterators.patch new file mode 100644 index 0000000..ec41517 --- /dev/null +++ b/0136-Remove-nested-functions-from-USB-iterators.patch @@ -0,0 +1,391 @@ +From 68a73af56d5070833b4a4785647e539a0a3da063 Mon Sep 17 00:00:00 2001 +From: Colin Watson +Date: Mon, 21 Jan 2013 21:02:24 +0000 +Subject: [PATCH 136/364] Remove nested functions from USB iterators. + +* include/grub/usb.h (grub_usb_iterate_hook_t): New type. +(grub_usb_controller_iterate_hook_t): Likewise. +(grub_usb_iterate): Add hook_data argument. +(grub_usb_controller_iterate): Likewise. +(struct grub_usb_controller_dev.iterate): Likewise. + +Update all implementations and callers. +--- + ChangeLog | 12 +++++ + grub-core/bus/usb/ehci.c | 4 +- + grub-core/bus/usb/emu/usb.c | 4 +- + grub-core/bus/usb/ohci.c | 4 +- + grub-core/bus/usb/uhci.c | 4 +- + grub-core/bus/usb/usb.c | 120 ++++++++++++++++++++++++------------------- + grub-core/bus/usb/usbhub.c | 4 +- + grub-core/commands/usbtest.c | 4 +- + include/grub/usb.h | 11 ++-- + 9 files changed, 100 insertions(+), 67 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index cf7a777..08c2c9f 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,15 @@ ++2013-01-21 Colin Watson ++ ++ Remove nested functions from USB iterators. ++ ++ * include/grub/usb.h (grub_usb_iterate_hook_t): New type. ++ (grub_usb_controller_iterate_hook_t): Likewise. ++ (grub_usb_iterate): Add hook_data argument. ++ (grub_usb_controller_iterate): Likewise. ++ (struct grub_usb_controller_dev.iterate): Likewise. ++ ++ Update all implementations and callers. ++ + 2013-01-21 Vladimir Serbinenko + + * grub-core/normal/term.c (print_ucs4_terminal): Don't output right +diff --git a/grub-core/bus/usb/ehci.c b/grub-core/bus/usb/ehci.c +index b9872b6..9215866 100644 +--- a/grub-core/bus/usb/ehci.c ++++ b/grub-core/bus/usb/ehci.c +@@ -870,7 +870,7 @@ fail: + } + + static int +-grub_ehci_iterate (int (*hook) (grub_usb_controller_t dev)) ++grub_ehci_iterate (grub_usb_controller_iterate_hook_t hook, void *hook_data) + { + struct grub_ehci *e; + struct grub_usb_controller dev; +@@ -878,7 +878,7 @@ grub_ehci_iterate (int (*hook) (grub_usb_controller_t dev)) + for (e = ehci; e; e = e->next) + { + dev.data = e; +- if (hook (&dev)) ++ if (hook (&dev, hook_data)) + return 1; + } + +diff --git a/grub-core/bus/usb/emu/usb.c b/grub-core/bus/usb/emu/usb.c +index 38c5f01..3ad2fc3 100644 +--- a/grub-core/bus/usb/emu/usb.c ++++ b/grub-core/bus/usb/emu/usb.c +@@ -88,7 +88,7 @@ grub_usb_poll_devices (void) + + + int +-grub_usb_iterate (int (*hook) (grub_usb_device_t dev)) ++grub_usb_iterate (grub_usb_iterate_hook_t hook, void *hook_data) + { + int i; + +@@ -96,7 +96,7 @@ grub_usb_iterate (int (*hook) (grub_usb_device_t dev)) + { + if (grub_usb_devs[i]) + { +- if (hook (grub_usb_devs[i])) ++ if (hook (grub_usb_devs[i], hook_data)) + return 1; + } + } +diff --git a/grub-core/bus/usb/ohci.c b/grub-core/bus/usb/ohci.c +index b10a9a3..835bb15 100644 +--- a/grub-core/bus/usb/ohci.c ++++ b/grub-core/bus/usb/ohci.c +@@ -483,7 +483,7 @@ grub_ohci_inithw (void) + + + static int +-grub_ohci_iterate (int (*hook) (grub_usb_controller_t dev)) ++grub_ohci_iterate (grub_usb_controller_iterate_hook_t hook, void *hook_data) + { + struct grub_ohci *o; + struct grub_usb_controller dev; +@@ -491,7 +491,7 @@ grub_ohci_iterate (int (*hook) (grub_usb_controller_t dev)) + for (o = ohci; o; o = o->next) + { + dev.data = o; +- if (hook (&dev)) ++ if (hook (&dev, hook_data)) + return 1; + } + +diff --git a/grub-core/bus/usb/uhci.c b/grub-core/bus/usb/uhci.c +index e405b33..74de392 100644 +--- a/grub-core/bus/usb/uhci.c ++++ b/grub-core/bus/usb/uhci.c +@@ -672,7 +672,7 @@ grub_uhci_cancel_transfer (grub_usb_controller_t dev, + } + + static int +-grub_uhci_iterate (int (*hook) (grub_usb_controller_t dev)) ++grub_uhci_iterate (grub_usb_controller_iterate_hook_t hook, void *hook_data) + { + struct grub_uhci *u; + struct grub_usb_controller dev; +@@ -680,7 +680,7 @@ grub_uhci_iterate (int (*hook) (grub_usb_controller_t dev)) + for (u = uhci; u; u = u->next) + { + dev.data = u; +- if (hook (&dev)) ++ if (hook (&dev, hook_data)) + return 1; + } + +diff --git a/grub-core/bus/usb/usb.c b/grub-core/bus/usb/usb.c +index fb04e65..6fbf134 100644 +--- a/grub-core/bus/usb/usb.c ++++ b/grub-core/bus/usb/usb.c +@@ -29,27 +29,28 @@ GRUB_MOD_LICENSE ("GPLv3+"); + static grub_usb_controller_dev_t grub_usb_list; + static struct grub_usb_attach_desc *attach_hooks; + +-void +-grub_usb_controller_dev_register (grub_usb_controller_dev_t usb) ++/* Iterate over all controllers found by the driver. */ ++static int ++grub_usb_controller_dev_register_iter (grub_usb_controller_t dev, void *data) + { +- auto int iterate_hook (grub_usb_controller_t dev); ++ grub_usb_controller_dev_t usb = data; + +- /* Iterate over all controllers found by the driver. */ +- int iterate_hook (grub_usb_controller_t dev) +- { +- dev->dev = usb; ++ dev->dev = usb; + +- /* Enable the ports of the USB Root Hub. */ +- grub_usb_root_hub (dev); ++ /* Enable the ports of the USB Root Hub. */ ++ grub_usb_root_hub (dev); + +- return 0; +- } ++ return 0; ++} + ++void ++grub_usb_controller_dev_register (grub_usb_controller_dev_t usb) ++{ + usb->next = grub_usb_list; + grub_usb_list = usb; + + if (usb->iterate) +- usb->iterate (iterate_hook); ++ usb->iterate (grub_usb_controller_dev_register_iter, usb); + } + + void +@@ -66,27 +67,41 @@ grub_usb_controller_dev_unregister (grub_usb_controller_dev_t usb) + } + + #if 0 +-int +-grub_usb_controller_iterate (int (*hook) (grub_usb_controller_t dev)) ++/* Context for grub_usb_controller_iterate. */ ++struct grub_usb_controller_iterate_ctx + { ++ grub_usb_controller_iterate_hook_t hook; ++ void *hook_data; + grub_usb_controller_dev_t p; ++}; + +- auto int iterate_hook (grub_usb_controller_t dev); ++/* Helper for grub_usb_controller_iterate. */ ++static int ++grub_usb_controller_iterate_iter (grub_usb_controller_t dev, void *data) ++{ ++ struct grub_usb_controller_iterate_ctx *ctx = data; + +- int iterate_hook (grub_usb_controller_t dev) +- { +- dev->dev = p; +- if (hook (dev)) +- return 1; +- return 0; +- } ++ dev->dev = ctx->p; ++ if (ctx->hook (dev, ctx->hook_data)) ++ return 1; ++ return 0; ++} ++ ++int ++grub_usb_controller_iterate (grub_usb_controller_iterate_hook_t hook, ++ void *hook_data) ++{ ++ struct grub_usb_controller_iterate_ctx ctx = { ++ .hook = hook, ++ .hook_data = hook_data ++ }; + + /* Iterate over all controller drivers. */ +- for (p = grub_usb_list; p; p = p->next) ++ for (ctx.p = grub_usb_list; ctx.p; ctx.p = ctx.p->next) + { + /* Iterate over the busses of the controllers. XXX: Actually, a + hub driver should do this. */ +- if (p->iterate (iterate_hook)) ++ if (ctx.p->iterate (grub_usb_controller_iterate_iter, &ctx)) + return 1; + } + +@@ -295,46 +310,47 @@ void grub_usb_device_attach (grub_usb_device_t dev) + } + } + +-void +-grub_usb_register_attach_hook_class (struct grub_usb_attach_desc *desc) ++/* Helper for grub_usb_register_attach_hook_class. */ ++static int ++grub_usb_register_attach_hook_class_iter (grub_usb_device_t usbdev, void *data) + { +- auto int usb_iterate (grub_usb_device_t dev); +- +- int usb_iterate (grub_usb_device_t usbdev) +- { +- struct grub_usb_desc_device *descdev = &usbdev->descdev; +- int i; +- +- if (descdev->class != 0 || descdev->subclass || descdev->protocol != 0 +- || descdev->configcnt == 0) +- return 0; ++ struct grub_usb_attach_desc *desc = data; ++ struct grub_usb_desc_device *descdev = &usbdev->descdev; ++ int i; + +- /* XXX: Just check configuration 0 for now. */ +- for (i = 0; i < usbdev->config[0].descconf->numif; i++) +- { +- struct grub_usb_desc_if *interf; ++ if (descdev->class != 0 || descdev->subclass || descdev->protocol != 0 ++ || descdev->configcnt == 0) ++ return 0; + +- interf = usbdev->config[0].interf[i].descif; ++ /* XXX: Just check configuration 0 for now. */ ++ for (i = 0; i < usbdev->config[0].descconf->numif; i++) ++ { ++ struct grub_usb_desc_if *interf; + +- grub_dprintf ("usb", "iterate: interf=%d, class=%d, subclass=%d, protocol=%d\n", +- i, interf->class, interf->subclass, interf->protocol); ++ interf = usbdev->config[0].interf[i].descif; + +- if (usbdev->config[0].interf[i].attached) +- continue; ++ grub_dprintf ("usb", "iterate: interf=%d, class=%d, subclass=%d, protocol=%d\n", ++ i, interf->class, interf->subclass, interf->protocol); + +- if (interf->class != desc->class) +- continue; +- if (desc->hook (usbdev, 0, i)) +- usbdev->config[0].interf[i].attached = 1; +- } ++ if (usbdev->config[0].interf[i].attached) ++ continue; + +- return 0; ++ if (interf->class != desc->class) ++ continue; ++ if (desc->hook (usbdev, 0, i)) ++ usbdev->config[0].interf[i].attached = 1; + } + ++ return 0; ++} ++ ++void ++grub_usb_register_attach_hook_class (struct grub_usb_attach_desc *desc) ++{ + desc->next = attach_hooks; + attach_hooks = desc; + +- grub_usb_iterate (usb_iterate); ++ grub_usb_iterate (grub_usb_register_attach_hook_class_iter, desc); + } + + void +diff --git a/grub-core/bus/usb/usbhub.c b/grub-core/bus/usb/usbhub.c +index 5fc5eba..3927f51 100644 +--- a/grub-core/bus/usb/usbhub.c ++++ b/grub-core/bus/usb/usbhub.c +@@ -556,7 +556,7 @@ grub_usb_poll_devices (void) + } + + int +-grub_usb_iterate (int (*hook) (grub_usb_device_t dev)) ++grub_usb_iterate (grub_usb_iterate_hook_t hook, void *hook_data) + { + int i; + +@@ -564,7 +564,7 @@ grub_usb_iterate (int (*hook) (grub_usb_device_t dev)) + { + if (grub_usb_devs[i]) + { +- if (hook (grub_usb_devs[i])) ++ if (hook (grub_usb_devs[i], hook_data)) + return 1; + } + } +diff --git a/grub-core/commands/usbtest.c b/grub-core/commands/usbtest.c +index 7247590..af35b8c 100644 +--- a/grub-core/commands/usbtest.c ++++ b/grub-core/commands/usbtest.c +@@ -129,7 +129,7 @@ usb_print_str (const char *description, grub_usb_device_t dev, int idx) + } + + static int +-usb_iterate (grub_usb_device_t dev) ++usb_iterate (grub_usb_device_t dev, void *data __attribute__ ((unused))) + { + struct grub_usb_desc_device *descdev; + int i; +@@ -199,7 +199,7 @@ grub_cmd_usbtest (grub_command_t cmd __attribute__ ((unused)), + grub_usb_poll_devices (); + + grub_printf ("USB devices:\n\n"); +- grub_usb_iterate (usb_iterate); ++ grub_usb_iterate (usb_iterate, NULL); + + return 0; + } +diff --git a/include/grub/usb.h b/include/grub/usb.h +index 08d57b2..cefa8b6 100644 +--- a/include/grub/usb.h ++++ b/include/grub/usb.h +@@ -50,8 +50,12 @@ typedef enum + GRUB_USB_SPEED_HIGH + } grub_usb_speed_t; + ++typedef int (*grub_usb_iterate_hook_t) (grub_usb_device_t dev, void *data); ++typedef int (*grub_usb_controller_iterate_hook_t) (grub_usb_controller_t dev, ++ void *data); ++ + /* Call HOOK with each device, until HOOK returns non-zero. */ +-int grub_usb_iterate (int (*hook) (grub_usb_device_t dev)); ++int grub_usb_iterate (grub_usb_iterate_hook_t hook, void *hook_data); + + grub_usb_err_t grub_usb_device_initialize (grub_usb_device_t dev); + +@@ -72,7 +76,8 @@ void grub_usb_controller_dev_register (grub_usb_controller_dev_t usb); + + void grub_usb_controller_dev_unregister (grub_usb_controller_dev_t usb); + +-int grub_usb_controller_iterate (int (*hook) (grub_usb_controller_t dev)); ++int grub_usb_controller_iterate (grub_usb_controller_iterate_hook_t hook, ++ void *hook_data); + + + grub_usb_err_t grub_usb_control_msg (grub_usb_device_t dev, grub_uint8_t reqtype, +@@ -98,7 +103,7 @@ struct grub_usb_controller_dev + /* The device name. */ + const char *name; + +- int (*iterate) (int (*hook) (grub_usb_controller_t dev)); ++ int (*iterate) (grub_usb_controller_iterate_hook_t hook, void *hook_data); + + grub_usb_err_t (*setup_transfer) (grub_usb_controller_t dev, + grub_usb_transfer_t transfer); +-- +1.8.1.4 + diff --git a/0137-grub-core-font-font.c-blit_comb-do_blit-Make-static-.patch b/0137-grub-core-font-font.c-blit_comb-do_blit-Make-static-.patch new file mode 100644 index 0000000..c478d9b --- /dev/null +++ b/0137-grub-core-font-font.c-blit_comb-do_blit-Make-static-.patch @@ -0,0 +1,275 @@ +From 5d4c7b334f440e337abf83b29408e06474497655 Mon Sep 17 00:00:00 2001 +From: Colin Watson +Date: Mon, 21 Jan 2013 21:03:26 +0000 +Subject: [PATCH 137/364] * grub-core/font/font.c (blit_comb: do_blit): Make + static instead of nested. (blit_comb: add_device_width): Likewise. + +--- + ChangeLog | 6 +++ + grub-core/font/font.c | 133 ++++++++++++++++++++++++++++---------------------- + 2 files changed, 80 insertions(+), 59 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 08c2c9f..a2edbc5 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,11 @@ + 2013-01-21 Colin Watson + ++ * grub-core/font/font.c (blit_comb: do_blit): Make static instead of ++ nested. ++ (blit_comb: add_device_width): Likewise. ++ ++2013-01-21 Colin Watson ++ + Remove nested functions from USB iterators. + + * include/grub/usb.h (grub_usb_iterate_hook_t): New type. +diff --git a/grub-core/font/font.c b/grub-core/font/font.c +index fca8c8d..6b54a84 100644 +--- a/grub-core/font/font.c ++++ b/grub-core/font/font.c +@@ -1143,6 +1143,49 @@ grub_font_blit_glyph_mirror (struct grub_font_glyph *target, + } + } + ++/* Context for blit_comb. */ ++struct blit_comb_ctx ++{ ++ struct grub_font_glyph *glyph; ++ int *device_width; ++ struct grub_video_signed_rect bounds; ++}; ++ ++/* Helper for blit_comb. */ ++static void ++do_blit (struct grub_font_glyph *src, signed dx, signed dy, ++ struct blit_comb_ctx *ctx) ++{ ++ if (ctx->glyph) ++ grub_font_blit_glyph (ctx->glyph, src, dx - ctx->glyph->offset_x, ++ (ctx->glyph->height + ctx->glyph->offset_y) + dy); ++ if (dx < ctx->bounds.x) ++ { ++ ctx->bounds.width += ctx->bounds.x - dx; ++ ctx->bounds.x = dx; ++ } ++ if (ctx->bounds.y > -src->height - dy) ++ { ++ ctx->bounds.height += ctx->bounds.y - (-src->height - dy); ++ ctx->bounds.y = (-src->height - dy); ++ } ++ if (dx + src->width - ctx->bounds.x >= (signed) ctx->bounds.width) ++ ctx->bounds.width = dx + src->width - ctx->bounds.x + 1; ++ if ((signed) ctx->bounds.height < src->height + (-src->height - dy) ++ - ctx->bounds.y) ++ ctx->bounds.height = src->height + (-src->height - dy) - ctx->bounds.y; ++} ++ ++/* Helper for blit_comb. */ ++static inline void ++add_device_width (int val, struct blit_comb_ctx *ctx) ++{ ++ if (ctx->glyph) ++ ctx->glyph->device_width += val; ++ if (ctx->device_width) ++ *ctx->device_width += val; ++} ++ + static void + blit_comb (const struct grub_unicode_glyph *glyph_id, + struct grub_font_glyph *glyph, +@@ -1150,63 +1193,34 @@ blit_comb (const struct grub_unicode_glyph *glyph_id, + struct grub_font_glyph *main_glyph, + struct grub_font_glyph **combining_glyphs, int *device_width) + { +- struct grub_video_signed_rect bounds; ++ struct blit_comb_ctx ctx = { ++ .glyph = glyph, ++ .device_width = device_width ++ }; + unsigned i; + signed above_rightx, above_righty; + signed above_leftx, above_lefty; + signed below_rightx, below_righty; + signed min_devwidth = 0; +- auto void NESTED_FUNC_ATTR do_blit (struct grub_font_glyph *src, +- signed dx, signed dy); +- void NESTED_FUNC_ATTR do_blit (struct grub_font_glyph *src, +- signed dx, signed dy) +- { +- if (glyph) +- grub_font_blit_glyph (glyph, src, dx - glyph->offset_x, +- (glyph->height + glyph->offset_y) + dy); +- if (dx < bounds.x) +- { +- bounds.width += bounds.x - dx; +- bounds.x = dx; +- } +- if (bounds.y > -src->height - dy) +- { +- bounds.height += bounds.y - (-src->height - dy); +- bounds.y = (-src->height - dy); +- } +- if (dx + src->width - bounds.x >= (signed) bounds.width) +- bounds.width = dx + src->width - bounds.x + 1; +- if ((signed) bounds.height < src->height + (-src->height - dy) - bounds.y) +- bounds.height = src->height + (-src->height - dy) - bounds.y; +- } +- +- auto void add_device_width (int val); +- void add_device_width (int val) +- { +- if (glyph) +- glyph->device_width += val; +- if (device_width) +- *device_width += val; +- } + + if (glyph) + glyph->device_width = main_glyph->device_width; + if (device_width) + *device_width = main_glyph->device_width; + +- bounds.x = main_glyph->offset_x; +- bounds.y = main_glyph->offset_y; +- bounds.width = main_glyph->width; +- bounds.height = main_glyph->height; ++ ctx.bounds.x = main_glyph->offset_x; ++ ctx.bounds.y = main_glyph->offset_y; ++ ctx.bounds.width = main_glyph->width; ++ ctx.bounds.height = main_glyph->height; + + above_rightx = main_glyph->offset_x + main_glyph->width; +- above_righty = bounds.y + bounds.height; ++ above_righty = ctx.bounds.y + ctx.bounds.height; + + above_leftx = main_glyph->offset_x; +- above_lefty = bounds.y + bounds.height; ++ above_lefty = ctx.bounds.y + ctx.bounds.height; + +- below_rightx = bounds.x + bounds.width; +- below_righty = bounds.y; ++ below_rightx = ctx.bounds.x + ctx.bounds.width; ++ below_righty = ctx.bounds.y; + + for (i = 0; i < glyph_id->ncomb; i++) + { +@@ -1216,7 +1230,7 @@ blit_comb (const struct grub_unicode_glyph *glyph_id, + + if (!combining_glyphs[i]) + continue; +- targetx = (bounds.width - combining_glyphs[i]->width) / 2 + bounds.x; ++ targetx = (ctx.bounds.width - combining_glyphs[i]->width) / 2 + ctx.bounds.x; + /* CGJ is to avoid diacritics reordering. */ + if (glyph_id->combining[i].code + == GRUB_UNICODE_COMBINING_GRAPHEME_JOINER) +@@ -1226,31 +1240,31 @@ blit_comb (const struct grub_unicode_glyph *glyph_id, + case GRUB_UNICODE_COMB_OVERLAY: + do_blit (combining_glyphs[i], + targetx, +- (bounds.height - combining_glyphs[i]->height) / 2 +- - (bounds.height + bounds.y)); ++ (ctx.bounds.height - combining_glyphs[i]->height) / 2 ++ - (ctx.bounds.height + ctx.bounds.y), &ctx); + if (min_devwidth < combining_glyphs[i]->width) + min_devwidth = combining_glyphs[i]->width; + break; + + case GRUB_UNICODE_COMB_ATTACHED_ABOVE_RIGHT: +- do_blit (combining_glyphs[i], above_rightx, -above_righty); ++ do_blit (combining_glyphs[i], above_rightx, -above_righty, &ctx); + above_rightx += combining_glyphs[i]->width; + break; + + case GRUB_UNICODE_COMB_ABOVE_RIGHT: + do_blit (combining_glyphs[i], above_rightx, +- -(above_righty + combining_glyphs[i]->height)); ++ -(above_righty + combining_glyphs[i]->height), &ctx); + above_rightx += combining_glyphs[i]->width; + break; + + case GRUB_UNICODE_COMB_ABOVE_LEFT: + above_leftx -= combining_glyphs[i]->width; + do_blit (combining_glyphs[i], above_leftx, +- -(above_lefty + combining_glyphs[i]->height)); ++ -(above_lefty + combining_glyphs[i]->height), &ctx); + break; + + case GRUB_UNICODE_COMB_BELOW_RIGHT: +- do_blit (combining_glyphs[i], below_rightx, below_righty); ++ do_blit (combining_glyphs[i], below_rightx, below_righty, &ctx); + below_rightx += combining_glyphs[i]->width; + break; + +@@ -1276,7 +1290,7 @@ blit_comb (const struct grub_unicode_glyph *glyph_id, + space = 1 + (grub_font_get_xheight (main_glyph->font)) / 8; + do_blit (combining_glyphs[i], targetx, + -(main_glyph->height + main_glyph->offset_y + space +- + combining_glyphs[i]->height)); ++ + combining_glyphs[i]->height), &ctx); + if (min_devwidth < combining_glyphs[i]->width) + min_devwidth = combining_glyphs[i]->width; + break; +@@ -1300,16 +1314,16 @@ blit_comb (const struct grub_unicode_glyph *glyph_id, + + case GRUB_UNICODE_STACK_ATTACHED_ABOVE: + do_blit (combining_glyphs[i], targetx, +- -(bounds.height + bounds.y + space +- + combining_glyphs[i]->height)); ++ -(ctx.bounds.height + ctx.bounds.y + space ++ + combining_glyphs[i]->height), &ctx); + if (min_devwidth < combining_glyphs[i]->width) + min_devwidth = combining_glyphs[i]->width; + break; + + case GRUB_UNICODE_COMB_HEBREW_DAGESH: + do_blit (combining_glyphs[i], targetx, +- -(bounds.height / 2 + bounds.y +- + combining_glyphs[i]->height / 2)); ++ -(ctx.bounds.height / 2 + ctx.bounds.y ++ + combining_glyphs[i]->height / 2), &ctx); + if (min_devwidth < combining_glyphs[i]->width) + min_devwidth = combining_glyphs[i]->width; + break; +@@ -1340,7 +1354,8 @@ blit_comb (const struct grub_unicode_glyph *glyph_id, + space = 1 + (grub_font_get_xheight (main_glyph->font)) / 8; + + case GRUB_UNICODE_STACK_ATTACHED_BELOW: +- do_blit (combining_glyphs[i], targetx, -(bounds.y - space)); ++ do_blit (combining_glyphs[i], targetx, -(ctx.bounds.y - space), ++ &ctx); + if (min_devwidth < combining_glyphs[i]->width) + min_devwidth = combining_glyphs[i]->width; + break; +@@ -1373,22 +1388,22 @@ blit_comb (const struct grub_unicode_glyph *glyph_id, + main_glyph->device_width + + combining_glyphs[i]->offset_x, + -(combining_glyphs[i]->height +- + combining_glyphs[i]->offset_y)); +- add_device_width (combining_glyphs[i]->device_width); ++ + combining_glyphs[i]->offset_y), &ctx); ++ add_device_width (combining_glyphs[i]->device_width, &ctx); + } + } + } + add_device_width ((above_rightx > + below_rightx ? above_rightx : below_rightx) - +- (main_glyph->offset_x + main_glyph->width)); +- add_device_width (above_leftx - main_glyph->offset_x); ++ (main_glyph->offset_x + main_glyph->width), &ctx); ++ add_device_width (above_leftx - main_glyph->offset_x, &ctx); + if (glyph && glyph->device_width < min_devwidth) + glyph->device_width = min_devwidth; + if (device_width && *device_width < min_devwidth) + *device_width = min_devwidth; + + if (bounds_out) +- *bounds_out = bounds; ++ *bounds_out = ctx.bounds; + } + + static struct grub_font_glyph * +-- +1.8.1.4 + diff --git a/0138-include-grub-kernel.h-FOR_MODULES-Adjust-to-preserve.patch b/0138-include-grub-kernel.h-FOR_MODULES-Adjust-to-preserve.patch new file mode 100644 index 0000000..3d4d888 --- /dev/null +++ b/0138-include-grub-kernel.h-FOR_MODULES-Adjust-to-preserve.patch @@ -0,0 +1,40 @@ +From 5657a74faa6aa56753f42e65b0806afb3cb7c842 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Mon, 21 Jan 2013 22:44:20 +0100 +Subject: [PATCH 138/364] * include/grub/kernel.h (FOR_MODULES): Adjust + to preserve alignment invariants. + +--- + ChangeLog | 5 +++++ + include/grub/kernel.h | 2 +- + 2 files changed, 6 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index a2edbc5..c3405df 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,8 @@ ++2013-01-21 Vladimir Serbinenko ++ ++ * include/grub/kernel.h (FOR_MODULES): Adjust to preserve alignment ++ invariants. ++ + 2013-01-21 Colin Watson + + * grub-core/font/font.c (blit_comb: do_blit): Make static instead of +diff --git a/include/grub/kernel.h b/include/grub/kernel.h +index 033479e..23e4f02 100644 +--- a/include/grub/kernel.h ++++ b/include/grub/kernel.h +@@ -78,7 +78,7 @@ extern grub_addr_t EXPORT_VAR (grub_modbase); + var && (grub_addr_t) var \ + < (grub_modbase + (((struct grub_module_info *) grub_modbase)->size)); \ + var = (struct grub_module_header *) \ +- ((void **) var + (((struct grub_module_header *) var)->size + sizeof (void *) - 1) / sizeof (void *))) ++ (((grub_uint32_t *) var) + ((((struct grub_module_header *) var)->size + sizeof (grub_addr_t) - 1) / sizeof (grub_addr_t)) * (sizeof (grub_addr_t) / sizeof (grub_uint32_t)))) + + grub_addr_t grub_modules_get_end (void); + +-- +1.8.1.4 + diff --git a/0139-grub-core-lib-libgcrypt_wrap-cipher_wrap.h-Include-s.patch b/0139-grub-core-lib-libgcrypt_wrap-cipher_wrap.h-Include-s.patch new file mode 100644 index 0000000..352a688 --- /dev/null +++ b/0139-grub-core-lib-libgcrypt_wrap-cipher_wrap.h-Include-s.patch @@ -0,0 +1,46 @@ +From 457800079c4b331161d9ca011f2d8971758f03c9 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Tue, 22 Jan 2013 07:46:29 +0100 +Subject: [PATCH 139/364] * grub-core/lib/libgcrypt_wrap/cipher_wrap.h: + Include sys/types.h rather than defining WORDS_BIGENDIAN manually. + +--- + ChangeLog | 5 +++++ + grub-core/lib/libgcrypt_wrap/cipher_wrap.h | 6 +----- + 2 files changed, 6 insertions(+), 5 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index c3405df..f3a9fa0 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,10 @@ + 2013-01-21 Vladimir Serbinenko + ++ * grub-core/lib/libgcrypt_wrap/cipher_wrap.h: Include sys/types.h rather ++ than defining WORDS_BIGENDIAN manually. ++ ++2013-01-21 Vladimir Serbinenko ++ + * include/grub/kernel.h (FOR_MODULES): Adjust to preserve alignment + invariants. + +diff --git a/grub-core/lib/libgcrypt_wrap/cipher_wrap.h b/grub-core/lib/libgcrypt_wrap/cipher_wrap.h +index 118b2f1..f537d50 100644 +--- a/grub-core/lib/libgcrypt_wrap/cipher_wrap.h ++++ b/grub-core/lib/libgcrypt_wrap/cipher_wrap.h +@@ -25,11 +25,7 @@ + #include + #include + +-#undef WORDS_BIGENDIAN +- +-#ifdef GRUB_CPU_WORDS_BIGENDIAN +-#define WORDS_BIGENDIAN 1 +-#endif ++#include + + #undef __GNU_LIBRARY__ + #define __GNU_LIBRARY__ 1 +-- +1.8.1.4 + diff --git a/0140-util-grub-reboot.in-usage-Document-the-need-for.patch b/0140-util-grub-reboot.in-usage-Document-the-need-for.patch new file mode 100644 index 0000000..993d154 --- /dev/null +++ b/0140-util-grub-reboot.in-usage-Document-the-need-for.patch @@ -0,0 +1,71 @@ +From 46759fbe61fcca60bc4e619a9cde0977f48c0723 Mon Sep 17 00:00:00 2001 +From: Colin Watson +Date: Tue, 22 Jan 2013 14:28:32 +0000 +Subject: [PATCH 140/364] * util/grub-reboot.in (usage): Document the need for + GRUB_DEFAULT=saved. * util/grub-set-default.in (usage): Likewise. Reported + by: Brian Candler. Fixes Ubuntu bug #1102925. + +--- + ChangeLog | 7 +++++++ + util/grub-reboot.in | 2 ++ + util/grub-set-default.in | 2 ++ + 3 files changed, 11 insertions(+) + +diff --git a/ChangeLog b/ChangeLog +index f3a9fa0..8c4d087 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,10 @@ ++2013-01-22 Colin Watson ++ ++ * util/grub-reboot.in (usage): Document the need for ++ GRUB_DEFAULT=saved. ++ * util/grub-set-default.in (usage): Likewise. ++ Reported by: Brian Candler. Fixes Ubuntu bug #1102925. ++ + 2013-01-21 Vladimir Serbinenko + + * grub-core/lib/libgcrypt_wrap/cipher_wrap.h: Include sys/types.h rather +diff --git a/util/grub-reboot.in b/util/grub-reboot.in +index 7516a03..1a91d36 100644 +--- a/util/grub-reboot.in ++++ b/util/grub-reboot.in +@@ -20,6 +20,7 @@ + prefix=@prefix@ + exec_prefix=@exec_prefix@ + bindir=@bindir@ ++sysconfdir="@sysconfdir@" + PACKAGE_NAME=@PACKAGE_NAME@ + PACKAGE_VERSION=@PACKAGE_VERSION@ + datarootdir="@datarootdir@" +@@ -45,6 +46,7 @@ export TEXTDOMAINDIR="@localedir@" + usage () { + gettext_printf "Usage: %s [OPTION] MENU_ENTRY\n" "$self" + gettext "Set the default boot menu entry for GRUB, for the next boot only."; echo ++ gettext_printf "This requires setting GRUB_DEFAULT=saved in %s/default/grub.\n" "$sysconfdir" + echo + print_option_help "-h, --help" "$(gettext "print this message and exit")" + print_option_help "-v, --version" "$(gettext "print the version information and exit")" +diff --git a/util/grub-set-default.in b/util/grub-set-default.in +index 443e56f..ea18da1 100644 +--- a/util/grub-set-default.in ++++ b/util/grub-set-default.in +@@ -20,6 +20,7 @@ + prefix=@prefix@ + exec_prefix=@exec_prefix@ + bindir=@bindir@ ++sysconfdir="@sysconfdir@" + PACKAGE_NAME=@PACKAGE_NAME@ + PACKAGE_VERSION=@PACKAGE_VERSION@ + datarootdir="@datarootdir@" +@@ -45,6 +46,7 @@ export TEXTDOMAINDIR="@localedir@" + usage () { + gettext_printf "Usage: %s [OPTION] MENU_ENTRY\n" "$self" + gettext "Set the default boot menu entry for GRUB."; echo ++ gettext_printf "This requires setting GRUB_DEFAULT=saved in %s/default/grub.\n" "$sysconfdir" + echo + print_option_help "-h, --help" "$(gettext "print this message and exit")" + print_option_help "-v, --version" "$(gettext "print the version information and exit")" +-- +1.8.1.4 + diff --git a/0141-Improve-FreeDOS-direct-loading-support-compatibility.patch b/0141-Improve-FreeDOS-direct-loading-support-compatibility.patch new file mode 100644 index 0000000..3b441ad --- /dev/null +++ b/0141-Improve-FreeDOS-direct-loading-support-compatibility.patch @@ -0,0 +1,211 @@ +From cf10c476b8dbe718f05da15a705ba106eae9f621 Mon Sep 17 00:00:00 2001 +From: "C. Masloch" +Date: Sun, 27 Jan 2013 16:07:25 +0100 +Subject: [PATCH 141/364] Improve FreeDOS direct loading support + compatibility. + + * include/grub/i386/relocator.h (grub_relocator16_state): + New member ebp. + * grub-core/lib/i386/relocator.c (grub_relocator16_ebp): New extern + variable. + (grub_relocator16_boot): Handle %ebp. + * grub-core/lib/i386/relocator16.S: Likewise. + * grub-core/loader/i386/pc/freedos.c: + Load BPB to pass kernel which partition to load from. + Check that kernel file is not too large. + Set register dl to BIOS unit number as well. +--- + ChangeLog | 15 ++++++++++ + grub-core/lib/i386/relocator.c | 2 ++ + grub-core/lib/i386/relocator16.S | 5 ++++ + grub-core/loader/i386/pc/freedos.c | 61 ++++++++++++++++++++++++++++++++++---- + include/grub/i386/relocator.h | 1 + + 5 files changed, 79 insertions(+), 5 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 8c4d087..f5cb7dc 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,18 @@ ++2013-01-27 C. Masloch ++ ++ Improve FreeDOS direct loading support compatibility. ++ ++ * include/grub/i386/relocator.h (grub_relocator16_state): ++ New member ebp. ++ * grub-core/lib/i386/relocator.c (grub_relocator16_ebp): New extern ++ variable. ++ (grub_relocator16_boot): Handle %ebp. ++ * grub-core/lib/i386/relocator16.S: Likewise. ++ * grub-core/loader/i386/pc/freedos.c: ++ Load BPB to pass kernel which partition to load from. ++ Check that kernel file is not too large. ++ Set register dl to BIOS unit number as well. ++ + 2013-01-22 Colin Watson + + * util/grub-reboot.in (usage): Document the need for +diff --git a/grub-core/lib/i386/relocator.c b/grub-core/lib/i386/relocator.c +index df25b30..0170eed 100644 +--- a/grub-core/lib/i386/relocator.c ++++ b/grub-core/lib/i386/relocator.c +@@ -54,6 +54,7 @@ extern grub_uint16_t grub_relocator16_sp; + extern grub_uint32_t grub_relocator16_edx; + extern grub_uint32_t grub_relocator16_ebx; + extern grub_uint32_t grub_relocator16_esi; ++extern grub_uint32_t grub_relocator16_ebp; + + extern grub_uint16_t grub_relocator16_keep_a20_enabled; + +@@ -225,6 +226,7 @@ grub_relocator16_boot (struct grub_relocator *rel, + grub_relocator16_ss = state.ss; + grub_relocator16_sp = state.sp; + ++ grub_relocator16_ebp = state.ebp; + grub_relocator16_ebx = state.ebx; + grub_relocator16_edx = state.edx; + grub_relocator16_esi = state.esi; +diff --git a/grub-core/lib/i386/relocator16.S b/grub-core/lib/i386/relocator16.S +index e79d875..c8d6f86 100644 +--- a/grub-core/lib/i386/relocator16.S ++++ b/grub-core/lib/i386/relocator16.S +@@ -259,6 +259,11 @@ VARIABLE(grub_relocator16_edx) + VARIABLE(grub_relocator16_ebx) + .long 0 + ++ /* movl imm32, %ebp. */ ++ .byte 0x66, 0xbd ++VARIABLE(grub_relocator16_ebp) ++ .long 0 ++ + /* Cleared direction flag is of no problem with any current + payload and makes this implementation easier. */ + cld +diff --git a/grub-core/loader/i386/pc/freedos.c b/grub-core/loader/i386/pc/freedos.c +index f1eed57..e685c6e 100644 +--- a/grub-core/loader/i386/pc/freedos.c ++++ b/grub-core/loader/i386/pc/freedos.c +@@ -32,6 +32,7 @@ + #include + #include + #include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -40,8 +41,23 @@ static struct grub_relocator *rel; + static grub_uint32_t ebx = 0xffffffff; + + #define GRUB_FREEDOS_SEGMENT 0x60 ++#define GRUB_FREEDOS_ADDR (GRUB_FREEDOS_SEGMENT << 4) + #define GRUB_FREEDOS_STACK_SEGMENT 0x1fe0 +-#define GRUB_FREEDOS_STACK_POINTER 0x8000 ++#define GRUB_FREEDOS_STACK_BPB_POINTER 0x7c00 ++#define GRUB_FREEDOS_BPB_ADDR ((GRUB_FREEDOS_STACK_SEGMENT << 4) \ ++ + GRUB_FREEDOS_STACK_BPB_POINTER) ++ ++/* FreeDOS boot.asm passes register sp as exactly this. Importantly, ++ it must point below the BPB (to avoid overwriting any of it). */ ++#define GRUB_FREEDOS_STACK_POINTER (GRUB_FREEDOS_STACK_BPB_POINTER \ ++ - 0x60) ++ ++/* In this, the additional 8192 bytes are the stack reservation; the ++ remaining parts trivially give the maximum allowed size. */ ++#define GRUB_FREEDOS_MAX_SIZE ((GRUB_FREEDOS_STACK_SEGMENT << 4) \ ++ + GRUB_FREEDOS_STACK_POINTER \ ++ - GRUB_FREEDOS_ADDR \ ++ - 8192) + + static grub_err_t + grub_freedos_boot (void) +@@ -49,14 +65,16 @@ grub_freedos_boot (void) + struct grub_relocator16_state state = { + .cs = GRUB_FREEDOS_SEGMENT, + .ip = 0, +- .ds = 0, ++ ++ .ds = GRUB_FREEDOS_STACK_SEGMENT, + .es = 0, + .fs = 0, + .gs = 0, + .ss = GRUB_FREEDOS_STACK_SEGMENT, + .sp = GRUB_FREEDOS_STACK_POINTER, ++ .ebp = GRUB_FREEDOS_STACK_BPB_POINTER, + .ebx = ebx, +- .edx = 0, ++ .edx = ebx, + .a20 = 1 + }; + grub_video_set_mode ("text", 0, 0); +@@ -79,8 +97,9 @@ grub_cmd_freedos (grub_command_t cmd __attribute__ ((unused)), + { + grub_file_t file = 0; + grub_err_t err; +- void *kernelsys; ++ void *bs, *kernelsys; + grub_size_t kernelsyssize; ++ grub_device_t dev; + + if (argc == 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); +@@ -95,12 +114,44 @@ grub_cmd_freedos (grub_command_t cmd __attribute__ ((unused)), + if (! file) + goto fail; + ++ { ++ grub_relocator_chunk_t ch; ++ err = grub_relocator_alloc_chunk_addr (rel, &ch, GRUB_FREEDOS_BPB_ADDR, ++ GRUB_DISK_SECTOR_SIZE); ++ if (err) ++ goto fail; ++ bs = get_virtual_current_address (ch); ++ } ++ + ebx = grub_get_root_biosnumber (); ++ dev = grub_device_open (0); ++ ++ if (dev && dev->disk) ++ { ++ err = grub_disk_read (dev->disk, 0, 0, GRUB_DISK_SECTOR_SIZE, bs); ++ if (err) ++ { ++ grub_device_close (dev); ++ goto fail; ++ } ++ grub_chainloader_patch_bpb (bs, dev, ebx); ++ } ++ ++ if (dev) ++ grub_device_close (dev); + + kernelsyssize = grub_file_size (file); ++ ++ if (kernelsyssize > GRUB_FREEDOS_MAX_SIZE) ++ { ++ grub_error (GRUB_ERR_BAD_OS, ++ N_("file `%s' is too large"), argv[0]); ++ goto fail; ++ } ++ + { + grub_relocator_chunk_t ch; +- err = grub_relocator_alloc_chunk_addr (rel, &ch, GRUB_FREEDOS_SEGMENT << 4, ++ err = grub_relocator_alloc_chunk_addr (rel, &ch, GRUB_FREEDOS_ADDR, + kernelsyssize); + if (err) + goto fail; +diff --git a/include/grub/i386/relocator.h b/include/grub/i386/relocator.h +index 46becb8..5f89a7e 100644 +--- a/include/grub/i386/relocator.h ++++ b/include/grub/i386/relocator.h +@@ -49,6 +49,7 @@ struct grub_relocator16_state + grub_uint32_t ebx; + grub_uint32_t edx; + grub_uint32_t esi; ++ grub_uint32_t ebp; + int a20; + }; + +-- +1.8.1.4 + diff --git a/0142-grub-core-normal-menu_text.c-grub_menu_init_page-Fix.patch b/0142-grub-core-normal-menu_text.c-grub_menu_init_page-Fix.patch new file mode 100644 index 0000000..954670a --- /dev/null +++ b/0142-grub-core-normal-menu_text.c-grub_menu_init_page-Fix.patch @@ -0,0 +1,40 @@ +From d663de5bc403d819059ec5b8faeade326311644b Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sun, 27 Jan 2013 16:12:05 +0100 +Subject: [PATCH 142/364] * grub-core/normal/menu_text.c + (grub_menu_init_page): Fix behaviour when menu highlight color isn't set. + +--- + ChangeLog | 5 +++++ + grub-core/normal/menu_text.c | 2 +- + 2 files changed, 6 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index f5cb7dc..2ad83f5 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,8 @@ ++2013-01-27 Vladimir Serbinenko ++ ++ * grub-core/normal/menu_text.c (grub_menu_init_page): Fix behaviour ++ when menu highlight color isn't set. ++ + 2013-01-27 C. Masloch + + Improve FreeDOS direct loading support compatibility. +diff --git a/grub-core/normal/menu_text.c b/grub-core/normal/menu_text.c +index 80a7cd9..0031b0c 100644 +--- a/grub-core/normal/menu_text.c ++++ b/grub-core/normal/menu_text.c +@@ -357,7 +357,7 @@ grub_menu_init_page (int nested, int edit, int *num_entries, + old_color_normal = grub_term_normal_color; + old_color_highlight = grub_term_highlight_color; + grub_color_menu_normal = grub_term_normal_color; +- grub_color_menu_highlight = grub_color_menu_highlight; ++ grub_color_menu_highlight = grub_term_highlight_color; + + /* Then give user a chance to replace them. */ + grub_parse_color_name_pair (&grub_color_menu_normal, +-- +1.8.1.4 + diff --git a/0143-util-grub-install.in-change-misleading-comment-about.patch b/0143-util-grub-install.in-change-misleading-comment-about.patch new file mode 100644 index 0000000..cecd639 --- /dev/null +++ b/0143-util-grub-install.in-change-misleading-comment-about.patch @@ -0,0 +1,40 @@ +From 860427424f29d2e1e799509aea585cf928982bba Mon Sep 17 00:00:00 2001 +From: Andrey Borzenkov +Date: Sun, 27 Jan 2013 16:17:21 +0100 +Subject: [PATCH 143/364] * util/grub-install.in: change misleading + comment about device.map creation + +--- + ChangeLog | 5 +++++ + util/grub-install.in | 2 +- + 2 files changed, 6 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index 2ad83f5..74ef434 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,8 @@ ++2013-01-27 Andrey Borzenkov ++ ++ * util/grub-install.in: change misleading comment about ++ device.map creation ++ + 2013-01-27 Vladimir Serbinenko + + * grub-core/normal/menu_text.c (grub_menu_init_page): Fix behaviour +diff --git a/util/grub-install.in b/util/grub-install.in +index aac27c7..9e63cf5 100644 +--- a/util/grub-install.in ++++ b/util/grub-install.in +@@ -505,7 +505,7 @@ if test $recheck = yes; then + rm -f "$device_map" + fi + +-# Create the device map file if it is not present. ++# Device map file is optional + if test -f "$device_map"; then + # Make sure that there is no duplicated entry. + tmp=`sed -n '/^([fh]d[0-9]*)/s/\(^(.*)\).*/\1/p' "$device_map" \ +-- +1.8.1.4 + diff --git a/0144-grub-core-fs-xfs.c-grub_xfs_read_block-Fix-computati.patch b/0144-grub-core-fs-xfs.c-grub_xfs_read_block-Fix-computati.patch new file mode 100644 index 0000000..c858562 --- /dev/null +++ b/0144-grub-core-fs-xfs.c-grub_xfs_read_block-Fix-computati.patch @@ -0,0 +1,42 @@ +From 08e4779087f1086d7e2b1d4818ea48618abc63ec Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Wed, 30 Jan 2013 09:22:43 +0100 +Subject: [PATCH 144/364] * grub-core/fs/xfs.c (grub_xfs_read_block): + Fix computation in presence of extended attributes. + +--- + ChangeLog | 5 +++++ + grub-core/fs/xfs.c | 4 +--- + 2 files changed, 6 insertions(+), 3 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 74ef434..e5b71cf 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,8 @@ ++2013-01-30 Vladimir Serbinenko ++ ++ * grub-core/fs/xfs.c (grub_xfs_read_block): Fix computation in presence ++ of extended attributes. ++ + 2013-01-27 Andrey Borzenkov + + * util/grub-install.in: change misleading comment about +diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c +index 49d2a89..aee1582 100644 +--- a/grub-core/fs/xfs.c ++++ b/grub-core/fs/xfs.c +@@ -295,9 +295,7 @@ grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) + nrec = grub_be_to_cpu16 (node->inode.data.btree.numrecs); + keys = &node->inode.data.btree.keys[0]; + if (node->inode.fork_offset) +- recoffset = (node->inode.fork_offset +- - ((char *) &node->inode.data.btree.keys - (char *) &node->inode)) +- / (2 * sizeof (grub_uint64_t)); ++ recoffset = (node->inode.fork_offset - 1) / 2; + else + recoffset = ((1 << node->data->sblock.log2_inode) + - ((char *) &node->inode.data.btree.keys +-- +1.8.1.4 + diff --git a/0145-grub-core-bus-usb-serial-common.c-grub_usbserial_att.patch b/0145-grub-core-bus-usb-serial-common.c-grub_usbserial_att.patch new file mode 100644 index 0000000..c509aa3 --- /dev/null +++ b/0145-grub-core-bus-usb-serial-common.c-grub_usbserial_att.patch @@ -0,0 +1,40 @@ +From e296c452399417a814ab8b025234235d7ea1552e Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Fri, 1 Feb 2013 21:32:17 +0100 +Subject: [PATCH 145/364] * grub-core/bus/usb/serial/common.c + (grub_usbserial_attach): Fix missing zero-out of port structure. + +--- + ChangeLog | 5 +++++ + grub-core/bus/usb/serial/common.c | 2 +- + 2 files changed, 6 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index e5b71cf..7bae470 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,8 @@ ++2013-02-01 Vladimir Serbinenko ++ ++ * grub-core/bus/usb/serial/common.c (grub_usbserial_attach): Fix missing ++ zero-out of port structure. ++ + 2013-01-30 Vladimir Serbinenko + + * grub-core/fs/xfs.c (grub_xfs_read_block): Fix computation in presence +diff --git a/grub-core/bus/usb/serial/common.c b/grub-core/bus/usb/serial/common.c +index 55d1884..9530259 100644 +--- a/grub-core/bus/usb/serial/common.c ++++ b/grub-core/bus/usb/serial/common.c +@@ -51,7 +51,7 @@ grub_usbserial_attach (grub_usb_device_t usbdev, int configno, int interfno, + + interf = usbdev->config[configno].interf[interfno].descif; + +- port = grub_malloc (sizeof (*port)); ++ port = grub_zalloc (sizeof (*port)); + if (!port) + { + grub_print_error (); +-- +1.8.1.4 + diff --git a/0146-grub-core-bus-usb-usb.c-grub_usb_device_attach-Add-m.patch b/0146-grub-core-bus-usb-usb.c-grub_usb_device_attach-Add-m.patch new file mode 100644 index 0000000..6596055 --- /dev/null +++ b/0146-grub-core-bus-usb-usb.c-grub_usb_device_attach-Add-m.patch @@ -0,0 +1,52 @@ +From b7ad8ce9acca6630b6e822f0f4c4e0fa28291860 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Fri, 1 Feb 2013 21:43:49 +0100 +Subject: [PATCH 146/364] * grub-core/bus/usb/usb.c + (grub_usb_device_attach): Add missing grub_print_error. + +--- + ChangeLog | 5 +++++ + grub-core/bus/usb/usb.c | 4 ++++ + 2 files changed, 9 insertions(+) + +diff --git a/ChangeLog b/ChangeLog +index 7bae470..26702c7 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,10 @@ + 2013-02-01 Vladimir Serbinenko + ++ * grub-core/bus/usb/usb.c (grub_usb_device_attach): Add missing ++ grub_print_error. ++ ++2013-02-01 Vladimir Serbinenko ++ + * grub-core/bus/usb/serial/common.c (grub_usbserial_attach): Fix missing + zero-out of port structure. + +diff --git a/grub-core/bus/usb/usb.c b/grub-core/bus/usb/usb.c +index 6fbf134..5df08e9 100644 +--- a/grub-core/bus/usb/usb.c ++++ b/grub-core/bus/usb/usb.c +@@ -297,14 +297,18 @@ void grub_usb_device_attach (grub_usb_device_t dev) + { + case GRUB_USB_CLASS_MASS_STORAGE: + grub_dl_load ("usbms"); ++ grub_print_error (); + break; + case GRUB_USB_CLASS_HID: + grub_dl_load ("usb_keyboard"); ++ grub_print_error (); + break; + case 0xff: + /* FIXME: don't load useless modules. */ + grub_dl_load ("usbserial_ftdi"); ++ grub_print_error (); + grub_dl_load ("usbserial_pl2303"); ++ grub_print_error (); + break; + } + } +-- +1.8.1.4 + diff --git a/0147-grub-core-commands-lsacpi.c-Show-more-info.-Hide-som.patch b/0147-grub-core-commands-lsacpi.c-Show-more-info.-Hide-som.patch new file mode 100644 index 0000000..496769c --- /dev/null +++ b/0147-grub-core-commands-lsacpi.c-Show-more-info.-Hide-som.patch @@ -0,0 +1,175 @@ +From 15fb0e0734d438c6873c00c0ec9838764414ae98 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Fri, 1 Feb 2013 21:45:39 +0100 +Subject: [PATCH 147/364] * grub-core/commands/lsacpi.c: Show more info. + Hide some boring parts unless they have unexpected values. + +--- + ChangeLog | 5 ++++ + grub-core/commands/lsacpi.c | 70 ++++++++++++++++++++++++++++++++++++++------- + 2 files changed, 64 insertions(+), 11 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 26702c7..4141f6a 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,10 @@ + 2013-02-01 Vladimir Serbinenko + ++ * grub-core/commands/lsacpi.c: Show more info. Hide some boring parts ++ unless they have unexpected values. ++ ++2013-02-01 Vladimir Serbinenko ++ + * grub-core/bus/usb/usb.c (grub_usb_device_attach): Add missing + grub_print_error. + +diff --git a/grub-core/commands/lsacpi.c b/grub-core/commands/lsacpi.c +index 07c3f0d..1038479 100644 +--- a/grub-core/commands/lsacpi.c ++++ b/grub-core/commands/lsacpi.c +@@ -44,7 +44,8 @@ static void + disp_acpi_table (struct grub_acpi_table_header *t) + { + print_field (t->signature); +- grub_printf ("%4" PRIuGRUB_UINT32_T "B rev=%u OEM=", t->length, t->revision); ++ grub_printf ("%4" PRIuGRUB_UINT32_T "B rev=%u chksum=0x%02x (%s) OEM=", t->length, t->revision, t->checksum, ++ grub_byte_checksum (t, t->length) == 0 ? "valid" : "invalid"); + print_field (t->oemid); + print_field (t->oemtable); + grub_printf ("OEMrev=%08" PRIxGRUB_UINT32_T " ", t->oemrev); +@@ -66,39 +67,81 @@ disp_madt_table (struct grub_acpi_madt *t) + d = t->entries; + for (;len > 0; len -= d->len, d = (void *) ((grub_uint8_t *) d + d->len)) + { +- grub_printf (" type=%x l=%u ", d->type, d->len); +- + switch (d->type) + { ++ case GRUB_ACPI_MADT_ENTRY_TYPE_LAPIC: ++ { ++ struct grub_acpi_madt_entry_lapic *dt = (void *) d; ++ grub_printf (" LAPIC ACPI_ID=%02x APIC_ID=%02x Flags=%08x\n", ++ dt->acpiid, dt->apicid, dt->flags); ++ if (dt->hdr.len != sizeof (*dt)) ++ grub_printf (" table size mismatch %d != %d\n", dt->hdr.len, sizeof (*dt)); ++ break; ++ } ++ ++ case GRUB_ACPI_MADT_ENTRY_TYPE_IOAPIC: ++ { ++ struct grub_acpi_madt_entry_ioapic *dt = (void *) d; ++ grub_printf (" IOAPIC ID=%02x address=%08x GSI=%08x\n", ++ dt->id, dt->address, dt->global_sys_interrupt); ++ if (dt->hdr.len != sizeof (*dt)) ++ grub_printf (" table size mismatch %d != %d\n", dt->hdr.len, sizeof (*dt)); ++ if (dt->pad) ++ grub_printf (" non-zero pad: %02x\n", dt->pad); ++ break; ++ } ++ + case GRUB_ACPI_MADT_ENTRY_TYPE_INTERRUPT_OVERRIDE: + { + struct grub_acpi_madt_entry_interrupt_override *dt = (void *) d; +- grub_printf ("Int Override bus=%x src=%x GSI=%08x Flags=%04x\n", ++ grub_printf (" Int Override bus=%x src=%x GSI=%08x Flags=%04x\n", + dt->bus, dt->source, dt->global_sys_interrupt, + dt->flags); ++ if (dt->hdr.len != sizeof (*dt)) ++ grub_printf (" table size mismatch %d != %d\n", dt->hdr.len, sizeof (*dt)); + } + break; ++ ++ case GRUB_ACPI_MADT_ENTRY_TYPE_LAPIC_NMI: ++ { ++ struct grub_acpi_madt_entry_lapic_nmi *dt = (void *) d; ++ grub_printf (" LAPIC_NMI ACPI_ID=%02x Flags=%04x lint=%02x\n", ++ dt->acpiid, dt->flags, dt->lint); ++ if (dt->hdr.len != sizeof (*dt)) ++ grub_printf (" table size mismatch %d != %d\n", dt->hdr.len, sizeof (*dt)); ++ break; ++ } ++ + case GRUB_ACPI_MADT_ENTRY_TYPE_SAPIC: + { + struct grub_acpi_madt_entry_sapic *dt = (void *) d; +- grub_printf ("IOSAPIC Id=%02x GSI=%08x Addr=%016" PRIxGRUB_UINT64_T ++ grub_printf (" IOSAPIC Id=%02x GSI=%08x Addr=%016" PRIxGRUB_UINT64_T + "\n", + dt->id, dt->global_sys_interrupt_base, + dt->addr); ++ if (dt->hdr.len != sizeof (*dt)) ++ grub_printf (" table size mismatch %d != %d\n", dt->hdr.len, sizeof (*dt)); ++ if (dt->pad) ++ grub_printf (" non-zero pad: %02x\n", dt->pad); ++ + } + break; + case GRUB_ACPI_MADT_ENTRY_TYPE_LSAPIC: + { + struct grub_acpi_madt_entry_lsapic *dt = (void *) d; +- grub_printf ("LSAPIC ProcId=%02x ID=%02x EID=%02x Flags=%x", ++ grub_printf (" LSAPIC ProcId=%02x ID=%02x EID=%02x Flags=%x", + dt->cpu_id, dt->id, dt->eid, dt->flags); + if (dt->flags & GRUB_ACPI_MADT_ENTRY_SAPIC_FLAGS_ENABLED) + grub_printf (" Enabled\n"); + else + grub_printf (" Disabled\n"); + if (d->len > sizeof (struct grub_acpi_madt_entry_sapic)) +- grub_printf (" UID val=%08x, Str=%s\n", dt->cpu_uid, ++ grub_printf (" UID val=%08x, Str=%s\n", dt->cpu_uid, + dt->cpu_uid_str); ++ if (dt->hdr.len != sizeof (*dt) + grub_strlen ((char *) dt->cpu_uid_str) + 1) ++ grub_printf (" table size mismatch %d != %d\n", dt->hdr.len, sizeof (*dt)); ++ if (dt->pad[0] || dt->pad[1] || dt->pad[2]) ++ grub_printf (" non-zero pad: %02x%02x%02x\n", dt->pad[0], dt->pad[1], dt->pad[2]); + } + break; + case GRUB_ACPI_MADT_ENTRY_TYPE_PLATFORM_INT_SOURCE: +@@ -107,17 +150,18 @@ disp_madt_table (struct grub_acpi_madt *t) + static const char * const platint_type[] = + {"Nul", "PMI", "INIT", "CPEI"}; + +- grub_printf ("Platform INT flags=%04x type=%02x (%s)" ++ grub_printf (" Platform INT flags=%04x type=%02x (%s)" + " ID=%02x EID=%02x\n", + dt->flags, dt->inttype, + (dt->inttype < ARRAY_SIZE (platint_type)) + ? platint_type[dt->inttype] : "??", dt->cpu_id, + dt->cpu_eid); +- grub_printf (" IOSAPIC Vec=%02x GSI=%08x source flags=%08x\n", ++ grub_printf (" IOSAPIC Vec=%02x GSI=%08x source flags=%08x\n", + dt->sapic_vector, dt->global_sys_int, dt->src_flags); + } + break; + default: ++ grub_printf (" type=%x l=%u ", d->type, d->len); + grub_printf (" ??\n"); + } + } +@@ -182,7 +226,7 @@ static void + disp_acpi_rsdpv1 (struct grub_acpi_rsdp_v10 *rsdp) + { + print_field (rsdp->signature); +- grub_printf ("chksum:%02x, OEM-ID: ", rsdp->checksum); ++ grub_printf ("chksum:%02x (%s), OEM-ID: ", rsdp->checksum, grub_byte_checksum (rsdp, sizeof (*rsdp)) == 0 ? "valid" : "invalid"); + print_field (rsdp->oemid); + grub_printf ("rev=%d\n", rsdp->revision); + grub_printf ("RSDT=%08" PRIxGRUB_UINT32_T "\n", rsdp->rsdt_addr); +@@ -192,8 +236,12 @@ static void + disp_acpi_rsdpv2 (struct grub_acpi_rsdp_v20 *rsdp) + { + disp_acpi_rsdpv1 (&rsdp->rsdpv1); +- grub_printf ("len=%d XSDT=%016" PRIxGRUB_UINT64_T "\n", rsdp->length, ++ grub_printf ("len=%d chksum=%02x (%s) XSDT=%016" PRIxGRUB_UINT64_T "\n", rsdp->length, rsdp->checksum, grub_byte_checksum (rsdp, rsdp->length) == 0 ? "valid" : "invalid", + rsdp->xsdt_addr); ++ if (rsdp->length != sizeof (*rsdp)) ++ grub_printf (" length mismatch %d != %d\n", rsdp->length, sizeof (*rsdp)); ++ if (rsdp->reserved[0] || rsdp->reserved[1] || rsdp->reserved[2]) ++ grub_printf (" non-zero reserved %02x%02x%02x\n", rsdp->reserved[0], rsdp->reserved[1], rsdp->reserved[2]); + } + + static const struct grub_arg_option options[] = { +-- +1.8.1.4 + diff --git a/0148-Missing-part-of-last-commit.patch b/0148-Missing-part-of-last-commit.patch new file mode 100644 index 0000000..0cfedcc --- /dev/null +++ b/0148-Missing-part-of-last-commit.patch @@ -0,0 +1,67 @@ +From 0484a13a5db39105b817cb9b10702d038e26b918 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Fri, 1 Feb 2013 21:48:01 +0100 +Subject: [PATCH 148/364] Missing part of last commit + +--- + include/grub/acpi.h | 31 ++++++++++++++++++++++++++++++- + 1 file changed, 30 insertions(+), 1 deletion(-) + +diff --git a/include/grub/acpi.h b/include/grub/acpi.h +index ee0a108..52d190c 100644 +--- a/include/grub/acpi.h ++++ b/include/grub/acpi.h +@@ -88,12 +88,32 @@ struct grub_acpi_madt + + enum + { ++ GRUB_ACPI_MADT_ENTRY_TYPE_LAPIC = 0, ++ GRUB_ACPI_MADT_ENTRY_TYPE_IOAPIC = 1, + GRUB_ACPI_MADT_ENTRY_TYPE_INTERRUPT_OVERRIDE = 2, ++ GRUB_ACPI_MADT_ENTRY_TYPE_LAPIC_NMI = 4, + GRUB_ACPI_MADT_ENTRY_TYPE_SAPIC = 6, + GRUB_ACPI_MADT_ENTRY_TYPE_LSAPIC = 7, + GRUB_ACPI_MADT_ENTRY_TYPE_PLATFORM_INT_SOURCE = 8 + }; + ++struct grub_acpi_madt_entry_lapic ++{ ++ struct grub_acpi_madt_entry_header hdr; ++ grub_uint8_t acpiid; ++ grub_uint8_t apicid; ++ grub_uint32_t flags; ++}; ++ ++struct grub_acpi_madt_entry_ioapic ++{ ++ struct grub_acpi_madt_entry_header hdr; ++ grub_uint8_t id; ++ grub_uint8_t pad; ++ grub_uint32_t address; ++ grub_uint32_t global_sys_interrupt; ++}; ++ + struct grub_acpi_madt_entry_interrupt_override + { + struct grub_acpi_madt_entry_header hdr; +@@ -101,7 +121,16 @@ struct grub_acpi_madt_entry_interrupt_override + grub_uint8_t source; + grub_uint32_t global_sys_interrupt; + grub_uint16_t flags; +-}; ++} __attribute__ ((packed)); ++ ++ ++struct grub_acpi_madt_entry_lapic_nmi ++{ ++ struct grub_acpi_madt_entry_header hdr; ++ grub_uint8_t acpiid; ++ grub_uint16_t flags; ++ grub_uint8_t lint; ++} __attribute__ ((packed)); + + struct grub_acpi_madt_entry_sapic + { +-- +1.8.1.4 + diff --git a/0149-Implement-USBDebug-full-USB-stack-variant.patch b/0149-Implement-USBDebug-full-USB-stack-variant.patch new file mode 100644 index 0000000..3737588 --- /dev/null +++ b/0149-Implement-USBDebug-full-USB-stack-variant.patch @@ -0,0 +1,272 @@ +From d425de05c38b6f588052be462e8539f2fb879e24 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Fri, 1 Feb 2013 21:49:29 +0100 +Subject: [PATCH 149/364] Implement USBDebug (full USB stack variant). + +--- + ChangeLog | 4 ++ + grub-core/Makefile.core.def | 6 +++ + grub-core/bus/usb/serial/common.c | 11 ++-- + grub-core/bus/usb/serial/ftdi.c | 4 +- + grub-core/bus/usb/serial/pl2303.c | 4 +- + grub-core/bus/usb/serial/usbdebug_late.c | 93 ++++++++++++++++++++++++++++++++ + grub-core/bus/usb/usb.c | 2 + + include/grub/usbdesc.h | 9 ++++ + include/grub/usbserial.h | 7 ++- + 9 files changed, 134 insertions(+), 6 deletions(-) + create mode 100644 grub-core/bus/usb/serial/usbdebug_late.c + +diff --git a/ChangeLog b/ChangeLog +index 4141f6a..2e681c1 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,9 @@ + 2013-02-01 Vladimir Serbinenko + ++ Implement USBDebug (full USB stack variant). ++ ++2013-02-01 Vladimir Serbinenko ++ + * grub-core/commands/lsacpi.c: Show more info. Hide some boring parts + unless they have unexpected values. + +diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def +index 4609a4b..c006abf 100644 +--- a/grub-core/Makefile.core.def ++++ b/grub-core/Makefile.core.def +@@ -448,6 +448,12 @@ module = { + }; + + module = { ++ name = usbserial_usbdebug; ++ common = bus/usb/serial/usbdebug_late.c; ++ enable = usb; ++}; ++ ++module = { + name = uhci; + common = bus/usb/uhci.c; + enable = x86; +diff --git a/grub-core/bus/usb/serial/common.c b/grub-core/bus/usb/serial/common.c +index 9530259..06f2b0e 100644 +--- a/grub-core/bus/usb/serial/common.c ++++ b/grub-core/bus/usb/serial/common.c +@@ -42,7 +42,8 @@ static int usbnum = 0; + + int + grub_usbserial_attach (grub_usb_device_t usbdev, int configno, int interfno, +- struct grub_serial_driver *driver) ++ struct grub_serial_driver *driver, int in_endp, ++ int out_endp) + { + struct grub_serial_port *port; + int j; +@@ -73,12 +74,16 @@ grub_usbserial_attach (grub_usb_device_t usbdev, int configno, int interfno, + struct grub_usb_desc_endp *endp; + endp = &usbdev->config[0].interf[interfno].descendp[j]; + +- if ((endp->endp_addr & 128) && (endp->attrib & 3) == 2) ++ if ((endp->endp_addr & 128) && (endp->attrib & 3) == 2 ++ && (in_endp == GRUB_USB_SERIAL_ENDPOINT_LAST_MATCHING ++ || in_endp == endp->endp_addr)) + { + /* Bulk IN endpoint. */ + port->in_endp = endp; + } +- else if (!(endp->endp_addr & 128) && (endp->attrib & 3) == 2) ++ else if (!(endp->endp_addr & 128) && (endp->attrib & 3) == 2 ++ && (out_endp == GRUB_USB_SERIAL_ENDPOINT_LAST_MATCHING ++ || out_endp == endp->endp_addr)) + { + /* Bulk OUT endpoint. */ + port->out_endp = endp; +diff --git a/grub-core/bus/usb/serial/ftdi.c b/grub-core/bus/usb/serial/ftdi.c +index 15ea8fb..e94fd27 100644 +--- a/grub-core/bus/usb/serial/ftdi.c ++++ b/grub-core/bus/usb/serial/ftdi.c +@@ -193,7 +193,9 @@ grub_ftdi_attach (grub_usb_device_t usbdev, int configno, int interfno) + return 0; + + return grub_usbserial_attach (usbdev, configno, interfno, +- &grub_ftdi_driver); ++ &grub_ftdi_driver, ++ GRUB_USB_SERIAL_ENDPOINT_LAST_MATCHING, ++ GRUB_USB_SERIAL_ENDPOINT_LAST_MATCHING); + } + + static struct grub_usb_attach_desc attach_hook = +diff --git a/grub-core/bus/usb/serial/pl2303.c b/grub-core/bus/usb/serial/pl2303.c +index 5433763..f46c6ac 100644 +--- a/grub-core/bus/usb/serial/pl2303.c ++++ b/grub-core/bus/usb/serial/pl2303.c +@@ -208,7 +208,9 @@ grub_pl2303_attach (grub_usb_device_t usbdev, int configno, int interfno) + return 0; + + return grub_usbserial_attach (usbdev, configno, interfno, +- &grub_pl2303_driver); ++ &grub_pl2303_driver, ++ GRUB_USB_SERIAL_ENDPOINT_LAST_MATCHING, ++ GRUB_USB_SERIAL_ENDPOINT_LAST_MATCHING); + } + + static struct grub_usb_attach_desc attach_hook = +diff --git a/grub-core/bus/usb/serial/usbdebug_late.c b/grub-core/bus/usb/serial/usbdebug_late.c +new file mode 100644 +index 0000000..23526e1 +--- /dev/null ++++ b/grub-core/bus/usb/serial/usbdebug_late.c +@@ -0,0 +1,93 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2000,2001,2002,2003,2004,2005,2007,2008,2009,2010,2013 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 ++ ++GRUB_MOD_LICENSE ("GPLv3+"); ++ ++ ++/* Fetch a key. */ ++static int ++usbdebug_late_hw_fetch (struct grub_serial_port *port) ++{ ++ return grub_usbserial_fetch (port, 0); ++} ++ ++/* Put a character. */ ++static void ++usbdebug_late_hw_put (struct grub_serial_port *port, const int c) ++{ ++ char cc = c; ++ ++ grub_usb_bulk_write (port->usbdev, port->out_endp->endp_addr, 1, &cc); ++} ++ ++static grub_err_t ++usbdebug_late_hw_configure (struct grub_serial_port *port __attribute__ ((unused)), ++ struct grub_serial_config *config __attribute__ ((unused))) ++{ ++ return GRUB_ERR_NONE; ++} ++ ++static struct grub_serial_driver grub_usbdebug_late_driver = ++ { ++ .configure = usbdebug_late_hw_configure, ++ .fetch = usbdebug_late_hw_fetch, ++ .put = usbdebug_late_hw_put, ++ .fini = grub_usbserial_fini ++ }; ++ ++static int ++grub_usbdebug_late_attach (grub_usb_device_t usbdev, int configno, int interfno) ++{ ++ grub_usb_err_t err; ++ struct grub_usb_desc_debug debugdesc; ++ ++ err = grub_usb_get_descriptor (usbdev, GRUB_USB_DESCRIPTOR_DEBUG, configno, ++ sizeof (debugdesc), (char *) &debugdesc); ++ if (err) ++ return 0; ++ ++ return grub_usbserial_attach (usbdev, configno, interfno, ++ &grub_usbdebug_late_driver, ++ debugdesc.in_endp, debugdesc.out_endp); ++} ++ ++static struct grub_usb_attach_desc attach_hook = ++{ ++ .class = 0xff, ++ .hook = grub_usbdebug_late_attach ++}; ++ ++GRUB_MOD_INIT(usbserial_usbdebug_late) ++{ ++ grub_usb_register_attach_hook_class (&attach_hook); ++} ++ ++GRUB_MOD_FINI(usbserial_usbdebug_late) ++{ ++ grub_serial_unregister_driver (&grub_usbdebug_late_driver); ++ grub_usb_unregister_attach_hook_class (&attach_hook); ++} +diff --git a/grub-core/bus/usb/usb.c b/grub-core/bus/usb/usb.c +index 5df08e9..41d8010 100644 +--- a/grub-core/bus/usb/usb.c ++++ b/grub-core/bus/usb/usb.c +@@ -309,6 +309,8 @@ void grub_usb_device_attach (grub_usb_device_t dev) + grub_print_error (); + grub_dl_load ("usbserial_pl2303"); + grub_print_error (); ++ grub_dl_load ("usbserial_usbdebug"); ++ grub_print_error (); + break; + } + } +diff --git a/include/grub/usbdesc.h b/include/grub/usbdesc.h +index 84b723a..7d14152 100644 +--- a/include/grub/usbdesc.h ++++ b/include/grub/usbdesc.h +@@ -28,6 +28,7 @@ typedef enum { + GRUB_USB_DESCRIPTOR_STRING, + GRUB_USB_DESCRIPTOR_INTERFACE, + GRUB_USB_DESCRIPTOR_ENDPOINT, ++ GRUB_USB_DESCRIPTOR_DEBUG = 10, + GRUB_USB_DESCRIPTOR_HUB = 0x29 + } grub_usb_descriptor_t; + +@@ -111,6 +112,14 @@ struct grub_usb_desc_str + grub_uint16_t str[0]; + } __attribute__ ((packed)); + ++struct grub_usb_desc_debug ++{ ++ grub_uint8_t length; ++ grub_uint8_t type; ++ grub_uint8_t in_endp; ++ grub_uint8_t out_endp; ++} __attribute__ ((packed)); ++ + struct grub_usb_usb_hubdesc + { + grub_uint8_t length; +diff --git a/include/grub/usbserial.h b/include/grub/usbserial.h +index 7420125..f81f97a 100644 +--- a/include/grub/usbserial.h ++++ b/include/grub/usbserial.h +@@ -27,7 +27,12 @@ void grub_usbserial_detach (grub_usb_device_t usbdev, int configno, + + int + grub_usbserial_attach (grub_usb_device_t usbdev, int configno, int interfno, +- struct grub_serial_driver *driver); ++ struct grub_serial_driver *driver, int in_endp, ++ int out_endp); ++enum ++ { ++ GRUB_USB_SERIAL_ENDPOINT_LAST_MATCHING = -1 ++ }; + int + grub_usbserial_fetch (struct grub_serial_port *port, grub_size_t header_size); + +-- +1.8.1.4 + diff --git a/0150-grub-core-fs-fshelp.c-find_file-Set-oldnode-to-zero-.patch b/0150-grub-core-fs-fshelp.c-find_file-Set-oldnode-to-zero-.patch new file mode 100644 index 0000000..e9dcb54 --- /dev/null +++ b/0150-grub-core-fs-fshelp.c-find_file-Set-oldnode-to-zero-.patch @@ -0,0 +1,67 @@ +From 6b0ffea6b4093185ae5eedc1ce115c4b1a51e65d Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Fri, 1 Feb 2013 21:51:09 +0100 +Subject: [PATCH 150/364] * grub-core/fs/fshelp.c (find_file): Set + oldnode to zero after freeing it. + +--- + ChangeLog | 5 +++++ + grub-core/fs/fshelp.c | 8 +++++++- + 2 files changed, 12 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index 2e681c1..f5396fe 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,10 @@ + 2013-02-01 Vladimir Serbinenko + ++ * grub-core/fs/fshelp.c (find_file): Set oldnode to zero after ++ freeing it. ++ ++2013-02-01 Vladimir Serbinenko ++ + Implement USBDebug (full USB stack variant). + + 2013-02-01 Vladimir Serbinenko +diff --git a/grub-core/fs/fshelp.c b/grub-core/fs/fshelp.c +index 7e557c3..11a1259 100644 +--- a/grub-core/fs/fshelp.c ++++ b/grub-core/fs/fshelp.c +@@ -147,6 +147,7 @@ find_file (const char *currpath, grub_fshelp_node_t currroot, + free_node (ctx->currnode, ctx); + free_node (ctx->oldnode, ctx); + ctx->currnode = 0; ++ ctx->oldnode = 0; + return grub_error (GRUB_ERR_SYMLINK_LOOP, + N_("too deep nesting of symlinks")); + } +@@ -158,6 +159,7 @@ find_file (const char *currpath, grub_fshelp_node_t currroot, + if (!symlink) + { + free_node (ctx->oldnode, ctx); ++ ctx->oldnode = 0; + return grub_errno; + } + +@@ -177,12 +179,16 @@ find_file (const char *currpath, grub_fshelp_node_t currroot, + if (grub_errno) + { + free_node (ctx->oldnode, ctx); ++ ctx->oldnode = 0; + return grub_errno; + } + } + + if (ctx->oldnode != ctx->currnode) +- free_node (ctx->oldnode, ctx); ++ { ++ free_node (ctx->oldnode, ctx); ++ ctx->oldnode = 0; ++ } + + /* Found the node! */ + if (! next || *next == '\0') +-- +1.8.1.4 + diff --git a/0151-grub-core-disk-cryptodisk.c-grub_cryptodisk_scan_dev.patch b/0151-grub-core-disk-cryptodisk.c-grub_cryptodisk_scan_dev.patch new file mode 100644 index 0000000..a9feea8 --- /dev/null +++ b/0151-grub-core-disk-cryptodisk.c-grub_cryptodisk_scan_dev.patch @@ -0,0 +1,43 @@ +From e24e009bf730aaeef10783fca8ec04221a115713 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Mon, 4 Feb 2013 15:36:03 +0100 +Subject: [PATCH 151/364] * grub-core/disk/cryptodisk.c + (grub_cryptodisk_scan_device): Don't stop on first error. + +--- + ChangeLog | 5 +++++ + grub-core/disk/cryptodisk.c | 5 ++++- + 2 files changed, 9 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index f5396fe..0994ee7 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,8 @@ ++2013-02-04 Vladimir Serbinenko ++ ++ * grub-core/disk/cryptodisk.c (grub_cryptodisk_scan_device): Don't stop ++ on first error. ++ + 2013-02-01 Vladimir Serbinenko + + * grub-core/fs/fshelp.c (find_file): Set oldnode to zero after +diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c +index ce755c3..f39c1ab 100644 +--- a/grub-core/disk/cryptodisk.c ++++ b/grub-core/disk/cryptodisk.c +@@ -875,7 +875,10 @@ grub_cryptodisk_scan_device (const char *name, + /* Try to open disk. */ + source = grub_disk_open (name); + if (!source) +- return grub_errno; ++ { ++ grub_print_error (); ++ return 0; ++ } + + err = grub_cryptodisk_scan_device_real (name, source); + +-- +1.8.1.4 + diff --git a/0152-grub-core-commands-lsacpi.c-Fix-types-on-64-bit-plat.patch b/0152-grub-core-commands-lsacpi.c-Fix-types-on-64-bit-plat.patch new file mode 100644 index 0000000..5ae9985 --- /dev/null +++ b/0152-grub-core-commands-lsacpi.c-Fix-types-on-64-bit-plat.patch @@ -0,0 +1,100 @@ +From 2e26bf539522207793cbdb2f26241273bb41d8fe Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Wed, 6 Feb 2013 17:37:29 +0100 +Subject: [PATCH 152/364] * grub-core/commands/lsacpi.c: Fix types on + 64-bit platform. + +--- + ChangeLog | 4 ++++ + grub-core/commands/lsacpi.c | 21 ++++++++++++++------- + 2 files changed, 18 insertions(+), 7 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 0994ee7..3731229 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,7 @@ ++2013-02-06 Vladimir Serbinenko ++ ++ * grub-core/commands/lsacpi.c: Fix types on 64-bit platform. ++ + 2013-02-04 Vladimir Serbinenko + + * grub-core/disk/cryptodisk.c (grub_cryptodisk_scan_device): Don't stop +diff --git a/grub-core/commands/lsacpi.c b/grub-core/commands/lsacpi.c +index 1038479..0824914 100644 +--- a/grub-core/commands/lsacpi.c ++++ b/grub-core/commands/lsacpi.c +@@ -75,7 +75,8 @@ disp_madt_table (struct grub_acpi_madt *t) + grub_printf (" LAPIC ACPI_ID=%02x APIC_ID=%02x Flags=%08x\n", + dt->acpiid, dt->apicid, dt->flags); + if (dt->hdr.len != sizeof (*dt)) +- grub_printf (" table size mismatch %d != %d\n", dt->hdr.len, sizeof (*dt)); ++ grub_printf (" table size mismatch %d != %d\n", dt->hdr.len, ++ (int) sizeof (*dt)); + break; + } + +@@ -85,7 +86,8 @@ disp_madt_table (struct grub_acpi_madt *t) + grub_printf (" IOAPIC ID=%02x address=%08x GSI=%08x\n", + dt->id, dt->address, dt->global_sys_interrupt); + if (dt->hdr.len != sizeof (*dt)) +- grub_printf (" table size mismatch %d != %d\n", dt->hdr.len, sizeof (*dt)); ++ grub_printf (" table size mismatch %d != %d\n", dt->hdr.len, ++ (int) sizeof (*dt)); + if (dt->pad) + grub_printf (" non-zero pad: %02x\n", dt->pad); + break; +@@ -98,7 +100,8 @@ disp_madt_table (struct grub_acpi_madt *t) + dt->bus, dt->source, dt->global_sys_interrupt, + dt->flags); + if (dt->hdr.len != sizeof (*dt)) +- grub_printf (" table size mismatch %d != %d\n", dt->hdr.len, sizeof (*dt)); ++ grub_printf (" table size mismatch %d != %d\n", dt->hdr.len, ++ (int) sizeof (*dt)); + } + break; + +@@ -108,7 +111,8 @@ disp_madt_table (struct grub_acpi_madt *t) + grub_printf (" LAPIC_NMI ACPI_ID=%02x Flags=%04x lint=%02x\n", + dt->acpiid, dt->flags, dt->lint); + if (dt->hdr.len != sizeof (*dt)) +- grub_printf (" table size mismatch %d != %d\n", dt->hdr.len, sizeof (*dt)); ++ grub_printf (" table size mismatch %d != %d\n", dt->hdr.len, ++ (int) sizeof (*dt)); + break; + } + +@@ -120,7 +124,8 @@ disp_madt_table (struct grub_acpi_madt *t) + dt->id, dt->global_sys_interrupt_base, + dt->addr); + if (dt->hdr.len != sizeof (*dt)) +- grub_printf (" table size mismatch %d != %d\n", dt->hdr.len, sizeof (*dt)); ++ grub_printf (" table size mismatch %d != %d\n", dt->hdr.len, ++ (int) sizeof (*dt)); + if (dt->pad) + grub_printf (" non-zero pad: %02x\n", dt->pad); + +@@ -139,7 +144,8 @@ disp_madt_table (struct grub_acpi_madt *t) + grub_printf (" UID val=%08x, Str=%s\n", dt->cpu_uid, + dt->cpu_uid_str); + if (dt->hdr.len != sizeof (*dt) + grub_strlen ((char *) dt->cpu_uid_str) + 1) +- grub_printf (" table size mismatch %d != %d\n", dt->hdr.len, sizeof (*dt)); ++ grub_printf (" table size mismatch %d != %d\n", dt->hdr.len, ++ (int) sizeof (*dt)); + if (dt->pad[0] || dt->pad[1] || dt->pad[2]) + grub_printf (" non-zero pad: %02x%02x%02x\n", dt->pad[0], dt->pad[1], dt->pad[2]); + } +@@ -239,7 +245,8 @@ disp_acpi_rsdpv2 (struct grub_acpi_rsdp_v20 *rsdp) + grub_printf ("len=%d chksum=%02x (%s) XSDT=%016" PRIxGRUB_UINT64_T "\n", rsdp->length, rsdp->checksum, grub_byte_checksum (rsdp, rsdp->length) == 0 ? "valid" : "invalid", + rsdp->xsdt_addr); + if (rsdp->length != sizeof (*rsdp)) +- grub_printf (" length mismatch %d != %d\n", rsdp->length, sizeof (*rsdp)); ++ grub_printf (" length mismatch %d != %d\n", rsdp->length, ++ (int) sizeof (*rsdp)); + if (rsdp->reserved[0] || rsdp->reserved[1] || rsdp->reserved[2]) + grub_printf (" non-zero reserved %02x%02x%02x\n", rsdp->reserved[0], rsdp->reserved[1], rsdp->reserved[2]); + } +-- +1.8.1.4 + diff --git a/0153-Support-Openfirmware-disks-with-non-512B-sectors.patch b/0153-Support-Openfirmware-disks-with-non-512B-sectors.patch new file mode 100644 index 0000000..058574d --- /dev/null +++ b/0153-Support-Openfirmware-disks-with-non-512B-sectors.patch @@ -0,0 +1,153 @@ +From 069348765049ede8357b604a232cc636e5f2dbbb Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Tue, 19 Feb 2013 09:10:26 +0100 +Subject: [PATCH 153/364] Support Openfirmware disks with non-512B + sectors. + + * grub-core/disk/ieee1275/ofdisk.c (grub_ofdisk_open): Get the block + size of the disk. + * (grub_ofdisk_get_block_size): New function. + * (grub_ofdisk_prepare): Use the correct block size. + * (grub_ofdisk_read): Likewise. + * (grub_ofdisk_write): Likewise. + * include/grub/ieee1275/ofdisk.h (grub_ofdisk_get_block_size): + New proto. +--- + ChangeLog | 13 +++++++++ + grub-core/disk/ieee1275/ofdisk.c | 59 ++++++++++++++++++++++++++++++++++++---- + include/grub/ieee1275/ofdisk.h | 3 ++ + 3 files changed, 70 insertions(+), 5 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 3731229..654ebcb 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,16 @@ ++2013-02-19 Paulo Flabiano Smorigo ++ ++ Support Openfirmware disks with non-512B sectors. ++ ++ * grub-core/disk/ieee1275/ofdisk.c (grub_ofdisk_open): Get the block ++ size of the disk. ++ * (grub_ofdisk_get_block_size): New function. ++ * (grub_ofdisk_prepare): Use the correct block size. ++ * (grub_ofdisk_read): Likewise. ++ * (grub_ofdisk_write): Likewise. ++ * include/grub/ieee1275/ofdisk.h (grub_ofdisk_get_block_size): ++ New proto. ++ + 2013-02-06 Vladimir Serbinenko + + * grub-core/commands/lsacpi.c: Fix types on 64-bit platform. +diff --git a/grub-core/disk/ieee1275/ofdisk.c b/grub-core/disk/ieee1275/ofdisk.c +index 644bbd2..2130cb1 100644 +--- a/grub-core/disk/ieee1275/ofdisk.c ++++ b/grub-core/disk/ieee1275/ofdisk.c +@@ -349,6 +349,14 @@ grub_ofdisk_open (const char *name, grub_disk_t disk) + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a block device"); + } + ++ grub_uint32_t block_size = 0; ++ if (grub_ofdisk_get_block_size (devpath, &block_size) == 0) ++ { ++ for (disk->log_sector_size = 0; ++ (1U << disk->log_sector_size) < block_size; ++ disk->log_sector_size++); ++ } ++ + /* 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. */ +@@ -415,7 +423,7 @@ grub_ofdisk_prepare (grub_disk_t disk, grub_disk_addr_t sector) + last_devpath = disk->data; + } + +- pos = sector << GRUB_DISK_SECTOR_BITS; ++ pos = sector << disk->log_sector_size; + + grub_ieee1275_seek (last_ihandle, pos, &status); + if (status < 0) +@@ -434,9 +442,9 @@ grub_ofdisk_read (grub_disk_t disk, grub_disk_addr_t sector, + err = grub_ofdisk_prepare (disk, sector); + if (err) + return err; +- grub_ieee1275_read (last_ihandle, buf, size << GRUB_DISK_SECTOR_BITS, ++ grub_ieee1275_read (last_ihandle, buf, size << disk->log_sector_size, + &actual); +- if (actual != (grub_ssize_t) (size << GRUB_DISK_SECTOR_BITS)) ++ if (actual != (grub_ssize_t) (size << disk->log_sector_size)) + return grub_error (GRUB_ERR_READ_ERROR, N_("failure reading sector 0x%llx " + "from `%s'"), + (unsigned long long) sector, +@@ -454,9 +462,9 @@ grub_ofdisk_write (grub_disk_t disk, grub_disk_addr_t sector, + err = grub_ofdisk_prepare (disk, sector); + if (err) + return err; +- grub_ieee1275_write (last_ihandle, buf, size << GRUB_DISK_SECTOR_BITS, ++ grub_ieee1275_write (last_ihandle, buf, size << disk->log_sector_size, + &actual); +- if (actual != (grub_ssize_t) (size << GRUB_DISK_SECTOR_BITS)) ++ if (actual != (grub_ssize_t) (size << disk->log_sector_size)) + return grub_error (GRUB_ERR_WRITE_ERROR, N_("failure writing sector 0x%llx " + "to `%s'"), + (unsigned long long) sector, +@@ -493,3 +501,44 @@ grub_ofdisk_fini (void) + + grub_disk_dev_unregister (&grub_ofdisk_dev); + } ++ ++grub_err_t ++grub_ofdisk_get_block_size (const char *device, grub_uint32_t *block_size) ++{ ++ struct size_args_ieee1275 ++ { ++ struct grub_ieee1275_common_hdr common; ++ grub_ieee1275_cell_t method; ++ grub_ieee1275_cell_t ihandle; ++ grub_ieee1275_cell_t result; ++ grub_ieee1275_cell_t size1; ++ grub_ieee1275_cell_t size2; ++ } args_ieee1275; ++ ++ if (last_ihandle) ++ grub_ieee1275_close (last_ihandle); ++ ++ last_ihandle = 0; ++ last_devpath = NULL; ++ ++ grub_ieee1275_open (device, &last_ihandle); ++ if (! last_ihandle) ++ return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't open device"); ++ ++ INIT_IEEE1275_COMMON (&args_ieee1275.common, "call-method", 2, 2); ++ args_ieee1275.method = (grub_ieee1275_cell_t) "block-size"; ++ args_ieee1275.ihandle = last_ihandle; ++ args_ieee1275.result = 1; ++ ++ *block_size = GRUB_DISK_SECTOR_SIZE; ++ ++ if ((IEEE1275_CALL_ENTRY_FN (&args_ieee1275) == -1) || (args_ieee1275.result)) ++ grub_dprintf ("disk", "can't get block size\n"); ++ else ++ if (args_ieee1275.size1 ++ && !(args_ieee1275.size1 & (args_ieee1275.size1 - 1)) ++ && args_ieee1275.size1 >= 512 && args_ieee1275.size1 <= 16384) ++ *block_size = args_ieee1275.size1; ++ ++ return 0; ++} +diff --git a/include/grub/ieee1275/ofdisk.h b/include/grub/ieee1275/ofdisk.h +index 2f69e3f..3f58317 100644 +--- a/include/grub/ieee1275/ofdisk.h ++++ b/include/grub/ieee1275/ofdisk.h +@@ -22,4 +22,7 @@ + extern void grub_ofdisk_init (void); + extern void grub_ofdisk_fini (void); + ++extern grub_err_t grub_ofdisk_get_block_size (const char *device, ++ grub_uint32_t *block_size); ++ + #endif /* ! GRUB_INIT_HEADER */ +-- +1.8.1.4 + diff --git a/0154-Implement-new-command-cmosdump.patch b/0154-Implement-new-command-cmosdump.patch new file mode 100644 index 0000000..4e93566 --- /dev/null +++ b/0154-Implement-new-command-cmosdump.patch @@ -0,0 +1,195 @@ +From e720300246bd79d0cdb36dc9df4491557ee48663 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sun, 24 Feb 2013 19:44:17 +0100 +Subject: [PATCH 154/364] Implement new command cmosdump. + +--- + ChangeLog | 4 +++ + grub-core/Makefile.core.def | 6 ++++ + grub-core/commands/i386/cmosdump.c | 64 ++++++++++++++++++++++++++++++++++++++ + include/grub/cmos.h | 24 +++++++++++--- + include/grub/i386/cmos.h | 2 ++ + include/grub/mips/loongson/cmos.h | 2 ++ + include/grub/mips/qemu_mips/cmos.h | 2 ++ + 7 files changed, 100 insertions(+), 4 deletions(-) + create mode 100644 grub-core/commands/i386/cmosdump.c + +diff --git a/ChangeLog b/ChangeLog +index 654ebcb..2faef5b 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,7 @@ ++2013-02-24 Vladimir Serbinenko ++ ++ Implement new command cmosdump. ++ + 2013-02-19 Paulo Flabiano Smorigo + + Support Openfirmware disks with non-512B sectors. +diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def +index c006abf..4b0e6e6 100644 +--- a/grub-core/Makefile.core.def ++++ b/grub-core/Makefile.core.def +@@ -510,6 +510,12 @@ module = { + }; + + module = { ++ name = cmosdump; ++ common = commands/i386/cmosdump.c; ++ enable = cmos; ++}; ++ ++module = { + name = iorw; + common = commands/iorw.c; + enable = x86; +diff --git a/grub-core/commands/i386/cmosdump.c b/grub-core/commands/i386/cmosdump.c +new file mode 100644 +index 0000000..952d200 +--- /dev/null ++++ b/grub-core/commands/i386/cmosdump.c +@@ -0,0 +1,64 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2009,2013 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_MOD_LICENSE ("GPLv3+"); ++ ++static grub_err_t ++grub_cmd_cmosdump (struct grub_command *cmd __attribute__ ((unused)), ++ int argc __attribute__ ((unused)), char *argv[] __attribute__ ((unused))) ++{ ++ int i; ++ ++ for (i = 0; i < 256; i++) ++ { ++ grub_err_t err; ++ grub_uint8_t value; ++ if ((i & 0xf) == 0) ++ grub_printf ("%02x: ", i); ++ ++ err = grub_cmos_read (i, &value); ++ if (err) ++ return err; ++ ++ grub_printf ("%02x ", value); ++ if ((i & 0xf) == 0xf) ++ grub_printf ("\n"); ++ } ++ return GRUB_ERR_NONE; ++} ++ ++static grub_command_t cmd; ++ ++ ++GRUB_MOD_INIT(cmosdump) ++{ ++ cmd = grub_register_command ("cmosdump", grub_cmd_cmosdump, ++ 0, ++ N_("Dump CMOS contents.")); ++} ++ ++GRUB_MOD_FINI(cmosdump) ++{ ++ grub_unregister_command (cmd); ++} +diff --git a/include/grub/cmos.h b/include/grub/cmos.h +index 331513c..aa2b233 100644 +--- a/include/grub/cmos.h ++++ b/include/grub/cmos.h +@@ -61,16 +61,32 @@ grub_num_to_bcd (grub_uint8_t a) + static inline grub_err_t + grub_cmos_read (grub_uint8_t index, grub_uint8_t *val) + { +- grub_outb (index, GRUB_CMOS_ADDR_REG); +- *val = grub_inb (GRUB_CMOS_DATA_REG); ++ if (index & 0x80) ++ { ++ grub_outb (index & 0x7f, GRUB_CMOS_ADDR_REG_HI); ++ *val = grub_inb (GRUB_CMOS_DATA_REG_HI); ++ } ++ else ++ { ++ grub_outb (index & 0x7f, GRUB_CMOS_ADDR_REG); ++ *val = grub_inb (GRUB_CMOS_DATA_REG); ++ } + return GRUB_ERR_NONE; + } + + static inline grub_err_t + 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); ++ if (index & 0x80) ++ { ++ grub_outb (index & 0x7f, GRUB_CMOS_ADDR_REG_HI); ++ grub_outb (value, GRUB_CMOS_DATA_REG_HI); ++ } ++ else ++ { ++ grub_outb (index & 0x7f, GRUB_CMOS_ADDR_REG); ++ grub_outb (value, GRUB_CMOS_DATA_REG); ++ } + return GRUB_ERR_NONE; + } + #else +diff --git a/include/grub/i386/cmos.h b/include/grub/i386/cmos.h +index 8b1fa35..27a2b21 100644 +--- a/include/grub/i386/cmos.h ++++ b/include/grub/i386/cmos.h +@@ -24,5 +24,7 @@ + + #define GRUB_CMOS_ADDR_REG 0x70 + #define GRUB_CMOS_DATA_REG 0x71 ++#define GRUB_CMOS_ADDR_REG_HI 0x72 ++#define GRUB_CMOS_DATA_REG_HI 0x73 + + #endif /* GRUB_CPU_CMOS_H */ +diff --git a/include/grub/mips/loongson/cmos.h b/include/grub/mips/loongson/cmos.h +index f2a32d7..96d50f2 100644 +--- a/include/grub/mips/loongson/cmos.h ++++ b/include/grub/mips/loongson/cmos.h +@@ -24,5 +24,7 @@ + + #define GRUB_CMOS_ADDR_REG 0xbfd00070 + #define GRUB_CMOS_DATA_REG 0xbfd00071 ++#define GRUB_CMOS_ADDR_REG 0xbfd00072 ++#define GRUB_CMOS_DATA_REG 0xbfd00073 + + #endif /* GRUB_CPU_CMOS_H */ +diff --git a/include/grub/mips/qemu_mips/cmos.h b/include/grub/mips/qemu_mips/cmos.h +index 4aef40e..0759704 100644 +--- a/include/grub/mips/qemu_mips/cmos.h ++++ b/include/grub/mips/qemu_mips/cmos.h +@@ -24,5 +24,7 @@ + + #define GRUB_CMOS_ADDR_REG 0xb4000070 + #define GRUB_CMOS_DATA_REG 0xb4000071 ++#define GRUB_CMOS_ADDR_REG_HI 0xb4000072 ++#define GRUB_CMOS_DATA_REG_HI 0xb4000073 + + #endif /* GRUB_CPU_CMOS_H */ +-- +1.8.1.4 + diff --git a/0155-grub-core-normal-misc.c-grub_normal_print_device_inf.patch b/0155-grub-core-normal-misc.c-grub_normal_print_device_inf.patch new file mode 100644 index 0000000..a02358d --- /dev/null +++ b/0155-grub-core-normal-misc.c-grub_normal_print_device_inf.patch @@ -0,0 +1,54 @@ +From 464ba9e859f993a3c5fe9dc3036f4acc51c94f84 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Mon, 25 Feb 2013 10:45:19 +0100 +Subject: [PATCH 155/364] * grub-core/normal/misc.c + (grub_normal_print_device_info): Use KiB to display sizes and display + sector size. + +--- + ChangeLog | 5 +++++ + grub-core/normal/misc.c | 12 ++++++++---- + 2 files changed, 13 insertions(+), 4 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 2faef5b..ff5a558 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,8 @@ ++2013-02-25 Vladimir Serbinenko ++ ++ * grub-core/normal/misc.c (grub_normal_print_device_info): Use KiB to display ++ sizes and display sector size. ++ + 2013-02-24 Vladimir Serbinenko + + Implement new command cmosdump. +diff --git a/grub-core/normal/misc.c b/grub-core/normal/misc.c +index e1e47b5..d23de62 100644 +--- a/grub-core/normal/misc.c ++++ b/grub-core/normal/misc.c +@@ -117,13 +117,17 @@ grub_normal_print_device_info (const char *name) + grub_printf ("%s", _("No known filesystem detected")); + + if (dev->disk->partition) +- grub_printf (_(" - Partition start at %llu"), +- (unsigned long long) grub_partition_get_start (dev->disk->partition)); ++ grub_printf (_(" - Partition start at %llu%sKiB"), ++ (unsigned long long) (grub_partition_get_start (dev->disk->partition) >> 1), ++ (grub_partition_get_start (dev->disk->partition) & 1) ? ".5" : "" ); ++ else ++ grub_printf_ (N_(" - Sector size %uB"), 1 << dev->disk->log_sector_size); + if (grub_disk_get_size (dev->disk) == GRUB_DISK_SIZE_UNKNOWN) + grub_puts_ (N_(" - Total size unknown")); + else +- grub_printf (_(" - Total size %llu sectors"), +- (unsigned long long) grub_disk_get_size (dev->disk)); ++ grub_printf (_(" - Total size %llu%sKiB"), ++ (unsigned long long) (grub_disk_get_size (dev->disk) >> 1), ++ (grub_disk_get_size (dev->disk) & 1) ? ".5" : ""); + + grub_device_close (dev); + } +-- +1.8.1.4 + diff --git a/0156-Makefile.util.def-Add-partmap-msdos.c-to-common-libr.patch b/0156-Makefile.util.def-Add-partmap-msdos.c-to-common-libr.patch new file mode 100644 index 0000000..433f1eb --- /dev/null +++ b/0156-Makefile.util.def-Add-partmap-msdos.c-to-common-libr.patch @@ -0,0 +1,160 @@ +From 13d76e946f149e21c67938e7dadcbb3db9019b17 Mon Sep 17 00:00:00 2001 +From: Andrey Borzenkov +Date: Mon, 25 Feb 2013 22:11:06 +0100 +Subject: [PATCH 156/364] * Makefile.util.def: Add partmap/msdos.c to + common library. * include/grub/msdos_partition.h: Add + GRUB_PC_PARTITION_TYPE_LDM * grub-core/disk/ldm.c: Check for existence of + GRUB_PC_PARTITION_TYPE_LDM. + +--- + ChangeLog | 7 +++++++ + Makefile.util.def | 2 +- + grub-core/disk/ldm.c | 42 ++++++++++++++++++++++++++++++++++++++++-- + include/grub/msdos_partition.h | 1 + + 4 files changed, 49 insertions(+), 3 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index ff5a558..107c049 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,10 @@ ++2013-02-25 Andrey Borzenkov ++ ++ * Makefile.util.def: Add partmap/msdos.c to common library. ++ * include/grub/msdos_partition.h: Add GRUB_PC_PARTITION_TYPE_LDM ++ * grub-core/disk/ldm.c: Check for existence of ++ GRUB_PC_PARTITION_TYPE_LDM. ++ + 2013-02-25 Vladimir Serbinenko + + * grub-core/normal/misc.c (grub_normal_print_device_info): Use KiB to display +diff --git a/Makefile.util.def b/Makefile.util.def +index 3ee5e4e..1ccf390 100644 +--- a/Makefile.util.def ++++ b/Makefile.util.def +@@ -32,6 +32,7 @@ library = { + common = grub-core/disk/ldm.c; + common = grub-core/disk/diskfilter.c; + common = grub-core/partmap/gpt.c; ++ common = grub-core/partmap/msdos.c; + }; + + library = { +@@ -110,7 +111,6 @@ library = { + common = grub-core/partmap/acorn.c; + common = grub-core/partmap/amiga.c; + common = grub-core/partmap/apple.c; +- common = grub-core/partmap/msdos.c; + common = grub-core/partmap/sun.c; + common = grub-core/partmap/plan.c; + common = grub-core/partmap/dvh.c; +diff --git a/grub-core/disk/ldm.c b/grub-core/disk/ldm.c +index b92433d..a2e26b2 100644 +--- a/grub-core/disk/ldm.c ++++ b/grub-core/disk/ldm.c +@@ -22,6 +22,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -103,6 +104,37 @@ read_int (grub_uint8_t *in, grub_size_t s) + return ret; + } + ++static int ++check_ldm_partition (grub_disk_t disk __attribute__ ((unused)), const grub_partition_t p, void *data) ++{ ++ int *has_ldm = data; ++ ++ if (p->number >= 4) ++ return 1; ++ if (p->msdostype == GRUB_PC_PARTITION_TYPE_LDM) ++ { ++ *has_ldm = 1; ++ return 1; ++ } ++ return 0; ++} ++ ++static int ++msdos_has_ldm_partition (grub_disk_t dsk) ++{ ++ grub_err_t err; ++ int has_ldm = 0; ++ ++ err = grub_partition_msdos_iterate (dsk, check_ldm_partition, &has_ldm); ++ if (err) ++ { ++ grub_errno = GRUB_ERR_NONE; ++ return 0; ++ } ++ ++ return has_ldm; ++} ++ + static const grub_gpt_part_type_t ldm_type = GRUB_GPT_PARTITION_TYPE_LDM; + + /* Helper for gpt_ldm_sector. */ +@@ -760,17 +792,20 @@ grub_ldm_detect (grub_disk_t disk, + + { + int i; ++ int has_ldm = msdos_has_ldm_partition (disk); + for (i = 0; i < 3; i++) + { + grub_disk_addr_t sector = LDM_LABEL_SECTOR; + switch (i) + { + case 0: ++ if (!has_ldm) ++ continue; + sector = LDM_LABEL_SECTOR; + break; + case 1: + /* LDM is never inside a partition. */ +- if (disk->partition) ++ if (!has_ldm || disk->partition) + continue; + sector = grub_disk_get_size (disk); + if (sector == GRUB_DISK_SIZE_UNKNOWN) +@@ -871,6 +906,7 @@ int + grub_util_is_ldm (grub_disk_t disk) + { + int i; ++ int has_ldm = msdos_has_ldm_partition (disk); + for (i = 0; i < 3; i++) + { + grub_disk_addr_t sector = LDM_LABEL_SECTOR; +@@ -880,11 +916,13 @@ grub_util_is_ldm (grub_disk_t disk) + switch (i) + { + case 0: ++ if (!has_ldm) ++ continue; + sector = LDM_LABEL_SECTOR; + break; + case 1: + /* LDM is never inside a partition. */ +- if (disk->partition) ++ if (!has_ldm || disk->partition) + continue; + sector = grub_disk_get_size (disk); + if (sector == GRUB_DISK_SIZE_UNKNOWN) +diff --git a/include/grub/msdos_partition.h b/include/grub/msdos_partition.h +index 1e9b65e..92f8539 100644 +--- a/include/grub/msdos_partition.h ++++ b/include/grub/msdos_partition.h +@@ -43,6 +43,7 @@ + #define GRUB_PC_PARTITION_TYPE_FAT16_LBA 0xe + #define GRUB_PC_PARTITION_TYPE_WIN95_EXTENDED 0xf + #define GRUB_PC_PARTITION_TYPE_PLAN9 0x39 ++#define GRUB_PC_PARTITION_TYPE_LDM 0x42 + #define GRUB_PC_PARTITION_TYPE_EZD 0x55 + #define GRUB_PC_PARTITION_TYPE_MINIX 0x80 + #define GRUB_PC_PARTITION_TYPE_LINUX_MINIX 0x81 +-- +1.8.1.4 + diff --git a/0157-grub-core-normal-menu_entry.c-insert_string-fix-off-.patch b/0157-grub-core-normal-menu_entry.c-insert_string-fix-off-.patch new file mode 100644 index 0000000..235d7f3 --- /dev/null +++ b/0157-grub-core-normal-menu_entry.c-insert_string-fix-off-.patch @@ -0,0 +1,51 @@ +From c6faf0e2eb58a0f9d31c6b110cd58b4956b13465 Mon Sep 17 00:00:00 2001 +From: Andrey Borzenkov +Date: Mon, 25 Feb 2013 22:42:25 +0100 +Subject: [PATCH 157/364] * grub-core/normal/menu_entry.c + (insert_string): fix off by one access to unallocated memory. + +--- + ChangeLog | 5 +++++ + grub-core/normal/menu_entry.c | 11 ++++++----- + 2 files changed, 11 insertions(+), 5 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 107c049..cc5d5e3 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,10 @@ + 2013-02-25 Andrey Borzenkov + ++ * grub-core/normal/menu_entry.c (insert_string): fix off by one ++ access to unallocated memory. ++ ++2013-02-25 Andrey Borzenkov ++ + * Makefile.util.def: Add partmap/msdos.c to common library. + * include/grub/msdos_partition.h: Add GRUB_PC_PARTITION_TYPE_LDM + * grub-core/disk/ldm.c: Check for existence of +diff --git a/grub-core/normal/menu_entry.c b/grub-core/normal/menu_entry.c +index 7cd67f3..85f97da 100644 +--- a/grub-core/normal/menu_entry.c ++++ b/grub-core/normal/menu_entry.c +@@ -393,11 +393,12 @@ insert_string (struct screen *screen, const char *s, int update) + if (! screen->lines) + return 0; + +- /* Scroll down. */ +- grub_memmove (screen->lines + screen->line + 2, +- screen->lines + screen->line + 1, +- ((screen->num_lines - screen->line - 2) +- * sizeof (struct line))); ++ /* Shift down if not appending after the last line. */ ++ if (screen->line < screen->num_lines - 2) ++ grub_memmove (screen->lines + screen->line + 2, ++ screen->lines + screen->line + 1, ++ ((screen->num_lines - screen->line - 2) ++ * sizeof (struct line))); + + if (! init_line (screen, screen->lines + screen->line + 1)) + return 0; +-- +1.8.1.4 + diff --git a/0158-grub-core-normal-menu_entry.c-update_screen-remove.patch b/0158-grub-core-normal-menu_entry.c-update_screen-remove.patch new file mode 100644 index 0000000..a1372cd --- /dev/null +++ b/0158-grub-core-normal-menu_entry.c-update_screen-remove.patch @@ -0,0 +1,51 @@ +From 6f9a84ac7b589b9f4a65177ab64f819fdc39b09a Mon Sep 17 00:00:00 2001 +From: Andrey Borzenkov +Date: Mon, 25 Feb 2013 22:53:40 +0100 +Subject: [PATCH 158/364] * grub-core/normal/menu_entry.c + (update_screen): remove unused variable `off' which caused scroll down + arrow to be always shown. + +--- + ChangeLog | 5 +++++ + grub-core/normal/menu_entry.c | 3 +-- + 2 files changed, 6 insertions(+), 2 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index cc5d5e3..1b66689 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,10 @@ + 2013-02-25 Andrey Borzenkov + ++ * grub-core/normal/menu_entry.c (update_screen): remove ++ unused variable `off' which caused scroll down arrow to be always shown. ++ ++2013-02-25 Andrey Borzenkov ++ + * grub-core/normal/menu_entry.c (insert_string): fix off by one + access to unallocated memory. + +diff --git a/grub-core/normal/menu_entry.c b/grub-core/normal/menu_entry.c +index 85f97da..f4c8afd 100644 +--- a/grub-core/normal/menu_entry.c ++++ b/grub-core/normal/menu_entry.c +@@ -243,7 +243,6 @@ update_screen (struct screen *screen, struct per_term_screen *term_screen, + + do + { +- int off = 0; + struct grub_term_pos **pos; + + if (linep >= screen->lines + screen->num_lines) +@@ -301,7 +300,7 @@ update_screen (struct screen *screen, struct per_term_screen *term_screen, + y += get_logical_num_lines (linep, term_screen); + if (y >= term_screen->num_entries) + { +- if (off <= linep->len || i + 1 < screen->num_lines) ++ if (i + 1 < screen->num_lines) + down_flag = 1; + } + +-- +1.8.1.4 + diff --git a/0159-grub-core-disk-efi-efidisk.c-grub_efidisk_get_device.patch b/0159-grub-core-disk-efi-efidisk.c-grub_efidisk_get_device.patch new file mode 100644 index 0000000..ffae510 --- /dev/null +++ b/0159-grub-core-disk-efi-efidisk.c-grub_efidisk_get_device.patch @@ -0,0 +1,44 @@ +From 10f5d37fd38d6c87a4273e3aa4957fbf90a28a75 Mon Sep 17 00:00:00 2001 +From: Andrey Borzenkov +Date: Tue, 26 Feb 2013 22:45:00 +0100 +Subject: [PATCH 159/364] * + grub-core/disk/efi/efidisk.c(grub_efidisk_get_device_name): Fix memory + leak if device name is not found. + +--- + ChangeLog | 5 +++++ + grub-core/disk/efi/efidisk.c | 5 ++++- + 2 files changed, 9 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index 1b66689..d770758 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,8 @@ ++2013-02-26 Andrey Borzenkov ++ ++ * grub-core/disk/efi/efidisk.c(grub_efidisk_get_device_name): Fix ++ memory leak if device name is not found. ++ + 2013-02-25 Andrey Borzenkov + + * grub-core/normal/menu_entry.c (update_screen): remove +diff --git a/grub-core/disk/efi/efidisk.c b/grub-core/disk/efi/efidisk.c +index 98cd226..19c5923 100644 +--- a/grub-core/disk/efi/efidisk.c ++++ b/grub-core/disk/efi/efidisk.c +@@ -797,7 +797,10 @@ grub_efidisk_get_device_name (grub_efi_handle_t *handle) + dup_ldp->length[1] = 0; + + if (!get_diskname_from_path (dup_dp, device_name)) +- return 0; ++ { ++ grub_free (dup_dp); ++ return 0; ++ } + parent = grub_disk_open (device_name); + grub_free (dup_dp); + +-- +1.8.1.4 + diff --git a/0160-grub-core-partmap-msdos.c-grub_partition_msdos_itera.patch b/0160-grub-core-partmap-msdos.c-grub_partition_msdos_itera.patch new file mode 100644 index 0000000..3f1faea --- /dev/null +++ b/0160-grub-core-partmap-msdos.c-grub_partition_msdos_itera.patch @@ -0,0 +1,41 @@ +From 012631e24db4e27a151faede9b6750cfc87e4ca6 Mon Sep 17 00:00:00 2001 +From: Andrey Borzenkov +Date: Wed, 27 Feb 2013 10:02:39 +0100 +Subject: [PATCH 160/364] * grub-core/partmap/msdos.c + (grub_partition_msdos_iterate): Fix off by one error in enumerating + extended partitions. + +--- + ChangeLog | 5 +++++ + grub-core/partmap/msdos.c | 2 +- + 2 files changed, 6 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index d770758..c77a6a6 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,8 @@ ++2012-02-27 Andrey Borzenkov ++ ++ * grub-core/partmap/msdos.c (grub_partition_msdos_iterate): ++ Fix off by one error in enumerating extended partitions. ++ + 2013-02-26 Andrey Borzenkov + + * grub-core/disk/efi/efidisk.c(grub_efidisk_get_device_name): Fix +diff --git a/grub-core/partmap/msdos.c b/grub-core/partmap/msdos.c +index b0e11c4..0d0a6b7 100644 +--- a/grub-core/partmap/msdos.c ++++ b/grub-core/partmap/msdos.c +@@ -196,7 +196,7 @@ grub_partition_msdos_iterate (grub_disk_t disk, + if (hook (disk, &p, hook_data)) + return grub_errno; + } +- else if (p.number < 4) ++ else if (p.number < 3) + /* If this partition is a logical one, shouldn't increase the + partition number. */ + p.number++; +-- +1.8.1.4 + diff --git a/0161-Remove-nested-functions-from-disk-and-file-read-hook.patch b/0161-Remove-nested-functions-from-disk-and-file-read-hook.patch new file mode 100644 index 0000000..0c6f040 --- /dev/null +++ b/0161-Remove-nested-functions-from-disk-and-file-read-hook.patch @@ -0,0 +1,1937 @@ +From 616e091047d45c0fb5908323a456096fc57824b7 Mon Sep 17 00:00:00 2001 +From: Colin Watson +Date: Wed, 27 Feb 2013 17:19:15 +0100 +Subject: [PATCH 161/364] Remove nested functions from disk and file + read hooks. + + * include/grub/disk.h (grub_disk_read_hook_t): New type. + (struct grub_disk): Add read_hook_data member. + * include/grub/file.h (struct grub_file): Likewise. + * include/grub/fshelp.h (grub_fshelp_read_file): Add read_hook_data + argument. + + Update all callers. +--- + ChangeLog | 12 +++ + config.h.in | 6 +- + grub-core/commands/blocklist.c | 106 ++++++++++++--------- + grub-core/commands/loadenv.c | 80 +++++++++------- + grub-core/commands/testload.c | 22 +++-- + grub-core/fs/affs.c | 2 +- + grub-core/fs/bfs.c | 41 ++++---- + grub-core/fs/ext2.c | 15 +-- + grub-core/fs/fat.c | 15 +-- + grub-core/fs/fshelp.c | 10 +- + grub-core/fs/hfs.c | 7 +- + grub-core/fs/hfsplus.c | 23 ++--- + grub-core/fs/iso9660.c | 1 + + grub-core/fs/jfs.c | 9 +- + grub-core/fs/minix.c | 17 ++-- + grub-core/fs/nilfs2.c | 17 ++-- + grub-core/fs/ntfs.c | 48 ++++------ + grub-core/fs/ntfscomp.c | 1 + + grub-core/fs/reiserfs.c | 15 ++- + grub-core/fs/romfs.c | 1 + + grub-core/fs/sfs.c | 9 +- + grub-core/fs/udf.c | 22 ++--- + grub-core/fs/ufs.c | 17 ++-- + grub-core/fs/xfs.c | 15 +-- + grub-core/kern/disk.c | 2 +- + include/grub/disk.h | 12 ++- + include/grub/file.h | 7 +- + include/grub/fshelp.h | 6 +- + util/grub-setup.c | 210 +++++++++++++++++++++-------------------- + 29 files changed, 406 insertions(+), 342 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index c77a6a6..dbecfef 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,15 @@ ++2013-02-27 Colin Watson ++ ++ Remove nested functions from disk and file read hooks. ++ ++ * include/grub/disk.h (grub_disk_read_hook_t): New type. ++ (struct grub_disk): Add read_hook_data member. ++ * include/grub/file.h (struct grub_file): Likewise. ++ * include/grub/fshelp.h (grub_fshelp_read_file): Add read_hook_data ++ argument. ++ ++ Update all callers. ++ + 2012-02-27 Andrey Borzenkov + + * grub-core/partmap/msdos.c (grub_partition_msdos_iterate): +diff --git a/config.h.in b/config.h.in +index a7eaf19..91afd98 100644 +--- a/config.h.in ++++ b/config.h.in +@@ -5,6 +5,10 @@ + #if defined(__PPC__) && !defined(__powerpc__) + #define __powerpc__ 1 + #endif ++ ++/* Define to 1 to enable disk cache statistics. */ ++#define DISK_CACHE_STATS @DISK_CACHE_STATS@ ++ + #if defined (GRUB_UTIL) || !defined (GRUB_MACHINE) + #include + #define NESTED_FUNC_ATTR +@@ -39,8 +43,6 @@ + #define NEED_ENABLE_EXECUTE_STACK @NEED_ENABLE_EXECUTE_STACK@ + /* Define to 1 if GCC generates calls to __register_frame_info(). */ + #define NEED_REGISTER_FRAME_INFO @NEED_REGISTER_FRAME_INFO@ +-/* Define to 1 to enable disk cache statistics. */ +-#define DISK_CACHE_STATS @DISK_CACHE_STATS@ + + #define GRUB_TARGET_CPU "@GRUB_TARGET_CPU@" + #define GRUB_PLATFORM "@GRUB_PLATFORM@" +diff --git a/grub-core/commands/blocklist.c b/grub-core/commands/blocklist.c +index 164a6fe..c531e44 100644 +--- a/grub-core/commands/blocklist.c ++++ b/grub-core/commands/blocklist.c +@@ -28,58 +28,71 @@ + + GRUB_MOD_LICENSE ("GPLv3+"); + +-static grub_err_t +-grub_cmd_blocklist (grub_command_t cmd __attribute__ ((unused)), +- int argc, char **args) ++/* Context for grub_cmd_blocklist. */ ++struct blocklist_ctx + { +- grub_file_t file; +- char buf[GRUB_DISK_SECTOR_SIZE]; +- unsigned long start_sector = 0; +- unsigned num_sectors = 0; +- int num_entries = 0; +- grub_disk_addr_t part_start = 0; +- auto void NESTED_FUNC_ATTR read_blocklist (grub_disk_addr_t sector, unsigned offset, +- unsigned length); +- auto void NESTED_FUNC_ATTR print_blocklist (grub_disk_addr_t sector, unsigned num, +- unsigned offset, unsigned length); +- +- void NESTED_FUNC_ATTR read_blocklist (grub_disk_addr_t sector, unsigned offset, +- unsigned length) ++ unsigned long start_sector; ++ unsigned num_sectors; ++ int num_entries; ++ grub_disk_addr_t part_start; ++}; ++ ++/* Helper for grub_cmd_blocklist. */ ++static void ++print_blocklist (grub_disk_addr_t sector, unsigned num, ++ unsigned offset, unsigned length, struct blocklist_ctx *ctx) ++{ ++ if (ctx->num_entries++) ++ grub_printf (","); ++ ++ grub_printf ("%llu", (unsigned long long) (sector - ctx->part_start)); ++ if (num > 0) ++ grub_printf ("+%u", num); ++ if (offset != 0 || length != 0) ++ grub_printf ("[%u-%u]", offset, offset + length); ++} ++ ++/* Helper for grub_cmd_blocklist. */ ++static void ++read_blocklist (grub_disk_addr_t sector, unsigned offset, unsigned length, ++ void *data) ++{ ++ struct blocklist_ctx *ctx = data; ++ ++ if (ctx->num_sectors > 0) + { +- if (num_sectors > 0) ++ if (ctx->start_sector + ctx->num_sectors == sector ++ && offset == 0 && length == GRUB_DISK_SECTOR_SIZE) + { +- if (start_sector + num_sectors == sector +- && offset == 0 && length == GRUB_DISK_SECTOR_SIZE) +- { +- num_sectors++; +- return; +- } +- +- print_blocklist (start_sector, num_sectors, 0, 0); +- num_sectors = 0; ++ ctx->num_sectors++; ++ return; + } + +- if (offset == 0 && length == GRUB_DISK_SECTOR_SIZE) +- { +- start_sector = sector; +- num_sectors++; +- } +- else +- print_blocklist (sector, 0, offset, length); ++ print_blocklist (ctx->start_sector, ctx->num_sectors, 0, 0, ctx); ++ ctx->num_sectors = 0; + } + +- void NESTED_FUNC_ATTR print_blocklist (grub_disk_addr_t sector, unsigned num, +- unsigned offset, unsigned length) ++ if (offset == 0 && length == GRUB_DISK_SECTOR_SIZE) + { +- if (num_entries++) +- grub_printf (","); +- +- grub_printf ("%llu", (unsigned long long) (sector - part_start)); +- if (num > 0) +- grub_printf ("+%u", num); +- if (offset != 0 || length != 0) +- grub_printf ("[%u-%u]", offset, offset + length); ++ ctx->start_sector = sector; ++ ctx->num_sectors++; + } ++ else ++ print_blocklist (sector, 0, offset, length, ctx); ++} ++ ++static grub_err_t ++grub_cmd_blocklist (grub_command_t cmd __attribute__ ((unused)), ++ int argc, char **args) ++{ ++ grub_file_t file; ++ char buf[GRUB_DISK_SECTOR_SIZE]; ++ struct blocklist_ctx ctx = { ++ .start_sector = 0, ++ .num_sectors = 0, ++ .num_entries = 0, ++ .part_start = 0 ++ }; + + if (argc < 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); +@@ -93,15 +106,16 @@ grub_cmd_blocklist (grub_command_t cmd __attribute__ ((unused)), + return grub_error (GRUB_ERR_BAD_DEVICE, + "this command is available only for disk devices"); + +- part_start = grub_partition_get_start (file->device->disk->partition); ++ ctx.part_start = grub_partition_get_start (file->device->disk->partition); + + file->read_hook = read_blocklist; ++ file->read_hook_data = &ctx; + + while (grub_file_read (file, buf, sizeof (buf)) > 0) + ; + +- if (num_sectors > 0) +- print_blocklist (start_sector, num_sectors, 0, 0); ++ if (ctx.num_sectors > 0) ++ print_blocklist (ctx.start_sector, ctx.num_sectors, 0, 0, &ctx); + + grub_file_close (file); + +diff --git a/grub-core/commands/loadenv.c b/grub-core/commands/loadenv.c +index 9a35550..4b94173 100644 +--- a/grub-core/commands/loadenv.c ++++ b/grub-core/commands/loadenv.c +@@ -284,44 +284,51 @@ write_blocklists (grub_envblk_t envblk, struct blocklist *blocklists, + return 1; + } + ++/* Context for grub_cmd_save_env. */ ++struct grub_cmd_save_env_ctx ++{ ++ struct blocklist *head, *tail; ++}; ++ ++/* Store blocklists in a linked list. */ ++static void ++save_env_read_hook (grub_disk_addr_t sector, unsigned offset, unsigned length, ++ void *data) ++{ ++ struct grub_cmd_save_env_ctx *ctx = data; ++ struct blocklist *block; ++ ++ if (offset + length > GRUB_DISK_SECTOR_SIZE) ++ /* Seemingly a bug. */ ++ return; ++ ++ block = grub_malloc (sizeof (*block)); ++ if (! block) ++ return; ++ ++ block->sector = sector; ++ block->offset = offset; ++ block->length = length; ++ ++ /* Slightly complicated, because the list should be FIFO. */ ++ block->next = 0; ++ if (ctx->tail) ++ ctx->tail->next = block; ++ ctx->tail = block; ++ if (! ctx->head) ++ ctx->head = block; ++} ++ + static grub_err_t + grub_cmd_save_env (grub_extcmd_context_t ctxt, int argc, char **args) + { + struct grub_arg_list *state = ctxt->state; + grub_file_t file; + grub_envblk_t envblk; +- struct blocklist *head = 0; +- struct blocklist *tail = 0; +- +- /* Store blocklists in a linked list. */ +- auto void NESTED_FUNC_ATTR read_hook (grub_disk_addr_t sector, +- unsigned offset, +- unsigned length); +- void NESTED_FUNC_ATTR read_hook (grub_disk_addr_t sector, +- unsigned offset, unsigned length) +- { +- struct blocklist *block; +- +- if (offset + length > GRUB_DISK_SECTOR_SIZE) +- /* Seemingly a bug. */ +- return; +- +- block = grub_malloc (sizeof (*block)); +- if (! block) +- return; +- +- block->sector = sector; +- block->offset = offset; +- block->length = length; +- +- /* Slightly complicated, because the list should be FIFO. */ +- block->next = 0; +- if (tail) +- tail->next = block; +- tail = block; +- if (! head) +- head = block; +- } ++ struct grub_cmd_save_env_ctx ctx = { ++ .head = 0, ++ .tail = 0 ++ }; + + if (! argc) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "no variable is specified"); +@@ -336,13 +343,14 @@ grub_cmd_save_env (grub_extcmd_context_t ctxt, int argc, char **args) + return grub_error (GRUB_ERR_BAD_DEVICE, "disk device required"); + } + +- file->read_hook = read_hook; ++ file->read_hook = save_env_read_hook; ++ file->read_hook_data = &ctx; + envblk = read_envblk_file (file); + file->read_hook = 0; + if (! envblk) + goto fail; + +- if (check_blocklists (envblk, head, file)) ++ if (check_blocklists (envblk, ctx.head, file)) + goto fail; + + while (argc) +@@ -363,12 +371,12 @@ grub_cmd_save_env (grub_extcmd_context_t ctxt, int argc, char **args) + args++; + } + +- write_blocklists (envblk, head, file); ++ write_blocklists (envblk, ctx.head, file); + + fail: + if (envblk) + grub_envblk_close (envblk); +- free_blocklists (head); ++ free_blocklists (ctx.head); + grub_file_close (file); + return grub_errno; + } +diff --git a/grub-core/commands/testload.c b/grub-core/commands/testload.c +index a1bf775..4d0280a 100644 +--- a/grub-core/commands/testload.c ++++ b/grub-core/commands/testload.c +@@ -31,6 +31,17 @@ + + GRUB_MOD_LICENSE ("GPLv3+"); + ++/* Helper for grub_cmd_testload. */ ++static void ++read_progress (grub_disk_addr_t sector __attribute__ ((unused)), ++ unsigned offset __attribute__ ((unused)), ++ unsigned len __attribute__ ((unused)), ++ void *data __attribute__ ((unused))) ++{ ++ grub_xputs ("."); ++ grub_refresh (); ++} ++ + static grub_err_t + grub_cmd_testload (struct grub_command *cmd __attribute__ ((unused)), + int argc, char *argv[]) +@@ -39,15 +50,6 @@ grub_cmd_testload (struct grub_command *cmd __attribute__ ((unused)), + char *buf; + grub_size_t size; + grub_off_t pos; +- auto void NESTED_FUNC_ATTR read_func (grub_disk_addr_t sector, unsigned offset, unsigned len); +- +- void NESTED_FUNC_ATTR read_func (grub_disk_addr_t sector __attribute__ ((unused)), +- unsigned offset __attribute__ ((unused)), +- unsigned len __attribute__ ((unused))) +- { +- grub_xputs ("."); +- grub_refresh (); +- } + + if (argc < 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); +@@ -68,7 +70,7 @@ grub_cmd_testload (struct grub_command *cmd __attribute__ ((unused)), + goto fail; + + grub_printf ("Reading %s sequentially", argv[0]); +- file->read_hook = read_func; ++ file->read_hook = read_progress; + if (grub_file_read (file, buf, size) != (grub_ssize_t) size) + goto fail; + grub_printf (" Done.\n"); +diff --git a/grub-core/fs/affs.c b/grub-core/fs/affs.c +index 6c49e5d..726704e 100644 +--- a/grub-core/fs/affs.c ++++ b/grub-core/fs/affs.c +@@ -531,7 +531,7 @@ grub_affs_read (grub_file_t file, char *buf, grub_size_t len) + (struct grub_affs_data *) file->data; + + return grub_fshelp_read_file (data->diropen.data->disk, &data->diropen, +- file->read_hook, ++ file->read_hook, file->read_hook_data, + file->offset, len, buf, grub_affs_read_block, + grub_be_to_cpu32 (data->diropen.di.size), + data->log_blocksize, 0); +diff --git a/grub-core/fs/bfs.c b/grub-core/fs/bfs.c +index fa2fc3f..f2e39d3 100644 +--- a/grub-core/fs/bfs.c ++++ b/grub-core/fs/bfs.c +@@ -217,9 +217,7 @@ read_bfs_file (grub_disk_t disk, + const struct grub_bfs_superblock *sb, + const struct grub_bfs_inode *ino, + grub_off_t off, void *buf, grub_size_t len, +- void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, +- unsigned offset, +- unsigned length)) ++ grub_disk_read_hook_t read_hook, void *read_hook_data) + { + if (len == 0) + return GRUB_ERR_NONE; +@@ -245,6 +243,7 @@ read_bfs_file (grub_disk_t disk, + if (read_size > len) + read_size = len; + disk->read_hook = read_hook; ++ disk->read_hook_data = read_hook_data; + err = read_extent (disk, sb, &ino->direct[i], 0, off - pos, + buf, read_size); + disk->read_hook = 0; +@@ -290,6 +289,7 @@ read_bfs_file (grub_disk_t disk, + if (read_size > len) + read_size = len; + disk->read_hook = read_hook; ++ disk->read_hook_data = read_hook_data; + err = read_extent (disk, sb, &entries[i], 0, off - pos, + buf, read_size); + disk->read_hook = 0; +@@ -401,6 +401,7 @@ read_bfs_file (grub_disk_t disk, + if (read_size > len) + read_size = len; + disk->read_hook = read_hook; ++ disk->read_hook_data = read_hook_data; + err = read_extent (disk, sb, &l2_entries[l2n], 0, boff, + buf, read_size); + disk->read_hook = 0; +@@ -431,7 +432,7 @@ iterate_in_b_tree (grub_disk_t disk, + int level; + grub_uint64_t node_off; + +- err = read_bfs_file (disk, sb, ino, 0, &head, sizeof (head), 0); ++ err = read_bfs_file (disk, sb, ino, 0, &head, sizeof (head), 0, 0); + if (err) + return 0; + node_off = grub_bfs_to_cpu64 (head.root); +@@ -441,7 +442,8 @@ iterate_in_b_tree (grub_disk_t disk, + { + struct grub_bfs_btree_node node; + grub_uint64_t key_value; +- err = read_bfs_file (disk, sb, ino, node_off, &node, sizeof (node), 0); ++ err = read_bfs_file (disk, sb, ino, node_off, &node, sizeof (node), ++ 0, 0); + if (err) + return 0; + err = read_bfs_file (disk, sb, ino, node_off +@@ -451,7 +453,7 @@ iterate_in_b_tree (grub_disk_t disk, + BTREE_ALIGN) + + grub_bfs_to_cpu_treehead (node.count_keys) * + sizeof (grub_uint16_t), &key_value, +- sizeof (grub_uint64_t), 0); ++ sizeof (grub_uint64_t), 0, 0); + if (err) + return 0; + +@@ -461,7 +463,8 @@ iterate_in_b_tree (grub_disk_t disk, + while (1) + { + struct grub_bfs_btree_node node; +- err = read_bfs_file (disk, sb, ino, node_off, &node, sizeof (node), 0); ++ err = read_bfs_file (disk, sb, ino, node_off, &node, sizeof (node), ++ 0, 0); + if (err) + return 0; + { +@@ -473,7 +476,7 @@ iterate_in_b_tree (grub_disk_t disk, + + err = + read_bfs_file (disk, sb, ino, node_off + sizeof (node), key_data, +- grub_bfs_to_cpu_treehead (node.total_key_len), 0); ++ grub_bfs_to_cpu_treehead (node.total_key_len), 0, 0); + if (err) + return 0; + key_data[grub_bfs_to_cpu_treehead (node.total_key_len)] = 0; +@@ -483,7 +486,7 @@ iterate_in_b_tree (grub_disk_t disk, + (node.total_key_len), BTREE_ALIGN), + keylen_idx, + grub_bfs_to_cpu_treehead (node.count_keys) * +- sizeof (grub_uint16_t), 0); ++ sizeof (grub_uint16_t), 0, 0); + if (err) + return 0; + err = read_bfs_file (disk, sb, ino, node_off +@@ -494,7 +497,7 @@ iterate_in_b_tree (grub_disk_t disk, + grub_bfs_to_cpu_treehead (node.count_keys) * + sizeof (grub_uint16_t), key_values, + grub_bfs_to_cpu_treehead (node.count_keys) * +- sizeof (grub_uint64_t), 0); ++ sizeof (grub_uint64_t), 0, 0); + if (err) + return 0; + +@@ -556,7 +559,7 @@ find_in_b_tree (grub_disk_t disk, + int level; + grub_uint64_t node_off; + +- err = read_bfs_file (disk, sb, ino, 0, &head, sizeof (head), 0); ++ err = read_bfs_file (disk, sb, ino, 0, &head, sizeof (head), 0, 0); + if (err) + return err; + node_off = grub_bfs_to_cpu64 (head.root); +@@ -565,7 +568,8 @@ find_in_b_tree (grub_disk_t disk, + while (1) + { + struct grub_bfs_btree_node node; +- err = read_bfs_file (disk, sb, ino, node_off, &node, sizeof (node), 0); ++ err = read_bfs_file (disk, sb, ino, node_off, &node, sizeof (node), ++ 0, 0); + if (err) + return err; + if (node.count_keys == 0) +@@ -578,7 +582,7 @@ find_in_b_tree (grub_disk_t disk, + unsigned i; + err = + read_bfs_file (disk, sb, ino, node_off + sizeof (node), key_data, +- grub_bfs_to_cpu_treehead (node.total_key_len), 0); ++ grub_bfs_to_cpu_treehead (node.total_key_len), 0, 0); + if (err) + return err; + key_data[grub_bfs_to_cpu_treehead (node.total_key_len)] = 0; +@@ -589,7 +593,7 @@ find_in_b_tree (grub_disk_t disk, + total_key_len), + BTREE_ALIGN), keylen_idx, + grub_bfs_to_cpu_treehead (node.count_keys) * +- sizeof (grub_uint16_t), 0); ++ sizeof (grub_uint16_t), 0, 0); + if (err) + return err; + err = read_bfs_file (disk, sb, ino, node_off +@@ -600,7 +604,7 @@ find_in_b_tree (grub_disk_t disk, + grub_bfs_to_cpu_treehead (node.count_keys) * + sizeof (grub_uint16_t), key_values, + grub_bfs_to_cpu_treehead (node.count_keys) * +- sizeof (grub_uint64_t), 0); ++ sizeof (grub_uint64_t), 0, 0); + if (err) + return err; + +@@ -771,7 +775,7 @@ find_file (const char *path, grub_disk_t disk, + return grub_errno; + } + grub_free (old_alloc); +- err = read_bfs_file (disk, sb, ino, 0, alloc, symsize, 0); ++ err = read_bfs_file (disk, sb, ino, 0, alloc, symsize, 0, 0); + if (err) + { + grub_free (alloc); +@@ -974,7 +978,8 @@ grub_bfs_read (grub_file_t file, char *buf, grub_size_t len) + struct grub_bfs_data *data = file->data; + + err = read_bfs_file (file->device->disk, &data->sb, +- data->ino, file->offset, buf, len, file->read_hook); ++ data->ino, file->offset, buf, len, ++ file->read_hook, file->read_hook_data); + if (err) + return -1; + return len; +@@ -1056,7 +1061,7 @@ read_bfs_attr (grub_disk_t disk, + if (read > len) + read = len; + +- err = read_bfs_file (disk, sb, &ino2.ino, 0, buf, read, 0); ++ err = read_bfs_file (disk, sb, &ino2.ino, 0, buf, read, 0, 0); + if (err) + return -1; + return read; +diff --git a/grub-core/fs/ext2.c b/grub-core/fs/ext2.c +index 0ebde35..18429ac 100644 +--- a/grub-core/fs/ext2.c ++++ b/grub-core/fs/ext2.c +@@ -525,11 +525,11 @@ grub_ext2_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) + POS. Return the amount of read bytes in READ. */ + static grub_ssize_t + grub_ext2_read_file (grub_fshelp_node_t node, +- void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, +- unsigned offset, unsigned length), ++ grub_disk_read_hook_t read_hook, void *read_hook_data, + grub_off_t pos, grub_size_t len, char *buf) + { +- return grub_fshelp_read_file (node->data->disk, node, read_hook, ++ return grub_fshelp_read_file (node->data->disk, node, ++ read_hook, read_hook_data, + pos, len, buf, grub_ext2_read_block, + grub_cpu_to_le32 (node->inode.size) + | (((grub_off_t) grub_cpu_to_le32 (node->inode.size_high)) << 32), +@@ -676,7 +676,7 @@ grub_ext2_read_symlink (grub_fshelp_node_t node) + grub_le_to_cpu32 (diro->inode.size)); + else + { +- grub_ext2_read_file (diro, 0, 0, ++ grub_ext2_read_file (diro, 0, 0, 0, + grub_le_to_cpu32 (diro->inode.size), + symlink); + if (grub_errno) +@@ -709,7 +709,7 @@ grub_ext2_iterate_dir (grub_fshelp_node_t dir, + { + struct ext2_dirent dirent; + +- grub_ext2_read_file (diro, 0, fpos, sizeof (struct ext2_dirent), ++ grub_ext2_read_file (diro, 0, 0, fpos, sizeof (struct ext2_dirent), + (char *) &dirent); + if (grub_errno) + return 0; +@@ -723,7 +723,7 @@ grub_ext2_iterate_dir (grub_fshelp_node_t dir, + struct grub_fshelp_node *fdiro; + enum grub_fshelp_filetype type = GRUB_FSHELP_UNKNOWN; + +- grub_ext2_read_file (diro, 0, fpos + sizeof (struct ext2_dirent), ++ grub_ext2_read_file (diro, 0, 0, fpos + sizeof (struct ext2_dirent), + dirent.namelen, filename); + if (grub_errno) + return 0; +@@ -850,7 +850,8 @@ grub_ext2_read (grub_file_t file, char *buf, grub_size_t len) + { + struct grub_ext2_data *data = (struct grub_ext2_data *) file->data; + +- return grub_ext2_read_file (&data->diropen, file->read_hook, ++ return grub_ext2_read_file (&data->diropen, ++ file->read_hook, file->read_hook_data, + file->offset, len, buf); + } + +diff --git a/grub-core/fs/fat.c b/grub-core/fs/fat.c +index 7664153..db28158 100644 +--- a/grub-core/fs/fat.c ++++ b/grub-core/fs/fat.c +@@ -454,8 +454,7 @@ grub_fat_mount (grub_disk_t disk) + + static grub_ssize_t + grub_fat_read_data (grub_disk_t disk, struct grub_fat_data *data, +- void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, +- unsigned offset, unsigned length), ++ grub_disk_read_hook_t read_hook, void *read_hook_data, + grub_off_t offset, grub_size_t len, char *buf) + { + grub_size_t size; +@@ -561,6 +560,7 @@ grub_fat_read_data (grub_disk_t disk, struct grub_fat_data *data, + size = len; + + disk->read_hook = read_hook; ++ disk->read_hook_data = read_hook_data; + grub_disk_read (disk, sector, offset, size, buf); + disk->read_hook = 0; + if (grub_errno) +@@ -630,7 +630,7 @@ grub_fat_iterate_dir_next (grub_disk_t disk, struct grub_fat_data *data, + + ctxt->offset += sizeof (dir); + +- if (grub_fat_read_data (disk, data, 0, ctxt->offset, sizeof (dir), ++ if (grub_fat_read_data (disk, data, 0, 0, ctxt->offset, sizeof (dir), + (char *) &dir) + != sizeof (dir)) + break; +@@ -652,7 +652,7 @@ grub_fat_iterate_dir_next (grub_disk_t disk, struct grub_fat_data *data, + { + struct grub_fat_dir_entry sec; + ctxt->offset += sizeof (sec); +- if (grub_fat_read_data (disk, data, 0, ++ if (grub_fat_read_data (disk, data, 0, 0, + ctxt->offset, sizeof (sec), (char *) &sec) + != sizeof (sec)) + break; +@@ -729,7 +729,7 @@ grub_fat_iterate_dir_next (grub_disk_t disk, struct grub_fat_data *data, + ctxt->offset += sizeof (ctxt->dir); + + /* Read a directory entry. */ +- if (grub_fat_read_data (disk, data, 0, ++ if (grub_fat_read_data (disk, data, 0, 0, + ctxt->offset, sizeof (ctxt->dir), + (char *) &ctxt->dir) + != sizeof (ctxt->dir) || ctxt->dir.name[0] == 0) +@@ -1031,7 +1031,8 @@ grub_fat_open (grub_file_t file, const char *name) + static grub_ssize_t + grub_fat_read (grub_file_t file, char *buf, grub_size_t len) + { +- return grub_fat_read_data (file->device->disk, file->data, file->read_hook, ++ return grub_fat_read_data (file->device->disk, file->data, ++ file->read_hook, file->read_hook_data, + file->offset, len, buf); + } + +@@ -1064,7 +1065,7 @@ grub_fat_label (grub_device_t device, char **label) + { + offset += sizeof (dir); + +- if (grub_fat_read_data (disk, data, 0, ++ if (grub_fat_read_data (disk, data, 0, 0, + offset, sizeof (dir), (char *) &dir) + != sizeof (dir)) + break; +diff --git a/grub-core/fs/fshelp.c b/grub-core/fs/fshelp.c +index 11a1259..d56e63f 100644 +--- a/grub-core/fs/fshelp.c ++++ b/grub-core/fs/fshelp.c +@@ -248,14 +248,13 @@ grub_fshelp_find_file (const char *path, grub_fshelp_node_t rootnode, + + /* Read LEN bytes from the file NODE on disk DISK into the buffer BUF, + beginning with the block POS. READ_HOOK should be set before +- reading a block from the file. GET_BLOCK is used to translate file +- blocks to disk blocks. The file is FILESIZE bytes big and the ++ reading a block from the file. READ_HOOK_DATA is passed through as ++ the DATA argument to READ_HOOK. GET_BLOCK is used to translate ++ file blocks to disk blocks. The file is FILESIZE bytes big and the + blocks have a size of LOG2BLOCKSIZE (in log2). */ + grub_ssize_t + grub_fshelp_read_file (grub_disk_t disk, grub_fshelp_node_t node, +- void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, +- unsigned offset, +- unsigned length), ++ grub_disk_read_hook_t read_hook, void *read_hook_data, + grub_off_t pos, grub_size_t len, char *buf, + grub_disk_addr_t (*get_block) (grub_fshelp_node_t node, + grub_disk_addr_t block), +@@ -307,6 +306,7 @@ grub_fshelp_read_file (grub_disk_t disk, grub_fshelp_node_t node, + if (blknr) + { + disk->read_hook = read_hook; ++ disk->read_hook_data = read_hook_data; + + grub_disk_read (disk, blknr + blocks_start, skipfirst, + blockend, buf); +diff --git a/grub-core/fs/hfs.c b/grub-core/fs/hfs.c +index 9ed3330..4b2b5aa 100644 +--- a/grub-core/fs/hfs.c ++++ b/grub-core/fs/hfs.c +@@ -243,8 +243,7 @@ grub_hfs_block (struct grub_hfs_data *data, grub_hfs_datarecord_t dat, + POS. Return the amount of read bytes in READ. */ + static grub_ssize_t + grub_hfs_read_file (struct grub_hfs_data *data, +- void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, +- unsigned offset, unsigned length), ++ grub_disk_read_hook_t read_hook, void *read_hook_data, + grub_off_t pos, grub_size_t len, char *buf) + { + grub_off_t i; +@@ -289,6 +288,7 @@ grub_hfs_read_file (struct grub_hfs_data *data, + if (blknr) + { + data->disk->read_hook = read_hook; ++ data->disk->read_hook_data = read_hook_data; + grub_disk_read (data->disk, blknr, skipfirst, + blockend, buf); + data->disk->read_hook = 0; +@@ -1269,7 +1269,8 @@ grub_hfs_read (grub_file_t file, char *buf, grub_size_t len) + struct grub_hfs_data *data = + (struct grub_hfs_data *) file->data; + +- return grub_hfs_read_file (data, file->read_hook, file->offset, len, buf); ++ return grub_hfs_read_file (data, file->read_hook, file->read_hook_data, ++ file->offset, len, buf); + } + + +diff --git a/grub-core/fs/hfsplus.c b/grub-core/fs/hfsplus.c +index dcca581..29a3a94 100644 +--- a/grub-core/fs/hfsplus.c ++++ b/grub-core/fs/hfsplus.c +@@ -375,11 +375,11 @@ grub_hfsplus_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) + POS. Return the amount of read bytes in READ. */ + static grub_ssize_t + grub_hfsplus_read_file (grub_fshelp_node_t node, +- void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, +- unsigned offset, unsigned length), ++ grub_disk_read_hook_t read_hook, void *read_hook_data, + grub_off_t pos, grub_size_t len, char *buf) + { +- return grub_fshelp_read_file (node->data->disk, node, read_hook, ++ return grub_fshelp_read_file (node->data->disk, node, ++ read_hook, read_hook_data, + pos, len, buf, grub_hfsplus_read_block, + node->size, + node->data->log2blksize - GRUB_DISK_SECTOR_BITS, +@@ -477,7 +477,7 @@ grub_hfsplus_mount (grub_disk_t disk) + grub_be_to_cpu64 (data->volheader.extents_file.size); + + /* Read the essential information about the trees. */ +- if (grub_hfsplus_read_file (&data->catalog_tree.file, 0, ++ if (grub_hfsplus_read_file (&data->catalog_tree.file, 0, 0, + sizeof (struct grub_hfsplus_btnode), + sizeof (header), (char *) &header) <= 0) + goto fail; +@@ -487,14 +487,14 @@ grub_hfsplus_mount (grub_disk_t disk) + data->case_sensitive = ((magic == GRUB_HFSPLUSX_MAGIC) && + (header.key_compare == GRUB_HFSPLUSX_BINARYCOMPARE)); + +- if (grub_hfsplus_read_file (&data->extoverflow_tree.file, 0, ++ if (grub_hfsplus_read_file (&data->extoverflow_tree.file, 0, 0, + sizeof (struct grub_hfsplus_btnode), + sizeof (header), (char *) &header) <= 0) + goto fail; + + data->extoverflow_tree.root = grub_be_to_cpu32 (header.root); + +- if (grub_hfsplus_read_file (&data->extoverflow_tree.file, 0, 0, ++ if (grub_hfsplus_read_file (&data->extoverflow_tree.file, 0, 0, 0, + sizeof (node), (char *) &node) <= 0) + goto fail; + +@@ -605,7 +605,7 @@ grub_hfsplus_read_symlink (grub_fshelp_node_t node) + if (!symlink) + return 0; + +- numread = grub_hfsplus_read_file (node, 0, 0, node->size, symlink); ++ numread = grub_hfsplus_read_file (node, 0, 0, 0, node->size, symlink); + if (numread != (grub_ssize_t) node->size) + { + grub_free (symlink); +@@ -649,7 +649,7 @@ grub_hfsplus_btree_iterate_node (struct grub_hfsplus_btree *btree, + saved_node = first_node->next; + node_count++; + +- if (grub_hfsplus_read_file (&btree->file, 0, ++ if (grub_hfsplus_read_file (&btree->file, 0, 0, + (((grub_disk_addr_t) + grub_be_to_cpu32 (first_node->next)) + * btree->nodesize), +@@ -702,7 +702,7 @@ grub_hfsplus_btree_search (struct grub_hfsplus_btree *btree, + node_count++; + + /* Read a node. */ +- if (grub_hfsplus_read_file (&btree->file, 0, ++ if (grub_hfsplus_read_file (&btree->file, 0, 0, + (grub_disk_addr_t) currnode + * (grub_disk_addr_t) btree->nodesize, + btree->nodesize, (char *) node) <= 0) +@@ -971,8 +971,9 @@ grub_hfsplus_read (grub_file_t file, char *buf, grub_size_t len) + struct grub_hfsplus_data *data = + (struct grub_hfsplus_data *) file->data; + +- return grub_hfsplus_read_file (&data->opened_file, file->read_hook, +- file->offset, len, buf); ++ return grub_hfsplus_read_file (&data->opened_file, ++ file->read_hook, file->read_hook_data, ++ file->offset, len, buf); + } + + /* Context for grub_hfsplus_dir. */ +diff --git a/grub-core/fs/iso9660.c b/grub-core/fs/iso9660.c +index e37553d..19471e8 100644 +--- a/grub-core/fs/iso9660.c ++++ b/grub-core/fs/iso9660.c +@@ -961,6 +961,7 @@ grub_iso9660_read (grub_file_t file, char *buf, grub_size_t len) + + /* XXX: The file is stored in as a single extent. */ + data->disk->read_hook = file->read_hook; ++ data->disk->read_hook_data = file->read_hook_data; + read_node (data->node, file->offset, len, buf); + data->disk->read_hook = NULL; + +diff --git a/grub-core/fs/jfs.c b/grub-core/fs/jfs.c +index 7c17192..88b21ad 100644 +--- a/grub-core/fs/jfs.c ++++ b/grub-core/fs/jfs.c +@@ -577,8 +577,7 @@ grub_jfs_getent (struct grub_jfs_diropen *diro) + POS. Return the amount of read bytes in READ. */ + static grub_ssize_t + grub_jfs_read_file (struct grub_jfs_data *data, +- void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, +- unsigned offset, unsigned length), ++ grub_disk_read_hook_t read_hook, void *read_hook_data, + grub_off_t pos, grub_size_t len, char *buf) + { + grub_off_t i; +@@ -616,6 +615,7 @@ grub_jfs_read_file (struct grub_jfs_data *data, + } + + data->disk->read_hook = read_hook; ++ data->disk->read_hook_data = read_hook_data; + grub_disk_read (data->disk, + blknr << (grub_le_to_cpu16 (data->sblock.log2_blksz) + - GRUB_DISK_SECTOR_BITS), +@@ -782,7 +782,7 @@ grub_jfs_lookup_symlink (struct grub_jfs_data *data, grub_uint32_t ino) + + if (size <= sizeof (data->currinode.symlink.path)) + grub_strncpy (symlink, (char *) (data->currinode.symlink.path), size); +- else if (grub_jfs_read_file (data, 0, 0, size, symlink) < 0) ++ else if (grub_jfs_read_file (data, 0, 0, 0, size, symlink) < 0) + return grub_errno; + + symlink[size] = '\0'; +@@ -894,7 +894,8 @@ grub_jfs_read (grub_file_t file, char *buf, grub_size_t len) + struct grub_jfs_data *data = + (struct grub_jfs_data *) file->data; + +- return grub_jfs_read_file (data, file->read_hook, file->offset, len, buf); ++ return grub_jfs_read_file (data, file->read_hook, file->read_hook_data, ++ file->offset, len, buf); + } + + +diff --git a/grub-core/fs/minix.c b/grub-core/fs/minix.c +index 9655211..918fe56 100644 +--- a/grub-core/fs/minix.c ++++ b/grub-core/fs/minix.c +@@ -249,8 +249,7 @@ grub_minix_get_file_block (struct grub_minix_data *data, unsigned int blk) + POS. Return the amount of read bytes in READ. */ + static grub_ssize_t + grub_minix_read_file (struct grub_minix_data *data, +- void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, +- unsigned offset, unsigned length), ++ grub_disk_read_hook_t read_hook, void *read_hook_data, + grub_off_t pos, grub_size_t len, char *buf) + { + grub_uint32_t i; +@@ -301,6 +300,7 @@ grub_minix_read_file (struct grub_minix_data *data, + } + + data->disk->read_hook = read_hook; ++ data->disk->read_hook_data = read_hook_data; + grub_disk_read (data->disk, + GRUB_MINIX_ZONE2SECT(blknr), + skipfirst, blockend, buf); +@@ -352,7 +352,7 @@ grub_minix_lookup_symlink (struct grub_minix_data *data, grub_minix_ino_t ino) + if (++data->linknest > GRUB_MINIX_MAX_SYMLNK_CNT) + return grub_error (GRUB_ERR_SYMLINK_LOOP, N_("too deep nesting of symlinks")); + +- if (grub_minix_read_file (data, 0, 0, ++ if (grub_minix_read_file (data, 0, 0, 0, + GRUB_MINIX_INODE_SIZE (data), symlink) < 0) + return grub_errno; + +@@ -409,10 +409,10 @@ grub_minix_find_file (struct grub_minix_data *data, const char *path) + if (grub_strlen (name) == 0) + return GRUB_ERR_NONE; + +- if (grub_minix_read_file (data, 0, pos, sizeof (ino), ++ if (grub_minix_read_file (data, 0, 0, pos, sizeof (ino), + (char *) &ino) < 0) + return grub_errno; +- if (grub_minix_read_file (data, 0, pos + sizeof (ino), ++ if (grub_minix_read_file (data, 0, 0, pos + sizeof (ino), + data->filename_size, (char *) filename)< 0) + return grub_errno; + +@@ -568,11 +568,11 @@ grub_minix_dir (grub_device_t device, const char *path, + grub_memset (&info, 0, sizeof (info)); + + +- if (grub_minix_read_file (data, 0, pos, sizeof (ino), ++ if (grub_minix_read_file (data, 0, 0, pos, sizeof (ino), + (char *) &ino) < 0) + return grub_errno; + +- if (grub_minix_read_file (data, 0, pos + sizeof (ino), ++ if (grub_minix_read_file (data, 0, 0, pos + sizeof (ino), + data->filename_size, + (char *) filename) < 0) + return grub_errno; +@@ -649,7 +649,8 @@ grub_minix_read (grub_file_t file, char *buf, grub_size_t len) + struct grub_minix_data *data = + (struct grub_minix_data *) file->data; + +- return grub_minix_read_file (data, file->read_hook, file->offset, len, buf); ++ return grub_minix_read_file (data, file->read_hook, file->read_hook_data, ++ file->offset, len, buf); + } + + +diff --git a/grub-core/fs/nilfs2.c b/grub-core/fs/nilfs2.c +index 9bd4444..3f28bd7 100644 +--- a/grub-core/fs/nilfs2.c ++++ b/grub-core/fs/nilfs2.c +@@ -630,13 +630,11 @@ grub_nilfs2_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) + 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), ++ grub_disk_read_hook_t read_hook, void *read_hook_data, + grub_off_t pos, grub_size_t len, char *buf) + { +- return grub_fshelp_read_file (node->data->disk, node, read_hook, ++ return grub_fshelp_read_file (node->data->disk, node, ++ read_hook, read_hook_data, + pos, len, buf, grub_nilfs2_read_block, + grub_le_to_cpu64 (node->inode.i_size), + LOG2_NILFS2_BLOCK_SIZE (node->data), 0); +@@ -856,7 +854,7 @@ grub_nilfs2_read_symlink (grub_fshelp_node_t node) + if (!symlink) + return 0; + +- grub_nilfs2_read_file (diro, 0, 0, ++ grub_nilfs2_read_file (diro, 0, 0, 0, + grub_le_to_cpu64 (diro->inode.i_size), symlink); + if (grub_errno) + { +@@ -887,7 +885,7 @@ grub_nilfs2_iterate_dir (grub_fshelp_node_t dir, + { + struct grub_nilfs2_dir_entry dirent; + +- grub_nilfs2_read_file (diro, 0, fpos, ++ grub_nilfs2_read_file (diro, 0, 0, fpos, + sizeof (struct grub_nilfs2_dir_entry), + (char *) &dirent); + if (grub_errno) +@@ -902,7 +900,7 @@ grub_nilfs2_iterate_dir (grub_fshelp_node_t dir, + struct grub_fshelp_node *fdiro; + enum grub_fshelp_filetype type = GRUB_FSHELP_UNKNOWN; + +- grub_nilfs2_read_file (diro, 0, ++ grub_nilfs2_read_file (diro, 0, 0, + fpos + sizeof (struct grub_nilfs2_dir_entry), + dirent.name_len, filename); + if (grub_errno) +@@ -1025,7 +1023,8 @@ 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, ++ return grub_nilfs2_read_file (&data->diropen, ++ file->read_hook, file->read_hook_data, + file->offset, len, buf); + } + +diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c +index 7ac46f9..5ea2e1b 100644 +--- a/grub-core/fs/ntfs.c ++++ b/grub-core/fs/ntfs.c +@@ -91,21 +91,15 @@ static grub_err_t read_mft (struct grub_ntfs_data *data, grub_uint8_t *buf, + static grub_err_t read_attr (struct grub_ntfs_attr *at, grub_uint8_t *dest, + grub_disk_addr_t ofs, grub_size_t len, + int cached, +- void +- NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t +- sector, +- unsigned offset, +- unsigned length)); ++ grub_disk_read_hook_t read_hook, ++ void *read_hook_data); + + static grub_err_t read_data (struct grub_ntfs_attr *at, grub_uint8_t *pa, + grub_uint8_t *dest, + grub_disk_addr_t ofs, grub_size_t len, + int cached, +- void +- NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t +- sector, +- unsigned offset, +- unsigned length)); ++ grub_disk_read_hook_t read_hook, ++ void *read_hook_data); + + static void + init_attr (struct grub_ntfs_attr *at, struct grub_ntfs_file *mft) +@@ -207,7 +201,7 @@ find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr) + at->edat_buf = grub_malloc (n); + if (!at->edat_buf) + return NULL; +- if (read_data (at, pa, at->edat_buf, 0, n, 0, 0)) ++ if (read_data (at, pa, at->edat_buf, 0, n, 0, 0, 0)) + { + grub_error (GRUB_ERR_BAD_FS, + "fail to read non-resident attribute list"); +@@ -249,7 +243,7 @@ find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr) + if (read_attr + (at, pa + 0x10, + u32at (pa, 0x10) * (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR), +- at->mft->data->mft_size << GRUB_NTFS_BLK_SHR, 0, 0)) ++ at->mft->data->mft_size << GRUB_NTFS_BLK_SHR, 0, 0, 0)) + return NULL; + pa += u16at (pa, 4); + } +@@ -325,9 +319,7 @@ retry: + { + if ((ctx->attr) && (ctx->attr->flags & GRUB_NTFS_AF_ALST)) + { +- void NESTED_FUNC_ATTR (*save_hook) (grub_disk_addr_t sector, +- unsigned offset, +- unsigned length); ++ grub_disk_read_hook_t save_hook; + + save_hook = ctx->comp.disk->read_hook; + ctx->comp.disk->read_hook = 0; +@@ -379,9 +371,7 @@ grub_ntfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t block) + static grub_err_t + read_data (struct grub_ntfs_attr *at, grub_uint8_t *pa, grub_uint8_t *dest, + grub_disk_addr_t ofs, grub_size_t len, int cached, +- void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, +- unsigned offset, +- unsigned length)) ++ grub_disk_read_hook_t read_hook, void *read_hook_data) + { + grub_disk_addr_t vcn; + struct grub_ntfs_rlst cc, *ctx; +@@ -480,7 +470,8 @@ read_data (struct grub_ntfs_attr *at, grub_uint8_t *pa, grub_uint8_t *dest, + if (!(ctx->flags & GRUB_NTFS_RF_COMP)) + { + grub_fshelp_read_file (ctx->comp.disk, (grub_fshelp_node_t) ctx, +- read_hook, ofs, len, (char *) dest, ++ read_hook, read_hook_data, ofs, len, ++ (char *) dest, + grub_ntfs_read_block, ofs + len, + ctx->comp.log_spc, 0); + return grub_errno; +@@ -495,9 +486,7 @@ read_data (struct grub_ntfs_attr *at, grub_uint8_t *pa, grub_uint8_t *dest, + static grub_err_t + read_attr (struct grub_ntfs_attr *at, grub_uint8_t *dest, grub_disk_addr_t ofs, + grub_size_t len, int cached, +- void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, +- unsigned offset, +- unsigned length)) ++ grub_disk_read_hook_t read_hook, void *read_hook_data) + { + grub_uint8_t *save_cur; + grub_uint8_t attr; +@@ -532,7 +521,8 @@ read_attr (struct grub_ntfs_attr *at, grub_uint8_t *dest, grub_disk_addr_t ofs, + } + pp = find_attr (at, attr); + if (pp) +- ret = read_data (at, pp, dest, ofs, len, cached, read_hook); ++ ret = read_data (at, pp, dest, ofs, len, cached, ++ read_hook, read_hook_data); + else + ret = + (grub_errno) ? grub_errno : grub_error (GRUB_ERR_BAD_FS, +@@ -546,7 +536,7 @@ read_mft (struct grub_ntfs_data *data, grub_uint8_t *buf, grub_uint32_t mftno) + { + if (read_attr + (&data->mmft.attr, buf, mftno * ((grub_disk_addr_t) data->mft_size << GRUB_NTFS_BLK_SHR), +- data->mft_size << GRUB_NTFS_BLK_SHR, 0, 0)) ++ data->mft_size << GRUB_NTFS_BLK_SHR, 0, 0, 0)) + return grub_error (GRUB_ERR_BAD_FS, "read MFT 0x%X fails", mftno); + return fixup (buf, data->mft_size, (const grub_uint8_t *) "FILE"); + } +@@ -717,7 +707,7 @@ grub_ntfs_read_symlink (grub_fshelp_node_t node) + } + + err = read_attr (&mft->attr, (grub_uint8_t *) &symdesc, 0, +- sizeof (struct symlink_descriptor), 1, 0); ++ sizeof (struct symlink_descriptor), 1, 0, 0); + if (err) + return NULL; + +@@ -743,7 +733,7 @@ grub_ntfs_read_symlink (grub_fshelp_node_t node) + if (!buf16) + return NULL; + +- err = read_attr (&mft->attr, (grub_uint8_t *) buf16, off, len, 1, 0); ++ err = read_attr (&mft->attr, (grub_uint8_t *) buf16, off, len, 1, 0, 0); + if (err) + return NULL; + +@@ -852,7 +842,7 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir, + } + else + { +- if (read_data (at, cur_pos, bmp, 0, bitmap_len, 0, 0)) ++ if (read_data (at, cur_pos, bmp, 0, bitmap_len, 0, 0, 0)) + { + grub_error (GRUB_ERR_BAD_FS, + "fails to read non-resident $BITMAP"); +@@ -899,7 +889,7 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir, + { + if ((read_attr + (at, indx, i * (mft->data->idx_size << GRUB_NTFS_BLK_SHR), +- (mft->data->idx_size << GRUB_NTFS_BLK_SHR), 0, 0)) ++ (mft->data->idx_size << GRUB_NTFS_BLK_SHR), 0, 0, 0)) + || (fixup (indx, mft->data->idx_size, + (const grub_uint8_t *) "INDX"))) + goto done; +@@ -1136,7 +1126,7 @@ grub_ntfs_read (grub_file_t file, char *buf, grub_size_t len) + mft->attr.save_pos = 1; + + read_attr (&mft->attr, (grub_uint8_t *) buf, file->offset, len, 1, +- file->read_hook); ++ file->read_hook, file->read_hook_data); + return (grub_errno) ? -1 : (grub_ssize_t) len; + } + +diff --git a/grub-core/fs/ntfscomp.c b/grub-core/fs/ntfscomp.c +index 02ea9fd..cf9e348 100644 +--- a/grub-core/fs/ntfscomp.c ++++ b/grub-core/fs/ntfscomp.c +@@ -302,6 +302,7 @@ ntfscomp (struct grub_ntfs_attr *at, grub_uint8_t *dest, grub_disk_addr_t ofs, + ret = 0; + + //ctx->comp.disk->read_hook = read_hook; ++ //ctx->comp.disk->read_hook_data = read_hook_data; + + if ((vcn > ctx->target_vcn) && + (read_block +diff --git a/grub-core/fs/reiserfs.c b/grub-core/fs/reiserfs.c +index 686e4da..eaa7ade 100644 +--- a/grub-core/fs/reiserfs.c ++++ b/grub-core/fs/reiserfs.c +@@ -240,9 +240,8 @@ struct grub_reiserfs_data + static grub_ssize_t + grub_reiserfs_read_real (struct grub_fshelp_node *node, + grub_off_t off, char *buf, grub_size_t len, +- void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, +- unsigned offset, +- unsigned length)); ++ grub_disk_read_hook_t read_hook, ++ void *read_hook_data); + + /* Internal-only functions. Not to be used outside of this file. */ + +@@ -674,7 +673,7 @@ grub_reiserfs_read_symlink (grub_fshelp_node_t node) + if (! symlink_buffer) + return 0; + +- ret = grub_reiserfs_read_real (node, 0, symlink_buffer, len, 0); ++ ret = grub_reiserfs_read_real (node, 0, symlink_buffer, len, 0, 0); + if (ret < 0) + { + grub_free (symlink_buffer); +@@ -1036,9 +1035,7 @@ grub_reiserfs_open (struct grub_file *file, const char *name) + static grub_ssize_t + grub_reiserfs_read_real (struct grub_fshelp_node *node, + grub_off_t off, char *buf, grub_size_t len, +- void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, +- unsigned offset, +- unsigned length)) ++ grub_disk_read_hook_t read_hook, void *read_hook_data) + { + unsigned int indirect_block, indirect_block_count; + struct grub_reiserfs_key key; +@@ -1105,6 +1102,7 @@ grub_reiserfs_read_real (struct grub_fshelp_node *node, + (unsigned) block, (unsigned) offset, + (unsigned) (offset + length)); + found.data->disk->read_hook = read_hook; ++ found.data->disk->read_hook_data = read_hook_data; + grub_disk_read (found.data->disk, + block, + offset +@@ -1131,6 +1129,7 @@ grub_reiserfs_read_real (struct grub_fshelp_node *node, + if (grub_errno) + goto fail; + found.data->disk->read_hook = read_hook; ++ found.data->disk->read_hook_data = read_hook_data; + for (indirect_block = 0; + indirect_block < indirect_block_count + && current_position < final_position; +@@ -1236,7 +1235,7 @@ static grub_ssize_t + grub_reiserfs_read (grub_file_t file, char *buf, grub_size_t len) + { + return grub_reiserfs_read_real (file->data, file->offset, buf, len, +- file->read_hook); ++ file->read_hook, file->read_hook_data); + } + + /* Close the file FILE. */ +diff --git a/grub-core/fs/romfs.c b/grub-core/fs/romfs.c +index b79b1e1..2e35444 100644 +--- a/grub-core/fs/romfs.c ++++ b/grub-core/fs/romfs.c +@@ -399,6 +399,7 @@ grub_romfs_read (grub_file_t file, char *buf, grub_size_t len) + + /* XXX: The file is stored in as a single extent. */ + data->data->disk->read_hook = file->read_hook; ++ data->data->disk->read_hook_data = file->read_hook_data; + grub_disk_read (data->data->disk, + (data->data_addr + file->offset) >> GRUB_DISK_SECTOR_BITS, + (data->data_addr + file->offset) & (GRUB_DISK_SECTOR_SIZE - 1), +diff --git a/grub-core/fs/sfs.c b/grub-core/fs/sfs.c +index fed17d3..e7d2f72 100644 +--- a/grub-core/fs/sfs.c ++++ b/grub-core/fs/sfs.c +@@ -345,11 +345,11 @@ grub_sfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) + POS. Return the amount of read bytes in READ. */ + static grub_ssize_t + grub_sfs_read_file (grub_fshelp_node_t node, +- void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, +- unsigned offset, unsigned length), ++ grub_disk_read_hook_t read_hook, void *read_hook_data, + grub_off_t pos, grub_size_t len, char *buf) + { +- return grub_fshelp_read_file (node->data->disk, node, read_hook, ++ return grub_fshelp_read_file (node->data->disk, node, ++ read_hook, read_hook_data, + pos, len, buf, grub_sfs_read_block, + node->size, node->data->log_blocksize, 0); + } +@@ -646,7 +646,8 @@ grub_sfs_read (grub_file_t file, char *buf, grub_size_t len) + { + struct grub_sfs_data *data = (struct grub_sfs_data *) file->data; + +- return grub_sfs_read_file (&data->diropen, file->read_hook, ++ return grub_sfs_read_file (&data->diropen, ++ file->read_hook, file->read_hook_data, + file->offset, len, buf); + } + +diff --git a/grub-core/fs/udf.c b/grub-core/fs/udf.c +index b7f3afb..405935e 100644 +--- a/grub-core/fs/udf.c ++++ b/grub-core/fs/udf.c +@@ -564,9 +564,7 @@ fail: + + static grub_ssize_t + grub_udf_read_file (grub_fshelp_node_t node, +- void NESTED_FUNC_ATTR +- (*read_hook) (grub_disk_addr_t sector, +- unsigned offset, unsigned length), ++ grub_disk_read_hook_t read_hook, void *read_hook_data, + grub_off_t pos, grub_size_t len, char *buf) + { + switch (U16 (node->block.fe.icbtag.flags) & GRUB_UDF_ICBTAG_FLAG_AD_MASK) +@@ -591,10 +589,11 @@ grub_udf_read_file (grub_fshelp_node_t node, + return 0; + } + +- return grub_fshelp_read_file (node->data->disk, node, read_hook, +- pos, len, buf, grub_udf_read_block, +- U64 (node->block.fe.file_size), +- node->data->lbshift, 0); ++ return grub_fshelp_read_file (node->data->disk, node, ++ read_hook, read_hook_data, ++ pos, len, buf, grub_udf_read_block, ++ U64 (node->block.fe.file_size), ++ node->data->lbshift, 0); + } + + static unsigned sblocklist[] = { 256, 512, 0 }; +@@ -861,7 +860,7 @@ grub_udf_iterate_dir (grub_fshelp_node_t dir, + + while (offset < U64 (dir->block.fe.file_size)) + { +- if (grub_udf_read_file (dir, 0, offset, sizeof (dirent), ++ if (grub_udf_read_file (dir, 0, 0, offset, sizeof (dirent), + (char *) &dirent) != sizeof (dirent)) + return 0; + +@@ -898,7 +897,7 @@ grub_udf_iterate_dir (grub_fshelp_node_t dir, + if (child->block.fe.icbtag.file_type == GRUB_UDF_ICBTAG_TYPE_SYMLINK) + type = GRUB_FSHELP_SYMLINK; + +- if ((grub_udf_read_file (dir, 0, offset, ++ if ((grub_udf_read_file (dir, 0, 0, offset, + dirent.file_ident_length, + (char *) raw)) + != dirent.file_ident_length) +@@ -937,7 +936,7 @@ grub_udf_read_symlink (grub_fshelp_node_t node) + raw = grub_malloc (sz); + if (!raw) + return NULL; +- if (grub_udf_read_file (node, NULL, 0, sz, (char *) raw) < 0) ++ if (grub_udf_read_file (node, NULL, NULL, 0, sz, (char *) raw) < 0) + { + grub_free (raw); + return NULL; +@@ -1149,7 +1148,8 @@ grub_udf_read (grub_file_t file, char *buf, grub_size_t len) + { + struct grub_fshelp_node *node = (struct grub_fshelp_node *) file->data; + +- return grub_udf_read_file (node, file->read_hook, file->offset, len, buf); ++ return grub_udf_read_file (node, file->read_hook, file->read_hook_data, ++ file->offset, len, buf); + } + + static grub_err_t +diff --git a/grub-core/fs/ufs.c b/grub-core/fs/ufs.c +index 089a5c6..c155912 100644 +--- a/grub-core/fs/ufs.c ++++ b/grub-core/fs/ufs.c +@@ -331,8 +331,7 @@ grub_ufs_get_file_block (struct grub_ufs_data *data, grub_disk_addr_t blk) + POS. Return the amount of read bytes in READ. */ + static grub_ssize_t + grub_ufs_read_file (struct grub_ufs_data *data, +- void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, +- unsigned offset, unsigned length), ++ grub_disk_read_hook_t read_hook, void *read_hook_data, + grub_off_t pos, grub_size_t len, char *buf) + { + struct grub_ufs_sblock *sblock = &data->sblock; +@@ -380,6 +379,7 @@ grub_ufs_read_file (struct grub_ufs_data *data, + if (blknr) + { + data->disk->read_hook = read_hook; ++ data->disk->read_hook_data = read_hook_data; + grub_disk_read (data->disk, + blknr << grub_ufs_to_cpu32 (data->sblock.log2_blksz), + skipfirst, blockend, buf); +@@ -455,7 +455,7 @@ grub_ufs_lookup_symlink (struct grub_ufs_data *data, int ino) + && INODE_SIZE (data) <= sizeof (data->inode.symlink)) + grub_strcpy (symlink, (char *) data->inode.symlink); + else +- grub_ufs_read_file (data, 0, 0, INODE_SIZE (data), symlink); ++ grub_ufs_read_file (data, 0, 0, 0, INODE_SIZE (data), symlink); + symlink[INODE_SIZE (data)] = '\0'; + + /* The symlink is an absolute path, go back to the root inode. */ +@@ -509,7 +509,7 @@ grub_ufs_find_file (struct grub_ufs_data *data, const char *path) + if (grub_strlen (name) == 0) + return GRUB_ERR_NONE; + +- if (grub_ufs_read_file (data, 0, pos, sizeof (dirent), ++ if (grub_ufs_read_file (data, 0, 0, pos, sizeof (dirent), + (char *) &dirent) < 0) + return grub_errno; + +@@ -521,7 +521,7 @@ grub_ufs_find_file (struct grub_ufs_data *data, const char *path) + { + char filename[namelen + 1]; + +- if (grub_ufs_read_file (data, 0, pos + sizeof (dirent), ++ if (grub_ufs_read_file (data, 0, 0, pos + sizeof (dirent), + namelen, filename) < 0) + return grub_errno; + +@@ -659,7 +659,7 @@ grub_ufs_dir (grub_device_t device, const char *path, + struct grub_ufs_dirent dirent; + int namelen; + +- if (grub_ufs_read_file (data, 0, pos, sizeof (dirent), ++ if (grub_ufs_read_file (data, 0, 0, pos, sizeof (dirent), + (char *) &dirent) < 0) + break; + +@@ -679,7 +679,7 @@ grub_ufs_dir (grub_device_t device, const char *path, + + grub_memset (&info, 0, sizeof (info)); + +- if (grub_ufs_read_file (data, 0, pos + sizeof (dirent), ++ if (grub_ufs_read_file (data, 0, 0, pos + sizeof (dirent), + namelen, filename) < 0) + break; + +@@ -752,7 +752,8 @@ grub_ufs_read (grub_file_t file, char *buf, grub_size_t len) + struct grub_ufs_data *data = + (struct grub_ufs_data *) file->data; + +- return grub_ufs_read_file (data, file->read_hook, file->offset, len, buf); ++ return grub_ufs_read_file (data, file->read_hook, file->read_hook_data, ++ file->offset, len, buf); + } + + +diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c +index aee1582..a5a1700 100644 +--- a/grub-core/fs/xfs.c ++++ b/grub-core/fs/xfs.c +@@ -379,11 +379,11 @@ grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) + POS. Return the amount of read bytes in READ. */ + static grub_ssize_t + grub_xfs_read_file (grub_fshelp_node_t node, +- void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, +- unsigned offset, unsigned length), ++ grub_disk_read_hook_t read_hook, void *read_hook_data, + grub_off_t pos, grub_size_t len, char *buf) + { +- return grub_fshelp_read_file (node->data->disk, node, read_hook, ++ return grub_fshelp_read_file (node->data->disk, node, ++ read_hook, read_hook_data, + pos, len, buf, grub_xfs_read_block, + grub_be_to_cpu64 (node->inode.size), + node->data->sblock.log2_bsize +@@ -410,7 +410,7 @@ grub_xfs_read_symlink (grub_fshelp_node_t node) + if (!symlink) + return 0; + +- numread = grub_xfs_read_file (node, 0, 0, size, symlink); ++ numread = grub_xfs_read_file (node, 0, 0, 0, size, symlink); + if (numread != size) + { + grub_free (symlink); +@@ -592,7 +592,7 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir, + struct grub_xfs_dirblock_tail *tail; + tail = (struct grub_xfs_dirblock_tail *) &dirblock[tail_start]; + +- numread = grub_xfs_read_file (dir, 0, ++ numread = grub_xfs_read_file (dir, 0, 0, + blk << dirblk_log2, + dirblk_size, dirblock); + if (numread != dirblk_size) +@@ -829,8 +829,9 @@ grub_xfs_read (grub_file_t file, char *buf, grub_size_t len) + struct grub_xfs_data *data = + (struct grub_xfs_data *) file->data; + +- return grub_xfs_read_file (&data->diropen, file->read_hook, +- file->offset, len, buf); ++ return grub_xfs_read_file (&data->diropen, ++ file->read_hook, file->read_hook_data, ++ file->offset, len, buf); + } + + +diff --git a/grub-core/kern/disk.c b/grub-core/kern/disk.c +index 94318af..76ff450 100644 +--- a/grub-core/kern/disk.c ++++ b/grub-core/kern/disk.c +@@ -603,7 +603,7 @@ grub_disk_read (grub_disk_t disk, grub_disk_addr_t sector, + cl = GRUB_DISK_SECTOR_SIZE - o; + if (cl > l) + cl = l; +- (disk->read_hook) (s, o, cl); ++ (disk->read_hook) (s, o, cl, disk->read_hook_data); + s++; + l -= cl; + o = 0; +diff --git a/include/grub/disk.h b/include/grub/disk.h +index 013ca1f..f0e3df3 100644 +--- a/include/grub/disk.h ++++ b/include/grub/disk.h +@@ -19,6 +19,8 @@ + #ifndef GRUB_DISK_HEADER + #define GRUB_DISK_HEADER 1 + ++#include ++ + #include + #include + #include +@@ -99,6 +101,10 @@ extern grub_disk_dev_t EXPORT_VAR (grub_disk_dev_list); + + struct grub_partition; + ++typedef void (*grub_disk_read_hook_t) (grub_disk_addr_t sector, ++ unsigned offset, unsigned length, ++ void *data); ++ + /* Disk. */ + struct grub_disk + { +@@ -122,8 +128,10 @@ struct grub_disk + + /* Called when a sector was read. OFFSET is between 0 and + the sector size minus 1, and LENGTH is between 0 and the sector size. */ +- void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, +- unsigned offset, unsigned length); ++ grub_disk_read_hook_t read_hook; ++ ++ /* Caller-specific data passed to the read hook. */ ++ void *read_hook_data; + + /* Device-specific data. */ + void *data; +diff --git a/include/grub/file.h b/include/grub/file.h +index ae86401..8003985 100644 +--- a/include/grub/file.h ++++ b/include/grub/file.h +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include + + /* File description. */ + struct grub_file +@@ -46,8 +47,10 @@ struct grub_file + void *data; + + /* This is called when a sector is read. Used only for a disk device. */ +- void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, +- unsigned offset, unsigned length); ++ grub_disk_read_hook_t read_hook; ++ ++ /* Caller-specific data passed to the read hook. */ ++ void *read_hook_data; + }; + typedef struct grub_file *grub_file_t; + +diff --git a/include/grub/fshelp.h b/include/grub/fshelp.h +index e437d4c..5c57236 100644 +--- a/include/grub/fshelp.h ++++ b/include/grub/fshelp.h +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include + + typedef struct grub_fshelp_node *grub_fshelp_node_t; + +@@ -68,9 +69,8 @@ EXPORT_FUNC(grub_fshelp_find_file) (const char *path, + blocks have a size of LOG2BLOCKSIZE (in log2). */ + grub_ssize_t + EXPORT_FUNC(grub_fshelp_read_file) (grub_disk_t disk, grub_fshelp_node_t node, +- void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, +- unsigned offset, +- unsigned length), ++ grub_disk_read_hook_t read_hook, ++ void *read_hook_data, + grub_off_t pos, grub_size_t len, char *buf, + grub_disk_addr_t (*get_block) (grub_fshelp_node_t node, + grub_disk_addr_t block), +diff --git a/util/grub-setup.c b/util/grub-setup.c +index 187345a..5a7a857 100644 +--- a/util/grub-setup.c ++++ b/util/grub-setup.c +@@ -138,6 +138,70 @@ write_rootdev (grub_device_t root_dev, + #define BOOT_SECTOR 0 + #endif + ++/* Helper for setup. */ ++static void ++save_first_sector (grub_disk_addr_t sector, unsigned offset, unsigned length, ++ void *data) ++{ ++ grub_disk_addr_t *first_sector = data; ++ grub_util_info ("the first sector is <%" PRIuGRUB_UINT64_T ",%u,%u>", ++ sector, offset, length); ++ ++ if (offset != 0 || length != GRUB_DISK_SECTOR_SIZE) ++ grub_util_error ("%s", _("the first sector of the core file is not sector-aligned")); ++ ++ *first_sector = sector; ++} ++ ++struct blocklists ++{ ++ struct grub_boot_blocklist *first_block, *block; ++#ifdef GRUB_SETUP_BIOS ++ grub_uint16_t current_segment; ++#endif ++ grub_uint16_t last_length; ++}; ++ ++/* Helper for setup. */ ++static void ++save_blocklists (grub_disk_addr_t sector, unsigned offset, unsigned length, ++ void *data) ++{ ++ struct blocklists *bl = data; ++ struct grub_boot_blocklist *prev = bl->block + 1; ++ ++ grub_util_info ("saving <%" PRIuGRUB_UINT64_T ",%u,%u>", ++ sector, offset, length); ++ ++ if (offset != 0 || bl->last_length != GRUB_DISK_SECTOR_SIZE) ++ grub_util_error ("%s", _("non-sector-aligned data is found in the core file")); ++ ++ if (bl->block != bl->first_block ++ && (grub_target_to_host64 (prev->start) ++ + grub_target_to_host16 (prev->len)) == sector) ++ { ++ grub_uint16_t t = grub_target_to_host16 (prev->len) + 1; ++ prev->len = grub_host_to_target16 (t); ++ } ++ else ++ { ++ bl->block->start = grub_host_to_target64 (sector); ++ bl->block->len = grub_host_to_target16 (1); ++#ifdef GRUB_SETUP_BIOS ++ bl->block->segment = grub_host_to_target16 (bl->current_segment); ++#endif ++ ++ bl->block--; ++ if (bl->block->len) ++ grub_util_error ("%s", _("the sectors of the core file are too fragmented")); ++ } ++ ++ bl->last_length = length; ++#ifdef GRUB_SETUP_BIOS ++ bl->current_segment += GRUB_DISK_SECTOR_SIZE >> 4; ++#endif ++} ++ + #ifdef GRUB_SETUP_BIOS + /* Context for setup/identify_partmap. */ + struct identify_partmap_ctx +@@ -147,7 +211,7 @@ struct identify_partmap_ctx + int multiple_partmaps; + }; + +-/* Helper for setup/identify_partmap. ++/* Helper for setup. + Unlike root_dev, with dest_dev we're interested in the partition map even + if dest_dev itself is a whole disk. */ + static int +@@ -190,73 +254,16 @@ setup (const char *dir, + grub_uint16_t core_sectors; + #endif + grub_device_t root_dev = 0, dest_dev, core_dev; +- struct grub_boot_blocklist *first_block, *block; ++ struct blocklists bl; + char *tmp_img; + grub_disk_addr_t first_sector; +-#ifdef GRUB_SETUP_BIOS +- grub_uint16_t current_segment +- = GRUB_BOOT_I386_PC_KERNEL_SEG + (GRUB_DISK_SECTOR_SIZE >> 4); +-#endif +- grub_uint16_t last_length = GRUB_DISK_SECTOR_SIZE; + FILE *fp; + +- auto void NESTED_FUNC_ATTR save_first_sector (grub_disk_addr_t sector, +- unsigned offset, +- unsigned length); +- auto void NESTED_FUNC_ATTR save_blocklists (grub_disk_addr_t sector, +- unsigned offset, +- unsigned length); +- +- void NESTED_FUNC_ATTR save_first_sector (grub_disk_addr_t sector, +- unsigned offset, +- unsigned length) +- { +- grub_util_info ("the first sector is <%" PRIuGRUB_UINT64_T ",%u,%u>", +- sector, offset, length); +- +- if (offset != 0 || length != GRUB_DISK_SECTOR_SIZE) +- grub_util_error ("%s", _("the first sector of the core file is not sector-aligned")); +- +- first_sector = sector; +- } +- +- void NESTED_FUNC_ATTR save_blocklists (grub_disk_addr_t sector, +- unsigned offset, +- unsigned length) +- { +- struct grub_boot_blocklist *prev = block + 1; +- +- grub_util_info ("saving <%" PRIuGRUB_UINT64_T ",%u,%u>", +- sector, offset, length); +- +- if (offset != 0 || last_length != GRUB_DISK_SECTOR_SIZE) +- grub_util_error ("%s", _("non-sector-aligned data is found in the core file")); +- +- if (block != first_block +- && (grub_target_to_host64 (prev->start) +- + grub_target_to_host16 (prev->len)) == sector) +- { +- grub_uint16_t t = grub_target_to_host16 (prev->len) + 1; +- prev->len = grub_host_to_target16 (t); +- } +- else +- { +- block->start = grub_host_to_target64 (sector); +- block->len = grub_host_to_target16 (1); + #ifdef GRUB_SETUP_BIOS +- block->segment = grub_host_to_target16 (current_segment); ++ bl.current_segment = ++ GRUB_BOOT_I386_PC_KERNEL_SEG + (GRUB_DISK_SECTOR_SIZE >> 4); + #endif +- +- block--; +- if (block->len) +- grub_util_error ("%s", _("the sectors of the core file are too fragmented")); +- } +- +- last_length = length; +-#ifdef GRUB_SETUP_BIOS +- current_segment += GRUB_DISK_SECTOR_SIZE >> 4; +-#endif +- } ++ bl.last_length = GRUB_DISK_SECTOR_SIZE; + + /* Read the boot image by the OS service. */ + boot_path = grub_util_get_path (dir, boot_file); +@@ -283,9 +290,9 @@ setup (const char *dir, + core_img = grub_util_read_image (core_path); + + /* Have FIRST_BLOCK to point to the first blocklist. */ +- first_block = (struct grub_boot_blocklist *) (core_img +- + GRUB_DISK_SECTOR_SIZE +- - sizeof (*block)); ++ bl.first_block = (struct grub_boot_blocklist *) (core_img ++ + GRUB_DISK_SECTOR_SIZE ++ - sizeof (*bl.block)); + grub_util_info ("root is `%s', dest is `%s'", root, dest); + + grub_util_info ("Opening dest"); +@@ -511,38 +518,38 @@ setup (const char *dir, + assert (nsec <= maxsec); + + /* Clean out the blocklists. */ +- block = first_block; +- while (block->len) ++ bl.block = bl.first_block; ++ while (bl.block->len) + { +- grub_memset (block, 0, sizeof (block)); ++ grub_memset (bl.block, 0, sizeof (bl.block)); + +- block--; ++ bl.block--; + +- if ((char *) block <= core_img) ++ if ((char *) bl.block <= core_img) + grub_util_error ("%s", _("no terminator in the core image")); + } + + save_first_sector (sectors[0] + grub_partition_get_start (ctx.container), +- 0, GRUB_DISK_SECTOR_SIZE); ++ 0, GRUB_DISK_SECTOR_SIZE, &first_sector); + +- block = first_block; ++ bl.block = bl.first_block; + for (i = 1; i < nsec; i++) + save_blocklists (sectors[i] + grub_partition_get_start (ctx.container), +- 0, GRUB_DISK_SECTOR_SIZE); ++ 0, GRUB_DISK_SECTOR_SIZE, &bl); + + /* Make sure that the last blocklist is a terminator. */ +- if (block == first_block) +- block--; +- block->start = 0; +- block->len = 0; +- block->segment = 0; ++ if (bl.block == bl.first_block) ++ bl.block--; ++ bl.block->start = 0; ++ bl.block->len = 0; ++ bl.block->segment = 0; + + write_rootdev (root_dev, boot_img, first_sector); + + core_img = realloc (core_img, nsec * GRUB_DISK_SECTOR_SIZE); +- first_block = (struct grub_boot_blocklist *) (core_img +- + GRUB_DISK_SECTOR_SIZE +- - sizeof (*block)); ++ bl.first_block = (struct grub_boot_blocklist *) (core_img ++ + GRUB_DISK_SECTOR_SIZE ++ - sizeof (*bl.block)); + + grub_size_t no_rs_length; + grub_set_unaligned32 ((core_img + GRUB_DISK_SECTOR_SIZE +@@ -698,22 +705,22 @@ unable_to_embed: + #endif + + /* Clean out the blocklists. */ +- block = first_block; +- while (block->len) ++ bl.block = bl.first_block; ++ while (bl.block->len) + { +- block->start = 0; +- block->len = 0; ++ bl.block->start = 0; ++ bl.block->len = 0; + #ifdef GRUB_SETUP_BIOS +- block->segment = 0; ++ bl.block->segment = 0; + #endif + +- block--; ++ bl.block--; + +- if ((char *) block <= core_img) ++ if ((char *) bl.block <= core_img) + grub_util_error ("%s", _("no terminator in the core image")); + } + +- block = first_block; ++ bl.block = bl.first_block; + + #ifdef __linux__ + { +@@ -766,11 +773,11 @@ unable_to_embed: + if (i == 0 && j == 0) + save_first_sector (((grub_uint64_t) blk) * mul + + container_start, +- 0, rest); ++ 0, rest, &first_sector); + else + save_blocklists (((grub_uint64_t) blk) * mul + j + + container_start, +- 0, rest); ++ 0, rest, &bl); + } + } + } +@@ -806,13 +813,14 @@ unable_to_embed: + >> GRUB_DISK_SECTOR_BITS) + + j + container_start, + fie2->fm_extents[i].fe_physical +- & (GRUB_DISK_SECTOR_SIZE - 1), len); ++ & (GRUB_DISK_SECTOR_SIZE - 1), len, ++ &first_sector); + else + save_blocklists ((fie2->fm_extents[i].fe_physical + >> GRUB_DISK_SECTOR_BITS) + + j + container_start, + fie2->fm_extents[i].fe_physical +- & (GRUB_DISK_SECTOR_SIZE - 1), len); ++ & (GRUB_DISK_SECTOR_SIZE - 1), len, &bl); + + + } +@@ -830,12 +838,14 @@ unable_to_embed: + grub_util_error ("%s", grub_errmsg); + + file->read_hook = save_first_sector; ++ file->read_hook_data = &first_sector; + if (grub_file_read (file, tmp_img, GRUB_DISK_SECTOR_SIZE) + != GRUB_DISK_SECTOR_SIZE) + grub_util_error ("%s", _("failed to read the first sector of the core image")); + +- block = first_block; ++ bl.block = bl.first_block; + file->read_hook = save_blocklists; ++ file->read_hook_data = &bl; + if (grub_file_read (file, tmp_img, core_size - GRUB_DISK_SECTOR_SIZE) + != (grub_ssize_t) core_size - GRUB_DISK_SECTOR_SIZE) + grub_util_error ("%s", _("failed to read the rest sectors of the core image")); +@@ -913,11 +923,11 @@ unable_to_embed: + ptr += GRUB_DISK_SECTOR_SIZE; + len -= GRUB_DISK_SECTOR_SIZE; + +- block = first_block; +- while (block->len) ++ bl.block = bl.first_block; ++ while (bl.block->len) + { +- size_t cur = grub_target_to_host16 (block->len) << GRUB_DISK_SECTOR_BITS; +- blk = grub_target_to_host64 (block->start); ++ size_t cur = grub_target_to_host16 (bl.block->len) << GRUB_DISK_SECTOR_BITS; ++ blk = grub_target_to_host64 (bl.block->start); + + if (cur > len) + cur = len; +@@ -932,9 +942,9 @@ unable_to_embed: + + ptr += cur; + len -= cur; +- block--; ++ bl.block--; + +- if ((char *) block <= core_img) ++ if ((char *) bl.block <= core_img) + grub_util_error ("%s", _("no terminator in the core image")); + } + core_dev->disk->partition = container; +-- +1.8.1.4 + diff --git a/0162-grub-core-loader-machoXX.c-Remove-nested-functions.patch b/0162-grub-core-loader-machoXX.c-Remove-nested-functions.patch new file mode 100644 index 0000000..aa436b3 --- /dev/null +++ b/0162-grub-core-loader-machoXX.c-Remove-nested-functions.patch @@ -0,0 +1,339 @@ +From fbb356247b5f555c776fca710a1059e6fce16e98 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Wed, 27 Feb 2013 20:56:23 +0100 +Subject: [PATCH 162/364] * grub-core/loader/machoXX.c: Remove nested + functions. + +--- + ChangeLog | 4 + + grub-core/loader/machoXX.c | 261 +++++++++++++++++++++++++-------------------- + 2 files changed, 148 insertions(+), 117 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index dbecfef..bb02830 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,7 @@ ++2013-02-27 Vladimir Serbinenko ++ ++ * grub-core/loader/machoXX.c: Remove nested functions. ++ + 2013-02-27 Colin Watson + + Remove nested functions from disk and file read hooks. +diff --git a/grub-core/loader/machoXX.c b/grub-core/loader/machoXX.c +index 5b78a61..3a382b3 100644 +--- a/grub-core/loader/machoXX.c ++++ b/grub-core/loader/machoXX.c +@@ -79,7 +79,7 @@ SUFFIX (grub_macho_parse) (grub_macho_t macho, const char *filename) + } + } + +-typedef int NESTED_FUNC_ATTR (*grub_macho_iter_hook_t) ++typedef int (*grub_macho_iter_hook_t) + (grub_macho_t , struct grub_macho_cmd *, + void *); + +@@ -200,46 +200,59 @@ SUFFIX (grub_macho_readfile) (grub_macho_t macho, + return GRUB_ERR_NONE; + } + ++struct calcsize_ctx ++{ ++ int flags; ++ int nr_phdrs; ++ grub_macho_addr_t *segments_start; ++ grub_macho_addr_t *segments_end; ++}; ++ ++/* Run through the program headers to calculate the total memory size we ++ should claim. */ ++static int ++calcsize (grub_macho_t _macho __attribute__ ((unused)), ++ struct grub_macho_cmd *hdr0, ++ void *_arg) ++{ ++ grub_macho_segment_t *hdr = (grub_macho_segment_t *) hdr0; ++ struct calcsize_ctx *ctx = _arg; ++ if (hdr->cmd != GRUB_MACHO_CMD_SEGMENT) ++ return 0; ++ ++ if (! hdr->vmsize) ++ return 0; ++ ++ if (! hdr->filesize && (ctx->flags & GRUB_MACHO_NOBSS)) ++ return 0; ++ ++ ctx->nr_phdrs++; ++ if (hdr->vmaddr < *ctx->segments_start) ++ *ctx->segments_start = hdr->vmaddr; ++ if (hdr->vmaddr + hdr->vmsize > *ctx->segments_end) ++ *ctx->segments_end = hdr->vmaddr + hdr->vmsize; ++ return 0; ++} ++ + /* Calculate the amount of memory spanned by the segments. */ + grub_err_t + SUFFIX (grub_macho_size) (grub_macho_t macho, grub_macho_addr_t *segments_start, + grub_macho_addr_t *segments_end, int flags, + const char *filename) + { +- int nr_phdrs = 0; +- +- /* Run through the program headers to calculate the total memory size we +- 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 _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) +- return 0; +- +- if (! hdr->vmsize) +- return 0; +- +- if (! hdr->filesize && (flags & GRUB_MACHO_NOBSS)) +- return 0; +- +- nr_phdrs++; +- if (hdr->vmaddr < *segments_start) +- *segments_start = hdr->vmaddr; +- if (hdr->vmaddr + hdr->vmsize > *segments_end) +- *segments_end = hdr->vmaddr + hdr->vmsize; +- return 0; +- } ++ struct calcsize_ctx ctx = { ++ .flags = flags, ++ .nr_phdrs = 0, ++ .segments_start = segments_start, ++ .segments_end = segments_end, ++ }; + + *segments_start = (grub_macho_addr_t) -1; + *segments_end = 0; + +- grub_macho_cmds_iterate (macho, calcsize, 0, filename); ++ grub_macho_cmds_iterate (macho, calcsize, &ctx, filename); + +- if (nr_phdrs == 0) ++ if (ctx.nr_phdrs == 0) + return grub_error (GRUB_ERR_BAD_OS, "no program headers present"); + + if (*segments_end < *segments_start) +@@ -249,109 +262,123 @@ SUFFIX (grub_macho_size) (grub_macho_t macho, grub_macho_addr_t *segments_start, + return GRUB_ERR_NONE; + } + ++struct do_load_ctx ++{ ++ int flags; ++ char *offset; ++ const char *filename; ++ int *darwin_version; ++}; ++ ++static int ++do_load(grub_macho_t _macho, ++ struct grub_macho_cmd *hdr0, ++ void *_arg) ++{ ++ grub_macho_segment_t *hdr = (grub_macho_segment_t *) hdr0; ++ struct do_load_ctx *ctx = _arg; ++ ++ if (hdr->cmd != GRUB_MACHO_CMD_SEGMENT) ++ return 0; ++ ++ if (! hdr->filesize && (ctx->flags & GRUB_MACHO_NOBSS)) ++ return 0; ++ if (! hdr->vmsize) ++ return 0; ++ ++ if (hdr->filesize) ++ { ++ grub_ssize_t read, toread = min (hdr->filesize, hdr->vmsize); ++ if (_macho->uncompressedXX) ++ { ++ if (hdr->fileoff + (grub_size_t) toread ++ > _macho->uncompressed_sizeXX) ++ read = -1; ++ else ++ { ++ read = toread; ++ grub_memcpy (ctx->offset + hdr->vmaddr, ++ _macho->uncompressedXX + hdr->fileoff, read); ++ } ++ } ++ else ++ { ++ if (grub_file_seek (_macho->file, hdr->fileoff ++ + _macho->offsetXX) == (grub_off_t) -1) ++ return 1; ++ read = grub_file_read (_macho->file, ctx->offset + hdr->vmaddr, ++ toread); ++ } ++ ++ if (read != toread) ++ { ++ /* XXX How can we free memory from `load_hook'? */ ++ if (!grub_errno) ++ grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), ++ ctx->filename); ++ ++ return 1; ++ } ++ if (ctx->darwin_version) ++ { ++ const char *ptr = ctx->offset + hdr->vmaddr; ++ const char *end = ptr + min (hdr->filesize, hdr->vmsize) ++ - (sizeof ("Darwin Kernel Version ") - 1); ++ for (; ptr < end; ptr++) ++ if (grub_memcmp (ptr, "Darwin Kernel Version ", ++ sizeof ("Darwin Kernel Version ") - 1) == 0) ++ { ++ ptr += sizeof ("Darwin Kernel Version ") - 1; ++ *ctx->darwin_version = 0; ++ end += (sizeof ("Darwin Kernel Version ") - 1); ++ while (ptr < end && grub_isdigit (*ptr)) ++ *ctx->darwin_version = (*ptr++ - '0') + *ctx->darwin_version * 10; ++ break; ++ } ++ } ++ } ++ ++ if (hdr->filesize < hdr->vmsize) ++ grub_memset (ctx->offset + hdr->vmaddr + hdr->filesize, ++ 0, hdr->vmsize - hdr->filesize); ++ return 0; ++} ++ + /* Load every loadable segment into memory specified by `_load_hook'. */ + grub_err_t + SUFFIX (grub_macho_load) (grub_macho_t macho, const char *filename, + char *offset, int flags, int *darwin_version) + { +- auto int NESTED_FUNC_ATTR do_load(grub_macho_t _macho, +- struct grub_macho_cmd *hdr0, +- void *_arg __attribute__ ((unused))); +- int NESTED_FUNC_ATTR do_load(grub_macho_t _macho, +- 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) +- return 0; +- +- if (! hdr->filesize && (flags & GRUB_MACHO_NOBSS)) +- return 0; +- if (! hdr->vmsize) +- return 0; +- +- if (hdr->filesize) +- { +- grub_ssize_t read, toread = min (hdr->filesize, hdr->vmsize); +- if (macho->uncompressedXX) +- { +- if (hdr->fileoff + (grub_size_t) toread +- > _macho->uncompressed_sizeXX) +- read = -1; +- else +- { +- read = toread; +- grub_memcpy (offset + hdr->vmaddr, +- _macho->uncompressedXX + hdr->fileoff, read); +- } +- } +- else +- { +- if (grub_file_seek (_macho->file, hdr->fileoff +- + _macho->offsetXX) == (grub_off_t) -1) +- return 1; +- read = grub_file_read (_macho->file, offset + hdr->vmaddr, +- toread); +- } +- +- if (read != toread) +- { +- /* XXX How can we free memory from `load_hook'? */ +- if (!grub_errno) +- grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), +- filename); +- +- return 1; +- } +- if (darwin_version) +- { +- const char *ptr = offset + hdr->vmaddr; +- const char *end = ptr + min (hdr->filesize, hdr->vmsize) +- - (sizeof ("Darwin Kernel Version ") - 1); +- for (; ptr < end; ptr++) +- if (grub_memcmp (ptr, "Darwin Kernel Version ", +- sizeof ("Darwin Kernel Version ") - 1) == 0) +- { +- ptr += sizeof ("Darwin Kernel Version ") - 1; +- *darwin_version = 0; +- end += (sizeof ("Darwin Kernel Version ") - 1); +- while (ptr < end && grub_isdigit (*ptr)) +- *darwin_version = (*ptr++ - '0') + *darwin_version * 10; +- break; +- } +- } +- } +- +- if (hdr->filesize < hdr->vmsize) +- grub_memset (offset + hdr->vmaddr + hdr->filesize, +- 0, hdr->vmsize - hdr->filesize); +- return 0; +- } ++ struct do_load_ctx ctx = { ++ .flags = flags, ++ .offset = offset, ++ .filename = filename, ++ .darwin_version = darwin_version ++ }; + + if (darwin_version) + *darwin_version = 0; + +- grub_macho_cmds_iterate (macho, do_load, 0, filename); ++ grub_macho_cmds_iterate (macho, do_load, &ctx, filename); + + return grub_errno; + } + ++static int ++find_entry_point (grub_macho_t _macho __attribute__ ((unused)), ++ struct grub_macho_cmd *hdr, ++ void *_arg) ++{ ++ grub_macho_addr_t *entry_point = _arg; ++ if (hdr->cmd == GRUB_MACHO_CMD_THREAD) ++ *entry_point = ((grub_macho_thread_t *) hdr)->entry_point; ++ return 0; ++} ++ + grub_macho_addr_t + SUFFIX (grub_macho_get_entry_point) (grub_macho_t macho, const char *filename) + { + grub_macho_addr_t entry_point = 0; +- auto int NESTED_FUNC_ATTR hook(grub_macho_t _macho, +- 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; +- return 0; +- } +- grub_macho_cmds_iterate (macho, hook, 0, filename); ++ grub_macho_cmds_iterate (macho, find_entry_point, &entry_point, filename); + return entry_point; + } +-- +1.8.1.4 + diff --git a/0163-util-grub-fstest.c-Remove-nested-functions.patch b/0163-util-grub-fstest.c-Remove-nested-functions.patch new file mode 100644 index 0000000..47abbf6 --- /dev/null +++ b/0163-util-grub-fstest.c-Remove-nested-functions.patch @@ -0,0 +1,273 @@ +From 4c12073435b0bc85e373bd74bb8091ccc538df6b Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Thu, 28 Feb 2013 09:36:55 +0100 +Subject: [PATCH 163/364] * util/grub-fstest.c: Remove nested functions. + +--- + ChangeLog | 4 ++ + util/grub-fstest.c | 166 ++++++++++++++++++++++++++++------------------------- + 2 files changed, 93 insertions(+), 77 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index bb02830..06123b6 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,7 @@ ++2013-02-28 Vladimir Serbinenko ++ ++ * util/grub-fstest.c: Remove nested functions. ++ + 2013-02-27 Vladimir Serbinenko + + * grub-core/loader/machoXX.c: Remove nested functions. +diff --git a/util/grub-fstest.c b/util/grub-fstest.c +index a546b75..253dee8 100644 +--- a/util/grub-fstest.c ++++ b/util/grub-fstest.c +@@ -79,7 +79,7 @@ static grub_disk_addr_t skip, leng; + static int uncompress = 0; + + static void +-read_file (char *pathname, int (*hook) (grub_off_t ofs, char *buf, int len)) ++read_file (char *pathname, int (*hook) (grub_off_t ofs, char *buf, int len, void *hook_arg), void *hook_arg) + { + static char buf[BUF_SIZE]; + grub_file_t file; +@@ -108,7 +108,7 @@ read_file (char *pathname, int (*hook) (grub_off_t ofs, char *buf, int len)) + grub_util_error (_("disk read fails at offset %lld, length %d"), + skip, len); + +- if (hook (skip, buf, len)) ++ if (hook (skip, buf, len, hook_arg)) + break; + + skip += len; +@@ -158,7 +158,7 @@ read_file (char *pathname, int (*hook) (grub_off_t ofs, char *buf, int len)) + break; + } + +- if ((sz == 0) || (hook (ofs, buf, sz))) ++ if ((sz == 0) || (hook (ofs, buf, sz, hook_arg))) + break; + + ofs += sz; +@@ -169,87 +169,99 @@ read_file (char *pathname, int (*hook) (grub_off_t ofs, char *buf, int len)) + grub_file_close (file); + } + +-static void +-cmd_cp (char *src, char *dest) ++struct cp_hook_ctx + { + FILE *ff; ++ const char *dest; ++}; + +- auto int cp_hook (grub_off_t ofs, char *buf, int len); +- int cp_hook (grub_off_t ofs, char *buf, int len) +- { +- (void) ofs; ++static int ++cp_hook (grub_off_t ofs, char *buf, int len, void *_ctx) ++{ ++ struct cp_hook_ctx *ctx = _ctx; ++ (void) ofs; + +- if ((int) fwrite (buf, 1, len, ff) != len) +- { +- grub_util_error (_("cannot write to `%s': %s"), +- dest, strerror (errno)); +- return 1; +- } ++ if ((int) fwrite (buf, 1, len, ctx->ff) != len) ++ { ++ grub_util_error (_("cannot write to `%s': %s"), ++ ctx->dest, strerror (errno)); ++ return 1; ++ } + +- return 0; +- } ++ return 0; ++} + +- ff = fopen (dest, "wb"); +- if (ff == NULL) ++static void ++cmd_cp (char *src, const char *dest) ++{ ++ struct cp_hook_ctx ctx = ++ { ++ .dest = dest ++ }; ++ ++ ctx.ff = fopen (dest, "wb"); ++ if (ctx.ff == NULL) + { + grub_util_error (_("cannot open OS file `%s': %s"), dest, + strerror (errno)); + return; + } +- read_file (src, cp_hook); +- fclose (ff); ++ read_file (src, cp_hook, &ctx); ++ fclose (ctx.ff); ++} ++ ++static int ++cat_hook (grub_off_t ofs, char *buf, int len, void *_arg __attribute__ ((unused))) ++{ ++ (void) ofs; ++ ++ if ((int) fwrite (buf, 1, len, stdout) != len) ++ { ++ grub_util_error (_("cannot write to the stdout: %s"), ++ strerror (errno)); ++ return 1; ++ } ++ ++ return 0; + } + + static void + cmd_cat (char *src) + { +- auto int cat_hook (grub_off_t ofs, char *buf, int len); +- int cat_hook (grub_off_t ofs, char *buf, int len) +- { +- (void) ofs; ++ read_file (src, cat_hook, 0); ++} + +- if ((int) fwrite (buf, 1, len, stdout) != len) +- { +- grub_util_error (_("cannot write to the stdout: %s"), +- strerror (errno)); +- return 1; +- } ++static int ++cmp_hook (grub_off_t ofs, char *buf, int len, void *ff_in) ++{ ++ FILE *ff = ff_in; ++ static char buf_1[BUF_SIZE]; ++ if ((int) fread (buf_1, 1, len, ff) != len) ++ { ++ grub_util_error (_("read error at offset %llu: %s"), ofs, ++ grub_errmsg); ++ return 1; ++ } + +- return 0; +- } ++ if (grub_memcmp (buf, buf_1, len) != 0) ++ { ++ int i; + +- read_file (src, cat_hook); ++ for (i = 0; i < len; i++, ofs++) ++ if (buf_1[i] != buf[i]) ++ { ++ grub_util_error (_("compare fail at offset %llu"), ofs); ++ return 1; ++ } ++ } ++ return 0; + } + ++ + static void + cmd_cmp (char *src, char *dest) + { + FILE *ff; +- static char buf_1[BUF_SIZE]; +- +- auto int cmp_hook (grub_off_t ofs, char *buf, int len); +- int cmp_hook (grub_off_t ofs, char *buf, int len) +- { +- if ((int) fread (buf_1, 1, len, ff) != len) +- { +- grub_util_error (_("read error at offset %llu: %s"), ofs, +- grub_errmsg); +- return 1; +- } +- +- if (grub_memcmp (buf, buf_1, len)) +- { +- int i; +- +- for (i = 0; i < len; i++, ofs++) +- if (buf_1[i] != buf[i]) +- { +- grub_util_error (_("compare fail at offset %llu"), ofs); +- return 1; +- } +- } +- return 0; +- } + + struct stat st; + if (stat (dest, &st) == -1) +@@ -306,7 +318,7 @@ cmd_cmp (char *src, char *dest) + grub_util_error (_("cannot seek `%s': %s"), dest, + strerror (errno)); + +- read_file (src, cmp_hook); ++ read_file (src, cmp_hook, ff); + + { + grub_uint64_t pre; +@@ -318,17 +330,26 @@ cmd_cmp (char *src, char *dest) + fclose (ff); + } + ++static int ++hex_hook (grub_off_t ofs, char *buf, int len, void *arg __attribute__ ((unused))) ++{ ++ hexdump (ofs, buf, len); ++ return 0; ++} ++ + static void + cmd_hex (char *pathname) + { +- auto int hex_hook (grub_off_t ofs, char *buf, int len); +- int hex_hook (grub_off_t ofs, char *buf, int len) +- { +- hexdump (ofs, buf, len); +- return 0; +- } ++ read_file (pathname, hex_hook, 0); ++} + +- read_file (pathname, hex_hook); ++static int ++crc_hook (grub_off_t ofs, char *buf, int len, void *crc_ctx) ++{ ++ (void) ofs; ++ ++ GRUB_MD_CRC32->write(crc_ctx, buf, len); ++ return 0; + } + + static void +@@ -337,16 +358,7 @@ cmd_crc (char *pathname) + grub_uint8_t crc32_context[GRUB_MD_CRC32->contextsize]; + GRUB_MD_CRC32->init(crc32_context); + +- auto int crc_hook (grub_off_t ofs, char *buf, int len); +- int crc_hook (grub_off_t ofs, char *buf, int len) +- { +- (void) ofs; +- +- GRUB_MD_CRC32->write(crc32_context, buf, len); +- return 0; +- } +- +- read_file (pathname, crc_hook); ++ read_file (pathname, crc_hook, crc32_context); + GRUB_MD_CRC32->final(crc32_context); + printf ("%08x\n", + grub_be_to_cpu32 (grub_get_unaligned32 (GRUB_MD_CRC32->read (crc32_context)))); +-- +1.8.1.4 + diff --git a/0164-grub-core-commands-parttool.c-grub_cmd_parttool-Move.patch b/0164-grub-core-commands-parttool.c-grub_cmd_parttool-Move.patch new file mode 100644 index 0000000..b916078 --- /dev/null +++ b/0164-grub-core-commands-parttool.c-grub_cmd_parttool-Move.patch @@ -0,0 +1,147 @@ +From c902417ff9033152f80cfddd55140bb4b216cfa5 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Thu, 28 Feb 2013 09:43:25 +0100 +Subject: [PATCH 164/364] * grub-core/commands/parttool.c + (grub_cmd_parttool): Move show_help out of parent function. + +--- + ChangeLog | 5 +++ + grub-core/commands/parttool.c | 90 ++++++++++++++++++++++--------------------- + 2 files changed, 51 insertions(+), 44 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 06123b6..df5f45b 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,10 @@ + 2013-02-28 Vladimir Serbinenko + ++ * grub-core/commands/parttool.c (grub_cmd_parttool): Move show_help out ++ of parent function. ++ ++2013-02-28 Vladimir Serbinenko ++ + * util/grub-fstest.c: Remove nested functions. + + 2013-02-27 Vladimir Serbinenko +diff --git a/grub-core/commands/parttool.c b/grub-core/commands/parttool.c +index fadf873..0f9b651 100644 +--- a/grub-core/commands/parttool.c ++++ b/grub-core/commands/parttool.c +@@ -95,6 +95,50 @@ grub_parttool_unregister (int handle) + } + + static grub_err_t ++show_help (grub_device_t dev) ++{ ++ int found = 0; ++ struct grub_parttool *cur; ++ ++ for (cur = parts; cur; cur = cur->next) ++ if (grub_strcmp (dev->disk->partition->partmap->name, cur->name) == 0) ++ { ++ struct grub_parttool_argdesc *curarg; ++ found = 1; ++ for (curarg = cur->args; curarg->name; curarg++) ++ { ++ int spacing = 20; ++ ++ spacing -= grub_strlen (curarg->name); ++ grub_printf ("%s", curarg->name); ++ ++ switch (curarg->type) ++ { ++ case GRUB_PARTTOOL_ARG_BOOL: ++ grub_printf ("+/-"); ++ spacing -= 3; ++ break; ++ ++ case GRUB_PARTTOOL_ARG_VAL: ++ grub_xputs (_("=VAL")); ++ spacing -= 4; ++ break; ++ ++ case GRUB_PARTTOOL_ARG_END: ++ break; ++ } ++ while (spacing-- > 0) ++ grub_printf (" "); ++ grub_puts_ (curarg->desc); ++ } ++ } ++ if (! found) ++ grub_printf_ (N_("Sorry no parttool is available for %s\n"), ++ dev->disk->partition->partmap->name); ++ return GRUB_ERR_NONE; ++} ++ ++static grub_err_t + grub_cmd_parttool (grub_command_t cmd __attribute__ ((unused)), + int argc, char **args) + { +@@ -104,48 +148,6 @@ grub_cmd_parttool (grub_command_t cmd __attribute__ ((unused)), + int i, j; + grub_err_t err = GRUB_ERR_NONE; + +- auto grub_err_t show_help (void); +- grub_err_t show_help (void) +- { +- int found = 0; +- for (cur = parts; cur; cur = cur->next) +- if (grub_strcmp (dev->disk->partition->partmap->name, cur->name) == 0) +- { +- struct grub_parttool_argdesc *curarg; +- found = 1; +- for (curarg = cur->args; curarg->name; curarg++) +- { +- int spacing = 20; +- +- spacing -= grub_strlen (curarg->name); +- grub_printf ("%s", curarg->name); +- +- switch (curarg->type) +- { +- case GRUB_PARTTOOL_ARG_BOOL: +- grub_printf ("+/-"); +- spacing -= 3; +- break; +- +- case GRUB_PARTTOOL_ARG_VAL: +- grub_xputs (_("=VAL")); +- spacing -= 4; +- break; +- +- case GRUB_PARTTOOL_ARG_END: +- break; +- } +- while (spacing-- > 0) +- grub_printf (" "); +- grub_puts_ (curarg->desc); +- } +- } +- if (! found) +- grub_printf_ (N_("Sorry no parttool is available for %s\n"), +- dev->disk->partition->partmap->name); +- return GRUB_ERR_NONE; +- } +- + if (argc < 1) + { + grub_puts_ (helpmsg); +@@ -241,11 +243,11 @@ grub_cmd_parttool (grub_command_t cmd __attribute__ ((unused)), + } + + if (argc == 1) +- return show_help (); ++ return show_help (dev); + + for (i = 1; i < argc; i++) + if (grub_strcmp (args[i], "help") == 0) +- return show_help (); ++ return show_help (dev); + + parsed = (int *) grub_zalloc (argc * sizeof (int)); + +-- +1.8.1.4 + diff --git a/0165-grub-core-fs-iso9660.c-Remove-nested-functions.patch b/0165-grub-core-fs-iso9660.c-Remove-nested-functions.patch new file mode 100644 index 0000000..b08c03a --- /dev/null +++ b/0165-grub-core-fs-iso9660.c-Remove-nested-functions.patch @@ -0,0 +1,622 @@ +From 649c9b2ef46f82724c81ed62139f1ac46b4bd758 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Thu, 28 Feb 2013 10:30:35 +0100 +Subject: [PATCH 165/364] * grub-core/fs/iso9660.c: Remove nested + functions. + +--- + ChangeLog | 4 + + grub-core/fs/iso9660.c | 409 +++++++++++++++++++++++++------------------------ + 2 files changed, 209 insertions(+), 204 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index df5f45b..206a094 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,9 @@ + 2013-02-28 Vladimir Serbinenko + ++ * grub-core/fs/iso9660.c: Remove nested functions. ++ ++2013-02-28 Vladimir Serbinenko ++ + * grub-core/commands/parttool.c (grub_cmd_parttool): Move show_help out + of parent function. + +diff --git a/grub-core/fs/iso9660.c b/grub-core/fs/iso9660.c +index 19471e8..01a07b8 100644 +--- a/grub-core/fs/iso9660.c ++++ b/grub-core/fs/iso9660.c +@@ -260,42 +260,26 @@ static grub_err_t + grub_iso9660_susp_iterate (grub_fshelp_node_t node, grub_off_t off, + grub_ssize_t sua_size, + grub_err_t (*hook) +- (struct grub_iso9660_susp_entry *entry)) ++ (struct grub_iso9660_susp_entry *entry, void *hook_arg), ++ void *hook_arg) + { + char *sua; + struct grub_iso9660_susp_entry *entry; +- grub_disk_addr_t ce_block; +- int is_ce = 0; +- +- auto grub_err_t load_sua (void); +- +- /* Load a part of the System Usage Area. */ +- grub_err_t load_sua (void) +- { +- grub_err_t err; +- sua = grub_malloc (sua_size); +- if (!sua) +- return grub_errno; +- +- if (is_ce) +- err = grub_disk_read (node->data->disk, ce_block, off, +- sua_size, sua); +- else +- err = read_node (node, off, sua_size, sua); +- if (err) +- return err; +- +- entry = (struct grub_iso9660_susp_entry *) sua; +- return 0; +- } ++ grub_err_t err; + + if (sua_size <= 0) + return GRUB_ERR_NONE; + +- if (load_sua ()) ++ sua = grub_malloc (sua_size); ++ if (!sua) + return grub_errno; + +- for (; (char *) entry < (char *) sua + sua_size - 1 && entry->len > 0; ++ /* Load a part of the System Usage Area. */ ++ err = read_node (node, off, sua_size, sua); ++ if (err) ++ return err; ++ ++ for (entry = (struct grub_iso9660_susp_entry *) sua; (char *) entry < (char *) sua + sua_size - 1 && entry->len > 0; + entry = (struct grub_iso9660_susp_entry *) + ((char *) entry + entry->len)) + { +@@ -307,19 +291,28 @@ grub_iso9660_susp_iterate (grub_fshelp_node_t node, grub_off_t off, + if (grub_strncmp ((char *) entry->sig, "CE", 2) == 0) + { + struct grub_iso9660_susp_ce *ce; ++ grub_disk_addr_t ce_block; + +- is_ce = 1; + ce = (struct grub_iso9660_susp_ce *) entry; + sua_size = grub_le_to_cpu32 (ce->len); + off = grub_le_to_cpu32 (ce->off); + ce_block = grub_le_to_cpu32 (ce->blk) << GRUB_ISO9660_LOG2_BLKSZ; + + grub_free (sua); +- if (load_sua ()) ++ sua = grub_malloc (sua_size); ++ if (!sua) + return grub_errno; ++ ++ /* Load a part of the System Usage Area. */ ++ err = grub_disk_read (node->data->disk, ce_block, off, ++ sua_size, sua); ++ if (err) ++ return err; ++ ++ entry = (struct grub_iso9660_susp_entry *) sua; + } + +- if (hook (entry)) ++ if (hook (entry, hook_arg)) + { + grub_free (sua); + return 0; +@@ -350,6 +343,21 @@ grub_iso9660_convert_string (grub_uint8_t *us, int len) + } + + static grub_err_t ++susp_iterate_set_rockridge (struct grub_iso9660_susp_entry *susp_entry, ++ void *_data) ++{ ++ struct grub_iso9660_data *data = _data; ++ /* The "ER" entry is used to detect extensions. The ++ `IEEE_P1285' extension means Rock ridge. */ ++ if (grub_strncmp ((char *) susp_entry->sig, "ER", 2) == 0) ++ { ++ data->rockridge = 1; ++ return 1; ++ } ++ return 0; ++} ++ ++static grub_err_t + set_rockridge (struct grub_iso9660_data *data) + { + int sua_pos; +@@ -358,20 +366,6 @@ set_rockridge (struct grub_iso9660_data *data) + struct grub_iso9660_dir rootdir; + struct grub_iso9660_susp_entry *entry; + +- auto grub_err_t susp_iterate (struct grub_iso9660_susp_entry *); +- +- grub_err_t susp_iterate (struct grub_iso9660_susp_entry *susp_entry) +- { +- /* The "ER" entry is used to detect extensions. The +- `IEEE_P1285' extension means Rock ridge. */ +- if (grub_strncmp ((char *) susp_entry->sig, "ER", 2) == 0) +- { +- data->rockridge = 1; +- return 1; +- } +- return 0; +- } +- + data->rockridge = 0; + + /* Read the system use area and test it to see if SUSP is +@@ -423,7 +417,8 @@ set_rockridge (struct grub_iso9660_data *data) + /* Iterate over the entries in the SUA area to detect + extensions. */ + if (grub_iso9660_susp_iterate (&rootnode, +- sua_pos, sua_size, susp_iterate)) ++ sua_pos, sua_size, susp_iterate_set_rockridge, ++ data)) + { + grub_free (sua); + return grub_errno; +@@ -519,154 +514,160 @@ get_node_size (grub_fshelp_node_t node) + return ret; + } + +-static int +-grub_iso9660_iterate_dir (grub_fshelp_node_t dir, +- grub_fshelp_iterate_dir_hook_t hook, void *hook_data) ++struct iterate_dir_ctx + { +- struct grub_iso9660_dir dirent; +- grub_off_t offset = 0; +- char *filename = 0; +- int filename_alloc = 0; ++ char *filename; ++ int filename_alloc; + enum grub_fshelp_filetype type; +- grub_off_t len; +- char *symlink = 0; +- int was_continue = 0; ++ char *symlink; ++ int was_continue; ++}; + + /* Extend the symlink. */ +- auto inline void __attribute__ ((always_inline)) add_part (const char *part, +- int len2); +- +- auto inline void __attribute__ ((always_inline)) add_part (const char *part, +- int len2) +- { +- int size = symlink ? grub_strlen (symlink) : 0; ++static void __attribute__ ((always_inline)) ++add_part (struct iterate_dir_ctx *ctx, ++ const char *part, ++ int len2) ++{ ++ int size = ctx->symlink ? grub_strlen (ctx->symlink) : 0; + +- symlink = grub_realloc (symlink, size + len2 + 1); +- if (! symlink) +- return; ++ ctx->symlink = grub_realloc (ctx->symlink, size + len2 + 1); ++ if (! ctx->symlink) ++ return; + +- symlink[size] = 0; +- grub_strncat (symlink, part, len2); +- } ++ ctx->symlink[size] = 0; ++ grub_strncat (ctx->symlink, part, len2); ++} + +- auto grub_err_t susp_iterate_dir (struct grub_iso9660_susp_entry *); ++static grub_err_t ++susp_iterate_dir (struct grub_iso9660_susp_entry *entry, ++ void *_ctx) ++{ ++ struct iterate_dir_ctx *ctx = _ctx; + +- grub_err_t susp_iterate_dir (struct grub_iso9660_susp_entry *entry) ++ /* The filename in the rock ridge entry. */ ++ if (grub_strncmp ("NM", (char *) entry->sig, 2) == 0) + { +- /* The filename in the rock ridge entry. */ +- if (grub_strncmp ("NM", (char *) entry->sig, 2) == 0) ++ /* The flags are stored at the data position 0, here the ++ filename type is stored. */ ++ /* FIXME: Fix this slightly improper cast. */ ++ if (entry->data[0] & GRUB_ISO9660_RR_DOT) ++ ctx->filename = (char *) "."; ++ else if (entry->data[0] & GRUB_ISO9660_RR_DOTDOT) ++ ctx->filename = (char *) ".."; ++ else if (entry->len >= 5) + { +- /* The flags are stored at the data position 0, here the +- filename type is stored. */ +- /* FIXME: Fix this slightly improper cast. */ +- if (entry->data[0] & GRUB_ISO9660_RR_DOT) +- filename = (char *) "."; +- else if (entry->data[0] & GRUB_ISO9660_RR_DOTDOT) +- filename = (char *) ".."; +- else if (entry->len >= 5) ++ grub_size_t size = 1, csize = 1; ++ char *old; ++ csize = size = entry->len - 5; ++ old = ctx->filename; ++ if (ctx->filename_alloc) ++ { ++ size += grub_strlen (ctx->filename); ++ ctx->filename = grub_realloc (ctx->filename, size + 1); ++ } ++ else ++ { ++ ctx->filename_alloc = 1; ++ ctx->filename = grub_zalloc (size + 1); ++ ctx->filename[0] = 0; ++ } ++ if (!ctx->filename) + { +- grub_size_t size = 1, csize = 1; +- char *old; +- csize = size = entry->len - 5; +- old = filename; +- if (filename_alloc) +- { +- size += grub_strlen (filename); +- filename = grub_realloc (filename, size + 1); +- } +- else +- { +- filename_alloc = 1; +- filename = grub_zalloc (size + 1); +- filename[0] = 0; +- } +- if (!filename) +- { +- filename = old; +- return grub_errno; +- } +- filename_alloc = 1; +- grub_strncat (filename, (char *) &entry->data[1], csize); +- filename[size] = '\0'; ++ ctx->filename = old; ++ return grub_errno; + } ++ ctx->filename_alloc = 1; ++ grub_strncat (ctx->filename, (char *) &entry->data[1], csize); ++ ctx->filename[size] = '\0'; + } +- /* The mode information (st_mode). */ +- else if (grub_strncmp ((char *) entry->sig, "PX", 2) == 0) ++ } ++ /* The mode information (st_mode). */ ++ else if (grub_strncmp ((char *) entry->sig, "PX", 2) == 0) ++ { ++ /* At position 0 of the PX record the st_mode information is ++ stored (little-endian). */ ++ grub_uint32_t mode = ((entry->data[0] + (entry->data[1] << 8)) ++ & GRUB_ISO9660_FSTYPE_MASK); ++ ++ switch (mode) + { +- /* At position 0 of the PX record the st_mode information is +- stored (little-endian). */ +- grub_uint32_t mode = ((entry->data[0] + (entry->data[1] << 8)) +- & GRUB_ISO9660_FSTYPE_MASK); ++ case GRUB_ISO9660_FSTYPE_DIR: ++ ctx->type = GRUB_FSHELP_DIR; ++ break; ++ case GRUB_ISO9660_FSTYPE_REG: ++ ctx->type = GRUB_FSHELP_REG; ++ break; ++ case GRUB_ISO9660_FSTYPE_SYMLINK: ++ ctx->type = GRUB_FSHELP_SYMLINK; ++ break; ++ default: ++ ctx->type = GRUB_FSHELP_UNKNOWN; ++ } ++ } ++ else if (grub_strncmp ("SL", (char *) entry->sig, 2) == 0) ++ { ++ unsigned int pos = 1; + +- switch (mode) ++ /* The symlink is not stored as a POSIX symlink, translate it. */ ++ while (pos + sizeof (*entry) < entry->len) ++ { ++ /* The current position is the `Component Flag'. */ ++ switch (entry->data[pos] & 30) + { +- case GRUB_ISO9660_FSTYPE_DIR: +- type = GRUB_FSHELP_DIR; ++ case 0: ++ { ++ /* The data on pos + 2 is the actual data, pos + 1 ++ is the length. Both are part of the `Component ++ Record'. */ ++ if (ctx->symlink && !ctx->was_continue) ++ add_part (ctx, "/", 1); ++ add_part (ctx, (char *) &entry->data[pos + 2], ++ entry->data[pos + 1]); ++ ctx->was_continue = (entry->data[pos] & 1); ++ break; ++ } ++ ++ case 2: ++ add_part (ctx, "./", 2); + break; +- case GRUB_ISO9660_FSTYPE_REG: +- type = GRUB_FSHELP_REG; ++ ++ case 4: ++ add_part (ctx, "../", 3); + break; +- case GRUB_ISO9660_FSTYPE_SYMLINK: +- type = GRUB_FSHELP_SYMLINK; ++ ++ case 8: ++ add_part (ctx, "/", 1); + break; +- default: +- type = GRUB_FSHELP_UNKNOWN; + } ++ /* In pos + 1 the length of the `Component Record' is ++ stored. */ ++ pos += entry->data[pos + 1] + 2; + } +- else if (grub_strncmp ("SL", (char *) entry->sig, 2) == 0) +- { +- unsigned int pos = 1; +- +- /* The symlink is not stored as a POSIX symlink, translate it. */ +- while (pos + sizeof (*entry) < entry->len) +- { +- /* The current position is the `Component Flag'. */ +- switch (entry->data[pos] & 30) +- { +- case 0: +- { +- /* The data on pos + 2 is the actual data, pos + 1 +- is the length. Both are part of the `Component +- Record'. */ +- if (symlink && !was_continue) +- add_part ("/", 1); +- add_part ((char *) &entry->data[pos + 2], +- entry->data[pos + 1]); +- was_continue = (entry->data[pos] & 1); +- break; +- } + +- case 2: +- add_part ("./", 2); +- break; +- +- case 4: +- add_part ("../", 3); +- break; +- +- case 8: +- add_part ("/", 1); +- break; +- } +- /* In pos + 1 the length of the `Component Record' is +- stored. */ +- pos += entry->data[pos + 1] + 2; +- } ++ /* Check if `grub_realloc' failed. */ ++ if (grub_errno) ++ return grub_errno; ++ } + +- /* Check if `grub_realloc' failed. */ +- if (grub_errno) +- return grub_errno; +- } ++ return 0; ++} + +- return 0; +- } ++static int ++grub_iso9660_iterate_dir (grub_fshelp_node_t dir, ++ grub_fshelp_iterate_dir_hook_t hook, void *hook_data) ++{ ++ struct grub_iso9660_dir dirent; ++ grub_off_t offset = 0; ++ grub_off_t len; ++ struct iterate_dir_ctx ctx; + + len = get_node_size (dir); + + for (; offset < len; offset += dirent.len) + { +- symlink = 0; +- was_continue = 0; ++ ctx.symlink = 0; ++ ctx.was_continue = 0; + + if (read_node (dir, offset, sizeof (dirent), (char *) &dirent)) + return 0; +@@ -688,13 +689,13 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir, + + sua_off += offset + dir->data->susp_skip; + +- filename = 0; +- filename_alloc = 0; +- type = GRUB_FSHELP_UNKNOWN; ++ ctx.filename = 0; ++ ctx.filename_alloc = 0; ++ ctx.type = GRUB_FSHELP_UNKNOWN; + + if (dir->data->rockridge + && grub_iso9660_susp_iterate (dir, sua_off, sua_size, +- susp_iterate_dir)) ++ susp_iterate_dir, &ctx)) + return 0; + + /* Read the name. */ +@@ -714,55 +715,55 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir, + + /* If the filetype was not stored using rockridge, use + whatever is stored in the iso9660 filesystem. */ +- if (type == GRUB_FSHELP_UNKNOWN) ++ if (ctx.type == GRUB_FSHELP_UNKNOWN) + { + if ((dirent.flags & FLAG_TYPE) == FLAG_TYPE_DIR) +- type = GRUB_FSHELP_DIR; ++ ctx.type = GRUB_FSHELP_DIR; + else +- type = GRUB_FSHELP_REG; ++ ctx.type = GRUB_FSHELP_REG; + } + + /* . and .. */ +- if (!filename && dirent.namelen == 1 && name[0] == 0) +- filename = (char *) "."; ++ if (!ctx.filename && dirent.namelen == 1 && name[0] == 0) ++ ctx.filename = (char *) "."; + +- if (!filename && dirent.namelen == 1 && name[0] == 1) +- filename = (char *) ".."; ++ if (!ctx.filename && dirent.namelen == 1 && name[0] == 1) ++ ctx.filename = (char *) ".."; + + /* The filename was not stored in a rock ridge entry. Read it + from the iso9660 filesystem. */ +- if (!dir->data->joliet && !filename) ++ if (!dir->data->joliet && !ctx.filename) + { + char *ptr; + name[dirent.namelen] = '\0'; +- filename = grub_strrchr (name, ';'); +- if (filename) +- *filename = '\0'; ++ ctx.filename = grub_strrchr (name, ';'); ++ if (ctx.filename) ++ *ctx.filename = '\0'; + /* ISO9660 names are not case-preserving. */ +- type |= GRUB_FSHELP_CASE_INSENSITIVE; ++ ctx.type |= GRUB_FSHELP_CASE_INSENSITIVE; + for (ptr = name; *ptr; ptr++) + *ptr = grub_tolower (*ptr); + if (ptr != name && *(ptr - 1) == '.') + *(ptr - 1) = 0; +- filename = name; ++ ctx.filename = name; + } + +- if (dir->data->joliet && !filename) ++ if (dir->data->joliet && !ctx.filename) + { + char *oldname, *semicolon; + + oldname = name; +- filename = grub_iso9660_convert_string ++ ctx.filename = grub_iso9660_convert_string + ((grub_uint8_t *) oldname, dirent.namelen >> 1); + +- semicolon = grub_strrchr (filename, ';'); ++ semicolon = grub_strrchr (ctx.filename, ';'); + if (semicolon) + *semicolon = '\0'; + +- if (filename_alloc) ++ if (ctx.filename_alloc) + grub_free (oldname); + +- filename_alloc = 1; ++ ctx.filename_alloc = 1; + } + + node->dirents[0] = dirent; +@@ -771,8 +772,8 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir, + offset += dirent.len; + if (read_node (dir, offset, sizeof (dirent), (char *) &dirent)) + { +- if (filename_alloc) +- grub_free (filename); ++ if (ctx.filename_alloc) ++ grub_free (ctx.filename); + grub_free (node); + return 0; + } +@@ -787,8 +788,8 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir, + * sizeof (node->dirents[0]))); + if (!new_node) + { +- if (filename_alloc) +- grub_free (filename); ++ if (ctx.filename_alloc) ++ grub_free (ctx.filename); + grub_free (node); + return 0; + } +@@ -796,10 +797,10 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir, + } + node->dirents[node->have_dirents++] = dirent; + } +- if (symlink) ++ if (ctx.symlink) + { + if ((node->alloc_dirents - node->have_dirents) +- * sizeof (node->dirents[0]) < grub_strlen (symlink) + 1) ++ * sizeof (node->dirents[0]) < grub_strlen (ctx.symlink) + 1) + { + struct grub_fshelp_node *new_node; + new_node = grub_realloc (node, +@@ -807,11 +808,11 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir, + + ((node->alloc_dirents + - ARRAY_SIZE (node->dirents)) + * sizeof (node->dirents[0])) +- + grub_strlen (symlink) + 1); ++ + grub_strlen (ctx.symlink) + 1); + if (!new_node) + { +- if (filename_alloc) +- grub_free (filename); ++ if (ctx.filename_alloc) ++ grub_free (ctx.filename); + grub_free (node); + return 0; + } +@@ -820,19 +821,19 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir, + node->have_symlink = 1; + grub_strcpy (node->symlink + + node->have_dirents * sizeof (node->dirents[0]) +- - sizeof (node->dirents), symlink); +- grub_free (symlink); +- symlink = 0; +- was_continue = 0; ++ - sizeof (node->dirents), ctx.symlink); ++ grub_free (ctx.symlink); ++ ctx.symlink = 0; ++ ctx.was_continue = 0; + } +- if (hook (filename, type, node, hook_data)) ++ if (hook (ctx.filename, ctx.type, node, hook_data)) + { +- if (filename_alloc) +- grub_free (filename); ++ if (ctx.filename_alloc) ++ grub_free (ctx.filename); + return 1; + } +- if (filename_alloc) +- grub_free (filename); ++ if (ctx.filename_alloc) ++ grub_free (ctx.filename); + } + } + +-- +1.8.1.4 + diff --git a/0166-grub-core-fs-minix.c-Remove-nested-functions.patch b/0166-grub-core-fs-minix.c-Remove-nested-functions.patch new file mode 100644 index 0000000..c0ea5cc --- /dev/null +++ b/0166-grub-core-fs-minix.c-Remove-nested-functions.patch @@ -0,0 +1,111 @@ +From a870b5f756cc03e163a0ed2a44276bac9ffd1f94 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Thu, 28 Feb 2013 10:50:01 +0100 +Subject: [PATCH 166/364] * grub-core/fs/minix.c: Remove nested + functions. + +--- + ChangeLog | 4 ++++ + grub-core/fs/minix.c | 41 ++++++++++++++++++++--------------------- + 2 files changed, 24 insertions(+), 21 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 206a094..056de9d 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,9 @@ + 2013-02-28 Vladimir Serbinenko + ++ * grub-core/fs/minix.c: Remove nested functions. ++ ++2013-02-28 Vladimir Serbinenko ++ + * grub-core/fs/iso9660.c: Remove nested functions. + + 2013-02-28 Vladimir Serbinenko +diff --git a/grub-core/fs/minix.c b/grub-core/fs/minix.c +index 918fe56..225770a 100644 +--- a/grub-core/fs/minix.c ++++ b/grub-core/fs/minix.c +@@ -178,6 +178,20 @@ static grub_dl_t my_mod; + static grub_err_t grub_minix_find_file (struct grub_minix_data *data, + const char *path); + ++ /* Read the block pointer in ZONE, on the offset NUM. */ ++static grub_minix_uintn_t ++grub_get_indir (struct grub_minix_data *data, ++ grub_minix_uintn_t zone, ++ grub_minix_uintn_t num) ++{ ++ grub_minix_uintn_t indirn; ++ grub_disk_read (data->disk, ++ GRUB_MINIX_ZONE2SECT(zone), ++ sizeof (grub_minix_uintn_t) * num, ++ sizeof (grub_minix_uintn_t), (char *) &indirn); ++ return grub_minix_to_cpu_n (indirn); ++} ++ + static grub_minix_uintn_t + grub_minix_get_file_block (struct grub_minix_data *data, unsigned int blk) + { +@@ -185,21 +199,6 @@ grub_minix_get_file_block (struct grub_minix_data *data, unsigned int blk) + const grub_uint32_t block_per_zone = (GRUB_MINIX_ZONESZ + / GRUB_MINIX_INODE_BLKSZ (data)); + +- auto grub_minix_uintn_t grub_get_indir (grub_minix_uintn_t, +- grub_minix_uintn_t); +- +- /* Read the block pointer in ZONE, on the offset NUM. */ +- grub_minix_uintn_t grub_get_indir (grub_minix_uintn_t zone, +- grub_minix_uintn_t num) +- { +- grub_minix_uintn_t indirn; +- grub_disk_read (data->disk, +- GRUB_MINIX_ZONE2SECT(zone), +- sizeof (grub_minix_uintn_t) * num, +- sizeof (grub_minix_uintn_t), (char *) &indirn); +- return grub_minix_to_cpu_n (indirn); +- } +- + /* Direct block. */ + if (blk < GRUB_MINIX_INODE_DIR_BLOCKS) + return GRUB_MINIX_INODE_DIR_ZONES (data, blk); +@@ -208,7 +207,7 @@ grub_minix_get_file_block (struct grub_minix_data *data, unsigned int blk) + blk -= GRUB_MINIX_INODE_DIR_BLOCKS; + if (blk < block_per_zone) + { +- indir = grub_get_indir (GRUB_MINIX_INODE_INDIR_ZONE (data), blk); ++ indir = grub_get_indir (data, GRUB_MINIX_INODE_INDIR_ZONE (data), blk); + return indir; + } + +@@ -216,10 +215,10 @@ grub_minix_get_file_block (struct grub_minix_data *data, unsigned int blk) + blk -= block_per_zone; + if (blk < block_per_zone * block_per_zone) + { +- indir = grub_get_indir (GRUB_MINIX_INODE_DINDIR_ZONE (data), ++ indir = grub_get_indir (data, GRUB_MINIX_INODE_DINDIR_ZONE (data), + blk / block_per_zone); + +- indir = grub_get_indir (indir, blk % block_per_zone); ++ indir = grub_get_indir (data, indir, blk % block_per_zone); + + return indir; + } +@@ -229,10 +228,10 @@ grub_minix_get_file_block (struct grub_minix_data *data, unsigned int blk) + if (blk < ((grub_uint64_t) block_per_zone * (grub_uint64_t) block_per_zone + * (grub_uint64_t) block_per_zone)) + { +- indir = grub_get_indir (grub_minix_to_cpu_n (data->inode.triple_indir_zone), ++ indir = grub_get_indir (data, grub_minix_to_cpu_n (data->inode.triple_indir_zone), + (blk / block_per_zone) / block_per_zone); +- indir = grub_get_indir (indir, (blk / block_per_zone) % block_per_zone); +- indir = grub_get_indir (indir, blk % block_per_zone); ++ indir = grub_get_indir (data, indir, (blk / block_per_zone) % block_per_zone); ++ indir = grub_get_indir (data, indir, blk % block_per_zone); + + return indir; + } +-- +1.8.1.4 + diff --git a/0167-grub-core-fs-jfs.c-Remove-nested-functions.patch b/0167-grub-core-fs-jfs.c-Remove-nested-functions.patch new file mode 100644 index 0000000..621e340 --- /dev/null +++ b/0167-grub-core-fs-jfs.c-Remove-nested-functions.patch @@ -0,0 +1,189 @@ +From f360e6e4d10c7f304127c50e03fd1c84c226f65e Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Thu, 28 Feb 2013 10:51:32 +0100 +Subject: [PATCH 167/364] * grub-core/fs/jfs.c: Remove nested functions. + +--- + ChangeLog | 4 ++ + grub-core/fs/jfs.c | 113 +++++++++++++++++++++++++++-------------------------- + 2 files changed, 61 insertions(+), 56 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 056de9d..6601c42 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,9 @@ + 2013-02-28 Vladimir Serbinenko + ++ * grub-core/fs/jfs.c: Remove nested functions. ++ ++2013-02-28 Vladimir Serbinenko ++ + * grub-core/fs/minix.c: Remove nested functions. + + 2013-02-28 Vladimir Serbinenko +diff --git a/grub-core/fs/jfs.c b/grub-core/fs/jfs.c +index 88b21ad..4122eff 100644 +--- a/grub-core/fs/jfs.c ++++ b/grub-core/fs/jfs.c +@@ -255,60 +255,60 @@ static grub_dl_t my_mod; + + static grub_err_t grub_jfs_lookup_symlink (struct grub_jfs_data *data, grub_uint32_t ino); + +-/* Get the block number for the block BLK in the node INODE in the +- mounted filesystem DATA. */ + static grub_int64_t +-grub_jfs_blkno (struct grub_jfs_data *data, struct grub_jfs_inode *inode, +- grub_uint64_t blk) ++getblk (struct grub_jfs_treehead *treehead, ++ struct grub_jfs_tree_extent *extents, ++ struct grub_jfs_data *data, ++ grub_uint64_t blk) + { +- auto grub_int64_t getblk (struct grub_jfs_treehead *treehead, +- struct grub_jfs_tree_extent *extents); ++ int found = -1; ++ int i; + +- grub_int64_t getblk (struct grub_jfs_treehead *treehead, +- struct grub_jfs_tree_extent *extents) ++ for (i = 0; i < grub_le_to_cpu16 (treehead->count) - 2; i++) + { +- int found = -1; +- int i; +- +- for (i = 0; i < grub_le_to_cpu16 (treehead->count) - 2; i++) ++ if (treehead->flags & GRUB_JFS_TREE_LEAF) + { +- if (treehead->flags & GRUB_JFS_TREE_LEAF) +- { +- /* Read the leafnode. */ +- if (grub_le_to_cpu32 (extents[i].offset2) <= blk +- && ((grub_le_to_cpu16 (extents[i].extent.length)) +- + (extents[i].extent.length2 << 16) +- + grub_le_to_cpu32 (extents[i].offset2)) > blk) +- return (blk - grub_le_to_cpu32 (extents[i].offset2) +- + grub_le_to_cpu32 (extents[i].extent.blk2)); +- } +- else +- if (blk >= grub_le_to_cpu32 (extents[i].offset2)) +- found = i; ++ /* Read the leafnode. */ ++ if (grub_le_to_cpu32 (extents[i].offset2) <= blk ++ && ((grub_le_to_cpu16 (extents[i].extent.length)) ++ + (extents[i].extent.length2 << 16) ++ + grub_le_to_cpu32 (extents[i].offset2)) > blk) ++ return (blk - grub_le_to_cpu32 (extents[i].offset2) ++ + grub_le_to_cpu32 (extents[i].extent.blk2)); + } ++ else ++ if (blk >= grub_le_to_cpu32 (extents[i].offset2)) ++ found = i; ++ } + +- if (found != -1) +- { +- struct +- { +- struct grub_jfs_treehead treehead; +- struct grub_jfs_tree_extent extents[254]; +- } tree; +- +- if (grub_disk_read (data->disk, +- ((grub_disk_addr_t) grub_le_to_cpu32 (extents[found].extent.blk2)) +- << (grub_le_to_cpu16 (data->sblock.log2_blksz) +- - GRUB_DISK_SECTOR_BITS), 0, +- sizeof (tree), (char *) &tree)) +- return -1; +- +- return getblk (&tree.treehead, &tree.extents[0]); +- } ++ if (found != -1) ++ { ++ struct ++ { ++ struct grub_jfs_treehead treehead; ++ struct grub_jfs_tree_extent extents[254]; ++ } tree; ++ ++ if (grub_disk_read (data->disk, ++ ((grub_disk_addr_t) grub_le_to_cpu32 (extents[found].extent.blk2)) ++ << (grub_le_to_cpu16 (data->sblock.log2_blksz) ++ - GRUB_DISK_SECTOR_BITS), 0, ++ sizeof (tree), (char *) &tree)) ++ return -1; + +- return -1; ++ return getblk (&tree.treehead, &tree.extents[0], data, blk); + } + +- return getblk (&inode->file.tree, &inode->file.extents[0]); ++ return -1; ++} ++ ++/* Get the block number for the block BLK in the node INODE in the ++ mounted filesystem DATA. */ ++static grub_int64_t ++grub_jfs_blkno (struct grub_jfs_data *data, struct grub_jfs_inode *inode, ++ grub_uint64_t blk) ++{ ++ return getblk (&inode->file.tree, &inode->file.extents[0], data, blk); + } + + +@@ -489,6 +489,13 @@ grub_jfs_closedir (struct grub_jfs_diropen *diro) + grub_free (diro); + } + ++static void ++le_to_cpu16_copy (grub_uint16_t *out, grub_uint16_t *in, grub_size_t len) ++{ ++ while (len--) ++ *out++ = grub_le_to_cpu16 (*in++); ++} ++ + + /* Read in the next dirent from the directory described by DIRO. */ + static grub_err_t +@@ -501,15 +508,6 @@ grub_jfs_getent (struct grub_jfs_diropen *diro) + int nextent; + grub_uint16_t filename[256]; + +- auto void addstr (grub_uint16_t *uname, int ulen); +- +- /* Add the unicode string to the utf16 filename buffer. */ +- void addstr (grub_uint16_t *name, int ulen) +- { +- while (ulen--) +- filename[strpos++] = grub_le_to_cpu16 (*(name++)); +- } +- + /* The last node, read in more. */ + if (diro->index == diro->count) + { +@@ -547,8 +545,10 @@ grub_jfs_getent (struct grub_jfs_diropen *diro) + return grub_jfs_getent (diro); + } + +- addstr (leaf->namepart, len < diro->data->namecomponentlen ? len +- : diro->data->namecomponentlen); ++ le_to_cpu16_copy (filename + strpos, leaf->namepart, len < diro->data->namecomponentlen ? len ++ : diro->data->namecomponentlen); ++ strpos += len < diro->data->namecomponentlen ? len ++ : diro->data->namecomponentlen; + diro->ino = grub_le_to_cpu32 (leaf->inode); + len -= diro->data->namecomponentlen; + +@@ -558,7 +558,8 @@ grub_jfs_getent (struct grub_jfs_diropen *diro) + do + { + next_leaf = &diro->next_leaf[nextent]; +- addstr (next_leaf->namepart, len < 15 ? len : 15 ); ++ le_to_cpu16_copy (filename + strpos, next_leaf->namepart, len < 15 ? len : 15); ++ strpos += len < 15 ? len : 15; + + len -= 15; + nextent = next_leaf->next; +-- +1.8.1.4 + diff --git a/0168-grub-core-lib-arg.c-grub_arg_show_help-Move-showargs.patch b/0168-grub-core-lib-arg.c-grub_arg_show_help-Move-showargs.patch new file mode 100644 index 0000000..51be0e6 --- /dev/null +++ b/0168-grub-core-lib-arg.c-grub_arg_show_help-Move-showargs.patch @@ -0,0 +1,153 @@ +From 34611e94df43293bd6fa318ffb61dd73a2501fae Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Thu, 28 Feb 2013 11:00:59 +0100 +Subject: [PATCH 168/364] * grub-core/lib/arg.c (grub_arg_show_help): + Move showargs out of its parent. + +--- + ChangeLog | 5 +++ + grub-core/lib/arg.c | 99 +++++++++++++++++++++++++++-------------------------- + 2 files changed, 55 insertions(+), 49 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 6601c42..21ec9a9 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,10 @@ + 2013-02-28 Vladimir Serbinenko + ++ * grub-core/lib/arg.c (grub_arg_show_help): Move showargs ++ out of its parent. ++ ++2013-02-28 Vladimir Serbinenko ++ + * grub-core/fs/jfs.c: Remove nested functions. + + 2013-02-28 Vladimir Serbinenko +diff --git a/grub-core/lib/arg.c b/grub-core/lib/arg.c +index a2d9416..da44e30 100644 +--- a/grub-core/lib/arg.c ++++ b/grub-core/lib/arg.c +@@ -109,69 +109,70 @@ show_usage (grub_extcmd_t cmd) + grub_printf ("%s %s %s\n", _("Usage:"), cmd->cmd->name, _(cmd->cmd->summary)); + } + +-void +-grub_arg_show_help (grub_extcmd_t cmd) ++static void ++showargs (const struct grub_arg_option *opt, ++ int h_is_used, int u_is_used) + { +- auto void showargs (const struct grub_arg_option *opt); +- int h_is_used = 0; +- int u_is_used = 0; +- +- auto void showargs (const struct grub_arg_option *opt) ++ for (; opt->doc; opt++) + { +- for (; opt->doc; opt++) ++ int spacing = 20; ++ ++ if (opt->shortarg && grub_isgraph (opt->shortarg)) ++ grub_printf ("-%c%c ", opt->shortarg, opt->longarg ? ',':' '); ++ else if (opt == help_options && ! h_is_used) ++ grub_printf ("-h, "); ++ else if (opt == help_options + 1 && ! u_is_used) ++ grub_printf ("-u, "); ++ else ++ grub_printf (" "); ++ ++ if (opt->longarg) + { +- int spacing = 20; +- +- if (opt->shortarg && grub_isgraph (opt->shortarg)) +- grub_printf ("-%c%c ", opt->shortarg, opt->longarg ? ',':' '); +- else if (opt == help_options && ! h_is_used) +- grub_printf ("-h, "); +- else if (opt == help_options + 1 && ! u_is_used) +- grub_printf ("-u, "); +- else +- grub_printf (" "); ++ grub_printf ("--%s", opt->longarg); ++ spacing -= grub_strlen (opt->longarg) + 2; + +- if (opt->longarg) ++ if (opt->arg) + { +- grub_printf ("--%s", opt->longarg); +- spacing -= grub_strlen (opt->longarg) + 2; +- +- if (opt->arg) +- { +- grub_printf ("=%s", opt->arg); +- spacing -= grub_strlen (opt->arg) + 1; +- } ++ grub_printf ("=%s", opt->arg); ++ spacing -= grub_strlen (opt->arg) + 1; + } ++ } + +- if (spacing < 0) +- spacing = 3; +- +- while (spacing--) +- grub_xputs (" "); +- +- grub_printf ("%s\n", _(opt->doc)); +- +- switch (opt->shortarg) +- { +- case 'h': +- h_is_used = 1; +- break; ++ if (spacing < 0) ++ spacing = 3; + +- case 'u': +- u_is_used = 1; +- break; ++ while (spacing--) ++ grub_xputs (" "); + +- default: +- break; +- } +- } ++ grub_printf ("%s\n", _(opt->doc)); + } ++} ++ ++void ++grub_arg_show_help (grub_extcmd_t cmd) ++{ ++ int h_is_used = 0; ++ int u_is_used = 0; ++ const struct grub_arg_option *opt; + + show_usage (cmd); + grub_printf ("%s\n\n", _(cmd->cmd->description)); ++ ++ for (opt = cmd->options; opt->doc; opt++) ++ switch (opt->shortarg) ++ { ++ case 'h': ++ h_is_used = 1; ++ break; ++ ++ case 'u': ++ u_is_used = 1; ++ break; ++ } ++ + if (cmd->options) +- showargs (cmd->options); +- showargs (help_options); ++ showargs (cmd->options, h_is_used, u_is_used); ++ showargs (help_options, h_is_used, u_is_used); + #if 0 + grub_printf ("\nReport bugs to <%s>.\n", PACKAGE_BUGREPORT); + #endif +-- +1.8.1.4 + diff --git a/0169-grub-core-kern-i386-coreboot-mmap.c-grub_linuxbios_t.patch b/0169-grub-core-kern-i386-coreboot-mmap.c-grub_linuxbios_t.patch new file mode 100644 index 0000000..7d1fc2d --- /dev/null +++ b/0169-grub-core-kern-i386-coreboot-mmap.c-grub_linuxbios_t.patch @@ -0,0 +1,66 @@ +From ab5a005a1cf0d03e88efb2a2853ed4668986a325 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Thu, 28 Feb 2013 13:16:39 +0100 +Subject: [PATCH 169/364] * grub-core/kern/i386/coreboot/mmap.c + (grub_linuxbios_table_iterate): Fix end of table condition. + +--- + ChangeLog | 5 +++++ + grub-core/kern/i386/coreboot/mmap.c | 6 ++++-- + include/grub/i386/coreboot/lbio.h | 8 ++++++-- + 3 files changed, 15 insertions(+), 4 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 21ec9a9..0eb0516 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,10 @@ + 2013-02-28 Vladimir Serbinenko + ++ * grub-core/kern/i386/coreboot/mmap.c (grub_linuxbios_table_iterate): ++ Fix end of table condition. ++ ++2013-02-28 Vladimir Serbinenko ++ + * grub-core/lib/arg.c (grub_arg_show_help): Move showargs + out of its parent. + +diff --git a/grub-core/kern/i386/coreboot/mmap.c b/grub-core/kern/i386/coreboot/mmap.c +index ae4af08..47efb72 100644 +--- a/grub-core/kern/i386/coreboot/mmap.c ++++ b/grub-core/kern/i386/coreboot/mmap.c +@@ -58,8 +58,10 @@ signature_found: + + table_item = + (grub_linuxbios_table_item_t) ((long) table_header + +- (long) table_header->size); +- for (; table_item->size; ++ (long) table_header->header_size); ++ for (; table_item < (grub_linuxbios_table_item_t) ((long) table_header ++ + (long) table_header->header_size ++ + (long) table_header->table_size); + table_item = (grub_linuxbios_table_item_t) ((long) table_item + (long) table_item->size)) + { + if (table_item->tag == GRUB_LINUXBIOS_MEMBER_LINK +diff --git a/include/grub/i386/coreboot/lbio.h b/include/grub/i386/coreboot/lbio.h +index aa18539..bac5492 100644 +--- a/include/grub/i386/coreboot/lbio.h ++++ b/include/grub/i386/coreboot/lbio.h +@@ -22,8 +22,12 @@ + + struct grub_linuxbios_table_header + { +- char signature[4]; +- grub_uint32_t size; ++ grub_uint8_t signature[4]; ++ grub_uint32_t header_size; ++ grub_uint32_t header_checksum; ++ grub_uint32_t table_size; ++ grub_uint32_t table_checksum; ++ grub_uint32_t table_entries; + }; + typedef struct grub_linuxbios_table_header *grub_linuxbios_table_header_t; + +-- +1.8.1.4 + diff --git a/0170-Enable-linux16-on-non-BIOS-systems-for-i.a.-memtest.patch b/0170-Enable-linux16-on-non-BIOS-systems-for-i.a.-memtest.patch new file mode 100644 index 0000000..2837cda --- /dev/null +++ b/0170-Enable-linux16-on-non-BIOS-systems-for-i.a.-memtest.patch @@ -0,0 +1,138 @@ +From 6002efaf14b06075755a6c552989a463c4bd8e4f Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Thu, 28 Feb 2013 22:48:41 +0100 +Subject: [PATCH 170/364] Enable linux16 on non-BIOS systems for i.a. + memtest. + + * grub-core/loader/i386/pc/linux.c (grub_cmd_linux): Handle hole at 0 + correctly. + * grub-core/Makefile.core.def (linux16): Enable on all x86 flavours. +--- + ChangeLog | 8 ++++++ + grub-core/Makefile.core.def | 6 ++-- + grub-core/loader/i386/pc/linux.c | 60 ++++++++++++++++++++++++++++------------ + 3 files changed, 54 insertions(+), 20 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 0eb0516..135586c 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,13 @@ + 2013-02-28 Vladimir Serbinenko + ++ Enable linux16 on non-BIOS systems for i.a. memtest. ++ ++ * grub-core/loader/i386/pc/linux.c (grub_cmd_linux): Handle hole at 0 ++ correctly. ++ * grub-core/Makefile.core.def (linux16): Enable on all x86 flavours. ++ ++2013-02-28 Vladimir Serbinenko ++ + * grub-core/kern/i386/coreboot/mmap.c (grub_linuxbios_table_iterate): + Fix end of table condition. + +diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def +index 4b0e6e6..93ff2a8 100644 +--- a/grub-core/Makefile.core.def ++++ b/grub-core/Makefile.core.def +@@ -1390,9 +1390,9 @@ module = { + + module = { + name = linux16; +- i386_pc = loader/i386/pc/linux.c; +- i386_pc = lib/cmdline.c; +- enable = i386_pc; ++ common = loader/i386/pc/linux.c; ++ common = lib/cmdline.c; ++ enable = x86; + }; + + module = { +diff --git a/grub-core/loader/i386/pc/linux.c b/grub-core/loader/i386/pc/linux.c +index 4eeb1b6..39206c8 100644 +--- a/grub-core/loader/i386/pc/linux.c ++++ b/grub-core/loader/i386/pc/linux.c +@@ -79,6 +79,42 @@ grub_linux_unload (void) + return GRUB_ERR_NONE; + } + ++static int ++target_hook (grub_uint64_t addr, grub_uint64_t size, grub_memory_type_t type, ++ void *data) ++{ ++ grub_uint64_t *result = data; ++ grub_uint64_t candidate; ++ ++ if (type != GRUB_MEMORY_AVAILABLE) ++ return 0; ++ if (addr >= 0xa0000) ++ return 0; ++ if (addr + size >= 0xa0000) ++ size = 0xa0000 - addr; ++ ++ /* Put the real mode part at as a high location as possible. */ ++ candidate = addr + size - (GRUB_LINUX_CL_OFFSET + maximal_cmdline_size); ++ /* But it must not exceed the traditional area. */ ++ if (candidate > GRUB_LINUX_OLD_REAL_MODE_ADDR) ++ candidate = GRUB_LINUX_OLD_REAL_MODE_ADDR; ++ if (candidate < addr) ++ return 0; ++ ++ if (candidate > *result || *result == (grub_uint64_t) -1) ++ *result = candidate; ++ return 0; ++} ++ ++static grub_addr_t ++grub_find_real_target (void) ++{ ++ grub_uint64_t result = (grub_uint64_t) -1; ++ ++ grub_mmap_iterate (target_hook, &result); ++ return result; ++} ++ + static grub_err_t + grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) +@@ -141,12 +177,13 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + if (grub_le_to_cpu16 (lh.version) >= 0x0206) + maximal_cmdline_size = grub_le_to_cpu32 (lh.cmdline_size) + 1; + +- /* Put the real mode part at as a high location as possible. */ +- grub_linux_real_target = grub_mmap_get_lower () +- - (GRUB_LINUX_CL_OFFSET + maximal_cmdline_size); +- /* But it must not exceed the traditional area. */ +- if (grub_linux_real_target > GRUB_LINUX_OLD_REAL_MODE_ADDR) +- grub_linux_real_target = GRUB_LINUX_OLD_REAL_MODE_ADDR; ++ grub_linux_real_target = grub_find_real_target (); ++ if (grub_linux_real_target == (grub_addr_t)-1) ++ { ++ grub_error (GRUB_ERR_OUT_OF_RANGE, ++ "no appropriate low memory found"); ++ goto fail; ++ } + + if (grub_le_to_cpu16 (lh.version) >= 0x0201) + { +@@ -193,17 +230,6 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + goto fail; + } + +- if (grub_linux_real_target + GRUB_LINUX_CL_OFFSET + maximal_cmdline_size +- > grub_mmap_get_lower ()) +- { +- grub_error (GRUB_ERR_OUT_OF_RANGE, +- "too small lower memory (0x%x > 0x%x)", +- grub_linux_real_target + GRUB_LINUX_CL_OFFSET +- + maximal_cmdline_size, +- (int) grub_mmap_get_lower ()); +- goto fail; +- } +- + grub_dprintf ("linux", "[Linux-%s, setup=0x%x, size=0x%x]\n", + grub_linux_is_bzimage ? "bzImage" : "zImage", real_size, + grub_linux16_prot_size); +-- +1.8.1.4 + diff --git a/0171-grub-core-kern-main.c-grub_set_prefix_and_root-Strip.patch b/0171-grub-core-kern-main.c-grub_set_prefix_and_root-Strip.patch new file mode 100644 index 0000000..d2deb3a --- /dev/null +++ b/0171-grub-core-kern-main.c-grub_set_prefix_and_root-Strip.patch @@ -0,0 +1,49 @@ +From 1d7f76afcf0ea16e362edbf053bb5b34d8dad048 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Fri, 1 Mar 2013 10:35:51 +0100 +Subject: [PATCH 171/364] * grub-core/kern/main.c + (grub_set_prefix_and_root): Strip trailing platform from firmware path. + +--- + ChangeLog | 5 +++++ + grub-core/kern/main.c | 11 ++++++++++- + 2 files changed, 15 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index 135586c..986871c 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,8 @@ ++2013-03-01 Vladimir Serbinenko ++ ++ * grub-core/kern/main.c (grub_set_prefix_and_root): Strip trailing ++ platform from firmware path. ++ + 2013-02-28 Vladimir Serbinenko + + Enable linux16 on non-BIOS systems for i.a. memtest. +diff --git a/grub-core/kern/main.c b/grub-core/kern/main.c +index 3262444..c43ac6b 100644 +--- a/grub-core/kern/main.c ++++ b/grub-core/kern/main.c +@@ -168,7 +168,16 @@ grub_set_prefix_and_root (void) + else + grub_free (fwdevice); + if (fwpath && !path) +- path = fwpath; ++ { ++ grub_size_t len = grub_strlen (fwpath); ++ while (len > 1 && fwpath[len - 1] == '/') ++ fwpath[--len] = 0; ++ if (len >= sizeof (GRUB_TARGET_CPU "-" GRUB_PLATFORM) - 1 ++ && grub_memcmp (fwpath + len - (sizeof (GRUB_TARGET_CPU "-" GRUB_PLATFORM) - 1), GRUB_TARGET_CPU "-" GRUB_PLATFORM, ++ sizeof (GRUB_TARGET_CPU "-" GRUB_PLATFORM) - 1) == 0) ++ fwpath[len - (sizeof (GRUB_TARGET_CPU "-" GRUB_PLATFORM) - 1)] = 0; ++ path = fwpath; ++ } + else + grub_free (fwpath); + if (device) +-- +1.8.1.4 + diff --git a/0172-grub-core-disk-efi-efidisk.c-Transform-iterate_child.patch b/0172-grub-core-disk-efi-efidisk.c-Transform-iterate_child.patch new file mode 100644 index 0000000..b0c8e65 --- /dev/null +++ b/0172-grub-core-disk-efi-efidisk.c-Transform-iterate_child.patch @@ -0,0 +1,119 @@ +From d81bf19e26c7af47e38206a7cbd825f559ac7457 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Fri, 1 Mar 2013 10:37:11 +0100 +Subject: [PATCH 172/364] * grub-core/disk/efi/efidisk.c: Transform + iterate_child_devices into a FOR_CHILDREN macro. + +--- + ChangeLog | 5 ++++ + grub-core/disk/efi/efidisk.c | 55 +++++++++++++++++--------------------------- + 2 files changed, 26 insertions(+), 34 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 986871c..ccd6c0a 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,10 @@ + 2013-03-01 Vladimir Serbinenko + ++ * grub-core/disk/efi/efidisk.c: Transform iterate_child_devices into ++ a FOR_CHILDREN macro. ++ ++2013-03-01 Vladimir Serbinenko ++ + * grub-core/kern/main.c (grub_set_prefix_and_root): Strip trailing + platform from firmware path. + +diff --git a/grub-core/disk/efi/efidisk.c b/grub-core/disk/efi/efidisk.c +index 19c5923..c883b2c 100644 +--- a/grub-core/disk/efi/efidisk.c ++++ b/grub-core/disk/efi/efidisk.c +@@ -175,39 +175,29 @@ find_parent_device (struct grub_efidisk_data *devices, + } + + static int +-iterate_child_devices (struct grub_efidisk_data *devices, +- struct grub_efidisk_data *d, +- int (*hook) (struct grub_efidisk_data *child)) ++is_child (struct grub_efidisk_data *child, ++ struct grub_efidisk_data *parent) + { +- struct grub_efidisk_data *p; +- +- for (p = devices; p; p = p->next) +- { +- grub_efi_device_path_t *dp, *ldp; +- +- dp = duplicate_device_path (p->device_path); +- if (! dp) +- return 0; +- +- ldp = find_last_device_path (dp); +- ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE; +- ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE; +- ldp->length[0] = sizeof (*ldp); +- ldp->length[1] = 0; ++ grub_efi_device_path_t *dp, *ldp; ++ int ret; + +- if (grub_efi_compare_device_paths (dp, d->device_path) == 0) +- if (hook (p)) +- { +- grub_free (dp); +- return 1; +- } ++ dp = duplicate_device_path (child->device_path); ++ if (! dp) ++ return 0; + +- grub_free (dp); +- } ++ ldp = find_last_device_path (dp); ++ ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE; ++ ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE; ++ ldp->length[0] = sizeof (*ldp); ++ ldp->length[1] = 0; + +- return 0; ++ ret = (grub_efi_compare_device_paths (dp, parent->device_path) == 0); ++ grub_free (dp); ++ return ret; + } + ++#define FOR_CHILDREN(p, dev) for (p = dev; p; p = p->next) if (is_child (p, d)) ++ + /* Add a device into a list of devices in an ascending order. */ + static void + add_device (struct grub_efidisk_data **devices, struct grub_efidisk_data *d) +@@ -655,9 +645,10 @@ grub_efidisk_get_device_handle (grub_disk_t disk) + { + struct grub_efidisk_data *devices; + grub_efi_handle_t handle = 0; +- auto int find_partition (struct grub_efidisk_data *c); ++ struct grub_efidisk_data *c; + +- int find_partition (struct grub_efidisk_data *c) ++ devices = make_devices (); ++ FOR_CHILDREN (c, devices) + { + grub_efi_hard_drive_device_path_t hd; + +@@ -673,14 +664,10 @@ grub_efidisk_get_device_handle (grub_disk_t disk) + == hd.partition_size)) + { + handle = c->handle; +- return 1; ++ break; + } +- +- return 0; + } + +- devices = make_devices (); +- iterate_child_devices (devices, d, find_partition); + free_devices (devices); + + if (handle != 0) +-- +1.8.1.4 + diff --git a/0173-grub-core-loader-i386-pc-linux.c-grub_cmd_linux-Fix-.patch b/0173-grub-core-loader-i386-pc-linux.c-grub_cmd_linux-Fix-.patch new file mode 100644 index 0000000..9354300 --- /dev/null +++ b/0173-grub-core-loader-i386-pc-linux.c-grub_cmd_linux-Fix-.patch @@ -0,0 +1,45 @@ +From 3e5394dbb6b5e9bc1ad10279270aecb578ff07b2 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Fri, 1 Mar 2013 10:39:41 +0100 +Subject: [PATCH 173/364] * grub-core/loader/i386/pc/linux.c + (grub_cmd_linux): Fix compilation for 64-bit platforms. + +--- + ChangeLog | 5 +++++ + grub-core/loader/i386/pc/linux.c | 5 +++-- + 2 files changed, 8 insertions(+), 2 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index ccd6c0a..3ca1fed 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,10 @@ + 2013-03-01 Vladimir Serbinenko + ++ * grub-core/loader/i386/pc/linux.c (grub_cmd_linux): Fix compilation ++ for 64-bit platforms. ++ ++2013-03-01 Vladimir Serbinenko ++ + * grub-core/disk/efi/efidisk.c: Transform iterate_child_devices into + a FOR_CHILDREN macro. + +diff --git a/grub-core/loader/i386/pc/linux.c b/grub-core/loader/i386/pc/linux.c +index 39206c8..3ce21bc 100644 +--- a/grub-core/loader/i386/pc/linux.c ++++ b/grub-core/loader/i386/pc/linux.c +@@ -231,8 +231,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + } + + grub_dprintf ("linux", "[Linux-%s, setup=0x%x, size=0x%x]\n", +- grub_linux_is_bzimage ? "bzImage" : "zImage", real_size, +- grub_linux16_prot_size); ++ grub_linux_is_bzimage ? "bzImage" : "zImage", ++ (unsigned) real_size, ++ (unsigned) grub_linux16_prot_size); + + relocator = grub_relocator_new (); + if (!relocator) +-- +1.8.1.4 + diff --git a/0174-Remove-nested-functions-from-videoinfo-iterators.patch b/0174-Remove-nested-functions-from-videoinfo-iterators.patch new file mode 100644 index 0000000..f6b1aca --- /dev/null +++ b/0174-Remove-nested-functions-from-videoinfo-iterators.patch @@ -0,0 +1,239 @@ +From 031f4b44a6488a0bd7fe79657480484ac981ce9e Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Fri, 1 Mar 2013 11:11:36 +0100 +Subject: [PATCH 174/364] Remove nested functions from videoinfo + iterators. + +--- + ChangeLog | 4 ++++ + grub-core/commands/videoinfo.c | 34 ++++++++++++++++++++-------------- + grub-core/video/efi_gop.c | 23 ++++++++++++----------- + grub-core/video/i386/pc/vbe.c | 4 ++-- + include/grub/video.h | 2 +- + 5 files changed, 39 insertions(+), 28 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 3ca1fed..7f5bcfa 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,9 @@ + 2013-03-01 Vladimir Serbinenko + ++ Remove nested functions from videoinfo iterators. ++ ++2013-03-01 Vladimir Serbinenko ++ + * grub-core/loader/i386/pc/linux.c (grub_cmd_linux): Fix compilation + for 64-bit platforms. + +diff --git a/grub-core/commands/videoinfo.c b/grub-core/commands/videoinfo.c +index 4a11576..7a75c9d 100644 +--- a/grub-core/commands/videoinfo.c ++++ b/grub-core/commands/videoinfo.c +@@ -27,23 +27,28 @@ + + GRUB_MOD_LICENSE ("GPLv3+"); + +-static unsigned height, width, depth; +-static struct grub_video_mode_info *current_mode; ++struct hook_ctx ++{ ++ unsigned height, width, depth; ++ struct grub_video_mode_info *current_mode; ++}; + + static int +-hook (const struct grub_video_mode_info *info) ++hook (const struct grub_video_mode_info *info, void *hook_arg) + { +- if (height && width && (info->width != width || info->height != height)) ++ struct hook_ctx *ctx = hook_arg; ++ ++ if (ctx->height && ctx->width && (info->width != ctx->width || info->height != ctx->height)) + return 0; + +- if (depth && info->bpp != depth) ++ if (ctx->depth && info->bpp != ctx->depth) + return 0; + + if (info->mode_number == GRUB_VIDEO_MODE_NUMBER_INVALID) + grub_printf (" "); + else + { +- if (current_mode && info->mode_number == current_mode->mode_number) ++ if (ctx->current_mode && info->mode_number == ctx->current_mode->mode_number) + grub_printf ("*"); + else + grub_printf (" "); +@@ -126,13 +131,14 @@ grub_cmd_videoinfo (grub_command_t cmd __attribute__ ((unused)), + { + grub_video_adapter_t adapter; + grub_video_driver_id_t id; ++ struct hook_ctx ctx; + +- height = width = depth = 0; ++ ctx.height = ctx.width = ctx.depth = 0; + if (argc) + { + char *ptr; + ptr = args[0]; +- width = grub_strtoul (ptr, &ptr, 0); ++ ctx.width = grub_strtoul (ptr, &ptr, 0); + if (grub_errno) + return grub_errno; + if (*ptr != 'x') +@@ -140,13 +146,13 @@ grub_cmd_videoinfo (grub_command_t cmd __attribute__ ((unused)), + N_("invalid video mode specification `%s'"), + args[0]); + ptr++; +- height = grub_strtoul (ptr, &ptr, 0); ++ ctx.height = grub_strtoul (ptr, &ptr, 0); + if (grub_errno) + return grub_errno; + if (*ptr == 'x') + { + ptr++; +- depth = grub_strtoul (ptr, &ptr, 0); ++ ctx.depth = grub_strtoul (ptr, &ptr, 0); + if (grub_errno) + return grub_errno; + } +@@ -175,12 +181,12 @@ grub_cmd_videoinfo (grub_command_t cmd __attribute__ ((unused)), + continue; + } + +- current_mode = NULL; ++ ctx.current_mode = NULL; + + if (adapter->id == id) + { + if (grub_video_get_info (&info) == GRUB_ERR_NONE) +- current_mode = &info; ++ ctx.current_mode = &info; + else + /* Don't worry about errors. */ + grub_errno = GRUB_ERR_NONE; +@@ -198,14 +204,14 @@ grub_cmd_videoinfo (grub_command_t cmd __attribute__ ((unused)), + if (adapter->print_adapter_specific_info) + adapter->print_adapter_specific_info (); + +- adapter->iterate (hook); ++ adapter->iterate (hook, &ctx); + + if (adapter->get_edid && adapter->get_edid (&edid_info) == GRUB_ERR_NONE) + print_edid (&edid_info); + else + grub_errno = GRUB_ERR_NONE; + +- current_mode = NULL; ++ ctx.current_mode = NULL; + + if (adapter->id != id) + { +diff --git a/grub-core/video/efi_gop.c b/grub-core/video/efi_gop.c +index 37a0015..f73a278 100644 +--- a/grub-core/video/efi_gop.c ++++ b/grub-core/video/efi_gop.c +@@ -42,7 +42,7 @@ static int restore_needed; + static grub_efi_handle_t gop_handle; + + static int +-grub_video_gop_iterate (int (*hook) (const struct grub_video_mode_info *info)); ++grub_video_gop_iterate (int (*hook) (const struct grub_video_mode_info *info, void *hook_arg), void *hook_arg); + + static struct + { +@@ -52,6 +52,14 @@ static struct + grub_uint8_t *offscreen; + } framebuffer; + ++static int ++check_protocol_hook (const struct grub_video_mode_info *info __attribute__ ((unused)), void *hook_arg) ++{ ++ int *have_usable_mode = hook_arg; ++ *have_usable_mode = 1; ++ return 1; ++} ++ + + static int + check_protocol (void) +@@ -60,13 +68,6 @@ check_protocol (void) + grub_efi_uintn_t num_handles, i; + int have_usable_mode = 0; + +- auto int hook (const struct grub_video_mode_info *info); +- int hook (const struct grub_video_mode_info *info __attribute__ ((unused))) +- { +- have_usable_mode = 1; +- return 1; +- } +- + handles = grub_efi_locate_handle (GRUB_EFI_BY_PROTOCOL, + &graphics_output_guid, NULL, &num_handles); + if (!handles || num_handles == 0) +@@ -77,7 +78,7 @@ check_protocol (void) + gop_handle = handles[i]; + gop = grub_efi_open_protocol (gop_handle, &graphics_output_guid, + GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); +- grub_video_gop_iterate (hook); ++ grub_video_gop_iterate (check_protocol_hook, &have_usable_mode); + if (have_usable_mode) + { + grub_free (handles); +@@ -256,7 +257,7 @@ grub_video_gop_fill_mode_info (unsigned mode, + } + + static int +-grub_video_gop_iterate (int (*hook) (const struct grub_video_mode_info *info)) ++grub_video_gop_iterate (int (*hook) (const struct grub_video_mode_info *info, void *hook_arg), void *hook_arg) + { + unsigned mode; + +@@ -282,7 +283,7 @@ grub_video_gop_iterate (int (*hook) (const struct grub_video_mode_info *info)) + grub_errno = GRUB_ERR_NONE; + continue; + } +- if (hook (&mode_info)) ++ if (hook (&mode_info, hook_arg)) + return 1; + } + return 0; +diff --git a/grub-core/video/i386/pc/vbe.c b/grub-core/video/i386/pc/vbe.c +index 81e5a8e..e8a8c7a 100644 +--- a/grub-core/video/i386/pc/vbe.c ++++ b/grub-core/video/i386/pc/vbe.c +@@ -952,7 +952,7 @@ vbe2videoinfo (grub_uint32_t mode, + } + + static int +-grub_video_vbe_iterate (int (*hook) (const struct grub_video_mode_info *info)) ++grub_video_vbe_iterate (int (*hook) (const struct grub_video_mode_info *info, void *hook_arg), void *hook_arg) + { + grub_uint16_t *p; + struct grub_vbe_mode_info_block vbe_mode_info; +@@ -969,7 +969,7 @@ grub_video_vbe_iterate (int (*hook) (const struct grub_video_mode_info *info)) + } + + vbe2videoinfo (*p, &vbe_mode_info, &mode_info); +- if (hook (&mode_info)) ++ if (hook (&mode_info, hook_arg)) + return 1; + } + return 0; +diff --git a/include/grub/video.h b/include/grub/video.h +index 08f7300..9fe4783 100644 +--- a/include/grub/video.h ++++ b/include/grub/video.h +@@ -372,7 +372,7 @@ struct grub_video_adapter + + grub_err_t (*get_active_render_target) (struct grub_video_render_target **target); + +- int (*iterate) (int (*hook) (const struct grub_video_mode_info *info)); ++ int (*iterate) (int (*hook) (const struct grub_video_mode_info *info, void *hook_arg), void *hook_arg); + + grub_err_t (*get_edid) (struct grub_video_edid_info *edid_info); + +-- +1.8.1.4 + diff --git a/0175-grub-core-gentrigtables.c-Make-tables-const.patch b/0175-grub-core-gentrigtables.c-Make-tables-const.patch new file mode 100644 index 0000000..2ab1632 --- /dev/null +++ b/0175-grub-core-gentrigtables.c-Make-tables-const.patch @@ -0,0 +1,57 @@ +From adebf599a9df7cf86a40a04429edcf24a572adac Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Fri, 1 Mar 2013 11:15:09 +0100 +Subject: [PATCH 175/364] * grub-core/gentrigtables.c: Make tables + const. + +--- + ChangeLog | 4 ++++ + grub-core/gentrigtables.c | 2 +- + include/grub/trig.h | 4 ++-- + 3 files changed, 7 insertions(+), 3 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 7f5bcfa..fda449d 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,9 @@ + 2013-03-01 Vladimir Serbinenko + ++ * grub-core/gentrigtables.c: Make tables const. ++ ++2013-03-01 Vladimir Serbinenko ++ + Remove nested functions from videoinfo iterators. + + 2013-03-01 Vladimir Serbinenko +diff --git a/grub-core/gentrigtables.c b/grub-core/gentrigtables.c +index 8c03957..fface6e 100644 +--- a/grub-core/gentrigtables.c ++++ b/grub-core/gentrigtables.c +@@ -40,7 +40,7 @@ main (int argc __attribute__ ((unused)), + printf ("GRUB_MOD_DUAL_LICENSE (\"Public Domain\");"); + + #define TAB(op) \ +- printf ("grub_int16_t grub_trig_" #op "tab[] =\n{"); \ ++ printf ("const 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; \ +diff --git a/include/grub/trig.h b/include/grub/trig.h +index 2512a5f..f19617c 100644 +--- a/include/grub/trig.h ++++ b/include/grub/trig.h +@@ -24,8 +24,8 @@ + #define GRUB_TRIG_ANGLE_MASK 255 + #define GRUB_TRIG_FRACTION_SCALE 16384 + +-extern short grub_trig_sintab[]; +-extern short grub_trig_costab[]; ++extern const short grub_trig_sintab[]; ++extern const short grub_trig_costab[]; + + static __inline int + grub_sin (int x) +-- +1.8.1.4 + diff --git a/0176-grub-core-kern-emu-hostdisk.c-read_device_map-Remove.patch b/0176-grub-core-kern-emu-hostdisk.c-read_device_map-Remove.patch new file mode 100644 index 0000000..665ec9c --- /dev/null +++ b/0176-grub-core-kern-emu-hostdisk.c-read_device_map-Remove.patch @@ -0,0 +1,82 @@ +From 473af7902f97c7677c802ab3d2a42be8f39fa30d Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Fri, 1 Mar 2013 13:46:24 +0100 +Subject: [PATCH 176/364] * grub-core/kern/emu/hostdisk.c + (read_device_map): Remove nested function. + +--- + ChangeLog | 5 +++++ + grub-core/kern/emu/hostdisk.c | 15 ++++----------- + 2 files changed, 9 insertions(+), 11 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index fda449d..f324b92 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,10 @@ + 2013-03-01 Vladimir Serbinenko + ++ * grub-core/kern/emu/hostdisk.c (read_device_map): Remove nested ++ function. ++ ++2013-03-01 Vladimir Serbinenko ++ + * grub-core/gentrigtables.c: Make tables const. + + 2013-03-01 Vladimir Serbinenko +diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c +index 92ce1d9..62a579b 100644 +--- a/grub-core/kern/emu/hostdisk.c ++++ b/grub-core/kern/emu/hostdisk.c +@@ -1209,13 +1209,6 @@ read_device_map (const char *dev_map) + int lineno = 0; + struct stat st; + +- auto void show_error (const char *msg) +- __attribute__ ((noreturn)); +- void __attribute__ ((noreturn)) show_error (const char *msg) +- { +- grub_util_error ("%s:%d: %s", dev_map, lineno, msg); +- } +- + if (dev_map[0] == '\0') + { + grub_util_info ("no device.map"); +@@ -1250,14 +1243,14 @@ read_device_map (const char *dev_map) + { + char *tmp; + tmp = xasprintf (_("missing `%c' symbol"), '('); +- show_error (tmp); ++ grub_util_error ("%s:%d: %s", dev_map, lineno, tmp); + } + + p++; + /* Find a free slot. */ + drive = find_free_slot (); + if (drive < 0) +- show_error (_("device count exceeds limit")); ++ grub_util_error ("%s:%d: %s", dev_map, lineno, _("device count exceeds limit")); + + e = p; + p = strchr (p, ')'); +@@ -1265,7 +1258,7 @@ read_device_map (const char *dev_map) + { + char *tmp; + tmp = xasprintf (_("missing `%c' symbol"), ')'); +- show_error (tmp); ++ grub_util_error ("%s:%d: %s", dev_map, lineno, tmp); + } + + map[drive].drive = 0; +@@ -1310,7 +1303,7 @@ read_device_map (const char *dev_map) + p++; + + if (*p == '\0') +- show_error (_("filename expected")); ++ grub_util_error ("%s:%d: %s", dev_map, lineno, _("filename expected")); + + /* NUL-terminate the filename. */ + e = p; +-- +1.8.1.4 + diff --git a/0177-util-grub-editenv.c-list_variables-Move-print_var-ou.patch b/0177-util-grub-editenv.c-list_variables-Move-print_var-ou.patch new file mode 100644 index 0000000..2fbccbc --- /dev/null +++ b/0177-util-grub-editenv.c-list_variables-Move-print_var-ou.patch @@ -0,0 +1,59 @@ +From 276613c0ebf746e6cde7068918f9dd2158f37cd8 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Fri, 1 Mar 2013 13:52:05 +0100 +Subject: [PATCH 177/364] * util/grub-editenv.c (list_variables): Move + print_var out of its parent. + +--- + ChangeLog | 5 +++++ + util/grub-editenv.c | 14 +++++++------- + 2 files changed, 12 insertions(+), 7 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index f324b92..0bad8bf 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,10 @@ + 2013-03-01 Vladimir Serbinenko + ++ * util/grub-editenv.c (list_variables): Move print_var out of its ++ parent. ++ ++2013-03-01 Vladimir Serbinenko ++ + * grub-core/kern/emu/hostdisk.c (read_device_map): Remove nested + function. + +diff --git a/util/grub-editenv.c b/util/grub-editenv.c +index 175ca8e..9b51acf 100644 +--- a/util/grub-editenv.c ++++ b/util/grub-editenv.c +@@ -184,18 +184,18 @@ open_envblk_file (const char *name) + return envblk; + } + ++static int ++print_var (const char *varname, const char *value) ++{ ++ printf ("%s=%s\n", varname, value); ++ return 0; ++} ++ + static void + list_variables (const char *name) + { + grub_envblk_t envblk; + +- auto int print_var (const char *varname, const char *value); +- int print_var (const char *varname, const char *value) +- { +- printf ("%s=%s\n", varname, value); +- return 0; +- } +- + envblk = open_envblk_file (name); + grub_envblk_iterate (envblk, print_var); + grub_envblk_close (envblk); +-- +1.8.1.4 + diff --git a/0178-grub-core-fs-hfsplus.c-grub_hfsplus_btree_iterate_no.patch b/0178-grub-core-fs-hfsplus.c-grub_hfsplus_btree_iterate_no.patch new file mode 100644 index 0000000..4ad16a6 --- /dev/null +++ b/0178-grub-core-fs-hfsplus.c-grub_hfsplus_btree_iterate_no.patch @@ -0,0 +1,304 @@ +From c00446a08396d8ddb56ec13cb0ef12c921d348e2 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Fri, 1 Mar 2013 14:02:27 +0100 +Subject: [PATCH 178/364] * grub-core/fs/hfsplus.c + (grub_hfsplus_btree_iterate_node): Pass the context through. + (grub_hfsplus_iterate_dir): Move nested function out of its parent. + +--- + ChangeLog | 6 ++ + grub-core/fs/hfsplus.c | 218 ++++++++++++++++++++++++++----------------------- + 2 files changed, 123 insertions(+), 101 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 0bad8bf..838d8af 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,11 @@ + 2013-03-01 Vladimir Serbinenko + ++ * grub-core/fs/hfsplus.c (grub_hfsplus_btree_iterate_node): Pass ++ the context through. ++ (grub_hfsplus_iterate_dir): Move nested function out of its parent. ++ ++2013-03-01 Vladimir Serbinenko ++ + * util/grub-editenv.c (list_variables): Move print_var out of its + parent. + +diff --git a/grub-core/fs/hfsplus.c b/grub-core/fs/hfsplus.c +index 29a3a94..a507c0f 100644 +--- a/grub-core/fs/hfsplus.c ++++ b/grub-core/fs/hfsplus.c +@@ -620,7 +620,8 @@ static int + grub_hfsplus_btree_iterate_node (struct grub_hfsplus_btree *btree, + struct grub_hfsplus_btnode *first_node, + grub_disk_addr_t first_rec, +- int (*hook) (void *record)) ++ int (*hook) (void *record, void *hook_arg), ++ void *hook_arg) + { + grub_disk_addr_t rec; + grub_uint64_t saved_node = -1; +@@ -633,7 +634,7 @@ grub_hfsplus_btree_iterate_node (struct grub_hfsplus_btree *btree, + /* Iterate over all records in this node. */ + for (rec = first_rec; rec < grub_be_to_cpu16 (first_node->count); rec++) + { +- if (hook (grub_hfsplus_btree_recptr (btree, first_node, rec))) ++ if (hook (grub_hfsplus_btree_recptr (btree, first_node, rec), hook_arg)) + return 1; + } + +@@ -764,123 +765,138 @@ grub_hfsplus_btree_search (struct grub_hfsplus_btree *btree, + } + } + ++struct list_nodes_ctx ++{ ++ int ret; ++ grub_fshelp_node_t dir; ++ grub_fshelp_iterate_dir_hook_t hook; ++ void *hook_data; ++}; ++ + static int +-grub_hfsplus_iterate_dir (grub_fshelp_node_t dir, +- grub_fshelp_iterate_dir_hook_t hook, void *hook_data) ++list_nodes (void *record, void *hook_arg) + { +- int ret = 0; ++ struct grub_hfsplus_catkey *catkey; ++ char *filename; ++ int i; ++ struct grub_fshelp_node *node; ++ struct grub_hfsplus_catfile *fileinfo; ++ enum grub_fshelp_filetype type = GRUB_FSHELP_UNKNOWN; ++ struct list_nodes_ctx *ctx = hook_arg; ++ ++ catkey = (struct grub_hfsplus_catkey *) record; ++ ++ fileinfo = ++ (struct grub_hfsplus_catfile *) ((char *) record ++ + grub_be_to_cpu16 (catkey->keylen) ++ + 2 + (grub_be_to_cpu16(catkey->keylen) ++ % 2)); + +- auto int list_nodes (void *record); +- int list_nodes (void *record) ++ /* Stop iterating when the last directory entry is found. */ ++ if (grub_be_to_cpu32 (catkey->parent) != ctx->dir->fileid) ++ return 1; ++ ++ /* Determine the type of the node that is found. */ ++ switch (fileinfo->type) + { +- struct grub_hfsplus_catkey *catkey; +- char *filename; +- int i; +- struct grub_fshelp_node *node; +- struct grub_hfsplus_catfile *fileinfo; +- enum grub_fshelp_filetype type = GRUB_FSHELP_UNKNOWN; +- +- catkey = (struct grub_hfsplus_catkey *) record; +- +- fileinfo = +- (struct grub_hfsplus_catfile *) ((char *) record +- + grub_be_to_cpu16 (catkey->keylen) +- + 2 + (grub_be_to_cpu16(catkey->keylen) +- % 2)); +- +- /* Stop iterating when the last directory entry is found. */ +- if (grub_be_to_cpu32 (catkey->parent) != dir->fileid) ++ case grub_cpu_to_be16_compile_time (GRUB_HFSPLUS_FILETYPE_REG): ++ { ++ int mode = (grub_be_to_cpu16 (fileinfo->mode) ++ & GRUB_HFSPLUS_FILEMODE_MASK); ++ ++ if (mode == GRUB_HFSPLUS_FILEMODE_REG) ++ type = GRUB_FSHELP_REG; ++ else if (mode == GRUB_HFSPLUS_FILEMODE_SYMLINK) ++ type = GRUB_FSHELP_SYMLINK; ++ else ++ type = GRUB_FSHELP_UNKNOWN; ++ break; ++ } ++ case grub_cpu_to_be16_compile_time (GRUB_HFSPLUS_FILETYPE_DIR): ++ type = GRUB_FSHELP_DIR; ++ break; ++ case grub_cpu_to_be16_compile_time (GRUB_HFSPLUS_FILETYPE_DIR_THREAD): ++ if (ctx->dir->fileid == 2) ++ return 0; ++ node = grub_malloc (sizeof (*node)); ++ if (!node) + return 1; ++ node->data = ctx->dir->data; ++ node->mtime = 0; ++ node->size = 0; ++ node->fileid = grub_be_to_cpu32 (fileinfo->parentid); + +- /* Determine the type of the node that is found. */ +- switch (fileinfo->type) +- { +- case grub_cpu_to_be16_compile_time (GRUB_HFSPLUS_FILETYPE_REG): +- { +- int mode = (grub_be_to_cpu16 (fileinfo->mode) +- & GRUB_HFSPLUS_FILEMODE_MASK); +- +- if (mode == GRUB_HFSPLUS_FILEMODE_REG) +- type = GRUB_FSHELP_REG; +- else if (mode == GRUB_HFSPLUS_FILEMODE_SYMLINK) +- type = GRUB_FSHELP_SYMLINK; +- else +- type = GRUB_FSHELP_UNKNOWN; +- break; +- } +- case grub_cpu_to_be16_compile_time (GRUB_HFSPLUS_FILETYPE_DIR): +- type = GRUB_FSHELP_DIR; +- break; +- case grub_cpu_to_be16_compile_time (GRUB_HFSPLUS_FILETYPE_DIR_THREAD): +- if (dir->fileid == 2) +- return 0; +- node = grub_malloc (sizeof (*node)); +- if (!node) +- return 1; +- node->data = dir->data; +- node->mtime = 0; +- node->size = 0; +- node->fileid = grub_be_to_cpu32 (fileinfo->parentid); ++ ctx->ret = ctx->hook ("..", GRUB_FSHELP_DIR, node, ctx->hook_data); ++ return ctx->ret; ++ } + +- ret = hook ("..", GRUB_FSHELP_DIR, node, hook_data); +- return ret; +- } ++ if (type == GRUB_FSHELP_UNKNOWN) ++ return 0; + +- if (type == GRUB_FSHELP_UNKNOWN) +- return 0; ++ filename = grub_malloc (grub_be_to_cpu16 (catkey->namelen) ++ * GRUB_MAX_UTF8_PER_UTF16 + 1); ++ if (! filename) ++ return 0; + +- filename = grub_malloc (grub_be_to_cpu16 (catkey->namelen) +- * GRUB_MAX_UTF8_PER_UTF16 + 1); +- if (! filename) +- return 0; ++ /* Make sure the byte order of the UTF16 string is correct. */ ++ for (i = 0; i < grub_be_to_cpu16 (catkey->namelen); i++) ++ { ++ catkey->name[i] = grub_be_to_cpu16 (catkey->name[i]); + +- /* Make sure the byte order of the UTF16 string is correct. */ +- for (i = 0; i < grub_be_to_cpu16 (catkey->namelen); i++) +- { +- catkey->name[i] = grub_be_to_cpu16 (catkey->name[i]); ++ if (catkey->name[i] == '/') ++ catkey->name[i] = ':'; + +- if (catkey->name[i] == '/') +- catkey->name[i] = ':'; ++ /* If the name is obviously invalid, skip this node. */ ++ if (catkey->name[i] == 0) ++ return 0; ++ } + +- /* If the name is obviously invalid, skip this node. */ +- if (catkey->name[i] == 0) +- return 0; +- } ++ *grub_utf16_to_utf8 ((grub_uint8_t *) filename, catkey->name, ++ grub_be_to_cpu16 (catkey->namelen)) = '\0'; + +- *grub_utf16_to_utf8 ((grub_uint8_t *) filename, catkey->name, +- grub_be_to_cpu16 (catkey->namelen)) = '\0'; ++ /* Restore the byte order to what it was previously. */ ++ for (i = 0; i < grub_be_to_cpu16 (catkey->namelen); i++) ++ { ++ if (catkey->name[i] == ':') ++ catkey->name[i] = '/'; ++ catkey->name[i] = grub_be_to_cpu16 (catkey->name[i]); ++ } + +- /* Restore the byte order to what it was previously. */ +- for (i = 0; i < grub_be_to_cpu16 (catkey->namelen); i++) +- { +- if (catkey->name[i] == ':') +- catkey->name[i] = '/'; +- catkey->name[i] = grub_be_to_cpu16 (catkey->name[i]); +- } ++ /* hfs+ is case insensitive. */ ++ if (! ctx->dir->data->case_sensitive) ++ type |= GRUB_FSHELP_CASE_INSENSITIVE; + +- /* hfs+ is case insensitive. */ +- if (! dir->data->case_sensitive) +- type |= GRUB_FSHELP_CASE_INSENSITIVE; ++ /* A valid node is found; setup the node and call the ++ callback function. */ ++ node = grub_malloc (sizeof (*node)); ++ if (!node) ++ return 1; ++ node->data = ctx->dir->data; + +- /* A valid node is found; setup the node and call the +- callback function. */ +- node = grub_malloc (sizeof (*node)); +- if (!node) +- return 1; +- node->data = dir->data; ++ grub_memcpy (node->extents, fileinfo->data.extents, ++ sizeof (node->extents)); ++ node->mtime = grub_be_to_cpu32 (fileinfo->mtime) - 2082844800; ++ node->size = grub_be_to_cpu64 (fileinfo->data.size); ++ node->fileid = grub_be_to_cpu32 (fileinfo->fileid); + +- grub_memcpy (node->extents, fileinfo->data.extents, +- sizeof (node->extents)); +- node->mtime = grub_be_to_cpu32 (fileinfo->mtime) - 2082844800; +- node->size = grub_be_to_cpu64 (fileinfo->data.size); +- node->fileid = grub_be_to_cpu32 (fileinfo->fileid); ++ ctx->ret = ctx->hook (filename, type, node, ctx->hook_data); + +- ret = hook (filename, type, node, hook_data); ++ grub_free (filename); + +- grub_free (filename); ++ return ctx->ret; ++} + +- return ret; +- } ++static int ++grub_hfsplus_iterate_dir (grub_fshelp_node_t dir, ++ grub_fshelp_iterate_dir_hook_t hook, void *hook_data) ++{ ++ struct list_nodes_ctx ctx = ++ { ++ .ret = 0, ++ .dir = dir, ++ .hook = hook, ++ .hook_data = hook_data ++ }; + + struct grub_hfsplus_key_internal intern; + struct grub_hfsplus_btnode *node; +@@ -908,11 +924,11 @@ grub_hfsplus_iterate_dir (grub_fshelp_node_t dir, + + /* Iterate over all entries in this directory. */ + grub_hfsplus_btree_iterate_node (&dir->data->catalog_tree, node, ptr, +- list_nodes); ++ list_nodes, &ctx); + + grub_free (node); + +- return ret; ++ return ctx.ret; + } + + /* Open a file named NAME and initialize FILE. */ +-- +1.8.1.4 + diff --git a/0179-grub-core-fs-hfs.c-Remove-nested-functions.patch b/0179-grub-core-fs-hfs.c-Remove-nested-functions.patch new file mode 100644 index 0000000..aca9972 --- /dev/null +++ b/0179-grub-core-fs-hfs.c-Remove-nested-functions.patch @@ -0,0 +1,476 @@ +From 52b8c810d30007f088a939c89343775fad18036b Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sat, 2 Mar 2013 11:31:00 +0100 +Subject: [PATCH 179/364] * grub-core/fs/hfs.c: Remove nested functions. + +--- + ChangeLog | 4 + + grub-core/fs/hfs.c | 329 ++++++++++++++++++++++++++++++----------------------- + 2 files changed, 192 insertions(+), 141 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 838d8af..0ca4aae 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,7 @@ ++2013-03-02 Vladimir Serbinenko ++ ++ * grub-core/fs/hfs.c: Remove nested functions. ++ + 2013-03-01 Vladimir Serbinenko + + * grub-core/fs/hfsplus.c (grub_hfsplus_btree_iterate_node): Pass +diff --git a/grub-core/fs/hfs.c b/grub-core/fs/hfs.c +index 4b2b5aa..73ac7f9 100644 +--- a/grub-core/fs/hfs.c ++++ b/grub-core/fs/hfs.c +@@ -161,15 +161,15 @@ struct grub_hfs_filerec + struct grub_hfs_record + { + void *key; +- int keylen; ++ grub_size_t keylen; + void *data; +- int datalen; ++ grub_size_t datalen; + }; + + static grub_dl_t my_mod; + + static int grub_hfs_find_node (struct grub_hfs_data *, char *, +- grub_uint32_t, int, char *, int); ++ grub_uint32_t, int, char *, grub_size_t); + + /* Find block BLOCK of the file FILE in the mounted UFS filesystem + DATA. The first 3 extents are described by DAT. If cache is set, +@@ -396,8 +396,8 @@ grub_hfs_mount (grub_disk_t disk) + + /* Compare the K1 and K2 catalog file keys using HFS character ordering. */ + static int +-grub_hfs_cmp_catkeys (struct grub_hfs_catalog_key *k1, +- struct grub_hfs_catalog_key *k2) ++grub_hfs_cmp_catkeys (const struct grub_hfs_catalog_key *k1, ++ const struct grub_hfs_catalog_key *k2) + { + /* Taken from hfsutils 3.2.6 and converted to a readable form */ + static const unsigned char hfs_charorder[256] = { +@@ -640,8 +640,8 @@ grub_hfs_cmp_catkeys (struct grub_hfs_catalog_key *k1, + + /* Compare the K1 and K2 extent overflow file keys. */ + static int +-grub_hfs_cmp_extkeys (struct grub_hfs_extent_key *k1, +- struct grub_hfs_extent_key *k2) ++grub_hfs_cmp_extkeys (const struct grub_hfs_extent_key *k1, ++ const struct grub_hfs_extent_key *k2) + { + int cmp = k1->forktype - k2->forktype; + if (cmp == 0) +@@ -660,7 +660,9 @@ grub_hfs_cmp_extkeys (struct grub_hfs_extent_key *k1, + static grub_err_t + grub_hfs_iterate_records (struct grub_hfs_data *data, int type, int idx, + int this, int (*node_hook) (struct grub_hfs_node *hnd, +- struct grub_hfs_record *)) ++ struct grub_hfs_record *, ++ void *hook_arg), ++ void *hook_arg) + { + int nodesize = type == 0 ? data->cat_size : data->ext_size; + +@@ -714,7 +716,7 @@ grub_hfs_iterate_records (struct grub_hfs_data *data, int type, int idx, + - pnt->keylen - 1 + }; + +- if (node_hook (&node.node, &rec)) ++ if (node_hook (&node.node, &rec, hook_arg)) + return 0; + } + +@@ -724,143 +726,178 @@ grub_hfs_iterate_records (struct grub_hfs_data *data, int type, int idx, + return 0; + } + ++struct grub_hfs_find_node_node_found_ctx ++{ ++ int found; ++ int isleaf; ++ int done; ++ int type; ++ const char *key; ++ char *datar; ++ grub_size_t datalen; ++}; + +-/* Lookup a record in the mounted filesystem DATA using the key KEY. +- The index of the node on top of the tree is IDX. The tree is of +- the type TYPE (0 = catalog node, 1 = extent overflow node). Return +- the data in DATAR with a maximum length of DATALEN. */ + static int +-grub_hfs_find_node (struct grub_hfs_data *data, char *key, +- grub_uint32_t idx, int type, char *datar, int datalen) ++grub_hfs_find_node_node_found (struct grub_hfs_node *hnd, struct grub_hfs_record *rec, ++ void *hook_arg) + { +- int found = -1; +- int isleaf = 0; +- int done = 0; +- +- auto int node_found (struct grub_hfs_node *, struct grub_hfs_record *); ++ struct grub_hfs_find_node_node_found_ctx *ctx = hook_arg; ++ int cmp = 1; + +- int node_found (struct grub_hfs_node *hnd, struct grub_hfs_record *rec) ++ if (ctx->type == 0) ++ cmp = grub_hfs_cmp_catkeys (rec->key, (const void *) ctx->key); ++ else ++ cmp = grub_hfs_cmp_extkeys (rec->key, (const void *) ctx->key); ++ ++ /* If the key is smaller or equal to the current node, mark the ++ entry. In case of a non-leaf mode it will be used to lookup ++ the rest of the tree. */ ++ if (cmp <= 0) ++ ctx->found = grub_be_to_cpu32 (grub_get_unaligned32 (rec->data)); ++ else /* The key can not be found in the tree. */ ++ return 1; ++ ++ /* Check if this node is a leaf node. */ ++ if (hnd->type == GRUB_HFS_NODE_LEAF) + { +- int cmp = 1; +- +- if (type == 0) +- cmp = grub_hfs_cmp_catkeys (rec->key, (void *) key); +- else +- cmp = grub_hfs_cmp_extkeys (rec->key, (void *) key); +- +- /* If the key is smaller or equal to the current node, mark the +- entry. In case of a non-leaf mode it will be used to lookup +- the rest of the tree. */ +- if (cmp <= 0) +- found = grub_be_to_cpu32 (grub_get_unaligned32 (rec->data)); +- else /* The key can not be found in the tree. */ +- return 1; +- +- /* Check if this node is a leaf node. */ +- if (hnd->type == GRUB_HFS_NODE_LEAF) +- { +- isleaf = 1; ++ ctx->isleaf = 1; + +- /* Found it!!!! */ +- if (cmp == 0) +- { +- done = 1; ++ /* Found it!!!! */ ++ if (cmp == 0) ++ { ++ ctx->done = 1; + +- grub_memcpy (datar, rec->data, +- rec->datalen < datalen ? rec->datalen : datalen); +- return 1; +- } ++ grub_memcpy (ctx->datar, rec->data, ++ rec->datalen < ctx->datalen ? rec->datalen : ctx->datalen); ++ return 1; + } +- +- return 0; + } + ++ return 0; ++} ++ ++ ++/* Lookup a record in the mounted filesystem DATA using the key KEY. ++ The index of the node on top of the tree is IDX. The tree is of ++ the type TYPE (0 = catalog node, 1 = extent overflow node). Return ++ the data in DATAR with a maximum length of DATALEN. */ ++static int ++grub_hfs_find_node (struct grub_hfs_data *data, char *key, ++ grub_uint32_t idx, int type, char *datar, grub_size_t datalen) ++{ ++ struct grub_hfs_find_node_node_found_ctx ctx = ++ { ++ .found = -1, ++ .isleaf = 0, ++ .done = 0, ++ .type = type, ++ .key = key, ++ .datar = datar, ++ .datalen = datalen ++ }; ++ + do + { +- found = -1; ++ ctx.found = -1; + +- if (grub_hfs_iterate_records (data, type, idx, 0, node_found)) ++ if (grub_hfs_iterate_records (data, type, idx, 0, grub_hfs_find_node_node_found, &ctx)) + return 0; + +- if (found == -1) ++ if (ctx.found == -1) + return 0; + +- idx = found; +- } while (! isleaf); ++ idx = ctx.found; ++ } while (! ctx.isleaf); + +- return done; ++ return ctx.done; + } + ++struct grub_hfs_iterate_dir_node_found_ctx ++{ ++ grub_uint32_t dir_be; ++ int found; ++ int isleaf; ++ grub_uint32_t next; ++ int (*hook) (struct grub_hfs_record *, void *hook_arg); ++ void *hook_arg; ++}; + +-/* Iterate over the directory with the id DIR. The tree is searched +- starting with the node ROOT_IDX. For every entry in this directory +- call HOOK. */ +-static grub_err_t +-grub_hfs_iterate_dir (struct grub_hfs_data *data, grub_uint32_t root_idx, +- unsigned int dir, int (*hook) (struct grub_hfs_record *)) ++static int ++grub_hfs_iterate_dir_node_found (struct grub_hfs_node *hnd, struct grub_hfs_record *rec, ++ void *hook_arg) + { +- int found = -1; +- int isleaf = 0; +- int next = 0; ++ struct grub_hfs_iterate_dir_node_found_ctx *ctx = hook_arg; ++ struct grub_hfs_catalog_key *ckey = rec->key; + + /* The lowest key possible with DIR as root directory. */ +- struct grub_hfs_catalog_key key = {0, grub_cpu_to_be32 (dir), 0, ""}; ++ const struct grub_hfs_catalog_key key = {0, ctx->dir_be, 0, ""}; + +- auto int node_found (struct grub_hfs_node *, struct grub_hfs_record *); +- auto int it_dir (struct grub_hfs_node * __attribute ((unused)), +- struct grub_hfs_record *); ++ if (grub_hfs_cmp_catkeys (rec->key, &key) <= 0) ++ ctx->found = grub_be_to_cpu32 (grub_get_unaligned32 (rec->data)); + +- +- int node_found (struct grub_hfs_node *hnd, struct grub_hfs_record *rec) ++ if (hnd->type == 0xFF && ckey->strlen > 0) + { +- struct grub_hfs_catalog_key *ckey = rec->key; +- +- if (grub_hfs_cmp_catkeys (rec->key, (void *) &key) <= 0) +- found = grub_be_to_cpu32 (grub_get_unaligned32 (rec->data)); ++ ctx->isleaf = 1; ++ ctx->next = grub_be_to_cpu32 (hnd->next); + +- if (hnd->type == 0xFF && ckey->strlen > 0) +- { +- isleaf = 1; +- next = grub_be_to_cpu32 (hnd->next); ++ /* An entry was found. */ ++ if (ckey->parent_dir == ctx->dir_be) ++ return ctx->hook (rec, ctx->hook_arg); ++ } + +- /* An entry was found. */ +- if (grub_be_to_cpu32 (ckey->parent_dir) == dir) +- return hook (rec); +- } ++ return 0; ++} + +- return 0; +- } ++static int ++grub_hfs_iterate_dir_it_dir (struct grub_hfs_node *hnd __attribute ((unused)), ++ struct grub_hfs_record *rec, ++ void *hook_arg) ++{ ++ struct grub_hfs_catalog_key *ckey = rec->key; ++ struct grub_hfs_iterate_dir_node_found_ctx *ctx = hook_arg; ++ ++ /* Stop when the entries do not match anymore. */ ++ if (ckey->parent_dir != ctx->dir_be) ++ return 1; + +- int it_dir (struct grub_hfs_node *hnd __attribute ((unused)), +- struct grub_hfs_record *rec) +- { +- struct grub_hfs_catalog_key *ckey = rec->key; +- struct grub_hfs_catalog_key *origkey = &key; ++ return ctx->hook (rec, ctx->hook_arg); ++} + +- /* Stop when the entries do not match anymore. */ +- if (grub_be_to_cpu32 (ckey->parent_dir) +- != grub_be_to_cpu32 ((origkey)->parent_dir)) +- return 1; + +- return hook (rec); +- } ++/* Iterate over the directory with the id DIR. The tree is searched ++ starting with the node ROOT_IDX. For every entry in this directory ++ call HOOK. */ ++static grub_err_t ++grub_hfs_iterate_dir (struct grub_hfs_data *data, grub_uint32_t root_idx, ++ grub_uint32_t dir, int (*hook) (struct grub_hfs_record *, void *hook_arg), ++ void *hook_arg) ++{ ++ struct grub_hfs_iterate_dir_node_found_ctx ctx = ++ { ++ .dir_be = grub_cpu_to_be32 (dir), ++ .found = -1, ++ .isleaf = 0, ++ .next = 0, ++ .hook = hook, ++ .hook_arg = hook_arg ++ }; + + do + { +- found = -1; ++ ctx.found = -1; + +- if (grub_hfs_iterate_records (data, 0, root_idx, 0, node_found)) ++ if (grub_hfs_iterate_records (data, 0, root_idx, 0, grub_hfs_iterate_dir_node_found, &ctx)) + return grub_errno; + +- if (found == -1) ++ if (ctx.found == -1) + return 0; + +- root_idx = found; +- } while (! isleaf); ++ root_idx = ctx.found; ++ } while (! ctx.isleaf); + + /* If there was a matching record in this leaf node, continue the + iteration until the last record was found. */ +- grub_hfs_iterate_records (data, 0, next, 1, it_dir); ++ grub_hfs_iterate_records (data, 0, ctx.next, 1, grub_hfs_iterate_dir_it_dir, &ctx); + return grub_errno; + } + +@@ -1148,56 +1185,66 @@ grub_hfs_find_dir (struct grub_hfs_data *data, const char *path, + return grub_errno; + } + +- +- +-static grub_err_t +-grub_hfs_dir (grub_device_t device, const char *path, grub_fs_dir_hook_t hook, +- void *hook_data) ++struct grub_hfs_dir_hook_ctx + { +- int inode; ++ grub_fs_dir_hook_t hook; ++ void *hook_data; ++}; + +- auto int dir_hook (struct grub_hfs_record *rec); ++static int ++grub_hfs_dir_hook (struct grub_hfs_record *rec, void *hook_arg) ++{ ++ struct grub_hfs_dir_hook_ctx *ctx = hook_arg; ++ struct grub_hfs_dirrec *drec = rec->data; ++ struct grub_hfs_filerec *frec = rec->data; ++ struct grub_hfs_catalog_key *ckey = rec->key; ++ char fname[sizeof (ckey->str) * MAX_UTF8_PER_MAC_ROMAN + 1]; ++ struct grub_dirhook_info info; ++ grub_size_t len; + +- int dir_hook (struct grub_hfs_record *rec) +- { +- struct grub_hfs_dirrec *drec = rec->data; +- struct grub_hfs_filerec *frec = rec->data; +- struct grub_hfs_catalog_key *ckey = rec->key; +- char fname[sizeof (ckey->str) * MAX_UTF8_PER_MAC_ROMAN + 1]; +- struct grub_dirhook_info info; +- grub_size_t len; ++ grub_memset (fname, 0, sizeof (fname)); + +- grub_memset (fname, 0, sizeof (fname)); ++ grub_memset (&info, 0, sizeof (info)); + +- grub_memset (&info, 0, sizeof (info)); ++ len = ckey->strlen; ++ if (len > sizeof (ckey->str)) ++ len = sizeof (ckey->str); ++ macroman_to_utf8 (fname, ckey->str, len, 1); + +- len = ckey->strlen; +- if (len > sizeof (ckey->str)) +- len = sizeof (ckey->str); +- macroman_to_utf8 (fname, ckey->str, len, 1); ++ info.case_insensitive = 1; + +- info.case_insensitive = 1; ++ if (drec->type == GRUB_HFS_FILETYPE_DIR) ++ { ++ info.dir = 1; ++ info.mtimeset = 1; ++ info.mtime = grub_be_to_cpu32 (drec->mtime) - 2082844800; ++ return ctx->hook (fname, &info, ctx->hook_data); ++ } ++ if (frec->type == GRUB_HFS_FILETYPE_FILE) ++ { ++ info.dir = 0; ++ info.mtimeset = 1; ++ info.mtime = grub_be_to_cpu32 (frec->mtime) - 2082844800; ++ return ctx->hook (fname, &info, ctx->hook_data); ++ } + +- if (drec->type == GRUB_HFS_FILETYPE_DIR) +- { +- info.dir = 1; +- info.mtimeset = 1; +- info.mtime = grub_be_to_cpu32 (drec->mtime) - 2082844800; +- return hook (fname, &info, hook_data); +- } +- if (frec->type == GRUB_HFS_FILETYPE_FILE) +- { +- info.dir = 0; +- info.mtimeset = 1; +- info.mtime = grub_be_to_cpu32 (frec->mtime) - 2082844800; +- return hook (fname, &info, hook_data); +- } ++ return 0; ++} + +- return 0; +- } ++ ++static grub_err_t ++grub_hfs_dir (grub_device_t device, const char *path, grub_fs_dir_hook_t hook, ++ void *hook_data) ++{ ++ int inode; + + struct grub_hfs_data *data; + struct grub_hfs_filerec frec; ++ struct grub_hfs_dir_hook_ctx ctx = ++ { ++ .hook = hook, ++ .hook_data = hook_data ++ }; + + grub_dl_ref (my_mod); + +@@ -1215,7 +1262,7 @@ grub_hfs_dir (grub_device_t device, const char *path, grub_fs_dir_hook_t hook, + goto fail; + } + +- grub_hfs_iterate_dir (data, data->cat_root, inode, dir_hook); ++ grub_hfs_iterate_dir (data, data->cat_root, inode, grub_hfs_dir_hook, &ctx); + + fail: + grub_free (data); +-- +1.8.1.4 + diff --git a/0180-grub-core-commands-loadenv.c-grub_cmd_list_env-Move-.patch b/0180-grub-core-commands-loadenv.c-grub_cmd_list_env-Move-.patch new file mode 100644 index 0000000..679796d --- /dev/null +++ b/0180-grub-core-commands-loadenv.c-grub_cmd_list_env-Move-.patch @@ -0,0 +1,63 @@ +From d4428b6c09ead48f694ccedd22dc9e9cb773dc77 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sat, 2 Mar 2013 11:45:01 +0100 +Subject: [PATCH 180/364] * grub-core/commands/loadenv.c + (grub_cmd_list_env): Move print_var out of its parent. + +--- + ChangeLog | 5 +++++ + grub-core/commands/loadenv.c | 16 ++++++++-------- + 2 files changed, 13 insertions(+), 8 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 0ca4aae..ddd903a 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,10 @@ + 2013-03-02 Vladimir Serbinenko + ++ * grub-core/commands/loadenv.c (grub_cmd_list_env): Move print_var ++ out of its parent. ++ ++2013-03-02 Vladimir Serbinenko ++ + * grub-core/fs/hfs.c: Remove nested functions. + + 2013-03-01 Vladimir Serbinenko +diff --git a/grub-core/commands/loadenv.c b/grub-core/commands/loadenv.c +index 4b94173..c0a42c5 100644 +--- a/grub-core/commands/loadenv.c ++++ b/grub-core/commands/loadenv.c +@@ -147,6 +147,14 @@ grub_cmd_load_env (grub_extcmd_context_t ctxt, + return grub_errno; + } + ++/* Print all variables in current context. */ ++static int ++print_var (const char *name, const char *value) ++{ ++ grub_printf ("%s=%s\n", name, value); ++ return 0; ++} ++ + static grub_err_t + grub_cmd_list_env (grub_extcmd_context_t ctxt, + int argc __attribute__ ((unused)), +@@ -156,14 +164,6 @@ grub_cmd_list_env (grub_extcmd_context_t ctxt, + grub_file_t file; + grub_envblk_t envblk; + +- /* Print all variables in current context. */ +- auto int print_var (const char *name, const char *value); +- int print_var (const char *name, const char *value) +- { +- grub_printf ("%s=%s\n", name, value); +- return 0; +- } +- + file = open_envblk_file ((state[0].set) ? state[0].arg : 0); + if (! file) + return grub_errno; +-- +1.8.1.4 + diff --git a/0181-grub-core-normal-charset.c-grub_bidi_logical_to_visu.patch b/0181-grub-core-normal-charset.c-grub_bidi_logical_to_visu.patch new file mode 100644 index 0000000..c42c07a --- /dev/null +++ b/0181-grub-core-normal-charset.c-grub_bidi_logical_to_visu.patch @@ -0,0 +1,137 @@ +From 46992a68784aedc4e53ce749a88b6034209af87e Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sat, 2 Mar 2013 11:47:59 +0100 +Subject: [PATCH 181/364] * grub-core/normal/charset.c + (grub_bidi_logical_to_visual): Add hook pass-through parameter. All users + updated and unnested. + +--- + grub-core/gfxmenu/font.c | 2 +- + grub-core/normal/charset.c | 14 +++++++++----- + grub-core/normal/term.c | 14 +++++++------- + include/grub/unicode.h | 3 ++- + 4 files changed, 19 insertions(+), 14 deletions(-) + +diff --git a/grub-core/gfxmenu/font.c b/grub-core/gfxmenu/font.c +index 81a689d..7174837 100644 +--- a/grub-core/gfxmenu/font.c ++++ b/grub-core/gfxmenu/font.c +@@ -52,7 +52,7 @@ grub_font_draw_string (const char *str, grub_font_t font, + return grub_errno; + + visual_len = grub_bidi_logical_to_visual (logical, logical_len, &visual, +- 0, 0, 0, 0, 0, 0); ++ 0, 0, 0, 0, 0, 0, 0); + grub_free (logical); + if (visual_len < 0) + return grub_errno; +diff --git a/grub-core/normal/charset.c b/grub-core/normal/charset.c +index bd9fbf4..ab3101b 100644 +--- a/grub-core/normal/charset.c ++++ b/grub-core/normal/charset.c +@@ -512,7 +512,8 @@ static grub_ssize_t + bidi_line_wrap (struct grub_unicode_glyph *visual_out, + struct grub_unicode_glyph *visual, + grub_size_t visual_len, unsigned *levels, +- grub_ssize_t (*getcharwidth) (const struct grub_unicode_glyph *visual), ++ grub_ssize_t (*getcharwidth) (const struct grub_unicode_glyph *visual, void *getcharwidth_arg), ++ void *getcharwidth_arg, + grub_size_t maxwidth, grub_size_t startwidth, + grub_uint32_t contchar, + struct grub_term_pos *pos, int primitive_wrap, +@@ -577,7 +578,7 @@ bidi_line_wrap (struct grub_unicode_glyph *visual_out, + } + + if (getcharwidth && k != visual_len) +- line_width += last_width = getcharwidth (&visual[k]); ++ line_width += last_width = getcharwidth (&visual[k], getcharwidth_arg); + + if (k != visual_len && (visual[k].base == ' ' + || visual[k].base == '\t') +@@ -752,7 +753,8 @@ static grub_ssize_t + grub_bidi_line_logical_to_visual (const grub_uint32_t *logical, + grub_size_t logical_len, + struct grub_unicode_glyph *visual_out, +- grub_ssize_t (*getcharwidth) (const struct grub_unicode_glyph *visual), ++ grub_ssize_t (*getcharwidth) (const struct grub_unicode_glyph *visual, void *getcharwidth_arg), ++ void *getcharwidth_arg, + grub_size_t maxwidth, grub_size_t startwidth, + grub_uint32_t contchar, + struct grub_term_pos *pos, +@@ -1116,7 +1118,7 @@ grub_bidi_line_logical_to_visual (const grub_uint32_t *logical, + { + grub_ssize_t ret; + ret = bidi_line_wrap (visual_out, visual, visual_len, levels, +- getcharwidth, maxwidth, startwidth, contchar, ++ getcharwidth, getcharwidth_arg, maxwidth, startwidth, contchar, + pos, primitive_wrap, log_end); + grub_free (levels); + grub_free (visual); +@@ -1128,7 +1130,8 @@ grub_ssize_t + grub_bidi_logical_to_visual (const grub_uint32_t *logical, + grub_size_t logical_len, + struct grub_unicode_glyph **visual_out, +- grub_ssize_t (*getcharwidth) (const struct grub_unicode_glyph *visual), ++ grub_ssize_t (*getcharwidth) (const struct grub_unicode_glyph *visual, void *getcharwidth_arg), ++ void *getcharwidth_arg, + grub_size_t max_length, grub_size_t startwidth, + grub_uint32_t contchar, struct grub_term_pos *pos, int primitive_wrap) + { +@@ -1147,6 +1150,7 @@ grub_bidi_logical_to_visual (const grub_uint32_t *logical, + ptr - line_start, + visual_ptr, + getcharwidth, ++ getcharwidth_arg, + max_length, + startwidth, + contchar, +diff --git a/grub-core/normal/term.c b/grub-core/normal/term.c +index dc03268..ae91071 100644 +--- a/grub-core/normal/term.c ++++ b/grub-core/normal/term.c +@@ -840,6 +840,12 @@ print_backlog (struct grub_term_output *term, + return 0; + } + ++static grub_ssize_t ++getcharwidth (const struct grub_unicode_glyph *c, void *term) ++{ ++ return grub_term_getcharwidth (term, c); ++} ++ + static int + print_ucs4_real (const grub_uint32_t * str, + const grub_uint32_t * last_position, +@@ -881,14 +887,8 @@ print_ucs4_real (const grub_uint32_t * str, + int ret; + struct grub_unicode_glyph *vptr; + +- auto grub_ssize_t getcharwidth (const struct grub_unicode_glyph *c); +- grub_ssize_t getcharwidth (const struct grub_unicode_glyph *c) +- { +- return grub_term_getcharwidth (term, c); +- } +- + visual_len = grub_bidi_logical_to_visual (str, last_position - str, +- &visual, getcharwidth, ++ &visual, getcharwidth, term, + get_maxwidth (term, + margin_left, + margin_right), +diff --git a/include/grub/unicode.h b/include/grub/unicode.h +index eb5051a..5a96a19 100644 +--- a/include/grub/unicode.h ++++ b/include/grub/unicode.h +@@ -240,7 +240,8 @@ grub_ssize_t + grub_bidi_logical_to_visual (const grub_uint32_t *logical, + grub_size_t logical_len, + struct grub_unicode_glyph **visual_out, +- grub_ssize_t (*getcharwidth) (const struct grub_unicode_glyph *visual), ++ grub_ssize_t (*getcharwidth) (const struct grub_unicode_glyph *visual, void *getcharwidth_arg), ++ void *getcharwidth_arg, + grub_size_t max_width, + grub_size_t start_width, grub_uint32_t codechar, + struct grub_term_pos *pos, +-- +1.8.1.4 + diff --git a/0182-grub-core-script-execute.c-gettext_append-Remove-nes.patch b/0182-grub-core-script-execute.c-gettext_append-Remove-nes.patch new file mode 100644 index 0000000..e1bec98 --- /dev/null +++ b/0182-grub-core-script-execute.c-gettext_append-Remove-nes.patch @@ -0,0 +1,319 @@ +From 5a04b68d6ab44ac2da3dee3d0d36747156c21238 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sat, 2 Mar 2013 12:17:52 +0100 +Subject: [PATCH 182/364] * grub-core/script/execute.c (gettext_append): + Remove nested functions. + +--- + ChangeLog | 9 +++ + grub-core/script/execute.c | 180 ++++++++++++++++++++++++--------------------- + 2 files changed, 107 insertions(+), 82 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index ddd903a..07318d8 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,14 @@ + 2013-03-02 Vladimir Serbinenko + ++ * grub-core/script/execute.c (gettext_append): Remove nested functions. ++ ++2013-03-02 Vladimir Serbinenko ++ ++ * grub-core/normal/charset.c (grub_bidi_logical_to_visual): Add ++ hook pass-through parameter. All users updated and unnested. ++ ++2013-03-02 Vladimir Serbinenko ++ + * grub-core/commands/loadenv.c (grub_cmd_list_env): Move print_var + out of its parent. + +diff --git a/grub-core/script/execute.c b/grub-core/script/execute.c +index 6619c2e..d6a2c78 100644 +--- a/grub-core/script/execute.c ++++ b/grub-core/script/execute.c +@@ -372,10 +372,19 @@ grub_script_env_set (const char *name, const char *val) + return grub_env_set (name, val); + } + ++struct gettext_context ++{ ++ char **allowed_strings; ++ grub_size_t nallowed_strings; ++ grub_size_t additional_len; ++}; ++ + static int + parse_string (const char *str, +- int (*hook) (const char *var, grub_size_t varlen), +- char **put) ++ int (*hook) (const char *var, grub_size_t varlen, ++ char **ptr, struct gettext_context *ctx), ++ struct gettext_context *ctx, ++ char *put) + { + const char *ptr; + int escaped = 0; +@@ -387,7 +396,7 @@ parse_string (const char *str, + case '\\': + escaped = !escaped; + if (!escaped && put) +- *((*put)++) = '\\'; ++ *(put++) = '\\'; + ptr++; + break; + case '$': +@@ -395,7 +404,7 @@ parse_string (const char *str, + { + escaped = 0; + if (put) +- *((*put)++) = *ptr; ++ *(put++) = *ptr; + ptr++; + break; + } +@@ -409,7 +418,7 @@ parse_string (const char *str, + ptr = grub_strchr (optr, '}'); + if (!ptr) + break; +- if (hook (optr, ptr - optr)) ++ if (hook (optr, ptr - optr, &put, ctx)) + return 1; + ptr++; + break; +@@ -418,7 +427,7 @@ parse_string (const char *str, + optr = ptr; + while (*ptr >= '0' && *ptr <= '9') + ptr++; +- if (hook (optr, ptr - optr)) ++ if (hook (optr, ptr - optr, &put, ctx)) + return 1; + break; + case 'a' ... 'z': +@@ -430,129 +439,136 @@ parse_string (const char *str, + || (*ptr >= 'A' && *ptr <= 'Z') + || *ptr == '_') + ptr++; +- if (hook (optr, ptr - optr)) ++ if (hook (optr, ptr - optr, &put, ctx)) + return 1; + break; + case '?': + case '#': +- if (hook (ptr, 1)) ++ if (hook (ptr, 1, &put, ctx)) + return 1; + ptr++; + break; + default: + if (put) +- *((*put)++) = '$'; ++ *(put++) = '$'; + } + break; + default: + if (escaped && put) +- *((*put)++) = '\\'; ++ *(put++) = '\\'; + escaped = 0; + if (put) +- *((*put)++) = *ptr; ++ *(put++) = *ptr; + ptr++; + break; + } ++ if (put) ++ *(put++) = 0; + return 0; + } + + static int +-gettext_append (struct grub_script_argv *result, const char *orig_str) ++gettext_putvar (const char *str, grub_size_t len, ++ char **ptr, struct gettext_context *ctx) + { +- const char *template; +- char *res = 0, *ptr; +- char **allowed_strings; +- grub_size_t nallowed_strings = 0; +- grub_size_t additional_len = 1; +- int rval = 1; +- const char *iptr; ++ const char *var; ++ grub_size_t i; + +- auto int save_allow (const char *str, grub_size_t len); +- int save_allow (const char *str, grub_size_t len) +- { +- allowed_strings[nallowed_strings++] = grub_strndup (str, len); +- if (!allowed_strings[nallowed_strings - 1]) +- return 1; ++ for (i = 0; i < ctx->nallowed_strings; i++) ++ if (grub_strncmp (ctx->allowed_strings[i], str, len) == 0 ++ && ctx->allowed_strings[i][len] == 0) ++ { ++ break; ++ } ++ if (i == ctx->nallowed_strings) + return 0; +- } +- +- auto int getlen (const char *str, grub_size_t len); +- int getlen (const char *str, grub_size_t len) +- { +- const char *var; +- grub_size_t i; + +- for (i = 0; i < nallowed_strings; i++) +- if (grub_strncmp (allowed_strings[i], str, len) == 0 +- && allowed_strings[i][len] == 0) +- break; +- if (i == nallowed_strings) ++ /* Enough for any number. */ ++ if (len == 1 && str[0] == '#') ++ { ++ grub_snprintf (*ptr, 30, "%u", scope->argv.argc); ++ *ptr += grub_strlen (*ptr); + return 0; ++ } ++ var = grub_env_get (ctx->allowed_strings[i]); ++ if (var) ++ *ptr = grub_stpcpy (*ptr, var); ++ return 0; ++} + +- /* Enough for any number. */ +- if (len == 1 && str[0] == '#') +- { +- additional_len += 30; +- return 0; +- } +- var = grub_env_get (allowed_strings[i]); +- if (var) +- additional_len += grub_strlen (var); +- return 0; +- } ++static int ++gettext_save_allow (const char *str, grub_size_t len, ++ char **ptr __attribute__ ((unused)), ++ struct gettext_context *ctx) ++{ ++ ctx->allowed_strings[ctx->nallowed_strings++] = grub_strndup (str, len); ++ if (!ctx->allowed_strings[ctx->nallowed_strings - 1]) ++ return 1; ++ return 0; ++} + +- auto int putvar (const char *str, grub_size_t len); +- int putvar (const char *str, grub_size_t len) +- { +- const char *var; +- grub_size_t i; ++static int ++gettext_getlen (const char *str, grub_size_t len, ++ char **ptr __attribute__ ((unused)), ++ struct gettext_context *ctx) ++{ ++ const char *var; ++ grub_size_t i; + +- for (i = 0; i < nallowed_strings; i++) +- if (grub_strncmp (allowed_strings[i], str, len) == 0 +- && allowed_strings[i][len] == 0) +- { +- break; +- } +- if (i == nallowed_strings) ++ for (i = 0; i < ctx->nallowed_strings; i++) ++ if (grub_strncmp (ctx->allowed_strings[i], str, len) == 0 ++ && ctx->allowed_strings[i][len] == 0) ++ break; ++ if (i == ctx->nallowed_strings) ++ return 0; ++ ++ /* Enough for any number. */ ++ if (len == 1 && str[0] == '#') ++ { ++ ctx->additional_len += 30; + return 0; ++ } ++ var = grub_env_get (ctx->allowed_strings[i]); ++ if (var) ++ ctx->additional_len += grub_strlen (var); ++ return 0; ++} + +- /* Enough for any number. */ +- if (len == 1 && str[0] == '#') +- { +- grub_snprintf (ptr, 30, "%u", scope->argv.argc); +- ptr += grub_strlen (ptr); +- return 0; +- } +- var = grub_env_get (allowed_strings[i]); +- if (var) +- ptr = grub_stpcpy (ptr, var); +- return 0; +- } ++static int ++gettext_append (struct grub_script_argv *result, const char *orig_str) ++{ ++ const char *template; ++ char *res = 0; ++ struct gettext_context ctx = { ++ .allowed_strings = 0, ++ .nallowed_strings = 0, ++ .additional_len = 1 ++ }; ++ int rval = 1; ++ const char *iptr; + + grub_size_t dollar_cnt = 0; + + for (iptr = orig_str; *iptr; iptr++) + if (*iptr == '$') + dollar_cnt++; +- allowed_strings = grub_malloc (sizeof (allowed_strings[0]) * dollar_cnt); ++ ctx.allowed_strings = grub_malloc (sizeof (ctx.allowed_strings[0]) * dollar_cnt); + +- if (parse_string (orig_str, save_allow, 0)) ++ if (parse_string (orig_str, gettext_save_allow, &ctx, 0)) + goto fail; + + template = _(orig_str); + +- if (parse_string (template, getlen, 0)) ++ if (parse_string (template, gettext_getlen, &ctx, 0)) + goto fail; + +- res = grub_malloc (grub_strlen (template) + additional_len); ++ res = grub_malloc (grub_strlen (template) + ctx.additional_len); + if (!res) + goto fail; +- ptr = res; + +- if (parse_string (template, putvar, &ptr)) ++ if (parse_string (template, gettext_putvar, &ctx, res)) + goto fail; + +- *ptr = 0; + char *escaped = 0; + escaped = wildcard_escape (res); + if (grub_script_argv_append (result, escaped, grub_strlen (escaped))) +@@ -567,10 +583,10 @@ gettext_append (struct grub_script_argv *result, const char *orig_str) + grub_free (res); + { + grub_size_t i; +- for (i = 0; i < nallowed_strings; i++) +- grub_free (allowed_strings[i]); ++ for (i = 0; i < ctx.nallowed_strings; i++) ++ grub_free (ctx.allowed_strings[i]); + } +- grub_free (allowed_strings); ++ grub_free (ctx.allowed_strings); + return rval; + } + +-- +1.8.1.4 + diff --git a/0183-grub-core-lib-ia64-longjmp.S-Fix-the-name-of-longjmp.patch b/0183-grub-core-lib-ia64-longjmp.S-Fix-the-name-of-longjmp.patch new file mode 100644 index 0000000..f514359 --- /dev/null +++ b/0183-grub-core-lib-ia64-longjmp.S-Fix-the-name-of-longjmp.patch @@ -0,0 +1,90 @@ +From 299c2c7a024efb609bf7fcf63e0cd9b59e16e684 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sat, 2 Mar 2013 15:31:17 +0100 +Subject: [PATCH 183/364] * grub-core/lib/ia64/longjmp.S: Fix the name + of longjmp function. * grub-core/lib/ia64/setjmp.S: Fix the name of setjmp + function. + +--- + ChangeLog | 5 +++++ + grub-core/lib/ia64/longjmp.S | 10 +++++----- + grub-core/lib/ia64/setjmp.S | 8 ++++---- + include/grub/ia64/setjmp.h | 2 +- + 4 files changed, 15 insertions(+), 10 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 07318d8..d55dd8f 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,10 @@ + 2013-03-02 Vladimir Serbinenko + ++ * grub-core/lib/ia64/longjmp.S: Fix the name of longjmp function. ++ * grub-core/lib/ia64/setjmp.S: Fix the name of setjmp function. ++ ++2013-03-02 Vladimir Serbinenko ++ + * grub-core/script/execute.c (gettext_append): Remove nested functions. + + 2013-03-02 Vladimir Serbinenko +diff --git a/grub-core/lib/ia64/longjmp.S b/grub-core/lib/ia64/longjmp.S +index 729bdc7..38afb22 100644 +--- a/grub-core/lib/ia64/longjmp.S ++++ b/grub-core/lib/ia64/longjmp.S +@@ -40,10 +40,10 @@ + + /* __longjmp(__jmp_buf buf, int val) */ + +- .text +- .global longjmp +- .proc longjmp +-longjmp: ++ .text ++ ++ .proc EXT_C(grub_longjmp) ++FUNCTION(grub_longjmp) + alloc r8=ar.pfs,2,1,0,0 + mov r27=ar.rsc + add r2=0x98,in0 // r2 <- &jmpbuf.orig_jmp_buf_addr +@@ -159,4 +159,4 @@ longjmp: + invala // virt. -> phys. regnum mapping may change + mov pr=r24,-1 + br.ret.dptk.few rp +- .endp longjmp ++ .endp EXT_C(grub_longjmp) +diff --git a/grub-core/lib/ia64/setjmp.S b/grub-core/lib/ia64/setjmp.S +index dc19be0..a0382d8 100644 +--- a/grub-core/lib/ia64/setjmp.S ++++ b/grub-core/lib/ia64/setjmp.S +@@ -74,13 +74,13 @@ GRUB_MOD_LICENSE "GPLv2+" + /* The following two entry points are the traditional entry points: */ + + .text +- .global setjmp +- .proc setjmp +-setjmp: ++ ++ .proc EXT_C(grub_setjmp) ++FUNCTION(grub_setjmp) + alloc r8=ar.pfs,2,0,0,0 + mov in1=1 + br.cond.sptk.many __sigsetjmp +- .endp setjmp ++ .endp EXT_C(grub_setjmp) + + /* __sigsetjmp(__jmp_buf buf, int savemask) */ + +diff --git a/include/grub/ia64/setjmp.h b/include/grub/ia64/setjmp.h +index a71c9c5..6e9bc8b 100644 +--- a/include/grub/ia64/setjmp.h ++++ b/include/grub/ia64/setjmp.h +@@ -24,5 +24,5 @@ + /* the __jmp_buf element type should be __float80 per ABI... */ + typedef long grub_jmp_buf[_JBLEN] __attribute__ ((aligned (16))); /* guarantees 128-bit alignment! */ + +-int grub_setjmp (grub_jmp_buf env); ++int grub_setjmp (grub_jmp_buf env) __attribute__ ((returns_twice)); + void grub_longjmp (grub_jmp_buf env, int val) __attribute__ ((noreturn)); +-- +1.8.1.4 + diff --git a/0184-Make-elfload-not-use-hooks.-Opt-for-flags-and-iterat.patch b/0184-Make-elfload-not-use-hooks.-Opt-for-flags-and-iterat.patch new file mode 100644 index 0000000..2dedcfb --- /dev/null +++ b/0184-Make-elfload-not-use-hooks.-Opt-for-flags-and-iterat.patch @@ -0,0 +1,1184 @@ +From efd159c0660c89f90089c7570c17c58c68df6dbe Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sat, 2 Mar 2013 16:45:57 +0100 +Subject: [PATCH 184/364] Make elfload not use hooks. Opt for flags and + iterators instead. + +--- + ChangeLog | 4 + + grub-core/kern/elf.c | 455 +++------------------------ + grub-core/kern/elfXX.c | 144 +++++++++ + grub-core/loader/i386/bsd.c | 137 +++----- + grub-core/loader/i386/coreboot/chainloader.c | 69 ++-- + grub-core/loader/mips/linux.c | 37 +-- + grub-core/loader/powerpc/ieee1275/linux.c | 34 +- + grub-core/loader/sparc64/ieee1275/linux.c | 18 +- + include/grub/elfload.h | 35 ++- + 9 files changed, 301 insertions(+), 632 deletions(-) + create mode 100644 grub-core/kern/elfXX.c + +diff --git a/ChangeLog b/ChangeLog +index d55dd8f..7c80ed6 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,9 @@ + 2013-03-02 Vladimir Serbinenko + ++ Make elfload not use hooks. Opt for flags and iterators instead. ++ ++2013-03-02 Vladimir Serbinenko ++ + * grub-core/lib/ia64/longjmp.S: Fix the name of longjmp function. + * grub-core/lib/ia64/setjmp.S: Fix the name of setjmp function. + +diff --git a/grub-core/kern/elf.c b/grub-core/kern/elf.c +index f52ca21..5f99c43 100644 +--- a/grub-core/kern/elf.c ++++ b/grub-core/kern/elf.c +@@ -51,6 +51,7 @@ grub_elf_close (grub_elf_t elf) + grub_file_t file = elf->file; + + grub_free (elf->phdrs); ++ grub_free (elf->filename); + grub_free (elf); + + if (file) +@@ -85,9 +86,14 @@ grub_elf_file (grub_file_t file, const char *filename) + if (grub_elf_check_header (elf)) + goto fail; + ++ elf->filename = grub_strdup (filename); ++ if (!elf->filename) ++ goto fail; ++ + return elf; + + fail: ++ grub_free (elf->filename); + grub_free (elf->phdrs); + grub_free (elf); + return 0; +@@ -112,420 +118,41 @@ grub_elf_open (const char *name) + + + /* 32-bit */ +- +-int +-grub_elf_is_elf32 (grub_elf_t elf) +-{ +- return elf->ehdr.ehdr32.e_ident[EI_CLASS] == ELFCLASS32; +-} +- +-static grub_err_t +-grub_elf32_load_phdrs (grub_elf_t elf, const char *filename) +-{ +- grub_ssize_t phdrs_size; +- +- phdrs_size = elf->ehdr.ehdr32.e_phnum * elf->ehdr.ehdr32.e_phentsize; +- +- grub_dprintf ("elf", "Loading program headers at 0x%llx, size 0x%lx.\n", +- (unsigned long long) elf->ehdr.ehdr32.e_phoff, +- (unsigned long) phdrs_size); +- +- elf->phdrs = grub_malloc (phdrs_size); +- if (! elf->phdrs) +- return grub_errno; +- +- if ((grub_file_seek (elf->file, elf->ehdr.ehdr32.e_phoff) == (grub_off_t) -1) +- || (grub_file_read (elf->file, elf->phdrs, phdrs_size) != phdrs_size)) +- { +- if (!grub_errno) +- grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"), +- filename); +- return grub_errno; +- } +- +- return GRUB_ERR_NONE; +-} +- +-grub_err_t +-grub_elf32_phdr_iterate (grub_elf_t elf, +- const char *filename, +- grub_elf32_phdr_iterate_hook_t hook, void *hook_arg) +-{ +- Elf32_Phdr *phdrs; +- unsigned int i; +- +- if (! elf->phdrs) +- if (grub_elf32_load_phdrs (elf, filename)) +- return grub_errno; +- phdrs = elf->phdrs; +- +- for (i = 0; i < elf->ehdr.ehdr32.e_phnum; i++) +- { +- Elf32_Phdr *phdr = phdrs + i; +- grub_dprintf ("elf", +- "Segment %u: type 0x%x paddr 0x%lx memsz 0x%lx " +- "filesz %lx\n", +- i, phdr->p_type, +- (unsigned long) phdr->p_paddr, +- (unsigned long) phdr->p_memsz, +- (unsigned long) phdr->p_filesz); +- if (hook (elf, phdr, hook_arg)) +- break; +- } +- +- return grub_errno; +-} +- +-struct grub_elf32_size_ctx +-{ +- Elf32_Addr segments_start, segments_end; +- int nr_phdrs; +- grub_uint32_t curr_align; +-}; +- +-/* Run through the program headers to calculate the total memory size we +- * should claim. */ +-static int +-grub_elf32_calcsize (grub_elf_t _elf __attribute__ ((unused)), +- Elf32_Phdr *phdr, void *data) +-{ +- struct grub_elf32_size_ctx *ctx = data; +- +- /* Only consider loadable segments. */ +- if (phdr->p_type != PT_LOAD) +- return 0; +- ctx->nr_phdrs++; +- if (phdr->p_paddr < ctx->segments_start) +- ctx->segments_start = phdr->p_paddr; +- if (phdr->p_paddr + phdr->p_memsz > ctx->segments_end) +- ctx->segments_end = phdr->p_paddr + phdr->p_memsz; +- if (ctx->curr_align < phdr->p_align) +- ctx->curr_align = phdr->p_align; +- return 0; +-} +- +-/* Calculate the amount of memory spanned by the segments. */ +-grub_size_t +-grub_elf32_size (grub_elf_t elf, const char *filename, +- Elf32_Addr *base, grub_uint32_t *max_align) +-{ +- struct grub_elf32_size_ctx ctx = { +- .segments_start = (Elf32_Addr) -1, +- .segments_end = 0, +- .nr_phdrs = 0, +- .curr_align = 1 +- }; +- +- grub_elf32_phdr_iterate (elf, filename, grub_elf32_calcsize, &ctx); +- +- if (base) +- *base = 0; +- +- if (ctx.nr_phdrs == 0) +- { +- grub_error (GRUB_ERR_BAD_OS, "no program headers present"); +- return 0; +- } +- +- if (ctx.segments_end < ctx.segments_start) +- { +- /* Very bad addresses. */ +- grub_error (GRUB_ERR_BAD_OS, "bad program header load addresses"); +- return 0; +- } +- +- if (base) +- *base = ctx.segments_start; +- if (max_align) +- *max_align = ctx.curr_align; +- return ctx.segments_end - ctx.segments_start; +-} +- +-struct grub_elf32_load_ctx +-{ +- const char *filename; +- grub_elf32_load_hook_t load_hook; +- grub_addr_t load_base; +- grub_size_t load_size; +-}; +- +-static int +-grub_elf32_load_segment (grub_elf_t elf, Elf32_Phdr *phdr, void *data) +-{ +- struct grub_elf32_load_ctx *ctx = data; +- grub_addr_t load_addr; +- int do_load = 1; +- +- load_addr = phdr->p_paddr; +- if (ctx->load_hook && ctx->load_hook (phdr, &load_addr, &do_load)) +- return 1; +- +- if (! do_load) +- return 0; +- +- if (load_addr < ctx->load_base) +- ctx->load_base = load_addr; +- +- grub_dprintf ("elf", "Loading segment at 0x%llx, size 0x%llx\n", +- (unsigned long long) load_addr, +- (unsigned long long) phdr->p_memsz); +- +- if (grub_file_seek (elf->file, phdr->p_offset) == (grub_off_t) -1) +- return grub_errno; +- +- if (phdr->p_filesz) +- { +- grub_ssize_t read; +- read = grub_file_read (elf->file, (void *) load_addr, phdr->p_filesz); +- if (read != (grub_ssize_t) phdr->p_filesz) +- { +- /* XXX How can we free memory from `ctx->load_hook'? */ +- if (!grub_errno) +- grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"), +- ctx->filename); +- return grub_errno; +- } +- } +- +- if (phdr->p_filesz < phdr->p_memsz) +- grub_memset ((void *) (long) (load_addr + phdr->p_filesz), +- 0, phdr->p_memsz - phdr->p_filesz); +- +- ctx->load_size += phdr->p_memsz; +- +- return 0; +-} +- +-/* Load every loadable segment into memory specified by `_load_hook'. */ +-grub_err_t +-grub_elf32_load (grub_elf_t elf, const char *filename, +- grub_elf32_load_hook_t load_hook, +- grub_addr_t *base, grub_size_t *size) +-{ +- struct grub_elf32_load_ctx ctx = { +- .filename = filename, +- .load_hook = load_hook, +- .load_base = (grub_addr_t) -1ULL, +- .load_size = 0 +- }; +- grub_err_t err; +- +- err = grub_elf32_phdr_iterate (elf, filename, grub_elf32_load_segment, &ctx); +- +- if (base) +- *base = ctx.load_base; +- if (size) +- *size = ctx.load_size; +- +- return err; +-} ++#define ehdrXX ehdr32 ++#define ELFCLASSXX ELFCLASS32 ++#define ElfXX_Addr Elf32_Addr ++#define grub_elfXX_size grub_elf32_size ++#define grub_elfXX_load grub_elf32_load ++#define FOR_ELFXX_PHDRS FOR_ELF32_PHDRS ++#define grub_elf_is_elfXX grub_elf_is_elf32 ++#define grub_elfXX_load_phdrs grub_elf32_load_phdrs ++#define ElfXX_Phdr Elf32_Phdr ++#define grub_uintXX_t grub_uint32_t ++ ++#include "elfXX.c" ++ ++#undef ehdrXX ++#undef ELFCLASSXX ++#undef ElfXX_Addr ++#undef grub_elfXX_size ++#undef grub_elfXX_load ++#undef FOR_ELFXX_PHDRS ++#undef grub_elf_is_elfXX ++#undef grub_elfXX_load_phdrs ++#undef ElfXX_Phdr ++#undef grub_uintXX_t + + + /* 64-bit */ +- +-int +-grub_elf_is_elf64 (grub_elf_t elf) +-{ +- return elf->ehdr.ehdr64.e_ident[EI_CLASS] == ELFCLASS64; +-} +- +-static grub_err_t +-grub_elf64_load_phdrs (grub_elf_t elf, const char *filename) +-{ +- grub_ssize_t phdrs_size; +- +- phdrs_size = elf->ehdr.ehdr64.e_phnum * elf->ehdr.ehdr64.e_phentsize; +- +- grub_dprintf ("elf", "Loading program headers at 0x%llx, size 0x%lx.\n", +- (unsigned long long) elf->ehdr.ehdr64.e_phoff, +- (unsigned long) phdrs_size); +- +- elf->phdrs = grub_malloc (phdrs_size); +- if (! elf->phdrs) +- return grub_errno; +- +- if ((grub_file_seek (elf->file, elf->ehdr.ehdr64.e_phoff) == (grub_off_t) -1) +- || (grub_file_read (elf->file, elf->phdrs, phdrs_size) != phdrs_size)) +- { +- if (!grub_errno) +- grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"), +- filename); +- return grub_errno; +- } +- +- return GRUB_ERR_NONE; +-} +- +-grub_err_t +-grub_elf64_phdr_iterate (grub_elf_t elf, +- const char *filename, +- grub_elf64_phdr_iterate_hook_t hook, void *hook_arg) +-{ +- Elf64_Phdr *phdrs; +- unsigned int i; +- +- if (! elf->phdrs) +- if (grub_elf64_load_phdrs (elf, filename)) +- return grub_errno; +- phdrs = elf->phdrs; +- +- for (i = 0; i < elf->ehdr.ehdr64.e_phnum; i++) +- { +- Elf64_Phdr *phdr = phdrs + i; +- grub_dprintf ("elf", +- "Segment %u: type 0x%x paddr 0x%lx memsz 0x%lx " +- "filesz %lx\n", +- i, phdr->p_type, +- (unsigned long) phdr->p_paddr, +- (unsigned long) phdr->p_memsz, +- (unsigned long) phdr->p_filesz); +- if (hook (elf, phdr, hook_arg)) +- break; +- } +- +- return grub_errno; +-} +- +-struct grub_elf64_size_ctx +-{ +- Elf64_Addr segments_start, segments_end; +- int nr_phdrs; +- grub_uint64_t curr_align; +-}; +- +-/* Run through the program headers to calculate the total memory size we +- * should claim. */ +-static int +-grub_elf64_calcsize (grub_elf_t _elf __attribute__ ((unused)), +- Elf64_Phdr *phdr, void *data) +-{ +- struct grub_elf64_size_ctx *ctx = data; +- +- /* Only consider loadable segments. */ +- if (phdr->p_type != PT_LOAD) +- return 0; +- ctx->nr_phdrs++; +- if (phdr->p_paddr < ctx->segments_start) +- ctx->segments_start = phdr->p_paddr; +- if (phdr->p_paddr + phdr->p_memsz > ctx->segments_end) +- ctx->segments_end = phdr->p_paddr + phdr->p_memsz; +- if (ctx->curr_align < phdr->p_align) +- ctx->curr_align = phdr->p_align; +- return 0; +-} +- +-/* Calculate the amount of memory spanned by the segments. */ +-grub_size_t +-grub_elf64_size (grub_elf_t elf, const char *filename, +- Elf64_Addr *base, grub_uint64_t *max_align) +-{ +- struct grub_elf64_size_ctx ctx = { +- .segments_start = (Elf64_Addr) -1, +- .segments_end = 0, +- .nr_phdrs = 0, +- .curr_align = 1 +- }; +- +- grub_elf64_phdr_iterate (elf, filename, grub_elf64_calcsize, &ctx); +- +- if (base) +- *base = 0; +- +- if (ctx.nr_phdrs == 0) +- { +- grub_error (GRUB_ERR_BAD_OS, "no program headers present"); +- return 0; +- } +- +- if (ctx.segments_end < ctx.segments_start) +- { +- /* Very bad addresses. */ +- grub_error (GRUB_ERR_BAD_OS, "bad program header load addresses"); +- return 0; +- } +- +- if (base) +- *base = ctx.segments_start; +- if (max_align) +- *max_align = ctx.curr_align; +- return ctx.segments_end - ctx.segments_start; +-} +- +-struct grub_elf64_load_ctx +-{ +- const char *filename; +- grub_elf64_load_hook_t load_hook; +- grub_addr_t load_base; +- grub_size_t load_size; +-}; +- +-static int +-grub_elf64_load_segment (grub_elf_t elf, Elf64_Phdr *phdr, void *data) +-{ +- struct grub_elf64_load_ctx *ctx = data; +- grub_addr_t load_addr; +- int do_load = 1; +- +- load_addr = phdr->p_paddr; +- if (ctx->load_hook && ctx->load_hook (phdr, &load_addr, &do_load)) +- return 1; +- +- if (! do_load) +- return 0; +- +- if (load_addr < ctx->load_base) +- ctx->load_base = load_addr; +- +- grub_dprintf ("elf", "Loading segment at 0x%llx, size 0x%llx\n", +- (unsigned long long) load_addr, +- (unsigned long long) phdr->p_memsz); +- +- if (grub_file_seek (elf->file, phdr->p_offset) == (grub_off_t) -1) +- return grub_errno; +- +- if (phdr->p_filesz) +- { +- grub_ssize_t read; +- read = grub_file_read (elf->file, (void *) load_addr, phdr->p_filesz); +- if (read != (grub_ssize_t) phdr->p_filesz) +- { +- /* XXX How can we free memory from `ctx->load_hook'? */ +- if (!grub_errno) +- grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"), +- ctx->filename); +- return grub_errno; +- } +- } +- +- if (phdr->p_filesz < phdr->p_memsz) +- grub_memset ((void *) (long) (load_addr + phdr->p_filesz), +- 0, phdr->p_memsz - phdr->p_filesz); +- +- ctx->load_size += phdr->p_memsz; +- +- return 0; +-} +- +-/* Load every loadable segment into memory specified by `_load_hook'. */ +-grub_err_t +-grub_elf64_load (grub_elf_t elf, const char *filename, +- grub_elf64_load_hook_t load_hook, +- grub_addr_t *base, grub_size_t *size) +-{ +- struct grub_elf64_load_ctx ctx = { +- .filename = filename, +- .load_hook = load_hook, +- .load_base = (grub_addr_t) -1ULL, +- .load_size = 0 +- }; +- grub_err_t err; +- +- err = grub_elf64_phdr_iterate (elf, filename, grub_elf64_load_segment, &ctx); +- +- if (base) +- *base = ctx.load_base; +- if (size) +- *size = ctx.load_size; +- +- return err; +-} ++#define ehdrXX ehdr64 ++#define ELFCLASSXX ELFCLASS64 ++#define ElfXX_Addr Elf64_Addr ++#define grub_elfXX_size grub_elf64_size ++#define grub_elfXX_load grub_elf64_load ++#define FOR_ELFXX_PHDRS FOR_ELF64_PHDRS ++#define grub_elf_is_elfXX grub_elf_is_elf64 ++#define grub_elfXX_load_phdrs grub_elf64_load_phdrs ++#define ElfXX_Phdr Elf64_Phdr ++#define grub_uintXX_t grub_uint64_t ++ ++#include "elfXX.c" +diff --git a/grub-core/kern/elfXX.c b/grub-core/kern/elfXX.c +new file mode 100644 +index 0000000..b35e235 +--- /dev/null ++++ b/grub-core/kern/elfXX.c +@@ -0,0 +1,144 @@ ++int ++grub_elf_is_elfXX (grub_elf_t elf) ++{ ++ return elf->ehdr.ehdrXX.e_ident[EI_CLASS] == ELFCLASSXX; ++} ++ ++grub_err_t ++grub_elfXX_load_phdrs (grub_elf_t elf) ++{ ++ grub_ssize_t phdrs_size; ++ ++ if (elf->phdrs) ++ return GRUB_ERR_NONE; ++ ++ phdrs_size = elf->ehdr.ehdrXX.e_phnum * elf->ehdr.ehdrXX.e_phentsize; ++ ++ grub_dprintf ("elf", "Loading program headers at 0x%llx, size 0x%lx.\n", ++ (unsigned long long) elf->ehdr.ehdrXX.e_phoff, ++ (unsigned long) phdrs_size); ++ ++ elf->phdrs = grub_malloc (phdrs_size); ++ if (! elf->phdrs) ++ return grub_errno; ++ ++ if ((grub_file_seek (elf->file, elf->ehdr.ehdrXX.e_phoff) == (grub_off_t) -1) ++ || (grub_file_read (elf->file, elf->phdrs, phdrs_size) != phdrs_size)) ++ { ++ if (!grub_errno) ++ grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"), ++ elf->filename); ++ return grub_errno; ++ } ++ ++ return GRUB_ERR_NONE; ++} ++ ++/* Calculate the amount of memory spanned by the segments. */ ++grub_size_t ++grub_elfXX_size (grub_elf_t elf, ++ ElfXX_Addr *base, grub_uintXX_t *max_align) ++{ ++ ElfXX_Addr segments_start = (ElfXX_Addr) -1; ++ ElfXX_Addr segments_end = 0; ++ int nr_phdrs = 0; ++ grub_uint32_t curr_align = 1; ++ ElfXX_Phdr *phdr; ++ ++ /* Run through the program headers to calculate the total memory size we ++ * should claim. */ ++ FOR_ELFXX_PHDRS (elf, phdr) ++ { ++ /* Only consider loadable segments. */ ++ if (phdr->p_type != PT_LOAD) ++ continue; ++ nr_phdrs++; ++ if (phdr->p_paddr < segments_start) ++ segments_start = phdr->p_paddr; ++ if (phdr->p_paddr + phdr->p_memsz > segments_end) ++ segments_end = phdr->p_paddr + phdr->p_memsz; ++ if (curr_align < phdr->p_align) ++ curr_align = phdr->p_align; ++ } ++ ++ if (base) ++ *base = 0; ++ ++ if (nr_phdrs == 0) ++ { ++ grub_error (GRUB_ERR_BAD_OS, "no program headers present"); ++ return 0; ++ } ++ ++ if (segments_end < segments_start) ++ { ++ /* Very bad addresses. */ ++ grub_error (GRUB_ERR_BAD_OS, "bad program header load addresses"); ++ return 0; ++ } ++ ++ if (base) ++ *base = segments_start; ++ if (max_align) ++ *max_align = curr_align; ++ return segments_end - segments_start; ++} ++ ++grub_err_t ++grub_elfXX_load (grub_elf_t elf, const char *filename, ++ void *load_offset, enum grub_elf_load_flags load_flags, ++ grub_addr_t *base, grub_size_t *size) ++{ ++ grub_addr_t load_base = (grub_addr_t) -1ULL; ++ grub_size_t load_size = 0; ++ ElfXX_Phdr *phdr; ++ ++ FOR_ELFXX_PHDRS(elf, phdr) ++ { ++ grub_addr_t load_addr; ++ ++ if (phdr->p_type != PT_LOAD && !((load_flags & GRUB_ELF_LOAD_FLAGS_LOAD_PT_DYNAMIC) && phdr->p_type == PT_DYNAMIC)) ++ continue; ++ ++ load_addr = (grub_addr_t) phdr->p_paddr; ++ if (load_flags & GRUB_ELF_LOAD_FLAGS_28BITS) ++ load_addr &= 0xFFFFFFF; ++ load_addr += (grub_addr_t) load_offset; ++ ++ if (load_addr < load_base) ++ load_base = load_addr; ++ ++ grub_dprintf ("elf", "Loading segment at 0x%llx, size 0x%llx\n", ++ (unsigned long long) load_addr, ++ (unsigned long long) phdr->p_memsz); ++ ++ if (grub_file_seek (elf->file, phdr->p_offset) == (grub_off_t) -1) ++ return grub_errno; ++ ++ if (phdr->p_filesz) ++ { ++ grub_ssize_t read; ++ read = grub_file_read (elf->file, (void *) load_addr, phdr->p_filesz); ++ if (read != (grub_ssize_t) phdr->p_filesz) ++ { ++ if (!grub_errno) ++ grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"), ++ filename); ++ return grub_errno; ++ } ++ } ++ ++ if (phdr->p_filesz < phdr->p_memsz) ++ grub_memset ((void *) (long) (load_addr + phdr->p_filesz), ++ 0, phdr->p_memsz - phdr->p_filesz); ++ ++ load_size += phdr->p_memsz; ++ } ++ ++ if (base) ++ *base = load_base; ++ if (size) ++ *size = load_size; ++ ++ return grub_errno; ++} +diff --git a/grub-core/loader/i386/bsd.c b/grub-core/loader/i386/bsd.c +index 9b86158..6199609 100644 +--- a/grub-core/loader/i386/bsd.c ++++ b/grub-core/loader/i386/bsd.c +@@ -1311,89 +1311,6 @@ grub_bsd_load_aout (grub_file_t file, const char *filename) + bss_size); + } + +-static int +-grub_bsd_elf32_size_hook (grub_elf_t elf __attribute__ ((unused)), +- Elf32_Phdr *phdr, void *arg __attribute__ ((unused))) +-{ +- Elf32_Addr paddr; +- +- if (phdr->p_type != PT_LOAD +- && phdr->p_type != PT_DYNAMIC) +- return 0; +- +- paddr = phdr->p_paddr & 0xFFFFFFF; +- +- if (paddr < kern_start) +- kern_start = paddr; +- +- if (paddr + phdr->p_memsz > kern_end) +- kern_end = paddr + phdr->p_memsz; +- +- return 0; +-} +- +-static grub_err_t +-grub_bsd_elf32_hook (Elf32_Phdr * phdr, grub_addr_t * addr, int *do_load) +-{ +- Elf32_Addr paddr; +- +- if (phdr->p_type != PT_LOAD +- && phdr->p_type != PT_DYNAMIC) +- { +- *do_load = 0; +- return 0; +- } +- +- *do_load = 1; +- phdr->p_paddr &= 0xFFFFFFF; +- paddr = phdr->p_paddr; +- +- *addr = (grub_addr_t) (paddr - kern_start + (grub_uint8_t *) kern_chunk_src); +- +- return GRUB_ERR_NONE; +-} +- +-static int +-grub_bsd_elf64_size_hook (grub_elf_t elf __attribute__ ((unused)), +- Elf64_Phdr *phdr, void *arg __attribute__ ((unused))) +-{ +- Elf64_Addr paddr; +- +- if (phdr->p_type != PT_LOAD +- && phdr->p_type != PT_DYNAMIC) +- return 0; +- +- paddr = phdr->p_paddr & 0xfffffff; +- +- if (paddr < kern_start) +- kern_start = paddr; +- +- if (paddr + phdr->p_memsz > kern_end) +- kern_end = paddr + phdr->p_memsz; +- +- return 0; +-} +- +-static grub_err_t +-grub_bsd_elf64_hook (Elf64_Phdr * phdr, grub_addr_t * addr, int *do_load) +-{ +- Elf64_Addr paddr; +- +- if (phdr->p_type != PT_LOAD +- && phdr->p_type != PT_DYNAMIC) +- { +- *do_load = 0; +- return 0; +- } +- +- *do_load = 1; +- paddr = phdr->p_paddr & 0xfffffff; +- +- *addr = (grub_addr_t) (paddr - kern_start + (grub_uint8_t *) kern_chunk_src); +- +- return GRUB_ERR_NONE; +-} +- + static grub_err_t + grub_bsd_load_elf (grub_elf_t elf, const char *filename) + { +@@ -1405,12 +1322,29 @@ grub_bsd_load_elf (grub_elf_t elf, const char *filename) + if (grub_elf_is_elf32 (elf)) + { + grub_relocator_chunk_t ch; ++ Elf32_Phdr *phdr; + + entry = elf->ehdr.ehdr32.e_entry & 0xFFFFFFF; +- err = grub_elf32_phdr_iterate (elf, filename, +- grub_bsd_elf32_size_hook, NULL); +- if (err) +- return err; ++ ++ FOR_ELF32_PHDRS (elf, phdr) ++ { ++ Elf32_Addr paddr; ++ ++ if (phdr->p_type != PT_LOAD ++ && phdr->p_type != PT_DYNAMIC) ++ continue; ++ ++ paddr = phdr->p_paddr & 0xFFFFFFF; ++ ++ if (paddr < kern_start) ++ kern_start = paddr; ++ ++ if (paddr + phdr->p_memsz > kern_end) ++ kern_end = paddr + phdr->p_memsz; ++ } ++ ++ if (grub_errno) ++ return grub_errno; + err = grub_relocator_alloc_chunk_addr (relocator, &ch, + kern_start, kern_end - kern_start); + if (err) +@@ -1418,7 +1352,7 @@ grub_bsd_load_elf (grub_elf_t elf, const char *filename) + + kern_chunk_src = get_virtual_current_address (ch); + +- err = grub_elf32_load (elf, filename, grub_bsd_elf32_hook, 0, 0); ++ err = grub_elf32_load (elf, filename, (grub_uint8_t *) kern_chunk_src - kern_start, GRUB_ELF_LOAD_FLAGS_LOAD_PT_DYNAMIC | GRUB_ELF_LOAD_FLAGS_28BITS, 0, 0); + if (err) + return err; + if (kernel_type != KERNEL_TYPE_OPENBSD) +@@ -1428,6 +1362,8 @@ grub_bsd_load_elf (grub_elf_t elf, const char *filename) + } + else if (grub_elf_is_elf64 (elf)) + { ++ Elf64_Phdr *phdr; ++ + is_64bit = 1; + + if (! grub_cpuid_has_longmode) +@@ -1445,10 +1381,25 @@ grub_bsd_load_elf (grub_elf_t elf, const char *filename) + entry_hi = 0; + } + +- err = grub_elf64_phdr_iterate (elf, filename, +- grub_bsd_elf64_size_hook, NULL); +- if (err) +- return err; ++ FOR_ELF64_PHDRS (elf, phdr) ++ { ++ Elf64_Addr paddr; ++ ++ if (phdr->p_type != PT_LOAD ++ && phdr->p_type != PT_DYNAMIC) ++ continue; ++ ++ paddr = phdr->p_paddr & 0xFFFFFFF; ++ ++ if (paddr < kern_start) ++ kern_start = paddr; ++ ++ if (paddr + phdr->p_memsz > kern_end) ++ kern_end = paddr + phdr->p_memsz; ++ } ++ ++ if (grub_errno) ++ return grub_errno; + + grub_dprintf ("bsd", "kern_start = %lx, kern_end = %lx\n", + (unsigned long) kern_start, (unsigned long) kern_end); +@@ -1463,7 +1414,7 @@ grub_bsd_load_elf (grub_elf_t elf, const char *filename) + } + + err = grub_elf64_load (elf, filename, +- grub_bsd_elf64_hook, 0, 0); ++ (grub_uint8_t *) kern_chunk_src - kern_start, GRUB_ELF_LOAD_FLAGS_LOAD_PT_DYNAMIC | GRUB_ELF_LOAD_FLAGS_28BITS, 0, 0); + if (err) + return err; + if (kernel_type != KERNEL_TYPE_OPENBSD) +diff --git a/grub-core/loader/i386/coreboot/chainloader.c b/grub-core/loader/i386/coreboot/chainloader.c +index df4e276..505aa0b 100644 +--- a/grub-core/loader/i386/coreboot/chainloader.c ++++ b/grub-core/loader/i386/coreboot/chainloader.c +@@ -56,36 +56,13 @@ grub_chain_unload (void) + } + + static grub_err_t +-grub_chain_elf32_hook (Elf32_Phdr * phdr, grub_addr_t * addr, int *do_load) +-{ +- grub_err_t err; +- grub_relocator_chunk_t ch; +- +- if (phdr->p_type != PT_LOAD) +- { +- *do_load = 0; +- return 0; +- } +- +- *do_load = 1; +- err = grub_relocator_alloc_chunk_addr (relocator, &ch, +- phdr->p_paddr, phdr->p_memsz); +- if (err) +- return err; +- +- *addr = (grub_addr_t) get_virtual_current_address (ch); +- +- return GRUB_ERR_NONE; +-} +- +- +-static grub_err_t + grub_cmd_chain (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) + { + grub_err_t err; + grub_file_t file; + grub_elf_t elf; ++ Elf32_Phdr *phdr; + + if (argc != 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); +@@ -118,13 +95,47 @@ grub_cmd_chain (grub_command_t cmd __attribute__ ((unused)), + grub_elf_close (elf); + } + +- entry = elf->ehdr.ehdr32.e_entry & 0xFFFFFF; +- +- err = grub_elf32_load (elf, argv[0], grub_chain_elf32_hook, 0, 0); ++ entry = elf->ehdr.ehdr32.e_entry; ++ ++ FOR_ELF32_PHDRS(elf, phdr) ++ { ++ grub_uint8_t *load_addr; ++ grub_relocator_chunk_t ch; ++ ++ if (phdr->p_type != PT_LOAD) ++ continue; ++ ++ err = grub_relocator_alloc_chunk_addr (relocator, &ch, ++ phdr->p_paddr, phdr->p_memsz); ++ if (err) ++ break; ++ ++ load_addr = get_virtual_current_address (ch); ++ ++ if (grub_file_seek (elf->file, phdr->p_offset) == (grub_off_t) -1) ++ return grub_errno; ++ ++ if (phdr->p_filesz) ++ { ++ grub_ssize_t read; ++ read = grub_file_read (elf->file, load_addr, phdr->p_filesz); ++ if (read != (grub_ssize_t) phdr->p_filesz) ++ { ++ if (!grub_errno) ++ grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"), ++ argv[0]); ++ break; ++ } ++ } ++ ++ if (phdr->p_filesz < phdr->p_memsz) ++ grub_memset ((load_addr + phdr->p_filesz), ++ 0, phdr->p_memsz - phdr->p_filesz); ++ } + + grub_elf_close (elf); +- if (err) +- return err; ++ if (grub_errno) ++ return grub_errno; + + grub_loader_set (grub_chain_boot, grub_chain_unload, 0); + return GRUB_ERR_NONE; +diff --git a/grub-core/loader/mips/linux.c b/grub-core/loader/mips/linux.c +index f2cf7cc..653f8a2 100644 +--- a/grub-core/loader/mips/linux.c ++++ b/grub-core/loader/mips/linux.c +@@ -144,7 +144,7 @@ grub_linux_load32 (grub_elf_t elf, const char *filename, + /* Linux's entry point incorrectly contains a virtual address. */ + entry_addr = elf->ehdr.ehdr32.e_entry; + +- linux_size = grub_elf32_size (elf, filename, &base, 0); ++ linux_size = grub_elf32_size (elf, &base, 0); + if (linux_size == 0) + return grub_errno; + target_addr = base; +@@ -171,22 +171,7 @@ grub_linux_load32 (grub_elf_t elf, const char *filename, + *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); +- 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 = (grub_addr_t) (phdr->p_paddr - base + playground); +- return 0; +- } +- return grub_elf32_load (elf, filename, offset_phdr, 0, 0); ++ return grub_elf32_load (elf, filename, playground - base, GRUB_ELF_LOAD_FLAGS_NONE, 0, 0); + } + + static grub_err_t +@@ -200,7 +185,7 @@ grub_linux_load64 (grub_elf_t elf, const char *filename, + /* Linux's entry point incorrectly contains a virtual address. */ + entry_addr = elf->ehdr.ehdr64.e_entry; + +- linux_size = grub_elf64_size (elf, filename, &base, 0); ++ linux_size = grub_elf64_size (elf, &base, 0); + if (linux_size == 0) + return grub_errno; + target_addr = base; +@@ -227,21 +212,7 @@ grub_linux_load64 (grub_elf_t elf, const char *filename, + *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); +- 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 = (grub_addr_t) (phdr->p_paddr - base + playground); +- return 0; +- } +- return grub_elf64_load (elf, filename, offset_phdr, 0, 0); ++ return grub_elf64_load (elf, filename, playground - base, GRUB_ELF_LOAD_FLAGS_NONE, 0, 0); + } + + static grub_err_t +diff --git a/grub-core/loader/powerpc/ieee1275/linux.c b/grub-core/loader/powerpc/ieee1275/linux.c +index c977941..9055399 100644 +--- a/grub-core/loader/powerpc/ieee1275/linux.c ++++ b/grub-core/loader/powerpc/ieee1275/linux.c +@@ -179,7 +179,7 @@ grub_linux_load32 (grub_elf_t elf, const char *filename) + grub_uint32_t offset; + Elf32_Addr entry; + +- linux_size = grub_elf32_size (elf, filename, &base_addr, &align); ++ linux_size = grub_elf32_size (elf, &base_addr, &align); + if (linux_size == 0) + return grub_errno; + /* Pad it; the kernel scribbles over memory beyond its load address. */ +@@ -203,20 +203,7 @@ grub_linux_load32 (grub_elf_t elf, const char *filename) + linux_addr = seg_addr; + + /* 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; +- +- *addr = (phdr->p_paddr - base_addr) + seg_addr; +- return 0; +- } +- return grub_elf32_load (elf, filename, offset_phdr, 0, 0); ++ return grub_elf32_load (elf, filename, (void *) (seg_addr - base_addr), GRUB_ELF_LOAD_FLAGS_NONE, 0, 0); + } + + static grub_err_t +@@ -228,7 +215,7 @@ grub_linux_load64 (grub_elf_t elf, const char *filename) + grub_uint64_t offset; + Elf64_Addr entry; + +- linux_size = grub_elf64_size (elf, filename, &base_addr, &align); ++ linux_size = grub_elf64_size (elf, &base_addr, &align); + if (linux_size == 0) + return grub_errno; + /* Pad it; the kernel scribbles over memory beyond its load address. */ +@@ -250,20 +237,7 @@ grub_linux_load64 (grub_elf_t elf, const char *filename) + linux_addr = seg_addr; + + /* 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; +- +- *addr = (phdr->p_paddr - base_addr) + seg_addr; +- return 0; +- } +- return grub_elf64_load (elf, filename, offset_phdr, 0, 0); ++ return grub_elf64_load (elf, filename, (void *) (grub_addr_t) (seg_addr - base_addr), GRUB_ELF_LOAD_FLAGS_NONE, 0, 0); + } + + static grub_err_t +diff --git a/grub-core/loader/sparc64/ieee1275/linux.c b/grub-core/loader/sparc64/ieee1275/linux.c +index c85fcfd..d203377 100644 +--- a/grub-core/loader/sparc64/ieee1275/linux.c ++++ b/grub-core/loader/sparc64/ieee1275/linux.c +@@ -261,7 +261,7 @@ grub_linux_load64 (grub_elf_t elf, const char *filename) + linux_entry = elf->ehdr.ehdr64.e_entry; + linux_addr = 0x40004000; + off = 0x4000; +- linux_size = grub_elf64_size (elf, filename, 0, 0); ++ linux_size = grub_elf64_size (elf, 0, 0); + if (linux_size == 0) + return grub_errno; + +@@ -286,21 +286,7 @@ grub_linux_load64 (grub_elf_t elf, const char *filename) + base = linux_entry - off; + + /* 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; +- +- /* Adjust the program load address to linux_addr. */ +- *addr = (phdr->p_paddr - base) + (linux_addr - off); +- return 0; +- } +- return grub_elf64_load (elf, filename, offset_phdr, 0, 0); ++ return grub_elf64_load (elf, filename, (void *) (linux_addr - off - base), GRUB_ELF_LOAD_FLAGS_NONE, 0, 0); + } + + static grub_err_t +diff --git a/include/grub/elfload.h b/include/grub/elfload.h +index d1a8d54..f854d0b 100644 +--- a/include/grub/elfload.h ++++ b/include/grub/elfload.h +@@ -33,14 +33,10 @@ struct grub_elf_file + Elf32_Ehdr ehdr32; + } ehdr; + void *phdrs; ++ char *filename; + }; + typedef struct grub_elf_file *grub_elf_t; + +-typedef grub_err_t (*grub_elf32_load_hook_t) +- (Elf32_Phdr *phdr, grub_addr_t *addr, int *load); +-typedef grub_err_t (*grub_elf64_load_hook_t) +- (Elf64_Phdr *phdr, grub_addr_t *addr, int *load); +- + typedef int (*grub_elf32_phdr_iterate_hook_t) + (grub_elf_t elf, Elf32_Phdr *phdr, void *arg); + typedef int (*grub_elf64_phdr_iterate_hook_t) +@@ -52,26 +48,31 @@ 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, +- const char *filename, + Elf32_Addr *, grub_uint32_t *); ++enum grub_elf_load_flags ++ { ++ GRUB_ELF_LOAD_FLAGS_NONE = 0, ++ GRUB_ELF_LOAD_FLAGS_LOAD_PT_DYNAMIC = 1, ++ GRUB_ELF_LOAD_FLAGS_28BITS = 2, ++ }; + grub_err_t grub_elf32_load (grub_elf_t, const char *filename, +- grub_elf32_load_hook_t, grub_addr_t *, ++ void *load_offset, enum grub_elf_load_flags flags, grub_addr_t *, + grub_size_t *); + + int grub_elf_is_elf64 (grub_elf_t); + grub_size_t grub_elf64_size (grub_elf_t, +- const char *filename, + Elf64_Addr *, grub_uint64_t *); + grub_err_t grub_elf64_load (grub_elf_t, const char *filename, +- grub_elf64_load_hook_t, grub_addr_t *, ++ void *load_offset, enum grub_elf_load_flags flags, grub_addr_t *, + grub_size_t *); +-grub_err_t +-grub_elf32_phdr_iterate (grub_elf_t elf, +- const char *filename, +- grub_elf32_phdr_iterate_hook_t hook, void *hook_arg); +-grub_err_t +-grub_elf64_phdr_iterate (grub_elf_t elf, +- const char *filename, +- grub_elf64_phdr_iterate_hook_t hook, void *hook_arg); ++grub_err_t grub_elf32_load_phdrs (grub_elf_t elf); ++grub_err_t grub_elf64_load_phdrs (grub_elf_t elf); ++ ++#define FOR_ELF32_PHDRS(elf, phdr) \ ++ for (grub_elf32_load_phdrs (elf), phdr = elf->phdrs; \ ++ phdr && phdr < (Elf32_Phdr *) elf->phdrs + elf->ehdr.ehdr32.e_phnum; phdr++) ++#define FOR_ELF64_PHDRS(elf, phdr) \ ++ for (grub_elf64_load_phdrs (elf), phdr = elf->phdrs; \ ++ phdr && phdr < (Elf64_Phdr *) elf->phdrs + elf->ehdr.ehdr64.e_phnum; phdr++) + + #endif /* ! GRUB_ELFLOAD_HEADER */ +-- +1.8.1.4 + diff --git a/0185-grub-core-kern-term.c-grub_term_normal_color.patch b/0185-grub-core-kern-term.c-grub_term_normal_color.patch new file mode 100644 index 0000000..2e97490 --- /dev/null +++ b/0185-grub-core-kern-term.c-grub_term_normal_color.patch @@ -0,0 +1,45 @@ +From 447bcdcd7ad914c3a18f6d91096fc78102e33b3e Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sat, 2 Mar 2013 23:23:51 +0100 +Subject: [PATCH 185/364] * grub-core/kern/term.c + (grub_term_normal_color), (grub_term_highlight_color): Add back lost + defaults. + +--- + ChangeLog | 5 +++++ + grub-core/kern/term.c | 4 ++-- + 2 files changed, 7 insertions(+), 2 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 7c80ed6..3231b4b 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,10 @@ + 2013-03-02 Vladimir Serbinenko + ++ * grub-core/kern/term.c (grub_term_normal_color), ++ (grub_term_highlight_color): Add back lost defaults. ++ ++2013-03-02 Vladimir Serbinenko ++ + Make elfload not use hooks. Opt for flags and iterators instead. + + 2013-03-02 Vladimir Serbinenko +diff --git a/grub-core/kern/term.c b/grub-core/kern/term.c +index 34096bc..44ada25 100644 +--- a/grub-core/kern/term.c ++++ b/grub-core/kern/term.c +@@ -29,8 +29,8 @@ struct grub_term_output *grub_term_outputs; + struct grub_term_input *grub_term_inputs; + + /* Current color state. */ +-grub_uint8_t grub_term_normal_color; +-grub_uint8_t grub_term_highlight_color; ++grub_uint8_t grub_term_normal_color = GRUB_TERM_DEFAULT_NORMAL_COLOR; ++grub_uint8_t grub_term_highlight_color = GRUB_TERM_DEFAULT_HIGHLIGHT_COLOR; + + void (*grub_term_poll_usb) (void) = NULL; + void (*grub_net_poll_cards_idle) (void) = NULL; +-- +1.8.1.4 + diff --git a/0186-Move-to-more-hookless-approach-in-IEEE1275-devices-h.patch b/0186-Move-to-more-hookless-approach-in-IEEE1275-devices-h.patch new file mode 100644 index 0000000..5cc390a --- /dev/null +++ b/0186-Move-to-more-hookless-approach-in-IEEE1275-devices-h.patch @@ -0,0 +1,995 @@ +From ae439540d2e2027ea4d9c5dcb18cdc9fc120c676 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sat, 2 Mar 2013 23:51:19 +0100 +Subject: [PATCH 186/364] Move to more hookless approach in IEEE1275 + devices handling. + +--- + ChangeLog | 4 + + grub-core/disk/ieee1275/nand.c | 31 ++-- + grub-core/disk/ieee1275/ofdisk.c | 172 +++++++++--------- + grub-core/kern/ieee1275/openfw.c | 308 ++++++++++++++++++--------------- + grub-core/net/drivers/ieee1275/ofnet.c | 23 +-- + grub-core/term/ieee1275/escc.c | 41 ++--- + grub-core/term/ieee1275/serial.c | 73 ++++---- + grub-core/video/ieee1275.c | 26 +-- + include/grub/ieee1275/ieee1275.h | 37 ++-- + 9 files changed, 376 insertions(+), 339 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 3231b4b..f107544 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,9 @@ + 2013-03-02 Vladimir Serbinenko + ++ Move to more hookless approach in IEEE1275 devices handling. ++ ++2013-03-02 Vladimir Serbinenko ++ + * grub-core/kern/term.c (grub_term_normal_color), + (grub_term_highlight_color): Add back lost defaults. + +diff --git a/grub-core/disk/ieee1275/nand.c b/grub-core/disk/ieee1275/nand.c +index b2844b1..30ea0f2 100644 +--- a/grub-core/disk/ieee1275/nand.c ++++ b/grub-core/disk/ieee1275/nand.c +@@ -36,22 +36,29 @@ static int + grub_nand_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data, + grub_disk_pull_t pull) + { +- auto int dev_iterate (struct grub_ieee1275_devalias *alias); +- int dev_iterate (struct grub_ieee1275_devalias *alias) +- { +- if (grub_strcmp (alias->name, "nand") == 0) +- { +- hook (alias->name, hook_data); +- return 1; +- } +- +- return 0; +- } ++ static int have_nand = -1; + + if (pull != GRUB_DISK_PULL_NONE) + return 0; + +- return grub_devalias_iterate (dev_iterate); ++ if (have_nand == -1) ++ { ++ struct grub_ieee1275_devalias alias; ++ ++ have_nand = 0; ++ FOR_IEEE1275_DEVALIASES(alias) ++ if (grub_strcmp (alias->name, "nand") == 0) ++ { ++ have_nand = 1; ++ break; ++ } ++ grub_ieee1275_devalias_free (&alias); ++ } ++ ++ if (have_nand) ++ return hook ("nand", hook_data); ++ ++ return 0; + } + + static grub_err_t +diff --git a/grub-core/disk/ieee1275/ofdisk.c b/grub-core/disk/ieee1275/ofdisk.c +index 2130cb1..1d4de90 100644 +--- a/grub-core/disk/ieee1275/ofdisk.c ++++ b/grub-core/disk/ieee1275/ofdisk.c +@@ -114,107 +114,113 @@ ofdisk_hash_add (char *devpath, char *curcan) + } + + static void +-scan (void) ++dev_iterate_real (const char *name, const char *path) + { +- auto int dev_iterate_real (const char *name, const char *path); +- +- int dev_iterate_real (const char *name, const char *path) +- { +- struct ofdisk_hash_ent *op; ++ struct ofdisk_hash_ent *op; + +- grub_dprintf ("disk", "disk name = %s, path = %s\n", name, +- path); ++ grub_dprintf ("disk", "disk name = %s, path = %s\n", name, ++ path); + +- op = ofdisk_hash_find (path); +- if (!op) ++ op = ofdisk_hash_find (path); ++ if (!op) ++ { ++ char *name_dup = grub_strdup (name); ++ char *can = grub_strdup (path); ++ if (!name_dup || !can) + { +- char *name_dup = grub_strdup (name); +- char *can = grub_strdup (path); +- if (!name_dup || !can) +- { +- grub_errno = GRUB_ERR_NONE; +- grub_free (name_dup); +- grub_free (can); +- return 0; +- } +- op = ofdisk_hash_add (name_dup, can); ++ grub_errno = GRUB_ERR_NONE; ++ grub_free (name_dup); ++ grub_free (can); ++ return; + } +- return 0; ++ op = ofdisk_hash_add (name_dup, can); + } ++ return; ++} + +- auto int dev_iterate_alias (struct grub_ieee1275_devalias *alias); +- int dev_iterate_alias (struct grub_ieee1275_devalias *alias) +- { +- if (grub_strcmp (alias->type, "block") != 0) +- return 0; +- return dev_iterate_real (alias->name, alias->path); +- } +- +- auto int dev_iterate (struct grub_ieee1275_devalias *alias); +- int dev_iterate (struct grub_ieee1275_devalias *alias) +- { +- if (grub_strcmp (alias->type, "vscsi") == 0) ++static void ++dev_iterate (const struct grub_ieee1275_devalias *alias) ++{ ++ if (grub_strcmp (alias->type, "vscsi") == 0) ++ { ++ static grub_ieee1275_ihandle_t ihandle; ++ struct set_color_args + { +- static grub_ieee1275_ihandle_t ihandle; +- struct set_color_args +- { +- struct grub_ieee1275_common_hdr common; +- grub_ieee1275_cell_t method; +- grub_ieee1275_cell_t ihandle; +- grub_ieee1275_cell_t catch_result; +- grub_ieee1275_cell_t nentries; +- grub_ieee1275_cell_t table; +- } +- args; +- char *buf, *bufptr; +- unsigned i; ++ struct grub_ieee1275_common_hdr common; ++ grub_ieee1275_cell_t method; ++ grub_ieee1275_cell_t ihandle; ++ grub_ieee1275_cell_t catch_result; ++ grub_ieee1275_cell_t nentries; ++ grub_ieee1275_cell_t table; ++ } ++ args; ++ char *buf, *bufptr; ++ unsigned i; + +- if (grub_ieee1275_open (alias->path, &ihandle)) +- return 0; ++ if (grub_ieee1275_open (alias->path, &ihandle)) ++ return; + +- INIT_IEEE1275_COMMON (&args.common, "call-method", 2, 3); +- args.method = (grub_ieee1275_cell_t) "vscsi-report-luns"; +- args.ihandle = ihandle; +- args.table = 0; +- args.nentries = 0; ++ INIT_IEEE1275_COMMON (&args.common, "call-method", 2, 3); ++ args.method = (grub_ieee1275_cell_t) "vscsi-report-luns"; ++ args.ihandle = ihandle; ++ args.table = 0; ++ args.nentries = 0; + +- if (IEEE1275_CALL_ENTRY_FN (&args) == -1 || args.catch_result) +- { +- grub_ieee1275_close (ihandle); +- return 0; +- } ++ if (IEEE1275_CALL_ENTRY_FN (&args) == -1 || args.catch_result) ++ { ++ grub_ieee1275_close (ihandle); ++ return; ++ } + +- buf = grub_malloc (grub_strlen (alias->path) + 32); +- if (!buf) +- return 0; +- bufptr = grub_stpcpy (buf, alias->path); ++ buf = grub_malloc (grub_strlen (alias->path) + 32); ++ if (!buf) ++ return; ++ bufptr = grub_stpcpy (buf, alias->path); + +- for (i = 0; i < args.nentries; i++) +- { +- grub_uint64_t *ptr; ++ for (i = 0; i < args.nentries; i++) ++ { ++ grub_uint64_t *ptr; + +- ptr = *(grub_uint64_t **) (args.table + 4 + 8 * i); +- while (*ptr) +- { +- grub_snprintf (bufptr, 32, "/disk@%" PRIxGRUB_UINT64_T, *ptr++); +- if (dev_iterate_real (buf, buf)) +- return 1; +- } +- } +- grub_ieee1275_close (ihandle); +- grub_free (buf); +- return 0; +- } ++ ptr = *(grub_uint64_t **) (args.table + 4 + 8 * i); ++ while (*ptr) ++ { ++ grub_snprintf (bufptr, 32, "/disk@%" PRIxGRUB_UINT64_T, *ptr++); ++ dev_iterate_real (buf, buf); ++ } ++ } ++ grub_ieee1275_close (ihandle); ++ grub_free (buf); ++ return; ++ } + +- if (!grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_TREE_SCANNING_FOR_DISKS) +- && grub_strcmp (alias->type, "block") == 0) +- return dev_iterate_real (alias->path, alias->path); ++ if (!grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_TREE_SCANNING_FOR_DISKS) ++ && grub_strcmp (alias->type, "block") == 0) ++ { ++ dev_iterate_real (alias->path, alias->path); ++ return; ++ } ++ ++ { ++ struct grub_ieee1275_devalias child; + +- return grub_children_iterate (alias->path, dev_iterate); ++ FOR_IEEE1275_DEVCHILDREN(alias->path, child) ++ dev_iterate (&child); + } ++} ++ ++static void ++scan (void) ++{ ++ struct grub_ieee1275_devalias alias; ++ FOR_IEEE1275_DEVALIASES(alias) ++ { ++ if (grub_strcmp (alias.type, "block") != 0) ++ continue; ++ dev_iterate_real (alias.name, alias.path); ++ } + +- grub_devalias_iterate (dev_iterate_alias); +- grub_children_iterate ("/", dev_iterate); ++ FOR_IEEE1275_DEVCHILDREN("/", alias) ++ dev_iterate (&alias); + } + + static int +diff --git a/grub-core/kern/ieee1275/openfw.c b/grub-core/kern/ieee1275/openfw.c +index 40abaa3..90c092c 100644 +--- a/grub-core/kern/ieee1275/openfw.c ++++ b/grub-core/kern/ieee1275/openfw.c +@@ -32,184 +32,227 @@ enum grub_ieee1275_parse_type + GRUB_PARSE_DEVICE_TYPE + }; + +-/* Walk children of 'devpath', calling hook for each. */ +-int +-grub_children_iterate (const char *devpath, +- int (*hook) (struct grub_ieee1275_devalias *alias)) ++static int ++fill_alias (struct grub_ieee1275_devalias *alias) + { +- grub_ieee1275_phandle_t dev; +- grub_ieee1275_phandle_t child; +- char *childtype, *childpath; +- char *childname; +- int ret = 0; ++ grub_ssize_t actual; + +- if (grub_ieee1275_finddevice (devpath, &dev)) ++ if (grub_ieee1275_get_property (alias->phandle, "device_type", alias->type, ++ IEEE1275_MAX_PROP_LEN, &actual)) ++ alias->type[0] = 0; ++ ++ if (alias->parent_dev == alias->phandle) + return 0; + +- if (grub_ieee1275_child (dev, &child)) ++ if (grub_ieee1275_package_to_path (alias->phandle, alias->path, ++ IEEE1275_MAX_PATH_LEN, &actual)) + return 0; + +- childtype = grub_malloc (IEEE1275_MAX_PROP_LEN); +- if (!childtype) ++ if (grub_strcmp (alias->parent_path, alias->path) == 0) + return 0; +- childpath = grub_malloc (IEEE1275_MAX_PATH_LEN); +- if (!childpath) ++ ++ if (grub_ieee1275_get_property (alias->phandle, "name", alias->name, ++ IEEE1275_MAX_PROP_LEN, &actual)) ++ return 0; ++ grub_dprintf ("devalias", "device path=%s\n", alias->path); ++ return 1; ++} ++ ++void ++grub_ieee1275_devalias_free (struct grub_ieee1275_devalias *alias) ++{ ++ grub_free (alias->name); ++ grub_free (alias->type); ++ grub_free (alias->path); ++ grub_free (alias->parent_path); ++ alias->name = 0; ++ alias->type = 0; ++ alias->path = 0; ++ alias->parent_path = 0; ++ alias->phandle = GRUB_IEEE1275_PHANDLE_INVALID; ++} ++ ++void ++grub_ieee1275_children_peer (struct grub_ieee1275_devalias *alias) ++{ ++ while (grub_ieee1275_peer (alias->phandle, &alias->phandle) != -1) ++ if (fill_alias (alias)) ++ return; ++ grub_ieee1275_devalias_free (alias); ++} ++ ++void ++grub_ieee1275_children_first (const char *devpath, ++ struct grub_ieee1275_devalias *alias) ++{ ++ grub_ieee1275_phandle_t dev; ++ ++ grub_dprintf ("devalias", "iterating children of %s\n", ++ devpath); ++ ++ alias->name = 0; ++ alias->path = 0; ++ alias->parent_path = 0; ++ alias->type = 0; ++ ++ if (grub_ieee1275_finddevice (devpath, &dev)) ++ return; ++ ++ if (grub_ieee1275_child (dev, &alias->phandle)) ++ return; ++ ++ alias->type = grub_malloc (IEEE1275_MAX_PROP_LEN); ++ if (!alias->type) ++ return; ++ alias->path = grub_malloc (IEEE1275_MAX_PATH_LEN); ++ if (!alias->path) + { +- grub_free (childtype); +- return 0; ++ grub_free (alias->type); ++ return; + } +- childname = grub_malloc (IEEE1275_MAX_PROP_LEN); +- if (!childname) ++ alias->parent_path = grub_strdup (devpath); ++ if (!alias->parent_path) + { +- grub_free (childpath); +- grub_free (childtype); +- return 0; ++ grub_free (alias->path); ++ grub_free (alias->type); ++ return; + } + +- do ++ alias->name = grub_malloc (IEEE1275_MAX_PROP_LEN); ++ if (!alias->name) + { +- struct grub_ieee1275_devalias alias; +- grub_ssize_t actual; +- +- if (grub_ieee1275_get_property (child, "device_type", childtype, +- 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; ++ grub_free (alias->path); ++ grub_free (alias->type); ++ grub_free (alias->parent_path); ++ return; ++ } ++ if (!fill_alias (alias)) ++ grub_ieee1275_children_peer (alias); ++} + +- if (grub_ieee1275_get_property (child, "name", childname, +- IEEE1275_MAX_PROP_LEN, &actual)) +- continue; ++static int ++iterate_recursively (const char *path, ++ int (*hook) (struct grub_ieee1275_devalias *alias)) ++{ ++ struct grub_ieee1275_devalias alias; ++ int ret = 0; + +- alias.type = childtype; +- alias.path = childpath; +- alias.name = childname; ++ FOR_IEEE1275_DEVCHILDREN(path, alias) ++ { + ret = hook (&alias); + if (ret) + break; ++ ret = iterate_recursively (alias.path, hook); ++ if (ret) ++ break; + } +- while (grub_ieee1275_peer (child, &child) != -1); +- +- grub_free (childname); +- grub_free (childpath); +- grub_free (childtype); +- ++ grub_ieee1275_devalias_free (&alias); + 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->path, it_through); +- } +- +- return grub_children_iterate ("/", it_through); ++ return iterate_recursively ("/", hook); + } + +-/* Iterate through all device aliases. This function can be used to +- find a device of a specific type. */ +-int +-grub_devalias_iterate (int (*hook) (struct grub_ieee1275_devalias *alias)) ++void ++grub_ieee1275_devalias_init_iterator (struct grub_ieee1275_devalias *alias) + { +- grub_ieee1275_phandle_t aliases; +- char *aliasname, *devtype; +- grub_ssize_t actual; +- struct grub_ieee1275_devalias alias; +- int ret = 0; ++ alias->name = 0; ++ alias->path = 0; ++ alias->parent_path = 0; ++ alias->type = 0; + +- if (grub_ieee1275_finddevice ("/aliases", &aliases)) +- return 0; ++ grub_dprintf ("devalias", "iterating aliases\n"); + +- aliasname = grub_malloc (IEEE1275_MAX_PROP_LEN); +- if (!aliasname) +- return 0; +- devtype = grub_malloc (IEEE1275_MAX_PROP_LEN); +- if (!devtype) ++ if (grub_ieee1275_finddevice ("/aliases", &alias->parent_dev)) ++ return; ++ ++ alias->name = grub_malloc (IEEE1275_MAX_PROP_LEN); ++ if (!alias->name) ++ return; ++ ++ alias->type = grub_malloc (IEEE1275_MAX_PROP_LEN); ++ if (!alias->type) + { +- grub_free (aliasname); +- return 0; ++ grub_free (alias->name); ++ alias->name = 0; ++ return; + } + +- /* Find the first property. */ +- aliasname[0] = '\0'; ++ alias->name[0] = '\0'; ++} + +- while (grub_ieee1275_next_property (aliases, aliasname, aliasname) > 0) ++int ++grub_ieee1275_devalias_next (struct grub_ieee1275_devalias *alias) ++{ ++ if (!alias->name) ++ return 0; ++ while (1) + { +- grub_ieee1275_phandle_t dev; + grub_ssize_t pathlen; +- char *devpath; ++ grub_ssize_t actual; ++ ++ if (alias->path) ++ { ++ grub_free (alias->path); ++ alias->path = 0; ++ } ++ if (grub_ieee1275_next_property (alias->parent_dev, alias->name, ++ alias->name) <= 0) ++ { ++ grub_ieee1275_devalias_free (alias); ++ return 0; ++ } + +- grub_dprintf ("devalias", "devalias name = %s\n", aliasname); ++ grub_dprintf ("devalias", "devalias name = %s\n", alias->name); + +- grub_ieee1275_get_property_length (aliases, aliasname, &pathlen); ++ grub_ieee1275_get_property_length (alias->parent_dev, alias->name, &pathlen); + + /* The property `name' is a special case we should skip. */ +- if (!grub_strcmp (aliasname, "name")) ++ if (grub_strcmp (alias->name, "name") == 0) + continue; + + /* Sun's OpenBoot often doesn't zero terminate the device alias + strings, so we will add a NULL byte at the end explicitly. */ + pathlen += 1; + +- devpath = grub_malloc (pathlen + 1); +- if (! devpath) ++ alias->path = grub_malloc (pathlen + 1); ++ if (! alias->path) + { +- grub_free (devtype); +- grub_free (aliasname); ++ grub_ieee1275_devalias_free (alias); + return 0; + } + +- if (grub_ieee1275_get_property (aliases, aliasname, devpath, pathlen, +- &actual) || actual < 0) ++ if (grub_ieee1275_get_property (alias->parent_dev, alias->name, alias->path, ++ pathlen, &actual) || actual < 0) + { +- grub_dprintf ("devalias", "get_property (%s) failed\n", aliasname); +- goto nextprop; ++ grub_dprintf ("devalias", "get_property (%s) failed\n", alias->name); ++ grub_free (alias->path); ++ continue; + } + if (actual > pathlen) + actual = pathlen; +- devpath[actual] = '\0'; +- devpath[pathlen] = '\0'; ++ alias->path[actual] = '\0'; ++ alias->path[pathlen] = '\0'; + +- if (grub_ieee1275_finddevice (devpath, &dev)) ++ if (grub_ieee1275_finddevice (alias->path, &alias->phandle)) + { +- grub_dprintf ("devalias", "finddevice (%s) failed\n", devpath); +- goto nextprop; ++ grub_dprintf ("devalias", "finddevice (%s) failed\n", alias->path); ++ grub_free (alias->path); ++ alias->path = 0; ++ continue; + } + +- if (grub_ieee1275_get_property (dev, "device_type", devtype, ++ if (grub_ieee1275_get_property (alias->phandle, "device_type", alias->type, + IEEE1275_MAX_PROP_LEN, &actual)) + { + /* NAND device don't have device_type property. */ +- devtype[0] = 0; ++ alias->type[0] = 0; + } +- +- alias.name = aliasname; +- alias.path = devpath; +- alias.type = devtype; +- ret = hook (&alias); +- +-nextprop: +- grub_free (devpath); +- if (ret) +- break; ++ return 1; + } +- +- grub_free (devtype); +- grub_free (aliasname); +- return ret; + } + + /* Call the "map" method of /chosen/mmu. */ +@@ -286,37 +329,28 @@ grub_ieee1275_get_devargs (const char *path) + } + + /* Get the device path of the Open Firmware node name `path'. */ +-static char * ++char * + grub_ieee1275_get_devname (const char *path) + { + char *colon = grub_strchr (path, ':'); +- char *newpath = 0; + int pathlen = grub_strlen (path); +- auto int match_alias (struct grub_ieee1275_devalias *alias); +- +- int match_alias (struct grub_ieee1275_devalias *curalias) +- { +- /* briQ firmware can change capitalization in /chosen/bootpath. */ +- if (grub_strncasecmp (curalias->path, path, pathlen) == 0 +- && curalias->path[pathlen] == 0) +- { +- newpath = grub_strdup (curalias->name); +- return 1; +- } +- +- return 0; +- } +- ++ struct grub_ieee1275_devalias curalias; + if (colon) + pathlen = (int)(colon - path); + + /* Try to find an alias for this device. */ +- grub_devalias_iterate (match_alias); +- +- if (! newpath) +- newpath = grub_strndup (path, pathlen); ++ FOR_IEEE1275_DEVALIASES (curalias) ++ /* briQ firmware can change capitalization in /chosen/bootpath. */ ++ if (grub_strncasecmp (curalias.path, path, pathlen) == 0 ++ && curalias.path[pathlen] == 0) ++ { ++ char *newpath; ++ newpath = grub_strdup (curalias.name); ++ grub_ieee1275_devalias_free (&curalias); ++ return newpath; ++ } + +- return newpath; ++ return grub_strndup (path, pathlen); + } + + static char * +diff --git a/grub-core/net/drivers/ieee1275/ofnet.c b/grub-core/net/drivers/ieee1275/ofnet.c +index 7e8e2a7..1acfb73 100644 +--- a/grub-core/net/drivers/ieee1275/ofnet.c ++++ b/grub-core/net/drivers/ieee1275/ofnet.c +@@ -198,27 +198,6 @@ grub_ieee1275_net_config_real (const char *devpath, char **device, char **path) + } + } + +-static char * +-find_alias (const char *fullname) +-{ +- char *ret = NULL; +- auto int find_alias_hook (struct grub_ieee1275_devalias *alias); +- +- int find_alias_hook (struct grub_ieee1275_devalias *alias) +- { +- if (grub_strcmp (alias->path, fullname) == 0) +- { +- ret = grub_strdup (alias->name); +- return 1; +- } +- return 0; +- } +- +- grub_devalias_iterate (find_alias_hook); +- grub_errno = GRUB_ERR_NONE; +- return ret; +-} +- + static int + search_net_devices (struct grub_ieee1275_devalias *alias) + { +@@ -308,7 +287,7 @@ search_net_devices (struct grub_ieee1275_devalias *alias) + card->driver = NULL; + card->data = ofdata; + card->flags = 0; +- shortname = find_alias (alias->path); ++ shortname = grub_ieee1275_get_devname (alias->path); + card->name = grub_xasprintf ("ofnet_%s", shortname ? : alias->path); + card->idle_poll_delay_ms = 10; + grub_free (shortname); +diff --git a/grub-core/term/ieee1275/escc.c b/grub-core/term/ieee1275/escc.c +index 6d7b636..40de3f7 100644 +--- a/grub-core/term/ieee1275/escc.c ++++ b/grub-core/term/ieee1275/escc.c +@@ -200,6 +200,7 @@ struct grub_serial_driver grub_escc_driver = + }; + + static struct grub_escc_descriptor escc_descs[2]; ++static char *macio = 0; + + static void + add_device (grub_addr_t addr, int channel) +@@ -243,38 +244,34 @@ add_device (grub_addr_t addr, int channel) + grub_serial_register (port); + } + ++static int ++find_macio (struct grub_ieee1275_devalias *alias) ++{ ++ if (grub_strcmp (alias->type, "mac-io") != 0) ++ return 0; ++ macio = grub_strdup (alias->path); ++ return 1; ++} ++ + GRUB_MOD_INIT (escc) + { +- char *macio = 0; +- char *escc = 0; + grub_uint32_t macio_addr[4]; + grub_uint32_t escc_addr[2]; + grub_ieee1275_phandle_t dev; +- +- auto int find_macio (struct grub_ieee1275_devalias *alias); +- auto int find_escc (struct grub_ieee1275_devalias *alias); +- +- int find_macio (struct grub_ieee1275_devalias *alias) +- { +- if (grub_strcmp (alias->type, "mac-io") != 0) +- return 0; +- macio = grub_strdup (alias->path); +- return 1; +- } +- +- int find_escc (struct grub_ieee1275_devalias *alias) +- { +- if (grub_strcmp (alias->type, "escc") != 0) +- return 0; +- escc = grub_strdup (alias->path); +- return 1; +- } ++ struct grub_ieee1275_devalias alias; ++ char *escc = 0; + + grub_ieee1275_devices_iterate (find_macio); + if (!macio) + return; + +- grub_children_iterate (macio, find_escc); ++ FOR_IEEE1275_DEVCHILDREN(macio, alias) ++ if (grub_strcmp (alias.type, "escc") == 0) ++ { ++ escc = grub_strdup (alias.path); ++ break; ++ } ++ grub_ieee1275_devalias_free (&alias); + if (!escc) + { + grub_free (macio); +diff --git a/grub-core/term/ieee1275/serial.c b/grub-core/term/ieee1275/serial.c +index 09a5a03..cda97d0 100644 +--- a/grub-core/term/ieee1275/serial.c ++++ b/grub-core/term/ieee1275/serial.c +@@ -180,58 +180,53 @@ ofserial_hash_add (char *devpath, char *curcan) + return p; + } + +-void +-grub_ofserial_init (void) ++static void ++dev_iterate_real (struct grub_ieee1275_devalias *alias, ++ int use_name) + { +- auto int dev_iterate_real (struct grub_ieee1275_devalias *alias, +- int use_name); +- +- int dev_iterate_real (struct grub_ieee1275_devalias *alias, +- int use_name) +- { +- struct ofserial_hash_ent *op; ++ struct ofserial_hash_ent *op; + +- if (grub_strcmp (alias->type, "serial") != 0) +- return 0; ++ if (grub_strcmp (alias->type, "serial") != 0) ++ return; + +- grub_dprintf ("serial", "serial name = %s, path = %s\n", alias->name, +- alias->path); ++ grub_dprintf ("serial", "serial name = %s, path = %s\n", alias->name, ++ alias->path); + +- op = ofserial_hash_find (alias->path); +- if (!op) ++ op = ofserial_hash_find (alias->path); ++ if (!op) ++ { ++ char *name = grub_strdup (use_name ? alias->name : alias->path); ++ char *can = grub_strdup (alias->path); ++ if (!name || !can) + { +- char *name = grub_strdup (use_name ? alias->name : alias->path); +- char *can = grub_strdup (alias->path); +- if (!name || !can) +- { +- grub_errno = GRUB_ERR_NONE; +- grub_free (name); +- grub_free (can); +- return 0; +- } +- op = ofserial_hash_add (name, can); ++ grub_errno = GRUB_ERR_NONE; ++ grub_free (name); ++ grub_free (can); ++ return; + } +- return 0; ++ op = ofserial_hash_add (name, can); + } ++ return; ++} + +- auto int dev_iterate_alias (struct grub_ieee1275_devalias *alias); +- int dev_iterate_alias (struct grub_ieee1275_devalias *alias) +- { +- return dev_iterate_real (alias, 1); +- } +- +- auto int dev_iterate (struct grub_ieee1275_devalias *alias); +- int dev_iterate (struct grub_ieee1275_devalias *alias) +- { +- return dev_iterate_real (alias, 0); +- } ++static int ++dev_iterate (struct grub_ieee1275_devalias *alias) ++{ ++ dev_iterate_real (alias, 0); ++ return 0; ++} + ++void ++grub_ofserial_init (void) ++{ + unsigned i; + grub_err_t err; ++ struct grub_ieee1275_devalias alias; + +- grub_devalias_iterate (dev_iterate_alias); +- grub_ieee1275_devices_iterate (dev_iterate); ++ FOR_IEEE1275_DEVALIASES(alias) ++ dev_iterate_real (&alias, 1); + ++ grub_ieee1275_devices_iterate (dev_iterate); + + for (i = 0; i < ARRAY_SIZE (ofserial_hash); i++) + { +diff --git a/grub-core/video/ieee1275.c b/grub-core/video/ieee1275.c +index 84f9b89..93feeb5 100644 +--- a/grub-core/video/ieee1275.c ++++ b/grub-core/video/ieee1275.c +@@ -54,22 +54,22 @@ set_video_mode (unsigned width __attribute__ ((unused)), + /* TODO */ + } + ++static int ++find_display_hook (struct grub_ieee1275_devalias *alias) ++{ ++ if (grub_strcmp (alias->type, "display") == 0) ++ { ++ grub_dprintf ("video", "Found display %s\n", alias->path); ++ display = grub_strdup (alias->path); ++ return 1; ++ } ++ return 0; ++} ++ + 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->path); +- display = grub_strdup (alias->path); +- return 1; +- } +- return 0; +- } +- +- grub_ieee1275_devices_iterate (hook); ++ grub_ieee1275_devices_iterate (find_display_hook); + } + + static grub_err_t +diff --git a/include/grub/ieee1275/ieee1275.h b/include/grub/ieee1275/ieee1275.h +index ee9b707..1e8ba6f 100644 +--- a/include/grub/ieee1275/ieee1275.h ++++ b/include/grub/ieee1275/ieee1275.h +@@ -24,13 +24,6 @@ + #include + #include + +-struct grub_ieee1275_devalias +-{ +- char *name; +- char *path; +- char *type; +-}; +- + struct grub_ieee1275_mem_region + { + unsigned int start; +@@ -64,6 +57,18 @@ struct grub_ieee1275_common_hdr + typedef grub_uint32_t grub_ieee1275_ihandle_t; + typedef grub_uint32_t grub_ieee1275_phandle_t; + ++#define GRUB_IEEE1275_PHANDLE_INVALID ((grub_ieee1275_phandle_t) -1) ++ ++struct grub_ieee1275_devalias ++{ ++ char *name; ++ char *path; ++ char *type; ++ char *parent_path; ++ grub_ieee1275_phandle_t phandle; ++ grub_ieee1275_phandle_t parent_dev; ++}; ++ + extern void (*EXPORT_VAR(grub_ieee1275_net_config)) (const char *dev, + char **device, + char **path); +@@ -192,10 +197,6 @@ int EXPORT_FUNC(grub_ieee1275_set_color) (grub_ieee1275_ihandle_t ihandle, + int EXPORT_FUNC(grub_ieee1275_milliseconds) (grub_uint32_t *msecs); + + +-int EXPORT_FUNC(grub_devalias_iterate) +- (int (*hook) (struct grub_ieee1275_devalias *alias)); +-int EXPORT_FUNC(grub_children_iterate) (const char *devpath, +- int (*hook) (struct grub_ieee1275_devalias *alias)); + grub_err_t EXPORT_FUNC(grub_claimmap) (grub_addr_t addr, grub_size_t size); + + int +@@ -210,5 +211,19 @@ int EXPORT_FUNC(grub_ieee1275_devices_iterate) (int (*hook) + char *EXPORT_FUNC(grub_ieee1275_get_aliasdevname) (const char *path); + char *EXPORT_FUNC(grub_ieee1275_canonicalise_devname) (const char *path); + char *EXPORT_FUNC(grub_ieee1275_get_device_type) (const char *path); ++char *EXPORT_FUNC(grub_ieee1275_get_devname) (const char *path); ++ ++void EXPORT_FUNC(grub_ieee1275_devalias_init_iterator) (struct grub_ieee1275_devalias *alias); ++void EXPORT_FUNC(grub_ieee1275_devalias_free) (struct grub_ieee1275_devalias *alias); ++int EXPORT_FUNC(grub_ieee1275_devalias_next) (struct grub_ieee1275_devalias *alias); ++void EXPORT_FUNC(grub_ieee1275_children_peer) (struct grub_ieee1275_devalias *alias); ++void EXPORT_FUNC(grub_ieee1275_children_first) (const char *devpath, ++ struct grub_ieee1275_devalias *alias); ++ ++#define FOR_IEEE1275_DEVALIASES(alias) for (grub_ieee1275_devalias_init_iterator (&(alias)); grub_ieee1275_devalias_next (&(alias));) ++ ++#define FOR_IEEE1275_DEVCHILDREN(devpath, alias) for (grub_ieee1275_children_first ((devpath), &(alias)); \ ++ (alias).name; \ ++ grub_ieee1275_children_peer (&(alias))) + + #endif /* ! GRUB_IEEE1275_HEADER */ +-- +1.8.1.4 + diff --git a/0187-include-grub-mips-loongson-cmos.h-Fix-high-CMOS-addr.patch b/0187-include-grub-mips-loongson-cmos.h-Fix-high-CMOS-addr.patch new file mode 100644 index 0000000..4fa7826 --- /dev/null +++ b/0187-include-grub-mips-loongson-cmos.h-Fix-high-CMOS-addr.patch @@ -0,0 +1,42 @@ +From 19efc9d2e2ee9483f6067b32d39415ece22d4e40 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sat, 2 Mar 2013 23:57:34 +0100 +Subject: [PATCH 187/364] * include/grub/mips/loongson/cmos.h: Fix high + CMOS addresses. + +--- + ChangeLog | 4 ++++ + include/grub/mips/loongson/cmos.h | 4 ++-- + 2 files changed, 6 insertions(+), 2 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index f107544..93a8a93 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,9 @@ + 2013-03-02 Vladimir Serbinenko + ++ * include/grub/mips/loongson/cmos.h: Fix high CMOS addresses. ++ ++2013-03-02 Vladimir Serbinenko ++ + Move to more hookless approach in IEEE1275 devices handling. + + 2013-03-02 Vladimir Serbinenko +diff --git a/include/grub/mips/loongson/cmos.h b/include/grub/mips/loongson/cmos.h +index 96d50f2..0c8cc8d 100644 +--- a/include/grub/mips/loongson/cmos.h ++++ b/include/grub/mips/loongson/cmos.h +@@ -24,7 +24,7 @@ + + #define GRUB_CMOS_ADDR_REG 0xbfd00070 + #define GRUB_CMOS_DATA_REG 0xbfd00071 +-#define GRUB_CMOS_ADDR_REG 0xbfd00072 +-#define GRUB_CMOS_DATA_REG 0xbfd00073 ++#define GRUB_CMOS_ADDR_REG_HI 0xbfd00072 ++#define GRUB_CMOS_DATA_REG_HI 0xbfd00073 + + #endif /* GRUB_CPU_CMOS_H */ +-- +1.8.1.4 + diff --git a/0188-include-grub-cmos.h-Handle-high-CMOS-addresses-on-sp.patch b/0188-include-grub-cmos.h-Handle-high-CMOS-addresses-on-sp.patch new file mode 100644 index 0000000..e8fdebc --- /dev/null +++ b/0188-include-grub-cmos.h-Handle-high-CMOS-addresses-on-sp.patch @@ -0,0 +1,54 @@ +From b2f7a41fb3505137cd02a22913787ec45512aaad Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sat, 2 Mar 2013 23:59:05 +0100 +Subject: [PATCH 188/364] * include/grub/cmos.h: Handle high CMOS + addresses on sparc64. + +--- + ChangeLog | 4 ++++ + include/grub/cmos.h | 8 ++++---- + 2 files changed, 8 insertions(+), 4 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 93a8a93..ea87229 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,9 @@ + 2013-03-02 Vladimir Serbinenko + ++ * include/grub/cmos.h: Handle high CMOS addresses on sparc64. ++ ++2013-03-02 Vladimir Serbinenko ++ + * include/grub/mips/loongson/cmos.h: Fix high CMOS addresses. + + 2013-03-02 Vladimir Serbinenko +diff --git a/include/grub/cmos.h b/include/grub/cmos.h +index aa2b233..56ccc71 100644 +--- a/include/grub/cmos.h ++++ b/include/grub/cmos.h +@@ -103,8 +103,8 @@ grub_cmos_read (grub_uint8_t index, grub_uint8_t *val) + if (err) + return err; + } +- grub_cmos_port[0] = index; +- *val = grub_cmos_port[1]; ++ grub_cmos_port[((index & 0x80) >> 6) | 0] = index & 0x7f; ++ *val = grub_cmos_port[((index & 0x80) >> 6) | 1]; + return GRUB_ERR_NONE; + } + +@@ -118,8 +118,8 @@ grub_cmos_write (grub_uint8_t index, grub_uint8_t val) + if (err) + return err; + } +- grub_cmos_port[0] = index; +- grub_cmos_port[1] = val; ++ grub_cmos_port[((index & 0x80) >> 6) | 0] = index; ++ grub_cmos_port[((index & 0x80) >> 6) | 1] = val; + return GRUB_ERR_NONE; + } + +-- +1.8.1.4 + diff --git a/0189-grub-core-disk-ieee1275-nand.c-Fix-compilation-on.patch b/0189-grub-core-disk-ieee1275-nand.c-Fix-compilation-on.patch new file mode 100644 index 0000000..2fe35fc --- /dev/null +++ b/0189-grub-core-disk-ieee1275-nand.c-Fix-compilation-on.patch @@ -0,0 +1,40 @@ +From 78ba098e4146119aab14f66f13ad4d8e20962342 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sun, 3 Mar 2013 01:30:55 +0100 +Subject: [PATCH 189/364] * grub-core/disk/ieee1275/nand.c: Fix + compilation on i386-ieee1275. + +--- + ChangeLog | 5 +++++ + grub-core/disk/ieee1275/nand.c | 2 +- + 2 files changed, 6 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index ea87229..f117127 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,8 @@ ++2013-03-03 Vladimir Serbinenko ++ ++ * grub-core/disk/ieee1275/nand.c: Fix compilation on ++ i386-ieee1275. ++ + 2013-03-02 Vladimir Serbinenko + + * include/grub/cmos.h: Handle high CMOS addresses on sparc64. +diff --git a/grub-core/disk/ieee1275/nand.c b/grub-core/disk/ieee1275/nand.c +index 30ea0f2..576e9cc 100644 +--- a/grub-core/disk/ieee1275/nand.c ++++ b/grub-core/disk/ieee1275/nand.c +@@ -47,7 +47,7 @@ grub_nand_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data, + + have_nand = 0; + FOR_IEEE1275_DEVALIASES(alias) +- if (grub_strcmp (alias->name, "nand") == 0) ++ if (grub_strcmp (alias.name, "nand") == 0) + { + have_nand = 1; + break; +-- +1.8.1.4 + diff --git a/0190-grub-core-kern-env.c-include-grub-env.h-Change-itera.patch b/0190-grub-core-kern-env.c-include-grub-env.h-Change-itera.patch new file mode 100644 index 0000000..3b24593 --- /dev/null +++ b/0190-grub-core-kern-env.c-include-grub-env.h-Change-itera.patch @@ -0,0 +1,419 @@ +From fae25d35c12764fae63a85df467470d6a1120bd5 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sun, 3 Mar 2013 01:34:27 +0100 +Subject: [PATCH 190/364] * grub-core/kern/env.c, include/grub/env.h: + Change iterator through all vars to a macro. All users updated. + +--- + ChangeLog | 5 ++++ + grub-core/efiemu/pnvram.c | 64 ++++++++++++++++++++------------------------- + grub-core/kern/corecmd.c | 12 +++------ + grub-core/kern/env.c | 39 +++++++-------------------- + grub-core/loader/i386/bsd.c | 46 ++++++++++++-------------------- + grub-core/loader/xnu.c | 16 +++++------- + include/grub/env.h | 6 ++++- + 7 files changed, 74 insertions(+), 114 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index f117127..5f9cde5 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,10 @@ + 2013-03-03 Vladimir Serbinenko + ++ * grub-core/kern/env.c, include/grub/env.h: Change iterator through ++ all vars to a macro. All users updated. ++ ++2013-03-03 Vladimir Serbinenko ++ + * grub-core/disk/ieee1275/nand.c: Fix compilation on + i386-ieee1275. + +diff --git a/grub-core/efiemu/pnvram.c b/grub-core/efiemu/pnvram.c +index 28d0050..c5c3d4b 100644 +--- a/grub-core/efiemu/pnvram.c ++++ b/grub-core/efiemu/pnvram.c +@@ -102,9 +102,23 @@ nvram_set (void * data __attribute__ ((unused))) + grub_uint32_t *accuracy + = grub_efiemu_mm_obtain_request (accuracy_handle); + char *nvramptr; ++ struct grub_env_var *var; + +- auto int iterate_env (struct grub_env_var *var); +- int iterate_env (struct grub_env_var *var) ++ /* Copy to definitive loaction */ ++ grub_dprintf ("efiemu", "preparing pnvram\n"); ++ ++ env = grub_env_get ("EfiEmu.pnvram.high_monotonic_count"); ++ *high_monotonic_count = env ? grub_strtoul (env, 0, 0) : 1; ++ env = grub_env_get ("EfiEmu.pnvram.timezone"); ++ *timezone = env ? grub_strtosl (env, 0, 0) : GRUB_EFI_UNSPECIFIED_TIMEZONE; ++ env = grub_env_get ("EfiEmu.pnvram.accuracy"); ++ *accuracy = env ? grub_strtoul (env, 0, 0) : 50000000; ++ env = grub_env_get ("EfiEmu.pnvram.daylight"); ++ *daylight = env ? grub_strtoul (env, 0, 0) : 0; ++ ++ nvramptr = nvram; ++ grub_memset (nvram, 0, nvramsize); ++ FOR_SORTED_ENV (var) + { + char *guid, *attr, *name, *varname; + struct efi_variable *efivar; +@@ -114,44 +128,41 @@ nvram_set (void * data __attribute__ ((unused))) + + if (grub_memcmp (var->name, "EfiEmu.pnvram.", + sizeof ("EfiEmu.pnvram.") - 1) != 0) +- return 0; ++ continue; + + guid = var->name + sizeof ("EfiEmu.pnvram.") - 1; + + attr = grub_strchr (guid, '.'); + if (!attr) +- return 0; ++ continue; + attr++; + + name = grub_strchr (attr, '.'); + if (!name) +- return 0; ++ continue; + name++; + + efivar = (struct efi_variable *) nvramptr; + if (nvramptr - nvram + sizeof (struct efi_variable) > nvramsize) +- { +- grub_error (GRUB_ERR_OUT_OF_MEMORY, +- "too many NVRAM variables for reserved variable space." +- " Try increasing EfiEmu.pnvram.size"); +- return 1; +- } ++ return grub_error (GRUB_ERR_OUT_OF_MEMORY, ++ "too many NVRAM variables for reserved variable space." ++ " Try increasing EfiEmu.pnvram.size"); + + nvramptr += sizeof (struct efi_variable); + + efivar->guid.data1 = grub_cpu_to_le32 (grub_strtoul (guid, &guid, 16)); + if (*guid != '-') +- return 0; ++ continue; + guid++; + + efivar->guid.data2 = grub_cpu_to_le16 (grub_strtoul (guid, &guid, 16)); + if (*guid != '-') +- return 0; ++ continue; + guid++; + + efivar->guid.data3 = grub_cpu_to_le16 (grub_strtoul (guid, &guid, 16)); + if (*guid != '-') +- return 0; ++ continue; + guid++; + + guidcomp = grub_strtoull (guid, 0, 16); +@@ -162,10 +173,10 @@ nvram_set (void * data __attribute__ ((unused))) + + varname = grub_malloc (grub_strlen (name) + 1); + if (! varname) +- return 1; ++ return grub_errno; + + if (unescape (name, varname, varname + grub_strlen (name) + 1, &len)) +- return 1; ++ break; + + len = grub_utf8_to_utf16 ((grub_uint16_t *) nvramptr, + (nvramsize - (nvramptr - nvram)) / 2, +@@ -179,33 +190,16 @@ nvram_set (void * data __attribute__ ((unused))) + if (unescape (var->value, nvramptr, nvram + nvramsize, &len)) + { + efivar->namelen = 0; +- return 1; ++ break; + } + + nvramptr += len; + + efivar->size = len; +- +- return 0; + } +- +- /* Copy to definitive loaction */ +- grub_dprintf ("efiemu", "preparing pnvram\n"); +- +- env = grub_env_get ("EfiEmu.pnvram.high_monotonic_count"); +- *high_monotonic_count = env ? grub_strtoul (env, 0, 0) : 1; +- env = grub_env_get ("EfiEmu.pnvram.timezone"); +- *timezone = env ? grub_strtosl (env, 0, 0) : GRUB_EFI_UNSPECIFIED_TIMEZONE; +- env = grub_env_get ("EfiEmu.pnvram.accuracy"); +- *accuracy = env ? grub_strtoul (env, 0, 0) : 50000000; +- env = grub_env_get ("EfiEmu.pnvram.daylight"); +- *daylight = env ? grub_strtoul (env, 0, 0) : 0; +- +- nvramptr = nvram; +- grub_memset (nvram, 0, nvramsize); +- grub_env_iterate (iterate_env); + if (grub_errno) + return grub_errno; ++ + *nvramsize_def = nvramsize; + + /* Register symbols */ +diff --git a/grub-core/kern/corecmd.c b/grub-core/kern/corecmd.c +index 0dc4d00..cfab676 100644 +--- a/grub-core/kern/corecmd.c ++++ b/grub-core/kern/corecmd.c +@@ -28,14 +28,6 @@ + #include + #include + +-/* Helper for grub_core_cmd_set. */ +-static int +-print_env (struct grub_env_var *env) +-{ +- grub_printf ("%s=%s\n", env->name, env->value); +- return 0; +-} +- + /* set ENVVAR=VALUE */ + static grub_err_t + grub_core_cmd_set (struct grub_command *cmd __attribute__ ((unused)), +@@ -46,7 +38,9 @@ grub_core_cmd_set (struct grub_command *cmd __attribute__ ((unused)), + + if (argc < 1) + { +- grub_env_iterate (print_env); ++ struct grub_env_var *env; ++ FOR_SORTED_ENV (env) ++ grub_printf ("%s=%s\n", env->name, env->value); + return 0; + } + +diff --git a/grub-core/kern/env.c b/grub-core/kern/env.c +index 7bfa238..c408626 100644 +--- a/grub-core/kern/env.c ++++ b/grub-core/kern/env.c +@@ -166,11 +166,10 @@ grub_env_unset (const char *name) + grub_free (var); + } + +-void +-grub_env_iterate (int (*func) (struct grub_env_var *var)) ++struct grub_env_var * ++grub_env_update_get_sorted (void) + { +- struct grub_env_sorted_var *sorted_list = 0; +- struct grub_env_sorted_var *sorted_var; ++ struct grub_env_var *sorted_list = 0; + int i; + + /* Add variables associated with this context into a sorted list. */ +@@ -180,40 +179,20 @@ grub_env_iterate (int (*func) (struct grub_env_var *var)) + + for (var = grub_current_context->vars[i]; var; var = var->next) + { +- struct grub_env_sorted_var *p, **q; +- +- sorted_var = grub_malloc (sizeof (*sorted_var)); +- if (! sorted_var) +- goto fail; +- +- sorted_var->var = var; ++ struct grub_env_var *p, **q; + +- for (q = &sorted_list, p = *q; p; q = &((*q)->next), p = *q) ++ for (q = &sorted_list, p = *q; p; q = &((*q)->sorted_next), p = *q) + { +- if (grub_strcmp (p->var->name, var->name) > 0) ++ if (grub_strcmp (p->name, var->name) > 0) + break; + } + +- sorted_var->next = *q; +- *q = sorted_var; ++ var->sorted_next = *q; ++ *q = var; + } + } + +- /* Iterate FUNC on the sorted list. */ +- for (sorted_var = sorted_list; sorted_var; sorted_var = sorted_var->next) +- if (func (sorted_var->var)) +- break; +- +- fail: +- +- /* Free the sorted list. */ +- for (sorted_var = sorted_list; sorted_var; ) +- { +- struct grub_env_sorted_var *tmp = sorted_var->next; +- +- grub_free (sorted_var); +- sorted_var = tmp; +- } ++ return sorted_list; + } + + grub_err_t +diff --git a/grub-core/loader/i386/bsd.c b/grub-core/loader/i386/bsd.c +index 6199609..e89ec26 100644 +--- a/grub-core/loader/i386/bsd.c ++++ b/grub-core/loader/i386/bsd.c +@@ -589,33 +589,7 @@ grub_freebsd_boot (void) + grub_err_t err; + grub_size_t tag_buf_len = 0; + +- auto int iterate_env (struct grub_env_var *var); +- int iterate_env (struct grub_env_var *var) +- { +- if ((!grub_memcmp (var->name, "kFreeBSD.", sizeof("kFreeBSD.") - 1)) && (var->name[sizeof("kFreeBSD.") - 1])) +- { +- grub_strcpy ((char *) p, &var->name[sizeof("kFreeBSD.") - 1]); +- p += grub_strlen ((char *) p); +- *(p++) = '='; +- grub_strcpy ((char *) p, var->value); +- p += grub_strlen ((char *) p) + 1; +- } +- +- return 0; +- } +- +- auto int iterate_env_count (struct grub_env_var *var); +- int iterate_env_count (struct grub_env_var *var) +- { +- if ((!grub_memcmp (var->name, "kFreeBSD.", sizeof("kFreeBSD.") - 1)) && (var->name[sizeof("kFreeBSD.") - 1])) +- { +- p_size += grub_strlen (&var->name[sizeof("kFreeBSD.") - 1]); +- p_size++; +- p_size += grub_strlen (var->value) + 1; +- } +- +- return 0; +- } ++ struct grub_env_var *var; + + grub_memset (&bi, 0, sizeof (bi)); + bi.version = FREEBSD_BOOTINFO_VERSION; +@@ -624,7 +598,13 @@ grub_freebsd_boot (void) + bi.boot_device = freebsd_biosdev; + + p_size = 0; +- grub_env_iterate (iterate_env_count); ++ FOR_SORTED_ENV (var) ++ if ((grub_memcmp (var->name, "kFreeBSD.", sizeof("kFreeBSD.") - 1) == 0) && (var->name[sizeof("kFreeBSD.") - 1])) ++ { ++ p_size += grub_strlen (&var->name[sizeof("kFreeBSD.") - 1]); ++ p_size++; ++ p_size += grub_strlen (var->value) + 1; ++ } + + if (p_size) + p_size = ALIGN_PAGE (kern_end + p_size + 1) - kern_end; +@@ -664,7 +644,15 @@ grub_freebsd_boot (void) + p0 = p; + kern_end += p_size; + +- grub_env_iterate (iterate_env); ++ FOR_SORTED_ENV (var) ++ if ((grub_memcmp (var->name, "kFreeBSD.", sizeof("kFreeBSD.") - 1) == 0) && (var->name[sizeof("kFreeBSD.") - 1])) ++ { ++ grub_strcpy ((char *) p, &var->name[sizeof("kFreeBSD.") - 1]); ++ p += grub_strlen ((char *) p); ++ *(p++) = '='; ++ grub_strcpy ((char *) p, var->value); ++ p += grub_strlen ((char *) p) + 1; ++ } + + if (p != p0) + { +diff --git a/grub-core/loader/xnu.c b/grub-core/loader/xnu.c +index 8c522f5..cdd9715 100644 +--- a/grub-core/loader/xnu.c ++++ b/grub-core/loader/xnu.c +@@ -1332,8 +1332,8 @@ unescape (char *name, char *curdot, char *nextdot, int *len) + grub_err_t + grub_xnu_fill_devicetree (void) + { +- auto int iterate_env (struct grub_env_var *var); +- int iterate_env (struct grub_env_var *var) ++ struct grub_env_var *var; ++ FOR_SORTED_ENV (var) + { + char *nextdot = 0, *curdot; + struct grub_xnu_devtree_key **curkey = &grub_xnu_devtree_root; +@@ -1343,7 +1343,7 @@ grub_xnu_fill_devicetree (void) + + if (grub_memcmp (var->name, "XNU.DeviceTree.", + sizeof ("XNU.DeviceTree.") - 1) != 0) +- return 0; ++ continue; + + curdot = var->name + sizeof ("XNU.DeviceTree.") - 1; + nextdot = grub_strchr (curdot, '.'); +@@ -1354,7 +1354,7 @@ grub_xnu_fill_devicetree (void) + name = grub_realloc (name, nextdot - curdot + 1); + + if (!name) +- return 1; ++ return grub_errno; + + unescape (name, curdot, nextdot, &len); + name[len - 1] = 0; +@@ -1372,7 +1372,7 @@ grub_xnu_fill_devicetree (void) + name = grub_realloc (name, nextdot - curdot + 1); + + if (!name) +- return 1; ++ return grub_errno; + + unescape (name, curdot, nextdot, &len); + name[len] = 0; +@@ -1382,18 +1382,14 @@ grub_xnu_fill_devicetree (void) + + data = grub_malloc (grub_strlen (var->value) + 1); + if (!data) +- return 1; ++ return grub_errno; + + unescape (data, var->value, var->value + grub_strlen (var->value), + &len); + curvalue->datasize = len; + curvalue->data = data; +- +- return 0; + } + +- grub_env_iterate (iterate_env); +- + return grub_errno; + } + +diff --git a/include/grub/env.h b/include/grub/env.h +index ef42582..76f832e 100644 +--- a/include/grub/env.h ++++ b/include/grub/env.h +@@ -39,13 +39,17 @@ struct grub_env_var + grub_env_write_hook_t write_hook; + struct grub_env_var *next; + struct grub_env_var **prevp; ++ struct grub_env_var *sorted_next; + int global; + }; + + grub_err_t EXPORT_FUNC(grub_env_set) (const char *name, const char *val); + const 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_update_get_sorted) (void); ++ ++#define FOR_SORTED_ENV(var) for (var = grub_env_update_get_sorted (); var; var = var->sorted_next) ++ + 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); +-- +1.8.1.4 + diff --git a/0191-grub-core-commands-regexp.c-set_matches-Move-setvar-.patch b/0191-grub-core-commands-regexp.c-set_matches-Move-setvar-.patch new file mode 100644 index 0000000..3fe01c2 --- /dev/null +++ b/0191-grub-core-commands-regexp.c-set_matches-Move-setvar-.patch @@ -0,0 +1,90 @@ +From 722e9b8b8bcf3d27f5f69b64ebcf10fad9e86cbb Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sun, 3 Mar 2013 15:24:02 +0100 +Subject: [PATCH 191/364] * grub-core/commands/regexp.c (set_matches): + Move setvar out of its parent. + +--- + ChangeLog | 5 +++++ + grub-core/commands/regexp.c | 27 +++++++++++++++------------ + 2 files changed, 20 insertions(+), 12 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 5f9cde5..e5e2248 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,10 @@ + 2013-03-03 Vladimir Serbinenko + ++ * grub-core/commands/regexp.c (set_matches): Move setvar out of its ++ parent. ++ ++2013-03-03 Vladimir Serbinenko ++ + * grub-core/kern/env.c, include/grub/env.h: Change iterator through + all vars to a macro. All users updated. + +diff --git a/grub-core/commands/regexp.c b/grub-core/commands/regexp.c +index b0706d0..f00b184 100644 +--- a/grub-core/commands/regexp.c ++++ b/grub-core/commands/regexp.c +@@ -47,6 +47,18 @@ static const struct grub_arg_option options[] = + }; + + static grub_err_t ++setvar (char *str, char *v, regmatch_t *m) ++{ ++ char ch; ++ grub_err_t err; ++ ch = str[m->rm_eo]; ++ str[m->rm_eo] = '\0'; ++ err = grub_env_set (v, str + m->rm_so); ++ str[m->rm_eo] = ch; ++ return err; ++} ++ ++static grub_err_t + set_matches (char **varnames, char *str, grub_size_t nmatches, + regmatch_t *matches) + { +@@ -56,18 +68,9 @@ set_matches (char **varnames, char *str, grub_size_t nmatches, + grub_err_t err; + unsigned long j; + +- auto void setvar (char *v, regmatch_t *m); +- void setvar (char *v, regmatch_t *m) +- { +- char ch; +- ch = str[m->rm_eo]; +- str[m->rm_eo] = '\0'; +- err = grub_env_set (v, str + m->rm_so); +- str[m->rm_eo] = ch; +- } +- + for (i = 0; varnames && varnames[i]; i++) + { ++ err = GRUB_ERR_NONE; + p = grub_strchr (varnames[i], ':'); + if (! p) + { +@@ -75,7 +78,7 @@ set_matches (char **varnames, char *str, grub_size_t nmatches, + if (nmatches < 2 || matches[1].rm_so == -1) + grub_env_unset (varnames[i]); + else +- setvar (varnames[i], &matches[1]); ++ err = setvar (str, varnames[i], &matches[1]); + } + else + { +@@ -87,7 +90,7 @@ set_matches (char **varnames, char *str, grub_size_t nmatches, + if (nmatches <= j || matches[j].rm_so == -1) + grub_env_unset (p + 1); + else +- setvar (p + 1, &matches[j]); ++ err = setvar (str, p + 1, &matches[j]); + } + + if (err != GRUB_ERR_NONE) +-- +1.8.1.4 + diff --git a/0192-grub-core-script-execute.c-grub_script_arglist_to_ar.patch b/0192-grub-core-script-execute.c-grub_script_arglist_to_ar.patch new file mode 100644 index 0000000..e094106 --- /dev/null +++ b/0192-grub-core-script-execute.c-grub_script_arglist_to_ar.patch @@ -0,0 +1,127 @@ +From cd2343c20da69dd14df7ff8f558014edb70f8927 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sun, 3 Mar 2013 15:26:29 +0100 +Subject: [PATCH 192/364] * grub-core/script/execute.c + (grub_script_arglist_to_argv): Move append out of its parent. + +--- + ChangeLog | 5 +++++ + grub-core/script/execute.c | 53 +++++++++++++++++++++++----------------------- + 2 files changed, 32 insertions(+), 26 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index e5e2248..e67ca9a 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,10 @@ + 2013-03-03 Vladimir Serbinenko + ++ * grub-core/script/execute.c (grub_script_arglist_to_argv): Move ++ append out of its parent. ++ ++2013-03-03 Vladimir Serbinenko ++ + * grub-core/commands/regexp.c (set_matches): Move setvar out of its + parent. + +diff --git a/grub-core/script/execute.c b/grub-core/script/execute.c +index d6a2c78..a1dcc34 100644 +--- a/grub-core/script/execute.c ++++ b/grub-core/script/execute.c +@@ -590,6 +590,29 @@ gettext_append (struct grub_script_argv *result, const char *orig_str) + return rval; + } + ++static int ++append (struct grub_script_argv *result, ++ const char *s, int escape_type) ++{ ++ int r; ++ char *p = 0; ++ ++ if (escape_type == 0) ++ return grub_script_argv_append (result, s, grub_strlen (s)); ++ ++ if (escape_type > 0) ++ p = wildcard_escape (s); ++ else if (escape_type < 0) ++ p = wildcard_unescape (s); ++ ++ if (! p) ++ return 1; ++ ++ r = grub_script_argv_append (result, p, grub_strlen (p)); ++ grub_free (p); ++ return r; ++} ++ + /* Convert arguments in ARGLIST into ARGV form. */ + static int + grub_script_arglist_to_argv (struct grub_script_arglist *arglist, +@@ -600,28 +623,6 @@ grub_script_arglist_to_argv (struct grub_script_arglist *arglist, + struct grub_script_arg *arg = 0; + struct grub_script_argv result = { 0, 0, 0 }; + +- auto int append (const char *s, int escape_type); +- int append (const char *s, int escape_type) +- { +- int r; +- char *p = 0; +- +- if (escape_type == 0) +- return grub_script_argv_append (&result, s, grub_strlen (s)); +- +- if (escape_type > 0) +- p = wildcard_escape (s); +- else if (escape_type < 0) +- p = wildcard_unescape (s); +- +- if (! p) +- return 1; +- +- r = grub_script_argv_append (&result, p, grub_strlen (p)); +- grub_free (p); +- return r; +- } +- + for (; arglist && arglist->arg; arglist = arglist->next) + { + if (grub_script_argv_next (&result)) +@@ -648,7 +649,7 @@ grub_script_arglist_to_argv (struct grub_script_arglist *arglist, + } + else + { +- if (append (values[i], 1)) ++ if (append (&result, values[i], 1)) + goto fail; + } + +@@ -694,7 +695,7 @@ grub_script_arglist_to_argv (struct grub_script_arglist *arglist, + + case GRUB_SCRIPT_ARG_TYPE_DQSTR: + case GRUB_SCRIPT_ARG_TYPE_SQSTR: +- if (append (arg->str, 1)) ++ if (append (&result, arg->str, 1)) + goto fail; + break; + } +@@ -727,14 +728,14 @@ grub_script_arglist_to_argv (struct grub_script_arglist *arglist, + if (! expansions) + { + grub_script_argv_next (&result); +- append (unexpanded.args[i], -1); ++ append (&result, unexpanded.args[i], -1); + } + else + { + for (j = 0; expansions[j]; j++) + { + failed = (failed || grub_script_argv_next (&result) || +- append (expansions[j], 0)); ++ append (&result, expansions[j], 0)); + grub_free (expansions[j]); + } + grub_free (expansions); +-- +1.8.1.4 + diff --git a/0193-Remove-all-trampoline-support.-Add-Wtrampolines-when.patch b/0193-Remove-all-trampoline-support.-Add-Wtrampolines-when.patch new file mode 100644 index 0000000..6a5c052 --- /dev/null +++ b/0193-Remove-all-trampoline-support.-Add-Wtrampolines-when.patch @@ -0,0 +1,202 @@ +From b4a236b957cd9f65bc70f04a0365085f8183bcb9 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sun, 3 Mar 2013 15:57:30 +0100 +Subject: [PATCH 193/364] Remove all trampoline support. Add + -Wtrampolines when present. Remove symbols used for trampolines to make + link fail if trampolines are present. + +--- + ChangeLog | 6 ++++++ + conf/Makefile.common | 2 +- + config.h.in | 7 ------- + configure.ac | 31 +++++++++++-------------------- + grub-core/kern/misc.c | 8 -------- + include/grub/libgcc.h | 8 -------- + include/grub/misc.h | 4 ---- + 7 files changed, 18 insertions(+), 48 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index e67ca9a..cacba37 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,11 @@ + 2013-03-03 Vladimir Serbinenko + ++ Remove all trampoline support. Add -Wtrampolines when ++ present. Remove symbols used for trampolines to make ++ link fail if trampolines are present. ++ ++2013-03-03 Vladimir Serbinenko ++ + * grub-core/script/execute.c (grub_script_arglist_to_argv): Move + append out of its parent. + +diff --git a/conf/Makefile.common b/conf/Makefile.common +index 75c0a5e..c185a55 100644 +--- a/conf/Makefile.common ++++ b/conf/Makefile.common +@@ -30,7 +30,7 @@ if COND_mips_loongson + CPPFLAGS_PLATFORM = -DUSE_ASCII_FAILBACK + endif + if COND_mips +- CFLAGS_PLATFORM += -mflush-func=grub_cpu_flush_cache ++ CFLAGS_PLATFORM += -mflush-func=grub_red_herring + CCASFLAGS_PLATFORM = -march=mips3 + endif + if COND_sparc64_ieee1275 +diff --git a/config.h.in b/config.h.in +index 91afd98..621742c 100644 +--- a/config.h.in ++++ b/config.h.in +@@ -11,7 +11,6 @@ + + #if defined (GRUB_UTIL) || !defined (GRUB_MACHINE) + #include +-#define NESTED_FUNC_ATTR + #else + /* Define if C symbols get an underscore after compilation. */ + #define HAVE_ASM_USCORE @HAVE_ASM_USCORE@ +@@ -49,10 +48,4 @@ + + #define RE_ENABLE_I18N 1 + +-#if defined(__i386__) +-#define NESTED_FUNC_ATTR __attribute__ ((__regparm__ (1))) +-#else +-#define NESTED_FUNC_ATTR +-#endif +- + #endif +diff --git a/configure.ac b/configure.ac +index 92b550a..038f429 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -357,21 +357,18 @@ AC_CHECK_HEADER([util.h], [ + ]) + AC_SUBST([LIBUTIL]) + +-AC_CACHE_CHECK([whether -Wno-trampolines work], [grub_cv_host_cc_wnotrampolines], [ ++AC_CACHE_CHECK([whether -Wtrampolines work], [grub_cv_host_cc_wtrampolines], [ + SAVED_CFLAGS="$CFLAGS" +- # Test for -Wtrampolines rather than -Wno-trampolines to reduce confusion +- # in the event of later failures (since -Wno-* is always accepted, but +- # produces a diagnostic if something else is wrong). + CFLAGS="$HOST_CFLAGS -Wtrampolines" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include + int va_arg_func (int fixed, va_list args);]], [[]])], +- [grub_cv_host_cc_wnotrampolines=yes], +- [grub_cv_host_cc_wnotrampolines=no]) ++ [grub_cv_host_cc_wtrampolines=yes], ++ [grub_cv_host_cc_wtrampolines=no]) + CFLAGS="$SAVED_CFLAGS" + ]) + +-if test x"$grub_host_cv_cc_wnotrampolines" = xyes ; then +- HOST_CFLAGS="$HOST_CFLAGS -Wno-trampolines" ++if test x"$grub_host_cv_cc_wtrampolines" = xyes ; then ++ HOST_CFLAGS="$HOST_CFLAGS -Wtrampolines" + fi + + # +@@ -621,9 +618,6 @@ fi + # Compiler features. + # + +-# Need __enable_execute_stack() for nested function trampolines? +-grub_CHECK_ENABLE_EXECUTE_STACK +- + # Position independent executable. + grub_CHECK_PIE + [# Need that, because some distributions ship compilers that include +@@ -715,7 +709,7 @@ 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 __ia64_trampoline __udivsi3 __umoddi3 __udivdi3 __divsi3 __modsi3 __umodsi3 __moddi3 __divdi3 __ctzdi2 __ctzsi2) ++AC_CHECK_FUNCS(__bswapsi2 __bswapdi2 __ashldi3 __ashrdi3 __lshrdi3 __ucmpdi2 _restgpr_14_x __udivsi3 __umoddi3 __udivdi3 __divsi3 __modsi3 __umodsi3 __moddi3 __divdi3 __ctzdi2 __ctzsi2) + + if test "x$TARGET_APPLE_CC" = x1 ; then + CFLAGS="$TARGET_CFLAGS -nostdlib" +@@ -761,21 +755,18 @@ if test x"$grub_cv_cc_isystem" = xyes ; then + fi + fi + +-AC_CACHE_CHECK([whether -Wno-trampolines work], [grub_cv_cc_wnotrampolines], [ ++AC_CACHE_CHECK([whether -Wtrampolines work], [grub_cv_cc_wtrampolines], [ + SAVED_CFLAGS="$CFLAGS" +- # Test for -Wtrampolines rather than -Wno-trampolines to reduce confusion +- # in the event of later failures (since -Wno-* is always accepted, but +- # produces a diagnostic if something else is wrong). + CFLAGS="$TARGET_CFLAGS -Wtrampolines" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include + int va_arg_func (int fixed, va_list args);]], [[]])], +- [grub_cv_cc_wnotrampolines=yes], +- [grub_cv_cc_wnotrampolines=no]) ++ [grub_cv_cc_wtrampolines=yes], ++ [grub_cv_cc_wtrampolines=no]) + CFLAGS="$SAVED_CFLAGS" + ]) + +-if test x"$grub_cv_cc_wnotrampolines" = xyes ; then +- TARGET_CFLAGS="$TARGET_CFLAGS -Wno-trampolines" ++if test x"$grub_cv_cc_wtrampolines" = xyes ; then ++ TARGET_CFLAGS="$TARGET_CFLAGS -Wtrampolines" + fi + + # Restore the flags. +diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c +index c3203a0..6cb8f0e 100644 +--- a/grub-core/kern/misc.c ++++ b/grub-core/kern/misc.c +@@ -1120,14 +1120,6 @@ grub_abort (void) + void abort (void) __attribute__ ((alias ("grub_abort"))); + #endif + +-#if 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))) +-{ +-} +-#endif +- + #if NEED_REGISTER_FRAME_INFO && !defined(GRUB_UTIL) + void __register_frame_info (void) + { +diff --git a/include/grub/libgcc.h b/include/grub/libgcc.h +index 956d639..ca0d577 100644 +--- a/include/grub/libgcc.h ++++ b/include/grub/libgcc.h +@@ -74,14 +74,6 @@ void EXPORT_FUNC (__ctzsi2) (void); + # endif + #endif + +-# ifdef HAVE___IA64_TRAMPOLINE +-void EXPORT_FUNC (__ia64_trampoline) (void); +-# endif +- +-#ifdef HAVE___TRAMPOLINE_SETUP +-void EXPORT_FUNC (__trampoline_setup) (void); +-#endif +- + #ifdef HAVE__RESTGPR_14_X + void EXPORT_FUNC (_restgpr_14_x) (void); + void EXPORT_FUNC (_restgpr_15_x) (void); +diff --git a/include/grub/misc.h b/include/grub/misc.h +index 33e6b73..11eeb22 100644 +--- a/include/grub/misc.h ++++ b/include/grub/misc.h +@@ -382,10 +382,6 @@ grub_uint64_t EXPORT_FUNC(grub_divmod64) (grub_uint64_t n, + grub_uint64_t d, + grub_uint64_t *r); + +-#if !defined(GRUB_UTIL) && NEED_ENABLE_EXECUTE_STACK +-void EXPORT_FUNC(__enable_execute_stack) (void *addr); +-#endif +- + #if !defined(GRUB_UTIL) && NEED_REGISTER_FRAME_INFO + void EXPORT_FUNC (__register_frame_info) (void); + void EXPORT_FUNC (__deregister_frame_info) (void); +-- +1.8.1.4 + diff --git a/0194-grub-core-term-terminfo.c-grub_terminfo_cls-Issue-an.patch b/0194-grub-core-term-terminfo.c-grub_terminfo_cls-Issue-an.patch new file mode 100644 index 0000000..27fa422 --- /dev/null +++ b/0194-grub-core-term-terminfo.c-grub_terminfo_cls-Issue-an.patch @@ -0,0 +1,41 @@ +From 90d1b9374dd522d4552b17b8fe1b4a49de63b997 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Tue, 5 Mar 2013 20:00:51 +0100 +Subject: [PATCH 194/364] * grub-core/term/terminfo.c + (grub_terminfo_cls): Issue an explicit gotoxy to 0,0. + +--- + ChangeLog | 5 +++++ + grub-core/term/terminfo.c | 3 +-- + 2 files changed, 6 insertions(+), 2 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index cacba37..f1ab52a 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,8 @@ ++2013-03-05 Vladimir Serbinenko ++ ++ * grub-core/term/terminfo.c (grub_terminfo_cls): Issue an explicit ++ gotoxy to 0,0. ++ + 2013-03-03 Vladimir Serbinenko + + Remove all trampoline support. Add -Wtrampolines when +diff --git a/grub-core/term/terminfo.c b/grub-core/term/terminfo.c +index eb0ef00..a46bb4b 100644 +--- a/grub-core/term/terminfo.c ++++ b/grub-core/term/terminfo.c +@@ -272,8 +272,7 @@ grub_terminfo_cls (struct grub_term_output *term) + = (struct grub_terminfo_output_state *) term->data; + + putstr (term, grub_terminfo_tparm (data->cls)); +- +- data->xpos = data->ypos = 0; ++ grub_terminfo_gotoxy (term, 0, 0); + } + + void +-- +1.8.1.4 + diff --git a/0195-Lift-up-core-size-limits-on-some-platforms.-Fix-pote.patch b/0195-Lift-up-core-size-limits-on-some-platforms.-Fix-pote.patch new file mode 100644 index 0000000..5cfe307 --- /dev/null +++ b/0195-Lift-up-core-size-limits-on-some-platforms.-Fix-pote.patch @@ -0,0 +1,462 @@ +From 68cd2e93537bee644f0595cb0b734fe53cfa0637 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Thu, 7 Mar 2013 08:17:24 +0100 +Subject: [PATCH 195/364] Lift up core size limits on some platforms. + Fix potential memory corruption with big core on small memory systems. + Document remaining limits. + +--- + ChangeLog | 6 ++++ + docs/grub.texi | 38 +++++++++++++++++++++++++ + grub-core/kern/i386/coreboot/init.c | 38 ++++++++++++++----------- + grub-core/kern/i386/pc/init.c | 12 +++++++- + grub-core/kern/main.c | 56 ++++++++++++++++++++++++++++++++----- + grub-core/kern/mm.c | 21 ++++++++++++++ + include/grub/kernel.h | 25 +++++++++++++++++ + include/grub/offsets.h | 1 + + util/grub-mkimage.c | 47 +++++++++++++++++++++++++------ + 9 files changed, 211 insertions(+), 33 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index f1ab52a..96527dd 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,9 @@ ++2013-03-07 Vladimir Serbinenko ++ ++ Lift up core size limits on some platforms. Fix potential memory ++ corruption with big core on small memory systems. Document remaining ++ limits. ++ + 2013-03-05 Vladimir Serbinenko + + * grub-core/term/terminfo.c (grub_terminfo_cls): Issue an explicit +diff --git a/docs/grub.texi b/docs/grub.texi +index 9941b47..0b66827 100644 +--- a/docs/grub.texi ++++ b/docs/grub.texi +@@ -89,6 +89,7 @@ This edition documents version @value{VERSION}. + * Serial terminal:: Using GRUB via a serial line + * Vendor power-on keys:: Changing GRUB behaviour on vendor power-on keys + * Images:: GRUB image files ++* Core image size limitation:: GRUB image files size limitations + * Filesystem:: Filesystem syntax and semantics + * Interface:: The menu and the command-line + * Environment:: GRUB environment variables +@@ -2390,6 +2391,43 @@ In GRUB 2, images for PXE network booting are now constructed using + contains the @samp{pxe} and @samp{pxecmd} modules. @xref{Network}. + @end table + ++@node Core image size limitation ++@chapter Core image size limitation ++ ++Heavily limited platforms: ++@itemize ++@item i386-pc (normal and PXE): the core image size (compressed) is limited by 458240 bytes. ++ kernel.img (.text + .data + .bss, uncompressed) is limited by 392704 bytes. ++ module size (uncompressed) + kernel.img (.text + .data, uncompressed) is limited by the size of contiguous chunk at 1M address. ++@item sparc64-ieee1275: kernel.img (.text + .data + .bss) + modules + 256K (stack) + 2M (heap) is limited by space available at 0x4400. On most platforms it's just 3 or 4M since ieee1275 maps only so much. ++@item i386-ieee1275: kernel.img (.text + .data + .bss) + modules is limited by memory available at 0x10000, at most 596K ++@end itemize ++ ++Lightly limited platforms: ++ ++@itemize ++@item i386-qemu: kernel.img (.text + .data + .bss) is limited by 392704 bytes. ++ (core.img would be limited by ROM size but it's unlimited on qemu ++@item All EFI platforms: limited by contiguous RAM size and possibly firmware bugs ++@item Coreboot and multiboot. kernel.img (.text + .data + .bss) is limited by 392704 bytes. ++ module size is limited by the size of contiguous chunk at 1M address. ++@item mipsel-loongson (ELF), mips(el)-qemu_mips (ELF): if uncompressed: ++ kernel.img (.text + .data) + modules is limited by the space from 80200000 forward ++ if compressed: ++ kernel.img (.text + .data, uncompressed) + modules (uncompressed) ++ + (modules + kernel.img (.text + .data)) (compressed) ++ + decompressor is limited by the space from 80200000 forward ++@item mipsel-loongson (Flash), mips(el)-qemu_mips (Flash): kernel.img (.text + .data) + modules is limited by the space from 80200000 forward ++ core.img (final) is limited by flash size (512K on yeeloong and fulooong) ++@item mips-arc: if uncompressed: ++ kernel.img (.text + .data) is limited by the space from 8bd00000 forward ++ modules + dummy decompressor is limited by the space from 8bd00000 backward ++ if compressed: ++ kernel.img (.text + .data, uncompressed) is limited by the space from 8bd00000 forward ++ modules (uncompressed) + (modules + kernel.img (.text + .data)) (compressed, aligned to 1M) ++ + 1M (decompressor + scratch space) is limited by the space from 8bd00000 backward ++@item powerpc-ieee1275: kernel.img (.text + .data + .bss) + modules is limited by space available at 0x200000 ++@end itemize + + @node Filesystem + @chapter Filesystem syntax and semantics +diff --git a/grub-core/kern/i386/coreboot/init.c b/grub-core/kern/i386/coreboot/init.c +index 48fd1a6..bfc8f3f 100644 +--- a/grub-core/kern/i386/coreboot/init.c ++++ b/grub-core/kern/i386/coreboot/init.c +@@ -54,7 +54,8 @@ grub_exit (void) + #ifdef GRUB_MACHINE_QEMU + grub_addr_t grub_modbase; + #else +-grub_addr_t grub_modbase = ALIGN_UP((grub_addr_t) _end, GRUB_KERNEL_MACHINE_MOD_ALIGN); ++grub_addr_t grub_modbase = GRUB_KERNEL_I386_COREBOOT_MODULES_ADDR; ++static grub_uint64_t modend; + #endif + + /* Helper for grub_machine_init. */ +@@ -62,30 +63,32 @@ static int + heap_init (grub_uint64_t addr, grub_uint64_t size, grub_memory_type_t type, + void *data __attribute__ ((unused))) + { ++ grub_uint64_t begin = addr, end = addr + size; ++ + #if GRUB_CPU_SIZEOF_VOID_P == 4 + /* Restrict ourselves to 32-bit memory space. */ +- if (addr > GRUB_ULONG_MAX) ++ if (begin > GRUB_ULONG_MAX) + return 0; +- if (addr + size > GRUB_ULONG_MAX) +- size = GRUB_ULONG_MAX - addr; ++ if (end > GRUB_ULONG_MAX) ++ end = GRUB_ULONG_MAX; + #endif + + if (type != GRUB_MEMORY_AVAILABLE) + return 0; + + /* Avoid the lower memory. */ +- if (addr < GRUB_MEMORY_MACHINE_LOWER_SIZE) +- { +- if (addr + size <= GRUB_MEMORY_MACHINE_LOWER_SIZE) +- return 0; +- else +- { +- size -= GRUB_MEMORY_MACHINE_LOWER_SIZE - addr; +- addr = GRUB_MEMORY_MACHINE_LOWER_SIZE; +- } +- } +- +- grub_mm_init_region ((void *) (grub_addr_t) addr, (grub_size_t) size); ++ if (begin < GRUB_MEMORY_MACHINE_LOWER_SIZE) ++ begin = GRUB_MEMORY_MACHINE_LOWER_SIZE; ++ ++#ifndef GRUB_MACHINE_QEMU ++ if (modend && begin < modend) ++ begin = modend; ++#endif ++ ++ if (end <= begin) ++ return 0; ++ ++ grub_mm_init_region ((void *) (grub_addr_t) begin, (grub_size_t) (end - begin)); + + return 0; + } +@@ -98,6 +101,9 @@ grub_machine_init (void) + + grub_qemu_init_cirrus (); + #endif ++#ifndef GRUB_MACHINE_QEMU ++ modend = grub_modules_get_end (); ++#endif + /* Initialize the console as early as possible. */ + grub_vga_text_init (); + +diff --git a/grub-core/kern/i386/pc/init.c b/grub-core/kern/i386/pc/init.c +index 7d8b12c..730e04a 100644 +--- a/grub-core/kern/i386/pc/init.c ++++ b/grub-core/kern/i386/pc/init.c +@@ -191,6 +191,7 @@ grub_machine_init (void) + #if 0 + int grub_lower_mem; + #endif ++ grub_addr_t modend; + + grub_modbase = GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR + (_edata - _start); + +@@ -222,8 +223,17 @@ grub_machine_init (void) + + compact_mem_regions (); + ++ modend = grub_modules_get_end (); + for (i = 0; i < num_regions; i++) +- grub_mm_init_region ((void *) mem_regions[i].addr, mem_regions[i].size); ++ { ++ grub_addr_t beg = mem_regions[i].addr; ++ grub_addr_t fin = mem_regions[i].addr + mem_regions[i].size; ++ if (modend && beg < modend) ++ beg = modend; ++ if (beg >= fin) ++ continue; ++ grub_mm_init_region ((void *) beg, fin - beg); ++ } + + grub_tsc_init (); + } +diff --git a/grub-core/kern/main.c b/grub-core/kern/main.c +index c43ac6b..e1a2001 100644 +--- a/grub-core/kern/main.c ++++ b/grub-core/kern/main.c +@@ -30,8 +30,10 @@ + #include + #include + +-/* This is actualy platform-independant but used only on loongson and sparc. */ +-#if defined (GRUB_MACHINE_MIPS_LOONGSON) || defined (GRUB_MACHINE_MIPS_QEMU_MIPS) || defined (GRUB_MACHINE_SPARC64) ++#ifdef GRUB_MACHINE_PCBIOS ++#include ++#endif ++ + grub_addr_t + grub_modules_get_end (void) + { +@@ -45,7 +47,6 @@ grub_modules_get_end (void) + + return grub_modbase + modinfo->size; + } +-#endif + + /* Load all modules in core. */ + static void +@@ -67,6 +68,8 @@ grub_load_modules (void) + } + } + ++static char *load_config; ++ + static void + grub_load_config (void) + { +@@ -76,9 +79,17 @@ grub_load_config (void) + /* Not an embedded config, skip. */ + if (header->type != OBJ_TYPE_CONFIG) + continue; +- +- grub_parser_execute ((char *) header + +- sizeof (struct grub_module_header)); ++ ++ load_config = grub_malloc (header->size - sizeof (struct grub_module_header) + 1); ++ if (!load_config) ++ { ++ grub_print_error (); ++ break; ++ } ++ grub_memcpy (load_config, (char *) header + ++ sizeof (struct grub_module_header), ++ header->size - sizeof (struct grub_module_header)); ++ load_config[header->size - sizeof (struct grub_module_header)] = 0; + break; + } + } +@@ -212,6 +223,30 @@ grub_load_normal_mode (void) + grub_command_execute ("normal", 0, 0); + } + ++static void ++reclaim_module_space (void) ++{ ++ grub_addr_t modstart, modend; ++ ++ if (!grub_modbase) ++ return; ++ ++#ifdef GRUB_MACHINE_PCBIOS ++ modstart = GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR; ++#else ++ modstart = grub_modbase; ++#endif ++ modend = grub_modules_get_end (); ++ grub_modbase = 0; ++ ++#if GRUB_KERNEL_PRELOAD_SPACE_REUSABLE ++ grub_mm_init_region ((void *) modstart, modend - modstart); ++#else ++ (void) modstart; ++ (void) modend; ++#endif ++} ++ + /* The main routine. */ + void __attribute__ ((noreturn)) + grub_main (void) +@@ -224,6 +259,8 @@ grub_main (void) + grub_printf ("Welcome to GRUB!\n\n"); + grub_setcolorstate (GRUB_TERM_COLOR_STANDARD); + ++ grub_load_config (); ++ + /* Load pre-loaded modules and free the space. */ + grub_register_exported_symbols (); + #ifdef GRUB_LINKER_HAVE_INIT +@@ -237,9 +274,14 @@ grub_main (void) + grub_env_export ("root"); + grub_env_export ("prefix"); + ++ /* Reclaim space used for modules. */ ++ reclaim_module_space (); ++ + grub_register_core_commands (); + +- grub_load_config (); ++ if (load_config) ++ grub_parser_execute (load_config); ++ + grub_load_normal_mode (); + grub_rescue_run (); + } +diff --git a/grub-core/kern/mm.c b/grub-core/kern/mm.c +index 9f08e05..d869091 100644 +--- a/grub-core/kern/mm.c ++++ b/grub-core/kern/mm.c +@@ -117,6 +117,27 @@ 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 + ++ for (p = &grub_mm_base, q = *p; q; p = &(q->next), q = *p) ++ if ((grub_uint8_t *) addr + size + q->pre_size == (grub_uint8_t *) q) ++ { ++ r = (grub_mm_region_t) ALIGN_UP ((grub_addr_t) addr, GRUB_MM_ALIGN); ++ *r = *q; ++ r->pre_size += size; ++ ++ if (r->pre_size >> GRUB_MM_ALIGN_LOG2) ++ { ++ h = (grub_mm_header_t) (r + 1); ++ h->size = (r->pre_size >> GRUB_MM_ALIGN_LOG2); ++ h->magic = GRUB_MM_ALLOC_MAGIC; ++ r->size += h->size << GRUB_MM_ALIGN_LOG2; ++ r->pre_size &= (GRUB_MM_ALIGN - 1); ++ *p = r; ++ grub_free (h + 1); ++ } ++ *p = r; ++ return; ++ } ++ + /* Allocate a region from the head. */ + r = (grub_mm_region_t) ALIGN_UP ((grub_addr_t) addr, GRUB_MM_ALIGN); + size -= (char *) r - (char *) addr + sizeof (*r); +diff --git a/include/grub/kernel.h b/include/grub/kernel.h +index 23e4f02..73ea416 100644 +--- a/include/grub/kernel.h ++++ b/include/grub/kernel.h +@@ -64,6 +64,29 @@ struct grub_module_info64 + grub_uint64_t size; + }; + ++#ifndef GRUB_UTIL ++/* Space isn't reusable on some platforms. */ ++/* On Qemu the preload space is readonly. */ ++/* On emu there is no preload space. */ ++/* On ieee1275 our code assumes that heap is p=v which isn't guaranteed for module space. */ ++#if defined (GRUB_MACHINE_QEMU) || defined (GRUB_MACHINE_EMU) \ ++ || defined (GRUB_MACHINE_EFI) \ ++ || (defined (GRUB_MACHINE_IEEE1275) && !defined (__sparc__)) ++#define GRUB_KERNEL_PRELOAD_SPACE_REUSABLE 0 ++#endif ++ ++#if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) \ ++ || defined (GRUB_MACHINE_MULTIBOOT) || defined (GRUB_MACHINE_MIPS_QEMU_MIPS) \ ++ || defined (GRUB_MACHINE_MIPS_LOONGSON) || defined (GRUB_MACHINE_ARC) \ ++ || defined (__sparc__) ++/* FIXME: stack is between 2 heap regions. Move it. */ ++#define GRUB_KERNEL_PRELOAD_SPACE_REUSABLE 1 ++#endif ++ ++#ifndef GRUB_KERNEL_PRELOAD_SPACE_REUSABLE ++#error "Please check if preload space is reusable on this platform!" ++#endif ++ + #if GRUB_TARGET_SIZEOF_VOID_P == 8 + #define grub_module_info grub_module_info64 + #else +@@ -82,6 +105,8 @@ extern grub_addr_t EXPORT_VAR (grub_modbase); + + grub_addr_t grub_modules_get_end (void); + ++#endif ++ + /* The start point of the C code. */ + void grub_main (void) __attribute__ ((noreturn)); + +diff --git a/include/grub/offsets.h b/include/grub/offsets.h +index d55e308..bce755d 100644 +--- a/include/grub/offsets.h ++++ b/include/grub/offsets.h +@@ -91,6 +91,7 @@ + #define GRUB_KERNEL_MIPS_ARC_TOTAL_MODULE_SIZE 0x08 + + #define GRUB_KERNEL_I386_COREBOOT_LINK_ADDR 0x8200 ++#define GRUB_KERNEL_I386_COREBOOT_MODULES_ADDR 0x100000 + + #define GRUB_KERNEL_I386_IEEE1275_LINK_ADDR 0x10000 + +diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c +index 29bda17..845abed 100644 +--- a/util/grub-mkimage.c ++++ b/util/grub-mkimage.c +@@ -995,16 +995,42 @@ generate_image (const char *dir, const char *prefix, + { + case IMAGE_I386_PC: + case IMAGE_I386_PC_PXE: +- { +- unsigned num; +- char *boot_path, *boot_img; +- size_t boot_size; +- + if (GRUB_KERNEL_I386_PC_LINK_ADDR + core_size > 0x78000 +- || (core_size > (0xffff << GRUB_DISK_SECTOR_BITS))) ++ || (core_size > (0xffff << GRUB_DISK_SECTOR_BITS)) ++ || (kernel_size + bss_size + GRUB_KERNEL_I386_PC_LINK_ADDR > 0x68000)) + grub_util_error (_("core image is too big (0x%x > 0x%x)"), + GRUB_KERNEL_I386_PC_LINK_ADDR + core_size, + 0x78000); ++ /* fallthrough */ ++ case IMAGE_COREBOOT: ++ case IMAGE_QEMU: ++ if (kernel_size + bss_size + GRUB_KERNEL_I386_PC_LINK_ADDR > 0x68000) ++ grub_util_error (_("kernel image is too big (0x%x > 0x%x)"), ++ kernel_size + bss_size + GRUB_KERNEL_I386_PC_LINK_ADDR, ++ 0x68000); ++ break; ++ case IMAGE_LOONGSON_ELF: ++ case IMAGE_YEELOONG_FLASH: ++ case IMAGE_FULOONG2F_FLASH: ++ case IMAGE_EFI: ++ case IMAGE_MIPS_ARC: ++ case IMAGE_QEMU_MIPS_FLASH: ++ break; ++ case IMAGE_SPARC64_AOUT: ++ case IMAGE_SPARC64_RAW: ++ case IMAGE_I386_IEEE1275: ++ case IMAGE_PPC: ++ break; ++ } ++ ++ switch (image_target->id) ++ { ++ case IMAGE_I386_PC: ++ case IMAGE_I386_PC_PXE: ++ { ++ unsigned num; ++ char *boot_path, *boot_img; ++ size_t boot_size; + + num = ((core_size + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS); + if (image_target->id == IMAGE_I386_PC_PXE) +@@ -1615,9 +1641,12 @@ generate_image (const char *dir, const char *prefix, + 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); ++ if (image_target->id == IMAGE_COREBOOT) ++ target_addr_mods = GRUB_KERNEL_I386_COREBOOT_MODULES_ADDR; ++ else ++ 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); +-- +1.8.1.4 + diff --git a/0196-grub-core-normal-crypto.c-read_crypto_list-Fix-incor.patch b/0196-grub-core-normal-crypto.c-read_crypto_list-Fix-incor.patch new file mode 100644 index 0000000..a8dfb0f --- /dev/null +++ b/0196-grub-core-normal-crypto.c-read_crypto_list-Fix-incor.patch @@ -0,0 +1,56 @@ +From 412f61e8c25bfde5526d86bc2db1988e4c403e1d Mon Sep 17 00:00:00 2001 +From: Nickolai Zeldovich +Date: Thu, 7 Mar 2013 08:41:27 +0100 +Subject: [PATCH 196/364] * grub-core/normal/crypto.c + (read_crypto_list): Fix incorrect OOM check. * + grub-core/normal/term.c (read_terminal_list): Likewise. + +--- + ChangeLog | 6 ++++++ + grub-core/normal/crypto.c | 2 +- + grub-core/normal/term.c | 2 +- + 3 files changed, 8 insertions(+), 2 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 96527dd..ca3d603 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,9 @@ ++2013-03-07 Nickolai Zeldovich ++ ++ * grub-core/normal/crypto.c (read_crypto_list): Fix incorrect ++ OOM check. ++ * grub-core/normal/term.c (read_terminal_list): Likewise. ++ + 2013-03-07 Vladimir Serbinenko + + Lift up core size limits on some platforms. Fix potential memory +diff --git a/grub-core/normal/crypto.c b/grub-core/normal/crypto.c +index e753dd7..2bfd67c 100644 +--- a/grub-core/normal/crypto.c ++++ b/grub-core/normal/crypto.c +@@ -136,7 +136,7 @@ read_crypto_list (const char *prefix) + } + + cur->name = grub_strdup (name); +- if (! name) ++ if (! cur->name) + { + grub_errno = GRUB_ERR_NONE; + grub_free (cur); +diff --git a/grub-core/normal/term.c b/grub-core/normal/term.c +index ae91071..f89e5d2 100644 +--- a/grub-core/normal/term.c ++++ b/grub-core/normal/term.c +@@ -389,7 +389,7 @@ read_terminal_list (const char *prefix) + } + + cur->name = grub_strdup (name); +- if (! name) ++ if (! cur->name) + { + grub_errno = GRUB_ERR_NONE; + grub_free (cur); +-- +1.8.1.4 + diff --git a/0197-grub-core-commands-acpi.c-grub_acpi_create_ebda-Don-.patch b/0197-grub-core-commands-acpi.c-grub_acpi_create_ebda-Don-.patch new file mode 100644 index 0000000..35e9704 --- /dev/null +++ b/0197-grub-core-commands-acpi.c-grub_acpi_create_ebda-Don-.patch @@ -0,0 +1,57 @@ +From c96f4909ef077ca8a1b8a5db356ed290e6177b5f Mon Sep 17 00:00:00 2001 +From: Nickolai Zeldovich +Date: Thu, 7 Mar 2013 08:52:29 +0100 +Subject: [PATCH 197/364] * grub-core/commands/acpi.c + (grub_acpi_create_ebda): Don't dereference null pointer. While the + code is technically correct, gcc may eliminate a null check if pointer + is already dereferenced. + +--- + ChangeLog | 6 ++++++ + grub-core/commands/acpi.c | 7 ++++--- + 2 files changed, 10 insertions(+), 3 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index ca3d603..5fb9b77 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,11 @@ + 2013-03-07 Nickolai Zeldovich + ++ * grub-core/commands/acpi.c (grub_acpi_create_ebda): Don't ++ dereference null pointer. While the code is technically correct, gcc ++ may eliminate a null check if pointer is already dereferenced. ++ ++2013-03-07 Nickolai Zeldovich ++ + * grub-core/normal/crypto.c (read_crypto_list): Fix incorrect + OOM check. + * grub-core/normal/term.c (read_terminal_list): Likewise. +diff --git a/grub-core/commands/acpi.c b/grub-core/commands/acpi.c +index 891e392..8000873 100644 +--- a/grub-core/commands/acpi.c ++++ b/grub-core/commands/acpi.c +@@ -171,7 +171,7 @@ grub_acpi_create_ebda (void) + struct grub_acpi_create_ebda_ctx ctx = { + .highestlow = 0 + }; +- int ebda_kb_len; ++ int ebda_kb_len = 0; + int mmapregion = 0; + grub_uint8_t *ebda, *v1inebda = 0, *v2inebda = 0; + grub_uint8_t *targetebda, *target; +@@ -179,8 +179,9 @@ grub_acpi_create_ebda (void) + struct grub_acpi_rsdp_v20 *v2; + + ebda = (grub_uint8_t *) (grub_addr_t) ((*((grub_uint16_t *)0x40e)) << 4); +- ebda_kb_len = *(grub_uint16_t *) ebda; +- if (! ebda || ebda_kb_len > 16) ++ if (ebda) ++ ebda_kb_len = *(grub_uint16_t *) ebda; ++ if (ebda_kb_len > 16) + ebda_kb_len = 0; + ctx.ebda_len = (ebda_kb_len + 1) << 10; + +-- +1.8.1.4 + diff --git a/0198-grub-core-fs-iso9660.c-add_part-Remove-always_inline.patch b/0198-grub-core-fs-iso9660.c-add_part-Remove-always_inline.patch new file mode 100644 index 0000000..f9eb3b5 --- /dev/null +++ b/0198-grub-core-fs-iso9660.c-add_part-Remove-always_inline.patch @@ -0,0 +1,40 @@ +From 169e65c4e6af3ed59e0854bd41531989a3b34ff5 Mon Sep 17 00:00:00 2001 +From: Andrey Borzenkov +Date: Thu, 7 Mar 2013 09:11:36 +0100 +Subject: [PATCH 198/364] * grub-core/fs/iso9660.c (add_part): Remove + always_inline attribute causing gcc error with gcc 4.7.1. + +--- + ChangeLog | 5 +++++ + grub-core/fs/iso9660.c | 2 +- + 2 files changed, 6 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index 5fb9b77..3b4b3b4 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,8 @@ ++2013-03-07 Andrey Borzenkov ++ ++ * grub-core/fs/iso9660.c (add_part): Remove always_inline attribute ++ causing gcc error with gcc 4.7.1. ++ + 2013-03-07 Nickolai Zeldovich + + * grub-core/commands/acpi.c (grub_acpi_create_ebda): Don't +diff --git a/grub-core/fs/iso9660.c b/grub-core/fs/iso9660.c +index 01a07b8..cdbd6dc 100644 +--- a/grub-core/fs/iso9660.c ++++ b/grub-core/fs/iso9660.c +@@ -524,7 +524,7 @@ struct iterate_dir_ctx + }; + + /* Extend the symlink. */ +-static void __attribute__ ((always_inline)) ++static void + add_part (struct iterate_dir_ctx *ctx, + const char *part, + int len2) +-- +1.8.1.4 + diff --git a/0199-grub-core-fs-fshelp.c-grub_fshelp_log2blksize-Remove.patch b/0199-grub-core-fs-fshelp.c-grub_fshelp_log2blksize-Remove.patch new file mode 100644 index 0000000..cacb83f --- /dev/null +++ b/0199-grub-core-fs-fshelp.c-grub_fshelp_log2blksize-Remove.patch @@ -0,0 +1,70 @@ +From d99417e57a1c5fb1628cc7010a9deabf41786a18 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sun, 10 Mar 2013 14:27:04 +0100 +Subject: [PATCH 199/364] * grub-core/fs/fshelp.c + (grub_fshelp_log2blksize): Remove now unused function. + +--- + ChangeLog | 5 +++++ + grub-core/fs/fshelp.c | 21 --------------------- + include/grub/fshelp.h | 4 ---- + 3 files changed, 5 insertions(+), 25 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 3b4b3b4..c604d8d 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,8 @@ ++2013-03-10 Vladimir Serbinenko ++ ++ * grub-core/fs/fshelp.c (grub_fshelp_log2blksize): Remove now unused ++ function. ++ + 2013-03-07 Andrey Borzenkov + + * grub-core/fs/iso9660.c (add_part): Remove always_inline attribute +diff --git a/grub-core/fs/fshelp.c b/grub-core/fs/fshelp.c +index d56e63f..6d6e71e 100644 +--- a/grub-core/fs/fshelp.c ++++ b/grub-core/fs/fshelp.c +@@ -322,24 +322,3 @@ grub_fshelp_read_file (grub_disk_t disk, grub_fshelp_node_t node, + + return len; + } +- +-unsigned int +-grub_fshelp_log2blksize (unsigned int blksize, unsigned int *pow) +-{ +- int mod; +- +- *pow = 0; +- while (blksize > 1) +- { +- mod = blksize - ((blksize >> 1) << 1); +- blksize >>= 1; +- +- /* Check if it really is a power of two. */ +- if (mod) +- return grub_error (GRUB_ERR_BAD_NUMBER, +- "the blocksize is not a power of two"); +- (*pow)++; +- } +- +- return GRUB_ERR_NONE; +-} +diff --git a/include/grub/fshelp.h b/include/grub/fshelp.h +index 5c57236..3892304 100644 +--- a/include/grub/fshelp.h ++++ b/include/grub/fshelp.h +@@ -77,8 +77,4 @@ EXPORT_FUNC(grub_fshelp_read_file) (grub_disk_t disk, grub_fshelp_node_t node, + grub_off_t filesize, int log2blocksize, + grub_disk_addr_t blocks_start); + +-unsigned int +-EXPORT_FUNC(grub_fshelp_log2blksize) (unsigned int blksize, +- unsigned int *pow); +- + #endif /* ! GRUB_FSHELP_HEADER */ +-- +1.8.1.4 + diff --git a/0200-Avoid-costly-64-bit-division-in-grub_get_time_ms-on-.patch b/0200-Avoid-costly-64-bit-division-in-grub_get_time_ms-on-.patch new file mode 100644 index 0000000..6945db0 --- /dev/null +++ b/0200-Avoid-costly-64-bit-division-in-grub_get_time_ms-on-.patch @@ -0,0 +1,371 @@ +From d47c03e078f39034d1843dfe8a84aedff40638ba Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sun, 10 Mar 2013 17:45:38 +0100 +Subject: [PATCH 200/364] Avoid costly 64-bit division in + grub_get_time_ms on most platforms. + +--- + ChangeLog | 4 ++++ + grub-core/Makefile.am | 14 ++++++------ + grub-core/Makefile.core.def | 3 --- + grub-core/kern/i386/pc/init.c | 6 +++--- + grub-core/kern/i386/pit.c | 49 ------------------------------------------ + grub-core/kern/i386/tsc.c | 50 +++++++++++++++++++++++++++++++++---------- + grub-core/loader/i386/xnu.c | 28 +++++++++++++----------- + include/grub/i386/pc/time.h | 5 ----- + include/grub/i386/pit.h | 2 -- + include/grub/i386/tsc.h | 2 ++ + 10 files changed, 70 insertions(+), 93 deletions(-) + delete mode 100644 grub-core/kern/i386/pit.c + +diff --git a/ChangeLog b/ChangeLog +index c604d8d..bc51ae9 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,9 @@ + 2013-03-10 Vladimir Serbinenko + ++ Avoid costly 64-bit division in grub_get_time_ms on most platforms. ++ ++2013-03-10 Vladimir Serbinenko ++ + * grub-core/fs/fshelp.c (grub_fshelp_log2blksize): Remove now unused + function. + +diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am +index 9cb14e2..221466b 100644 +--- a/grub-core/Makefile.am ++++ b/grub-core/Makefile.am +@@ -98,29 +98,29 @@ if COND_i386_pc + KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h + KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/pxe.h + KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/int.h +-KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pit.h ++KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h + endif + + if COND_i386_efi + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h +-KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pit.h ++KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/pci.h + endif + + if COND_i386_coreboot +-KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pit.h ++KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h + KERNEL_HEADER_FILES += $(top_builddir)/include/grub/i386/pc/int.h + endif + + if COND_i386_multiboot +-KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pit.h ++KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h + KERNEL_HEADER_FILES += $(top_builddir)/include/grub/i386/pc/int.h + endif + + if COND_i386_qemu + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/pci.h +-KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pit.h ++KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h + endif + + if COND_i386_ieee1275 +@@ -128,13 +128,13 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ieee1275.h + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h +-KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pit.h ++KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h + endif + + if COND_x86_64_efi + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h +-KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pit.h ++KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/pci.h + endif + +diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def +index 93ff2a8..3bcf662 100644 +--- a/grub-core/Makefile.core.def ++++ b/grub-core/Makefile.core.def +@@ -102,7 +102,6 @@ kernel = { + + noemu_nodist = symlist.c; + +- i386_pc = kern/generic/rtc_get_time_ms.c; + mips = kern/generic/rtc_get_time_ms.c; + + ieee1275 = disk/ieee1275/ofdisk.c; +@@ -123,8 +122,6 @@ kernel = { + i386_coreboot_multiboot_qemu = kern/i386/coreboot/init.c; + i386_coreboot_multiboot_qemu = term/i386/pc/vga_text.c; + +- x86 = kern/i386/pit.c; +- + efi = disk/efi/efidisk.c; + efi = kern/efi/efi.c; + efi = kern/efi/init.c; +diff --git a/grub-core/kern/i386/pc/init.c b/grub-core/kern/i386/pc/init.c +index 730e04a..5b68504 100644 +--- a/grub-core/kern/i386/pc/init.c ++++ b/grub-core/kern/i386/pc/init.c +@@ -52,8 +52,8 @@ void (*grub_pc_net_config) (char **device, char **path); + * return the real time in ticks, of which there are about + * 18-20 per second + */ +-grub_uint32_t +-grub_get_rtc (void) ++grub_uint64_t ++grub_rtc_get_time_ms (void) + { + struct grub_bios_int_registers regs; + +@@ -61,7 +61,7 @@ grub_get_rtc (void) + regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; + grub_bios_interrupt (0x1a, ®s); + +- return (regs.ecx << 16) | (regs.edx & 0xffff); ++ return ((regs.ecx << 16) | (regs.edx & 0xffff)) * 55ULL; + } + + void +diff --git a/grub-core/kern/i386/pit.c b/grub-core/kern/i386/pit.c +deleted file mode 100644 +index 092481a..0000000 +--- a/grub-core/kern/i386/pit.c ++++ /dev/null +@@ -1,49 +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 . +- */ +- +-#include +-#include +-#include +- +-void +-grub_pit_wait (grub_uint16_t tics) +-{ +- /* Disable timer2 gate and speaker. */ +- grub_outb (grub_inb (GRUB_PIT_SPEAKER_PORT) +- & ~ (GRUB_PIT_SPK_DATA | GRUB_PIT_SPK_TMR2), +- GRUB_PIT_SPEAKER_PORT); +- +- /* Set tics. */ +- grub_outb (GRUB_PIT_CTRL_SELECT_2 | GRUB_PIT_CTRL_READLOAD_WORD, +- GRUB_PIT_CTRL); +- grub_outb (tics & 0xff, GRUB_PIT_COUNTER_2); +- grub_outb (tics >> 8, GRUB_PIT_COUNTER_2); +- +- /* Enable timer2 gate, keep speaker disabled. */ +- grub_outb ((grub_inb (GRUB_PIT_SPEAKER_PORT) & ~ GRUB_PIT_SPK_DATA) +- | GRUB_PIT_SPK_TMR2, +- GRUB_PIT_SPEAKER_PORT); +- +- /* Wait. */ +- while ((grub_inb (GRUB_PIT_SPEAKER_PORT) & GRUB_PIT_SPK_TMR2_LATCH) == 0x00); +- +- /* Disable timer2 gate and speaker. */ +- grub_outb (grub_inb (GRUB_PIT_SPEAKER_PORT) +- & ~ (GRUB_PIT_SPK_DATA | GRUB_PIT_SPK_TMR2), +- GRUB_PIT_SPEAKER_PORT); +-} +diff --git a/grub-core/kern/i386/tsc.c b/grub-core/kern/i386/tsc.c +index c4645f0..9efd633 100644 +--- a/grub-core/kern/i386/tsc.c ++++ b/grub-core/kern/i386/tsc.c +@@ -25,37 +25,66 @@ + #include + #include + #include ++#include + + /* This defines the value TSC had at the epoch (that is, when we calibrated it). */ + static grub_uint64_t tsc_boot_time; + +-/* Calibrated TSC rate. (In TSC ticks per millisecond.) */ +-static grub_uint64_t tsc_ticks_per_ms; ++/* Calibrated TSC rate. (In ms per 2^32 ticks) */ ++/* We assume that the tick is less than 1 ms and hence this value fits ++ in 32-bit. */ ++grub_uint32_t grub_tsc_rate; + ++static void ++grub_pit_wait (grub_uint16_t tics) ++{ ++ /* Disable timer2 gate and speaker. */ ++ grub_outb (grub_inb (GRUB_PIT_SPEAKER_PORT) ++ & ~ (GRUB_PIT_SPK_DATA | GRUB_PIT_SPK_TMR2), ++ GRUB_PIT_SPEAKER_PORT); ++ ++ /* Set tics. */ ++ grub_outb (GRUB_PIT_CTRL_SELECT_2 | GRUB_PIT_CTRL_READLOAD_WORD, ++ GRUB_PIT_CTRL); ++ grub_outb (tics & 0xff, GRUB_PIT_COUNTER_2); ++ grub_outb (tics >> 8, GRUB_PIT_COUNTER_2); ++ ++ /* Enable timer2 gate, keep speaker disabled. */ ++ grub_outb ((grub_inb (GRUB_PIT_SPEAKER_PORT) & ~ GRUB_PIT_SPK_DATA) ++ | GRUB_PIT_SPK_TMR2, ++ GRUB_PIT_SPEAKER_PORT); ++ ++ /* Wait. */ ++ while ((grub_inb (GRUB_PIT_SPEAKER_PORT) & GRUB_PIT_SPK_TMR2_LATCH) == 0x00); ++ ++ /* Disable timer2 gate and speaker. */ ++ grub_outb (grub_inb (GRUB_PIT_SPEAKER_PORT) ++ & ~ (GRUB_PIT_SPK_DATA | GRUB_PIT_SPK_TMR2), ++ GRUB_PIT_SPEAKER_PORT); ++} + + grub_uint64_t + grub_tsc_get_time_ms (void) + { +- return tsc_boot_time + grub_divmod64 (grub_get_tsc (), tsc_ticks_per_ms, 0); +-} ++ grub_uint64_t a = grub_get_tsc () - tsc_boot_time; ++ grub_uint64_t ah = a >> 32; ++ grub_uint64_t al = a & 0xffffffff; + +- +-/* How many RTC ticks to use for calibration loop. (>= 1) */ +-#define CALIBRATION_TICKS 2 ++ return ((al * grub_tsc_rate) >> 32) + ah * grub_tsc_rate; ++} + + /* Calibrate the TSC based on the RTC. */ + static void + calibrate_tsc (void) + { + /* First calibrate the TSC rate (relative, not absolute time). */ +- grub_uint64_t start_tsc; + grub_uint64_t end_tsc; + +- start_tsc = grub_get_tsc (); ++ tsc_boot_time = grub_get_tsc (); + grub_pit_wait (0xffff); + end_tsc = grub_get_tsc (); + +- tsc_ticks_per_ms = grub_divmod64 (end_tsc - start_tsc, 55, 0); ++ grub_tsc_rate = grub_divmod64 ((55ULL << 32), end_tsc - tsc_boot_time, 0); + } + + void +@@ -63,7 +92,6 @@ grub_tsc_init (void) + { + if (grub_cpu_is_tsc_supported ()) + { +- tsc_boot_time = grub_get_tsc (); + calibrate_tsc (); + grub_install_get_time_ms (grub_tsc_get_time_ms); + } +diff --git a/grub-core/loader/i386/xnu.c b/grub-core/loader/i386/xnu.c +index 4e5ce09..497529b 100644 +--- a/grub-core/loader/i386/xnu.c ++++ b/grub-core/loader/i386/xnu.c +@@ -125,9 +125,6 @@ guessfsb (void) + { + const grub_uint64_t sane_value = 100000000; + grub_uint32_t manufacturer[3], max_cpuid, capabilities, msrlow; +- grub_uint64_t start_tsc; +- grub_uint64_t end_tsc; +- grub_uint64_t tsc_ticks_per_ms; + + if (! grub_cpu_is_cpuid_supported ()) + return sane_value; +@@ -192,14 +189,6 @@ guessfsb (void) + if (! (capabilities & (1 << 7))) + return sane_value; + +- /* Calibrate the TSC rate. */ +- +- start_tsc = grub_get_tsc (); +- grub_pit_wait (0xffff); +- end_tsc = grub_get_tsc (); +- +- tsc_ticks_per_ms = grub_divmod64 (end_tsc - start_tsc, 55, 0); +- + /* Read the multiplier. */ + asm volatile ("movl $0x198, %%ecx\n" + "rdmsr" +@@ -207,8 +196,21 @@ guessfsb (void) + : + : "%ecx", "%eax"); + +- return grub_divmod64 (2000 * tsc_ticks_per_ms, +- ((msrlow >> 7) & 0x3e) + ((msrlow >> 14) & 1), 0); ++ grub_uint64_t v; ++ grub_uint32_t r; ++ ++ /* (2000ULL << 32) / grub_tsc_rate */ ++ /* Assumption: TSC frequency is over 2 MHz. */ ++ v = 0xffffffff / grub_tsc_rate; ++ v *= 2000; ++ /* v is at most 2000 off from (2000ULL << 32) / grub_tsc_rate. ++ Since grub_tsc_rate < 2^32/2^11=2^21, so no overflow. ++ */ ++ r = (2000ULL << 32) - v * grub_tsc_rate; ++ v += r / grub_tsc_rate; ++ ++ return grub_divmod64 (v, ((msrlow >> 7) & 0x3e) | ((msrlow >> 14) & 1), ++ 0); + } + + struct property_descriptor +diff --git a/include/grub/i386/pc/time.h b/include/grub/i386/pc/time.h +index ba227ca..e93320f 100644 +--- a/include/grub/i386/pc/time.h ++++ b/include/grub/i386/pc/time.h +@@ -21,9 +21,4 @@ + + #include + +-#define GRUB_TICKS_PER_SECOND 18 +- +-/* Return the real time in ticks. */ +-grub_uint32_t grub_get_rtc (void); +- + #endif /* ! KERNEL_MACHINE_TIME_HEADER */ +diff --git a/include/grub/i386/pit.h b/include/grub/i386/pit.h +index e1c92cd..4bd49d4 100644 +--- a/include/grub/i386/pit.h ++++ b/include/grub/i386/pit.h +@@ -100,6 +100,4 @@ enum + GRUB_PIT_CTRL_COUNT_BCD = 0x01 /* 4-decade BCD counter. */ + }; + +-void EXPORT_FUNC(grub_pit_wait) (grub_uint16_t tics); +- + #endif /* ! KERNEL_CPU_PIT_HEADER */ +diff --git a/include/grub/i386/tsc.h b/include/grub/i386/tsc.h +index 2442d7e..d25d0e3 100644 +--- a/include/grub/i386/tsc.h ++++ b/include/grub/i386/tsc.h +@@ -137,5 +137,7 @@ grub_cpu_is_tsc_supported (void) + + void grub_tsc_init (void); + grub_uint64_t grub_tsc_get_time_ms (void); ++/* In ms per 2^32 ticks. */ ++extern grub_uint32_t EXPORT_VAR(grub_tsc_rate); + + #endif /* ! KERNEL_CPU_TSC_HEADER */ +-- +1.8.1.4 + diff --git a/0201-grub-core-fs-hfs.c-grub_hfs_read_file-Avoid-divmod64.patch b/0201-grub-core-fs-hfs.c-grub_hfs_read_file-Avoid-divmod64.patch new file mode 100644 index 0000000..9ef8ea3 --- /dev/null +++ b/0201-grub-core-fs-hfs.c-grub_hfs_read_file-Avoid-divmod64.patch @@ -0,0 +1,81 @@ +From ee4b14ff422b784baa941c80613c79b8ab5140ea Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sun, 10 Mar 2013 18:27:53 +0100 +Subject: [PATCH 201/364] * grub-core/fs/hfs.c (grub_hfs_read_file): + Avoid divmod64 since the maximum size is 4G - 1 on hfs + +--- + ChangeLog | 5 +++++ + grub-core/fs/hfs.c | 15 ++++++++------- + 2 files changed, 13 insertions(+), 7 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index bc51ae9..931ae8e 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,10 @@ + 2013-03-10 Vladimir Serbinenko + ++ * grub-core/fs/hfs.c (grub_hfs_read_file): Avoid divmod64 since the ++ maximum size is 4G - 1 on hfs ++ ++2013-03-10 Vladimir Serbinenko ++ + Avoid costly 64-bit division in grub_get_time_ms on most platforms. + + 2013-03-10 Vladimir Serbinenko +diff --git a/grub-core/fs/hfs.c b/grub-core/fs/hfs.c +index 73ac7f9..14520c0 100644 +--- a/grub-core/fs/hfs.c ++++ b/grub-core/fs/hfs.c +@@ -244,15 +244,16 @@ grub_hfs_block (struct grub_hfs_data *data, grub_hfs_datarecord_t dat, + static grub_ssize_t + grub_hfs_read_file (struct grub_hfs_data *data, + grub_disk_read_hook_t read_hook, void *read_hook_data, +- grub_off_t pos, grub_size_t len, char *buf) ++ grub_uint32_t pos, grub_size_t len, char *buf) + { + grub_off_t i; + grub_off_t blockcnt; + +- blockcnt = grub_divmod64 (((len + pos) +- + data->blksz - 1), data->blksz, 0); ++ /* Files are at most 2G/4G - 1 bytes on hfs. Avoid 64-bit division. ++ Moreover len > 0 as checked in upper layer. */ ++ blockcnt = (len + pos - 1) / data->blksz + 1; + +- for (i = grub_divmod64 (pos, data->blksz, 0); i < blockcnt; i++) ++ for (i = pos / data->blksz; i < blockcnt; i++) + { + grub_disk_addr_t blknr; + grub_off_t blockoff; +@@ -260,7 +261,7 @@ grub_hfs_read_file (struct grub_hfs_data *data, + + int skipfirst = 0; + +- grub_divmod64 (pos, data->blksz, &blockoff); ++ blockoff = pos % data->blksz; + + blknr = grub_hfs_block (data, data->extents, data->fileid, i, 1); + if (grub_errno) +@@ -269,7 +270,7 @@ grub_hfs_read_file (struct grub_hfs_data *data, + /* Last block. */ + if (i == blockcnt - 1) + { +- grub_divmod64 ((len + pos), data->blksz, &blockend); ++ blockend = (len + pos) % data->blksz; + + /* The last portion is exactly EXT2_BLOCK_SIZE (data). */ + if (! blockend) +@@ -277,7 +278,7 @@ grub_hfs_read_file (struct grub_hfs_data *data, + } + + /* First block. */ +- if (i == grub_divmod64 (pos, data->blksz, 0)) ++ if (i == pos / data->blksz) + { + skipfirst = blockoff; + blockend -= skipfirst; +-- +1.8.1.4 + diff --git a/0202-Adjust-types-in-gdb-module-to-have-intended-unsigned.patch b/0202-Adjust-types-in-gdb-module-to-have-intended-unsigned.patch new file mode 100644 index 0000000..d7f307a --- /dev/null +++ b/0202-Adjust-types-in-gdb-module-to-have-intended-unsigned.patch @@ -0,0 +1,79 @@ +From 38ce1e9087067fa3fbb132d943b35d3a995408a5 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sun, 10 Mar 2013 18:36:39 +0100 +Subject: [PATCH 202/364] Adjust types in gdb module to have intended + unsigned shifts rather than signed divisions. + +--- + ChangeLog | 5 +++++ + grub-core/gdb/cstub.c | 4 ++-- + grub-core/gdb/i386/signal.c | 2 +- + include/grub/gdb.h | 2 +- + 4 files changed, 9 insertions(+), 4 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 931ae8e..51bc363 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,10 @@ + 2013-03-10 Vladimir Serbinenko + ++ Adjust types in gdb module to have intended unsigned shifts rather than ++ signed divisions. ++ ++2013-03-10 Vladimir Serbinenko ++ + * grub-core/fs/hfs.c (grub_hfs_read_file): Avoid divmod64 since the + maximum size is 4G - 1 on hfs + +diff --git a/grub-core/gdb/cstub.c b/grub-core/gdb/cstub.c +index a5c0c43..3c89c19 100644 +--- a/grub-core/gdb/cstub.c ++++ b/grub-core/gdb/cstub.c +@@ -204,7 +204,7 @@ grub_gdb_hex2int (char **ptr, grub_uint64_t *int_value) + void + grub_gdb_trap (int trap_no) + { +- int sig_no; ++ unsigned int sig_no; + int stepping; + grub_uint64_t addr; + grub_uint64_t length; +@@ -264,7 +264,7 @@ grub_gdb_trap (int trap_no) + case '?': + grub_gdb_outbuf[0] = 'S'; + grub_gdb_outbuf[1] = hexchars[sig_no >> 4]; +- grub_gdb_outbuf[2] = hexchars[sig_no % 16]; ++ grub_gdb_outbuf[2] = hexchars[sig_no & 0xf]; + grub_gdb_outbuf[3] = 0; + break; + +diff --git a/grub-core/gdb/i386/signal.c b/grub-core/gdb/i386/signal.c +index 23b7c35..1ac3bbd 100644 +--- a/grub-core/gdb/i386/signal.c ++++ b/grub-core/gdb/i386/signal.c +@@ -24,7 +24,7 @@ + + /* Converting CPU trap number to UNIX signal number as + described in System V ABI i386 Processor Supplement, 3-25. */ +-int ++unsigned int + grub_gdb_trap2sig (int trap_no) + { + const int signals[] = { +diff --git a/include/grub/gdb.h b/include/grub/gdb.h +index 59fd456..e73d135 100644 +--- a/include/grub/gdb.h ++++ b/include/grub/gdb.h +@@ -33,7 +33,7 @@ struct grub_serial_port; + extern struct grub_serial_port *grub_gdb_port; + + void grub_gdb_breakpoint (void); +-int grub_gdb_trap2sig (int); ++unsigned int grub_gdb_trap2sig (int); + + #endif /* ! GRUB_GDB_HEADER */ + +-- +1.8.1.4 + diff --git a/0203-grub-core-video-i386-pc-vbe.c.patch b/0203-grub-core-video-i386-pc-vbe.c.patch new file mode 100644 index 0000000..9ddb23a --- /dev/null +++ b/0203-grub-core-video-i386-pc-vbe.c.patch @@ -0,0 +1,44 @@ +From ed1dd57ff45a059bc3f54c96ac9e41bbc002186f Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sun, 10 Mar 2013 18:49:05 +0100 +Subject: [PATCH 203/364] * grub-core/video/i386/pc/vbe.c + (grub_video_vbe_print_adapter_specific_info): Replace division by + shifts. + +--- + ChangeLog | 6 ++++++ + grub-core/video/i386/pc/vbe.c | 2 +- + 2 files changed, 7 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index 51bc363..48ca30e 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,11 @@ + 2013-03-10 Vladimir Serbinenko + ++ * grub-core/video/i386/pc/vbe.c ++ (grub_video_vbe_print_adapter_specific_info): Replace division by ++ shifts. ++ ++2013-03-10 Vladimir Serbinenko ++ + Adjust types in gdb module to have intended unsigned shifts rather than + signed divisions. + +diff --git a/grub-core/video/i386/pc/vbe.c b/grub-core/video/i386/pc/vbe.c +index e8a8c7a..f112f15 100644 +--- a/grub-core/video/i386/pc/vbe.c ++++ b/grub-core/video/i386/pc/vbe.c +@@ -1197,7 +1197,7 @@ grub_video_vbe_print_adapter_specific_info (void) + + /* The total_memory field is in 64 KiB units. */ + grub_printf_ (N_(" total memory: %d KiB\n"), +- (controller_info.total_memory << 16) / 1024); ++ (controller_info.total_memory << 6)); + } + + static struct grub_video_adapter grub_video_vbe_adapter = +-- +1.8.1.4 + diff --git a/0204-include-grub-datetime.h-grub_datetime2unixtime-Fix-u.patch b/0204-include-grub-datetime.h-grub_datetime2unixtime-Fix-u.patch new file mode 100644 index 0000000..a1d8351 --- /dev/null +++ b/0204-include-grub-datetime.h-grub_datetime2unixtime-Fix-u.patch @@ -0,0 +1,46 @@ +From 8aaee3ccd69f2eb821116c0496b734641fb69b05 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sun, 10 Mar 2013 19:19:21 +0100 +Subject: [PATCH 204/364] * include/grub/datetime.h + (grub_datetime2unixtime): Fix unixtime computation for some years + before epoch. Avode confusing division while on it. + +--- + ChangeLog | 6 ++++++ + include/grub/datetime.h | 4 +--- + 2 files changed, 7 insertions(+), 3 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 48ca30e..8814c22 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,11 @@ + 2013-03-10 Vladimir Serbinenko + ++ * include/grub/datetime.h (grub_datetime2unixtime): Fix unixtime ++ computation for some years before epoch. Avode confusing division ++ while on it. ++ ++2013-03-10 Vladimir Serbinenko ++ + * grub-core/video/i386/pc/vbe.c + (grub_video_vbe_print_adapter_specific_info): Replace division by + shifts. +diff --git a/include/grub/datetime.h b/include/grub/datetime.h +index 3a3b3d0..fef2814 100644 +--- a/include/grub/datetime.h ++++ b/include/grub/datetime.h +@@ -89,9 +89,7 @@ grub_datetime2unixtime (const struct grub_datetime *datetime, grub_int32_t *nix) + ret = 3 * SECPERYEAR + SECPERDAY; + + /* Transform C divisions and modulos to mathematical ones */ +- y4 = (datetime->year - 1973) / 4; +- if (datetime->year < 1973) +- y4--; ++ y4 = ((datetime->year - 1) >> 2) - (1973 / 4); + ay = datetime->year - 1973 - 4 * y4; + ret += y4 * SECPER4YEARS; + ret += ay * SECPERYEAR; +-- +1.8.1.4 + diff --git a/0205-grub-core-loader-i386-pc-plan9.c-fill_disk-Fix-types.patch b/0205-grub-core-loader-i386-pc-plan9.c-fill_disk-Fix-types.patch new file mode 100644 index 0000000..37effe8 --- /dev/null +++ b/0205-grub-core-loader-i386-pc-plan9.c-fill_disk-Fix-types.patch @@ -0,0 +1,51 @@ +From 17a6553c2d4bbe04e9063dac50637262af4aeac1 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sun, 10 Mar 2013 19:27:50 +0100 +Subject: [PATCH 205/364] * grub-core/loader/i386/pc/plan9.c + (fill_disk): Fix types to use intended shifts rather than division. + +--- + ChangeLog | 5 +++++ + grub-core/loader/i386/pc/plan9.c | 4 ++-- + 2 files changed, 7 insertions(+), 2 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 8814c22..334f81d 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,10 @@ + 2013-03-10 Vladimir Serbinenko + ++ * grub-core/loader/i386/pc/plan9.c (fill_disk): Fix types to use ++ intended shifts rather than division. ++ ++2013-03-10 Vladimir Serbinenko ++ + * include/grub/datetime.h (grub_datetime2unixtime): Fix unixtime + computation for some years before epoch. Avode confusing division + while on it. +diff --git a/grub-core/loader/i386/pc/plan9.c b/grub-core/loader/i386/pc/plan9.c +index 7dc12a8..1c7b381 100644 +--- a/grub-core/loader/i386/pc/plan9.c ++++ b/grub-core/loader/i386/pc/plan9.c +@@ -292,7 +292,7 @@ fill_disk (const char *name, void *data) + + case GRUB_DISK_DEVICE_ATA_ID: + { +- int unit; ++ unsigned unit; + if (grub_strlen (dev->disk->name) < sizeof ("ata0") - 1) + unit = 0; + else +@@ -304,7 +304,7 @@ fill_disk (const char *name, void *data) + if (((dev->disk->id >> GRUB_SCSI_ID_SUBSYSTEM_SHIFT) & 0xff) + == GRUB_SCSI_SUBSYSTEM_PATA) + { +- int unit; ++ unsigned unit; + if (grub_strlen (dev->disk->name) < sizeof ("ata0") - 1) + unit = 0; + else +-- +1.8.1.4 + diff --git a/0206-grub-core-commands-verify.c-grub_verify_signature-Us.patch b/0206-grub-core-commands-verify.c-grub_verify_signature-Us.patch new file mode 100644 index 0000000..75d97ea --- /dev/null +++ b/0206-grub-core-commands-verify.c-grub_verify_signature-Us.patch @@ -0,0 +1,51 @@ +From 2f505c89522520243b7164a744953afa6dc8691d Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sun, 10 Mar 2013 19:39:14 +0100 +Subject: [PATCH 206/364] * grub-core/commands/verify.c + (grub_verify_signature): Use unsigned operations to have intended shifts and + not divisions. + +--- + ChangeLog | 5 +++++ + grub-core/commands/verify.c | 9 ++++++--- + 2 files changed, 11 insertions(+), 3 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 334f81d..c2821c9 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,10 @@ + 2013-03-10 Vladimir Serbinenko + ++ * grub-core/commands/verify.c (grub_verify_signature): Use unsigned ++ operations to have intended shifts and not divisions. ++ ++2013-03-10 Vladimir Serbinenko ++ + * grub-core/loader/i386/pc/plan9.c (fill_disk): Fix types to use + intended shifts rather than division. + +diff --git a/grub-core/commands/verify.c b/grub-core/commands/verify.c +index d399d0f..38bb941 100644 +--- a/grub-core/commands/verify.c ++++ b/grub-core/commands/verify.c +@@ -510,10 +510,13 @@ grub_verify_signature (grub_file_t f, grub_file_t sig, + /* TRANSLATORS: %08x is 32-bit key id. */ + return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("public key %08x not found"), keyid); + +- int nbits = gcry_mpi_get_nbits (sk->mpis[1]); +- grub_dprintf ("crypt", "must be %d bits got %d bits\n", (int)nbits, (int)(8 * hash->mdlen)); ++ unsigned nbits = gcry_mpi_get_nbits (sk->mpis[1]); ++ grub_dprintf ("crypt", "must be %u bits got %d bits\n", nbits, ++ (int)(8 * hash->mdlen)); + +- if (gcry_mpi_scan (&hmpi, GCRYMPI_FMT_USG, hval, nbits / 8 < (int) hash->mdlen ? nbits / 8 : (int) hash->mdlen, 0)) ++ if (gcry_mpi_scan (&hmpi, GCRYMPI_FMT_USG, hval, ++ nbits / 8 < (unsigned) hash->mdlen ? nbits / 8 ++ : (unsigned) hash->mdlen, 0)) + return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); + if (!grub_crypto_pk_dsa) + return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("module `%s' isn't loaded"), "gcry_dsa"); +-- +1.8.1.4 + diff --git a/0207-grub-core-lib-arg.c-grub_arg_list_alloc-Use-shifts-r.patch b/0207-grub-core-lib-arg.c-grub_arg_list_alloc-Use-shifts-r.patch new file mode 100644 index 0000000..b501f4d --- /dev/null +++ b/0207-grub-core-lib-arg.c-grub_arg_list_alloc-Use-shifts-r.patch @@ -0,0 +1,60 @@ +From f57dd7a0c54ee35789d8cb44989622c269342db7 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sun, 10 Mar 2013 20:08:15 +0100 +Subject: [PATCH 207/364] * grub-core/lib/arg.c (grub_arg_list_alloc): + Use shifts rather than divisions. + +--- + ChangeLog | 5 +++++ + grub-core/lib/arg.c | 6 +++--- + 2 files changed, 8 insertions(+), 3 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index c2821c9..8f8de8b 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,10 @@ + 2013-03-10 Vladimir Serbinenko + ++ * grub-core/lib/arg.c (grub_arg_list_alloc): Use shifts rather ++ than divisions. ++ ++2013-03-10 Vladimir Serbinenko ++ + * grub-core/commands/verify.c (grub_verify_signature): Use unsigned + operations to have intended shifts and not divisions. + +diff --git a/grub-core/lib/arg.c b/grub-core/lib/arg.c +index da44e30..7492ac6 100644 +--- a/grub-core/lib/arg.c ++++ b/grub-core/lib/arg.c +@@ -428,7 +428,7 @@ grub_arg_list_alloc(grub_extcmd_t extcmd, int argc, + { + int i; + char **args; +- unsigned argcnt; ++ grub_size_t argcnt; + struct grub_arg_list *list; + const struct grub_arg_option *options; + +@@ -440,7 +440,7 @@ grub_arg_list_alloc(grub_extcmd_t extcmd, int argc, + for (i = 0; options[i].doc; i++) + { + if (options[i].flags & GRUB_ARG_OPTION_REPEATABLE) +- argcnt += (argc + 1) / 2 + 1; /* max possible for any option */ ++ argcnt += ((grub_size_t) argc + 1) / 2 + 1; /* max possible for any option */ + } + + list = grub_zalloc (sizeof (*list) * i + sizeof (char*) * argcnt); +@@ -456,7 +456,7 @@ grub_arg_list_alloc(grub_extcmd_t extcmd, int argc, + if (options[i].flags & GRUB_ARG_OPTION_REPEATABLE) + { + list[i].args = args; +- args += argc / 2 + 1; ++ args += (grub_size_t) argc / 2 + 1; + } + } + return list; +-- +1.8.1.4 + diff --git a/0208-grub-core-loader-i386-bsdXX.c-grub_openbsd_find_ramd.patch b/0208-grub-core-loader-i386-bsdXX.c-grub_openbsd_find_ramd.patch new file mode 100644 index 0000000..87fcd01 --- /dev/null +++ b/0208-grub-core-loader-i386-bsdXX.c-grub_openbsd_find_ramd.patch @@ -0,0 +1,42 @@ +From a3b87da49162a9c439bf464d0f45a0f48912bff9 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sun, 10 Mar 2013 20:37:41 +0100 +Subject: [PATCH 208/364] * grub-core/loader/i386/bsdXX.c + (grub_openbsd_find_ramdisk): Use multiplication rather than division. + +--- + ChangeLog | 5 +++++ + grub-core/loader/i386/bsdXX.c | 2 +- + 2 files changed, 6 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index 8f8de8b..4f5a281 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,10 @@ + 2013-03-10 Vladimir Serbinenko + ++ * grub-core/loader/i386/bsdXX.c (grub_openbsd_find_ramdisk): Use ++ multiplication rather than division. ++ ++2013-03-10 Vladimir Serbinenko ++ + * grub-core/lib/arg.c (grub_arg_list_alloc): Use shifts rather + than divisions. + +diff --git a/grub-core/loader/i386/bsdXX.c b/grub-core/loader/i386/bsdXX.c +index 3f9f093..9e36cd4 100644 +--- a/grub-core/loader/i386/bsdXX.c ++++ b/grub-core/loader/i386/bsdXX.c +@@ -594,7 +594,7 @@ SUFFIX(grub_openbsd_find_ramdisk) (grub_file_t file, + return grub_errno; + } + +- for (i = 0, sym = syms; i < symsize / symentsize; ++ for (i = 0, sym = syms; i * symentsize < symsize; + i++, sym = (Elf_Sym *) ((char *) sym + symentsize)) + { + if (ELF_ST_TYPE (sym->st_info) != STT_OBJECT) +-- +1.8.1.4 + diff --git a/0209-Resend-a-packet-if-we-got-the-wrong-buffer-in-status.patch b/0209-Resend-a-packet-if-we-got-the-wrong-buffer-in-status.patch new file mode 100644 index 0000000..751a4ca --- /dev/null +++ b/0209-Resend-a-packet-if-we-got-the-wrong-buffer-in-status.patch @@ -0,0 +1,84 @@ +From a9a4ba2857cae31eac34febe2d08e9d6849b119e Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sun, 17 Mar 2013 13:33:16 +0100 +Subject: [PATCH 209/364] Resend a packet if we got the wrong buffer in + status. + +--- + ChangeLog | 4 ++++ + grub-core/net/drivers/efi/efinet.c | 22 +++++++++++++++------- + include/grub/net.h | 1 + + 3 files changed, 20 insertions(+), 7 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 4f5a281..ad84d27 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,7 @@ ++2013-03-17 Vladimir Serbinenko ++ ++ Resend a packet if we got the wrong buffer in status. ++ + 2013-03-10 Vladimir Serbinenko + + * grub-core/loader/i386/bsdXX.c (grub_openbsd_find_ramdisk): Use +diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c +index 28f2db2..2b344d6 100644 +--- a/grub-core/net/drivers/efi/efinet.c ++++ b/grub-core/net/drivers/efi/efinet.c +@@ -37,7 +37,6 @@ send_card_buffer (struct grub_net_card *dev, + grub_efi_status_t st; + grub_efi_simple_network_t *net = dev->efi_net; + grub_uint64_t limit_time = grub_get_time_ms () + 4000; +- grub_size_t len; + + if (dev->txbusy) + while (1) +@@ -52,17 +51,26 @@ send_card_buffer (struct grub_net_card *dev, + dev->txbusy = 0; + break; + } ++ if (txbuf) ++ { ++ st = efi_call_7 (net->transmit, net, 0, dev->last_pkt_size, ++ dev->txbuf, NULL, NULL, NULL); ++ if (st != GRUB_EFI_SUCCESS) ++ return grub_error (GRUB_ERR_IO, ++ N_("couldn't send network packet")); ++ } + if (limit_time < grub_get_time_ms ()) +- return grub_error (GRUB_ERR_TIMEOUT, N_("couldn't send network packet")); ++ return grub_error (GRUB_ERR_TIMEOUT, ++ N_("couldn't send network packet")); + } + +- len = (pack->tail - pack->data); +- if (len > dev->mtu) +- len = dev->mtu; ++ dev->last_pkt_size = (pack->tail - pack->data); ++ if (dev->last_pkt_size > dev->mtu) ++ dev->last_pkt_size = dev->mtu; + +- grub_memcpy (dev->txbuf, pack->data, len); ++ grub_memcpy (dev->txbuf, pack->data, dev->last_pkt_size); + +- st = efi_call_7 (net->transmit, net, 0, len, ++ st = efi_call_7 (net->transmit, net, 0, dev->last_pkt_size, + dev->txbuf, NULL, NULL, NULL); + if (st != GRUB_EFI_SUCCESS) + return grub_error (GRUB_ERR_IO, N_("couldn't send network packet")); +diff --git a/include/grub/net.h b/include/grub/net.h +index 3877451..1bd7af2 100644 +--- a/include/grub/net.h ++++ b/include/grub/net.h +@@ -139,6 +139,7 @@ struct grub_net_card + { + struct grub_efi_simple_network *efi_net; + grub_efi_handle_t efi_handle; ++ grub_size_t last_pkt_size; + }; + #endif + void *data; +-- +1.8.1.4 + diff --git a/0210-Better-estimate-the-maximum-USB-transfer-size.patch b/0210-Better-estimate-the-maximum-USB-transfer-size.patch new file mode 100644 index 0000000..05470a6 --- /dev/null +++ b/0210-Better-estimate-the-maximum-USB-transfer-size.patch @@ -0,0 +1,237 @@ +From 880bee5493e9515001f87355f54af34df64c90f4 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Tue, 19 Mar 2013 08:17:51 +0100 +Subject: [PATCH 210/364] Better estimate the maximum USB transfer size. + +--- + ChangeLog | 4 ++ + grub-core/bus/usb/ehci.c | 4 +- + grub-core/bus/usb/ohci.c | 4 +- + grub-core/bus/usb/uhci.c | 4 +- + grub-core/bus/usb/usbtrans.c | 96 +++++++++++++++++++++++++++----------------- + include/grub/usb.h | 7 ++++ + 6 files changed, 80 insertions(+), 39 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index ad84d27..d331cb4 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,7 @@ ++2013-03-19 Aleš Nesrsta ++ ++ Better estimate the maximum USB transfer size. ++ + 2013-03-17 Vladimir Serbinenko + + Resend a packet if we got the wrong buffer in status. +diff --git a/grub-core/bus/usb/ehci.c b/grub-core/bus/usb/ehci.c +index 9215866..c60873d 100644 +--- a/grub-core/bus/usb/ehci.c ++++ b/grub-core/bus/usb/ehci.c +@@ -1902,7 +1902,9 @@ static struct grub_usb_controller_dev usb_controller = { + .cancel_transfer = grub_ehci_cancel_transfer, + .hubports = grub_ehci_hubports, + .portstatus = grub_ehci_portstatus, +- .detect_dev = grub_ehci_detect_dev ++ .detect_dev = grub_ehci_detect_dev, ++ /* estimated max. count of TDs for one bulk transfer */ ++ .max_bulk_tds = GRUB_EHCI_N_TD * 3 / 4 + }; + + GRUB_MOD_INIT (ehci) +diff --git a/grub-core/bus/usb/ohci.c b/grub-core/bus/usb/ohci.c +index 835bb15..2f3fd91 100644 +--- a/grub-core/bus/usb/ohci.c ++++ b/grub-core/bus/usb/ohci.c +@@ -1431,7 +1431,9 @@ static struct grub_usb_controller_dev usb_controller = + .cancel_transfer = grub_ohci_cancel_transfer, + .hubports = grub_ohci_hubports, + .portstatus = grub_ohci_portstatus, +- .detect_dev = grub_ohci_detect_dev ++ .detect_dev = grub_ohci_detect_dev, ++ /* estimated max. count of TDs for one bulk transfer */ ++ .max_bulk_tds = GRUB_OHCI_TDS * 3 / 4 + }; + + static struct grub_preboot *fini_hnd; +diff --git a/grub-core/bus/usb/uhci.c b/grub-core/bus/usb/uhci.c +index 74de392..3639c42 100644 +--- a/grub-core/bus/usb/uhci.c ++++ b/grub-core/bus/usb/uhci.c +@@ -823,7 +823,9 @@ static struct grub_usb_controller_dev usb_controller = + .cancel_transfer = grub_uhci_cancel_transfer, + .hubports = grub_uhci_hubports, + .portstatus = grub_uhci_portstatus, +- .detect_dev = grub_uhci_detect_dev ++ .detect_dev = grub_uhci_detect_dev, ++ /* estimated max. count of TDs for one bulk transfer */ ++ .max_bulk_tds = N_TD * 3 / 4 + }; + + GRUB_MOD_INIT(uhci) +diff --git a/grub-core/bus/usb/usbtrans.c b/grub-core/bus/usb/usbtrans.c +index 154c72d..4c4d8b4 100644 +--- a/grub-core/bus/usb/usbtrans.c ++++ b/grub-core/bus/usb/usbtrans.c +@@ -25,6 +25,26 @@ + #include + #include + ++ ++static inline unsigned int ++grub_usb_bulk_maxpacket (grub_usb_device_t dev, int endpoint) ++{ ++ unsigned int max = 64; ++ ++ /* Use the maximum packet size given in the endpoint descriptor. */ ++ if (dev->initialized) ++ { ++ struct grub_usb_desc_endp *endpdesc; ++ endpdesc = grub_usb_get_endpdescriptor (dev, endpoint); ++ ++ if (endpdesc) ++ max = endpdesc->maxpacket; ++ } ++ ++ return max; ++} ++ ++ + static grub_usb_err_t + grub_usb_execute_and_wait_transfer (grub_usb_device_t dev, + grub_usb_transfer_t transfer, +@@ -224,20 +244,6 @@ grub_usb_bulk_setup_readwrite (grub_usb_device_t dev, + 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) +- { +- struct grub_usb_desc_endp *endpdesc; +- endpdesc = grub_usb_get_endpdescriptor (dev, endpoint); +- +- if (endpdesc) +- max = endpdesc->maxpacket; +- else +- max = 64; +- } +- else +- max = 64; +- + /* Create a transfer. */ + transfer = grub_malloc (sizeof (struct grub_usb_transfer)); + if (! transfer) +@@ -246,6 +252,8 @@ grub_usb_bulk_setup_readwrite (grub_usb_device_t dev, + return NULL; + } + ++ max = grub_usb_bulk_maxpacket (dev, endpoint); ++ + datablocks = ((size + max - 1) / max); + transfer->transcnt = datablocks; + transfer->size = size - 1; +@@ -333,38 +341,36 @@ grub_usb_bulk_readwrite (grub_usb_device_t dev, + return err; + } + +-grub_usb_err_t +-grub_usb_bulk_write (grub_usb_device_t dev, +- int endpoint, grub_size_t size, char *data) +-{ +- grub_size_t actual; +- grub_usb_err_t err; +- +- err = grub_usb_bulk_readwrite (dev, endpoint, size, data, +- GRUB_USB_TRANSFER_TYPE_OUT, 1000, &actual); +- if (!err && actual != size) +- err = GRUB_USB_ERR_DATA; +- return err; +-} +- +-grub_usb_err_t +-grub_usb_bulk_read (grub_usb_device_t dev, +- int endpoint, grub_size_t size, char *data) ++static grub_usb_err_t ++grub_usb_bulk_readwrite_packetize (grub_usb_device_t dev, ++ int endpoint, ++ grub_transfer_type_t type, ++ grub_size_t size, char *data) + { + grub_size_t actual, transferred; + grub_usb_err_t err; + grub_size_t current_size, position; ++ grub_size_t max_bulk_transfer_len = MAX_USB_TRANSFER_LEN; ++ grub_size_t max; ++ ++ if (dev->controller.dev->max_bulk_tds) ++ { ++ max = grub_usb_bulk_maxpacket (dev, endpoint); ++ ++ /* Calculate max. possible length of bulk transfer */ ++ max_bulk_transfer_len = dev->controller.dev->max_bulk_tds * max; ++ } + + for (position = 0, transferred = 0; +- position < size; position += MAX_USB_TRANSFER_LEN) ++ position < size; position += max_bulk_transfer_len) + { + current_size = size - position; +- if (current_size >= MAX_USB_TRANSFER_LEN) +- current_size = MAX_USB_TRANSFER_LEN; ++ if (current_size >= max_bulk_transfer_len) ++ current_size = max_bulk_transfer_len; + err = grub_usb_bulk_readwrite (dev, endpoint, current_size, +- &data[position], GRUB_USB_TRANSFER_TYPE_IN, 1000, &actual); ++ &data[position], type, 1000, &actual); + transferred += actual; +- if (err || (current_size != actual) ) break; ++ if (err || (current_size != actual)) break; + } + + if (!err && transferred != size) +@@ -373,6 +379,24 @@ grub_usb_bulk_read (grub_usb_device_t dev, + } + + grub_usb_err_t ++grub_usb_bulk_write (grub_usb_device_t dev, ++ int endpoint, grub_size_t size, char *data) ++{ ++ return grub_usb_bulk_readwrite_packetize (dev, endpoint, ++ GRUB_USB_TRANSFER_TYPE_OUT, ++ size, data); ++} ++ ++grub_usb_err_t ++grub_usb_bulk_read (grub_usb_device_t dev, ++ int endpoint, grub_size_t size, char *data) ++{ ++ return grub_usb_bulk_readwrite_packetize (dev, endpoint, ++ GRUB_USB_TRANSFER_TYPE_IN, ++ size, data); ++} ++ ++grub_usb_err_t + grub_usb_check_transfer (grub_usb_transfer_t transfer, grub_size_t *actual) + { + grub_usb_err_t err; +diff --git a/include/grub/usb.h b/include/grub/usb.h +index cefa8b6..55f65f7 100644 +--- a/include/grub/usb.h ++++ b/include/grub/usb.h +@@ -124,6 +124,13 @@ struct grub_usb_controller_dev + + /* Per controller flag - port reset pending, don't do another reset */ + grub_uint64_t pending_reset; ++ ++ /* Max. number of transfer descriptors used per one bulk transfer */ ++ /* The reason is to prevent "exhausting" of TD by large bulk */ ++ /* transfer - number of TD is limited in USB host driver */ ++ /* Value is calculated/estimated in driver - some TDs should be */ ++ /* reserved for posible concurrent control or "interrupt" transfers */ ++ grub_size_t max_bulk_tds; + + /* The next host controller. */ + struct grub_usb_controller_dev *next; +-- +1.8.1.4 + diff --git a/0211-remove-get_endpoint_descriptor-and-change-all-functi.patch b/0211-remove-get_endpoint_descriptor-and-change-all-functi.patch new file mode 100644 index 0000000..29725c5 --- /dev/null +++ b/0211-remove-get_endpoint_descriptor-and-change-all-functi.patch @@ -0,0 +1,415 @@ +From 944030c773c6dc4500d5ccf7762705b3fb1494e1 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Tue, 19 Mar 2013 11:19:36 +0100 +Subject: [PATCH 211/364] remove get_endpoint_descriptor and change all + functions needing descriptor to just receive it as argument rather than + endpoint address. + +--- + ChangeLog | 6 +++++ + grub-core/bus/usb/serial/common.c | 2 +- + grub-core/bus/usb/serial/ftdi.c | 2 +- + grub-core/bus/usb/serial/pl2303.c | 2 +- + grub-core/bus/usb/serial/usbdebug_late.c | 2 +- + grub-core/bus/usb/usb.c | 25 ------------------- + grub-core/bus/usb/usbhub.c | 4 ++-- + grub-core/bus/usb/usbtrans.c | 41 ++++++++++++++++---------------- + grub-core/disk/usbms.c | 18 +++++++------- + grub-core/term/usb_keyboard.c | 4 ++-- + include/grub/usb.h | 15 ++++++------ + 11 files changed, 51 insertions(+), 70 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index d331cb4..a544fbf 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,9 @@ ++2013-03-19 Vladimir Serbinenko ++ ++ remove get_endpoint_descriptor and change all functions needing ++ descriptor to just receive it as argument rather than endpoint ++ address. ++ + 2013-03-19 Aleš Nesrsta + + Better estimate the maximum USB transfer size. +diff --git a/grub-core/bus/usb/serial/common.c b/grub-core/bus/usb/serial/common.c +index 06f2b0e..8e94c7d 100644 +--- a/grub-core/bus/usb/serial/common.c ++++ b/grub-core/bus/usb/serial/common.c +@@ -124,7 +124,7 @@ grub_usbserial_fetch (struct grub_serial_port *port, grub_size_t header_size) + if (port->bufstart < port->bufend) + return port->buf[port->bufstart++]; + +- err = grub_usb_bulk_read_extended (port->usbdev, port->in_endp->endp_addr, ++ err = grub_usb_bulk_read_extended (port->usbdev, port->in_endp, + sizeof (port->buf), port->buf, 10, + &actual); + if (err != GRUB_USB_ERR_NONE) +diff --git a/grub-core/bus/usb/serial/ftdi.c b/grub-core/bus/usb/serial/ftdi.c +index e94fd27..25c1d6f 100644 +--- a/grub-core/bus/usb/serial/ftdi.c ++++ b/grub-core/bus/usb/serial/ftdi.c +@@ -128,7 +128,7 @@ ftdi_hw_put (struct grub_serial_port *port, const int c) + + real_config (port); + +- grub_usb_bulk_write (port->usbdev, port->out_endp->endp_addr, 1, &cc); ++ grub_usb_bulk_write (port->usbdev, port->out_endp, 1, &cc); + } + + static grub_err_t +diff --git a/grub-core/bus/usb/serial/pl2303.c b/grub-core/bus/usb/serial/pl2303.c +index f46c6ac..92b00ef 100644 +--- a/grub-core/bus/usb/serial/pl2303.c ++++ b/grub-core/bus/usb/serial/pl2303.c +@@ -146,7 +146,7 @@ pl2303_hw_put (struct grub_serial_port *port, const int c) + + real_config (port); + +- grub_usb_bulk_write (port->usbdev, port->out_endp->endp_addr, 1, &cc); ++ grub_usb_bulk_write (port->usbdev, port->out_endp, 1, &cc); + } + + static grub_err_t +diff --git a/grub-core/bus/usb/serial/usbdebug_late.c b/grub-core/bus/usb/serial/usbdebug_late.c +index 23526e1..e88ba13 100644 +--- a/grub-core/bus/usb/serial/usbdebug_late.c ++++ b/grub-core/bus/usb/serial/usbdebug_late.c +@@ -41,7 +41,7 @@ usbdebug_late_hw_put (struct grub_serial_port *port, const int c) + { + char cc = c; + +- grub_usb_bulk_write (port->usbdev, port->out_endp->endp_addr, 1, &cc); ++ grub_usb_bulk_write (port->usbdev, port->out_endp, 1, &cc); + } + + static grub_err_t +diff --git a/grub-core/bus/usb/usb.c b/grub-core/bus/usb/usb.c +index 41d8010..7a517f8 100644 +--- a/grub-core/bus/usb/usb.c ++++ b/grub-core/bus/usb/usb.c +@@ -147,31 +147,6 @@ grub_usb_get_descriptor (grub_usb_device_t dev, + 0, size, data); + } + +-struct grub_usb_desc_endp * +-grub_usb_get_endpdescriptor (grub_usb_device_t usbdev, int addr) +-{ +- int i; +- +- for (i = 0; i < usbdev->config[0].descconf->numif; i++) +- { +- struct grub_usb_desc_if *interf; +- int j; +- +- interf = usbdev->config[0].interf[i].descif; +- +- for (j = 0; j < interf->endpointcnt; j++) +- { +- struct grub_usb_desc_endp *endp; +- endp = &usbdev->config[0].interf[i].descendp[j]; +- +- if (endp->endp_addr == addr) +- return endp; +- } +- } +- +- return NULL; +-} +- + grub_usb_err_t + grub_usb_device_initialize (grub_usb_device_t dev) + { +diff --git a/grub-core/bus/usb/usbhub.c b/grub-core/bus/usb/usbhub.c +index 3927f51..7e7dc8c 100644 +--- a/grub-core/bus/usb/usbhub.c ++++ b/grub-core/bus/usb/usbhub.c +@@ -173,7 +173,7 @@ grub_usb_add_hub (grub_usb_device_t dev) + if (len > sizeof (dev->statuschange)) + len = sizeof (dev->statuschange); + dev->hub_transfer +- = grub_usb_bulk_read_background (dev, endp->endp_addr, len, ++ = grub_usb_bulk_read_background (dev, endp, len, + (char *) &dev->statuschange); + break; + } +@@ -342,7 +342,7 @@ poll_nonroot_hub (grub_usb_device_t dev) + if (len > sizeof (dev->statuschange)) + len = sizeof (dev->statuschange); + dev->hub_transfer +- = grub_usb_bulk_read_background (dev, dev->hub_endpoint->endp_addr, len, ++ = grub_usb_bulk_read_background (dev, dev->hub_endpoint, len, + (char *) &dev->statuschange); + + if (err || actual == 0 || changed == 0) +diff --git a/grub-core/bus/usb/usbtrans.c b/grub-core/bus/usb/usbtrans.c +index 4c4d8b4..533c3e7 100644 +--- a/grub-core/bus/usb/usbtrans.c ++++ b/grub-core/bus/usb/usbtrans.c +@@ -27,21 +27,14 @@ + + + static inline unsigned int +-grub_usb_bulk_maxpacket (grub_usb_device_t dev, int endpoint) ++grub_usb_bulk_maxpacket (grub_usb_device_t dev, ++ struct grub_usb_desc_endp *endpoint) + { +- unsigned int max = 64; +- + /* Use the maximum packet size given in the endpoint descriptor. */ +- if (dev->initialized) +- { +- struct grub_usb_desc_endp *endpdesc; +- endpdesc = grub_usb_get_endpdescriptor (dev, endpoint); +- +- if (endpdesc) +- max = endpdesc->maxpacket; +- } ++ if (dev->initialized && endpoint) ++ return endpoint->maxpacket; + +- return max; ++ return 64; + } + + +@@ -219,7 +212,8 @@ grub_usb_control_msg (grub_usb_device_t dev, + + static grub_usb_transfer_t + grub_usb_bulk_setup_readwrite (grub_usb_device_t dev, +- int endpoint, grub_size_t size0, char *data_in, ++ struct grub_usb_desc_endp *endpoint, ++ grub_size_t size0, char *data_in, + grub_transfer_type_t type) + { + int i; +@@ -230,7 +224,7 @@ grub_usb_bulk_setup_readwrite (grub_usb_device_t dev, + grub_uint32_t data_addr; + struct grub_pci_dma_chunk *data_chunk; + grub_size_t size = size0; +- int toggle = dev->toggle[endpoint]; ++ int toggle = dev->toggle[endpoint->endp_addr]; + + grub_dprintf ("usb", "bulk: size=0x%02lx type=%d\n", (unsigned long) size, + type); +@@ -257,7 +251,7 @@ grub_usb_bulk_setup_readwrite (grub_usb_device_t dev, + datablocks = ((size + max - 1) / max); + transfer->transcnt = datablocks; + transfer->size = size - 1; +- transfer->endpoint = endpoint; ++ transfer->endpoint = endpoint->endp_addr; + transfer->devaddr = dev->addr; + transfer->type = GRUB_USB_TRANSACTION_TYPE_BULK; + transfer->dir = type; +@@ -323,7 +317,8 @@ grub_usb_bulk_finish_readwrite (grub_usb_transfer_t transfer) + + static grub_usb_err_t + grub_usb_bulk_readwrite (grub_usb_device_t dev, +- int endpoint, grub_size_t size0, char *data_in, ++ struct grub_usb_desc_endp *endpoint, ++ grub_size_t size0, char *data_in, + grub_transfer_type_t type, int timeout, + grub_size_t *actual) + { +@@ -343,7 +338,7 @@ grub_usb_bulk_readwrite (grub_usb_device_t dev, + + static grub_usb_err_t + grub_usb_bulk_readwrite_packetize (grub_usb_device_t dev, +- int endpoint, ++ struct grub_usb_desc_endp *endpoint, + grub_transfer_type_t type, + grub_size_t size, char *data) + { +@@ -380,7 +375,8 @@ grub_usb_bulk_readwrite_packetize (grub_usb_device_t dev, + + grub_usb_err_t + grub_usb_bulk_write (grub_usb_device_t dev, +- int endpoint, grub_size_t size, char *data) ++ struct grub_usb_desc_endp *endpoint, ++ grub_size_t size, char *data) + { + return grub_usb_bulk_readwrite_packetize (dev, endpoint, + GRUB_USB_TRANSFER_TYPE_OUT, +@@ -389,7 +385,8 @@ grub_usb_bulk_write (grub_usb_device_t dev, + + grub_usb_err_t + grub_usb_bulk_read (grub_usb_device_t dev, +- int endpoint, grub_size_t size, char *data) ++ struct grub_usb_desc_endp *endpoint, ++ grub_size_t size, char *data) + { + return grub_usb_bulk_readwrite_packetize (dev, endpoint, + GRUB_USB_TRANSFER_TYPE_IN, +@@ -414,7 +411,8 @@ grub_usb_check_transfer (grub_usb_transfer_t transfer, grub_size_t *actual) + + grub_usb_transfer_t + grub_usb_bulk_read_background (grub_usb_device_t dev, +- int endpoint, grub_size_t size, void *data) ++ struct grub_usb_desc_endp *endpoint, ++ grub_size_t size, void *data) + { + grub_usb_err_t err; + grub_usb_transfer_t transfer; +@@ -441,7 +439,8 @@ grub_usb_cancel_transfer (grub_usb_transfer_t transfer) + + grub_usb_err_t + grub_usb_bulk_read_extended (grub_usb_device_t dev, +- int endpoint, grub_size_t size, char *data, ++ struct grub_usb_desc_endp *endpoint, ++ grub_size_t size, char *data, + int timeout, grub_size_t *actual) + { + return grub_usb_bulk_readwrite (dev, endpoint, size, data, +diff --git a/grub-core/disk/usbms.c b/grub-core/disk/usbms.c +index 50f0caf..dd35bff 100644 +--- a/grub-core/disk/usbms.c ++++ b/grub-core/disk/usbms.c +@@ -326,7 +326,7 @@ grub_usbms_transfer_bo (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd, + + /* Write the request. + * XXX: Error recovery is maybe still not fully correct. */ +- err = grub_usb_bulk_write (dev->dev, dev->out->endp_addr, ++ err = grub_usb_bulk_write (dev->dev, dev->out, + sizeof (cbw), (char *) &cbw); + if (err) + { +@@ -341,7 +341,7 @@ grub_usbms_transfer_bo (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd, + /* Read/write the data, (maybe) according to specification. */ + if (size && (read_write == 0)) + { +- err = grub_usb_bulk_read (dev->dev, dev->in->endp_addr, size, buf); ++ err = grub_usb_bulk_read (dev->dev, dev->in, size, buf); + grub_dprintf ("usb", "read: %d %d\n", err, GRUB_USB_ERR_STALL); + if (err) + { +@@ -362,7 +362,7 @@ grub_usbms_transfer_bo (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd, + } + else if (size) + { +- err = grub_usb_bulk_write (dev->dev, dev->out->endp_addr, size, buf); ++ err = grub_usb_bulk_write (dev->dev, dev->out, size, buf); + grub_dprintf ("usb", "write: %d %d\n", err, GRUB_USB_ERR_STALL); + grub_dprintf ("usb", "First 16 bytes of sent data:\n %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", + buf[ 0], buf[ 1], buf[ 2], buf[ 3], +@@ -388,12 +388,12 @@ grub_usbms_transfer_bo (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd, + + /* Read the status - (maybe) according to specification. */ + CheckCSW: +- errCSW = grub_usb_bulk_read (dev->dev, dev->in->endp_addr, ++ errCSW = grub_usb_bulk_read (dev->dev, dev->in, + sizeof (status), (char *) &status); + if (errCSW) + { + grub_usb_clear_halt (dev->dev, dev->in->endp_addr); +- errCSW = grub_usb_bulk_read (dev->dev, dev->in->endp_addr, ++ errCSW = grub_usb_bulk_read (dev->dev, dev->in, + sizeof (status), (char *) &status); + if (errCSW) + { /* Bulk-only reset device. */ +@@ -476,7 +476,7 @@ grub_usbms_transfer_cbi (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd, + else if (dev->protocol == GRUB_USBMS_PROTOCOL_CBI) + { + /* Try to get status from interrupt pipe */ +- err = grub_usb_bulk_read (dev->dev, dev->intrpt->endp_addr, ++ err = grub_usb_bulk_read (dev->dev, dev->intrpt, + 2, (char*)&status); + grub_dprintf ("usb", "CBI cmdcb setup status: err=%d, status=0x%x\n", err, status); + } +@@ -487,7 +487,7 @@ grub_usbms_transfer_cbi (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd, + /* Read/write the data, (maybe) according to specification. */ + if (size && (read_write == 0)) + { +- err = grub_usb_bulk_read (dev->dev, dev->in->endp_addr, size, buf); ++ err = grub_usb_bulk_read (dev->dev, dev->in, size, buf); + grub_dprintf ("usb", "read: %d\n", err); + if (err) + { +@@ -498,7 +498,7 @@ grub_usbms_transfer_cbi (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd, + } + else if (size) + { +- err = grub_usb_bulk_write (dev->dev, dev->out->endp_addr, size, buf); ++ err = grub_usb_bulk_write (dev->dev, dev->out, size, buf); + grub_dprintf ("usb", "write: %d\n", err); + if (err) + { +@@ -517,7 +517,7 @@ grub_usbms_transfer_cbi (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd, + * (we do not it yet) - ? */ + if (dev->protocol == GRUB_USBMS_PROTOCOL_CBI) + { /* Check status in interrupt pipe */ +- err = grub_usb_bulk_read (dev->dev, dev->intrpt->endp_addr, ++ err = grub_usb_bulk_read (dev->dev, dev->intrpt, + 2, (char*)&status); + grub_dprintf ("usb", "read status: %d\n", err); + if (err) +diff --git a/grub-core/term/usb_keyboard.c b/grub-core/term/usb_keyboard.c +index ae00936..3b74846 100644 +--- a/grub-core/term/usb_keyboard.c ++++ b/grub-core/term/usb_keyboard.c +@@ -244,7 +244,7 @@ grub_usb_keyboard_attach (grub_usb_device_t usbdev, int configno, int interfno) + #endif + + data->transfer = grub_usb_bulk_read_background (usbdev, +- data->endp->endp_addr, ++ data->endp, + sizeof (data->report), + (char *) data->report); + if (!data->transfer) +@@ -394,7 +394,7 @@ grub_usb_keyboard_getkey (struct grub_term_input *term) + sizeof (termdata->report)); + + termdata->transfer = grub_usb_bulk_read_background (termdata->usbdev, +- termdata->endp->endp_addr, ++ termdata->endp, + sizeof (termdata->report), + (char *) termdata->report); + if (!termdata->transfer) +diff --git a/include/grub/usb.h b/include/grub/usb.h +index 55f65f7..32f0ecd 100644 +--- a/include/grub/usb.h ++++ b/include/grub/usb.h +@@ -63,9 +63,6 @@ grub_usb_err_t grub_usb_get_descriptor (grub_usb_device_t dev, + grub_uint8_t type, grub_uint8_t index, + grub_size_t size, char *data); + +-struct grub_usb_desc_endp * +-grub_usb_get_endpdescriptor (grub_usb_device_t usbdev, int addr); +- + grub_usb_err_t grub_usb_clear_halt (grub_usb_device_t dev, int endpoint); + + +@@ -87,10 +84,12 @@ grub_usb_err_t grub_usb_control_msg (grub_usb_device_t dev, grub_uint8_t reqtype + + grub_usb_err_t + grub_usb_bulk_read (grub_usb_device_t dev, +- int endpoint, grub_size_t size, char *data); ++ struct grub_usb_desc_endp *endpoint, ++ grub_size_t size, char *data); + grub_usb_err_t + grub_usb_bulk_write (grub_usb_device_t dev, +- int endpoint, grub_size_t size, char *data); ++ struct grub_usb_desc_endp *endpoint, ++ grub_size_t size, char *data); + + grub_usb_err_t + grub_usb_root_hub (grub_usb_controller_t controller); +@@ -297,11 +296,13 @@ void grub_usb_poll_devices (void); + void grub_usb_device_attach (grub_usb_device_t dev); + grub_usb_err_t + grub_usb_bulk_read_extended (grub_usb_device_t dev, +- int endpoint, grub_size_t size, char *data, ++ struct grub_usb_desc_endp *endpoint, ++ grub_size_t size, char *data, + int timeout, grub_size_t *actual); + grub_usb_transfer_t + grub_usb_bulk_read_background (grub_usb_device_t dev, +- int endpoint, grub_size_t size, void *data); ++ struct grub_usb_desc_endp *endpoint, ++ grub_size_t size, void *data); + grub_usb_err_t + grub_usb_check_transfer (grub_usb_transfer_t trans, grub_size_t *actual); + void +-- +1.8.1.4 + diff --git a/0212-Implement-boot-time-analysis-framework.patch b/0212-Implement-boot-time-analysis-framework.patch new file mode 100644 index 0000000..40f03f9 --- /dev/null +++ b/0212-Implement-boot-time-analysis-framework.patch @@ -0,0 +1,595 @@ +From 6136b9fb4811ee44ec16f3ad9f4306d0798419b1 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Tue, 19 Mar 2013 20:25:09 +0100 +Subject: [PATCH 212/364] Implement boot time analysis framework. + +--- + ChangeLog | 6 +++- + config.h.in | 1 + + configure.ac | 19 +++++++++++++ + grub-core/Makefile.core.def | 6 ++++ + grub-core/bus/usb/ehci.c | 7 +++++ + grub-core/bus/usb/usb.c | 9 ++++-- + grub-core/bus/usb/usbhub.c | 35 +++++++++++++++++++---- + grub-core/commands/boottime.c | 66 +++++++++++++++++++++++++++++++++++++++++++ + grub-core/disk/usbms.c | 4 +++ + grub-core/kern/dl.c | 3 ++ + grub-core/kern/main.c | 12 ++++++++ + grub-core/kern/misc.c | 39 +++++++++++++++++++++++++ + grub-core/normal/main.c | 13 +++++++++ + include/grub/misc.h | 20 +++++++++++++ + 14 files changed, 232 insertions(+), 8 deletions(-) + create mode 100644 grub-core/commands/boottime.c + +diff --git a/ChangeLog b/ChangeLog +index a544fbf..94dd5bb 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,6 +1,10 @@ + 2013-03-19 Vladimir Serbinenko + +- remove get_endpoint_descriptor and change all functions needing ++ Implement boot time analysis framework. ++ ++2013-03-19 Vladimir Serbinenko ++ ++ Remove get_endpoint_descriptor and change all functions needing + descriptor to just receive it as argument rather than endpoint + address. + +diff --git a/config.h.in b/config.h.in +index 621742c..2e1f459 100644 +--- a/config.h.in ++++ b/config.h.in +@@ -8,6 +8,7 @@ + + /* Define to 1 to enable disk cache statistics. */ + #define DISK_CACHE_STATS @DISK_CACHE_STATS@ ++#define BOOT_TIME_STATS @BOOT_TIME_STATS@ + + #if defined (GRUB_UTIL) || !defined (GRUB_MACHINE) + #include +diff --git a/configure.ac b/configure.ac +index 038f429..a39a025 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -798,6 +798,17 @@ else + fi + AC_SUBST([DISK_CACHE_STATS]) + ++AC_ARG_ENABLE([boot-time], ++ AS_HELP_STRING([--enable-boot-time], ++ [enable boot time statistics collection])) ++ ++if test x$enable_boot_time = xyes; then ++ BOOT_TIME_STATS=1 ++else ++ BOOT_TIME_STATS=0 ++fi ++AC_SUBST([BOOT_TIME_STATS]) ++ + AC_ARG_ENABLE([grub-emu-usb], + [AS_HELP_STRING([--enable-grub-emu-usb], + [build and install the `grub-emu' debugging utility with USB support (default=guessed)])]) +@@ -1159,6 +1170,7 @@ AM_CONDITIONAL([COND_GRUB_PE2ELF], [test x$TARGET_OBJ2ELF != x]) + AM_CONDITIONAL([COND_APPLE_CC], [test x$TARGET_APPLE_CC = x1]) + AM_CONDITIONAL([COND_ENABLE_EFIEMU], [test x$enable_efiemu = xyes]) + AM_CONDITIONAL([COND_ENABLE_CACHE_STATS], [test x$DISK_CACHE_STATS = x1]) ++AM_CONDITIONAL([COND_ENABLE_BOOT_TIME_STATS], [test x$BOOT_TIME_STATS = x1]) + + AM_CONDITIONAL([COND_HAVE_ASM_USCORE], [test x$HAVE_ASM_USCORE = x1]) + AM_CONDITIONAL([COND_CYGWIN], [test x$host_os = xcygwin]) +@@ -1231,6 +1243,13 @@ echo With disk cache statistics: Yes + else + echo With disk cache statistics: No + fi ++ ++if [ x"$enable_boot_time" = xyes ]; then ++echo With boot time statistics: Yes ++else ++echo With boot time statistics: No ++fi ++ + if [ x"$efiemu_excuse" = x ]; then + echo efiemu runtime: Yes + else +diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def +index 3bcf662..5c15f32 100644 +--- a/grub-core/Makefile.core.def ++++ b/grub-core/Makefile.core.def +@@ -1869,6 +1869,12 @@ module = { + }; + + module = { ++ name = boottime; ++ common = commands/boottime.c; ++ condition = COND_ENABLE_BOOT_TIME_STATS; ++}; ++ ++module = { + name = adler32; + common = lib/adler32.c; + }; +diff --git a/grub-core/bus/usb/ehci.c b/grub-core/bus/usb/ehci.c +index c60873d..a5a24af 100644 +--- a/grub-core/bus/usb/ehci.c ++++ b/grub-core/bus/usb/ehci.c +@@ -715,6 +715,7 @@ grub_ehci_pci_iter (grub_pci_device_t dev, grub_pci_id_t pciid, + usblegsup = grub_pci_read (pciaddr_eecp); + if (usblegsup & GRUB_EHCI_BIOS_OWNED) + { ++ grub_boot_time ("Taking ownership of EHCI port"); + grub_dprintf ("ehci", + "EHCI grub_ehci_pci_iter: EHCI owned by: BIOS\n"); + /* Ownership change - set OS_OWNED bit */ +@@ -741,6 +742,7 @@ grub_ehci_pci_iter (grub_pci_device_t dev, grub_pci_id_t pciid, + /* Ensure PCI register is written */ + grub_pci_read (pciaddr_eecp); + } ++ grub_boot_time ("Ownership of EHCI port taken"); + } + else if (usblegsup & GRUB_EHCI_OS_OWNED) + /* XXX: What to do in this case - nothing ? Can it happen ? */ +@@ -1706,10 +1708,12 @@ grub_ehci_portstatus (grub_usb_controller_t dev, + /* Reset RESET bit and wait for the end of reset */ + grub_ehci_port_resbits (e, port, GRUB_EHCI_PORT_RESET); + endtime = grub_get_time_ms () + 1000; ++ grub_boot_time ("Resetting port %d", port); + while (grub_ehci_port_read (e, port) & GRUB_EHCI_PORT_RESET) + if (grub_get_time_ms () > endtime) + return grub_error (GRUB_ERR_IO, + "portstatus: EHCI Timed out - reset port"); ++ grub_boot_time ("Port %d reset", port); + /* Remember "we did the reset" - needed by detect_dev */ + e->reset |= (1 << port); + /* Test if port enabled, i.e. HIGH speed device connected */ +@@ -1911,8 +1915,11 @@ GRUB_MOD_INIT (ehci) + { + COMPILE_TIME_ASSERT (sizeof (struct grub_ehci_td) == 64); + COMPILE_TIME_ASSERT (sizeof (struct grub_ehci_qh) == 96); ++ grub_boot_time ("Initing EHCI hardware"); + grub_ehci_inithw (); ++ grub_boot_time ("Registering EHCI driver"); + grub_usb_controller_dev_register (&usb_controller); ++ grub_boot_time ("EHCI driver registered"); + grub_loader_register_preboot_hook (grub_ehci_fini_hw, grub_ehci_restore_hw, + GRUB_LOADER_PREBOOT_HOOK_PRIO_DISK); + } +diff --git a/grub-core/bus/usb/usb.c b/grub-core/bus/usb/usb.c +index 7a517f8..108c69b 100644 +--- a/grub-core/bus/usb/usb.c ++++ b/grub-core/bus/usb/usb.c +@@ -262,8 +262,13 @@ void grub_usb_device_attach (grub_usb_device_t dev) + continue; + + for (desc = attach_hooks; desc; desc = desc->next) +- if (interf->class == desc->class && desc->hook (dev, 0, i)) +- dev->config[0].interf[i].attached = 1; ++ if (interf->class == desc->class) ++ { ++ grub_boot_time ("Probing USB device driver class %x", desc->class); ++ if (desc->hook (dev, 0, i)) ++ dev->config[0].interf[i].attached = 1; ++ grub_boot_time ("Probed USB device driver class %x", desc->class); ++ } + + if (dev->config[0].interf[i].attached) + continue; +diff --git a/grub-core/bus/usb/usbhub.c b/grub-core/bus/usb/usbhub.c +index 7e7dc8c..f95a567 100644 +--- a/grub-core/bus/usb/usbhub.c ++++ b/grub-core/bus/usb/usbhub.c +@@ -52,6 +52,8 @@ grub_usb_hub_add_dev (grub_usb_controller_t controller, + int i; + grub_usb_err_t err; + ++ grub_boot_time ("Attaching USB device"); ++ + dev = grub_zalloc (sizeof (struct grub_usb_device)); + if (! dev) + return NULL; +@@ -108,8 +110,12 @@ grub_usb_hub_add_dev (grub_usb_controller_t controller, + + /* Wait "recovery interval", spec. says 2ms */ + grub_millisleep (2); ++ ++ grub_boot_time ("Probing USB device driver"); + + grub_usb_device_attach (dev); ++ ++ grub_boot_time ("Attached USB device"); + + return dev; + } +@@ -194,6 +200,8 @@ attach_root_port (struct grub_usb_hub *hub, int portno, + grub_usb_speed_t current_speed = GRUB_USB_SPEED_NONE; + int changed=0; + ++ grub_boot_time ("detect_dev USB root portno=%d\n", portno); ++ + #if 0 + /* Specification does not say about disabling of port when device + * connected. If disabling is really necessary for some devices, +@@ -203,6 +211,9 @@ attach_root_port (struct grub_usb_hub *hub, int portno, + if (err) + return; + #endif ++ ++ grub_boot_time ("Before the stable power wait portno=%d", portno); ++ + /* Wait for completion of insertion and stable power (USB spec.) + * Should be at least 100ms, some devices requires more... + * There is also another thing - some devices have worse contacts +@@ -239,6 +250,8 @@ attach_root_port (struct grub_usb_hub *hub, int portno, + /* If the device is a Hub, scan it for more devices. */ + if (dev->descdev.class == 0x09) + grub_usb_add_hub (dev); ++ ++ grub_boot_time ("Attached root port"); + } + + grub_usb_err_t +@@ -248,6 +261,8 @@ grub_usb_root_hub (grub_usb_controller_t controller) + struct grub_usb_hub *hub; + int changed=0; + ++ grub_boot_time ("Registering USB root hub"); ++ + hub = grub_malloc (sizeof (*hub)); + if (!hub) + return GRUB_USB_ERR_INTERNAL; +@@ -287,6 +302,8 @@ grub_usb_root_hub (grub_usb_controller_t controller) + } + } + ++ grub_boot_time ("USB root hub registered"); ++ + return GRUB_USB_ERR_NONE; + } + +@@ -407,12 +424,13 @@ poll_nonroot_hub (grub_usb_device_t dev) + /* Connected and status of connection changed ? */ + if (status & GRUB_USB_HUB_STATUS_PORT_CONNECTED) + { ++ grub_boot_time ("Before the stable power wait portno=%d", i); + /* A device is actually connected to this port. */ +- /* Wait for completion of insertion and stable power (USB spec.) +- * Should be at least 100ms, some devices requires more... +- * There is also another thing - some devices have worse contacts +- * and connected signal is unstable for some time - we should handle +- * it - but prevent deadlock in case when device is too faulty... */ ++ /* Wait for completion of insertion and stable power (USB spec.) ++ * Should be at least 100ms, some devices requires more... ++ * There is also another thing - some devices have worse contacts ++ * and connected signal is unstable for some time - we should handle ++ * it - but prevent deadlock in case when device is too faulty... */ + for (total = j = 0; (j < 250) && (total < 2000); j++, total++) + { + grub_millisleep (1); +@@ -432,6 +450,9 @@ poll_nonroot_hub (grub_usb_device_t dev) + if (!(current_status & GRUB_USB_HUB_STATUS_PORT_CONNECTED)) + j = 0; + } ++ ++ grub_boot_time ("After the stable power wait portno=%d", i); ++ + grub_dprintf ("usb", "(non-root) total=%d\n", total); + if (total >= 2000) + continue; +@@ -443,6 +464,8 @@ poll_nonroot_hub (grub_usb_device_t dev) + GRUB_USB_REQ_SET_FEATURE, + GRUB_USB_HUB_FEATURE_PORT_RESET, + i, 0, 0); ++ grub_boot_time ("Resetting port %d", i); ++ + rescan = 1; + /* We cannot reset more than one device at the same time ! + * Resetting more devices together results in very bad +@@ -464,6 +487,8 @@ poll_nonroot_hub (grub_usb_device_t dev) + GRUB_USB_REQ_CLEAR_FEATURE, + GRUB_USB_HUB_FEATURE_C_PORT_RESET, i, 0, 0); + ++ grub_boot_time ("Port %d reset", i); ++ + if (status & GRUB_USB_HUB_STATUS_PORT_CONNECTED) + { + grub_usb_speed_t speed; +diff --git a/grub-core/commands/boottime.c b/grub-core/commands/boottime.c +new file mode 100644 +index 0000000..cd7f70a +--- /dev/null ++++ b/grub-core/commands/boottime.c +@@ -0,0 +1,66 @@ ++/* cacheinfo.c - disk cache statistics */ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * 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 ++ * 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_MOD_LICENSE ("GPLv3+"); ++ ++ ++static grub_err_t ++grub_cmd_boottime (struct grub_command *cmd __attribute__ ((unused)), ++ int argc __attribute__ ((unused)), ++ char *argv[] __attribute__ ((unused))) ++{ ++ struct grub_boot_time *cur; ++ grub_uint64_t last_time = 0, start_time = 0; ++ if (!grub_boot_time_head) ++ { ++ grub_puts_ (N_("No boot time statistics is available\n")); ++ return 0; ++ } ++ start_time = last_time = grub_boot_time_head->tp; ++ for (cur = grub_boot_time_head; cur; cur = cur->next) ++ { ++ grub_uint32_t tmabs = cur->tp - start_time; ++ grub_uint32_t tmrel = cur->tp - last_time; ++ last_time = cur->tp; ++ ++ grub_printf ("%3d.%03ds %2d.%03ds %s:%d %s\n", ++ tmabs / 1000, tmabs % 1000, tmrel / 1000, tmrel % 1000, cur->file, cur->line, ++ cur->msg); ++ } ++ return 0; ++} ++ ++static grub_command_t cmd_boottime; ++ ++GRUB_MOD_INIT(boottime) ++{ ++ cmd_boottime = ++ grub_register_command ("boottime", grub_cmd_boottime, ++ 0, N_("Get boot time statistics.")); ++} ++ ++GRUB_MOD_FINI(boottime) ++{ ++ grub_unregister_command (cmd_boottime); ++} +diff --git a/grub-core/disk/usbms.c b/grub-core/disk/usbms.c +index dd35bff..2cfc537 100644 +--- a/grub-core/disk/usbms.c ++++ b/grub-core/disk/usbms.c +@@ -151,6 +151,8 @@ grub_usbms_attach (grub_usb_device_t usbdev, int configno, int interfno) + unsigned curnum; + grub_usb_err_t err = GRUB_ERR_NONE; + ++ grub_boot_time ("Attaching USB mass storage"); ++ + if (first_available_slot == ARRAY_SIZE (grub_usbms_devices)) + return 0; + +@@ -246,6 +248,8 @@ grub_usbms_attach (grub_usb_device_t usbdev, int configno, int interfno) + + usbdev->config[configno].interf[interfno].detach_hook = grub_usbms_detach; + ++ grub_boot_time ("Attached USB mass storage"); ++ + #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... +diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c +index 5b0aa65..d06b6ae 100644 +--- a/grub-core/kern/dl.c ++++ b/grub-core/kern/dl.c +@@ -648,7 +648,10 @@ grub_dl_load_core (void *addr, grub_size_t size) + + grub_dprintf ("modules", "module name: %s\n", mod->name); + grub_dprintf ("modules", "init function: %p\n", mod->init); ++ ++ grub_boot_time ("Initing module %s", mod->name); + grub_dl_call_init (mod); ++ grub_boot_time ("Module %s inited", mod->name); + + if (grub_dl_add (mod)) + { +diff --git a/grub-core/kern/main.c b/grub-core/kern/main.c +index e1a2001..19dc988 100644 +--- a/grub-core/kern/main.c ++++ b/grub-core/kern/main.c +@@ -254,6 +254,8 @@ grub_main (void) + /* First of all, initialize the machine. */ + grub_machine_init (); + ++ grub_boot_time ("After machine init."); ++ + /* Hello. */ + grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT); + grub_printf ("Welcome to GRUB!\n\n"); +@@ -261,6 +263,8 @@ grub_main (void) + + grub_load_config (); + ++ grub_boot_time ("Before loading embedded modules."); ++ + /* Load pre-loaded modules and free the space. */ + grub_register_exported_symbols (); + #ifdef GRUB_LINKER_HAVE_INIT +@@ -268,6 +272,8 @@ grub_main (void) + #endif + grub_load_modules (); + ++ grub_boot_time ("After loading embedded modules."); ++ + /* It is better to set the root device as soon as possible, + for convenience. */ + grub_set_prefix_and_root (); +@@ -277,11 +283,17 @@ grub_main (void) + /* Reclaim space used for modules. */ + reclaim_module_space (); + ++ grub_boot_time ("After reclaiming module space."); ++ + grub_register_core_commands (); + ++ grub_boot_time ("Before execution of embedded config."); ++ + if (load_config) + grub_parser_execute (load_config); + ++ grub_boot_time ("After execution of embedded config. Attempt to go to normal mode"); ++ + grub_load_normal_mode (); + grub_rescue_run (); + } +diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c +index 6cb8f0e..94b88a3 100644 +--- a/grub-core/kern/misc.c ++++ b/grub-core/kern/misc.c +@@ -1130,3 +1130,42 @@ void __deregister_frame_info (void) + } + #endif + ++#if BOOT_TIME_STATS ++ ++#include ++ ++struct grub_boot_time *grub_boot_time_head; ++static struct grub_boot_time **boot_time_last = &grub_boot_time_head; ++ ++void ++grub_real_boot_time (const char *file, ++ const int line, ++ const char *fmt, ...) ++{ ++ struct grub_boot_time *n; ++ va_list args; ++ ++ grub_error_push (); ++ n = grub_malloc (sizeof (*n)); ++ if (!n) ++ { ++ grub_errno = 0; ++ grub_error_pop (); ++ return; ++ } ++ n->file = file; ++ n->line = line; ++ n->tp = grub_get_time_ms (); ++ n->next = 0; ++ ++ va_start (args, fmt); ++ n->msg = grub_xvasprintf (fmt, args); ++ va_end (args); ++ ++ *boot_time_last = n; ++ boot_time_last = &n->next; ++ ++ grub_errno = 0; ++ grub_error_pop (); ++} ++#endif +diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c +index 07f337d..9aaa3b2 100644 +--- a/grub-core/normal/main.c ++++ b/grub-core/normal/main.c +@@ -296,6 +296,8 @@ grub_normal_execute (const char *config, int nested, int batch) + grub_register_variable_hook ("prefix", NULL, read_lists_hook); + } + ++ grub_boot_time ("Executing config file"); ++ + if (config) + { + menu = read_config_file (config); +@@ -304,10 +306,14 @@ grub_normal_execute (const char *config, int nested, int batch) + grub_errno = GRUB_ERR_NONE; + } + ++ grub_boot_time ("Executed config file"); ++ + if (! batch) + { + if (menu && menu->size) + { ++ ++ grub_boot_time ("Entering menu"); + grub_show_menu (menu, nested, 0); + if (nested) + grub_normal_free_menu (menu); +@@ -319,12 +325,15 @@ grub_normal_execute (const char *config, int nested, int batch) + void + grub_enter_normal_mode (const char *config) + { ++ grub_boot_time ("Entering normal mode"); + nested_level++; + grub_normal_execute (config, 0, 0); ++ grub_boot_time ("Entering shell"); + grub_cmdline_run (0); + nested_level--; + if (grub_normal_exit_level) + grub_normal_exit_level--; ++ grub_boot_time ("Exiting normal mode"); + } + + /* Enter normal mode from rescue mode. */ +@@ -504,6 +513,8 @@ GRUB_MOD_INIT(normal) + { + unsigned i; + ++ grub_boot_time ("Preparing normal module"); ++ + /* Previously many modules depended on gzio. Be nice to user and load it. */ + grub_dl_load ("gzio"); + grub_errno = 0; +@@ -556,6 +567,8 @@ GRUB_MOD_INIT(normal) + grub_env_export ("grub_cpu"); + grub_env_set ("grub_platform", GRUB_PLATFORM); + grub_env_export ("grub_platform"); ++ ++ grub_boot_time ("Normal module prepared"); + } + + GRUB_MOD_FINI(normal) +diff --git a/include/grub/misc.h b/include/grub/misc.h +index 11eeb22..f0ecaec 100644 +--- a/include/grub/misc.h ++++ b/include/grub/misc.h +@@ -458,4 +458,24 @@ grub_error_load (const struct grub_error_saved *save) + grub_errno = save->grub_errno; + } + ++#if BOOT_TIME_STATS ++struct grub_boot_time ++{ ++ struct grub_boot_time *next; ++ grub_uint64_t tp; ++ const char *file; ++ int line; ++ char *msg; ++}; ++ ++extern struct grub_boot_time *EXPORT_VAR(grub_boot_time_head); ++ ++void EXPORT_FUNC(grub_real_boot_time) (const char *file, ++ const int line, ++ const char *fmt, ...) __attribute__ ((format (printf, 3, 4))); ++#define grub_boot_time(fmt, args...) grub_real_boot_time(GRUB_FILE, __LINE__, fmt, ## args) ++#else ++#define grub_boot_time(fmt, args...) ++#endif ++ + #endif /* ! GRUB_MISC_HEADER */ +-- +1.8.1.4 + diff --git a/0213-Fix-USB-devices-not-being-detected-when-requested.patch b/0213-Fix-USB-devices-not-being-detected-when-requested.patch new file mode 100644 index 0000000..229a7a5 --- /dev/null +++ b/0213-Fix-USB-devices-not-being-detected-when-requested.patch @@ -0,0 +1,267 @@ +From e8bff0306f0d095082eea159133007f1de62b169 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Tue, 19 Mar 2013 20:35:21 +0100 +Subject: [PATCH 213/364] Fix USB devices not being detected when + requested due to delayed attach. + +--- + ChangeLog | 5 +++++ + grub-core/bus/usb/usbhub.c | 29 ++++++++++++++++++++++++----- + grub-core/commands/keystatus.c | 2 +- + grub-core/commands/terminal.c | 12 ++++++++++-- + grub-core/commands/usbtest.c | 2 +- + grub-core/disk/usbms.c | 5 +++-- + grub-core/kern/term.c | 4 ++-- + include/grub/term.h | 2 +- + include/grub/usb.h | 2 +- + 9 files changed, 48 insertions(+), 15 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 94dd5bb..725fbe2 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,10 @@ + 2013-03-19 Vladimir Serbinenko + ++ Fix USB devices not being detected when requested ++ due to delayed attach. ++ ++2013-03-19 Vladimir Serbinenko ++ + Implement boot time analysis framework. + + 2013-03-19 Vladimir Serbinenko +diff --git a/grub-core/bus/usb/usbhub.c b/grub-core/bus/usb/usbhub.c +index f95a567..253e49f 100644 +--- a/grub-core/bus/usb/usbhub.c ++++ b/grub-core/bus/usb/usbhub.c +@@ -29,6 +29,7 @@ + static struct grub_usb_device *grub_usb_devs[GRUB_USBHUB_MAX_DEVICES]; + + static int rescan = 0; ++static int npending = 0; + + struct grub_usb_hub + { +@@ -227,21 +228,33 @@ attach_root_port (struct grub_usb_hub *hub, int portno, + if (current_speed == GRUB_USB_SPEED_NONE) + i = 0; + } ++ ++ grub_boot_time ("After the stable power wait portno=%d", portno); ++ + grub_dprintf ("usb", "total=%d\n", total); + if (total >= 2000) +- return; ++ { ++ grub_boot_time ("Root port timeout"); ++ return; ++ } ++ ++ grub_boot_time ("After detect_dev"); + + /* Enable the port. */ + err = hub->controller->dev->portstatus (hub->controller, portno, 1); + if (err) + return; + hub->controller->dev->pending_reset = grub_get_time_ms () + 5000; ++ npending++; + + grub_millisleep (10); + ++ grub_boot_time ("Port enabled"); ++ + /* Enable the port and create a device. */ + dev = grub_usb_hub_add_dev (hub->controller, speed, portno, 0); + hub->controller->dev->pending_reset = 0; ++ npending--; + if (! dev) + return; + +@@ -475,6 +488,7 @@ poll_nonroot_hub (grub_usb_device_t dev) + * anywhere on the same OHCI controller until + * we will finish addressing of reseted device ! */ + dev->controller.dev->pending_reset = grub_get_time_ms () + 5000; ++ npending++; + return; + } + } +@@ -510,7 +524,11 @@ poll_nonroot_hub (grub_usb_device_t dev) + + /* Add the device and assign a device address to it. */ + next_dev = grub_usb_hub_add_dev (&dev->controller, speed, i, dev->addr); +- dev->controller.dev->pending_reset = 0; ++ if (dev->controller.dev->pending_reset) ++ { ++ dev->controller.dev->pending_reset = 0; ++ npending--; ++ } + if (! next_dev) + continue; + +@@ -525,7 +543,7 @@ poll_nonroot_hub (grub_usb_device_t dev) + } + + void +-grub_usb_poll_devices (void) ++grub_usb_poll_devices (int wait_for_completion) + { + struct grub_usb_hub *hub; + int i; +@@ -539,7 +557,7 @@ grub_usb_poll_devices (void) + grub_usb_speed_t speed = GRUB_USB_SPEED_NONE; + int changed = 0; + +- if (!hub->controller->dev->pending_reset) ++ if (hub->controller->dev->pending_reset) + { + /* Check for possible timeout */ + if (grub_get_time_ms () > hub->controller->dev->pending_reset) +@@ -547,6 +565,7 @@ grub_usb_poll_devices (void) + /* Something went wrong, reset device was not + * addressed properly, timeout happened */ + hub->controller->dev->pending_reset = 0; ++ npending--; + speed = hub->controller->dev->detect_dev (hub->controller, + i, &changed); + } +@@ -573,7 +592,7 @@ grub_usb_poll_devices (void) + if (dev && dev->descdev.class == 0x09) + poll_nonroot_hub (dev); + } +- if (!rescan) ++ if (!(rescan || (npending && wait_for_completion))) + break; + grub_millisleep (50); + } +diff --git a/grub-core/commands/keystatus.c b/grub-core/commands/keystatus.c +index 0925c6a..460cf4e 100644 +--- a/grub-core/commands/keystatus.c ++++ b/grub-core/commands/keystatus.c +@@ -42,7 +42,7 @@ grub_getkeystatus (void) + grub_term_input_t term; + + if (grub_term_poll_usb) +- grub_term_poll_usb (); ++ grub_term_poll_usb (0); + + FOR_ACTIVE_TERM_INPUTS(term) + { +diff --git a/grub-core/commands/terminal.c b/grub-core/commands/terminal.c +index 425a411..3002186 100644 +--- a/grub-core/commands/terminal.c ++++ b/grub-core/commands/terminal.c +@@ -108,9 +108,9 @@ handle_command (int argc, char **args, struct abstract_terminal **enabled, + if (term) + break; + if (again) +- return grub_error (GRUB_ERR_BAD_ARGUMENT, ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, + N_("terminal `%s' isn't found"), +- args[i]); ++ args[i]); + for (aut = autoloads; aut; aut = aut->next) + if (grub_strcmp (args[i], aut->name) == 0 + || (grub_strcmp (args[i], "ofconsole") == 0 +@@ -126,6 +126,14 @@ handle_command (int argc, char **args, struct abstract_terminal **enabled, + grub_errno = GRUB_ERR_NONE; + break; + } ++ if (grub_memcmp (args[i], "serial_usb", ++ sizeof ("serial_usb") - 1) == 0 ++ && grub_term_poll_usb) ++ { ++ grub_term_poll_usb (1); ++ again = 1; ++ continue; ++ } + if (!aut) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + N_("terminal `%s' isn't found"), +diff --git a/grub-core/commands/usbtest.c b/grub-core/commands/usbtest.c +index af35b8c..01cdca9 100644 +--- a/grub-core/commands/usbtest.c ++++ b/grub-core/commands/usbtest.c +@@ -196,7 +196,7 @@ grub_cmd_usbtest (grub_command_t cmd __attribute__ ((unused)), + int argc __attribute__ ((unused)), + char **args __attribute__ ((unused))) + { +- grub_usb_poll_devices (); ++ grub_usb_poll_devices (1); + + grub_printf ("USB devices:\n\n"); + grub_usb_iterate (usb_iterate, NULL); +diff --git a/grub-core/disk/usbms.c b/grub-core/disk/usbms.c +index 2cfc537..da01be3 100644 +--- a/grub-core/disk/usbms.c ++++ b/grub-core/disk/usbms.c +@@ -277,7 +277,7 @@ grub_usbms_iterate (grub_scsi_dev_iterate_hook_t hook, void *hook_data, + if (pull != GRUB_DISK_PULL_NONE) + return 0; + +- grub_usb_poll_devices (); ++ grub_usb_poll_devices (1); + + for (i = 0; i < ARRAY_SIZE (grub_usbms_devices); i++) + if (grub_usbms_devices[i]) +@@ -611,7 +611,8 @@ grub_usbms_open (int id, int devnum, struct grub_scsi *scsi) + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, + "not USB Mass Storage device"); + +- grub_usb_poll_devices (); ++ if (!grub_usbms_devices[devnum]) ++ grub_usb_poll_devices (1); + + if (!grub_usbms_devices[devnum]) + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, +diff --git a/grub-core/kern/term.c b/grub-core/kern/term.c +index 44ada25..66c5971 100644 +--- a/grub-core/kern/term.c ++++ b/grub-core/kern/term.c +@@ -32,7 +32,7 @@ struct grub_term_input *grub_term_inputs; + grub_uint8_t grub_term_normal_color = GRUB_TERM_DEFAULT_NORMAL_COLOR; + grub_uint8_t grub_term_highlight_color = GRUB_TERM_DEFAULT_HIGHLIGHT_COLOR; + +-void (*grub_term_poll_usb) (void) = NULL; ++void (*grub_term_poll_usb) (int wait_for_completion) = NULL; + void (*grub_net_poll_cards_idle) (void) = NULL; + + /* Put a Unicode character. */ +@@ -90,7 +90,7 @@ grub_getkey_noblock (void) + grub_term_input_t term; + + if (grub_term_poll_usb) +- grub_term_poll_usb (); ++ grub_term_poll_usb (0); + + if (grub_net_poll_cards_idle) + grub_net_poll_cards_idle (); +diff --git a/include/grub/term.h b/include/grub/term.h +index 84f5766..655a5e3 100644 +--- a/include/grub/term.h ++++ b/include/grub/term.h +@@ -467,7 +467,7 @@ grub_print_spaces (struct grub_term_output *term, int number_spaces) + grub_putcode (' ', term); + } + +-extern void (*EXPORT_VAR (grub_term_poll_usb)) (void); ++extern void (*EXPORT_VAR (grub_term_poll_usb)) (int wait_for_completion); + + #define GRUB_TERM_REPEAT_PRE_INTERVAL 400 + #define GRUB_TERM_REPEAT_INTERVAL 50 +diff --git a/include/grub/usb.h b/include/grub/usb.h +index 32f0ecd..7164dd5 100644 +--- a/include/grub/usb.h ++++ b/include/grub/usb.h +@@ -291,7 +291,7 @@ struct grub_usb_attach_desc + void grub_usb_register_attach_hook_class (struct grub_usb_attach_desc *desc); + void grub_usb_unregister_attach_hook_class (struct grub_usb_attach_desc *desc); + +-void grub_usb_poll_devices (void); ++void grub_usb_poll_devices (int wait_for_completion); + + void grub_usb_device_attach (grub_usb_device_t dev); + grub_usb_err_t +-- +1.8.1.4 + diff --git a/0214-Initialize-USB-ports-in-parallel-to-speed-up-boot.patch b/0214-Initialize-USB-ports-in-parallel-to-speed-up-boot.patch new file mode 100644 index 0000000..aa1cd75 --- /dev/null +++ b/0214-Initialize-USB-ports-in-parallel-to-speed-up-boot.patch @@ -0,0 +1,539 @@ +From b5ba765ba55f33743558a7f3a965b6156903e381 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Tue, 19 Mar 2013 23:06:44 +0100 +Subject: [PATCH 214/364] Initialize USB ports in parallel to speed-up + boot. + +--- + ChangeLog | 4 + + grub-core/bus/usb/usb.c | 38 ------ + grub-core/bus/usb/usbhub.c | 320 +++++++++++++++++++++++++++++---------------- + include/grub/usb.h | 16 +++ + 4 files changed, 228 insertions(+), 150 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 725fbe2..dd9c97a 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,9 @@ + 2013-03-19 Vladimir Serbinenko + ++ Initialize USB ports in parallel to speed-up boot. ++ ++2013-03-19 Vladimir Serbinenko ++ + Fix USB devices not being detected when requested + due to delayed attach. + +diff --git a/grub-core/bus/usb/usb.c b/grub-core/bus/usb/usb.c +index 108c69b..024190e 100644 +--- a/grub-core/bus/usb/usb.c ++++ b/grub-core/bus/usb/usb.c +@@ -26,46 +26,8 @@ + + GRUB_MOD_LICENSE ("GPLv3+"); + +-static grub_usb_controller_dev_t grub_usb_list; + static struct grub_usb_attach_desc *attach_hooks; + +-/* Iterate over all controllers found by the driver. */ +-static int +-grub_usb_controller_dev_register_iter (grub_usb_controller_t dev, void *data) +-{ +- grub_usb_controller_dev_t usb = data; +- +- dev->dev = usb; +- +- /* Enable the ports of the USB Root Hub. */ +- grub_usb_root_hub (dev); +- +- return 0; +-} +- +-void +-grub_usb_controller_dev_register (grub_usb_controller_dev_t usb) +-{ +- usb->next = grub_usb_list; +- grub_usb_list = usb; +- +- if (usb->iterate) +- usb->iterate (grub_usb_controller_dev_register_iter, usb); +-} +- +-void +-grub_usb_controller_dev_unregister (grub_usb_controller_dev_t usb) +-{ +- grub_usb_controller_dev_t *p, q; +- +- for (p = &grub_usb_list, q = *p; q; p = &(q->next), q = q->next) +- if (q == usb) +- { +- *p = q->next; +- break; +- } +-} +- + #if 0 + /* Context for grub_usb_controller_iterate. */ + struct grub_usb_controller_iterate_ctx +diff --git a/grub-core/bus/usb/usbhub.c b/grub-core/bus/usb/usbhub.c +index 253e49f..d0be80d 100644 +--- a/grub-core/bus/usb/usbhub.c ++++ b/grub-core/bus/usb/usbhub.c +@@ -41,6 +41,7 @@ struct grub_usb_hub + }; + + static struct grub_usb_hub *hubs; ++static grub_usb_controller_dev_t grub_usb_list; + + /* Add a device that currently has device number 0 and resides on + CONTROLLER, the Hub reported that the device speed is SPEED. */ +@@ -146,10 +147,15 @@ grub_usb_add_hub (grub_usb_device_t dev) + grub_dprintf ("usb", "Hub set configuration\n"); + grub_usb_set_configuration (dev, 1); + +- dev->children = grub_zalloc (hubdesc.portcnt * sizeof (dev->children[0])); +- if (!dev->children) +- return GRUB_USB_ERR_INTERNAL; + dev->nports = hubdesc.portcnt; ++ dev->children = grub_zalloc (hubdesc.portcnt * sizeof (dev->children[0])); ++ dev->ports = grub_zalloc (dev->nports * sizeof (dev->ports[0])); ++ if (!dev->children || !dev->ports) ++ { ++ grub_free (dev->children); ++ grub_free (dev->ports); ++ return GRUB_USB_ERR_INTERNAL; ++ } + + /* Power on all Hub ports. */ + for (i = 1; i <= hubdesc.portcnt; i++) +@@ -197,46 +203,6 @@ attach_root_port (struct grub_usb_hub *hub, int portno, + { + grub_usb_device_t dev; + grub_err_t err; +- int total, i; +- grub_usb_speed_t current_speed = GRUB_USB_SPEED_NONE; +- int changed=0; +- +- grub_boot_time ("detect_dev USB root portno=%d\n", portno); +- +-#if 0 +-/* Specification does not say about disabling of port when device +- * connected. If disabling is really necessary for some devices, +- * delete this #if 0 and related #endif */ +- /* Disable the port. XXX: Why? */ +- err = hub->controller->dev->portstatus (hub->controller, portno, 0); +- if (err) +- return; +-#endif +- +- grub_boot_time ("Before the stable power wait portno=%d", portno); +- +- /* Wait for completion of insertion and stable power (USB spec.) +- * Should be at least 100ms, some devices requires more... +- * There is also another thing - some devices have worse contacts +- * and connected signal is unstable for some time - we should handle +- * it - but prevent deadlock in case when device is too faulty... */ +- for (total = i = 0; (i < 250) && (total < 2000); i++, total++) +- { +- grub_millisleep (1); +- current_speed = hub->controller->dev->detect_dev +- (hub->controller, portno, &changed); +- if (current_speed == GRUB_USB_SPEED_NONE) +- i = 0; +- } +- +- grub_boot_time ("After the stable power wait portno=%d", portno); +- +- grub_dprintf ("usb", "total=%d\n", total); +- if (total >= 2000) +- { +- grub_boot_time ("Root port timeout"); +- return; +- } + + grub_boot_time ("After detect_dev"); + +@@ -267,12 +233,14 @@ attach_root_port (struct grub_usb_hub *hub, int portno, + grub_boot_time ("Attached root port"); + } + +-grub_usb_err_t +-grub_usb_root_hub (grub_usb_controller_t controller) ++/* Iterate over all controllers found by the driver. */ ++static int ++grub_usb_controller_dev_register_iter (grub_usb_controller_t controller, void *data) + { +- int i; ++ grub_usb_controller_dev_t usb = data; + struct grub_usb_hub *hub; +- int changed=0; ++ ++ controller->dev = usb; + + grub_boot_time ("Registering USB root hub"); + +@@ -295,29 +263,118 @@ grub_usb_root_hub (grub_usb_controller_t controller) + /* Query the number of ports the root Hub has. */ + hub->nports = controller->dev->hubports (controller); + hub->devices = grub_zalloc (sizeof (hub->devices[0]) * hub->nports); +- if (!hub->devices) ++ usb->ports = grub_zalloc (sizeof (usb->ports[0]) * hub->nports); ++ if (!hub->devices || !usb->ports) + { ++ grub_free (hub->devices); ++ grub_free (usb->ports); + grub_free (hub->controller); + grub_free (hub); +- return GRUB_USB_ERR_INTERNAL; ++ grub_print_error (); ++ return 0; + } + +- for (i = 0; i < hub->nports; i++) ++ return 0; ++} ++ ++void ++grub_usb_controller_dev_unregister (grub_usb_controller_dev_t usb) ++{ ++ grub_usb_controller_dev_t *p, q; ++ ++ for (p = &grub_usb_list, q = *p; q; p = &(q->next), q = q->next) ++ if (q == usb) ++ { ++ *p = q->next; ++ break; ++ } ++} ++ ++void ++grub_usb_controller_dev_register (grub_usb_controller_dev_t usb) ++{ ++ int portno; ++ int continue_waiting = 0; ++ struct grub_usb_hub *hub; ++ ++ usb->next = grub_usb_list; ++ grub_usb_list = usb; ++ ++ if (usb->iterate) ++ usb->iterate (grub_usb_controller_dev_register_iter, usb); ++ ++ grub_boot_time ("waiting for stable power on USB root\n"); ++ ++ while (1) + { +- grub_usb_speed_t speed; +- if (!controller->dev->pending_reset) +- { +- speed = controller->dev->detect_dev (hub->controller, i, +- &changed); +- +- if (speed != GRUB_USB_SPEED_NONE) +- attach_root_port (hub, i, speed); +- } ++ for (hub = hubs; hub; hub = hub->next) ++ if (hub->controller->dev == usb) ++ { ++ /* Wait for completion of insertion and stable power (USB spec.) ++ * Should be at least 100ms, some devices requires more... ++ * There is also another thing - some devices have worse contacts ++ * and connected signal is unstable for some time - we should handle ++ * it - but prevent deadlock in case when device is too faulty... */ ++ for (portno = 0; portno < hub->nports; portno++) ++ { ++ grub_usb_speed_t speed; ++ int changed = 0; ++ ++ speed = hub->controller->dev->detect_dev (hub->controller, portno, ++ &changed); ++ ++ if (usb->ports[portno].state == PORT_STATE_NORMAL ++ && speed != GRUB_USB_SPEED_NONE) ++ { ++ usb->ports[portno].soft_limit_time = grub_get_time_ms () + 250; ++ usb->ports[portno].hard_limit_time = usb->ports[portno].soft_limit_time + 1750; ++ usb->ports[portno].state = PORT_STATE_WAITING_FOR_STABLE_POWER; ++ continue_waiting++; ++ continue; ++ } ++ ++ if (usb->ports[portno].state == PORT_STATE_WAITING_FOR_STABLE_POWER ++ && speed == GRUB_USB_SPEED_NONE) ++ { ++ usb->ports[portno].soft_limit_time = grub_get_time_ms () + 250; ++ continue; ++ } ++ if (usb->ports[portno].state == PORT_STATE_WAITING_FOR_STABLE_POWER ++ && grub_get_time_ms () > usb->ports[portno].soft_limit_time) ++ { ++ usb->ports[portno].state = PORT_STATE_STABLE_POWER; ++ continue_waiting--; ++ continue; ++ } ++ if (usb->ports[portno].state == PORT_STATE_WAITING_FOR_STABLE_POWER ++ && grub_get_time_ms () > usb->ports[portno].hard_limit_time) ++ { ++ usb->ports[portno].state = PORT_STATE_FAILED_DEVICE; ++ continue_waiting--; ++ continue; ++ } ++ } ++ } ++ if (!continue_waiting) ++ break; ++ grub_millisleep (1); + } + +- grub_boot_time ("USB root hub registered"); ++ grub_boot_time ("After the stable power wait on USB root"); + +- return GRUB_USB_ERR_NONE; ++ for (hub = hubs; hub; hub = hub->next) ++ if (hub->controller->dev == usb) ++ for (portno = 0; portno < hub->nports; portno++) ++ if (usb->ports[portno].state == PORT_STATE_STABLE_POWER) ++ { ++ grub_usb_speed_t speed; ++ int changed = 0; ++ usb->ports[portno].state = PORT_STATE_NORMAL; ++ speed = hub->controller->dev->detect_dev (hub->controller, portno, &changed); ++ attach_root_port (hub, portno, speed); ++ } ++ ++ grub_boot_time ("USB root hub registered"); + } + + static void detach_device (grub_usb_device_t dev); +@@ -349,6 +406,71 @@ detach_device (grub_usb_device_t dev) + grub_usb_devs[dev->addr] = 0; + } + ++static int ++wait_power_nonroot_hub (grub_usb_device_t dev) ++{ ++ grub_usb_err_t err; ++ int continue_waiting = 0; ++ unsigned i; ++ ++ for (i = 1; i <= dev->nports; i++) ++ if (dev->ports[i - 1].state == PORT_STATE_WAITING_FOR_STABLE_POWER) ++ { ++ grub_uint64_t tm; ++ grub_uint32_t current_status = 0; ++ ++ /* Get the port status. */ ++ err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_IN ++ | GRUB_USB_REQTYPE_CLASS ++ | GRUB_USB_REQTYPE_TARGET_OTHER), ++ GRUB_USB_REQ_GET_STATUS, ++ 0, i, ++ sizeof (current_status), ++ (char *) ¤t_status); ++ if (err) ++ { ++ dev->ports[i - 1].state = PORT_STATE_FAILED_DEVICE; ++ continue; ++ } ++ tm = grub_get_time_ms (); ++ if (!(current_status & GRUB_USB_HUB_STATUS_PORT_CONNECTED)) ++ dev->ports[i - 1].soft_limit_time = tm + 250; ++ if (tm >= dev->ports[i - 1].soft_limit_time) ++ { ++ if (dev->controller.dev->pending_reset) ++ continue; ++ /* Now do reset of port. */ ++ grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT ++ | GRUB_USB_REQTYPE_CLASS ++ | GRUB_USB_REQTYPE_TARGET_OTHER), ++ GRUB_USB_REQ_SET_FEATURE, ++ GRUB_USB_HUB_FEATURE_PORT_RESET, ++ i, 0, 0); ++ dev->ports[i - 1].state = PORT_STATE_NORMAL; ++ grub_boot_time ("Resetting port %d", i); ++ ++ rescan = 1; ++ /* We cannot reset more than one device at the same time ! ++ * Resetting more devices together results in very bad ++ * situation: more than one device has default address 0 ++ * at the same time !!! ++ * Additionaly, we cannot perform another reset ++ * anywhere on the same OHCI controller until ++ * we will finish addressing of reseted device ! */ ++ dev->controller.dev->pending_reset = grub_get_time_ms () + 5000; ++ npending++; ++ continue; ++ } ++ if (tm >= dev->ports[i - 1].hard_limit_time) ++ { ++ dev->ports[i - 1].state = PORT_STATE_FAILED_DEVICE; ++ continue; ++ } ++ continue_waiting = 1; ++ } ++ return continue_waiting && dev->controller.dev->pending_reset == 0; ++} ++ + static void + poll_nonroot_hub (grub_usb_device_t dev) + { +@@ -356,7 +478,6 @@ poll_nonroot_hub (grub_usb_device_t dev) + unsigned i; + grub_uint8_t changed; + grub_size_t actual, len; +- int j, total; + + if (!dev->hub_transfer) + return; +@@ -382,9 +503,9 @@ poll_nonroot_hub (grub_usb_device_t dev) + for (i = 1; i <= dev->nports; i++) + { + grub_uint32_t status; +- grub_uint32_t current_status = 0; + +- if (!(changed & (1 << i))) ++ if (!(changed & (1 << i)) ++ || dev->ports[i - 1].state == PORT_STATE_WAITING_FOR_STABLE_POWER) + continue; + + /* Get the port status. */ +@@ -444,52 +565,10 @@ poll_nonroot_hub (grub_usb_device_t dev) + * There is also another thing - some devices have worse contacts + * and connected signal is unstable for some time - we should handle + * it - but prevent deadlock in case when device is too faulty... */ +- for (total = j = 0; (j < 250) && (total < 2000); j++, total++) +- { +- grub_millisleep (1); +- /* Get the port status. */ +- err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_IN +- | GRUB_USB_REQTYPE_CLASS +- | GRUB_USB_REQTYPE_TARGET_OTHER), +- GRUB_USB_REQ_GET_STATUS, +- 0, i, +- sizeof (current_status), +- (char *) ¤t_status); +- if (err) +- { +- total = 2000; +- break; +- } +- if (!(current_status & GRUB_USB_HUB_STATUS_PORT_CONNECTED)) +- j = 0; +- } +- +- grub_boot_time ("After the stable power wait portno=%d", i); +- +- grub_dprintf ("usb", "(non-root) total=%d\n", total); +- if (total >= 2000) +- continue; +- +- /* Now do reset of port. */ +- grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT +- | GRUB_USB_REQTYPE_CLASS +- | GRUB_USB_REQTYPE_TARGET_OTHER), +- GRUB_USB_REQ_SET_FEATURE, +- GRUB_USB_HUB_FEATURE_PORT_RESET, +- i, 0, 0); +- grub_boot_time ("Resetting port %d", i); +- +- rescan = 1; +- /* We cannot reset more than one device at the same time ! +- * Resetting more devices together results in very bad +- * situation: more than one device has default address 0 +- * at the same time !!! +- * Additionaly, we cannot perform another reset +- * anywhere on the same OHCI controller until +- * we will finish addressing of reseted device ! */ +- dev->controller.dev->pending_reset = grub_get_time_ms () + 5000; +- npending++; +- return; ++ dev->ports[i - 1].soft_limit_time = grub_get_time_ms () + 250; ++ dev->ports[i - 1].hard_limit_time = dev->ports[i - 1].soft_limit_time + 1750; ++ dev->ports[i - 1].state = PORT_STATE_WAITING_FOR_STABLE_POWER; ++ continue; + } + } + +@@ -580,6 +659,8 @@ grub_usb_poll_devices (int wait_for_completion) + } + } + ++ grub_boot_time ("Probing USB device driver"); ++ + while (1) + { + rescan = 0; +@@ -592,11 +673,26 @@ grub_usb_poll_devices (int wait_for_completion) + if (dev && dev->descdev.class == 0x09) + poll_nonroot_hub (dev); + } ++ ++ while (1) ++ { ++ int continue_waiting = 0; ++ for (i = 0; i < GRUB_USBHUB_MAX_DEVICES; i++) ++ { ++ grub_usb_device_t dev = grub_usb_devs[i]; ++ ++ if (dev && dev->descdev.class == 0x09) ++ continue_waiting = continue_waiting || wait_power_nonroot_hub (dev); ++ } ++ if (!continue_waiting) ++ break; ++ grub_millisleep (1); ++ } ++ + if (!(rescan || (npending && wait_for_completion))) + break; +- grub_millisleep (50); ++ grub_millisleep (25); + } +- + } + + int +diff --git a/include/grub/usb.h b/include/grub/usb.h +index 7164dd5..12a456b 100644 +--- a/include/grub/usb.h ++++ b/include/grub/usb.h +@@ -121,6 +121,8 @@ struct grub_usb_controller_dev + + grub_usb_speed_t (*detect_dev) (grub_usb_controller_t dev, int port, int *changed); + ++ struct grub_usb_hub_port *ports; ++ + /* Per controller flag - port reset pending, don't do another reset */ + grub_uint64_t pending_reset; + +@@ -170,6 +172,18 @@ struct grub_usb_configuration + struct grub_usb_interface interf[32]; + }; + ++struct grub_usb_hub_port ++{ ++ grub_uint64_t soft_limit_time; ++ grub_uint64_t hard_limit_time; ++ enum { ++ PORT_STATE_NORMAL = 0, ++ PORT_STATE_WAITING_FOR_STABLE_POWER = 1, ++ PORT_STATE_FAILED_DEVICE = 2, ++ PORT_STATE_STABLE_POWER = 3, ++ } state; ++}; ++ + struct grub_usb_device + { + /* The device descriptor of this device. */ +@@ -204,6 +218,8 @@ struct grub_usb_device + /* Number of hub ports. */ + unsigned nports; + ++ struct grub_usb_hub_port *ports; ++ + grub_usb_transfer_t hub_transfer; + + grub_uint32_t statuschange; +-- +1.8.1.4 + diff --git a/0215-include-grub-boottime.h-Add-missing-file.patch b/0215-include-grub-boottime.h-Add-missing-file.patch new file mode 100644 index 0000000..6bd18e8 --- /dev/null +++ b/0215-include-grub-boottime.h-Add-missing-file.patch @@ -0,0 +1,29 @@ +From 07cecc1a92518d0e2fb621f826befb14bb1413ca Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Wed, 20 Mar 2013 16:58:07 +0100 +Subject: [PATCH 215/364] * include/grub/boottime.h: Add missing file. + +--- + ChangeLog | 4 ++++ + include/grub/boottime.h | 0 + 2 files changed, 4 insertions(+) + create mode 100644 include/grub/boottime.h + +diff --git a/ChangeLog b/ChangeLog +index dd9c97a..0c28b11 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,7 @@ ++2013-03-20 Vladimir Serbinenko ++ ++ * include/grub/boottime.h: Add missing file. ++ + 2013-03-19 Vladimir Serbinenko + + Initialize USB ports in parallel to speed-up boot. +diff --git a/include/grub/boottime.h b/include/grub/boottime.h +new file mode 100644 +index 0000000..e69de29 +-- +1.8.1.4 + diff --git a/0216-Fix-a-conflict-between-ports-structures-with-2-contr.patch b/0216-Fix-a-conflict-between-ports-structures-with-2-contr.patch new file mode 100644 index 0000000..714ea61 --- /dev/null +++ b/0216-Fix-a-conflict-between-ports-structures-with-2-contr.patch @@ -0,0 +1,134 @@ +From 018defe9d63f3a44e87b3345a8e5daeaa389a2bf Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Wed, 20 Mar 2013 17:07:08 +0100 +Subject: [PATCH 216/364] Fix a conflict between ports structures with 2 + controllers of same kind. + +--- + ChangeLog | 5 +++++ + grub-core/bus/usb/usbhub.c | 39 ++++++++++++++++++++++----------------- + include/grub/usb.h | 2 -- + 3 files changed, 27 insertions(+), 19 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 0c28b11..0fcaa65 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,10 @@ + 2013-03-20 Vladimir Serbinenko + ++ Fix a conflict between ports structures with 2 controllers of ++ same kind. ++ ++2013-03-20 Vladimir Serbinenko ++ + * include/grub/boottime.h: Add missing file. + + 2013-03-19 Vladimir Serbinenko +diff --git a/grub-core/bus/usb/usbhub.c b/grub-core/bus/usb/usbhub.c +index d0be80d..fd7b94e 100644 +--- a/grub-core/bus/usb/usbhub.c ++++ b/grub-core/bus/usb/usbhub.c +@@ -37,6 +37,7 @@ struct grub_usb_hub + grub_usb_controller_t controller; + int nports; + struct grub_usb_device **devices; ++ struct grub_usb_hub_port *ports; + grub_usb_device_t dev; + }; + +@@ -263,11 +264,11 @@ grub_usb_controller_dev_register_iter (grub_usb_controller_t controller, void *d + /* Query the number of ports the root Hub has. */ + hub->nports = controller->dev->hubports (controller); + hub->devices = grub_zalloc (sizeof (hub->devices[0]) * hub->nports); +- usb->ports = grub_zalloc (sizeof (usb->ports[0]) * hub->nports); +- if (!hub->devices || !usb->ports) ++ hub->ports = grub_zalloc (sizeof (hub->ports[0]) * hub->nports); ++ if (!hub->devices || !hub->ports) + { + grub_free (hub->devices); +- grub_free (usb->ports); ++ grub_free (hub->ports); + grub_free (hub->controller); + grub_free (hub); + grub_print_error (); +@@ -323,33 +324,37 @@ grub_usb_controller_dev_register (grub_usb_controller_dev_t usb) + speed = hub->controller->dev->detect_dev (hub->controller, portno, + &changed); + +- if (usb->ports[portno].state == PORT_STATE_NORMAL ++ if (hub->ports[portno].state == PORT_STATE_NORMAL + && speed != GRUB_USB_SPEED_NONE) + { +- usb->ports[portno].soft_limit_time = grub_get_time_ms () + 250; +- usb->ports[portno].hard_limit_time = usb->ports[portno].soft_limit_time + 1750; +- usb->ports[portno].state = PORT_STATE_WAITING_FOR_STABLE_POWER; ++ hub->ports[portno].soft_limit_time = grub_get_time_ms () + 250; ++ hub->ports[portno].hard_limit_time = hub->ports[portno].soft_limit_time + 1750; ++ hub->ports[portno].state = PORT_STATE_WAITING_FOR_STABLE_POWER; ++ grub_boot_time ("Scheduling stable power wait for port %p:%d", ++ usb, portno); + continue_waiting++; + continue; + } + +- if (usb->ports[portno].state == PORT_STATE_WAITING_FOR_STABLE_POWER ++ if (hub->ports[portno].state == PORT_STATE_WAITING_FOR_STABLE_POWER + && speed == GRUB_USB_SPEED_NONE) + { +- usb->ports[portno].soft_limit_time = grub_get_time_ms () + 250; ++ hub->ports[portno].soft_limit_time = grub_get_time_ms () + 250; + continue; + } +- if (usb->ports[portno].state == PORT_STATE_WAITING_FOR_STABLE_POWER +- && grub_get_time_ms () > usb->ports[portno].soft_limit_time) ++ if (hub->ports[portno].state == PORT_STATE_WAITING_FOR_STABLE_POWER ++ && grub_get_time_ms () > hub->ports[portno].soft_limit_time) + { +- usb->ports[portno].state = PORT_STATE_STABLE_POWER; ++ hub->ports[portno].state = PORT_STATE_STABLE_POWER; ++ grub_boot_time ("Got stable power wait for port %p:%d", ++ usb, portno); + continue_waiting--; + continue; + } +- if (usb->ports[portno].state == PORT_STATE_WAITING_FOR_STABLE_POWER +- && grub_get_time_ms () > usb->ports[portno].hard_limit_time) ++ if (hub->ports[portno].state == PORT_STATE_WAITING_FOR_STABLE_POWER ++ && grub_get_time_ms () > hub->ports[portno].hard_limit_time) + { +- usb->ports[portno].state = PORT_STATE_FAILED_DEVICE; ++ hub->ports[portno].state = PORT_STATE_FAILED_DEVICE; + continue_waiting--; + continue; + } +@@ -365,11 +370,11 @@ grub_usb_controller_dev_register (grub_usb_controller_dev_t usb) + for (hub = hubs; hub; hub = hub->next) + if (hub->controller->dev == usb) + for (portno = 0; portno < hub->nports; portno++) +- if (usb->ports[portno].state == PORT_STATE_STABLE_POWER) ++ if (hub->ports[portno].state == PORT_STATE_STABLE_POWER) + { + grub_usb_speed_t speed; + int changed = 0; +- usb->ports[portno].state = PORT_STATE_NORMAL; ++ hub->ports[portno].state = PORT_STATE_NORMAL; + speed = hub->controller->dev->detect_dev (hub->controller, portno, &changed); + attach_root_port (hub, portno, speed); + } +diff --git a/include/grub/usb.h b/include/grub/usb.h +index 12a456b..9e2c221 100644 +--- a/include/grub/usb.h ++++ b/include/grub/usb.h +@@ -121,8 +121,6 @@ struct grub_usb_controller_dev + + grub_usb_speed_t (*detect_dev) (grub_usb_controller_t dev, int port, int *changed); + +- struct grub_usb_hub_port *ports; +- + /* Per controller flag - port reset pending, don't do another reset */ + grub_uint64_t pending_reset; + +-- +1.8.1.4 + diff --git a/0217-New-commands-cbmemc-lscoreboot-coreboot_boottime-to-.patch b/0217-New-commands-cbmemc-lscoreboot-coreboot_boottime-to-.patch new file mode 100644 index 0000000..bda4de7 --- /dev/null +++ b/0217-New-commands-cbmemc-lscoreboot-coreboot_boottime-to-.patch @@ -0,0 +1,604 @@ +From d060cd9ae53e59c0bf1e58f05c6ead1989b7d291 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Wed, 20 Mar 2013 17:13:31 +0100 +Subject: [PATCH 217/364] New commands cbmemc, lscoreboot, + coreboot_boottime to inspect coreboot tables content. Support for cbmemc. + +--- + ChangeLog | 5 + + grub-core/Makefile.am | 1 + + grub-core/Makefile.core.def | 18 ++++ + grub-core/commands/i386/coreboot/cb_timestamps.c | 118 +++++++++++++++++++++ + grub-core/commands/i386/coreboot/cbls.c | 128 +++++++++++++++++++++++ + grub-core/kern/i386/coreboot/mmap.c | 2 +- + grub-core/normal/term.c | 19 +++- + grub-core/term/i386/coreboot/cbmemc.c | 127 ++++++++++++++++++++++ + include/grub/i386/coreboot/lbio.h | 30 ++++++ + include/grub/normal.h | 3 + + 10 files changed, 446 insertions(+), 5 deletions(-) + create mode 100644 grub-core/commands/i386/coreboot/cb_timestamps.c + create mode 100644 grub-core/commands/i386/coreboot/cbls.c + create mode 100644 grub-core/term/i386/coreboot/cbmemc.c + +diff --git a/ChangeLog b/ChangeLog +index 0fcaa65..5bb93ed 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,10 @@ + 2013-03-20 Vladimir Serbinenko + ++ New commands cbmemc, lscoreboot, coreboot_boottime to inspect ++ coreboot tables content. Support for cbmemc. ++ ++2013-03-20 Vladimir Serbinenko ++ + Fix a conflict between ports structures with 2 controllers of + same kind. + +diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am +index 221466b..6f156e7 100644 +--- a/grub-core/Makefile.am ++++ b/grub-core/Makefile.am +@@ -110,6 +110,7 @@ endif + + if COND_i386_coreboot + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h ++KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/coreboot/lbio.h + KERNEL_HEADER_FILES += $(top_builddir)/include/grub/i386/pc/int.h + endif + +diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def +index 5c15f32..d851bc3 100644 +--- a/grub-core/Makefile.core.def ++++ b/grub-core/Makefile.core.def +@@ -519,6 +519,24 @@ module = { + }; + + module = { ++ name = cbtime; ++ common = commands/i386/coreboot/cb_timestamps.c; ++ enable = i386_coreboot; ++}; ++ ++module = { ++ name = cbls; ++ common = commands/i386/coreboot/cbls.c; ++ enable = i386_coreboot; ++}; ++ ++module = { ++ name = cbmemc; ++ common = term/i386/coreboot/cbmemc.c; ++ enable = i386_coreboot; ++}; ++ ++module = { + name = regexp; + common = commands/regexp.c; + common = commands/wildcard.c; +diff --git a/grub-core/commands/i386/coreboot/cb_timestamps.c b/grub-core/commands/i386/coreboot/cb_timestamps.c +new file mode 100644 +index 0000000..5299ad4 +--- /dev/null ++++ b/grub-core/commands/i386/coreboot/cb_timestamps.c +@@ -0,0 +1,118 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2013 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 ++ ++GRUB_MOD_LICENSE ("GPLv3+"); ++ ++static grub_uint32_t ++tsc2ms (grub_uint64_t tsc) ++{ ++ grub_uint64_t ah = tsc >> 32; ++ grub_uint64_t al = tsc & 0xffffffff; ++ ++ return ((al * grub_tsc_rate) >> 32) + ah * grub_tsc_rate; ++} ++ ++static const char *descs[] = { ++ [1] = "romstage", ++ [2] = "before RAM init", ++ [3] = "after RAM init", ++ [4] = "end of romstage", ++ [8] = "start of RAM copy", ++ [9] = "end of RAM copy", ++ [10] = "start of ramstage", ++ [30] = "device enumerate", ++ [40] = "device configure", ++ [50] = "device enable", ++ [60] = "device initialize", ++ [70] = "device done", ++ [75] = "CBMEM POST", ++ [80] = "writing tables", ++ [90] = "loading payload", ++ [98] = "wake jump", ++ [99] = "selfboot jump", ++}; ++ ++static int ++iterate_linuxbios_table (grub_linuxbios_table_item_t table_item, ++ void *data) ++{ ++ int *available = data; ++ grub_uint64_t last_tsc = 0; ++ struct grub_linuxbios_timestamp_table *ts_table; ++ unsigned i; ++ ++ if (table_item->tag != GRUB_LINUXBIOS_MEMBER_TIMESTAMPS) ++ return 0; ++ ++ *available = 1; ++ ts_table = (struct grub_linuxbios_timestamp_table *) (grub_addr_t) ++ *(grub_uint64_t *) (table_item + 1); ++ ++ for (i = 0; i < ts_table->used; i++) ++ { ++ grub_uint32_t tmabs = tsc2ms (ts_table->entries[i].tsc); ++ grub_uint32_t tmrel = tsc2ms (ts_table->entries[i].tsc - last_tsc); ++ last_tsc = ts_table->entries[i].tsc; ++ ++ grub_printf ("%3d.%03ds %2d.%03ds %02d %s\n", ++ tmabs / 1000, tmabs % 1000, tmrel / 1000, tmrel % 1000, ++ ts_table->entries[i].id, ++ (ts_table->entries[i].id < ARRAY_SIZE (descs) ++ && descs[ts_table->entries[i].id]) ++ ? descs[ts_table->entries[i].id] : ""); ++ } ++ return 1; ++} ++ ++ ++static grub_err_t ++grub_cmd_coreboot_boottime (struct grub_command *cmd __attribute__ ((unused)), ++ int argc __attribute__ ((unused)), ++ char *argv[] __attribute__ ((unused))) ++{ ++ int available = 0; ++ ++ grub_linuxbios_table_iterate (iterate_linuxbios_table, &available); ++ if (!available) ++ { ++ grub_puts_ (N_("No boot time statistics is available\n")); ++ return 0; ++ } ++ return 0; ++} ++ ++static grub_command_t cmd_boottime; ++ ++GRUB_MOD_INIT(cbtime) ++{ ++ cmd_boottime = ++ grub_register_command ("coreboot_boottime", grub_cmd_coreboot_boottime, ++ 0, N_("Get coreboot boot time statistics.")); ++} ++ ++GRUB_MOD_FINI(cbtime) ++{ ++ grub_unregister_command (cmd_boottime); ++} +diff --git a/grub-core/commands/i386/coreboot/cbls.c b/grub-core/commands/i386/coreboot/cbls.c +new file mode 100644 +index 0000000..dc46d55 +--- /dev/null ++++ b/grub-core/commands/i386/coreboot/cbls.c +@@ -0,0 +1,128 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2013 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 ++ ++GRUB_MOD_LICENSE ("GPLv3+"); ++ ++static const char *console_descs[] = { ++ "8250 UART", ++ "VGA", ++ "BTEXT", ++ "CBMEM console", ++ "SROM", ++ "EHCI debug", ++ "memory-mapped 8250 UART" ++}; ++ ++static const char *descs[] = { ++ [GRUB_LINUXBIOS_MEMBER_MEMORY] = "memory map (`lsmmap' to list)", ++ [GRUB_LINUXBIOS_MEMBER_MAINBOARD] = "mainboard", ++ [4] = "version", ++ [5] = "extra version", ++ [6] = "build", ++ [7] = "compile time", ++ [8] = "compile by", ++ [9] = "compile host", ++ [0xa] = "compile domain", ++ [0xb] = "compiler", ++ [0xc] = "linker", ++ [0xd] = "assembler", ++ [0xf] = "serial", ++ [GRUB_LINUXBIOS_MEMBER_CONSOLE] = "console", ++ [0x12] = "framebuffer", ++ [0x13] = "GPIO", ++ [0x15] = "VDAT", ++ [GRUB_LINUXBIOS_MEMBER_TIMESTAMPS] = "timestamps (`coreboot_boottime' to list)", ++ [GRUB_LINUXBIOS_MEMBER_CBMEMC] = "CBMEM console (`cbmem' to list)", ++ [0x18] = "MRC cache", ++ [0x19] = "VBNV", ++ [0xc8] = "CMOS option table", ++ [0xc9] = "CMOS option", ++ [0xca] = "CMOS option enum", ++ [0xcb] = "CMOS option defaults", ++ [0xcc] = "CMOS checksum", ++}; ++ ++static int ++iterate_linuxbios_table (grub_linuxbios_table_item_t table_item, ++ void *data __attribute__ ((unused))) ++{ ++ if (table_item->tag < ARRAY_SIZE (descs) && descs[table_item->tag]) ++ grub_printf ("tag=%02x size=%02x %s", ++ table_item->tag, table_item->size, descs[table_item->tag]); ++ else ++ grub_printf ("tag=%02x size=%02x", ++ table_item->tag, table_item->size); ++ ++ switch (table_item->tag) ++ { ++ case GRUB_LINUXBIOS_MEMBER_MAINBOARD: ++ { ++ struct grub_linuxbios_mainboard *mb; ++ mb = (struct grub_linuxbios_mainboard *) (table_item + 1); ++ grub_printf (": vendor=`%s' part_number=`%s'", ++ mb->strings + mb->vendor, ++ mb->strings + mb->part_number); ++ break; ++ } ++ case 0x04 ... 0x0d: ++ grub_printf (": `%s'", (char *) (table_item + 1)); ++ break; ++ case GRUB_LINUXBIOS_MEMBER_CONSOLE: ++ { ++ grub_uint16_t *val = (grub_uint16_t *) (table_item + 1); ++ grub_printf (": id=%d", *val); ++ if (*val < ARRAY_SIZE (console_descs) ++ && console_descs[*val]) ++ grub_printf (" %s", console_descs[*val]); ++ } ++ } ++ grub_printf ("\n"); ++ ++ return 0; ++} ++ ++ ++static grub_err_t ++grub_cmd_lscoreboot (struct grub_command *cmd __attribute__ ((unused)), ++ int argc __attribute__ ((unused)), ++ char *argv[] __attribute__ ((unused))) ++{ ++ grub_linuxbios_table_iterate (iterate_linuxbios_table, 0); ++ return 0; ++} ++ ++static grub_command_t cmd; ++ ++GRUB_MOD_INIT(cbls) ++{ ++ cmd = ++ grub_register_command ("lscoreboot", grub_cmd_lscoreboot, ++ 0, N_("List coreboot tables.")); ++} ++ ++GRUB_MOD_FINI(cbls) ++{ ++ grub_unregister_command (cmd); ++} +diff --git a/grub-core/kern/i386/coreboot/mmap.c b/grub-core/kern/i386/coreboot/mmap.c +index 47efb72..6a14d29 100644 +--- a/grub-core/kern/i386/coreboot/mmap.c ++++ b/grub-core/kern/i386/coreboot/mmap.c +@@ -32,7 +32,7 @@ check_signature (grub_linuxbios_table_header_t tbl_header) + return 0; + } + +-static grub_err_t ++grub_err_t + grub_linuxbios_table_iterate (int (*hook) (grub_linuxbios_table_item_t, + void *), + void *hook_data) +diff --git a/grub-core/normal/term.c b/grub-core/normal/term.c +index f89e5d2..32deba3 100644 +--- a/grub-core/normal/term.c ++++ b/grub-core/normal/term.c +@@ -979,20 +979,21 @@ grub_ucs4_count_lines (const grub_uint32_t * str, + } + + void +-grub_xputs_normal (const char *str) ++grub_xnputs (const char *str, grub_size_t msg_len) + { + grub_uint32_t *unicode_str = NULL, *unicode_last_position; + int backlog = 0; + grub_term_output_t term; + + grub_error_push (); +- grub_utf8_to_ucs4_alloc (str, &unicode_str, +- &unicode_last_position); ++ ++ unicode_str = grub_malloc (msg_len * sizeof (grub_uint32_t)); ++ + grub_error_pop (); + + if (!unicode_str) + { +- for (; *str; str++) ++ for (; msg_len--; str++, msg_len++) + { + struct grub_unicode_glyph c = + { +@@ -1021,6 +1022,10 @@ grub_xputs_normal (const char *str) + return; + } + ++ msg_len = grub_utf8_to_ucs4 (unicode_str, msg_len, ++ (grub_uint8_t *) str, -1, 0); ++ unicode_last_position = unicode_str + msg_len; ++ + FOR_ACTIVE_TERM_OUTPUTS(term) + { + int cur; +@@ -1045,6 +1050,12 @@ grub_xputs_normal (const char *str) + } + + void ++grub_xputs_normal (const char *str) ++{ ++ grub_xnputs (str, grub_strlen (str)); ++} ++ ++void + grub_cls (void) + { + struct grub_term_output *term; +diff --git a/grub-core/term/i386/coreboot/cbmemc.c b/grub-core/term/i386/coreboot/cbmemc.c +new file mode 100644 +index 0000000..c58d671 +--- /dev/null ++++ b/grub-core/term/i386/coreboot/cbmemc.c +@@ -0,0 +1,127 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2013 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_MOD_LICENSE ("GPLv3+"); ++ ++struct grub_linuxbios_cbmemc ++{ ++ grub_uint32_t size; ++ grub_uint32_t pointer; ++ char data[0]; ++}; ++ ++static struct grub_linuxbios_cbmemc *cbmemc; ++ ++static void ++put (struct grub_term_output *term __attribute__ ((unused)), const int c) ++{ ++ if (!cbmemc) ++ return; ++ if (cbmemc->pointer < cbmemc->size) ++ cbmemc->data[cbmemc->pointer] = c; ++ cbmemc->pointer++; ++} ++ ++struct grub_terminfo_output_state grub_cbmemc_terminfo_output = ++ { ++ .put = put, ++ .width = 80, ++ .height = 24 ++ }; ++ ++static struct grub_term_output grub_cbmemc_term_output = ++ { ++ .name = "cbmemc", ++ .init = grub_terminfo_output_init, ++ .fini = 0, ++ .putchar = grub_terminfo_putchar, ++ .getxy = grub_terminfo_getxy, ++ .getwh = grub_terminfo_getwh, ++ .gotoxy = grub_terminfo_gotoxy, ++ .cls = grub_terminfo_cls, ++ .setcolorstate = grub_terminfo_setcolorstate, ++ .setcursor = grub_terminfo_setcursor, ++ .flags = GRUB_TERM_CODE_TYPE_ASCII, ++ .data = &grub_cbmemc_terminfo_output, ++ }; ++ ++static int ++iterate_linuxbios_table (grub_linuxbios_table_item_t table_item, ++ void *data __attribute__ ((unused))) ++{ ++ if (table_item->tag != GRUB_LINUXBIOS_MEMBER_CBMEMC) ++ return 0; ++ cbmemc = (struct grub_linuxbios_cbmemc *) (grub_addr_t) ++ *(grub_uint64_t *) (table_item + 1); ++ return 1; ++} ++ ++static grub_err_t ++grub_cmd_cbmemc (struct grub_command *cmd __attribute__ ((unused)), ++ int argc __attribute__ ((unused)), ++ char *argv[] __attribute__ ((unused))) ++{ ++ grub_size_t len; ++ char *str; ++ struct grub_linuxbios_cbmemc *cbmemc_saved; ++ ++ if (!cbmemc) ++ return grub_error (GRUB_ERR_IO, "no CBMEM console found"); ++ ++ len = cbmemc->pointer; ++ if (len > cbmemc->size) ++ len = cbmemc->size; ++ str = cbmemc->data; ++ cbmemc_saved = cbmemc; ++ cbmemc = 0; ++ grub_xnputs (str, len); ++ cbmemc = cbmemc_saved; ++ return 0; ++} ++ ++static grub_command_t cmd; ++ ++GRUB_MOD_INIT (cbmemc) ++{ ++ grub_linuxbios_table_iterate (iterate_linuxbios_table, 0); ++ ++ if (cbmemc) ++ grub_term_register_output ("cbmemc", &grub_cbmemc_term_output); ++ ++ cmd = ++ grub_register_command ("cbmemc", grub_cmd_cbmemc, ++ 0, N_("Show CBMEM console content.")); ++} ++ ++ ++GRUB_MOD_FINI (cbmemc) ++{ ++ grub_term_unregister_output (&grub_cbmemc_term_output); ++ grub_unregister_command (cmd); ++} +diff --git a/include/grub/i386/coreboot/lbio.h b/include/grub/i386/coreboot/lbio.h +index bac5492..b4150f4 100644 +--- a/include/grub/i386/coreboot/lbio.h ++++ b/include/grub/i386/coreboot/lbio.h +@@ -31,11 +31,36 @@ struct grub_linuxbios_table_header + }; + typedef struct grub_linuxbios_table_header *grub_linuxbios_table_header_t; + ++struct grub_linuxbios_timestamp_entry ++{ ++ grub_uint32_t id; ++ grub_uint64_t tsc; ++} __attribute__((packed)); ++ ++struct grub_linuxbios_timestamp_table ++{ ++ grub_uint64_t base_tsc; ++ grub_uint32_t capacity; ++ grub_uint32_t used; ++ struct grub_linuxbios_timestamp_entry entries[0]; ++} __attribute__((packed)); ++ ++struct grub_linuxbios_mainboard ++{ ++ grub_uint8_t vendor; ++ grub_uint8_t part_number; ++ char strings[0]; ++}; ++ + struct grub_linuxbios_table_item + { + #define GRUB_LINUXBIOS_MEMBER_UNUSED 0x00 + #define GRUB_LINUXBIOS_MEMBER_MEMORY 0x01 ++#define GRUB_LINUXBIOS_MEMBER_MAINBOARD 0x03 ++#define GRUB_LINUXBIOS_MEMBER_CONSOLE 0x10 + #define GRUB_LINUXBIOS_MEMBER_LINK 0x11 ++#define GRUB_LINUXBIOS_MEMBER_TIMESTAMPS 0x16 ++#define GRUB_LINUXBIOS_MEMBER_CBMEMC 0x17 + grub_uint32_t tag; + grub_uint32_t size; + }; +@@ -50,4 +75,9 @@ struct grub_linuxbios_mem_region + }; + typedef struct grub_linuxbios_mem_region *mem_region_t; + ++grub_err_t ++EXPORT_FUNC(grub_linuxbios_table_iterate) (int (*hook) (grub_linuxbios_table_item_t, ++ void *), ++ void *hook_data); ++ + #endif +diff --git a/include/grub/normal.h b/include/grub/normal.h +index 416faa4..4fcc3da 100644 +--- a/include/grub/normal.h ++++ b/include/grub/normal.h +@@ -141,6 +141,9 @@ void grub_normal_free_menu (grub_menu_t menu); + void grub_normal_auth_init (void); + void grub_normal_auth_fini (void); + ++void ++grub_xnputs (const char *str, grub_size_t msg_len); ++ + grub_command_t + grub_dyncmd_get_cmd (grub_command_t cmd); + +-- +1.8.1.4 + diff --git a/0218-grub-core-commands-boottime.c-Fix-copyright-header.patch b/0218-grub-core-commands-boottime.c-Fix-copyright-header.patch new file mode 100644 index 0000000..cbedfcc --- /dev/null +++ b/0218-grub-core-commands-boottime.c-Fix-copyright-header.patch @@ -0,0 +1,41 @@ +From d1318e17015a2dd058e06b4769d4bb67a95f832b Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Wed, 20 Mar 2013 17:16:35 +0100 +Subject: [PATCH 218/364] * grub-core/commands/boottime.c: Fix copyright + header. + +--- + ChangeLog | 4 ++++ + grub-core/commands/boottime.c | 3 +-- + 2 files changed, 5 insertions(+), 2 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 5bb93ed..69c764b 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,9 @@ + 2013-03-20 Vladimir Serbinenko + ++ * grub-core/commands/boottime.c: Fix copyright header. ++ ++2013-03-20 Vladimir Serbinenko ++ + New commands cbmemc, lscoreboot, coreboot_boottime to inspect + coreboot tables content. Support for cbmemc. + +diff --git a/grub-core/commands/boottime.c b/grub-core/commands/boottime.c +index cd7f70a..7370d27 100644 +--- a/grub-core/commands/boottime.c ++++ b/grub-core/commands/boottime.c +@@ -1,7 +1,6 @@ +-/* cacheinfo.c - disk cache statistics */ + /* + * GRUB -- GRand Unified Bootloader +- * Copyright (C) 2008,2010 Free Software Foundation, Inc. ++ * Copyright (C) 2013 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 +-- +1.8.1.4 + diff --git a/0219-Slight-improve-in-USB-related-boot-time-checkpoints.patch b/0219-Slight-improve-in-USB-related-boot-time-checkpoints.patch new file mode 100644 index 0000000..ff3e398 --- /dev/null +++ b/0219-Slight-improve-in-USB-related-boot-time-checkpoints.patch @@ -0,0 +1,81 @@ +From d0340ebbae7c69cc2ba5c7d8001c674f90ae2265 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Wed, 20 Mar 2013 17:21:13 +0100 +Subject: [PATCH 219/364] Slight improve in USB-related boot-time + checkpoints. + +--- + ChangeLog | 4 ++++ + grub-core/bus/usb/ehci.c | 3 ++- + grub-core/bus/usb/usbhub.c | 6 +++--- + 3 files changed, 9 insertions(+), 4 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 69c764b..5e6369c 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,9 @@ + 2013-03-20 Vladimir Serbinenko + ++ Slight improve in USB-related boot-time checkpoints. ++ ++2013-03-20 Vladimir Serbinenko ++ + * grub-core/commands/boottime.c: Fix copyright header. + + 2013-03-20 Vladimir Serbinenko +diff --git a/grub-core/bus/usb/ehci.c b/grub-core/bus/usb/ehci.c +index a5a24af..e902fcd 100644 +--- a/grub-core/bus/usb/ehci.c ++++ b/grub-core/bus/usb/ehci.c +@@ -1699,6 +1699,8 @@ grub_ehci_portstatus (grub_usb_controller_t dev, + + grub_dprintf ("ehci", "portstatus: enable\n"); + ++ grub_boot_time ("Resetting port %d", port); ++ + /* Now we will do reset - if HIGH speed device connected, it will + * result in Enabled state, otherwise port remains disabled. */ + /* Set RESET bit for 50ms */ +@@ -1708,7 +1710,6 @@ grub_ehci_portstatus (grub_usb_controller_t dev, + /* Reset RESET bit and wait for the end of reset */ + grub_ehci_port_resbits (e, port, GRUB_EHCI_PORT_RESET); + endtime = grub_get_time_ms () + 1000; +- grub_boot_time ("Resetting port %d", port); + while (grub_ehci_port_read (e, port) & GRUB_EHCI_PORT_RESET) + if (grub_get_time_ms () > endtime) + return grub_error (GRUB_ERR_IO, +diff --git a/grub-core/bus/usb/usbhub.c b/grub-core/bus/usb/usbhub.c +index fd7b94e..6fc9d02 100644 +--- a/grub-core/bus/usb/usbhub.c ++++ b/grub-core/bus/usb/usbhub.c +@@ -452,7 +452,7 @@ wait_power_nonroot_hub (grub_usb_device_t dev) + GRUB_USB_HUB_FEATURE_PORT_RESET, + i, 0, 0); + dev->ports[i - 1].state = PORT_STATE_NORMAL; +- grub_boot_time ("Resetting port %d", i); ++ grub_boot_time ("Resetting port %p:%d", dev, i - 1); + + rescan = 1; + /* We cannot reset more than one device at the same time ! +@@ -573,6 +573,8 @@ poll_nonroot_hub (grub_usb_device_t dev) + dev->ports[i - 1].soft_limit_time = grub_get_time_ms () + 250; + dev->ports[i - 1].hard_limit_time = dev->ports[i - 1].soft_limit_time + 1750; + dev->ports[i - 1].state = PORT_STATE_WAITING_FOR_STABLE_POWER; ++ grub_boot_time ("Scheduling stable power wait for port %p:%d", ++ dev, i - 1); + continue; + } + } +@@ -664,8 +666,6 @@ grub_usb_poll_devices (int wait_for_completion) + } + } + +- grub_boot_time ("Probing USB device driver"); +- + while (1) + { + rescan = 0; +-- +1.8.1.4 + diff --git a/0220-grub-core-commands-verify.c-hashes-Add-several-hashe.patch b/0220-grub-core-commands-verify.c-hashes-Add-several-hashe.patch new file mode 100644 index 0000000..197b1cd --- /dev/null +++ b/0220-grub-core-commands-verify.c-hashes-Add-several-hashe.patch @@ -0,0 +1,45 @@ +From d7fd8ed25c43bd6d83e9b549a329feebaec79946 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Wed, 20 Mar 2013 17:24:39 +0100 +Subject: [PATCH 220/364] * grub-core/commands/verify.c (hashes): Add + several hashes from the spec. + +--- + ChangeLog | 5 +++++ + grub-core/commands/verify.c | 5 ++++- + 2 files changed, 9 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index 5e6369c..bcc2f92 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,10 @@ + 2013-03-20 Vladimir Serbinenko + ++ * grub-core/commands/verify.c (hashes): Add several hashes ++ from the spec. ++ ++2013-03-20 Vladimir Serbinenko ++ + Slight improve in USB-related boot-time checkpoints. + + 2013-03-20 Vladimir Serbinenko +diff --git a/grub-core/commands/verify.c b/grub-core/commands/verify.c +index 38bb941..6c0b580 100644 +--- a/grub-core/commands/verify.c ++++ b/grub-core/commands/verify.c +@@ -124,7 +124,10 @@ struct signature_v4_header + + const char *hashes[] = { + "md5", "sha1", "ripemd160", +- [0x0a] = "sha512" ++ [0x08] = "sha256", ++ [0x09] = "sha384", ++ [0x0a] = "sha512", ++ [0x0b] = "sha224" + }; + + struct +-- +1.8.1.4 + diff --git a/0221-po-POTFILES.in-Regenerate.patch b/0221-po-POTFILES.in-Regenerate.patch new file mode 100644 index 0000000..d448fea --- /dev/null +++ b/0221-po-POTFILES.in-Regenerate.patch @@ -0,0 +1,232 @@ +From 39ad20fe77008cdcbab99329d34b4dee56c26dcd Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Thu, 21 Mar 2013 21:54:31 +0100 +Subject: [PATCH 221/364] * po/POTFILES.in: Regenerate. + +--- + ChangeLog | 4 +++ + po/POTFILES.in | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- + 2 files changed, 84 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index bcc2f92..8d8c590 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,7 @@ ++2013-03-21 Vladimir Serbinenko ++ ++ * po/POTFILES.in: Regenerate. ++ + 2013-03-20 Vladimir Serbinenko + + * grub-core/commands/verify.c (hashes): Add several hashes +diff --git a/po/POTFILES.in b/po/POTFILES.in +index 01cc53c..ec79914 100644 +--- a/po/POTFILES.in ++++ b/po/POTFILES.in +@@ -14,6 +14,7 @@ + ./grub-core/bus/usb/serial/common.c + ./grub-core/bus/usb/serial/ftdi.c + ./grub-core/bus/usb/serial/pl2303.c ++./grub-core/bus/usb/serial/usbdebug_late.c + ./grub-core/bus/usb/uhci.c + ./grub-core/bus/usb/usb.c + ./grub-core/bus/usb/usbhub.c +@@ -23,6 +24,7 @@ + ./grub-core/commands/arc/lsdev.c + ./grub-core/commands/blocklist.c + ./grub-core/commands/boot.c ++./grub-core/commands/boottime.c + ./grub-core/commands/cacheinfo.c + ./grub-core/commands/cat.c + ./grub-core/commands/cmp.c +@@ -30,6 +32,7 @@ + ./grub-core/commands/date.c + ./grub-core/commands/echo.c + ./grub-core/commands/efi/acpi.c ++./grub-core/commands/efi/efifwsetup.c + ./grub-core/commands/efi/fixvideo.c + ./grub-core/commands/efi/loadbios.c + ./grub-core/commands/efi/lsefi.c +@@ -43,7 +46,10 @@ + ./grub-core/commands/hdparm.c + ./grub-core/commands/help.c + ./grub-core/commands/hexdump.c ++./grub-core/commands/i386/cmosdump.c + ./grub-core/commands/i386/cmostest.c ++./grub-core/commands/i386/coreboot/cbls.c ++./grub-core/commands/i386/coreboot/cb_timestamps.c + ./grub-core/commands/i386/cpuid.c + ./grub-core/commands/i386/pc/acpi.c + ./grub-core/commands/i386/pc/drivemap.c +@@ -68,6 +74,7 @@ + ./grub-core/commands/parttool.c + ./grub-core/commands/password.c + ./grub-core/commands/password_pbkdf2.c ++./grub-core/commands/pcidump.c + ./grub-core/commands/probe.c + ./grub-core/commands/read.c + ./grub-core/commands/reboot.c +@@ -85,6 +92,7 @@ + ./grub-core/commands/time.c + ./grub-core/commands/true.c + ./grub-core/commands/usbtest.c ++./grub-core/commands/verify.c + ./grub-core/commands/videoinfo.c + ./grub-core/commands/videotest.c + ./grub-core/commands/wildcard.c +@@ -167,6 +175,7 @@ + ./grub-core/fs/tar.c + ./grub-core/fs/udf.c + ./grub-core/fs/ufs2.c ++./grub-core/fs/ufs_be.c + ./grub-core/fs/ufs.c + ./grub-core/fs/xfs.c + ./grub-core/fs/zfs/zfs.c +@@ -304,6 +313,7 @@ + ./grub-core/kern/efi/init.c + ./grub-core/kern/efi/mm.c + ./grub-core/kern/elf.c ++./grub-core/kern/elfXX.c + ./grub-core/kern/emu/argp_common.c + ./grub-core/kern/emu/cache.c + ./grub-core/kern/emu/full.c +@@ -327,7 +337,6 @@ + ./grub-core/kern/i386/multiboot_mmap.c + ./grub-core/kern/i386/pc/init.c + ./grub-core/kern/i386/pc/mmap.c +-./grub-core/kern/i386/pit.c + ./grub-core/kern/i386/qemu/mmap.c + ./grub-core/kern/i386/tsc.c + ./grub-core/kern/ia64/dl.c +@@ -420,10 +429,71 @@ + ./grub-core/lib/libgcrypt/cipher/sha1.c + ./grub-core/lib/libgcrypt/cipher/sha256.c + ./grub-core/lib/libgcrypt/cipher/sha512.c ++./grub-core/lib/libgcrypt/cipher/test-getrusage.c + ./grub-core/lib/libgcrypt/cipher/tiger.c + ./grub-core/lib/libgcrypt/cipher/twofish.c + ./grub-core/lib/libgcrypt/cipher/whirlpool.c ++./grub-core/lib/libgcrypt/mpi/ec.c ++./grub-core/lib/libgcrypt/mpi/generic/mpi-asm-defs.h ++./grub-core/lib/libgcrypt/mpi/generic/mpih-add1.c ++./grub-core/lib/libgcrypt/mpi/generic/mpih-lshift.c ++./grub-core/lib/libgcrypt/mpi/generic/mpih-mul1.c ++./grub-core/lib/libgcrypt/mpi/generic/mpih-mul2.c ++./grub-core/lib/libgcrypt/mpi/generic/mpih-mul3.c ++./grub-core/lib/libgcrypt/mpi/generic/mpih-rshift.c ++./grub-core/lib/libgcrypt/mpi/generic/mpih-sub1.c ++./grub-core/lib/libgcrypt/mpi/generic/udiv-w-sdiv.c ++./grub-core/lib/libgcrypt/mpi/i386/syntax.h ++./grub-core/lib/libgcrypt/mpi/longlong.h ++./grub-core/lib/libgcrypt/mpi/m68k/syntax.h ++./grub-core/lib/libgcrypt/mpi/mips3/mpi-asm-defs.h ++./grub-core/lib/libgcrypt/mpi/mpi-add.c ++./grub-core/lib/libgcrypt/mpi/mpi-bit.c ++./grub-core/lib/libgcrypt/mpi/mpi-cmp.c ++./grub-core/lib/libgcrypt/mpi/mpicoder.c ++./grub-core/lib/libgcrypt/mpi/mpi-div.c ++./grub-core/lib/libgcrypt/mpi/mpi-gcd.c ++./grub-core/lib/libgcrypt/mpi/mpih-div.c ++./grub-core/lib/libgcrypt/mpi/mpih-mul.c ++./grub-core/lib/libgcrypt/mpi/mpi-inline.c ++./grub-core/lib/libgcrypt/mpi/mpi-inline.h ++./grub-core/lib/libgcrypt/mpi/mpi-internal.h ++./grub-core/lib/libgcrypt/mpi/mpi-inv.c ++./grub-core/lib/libgcrypt/mpi/mpi-mod.c ++./grub-core/lib/libgcrypt/mpi/mpi-mpow.c ++./grub-core/lib/libgcrypt/mpi/mpi-mul.c ++./grub-core/lib/libgcrypt/mpi/mpi-pow.c ++./grub-core/lib/libgcrypt/mpi/mpi-scan.c ++./grub-core/lib/libgcrypt/mpi/mpiutil.c ++./grub-core/lib/libgcrypt/mpi/powerpc32/syntax.h ++./grub-core/lib/libgcrypt/src/ath.c ++./grub-core/lib/libgcrypt/src/ath.h ++./grub-core/lib/libgcrypt/src/cipher.h ++./grub-core/lib/libgcrypt/src/cipher-proto.h ++./grub-core/lib/libgcrypt/src/dumpsexp.c ++./grub-core/lib/libgcrypt/src/fips.c ++./grub-core/lib/libgcrypt/src/g10lib.h ++./grub-core/lib/libgcrypt/src/gcrypt-module.h ++./grub-core/lib/libgcrypt/src/gcryptrnd.c ++./grub-core/lib/libgcrypt/src/getrandom.c ++./grub-core/lib/libgcrypt/src/global.c ++./grub-core/lib/libgcrypt/src/hmac256.c ++./grub-core/lib/libgcrypt/src/hmac256.h ++./grub-core/lib/libgcrypt/src/hwfeatures.c ++./grub-core/lib/libgcrypt/src/misc.c ++./grub-core/lib/libgcrypt/src/missing-string.c ++./grub-core/lib/libgcrypt/src/module.c ++./grub-core/lib/libgcrypt/src/mpi.h ++./grub-core/lib/libgcrypt/src/secmem.c ++./grub-core/lib/libgcrypt/src/secmem.h ++./grub-core/lib/libgcrypt/src/sexp.c ++./grub-core/lib/libgcrypt/src/stdmem.c ++./grub-core/lib/libgcrypt/src/stdmem.h ++./grub-core/lib/libgcrypt/src/types.h ++./grub-core/lib/libgcrypt/src/visibility.c ++./grub-core/lib/libgcrypt/src/visibility.h + ./grub-core/lib/libgcrypt_wrap/cipher_wrap.h ++./grub-core/lib/libgcrypt_wrap/mem.c + ./grub-core/lib/LzFind.c + ./grub-core/lib/LzmaDec.c + ./grub-core/lib/LzmaEnc.c +@@ -558,14 +628,17 @@ + ./grub-core/term/efi/serial.c + ./grub-core/term/emu/console.c + ./grub-core/term/gfxterm.c ++./grub-core/term/i386/coreboot/cbmemc.c + ./grub-core/term/i386/pc/console.c + ./grub-core/term/i386/pc/mda_text.c + ./grub-core/term/i386/pc/vga_text.c + ./grub-core/term/ieee1275/console.c + ./grub-core/term/ieee1275/escc.c + ./grub-core/term/ieee1275/serial.c ++./grub-core/term/morse.c + ./grub-core/term/ns8250.c + ./grub-core/term/serial.c ++./grub-core/term/spkmodem.c + ./grub-core/term/terminfo.c + ./grub-core/term/tparm.c + ./grub-core/term/usb_keyboard.c +@@ -609,6 +682,7 @@ + ./include/grub/backtrace.h + ./include/grub/bitmap.h + ./include/grub/bitmap_scale.h ++./include/grub/boottime.h + ./include/grub/bsdlabel.h + ./include/grub/bufio.h + ./include/grub/cache.h +@@ -658,6 +732,8 @@ + ./include/grub/font.h + ./include/grub/fs.h + ./include/grub/fshelp.h ++./include/grub/gcrypt/gpg-error.h ++./include/grub/gcry/types.h + ./include/grub/gdb.h + ./include/grub/gfxmenu_model.h + ./include/grub/gfxmenu_view.h +@@ -829,6 +905,7 @@ + ./include/grub/powerpc/time.h + ./include/grub/powerpc/types.h + ./include/grub/priority_queue.h ++./include/grub/pubkey.h + ./include/grub/reader.h + ./include/grub/reed_solomon.h + ./include/grub/relocator.h +@@ -847,6 +924,7 @@ + ./include/grub/sparc64/setjmp.h + ./include/grub/sparc64/time.h + ./include/grub/sparc64/types.h ++./include/grub/speaker.h + ./include/grub/symbol.h + ./include/grub/term.h + ./include/grub/terminfo.h +@@ -933,3 +1011,4 @@ + ./util/misc.c + ./util/raid.c + ./util/resolve.c ++./util/spkmodem-recv.c +-- +1.8.1.4 + diff --git a/0222-grub-core-commands-i386-coreboot-cbls.c-Fix-typos-an.patch b/0222-grub-core-commands-i386-coreboot-cbls.c-Fix-typos-an.patch new file mode 100644 index 0000000..96fb035 --- /dev/null +++ b/0222-grub-core-commands-i386-coreboot-cbls.c-Fix-typos-an.patch @@ -0,0 +1,49 @@ +From 20c550c1de7da63334394e04474f89f3378412cc Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Fri, 22 Mar 2013 14:06:48 +0100 +Subject: [PATCH 222/364] * grub-core/commands/i386/coreboot/cbls.c: Fix + typos and wrong description. + +--- + ChangeLog | 5 +++++ + grub-core/commands/i386/coreboot/cbls.c | 4 ++-- + 2 files changed, 7 insertions(+), 2 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 8d8c590..4a5b683 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,8 @@ ++2013-03-22 Vladimir Serbinenko ++ ++ * grub-core/commands/i386/coreboot/cbls.c: Fix typos and wrong ++ description. ++ + 2013-03-21 Vladimir Serbinenko + + * po/POTFILES.in: Regenerate. +diff --git a/grub-core/commands/i386/coreboot/cbls.c b/grub-core/commands/i386/coreboot/cbls.c +index dc46d55..151f9e8 100644 +--- a/grub-core/commands/i386/coreboot/cbls.c ++++ b/grub-core/commands/i386/coreboot/cbls.c +@@ -29,7 +29,7 @@ static const char *console_descs[] = { + "8250 UART", + "VGA", + "BTEXT", +- "CBMEM console", ++ "log buffer console", + "SROM", + "EHCI debug", + "memory-mapped 8250 UART" +@@ -54,7 +54,7 @@ static const char *descs[] = { + [0x13] = "GPIO", + [0x15] = "VDAT", + [GRUB_LINUXBIOS_MEMBER_TIMESTAMPS] = "timestamps (`coreboot_boottime' to list)", +- [GRUB_LINUXBIOS_MEMBER_CBMEMC] = "CBMEM console (`cbmem' to list)", ++ [GRUB_LINUXBIOS_MEMBER_CBMEMC] = "CBMEM console (`cbmemc' to list)", + [0x18] = "MRC cache", + [0x19] = "VBNV", + [0xc8] = "CMOS option table", +-- +1.8.1.4 + diff --git a/0223-Add-ability-to-generate-newc-additions-on-runtime.patch b/0223-Add-ability-to-generate-newc-additions-on-runtime.patch new file mode 100644 index 0000000..b064bc5 --- /dev/null +++ b/0223-Add-ability-to-generate-newc-additions-on-runtime.patch @@ -0,0 +1,888 @@ +From 78ea5ad1d1b80e3534d8ceabbf23ba23a62fd22f Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Fri, 22 Mar 2013 21:01:28 +0100 +Subject: [PATCH 223/364] Add ability to generate newc additions on + runtime. + +--- + ChangeLog | 4 + + grub-core/Makefile.core.def | 2 + + grub-core/loader/i386/linux.c | 40 +--- + grub-core/loader/i386/pc/linux.c | 40 +--- + grub-core/loader/ia64/efi/linux.c | 42 +---- + grub-core/loader/linux.c | 294 ++++++++++++++++++++++++++++++ + grub-core/loader/mips/linux.c | 40 +--- + grub-core/loader/powerpc/ieee1275/linux.c | 41 +---- + grub-core/loader/sparc64/ieee1275/linux.c | 40 +--- + include/grub/linux.h | 24 +++ + 10 files changed, 366 insertions(+), 201 deletions(-) + create mode 100644 grub-core/loader/linux.c + create mode 100644 include/grub/linux.h + +diff --git a/ChangeLog b/ChangeLog +index 4a5b683..5582e13 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,9 @@ + 2013-03-22 Vladimir Serbinenko + ++ Add ability to generate newc additions on runtime. ++ ++2013-03-22 Vladimir Serbinenko ++ + * grub-core/commands/i386/coreboot/cbls.c: Fix typos and wrong + description. + +diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def +index d851bc3..a614b22 100644 +--- a/grub-core/Makefile.core.def ++++ b/grub-core/Makefile.core.def +@@ -1406,6 +1406,7 @@ module = { + module = { + name = linux16; + common = loader/i386/pc/linux.c; ++ common = loader/linux.c; + common = lib/cmdline.c; + enable = x86; + }; +@@ -1454,6 +1455,7 @@ module = { + powerpc_ieee1275 = loader/powerpc/ieee1275/linux.c; + sparc64_ieee1275 = loader/sparc64/ieee1275/linux.c; + ia64_efi = loader/ia64/efi/linux.c; ++ common = loader/linux.c; + common = lib/cmdline.c; + enable = noemu; + }; +diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c +index 92cabfb..bdfe19a 100644 +--- a/grub-core/loader/i386/linux.c ++++ b/grub-core/loader/i386/linux.c +@@ -34,6 +34,7 @@ + #include + #include + #include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -1055,14 +1056,11 @@ static grub_err_t + grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) + { +- grub_file_t *files = 0; + grub_size_t size = 0; + grub_addr_t addr_min, addr_max; + grub_addr_t addr; + grub_err_t err; +- int i; +- int nfiles = 0; +- grub_uint8_t *ptr; ++ struct grub_linux_initrd_context initrd_ctx; + + if (argc == 0) + { +@@ -1076,19 +1074,10 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), + goto fail; + } + +- files = grub_zalloc (argc * sizeof (files[0])); +- if (!files) ++ if (grub_initrd_init (argc, argv, &initrd_ctx)) + goto fail; + +- for (i = 0; i < argc; i++) +- { +- grub_file_filter_disable_compression (); +- files[i] = grub_file_open (argv[i]); +- if (! files[i]) +- goto fail; +- nfiles++; +- size += ALIGN_UP (grub_file_size (files[i]), 4); +- } ++ size = grub_get_initrd_size (&initrd_ctx); + + initrd_pages = (page_align (size) >> 12); + +@@ -1138,21 +1127,8 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), + initrd_mem_target = get_physical_target_address (ch); + } + +- ptr = initrd_mem; +- for (i = 0; i < nfiles; i++) +- { +- grub_ssize_t cursize = grub_file_size (files[i]); +- if (grub_file_read (files[i], ptr, cursize) != cursize) +- { +- if (!grub_errno) +- grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"), +- argv[i]); +- goto fail; +- } +- ptr += cursize; +- grub_memset (ptr, 0, ALIGN_UP_OVERHEAD (cursize, 4)); +- ptr += ALIGN_UP_OVERHEAD (cursize, 4); +- } ++ if (grub_initrd_load (&initrd_ctx, argv, initrd_mem)) ++ goto fail; + + grub_dprintf ("linux", "Initrd, addr=0x%x, size=0x%x\n", + (unsigned) addr, (unsigned) size); +@@ -1162,9 +1138,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), + linux_params.root_dev = 0x0100; /* XXX */ + + fail: +- for (i = 0; i < nfiles; i++) +- grub_file_close (files[i]); +- grub_free (files); ++ grub_initrd_close (&initrd_ctx); + + return grub_errno; + } +diff --git a/grub-core/loader/i386/pc/linux.c b/grub-core/loader/i386/pc/linux.c +index 3ce21bc..672c013 100644 +--- a/grub-core/loader/i386/pc/linux.c ++++ b/grub-core/loader/i386/pc/linux.c +@@ -34,6 +34,7 @@ + #include + #include + #include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -381,15 +382,13 @@ static grub_err_t + grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) + { +- grub_file_t *files = 0; + grub_size_t size = 0; + grub_addr_t addr_max, addr_min; + struct linux_kernel_header *lh; + grub_uint8_t *initrd_chunk; + grub_addr_t initrd_addr; + grub_err_t err; +- int i, nfiles = 0; +- grub_uint8_t *ptr; ++ struct grub_linux_initrd_context initrd_ctx; + + if (argc == 0) + { +@@ -437,19 +436,10 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), + + addr_min = GRUB_LINUX_BZIMAGE_ADDR + grub_linux16_prot_size; + +- files = grub_zalloc (argc * sizeof (files[0])); +- if (!files) ++ if (grub_initrd_init (argc, argv, &initrd_ctx)) + goto fail; + +- for (i = 0; i < argc; i++) +- { +- grub_file_filter_disable_compression (); +- files[i] = grub_file_open (argv[i]); +- if (! files[i]) +- goto fail; +- nfiles++; +- size += ALIGN_UP (grub_file_size (files[i]), 4); +- } ++ size = grub_get_initrd_size (&initrd_ctx); + + { + grub_relocator_chunk_t ch; +@@ -463,30 +453,14 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), + initrd_addr = get_physical_target_address (ch); + } + +- ptr = initrd_chunk; +- +- for (i = 0; i < nfiles; i++) +- { +- grub_ssize_t cursize = grub_file_size (files[i]); +- if (grub_file_read (files[i], ptr, cursize) != cursize) +- { +- if (!grub_errno) +- grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"), +- argv[i]); +- goto fail; +- } +- ptr += cursize; +- grub_memset (ptr, 0, ALIGN_UP_OVERHEAD (cursize, 4)); +- ptr += ALIGN_UP_OVERHEAD (cursize, 4); +- } ++ if (grub_initrd_load (&initrd_ctx, argv, initrd_chunk)) ++ goto fail; + + lh->ramdisk_image = initrd_addr; + lh->ramdisk_size = size; + + fail: +- for (i = 0; i < nfiles; i++) +- grub_file_close (files[i]); +- grub_free (files); ++ grub_initrd_close (&initrd_ctx); + + return grub_errno; + } +diff --git a/grub-core/loader/ia64/efi/linux.c b/grub-core/loader/ia64/efi/linux.c +index 17843fd..87ac49f 100644 +--- a/grub-core/loader/ia64/efi/linux.c ++++ b/grub-core/loader/ia64/efi/linux.c +@@ -32,6 +32,7 @@ + #include + #include + #include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -567,10 +568,7 @@ static grub_err_t + grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) + { +- grub_file_t *files = 0; +- int i; +- int nfiles = 0; +- grub_uint8_t *ptr; ++ struct grub_linux_initrd_context initrd_ctx; + + if (argc == 0) + { +@@ -584,22 +582,11 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), + goto fail; + } + +- files = grub_zalloc (argc * sizeof (files[0])); +- if (!files) ++ if (grub_initrd_init (argc, argv, &initrd_ctx)) + goto fail; + +- initrd_size = 0; ++ initrd_size = grub_get_initrd_size (&initrd_ctx); + grub_dprintf ("linux", "Loading initrd\n"); +- for (i = 0; i < argc; i++) +- { +- grub_file_filter_disable_compression (); +- files[i] = grub_file_open (argv[i]); +- if (! files[i]) +- goto fail; +- nfiles++; +- initrd_size += ALIGN_UP (grub_file_size (files[i]), 4); +- grub_dprintf ("linux", "File %d: %s\n", i, argv[i]); +- } + + initrd_pages = (page_align (initrd_size) >> 12); + initrd_mem = grub_efi_allocate_pages (0, initrd_pages); +@@ -612,25 +599,10 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), + grub_dprintf ("linux", "[addr=0x%lx, size=0x%lx]\n", + (grub_uint64_t) initrd_mem, initrd_size); + +- ptr = initrd_mem; +- for (i = 0; i < nfiles; i++) +- { +- grub_ssize_t cursize = grub_file_size (files[i]); +- if (grub_file_read (files[i], ptr, cursize) != cursize) +- { +- if (!grub_errno) +- grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"), +- argv[i]); +- goto fail; +- } +- ptr += cursize; +- grub_memset (ptr, 0, ALIGN_UP_OVERHEAD (cursize, 4)); +- ptr += ALIGN_UP_OVERHEAD (cursize, 4); +- } ++ if (grub_initrd_load (&initrd_ctx, argv, initrd_mem)) ++ goto fail; + fail: +- for (i = 0; i < nfiles; i++) +- grub_file_close (files[i]); +- grub_free (files); ++ grub_initrd_close (&initrd_ctx); + return grub_errno; + } + +diff --git a/grub-core/loader/linux.c b/grub-core/loader/linux.c +new file mode 100644 +index 0000000..cbe3c53 +--- /dev/null ++++ b/grub-core/loader/linux.c +@@ -0,0 +1,294 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++struct newc_head ++{ ++ char magic[6]; ++ char ino[8]; ++ char mode[8]; ++ char uid[8]; ++ char gid[8]; ++ char nlink[8]; ++ char mtime[8]; ++ char filesize[8]; ++ char devmajor[8]; ++ char devminor[8]; ++ char rdevmajor[8]; ++ char rdevminor[8]; ++ char namesize[8]; ++ char check[8]; ++} __attribute__ ((packed)); ++ ++struct grub_linux_initrd_component ++{ ++ grub_file_t file; ++ char *newc_name; ++ grub_off_t size; ++}; ++ ++struct dir ++{ ++ char *name; ++ struct dir *next; ++ struct dir *child; ++}; ++ ++static char ++hex (grub_uint8_t val) ++{ ++ if (val < 10) ++ return '0' + val; ++ return 'a' + val - 10; ++} ++ ++static void ++set_field (char *var, grub_uint32_t val) ++{ ++ int i; ++ char *ptr = var; ++ for (i = 28; i >= 0; i -= 4) ++ *ptr++ = hex((val >> i) & 0xf); ++} ++ ++static grub_uint8_t * ++make_header (grub_uint8_t *ptr, ++ const char *name, grub_size_t len, ++ grub_uint32_t mode, ++ grub_off_t fsize) ++{ ++ struct newc_head *head = (struct newc_head *) ptr; ++ grub_uint8_t *optr; ++ grub_size_t oh = 0; ++ grub_memcpy (head->magic, "070701", 6); ++ set_field (head->ino, 0); ++ set_field (head->mode, mode); ++ set_field (head->uid, 0); ++ set_field (head->gid, 0); ++ set_field (head->nlink, 1); ++ set_field (head->mtime, 0); ++ set_field (head->filesize, fsize); ++ set_field (head->devmajor, 0); ++ set_field (head->devminor, 0); ++ set_field (head->rdevmajor, 0); ++ set_field (head->rdevminor, 0); ++ set_field (head->namesize, len); ++ set_field (head->check, 0); ++ optr = ptr; ++ ptr += sizeof (struct newc_head); ++ grub_memcpy (ptr, name, len); ++ ptr += len; ++ oh = ALIGN_UP_OVERHEAD (ptr - optr, 4); ++ grub_memset (ptr, 0, oh); ++ ptr += oh; ++ return ptr; ++} ++ ++static void ++free_dir (struct dir *root) ++{ ++ if (!root) ++ return; ++ free_dir (root->next); ++ free_dir (root->child); ++ grub_free (root->name); ++ grub_free (root); ++} ++ ++static grub_size_t ++insert_dir (const char *name, struct dir **root, ++ grub_uint8_t *ptr) ++{ ++ struct dir *cur, **head = root; ++ const char *cb, *ce = name; ++ grub_size_t size = 0; ++ while (1) ++ { ++ for (cb = ce; *cb == '/'; cb++); ++ for (ce = cb; *ce && *ce != '/'; ce++); ++ if (!*ce) ++ break; ++ ++ for (cur = *root; cur; cur = cur->next) ++ if (grub_memcmp (cur->name, cb, ce - cb) ++ && cur->name[ce - cb] == 0) ++ break; ++ if (!cur) ++ { ++ struct dir *n; ++ n = grub_zalloc (sizeof (*n)); ++ if (!n) ++ return 0; ++ n->next = *head; ++ n->name = grub_strndup (cb, ce - cb); ++ if (ptr) ++ { ++ grub_printf ("Creating directory %s, %s\n", name, ce); ++ ptr = make_header (ptr, name, ce - name, ++ 040777, 0); ++ } ++ size += ALIGN_UP ((ce - (char *) name) ++ + sizeof (struct newc_head), 4); ++ *head = n; ++ cur = n; ++ } ++ root = &cur->next; ++ } ++ return size; ++} ++ ++grub_err_t ++grub_initrd_init (int argc, char *argv[], ++ struct grub_linux_initrd_context *initrd_ctx) ++{ ++ int i; ++ int newc = 0; ++ struct dir *root = 0; ++ ++ initrd_ctx->nfiles = 0; ++ initrd_ctx->components = 0; ++ ++ initrd_ctx->components = grub_zalloc (argc ++ * sizeof (initrd_ctx->components[0])); ++ if (!initrd_ctx->components) ++ return grub_errno; ++ ++ initrd_ctx->size = 0; ++ ++ for (i = 0; i < argc; i++) ++ { ++ const char *fname = argv[i]; ++ if (grub_memcmp (argv[i], "newc:", 5) == 0) ++ { ++ const char *ptr, *eptr; ++ ptr = argv[i] + 5; ++ while (*ptr == '/') ++ ptr++; ++ eptr = grub_strchr (ptr, ':'); ++ if (eptr) ++ { ++ grub_file_filter_disable_compression (); ++ initrd_ctx->components[i].newc_name = grub_strndup (ptr, eptr - ptr); ++ if (!initrd_ctx->components[i].newc_name) ++ { ++ grub_initrd_close (initrd_ctx); ++ return grub_errno; ++ } ++ initrd_ctx->size ++ += ALIGN_UP (sizeof (struct newc_head) ++ + grub_strlen (initrd_ctx->components[i].newc_name), ++ 4); ++ initrd_ctx->size += insert_dir (initrd_ctx->components[i].newc_name, ++ &root, 0); ++ newc = 1; ++ fname = eptr + 1; ++ } ++ } ++ else if (newc) ++ { ++ initrd_ctx->size += ALIGN_UP (sizeof (struct newc_head) ++ + sizeof ("TRAILER!!!") - 1, 4); ++ free_dir (root); ++ root = 0; ++ newc = 0; ++ } ++ grub_file_filter_disable_compression (); ++ initrd_ctx->components[i].file = grub_file_open (fname); ++ if (!initrd_ctx->components[i].file) ++ { ++ grub_initrd_close (initrd_ctx); ++ return grub_errno; ++ } ++ initrd_ctx->nfiles++; ++ initrd_ctx->components[i].size ++ = grub_file_size (initrd_ctx->components[i].file); ++ initrd_ctx->size += ALIGN_UP (initrd_ctx->components[i].size, 4); ++ } ++ ++ if (newc) ++ { ++ initrd_ctx->size += ALIGN_UP (sizeof (struct newc_head) ++ + sizeof ("TRAILER!!!") - 1, 4); ++ free_dir (root); ++ root = 0; ++ } ++ ++ return GRUB_ERR_NONE; ++} ++ ++grub_size_t ++grub_get_initrd_size (struct grub_linux_initrd_context *initrd_ctx) ++{ ++ return initrd_ctx->size; ++} ++ ++void ++grub_initrd_close (struct grub_linux_initrd_context *initrd_ctx) ++{ ++ int i; ++ if (!initrd_ctx->components) ++ return; ++ for (i = 0; i < initrd_ctx->nfiles; i++) ++ { ++ grub_free (initrd_ctx->components[i].newc_name); ++ grub_file_close (initrd_ctx->components[i].file); ++ } ++ grub_free (initrd_ctx->components); ++ initrd_ctx->components = 0; ++} ++ ++grub_err_t ++grub_initrd_load (struct grub_linux_initrd_context *initrd_ctx, ++ char *argv[], void *target) ++{ ++ grub_uint8_t *ptr = target; ++ int i; ++ int newc = 0; ++ struct dir *root = 0; ++ ++ for (i = 0; i < initrd_ctx->nfiles; i++) ++ { ++ grub_ssize_t cursize; ++ ++ if (initrd_ctx->components[i].newc_name) ++ { ++ ptr += insert_dir (initrd_ctx->components[i].newc_name, ++ &root, ptr); ++ ptr = make_header (ptr, initrd_ctx->components[i].newc_name, ++ grub_strlen (initrd_ctx->components[i].newc_name), ++ 0100777, ++ initrd_ctx->components[i].size); ++ newc = 1; ++ } ++ else if (newc) ++ { ++ ptr = make_header (ptr, "TRAILER!!!", sizeof ("TRAILER!!!") - 1, ++ 0, 0); ++ free_dir (root); ++ root = 0; ++ newc = 0; ++ } ++ ++ cursize = initrd_ctx->components[i].size; ++ if (grub_file_read (initrd_ctx->components[i].file, ptr, cursize) ++ != cursize) ++ { ++ if (!grub_errno) ++ grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"), ++ argv[i]); ++ grub_initrd_close (initrd_ctx); ++ return grub_errno; ++ } ++ ptr += cursize; ++ grub_memset (ptr, 0, ALIGN_UP_OVERHEAD (cursize, 4)); ++ ptr += ALIGN_UP_OVERHEAD (cursize, 4); ++ } ++ if (newc) ++ ptr = make_header (ptr, "TRAILER!!!", sizeof ("TRAILER!!!") - 1, 0, 0); ++ free_dir (root); ++ root = 0; ++ return GRUB_ERR_NONE; ++} +diff --git a/grub-core/loader/mips/linux.c b/grub-core/loader/mips/linux.c +index 653f8a2..ef64a5b 100644 +--- a/grub-core/loader/mips/linux.c ++++ b/grub-core/loader/mips/linux.c +@@ -28,6 +28,7 @@ + #include + #include + #include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -410,14 +411,11 @@ static grub_err_t + grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) + { +- grub_file_t *files = 0; + grub_size_t size = 0; + void *initrd_src; + grub_addr_t initrd_dest; + grub_err_t err; +- int i; +- int nfiles = 0; +- grub_uint8_t *ptr; ++ struct grub_linux_initrd_context initrd_ctx; + + if (argc == 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); +@@ -428,19 +426,10 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), + if (initrd_loaded) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "only one initrd command can be issued."); + +- files = grub_zalloc (argc * sizeof (files[0])); +- if (!files) ++ if (grub_initrd_init (argc, argv, &initrd_ctx)) + goto fail; + +- for (i = 0; i < argc; i++) +- { +- grub_file_filter_disable_compression (); +- files[i] = grub_file_open (argv[i]); +- if (! files[i]) +- goto fail; +- nfiles++; +- size += ALIGN_UP (grub_file_size (files[i]), 4); +- } ++ size = grub_get_initrd_size (&initrd_ctx); + + { + grub_relocator_chunk_t ch; +@@ -458,21 +447,8 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), + initrd_dest = get_physical_target_address (ch) | 0x80000000; + } + +- ptr = initrd_src; +- for (i = 0; i < nfiles; i++) +- { +- grub_ssize_t cursize = grub_file_size (files[i]); +- if (grub_file_read (files[i], ptr, cursize) != cursize) +- { +- if (!grub_errno) +- grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"), +- argv[i]); +- goto fail; +- } +- ptr += cursize; +- grub_memset (ptr, 0, ALIGN_UP_OVERHEAD (cursize, 4)); +- ptr += ALIGN_UP_OVERHEAD (cursize, 4); +- } ++ if (grub_initrd_load (&initrd_ctx, argv, initrd_src)) ++ goto fail; + + #ifdef GRUB_MACHINE_MIPS_QEMU_MIPS + { +@@ -504,9 +480,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), + initrd_loaded = 1; + + fail: +- for (i = 0; i < nfiles; i++) +- grub_file_close (files[i]); +- grub_free (files); ++ grub_initrd_close (&initrd_ctx); + + return grub_errno; + } +diff --git a/grub-core/loader/powerpc/ieee1275/linux.c b/grub-core/loader/powerpc/ieee1275/linux.c +index 9055399..cff4fd1 100644 +--- a/grub-core/loader/powerpc/ieee1275/linux.c ++++ b/grub-core/loader/powerpc/ieee1275/linux.c +@@ -29,6 +29,7 @@ + #include + #include + #include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -315,13 +316,10 @@ static grub_err_t + grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) + { +- grub_file_t *files = 0; + grub_size_t size = 0; + grub_addr_t first_addr; + grub_addr_t addr; +- int i; +- int nfiles = 0; +- grub_uint8_t *ptr; ++ struct grub_linux_initrd_context initrd_ctx; + + if (argc == 0) + { +@@ -335,19 +333,10 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), + goto fail; + } + +- files = grub_zalloc (argc * sizeof (files[0])); +- if (!files) ++ if (grub_initrd_init (argc, argv, &initrd_ctx)) + goto fail; + +- for (i = 0; i < argc; i++) +- { +- grub_file_filter_disable_compression (); +- files[i] = grub_file_open (argv[i]); +- if (! files[i]) +- goto fail; +- nfiles++; +- size += ALIGN_UP (grub_file_size (files[i]), 4); +- } ++ size = grub_get_initrd_size (&initrd_ctx); + + first_addr = linux_addr + linux_size; + +@@ -359,30 +348,14 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), + + grub_dprintf ("loader", "Loading initrd at 0x%x, size 0x%x\n", addr, size); + +- ptr = (void *) addr; +- for (i = 0; i < nfiles; i++) +- { +- grub_ssize_t cursize = grub_file_size (files[i]); +- if (grub_file_read (files[i], ptr, cursize) != cursize) +- { +- grub_ieee1275_release (addr, size); +- if (!grub_errno) +- grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"), +- argv[i]); +- goto fail; +- } +- ptr += cursize; +- grub_memset (ptr, 0, ALIGN_UP_OVERHEAD (cursize, 4)); +- ptr += ALIGN_UP_OVERHEAD (cursize, 4); +- } ++ if (grub_initrd_load (&initrd_ctx, argv, (void *) addr)) ++ goto fail; + + initrd_addr = addr; + initrd_size = size; + + fail: +- for (i = 0; i < nfiles; i++) +- grub_file_close (files[i]); +- grub_free (files); ++ grub_initrd_close (&initrd_ctx); + + return grub_errno; + } +diff --git a/grub-core/loader/sparc64/ieee1275/linux.c b/grub-core/loader/sparc64/ieee1275/linux.c +index d203377..577ecff 100644 +--- a/grub-core/loader/sparc64/ieee1275/linux.c ++++ b/grub-core/loader/sparc64/ieee1275/linux.c +@@ -28,6 +28,7 @@ + #include + #include + #include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -368,14 +369,11 @@ static grub_err_t + grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) + { +- grub_file_t *files = 0; + grub_size_t size = 0; + grub_addr_t paddr; + grub_addr_t addr; + int ret; +- int i; +- int nfiles = 0; +- grub_uint8_t *ptr; ++ struct grub_linux_initrd_context initrd_ctx; + + if (argc == 0) + { +@@ -389,19 +387,10 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), + goto fail; + } + +- files = grub_zalloc (argc * sizeof (files[0])); +- if (!files) ++ if (grub_initrd_init (argc, argv, &initrd_ctx)) + goto fail; + +- for (i = 0; i < argc; i++) +- { +- grub_file_filter_disable_compression (); +- files[i] = grub_file_open (argv[i]); +- if (! files[i]) +- goto fail; +- nfiles++; +- size += ALIGN_UP(grub_file_size (files[i]), 4); +- } ++ size = grub_get_initrd_size (&initrd_ctx); + + addr = 0x60000000; + +@@ -423,30 +412,15 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), + grub_dprintf ("loader", "Loading initrd at vaddr 0x%lx, paddr 0x%lx, size 0x%lx\n", + addr, paddr, size); + +- ptr = (void *) addr; +- for (i = 0; i < nfiles; i++) +- { +- grub_ssize_t cursize = grub_file_size (files[i]); +- if (grub_file_read (files[i], ptr, cursize) != cursize) +- { +- if (!grub_errno) +- grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"), +- argv[i]); +- goto fail; +- } +- ptr += cursize; +- grub_memset (ptr, 0, ALIGN_UP_OVERHEAD (cursize, 4)); +- ptr += ALIGN_UP_OVERHEAD (cursize, 4); +- } ++ if (grub_initrd_load (&initrd_ctx, argv, (void *) addr)) ++ goto fail; + + initrd_addr = addr; + initrd_paddr = paddr; + initrd_size = size; + + fail: +- for (i = 0; i < nfiles; i++) +- grub_file_close (files[i]); +- grub_free (files); ++ grub_initrd_close (&initrd_ctx); + + return grub_errno; + } +diff --git a/include/grub/linux.h b/include/grub/linux.h +new file mode 100644 +index 0000000..594a3f3 +--- /dev/null ++++ b/include/grub/linux.h +@@ -0,0 +1,24 @@ ++#include ++ ++struct grub_linux_initrd_component; ++ ++struct grub_linux_initrd_context ++{ ++ int nfiles; ++ struct grub_linux_initrd_component *components; ++ grub_size_t size; ++}; ++ ++grub_err_t ++grub_initrd_init (int argc, char *argv[], ++ struct grub_linux_initrd_context *ctx); ++ ++grub_size_t ++grub_get_initrd_size (struct grub_linux_initrd_context *ctx); ++ ++void ++grub_initrd_close (struct grub_linux_initrd_context *initrd_ctx); ++ ++grub_err_t ++grub_initrd_load (struct grub_linux_initrd_context *initrd_ctx, ++ char *argv[], void *target); +-- +1.8.1.4 + diff --git a/0224-grub-core-fs-zfs-zfs.c-Fix-incorrect-handling-of-spe.patch b/0224-grub-core-fs-zfs-zfs.c-Fix-incorrect-handling-of-spe.patch new file mode 100644 index 0000000..d2d27d9 --- /dev/null +++ b/0224-grub-core-fs-zfs-zfs.c-Fix-incorrect-handling-of-spe.patch @@ -0,0 +1,170 @@ +From 42aa5a0f3a2519102f5f925bd7147e93a641682a Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Fri, 22 Mar 2013 22:18:38 +0100 +Subject: [PATCH 224/364] * grub-core/fs/zfs/zfs.c: Fix incorrect + handling of special volumes. + +--- + ChangeLog | 4 ++++ + grub-core/fs/zfs/zfs.c | 59 ++++++++++++++++++++++++++++++++++++-------------- + 2 files changed, 47 insertions(+), 16 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 5582e13..8175269 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,9 @@ + 2013-03-22 Vladimir Serbinenko + ++ * grub-core/fs/zfs/zfs.c: Fix incorrect handling of special volumes. ++ ++2013-03-22 Vladimir Serbinenko ++ + Add ability to generate newc additions on runtime. + + 2013-03-22 Vladimir Serbinenko +diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c +index 822d65b..3d57978 100644 +--- a/grub-core/fs/zfs/zfs.c ++++ b/grub-core/fs/zfs/zfs.c +@@ -3695,7 +3695,7 @@ grub_zfs_getmdnobj (grub_device_t dev, const char *fsfilename, + return err; + } + +-static void ++static grub_err_t + fill_fs_info (struct grub_dirhook_info *info, + dnode_end_t mdn, struct grub_zfs_data *data) + { +@@ -3716,30 +3716,32 @@ fill_fs_info (struct grub_dirhook_info *info, + if (err) + { + grub_dprintf ("zfs", "failed here\n"); +- return; ++ return err; + } + } +- make_mdn (&mdn, data); ++ err = make_mdn (&mdn, data); ++ if (err) ++ return err; + err = dnode_get (&mdn, MASTER_NODE_OBJ, DMU_OT_MASTER_NODE, + &dn, data); + if (err) + { + grub_dprintf ("zfs", "failed here\n"); +- return; ++ return err; + } + + err = zap_lookup (&dn, ZFS_ROOT_OBJ, &objnum, data, 0); + if (err) + { + grub_dprintf ("zfs", "failed here\n"); +- return; ++ return err; + } + + err = dnode_get (&mdn, objnum, 0, &dn, data); + if (err) + { + grub_dprintf ("zfs", "failed here\n"); +- return; ++ return err; + } + + if (dn.dn.dn_bonustype == DMU_OT_SA) +@@ -3757,12 +3759,12 @@ fill_fs_info (struct grub_dirhook_info *info, + + err = zio_read (bp, dn.endian, &sahdrp, NULL, data); + if (err) +- return; ++ return err; + } + else + { + grub_error (GRUB_ERR_BAD_FS, "filesystem is corrupt"); +- return; ++ return grub_errno; + } + + hdrsize = SA_HDR_SIZE (((sa_hdr_phys_t *) sahdrp)); +@@ -3775,7 +3777,7 @@ fill_fs_info (struct grub_dirhook_info *info, + info->mtimeset = 1; + info->mtime = grub_zfs_to_cpu64 (((znode_phys_t *) DN_BONUS (&dn.dn))->zp_mtime[0], dn.endian); + } +- return; ++ return 0; + } + + /* Helper for grub_zfs_dir. */ +@@ -3846,11 +3848,19 @@ iterate_zap_fs (const char *name, grub_uint64_t val, + dnode_end_t mdn; + err = dnode_get (&(ctx->data->mos), val, 0, &mdn, ctx->data); + if (err) +- return 0; ++ { ++ grub_errno = 0; ++ return 0; ++ } + if (mdn.dn.dn_type != DMU_OT_DSL_DIR) + return 0; + +- fill_fs_info (&info, mdn, ctx->data); ++ err = fill_fs_info (&info, mdn, ctx->data); ++ if (err) ++ { ++ grub_errno = 0; ++ return 0; ++ } + return ctx->hook (name, &info, ctx->hook_data); + } + +@@ -3868,12 +3878,20 @@ iterate_zap_snap (const char *name, grub_uint64_t val, + + err = dnode_get (&(ctx->data->mos), val, 0, &mdn, ctx->data); + if (err) +- return 0; ++ { ++ grub_errno = 0; ++ return 0; ++ } + + if (mdn.dn.dn_type != DMU_OT_DSL_DATASET) + return 0; + +- fill_fs_info (&info, mdn, ctx->data); ++ err = fill_fs_info (&info, mdn, ctx->data); ++ if (err) ++ { ++ grub_errno = 0; ++ return 0; ++ } + + name2 = grub_malloc (grub_strlen (name) + 2); + name2[0] = '@'; +@@ -3913,9 +3931,18 @@ grub_zfs_dir (grub_device_t device, const char *path, + dnode_end_t dn; + struct grub_dirhook_info info; + +- fill_fs_info (&info, data->dnode, data); +- hook ("@", &info, hook_data); +- ++ err = fill_fs_info (&info, data->dnode, data); ++ if (err) ++ { ++ zfs_unmount (data); ++ return err; ++ } ++ if (hook ("@", &info, hook_data)) ++ { ++ zfs_unmount (data); ++ return GRUB_ERR_NONE; ++ } ++ + childobj = grub_zfs_to_cpu64 (((dsl_dir_phys_t *) DN_BONUS (&data->dnode.dn))->dd_child_dir_zapobj, data->dnode.endian); + headobj = grub_zfs_to_cpu64 (((dsl_dir_phys_t *) DN_BONUS (&data->dnode.dn))->dd_head_dataset_obj, data->dnode.endian); + err = dnode_get (&(data->mos), childobj, +-- +1.8.1.4 + diff --git a/0225-grub-core-term-at_keyboard.c-Increase-robustness-on-.patch b/0225-grub-core-term-at_keyboard.c-Increase-robustness-on-.patch new file mode 100644 index 0000000..b087ca5 --- /dev/null +++ b/0225-grub-core-term-at_keyboard.c-Increase-robustness-on-.patch @@ -0,0 +1,70 @@ +From 99462758030178ce8e28fc59e9275824e1e0fd1b Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sat, 23 Mar 2013 16:54:36 +0100 +Subject: [PATCH 225/364] * grub-core/term/at_keyboard.c: Increase + robustness on coreboot and qemu. + +--- + ChangeLog | 5 +++++ + grub-core/term/at_keyboard.c | 16 +++++++++++++--- + 2 files changed, 18 insertions(+), 3 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 8175269..9841659 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,8 @@ ++2013-03-23 Vladimir Serbinenko ++ ++ * grub-core/term/at_keyboard.c: Increase robustness on coreboot ++ and qemu. ++ + 2013-03-22 Vladimir Serbinenko + + * grub-core/fs/zfs/zfs.c: Fix incorrect handling of special volumes. +diff --git a/grub-core/term/at_keyboard.c b/grub-core/term/at_keyboard.c +index 2afcceb..b2f328f 100644 +--- a/grub-core/term/at_keyboard.c ++++ b/grub-core/term/at_keyboard.c +@@ -259,7 +259,13 @@ grub_keyboard_controller_write (grub_uint8_t c) + grub_outb (c, KEYBOARD_REG_DATA); + } + +-#if !defined (GRUB_MACHINE_MIPS_LOONGSON) && !defined (GRUB_MACHINE_QEMU) && !defined (GRUB_MACHINE_MIPS_QEMU_MIPS) ++#if defined (GRUB_MACHINE_MIPS_LOONGSON) || defined (GRUB_MACHINE_QEMU) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_MIPS_QEMU_MIPS) ++#define USE_SCANCODE_SET 1 ++#else ++#define USE_SCANCODE_SET 0 ++#endif ++ ++#if !USE_SCANCODE_SET + + static grub_uint8_t + grub_keyboard_controller_read (void) +@@ -332,7 +338,7 @@ set_scancodes (void) + return; + } + +-#if !(defined (GRUB_MACHINE_MIPS_LOONGSON) || defined (GRUB_MACHINE_QEMU) || defined (GRUB_MACHINE_MIPS_QEMU_MIPS)) ++#if !USE_SCANCODE_SET + current_set = 1; + return; + #else +@@ -570,9 +576,13 @@ grub_keyboard_controller_init (struct grub_term_input *term __attribute__ ((unus + keyboard_controller_wait_until_ready (); + grub_inb (KEYBOARD_REG_DATA); + } +-#if defined (GRUB_MACHINE_MIPS_LOONGSON) || defined (GRUB_MACHINE_QEMU) || defined (GRUB_MACHINE_MIPS_QEMU_MIPS) ++#if defined (GRUB_MACHINE_MIPS_LOONGSON) || defined (GRUB_MACHINE_MIPS_QEMU_MIPS) + grub_keyboard_controller_orig = 0; + grub_keyboard_orig_set = 2; ++#elif defined (GRUB_MACHINE_QEMU) || defined (GRUB_MACHINE_COREBOOT) ++ /* *BSD relies on those settings. */ ++ grub_keyboard_controller_orig = KEYBOARD_AT_TRANSLATE; ++ grub_keyboard_orig_set = 2; + #else + grub_keyboard_controller_orig = grub_keyboard_controller_read (); + grub_keyboard_orig_set = query_mode (); +-- +1.8.1.4 + diff --git a/0226-Add-new-proc-filesystem-framework-and-put-luks_scrip.patch b/0226-Add-new-proc-filesystem-framework-and-put-luks_scrip.patch new file mode 100644 index 0000000..f8cc8e0 --- /dev/null +++ b/0226-Add-new-proc-filesystem-framework-and-put-luks_scrip.patch @@ -0,0 +1,514 @@ +From a613c3ea1106ce4dc1e44f88665d14259b659da8 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sun, 24 Mar 2013 13:05:59 +0100 +Subject: [PATCH 226/364] Add new 'proc' filesystem framework and put + luks_script into it. + +--- + ChangeLog | 4 ++ + Makefile.util.def | 1 + + grub-core/Makefile.core.def | 5 ++ + grub-core/disk/cryptodisk.c | 113 +++++++++++++++++++++++++++++ + grub-core/disk/geli.c | 2 - + grub-core/disk/luks.c | 2 - + grub-core/fs/proc.c | 172 ++++++++++++++++++++++++++++++++++++++++++++ + include/grub/cryptodisk.h | 5 +- + include/grub/disk.h | 1 + + include/grub/procfs.h | 50 +++++++++++++ + 10 files changed, 350 insertions(+), 5 deletions(-) + create mode 100644 grub-core/fs/proc.c + create mode 100644 include/grub/procfs.h + +diff --git a/ChangeLog b/ChangeLog +index 9841659..8f3878d 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,7 @@ ++2013-03-24 Vladimir Serbinenko ++ ++ Add new 'proc' filesystem framework and put luks_script into it. ++ + 2013-03-23 Vladimir Serbinenko + + * grub-core/term/at_keyboard.c: Increase robustness on coreboot +diff --git a/Makefile.util.def b/Makefile.util.def +index 1ccf390..62bcf2d 100644 +--- a/Makefile.util.def ++++ b/Makefile.util.def +@@ -33,6 +33,7 @@ library = { + common = grub-core/disk/diskfilter.c; + common = grub-core/partmap/gpt.c; + common = grub-core/partmap/msdos.c; ++ common = grub-core/fs/proc.c; + }; + + library = { +diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def +index a614b22..b1c1ab9 100644 +--- a/grub-core/Makefile.core.def ++++ b/grub-core/Makefile.core.def +@@ -1068,6 +1068,11 @@ module = { + }; + + module = { ++ name = procfs; ++ common = fs/proc.c; ++}; ++ ++module = { + name = affs; + common = fs/affs.c; + }; +diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c +index f39c1ab..374edd1 100644 +--- a/grub-core/disk/cryptodisk.c ++++ b/grub-core/disk/cryptodisk.c +@@ -22,6 +22,9 @@ + #include + #include + #include ++#include ++#include ++#include + + #ifdef GRUB_UTIL + #include +@@ -403,6 +406,8 @@ grub_cryptodisk_setkey (grub_cryptodisk_t dev, grub_uint8_t *key, grub_size_t ke + err = grub_crypto_cipher_set_key (dev->cipher, key, real_keysize); + if (err) + return err; ++ grub_memcpy (dev->key, key, keysize); ++ dev->keysize = keysize; + + /* Configure ESSIV if necessary. */ + if (dev->mode_iv == GRUB_CRYPTODISK_MODE_IV_ESSIV) +@@ -979,6 +984,112 @@ static struct grub_disk_dev grub_cryptodisk_dev = { + .next = 0 + }; + ++static char ++hex (grub_uint8_t val) ++{ ++ if (val < 10) ++ return '0' + val; ++ return 'a' + val - 10; ++} ++ ++/* Open a file named NAME and initialize FILE. */ ++static char * ++luks_script_get (void) ++{ ++ grub_cryptodisk_t i; ++ grub_size_t size = 0; ++ char *ptr, *ret; ++ ++ for (i = cryptodisk_list; i != NULL; i = i->next) ++ if (grub_strcmp (i->modname, "luks") == 0) ++ { ++ size += sizeof ("luks_mount "); ++ size += grub_strlen (i->uuid); ++ size += grub_strlen (i->cipher->cipher->name); ++ size += 54; ++ if (i->essiv_hash) ++ size += grub_strlen (i->essiv_hash->name); ++ size += i->keysize * 2; ++ } ++ ++ ret = grub_malloc (size + 1); ++ if (!ret) ++ return 0; ++ ++ ptr = ret; ++ ++ for (i = cryptodisk_list; i != NULL; i = i->next) ++ if (grub_strcmp (i->modname, "luks") == 0) ++ { ++ unsigned j; ++ const char *iptr; ++ ptr = grub_stpcpy (ptr, "luks_mount "); ++ ptr = grub_stpcpy (ptr, i->uuid); ++ *ptr++ = ' '; ++ grub_snprintf (ptr, 21, "%" PRIuGRUB_UINT64_T " ", i->offset); ++ while (*ptr) ++ ptr++; ++ for (iptr = i->cipher->cipher->name; *iptr; iptr++) ++ *ptr++ = grub_tolower (*iptr); ++ switch (i->mode) ++ { ++ case GRUB_CRYPTODISK_MODE_ECB: ++ ptr = grub_stpcpy (ptr, "-ecb"); ++ break; ++ case GRUB_CRYPTODISK_MODE_CBC: ++ ptr = grub_stpcpy (ptr, "-cbc"); ++ break; ++ case GRUB_CRYPTODISK_MODE_PCBC: ++ ptr = grub_stpcpy (ptr, "-pcbc"); ++ break; ++ case GRUB_CRYPTODISK_MODE_XTS: ++ ptr = grub_stpcpy (ptr, "-xts"); ++ break; ++ case GRUB_CRYPTODISK_MODE_LRW: ++ ptr = grub_stpcpy (ptr, "-lrw"); ++ break; ++ } ++ ++ switch (i->mode_iv) ++ { ++ case GRUB_CRYPTODISK_MODE_IV_NULL: ++ ptr = grub_stpcpy (ptr, "-null"); ++ break; ++ case GRUB_CRYPTODISK_MODE_IV_PLAIN: ++ ptr = grub_stpcpy (ptr, "-plain"); ++ break; ++ case GRUB_CRYPTODISK_MODE_IV_PLAIN64: ++ ptr = grub_stpcpy (ptr, "-plain64"); ++ break; ++ case GRUB_CRYPTODISK_MODE_IV_BENBI: ++ ptr = grub_stpcpy (ptr, "-benbi"); ++ break; ++ case GRUB_CRYPTODISK_MODE_IV_ESSIV: ++ ptr = grub_stpcpy (ptr, "-essiv:"); ++ ptr = grub_stpcpy (ptr, i->essiv_hash->name); ++ break; ++ case GRUB_CRYPTODISK_MODE_IV_BYTECOUNT64: ++ case GRUB_CRYPTODISK_MODE_IV_BYTECOUNT64_HASH: ++ break; ++ } ++ *ptr++ = ' '; ++ for (j = 0; j < i->keysize; j++) ++ { ++ *ptr++ = hex (i->key[j] >> 4); ++ *ptr++ = hex (i->key[j] & 0xf); ++ } ++ *ptr++ = '\n'; ++ } ++ *ptr = '\0'; ++ return ret; ++} ++ ++struct grub_procfs_entry luks_script = ++{ ++ .name = "luks_script", ++ .get_contents = luks_script_get ++}; ++ + static grub_extcmd_t cmd; + + GRUB_MOD_INIT (cryptodisk) +@@ -987,10 +1098,12 @@ GRUB_MOD_INIT (cryptodisk) + cmd = grub_register_extcmd ("cryptomount", grub_cmd_cryptomount, 0, + N_("SOURCE|-u UUID|-a|-b"), + N_("Mount a crypto device."), options); ++ grub_procfs_register ("luks_script", &luks_script); + } + + GRUB_MOD_FINI (cryptodisk) + { + grub_disk_dev_unregister (&grub_cryptodisk_dev); + cryptodisk_cleanup (); ++ grub_procfs_unregister (&luks_script); + } +diff --git a/grub-core/disk/geli.c b/grub-core/disk/geli.c +index f9315df..0b94414 100644 +--- a/grub-core/disk/geli.c ++++ b/grub-core/disk/geli.c +@@ -381,9 +381,7 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid, + newdev->rekey_shift = 20; + } + +-#ifdef GRUB_UTIL + newdev->modname = "geli"; +-#endif + + newdev->total_length = grub_disk_get_size (disk) - 1; + grub_memcpy (newdev->uuid, uuid, sizeof (newdev->uuid)); +diff --git a/grub-core/disk/luks.c b/grub-core/disk/luks.c +index 44f3cac..afcb7e4 100644 +--- a/grub-core/disk/luks.c ++++ b/grub-core/disk/luks.c +@@ -290,9 +290,7 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid, + newdev->log_sector_size = 9; + newdev->total_length = grub_disk_get_size (disk) - newdev->offset; + grub_memcpy (newdev->uuid, uuid, sizeof (newdev->uuid)); +-#ifdef GRUB_UTIL + newdev->modname = "luks"; +-#endif + COMPILE_TIME_ASSERT (sizeof (newdev->uuid) >= sizeof (uuid)); + return newdev; + } +diff --git a/grub-core/fs/proc.c b/grub-core/fs/proc.c +new file mode 100644 +index 0000000..8f27682 +--- /dev/null ++++ b/grub-core/fs/proc.c +@@ -0,0 +1,172 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2013 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 ++ ++GRUB_MOD_LICENSE ("GPLv3+"); ++ ++struct grub_procfs_entry *grub_procfs_entries; ++ ++static int ++grub_procdev_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data, ++ grub_disk_pull_t pull) ++{ ++ if (pull != GRUB_DISK_PULL_NONE) ++ return 0; ++ ++ return hook ("proc", hook_data); ++} ++ ++static grub_err_t ++grub_procdev_open (const char *name, grub_disk_t disk) ++{ ++ if (grub_strcmp (name, "proc")) ++ return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a procfs disk"); ++ ++ disk->total_sectors = 0; ++ disk->id = (unsigned long) "proc"; ++ ++ disk->data = 0; ++ ++ return GRUB_ERR_NONE; ++} ++ ++static void ++grub_procdev_close (grub_disk_t disk __attribute((unused))) ++{ ++} ++ ++static grub_err_t ++grub_procdev_read (grub_disk_t disk __attribute((unused)), ++ grub_disk_addr_t sector __attribute((unused)), ++ grub_size_t size __attribute((unused)), ++ char *buf __attribute((unused))) ++{ ++ return GRUB_ERR_OUT_OF_RANGE; ++} ++ ++static grub_err_t ++grub_procdev_write (grub_disk_t disk __attribute ((unused)), ++ grub_disk_addr_t sector __attribute ((unused)), ++ grub_size_t size __attribute ((unused)), ++ const char *buf __attribute ((unused))) ++{ ++ return GRUB_ERR_OUT_OF_RANGE; ++} ++ ++static grub_ssize_t ++grub_procfs_read (grub_file_t file, char *buf, grub_size_t len) ++{ ++ char *data = file->data; ++ ++ grub_memcpy (buf, data + file->offset, len); ++ ++ return len; ++} ++ ++static grub_err_t ++grub_procfs_close (grub_file_t file) ++{ ++ char *data; ++ ++ data = file->data; ++ grub_free (data); ++ ++ return GRUB_ERR_NONE; ++} ++ ++static grub_err_t ++grub_procfs_dir (grub_device_t device, const char *path, ++ grub_fs_dir_hook_t hook, void *hook_data) ++{ ++ const char *ptr; ++ struct grub_dirhook_info info; ++ struct grub_procfs_entry *entry; ++ ++ grub_memset (&info, 0, sizeof (info)); ++ ++ /* Check if the disk is our dummy disk. */ ++ if (grub_strcmp (device->disk->name, "proc")) ++ return grub_error (GRUB_ERR_BAD_FS, "not a procfs"); ++ for (ptr = path; *ptr == '/'; ptr++); ++ if (*ptr) ++ return 0; ++ FOR_LIST_ELEMENTS((entry), (grub_procfs_entries)) ++ if (hook (entry->name, &info, hook_data)) ++ return 0; ++ return 0; ++} ++ ++static grub_err_t ++grub_procfs_open (struct grub_file *file, const char *path) ++{ ++ const char *pathptr; ++ struct grub_procfs_entry *entry; ++ ++ for (pathptr = path; *pathptr == '/'; pathptr++); ++ ++ FOR_LIST_ELEMENTS((entry), (grub_procfs_entries)) ++ if (grub_strcmp (pathptr, entry->name) == 0) ++ { ++ file->data = entry->get_contents (); ++ if (!file->data) ++ return grub_errno; ++ file->size = grub_strlen (file->data); ++ return GRUB_ERR_NONE; ++ } ++ ++ return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file `%s' not found"), path); ++} ++ ++static struct grub_disk_dev grub_procfs_dev = { ++ .name = "proc", ++ .id = GRUB_DISK_DEVICE_PROCFS_ID, ++ .iterate = grub_procdev_iterate, ++ .open = grub_procdev_open, ++ .close = grub_procdev_close, ++ .read = grub_procdev_read, ++ .write = grub_procdev_write, ++ .next = 0 ++}; ++ ++static struct grub_fs grub_procfs_fs = ++ { ++ .name = "procfs", ++ .dir = grub_procfs_dir, ++ .open = grub_procfs_open, ++ .read = grub_procfs_read, ++ .close = grub_procfs_close, ++ .next = 0 ++ }; ++ ++GRUB_MOD_INIT (procfs) ++{ ++ grub_disk_dev_register (&grub_procfs_dev); ++ grub_fs_register (&grub_procfs_fs); ++} ++ ++GRUB_MOD_FINI (procfs) ++{ ++ grub_disk_dev_unregister (&grub_procfs_dev); ++ grub_fs_unregister (&grub_procfs_fs); ++} +diff --git a/include/grub/cryptodisk.h b/include/grub/cryptodisk.h +index 0bb5d44..c3ee820 100644 +--- a/include/grub/cryptodisk.h ++++ b/include/grub/cryptodisk.h +@@ -49,6 +49,7 @@ typedef enum + #define GRUB_CRYPTODISK_GF_SIZE (1U << GRUB_CRYPTODISK_GF_LOG_SIZE) + #define GRUB_CRYPTODISK_GF_LOG_BYTES (GRUB_CRYPTODISK_GF_LOG_SIZE - 3) + #define GRUB_CRYPTODISK_GF_BYTES (1U << GRUB_CRYPTODISK_GF_LOG_BYTES) ++#define GRUB_CRYPTODISK_MAX_KEYLEN 128 + + struct grub_cryptodisk; + +@@ -80,11 +81,13 @@ struct grub_cryptodisk + grub_uint8_t *lrw_precalc; + grub_uint8_t iv_prefix[64]; + grub_size_t iv_prefix_len; ++ grub_uint8_t key[GRUB_CRYPTODISK_MAX_KEYLEN]; ++ grub_size_t keysize; + #ifdef GRUB_UTIL + char *cheat; +- const char *modname; + int cheat_fd; + #endif ++ const char *modname; + int log_sector_size; + grub_cryptodisk_rekey_func_t rekey; + int rekey_shift; +diff --git a/include/grub/disk.h b/include/grub/disk.h +index f0e3df3..d19b1ac 100644 +--- a/include/grub/disk.h ++++ b/include/grub/disk.h +@@ -43,6 +43,7 @@ enum grub_disk_dev_id + GRUB_DISK_DEVICE_CRYPTODISK_ID, + GRUB_DISK_DEVICE_ARCDISK_ID, + GRUB_DISK_DEVICE_HOSTDISK_ID, ++ GRUB_DISK_DEVICE_PROCFS_ID, + }; + + struct grub_disk; +diff --git a/include/grub/procfs.h b/include/grub/procfs.h +new file mode 100644 +index 0000000..55cbb21 +--- /dev/null ++++ b/include/grub/procfs.h +@@ -0,0 +1,50 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2013 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_PROCFS_HEADER ++#define GRUB_PROCFS_HEADER 1 ++ ++#include ++ ++struct grub_procfs_entry ++{ ++ struct grub_procfs_entry *next; ++ struct grub_procfs_entry **prev; ++ ++ const char *name; ++ char * (*get_contents) (void); ++}; ++ ++extern struct grub_procfs_entry *grub_procfs_entries; ++ ++static inline void ++grub_procfs_register (const char *name __attribute__ ((unused)), ++ struct grub_procfs_entry *entry) ++{ ++ grub_list_push (GRUB_AS_LIST_P (&grub_procfs_entries), ++ GRUB_AS_LIST (entry)); ++} ++ ++static inline void ++grub_procfs_unregister (struct grub_procfs_entry *entry) ++{ ++ grub_list_remove (GRUB_AS_LIST (entry)); ++} ++ ++ ++#endif +-- +1.8.1.4 + diff --git a/0227-grub-core-Makefile.core.def-vbe-Disable-on-coreboot-.patch b/0227-grub-core-Makefile.core.def-vbe-Disable-on-coreboot-.patch new file mode 100644 index 0000000..58dd09a --- /dev/null +++ b/0227-grub-core-Makefile.core.def-vbe-Disable-on-coreboot-.patch @@ -0,0 +1,42 @@ +From 53fc7d734da80509a08ccbf6246f5fe26ab61a91 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sun, 24 Mar 2013 13:07:51 +0100 +Subject: [PATCH 227/364] * grub-core/Makefile.core.def (vbe): Disable + on coreboot and multiboot platforms. + +--- + ChangeLog | 5 +++++ + grub-core/Makefile.core.def | 2 -- + 2 files changed, 5 insertions(+), 2 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 8f3878d..6fab49f 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,10 @@ + 2013-03-24 Vladimir Serbinenko + ++ * grub-core/Makefile.core.def (vbe): Disable on coreboot and multiboot ++ platforms. ++ ++2013-03-24 Vladimir Serbinenko ++ + Add new 'proc' filesystem framework and put luks_script into it. + + 2013-03-23 Vladimir Serbinenko +diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def +index b1c1ab9..4f705b9 100644 +--- a/grub-core/Makefile.core.def ++++ b/grub-core/Makefile.core.def +@@ -1740,8 +1740,6 @@ module = { + name = vbe; + common = video/i386/pc/vbe.c; + enable = i386_pc; +- enable = i386_coreboot; +- enable = i386_multiboot; + }; + + module = { +-- +1.8.1.4 + diff --git a/0228-util-grub-mkconfig_lib.in-prepare_grub_to_access_dev.patch b/0228-util-grub-mkconfig_lib.in-prepare_grub_to_access_dev.patch new file mode 100644 index 0000000..5ae21af --- /dev/null +++ b/0228-util-grub-mkconfig_lib.in-prepare_grub_to_access_dev.patch @@ -0,0 +1,81 @@ +From 321ac40b339af9820d4f9df7d301524a3b9ffbbe Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sun, 24 Mar 2013 13:11:19 +0100 +Subject: [PATCH 228/364] * util/grub-mkconfig_lib.in + (prepare_grub_to_access_device): Fix handling of multi-device filesystems. + +--- + ChangeLog | 5 +++++ + util/grub-mkconfig_lib.in | 16 +++++++--------- + 2 files changed, 12 insertions(+), 9 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 6fab49f..4df000e 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,10 @@ + 2013-03-24 Vladimir Serbinenko + ++ * util/grub-mkconfig_lib.in (prepare_grub_to_access_device): Fix ++ handling of multi-device filesystems. ++ ++2013-03-24 Vladimir Serbinenko ++ + * grub-core/Makefile.core.def (vbe): Disable on coreboot and multiboot + platforms. + +diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in +index e560dd7..b48e2af 100644 +--- a/util/grub-mkconfig_lib.in ++++ b/util/grub-mkconfig_lib.in +@@ -115,9 +115,7 @@ EOF + + prepare_grub_to_access_device () + { +- device="$1" +- +- partmap="`"${grub_probe}" --device "${device}" --target=partmap`" ++ partmap="`"${grub_probe}" --device "$@" --target=partmap`" + for module in ${partmap} ; do + case "${module}" in + netbsd | openbsd) +@@ -128,30 +126,30 @@ prepare_grub_to_access_device () + done + + # Abstraction modules aren't auto-loaded. +- abstraction="`"${grub_probe}" --device "${device}" --target=abstraction`" ++ abstraction="`"${grub_probe}" --device "$@" --target=abstraction`" + for module in ${abstraction} ; do + echo "insmod ${module}" + done + +- fs="`"${grub_probe}" --device "${device}" --target=fs`" ++ fs="`"${grub_probe}" --device "$@" --target=fs`" + for module in ${fs} ; do + echo "insmod ${module}" + done + + if [ x$GRUB_CRYPTODISK_ENABLE = xy ]; then +- for uuid in "`"${grub_probe}" --device "${device}" --target=cryptodisk_uuid`"; do ++ for uuid in "`"${grub_probe}" --device "$@" --target=cryptodisk_uuid`"; do + echo "cryptomount -u $uuid" + done + fi + + # If there's a filesystem UUID that GRUB is capable of identifying, use it; + # otherwise set root as per value in device.map. +- fs_hint="`"${grub_probe}" --device "${device}" --target=compatibility_hint`" ++ fs_hint="`"${grub_probe}" --device "$@" --target=compatibility_hint`" + if [ "x$fs_hint" != x ]; then + echo "set root='$fs_hint'" + fi +- if fs_uuid="`"${grub_probe}" --device "${device}" --target=fs_uuid 2> /dev/null`" ; then +- hints="`"${grub_probe}" --device "${device}" --target=hints_string 2> /dev/null`" || hints= ++ if fs_uuid="`"${grub_probe}" --device "$@" --target=fs_uuid 2> /dev/null`" ; then ++ hints="`"${grub_probe}" --device "$@" --target=hints_string 2> /dev/null`" || hints= + echo "if [ x\$feature_platform_search_hint = xy ]; then" + echo " search --no-floppy --fs-uuid --set=root ${hints} ${fs_uuid}" + echo "else" +-- +1.8.1.4 + diff --git a/0229-grub-core-Makefile.core.def-vga-Disable-on-coreboot-.patch b/0229-grub-core-Makefile.core.def-vga-Disable-on-coreboot-.patch new file mode 100644 index 0000000..a7be99a --- /dev/null +++ b/0229-grub-core-Makefile.core.def-vga-Disable-on-coreboot-.patch @@ -0,0 +1,42 @@ +From 71b0dcebbd780be081b55821e3b3f83badb387a1 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sun, 24 Mar 2013 14:01:51 +0100 +Subject: [PATCH 229/364] * grub-core/Makefile.core.def (vga): Disable + on coreboot and multiboot platforms. + +--- + ChangeLog | 5 +++++ + grub-core/Makefile.core.def | 2 -- + 2 files changed, 5 insertions(+), 2 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 4df000e..43dcf93 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,10 @@ + 2013-03-24 Vladimir Serbinenko + ++ * grub-core/Makefile.core.def (vga): Disable on coreboot and multiboot ++ platforms. ++ ++2013-03-24 Vladimir Serbinenko ++ + * util/grub-mkconfig_lib.in (prepare_grub_to_access_device): Fix + handling of multi-device filesystems. + +diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def +index 4f705b9..911754d 100644 +--- a/grub-core/Makefile.core.def ++++ b/grub-core/Makefile.core.def +@@ -1656,8 +1656,6 @@ module = { + name = vga; + common = video/i386/pc/vga.c; + enable = i386_pc; +- enable = i386_coreboot; +- enable = i386_multiboot; + }; + + module = { +-- +1.8.1.4 + diff --git a/0230-util-grub.d-20_linux_xen.in-Automatically-add-no-rea.patch b/0230-util-grub.d-20_linux_xen.in-Automatically-add-no-rea.patch new file mode 100644 index 0000000..ea5f8cf --- /dev/null +++ b/0230-util-grub.d-20_linux_xen.in-Automatically-add-no-rea.patch @@ -0,0 +1,47 @@ +From 7ecfb461eeb576ba07a0f810a19c2ed4149ea2c7 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sun, 24 Mar 2013 14:03:33 +0100 +Subject: [PATCH 230/364] * util/grub.d/20_linux_xen.in: Automatically + add no-real-mode edd=off on non-BIOS platforms. + +--- + ChangeLog | 5 +++++ + util/grub.d/20_linux_xen.in | 7 ++++++- + 2 files changed, 11 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index 43dcf93..981991b 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,10 @@ + 2013-03-24 Vladimir Serbinenko + ++ * util/grub.d/20_linux_xen.in: Automatically add no-real-mode edd=off on ++ non-BIOS platforms. ++ ++2013-03-24 Vladimir Serbinenko ++ + * grub-core/Makefile.core.def (vga): Disable on coreboot and multiboot + platforms. + +diff --git a/util/grub.d/20_linux_xen.in b/util/grub.d/20_linux_xen.in +index ac05ee4..6651cbc 100644 +--- a/util/grub.d/20_linux_xen.in ++++ b/util/grub.d/20_linux_xen.in +@@ -121,7 +121,12 @@ linux_entry () + lmessage="$(gettext_printf "Loading Linux %s ..." ${version})" + sed "s/^/$submenu_indentation/" << EOF + echo '$(echo "$xmessage" | grub_quote)' +- multiboot ${rel_xen_dirname}/${xen_basename} placeholder ${xen_args} ++ if [ "\$grub_platform" = "pc" -o "\$grub_platform" = "" ]; then ++ xen_rm_opts= ++ else ++ xen_rm_opts="no-real-mode edd=off" ++ fi ++ multiboot ${rel_xen_dirname}/${xen_basename} placeholder ${xen_args} \${xen_rm_opts} + echo '$(echo "$lmessage" | grub_quote)' + module ${rel_dirname}/${basename} placeholder root=${linux_root_device_thisversion} ro ${args} + EOF +-- +1.8.1.4 + diff --git a/0231-Replace-the-region-at-0-from-coreboot-tables-to-avai.patch b/0231-Replace-the-region-at-0-from-coreboot-tables-to-avai.patch new file mode 100644 index 0000000..e4d71c4 --- /dev/null +++ b/0231-Replace-the-region-at-0-from-coreboot-tables-to-avai.patch @@ -0,0 +1,127 @@ +From ba34f38a269b2cb0deb9a6c0574d1d192e99f2aa Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Mon, 25 Mar 2013 10:23:04 +0100 +Subject: [PATCH 231/364] Replace the region at 0 from coreboot tables + to available in BSD memory map. + +--- + ChangeLog | 5 +++++ + grub-core/commands/lsmmap.c | 1 + + grub-core/kern/i386/coreboot/mmap.c | 6 +++++- + grub-core/loader/i386/bsd.c | 13 +++++++++++-- + grub-core/mmap/mmap.c | 1 + + include/grub/memory.h | 1 + + 6 files changed, 24 insertions(+), 3 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 981991b..8425aff 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,8 @@ ++2013-03-25 Vladimir Serbinenko ++ ++ Replace the region at 0 from coreboot tables to available in BSD ++ memory map. ++ + 2013-03-24 Vladimir Serbinenko + + * util/grub.d/20_linux_xen.in: Automatically add no-real-mode edd=off on +diff --git a/grub-core/commands/lsmmap.c b/grub-core/commands/lsmmap.c +index c1a05d8..0d29855 100644 +--- a/grub-core/commands/lsmmap.c ++++ b/grub-core/commands/lsmmap.c +@@ -37,6 +37,7 @@ static const char *names[] = + is required to save accross hibernations. */ + [GRUB_MEMORY_NVS] = N_("ACPI non-volatile storage RAM"), + [GRUB_MEMORY_BADRAM] = N_("faulty RAM (BadRAM)"), ++ [GRUB_MEMORY_COREBOOT_TABLES] = N_("RAM holding coreboot tables"), + [GRUB_MEMORY_CODE] = N_("RAM holding firmware code"), + [GRUB_MEMORY_HOLE] = N_("Address range not associated with RAM") + }; +diff --git a/grub-core/kern/i386/coreboot/mmap.c b/grub-core/kern/i386/coreboot/mmap.c +index 6a14d29..0aade62 100644 +--- a/grub-core/kern/i386/coreboot/mmap.c ++++ b/grub-core/kern/i386/coreboot/mmap.c +@@ -86,6 +86,8 @@ struct grub_machine_mmap_iterate_ctx + void *hook_data; + }; + ++#define GRUB_MACHINE_MEMORY_BADRAM 5 ++ + /* Helper for grub_machine_mmap_iterate. */ + static int + iterate_linuxbios_table (grub_linuxbios_table_item_t table_item, void *data) +@@ -105,7 +107,9 @@ iterate_linuxbios_table (grub_linuxbios_table_item_t table_item, void *data) + /* Multiboot mmaps match with the coreboot mmap + definition. Therefore, we can just pass type + through. */ +- mem_region->type, ctx->hook_data)) ++ (((mem_region->type <= GRUB_MACHINE_MEMORY_BADRAM) && (mem_region->type >= GRUB_MACHINE_MEMORY_AVAILABLE)) ++ || mem_region->type == GRUB_MEMORY_COREBOOT_TABLES) ? mem_region->type : GRUB_MEMORY_RESERVED, ++ ctx->hook_data)) + return 1; + + mem_region++; +diff --git a/grub-core/loader/i386/bsd.c b/grub-core/loader/i386/bsd.c +index e89ec26..5fe586f 100644 +--- a/grub-core/loader/i386/bsd.c ++++ b/grub-core/loader/i386/bsd.c +@@ -268,6 +268,7 @@ struct grub_e820_mmap + #define GRUB_E820_ACPI 3 + #define GRUB_E820_NVS 4 + #define GRUB_E820_BADRAM 5 ++#define GRUB_E820_COREBOOT_TABLES 0x10 + + /* Context for generate_e820_mmap. */ + struct generate_e820_mmap_ctx +@@ -299,13 +300,21 @@ generate_e820_mmap_iter (grub_uint64_t addr, grub_uint64_t size, + case GRUB_MEMORY_NVS: + ctx->cur.type = GRUB_E820_NVS; + break; +- ++ case GRUB_MEMORY_COREBOOT_TABLES: ++ /* Nowadays the tables at 0 don't contain anything important but ++ *BSD needs the memory at 0 for own needs. ++ */ ++ if (addr == 0) ++ ctx->cur.type = GRUB_E820_RAM; ++ else ++ ctx->cur.type = GRUB_E820_COREBOOT_TABLES; ++ break; + default: + case GRUB_MEMORY_CODE: + case GRUB_MEMORY_RESERVED: + ctx->cur.type = GRUB_E820_RESERVED; + break; +- } ++ } + + /* Merge regions if possible. */ + if (ctx->count && ctx->cur.type == ctx->prev.type +diff --git a/grub-core/mmap/mmap.c b/grub-core/mmap/mmap.c +index 40ffb2e..d8bd8d2 100644 +--- a/grub-core/mmap/mmap.c ++++ b/grub-core/mmap/mmap.c +@@ -47,6 +47,7 @@ static const int priority[] = + [GRUB_MEMORY_AVAILABLE] = 1, + [GRUB_MEMORY_RESERVED] = 3, + [GRUB_MEMORY_ACPI] = 2, ++ [GRUB_MEMORY_COREBOOT_TABLES] = 2, + [GRUB_MEMORY_CODE] = 3, + [GRUB_MEMORY_NVS] = 3, + [GRUB_MEMORY_HOLE] = 4, +diff --git a/include/grub/memory.h b/include/grub/memory.h +index 3311fcb..0df8074 100644 +--- a/include/grub/memory.h ++++ b/include/grub/memory.h +@@ -30,6 +30,7 @@ typedef enum grub_memory_type + GRUB_MEMORY_ACPI = 3, + GRUB_MEMORY_NVS = 4, + GRUB_MEMORY_BADRAM = 5, ++ GRUB_MEMORY_COREBOOT_TABLES = 16, + GRUB_MEMORY_CODE = 20, + /* This one is special: it's used internally but is never reported + by firmware. */ +-- +1.8.1.4 + diff --git a/0232-grub-core-normal-menu.c-Wait-if-there-were-errors-sh.patch b/0232-grub-core-normal-menu.c-Wait-if-there-were-errors-sh.patch new file mode 100644 index 0000000..150d162 --- /dev/null +++ b/0232-grub-core-normal-menu.c-Wait-if-there-were-errors-sh.patch @@ -0,0 +1,49 @@ +From 55073b6febd54c1dfe6366f9e8a4d945d1eb70ca Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Mon, 25 Mar 2013 10:32:06 +0100 +Subject: [PATCH 232/364] * grub-core/normal/menu.c: Wait if there were + errors shown at "boot" command. + +--- + ChangeLog | 5 +++++ + grub-core/normal/menu.c | 5 +++++ + 2 files changed, 10 insertions(+) + +diff --git a/ChangeLog b/ChangeLog +index 8425aff..5ca62d0 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,10 @@ + 2013-03-25 Vladimir Serbinenko + ++ * grub-core/normal/menu.c: Wait if there were errors shown at "boot" ++ command. ++ ++2013-03-25 Vladimir Serbinenko ++ + Replace the region at 0 from coreboot tables to available in BSD + memory map. + +diff --git a/grub-core/normal/menu.c b/grub-core/normal/menu.c +index 7e0a158..787b287 100644 +--- a/grub-core/normal/menu.c ++++ b/grub-core/normal/menu.c +@@ -250,10 +250,15 @@ grub_menu_execute_entry(grub_menu_entry_t entry, int auto_boot) + if (errs_before != grub_err_printed_errors) + grub_wait_after_message (); + ++ errs_before = grub_err_printed_errors; ++ + if (grub_errno == GRUB_ERR_NONE && grub_loader_is_loaded ()) + /* Implicit execution of boot, only if something is loaded. */ + grub_command_execute ("boot", 0, 0); + ++ if (errs_before != grub_err_printed_errors) ++ grub_wait_after_message (); ++ + if (entry->submenu) + { + if (menu && menu->size) +-- +1.8.1.4 + diff --git a/0233-grub-core-disk-ahci.c-Give-more-time-for-AHCI-reques.patch b/0233-grub-core-disk-ahci.c-Give-more-time-for-AHCI-reques.patch new file mode 100644 index 0000000..18c1b9e --- /dev/null +++ b/0233-grub-core-disk-ahci.c-Give-more-time-for-AHCI-reques.patch @@ -0,0 +1,41 @@ +From e8d8a43fd12c2a407358bed74697c168578ca1e5 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Mon, 25 Mar 2013 10:32:56 +0100 +Subject: [PATCH 233/364] * grub-core/disk/ahci.c: Give more time for + AHCI request. + +--- + ChangeLog | 4 ++++ + grub-core/disk/ahci.c | 2 +- + 2 files changed, 5 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index 5ca62d0..615c9a1 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,9 @@ + 2013-03-25 Vladimir Serbinenko + ++ * grub-core/disk/ahci.c: Give more time for AHCI request. ++ ++2013-03-25 Vladimir Serbinenko ++ + * grub-core/normal/menu.c: Wait if there were errors shown at "boot" + command. + +diff --git a/grub-core/disk/ahci.c b/grub-core/disk/ahci.c +index f9258fd..143ab97 100644 +--- a/grub-core/disk/ahci.c ++++ b/grub-core/disk/ahci.c +@@ -619,7 +619,7 @@ grub_ahci_readwrite_real (struct grub_ahci_device *dev, + grub_dprintf ("ahci", "AHCI tfd = %x\n", + dev->hba->ports[dev->port].task_file_data); + +- endtime = grub_get_time_ms () + (spinup ? 10000 : 1000); ++ endtime = grub_get_time_ms () + (spinup ? 10000 : 5000); + while ((dev->hba->ports[dev->port].command_issue & 1)) + if (grub_get_time_ms () > endtime) + { +-- +1.8.1.4 + diff --git a/0234-grub-core-gfxmenu-font.c-grub_font_get_string_width-.patch b/0234-grub-core-gfxmenu-font.c-grub_font_get_string_width-.patch new file mode 100644 index 0000000..aa9aa42 --- /dev/null +++ b/0234-grub-core-gfxmenu-font.c-grub_font_get_string_width-.patch @@ -0,0 +1,39 @@ +From 4560492f5a1aa3dcedc05a628b79ee3ce8d2dd20 Mon Sep 17 00:00:00 2001 +From: Vladimir Testov +Date: Tue, 26 Mar 2013 08:26:01 +0100 +Subject: [PATCH 234/364] * grub-core/gfxmenu/font.c + (grub_font_get_string_width): Fix memory leak. + +--- + ChangeLog | 5 +++++ + grub-core/gfxmenu/font.c | 1 + + 2 files changed, 6 insertions(+) + +diff --git a/ChangeLog b/ChangeLog +index 615c9a1..399b72f 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,8 @@ ++2013-03-26 Vladimir Testov ++ ++ * grub-core/gfxmenu/font.c (grub_font_get_string_width): Fix ++ memory leak. ++ + 2013-03-25 Vladimir Serbinenko + + * grub-core/disk/ahci.c: Give more time for AHCI request. +diff --git a/grub-core/gfxmenu/font.c b/grub-core/gfxmenu/font.c +index 7174837..4a8e1f1 100644 +--- a/grub-core/gfxmenu/font.c ++++ b/grub-core/gfxmenu/font.c +@@ -104,6 +104,7 @@ grub_font_get_string_width (grub_font_t font, const char *str) + + grub_free (glyph.combining); + } ++ grub_free (logical); + + return width; + } +-- +1.8.1.4 + diff --git a/0235-grub-core-commands-acpihalt.c-skip_ext_op-Add-suppor.patch b/0235-grub-core-commands-acpihalt.c-skip_ext_op-Add-suppor.patch new file mode 100644 index 0000000..a727b16 --- /dev/null +++ b/0235-grub-core-commands-acpihalt.c-skip_ext_op-Add-suppor.patch @@ -0,0 +1,225 @@ +From 7dca4f4e8f3666892b8139529213fd394844815f Mon Sep 17 00:00:00 2001 +From: Colin Watson +Date: Tue, 26 Mar 2013 11:29:52 +0100 +Subject: [PATCH 235/364] * grub-core/commands/acpihalt.c (skip_ext_op): + Add support for skipping Event, Device, Processor, PowerRes, + ThermalZone, and BankField extended opcodes. (get_sleep_type): + Add minimal scope handling (just enough to handle setting the scope to + the root path). (grub_acpi_halt): Parse any SSDTs as well as the + DSDT. * include/grub/acpi.h: Add enumeration values for Event, Device, + Processor, PowerRes, ThermalZone, and BankField extended opcodes. + +--- + ChangeLog | 11 ++++++ + grub-core/commands/acpihalt.c | 82 ++++++++++++++++++++++++++++++++----------- + include/grub/acpi.h | 6 ++++ + 3 files changed, 78 insertions(+), 21 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 399b72f..07a69bc 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,14 @@ ++2013-03-26 Colin Watson ++ ++ * grub-core/commands/acpihalt.c (skip_ext_op): Add support for ++ skipping Event, Device, Processor, PowerRes, ThermalZone, and ++ BankField extended opcodes. ++ (get_sleep_type): Add minimal scope handling (just enough to ++ handle setting the scope to the root path). ++ (grub_acpi_halt): Parse any SSDTs as well as the DSDT. ++ * include/grub/acpi.h: Add enumeration values for Event, Device, ++ Processor, PowerRes, ThermalZone, and BankField extended opcodes. ++ + 2013-03-26 Vladimir Testov + + * grub-core/gfxmenu/font.c (grub_font_get_string_width): Fix +diff --git a/grub-core/commands/acpihalt.c b/grub-core/commands/acpihalt.c +index 3db224d..a8014de 100644 +--- a/grub-core/commands/acpihalt.c ++++ b/grub-core/commands/acpihalt.c +@@ -41,6 +41,7 @@ typedef uint8_t grub_uint8_t; + #endif + + #ifndef GRUB_DSDT_TEST ++#include + #include + #include + #include +@@ -146,6 +147,10 @@ skip_ext_op (const grub_uint8_t *ptr, const grub_uint8_t *end) + ptr += skip_name_string (ptr, end); + ptr++; + break; ++ case GRUB_ACPI_EXTOPCODE_EVENT_OP: ++ ptr++; ++ ptr += skip_name_string (ptr, end); ++ break; + case GRUB_ACPI_EXTOPCODE_OPERATION_REGION: + ptr++; + ptr += skip_name_string (ptr, end); +@@ -158,7 +163,12 @@ skip_ext_op (const grub_uint8_t *ptr, const grub_uint8_t *end) + return 0; + break; + case GRUB_ACPI_EXTOPCODE_FIELD_OP: ++ case GRUB_ACPI_EXTOPCODE_DEVICE_OP: ++ case GRUB_ACPI_EXTOPCODE_PROCESSOR_OP: ++ case GRUB_ACPI_EXTOPCODE_POWER_RES_OP: ++ case GRUB_ACPI_EXTOPCODE_THERMAL_ZONE_OP: + case GRUB_ACPI_EXTOPCODE_INDEX_FIELD_OP: ++ case GRUB_ACPI_EXTOPCODE_BANK_FIELD_OP: + ptr++; + ptr += decode_length (ptr, 0); + break; +@@ -170,12 +180,14 @@ skip_ext_op (const grub_uint8_t *ptr, const grub_uint8_t *end) + } + + static int +-get_sleep_type (grub_uint8_t *table, grub_uint8_t *end) ++get_sleep_type (grub_uint8_t *table, grub_uint8_t *ptr, grub_uint8_t *end, ++ grub_uint8_t *scope, int scope_len) + { +- grub_uint8_t *ptr, *prev = table; +- int sleep_type = -1; ++ grub_uint8_t *prev = table; ++ int sleep_type = -2; + +- ptr = table + sizeof (struct grub_acpi_table_header); ++ if (!ptr) ++ ptr = table + sizeof (struct grub_acpi_table_header); + while (ptr < end && prev < ptr) + { + int add; +@@ -202,7 +214,8 @@ get_sleep_type (grub_uint8_t *table, grub_uint8_t *end) + } + case GRUB_ACPI_OPCODE_NAME: + ptr++; +- if (memcmp (ptr, "_S5_", 4) == 0 || memcmp (ptr, "\\_S5_", 4) == 0) ++ if ((!scope || memcmp (scope, "\\", scope_len) == 0) && ++ (memcmp (ptr, "_S5_", 4) == 0 || memcmp (ptr, "\\_S5_", 4) == 0)) + { + int ll; + grub_uint8_t *ptr2 = ptr; +@@ -241,6 +254,25 @@ get_sleep_type (grub_uint8_t *table, grub_uint8_t *end) + return -1; + break; + case GRUB_ACPI_OPCODE_SCOPE: ++ { ++ int scope_sleep_type; ++ int ll; ++ grub_uint8_t *name; ++ int name_len; ++ ++ ptr++; ++ add = decode_length (ptr, &ll); ++ name = ptr + ll; ++ name_len = skip_name_string (name, ptr + add); ++ if (!name_len) ++ return -1; ++ scope_sleep_type = get_sleep_type (table, name + name_len, ++ ptr + add, name, name_len); ++ if (scope_sleep_type != -2) ++ return scope_sleep_type; ++ ptr += add; ++ break; ++ } + case GRUB_ACPI_OPCODE_IF: + case GRUB_ACPI_OPCODE_METHOD: + { +@@ -291,7 +323,7 @@ main (int argc, char **argv) + return 2; + } + +- printf ("Sleep type = %d\n", get_sleep_type (buf, buf + len)); ++ printf ("Sleep type = %d\n", get_sleep_type (buf, NULL, buf + len, NULL, 0)); + free (buf); + fclose (f); + return 0; +@@ -304,8 +336,10 @@ grub_acpi_halt (void) + { + struct grub_acpi_rsdp_v20 *rsdp2; + struct grub_acpi_rsdp_v10 *rsdp1; +- struct grub_acpi_table_header *rsdt; +- grub_uint32_t *entry_ptr; ++ struct grub_acpi_table_header *rsdt; ++ grub_uint32_t *entry_ptr; ++ grub_uint32_t port = 0; ++ int sleep_type = -1; + + rsdp2 = grub_acpi_get_rsdpv2 (); + if (rsdp2) +@@ -324,33 +358,39 @@ grub_acpi_halt (void) + { + if (grub_memcmp ((void *) (grub_addr_t) *entry_ptr, "FACP", 4) == 0) + { +- grub_uint32_t port; + struct grub_acpi_fadt *fadt + = ((struct grub_acpi_fadt *) (grub_addr_t) *entry_ptr); + struct grub_acpi_table_header *dsdt + = (struct grub_acpi_table_header *) (grub_addr_t) fadt->dsdt_addr; +- int sleep_type = -1; ++ grub_uint8_t *buf = (grub_uint8_t *) dsdt; + + port = fadt->pm1a; + + grub_dprintf ("acpi", "PM1a port=%x\n", port); + + if (grub_memcmp (dsdt->signature, "DSDT", +- sizeof (dsdt->signature)) != 0) +- break; ++ sizeof (dsdt->signature)) == 0) ++ sleep_type = get_sleep_type (buf, NULL, buf + dsdt->length, ++ NULL, 0); ++ } ++ else if (grub_memcmp ((void *) (grub_addr_t) *entry_ptr, "SSDT", 4) == 0) ++ { ++ struct grub_acpi_table_header *ssdt ++ = (struct grub_acpi_table_header *) (grub_addr_t) *entry_ptr; ++ grub_uint8_t *buf = (grub_uint8_t *) ssdt; + +- sleep_type = get_sleep_type ((grub_uint8_t *) dsdt, +- (grub_uint8_t *) dsdt + dsdt->length); ++ grub_dprintf ("acpi", "SSDT = %p\n", ssdt); + +- if (sleep_type < 0 || sleep_type >= 8) +- break; ++ sleep_type = get_sleep_type (buf, NULL, buf + ssdt->length, NULL, 0); ++ } ++ } + +- grub_dprintf ("acpi", "SLP_TYP = %d, port = 0x%x\n", +- sleep_type, port); ++ if (port && sleep_type >= 0 && sleep_type < 8) ++ { ++ grub_dprintf ("acpi", "SLP_TYP = %d, port = 0x%x\n", sleep_type, port); + +- grub_outw (GRUB_ACPI_SLP_EN +- | (sleep_type << GRUB_ACPI_SLP_TYP_OFFSET), port & 0xffff); +- } ++ grub_outw (GRUB_ACPI_SLP_EN | (sleep_type << GRUB_ACPI_SLP_TYP_OFFSET), ++ port & 0xffff); + } + + grub_millisleep (1500); +diff --git a/include/grub/acpi.h b/include/grub/acpi.h +index 52d190c..8fa957d 100644 +--- a/include/grub/acpi.h ++++ b/include/grub/acpi.h +@@ -203,9 +203,15 @@ enum + enum + { + GRUB_ACPI_EXTOPCODE_MUTEX = 0x01, ++ GRUB_ACPI_EXTOPCODE_EVENT_OP = 0x02, + GRUB_ACPI_EXTOPCODE_OPERATION_REGION = 0x80, + GRUB_ACPI_EXTOPCODE_FIELD_OP = 0x81, ++ GRUB_ACPI_EXTOPCODE_DEVICE_OP = 0x82, ++ GRUB_ACPI_EXTOPCODE_PROCESSOR_OP = 0x83, ++ GRUB_ACPI_EXTOPCODE_POWER_RES_OP = 0x84, ++ GRUB_ACPI_EXTOPCODE_THERMAL_ZONE_OP = 0x85, + GRUB_ACPI_EXTOPCODE_INDEX_FIELD_OP = 0x86, ++ GRUB_ACPI_EXTOPCODE_BANK_FIELD_OP = 0x87, + }; + + #endif /* ! GRUB_ACPI_HEADER */ +-- +1.8.1.4 + diff --git a/0236-grub-core-kern-efi-mm.c-grub_efi_finish_boot_service.patch b/0236-grub-core-kern-efi-mm.c-grub_efi_finish_boot_service.patch new file mode 100644 index 0000000..39e0282 --- /dev/null +++ b/0236-grub-core-kern-efi-mm.c-grub_efi_finish_boot_service.patch @@ -0,0 +1,91 @@ +From 7916d7c3a1e92dfbd8720a6275d7f23025abe612 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Tue, 26 Mar 2013 11:34:56 +0100 +Subject: [PATCH 236/364] * grub-core/kern/efi/mm.c + (grub_efi_finish_boot_services): Try terminating EFI services several + times due to quirks in some implementations. + +--- + ChangeLog | 6 ++++++ + grub-core/kern/efi/mm.c | 46 ++++++++++++++++++++++++++++++---------------- + 2 files changed, 36 insertions(+), 16 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 07a69bc..58c2242 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,9 @@ ++2013-03-26 Vladimir Serbinenko ++ ++ * grub-core/kern/efi/mm.c (grub_efi_finish_boot_services): ++ Try terminating EFI services several times due to quirks in some ++ implementations. ++ + 2013-03-26 Colin Watson + + * grub-core/commands/acpihalt.c (skip_ext_op): Add support for +diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c +index 351317b..77c9384 100644 +--- a/grub-core/kern/efi/mm.c ++++ b/grub-core/kern/efi/mm.c +@@ -160,27 +160,41 @@ grub_efi_finish_boot_services (grub_efi_uintn_t *outbuf_size, void *outbuf, + apple, sizeof (apple)) == 0); + #endif + +- if (grub_efi_get_memory_map (&finish_mmap_size, finish_mmap_buf, &finish_key, +- &finish_desc_size, &finish_desc_version) < 0) +- return grub_error (GRUB_ERR_IO, "couldn't retrieve memory map"); ++ while (1) ++ { ++ if (grub_efi_get_memory_map (&finish_mmap_size, finish_mmap_buf, &finish_key, ++ &finish_desc_size, &finish_desc_version) < 0) ++ return grub_error (GRUB_ERR_IO, "couldn't retrieve memory map"); + +- if (outbuf && *outbuf_size < finish_mmap_size) +- return grub_error (GRUB_ERR_IO, "memory map buffer is too small"); ++ if (outbuf && *outbuf_size < finish_mmap_size) ++ return grub_error (GRUB_ERR_IO, "memory map buffer is too small"); + +- finish_mmap_buf = grub_malloc (finish_mmap_size); +- if (!finish_mmap_buf) +- return grub_errno; ++ finish_mmap_buf = grub_malloc (finish_mmap_size); ++ if (!finish_mmap_buf) ++ return grub_errno; + +- if (grub_efi_get_memory_map (&finish_mmap_size, finish_mmap_buf, &finish_key, +- &finish_desc_size, &finish_desc_version) <= 0) +- return grub_error (GRUB_ERR_IO, "couldn't retrieve memory map"); ++ if (grub_efi_get_memory_map (&finish_mmap_size, finish_mmap_buf, &finish_key, ++ &finish_desc_size, &finish_desc_version) <= 0) ++ { ++ grub_free (finish_mmap_buf); ++ return grub_error (GRUB_ERR_IO, "couldn't retrieve memory map"); ++ } + +- b = grub_efi_system_table->boot_services; +- status = efi_call_2 (b->exit_boot_services, grub_efi_image_handle, +- finish_key); +- if (status != GRUB_EFI_SUCCESS) +- return grub_error (GRUB_ERR_IO, "couldn't terminate EFI services"); ++ b = grub_efi_system_table->boot_services; ++ status = efi_call_2 (b->exit_boot_services, grub_efi_image_handle, ++ finish_key); ++ if (status == GRUB_EFI_SUCCESS) ++ break; + ++ if (status != GRUB_EFI_INVALID_PARAMETER) ++ { ++ grub_free (finish_mmap_buf); ++ return grub_error (GRUB_ERR_IO, "couldn't terminate EFI services"); ++ } ++ ++ grub_free (finish_mmap_buf); ++ grub_printf ("Trying to terminate EFI services again\n"); ++ } + grub_efi_is_finished = 1; + if (outbuf_size) + *outbuf_size = finish_mmap_size; +-- +1.8.1.4 + diff --git a/0237-grub-core-commands-verify.c-Fix-hash-algorithms-valu.patch b/0237-grub-core-commands-verify.c-Fix-hash-algorithms-valu.patch new file mode 100644 index 0000000..97980ea --- /dev/null +++ b/0237-grub-core-commands-verify.c-Fix-hash-algorithms-valu.patch @@ -0,0 +1,43 @@ +From 41554b3b4fc818587dc532bfe045c282185903be Mon Sep 17 00:00:00 2001 +From: Andrey Borzenkov +Date: Mon, 1 Apr 2013 01:43:04 +0200 +Subject: [PATCH 237/364] * grub-core/commands/verify.c: Fix hash + algorithms values for the first three hashes - they start with 1, not with + 0. + +--- + ChangeLog | 5 +++++ + grub-core/commands/verify.c | 4 +++- + 2 files changed, 8 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index 58c2242..672aa74 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,8 @@ ++2013-03-31 Andrey Borzenkov ++ ++ * grub-core/commands/verify.c: Fix hash algorithms values for ++ the first three hashes - they start with 1, not with 0. ++ + 2013-03-26 Vladimir Serbinenko + + * grub-core/kern/efi/mm.c (grub_efi_finish_boot_services): +diff --git a/grub-core/commands/verify.c b/grub-core/commands/verify.c +index 6c0b580..b4d5e7b 100644 +--- a/grub-core/commands/verify.c ++++ b/grub-core/commands/verify.c +@@ -123,7 +123,9 @@ struct signature_v4_header + } __attribute__ ((packed)); + + const char *hashes[] = { +- "md5", "sha1", "ripemd160", ++ [0x01] = "md5", ++ [0x02] = "sha1", ++ [0x03] = "ripemd160", + [0x08] = "sha256", + [0x09] = "sha384", + [0x0a] = "sha512", +-- +1.8.1.4 + diff --git a/0238-INSTALL-Mention-xorriso-requirement.patch b/0238-INSTALL-Mention-xorriso-requirement.patch new file mode 100644 index 0000000..3878844 --- /dev/null +++ b/0238-INSTALL-Mention-xorriso-requirement.patch @@ -0,0 +1,37 @@ +From 1a0d5df4f75260dd999aef39a79532a7adb24bb1 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rados=C5=82aw=20Szymczyszyn?= +Date: Mon, 1 Apr 2013 02:55:10 +0200 +Subject: [PATCH 238/364] * INSTALL: Mention xorriso requirement. + +--- + ChangeLog | 4 ++++ + INSTALL | 1 + + 2 files changed, 5 insertions(+) + +diff --git a/ChangeLog b/ChangeLog +index 672aa74..18c871f 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,7 @@ ++2013-04-01 Radosław Szymczyszyn ++ ++ * INSTALL: Mention xorriso requirement. ++ + 2013-03-31 Andrey Borzenkov + + * grub-core/commands/verify.c: Fix hash algorithms values for +diff --git a/INSTALL b/INSTALL +index e325fa2..128bf47 100644 +--- a/INSTALL ++++ b/INSTALL +@@ -45,6 +45,7 @@ need the following. + Prerequisites for make-check: + + * qemu, specifically the binary 'qemu-system-i386' ++* xorriso, for grub-mkrescue and grub-shell + + Configuring the GRUB + ==================== +-- +1.8.1.4 + diff --git a/0239-grub-core-partmap-apple.c-apple_partition_map_iterat.patch b/0239-grub-core-partmap-apple.c-apple_partition_map_iterat.patch new file mode 100644 index 0000000..484f1c4 --- /dev/null +++ b/0239-grub-core-partmap-apple.c-apple_partition_map_iterat.patch @@ -0,0 +1,51 @@ +From ab72a23a2a1fe9990661a31bdc71ffd951489636 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rados=C5=82aw=20Szymczyszyn?= +Date: Mon, 1 Apr 2013 02:58:47 +0200 +Subject: [PATCH 239/364] * grub-core/partmap/apple.c + (apple_partition_map_iterate): Add missing closing bracket. + +--- + ChangeLog | 5 +++++ + grub-core/partmap/apple.c | 4 ++-- + 2 files changed, 7 insertions(+), 2 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 18c871f..969a90f 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,10 @@ + 2013-04-01 Radosław Szymczyszyn + ++ * grub-core/partmap/apple.c (apple_partition_map_iterate): Add ++ missing closing bracket. ++ ++2013-04-01 Radosław Szymczyszyn ++ + * INSTALL: Mention xorriso requirement. + + 2013-03-31 Andrey Borzenkov +diff --git a/grub-core/partmap/apple.c b/grub-core/partmap/apple.c +index f4e608f..c3ead0f 100644 +--- a/grub-core/partmap/apple.c ++++ b/grub-core/partmap/apple.c +@@ -118,7 +118,7 @@ apple_partition_map_iterate (grub_disk_t disk, + if (grub_be_to_cpu16 (aheader.magic) != GRUB_APPLE_HEADER_MAGIC) + { + grub_dprintf ("partition", +- "bad magic (found 0x%x; wanted 0x%x\n", ++ "bad magic (found 0x%x; wanted 0x%x)\n", + grub_be_to_cpu16 (aheader.magic), + GRUB_APPLE_HEADER_MAGIC); + goto fail; +@@ -138,7 +138,7 @@ apple_partition_map_iterate (grub_disk_t disk, + if (grub_be_to_cpu16 (apart.magic) != GRUB_APPLE_PART_MAGIC) + { + grub_dprintf ("partition", +- "partition %d: bad magic (found 0x%x; wanted 0x%x\n", ++ "partition %d: bad magic (found 0x%x; wanted 0x%x)\n", + partno, grub_be_to_cpu16 (apart.magic), + GRUB_APPLE_PART_MAGIC); + break; +-- +1.8.1.4 + diff --git a/0240-grub-core-gfxmenu-gui_circular_progress.c-Fix-off-by.patch b/0240-grub-core-gfxmenu-gui_circular_progress.c-Fix-off-by.patch new file mode 100644 index 0000000..1369344 --- /dev/null +++ b/0240-grub-core-gfxmenu-gui_circular_progress.c-Fix-off-by.patch @@ -0,0 +1,45 @@ +From 67ce00e14b3ba739178e9effc215744e4634e4da Mon Sep 17 00:00:00 2001 +From: Vladimir Testov +Date: Wed, 3 Apr 2013 08:51:13 +0200 +Subject: [PATCH 240/364] * grub-core/gfxmenu/gui_circular_progress.c: + Fix off-by-one error. + +--- + ChangeLog | 4 ++++ + grub-core/gfxmenu/gui_circular_progress.c | 4 ++-- + 2 files changed, 6 insertions(+), 2 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 969a90f..ebc71eb 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,7 @@ ++2013-04-03 Vladimir Testov ++ ++ * grub-core/gfxmenu/gui_circular_progress.c: Fix off-by-one error. ++ + 2013-04-01 Radosław Szymczyszyn + + * grub-core/partmap/apple.c (apple_partition_map_iterate): Add +diff --git a/grub-core/gfxmenu/gui_circular_progress.c b/grub-core/gfxmenu/gui_circular_progress.c +index 098ae1c..d07ca6e 100644 +--- a/grub-core/gfxmenu/gui_circular_progress.c ++++ b/grub-core/gfxmenu/gui_circular_progress.c +@@ -152,12 +152,12 @@ circprog_paint (void *vself, const grub_video_rect_t *region) + if (self->ticks_disappear) + { + tick_begin = nticks; +- tick_end = self->num_ticks - 1; ++ tick_end = self->num_ticks; + } + else + { + tick_begin = 0; +- tick_end = nticks - 1; ++ tick_end = nticks; + } + + int i; +-- +1.8.1.4 + diff --git a/0241-grub-core-gfxmenu-view.c-Fix-off-by-one-error.patch b/0241-grub-core-gfxmenu-view.c-Fix-off-by-one-error.patch new file mode 100644 index 0000000..999044e --- /dev/null +++ b/0241-grub-core-gfxmenu-view.c-Fix-off-by-one-error.patch @@ -0,0 +1,41 @@ +From 7be9ea372ccf543e52f5a3d047d3e2023cd9e6b7 Mon Sep 17 00:00:00 2001 +From: Vladimir Testov +Date: Wed, 3 Apr 2013 08:53:58 +0200 +Subject: [PATCH 241/364] * grub-core/gfxmenu/view.c: Fix off-by-one + error. + +--- + ChangeLog | 4 ++++ + grub-core/gfxmenu/view.c | 2 +- + 2 files changed, 5 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index ebc71eb..8bdb17a 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,9 @@ + 2013-04-03 Vladimir Testov + ++ * grub-core/gfxmenu/view.c: Fix off-by-one error. ++ ++2013-04-03 Vladimir Testov ++ + * grub-core/gfxmenu/gui_circular_progress.c: Fix off-by-one error. + + 2013-04-01 Radosław Szymczyszyn +diff --git a/grub-core/gfxmenu/view.c b/grub-core/gfxmenu/view.c +index 1918ea4..6de96ca 100644 +--- a/grub-core/gfxmenu/view.c ++++ b/grub-core/gfxmenu/view.c +@@ -195,7 +195,7 @@ grub_gfxmenu_print_timeout (int timeout, void *data) + if (view->first_timeout == -1) + view->first_timeout = timeout; + +- update_timeouts (1, -(view->first_timeout + 1), -timeout, 0); ++ update_timeouts (1, -view->first_timeout, -timeout, 0); + redraw_timeouts (view); + grub_video_swap_buffers (); + if (view->double_repaint) +-- +1.8.1.4 + diff --git a/0242-grub-core-gfxmenu-gui_circular_progress.c-Take-both-.patch b/0242-grub-core-gfxmenu-gui_circular_progress.c-Take-both-.patch new file mode 100644 index 0000000..4d9be74 --- /dev/null +++ b/0242-grub-core-gfxmenu-gui_circular_progress.c-Take-both-.patch @@ -0,0 +1,55 @@ +From a2575f0e5de45c022ed54a5b368e82b2a688c73e Mon Sep 17 00:00:00 2001 +From: Vladimir Testov +Date: Wed, 3 Apr 2013 09:20:29 +0200 +Subject: [PATCH 242/364] * grub-core/gfxmenu/gui_circular_progress.c: + Take both width and height into account when calculating radius. + +--- + ChangeLog | 6 ++++++ + grub-core/gfxmenu/gui_circular_progress.c | 2 +- + include/grub/misc.h | 3 +++ + 3 files changed, 10 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index 8bdb17a..92e8dad 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,4 +1,10 @@ + 2013-04-03 Vladimir Testov ++2013-04-03 Vladimir Serbinenko ++ ++ * grub-core/gfxmenu/gui_circular_progress.c: Take both width and height ++ into account when calculating radius. ++ ++2013-04-03 Vladimir Testov + + * grub-core/gfxmenu/view.c: Fix off-by-one error. + +diff --git a/grub-core/gfxmenu/gui_circular_progress.c b/grub-core/gfxmenu/gui_circular_progress.c +index d07ca6e..e06d40c 100644 +--- a/grub-core/gfxmenu/gui_circular_progress.c ++++ b/grub-core/gfxmenu/gui_circular_progress.c +@@ -138,7 +138,7 @@ circprog_paint (void *vself, const grub_video_rect_t *region) + (height - center_height) / 2, 0, 0, + center_width, center_height); + +- int radius = width / 2 - tick_width / 2 - 1; ++ int radius = grub_min (height, width) / 2 - grub_max (tick_height, tick_width) / 2 - 1; + int nticks; + int tick_begin; + int tick_end; +diff --git a/include/grub/misc.h b/include/grub/misc.h +index f0ecaec..c953a00 100644 +--- a/include/grub/misc.h ++++ b/include/grub/misc.h +@@ -478,4 +478,7 @@ void EXPORT_FUNC(grub_real_boot_time) (const char *file, + #define grub_boot_time(fmt, args...) + #endif + ++#define grub_max(a, b) (((a) > (b)) ? (a) : (b)) ++#define grub_min(a, b) (((a) < (b)) ? (a) : (b)) ++ + #endif /* ! GRUB_MISC_HEADER */ +-- +1.8.1.4 + diff --git a/0243-grub-core-gfxmenu-gui_progress_bar.c-Handle-padding-.patch b/0243-grub-core-gfxmenu-gui_progress_bar.c-Handle-padding-.patch new file mode 100644 index 0000000..afe5ecc --- /dev/null +++ b/0243-grub-core-gfxmenu-gui_progress_bar.c-Handle-padding-.patch @@ -0,0 +1,53 @@ +From 911b53873d4c24656d2587650103ca3af081fa61 Mon Sep 17 00:00:00 2001 +From: Vladimir Testov +Date: Wed, 3 Apr 2013 09:34:08 +0200 +Subject: [PATCH 243/364] * grub-core/gfxmenu/gui_progress_bar.c: Handle + padding sizes. + +--- + ChangeLog | 4 ++++ + grub-core/gfxmenu/gui_progress_bar.c | 8 +++++++- + 2 files changed, 11 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index 92e8dad..5e516dc 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,4 +1,8 @@ + 2013-04-03 Vladimir Testov ++ ++ * grub-core/gfxmenu/gui_progress_bar.c: Handle padding sizes. ++ ++2013-04-03 Vladimir Testov + 2013-04-03 Vladimir Serbinenko + + * grub-core/gfxmenu/gui_circular_progress.c: Take both width and height +diff --git a/grub-core/gfxmenu/gui_progress_bar.c b/grub-core/gfxmenu/gui_progress_bar.c +index 7b005f4..965c6b3 100644 +--- a/grub-core/gfxmenu/gui_progress_bar.c ++++ b/grub-core/gfxmenu/gui_progress_bar.c +@@ -139,6 +139,12 @@ draw_pixmap_bar (grub_gui_progress_bar_t self) + 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 hl_l_pad = hl->get_left_pad (hl); ++ int hl_r_pad = hl->get_right_pad (hl); ++ int hl_t_pad = hl->get_top_pad (hl); ++ int hl_b_pad = hl->get_bottom_pad (hl); ++ int hl_h_pad = hl_l_pad + hl_r_pad; ++ int hl_v_pad = hl_t_pad + hl_b_pad; + int tracklen = w - bar_h_pad; + int trackheight = h - bar_v_pad; + int barwidth; +@@ -148,7 +154,7 @@ draw_pixmap_bar (grub_gui_progress_bar_t self) + barwidth = (tracklen * (self->value - self->start) + / (self->end - self->start)); + +- hl->set_content_size (hl, barwidth, h - bar_v_pad); ++ hl->set_content_size (hl, barwidth - hl_h_pad, h - bar_v_pad - hl_v_pad); + + bar->draw (bar, 0, 0); + hl->draw (hl, bar_l_pad, bar_t_pad); +-- +1.8.1.4 + diff --git a/0244-include-grub-elf.h-Add-missing-ARM-relocation-codes-.patch b/0244-include-grub-elf.h-Add-missing-ARM-relocation-codes-.patch new file mode 100644 index 0000000..2c54087 --- /dev/null +++ b/0244-include-grub-elf.h-Add-missing-ARM-relocation-codes-.patch @@ -0,0 +1,182 @@ +From d00603517b5b4226d3467765d46628db271ad887 Mon Sep 17 00:00:00 2001 +From: Francesco Lavra +Date: Wed, 3 Apr 2013 11:23:22 +0200 +Subject: [PATCH 244/364] * include/grub/elf.h: Add missing ARM + relocation codes and fix existing ones. + +--- + ChangeLog | 5 +++ + include/grub/elf.h | 110 ++++++++++++++++++++++++++++++++++++++++++++--------- + 2 files changed, 98 insertions(+), 17 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 5e516dc..56588dd 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,8 @@ ++2013-04-03 Francesco Lavra ++ ++ * include/grub/elf.h: Add missing ARM relocation codes and fix ++ existing ones. ++ + 2013-04-03 Vladimir Testov + + * grub-core/gfxmenu/gui_progress_bar.c: Handle padding sizes. +diff --git a/include/grub/elf.h b/include/grub/elf.h +index d4a2a5f..708cd6a 100644 +--- a/include/grub/elf.h ++++ b/include/grub/elf.h +@@ -2067,7 +2067,7 @@ typedef Elf32_Addr Elf32_Conflict; + #define R_ARM_PC24 1 /* PC relative 26 bit branch */ + #define R_ARM_ABS32 2 /* Direct 32 bit */ + #define R_ARM_REL32 3 /* PC relative 32 bit */ +-#define R_ARM_PC13 4 ++#define R_ARM_LDR_PC_G0 4 + #define R_ARM_ABS16 5 /* Direct 16 bit */ + #define R_ARM_ABS12 6 /* Direct 12 bit */ + #define R_ARM_THM_ABS5 7 +@@ -2075,18 +2075,21 @@ typedef Elf32_Addr Elf32_Conflict; + #define R_ARM_SBREL32 9 + #define R_ARM_THM_CALL 10 + #define R_ARM_THM_PC8 11 +-#define R_ARM_AMP_VCALL9 12 +-#define R_ARM_SWI24 13 ++#define R_ARM_BREL_ADJ 12 ++#define R_ARM_TLS_DESC 13 + #define R_ARM_THM_SWI8 14 + #define R_ARM_XPC25 15 + #define R_ARM_THM_XPC22 16 ++#define R_ARM_TLS_DTPMOD32 17 ++#define R_ARM_TLS_DTPOFF32 18 ++#define R_ARM_TLS_TPOFF32 19 + #define R_ARM_COPY 20 /* Copy symbol at runtime */ + #define R_ARM_GLOB_DAT 21 /* Create GOT entry */ + #define R_ARM_JUMP_SLOT 22 /* Create PLT entry */ + #define R_ARM_RELATIVE 23 /* Adjust by program base */ +-#define R_ARM_GOTOFF 24 /* 32 bit offset to GOT */ +-#define R_ARM_GOTPC 25 /* 32 bit PC relative offset to GOT */ +-#define R_ARM_GOT32 26 /* 32 bit GOT entry */ ++#define R_ARM_GOTOFF32 24 /* 32 bit offset to GOT */ ++#define R_ARM_BASE_PREL 25 /* 32 bit PC relative offset to GOT */ ++#define R_ARM_GOT_BREL 26 /* 32 bit GOT entry */ + #define R_ARM_PLT32 27 /* 32 bit PLT address */ + #define R_ARM_CALL 28 + #define R_ARM_JUMP24 29 +@@ -2098,14 +2101,72 @@ typedef Elf32_Addr Elf32_Conflict; + #define R_ARM_LDR_SBREL_11_0 35 + #define R_ARM_ALU_SBREL_19_12 36 + #define R_ARM_ALU_SBREL_27_20 37 ++#define R_ARM_TARGET1 38 ++#define R_ARM_SBREL31 39 ++#define R_ARM_V4BX 40 ++#define R_ARM_TARGET2 41 ++#define R_ARM_PREL31 42 ++#define R_ARM_MOVW_ABS_NC 43 ++#define R_ARM_MOVT_ABS 44 ++#define R_ARM_MOVW_PREL_NC 45 ++#define R_ARM_MOVT_PREL 46 ++#define R_ARM_THM_MOVW_ABS_NC 47 ++#define R_ARM_THM_MOVT_ABS 48 ++#define R_ARM_THM_MOVW_PREL_NC 49 ++#define R_ARM_THM_MOVT_PREL 50 ++#define R_ARM_THM_JUMP19 51 ++#define R_ARM_THM_JUMP6 52 ++#define R_ARM_THM_ALU_PREL_11_0 53 ++#define R_ARM_THM_PC12 54 ++#define R_ARM_ABS32_NOI 55 ++#define R_ARM_REL32_NOI 56 ++#define R_ARM_ALU_PC_G0_NC 57 ++#define R_ARM_ALU_PC_G0 58 ++#define R_ARM_ALU_PC_G1_NC 59 ++#define R_ARM_ALU_PC_G1 60 ++#define R_ARM_ALU_PC_G2 61 ++#define R_ARM_LDR_PC_G1 62 ++#define R_ARM_LDR_PC_G2 63 ++#define R_ARM_LDRS_PC_G0 64 ++#define R_ARM_LDRS_PC_G1 65 ++#define R_ARM_LDRS_PC_G2 66 ++#define R_ARM_LDC_PC_G0 67 ++#define R_ARM_LDC_PC_G1 68 ++#define R_ARM_LDC_PC_G2 69 ++#define R_ARM_ALU_SB_G0_NC 70 ++#define R_ARM_ALU_SB_G0 71 ++#define R_ARM_ALU_SB_G1_NC 72 ++#define R_ARM_ALU_SB_G1 73 ++#define R_ARM_ALU_SB_G2 74 ++#define R_ARM_LDR_SB_G0 75 ++#define R_ARM_LDR_SB_G1 76 ++#define R_ARM_LDR_SB_G2 77 ++#define R_ARM_LDRS_SB_G0 78 ++#define R_ARM_LDRS_SB_G1 79 ++#define R_ARM_LDRS_SB_G2 80 ++#define R_ARM_LDC_SB_G0 81 ++#define R_ARM_LDC_SB_G1 82 ++#define R_ARM_LDC_SB_G2 83 ++#define R_ARM_MOVW_BREL_NC 84 ++#define R_ARM_MOVT_BREL 85 ++#define R_ARM_MOVW_BREL 86 ++#define R_ARM_THM_MOVW_BREL_NC 87 ++#define R_ARM_THM_MOVT_BREL 88 ++#define R_ARM_THM_MOVW_BREL 89 + #define R_ARM_TLS_GOTDESC 90 + #define R_ARM_TLS_CALL 91 + #define R_ARM_TLS_DESCSEQ 92 + #define R_ARM_THM_TLS_CALL 93 ++#define R_ARM_PLT32_ABS 94 ++#define R_ARM_GOT_ABS 95 ++#define R_ARM_GOT_PREL 96 ++#define R_ARM_GOT_BREL12 97 ++#define R_ARM_GOTOFF12 98 ++#define R_ARM_GOTRELAX 99 + #define R_ARM_GNU_VTENTRY 100 + #define R_ARM_GNU_VTINHERIT 101 +-#define R_ARM_THM_PC11 102 /* thumb unconditional branch */ +-#define R_ARM_THM_PC9 103 /* thumb conditional branch */ ++#define R_ARM_THM_JUMP11 102 /* thumb unconditional branch */ ++#define R_ARM_THM_JUMP8 103 /* thumb conditional branch */ + #define R_ARM_TLS_GD32 104 /* PC-rel 32 bit for global dynamic + thread local data */ + #define R_ARM_TLS_LDM32 105 /* PC-rel 32 bit for local dynamic +@@ -2116,15 +2177,30 @@ typedef Elf32_Addr Elf32_Conflict; + static TLS block offset */ + #define R_ARM_TLS_LE32 108 /* 32 bit offset relative to static + TLS block */ +-#define R_ARM_THM_TLS_DESCSEQ 129 +-#define R_ARM_IRELATIVE 160 +-#define R_ARM_RXPC25 249 +-#define R_ARM_RSBREL32 250 +-#define R_ARM_THM_RPC22 251 +-#define R_ARM_RREL32 252 +-#define R_ARM_RABS22 253 +-#define R_ARM_RPC24 254 +-#define R_ARM_RBASE 255 ++#define R_ARM_TLS_LDO12 109 ++#define R_ARM_TLS_LE12 110 ++#define R_ARM_IE12GP 111 ++#define R_ARM_PRIVATE_0 112 ++#define R_ARM_PRIVATE_1 113 ++#define R_ARM_PRIVATE_2 114 ++#define R_ARM_PRIVATE_3 115 ++#define R_ARM_PRIVATE_4 116 ++#define R_ARM_PRIVATE_5 117 ++#define R_ARM_PRIVATE_6 118 ++#define R_ARM_PRIVATE_7 119 ++#define R_ARM_PRIVATE_8 120 ++#define R_ARM_PRIVATE_9 121 ++#define R_ARM_PRIVATE_10 122 ++#define R_ARM_PRIVATE_11 123 ++#define R_ARM_PRIVATE_12 124 ++#define R_ARM_PRIVATE_13 125 ++#define R_ARM_PRIVATE_14 126 ++#define R_ARM_PRIVATE_15 127 ++#define R_ARM_ME_TOO 128 ++#define R_ARM_THM_TLS_DESCSEQ16 129 ++#define R_ARM_THM_TLS_DESCSEQ32 130 ++#define R_ARM_THM_GOT_BREL12 131 ++#define R_ARM_IRELATIVE 140 + /* Keep this the last entry. */ + #define R_ARM_NUM 256 + +-- +1.8.1.4 + diff --git a/0245-util-grub-mount.c-fuse_init-Return-error-if-fuse_mai.patch b/0245-util-grub-mount.c-fuse_init-Return-error-if-fuse_mai.patch new file mode 100644 index 0000000..0e24c92 --- /dev/null +++ b/0245-util-grub-mount.c-fuse_init-Return-error-if-fuse_mai.patch @@ -0,0 +1,50 @@ +From 52556c462eeee3a3f10f79923dd3b9eff1e520e7 Mon Sep 17 00:00:00 2001 +From: Andrey Borzenkov +Date: Wed, 3 Apr 2013 11:28:16 +0200 +Subject: [PATCH 245/364] * util/grub-mount.c (fuse_init): Return error + if fuse_main failed. + +--- + ChangeLog | 5 +++++ + util/grub-mount.c | 5 +++-- + 2 files changed, 8 insertions(+), 2 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 56588dd..7cda161 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,8 @@ ++2013-04-03 Andrey Borzenkov ++ ++ * util/grub-mount.c (fuse_init): Return error if fuse_main ++ failed. ++ + 2013-04-03 Francesco Lavra + + * include/grub/elf.h: Add missing ARM relocation codes and fix +diff --git a/util/grub-mount.c b/util/grub-mount.c +index d0ab6a2..4a2333a 100644 +--- a/util/grub-mount.c ++++ b/util/grub-mount.c +@@ -407,7 +407,8 @@ fuse_init (void) + return grub_errno; + } + +- fuse_main (fuse_argc, fuse_args, &grub_opers, NULL); ++ if (fuse_main (fuse_argc, fuse_args, &grub_opers, NULL)) ++ grub_error (GRUB_ERR_IO, "fuse_main failed"); + + for (i = 0; i < num_disks; i++) + { +@@ -427,7 +428,7 @@ fuse_init (void) + grub_free (loop_name); + } + +- return GRUB_ERR_NONE; ++ return grub_errno; + } + + static struct argp_option options[] = { +-- +1.8.1.4 + diff --git a/0246-Fix-screen-corruption-in-menu-entry-editor-and-simpl.patch b/0246-Fix-screen-corruption-in-menu-entry-editor-and-simpl.patch new file mode 100644 index 0000000..97b52cc --- /dev/null +++ b/0246-Fix-screen-corruption-in-menu-entry-editor-and-simpl.patch @@ -0,0 +1,134 @@ +From 04ff4b20743dbb42ec7a61de0682574f694b10ea Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Wed, 3 Apr 2013 15:19:34 +0200 +Subject: [PATCH 246/364] Fix screen corruption in menu entry editor and + simplify the code flow while on it. + +--- + ChangeLog | 5 +++++ + grub-core/normal/menu_entry.c | 35 +++++------------------------------ + grub-core/normal/term.c | 15 ++++++++++++++- + 3 files changed, 24 insertions(+), 31 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 7cda161..0592cac 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,8 @@ ++2013-04-03 Vladimir Serbinenko ++ ++ Fix screen corruption in menu entry editor and simplify the code ++ flow while on it. ++ + 2013-04-03 Andrey Borzenkov + + * util/grub-mount.c (fuse_init): Return error if fuse_main +diff --git a/grub-core/normal/menu_entry.c b/grub-core/normal/menu_entry.c +index f4c8afd..80f9464 100644 +--- a/grub-core/normal/menu_entry.c ++++ b/grub-core/normal/menu_entry.c +@@ -253,49 +253,24 @@ update_screen (struct screen *screen, struct per_term_screen *term_screen, + if (!*pos) + *pos = grub_zalloc ((linep->len + 1) * sizeof (**pos)); + +- if (i == region_start || linep == screen->lines + screen->line) ++ if (i == region_start || linep == screen->lines + screen->line ++ || (i > region_start && mode == ALL_LINES)) + { +- int sp; +- grub_term_gotoxy (term_screen->term, GRUB_TERM_LEFT_BORDER_X +- + GRUB_TERM_MARGIN + 1, (y < 0 ? 0 : y) +- + GRUB_TERM_FIRST_ENTRY_Y); +- grub_print_ucs4_menu (linep->buf, +- linep->buf + linep->len, +- GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN +- + 1, +- GRUB_TERM_MARGIN +- + GRUB_TERM_SCROLL_WIDTH + 2, +- term_screen->term, +- (y < 0) ? -y : 0, +- term_screen->num_entries +- - ((y > 0) ? y : 0), '\\', +- *pos); +- sp = grub_term_entry_width (term_screen->term) +- - (*pos)[linep->len].x; +- if (sp > 0) +- grub_print_spaces (term_screen->term, sp); +- } +- else if (i > region_start && mode == ALL_LINES) +- { +- int sp; + grub_term_gotoxy (term_screen->term, GRUB_TERM_LEFT_BORDER_X + + GRUB_TERM_MARGIN + 1, (y < 0 ? 0 : y) + + GRUB_TERM_FIRST_ENTRY_Y); ++ + grub_print_ucs4_menu (linep->buf, + linep->buf + linep->len, + GRUB_TERM_LEFT_BORDER_X +- + GRUB_TERM_MARGIN + 1, ++ + GRUB_TERM_MARGIN + 1, + GRUB_TERM_MARGIN +- + GRUB_TERM_SCROLL_WIDTH + 2, ++ + GRUB_TERM_SCROLL_WIDTH, + term_screen->term, + (y < 0) ? -y : 0, + term_screen->num_entries + - ((y > 0) ? y : 0), '\\', + *pos); +- sp = grub_term_entry_width (term_screen->term) +- - (*pos)[linep->len].x; +- if (sp > 0) +- grub_print_spaces (term_screen->term, sp); + } + y += get_logical_num_lines (linep, term_screen); + if (y >= term_screen->num_entries) +diff --git a/grub-core/normal/term.c b/grub-core/normal/term.c +index 32deba3..f05184b 100644 +--- a/grub-core/normal/term.c ++++ b/grub-core/normal/term.c +@@ -690,6 +690,13 @@ print_ucs4_terminal (const grub_uint32_t * str, + line_width -= lastspacewidth; + if (ptr == last_space || *ptr == '\n') + ptr++; ++ else if (pos) ++ { ++ pos[ptr - str].x = line_width - last_width; ++ pos[ptr - str].y = lines; ++ pos[ptr - str].valid = 1; ++ } ++ + line_start = ptr; + + if (skip_lines) +@@ -726,6 +733,8 @@ print_ucs4_terminal (const grub_uint32_t * str, + if (!dry_run && !skip_lines && max_lines) + { + const grub_uint32_t *ptr2; ++ int sp; ++ + for (ptr2 = line_start; ptr2 < last_position; ptr2++) + { + /* Skip combining characters on non-UTF8 terminals. */ +@@ -736,6 +745,10 @@ print_ucs4_terminal (const grub_uint32_t * str, + continue; + putcode_real (*ptr2, term, fixed_tab); + } ++ ++ sp = max_width - pos[last_position - str].x + 1; ++ if (sp > 0) ++ grub_print_spaces (term, sp); + } + return dry_run ? lines : 0; + } +@@ -908,7 +921,7 @@ print_ucs4_real (const grub_uint32_t * str, + { + for (vptr = visual_show; + max_lines && vptr < visual + visual_len; vptr++) +- if (visual_show->base == '\n') ++ if (vptr->base == '\n') + max_lines--; + + visual_len_show = vptr - visual_show; +-- +1.8.1.4 + diff --git a/0247-grub-core-term-i386-pc-console.c-grub_console_getwh-.patch b/0247-grub-core-term-i386-pc-console.c-grub_console_getwh-.patch new file mode 100644 index 0000000..9c92a2d --- /dev/null +++ b/0247-grub-core-term-i386-pc-console.c-grub_console_getwh-.patch @@ -0,0 +1,44 @@ +From f83e8de1b9f832f9d3ef54ea4ba7f5694ac5a3ed Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Wed, 3 Apr 2013 15:21:51 +0200 +Subject: [PATCH 247/364] * grub-core/term/i386/pc/console.c + (grub_console_getwh): Decrease reported width by one to compensate + for curesor algorithm problem. + +--- + ChangeLog | 5 +++++ + grub-core/term/i386/pc/console.c | 3 ++- + 2 files changed, 7 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index 0592cac..b0c57bb 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,10 @@ + 2013-04-03 Vladimir Serbinenko + ++ * grub-core/term/i386/pc/console.c (grub_console_getwh): Decrease ++ reported width by one to compensate for curesor algorithm problem. ++ ++2013-04-03 Vladimir Serbinenko ++ + Fix screen corruption in menu entry editor and simplify the code + flow while on it. + +diff --git a/grub-core/term/i386/pc/console.c b/grub-core/term/i386/pc/console.c +index 2aa1943..ee6650b 100644 +--- a/grub-core/term/i386/pc/console.c ++++ b/grub-core/term/i386/pc/console.c +@@ -255,7 +255,8 @@ grub_console_getkeystatus (struct grub_term_input *term __attribute__ ((unused)) + static grub_uint16_t + grub_console_getwh (struct grub_term_output *term __attribute__ ((unused))) + { +- return (80 << 8) | 25; ++ /* Due to current cursor moving algorithm we lost the last column. */ ++ return (79 << 8) | 25; + } + + static void +-- +1.8.1.4 + diff --git a/0248-grub-core-commands-verify.c-Save-verified-file-to-av.patch b/0248-grub-core-commands-verify.c-Save-verified-file-to-av.patch new file mode 100644 index 0000000..48d7d4a --- /dev/null +++ b/0248-grub-core-commands-verify.c-Save-verified-file-to-av.patch @@ -0,0 +1,197 @@ +From 2923eb14c2e0feab103391314331a13f069df813 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Wed, 3 Apr 2013 17:32:33 +0200 +Subject: [PATCH 248/364] * grub-core/commands/verify.c: Save verified + file to avoid it being tampered with after verification was done. + +--- + ChangeLog | 5 +++ + grub-core/commands/verify.c | 98 +++++++++++++++++++++++++++++++++++++-------- + include/grub/misc.h | 2 + + 3 files changed, 88 insertions(+), 17 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index b0c57bb..6dc95ba 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,10 @@ + 2013-04-03 Vladimir Serbinenko + ++ * grub-core/commands/verify.c: Save verified file to avoid it being ++ tampered with after verification was done. ++ ++2013-04-03 Vladimir Serbinenko ++ + * grub-core/term/i386/pc/console.c (grub_console_getwh): Decrease + reported width by one to compensate for curesor algorithm problem. + +diff --git a/grub-core/commands/verify.c b/grub-core/commands/verify.c +index b4d5e7b..bd47611 100644 +--- a/grub-core/commands/verify.c ++++ b/grub-core/commands/verify.c +@@ -1,6 +1,6 @@ + /* + * GRUB -- GRand Unified Bootloader +- * Copyright (C) 2011 Free Software Foundation, Inc. ++ * Copyright (C) 2013 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 +@@ -338,9 +338,10 @@ grub_crypto_pk_locate_subkey_in_trustdb (grub_uint64_t keyid) + return 0; + } + +-grub_err_t +-grub_verify_signature (grub_file_t f, grub_file_t sig, +- struct grub_public_key *pkey) ++static grub_err_t ++grub_verify_signature_real (char *buf, grub_size_t size, ++ grub_file_t f, grub_file_t sig, ++ struct grub_public_key *pkey) + { + grub_size_t len; + grub_uint8_t v; +@@ -404,16 +405,19 @@ grub_verify_signature (grub_file_t f, grub_file_t sig, + + grub_memset (context, 0, sizeof (context)); + hash->init (context); +- while (1) +- { +- grub_uint8_t readbuf[4096]; +- r = grub_file_read (f, readbuf, sizeof (readbuf)); +- if (r < 0) +- return grub_errno; +- if (r == 0) +- break; +- hash->write (context, readbuf, r); +- } ++ if (buf) ++ hash->write (context, buf, size); ++ else ++ while (1) ++ { ++ grub_uint8_t readbuf[4096]; ++ r = grub_file_read (f, readbuf, sizeof (readbuf)); ++ if (r < 0) ++ return grub_errno; ++ if (r == 0) ++ break; ++ hash->write (context, readbuf, r); ++ } + + hash->write (context, &v, sizeof (v)); + hash->write (context, &v4, sizeof (v4)); +@@ -532,6 +536,13 @@ grub_verify_signature (grub_file_t f, grub_file_t sig, + return GRUB_ERR_NONE; + } + ++grub_err_t ++grub_verify_signature (grub_file_t f, grub_file_t sig, ++ struct grub_public_key *pkey) ++{ ++ return grub_verify_signature_real (0, 0, f, sig, pkey); ++} ++ + static grub_err_t + grub_cmd_trust (grub_command_t cmd __attribute__ ((unused)), + int argc, char **args) +@@ -665,6 +676,28 @@ grub_cmd_verify_signature (grub_command_t cmd __attribute__ ((unused)), + + static int sec = 0; + ++static grub_ssize_t ++verified_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 ++verified_close (struct grub_file *file) ++{ ++ grub_free (file->data); ++ file->data = 0; ++ return GRUB_ERR_NONE; ++} ++ ++struct grub_fs verified_fs = ++{ ++ .name = "verified_read", ++ .read = verified_read, ++ .close = verified_close ++}; ++ + static grub_file_t + grub_pubkey_open (grub_file_t io, const char *filename) + { +@@ -672,9 +705,12 @@ grub_pubkey_open (grub_file_t io, const char *filename) + char *fsuf, *ptr; + grub_err_t err; + grub_file_filter_t curfilt[GRUB_FILE_FILTER_MAX]; ++ grub_file_t ret; + + if (!sec) + return io; ++ if (io->device->disk && io->device->disk->id == GRUB_DISK_DEVICE_MEMDISK_ID) ++ return io; + fsuf = grub_malloc (grub_strlen (filename) + sizeof (".sig")); + if (!fsuf) + return NULL; +@@ -691,12 +727,40 @@ grub_pubkey_open (grub_file_t io, const char *filename) + if (!sig) + return NULL; + +- err = grub_verify_signature (io, sig, NULL); ++ ret = grub_malloc (sizeof (*ret)); ++ if (!ret) ++ return NULL; ++ *ret = *io; ++ ++ ret->fs = &verified_fs; ++ ret->not_easily_seekable = 0; ++ if (ret->size >> (sizeof (grub_size_t) * GRUB_CHAR_BIT - 1)) ++ { ++ grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, ++ "big file signature isn't implemented yet"); ++ return NULL; ++ } ++ ret->data = grub_malloc (ret->size); ++ if (!ret->data) ++ { ++ grub_free (ret); ++ return NULL; ++ } ++ if (grub_file_read (io, ret->data, ret->size) != (grub_ssize_t) ret->size) ++ { ++ if (!grub_errno) ++ grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"), ++ filename); ++ return NULL; ++ } ++ ++ err = grub_verify_signature_real (ret->data, ret->size, 0, sig, NULL); + grub_file_close (sig); + if (err) + return NULL; +- grub_file_seek (io, 0); +- return io; ++ io->device = 0; ++ grub_file_close (io); ++ return ret; + } + + static char * +diff --git a/include/grub/misc.h b/include/grub/misc.h +index c953a00..0ea5114 100644 +--- a/include/grub/misc.h ++++ b/include/grub/misc.h +@@ -481,4 +481,6 @@ void EXPORT_FUNC(grub_real_boot_time) (const char *file, + #define grub_max(a, b) (((a) > (b)) ? (a) : (b)) + #define grub_min(a, b) (((a) < (b)) ? (a) : (b)) + ++#define GRUB_CHAR_BIT 8 ++ + #endif /* ! GRUB_MISC_HEADER */ +-- +1.8.1.4 + diff --git a/0249-grub-core-lib-posix_wrap-locale.h-GRUB_UTIL-Include-.patch b/0249-grub-core-lib-posix_wrap-locale.h-GRUB_UTIL-Include-.patch new file mode 100644 index 0000000..eb87915 --- /dev/null +++ b/0249-grub-core-lib-posix_wrap-locale.h-GRUB_UTIL-Include-.patch @@ -0,0 +1,34 @@ +From fc4e8f971c20e45d49c3a252c119d1b27802f79f Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Thu, 4 Apr 2013 08:54:02 +0200 +Subject: [PATCH 249/364] * grub-core/lib/posix_wrap/locale.h + [GRUB_UTIL]: Include host locale.h. + +--- + ChangeLog | 4 ++++ + grub-core/lib/posix_wrap/locale.h | 3 +++ + 2 files changed, 7 insertions(+) + +diff --git a/ChangeLog b/ChangeLog +index 6dc95ba..467a621 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,7 @@ ++2013-04-04 Vladimir Serbinenko ++ ++ * grub-core/lib/posix_wrap/locale.h [GRUB_UTIL]: Include host locale.h. ++ + 2013-04-03 Vladimir Serbinenko + + * grub-core/commands/verify.c: Save verified file to avoid it being +diff --git a/grub-core/lib/posix_wrap/locale.h b/grub-core/lib/posix_wrap/locale.h +index e69de29..569a765 100644 +--- a/grub-core/lib/posix_wrap/locale.h ++++ b/grub-core/lib/posix_wrap/locale.h +@@ -0,0 +1,3 @@ ++#ifdef GRUB_UTIL ++#include_next ++#endif +-- +1.8.1.4 + diff --git a/0250-util-grub-setup.c-setup-Handle-some-corner-cases.patch b/0250-util-grub-setup.c-setup-Handle-some-corner-cases.patch new file mode 100644 index 0000000..df9bcb4 --- /dev/null +++ b/0250-util-grub-setup.c-setup-Handle-some-corner-cases.patch @@ -0,0 +1,68 @@ +From 14cd2eb249c43b97193fc8456e0ffa073537bdbd Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Thu, 4 Apr 2013 08:55:06 +0200 +Subject: [PATCH 250/364] * util/grub-setup.c (setup): Handle some + corner cases. + +--- + ChangeLog | 4 ++++ + util/grub-setup.c | 8 ++++++-- + 2 files changed, 10 insertions(+), 2 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 467a621..8a3fd45 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,9 @@ + 2013-04-04 Vladimir Serbinenko + ++ * util/grub-setup.c (setup): Handle some corner cases. ++ ++2013-04-04 Vladimir Serbinenko ++ + * grub-core/lib/posix_wrap/locale.h [GRUB_UTIL]: Include host locale.h. + + 2013-04-03 Vladimir Serbinenko +diff --git a/util/grub-setup.c b/util/grub-setup.c +index 5a7a857..27a815f 100644 +--- a/util/grub-setup.c ++++ b/util/grub-setup.c +@@ -256,7 +256,7 @@ setup (const char *dir, + grub_device_t root_dev = 0, dest_dev, core_dev; + struct blocklists bl; + char *tmp_img; +- grub_disk_addr_t first_sector; ++ grub_disk_addr_t first_sector = (grub_disk_addr_t)-1; + FILE *fp; + + #ifdef GRUB_SETUP_BIOS +@@ -756,6 +756,8 @@ unable_to_embed: + grub_util_error ("%s", _("blocksize is not divisible by 512")); + mul = bsize >> GRUB_DISK_SECTOR_BITS; + nblocks = (core_size + bsize - 1) / bsize; ++ if (mul == 0 || nblocks == 0) ++ grub_util_error ("%s", _("can't retrieve blocklists")); + for (i = 0; i < nblocks; i++) + { + unsigned blk = i; +@@ -808,7 +810,7 @@ unable_to_embed: + - j * GRUB_DISK_SECTOR_SIZE); + if (len > GRUB_DISK_SECTOR_SIZE) + len = GRUB_DISK_SECTOR_SIZE; +- if (i == 0 && j == 0) ++ if (first_sector == (grub_disk_addr_t)-1) + save_first_sector ((fie2->fm_extents[i].fe_physical + >> GRUB_DISK_SECTOR_BITS) + + j + container_start, +@@ -825,6 +827,8 @@ unable_to_embed: + + } + } ++ if (first_sector == (grub_disk_addr_t)-1) ++ grub_util_error ("%s", _("can't retrieve blocklists")); + } + fclose (fp); + } +-- +1.8.1.4 + diff --git a/0251-grub-core-bus-usb-usbtrans.c-grub_usb_bulk_readwrite.patch b/0251-grub-core-bus-usb-usbtrans.c-grub_usb_bulk_readwrite.patch new file mode 100644 index 0000000..7c5f8aa --- /dev/null +++ b/0251-grub-core-bus-usb-usbtrans.c-grub_usb_bulk_readwrite.patch @@ -0,0 +1,42 @@ +From c9e516f1d40681546719f1bbf33f81db8e968361 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Thu, 4 Apr 2013 08:56:45 +0200 +Subject: [PATCH 251/364] * grub-core/bus/usb/usbtrans.c + (grub_usb_bulk_readwrite_packetize): Init err. + +--- + ChangeLog | 5 +++++ + grub-core/bus/usb/usbtrans.c | 2 +- + 2 files changed, 6 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index 8a3fd45..7bbcffa 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,10 @@ + 2013-04-04 Vladimir Serbinenko + ++ * grub-core/bus/usb/usbtrans.c (grub_usb_bulk_readwrite_packetize): ++ Init err. ++ ++2013-04-04 Vladimir Serbinenko ++ + * util/grub-setup.c (setup): Handle some corner cases. + + 2013-04-04 Vladimir Serbinenko +diff --git a/grub-core/bus/usb/usbtrans.c b/grub-core/bus/usb/usbtrans.c +index 533c3e7..557e71c 100644 +--- a/grub-core/bus/usb/usbtrans.c ++++ b/grub-core/bus/usb/usbtrans.c +@@ -343,7 +343,7 @@ grub_usb_bulk_readwrite_packetize (grub_usb_device_t dev, + grub_size_t size, char *data) + { + grub_size_t actual, transferred; +- grub_usb_err_t err; ++ grub_usb_err_t err = GRUB_USB_ERR_NONE; + grub_size_t current_size, position; + grub_size_t max_bulk_transfer_len = MAX_USB_TRANSFER_LEN; + grub_size_t max; +-- +1.8.1.4 + diff --git a/0252-Use-TSC-as-a-possible-time-source-on-i386-ieee1275.patch b/0252-Use-TSC-as-a-possible-time-source-on-i386-ieee1275.patch new file mode 100644 index 0000000..07eccd5 --- /dev/null +++ b/0252-Use-TSC-as-a-possible-time-source-on-i386-ieee1275.patch @@ -0,0 +1,114 @@ +From 0535e4875ec962879b74f69e472615245f7ff987 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Thu, 4 Apr 2013 09:55:44 +0200 +Subject: [PATCH 252/364] Use TSC as a possible time source on + i386-ieee1275. + +--- + ChangeLog | 4 ++++ + grub-core/Makefile.core.def | 8 ++------ + grub-core/kern/ieee1275/init.c | 15 ++++++++++----- + 3 files changed, 16 insertions(+), 11 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 7bbcffa..bd9e903 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,9 @@ + 2013-04-04 Vladimir Serbinenko + ++ Use TSC as a possible time source on i386-ieee1275. ++ ++2013-04-04 Vladimir Serbinenko ++ + * grub-core/bus/usb/usbtrans.c (grub_usb_bulk_readwrite_packetize): + Init err. + +diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def +index 911754d..4b4c024 100644 +--- a/grub-core/Makefile.core.def ++++ b/grub-core/Makefile.core.def +@@ -128,11 +128,11 @@ kernel = { + efi = kern/efi/mm.c; + efi = term/efi/console.c; + +- i386_efi = kern/i386/tsc.c; ++ x86 = kern/i386/tsc.c; ++ + i386_efi = kern/i386/efi/init.c; + i386_efi = bus/pci.c; + +- x86_64_efi = kern/i386/tsc.c; + x86_64_efi = kern/x86_64/dl.c; + x86_64_efi = kern/x86_64/efi/callwrap.S; + x86_64_efi = kern/i386/efi/init.c; +@@ -145,19 +145,15 @@ kernel = { + + i386_pc = kern/i386/pc/init.c; + i386_pc = kern/i386/pc/mmap.c; +- i386_pc = kern/i386/tsc.c; + i386_pc = term/i386/pc/console.c; + + i386_qemu = bus/pci.c; + i386_qemu = kern/vga_init.c; + i386_qemu = kern/i386/qemu/mmap.c; +- i386_qemu = kern/i386/tsc.c; + + i386_coreboot = kern/i386/coreboot/mmap.c; +- i386_coreboot = kern/i386/tsc.c; + + i386_multiboot = kern/i386/multiboot_mmap.c; +- i386_multiboot = kern/i386/tsc.c; + + mips = kern/mips/cache.S; + mips = kern/mips/dl.c; +diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c +index 0894cb6..391a734 100644 +--- a/grub-core/kern/ieee1275/init.c ++++ b/grub-core/kern/ieee1275/init.c +@@ -34,6 +34,9 @@ + #include + #include + #include ++#ifdef __i386__ ++#include ++#endif + #ifdef __sparc__ + #include + #endif +@@ -269,8 +272,6 @@ grub_parse_cmdline (void) + } + } + +-static grub_uint64_t ieee1275_get_time_ms (void); +- + grub_addr_t grub_modbase; + + void +@@ -288,7 +289,11 @@ grub_machine_init (void) + + grub_parse_cmdline (); + +- grub_install_get_time_ms (ieee1275_get_time_ms); ++#ifdef __i386__ ++ grub_tsc_init (); ++#else ++ grub_install_get_time_ms (grub_rtc_get_time_ms); ++#endif + } + + void +@@ -298,8 +303,8 @@ grub_machine_fini (void) + grub_console_fini (); + } + +-static grub_uint64_t +-ieee1275_get_time_ms (void) ++grub_uint64_t ++grub_rtc_get_time_ms (void) + { + grub_uint32_t msecs = 0; + +-- +1.8.1.4 + diff --git a/0253-grub-core-disk-efi-efidisk.c-Handle-partitions-on-no.patch b/0253-grub-core-disk-efi-efidisk.c-Handle-partitions-on-no.patch new file mode 100644 index 0000000..7fb23ce --- /dev/null +++ b/0253-grub-core-disk-efi-efidisk.c-Handle-partitions-on-no.patch @@ -0,0 +1,74 @@ +From 9c5d1aa956de89b429997b19e20cdd887f612414 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Thu, 4 Apr 2013 10:35:50 +0200 +Subject: [PATCH 253/364] * grub-core/disk/efi/efidisk.c: Handle + partitions on non-512B disks. + +--- + ChangeLog | 5 +++++ + grub-core/disk/efi/efidisk.c | 20 ++++++++++++++------ + 2 files changed, 19 insertions(+), 6 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index bd9e903..400a071 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,4 +1,9 @@ + 2013-04-04 Vladimir Serbinenko ++2013-04-04 Peter Jones ++ ++ * grub-core/disk/efi/efidisk.c: Handle partitions on non-512B disks. ++ ++2013-04-04 Vladimir Serbinenko + + Use TSC as a possible time source on i386-ieee1275. + +diff --git a/grub-core/disk/efi/efidisk.c b/grub-core/disk/efi/efidisk.c +index c883b2c..0a364f1 100644 +--- a/grub-core/disk/efi/efidisk.c ++++ b/grub-core/disk/efi/efidisk.c +@@ -658,10 +658,12 @@ grub_efidisk_get_device_handle (grub_disk_t disk) + == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE) + && (GRUB_EFI_DEVICE_PATH_SUBTYPE (c->last_device_path) + == GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE) +- && (grub_partition_get_start (disk->partition) +- == hd.partition_start) ++ && (grub_partition_get_start (disk->partition) ++ == (hd.partition_start << (disk->log_sector_size ++ - GRUB_DISK_SECTOR_BITS))) + && (grub_partition_get_len (disk->partition) +- == hd.partition_size)) ++ == (hd.partition_size << (disk->log_sector_size ++ - GRUB_DISK_SECTOR_BITS)))) + { + handle = c->handle; + break; +@@ -738,8 +740,12 @@ grub_efidisk_get_device_name_iter (grub_disk_t disk __attribute__ ((unused)), + { + struct grub_efidisk_get_device_name_ctx *ctx = data; + +- if (grub_partition_get_start (part) == ctx->hd.partition_start +- && grub_partition_get_len (part) == ctx->hd.partition_size) ++ if (grub_partition_get_start (part) ++ == (ctx->hd.partition_start << (disk->log_sector_size ++ - GRUB_DISK_SECTOR_BITS)) ++ && grub_partition_get_len (part) ++ == (ctx->hd.partition_size << (disk->log_sector_size ++ - GRUB_DISK_SECTOR_BITS))) + { + ctx->partition_name = grub_partition_get_name (part); + return 1; +@@ -798,7 +804,9 @@ grub_efidisk_get_device_name (grub_efi_handle_t *handle) + ctx.partition_name = NULL; + grub_memcpy (&ctx.hd, ldp, sizeof (ctx.hd)); + if (ctx.hd.partition_start == 0 +- && ctx.hd.partition_size == grub_disk_get_size (parent)) ++ && (ctx.hd.partition_size << (parent->log_sector_size ++ - GRUB_DISK_SECTOR_BITS)) ++ == grub_disk_get_size (parent)) + { + dev_name = grub_strdup (parent->name); + } +-- +1.8.1.4 + diff --git a/0254-Unify-file-copying-setup-across-different-install-sc.patch b/0254-Unify-file-copying-setup-across-different-install-sc.patch new file mode 100644 index 0000000..cd87dcd --- /dev/null +++ b/0254-Unify-file-copying-setup-across-different-install-sc.patch @@ -0,0 +1,588 @@ +From 2b7cc814ca7d780576f2fd7fa41058a5a15a589a Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Thu, 4 Apr 2013 19:59:59 +0200 +Subject: [PATCH 254/364] Unify file copying setup across different + install scripts. Add options for performing partial install. + +--- + ChangeLog | 5 ++ + Makefile.util.def | 7 ++ + gentpl.py | 4 +- + util/grub-install.in | 47 +++----------- + util/grub-install_header | 161 ++++++++++++++++++++++++++++++++++++++++++++++ + util/grub-mknetdir.in | 47 +++----------- + util/grub-mkrescue.in | 42 +++--------- + util/grub-mkstandalone.in | 44 +++---------- + 8 files changed, 212 insertions(+), 145 deletions(-) + create mode 100644 util/grub-install_header + +diff --git a/ChangeLog b/ChangeLog +index 400a071..94f2631 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,4 +1,9 @@ + 2013-04-04 Vladimir Serbinenko ++ ++ Unify file copying setup across different install scripts. Add ++ options for performing partial install. ++ ++2013-04-04 Vladimir Serbinenko + 2013-04-04 Peter Jones + + * grub-core/disk/efi/efidisk.c: Handle partitions on non-512B disks. +diff --git a/Makefile.util.def b/Makefile.util.def +index 62bcf2d..513dc38 100644 +--- a/Makefile.util.def ++++ b/Makefile.util.def +@@ -451,9 +451,13 @@ script = { + script = { + mansection = 1; + name = grub-mkrescue; ++ x86 = util/grub-install_header; + x86 = util/grub-mkrescue.in; ++ mips_qemu_mips = util/grub-install_header; + mips_qemu_mips = util/grub-mkrescue.in; ++ mips_loongson = util/grub-install_header; + mips_loongson = util/grub-mkrescue.in; ++ ia64_efi = util/grub-install_header; + ia64_efi = util/grub-mkrescue.in; + powerpc_ieee1275 = util/powerpc/ieee1275/grub-mkrescue.in; + enable = i386_pc; +@@ -471,6 +475,7 @@ script = { + script = { + mansection = 1; + name = grub-mkstandalone; ++ common = util/grub-install_header; + common = util/grub-mkstandalone.in; + }; + +@@ -479,6 +484,7 @@ script = { + installdir = sbin; + name = grub-install; + ++ common = util/grub-install_header; + common = util/grub-install.in; + enable = noemu; + }; +@@ -488,6 +494,7 @@ script = { + installdir = bin; + name = grub-mknetdir; + ++ common = util/grub-install_header; + common = util/grub-mknetdir.in; + }; + +diff --git a/gentpl.py b/gentpl.py +index 6d7f613..b159795 100644 +--- a/gentpl.py ++++ b/gentpl.py +@@ -535,8 +535,8 @@ def script(platform): + r += "[+ IF mansection +]" + manpage("grub-mkconfig_lib") + "[+ ENDIF +]" + r += "[+ ENDIF +]" + +- r += rule("[+ name +]", platform_sources(platform) + " $(top_builddir)/config.status", """ +-$(top_builddir)/config.status --file=$@:$< ++ r += rule("[+ name +]", "$(top_builddir)/config.status " + platform_sources(platform), """ ++(skip=1; for x in $^; do if [ $$skip = 1 ]; then skip=0; else cat "$$x"; fi; done) | $(top_builddir)/config.status --file=$@:- + chmod a+x [+ name +] + """) + +diff --git a/util/grub-install.in b/util/grub-install.in +index 9e63cf5..016b161 100644 +--- a/util/grub-install.in ++++ b/util/grub-install.in +@@ -88,6 +88,8 @@ usage () { + print_option_help "-h, --help" "$(gettext "print this message and exit")" + print_option_help "-v, --version" "$(gettext "print the version information and exit")" + print_option_help "--modules=$(gettext "MODULES")" "$(gettext "pre-load specified modules MODULES")" ++ grub_print_install_files_help ++ + dirmsg="$(gettext_printf "install GRUB images under the directory DIR/%s instead of the %s directory" "@grubdirname@" "$grubdir")" + print_option_help "--boot-directory=$(gettext "DIR")" "$dirmsg" + # TRANSLATORS: "TARGET" as in "target platform". +@@ -120,17 +122,6 @@ echo + gettext "Report bugs to ."; echo + } + +-argument () { +- opt="$1" +- shift +- +- if test $# -eq 0; then +- gettext_printf "%s: option requires an argument -- \`%s'\n" "$0" "$opt" 1>&2 +- exit 1 +- fi +- echo "$1" +-} +- + allow_floppy="" + force_file_id= + efidir= +@@ -138,6 +129,12 @@ efidir= + # Check the arguments. + while test $# -gt 0 + do ++ grub_process_install_options "$@" ++ case "$grub_process_install_options_consumed" in ++ 1) shift; continue;; ++ 2) shift; shift; continue;; ++ esac ++ + option=$1 + shift + +@@ -519,14 +516,8 @@ else + fi + + # Copy the GRUB images to the GRUB directory. +-for file in "${grubdir}"/*.mod "${grubdir}"/*.lst "${grubdir}"/*.img "${grubdir}"/efiemu??.o "${grubdir}"/${grub_modinfo_target_cpu}-$grub_modinfo_platform/*.mod "${grubdir}"/${grub_modinfo_target_cpu}-$grub_modinfo_platform/*.lst "${grubdir}"/${grub_modinfo_target_cpu}-$grub_modinfo_platform/*.img "${grubdir}"/${grub_modinfo_target_cpu}-$grub_modinfo_platform/efiemu??.o; do +- if test -f "$file" && [ "`basename $file`" != menu.lst ]; then +- rm -f "$file" || exit 1 +- fi +-done +-for file in "${source_dir}"/*.mod "${source_dir}"/*.lst; do +- cp -f "$file" "${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform" || exit 1 +-done ++grub_install_files "${source_dir}" "${grubdir}" "${grub_modinfo_target_cpu}-$grub_modinfo_platform" all ++ + if [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "i386-pc" ] || [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "sparc64-ieee1275" ] ; then + for file in "${source_dir}"/*.img "${source_dir}"/efiemu??.o; do + if test -f "$file"; then +@@ -535,24 +526,6 @@ if [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "i386-pc" ] || [ "$ + done + fi + +-# Copy gettext files +-mkdir -p "${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 +- +-if test -f "${pkgdatadir}"/themes/starfield/theme.txt; then +- mkdir -p "${grubdir}"/themes/starfield +- cp "${pkgdatadir}"/themes/starfield/* "${grubdir}"/themes/starfield +-fi +- +-if test -f "${pkgdatadir}"/unicode.pf2; then +- mkdir -p "${grubdir}"/fonts +- cp "${pkgdatadir}"/unicode.pf2 "${grubdir}"/fonts +-fi +- + if ! is_path_readable_by_grub "${grubdir}"; then + gettext_printf "Path \`%s' is not readable by GRUB on boot. Installation is impossible. Aborting.\n" "${grubdir}" 1>&2 + exit 1 +diff --git a/util/grub-install_header b/util/grub-install_header +new file mode 100644 +index 0000000..7c2c0a5 +--- /dev/null ++++ b/util/grub-install_header +@@ -0,0 +1,161 @@ ++#! /bin/sh ++set -e ++ ++# Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012 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 . ++ ++pkglib_DATA="moddep.lst command.lst fs.lst partmap.lst parttool.lst \ ++handler.lst video.lst crypto.lst terminal.lst" ++ ++grub_install_files () { ++ grub_install_files_source_directory="$1" ++ grub_install_files_target_directory="$2" ++ grub_install_files_platform="$3" ++ ++ mkdir -p "${grub_install_files_target_directory}"/"${grub_install_files_platform}" ++ ++ for file in "${grub_install_files_target_directory}"/*.mod \ ++"${grub_install_files_target_directory}"/*.lst \ ++"${grub_install_files_target_directory}"/*.img \ ++"${grub_install_files_target_directory}"/efiemu??.o \ ++"${grub_install_files_target_directory}"/"${grub_install_files_platform}"/*.mod \ ++"${grub_install_files_target_directory}"/"${grub_install_files_platform}"/*.lst \ ++"${grub_install_files_target_directory}"/"${grub_install_files_platform}"/*.img \ ++"${grub_install_files_target_directory}"/"${grub_install_files_platform}"/efiemu??.o; ++ do ++ if test -f "$file" && [ "`basename $file`" != menu.lst ]; then ++ rm -f "$file" || exit 1 ++ fi ++ done ++ ++ if [ x"$install_modules" = xall ]; then ++ for file in "${grub_install_files_source_directory}/"*.mod; do ++ cp -f "$file" "${grub_install_files_target_directory}"/"${grub_install_files_platform}" ++ done ++ else ++ modules1= ++ modules2="$install_modules" ++ while [ x"$modules2" != x ]; do ++ modules3= ++ for x in $modules2; do ++ modules3="$modules3 $(grep "^$x:" "${grub_install_files_source_directory}/moddep.lst" | sed 's,^[^:]*:,,')" ++ done ++ modules1="$modules1 $modules2" ++ modules2="$modules3" ++ done ++ for file in $(echo "$modules1" | sed 's, ,\n,g' |sort -u); do ++ cp -f "${grub_install_files_source_directory}/$file.mod" "${grub_install_files_target_directory}"/"${grub_install_files_platform}" ++ done ++ fi ++ ++ for file in ${pkglib_DATA} efiemu32.o efiemu64.o; do ++ if test -f "${grub_install_files_source_directory}/${file}"; then ++ cp -f "${grub_install_files_source_directory}/${file}" "${grub_install_files_target_directory}"/"${grub_install_files_platform}" ++ fi ++ done ++ ++ # Copy gettext files ++ mkdir -p "${grub_install_files_target_directory}"/locale ++ ++ for file in "${grub_install_files_target_directory}"/locale/*.mo; do ++ if test -f "$file"; then ++ rm -f "$file" || exit 1 ++ fi ++ done ++ ++ if [ x"$install_locales" = xall ]; then ++ for file in "${grub_install_files_source_directory}"/po/*.mo; do ++ if test -f "$file"; then ++ cp -f "$file" "${grub_install_files_target_directory}"/locale/ ++ fi ++ done ++ for dir in "${localedir}"/*; do ++ if test -f "$dir/LC_MESSAGES/grub.mo" && ! test -f "${grub_install_files_target_directory}"/locale/"${dir##*/}.mo"; then ++ cp -f "$dir/LC_MESSAGES/grub.mo" "${grub_install_files_target_directory}"/locale/"${dir##*/}.mo" ++ fi ++ done ++ else ++ for locale in $install_locales; do ++ if test -f "${grub_install_files_source_directory}"/po/$locale.mo; then ++ cp -f " "${grub_install_files_source_directory}"/po/$locale.mo" "${grub_install_files_target_directory}"/locale/$locale.mo ++ elif test -f "${localedir}/$locale/LC_MESSAGES/grub.mo"; then ++ cp -f "${localedir}/$locale/LC_MESSAGES/grub.mo" "${grub_install_files_target_directory}"/locale/$locale.mo ++ fi ++ done ++ fi ++ for theme in ${install_themes} ; do ++ if test -f "${pkgdatadir}"/themes/"${theme}"/theme.txt; then ++ mkdir -p "${grub_install_files_target_directory}"/themes/"${theme}" ++ cp "${pkgdatadir}"/themes/"${theme}"/* "${grub_install_files_target_directory}"/themes/"${theme}" ++ fi ++ done ++ ++ for font in ${install_fonts} ; do ++ if test -f "${pkgdatadir}"/"$font".pf2; then ++ mkdir -p "${grub_install_files_target_directory}"/fonts ++ cp "${pkgdatadir}"/"$font".pf2 "${grub_install_files_target_directory}"/fonts ++ fi ++ done ++} ++ ++grub_print_install_files_help () { ++ print_option_help "--install-modules=$(gettext "MODULES")" "$(gettext "install only MODULES and their dependencies [default=all]")" ++ print_option_help "--themes=THEMES" "$(gettext_printf "install THEMES [default=%s]" "starfield")" ++ print_option_help "--fonts=FONTS" "$(gettext_printf "install FONTS [default=%s]" "unicode")" ++ print_option_help "--locales=LOCALES" "$(gettext_printf "install only LOCALES [default=all]")" ++} ++ ++install_modules=all ++install_themes=starfield ++install_fonts=unicode ++install_locales=all ++ ++argument () { ++ opt=$1 ++ shift ++ ++ if test $# -eq 0; then ++ gettext_printf "%s: option requires an argument -- \`%s'\n" "$0" "$opt" 1>&2 ++ exit 1 ++ fi ++ echo $1 ++} ++ ++grub_process_install_options () { ++ option=$1 ++ shift ++ ++ grub_process_install_options_consumed=0 ++ ++ case "$option" in ++ --install-modules) ++ install_modules=`argument $option "$@"`; grub_process_install_options_consumed=2; return ;; ++ --install-modules=*) ++ install_modules=`echo "$option" | sed 's/--install-modules=//'`; grub_process_install_options_consumed=1; return ;; ++ --themes) ++ install_themes=`argument $option "$@"`; grub_process_install_options_consumed=2; return ;; ++ --themes=*) ++ install_themes=`echo "$option" | sed 's/--themes=//'`; grub_process_install_options_consumed=1; return ;; ++ --fonts) ++ install_fonts=`argument $option "$@"`; grub_process_install_options_consumed=2; return ;; ++ --fonts=*) ++ install_fonts=`echo "$option" | sed 's/--fonts=//'`; grub_process_install_options_consumed=1; return ;; ++ --locales) ++ install_locales=`argument $option "$@"`; grub_process_install_options_consumed=2; return ;; ++ --locales=*) ++ install_locales=`echo "$option" | sed 's/--locales=//'`; grub_process_install_options_consumed=1; return ;; ++ esac ++} ++ +diff --git a/util/grub-mknetdir.in b/util/grub-mknetdir.in +index e235af3..6df761a 100644 +--- a/util/grub-mknetdir.in ++++ b/util/grub-mknetdir.in +@@ -1,5 +1,3 @@ +-#! /bin/sh +- + # Install GRUB on your drive. + # Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc. + # +@@ -26,7 +24,6 @@ PACKAGE_NAME=@PACKAGE_NAME@ + PACKAGE_TARNAME=@PACKAGE_TARNAME@ + PACKAGE_VERSION=@PACKAGE_VERSION@ + host_os=@host_os@ +-pkglib_DATA="moddep.lst command.lst fs.lst partmap.lst parttool.lst handler.lst video.lst crypto.lst terminal.lst" + datadir="@datadir@" + if [ "x$pkgdatadir" = x ]; then + pkgdatadir="${datadir}/@PACKAGE@" +@@ -65,6 +62,7 @@ usage () { + print_option_help "-h, --help" "$(gettext "print this message and exit")" + print_option_help "-v, --version" "$(gettext "print the version information and exit")" + print_option_help "--modules=$(gettext "MODULES")" "$(gettext "pre-load specified modules MODULES")" ++ grub_print_install_files_help + print_option_help "--net-directory=$(gettext "DIR")" "$(gettext "root directory of TFTP server")" + print_option_help "--subdir=$(gettext "DIR")" "$(gettext "relative subdirectory on network server")" + print_option_help "--grub-mkimage=$(gettext "FILE")" "$(gettext "use FILE as grub-mkimage")" +@@ -77,20 +75,15 @@ usage () { + gettext "Report bugs to ."; echo + } + +-argument () { +- opt=$1 +- shift +- +- if test $# -eq 0; then +- gettext_printf "%s: option requires an argument -- \`%s'\n" "$0" "$opt" 1>&2 +- exit 1 +- fi +- echo $1 +-} +- + # Check the arguments. + while test $# -gt 0 + do ++ grub_process_install_options "$@" ++ case "$grub_process_install_options_consumed" in ++ 1) shift; continue;; ++ 2) shift; shift; continue;; ++ esac ++ + option=$1 + shift + +@@ -166,32 +159,10 @@ process_input_dir () + platform="$2" + grubdir="${rootdir}/${subdir}/${platform}" + config_opt= +- mkdir -p "$grubdir" || exit 1 +- +- for file in "${grubdir}"/*.mod "${grubdir}"/*.lst "${grubdir}"/*.img "${grubdir}"/efiemu??.o; do +- if test -f "$file" && [ "`basename $file`" != menu.lst ]; then +- rm -f "$file" || exit 1 +- fi +- done +- for file in "${input_dir}"/*.mod; do +- if test -f "$file"; then +- cp -f "$file" "$grubdir/" +- fi +- done +- for file in ${pkglib_DATA}; do +- if test -f "${input_dir}/${file}"; then +- cp -f "${input_dir}/${file}" "$grubdir/" +- fi +- done + +- mkdir -p "$grubdir/locale" +- for file in ${input_dir}/po/*.mo; do +- if test -f "$file"; then +- cp -f "$file" "$grubdir/locale/" +- fi +- done ++ grub_install_files "${input_dir}" "${rootdir}/${subdir}" "${platform}" + +- rm -f ${grubdir}/load.cfg ++ rm -f "${grubdir}"/load.cfg + + if [ "x${debug_image}" != x ]; then + echo "set debug='${debug_image}'" >> ${grubdir}/load.cfg +diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in +index d279a9d..c57a0d9 100644 +--- a/util/grub-mkrescue.in ++++ b/util/grub-mkrescue.in +@@ -1,5 +1,3 @@ +-#! /bin/sh +-set -e + + # Make GRUB rescue image + # Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc. +@@ -70,6 +68,8 @@ usage () { + print_option_help "-v, --version" "$(gettext "print the version information and exit")" + print_option_help "-o, --output=$filetrans" "$(gettext "save output in FILE [required]")" + print_option_help "--modules=$(gettext "MODULES")" "$(gettext "pre-load specified modules MODULES")" ++ grub_print_install_files_help ++ print_option_help "--install-modules=$(gettext "MODULES")" "$(gettext "install only MODULES and their dependencies on bootable media")" + print_option_help "--rom-directory=$(gettext "DIR")" "$(gettext "save ROM images in DIR [optional]")" + # TRANSLATORS: xorriso is a program for creating ISOs and burning CDs + print_option_help "--xorriso=$filetrans" "$(gettext "use FILE as xorriso [optional]")" +@@ -83,20 +83,15 @@ usage () { + gettext "Mail xorriso support requests to ."; echo + } + +-argument () { +- opt=$1 +- shift +- +- if test $# -eq 0; then +- gettext_printf "%s: option requires an argument -- \`%s'\n" "$0" "$opt" 1>&2 +- exit 1 +- fi +- echo $1 +-} +- + # Check the arguments. + while test $# -gt 0 + do ++ grub_process_install_options "$@" ++ case "$grub_process_install_options_consumed" in ++ 1) shift; continue;; ++ 2) shift; shift; continue;; ++ esac ++ + option=$1 + shift + +@@ -171,26 +166,7 @@ mkdir -p ${iso9660_dir}/boot/grub + + process_input_dir () + { +- input_dir="$1" +- platform="$2" +- mkdir -p "${iso9660_dir}/boot/grub/${platform}" +- for file in "${input_dir}/"*.mod "${input_dir}/"efiemu32.o "${input_dir}/"efiemu64.o; do +- if test -f "$file"; then +- 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/${platform}/" +- fi +- done +- +- mkdir -p "${iso9660_dir}/boot/grub/locale" +- for dir in "${localedir}"/*; do +- if test -f "$dir/LC_MESSAGES/grub.mo"; then +- cp -f "$dir/LC_MESSAGES/grub.mo" "${iso9660_dir}/boot/grub/locale/${dir##*/}.mo" +- fi +- done ++ grub_install_files "$1" "${iso9660_dir}/boot/grub" "$2" + } + + make_image () +diff --git a/util/grub-mkstandalone.in b/util/grub-mkstandalone.in +index 78b83e0..a5434c4 100644 +--- a/util/grub-mkstandalone.in ++++ b/util/grub-mkstandalone.in +@@ -1,5 +1,4 @@ +-#! /bin/sh +-set -e ++#!/bin/sh + + # Make GRUB rescue image + # Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012 Free Software Foundation, Inc. +@@ -27,7 +26,6 @@ libdir="@libdir@" + PACKAGE_NAME=@PACKAGE_NAME@ + PACKAGE_TARNAME=@PACKAGE_TARNAME@ + PACKAGE_VERSION=@PACKAGE_VERSION@ +-pkglib_DATA="moddep.lst command.lst fs.lst partmap.lst parttool.lst handler.lst video.lst crypto.lst terminal.lst" + datadir="@datadir@" + if [ "x$pkgdatadir" = x ]; then + pkgdatadir="${datadir}/@PACKAGE@" +@@ -64,25 +62,21 @@ usage () { + echo + print_option_help "-C, --compression=(xz|none|auto)" "$(gettext "choose the compression to use")" + print_option_help "--modules=$(gettext "MODULES")" "$(gettext "pre-load specified modules MODULES")" ++ grub_print_install_files_help + print_option_help "--grub-mkimage=$(gettext "FILE")" "$(gettext "use FILE as grub-mkimage")" + echo + gettext "Report bugs to ."; echo + } + +-argument () { +- opt=$1 +- shift +- +- if test $# -eq 0; then +- gettext_printf "%s: option requires an argument -- \`%s'\n" "$0" "$opt" 1>&2 +- exit 1 +- fi +- echo $1 +-} +- + # Check the arguments. + while test $# -gt 0 + do ++ grub_process_install_options "$@" ++ case "$grub_process_install_options_consumed" in ++ 1) shift; continue;; ++ 2) shift; shift; continue;; ++ esac ++ + option=$1 + shift + +@@ -167,27 +161,7 @@ else + fi + + memdisk_dir="`mktemp -d "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"`" || exit 1 +-mkdir -p "${memdisk_dir}"/boot/grub/"${grub_modinfo_target_cpu}-${grub_modinfo_platform}" +- +-for file in "${source_directory}/"*.mod "${source_directory}/"efiemu32.o "${source_directory}/"efiemu64.o; do +- if test -f "$file"; then +- cp -f "$file" "${memdisk_dir}"/boot/grub/"${grub_modinfo_target_cpu}-${grub_modinfo_platform}" +- fi +-done +- +-for file in ${pkglib_DATA}; do +- if test -f "${source_directory}/${file}"; then +- cp -f "${source_directory}/${file}" "${memdisk_dir}"/boot/grub/"${grub_modinfo_target_cpu}-${grub_modinfo_platform}" +- fi +-done +- +-mkdir -p "${memdisk_dir}"/boot/grub/locale +-for file in "${source_directory}"/po/*.mo; do +- if test -f "$file"; then +- cp -f "$file" "${memdisk_dir}"/boot/grub/locale/ +- fi +-done +- ++grub_install_files "${source_directory}" "${memdisk_dir}"/boot/grub "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" + for file in $source; do + cp -f "$file" "${memdisk_dir}"/"$file"; + done +-- +1.8.1.4 + diff --git a/0255-util-grub-mkimage.c-Introduce-new-define-EFI32_HEADE.patch b/0255-util-grub-mkimage.c-Introduce-new-define-EFI32_HEADE.patch new file mode 100644 index 0000000..a25d063 --- /dev/null +++ b/0255-util-grub-mkimage.c-Introduce-new-define-EFI32_HEADE.patch @@ -0,0 +1,72 @@ +From 74f9afff3de573ac527fee26c516e057918ab7ef Mon Sep 17 00:00:00 2001 +From: Francesco Lavra +Date: Thu, 4 Apr 2013 20:07:44 +0200 +Subject: [PATCH 255/364] * util/grub-mkimage.c: Introduce new define + EFI32_HEADER_SIZE. + +--- + ChangeLog | 4 ++++ + util/grub-mkimage.c | 21 +++++++++------------ + 2 files changed, 13 insertions(+), 12 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 94f2631..f2c2d2f 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,7 @@ ++2013-04-04 Francesco Lavra ++ ++ * util/grub-mkimage.c: Introduce new define EFI32_HEADER_SIZE. ++ + 2013-04-04 Vladimir Serbinenko + + Unify file copying setup across different install scripts. Add +diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c +index 845abed..ecea5d4 100644 +--- a/util/grub-mkimage.c ++++ b/util/grub-mkimage.c +@@ -91,6 +91,13 @@ struct image_target_desc + grub_uint16_t pe_target; + }; + ++#define EFI32_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) ++ + #define EFI64_HEADER_SIZE ALIGN_UP (GRUB_PE32_MSDOS_STUB_SIZE \ + + GRUB_PE32_SIGNATURE_SIZE \ + + sizeof (struct grub_pe32_coff_header) \ +@@ -182,12 +189,7 @@ struct image_target_desc image_targets[] = + .decompressor_uncompressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_addr = 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), ++ .vaddr_offset = EFI32_HEADER_SIZE, + .pe_target = GRUB_PE32_MACHINE_I386, + .elf_target = EM_386, + }, +@@ -1101,12 +1103,7 @@ generate_image (const char *dir, const char *prefix, + int reloc_addr; + + 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); ++ header_size = EFI32_HEADER_SIZE; + else + header_size = EFI64_HEADER_SIZE; + +-- +1.8.1.4 + diff --git a/0256-docs-grub.texi-Document-menuentry-id-option.patch b/0256-docs-grub.texi-Document-menuentry-id-option.patch new file mode 100644 index 0000000..f1c071f --- /dev/null +++ b/0256-docs-grub.texi-Document-menuentry-id-option.patch @@ -0,0 +1,77 @@ +From f15f2bd2977f88231e5c4ae718421360129c889d Mon Sep 17 00:00:00 2001 +From: Andrey Borzenkov +Date: Fri, 5 Apr 2013 10:08:20 +0200 +Subject: [PATCH 256/364] * docs/grub.texi: Document menuentry --id + option. + +--- + ChangeLog | 4 ++++ + docs/grub.texi | 16 ++++++++++------ + 2 files changed, 14 insertions(+), 6 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index f2c2d2f..6113a39 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,7 @@ ++2013-04-04 Andrey Borzenkov ++ ++ * docs/grub.texi: Document menuentry --id option. ++ + 2013-04-04 Francesco Lavra + + * util/grub-mkimage.c: Introduce new define EFI32_HEADER_SIZE. +diff --git a/docs/grub.texi b/docs/grub.texi +index 0b66827..742d406 100644 +--- a/docs/grub.texi ++++ b/docs/grub.texi +@@ -1522,7 +1522,7 @@ definitions do not affect the exit status in @code{$?}. When executed, the + exit status of a function is the exit status of the last command executed in + the body. + +-@item menuentry @var{title} [@option{--class=class} @dots{}] [@option{--users=users}] [@option{--unrestricted}] [@option{--hotkey=key}] @{ @var{command}; @dots{} @} ++@item menuentry @var{title} [@option{--class=class} @dots{}] [@option{--users=users}] [@option{--unrestricted}] [@option{--hotkey=key}] [@option{--id=id}] @{ @var{command}; @dots{} @} + @xref{menuentry}. + @end table + +@@ -3215,13 +3215,13 @@ These commands can only be used in the menu: + + @deffn Command menuentry @var{title} @ + [@option{--class=class} @dots{}] [@option{--users=users}] @ +- [@option{--unrestricted}] [@option{--hotkey=key}] @ ++ [@option{--unrestricted}] [@option{--hotkey=key}] [@option{--id=id}] @ + @{ @var{command}; @dots{} @} + This defines a GRUB menu entry named @var{title}. When this entry is + selected from the menu, GRUB will set the @var{chosen} environment variable +-to @var{title}, execute the list of commands given within braces, and if the +-last command in the list returned successfully and a kernel was loaded it +-will execute the @command{boot} command. ++to value of @option{--id} if @option{--id} is given, execute the list of ++commands given within braces, and if the last command in the list returned ++successfully and a kernel was loaded it will execute the @command{boot} command. + + The @option{--class} option may be used any number of times to group menu + entries into classes. Menu themes may display different classes using +@@ -3236,6 +3236,10 @@ entries. @xref{Security}. + The @option{--hotkey} option associates a hotkey with a menu entry. + @var{key} may be a single letter, or one of the aliases @samp{backspace}, + @samp{tab}, or @samp{delete}. ++ ++The @option{--id} may be used to associate unique identifier with a menu entry. ++@var{id} is string of ASCII aphanumeric characters, underscore and hyphen ++and should not start with a digit. + @end deffn + + +@@ -3244,7 +3248,7 @@ The @option{--hotkey} option associates a hotkey with a menu entry. + + @deffn Command submenu @var{title} @ + [@option{--class=class} @dots{}] [@option{--users=users}] @ +- [@option{--unrestricted}] [@option{--hotkey=key}] @ ++ [@option{--unrestricted}] [@option{--hotkey=key}] [@option{--id=id}] @ + @{ @var{menu entries} @dots{} @} + This defines a submenu. An entry called @var{title} will be added to the + menu; when that entry is selected, a new menu will be displayed showing all +-- +1.8.1.4 + diff --git a/0257-docs-grub.texi-Document-more-user-commands.patch b/0257-docs-grub.texi-Document-more-user-commands.patch new file mode 100644 index 0000000..bc77c35 --- /dev/null +++ b/0257-docs-grub.texi-Document-more-user-commands.patch @@ -0,0 +1,546 @@ +From 96fd4bad7168a598343b0a7ac9a1901a8075a2c3 Mon Sep 17 00:00:00 2001 +From: Andrey Borzenkov +Date: Fri, 5 Apr 2013 10:18:42 +0200 +Subject: [PATCH 257/364] * docs/grub.texi: Document more user commands. + +--- + ChangeLog | 4 + + docs/grub.texi | 352 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- + 2 files changed, 347 insertions(+), 9 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 6113a39..d63c0e5 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,7 @@ ++2013-04-04 Andrey Borzenkov ++ ++ * docs/grub.texi: Document more user commands. ++ + 2013-04-04 Andrey Borzenkov + + * docs/grub.texi: Document menuentry --id option. +diff --git a/docs/grub.texi b/docs/grub.texi +index 742d406..bd366a6 100644 +--- a/docs/grub.texi ++++ b/docs/grub.texi +@@ -1554,6 +1554,10 @@ Causes a function to exit with the return value specified by @code{n}. If + in the function body. If used outside a function the return status is + false. + ++@item setparams [@code{arg}] @dots{} ++Replace positional parameters starting with @code{$1} with arguments to ++@command{setparams}. ++ + @item shift [@code{n}] + The positional parameters from @code{n}+1 @dots{} are renamed to + @code{$1}@dots{}. Parameters represented by the numbers @code{$#} down to +@@ -1751,8 +1755,8 @@ Colors can be specified in several ways: + The fonts GRUB uses ``PFF2 font format'' bitmap fonts. Fonts are specified + with full font names. Currently there is no + provision for a preference list of fonts, or deriving one font from another. +-Fonts are loaded with the ``loadfont'' command in GRUB. To see the list of +-loaded fonts, execute the ``lsfonts'' command. If there are too many fonts to ++Fonts are loaded with the ``loadfont'' command in GRUB (@ref{loadfont}). To see the list of ++loaded fonts, execute the ``lsfonts'' command (@ref{lsfonts}). If there are too many fonts to + fit on screen, do ``set pager=1'' before executing ``lsfonts''. + + +@@ -3365,16 +3369,25 @@ you forget a command, you can run the command @command{help} + (@pxref{help}). + + @menu ++* [:: Check file types and compare values + * acpi:: Load ACPI tables ++* authenticate:: Check whether user is in user list ++* background_color:: Set background color for active terminal ++* background_image:: Load background image for active terminal + * badram:: Filter out bad regions of RAM + * blocklist:: Print a block list + * boot:: Start up your operating system + * cat:: Show the contents of a file + * chainloader:: Chain-load another boot loader ++* clear:: Clear the screen ++* cmosclean:: Clear bit in CMOS ++* cmosdump:: Dump CMOS contents ++* cmostest:: Test bit in CMOS + * cmp:: Compare two files + * configfile:: Load a configuration file + * cpuid:: Check for CPU features +-* crc:: Calculate CRC32 checksums ++* crc:: Compute or check CRC32 checksums ++* cryptomount:: Mount a crypto device + * date:: Display or set current date and time + * drivemap:: Map a drive to another + * echo:: Display a line of text +@@ -3383,6 +3396,7 @@ you forget a command, you can run the command @command{help} + * gettext:: Translate a string + * gptsync:: Fill an MBR based on GPT entries + * halt:: Shut down your computer ++* hashsum:: Compute or check hash checksum + * help:: Show help messages + * initrd:: Load a Linux initrd + * initrd16:: Load a Linux initrd (16-bit mode) +@@ -3391,29 +3405,50 @@ you forget a command, you can run the command @command{help} + * linux:: Load a Linux kernel + * linux16:: Load a Linux kernel (16-bit mode) + * list_env:: List variables in environment block ++* loadfont:: Load font files + * load_env:: Load variables from environment block + * loopback:: Make a device from a filesystem image + * ls:: List devices or files ++* lsfonts:: List loaded fonts ++* lsmod:: Show loaded modules ++* md5sum:: Compute or check MD5 hash + * normal:: Enter normal mode + * normal_exit:: Exit from normal mode + * parttool:: Modify partition table entries + * password:: Set a clear-text password + * password_pbkdf2:: Set a hashed password + * play:: Play a tune ++* probe:: Retrieve device info + * pxe_unload:: Unload the PXE environment + * read:: Read user input + * reboot:: Reboot your computer ++* regexp:: Test if regular expression matches string ++* rmmod:: Remove a module + * save_env:: Save variables to environment block + * search:: Search devices by file, label, or UUID + * sendkey:: Emulate keystrokes + * set:: Set an environment variable ++* sha1sum:: Compute or check SHA1 hash ++* sha256sum:: Compute or check SHA256 hash ++* sha512sum:: Compute or check SHA512 hash ++* sleep:: Wait for a specified number of seconds + * source:: Read a configuration file in same context ++* test:: Check file types and compare values + * true:: Do nothing, successfully + * unset:: Unset an environment variable + * uppermem:: Set the upper memory size ++@comment * vbeinfo:: List available video modes ++* videoinfo:: List available video modes + @end menu + + ++@node [ ++@subsection [ ++@deffn Command @code{[} expression @code{]} ++Alias for @code{test @var{expression}} (@pxref{test}). ++@end deffn ++ ++ + @node acpi + @subsection acpi + +@@ -3435,6 +3470,42 @@ Normally, this command will replace the Root System Description Pointer + GRUB, but may be used by GRUB's EFI emulation. + @end deffn + ++ ++@node authenticate ++@subsection authenticate ++@deffn Command authenticate [userlist] ++Check whether user is in @var{userlist} or listed in the value of variable ++@samp{superusers}. See @pxref{superusers} for valid user list format. ++If @samp{superusers} is empty, this command returns true. @xref{Security}. ++@end deffn ++ ++ ++@node background_color ++@subsection background_color ++ ++@deffn Command background_color color ++Set background color for active terminal. For valid color specifications see ++@pxref{Theme file format, ,Colors}. Background color can be changed only when ++using @samp{gfxterm} for terminal output. ++ ++This command sets color of empty areas without text. Text background color ++is controlled by environment variables @var{color_normal}, @var{color_highlight}, ++@var{menu_color_normal}, @var{menu_color_highlight}. @xref{Special environment variables}. ++@end deffn ++ ++ ++@node background_image ++@subsection background_image ++ ++@deffn Command background_image [[@option{--mode} @samp{stretch}|@samp{normal}] file] ++Load background image for active terminal from @var{file}. Image is stretched ++to fill up entire screen unless option @option{--mode} @samp{normal} is given. ++Without arguments remove currently loaded background image. Background image ++can be changed only when using @samp{gfxterm} for terminal output. ++ ++@end deffn ++ ++ + @node badram + @subsection badram + +@@ -3507,6 +3578,42 @@ load a defective boot loader, such as SCO UnixWare 7.1. + @end deffn + + ++@node clear ++@subsection clear ++ ++@deffn Command clear ++Clear the screen. ++@end deffn ++ ++ ++@node cmosclean ++@subsection cmosclean ++ ++@deffn Command cmosclean byte:bit ++Clear value of bit in CMOS at location @var{byte}:@var{bit}. This command ++is available only on platforms that support CMOS. ++@end deffn ++ ++ ++@node cmosdump ++@subsection cmosdump ++ ++@deffn Dump CMOS contents ++Dump full CMOS contents as hexadecimal values. This command is available only ++on platforms that support CMOS. ++@end deffn ++ ++ ++@node cmostest ++@subsection cmostest ++ ++@deffn Command cmostest byte:bit ++Test value of bit in CMOS at location @var{byte}:@var{bit}. Exit status ++is zero if bit is set, non zero otherwise. This command is available only ++on platforms that support CMOS. ++@end deffn ++ ++ + @node cmp + @subsection cmp + +@@ -3557,8 +3664,24 @@ invoked with @option{-l}. This may change in the future. + @node crc + @subsection crc + +-@deffn Command crc file +-Display the CRC32 checksum of @var{file}. ++@deffn Command crc arg @dots{} ++Alias for @code{hashsum --hash crc32 arg @dots{}}. See command @command{hashsum} ++(@pxref{hashsum}) for full description. ++@end deffn ++ ++ ++@node cryptomount ++@subsection cryptomount ++ ++@deffn Command cryptomount device|@option{-u} uuid|@option{-a}|@option{-b} ++Setup access to encrypted device. If necessary, passphrase ++is requested interactively. Option @var{device} configures specific grub device ++(@pxref{Naming convention}); option @option{-u} @var{uuid} configures device ++with specified @var{uuid}; option @option{-a} configures all detected encrypted ++devices; option @option{-b} configures all geli containers that have boot flag set. ++ ++GRUB suports devices encrypted using LUKS and geli. Note that necessary modules (@var{luks} and @var{geli}) have to be loaded manually before this command can ++be used. + @end deffn + + +@@ -3704,6 +3827,29 @@ is shut down using APM. + @end deffn + + ++@node hashsum ++@subsection hashsum ++ ++@deffn Command hashsum @option{--hash} hash @option{--keep-going} @option{--uncompress} @option{--check} file [@option{--prefix} dir]|file @dots{} ++Compute or verify file hashes. Hash type is selected with option @option{--hash}. ++Supported hashes are: @samp{adler32}, @samp{crc64}, @samp{crc32}, ++@samp{crc32rfc1510}, @samp{crc24rfc2440}, @samp{md4}, @samp{md5}, ++@samp{ripemd160}, @samp{sha1}, @samp{sha224}, @samp{sha256}, @samp{sha512}, ++@samp{sha384}, @samp{tiger192}, @samp{tiger}, @samp{tiger2}, @samp{whirlpool}. ++Option @option{--uncompress} uncompresses files before computing hash. ++ ++When list of files is given, hash of each file is computed and printed, ++followed by file name, each file on a new line. ++ ++When option @option{--check} is given, it points to a file that contains ++list of @var{hash name} pairs in the same format as used by UNIX ++@command{md5sum} command. Option @option{--prefix} ++may be used to give directory where files are located. Hash verification ++stops after the first mismatch was found unless option @option{--keep-going} ++was given. ++@end deffn ++ ++ + @node help + @subsection help + +@@ -3822,6 +3968,16 @@ block. + @end deffn + + ++@node loadfont ++@subsection loadfont ++ ++@deffn Command loadfont file @dots{} ++Load specified font files. Unless absolute pathname is given, @var{file} ++is assumed to be in directory @samp{$prefix/fonts} with ++suffix @samp{.pf2} appended. @xref{Theme file format,,Fonts}. ++@end deffn ++ ++ + @node loopback + @subsection loopback + +@@ -3855,6 +4011,31 @@ name syntax}), then list the contents of that directory. + @end deffn + + ++@node lsfonts ++@subsection lsfonts ++ ++@deffn Command lsfonts ++List loaded fonts. ++@end deffn ++ ++ ++@node lsmod ++@subsection lsmod ++ ++@deffn Command lsmod ++Show list of loaded modules. ++@end deffn ++ ++ ++@node md5sum ++@subsection md5sum ++ ++@deffn Command md5sum arg @dots{} ++Alias for @code{hashsum --hash md5 arg @dots{}}. See command @command{hashsum} ++(@pxref{hashsum}) for full description. ++@end deffn ++ ++ + @node normal + @subsection normal + +@@ -3940,7 +4121,7 @@ to generate password hashes. @xref{Security}. + @node play + @subsection play + +-@deffn Command play file | tempo [pitch1 duration1] [pitch2 duration2] ... ++@deffn Command play file | tempo [pitch1 duration1] [pitch2 duration2] @dots{} + Plays a tune + + If the argument is a file name (@pxref{File name syntax}), play the tune +@@ -3956,6 +4137,15 @@ a rest. + @end deffn + + ++@node probe ++@subsection probe ++ ++@deffn Command probe [@option{--set} var] @option{--driver}|@option{--partmap}|@option{--fs}|@option{--fs-uuid}|@option{--label} device ++Retrieve device information. If option @option{--set} is given, assign result ++to variable @var{var}, otherwise print information on the screen. ++@end deffn ++ ++ + @node pxe_unload + @subsection pxe_unload + +@@ -3984,6 +4174,26 @@ Reboot the computer. + @end deffn + + ++@node regexp ++@subsection regexp ++ ++@deffn Command regexp [@option{--set} [number:]var] regexp string ++Test if regular expression @var{regexp} matches @var{string}. Supported ++regular expressions are POSIX.2 Extended Regular Expressions. If option ++@option{--set} is given, store @var{number}th matched subexpression in ++variable @var{var}. Subexpressions are numbered in order of their opening ++parentheses starting from @samp{1}. @var{number} defaults to @samp{1}. ++@end deffn ++ ++ ++@node rmmod ++@subsection rmmod ++ ++@deffn Command rmmod module ++Remove a loaded @var{module}. ++@end deffn ++ ++ + @node save_env + @subsection save_env + +@@ -4176,6 +4386,43 @@ arguments, print all environment variables with their values. + @end deffn + + ++@node sha1sum ++@subsection sha1sum ++ ++@deffn Command sha1sum arg @dots{} ++Alias for @code{hashsum --hash sha1 arg @dots{}}. See command @command{hashsum} ++(@pxref{hashsum}) for full description. ++@end deffn ++ ++ ++@node sha256sum ++@subsection sha256sum ++ ++@deffn Command sha256sum arg @dots{} ++Alias for @code{hashsum --hash sha256 arg @dots{}}. See command @command{hashsum} ++(@pxref{hashsum}) for full description. ++@end deffn ++ ++ ++@node sha512sum ++@subsection sha512sum ++ ++@deffn Command sha512sum arg @dots{} ++Alias for @code{hashsum --hash sha512 arg @dots{}}. See command @command{hashsum} ++(@pxref{hashsum}) for full description. ++@end deffn ++ ++ ++@node sleep ++@subsection sleep ++ ++@deffn Command sleep [@option{--verbose}] [@option{--interruptible}] count ++Sleep for @var{count} seconds. If option @option{--interruptible} is given, ++allow @key{ESC} to interrupt sleep. With @option{--verbose} show countdown ++of remaining seconds. ++@end deffn ++ ++ + @node source + @subsection source + +@@ -4189,6 +4436,74 @@ will not be shown immediately. + @end deffn + + ++@node test ++@subsection test ++ ++@deffn Command test expression ++Evaluate @var{expression} and return zero exit status if result is true, ++non zero status otherwise. ++ ++@var{expression} is one of: ++ ++@table @asis ++@item @var{string1} @code{==} @var{string2} ++the strings are equal ++@item @var{string1} @code{!=} @var{string2} ++the strings are not equal ++@item @var{string1} @code{<} @var{string2} ++@var{string1} is lexicographically less than @var{string2} ++@item @var{string1} @code{<=} @var{string2} ++@var{string1} is lexicographically less or equal than @var{string2} ++@item @var{string1} @code{>} @var{string2} ++@var{string1} is lexicographically greater than @var{string2} ++@item @var{string1} @code{>=} @var{string2} ++@var{string1} is lexicographically greater or equal than @var{string2} ++@item @var{integer1} @code{-eq} @var{integer2} ++@var{integer1} is equal to @var{integer2} ++@item @var{integer1} @code{-ge} @var{integer2} ++@var{integer1} is greater than or equal to @var{integer2} ++@item @var{integer1} @code{-gt} @var{integer2} ++@var{integer1} is greater than @var{integer2} ++@item @var{integer1} @code{-le} @var{integer2} ++@var{integer1} is less than or equal to @var{integer2} ++@item @var{integer1} @code{-lt} @var{integer2} ++@var{integer1} is less than @var{integer2} ++@item @var{integer1} @code{-ne} @var{integer2} ++@var{integer1} is not equal to @var{integer2} ++@item @var{prefix}@var{integer1} @code{-pgt} @var{prefix}@var{integer2} ++@var{integer1} is greater than @var{integer2} after stripping off common non-numeric @var{prefix}. ++@item @var{prefix}@var{integer1} @code{-plt} @var{prefix}@var{integer2} ++@var{integer1} is less than @var{integer2} after stripping off common non-numeric @var{prefix}. ++@item @var{file1} @code{-nt} @var{file2} ++@var{file1} is newer than @var{file2} (modification time). Optionally numeric @var{bias} may be directly appended to @code{-nt} in which case it is added to the first file modification time. ++@item @var{file1} @code{-ot} @var{file2} ++@var{file1} is older than @var{file2} (modification time). Optionally numeric @var{bias} may be directly appended to @code{-ot} in which case it is added to the first file modification time. ++@item @code{-d} @var{file} ++@var{file} exists and is a directory ++@item @code{-e} @var{file} ++@var{file} exists ++@item @code{-f} @var{file} ++@var{file} exists and is not a directory ++@item @code{-s} @var{file} ++@var{file} exists and has a size greater than zero ++@item @code{-n} @var{string} ++the length of @var{string} is nonzero ++@item @var{string} ++@var{string} is equivalent to @code{-n @var{string}} ++@item @code{-z} @var{string} ++the length of @var{string} is zero ++@item @code{(} @var{expression} @code{)} ++@var{expression} is true ++@item @code{!} @var{expression} ++@var{expression} is false ++@item @var{expression1} @code{-a} @var{expression2} ++both @var{expression1} and @var{expression2} are true ++@item @var{expression1} @code{-o} @var{expression2} ++either @var{expression1} or @var{expression2} is true ++@end table ++@end deffn ++ ++ + @node true + @subsection true + +@@ -4211,6 +4526,25 @@ Unset the environment variable @var{envvar}. + + This command is not yet implemented for GRUB 2, although it is planned. + ++ ++@ignore ++@node vbeinfo ++@subsection vbeinfo ++ ++@deffn Command vbeinfo [[WxH]xD] ++Alias for command @command{videoinfo} (@pxref{videoinfo}). It is available ++only on PC BIOS platforms. ++@end deffn ++@end ignore ++ ++ ++@node videoinfo ++@subsection videoinfo ++ ++@deffn Command videoinfo [[WxH]xD] ++List available video modes. If resolution is given, show only matching modes. ++@end deffn ++ + @node Internationalisation + @chapter Charset + GRUB uses UTF-8 internally other than in rendering where some GRUB-specific +@@ -4311,7 +4645,7 @@ Identifiers containing non-ASCII may work but aren't supported. + Only the ASCII space characters (space U+0020, tab U+000b, CR U+000d and + LF U+000a) are recognised. Other unicode space characters aren't a valid + field separator. +-@command{test} tests <, >, <=, >=, -pgt and -plt compare the strings in the ++@command{test} (@pxref{test}) tests <, >, <=, >=, -pgt and -plt compare the strings in the + lexicographical order of unicode codepoints, replicating the behaviour of + test from coreutils. + environment variables and commands are listed in the same order. +@@ -4769,8 +5103,8 @@ 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. ++devices with unsupported encryption scheme, nor from file systems for which ++support has not yet been added to GRUB. + @end itemize + + +-- +1.8.1.4 + diff --git a/0258-Move-GRUB_CHAR_BIT-to-types.h.patch b/0258-Move-GRUB_CHAR_BIT-to-types.h.patch new file mode 100644 index 0000000..a15b054 --- /dev/null +++ b/0258-Move-GRUB_CHAR_BIT-to-types.h.patch @@ -0,0 +1,48 @@ +From 1c71a6e0aa77b119cb196b296aff5393246c541d Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Fri, 5 Apr 2013 10:31:12 +0200 +Subject: [PATCH 258/364] Move GRUB_CHAR_BIT to types.h. + +--- + ChangeLog | 4 ++++ + include/grub/misc.h | 2 -- + include/grub/types.h | 2 ++ + 3 files changed, 6 insertions(+), 2 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index d63c0e5..3008ff0 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,7 @@ ++2013-04-05 Vladimir Serbinenko ++ ++ Move GRUB_CHAR_BIT to types.h. ++ + 2013-04-04 Andrey Borzenkov + + * docs/grub.texi: Document more user commands. +diff --git a/include/grub/misc.h b/include/grub/misc.h +index 0ea5114..c953a00 100644 +--- a/include/grub/misc.h ++++ b/include/grub/misc.h +@@ -481,6 +481,4 @@ void EXPORT_FUNC(grub_real_boot_time) (const char *file, + #define grub_max(a, b) (((a) > (b)) ? (a) : (b)) + #define grub_min(a, b) (((a) < (b)) ? (a) : (b)) + +-#define GRUB_CHAR_BIT 8 +- + #endif /* ! GRUB_MISC_HEADER */ +diff --git a/include/grub/types.h b/include/grub/types.h +index 22d1be7..7c56f40 100644 +--- a/include/grub/types.h ++++ b/include/grub/types.h +@@ -300,4 +300,6 @@ static inline void grub_set_unaligned64 (void *ptr, grub_uint64_t val) + dd->d = val; + } + ++#define GRUB_CHAR_BIT 8 ++ + #endif /* ! GRUB_TYPES_HEADER */ +-- +1.8.1.4 + diff --git a/0259-include-grub-bsdlabel.h-Use-enums.patch b/0259-include-grub-bsdlabel.h-Use-enums.patch new file mode 100644 index 0000000..0d539ef --- /dev/null +++ b/0259-include-grub-bsdlabel.h-Use-enums.patch @@ -0,0 +1,120 @@ +From c74a404c260cba6d901b51e9915639966ff1a732 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Fri, 5 Apr 2013 10:33:53 +0200 +Subject: [PATCH 259/364] * include/grub/bsdlabel.h: Use enums. + +--- + ChangeLog | 4 +++ + include/grub/bsdlabel.h | 76 ++++++++++++++++++++++++++++--------------------- + 2 files changed, 48 insertions(+), 32 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 3008ff0..37021c0 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,9 @@ + 2013-04-05 Vladimir Serbinenko + ++ * include/grub/bsdlabel.h: Use enums. ++ ++2013-04-05 Vladimir Serbinenko ++ + Move GRUB_CHAR_BIT to types.h. + + 2013-04-04 Andrey Borzenkov +diff --git a/include/grub/bsdlabel.h b/include/grub/bsdlabel.h +index b10336c..8f241df 100644 +--- a/include/grub/bsdlabel.h ++++ b/include/grub/bsdlabel.h +@@ -24,44 +24,56 @@ + #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 ++enum ++ { ++ GRUB_PC_PARTITION_BSD_TYPE_UNUSED = 0, ++ GRUB_PC_PARTITION_BSD_TYPE_SWAP = 1, ++ GRUB_PC_PARTITION_BSD_TYPE_V6 = 2, ++ GRUB_PC_PARTITION_BSD_TYPE_V7 = 3, ++ GRUB_PC_PARTITION_BSD_TYPE_SYSV = 4, ++ GRUB_PC_PARTITION_BSD_TYPE_V71K = 5, ++ GRUB_PC_PARTITION_BSD_TYPE_V8 = 6, ++ GRUB_PC_PARTITION_BSD_TYPE_BSDFFS = 7, ++ GRUB_PC_PARTITION_BSD_TYPE_MSDOS = 8, ++ GRUB_PC_PARTITION_BSD_TYPE_BSDLFS = 9, ++ GRUB_PC_PARTITION_BSD_TYPE_OTHER = 10, ++ GRUB_PC_PARTITION_BSD_TYPE_HPFS = 11, ++ GRUB_PC_PARTITION_BSD_TYPE_ISO9660 = 12, ++ 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 ++enum ++ { ++ GRUB_PC_PARTITION_FREEBSD_TYPE_VINUM = 14, ++ GRUB_PC_PARTITION_FREEBSD_TYPE_RAID = 15, ++ 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 ++enum ++ { ++ GRUB_PC_PARTITION_NETBSD_TYPE_ADOS = 14, ++ GRUB_PC_PARTITION_NETBSD_TYPE_HFS = 15, ++ GRUB_PC_PARTITION_NETBSD_TYPE_FILECORE = 16, ++ GRUB_PC_PARTITION_NETBSD_TYPE_EXT2FS = 17, ++ GRUB_PC_PARTITION_NETBSD_TYPE_NTFS = 18, ++ GRUB_PC_PARTITION_NETBSD_TYPE_RAID = 19, ++ GRUB_PC_PARTITION_NETBSD_TYPE_CCD = 20, ++ GRUB_PC_PARTITION_NETBSD_TYPE_JFS2 = 21, ++ 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 ++enum ++ { ++ GRUB_PC_PARTITION_OPENBSD_TYPE_ADOS = 14, ++ GRUB_PC_PARTITION_OPENBSD_TYPE_HFS = 15, ++ GRUB_PC_PARTITION_OPENBSD_TYPE_FILECORE = 16, ++ GRUB_PC_PARTITION_OPENBSD_TYPE_EXT2FS = 17, ++ GRUB_PC_PARTITION_OPENBSD_TYPE_NTFS = 18, ++ GRUB_PC_PARTITION_OPENBSD_TYPE_RAID = 19 ++ }; + + #define GRUB_PC_PARTITION_BSD_LABEL_WHOLE_DISK_PARTITION 2 + +-- +1.8.1.4 + diff --git a/0260-grub-core-commands-verify.c-Use-GRUB_CHAR_BIT.patch b/0260-grub-core-commands-verify.c-Use-GRUB_CHAR_BIT.patch new file mode 100644 index 0000000..0b0405a --- /dev/null +++ b/0260-grub-core-commands-verify.c-Use-GRUB_CHAR_BIT.patch @@ -0,0 +1,59 @@ +From f7db5c611d5560adea0c15e804d3b6dbca5d03b9 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Fri, 5 Apr 2013 10:52:13 +0200 +Subject: [PATCH 260/364] * grub-core/commands/verify.c: Use + GRUB_CHAR_BIT. + +--- + ChangeLog | 4 ++++ + grub-core/commands/verify.c | 6 +++--- + 2 files changed, 7 insertions(+), 3 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 37021c0..e52e7ee 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,9 @@ + 2013-04-05 Vladimir Serbinenko + ++ * grub-core/commands/verify.c: Use GRUB_CHAR_BIT. ++ ++2013-04-05 Vladimir Serbinenko ++ + * include/grub/bsdlabel.h: Use enums. + + 2013-04-05 Vladimir Serbinenko +diff --git a/grub-core/commands/verify.c b/grub-core/commands/verify.c +index bd47611..fd6f436 100644 +--- a/grub-core/commands/verify.c ++++ b/grub-core/commands/verify.c +@@ -77,7 +77,7 @@ read_packet_header (grub_file_t sig, grub_uint8_t *out_type, grub_size_t *len) + } + if (l < 224) + { +- *len = (l - 192) << 8; ++ *len = (l - 192) << GRUB_CHAR_BIT; + if (grub_file_read (sig, &l, sizeof (l)) != 1) + return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); + *len |= l; +@@ -273,7 +273,7 @@ grub_load_public_key (grub_file_t f) + goto fail; + } + +- lb = (grub_be_to_cpu16 (l) + 7) / 8; ++ lb = (grub_be_to_cpu16 (l) + GRUB_CHAR_BIT - 1) / GRUB_CHAR_BIT; + if (lb > sizeof (buffer) - sizeof (grub_uint16_t)) + { + grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature")); +@@ -457,7 +457,7 @@ grub_verify_signature_real (char *buf, grub_size_t size, + { + if (ptr + 1 >= readbuf + rem) + break; +- l = (((ptr[0] & ~192) << 8) | ptr[1]) + 192; ++ l = (((ptr[0] & ~192) << GRUB_CHAR_BIT) | ptr[1]) + 192; + ptr += 2; + } + else +-- +1.8.1.4 + diff --git a/0261-Add-new-defines-GRUB_RSDP_SIGNATURE_SIZE-and-GRUB_RS.patch b/0261-Add-new-defines-GRUB_RSDP_SIGNATURE_SIZE-and-GRUB_RS.patch new file mode 100644 index 0000000..f247fd6 --- /dev/null +++ b/0261-Add-new-defines-GRUB_RSDP_SIGNATURE_SIZE-and-GRUB_RS.patch @@ -0,0 +1,137 @@ +From ef226c0cc274e70d8a2be3798a1c7ae3e96dbdce Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Fri, 5 Apr 2013 10:56:43 +0200 +Subject: [PATCH 261/364] Add new defines GRUB_RSDP_SIGNATURE_SIZE and + GRUB_RSDP_SIGNATURE. + +--- + ChangeLog | 4 ++++ + grub-core/commands/acpi.c | 10 +++++----- + grub-core/commands/i386/pc/acpi.c | 8 ++++---- + include/grub/acpi.h | 5 ++++- + 4 files changed, 17 insertions(+), 10 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index e52e7ee..3431895 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,9 @@ + 2013-04-05 Vladimir Serbinenko + ++ Add new defines GRUB_RSDP_SIGNATURE_SIZE and GRUB_RSDP_SIGNATURE. ++ ++2013-04-05 Vladimir Serbinenko ++ + * grub-core/commands/verify.c: Use GRUB_CHAR_BIT. + + 2013-04-05 Vladimir Serbinenko +diff --git a/grub-core/commands/acpi.c b/grub-core/commands/acpi.c +index 8000873..4ca8cf7 100644 +--- a/grub-core/commands/acpi.c ++++ b/grub-core/commands/acpi.c +@@ -217,7 +217,7 @@ grub_acpi_create_ebda (void) + { + grub_dprintf ("acpi", "Scanning EBDA for old rsdpv2\n"); + for (; target < targetebda + 0x400 - v2->length; target += 0x10) +- if (grub_memcmp (target, "RSD PTR ", 8) == 0 ++ if (grub_memcmp (target, GRUB_RSDP_SIGNATURE, GRUB_RSDP_SIGNATURE_SIZE) == 0 + && grub_byte_checksum (target, + sizeof (struct grub_acpi_rsdp_v10)) == 0 + && ((struct grub_acpi_rsdp_v10 *) target)->revision != 0 +@@ -238,7 +238,7 @@ grub_acpi_create_ebda (void) + grub_dprintf ("acpi", "Scanning EBDA for old rsdpv1\n"); + for (; target < targetebda + 0x400 - sizeof (struct grub_acpi_rsdp_v10); + target += 0x10) +- if (grub_memcmp (target, "RSD PTR ", 8) == 0 ++ if (grub_memcmp (target, GRUB_RSDP_SIGNATURE, GRUB_RSDP_SIGNATURE_SIZE) == 0 + && grub_byte_checksum (target, + sizeof (struct grub_acpi_rsdp_v10)) == 0) + { +@@ -299,7 +299,7 @@ grub_acpi_create_ebda (void) + for (target = targetebda; + target < targetebda + 0x400 - sizeof (struct grub_acpi_rsdp_v10); + target += 0x10) +- if (grub_memcmp (target, "RSD PTR ", 8) == 0 ++ if (grub_memcmp (target, GRUB_RSDP_SIGNATURE, GRUB_RSDP_SIGNATURE_SIZE) == 0 + && grub_byte_checksum (target, + sizeof (struct grub_acpi_rsdp_v10)) == 0 + && target != v1inebda && target != v2inebda) +@@ -394,7 +394,7 @@ setv1table (void) + /* Create RSDP. */ + rsdpv1_new = (struct grub_acpi_rsdp_v10 *) playground_ptr; + playground_ptr += sizeof (struct grub_acpi_rsdp_v10); +- grub_memcpy (&(rsdpv1_new->signature), "RSD PTR ", ++ grub_memcpy (&(rsdpv1_new->signature), GRUB_RSDP_SIGNATURE, + sizeof (rsdpv1_new->signature)); + grub_memcpy (&(rsdpv1_new->oemid), root_oemid, sizeof (rsdpv1_new->oemid)); + rsdpv1_new->revision = 0; +@@ -438,7 +438,7 @@ setv2table (void) + /* Create RSDPv2. */ + rsdpv2_new = (struct grub_acpi_rsdp_v20 *) playground_ptr; + playground_ptr += sizeof (struct grub_acpi_rsdp_v20); +- grub_memcpy (&(rsdpv2_new->rsdpv1.signature), "RSD PTR ", ++ grub_memcpy (&(rsdpv2_new->rsdpv1.signature), GRUB_RSDP_SIGNATURE, + sizeof (rsdpv2_new->rsdpv1.signature)); + grub_memcpy (&(rsdpv2_new->rsdpv1.oemid), root_oemid, + sizeof (rsdpv2_new->rsdpv1.oemid)); +diff --git a/grub-core/commands/i386/pc/acpi.c b/grub-core/commands/i386/pc/acpi.c +index 88e4f55..d415d23 100644 +--- a/grub-core/commands/i386/pc/acpi.c ++++ b/grub-core/commands/i386/pc/acpi.c +@@ -32,7 +32,7 @@ grub_machine_acpi_get_rsdpv1 (void) + if (! ebda_len) + return 0; + for (ptr = ebda; ptr < ebda + 0x400; ptr += 16) +- if (grub_memcmp (ptr, "RSD PTR ", 8) == 0 ++ if (grub_memcmp (ptr, GRUB_RSDP_SIGNATURE, GRUB_RSDP_SIGNATURE_SIZE) == 0 + && grub_byte_checksum (ptr, sizeof (struct grub_acpi_rsdp_v10)) == 0 + && ((struct grub_acpi_rsdp_v10 *) ptr)->revision == 0) + return (struct grub_acpi_rsdp_v10 *) ptr; +@@ -40,7 +40,7 @@ grub_machine_acpi_get_rsdpv1 (void) + grub_dprintf ("acpi", "Looking for RSDP. Scanning BIOS\n"); + for (ptr = (grub_uint8_t *) 0xe0000; ptr < (grub_uint8_t *) 0x100000; + ptr += 16) +- if (grub_memcmp (ptr, "RSD PTR ", 8) == 0 ++ if (grub_memcmp (ptr, GRUB_RSDP_SIGNATURE, GRUB_RSDP_SIGNATURE_SIZE) == 0 + && grub_byte_checksum (ptr, sizeof (struct grub_acpi_rsdp_v10)) == 0 + && ((struct grub_acpi_rsdp_v10 *) ptr)->revision == 0) + return (struct grub_acpi_rsdp_v10 *) ptr; +@@ -59,7 +59,7 @@ grub_machine_acpi_get_rsdpv2 (void) + if (! ebda_len) + return 0; + for (ptr = ebda; ptr < ebda + 0x400; ptr += 16) +- if (grub_memcmp (ptr, "RSD PTR ", 8) == 0 ++ if (grub_memcmp (ptr, GRUB_RSDP_SIGNATURE, GRUB_RSDP_SIGNATURE_SIZE) == 0 + && grub_byte_checksum (ptr, sizeof (struct grub_acpi_rsdp_v10)) == 0 + && ((struct grub_acpi_rsdp_v10 *) ptr)->revision != 0 + && ((struct grub_acpi_rsdp_v20 *) ptr)->length < 1024 +@@ -70,7 +70,7 @@ grub_machine_acpi_get_rsdpv2 (void) + grub_dprintf ("acpi", "Looking for RSDP. Scanning BIOS\n"); + for (ptr = (grub_uint8_t *) 0xe0000; ptr < (grub_uint8_t *) 0x100000; + ptr += 16) +- if (grub_memcmp (ptr, "RSD PTR ", 8) == 0 ++ if (grub_memcmp (ptr, GRUB_RSDP_SIGNATURE, GRUB_RSDP_SIGNATURE_SIZE) == 0 + && grub_byte_checksum (ptr, sizeof (struct grub_acpi_rsdp_v10)) == 0 + && ((struct grub_acpi_rsdp_v10 *) ptr)->revision != 0 + && ((struct grub_acpi_rsdp_v20 *) ptr)->length < 1024 +diff --git a/include/grub/acpi.h b/include/grub/acpi.h +index 8fa957d..32bb95c 100644 +--- a/include/grub/acpi.h ++++ b/include/grub/acpi.h +@@ -24,9 +24,12 @@ + #include + #endif + ++#define GRUB_RSDP_SIGNATURE "RSD PTR " ++#define GRUB_RSDP_SIGNATURE_SIZE 8 ++ + struct grub_acpi_rsdp_v10 + { +- grub_uint8_t signature[8]; ++ grub_uint8_t signature[GRUB_RSDP_SIGNATURE_SIZE]; + grub_uint8_t checksum; + grub_uint8_t oemid[6]; + grub_uint8_t revision; +-- +1.8.1.4 + diff --git a/0262-Replace-8-with-GRUB_CHAR_BIT-in-several-places-when-.patch b/0262-Replace-8-with-GRUB_CHAR_BIT-in-several-places-when-.patch new file mode 100644 index 0000000..a26bccf --- /dev/null +++ b/0262-Replace-8-with-GRUB_CHAR_BIT-in-several-places-when-.patch @@ -0,0 +1,69 @@ +From 28faaaf7c2a7b639839dcb027275f0f8631ed837 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Fri, 5 Apr 2013 10:59:26 +0200 +Subject: [PATCH 262/364] Replace 8 with GRUB_CHAR_BIT in several places + when appropriate. + +--- + ChangeLog | 4 ++++ + grub-core/disk/cryptodisk.c | 2 +- + grub-core/disk/efi/efidisk.c | 2 +- + grub-core/disk/geli.c | 2 +- + 4 files changed, 7 insertions(+), 3 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 3431895..7e2a62f 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,9 @@ + 2013-04-05 Vladimir Serbinenko + ++ Replace 8 with GRUB_CHAR_BIT in several places when appropriate. ++ ++2013-04-05 Vladimir Serbinenko ++ + Add new defines GRUB_RSDP_SIGNATURE_SIZE and GRUB_RSDP_SIGNATURE. + + 2013-04-05 Vladimir Serbinenko +diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c +index 374edd1..5b12a23 100644 +--- a/grub-core/disk/cryptodisk.c ++++ b/grub-core/disk/cryptodisk.c +@@ -103,7 +103,7 @@ gf_mul_be (grub_uint8_t *o, const grub_uint8_t *a, const grub_uint8_t *b) + grub_memcpy (t, b, GRUB_CRYPTODISK_GF_BYTES); + for (i = 0; i < GRUB_CRYPTODISK_GF_SIZE; i++) + { +- if (((a[GRUB_CRYPTODISK_GF_BYTES - i / 8 - 1] >> (i % 8))) & 1) ++ if (((a[GRUB_CRYPTODISK_GF_BYTES - i / GRUB_CHAR_BIT - 1] >> (i % GRUB_CHAR_BIT))) & 1) + grub_crypto_xor (o, o, t, GRUB_CRYPTODISK_GF_BYTES); + gf_mul_x_be (t); + } +diff --git a/grub-core/disk/efi/efidisk.c b/grub-core/disk/efi/efidisk.c +index 0a364f1..28b9fa1 100644 +--- a/grub-core/disk/efi/efidisk.c ++++ b/grub-core/disk/efi/efidisk.c +@@ -501,7 +501,7 @@ grub_efidisk_open (const char *name, struct grub_disk *disk) + if (! d) + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no such device"); + +- disk->id = ((num << 8) | name[0]); ++ disk->id = ((num << GRUB_CHAR_BIT) | name[0]); + m = d->block_io->media; + /* FIXME: Probably it is better to store the block size in the disk, + and total sectors should be replaced with total blocks. */ +diff --git a/grub-core/disk/geli.c b/grub-core/disk/geli.c +index 0b94414..55aa5b9 100644 +--- a/grub-core/disk/geli.c ++++ b/grub-core/disk/geli.c +@@ -414,7 +414,7 @@ recover_key (grub_disk_t source, grub_cryptodisk_t dev) + if (err) + return err; + +- keysize = grub_le_to_cpu16 (header.keylen) / 8; ++ keysize = grub_le_to_cpu16 (header.keylen) / GRUB_CHAR_BIT; + grub_memset (zero, 0, sizeof (zero)); + + grub_puts_ (N_("Attempting to decrypt master key...")); +-- +1.8.1.4 + diff --git a/0263-grub-core-commands-acpi.c-Use-sizeof-rather-than-har.patch b/0263-grub-core-commands-acpi.c-Use-sizeof-rather-than-har.patch new file mode 100644 index 0000000..bb9bd23 --- /dev/null +++ b/0263-grub-core-commands-acpi.c-Use-sizeof-rather-than-har.patch @@ -0,0 +1,78 @@ +From a275d1fc56fb118a9ebdd48c8680d0b47e3c3c59 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Fri, 5 Apr 2013 11:01:19 +0200 +Subject: [PATCH 263/364] * grub-core/commands/acpi.c: Use sizeof rather + than hardcoding the size. + +--- + ChangeLog | 4 ++++ + grub-core/commands/acpi.c | 12 ++++++------ + 2 files changed, 10 insertions(+), 6 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 7e2a62f..f90fab4 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,9 @@ + 2013-04-05 Vladimir Serbinenko + ++ * grub-core/commands/acpi.c: Use sizeof rather than hardcoding the size. ++ ++2013-04-05 Vladimir Serbinenko ++ + Replace 8 with GRUB_CHAR_BIT in several places when appropriate. + + 2013-04-05 Vladimir Serbinenko +diff --git a/grub-core/commands/acpi.c b/grub-core/commands/acpi.c +index 4ca8cf7..14f639c 100644 +--- a/grub-core/commands/acpi.c ++++ b/grub-core/commands/acpi.c +@@ -365,13 +365,13 @@ setup_common_tables (void) + numoftables++; + + rsdt_addr = rsdt = (struct grub_acpi_table_header *) playground_ptr; +- playground_ptr += sizeof (struct grub_acpi_table_header) + 4 * numoftables; ++ playground_ptr += sizeof (struct grub_acpi_table_header) + sizeof (grub_uint32_t) * numoftables; + + rsdt_entry = (grub_uint32_t *) (rsdt + 1); + + /* Fill RSDT header. */ + grub_memcpy (&(rsdt->signature), "RSDT", 4); +- rsdt->length = sizeof (struct grub_acpi_table_header) + 4 * numoftables; ++ rsdt->length = sizeof (struct grub_acpi_table_header) + sizeof (grub_uint32_t) * numoftables; + rsdt->revision = 1; + grub_memcpy (&(rsdt->oemid), root_oemid, sizeof (rsdt->oemid)); + grub_memcpy (&(rsdt->oemtable), root_oemtable, sizeof (rsdt->oemtable)); +@@ -419,13 +419,13 @@ setv2table (void) + + /* Create XSDT. */ + xsdt = (struct grub_acpi_table_header *) playground_ptr; +- playground_ptr += sizeof (struct grub_acpi_table_header) + 8 * numoftables; ++ playground_ptr += sizeof (struct grub_acpi_table_header) + sizeof (grub_uint64_t) * numoftables; + + xsdt_entry = (grub_uint64_t *)(xsdt + 1); + for (cur = acpi_tables; cur; cur = cur->next) + *(xsdt_entry++) = (grub_addr_t) cur->addr; + grub_memcpy (&(xsdt->signature), "XSDT", 4); +- xsdt->length = sizeof (struct grub_acpi_table_header) + 8 * numoftables; ++ xsdt->length = sizeof (struct grub_acpi_table_header) + sizeof (grub_uint64_t) * numoftables; + xsdt->revision = 1; + grub_memcpy (&(xsdt->oemid), root_oemid, sizeof (xsdt->oemid)); + grub_memcpy (&(xsdt->oemtable), root_oemtable, sizeof (xsdt->oemtable)); +@@ -708,11 +708,11 @@ grub_cmd_acpi (struct grub_extcmd_context *ctxt, int argc, char **args) + /* DSDT. */ + playground_size += dsdt_size; + /* RSDT. */ +- playground_size += sizeof (struct grub_acpi_table_header) + 4 * numoftables; ++ playground_size += sizeof (struct grub_acpi_table_header) + sizeof (grub_uint32_t) * numoftables; + /* RSDPv1. */ + playground_size += sizeof (struct grub_acpi_rsdp_v10); + /* XSDT. */ +- playground_size += sizeof (struct grub_acpi_table_header) + 8 * numoftables; ++ playground_size += sizeof (struct grub_acpi_table_header) + sizeof (grub_uint64_t) * numoftables; + /* RSDPv2. */ + playground_size += sizeof (struct grub_acpi_rsdp_v20); + +-- +1.8.1.4 + diff --git a/0264-util-grub-mkfont.c-Prefer-enum-to-define.patch b/0264-util-grub-mkfont.c-Prefer-enum-to-define.patch new file mode 100644 index 0000000..29281b1 --- /dev/null +++ b/0264-util-grub-mkfont.c-Prefer-enum-to-define.patch @@ -0,0 +1,49 @@ +From d01148a183ca591cc2e2c9313f939eb4392d0166 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Fri, 5 Apr 2013 11:13:37 +0200 +Subject: [PATCH 264/364] * util/grub-mkfont.c: Prefer enum to #define. + +--- + ChangeLog | 4 ++++ + util/grub-mkfont.c | 11 +++++++---- + 2 files changed, 11 insertions(+), 4 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index f90fab4..41370a1 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,9 @@ + 2013-04-05 Vladimir Serbinenko + ++ * util/grub-mkfont.c: Prefer enum to #define. ++ ++2013-04-05 Vladimir Serbinenko ++ + * grub-core/commands/acpi.c: Use sizeof rather than hardcoding the size. + + 2013-04-05 Vladimir Serbinenko +diff --git a/util/grub-mkfont.c b/util/grub-mkfont.c +index 83fb2d2..0343fd2 100644 +--- a/util/grub-mkfont.c ++++ b/util/grub-mkfont.c +@@ -73,10 +73,13 @@ enum file_formats + WIDTH_SPEC + }; + +-#define GRUB_FONT_FLAG_BOLD 1 +-#define GRUB_FONT_FLAG_NOBITMAP 2 +-#define GRUB_FONT_FLAG_NOHINTING 4 +-#define GRUB_FONT_FLAG_FORCEHINT 8 ++enum ++ { ++ GRUB_FONT_FLAG_BOLD = 1, ++ GRUB_FONT_FLAG_NOBITMAP = 2, ++ GRUB_FONT_FLAG_NOHINTING = 4, ++ GRUB_FONT_FLAG_FORCEHINT = 8 ++ }; + + struct grub_font_info + { +-- +1.8.1.4 + diff --git a/0265-Use-GRUB_PROPERLY_ALIGNED_ARRAY-in-grub-core-disk-cr.patch b/0265-Use-GRUB_PROPERLY_ALIGNED_ARRAY-in-grub-core-disk-cr.patch new file mode 100644 index 0000000..fefc3a3 --- /dev/null +++ b/0265-Use-GRUB_PROPERLY_ALIGNED_ARRAY-in-grub-core-disk-cr.patch @@ -0,0 +1,56 @@ +From e16d5721a09be08276d8b0555a69f798dcf12550 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Fri, 5 Apr 2013 13:26:10 +0200 +Subject: [PATCH 265/364] Use GRUB_PROPERLY_ALIGNED_ARRAY in + grub-core/disk/cryptodisk.c and grub-core/disk/geli.c. + +--- + ChangeLog | 5 +++++ + grub-core/disk/cryptodisk.c | 2 +- + grub-core/disk/geli.c | 2 +- + 3 files changed, 7 insertions(+), 2 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 41370a1..2f2f7a3 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,10 @@ + 2013-04-05 Vladimir Serbinenko + ++ Use GRUB_PROPERLY_ALIGNED_ARRAY in grub-core/disk/cryptodisk.c and ++ grub-core/disk/geli.c. ++ ++2013-04-05 Vladimir Serbinenko ++ + * util/grub-mkfont.c: Prefer enum to #define. + + 2013-04-05 Vladimir Serbinenko +diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c +index 5b12a23..6fbfc4a 100644 +--- a/grub-core/disk/cryptodisk.c ++++ b/grub-core/disk/cryptodisk.c +@@ -256,7 +256,7 @@ grub_cryptodisk_endecrypt (struct grub_cryptodisk *dev, + case GRUB_CRYPTODISK_MODE_IV_BYTECOUNT64_HASH: + { + grub_uint64_t tmp; +- grub_uint64_t ctx[(dev->iv_hash->contextsize + 7) / 8]; ++ GRUB_PROPERLY_ALIGNED_ARRAY (ctx, dev->iv_hash->contextsize); + + grub_memset (ctx, 0, sizeof (ctx)); + +diff --git a/grub-core/disk/geli.c b/grub-core/disk/geli.c +index 55aa5b9..2aa1ae0 100644 +--- a/grub-core/disk/geli.c ++++ b/grub-core/disk/geli.c +@@ -146,7 +146,7 @@ geli_rekey (struct grub_cryptodisk *dev, grub_uint64_t zoneno) + grub_uint64_t zone; + } __attribute__ ((packed)) tohash + = { {'e', 'k', 'e', 'y'}, grub_cpu_to_le64 (zoneno) }; +- grub_uint64_t key[(dev->hash->mdlen + 7) / 8]; ++ GRUB_PROPERLY_ALIGNED_ARRAY (key, dev->hash->mdlen); + + grub_dprintf ("geli", "rekeying %" PRIuGRUB_UINT64_T " keysize=%d\n", + zoneno, dev->rekey_derived_size); +-- +1.8.1.4 + diff --git a/0266-util-grub.d-30_os-prober.in-Support-btrrfs-linux-pro.patch b/0266-util-grub.d-30_os-prober.in-Support-btrrfs-linux-pro.patch new file mode 100644 index 0000000..54a9cb4 --- /dev/null +++ b/0266-util-grub.d-30_os-prober.in-Support-btrrfs-linux-pro.patch @@ -0,0 +1,55 @@ +From 790ea9881cf13902e966034fdde12850d7b5085b Mon Sep 17 00:00:00 2001 +From: Fedora Ninjas +Date: Fri, 5 Apr 2013 14:55:37 +0200 +Subject: [PATCH 266/364] * util/grub.d/30_os-prober.in: Support btrrfs + linux-prober extensions. + +--- + ChangeLog | 4 ++++ + util/grub.d/30_os-prober.in | 11 ++++++++++- + 2 files changed, 14 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index 2f2f7a3..954d85f 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,7 @@ ++2013-04-05 Fedora Ninjas ++ ++ * util/grub.d/30_os-prober.in: Support btrrfs linux-prober extensions. ++ + 2013-04-05 Vladimir Serbinenko + + Use GRUB_PROPERLY_ALIGNED_ARRAY in grub-core/disk/cryptodisk.c and +diff --git a/util/grub.d/30_os-prober.in b/util/grub.d/30_os-prober.in +index bf47dc3..e20d8b3 100644 +--- a/util/grub.d/30_os-prober.in ++++ b/util/grub.d/30_os-prober.in +@@ -112,6 +112,11 @@ for OS in ${OSPROBED} ; do + LONGNAME="`echo ${OS} | cut -d ':' -f 2 | tr '^' ' '`" + LABEL="`echo ${OS} | cut -d ':' -f 3 | tr '^' ' '`" + BOOT="`echo ${OS} | cut -d ':' -f 4`" ++ BTRFS="`echo ${OS} | cut -d ':' -f 5`" ++ if [ "x$BTRFS" = "xbtrfs" ]; then ++ BTRFSuuid="`echo ${OS} | cut -d ':' -f 6`" ++ BTRFSsubvol="`echo ${OS} | cut -d ':' -f 7`" ++ fi + + if [ -z "${LONGNAME}" ] ; then + LONGNAME="${LABEL}" +@@ -145,7 +150,11 @@ EOF + EOF + ;; + linux) +- LINUXPROBED="`linux-boot-prober ${DEVICE} 2> /dev/null | tr ' ' '^' | paste -s -d ' '`" ++ if [ "x$BTRFS" = "xbtrfs" ]; then ++ LINUXPROBED="`linux-boot-prober btrfs ${BTRFSuuid} ${BTRFSsubvol} 2> /dev/null | tr ' ' '^' | paste -s -d ' '`" ++ else ++ LINUXPROBED="`linux-boot-prober ${DEVICE} 2> /dev/null | tr ' ' '^' | paste -s -d ' '`" ++ fi + prepare_boot_cache= + boot_device_id= + is_first_entry=true +-- +1.8.1.4 + diff --git a/0267-util-grub-install_header-Use-PACKAGE-.mo-in-message-.patch b/0267-util-grub-install_header-Use-PACKAGE-.mo-in-message-.patch new file mode 100644 index 0000000..8a62c76 --- /dev/null +++ b/0267-util-grub-install_header-Use-PACKAGE-.mo-in-message-.patch @@ -0,0 +1,52 @@ +From ae1957bc0b8982ee73b60aa194f72bc538c60854 Mon Sep 17 00:00:00 2001 +From: Andrey Borzenkov +Date: Sat, 6 Apr 2013 20:14:29 +0200 +Subject: [PATCH 267/364] * util/grub-install_header: Use @PACKAGE@.mo + in message catalog name instead of hardcoding grub.mo. + +--- + ChangeLog | 5 +++++ + util/grub-install_header | 8 ++++---- + 2 files changed, 9 insertions(+), 4 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 954d85f..300ddd0 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,8 @@ ++2013-04-06 Andrey Borzenkov ++ ++ * util/grub-install_header: Use @PACKAGE@.mo in message catalog name ++ instead of hardcoding grub.mo. ++ + 2013-04-05 Fedora Ninjas + + * util/grub.d/30_os-prober.in: Support btrrfs linux-prober extensions. +diff --git a/util/grub-install_header b/util/grub-install_header +index 7c2c0a5..69aac46 100644 +--- a/util/grub-install_header ++++ b/util/grub-install_header +@@ -82,16 +82,16 @@ grub_install_files () { + fi + done + for dir in "${localedir}"/*; do +- if test -f "$dir/LC_MESSAGES/grub.mo" && ! test -f "${grub_install_files_target_directory}"/locale/"${dir##*/}.mo"; then +- cp -f "$dir/LC_MESSAGES/grub.mo" "${grub_install_files_target_directory}"/locale/"${dir##*/}.mo" ++ if test -f "$dir/LC_MESSAGES/@PACKAGE@.mo" && ! test -f "${grub_install_files_target_directory}"/locale/"${dir##*/}.mo"; then ++ cp -f "$dir/LC_MESSAGES/@PACKAGE@.mo" "${grub_install_files_target_directory}"/locale/"${dir##*/}.mo" + fi + done + else + for locale in $install_locales; do + if test -f "${grub_install_files_source_directory}"/po/$locale.mo; then + cp -f " "${grub_install_files_source_directory}"/po/$locale.mo" "${grub_install_files_target_directory}"/locale/$locale.mo +- elif test -f "${localedir}/$locale/LC_MESSAGES/grub.mo"; then +- cp -f "${localedir}/$locale/LC_MESSAGES/grub.mo" "${grub_install_files_target_directory}"/locale/$locale.mo ++ elif test -f "${localedir}/$locale/LC_MESSAGES/@PACKAGE@.mo"; then ++ cp -f "${localedir}/$locale/LC_MESSAGES/@PACKAGE@.mo" "${grub_install_files_target_directory}"/locale/$locale.mo + fi + done + fi +-- +1.8.1.4 + diff --git a/0268-conf-Makefile.extra-dist-EXTRA_DIST-Add.patch b/0268-conf-Makefile.extra-dist-EXTRA_DIST-Add.patch new file mode 100644 index 0000000..3c71e7f --- /dev/null +++ b/0268-conf-Makefile.extra-dist-EXTRA_DIST-Add.patch @@ -0,0 +1,47 @@ +From b970f640ef40de57c1d69ef7cbce96287d3a034f Mon Sep 17 00:00:00 2001 +From: Andrey Borzenkov +Date: Sat, 6 Apr 2013 20:49:02 +0200 +Subject: [PATCH 268/364] * conf/Makefile.extra-dist (EXTRA_DIST): Add + grub-core/lib/libgcrypt/src/gcrypt.h.in and util/import_gcrypth.sed. + +--- + ChangeLog | 5 +++++ + conf/Makefile.extra-dist | 2 ++ + 2 files changed, 7 insertions(+) + +diff --git a/ChangeLog b/ChangeLog +index 300ddd0..9163911 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,10 @@ + 2013-04-06 Andrey Borzenkov + ++ * conf/Makefile.extra-dist (EXTRA_DIST): Add ++ grub-core/lib/libgcrypt/src/gcrypt.h.in and util/import_gcrypth.sed. ++ ++2013-04-06 Andrey Borzenkov ++ + * util/grub-install_header: Use @PACKAGE@.mo in message catalog name + instead of hardcoding grub.mo. + +diff --git a/conf/Makefile.extra-dist b/conf/Makefile.extra-dist +index c862206..2e36500 100644 +--- a/conf/Makefile.extra-dist ++++ b/conf/Makefile.extra-dist +@@ -31,11 +31,13 @@ EXTRA_DIST += $(shell find $(top_srcdir)/include -name '*.h') + EXTRA_DIST += $(shell find $(top_srcdir)/grub-core/lib -name '*.h') + EXTRA_DIST += $(shell find $(top_srcdir)/grub-core/gnulib -name '*.h') + EXTRA_DIST += grub-core/efiemu/runtime/config.h ++EXTRA_DIST += grub-core/lib/libgcrypt/src/gcrypt.h.in + + EXTRA_DIST += grub-core/lib/LzmaDec.c + + EXTRA_DIST += BUGS + EXTRA_DIST += util/i386/efi/grub-dumpdevtree ++EXTRA_DIST += util/import_gcrypth.sed + + EXTRA_DIST += m4/gnulib-cache.m4 + EXTRA_DIST += m4/glibc2.m4 +-- +1.8.1.4 + diff --git a/0269-grub-core-normal-term.c-Few-more-fixes-for-menu-entr.patch b/0269-grub-core-normal-term.c-Few-more-fixes-for-menu-entr.patch new file mode 100644 index 0000000..9b37b19 --- /dev/null +++ b/0269-grub-core-normal-term.c-Few-more-fixes-for-menu-entr.patch @@ -0,0 +1,92 @@ +From ae9964bfa8ff7b27534cbf8ff40cdbbaa02c8d48 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sun, 7 Apr 2013 17:48:22 +0200 +Subject: [PATCH 269/364] * grub-core/normal/term.c: Few more fixes for + menu entry editor rendering. Reported by: Andrey Borzenkov + + +--- + ChangeLog | 6 ++++++ + grub-core/normal/term.c | 24 ++++++++++++++++-------- + 2 files changed, 22 insertions(+), 8 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 9163911..8b90e7a 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,9 @@ ++2013-04-07 Vladimir Serbinenko ++ ++ * grub-core/normal/term.c: Few more fixes for menu entry editor ++ rendering. ++ Reported by: Andrey Borzenkov ++ + 2013-04-06 Andrey Borzenkov + + * conf/Makefile.extra-dist (EXTRA_DIST): Add +diff --git a/grub-core/normal/term.c b/grub-core/normal/term.c +index f05184b..d73d29c 100644 +--- a/grub-core/normal/term.c ++++ b/grub-core/normal/term.c +@@ -746,9 +746,12 @@ print_ucs4_terminal (const grub_uint32_t * str, + putcode_real (*ptr2, term, fixed_tab); + } + +- sp = max_width - pos[last_position - str].x + 1; +- if (sp > 0) +- grub_print_spaces (term, sp); ++ if (contchar) ++ { ++ sp = max_width - pos[last_position - str].x + 1; ++ if (sp > 0) ++ grub_print_spaces (term, sp); ++ } + } + return dry_run ? lines : 0; + } +@@ -780,7 +783,8 @@ put_glyphs_terminal (const struct grub_unicode_glyph *visual, + grub_ssize_t visual_len, + int margin_left, int margin_right, + struct grub_term_output *term, +- struct term_state *state, int fixed_tab) ++ struct term_state *state, int fixed_tab, ++ grub_uint32_t contchar) + { + const struct grub_unicode_glyph *visual_ptr; + for (visual_ptr = visual; visual_ptr < visual + visual_len; visual_ptr++) +@@ -799,7 +803,11 @@ put_glyphs_terminal (const struct grub_unicode_glyph *visual, + return 1; + } + +- grub_print_spaces (term, margin_left); ++ if (!contchar) ++ grub_print_spaces (term, margin_left); ++ else ++ grub_term_gotoxy (term, margin_left, ++ grub_term_getxy (term) & 0xff); + } + grub_free (visual_ptr->combining); + } +@@ -839,7 +847,7 @@ print_backlog (struct grub_term_output *term, + ret = put_glyphs_terminal (state->backlog_glyphs, + state->backlog_len, + margin_left, margin_right, term, state, +- state->backlog_fixed_tab); ++ state->backlog_fixed_tab, 0); + if (!ret) + { + grub_free (state->free); +@@ -942,8 +950,8 @@ print_ucs4_real (const grub_uint32_t * str, + else + { + ret = put_glyphs_terminal (visual_show, visual_len_show, margin_left, +- contchar ? margin_right : 1, +- term, state, fixed_tab); ++ contchar ? 0 : margin_right, ++ term, state, fixed_tab, contchar); + + if (!ret) + grub_free (visual); +-- +1.8.1.4 + diff --git a/0270-grub-core-normal-term.c-Few-more-fixes-for-menu-entr.patch b/0270-grub-core-normal-term.c-Few-more-fixes-for-menu-entr.patch new file mode 100644 index 0000000..380b121 --- /dev/null +++ b/0270-grub-core-normal-term.c-Few-more-fixes-for-menu-entr.patch @@ -0,0 +1,122 @@ +From 4e8d4c0c9af6f05c4b7a9d64baaf846449624068 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Mon, 8 Apr 2013 14:35:26 +0200 +Subject: [PATCH 270/364] * grub-core/normal/term.c: Few more fixes for + menu entry editor rendering. Reported by: Andrey Borzenkov + + +--- + ChangeLog | 6 ++++++ + grub-core/normal/menu_entry.c | 11 ++++++++++- + grub-core/normal/term.c | 13 ++++++++++--- + include/grub/term.h | 8 -------- + 4 files changed, 26 insertions(+), 12 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 8b90e7a..0c97d42 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,9 @@ ++2013-04-08 Vladimir Serbinenko ++ ++ * grub-core/normal/term.c: Few more fixes for menu entry editor ++ rendering. ++ Reported by: Andrey Borzenkov ++ + 2013-04-07 Vladimir Serbinenko + + * grub-core/normal/term.c: Few more fixes for menu entry editor +diff --git a/grub-core/normal/menu_entry.c b/grub-core/normal/menu_entry.c +index 80f9464..e0407aa 100644 +--- a/grub-core/normal/menu_entry.c ++++ b/grub-core/normal/menu_entry.c +@@ -118,6 +118,15 @@ ensure_space (struct line *linep, int extra) + return 1; + } + ++/* The max column number of an entry. The last "-1" is for a ++ continuation marker. */ ++static inline int ++grub_term_entry_width (struct grub_term_output *term) ++{ ++ return grub_term_border_width (term) - GRUB_TERM_MARGIN * 2 - 2; ++} ++ ++ + /* Return the number of lines occupied by this line on the screen. */ + static int + get_logical_num_lines (struct line *linep, struct per_term_screen *term_screen) +@@ -150,7 +159,7 @@ print_empty_line (int y, struct per_term_screen *term_screen) + GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN + 1, + y + GRUB_TERM_FIRST_ENTRY_Y); + +- for (i = 0; i < grub_term_entry_width (term_screen->term); i++) ++ for (i = 0; i < grub_term_entry_width (term_screen->term) + 1; i++) + grub_putcode (' ', term_screen->term); + } + +diff --git a/grub-core/normal/term.c b/grub-core/normal/term.c +index d73d29c..f9620f6 100644 +--- a/grub-core/normal/term.c ++++ b/grub-core/normal/term.c +@@ -787,13 +787,17 @@ put_glyphs_terminal (const struct grub_unicode_glyph *visual, + grub_uint32_t contchar) + { + const struct grub_unicode_glyph *visual_ptr; ++ int since_last_nl = 1; + for (visual_ptr = visual; visual_ptr < visual + visual_len; visual_ptr++) + { +- if (visual_ptr->base == '\n') +- grub_print_spaces (term, margin_right); ++ if (visual_ptr->base == '\n' && contchar) ++ fill_margin (term, margin_right); ++ + putglyph (visual_ptr, term, fixed_tab); ++ since_last_nl++; + if (visual_ptr->base == '\n') + { ++ since_last_nl = 0; + if (state && ++state->num_lines + >= (grub_ssize_t) grub_term_height (term) - 2) + { +@@ -811,6 +815,9 @@ put_glyphs_terminal (const struct grub_unicode_glyph *visual, + } + grub_free (visual_ptr->combining); + } ++ if (contchar && since_last_nl) ++ fill_margin (term, margin_right); ++ + return 0; + } + +@@ -950,7 +957,7 @@ print_ucs4_real (const grub_uint32_t * str, + else + { + ret = put_glyphs_terminal (visual_show, visual_len_show, margin_left, +- contchar ? 0 : margin_right, ++ margin_right, + term, state, fixed_tab, contchar); + + if (!ret) +diff --git a/include/grub/term.h b/include/grub/term.h +index 655a5e3..565d14f 100644 +--- a/include/grub/term.h ++++ b/include/grub/term.h +@@ -347,14 +347,6 @@ grub_term_border_width (struct grub_term_output *term) + return grub_term_width (term) - GRUB_TERM_MARGIN * 2; + } + +-/* The max column number of an entry. The last "-1" is for a +- continuation marker. */ +-static inline int +-grub_term_entry_width (struct grub_term_output *term) +-{ +- return grub_term_border_width (term) - GRUB_TERM_MARGIN * 2 - 1; +-} +- + static inline grub_uint16_t + grub_term_getxy (struct grub_term_output *term) + { +-- +1.8.1.4 + diff --git a/0271-docs-grub-dev.texi-Move-itemize-after-subsection-to-.patch b/0271-docs-grub-dev.texi-Move-itemize-after-subsection-to-.patch new file mode 100644 index 0000000..46dd5b3 --- /dev/null +++ b/0271-docs-grub-dev.texi-Move-itemize-after-subsection-to-.patch @@ -0,0 +1,41 @@ +From 8f7bea9a0975542cc54653d67bf090b4ed63064a Mon Sep 17 00:00:00 2001 +From: Bryan Hundven +Date: Mon, 8 Apr 2013 15:23:07 +0200 +Subject: [PATCH 271/364] * docs/grub-dev.texi: Move @itemize after + @subsection to satisfy texinfo-5.1. + +--- + ChangeLog | 5 +++++ + docs/grub-dev.texi | 2 +- + 2 files changed, 6 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index 0c97d42..3a241c0 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,8 @@ ++2013-04-08 Bryan Hundven ++ ++ * docs/grub-dev.texi: Move @itemize after @subsection to satisfy ++ texinfo-5.1. ++ + 2013-04-08 Vladimir Serbinenko + + * grub-core/normal/term.c: Few more fixes for menu entry editor +diff --git a/docs/grub-dev.texi b/docs/grub-dev.texi +index a4a3820..f74c966 100644 +--- a/docs/grub-dev.texi ++++ b/docs/grub-dev.texi +@@ -1394,8 +1394,8 @@ grub_video_blit_glyph (&glyph, color, 0, 0); + + @node Bitmap API + @section Bitmap API +-@itemize + @subsection grub_video_bitmap_create ++@itemize + @item Prototype: + @example + 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) +-- +1.8.1.4 + diff --git a/0272-grub-core-term-i386-pc-console.c-Fix-cursor-moving-a.patch b/0272-grub-core-term-i386-pc-console.c-Fix-cursor-moving-a.patch new file mode 100644 index 0000000..7c9afd7 --- /dev/null +++ b/0272-grub-core-term-i386-pc-console.c-Fix-cursor-moving-a.patch @@ -0,0 +1,82 @@ +From 105030380129f8c17035ac88980eaa4c151ee521 Mon Sep 17 00:00:00 2001 +From: Andrey Borzenkov +Date: Mon, 8 Apr 2013 19:51:33 +0200 +Subject: [PATCH 272/364] * grub-core/term/i386/pc/console.c: Fix cursor + moving algorithm. + +--- + ChangeLog | 4 ++++ + grub-core/term/i386/pc/console.c | 24 +++++++++--------------- + 2 files changed, 13 insertions(+), 15 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 3a241c0..9e08bea 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,7 @@ ++2013-04-08 Andrey Borzenkov ++ ++ * grub-core/term/i386/pc/console.c: Fix cursor moving algorithm. ++ + 2013-04-08 Bryan Hundven + + * docs/grub-dev.texi: Move @itemize after @subsection to satisfy +diff --git a/grub-core/term/i386/pc/console.c b/grub-core/term/i386/pc/console.c +index ee6650b..358611a 100644 +--- a/grub-core/term/i386/pc/console.c ++++ b/grub-core/term/i386/pc/console.c +@@ -86,13 +86,9 @@ grub_console_gotoxy (struct grub_term_output *term __attribute__ ((unused)), + * Put the character C on the console. Because GRUB wants to write a + * character with an attribute, this implementation is a bit tricky. + * If C is a control character (CR, LF, BEL, BS), use INT 10, AH = 0Eh +- * (TELETYPE OUTPUT). Otherwise, save the original position, put a space, +- * save the current position, restore the original position, write the +- * character and the attribute, and restore the current position. +- * +- * The reason why this is so complicated is that there is no easy way to +- * get the height of the screen, and the TELETYPE OUTPUT BIOS call doesn't +- * support setting a background attribute. ++ * (TELETYPE OUTPUT). Otherwise, use INT 10, AH = 9 to write character ++ * with attributes and advance cursor. If we are on the last column, ++ * let BIOS to wrap line correctly. + */ + static void + grub_console_putchar_real (grub_uint8_t c) +@@ -112,19 +108,18 @@ grub_console_putchar_real (grub_uint8_t c) + /* get the current position */ + pos = grub_console_getxy (NULL); + ++ /* write the character with the attribute */ ++ int10_9 (c, 1); ++ + /* check the column with the width */ + if ((pos & 0xff00) >= (79 << 8)) + { + grub_console_putchar_real (0x0d); + grub_console_putchar_real (0x0a); +- /* get the current position */ +- pos = grub_console_getxy (NULL); + } ++ else ++ grub_console_gotoxy (NULL, ((pos & 0xff00) >> 8) + 1, (pos & 0xff)); + +- /* write the character with the attribute */ +- int10_9 (c, 1); +- +- grub_console_gotoxy (NULL, ((pos & 0xff00) >> 8) + 1, (pos & 0xff)); + } + + static void +@@ -255,8 +250,7 @@ grub_console_getkeystatus (struct grub_term_input *term __attribute__ ((unused)) + static grub_uint16_t + grub_console_getwh (struct grub_term_output *term __attribute__ ((unused))) + { +- /* Due to current cursor moving algorithm we lost the last column. */ +- return (79 << 8) | 25; ++ return (80 << 8) | 25; + } + + static void +-- +1.8.1.4 + diff --git a/0273-grub-core-Makefile.core.def-Add-kern-elfXX.c-to-elf-.patch b/0273-grub-core-Makefile.core.def-Add-kern-elfXX.c-to-elf-.patch new file mode 100644 index 0000000..04fb539 --- /dev/null +++ b/0273-grub-core-Makefile.core.def-Add-kern-elfXX.c-to-elf-.patch @@ -0,0 +1,42 @@ +From 0dd4469b79f41c950f59eeb1f7899bb3f2e246fe Mon Sep 17 00:00:00 2001 +From: Andrey Borzenkov +Date: Mon, 8 Apr 2013 19:57:56 +0200 +Subject: [PATCH 273/364] * grub-core/Makefile.core.def: Add + kern/elfXX.c to elf module as extra_dist. + +--- + ChangeLog | 5 +++++ + grub-core/Makefile.core.def | 2 ++ + 2 files changed, 7 insertions(+) + +diff --git a/ChangeLog b/ChangeLog +index 9e08bea..083d86a 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,10 @@ + 2013-04-08 Andrey Borzenkov + ++ * grub-core/Makefile.core.def: Add kern/elfXX.c to elf module ++ as extra_dist. ++ ++2013-04-08 Andrey Borzenkov ++ + * grub-core/term/i386/pc/console.c: Fix cursor moving algorithm. + + 2013-04-08 Bryan Hundven +diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def +index 4b4c024..fece882 100644 +--- a/grub-core/Makefile.core.def ++++ b/grub-core/Makefile.core.def +@@ -1316,6 +1316,8 @@ module = { + module = { + name = elf; + common = kern/elf.c; ++ ++ extra_dist = kern/elfXX.c; + }; + + module = { +-- +1.8.1.4 + diff --git a/0274-Fix-ia64-efi-image-generation-on-big-endian-machines.patch b/0274-Fix-ia64-efi-image-generation-on-big-endian-machines.patch new file mode 100644 index 0000000..876787c --- /dev/null +++ b/0274-Fix-ia64-efi-image-generation-on-big-endian-machines.patch @@ -0,0 +1,784 @@ +From e5668a21f2e71785573ab072471c9254fa6e73b0 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Tue, 9 Apr 2013 19:19:19 +0200 +Subject: [PATCH 274/364] Fix ia64-efi image generation on big-endian + machines. Deduplicate some code while on it. Reported by: Leif Lindholm. + +--- + ChangeLog | 6 ++ + grub-core/kern/ia64/dl.c | 135 ++---------------------------- + grub-core/kern/ia64/dl_helper.c | 159 +++++++++++++++++++++++++++++++++-- + include/grub/ia64/reloc.h | 42 ++++++++++ + util/grub-mkimage.c | 9 +- + util/grub-mkimagexx.c | 178 +++++++--------------------------------- + 6 files changed, 243 insertions(+), 286 deletions(-) + create mode 100644 include/grub/ia64/reloc.h + +diff --git a/ChangeLog b/ChangeLog +index 083d86a..e45ca35 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,9 @@ ++2013-04-08 Vladimir Serbinenko ++ ++ Fix ia64-efi image generation on big-endian machines. Deduplicate ++ some code while on it. ++ Reported by: Leif Lindholm. ++ + 2013-04-08 Andrey Borzenkov + + * grub-core/Makefile.core.def: Add kern/elfXX.c to elf module +diff --git a/grub-core/kern/ia64/dl.c b/grub-core/kern/ia64/dl.c +index 7c22b0b..957ceaa 100644 +--- a/grub-core/kern/ia64/dl.c ++++ b/grub-core/kern/ia64/dl.c +@@ -23,6 +23,9 @@ + #include + #include + #include ++#include ++ ++#define MASK19 ((1 << 19) - 1) + + /* Check if EHDR is a valid ELF header. */ + grub_err_t +@@ -41,126 +44,6 @@ grub_arch_dl_check_header (void *ehdr) + + #pragma GCC diagnostic ignored "-Wcast-align" + +-#define MASK20 ((1 << 20) - 1) +-#define MASK19 ((1 << 19) - 1) +- +-struct unaligned_uint32 +-{ +- grub_uint32_t val; +-} __attribute__ ((packed)); +- +-static void +-add_value_to_slot_20b (grub_addr_t addr, grub_uint32_t value) +-{ +- struct unaligned_uint32 *p; +- switch (addr & 3) +- { +- case 0: +- p = (struct unaligned_uint32 *) ((addr & ~3ULL) + 2); +- p->val = ((((((p->val >> 2) & MASK20) + value) & MASK20) << 2) +- | (p->val & ~(MASK20 << 2))); +- break; +- case 1: +- p = (struct unaligned_uint32 *) ((grub_uint8_t *) (addr & ~3ULL) + 7); +- p->val = ((((((p->val >> 3) & MASK20) + value) & MASK20) << 3) +- | (p->val & ~(MASK20 << 3))); +- break; +- case 2: +- p = (struct unaligned_uint32 *) ((grub_uint8_t *) (addr & ~3ULL) + 12); +- p->val = ((((((p->val >> 4) & MASK20) + value) & MASK20) << 4) +- | (p->val & ~(MASK20 << 4))); +- break; +- } +-} +- +-#define MASKF21 ( ((1 << 23) - 1) & ~((1 << 7) | (1 << 8)) ) +- +-static grub_uint32_t +-add_value_to_slot_21_real (grub_uint32_t a, grub_uint32_t value) +-{ +- grub_uint32_t high, mid, low, c; +- low = (a & 0x00007f); +- mid = (a & 0x7fc000) >> 7; +- high = (a & 0x003e00) << 7; +- c = (low | mid | high) + value; +- return (c & 0x7f) | ((c << 7) & 0x7fc000) | ((c >> 7) & 0x0003e00); //0x003e00 +-} +- +-static void +-add_value_to_slot_21 (grub_addr_t addr, grub_uint32_t value) +-{ +- struct unaligned_uint32 *p; +- switch (addr & 3) +- { +- case 0: +- p = (struct unaligned_uint32 *) ((addr & ~3ULL) + 2); +- p->val = ((add_value_to_slot_21_real (((p->val >> 2) & MASKF21), value) & MASKF21) << 2) | (p->val & ~(MASKF21 << 2)); +- break; +- case 1: +- p = (struct unaligned_uint32 *) ((grub_uint8_t *) (addr & ~3ULL) + 7); +- p->val = ((add_value_to_slot_21_real (((p->val >> 3) & MASKF21), value) & MASKF21) << 3) | (p->val & ~(MASKF21 << 3)); +- break; +- case 2: +- p = (struct unaligned_uint32 *) ((grub_uint8_t *) (addr & ~3ULL) + 12); +- p->val = ((add_value_to_slot_21_real (((p->val >> 4) & MASKF21), value) & MASKF21) << 4) | (p->val & ~(MASKF21 << 4)); +- break; +- } +-} +- +-static const grub_uint8_t nopm[5] = +- { +- /* [MLX] nop.m 0x0 */ +- 0x05, 0x00, 0x00, 0x00, 0x01 +- }; +- +-static const grub_uint8_t jump[0x20] = +- { +- /* ld8 r16=[r15],8 */ +- 0x02, 0x80, 0x20, 0x1e, 0x18, 0x14, +- /* mov r14=r1;; */ +- 0xe0, 0x00, 0x04, 0x00, 0x42, 0x00, +- /* nop.i 0x0 */ +- 0x00, 0x00, 0x04, 0x00, +- /* ld8 r1=[r15] */ +- 0x11, 0x08, 0x00, 0x1e, 0x18, 0x10, +- /* mov b6=r16 */ +- 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, +- /* br.few b6;; */ +- 0x60, 0x00, 0x80, 0x00 +- }; +- +-struct ia64_trampoline +-{ +- /* nop.m */ +- grub_uint8_t nop[5]; +- /* movl r15 = addr*/ +- grub_uint8_t addr_hi[6]; +- grub_uint8_t e0; +- grub_uint8_t addr_lo[4]; +- grub_uint8_t jump[0x20]; +-}; +- +-static void +-make_trampoline (struct ia64_trampoline *tr, grub_uint64_t addr) +-{ +- COMPILE_TIME_ASSERT (sizeof (struct ia64_trampoline) +- == GRUB_IA64_DL_TRAMP_SIZE); +- grub_memcpy (tr->nop, nopm, sizeof (tr->nop)); +- tr->addr_hi[0] = ((addr & 0xc00000) >> 16); +- tr->addr_hi[1] = (addr >> 24) & 0xff; +- tr->addr_hi[2] = (addr >> 32) & 0xff; +- tr->addr_hi[3] = (addr >> 40) & 0xff; +- tr->addr_hi[4] = (addr >> 48) & 0xff; +- tr->addr_hi[5] = (addr >> 56) & 0xff; +- tr->e0 = 0xe0; +- tr->addr_lo[0] = ((addr & 0x000f) << 4) | 0x01; +- tr->addr_lo[1] = (((addr & 0x0070) >> 4) | ((addr & 0x070000) >> 11) +- | ((addr & 0x200000) >> 17)); +- tr->addr_lo[2] = ((addr & 0x1f80) >> 5) | ((addr & 0x180000) >> 19); +- tr->addr_lo[3] = ((addr & 0xe000) >> 13) | 0x60; +- grub_memcpy (tr->jump, jump, sizeof (tr->jump)); +-} +- + /* Relocate symbols. */ + grub_err_t + grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) +@@ -170,7 +53,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) + Elf_Word entsize; + unsigned i; + grub_uint64_t *gp, *gpptr; +- struct ia64_trampoline *tr; ++ struct grub_ia64_trampoline *tr; + + gp = (grub_uint64_t *) mod->base; + gpptr = (grub_uint64_t *) mod->got; +@@ -230,13 +113,13 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) + case R_IA64_PCREL21B: + { + grub_uint64_t noff; +- make_trampoline (tr, value); ++ grub_ia64_make_trampoline (tr, value); + noff = ((char *) tr - (char *) (addr & ~3)) >> 4; +- tr++; ++ tr = (struct grub_ia64_trampoline *) ((char *) tr + GRUB_IA64_DL_TRAMP_SIZE); + if (noff & ~MASK19) + return grub_error (GRUB_ERR_BAD_OS, + "trampoline offset too big (%lx)", noff); +- add_value_to_slot_20b (addr, noff); ++ grub_ia64_add_value_to_slot_20b (addr, noff); + } + break; + case R_IA64_SEGREL64LSB: +@@ -250,7 +133,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) + *(grub_uint64_t *) addr += value - addr; + break; + case R_IA64_GPREL22: +- add_value_to_slot_21 (addr, value - (grub_addr_t) gp); ++ grub_ia64_add_value_to_slot_21 (addr, value - (grub_addr_t) gp); + break; + + case R_IA64_LTOFF22X: +@@ -259,7 +142,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) + value = *(grub_uint64_t *) sym->st_value + rel->r_addend; + case R_IA64_LTOFF_FPTR22: + *gpptr = value; +- add_value_to_slot_21 (addr, (grub_addr_t) gpptr - (grub_addr_t) gp); ++ grub_ia64_add_value_to_slot_21 (addr, (grub_addr_t) gpptr - (grub_addr_t) gp); + gpptr++; + break; + +diff --git a/grub-core/kern/ia64/dl_helper.c b/grub-core/kern/ia64/dl_helper.c +index 9394e32..e2209ca 100644 +--- a/grub-core/kern/ia64/dl_helper.c ++++ b/grub-core/kern/ia64/dl_helper.c +@@ -22,9 +22,154 @@ + #include + #include + #include ++#include ++#include + + #pragma GCC diagnostic ignored "-Wcast-align" + ++#define MASK20 ((1 << 20) - 1) ++#define MASK3 (~(grub_addr_t) 3) ++ ++void ++grub_ia64_add_value_to_slot_20b (grub_addr_t addr, grub_uint32_t value) ++{ ++ grub_uint32_t val; ++ switch (addr & 3) ++ { ++ case 0: ++ val = grub_le_to_cpu32 (grub_get_unaligned32 (((grub_uint8_t *) ++ (addr & MASK3) + 2))); ++ val = (((((val & MASK20) + value) & MASK20) << 2) ++ | (val & ~(MASK20 << 2))); ++ grub_set_unaligned32 (((grub_uint8_t *) (addr & MASK3) + 2), ++ grub_cpu_to_le32 (val)); ++ break; ++ case 1: ++ val = grub_le_to_cpu32 (grub_get_unaligned32 (((grub_uint8_t *) ++ (addr & MASK3) + 7))); ++ val = ((((((val >> 3) & MASK20) + value) & MASK20) << 3) ++ | (val & ~(MASK20 << 3))); ++ grub_set_unaligned32 (((grub_uint8_t *) (addr & MASK3) + 7), ++ grub_cpu_to_le32 (val)); ++ break; ++ case 2: ++ val = grub_le_to_cpu32 (grub_get_unaligned32 (((grub_uint8_t *) ++ (addr & MASK3) + 12))); ++ val = ((((((val >> 4) & MASK20) + value) & MASK20) << 4) ++ | (val & ~(MASK20 << 4))); ++ grub_set_unaligned32 (((grub_uint8_t *) (addr & MASK3) + 12), ++ grub_cpu_to_le32 (val)); ++ break; ++ } ++} ++ ++#define MASKF21 ( ((1 << 23) - 1) & ~((1 << 7) | (1 << 8)) ) ++ ++static grub_uint32_t ++add_value_to_slot_21_real (grub_uint32_t a, grub_uint32_t value) ++{ ++ grub_uint32_t high, mid, low, c; ++ low = (a & 0x00007f); ++ mid = (a & 0x7fc000) >> 7; ++ high = (a & 0x003e00) << 7; ++ c = (low | mid | high) + value; ++ return (c & 0x7f) | ((c << 7) & 0x7fc000) | ((c >> 7) & 0x0003e00); //0x003e00 ++} ++ ++void ++grub_ia64_add_value_to_slot_21 (grub_addr_t addr, grub_uint32_t value) ++{ ++ grub_uint32_t val; ++ switch (addr & 3) ++ { ++ case 0: ++ val = grub_le_to_cpu32 (grub_get_unaligned32 (((grub_uint8_t *) ++ (addr & MASK3) + 2))); ++ val = ((add_value_to_slot_21_real (((val >> 2) & MASKF21), value) ++ & MASKF21) << 2) | (val & ~(MASKF21 << 2)); ++ grub_set_unaligned32 (((grub_uint8_t *) (addr & MASK3) + 2), ++ grub_cpu_to_le32 (val)); ++ break; ++ case 1: ++ val = grub_le_to_cpu32 (grub_get_unaligned32 (((grub_uint8_t *) ++ (addr & MASK3) + 7))); ++ val = ((add_value_to_slot_21_real (((val >> 3) & MASKF21), value) ++ & MASKF21) << 3) | (val & ~(MASKF21 << 3)); ++ grub_set_unaligned32 (((grub_uint8_t *) (addr & MASK3) + 7), ++ grub_cpu_to_le32 (val)); ++ break; ++ case 2: ++ val = grub_le_to_cpu32 (grub_get_unaligned32 (((grub_uint8_t *) ++ (addr & MASK3) + 12))); ++ val = ((add_value_to_slot_21_real (((val >> 4) & MASKF21), value) ++ & MASKF21) << 4) | (val & ~(MASKF21 << 4)); ++ grub_set_unaligned32 (((grub_uint8_t *) (addr & MASK3) + 12), ++ grub_cpu_to_le32 (val)); ++ break; ++ } ++} ++ ++static const grub_uint8_t nopm[5] = ++ { ++ /* [MLX] nop.m 0x0 */ ++ 0x05, 0x00, 0x00, 0x00, 0x01 ++ }; ++ ++#ifdef GRUB_UTIL ++static grub_uint8_t jump[0x20] = ++ { ++ /* [MMI] add r15=r15,r1;; */ ++ 0x0b, 0x78, 0x3c, 0x02, 0x00, 0x20, ++ /* ld8 r16=[r15],8 */ ++ 0x00, 0x41, 0x3c, 0x30, 0x28, 0xc0, ++ /* mov r14=r1;; */ ++ 0x01, 0x08, 0x00, 0x84, ++ /* [MIB] ld8 r1=[r15] */ ++ 0x11, 0x08, 0x00, 0x1e, 0x18, 0x10, ++ /* mov b6=r16 */ ++ 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, ++ /* br.few b6;; */ ++ 0x60, 0x00, 0x80, 0x00 ++ }; ++#else ++static const grub_uint8_t jump[0x20] = ++ { ++ /* ld8 r16=[r15],8 */ ++ 0x02, 0x80, 0x20, 0x1e, 0x18, 0x14, ++ /* mov r14=r1;; */ ++ 0xe0, 0x00, 0x04, 0x00, 0x42, 0x00, ++ /* nop.i 0x0 */ ++ 0x00, 0x00, 0x04, 0x00, ++ /* ld8 r1=[r15] */ ++ 0x11, 0x08, 0x00, 0x1e, 0x18, 0x10, ++ /* mov b6=r16 */ ++ 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, ++ /* br.few b6;; */ ++ 0x60, 0x00, 0x80, 0x00 ++ }; ++#endif ++ ++void ++grub_ia64_make_trampoline (struct grub_ia64_trampoline *tr, grub_uint64_t addr) ++{ ++ COMPILE_TIME_ASSERT (sizeof (struct grub_ia64_trampoline) ++ == GRUB_IA64_DL_TRAMP_SIZE); ++ grub_memcpy (tr->nop, nopm, sizeof (tr->nop)); ++ tr->addr_hi[0] = ((addr & 0xc00000) >> 16); ++ tr->addr_hi[1] = (addr >> 24) & 0xff; ++ tr->addr_hi[2] = (addr >> 32) & 0xff; ++ tr->addr_hi[3] = (addr >> 40) & 0xff; ++ tr->addr_hi[4] = (addr >> 48) & 0xff; ++ tr->addr_hi[5] = (addr >> 56) & 0xff; ++ tr->e0 = 0xe0; ++ tr->addr_lo[0] = ((addr & 0x000f) << 4) | 0x01; ++ tr->addr_lo[1] = (((addr & 0x0070) >> 4) | ((addr & 0x070000) >> 11) ++ | ((addr & 0x200000) >> 17)); ++ tr->addr_lo[2] = ((addr & 0x1f80) >> 5) | ((addr & 0x180000) >> 19); ++ tr->addr_lo[3] = ((addr & 0xe000) >> 13) | 0x60; ++ grub_memcpy (tr->jump, jump, sizeof (tr->jump)); ++} ++ + void + grub_ia64_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp, + grub_size_t *got) +@@ -35,26 +180,26 @@ grub_ia64_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp, + unsigned i; + + /* Find a symbol table. */ +- for (i = 0, s = (Elf64_Shdr *) ((char *) e + grub_le_to_cpu32 (e->e_shoff)); ++ for (i = 0, s = (Elf64_Shdr *) ((char *) e + grub_le_to_cpu64 (e->e_shoff)); + i < grub_le_to_cpu16 (e->e_shnum); + i++, s = (Elf64_Shdr *) ((char *) s + grub_le_to_cpu16 (e->e_shentsize))) +- if (grub_le_to_cpu32 (s->sh_type) == SHT_SYMTAB) ++ if (s->sh_type == grub_cpu_to_le32_compile_time (SHT_SYMTAB)) + break; + + if (i == grub_le_to_cpu16 (e->e_shnum)) + return; + +- for (i = 0, s = (Elf64_Shdr *) ((char *) e + grub_le_to_cpu32 (e->e_shoff)); ++ for (i = 0, s = (Elf64_Shdr *) ((char *) e + grub_le_to_cpu64 (e->e_shoff)); + i < grub_le_to_cpu16 (e->e_shnum); + i++, s = (Elf64_Shdr *) ((char *) s + grub_le_to_cpu16 (e->e_shentsize))) +- if (grub_le_to_cpu32 (s->sh_type) == SHT_RELA) ++ if (s->sh_type == grub_cpu_to_le32_compile_time (SHT_RELA)) + { + Elf64_Rela *rel, *max; + +- for (rel = (Elf64_Rela *) ((char *) e + grub_le_to_cpu32 (s->sh_offset)), +- max = rel + grub_le_to_cpu32 (s->sh_size) / grub_le_to_cpu16 (s->sh_entsize); ++ for (rel = (Elf64_Rela *) ((char *) e + grub_le_to_cpu64 (s->sh_offset)), ++ max = rel + grub_le_to_cpu64 (s->sh_size) / grub_le_to_cpu64 (s->sh_entsize); + rel < max; rel++) +- switch (ELF64_R_TYPE (grub_le_to_cpu32 (rel->r_info))) ++ switch (ELF64_R_TYPE (grub_le_to_cpu64 (rel->r_info))) + { + case R_IA64_PCREL21B: + cntt++; +diff --git a/include/grub/ia64/reloc.h b/include/grub/ia64/reloc.h +new file mode 100644 +index 0000000..4c02ab2 +--- /dev/null ++++ b/include/grub/ia64/reloc.h +@@ -0,0 +1,42 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2013 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_IA64_RELOC_H ++#define GRUB_IA64_RELOC_H 1 ++ ++struct grub_ia64_trampoline; ++ ++void ++grub_ia64_add_value_to_slot_20b (grub_addr_t addr, grub_uint32_t value); ++void ++grub_ia64_add_value_to_slot_21 (grub_addr_t addr, grub_uint32_t value); ++void ++grub_ia64_make_trampoline (struct grub_ia64_trampoline *tr, grub_uint64_t addr); ++ ++struct grub_ia64_trampoline ++{ ++ /* nop.m */ ++ grub_uint8_t nop[5]; ++ /* movl r15 = addr*/ ++ grub_uint8_t addr_hi[6]; ++ grub_uint8_t e0; ++ grub_uint8_t addr_lo[4]; ++ grub_uint8_t jump[0x20]; ++}; ++ ++#endif +diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c +index ecea5d4..dce2c29 100644 +--- a/util/grub-mkimage.c ++++ b/util/grub-mkimage.c +@@ -40,6 +40,7 @@ + #include + #include + #include ++#include + + #define _GNU_SOURCE 1 + #include +@@ -1201,10 +1202,10 @@ generate_image (const char *dir, const char *prefix, + 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->stack_reserve_size = grub_host_to_target64 (0x10000); ++ o->stack_commit_size = grub_host_to_target64 (0x10000); ++ o->heap_reserve_size = grub_host_to_target64 (0x10000); ++ o->heap_commit_size = grub_host_to_target64 (0x10000); + + o->num_data_directories + = grub_host_to_target32 (GRUB_PE32_NUM_DATA_DIRECTORIES); +diff --git a/util/grub-mkimagexx.c b/util/grub-mkimagexx.c +index 476d05e..b6b263d 100644 +--- a/util/grub-mkimagexx.c ++++ b/util/grub-mkimagexx.c +@@ -117,7 +117,7 @@ SUFFIX (relocate_symbols) (Elf_Ehdr *e, Elf_Shdr *sections, + if (image_target->elf_target == EM_IA_64 && ELF_ST_TYPE (sym->st_info) + == STT_FUNC) + { +- *jptr = sym->st_value; ++ *jptr = grub_host_to_target64 (sym->st_value); + sym->st_value = (char *) jptr - (char *) jumpers + jumpers_addr; + jptr++; + *jptr = 0; +@@ -143,8 +143,8 @@ SUFFIX (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)); ++ + grub_target_to_host (s->sh_offset) ++ + i * grub_target_to_host (s->sh_entsize)); + return sym->st_value; + } + +@@ -153,7 +153,7 @@ 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); ++ return (Elf_Addr *) ((char *) e + grub_target_to_host (s->sh_offset) + offset); + } + + #ifdef MKIMAGE_ELF64 +@@ -182,128 +182,6 @@ SUFFIX (count_funcs) (Elf_Ehdr *e, Elf_Shdr *symtab_section, + } + #endif + +-#ifdef MKIMAGE_ELF64 +-struct unaligned_uint32 +-{ +- grub_uint32_t val; +-} __attribute__ ((packed)); +- +-#define MASK20 ((1 << 20) - 1) +-#define MASK19 ((1 << 19) - 1) +-#define MASK3 (~(grub_addr_t) 3) +- +-static void +-add_value_to_slot_20b (grub_addr_t addr, grub_uint32_t value) +-{ +- struct unaligned_uint32 *p; +- switch (addr & 3) +- { +- case 0: +- p = (struct unaligned_uint32 *) ((addr & MASK3) + 2); +- p->val = ((((((p->val >> 2) & MASK20) + value) & MASK20) << 2) +- | (p->val & ~(MASK20 << 2))); +- break; +- case 1: +- p = (struct unaligned_uint32 *) ((grub_uint8_t *) (addr & MASK3) + 7); +- p->val = ((((((p->val >> 3) & MASK20) + value) & MASK20) << 3) +- | (p->val & ~(MASK20 << 3))); +- break; +- case 2: +- p = (struct unaligned_uint32 *) ((grub_uint8_t *) (addr & MASK3) + 12); +- p->val = ((((((p->val >> 4) & MASK20) + value) & MASK20) << 4) +- | (p->val & ~(MASK20 << 4))); +- break; +- } +-} +- +-#define MASKF21 ( ((1 << 23) - 1) & ~((1 << 7) | (1 << 8)) ) +- +-static grub_uint32_t +-add_value_to_slot_21_real (grub_uint32_t a, grub_uint32_t value) +-{ +- grub_uint32_t high, mid, low, c; +- low = (a & 0x00007f); +- mid = (a & 0x7fc000) >> 7; +- high = (a & 0x003e00) << 7; +- c = (low | mid | high) + value; +- return (c & 0x7f) | ((c << 7) & 0x7fc000) | ((c >> 7) & 0x0003e00); //0x003e00 +-} +- +-static void +-add_value_to_slot_21 (grub_addr_t addr, grub_uint32_t value) +-{ +- struct unaligned_uint32 *p; +- switch (addr & 3) +- { +- case 0: +- p = (struct unaligned_uint32 *) ((addr & MASK3) + 2); +- p->val = ((add_value_to_slot_21_real (((p->val >> 2) & MASKF21), value) & MASKF21) << 2) | (p->val & ~(MASKF21 << 2)); +- break; +- case 1: +- p = (struct unaligned_uint32 *) ((grub_uint8_t *) (addr & MASK3) + 7); +- p->val = ((add_value_to_slot_21_real (((p->val >> 3) & MASKF21), value) & MASKF21) << 3) | (p->val & ~(MASKF21 << 3)); +- break; +- case 2: +- p = (struct unaligned_uint32 *) ((grub_uint8_t *) (addr & MASK3) + 12); +- p->val = ((add_value_to_slot_21_real (((p->val >> 4) & MASKF21), value) & MASKF21) << 4) | (p->val & ~(MASKF21 << 4)); +- break; +- } +-} +- +- +-struct ia64_kernel_trampoline +-{ +- /* nop.m */ +- grub_uint8_t nop[5]; +- /* movl r15 = addr*/ +- grub_uint8_t addr_hi[6]; +- grub_uint8_t e0; +- grub_uint8_t addr_lo[4]; +- grub_uint8_t jump[0x20]; +-}; +- +-static grub_uint8_t nopm[5] = +- { +- /* [MLX] nop.m 0x0 */ +- 0x05, 0x00, 0x00, 0x00, 0x01 +- }; +- +-static grub_uint8_t jump[0x20] = +- { +- /* [MMI] add r15=r15,r1;; */ +- 0x0b, 0x78, 0x3c, 0x02, 0x00, 0x20, +- /* ld8 r16=[r15],8 */ +- 0x00, 0x41, 0x3c, 0x30, 0x28, 0xc0, +- /* mov r14=r1;; */ +- 0x01, 0x08, 0x00, 0x84, +- /* [MIB] ld8 r1=[r15] */ +- 0x11, 0x08, 0x00, 0x1e, 0x18, 0x10, +- /* mov b6=r16 */ +- 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, +- /* br.few b6;; */ +- 0x60, 0x00, 0x80, 0x00 +- }; +- +-static void +-make_trampoline (struct ia64_kernel_trampoline *tr, grub_uint64_t addr) +-{ +- grub_memcpy (tr->nop, nopm, sizeof (tr->nop)); +- tr->addr_hi[0] = ((addr & 0xc00000) >> 16); +- tr->addr_hi[1] = (addr >> 24) & 0xff; +- tr->addr_hi[2] = (addr >> 32) & 0xff; +- tr->addr_hi[3] = (addr >> 40) & 0xff; +- tr->addr_hi[4] = (addr >> 48) & 0xff; +- tr->addr_hi[5] = (addr >> 56) & 0xff; +- tr->e0 = 0xe0; +- tr->addr_lo[0] = ((addr & 0x000f) << 4) | 0x01; +- tr->addr_lo[1] = (((addr & 0x0070) >> 4) | ((addr & 0x070000) >> 11) +- | ((addr & 0x200000) >> 17)); +- tr->addr_lo[2] = ((addr & 0x1f80) >> 5) | ((addr & 0x180000) >> 19); +- tr->addr_lo[3] = ((addr & 0xe000) >> 13) | 0x60; +- grub_memcpy (tr->jump, jump, sizeof (tr->jump)); +-} +-#endif +- + /* 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 +@@ -320,8 +198,9 @@ SUFFIX (relocate_addresses) (Elf_Ehdr *e, Elf_Shdr *sections, + Elf_Half i; + Elf_Shdr *s; + #ifdef MKIMAGE_ELF64 +- struct ia64_kernel_trampoline *tr = (void *) (pe_target + tramp_off); ++ struct grub_ia64_trampoline *tr = (void *) (pe_target + tramp_off); + grub_uint64_t *gpptr = (void *) (pe_target + got_off); ++#define MASK19 ((1 << 19) - 1) + #endif + + for (i = 0, s = sections; +@@ -352,9 +231,9 @@ SUFFIX (relocate_addresses) (Elf_Ehdr *e, Elf_Shdr *sections, + 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); ++ rtab_size = grub_target_to_host (s->sh_size); ++ r_size = grub_target_to_host (s->sh_entsize); ++ rtab_offset = grub_target_to_host (s->sh_offset); + num_rs = rtab_size / r_size; + + for (j = 0, r = (Elf_Rela *) ((char *) e + rtab_offset); +@@ -375,7 +254,7 @@ SUFFIX (relocate_addresses) (Elf_Ehdr *e, Elf_Shdr *sections, + ELF_R_SYM (info), image_target); + + addend = (s->sh_type == grub_target_to_host32 (SHT_RELA)) ? +- r->r_addend : 0; ++ grub_target_to_host (r->r_addend) : 0; + + switch (image_target->elf_target) + { +@@ -461,14 +340,14 @@ SUFFIX (relocate_addresses) (Elf_Ehdr *e, Elf_Shdr *sections, + case R_IA64_PCREL21B: + { + grub_uint64_t noff; +- make_trampoline (tr, addend + sym_addr); ++ grub_ia64_make_trampoline (tr, addend + sym_addr); + noff = ((char *) tr - (char *) pe_target + - target_section_addr - (offset & ~3)) >> 4; + tr++; + if (noff & ~MASK19) + grub_util_error ("trampoline offset too big (%" + PRIxGRUB_UINT64_T ")", noff); +- add_value_to_slot_20b ((grub_addr_t) target, noff); ++ grub_ia64_add_value_to_slot_20b ((grub_addr_t) target, noff); + } + break; + +@@ -478,8 +357,8 @@ SUFFIX (relocate_addresses) (Elf_Ehdr *e, Elf_Shdr *sections, + Elf_Sym *sym; + + sym = (Elf_Sym *) ((char *) e +- + grub_target_to_host32 (symtab_section->sh_offset) +- + ELF_R_SYM (info) * grub_target_to_host32 (symtab_section->sh_entsize)); ++ + grub_target_to_host (symtab_section->sh_offset) ++ + ELF_R_SYM (info) * grub_target_to_host (symtab_section->sh_entsize)); + if (ELF_ST_TYPE (sym->st_info) == STT_FUNC) + sym_addr = grub_target_to_host64 (*(grub_uint64_t *) (pe_target + + sym->st_value +@@ -487,15 +366,15 @@ SUFFIX (relocate_addresses) (Elf_Ehdr *e, Elf_Shdr *sections, + } + case R_IA64_LTOFF_FPTR22: + *gpptr = grub_host_to_target64 (addend + sym_addr); +- add_value_to_slot_21 ((grub_addr_t) target, +- (char *) gpptr - (char *) pe_target +- + image_target->vaddr_offset); ++ grub_ia64_add_value_to_slot_21 ((grub_addr_t) target, ++ (char *) gpptr - (char *) pe_target ++ + image_target->vaddr_offset); + gpptr++; + break; + + case R_IA64_GPREL22: +- add_value_to_slot_21 ((grub_addr_t) target, +- addend + sym_addr); ++ grub_ia64_add_value_to_slot_21 ((grub_addr_t) target, ++ addend + sym_addr); + break; + case R_IA64_PCREL64LSB: + *target = grub_host_to_target64 (grub_target_to_host64 (*target) +@@ -514,7 +393,8 @@ SUFFIX (relocate_addresses) (Elf_Ehdr *e, Elf_Shdr *sections, + + addend + sym_addr); + grub_util_info ("relocating a direct entry to 0x%" + PRIxGRUB_UINT64_T " at the offset 0x%llx", +- *target, (unsigned long long) offset); ++ grub_target_to_host64 (*target), ++ (unsigned long long) offset); + break; + + /* We treat LTOFF22X as LTOFF22, so we can ignore LDXMOV. */ +@@ -650,8 +530,8 @@ SUFFIX (make_reloc_section) (Elf_Ehdr *e, void **out, + + 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))) ++ if ((grub_target_to_host32 (s->sh_type) == SHT_REL) || ++ (grub_target_to_host32 (s->sh_type) == SHT_RELA)) + { + Elf_Rel *r; + Elf_Word rtab_size, r_size, num_rs; +@@ -662,9 +542,9 @@ SUFFIX (make_reloc_section) (Elf_Ehdr *e, void **out, + 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); ++ rtab_size = grub_target_to_host (s->sh_size); ++ r_size = grub_target_to_host (s->sh_entsize); ++ rtab_offset = grub_target_to_host (s->sh_offset); + num_rs = rtab_size / r_size; + + section_address = section_addresses[grub_le_to_cpu32 (s->sh_info)]; +@@ -676,8 +556,8 @@ SUFFIX (make_reloc_section) (Elf_Ehdr *e, void **out, + Elf_Addr info; + Elf_Addr offset; + +- offset = grub_le_to_cpu32 (r->r_offset); +- info = grub_le_to_cpu32 (r->r_info); ++ offset = grub_target_to_host (r->r_offset); ++ info = grub_target_to_host (r->r_info); + + /* Necessary to relocate only absolute addresses. */ + switch (image_target->elf_target) +@@ -1027,7 +907,7 @@ SUFFIX (load_image) (const char *kernel_path, grub_size_t *exec_size, + *kernel_sz = ALIGN_UP (*kernel_sz, 16); + + grub_ia64_dl_get_tramp_got_size (e, &tramp, &got); +- tramp *= sizeof (struct ia64_kernel_trampoline); ++ tramp *= sizeof (struct grub_ia64_trampoline); + + ia64_toff = *kernel_sz; + *kernel_sz += ALIGN_UP (tramp, 16); +-- +1.8.1.4 + diff --git a/0275-autogen.sh-Use-h-not-f-to-test-for-existence-of-symb.patch b/0275-autogen.sh-Use-h-not-f-to-test-for-existence-of-symb.patch new file mode 100644 index 0000000..c8d3a37 --- /dev/null +++ b/0275-autogen.sh-Use-h-not-f-to-test-for-existence-of-symb.patch @@ -0,0 +1,40 @@ +From c6be98fd2558c7354ac1653c2d1526c89ef80f75 Mon Sep 17 00:00:00 2001 +From: Andrey Borzenkov +Date: Wed, 10 Apr 2013 15:57:40 +0200 +Subject: [PATCH 275/364] * autogen.sh: Use "-h", not "-f", to test for + existence of symbolic links under grub-core/lib/libgcrypt-grub/mpi. + +--- + ChangeLog | 5 +++++ + autogen.sh | 2 +- + 2 files changed, 6 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index e45ca35..fd9c082 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,8 @@ ++2013-04-09 Andrey Borzenkov ++ ++ * autogen.sh: Use "-h", not "-f", to test for existence of symbolic ++ links under grub-core/lib/libgcrypt-grub/mpi. ++ + 2013-04-08 Vladimir Serbinenko + + Fix ia64-efi image generation on big-endian machines. Deduplicate +diff --git a/autogen.sh b/autogen.sh +index 7a4b5c8..d47650b 100755 +--- a/autogen.sh ++++ b/autogen.sh +@@ -24,7 +24,7 @@ ln -s ../../../grub-core/lib/libgcrypt-grub/src/g10lib.h include/grub/gcrypt/g10 + cp -R grub-core/lib/libgcrypt/mpi/generic grub-core/lib/libgcrypt-grub/mpi/generic + + for x in mpi-asm-defs.h mpih-add1.c mpih-sub1.c mpih-mul1.c mpih-mul2.c mpih-mul3.c mpih-lshift.c mpih-rshift.c; do +- if [ -f grub-core/lib/libgcrypt-grub/mpi/"$x" ]; then ++ if [ -h grub-core/lib/libgcrypt-grub/mpi/"$x" ]; then + rm grub-core/lib/libgcrypt-grub/mpi/"$x" + fi + ln -s generic/"$x" grub-core/lib/libgcrypt-grub/mpi/"$x" +-- +1.8.1.4 + diff --git a/0276-Fix-missing-PVs-if-they-don-t-contain-interesting-LV.patch b/0276-Fix-missing-PVs-if-they-don-t-contain-interesting-LV.patch new file mode 100644 index 0000000..2faf45e --- /dev/null +++ b/0276-Fix-missing-PVs-if-they-don-t-contain-interesting-LV.patch @@ -0,0 +1,179 @@ +From 799c9e78e1e63c3abf22f62b453dcd9b50f929c2 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Thu, 11 Apr 2013 00:08:27 +0200 +Subject: [PATCH 276/364] Fix missing PVs if they don't contain + "interesting" LV. Closes #38677. Fix few warining messages and leaks + while on it. + +--- + ChangeLog | 5 +++ + grub-core/disk/diskfilter.c | 12 ++----- + grub-core/kern/emu/hostdisk.c | 4 ++- + util/getroot.c | 79 +++++++++++++++++++++++++++++++++++++++++++ + 4 files changed, 89 insertions(+), 11 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index fd9c082..602fc9b 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,8 @@ ++2013-04-11 Vladimir Serbinenko ++ ++ Fix missing PVs if they don't contain "interesting" LV. Closes #38677. ++ Fix few warining messages and leaks while on it. ++ + 2013-04-09 Andrey Borzenkov + + * autogen.sh: Use "-h", not "-f", to test for existence of symbolic +diff --git a/grub-core/disk/diskfilter.c b/grub-core/disk/diskfilter.c +index 2ff47e9..c4eb97e 100644 +--- a/grub-core/disk/diskfilter.c ++++ b/grub-core/disk/diskfilter.c +@@ -199,16 +199,8 @@ scan_disk (const char *name, int accept_diskfilter) + scan_depth--; + return 0; + } +- if (scan_disk_partition_iter (disk, 0, (void *) name)) +- { +- scan_depth--; +- return 1; +- } +- if (grub_partition_iterate (disk, scan_disk_partition_iter, (void *) name)) +- { +- scan_depth--; +- return 1; +- } ++ scan_disk_partition_iter (disk, 0, (void *) name); ++ grub_partition_iterate (disk, scan_disk_partition_iter, (void *) name); + grub_disk_close (disk); + scan_depth--; + return 0; +diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c +index 62a579b..4a5eee0 100644 +--- a/grub-core/kern/emu/hostdisk.c ++++ b/grub-core/kern/emu/hostdisk.c +@@ -431,7 +431,7 @@ grub_util_get_dm_node_linear_info (const char *dev, + uint64_t length, start; + char *target, *params; + char *ptr; +- int major, minor; ++ int major = 0, minor = 0; + int first = 1; + grub_disk_addr_t partstart = 0; + +@@ -497,6 +497,8 @@ grub_util_get_dm_node_linear_info (const char *dev, + + dm_task_destroy (dmt); + first = 0; ++ if (!dm_is_dm_major (major)) ++ break; + } + if (first) + return 0; +diff --git a/util/getroot.c b/util/getroot.c +index 654d1e1..f65fd1e 100644 +--- a/util/getroot.c ++++ b/util/getroot.c +@@ -243,6 +243,13 @@ exec_pipe (char **argv, int *fd) + else if (mdadm_pid == 0) + { + /* Child. */ ++ ++ /* Close fd's. */ ++#ifdef HAVE_DEVICE_MAPPER ++ dm_lib_release (); ++#endif ++ grub_diskfilter_fini (); ++ + /* Ensure child is not localised. */ + setenv ("LC_ALL", "C", 1); + +@@ -1315,6 +1322,76 @@ grub_util_get_dev_abstraction (const char *os_dev) + return GRUB_DEV_ABSTRACTION_NONE; + } + ++static void ++pull_lvm_by_command (const char *os_dev) ++{ ++ char *argv[6]; ++ int fd; ++ pid_t pid; ++ FILE *mdadm; ++ char *buf = NULL; ++ size_t len = 0; ++ char *vgname; ++ const char *iptr; ++ char *optr; ++ ++ if (strncmp (os_dev, "/dev/mapper/", sizeof ("/dev/mapper/") - 1) ++ != 0) ++ return; ++ ++ vgname = xmalloc (strlen (os_dev + sizeof ("/dev/mapper/") - 1) + 1); ++ for (iptr = os_dev + sizeof ("/dev/mapper/") - 1, optr = vgname; *iptr; ) ++ if (*iptr != '-') ++ *optr++ = *iptr++; ++ else if (iptr[0] == '-' && iptr[1] == '-') ++ { ++ iptr += 2; ++ *optr++ = '-'; ++ } ++ else ++ break; ++ *optr = '\0'; ++ ++ /* execvp has inconvenient types, hence the casts. None of these ++ strings will actually be modified. */ ++ argv[0] = (char *) "vgs"; ++ argv[1] = (char *) "--options"; ++ argv[2] = (char *) "pv_name"; ++ argv[3] = (char *) "--noheadings"; ++ argv[4] = vgname; ++ argv[5] = NULL; ++ ++ pid = exec_pipe (argv, &fd); ++ free (vgname); ++ ++ if (!pid) ++ return; ++ ++ /* Parent. Read mdadm's output. */ ++ mdadm = fdopen (fd, "r"); ++ if (! mdadm) ++ { ++ grub_util_warn (_("Unable to open stream from %s: %s"), ++ "vgs", strerror (errno)); ++ goto out; ++ } ++ ++ while (getline (&buf, &len, mdadm) > 0) ++ { ++ char *ptr; ++ for (ptr = buf; ptr < buf + 2 && *ptr == ' '; ptr++); ++ if (*ptr == '\0') ++ continue; ++ *(ptr + strlen (ptr) - 1) = '\0'; ++ grub_util_pull_device (ptr); ++ } ++ ++out: ++ close (fd); ++ waitpid (pid, NULL, 0); ++ free (buf); ++} ++ + #ifdef __linux__ + static char * + get_mdadm_uuid (const char *os_dev) +@@ -1538,6 +1615,8 @@ grub_util_pull_device (const char *os_dev) + break; + + case GRUB_DEV_ABSTRACTION_LVM: ++ pull_lvm_by_command (os_dev); ++ /* Fallthrough in case that lvm-tools are unavailable. */ + case GRUB_DEV_ABSTRACTION_LUKS: + #ifdef HAVE_DEVICE_MAPPER + { +-- +1.8.1.4 + diff --git a/0277-util-grub.d-30_os-prober.in-Add-onstr-to-entries-for.patch b/0277-util-grub.d-30_os-prober.in-Add-onstr-to-entries-for.patch new file mode 100644 index 0000000..8b6f89b --- /dev/null +++ b/0277-util-grub.d-30_os-prober.in-Add-onstr-to-entries-for.patch @@ -0,0 +1,49 @@ +From 590d8ede1ee3d379b19371c1e1a833906bfe0fa0 Mon Sep 17 00:00:00 2001 +From: Andrey Borzenkov +Date: Thu, 11 Apr 2013 15:11:14 +0200 +Subject: [PATCH 277/364] * util/grub.d/30_os-prober.in: Add onstr to + entries for visual distinction. + +--- + ChangeLog | 5 +++++ + util/grub.d/30_os-prober.in | 4 ++-- + 2 files changed, 7 insertions(+), 2 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 602fc9b..bb6d97b 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,8 @@ ++2013-04-11 Andrey Borzenkov ++ ++ * util/grub.d/30_os-prober.in: Add onstr to entries for visual ++ distinction. ++ + 2013-04-11 Vladimir Serbinenko + + Fix missing PVs if they don't contain "interesting" LV. Closes #38677. +diff --git a/util/grub.d/30_os-prober.in b/util/grub.d/30_os-prober.in +index e20d8b3..5500a3c 100644 +--- a/util/grub.d/30_os-prober.in ++++ b/util/grub.d/30_os-prober.in +@@ -195,7 +195,7 @@ EOF + + if [ "x$is_first_entry" = xtrue ]; then + cat << EOF +-menuentry '$(echo "$OS" | grub_quote)' --class gnu-linux --class gnu --class os \$menuentry_id_option 'osprober-gnulinux-simple-$boot_device_id' { ++menuentry '$(echo "$OS $onstr" | grub_quote)' --class gnu-linux --class gnu --class os \$menuentry_id_option 'osprober-gnulinux-simple-$boot_device_id' { + EOF + save_default_entry | grub_add_tab + printf '%s\n' "${prepare_boot_cache}" +@@ -210,7 +210,7 @@ EOF + cat << EOF + } + EOF +- echo "submenu '$(gettext_printf "Advanced options for %s" "${OS}" | grub_quote)' \$menuentry_id_option 'osprober-gnulinux-advanced-$boot_device_id' {" ++ echo "submenu '$(gettext_printf "Advanced options for %s" "${OS} $onstr" | grub_quote)' \$menuentry_id_option 'osprober-gnulinux-advanced-$boot_device_id' {" + is_first_entry=false + fi + title="${LLABEL} $onstr" +-- +1.8.1.4 + diff --git a/0278-Use-ACPI-shutdown-intests-as-traditional-port-was-re.patch b/0278-Use-ACPI-shutdown-intests-as-traditional-port-was-re.patch new file mode 100644 index 0000000..b1f4b29 --- /dev/null +++ b/0278-Use-ACPI-shutdown-intests-as-traditional-port-was-re.patch @@ -0,0 +1,451 @@ +From 3f4af0c00ca064488a7186696fecf27a55a2165f Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Thu, 11 Apr 2013 21:09:43 +0200 +Subject: [PATCH 278/364] Use ACPI shutdown intests as traditional port + was removed. + +--- + ChangeLog | 4 +++ + grub-core/tests/boot/kbsd.init-i386.S | 20 +------------ + grub-core/tests/boot/kbsd.init-x86_64.S | 19 +----------- + grub-core/tests/boot/kernel-8086.S | 21 +------------- + grub-core/tests/boot/kernel-i386.S | 21 ++------------ + grub-core/tests/boot/kfreebsd.init-i386.S | 45 +++++++++++++---------------- + grub-core/tests/boot/kfreebsd.init-x86_64.S | 40 ++++++++++--------------- + grub-core/tests/boot/linux.init-i386.S | 20 +------------ + grub-core/tests/boot/linux.init-x86_64.S | 20 +------------ + grub-core/tests/boot/qemu-shutdown-x86.S | 9 ++++++ + 10 files changed, 56 insertions(+), 163 deletions(-) + create mode 100644 grub-core/tests/boot/qemu-shutdown-x86.S + +diff --git a/ChangeLog b/ChangeLog +index bb6d97b..614748a 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,7 @@ ++2013-04-11 Vladimir Serbinenko ++ ++ Use ACPI shutdown intests as traditional port was removed. ++ + 2013-04-11 Andrey Borzenkov + + * util/grub.d/30_os-prober.in: Add onstr to entries for visual +diff --git a/grub-core/tests/boot/kbsd.init-i386.S b/grub-core/tests/boot/kbsd.init-i386.S +index 7011c79..72ddb7c 100644 +--- a/grub-core/tests/boot/kbsd.init-i386.S ++++ b/grub-core/tests/boot/kbsd.init-i386.S +@@ -37,8 +37,6 @@ + #define RESET_HALT 0x8 + #define RESET_POWEROFF 0x800 + +-#define SHUTDOWN_PORT 0x8900 +- + .section ".init", "ax" + .global start,_start + start: +@@ -72,23 +70,7 @@ _start: + int $SYSCALL_INT + addl $12, %esp + +- movw $SHUTDOWN_PORT, %dx +- movb $'S', %al +- outb %al, %dx +- movb $'h', %al +- outb %al, %dx +- movb $'u', %al +- outb %al, %dx +- movb $'t', %al +- outb %al, %dx +- movb $'d', %al +- outb %al, %dx +- movb $'o', %al +- outb %al, %dx +- movb $'w', %al +- outb %al, %dx +- movb $'n', %al +- outb %al, %dx ++#include "qemu-shutdown-x86.S" + + /* shutdown. */ + movl $SYSCALL_RESET, %eax +diff --git a/grub-core/tests/boot/kbsd.init-x86_64.S b/grub-core/tests/boot/kbsd.init-x86_64.S +index 81f810e..7486bc3 100644 +--- a/grub-core/tests/boot/kbsd.init-x86_64.S ++++ b/grub-core/tests/boot/kbsd.init-x86_64.S +@@ -35,7 +35,6 @@ + #define RESET_NOSYNC 0x4 + #define RESET_HALT 0x8 + #define RESET_POWEROFF 0x800 +-#define SHUTDOWN_PORT 0x8900 + + .section ".init", "ax" + .global start,_start +@@ -61,23 +60,7 @@ _start: + leaq iopl_arg, %rsi + syscall + +- movw $SHUTDOWN_PORT, %dx +- movb $'S', %al +- outb %al, %dx +- movb $'h', %al +- outb %al, %dx +- movb $'u', %al +- outb %al, %dx +- movb $'t', %al +- outb %al, %dx +- movb $'d', %al +- outb %al, %dx +- movb $'o', %al +- outb %al, %dx +- movb $'w', %al +- outb %al, %dx +- movb $'n', %al +- outb %al, %dx ++#include "qemu-shutdown-x86.S" + + /* shutdown. */ + movq $SYSCALL_RESET, %rax +diff --git a/grub-core/tests/boot/kernel-8086.S b/grub-core/tests/boot/kernel-8086.S +index 20040da..510897c 100644 +--- a/grub-core/tests/boot/kernel-8086.S ++++ b/grub-core/tests/boot/kernel-8086.S +@@ -1,6 +1,4 @@ + +-#define SHUTDOWN_PORT 0x8900 +- + .text + .globl _start + _start: +@@ -8,18 +6,6 @@ base: + .code16 + jmp cont + +-portmsg: +- xorw %ax, %ax +-1: +- movb 0(%si), %al +- test %ax, %ax +- jz 1f +- outb %al, %dx +- incw %si +- jmp 1b +-1: +- ret +- + serialmsg: + 1: + movb 0(%si), %bl +@@ -50,17 +36,12 @@ cont: + movw %ax, %ds + lea message, %si + call serialmsg +- lea shutdown, %si +- movw $SHUTDOWN_PORT, %dx +- call portmsg ++#include "qemu-shutdown-x86.S" + + 1: + hlt + jmp 1b + +-shutdown: +- .ascii "Shutdown" +- .byte 0 + message: + .ascii "Boot Test Passed Successfully\n" SUCCESSFUL_BOOT_STRING "\n" + .byte 0 +diff --git a/grub-core/tests/boot/kernel-i386.S b/grub-core/tests/boot/kernel-i386.S +index 904b0d4..2154d3b 100644 +--- a/grub-core/tests/boot/kernel-i386.S ++++ b/grub-core/tests/boot/kernel-i386.S +@@ -5,8 +5,6 @@ + #include + #endif + +-#define SHUTDOWN_PORT 0x8900 +- + .text + /* Align 32 bits boundary. */ + .align 8 +@@ -38,17 +36,6 @@ multiboot_header: + #endif + + .global start +-portmsg: +- xorl %eax, %eax +-1: +- movb 0(%esi), %al +- test %eax, %eax +- jz 1f +- outb %al, %dx +- incl %esi +- jmp 1b +-1: +- ret + + serialmsg: + 1: +@@ -73,17 +60,13 @@ serialmsg: + _start: + lea message, %esi + call serialmsg +- lea shutdown, %esi +- movw $SHUTDOWN_PORT, %dx +- call portmsg ++ ++#include "qemu-shutdown-x86.S" + + 1: + hlt + jmp 1b + +-shutdown: +- .ascii "Shutdown" +- .byte 0 + message: + .ascii "Boot Test Passed Successfully\n" SUCCESSFUL_BOOT_STRING "\n" + .byte 0 +diff --git a/grub-core/tests/boot/kfreebsd.init-i386.S b/grub-core/tests/boot/kfreebsd.init-i386.S +index 12c94a0..a448152 100644 +--- a/grub-core/tests/boot/kfreebsd.init-i386.S ++++ b/grub-core/tests/boot/kfreebsd.init-i386.S +@@ -24,13 +24,12 @@ + #define SYSCALL_FSYNC 95 + #define SYSCALL_ARCH 165 + #define SYSCALL_EXIT 1 +-#define SYSCALL_ARCH_IOPL 4 ++#define SYSCALL_ARCH_IOPERM 4 + #define SYSCALL_INT 0x80 + + #define RESET_NOSYNC 0x4 + #define RESET_HALT 0x8 + #define RESET_POWEROFF 0x4000 +-#define SHUTDOWN_PORT 0x8900 + + .section ".init", "ax" + .global start,_start +@@ -64,31 +63,23 @@ _start: + int $SYSCALL_INT + addl $8, %esp + +- /* IOPL. */ ++ /* IOPERM. */ + movl $SYSCALL_ARCH, %eax +- pushl $iopl_arg +- pushl $SYSCALL_ARCH_IOPL ++ pushl $iopl_arg1 ++ pushl $SYSCALL_ARCH_IOPERM + pushl $0 + int $SYSCALL_INT + addl $12, %esp +- +- movw $SHUTDOWN_PORT, %dx +- movb $'S', %al +- outb %al, %dx +- movb $'h', %al +- outb %al, %dx +- movb $'u', %al +- outb %al, %dx +- movb $'t', %al +- outb %al, %dx +- movb $'d', %al +- outb %al, %dx +- movb $'o', %al +- outb %al, %dx +- movb $'w', %al +- outb %al, %dx +- movb $'n', %al +- outb %al, %dx ++ ++ /* IOPERM. */ ++ movl $SYSCALL_ARCH, %eax ++ pushl $iopl_arg2 ++ pushl $SYSCALL_ARCH_IOPERM ++ pushl $0 ++ int $SYSCALL_INT ++ addl $12, %esp ++ ++#include "qemu-shutdown-x86.S" + + /* shutdown. */ + movl $SYSCALL_RESET, %eax +@@ -108,7 +99,11 @@ device: + message: + .ascii "Boot Test Passed Successfully\n" SUCCESSFUL_BOOT_STRING "\n" + messageend: +-iopl_arg: +- .long SHUTDOWN_PORT ++ioperm_arg1: ++ .long 0xcf8 ++ .long 8 + .long 1 ++ioperm_arg2: ++ .long 0x1000 ++ .long 8 + .long 1 +diff --git a/grub-core/tests/boot/kfreebsd.init-x86_64.S b/grub-core/tests/boot/kfreebsd.init-x86_64.S +index 0a9ff51..de7bab6 100644 +--- a/grub-core/tests/boot/kfreebsd.init-x86_64.S ++++ b/grub-core/tests/boot/kfreebsd.init-x86_64.S +@@ -23,13 +23,12 @@ + #define SYSCALL_WRITE 4 + #define SYSCALL_RESET 55 + #define SYSCALL_EXIT 1 +-#define SYSCALL_ARCH_IOPL 4 ++#define SYSCALL_ARCH_IOPERM 4 + #define SYSCALL_FSYNC 95 + + #define RESET_NOSYNC 0x4 + #define RESET_HALT 0x8 + #define RESET_POWEROFF 0x4000 +-#define SHUTDOWN_PORT 0x8900 + + .section ".init", "ax" + .global start,_start +@@ -53,29 +52,18 @@ _start: + movq $SYSCALL_FSYNC, %rax + syscall + +- /* IOPL. */ ++ /* IOPERM. */ + movq $SYSCALL_ARCH, %rax +- movq $SYSCALL_ARCH_IOPL, %rdi +- leaq iopl_arg, %rsi ++ movq $SYSCALL_ARCH_IOPERM, %rdi ++ leaq ioperm_arg1, %rsi + syscall + +- movw $SHUTDOWN_PORT, %dx +- movb $'S', %al +- outb %al, %dx +- movb $'h', %al +- outb %al, %dx +- movb $'u', %al +- outb %al, %dx +- movb $'t', %al +- outb %al, %dx +- movb $'d', %al +- outb %al, %dx +- movb $'o', %al +- outb %al, %dx +- movb $'w', %al +- outb %al, %dx +- movb $'n', %al +- outb %al, %dx ++ movq $SYSCALL_ARCH, %rax ++ movq $SYSCALL_ARCH_IOPERM, %rdi ++ leaq ioperm_arg2, %rsi ++ syscall ++ ++#include "qemu-shutdown-x86.S" + + /* shutdown. */ + movq $SYSCALL_RESET, %rax +@@ -92,7 +80,11 @@ device: + message: + .ascii "Boot Test Passed Successfully\n" SUCCESSFUL_BOOT_STRING "\n" + messageend: +-iopl_arg: +- .long SHUTDOWN_PORT ++ioperm_arg1: ++ .long 0xcf8 ++ .long 8 + .long 1 ++ioperm_arg2: ++ .long 0x1000 ++ .long 8 + .long 1 +diff --git a/grub-core/tests/boot/linux.init-i386.S b/grub-core/tests/boot/linux.init-i386.S +index 5b0088e..c0983ac 100644 +--- a/grub-core/tests/boot/linux.init-i386.S ++++ b/grub-core/tests/boot/linux.init-i386.S +@@ -27,8 +27,6 @@ + #define SHUTDOWN_MAGIC2 0x28121969 + #define SHUTDOWN_MAGIC3 0x4321fedc + +-#define SHUTDOWN_PORT 0x8900 +- + .text + .global start, _start + _start: +@@ -44,23 +42,7 @@ start: + movl $3, %ebx + int $SYSCALL_INT + +- movw $SHUTDOWN_PORT, %dx +- movb $'S', %al +- outb %al, %dx +- movb $'h', %al +- outb %al, %dx +- movb $'u', %al +- outb %al, %dx +- movb $'t', %al +- outb %al, %dx +- movb $'d', %al +- outb %al, %dx +- movb $'o', %al +- outb %al, %dx +- movb $'w', %al +- outb %al, %dx +- movb $'n', %al +- outb %al, %dx ++#include "qemu-shutdown-x86.S" + + /* shutdown. */ + movl $SYSCALL_RESET, %eax +diff --git a/grub-core/tests/boot/linux.init-x86_64.S b/grub-core/tests/boot/linux.init-x86_64.S +index fc32dfd..90bdcc3 100644 +--- a/grub-core/tests/boot/linux.init-x86_64.S ++++ b/grub-core/tests/boot/linux.init-x86_64.S +@@ -26,8 +26,6 @@ + #define SHUTDOWN_MAGIC2 0x28121969 + #define SHUTDOWN_MAGIC3 0x4321fedc + +-#define SHUTDOWN_PORT 0x8900 +- + .text + .global start, _start + _start: +@@ -43,23 +41,7 @@ start: + movq $3, %rdi + syscall + +- movw $SHUTDOWN_PORT, %dx +- movb $'S', %al +- outb %al, %dx +- movb $'h', %al +- outb %al, %dx +- movb $'u', %al +- outb %al, %dx +- movb $'t', %al +- outb %al, %dx +- movb $'d', %al +- outb %al, %dx +- movb $'o', %al +- outb %al, %dx +- movb $'w', %al +- outb %al, %dx +- movb $'n', %al +- outb %al, %dx ++#include "qemu-shutdown-x86.S" + + /* shutdown. */ + movq $SYSCALL_RESET, %rax +diff --git a/grub-core/tests/boot/qemu-shutdown-x86.S b/grub-core/tests/boot/qemu-shutdown-x86.S +new file mode 100644 +index 0000000..8f794fc +--- /dev/null ++++ b/grub-core/tests/boot/qemu-shutdown-x86.S +@@ -0,0 +1,9 @@ ++ movl $0x80000b40, %eax ++ movw $0xcf8, %dx ++ outl %eax, %dx ++ movl $0x1001, %eax ++ movw $0xcfc, %dx ++ outl %eax, %dx ++ movw $0x2000, %ax ++ movw $0x1004, %dx ++ outw %ax, %dx +-- +1.8.1.4 + diff --git a/0279-Import-new-gnulib.patch b/0279-Import-new-gnulib.patch new file mode 100644 index 0000000..30defe1 --- /dev/null +++ b/0279-Import-new-gnulib.patch @@ -0,0 +1,29453 @@ +From 6a26cd474ef12887f60a6c9c0be1ffb9b0a510cd Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Thu, 11 Apr 2013 21:12:46 +0200 +Subject: [PATCH 279/364] Import new gnulib. + +--- + ChangeLog | 4 + + build-aux/arg-nonnull.h | 26 - + build-aux/c++defs.h | 271 --------- + build-aux/config.rpath | 228 +++++--- + build-aux/warn-on-use.h | 109 ---- + config.h.in | 2 + + grub-core/Makefile.core.def | 2 +- + grub-core/gnulib-fix-null-deref.diff | 13 + + grub-core/gnulib-fix-width.diff | 231 ++++++++ + grub-core/gnulib-no-abort.diff | 30 + + grub-core/gnulib-no-gets.diff | 10 + + grub-core/gnulib/Makefile.am | 1020 +++++++++++++++++++++++----------- + grub-core/gnulib/alloca.c | 31 +- + grub-core/gnulib/alloca.in.h | 15 +- + grub-core/gnulib/argp-ba.c | 8 +- + grub-core/gnulib/argp-eexst.c | 2 +- + grub-core/gnulib/argp-fmtstream.c | 71 ++- + grub-core/gnulib/argp-fmtstream.h | 34 +- + grub-core/gnulib/argp-fs-xinl.c | 8 +- + grub-core/gnulib/argp-help.c | 71 +-- + grub-core/gnulib/argp-namefrob.h | 28 +- + grub-core/gnulib/argp-parse.c | 29 +- + grub-core/gnulib/argp-pin.c | 3 +- + grub-core/gnulib/argp-pv.c | 4 +- + grub-core/gnulib/argp-pvh.c | 2 +- + grub-core/gnulib/argp-xinl.c | 8 +- + grub-core/gnulib/argp.h | 71 +-- + grub-core/gnulib/asnprintf.c | 5 +- + grub-core/gnulib/basename-lgpl.c | 2 +- + grub-core/gnulib/btowc.c | 2 +- + grub-core/gnulib/config.charset | 7 +- + grub-core/gnulib/dirname-lgpl.c | 8 +- + grub-core/gnulib/dirname.h | 38 +- + grub-core/gnulib/dosname.h | 53 ++ + grub-core/gnulib/errno.in.h | 195 +++++-- + grub-core/gnulib/error.c | 27 +- + grub-core/gnulib/error.h | 24 +- + grub-core/gnulib/float+.h | 11 +- + grub-core/gnulib/float.c | 33 ++ + grub-core/gnulib/float.in.h | 138 ++++- + grub-core/gnulib/fnmatch.c | 16 +- + grub-core/gnulib/fnmatch.in.h | 19 +- + grub-core/gnulib/fnmatch_loop.c | 28 +- + grub-core/gnulib/getdelim.c | 12 +- + grub-core/gnulib/getline.c | 6 +- + grub-core/gnulib/getopt.c | 159 ++++-- + grub-core/gnulib/getopt.in.h | 70 +-- + grub-core/gnulib/getopt1.c | 8 +- + grub-core/gnulib/getopt_int.h | 18 +- + grub-core/gnulib/gettext.h | 22 +- + grub-core/gnulib/intprops.h | 318 +++++++++-- + grub-core/gnulib/itold.c | 28 + + grub-core/gnulib/langinfo.in.h | 19 +- + grub-core/gnulib/localcharset.c | 45 +- + grub-core/gnulib/localcharset.h | 5 +- + grub-core/gnulib/locale.in.h | 216 +++++++ + grub-core/gnulib/localeconv.c | 103 ++++ + grub-core/gnulib/malloc.c | 10 +- + grub-core/gnulib/mbrtowc.c | 48 +- + grub-core/gnulib/mbsinit.c | 18 +- + grub-core/gnulib/mbsrtowcs-impl.h | 122 ++++ + grub-core/gnulib/mbsrtowcs-state.c | 4 +- + grub-core/gnulib/mbsrtowcs.c | 108 +--- + grub-core/gnulib/mbswidth.c | 199 +++++++ + grub-core/gnulib/mbswidth.h | 63 +++ + grub-core/gnulib/mbtowc-impl.h | 44 ++ + grub-core/gnulib/mbtowc.c | 26 + + grub-core/gnulib/memchr.c | 2 +- + grub-core/gnulib/mempcpy.c | 5 +- + grub-core/gnulib/msvc-inval.c | 129 +++++ + grub-core/gnulib/msvc-inval.h | 222 ++++++++ + grub-core/gnulib/msvc-nothrow.c | 49 ++ + grub-core/gnulib/msvc-nothrow.h | 43 ++ + grub-core/gnulib/nl_langinfo.c | 7 +- + grub-core/gnulib/printf-args.c | 5 +- + grub-core/gnulib/printf-args.h | 9 +- + grub-core/gnulib/printf-parse.c | 55 +- + grub-core/gnulib/printf-parse.h | 19 +- + grub-core/gnulib/progname.c | 2 +- + grub-core/gnulib/progname.h | 2 +- + grub-core/gnulib/rawmemchr.c | 2 +- + grub-core/gnulib/realloc.c | 16 +- + grub-core/gnulib/ref-add.sin | 5 +- + grub-core/gnulib/ref-del.sin | 5 +- + grub-core/gnulib/regcomp.c | 348 ++++++------ + grub-core/gnulib/regex.c | 37 +- + grub-core/gnulib/regex.h | 252 ++++----- + grub-core/gnulib/regex_internal.c | 99 ++-- + grub-core/gnulib/regex_internal.h | 148 ++--- + grub-core/gnulib/regexec.c | 202 ++++--- + grub-core/gnulib/size_max.h | 5 +- + grub-core/gnulib/sleep.c | 11 +- + grub-core/gnulib/stdalign.in.h | 90 +++ + grub-core/gnulib/stdbool.in.h | 56 +- + grub-core/gnulib/stddef.in.h | 20 +- + grub-core/gnulib/stdint.in.h | 286 ++++++---- + grub-core/gnulib/stdio-write.c | 148 ----- + grub-core/gnulib/stdio.in.h | 450 +++++++++++---- + grub-core/gnulib/stdlib.in.h | 327 +++++++++-- + grub-core/gnulib/strcasecmp.c | 5 +- + grub-core/gnulib/strchrnul.c | 2 +- + grub-core/gnulib/streq.h | 12 +- + grub-core/gnulib/strerror-override.c | 302 ++++++++++ + grub-core/gnulib/strerror-override.h | 56 ++ + grub-core/gnulib/strerror.c | 354 ++---------- + grub-core/gnulib/string.in.h | 144 ++++- + grub-core/gnulib/strings.in.h | 47 +- + grub-core/gnulib/stripslash.c | 4 +- + grub-core/gnulib/strncasecmp.c | 5 +- + grub-core/gnulib/strndup.c | 7 +- + grub-core/gnulib/strnlen.c | 5 +- + grub-core/gnulib/strnlen1.c | 2 +- + grub-core/gnulib/strnlen1.h | 5 +- + grub-core/gnulib/sys_types.in.h | 51 ++ + grub-core/gnulib/sys_wait.in.h | 106 ---- + grub-core/gnulib/sysexits.in.h | 13 +- + grub-core/gnulib/unistd.c | 3 + + grub-core/gnulib/unistd.in.h | 508 ++++++++++++----- + grub-core/gnulib/unitypes.in.h | 46 ++ + grub-core/gnulib/uniwidth.in.h | 72 +++ + grub-core/gnulib/uniwidth/cjk.h | 37 ++ + grub-core/gnulib/uniwidth/width.c | 368 ++++++++++++ + grub-core/gnulib/vasnprintf.c | 137 +++-- + grub-core/gnulib/vasnprintf.h | 19 +- + grub-core/gnulib/verify.h | 150 +++-- + grub-core/gnulib/vsnprintf.c | 5 +- + grub-core/gnulib/wchar.in.h | 636 ++++++++++++++++++++- + grub-core/gnulib/wcrtomb.c | 2 +- + grub-core/gnulib/wctype-h.c | 4 + + grub-core/gnulib/wctype.in.h | 372 ++++++++----- + grub-core/gnulib/wcwidth.c | 50 ++ + grub-core/gnulib/xsize.c | 3 + + grub-core/gnulib/xsize.h | 22 +- + grub-core/kern/emu/argp_common.c | 1 + + grub-core/kern/emu/error.c | 2 + + grub-core/kern/emu/hostdisk.c | 2 + + grub-core/kern/emu/hostfs.c | 3 + + grub-core/kern/emu/main.c | 3 + + grub-core/lib/posix_wrap/limits.h | 1 + + grub-core/lib/posix_wrap/sys/types.h | 2 + + include/grub/types.h | 4 + + m4/00gnulib.m4 | 2 +- + m4/alloca.m4 | 86 ++- + m4/argp.m4 | 32 +- + m4/asm-underscore.m4 | 48 -- + m4/btowc.m4 | 25 +- + m4/codeset.m4 | 2 +- + m4/configmake.m4 | 50 ++ + m4/dirname.m4 | 11 +- + m4/dos.m4 | 71 --- + m4/double-slash-root.m4 | 2 +- + m4/eealloc.m4 | 31 ++ + m4/errno_h.m4 | 28 +- + m4/error.m4 | 20 +- + m4/exponentd.m4 | 116 ++++ + m4/extensions.m4 | 54 +- + m4/extern-inline.m4 | 65 +++ + m4/fcntl-o.m4 | 89 ++- + m4/float_h.m4 | 87 ++- + m4/fnmatch.m4 | 117 ++-- + m4/getdelim.m4 | 30 +- + m4/getline.m4 | 33 +- + m4/getopt.m4 | 382 +++++++------ + m4/gettext.m4 | 8 +- + m4/glibc2.m4 | 7 +- + m4/glibc21.m4 | 14 +- + m4/gnulib-cache.m4 | 25 +- + m4/gnulib-common.m4 | 192 ++++++- + m4/gnulib-comp.m4 | 329 ++++++++--- + m4/gnulib-tool.m4 | 2 +- + m4/iconv.m4 | 30 +- + m4/include_next.m4 | 158 ++++-- + m4/intdiv0.m4 | 8 +- + m4/intl.m4 | 14 +- + m4/intldir.m4 | 2 +- + m4/intlmacosx.m4 | 14 +- + m4/intmax.m4 | 2 +- + m4/intmax_t.m4 | 2 +- + m4/inttypes-pri.m4 | 2 +- + m4/inttypes_h.m4 | 2 +- + m4/langinfo_h.m4 | 2 +- + m4/lcmessage.m4 | 2 +- + m4/lib-ld.m4 | 60 +- + m4/lib-link.m4 | 6 +- + m4/lib-prefix.m4 | 2 +- + m4/libunistring-base.m4 | 141 +++++ + m4/localcharset.m4 | 2 +- + m4/locale-fr.m4 | 161 ++++-- + m4/locale-ja.m4 | 97 ++-- + m4/locale-zh.m4 | 80 ++- + m4/locale_h.m4 | 122 ++++ + m4/localeconv.m4 | 22 + + m4/lock.m4 | 12 +- + m4/longlong.m4 | 87 +-- + m4/malloc.m4 | 52 +- + m4/math_h.m4 | 353 ++++++++++++ + m4/mbrtowc.m4 | 249 +++++++-- + m4/mbsinit.m4 | 33 +- + m4/mbsrtowcs.m4 | 66 ++- + m4/mbstate_t.m4 | 13 +- + m4/mbswidth.m4 | 46 ++ + m4/mbtowc.m4 | 19 + + m4/memchr.m4 | 31 +- + m4/mempcpy.m4 | 7 +- + m4/mmap-anon.m4 | 18 +- + m4/msvc-inval.m4 | 19 + + m4/msvc-nothrow.m4 | 10 + + m4/multiarch.m4 | 11 +- + m4/nl_langinfo.m4 | 35 +- + m4/nls.m4 | 2 +- + m4/nocrash.m4 | 130 +++++ + m4/off_t.m4 | 18 + + m4/po.m4 | 35 +- + m4/printf-posix.m4 | 2 +- + m4/printf.m4 | 370 +++++++----- + m4/progtest.m4 | 2 +- + m4/rawmemchr.m4 | 7 +- + m4/realloc.m4 | 52 +- + m4/regex.m4 | 134 +++-- + m4/size_max.m4 | 2 +- + m4/sleep.m4 | 33 +- + m4/ssize_t.m4 | 2 +- + m4/stdalign.m4 | 52 ++ + m4/stdbool.m4 | 17 +- + m4/stddef_h.m4 | 10 +- + m4/stdint.m4 | 40 +- + m4/stdint_h.m4 | 2 +- + m4/stdio_h.m4 | 95 +++- + m4/stdlib_h.m4 | 49 +- + m4/strcase.m4 | 15 +- + m4/strchrnul.m4 | 37 +- + m4/strerror.m4 | 116 ++-- + m4/string_h.m4 | 20 +- + m4/strings_h.m4 | 23 +- + m4/strndup.m4 | 20 +- + m4/strnlen.m4 | 12 +- + m4/sys_socket_h.m4 | 176 ++++++ + m4/sys_types_h.m4 | 24 + + m4/sys_wait_h.m4 | 25 - + m4/sysexits.m4 | 5 +- + m4/threadlib.m4 | 97 ++-- + m4/uintmax_t.m4 | 2 +- + m4/unistd_h.m4 | 137 +++-- + m4/vasnprintf.m4 | 15 +- + m4/visibility.m4 | 6 +- + m4/vsnprintf.m4 | 20 +- + m4/warn-on-use.m4 | 14 +- + m4/wchar_h.m4 | 123 +++- + m4/wchar_t.m4 | 2 +- + m4/wcrtomb.m4 | 44 +- + m4/wctype_h.m4 | 190 +++++-- + m4/wcwidth.m4 | 101 ++++ + m4/wint_t.m4 | 2 +- + m4/xsize.m4 | 5 +- + po/POTFILES.in | 39 +- + 255 files changed, 12570 insertions(+), 4940 deletions(-) + delete mode 100644 build-aux/arg-nonnull.h + delete mode 100644 build-aux/c++defs.h + delete mode 100644 build-aux/warn-on-use.h + create mode 100644 grub-core/gnulib-fix-null-deref.diff + create mode 100644 grub-core/gnulib-fix-width.diff + create mode 100644 grub-core/gnulib-no-abort.diff + create mode 100644 grub-core/gnulib-no-gets.diff + create mode 100644 grub-core/gnulib/dosname.h + create mode 100644 grub-core/gnulib/float.c + create mode 100644 grub-core/gnulib/itold.c + create mode 100644 grub-core/gnulib/locale.in.h + create mode 100644 grub-core/gnulib/localeconv.c + create mode 100644 grub-core/gnulib/mbsrtowcs-impl.h + create mode 100644 grub-core/gnulib/mbswidth.c + create mode 100644 grub-core/gnulib/mbswidth.h + create mode 100644 grub-core/gnulib/mbtowc-impl.h + create mode 100644 grub-core/gnulib/mbtowc.c + create mode 100644 grub-core/gnulib/msvc-inval.c + create mode 100644 grub-core/gnulib/msvc-inval.h + create mode 100644 grub-core/gnulib/msvc-nothrow.c + create mode 100644 grub-core/gnulib/msvc-nothrow.h + create mode 100644 grub-core/gnulib/stdalign.in.h + delete mode 100644 grub-core/gnulib/stdio-write.c + create mode 100644 grub-core/gnulib/strerror-override.c + create mode 100644 grub-core/gnulib/strerror-override.h + create mode 100644 grub-core/gnulib/sys_types.in.h + delete mode 100644 grub-core/gnulib/sys_wait.in.h + create mode 100644 grub-core/gnulib/unistd.c + create mode 100644 grub-core/gnulib/unitypes.in.h + create mode 100644 grub-core/gnulib/uniwidth.in.h + create mode 100644 grub-core/gnulib/uniwidth/cjk.h + create mode 100644 grub-core/gnulib/uniwidth/width.c + create mode 100644 grub-core/gnulib/wctype-h.c + create mode 100644 grub-core/gnulib/wcwidth.c + create mode 100644 grub-core/gnulib/xsize.c + create mode 100644 grub-core/kern/emu/error.c + delete mode 100644 m4/asm-underscore.m4 + create mode 100644 m4/configmake.m4 + delete mode 100644 m4/dos.m4 + create mode 100644 m4/eealloc.m4 + create mode 100644 m4/exponentd.m4 + create mode 100644 m4/extern-inline.m4 + create mode 100644 m4/libunistring-base.m4 + create mode 100644 m4/locale_h.m4 + create mode 100644 m4/localeconv.m4 + create mode 100644 m4/math_h.m4 + create mode 100644 m4/mbswidth.m4 + create mode 100644 m4/mbtowc.m4 + create mode 100644 m4/msvc-inval.m4 + create mode 100644 m4/msvc-nothrow.m4 + create mode 100644 m4/nocrash.m4 + create mode 100644 m4/off_t.m4 + create mode 100644 m4/stdalign.m4 + create mode 100644 m4/sys_socket_h.m4 + create mode 100644 m4/sys_types_h.m4 + delete mode 100644 m4/sys_wait_h.m4 + create mode 100644 m4/wcwidth.m4 + +diff --git a/ChangeLog b/ChangeLog +index 614748a..90aacbe 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,9 @@ + 2013-04-11 Vladimir Serbinenko + ++ Import new gnulib. ++ ++2013-04-11 Vladimir Serbinenko ++ + Use ACPI shutdown intests as traditional port was removed. + + 2013-04-11 Andrey Borzenkov +diff --git a/build-aux/arg-nonnull.h b/build-aux/arg-nonnull.h +deleted file mode 100644 +index 7e3e2db..0000000 +--- a/build-aux/arg-nonnull.h ++++ /dev/null +@@ -1,26 +0,0 @@ +-/* A C macro for declaring that specific arguments must not be NULL. +- 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 +- Lesser 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 . */ +- +-/* _GL_ARG_NONNULL((n,...,m)) tells the compiler and static analyzer tools +- that the values passed as arguments n, ..., m must be non-NULL pointers. +- n = 1 stands for the first argument, n = 2 for the second argument etc. */ +-#ifndef _GL_ARG_NONNULL +-# if (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) || __GNUC__ > 3 +-# define _GL_ARG_NONNULL(params) __attribute__ ((__nonnull__ params)) +-# else +-# define _GL_ARG_NONNULL(params) +-# endif +-#endif +diff --git a/build-aux/c++defs.h b/build-aux/c++defs.h +deleted file mode 100644 +index 0c2fad7..0000000 +--- a/build-aux/c++defs.h ++++ /dev/null +@@ -1,271 +0,0 @@ +-/* C++ compatible function declaration macros. +- Copyright (C) 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 +- Lesser 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 _GL_CXXDEFS_H +-#define _GL_CXXDEFS_H +- +-/* The three most frequent use cases of these macros are: +- +- * For providing a substitute for a function that is missing on some +- platforms, but is declared and works fine on the platforms on which +- it exists: +- +- #if @GNULIB_FOO@ +- # if !@HAVE_FOO@ +- _GL_FUNCDECL_SYS (foo, ...); +- # endif +- _GL_CXXALIAS_SYS (foo, ...); +- _GL_CXXALIASWARN (foo); +- #elif defined GNULIB_POSIXCHECK +- ... +- #endif +- +- * For providing a replacement for a function that exists on all platforms, +- but is broken/insufficient and needs to be replaced on some platforms: +- +- #if @GNULIB_FOO@ +- # if @REPLACE_FOO@ +- # if !(defined __cplusplus && defined GNULIB_NAMESPACE) +- # undef foo +- # define foo rpl_foo +- # endif +- _GL_FUNCDECL_RPL (foo, ...); +- _GL_CXXALIAS_RPL (foo, ...); +- # else +- _GL_CXXALIAS_SYS (foo, ...); +- # endif +- _GL_CXXALIASWARN (foo); +- #elif defined GNULIB_POSIXCHECK +- ... +- #endif +- +- * For providing a replacement for a function that exists on some platforms +- but is broken/insufficient and needs to be replaced on some of them and +- is additionally either missing or undeclared on some other platforms: +- +- #if @GNULIB_FOO@ +- # if @REPLACE_FOO@ +- # if !(defined __cplusplus && defined GNULIB_NAMESPACE) +- # undef foo +- # define foo rpl_foo +- # endif +- _GL_FUNCDECL_RPL (foo, ...); +- _GL_CXXALIAS_RPL (foo, ...); +- # else +- # if !@HAVE_FOO@ or if !@HAVE_DECL_FOO@ +- _GL_FUNCDECL_SYS (foo, ...); +- # endif +- _GL_CXXALIAS_SYS (foo, ...); +- # endif +- _GL_CXXALIASWARN (foo); +- #elif defined GNULIB_POSIXCHECK +- ... +- #endif +-*/ +- +-/* _GL_EXTERN_C declaration; +- performs the declaration with C linkage. */ +-#if defined __cplusplus +-# define _GL_EXTERN_C extern "C" +-#else +-# define _GL_EXTERN_C extern +-#endif +- +-/* _GL_FUNCDECL_RPL (func, rettype, parameters_and_attributes); +- declares a replacement function, named rpl_func, with the given prototype, +- consisting of return type, parameters, and attributes. +- Example: +- _GL_FUNCDECL_RPL (open, int, (const char *filename, int flags, ...) +- _GL_ARG_NONNULL ((1))); +- */ +-#define _GL_FUNCDECL_RPL(func,rettype,parameters_and_attributes) \ +- _GL_FUNCDECL_RPL_1 (rpl_##func, rettype, parameters_and_attributes) +-#define _GL_FUNCDECL_RPL_1(rpl_func,rettype,parameters_and_attributes) \ +- _GL_EXTERN_C rettype rpl_func parameters_and_attributes +- +-/* _GL_FUNCDECL_SYS (func, rettype, parameters_and_attributes); +- declares the system function, named func, with the given prototype, +- consisting of return type, parameters, and attributes. +- Example: +- _GL_FUNCDECL_SYS (open, int, (const char *filename, int flags, ...) +- _GL_ARG_NONNULL ((1))); +- */ +-#define _GL_FUNCDECL_SYS(func,rettype,parameters_and_attributes) \ +- _GL_EXTERN_C rettype func parameters_and_attributes +- +-/* _GL_CXXALIAS_RPL (func, rettype, parameters); +- declares a C++ alias called GNULIB_NAMESPACE::func +- that redirects to rpl_func, if GNULIB_NAMESPACE is defined. +- Example: +- _GL_CXXALIAS_RPL (open, int, (const char *filename, int flags, ...)); +- */ +-#define _GL_CXXALIAS_RPL(func,rettype,parameters) \ +- _GL_CXXALIAS_RPL_1 (func, rpl_##func, rettype, parameters) +-#if defined __cplusplus && defined GNULIB_NAMESPACE +-# define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \ +- namespace GNULIB_NAMESPACE \ +- { \ +- rettype (*const func) parameters = ::rpl_func; \ +- } \ +- _GL_EXTERN_C int _gl_cxxalias_dummy +-#else +-# define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \ +- _GL_EXTERN_C int _gl_cxxalias_dummy +-#endif +- +-/* _GL_CXXALIAS_RPL_CAST_1 (func, rpl_func, rettype, parameters); +- is like _GL_CXXALIAS_RPL_1 (func, rpl_func, rettype, parameters); +- except that the C function rpl_func may have a slightly different +- declaration. A cast is used to silence the "invalid conversion" error +- that would otherwise occur. */ +-#if defined __cplusplus && defined GNULIB_NAMESPACE +-# define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \ +- namespace GNULIB_NAMESPACE \ +- { \ +- rettype (*const func) parameters = \ +- reinterpret_cast(::rpl_func); \ +- } \ +- _GL_EXTERN_C int _gl_cxxalias_dummy +-#else +-# define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \ +- _GL_EXTERN_C int _gl_cxxalias_dummy +-#endif +- +-/* _GL_CXXALIAS_SYS (func, rettype, parameters); +- declares a C++ alias called GNULIB_NAMESPACE::func +- that redirects to the system provided function func, if GNULIB_NAMESPACE +- is defined. +- Example: +- _GL_CXXALIAS_SYS (open, int, (const char *filename, int flags, ...)); +- */ +-#if defined __cplusplus && defined GNULIB_NAMESPACE +- /* If we were to write +- rettype (*const func) parameters = ::func; +- like above in _GL_CXXALIAS_RPL_1, the compiler could optimize calls +- better (remove an indirection through a 'static' pointer variable), +- but then the _GL_CXXALIASWARN macro below would cause a warning not only +- for uses of ::func but also for uses of GNULIB_NAMESPACE::func. */ +-# define _GL_CXXALIAS_SYS(func,rettype,parameters) \ +- namespace GNULIB_NAMESPACE \ +- { \ +- static rettype (*func) parameters = ::func; \ +- } \ +- _GL_EXTERN_C int _gl_cxxalias_dummy +-#else +-# define _GL_CXXALIAS_SYS(func,rettype,parameters) \ +- _GL_EXTERN_C int _gl_cxxalias_dummy +-#endif +- +-/* _GL_CXXALIAS_SYS_CAST (func, rettype, parameters); +- is like _GL_CXXALIAS_SYS (func, rettype, parameters); +- except that the C function func may have a slightly different declaration. +- A cast is used to silence the "invalid conversion" error that would +- otherwise occur. */ +-#if defined __cplusplus && defined GNULIB_NAMESPACE +-# define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \ +- namespace GNULIB_NAMESPACE \ +- { \ +- static rettype (*func) parameters = \ +- reinterpret_cast(::func); \ +- } \ +- _GL_EXTERN_C int _gl_cxxalias_dummy +-#else +-# define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \ +- _GL_EXTERN_C int _gl_cxxalias_dummy +-#endif +- +-/* _GL_CXXALIAS_SYS_CAST2 (func, rettype, parameters, rettype2, parameters2); +- is like _GL_CXXALIAS_SYS (func, rettype, parameters); +- except that the C function is picked among a set of overloaded functions, +- namely the one with rettype2 and parameters2. Two consecutive casts +- are used to silence the "cannot find a match" and "invalid conversion" +- errors that would otherwise occur. */ +-#if defined __cplusplus && defined GNULIB_NAMESPACE +- /* The outer cast must be a reinterpret_cast. +- The inner cast: When the function is defined as a set of overloaded +- functions, it works as a static_cast<>, choosing the designated variant. +- When the function is defined as a single variant, it works as a +- reinterpret_cast<>. The parenthesized cast syntax works both ways. */ +-# define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \ +- namespace GNULIB_NAMESPACE \ +- { \ +- static rettype (*func) parameters = \ +- reinterpret_cast( \ +- (rettype2(*)parameters2)(::func)); \ +- } \ +- _GL_EXTERN_C int _gl_cxxalias_dummy +-#else +-# define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \ +- _GL_EXTERN_C int _gl_cxxalias_dummy +-#endif +- +-/* _GL_CXXALIASWARN (func); +- causes a warning to be emitted when ::func is used but not when +- GNULIB_NAMESPACE::func is used. func must be defined without overloaded +- variants. */ +-#if defined __cplusplus && defined GNULIB_NAMESPACE +-# define _GL_CXXALIASWARN(func) \ +- _GL_CXXALIASWARN_1 (func, GNULIB_NAMESPACE) +-# define _GL_CXXALIASWARN_1(func,namespace) \ +- _GL_CXXALIASWARN_2 (func, namespace) +-/* To work around GCC bug , +- we enable the warning only when not optimizing. */ +-# if !__OPTIMIZE__ +-# define _GL_CXXALIASWARN_2(func,namespace) \ +- _GL_WARN_ON_USE (func, \ +- "The symbol ::" #func " refers to the system function. " \ +- "Use " #namespace "::" #func " instead.") +-# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING +-# define _GL_CXXALIASWARN_2(func,namespace) \ +- extern __typeof__ (func) func +-# else +-# define _GL_CXXALIASWARN_2(func,namespace) \ +- _GL_EXTERN_C int _gl_cxxalias_dummy +-# endif +-#else +-# define _GL_CXXALIASWARN(func) \ +- _GL_EXTERN_C int _gl_cxxalias_dummy +-#endif +- +-/* _GL_CXXALIASWARN1 (func, rettype, parameters_and_attributes); +- causes a warning to be emitted when the given overloaded variant of ::func +- is used but not when GNULIB_NAMESPACE::func is used. */ +-#if defined __cplusplus && defined GNULIB_NAMESPACE +-# define _GL_CXXALIASWARN1(func,rettype,parameters_and_attributes) \ +- _GL_CXXALIASWARN1_1 (func, rettype, parameters_and_attributes, \ +- GNULIB_NAMESPACE) +-# define _GL_CXXALIASWARN1_1(func,rettype,parameters_and_attributes,namespace) \ +- _GL_CXXALIASWARN1_2 (func, rettype, parameters_and_attributes, namespace) +-/* To work around GCC bug , +- we enable the warning only when not optimizing. */ +-# if !__OPTIMIZE__ +-# define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \ +- _GL_WARN_ON_USE_CXX (func, rettype, parameters_and_attributes, \ +- "The symbol ::" #func " refers to the system function. " \ +- "Use " #namespace "::" #func " instead.") +-# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING +-# define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \ +- extern __typeof__ (func) func +-# else +-# define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \ +- _GL_EXTERN_C int _gl_cxxalias_dummy +-# endif +-#else +-# define _GL_CXXALIASWARN1(func,rettype,parameters_and_attributes) \ +- _GL_EXTERN_C int _gl_cxxalias_dummy +-#endif +- +-#endif /* _GL_CXXDEFS_H */ +diff --git a/build-aux/config.rpath b/build-aux/config.rpath +index c492a93..c38b914 100755 +--- a/build-aux/config.rpath ++++ b/build-aux/config.rpath +@@ -2,7 +2,7 @@ + # Output a system dependent set of variables, describing how to set the + # run time search path of shared libraries in an executable. + # +-# Copyright 1996-2006 Free Software Foundation, Inc. ++# Copyright 1996-2013 Free Software Foundation, Inc. + # Taken from GNU libtool, 2001 + # Originally by Gordon Matzigkeit , 1996 + # +@@ -25,7 +25,7 @@ + # known workaround is to choose shorter directory names for the build + # directory and/or the installation directory. + +-# All known linkers require a `.a' archive for static linking (except MSVC, ++# All known linkers require a '.a' archive for static linking (except MSVC, + # which needs '.lib'). + libext=a + shrext=.so +@@ -47,7 +47,7 @@ for cc_temp in $CC""; do + done + cc_basename=`echo "$cc_temp" | sed -e 's%^.*/%%'` + +-# Code taken from libtool.m4's AC_LIBTOOL_PROG_COMPILER_PIC. ++# Code taken from libtool.m4's _LT_COMPILER_PIC. + + wl= + if test "$GCC" = yes; then +@@ -57,14 +57,7 @@ else + aix*) + wl='-Wl,' + ;; +- darwin*) +- case $cc_basename in +- xlc*) +- wl='-Wl,' +- ;; +- esac +- ;; +- mingw* | pw32* | os2*) ++ mingw* | cygwin* | pw32* | os2* | cegcc*) + ;; + hpux9* | hpux10* | hpux11*) + wl='-Wl,' +@@ -72,24 +65,37 @@ else + irix5* | irix6* | nonstopux*) + wl='-Wl,' + ;; +- newsos6) +- ;; +- linux*) ++ linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in +- icc* | ecc*) ++ ecc*) + wl='-Wl,' + ;; +- pgcc | pgf77 | pgf90) ++ icc* | ifort*) ++ wl='-Wl,' ++ ;; ++ lf95*) ++ wl='-Wl,' ++ ;; ++ nagfor*) ++ wl='-Wl,-Wl,,' ++ ;; ++ pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) + wl='-Wl,' + ;; + ccc*) + wl='-Wl,' + ;; ++ xl* | bgxl* | bgf* | mpixl*) ++ wl='-Wl,' ++ ;; + como) + wl='-lopt=' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in ++ *Sun\ F* | *Sun*Fortran*) ++ wl= ++ ;; + *Sun\ C*) + wl='-Wl,' + ;; +@@ -97,22 +103,36 @@ else + ;; + esac + ;; ++ newsos6) ++ ;; ++ *nto* | *qnx*) ++ ;; + osf3* | osf4* | osf5*) + wl='-Wl,' + ;; +- sco3.2v5*) ++ rdos*) + ;; + solaris*) +- wl='-Wl,' ++ case $cc_basename in ++ f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) ++ wl='-Qoption ld ' ++ ;; ++ *) ++ wl='-Wl,' ++ ;; ++ esac + ;; + sunos4*) + wl='-Qoption ld ' + ;; +- sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) ++ sysv4 | sysv4.2uw2* | sysv4.3*) + wl='-Wl,' + ;; + sysv4*MP*) + ;; ++ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) ++ wl='-Wl,' ++ ;; + unicos*) + wl='-Wl,' + ;; +@@ -121,7 +141,7 @@ else + esac + fi + +-# Code taken from libtool.m4's AC_LIBTOOL_PROG_LD_SHLIBS. ++# Code taken from libtool.m4's _LT_LINKER_SHLIBS. + + hardcode_libdir_flag_spec= + hardcode_libdir_separator= +@@ -129,7 +149,7 @@ hardcode_direct=no + hardcode_minus_L=no + + case "$host_os" in +- cygwin* | mingw* | pw32*) ++ cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. +@@ -155,22 +175,21 @@ if test "$with_gnu_ld" = yes; then + # option of GNU ld is called -rpath, not --rpath. + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + case "$host_os" in +- aix3* | aix4* | aix5*) ++ aix[3-9]*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + ld_shlibs=no + fi + ;; + amigaos*) +- hardcode_libdir_flag_spec='-L$libdir' +- hardcode_minus_L=yes +- # Samuel A. Falvo II reports +- # that the semantics of dynamic libraries on AmigaOS, at least up +- # to version 4, is to share data among multiple programs linked +- # with the same dynamic library. Since this doesn't match the +- # behavior of shared libraries on other platforms, we cannot use +- # them. +- ld_shlibs=no ++ case "$host_cpu" in ++ powerpc) ++ ;; ++ m68k) ++ hardcode_libdir_flag_spec='-L$libdir' ++ hardcode_minus_L=yes ++ ;; ++ esac + ;; + beos*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then +@@ -179,7 +198,7 @@ if test "$with_gnu_ld" = yes; then + ld_shlibs=no + fi + ;; +- cygwin* | mingw* | pw32*) ++ cygwin* | mingw* | pw32* | cegcc*) + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' +@@ -189,11 +208,13 @@ if test "$with_gnu_ld" = yes; then + ld_shlibs=no + fi + ;; +- interix3*) ++ haiku*) ++ ;; ++ interix[3-9]*) + hardcode_direct=no + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + ;; +- linux*) ++ gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + : + else +@@ -251,7 +272,7 @@ else + hardcode_direct=unsupported + fi + ;; +- aix4* | aix5*) ++ aix[4-9]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. +@@ -261,7 +282,7 @@ else + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. +- case $host_os in aix4.[23]|aix4.[23].*|aix5*) ++ case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes +@@ -280,7 +301,7 @@ else + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 +- hardcode_direct=yes ++ : + else + # We have old collect2 + hardcode_direct=unsupported +@@ -316,14 +337,18 @@ else + fi + ;; + amigaos*) +- hardcode_libdir_flag_spec='-L$libdir' +- hardcode_minus_L=yes +- # see comment about different semantics on the GNU ld section +- ld_shlibs=no ++ case "$host_cpu" in ++ powerpc) ++ ;; ++ m68k) ++ hardcode_libdir_flag_spec='-L$libdir' ++ hardcode_minus_L=yes ++ ;; ++ esac + ;; + bsdi[45]*) + ;; +- cygwin* | mingw* | pw32*) ++ cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is +@@ -333,24 +358,15 @@ else + ;; + darwin* | rhapsody*) + hardcode_direct=no +- if test "$GCC" = yes ; then ++ if { case $cc_basename in ifort*) true;; *) test "$GCC" = yes;; esac; }; then + : + else +- case $cc_basename in +- xlc*) +- ;; +- *) +- ld_shlibs=no +- ;; +- esac ++ ld_shlibs=no + fi + ;; + dgux*) + hardcode_libdir_flag_spec='-L$libdir' + ;; +- freebsd1*) +- ld_shlibs=no +- ;; + freebsd2.2*) + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes +@@ -359,7 +375,7 @@ else + hardcode_direct=yes + hardcode_minus_L=yes + ;; +- freebsd* | kfreebsd*-gnu | dragonfly*) ++ freebsd* | dragonfly*) + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + ;; +@@ -411,19 +427,25 @@ else + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; ++ *nto* | *qnx*) ++ ;; + openbsd*) +- hardcode_direct=yes +- if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then +- hardcode_libdir_flag_spec='${wl}-rpath,$libdir' ++ if test -f /usr/libexec/ld.so; then ++ hardcode_direct=yes ++ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then ++ hardcode_libdir_flag_spec='${wl}-rpath,$libdir' ++ else ++ case "$host_os" in ++ openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) ++ hardcode_libdir_flag_spec='-R$libdir' ++ ;; ++ *) ++ hardcode_libdir_flag_spec='${wl}-rpath,$libdir' ++ ;; ++ esac ++ fi + else +- case "$host_os" in +- openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) +- hardcode_libdir_flag_spec='-R$libdir' +- ;; +- *) +- hardcode_libdir_flag_spec='${wl}-rpath,$libdir' +- ;; +- esac ++ ld_shlibs=no + fi + ;; + os2*) +@@ -471,7 +493,7 @@ else + ld_shlibs=yes + fi + ;; +- sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7*) ++ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + ;; + sysv5* | sco3.2v5* | sco5v6*) + hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' +@@ -487,34 +509,58 @@ else + fi + + # Check dynamic linker characteristics +-# Code taken from libtool.m4's AC_LIBTOOL_SYS_DYNAMIC_LINKER. ++# Code taken from libtool.m4's _LT_SYS_DYNAMIC_LINKER. ++# Unlike libtool.m4, here we don't care about _all_ names of the library, but ++# only about the one the linker finds when passed -lNAME. This is the last ++# element of library_names_spec in libtool.m4, or possibly two of them if the ++# linker has special search rules. ++library_names_spec= # the last element of library_names_spec in libtool.m4 + libname_spec='lib$name' + case "$host_os" in + aix3*) ++ library_names_spec='$libname.a' + ;; +- aix4* | aix5*) ++ aix[4-9]*) ++ library_names_spec='$libname$shrext' + ;; + amigaos*) ++ case "$host_cpu" in ++ powerpc*) ++ library_names_spec='$libname$shrext' ;; ++ m68k) ++ library_names_spec='$libname.a' ;; ++ esac + ;; + beos*) ++ library_names_spec='$libname$shrext' + ;; + bsdi[45]*) ++ library_names_spec='$libname$shrext' + ;; +- cygwin* | mingw* | pw32*) ++ cygwin* | mingw* | pw32* | cegcc*) + shrext=.dll ++ library_names_spec='$libname.dll.a $libname.lib' + ;; + darwin* | rhapsody*) + shrext=.dylib ++ library_names_spec='$libname$shrext' + ;; + dgux*) +- ;; +- freebsd1*) +- ;; +- kfreebsd*-gnu) ++ library_names_spec='$libname$shrext' + ;; + freebsd* | dragonfly*) ++ case "$host_os" in ++ freebsd[123]*) ++ library_names_spec='$libname$shrext$versuffix' ;; ++ *) ++ library_names_spec='$libname$shrext' ;; ++ esac + ;; + gnu*) ++ library_names_spec='$libname$shrext' ++ ;; ++ haiku*) ++ library_names_spec='$libname$shrext' + ;; + hpux9* | hpux10* | hpux11*) + case $host_cpu in +@@ -528,10 +574,13 @@ case "$host_os" in + shrext=.sl + ;; + esac ++ library_names_spec='$libname$shrext' + ;; +- interix3*) ++ interix[3-9]*) ++ library_names_spec='$libname$shrext' + ;; + irix5* | irix6* | nonstopux*) ++ library_names_spec='$libname$shrext' + case "$host_os" in + irix5* | nonstopux*) + libsuff= shlibsuff= +@@ -548,41 +597,62 @@ case "$host_os" in + ;; + linux*oldld* | linux*aout* | linux*coff*) + ;; +- linux*) ++ linux* | k*bsd*-gnu | kopensolaris*-gnu) ++ library_names_spec='$libname$shrext' + ;; + knetbsd*-gnu) ++ library_names_spec='$libname$shrext' + ;; + netbsd*) ++ library_names_spec='$libname$shrext' + ;; + newsos6) ++ library_names_spec='$libname$shrext' + ;; +- nto-qnx*) ++ *nto* | *qnx*) ++ library_names_spec='$libname$shrext' + ;; + openbsd*) ++ library_names_spec='$libname$shrext$versuffix' + ;; + os2*) + libname_spec='$name' + shrext=.dll ++ library_names_spec='$libname.a' + ;; + osf3* | osf4* | osf5*) ++ library_names_spec='$libname$shrext' ++ ;; ++ rdos*) + ;; + solaris*) ++ library_names_spec='$libname$shrext' + ;; + sunos4*) ++ library_names_spec='$libname$shrext$versuffix' + ;; + sysv4 | sysv4.3*) ++ library_names_spec='$libname$shrext' + ;; + sysv4*MP*) ++ library_names_spec='$libname$shrext' + ;; + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) ++ library_names_spec='$libname$shrext' ++ ;; ++ tpf*) ++ library_names_spec='$libname$shrext' + ;; + uts4*) ++ library_names_spec='$libname$shrext' + ;; + esac + + sed_quote_subst='s/\(["`$\\]\)/\\\1/g' + escaped_wl=`echo "X$wl" | sed -e 's/^X//' -e "$sed_quote_subst"` + shlibext=`echo "$shrext" | sed -e 's,^\.,,'` ++escaped_libname_spec=`echo "X$libname_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` ++escaped_library_names_spec=`echo "X$library_names_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` + escaped_hardcode_libdir_flag_spec=`echo "X$hardcode_libdir_flag_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` + + LC_ALL=C sed -e 's/^\([a-zA-Z0-9_]*\)=/acl_cv_\1=/' <. */ +- +-/* _GL_WARN_ON_USE (function, "literal string") issues a declaration +- for FUNCTION which will then trigger a compiler warning containing +- the text of "literal string" anywhere that function is called, if +- supported by the compiler. If the compiler does not support this +- feature, the macro expands to an unused extern declaration. +- +- This macro is useful for marking a function as a potential +- portability trap, with the intent that "literal string" include +- instructions on the replacement function that should be used +- instead. However, one of the reasons that a function is a +- portability trap is if it has the wrong signature. Declaring +- FUNCTION with a different signature in C is a compilation error, so +- this macro must use the same type as any existing declaration so +- that programs that avoid the problematic FUNCTION do not fail to +- compile merely because they included a header that poisoned the +- function. But this implies that _GL_WARN_ON_USE is only safe to +- use if FUNCTION is known to already have a declaration. Use of +- this macro implies that there must not be any other macro hiding +- the declaration of FUNCTION; but undefining FUNCTION first is part +- of the poisoning process anyway (although for symbols that are +- provided only via a macro, the result is a compilation error rather +- than a warning containing "literal string"). Also note that in +- C++, it is only safe to use if FUNCTION has no overloads. +- +- For an example, it is possible to poison 'getline' by: +- - adding a call to gl_WARN_ON_USE_PREPARE([[#include ]], +- [getline]) in configure.ac, which potentially defines +- HAVE_RAW_DECL_GETLINE +- - adding this code to a header that wraps the system : +- #undef getline +- #if HAVE_RAW_DECL_GETLINE +- _GL_WARN_ON_USE (getline, "getline is required by POSIX 2008, but" +- "not universally present; use the gnulib module getline"); +- #endif +- +- It is not possible to directly poison global variables. But it is +- possible to write a wrapper accessor function, and poison that +- (less common usage, like &environ, will cause a compilation error +- rather than issue the nice warning, but the end result of informing +- the developer about their portability problem is still achieved): +- #if HAVE_RAW_DECL_ENVIRON +- static inline char ***rpl_environ (void) { return &environ; } +- _GL_WARN_ON_USE (rpl_environ, "environ is not always properly declared"); +- # undef environ +- # define environ (*rpl_environ ()) +- #endif +- */ +-#ifndef _GL_WARN_ON_USE +- +-# if 4 < __GNUC__ || (__GNUC__ == 4 && 3 <= __GNUC_MINOR__) +-/* A compiler attribute is available in gcc versions 4.3.0 and later. */ +-# define _GL_WARN_ON_USE(function, message) \ +-extern __typeof__ (function) function __attribute__ ((__warning__ (message))) +-# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING +-/* Verify the existence of the function. */ +-# define _GL_WARN_ON_USE(function, message) \ +-extern __typeof__ (function) function +-# else /* Unsupported. */ +-# define _GL_WARN_ON_USE(function, message) \ +-_GL_WARN_EXTERN_C int _gl_warn_on_use +-# endif +-#endif +- +-/* _GL_WARN_ON_USE_CXX (function, rettype, parameters_and_attributes, "string") +- is like _GL_WARN_ON_USE (function, "string"), except that the function is +- declared with the given prototype, consisting of return type, parameters, +- and attributes. +- This variant is useful for overloaded functions in C++. _GL_WARN_ON_USE does +- not work in this case. */ +-#ifndef _GL_WARN_ON_USE_CXX +-# if 4 < __GNUC__ || (__GNUC__ == 4 && 3 <= __GNUC_MINOR__) +-# define _GL_WARN_ON_USE_CXX(function,rettype,parameters_and_attributes,msg) \ +-extern rettype function parameters_and_attributes \ +- __attribute__ ((__warning__ (msg))) +-# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING +-/* Verify the existence of the function. */ +-# define _GL_WARN_ON_USE_CXX(function,rettype,parameters_and_attributes,msg) \ +-extern rettype function parameters_and_attributes +-# else /* Unsupported. */ +-# define _GL_WARN_ON_USE_CXX(function,rettype,parameters_and_attributes,msg) \ +-_GL_WARN_EXTERN_C int _gl_warn_on_use +-# endif +-#endif +- +-/* _GL_WARN_EXTERN_C declaration; +- performs the declaration with C linkage. */ +-#ifndef _GL_WARN_EXTERN_C +-# if defined __cplusplus +-# define _GL_WARN_EXTERN_C extern "C" +-# else +-# define _GL_WARN_EXTERN_C extern +-# endif +-#endif +diff --git a/config.h.in b/config.h.in +index 2e1f459..065db78 100644 +--- a/config.h.in ++++ b/config.h.in +@@ -49,4 +49,6 @@ + + #define RE_ENABLE_I18N 1 + ++#define __USE_GNU 1 ++ + #endif +diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def +index fece882..4c8e947 100644 +--- a/grub-core/Makefile.core.def ++++ b/grub-core/Makefile.core.def +@@ -194,7 +194,7 @@ kernel = { + + emu = disk/host.c; + emu = gnulib/progname.c; +- emu = gnulib/error.c; ++ emu = kern/emu/error.c; + emu = kern/emu/cache_s.S; + emu = kern/emu/hostdisk.c; + emu = kern/emu/hostfs.c; +diff --git a/grub-core/gnulib-fix-null-deref.diff b/grub-core/gnulib-fix-null-deref.diff +new file mode 100644 +index 0000000..a2fba8c +--- /dev/null ++++ b/grub-core/gnulib-fix-null-deref.diff +@@ -0,0 +1,13 @@ ++=== modified file 'grub-core/gnulib/argp-parse.c' ++--- grub-core/gnulib/argp-parse.c 2010-04-02 22:45:01 +0000 +++++ grub-core/gnulib/argp-parse.c 2011-04-10 13:25:52 +0000 ++@@ -935,7 +935,7 @@ ++ void * ++ __argp_input (const struct argp *argp, const struct argp_state *state) ++ { ++- if (state) +++ if (state && state->pstate) ++ { ++ struct group *group; ++ struct parser *parser = state->pstate; ++ +diff --git a/grub-core/gnulib-fix-width.diff b/grub-core/gnulib-fix-width.diff +new file mode 100644 +index 0000000..ae77af6 +--- /dev/null ++++ b/grub-core/gnulib-fix-width.diff +@@ -0,0 +1,231 @@ ++diff --git a/lib/argp-fmtstream.c b/lib/argp-fmtstream.c ++index 7aa317c..02406ff 100644 ++--- a/lib/argp-fmtstream.c +++++ b/lib/argp-fmtstream.c ++@@ -29,9 +29,11 @@ ++ #include ++ #include ++ #include +++#include ++ ++ #include "argp-fmtstream.h" ++ #include "argp-namefrob.h" +++#include "mbswidth.h" ++ ++ #ifndef ARGP_FMTSTREAM_USE_LINEWRAP ++ ++@@ -116,6 +118,51 @@ weak_alias (__argp_fmtstream_free, argp_fmtstream_free) ++ #endif ++ #endif ++ +++ +++/* Return the pointer to the first character that doesn't fit in l columns. */ +++static inline const ptrdiff_t +++add_width (const char *ptr, const char *end, size_t l) +++{ +++ mbstate_t ps; +++ const char *ptr0 = ptr; +++ +++ memset (&ps, 0, sizeof (ps)); +++ +++ while (ptr < end) +++ { +++ wchar_t wc; +++ size_t s, k; +++ +++ s = mbrtowc (&wc, ptr, end - ptr, &ps); +++ if (s == (size_t) -1) +++ break; +++ if (s == (size_t) -2) +++ { +++ if (1 >= l) +++ break; +++ l--; +++ ptr++; +++ continue; +++ } +++ +++ if (wc == '\e' && ptr + 3 < end +++ && ptr[1] == '[' && (ptr[2] == '0' || ptr[2] == '1') +++ && ptr[3] == 'm') +++ { +++ ptr += 4; +++ continue; +++ } +++ +++ k = wcwidth (wc); +++ +++ if (k >= l) +++ break; +++ l -= k; +++ ptr += s; +++ } +++ return ptr - ptr0; +++} +++ ++ /* 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 ++@@ -168,14 +215,15 @@ __argp_fmtstream_update (argp_fmtstream_t fs) ++ ++ if (!nl) ++ { +++ size_t display_width = mbsnwidth (buf, fs->p - buf, MBSW_STOP_AT_NUL); ++ /* The buffer ends in a partial line. */ ++ ++- if (fs->point_col + len < fs->rmargin) +++ if (fs->point_col + display_width < 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; +++ fs->point_col += display_width; ++ break; ++ } ++ else ++@@ -183,14 +231,18 @@ __argp_fmtstream_update (argp_fmtstream_t fs) ++ 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; ++- } +++ else +++ { +++ size_t display_width = mbsnwidth (buf, nl - buf, MBSW_STOP_AT_NUL); +++ if (display_width < (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; ++@@ -226,7 +278,7 @@ __argp_fmtstream_update (argp_fmtstream_t fs) ++ char *p, *nextline; ++ int i; ++ ++- p = buf + (r + 1 - fs->point_col); +++ p = buf + add_width (buf, fs->p, (r + 1 - fs->point_col)); ++ while (p >= buf && !isblank ((unsigned char) *p)) ++ --p; ++ nextline = p + 1; /* This will begin the next line. */ ++@@ -244,7 +296,7 @@ __argp_fmtstream_update (argp_fmtstream_t fs) ++ { ++ /* 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); +++ p = buf + add_width (buf, fs->p, (r + 1 - fs->point_col)); ++ /* Find the end of the long word. */ ++ if (p < nl) ++ do ++@@ -278,7 +330,8 @@ __argp_fmtstream_update (argp_fmtstream_t fs) ++ && fs->p > nextline) ++ { ++ /* The margin needs more blanks than we removed. */ ++- if (fs->end - fs->p > fs->wmargin + 1) +++ if (mbsnwidth (fs->p, fs->end - fs->p, MBSW_STOP_AT_NUL) +++ > fs->wmargin + 1) ++ /* Make some space for them. */ ++ { ++ size_t mv = fs->p - nextline; ++diff --git a/lib/argp-help.c b/lib/argp-help.c ++index 354f1e2..2914f47 100644 ++--- a/lib/argp-help.c +++++ b/lib/argp-help.c ++@@ -50,6 +50,7 @@ ++ #include "argp.h" ++ #include "argp-fmtstream.h" ++ #include "argp-namefrob.h" +++#include "mbswidth.h" ++ ++ #ifndef SIZE_MAX ++ # define SIZE_MAX ((size_t) -1) ++@@ -1452,7 +1453,7 @@ argp_args_usage (const struct argp *argp, const struct argp_state *state, ++ ++ /* Manually do line wrapping so that it (probably) won't get wrapped at ++ any embedded spaces. */ ++- space (stream, 1 + nl - cp); +++ space (stream, 1 + mbsnwidth (cp, nl - cp, MBSW_STOP_AT_NUL)); ++ ++ __argp_fmtstream_write (stream, cp, nl - cp); ++ } ++diff --git a/lib/mbswidth.c b/lib/mbswidth.c ++index 7c2dfce..baa4f27 100644 ++--- a/lib/mbswidth.c +++++ b/lib/mbswidth.c ++@@ -90,6 +90,9 @@ mbsnwidth (const char *string, size_t nbytes, int flags) ++ p++; ++ width++; ++ break; +++ case '\0': +++ if (flags & MBSW_STOP_AT_NUL) +++ return width; ++ default: ++ /* If we have a multibyte sequence, scan it up to its end. */ ++ { ++@@ -168,6 +171,9 @@ mbsnwidth (const char *string, size_t nbytes, int flags) ++ { ++ unsigned char c = (unsigned char) *p++; ++ +++ if (c == 0 && (flags & MBSW_STOP_AT_NUL)) +++ return width; +++ ++ if (isprint (c)) ++ { ++ if (width == INT_MAX) ++diff --git a/lib/mbswidth.h b/lib/mbswidth.h ++index e9c0b03..d7207c5 100644 ++--- a/lib/mbswidth.h +++++ b/lib/mbswidth.h ++@@ -45,6 +45,9 @@ extern "C" { ++ control characters and 1 otherwise. */ ++ #define MBSW_REJECT_UNPRINTABLE 2 ++ +++/* If this bit is set \0 is treated as the end of string. +++ Otherwise it's treated as a normal one column width character. */ +++#define MBSW_STOP_AT_NUL 4 ++ ++ /* Returns the number of screen columns needed for STRING. */ ++ #define mbswidth gnu_mbswidth /* avoid clash with UnixWare 7.1.1 function */ ++diff --git a/modules/argp b/modules/argp ++index 125046a..6f14d10 100644 ++--- a/modules/argp +++++ b/modules/argp ++@@ -40,6 +40,7 @@ stdalign ++ strerror ++ memchr ++ memmove +++mbswidth ++ ++ configure.ac: ++ gl_ARGP ++diff --git a/modules/argp-tests b/modules/argp-tests ++index 8f92a4d..0463927 100644 ++--- a/modules/argp-tests +++++ b/modules/argp-tests ++@@ -1,11 +1,13 @@ ++ Files: ++ tests/test-argp.c ++ tests/test-argp-2.sh +++tests/test-argp-2-utf.sh ++ ++ Depends-on: ++ progname ++ ++ Makefile.am: ++ TESTS += test-argp test-argp-2.sh ++-check_PROGRAMS += test-argp +++TESTS += test-argp test-argp-2.sh test-argp-2-utf.sh +++check_PROGRAMS += test-argp test-argp-utf8 ++ test_argp_LDADD = $(LDADD) @LIBINTL@ +diff --git a/grub-core/gnulib-no-abort.diff b/grub-core/gnulib-no-abort.diff +new file mode 100644 +index 0000000..8377338 +--- /dev/null ++++ b/grub-core/gnulib-no-abort.diff +@@ -0,0 +1,30 @@ ++=== modified file 'grub-core/gnulib/regcomp.c' ++--- grub-core/gnulib/regcomp.c 2010-09-20 10:35:33 +0000 +++++ grub-core/gnulib/regcomp.c 2012-03-10 11:31:42 +0000 ++@@ -549,13 +549,9 @@ regerror (int errcode, const regex_t *_R ++ 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 = gettext ("unknown regexp error"); +++ else +++ msg = gettext (__re_error_msgid + __re_error_msgid_idx[errcode]); ++ ++ msg_size = strlen (msg) + 1; /* Includes the null. */ ++ ++@@ -1119,7 +1119,7 @@ ++ } ++ break; ++ default: ++- abort (); +++ break; ++ } ++ ++ if (mb_chars || has_period) ++ +diff --git a/grub-core/gnulib-no-gets.diff b/grub-core/gnulib-no-gets.diff +new file mode 100644 +index 0000000..1a9487e +--- /dev/null ++++ b/grub-core/gnulib-no-gets.diff +@@ -0,0 +1,10 @@ ++--- /tmp/x.diff 2013-04-11 16:51:42.777873536 +0200 +++++ grub-core/gnulib/stdio.in.h 2013-04-11 16:51:49.917873298 +0200 ++@@ -700,7 +700,6 @@ ++ removed it. */ ++ #undef gets ++ #if HAVE_RAW_DECL_GETS ++-_GL_WARN_ON_USE (gets, "gets is a security hole - use fgets instead"); ++ #endif ++ ++ +diff --git a/grub-core/gnulib/Makefile.am b/grub-core/gnulib/Makefile.am +index fb1525f..3444397 100644 +--- a/grub-core/gnulib/Makefile.am ++++ b/grub-core/gnulib/Makefile.am +@@ -1,17 +1,29 @@ + ## DO NOT EDIT! GENERATED AUTOMATICALLY! + ## Process this file with automake to produce Makefile.in. +-# Copyright (C) 2002-2010 Free Software Foundation, Inc. ++# Copyright (C) 2002-2013 Free Software Foundation, Inc. + # +-# This file is free software, distributed under the terms of the GNU +-# General Public License. As a special exception to the GNU General +-# Public License, this file may be distributed as part of a program +-# that contains a configuration script generated by Autoconf, under ++# This file 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 file 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 file. If not, see . ++# ++# As a special exception to the GNU General Public License, ++# this file may be distributed as part of a program that ++# contains a configuration script generated by Autoconf, under + # the same distribution terms as the rest of that program. + # + # Generated by gnulib-tool. +-# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=grub-core/gnulib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --no-libtool --macro-prefix=gl --no-vc-files argp error fnmatch getdelim getline gettext progname regex ++# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=grub-core/gnulib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --no-conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files argp error fnmatch getdelim getline gettext progname regex + +-AUTOMAKE_OPTIONS = 1.5 gnits ++AUTOMAKE_OPTIONS = 1.5 gnits subdir-objects + + SUBDIRS = + noinst_HEADERS = +@@ -39,12 +51,12 @@ EXTRA_libgnu_a_SOURCES = + ## begin gnulib module alloca + + ++libgnu_a_LIBADD += @ALLOCA@ ++libgnu_a_DEPENDENCIES += @ALLOCA@ + EXTRA_DIST += alloca.c + + EXTRA_libgnu_a_SOURCES += alloca.c + +-libgnu_a_LIBADD += @ALLOCA@ +-libgnu_a_DEPENDENCIES += @ALLOCA@ + ## end gnulib module alloca + + ## begin gnulib module alloca-opt +@@ -53,42 +65,23 @@ BUILT_SOURCES += $(ALLOCA_H) + + # We need the following in order to create when the system + # doesn't have one that works with the given compiler. +-alloca.h: alloca.in.h ++if GL_GENERATE_ALLOCA_H ++alloca.h: alloca.in.h $(top_builddir)/config.status + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ + cat $(srcdir)/alloca.in.h; \ + } > $@-t && \ + mv -f $@-t $@ ++else ++alloca.h: $(top_builddir)/config.status ++ rm -f $@ ++endif + MOSTLYCLEANFILES += alloca.h alloca.h-t + + EXTRA_DIST += alloca.in.h + + ## end gnulib module alloca-opt + +-## begin gnulib module arg-nonnull +- +-# The BUILT_SOURCES created by this Makefile snippet are not used via #include +-# statements but through direct file reference. Therefore this snippet must be +-# present in all Makefile.am that need it. This is ensured by the applicability +-# 'all' defined above. +- +-BUILT_SOURCES += arg-nonnull.h +-# The arg-nonnull.h that gets inserted into generated .h files is the same as +-# build-aux/arg-nonnull.h, except that it has the copyright header cut off. +-arg-nonnull.h: $(top_srcdir)/build-aux/arg-nonnull.h +- $(AM_V_GEN)rm -f $@-t $@ && \ +- sed -n -e '/GL_ARG_NONNULL/,$$p' \ +- < $(top_srcdir)/build-aux/arg-nonnull.h \ +- > $@-t && \ +- mv $@-t $@ +-MOSTLYCLEANFILES += arg-nonnull.h arg-nonnull.h-t +- +-ARG_NONNULL_H=arg-nonnull.h +- +-EXTRA_DIST += $(top_srcdir)/build-aux/arg-nonnull.h +- +-## end gnulib module arg-nonnull +- + ## begin gnulib module argp + + libgnu_a_SOURCES += argp.h argp-ba.c argp-eexst.c \ +@@ -107,47 +100,10 @@ EXTRA_libgnu_a_SOURCES += btowc.c + + ## end gnulib module btowc + +-## begin gnulib module c++defs +- +-# The BUILT_SOURCES created by this Makefile snippet are not used via #include +-# statements but through direct file reference. Therefore this snippet must be +-# present in all Makefile.am that need it. This is ensured by the applicability +-# 'all' defined above. +- +-BUILT_SOURCES += c++defs.h +-# The c++defs.h that gets inserted into generated .h files is the same as +-# build-aux/c++defs.h, except that it has the copyright header cut off. +-c++defs.h: $(top_srcdir)/build-aux/c++defs.h +- $(AM_V_GEN)rm -f $@-t $@ && \ +- sed -n -e '/_GL_CXXDEFS/,$$p' \ +- < $(top_srcdir)/build-aux/c++defs.h \ +- > $@-t && \ +- mv $@-t $@ +-MOSTLYCLEANFILES += c++defs.h c++defs.h-t +- +-CXXDEFS_H=c++defs.h +- +-EXTRA_DIST += $(top_srcdir)/build-aux/c++defs.h +- +-## end gnulib module c++defs +- + ## begin gnulib module configmake + +-# Retrieve values of the variables through 'configure' followed by +-# 'make', not directly through 'configure', so that a user who +-# sets some of these variables consistently on the 'make' command +-# line gets correct results. +-# +-# One advantage of this approach, compared to the classical +-# approach of adding -DLIBDIR=\"$(libdir)\" etc. to AM_CPPFLAGS, +-# is that it protects against the use of undefined variables. +-# If, say, $(libdir) is not set in the Makefile, LIBDIR is not +-# defined by this module, and code using LIBDIR gives a +-# compilation error. +-# +-# Another advantage is that 'make' output is shorter. +-# +-# Listed in the same order as the GNU makefile conventions. ++# Listed in the same order as the GNU makefile conventions, and ++# provided by autoconf 2.59c+. + # The Automake-defined pkg* macros are appended, in the order + # listed in the Automake 1.10a+ documentation. + configmake.h: Makefile +@@ -181,11 +137,7 @@ configmake.h: Makefile + echo '#define PKGLIBDIR "$(pkglibdir)"'; \ + echo '#define PKGLIBEXECDIR "$(pkglibexecdir)"'; \ + } | sed '/""/d' > $@-t && \ +- if test -f $@ && cmp $@-t $@ > /dev/null; then \ +- rm -f $@-t; \ +- else \ +- rm -f $@; mv $@-t $@; \ +- fi ++ mv -f $@-t $@ + + BUILT_SOURCES += configmake.h + CLEANFILES += configmake.h configmake.h-t +@@ -194,24 +146,33 @@ CLEANFILES += configmake.h configmake.h-t + + ## begin gnulib module dirname-lgpl + ++libgnu_a_SOURCES += dirname-lgpl.c basename-lgpl.c stripslash.c + +-EXTRA_DIST += basename-lgpl.c dirname-lgpl.c dirname.h stripslash.c +- +-EXTRA_libgnu_a_SOURCES += basename-lgpl.c dirname-lgpl.c stripslash.c ++EXTRA_DIST += dirname.h + + ## end gnulib module dirname-lgpl + ++## begin gnulib module dosname ++ ++ ++EXTRA_DIST += dosname.h ++ ++## end gnulib module dosname ++ + ## begin gnulib module errno + + BUILT_SOURCES += $(ERRNO_H) + + # We need the following in order to create when the system + # doesn't have one that is POSIX compliant. +-errno.h: errno.in.h ++if GL_GENERATE_ERRNO_H ++errno.h: errno.in.h $(top_builddir)/config.status + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ +- sed -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ ++ sed -e 's|@''GUARD_PREFIX''@|GL|g' \ ++ -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ ++ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ + -e 's|@''NEXT_ERRNO_H''@|$(NEXT_ERRNO_H)|g' \ + -e 's|@''EMULTIHOP_HIDDEN''@|$(EMULTIHOP_HIDDEN)|g' \ + -e 's|@''EMULTIHOP_VALUE''@|$(EMULTIHOP_VALUE)|g' \ +@@ -222,6 +183,10 @@ errno.h: errno.in.h + < $(srcdir)/errno.in.h; \ + } > $@-t && \ + mv $@-t $@ ++else ++errno.h: $(top_builddir)/config.status ++ rm -f $@ ++endif + MOSTLYCLEANFILES += errno.h errno.h-t + + EXTRA_DIST += errno.in.h +@@ -243,18 +208,28 @@ BUILT_SOURCES += $(FLOAT_H) + + # We need the following in order to create when the system + # doesn't have one that works with the given compiler. +-float.h: float.in.h ++if GL_GENERATE_FLOAT_H ++float.h: float.in.h $(top_builddir)/config.status + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ +- sed -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ ++ sed -e 's|@''GUARD_PREFIX''@|GL|g' \ ++ -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ ++ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ + -e 's|@''NEXT_FLOAT_H''@|$(NEXT_FLOAT_H)|g' \ ++ -e 's|@''REPLACE_ITOLD''@|$(REPLACE_ITOLD)|g' \ + < $(srcdir)/float.in.h; \ + } > $@-t && \ + mv $@-t $@ ++else ++float.h: $(top_builddir)/config.status ++ rm -f $@ ++endif + MOSTLYCLEANFILES += float.h float.h-t + +-EXTRA_DIST += float.in.h ++EXTRA_DIST += float.c float.in.h itold.c ++ ++EXTRA_libgnu_a_SOURCES += float.c itold.c + + ## end gnulib module float + +@@ -264,13 +239,18 @@ BUILT_SOURCES += $(FNMATCH_H) + + # We need the following in order to create when the system + # doesn't have one that supports the required API. +-fnmatch.h: fnmatch.in.h $(ARG_NONNULL_H) ++if GL_GENERATE_FNMATCH_H ++fnmatch.h: fnmatch.in.h $(top_builddir)/config.status $(ARG_NONNULL_H) + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ + sed -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ + < $(srcdir)/fnmatch.in.h; \ + } > $@-t && \ + mv -f $@-t $@ ++else ++fnmatch.h: $(top_builddir)/config.status ++ rm -f $@ ++endif + MOSTLYCLEANFILES += fnmatch.h fnmatch.h-t + + EXTRA_DIST += fnmatch.c fnmatch.in.h fnmatch_loop.c +@@ -303,12 +283,14 @@ BUILT_SOURCES += $(GETOPT_H) + + # We need the following in order to create when the system + # doesn't have one that works with the given compiler. +-getopt.h: getopt.in.h $(ARG_NONNULL_H) ++getopt.h: getopt.in.h $(top_builddir)/config.status $(ARG_NONNULL_H) + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ +- sed -e 's|@''HAVE_GETOPT_H''@|$(HAVE_GETOPT_H)|g' \ ++ sed -e 's|@''GUARD_PREFIX''@|GL|g' \ ++ -e 's|@''HAVE_GETOPT_H''@|$(HAVE_GETOPT_H)|g' \ + -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ ++ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ + -e 's|@''NEXT_GETOPT_H''@|$(NEXT_GETOPT_H)|g' \ + -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ + < $(srcdir)/getopt.in.h; \ +@@ -364,14 +346,16 @@ BUILT_SOURCES += langinfo.h + + # We need the following in order to create an empty placeholder for + # when the system doesn't have one. +-langinfo.h: langinfo.in.h $(CXXDEFS_H) $(WARN_ON_USE_H) ++langinfo.h: langinfo.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_ON_USE_H) + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ +- sed -e 's|@''HAVE_LANGINFO_H''@|$(HAVE_LANGINFO_H)|g' \ ++ sed -e 's|@''GUARD_PREFIX''@|GL|g' \ ++ -e 's|@''HAVE_LANGINFO_H''@|$(HAVE_LANGINFO_H)|g' \ + -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ ++ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ + -e 's|@''NEXT_LANGINFO_H''@|$(NEXT_LANGINFO_H)|g' \ +- -e 's|@''GNULIB_NL_LANGINFO''@|$(GNULIB_NL_LANGINFO)|g' \ ++ -e 's/@''GNULIB_NL_LANGINFO''@/$(GNULIB_NL_LANGINFO)/g' \ + -e 's|@''HAVE_LANGINFO_CODESET''@|$(HAVE_LANGINFO_CODESET)|g' \ + -e 's|@''HAVE_LANGINFO_T_FMT_AMPM''@|$(HAVE_LANGINFO_T_FMT_AMPM)|g' \ + -e 's|@''HAVE_LANGINFO_ERA''@|$(HAVE_LANGINFO_ERA)|g' \ +@@ -463,6 +447,50 @@ EXTRA_DIST += config.charset ref-add.sin ref-del.sin + + ## end gnulib module localcharset + ++## begin gnulib module locale ++ ++BUILT_SOURCES += locale.h ++ ++# We need the following in order to create when the system ++# doesn't have one that provides all definitions. ++locale.h: locale.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) ++ $(AM_V_GEN)rm -f $@-t $@ && \ ++ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ ++ sed -e 's|@''GUARD_PREFIX''@|GL|g' \ ++ -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ ++ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ ++ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ ++ -e 's|@''NEXT_LOCALE_H''@|$(NEXT_LOCALE_H)|g' \ ++ -e 's/@''GNULIB_LOCALECONV''@/$(GNULIB_LOCALECONV)/g' \ ++ -e 's/@''GNULIB_SETLOCALE''@/$(GNULIB_SETLOCALE)/g' \ ++ -e 's/@''GNULIB_DUPLOCALE''@/$(GNULIB_DUPLOCALE)/g' \ ++ -e 's|@''HAVE_DUPLOCALE''@|$(HAVE_DUPLOCALE)|g' \ ++ -e 's|@''HAVE_XLOCALE_H''@|$(HAVE_XLOCALE_H)|g' \ ++ -e 's|@''REPLACE_LOCALECONV''@|$(REPLACE_LOCALECONV)|g' \ ++ -e 's|@''REPLACE_SETLOCALE''@|$(REPLACE_SETLOCALE)|g' \ ++ -e 's|@''REPLACE_DUPLOCALE''@|$(REPLACE_DUPLOCALE)|g' \ ++ -e 's|@''REPLACE_STRUCT_LCONV''@|$(REPLACE_STRUCT_LCONV)|g' \ ++ -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ ++ -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ ++ -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ ++ < $(srcdir)/locale.in.h; \ ++ } > $@-t && \ ++ mv $@-t $@ ++MOSTLYCLEANFILES += locale.h locale.h-t ++ ++EXTRA_DIST += locale.in.h ++ ++## end gnulib module locale ++ ++## begin gnulib module localeconv ++ ++ ++EXTRA_DIST += localeconv.c ++ ++EXTRA_libgnu_a_SOURCES += localeconv.c ++ ++## end gnulib module localeconv ++ + ## begin gnulib module malloc-gnu + + +@@ -502,12 +530,27 @@ EXTRA_libgnu_a_SOURCES += mbsinit.c + ## begin gnulib module mbsrtowcs + + +-EXTRA_DIST += mbsrtowcs-state.c mbsrtowcs.c ++EXTRA_DIST += mbsrtowcs-impl.h mbsrtowcs-state.c mbsrtowcs.c + + EXTRA_libgnu_a_SOURCES += mbsrtowcs-state.c mbsrtowcs.c + + ## end gnulib module mbsrtowcs + ++## begin gnulib module mbswidth ++ ++libgnu_a_SOURCES += mbswidth.h mbswidth.c ++ ++## end gnulib module mbswidth ++ ++## begin gnulib module mbtowc ++ ++ ++EXTRA_DIST += mbtowc-impl.h mbtowc.c ++ ++EXTRA_libgnu_a_SOURCES += mbtowc.c ++ ++## end gnulib module mbtowc ++ + ## begin gnulib module memchr + + +@@ -526,6 +569,24 @@ EXTRA_libgnu_a_SOURCES += mempcpy.c + + ## end gnulib module mempcpy + ++## begin gnulib module msvc-inval ++ ++ ++EXTRA_DIST += msvc-inval.c msvc-inval.h ++ ++EXTRA_libgnu_a_SOURCES += msvc-inval.c ++ ++## end gnulib module msvc-inval ++ ++## begin gnulib module msvc-nothrow ++ ++ ++EXTRA_DIST += msvc-nothrow.c msvc-nothrow.h ++ ++EXTRA_libgnu_a_SOURCES += msvc-nothrow.c ++ ++## end gnulib module msvc-nothrow ++ + ## begin gnulib module nl_langinfo + + +@@ -583,18 +644,127 @@ EXTRA_libgnu_a_SOURCES += sleep.c + + ## end gnulib module sleep + ++## begin gnulib module snippet/_Noreturn ++ ++# Because this Makefile snippet defines a variable used by other ++# gnulib Makefile snippets, it must be present in all Makefile.am that ++# need it. This is ensured by the applicability 'all' defined above. ++ ++_NORETURN_H=$(top_srcdir)/build-aux/snippet/_Noreturn.h ++ ++EXTRA_DIST += $(top_srcdir)/build-aux/snippet/_Noreturn.h ++ ++## end gnulib module snippet/_Noreturn ++ ++## begin gnulib module snippet/arg-nonnull ++ ++# The BUILT_SOURCES created by this Makefile snippet are not used via #include ++# statements but through direct file reference. Therefore this snippet must be ++# present in all Makefile.am that need it. This is ensured by the applicability ++# 'all' defined above. ++ ++BUILT_SOURCES += arg-nonnull.h ++# The arg-nonnull.h that gets inserted into generated .h files is the same as ++# build-aux/snippet/arg-nonnull.h, except that it has the copyright header cut ++# off. ++arg-nonnull.h: $(top_srcdir)/build-aux/snippet/arg-nonnull.h ++ $(AM_V_GEN)rm -f $@-t $@ && \ ++ sed -n -e '/GL_ARG_NONNULL/,$$p' \ ++ < $(top_srcdir)/build-aux/snippet/arg-nonnull.h \ ++ > $@-t && \ ++ mv $@-t $@ ++MOSTLYCLEANFILES += arg-nonnull.h arg-nonnull.h-t ++ ++ARG_NONNULL_H=arg-nonnull.h ++ ++EXTRA_DIST += $(top_srcdir)/build-aux/snippet/arg-nonnull.h ++ ++## end gnulib module snippet/arg-nonnull ++ ++## begin gnulib module snippet/c++defs ++ ++# The BUILT_SOURCES created by this Makefile snippet are not used via #include ++# statements but through direct file reference. Therefore this snippet must be ++# present in all Makefile.am that need it. This is ensured by the applicability ++# 'all' defined above. ++ ++BUILT_SOURCES += c++defs.h ++# The c++defs.h that gets inserted into generated .h files is the same as ++# build-aux/snippet/c++defs.h, except that it has the copyright header cut off. ++c++defs.h: $(top_srcdir)/build-aux/snippet/c++defs.h ++ $(AM_V_GEN)rm -f $@-t $@ && \ ++ sed -n -e '/_GL_CXXDEFS/,$$p' \ ++ < $(top_srcdir)/build-aux/snippet/c++defs.h \ ++ > $@-t && \ ++ mv $@-t $@ ++MOSTLYCLEANFILES += c++defs.h c++defs.h-t ++ ++CXXDEFS_H=c++defs.h ++ ++EXTRA_DIST += $(top_srcdir)/build-aux/snippet/c++defs.h ++ ++## end gnulib module snippet/c++defs ++ ++## begin gnulib module snippet/warn-on-use ++ ++BUILT_SOURCES += warn-on-use.h ++# The warn-on-use.h that gets inserted into generated .h files is the same as ++# build-aux/snippet/warn-on-use.h, except that it has the copyright header cut ++# off. ++warn-on-use.h: $(top_srcdir)/build-aux/snippet/warn-on-use.h ++ $(AM_V_GEN)rm -f $@-t $@ && \ ++ sed -n -e '/^.ifndef/,$$p' \ ++ < $(top_srcdir)/build-aux/snippet/warn-on-use.h \ ++ > $@-t && \ ++ mv $@-t $@ ++MOSTLYCLEANFILES += warn-on-use.h warn-on-use.h-t ++ ++WARN_ON_USE_H=warn-on-use.h ++ ++EXTRA_DIST += $(top_srcdir)/build-aux/snippet/warn-on-use.h ++ ++## end gnulib module snippet/warn-on-use ++ ++## begin gnulib module stdalign ++ ++BUILT_SOURCES += $(STDALIGN_H) ++ ++# We need the following in order to create when the system ++# doesn't have one that works. ++if GL_GENERATE_STDALIGN_H ++stdalign.h: stdalign.in.h $(top_builddir)/config.status ++ $(AM_V_GEN)rm -f $@-t $@ && \ ++ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ ++ cat $(srcdir)/stdalign.in.h; \ ++ } > $@-t && \ ++ mv $@-t $@ ++else ++stdalign.h: $(top_builddir)/config.status ++ rm -f $@ ++endif ++MOSTLYCLEANFILES += stdalign.h stdalign.h-t ++ ++EXTRA_DIST += stdalign.in.h ++ ++## end gnulib module stdalign ++ + ## begin gnulib module stdbool + + BUILT_SOURCES += $(STDBOOL_H) + + # We need the following in order to create when the system + # doesn't have one that works. +-stdbool.h: stdbool.in.h ++if GL_GENERATE_STDBOOL_H ++stdbool.h: stdbool.in.h $(top_builddir)/config.status + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ + sed -e 's/@''HAVE__BOOL''@/$(HAVE__BOOL)/g' < $(srcdir)/stdbool.in.h; \ + } > $@-t && \ + mv $@-t $@ ++else ++stdbool.h: $(top_builddir)/config.status ++ rm -f $@ ++endif + MOSTLYCLEANFILES += stdbool.h stdbool.h-t + + EXTRA_DIST += stdbool.in.h +@@ -607,17 +777,24 @@ BUILT_SOURCES += $(STDDEF_H) + + # We need the following in order to create when the system + # doesn't have one that works with the given compiler. +-stddef.h: stddef.in.h ++if GL_GENERATE_STDDEF_H ++stddef.h: stddef.in.h $(top_builddir)/config.status + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ +- sed -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ ++ sed -e 's|@''GUARD_PREFIX''@|GL|g' \ ++ -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ ++ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ + -e 's|@''NEXT_STDDEF_H''@|$(NEXT_STDDEF_H)|g' \ + -e 's|@''HAVE_WCHAR_T''@|$(HAVE_WCHAR_T)|g' \ + -e 's|@''REPLACE_NULL''@|$(REPLACE_NULL)|g' \ + < $(srcdir)/stddef.in.h; \ + } > $@-t && \ + mv $@-t $@ ++else ++stddef.h: $(top_builddir)/config.status ++ rm -f $@ ++endif + MOSTLYCLEANFILES += stddef.h stddef.h-t + + EXTRA_DIST += stddef.in.h +@@ -630,17 +807,21 @@ BUILT_SOURCES += $(STDINT_H) + + # We need the following in order to create when the system + # doesn't have one that works with the given compiler. +-stdint.h: stdint.in.h ++if GL_GENERATE_STDINT_H ++stdint.h: stdint.in.h $(top_builddir)/config.status + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ +- sed -e 's/@''HAVE_STDINT_H''@/$(HAVE_STDINT_H)/g' \ ++ sed -e 's|@''GUARD_PREFIX''@|GL|g' \ ++ -e 's/@''HAVE_STDINT_H''@/$(HAVE_STDINT_H)/g' \ + -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ ++ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ + -e 's|@''NEXT_STDINT_H''@|$(NEXT_STDINT_H)|g' \ + -e 's/@''HAVE_SYS_TYPES_H''@/$(HAVE_SYS_TYPES_H)/g' \ + -e 's/@''HAVE_INTTYPES_H''@/$(HAVE_INTTYPES_H)/g' \ + -e 's/@''HAVE_SYS_INTTYPES_H''@/$(HAVE_SYS_INTTYPES_H)/g' \ + -e 's/@''HAVE_SYS_BITYPES_H''@/$(HAVE_SYS_BITYPES_H)/g' \ ++ -e 's/@''HAVE_WCHAR_H''@/$(HAVE_WCHAR_H)/g' \ + -e 's/@''HAVE_LONG_LONG_INT''@/$(HAVE_LONG_LONG_INT)/g' \ + -e 's/@''HAVE_UNSIGNED_LONG_LONG_INT''@/$(HAVE_UNSIGNED_LONG_LONG_INT)/g' \ + -e 's/@''APPLE_UNIVERSAL_BUILD''@/$(APPLE_UNIVERSAL_BUILD)/g' \ +@@ -660,6 +841,10 @@ stdint.h: stdint.in.h + < $(srcdir)/stdint.in.h; \ + } > $@-t && \ + mv $@-t $@ ++else ++stdint.h: $(top_builddir)/config.status ++ rm -f $@ ++endif + MOSTLYCLEANFILES += stdint.h stdint.h-t + + EXTRA_DIST += stdint.in.h +@@ -672,55 +857,71 @@ BUILT_SOURCES += stdio.h + + # We need the following in order to create when the system + # doesn't have one that works with the given compiler. +-stdio.h: stdio.in.h $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) ++stdio.h: stdio.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ +- sed -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ ++ sed -e 's|@''GUARD_PREFIX''@|GL|g' \ ++ -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ ++ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ + -e 's|@''NEXT_STDIO_H''@|$(NEXT_STDIO_H)|g' \ +- -e 's|@''GNULIB_DPRINTF''@|$(GNULIB_DPRINTF)|g' \ +- -e 's|@''GNULIB_FCLOSE''@|$(GNULIB_FCLOSE)|g' \ +- -e 's|@''GNULIB_FFLUSH''@|$(GNULIB_FFLUSH)|g' \ +- -e 's|@''GNULIB_FOPEN''@|$(GNULIB_FOPEN)|g' \ +- -e 's|@''GNULIB_FPRINTF''@|$(GNULIB_FPRINTF)|g' \ +- -e 's|@''GNULIB_FPRINTF_POSIX''@|$(GNULIB_FPRINTF_POSIX)|g' \ +- -e 's|@''GNULIB_FPURGE''@|$(GNULIB_FPURGE)|g' \ +- -e 's|@''GNULIB_FPUTC''@|$(GNULIB_FPUTC)|g' \ +- -e 's|@''GNULIB_FPUTS''@|$(GNULIB_FPUTS)|g' \ +- -e 's|@''GNULIB_FREOPEN''@|$(GNULIB_FREOPEN)|g' \ +- -e 's|@''GNULIB_FSEEK''@|$(GNULIB_FSEEK)|g' \ +- -e 's|@''GNULIB_FSEEKO''@|$(GNULIB_FSEEKO)|g' \ +- -e 's|@''GNULIB_FTELL''@|$(GNULIB_FTELL)|g' \ +- -e 's|@''GNULIB_FTELLO''@|$(GNULIB_FTELLO)|g' \ +- -e 's|@''GNULIB_FWRITE''@|$(GNULIB_FWRITE)|g' \ +- -e 's|@''GNULIB_GETDELIM''@|$(GNULIB_GETDELIM)|g' \ +- -e 's|@''GNULIB_GETLINE''@|$(GNULIB_GETLINE)|g' \ +- -e 's|@''GNULIB_OBSTACK_PRINTF''@|$(GNULIB_OBSTACK_PRINTF)|g' \ +- -e 's|@''GNULIB_OBSTACK_PRINTF_POSIX''@|$(GNULIB_OBSTACK_PRINTF_POSIX)|g' \ +- -e 's|@''GNULIB_PERROR''@|$(GNULIB_PERROR)|g' \ +- -e 's|@''GNULIB_POPEN''@|$(GNULIB_POPEN)|g' \ +- -e 's|@''GNULIB_PRINTF''@|$(GNULIB_PRINTF)|g' \ +- -e 's|@''GNULIB_PRINTF_POSIX''@|$(GNULIB_PRINTF_POSIX)|g' \ +- -e 's|@''GNULIB_PUTC''@|$(GNULIB_PUTC)|g' \ +- -e 's|@''GNULIB_PUTCHAR''@|$(GNULIB_PUTCHAR)|g' \ +- -e 's|@''GNULIB_PUTS''@|$(GNULIB_PUTS)|g' \ +- -e 's|@''GNULIB_REMOVE''@|$(GNULIB_REMOVE)|g' \ +- -e 's|@''GNULIB_RENAME''@|$(GNULIB_RENAME)|g' \ +- -e 's|@''GNULIB_RENAMEAT''@|$(GNULIB_RENAMEAT)|g' \ +- -e 's|@''GNULIB_SNPRINTF''@|$(GNULIB_SNPRINTF)|g' \ +- -e 's|@''GNULIB_SPRINTF_POSIX''@|$(GNULIB_SPRINTF_POSIX)|g' \ +- -e 's|@''GNULIB_STDIO_H_SIGPIPE''@|$(GNULIB_STDIO_H_SIGPIPE)|g' \ +- -e 's|@''GNULIB_TMPFILE''@|$(GNULIB_TMPFILE)|g' \ +- -e 's|@''GNULIB_VASPRINTF''@|$(GNULIB_VASPRINTF)|g' \ +- -e 's|@''GNULIB_VDPRINTF''@|$(GNULIB_VDPRINTF)|g' \ +- -e 's|@''GNULIB_VFPRINTF''@|$(GNULIB_VFPRINTF)|g' \ +- -e 's|@''GNULIB_VFPRINTF_POSIX''@|$(GNULIB_VFPRINTF_POSIX)|g' \ +- -e 's|@''GNULIB_VPRINTF''@|$(GNULIB_VPRINTF)|g' \ +- -e 's|@''GNULIB_VPRINTF_POSIX''@|$(GNULIB_VPRINTF_POSIX)|g' \ +- -e 's|@''GNULIB_VSNPRINTF''@|$(GNULIB_VSNPRINTF)|g' \ +- -e 's|@''GNULIB_VSPRINTF_POSIX''@|$(GNULIB_VSPRINTF_POSIX)|g' \ ++ -e 's/@''GNULIB_DPRINTF''@/$(GNULIB_DPRINTF)/g' \ ++ -e 's/@''GNULIB_FCLOSE''@/$(GNULIB_FCLOSE)/g' \ ++ -e 's/@''GNULIB_FDOPEN''@/$(GNULIB_FDOPEN)/g' \ ++ -e 's/@''GNULIB_FFLUSH''@/$(GNULIB_FFLUSH)/g' \ ++ -e 's/@''GNULIB_FGETC''@/$(GNULIB_FGETC)/g' \ ++ -e 's/@''GNULIB_FGETS''@/$(GNULIB_FGETS)/g' \ ++ -e 's/@''GNULIB_FOPEN''@/$(GNULIB_FOPEN)/g' \ ++ -e 's/@''GNULIB_FPRINTF''@/$(GNULIB_FPRINTF)/g' \ ++ -e 's/@''GNULIB_FPRINTF_POSIX''@/$(GNULIB_FPRINTF_POSIX)/g' \ ++ -e 's/@''GNULIB_FPURGE''@/$(GNULIB_FPURGE)/g' \ ++ -e 's/@''GNULIB_FPUTC''@/$(GNULIB_FPUTC)/g' \ ++ -e 's/@''GNULIB_FPUTS''@/$(GNULIB_FPUTS)/g' \ ++ -e 's/@''GNULIB_FREAD''@/$(GNULIB_FREAD)/g' \ ++ -e 's/@''GNULIB_FREOPEN''@/$(GNULIB_FREOPEN)/g' \ ++ -e 's/@''GNULIB_FSCANF''@/$(GNULIB_FSCANF)/g' \ ++ -e 's/@''GNULIB_FSEEK''@/$(GNULIB_FSEEK)/g' \ ++ -e 's/@''GNULIB_FSEEKO''@/$(GNULIB_FSEEKO)/g' \ ++ -e 's/@''GNULIB_FTELL''@/$(GNULIB_FTELL)/g' \ ++ -e 's/@''GNULIB_FTELLO''@/$(GNULIB_FTELLO)/g' \ ++ -e 's/@''GNULIB_FWRITE''@/$(GNULIB_FWRITE)/g' \ ++ -e 's/@''GNULIB_GETC''@/$(GNULIB_GETC)/g' \ ++ -e 's/@''GNULIB_GETCHAR''@/$(GNULIB_GETCHAR)/g' \ ++ -e 's/@''GNULIB_GETDELIM''@/$(GNULIB_GETDELIM)/g' \ ++ -e 's/@''GNULIB_GETLINE''@/$(GNULIB_GETLINE)/g' \ ++ -e 's/@''GNULIB_OBSTACK_PRINTF''@/$(GNULIB_OBSTACK_PRINTF)/g' \ ++ -e 's/@''GNULIB_OBSTACK_PRINTF_POSIX''@/$(GNULIB_OBSTACK_PRINTF_POSIX)/g' \ ++ -e 's/@''GNULIB_PCLOSE''@/$(GNULIB_PCLOSE)/g' \ ++ -e 's/@''GNULIB_PERROR''@/$(GNULIB_PERROR)/g' \ ++ -e 's/@''GNULIB_POPEN''@/$(GNULIB_POPEN)/g' \ ++ -e 's/@''GNULIB_PRINTF''@/$(GNULIB_PRINTF)/g' \ ++ -e 's/@''GNULIB_PRINTF_POSIX''@/$(GNULIB_PRINTF_POSIX)/g' \ ++ -e 's/@''GNULIB_PUTC''@/$(GNULIB_PUTC)/g' \ ++ -e 's/@''GNULIB_PUTCHAR''@/$(GNULIB_PUTCHAR)/g' \ ++ -e 's/@''GNULIB_PUTS''@/$(GNULIB_PUTS)/g' \ ++ -e 's/@''GNULIB_REMOVE''@/$(GNULIB_REMOVE)/g' \ ++ -e 's/@''GNULIB_RENAME''@/$(GNULIB_RENAME)/g' \ ++ -e 's/@''GNULIB_RENAMEAT''@/$(GNULIB_RENAMEAT)/g' \ ++ -e 's/@''GNULIB_SCANF''@/$(GNULIB_SCANF)/g' \ ++ -e 's/@''GNULIB_SNPRINTF''@/$(GNULIB_SNPRINTF)/g' \ ++ -e 's/@''GNULIB_SPRINTF_POSIX''@/$(GNULIB_SPRINTF_POSIX)/g' \ ++ -e 's/@''GNULIB_STDIO_H_NONBLOCKING''@/$(GNULIB_STDIO_H_NONBLOCKING)/g' \ ++ -e 's/@''GNULIB_STDIO_H_SIGPIPE''@/$(GNULIB_STDIO_H_SIGPIPE)/g' \ ++ -e 's/@''GNULIB_TMPFILE''@/$(GNULIB_TMPFILE)/g' \ ++ -e 's/@''GNULIB_VASPRINTF''@/$(GNULIB_VASPRINTF)/g' \ ++ -e 's/@''GNULIB_VDPRINTF''@/$(GNULIB_VDPRINTF)/g' \ ++ -e 's/@''GNULIB_VFPRINTF''@/$(GNULIB_VFPRINTF)/g' \ ++ -e 's/@''GNULIB_VFPRINTF_POSIX''@/$(GNULIB_VFPRINTF_POSIX)/g' \ ++ -e 's/@''GNULIB_VFSCANF''@/$(GNULIB_VFSCANF)/g' \ ++ -e 's/@''GNULIB_VSCANF''@/$(GNULIB_VSCANF)/g' \ ++ -e 's/@''GNULIB_VPRINTF''@/$(GNULIB_VPRINTF)/g' \ ++ -e 's/@''GNULIB_VPRINTF_POSIX''@/$(GNULIB_VPRINTF_POSIX)/g' \ ++ -e 's/@''GNULIB_VSNPRINTF''@/$(GNULIB_VSNPRINTF)/g' \ ++ -e 's/@''GNULIB_VSPRINTF_POSIX''@/$(GNULIB_VSPRINTF_POSIX)/g' \ + < $(srcdir)/stdio.in.h | \ + sed -e 's|@''HAVE_DECL_FPURGE''@|$(HAVE_DECL_FPURGE)|g' \ ++ -e 's|@''HAVE_DECL_FSEEKO''@|$(HAVE_DECL_FSEEKO)|g' \ ++ -e 's|@''HAVE_DECL_FTELLO''@|$(HAVE_DECL_FTELLO)|g' \ + -e 's|@''HAVE_DECL_GETDELIM''@|$(HAVE_DECL_GETDELIM)|g' \ + -e 's|@''HAVE_DECL_GETLINE''@|$(HAVE_DECL_GETLINE)|g' \ + -e 's|@''HAVE_DECL_OBSTACK_PRINTF''@|$(HAVE_DECL_OBSTACK_PRINTF)|g' \ +@@ -729,11 +930,14 @@ stdio.h: stdio.in.h $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) + -e 's|@''HAVE_DPRINTF''@|$(HAVE_DPRINTF)|g' \ + -e 's|@''HAVE_FSEEKO''@|$(HAVE_FSEEKO)|g' \ + -e 's|@''HAVE_FTELLO''@|$(HAVE_FTELLO)|g' \ ++ -e 's|@''HAVE_PCLOSE''@|$(HAVE_PCLOSE)|g' \ ++ -e 's|@''HAVE_POPEN''@|$(HAVE_POPEN)|g' \ + -e 's|@''HAVE_RENAMEAT''@|$(HAVE_RENAMEAT)|g' \ + -e 's|@''HAVE_VASPRINTF''@|$(HAVE_VASPRINTF)|g' \ + -e 's|@''HAVE_VDPRINTF''@|$(HAVE_VDPRINTF)|g' \ + -e 's|@''REPLACE_DPRINTF''@|$(REPLACE_DPRINTF)|g' \ + -e 's|@''REPLACE_FCLOSE''@|$(REPLACE_FCLOSE)|g' \ ++ -e 's|@''REPLACE_FDOPEN''@|$(REPLACE_FDOPEN)|g' \ + -e 's|@''REPLACE_FFLUSH''@|$(REPLACE_FFLUSH)|g' \ + -e 's|@''REPLACE_FOPEN''@|$(REPLACE_FOPEN)|g' \ + -e 's|@''REPLACE_FPRINTF''@|$(REPLACE_FPRINTF)|g' \ +@@ -754,6 +958,7 @@ stdio.h: stdio.in.h $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) + -e 's|@''REPLACE_RENAMEAT''@|$(REPLACE_RENAMEAT)|g' \ + -e 's|@''REPLACE_SNPRINTF''@|$(REPLACE_SNPRINTF)|g' \ + -e 's|@''REPLACE_SPRINTF''@|$(REPLACE_SPRINTF)|g' \ ++ -e 's|@''REPLACE_STDIO_READ_FUNCS''@|$(REPLACE_STDIO_READ_FUNCS)|g' \ + -e 's|@''REPLACE_STDIO_WRITE_FUNCS''@|$(REPLACE_STDIO_WRITE_FUNCS)|g' \ + -e 's|@''REPLACE_TMPFILE''@|$(REPLACE_TMPFILE)|g' \ + -e 's|@''REPLACE_VASPRINTF''@|$(REPLACE_VASPRINTF)|g' \ +@@ -770,9 +975,7 @@ stdio.h: stdio.in.h $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) + mv $@-t $@ + MOSTLYCLEANFILES += stdio.h stdio.h-t + +-EXTRA_DIST += stdio-write.c stdio.in.h +- +-EXTRA_libgnu_a_SOURCES += stdio-write.c ++EXTRA_DIST += stdio.in.h + + ## end gnulib module stdio + +@@ -782,38 +985,49 @@ BUILT_SOURCES += stdlib.h + + # We need the following in order to create when the system + # doesn't have one that works with the given compiler. +-stdlib.h: stdlib.in.h $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) ++stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \ ++ $(_NORETURN_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ +- sed -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ ++ sed -e 's|@''GUARD_PREFIX''@|GL|g' \ ++ -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ ++ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ + -e 's|@''NEXT_STDLIB_H''@|$(NEXT_STDLIB_H)|g' \ +- -e 's|@''GNULIB__EXIT''@|$(GNULIB__EXIT)|g' \ +- -e 's|@''GNULIB_ATOLL''@|$(GNULIB_ATOLL)|g' \ +- -e 's|@''GNULIB_CALLOC_POSIX''@|$(GNULIB_CALLOC_POSIX)|g' \ +- -e 's|@''GNULIB_CANONICALIZE_FILE_NAME''@|$(GNULIB_CANONICALIZE_FILE_NAME)|g' \ +- -e 's|@''GNULIB_GETLOADAVG''@|$(GNULIB_GETLOADAVG)|g' \ +- -e 's|@''GNULIB_GETSUBOPT''@|$(GNULIB_GETSUBOPT)|g' \ +- -e 's|@''GNULIB_GRANTPT''@|$(GNULIB_GRANTPT)|g' \ +- -e 's|@''GNULIB_MALLOC_POSIX''@|$(GNULIB_MALLOC_POSIX)|g' \ +- -e 's|@''GNULIB_MKDTEMP''@|$(GNULIB_MKDTEMP)|g' \ +- -e 's|@''GNULIB_MKOSTEMP''@|$(GNULIB_MKOSTEMP)|g' \ +- -e 's|@''GNULIB_MKOSTEMPS''@|$(GNULIB_MKOSTEMPS)|g' \ +- -e 's|@''GNULIB_MKSTEMP''@|$(GNULIB_MKSTEMP)|g' \ +- -e 's|@''GNULIB_MKSTEMPS''@|$(GNULIB_MKSTEMPS)|g' \ +- -e 's|@''GNULIB_PTSNAME''@|$(GNULIB_PTSNAME)|g' \ +- -e 's|@''GNULIB_PUTENV''@|$(GNULIB_PUTENV)|g' \ +- -e 's|@''GNULIB_RANDOM_R''@|$(GNULIB_RANDOM_R)|g' \ +- -e 's|@''GNULIB_REALLOC_POSIX''@|$(GNULIB_REALLOC_POSIX)|g' \ +- -e 's|@''GNULIB_REALPATH''@|$(GNULIB_REALPATH)|g' \ +- -e 's|@''GNULIB_RPMATCH''@|$(GNULIB_RPMATCH)|g' \ +- -e 's|@''GNULIB_SETENV''@|$(GNULIB_SETENV)|g' \ +- -e 's|@''GNULIB_STRTOD''@|$(GNULIB_STRTOD)|g' \ +- -e 's|@''GNULIB_STRTOLL''@|$(GNULIB_STRTOLL)|g' \ +- -e 's|@''GNULIB_STRTOULL''@|$(GNULIB_STRTOULL)|g' \ +- -e 's|@''GNULIB_UNLOCKPT''@|$(GNULIB_UNLOCKPT)|g' \ +- -e 's|@''GNULIB_UNSETENV''@|$(GNULIB_UNSETENV)|g' \ +- -e 's|@''HAVE__EXIT''@|$(HAVE__EXIT)|g' \ ++ -e 's/@''GNULIB__EXIT''@/$(GNULIB__EXIT)/g' \ ++ -e 's/@''GNULIB_ATOLL''@/$(GNULIB_ATOLL)/g' \ ++ -e 's/@''GNULIB_CALLOC_POSIX''@/$(GNULIB_CALLOC_POSIX)/g' \ ++ -e 's/@''GNULIB_CANONICALIZE_FILE_NAME''@/$(GNULIB_CANONICALIZE_FILE_NAME)/g' \ ++ -e 's/@''GNULIB_GETLOADAVG''@/$(GNULIB_GETLOADAVG)/g' \ ++ -e 's/@''GNULIB_GETSUBOPT''@/$(GNULIB_GETSUBOPT)/g' \ ++ -e 's/@''GNULIB_GRANTPT''@/$(GNULIB_GRANTPT)/g' \ ++ -e 's/@''GNULIB_MALLOC_POSIX''@/$(GNULIB_MALLOC_POSIX)/g' \ ++ -e 's/@''GNULIB_MBTOWC''@/$(GNULIB_MBTOWC)/g' \ ++ -e 's/@''GNULIB_MKDTEMP''@/$(GNULIB_MKDTEMP)/g' \ ++ -e 's/@''GNULIB_MKOSTEMP''@/$(GNULIB_MKOSTEMP)/g' \ ++ -e 's/@''GNULIB_MKOSTEMPS''@/$(GNULIB_MKOSTEMPS)/g' \ ++ -e 's/@''GNULIB_MKSTEMP''@/$(GNULIB_MKSTEMP)/g' \ ++ -e 's/@''GNULIB_MKSTEMPS''@/$(GNULIB_MKSTEMPS)/g' \ ++ -e 's/@''GNULIB_POSIX_OPENPT''@/$(GNULIB_POSIX_OPENPT)/g' \ ++ -e 's/@''GNULIB_PTSNAME''@/$(GNULIB_PTSNAME)/g' \ ++ -e 's/@''GNULIB_PTSNAME_R''@/$(GNULIB_PTSNAME_R)/g' \ ++ -e 's/@''GNULIB_PUTENV''@/$(GNULIB_PUTENV)/g' \ ++ -e 's/@''GNULIB_RANDOM''@/$(GNULIB_RANDOM)/g' \ ++ -e 's/@''GNULIB_RANDOM_R''@/$(GNULIB_RANDOM_R)/g' \ ++ -e 's/@''GNULIB_REALLOC_POSIX''@/$(GNULIB_REALLOC_POSIX)/g' \ ++ -e 's/@''GNULIB_REALPATH''@/$(GNULIB_REALPATH)/g' \ ++ -e 's/@''GNULIB_RPMATCH''@/$(GNULIB_RPMATCH)/g' \ ++ -e 's/@''GNULIB_SECURE_GETENV''@/$(GNULIB_SECURE_GETENV)/g' \ ++ -e 's/@''GNULIB_SETENV''@/$(GNULIB_SETENV)/g' \ ++ -e 's/@''GNULIB_STRTOD''@/$(GNULIB_STRTOD)/g' \ ++ -e 's/@''GNULIB_STRTOLL''@/$(GNULIB_STRTOLL)/g' \ ++ -e 's/@''GNULIB_STRTOULL''@/$(GNULIB_STRTOULL)/g' \ ++ -e 's/@''GNULIB_SYSTEM_POSIX''@/$(GNULIB_SYSTEM_POSIX)/g' \ ++ -e 's/@''GNULIB_UNLOCKPT''@/$(GNULIB_UNLOCKPT)/g' \ ++ -e 's/@''GNULIB_UNSETENV''@/$(GNULIB_UNSETENV)/g' \ ++ -e 's/@''GNULIB_WCTOMB''@/$(GNULIB_WCTOMB)/g' \ ++ < $(srcdir)/stdlib.in.h | \ ++ sed -e 's|@''HAVE__EXIT''@|$(HAVE__EXIT)|g' \ + -e 's|@''HAVE_ATOLL''@|$(HAVE_ATOLL)|g' \ + -e 's|@''HAVE_CANONICALIZE_FILE_NAME''@|$(HAVE_CANONICALIZE_FILE_NAME)|g' \ + -e 's|@''HAVE_DECL_GETLOADAVG''@|$(HAVE_DECL_GETLOADAVG)|g' \ +@@ -824,33 +1038,42 @@ stdlib.h: stdlib.in.h $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) + -e 's|@''HAVE_MKOSTEMPS''@|$(HAVE_MKOSTEMPS)|g' \ + -e 's|@''HAVE_MKSTEMP''@|$(HAVE_MKSTEMP)|g' \ + -e 's|@''HAVE_MKSTEMPS''@|$(HAVE_MKSTEMPS)|g' \ ++ -e 's|@''HAVE_POSIX_OPENPT''@|$(HAVE_POSIX_OPENPT)|g' \ + -e 's|@''HAVE_PTSNAME''@|$(HAVE_PTSNAME)|g' \ ++ -e 's|@''HAVE_PTSNAME_R''@|$(HAVE_PTSNAME_R)|g' \ ++ -e 's|@''HAVE_RANDOM''@|$(HAVE_RANDOM)|g' \ + -e 's|@''HAVE_RANDOM_H''@|$(HAVE_RANDOM_H)|g' \ + -e 's|@''HAVE_RANDOM_R''@|$(HAVE_RANDOM_R)|g' \ + -e 's|@''HAVE_REALPATH''@|$(HAVE_REALPATH)|g' \ + -e 's|@''HAVE_RPMATCH''@|$(HAVE_RPMATCH)|g' \ +- -e 's|@''HAVE_SETENV''@|$(HAVE_SETENV)|g' \ ++ -e 's|@''HAVE_SECURE_GETENV''@|$(HAVE_SECURE_GETENV)|g' \ ++ -e 's|@''HAVE_DECL_SETENV''@|$(HAVE_DECL_SETENV)|g' \ + -e 's|@''HAVE_STRTOD''@|$(HAVE_STRTOD)|g' \ + -e 's|@''HAVE_STRTOLL''@|$(HAVE_STRTOLL)|g' \ + -e 's|@''HAVE_STRTOULL''@|$(HAVE_STRTOULL)|g' \ + -e 's|@''HAVE_STRUCT_RANDOM_DATA''@|$(HAVE_STRUCT_RANDOM_DATA)|g' \ + -e 's|@''HAVE_SYS_LOADAVG_H''@|$(HAVE_SYS_LOADAVG_H)|g' \ + -e 's|@''HAVE_UNLOCKPT''@|$(HAVE_UNLOCKPT)|g' \ +- -e 's|@''HAVE_UNSETENV''@|$(HAVE_UNSETENV)|g' \ ++ -e 's|@''HAVE_DECL_UNSETENV''@|$(HAVE_DECL_UNSETENV)|g' \ + -e 's|@''REPLACE_CALLOC''@|$(REPLACE_CALLOC)|g' \ + -e 's|@''REPLACE_CANONICALIZE_FILE_NAME''@|$(REPLACE_CANONICALIZE_FILE_NAME)|g' \ + -e 's|@''REPLACE_MALLOC''@|$(REPLACE_MALLOC)|g' \ ++ -e 's|@''REPLACE_MBTOWC''@|$(REPLACE_MBTOWC)|g' \ + -e 's|@''REPLACE_MKSTEMP''@|$(REPLACE_MKSTEMP)|g' \ ++ -e 's|@''REPLACE_PTSNAME''@|$(REPLACE_PTSNAME)|g' \ ++ -e 's|@''REPLACE_PTSNAME_R''@|$(REPLACE_PTSNAME_R)|g' \ + -e 's|@''REPLACE_PUTENV''@|$(REPLACE_PUTENV)|g' \ ++ -e 's|@''REPLACE_RANDOM_R''@|$(REPLACE_RANDOM_R)|g' \ + -e 's|@''REPLACE_REALLOC''@|$(REPLACE_REALLOC)|g' \ + -e 's|@''REPLACE_REALPATH''@|$(REPLACE_REALPATH)|g' \ + -e 's|@''REPLACE_SETENV''@|$(REPLACE_SETENV)|g' \ + -e 's|@''REPLACE_STRTOD''@|$(REPLACE_STRTOD)|g' \ + -e 's|@''REPLACE_UNSETENV''@|$(REPLACE_UNSETENV)|g' \ ++ -e 's|@''REPLACE_WCTOMB''@|$(REPLACE_WCTOMB)|g' \ + -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ ++ -e '/definition of _Noreturn/r $(_NORETURN_H)' \ + -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ +- -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ +- < $(srcdir)/stdlib.in.h; \ ++ -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)'; \ + } > $@-t && \ + mv $@-t $@ + MOSTLYCLEANFILES += stdlib.h stdlib.h-t +@@ -893,54 +1116,70 @@ EXTRA_libgnu_a_SOURCES += strerror.c + + ## end gnulib module strerror + ++## begin gnulib module strerror-override ++ ++ ++EXTRA_DIST += strerror-override.c strerror-override.h ++ ++EXTRA_libgnu_a_SOURCES += strerror-override.c ++ ++## end gnulib module strerror-override ++ + ## begin gnulib module string + + BUILT_SOURCES += string.h + + # We need the following in order to create when the system + # doesn't have one that works with the given compiler. +-string.h: string.in.h $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) ++string.h: string.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ +- sed -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ ++ sed -e 's|@''GUARD_PREFIX''@|GL|g' \ ++ -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ ++ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ + -e 's|@''NEXT_STRING_H''@|$(NEXT_STRING_H)|g' \ +- -e 's|@''GNULIB_MBSLEN''@|$(GNULIB_MBSLEN)|g' \ +- -e 's|@''GNULIB_MBSNLEN''@|$(GNULIB_MBSNLEN)|g' \ +- -e 's|@''GNULIB_MBSCHR''@|$(GNULIB_MBSCHR)|g' \ +- -e 's|@''GNULIB_MBSRCHR''@|$(GNULIB_MBSRCHR)|g' \ +- -e 's|@''GNULIB_MBSSTR''@|$(GNULIB_MBSSTR)|g' \ +- -e 's|@''GNULIB_MBSCASECMP''@|$(GNULIB_MBSCASECMP)|g' \ +- -e 's|@''GNULIB_MBSNCASECMP''@|$(GNULIB_MBSNCASECMP)|g' \ +- -e 's|@''GNULIB_MBSPCASECMP''@|$(GNULIB_MBSPCASECMP)|g' \ +- -e 's|@''GNULIB_MBSCASESTR''@|$(GNULIB_MBSCASESTR)|g' \ +- -e 's|@''GNULIB_MBSCSPN''@|$(GNULIB_MBSCSPN)|g' \ +- -e 's|@''GNULIB_MBSPBRK''@|$(GNULIB_MBSPBRK)|g' \ +- -e 's|@''GNULIB_MBSSPN''@|$(GNULIB_MBSSPN)|g' \ +- -e 's|@''GNULIB_MBSSEP''@|$(GNULIB_MBSSEP)|g' \ +- -e 's|@''GNULIB_MBSTOK_R''@|$(GNULIB_MBSTOK_R)|g' \ +- -e 's|@''GNULIB_MEMCHR''@|$(GNULIB_MEMCHR)|g' \ +- -e 's|@''GNULIB_MEMMEM''@|$(GNULIB_MEMMEM)|g' \ +- -e 's|@''GNULIB_MEMPCPY''@|$(GNULIB_MEMPCPY)|g' \ +- -e 's|@''GNULIB_MEMRCHR''@|$(GNULIB_MEMRCHR)|g' \ +- -e 's|@''GNULIB_RAWMEMCHR''@|$(GNULIB_RAWMEMCHR)|g' \ +- -e 's|@''GNULIB_STPCPY''@|$(GNULIB_STPCPY)|g' \ +- -e 's|@''GNULIB_STPNCPY''@|$(GNULIB_STPNCPY)|g' \ +- -e 's|@''GNULIB_STRCHRNUL''@|$(GNULIB_STRCHRNUL)|g' \ +- -e 's|@''GNULIB_STRDUP''@|$(GNULIB_STRDUP)|g' \ +- -e 's|@''GNULIB_STRNCAT''@|$(GNULIB_STRNCAT)|g' \ +- -e 's|@''GNULIB_STRNDUP''@|$(GNULIB_STRNDUP)|g' \ +- -e 's|@''GNULIB_STRNLEN''@|$(GNULIB_STRNLEN)|g' \ +- -e 's|@''GNULIB_STRPBRK''@|$(GNULIB_STRPBRK)|g' \ +- -e 's|@''GNULIB_STRSEP''@|$(GNULIB_STRSEP)|g' \ +- -e 's|@''GNULIB_STRSTR''@|$(GNULIB_STRSTR)|g' \ +- -e 's|@''GNULIB_STRCASESTR''@|$(GNULIB_STRCASESTR)|g' \ +- -e 's|@''GNULIB_STRTOK_R''@|$(GNULIB_STRTOK_R)|g' \ +- -e 's|@''GNULIB_STRERROR''@|$(GNULIB_STRERROR)|g' \ +- -e 's|@''GNULIB_STRSIGNAL''@|$(GNULIB_STRSIGNAL)|g' \ +- -e 's|@''GNULIB_STRVERSCMP''@|$(GNULIB_STRVERSCMP)|g' \ ++ -e 's/@''GNULIB_FFSL''@/$(GNULIB_FFSL)/g' \ ++ -e 's/@''GNULIB_FFSLL''@/$(GNULIB_FFSLL)/g' \ ++ -e 's/@''GNULIB_MBSLEN''@/$(GNULIB_MBSLEN)/g' \ ++ -e 's/@''GNULIB_MBSNLEN''@/$(GNULIB_MBSNLEN)/g' \ ++ -e 's/@''GNULIB_MBSCHR''@/$(GNULIB_MBSCHR)/g' \ ++ -e 's/@''GNULIB_MBSRCHR''@/$(GNULIB_MBSRCHR)/g' \ ++ -e 's/@''GNULIB_MBSSTR''@/$(GNULIB_MBSSTR)/g' \ ++ -e 's/@''GNULIB_MBSCASECMP''@/$(GNULIB_MBSCASECMP)/g' \ ++ -e 's/@''GNULIB_MBSNCASECMP''@/$(GNULIB_MBSNCASECMP)/g' \ ++ -e 's/@''GNULIB_MBSPCASECMP''@/$(GNULIB_MBSPCASECMP)/g' \ ++ -e 's/@''GNULIB_MBSCASESTR''@/$(GNULIB_MBSCASESTR)/g' \ ++ -e 's/@''GNULIB_MBSCSPN''@/$(GNULIB_MBSCSPN)/g' \ ++ -e 's/@''GNULIB_MBSPBRK''@/$(GNULIB_MBSPBRK)/g' \ ++ -e 's/@''GNULIB_MBSSPN''@/$(GNULIB_MBSSPN)/g' \ ++ -e 's/@''GNULIB_MBSSEP''@/$(GNULIB_MBSSEP)/g' \ ++ -e 's/@''GNULIB_MBSTOK_R''@/$(GNULIB_MBSTOK_R)/g' \ ++ -e 's/@''GNULIB_MEMCHR''@/$(GNULIB_MEMCHR)/g' \ ++ -e 's/@''GNULIB_MEMMEM''@/$(GNULIB_MEMMEM)/g' \ ++ -e 's/@''GNULIB_MEMPCPY''@/$(GNULIB_MEMPCPY)/g' \ ++ -e 's/@''GNULIB_MEMRCHR''@/$(GNULIB_MEMRCHR)/g' \ ++ -e 's/@''GNULIB_RAWMEMCHR''@/$(GNULIB_RAWMEMCHR)/g' \ ++ -e 's/@''GNULIB_STPCPY''@/$(GNULIB_STPCPY)/g' \ ++ -e 's/@''GNULIB_STPNCPY''@/$(GNULIB_STPNCPY)/g' \ ++ -e 's/@''GNULIB_STRCHRNUL''@/$(GNULIB_STRCHRNUL)/g' \ ++ -e 's/@''GNULIB_STRDUP''@/$(GNULIB_STRDUP)/g' \ ++ -e 's/@''GNULIB_STRNCAT''@/$(GNULIB_STRNCAT)/g' \ ++ -e 's/@''GNULIB_STRNDUP''@/$(GNULIB_STRNDUP)/g' \ ++ -e 's/@''GNULIB_STRNLEN''@/$(GNULIB_STRNLEN)/g' \ ++ -e 's/@''GNULIB_STRPBRK''@/$(GNULIB_STRPBRK)/g' \ ++ -e 's/@''GNULIB_STRSEP''@/$(GNULIB_STRSEP)/g' \ ++ -e 's/@''GNULIB_STRSTR''@/$(GNULIB_STRSTR)/g' \ ++ -e 's/@''GNULIB_STRCASESTR''@/$(GNULIB_STRCASESTR)/g' \ ++ -e 's/@''GNULIB_STRTOK_R''@/$(GNULIB_STRTOK_R)/g' \ ++ -e 's/@''GNULIB_STRERROR''@/$(GNULIB_STRERROR)/g' \ ++ -e 's/@''GNULIB_STRERROR_R''@/$(GNULIB_STRERROR_R)/g' \ ++ -e 's/@''GNULIB_STRSIGNAL''@/$(GNULIB_STRSIGNAL)/g' \ ++ -e 's/@''GNULIB_STRVERSCMP''@/$(GNULIB_STRVERSCMP)/g' \ + < $(srcdir)/string.in.h | \ +- sed -e 's|@''HAVE_MBSLEN''@|$(HAVE_MBSLEN)|g' \ ++ sed -e 's|@''HAVE_FFSL''@|$(HAVE_FFSL)|g' \ ++ -e 's|@''HAVE_FFSLL''@|$(HAVE_FFSLL)|g' \ ++ -e 's|@''HAVE_MBSLEN''@|$(HAVE_MBSLEN)|g' \ + -e 's|@''HAVE_MEMCHR''@|$(HAVE_MEMCHR)|g' \ + -e 's|@''HAVE_DECL_MEMMEM''@|$(HAVE_DECL_MEMMEM)|g' \ + -e 's|@''HAVE_MEMPCPY''@|$(HAVE_MEMPCPY)|g' \ +@@ -956,15 +1195,18 @@ string.h: string.in.h $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) + -e 's|@''HAVE_STRSEP''@|$(HAVE_STRSEP)|g' \ + -e 's|@''HAVE_STRCASESTR''@|$(HAVE_STRCASESTR)|g' \ + -e 's|@''HAVE_DECL_STRTOK_R''@|$(HAVE_DECL_STRTOK_R)|g' \ ++ -e 's|@''HAVE_DECL_STRERROR_R''@|$(HAVE_DECL_STRERROR_R)|g' \ + -e 's|@''HAVE_DECL_STRSIGNAL''@|$(HAVE_DECL_STRSIGNAL)|g' \ + -e 's|@''HAVE_STRVERSCMP''@|$(HAVE_STRVERSCMP)|g' \ + -e 's|@''REPLACE_STPNCPY''@|$(REPLACE_STPNCPY)|g' \ + -e 's|@''REPLACE_MEMCHR''@|$(REPLACE_MEMCHR)|g' \ + -e 's|@''REPLACE_MEMMEM''@|$(REPLACE_MEMMEM)|g' \ + -e 's|@''REPLACE_STRCASESTR''@|$(REPLACE_STRCASESTR)|g' \ ++ -e 's|@''REPLACE_STRCHRNUL''@|$(REPLACE_STRCHRNUL)|g' \ + -e 's|@''REPLACE_STRDUP''@|$(REPLACE_STRDUP)|g' \ + -e 's|@''REPLACE_STRSTR''@|$(REPLACE_STRSTR)|g' \ + -e 's|@''REPLACE_STRERROR''@|$(REPLACE_STRERROR)|g' \ ++ -e 's|@''REPLACE_STRERROR_R''@|$(REPLACE_STRERROR_R)|g' \ + -e 's|@''REPLACE_STRNCAT''@|$(REPLACE_STRNCAT)|g' \ + -e 's|@''REPLACE_STRNDUP''@|$(REPLACE_STRNDUP)|g' \ + -e 's|@''REPLACE_STRNLEN''@|$(REPLACE_STRNLEN)|g' \ +@@ -989,14 +1231,20 @@ BUILT_SOURCES += strings.h + + # We need the following in order to create when the system + # doesn't have one that works with the given compiler. +-strings.h: strings.in.h $(WARN_ON_USE_H) $(ARG_NONNULL_H) ++strings.h: strings.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_ON_USE_H) $(ARG_NONNULL_H) + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ +- sed -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ ++ sed -e 's|@''GUARD_PREFIX''@|GL|g' \ ++ -e 's|@''HAVE_STRINGS_H''@|$(HAVE_STRINGS_H)|g' \ ++ -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ ++ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ + -e 's|@''NEXT_STRINGS_H''@|$(NEXT_STRINGS_H)|g' \ ++ -e 's|@''GNULIB_FFS''@|$(GNULIB_FFS)|g' \ ++ -e 's|@''HAVE_FFS''@|$(HAVE_FFS)|g' \ + -e 's|@''HAVE_STRCASECMP''@|$(HAVE_STRCASECMP)|g' \ + -e 's|@''HAVE_DECL_STRNCASECMP''@|$(HAVE_DECL_STRNCASECMP)|g' \ ++ -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ + -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ + -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ + < $(srcdir)/strings.in.h; \ +@@ -1032,28 +1280,30 @@ libgnu_a_SOURCES += strnlen1.h strnlen1.c + + ## end gnulib module strnlen1 + +-## begin gnulib module sys_wait ++## begin gnulib module sys_types + +-BUILT_SOURCES += sys/wait.h ++BUILT_SOURCES += sys/types.h + +-# We need the following in order to create when the system +-# has one that is incomplete. +-sys/wait.h: sys_wait.in.h ++# We need the following in order to create when the system ++# doesn't have one that works with the given compiler. ++sys/types.h: sys_types.in.h $(top_builddir)/config.status + $(AM_V_at)$(MKDIR_P) sys + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ +- sed -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ ++ sed -e 's|@''GUARD_PREFIX''@|GL|g' \ ++ -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ +- -e 's|@''NEXT_SYS_WAIT_H''@|$(NEXT_SYS_WAIT_H)|g' \ +- < $(srcdir)/sys_wait.in.h; \ ++ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ ++ -e 's|@''NEXT_SYS_TYPES_H''@|$(NEXT_SYS_TYPES_H)|g' \ ++ -e 's|@''WINDOWS_64_BIT_OFF_T''@|$(WINDOWS_64_BIT_OFF_T)|g' \ ++ < $(srcdir)/sys_types.in.h; \ + } > $@-t && \ + mv $@-t $@ +-MOSTLYCLEANFILES += sys/wait.h sys/wait.h-t +-MOSTLYCLEANDIRS += sys ++MOSTLYCLEANFILES += sys/types.h sys/types.h-t + +-EXTRA_DIST += sys_wait.in.h ++EXTRA_DIST += sys_types.in.h + +-## end gnulib module sys_wait ++## end gnulib module sys_types + + ## begin gnulib module sysexits + +@@ -1061,16 +1311,23 @@ BUILT_SOURCES += $(SYSEXITS_H) + + # We need the following in order to create when the system + # doesn't have one that works with the given compiler. +-sysexits.h: sysexits.in.h ++if GL_GENERATE_SYSEXITS_H ++sysexits.h: sysexits.in.h $(top_builddir)/config.status + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ +- sed -e 's|@''HAVE_SYSEXITS_H''@|$(HAVE_SYSEXITS_H)|g' \ ++ sed -e 's|@''GUARD_PREFIX''@|GL|g' \ ++ -e 's|@''HAVE_SYSEXITS_H''@|$(HAVE_SYSEXITS_H)|g' \ + -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ ++ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ + -e 's|@''NEXT_SYSEXITS_H''@|$(NEXT_SYSEXITS_H)|g' \ + < $(srcdir)/sysexits.in.h; \ + } > $@-t && \ + mv -f $@-t $@ ++else ++sysexits.h: $(top_builddir)/config.status ++ rm -f $@ ++endif + MOSTLYCLEANFILES += sysexits.h sysexits.h-t + + EXTRA_DIST += sysexits.in.h +@@ -1080,56 +1337,69 @@ EXTRA_DIST += sysexits.in.h + ## begin gnulib module unistd + + BUILT_SOURCES += unistd.h ++libgnu_a_SOURCES += unistd.c + + # We need the following in order to create an empty placeholder for + # when the system doesn't have one. +-unistd.h: unistd.in.h $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) ++unistd.h: unistd.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ +- sed -e 's|@''HAVE_UNISTD_H''@|$(HAVE_UNISTD_H)|g' \ ++ sed -e 's|@''GUARD_PREFIX''@|GL|g' \ ++ -e 's|@''HAVE_UNISTD_H''@|$(HAVE_UNISTD_H)|g' \ + -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ ++ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ + -e 's|@''NEXT_UNISTD_H''@|$(NEXT_UNISTD_H)|g' \ +- -e 's|@''GNULIB_CHOWN''@|$(GNULIB_CHOWN)|g' \ +- -e 's|@''GNULIB_CLOSE''@|$(GNULIB_CLOSE)|g' \ +- -e 's|@''GNULIB_DUP2''@|$(GNULIB_DUP2)|g' \ +- -e 's|@''GNULIB_DUP3''@|$(GNULIB_DUP3)|g' \ +- -e 's|@''GNULIB_ENVIRON''@|$(GNULIB_ENVIRON)|g' \ +- -e 's|@''GNULIB_EUIDACCESS''@|$(GNULIB_EUIDACCESS)|g' \ +- -e 's|@''GNULIB_FACCESSAT''@|$(GNULIB_FACCESSAT)|g' \ +- -e 's|@''GNULIB_FCHDIR''@|$(GNULIB_FCHDIR)|g' \ +- -e 's|@''GNULIB_FCHOWNAT''@|$(GNULIB_FCHOWNAT)|g' \ +- -e 's|@''GNULIB_FSYNC''@|$(GNULIB_FSYNC)|g' \ +- -e 's|@''GNULIB_FTRUNCATE''@|$(GNULIB_FTRUNCATE)|g' \ +- -e 's|@''GNULIB_GETCWD''@|$(GNULIB_GETCWD)|g' \ +- -e 's|@''GNULIB_GETDOMAINNAME''@|$(GNULIB_GETDOMAINNAME)|g' \ +- -e 's|@''GNULIB_GETDTABLESIZE''@|$(GNULIB_GETDTABLESIZE)|g' \ +- -e 's|@''GNULIB_GETGROUPS''@|$(GNULIB_GETGROUPS)|g' \ +- -e 's|@''GNULIB_GETHOSTNAME''@|$(GNULIB_GETHOSTNAME)|g' \ +- -e 's|@''GNULIB_GETLOGIN''@|$(GNULIB_GETLOGIN)|g' \ +- -e 's|@''GNULIB_GETLOGIN_R''@|$(GNULIB_GETLOGIN_R)|g' \ +- -e 's|@''GNULIB_GETPAGESIZE''@|$(GNULIB_GETPAGESIZE)|g' \ +- -e 's|@''GNULIB_GETUSERSHELL''@|$(GNULIB_GETUSERSHELL)|g' \ +- -e 's|@''GNULIB_LCHOWN''@|$(GNULIB_LCHOWN)|g' \ +- -e 's|@''GNULIB_LINK''@|$(GNULIB_LINK)|g' \ +- -e 's|@''GNULIB_LINKAT''@|$(GNULIB_LINKAT)|g' \ +- -e 's|@''GNULIB_LSEEK''@|$(GNULIB_LSEEK)|g' \ +- -e 's|@''GNULIB_PIPE2''@|$(GNULIB_PIPE2)|g' \ +- -e 's|@''GNULIB_PREAD''@|$(GNULIB_PREAD)|g' \ +- -e 's|@''GNULIB_PWRITE''@|$(GNULIB_PWRITE)|g' \ +- -e 's|@''GNULIB_READLINK''@|$(GNULIB_READLINK)|g' \ +- -e 's|@''GNULIB_READLINKAT''@|$(GNULIB_READLINKAT)|g' \ +- -e 's|@''GNULIB_RMDIR''@|$(GNULIB_RMDIR)|g' \ +- -e 's|@''GNULIB_SLEEP''@|$(GNULIB_SLEEP)|g' \ +- -e 's|@''GNULIB_SYMLINK''@|$(GNULIB_SYMLINK)|g' \ +- -e 's|@''GNULIB_SYMLINKAT''@|$(GNULIB_SYMLINKAT)|g' \ +- -e 's|@''GNULIB_TTYNAME_R''@|$(GNULIB_TTYNAME_R)|g' \ +- -e 's|@''GNULIB_UNISTD_H_GETOPT''@|$(GNULIB_UNISTD_H_GETOPT)|g' \ +- -e 's|@''GNULIB_UNISTD_H_SIGPIPE''@|$(GNULIB_UNISTD_H_SIGPIPE)|g' \ +- -e 's|@''GNULIB_UNLINK''@|$(GNULIB_UNLINK)|g' \ +- -e 's|@''GNULIB_UNLINKAT''@|$(GNULIB_UNLINKAT)|g' \ +- -e 's|@''GNULIB_USLEEP''@|$(GNULIB_USLEEP)|g' \ +- -e 's|@''GNULIB_WRITE''@|$(GNULIB_WRITE)|g' \ ++ -e 's|@''WINDOWS_64_BIT_OFF_T''@|$(WINDOWS_64_BIT_OFF_T)|g' \ ++ -e 's/@''GNULIB_CHDIR''@/$(GNULIB_CHDIR)/g' \ ++ -e 's/@''GNULIB_CHOWN''@/$(GNULIB_CHOWN)/g' \ ++ -e 's/@''GNULIB_CLOSE''@/$(GNULIB_CLOSE)/g' \ ++ -e 's/@''GNULIB_DUP''@/$(GNULIB_DUP)/g' \ ++ -e 's/@''GNULIB_DUP2''@/$(GNULIB_DUP2)/g' \ ++ -e 's/@''GNULIB_DUP3''@/$(GNULIB_DUP3)/g' \ ++ -e 's/@''GNULIB_ENVIRON''@/$(GNULIB_ENVIRON)/g' \ ++ -e 's/@''GNULIB_EUIDACCESS''@/$(GNULIB_EUIDACCESS)/g' \ ++ -e 's/@''GNULIB_FACCESSAT''@/$(GNULIB_FACCESSAT)/g' \ ++ -e 's/@''GNULIB_FCHDIR''@/$(GNULIB_FCHDIR)/g' \ ++ -e 's/@''GNULIB_FCHOWNAT''@/$(GNULIB_FCHOWNAT)/g' \ ++ -e 's/@''GNULIB_FDATASYNC''@/$(GNULIB_FDATASYNC)/g' \ ++ -e 's/@''GNULIB_FSYNC''@/$(GNULIB_FSYNC)/g' \ ++ -e 's/@''GNULIB_FTRUNCATE''@/$(GNULIB_FTRUNCATE)/g' \ ++ -e 's/@''GNULIB_GETCWD''@/$(GNULIB_GETCWD)/g' \ ++ -e 's/@''GNULIB_GETDOMAINNAME''@/$(GNULIB_GETDOMAINNAME)/g' \ ++ -e 's/@''GNULIB_GETDTABLESIZE''@/$(GNULIB_GETDTABLESIZE)/g' \ ++ -e 's/@''GNULIB_GETGROUPS''@/$(GNULIB_GETGROUPS)/g' \ ++ -e 's/@''GNULIB_GETHOSTNAME''@/$(GNULIB_GETHOSTNAME)/g' \ ++ -e 's/@''GNULIB_GETLOGIN''@/$(GNULIB_GETLOGIN)/g' \ ++ -e 's/@''GNULIB_GETLOGIN_R''@/$(GNULIB_GETLOGIN_R)/g' \ ++ -e 's/@''GNULIB_GETPAGESIZE''@/$(GNULIB_GETPAGESIZE)/g' \ ++ -e 's/@''GNULIB_GETUSERSHELL''@/$(GNULIB_GETUSERSHELL)/g' \ ++ -e 's/@''GNULIB_GROUP_MEMBER''@/$(GNULIB_GROUP_MEMBER)/g' \ ++ -e 's/@''GNULIB_ISATTY''@/$(GNULIB_ISATTY)/g' \ ++ -e 's/@''GNULIB_LCHOWN''@/$(GNULIB_LCHOWN)/g' \ ++ -e 's/@''GNULIB_LINK''@/$(GNULIB_LINK)/g' \ ++ -e 's/@''GNULIB_LINKAT''@/$(GNULIB_LINKAT)/g' \ ++ -e 's/@''GNULIB_LSEEK''@/$(GNULIB_LSEEK)/g' \ ++ -e 's/@''GNULIB_PIPE''@/$(GNULIB_PIPE)/g' \ ++ -e 's/@''GNULIB_PIPE2''@/$(GNULIB_PIPE2)/g' \ ++ -e 's/@''GNULIB_PREAD''@/$(GNULIB_PREAD)/g' \ ++ -e 's/@''GNULIB_PWRITE''@/$(GNULIB_PWRITE)/g' \ ++ -e 's/@''GNULIB_READ''@/$(GNULIB_READ)/g' \ ++ -e 's/@''GNULIB_READLINK''@/$(GNULIB_READLINK)/g' \ ++ -e 's/@''GNULIB_READLINKAT''@/$(GNULIB_READLINKAT)/g' \ ++ -e 's/@''GNULIB_RMDIR''@/$(GNULIB_RMDIR)/g' \ ++ -e 's/@''GNULIB_SETHOSTNAME''@/$(GNULIB_SETHOSTNAME)/g' \ ++ -e 's/@''GNULIB_SLEEP''@/$(GNULIB_SLEEP)/g' \ ++ -e 's/@''GNULIB_SYMLINK''@/$(GNULIB_SYMLINK)/g' \ ++ -e 's/@''GNULIB_SYMLINKAT''@/$(GNULIB_SYMLINKAT)/g' \ ++ -e 's/@''GNULIB_TTYNAME_R''@/$(GNULIB_TTYNAME_R)/g' \ ++ -e 's/@''GNULIB_UNISTD_H_GETOPT''@/0$(GNULIB_GL_UNISTD_H_GETOPT)/g' \ ++ -e 's/@''GNULIB_UNISTD_H_NONBLOCKING''@/$(GNULIB_UNISTD_H_NONBLOCKING)/g' \ ++ -e 's/@''GNULIB_UNISTD_H_SIGPIPE''@/$(GNULIB_UNISTD_H_SIGPIPE)/g' \ ++ -e 's/@''GNULIB_UNLINK''@/$(GNULIB_UNLINK)/g' \ ++ -e 's/@''GNULIB_UNLINKAT''@/$(GNULIB_UNLINKAT)/g' \ ++ -e 's/@''GNULIB_USLEEP''@/$(GNULIB_USLEEP)/g' \ ++ -e 's/@''GNULIB_WRITE''@/$(GNULIB_WRITE)/g' \ + < $(srcdir)/unistd.in.h | \ + sed -e 's|@''HAVE_CHOWN''@|$(HAVE_CHOWN)|g' \ + -e 's|@''HAVE_DUP2''@|$(HAVE_DUP2)|g' \ +@@ -1138,48 +1408,61 @@ unistd.h: unistd.in.h $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) + -e 's|@''HAVE_FACCESSAT''@|$(HAVE_FACCESSAT)|g' \ + -e 's|@''HAVE_FCHDIR''@|$(HAVE_FCHDIR)|g' \ + -e 's|@''HAVE_FCHOWNAT''@|$(HAVE_FCHOWNAT)|g' \ ++ -e 's|@''HAVE_FDATASYNC''@|$(HAVE_FDATASYNC)|g' \ + -e 's|@''HAVE_FSYNC''@|$(HAVE_FSYNC)|g' \ + -e 's|@''HAVE_FTRUNCATE''@|$(HAVE_FTRUNCATE)|g' \ +- -e 's|@''HAVE_GETDOMAINNAME''@|$(HAVE_GETDOMAINNAME)|g' \ + -e 's|@''HAVE_GETDTABLESIZE''@|$(HAVE_GETDTABLESIZE)|g' \ + -e 's|@''HAVE_GETGROUPS''@|$(HAVE_GETGROUPS)|g' \ + -e 's|@''HAVE_GETHOSTNAME''@|$(HAVE_GETHOSTNAME)|g' \ + -e 's|@''HAVE_GETLOGIN''@|$(HAVE_GETLOGIN)|g' \ + -e 's|@''HAVE_GETPAGESIZE''@|$(HAVE_GETPAGESIZE)|g' \ ++ -e 's|@''HAVE_GROUP_MEMBER''@|$(HAVE_GROUP_MEMBER)|g' \ + -e 's|@''HAVE_LCHOWN''@|$(HAVE_LCHOWN)|g' \ + -e 's|@''HAVE_LINK''@|$(HAVE_LINK)|g' \ + -e 's|@''HAVE_LINKAT''@|$(HAVE_LINKAT)|g' \ ++ -e 's|@''HAVE_PIPE''@|$(HAVE_PIPE)|g' \ + -e 's|@''HAVE_PIPE2''@|$(HAVE_PIPE2)|g' \ + -e 's|@''HAVE_PREAD''@|$(HAVE_PREAD)|g' \ + -e 's|@''HAVE_PWRITE''@|$(HAVE_PWRITE)|g' \ + -e 's|@''HAVE_READLINK''@|$(HAVE_READLINK)|g' \ + -e 's|@''HAVE_READLINKAT''@|$(HAVE_READLINKAT)|g' \ ++ -e 's|@''HAVE_SETHOSTNAME''@|$(HAVE_SETHOSTNAME)|g' \ + -e 's|@''HAVE_SLEEP''@|$(HAVE_SLEEP)|g' \ + -e 's|@''HAVE_SYMLINK''@|$(HAVE_SYMLINK)|g' \ + -e 's|@''HAVE_SYMLINKAT''@|$(HAVE_SYMLINKAT)|g' \ +- -e 's|@''HAVE_TTYNAME_R''@|$(HAVE_TTYNAME_R)|g' \ + -e 's|@''HAVE_UNLINKAT''@|$(HAVE_UNLINKAT)|g' \ + -e 's|@''HAVE_USLEEP''@|$(HAVE_USLEEP)|g' \ + -e 's|@''HAVE_DECL_ENVIRON''@|$(HAVE_DECL_ENVIRON)|g' \ ++ -e 's|@''HAVE_DECL_FCHDIR''@|$(HAVE_DECL_FCHDIR)|g' \ ++ -e 's|@''HAVE_DECL_FDATASYNC''@|$(HAVE_DECL_FDATASYNC)|g' \ ++ -e 's|@''HAVE_DECL_GETDOMAINNAME''@|$(HAVE_DECL_GETDOMAINNAME)|g' \ + -e 's|@''HAVE_DECL_GETLOGIN_R''@|$(HAVE_DECL_GETLOGIN_R)|g' \ + -e 's|@''HAVE_DECL_GETPAGESIZE''@|$(HAVE_DECL_GETPAGESIZE)|g' \ + -e 's|@''HAVE_DECL_GETUSERSHELL''@|$(HAVE_DECL_GETUSERSHELL)|g' \ ++ -e 's|@''HAVE_DECL_SETHOSTNAME''@|$(HAVE_DECL_SETHOSTNAME)|g' \ ++ -e 's|@''HAVE_DECL_TTYNAME_R''@|$(HAVE_DECL_TTYNAME_R)|g' \ + -e 's|@''HAVE_OS_H''@|$(HAVE_OS_H)|g' \ + -e 's|@''HAVE_SYS_PARAM_H''@|$(HAVE_SYS_PARAM_H)|g' \ +- -e 's|@''REPLACE_CHOWN''@|$(REPLACE_CHOWN)|g' \ ++ | \ ++ sed -e 's|@''REPLACE_CHOWN''@|$(REPLACE_CHOWN)|g' \ + -e 's|@''REPLACE_CLOSE''@|$(REPLACE_CLOSE)|g' \ + -e 's|@''REPLACE_DUP''@|$(REPLACE_DUP)|g' \ + -e 's|@''REPLACE_DUP2''@|$(REPLACE_DUP2)|g' \ + -e 's|@''REPLACE_FCHOWNAT''@|$(REPLACE_FCHOWNAT)|g' \ ++ -e 's|@''REPLACE_FTRUNCATE''@|$(REPLACE_FTRUNCATE)|g' \ + -e 's|@''REPLACE_GETCWD''@|$(REPLACE_GETCWD)|g' \ ++ -e 's|@''REPLACE_GETDOMAINNAME''@|$(REPLACE_GETDOMAINNAME)|g' \ ++ -e 's|@''REPLACE_GETLOGIN_R''@|$(REPLACE_GETLOGIN_R)|g' \ + -e 's|@''REPLACE_GETGROUPS''@|$(REPLACE_GETGROUPS)|g' \ + -e 's|@''REPLACE_GETPAGESIZE''@|$(REPLACE_GETPAGESIZE)|g' \ ++ -e 's|@''REPLACE_ISATTY''@|$(REPLACE_ISATTY)|g' \ + -e 's|@''REPLACE_LCHOWN''@|$(REPLACE_LCHOWN)|g' \ + -e 's|@''REPLACE_LINK''@|$(REPLACE_LINK)|g' \ + -e 's|@''REPLACE_LINKAT''@|$(REPLACE_LINKAT)|g' \ + -e 's|@''REPLACE_LSEEK''@|$(REPLACE_LSEEK)|g' \ + -e 's|@''REPLACE_PREAD''@|$(REPLACE_PREAD)|g' \ + -e 's|@''REPLACE_PWRITE''@|$(REPLACE_PWRITE)|g' \ ++ -e 's|@''REPLACE_READ''@|$(REPLACE_READ)|g' \ + -e 's|@''REPLACE_READLINK''@|$(REPLACE_READLINK)|g' \ + -e 's|@''REPLACE_RMDIR''@|$(REPLACE_RMDIR)|g' \ + -e 's|@''REPLACE_SLEEP''@|$(REPLACE_SLEEP)|g' \ +@@ -1202,6 +1485,48 @@ EXTRA_DIST += unistd.in.h + + ## end gnulib module unistd + ++## begin gnulib module unitypes ++ ++BUILT_SOURCES += $(LIBUNISTRING_UNITYPES_H) ++ ++unitypes.h: unitypes.in.h ++ $(AM_V_GEN)rm -f $@-t $@ && \ ++ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ ++ cat $(srcdir)/unitypes.in.h; \ ++ } > $@-t && \ ++ mv -f $@-t $@ ++MOSTLYCLEANFILES += unitypes.h unitypes.h-t ++ ++EXTRA_DIST += unitypes.in.h ++ ++## end gnulib module unitypes ++ ++## begin gnulib module uniwidth/base ++ ++BUILT_SOURCES += $(LIBUNISTRING_UNIWIDTH_H) ++ ++uniwidth.h: uniwidth.in.h ++ $(AM_V_GEN)rm -f $@-t $@ && \ ++ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ ++ cat $(srcdir)/uniwidth.in.h; \ ++ } > $@-t && \ ++ mv -f $@-t $@ ++MOSTLYCLEANFILES += uniwidth.h uniwidth.h-t ++ ++EXTRA_DIST += localcharset.h uniwidth.in.h ++ ++## end gnulib module uniwidth/base ++ ++## begin gnulib module uniwidth/width ++ ++if LIBUNISTRING_COMPILE_UNIWIDTH_WIDTH ++libgnu_a_SOURCES += uniwidth/width.c ++endif ++ ++EXTRA_DIST += uniwidth/cjk.h ++ ++## end gnulib module uniwidth/width ++ + ## begin gnulib module vasnprintf + + +@@ -1213,7 +1538,8 @@ EXTRA_libgnu_a_SOURCES += asnprintf.c printf-args.c printf-parse.c vasnprintf.c + + ## begin gnulib module verify + +-libgnu_a_SOURCES += verify.h ++ ++EXTRA_DIST += verify.h + + ## end gnulib module verify + +@@ -1226,50 +1552,63 @@ EXTRA_libgnu_a_SOURCES += vsnprintf.c + + ## end gnulib module vsnprintf + +-## begin gnulib module warn-on-use +- +-BUILT_SOURCES += warn-on-use.h +-# The warn-on-use.h that gets inserted into generated .h files is the same as +-# build-aux/warn-on-use.h, except that it has the copyright header cut off. +-warn-on-use.h: $(top_srcdir)/build-aux/warn-on-use.h +- $(AM_V_GEN)rm -f $@-t $@ && \ +- sed -n -e '/^.ifndef/,$$p' \ +- < $(top_srcdir)/build-aux/warn-on-use.h \ +- > $@-t && \ +- mv $@-t $@ +-MOSTLYCLEANFILES += warn-on-use.h warn-on-use.h-t +- +-WARN_ON_USE_H=warn-on-use.h +- +-EXTRA_DIST += $(top_srcdir)/build-aux/warn-on-use.h +- +-## end gnulib module warn-on-use +- + ## begin gnulib module wchar + + BUILT_SOURCES += wchar.h + + # We need the following in order to create when the system + # version does not work standalone. +-wchar.h: wchar.in.h $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) ++wchar.h: wchar.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ +- sed -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ ++ sed -e 's|@''GUARD_PREFIX''@|GL|g' \ ++ -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ ++ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ ++ -e 's|@''HAVE_FEATURES_H''@|$(HAVE_FEATURES_H)|g' \ + -e 's|@''NEXT_WCHAR_H''@|$(NEXT_WCHAR_H)|g' \ + -e 's|@''HAVE_WCHAR_H''@|$(HAVE_WCHAR_H)|g' \ +- -e 's|@''GNULIB_BTOWC''@|$(GNULIB_BTOWC)|g' \ +- -e 's|@''GNULIB_WCTOB''@|$(GNULIB_WCTOB)|g' \ +- -e 's|@''GNULIB_MBSINIT''@|$(GNULIB_MBSINIT)|g' \ +- -e 's|@''GNULIB_MBRTOWC''@|$(GNULIB_MBRTOWC)|g' \ +- -e 's|@''GNULIB_MBRLEN''@|$(GNULIB_MBRLEN)|g' \ +- -e 's|@''GNULIB_MBSRTOWCS''@|$(GNULIB_MBSRTOWCS)|g' \ +- -e 's|@''GNULIB_MBSNRTOWCS''@|$(GNULIB_MBSNRTOWCS)|g' \ +- -e 's|@''GNULIB_WCRTOMB''@|$(GNULIB_WCRTOMB)|g' \ +- -e 's|@''GNULIB_WCSRTOMBS''@|$(GNULIB_WCSRTOMBS)|g' \ +- -e 's|@''GNULIB_WCSNRTOMBS''@|$(GNULIB_WCSNRTOMBS)|g' \ +- -e 's|@''GNULIB_WCWIDTH''@|$(GNULIB_WCWIDTH)|g' \ +- -e 's|@''HAVE_WINT_T''@|$(HAVE_WINT_T)|g' \ ++ -e 's/@''GNULIB_BTOWC''@/$(GNULIB_BTOWC)/g' \ ++ -e 's/@''GNULIB_WCTOB''@/$(GNULIB_WCTOB)/g' \ ++ -e 's/@''GNULIB_MBSINIT''@/$(GNULIB_MBSINIT)/g' \ ++ -e 's/@''GNULIB_MBRTOWC''@/$(GNULIB_MBRTOWC)/g' \ ++ -e 's/@''GNULIB_MBRLEN''@/$(GNULIB_MBRLEN)/g' \ ++ -e 's/@''GNULIB_MBSRTOWCS''@/$(GNULIB_MBSRTOWCS)/g' \ ++ -e 's/@''GNULIB_MBSNRTOWCS''@/$(GNULIB_MBSNRTOWCS)/g' \ ++ -e 's/@''GNULIB_WCRTOMB''@/$(GNULIB_WCRTOMB)/g' \ ++ -e 's/@''GNULIB_WCSRTOMBS''@/$(GNULIB_WCSRTOMBS)/g' \ ++ -e 's/@''GNULIB_WCSNRTOMBS''@/$(GNULIB_WCSNRTOMBS)/g' \ ++ -e 's/@''GNULIB_WCWIDTH''@/$(GNULIB_WCWIDTH)/g' \ ++ -e 's/@''GNULIB_WMEMCHR''@/$(GNULIB_WMEMCHR)/g' \ ++ -e 's/@''GNULIB_WMEMCMP''@/$(GNULIB_WMEMCMP)/g' \ ++ -e 's/@''GNULIB_WMEMCPY''@/$(GNULIB_WMEMCPY)/g' \ ++ -e 's/@''GNULIB_WMEMMOVE''@/$(GNULIB_WMEMMOVE)/g' \ ++ -e 's/@''GNULIB_WMEMSET''@/$(GNULIB_WMEMSET)/g' \ ++ -e 's/@''GNULIB_WCSLEN''@/$(GNULIB_WCSLEN)/g' \ ++ -e 's/@''GNULIB_WCSNLEN''@/$(GNULIB_WCSNLEN)/g' \ ++ -e 's/@''GNULIB_WCSCPY''@/$(GNULIB_WCSCPY)/g' \ ++ -e 's/@''GNULIB_WCPCPY''@/$(GNULIB_WCPCPY)/g' \ ++ -e 's/@''GNULIB_WCSNCPY''@/$(GNULIB_WCSNCPY)/g' \ ++ -e 's/@''GNULIB_WCPNCPY''@/$(GNULIB_WCPNCPY)/g' \ ++ -e 's/@''GNULIB_WCSCAT''@/$(GNULIB_WCSCAT)/g' \ ++ -e 's/@''GNULIB_WCSNCAT''@/$(GNULIB_WCSNCAT)/g' \ ++ -e 's/@''GNULIB_WCSCMP''@/$(GNULIB_WCSCMP)/g' \ ++ -e 's/@''GNULIB_WCSNCMP''@/$(GNULIB_WCSNCMP)/g' \ ++ -e 's/@''GNULIB_WCSCASECMP''@/$(GNULIB_WCSCASECMP)/g' \ ++ -e 's/@''GNULIB_WCSNCASECMP''@/$(GNULIB_WCSNCASECMP)/g' \ ++ -e 's/@''GNULIB_WCSCOLL''@/$(GNULIB_WCSCOLL)/g' \ ++ -e 's/@''GNULIB_WCSXFRM''@/$(GNULIB_WCSXFRM)/g' \ ++ -e 's/@''GNULIB_WCSDUP''@/$(GNULIB_WCSDUP)/g' \ ++ -e 's/@''GNULIB_WCSCHR''@/$(GNULIB_WCSCHR)/g' \ ++ -e 's/@''GNULIB_WCSRCHR''@/$(GNULIB_WCSRCHR)/g' \ ++ -e 's/@''GNULIB_WCSCSPN''@/$(GNULIB_WCSCSPN)/g' \ ++ -e 's/@''GNULIB_WCSSPN''@/$(GNULIB_WCSSPN)/g' \ ++ -e 's/@''GNULIB_WCSPBRK''@/$(GNULIB_WCSPBRK)/g' \ ++ -e 's/@''GNULIB_WCSSTR''@/$(GNULIB_WCSSTR)/g' \ ++ -e 's/@''GNULIB_WCSTOK''@/$(GNULIB_WCSTOK)/g' \ ++ -e 's/@''GNULIB_WCSWIDTH''@/$(GNULIB_WCSWIDTH)/g' \ ++ < $(srcdir)/wchar.in.h | \ ++ sed -e 's|@''HAVE_WINT_T''@|$(HAVE_WINT_T)|g' \ + -e 's|@''HAVE_BTOWC''@|$(HAVE_BTOWC)|g' \ + -e 's|@''HAVE_MBSINIT''@|$(HAVE_MBSINIT)|g' \ + -e 's|@''HAVE_MBRTOWC''@|$(HAVE_MBRTOWC)|g' \ +@@ -1279,9 +1618,38 @@ wchar.h: wchar.in.h $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) + -e 's|@''HAVE_WCRTOMB''@|$(HAVE_WCRTOMB)|g' \ + -e 's|@''HAVE_WCSRTOMBS''@|$(HAVE_WCSRTOMBS)|g' \ + -e 's|@''HAVE_WCSNRTOMBS''@|$(HAVE_WCSNRTOMBS)|g' \ ++ -e 's|@''HAVE_WMEMCHR''@|$(HAVE_WMEMCHR)|g' \ ++ -e 's|@''HAVE_WMEMCMP''@|$(HAVE_WMEMCMP)|g' \ ++ -e 's|@''HAVE_WMEMCPY''@|$(HAVE_WMEMCPY)|g' \ ++ -e 's|@''HAVE_WMEMMOVE''@|$(HAVE_WMEMMOVE)|g' \ ++ -e 's|@''HAVE_WMEMSET''@|$(HAVE_WMEMSET)|g' \ ++ -e 's|@''HAVE_WCSLEN''@|$(HAVE_WCSLEN)|g' \ ++ -e 's|@''HAVE_WCSNLEN''@|$(HAVE_WCSNLEN)|g' \ ++ -e 's|@''HAVE_WCSCPY''@|$(HAVE_WCSCPY)|g' \ ++ -e 's|@''HAVE_WCPCPY''@|$(HAVE_WCPCPY)|g' \ ++ -e 's|@''HAVE_WCSNCPY''@|$(HAVE_WCSNCPY)|g' \ ++ -e 's|@''HAVE_WCPNCPY''@|$(HAVE_WCPNCPY)|g' \ ++ -e 's|@''HAVE_WCSCAT''@|$(HAVE_WCSCAT)|g' \ ++ -e 's|@''HAVE_WCSNCAT''@|$(HAVE_WCSNCAT)|g' \ ++ -e 's|@''HAVE_WCSCMP''@|$(HAVE_WCSCMP)|g' \ ++ -e 's|@''HAVE_WCSNCMP''@|$(HAVE_WCSNCMP)|g' \ ++ -e 's|@''HAVE_WCSCASECMP''@|$(HAVE_WCSCASECMP)|g' \ ++ -e 's|@''HAVE_WCSNCASECMP''@|$(HAVE_WCSNCASECMP)|g' \ ++ -e 's|@''HAVE_WCSCOLL''@|$(HAVE_WCSCOLL)|g' \ ++ -e 's|@''HAVE_WCSXFRM''@|$(HAVE_WCSXFRM)|g' \ ++ -e 's|@''HAVE_WCSDUP''@|$(HAVE_WCSDUP)|g' \ ++ -e 's|@''HAVE_WCSCHR''@|$(HAVE_WCSCHR)|g' \ ++ -e 's|@''HAVE_WCSRCHR''@|$(HAVE_WCSRCHR)|g' \ ++ -e 's|@''HAVE_WCSCSPN''@|$(HAVE_WCSCSPN)|g' \ ++ -e 's|@''HAVE_WCSSPN''@|$(HAVE_WCSSPN)|g' \ ++ -e 's|@''HAVE_WCSPBRK''@|$(HAVE_WCSPBRK)|g' \ ++ -e 's|@''HAVE_WCSSTR''@|$(HAVE_WCSSTR)|g' \ ++ -e 's|@''HAVE_WCSTOK''@|$(HAVE_WCSTOK)|g' \ ++ -e 's|@''HAVE_WCSWIDTH''@|$(HAVE_WCSWIDTH)|g' \ + -e 's|@''HAVE_DECL_WCTOB''@|$(HAVE_DECL_WCTOB)|g' \ + -e 's|@''HAVE_DECL_WCWIDTH''@|$(HAVE_DECL_WCWIDTH)|g' \ +- -e 's|@''REPLACE_MBSTATE_T''@|$(REPLACE_MBSTATE_T)|g' \ ++ | \ ++ sed -e 's|@''REPLACE_MBSTATE_T''@|$(REPLACE_MBSTATE_T)|g' \ + -e 's|@''REPLACE_BTOWC''@|$(REPLACE_BTOWC)|g' \ + -e 's|@''REPLACE_WCTOB''@|$(REPLACE_WCTOB)|g' \ + -e 's|@''REPLACE_MBSINIT''@|$(REPLACE_MBSINIT)|g' \ +@@ -1293,10 +1661,10 @@ wchar.h: wchar.in.h $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) + -e 's|@''REPLACE_WCSRTOMBS''@|$(REPLACE_WCSRTOMBS)|g' \ + -e 's|@''REPLACE_WCSNRTOMBS''@|$(REPLACE_WCSNRTOMBS)|g' \ + -e 's|@''REPLACE_WCWIDTH''@|$(REPLACE_WCWIDTH)|g' \ ++ -e 's|@''REPLACE_WCSWIDTH''@|$(REPLACE_WCSWIDTH)|g' \ + -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ + -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ +- -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ +- < $(srcdir)/wchar.in.h; \ ++ -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)'; \ + } > $@-t && \ + mv $@-t $@ + MOSTLYCLEANFILES += wchar.h wchar.h-t +@@ -1314,24 +1682,35 @@ EXTRA_libgnu_a_SOURCES += wcrtomb.c + + ## end gnulib module wcrtomb + +-## begin gnulib module wctype ++## begin gnulib module wctype-h + + BUILT_SOURCES += wctype.h ++libgnu_a_SOURCES += wctype-h.c + + # We need the following in order to create when the system + # doesn't have one that works with the given compiler. +-wctype.h: wctype.in.h $(CXXDEFS_H) $(WARN_ON_USE_H) ++wctype.h: wctype.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_ON_USE_H) + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ +- sed -e 's/@''HAVE_WCTYPE_H''@/$(HAVE_WCTYPE_H)/g' \ ++ sed -e 's|@''GUARD_PREFIX''@|GL|g' \ ++ -e 's/@''HAVE_WCTYPE_H''@/$(HAVE_WCTYPE_H)/g' \ + -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ + -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ ++ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ + -e 's|@''NEXT_WCTYPE_H''@|$(NEXT_WCTYPE_H)|g' \ ++ -e 's/@''GNULIB_ISWBLANK''@/$(GNULIB_ISWBLANK)/g' \ ++ -e 's/@''GNULIB_WCTYPE''@/$(GNULIB_WCTYPE)/g' \ ++ -e 's/@''GNULIB_ISWCTYPE''@/$(GNULIB_ISWCTYPE)/g' \ ++ -e 's/@''GNULIB_WCTRANS''@/$(GNULIB_WCTRANS)/g' \ ++ -e 's/@''GNULIB_TOWCTRANS''@/$(GNULIB_TOWCTRANS)/g' \ + -e 's/@''HAVE_ISWBLANK''@/$(HAVE_ISWBLANK)/g' \ + -e 's/@''HAVE_ISWCNTRL''@/$(HAVE_ISWCNTRL)/g' \ ++ -e 's/@''HAVE_WCTYPE_T''@/$(HAVE_WCTYPE_T)/g' \ ++ -e 's/@''HAVE_WCTRANS_T''@/$(HAVE_WCTRANS_T)/g' \ + -e 's/@''HAVE_WINT_T''@/$(HAVE_WINT_T)/g' \ + -e 's/@''REPLACE_ISWBLANK''@/$(REPLACE_ISWBLANK)/g' \ + -e 's/@''REPLACE_ISWCNTRL''@/$(REPLACE_ISWCNTRL)/g' \ ++ -e 's/@''REPLACE_TOWLOWER''@/$(REPLACE_TOWLOWER)/g' \ + -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ + -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ + < $(srcdir)/wctype.in.h; \ +@@ -1341,11 +1720,20 @@ MOSTLYCLEANFILES += wctype.h wctype.h-t + + EXTRA_DIST += wctype.in.h + +-## end gnulib module wctype ++## end gnulib module wctype-h ++ ++## begin gnulib module wcwidth ++ ++ ++EXTRA_DIST += wcwidth.c ++ ++EXTRA_libgnu_a_SOURCES += wcwidth.c ++ ++## end gnulib module wcwidth + + ## begin gnulib module xsize + +-libgnu_a_SOURCES += xsize.h ++libgnu_a_SOURCES += xsize.h xsize.c + + ## end gnulib module xsize + +diff --git a/grub-core/gnulib/alloca.c b/grub-core/gnulib/alloca.c +index 75afdb9..ee0f018 100644 +--- a/grub-core/gnulib/alloca.c ++++ b/grub-core/gnulib/alloca.c +@@ -93,26 +93,15 @@ long i00afunc (); + static int stack_dir; /* 1 or -1 once known. */ + # define STACK_DIR stack_dir + +-static void +-find_stack_direction (void) ++static int ++find_stack_direction (int *addr, int depth) + { +- static char *addr = NULL; /* Address of first `dummy', once known. */ +- auto char dummy; /* To get stack address. */ +- +- if (addr == NULL) +- { /* Initial entry. */ +- addr = ADDRESS_FUNCTION (dummy); +- +- find_stack_direction (); /* Recurse once. */ +- } +- else +- { +- /* Second entry. */ +- if (ADDRESS_FUNCTION (dummy) > addr) +- stack_dir = 1; /* Stack grew upward. */ +- else +- stack_dir = -1; /* Stack grew downward. */ +- } ++ int dir, dummy = 0; ++ if (! addr) ++ addr = &dummy; ++ *addr = addr < &dummy ? 1 : addr == &dummy ? 0 : -1; ++ dir = depth ? find_stack_direction (addr, depth - 1) : 0; ++ return dir + dummy; + } + + # endif /* STACK_DIRECTION == 0 */ +@@ -155,7 +144,7 @@ alloca (size_t size) + + # if STACK_DIRECTION == 0 + if (STACK_DIR == 0) /* Unknown growth direction. */ +- find_stack_direction (); ++ STACK_DIR = find_stack_direction (NULL, (size & 1) + 20); + # endif + + /* Reclaim garbage, defined as all alloca'd storage that +@@ -486,4 +475,4 @@ i00afunc (long address) + # endif /* CRAY */ + + # endif /* no alloca */ +-#endif /* not GCC version 3 */ ++#endif /* not GCC 2 */ +diff --git a/grub-core/gnulib/alloca.in.h b/grub-core/gnulib/alloca.in.h +index 44f20b7..72d28ee 100644 +--- a/grub-core/gnulib/alloca.in.h ++++ b/grub-core/gnulib/alloca.in.h +@@ -1,6 +1,6 @@ + /* Memory allocation on the stack. + +- Copyright (C) 1995, 1999, 2001-2004, 2006-2010 Free Software Foundation, ++ Copyright (C) 1995, 1999, 2001-2004, 2006-2013 Free Software Foundation, + Inc. + + This program is free software; you can redistribute it and/or modify it +@@ -14,9 +14,9 @@ + 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. */ ++ License along with this program; if not, see ++ . ++ */ + + /* Avoid using the symbol _ALLOCA_H here, as Bison assumes _ALLOCA_H + means there is a real alloca function. */ +@@ -44,6 +44,13 @@ + # define alloca _alloca + # elif defined __DECC && defined __VMS + # define alloca __ALLOCA ++# elif defined __TANDEM && defined _TNS_E_TARGET ++# ifdef __cplusplus ++extern "C" ++# endif ++void *_alloca (unsigned short); ++# pragma intrinsic (_alloca) ++# define alloca _alloca + # else + # include + # ifdef __cplusplus +diff --git a/grub-core/gnulib/argp-ba.c b/grub-core/gnulib/argp-ba.c +index 95feabb..5abc9d0 100644 +--- a/grub-core/gnulib/argp-ba.c ++++ b/grub-core/gnulib/argp-ba.c +@@ -1,5 +1,5 @@ + /* Default definition for ARGP_PROGRAM_BUG_ADDRESS. +- Copyright (C) 1996, 1997, 1999, 2009, 2010 Free Software Foundation, Inc. ++ Copyright (C) 1996-1997, 1999, 2009-2013 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Written by Miles Bader . + +@@ -19,11 +19,11 @@ + /* 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.'. */ ++ 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 ++ BSS is sufficient. Not so on Mac OS X 10.3 and 10.4, see + + . */ + #if defined __ELF__ +diff --git a/grub-core/gnulib/argp-eexst.c b/grub-core/gnulib/argp-eexst.c +index 115a8cd..a8bb77f 100644 +--- a/grub-core/gnulib/argp-eexst.c ++++ b/grub-core/gnulib/argp-eexst.c +@@ -1,5 +1,5 @@ + /* Default definition for ARGP_ERR_EXIT_STATUS +- Copyright (C) 1997, 2009, 2010 Free Software Foundation, Inc. ++ Copyright (C) 1997, 2009-2013 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Written by Miles Bader . + +diff --git a/grub-core/gnulib/argp-fmtstream.c b/grub-core/gnulib/argp-fmtstream.c +index 248a09a..02406ff 100644 +--- a/grub-core/gnulib/argp-fmtstream.c ++++ b/grub-core/gnulib/argp-fmtstream.c +@@ -1,5 +1,5 @@ + /* Word-wrapping and line-truncating streams +- Copyright (C) 1997-1999, 2001-2003, 2005, 2009-2010 Free Software ++ Copyright (C) 1997-1999, 2001-2003, 2005, 2009-2013 Free Software + Foundation, Inc. + This file is part of the GNU C Library. + Written by Miles Bader . +@@ -17,7 +17,7 @@ + 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 ++/* This package emulates glibc 'line_wrap_stream' semantics for systems that + don't have that. */ + + #ifdef HAVE_CONFIG_H +@@ -33,6 +33,7 @@ + + #include "argp-fmtstream.h" + #include "argp-namefrob.h" ++#include "mbswidth.h" + + #ifndef ARGP_FMTSTREAM_USE_LINEWRAP + +@@ -118,51 +119,48 @@ weak_alias (__argp_fmtstream_free, argp_fmtstream_free) + #endif + + +-size_t +-__argp_get_display_len (const char *beg, const char *end) ++/* Return the pointer to the first character that doesn't fit in l columns. */ ++static inline const ptrdiff_t ++add_width (const char *ptr, const char *end, size_t l) + { +- const char *ptr; +- size_t r = 0; + mbstate_t ps; ++ const char *ptr0 = ptr; + + memset (&ps, 0, sizeof (ps)); + +- for (ptr = beg; ptr < end && *ptr; ) ++ while (ptr < end) + { + wchar_t wc; +- size_t s; ++ size_t s, k; + + s = mbrtowc (&wc, ptr, end - ptr, &ps); + if (s == (size_t) -1) + break; +- r += wcwidth (wc); +- ptr += s; +- } +- return r; +-} +- +-static inline char * +-add_length (char *ptr, char *end, size_t l) +-{ +- mbstate_t ps; +- +- memset (&ps, 0, sizeof (ps)); ++ if (s == (size_t) -2) ++ { ++ if (1 >= l) ++ break; ++ l--; ++ ptr++; ++ continue; ++ } + +- while (ptr < end && *ptr) +- { +- wchar_t wc; +- size_t s, k; ++ if (wc == '\e' && ptr + 3 < end ++ && ptr[1] == '[' && (ptr[2] == '0' || ptr[2] == '1') ++ && ptr[3] == 'm') ++ { ++ ptr += 4; ++ continue; ++ } + +- s = mbrtowc (&wc, ptr, end - ptr, &ps); +- if (s == (size_t) -1) +- break; + k = wcwidth (wc); ++ + if (k >= l) + break; + l -= k; + ptr += s; + } +- return ptr; ++ return ptr - ptr0; + } + + /* Process FS's buffer so that line wrapping is done from POINT_OFFS to the +@@ -217,15 +215,15 @@ __argp_fmtstream_update (argp_fmtstream_t fs) + + if (!nl) + { +- size_t display_len = __argp_get_display_len (buf, fs->p); ++ size_t display_width = mbsnwidth (buf, fs->p - buf, MBSW_STOP_AT_NUL); + /* The buffer ends in a partial line. */ + +- if (fs->point_col + display_len < fs->rmargin) ++ if (fs->point_col + display_width < 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 += display_len; ++ fs->point_col += display_width; + break; + } + else +@@ -235,8 +233,8 @@ __argp_fmtstream_update (argp_fmtstream_t fs) + } + else + { +- size_t display_len = __argp_get_display_len (buf, nl); +- if (display_len < (ssize_t) fs->rmargin) ++ size_t display_width = mbsnwidth (buf, nl - buf, MBSW_STOP_AT_NUL); ++ if (display_width < (ssize_t) fs->rmargin) + { + /* The buffer contains a full line that fits within the maximum + line width. Reset point and scan the next line. */ +@@ -280,7 +278,7 @@ __argp_fmtstream_update (argp_fmtstream_t fs) + char *p, *nextline; + int i; + +- p = add_length (buf, fs->p, (r + 1 - fs->point_col)); ++ p = buf + add_width (buf, fs->p, (r + 1 - fs->point_col)); + while (p >= buf && !isblank ((unsigned char) *p)) + --p; + nextline = p + 1; /* This will begin the next line. */ +@@ -298,7 +296,7 @@ __argp_fmtstream_update (argp_fmtstream_t fs) + { + /* A single word that is greater than the maximum line width. + Oh well. Put it on an overlong line by itself. */ +- p = add_length (buf, fs->p, (r + 1 - fs->point_col)); ++ p = buf + add_width (buf, fs->p, (r + 1 - fs->point_col)); + /* Find the end of the long word. */ + if (p < nl) + do +@@ -332,7 +330,8 @@ __argp_fmtstream_update (argp_fmtstream_t fs) + && fs->p > nextline) + { + /* The margin needs more blanks than we removed. */ +- if (__argp_get_display_len (fs->p, fs->end) > fs->wmargin + 1) ++ if (mbsnwidth (fs->p, fs->end - fs->p, MBSW_STOP_AT_NUL) ++ > fs->wmargin + 1) + /* Make some space for them. */ + { + size_t mv = fs->p - nextline; +diff --git a/grub-core/gnulib/argp-fmtstream.h b/grub-core/gnulib/argp-fmtstream.h +index 8a67817..000090e 100644 +--- a/grub-core/gnulib/argp-fmtstream.h ++++ b/grub-core/gnulib/argp-fmtstream.h +@@ -1,5 +1,5 @@ + /* Word-wrapping and line-truncating streams. +- Copyright (C) 1997, 2006-2010 Free Software Foundation, Inc. ++ Copyright (C) 1997, 2006-2013 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Written by Miles Bader . + +@@ -16,7 +16,7 @@ + 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 ++/* 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. */ +@@ -28,16 +28,16 @@ + #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 ++ We enable _GL_ATTRIBUTE_FORMAT 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 ++#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7) ++# define _GL_ATTRIBUTE_FORMAT(spec) __attribute__ ((__format__ spec)) ++#else ++# define _GL_ATTRIBUTE_FORMAT(spec) /* empty */ + #endif + + #if (_LIBC - 0 && !defined (USE_IN_LIBIO)) \ +@@ -128,12 +128,12 @@ 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))); ++ _GL_ATTRIBUTE_FORMAT ((printf, 2, 3)); + extern ssize_t argp_fmtstream_printf (argp_fmtstream_t __fs, + const char *__fmt, ...) +- __attribute__ ((__format__ (printf, 2, 3))); ++ _GL_ATTRIBUTE_FORMAT ((printf, 2, 3)); + +-#if _LIBC || !defined __OPTIMIZE__ ++#if _LIBC + extern int __argp_fmtstream_putc (argp_fmtstream_t __fs, int __ch); + extern int argp_fmtstream_putc (argp_fmtstream_t __fs, int __ch); + +@@ -154,7 +154,7 @@ extern size_t argp_fmtstream_write (argp_fmtstream_t __fs, + #define __argp_fmtstream_rmargin argp_fmtstream_rmargin + #define __argp_fmtstream_wmargin argp_fmtstream_wmargin + +-#if _LIBC || !defined __OPTIMIZE__ ++#if _LIBC + /* 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); +@@ -184,7 +184,7 @@ 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__ ++#if !_LIBC || defined __OPTIMIZE__ + /* Inline versions of above routines. */ + + #if !_LIBC +@@ -197,6 +197,10 @@ extern int __argp_fmtstream_ensure (argp_fmtstream_t __fs, size_t __amount); + #define __argp_fmtstream_point argp_fmtstream_point + #define __argp_fmtstream_update _argp_fmtstream_update + #define __argp_fmtstream_ensure _argp_fmtstream_ensure ++_GL_INLINE_HEADER_BEGIN ++#ifndef ARGP_FS_EI ++# define ARGP_FS_EI _GL_INLINE ++#endif + #endif + + #ifndef ARGP_FS_EI +@@ -335,9 +339,6 @@ __argp_fmtstream_point (argp_fmtstream_t __fs) + return __fs->point_col >= 0 ? __fs->point_col : 0; + } + +-size_t +-__argp_get_display_len (const char *beg, const char *end); +- + #if !_LIBC + #undef __argp_fmtstream_putc + #undef __argp_fmtstream_puts +@@ -348,9 +349,10 @@ __argp_get_display_len (const char *beg, const char *end); + #undef __argp_fmtstream_point + #undef __argp_fmtstream_update + #undef __argp_fmtstream_ensure ++_GL_INLINE_HEADER_END + #endif + +-#endif /* __OPTIMIZE__ */ ++#endif /* !_LIBC || __OPTIMIZE__ */ + + #endif /* ARGP_FMTSTREAM_USE_LINEWRAP */ + +diff --git a/grub-core/gnulib/argp-fs-xinl.c b/grub-core/gnulib/argp-fs-xinl.c +index 2c683f9..35547d9 100644 +--- a/grub-core/gnulib/argp-fs-xinl.c ++++ b/grub-core/gnulib/argp-fs-xinl.c +@@ -1,5 +1,5 @@ + /* Real definitions for extern inline functions in argp-fmtstream.h +- Copyright (C) 1997, 2003, 2004, 2009, 2010 Free Software Foundation, Inc. ++ Copyright (C) 1997, 2003-2004, 2009-2013 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Written by Miles Bader . + +@@ -20,7 +20,11 @@ + # include + #endif + +-#define ARGP_FS_EI ++#ifdef _LIBC ++# define ARGP_FS_EI ++#else ++# define ARGP_FS_EI _GL_EXTERN_INLINE ++#endif + #undef __OPTIMIZE__ + #define __OPTIMIZE__ 1 + #include "argp-fmtstream.h" +diff --git a/grub-core/gnulib/argp-help.c b/grub-core/gnulib/argp-help.c +index c82e38e..2914f47 100644 +--- a/grub-core/gnulib/argp-help.c ++++ b/grub-core/gnulib/argp-help.c +@@ -1,5 +1,5 @@ +-/* Hierarchial argument parsing help output +- Copyright (C) 1995-2005, 2007, 2009-2010 Free Software Foundation, Inc. ++/* Hierarchical argument parsing help output ++ Copyright (C) 1995-2005, 2007, 2009-2013 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Written by Miles Bader . + +@@ -29,6 +29,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -49,6 +50,7 @@ + #include "argp.h" + #include "argp-fmtstream.h" + #include "argp-namefrob.h" ++#include "mbswidth.h" + + #ifndef SIZE_MAX + # define SIZE_MAX ((size_t) -1) +@@ -56,7 +58,7 @@ + + /* User-selectable (using an environment variable) formatting parameters. + +- These may be specified in an environment variable called `ARGP_HELP_FMT', ++ 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. */ +@@ -73,13 +75,13 @@ + #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. */ ++ 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'. ++ 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 ++ 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; + +@@ -111,7 +113,7 @@ static struct uparams uparams = { + struct uparam_name + { + const char *name; /* User name. */ +- int is_bool; /* Whether it's `boolean'. */ ++ int is_bool; /* Whether it's 'boolean'. */ + size_t uparams_offs; /* Location of the (int) field in UPARAMS. */ + }; + +@@ -154,7 +156,7 @@ ARGP_HELP_FMT: %s value is less than or equal to %s"), + uparams.valid = 1; + } + +-/* Read user options from the environment, and fill in UPARAMS appropiately. */ ++/* Read user options from the environment, and fill in UPARAMS appropriately. */ + static void + fill_in_uparams (const struct argp_state *state) + { +@@ -259,7 +261,7 @@ fill_in_uparams (const struct argp_state *state) + /* 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. */ ++/* Returns true if OPT is a documentation-only entry. */ + #define odoc(opt) ((opt)->flags & OPTION_DOC) + + /* Returns true if OPT should not be translated */ +@@ -277,11 +279,11 @@ fill_in_uparams (const struct argp_state *state) + -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 ++ will be surrounded by "[" and "]" appropriately if the argument is ++ optional. The documentation string is word-wrapped appropriately, 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 ++ indented slightly 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): +@@ -359,7 +361,7 @@ struct hol_entry + /* 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 ++ most NUM. A short option recorded in an 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; +@@ -570,7 +572,9 @@ hol_entry_short_iterate (const struct hol_entry *entry, + } + + static inline int ++#if __GNUC__ >= 3 + __attribute__ ((always_inline)) ++#endif + hol_entry_long_iterate (const struct hol_entry *entry, + int (*func)(const struct argp_option *opt, + const struct argp_option *real, +@@ -711,7 +715,7 @@ hol_cluster_is_child (const struct hol_cluster *cl1, + return cl1 == cl2; + } + +-/* Given the name of a OPTION_DOC option, modifies NAME to start at the tail ++/* Given the name of an 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 +@@ -726,7 +730,7 @@ canon_doc_option (const char **name) + /* Skip initial whitespace. */ + while (isspace ((unsigned char) **name)) + (*name)++; +- /* Decide whether this looks like an option (leading `-') or not. */ ++ /* 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)) +@@ -751,9 +755,9 @@ hol_entry_cmp (const struct hol_entry *entry1, + 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. */ ++ directly, we have to use the appropriate clustering level too. */ + if (! entry1->cluster) +- /* ENTRY1 is at the `base level', not in a cluster, so we have to ++ /* 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. */ +@@ -783,7 +787,7 @@ hol_entry_cmp (const struct hol_entry *entry1, + doc2 = canon_doc_option (&long2); + + if (doc1 != doc2) +- /* `documentation' options always follow normal options (or ++ /* "documentation" options always follow normal options (or + documentation options that *look* like normal options). */ + return doc1 - doc2; + else if (!short1 && !short2 && long1 && long2) +@@ -889,7 +893,8 @@ hol_append (struct hol *hol, struct hol *more) + + /* 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); ++ e->short_options = ++ short_options + (e->short_options - hol->short_options); + + /* Now add the short options from MORE, fixing up its entries + too. */ +@@ -1020,7 +1025,7 @@ filter_doc (const char *doc, int key, const struct argp *argp, + return doc; + } + +-/* Prints STR as a header line, with the margin lines set appropiately, and ++/* Prints STR as a header line, with the margin lines set appropriately, 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 +@@ -1142,7 +1147,7 @@ hol_entry_help (struct hol_entry *entry, const struct argp_state *state, + + /* Now, long options. */ + if (odoc (real)) +- /* A `documentation' option. */ ++ /* A "documentation" option. */ + { + __argp_fmtstream_set_wmargin (stream, uparams.doc_opt_col); + for (opt = real, num = entry->num; num > 0; opt++, num--) +@@ -1436,7 +1441,7 @@ argp_args_usage (const struct argp *argp, const struct argp_state *state, + const char *cp = fdoc; + nl = __strchrnul (cp, '\n'); + if (*nl != '\0') +- /* This is a `multi-level' args doc; advance to the correct position ++ /* This is a "multi-level" args doc; advance to the correct position + as determined by our state in LEVELS, and update LEVELS. */ + { + int i; +@@ -1448,7 +1453,7 @@ argp_args_usage (const struct argp *argp, const struct argp_state *state, + + /* Manually do line wrapping so that it (probably) won't get wrapped at + any embedded spaces. */ +- space (stream, 1 + __argp_get_display_len (cp, nl)); ++ space (stream, 1 + mbsnwidth (cp, nl - cp, MBSW_STOP_AT_NUL)); + + __argp_fmtstream_write (stream, cp, nl - cp); + } +@@ -1477,9 +1482,9 @@ argp_args_usage (const struct argp *argp, const struct argp_state *state, + } + + /* Print the documentation for ARGP to STREAM; if POST is false, then +- everything preceeding a `\v' character in the documentation strings (or ++ everything preceding 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 ++ 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. */ +@@ -1549,7 +1554,7 @@ argp_doc (const struct argp *argp, const struct argp_state *state, + 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. */ ++ /* Now see if we have to output an ARGP_KEY_HELP_EXTRA text. */ + { + text = (*argp->help_filter) (ARGP_KEY_HELP_EXTRA, 0, input); + if (text) +@@ -1576,8 +1581,8 @@ argp_doc (const struct argp *argp, const struct argp_state *state, + } + + /* 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 ++ argp_state_help, STATE is the relevant 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, +@@ -1618,7 +1623,7 @@ _help (const struct argp *argp, const struct argp_state *state, FILE *stream, + } + + if (flags & (ARGP_HELP_USAGE | ARGP_HELP_SHORT_USAGE)) +- /* Print a short `Usage:' message. */ ++ /* Print a short "Usage:" message. */ + { + int first_pattern = 1, more_patterns; + size_t num_pattern_levels = argp_args_levels (argp); +@@ -1678,7 +1683,7 @@ _help (const struct argp *argp, const struct argp_state *state, FILE *stream, + if (flags & ARGP_HELP_SEE) + { + __argp_fmtstream_printf (fs, dgettext (argp->argp_domain, "\ +-Try `%s --help' or `%s --usage' for more information.\n"), ++Try '%s --help' or '%s --usage' for more information.\n"), + name, name); + anything = 1; + } +@@ -1721,7 +1726,7 @@ Try `%s --help' or `%s --usage' for more information.\n"), + } + + /* 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. */ ++ 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) + { +@@ -1779,7 +1784,7 @@ 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' ++ 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, ...) +@@ -1915,7 +1920,7 @@ __argp_failure (const struct argp_state *state, int status, int errnum, + char const *s = NULL; + putc_unlocked (':', stream); + putc_unlocked (' ', stream); +-#if _LIBC || (HAVE_DECL_STRERROR_R && STRERROR_R_CHAR_P) ++#if _LIBC || (HAVE_DECL_STRERROR_R && STRERROR_R_CHAR_P && !defined strerror_r) + s = __strerror_r (errnum, buf, sizeof buf); + #elif HAVE_DECL_STRERROR_R + if (__strerror_r (errnum, buf, sizeof buf) == 0) +diff --git a/grub-core/gnulib/argp-namefrob.h b/grub-core/gnulib/argp-namefrob.h +index 24581a6..6333958 100644 +--- a/grub-core/gnulib/argp-namefrob.h ++++ b/grub-core/gnulib/argp-namefrob.h +@@ -1,5 +1,5 @@ + /* Name frobnication for compiling argp outside of glibc +- Copyright (C) 1997, 2003, 2007, 2009, 2010 Free Software Foundation, Inc. ++ Copyright (C) 1997, 2003, 2007, 2009-2013 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Written by Miles Bader . + +@@ -100,45 +100,45 @@ + #endif + #if defined(HAVE_DECL_FEOF_UNLOCKED) && !HAVE_DECL_FEOF_UNLOCKED + # define feof_unlocked(x) feof (x) +-# endif ++#endif + #if defined(HAVE_DECL_FERROR_UNLOCKED) && !HAVE_DECL_FERROR_UNLOCKED + # define ferror_unlocked(x) ferror (x) +-# endif ++#endif + #if defined(HAVE_DECL_FFLUSH_UNLOCKED) && !HAVE_DECL_FFLUSH_UNLOCKED + # define fflush_unlocked(x) fflush (x) +-# endif ++#endif + #if defined(HAVE_DECL_FGETS_UNLOCKED) && !HAVE_DECL_FGETS_UNLOCKED + # define fgets_unlocked(x,y,z) fgets (x,y,z) +-# endif ++#endif + #if defined(HAVE_DECL_FPUTC_UNLOCKED) && !HAVE_DECL_FPUTC_UNLOCKED + # define fputc_unlocked(x,y) fputc (x,y) +-# endif ++#endif + #if defined(HAVE_DECL_FPUTS_UNLOCKED) && !HAVE_DECL_FPUTS_UNLOCKED + # define fputs_unlocked(x,y) fputs (x,y) +-# endif ++#endif + #if defined(HAVE_DECL_FREAD_UNLOCKED) && !HAVE_DECL_FREAD_UNLOCKED + # define fread_unlocked(w,x,y,z) fread (w,x,y,z) +-# endif ++#endif + #if defined(HAVE_DECL_FWRITE_UNLOCKED) && !HAVE_DECL_FWRITE_UNLOCKED + # define fwrite_unlocked(w,x,y,z) fwrite (w,x,y,z) +-# endif ++#endif + #if defined(HAVE_DECL_GETC_UNLOCKED) && !HAVE_DECL_GETC_UNLOCKED + # define getc_unlocked(x) getc (x) +-# endif ++#endif + #if defined(HAVE_DECL_GETCHAR_UNLOCKED) && !HAVE_DECL_GETCHAR_UNLOCKED + # define getchar_unlocked() getchar () +-# endif ++#endif + #if defined(HAVE_DECL_PUTC_UNLOCKED) && !HAVE_DECL_PUTC_UNLOCKED + # define putc_unlocked(x,y) putc (x,y) +-# endif ++#endif + #if defined(HAVE_DECL_PUTCHAR_UNLOCKED) && !HAVE_DECL_PUTCHAR_UNLOCKED + # define putchar_unlocked(x) putchar (x) +-# endif ++#endif + + #endif /* !_LIBC */ + + #ifndef __set_errno +-#define __set_errno(e) (errno = (e)) ++# define __set_errno(e) (errno = (e)) + #endif + + #if defined GNULIB_ARGP_DISABLE_DIRNAME +diff --git a/grub-core/gnulib/argp-parse.c b/grub-core/gnulib/argp-parse.c +index 9c05465..67ea32c 100644 +--- a/grub-core/gnulib/argp-parse.c ++++ b/grub-core/gnulib/argp-parse.c +@@ -1,5 +1,5 @@ +-/* Hierarchial argument parsing, layered over getopt +- Copyright (C) 1995-2000, 2002-2004, 2009-2010 Free Software Foundation, Inc. ++/* Hierarchical argument parsing, layered over getopt ++ Copyright (C) 1995-2000, 2002-2004, 2009-2013 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Written by Miles Bader . + +@@ -21,6 +21,7 @@ + #endif + + #include ++#include + #include + #include + #include +@@ -42,7 +43,6 @@ + #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. */ +@@ -154,8 +154,9 @@ argp_version_parser (int key, char *arg, struct argp_state *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!?")); ++ __argp_error (state, "%s", ++ dgettext (state->root_argp->argp_domain, ++ "(PROGRAM ERROR) No version known!?")); + if (! (state->flags & ARGP_NO_EXIT)) + exit (0); + break; +@@ -187,7 +188,7 @@ find_long_option (struct option *long_options, const char *name) + } + + +-/* The state of a `group' during parsing. Each group corresponds to a ++/* 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 +@@ -203,7 +204,7 @@ struct group + particular short options is from. */ + char *short_end; + +- /* The number of non-option args sucessfully handled by this parser. */ ++ /* The number of non-option args successfully handled by this parser. */ + unsigned args_processed; + + /* This group's parser's parent's group. */ +@@ -254,7 +255,7 @@ struct parser + struct group *groups; + /* The end of the GROUPS array. */ + struct group *egroup; +- /* An vector containing storage for the CHILD_INPUTS field in all groups. */ ++ /* A 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 +@@ -385,7 +386,7 @@ convert_options (const struct argp *argp, + return group; + } + +-/* Find the merged set of getopt options, with keys appropiately prefixed. */ ++/* Find the merged set of getopt options, with keys appropriately prefixed. */ + static void + parser_convert (struct parser *parser, const struct argp *argp, int flags) + { +@@ -439,7 +440,7 @@ calc_sizes (const struct argp *argp, struct parser_sizes *szs) + int num_opts = 0; + while (!__option_is_end (opt++)) + num_opts++; +- szs->short_len += num_opts * 3; /* opt + up to 2 `:'s */ ++ szs->short_len += num_opts * 3; /* opt + up to 2 ':'s */ + szs->long_len += num_opts; + } + } +@@ -781,7 +782,7 @@ parser_parse_next (struct parser *parser, int *arg_ebadkey) + + 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 ++ 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; +@@ -813,7 +814,7 @@ parser_parse_next (struct parser *parser, int *arg_ebadkey) + && 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 ++ "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; +@@ -879,11 +880,11 @@ __argp_parse (const struct argp *argp, int argc, char **argv, unsigned flags, + #ifndef _LIBC + if (!(flags & ARGP_PARSE_ARGV0)) + { +-#ifdef HAVE_DECL_PROGRAM_INVOCATION_NAME ++#if HAVE_DECL_PROGRAM_INVOCATION_NAME + if (!program_invocation_name) + program_invocation_name = argv[0]; + #endif +-#ifdef HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME ++#if HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME + if (!program_invocation_short_name) + program_invocation_short_name = __argp_base_name (argv[0]); + #endif +diff --git a/grub-core/gnulib/argp-pin.c b/grub-core/gnulib/argp-pin.c +index eda4d95..78cbb35 100644 +--- a/grub-core/gnulib/argp-pin.c ++++ b/grub-core/gnulib/argp-pin.c +@@ -1,5 +1,5 @@ + /* Full and short program names for argp module +- Copyright (C) 2005, 2009, 2010 Free Software Foundation, Inc. ++ Copyright (C) 2005, 2009-2013 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 +@@ -24,4 +24,3 @@ char *program_invocation_short_name = 0; + #ifndef HAVE_PROGRAM_INVOCATION_NAME + char *program_invocation_name = 0; + #endif +- +diff --git a/grub-core/gnulib/argp-pv.c b/grub-core/gnulib/argp-pv.c +index e3227d3..c74070d 100644 +--- a/grub-core/gnulib/argp-pv.c ++++ b/grub-core/gnulib/argp-pv.c +@@ -1,5 +1,5 @@ + /* Default definition for ARGP_PROGRAM_VERSION. +- Copyright (C) 1996, 1997, 1999, 2006, 2009, 2010 Free Software Foundation, ++ Copyright (C) 1996-1997, 1999, 2006, 2009-2013 Free Software Foundation, + Inc. + This file is part of the GNU C Library. + Written by Miles Bader . +@@ -23,7 +23,7 @@ + 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 ++ BSS is sufficient. Not so on Mac OS X 10.3 and 10.4, see + + . */ + #if defined __ELF__ +diff --git a/grub-core/gnulib/argp-pvh.c b/grub-core/gnulib/argp-pvh.c +index fb98fc2..885ff4b 100644 +--- a/grub-core/gnulib/argp-pvh.c ++++ b/grub-core/gnulib/argp-pvh.c +@@ -1,5 +1,5 @@ + /* Default definition for ARGP_PROGRAM_VERSION_HOOK. +- Copyright (C) 1996, 1997, 1999, 2004, 2009, 2010 Free Software Foundation, ++ Copyright (C) 1996-1997, 1999, 2004, 2009-2013 Free Software Foundation, + Inc. + This file is part of the GNU C Library. + Written by Miles Bader . +diff --git a/grub-core/gnulib/argp-xinl.c b/grub-core/gnulib/argp-xinl.c +index 6e7e20b..04d8cf7 100644 +--- a/grub-core/gnulib/argp-xinl.c ++++ b/grub-core/gnulib/argp-xinl.c +@@ -1,5 +1,5 @@ + /* Real definitions for extern inline functions in argp.h +- Copyright (C) 1997, 1998, 2004, 2009, 2010 Free Software Foundation, Inc. ++ Copyright (C) 1997-1998, 2004, 2009-2013 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Written by Miles Bader . + +@@ -27,7 +27,11 @@ + #ifndef __USE_EXTERN_INLINES + # define __USE_EXTERN_INLINES 1 + #endif +-#define ARGP_EI ++#ifdef _LIBC ++# define ARGP_EI ++#else ++# define ARGP_EI _GL_EXTERN_INLINE ++#endif + #undef __OPTIMIZE__ + #define __OPTIMIZE__ 1 + #include "argp.h" +diff --git a/grub-core/gnulib/argp.h b/grub-core/gnulib/argp.h +index 3667224..c4094a4 100644 +--- a/grub-core/gnulib/argp.h ++++ b/grub-core/gnulib/argp.h +@@ -1,5 +1,5 @@ +-/* Hierarchial argument parsing, layered over getopt. +- Copyright (C) 1995-1999, 2003-2010 Free Software Foundation, Inc. ++/* Hierarchical argument parsing, layered over getopt. ++ Copyright (C) 1995-1999, 2003-2013 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Written by Miles Bader . + +@@ -34,16 +34,16 @@ + # 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 ++ We enable _GL_ATTRIBUTE_FORMAT 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 ++#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7) ++# define _GL_ATTRIBUTE_FORMAT(spec) __attribute__ ((__format__ spec)) ++#else ++# define _GL_ATTRIBUTE_FORMAT(spec) /* empty */ + #endif + + /* GCC 2.95 and later have "__restrict"; C99 compilers have +@@ -94,7 +94,7 @@ struct argp_option + /* 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 `:'. ++ 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. */ +@@ -124,21 +124,21 @@ struct argp_option + /* 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 `--' ++ 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 ++ 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. */ ++ '-') in the same group. */ + #define OPTION_DOC 0x8 + +-/* This option shouldn't be included in `long' usage messages (but is still ++/* 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 ++ 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 +@@ -167,7 +167,7 @@ typedef error_t (*argp_parser_t) (int key, char *arg, + 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): ++ 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 +@@ -238,15 +238,15 @@ struct argp + 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 ++ 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:'). */ ++ 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). ++ '\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; +@@ -265,7 +265,7 @@ struct argp + 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 ++ 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. */ +@@ -278,7 +278,7 @@ struct argp + }; + + /* Possible KEY arguments to a help filter function. */ +-#define ARGP_KEY_HELP_PRE_DOC 0x2000001 /* Help text preceeding options. */ ++#define ARGP_KEY_HELP_PRE_DOC 0x2000001 /* Help text preceding 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; +@@ -304,7 +304,7 @@ struct argp_child + printing a header string, use a value of "". */ + const char *header; + +- /* Where to group the child options relative to the other (`consolidated') ++ /* 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 +@@ -337,7 +337,7 @@ struct argp_state + 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 ++ '--' argument (which prevents anything following being interpreted as an + option). Only set once argument parsing has proceeded past this point. */ + int quoted; + +@@ -399,7 +399,7 @@ struct argp_state + /* 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. */ ++/* Use the gnu getopt "long-only" rules for parsing arguments. */ + #define ARGP_LONG_ONLY 0x40 + + /* Turns off any message-printing/exiting options. */ +@@ -456,7 +456,7 @@ extern void (*argp_program_version_hook) (FILE *__restrict __stream, + 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.'. */ ++ "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. +@@ -467,7 +467,7 @@ 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_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. */ +@@ -506,7 +506,7 @@ extern void __argp_help (const struct argp *__restrict __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 *not* to exit, and should return an appropriate 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] */ + +@@ -519,21 +519,21 @@ extern void __argp_state_help (const struct argp_state *__restrict __state, + FILE *__restrict __stream, + unsigned int __flags); + +-#if _LIBC || !defined __USE_EXTERN_INLINES ++#if _LIBC + /* 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' ++ 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))); ++ _GL_ATTRIBUTE_FORMAT ((__printf__, 2, 3)); + extern void __argp_error (const struct argp_state *__restrict __state, + const char *__restrict __fmt, ...) +- __attribute__ ((__format__ (__printf__, 2, 3))); ++ _GL_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 +@@ -546,13 +546,13 @@ extern void __argp_error (const struct argp_state *__restrict __state, + extern void argp_failure (const struct argp_state *__restrict __state, + int __status, int __errnum, + const char *__restrict __fmt, ...) +- __attribute__ ((__format__ (__printf__, 4, 5))); ++ _GL_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))); ++ _GL_ATTRIBUTE_FORMAT ((__printf__, 4, 5)); + +-#if _LIBC || !defined __USE_EXTERN_INLINES ++#if _LIBC + /* 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; +@@ -572,13 +572,17 @@ extern void *__argp_input (const struct argp *__restrict __argp, + const struct argp_state *__restrict __state) + __THROW; + +-#ifdef __USE_EXTERN_INLINES ++#if !_LIBC || defined __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 ++_GL_INLINE_HEADER_BEGIN ++# ifndef ARGP_EI ++# define ARGP_EI _GL_INLINE ++# endif + # endif + + # ifndef ARGP_EI +@@ -635,6 +639,7 @@ __NTH (__option_is_end (const struct argp_option *__opt)) + # undef __argp_state_help + # undef __option_is_short + # undef __option_is_end ++_GL_INLINE_HEADER_END + # endif + #endif /* Use extern inlines. */ + +diff --git a/grub-core/gnulib/asnprintf.c b/grub-core/gnulib/asnprintf.c +index 3bd2229..76e228d 100644 +--- a/grub-core/gnulib/asnprintf.c ++++ b/grub-core/gnulib/asnprintf.c +@@ -1,5 +1,5 @@ + /* Formatted output to strings. +- Copyright (C) 1999, 2002, 2006, 2009, 2010 Free Software Foundation, Inc. ++ Copyright (C) 1999, 2002, 2006, 2009-2013 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 +@@ -12,8 +12,7 @@ + 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. */ ++ with this program; if not, see . */ + + #include + +diff --git a/grub-core/gnulib/basename-lgpl.c b/grub-core/gnulib/basename-lgpl.c +index a35ff01..9307e83 100644 +--- a/grub-core/gnulib/basename-lgpl.c ++++ b/grub-core/gnulib/basename-lgpl.c +@@ -1,6 +1,6 @@ + /* basename.c -- return the last element in a file name + +- Copyright (C) 1990, 1998-2001, 2003-2006, 2009-2010 Free Software ++ Copyright (C) 1990, 1998-2001, 2003-2006, 2009-2013 Free Software + Foundation, Inc. + + This program is free software: you can redistribute it and/or modify +diff --git a/grub-core/gnulib/btowc.c b/grub-core/gnulib/btowc.c +index 8744602..6c7cbec 100644 +--- a/grub-core/gnulib/btowc.c ++++ b/grub-core/gnulib/btowc.c +@@ -1,5 +1,5 @@ + /* Convert unibyte character to wide character. +- Copyright (C) 2008, 2010 Free Software Foundation, Inc. ++ Copyright (C) 2008, 2010-2013 Free Software Foundation, Inc. + Written by Bruno Haible , 2008. + + This program is free software: you can redistribute it and/or modify +diff --git a/grub-core/gnulib/config.charset b/grub-core/gnulib/config.charset +index aa7d00d..a991419 100644 +--- a/grub-core/gnulib/config.charset ++++ b/grub-core/gnulib/config.charset +@@ -1,7 +1,7 @@ + #! /bin/sh + # Output a system dependent table of character encoding aliases. + # +-# Copyright (C) 2000-2004, 2006-2010 Free Software Foundation, Inc. ++# Copyright (C) 2000-2004, 2006-2013 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 +@@ -14,8 +14,7 @@ + # 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. ++# with this program; if not, see . + # + # The table consists of lines of the form + # ALIAS CANONICAL +@@ -30,6 +29,8 @@ + # The current list of GNU canonical charset names is as follows. + # + # name MIME? used by which systems ++# (darwin = Mac OS X, woe32 = native Windows) ++# + # ASCII, ANSI_X3.4-1968 glibc solaris freebsd netbsd darwin cygwin + # ISO-8859-1 Y glibc aix hpux irix osf solaris freebsd netbsd openbsd darwin cygwin + # ISO-8859-2 Y glibc aix hpux irix osf solaris freebsd netbsd openbsd darwin cygwin +diff --git a/grub-core/gnulib/dirname-lgpl.c b/grub-core/gnulib/dirname-lgpl.c +index d4506e0..82f6630 100644 +--- a/grub-core/gnulib/dirname-lgpl.c ++++ b/grub-core/gnulib/dirname-lgpl.c +@@ -1,6 +1,6 @@ + /* dirname.c -- return all but the last element in a file name + +- Copyright (C) 1990, 1998, 2000-2001, 2003-2006, 2009-2010 Free Software ++ Copyright (C) 1990, 1998, 2000-2001, 2003-2006, 2009-2013 Free Software + Foundation, Inc. + + This program is free software: you can redistribute it and/or modify +@@ -25,7 +25,7 @@ + + /* Return the length of the prefix of FILE that will be used by + dir_name. If FILE is in the working directory, this returns zero +- even though `dir_name (FILE)' will return ".". Works properly even ++ even though 'dir_name (FILE)' will return ".". Works properly even + if there are trailing slashes (by effectively ignoring them). */ + + size_t +@@ -53,9 +53,9 @@ dir_len (char const *file) + } + + +-/* In general, we can't use the builtin `dirname' function if available, ++/* In general, we can't use the builtin 'dirname' function if available, + since it has different meanings in different environments. +- In some environments the builtin `dirname' modifies its argument. ++ In some environments the builtin 'dirname' modifies its argument. + + Return the leading directories part of FILE, allocated with malloc. + Works properly even if there are trailing slashes (by effectively +diff --git a/grub-core/gnulib/dirname.h b/grub-core/gnulib/dirname.h +index fb19508..4ad0312 100644 +--- a/grub-core/gnulib/dirname.h ++++ b/grub-core/gnulib/dirname.h +@@ -1,6 +1,6 @@ + /* Take file names apart into directory and base names. + +- Copyright (C) 1998, 2001, 2003-2006, 2009-2010 Free Software Foundation, ++ Copyright (C) 1998, 2001, 2003-2006, 2009-2013 Free Software Foundation, + Inc. + + This program is free software: you can redistribute it and/or modify +@@ -21,53 +21,25 @@ + + # include + # include ++# include "dosname.h" + + # ifndef DIRECTORY_SEPARATOR + # define DIRECTORY_SEPARATOR '/' + # endif + +-# ifndef ISSLASH +-# define ISSLASH(C) ((C) == DIRECTORY_SEPARATOR) +-# endif +- +-# ifndef FILE_SYSTEM_PREFIX_LEN +-# if FILE_SYSTEM_ACCEPTS_DRIVE_LETTER_PREFIX +- /* This internal macro assumes ASCII, but all hosts that support drive +- letters use ASCII. */ +-# define _IS_DRIVE_LETTER(c) (((unsigned int) (c) | ('a' - 'A')) - 'a' \ +- <= 'z' - 'a') +-# define FILE_SYSTEM_PREFIX_LEN(Filename) \ +- (_IS_DRIVE_LETTER ((Filename)[0]) && (Filename)[1] == ':' ? 2 : 0) +-# else +-# define FILE_SYSTEM_PREFIX_LEN(Filename) 0 +-# endif +-# endif +- +-# ifndef FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE +-# define FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE 0 +-# endif +- + # ifndef DOUBLE_SLASH_IS_DISTINCT_ROOT + # define DOUBLE_SLASH_IS_DISTINCT_ROOT 0 + # endif + +-# if FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE +-# define IS_ABSOLUTE_FILE_NAME(F) ISSLASH ((F)[FILE_SYSTEM_PREFIX_LEN (F)]) +-# else +-# define IS_ABSOLUTE_FILE_NAME(F) \ +- (ISSLASH ((F)[0]) || 0 < FILE_SYSTEM_PREFIX_LEN (F)) +-# endif +-# define IS_RELATIVE_FILE_NAME(F) (! IS_ABSOLUTE_FILE_NAME (F)) +- + # if GNULIB_DIRNAME + char *base_name (char const *file); + char *dir_name (char const *file); + # endif + + char *mdir_name (char const *file); +-size_t base_len (char const *file); +-size_t dir_len (char const *file); +-char *last_component (char const *file); ++size_t base_len (char const *file) _GL_ATTRIBUTE_PURE; ++size_t dir_len (char const *file) _GL_ATTRIBUTE_PURE; ++char *last_component (char const *file) _GL_ATTRIBUTE_PURE; + + bool strip_trailing_slashes (char *file); + +diff --git a/grub-core/gnulib/dosname.h b/grub-core/gnulib/dosname.h +new file mode 100644 +index 0000000..ba63ce4 +--- /dev/null ++++ b/grub-core/gnulib/dosname.h +@@ -0,0 +1,53 @@ ++/* File names on MS-DOS/Windows systems. ++ ++ Copyright (C) 2000-2001, 2004-2006, 2009-2013 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 . ++ ++ From Paul Eggert and Jim Meyering. */ ++ ++#ifndef _DOSNAME_H ++#define _DOSNAME_H ++ ++#if (defined _WIN32 || defined __WIN32__ || \ ++ defined __MSDOS__ || defined __CYGWIN__ || \ ++ defined __EMX__ || defined __DJGPP__) ++ /* This internal macro assumes ASCII, but all hosts that support drive ++ letters use ASCII. */ ++# define _IS_DRIVE_LETTER(C) (((unsigned int) (C) | ('a' - 'A')) - 'a' \ ++ <= 'z' - 'a') ++# define FILE_SYSTEM_PREFIX_LEN(Filename) \ ++ (_IS_DRIVE_LETTER ((Filename)[0]) && (Filename)[1] == ':' ? 2 : 0) ++# ifndef __CYGWIN__ ++# define FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE 1 ++# endif ++# define ISSLASH(C) ((C) == '/' || (C) == '\\') ++#else ++# define FILE_SYSTEM_PREFIX_LEN(Filename) 0 ++# define ISSLASH(C) ((C) == '/') ++#endif ++ ++#ifndef FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE ++# define FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE 0 ++#endif ++ ++#if FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE ++# define IS_ABSOLUTE_FILE_NAME(F) ISSLASH ((F)[FILE_SYSTEM_PREFIX_LEN (F)]) ++# else ++# define IS_ABSOLUTE_FILE_NAME(F) \ ++ (ISSLASH ((F)[0]) || FILE_SYSTEM_PREFIX_LEN (F) != 0) ++#endif ++#define IS_RELATIVE_FILE_NAME(F) (! IS_ABSOLUTE_FILE_NAME (F)) ++ ++#endif /* DOSNAME_H_ */ +diff --git a/grub-core/gnulib/errno.in.h b/grub-core/gnulib/errno.in.h +index 140e5d1..49b3546 100644 +--- a/grub-core/gnulib/errno.in.h ++++ b/grub-core/gnulib/errno.in.h +@@ -1,6 +1,6 @@ + /* A POSIX-like . + +- Copyright (C) 2008-2010 Free Software Foundation, Inc. ++ Copyright (C) 2008-2013 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 +@@ -13,69 +13,137 @@ + 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. */ ++ along with this program; if not, see . */ + +-#ifndef _GL_ERRNO_H ++#ifndef _@GUARD_PREFIX@_ERRNO_H + + #if __GNUC__ >= 3 + @PRAGMA_SYSTEM_HEADER@ + #endif ++@PRAGMA_COLUMNS@ + + /* The include_next requires a split double-inclusion guard. */ + #@INCLUDE_NEXT@ @NEXT_ERRNO_H@ + +-#ifndef _GL_ERRNO_H +-#define _GL_ERRNO_H ++#ifndef _@GUARD_PREFIX@_ERRNO_H ++#define _@GUARD_PREFIX@_ERRNO_H + + + /* On native Windows platforms, many macros are not defined. */ + # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ + +-/* POSIX says that EAGAIN and EWOULDBLOCK may have the same value. */ +-# define EWOULDBLOCK EAGAIN ++/* These are the same values as defined by MSVC 10, for interoperability. */ + +-/* Values >= 100 seem safe to use. */ +-# define ETXTBSY 100 +-# define GNULIB_defined_ETXTBSY 1 ++# ifndef ENOMSG ++# define ENOMSG 122 ++# define GNULIB_defined_ENOMSG 1 ++# endif ++ ++# ifndef EIDRM ++# define EIDRM 111 ++# define GNULIB_defined_EIDRM 1 ++# endif ++ ++# ifndef ENOLINK ++# define ENOLINK 121 ++# define GNULIB_defined_ENOLINK 1 ++# endif ++ ++# ifndef EPROTO ++# define EPROTO 134 ++# define GNULIB_defined_EPROTO 1 ++# endif ++ ++# ifndef EBADMSG ++# define EBADMSG 104 ++# define GNULIB_defined_EBADMSG 1 ++# endif ++ ++# ifndef EOVERFLOW ++# define EOVERFLOW 132 ++# define GNULIB_defined_EOVERFLOW 1 ++# endif ++ ++# ifndef ENOTSUP ++# define ENOTSUP 129 ++# define GNULIB_defined_ENOTSUP 1 ++# endif ++ ++# ifndef ENETRESET ++# define ENETRESET 117 ++# define GNULIB_defined_ENETRESET 1 ++# endif ++ ++# ifndef ECONNABORTED ++# define ECONNABORTED 106 ++# define GNULIB_defined_ECONNABORTED 1 ++# endif ++ ++# ifndef ECANCELED ++# define ECANCELED 105 ++# define GNULIB_defined_ECANCELED 1 ++# endif ++ ++# ifndef EOWNERDEAD ++# define EOWNERDEAD 133 ++# define GNULIB_defined_EOWNERDEAD 1 ++# endif ++ ++# ifndef ENOTRECOVERABLE ++# define ENOTRECOVERABLE 127 ++# define GNULIB_defined_ENOTRECOVERABLE 1 ++# endif ++ ++# ifndef EINPROGRESS ++# define EINPROGRESS 112 ++# define EALREADY 103 ++# define ENOTSOCK 128 ++# define EDESTADDRREQ 109 ++# define EMSGSIZE 115 ++# define EPROTOTYPE 136 ++# define ENOPROTOOPT 123 ++# define EPROTONOSUPPORT 135 ++# define EOPNOTSUPP 130 ++# define EAFNOSUPPORT 102 ++# define EADDRINUSE 100 ++# define EADDRNOTAVAIL 101 ++# define ENETDOWN 116 ++# define ENETUNREACH 118 ++# define ECONNRESET 108 ++# define ENOBUFS 119 ++# define EISCONN 113 ++# define ENOTCONN 126 ++# define ETIMEDOUT 138 ++# define ECONNREFUSED 107 ++# define ELOOP 114 ++# define EHOSTUNREACH 110 ++# define EWOULDBLOCK 140 ++# define GNULIB_defined_ESOCK 1 ++# endif ++ ++# ifndef ETXTBSY ++# define ETXTBSY 139 ++# define ENODATA 120 /* not required by POSIX */ ++# define ENOSR 124 /* not required by POSIX */ ++# define ENOSTR 125 /* not required by POSIX */ ++# define ETIME 137 /* not required by POSIX */ ++# define EOTHER 131 /* not required by POSIX */ ++# define GNULIB_defined_ESTREAMS 1 ++# endif + + /* These are intentionally the same values as the WSA* error numbers, defined + in . */ +-# define EINPROGRESS 10036 +-# define EALREADY 10037 +-# define ENOTSOCK 10038 +-# define EDESTADDRREQ 10039 +-# define EMSGSIZE 10040 +-# define EPROTOTYPE 10041 +-# define ENOPROTOOPT 10042 +-# define EPROTONOSUPPORT 10043 + # define ESOCKTNOSUPPORT 10044 /* not required by POSIX */ +-# define EOPNOTSUPP 10045 + # define EPFNOSUPPORT 10046 /* not required by POSIX */ +-# define EAFNOSUPPORT 10047 +-# define EADDRINUSE 10048 +-# define EADDRNOTAVAIL 10049 +-# define ENETDOWN 10050 +-# define ENETUNREACH 10051 +-# define ENETRESET 10052 +-# define ECONNABORTED 10053 +-# define ECONNRESET 10054 +-# define ENOBUFS 10055 +-# define EISCONN 10056 +-# define ENOTCONN 10057 + # define ESHUTDOWN 10058 /* not required by POSIX */ + # define ETOOMANYREFS 10059 /* not required by POSIX */ +-# define ETIMEDOUT 10060 +-# define ECONNREFUSED 10061 +-# define ELOOP 10062 + # define EHOSTDOWN 10064 /* not required by POSIX */ +-# define EHOSTUNREACH 10065 + # define EPROCLIM 10067 /* not required by POSIX */ + # define EUSERS 10068 /* not required by POSIX */ + # define EDQUOT 10069 + # define ESTALE 10070 + # define EREMOTE 10071 /* not required by POSIX */ +-# define GNULIB_defined_ESOCK 1 ++# define GNULIB_defined_EWINSOCK 1 + + # endif + +@@ -98,6 +166,7 @@ + + /* On OpenBSD 4.0 and on native Windows, the macros ENOMSG, EIDRM, ENOLINK, + EPROTO, EMULTIHOP, EBADMSG, EOVERFLOW, ENOTSUP, ECANCELED are not defined. ++ Likewise, on NonStop Kernel, EDQUOT is not defined. + Define them here. Values >= 2000 seem safe to use: Solaris ESTALE = 151, + HP-UX EWOULDBLOCK = 246, IRIX EDQUOT = 1133. + +@@ -145,16 +214,66 @@ + # define GNULIB_defined_ENOTSUP 1 + # endif + ++# ifndef ENETRESET ++# define ENETRESET 2011 ++# define GNULIB_defined_ENETRESET 1 ++# endif ++ ++# ifndef ECONNABORTED ++# define ECONNABORTED 2012 ++# define GNULIB_defined_ECONNABORTED 1 ++# endif ++ + # ifndef ESTALE + # define ESTALE 2009 + # define GNULIB_defined_ESTALE 1 + # endif + ++# ifndef EDQUOT ++# define EDQUOT 2010 ++# define GNULIB_defined_EDQUOT 1 ++# endif ++ + # ifndef ECANCELED + # define ECANCELED 2008 + # define GNULIB_defined_ECANCELED 1 + # endif + ++/* On many platforms, the macros EOWNERDEAD and ENOTRECOVERABLE are not ++ defined. */ ++ ++# ifndef EOWNERDEAD ++# if defined __sun ++ /* Use the same values as defined for Solaris >= 8, for ++ interoperability. */ ++# define EOWNERDEAD 58 ++# define ENOTRECOVERABLE 59 ++# elif (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ ++ /* We have a conflict here: pthreads-win32 defines these values ++ differently than MSVC 10. It's hairy to decide which one to use. */ ++# if defined __MINGW32__ && !defined USE_WINDOWS_THREADS ++ /* Use the same values as defined by pthreads-win32, for ++ interoperability. */ ++# define EOWNERDEAD 43 ++# define ENOTRECOVERABLE 44 ++# else ++ /* Use the same values as defined by MSVC 10, for ++ interoperability. */ ++# define EOWNERDEAD 133 ++# define ENOTRECOVERABLE 127 ++# endif ++# else ++# define EOWNERDEAD 2013 ++# define ENOTRECOVERABLE 2014 ++# endif ++# define GNULIB_defined_EOWNERDEAD 1 ++# define GNULIB_defined_ENOTRECOVERABLE 1 ++# endif ++ ++# ifndef EILSEQ ++# define EILSEQ 2015 ++# define GNULIB_defined_EILSEQ 1 ++# endif + +-#endif /* _GL_ERRNO_H */ +-#endif /* _GL_ERRNO_H */ ++#endif /* _@GUARD_PREFIX@_ERRNO_H */ ++#endif /* _@GUARD_PREFIX@_ERRNO_H */ +diff --git a/grub-core/gnulib/error.c b/grub-core/gnulib/error.c +index ed9dba0..865b293 100644 +--- a/grub-core/gnulib/error.c ++++ b/grub-core/gnulib/error.c +@@ -1,5 +1,5 @@ + /* Error handler for noninteractive utilities +- Copyright (C) 1990-1998, 2000-2007, 2009-2010 Free Software Foundation, Inc. ++ Copyright (C) 1990-1998, 2000-2007, 2009-2013 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 +@@ -54,7 +54,7 @@ + function without parameters instead. */ + void (*error_print_progname) (void); + +-/* This variable is incremented each time `error' is called. */ ++/* This variable is incremented each time 'error' is called. */ + unsigned int error_message_count; + + #ifdef _LIBC +@@ -65,7 +65,7 @@ unsigned int error_message_count; + # include + # include + +-/* In GNU libc we want do not want to use the common name `error' directly. ++/* In GNU libc we want do not want to use the common name 'error' directly. + Instead make it a weak alias. */ + extern void __error (int status, int errnum, const char *message, ...) + __attribute__ ((__format__ (__printf__, 3, 4))); +@@ -89,19 +89,25 @@ extern void __error_at_line (int status, int errnum, const char *file_name, + # include + + # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ +-/* Get declarations of the Win32 API functions. */ ++/* Get declarations of the native Windows API functions. */ + # define WIN32_LEAN_AND_MEAN + # include ++/* Get _get_osfhandle. */ ++# include "msvc-nothrow.h" + # endif + + /* The gnulib override of fcntl is not needed in this file. */ + # undef fcntl + +-# if !HAVE_DECL_STRERROR_R && STRERROR_R_CHAR_P ++# if !HAVE_DECL_STRERROR_R + # ifndef HAVE_DECL_STRERROR_R + "this configure-time declaration test was not run" + # endif ++# if STRERROR_R_CHAR_P + char *strerror_r (); ++# else ++int strerror_r (); ++# endif + # endif + + /* The calling program should define program_name and set it to the +@@ -115,13 +121,14 @@ extern char *program_name; + + #if !_LIBC + /* Return non-zero if FD is open. */ +-static inline int ++static int + is_open (int fd) + { + # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ +- /* On Win32: The initial state of unassigned standard file descriptors is +- that they are open but point to an INVALID_HANDLE_VALUE. There is no +- fcntl, and the gnulib replacement fcntl does not support F_GETFL. */ ++ /* On native Windows: The initial state of unassigned standard file ++ descriptors is that they are open but point to an INVALID_HANDLE_VALUE. ++ There is no fcntl, and the gnulib replacement fcntl does not support ++ F_GETFL. */ + return (HANDLE) _get_osfhandle (fd) != INVALID_HANDLE_VALUE; + # else + # ifndef F_GETFL +@@ -132,7 +139,7 @@ is_open (int fd) + } + #endif + +-static inline void ++static void + flush_stdout (void) + { + #if !_LIBC +diff --git a/grub-core/gnulib/error.h b/grub-core/gnulib/error.h +index 9deef02..afcb0e1 100644 +--- a/grub-core/gnulib/error.h ++++ b/grub-core/gnulib/error.h +@@ -1,6 +1,6 @@ + /* Declaration for error-reporting function +- Copyright (C) 1995, 1996, 1997, 2003, 2006, 2008, 2009, 2010 Free Software +- Foundation, Inc. ++ Copyright (C) 1995-1997, 2003, 2006, 2008-2013 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,39 +19,39 @@ + #ifndef _ERROR_H + #define _ERROR_H 1 + +-#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 ++ We enable _GL_ATTRIBUTE_FORMAT 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 ++#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7) ++# define _GL_ATTRIBUTE_FORMAT(spec) __attribute__ ((__format__ spec)) ++#else ++# define _GL_ATTRIBUTE_FORMAT(spec) /* empty */ + #endif + + #ifdef __cplusplus + extern "C" { + #endif + +-/* Print a message with `fprintf (stderr, FORMAT, ...)'; ++/* Print a message with 'fprintf (stderr, FORMAT, ...)'; + if ERRNUM is nonzero, follow it with ": " and strerror (ERRNUM). +- If STATUS is nonzero, terminate the program with `exit (STATUS)'. */ ++ If STATUS is nonzero, terminate the program with 'exit (STATUS)'. */ + + extern void error (int __status, int __errnum, const char *__format, ...) +- __attribute__ ((__format__ (__printf__, 3, 4))); ++ _GL_ATTRIBUTE_FORMAT ((__printf__, 3, 4)); + + extern void error_at_line (int __status, int __errnum, const char *__fname, + unsigned int __lineno, const char *__format, ...) +- __attribute__ ((__format__ (__printf__, 5, 6))); ++ _GL_ATTRIBUTE_FORMAT ((__printf__, 5, 6)); + + /* If NULL, error will flush stdout, then print on stderr the program + name, a colon and a space. Otherwise, error will call this + function without parameters instead. */ + extern void (*error_print_progname) (void); + +-/* This variable is incremented each time `error' is called. */ ++/* This variable is incremented each time 'error' is called. */ + extern unsigned int error_message_count; + + /* Sometimes we want to have at most one error per line. This +diff --git a/grub-core/gnulib/float+.h b/grub-core/gnulib/float+.h +index b55e5e6..32fb790 100644 +--- a/grub-core/gnulib/float+.h ++++ b/grub-core/gnulib/float+.h +@@ -1,5 +1,5 @@ + /* Supplemental information about the floating-point formats. +- Copyright (C) 2007, 2009, 2010 Free Software Foundation, Inc. ++ Copyright (C) 2007, 2009-2013 Free Software Foundation, Inc. + Written by Bruno Haible , 2007. + + This program is free software; you can redistribute it and/or modify +@@ -13,8 +13,7 @@ + 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. */ ++ along with this program; if not, see . */ + + #ifndef _FLOATPLUS_H + #define _FLOATPLUS_H +@@ -141,8 +140,8 @@ + #define SIZEOF_LDBL ((LDBL_TOTAL_BIT + CHAR_BIT - 1) / CHAR_BIT) + + /* Verify that SIZEOF_FLT <= sizeof (float) etc. */ +-typedef int verify_sizeof_flt[2 * (SIZEOF_FLT <= sizeof (float)) - 1]; +-typedef int verify_sizeof_dbl[2 * (SIZEOF_DBL <= sizeof (double)) - 1]; +-typedef int verify_sizeof_ldbl[2 * (SIZEOF_LDBL <= sizeof (long double)) - 1]; ++typedef int verify_sizeof_flt[SIZEOF_FLT <= sizeof (float) ? 1 : -1]; ++typedef int verify_sizeof_dbl[SIZEOF_DBL <= sizeof (double) ? 1 : - 1]; ++typedef int verify_sizeof_ldbl[SIZEOF_LDBL <= sizeof (long double) ? 1 : - 1]; + + #endif /* _FLOATPLUS_H */ +diff --git a/grub-core/gnulib/float.c b/grub-core/gnulib/float.c +new file mode 100644 +index 0000000..366945f +--- /dev/null ++++ b/grub-core/gnulib/float.c +@@ -0,0 +1,33 @@ ++/* Auxiliary definitions for . ++ Copyright (C) 2011-2013 Free Software Foundation, Inc. ++ Written by Bruno Haible , 2011. ++ ++ 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 ++ ++/* Specification. */ ++#include ++ ++#if (defined _ARCH_PPC || defined _POWER) && (defined _AIX || defined __linux__) && (LDBL_MANT_DIG == 106) && defined __GNUC__ ++const union gl_long_double_union gl_LDBL_MAX = ++ { { DBL_MAX, DBL_MAX / (double)134217728UL / (double)134217728UL } }; ++#elif defined __i386__ ++const union gl_long_double_union gl_LDBL_MAX = ++ { { 0xFFFFFFFF, 0xFFFFFFFF, 32766 } }; ++#else ++/* This declaration is solely to ensure that after preprocessing ++ this file is never empty. */ ++typedef int dummy; ++#endif +diff --git a/grub-core/gnulib/float.in.h b/grub-core/gnulib/float.in.h +index caf822f..84e1950 100644 +--- a/grub-core/gnulib/float.in.h ++++ b/grub-core/gnulib/float.in.h +@@ -1,6 +1,6 @@ + /* A correct . + +- Copyright (C) 2007-2010 Free Software Foundation, Inc. ++ Copyright (C) 2007-2013 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 +@@ -15,19 +15,21 @@ + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +-#ifndef _GL_FLOAT_H ++#ifndef _@GUARD_PREFIX@_FLOAT_H + + #if __GNUC__ >= 3 + @PRAGMA_SYSTEM_HEADER@ + #endif ++@PRAGMA_COLUMNS@ + + /* The include_next requires a split double-inclusion guard. */ + #@INCLUDE_NEXT@ @NEXT_FLOAT_H@ + +-#ifndef _GL_FLOAT_H +-#define _GL_FLOAT_H ++#ifndef _@GUARD_PREFIX@_FLOAT_H ++#define _@GUARD_PREFIX@_FLOAT_H + + /* 'long double' properties. */ ++ + #if defined __i386__ && (defined __BEOS__ || defined __OpenBSD__) + /* Number of mantissa units, in base FLT_RADIX. */ + # undef LDBL_MANT_DIG +@@ -58,5 +60,129 @@ + # define LDBL_MAX_10_EXP 4932 + #endif + +-#endif /* _GL_FLOAT_H */ +-#endif /* _GL_FLOAT_H */ ++/* On FreeBSD/x86 6.4, the 'long double' type really has only 53 bits of ++ precision in the compiler but 64 bits of precision at runtime. See ++ . */ ++#if defined __i386__ && defined __FreeBSD__ ++/* Number of mantissa units, in base FLT_RADIX. */ ++# undef LDBL_MANT_DIG ++# define LDBL_MANT_DIG 64 ++/* Number of decimal digits that is sufficient for representing a number. */ ++# undef LDBL_DIG ++# define LDBL_DIG 18 ++/* x-1 where x is the smallest representable number > 1. */ ++# undef LDBL_EPSILON ++# define LDBL_EPSILON 1.084202172485504434007452800869941711426e-19L /* 2^-63 */ ++/* Minimum e such that FLT_RADIX^(e-1) is a normalized number. */ ++# undef LDBL_MIN_EXP ++# define LDBL_MIN_EXP (-16381) ++/* Maximum e such that FLT_RADIX^(e-1) is a representable finite number. */ ++# undef LDBL_MAX_EXP ++# define LDBL_MAX_EXP 16384 ++/* Minimum positive normalized number. */ ++# undef LDBL_MIN ++# define LDBL_MIN 3.3621031431120935E-4932L /* = 0x1p-16382L */ ++/* Maximum representable finite number. */ ++# undef LDBL_MAX ++/* LDBL_MAX is represented as { 0xFFFFFFFF, 0xFFFFFFFF, 32766 }. ++ But the largest literal that GCC allows us to write is ++ 0x0.fffffffffffff8p16384L = { 0xFFFFF800, 0xFFFFFFFF, 32766 }. ++ So, define it like this through a reference to an external variable ++ ++ const unsigned int LDBL_MAX[3] = { 0xFFFFFFFF, 0xFFFFFFFF, 32766 }; ++ extern const long double LDBL_MAX; ++ ++ Unfortunately, this is not a constant expression. */ ++union gl_long_double_union ++ { ++ struct { unsigned int lo; unsigned int hi; unsigned int exponent; } xd; ++ long double ld; ++ }; ++extern const union gl_long_double_union gl_LDBL_MAX; ++# define LDBL_MAX (gl_LDBL_MAX.ld) ++/* Minimum e such that 10^e is in the range of normalized numbers. */ ++# undef LDBL_MIN_10_EXP ++# define LDBL_MIN_10_EXP (-4931) ++/* Maximum e such that 10^e is in the range of representable finite numbers. */ ++# undef LDBL_MAX_10_EXP ++# define LDBL_MAX_10_EXP 4932 ++#endif ++ ++/* On AIX 7.1 with gcc 4.2, the values of LDBL_MIN_EXP, LDBL_MIN, LDBL_MAX are ++ wrong. ++ On Linux/PowerPC with gcc 4.4, the value of LDBL_MAX is wrong. */ ++#if (defined _ARCH_PPC || defined _POWER) && defined _AIX && (LDBL_MANT_DIG == 106) && defined __GNUC__ ++# undef LDBL_MIN_EXP ++# define LDBL_MIN_EXP DBL_MIN_EXP ++# undef LDBL_MIN_10_EXP ++# define LDBL_MIN_10_EXP DBL_MIN_10_EXP ++# undef LDBL_MIN ++# define LDBL_MIN 2.22507385850720138309023271733240406422e-308L /* DBL_MIN = 2^-1022 */ ++#endif ++#if (defined _ARCH_PPC || defined _POWER) && (defined _AIX || defined __linux__) && (LDBL_MANT_DIG == 106) && defined __GNUC__ ++# undef LDBL_MAX ++/* LDBL_MAX is represented as { 0x7FEFFFFF, 0xFFFFFFFF, 0x7C8FFFFF, 0xFFFFFFFF }. ++ It is not easy to define: ++ #define LDBL_MAX 1.79769313486231580793728971405302307166e308L ++ is too small, whereas ++ #define LDBL_MAX 1.79769313486231580793728971405302307167e308L ++ is too large. Apparently a bug in GCC decimal-to-binary conversion. ++ Also, I can't get values larger than ++ #define LDBL63 ((long double) (1ULL << 63)) ++ #define LDBL882 (LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63) ++ #define LDBL945 (LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63) ++ #define LDBL1008 (LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63 * LDBL63) ++ #define LDBL_MAX (LDBL1008 * 65535.0L + LDBL945 * (long double) 9223372036821221375ULL + LDBL882 * (long double) 4611686018427387904ULL) ++ which is represented as { 0x7FEFFFFF, 0xFFFFFFFF, 0x7C8FFFFF, 0xF8000000 }. ++ So, define it like this through a reference to an external variable ++ ++ const double LDBL_MAX[2] = { DBL_MAX, DBL_MAX / (double)134217728UL / (double)134217728UL }; ++ extern const long double LDBL_MAX; ++ ++ or through a pointer cast ++ ++ #define LDBL_MAX \ ++ (*(const long double *) (double[]) { DBL_MAX, DBL_MAX / (double)134217728UL / (double)134217728UL }) ++ ++ Unfortunately, this is not a constant expression, and the latter expression ++ does not work well when GCC is optimizing.. */ ++union gl_long_double_union ++ { ++ struct { double hi; double lo; } dd; ++ long double ld; ++ }; ++extern const union gl_long_double_union gl_LDBL_MAX; ++# define LDBL_MAX (gl_LDBL_MAX.ld) ++#endif ++ ++/* On IRIX 6.5, with cc, the value of LDBL_MANT_DIG is wrong. ++ On IRIX 6.5, with gcc 4.2, the values of LDBL_MIN_EXP, LDBL_MIN, LDBL_EPSILON ++ are wrong. */ ++#if defined __sgi && (LDBL_MANT_DIG >= 106) ++# undef LDBL_MANT_DIG ++# define LDBL_MANT_DIG 106 ++# if defined __GNUC__ ++# undef LDBL_MIN_EXP ++# define LDBL_MIN_EXP DBL_MIN_EXP ++# undef LDBL_MIN_10_EXP ++# define LDBL_MIN_10_EXP DBL_MIN_10_EXP ++# undef LDBL_MIN ++# define LDBL_MIN 2.22507385850720138309023271733240406422e-308L /* DBL_MIN = 2^-1022 */ ++# undef LDBL_EPSILON ++# define LDBL_EPSILON 2.46519032881566189191165176650870696773e-32L /* 2^-105 */ ++# endif ++#endif ++ ++#if @REPLACE_ITOLD@ ++/* Pull in a function that fixes the 'int' to 'long double' conversion ++ of glibc 2.7. */ ++extern ++# ifdef __cplusplus ++"C" ++# endif ++void _Qp_itoq (long double *, int); ++static void (*_gl_float_fix_itold) (long double *, int) = _Qp_itoq; ++#endif ++ ++#endif /* _@GUARD_PREFIX@_FLOAT_H */ ++#endif /* _@GUARD_PREFIX@_FLOAT_H */ +diff --git a/grub-core/gnulib/fnmatch.c b/grub-core/gnulib/fnmatch.c +index d73e47d..6a09e1a 100644 +--- a/grub-core/gnulib/fnmatch.c ++++ b/grub-core/gnulib/fnmatch.c +@@ -1,5 +1,4 @@ +-/* Copyright (C) 1991, 1992, 1993, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +- 2003, 2004, 2005, 2006, 2007, 2009, 2010 Free Software Foundation, Inc. ++/* Copyright (C) 1991-1993, 1996-2007, 2009-2013 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 +@@ -12,8 +11,7 @@ + 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. */ ++ along with this program; if not, see . */ + + #ifndef _LIBC + # include +@@ -43,7 +41,7 @@ + (HAVE_WCTYPE_H && HAVE_BTOWC && HAVE_ISWCTYPE \ + && HAVE_WMEMCHR && (HAVE_WMEMCPY || HAVE_WMEMPCPY)) + +-/* For platform which support the ISO C amendement 1 functionality we ++/* For platform which support the ISO C amendment 1 functionality we + support user defined character classes. */ + #if defined _LIBC || WIDE_CHAR_SUPPORT + # include +@@ -79,7 +77,7 @@ extern int fnmatch (const char *pattern, const char *string, int flags); + Library, but also included in many other GNU distributions. Compiling + and linking in this code is a waste when using the GNU C library + (especially if it is a shared library). Rather than having every GNU +- program understand `configure --with-gnu-libc' and omit the object files, ++ program understand 'configure --with-gnu-libc' and omit the object files, + it is simpler to just do this in the source for each such file. */ + + #if defined _LIBC || !defined __GNU_LIBRARY__ || !HAVE_FNMATCH_GNU +@@ -93,7 +91,7 @@ extern int fnmatch (const char *pattern, const char *string, int flags); + + # if defined _LIBC || WIDE_CHAR_SUPPORT + /* The GNU C library provides support for user-defined character classes +- and the functions from ISO C amendement 1. */ ++ and the functions from ISO C amendment 1. */ + # ifdef CHARCLASS_NAME_MAX + # define CHAR_CLASS_MAX_LENGTH CHARCLASS_NAME_MAX + # else +@@ -120,7 +118,7 @@ extern int fnmatch (const char *pattern, const char *string, int flags); + # endif + + # else +-# define CHAR_CLASS_MAX_LENGTH 6 /* Namely, `xdigit'. */ ++# define CHAR_CLASS_MAX_LENGTH 6 /* Namely, 'xdigit'. */ + + # define IS_CHAR_CLASS(string) \ + (STREQ (string, "alpha") || STREQ (string, "upper") \ +@@ -169,7 +167,6 @@ static int posixly_correct; + # endif + # endif + # define MEMCHR(S, C, N) memchr (S, C, N) +-# define STRCOLL(S1, S2) strcoll (S1, S2) + # include "fnmatch_loop.c" + + +@@ -197,7 +194,6 @@ static int posixly_correct; + # endif + # endif + # define MEMCHR(S, C, N) wmemchr (S, C, N) +-# define STRCOLL(S1, S2) wcscoll (S1, S2) + # define WIDE_CHAR_VERSION 1 + + # undef IS_CHAR_CLASS +diff --git a/grub-core/gnulib/fnmatch.in.h b/grub-core/gnulib/fnmatch.in.h +index 8caab19..d39ce2f 100644 +--- a/grub-core/gnulib/fnmatch.in.h ++++ b/grub-core/gnulib/fnmatch.in.h +@@ -1,5 +1,5 @@ +-/* Copyright (C) 1991, 1992, 1993, 1996, 1997, 1998, 1999, 2001, 2002, 2003, +- 2005, 2007, 2009, 2010 Free Software Foundation, Inc. ++/* Copyright (C) 1991-1993, 1996-1999, 2001-2003, 2005, 2007, 2009-2013 Free ++ Software Foundation, Inc. + + This file is part of the GNU C Library. + +@@ -14,8 +14,7 @@ + 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. */ ++ along with this program; if not, see . */ + + #ifndef _FNMATCH_H + #define _FNMATCH_H 1 +@@ -32,23 +31,23 @@ extern "C" { + #undef FNM_NOESCAPE + #undef FNM_PERIOD + +-/* Bits set in the FLAGS argument to `fnmatch'. */ +-#define FNM_PATHNAME (1 << 0) /* No wildcard can ever match `/'. */ ++/* Bits set in the FLAGS argument to 'fnmatch'. */ ++#define FNM_PATHNAME (1 << 0) /* No wildcard can ever match '/'. */ + #define FNM_NOESCAPE (1 << 1) /* Backslashes don't quote special chars. */ +-#define FNM_PERIOD (1 << 2) /* Leading `.' is matched only explicitly. */ ++#define FNM_PERIOD (1 << 2) /* Leading '.' is matched only explicitly. */ + + #if !defined _POSIX_C_SOURCE || _POSIX_C_SOURCE < 2 || defined _GNU_SOURCE + # define FNM_FILE_NAME FNM_PATHNAME /* Preferred GNU name. */ +-# define FNM_LEADING_DIR (1 << 3) /* Ignore `/...' after a match. */ ++# define FNM_LEADING_DIR (1 << 3) /* Ignore '/...' after a match. */ + # define FNM_CASEFOLD (1 << 4) /* Compare without regard to case. */ + # define FNM_EXTMATCH (1 << 5) /* Use ksh-like extended matching. */ + #endif + +-/* Value returned by `fnmatch' if STRING does not match PATTERN. */ ++/* Value returned by 'fnmatch' if STRING does not match PATTERN. */ + #define FNM_NOMATCH 1 + + /* This value is returned if the implementation does not support +- `fnmatch'. Since this is not the case here it will never be ++ 'fnmatch'. Since this is not the case here it will never be + returned but the conformance test suites still require the symbol + to be defined. */ + #ifdef _XOPEN_SOURCE +diff --git a/grub-core/gnulib/fnmatch_loop.c b/grub-core/gnulib/fnmatch_loop.c +index 741c993..f57cd63 100644 +--- a/grub-core/gnulib/fnmatch_loop.c ++++ b/grub-core/gnulib/fnmatch_loop.c +@@ -1,5 +1,4 @@ +-/* Copyright (C) 1991, 1992, 1993, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +- 2003, 2004, 2005, 2006, 2009, 2010 Free Software Foundation, Inc. ++/* Copyright (C) 1991-1993, 1996-2006, 2009-2013 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 +@@ -13,8 +12,7 @@ + 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. */ ++ along with this program; if not, see . */ + + /* Match STRING against the file name pattern PATTERN, returning zero if + it matches, nonzero if not. */ +@@ -201,6 +199,8 @@ FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, + case L_('['): + { + /* Nonzero if the sense of the character class is inverted. */ ++ const CHAR *p_init = p; ++ const CHAR *n_init = n; + register bool not; + CHAR cold; + UCHAR fn; +@@ -215,7 +215,7 @@ FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, + return FNM_NOMATCH; + + if (*n == L_('/') && (flags & FNM_FILE_NAME)) +- /* `/' cannot be matched. */ ++ /* '/' cannot be matched. */ + return FNM_NOMATCH; + + not = (*p == L_('!') || (posixly_correct < 0 && *p == L_('^'))); +@@ -381,7 +381,7 @@ FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, + { + /* We found a table entry. Now see whether the + character we are currently at has the same +- equivalance class value. */ ++ equivalence class value. */ + int len = weights[idx & 0xffffff]; + int32_t idx2; + const UCHAR *np = (const UCHAR *) n; +@@ -411,8 +411,13 @@ FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, + } + #endif + else if (c == L_('\0')) +- /* [ (unterminated) loses. */ +- return FNM_NOMATCH; ++ { ++ /* [ unterminated, treat as normal character. */ ++ p = p_init; ++ n = n_init; ++ c = L_('['); ++ goto normal_match; ++ } + else + { + bool is_range = false; +@@ -630,7 +635,7 @@ FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, + UCHAR cend = *p++; + + # ifdef WIDE_CHAR_VERSION +- /* Search in the `names' array for the characters. */ ++ /* 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 +@@ -833,7 +838,7 @@ FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, + #else + /* We use a boring value comparison of the character + values. This is better than comparing using +- `strcoll' since the latter would have surprising ++ 'strcoll' since the latter would have surprising + and sometimes fatal consequences. */ + UCHAR cend = *p++; + +@@ -1150,7 +1155,7 @@ EXT (INT opt, const CHAR *pattern, const CHAR *string, const CHAR *string_end, + + case L_('@'): + do +- /* I cannot believe it but `strcat' is actually acceptable ++ /* 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. */ +@@ -1208,7 +1213,6 @@ EXT (INT opt, const CHAR *pattern, const CHAR *string, const CHAR *string_end, + #undef END + #undef MEMPCPY + #undef MEMCHR +-#undef STRCOLL + #undef STRLEN + #undef STRCAT + #undef L_ +diff --git a/grub-core/gnulib/getdelim.c b/grub-core/gnulib/getdelim.c +index 66d07b9..fdbcde2 100644 +--- a/grub-core/gnulib/getdelim.c ++++ b/grub-core/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, 2010 Free Software Foundation, Inc. ++ Copyright (C) 1994, 1996-1998, 2001, 2003, 2005-2013 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 +@@ -13,18 +13,16 @@ + 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. */ ++ along with this program; if not, see . */ + + /* Ported from glibc by Simon Josefsson. */ + +-#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 +diff --git a/grub-core/gnulib/getline.c b/grub-core/gnulib/getline.c +index 30c076e..1aa07b9 100644 +--- a/grub-core/gnulib/getline.c ++++ b/grub-core/gnulib/getline.c +@@ -1,5 +1,5 @@ + /* getline.c --- Implementation of replacement getline function. +- Copyright (C) 2005, 2006, 2007, 2009, 2010 Free Software Foundation, Inc. ++ Copyright (C) 2005-2007, 2009-2013 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 +@@ -12,9 +12,7 @@ + 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. */ ++ along with this program; if not, see . */ + + /* Written by Simon Josefsson. */ + +diff --git a/grub-core/gnulib/getopt.c b/grub-core/gnulib/getopt.c +index 3791f12..ef0f4ce 100644 +--- a/grub-core/gnulib/getopt.c ++++ b/grub-core/gnulib/getopt.c +@@ -2,7 +2,7 @@ + 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-1996, 1998-2004, 2006, 2008-2010 Free Software ++ Copyright (C) 1987-1996, 1998-2004, 2006, 2008-2013 Free Software + Foundation, Inc. + This file is part of the GNU C Library. + +@@ -41,15 +41,15 @@ + # include + #endif + +-/* This version of `getopt' appears to the caller like standard Unix `getopt' ++/* 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, ++ As 'getopt_long' works, it permutes the elements of ARGV so that, + when it is done, all the options precede everything else. Thus + all application programs are extended to handle flexible argument order. + +- Using `getopt' or setting the environment variable POSIXLY_CORRECT ++ Using 'getopt' or setting the environment variable POSIXLY_CORRECT + disables permutation. + Then the behavior is completely standard. + +@@ -58,24 +58,24 @@ + + #include "getopt_int.h" + +-/* For communication from `getopt' to the caller. +- When `getopt' finds an option that takes an argument, ++/* For communication from 'getopt' to the caller. ++ When 'getopt' finds an option that takes an argument, + the argument value is returned here. +- Also, when `ordering' is RETURN_IN_ORDER, ++ Also, when 'ordering' is RETURN_IN_ORDER, + each non-option ARGV-element is returned here. */ + + char *optarg; + + /* Index in ARGV of the next element to be scanned. + This is used for communication to and from the caller +- and for communication between successive calls to `getopt'. ++ and for communication between successive calls to 'getopt'. + +- On entry to `getopt', zero means this is the first call; initialize. ++ On entry to 'getopt', zero means this is the first call; initialize. + +- When `getopt' returns -1, this is the index of the first of the ++ When 'getopt' returns -1, this is the index of the first of the + non-option elements that the caller should itself scan. + +- Otherwise, `optind' communicates from one call to the next ++ Otherwise, 'optind' communicates from one call to the next + how much of ARGV has been scanned so far. */ + + /* 1003.2 says this must be 1 before any call. */ +@@ -137,7 +137,7 @@ extern char *__getopt_nonoption_flags; + The other is elements [last_nonopt,optind), which contains all + the options processed since those non-options were skipped. + +- `first_nonopt' and `last_nonopt' are relocated so that they describe ++ 'first_nonopt' and 'last_nonopt' are relocated so that they describe + the new indices of the non-options in ARGV after they are moved. */ + + static void +@@ -154,7 +154,7 @@ exchange (char **argv, struct _getopt_data *d) + but it consists of two parts that need to be swapped next. */ + + #if defined _LIBC && defined USE_NONOPTION_FLAGS +- /* First make sure the handling of the `__getopt_nonoption_flags' ++ /* First make sure the handling of the '__getopt_nonoption_flags' + string can work normally. Our top argument must be in the range + of the string. */ + if (d->__nonoption_flags_len > 0 && top >= d->__nonoption_flags_max_len) +@@ -291,48 +291,48 @@ _getopt_initialize (int argc _GL_UNUSED, + + If an element of ARGV starts with '-', and is not exactly "-" or "--", + then it is an option element. The characters of this element +- (aside from the initial '-') are option characters. If `getopt' ++ (aside from the initial '-') are option characters. If 'getopt' + is called repeatedly, it returns successively each of the option characters + from each of the option elements. + +- If `getopt' finds another option character, it returns that character, +- updating `optind' and `nextchar' so that the next call to `getopt' can ++ If 'getopt' finds another option character, it returns that character, ++ updating 'optind' and 'nextchar' so that the next call to 'getopt' can + resume the scan with the following option character or ARGV-element. + +- If there are no more option characters, `getopt' returns -1. +- Then `optind' is the index in ARGV of the first ARGV-element ++ If there are no more option characters, 'getopt' returns -1. ++ Then 'optind' is the index in ARGV of the first ARGV-element + that is not an option. (The ARGV-elements have been permuted + so that those that are not options now come last.) + + OPTSTRING is a string containing the legitimate option characters. + If an option character is seen that is not listed in OPTSTRING, +- return '?' after printing an error message. If you set `opterr' to ++ return '?' after printing an error message. If you set 'opterr' to + zero, the error message is suppressed but we still return '?'. + + If a char in OPTSTRING is followed by a colon, that means it wants an arg, + so the following text in the same ARGV-element, or the text of the following +- ARGV-element, is returned in `optarg'. Two colons mean an option that ++ ARGV-element, is returned in 'optarg'. Two colons mean an option that + wants an optional arg; if there is text in the current ARGV-element, +- it is returned in `optarg', otherwise `optarg' is set to zero. ++ it is returned in 'optarg', otherwise 'optarg' is set to zero. + +- If OPTSTRING starts with `-' or `+', it requests different methods of ++ If OPTSTRING starts with '-' or '+', it requests different methods of + handling the non-option ARGV-elements. + See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. + +- Long-named options begin with `--' instead of `-'. ++ Long-named options begin with '--' instead of '-'. + Their names may be abbreviated as long as the abbreviation is unique + or is an exact match for some defined option. If they have an + argument, it follows the option name in the same ARGV-element, separated +- from the option name by a `=', or else the in next ARGV-element. +- When `getopt' finds a long-named option, it returns 0 if that option's +- `flag' field is nonzero, the value of the option's `val' field +- if the `flag' field is zero. ++ from the option name by a '=', or else the in next ARGV-element. ++ When 'getopt' finds a long-named option, it returns 0 if that option's ++ '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 ++ LONGOPTS is a vector of 'struct option' terminated by an + element containing a name which is zero. + + LONGIND returns the index in LONGOPT of the long-named option found. +@@ -409,7 +409,7 @@ _getopt_internal_r (int argc, char **argv, const char *optstring, + d->__last_nonopt = d->optind; + } + +- /* The special ARGV-element `--' means premature end of options. ++ /* 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. */ +@@ -479,23 +479,28 @@ _getopt_internal_r (int argc, char **argv, const char *optstring, + || !strchr (optstring, argv[d->optind][1]))))) + { + char *nameend; ++ unsigned int namelen; + const struct option *p; + const struct option *pfound = NULL; ++ struct option_list ++ { ++ const struct option *p; ++ struct option_list *next; ++ } *ambig_list = NULL; + int exact = 0; +- int ambig = 0; + int indfound = -1; + int option_index; + + for (nameend = d->__nextchar; *nameend && *nameend != '='; nameend++) + /* Do nothing. */ ; ++ namelen = nameend - d->__nextchar; + + /* 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 (!strncmp (p->name, d->__nextchar, namelen)) + { +- if ((unsigned int) (nameend - d->__nextchar) +- == (unsigned int) strlen (p->name)) ++ if (namelen == (unsigned int) strlen (p->name)) + { + /* Exact match found. */ + pfound = p; +@@ -513,35 +518,71 @@ _getopt_internal_r (int argc, char **argv, const char *optstring, + || pfound->has_arg != p->has_arg + || pfound->flag != p->flag + || pfound->val != p->val) +- /* Second or later nonexact match found. */ +- ambig = 1; ++ { ++ /* Second or later nonexact match found. */ ++ struct option_list *newp = malloc (sizeof (*newp)); ++ newp->p = p; ++ newp->next = ambig_list; ++ ambig_list = newp; ++ } + } + +- if (ambig && !exact) ++ if (ambig_list != NULL && !exact) + { + if (print_errors) + { ++ struct option_list first; ++ first.p = pfound; ++ first.next = ambig_list; ++ ambig_list = &first; ++ + #if defined _LIBC && defined USE_IN_LIBIO +- char *buf; ++ char *buf = NULL; ++ size_t buflen = 0; + +- if (__asprintf (&buf, _("%s: option '%s' is ambiguous\n"), +- argv[0], argv[d->optind]) >= 0) ++ FILE *fp = open_memstream (&buf, &buflen); ++ if (fp != NULL) + { +- _IO_flockfile (stderr); ++ fprintf (fp, ++ _("%s: option '%s' is ambiguous; possibilities:"), ++ argv[0], argv[d->optind]); + +- int old_flags2 = ((_IO_FILE *) stderr)->_flags2; +- ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; ++ do ++ { ++ fprintf (fp, " '--%s'", ambig_list->p->name); ++ ambig_list = ambig_list->next; ++ } ++ while (ambig_list != NULL); + +- __fxprintf (NULL, "%s", buf); ++ fputc_unlocked ('\n', fp); + +- ((_IO_FILE *) stderr)->_flags2 = old_flags2; +- _IO_funlockfile (stderr); ++ if (__builtin_expect (fclose (fp) != EOF, 1)) ++ { ++ _IO_flockfile (stderr); + +- free (buf); ++ int old_flags2 = ((_IO_FILE *) stderr)->_flags2; ++ ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; ++ ++ __fxprintf (NULL, "%s", buf); ++ ++ ((_IO_FILE *) stderr)->_flags2 = old_flags2; ++ _IO_funlockfile (stderr); ++ ++ free (buf); ++ } + } + #else +- fprintf (stderr, _("%s: option '%s' is ambiguous\n"), ++ fprintf (stderr, ++ _("%s: option '%s' is ambiguous; possibilities:"), + argv[0], argv[d->optind]); ++ do ++ { ++ fprintf (stderr, " '--%s'", ambig_list->p->name); ++ ambig_list = ambig_list->next; ++ } ++ while (ambig_list != NULL); ++ ++ fputc ('\n', stderr); + #endif + } + d->__nextchar += strlen (d->__nextchar); +@@ -550,6 +591,13 @@ _getopt_internal_r (int argc, char **argv, const char *optstring, + return '?'; + } + ++ while (ambig_list != NULL) ++ { ++ struct option_list *pn = ambig_list->next; ++ free (ambig_list); ++ ambig_list = pn; ++ } ++ + if (pfound != NULL) + { + option_index = indfound; +@@ -740,7 +788,7 @@ _getopt_internal_r (int argc, char **argv, const char *optstring, + char c = *d->__nextchar++; + const char *temp = strchr (optstring, c); + +- /* Increment `optind' when we start to process its last character. */ ++ /* Increment 'optind' when we start to process its last character. */ + if (*d->__nextchar == '\0') + ++d->optind; + +@@ -791,6 +839,9 @@ _getopt_internal_r (int argc, char **argv, const char *optstring, + int indfound = 0; + int option_index; + ++ if (longopts == NULL) ++ goto no_longs; ++ + /* This is an option that requires an argument. */ + if (*d->__nextchar != '\0') + { +@@ -836,7 +887,7 @@ _getopt_internal_r (int argc, char **argv, const char *optstring, + return c; + } + else +- /* We already incremented `d->optind' once; ++ /* We already incremented 'd->optind' once; + increment it again when taking next ARGV-elt as argument. */ + d->optarg = argv[d->optind++]; + +@@ -998,8 +1049,10 @@ _getopt_internal_r (int argc, char **argv, const char *optstring, + } + return pfound->val; + } +- d->__nextchar = NULL; +- return 'W'; /* Let the application handle it. */ ++ ++ no_longs: ++ d->__nextchar = NULL; ++ return 'W'; /* Let the application handle it. */ + } + if (temp[1] == ':') + { +@@ -1061,7 +1114,7 @@ _getopt_internal_r (int argc, char **argv, const char *optstring, + c = '?'; + } + else +- /* We already incremented `optind' once; ++ /* We already incremented 'optind' once; + increment it again when taking next ARGV-elt as argument. */ + d->optarg = argv[d->optind++]; + d->__nextchar = NULL; +@@ -1124,7 +1177,7 @@ __posix_getopt (int argc, char *const *argv, const char *optstring) + #ifdef TEST + + /* Compile with -DTEST to make an executable for use in testing +- the above definition of `getopt'. */ ++ the above definition of 'getopt'. */ + + int + main (int argc, char **argv) +diff --git a/grub-core/gnulib/getopt.in.h b/grub-core/gnulib/getopt.in.h +index 57a8e89..d9c7d81 100644 +--- a/grub-core/gnulib/getopt.in.h ++++ b/grub-core/gnulib/getopt.in.h +@@ -1,5 +1,5 @@ + /* Declarations for getopt. +- Copyright (C) 1989-1994, 1996-1999, 2001, 2003-2007, 2009-2010 Free Software ++ Copyright (C) 1989-1994, 1996-1999, 2001, 2003-2007, 2009-2013 Free Software + Foundation, Inc. + This file is part of the GNU C Library. + +@@ -16,11 +16,12 @@ + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +-#ifndef _GL_GETOPT_H ++#ifndef _@GUARD_PREFIX@_GETOPT_H + + #if __GNUC__ >= 3 + @PRAGMA_SYSTEM_HEADER@ + #endif ++@PRAGMA_COLUMNS@ + + /* The include_next requires a split double-inclusion guard. We must + also inform the replacement unistd.h to not recursively use +@@ -31,10 +32,10 @@ + # undef _GL_SYSTEM_GETOPT + #endif + +-#ifndef _GL_GETOPT_H ++#ifndef _@GUARD_PREFIX@_GETOPT_H + + #ifndef __need_getopt +-# define _GL_GETOPT_H 1 ++# define _@GUARD_PREFIX@_GETOPT_H 1 + #endif + + /* Standalone applications should #define __GETOPT_PREFIX to an +@@ -48,7 +49,9 @@ + linkers. */ + #if defined __GETOPT_PREFIX && !defined __need_getopt + # if !@HAVE_GETOPT_H@ ++# define __need_system_stdlib_h + # include ++# undef __need_system_stdlib_h + # include + # include + # endif +@@ -81,7 +84,7 @@ + getopt_long_only can permute argv; this is required for backward + compatibility (e.g., for LSB 2.0.1). + +- This used to be `#if defined __GETOPT_PREFIX && !defined __need_getopt', ++ This used to be '#if defined __GETOPT_PREFIX && !defined __need_getopt', + but it caused redefinition warnings if both unistd.h and getopt.h were + included, since unistd.h includes getopt.h having previously defined + __need_getopt. +@@ -127,29 +130,29 @@ + extern "C" { + #endif + +-/* For communication from `getopt' to the caller. +- When `getopt' finds an option that takes an argument, ++/* For communication from 'getopt' to the caller. ++ When 'getopt' finds an option that takes an argument, + the argument value is returned here. +- Also, when `ordering' is RETURN_IN_ORDER, ++ Also, when 'ordering' is RETURN_IN_ORDER, + each non-option ARGV-element is returned here. */ + + extern char *optarg; + + /* Index in ARGV of the next element to be scanned. + This is used for communication to and from the caller +- and for communication between successive calls to `getopt'. ++ and for communication between successive calls to 'getopt'. + +- On entry to `getopt', zero means this is the first call; initialize. ++ On entry to 'getopt', zero means this is the first call; initialize. + +- When `getopt' returns -1, this is the index of the first of the ++ When 'getopt' returns -1, this is the index of the first of the + non-option elements that the caller should itself scan. + +- Otherwise, `optind' communicates from one call to the next ++ Otherwise, 'optind' communicates from one call to the next + how much of ARGV has been scanned so far. */ + + extern int optind; + +-/* Callers store zero here to inhibit the error message `getopt' prints ++/* Callers store zero here to inhibit the error message 'getopt' prints + for unrecognized options. */ + + extern int opterr; +@@ -161,25 +164,26 @@ extern int optopt; + #ifndef __need_getopt + /* Describe the long-named options requested by the application. + The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector +- of `struct option' terminated by an element containing a name which is ++ of 'struct option' terminated by an element containing a name which is + zero. + +- The field `has_arg' is: ++ The field 'has_arg' is: + no_argument (or 0) if the option does not take an argument, + required_argument (or 1) if the option requires an argument, + optional_argument (or 2) if the option takes an optional argument. + +- If the field `flag' is not NULL, it points to a variable that is set +- to the value given in the field `val' when the option is found, but ++ If the field 'flag' is not NULL, it points to a variable that is set ++ to the value given in the field 'val' when the option is found, but + left unchanged if the option is not found. + +- To have a long-named option do something other than set an `int' to +- a compiled-in constant, such as set a value from `optarg', set the +- option's `flag' field to zero and its `val' field to a nonzero ++ To have a long-named option do something other than set an 'int' to ++ a compiled-in constant, such as set a value from 'optarg', set the ++ option's 'flag' field to zero and its 'val' field to a nonzero + value (the equivalent single-letter option character, if there is +- one). For long options that have a zero `flag' field, `getopt' +- returns the contents of the `val' field. */ ++ one). For long options that have a zero 'flag' field, 'getopt' ++ returns the contents of the 'val' field. */ + ++# if !GNULIB_defined_struct_option + struct option + { + const char *name; +@@ -189,8 +193,10 @@ struct option + int *flag; + int val; + }; ++# define GNULIB_defined_struct_option 1 ++# endif + +-/* Names for the values of the `has_arg' field of `struct option'. */ ++/* Names for the values of the 'has_arg' field of 'struct option'. */ + + # define no_argument 0 + # define required_argument 1 +@@ -204,23 +210,23 @@ struct option + + Return the option character from OPTS just read. Return -1 when + there are no more options. For unrecognized options, or options +- missing arguments, `optopt' is set to the option letter, and '?' is ++ missing arguments, 'optopt' is set to the option letter, and '?' is + returned. + + The OPTS string is a list of characters which are recognized option + letters, optionally followed by colons, specifying that that letter +- takes an argument, to be placed in `optarg'. ++ takes an argument, to be placed in 'optarg'. + + If a letter in OPTS is followed by two colons, its argument is +- optional. This behavior is specific to the GNU `getopt'. ++ optional. This behavior is specific to the GNU 'getopt'. + +- The argument `--' causes premature termination of argument +- scanning, explicitly telling `getopt' that there are no more ++ The argument '--' causes premature termination of argument ++ scanning, explicitly telling 'getopt' that there are no more + options. + +- If OPTS begins with `-', then non-option arguments are treated as ++ If OPTS begins with '-', then non-option arguments are treated as + arguments to the option '\1'. This behavior is specific to the GNU +- `getopt'. If OPTS begins with `+', or POSIXLY_CORRECT is set in ++ 'getopt'. If OPTS begins with '+', or POSIXLY_CORRECT is set in + the environment, then do not permute arguments. */ + + extern int getopt (int ___argc, char *const *___argv, const char *__shortopts) +@@ -245,5 +251,5 @@ extern int getopt_long_only (int ___argc, char *__getopt_argv_const *___argv, + /* Make sure we later can get all the definitions and declarations. */ + #undef __need_getopt + +-#endif /* getopt.h */ +-#endif /* getopt.h */ ++#endif /* _@GUARD_PREFIX@_GETOPT_H */ ++#endif /* _@GUARD_PREFIX@_GETOPT_H */ +diff --git a/grub-core/gnulib/getopt1.c b/grub-core/gnulib/getopt1.c +index 046d69f..55a6b4e 100644 +--- a/grub-core/gnulib/getopt1.c ++++ b/grub-core/gnulib/getopt1.c +@@ -1,6 +1,6 @@ + /* getopt_long and getopt_long_only entry points for GNU getopt. +- Copyright (C) 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1996, 1997, +- 1998, 2004, 2006, 2009, 2010 Free Software Foundation, Inc. ++ Copyright (C) 1987-1994, 1996-1998, 2004, 2006, 2009-2013 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 +@@ -141,11 +141,11 @@ main (int argc, char **argv) + break; + + case 'c': +- printf ("option c with value `%s'\n", optarg); ++ printf ("option c with value '%s'\n", optarg); + break; + + case 'd': +- printf ("option d with value `%s'\n", optarg); ++ printf ("option d with value '%s'\n", optarg); + break; + + case '?': +diff --git a/grub-core/gnulib/getopt_int.h b/grub-core/gnulib/getopt_int.h +index 980b750..a6e4b9e 100644 +--- a/grub-core/gnulib/getopt_int.h ++++ b/grub-core/gnulib/getopt_int.h +@@ -1,5 +1,5 @@ + /* Internal declarations for getopt. +- Copyright (C) 1989-1994, 1996-1999, 2001, 2003-2004, 2009-2010 Free Software ++ Copyright (C) 1989-1994, 1996-1999, 2001, 2003-2004, 2009-2013 Free Software + Foundation, Inc. + This file is part of the GNU C Library. + +@@ -40,7 +40,7 @@ extern int _getopt_internal (int ___argc, char **___argv, + stop option processing when the first non-option is seen. + This is what Unix does. + This mode of operation is selected by either setting the environment +- variable POSIXLY_CORRECT, or using `+' as the first character ++ variable POSIXLY_CORRECT, or using '+' as the first character + of the list of option characters, or by calling getopt. + + PERMUTE is the default. We permute the contents of ARGV as we +@@ -52,12 +52,12 @@ extern int _getopt_internal (int ___argc, char **___argv, + written to 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. Using `-' as the first character of the ++ with character code 1. Using '-' as the first character of the + list of option characters selects this mode of operation. + +- The special argument `--' forces an end of option-scanning regardless +- of the value of `ordering'. In the case of RETURN_IN_ORDER, only +- `--' can cause `getopt' to return -1 with `optind' != ARGC. */ ++ The special argument '--' forces an end of option-scanning regardless ++ of the value of 'ordering'. In the case of RETURN_IN_ORDER, only ++ '--' can cause 'getopt' to return -1 with 'optind' != ARGC. */ + + enum __ord + { +@@ -99,8 +99,8 @@ struct _getopt_data + /* Handle permutation of arguments. */ + + /* Describe the part of ARGV that contains non-options that have +- been skipped. `first_nonopt' is the index in ARGV of the first +- of them; `last_nonopt' is the index after the last of them. */ ++ been skipped. 'first_nonopt' is the index in ARGV of the first ++ of them; 'last_nonopt' is the index after the last of them. */ + + int __first_nonopt; + int __last_nonopt; +@@ -108,7 +108,7 @@ struct _getopt_data + #if defined _LIBC && defined USE_NONOPTION_FLAGS + int __nonoption_flags_max_len; + int __nonoption_flags_len; +-# endif ++#endif + }; + + /* The initializer is necessary to set OPTIND and OPTERR to their +diff --git a/grub-core/gnulib/gettext.h b/grub-core/gnulib/gettext.h +index 881ae33..d021571 100644 +--- a/grub-core/gnulib/gettext.h ++++ b/grub-core/gnulib/gettext.h +@@ -1,5 +1,5 @@ + /* Convenience header for conditional use of GNU . +- Copyright (C) 1995-1998, 2000-2002, 2004-2006, 2009-2010 Free Software ++ Copyright (C) 1995-1998, 2000-2002, 2004-2006, 2009-2013 Free Software + Foundation, Inc. + + This program is free software; you can redistribute it and/or modify +@@ -13,8 +13,7 @@ + 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. */ ++ with this program; if not, see . */ + + #ifndef _LIBGETTEXT_H + #define _LIBGETTEXT_H 1 +@@ -54,7 +53,7 @@ + it now, to make later inclusions of a NOP. */ + #if defined(__cplusplus) && defined(__GNUG__) && (__GNUC__ >= 3) + # include +-# if (__GLIBC__ >= 2) || _GLIBCXX_HAVE_LIBINTL_H ++# if (__GLIBC__ >= 2 && !defined __UCLIBC__) || _GLIBCXX_HAVE_LIBINTL_H + # include + # endif + #endif +@@ -93,6 +92,12 @@ + + #endif + ++/* Prefer gnulib's setlocale override over libintl's setlocale override. */ ++#ifdef GNULIB_defined_setlocale ++# undef setlocale ++# define setlocale rpl_setlocale ++#endif ++ + /* A pseudo function call that serves as a marker for the automated + extraction of messages, but does not call gettext(). The run-time + translation is done at a different place in the code. +@@ -178,9 +183,12 @@ npgettext_aux (const char *domain, + + #include + +-#define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS \ +- (((__GNUC__ >= 3 || __GNUG__ >= 2) && !__STRICT_ANSI__) \ +- /* || __STDC_VERSION__ >= 199901L */ ) ++#if (((__GNUC__ >= 3 || __GNUG__ >= 2) && !defined __STRICT_ANSI__) \ ++ /* || __STDC_VERSION__ >= 199901L */ ) ++# define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS 1 ++#else ++# define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS 0 ++#endif + + #if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS + #include +diff --git a/grub-core/gnulib/intprops.h b/grub-core/gnulib/intprops.h +index 46f4d47..b473052 100644 +--- a/grub-core/gnulib/intprops.h ++++ b/grub-core/gnulib/intprops.h +@@ -1,7 +1,6 @@ + /* intprops.h -- properties of integer types + +- Copyright (C) 2001, 2002, 2003, 2004, 2005, 2009, 2010 Free Software +- Foundation, Inc. ++ Copyright (C) 2001-2005, 2009-2013 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 +@@ -18,66 +17,303 @@ + + /* Written by Paul Eggert. */ + +-#ifndef GL_INTPROPS_H +-# define GL_INTPROPS_H ++#ifndef _GL_INTPROPS_H ++#define _GL_INTPROPS_H + +-# include ++#include ++ ++/* Return an integer value, converted to the same type as the integer ++ expression E after integer type promotion. V is the unconverted value. */ ++#define _GL_INT_CONVERT(e, v) (0 * (e) + (v)) ++ ++/* Act like _GL_INT_CONVERT (E, -V) but work around a bug in IRIX 6.5 cc; see ++ . */ ++#define _GL_INT_NEGATE_CONVERT(e, v) (0 * (e) - (v)) + + /* The extra casts in the following macros work around compiler bugs, + e.g., in Cray C 5.0.3.0. */ + + /* True if the arithmetic type T is an integer type. bool counts as + an integer. */ +-# define TYPE_IS_INTEGER(t) ((t) 1.5 == 1) ++#define TYPE_IS_INTEGER(t) ((t) 1.5 == 1) + + /* True if negative values of the signed integer type T use two's + complement, ones' complement, or signed magnitude representation, + respectively. Much GNU code assumes two's complement, but some + people like to be portable to all possible C hosts. */ +-# define TYPE_TWOS_COMPLEMENT(t) ((t) ~ (t) 0 == (t) -1) +-# define TYPE_ONES_COMPLEMENT(t) ((t) ~ (t) 0 == 0) +-# define TYPE_SIGNED_MAGNITUDE(t) ((t) ~ (t) 0 < (t) -1) ++#define TYPE_TWOS_COMPLEMENT(t) ((t) ~ (t) 0 == (t) -1) ++#define TYPE_ONES_COMPLEMENT(t) ((t) ~ (t) 0 == 0) ++#define TYPE_SIGNED_MAGNITUDE(t) ((t) ~ (t) 0 < (t) -1) ++ ++/* True if the signed integer expression E uses two's complement. */ ++#define _GL_INT_TWOS_COMPLEMENT(e) (~ _GL_INT_CONVERT (e, 0) == -1) + + /* True if the arithmetic type T is signed. */ +-# define TYPE_SIGNED(t) (! ((t) 0 < (t) -1)) ++#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1)) + +-/* The maximum and minimum values for the integer type T. These ++/* Return 1 if the integer expression E, after integer promotion, has ++ a signed type. */ ++#define _GL_INT_SIGNED(e) (_GL_INT_NEGATE_CONVERT (e, 1) < 0) ++ ++ ++/* Minimum and maximum values for integer types and expressions. These + macros have undefined behavior if T is signed and has padding bits. + If this is a problem for you, please let us know how to fix it for + your host. */ +-# define TYPE_MINIMUM(t) \ +- ((t) (! TYPE_SIGNED (t) \ +- ? (t) 0 \ +- : TYPE_SIGNED_MAGNITUDE (t) \ +- ? ~ (t) 0 \ +- : ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1))) +-# define TYPE_MAXIMUM(t) \ +- ((t) (! TYPE_SIGNED (t) \ +- ? (t) -1 \ +- : ~ (~ (t) 0 << (sizeof (t) * CHAR_BIT - 1)))) +- +-/* Return zero if T can be determined to be an unsigned type. +- Otherwise, return 1. +- When compiling with GCC, INT_STRLEN_BOUND uses this macro to obtain a +- tighter bound. Otherwise, it overestimates the true bound by one byte +- when applied to unsigned types of size 2, 4, 16, ... bytes. +- The symbol signed_type_or_expr__ is private to this header file. */ +-# if __GNUC__ >= 2 +-# define signed_type_or_expr__(t) TYPE_SIGNED (__typeof__ (t)) +-# else +-# define signed_type_or_expr__(t) 1 +-# endif ++ ++/* The maximum and minimum values for the integer type T. */ ++#define TYPE_MINIMUM(t) \ ++ ((t) (! TYPE_SIGNED (t) \ ++ ? (t) 0 \ ++ : TYPE_SIGNED_MAGNITUDE (t) \ ++ ? ~ (t) 0 \ ++ : ~ TYPE_MAXIMUM (t))) ++#define TYPE_MAXIMUM(t) \ ++ ((t) (! TYPE_SIGNED (t) \ ++ ? (t) -1 \ ++ : ((((t) 1 << (sizeof (t) * CHAR_BIT - 2)) - 1) * 2 + 1))) ++ ++/* The maximum and minimum values for the type of the expression E, ++ after integer promotion. E should not have side effects. */ ++#define _GL_INT_MINIMUM(e) \ ++ (_GL_INT_SIGNED (e) \ ++ ? - _GL_INT_TWOS_COMPLEMENT (e) - _GL_SIGNED_INT_MAXIMUM (e) \ ++ : _GL_INT_CONVERT (e, 0)) ++#define _GL_INT_MAXIMUM(e) \ ++ (_GL_INT_SIGNED (e) \ ++ ? _GL_SIGNED_INT_MAXIMUM (e) \ ++ : _GL_INT_NEGATE_CONVERT (e, 1)) ++#define _GL_SIGNED_INT_MAXIMUM(e) \ ++ (((_GL_INT_CONVERT (e, 1) << (sizeof ((e) + 0) * CHAR_BIT - 2)) - 1) * 2 + 1) ++ ++ ++/* Return 1 if the __typeof__ keyword works. This could be done by ++ 'configure', but for now it's easier to do it by hand. */ ++#if 2 <= __GNUC__ || 0x5110 <= __SUNPRO_C ++# define _GL_HAVE___TYPEOF__ 1 ++#else ++# define _GL_HAVE___TYPEOF__ 0 ++#endif ++ ++/* Return 1 if the integer type or expression T might be signed. Return 0 ++ if it is definitely unsigned. This macro does not evaluate its argument, ++ and expands to an integer constant expression. */ ++#if _GL_HAVE___TYPEOF__ ++# define _GL_SIGNED_TYPE_OR_EXPR(t) TYPE_SIGNED (__typeof__ (t)) ++#else ++# define _GL_SIGNED_TYPE_OR_EXPR(t) 1 ++#endif ++ ++/* Bound on length of the string representing an unsigned integer ++ value representable in B bits. log10 (2.0) < 146/485. The ++ smallest value of B where this bound is not tight is 2621. */ ++#define INT_BITS_STRLEN_BOUND(b) (((b) * 146 + 484) / 485) + + /* Bound on length of the string representing an integer type or expression T. +- Subtract 1 for the sign bit if T is signed; log10 (2.0) < 146/485; +- add 1 for integer division truncation; add 1 more for a minus sign +- if needed. */ +-# define INT_STRLEN_BOUND(t) \ +- ((sizeof (t) * CHAR_BIT - signed_type_or_expr__ (t)) * 146 / 485 \ +- + signed_type_or_expr__ (t) + 1) ++ Subtract 1 for the sign bit if T is signed, and then add 1 more for ++ a minus sign if needed. ++ ++ Because _GL_SIGNED_TYPE_OR_EXPR sometimes returns 0 when its argument is ++ signed, this macro may overestimate the true bound by one byte when ++ applied to unsigned types of size 2, 4, 16, ... bytes. */ ++#define INT_STRLEN_BOUND(t) \ ++ (INT_BITS_STRLEN_BOUND (sizeof (t) * CHAR_BIT \ ++ - _GL_SIGNED_TYPE_OR_EXPR (t)) \ ++ + _GL_SIGNED_TYPE_OR_EXPR (t)) + + /* Bound on buffer size needed to represent an integer type or expression T, + including the terminating null. */ +-# define INT_BUFSIZE_BOUND(t) (INT_STRLEN_BOUND (t) + 1) ++#define INT_BUFSIZE_BOUND(t) (INT_STRLEN_BOUND (t) + 1) ++ ++ ++/* Range overflow checks. ++ ++ The INT__RANGE_OVERFLOW macros return 1 if the corresponding C ++ operators might not yield numerically correct answers due to ++ arithmetic overflow. They do not rely on undefined or ++ implementation-defined behavior. Their implementations are simple ++ and straightforward, but they are a bit harder to use than the ++ INT__OVERFLOW macros described below. ++ ++ Example usage: ++ ++ long int i = ...; ++ long int j = ...; ++ if (INT_MULTIPLY_RANGE_OVERFLOW (i, j, LONG_MIN, LONG_MAX)) ++ printf ("multiply would overflow"); ++ else ++ printf ("product is %ld", i * j); ++ ++ Restrictions on *_RANGE_OVERFLOW macros: ++ ++ These macros do not check for all possible numerical problems or ++ undefined or unspecified behavior: they do not check for division ++ by zero, for bad shift counts, or for shifting negative numbers. ++ ++ These macros may evaluate their arguments zero or multiple times, ++ so the arguments should not have side effects. The arithmetic ++ arguments (including the MIN and MAX arguments) must be of the same ++ integer type after the usual arithmetic conversions, and the type ++ must have minimum value MIN and maximum MAX. Unsigned types should ++ use a zero MIN of the proper type. ++ ++ These macros are tuned for constant MIN and MAX. For commutative ++ operations such as A + B, they are also tuned for constant B. */ ++ ++/* Return 1 if A + B would overflow in [MIN,MAX] arithmetic. ++ See above for restrictions. */ ++#define INT_ADD_RANGE_OVERFLOW(a, b, min, max) \ ++ ((b) < 0 \ ++ ? (a) < (min) - (b) \ ++ : (max) - (b) < (a)) ++ ++/* Return 1 if A - B would overflow in [MIN,MAX] arithmetic. ++ See above for restrictions. */ ++#define INT_SUBTRACT_RANGE_OVERFLOW(a, b, min, max) \ ++ ((b) < 0 \ ++ ? (max) + (b) < (a) \ ++ : (a) < (min) + (b)) ++ ++/* Return 1 if - A would overflow in [MIN,MAX] arithmetic. ++ See above for restrictions. */ ++#define INT_NEGATE_RANGE_OVERFLOW(a, min, max) \ ++ ((min) < 0 \ ++ ? (a) < - (max) \ ++ : 0 < (a)) ++ ++/* Return 1 if A * B would overflow in [MIN,MAX] arithmetic. ++ See above for restrictions. Avoid && and || as they tickle ++ bugs in Sun C 5.11 2010/08/13 and other compilers; see ++ . */ ++#define INT_MULTIPLY_RANGE_OVERFLOW(a, b, min, max) \ ++ ((b) < 0 \ ++ ? ((a) < 0 \ ++ ? (a) < (max) / (b) \ ++ : (b) == -1 \ ++ ? 0 \ ++ : (min) / (b) < (a)) \ ++ : (b) == 0 \ ++ ? 0 \ ++ : ((a) < 0 \ ++ ? (a) < (min) / (b) \ ++ : (max) / (b) < (a))) ++ ++/* Return 1 if A / B would overflow in [MIN,MAX] arithmetic. ++ See above for restrictions. Do not check for division by zero. */ ++#define INT_DIVIDE_RANGE_OVERFLOW(a, b, min, max) \ ++ ((min) < 0 && (b) == -1 && (a) < - (max)) ++ ++/* Return 1 if A % B would overflow in [MIN,MAX] arithmetic. ++ See above for restrictions. Do not check for division by zero. ++ Mathematically, % should never overflow, but on x86-like hosts ++ INT_MIN % -1 traps, and the C standard permits this, so treat this ++ as an overflow too. */ ++#define INT_REMAINDER_RANGE_OVERFLOW(a, b, min, max) \ ++ INT_DIVIDE_RANGE_OVERFLOW (a, b, min, max) ++ ++/* Return 1 if A << B would overflow in [MIN,MAX] arithmetic. ++ See above for restrictions. Here, MIN and MAX are for A only, and B need ++ not be of the same type as the other arguments. The C standard says that ++ behavior is undefined for shifts unless 0 <= B < wordwidth, and that when ++ A is negative then A << B has undefined behavior and A >> B has ++ implementation-defined behavior, but do not check these other ++ restrictions. */ ++#define INT_LEFT_SHIFT_RANGE_OVERFLOW(a, b, min, max) \ ++ ((a) < 0 \ ++ ? (a) < (min) >> (b) \ ++ : (max) >> (b) < (a)) ++ ++ ++/* The _GL*_OVERFLOW macros have the same restrictions as the ++ *_RANGE_OVERFLOW macros, except that they do not assume that operands ++ (e.g., A and B) have the same type as MIN and MAX. Instead, they assume ++ that the result (e.g., A + B) has that type. */ ++#define _GL_ADD_OVERFLOW(a, b, min, max) \ ++ ((min) < 0 ? INT_ADD_RANGE_OVERFLOW (a, b, min, max) \ ++ : (a) < 0 ? (b) <= (a) + (b) \ ++ : (b) < 0 ? (a) <= (a) + (b) \ ++ : (a) + (b) < (b)) ++#define _GL_SUBTRACT_OVERFLOW(a, b, min, max) \ ++ ((min) < 0 ? INT_SUBTRACT_RANGE_OVERFLOW (a, b, min, max) \ ++ : (a) < 0 ? 1 \ ++ : (b) < 0 ? (a) - (b) <= (a) \ ++ : (a) < (b)) ++#define _GL_MULTIPLY_OVERFLOW(a, b, min, max) \ ++ (((min) == 0 && (((a) < 0 && 0 < (b)) || ((b) < 0 && 0 < (a)))) \ ++ || INT_MULTIPLY_RANGE_OVERFLOW (a, b, min, max)) ++#define _GL_DIVIDE_OVERFLOW(a, b, min, max) \ ++ ((min) < 0 ? (b) == _GL_INT_NEGATE_CONVERT (min, 1) && (a) < - (max) \ ++ : (a) < 0 ? (b) <= (a) + (b) - 1 \ ++ : (b) < 0 && (a) + (b) <= (a)) ++#define _GL_REMAINDER_OVERFLOW(a, b, min, max) \ ++ ((min) < 0 ? (b) == _GL_INT_NEGATE_CONVERT (min, 1) && (a) < - (max) \ ++ : (a) < 0 ? (a) % (b) != ((max) - (b) + 1) % (b) \ ++ : (b) < 0 && ! _GL_UNSIGNED_NEG_MULTIPLE (a, b, max)) ++ ++/* Return a nonzero value if A is a mathematical multiple of B, where ++ A is unsigned, B is negative, and MAX is the maximum value of A's ++ type. A's type must be the same as (A % B)'s type. Normally (A % ++ -B == 0) suffices, but things get tricky if -B would overflow. */ ++#define _GL_UNSIGNED_NEG_MULTIPLE(a, b, max) \ ++ (((b) < -_GL_SIGNED_INT_MAXIMUM (b) \ ++ ? (_GL_SIGNED_INT_MAXIMUM (b) == (max) \ ++ ? (a) \ ++ : (a) % (_GL_INT_CONVERT (a, _GL_SIGNED_INT_MAXIMUM (b)) + 1)) \ ++ : (a) % - (b)) \ ++ == 0) ++ ++ ++/* Integer overflow checks. ++ ++ The INT__OVERFLOW macros return 1 if the corresponding C operators ++ might not yield numerically correct answers due to arithmetic overflow. ++ They work correctly on all known practical hosts, and do not rely ++ on undefined behavior due to signed arithmetic overflow. ++ ++ Example usage: ++ ++ long int i = ...; ++ long int j = ...; ++ if (INT_MULTIPLY_OVERFLOW (i, j)) ++ printf ("multiply would overflow"); ++ else ++ printf ("product is %ld", i * j); ++ ++ These macros do not check for all possible numerical problems or ++ undefined or unspecified behavior: they do not check for division ++ by zero, for bad shift counts, or for shifting negative numbers. ++ ++ These macros may evaluate their arguments zero or multiple times, so the ++ arguments should not have side effects. ++ ++ These macros are tuned for their last argument being a constant. ++ ++ Return 1 if the integer expressions A * B, A - B, -A, A * B, A / B, ++ A % B, and A << B would overflow, respectively. */ ++ ++#define INT_ADD_OVERFLOW(a, b) \ ++ _GL_BINARY_OP_OVERFLOW (a, b, _GL_ADD_OVERFLOW) ++#define INT_SUBTRACT_OVERFLOW(a, b) \ ++ _GL_BINARY_OP_OVERFLOW (a, b, _GL_SUBTRACT_OVERFLOW) ++#define INT_NEGATE_OVERFLOW(a) \ ++ INT_NEGATE_RANGE_OVERFLOW (a, _GL_INT_MINIMUM (a), _GL_INT_MAXIMUM (a)) ++#define INT_MULTIPLY_OVERFLOW(a, b) \ ++ _GL_BINARY_OP_OVERFLOW (a, b, _GL_MULTIPLY_OVERFLOW) ++#define INT_DIVIDE_OVERFLOW(a, b) \ ++ _GL_BINARY_OP_OVERFLOW (a, b, _GL_DIVIDE_OVERFLOW) ++#define INT_REMAINDER_OVERFLOW(a, b) \ ++ _GL_BINARY_OP_OVERFLOW (a, b, _GL_REMAINDER_OVERFLOW) ++#define INT_LEFT_SHIFT_OVERFLOW(a, b) \ ++ INT_LEFT_SHIFT_RANGE_OVERFLOW (a, b, \ ++ _GL_INT_MINIMUM (a), _GL_INT_MAXIMUM (a)) ++ ++/* Return 1 if the expression A B would overflow, ++ where OP_RESULT_OVERFLOW (A, B, MIN, MAX) does the actual test, ++ assuming MIN and MAX are the minimum and maximum for the result type. ++ Arguments should be free of side effects. */ ++#define _GL_BINARY_OP_OVERFLOW(a, b, op_result_overflow) \ ++ op_result_overflow (a, b, \ ++ _GL_INT_MINIMUM (0 * (b) + (a)), \ ++ _GL_INT_MAXIMUM (0 * (b) + (a))) + +-#endif /* GL_INTPROPS_H */ ++#endif /* _GL_INTPROPS_H */ +diff --git a/grub-core/gnulib/itold.c b/grub-core/gnulib/itold.c +new file mode 100644 +index 0000000..9aabc7e +--- /dev/null ++++ b/grub-core/gnulib/itold.c +@@ -0,0 +1,28 @@ ++/* Replacement for 'int' to 'long double' conversion routine. ++ Copyright (C) 2011-2013 Free Software Foundation, Inc. ++ Written by Bruno Haible , 2011. ++ ++ 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 ++ ++/* Specification. */ ++#include ++ ++void ++_Qp_itoq (long double *result, int a) ++{ ++ /* Convert from 'int' to 'double', then from 'double' to 'long double'. */ ++ *result = (double) a; ++} +diff --git a/grub-core/gnulib/langinfo.in.h b/grub-core/gnulib/langinfo.in.h +index 3a92647..5388ce6 100644 +--- a/grub-core/gnulib/langinfo.in.h ++++ b/grub-core/gnulib/langinfo.in.h +@@ -1,5 +1,5 @@ + /* Substitute for and wrapper around . +- Copyright (C) 2009, 2010 Free Software Foundation, Inc. ++ Copyright (C) 2009-2013 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 +@@ -12,27 +12,27 @@ + 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. */ ++ along with this program; if not, see . */ + + /* + * POSIX for platforms that lack it or have an incomplete one. + * + */ + +-#ifndef _GL_LANGINFO_H ++#ifndef _@GUARD_PREFIX@_LANGINFO_H + + #if __GNUC__ >= 3 + @PRAGMA_SYSTEM_HEADER@ + #endif ++@PRAGMA_COLUMNS@ + + /* The include_next requires a split double-inclusion guard. */ + #if @HAVE_LANGINFO_H@ + # @INCLUDE_NEXT@ @NEXT_LANGINFO_H@ + #endif + +-#ifndef _GL_LANGINFO_H +-#define _GL_LANGINFO_H ++#ifndef _@GUARD_PREFIX@_LANGINFO_H ++#define _@GUARD_PREFIX@_LANGINFO_H + + + #if !@HAVE_LANGINFO_H@ +@@ -40,7 +40,10 @@ + /* A platform that lacks . */ + + /* Assume that it also lacks and the nl_item type. */ ++# if !GNULIB_defined_nl_item + typedef int nl_item; ++# define GNULIB_defined_nl_item 1 ++# endif + + /* nl_langinfo items of the LC_CTYPE category */ + # define CODESET 10000 +@@ -169,5 +172,5 @@ _GL_WARN_ON_USE (nl_langinfo, "nl_langinfo is not portable - " + #endif + + +-#endif /* _GL_LANGINFO_H */ +-#endif /* _GL_LANGINFO_H */ ++#endif /* _@GUARD_PREFIX@_LANGINFO_H */ ++#endif /* _@GUARD_PREFIX@_LANGINFO_H */ +diff --git a/grub-core/gnulib/localcharset.c b/grub-core/gnulib/localcharset.c +index fa2207f..953cc1e 100644 +--- a/grub-core/gnulib/localcharset.c ++++ b/grub-core/gnulib/localcharset.c +@@ -1,6 +1,6 @@ + /* Determine a canonical name for the current locale's character encoding. + +- Copyright (C) 2000-2006, 2008-2010 Free Software Foundation, Inc. ++ Copyright (C) 2000-2006, 2008-2013 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 +@@ -13,8 +13,7 @@ + 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. */ ++ with this program; if not, see . */ + + /* Written by Bruno Haible . */ + +@@ -30,11 +29,11 @@ + #include + + #if defined __APPLE__ && defined __MACH__ && HAVE_LANGINFO_CODESET +-# define DARWIN7 /* Darwin 7 or newer, i.e. MacOS X 10.3 or newer */ ++# define DARWIN7 /* Darwin 7 or newer, i.e. Mac OS X 10.3 or newer */ + #endif + + #if defined _WIN32 || defined __WIN32__ +-# define WIN32_NATIVE ++# define WINDOWS_NATIVE + #endif + + #if defined __EMX__ +@@ -44,7 +43,7 @@ + # endif + #endif + +-#if !defined WIN32_NATIVE ++#if !defined WINDOWS_NATIVE + # include + # if HAVE_LANGINFO_CODESET + # include +@@ -57,7 +56,7 @@ + # define WIN32_LEAN_AND_MEAN + # include + # endif +-#elif defined WIN32_NATIVE ++#elif defined WINDOWS_NATIVE + # define WIN32_LEAN_AND_MEAN + # include + #endif +@@ -83,7 +82,7 @@ + #endif + + #if defined _WIN32 || defined __WIN32__ || defined __CYGWIN__ || defined __EMX__ || defined __DJGPP__ +- /* Win32, Cygwin, OS/2, DOS */ ++ /* Native Windows, Cygwin, OS/2, DOS */ + # define ISSLASH(C) ((C) == '/' || (C) == '\\') + #endif + +@@ -123,7 +122,7 @@ get_charset_aliases (void) + cp = charset_aliases; + if (cp == NULL) + { +-#if !(defined DARWIN7 || defined VMS || defined WIN32_NATIVE || defined __CYGWIN__) ++#if !(defined DARWIN7 || defined VMS || defined WINDOWS_NATIVE || defined __CYGWIN__) + const char *dir; + const char *base = "charset.alias"; + char *file_name; +@@ -228,8 +227,7 @@ get_charset_aliases (void) + { + /* Out of memory. */ + res_size = 0; +- if (old_res_ptr != NULL) +- free (old_res_ptr); ++ free (old_res_ptr); + break; + } + strcpy (res_ptr + res_size - (l2 + 1) - (l1 + 1), buf1); +@@ -309,7 +307,7 @@ get_charset_aliases (void) + "DECKOREAN" "\0" "EUC-KR" "\0"; + # endif + +-# if defined WIN32_NATIVE || defined __CYGWIN__ ++# if defined WINDOWS_NATIVE || defined __CYGWIN__ + /* To avoid the troubles of installing a separate file in the same + directory as the DLL and of retrieving the DLL's directory at + runtime, simply inline the aliases here. */ +@@ -361,7 +359,7 @@ locale_charset (void) + const char *codeset; + const char *aliases; + +-#if !(defined WIN32_NATIVE || defined OS2) ++#if !(defined WINDOWS_NATIVE || defined OS2) + + # if HAVE_LANGINFO_CODESET + +@@ -408,10 +406,10 @@ locale_charset (void) + } + } + +- /* Woe32 has a function returning the locale's codepage as a number: +- GetACP(). This encoding is used by Cygwin, unless the user has set +- the environment variable CYGWIN=codepage:oem (which very few people +- do). ++ /* The Windows API has a function returning the locale's codepage as a ++ number: GetACP(). This encoding is used by Cygwin, unless the user ++ has set the environment variable CYGWIN=codepage:oem (which very few ++ people do). + Output directed to console windows needs to be converted (to + GetOEMCP() if the console is using a raster font, or to + GetConsoleOutputCP() if it is using a TrueType font). Cygwin does +@@ -454,12 +452,12 @@ locale_charset (void) + + # endif + +-#elif defined WIN32_NATIVE ++#elif defined WINDOWS_NATIVE + + static char buf[2 + 10 + 1]; + +- /* Woe32 has a function returning the locale's codepage as a number: +- GetACP(). ++ /* The Windows API has a function returning the locale's codepage as a ++ number: GetACP(). + When the output goes to a console window, it needs to be provided in + GetOEMCP() encoding if the console is using a raster font, or in + GetConsoleOutputCP() encoding if it is using a TrueType font. +@@ -544,5 +542,12 @@ locale_charset (void) + if (codeset[0] == '\0') + codeset = "ASCII"; + ++#ifdef DARWIN7 ++ /* Mac OS X sets MB_CUR_MAX to 1 when LC_ALL=C, and "UTF-8" ++ (the default codeset) does not work when MB_CUR_MAX is 1. */ ++ if (strcmp (codeset, "UTF-8") == 0 && MB_CUR_MAX <= 1) ++ codeset = "ASCII"; ++#endif ++ + return codeset; + } +diff --git a/grub-core/gnulib/localcharset.h b/grub-core/gnulib/localcharset.h +index 899b3ba..c209829 100644 +--- a/grub-core/gnulib/localcharset.h ++++ b/grub-core/gnulib/localcharset.h +@@ -1,5 +1,5 @@ + /* Determine a canonical name for the current locale's character encoding. +- Copyright (C) 2000-2003, 2009-2010 Free Software Foundation, Inc. ++ Copyright (C) 2000-2003, 2009-2013 Free Software Foundation, Inc. + This file is part of the GNU CHARSET Library. + + This program is free software; you can redistribute it and/or modify +@@ -13,8 +13,7 @@ + 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. */ ++ with this program; if not, see . */ + + #ifndef _LOCALCHARSET_H + #define _LOCALCHARSET_H +diff --git a/grub-core/gnulib/locale.in.h b/grub-core/gnulib/locale.in.h +new file mode 100644 +index 0000000..264161a +--- /dev/null ++++ b/grub-core/gnulib/locale.in.h +@@ -0,0 +1,216 @@ ++/* A POSIX . ++ Copyright (C) 2007-2013 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 . */ ++ ++#if __GNUC__ >= 3 ++@PRAGMA_SYSTEM_HEADER@ ++#endif ++@PRAGMA_COLUMNS@ ++ ++#ifdef _GL_ALREADY_INCLUDING_LOCALE_H ++ ++/* Special invocation conventions to handle Solaris header files ++ (through Solaris 10) when combined with gettext's libintl.h. */ ++ ++#@INCLUDE_NEXT@ @NEXT_LOCALE_H@ ++ ++#else ++/* Normal invocation convention. */ ++ ++#ifndef _@GUARD_PREFIX@_LOCALE_H ++ ++#define _GL_ALREADY_INCLUDING_LOCALE_H ++ ++/* The include_next requires a split double-inclusion guard. */ ++#@INCLUDE_NEXT@ @NEXT_LOCALE_H@ ++ ++#undef _GL_ALREADY_INCLUDING_LOCALE_H ++ ++#ifndef _@GUARD_PREFIX@_LOCALE_H ++#define _@GUARD_PREFIX@_LOCALE_H ++ ++/* NetBSD 5.0 mis-defines NULL. */ ++#include ++ ++/* Mac OS X 10.5 defines the locale_t type in . */ ++#if @HAVE_XLOCALE_H@ ++# include ++#endif ++ ++/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ ++ ++/* The definition of _GL_ARG_NONNULL is copied here. */ ++ ++/* The definition of _GL_WARN_ON_USE is copied here. */ ++ ++/* The LC_MESSAGES locale category is specified in POSIX, but not in ISO C. ++ On systems that don't define it, use the same value as GNU libintl. */ ++#if !defined LC_MESSAGES ++# define LC_MESSAGES 1729 ++#endif ++ ++/* Bionic libc's 'struct lconv' is just a dummy. */ ++#if @REPLACE_STRUCT_LCONV@ ++# define lconv rpl_lconv ++struct lconv ++{ ++ /* All 'char *' are actually 'const char *'. */ ++ ++ /* Members that depend on the LC_NUMERIC category of the locale. See ++ */ ++ ++ /* Symbol used as decimal point. */ ++ char *decimal_point; ++ /* Symbol used to separate groups of digits to the left of the decimal ++ point. */ ++ char *thousands_sep; ++ /* Definition of the size of groups of digits to the left of the decimal ++ point. */ ++ char *grouping; ++ ++ /* Members that depend on the LC_MONETARY category of the locale. See ++ */ ++ ++ /* Symbol used as decimal point. */ ++ char *mon_decimal_point; ++ /* Symbol used to separate groups of digits to the left of the decimal ++ point. */ ++ char *mon_thousands_sep; ++ /* Definition of the size of groups of digits to the left of the decimal ++ point. */ ++ char *mon_grouping; ++ /* Sign used to indicate a value >= 0. */ ++ char *positive_sign; ++ /* Sign used to indicate a value < 0. */ ++ char *negative_sign; ++ ++ /* For formatting local currency. */ ++ /* Currency symbol (3 characters) followed by separator (1 character). */ ++ char *currency_symbol; ++ /* Number of digits after the decimal point. */ ++ char frac_digits; ++ /* For values >= 0: 1 if the currency symbol precedes the number, 0 if it ++ comes after the number. */ ++ char p_cs_precedes; ++ /* For values >= 0: Position of the sign. */ ++ char p_sign_posn; ++ /* For values >= 0: Placement of spaces between currency symbol, sign, and ++ number. */ ++ char p_sep_by_space; ++ /* For values < 0: 1 if the currency symbol precedes the number, 0 if it ++ comes after the number. */ ++ char n_cs_precedes; ++ /* For values < 0: Position of the sign. */ ++ char n_sign_posn; ++ /* For values < 0: Placement of spaces between currency symbol, sign, and ++ number. */ ++ char n_sep_by_space; ++ ++ /* For formatting international currency. */ ++ /* Currency symbol (3 characters) followed by separator (1 character). */ ++ char *int_curr_symbol; ++ /* Number of digits after the decimal point. */ ++ char int_frac_digits; ++ /* For values >= 0: 1 if the currency symbol precedes the number, 0 if it ++ comes after the number. */ ++ char int_p_cs_precedes; ++ /* For values >= 0: Position of the sign. */ ++ char int_p_sign_posn; ++ /* For values >= 0: Placement of spaces between currency symbol, sign, and ++ number. */ ++ char int_p_sep_by_space; ++ /* For values < 0: 1 if the currency symbol precedes the number, 0 if it ++ comes after the number. */ ++ char int_n_cs_precedes; ++ /* For values < 0: Position of the sign. */ ++ char int_n_sign_posn; ++ /* For values < 0: Placement of spaces between currency symbol, sign, and ++ number. */ ++ char int_n_sep_by_space; ++}; ++#endif ++ ++#if @GNULIB_LOCALECONV@ ++# if @REPLACE_LOCALECONV@ ++# if !(defined __cplusplus && defined GNULIB_NAMESPACE) ++# undef localeconv ++# define localeconv rpl_localeconv ++# endif ++_GL_FUNCDECL_RPL (localeconv, struct lconv *, (void)); ++_GL_CXXALIAS_RPL (localeconv, struct lconv *, (void)); ++# else ++_GL_CXXALIAS_SYS (localeconv, struct lconv *, (void)); ++# endif ++_GL_CXXALIASWARN (localeconv); ++#elif @REPLACE_STRUCT_LCONV@ ++# undef localeconv ++# define localeconv localeconv_used_without_requesting_gnulib_module_localeconv ++#elif defined GNULIB_POSIXCHECK ++# undef localeconv ++# if HAVE_RAW_DECL_LOCALECONV ++_GL_WARN_ON_USE (localeconv, ++ "localeconv returns too few information on some platforms - " ++ "use gnulib module localeconv for portability"); ++# endif ++#endif ++ ++#if @GNULIB_SETLOCALE@ ++# if @REPLACE_SETLOCALE@ ++# if !(defined __cplusplus && defined GNULIB_NAMESPACE) ++# undef setlocale ++# define setlocale rpl_setlocale ++# define GNULIB_defined_setlocale 1 ++# endif ++_GL_FUNCDECL_RPL (setlocale, char *, (int category, const char *locale)); ++_GL_CXXALIAS_RPL (setlocale, char *, (int category, const char *locale)); ++# else ++_GL_CXXALIAS_SYS (setlocale, char *, (int category, const char *locale)); ++# endif ++_GL_CXXALIASWARN (setlocale); ++#elif defined GNULIB_POSIXCHECK ++# undef setlocale ++# if HAVE_RAW_DECL_SETLOCALE ++_GL_WARN_ON_USE (setlocale, "setlocale works differently on native Windows - " ++ "use gnulib module setlocale for portability"); ++# endif ++#endif ++ ++#if @GNULIB_DUPLOCALE@ ++# if @REPLACE_DUPLOCALE@ ++# if !(defined __cplusplus && defined GNULIB_NAMESPACE) ++# undef duplocale ++# define duplocale rpl_duplocale ++# endif ++_GL_FUNCDECL_RPL (duplocale, locale_t, (locale_t locale) _GL_ARG_NONNULL ((1))); ++_GL_CXXALIAS_RPL (duplocale, locale_t, (locale_t locale)); ++# else ++# if @HAVE_DUPLOCALE@ ++_GL_CXXALIAS_SYS (duplocale, locale_t, (locale_t locale)); ++# endif ++# endif ++# if @HAVE_DUPLOCALE@ ++_GL_CXXALIASWARN (duplocale); ++# endif ++#elif defined GNULIB_POSIXCHECK ++# undef duplocale ++# if HAVE_RAW_DECL_DUPLOCALE ++_GL_WARN_ON_USE (duplocale, "duplocale is buggy on some glibc systems - " ++ "use gnulib module duplocale for portability"); ++# endif ++#endif ++ ++#endif /* _@GUARD_PREFIX@_LOCALE_H */ ++#endif /* ! _GL_ALREADY_INCLUDING_LOCALE_H */ ++#endif /* _@GUARD_PREFIX@_LOCALE_H */ +diff --git a/grub-core/gnulib/localeconv.c b/grub-core/gnulib/localeconv.c +new file mode 100644 +index 0000000..7c7c77c +--- /dev/null ++++ b/grub-core/gnulib/localeconv.c +@@ -0,0 +1,103 @@ ++/* Query locale dependent information for formatting numbers. ++ Copyright (C) 2012-2013 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 ++ ++/* Specification. */ ++#include ++ ++#if HAVE_STRUCT_LCONV_DECIMAL_POINT ++ ++/* Override for platforms where 'struct lconv' lacks the int_p_*, int_n_* ++ members. */ ++ ++struct lconv * ++localeconv (void) ++{ ++ static struct lconv result; ++# undef lconv ++# undef localeconv ++ struct lconv *sys_result = localeconv (); ++ ++ result.decimal_point = sys_result->decimal_point; ++ result.thousands_sep = sys_result->thousands_sep; ++ result.grouping = sys_result->grouping; ++ result.mon_decimal_point = sys_result->mon_decimal_point; ++ result.mon_thousands_sep = sys_result->mon_thousands_sep; ++ result.mon_grouping = sys_result->mon_grouping; ++ result.positive_sign = sys_result->positive_sign; ++ result.negative_sign = sys_result->negative_sign; ++ result.currency_symbol = sys_result->currency_symbol; ++ result.frac_digits = sys_result->frac_digits; ++ result.p_cs_precedes = sys_result->p_cs_precedes; ++ result.p_sign_posn = sys_result->p_sign_posn; ++ result.p_sep_by_space = sys_result->p_sep_by_space; ++ result.n_cs_precedes = sys_result->n_cs_precedes; ++ result.n_sign_posn = sys_result->n_sign_posn; ++ result.n_sep_by_space = sys_result->n_sep_by_space; ++ result.int_curr_symbol = sys_result->int_curr_symbol; ++ result.int_frac_digits = sys_result->int_frac_digits; ++ result.int_p_cs_precedes = sys_result->p_cs_precedes; ++ result.int_p_sign_posn = sys_result->p_sign_posn; ++ result.int_p_sep_by_space = sys_result->p_sep_by_space; ++ result.int_n_cs_precedes = sys_result->n_cs_precedes; ++ result.int_n_sign_posn = sys_result->n_sign_posn; ++ result.int_n_sep_by_space = sys_result->n_sep_by_space; ++ ++ return &result; ++} ++ ++#else ++ ++/* Override for platforms where 'struct lconv' is a dummy. */ ++ ++# include ++ ++struct lconv * ++localeconv (void) ++{ ++ static /*const*/ struct lconv result = ++ { ++ /* decimal_point */ ".", ++ /* thousands_sep */ "", ++ /* grouping */ "", ++ /* mon_decimal_point */ "", ++ /* mon_thousands_sep */ "", ++ /* mon_grouping */ "", ++ /* positive_sign */ "", ++ /* negative_sign */ "", ++ /* currency_symbol */ "", ++ /* frac_digits */ CHAR_MAX, ++ /* p_cs_precedes */ CHAR_MAX, ++ /* p_sign_posn */ CHAR_MAX, ++ /* p_sep_by_space */ CHAR_MAX, ++ /* n_cs_precedes */ CHAR_MAX, ++ /* n_sign_posn */ CHAR_MAX, ++ /* n_sep_by_space */ CHAR_MAX, ++ /* int_curr_symbol */ "", ++ /* int_frac_digits */ CHAR_MAX, ++ /* int_p_cs_precedes */ CHAR_MAX, ++ /* int_p_sign_posn */ CHAR_MAX, ++ /* int_p_sep_by_space */ CHAR_MAX, ++ /* int_n_cs_precedes */ CHAR_MAX, ++ /* int_n_sign_posn */ CHAR_MAX, ++ /* int_n_sep_by_space */ CHAR_MAX ++ }; ++ ++ return &result; ++} ++ ++#endif +diff --git a/grub-core/gnulib/malloc.c b/grub-core/gnulib/malloc.c +index 4fa38ee..908735d 100644 +--- a/grub-core/gnulib/malloc.c ++++ b/grub-core/gnulib/malloc.c +@@ -1,6 +1,6 @@ + /* malloc() function that is glibc compatible. + +- Copyright (C) 1997-1998, 2006-2007, 2009-2010 Free Software Foundation, Inc. ++ Copyright (C) 1997-1998, 2006-2007, 2009-2013 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 +@@ -13,11 +13,11 @@ + 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. */ ++ along with this program; if not, see . */ + + /* written by Jim Meyering and Bruno Haible */ + ++#define _GL_USE_STDLIB_ALLOC 1 + #include + /* Only the AC_FUNC_MALLOC macro defines 'malloc' already in config.h. */ + #ifdef malloc +@@ -28,14 +28,10 @@ + # define NEED_MALLOC_GNU 1 + #endif + +-/* Specification. */ + #include + + #include + +-/* Call the system's malloc below. */ +-#undef malloc +- + /* Allocate an N-byte block of memory from the heap. + If N is zero, allocate a 1-byte block. */ + +diff --git a/grub-core/gnulib/mbrtowc.c b/grub-core/gnulib/mbrtowc.c +index 5c2650e..5ee44ae 100644 +--- a/grub-core/gnulib/mbrtowc.c ++++ b/grub-core/gnulib/mbrtowc.c +@@ -1,5 +1,5 @@ + /* Convert multibyte character to wide character. +- Copyright (C) 1999-2002, 2005-2010 Free Software Foundation, Inc. ++ Copyright (C) 1999-2002, 2005-2013 Free Software Foundation, Inc. + Written by Bruno Haible , 2008. + + This program is free software: you can redistribute it and/or modify +@@ -40,9 +40,6 @@ mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps) + { + char *pstate = (char *)ps; + +- if (pstate == NULL) +- pstate = internal_state; +- + if (s == NULL) + { + pwc = NULL; +@@ -54,6 +51,10 @@ mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps) + return (size_t)(-2); + + /* Here n > 0. */ ++ ++ if (pstate == NULL) ++ pstate = internal_state; ++ + { + size_t nstate = pstate[0]; + char buf[4]; +@@ -91,7 +92,7 @@ mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps) + + /* Here m > 0. */ + +-# if __GLIBC__ ++# if __GLIBC__ || defined __UCLIBC__ + /* Work around bug */ + mbtowc (NULL, NULL, 0); + # endif +@@ -127,7 +128,7 @@ mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps) + { + const char *encoding = locale_charset (); + +- if (STREQ (encoding, "UTF-8", 'U', 'T', 'F', '-', '8', 0, 0, 0, 0)) ++ if (STREQ_OPT (encoding, "UTF-8", 'U', 'T', 'F', '-', '8', 0, 0, 0, 0)) + { + /* Cf. unistr/u8-mblen.c. */ + unsigned char c = (unsigned char) p[0]; +@@ -184,7 +185,8 @@ mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps) + /* As a reference for this code, you can use the GNU libiconv + implementation. Look for uses of the RET_TOOFEW macro. */ + +- if (STREQ (encoding, "EUC-JP", 'E', 'U', 'C', '-', 'J', 'P', 0, 0, 0)) ++ if (STREQ_OPT (encoding, ++ "EUC-JP", 'E', 'U', 'C', '-', 'J', 'P', 0, 0, 0)) + { + if (m == 1) + { +@@ -207,9 +209,12 @@ mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps) + } + goto invalid; + } +- if (STREQ (encoding, "EUC-KR", 'E', 'U', 'C', '-', 'K', 'R', 0, 0, 0) +- || STREQ (encoding, "GB2312", 'G', 'B', '2', '3', '1', '2', 0, 0, 0) +- || STREQ (encoding, "BIG5", 'B', 'I', 'G', '5', 0, 0, 0, 0, 0)) ++ if (STREQ_OPT (encoding, ++ "EUC-KR", 'E', 'U', 'C', '-', 'K', 'R', 0, 0, 0) ++ || STREQ_OPT (encoding, ++ "GB2312", 'G', 'B', '2', '3', '1', '2', 0, 0, 0) ++ || STREQ_OPT (encoding, ++ "BIG5", 'B', 'I', 'G', '5', 0, 0, 0, 0, 0)) + { + if (m == 1) + { +@@ -220,7 +225,8 @@ mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps) + } + goto invalid; + } +- if (STREQ (encoding, "EUC-TW", 'E', 'U', 'C', '-', 'T', 'W', 0, 0, 0)) ++ if (STREQ_OPT (encoding, ++ "EUC-TW", 'E', 'U', 'C', '-', 'T', 'W', 0, 0, 0)) + { + if (m == 1) + { +@@ -238,7 +244,8 @@ mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps) + } + goto invalid; + } +- if (STREQ (encoding, "GB18030", 'G', 'B', '1', '8', '0', '3', '0', 0, 0)) ++ if (STREQ_OPT (encoding, ++ "GB18030", 'G', 'B', '1', '8', '0', '3', '0', 0, 0)) + { + if (m == 1) + { +@@ -271,7 +278,7 @@ mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps) + } + goto invalid; + } +- if (STREQ (encoding, "SJIS", 'S', 'J', 'I', 'S', 0, 0, 0, 0, 0)) ++ if (STREQ_OPT (encoding, "SJIS", 'S', 'J', 'I', 'S', 0, 0, 0, 0, 0)) + { + if (m == 1) + { +@@ -321,7 +328,7 @@ mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps) + size_t + rpl_mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps) + { +-# if MBRTOWC_NULL_ARG_BUG || MBRTOWC_RETVAL_BUG ++# if MBRTOWC_NULL_ARG2_BUG || MBRTOWC_RETVAL_BUG + if (s == NULL) + { + pwc = NULL; +@@ -334,7 +341,7 @@ rpl_mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps) + { + static mbstate_t internal_state; + +- /* Override mbrtowc's internal state. We can not call mbsinit() on the ++ /* Override mbrtowc's internal state. We cannot call mbsinit() on the + hidden internal state, but we can call it on our variable. */ + if (ps == NULL) + ps = &internal_state; +@@ -379,7 +386,16 @@ rpl_mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps) + return ret; + } + # else +- return mbrtowc (pwc, s, n, ps); ++ { ++# if MBRTOWC_NULL_ARG1_BUG ++ wchar_t dummy; ++ ++ if (pwc == NULL) ++ pwc = &dummy; ++# endif ++ ++ return mbrtowc (pwc, s, n, ps); ++ } + # endif + } + +diff --git a/grub-core/gnulib/mbsinit.c b/grub-core/gnulib/mbsinit.c +index 066ddfe..26fbb7f 100644 +--- a/grub-core/gnulib/mbsinit.c ++++ b/grub-core/gnulib/mbsinit.c +@@ -1,5 +1,5 @@ + /* Test for initial conversion state. +- Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc. ++ Copyright (C) 2008-2013 Free Software Foundation, Inc. + Written by Bruno Haible , 2008. + + This program is free software: you can redistribute it and/or modify +@@ -22,6 +22,18 @@ + + #include "verify.h" + ++#if (defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__ ++ ++/* On native Windows, 'mbstate_t' is defined as 'int'. */ ++ ++int ++mbsinit (const mbstate_t *ps) ++{ ++ return ps == NULL || *ps == 0; ++} ++ ++#else ++ + /* Platforms that lack mbsinit() also lack mbrlen(), mbrtowc(), mbsrtowcs() + and wcrtomb(), wcsrtombs(). + We assume that +@@ -43,5 +55,7 @@ mbsinit (const mbstate_t *ps) + { + const char *pstate = (const char *)ps; + +- return pstate[0] == 0; ++ return pstate == NULL || pstate[0] == 0; + } ++ ++#endif +diff --git a/grub-core/gnulib/mbsrtowcs-impl.h b/grub-core/gnulib/mbsrtowcs-impl.h +new file mode 100644 +index 0000000..b50e973 +--- /dev/null ++++ b/grub-core/gnulib/mbsrtowcs-impl.h +@@ -0,0 +1,122 @@ ++/* Convert string to wide string. ++ Copyright (C) 2008-2013 Free Software Foundation, Inc. ++ Written by Bruno Haible , 2008. ++ ++ 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 . */ ++ ++size_t ++mbsrtowcs (wchar_t *dest, const char **srcp, size_t len, mbstate_t *ps) ++{ ++ if (ps == NULL) ++ ps = &_gl_mbsrtowcs_state; ++ { ++ const char *src = *srcp; ++ ++ if (dest != NULL) ++ { ++ wchar_t *destptr = dest; ++ ++ for (; len > 0; destptr++, len--) ++ { ++ size_t src_avail; ++ size_t ret; ++ ++ /* An optimized variant of ++ src_avail = strnlen1 (src, MB_LEN_MAX); */ ++ if (src[0] == '\0') ++ src_avail = 1; ++ else if (src[1] == '\0') ++ src_avail = 2; ++ else if (src[2] == '\0') ++ src_avail = 3; ++ else if (MB_LEN_MAX <= 4 || src[3] == '\0') ++ src_avail = 4; ++ else ++ src_avail = 4 + strnlen1 (src + 4, MB_LEN_MAX - 4); ++ ++ /* Parse the next multibyte character. */ ++ ret = mbrtowc (destptr, src, src_avail, ps); ++ ++ if (ret == (size_t)(-2)) ++ /* Encountered a multibyte character that extends past a '\0' byte ++ or that is longer than MB_LEN_MAX bytes. Cannot happen. */ ++ abort (); ++ ++ if (ret == (size_t)(-1)) ++ goto bad_input; ++ if (ret == 0) ++ { ++ src = NULL; ++ /* Here mbsinit (ps). */ ++ break; ++ } ++ src += ret; ++ } ++ ++ *srcp = src; ++ return destptr - dest; ++ } ++ else ++ { ++ /* Ignore dest and len, don't store *srcp at the end, and ++ don't clobber *ps. */ ++ mbstate_t state = *ps; ++ size_t totalcount = 0; ++ ++ for (;; totalcount++) ++ { ++ size_t src_avail; ++ size_t ret; ++ ++ /* An optimized variant of ++ src_avail = strnlen1 (src, MB_LEN_MAX); */ ++ if (src[0] == '\0') ++ src_avail = 1; ++ else if (src[1] == '\0') ++ src_avail = 2; ++ else if (src[2] == '\0') ++ src_avail = 3; ++ else if (MB_LEN_MAX <= 4 || src[3] == '\0') ++ src_avail = 4; ++ else ++ src_avail = 4 + strnlen1 (src + 4, MB_LEN_MAX - 4); ++ ++ /* Parse the next multibyte character. */ ++ ret = mbrtowc (NULL, src, src_avail, &state); ++ ++ if (ret == (size_t)(-2)) ++ /* Encountered a multibyte character that extends past a '\0' byte ++ or that is longer than MB_LEN_MAX bytes. Cannot happen. */ ++ abort (); ++ ++ if (ret == (size_t)(-1)) ++ goto bad_input2; ++ if (ret == 0) ++ { ++ /* Here mbsinit (&state). */ ++ break; ++ } ++ src += ret; ++ } ++ ++ return totalcount; ++ } ++ ++ bad_input: ++ *srcp = src; ++ bad_input2: ++ errno = EILSEQ; ++ return (size_t)(-1); ++ } ++} +diff --git a/grub-core/gnulib/mbsrtowcs-state.c b/grub-core/gnulib/mbsrtowcs-state.c +index 35045f6..5a0b888 100644 +--- a/grub-core/gnulib/mbsrtowcs-state.c ++++ b/grub-core/gnulib/mbsrtowcs-state.c +@@ -1,5 +1,5 @@ + /* Convert string to wide string. +- Copyright (C) 2008-2010 Free Software Foundation, Inc. ++ Copyright (C) 2008-2013 Free Software Foundation, Inc. + Written by Bruno Haible , 2008. + + This program is free software: you can redistribute it and/or modify +@@ -22,7 +22,7 @@ + /* Internal state used by the functions mbsrtowcs() and mbsnrtowcs(). */ + mbstate_t _gl_mbsrtowcs_state + /* The state must initially be in the "initial state"; so, zero-initialize it. +- On most systems, putting it into BSS is sufficient. Not so on MacOS X 10.3, ++ On most systems, putting it into BSS is sufficient. Not so on Mac OS X 10.3, + see . + When it needs an initializer, use 0 or {0} as initializer? 0 only works + when mbstate_t is a scalar type (such as when gnulib defines it, or on +diff --git a/grub-core/gnulib/mbsrtowcs.c b/grub-core/gnulib/mbsrtowcs.c +index c577f36..116ff49 100644 +--- a/grub-core/gnulib/mbsrtowcs.c ++++ b/grub-core/gnulib/mbsrtowcs.c +@@ -1,5 +1,5 @@ + /* Convert string to wide string. +- Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc. ++ Copyright (C) 2008-2013 Free Software Foundation, Inc. + Written by Bruno Haible , 2008. + + This program is free software: you can redistribute it and/or modify +@@ -29,108 +29,4 @@ + + extern mbstate_t _gl_mbsrtowcs_state; + +-size_t +-mbsrtowcs (wchar_t *dest, const char **srcp, size_t len, mbstate_t *ps) +-{ +- if (ps == NULL) +- ps = &_gl_mbsrtowcs_state; +- { +- const char *src = *srcp; +- +- if (dest != NULL) +- { +- wchar_t *destptr = dest; +- +- for (; len > 0; destptr++, len--) +- { +- size_t src_avail; +- size_t ret; +- +- /* An optimized variant of +- src_avail = strnlen1 (src, MB_LEN_MAX); */ +- if (src[0] == '\0') +- src_avail = 1; +- else if (src[1] == '\0') +- src_avail = 2; +- else if (src[2] == '\0') +- src_avail = 3; +- else if (MB_LEN_MAX <= 4 || src[3] == '\0') +- src_avail = 4; +- else +- src_avail = 4 + strnlen1 (src + 4, MB_LEN_MAX - 4); +- +- /* Parse the next multibyte character. */ +- ret = mbrtowc (destptr, src, src_avail, ps); +- +- if (ret == (size_t)(-2)) +- /* Encountered a multibyte character that extends past a '\0' byte +- or that is longer than MB_LEN_MAX bytes. Cannot happen. */ +- abort (); +- +- if (ret == (size_t)(-1)) +- goto bad_input; +- if (ret == 0) +- { +- src = NULL; +- /* Here mbsinit (ps). */ +- break; +- } +- src += ret; +- } +- +- *srcp = src; +- return destptr - dest; +- } +- else +- { +- /* Ignore dest and len, don't store *srcp at the end, and +- don't clobber *ps. */ +- mbstate_t state = *ps; +- size_t totalcount = 0; +- +- for (;; totalcount++) +- { +- size_t src_avail; +- size_t ret; +- +- /* An optimized variant of +- src_avail = strnlen1 (src, MB_LEN_MAX); */ +- if (src[0] == '\0') +- src_avail = 1; +- else if (src[1] == '\0') +- src_avail = 2; +- else if (src[2] == '\0') +- src_avail = 3; +- else if (MB_LEN_MAX <= 4 || src[3] == '\0') +- src_avail = 4; +- else +- src_avail = 4 + strnlen1 (src + 4, MB_LEN_MAX - 4); +- +- /* Parse the next multibyte character. */ +- ret = mbrtowc (NULL, src, src_avail, &state); +- +- if (ret == (size_t)(-2)) +- /* Encountered a multibyte character that extends past a '\0' byte +- or that is longer than MB_LEN_MAX bytes. Cannot happen. */ +- abort (); +- +- if (ret == (size_t)(-1)) +- goto bad_input2; +- if (ret == 0) +- { +- /* Here mbsinit (&state). */ +- break; +- } +- src += ret; +- } +- +- return totalcount; +- } +- +- bad_input: +- *srcp = src; +- bad_input2: +- errno = EILSEQ; +- return (size_t)(-1); +- } +-} ++#include "mbsrtowcs-impl.h" +diff --git a/grub-core/gnulib/mbswidth.c b/grub-core/gnulib/mbswidth.c +new file mode 100644 +index 0000000..baa4f27 +--- /dev/null ++++ b/grub-core/gnulib/mbswidth.c +@@ -0,0 +1,199 @@ ++/* Determine the number of screen columns needed for a string. ++ Copyright (C) 2000-2013 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 . */ ++ ++/* Written by Bruno Haible . */ ++ ++#include ++ ++/* Specification. */ ++#include "mbswidth.h" ++ ++/* Get MB_CUR_MAX. */ ++#include ++ ++#include ++ ++/* Get isprint(). */ ++#include ++ ++/* Get mbstate_t, mbrtowc(), mbsinit(), wcwidth(). */ ++#include ++ ++/* Get iswcntrl(). */ ++#include ++ ++/* Get INT_MAX. */ ++#include ++ ++/* Returns the number of columns needed to represent the multibyte ++ character string pointed to by STRING. If a non-printable character ++ occurs, and MBSW_REJECT_UNPRINTABLE is specified, -1 is returned. ++ With flags = MBSW_REJECT_INVALID | MBSW_REJECT_UNPRINTABLE, this is ++ the multibyte analogue of the wcswidth function. */ ++int ++mbswidth (const char *string, int flags) ++{ ++ return mbsnwidth (string, strlen (string), flags); ++} ++ ++/* Returns the number of columns needed to represent the multibyte ++ character string pointed to by STRING of length NBYTES. If a ++ non-printable character occurs, and MBSW_REJECT_UNPRINTABLE is ++ specified, -1 is returned. */ ++int ++mbsnwidth (const char *string, size_t nbytes, int flags) ++{ ++ const char *p = string; ++ const char *plimit = p + nbytes; ++ int width; ++ ++ width = 0; ++ if (MB_CUR_MAX > 1) ++ { ++ while (p < plimit) ++ switch (*p) ++ { ++ case ' ': case '!': case '"': case '#': case '%': ++ case '&': case '\'': case '(': case ')': case '*': ++ case '+': case ',': case '-': case '.': case '/': ++ case '0': case '1': case '2': case '3': case '4': ++ case '5': case '6': case '7': case '8': case '9': ++ case ':': case ';': case '<': case '=': case '>': ++ case '?': ++ case 'A': case 'B': case 'C': case 'D': case 'E': ++ case 'F': case 'G': case 'H': case 'I': case 'J': ++ case 'K': case 'L': case 'M': case 'N': case 'O': ++ case 'P': case 'Q': case 'R': case 'S': case 'T': ++ case 'U': case 'V': case 'W': case 'X': case 'Y': ++ case 'Z': ++ case '[': case '\\': case ']': case '^': case '_': ++ case 'a': case 'b': case 'c': case 'd': case 'e': ++ case 'f': case 'g': case 'h': case 'i': case 'j': ++ case 'k': case 'l': case 'm': case 'n': case 'o': ++ case 'p': case 'q': case 'r': case 's': case 't': ++ case 'u': case 'v': case 'w': case 'x': case 'y': ++ case 'z': case '{': case '|': case '}': case '~': ++ /* These characters are printable ASCII characters. */ ++ p++; ++ width++; ++ break; ++ case '\0': ++ if (flags & MBSW_STOP_AT_NUL) ++ return width; ++ default: ++ /* If we have a multibyte sequence, scan it up to its end. */ ++ { ++ mbstate_t mbstate; ++ memset (&mbstate, 0, sizeof mbstate); ++ do ++ { ++ wchar_t wc; ++ size_t bytes; ++ int w; ++ ++ bytes = mbrtowc (&wc, p, plimit - p, &mbstate); ++ ++ if (bytes == (size_t) -1) ++ /* An invalid multibyte sequence was encountered. */ ++ { ++ if (!(flags & MBSW_REJECT_INVALID)) ++ { ++ p++; ++ width++; ++ break; ++ } ++ else ++ return -1; ++ } ++ ++ if (bytes == (size_t) -2) ++ /* An incomplete multibyte character at the end. */ ++ { ++ if (!(flags & MBSW_REJECT_INVALID)) ++ { ++ p = plimit; ++ width++; ++ break; ++ } ++ else ++ return -1; ++ } ++ ++ if (bytes == 0) ++ /* A null wide character was encountered. */ ++ bytes = 1; ++ ++ w = wcwidth (wc); ++ if (w >= 0) ++ /* A printable multibyte character. */ ++ { ++ if (w > INT_MAX - width) ++ goto overflow; ++ width += w; ++ } ++ else ++ /* An unprintable multibyte character. */ ++ if (!(flags & MBSW_REJECT_UNPRINTABLE)) ++ { ++ if (!iswcntrl (wc)) ++ { ++ if (width == INT_MAX) ++ goto overflow; ++ width++; ++ } ++ } ++ else ++ return -1; ++ ++ p += bytes; ++ } ++ while (! mbsinit (&mbstate)); ++ } ++ break; ++ } ++ return width; ++ } ++ ++ while (p < plimit) ++ { ++ unsigned char c = (unsigned char) *p++; ++ ++ if (c == 0 && (flags & MBSW_STOP_AT_NUL)) ++ return width; ++ ++ if (isprint (c)) ++ { ++ if (width == INT_MAX) ++ goto overflow; ++ width++; ++ } ++ else if (!(flags & MBSW_REJECT_UNPRINTABLE)) ++ { ++ if (!iscntrl (c)) ++ { ++ if (width == INT_MAX) ++ goto overflow; ++ width++; ++ } ++ } ++ else ++ return -1; ++ } ++ return width; ++ ++ overflow: ++ return INT_MAX; ++} +diff --git a/grub-core/gnulib/mbswidth.h b/grub-core/gnulib/mbswidth.h +new file mode 100644 +index 0000000..d7207c5 +--- /dev/null ++++ b/grub-core/gnulib/mbswidth.h +@@ -0,0 +1,63 @@ ++/* Determine the number of screen columns needed for a string. ++ Copyright (C) 2000-2004, 2007, 2009-2013 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 ++ ++/* Avoid a clash of our mbswidth() with a function of the same name defined ++ in UnixWare 7.1.1 . We need this #include before the #define ++ below. ++ However, we don't want to #include on all platforms because ++ - Tru64 with Desktop Toolkit C has a bug: must be included before ++ . ++ - BSD/OS 4.1 has a bug: and must be included before ++ . */ ++#if HAVE_DECL_MBSWIDTH_IN_WCHAR_H ++# include ++#endif ++ ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++ ++/* Optional flags to influence mbswidth/mbsnwidth behavior. */ ++ ++/* If this bit is set, return -1 upon finding an invalid or incomplete ++ character. Otherwise, assume invalid characters have width 1. */ ++#define MBSW_REJECT_INVALID 1 ++ ++/* If this bit is set, return -1 upon finding a non-printable character. ++ Otherwise, assume unprintable characters have width 0 if they are ++ control characters and 1 otherwise. */ ++#define MBSW_REJECT_UNPRINTABLE 2 ++ ++/* If this bit is set \0 is treated as the end of string. ++ Otherwise it's treated as a normal one column width character. */ ++#define MBSW_STOP_AT_NUL 4 ++ ++/* Returns the number of screen columns needed for STRING. */ ++#define mbswidth gnu_mbswidth /* avoid clash with UnixWare 7.1.1 function */ ++extern int mbswidth (const char *string, int flags); ++ ++/* Returns the number of screen columns needed for the NBYTES bytes ++ starting at BUF. */ ++extern int mbsnwidth (const char *buf, size_t nbytes, int flags); ++ ++ ++#ifdef __cplusplus ++} ++#endif +diff --git a/grub-core/gnulib/mbtowc-impl.h b/grub-core/gnulib/mbtowc-impl.h +new file mode 100644 +index 0000000..767ab39 +--- /dev/null ++++ b/grub-core/gnulib/mbtowc-impl.h +@@ -0,0 +1,44 @@ ++/* Convert multibyte character to wide character. ++ Copyright (C) 2011-2013 Free Software Foundation, Inc. ++ Written by Bruno Haible , 2011. ++ ++ 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 . */ ++ ++/* We don't need a static internal state, because the encoding is not state ++ dependent, and when mbrtowc returns (size_t)(-2). we throw the result ++ away. */ ++ ++int ++mbtowc (wchar_t *pwc, const char *s, size_t n) ++{ ++ if (s == NULL) ++ return 0; ++ else ++ { ++ mbstate_t state; ++ wchar_t wc; ++ size_t result; ++ ++ memset (&state, 0, sizeof (mbstate_t)); ++ result = mbrtowc (&wc, s, n, &state); ++ if (result == (size_t)-1 || result == (size_t)-2) ++ { ++ errno = EILSEQ; ++ return -1; ++ } ++ if (pwc != NULL) ++ *pwc = wc; ++ return (wc == 0 ? 0 : result); ++ } ++} +diff --git a/grub-core/gnulib/mbtowc.c b/grub-core/gnulib/mbtowc.c +new file mode 100644 +index 0000000..632f2e1 +--- /dev/null ++++ b/grub-core/gnulib/mbtowc.c +@@ -0,0 +1,26 @@ ++/* Convert multibyte character to wide character. ++ Copyright (C) 2011-2013 Free Software Foundation, Inc. ++ Written by Bruno Haible , 2011. ++ ++ 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 ++#include ++ ++#include "mbtowc-impl.h" +diff --git a/grub-core/gnulib/memchr.c b/grub-core/gnulib/memchr.c +index 6c2b2d6..3db38a9 100644 +--- a/grub-core/gnulib/memchr.c ++++ b/grub-core/gnulib/memchr.c +@@ -1,4 +1,4 @@ +-/* Copyright (C) 1991, 1993, 1996-1997, 1999-2000, 2003-2004, 2006, 2008-2010 ++/* Copyright (C) 1991, 1993, 1996-1997, 1999-2000, 2003-2004, 2006, 2008-2013 + Free Software Foundation, Inc. + + Based on strlen implementation by Torbjorn Granlund (tege@sics.se), +diff --git a/grub-core/gnulib/mempcpy.c b/grub-core/gnulib/mempcpy.c +index b624d69..5582368 100644 +--- a/grub-core/gnulib/mempcpy.c ++++ b/grub-core/gnulib/mempcpy.c +@@ -1,5 +1,5 @@ + /* Copy memory area and return pointer after last written byte. +- Copyright (C) 2003, 2007, 2009, 2010 Free Software Foundation, Inc. ++ Copyright (C) 2003, 2007, 2009-2013 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 +@@ -12,8 +12,7 @@ + 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. */ ++ along with this program; if not, see . */ + + #include + +diff --git a/grub-core/gnulib/msvc-inval.c b/grub-core/gnulib/msvc-inval.c +new file mode 100644 +index 0000000..72a6b6e +--- /dev/null ++++ b/grub-core/gnulib/msvc-inval.c +@@ -0,0 +1,129 @@ ++/* Invalid parameter handler for MSVC runtime libraries. ++ Copyright (C) 2011-2013 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 ++ ++/* Specification. */ ++#include "msvc-inval.h" ++ ++#if HAVE_MSVC_INVALID_PARAMETER_HANDLER \ ++ && !(MSVC_INVALID_PARAMETER_HANDLING == SANE_LIBRARY_HANDLING) ++ ++/* Get _invalid_parameter_handler type and _set_invalid_parameter_handler ++ declaration. */ ++# include ++ ++# if MSVC_INVALID_PARAMETER_HANDLING == DEFAULT_HANDLING ++ ++static void cdecl ++gl_msvc_invalid_parameter_handler (const wchar_t *expression, ++ const wchar_t *function, ++ const wchar_t *file, ++ unsigned int line, ++ uintptr_t dummy) ++{ ++} ++ ++# else ++ ++/* Get declarations of the native Windows API functions. */ ++# define WIN32_LEAN_AND_MEAN ++# include ++ ++# if defined _MSC_VER ++ ++static void cdecl ++gl_msvc_invalid_parameter_handler (const wchar_t *expression, ++ const wchar_t *function, ++ const wchar_t *file, ++ unsigned int line, ++ uintptr_t dummy) ++{ ++ RaiseException (STATUS_GNULIB_INVALID_PARAMETER, 0, 0, NULL); ++} ++ ++# else ++ ++/* An index to thread-local storage. */ ++static DWORD tls_index; ++static int tls_initialized /* = 0 */; ++ ++/* Used as a fallback only. */ ++static struct gl_msvc_inval_per_thread not_per_thread; ++ ++struct gl_msvc_inval_per_thread * ++gl_msvc_inval_current (void) ++{ ++ if (!tls_initialized) ++ { ++ tls_index = TlsAlloc (); ++ tls_initialized = 1; ++ } ++ if (tls_index == TLS_OUT_OF_INDEXES) ++ /* TlsAlloc had failed. */ ++ return ¬_per_thread; ++ else ++ { ++ struct gl_msvc_inval_per_thread *pointer = ++ (struct gl_msvc_inval_per_thread *) TlsGetValue (tls_index); ++ if (pointer == NULL) ++ { ++ /* First call. Allocate a new 'struct gl_msvc_inval_per_thread'. */ ++ pointer = ++ (struct gl_msvc_inval_per_thread *) ++ malloc (sizeof (struct gl_msvc_inval_per_thread)); ++ if (pointer == NULL) ++ /* Could not allocate memory. Use the global storage. */ ++ pointer = ¬_per_thread; ++ TlsSetValue (tls_index, pointer); ++ } ++ return pointer; ++ } ++} ++ ++static void cdecl ++gl_msvc_invalid_parameter_handler (const wchar_t *expression, ++ const wchar_t *function, ++ const wchar_t *file, ++ unsigned int line, ++ uintptr_t dummy) ++{ ++ struct gl_msvc_inval_per_thread *current = gl_msvc_inval_current (); ++ if (current->restart_valid) ++ longjmp (current->restart, 1); ++ else ++ /* An invalid parameter notification from outside the gnulib code. ++ Give the caller a chance to intervene. */ ++ RaiseException (STATUS_GNULIB_INVALID_PARAMETER, 0, 0, NULL); ++} ++ ++# endif ++ ++# endif ++ ++static int gl_msvc_inval_initialized /* = 0 */; ++ ++void ++gl_msvc_inval_ensure_handler (void) ++{ ++ if (gl_msvc_inval_initialized == 0) ++ { ++ _set_invalid_parameter_handler (gl_msvc_invalid_parameter_handler); ++ gl_msvc_inval_initialized = 1; ++ } ++} ++ ++#endif +diff --git a/grub-core/gnulib/msvc-inval.h b/grub-core/gnulib/msvc-inval.h +new file mode 100644 +index 0000000..dcb0353 +--- /dev/null ++++ b/grub-core/gnulib/msvc-inval.h +@@ -0,0 +1,222 @@ ++/* Invalid parameter handler for MSVC runtime libraries. ++ Copyright (C) 2011-2013 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 . */ ++ ++#ifndef _MSVC_INVAL_H ++#define _MSVC_INVAL_H ++ ++/* With MSVC runtime libraries with the "invalid parameter handler" concept, ++ functions like fprintf(), dup2(), or close() crash when the caller passes ++ an invalid argument. But POSIX wants error codes (such as EINVAL or EBADF) ++ instead. ++ This file defines macros that turn such an invalid parameter notification ++ into a non-local exit. An error code can then be produced at the target ++ of this exit. You can thus write code like ++ ++ TRY_MSVC_INVAL ++ { ++ ++ } ++ CATCH_MSVC_INVAL ++ { ++ ++ } ++ DONE_MSVC_INVAL; ++ ++ This entire block expands to a single statement. ++ ++ The handling of invalid parameters can be done in three ways: ++ ++ * The default way, which is reasonable for programs (not libraries): ++ AC_DEFINE([MSVC_INVALID_PARAMETER_HANDLING], [DEFAULT_HANDLING]) ++ ++ * The way for libraries that make "hairy" calls (like close(-1), or ++ fclose(fp) where fileno(fp) is closed, or simply getdtablesize()): ++ AC_DEFINE([MSVC_INVALID_PARAMETER_HANDLING], [HAIRY_LIBRARY_HANDLING]) ++ ++ * The way for libraries that make no "hairy" calls: ++ AC_DEFINE([MSVC_INVALID_PARAMETER_HANDLING], [SANE_LIBRARY_HANDLING]) ++ */ ++ ++#define DEFAULT_HANDLING 0 ++#define HAIRY_LIBRARY_HANDLING 1 ++#define SANE_LIBRARY_HANDLING 2 ++ ++#if HAVE_MSVC_INVALID_PARAMETER_HANDLER \ ++ && !(MSVC_INVALID_PARAMETER_HANDLING == SANE_LIBRARY_HANDLING) ++/* A native Windows platform with the "invalid parameter handler" concept, ++ and either DEFAULT_HANDLING or HAIRY_LIBRARY_HANDLING. */ ++ ++# if MSVC_INVALID_PARAMETER_HANDLING == DEFAULT_HANDLING ++/* Default handling. */ ++ ++# ifdef __cplusplus ++extern "C" { ++# endif ++ ++/* Ensure that the invalid parameter handler in installed that just returns. ++ Because we assume no other part of the program installs a different ++ invalid parameter handler, this solution is multithread-safe. */ ++extern void gl_msvc_inval_ensure_handler (void); ++ ++# ifdef __cplusplus ++} ++# endif ++ ++# define TRY_MSVC_INVAL \ ++ do \ ++ { \ ++ gl_msvc_inval_ensure_handler (); \ ++ if (1) ++# define CATCH_MSVC_INVAL \ ++ else ++# define DONE_MSVC_INVAL \ ++ } \ ++ while (0) ++ ++# else ++/* Handling for hairy libraries. */ ++ ++# include ++ ++/* Gnulib can define its own status codes, as described in the page ++ "Raising Software Exceptions" on microsoft.com ++ . ++ Our status codes are composed of ++ - 0xE0000000, mandatory for all user-defined status codes, ++ - 0x474E550, a API identifier ("GNU"), ++ - 0, 1, 2, ..., used to distinguish different status codes from the ++ same API. */ ++# define STATUS_GNULIB_INVALID_PARAMETER (0xE0000000 + 0x474E550 + 0) ++ ++# if defined _MSC_VER ++/* A compiler that supports __try/__except, as described in the page ++ "try-except statement" on microsoft.com ++ . ++ With __try/__except, we can use the multithread-safe exception handling. */ ++ ++# ifdef __cplusplus ++extern "C" { ++# endif ++ ++/* Ensure that the invalid parameter handler in installed that raises a ++ software exception with code STATUS_GNULIB_INVALID_PARAMETER. ++ Because we assume no other part of the program installs a different ++ invalid parameter handler, this solution is multithread-safe. */ ++extern void gl_msvc_inval_ensure_handler (void); ++ ++# ifdef __cplusplus ++} ++# endif ++ ++# define TRY_MSVC_INVAL \ ++ do \ ++ { \ ++ gl_msvc_inval_ensure_handler (); \ ++ __try ++# define CATCH_MSVC_INVAL \ ++ __except (GetExceptionCode () == STATUS_GNULIB_INVALID_PARAMETER \ ++ ? EXCEPTION_EXECUTE_HANDLER \ ++ : EXCEPTION_CONTINUE_SEARCH) ++# define DONE_MSVC_INVAL \ ++ } \ ++ while (0) ++ ++# else ++/* Any compiler. ++ We can only use setjmp/longjmp. */ ++ ++# include ++ ++# ifdef __cplusplus ++extern "C" { ++# endif ++ ++struct gl_msvc_inval_per_thread ++{ ++ /* The restart that will resume execution at the code between ++ CATCH_MSVC_INVAL and DONE_MSVC_INVAL. It is enabled only between ++ TRY_MSVC_INVAL and CATCH_MSVC_INVAL. */ ++ jmp_buf restart; ++ ++ /* Tells whether the contents of restart is valid. */ ++ int restart_valid; ++}; ++ ++/* Ensure that the invalid parameter handler in installed that passes ++ control to the gl_msvc_inval_restart if it is valid, or raises a ++ software exception with code STATUS_GNULIB_INVALID_PARAMETER otherwise. ++ Because we assume no other part of the program installs a different ++ invalid parameter handler, this solution is multithread-safe. */ ++extern void gl_msvc_inval_ensure_handler (void); ++ ++/* Return a pointer to the per-thread data for the current thread. */ ++extern struct gl_msvc_inval_per_thread *gl_msvc_inval_current (void); ++ ++# ifdef __cplusplus ++} ++# endif ++ ++# define TRY_MSVC_INVAL \ ++ do \ ++ { \ ++ struct gl_msvc_inval_per_thread *msvc_inval_current; \ ++ gl_msvc_inval_ensure_handler (); \ ++ msvc_inval_current = gl_msvc_inval_current (); \ ++ /* First, initialize gl_msvc_inval_restart. */ \ ++ if (setjmp (msvc_inval_current->restart) == 0) \ ++ { \ ++ /* Then, mark it as valid. */ \ ++ msvc_inval_current->restart_valid = 1; ++# define CATCH_MSVC_INVAL \ ++ /* Execution completed. \ ++ Mark gl_msvc_inval_restart as invalid. */ \ ++ msvc_inval_current->restart_valid = 0; \ ++ } \ ++ else \ ++ { \ ++ /* Execution triggered an invalid parameter notification. \ ++ Mark gl_msvc_inval_restart as invalid. */ \ ++ msvc_inval_current->restart_valid = 0; ++# define DONE_MSVC_INVAL \ ++ } \ ++ } \ ++ while (0) ++ ++# endif ++ ++# endif ++ ++#else ++/* A platform that does not need to the invalid parameter handler, ++ or when SANE_LIBRARY_HANDLING is desired. */ ++ ++/* The braces here avoid GCC warnings like ++ "warning: suggest explicit braces to avoid ambiguous 'else'". */ ++# define TRY_MSVC_INVAL \ ++ do \ ++ { \ ++ if (1) ++# define CATCH_MSVC_INVAL \ ++ else ++# define DONE_MSVC_INVAL \ ++ } \ ++ while (0) ++ ++#endif ++ ++#endif /* _MSVC_INVAL_H */ +diff --git a/grub-core/gnulib/msvc-nothrow.c b/grub-core/gnulib/msvc-nothrow.c +new file mode 100644 +index 0000000..8d65472 +--- /dev/null ++++ b/grub-core/gnulib/msvc-nothrow.c +@@ -0,0 +1,49 @@ ++/* Wrappers that don't throw invalid parameter notifications ++ with MSVC runtime libraries. ++ Copyright (C) 2011-2013 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 ++ ++/* Specification. */ ++#include "msvc-nothrow.h" ++ ++/* Get declarations of the native Windows API functions. */ ++#define WIN32_LEAN_AND_MEAN ++#include ++ ++#include "msvc-inval.h" ++ ++#undef _get_osfhandle ++ ++#if HAVE_MSVC_INVALID_PARAMETER_HANDLER ++intptr_t ++_gl_nothrow_get_osfhandle (int fd) ++{ ++ intptr_t result; ++ ++ TRY_MSVC_INVAL ++ { ++ result = _get_osfhandle (fd); ++ } ++ CATCH_MSVC_INVAL ++ { ++ result = (intptr_t) INVALID_HANDLE_VALUE; ++ } ++ DONE_MSVC_INVAL; ++ ++ return result; ++} ++#endif +diff --git a/grub-core/gnulib/msvc-nothrow.h b/grub-core/gnulib/msvc-nothrow.h +new file mode 100644 +index 0000000..5f52181 +--- /dev/null ++++ b/grub-core/gnulib/msvc-nothrow.h +@@ -0,0 +1,43 @@ ++/* Wrappers that don't throw invalid parameter notifications ++ with MSVC runtime libraries. ++ Copyright (C) 2011-2013 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 . */ ++ ++#ifndef _MSVC_NOTHROW_H ++#define _MSVC_NOTHROW_H ++ ++/* With MSVC runtime libraries with the "invalid parameter handler" concept, ++ functions like fprintf(), dup2(), or close() crash when the caller passes ++ an invalid argument. But POSIX wants error codes (such as EINVAL or EBADF) ++ instead. ++ This file defines wrappers that turn such an invalid parameter notification ++ into an error code. */ ++ ++#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ ++ ++/* Get original declaration of _get_osfhandle. */ ++# include ++ ++# if HAVE_MSVC_INVALID_PARAMETER_HANDLER ++ ++/* Override _get_osfhandle. */ ++extern intptr_t _gl_nothrow_get_osfhandle (int fd); ++# define _get_osfhandle _gl_nothrow_get_osfhandle ++ ++# endif ++ ++#endif ++ ++#endif /* _MSVC_NOTHROW_H */ +diff --git a/grub-core/gnulib/nl_langinfo.c b/grub-core/gnulib/nl_langinfo.c +index a3d0d11..771c953 100644 +--- a/grub-core/gnulib/nl_langinfo.c ++++ b/grub-core/gnulib/nl_langinfo.c +@@ -1,6 +1,6 @@ + /* nl_langinfo() replacement: query locale dependent information. + +- Copyright (C) 2007-2010 Free Software Foundation, Inc. ++ Copyright (C) 2007-2013 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 +@@ -97,7 +97,7 @@ rpl_nl_langinfo (nl_item item) + strings, appended in memory. */ + return "\0\0\0\0\0\0\0\0\0\0"; + # endif +-# if GNULIB_defined_YESEXPR ++# if GNULIB_defined_YESEXPR || !FUNC_NL_LANGINFO_YESEXPR_WORKS + case YESEXPR: + return "^[yY]"; + case NOEXPR: +@@ -141,7 +141,8 @@ nl_langinfo (nl_item item) + { + static char buf[2 + 10 + 1]; + +- /* Woe32 has a function returning the locale's codepage as a number. */ ++ /* The Windows API has a function returning the locale's codepage as ++ a number. */ + sprintf (buf, "CP%u", GetACP ()); + return buf; + } +diff --git a/grub-core/gnulib/printf-args.c b/grub-core/gnulib/printf-args.c +index 46c03a2..c27e6bc 100644 +--- a/grub-core/gnulib/printf-args.c ++++ b/grub-core/gnulib/printf-args.c +@@ -1,5 +1,5 @@ + /* Decomposed printf argument list. +- Copyright (C) 1999, 2002-2003, 2005-2007, 2009-2010 Free Software ++ Copyright (C) 1999, 2002-2003, 2005-2007, 2009-2013 Free Software + Foundation, Inc. + + This program is free software; you can redistribute it and/or modify +@@ -13,8 +13,7 @@ + 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. */ ++ with this program; if not, see . */ + + /* This file can be parametrized with the following macros: + ENABLE_UNISTDIO Set to 1 to enable the unistdio extensions. +diff --git a/grub-core/gnulib/printf-args.h b/grub-core/gnulib/printf-args.h +index 2536eba..2a9c2a3 100644 +--- a/grub-core/gnulib/printf-args.h ++++ b/grub-core/gnulib/printf-args.h +@@ -1,5 +1,5 @@ + /* Decomposed printf argument list. +- Copyright (C) 1999, 2002-2003, 2006-2007, 2009-2010 Free Software ++ Copyright (C) 1999, 2002-2003, 2006-2007, 2011-2013 Free Software + Foundation, Inc. + + This program is free software; you can redistribute it and/or modify +@@ -13,8 +13,7 @@ + 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. */ ++ with this program; if not, see . */ + + #ifndef _PRINTF_ARGS_H + #define _PRINTF_ARGS_H +@@ -136,10 +135,14 @@ typedef struct + } + argument; + ++/* Number of directly allocated arguments (no malloc() needed). */ ++#define N_DIRECT_ALLOC_ARGUMENTS 7 ++ + typedef struct + { + size_t count; + argument *arg; ++ argument direct_alloc_arg[N_DIRECT_ALLOC_ARGUMENTS]; + } + arguments; + +diff --git a/grub-core/gnulib/printf-parse.c b/grub-core/gnulib/printf-parse.c +index f612beb..23cacc1 100644 +--- a/grub-core/gnulib/printf-parse.c ++++ b/grub-core/gnulib/printf-parse.c +@@ -1,5 +1,5 @@ + /* Formatted output to strings. +- Copyright (C) 1999-2000, 2002-2003, 2006-2010 Free Software Foundation, Inc. ++ Copyright (C) 1999-2000, 2002-2003, 2006-2013 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 +@@ -12,8 +12,7 @@ + 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. */ ++ with this program; if not, see . */ + + /* This file can be parametrized with the following macros: + CHAR_T The element type of the format string. +@@ -63,6 +62,9 @@ + /* malloc(), realloc(), free(). */ + #include + ++/* memcpy(). */ ++#include ++ + /* errno. */ + #include + +@@ -80,23 +82,20 @@ STATIC + int + PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a) + { +- const CHAR_T *cp = format; /* pointer into format */ ++ const CHAR_T *cp = format; /* pointer into format */ + size_t arg_posn = 0; /* number of regular arguments consumed */ +- size_t d_allocated; /* allocated elements of d->dir */ +- size_t a_allocated; /* allocated elements of a->arg */ ++ size_t d_allocated; /* allocated elements of d->dir */ ++ size_t a_allocated; /* allocated elements of a->arg */ + size_t max_width_length = 0; + size_t max_precision_length = 0; + + d->count = 0; +- d_allocated = 1; +- d->dir = (DIRECTIVE *) malloc (d_allocated * sizeof (DIRECTIVE)); +- if (d->dir == NULL) +- /* Out of memory. */ +- goto out_of_memory_1; ++ d_allocated = N_DIRECT_ALLOC_DIRECTIVES; ++ d->dir = d->direct_alloc_dir; + + a->count = 0; +- a_allocated = 0; +- a->arg = NULL; ++ a_allocated = N_DIRECT_ALLOC_ARGUMENTS; ++ a->arg = a->direct_alloc_arg; + + #define REGISTER_ARG(_index_,_type_) \ + { \ +@@ -113,12 +112,14 @@ PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a) + if (size_overflow_p (memory_size)) \ + /* Overflow, would lead to out of memory. */ \ + goto out_of_memory; \ +- memory = (argument *) (a->arg \ ++ memory = (argument *) (a->arg != a->direct_alloc_arg \ + ? realloc (a->arg, memory_size) \ + : malloc (memory_size)); \ + if (memory == NULL) \ + /* Out of memory. */ \ + goto out_of_memory; \ ++ if (a->arg == a->direct_alloc_arg) \ ++ memcpy (memory, a->arg, a->count * sizeof (argument)); \ + a->arg = memory; \ + } \ + while (a->count <= n) \ +@@ -206,6 +207,13 @@ PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a) + dp->flags |= FLAG_ZERO; + cp++; + } ++#if __GLIBC__ >= 2 && !defined __UCLIBC__ ++ else if (*cp == 'I') ++ { ++ dp->flags |= FLAG_LOCALIZED; ++ cp++; ++ } ++#endif + else + break; + } +@@ -393,7 +401,7 @@ PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a) + cp++; + } + #if defined __APPLE__ && defined __MACH__ +- /* On MacOS X 10.3, PRIdMAX is defined as "qd". ++ /* On Mac OS X 10.3, PRIdMAX is defined as "qd". + We cannot change it to "lld" because PRIdMAX must also + be understood by the system's printf routines. */ + else if (*cp == 'q') +@@ -412,7 +420,7 @@ PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a) + } + #endif + #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ +- /* On native Win32, PRIdMAX is defined as "I64d". ++ /* On native Windows, PRIdMAX is defined as "I64d". + We cannot change it to "lld" because PRIdMAX must also + be understood by the system's printf routines. */ + else if (*cp == 'I' && cp[1] == '6' && cp[2] == '4') +@@ -581,10 +589,14 @@ PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a) + if (size_overflow_p (memory_size)) + /* Overflow, would lead to out of memory. */ + goto out_of_memory; +- memory = (DIRECTIVE *) realloc (d->dir, memory_size); ++ memory = (DIRECTIVE *) (d->dir != d->direct_alloc_dir ++ ? realloc (d->dir, memory_size) ++ : malloc (memory_size)); + if (memory == NULL) + /* Out of memory. */ + goto out_of_memory; ++ if (d->dir == d->direct_alloc_dir) ++ memcpy (memory, d->dir, d->count * sizeof (DIRECTIVE)); + d->dir = memory; + } + } +@@ -603,19 +615,18 @@ PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a) + return 0; + + error: +- if (a->arg) ++ if (a->arg != a->direct_alloc_arg) + free (a->arg); +- if (d->dir) ++ if (d->dir != d->direct_alloc_dir) + free (d->dir); + errno = EINVAL; + return -1; + + out_of_memory: +- if (a->arg) ++ if (a->arg != a->direct_alloc_arg) + free (a->arg); +- if (d->dir) ++ if (d->dir != d->direct_alloc_dir) + free (d->dir); +-out_of_memory_1: + errno = ENOMEM; + return -1; + } +diff --git a/grub-core/gnulib/printf-parse.h b/grub-core/gnulib/printf-parse.h +index 0f2b708..d8474be 100644 +--- a/grub-core/gnulib/printf-parse.h ++++ b/grub-core/gnulib/printf-parse.h +@@ -1,5 +1,5 @@ + /* Parse printf format string. +- Copyright (C) 1999, 2002-2003, 2005, 2007, 2009-2010 Free Software ++ Copyright (C) 1999, 2002-2003, 2005, 2007, 2010-2013 Free Software + Foundation, Inc. + + This program is free software; you can redistribute it and/or modify +@@ -13,8 +13,7 @@ + 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. */ ++ with this program; if not, see . */ + + #ifndef _PRINTF_PARSE_H + #define _PRINTF_PARSE_H +@@ -23,6 +22,10 @@ + ENABLE_UNISTDIO Set to 1 to enable the unistdio extensions. + STATIC Set to 'static' to declare the function static. */ + ++#if HAVE_FEATURES_H ++# include /* for __GLIBC__, __UCLIBC__ */ ++#endif ++ + #include "printf-args.h" + + +@@ -33,6 +36,9 @@ + #define FLAG_SPACE 8 /* space flag */ + #define FLAG_ALT 16 /* # flag */ + #define FLAG_ZERO 32 ++#if __GLIBC__ >= 2 && !defined __UCLIBC__ ++# define FLAG_LOCALIZED 64 /* I flag, uses localized digits */ ++#endif + + /* arg_index value indicating that no argument is consumed. */ + #define ARG_NONE (~(size_t)0) +@@ -40,6 +46,9 @@ + /* xxx_directive: A parsed directive. + xxx_directives: A parsed format string. */ + ++/* Number of directly allocated directives (no malloc() needed). */ ++#define N_DIRECT_ALLOC_DIRECTIVES 7 ++ + /* A parsed directive. */ + typedef struct + { +@@ -64,6 +73,7 @@ typedef struct + char_directive *dir; + size_t max_width_length; + size_t max_precision_length; ++ char_directive direct_alloc_dir[N_DIRECT_ALLOC_DIRECTIVES]; + } + char_directives; + +@@ -93,6 +103,7 @@ typedef struct + u8_directive *dir; + size_t max_width_length; + size_t max_precision_length; ++ u8_directive direct_alloc_dir[N_DIRECT_ALLOC_DIRECTIVES]; + } + u8_directives; + +@@ -120,6 +131,7 @@ typedef struct + u16_directive *dir; + size_t max_width_length; + size_t max_precision_length; ++ u16_directive direct_alloc_dir[N_DIRECT_ALLOC_DIRECTIVES]; + } + u16_directives; + +@@ -147,6 +159,7 @@ typedef struct + u32_directive *dir; + size_t max_width_length; + size_t max_precision_length; ++ u32_directive direct_alloc_dir[N_DIRECT_ALLOC_DIRECTIVES]; + } + u32_directives; + +diff --git a/grub-core/gnulib/progname.c b/grub-core/gnulib/progname.c +index 1415e6a..0c195e5 100644 +--- a/grub-core/gnulib/progname.c ++++ b/grub-core/gnulib/progname.c +@@ -1,5 +1,5 @@ + /* Program name management. +- Copyright (C) 2001-2003, 2005-2010 Free Software Foundation, Inc. ++ Copyright (C) 2001-2003, 2005-2013 Free Software Foundation, Inc. + Written by Bruno Haible , 2001. + + This program is free software: you can redistribute it and/or modify +diff --git a/grub-core/gnulib/progname.h b/grub-core/gnulib/progname.h +index 5ba303b..b4f3c27 100644 +--- a/grub-core/gnulib/progname.h ++++ b/grub-core/gnulib/progname.h +@@ -1,5 +1,5 @@ + /* Program name management. +- Copyright (C) 2001-2004, 2006, 2009-2010 Free Software Foundation, Inc. ++ Copyright (C) 2001-2004, 2006, 2009-2013 Free Software Foundation, Inc. + Written by Bruno Haible , 2001. + + This program is free software: you can redistribute it and/or modify +diff --git a/grub-core/gnulib/rawmemchr.c b/grub-core/gnulib/rawmemchr.c +index 0a88777..a0298ce 100644 +--- a/grub-core/gnulib/rawmemchr.c ++++ b/grub-core/gnulib/rawmemchr.c +@@ -1,5 +1,5 @@ + /* Searching in a string. +- Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc. ++ Copyright (C) 2008-2013 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 +diff --git a/grub-core/gnulib/realloc.c b/grub-core/gnulib/realloc.c +index 053208f..b51010a 100644 +--- a/grub-core/gnulib/realloc.c ++++ b/grub-core/gnulib/realloc.c +@@ -1,6 +1,6 @@ + /* realloc() function that is glibc compatible. + +- Copyright (C) 1997, 2003-2004, 2006-2007, 2009-2010 Free Software ++ Copyright (C) 1997, 2003-2004, 2006-2007, 2009-2013 Free Software + Foundation, Inc. + + This program is free software: you can redistribute it and/or modify +@@ -18,6 +18,7 @@ + + /* written by Jim Meyering and Bruno Haible */ + ++#define _GL_USE_STDLIB_ALLOC 1 + #include + + /* Only the AC_FUNC_REALLOC macro defines 'realloc' already in config.h. */ +@@ -34,23 +35,10 @@ + # define SYSTEM_MALLOC_GLIBC_COMPATIBLE 1 + #endif + +-/* Below we want to call the system's malloc and realloc. +- Undefine the symbols here so that including provides a +- declaration of malloc(), not of rpl_malloc(), and likewise for realloc. */ +-#undef malloc +-#undef realloc +- +-/* Specification. */ + #include + + #include + +-/* Below we want to call the system's malloc and realloc. +- Undefine the symbols, if they were defined by gnulib's +- replacement. */ +-#undef malloc +-#undef realloc +- + /* Change the size of an allocated block of memory P to N bytes, + with error checking. If N is zero, change it to 1. If P is NULL, + use malloc. */ +diff --git a/grub-core/gnulib/ref-add.sin b/grub-core/gnulib/ref-add.sin +index dbb61df..112bcdc 100644 +--- a/grub-core/gnulib/ref-add.sin ++++ b/grub-core/gnulib/ref-add.sin +@@ -1,6 +1,6 @@ + # Add this package to a list of references stored in a text file. + # +-# Copyright (C) 2000, 2009, 2010 Free Software Foundation, Inc. ++# Copyright (C) 2000, 2009-2013 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 +@@ -13,8 +13,7 @@ + # 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. ++# with this program; if not, see . + # + # Written by Bruno Haible . + # +diff --git a/grub-core/gnulib/ref-del.sin b/grub-core/gnulib/ref-del.sin +index 4c31a6e..6f73868 100644 +--- a/grub-core/gnulib/ref-del.sin ++++ b/grub-core/gnulib/ref-del.sin +@@ -1,6 +1,6 @@ + # Remove this package from a list of references stored in a text file. + # +-# Copyright (C) 2000, 2009, 2010 Free Software Foundation, Inc. ++# Copyright (C) 2000, 2009-2013 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 +@@ -13,8 +13,7 @@ + # 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. ++# with this program; if not, see . + # + # Written by Bruno Haible . + # +diff --git a/grub-core/gnulib/regcomp.c b/grub-core/gnulib/regcomp.c +index ddea3fb..596e0cf 100644 +--- a/grub-core/gnulib/regcomp.c ++++ b/grub-core/gnulib/regcomp.c +@@ -1,22 +1,21 @@ + /* Extended regular expression matching and search library. +- Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free +- Software Foundation, Inc. ++ Copyright (C) 2002-2013 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 3, or (at your option) +- any later version. ++ The GNU C Library 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, ++ The GNU C Library 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. ++ 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. */ ++ You should have received a copy of the GNU General Public ++ License along with the GNU C Library; if not, see ++ . */ + + static reg_errcode_t re_compile_internal (regex_t *preg, const char * pattern, + size_t length, reg_syntax_t syntax); +@@ -95,20 +94,20 @@ 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, ++ const 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, ++ const 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, ++ const char *class_name, ++ const 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, +@@ -207,7 +206,7 @@ static const size_t __re_error_msgid_idx[] = + 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 ++ Assumes the 'allocated' (and perhaps 'buffer') and 'translate' fields + are set in BUFP on entry. */ + + #ifdef _LIBC +@@ -242,7 +241,7 @@ re_compile_pattern (const char *pattern, size_t length, + weak_alias (__re_compile_pattern, re_compile_pattern) + #endif + +-/* Set by `re_set_syntax' to the current regexp syntax to recognize. Can ++/* 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 +@@ -274,7 +273,7 @@ int + re_compile_fastmap (bufp) + struct re_pattern_buffer *bufp; + { +- re_dfa_t *dfa = (re_dfa_t *) bufp->buffer; ++ re_dfa_t *dfa = bufp->buffer; + char *fastmap = bufp->fastmap; + + memset (fastmap, '\0', sizeof (char) * SBC_MAX); +@@ -293,7 +292,7 @@ weak_alias (__re_compile_fastmap, re_compile_fastmap) + #endif + + static inline void +-__attribute ((always_inline)) ++__attribute__ ((always_inline)) + re_set_fastmap (char *fastmap, bool icase, int ch) + { + fastmap[ch] = 1; +@@ -308,7 +307,7 @@ 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; ++ re_dfa_t *dfa = 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) +@@ -440,15 +439,15 @@ re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state, + 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 ++ '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. ++ '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. + +@@ -551,10 +550,6 @@ regerror (int errcode, const regex_t *_Restrict_ preg, + 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. */ + msg = gettext ("unknown regexp error"); + else + msg = gettext (__re_error_msgid + __re_error_msgid_idx[errcode]); +@@ -587,19 +582,23 @@ weak_alias (__regerror, regerror) + 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 ++# ifdef __GNUC__ ++ [0 ... 0x80 / BITSET_WORD_BITS - 1] = BITSET_WORD_MAX ++# else ++# 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 ++# elif 2 * BITSET_WORD_BITS < ASCII_CHARS + BITSET_WORD_MAX, BITSET_WORD_MAX, +-# elif 1 * BITSET_WORD_BITS < ASCII_CHARS ++# elif 1 * BITSET_WORD_BITS < ASCII_CHARS + BITSET_WORD_MAX, +-# endif ++# endif + (BITSET_WORD_MAX + >> (SBC_MAX % BITSET_WORD_BITS == 0 + ? 0 + : BITSET_WORD_BITS - SBC_MAX % BITSET_WORD_BITS)) ++# endif + }; + #endif + +@@ -658,7 +657,7 @@ void + regfree (preg) + regex_t *preg; + { +- re_dfa_t *dfa = (re_dfa_t *) preg->buffer; ++ re_dfa_t *dfa = preg->buffer; + if (BE (dfa != NULL, 1)) + free_dfa_content (dfa); + preg->buffer = NULL; +@@ -719,7 +718,7 @@ re_comp (s) + + __re_error_msgid_idx[(int) REG_ESPACE]); + } + +- /* Since `re_exec' always passes NULL for the `regs' argument, we ++ /* 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. */ +@@ -730,7 +729,7 @@ re_comp (s) + if (!ret) + return NULL; + +- /* Yes, we're discarding `const' here if !HAVE_LIBINTL. */ ++ /* Yes, we're discarding 'const' here if !HAVE_LIBINTL. */ + return (char *) gettext (__re_error_msgid + __re_error_msgid_idx[(int) ret]); + } + +@@ -765,7 +764,7 @@ re_compile_internal (regex_t *preg, const char * pattern, size_t length, + preg->regs_allocated = REGS_UNALLOCATED; + + /* Initialize the dfa. */ +- dfa = (re_dfa_t *) preg->buffer; ++ dfa = preg->buffer; + if (BE (preg->allocated < sizeof (re_dfa_t), 0)) + { + /* If zero allocated, but buffer is non-null, try to realloc +@@ -874,7 +873,7 @@ init_dfa (re_dfa_t *dfa, size_t pat_len) + 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)) ++ if (BE (MIN (IDX_MAX, SIZE_MAX / max_object_size) / 2 <= pat_len, 0)) + return REG_ESPACE; + + dfa->nodes_alloc = pat_len + 1; +@@ -897,8 +896,10 @@ init_dfa (re_dfa_t *dfa, size_t pat_len) + != 0); + #else + codeset_name = nl_langinfo (CODESET); +- if (strcasecmp (codeset_name, "UTF-8") == 0 +- || strcasecmp (codeset_name, "UTF8") == 0) ++ if ((codeset_name[0] == 'U' || codeset_name[0] == 'u') ++ && (codeset_name[1] == 'T' || codeset_name[1] == 't') ++ && (codeset_name[2] == 'F' || codeset_name[2] == 'f') ++ && strcmp (codeset_name + 3 + (codeset_name[3] == '-'), "8") == 0) + dfa->is_utf8 = 1; + + /* We check exhaustively in the loop below if this charset is a +@@ -948,9 +949,43 @@ static void + internal_function + init_word_char (re_dfa_t *dfa) + { +- int i, j, ch; ++ int i = 0; ++ int j; ++ int ch = 0; + dfa->word_ops_used = 1; +- for (i = 0, ch = 0; i < BITSET_WORDS; ++i) ++ if (BE (dfa->map_notascii == 0, 1)) ++ { ++ bitset_word_t bits0 = 0x00000000; ++ bitset_word_t bits1 = 0x03ff0000; ++ bitset_word_t bits2 = 0x87fffffe; ++ bitset_word_t bits3 = 0x07fffffe; ++ if (BITSET_WORD_BITS == 64) ++ { ++ dfa->word_char[0] = bits1 << 31 << 1 | bits0; ++ dfa->word_char[1] = bits3 << 31 << 1 | bits2; ++ i = 2; ++ } ++ else if (BITSET_WORD_BITS == 32) ++ { ++ dfa->word_char[0] = bits0; ++ dfa->word_char[1] = bits1; ++ dfa->word_char[2] = bits2; ++ dfa->word_char[3] = bits3; ++ i = 4; ++ } ++ else ++ goto general_case; ++ ch = 128; ++ ++ if (BE (dfa->is_utf8, 1)) ++ { ++ memset (&dfa->word_char[i], '\0', (SBC_MAX - ch) / 8); ++ return; ++ } ++ } ++ ++ general_case: ++ for (; 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; +@@ -961,7 +996,7 @@ init_word_char (re_dfa_t *dfa) + static void + free_workarea_compile (regex_t *preg) + { +- re_dfa_t *dfa = (re_dfa_t *) preg->buffer; ++ re_dfa_t *dfa = preg->buffer; + bin_tree_storage_t *storage, *next; + for (storage = dfa->str_tree_storage; storage; storage = next) + { +@@ -1145,7 +1180,7 @@ optimize_utf8 (re_dfa_t *dfa) + static reg_errcode_t + analyze (regex_t *preg) + { +- re_dfa_t *dfa = (re_dfa_t *) preg->buffer; ++ re_dfa_t *dfa = preg->buffer; + reg_errcode_t ret; + + /* Allocate arrays. */ +@@ -1326,7 +1361,7 @@ 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) + { +- re_dfa_t *dfa = (re_dfa_t *) preg->buffer; ++ re_dfa_t *dfa = preg->buffer; + bin_tree_t *body = node->left; + bin_tree_t *op, *cls, *tree1, *tree; + +@@ -1660,7 +1695,7 @@ calc_eclosure (re_dfa_t *dfa) + /* If we have already calculated, skip it. */ + if (dfa->eclosures[node_idx].nelem != 0) + continue; +- /* Calculate epsilon closure of `node_idx'. */ ++ /* Calculate epsilon closure of 'node_idx'. */ + err = calc_eclosure_iter (&eclosure_elem, dfa, node_idx, true); + if (BE (err != REG_NOERROR, 0)) + return err; +@@ -1710,14 +1745,14 @@ calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa, Idx node, bool root) + { + re_node_set eclosure_elem; + Idx edest = dfa->edests[node].elems[i]; +- /* If calculating the epsilon closure of `edest' is in progress, ++ /* 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, ++ /* If we haven't calculated the epsilon closure of 'edest' yet, + calculate now. Otherwise use calculated epsilon closure. */ + if (dfa->eclosures[edest].nelem == 0) + { +@@ -1727,11 +1762,11 @@ 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'. */ ++ /* Merge the epsilon closure of 'edest'. */ + err = re_node_set_merge (&eclosure, &eclosure_elem); + if (BE (err != REG_NOERROR, 0)) + return err; +- /* If the epsilon closure of `edest' is incomplete, ++ /* If the epsilon closure of 'edest' is incomplete, + the epsilon closure of this node is also incomplete. */ + if (dfa->eclosures[edest].nelem == 0) + { +@@ -2093,7 +2128,7 @@ peek_token_bracket (re_token_t *token, re_string_t *input, reg_syntax_t syntax) + + /* 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. ++ If an error occurs, ERR is set by error code, and return NULL. + This function build the following tree, from regular expression : + CAT + / \ +@@ -2107,7 +2142,7 @@ 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; ++ re_dfa_t *dfa = preg->buffer; + bin_tree_t *tree, *eor, *root; + re_token_t current_token; + dfa->syntax = syntax; +@@ -2135,13 +2170,13 @@ parse (re_string_t *regexp, regex_t *preg, reg_syntax_t syntax, + / \ + + +- ALT means alternative, which represents the operator `|'. */ ++ 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; ++ re_dfa_t *dfa = 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)) +@@ -2183,7 +2218,7 @@ 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; ++ re_dfa_t *dfa = preg->buffer; + tree = parse_expression (regexp, preg, token, syntax, nest, err); + if (BE (*err != REG_NOERROR && tree == NULL, 0)) + return NULL; +@@ -2194,16 +2229,21 @@ parse_branch (re_string_t *regexp, regex_t *preg, re_token_t *token, + expr = parse_expression (regexp, preg, token, syntax, nest, err); + if (BE (*err != REG_NOERROR && expr == NULL, 0)) + { ++ if (tree != NULL) ++ postorder (tree, free_tree, NULL); + return NULL; + } + if (tree != NULL && expr != NULL) + { +- tree = create_tree (dfa, tree, expr, CONCAT); +- if (tree == NULL) ++ bin_tree_t *newtree = create_tree (dfa, tree, expr, CONCAT); ++ if (newtree == NULL) + { ++ postorder (expr, free_tree, NULL); ++ postorder (tree, free_tree, NULL); + *err = REG_ESPACE; + return NULL; + } ++ tree = newtree; + } + else if (tree == NULL) + tree = expr; +@@ -2222,7 +2262,7 @@ 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; ++ re_dfa_t *dfa = preg->buffer; + bin_tree_t *tree; + switch (token->type) + { +@@ -2378,8 +2418,8 @@ parse_expression (re_string_t *regexp, regex_t *preg, re_token_t *token, + case OP_WORD: + case OP_NOTWORD: + tree = build_charclass_op (dfa, regexp->trans, +- (const unsigned char *) "alnum", +- (const unsigned char *) "_", ++ "alnum", ++ "_", + token->type == OP_NOTWORD, err); + if (BE (*err != REG_NOERROR && tree == NULL, 0)) + return NULL; +@@ -2387,8 +2427,8 @@ parse_expression (re_string_t *regexp, regex_t *preg, re_token_t *token, + case OP_SPACE: + case OP_NOTSPACE: + tree = build_charclass_op (dfa, regexp->trans, +- (const unsigned char *) "space", +- (const unsigned char *) "", ++ "space", ++ "", + token->type == OP_NOTSPACE, err); + if (BE (*err != REG_NOERROR && tree == NULL, 0)) + return NULL; +@@ -2438,7 +2478,7 @@ 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; ++ re_dfa_t *dfa = preg->buffer; + bin_tree_t *tree; + size_t cur_nsub; + cur_nsub = preg->re_nsub++; +@@ -2452,7 +2492,11 @@ 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; ++ { ++ if (tree != NULL) ++ postorder (tree, free_tree, NULL); ++ *err = REG_EPAREN; ++ } + if (BE (*err != REG_NOERROR, 0)) + return NULL; + } +@@ -2530,6 +2574,12 @@ parse_dup_op (bin_tree_t *elem, re_string_t *regexp, re_dfa_t *dfa, + *err = REG_BADBR; + return NULL; + } ++ ++ if (BE (RE_DUP_MAX < (end == REG_MISSING ? start : end), 0)) ++ { ++ *err = REG_ESIZE; ++ return NULL; ++ } + } + else + { +@@ -2570,7 +2620,10 @@ parse_dup_op (bin_tree_t *elem, re_string_t *regexp, re_dfa_t *dfa, + old_tree = NULL; + + if (elem->token.type == SUBEXP) +- postorder (elem, mark_opt_subexp, (void *) (long) elem->token.opr.idx); ++ { ++ uintptr_t subidx = elem->token.opr.idx; ++ postorder (elem, mark_opt_subexp, (void *) subidx); ++ } + + tree = create_tree (dfa, elem, NULL, + (end == REG_MISSING ? OP_DUP_ASTERISK : OP_ALT)); +@@ -2616,7 +2669,7 @@ parse_dup_op (bin_tree_t *elem, re_string_t *regexp, re_dfa_t *dfa, + 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 ++ mbcset->range_ends, is a pointer argument since we may + update it. */ + + static reg_errcode_t +@@ -2655,7 +2708,6 @@ build_range_exp (const reg_syntax_t syntax, + 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] +@@ -2669,11 +2721,7 @@ build_range_exp (const reg_syntax_t syntax, + ? __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 (BE ((syntax & RE_NO_EMPTY_RANGES) +- && wcscoll (cmp_buf, cmp_buf + 4) > 0, 0)) ++ else if (BE ((syntax & RE_NO_EMPTY_RANGES) && start_wc > end_wc, 0)) + return REG_ERANGE; + + /* Got valid collation sequence values, add them as a new entry. +@@ -2714,9 +2762,7 @@ build_range_exp (const reg_syntax_t syntax, + /* 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) ++ if (start_wc <= wc && wc <= end_wc) + bitset_set (sbcset, wc); + } + } +@@ -2750,11 +2796,12 @@ build_range_exp (const reg_syntax_t syntax, + + 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) ++build_collating_symbol (bitset_t sbcset, re_charset_t *mbcset, ++ Idx *coll_sym_alloc, const unsigned char *name) ++# else /* not RE_ENABLE_I18N */ ++build_collating_symbol (bitset_t sbcset, const unsigned char *name) ++# endif /* not RE_ENABLE_I18N */ + { + size_t name_len = strlen ((const char *) name); + if (BE (name_len != 1, 0)) +@@ -2782,42 +2829,31 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token, + 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. */ ++ /* Local function for parse_bracket_exp used in _LIBC environment. ++ Seek the collating symbol entry corresponding to NAME. ++ Return the index of the symbol in the SYMB_TABLE, ++ or -1 if not found. */ + + auto inline int32_t +- __attribute ((always_inline)) +- seek_collating_symbol_entry (name, name_len) +- const unsigned char *name; +- size_t name_len; ++ __attribute__ ((always_inline)) ++ seek_collating_symbol_entry (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; ++ int32_t elem; + +- 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; ++ for (elem = 0; elem < table_size; elem++) ++ if (symb_table[2 * elem] != 0) ++ { ++ int32_t idx = symb_table[2 * elem + 1]; ++ /* Skip the name of collating element name. */ ++ idx += 1 + extra[idx]; ++ if (/* Compare the length of the name. */ ++ name_len == extra[idx] ++ /* Compare the name. */ ++ && memcmp (name, &extra[idx + 1], name_len) == 0) ++ /* Yep, this is the entry. */ ++ return elem; ++ } ++ return -1; + } + + /* Local function for parse_bracket_exp used in _LIBC environment. +@@ -2825,9 +2861,8 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token, + 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; ++ __attribute__ ((always_inline)) ++ lookup_collation_sequence_value (bracket_elem_t *br_elem) + { + if (br_elem->type == SB_CHAR) + { +@@ -2855,7 +2890,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token, + int32_t elem, idx; + elem = seek_collating_symbol_entry (br_elem->opr.name, + sym_name_len); +- if (symb_table[2 * elem] != 0) ++ if (elem != -1) + { + /* We found the entry. */ + idx = symb_table[2 * elem + 1]; +@@ -2873,7 +2908,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token, + /* Return the collation sequence value. */ + return *(unsigned int *) (extra + idx); + } +- else if (symb_table[2 * elem] == 0 && sym_name_len == 1) ++ else if (sym_name_len == 1) + { + /* No valid character. Match it as a single byte + character. */ +@@ -2886,20 +2921,17 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token, + return UINT_MAX; + } + +- /* Local function for parse_bracket_exp used in _LIBC environement. ++ /* Local function for parse_bracket_exp used in _LIBC environment. + 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 ++ mbcset->range_ends, is a pointer argument since 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; ++ __attribute__ ((always_inline)) ++ build_range_exp (bitset_t sbcset, re_charset_t *mbcset, int *range_alloc, ++ bracket_elem_t *start_elem, bracket_elem_t *end_elem) + { + unsigned int ch; + uint32_t start_collseq; +@@ -2912,6 +2944,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token, + 0)) + return REG_ERANGE; + ++ /* FIXME: Implement rational ranges here, too. */ + start_collseq = lookup_collation_sequence_value (start_elem); + end_collseq = lookup_collation_sequence_value (end_elem); + /* Check start/end collation sequence values. */ +@@ -2970,33 +3003,30 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token, + return REG_NOERROR; + } + +- /* Local function for parse_bracket_exp used in _LIBC environement. ++ /* Local function for parse_bracket_exp used in _LIBC environment. + 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. */ ++ pointer argument since 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; ++ __attribute__ ((always_inline)) ++ build_collating_symbol (bitset_t sbcset, re_charset_t *mbcset, ++ Idx *coll_sym_alloc, 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) ++ if (elem != -1) + { + /* 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) ++ else if (name_len == 1) + { + /* No valid character, treat it as a normal + character. */ +@@ -3076,6 +3106,10 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token, + if (BE (sbcset == NULL, 0)) + #endif /* RE_ENABLE_I18N */ + { ++ re_free (sbcset); ++#ifdef RE_ENABLE_I18N ++ re_free (mbcset); ++#endif + *err = REG_ESPACE; + return NULL; + } +@@ -3235,7 +3269,8 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token, + #ifdef RE_ENABLE_I18N + mbcset, &char_class_alloc, + #endif /* RE_ENABLE_I18N */ +- start_elem.opr.name, syntax); ++ (const char *) start_elem.opr.name, ++ syntax); + if (BE (*err != REG_NOERROR, 0)) + goto parse_bracket_exp_free_return; + break; +@@ -3414,7 +3449,7 @@ parse_bracket_symbol (bracket_elem_t *elem, re_string_t *regexp, + 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. */ ++ is a pointer argument since we may update it. */ + + static reg_errcode_t + #ifdef RE_ENABLE_I18N +@@ -3445,19 +3480,18 @@ build_equiv_class (bitset_t sbcset, const unsigned char *name) + _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)) ++ idx1 = findidx (&cp, -1); ++ if (BE (idx1 == 0 || *cp != '\0', 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'; ++ /* Build single byte matching table for this equivalence class. */ + len = weights[idx1 & 0xffffff]; + for (ch = 0; ch < SBC_MAX; ++ch) + { + char_buf[0] = ch; + cp = char_buf; +- idx2 = findidx (&cp); ++ idx2 = findidx (&cp, 1); + /* + idx2 = table[ch]; + */ +@@ -3510,20 +3544,20 @@ build_equiv_class (bitset_t sbcset, const unsigned char *name) + 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. */ ++ is a pointer argument since 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) ++ const 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) ++ const char *class_name, reg_syntax_t syntax) + #endif /* not RE_ENABLE_I18N */ + { + int i; +- const char *name = (const char *) class_name; ++ const char *name = class_name; + + /* In case of REG_ICASE "upper" and "lower" match the both of + upper and lower cases. */ +@@ -3597,8 +3631,8 @@ build_charclass (RE_TRANSLATE_TYPE trans, bitset_t sbcset, + + 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, ++ const char *class_name, ++ const char *extra, bool non_match, + reg_errcode_t *err) + { + re_bitset_ptr_t sbcset; +@@ -3704,8 +3738,9 @@ build_charclass_op (re_dfa_t *dfa, RE_TRANSLATE_TYPE trans, + } + + /* This is intended for the expressions like "a{1,3}". +- Fetch a number from `input', and return the number. ++ Fetch a number from 'input', and return the number. + Return REG_MISSING if the number field is empty like "{,1}". ++ Return RE_DUP_MAX + 1 if the number field is too large. + Return REG_ERROR if an error occurred. */ + + static Idx +@@ -3724,8 +3759,9 @@ fetch_number (re_string_t *input, re_token_t *token, reg_syntax_t syntax) + 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; ++ : num == REG_MISSING ++ ? c - '0' ++ : MIN (RE_DUP_MAX + 1, num * 10 + c - '0')); + } + return num; + } +@@ -3799,7 +3835,7 @@ create_token_tree (re_dfa_t *dfa, bin_tree_t *left, bin_tree_t *right, + static reg_errcode_t + mark_opt_subexp (void *extra, bin_tree_t *node) + { +- Idx idx = (Idx) (long) extra; ++ Idx idx = (uintptr_t) extra; + if (node->token.type == SUBEXP && node->token.opr.idx == idx) + node->token.opt_subexp = 1; + +diff --git a/grub-core/gnulib/regex.c b/grub-core/gnulib/regex.c +index ba0eebe..5a0332e 100644 +--- a/grub-core/gnulib/regex.c ++++ b/grub-core/gnulib/regex.c +@@ -1,26 +1,35 @@ + /* Extended regular expression matching and search library. +- Copyright (C) 2002, 2003, 2005, 2006, 2009, 2010 Free Software Foundation, +- Inc. ++ Copyright (C) 2002-2013 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 3, or (at your option) +- any later version. ++ The GNU C Library 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, ++ The GNU C Library 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. ++ 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. */ ++ You should have received a copy of the GNU General Public ++ License along with the GNU C Library; if not, see ++ . */ + +-#include ++#ifndef _LIBC ++# include + +-/* Make sure noone compiles this code with a C++ compiler. */ ++# if (__GNUC__ == 4 && 6 <= __GNUC_MINOR__) || 4 < __GNUC__ ++# pragma GCC diagnostic ignored "-Wsuggest-attribute=pure" ++# endif ++# if (__GNUC__ == 4 && 3 <= __GNUC_MINOR__) || 4 < __GNUC__ ++# pragma GCC diagnostic ignored "-Wold-style-definition" ++# pragma GCC diagnostic ignored "-Wtype-limits" ++# endif ++#endif ++ ++/* Make sure no one compiles this code with a C++ compiler. */ + #if defined __cplusplus && defined _LIBC + # error "This is C code, use a C compiler" + #endif +diff --git a/grub-core/gnulib/regex.h b/grub-core/gnulib/regex.h +index 1c139d6..854c6ed 100644 +--- a/grub-core/gnulib/regex.h ++++ b/grub-core/gnulib/regex.h +@@ -1,23 +1,22 @@ + /* Definitions for data structures and routines for the regular + expression library. +- Copyright (C) 1985, 1989, 1990, 1991, 1992, 1993, 1995, 1996, 1997, 1998, +- 2000, 2001, 2002, 2003, 2005, 2006, 2009, 2010 Free Software Foundation, +- Inc. ++ Copyright (C) 1985, 1989-1993, 1995-1998, 2000-2003, 2005-2013 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 3, or (at your option) +- any later version. ++ The GNU C Library 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, ++ The GNU C Library 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. ++ 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. */ ++ You should have received a copy of the GNU General Public ++ License along with the GNU C Library; if not, see ++ . */ + + #ifndef _REGEX_H + #define _REGEX_H 1 +@@ -29,13 +28,10 @@ + extern "C" { + #endif + +-/* Define __USE_GNU_REGEX to declare GNU extensions that violate the ++/* Define __USE_GNU 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 ++#ifdef _GNU_SOURCE ++# define __USE_GNU 1 + #endif + + #ifdef _REGEX_LARGE_OFFSETS +@@ -46,16 +42,6 @@ extern "C" { + 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. */ +@@ -70,10 +56,8 @@ 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; ++/* The traditional GNU regex implementation mishandles strings longer ++ than INT_MAX. */ + typedef int __re_idx_t; + typedef unsigned int __re_size_t; + typedef unsigned long int __re_long_size_t; +@@ -94,8 +78,7 @@ typedef unsigned long int active_reg_t; + add or remove a bit, only one other definition need change. */ + typedef unsigned long int reg_syntax_t; + +-#ifdef __USE_GNU_REGEX +- ++#ifdef __USE_GNU + /* 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) +@@ -162,9 +145,9 @@ typedef unsigned long int reg_syntax_t; + 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 \} ++/* If this bit is set, then '{...}' defines an interval, and \{ and \} + are literals. +- If not set, then `\{...\}' defines an interval. */ ++ 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. +@@ -226,8 +209,7 @@ typedef unsigned long int reg_syntax_t; + /* 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 */ ++#endif + + /* This global variable defines the particular regexp syntax to use (for + some interfaces). When a regexp is compiled, the syntax used is +@@ -235,7 +217,7 @@ typedef unsigned long int reg_syntax_t; + already-compiled regexps. */ + extern reg_syntax_t re_syntax_options; + +-#ifdef __USE_GNU_REGEX ++#ifdef __USE_GNU + /* 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!) */ +@@ -247,16 +229,19 @@ extern reg_syntax_t re_syntax_options; + | RE_NO_BK_PARENS | RE_NO_BK_REFS \ + | RE_NO_BK_VBAR | RE_NO_EMPTY_RANGES \ + | RE_DOT_NEWLINE | RE_CONTEXT_INDEP_ANCHORS \ ++ | RE_CHAR_CLASSES \ + | 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 )) ++ ((RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS \ ++ | RE_INVALID_INTERVAL_ORD) \ ++ & ~(RE_DOT_NOT_NULL | 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) ++ | RE_INTERVALS | RE_NO_GNU_OPS \ ++ | RE_INVALID_INTERVAL_ORD) + + # define RE_SYNTAX_GREP \ + (RE_BK_PLUS_QM | RE_CHAR_CLASSES \ +@@ -307,13 +292,12 @@ extern reg_syntax_t re_syntax_options; + | 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 _REGEX_INCLUDE_LIMITS_H ++# include ++# endif + # ifdef RE_DUP_MAX + # undef RE_DUP_MAX + # endif +@@ -321,16 +305,15 @@ extern reg_syntax_t re_syntax_options; + /* 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. ++ ((SIZE_MAX - 9) / 10) 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 */ ++#endif + + +-/* POSIX `cflags' bits (i.e., information for `regcomp'). */ ++/* 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. */ +@@ -350,7 +333,7 @@ extern reg_syntax_t re_syntax_options; + #define REG_NOSUB (1 << 3) + + +-/* POSIX `eflags' bits (i.e., information for regexec). */ ++/* 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 +@@ -368,7 +351,7 @@ extern reg_syntax_t re_syntax_options; + + + /* If any error codes are removed, changed, or added, update the +- `__re_error_msgid' table in regcomp.c. */ ++ '__re_error_msgid' table in regcomp.c. */ + + typedef enum + { +@@ -393,11 +376,11 @@ typedef enum + + /* Error codes we've added. */ + _REG_EEND, /* Premature end. */ +- _REG_ESIZE, /* Compiled pattern bigger than 2^16 bytes. */ ++ _REG_ESIZE, /* Too large (e.g., repeat count too large). */ + _REG_ERPAREN /* Unmatched ) or \); not returned from regcomp. */ + } reg_errcode_t; + +-#ifdef _XOPEN_SOURCE ++#if defined _XOPEN_SOURCE || defined __USE_XOPEN2K + # define REG_ENOSYS _REG_ENOSYS + #endif + #define REG_NOERROR _REG_NOERROR +@@ -418,129 +401,127 @@ typedef enum + #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 ++/* This data structure represents a compiled pattern. Before calling ++ the pattern compiler, the fields 'buffer', 'allocated', 'fastmap', ++ and 'translate' can be set. After the pattern has been compiled, ++ the fields 're_nsub', 'not_bol' and 'not_eol' are available. All ++ other fields are private to the regex routines. */ ++ ++#ifndef RE_TRANSLATE_TYPE ++# define __RE_TRANSLATE_TYPE unsigned char * ++# ifdef __USE_GNU ++# define RE_TRANSLATE_TYPE __RE_TRANSLATE_TYPE ++# endif + #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 ++#ifdef __USE_GNU ++# define __REPB_PREFIX(name) name + #else +-# define REG_TRANSLATE_TYPE unsigned char * ++# define __REPB_PREFIX(name) __##name + #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_dfa_t; +-typedef struct re_dfa_t re_dfa_t; +- + 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. */ +- re_dfa_t *_REG_RE_NAME (buffer); ++ /* Space that holds the compiled pattern. The type ++ 'struct re_dfa_t' is private and is not declared here. */ ++ struct re_dfa_t *__REPB_PREFIX(buffer); + +- /* Number of bytes to which `buffer' points. */ +- __re_long_size_t _REG_RE_NAME (allocated); ++ /* Number of bytes to which 'buffer' points. */ ++ __re_long_size_t __REPB_PREFIX(allocated); + +- /* Number of bytes actually used in `buffer'. */ +- __re_long_size_t _REG_RE_NAME (used); ++ /* Number of bytes actually used in 'buffer'. */ ++ __re_long_size_t __REPB_PREFIX(used); + + /* Syntax setting with which the pattern was compiled. */ +- reg_syntax_t _REG_RE_NAME (syntax); ++ reg_syntax_t __REPB_PREFIX(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); ++ char *__REPB_PREFIX(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); ++ __RE_TRANSLATE_TYPE __REPB_PREFIX(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 ++ 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; ++ perfectly; see 're_compile_fastmap' (the "duplicate" case). */ ++ unsigned __REPB_PREFIX(can_be_null) : 1; + +- /* If REGS_UNALLOCATED, allocate space in the `regs' structure +- for `max (RE_NREGS, re_nsub + 1)' groups. ++ /* 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 ++#ifdef __USE_GNU + # define REGS_UNALLOCATED 0 + # define REGS_REALLOCATE 1 + # define REGS_FIXED 2 + #endif +- unsigned int _REG_RE_NAME (regs_allocated) : 2; ++ unsigned __REPB_PREFIX(regs_allocated) : 2; + +- /* Set to zero when `re_compile_pattern' compiles a pattern; set to +- one by `re_compile_fastmap' if it updates the fastmap. */ +- unsigned int _REG_RE_NAME (fastmap_accurate) : 1; ++ /* Set to zero when 're_compile_pattern' compiles a pattern; set to ++ one by 're_compile_fastmap' if it updates the fastmap. */ ++ unsigned __REPB_PREFIX(fastmap_accurate) : 1; + +- /* If set, `re_match_2' does not return information about ++ /* If set, 're_match_2' does not return information about + subexpressions. */ +- unsigned int _REG_RE_NAME (no_sub) : 1; ++ unsigned __REPB_PREFIX(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; ++ unsigned __REPB_PREFIX(not_bol) : 1; + + /* Similarly for an end-of-line anchor. */ +- unsigned int _REG_RE_NAME (not_eol) : 1; ++ unsigned __REPB_PREFIX(not_eol) : 1; + + /* If true, an anchor at a newline matches. */ +- unsigned int _REG_RE_NAME (newline_anchor) : 1; +- +-/* [[[end pattern_buffer]]] */ ++ unsigned __REPB_PREFIX(newline_anchor) : 1; + }; + + typedef struct re_pattern_buffer regex_t; + ++/* Type for byte offsets within the string. POSIX mandates this. */ ++#ifdef _REGEX_LARGE_OFFSETS ++/* POSIX 1003.1-2008 requires that regoff_t be at least as wide as ++ ptrdiff_t and ssize_t. We don't know of any hosts where ptrdiff_t ++ is wider than ssize_t, so ssize_t is safe. */ ++typedef ssize_t regoff_t; ++#else ++/* The traditional GNU regex implementation mishandles strings longer ++ than INT_MAX. */ ++typedef int regoff_t; ++#endif ++ ++ ++#ifdef __USE_GNU + /* 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); ++ __re_size_t num_regs; ++ regoff_t *start; ++ regoff_t *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 ++/* 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. */ ++# ifndef RE_NREGS ++# define RE_NREGS 30 ++# endif + #endif + + + /* POSIX specification for registers. Aside from the different names than +- `re_registers', POSIX uses an array of structures, instead of a ++ 're_registers', POSIX uses an array of structures, instead of a + structure of arrays. */ + typedef struct + { +@@ -550,13 +531,19 @@ typedef struct + + /* Declarations for routines. */ + ++#ifdef __USE_GNU + /* Sets the current default syntax to SYNTAX, and return the old syntax. +- You can also simply assign to the `re_syntax_options' variable. */ ++ 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. */ ++ and syntax given by the global 're_syntax_options', into the buffer ++ BUFFER. Return NULL if successful, and an error string if not. ++ ++ To free the allocated storage, you must call 'regfree' on BUFFER. ++ Note that the translate table must either have been initialised by ++ 'regcomp', with a malloc'ed value, or set to NULL before calling ++ 'regfree'. */ + extern const char *re_compile_pattern (const char *__pattern, size_t __length, + struct re_pattern_buffer *__buffer); + +@@ -578,7 +565,7 @@ extern regoff_t re_search (struct re_pattern_buffer *__buffer, + struct re_registers *__regs); + + +-/* Like `re_search', but search in the concatenation of STRING1 and ++/* 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, +@@ -588,14 +575,14 @@ extern regoff_t re_search_2 (struct re_pattern_buffer *__buffer, + __re_idx_t __stop); + + +-/* Like `re_search', but return how many characters in STRING the regexp ++/* 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'. */ ++/* 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, +@@ -606,21 +593,22 @@ extern regoff_t re_match_2 (struct re_pattern_buffer *__buffer, + /* 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 ++ 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 +- BUFFER will allocate its own register data, without freeing the old +- data. */ ++ 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); ++#endif /* Use GNU */ + +-#if defined _REGEX_RE_COMP || defined _LIBC ++#if defined _REGEX_RE_COMP || (defined _LIBC && defined __USE_BSD) + # ifndef _CRAY + /* 4.2 bsd compatibility. */ + extern char *re_comp (const char *); +@@ -648,7 +636,7 @@ extern int re_exec (const char *); + #ifndef _Restrict_arr_ + # if ((199901L <= __STDC_VERSION__ \ + || ((3 < __GNUC__ || (3 == __GNUC__ && 1 <= __GNUC_MINOR__)) \ +- && !__STRICT_ANSI__)) \ ++ && !defined __STRICT_ANSI__)) \ + && !defined __GNUG__) + # define _Restrict_arr_ _Restrict_ + # else +diff --git a/grub-core/gnulib/regex_internal.c b/grub-core/gnulib/regex_internal.c +index 98b8d5d..899b0ae 100644 +--- a/grub-core/gnulib/regex_internal.c ++++ b/grub-core/gnulib/regex_internal.c +@@ -1,22 +1,21 @@ + /* Extended regular expression matching and search library. +- Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free +- Software Foundation, Inc. ++ Copyright (C) 2002-2013 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 3, or (at your option) +- any later version. ++ The GNU C Library 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, ++ The GNU C Library 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. ++ 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. */ ++ You should have received a copy of the GNU General Public ++ License along with the GNU C Library; if not, see ++ . */ + + static void re_string_construct_common (const char *str, Idx len, + re_string_t *pstr, +@@ -135,9 +134,9 @@ re_string_realloc_buffers (re_string_t *pstr, Idx new_buf_len) + { + 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)) ++ /* Avoid overflow in realloc. */ ++ const size_t max_object_size = MAX (sizeof (wint_t), sizeof (Idx)); ++ if (BE (MIN (IDX_MAX, SIZE_MAX / max_object_size) < new_buf_len, 0)) + return REG_ESPACE; + + new_wcs = re_realloc (pstr->wcs, wint_t, new_buf_len); +@@ -237,13 +236,8 @@ build_wcs_buffer (re_string_t *pstr) + 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)) ++ if (BE (mbclen == (size_t) -1 || mbclen == 0 ++ || (mbclen == (size_t) -2 && pstr->bufs_len >= pstr->len), 0)) + { + /* We treat these cases as a singlebyte character. */ + mbclen = 1; +@@ -252,6 +246,12 @@ build_wcs_buffer (re_string_t *pstr) + wc = pstr->trans[wc]; + pstr->cur_state = prev_st; + } ++ else if (BE (mbclen == (size_t) -2, 0)) ++ { ++ /* The buffer doesn't have enough space, finish to build. */ ++ pstr->cur_state = prev_st; ++ break; ++ } + + /* Write wide character and padding. */ + pstr->wcs[byte_idx++] = wc; +@@ -334,9 +334,11 @@ build_wcs_upper_buffer (re_string_t *pstr) + for (remain_len = byte_idx + mbclen - 1; byte_idx < remain_len ;) + pstr->wcs[byte_idx++] = WEOF; + } +- else if (mbclen == (size_t) -1 || mbclen == 0) ++ else if (mbclen == (size_t) -1 || mbclen == 0 ++ || (mbclen == (size_t) -2 && pstr->bufs_len >= pstr->len)) + { +- /* It is an invalid character or '\0'. Just use the byte. */ ++ /* It is an invalid character, an incomplete character ++ at the end of the string, 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. */ +@@ -449,7 +451,8 @@ build_wcs_upper_buffer (re_string_t *pstr) + for (remain_len = byte_idx + mbclen - 1; byte_idx < remain_len ;) + pstr->wcs[byte_idx++] = WEOF; + } +- else if (mbclen == (size_t) -1 || mbclen == 0) ++ else if (mbclen == (size_t) -1 || mbclen == 0 ++ || (mbclen == (size_t) -2 && pstr->bufs_len >= pstr->len)) + { + /* It is an invalid character or '\0'. Just use the byte. */ + int ch = pstr->raw_mbs[pstr->raw_mbs_idx + src_idx]; +@@ -496,8 +499,7 @@ re_string_skip_chars (re_string_t *pstr, Idx new_raw_idx, wint_t *last_wc) + rawbuf_idx < new_raw_idx;) + { + wchar_t wc2; +- Idx remain_len; +- remain_len = pstr->len - rawbuf_idx; ++ Idx remain_len = pstr->raw_len - rawbuf_idx; + prev_st = pstr->cur_state; + mbclen = __mbrtowc (&wc2, (const char *) pstr->raw_mbs + rawbuf_idx, + remain_len, &pstr->cur_state); +@@ -733,21 +735,21 @@ re_string_reconstruct (re_string_t *pstr, Idx idx, int eflags) + mbstate_t cur_state; + wchar_t wc2; + Idx mlen = raw + pstr->len - p; ++ unsigned char buf[6]; + size_t mbclen; + +-#if 0 /* dead code: buf is set but never used */ +- unsigned char buf[6]; ++ const unsigned char *pp = p; + if (BE (pstr->trans != NULL, 0)) + { + int i = mlen < 6 ? mlen : 6; + while (--i >= 0) + buf[i] = pstr->trans[p[i]]; ++ pp = buf; + } +-#endif + /* 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, ++ mbclen = __mbrtowc (&wc2, (const char *) pp, mlen, + &cur_state); + if (raw + offset - p <= mbclen + && mbclen < (size_t) -2) +@@ -832,7 +834,7 @@ re_string_reconstruct (re_string_t *pstr, Idx idx, int eflags) + } + + static unsigned char +-internal_function __attribute ((pure)) ++internal_function __attribute__ ((pure)) + re_string_peek_byte_case (const re_string_t *pstr, Idx idx) + { + int ch; +@@ -869,7 +871,7 @@ re_string_peek_byte_case (const re_string_t *pstr, Idx idx) + } + + static unsigned char +-internal_function __attribute ((pure)) ++internal_function + re_string_fetch_byte_case (re_string_t *pstr) + { + if (BE (!pstr->mbs_allocated, 1)) +@@ -972,7 +974,7 @@ 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)) ++ if (BE (set->elems == NULL, 0) && (MALLOC_0_IS_NONNULL || size != 0)) + return REG_ESPACE; + return REG_NOERROR; + } +@@ -1352,7 +1354,7 @@ re_node_set_insert_last (re_node_set *set, Idx elem) + Return true if SET1 and SET2 are equivalent. */ + + static bool +-internal_function __attribute ((pure)) ++internal_function __attribute__ ((pure)) + re_node_set_compare (const re_node_set *set1, const re_node_set *set2) + { + Idx i; +@@ -1367,7 +1369,7 @@ re_node_set_compare (const re_node_set *set1, const re_node_set *set2) + /* Return (idx + 1) if SET contains the element ELEM, return 0 otherwise. */ + + static Idx +-internal_function __attribute ((pure)) ++internal_function __attribute__ ((pure)) + re_node_set_contains (const re_node_set *set, Idx elem) + { + __re_size_t idx, right, mid; +@@ -1413,13 +1415,12 @@ re_dfa_add_node (re_dfa_t *dfa, re_token_t token) + 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)) ++ /* Avoid overflows in realloc. */ ++ const size_t max_object_size = MAX (sizeof (re_token_t), ++ MAX (sizeof (re_node_set), ++ sizeof (Idx))); ++ if (BE (MIN (IDX_MAX, SIZE_MAX / max_object_size) < new_nodes_alloc, 0)) + return REG_MISSING; + + new_nodes = re_realloc (dfa->nodes, re_token_t, new_nodes_alloc); +@@ -1442,11 +1443,9 @@ re_dfa_add_node (re_dfa_t *dfa, re_token_t token) + 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; +- } ++ ((token.type == OP_PERIOD && dfa->mb_cur_max > 1) ++ || token.type == COMPLEX_BRACKET); + #endif + dfa->nexts[dfa->nodes_len] = REG_MISSING; + re_node_set_init_empty (dfa->edests + dfa->nodes_len); +@@ -1454,7 +1453,7 @@ re_dfa_add_node (re_dfa_t *dfa, re_token_t token) + return dfa->nodes_len++; + } + +-static inline re_hashval_t ++static re_hashval_t + internal_function + calc_state_hash (const re_node_set *nodes, unsigned int context) + { +@@ -1551,7 +1550,7 @@ re_acquire_state_context (reg_errcode_t *err, const re_dfa_t *dfa, + && re_node_set_compare (state->entrance_nodes, nodes)) + return state; + } +- /* There are no appropriate state in `dfa', create the new one. */ ++ /* 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; +@@ -1580,7 +1579,7 @@ register_state (const re_dfa_t *dfa, re_dfastate_t *newstate, + { + 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)) ++ if (! re_node_set_insert_last (&newstate->non_eps_nodes, elem)) + return REG_ESPACE; + } + +@@ -1615,7 +1614,7 @@ free_state (re_dfastate_t *state) + re_free (state); + } + +-/* Create the new state which is independ of contexts. ++/* Create the new state which is independent of contexts. + Return the new state if succeeded, otherwise return NULL. */ + + static re_dfastate_t * +diff --git a/grub-core/gnulib/regex_internal.h b/grub-core/gnulib/regex_internal.h +index e5b6679..c467b29 100644 +--- a/grub-core/gnulib/regex_internal.h ++++ b/grub-core/gnulib/regex_internal.h +@@ -1,43 +1,36 @@ + /* Extended regular expression matching and search library. +- Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free +- Software Foundation, Inc. ++ Copyright (C) 2002-2013 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 3, or (at your option) +- any later version. ++ The GNU C Library 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, ++ The GNU C Library 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. ++ 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. */ ++ You should have received a copy of the GNU General Public ++ License along with the GNU C Library; if not, see ++ . */ + + #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 ++#include + #include + #if defined _LIBC + # include +@@ -67,7 +60,7 @@ + # ifdef _LIBC + # undef gettext + # define gettext(msgid) \ +- INTUSE(__dcgettext) (_libc_intl_domainname, msgid, LC_MESSAGES) ++ __dcgettext (_libc_intl_domainname, msgid, LC_MESSAGES) + # endif + #else + # define gettext(msgid) (msgid) +@@ -79,12 +72,7 @@ + # 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 ++#if (defined MB_CUR_MAX && HAVE_WCTYPE_H && HAVE_ISWCTYPE && HAVE_WCSCOLL) || _LIBC + # define RE_ENABLE_I18N + #endif + +@@ -92,9 +80,6 @@ + # define BE(expr, val) __builtin_expect (expr, val) + #else + # define BE(expr, val) (expr) +-# ifdef _LIBC +-# define inline +-# endif + #endif + + /* Number of ASCII characters. */ +@@ -111,22 +96,27 @@ + + /* Rename to standard API for using out of glibc. */ + #ifndef _LIBC ++# undef __wctype ++# undef __iswctype + # define __wctype wctype + # define __iswctype iswctype + # define __btowc btowc +-# define __wcrtomb wcrtomb + # define __mbrtowc mbrtowc ++# define __wcrtomb wcrtomb + # 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) ++#if __GNUC__ < 3 + (__GNUC_MINOR__ < 1) ++# define __attribute__(arg) + #endif + + typedef __re_idx_t Idx; ++#ifdef _REGEX_LARGE_OFFSETS ++# define IDX_MAX (SIZE_MAX - 2) ++#else ++# define IDX_MAX INT_MAX ++#endif + + /* Special return value for failure to match. */ + #define REG_MISSING ((Idx) -1) +@@ -337,7 +327,7 @@ typedef struct + Idx idx; /* for BACK_REF */ + re_context_type ctx_type; /* for ANCHOR */ + } opr; +-#if __GNUC__ >= 2 && !__STRICT_ANSI__ ++#if __GNUC__ >= 2 && !defined __STRICT_ANSI__ + re_token_type_t type : 8; + #else + re_token_type_t type; +@@ -413,27 +403,29 @@ struct re_string_t + }; + 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 ++# define internal_function + #endif + ++#ifndef NOT_IN_libc + static reg_errcode_t re_string_realloc_buffers (re_string_t *pstr, + Idx new_buf_len) + internal_function; +-#ifdef RE_ENABLE_I18N ++# 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 */ ++ 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)); ++ internal_function __attribute__ ((pure)); ++#endif + #define re_string_peek_byte(pstr, offset) \ + ((pstr)->mbs[(pstr)->cur_idx + offset]) + #define re_string_fetch_byte(pstr) \ +@@ -451,7 +443,9 @@ static unsigned int re_string_context_at (const re_string_t *input, Idx idx, + #define re_string_skip_bytes(pstr,idx) ((pstr)->cur_idx += (idx)) + #define re_string_set_index(pstr,idx) ((pstr)->cur_idx = (idx)) + +-#include ++#if defined _LIBC || HAVE_ALLOCA ++# include ++#endif + + #ifndef _LIBC + # if HAVE_ALLOCA +@@ -468,9 +462,18 @@ static unsigned int re_string_context_at (const re_string_t *input, Idx idx, + # endif + #endif + ++#ifdef _LIBC ++# define MALLOC_0_IS_NONNULL 1 ++#elif !defined MALLOC_0_IS_NONNULL ++# define MALLOC_0_IS_NONNULL 0 ++#endif ++ + #ifndef MAX + # define MAX(a,b) ((a) < (b) ? (b) : (a)) + #endif ++#ifndef MIN ++# define MIN(a,b) ((a) < (b) ? (a) : (b)) ++#endif + + #define re_malloc(t,n) ((t *) malloc ((n) * sizeof (t))) + #define re_realloc(p,t,n) ((t *) realloc (p, (n) * sizeof (t))) +@@ -486,8 +489,8 @@ struct bin_tree_t + + re_token_t token; + +- /* `node_idx' is the index in dfa->nodes, if `type' == 0. +- Otherwise `type' indicate the type of this node. */ ++ /* '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; +@@ -540,9 +543,9 @@ struct re_dfastate_t + struct re_dfastate_t **trtable, **word_trtable; + unsigned int context : 4; + unsigned int halt : 1; +- /* If this state can accept `multi byte'. ++ /* If this state can accept "multi byte". + Note that we refer to multibyte characters, and multi character +- collating elements as `multi byte'. */ ++ collating elements as "multi byte". */ + unsigned int accept_mb : 1; + /* If this state has backreference node(s). */ + unsigned int has_backref : 1; +@@ -671,7 +674,7 @@ struct re_dfa_t + re_bitset_ptr_t sb_char; + int str_tree_storage_idx; + +- /* number of subexpressions `re_nsub' is in regex_t. */ ++ /* 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. */ +@@ -728,33 +731,33 @@ typedef struct + } bracket_elem_t; + + +-/* Inline functions for bitset_t operation. */ ++/* Functions for bitset_t operation. */ + +-static inline void ++static void + bitset_set (bitset_t set, Idx i) + { + set[i / BITSET_WORD_BITS] |= (bitset_word_t) 1 << i % BITSET_WORD_BITS; + } + +-static inline void ++static void + bitset_clear (bitset_t set, Idx i) + { + set[i / BITSET_WORD_BITS] &= ~ ((bitset_word_t) 1 << i % BITSET_WORD_BITS); + } + +-static inline bool ++static bool + bitset_contain (const bitset_t set, Idx i) + { + return (set[i / BITSET_WORD_BITS] >> i % BITSET_WORD_BITS) & 1; + } + +-static inline void ++static void + bitset_empty (bitset_t set) + { + memset (set, '\0', sizeof (bitset_t)); + } + +-static inline void ++static void + bitset_set_all (bitset_t set) + { + memset (set, -1, sizeof (bitset_word_t) * (SBC_MAX / BITSET_WORD_BITS)); +@@ -763,13 +766,13 @@ bitset_set_all (bitset_t set) + ((bitset_word_t) 1 << SBC_MAX % BITSET_WORD_BITS) - 1; + } + +-static inline void ++static void + bitset_copy (bitset_t dest, const bitset_t src) + { + memcpy (dest, src, sizeof (bitset_t)); + } + +-static inline void ++static void __attribute__ ((unused)) + bitset_not (bitset_t set) + { + int bitset_i; +@@ -781,7 +784,7 @@ bitset_not (bitset_t set) + & ~set[BITSET_WORDS - 1]); + } + +-static inline void ++static void __attribute__ ((unused)) + bitset_merge (bitset_t dest, const bitset_t src) + { + int bitset_i; +@@ -789,7 +792,7 @@ bitset_merge (bitset_t dest, const bitset_t src) + dest[bitset_i] |= src[bitset_i]; + } + +-static inline void ++static void __attribute__ ((unused)) + bitset_mask (bitset_t dest, const bitset_t src) + { + int bitset_i; +@@ -798,9 +801,9 @@ bitset_mask (bitset_t dest, const bitset_t src) + } + + #ifdef RE_ENABLE_I18N +-/* Inline functions for re_string. */ +-static inline int +-internal_function __attribute ((pure)) ++/* Functions for re_string. */ ++static int ++internal_function __attribute__ ((pure, unused)) + re_string_char_size_at (const re_string_t *pstr, Idx idx) + { + int byte_idx; +@@ -812,8 +815,8 @@ re_string_char_size_at (const re_string_t *pstr, Idx idx) + return byte_idx; + } + +-static inline wint_t +-internal_function __attribute ((pure)) ++static wint_t ++internal_function __attribute__ ((pure, unused)) + re_string_wchar_at (const re_string_t *pstr, Idx idx) + { + if (pstr->mb_cur_max == 1) +@@ -821,15 +824,15 @@ re_string_wchar_at (const re_string_t *pstr, Idx idx) + return (wint_t) pstr->wcs[idx]; + } + ++# ifndef NOT_IN_libc + static int +-internal_function __attribute ((pure)) ++internal_function __attribute__ ((pure, unused)) + re_string_elem_size_at (const re_string_t *pstr, Idx idx) + { +-# ifdef _LIBC ++# ifdef _LIBC + const unsigned char *p, *extra; + const int32_t *table, *indirect; +- int32_t tmp; +-# include ++# include + uint_fast32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES); + + if (nrules != 0) +@@ -840,13 +843,14 @@ re_string_elem_size_at (const re_string_t *pstr, Idx idx) + indirect = (const int32_t *) _NL_CURRENT (LC_COLLATE, + _NL_COLLATE_INDIRECTMB); + p = pstr->mbs + idx; +- tmp = findidx (&p); ++ findidx (&p, pstr->len - idx); + return p - pstr->mbs - idx; + } + else +-# endif /* _LIBC */ ++# endif /* _LIBC */ + return 1; + } ++# endif + #endif /* RE_ENABLE_I18N */ + + #ifndef __GNUC_PREREQ +diff --git a/grub-core/gnulib/regexec.c b/grub-core/gnulib/regexec.c +index dc449ce..f632cd4 100644 +--- a/grub-core/gnulib/regexec.c ++++ b/grub-core/gnulib/regexec.c +@@ -1,22 +1,21 @@ + /* Extended regular expression matching and search library. +- Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free +- Software Foundation, Inc. ++ Copyright (C) 2002-2013 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 3, or (at your option) +- any later version. ++ The GNU C Library 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, ++ The GNU C Library 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. ++ 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. */ ++ You should have received a copy of the GNU General Public ++ License along with the GNU C Library; if not, see ++ . */ + + static reg_errcode_t match_ctx_init (re_match_context_t *cache, int eflags, + Idx n) internal_function; +@@ -52,9 +51,8 @@ static regoff_t re_search_stub (struct re_pattern_buffer *bufp, + 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 unsigned 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, +@@ -201,7 +199,7 @@ static Idx group_nodes_into_DFAstates (const re_dfa_t *dfa, + 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) ++static reg_errcode_t extend_buffers (re_match_context_t *mctx, int min_len) + internal_function; + + /* Entry point for POSIX code. */ +@@ -210,11 +208,11 @@ static reg_errcode_t extend_buffers (re_match_context_t *mctx) + 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 ++ '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 ++ 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. + +@@ -231,7 +229,7 @@ regexec (preg, string, nmatch, pmatch, eflags) + reg_errcode_t err; + Idx start, length; + #ifdef _LIBC +- re_dfa_t *dfa = (re_dfa_t *) preg->buffer; ++ re_dfa_t *dfa = preg->buffer; + #endif + + if (eflags & ~(REG_NOTBOL | REG_NOTEOL | REG_STARTEND)) +@@ -366,7 +364,6 @@ 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, +@@ -414,7 +411,6 @@ re_search_2_stub (struct re_pattern_buffer *bufp, + 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, +@@ -426,7 +422,7 @@ re_search_stub (struct re_pattern_buffer *bufp, + regoff_t rval; + int eflags = 0; + #ifdef _LIBC +- re_dfa_t *dfa = (re_dfa_t *) bufp->buffer; ++ re_dfa_t *dfa = bufp->buffer; + #endif + Idx last_start = start + range; + +@@ -478,9 +474,9 @@ re_search_stub (struct re_pattern_buffer *bufp, + + rval = 0; + +- /* I hope we needn't fill ther regs with -1's when no match was found. */ ++ /* I hope we needn't fill their regs with -1's when no match was found. */ + if (result != REG_NOERROR) +- rval = -1; ++ rval = result == REG_NOMATCH ? -1 : -2; + else if (regs != NULL) + { + /* If caller wants register contents data back, copy them. */ +@@ -506,15 +502,14 @@ re_search_stub (struct re_pattern_buffer *bufp, + return rval; + } + +-static unsigned int +-internal_function ++static unsigned + 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 ++ /* We need one extra element beyond 'num_regs' for the '-1' marker GNU code + uses. */ + + /* Have the register data arrays been allocated? */ +@@ -637,7 +632,7 @@ re_exec (s) + (0 <= LAST_START && LAST_START <= LENGTH) */ + + static reg_errcode_t +-internal_function __attribute_warn_unused_result__ ++__attribute_warn_unused_result__ + re_search_internal (const regex_t *preg, + const char *string, Idx length, + Idx start, Idx last_start, Idx stop, +@@ -645,7 +640,7 @@ re_search_internal (const regex_t *preg, + int eflags) + { + reg_errcode_t err; +- const re_dfa_t *dfa = (const re_dfa_t *) preg->buffer; ++ const re_dfa_t *dfa = preg->buffer; + Idx left_lim, right_lim; + int incr; + bool fl_longest_match; +@@ -720,7 +715,8 @@ re_search_internal (const regex_t *preg, + if (nmatch > 1 || dfa->has_mb_node) + { + /* Avoid overflow. */ +- if (BE (SIZE_MAX / sizeof (re_dfastate_t *) <= mctx.input.bufs_len, 0)) ++ if (BE ((MIN (IDX_MAX, SIZE_MAX / sizeof (re_dfastate_t *)) ++ <= mctx.input.bufs_len), 0)) + { + err = REG_ESPACE; + goto free_return; +@@ -740,7 +736,7 @@ re_search_internal (const regex_t *preg, + mctx.input.tip_context = (eflags & REG_NOTBOL) ? CONTEXT_BEGBUF + : CONTEXT_NEWLINE | CONTEXT_BEGBUF; + +- /* Check incrementally whether of not the input string match. */ ++ /* Check incrementally whether the input string matches. */ + incr = (last_start < start) ? -1 : 1; + left_lim = (last_start < start) ? last_start : start; + right_lim = (last_start < start) ? start : last_start; +@@ -922,7 +918,7 @@ re_search_internal (const regex_t *preg, + goto free_return; + } + +- /* At last, add the offset to the each registers, since we slided ++ /* At last, add the offset to each register, since we slid + the buffers so that we could assume that the matching starts + from 0. */ + for (reg_idx = 0; reg_idx < nmatch; ++reg_idx) +@@ -972,7 +968,7 @@ re_search_internal (const regex_t *preg, + } + + static reg_errcode_t +-internal_function __attribute_warn_unused_result__ ++__attribute_warn_unused_result__ + prune_impossible_nodes (re_match_context_t *mctx) + { + const re_dfa_t *const dfa = mctx->dfa; +@@ -988,7 +984,7 @@ prune_impossible_nodes (re_match_context_t *mctx) + halt_node = mctx->last_node; + + /* Avoid overflow. */ +- if (BE (SIZE_MAX / sizeof (re_dfastate_t *) <= match_last, 0)) ++ if (BE (MIN (IDX_MAX, SIZE_MAX / sizeof (re_dfastate_t *)) <= match_last, 0)) + return REG_ESPACE; + + sifted_states = re_malloc (re_dfastate_t *, match_last + 1); +@@ -1068,7 +1064,7 @@ prune_impossible_nodes (re_match_context_t *mctx) + since initial states may have constraints like "\<", "^", etc.. */ + + static inline re_dfastate_t * +-__attribute ((always_inline)) internal_function ++__attribute__ ((always_inline)) internal_function + acquire_init_state_context (reg_errcode_t *err, const re_match_context_t *mctx, + Idx idx) + { +@@ -1106,7 +1102,7 @@ acquire_init_state_context (reg_errcode_t *err, const re_match_context_t *mctx, + 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 ++ Note that the matcher assumes that the matching starts from the current + index of the buffer. */ + + static Idx +@@ -1175,11 +1171,12 @@ check_matching (re_match_context_t *mctx, bool fl_longest_match, + 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) ++ if ((BE (next_char_idx >= mctx->input.bufs_len, 0) ++ && mctx->input.bufs_len < mctx->input.len) + || (BE (next_char_idx >= mctx->input.valid_len, 0) + && mctx->input.valid_len < mctx->input.len)) + { +- err = extend_buffers (mctx); ++ err = extend_buffers (mctx, next_char_idx + 1); + if (BE (err != REG_NOERROR, 0)) + { + assert (err == REG_ESPACE); +@@ -1436,7 +1433,7 @@ 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) + { +- const re_dfa_t *dfa = (const re_dfa_t *) preg->buffer; ++ const re_dfa_t *dfa = preg->buffer; + Idx idx, cur_node; + re_node_set eps_via_nodes; + struct re_fail_stack_t *fs; +@@ -1608,21 +1605,21 @@ update_regs (const re_dfa_t *dfa, regmatch_t *pmatch, + 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... ++ 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': ++ 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'. ++ 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'. ++ 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'. ++ node 'a'. + ii. If 'b' is in the STATE_LOG[STR_IDX] but 'b' is thrown away, +- we throw away the node `a'. */ ++ we throw away the node 'a'. */ + + #define STATE_NODE_CONTAINS(state,node) \ + ((state) != NULL && re_node_set_contains (&(state)->nodes, node)) +@@ -1695,11 +1692,11 @@ build_sifted_states (const re_match_context_t *mctx, re_sift_context_t *sctx, + 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'. ++ 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]' ++ '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++) + { +@@ -1712,7 +1709,7 @@ build_sifted_states (const re_match_context_t *mctx, re_sift_context_t *sctx, + assert (!IS_EPSILON_NODE (type)); + #endif + #ifdef RE_ENABLE_I18N +- /* If the node may accept `multi byte'. */ ++ /* 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); +@@ -1753,12 +1750,13 @@ 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 ++ if ((next_state_log_idx >= mctx->input.bufs_len ++ && mctx->input.bufs_len < mctx->input.len) + || (next_state_log_idx >= mctx->input.valid_len + && mctx->input.valid_len < mctx->input.len)) + { + reg_errcode_t err; +- err = extend_buffers (mctx); ++ err = extend_buffers (mctx, next_state_log_idx + 1); + if (BE (err != REG_NOERROR, 0)) + return err; + } +@@ -2268,17 +2266,17 @@ sift_states_iter_mb (const re_match_context_t *mctx, re_sift_context_t *sctx, + { + const re_dfa_t *const dfa = mctx->dfa; + int naccepted; +- /* Check the node can accept `multi byte'. */ ++ /* 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 ++ /* 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'. */ ++ could't accept the current input "multi byte". */ + naccepted = 0; + /* Otherwise, it is sure that the node could accept +- `naccepted' bytes input. */ ++ 'naccepted' bytes input. */ + return naccepted; + } + #endif /* RE_ENABLE_I18N */ +@@ -2457,7 +2455,7 @@ find_recover_state (reg_errcode_t *err, re_match_context_t *mctx) + /* 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. */ ++ corresponding back references. */ + + static reg_errcode_t + internal_function +@@ -2568,7 +2566,7 @@ transit_state_mb (re_match_context_t *mctx, re_dfastate_t *pstate) + if (naccepted == 0) + continue; + +- /* The node can accepts `naccepted' bytes. */ ++ /* 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); +@@ -2620,7 +2618,7 @@ transit_state_bkref (re_match_context_t *mctx, const re_node_set *nodes) + const re_token_t *node = dfa->nodes + node_idx; + re_node_set *new_dest_nodes; + +- /* Check whether `node' is a backreference or not. */ ++ /* Check whether 'node' is a backreference or not. */ + if (node->type != OP_BACK_REF) + continue; + +@@ -2632,14 +2630,14 @@ transit_state_bkref (re_match_context_t *mctx, const re_node_set *nodes) + continue; + } + +- /* `node' is a backreference. ++ /* '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 ++ /* 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); +@@ -2663,7 +2661,7 @@ transit_state_bkref (re_match_context_t *mctx, const re_node_set *nodes) + 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. */ ++ /* Add 'new_dest_node' to state_log. */ + if (dest_state == NULL) + { + mctx->state_log[dest_str_idx] +@@ -2815,7 +2813,7 @@ get_subexp (re_match_context_t *mctx, Idx bkref_node, Idx bkref_str_idx) + if (bkref_str_off >= mctx->input.len) + break; + +- err = extend_buffers (mctx); ++ err = extend_buffers (mctx, bkref_str_off + 1); + if (BE (err != REG_NOERROR, 0)) + return err; + +@@ -2937,9 +2935,12 @@ check_arrival (re_match_context_t *mctx, state_array_t *path, Idx top_node, + { + 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)) ++ Idx incr_alloc = last_str + mctx->max_mb_elem_len + 1; ++ Idx new_alloc; ++ if (BE (IDX_MAX - old_alloc < incr_alloc, 0)) ++ return REG_ESPACE; ++ new_alloc = old_alloc + incr_alloc; ++ if (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)) +@@ -3102,7 +3103,7 @@ check_arrival_add_next_nodes (re_match_context_t *mctx, Idx str_idx, + assert (!IS_EPSILON_NODE (type)); + #endif + #ifdef RE_ENABLE_I18N +- /* If the node may accept `multi byte'. */ ++ /* If the node may accept "multi byte". */ + if (dfa->nodes[cur_node].accept_mb) + { + naccepted = check_node_accept_bytes (dfa, cur_node, &mctx->input, +@@ -3359,7 +3360,7 @@ build_trtable (const re_dfa_t *dfa, re_dfastate_t *state) + bitset_word_t elem, mask; + bool dests_node_malloced = false; + bool dest_states_malloced = false; +- Idx ndests; /* Number of the destination states from `state'. */ ++ 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; +@@ -3373,8 +3374,8 @@ build_trtable (const re_dfa_t *dfa, re_dfastate_t *state) + } *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 ++ 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)); +@@ -3388,20 +3389,23 @@ build_trtable (const re_dfa_t *dfa, re_dfastate_t *state) + dests_node = dests_alloc->dests_node; + dests_ch = dests_alloc->dests_ch; + +- /* Initialize transiton table. */ ++ /* Initialize transition table. */ + state->word_trtable = state->trtable = NULL; + +- /* At first, group all nodes belonging to `state' into several ++ /* 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); ++ /* Return false in case of an error, true otherwise. */ + if (ndests == 0) + { + state->trtable = (re_dfastate_t **) + calloc (sizeof (re_dfastate_t *), SBC_MAX); ++ if (BE (state->trtable == NULL, 0)) ++ return false; + return true; + } + return false; +@@ -3591,13 +3595,13 @@ group_nodes_into_DFAstates (const re_dfa_t *dfa, const re_dfastate_t *state, + reg_errcode_t err; + bool ok; + Idx i, j, k; +- Idx ndests; /* Number of the destinations from `state'. */ ++ 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 all the nodes belonging to 'state', */ + for (i = 0; i < cur_nodes->nelem; ++i) + { + re_token_t *node = &dfa->nodes[cur_nodes->elems[i]]; +@@ -3640,7 +3644,7 @@ group_nodes_into_DFAstates (const re_dfa_t *dfa, const re_dfastate_t *state, + else + continue; + +- /* Check the `accepts' and sift the characters which are not ++ /* Check the 'accepts' and sift the characters which are not + match it the context. */ + if (constraint) + { +@@ -3699,7 +3703,7 @@ group_nodes_into_DFAstates (const re_dfa_t *dfa, const re_dfastate_t *state, + } + } + +- /* Then divide `accepts' into DFA states, or create a new ++ /* 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) + { +@@ -3712,7 +3716,7 @@ group_nodes_into_DFAstates (const re_dfa_t *dfa, const re_dfastate_t *state, + if (type == CHARACTER && !bitset_contain (dests_ch[j], node->opr.c)) + continue; + +- /* Enumerate the intersection set of this state and `accepts'. */ ++ /* 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]; +@@ -3720,7 +3724,7 @@ group_nodes_into_DFAstates (const re_dfa_t *dfa, const re_dfastate_t *state, + if (!has_intersec) + continue; + +- /* Then check if this state is a subset of `accepts'. */ ++ /* Then check if this state is a subset of 'accepts'. */ + not_subset = not_consumed = 0; + for (k = 0; k < BITSET_WORDS; ++k) + { +@@ -3728,8 +3732,8 @@ group_nodes_into_DFAstates (const re_dfa_t *dfa, const re_dfastate_t *state, + 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 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); +@@ -3768,7 +3772,7 @@ group_nodes_into_DFAstates (const re_dfa_t *dfa, const re_dfastate_t *state, + } + + #ifdef RE_ENABLE_I18N +-/* Check how many bytes the node `dfa->nodes[node_idx]' accepts. ++/* 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. + +@@ -3895,7 +3899,6 @@ check_node_accept_bytes (const re_dfa_t *dfa, Idx node_idx, + const int32_t *table, *indirect; + const unsigned char *weights, *extra; + const char *collseqwc; +- int32_t idx; + /* This #include defines a local function! */ + # include + +@@ -3933,6 +3936,7 @@ check_node_accept_bytes (const re_dfa_t *dfa, Idx node_idx, + in_collseq = find_collation_sequence_value (pin, elem_len); + } + /* match with range expression? */ ++ /* FIXME: Implement rational ranges here, too. */ + for (i = 0; i < cset->nranges; ++i) + if (cset->range_starts[i] <= in_collseq + && in_collseq <= cset->range_ends[i]) +@@ -3953,7 +3957,7 @@ 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); +- int32_t idx = findidx (&cp); ++ int32_t idx = findidx (&cp, elem_len); + if (idx > 0) + for (i = 0; i < cset->nequiv_classes; ++i) + { +@@ -3984,18 +3988,9 @@ check_node_accept_bytes (const re_dfa_t *dfa, Idx node_idx, + # 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) ++ if (cset->range_starts[i] <= wc && wc <= cset->range_ends[i]) + { + match_len = char_len; + goto check_node_accept_bytes_match; +@@ -4065,7 +4060,7 @@ find_collation_sequence_value (const unsigned char *mbs, size_t mbs_len) + /* 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); ++ idx = idx + sizeof (uint32_t) * (*(int32_t *) (extra + idx) + 1); + /* If we found the entry, return the sequence value. */ + if (found) + return *(uint32_t *) (extra + idx); +@@ -4133,17 +4128,20 @@ check_node_accept (const re_match_context_t *mctx, const re_token_t *node, + + static reg_errcode_t + internal_function __attribute_warn_unused_result__ +-extend_buffers (re_match_context_t *mctx) ++extend_buffers (re_match_context_t *mctx, int min_len) + { + 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)) ++ if (BE (MIN (IDX_MAX, SIZE_MAX / sizeof (re_dfastate_t *)) / 2 ++ <= pstr->bufs_len, 0)) + return REG_ESPACE; + +- /* Double the lengthes of the buffers. */ +- ret = re_string_realloc_buffers (pstr, pstr->bufs_len * 2); ++ /* Double the lengths of the buffers, but allocate at least MIN_LEN. */ ++ ret = re_string_realloc_buffers (pstr, ++ MAX (min_len, ++ MIN (pstr->len, pstr->bufs_len * 2))); + if (BE (ret != REG_NOERROR, 0)) + return ret; + +@@ -4206,7 +4204,7 @@ match_ctx_init (re_match_context_t *mctx, int eflags, Idx n) + 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)) ++ if (BE (MIN (IDX_MAX, SIZE_MAX / max_object_size) < n, 0)) + return REG_ESPACE; + + mctx->bkref_ents = re_malloc (struct re_backref_cache_entry, n); +diff --git a/grub-core/gnulib/size_max.h b/grub-core/gnulib/size_max.h +index 56d5a9b..5f33124 100644 +--- a/grub-core/gnulib/size_max.h ++++ b/grub-core/gnulib/size_max.h +@@ -1,5 +1,5 @@ + /* size_max.h -- declare SIZE_MAX through system headers +- Copyright (C) 2005-2006, 2009-2010 Free Software Foundation, Inc. ++ Copyright (C) 2005-2006, 2009-2013 Free Software Foundation, Inc. + Written by Simon Josefsson. + + This program is free software; you can redistribute it and/or modify +@@ -13,8 +13,7 @@ + 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. */ ++ along with this program; if not, see . */ + + #ifndef GNULIB_SIZE_MAX_H + #define GNULIB_SIZE_MAX_H +diff --git a/grub-core/gnulib/sleep.c b/grub-core/gnulib/sleep.c +index 213e5bd..4c97d7d 100644 +--- a/grub-core/gnulib/sleep.c ++++ b/grub-core/gnulib/sleep.c +@@ -1,5 +1,5 @@ + /* Pausing execution of the current thread. +- Copyright (C) 2007, 2009, 2010 Free Software Foundation, Inc. ++ Copyright (C) 2007, 2009-2013 Free Software Foundation, Inc. + Written by Bruno Haible , 2007. + + This program is free software: you can redistribute it and/or modify +@@ -35,7 +35,7 @@ sleep (unsigned int seconds) + unsigned int remaining; + + /* Sleep for 1 second many times, because +- 1. Sleep is not interruptiple by Ctrl-C, ++ 1. Sleep is not interruptible by Ctrl-C, + 2. we want to avoid arithmetic overflow while multiplying with 1000. */ + for (remaining = seconds; remaining > 0; remaining--) + Sleep (1000); +@@ -50,13 +50,14 @@ sleep (unsigned int seconds) + /* Guarantee unlimited sleep and a reasonable return value. Cygwin + 1.5.x rejects attempts to sleep more than 49.7 days (2**32 + milliseconds), but uses uninitialized memory which results in a +- garbage answer. */ ++ garbage answer. Similarly, Linux 2.6.9 with glibc 2.3.4 has a too ++ small return value when asked to sleep more than 24.85 days. */ + unsigned int + rpl_sleep (unsigned int seconds) + { + /* This requires int larger than 16 bits. */ +- verify (UINT_MAX / 49 / 24 / 60 / 60); +- const unsigned int limit = 49 * 24 * 60 * 60; ++ verify (UINT_MAX / 24 / 24 / 60 / 60); ++ const unsigned int limit = 24 * 24 * 60 * 60; + while (limit < seconds) + { + unsigned int result; +diff --git a/grub-core/gnulib/stdalign.in.h b/grub-core/gnulib/stdalign.in.h +new file mode 100644 +index 0000000..c3a6732 +--- /dev/null ++++ b/grub-core/gnulib/stdalign.in.h +@@ -0,0 +1,90 @@ ++/* A substitute for ISO C11 . ++ ++ Copyright 2011-2013 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 . */ ++ ++/* Written by Paul Eggert and Bruno Haible. */ ++ ++#ifndef _GL_STDALIGN_H ++#define _GL_STDALIGN_H ++ ++/* ISO C11 for platforms that lack it. ++ ++ References: ++ ISO C11 (latest free draft ++ ) ++ sections 6.5.3.4, 6.7.5, 7.15. ++ C++11 (latest free draft ++ ) ++ section 18.10. */ ++ ++/* alignof (TYPE), also known as _Alignof (TYPE), yields the alignment ++ requirement of a structure member (i.e., slot or field) that is of ++ type TYPE, as an integer constant expression. ++ ++ This differs from GCC's __alignof__ operator, which can yield a ++ better-performing alignment for an object of that type. For ++ example, on x86 with GCC, __alignof__ (double) and __alignof__ ++ (long long) are 8, whereas alignof (double) and alignof (long long) ++ are 4 unless the option '-malign-double' is used. ++ ++ The result cannot be used as a value for an 'enum' constant, if you ++ want to be portable to HP-UX 10.20 cc and AIX 3.2.5 xlc. */ ++#include ++#if defined __cplusplus ++ template struct __alignof_helper { char __a; __t __b; }; ++# define _Alignof(type) offsetof (__alignof_helper, __b) ++#else ++# define _Alignof(type) offsetof (struct { char __a; type __b; }, __b) ++#endif ++#define alignof _Alignof ++#define __alignof_is_defined 1 ++ ++/* alignas (A), also known as _Alignas (A), aligns a variable or type ++ to the alignment A, where A is an integer constant expression. For ++ example: ++ ++ int alignas (8) foo; ++ struct s { int a; int alignas (8) bar; }; ++ ++ aligns the address of FOO and the offset of BAR to be multiples of 8. ++ ++ A should be a power of two that is at least the type's alignment ++ and at most the implementation's alignment limit. This limit is ++ 2**28 on typical GNUish hosts, and 2**13 on MSVC. To be portable ++ to MSVC through at least version 10.0, A should be an integer ++ constant, as MSVC does not support expressions such as 1 << 3. ++ To be portable to Sun C 5.11, do not align auto variables to ++ anything stricter than their default alignment. ++ ++ The following C11 requirements are not supported here: ++ ++ - If A is zero, alignas has no effect. ++ - alignas can be used multiple times; the strictest one wins. ++ - alignas (TYPE) is equivalent to alignas (alignof (TYPE)). ++ ++ */ ++ ++#if __GNUC__ || __IBMC__ || __IBMCPP__ || 0x5110 <= __SUNPRO_C ++# define _Alignas(a) __attribute__ ((__aligned__ (a))) ++#elif 1300 <= _MSC_VER ++# define _Alignas(a) __declspec (align (a)) ++#endif ++#ifdef _Alignas ++# define alignas _Alignas ++# define __alignas_is_defined 1 ++#endif ++ ++#endif /* _GL_STDALIGN_H */ +diff --git a/grub-core/gnulib/stdbool.in.h b/grub-core/gnulib/stdbool.in.h +index 574c281..7c15772 100644 +--- a/grub-core/gnulib/stdbool.in.h ++++ b/grub-core/gnulib/stdbool.in.h +@@ -1,4 +1,4 @@ +-/* Copyright (C) 2001-2003, 2006-2010 Free Software Foundation, Inc. ++/* Copyright (C) 2001-2003, 2006-2013 Free Software Foundation, Inc. + Written by Bruno Haible , 2001. + + This program is free software; you can redistribute it and/or modify +@@ -12,8 +12,7 @@ + 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. */ ++ along with this program; if not, see . */ + + #ifndef _GL_STDBOOL_H + #define _GL_STDBOOL_H +@@ -67,24 +66,19 @@ + # undef true + #endif + +-/* For the sake of symbolic names in gdb, we define true and false as +- enum constants, not only as macros. +- It is tempting to write +- typedef enum { false = 0, true = 1 } _Bool; +- so that gdb prints values of type 'bool' symbolically. But if we do +- this, values of type '_Bool' may promote to 'int' or 'unsigned int' +- (see ISO C 99 6.7.2.2.(4)); however, '_Bool' must promote to 'int' +- (see ISO C 99 6.3.1.1.(2)). So we add a negative value to the +- enum; this ensures that '_Bool' promotes to 'int'. */ +-#if defined __cplusplus || (defined __BEOS__ && !defined __HAIKU__) ++#ifdef __cplusplus ++# define _Bool bool ++# define bool bool ++#else ++# if defined __BEOS__ && !defined __HAIKU__ + /* A compiler known to have 'bool'. */ + /* If the compiler already has both 'bool' and '_Bool', we can assume they + are the same types. */ +-# if !@HAVE__BOOL@ ++# if !@HAVE__BOOL@ + typedef bool _Bool; +-# endif +-#else +-# if !defined __GNUC__ ++# endif ++# else ++# if !defined __GNUC__ + /* If @HAVE__BOOL@: + Some HP-UX cc and AIX IBM C compiler versions have compiler bugs when + the built-in _Bool type is used. See +@@ -104,19 +98,35 @@ typedef bool _Bool; + "Invalid enumerator. (badenum)" with HP-UX cc on Tru64. + The only benefit of the enum, debuggability, is not important + with these compilers. So use 'signed char' and no enum. */ +-# define _Bool signed char +-# else ++# define _Bool signed char ++# else + /* With this compiler, trust the _Bool type if the compiler has it. */ +-# if !@HAVE__BOOL@ ++# if !@HAVE__BOOL@ ++ /* For the sake of symbolic names in gdb, define true and false as ++ enum constants, not only as macros. ++ It is tempting to write ++ typedef enum { false = 0, true = 1 } _Bool; ++ so that gdb prints values of type 'bool' symbolically. But then ++ values of type '_Bool' might promote to 'int' or 'unsigned int' ++ (see ISO C 99 6.7.2.2.(4)); however, '_Bool' must promote to 'int' ++ (see ISO C 99 6.3.1.1.(2)). So add a negative value to the ++ enum; this ensures that '_Bool' promotes to 'int'. */ + typedef enum { _Bool_must_promote_to_int = -1, false = 0, true = 1 } _Bool; ++# endif + # endif + # endif ++# define bool _Bool + #endif +-#define bool _Bool + + /* The other macros must be usable in preprocessor directives. */ +-#define false 0 +-#define true 1 ++#ifdef __cplusplus ++# define false false ++# define true true ++#else ++# define false 0 ++# define true 1 ++#endif ++ + #define __bool_true_false_are_defined 1 + + #endif /* _GL_STDBOOL_H */ +diff --git a/grub-core/gnulib/stddef.in.h b/grub-core/gnulib/stddef.in.h +index 08778a2..40f0536 100644 +--- a/grub-core/gnulib/stddef.in.h ++++ b/grub-core/gnulib/stddef.in.h +@@ -1,6 +1,6 @@ + /* A substitute for POSIX 2008 , for platforms that have issues. + +- Copyright (C) 2009, 2010 Free Software Foundation, Inc. ++ Copyright (C) 2009-2013 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 +@@ -13,8 +13,7 @@ + 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. */ ++ along with this program; if not, see . */ + + /* Written by Eric Blake. */ + +@@ -26,6 +25,7 @@ + #if __GNUC__ >= 3 + @PRAGMA_SYSTEM_HEADER@ + #endif ++@PRAGMA_COLUMNS@ + + #if defined __need_wchar_t || defined __need_size_t \ + || defined __need_ptrdiff_t || defined __need_NULL \ +@@ -37,9 +37,9 @@ + remember if special invocation has ever been used to obtain wint_t, + in which case we need to clean up NULL yet again. */ + +-# if !(defined _GL_STDDEF_H && defined _GL_STDDEF_WINT_T) ++# if !(defined _@GUARD_PREFIX@_STDDEF_H && defined _GL_STDDEF_WINT_T) + # ifdef __need_wint_t +-# undef _GL_STDDEF_H ++# undef _@GUARD_PREFIX@_STDDEF_H + # define _GL_STDDEF_WINT_T + # endif + # @INCLUDE_NEXT@ @NEXT_STDDEF_H@ +@@ -48,14 +48,14 @@ + #else + /* Normal invocation convention. */ + +-# ifndef _GL_STDDEF_H ++# ifndef _@GUARD_PREFIX@_STDDEF_H + + /* The include_next requires a split double-inclusion guard. */ + + # @INCLUDE_NEXT@ @NEXT_STDDEF_H@ + +-# ifndef _GL_STDDEF_H +-# define _GL_STDDEF_H ++# ifndef _@GUARD_PREFIX@_STDDEF_H ++# define _@GUARD_PREFIX@_STDDEF_H + + /* On NetBSD 5.0, the definition of NULL lacks proper parentheses. */ + #if @REPLACE_NULL@ +@@ -81,6 +81,6 @@ + # define wchar_t int + #endif + +-# endif /* _GL_STDDEF_H */ +-# endif /* _GL_STDDEF_H */ ++# endif /* _@GUARD_PREFIX@_STDDEF_H */ ++# endif /* _@GUARD_PREFIX@_STDDEF_H */ + #endif /* __need_XXX */ +diff --git a/grub-core/gnulib/stdint.in.h b/grub-core/gnulib/stdint.in.h +index 5da5f17..2db8b2e 100644 +--- a/grub-core/gnulib/stdint.in.h ++++ b/grub-core/gnulib/stdint.in.h +@@ -1,4 +1,4 @@ +-/* Copyright (C) 2001-2002, 2004-2010 Free Software Foundation, Inc. ++/* Copyright (C) 2001-2002, 2004-2013 Free Software Foundation, Inc. + Written by Paul Eggert, Bruno Haible, Sam Steingold, Peter Burwood. + This file is part of gnulib. + +@@ -13,19 +13,19 @@ + 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. */ ++ along with this program; if not, see . */ + + /* + * ISO C 99 for platforms that lack it. + * + */ + +-#ifndef _GL_STDINT_H ++#ifndef _@GUARD_PREFIX@_STDINT_H + + #if __GNUC__ >= 3 + @PRAGMA_SYSTEM_HEADER@ + #endif ++@PRAGMA_COLUMNS@ + + /* When including a system file that in turn includes , + use the system , not our substitute. This avoids +@@ -33,6 +33,16 @@ + . */ + #define _GL_JUST_INCLUDE_SYSTEM_INTTYPES_H + ++/* On Android (Bionic libc), includes this file before ++ having defined 'time_t'. Therefore in this case avoid including ++ other system header files; just include the system's . ++ Ideally we should test __BIONIC__ here, but it is only defined after ++ has been included; hence test __ANDROID__ instead. */ ++#if defined __ANDROID__ \ ++ && defined _SYS_TYPES_H_ && !defined __need_size_t ++# @INCLUDE_NEXT@ @NEXT_STDINT_H@ ++#else ++ + /* Get those types that are already defined in other system include + files, so that we can "#define int8_t signed char" below without + worrying about a later system include file containing a "typedef +@@ -48,28 +58,40 @@ + diagnostics. */ + # define __STDINT_H__ + # endif ++ ++ /* Some pre-C++11 implementations need this. */ ++# ifdef __cplusplus ++# ifndef __STDC_CONSTANT_MACROS ++# define __STDC_CONSTANT_MACROS 1 ++# endif ++# ifndef __STDC_LIMIT_MACROS ++# define __STDC_LIMIT_MACROS 1 ++# endif ++# endif ++ + /* Other systems may have an incomplete or buggy . + Include it before , since any "#include " + in would reinclude us, skipping our contents because +- _GL_STDINT_H is defined. ++ _@GUARD_PREFIX@_STDINT_H is defined. + The include_next requires a split double-inclusion guard. */ + # @INCLUDE_NEXT@ @NEXT_STDINT_H@ + #endif + +-#if ! defined _GL_STDINT_H && ! defined _GL_JUST_INCLUDE_SYSTEM_STDINT_H +-#define _GL_STDINT_H ++#if ! defined _@GUARD_PREFIX@_STDINT_H && ! defined _GL_JUST_INCLUDE_SYSTEM_STDINT_H ++#define _@GUARD_PREFIX@_STDINT_H + + /* defines some of the stdint.h types as well, on glibc, + IRIX 6.5, and OpenBSD 3.8 (via ). + AIX 5.2 isn't needed and causes troubles. +- MacOS X 10.4.6 includes (which is us), but ++ Mac OS X 10.4.6 includes (which is us), but + relies on the system definitions, so include + after @NEXT_STDINT_H@. */ + #if @HAVE_SYS_TYPES_H@ && ! defined _AIX + # include + #endif + +-/* Get LONG_MIN, LONG_MAX, ULONG_MAX. */ ++/* Get SCHAR_MIN, SCHAR_MAX, UCHAR_MAX, INT_MIN, INT_MAX, ++ LONG_MIN, LONG_MAX, ULONG_MAX. */ + #include + + #if @HAVE_INTTYPES_H@ +@@ -92,7 +114,7 @@ + + #undef _GL_JUST_INCLUDE_SYSTEM_INTTYPES_H + +-/* Minimum and maximum values for a integer type under the usual assumption. ++/* Minimum and maximum values for an integer type under the usual assumption. + Return an unspecified value if BITS == 0, adding a check to pacify + picky compilers. */ + +@@ -107,6 +129,8 @@ + warnings in the signed case. */ \ + ((((zero) + 1) << ((bits) ? (bits) - 1 - (signed) : 0)) - 1) * 2 + 1) + ++#if !GNULIB_defined_stdint_types ++ + /* 7.18.1.1. Exact-width integer types */ + + /* Here we assume a standard architecture where the hardware integer +@@ -133,40 +157,54 @@ typedef unsigned int gl_uint32_t; + #define int32_t gl_int32_t + #define uint32_t gl_uint32_t + ++/* If the system defines INT64_MAX, assume int64_t works. That way, ++ if the underlying platform defines int64_t to be a 64-bit long long ++ int, the code below won't mistakenly define it to be a 64-bit long ++ int, which would mess up C++ name mangling. We must use #ifdef ++ rather than #if, to avoid an error with HP-UX 10.20 cc. */ ++ ++#ifdef INT64_MAX ++# define GL_INT64_T ++#else + /* Do not undefine int64_t if gnulib is not being used with 64-bit + types, since otherwise it breaks platforms like Tandem/NSK. */ +-#if LONG_MAX >> 31 >> 31 == 1 +-# undef int64_t ++# if LONG_MAX >> 31 >> 31 == 1 ++# undef int64_t + typedef long int gl_int64_t; +-# define int64_t gl_int64_t +-# define GL_INT64_T +-#elif defined _MSC_VER +-# undef int64_t ++# define int64_t gl_int64_t ++# define GL_INT64_T ++# elif defined _MSC_VER ++# undef int64_t + typedef __int64 gl_int64_t; +-# define int64_t gl_int64_t +-# define GL_INT64_T +-#elif @HAVE_LONG_LONG_INT@ +-# undef int64_t ++# define int64_t gl_int64_t ++# define GL_INT64_T ++# elif @HAVE_LONG_LONG_INT@ ++# undef int64_t + typedef long long int gl_int64_t; +-# define int64_t gl_int64_t +-# define GL_INT64_T ++# define int64_t gl_int64_t ++# define GL_INT64_T ++# endif + #endif + +-#if ULONG_MAX >> 31 >> 31 >> 1 == 1 +-# undef uint64_t +-typedef unsigned long int gl_uint64_t; +-# define uint64_t gl_uint64_t ++#ifdef UINT64_MAX + # define GL_UINT64_T +-#elif defined _MSC_VER +-# undef uint64_t ++#else ++# if ULONG_MAX >> 31 >> 31 >> 1 == 1 ++# undef uint64_t ++typedef unsigned long int gl_uint64_t; ++# define uint64_t gl_uint64_t ++# define GL_UINT64_T ++# elif defined _MSC_VER ++# undef uint64_t + typedef unsigned __int64 gl_uint64_t; +-# define uint64_t gl_uint64_t +-# define GL_UINT64_T +-#elif @HAVE_UNSIGNED_LONG_LONG_INT@ +-# undef uint64_t ++# define uint64_t gl_uint64_t ++# define GL_UINT64_T ++# elif @HAVE_UNSIGNED_LONG_LONG_INT@ ++# undef uint64_t + typedef unsigned long long int gl_uint64_t; +-# define uint64_t gl_uint64_t +-# define GL_UINT64_T ++# define uint64_t gl_uint64_t ++# define GL_UINT64_T ++# endif + #endif + + /* Avoid collision with Solaris 2.5.1 etc. */ +@@ -209,8 +247,9 @@ typedef unsigned long long int gl_uint64_t; + + /* Here we assume a standard architecture where the hardware integer + types have 8, 16, 32, optionally 64 bits. Therefore the fastN_t types +- are taken from the same list of types. Assume that 'long int' +- is fast enough for all narrower integers. */ ++ are taken from the same list of types. The following code normally ++ uses types consistent with glibc, as that lessens the chance of ++ incompatibility with older GNU hosts. */ + + #undef int_fast8_t + #undef uint_fast8_t +@@ -220,12 +259,21 @@ typedef unsigned long long int gl_uint64_t; + #undef uint_fast32_t + #undef int_fast64_t + #undef uint_fast64_t +-typedef long int gl_int_fast8_t; +-typedef unsigned long int gl_uint_fast8_t; +-typedef long int gl_int_fast16_t; +-typedef unsigned long int gl_uint_fast16_t; ++typedef signed char gl_int_fast8_t; ++typedef unsigned char gl_uint_fast8_t; ++ ++#ifdef __sun ++/* Define types compatible with SunOS 5.10, so that code compiled under ++ earlier SunOS versions works with code compiled under SunOS 5.10. */ ++typedef int gl_int_fast32_t; ++typedef unsigned int gl_uint_fast32_t; ++#else + typedef long int gl_int_fast32_t; + typedef unsigned long int gl_uint_fast32_t; ++#endif ++typedef gl_int_fast32_t gl_int_fast16_t; ++typedef gl_uint_fast32_t gl_uint_fast16_t; ++ + #define int_fast8_t gl_int_fast8_t + #define uint_fast8_t gl_uint_fast8_t + #define int_fast16_t gl_int_fast16_t +@@ -253,36 +301,48 @@ typedef unsigned long int gl_uintptr_t; + /* Note: These types are compiler dependent. It may be unwise to use them in + public header files. */ + +-#undef intmax_t +-#if @HAVE_LONG_LONG_INT@ && LONG_MAX >> 30 == 1 ++/* If the system defines INTMAX_MAX, assume that intmax_t works, and ++ similarly for UINTMAX_MAX and uintmax_t. This avoids problems with ++ assuming one type where another is used by the system. */ ++ ++#ifndef INTMAX_MAX ++# undef INTMAX_C ++# undef intmax_t ++# if @HAVE_LONG_LONG_INT@ && LONG_MAX >> 30 == 1 + typedef long long int gl_intmax_t; +-# define intmax_t gl_intmax_t +-#elif defined GL_INT64_T +-# define intmax_t int64_t +-#else ++# define intmax_t gl_intmax_t ++# elif defined GL_INT64_T ++# define intmax_t int64_t ++# else + typedef long int gl_intmax_t; +-# define intmax_t gl_intmax_t ++# define intmax_t gl_intmax_t ++# endif + #endif + +-#undef uintmax_t +-#if @HAVE_UNSIGNED_LONG_LONG_INT@ && ULONG_MAX >> 31 == 1 ++#ifndef UINTMAX_MAX ++# undef UINTMAX_C ++# undef uintmax_t ++# if @HAVE_UNSIGNED_LONG_LONG_INT@ && ULONG_MAX >> 31 == 1 + typedef unsigned long long int gl_uintmax_t; +-# define uintmax_t gl_uintmax_t +-#elif defined GL_UINT64_T +-# define uintmax_t uint64_t +-#else ++# define uintmax_t gl_uintmax_t ++# elif defined GL_UINT64_T ++# define uintmax_t uint64_t ++# else + typedef unsigned long int gl_uintmax_t; +-# define uintmax_t gl_uintmax_t ++# define uintmax_t gl_uintmax_t ++# endif + #endif + + /* Verify that intmax_t and uintmax_t have the same size. Too much code + breaks if this is not the case. If this check fails, the reason is likely + to be found in the autoconf macros. */ +-typedef int _verify_intmax_size[2 * (sizeof (intmax_t) == sizeof (uintmax_t)) - 1]; ++typedef int _verify_intmax_size[sizeof (intmax_t) == sizeof (uintmax_t) ++ ? 1 : -1]; + +-/* 7.18.2. Limits of specified-width integer types */ ++#define GNULIB_defined_stdint_types 1 ++#endif /* !GNULIB_defined_stdint_types */ + +-#if ! defined __cplusplus || defined __STDC_LIMIT_MACROS ++/* 7.18.2. Limits of specified-width integer types */ + + /* 7.18.2.1. Limits of exact-width integer types */ + +@@ -310,17 +370,14 @@ typedef int _verify_intmax_size[2 * (sizeof (intmax_t) == sizeof (uintmax_t)) - + #define INT32_MAX 2147483647 + #define UINT32_MAX 4294967295U + +-#undef INT64_MIN +-#undef INT64_MAX +-#ifdef GL_INT64_T ++#if defined GL_INT64_T && ! defined INT64_MAX + /* Prefer (- INTMAX_C (1) << 63) over (~ INT64_MAX) because SunPRO C 5.0 + evaluates the latter incorrectly in preprocessor expressions. */ + # define INT64_MIN (- INTMAX_C (1) << 63) + # define INT64_MAX INTMAX_C (9223372036854775807) + #endif + +-#undef UINT64_MAX +-#ifdef GL_UINT64_T ++#if defined GL_UINT64_T && ! defined UINT64_MAX + # define UINT64_MAX UINTMAX_C (18446744073709551615) + #endif + +@@ -372,23 +429,29 @@ typedef int _verify_intmax_size[2 * (sizeof (intmax_t) == sizeof (uintmax_t)) - + #undef INT_FAST8_MIN + #undef INT_FAST8_MAX + #undef UINT_FAST8_MAX +-#define INT_FAST8_MIN LONG_MIN +-#define INT_FAST8_MAX LONG_MAX +-#define UINT_FAST8_MAX ULONG_MAX ++#define INT_FAST8_MIN SCHAR_MIN ++#define INT_FAST8_MAX SCHAR_MAX ++#define UINT_FAST8_MAX UCHAR_MAX + + #undef INT_FAST16_MIN + #undef INT_FAST16_MAX + #undef UINT_FAST16_MAX +-#define INT_FAST16_MIN LONG_MIN +-#define INT_FAST16_MAX LONG_MAX +-#define UINT_FAST16_MAX ULONG_MAX ++#define INT_FAST16_MIN INT_FAST32_MIN ++#define INT_FAST16_MAX INT_FAST32_MAX ++#define UINT_FAST16_MAX UINT_FAST32_MAX + + #undef INT_FAST32_MIN + #undef INT_FAST32_MAX + #undef UINT_FAST32_MAX +-#define INT_FAST32_MIN LONG_MIN +-#define INT_FAST32_MAX LONG_MAX +-#define UINT_FAST32_MAX ULONG_MAX ++#ifdef __sun ++# define INT_FAST32_MIN INT_MIN ++# define INT_FAST32_MAX INT_MAX ++# define UINT_FAST32_MAX UINT_MAX ++#else ++# define INT_FAST32_MIN LONG_MIN ++# define INT_FAST32_MAX LONG_MAX ++# define UINT_FAST32_MAX ULONG_MAX ++#endif + + #undef INT_FAST64_MIN + #undef INT_FAST64_MAX +@@ -413,21 +476,23 @@ typedef int _verify_intmax_size[2 * (sizeof (intmax_t) == sizeof (uintmax_t)) - + + /* 7.18.2.5. Limits of greatest-width integer types */ + +-#undef INTMAX_MIN +-#undef INTMAX_MAX +-#ifdef INT64_MAX +-# define INTMAX_MIN INT64_MIN +-# define INTMAX_MAX INT64_MAX +-#else +-# define INTMAX_MIN INT32_MIN +-# define INTMAX_MAX INT32_MAX ++#ifndef INTMAX_MAX ++# undef INTMAX_MIN ++# ifdef INT64_MAX ++# define INTMAX_MIN INT64_MIN ++# define INTMAX_MAX INT64_MAX ++# else ++# define INTMAX_MIN INT32_MIN ++# define INTMAX_MAX INT32_MAX ++# endif + #endif + +-#undef UINTMAX_MAX +-#ifdef UINT64_MAX +-# define UINTMAX_MAX UINT64_MAX +-#else +-# define UINTMAX_MAX UINT32_MAX ++#ifndef UINTMAX_MAX ++# ifdef UINT64_MAX ++# define UINTMAX_MAX UINT64_MAX ++# else ++# define UINTMAX_MAX UINT32_MAX ++# endif + #endif + + /* 7.18.3. Limits of other integer types */ +@@ -475,10 +540,16 @@ typedef int _verify_intmax_size[2 * (sizeof (intmax_t) == sizeof (uintmax_t)) - + + /* wchar_t limits */ + /* Get WCHAR_MIN, WCHAR_MAX. +- This include is not on the top, above, because on OSF/1 4.0 we have a sequence of nested +- includes -> -> -> , and the latter includes ++ This include is not on the top, above, because on OSF/1 4.0 we have a ++ sequence of nested includes ++ -> -> -> , and the latter includes + and assumes its types are already defined. */ +-#if ! (defined WCHAR_MIN && defined WCHAR_MAX) ++#if @HAVE_WCHAR_H@ && ! (defined WCHAR_MIN && defined WCHAR_MAX) ++ /* BSD/OS 4.0.1 has a bug: , and must be ++ included before . */ ++# include ++# include ++# include + # define _GL_JUST_INCLUDE_SYSTEM_WCHAR_H + # include + # undef _GL_JUST_INCLUDE_SYSTEM_WCHAR_H +@@ -498,12 +569,8 @@ typedef int _verify_intmax_size[2 * (sizeof (intmax_t) == sizeof (uintmax_t)) - + #define WINT_MAX \ + _STDINT_MAX (@HAVE_SIGNED_WINT_T@, @BITSIZEOF_WINT_T@, 0@WINT_T_SUFFIX@) + +-#endif /* !defined __cplusplus || defined __STDC_LIMIT_MACROS */ +- + /* 7.18.4. Macros for integer constants */ + +-#if ! defined __cplusplus || defined __STDC_CONSTANT_MACROS +- + /* 7.18.4.1. Macros for minimum-width integer constants */ + /* According to ISO C 99 Technical Corrigendum 1 */ + +@@ -544,25 +611,26 @@ typedef int _verify_intmax_size[2 * (sizeof (intmax_t) == sizeof (uintmax_t)) - + + /* 7.18.4.2. Macros for greatest-width integer constants */ + +-#undef INTMAX_C +-#if @HAVE_LONG_LONG_INT@ && LONG_MAX >> 30 == 1 +-# define INTMAX_C(x) x##LL +-#elif defined GL_INT64_T +-# define INTMAX_C(x) INT64_C(x) +-#else +-# define INTMAX_C(x) x##L ++#ifndef INTMAX_C ++# if @HAVE_LONG_LONG_INT@ && LONG_MAX >> 30 == 1 ++# define INTMAX_C(x) x##LL ++# elif defined GL_INT64_T ++# define INTMAX_C(x) INT64_C(x) ++# else ++# define INTMAX_C(x) x##L ++# endif + #endif + +-#undef UINTMAX_C +-#if @HAVE_UNSIGNED_LONG_LONG_INT@ && ULONG_MAX >> 31 == 1 +-# define UINTMAX_C(x) x##ULL +-#elif defined GL_UINT64_T +-# define UINTMAX_C(x) UINT64_C(x) +-#else +-# define UINTMAX_C(x) x##UL ++#ifndef UINTMAX_C ++# if @HAVE_UNSIGNED_LONG_LONG_INT@ && ULONG_MAX >> 31 == 1 ++# define UINTMAX_C(x) x##ULL ++# elif defined GL_UINT64_T ++# define UINTMAX_C(x) UINT64_C(x) ++# else ++# define UINTMAX_C(x) x##UL ++# endif + #endif + +-#endif /* !defined __cplusplus || defined __STDC_CONSTANT_MACROS */ +- +-#endif /* _GL_STDINT_H */ +-#endif /* !defined _GL_STDINT_H && !defined _GL_JUST_INCLUDE_SYSTEM_STDINT_H */ ++#endif /* _@GUARD_PREFIX@_STDINT_H */ ++#endif /* !(defined __ANDROID__ && ...) */ ++#endif /* !defined _@GUARD_PREFIX@_STDINT_H && !defined _GL_JUST_INCLUDE_SYSTEM_STDINT_H */ +diff --git a/grub-core/gnulib/stdio-write.c b/grub-core/gnulib/stdio-write.c +deleted file mode 100644 +index a6a0eb1..0000000 +--- a/grub-core/gnulib/stdio-write.c ++++ /dev/null +@@ -1,148 +0,0 @@ +-/* POSIX compatible FILE stream write function. +- Copyright (C) 2008-2010 Free Software Foundation, Inc. +- Written by Bruno Haible , 2008. +- +- 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 +- +-/* Specification. */ +-#include +- +-/* Replace these functions only if module 'sigpipe' is requested. */ +-#if GNULIB_SIGPIPE +- +-/* On native Windows platforms, SIGPIPE does not exist. When write() is +- called on a pipe with no readers, WriteFile() fails with error +- GetLastError() = ERROR_NO_DATA, and write() in consequence fails with +- error EINVAL. This write() function is at the basis of the function +- which flushes the buffer of a FILE stream. */ +- +-# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ +- +-# include +-# include +-# include +- +-# define WIN32_LEAN_AND_MEAN /* avoid including junk */ +-# include +- +-# define CALL_WITH_SIGPIPE_EMULATION(RETTYPE, EXPRESSION, FAILED) \ +- if (ferror (stream)) \ +- return (EXPRESSION); \ +- else \ +- { \ +- RETTYPE ret; \ +- SetLastError (0); \ +- ret = (EXPRESSION); \ +- if (FAILED && GetLastError () == ERROR_NO_DATA && ferror (stream)) \ +- { \ +- int fd = fileno (stream); \ +- if (fd >= 0 \ +- && GetFileType ((HANDLE) _get_osfhandle (fd)) == FILE_TYPE_PIPE)\ +- { \ +- /* Try to raise signal SIGPIPE. */ \ +- raise (SIGPIPE); \ +- /* If it is currently blocked or ignored, change errno from \ +- EINVAL to EPIPE. */ \ +- errno = EPIPE; \ +- } \ +- } \ +- return ret; \ +- } +- +-# if !REPLACE_PRINTF_POSIX /* avoid collision with printf.c */ +-int +-printf (const char *format, ...) +-{ +- int retval; +- va_list args; +- +- va_start (args, format); +- retval = vfprintf (stdout, format, args); +- va_end (args); +- +- return retval; +-} +-# endif +- +-# if !REPLACE_FPRINTF_POSIX /* avoid collision with fprintf.c */ +-int +-fprintf (FILE *stream, const char *format, ...) +-{ +- int retval; +- va_list args; +- +- va_start (args, format); +- retval = vfprintf (stream, format, args); +- va_end (args); +- +- return retval; +-} +-# endif +- +-# if !REPLACE_VPRINTF_POSIX /* avoid collision with vprintf.c */ +-int +-vprintf (const char *format, va_list args) +-{ +- return vfprintf (stdout, format, args); +-} +-# endif +- +-# if !REPLACE_VFPRINTF_POSIX /* avoid collision with vfprintf.c */ +-int +-vfprintf (FILE *stream, const char *format, va_list args) +-#undef vfprintf +-{ +- CALL_WITH_SIGPIPE_EMULATION (int, vfprintf (stream, format, args), ret == EOF) +-} +-# endif +- +-int +-putchar (int c) +-{ +- return fputc (c, stdout); +-} +- +-int +-fputc (int c, FILE *stream) +-#undef fputc +-{ +- CALL_WITH_SIGPIPE_EMULATION (int, fputc (c, stream), ret == EOF) +-} +- +-int +-fputs (const char *string, FILE *stream) +-#undef fputs +-{ +- CALL_WITH_SIGPIPE_EMULATION (int, fputs (string, stream), ret == EOF) +-} +- +-int +-puts (const char *string) +-#undef puts +-{ +- FILE *stream = stdout; +- CALL_WITH_SIGPIPE_EMULATION (int, puts (string), ret == EOF) +-} +- +-size_t +-fwrite (const void *ptr, size_t s, size_t n, FILE *stream) +-#undef fwrite +-{ +- CALL_WITH_SIGPIPE_EMULATION (size_t, fwrite (ptr, s, n, stream), ret < n) +-} +- +-# endif +-#endif +diff --git a/grub-core/gnulib/stdio.in.h b/grub-core/gnulib/stdio.in.h +index a8b00c6..e1d28ce 100644 +--- a/grub-core/gnulib/stdio.in.h ++++ b/grub-core/gnulib/stdio.in.h +@@ -1,6 +1,6 @@ + /* A GNU-like . + +- Copyright (C) 2004, 2007-2010 Free Software Foundation, Inc. ++ Copyright (C) 2004, 2007-2013 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 +@@ -13,47 +13,104 @@ + 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. */ ++ along with this program; if not, see . */ + + #if __GNUC__ >= 3 + @PRAGMA_SYSTEM_HEADER@ + #endif ++@PRAGMA_COLUMNS@ + +-#if defined __need_FILE || defined __need___FILE +-/* Special invocation convention inside glibc header files. */ ++#if defined __need_FILE || defined __need___FILE || defined _GL_ALREADY_INCLUDING_STDIO_H ++/* Special invocation convention: ++ - Inside glibc header files. ++ - On OSF/1 5.1 we have a sequence of nested includes ++ -> -> -> -> ++ -> -> -> . ++ In this situation, the functions are not yet declared, therefore we cannot ++ provide the C++ aliases. */ + + #@INCLUDE_NEXT@ @NEXT_STDIO_H@ + + #else + /* Normal invocation convention. */ + +-#ifndef _GL_STDIO_H ++#ifndef _@GUARD_PREFIX@_STDIO_H ++ ++#define _GL_ALREADY_INCLUDING_STDIO_H + + /* The include_next requires a split double-inclusion guard. */ + #@INCLUDE_NEXT@ @NEXT_STDIO_H@ + +-#ifndef _GL_STDIO_H +-#define _GL_STDIO_H ++#undef _GL_ALREADY_INCLUDING_STDIO_H ++ ++#ifndef _@GUARD_PREFIX@_STDIO_H ++#define _@GUARD_PREFIX@_STDIO_H + + /* Get va_list. Needed on many systems, including glibc 2.8. */ + #include + + #include + +-/* Get off_t and ssize_t. Needed on many systems, including glibc 2.8. */ ++/* Get off_t and ssize_t. Needed on many systems, including glibc 2.8 ++ and eglibc 2.11.2. ++ May also define off_t to a 64-bit type on native Windows. */ + #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 ++ We enable _GL_ATTRIBUTE_FORMAT 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 ++#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7) ++# define _GL_ATTRIBUTE_FORMAT(spec) __attribute__ ((__format__ spec)) ++#else ++# define _GL_ATTRIBUTE_FORMAT(spec) /* empty */ ++#endif ++ ++/* _GL_ATTRIBUTE_FORMAT_PRINTF ++ indicates to GCC that the function takes a format string and arguments, ++ where the format string directives are the ones standardized by ISO C99 ++ and POSIX. */ ++#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) ++# define _GL_ATTRIBUTE_FORMAT_PRINTF(formatstring_parameter, first_argument) \ ++ _GL_ATTRIBUTE_FORMAT ((__gnu_printf__, formatstring_parameter, first_argument)) ++#else ++# define _GL_ATTRIBUTE_FORMAT_PRINTF(formatstring_parameter, first_argument) \ ++ _GL_ATTRIBUTE_FORMAT ((__printf__, formatstring_parameter, first_argument)) ++#endif ++ ++/* _GL_ATTRIBUTE_FORMAT_PRINTF_SYSTEM is like _GL_ATTRIBUTE_FORMAT_PRINTF, ++ except that it indicates to GCC that the supported format string directives ++ are the ones of the system printf(), rather than the ones standardized by ++ ISO C99 and POSIX. */ ++#define _GL_ATTRIBUTE_FORMAT_PRINTF_SYSTEM(formatstring_parameter, first_argument) \ ++ _GL_ATTRIBUTE_FORMAT ((__printf__, formatstring_parameter, first_argument)) ++ ++/* _GL_ATTRIBUTE_FORMAT_SCANF ++ indicates to GCC that the function takes a format string and arguments, ++ where the format string directives are the ones standardized by ISO C99 ++ and POSIX. */ ++#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) ++# define _GL_ATTRIBUTE_FORMAT_SCANF(formatstring_parameter, first_argument) \ ++ _GL_ATTRIBUTE_FORMAT ((__gnu_scanf__, formatstring_parameter, first_argument)) ++#else ++# define _GL_ATTRIBUTE_FORMAT_SCANF(formatstring_parameter, first_argument) \ ++ _GL_ATTRIBUTE_FORMAT ((__scanf__, formatstring_parameter, first_argument)) ++#endif ++ ++/* _GL_ATTRIBUTE_FORMAT_SCANF_SYSTEM is like _GL_ATTRIBUTE_FORMAT_SCANF, ++ except that it indicates to GCC that the supported format string directives ++ are the ones of the system scanf(), rather than the ones standardized by ++ ISO C99 and POSIX. */ ++#define _GL_ATTRIBUTE_FORMAT_SCANF_SYSTEM(formatstring_parameter, first_argument) \ ++ _GL_ATTRIBUTE_FORMAT ((__scanf__, formatstring_parameter, first_argument)) ++ ++/* Solaris 10 declares renameat in , not in . */ ++/* But in any case avoid namespace pollution on glibc systems. */ ++#if (@GNULIB_RENAMEAT@ || defined GNULIB_POSIXCHECK) && defined __sun \ ++ && ! defined __GLIBC__ ++# include + #endif + + +@@ -74,13 +131,13 @@ + # define dprintf rpl_dprintf + # endif + _GL_FUNCDECL_RPL (dprintf, int, (int fd, const char *format, ...) +- __attribute__ ((__format__ (__printf__, 2, 3))) ++ _GL_ATTRIBUTE_FORMAT_PRINTF (2, 3) + _GL_ARG_NONNULL ((2))); + _GL_CXXALIAS_RPL (dprintf, int, (int fd, const char *format, ...)); + # else + # if !@HAVE_DPRINTF@ + _GL_FUNCDECL_SYS (dprintf, int, (int fd, const char *format, ...) +- __attribute__ ((__format__ (__printf__, 2, 3))) ++ _GL_ATTRIBUTE_FORMAT_PRINTF (2, 3) + _GL_ARG_NONNULL ((2))); + # endif + _GL_CXXALIAS_SYS (dprintf, int, (int fd, const char *format, ...)); +@@ -113,6 +170,26 @@ _GL_WARN_ON_USE (fclose, "fclose is not always POSIX compliant - " + "use gnulib module fclose for portable POSIX compliance"); + #endif + ++#if @GNULIB_FDOPEN@ ++# if @REPLACE_FDOPEN@ ++# if !(defined __cplusplus && defined GNULIB_NAMESPACE) ++# undef fdopen ++# define fdopen rpl_fdopen ++# endif ++_GL_FUNCDECL_RPL (fdopen, FILE *, (int fd, const char *mode) ++ _GL_ARG_NONNULL ((2))); ++_GL_CXXALIAS_RPL (fdopen, FILE *, (int fd, const char *mode)); ++# else ++_GL_CXXALIAS_SYS (fdopen, FILE *, (int fd, const char *mode)); ++# endif ++_GL_CXXALIASWARN (fdopen); ++#elif defined GNULIB_POSIXCHECK ++# undef fdopen ++/* Assume fdopen is always declared. */ ++_GL_WARN_ON_USE (fdopen, "fdopen on native Windows platforms is not POSIX compliant - " ++ "use gnulib module fdopen for portability"); ++#endif ++ + #if @GNULIB_FFLUSH@ + /* Flush all pending data on STREAM according to POSIX rules. Both + output and seekable input streams are supported. +@@ -137,12 +214,33 @@ _GL_WARN_ON_USE (fflush, "fflush is not always POSIX compliant - " + "use gnulib module fflush for portable POSIX compliance"); + #endif + +-/* It is very rare that the developer ever has full control of stdin, +- so any use of gets warrants an unconditional warning; besides, C11 +- removed it. */ +-#undef gets +-#if HAVE_RAW_DECL_GETS +-_GL_WARN_ON_USE (gets, "gets is a security hole - use fgets instead"); ++#if @GNULIB_FGETC@ ++# if @REPLACE_STDIO_READ_FUNCS@ && @GNULIB_STDIO_H_NONBLOCKING@ ++# if !(defined __cplusplus && defined GNULIB_NAMESPACE) ++# undef fgetc ++# define fgetc rpl_fgetc ++# endif ++_GL_FUNCDECL_RPL (fgetc, int, (FILE *stream) _GL_ARG_NONNULL ((1))); ++_GL_CXXALIAS_RPL (fgetc, int, (FILE *stream)); ++# else ++_GL_CXXALIAS_SYS (fgetc, int, (FILE *stream)); ++# endif ++_GL_CXXALIASWARN (fgetc); ++#endif ++ ++#if @GNULIB_FGETS@ ++# if @REPLACE_STDIO_READ_FUNCS@ && @GNULIB_STDIO_H_NONBLOCKING@ ++# if !(defined __cplusplus && defined GNULIB_NAMESPACE) ++# undef fgets ++# define fgets rpl_fgets ++# endif ++_GL_FUNCDECL_RPL (fgets, char *, (char *s, int n, FILE *stream) ++ _GL_ARG_NONNULL ((1, 3))); ++_GL_CXXALIAS_RPL (fgets, char *, (char *s, int n, FILE *stream)); ++# else ++_GL_CXXALIAS_SYS (fgets, char *, (char *s, int n, FILE *stream)); ++# endif ++_GL_CXXALIASWARN (fgets); + #endif + + #if @GNULIB_FOPEN@ +@@ -161,20 +259,26 @@ _GL_CXXALIASWARN (fopen); + #elif defined GNULIB_POSIXCHECK + # undef fopen + /* Assume fopen is always declared. */ +-_GL_WARN_ON_USE (fopen, "fopen on Win32 platforms is not POSIX compatible - " ++_GL_WARN_ON_USE (fopen, "fopen on native Windows platforms is not POSIX compliant - " + "use gnulib module fopen for portability"); + #endif + + #if @GNULIB_FPRINTF_POSIX@ || @GNULIB_FPRINTF@ + # if (@GNULIB_FPRINTF_POSIX@ && @REPLACE_FPRINTF@) \ +- || (@GNULIB_FPRINTF@ && @REPLACE_STDIO_WRITE_FUNCS@ && @GNULIB_STDIO_H_SIGPIPE@) ++ || (@GNULIB_FPRINTF@ && @REPLACE_STDIO_WRITE_FUNCS@ && (@GNULIB_STDIO_H_NONBLOCKING@ || @GNULIB_STDIO_H_SIGPIPE@)) + # if !(defined __cplusplus && defined GNULIB_NAMESPACE) + # define fprintf rpl_fprintf + # endif + # define GNULIB_overrides_fprintf 1 ++# if @GNULIB_FPRINTF_POSIX@ || @GNULIB_VFPRINTF_POSIX@ + _GL_FUNCDECL_RPL (fprintf, int, (FILE *fp, const char *format, ...) +- __attribute__ ((__format__ (__printf__, 2, 3))) ++ _GL_ATTRIBUTE_FORMAT_PRINTF (2, 3) + _GL_ARG_NONNULL ((1, 2))); ++# else ++_GL_FUNCDECL_RPL (fprintf, int, (FILE *fp, const char *format, ...) ++ _GL_ATTRIBUTE_FORMAT_PRINTF_SYSTEM (2, 3) ++ _GL_ARG_NONNULL ((1, 2))); ++# endif + _GL_CXXALIAS_RPL (fprintf, int, (FILE *fp, const char *format, ...)); + # else + _GL_CXXALIAS_SYS (fprintf, int, (FILE *fp, const char *format, ...)); +@@ -220,7 +324,7 @@ _GL_WARN_ON_USE (fpurge, "fpurge is not always present - " + #endif + + #if @GNULIB_FPUTC@ +-# if @REPLACE_STDIO_WRITE_FUNCS@ && @GNULIB_STDIO_H_SIGPIPE@ ++# if @REPLACE_STDIO_WRITE_FUNCS@ && (@GNULIB_STDIO_H_NONBLOCKING@ || @GNULIB_STDIO_H_SIGPIPE@) + # if !(defined __cplusplus && defined GNULIB_NAMESPACE) + # undef fputc + # define fputc rpl_fputc +@@ -234,7 +338,7 @@ _GL_CXXALIASWARN (fputc); + #endif + + #if @GNULIB_FPUTS@ +-# if @REPLACE_STDIO_WRITE_FUNCS@ && @GNULIB_STDIO_H_SIGPIPE@ ++# if @REPLACE_STDIO_WRITE_FUNCS@ && (@GNULIB_STDIO_H_NONBLOCKING@ || @GNULIB_STDIO_H_SIGPIPE@) + # if !(defined __cplusplus && defined GNULIB_NAMESPACE) + # undef fputs + # define fputs rpl_fputs +@@ -248,6 +352,21 @@ _GL_CXXALIAS_SYS (fputs, int, (const char *string, FILE *stream)); + _GL_CXXALIASWARN (fputs); + #endif + ++#if @GNULIB_FREAD@ ++# if @REPLACE_STDIO_READ_FUNCS@ && @GNULIB_STDIO_H_NONBLOCKING@ ++# if !(defined __cplusplus && defined GNULIB_NAMESPACE) ++# undef fread ++# define fread rpl_fread ++# endif ++_GL_FUNCDECL_RPL (fread, size_t, (void *ptr, size_t s, size_t n, FILE *stream) ++ _GL_ARG_NONNULL ((4))); ++_GL_CXXALIAS_RPL (fread, size_t, (void *ptr, size_t s, size_t n, FILE *stream)); ++# else ++_GL_CXXALIAS_SYS (fread, size_t, (void *ptr, size_t s, size_t n, FILE *stream)); ++# endif ++_GL_CXXALIASWARN (fread); ++#endif ++ + #if @GNULIB_FREOPEN@ + # if @REPLACE_FREOPEN@ + # if !(defined __cplusplus && defined GNULIB_NAMESPACE) +@@ -267,10 +386,27 @@ _GL_CXXALIASWARN (freopen); + #elif defined GNULIB_POSIXCHECK + # undef freopen + /* Assume freopen is always declared. */ +-_GL_WARN_ON_USE (freopen, "freopen on Win32 platforms is not POSIX compatible - " ++_GL_WARN_ON_USE (freopen, ++ "freopen on native Windows platforms is not POSIX compliant - " + "use gnulib module freopen for portability"); + #endif + ++#if @GNULIB_FSCANF@ ++# if @REPLACE_STDIO_READ_FUNCS@ && @GNULIB_STDIO_H_NONBLOCKING@ ++# if !(defined __cplusplus && defined GNULIB_NAMESPACE) ++# undef fscanf ++# define fscanf rpl_fscanf ++# endif ++_GL_FUNCDECL_RPL (fscanf, int, (FILE *stream, const char *format, ...) ++ _GL_ATTRIBUTE_FORMAT_SCANF_SYSTEM (2, 3) ++ _GL_ARG_NONNULL ((1, 2))); ++_GL_CXXALIAS_RPL (fscanf, int, (FILE *stream, const char *format, ...)); ++# else ++_GL_CXXALIAS_SYS (fscanf, int, (FILE *stream, const char *format, ...)); ++# endif ++_GL_CXXALIASWARN (fscanf); ++#endif ++ + + /* Set up the following warnings, based on which modules are in use. + GNU Coding Standards discourage the use of fseek, since it imposes +@@ -338,29 +474,13 @@ _GL_FUNCDECL_RPL (fseeko, int, (FILE *fp, off_t offset, int whence) + _GL_ARG_NONNULL ((1))); + _GL_CXXALIAS_RPL (fseeko, int, (FILE *fp, off_t offset, int whence)); + # else +-# if ! @HAVE_FSEEKO@ ++# if ! @HAVE_DECL_FSEEKO@ + _GL_FUNCDECL_SYS (fseeko, int, (FILE *fp, off_t offset, int whence) + _GL_ARG_NONNULL ((1))); + # endif + _GL_CXXALIAS_SYS (fseeko, int, (FILE *fp, off_t offset, int whence)); + # endif + _GL_CXXALIASWARN (fseeko); +-# if (@REPLACE_FSEEKO@ || !@HAVE_FSEEKO@) && !@GNULIB_FSEEK@ +- /* Provide an fseek function that is consistent with fseeko. */ +- /* In order to avoid that fseek gets defined as a macro here, the +- developer can request the 'fseek' module. */ +-# undef fseek +-# define fseek rpl_fseek +-static inline int _GL_ARG_NONNULL ((1)) +-rpl_fseek (FILE *fp, long offset, int whence) +-{ +-# if @REPLACE_FSEEKO@ +- return rpl_fseeko (fp, offset, whence); +-# else +- return fseeko (fp, offset, whence); +-# endif +-} +-# endif + #elif defined GNULIB_POSIXCHECK + # define _GL_FSEEK_WARN /* Category 1, above. */ + # undef fseek +@@ -414,28 +534,12 @@ _GL_CXXALIASWARN (ftell); + _GL_FUNCDECL_RPL (ftello, off_t, (FILE *fp) _GL_ARG_NONNULL ((1))); + _GL_CXXALIAS_RPL (ftello, off_t, (FILE *fp)); + # else +-# if ! @HAVE_FTELLO@ ++# if ! @HAVE_DECL_FTELLO@ + _GL_FUNCDECL_SYS (ftello, off_t, (FILE *fp) _GL_ARG_NONNULL ((1))); + # endif + _GL_CXXALIAS_SYS (ftello, off_t, (FILE *fp)); + # endif + _GL_CXXALIASWARN (ftello); +-# if (@REPLACE_FTELLO@ || !@HAVE_FTELLO@) && !@GNULIB_FTELL@ +- /* Provide an ftell function that is consistent with ftello. */ +- /* In order to avoid that ftell gets defined as a macro here, the +- developer can request the 'ftell' module. */ +-# undef ftell +-# define ftell rpl_ftell +-static inline long _GL_ARG_NONNULL ((1)) +-rpl_ftell (FILE *f) +-{ +-# if @REPLACE_FTELLO@ +- return rpl_ftello (f); +-# else +- return ftello (f); +-# endif +-} +-# endif + #elif defined GNULIB_POSIXCHECK + # define _GL_FTELL_WARN /* Category 1, above. */ + # undef ftell +@@ -457,7 +561,7 @@ _GL_WARN_ON_USE (ftell, "ftell cannot handle files larger than 4 GB " + + + #if @GNULIB_FWRITE@ +-# if @REPLACE_STDIO_WRITE_FUNCS@ && @GNULIB_STDIO_H_SIGPIPE@ ++# if @REPLACE_STDIO_WRITE_FUNCS@ && (@GNULIB_STDIO_H_NONBLOCKING@ || @GNULIB_STDIO_H_SIGPIPE@) + # if !(defined __cplusplus && defined GNULIB_NAMESPACE) + # undef fwrite + # define fwrite rpl_fwrite +@@ -470,10 +574,51 @@ _GL_CXXALIAS_RPL (fwrite, size_t, + # else + _GL_CXXALIAS_SYS (fwrite, size_t, + (const void *ptr, size_t s, size_t n, FILE *stream)); ++ ++/* Work around bug 11959 when fortifying glibc 2.4 through 2.15 ++ , ++ which sometimes causes an unwanted diagnostic for fwrite calls. ++ This affects only function declaration attributes under certain ++ versions of gcc, and is not needed for C++. */ ++# if (0 < __USE_FORTIFY_LEVEL \ ++ && __GLIBC__ == 2 && 4 <= __GLIBC_MINOR__ && __GLIBC_MINOR__ <= 15 \ ++ && 3 < __GNUC__ + (4 <= __GNUC_MINOR__) \ ++ && !defined __cplusplus) ++# undef fwrite ++# define fwrite(a, b, c, d) ({size_t __r = fwrite (a, b, c, d); __r; }) ++# endif + # endif + _GL_CXXALIASWARN (fwrite); + #endif + ++#if @GNULIB_GETC@ ++# if @REPLACE_STDIO_READ_FUNCS@ && @GNULIB_STDIO_H_NONBLOCKING@ ++# if !(defined __cplusplus && defined GNULIB_NAMESPACE) ++# undef getc ++# define getc rpl_fgetc ++# endif ++_GL_FUNCDECL_RPL (fgetc, int, (FILE *stream) _GL_ARG_NONNULL ((1))); ++_GL_CXXALIAS_RPL_1 (getc, rpl_fgetc, int, (FILE *stream)); ++# else ++_GL_CXXALIAS_SYS (getc, int, (FILE *stream)); ++# endif ++_GL_CXXALIASWARN (getc); ++#endif ++ ++#if @GNULIB_GETCHAR@ ++# if @REPLACE_STDIO_READ_FUNCS@ && @GNULIB_STDIO_H_NONBLOCKING@ ++# if !(defined __cplusplus && defined GNULIB_NAMESPACE) ++# undef getchar ++# define getchar rpl_getchar ++# endif ++_GL_FUNCDECL_RPL (getchar, int, (void)); ++_GL_CXXALIAS_RPL (getchar, int, (void)); ++# else ++_GL_CXXALIAS_SYS (getchar, int, (void)); ++# endif ++_GL_CXXALIASWARN (getchar); ++#endif ++ + #if @GNULIB_GETDELIM@ + /* Read input, up to (and including) the next occurrence of DELIMITER, from + STREAM, store it in *LINEPTR (and NUL-terminate it). +@@ -550,6 +695,14 @@ _GL_WARN_ON_USE (getline, "getline is unportable - " + # endif + #endif + ++/* It is very rare that the developer ever has full control of stdin, ++ so any use of gets warrants an unconditional warning; besides, C11 ++ removed it. */ ++#undef gets ++#if HAVE_RAW_DECL_GETS ++#endif ++ ++ + #if @GNULIB_OBSTACK_PRINTF@ || @GNULIB_OBSTACK_PRINTF_POSIX@ + struct obstack; + /* Grow an obstack with formatted output. Return the number of +@@ -563,7 +716,7 @@ struct obstack; + # endif + _GL_FUNCDECL_RPL (obstack_printf, int, + (struct obstack *obs, const char *format, ...) +- __attribute__ ((__format__ (__printf__, 2, 3))) ++ _GL_ATTRIBUTE_FORMAT_PRINTF (2, 3) + _GL_ARG_NONNULL ((1, 2))); + _GL_CXXALIAS_RPL (obstack_printf, int, + (struct obstack *obs, const char *format, ...)); +@@ -571,7 +724,7 @@ _GL_CXXALIAS_RPL (obstack_printf, int, + # if !@HAVE_DECL_OBSTACK_PRINTF@ + _GL_FUNCDECL_SYS (obstack_printf, int, + (struct obstack *obs, const char *format, ...) +- __attribute__ ((__format__ (__printf__, 2, 3))) ++ _GL_ATTRIBUTE_FORMAT_PRINTF (2, 3) + _GL_ARG_NONNULL ((1, 2))); + # endif + _GL_CXXALIAS_SYS (obstack_printf, int, +@@ -584,7 +737,7 @@ _GL_CXXALIASWARN (obstack_printf); + # endif + _GL_FUNCDECL_RPL (obstack_vprintf, int, + (struct obstack *obs, const char *format, va_list args) +- __attribute__ ((__format__ (__printf__, 2, 0))) ++ _GL_ATTRIBUTE_FORMAT_PRINTF (2, 0) + _GL_ARG_NONNULL ((1, 2))); + _GL_CXXALIAS_RPL (obstack_vprintf, int, + (struct obstack *obs, const char *format, va_list args)); +@@ -592,7 +745,7 @@ _GL_CXXALIAS_RPL (obstack_vprintf, int, + # if !@HAVE_DECL_OBSTACK_PRINTF@ + _GL_FUNCDECL_SYS (obstack_vprintf, int, + (struct obstack *obs, const char *format, va_list args) +- __attribute__ ((__format__ (__printf__, 2, 0))) ++ _GL_ATTRIBUTE_FORMAT_PRINTF (2, 0) + _GL_ARG_NONNULL ((1, 2))); + # endif + _GL_CXXALIAS_SYS (obstack_vprintf, int, +@@ -601,6 +754,20 @@ _GL_CXXALIAS_SYS (obstack_vprintf, int, + _GL_CXXALIASWARN (obstack_vprintf); + #endif + ++#if @GNULIB_PCLOSE@ ++# if !@HAVE_PCLOSE@ ++_GL_FUNCDECL_SYS (pclose, int, (FILE *stream) _GL_ARG_NONNULL ((1))); ++# endif ++_GL_CXXALIAS_SYS (pclose, int, (FILE *stream)); ++_GL_CXXALIASWARN (pclose); ++#elif defined GNULIB_POSIXCHECK ++# undef pclose ++# if HAVE_RAW_DECL_PCLOSE ++_GL_WARN_ON_USE (pclose, "pclose is unportable - " ++ "use gnulib module pclose for more portability"); ++# endif ++#endif ++ + #if @GNULIB_PERROR@ + /* Print a message to standard error, describing the value of ERRNO, + (if STRING is not NULL and not empty) prefixed with STRING and ": ", +@@ -632,6 +799,10 @@ _GL_FUNCDECL_RPL (popen, FILE *, (const char *cmd, const char *mode) + _GL_ARG_NONNULL ((1, 2))); + _GL_CXXALIAS_RPL (popen, FILE *, (const char *cmd, const char *mode)); + # else ++# if !@HAVE_POPEN@ ++_GL_FUNCDECL_SYS (popen, FILE *, (const char *cmd, const char *mode) ++ _GL_ARG_NONNULL ((1, 2))); ++# endif + _GL_CXXALIAS_SYS (popen, FILE *, (const char *cmd, const char *mode)); + # endif + _GL_CXXALIASWARN (popen); +@@ -645,23 +816,35 @@ _GL_WARN_ON_USE (popen, "popen is buggy on some platforms - " + + #if @GNULIB_PRINTF_POSIX@ || @GNULIB_PRINTF@ + # if (@GNULIB_PRINTF_POSIX@ && @REPLACE_PRINTF@) \ +- || (@GNULIB_PRINTF@ && @REPLACE_STDIO_WRITE_FUNCS@ && @GNULIB_STDIO_H_SIGPIPE@) ++ || (@GNULIB_PRINTF@ && @REPLACE_STDIO_WRITE_FUNCS@ && (@GNULIB_STDIO_H_NONBLOCKING@ || @GNULIB_STDIO_H_SIGPIPE@)) + # if defined __GNUC__ + # if !(defined __cplusplus && defined GNULIB_NAMESPACE) + /* Don't break __attribute__((format(printf,M,N))). */ + # define printf __printf__ + # endif ++# if @GNULIB_PRINTF_POSIX@ || @GNULIB_VFPRINTF_POSIX@ ++_GL_FUNCDECL_RPL_1 (__printf__, int, ++ (const char *format, ...) ++ __asm__ (@ASM_SYMBOL_PREFIX@ ++ _GL_STDIO_MACROEXPAND_AND_STRINGIZE(rpl_printf)) ++ _GL_ATTRIBUTE_FORMAT_PRINTF (1, 2) ++ _GL_ARG_NONNULL ((1))); ++# else + _GL_FUNCDECL_RPL_1 (__printf__, int, + (const char *format, ...) + __asm__ (@ASM_SYMBOL_PREFIX@ + _GL_STDIO_MACROEXPAND_AND_STRINGIZE(rpl_printf)) +- __attribute__ ((__format__ (__printf__, 1, 2))) ++ _GL_ATTRIBUTE_FORMAT_PRINTF_SYSTEM (1, 2) + _GL_ARG_NONNULL ((1))); ++# endif + _GL_CXXALIAS_RPL_1 (printf, __printf__, int, (const char *format, ...)); + # else ++# if !(defined __cplusplus && defined GNULIB_NAMESPACE) ++# define printf rpl_printf ++# endif + _GL_FUNCDECL_RPL (printf, int, + (const char *format, ...) +- __attribute__ ((__format__ (__printf__, 1, 2))) ++ _GL_ATTRIBUTE_FORMAT_PRINTF (1, 2) + _GL_ARG_NONNULL ((1))); + _GL_CXXALIAS_RPL (printf, int, (const char *format, ...)); + # endif +@@ -682,7 +865,7 @@ _GL_WARN_ON_USE (printf, "printf is not always POSIX compliant - " + #endif + + #if @GNULIB_PUTC@ +-# if @REPLACE_STDIO_WRITE_FUNCS@ && @GNULIB_STDIO_H_SIGPIPE@ ++# if @REPLACE_STDIO_WRITE_FUNCS@ && (@GNULIB_STDIO_H_NONBLOCKING@ || @GNULIB_STDIO_H_SIGPIPE@) + # if !(defined __cplusplus && defined GNULIB_NAMESPACE) + # undef putc + # define putc rpl_fputc +@@ -696,7 +879,7 @@ _GL_CXXALIASWARN (putc); + #endif + + #if @GNULIB_PUTCHAR@ +-# if @REPLACE_STDIO_WRITE_FUNCS@ && @GNULIB_STDIO_H_SIGPIPE@ ++# if @REPLACE_STDIO_WRITE_FUNCS@ && (@GNULIB_STDIO_H_NONBLOCKING@ || @GNULIB_STDIO_H_SIGPIPE@) + # if !(defined __cplusplus && defined GNULIB_NAMESPACE) + # undef putchar + # define putchar rpl_putchar +@@ -710,7 +893,7 @@ _GL_CXXALIASWARN (putchar); + #endif + + #if @GNULIB_PUTS@ +-# if @REPLACE_STDIO_WRITE_FUNCS@ && @GNULIB_STDIO_H_SIGPIPE@ ++# if @REPLACE_STDIO_WRITE_FUNCS@ && (@GNULIB_STDIO_H_NONBLOCKING@ || @GNULIB_STDIO_H_SIGPIPE@) + # if !(defined __cplusplus && defined GNULIB_NAMESPACE) + # undef puts + # define puts rpl_puts +@@ -794,6 +977,37 @@ _GL_WARN_ON_USE (renameat, "renameat is not portable - " + # endif + #endif + ++#if @GNULIB_SCANF@ ++# if @REPLACE_STDIO_READ_FUNCS@ && @GNULIB_STDIO_H_NONBLOCKING@ ++# if defined __GNUC__ ++# if !(defined __cplusplus && defined GNULIB_NAMESPACE) ++# undef scanf ++/* Don't break __attribute__((format(scanf,M,N))). */ ++# define scanf __scanf__ ++# endif ++_GL_FUNCDECL_RPL_1 (__scanf__, int, ++ (const char *format, ...) ++ __asm__ (@ASM_SYMBOL_PREFIX@ ++ _GL_STDIO_MACROEXPAND_AND_STRINGIZE(rpl_scanf)) ++ _GL_ATTRIBUTE_FORMAT_SCANF_SYSTEM (1, 2) ++ _GL_ARG_NONNULL ((1))); ++_GL_CXXALIAS_RPL_1 (scanf, __scanf__, int, (const char *format, ...)); ++# else ++# if !(defined __cplusplus && defined GNULIB_NAMESPACE) ++# undef scanf ++# define scanf rpl_scanf ++# endif ++_GL_FUNCDECL_RPL (scanf, int, (const char *format, ...) ++ _GL_ATTRIBUTE_FORMAT_SCANF_SYSTEM (1, 2) ++ _GL_ARG_NONNULL ((1))); ++_GL_CXXALIAS_RPL (scanf, int, (const char *format, ...)); ++# endif ++# else ++_GL_CXXALIAS_SYS (scanf, int, (const char *format, ...)); ++# endif ++_GL_CXXALIASWARN (scanf); ++#endif ++ + #if @GNULIB_SNPRINTF@ + # if @REPLACE_SNPRINTF@ + # if !(defined __cplusplus && defined GNULIB_NAMESPACE) +@@ -801,7 +1015,7 @@ _GL_WARN_ON_USE (renameat, "renameat is not portable - " + # endif + _GL_FUNCDECL_RPL (snprintf, int, + (char *str, size_t size, const char *format, ...) +- __attribute__ ((__format__ (__printf__, 3, 4))) ++ _GL_ATTRIBUTE_FORMAT_PRINTF (3, 4) + _GL_ARG_NONNULL ((3))); + _GL_CXXALIAS_RPL (snprintf, int, + (char *str, size_t size, const char *format, ...)); +@@ -809,7 +1023,7 @@ _GL_CXXALIAS_RPL (snprintf, int, + # if !@HAVE_DECL_SNPRINTF@ + _GL_FUNCDECL_SYS (snprintf, int, + (char *str, size_t size, const char *format, ...) +- __attribute__ ((__format__ (__printf__, 3, 4))) ++ _GL_ATTRIBUTE_FORMAT_PRINTF (3, 4) + _GL_ARG_NONNULL ((3))); + # endif + _GL_CXXALIAS_SYS (snprintf, int, +@@ -824,9 +1038,9 @@ _GL_WARN_ON_USE (snprintf, "snprintf is unportable - " + # endif + #endif + +-/* Some people would argue that sprintf should be handled like gets +- (for example, OpenBSD issues a link warning for both functions), +- since both can cause security holes due to buffer overruns. ++/* Some people would argue that all sprintf uses should be warned about ++ (for example, OpenBSD issues a link warning for it), ++ since it can cause security holes due to buffer overruns. + However, we believe that sprintf can be used safely, and is more + efficient than snprintf in those safe cases; and as proof of our + belief, we use sprintf in several gnulib modules. So this header +@@ -839,7 +1053,7 @@ _GL_WARN_ON_USE (snprintf, "snprintf is unportable - " + # define sprintf rpl_sprintf + # endif + _GL_FUNCDECL_RPL (sprintf, int, (char *str, const char *format, ...) +- __attribute__ ((__format__ (__printf__, 2, 3))) ++ _GL_ATTRIBUTE_FORMAT_PRINTF (2, 3) + _GL_ARG_NONNULL ((1, 2))); + _GL_CXXALIAS_RPL (sprintf, int, (char *str, const char *format, ...)); + # else +@@ -884,7 +1098,7 @@ _GL_WARN_ON_USE (tmpfile, "tmpfile is not usable on mingw - " + # endif + _GL_FUNCDECL_RPL (asprintf, int, + (char **result, const char *format, ...) +- __attribute__ ((__format__ (__printf__, 2, 3))) ++ _GL_ATTRIBUTE_FORMAT_PRINTF (2, 3) + _GL_ARG_NONNULL ((1, 2))); + _GL_CXXALIAS_RPL (asprintf, int, + (char **result, const char *format, ...)); +@@ -892,7 +1106,7 @@ _GL_CXXALIAS_RPL (asprintf, int, + # if !@HAVE_VASPRINTF@ + _GL_FUNCDECL_SYS (asprintf, int, + (char **result, const char *format, ...) +- __attribute__ ((__format__ (__printf__, 2, 3))) ++ _GL_ATTRIBUTE_FORMAT_PRINTF (2, 3) + _GL_ARG_NONNULL ((1, 2))); + # endif + _GL_CXXALIAS_SYS (asprintf, int, +@@ -905,7 +1119,7 @@ _GL_CXXALIASWARN (asprintf); + # endif + _GL_FUNCDECL_RPL (vasprintf, int, + (char **result, const char *format, va_list args) +- __attribute__ ((__format__ (__printf__, 2, 0))) ++ _GL_ATTRIBUTE_FORMAT_PRINTF (2, 0) + _GL_ARG_NONNULL ((1, 2))); + _GL_CXXALIAS_RPL (vasprintf, int, + (char **result, const char *format, va_list args)); +@@ -913,7 +1127,7 @@ _GL_CXXALIAS_RPL (vasprintf, int, + # if !@HAVE_VASPRINTF@ + _GL_FUNCDECL_SYS (vasprintf, int, + (char **result, const char *format, va_list args) +- __attribute__ ((__format__ (__printf__, 2, 0))) ++ _GL_ATTRIBUTE_FORMAT_PRINTF (2, 0) + _GL_ARG_NONNULL ((1, 2))); + # endif + _GL_CXXALIAS_SYS (vasprintf, int, +@@ -928,13 +1142,13 @@ _GL_CXXALIASWARN (vasprintf); + # define vdprintf rpl_vdprintf + # endif + _GL_FUNCDECL_RPL (vdprintf, int, (int fd, const char *format, va_list args) +- __attribute__ ((__format__ (__printf__, 2, 0))) ++ _GL_ATTRIBUTE_FORMAT_PRINTF (2, 0) + _GL_ARG_NONNULL ((2))); + _GL_CXXALIAS_RPL (vdprintf, int, (int fd, const char *format, va_list args)); + # else + # if !@HAVE_VDPRINTF@ + _GL_FUNCDECL_SYS (vdprintf, int, (int fd, const char *format, va_list args) +- __attribute__ ((__format__ (__printf__, 2, 0))) ++ _GL_ATTRIBUTE_FORMAT_PRINTF (2, 0) + _GL_ARG_NONNULL ((2))); + # endif + /* Need to cast, because on Solaris, the third parameter will likely be +@@ -953,14 +1167,20 @@ _GL_WARN_ON_USE (vdprintf, "vdprintf is unportable - " + + #if @GNULIB_VFPRINTF_POSIX@ || @GNULIB_VFPRINTF@ + # if (@GNULIB_VFPRINTF_POSIX@ && @REPLACE_VFPRINTF@) \ +- || (@GNULIB_VFPRINTF@ && @REPLACE_STDIO_WRITE_FUNCS@ && @GNULIB_STDIO_H_SIGPIPE@) ++ || (@GNULIB_VFPRINTF@ && @REPLACE_STDIO_WRITE_FUNCS@ && (@GNULIB_STDIO_H_NONBLOCKING@ || @GNULIB_STDIO_H_SIGPIPE@)) + # if !(defined __cplusplus && defined GNULIB_NAMESPACE) + # define vfprintf rpl_vfprintf + # endif + # define GNULIB_overrides_vfprintf 1 ++# if @GNULIB_VFPRINTF_POSIX@ ++_GL_FUNCDECL_RPL (vfprintf, int, (FILE *fp, const char *format, va_list args) ++ _GL_ATTRIBUTE_FORMAT_PRINTF (2, 0) ++ _GL_ARG_NONNULL ((1, 2))); ++# else + _GL_FUNCDECL_RPL (vfprintf, int, (FILE *fp, const char *format, va_list args) +- __attribute__ ((__format__ (__printf__, 2, 0))) ++ _GL_ATTRIBUTE_FORMAT_PRINTF_SYSTEM (2, 0) + _GL_ARG_NONNULL ((1, 2))); ++# endif + _GL_CXXALIAS_RPL (vfprintf, int, (FILE *fp, const char *format, va_list args)); + # else + /* Need to cast, because on Solaris, the third parameter is +@@ -981,16 +1201,41 @@ _GL_WARN_ON_USE (vfprintf, "vfprintf is not always POSIX compliant - " + "POSIX compliance"); + #endif + ++#if @GNULIB_VFSCANF@ ++# if @REPLACE_STDIO_READ_FUNCS@ && @GNULIB_STDIO_H_NONBLOCKING@ ++# if !(defined __cplusplus && defined GNULIB_NAMESPACE) ++# undef vfscanf ++# define vfscanf rpl_vfscanf ++# endif ++_GL_FUNCDECL_RPL (vfscanf, int, ++ (FILE *stream, const char *format, va_list args) ++ _GL_ATTRIBUTE_FORMAT_SCANF_SYSTEM (2, 0) ++ _GL_ARG_NONNULL ((1, 2))); ++_GL_CXXALIAS_RPL (vfscanf, int, ++ (FILE *stream, const char *format, va_list args)); ++# else ++_GL_CXXALIAS_SYS (vfscanf, int, ++ (FILE *stream, const char *format, va_list args)); ++# endif ++_GL_CXXALIASWARN (vfscanf); ++#endif ++ + #if @GNULIB_VPRINTF_POSIX@ || @GNULIB_VPRINTF@ + # if (@GNULIB_VPRINTF_POSIX@ && @REPLACE_VPRINTF@) \ +- || (@GNULIB_VPRINTF@ && @REPLACE_STDIO_WRITE_FUNCS@ && @GNULIB_STDIO_H_SIGPIPE@) ++ || (@GNULIB_VPRINTF@ && @REPLACE_STDIO_WRITE_FUNCS@ && (@GNULIB_STDIO_H_NONBLOCKING@ || @GNULIB_STDIO_H_SIGPIPE@)) + # if !(defined __cplusplus && defined GNULIB_NAMESPACE) + # define vprintf rpl_vprintf + # endif + # define GNULIB_overrides_vprintf 1 ++# if @GNULIB_VPRINTF_POSIX@ || @GNULIB_VFPRINTF_POSIX@ + _GL_FUNCDECL_RPL (vprintf, int, (const char *format, va_list args) +- __attribute__ ((__format__ (__printf__, 1, 0))) ++ _GL_ATTRIBUTE_FORMAT_PRINTF (1, 0) + _GL_ARG_NONNULL ((1))); ++# else ++_GL_FUNCDECL_RPL (vprintf, int, (const char *format, va_list args) ++ _GL_ATTRIBUTE_FORMAT_PRINTF_SYSTEM (1, 0) ++ _GL_ARG_NONNULL ((1))); ++# endif + _GL_CXXALIAS_RPL (vprintf, int, (const char *format, va_list args)); + # else + /* Need to cast, because on Solaris, the second parameter is +@@ -1010,6 +1255,22 @@ _GL_WARN_ON_USE (vprintf, "vprintf is not always POSIX compliant - " + "POSIX compliance"); + #endif + ++#if @GNULIB_VSCANF@ ++# if @REPLACE_STDIO_READ_FUNCS@ && @GNULIB_STDIO_H_NONBLOCKING@ ++# if !(defined __cplusplus && defined GNULIB_NAMESPACE) ++# undef vscanf ++# define vscanf rpl_vscanf ++# endif ++_GL_FUNCDECL_RPL (vscanf, int, (const char *format, va_list args) ++ _GL_ATTRIBUTE_FORMAT_SCANF_SYSTEM (1, 0) ++ _GL_ARG_NONNULL ((1))); ++_GL_CXXALIAS_RPL (vscanf, int, (const char *format, va_list args)); ++# else ++_GL_CXXALIAS_SYS (vscanf, int, (const char *format, va_list args)); ++# endif ++_GL_CXXALIASWARN (vscanf); ++#endif ++ + #if @GNULIB_VSNPRINTF@ + # if @REPLACE_VSNPRINTF@ + # if !(defined __cplusplus && defined GNULIB_NAMESPACE) +@@ -1017,7 +1278,7 @@ _GL_WARN_ON_USE (vprintf, "vprintf is not always POSIX compliant - " + # endif + _GL_FUNCDECL_RPL (vsnprintf, int, + (char *str, size_t size, const char *format, va_list args) +- __attribute__ ((__format__ (__printf__, 3, 0))) ++ _GL_ATTRIBUTE_FORMAT_PRINTF (3, 0) + _GL_ARG_NONNULL ((3))); + _GL_CXXALIAS_RPL (vsnprintf, int, + (char *str, size_t size, const char *format, va_list args)); +@@ -1025,7 +1286,7 @@ _GL_CXXALIAS_RPL (vsnprintf, int, + # if !@HAVE_DECL_VSNPRINTF@ + _GL_FUNCDECL_SYS (vsnprintf, int, + (char *str, size_t size, const char *format, va_list args) +- __attribute__ ((__format__ (__printf__, 3, 0))) ++ _GL_ATTRIBUTE_FORMAT_PRINTF (3, 0) + _GL_ARG_NONNULL ((3))); + # endif + _GL_CXXALIAS_SYS (vsnprintf, int, +@@ -1047,7 +1308,7 @@ _GL_WARN_ON_USE (vsnprintf, "vsnprintf is unportable - " + # endif + _GL_FUNCDECL_RPL (vsprintf, int, + (char *str, const char *format, va_list args) +- __attribute__ ((__format__ (__printf__, 2, 0))) ++ _GL_ATTRIBUTE_FORMAT_PRINTF (2, 0) + _GL_ARG_NONNULL ((1, 2))); + _GL_CXXALIAS_RPL (vsprintf, int, + (char *str, const char *format, va_list args)); +@@ -1067,7 +1328,6 @@ _GL_WARN_ON_USE (vsprintf, "vsprintf is not always POSIX compliant - " + "POSIX compliance"); + #endif + +- +-#endif /* _GL_STDIO_H */ +-#endif /* _GL_STDIO_H */ ++#endif /* _@GUARD_PREFIX@_STDIO_H */ ++#endif /* _@GUARD_PREFIX@_STDIO_H */ + #endif +diff --git a/grub-core/gnulib/stdlib.in.h b/grub-core/gnulib/stdlib.in.h +index f4309ed..c955248 100644 +--- a/grub-core/gnulib/stdlib.in.h ++++ b/grub-core/gnulib/stdlib.in.h +@@ -1,6 +1,6 @@ + /* A GNU-like . + +- Copyright (C) 1995, 2001-2004, 2006-2010 Free Software Foundation, Inc. ++ Copyright (C) 1995, 2001-2004, 2006-2013 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 +@@ -18,28 +18,30 @@ + #if __GNUC__ >= 3 + @PRAGMA_SYSTEM_HEADER@ + #endif ++@PRAGMA_COLUMNS@ + +-#if defined __need_malloc_and_calloc +-/* Special invocation convention inside glibc header files. */ ++#if defined __need_system_stdlib_h || defined __need_malloc_and_calloc ++/* Special invocation conventions inside some gnulib header files, ++ and inside some glibc header files, respectively. */ + + #@INCLUDE_NEXT@ @NEXT_STDLIB_H@ + + #else + /* Normal invocation convention. */ + +-#ifndef _GL_STDLIB_H ++#ifndef _@GUARD_PREFIX@_STDLIB_H + + /* The include_next requires a split double-inclusion guard. */ + #@INCLUDE_NEXT@ @NEXT_STDLIB_H@ + +-#ifndef _GL_STDLIB_H +-#define _GL_STDLIB_H ++#ifndef _@GUARD_PREFIX@_STDLIB_H ++#define _@GUARD_PREFIX@_STDLIB_H + + /* NetBSD 5.0 mis-defines NULL. */ + #include + + /* MirBSD 10 defines WEXITSTATUS in , not in . */ +-#ifndef WEXITSTATUS ++#if @GNULIB_SYSTEM_POSIX@ && !defined WEXITSTATUS + # include + #endif + +@@ -48,18 +50,28 @@ + # include + #endif + +-/* OSF/1 5.1 declares 'struct random_data' in , which is included +- from if _REENTRANT is defined. Include it always. */ +-#if @HAVE_RANDOM_H@ +-# include ++/* Native Windows platforms declare mktemp() in . */ ++#if 0 && ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__) ++# include + #endif + +-#if !@HAVE_STRUCT_RANDOM_DATA@ || (@GNULIB_RANDOM_R@ && !@HAVE_RANDOM_R@) \ +- || defined GNULIB_POSIXCHECK +-# include +-#endif ++#if @GNULIB_RANDOM_R@ ++ ++/* OSF/1 5.1 declares 'struct random_data' in , which is included ++ from if _REENTRANT is defined. Include it whenever we need ++ 'struct random_data'. */ ++# if @HAVE_RANDOM_H@ ++# include ++# endif ++ ++# if !@HAVE_STRUCT_RANDOM_DATA@ || @REPLACE_RANDOM_R@ || !@HAVE_RANDOM_R@ ++# include ++# endif + +-#if !@HAVE_STRUCT_RANDOM_DATA@ ++# if !@HAVE_STRUCT_RANDOM_DATA@ ++/* Define 'struct random_data'. ++ But allow multiple gnulib generated replacements to coexist. */ ++# if !GNULIB_defined_struct_random_data + struct random_data + { + int32_t *fptr; /* Front pointer. */ +@@ -70,21 +82,29 @@ struct random_data + int rand_sep; /* Distance between front and rear. */ + int32_t *end_ptr; /* Pointer behind state table. */ + }; ++# define GNULIB_defined_struct_random_data 1 ++# endif ++# endif + #endif + +-#if (@GNULIB_MKSTEMP@ || @GNULIB_GETSUBOPT@ || defined GNULIB_POSIXCHECK) && ! defined __GLIBC__ && !((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__) +-/* On MacOS X 10.3, only declares mkstemp. */ ++#if (@GNULIB_MKSTEMP@ || @GNULIB_MKSTEMPS@ || @GNULIB_GETSUBOPT@ || defined GNULIB_POSIXCHECK) && ! defined __GLIBC__ && !((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__) ++/* On Mac OS X 10.3, only declares mkstemp. */ ++/* On Mac OS X 10.5, only declares mkstemps. */ + /* On Cygwin 1.7.1, only declares getsubopt. */ + /* But avoid namespace pollution on glibc systems and native Windows. */ + # include + #endif + +-#ifndef __attribute__ +-# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) +-# define __attribute__(Spec) /* empty */ +-# endif ++/* The __attribute__ feature is available in gcc versions 2.5 and later. ++ The attribute __pure__ was added in gcc 2.96. */ ++#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) ++# define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__)) ++#else ++# define _GL_ATTRIBUTE_PURE /* empty */ + #endif + ++/* The definition of _Noreturn is copied here. */ ++ + /* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ + + /* The definition of _GL_ARG_NONNULL is copied here. */ +@@ -110,7 +130,7 @@ struct random_data + /* Terminate the current process with the given return code, without running + the 'atexit' handlers. */ + # if !@HAVE__EXIT@ +-_GL_FUNCDECL_SYS (_Exit, void, (int status) __attribute__ ((__noreturn__))); ++_GL_FUNCDECL_SYS (_Exit, _Noreturn void, (int status)); + # endif + _GL_CXXALIAS_SYS (_Exit, void, (int status)); + _GL_CXXALIASWARN (_Exit); +@@ -127,7 +147,9 @@ _GL_WARN_ON_USE (_Exit, "_Exit is unportable - " + /* Parse a signed decimal integer. + Returns the value of the integer. Errors are not detected. */ + # if !@HAVE_ATOLL@ +-_GL_FUNCDECL_SYS (atoll, long long, (const char *string) _GL_ARG_NONNULL ((1))); ++_GL_FUNCDECL_SYS (atoll, long long, (const char *string) ++ _GL_ATTRIBUTE_PURE ++ _GL_ARG_NONNULL ((1))); + # endif + _GL_CXXALIAS_SYS (atoll, long long, (const char *string)); + _GL_CXXALIASWARN (atoll); +@@ -177,7 +199,8 @@ _GL_CXXALIASWARN (canonicalize_file_name); + #elif defined GNULIB_POSIXCHECK + # undef canonicalize_file_name + # if HAVE_RAW_DECL_CANONICALIZE_FILE_NAME +-_GL_WARN_ON_USE (canonicalize_file_name, "canonicalize_file_name is unportable - " ++_GL_WARN_ON_USE (canonicalize_file_name, ++ "canonicalize_file_name is unportable - " + "use gnulib module canonicalize-lgpl for portability"); + # endif + #endif +@@ -240,14 +263,19 @@ _GL_CXXALIASWARN (grantpt); + #elif defined GNULIB_POSIXCHECK + # undef grantpt + # if HAVE_RAW_DECL_GRANTPT +-_GL_WARN_ON_USE (ptsname, "grantpt is not portable - " ++_GL_WARN_ON_USE (grantpt, "grantpt is not portable - " + "use gnulib module grantpt for portability"); + # endif + #endif + ++/* If _GL_USE_STDLIB_ALLOC is nonzero, the including module does not ++ rely on GNU or POSIX semantics for malloc and realloc (for example, ++ by never specifying a zero size), so it does not need malloc or ++ realloc to be redefined. */ + #if @GNULIB_MALLOC_POSIX@ + # if @REPLACE_MALLOC@ +-# if !(defined __cplusplus && defined GNULIB_NAMESPACE) ++# if !((defined __cplusplus && defined GNULIB_NAMESPACE) \ ++ || _GL_USE_STDLIB_ALLOC) + # undef malloc + # define malloc rpl_malloc + # endif +@@ -257,13 +285,28 @@ _GL_CXXALIAS_RPL (malloc, void *, (size_t size)); + _GL_CXXALIAS_SYS (malloc, void *, (size_t size)); + # endif + _GL_CXXALIASWARN (malloc); +-#elif defined GNULIB_POSIXCHECK ++#elif defined GNULIB_POSIXCHECK && !_GL_USE_STDLIB_ALLOC + # undef malloc + /* Assume malloc is always declared. */ + _GL_WARN_ON_USE (malloc, "malloc is not POSIX compliant everywhere - " + "use gnulib module malloc-posix for portability"); + #endif + ++/* Convert a multibyte character to a wide character. */ ++#if @GNULIB_MBTOWC@ ++# if @REPLACE_MBTOWC@ ++# if !(defined __cplusplus && defined GNULIB_NAMESPACE) ++# undef mbtowc ++# define mbtowc rpl_mbtowc ++# endif ++_GL_FUNCDECL_RPL (mbtowc, int, (wchar_t *pwc, const char *s, size_t n)); ++_GL_CXXALIAS_RPL (mbtowc, int, (wchar_t *pwc, const char *s, size_t n)); ++# else ++_GL_CXXALIAS_SYS (mbtowc, int, (wchar_t *pwc, const char *s, size_t n)); ++# endif ++_GL_CXXALIASWARN (mbtowc); ++#endif ++ + #if @GNULIB_MKDTEMP@ + /* Create a unique temporary directory from TEMPLATE. + The last six characters of TEMPLATE must be "XXXXXX"; +@@ -396,13 +439,38 @@ _GL_WARN_ON_USE (mkstemps, "mkstemps is unportable - " + # endif + #endif + ++#if @GNULIB_POSIX_OPENPT@ ++/* Return an FD open to the master side of a pseudo-terminal. Flags should ++ include O_RDWR, and may also include O_NOCTTY. */ ++# if !@HAVE_POSIX_OPENPT@ ++_GL_FUNCDECL_SYS (posix_openpt, int, (int flags)); ++# endif ++_GL_CXXALIAS_SYS (posix_openpt, int, (int flags)); ++_GL_CXXALIASWARN (posix_openpt); ++#elif defined GNULIB_POSIXCHECK ++# undef posix_openpt ++# if HAVE_RAW_DECL_POSIX_OPENPT ++_GL_WARN_ON_USE (posix_openpt, "posix_openpt is not portable - " ++ "use gnulib module posix_openpt for portability"); ++# endif ++#endif ++ + #if @GNULIB_PTSNAME@ + /* Return the pathname of the pseudo-terminal slave associated with + the master FD is open on, or NULL on errors. */ +-# if !@HAVE_PTSNAME@ ++# if @REPLACE_PTSNAME@ ++# if !(defined __cplusplus && defined GNULIB_NAMESPACE) ++# undef ptsname ++# define ptsname rpl_ptsname ++# endif ++_GL_FUNCDECL_RPL (ptsname, char *, (int fd)); ++_GL_CXXALIAS_RPL (ptsname, char *, (int fd)); ++# else ++# if !@HAVE_PTSNAME@ + _GL_FUNCDECL_SYS (ptsname, char *, (int fd)); +-# endif ++# endif + _GL_CXXALIAS_SYS (ptsname, char *, (int fd)); ++# endif + _GL_CXXALIASWARN (ptsname); + #elif defined GNULIB_POSIXCHECK + # undef ptsname +@@ -412,6 +480,32 @@ _GL_WARN_ON_USE (ptsname, "ptsname is not portable - " + # endif + #endif + ++#if @GNULIB_PTSNAME_R@ ++/* Set the pathname of the pseudo-terminal slave associated with ++ the master FD is open on and return 0, or set errno and return ++ non-zero on errors. */ ++# if @REPLACE_PTSNAME_R@ ++# if !(defined __cplusplus && defined GNULIB_NAMESPACE) ++# undef ptsname_r ++# define ptsname_r rpl_ptsname_r ++# endif ++_GL_FUNCDECL_RPL (ptsname_r, int, (int fd, char *buf, size_t len)); ++_GL_CXXALIAS_RPL (ptsname_r, int, (int fd, char *buf, size_t len)); ++# else ++# if !@HAVE_PTSNAME_R@ ++_GL_FUNCDECL_SYS (ptsname_r, int, (int fd, char *buf, size_t len)); ++# endif ++_GL_CXXALIAS_SYS (ptsname_r, int, (int fd, char *buf, size_t len)); ++# endif ++_GL_CXXALIASWARN (ptsname_r); ++#elif defined GNULIB_POSIXCHECK ++# undef ptsname_r ++# if HAVE_RAW_DECL_PTSNAME_R ++_GL_WARN_ON_USE (ptsname_r, "ptsname_r is not portable - " ++ "use gnulib module ptsname_r for portability"); ++# endif ++#endif ++ + #if @GNULIB_PUTENV@ + # if @REPLACE_PUTENV@ + # if !(defined __cplusplus && defined GNULIB_NAMESPACE) +@@ -435,12 +529,83 @@ _GL_CXXALIASWARN (putenv); + # endif + #endif + ++ ++#if @GNULIB_RANDOM@ ++# if !@HAVE_RANDOM@ ++_GL_FUNCDECL_SYS (random, long, (void)); ++# endif ++_GL_CXXALIAS_SYS (random, long, (void)); ++_GL_CXXALIASWARN (random); ++#elif defined GNULIB_POSIXCHECK ++# undef random ++# if HAVE_RAW_DECL_RANDOM ++_GL_WARN_ON_USE (random, "random is unportable - " ++ "use gnulib module random for portability"); ++# endif ++#endif ++ ++#if @GNULIB_RANDOM@ ++# if !@HAVE_RANDOM@ ++_GL_FUNCDECL_SYS (srandom, void, (unsigned int seed)); ++# endif ++_GL_CXXALIAS_SYS (srandom, void, (unsigned int seed)); ++_GL_CXXALIASWARN (srandom); ++#elif defined GNULIB_POSIXCHECK ++# undef srandom ++# if HAVE_RAW_DECL_SRANDOM ++_GL_WARN_ON_USE (srandom, "srandom is unportable - " ++ "use gnulib module random for portability"); ++# endif ++#endif ++ ++#if @GNULIB_RANDOM@ ++# if !@HAVE_RANDOM@ ++_GL_FUNCDECL_SYS (initstate, char *, ++ (unsigned int seed, char *buf, size_t buf_size) ++ _GL_ARG_NONNULL ((2))); ++# endif ++_GL_CXXALIAS_SYS (initstate, char *, ++ (unsigned int seed, char *buf, size_t buf_size)); ++_GL_CXXALIASWARN (initstate); ++#elif defined GNULIB_POSIXCHECK ++# undef initstate ++# if HAVE_RAW_DECL_INITSTATE_R ++_GL_WARN_ON_USE (initstate, "initstate is unportable - " ++ "use gnulib module random for portability"); ++# endif ++#endif ++ ++#if @GNULIB_RANDOM@ ++# if !@HAVE_RANDOM@ ++_GL_FUNCDECL_SYS (setstate, char *, (char *arg_state) _GL_ARG_NONNULL ((1))); ++# endif ++_GL_CXXALIAS_SYS (setstate, char *, (char *arg_state)); ++_GL_CXXALIASWARN (setstate); ++#elif defined GNULIB_POSIXCHECK ++# undef setstate ++# if HAVE_RAW_DECL_SETSTATE_R ++_GL_WARN_ON_USE (setstate, "setstate is unportable - " ++ "use gnulib module random for portability"); ++# endif ++#endif ++ ++ + #if @GNULIB_RANDOM_R@ +-# if !@HAVE_RANDOM_R@ ++# if @REPLACE_RANDOM_R@ ++# if !(defined __cplusplus && defined GNULIB_NAMESPACE) ++# undef random_r ++# define random_r rpl_random_r ++# endif ++_GL_FUNCDECL_RPL (random_r, int, (struct random_data *buf, int32_t *result) ++ _GL_ARG_NONNULL ((1, 2))); ++_GL_CXXALIAS_RPL (random_r, int, (struct random_data *buf, int32_t *result)); ++# else ++# if !@HAVE_RANDOM_R@ + _GL_FUNCDECL_SYS (random_r, int, (struct random_data *buf, int32_t *result) + _GL_ARG_NONNULL ((1, 2))); +-# endif ++# endif + _GL_CXXALIAS_SYS (random_r, int, (struct random_data *buf, int32_t *result)); ++# endif + _GL_CXXALIASWARN (random_r); + #elif defined GNULIB_POSIXCHECK + # undef random_r +@@ -451,13 +616,25 @@ _GL_WARN_ON_USE (random_r, "random_r is unportable - " + #endif + + #if @GNULIB_RANDOM_R@ +-# if !@HAVE_RANDOM_R@ ++# if @REPLACE_RANDOM_R@ ++# if !(defined __cplusplus && defined GNULIB_NAMESPACE) ++# undef srandom_r ++# define srandom_r rpl_srandom_r ++# endif ++_GL_FUNCDECL_RPL (srandom_r, int, ++ (unsigned int seed, struct random_data *rand_state) ++ _GL_ARG_NONNULL ((2))); ++_GL_CXXALIAS_RPL (srandom_r, int, ++ (unsigned int seed, struct random_data *rand_state)); ++# else ++# if !@HAVE_RANDOM_R@ + _GL_FUNCDECL_SYS (srandom_r, int, + (unsigned int seed, struct random_data *rand_state) + _GL_ARG_NONNULL ((2))); +-# endif ++# endif + _GL_CXXALIAS_SYS (srandom_r, int, + (unsigned int seed, struct random_data *rand_state)); ++# endif + _GL_CXXALIASWARN (srandom_r); + #elif defined GNULIB_POSIXCHECK + # undef srandom_r +@@ -468,15 +645,29 @@ _GL_WARN_ON_USE (srandom_r, "srandom_r is unportable - " + #endif + + #if @GNULIB_RANDOM_R@ +-# if !@HAVE_RANDOM_R@ ++# if @REPLACE_RANDOM_R@ ++# if !(defined __cplusplus && defined GNULIB_NAMESPACE) ++# undef initstate_r ++# define initstate_r rpl_initstate_r ++# endif ++_GL_FUNCDECL_RPL (initstate_r, int, ++ (unsigned int seed, char *buf, size_t buf_size, ++ struct random_data *rand_state) ++ _GL_ARG_NONNULL ((2, 4))); ++_GL_CXXALIAS_RPL (initstate_r, int, ++ (unsigned int seed, char *buf, size_t buf_size, ++ struct random_data *rand_state)); ++# else ++# if !@HAVE_RANDOM_R@ + _GL_FUNCDECL_SYS (initstate_r, int, + (unsigned int seed, char *buf, size_t buf_size, + struct random_data *rand_state) + _GL_ARG_NONNULL ((2, 4))); +-# endif ++# endif + _GL_CXXALIAS_SYS (initstate_r, int, + (unsigned int seed, char *buf, size_t buf_size, + struct random_data *rand_state)); ++# endif + _GL_CXXALIASWARN (initstate_r); + #elif defined GNULIB_POSIXCHECK + # undef initstate_r +@@ -487,13 +678,25 @@ _GL_WARN_ON_USE (initstate_r, "initstate_r is unportable - " + #endif + + #if @GNULIB_RANDOM_R@ +-# if !@HAVE_RANDOM_R@ ++# if @REPLACE_RANDOM_R@ ++# if !(defined __cplusplus && defined GNULIB_NAMESPACE) ++# undef setstate_r ++# define setstate_r rpl_setstate_r ++# endif ++_GL_FUNCDECL_RPL (setstate_r, int, ++ (char *arg_state, struct random_data *rand_state) ++ _GL_ARG_NONNULL ((1, 2))); ++_GL_CXXALIAS_RPL (setstate_r, int, ++ (char *arg_state, struct random_data *rand_state)); ++# else ++# if !@HAVE_RANDOM_R@ + _GL_FUNCDECL_SYS (setstate_r, int, + (char *arg_state, struct random_data *rand_state) + _GL_ARG_NONNULL ((1, 2))); +-# endif ++# endif + _GL_CXXALIAS_SYS (setstate_r, int, + (char *arg_state, struct random_data *rand_state)); ++# endif + _GL_CXXALIASWARN (setstate_r); + #elif defined GNULIB_POSIXCHECK + # undef setstate_r +@@ -506,7 +709,8 @@ _GL_WARN_ON_USE (setstate_r, "setstate_r is unportable - " + + #if @GNULIB_REALLOC_POSIX@ + # if @REPLACE_REALLOC@ +-# if !(defined __cplusplus && defined GNULIB_NAMESPACE) ++# if !((defined __cplusplus && defined GNULIB_NAMESPACE) \ ++ || _GL_USE_STDLIB_ALLOC) + # undef realloc + # define realloc rpl_realloc + # endif +@@ -516,7 +720,7 @@ _GL_CXXALIAS_RPL (realloc, void *, (void *ptr, size_t size)); + _GL_CXXALIAS_SYS (realloc, void *, (void *ptr, size_t size)); + # endif + _GL_CXXALIASWARN (realloc); +-#elif defined GNULIB_POSIXCHECK ++#elif defined GNULIB_POSIXCHECK && !_GL_USE_STDLIB_ALLOC + # undef realloc + /* Assume realloc is always declared. */ + _GL_WARN_ON_USE (realloc, "realloc is not POSIX compliant everywhere - " +@@ -563,6 +767,22 @@ _GL_WARN_ON_USE (rpmatch, "rpmatch is unportable - " + # endif + #endif + ++#if @GNULIB_SECURE_GETENV@ ++/* Look up NAME in the environment, returning 0 in insecure situations. */ ++# if !@HAVE_SECURE_GETENV@ ++_GL_FUNCDECL_SYS (secure_getenv, char *, ++ (char const *name) _GL_ARG_NONNULL ((1))); ++# endif ++_GL_CXXALIAS_SYS (secure_getenv, char *, (char const *name)); ++_GL_CXXALIASWARN (secure_getenv); ++#elif defined GNULIB_POSIXCHECK ++# undef secure_getenv ++# if HAVE_RAW_DECL_SECURE_GETENV ++_GL_WARN_ON_USE (secure_getenv, "secure_getenv is unportable - " ++ "use gnulib module secure_getenv for portability"); ++# endif ++#endif ++ + #if @GNULIB_SETENV@ + /* Set NAME to VALUE in the environment. + If REPLACE is nonzero, overwrite an existing value. */ +@@ -577,7 +797,7 @@ _GL_FUNCDECL_RPL (setenv, int, + _GL_CXXALIAS_RPL (setenv, int, + (const char *name, const char *value, int replace)); + # else +-# if !@HAVE_SETENV@ ++# if !@HAVE_DECL_SETENV@ + _GL_FUNCDECL_SYS (setenv, int, + (const char *name, const char *value, int replace) + _GL_ARG_NONNULL ((1))); +@@ -585,7 +805,9 @@ _GL_FUNCDECL_SYS (setenv, int, + _GL_CXXALIAS_SYS (setenv, int, + (const char *name, const char *value, int replace)); + # endif ++# if !(@REPLACE_SETENV@ && !@HAVE_DECL_SETENV@) + _GL_CXXALIASWARN (setenv); ++# endif + #elif defined GNULIB_POSIXCHECK + # undef setenv + # if HAVE_RAW_DECL_SETENV +@@ -695,12 +917,14 @@ _GL_WARN_ON_USE (unlockpt, "unlockpt is not portable - " + _GL_FUNCDECL_RPL (unsetenv, int, (const char *name) _GL_ARG_NONNULL ((1))); + _GL_CXXALIAS_RPL (unsetenv, int, (const char *name)); + # else +-# if !@HAVE_UNSETENV@ ++# if !@HAVE_DECL_UNSETENV@ + _GL_FUNCDECL_SYS (unsetenv, int, (const char *name) _GL_ARG_NONNULL ((1))); + # endif + _GL_CXXALIAS_SYS (unsetenv, int, (const char *name)); + # endif ++# if !(@REPLACE_UNSETENV@ && !@HAVE_DECL_UNSETENV@) + _GL_CXXALIASWARN (unsetenv); ++# endif + #elif defined GNULIB_POSIXCHECK + # undef unsetenv + # if HAVE_RAW_DECL_UNSETENV +@@ -709,7 +933,22 @@ _GL_WARN_ON_USE (unsetenv, "unsetenv is unportable - " + # endif + #endif + ++/* Convert a wide character to a multibyte character. */ ++#if @GNULIB_WCTOMB@ ++# if @REPLACE_WCTOMB@ ++# if !(defined __cplusplus && defined GNULIB_NAMESPACE) ++# undef wctomb ++# define wctomb rpl_wctomb ++# endif ++_GL_FUNCDECL_RPL (wctomb, int, (char *s, wchar_t wc)); ++_GL_CXXALIAS_RPL (wctomb, int, (char *s, wchar_t wc)); ++# else ++_GL_CXXALIAS_SYS (wctomb, int, (char *s, wchar_t wc)); ++# endif ++_GL_CXXALIASWARN (wctomb); ++#endif ++ + +-#endif /* _GL_STDLIB_H */ +-#endif /* _GL_STDLIB_H */ ++#endif /* _@GUARD_PREFIX@_STDLIB_H */ ++#endif /* _@GUARD_PREFIX@_STDLIB_H */ + #endif +diff --git a/grub-core/gnulib/strcasecmp.c b/grub-core/gnulib/strcasecmp.c +index 612c80f..0f0a742 100644 +--- a/grub-core/gnulib/strcasecmp.c ++++ b/grub-core/gnulib/strcasecmp.c +@@ -1,5 +1,5 @@ + /* Case-insensitive string comparison function. +- Copyright (C) 1998-1999, 2005-2007, 2009-2010 Free Software Foundation, Inc. ++ Copyright (C) 1998-1999, 2005-2007, 2009-2013 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 +@@ -12,8 +12,7 @@ + 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. */ ++ along with this program; if not, see . */ + + #include + +diff --git a/grub-core/gnulib/strchrnul.c b/grub-core/gnulib/strchrnul.c +index f834d34..f6b0722 100644 +--- a/grub-core/gnulib/strchrnul.c ++++ b/grub-core/gnulib/strchrnul.c +@@ -1,5 +1,5 @@ + /* Searching in a string. +- Copyright (C) 2003, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. ++ Copyright (C) 2003, 2007-2013 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 +diff --git a/grub-core/gnulib/streq.h b/grub-core/gnulib/streq.h +index aa65bb8..12c1867 100644 +--- a/grub-core/gnulib/streq.h ++++ b/grub-core/gnulib/streq.h +@@ -1,5 +1,5 @@ + /* Optimized string comparison. +- Copyright (C) 2001-2002, 2007, 2009-2010 Free Software Foundation, Inc. ++ Copyright (C) 2001-2002, 2007, 2009-2013 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 +@@ -9,7 +9,7 @@ + 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 +- Lesser General Public License for more details. ++ 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 . */ +@@ -21,8 +21,8 @@ + + #include + +-/* STREQ allows to optimize string comparison with a small literal string. +- STREQ (s, "EUC-KR", 'E', 'U', 'C', '-', 'K', 'R', 0, 0, 0) ++/* STREQ_OPT allows to optimize string comparison with a small literal string. ++ STREQ_OPT (s, "EUC-KR", 'E', 'U', 'C', '-', 'K', 'R', 0, 0, 0) + is semantically equivalent to + strcmp (s, "EUC-KR") == 0 + just faster. */ +@@ -163,12 +163,12 @@ streq0 (const char *s1, const char *s2, char s20, char s21, char s22, char s23, + return 0; + } + +-#define STREQ(s1,s2,s20,s21,s22,s23,s24,s25,s26,s27,s28) \ ++#define STREQ_OPT(s1,s2,s20,s21,s22,s23,s24,s25,s26,s27,s28) \ + streq0 (s1, s2, s20, s21, s22, s23, s24, s25, s26, s27, s28) + + #else + +-#define STREQ(s1,s2,s20,s21,s22,s23,s24,s25,s26,s27,s28) \ ++#define STREQ_OPT(s1,s2,s20,s21,s22,s23,s24,s25,s26,s27,s28) \ + (strcmp (s1, s2) == 0) + + #endif +diff --git a/grub-core/gnulib/strerror-override.c b/grub-core/gnulib/strerror-override.c +new file mode 100644 +index 0000000..d0ed2fb +--- /dev/null ++++ b/grub-core/gnulib/strerror-override.c +@@ -0,0 +1,302 @@ ++/* strerror-override.c --- POSIX compatible system error routine ++ ++ Copyright (C) 2010-2013 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 . */ ++ ++/* Written by Bruno Haible , 2010. */ ++ ++#include ++ ++#include "strerror-override.h" ++ ++#include ++ ++#if GNULIB_defined_EWINSOCK /* native Windows platforms */ ++# if HAVE_WINSOCK2_H ++# include ++# endif ++#endif ++ ++/* If ERRNUM maps to an errno value defined by gnulib, return a string ++ describing the error. Otherwise return NULL. */ ++const char * ++strerror_override (int errnum) ++{ ++ /* These error messages are taken from glibc/sysdeps/gnu/errlist.c. */ ++ switch (errnum) ++ { ++#if REPLACE_STRERROR_0 ++ case 0: ++ return "Success"; ++#endif ++ ++#if GNULIB_defined_ESOCK /* native Windows platforms with older */ ++ case EINPROGRESS: ++ return "Operation now in progress"; ++ case EALREADY: ++ return "Operation already in progress"; ++ case ENOTSOCK: ++ return "Socket operation on non-socket"; ++ case EDESTADDRREQ: ++ return "Destination address required"; ++ case EMSGSIZE: ++ return "Message too long"; ++ case EPROTOTYPE: ++ return "Protocol wrong type for socket"; ++ case ENOPROTOOPT: ++ return "Protocol not available"; ++ case EPROTONOSUPPORT: ++ return "Protocol not supported"; ++ case EOPNOTSUPP: ++ return "Operation not supported"; ++ case EAFNOSUPPORT: ++ return "Address family not supported by protocol"; ++ case EADDRINUSE: ++ return "Address already in use"; ++ case EADDRNOTAVAIL: ++ return "Cannot assign requested address"; ++ case ENETDOWN: ++ return "Network is down"; ++ case ENETUNREACH: ++ return "Network is unreachable"; ++ case ECONNRESET: ++ return "Connection reset by peer"; ++ case ENOBUFS: ++ return "No buffer space available"; ++ case EISCONN: ++ return "Transport endpoint is already connected"; ++ case ENOTCONN: ++ return "Transport endpoint is not connected"; ++ case ETIMEDOUT: ++ return "Connection timed out"; ++ case ECONNREFUSED: ++ return "Connection refused"; ++ case ELOOP: ++ return "Too many levels of symbolic links"; ++ case EHOSTUNREACH: ++ return "No route to host"; ++ case EWOULDBLOCK: ++ return "Operation would block"; ++#endif ++#if GNULIB_defined_ESTREAMS /* native Windows platforms with older */ ++ case ETXTBSY: ++ return "Text file busy"; ++ case ENODATA: ++ return "No data available"; ++ case ENOSR: ++ return "Out of streams resources"; ++ case ENOSTR: ++ return "Device not a stream"; ++ case ETIME: ++ return "Timer expired"; ++ case EOTHER: ++ return "Other error"; ++#endif ++#if GNULIB_defined_EWINSOCK /* native Windows platforms */ ++ case ESOCKTNOSUPPORT: ++ return "Socket type not supported"; ++ case EPFNOSUPPORT: ++ return "Protocol family not supported"; ++ case ESHUTDOWN: ++ return "Cannot send after transport endpoint shutdown"; ++ case ETOOMANYREFS: ++ return "Too many references: cannot splice"; ++ case EHOSTDOWN: ++ return "Host is down"; ++ case EPROCLIM: ++ return "Too many processes"; ++ case EUSERS: ++ return "Too many users"; ++ case EDQUOT: ++ return "Disk quota exceeded"; ++ case ESTALE: ++ return "Stale NFS file handle"; ++ case EREMOTE: ++ return "Object is remote"; ++# if HAVE_WINSOCK2_H ++ /* WSA_INVALID_HANDLE maps to EBADF */ ++ /* WSA_NOT_ENOUGH_MEMORY maps to ENOMEM */ ++ /* WSA_INVALID_PARAMETER maps to EINVAL */ ++ case WSA_OPERATION_ABORTED: ++ return "Overlapped operation aborted"; ++ case WSA_IO_INCOMPLETE: ++ return "Overlapped I/O event object not in signaled state"; ++ case WSA_IO_PENDING: ++ return "Overlapped operations will complete later"; ++ /* WSAEINTR maps to EINTR */ ++ /* WSAEBADF maps to EBADF */ ++ /* WSAEACCES maps to EACCES */ ++ /* WSAEFAULT maps to EFAULT */ ++ /* WSAEINVAL maps to EINVAL */ ++ /* WSAEMFILE maps to EMFILE */ ++ /* WSAEWOULDBLOCK maps to EWOULDBLOCK */ ++ /* WSAEINPROGRESS maps to EINPROGRESS */ ++ /* WSAEALREADY maps to EALREADY */ ++ /* WSAENOTSOCK maps to ENOTSOCK */ ++ /* WSAEDESTADDRREQ maps to EDESTADDRREQ */ ++ /* WSAEMSGSIZE maps to EMSGSIZE */ ++ /* WSAEPROTOTYPE maps to EPROTOTYPE */ ++ /* WSAENOPROTOOPT maps to ENOPROTOOPT */ ++ /* WSAEPROTONOSUPPORT maps to EPROTONOSUPPORT */ ++ /* WSAESOCKTNOSUPPORT is ESOCKTNOSUPPORT */ ++ /* WSAEOPNOTSUPP maps to EOPNOTSUPP */ ++ /* WSAEPFNOSUPPORT is EPFNOSUPPORT */ ++ /* WSAEAFNOSUPPORT maps to EAFNOSUPPORT */ ++ /* WSAEADDRINUSE maps to EADDRINUSE */ ++ /* WSAEADDRNOTAVAIL maps to EADDRNOTAVAIL */ ++ /* WSAENETDOWN maps to ENETDOWN */ ++ /* WSAENETUNREACH maps to ENETUNREACH */ ++ /* WSAENETRESET maps to ENETRESET */ ++ /* WSAECONNABORTED maps to ECONNABORTED */ ++ /* WSAECONNRESET maps to ECONNRESET */ ++ /* WSAENOBUFS maps to ENOBUFS */ ++ /* WSAEISCONN maps to EISCONN */ ++ /* WSAENOTCONN maps to ENOTCONN */ ++ /* WSAESHUTDOWN is ESHUTDOWN */ ++ /* WSAETOOMANYREFS is ETOOMANYREFS */ ++ /* WSAETIMEDOUT maps to ETIMEDOUT */ ++ /* WSAECONNREFUSED maps to ECONNREFUSED */ ++ /* WSAELOOP maps to ELOOP */ ++ /* WSAENAMETOOLONG maps to ENAMETOOLONG */ ++ /* WSAEHOSTDOWN is EHOSTDOWN */ ++ /* WSAEHOSTUNREACH maps to EHOSTUNREACH */ ++ /* WSAENOTEMPTY maps to ENOTEMPTY */ ++ /* WSAEPROCLIM is EPROCLIM */ ++ /* WSAEUSERS is EUSERS */ ++ /* WSAEDQUOT is EDQUOT */ ++ /* WSAESTALE is ESTALE */ ++ /* WSAEREMOTE is EREMOTE */ ++ case WSASYSNOTREADY: ++ return "Network subsystem is unavailable"; ++ case WSAVERNOTSUPPORTED: ++ return "Winsock.dll version out of range"; ++ case WSANOTINITIALISED: ++ return "Successful WSAStartup not yet performed"; ++ case WSAEDISCON: ++ return "Graceful shutdown in progress"; ++ case WSAENOMORE: case WSA_E_NO_MORE: ++ return "No more results"; ++ case WSAECANCELLED: case WSA_E_CANCELLED: ++ return "Call was canceled"; ++ case WSAEINVALIDPROCTABLE: ++ return "Procedure call table is invalid"; ++ case WSAEINVALIDPROVIDER: ++ return "Service provider is invalid"; ++ case WSAEPROVIDERFAILEDINIT: ++ return "Service provider failed to initialize"; ++ case WSASYSCALLFAILURE: ++ return "System call failure"; ++ case WSASERVICE_NOT_FOUND: ++ return "Service not found"; ++ case WSATYPE_NOT_FOUND: ++ return "Class type not found"; ++ case WSAEREFUSED: ++ return "Database query was refused"; ++ case WSAHOST_NOT_FOUND: ++ return "Host not found"; ++ case WSATRY_AGAIN: ++ return "Nonauthoritative host not found"; ++ case WSANO_RECOVERY: ++ return "Nonrecoverable error"; ++ case WSANO_DATA: ++ return "Valid name, no data record of requested type"; ++ /* WSA_QOS_* omitted */ ++# endif ++#endif ++ ++#if GNULIB_defined_ENOMSG ++ case ENOMSG: ++ return "No message of desired type"; ++#endif ++ ++#if GNULIB_defined_EIDRM ++ case EIDRM: ++ return "Identifier removed"; ++#endif ++ ++#if GNULIB_defined_ENOLINK ++ case ENOLINK: ++ return "Link has been severed"; ++#endif ++ ++#if GNULIB_defined_EPROTO ++ case EPROTO: ++ return "Protocol error"; ++#endif ++ ++#if GNULIB_defined_EMULTIHOP ++ case EMULTIHOP: ++ return "Multihop attempted"; ++#endif ++ ++#if GNULIB_defined_EBADMSG ++ case EBADMSG: ++ return "Bad message"; ++#endif ++ ++#if GNULIB_defined_EOVERFLOW ++ case EOVERFLOW: ++ return "Value too large for defined data type"; ++#endif ++ ++#if GNULIB_defined_ENOTSUP ++ case ENOTSUP: ++ return "Not supported"; ++#endif ++ ++#if GNULIB_defined_ENETRESET ++ case ENETRESET: ++ return "Network dropped connection on reset"; ++#endif ++ ++#if GNULIB_defined_ECONNABORTED ++ case ECONNABORTED: ++ return "Software caused connection abort"; ++#endif ++ ++#if GNULIB_defined_ESTALE ++ case ESTALE: ++ return "Stale NFS file handle"; ++#endif ++ ++#if GNULIB_defined_EDQUOT ++ case EDQUOT: ++ return "Disk quota exceeded"; ++#endif ++ ++#if GNULIB_defined_ECANCELED ++ case ECANCELED: ++ return "Operation canceled"; ++#endif ++ ++#if GNULIB_defined_EOWNERDEAD ++ case EOWNERDEAD: ++ return "Owner died"; ++#endif ++ ++#if GNULIB_defined_ENOTRECOVERABLE ++ case ENOTRECOVERABLE: ++ return "State not recoverable"; ++#endif ++ ++#if GNULIB_defined_EILSEQ ++ case EILSEQ: ++ return "Invalid or incomplete multibyte or wide character"; ++#endif ++ ++ default: ++ return NULL; ++ } ++} +diff --git a/grub-core/gnulib/strerror-override.h b/grub-core/gnulib/strerror-override.h +new file mode 100644 +index 0000000..3b8f24b +--- /dev/null ++++ b/grub-core/gnulib/strerror-override.h +@@ -0,0 +1,56 @@ ++/* strerror-override.h --- POSIX compatible system error routine ++ ++ Copyright (C) 2010-2013 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 _GL_STRERROR_OVERRIDE_H ++# define _GL_STRERROR_OVERRIDE_H ++ ++# include ++# include ++ ++/* Reasonable buffer size that should never trigger ERANGE; if this ++ proves too small, we intentionally abort(), to remind us to fix ++ this value. */ ++# define STACKBUF_LEN 256 ++ ++/* If ERRNUM maps to an errno value defined by gnulib, return a string ++ describing the error. Otherwise return NULL. */ ++# if REPLACE_STRERROR_0 \ ++ || GNULIB_defined_ESOCK \ ++ || GNULIB_defined_ESTREAMS \ ++ || GNULIB_defined_EWINSOCK \ ++ || GNULIB_defined_ENOMSG \ ++ || GNULIB_defined_EIDRM \ ++ || GNULIB_defined_ENOLINK \ ++ || GNULIB_defined_EPROTO \ ++ || GNULIB_defined_EMULTIHOP \ ++ || GNULIB_defined_EBADMSG \ ++ || GNULIB_defined_EOVERFLOW \ ++ || GNULIB_defined_ENOTSUP \ ++ || GNULIB_defined_ENETRESET \ ++ || GNULIB_defined_ECONNABORTED \ ++ || GNULIB_defined_ESTALE \ ++ || GNULIB_defined_EDQUOT \ ++ || GNULIB_defined_ECANCELED \ ++ || GNULIB_defined_EOWNERDEAD \ ++ || GNULIB_defined_ENOTRECOVERABLE \ ++ || GNULIB_defined_EILSEQ ++extern const char *strerror_override (int errnum); ++# else ++# define strerror_override(ignored) NULL ++# endif ++ ++#endif /* _GL_STRERROR_OVERRIDE_H */ +diff --git a/grub-core/gnulib/strerror.c b/grub-core/gnulib/strerror.c +index 46153ab..80a2f2e 100644 +--- a/grub-core/gnulib/strerror.c ++++ b/grub-core/gnulib/strerror.c +@@ -1,6 +1,6 @@ + /* strerror.c --- POSIX compatible system error routine + +- Copyright (C) 2007-2010 Free Software Foundation, Inc. ++ Copyright (C) 2007-2013 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 +@@ -17,334 +17,54 @@ + + #include + ++/* Specification. */ + #include + +-#if REPLACE_STRERROR +- +-# include +-# include +- +-# if GNULIB_defined_ESOCK /* native Windows platforms */ +-# if HAVE_WINSOCK2_H +-# include +-# endif +-# endif ++#include ++#include ++#include ++#include + +-# include "intprops.h" ++#include "intprops.h" ++#include "strerror-override.h" ++#include "verify.h" + + /* Use the system functions, not the gnulib overrides in this file. */ +-# undef sprintf +- +-# undef strerror +-# if ! HAVE_DECL_STRERROR +-# define strerror(n) NULL +-# endif ++#undef sprintf + + char * +-rpl_strerror (int n) ++strerror (int n) ++#undef strerror + { +- char const *msg = NULL; +- /* These error messages are taken from glibc/sysdeps/gnu/errlist.c. */ +- switch (n) +- { +-# if GNULIB_defined_ETXTBSY +- case ETXTBSY: +- msg = "Text file busy"; +- break; +-# endif +- +-# if GNULIB_defined_ESOCK /* native Windows platforms */ +- /* EWOULDBLOCK is the same as EAGAIN. */ +- case EINPROGRESS: +- msg = "Operation now in progress"; +- break; +- case EALREADY: +- msg = "Operation already in progress"; +- break; +- case ENOTSOCK: +- msg = "Socket operation on non-socket"; +- break; +- case EDESTADDRREQ: +- msg = "Destination address required"; +- break; +- case EMSGSIZE: +- msg = "Message too long"; +- break; +- case EPROTOTYPE: +- msg = "Protocol wrong type for socket"; +- break; +- case ENOPROTOOPT: +- msg = "Protocol not available"; +- break; +- case EPROTONOSUPPORT: +- msg = "Protocol not supported"; +- break; +- case ESOCKTNOSUPPORT: +- msg = "Socket type not supported"; +- break; +- case EOPNOTSUPP: +- msg = "Operation not supported"; +- break; +- case EPFNOSUPPORT: +- msg = "Protocol family not supported"; +- break; +- case EAFNOSUPPORT: +- msg = "Address family not supported by protocol"; +- break; +- case EADDRINUSE: +- msg = "Address already in use"; +- break; +- case EADDRNOTAVAIL: +- msg = "Cannot assign requested address"; +- break; +- case ENETDOWN: +- msg = "Network is down"; +- break; +- case ENETUNREACH: +- msg = "Network is unreachable"; +- break; +- case ENETRESET: +- msg = "Network dropped connection on reset"; +- break; +- case ECONNABORTED: +- msg = "Software caused connection abort"; +- break; +- case ECONNRESET: +- msg = "Connection reset by peer"; +- break; +- case ENOBUFS: +- msg = "No buffer space available"; +- break; +- case EISCONN: +- msg = "Transport endpoint is already connected"; +- break; +- case ENOTCONN: +- msg = "Transport endpoint is not connected"; +- break; +- case ESHUTDOWN: +- msg = "Cannot send after transport endpoint shutdown"; +- break; +- case ETOOMANYREFS: +- msg = "Too many references: cannot splice"; +- break; +- case ETIMEDOUT: +- msg = "Connection timed out"; +- break; +- case ECONNREFUSED: +- msg = "Connection refused"; +- break; +- case ELOOP: +- msg = "Too many levels of symbolic links"; +- break; +- case EHOSTDOWN: +- msg = "Host is down"; +- break; +- case EHOSTUNREACH: +- msg = "No route to host"; +- break; +- case EPROCLIM: +- msg = "Too many processes"; +- break; +- case EUSERS: +- msg = "Too many users"; +- break; +- case EDQUOT: +- msg = "Disk quota exceeded"; +- break; +- case ESTALE: +- msg = "Stale NFS file handle"; +- break; +- case EREMOTE: +- msg = "Object is remote"; +- break; +-# if HAVE_WINSOCK2_H +- /* WSA_INVALID_HANDLE maps to EBADF */ +- /* WSA_NOT_ENOUGH_MEMORY maps to ENOMEM */ +- /* WSA_INVALID_PARAMETER maps to EINVAL */ +- case WSA_OPERATION_ABORTED: +- msg = "Overlapped operation aborted"; +- break; +- case WSA_IO_INCOMPLETE: +- msg = "Overlapped I/O event object not in signaled state"; +- break; +- case WSA_IO_PENDING: +- msg = "Overlapped operations will complete later"; +- break; +- /* WSAEINTR maps to EINTR */ +- /* WSAEBADF maps to EBADF */ +- /* WSAEACCES maps to EACCES */ +- /* WSAEFAULT maps to EFAULT */ +- /* WSAEINVAL maps to EINVAL */ +- /* WSAEMFILE maps to EMFILE */ +- /* WSAEWOULDBLOCK maps to EWOULDBLOCK */ +- /* WSAEINPROGRESS is EINPROGRESS */ +- /* WSAEALREADY is EALREADY */ +- /* WSAENOTSOCK is ENOTSOCK */ +- /* WSAEDESTADDRREQ is EDESTADDRREQ */ +- /* WSAEMSGSIZE is EMSGSIZE */ +- /* WSAEPROTOTYPE is EPROTOTYPE */ +- /* WSAENOPROTOOPT is ENOPROTOOPT */ +- /* WSAEPROTONOSUPPORT is EPROTONOSUPPORT */ +- /* WSAESOCKTNOSUPPORT is ESOCKTNOSUPPORT */ +- /* WSAEOPNOTSUPP is EOPNOTSUPP */ +- /* WSAEPFNOSUPPORT is EPFNOSUPPORT */ +- /* WSAEAFNOSUPPORT is EAFNOSUPPORT */ +- /* WSAEADDRINUSE is EADDRINUSE */ +- /* WSAEADDRNOTAVAIL is EADDRNOTAVAIL */ +- /* WSAENETDOWN is ENETDOWN */ +- /* WSAENETUNREACH is ENETUNREACH */ +- /* WSAENETRESET is ENETRESET */ +- /* WSAECONNABORTED is ECONNABORTED */ +- /* WSAECONNRESET is ECONNRESET */ +- /* WSAENOBUFS is ENOBUFS */ +- /* WSAEISCONN is EISCONN */ +- /* WSAENOTCONN is ENOTCONN */ +- /* WSAESHUTDOWN is ESHUTDOWN */ +- /* WSAETOOMANYREFS is ETOOMANYREFS */ +- /* WSAETIMEDOUT is ETIMEDOUT */ +- /* WSAECONNREFUSED is ECONNREFUSED */ +- /* WSAELOOP is ELOOP */ +- /* WSAENAMETOOLONG maps to ENAMETOOLONG */ +- /* WSAEHOSTDOWN is EHOSTDOWN */ +- /* WSAEHOSTUNREACH is EHOSTUNREACH */ +- /* WSAENOTEMPTY maps to ENOTEMPTY */ +- /* WSAEPROCLIM is EPROCLIM */ +- /* WSAEUSERS is EUSERS */ +- /* WSAEDQUOT is EDQUOT */ +- /* WSAESTALE is ESTALE */ +- /* WSAEREMOTE is EREMOTE */ +- case WSASYSNOTREADY: +- msg = "Network subsystem is unavailable"; +- break; +- case WSAVERNOTSUPPORTED: +- msg = "Winsock.dll version out of range"; +- break; +- case WSANOTINITIALISED: +- msg = "Successful WSAStartup not yet performed"; +- break; +- case WSAEDISCON: +- msg = "Graceful shutdown in progress"; +- break; +- case WSAENOMORE: case WSA_E_NO_MORE: +- msg = "No more results"; +- break; +- case WSAECANCELLED: case WSA_E_CANCELLED: +- msg = "Call was canceled"; +- break; +- case WSAEINVALIDPROCTABLE: +- msg = "Procedure call table is invalid"; +- break; +- case WSAEINVALIDPROVIDER: +- msg = "Service provider is invalid"; +- break; +- case WSAEPROVIDERFAILEDINIT: +- msg = "Service provider failed to initialize"; +- break; +- case WSASYSCALLFAILURE: +- msg = "System call failure"; +- break; +- case WSASERVICE_NOT_FOUND: +- msg = "Service not found"; +- break; +- case WSATYPE_NOT_FOUND: +- msg = "Class type not found"; +- break; +- case WSAEREFUSED: +- msg = "Database query was refused"; +- break; +- case WSAHOST_NOT_FOUND: +- msg = "Host not found"; +- break; +- case WSATRY_AGAIN: +- msg = "Nonauthoritative host not found"; +- break; +- case WSANO_RECOVERY: +- msg = "Nonrecoverable error"; +- break; +- case WSANO_DATA: +- msg = "Valid name, no data record of requested type"; +- break; +- /* WSA_QOS_* omitted */ +-# endif +-# endif +- +-# if GNULIB_defined_ENOMSG +- case ENOMSG: +- msg = "No message of desired type"; +- break; +-# endif +- +-# if GNULIB_defined_EIDRM +- case EIDRM: +- msg = "Identifier removed"; +- break; +-# endif +- +-# if GNULIB_defined_ENOLINK +- case ENOLINK: +- msg = "Link has been severed"; +- break; +-# endif +- +-# if GNULIB_defined_EPROTO +- case EPROTO: +- msg = "Protocol error"; +- break; +-# endif +- +-# if GNULIB_defined_EMULTIHOP +- case EMULTIHOP: +- msg = "Multihop attempted"; +- break; +-# endif +- +-# if GNULIB_defined_EBADMSG +- case EBADMSG: +- msg = "Bad message"; +- break; +-# endif +- +-# if GNULIB_defined_EOVERFLOW +- case EOVERFLOW: +- msg = "Value too large for defined data type"; +- break; +-# endif +- +-# if GNULIB_defined_ENOTSUP +- case ENOTSUP: +- msg = "Not supported"; +- break; +-# endif +- +-# if GNULIB_defined_ESTALE +- case ESTALE: +- msg = "Stale NFS file handle"; +- break; +-# endif +- +-# if GNULIB_defined_ECANCELED +- case ECANCELED: +- msg = "Operation canceled"; +- break; +-# endif +- } ++ static char buf[STACKBUF_LEN]; ++ size_t len; + ++ /* Cast away const, due to the historical signature of strerror; ++ callers should not be modifying the string. */ ++ const char *msg = strerror_override (n); + if (msg) + return (char *) msg; + +- { +- char *result = strerror (n); ++ msg = strerror (n); + +- if (result == NULL || result[0] == '\0') +- { +- static char const fmt[] = "Unknown error (%d)"; +- static char msg_buf[sizeof fmt + INT_STRLEN_BOUND (n)]; +- sprintf (msg_buf, fmt, n); +- return msg_buf; +- } ++ /* Our strerror_r implementation might use the system's strerror ++ buffer, so all other clients of strerror have to see the error ++ copied into a buffer that we manage. This is not thread-safe, ++ even if the system strerror is, but portable programs shouldn't ++ be using strerror if they care about thread-safety. */ ++ if (!msg || !*msg) ++ { ++ static char const fmt[] = "Unknown error %d"; ++ verify (sizeof buf >= sizeof (fmt) + INT_STRLEN_BOUND (n)); ++ sprintf (buf, fmt, n); ++ errno = EINVAL; ++ return buf; ++ } + +- return result; +- } +-} ++ /* Fix STACKBUF_LEN if this ever aborts. */ ++ len = strlen (msg); ++ if (sizeof buf <= len) ++ abort (); + +-#endif ++ return memcpy (buf, msg, len + 1); ++} +diff --git a/grub-core/gnulib/string.in.h b/grub-core/gnulib/string.in.h +index 49c711d..d7a6c9c 100644 +--- a/grub-core/gnulib/string.in.h ++++ b/grub-core/gnulib/string.in.h +@@ -1,6 +1,6 @@ + /* A GNU-like . + +- Copyright (C) 1995-1996, 2001-2010 Free Software Foundation, Inc. ++ Copyright (C) 1995-1996, 2001-2013 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 +@@ -13,20 +13,20 @@ + 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. */ ++ along with this program; if not, see . */ + +-#ifndef _GL_STRING_H ++#ifndef _@GUARD_PREFIX@_STRING_H + + #if __GNUC__ >= 3 + @PRAGMA_SYSTEM_HEADER@ + #endif ++@PRAGMA_COLUMNS@ + + /* The include_next requires a split double-inclusion guard. */ + #@INCLUDE_NEXT@ @NEXT_STRING_H@ + +-#ifndef _GL_STRING_H +-#define _GL_STRING_H ++#ifndef _@GUARD_PREFIX@_STRING_H ++#define _@GUARD_PREFIX@_STRING_H + + /* NetBSD 5.0 mis-defines NULL. */ + #include +@@ -36,13 +36,8 @@ + # include + #endif + +-#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 +-#endif +-/* The attribute __pure__ was added in gcc 2.96. */ ++/* The __attribute__ feature is available in gcc versions 2.5 and later. ++ The attribute __pure__ was added in gcc 2.96. */ + #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) + # define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__)) + #else +@@ -50,8 +45,8 @@ + #endif + + /* NetBSD 5.0 declares strsignal in , not in . */ +-/* But avoid namespace pollution on glibc systems. */ +-#if (@GNULIB_STRSIGNAL@ || defined GNULIB_POSIXCHECK) \ ++/* But in any case avoid namespace pollution on glibc systems. */ ++#if (@GNULIB_STRSIGNAL@ || defined GNULIB_POSIXCHECK) && defined __NetBSD__ \ + && ! defined __GLIBC__ + # include + #endif +@@ -63,6 +58,36 @@ + /* The definition of _GL_WARN_ON_USE is copied here. */ + + ++/* Find the index of the least-significant set bit. */ ++#if @GNULIB_FFSL@ ++# if !@HAVE_FFSL@ ++_GL_FUNCDECL_SYS (ffsl, int, (long int i)); ++# endif ++_GL_CXXALIAS_SYS (ffsl, int, (long int i)); ++_GL_CXXALIASWARN (ffsl); ++#elif defined GNULIB_POSIXCHECK ++# undef ffsl ++# if HAVE_RAW_DECL_FFSL ++_GL_WARN_ON_USE (ffsl, "ffsl is not portable - use the ffsl module"); ++# endif ++#endif ++ ++ ++/* Find the index of the least-significant set bit. */ ++#if @GNULIB_FFSLL@ ++# if !@HAVE_FFSLL@ ++_GL_FUNCDECL_SYS (ffsll, int, (long long int i)); ++# endif ++_GL_CXXALIAS_SYS (ffsll, int, (long long int i)); ++_GL_CXXALIASWARN (ffsll); ++#elif defined GNULIB_POSIXCHECK ++# undef ffsll ++# if HAVE_RAW_DECL_FFSLL ++_GL_WARN_ON_USE (ffsll, "ffsll is not portable - use the ffsll module"); ++# endif ++#endif ++ ++ + /* Return the first instance of C within N bytes of S, or NULL. */ + #if @GNULIB_MEMCHR@ + # if @REPLACE_MEMCHR@ +@@ -86,7 +111,7 @@ _GL_CXXALIAS_SYS_CAST2 (memchr, + void *, (void const *__s, int __c, size_t __n), + void const *, (void const *__s, int __c, size_t __n)); + # endif +-# if __GLIBC__ == 2 && __GLIBC_MINOR__ >= 10 \ ++# if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \ + && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) + _GL_CXXALIASWARN1 (memchr, void *, (void *__s, int __c, size_t __n)); + _GL_CXXALIASWARN1 (memchr, void const *, +@@ -171,7 +196,7 @@ _GL_FUNCDECL_SYS (memrchr, void *, (void const *, int, size_t) + _GL_CXXALIAS_SYS_CAST2 (memrchr, + void *, (void const *, int, size_t), + void const *, (void const *, int, size_t)); +-# if __GLIBC__ == 2 && __GLIBC_MINOR__ >= 10 \ ++# if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \ + && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) + _GL_CXXALIASWARN1 (memrchr, void *, (void *, int, size_t)); + _GL_CXXALIASWARN1 (memrchr, void const *, (void const *, int, size_t)); +@@ -201,7 +226,7 @@ _GL_FUNCDECL_SYS (rawmemchr, void *, (void const *__s, int __c_in) + _GL_CXXALIAS_SYS_CAST2 (rawmemchr, + void *, (void const *__s, int __c_in), + void const *, (void const *__s, int __c_in)); +-# if __GLIBC__ == 2 && __GLIBC_MINOR__ >= 10 \ ++# if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \ + && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) + _GL_CXXALIASWARN1 (rawmemchr, void *, (void *__s, int __c_in)); + _GL_CXXALIASWARN1 (rawmemchr, void const *, (void const *__s, int __c_in)); +@@ -281,18 +306,29 @@ _GL_WARN_ON_USE (strchr, "strchr cannot work correctly on character strings " + + /* Find the first occurrence of C in S or the final NUL byte. */ + #if @GNULIB_STRCHRNUL@ +-# if ! @HAVE_STRCHRNUL@ ++# if @REPLACE_STRCHRNUL@ ++# if !(defined __cplusplus && defined GNULIB_NAMESPACE) ++# define strchrnul rpl_strchrnul ++# endif ++_GL_FUNCDECL_RPL (strchrnul, char *, (const char *__s, int __c_in) ++ _GL_ATTRIBUTE_PURE ++ _GL_ARG_NONNULL ((1))); ++_GL_CXXALIAS_RPL (strchrnul, char *, ++ (const char *str, int ch)); ++# else ++# if ! @HAVE_STRCHRNUL@ + _GL_FUNCDECL_SYS (strchrnul, char *, (char const *__s, int __c_in) + _GL_ATTRIBUTE_PURE + _GL_ARG_NONNULL ((1))); +-# endif ++# endif + /* On some systems, this function is defined as an overloaded function: + extern "C++" { const char * std::strchrnul (const char *, int); } + extern "C++" { char * std::strchrnul (char *, int); } */ + _GL_CXXALIAS_SYS_CAST2 (strchrnul, + char *, (char const *__s, int __c_in), + char const *, (char const *__s, int __c_in)); +-# if __GLIBC__ == 2 && __GLIBC_MINOR__ >= 10 \ ++# endif ++# if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \ + && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) + _GL_CXXALIASWARN1 (strchrnul, char *, (char *__s, int __c_in)); + _GL_CXXALIASWARN1 (strchrnul, char const *, (char const *__s, int __c_in)); +@@ -438,7 +474,7 @@ _GL_FUNCDECL_SYS (strpbrk, char *, (char const *__s, char const *__accept) + _GL_CXXALIAS_SYS_CAST2 (strpbrk, + char *, (char const *__s, char const *__accept), + const char *, (char const *__s, char const *__accept)); +-# if __GLIBC__ == 2 && __GLIBC_MINOR__ >= 10 \ ++# if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \ + && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) + _GL_CXXALIASWARN1 (strpbrk, char *, (char *__s, char const *__accept)); + _GL_CXXALIASWARN1 (strpbrk, char const *, +@@ -540,7 +576,7 @@ _GL_CXXALIAS_SYS_CAST2 (strstr, + char *, (const char *haystack, const char *needle), + const char *, (const char *haystack, const char *needle)); + # endif +-# if __GLIBC__ == 2 && __GLIBC_MINOR__ >= 10 \ ++# if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \ + && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) + _GL_CXXALIASWARN1 (strstr, char *, (char *haystack, const char *needle)); + _GL_CXXALIASWARN1 (strstr, const char *, +@@ -589,7 +625,7 @@ _GL_CXXALIAS_SYS_CAST2 (strcasestr, + char *, (const char *haystack, const char *needle), + const char *, (const char *haystack, const char *needle)); + # endif +-# if __GLIBC__ == 2 && __GLIBC_MINOR__ >= 10 \ ++# if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \ + && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) + _GL_CXXALIASWARN1 (strcasestr, char *, (char *haystack, const char *needle)); + _GL_CXXALIASWARN1 (strcasestr, const char *, +@@ -688,10 +724,14 @@ _GL_WARN_ON_USE (strtok_r, "strtok_r is unportable - " + # if !(defined __cplusplus && defined GNULIB_NAMESPACE) + # define mbslen rpl_mbslen + # endif +-_GL_FUNCDECL_RPL (mbslen, size_t, (const char *string) _GL_ARG_NONNULL ((1))); ++_GL_FUNCDECL_RPL (mbslen, size_t, (const char *string) ++ _GL_ATTRIBUTE_PURE ++ _GL_ARG_NONNULL ((1))); + _GL_CXXALIAS_RPL (mbslen, size_t, (const char *string)); + # else +-_GL_FUNCDECL_SYS (mbslen, size_t, (const char *string) _GL_ARG_NONNULL ((1))); ++_GL_FUNCDECL_SYS (mbslen, size_t, (const char *string) ++ _GL_ATTRIBUTE_PURE ++ _GL_ARG_NONNULL ((1))); + _GL_CXXALIAS_SYS (mbslen, size_t, (const char *string)); + # endif + _GL_CXXALIASWARN (mbslen); +@@ -701,6 +741,7 @@ _GL_CXXALIASWARN (mbslen); + /* Return the number of multibyte characters in the character string starting + at STRING and ending at STRING + LEN. */ + _GL_EXTERN_C size_t mbsnlen (const char *string, size_t len) ++ _GL_ATTRIBUTE_PURE + _GL_ARG_NONNULL ((1)); + #endif + +@@ -714,10 +755,12 @@ _GL_EXTERN_C size_t mbsnlen (const char *string, size_t len) + # define mbschr rpl_mbschr /* avoid collision with HP-UX function */ + # endif + _GL_FUNCDECL_RPL (mbschr, char *, (const char *string, int c) ++ _GL_ATTRIBUTE_PURE + _GL_ARG_NONNULL ((1))); + _GL_CXXALIAS_RPL (mbschr, char *, (const char *string, int c)); + # else + _GL_FUNCDECL_SYS (mbschr, char *, (const char *string, int c) ++ _GL_ATTRIBUTE_PURE + _GL_ARG_NONNULL ((1))); + _GL_CXXALIAS_SYS (mbschr, char *, (const char *string, int c)); + # endif +@@ -729,15 +772,17 @@ _GL_CXXALIASWARN (mbschr); + and return a pointer to it. Return NULL if C is not found in STRING. + Unlike strrchr(), this function works correctly in multibyte locales with + encodings such as GB18030. */ +-# if defined __hpux ++# if defined __hpux || defined __INTERIX + # if !(defined __cplusplus && defined GNULIB_NAMESPACE) +-# define mbsrchr rpl_mbsrchr /* avoid collision with HP-UX function */ ++# define mbsrchr rpl_mbsrchr /* avoid collision with system function */ + # endif + _GL_FUNCDECL_RPL (mbsrchr, char *, (const char *string, int c) ++ _GL_ATTRIBUTE_PURE + _GL_ARG_NONNULL ((1))); + _GL_CXXALIAS_RPL (mbsrchr, char *, (const char *string, int c)); + # else + _GL_FUNCDECL_SYS (mbsrchr, char *, (const char *string, int c) ++ _GL_ATTRIBUTE_PURE + _GL_ARG_NONNULL ((1))); + _GL_CXXALIAS_SYS (mbsrchr, char *, (const char *string, int c)); + # endif +@@ -750,6 +795,7 @@ _GL_CXXALIASWARN (mbsrchr); + Unlike strstr(), this function works correctly in multibyte locales with + encodings different from UTF-8. */ + _GL_EXTERN_C char * mbsstr (const char *haystack, const char *needle) ++ _GL_ATTRIBUTE_PURE + _GL_ARG_NONNULL ((1, 2)); + #endif + +@@ -761,6 +807,7 @@ _GL_EXTERN_C char * mbsstr (const char *haystack, const char *needle) + different lengths! + Unlike strcasecmp(), this function works correctly in multibyte locales. */ + _GL_EXTERN_C int mbscasecmp (const char *s1, const char *s2) ++ _GL_ATTRIBUTE_PURE + _GL_ARG_NONNULL ((1, 2)); + #endif + +@@ -775,6 +822,7 @@ _GL_EXTERN_C int mbscasecmp (const char *s1, const char *s2) + Unlike strncasecmp(), this function works correctly in multibyte locales. + But beware that N is not a byte count but a character count! */ + _GL_EXTERN_C int mbsncasecmp (const char *s1, const char *s2, size_t n) ++ _GL_ATTRIBUTE_PURE + _GL_ARG_NONNULL ((1, 2)); + #endif + +@@ -788,6 +836,7 @@ _GL_EXTERN_C int mbsncasecmp (const char *s1, const char *s2, size_t n) + Unlike strncasecmp(), this function works correctly in multibyte + locales. */ + _GL_EXTERN_C char * mbspcasecmp (const char *string, const char *prefix) ++ _GL_ATTRIBUTE_PURE + _GL_ARG_NONNULL ((1, 2)); + #endif + +@@ -798,6 +847,7 @@ _GL_EXTERN_C char * mbspcasecmp (const char *string, const char *prefix) + strlen (haystack) < strlen (needle) ! + Unlike strcasestr(), this function works correctly in multibyte locales. */ + _GL_EXTERN_C char * mbscasestr (const char *haystack, const char *needle) ++ _GL_ATTRIBUTE_PURE + _GL_ARG_NONNULL ((1, 2)); + #endif + +@@ -808,6 +858,7 @@ _GL_EXTERN_C char * mbscasestr (const char *haystack, const char *needle) + if none exists. + Unlike strcspn(), this function works correctly in multibyte locales. */ + _GL_EXTERN_C size_t mbscspn (const char *string, const char *accept) ++ _GL_ATTRIBUTE_PURE + _GL_ARG_NONNULL ((1, 2)); + #endif + +@@ -821,10 +872,12 @@ _GL_EXTERN_C size_t mbscspn (const char *string, const char *accept) + # define mbspbrk rpl_mbspbrk /* avoid collision with HP-UX function */ + # endif + _GL_FUNCDECL_RPL (mbspbrk, char *, (const char *string, const char *accept) ++ _GL_ATTRIBUTE_PURE + _GL_ARG_NONNULL ((1, 2))); + _GL_CXXALIAS_RPL (mbspbrk, char *, (const char *string, const char *accept)); + # else + _GL_FUNCDECL_SYS (mbspbrk, char *, (const char *string, const char *accept) ++ _GL_ATTRIBUTE_PURE + _GL_ARG_NONNULL ((1, 2))); + _GL_CXXALIAS_SYS (mbspbrk, char *, (const char *string, const char *accept)); + # endif +@@ -838,6 +891,7 @@ _GL_CXXALIASWARN (mbspbrk); + if none exists. + Unlike strspn(), this function works correctly in multibyte locales. */ + _GL_EXTERN_C size_t mbsspn (const char *string, const char *reject) ++ _GL_ATTRIBUTE_PURE + _GL_ARG_NONNULL ((1, 2)); + #endif + +@@ -901,6 +955,35 @@ _GL_WARN_ON_USE (strerror, "strerror is unportable - " + "use gnulib module strerror to guarantee non-NULL result"); + #endif + ++/* Map any int, typically from errno, into an error message. Multithread-safe. ++ Uses the POSIX declaration, not the glibc declaration. */ ++#if @GNULIB_STRERROR_R@ ++# if @REPLACE_STRERROR_R@ ++# if !(defined __cplusplus && defined GNULIB_NAMESPACE) ++# undef strerror_r ++# define strerror_r rpl_strerror_r ++# endif ++_GL_FUNCDECL_RPL (strerror_r, int, (int errnum, char *buf, size_t buflen) ++ _GL_ARG_NONNULL ((2))); ++_GL_CXXALIAS_RPL (strerror_r, int, (int errnum, char *buf, size_t buflen)); ++# else ++# if !@HAVE_DECL_STRERROR_R@ ++_GL_FUNCDECL_SYS (strerror_r, int, (int errnum, char *buf, size_t buflen) ++ _GL_ARG_NONNULL ((2))); ++# endif ++_GL_CXXALIAS_SYS (strerror_r, int, (int errnum, char *buf, size_t buflen)); ++# endif ++# if @HAVE_DECL_STRERROR_R@ ++_GL_CXXALIASWARN (strerror_r); ++# endif ++#elif defined GNULIB_POSIXCHECK ++# undef strerror_r ++# if HAVE_RAW_DECL_STRERROR_R ++_GL_WARN_ON_USE (strerror_r, "strerror_r is unportable - " ++ "use gnulib module strerror_r-posix for portability"); ++# endif ++#endif ++ + #if @GNULIB_STRSIGNAL@ + # if @REPLACE_STRSIGNAL@ + # if !(defined __cplusplus && defined GNULIB_NAMESPACE) +@@ -928,6 +1011,7 @@ _GL_WARN_ON_USE (strsignal, "strsignal is unportable - " + #if @GNULIB_STRVERSCMP@ + # if !@HAVE_STRVERSCMP@ + _GL_FUNCDECL_SYS (strverscmp, int, (const char *, const char *) ++ _GL_ATTRIBUTE_PURE + _GL_ARG_NONNULL ((1, 2))); + # endif + _GL_CXXALIAS_SYS (strverscmp, int, (const char *, const char *)); +@@ -941,5 +1025,5 @@ _GL_WARN_ON_USE (strverscmp, "strverscmp is unportable - " + #endif + + +-#endif /* _GL_STRING_H */ +-#endif /* _GL_STRING_H */ ++#endif /* _@GUARD_PREFIX@_STRING_H */ ++#endif /* _@GUARD_PREFIX@_STRING_H */ +diff --git a/grub-core/gnulib/strings.in.h b/grub-core/gnulib/strings.in.h +index c726a16..4469f86 100644 +--- a/grub-core/gnulib/strings.in.h ++++ b/grub-core/gnulib/strings.in.h +@@ -1,6 +1,6 @@ + /* A substitute . + +- Copyright (C) 2007-2010 Free Software Foundation, Inc. ++ Copyright (C) 2007-2013 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 +@@ -13,22 +13,37 @@ + 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. */ ++ along with this program; if not, see . */ + +-#ifndef _GL_STRINGS_H ++#ifndef _@GUARD_PREFIX@_STRINGS_H + + #if __GNUC__ >= 3 + @PRAGMA_SYSTEM_HEADER@ + #endif ++@PRAGMA_COLUMNS@ ++ ++/* Minix 3.1.8 has a bug: must be included before . ++ But avoid namespace pollution on glibc systems. */ ++#if defined __minix && !defined __GLIBC__ ++# include ++#endif + + /* The include_next requires a split double-inclusion guard. */ +-#@INCLUDE_NEXT@ @NEXT_STRINGS_H@ ++#if @HAVE_STRINGS_H@ ++# @INCLUDE_NEXT@ @NEXT_STRINGS_H@ ++#endif + +-#ifndef _GL_STRINGS_H +-#define _GL_STRINGS_H ++#ifndef _@GUARD_PREFIX@_STRINGS_H ++#define _@GUARD_PREFIX@_STRINGS_H ++ ++#if ! @HAVE_DECL_STRNCASECMP@ ++/* Get size_t. */ ++# include ++#endif + + ++/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ ++ + /* The definition of _GL_ARG_NONNULL is copied here. */ + + /* The definition of _GL_WARN_ON_USE is copied here. */ +@@ -38,6 +53,20 @@ extern "C" { + #endif + + ++ /* Find the index of the least-significant set bit. */ ++#if @GNULIB_FFS@ ++# if !@HAVE_FFS@ ++_GL_FUNCDECL_SYS (ffs, int, (int i)); ++# endif ++_GL_CXXALIAS_SYS (ffs, int, (int i)); ++_GL_CXXALIASWARN (ffs); ++#elif defined GNULIB_POSIXCHECK ++# undef ffs ++# if HAVE_RAW_DECL_FFS ++_GL_WARN_ON_USE (ffs, "ffs is not portable - use the ffs module"); ++# endif ++#endif ++ + /* Compare strings S1 and S2, ignoring case, returning less than, equal to or + greater than zero if S1 is lexicographically less than, equal to or greater + than S2. +@@ -89,5 +118,5 @@ _GL_WARN_ON_USE (strncasecmp, "strncasecmp cannot work correctly on character " + } + #endif + +-#endif /* _GL_STRING_H */ +-#endif /* _GL_STRING_H */ ++#endif /* _@GUARD_PREFIX@_STRING_H */ ++#endif /* _@GUARD_PREFIX@_STRING_H */ +diff --git a/grub-core/gnulib/stripslash.c b/grub-core/gnulib/stripslash.c +index 3a5996f..0e452a9 100644 +--- a/grub-core/gnulib/stripslash.c ++++ b/grub-core/gnulib/stripslash.c +@@ -1,6 +1,6 @@ + /* stripslash.c -- remove redundant trailing slashes from a file name + +- Copyright (C) 1990, 2001, 2003-2006, 2009-2010 Free Software Foundation, ++ Copyright (C) 1990, 2001, 2003-2006, 2009-2013 Free Software Foundation, + Inc. + + This program is free software: you can redistribute it and/or modify +@@ -35,7 +35,7 @@ strip_trailing_slashes (char *file) + bool had_slash; + + /* last_component returns "" for file system roots, but we need to turn +- `///' into `/'. */ ++ "///" into "/". */ + if (! *base) + base = file; + base_lim = base + base_len (base); +diff --git a/grub-core/gnulib/strncasecmp.c b/grub-core/gnulib/strncasecmp.c +index 8c806a6..35840bc 100644 +--- a/grub-core/gnulib/strncasecmp.c ++++ b/grub-core/gnulib/strncasecmp.c +@@ -1,5 +1,5 @@ + /* strncasecmp.c -- case insensitive string comparator +- Copyright (C) 1998-1999, 2005-2007, 2009-2010 Free Software Foundation, Inc. ++ Copyright (C) 1998-1999, 2005-2007, 2009-2013 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 +@@ -12,8 +12,7 @@ + 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. */ ++ along with this program; if not, see . */ + + #include + +diff --git a/grub-core/gnulib/strndup.c b/grub-core/gnulib/strndup.c +index 3de3dbc..e60268b 100644 +--- a/grub-core/gnulib/strndup.c ++++ b/grub-core/gnulib/strndup.c +@@ -1,7 +1,7 @@ + /* A replacement function, for systems that lack strndup. + +- Copyright (C) 1996, 1997, 1998, 2001, 2002, 2003, 2005, 2006, 2007, 2009, +- 2010 Free Software Foundation, Inc. ++ Copyright (C) 1996-1998, 2001-2003, 2005-2007, 2009-2013 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 +@@ -14,8 +14,7 @@ + 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. */ ++ along with this program; if not, see . */ + + #include + +diff --git a/grub-core/gnulib/strnlen.c b/grub-core/gnulib/strnlen.c +index f1ec356..57fdfe7 100644 +--- a/grub-core/gnulib/strnlen.c ++++ b/grub-core/gnulib/strnlen.c +@@ -1,5 +1,5 @@ + /* Find the length of STRING, but scan at most MAXLEN characters. +- Copyright (C) 2005, 2006, 2007, 2009, 2010 Free Software Foundation, Inc. ++ Copyright (C) 2005-2007, 2009-2013 Free Software Foundation, Inc. + Written by Simon Josefsson. + + This program is free software; you can redistribute it and/or modify +@@ -13,8 +13,7 @@ + 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. */ ++ along with this program; if not, see . */ + + #include + +diff --git a/grub-core/gnulib/strnlen1.c b/grub-core/gnulib/strnlen1.c +index b8cd2bf..0c22d21 100644 +--- a/grub-core/gnulib/strnlen1.c ++++ b/grub-core/gnulib/strnlen1.c +@@ -1,5 +1,5 @@ + /* Find the length of STRING + 1, but scan at most MAXLEN bytes. +- Copyright (C) 2005-2006, 2009-2010 Free Software Foundation, Inc. ++ Copyright (C) 2005-2006, 2009-2013 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 +diff --git a/grub-core/gnulib/strnlen1.h b/grub-core/gnulib/strnlen1.h +index dfaf62d..7c65e31 100644 +--- a/grub-core/gnulib/strnlen1.h ++++ b/grub-core/gnulib/strnlen1.h +@@ -1,5 +1,5 @@ + /* Find the length of STRING + 1, but scan at most MAXLEN bytes. +- Copyright (C) 2005, 2009, 2010 Free Software Foundation, Inc. ++ Copyright (C) 2005, 2009-2013 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 +@@ -28,7 +28,8 @@ extern "C" { + /* Find the length of STRING + 1, but scan at most MAXLEN bytes. + If no '\0' terminator is found in that many characters, return MAXLEN. */ + /* This is the same as strnlen (string, maxlen - 1) + 1. */ +-extern size_t strnlen1 (const char *string, size_t maxlen); ++extern size_t strnlen1 (const char *string, size_t maxlen) ++ _GL_ATTRIBUTE_PURE; + + + #ifdef __cplusplus +diff --git a/grub-core/gnulib/sys_types.in.h b/grub-core/gnulib/sys_types.in.h +new file mode 100644 +index 0000000..d7da356 +--- /dev/null ++++ b/grub-core/gnulib/sys_types.in.h +@@ -0,0 +1,51 @@ ++/* Provide a more complete sys/types.h. ++ ++ Copyright (C) 2011-2013 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 . */ ++ ++#if __GNUC__ >= 3 ++@PRAGMA_SYSTEM_HEADER@ ++#endif ++@PRAGMA_COLUMNS@ ++ ++#ifndef _@GUARD_PREFIX@_SYS_TYPES_H ++ ++/* The include_next requires a split double-inclusion guard. */ ++#@INCLUDE_NEXT@ @NEXT_SYS_TYPES_H@ ++ ++#ifndef _@GUARD_PREFIX@_SYS_TYPES_H ++#define _@GUARD_PREFIX@_SYS_TYPES_H ++ ++/* Override off_t if Large File Support is requested on native Windows. */ ++#if @WINDOWS_64_BIT_OFF_T@ ++/* Same as int64_t in . */ ++# if defined _MSC_VER ++# define off_t __int64 ++# else ++# define off_t long long int ++# endif ++/* Indicator, for gnulib internal purposes. */ ++# define _GL_WINDOWS_64_BIT_OFF_T 1 ++#endif ++ ++/* MSVC 9 defines size_t in , not in . */ ++/* But avoid namespace pollution on glibc systems. */ ++#if ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__) \ ++ && ! defined __GLIBC__ ++# include ++#endif ++ ++#endif /* _@GUARD_PREFIX@_SYS_TYPES_H */ ++#endif /* _@GUARD_PREFIX@_SYS_TYPES_H */ +diff --git a/grub-core/gnulib/sys_wait.in.h b/grub-core/gnulib/sys_wait.in.h +deleted file mode 100644 +index 009fa21..0000000 +--- a/grub-core/gnulib/sys_wait.in.h ++++ /dev/null +@@ -1,106 +0,0 @@ +-/* A POSIX-like . +- Copyright (C) 2001-2003, 2005-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, write to the Free Software Foundation, +- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +- +- +-#ifndef _GL_SYS_WAIT_H +- +-#if __GNUC__ >= 3 +-@PRAGMA_SYSTEM_HEADER@ +-#endif +- +-/* The include_next requires a split double-inclusion guard. */ +-#if !((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__) +-# @INCLUDE_NEXT@ @NEXT_SYS_WAIT_H@ +-#endif +- +-#ifndef _GL_SYS_WAIT_H +-#define _GL_SYS_WAIT_H +- +-#if !((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__) +-/* Unix API. */ +- +-/* The following macros apply to an argument x, that is a status of a process, +- as returned by waitpid(). +- On nearly all systems, including Linux/x86, WEXITSTATUS are bits 15..8 and +- WTERMSIG are bits 7..0, while BeOS uses the opposite. Therefore programs +- have to use the abstract macros. */ +- +-/* For valid x, exactly one of WIFSIGNALED(x), WIFEXITED(x), WIFSTOPPED(x) +- is true. */ +-# ifndef WIFSIGNALED +-# define WIFSIGNALED(x) (WTERMSIG (x) != 0 && WTERMSIG(x) != 0x7f) +-# endif +-# ifndef WIFEXITED +-# define WIFEXITED(x) (WTERMSIG (x) == 0) +-# endif +-# ifndef WIFSTOPPED +-# define WIFSTOPPED(x) (WTERMSIG (x) == 0x7f) +-# endif +- +-/* The termination signal. Only to be accessed if WIFSIGNALED(x) is true. */ +-# ifndef WTERMSIG +-# define WTERMSIG(x) ((x) & 0x7f) +-# endif +- +-/* The exit status. Only to be accessed if WIFEXITED(x) is true. */ +-# ifndef WEXITSTATUS +-# define WEXITSTATUS(x) (((x) >> 8) & 0xff) +-# endif +- +-/* True if the process dumped core. Not standardized by POSIX. */ +-# ifndef WCOREDUMP +-# define WCOREDUMP(x) ((x) & 0x80) +-# endif +- +-# ifdef __cplusplus +-extern "C" { +-# endif +- +-/* Declarations of functions. */ +- +-# ifdef __cplusplus +-} +-# endif +- +-#else +-/* Native Windows API. */ +- +-# include +- +-# define waitpid(pid,statusp,options) _cwait (statusp, pid, WAIT_CHILD) +- +-/* The following macros apply to an argument x, that is a status of a process, +- as returned by waitpid() or, equivalently, _cwait() or GetExitCodeProcess(). +- This value is simply an 'int', not composed of bit fields. */ +- +-/* When an unhandled fatal signal terminates a process, the exit code is 3. */ +-# define WIFSIGNALED(x) ((x) == 3) +-# define WIFEXITED(x) ((x) != 3) +-# define WIFSTOPPED(x) 0 +- +-/* The signal that terminated a process is not known posthum. */ +-# define WTERMSIG(x) SIGTERM +- +-# define WEXITSTATUS(x) (x) +- +-/* There are no core dumps. */ +-# define WCOREDUMP(x) 0 +- +-#endif +- +-#endif /* _GL_SYS_WAIT_H */ +-#endif /* _GL_SYS_WAIT_H */ +diff --git a/grub-core/gnulib/sysexits.in.h b/grub-core/gnulib/sysexits.in.h +index 45255df..fa8db83 100644 +--- a/grub-core/gnulib/sysexits.in.h ++++ b/grub-core/gnulib/sysexits.in.h +@@ -1,5 +1,5 @@ + /* exit() exit codes for some BSD system programs. +- Copyright (C) 2003, 2006-2010 Free Software Foundation, Inc. ++ Copyright (C) 2003, 2006-2013 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 +@@ -16,11 +16,12 @@ + + /* Written by Simon Josefsson based on sysexits(3) man page */ + +-#ifndef _GL_SYSEXITS_H ++#ifndef _@GUARD_PREFIX@_SYSEXITS_H + + #if __GNUC__ >= 3 + @PRAGMA_SYSTEM_HEADER@ + #endif ++@PRAGMA_COLUMNS@ + + #if @HAVE_SYSEXITS_H@ + +@@ -42,8 +43,8 @@ + + #endif + +-#ifndef _GL_SYSEXITS_H +-#define _GL_SYSEXITS_H ++#ifndef _@GUARD_PREFIX@_SYSEXITS_H ++#define _@GUARD_PREFIX@_SYSEXITS_H + + #if !@HAVE_SYSEXITS_H@ + +@@ -67,5 +68,5 @@ + + #endif + +-#endif /* _GL_SYSEXITS_H */ +-#endif /* _GL_SYSEXITS_H */ ++#endif /* _@GUARD_PREFIX@_SYSEXITS_H */ ++#endif /* _@GUARD_PREFIX@_SYSEXITS_H */ +diff --git a/grub-core/gnulib/unistd.c b/grub-core/gnulib/unistd.c +new file mode 100644 +index 0000000..6c6a8e2 +--- /dev/null ++++ b/grub-core/gnulib/unistd.c +@@ -0,0 +1,3 @@ ++#include ++#define _GL_UNISTD_INLINE _GL_EXTERN_INLINE ++#include "unistd.h" +diff --git a/grub-core/gnulib/unistd.in.h b/grub-core/gnulib/unistd.in.h +index 26a4cbd..2ea9af4 100644 +--- a/grub-core/gnulib/unistd.in.h ++++ b/grub-core/gnulib/unistd.in.h +@@ -1,5 +1,5 @@ + /* Substitute for and wrapper around . +- Copyright (C) 2003-2010 Free Software Foundation, Inc. ++ Copyright (C) 2003-2013 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 +@@ -12,30 +12,14 @@ + 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. */ ++ along with this program; if not, see . */ ++ ++#ifndef _@GUARD_PREFIX@_UNISTD_H + + #if __GNUC__ >= 3 + @PRAGMA_SYSTEM_HEADER@ + #endif +- +-/* Special invocation convention: +- - On mingw, several headers, including , include , +- but we need to ensure that both the system and +- are completely included before we replace gethostname. */ +-#if @GNULIB_GETHOSTNAME@ && @UNISTD_H_HAVE_WINSOCK2_H@ \ +- && !defined _GL_WINSOCK2_H_WITNESS && defined _WINSOCK2_H +-/* is being indirectly included for the first time from +- ; avoid declaring any overrides. */ +-# if @HAVE_UNISTD_H@ +-# @INCLUDE_NEXT@ @NEXT_UNISTD_H@ +-# else +-# error unexpected; report this to bug-gnulib@gnu.org +-# endif +-# define _GL_WINSOCK2_H_WITNESS +- +-/* Normal invocation. */ +-#elif !defined _GL_UNISTD_H ++@PRAGMA_COLUMNS@ + + /* The include_next requires a split double-inclusion guard. */ + #if @HAVE_UNISTD_H@ +@@ -50,8 +34,8 @@ + # undef _GL_INCLUDING_WINSOCK2_H + #endif + +-#if !defined _GL_UNISTD_H && !defined _GL_INCLUDING_WINSOCK2_H +-#define _GL_UNISTD_H ++#if !defined _@GUARD_PREFIX@_UNISTD_H && !defined _GL_INCLUDING_WINSOCK2_H ++#define _@GUARD_PREFIX@_UNISTD_H + + /* NetBSD 5.0 mis-defines NULL. Also get size_t. */ + #include +@@ -60,32 +44,66 @@ + /* Cygwin 1.7.1 declares symlinkat in , not in . */ + /* But avoid namespace pollution on glibc systems. */ + #if (!(defined SEEK_CUR && defined SEEK_END && defined SEEK_SET) \ +- || (@GNULIB_SYMLINKAT@ || defined GNULIB_POSIXCHECK)) \ ++ || ((@GNULIB_SYMLINKAT@ || defined GNULIB_POSIXCHECK) \ ++ && defined __CYGWIN__)) \ + && ! defined __GLIBC__ + # include + #endif + + /* Cygwin 1.7.1 declares unlinkat in , not in . */ + /* But avoid namespace pollution on glibc systems. */ +-#if (@GNULIB_UNLINKAT@ || defined GNULIB_POSIXCHECK) && ! defined __GLIBC__ ++#if (@GNULIB_UNLINKAT@ || defined GNULIB_POSIXCHECK) && defined __CYGWIN__ \ ++ && ! defined __GLIBC__ + # include + #endif + + /* mingw fails to declare _exit in . */ +-/* mingw, BeOS, Haiku declare environ in , not in . */ ++/* mingw, MSVC, BeOS, Haiku declare environ in , not in ++ . */ + /* Solaris declares getcwd not only in but also in . */ ++/* OSF Tru64 Unix cannot see gnulib rpl_strtod when system is ++ included here. */ + /* But avoid namespace pollution on glibc systems. */ +-#ifndef __GLIBC__ ++#if !defined __GLIBC__ && !defined __osf__ ++# define __need_system_stdlib_h + # include ++# undef __need_system_stdlib_h + #endif + +-/* mingw declares getcwd in , not in . */ +-#if ((@GNULIB_GETCWD@ || defined GNULIB_POSIXCHECK) \ ++/* Native Windows platforms declare chdir, getcwd, rmdir in ++ and/or , not in . ++ They also declare access(), chmod(), close(), dup(), dup2(), isatty(), ++ lseek(), read(), unlink(), write() in . */ ++#if ((@GNULIB_CHDIR@ || @GNULIB_GETCWD@ || @GNULIB_RMDIR@ \ ++ || defined GNULIB_POSIXCHECK) \ + && ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__)) ++# include /* mingw32, mingw64 */ ++# include /* mingw64, MSVC 9 */ ++#elif (@GNULIB_CLOSE@ || @GNULIB_DUP@ || @GNULIB_DUP2@ || @GNULIB_ISATTY@ \ ++ || @GNULIB_LSEEK@ || @GNULIB_READ@ || @GNULIB_UNLINK@ || @GNULIB_WRITE@ \ ++ || defined GNULIB_POSIXCHECK) \ ++ && ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__) + # include + #endif + +-#if (@GNULIB_WRITE@ || @GNULIB_READLINK@ || @GNULIB_READLINKAT@ \ ++/* AIX and OSF/1 5.1 declare getdomainname in , not in . ++ NonStop Kernel declares gethostname in , not in . */ ++/* But avoid namespace pollution on glibc systems. */ ++#if ((@GNULIB_GETDOMAINNAME@ && (defined _AIX || defined __osf__)) \ ++ || (@GNULIB_GETHOSTNAME@ && defined __TANDEM)) \ ++ && !defined __GLIBC__ ++# include ++#endif ++ ++/* MSVC defines off_t in . ++ May also define off_t to a 64-bit type on native Windows. */ ++#if !@HAVE_UNISTD_H@ || @WINDOWS_64_BIT_OFF_T@ ++/* Get off_t. */ ++# include ++#endif ++ ++#if (@GNULIB_READ@ || @GNULIB_WRITE@ \ ++ || @GNULIB_READLINK@ || @GNULIB_READLINKAT@ \ + || @GNULIB_PREAD@ || @GNULIB_PWRITE@ || defined GNULIB_POSIXCHECK) + /* Get ssize_t. */ + # include +@@ -94,9 +112,15 @@ + /* Get getopt(), optarg, optind, opterr, optopt. + But avoid namespace pollution on glibc systems. */ + #if @GNULIB_UNISTD_H_GETOPT@ && !defined __GLIBC__ && !defined _GL_SYSTEM_GETOPT ++# define __need_getopt + # include + #endif + ++_GL_INLINE_HEADER_BEGIN ++#ifndef _GL_UNISTD_INLINE ++# define _GL_UNISTD_INLINE _GL_INLINE ++#endif ++ + /* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ + + /* The definition of _GL_ARG_NONNULL is copied here. */ +@@ -104,78 +128,77 @@ + /* The definition of _GL_WARN_ON_USE is copied here. */ + + +-#if @GNULIB_GETHOSTNAME@ +-/* Get all possible declarations of gethostname(). */ +-# if @UNISTD_H_HAVE_WINSOCK2_H@ +-# if !defined _GL_SYS_SOCKET_H +-# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +-# undef socket +-# define socket socket_used_without_including_sys_socket_h +-# undef connect +-# define connect connect_used_without_including_sys_socket_h +-# undef accept +-# define accept accept_used_without_including_sys_socket_h +-# undef bind +-# define bind bind_used_without_including_sys_socket_h +-# undef getpeername +-# define getpeername getpeername_used_without_including_sys_socket_h +-# undef getsockname +-# define getsockname getsockname_used_without_including_sys_socket_h +-# undef getsockopt +-# define getsockopt getsockopt_used_without_including_sys_socket_h +-# undef listen +-# define listen listen_used_without_including_sys_socket_h +-# undef recv +-# define recv recv_used_without_including_sys_socket_h +-# undef send +-# define send send_used_without_including_sys_socket_h +-# undef recvfrom +-# define recvfrom recvfrom_used_without_including_sys_socket_h +-# undef sendto +-# define sendto sendto_used_without_including_sys_socket_h +-# undef setsockopt +-# define setsockopt setsockopt_used_without_including_sys_socket_h +-# undef shutdown +-# define shutdown shutdown_used_without_including_sys_socket_h +-# else +- _GL_WARN_ON_USE (socket, +- "socket() used without including "); +- _GL_WARN_ON_USE (connect, +- "connect() used without including "); +- _GL_WARN_ON_USE (accept, +- "accept() used without including "); +- _GL_WARN_ON_USE (bind, +- "bind() used without including "); +- _GL_WARN_ON_USE (getpeername, +- "getpeername() used without including "); +- _GL_WARN_ON_USE (getsockname, +- "getsockname() used without including "); +- _GL_WARN_ON_USE (getsockopt, +- "getsockopt() used without including "); +- _GL_WARN_ON_USE (listen, +- "listen() used without including "); +- _GL_WARN_ON_USE (recv, +- "recv() used without including "); +- _GL_WARN_ON_USE (send, +- "send() used without including "); +- _GL_WARN_ON_USE (recvfrom, +- "recvfrom() used without including "); +- _GL_WARN_ON_USE (sendto, +- "sendto() used without including "); +- _GL_WARN_ON_USE (setsockopt, +- "setsockopt() used without including "); +- _GL_WARN_ON_USE (shutdown, +- "shutdown() used without including "); +-# endif ++/* Hide some function declarations from . */ ++ ++#if @GNULIB_GETHOSTNAME@ && @UNISTD_H_HAVE_WINSOCK2_H@ ++# if !defined _@GUARD_PREFIX@_SYS_SOCKET_H ++# if !(defined __cplusplus && defined GNULIB_NAMESPACE) ++# undef socket ++# define socket socket_used_without_including_sys_socket_h ++# undef connect ++# define connect connect_used_without_including_sys_socket_h ++# undef accept ++# define accept accept_used_without_including_sys_socket_h ++# undef bind ++# define bind bind_used_without_including_sys_socket_h ++# undef getpeername ++# define getpeername getpeername_used_without_including_sys_socket_h ++# undef getsockname ++# define getsockname getsockname_used_without_including_sys_socket_h ++# undef getsockopt ++# define getsockopt getsockopt_used_without_including_sys_socket_h ++# undef listen ++# define listen listen_used_without_including_sys_socket_h ++# undef recv ++# define recv recv_used_without_including_sys_socket_h ++# undef send ++# define send send_used_without_including_sys_socket_h ++# undef recvfrom ++# define recvfrom recvfrom_used_without_including_sys_socket_h ++# undef sendto ++# define sendto sendto_used_without_including_sys_socket_h ++# undef setsockopt ++# define setsockopt setsockopt_used_without_including_sys_socket_h ++# undef shutdown ++# define shutdown shutdown_used_without_including_sys_socket_h ++# else ++ _GL_WARN_ON_USE (socket, ++ "socket() used without including "); ++ _GL_WARN_ON_USE (connect, ++ "connect() used without including "); ++ _GL_WARN_ON_USE (accept, ++ "accept() used without including "); ++ _GL_WARN_ON_USE (bind, ++ "bind() used without including "); ++ _GL_WARN_ON_USE (getpeername, ++ "getpeername() used without including "); ++ _GL_WARN_ON_USE (getsockname, ++ "getsockname() used without including "); ++ _GL_WARN_ON_USE (getsockopt, ++ "getsockopt() used without including "); ++ _GL_WARN_ON_USE (listen, ++ "listen() used without including "); ++ _GL_WARN_ON_USE (recv, ++ "recv() used without including "); ++ _GL_WARN_ON_USE (send, ++ "send() used without including "); ++ _GL_WARN_ON_USE (recvfrom, ++ "recvfrom() used without including "); ++ _GL_WARN_ON_USE (sendto, ++ "sendto() used without including "); ++ _GL_WARN_ON_USE (setsockopt, ++ "setsockopt() used without including "); ++ _GL_WARN_ON_USE (shutdown, ++ "shutdown() used without including "); + # endif +-# if !defined _GL_SYS_SELECT_H +-# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +-# undef select +-# define select select_used_without_including_sys_select_h +-# else +- _GL_WARN_ON_USE (select, +- "select() used without including "); +-# endif ++# endif ++# if !defined _@GUARD_PREFIX@_SYS_SELECT_H ++# if !(defined __cplusplus && defined GNULIB_NAMESPACE) ++# undef select ++# define select select_used_without_including_sys_select_h ++# else ++ _GL_WARN_ON_USE (select, ++ "select() used without including "); + # endif + # endif + #endif +@@ -211,12 +234,24 @@ _GL_WARN_ON_USE (access, "the access function is a security risk - " + #endif + + ++#if @GNULIB_CHDIR@ ++_GL_CXXALIAS_SYS (chdir, int, (const char *file) _GL_ARG_NONNULL ((1))); ++_GL_CXXALIASWARN (chdir); ++#elif defined GNULIB_POSIXCHECK ++# undef chdir ++# if HAVE_RAW_DECL_CHDIR ++_GL_WARN_ON_USE (chown, "chdir is not always in - " ++ "use gnulib module chdir for portability"); ++# endif ++#endif ++ ++ + #if @GNULIB_CHOWN@ + /* Change the owner of FILE to UID (if UID is not -1) and the group of FILE + to GID (if GID is not -1). Follow symbolic links. + Return 0 if successful, otherwise -1 and errno set. +- See the POSIX:2001 specification +- . */ ++ See the POSIX:2008 specification ++ . */ ++ See the POSIX:2008 specification ++ . */ + # if @REPLACE_DUP2@ + # if !(defined __cplusplus && defined GNULIB_NAMESPACE) + # define dup2 rpl_dup2 +@@ -355,7 +398,7 @@ extern char **environ; + # endif + #elif defined GNULIB_POSIXCHECK + # if HAVE_RAW_DECL_ENVIRON +-static inline char *** ++_GL_UNISTD_INLINE char *** + rpl_environ (void) + { + return &environ; +@@ -413,8 +456,8 @@ _GL_WARN_ON_USE (faccessat, "faccessat is not portable - " + /* Change the process' current working directory to the directory on which + the given file descriptor is open. + Return 0 if successful, otherwise -1 and errno set. +- See the POSIX:2001 specification +- . */ ++ See the POSIX:2008 specification ++ . */ + # if ! @HAVE_FCHDIR@ + _GL_FUNCDECL_SYS (fchdir, int, (int /*fd*/)); + +@@ -425,6 +468,10 @@ _GL_EXTERN_C void _gl_unregister_fd (int fd); + _GL_EXTERN_C int _gl_register_dup (int oldfd, int newfd); + _GL_EXTERN_C const char *_gl_directory_name (int fd); + ++# else ++# if !@HAVE_DECL_FCHDIR@ ++_GL_FUNCDECL_SYS (fchdir, int, (int /*fd*/)); ++# endif + # endif + _GL_CXXALIAS_SYS (fchdir, int, (int /*fd*/)); + _GL_CXXALIASWARN (fchdir); +@@ -467,11 +514,30 @@ _GL_WARN_ON_USE (fchownat, "fchownat is not portable - " + #endif + + +-#if @GNULIB_FSYNC@ ++#if @GNULIB_FDATASYNC@ + /* Synchronize changes to a file. + Return 0 if successful, otherwise -1 and errno set. +- See POSIX:2001 specification +- . */ ++ See POSIX:2008 specification ++ . */ ++# if !@HAVE_FDATASYNC@ || !@HAVE_DECL_FDATASYNC@ ++_GL_FUNCDECL_SYS (fdatasync, int, (int fd)); ++# endif ++_GL_CXXALIAS_SYS (fdatasync, int, (int fd)); ++_GL_CXXALIASWARN (fdatasync); ++#elif defined GNULIB_POSIXCHECK ++# undef fdatasync ++# if HAVE_RAW_DECL_FDATASYNC ++_GL_WARN_ON_USE (fdatasync, "fdatasync is unportable - " ++ "use gnulib module fdatasync for portability"); ++# endif ++#endif ++ ++ ++#if @GNULIB_FSYNC@ ++/* Synchronize changes, including metadata, to a file. ++ Return 0 if successful, otherwise -1 and errno set. ++ See POSIX:2008 specification ++ . */ + # if !@HAVE_FSYNC@ + _GL_FUNCDECL_SYS (fsync, int, (int fd)); + # endif +@@ -489,12 +555,21 @@ _GL_WARN_ON_USE (fsync, "fsync is unportable - " + #if @GNULIB_FTRUNCATE@ + /* Change the size of the file to which FD is opened to become equal to LENGTH. + Return 0 if successful, otherwise -1 and errno set. +- See the POSIX:2001 specification +- . */ +-# if !@HAVE_FTRUNCATE@ ++ See the POSIX:2008 specification ++ . */ ++# if @REPLACE_FTRUNCATE@ ++# if !(defined __cplusplus && defined GNULIB_NAMESPACE) ++# undef ftruncate ++# define ftruncate rpl_ftruncate ++# endif ++_GL_FUNCDECL_RPL (ftruncate, int, (int fd, off_t length)); ++_GL_CXXALIAS_RPL (ftruncate, int, (int fd, off_t length)); ++# else ++# if !@HAVE_FTRUNCATE@ + _GL_FUNCDECL_SYS (ftruncate, int, (int fd, off_t length)); +-# endif ++# endif + _GL_CXXALIAS_SYS (ftruncate, int, (int fd, off_t length)); ++# endif + _GL_CXXALIASWARN (ftruncate); + #elif defined GNULIB_POSIXCHECK + # undef ftruncate +@@ -510,8 +585,8 @@ _GL_WARN_ON_USE (ftruncate, "ftruncate is unportable - " + of BUF. + Return BUF if successful, or NULL if the directory couldn't be determined + or SIZE was too small. +- See the POSIX:2001 specification +- . ++ See the POSIX:2008 specification ++ . + Additionally, the gnulib module 'getcwd' guarantees the following GNU + extension: If BUF is NULL, an array is allocated with 'malloc'; the array + is SIZE bytes long, unless SIZE == 0, in which case it is as big as +@@ -548,13 +623,21 @@ _GL_WARN_ON_USE (getcwd, "getcwd is unportable - " + Null terminate it if the name is shorter than LEN. + If the NIS domain name is longer than LEN, set errno = EINVAL and return -1. + Return 0 if successful, otherwise set errno and return -1. */ +-# if !@HAVE_GETDOMAINNAME@ ++# if @REPLACE_GETDOMAINNAME@ ++# if !(defined __cplusplus && defined GNULIB_NAMESPACE) ++# undef getdomainname ++# define getdomainname rpl_getdomainname ++# endif ++_GL_FUNCDECL_RPL (getdomainname, int, (char *name, size_t len) ++ _GL_ARG_NONNULL ((1))); ++_GL_CXXALIAS_RPL (getdomainname, int, (char *name, size_t len)); ++# else ++# if !@HAVE_DECL_GETDOMAINNAME@ + _GL_FUNCDECL_SYS (getdomainname, int, (char *name, size_t len) + _GL_ARG_NONNULL ((1))); ++# endif ++_GL_CXXALIAS_SYS (getdomainname, int, (char *name, size_t len)); + # endif +-/* Need to cast, because on MacOS X 10.5 systems, the second parameter is +- int len. */ +-_GL_CXXALIAS_SYS_CAST (getdomainname, int, (char *name, size_t len)); + _GL_CXXALIASWARN (getdomainname); + #elif defined GNULIB_POSIXCHECK + # undef getdomainname +@@ -632,7 +715,8 @@ _GL_CXXALIAS_RPL (gethostname, int, (char *name, size_t len)); + _GL_FUNCDECL_SYS (gethostname, int, (char *name, size_t len) + _GL_ARG_NONNULL ((1))); + # endif +-/* Need to cast, because on Solaris 10 systems, the second parameter is ++/* Need to cast, because on Solaris 10 and OSF/1 5.1 systems, the second ++ parameter is + int len. */ + _GL_CXXALIAS_SYS_CAST (gethostname, int, (char *name, size_t len)); + # endif +@@ -689,13 +773,22 @@ _GL_WARN_ON_USE (getlogin, "getlogin is unportable - " + ${LOGNAME-$USER} on Unix platforms, + $USERNAME on native Windows platforms. + */ +-# if !@HAVE_DECL_GETLOGIN_R@ ++# if @REPLACE_GETLOGIN_R@ ++# if !(defined __cplusplus && defined GNULIB_NAMESPACE) ++# define getlogin_r rpl_getlogin_r ++# endif ++_GL_FUNCDECL_RPL (getlogin_r, int, (char *name, size_t size) ++ _GL_ARG_NONNULL ((1))); ++_GL_CXXALIAS_RPL (getlogin_r, int, (char *name, size_t size)); ++# else ++# if !@HAVE_DECL_GETLOGIN_R@ + _GL_FUNCDECL_SYS (getlogin_r, int, (char *name, size_t size) + _GL_ARG_NONNULL ((1))); +-# endif ++# endif + /* Need to cast, because on Solaris 10 systems, the second argument is + int size. */ + _GL_CXXALIAS_SYS_CAST (getlogin_r, int, (char *name, size_t size)); ++# endif + _GL_CXXALIASWARN (getlogin_r); + #elif defined GNULIB_POSIXCHECK + # undef getlogin_r +@@ -762,11 +855,14 @@ _GL_CXXALIAS_RPL (getpagesize, int, (void)); + # if !(defined __cplusplus && defined GNULIB_NAMESPACE) + # define getpagesize() _gl_getpagesize () + # else +-static inline int ++# if !GNULIB_defined_getpagesize_function ++_GL_UNISTD_INLINE int + getpagesize () + { + return _gl_getpagesize (); + } ++# define GNULIB_defined_getpagesize_function 1 ++# endif + # endif + # endif + # endif +@@ -833,12 +929,49 @@ _GL_WARN_ON_USE (endusershell, "endusershell is unportable - " + #endif + + ++#if @GNULIB_GROUP_MEMBER@ ++/* Determine whether group id is in calling user's group list. */ ++# if !@HAVE_GROUP_MEMBER@ ++_GL_FUNCDECL_SYS (group_member, int, (gid_t gid)); ++# endif ++_GL_CXXALIAS_SYS (group_member, int, (gid_t gid)); ++_GL_CXXALIASWARN (group_member); ++#elif defined GNULIB_POSIXCHECK ++# undef group_member ++# if HAVE_RAW_DECL_GROUP_MEMBER ++_GL_WARN_ON_USE (group_member, "group_member is unportable - " ++ "use gnulib module group-member for portability"); ++# endif ++#endif ++ ++ ++#if @GNULIB_ISATTY@ ++# if @REPLACE_ISATTY@ ++# if !(defined __cplusplus && defined GNULIB_NAMESPACE) ++# undef isatty ++# define isatty rpl_isatty ++# endif ++_GL_FUNCDECL_RPL (isatty, int, (int fd)); ++_GL_CXXALIAS_RPL (isatty, int, (int fd)); ++# else ++_GL_CXXALIAS_SYS (isatty, int, (int fd)); ++# endif ++_GL_CXXALIASWARN (isatty); ++#elif defined GNULIB_POSIXCHECK ++# undef isatty ++# if HAVE_RAW_DECL_ISATTY ++_GL_WARN_ON_USE (isatty, "isatty has portability problems on native Windows - " ++ "use gnulib module isatty for portability"); ++# endif ++#endif ++ ++ + #if @GNULIB_LCHOWN@ + /* Change the owner of FILE to UID (if UID is not -1) and the group of FILE + to GID (if GID is not -1). Do not follow symbolic links. + Return 0 if successful, otherwise -1 and errno set. +- See the POSIX:2001 specification +- . */ ++ See the POSIX:2008 specification ++ . */ + # if @REPLACE_LCHOWN@ + # if !(defined __cplusplus && defined GNULIB_NAMESPACE) + # undef lchown +@@ -867,8 +1000,8 @@ _GL_WARN_ON_USE (lchown, "lchown is unportable to pre-POSIX.1-2001 systems - " + #if @GNULIB_LINK@ + /* Create a new hard link for an existing file. + Return 0 if successful, otherwise -1 and errno set. +- See POSIX:2001 specification +- . */ ++ See POSIX:2008 specification ++ . */ + # if @REPLACE_LINK@ + # if !(defined __cplusplus && defined GNULIB_NAMESPACE) + # define link rpl_link +@@ -933,8 +1066,8 @@ _GL_WARN_ON_USE (linkat, "linkat is unportable - " + #if @GNULIB_LSEEK@ + /* Set the offset of FD relative to SEEK_SET, SEEK_CUR, or SEEK_END. + Return the new offset if successful, otherwise -1 and errno set. +- See the POSIX:2001 specification +- . */ ++ See the POSIX:2008 specification ++ . */ + # if @REPLACE_LSEEK@ + # if !(defined __cplusplus && defined GNULIB_NAMESPACE) + # define lseek rpl_lseek +@@ -954,6 +1087,24 @@ _GL_WARN_ON_USE (lseek, "lseek does not fail with ESPIPE on pipes on some " + #endif + + ++#if @GNULIB_PIPE@ ++/* Create a pipe, defaulting to O_BINARY mode. ++ Store the read-end as fd[0] and the write-end as fd[1]. ++ Return 0 upon success, or -1 with errno set upon failure. */ ++# if !@HAVE_PIPE@ ++_GL_FUNCDECL_SYS (pipe, int, (int fd[2]) _GL_ARG_NONNULL ((1))); ++# endif ++_GL_CXXALIAS_SYS (pipe, int, (int fd[2])); ++_GL_CXXALIASWARN (pipe); ++#elif defined GNULIB_POSIXCHECK ++# undef pipe ++# if HAVE_RAW_DECL_PIPE ++_GL_WARN_ON_USE (pipe, "pipe is unportable - " ++ "use gnulib module pipe-posix for portability"); ++# endif ++#endif ++ ++ + #if @GNULIB_PIPE2@ + /* Create a pipe, applying the given flags when opening the read-end of the + pipe and the write-end of the pipe. +@@ -986,10 +1137,12 @@ _GL_WARN_ON_USE (pipe2, "pipe2 is unportable - " + #if @GNULIB_PREAD@ + /* Read at most BUFSIZE bytes from FD into BUF, starting at OFFSET. + Return the number of bytes placed into BUF if successful, otherwise +- set errno and return -1. 0 indicates EOF. See the POSIX:2001 +- specification . */ ++ set errno and return -1. 0 indicates EOF. ++ See the POSIX:2008 specification ++ . */ + # if @REPLACE_PREAD@ + # if !(defined __cplusplus && defined GNULIB_NAMESPACE) ++# undef pread + # define pread rpl_pread + # endif + _GL_FUNCDECL_RPL (pread, ssize_t, +@@ -1020,10 +1173,11 @@ _GL_WARN_ON_USE (pread, "pread is unportable - " + /* Write at most BUFSIZE bytes from BUF into FD, starting at OFFSET. + Return the number of bytes written if successful, otherwise + set errno and return -1. 0 indicates nothing written. See the +- POSIX:2001 specification +- . */ ++ POSIX:2008 specification ++ . */ + # if @REPLACE_PWRITE@ + # if !(defined __cplusplus && defined GNULIB_NAMESPACE) ++# undef pwrite + # define pwrite rpl_pwrite + # endif + _GL_FUNCDECL_RPL (pwrite, ssize_t, +@@ -1050,12 +1204,34 @@ _GL_WARN_ON_USE (pwrite, "pwrite is unportable - " + #endif + + ++#if @GNULIB_READ@ ++/* Read up to COUNT bytes from file descriptor FD into the buffer starting ++ at BUF. See the POSIX:2008 specification ++ . */ ++# if @REPLACE_READ@ ++# if !(defined __cplusplus && defined GNULIB_NAMESPACE) ++# undef read ++# define read rpl_read ++# endif ++_GL_FUNCDECL_RPL (read, ssize_t, (int fd, void *buf, size_t count) ++ _GL_ARG_NONNULL ((2))); ++_GL_CXXALIAS_RPL (read, ssize_t, (int fd, void *buf, size_t count)); ++# else ++/* Need to cast, because on mingw, the third parameter is ++ unsigned int count ++ and the return type is 'int'. */ ++_GL_CXXALIAS_SYS_CAST (read, ssize_t, (int fd, void *buf, size_t count)); ++# endif ++_GL_CXXALIASWARN (read); ++#endif ++ ++ + #if @GNULIB_READLINK@ + /* Read the contents of the symbolic link FILE and place the first BUFSIZE + bytes of it into BUF. Return the number of bytes placed into BUF if + successful, otherwise -1 and errno set. +- See the POSIX:2001 specification +- . */ ++ See the POSIX:2008 specification ++ . */ + # if @REPLACE_READLINK@ + # if !(defined __cplusplus && defined GNULIB_NAMESPACE) + # define readlink rpl_readlink +@@ -1123,11 +1299,38 @@ _GL_WARN_ON_USE (rmdir, "rmdir is unportable - " + #endif + + ++#if @GNULIB_SETHOSTNAME@ ++/* Set the host name of the machine. ++ The host name may or may not be fully qualified. ++ ++ Put LEN bytes of NAME into the host name. ++ Return 0 if successful, otherwise, set errno and return -1. ++ ++ Platforms with no ability to set the hostname return -1 and set ++ errno = ENOSYS. */ ++# if !@HAVE_SETHOSTNAME@ || !@HAVE_DECL_SETHOSTNAME@ ++_GL_FUNCDECL_SYS (sethostname, int, (const char *name, size_t len) ++ _GL_ARG_NONNULL ((1))); ++# endif ++/* Need to cast, because on Solaris 11 2011-10, Mac OS X 10.5, IRIX 6.5 ++ and FreeBSD 6.4 the second parameter is int. On Solaris 11 ++ 2011-10, the first parameter is not const. */ ++_GL_CXXALIAS_SYS_CAST (sethostname, int, (const char *name, size_t len)); ++_GL_CXXALIASWARN (sethostname); ++#elif defined GNULIB_POSIXCHECK ++# undef sethostname ++# if HAVE_RAW_DECL_SETHOSTNAME ++_GL_WARN_ON_USE (sethostname, "sethostname is unportable - " ++ "use gnulib module sethostname for portability"); ++# endif ++#endif ++ ++ + #if @GNULIB_SLEEP@ + /* Pause the execution of the current thread for N seconds. + Returns the number of seconds left to sleep. +- See the POSIX:2001 specification +- . */ ++ See the POSIX:2008 specification ++ . */ + # if @REPLACE_SLEEP@ + # if !(defined __cplusplus && defined GNULIB_NAMESPACE) + # undef sleep +@@ -1208,7 +1411,7 @@ _GL_FUNCDECL_RPL (ttyname_r, int, + _GL_CXXALIAS_RPL (ttyname_r, int, + (int fd, char *buf, size_t buflen)); + # else +-# if !@HAVE_TTYNAME_R@ ++# if !@HAVE_DECL_TTYNAME_R@ + _GL_FUNCDECL_SYS (ttyname_r, int, + (int fd, char *buf, size_t buflen) _GL_ARG_NONNULL ((2))); + # endif +@@ -1276,7 +1479,7 @@ _GL_WARN_ON_USE (unlinkat, "unlinkat is not portable - " + /* Pause the execution of the current thread for N microseconds. + Returns 0 on completion, or -1 on range error. + See the POSIX:2001 specification +- . */ ++ . */ + # if @REPLACE_USLEEP@ + # if !(defined __cplusplus && defined GNULIB_NAMESPACE) + # undef usleep +@@ -1302,9 +1505,9 @@ _GL_WARN_ON_USE (usleep, "usleep is unportable - " + + #if @GNULIB_WRITE@ + /* Write up to COUNT bytes starting at BUF to file descriptor FD. +- See the POSIX:2001 specification +- . */ +-# if @REPLACE_WRITE@ && @GNULIB_UNISTD_H_SIGPIPE@ ++ See the POSIX:2008 specification ++ . */ ++# if @REPLACE_WRITE@ + # if !(defined __cplusplus && defined GNULIB_NAMESPACE) + # undef write + # define write rpl_write +@@ -1321,6 +1524,7 @@ _GL_CXXALIAS_SYS_CAST (write, ssize_t, (int fd, const void *buf, size_t count)); + _GL_CXXALIASWARN (write); + #endif + ++_GL_INLINE_HEADER_END + +-#endif /* _GL_UNISTD_H */ +-#endif /* _GL_UNISTD_H */ ++#endif /* _@GUARD_PREFIX@_UNISTD_H */ ++#endif /* _@GUARD_PREFIX@_UNISTD_H */ +diff --git a/grub-core/gnulib/unitypes.in.h b/grub-core/gnulib/unitypes.in.h +new file mode 100644 +index 0000000..06eef05 +--- /dev/null ++++ b/grub-core/gnulib/unitypes.in.h +@@ -0,0 +1,46 @@ ++/* Elementary types and macros for the GNU UniString library. ++ Copyright (C) 2002, 2005-2006, 2009-2013 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 _UNITYPES_H ++#define _UNITYPES_H ++ ++/* Get uint8_t, uint16_t, uint32_t. */ ++#include ++ ++/* Type representing a Unicode character. */ ++typedef uint32_t ucs4_t; ++ ++/* Attribute of a function whose result depends only on the arguments ++ (not pointers!) and which has no side effects. */ ++#ifndef _UC_ATTRIBUTE_CONST ++# if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) ++# define _UC_ATTRIBUTE_CONST __attribute__ ((__const__)) ++# else ++# define _UC_ATTRIBUTE_CONST ++# endif ++#endif ++ ++/* Attribute of a function whose result depends only on the arguments ++ (possibly pointers) and global memory, and which has no side effects. */ ++#ifndef _UC_ATTRIBUTE_PURE ++# if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) ++# define _UC_ATTRIBUTE_PURE __attribute__ ((__pure__)) ++# else ++# define _UC_ATTRIBUTE_PURE ++# endif ++#endif ++ ++#endif /* _UNITYPES_H */ +diff --git a/grub-core/gnulib/uniwidth.in.h b/grub-core/gnulib/uniwidth.in.h +new file mode 100644 +index 0000000..8931cc9 +--- /dev/null ++++ b/grub-core/gnulib/uniwidth.in.h +@@ -0,0 +1,72 @@ ++/* Display width functions. ++ Copyright (C) 2001-2002, 2005, 2007, 2009-2013 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 _UNIWIDTH_H ++#define _UNIWIDTH_H ++ ++#include "unitypes.h" ++ ++/* Get size_t. */ ++#include ++ ++/* Get locale_charset() declaration. */ ++#include "localcharset.h" ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++ ++/* Display width. */ ++ ++/* These functions are locale dependent. The encoding argument identifies ++ the encoding (e.g. "ISO-8859-2" for Polish). */ ++ ++/* Determine number of column positions required for UC. */ ++extern int ++ uc_width (ucs4_t uc, const char *encoding) ++ _UC_ATTRIBUTE_PURE; ++ ++/* Determine number of column positions required for first N units ++ (or fewer if S ends before this) in S. */ ++extern int ++ u8_width (const uint8_t *s, size_t n, const char *encoding) ++ _UC_ATTRIBUTE_PURE; ++extern int ++ u16_width (const uint16_t *s, size_t n, const char *encoding) ++ _UC_ATTRIBUTE_PURE; ++extern int ++ u32_width (const uint32_t *s, size_t n, const char *encoding) ++ _UC_ATTRIBUTE_PURE; ++ ++/* Determine number of column positions required for S. */ ++extern int ++ u8_strwidth (const uint8_t *s, const char *encoding) ++ _UC_ATTRIBUTE_PURE; ++extern int ++ u16_strwidth (const uint16_t *s, const char *encoding) ++ _UC_ATTRIBUTE_PURE; ++extern int ++ u32_strwidth (const uint32_t *s, const char *encoding) ++ _UC_ATTRIBUTE_PURE; ++ ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif /* _UNIWIDTH_H */ +diff --git a/grub-core/gnulib/uniwidth/cjk.h b/grub-core/gnulib/uniwidth/cjk.h +new file mode 100644 +index 0000000..11b14df +--- /dev/null ++++ b/grub-core/gnulib/uniwidth/cjk.h +@@ -0,0 +1,37 @@ ++/* Test for CJK encoding. ++ Copyright (C) 2001-2002, 2005-2007, 2009-2013 Free Software Foundation, Inc. ++ Written by Bruno Haible , 2002. ++ ++ 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 "streq.h" ++ ++static int ++is_cjk_encoding (const char *encoding) ++{ ++ if (0 ++ /* Legacy Japanese encodings */ ++ || STREQ_OPT (encoding, "EUC-JP", 'E', 'U', 'C', '-', 'J', 'P', 0, 0, 0) ++ /* Legacy Chinese encodings */ ++ || STREQ_OPT (encoding, "GB2312", 'G', 'B', '2', '3', '1', '2', 0, 0, 0) ++ || STREQ_OPT (encoding, "GBK", 'G', 'B', 'K', 0, 0, 0, 0, 0, 0) ++ || STREQ_OPT (encoding, "EUC-TW", 'E', 'U', 'C', '-', 'T', 'W', 0, 0, 0) ++ || STREQ_OPT (encoding, "BIG5", 'B', 'I', 'G', '5', 0, 0, 0, 0, 0) ++ /* Legacy Korean encodings */ ++ || STREQ_OPT (encoding, "EUC-KR", 'E', 'U', 'C', '-', 'K', 'R', 0, 0, 0) ++ || STREQ_OPT (encoding, "CP949", 'C', 'P', '9', '4', '9', 0, 0, 0, 0) ++ || STREQ_OPT (encoding, "JOHAB", 'J', 'O', 'H', 'A', 'B', 0, 0, 0, 0)) ++ return 1; ++ return 0; ++} +diff --git a/grub-core/gnulib/uniwidth/width.c b/grub-core/gnulib/uniwidth/width.c +new file mode 100644 +index 0000000..173d087 +--- /dev/null ++++ b/grub-core/gnulib/uniwidth/width.c +@@ -0,0 +1,368 @@ ++/* Determine display width of Unicode character. ++ Copyright (C) 2001-2002, 2006-2013 Free Software Foundation, Inc. ++ Written by Bruno Haible , 2002. ++ ++ 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 ++ ++/* Specification. */ ++#include "uniwidth.h" ++ ++#include "cjk.h" ++ ++/* ++ * Non-spacing attribute table. ++ * Consists of: ++ * - Non-spacing characters; generated from PropList.txt or ++ * "grep '^[^;]*;[^;]*;[^;]*;[^;]*;NSM;' UnicodeData.txt" ++ * - Format control characters; generated from ++ * "grep '^[^;]*;[^;]*;Cf;' UnicodeData.txt" ++ * - Zero width characters; generated from ++ * "grep '^[^;]*;ZERO WIDTH ' UnicodeData.txt" ++ */ ++static const unsigned char nonspacing_table_data[27*64] = { ++ /* 0x0000-0x01ff */ ++ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, /* 0x0000-0x003f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* 0x0040-0x007f */ ++ 0xff, 0xff, 0xff, 0xff, 0x00, 0x20, 0x00, 0x00, /* 0x0080-0x00bf */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00c0-0x00ff */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0100-0x013f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0140-0x017f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0180-0x01bf */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x01c0-0x01ff */ ++ /* 0x0200-0x03ff */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0200-0x023f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0240-0x027f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0280-0x02bf */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x02c0-0x02ff */ ++ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x0300-0x033f */ ++ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, /* 0x0340-0x037f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0380-0x03bf */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x03c0-0x03ff */ ++ /* 0x0400-0x05ff */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0400-0x043f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0440-0x047f */ ++ 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0480-0x04bf */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04c0-0x04ff */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0500-0x053f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0540-0x057f */ ++ 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xbf, /* 0x0580-0x05bf */ ++ 0xb6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x05c0-0x05ff */ ++ /* 0x0600-0x07ff */ ++ 0x0f, 0x00, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, /* 0x0600-0x063f */ ++ 0x00, 0xf8, 0xff, 0xff, 0x00, 0x00, 0x01, 0x00, /* 0x0640-0x067f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0680-0x06bf */ ++ 0x00, 0x00, 0xc0, 0xbf, 0x9f, 0x3d, 0x00, 0x00, /* 0x06c0-0x06ff */ ++ 0x00, 0x80, 0x02, 0x00, 0x00, 0x00, 0xff, 0xff, /* 0x0700-0x073f */ ++ 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0740-0x077f */ ++ 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0x01, 0x00, /* 0x0780-0x07bf */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x0f, 0x00, /* 0x07c0-0x07ff */ ++ /* 0x0800-0x09ff */ ++ 0x00, 0x00, 0xc0, 0xfb, 0xef, 0x3e, 0x00, 0x00, /* 0x0800-0x083f */ ++ 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, /* 0x0840-0x087f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0880-0x08bf */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08c0-0x08ff */ ++ 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, /* 0x0900-0x093f */ ++ 0xfe, 0x21, 0xfe, 0x00, 0x0c, 0x00, 0x00, 0x00, /* 0x0940-0x097f */ ++ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, /* 0x0980-0x09bf */ ++ 0x1e, 0x20, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, /* 0x09c0-0x09ff */ ++ /* 0x0a00-0x0bff */ ++ 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, /* 0x0a00-0x0a3f */ ++ 0x86, 0x39, 0x02, 0x00, 0x00, 0x00, 0x23, 0x00, /* 0x0a40-0x0a7f */ ++ 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, /* 0x0a80-0x0abf */ ++ 0xbe, 0x21, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, /* 0x0ac0-0x0aff */ ++ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, /* 0x0b00-0x0b3f */ ++ 0x1e, 0x20, 0x40, 0x00, 0x0c, 0x00, 0x00, 0x00, /* 0x0b40-0x0b7f */ ++ 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0b80-0x0bbf */ ++ 0x01, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0bc0-0x0bff */ ++ /* 0x0c00-0x0dff */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, /* 0x0c00-0x0c3f */ ++ 0xc1, 0x3d, 0x60, 0x00, 0x0c, 0x00, 0x00, 0x00, /* 0x0c40-0x0c7f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, /* 0x0c80-0x0cbf */ ++ 0x00, 0x30, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, /* 0x0cc0-0x0cff */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0d00-0x0d3f */ ++ 0x1e, 0x20, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, /* 0x0d40-0x0d7f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0d80-0x0dbf */ ++ 0x00, 0x04, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0dc0-0x0dff */ ++ /* 0x0e00-0x0fff */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x07, /* 0x0e00-0x0e3f */ ++ 0x80, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0e40-0x0e7f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x1b, /* 0x0e80-0x0ebf */ ++ 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0ec0-0x0eff */ ++ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0xa0, 0x02, /* 0x0f00-0x0f3f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x7f, /* 0x0f40-0x0f7f */ ++ 0xdf, 0xe0, 0xff, 0xfe, 0xff, 0xff, 0xff, 0x1f, /* 0x0f80-0x0fbf */ ++ 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0fc0-0x0fff */ ++ /* 0x1000-0x11ff */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xfd, 0x66, /* 0x1000-0x103f */ ++ 0x00, 0x00, 0x00, 0xc3, 0x01, 0x00, 0x1e, 0x00, /* 0x1040-0x107f */ ++ 0x64, 0x20, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, /* 0x1080-0x10bf */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10c0-0x10ff */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1100-0x113f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1140-0x117f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1180-0x11bf */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11c0-0x11ff */ ++ /* 0x1200-0x13ff */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1200-0x123f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1240-0x127f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1280-0x12bf */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x12c0-0x12ff */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1300-0x133f */ ++ 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, /* 0x1340-0x137f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1380-0x13bf */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x13c0-0x13ff */ ++ /* 0x1600-0x17ff */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1600-0x163f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1640-0x167f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1680-0x16bf */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x16c0-0x16ff */ ++ 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x1c, 0x00, /* 0x1700-0x173f */ ++ 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0c, 0x00, /* 0x1740-0x177f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x3f, /* 0x1780-0x17bf */ ++ 0x40, 0xfe, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x00, /* 0x17c0-0x17ff */ ++ /* 0x1800-0x19ff */ ++ 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1800-0x183f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1840-0x187f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, /* 0x1880-0x18bf */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18c0-0x18ff */ ++ 0x00, 0x00, 0x00, 0x00, 0x87, 0x01, 0x04, 0x0e, /* 0x1900-0x193f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1940-0x197f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1980-0x19bf */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x19c0-0x19ff */ ++ /* 0x1a00-0x1bff */ ++ 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, /* 0x1a00-0x1a3f */ ++ 0x00, 0x00, 0x40, 0x7f, 0xe5, 0x1f, 0xf8, 0x9f, /* 0x1a40-0x1a7f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1a80-0x1abf */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1ac0-0x1aff */ ++ 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x17, /* 0x1b00-0x1b3f */ ++ 0x04, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x0f, 0x00, /* 0x1b40-0x1b7f */ ++ 0x03, 0x00, 0x00, 0x00, 0x3c, 0x03, 0x00, 0x00, /* 0x1b80-0x1bbf */ ++ 0x00, 0x00, 0x00, 0x00, 0x40, 0xa3, 0x03, 0x00, /* 0x1bc0-0x1bff */ ++ /* 0x1c00-0x1dff */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xcf, 0x00, /* 0x1c00-0x1c3f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1c40-0x1c7f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1c80-0x1cbf */ ++ 0x00, 0x00, 0xf7, 0xff, 0xfd, 0x21, 0x00, 0x00, /* 0x1cc0-0x1cff */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d00-0x1d3f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d40-0x1d7f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d80-0x1dbf */ ++ 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0xf0, /* 0x1dc0-0x1dff */ ++ /* 0x2000-0x21ff */ ++ 0x00, 0xf8, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, /* 0x2000-0x203f */ ++ 0x00, 0x00, 0x00, 0x00, 0x1f, 0xfc, 0x00, 0x00, /* 0x2040-0x207f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2080-0x20bf */ ++ 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, /* 0x20c0-0x20ff */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2100-0x213f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2140-0x217f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2180-0x21bf */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x21c0-0x21ff */ ++ /* 0x2c00-0x2dff */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2c00-0x2c3f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2c40-0x2c7f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2c80-0x2cbf */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00, /* 0x2cc0-0x2cff */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2d00-0x2d3f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* 0x2d40-0x2d7f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2d80-0x2dbf */ ++ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, /* 0x2dc0-0x2dff */ ++ /* 0x3000-0x31ff */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, /* 0x3000-0x303f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3040-0x307f */ ++ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, /* 0x3080-0x30bf */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30c0-0x30ff */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3100-0x313f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3140-0x317f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3180-0x31bf */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x31c0-0x31ff */ ++ /* 0xa600-0xa7ff */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa600-0xa63f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0x30, /* 0xa640-0xa67f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa680-0xa6bf */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, /* 0xa6c0-0xa6ff */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa700-0xa73f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa740-0xa77f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa780-0xa7bf */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa7c0-0xa7ff */ ++ /* 0xa800-0xa9ff */ ++ 0x44, 0x08, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, /* 0xa800-0xa83f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa840-0xa87f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa880-0xa8bf */ ++ 0x10, 0x00, 0x00, 0x00, 0xff, 0xff, 0x03, 0x00, /* 0xa8c0-0xa8ff */ ++ 0x00, 0x00, 0x00, 0x00, 0xc0, 0x3f, 0x00, 0x00, /* 0xa900-0xa93f */ ++ 0x80, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa940-0xa97f */ ++ 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x13, /* 0xa980-0xa9bf */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa9c0-0xa9ff */ ++ /* 0xaa00-0xabff */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x66, 0x00, /* 0xaa00-0xaa3f */ ++ 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xaa40-0xaa7f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9d, 0xc1, /* 0xaa80-0xaabf */ ++ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xaac0-0xaaff */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xab00-0xab3f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xab40-0xab7f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xab80-0xabbf */ ++ 0x00, 0x00, 0x00, 0x00, 0x20, 0x21, 0x00, 0x00, /* 0xabc0-0xabff */ ++ /* 0xfa00-0xfbff */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfa00-0xfa3f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfa40-0xfa7f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfa80-0xfabf */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfac0-0xfaff */ ++ 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, /* 0xfb00-0xfb3f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfb40-0xfb7f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfb80-0xfbbf */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfbc0-0xfbff */ ++ /* 0xfe00-0xffff */ ++ 0xff, 0xff, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, /* 0xfe00-0xfe3f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfe40-0xfe7f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfe80-0xfebf */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* 0xfec0-0xfeff */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xff00-0xff3f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xff40-0xff7f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xff80-0xffbf */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, /* 0xffc0-0xffff */ ++ /* 0x10000-0x101ff */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10000-0x1003f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10040-0x1007f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10080-0x100bf */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x100c0-0x100ff */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10100-0x1013f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10140-0x1017f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10180-0x101bf */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, /* 0x101c0-0x101ff */ ++ /* 0x10a00-0x10bff */ ++ 0x6e, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, /* 0x10a00-0x10a3f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10a40-0x10a7f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10a80-0x10abf */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10ac0-0x10aff */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10b00-0x10b3f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10b40-0x10b7f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10b80-0x10bbf */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10bc0-0x10bff */ ++ /* 0x11000-0x111ff */ ++ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, /* 0x11000-0x1103f */ ++ 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11040-0x1107f */ ++ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x26, /* 0x11080-0x110bf */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x110c0-0x110ff */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11100-0x1113f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11140-0x1117f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11180-0x111bf */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x111c0-0x111ff */ ++ /* 0x1d000-0x1d1ff */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d000-0x1d03f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d040-0x1d07f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d080-0x1d0bf */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d0c0-0x1d0ff */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d100-0x1d13f */ ++ 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0xf8, 0xff, /* 0x1d140-0x1d17f */ ++ 0xe7, 0x0f, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, /* 0x1d180-0x1d1bf */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d1c0-0x1d1ff */ ++ /* 0x1d200-0x1d3ff */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d200-0x1d23f */ ++ 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d240-0x1d27f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d280-0x1d2bf */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d2c0-0x1d2ff */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d300-0x1d33f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d340-0x1d37f */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d380-0x1d3bf */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* 0x1d3c0-0x1d3ff */ ++}; ++static const signed char nonspacing_table_ind[240] = { ++ 0, 1, 2, 3, 4, 5, 6, 7, /* 0x0000-0x0fff */ ++ 8, 9, -1, 10, 11, 12, 13, -1, /* 0x1000-0x1fff */ ++ 14, -1, -1, -1, -1, -1, 15, -1, /* 0x2000-0x2fff */ ++ 16, -1, -1, -1, -1, -1, -1, -1, /* 0x3000-0x3fff */ ++ -1, -1, -1, -1, -1, -1, -1, -1, /* 0x4000-0x4fff */ ++ -1, -1, -1, -1, -1, -1, -1, -1, /* 0x5000-0x5fff */ ++ -1, -1, -1, -1, -1, -1, -1, -1, /* 0x6000-0x6fff */ ++ -1, -1, -1, -1, -1, -1, -1, -1, /* 0x7000-0x7fff */ ++ -1, -1, -1, -1, -1, -1, -1, -1, /* 0x8000-0x8fff */ ++ -1, -1, -1, -1, -1, -1, -1, -1, /* 0x9000-0x9fff */ ++ -1, -1, -1, 17, 18, 19, -1, -1, /* 0xa000-0xafff */ ++ -1, -1, -1, -1, -1, -1, -1, -1, /* 0xb000-0xbfff */ ++ -1, -1, -1, -1, -1, -1, -1, -1, /* 0xc000-0xcfff */ ++ -1, -1, -1, -1, -1, -1, -1, -1, /* 0xd000-0xdfff */ ++ -1, -1, -1, -1, -1, -1, -1, -1, /* 0xe000-0xefff */ ++ -1, -1, -1, -1, -1, 20, -1, 21, /* 0xf000-0xffff */ ++ 22, -1, -1, -1, -1, 23, -1, -1, /* 0x10000-0x10fff */ ++ 24, -1, -1, -1, -1, -1, -1, -1, /* 0x11000-0x11fff */ ++ -1, -1, -1, -1, -1, -1, -1, -1, /* 0x12000-0x12fff */ ++ -1, -1, -1, -1, -1, -1, -1, -1, /* 0x13000-0x13fff */ ++ -1, -1, -1, -1, -1, -1, -1, -1, /* 0x14000-0x14fff */ ++ -1, -1, -1, -1, -1, -1, -1, -1, /* 0x15000-0x15fff */ ++ -1, -1, -1, -1, -1, -1, -1, -1, /* 0x16000-0x16fff */ ++ -1, -1, -1, -1, -1, -1, -1, -1, /* 0x17000-0x17fff */ ++ -1, -1, -1, -1, -1, -1, -1, -1, /* 0x18000-0x18fff */ ++ -1, -1, -1, -1, -1, -1, -1, -1, /* 0x19000-0x19fff */ ++ -1, -1, -1, -1, -1, -1, -1, -1, /* 0x1a000-0x1afff */ ++ -1, -1, -1, -1, -1, -1, -1, -1, /* 0x1b000-0x1bfff */ ++ -1, -1, -1, -1, -1, -1, -1, -1, /* 0x1c000-0x1cfff */ ++ 25, 26, -1, -1, -1, -1, -1, -1 /* 0x1d000-0x1dfff */ ++}; ++ ++/* Determine number of column positions required for UC. */ ++int ++uc_width (ucs4_t uc, const char *encoding) ++{ ++ /* Test for non-spacing or control character. */ ++ if ((uc >> 9) < 240) ++ { ++ int ind = nonspacing_table_ind[uc >> 9]; ++ if (ind >= 0) ++ if ((nonspacing_table_data[64*ind + ((uc >> 3) & 63)] >> (uc & 7)) & 1) ++ { ++ if (uc > 0 && uc < 0xa0) ++ return -1; ++ else ++ return 0; ++ } ++ } ++ else if ((uc >> 9) == (0xe0000 >> 9)) ++ { ++ if (uc >= 0xe0100) ++ { ++ if (uc <= 0xe01ef) ++ return 0; ++ } ++ else ++ { ++ if (uc >= 0xe0020 ? uc <= 0xe007f : uc == 0xe0001) ++ return 0; ++ } ++ } ++ /* Test for double-width character. ++ * Generated from "grep '^[^;]\{4,5\};[WF]' EastAsianWidth.txt" ++ * and "grep '^[^;]\{4,5\};[^WF]' EastAsianWidth.txt" ++ */ ++ if (uc >= 0x1100 ++ && ((uc < 0x1160) /* Hangul Jamo */ ++ || (uc >= 0x2329 && uc < 0x232b) /* Angle Brackets */ ++ || (uc >= 0x2e80 && uc < 0xa4d0 /* CJK ... Yi */ ++ && !(uc == 0x303f) && !(uc >= 0x4dc0 && uc < 0x4e00)) ++ || (uc >= 0xac00 && uc < 0xd7a4) /* Hangul Syllables */ ++ || (uc >= 0xf900 && uc < 0xfb00) /* CJK Compatibility Ideographs */ ++ || (uc >= 0xfe10 && uc < 0xfe20) /* Presentation Forms for Vertical */ ++ || (uc >= 0xfe30 && uc < 0xfe70) /* CJK Compatibility Forms */ ++ || (uc >= 0xff00 && uc < 0xff61) /* Fullwidth Forms */ ++ || (uc >= 0xffe0 && uc < 0xffe7) /* Fullwidth Signs */ ++ || (uc >= 0x20000 && uc <= 0x2ffff) /* Supplementary Ideographic Plane */ ++ || (uc >= 0x30000 && uc <= 0x3ffff) /* Tertiary Ideographic Plane */ ++ ) ) ++ return 2; ++ /* In ancient CJK encodings, Cyrillic and most other characters are ++ double-width as well. */ ++ if (uc >= 0x00A1 && uc < 0xFF61 && uc != 0x20A9 ++ && is_cjk_encoding (encoding)) ++ return 2; ++ return 1; ++} +diff --git a/grub-core/gnulib/vasnprintf.c b/grub-core/gnulib/vasnprintf.c +index e618901..8fdab32 100644 +--- a/grub-core/gnulib/vasnprintf.c ++++ b/grub-core/gnulib/vasnprintf.c +@@ -1,5 +1,5 @@ + /* vsprintf with automatic memory allocation. +- Copyright (C) 1999, 2002-2010 Free Software Foundation, Inc. ++ Copyright (C) 1999, 2002-2013 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 +@@ -12,8 +12,7 @@ + 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. */ ++ with this program; if not, see . */ + + /* This file can be parametrized with the following macros: + VASNPRINTF The name of the function being defined. +@@ -88,6 +87,8 @@ + /* Checked size_t computations. */ + #include "xsize.h" + ++#include "verify.h" ++ + #if (NEED_PRINTF_DOUBLE || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL + # include + # include "float+.h" +@@ -274,10 +275,10 @@ decimal_point_char (void) + { + const char *point; + /* Determine it in a multithread-safe way. We know nl_langinfo is +- multithread-safe on glibc systems and MacOS X systems, but is not required ++ multithread-safe on glibc systems and Mac OS X systems, but is not required + to be multithread-safe by POSIX. sprintf(), however, is multithread-safe. + localeconv() is rarely multithread-safe. */ +-# if HAVE_NL_LANGINFO && (__GLIBC__ || (defined __APPLE__ && defined __MACH__)) ++# if HAVE_NL_LANGINFO && (__GLIBC__ || defined __UCLIBC__ || (defined __APPLE__ && defined __MACH__)) + point = nl_langinfo (RADIXCHAR); + # elif 1 + char pointbuf[5]; +@@ -322,11 +323,11 @@ is_infinite_or_zerol (long double x) + + typedef unsigned int mp_limb_t; + # define GMP_LIMB_BITS 32 +-typedef int mp_limb_verify[2 * (sizeof (mp_limb_t) * CHAR_BIT == GMP_LIMB_BITS) - 1]; ++verify (sizeof (mp_limb_t) * CHAR_BIT == GMP_LIMB_BITS); + + typedef unsigned long long mp_twolimb_t; + # define GMP_TWOLIMB_BITS 64 +-typedef int mp_twolimb_verify[2 * (sizeof (mp_twolimb_t) * CHAR_BIT == GMP_TWOLIMB_BITS) - 1]; ++verify (sizeof (mp_twolimb_t) * CHAR_BIT == GMP_TWOLIMB_BITS); + + /* Representation of a bignum >= 0. */ + typedef struct +@@ -551,32 +552,61 @@ divide (mpn_t a, mpn_t b, mpn_t *q) + size_t s; + { + mp_limb_t msd = b_ptr[b_len - 1]; /* = b[n-1], > 0 */ +- s = 31; +- if (msd >= 0x10000) +- { +- msd = msd >> 16; +- s -= 16; +- } +- if (msd >= 0x100) +- { +- msd = msd >> 8; +- s -= 8; +- } +- if (msd >= 0x10) +- { +- msd = msd >> 4; +- s -= 4; +- } +- if (msd >= 0x4) ++ /* Determine s = GMP_LIMB_BITS - integer_length (msd). ++ Code copied from gnulib's integer_length.c. */ ++# if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) ++ s = __builtin_clz (msd); ++# else ++# if defined DBL_EXPBIT0_WORD && defined DBL_EXPBIT0_BIT ++ if (GMP_LIMB_BITS <= DBL_MANT_BIT) + { +- msd = msd >> 2; +- s -= 2; ++ /* Use 'double' operations. ++ Assumes an IEEE 754 'double' implementation. */ ++# define DBL_EXP_MASK ((DBL_MAX_EXP - DBL_MIN_EXP) | 7) ++# define DBL_EXP_BIAS (DBL_EXP_MASK / 2 - 1) ++# define NWORDS \ ++ ((sizeof (double) + sizeof (unsigned int) - 1) / sizeof (unsigned int)) ++ union { double value; unsigned int word[NWORDS]; } m; ++ ++ /* Use a single integer to floating-point conversion. */ ++ m.value = msd; ++ ++ s = GMP_LIMB_BITS ++ - (((m.word[DBL_EXPBIT0_WORD] >> DBL_EXPBIT0_BIT) & DBL_EXP_MASK) ++ - DBL_EXP_BIAS); + } +- if (msd >= 0x2) ++ else ++# undef NWORDS ++# endif + { +- msd = msd >> 1; +- s -= 1; ++ s = 31; ++ if (msd >= 0x10000) ++ { ++ msd = msd >> 16; ++ s -= 16; ++ } ++ if (msd >= 0x100) ++ { ++ msd = msd >> 8; ++ s -= 8; ++ } ++ if (msd >= 0x10) ++ { ++ msd = msd >> 4; ++ s -= 4; ++ } ++ if (msd >= 0x4) ++ { ++ msd = msd >> 2; ++ s -= 2; ++ } ++ if (msd >= 0x2) ++ { ++ msd = msd >> 1; ++ s -= 1; ++ } + } ++# endif + } + /* 0 <= s < GMP_LIMB_BITS. + Copy b, shifting it left by s bits. */ +@@ -883,9 +913,9 @@ decode_long_double (long double x, int *ep, mpn_t *mp) + y = frexpl (x, &exp); + if (!(y >= 0.0L && y < 1.0L)) + abort (); +- /* x = 2^exp * y = 2^(exp - LDBL_MANT_BIT) * (y * LDBL_MANT_BIT), and the ++ /* x = 2^exp * y = 2^(exp - LDBL_MANT_BIT) * (y * 2^LDBL_MANT_BIT), and the + latter is an integer. */ +- /* Convert the mantissa (y * LDBL_MANT_BIT) to a sequence of limbs. ++ /* Convert the mantissa (y * 2^LDBL_MANT_BIT) to a sequence of limbs. + I'm not sure whether it's safe to cast a 'long double' value between + 2^31 and 2^32 to 'unsigned int', therefore play safe and cast only + 'long double' values between 0 and 2^16 (to 'unsigned int' or 'int', +@@ -933,11 +963,11 @@ decode_long_double (long double x, int *ep, mpn_t *mp) + abort (); + m.limbs[--i] = (hi << (GMP_LIMB_BITS / 2)) | lo; + } +-#if 0 /* On FreeBSD 6.1/x86, 'long double' numbers sometimes have excess +- precision. */ ++# if 0 /* On FreeBSD 6.1/x86, 'long double' numbers sometimes have excess ++ precision. */ + if (!(y == 0.0L)) + abort (); +-#endif ++# endif + /* Normalise. */ + while (m.nlimbs > 0 && m.limbs[m.nlimbs - 1] == 0) + m.nlimbs--; +@@ -971,9 +1001,9 @@ decode_double (double x, int *ep, mpn_t *mp) + y = frexp (x, &exp); + if (!(y >= 0.0 && y < 1.0)) + abort (); +- /* x = 2^exp * y = 2^(exp - DBL_MANT_BIT) * (y * DBL_MANT_BIT), and the ++ /* x = 2^exp * y = 2^(exp - DBL_MANT_BIT) * (y * 2^DBL_MANT_BIT), and the + latter is an integer. */ +- /* Convert the mantissa (y * DBL_MANT_BIT) to a sequence of limbs. ++ /* Convert the mantissa (y * 2^DBL_MANT_BIT) to a sequence of limbs. + I'm not sure whether it's safe to cast a 'double' value between + 2^31 and 2^32 to 'unsigned int', therefore play safe and cast only + 'double' values between 0 and 2^16 (to 'unsigned int' or 'int', +@@ -1500,7 +1530,7 @@ is_borderline (const char *digits, size_t precision) + + /* Returns the number of TCHAR_T units needed as temporary space for the result + of sprintf or SNPRINTF of a single conversion directive. */ +-static inline size_t ++static size_t + MAX_ROOM_NEEDED (const arguments *ap, size_t arg_index, FCHAR_T conversion, + arg_type type, int flags, size_t width, int has_precision, + size_t precision, int pad_ourselves) +@@ -1751,8 +1781,9 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, + return NULL; + + #define CLEANUP() \ +- free (d.dir); \ +- if (a.arg) \ ++ if (d.dir != d.direct_alloc_dir) \ ++ free (d.dir); \ ++ if (a.arg != a.direct_alloc_arg) \ + free (a.arg); + + if (PRINTF_FETCHARGS (args, &a) < 0) +@@ -2621,7 +2652,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, + size_t characters; + # if !DCHAR_IS_TCHAR + /* This code assumes that TCHAR_T is 'char'. */ +- typedef int TCHAR_T_verify[2 * (sizeof (TCHAR_T) == 1) - 1]; ++ verify (sizeof (TCHAR_T) == 1); + TCHAR_T *tmpsrc; + DCHAR_T *tmpdst; + size_t tmpdst_len; +@@ -2782,7 +2813,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, + if (has_width) + { + # if ENABLE_UNISTDIO +- /* Outside POSIX, it's preferrable to compare the width ++ /* Outside POSIX, it's preferable to compare the width + against the number of _characters_ of the converted + value. */ + w = DCHAR_MBSNLEN (result + length, characters); +@@ -4597,6 +4628,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, + TCHAR_T *fbp; + unsigned int prefix_count; + int prefixes[2] IF_LINT (= { 0 }); ++ int orig_errno; + #if !USE_SNPRINTF + size_t tmp_length; + TCHAR_T tmpbuf[700]; +@@ -4751,6 +4783,10 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, + *fbp++ = ' '; + if (flags & FLAG_ALT) + *fbp++ = '#'; ++#if __GLIBC__ >= 2 && !defined __UCLIBC__ ++ if (flags & FLAG_LOCALIZED) ++ *fbp++ = 'I'; ++#endif + if (!pad_ourselves) + { + if (flags & FLAG_ZERO) +@@ -4834,20 +4870,21 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, + #endif + *fbp = dp->conversion; + #if USE_SNPRINTF +-# if !(__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3) || ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__)) ++# if !(((__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3)) && !defined __UCLIBC__) || ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__)) + fbp[1] = '%'; + fbp[2] = 'n'; + fbp[3] = '\0'; + # else + /* On glibc2 systems from glibc >= 2.3 - probably also older +- ones - we know that snprintf's returns value conforms to +- ISO C 99: the gl_SNPRINTF_DIRECTIVE_N test passes. ++ ones - we know that snprintf's return value conforms to ++ ISO C 99: the tests gl_SNPRINTF_RETVAL_C99 and ++ gl_SNPRINTF_TRUNCATION_C99 pass. + Therefore we can avoid using %n in this situation. + On glibc2 systems from 2004-10-18 or newer, the use of %n + in format strings in writable memory may crash the program + (if compiled with _FORTIFY_SOURCE=2), so we should avoid it + in this situation. */ +- /* On native Win32 systems (such as mingw), we can avoid using ++ /* On native Windows systems (such as mingw), we can avoid using + %n because: + - Although the gl_SNPRINTF_TRUNCATION_C99 test fails, + snprintf does not write more than the specified number +@@ -4856,7 +4893,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, + - Although the gl_SNPRINTF_RETVAL_C99 test fails, snprintf + allows us to recognize the case of an insufficient + buffer size: it returns -1 in this case. +- On native Win32 systems (such as mingw) where the OS is ++ On native Windows systems (such as mingw) where the OS is + Windows Vista, the use of %n in format strings by default + crashes the program. See + and +@@ -4900,6 +4937,8 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, + *(TCHAR_T *) (result + length) = '\0'; + #endif + ++ orig_errno = errno; ++ + for (;;) + { + int count = -1; +@@ -5284,8 +5323,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, + DCHAR_T *tmpdst; + size_t tmpdst_len; + /* This code assumes that TCHAR_T is 'char'. */ +- typedef int TCHAR_T_verify +- [2 * (sizeof (TCHAR_T) == 1) - 1]; ++ verify (sizeof (TCHAR_T) == 1); + # if USE_SNPRINTF + tmpsrc = (TCHAR_T *) (result + length); + # else +@@ -5378,7 +5416,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, + { + size_t w; + # if ENABLE_UNISTDIO +- /* Outside POSIX, it's preferrable to compare the width ++ /* Outside POSIX, it's preferable to compare the width + against the number of _characters_ of the converted + value. */ + w = DCHAR_MBSNLEN (result + length, count); +@@ -5498,6 +5536,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, + length += count; + break; + } ++ errno = orig_errno; + #undef pad_ourselves + #undef prec_ourselves + } +diff --git a/grub-core/gnulib/vasnprintf.h b/grub-core/gnulib/vasnprintf.h +index a689bad..7658f50 100644 +--- a/grub-core/gnulib/vasnprintf.h ++++ b/grub-core/gnulib/vasnprintf.h +@@ -1,5 +1,5 @@ + /* vsprintf with automatic memory allocation. +- Copyright (C) 2002-2004, 2007-2010 Free Software Foundation, Inc. ++ Copyright (C) 2002-2004, 2007-2013 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 +@@ -12,8 +12,7 @@ + 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. */ ++ with this program; if not, see . */ + + #ifndef _VASNPRINTF_H + #define _VASNPRINTF_H +@@ -24,16 +23,16 @@ + /* Get size_t. */ + #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 ++ We enable _GL_ATTRIBUTE_FORMAT 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 ++#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7) ++# define _GL_ATTRIBUTE_FORMAT(spec) __attribute__ ((__format__ spec)) ++#else ++# define _GL_ATTRIBUTE_FORMAT(spec) /* empty */ + #endif + + #ifdef __cplusplus +@@ -69,9 +68,9 @@ extern "C" { + # define vasnprintf rpl_vasnprintf + #endif + extern char * asnprintf (char *resultbuf, size_t *lengthp, const char *format, ...) +- __attribute__ ((__format__ (__printf__, 3, 4))); ++ _GL_ATTRIBUTE_FORMAT ((__printf__, 3, 4)); + extern char * vasnprintf (char *resultbuf, size_t *lengthp, const char *format, va_list args) +- __attribute__ ((__format__ (__printf__, 3, 0))); ++ _GL_ATTRIBUTE_FORMAT ((__printf__, 3, 0)); + + #ifdef __cplusplus + } +diff --git a/grub-core/gnulib/verify.h b/grub-core/gnulib/verify.h +index 4ad780c..cb8e90b 100644 +--- a/grub-core/gnulib/verify.h ++++ b/grub-core/gnulib/verify.h +@@ -1,6 +1,6 @@ + /* Compile-time assert-like macros. + +- Copyright (C) 2005-2006, 2009-2010 Free Software Foundation, Inc. ++ Copyright (C) 2005-2006, 2009-2013 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 +@@ -17,21 +17,39 @@ + + /* Written by Paul Eggert, Bruno Haible, and Jim Meyering. */ + +-#ifndef VERIFY_H +-# define VERIFY_H 1 ++#ifndef _GL_VERIFY_H ++# define _GL_VERIFY_H ++ ++ ++/* Define _GL_HAVE__STATIC_ASSERT to 1 if _Static_assert works as per C11. ++ This is supported by GCC 4.6.0 and later, in C mode, and its use ++ here generates easier-to-read diagnostics when verify (R) fails. ++ ++ Define _GL_HAVE_STATIC_ASSERT to 1 if static_assert works as per C++11. ++ This will likely be supported by future GCC versions, in C++ mode. ++ ++ Use this only with GCC. If we were willing to slow 'configure' ++ down we could also use it with other compilers, but since this ++ affects only the quality of diagnostics, why bother? */ ++# if (4 < __GNUC__ || (__GNUC__ == 4 && 6 <= __GNUC_MINOR__)) && !defined __cplusplus ++# define _GL_HAVE__STATIC_ASSERT 1 ++# endif ++/* The condition (99 < __GNUC__) is temporary, until we know about the ++ first G++ release that supports static_assert. */ ++# if (99 < __GNUC__) && defined __cplusplus ++# define _GL_HAVE_STATIC_ASSERT 1 ++# endif + + /* Each of these macros verifies that its argument R is nonzero. To + be portable, R should be an integer constant expression. Unlike + assert (R), there is no run-time overhead. + +- There are two macros, since no single macro can be used in all +- contexts in C. verify_true (R) is for scalar contexts, including +- integer constant expression contexts. verify (R) is for declaration +- contexts, e.g., the top level. +- +- Symbols ending in "__" are private to this header. ++ If _Static_assert works, verify (R) uses it directly. Similarly, ++ _GL_VERIFY_TRUE works by packaging a _Static_assert inside a struct ++ that is an operand of sizeof. + +- The code below uses several ideas. ++ The code below uses several ideas for C++ compilers, and for C ++ compilers that do not support _Static_assert: + + * The first step is ((R) ? 1 : -1). Given an expression R, of + integral or boolean or floating-point type, this yields an +@@ -39,7 +57,9 @@ + constant and nonnegative. + + * Next this expression W is wrapped in a type +- struct verify_type__ { unsigned int verify_error_if_negative_size__: W; }. ++ struct _gl_verify_type { ++ unsigned int _gl_verify_error_if_negative: W; ++ }. + If W is negative, this yields a compile-time error. No compiler can + deal with a bit-field of negative size. + +@@ -53,7 +73,7 @@ + + void function (int n) { verify (n < 0); } + +- * For the verify macro, the struct verify_type__ will need to ++ * For the verify macro, the struct _gl_verify_type will need to + somehow be embedded into a declaration. To be portable, this + declaration must declare an object, a constant, a function, or a + typedef name. If the declared entity uses the type directly, +@@ -91,11 +111,11 @@ + Which of the following alternatives can be used? + + extern int dummy [sizeof (struct {...})]; +- extern int dummy [sizeof (struct verify_type__ {...})]; ++ extern int dummy [sizeof (struct _gl_verify_type {...})]; + extern void dummy (int [sizeof (struct {...})]); +- extern void dummy (int [sizeof (struct verify_type__ {...})]); ++ extern void dummy (int [sizeof (struct _gl_verify_type {...})]); + extern int (*dummy (void)) [sizeof (struct {...})]; +- extern int (*dummy (void)) [sizeof (struct verify_type__ {...})]; ++ extern int (*dummy (void)) [sizeof (struct _gl_verify_type {...})]; + + In the second and sixth case, the struct type is exported to the + outer scope; two such declarations therefore collide. GCC warns +@@ -105,19 +125,17 @@ + extern int (*dummy (void)) [sizeof (struct {...})]; + + * GCC warns about duplicate declarations of the dummy function if +- -Wredundant_decls is used. GCC 4.3 and later have a builtin ++ -Wredundant-decls is used. GCC 4.3 and later have a builtin + __COUNTER__ macro that can let us generate unique identifiers for + each dummy function, to suppress this warning. + +- * This implementation exploits the fact that GCC does not warn about +- the last declaration mentioned above. If a future version of GCC +- introduces a warning for this, the problem could be worked around +- by using code specialized to GCC, just as __COUNTER__ is already +- being used if available. ++ * This implementation exploits the fact that older versions of GCC, ++ which do not support _Static_assert, also do not warn about the ++ last declaration mentioned above. + +- #if 4 <= __GNUC__ +- # define verify(R) [another version to keep GCC happy] +- #endif ++ * GCC warns if -Wnested-externs is enabled and verify() is used ++ within a function body; but inside a function, you can always ++ arrange to use verify_expr() instead. + + * In C++, any struct definition inside sizeof is invalid. + Use a template type to work around the problem. */ +@@ -140,24 +158,88 @@ + possible. */ + # define _GL_GENSYM(prefix) _GL_CONCAT (prefix, _GL_COUNTER) + +-/* Verify requirement R at compile-time, as an integer constant expression. +- Return 1. */ ++/* Verify requirement R at compile-time, as an integer constant expression ++ that returns 1. If R is false, fail at compile-time, preferably ++ with a diagnostic that includes the string-literal DIAGNOSTIC. */ ++ ++# define _GL_VERIFY_TRUE(R, DIAGNOSTIC) \ ++ (!!sizeof (_GL_VERIFY_TYPE (R, DIAGNOSTIC))) + + # ifdef __cplusplus ++# if !GNULIB_defined_struct__gl_verify_type + template +- struct verify_type__ { unsigned int verify_error_if_negative_size__: w; }; +-# define verify_true(R) \ +- (!!sizeof (verify_type__<(R) ? 1 : -1>)) ++ struct _gl_verify_type { ++ unsigned int _gl_verify_error_if_negative: w; ++ }; ++# define GNULIB_defined_struct__gl_verify_type 1 ++# endif ++# define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \ ++ _gl_verify_type<(R) ? 1 : -1> ++# elif defined _GL_HAVE__STATIC_ASSERT ++# define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \ ++ struct { \ ++ _Static_assert (R, DIAGNOSTIC); \ ++ int _gl_dummy; \ ++ } ++# else ++# define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \ ++ struct { unsigned int _gl_verify_error_if_negative: (R) ? 1 : -1; } ++# endif ++ ++/* Verify requirement R at compile-time, as a declaration without a ++ trailing ';'. If R is false, fail at compile-time, preferably ++ with a diagnostic that includes the string-literal DIAGNOSTIC. ++ ++ Unfortunately, unlike C11, this implementation must appear as an ++ ordinary declaration, and cannot appear inside struct { ... }. */ ++ ++# ifdef _GL_HAVE__STATIC_ASSERT ++# define _GL_VERIFY _Static_assert + # else +-# define verify_true(R) \ +- (!!sizeof \ +- (struct { unsigned int verify_error_if_negative_size__: (R) ? 1 : -1; })) ++# define _GL_VERIFY(R, DIAGNOSTIC) \ ++ extern int (*_GL_GENSYM (_gl_verify_function) (void)) \ ++ [_GL_VERIFY_TRUE (R, DIAGNOSTIC)] + # endif + ++/* _GL_STATIC_ASSERT_H is defined if this code is copied into assert.h. */ ++# ifdef _GL_STATIC_ASSERT_H ++# if !defined _GL_HAVE__STATIC_ASSERT && !defined _Static_assert ++# define _Static_assert(R, DIAGNOSTIC) _GL_VERIFY (R, DIAGNOSTIC) ++# endif ++# if !defined _GL_HAVE_STATIC_ASSERT && !defined static_assert ++# define static_assert _Static_assert /* C11 requires this #define. */ ++# endif ++# endif ++ ++/* @assert.h omit start@ */ ++ ++/* Each of these macros verifies that its argument R is nonzero. To ++ be portable, R should be an integer constant expression. Unlike ++ assert (R), there is no run-time overhead. ++ ++ There are two macros, since no single macro can be used in all ++ contexts in C. verify_true (R) is for scalar contexts, including ++ integer constant expression contexts. verify (R) is for declaration ++ contexts, e.g., the top level. */ ++ ++/* Verify requirement R at compile-time, as an integer constant expression. ++ Return 1. This is equivalent to verify_expr (R, 1). ++ ++ verify_true is obsolescent; please use verify_expr instead. */ ++ ++# define verify_true(R) _GL_VERIFY_TRUE (R, "verify_true (" #R ")") ++ ++/* Verify requirement R at compile-time. Return the value of the ++ expression E. */ ++ ++# define verify_expr(R, E) \ ++ (_GL_VERIFY_TRUE (R, "verify_expr (" #R ", " #E ")") ? (E) : (E)) ++ + /* Verify requirement R at compile-time, as a declaration without a + trailing ';'. */ + +-# define verify(R) \ +- extern int (* _GL_GENSYM (verify_function) (void)) [verify_true (R)] ++# define verify(R) _GL_VERIFY (R, "verify (" #R ")") ++ ++/* @assert.h omit end@ */ + + #endif +diff --git a/grub-core/gnulib/vsnprintf.c b/grub-core/gnulib/vsnprintf.c +index d447cc2..7d4dfbe 100644 +--- a/grub-core/gnulib/vsnprintf.c ++++ b/grub-core/gnulib/vsnprintf.c +@@ -1,5 +1,5 @@ + /* Formatted output to strings. +- Copyright (C) 2004, 2006-2010 Free Software Foundation, Inc. ++ Copyright (C) 2004, 2006-2013 Free Software Foundation, Inc. + Written by Simon Josefsson and Yoann Vandoorselaere . + + This program is free software; you can redistribute it and/or modify +@@ -13,8 +13,7 @@ + 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. */ ++ with this program; if not, see . */ + + #ifdef HAVE_CONFIG_H + # include +diff --git a/grub-core/gnulib/wchar.in.h b/grub-core/gnulib/wchar.in.h +index 88d47db..b6e4362 100644 +--- a/grub-core/gnulib/wchar.in.h ++++ b/grub-core/gnulib/wchar.in.h +@@ -1,6 +1,6 @@ + /* A substitute for ISO C99 , for platforms that have issues. + +- Copyright (C) 2007-2010 Free Software Foundation, Inc. ++ Copyright (C) 2007-2013 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 +@@ -13,8 +13,7 @@ + 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. */ ++ along with this program; if not, see . */ + + /* Written by Eric Blake. */ + +@@ -29,6 +28,7 @@ + #if __GNUC__ >= 3 + @PRAGMA_SYSTEM_HEADER@ + #endif ++@PRAGMA_COLUMNS@ + + #if defined __need_mbstate_t || defined __need_wint_t || (defined __hpux && ((defined _INTTYPES_INCLUDED && !defined strtoimax) || defined _GL_JUST_INCLUDE_SYSTEM_WCHAR_H)) || defined _GL_ALREADY_INCLUDING_WCHAR_H + /* Special invocation convention: +@@ -48,17 +48,25 @@ + #else + /* Normal invocation convention. */ + +-#ifndef _GL_WCHAR_H ++#ifndef _@GUARD_PREFIX@_WCHAR_H + + #define _GL_ALREADY_INCLUDING_WCHAR_H + ++#if @HAVE_FEATURES_H@ ++# include /* for __GLIBC__ */ ++#endif ++ + /* Tru64 with Desktop Toolkit C has a bug: must be included before + . + BSD/OS 4.0.1 has a bug: , and must be + included before . ++ In some builds of uClibc, is nonexistent and wchar_t is defined ++ by . + But avoid namespace pollution on glibc systems. */ +-#ifndef __GLIBC__ ++#if !(defined __GLIBC__ && !defined __UCLIBC__) + # include ++#endif ++#ifndef __GLIBC__ + # include + # include + #endif +@@ -72,8 +80,16 @@ + + #undef _GL_ALREADY_INCLUDING_WCHAR_H + +-#ifndef _GL_WCHAR_H +-#define _GL_WCHAR_H ++#ifndef _@GUARD_PREFIX@_WCHAR_H ++#define _@GUARD_PREFIX@_WCHAR_H ++ ++/* The __attribute__ feature is available in gcc versions 2.5 and later. ++ The attribute __pure__ was added in gcc 2.96. */ ++#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) ++# define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__)) ++#else ++# define _GL_ATTRIBUTE_PURE /* empty */ ++#endif + + /* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ + +@@ -89,6 +105,18 @@ + # define WEOF -1 + # endif + #else ++/* MSVC defines wint_t as 'unsigned short' in . ++ This is too small: ISO C 99 section 7.24.1.(2) says that wint_t must be ++ "unchanged by default argument promotions". Override it. */ ++# if defined _MSC_VER ++# if !GNULIB_defined_wint_t ++# include ++typedef unsigned int rpl_wint_t; ++# undef wint_t ++# define wint_t rpl_wint_t ++# define GNULIB_defined_wint_t 1 ++# endif ++# endif + # ifndef WEOF + # define WEOF ((wint_t) -1) + # endif +@@ -99,10 +127,12 @@ + On IRIX 6.5, sizeof (mbstate_t) == 1, which is not sufficient for + implementing mbrtowc for encodings like UTF-8. */ + #if !(@HAVE_MBSINIT@ && @HAVE_MBRTOWC@) || @REPLACE_MBSTATE_T@ ++# if !GNULIB_defined_mbstate_t + typedef int rpl_mbstate_t; +-# undef mbstate_t +-# define mbstate_t rpl_mbstate_t +-# define GNULIB_defined_mbstate_t 1 ++# undef mbstate_t ++# define mbstate_t rpl_mbstate_t ++# define GNULIB_defined_mbstate_t 1 ++# endif + #endif + + +@@ -113,11 +143,11 @@ typedef int rpl_mbstate_t; + # undef btowc + # define btowc rpl_btowc + # endif +-_GL_FUNCDECL_RPL (btowc, wint_t, (int c)); ++_GL_FUNCDECL_RPL (btowc, wint_t, (int c) _GL_ATTRIBUTE_PURE); + _GL_CXXALIAS_RPL (btowc, wint_t, (int c)); + # else + # if !@HAVE_BTOWC@ +-_GL_FUNCDECL_SYS (btowc, wint_t, (int c)); ++_GL_FUNCDECL_SYS (btowc, wint_t, (int c) _GL_ATTRIBUTE_PURE); + # endif + _GL_CXXALIAS_SYS (btowc, wint_t, (int c)); + # endif +@@ -138,12 +168,12 @@ _GL_WARN_ON_USE (btowc, "btowc is unportable - " + # undef wctob + # define wctob rpl_wctob + # endif +-_GL_FUNCDECL_RPL (wctob, int, (wint_t wc)); ++_GL_FUNCDECL_RPL (wctob, int, (wint_t wc) _GL_ATTRIBUTE_PURE); + _GL_CXXALIAS_RPL (wctob, int, (wint_t wc)); + # else + # if !defined wctob && !@HAVE_DECL_WCTOB@ + /* wctob is provided by gnulib, or wctob exists but is not declared. */ +-_GL_FUNCDECL_SYS (wctob, int, (wint_t wc)); ++_GL_FUNCDECL_SYS (wctob, int, (wint_t wc) _GL_ATTRIBUTE_PURE); + # endif + _GL_CXXALIAS_SYS (wctob, int, (wint_t wc)); + # endif +@@ -404,12 +434,12 @@ _GL_WARN_ON_USE (wcsnrtombs, "wcsnrtombs is unportable - " + # undef wcwidth + # define wcwidth rpl_wcwidth + # endif +-_GL_FUNCDECL_RPL (wcwidth, int, (wchar_t)); ++_GL_FUNCDECL_RPL (wcwidth, int, (wchar_t) _GL_ATTRIBUTE_PURE); + _GL_CXXALIAS_RPL (wcwidth, int, (wchar_t)); + # else + # if !@HAVE_DECL_WCWIDTH@ + /* wcwidth exists but is not declared. */ +-_GL_FUNCDECL_SYS (wcwidth, int, (wchar_t)); ++_GL_FUNCDECL_SYS (wcwidth, int, (wchar_t) _GL_ATTRIBUTE_PURE); + # endif + _GL_CXXALIAS_SYS (wcwidth, int, (wchar_t)); + # endif +@@ -423,6 +453,576 @@ _GL_WARN_ON_USE (wcwidth, "wcwidth is unportable - " + #endif + + +-#endif /* _GL_WCHAR_H */ +-#endif /* _GL_WCHAR_H */ ++/* Search N wide characters of S for C. */ ++#if @GNULIB_WMEMCHR@ ++# if !@HAVE_WMEMCHR@ ++_GL_FUNCDECL_SYS (wmemchr, wchar_t *, (const wchar_t *s, wchar_t c, size_t n) ++ _GL_ATTRIBUTE_PURE); ++# endif ++ /* On some systems, this function is defined as an overloaded function: ++ extern "C++" { ++ const wchar_t * std::wmemchr (const wchar_t *, wchar_t, size_t); ++ wchar_t * std::wmemchr (wchar_t *, wchar_t, size_t); ++ } */ ++_GL_CXXALIAS_SYS_CAST2 (wmemchr, ++ wchar_t *, (const wchar_t *, wchar_t, size_t), ++ const wchar_t *, (const wchar_t *, wchar_t, size_t)); ++# if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \ ++ && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) ++_GL_CXXALIASWARN1 (wmemchr, wchar_t *, (wchar_t *s, wchar_t c, size_t n)); ++_GL_CXXALIASWARN1 (wmemchr, const wchar_t *, ++ (const wchar_t *s, wchar_t c, size_t n)); ++# else ++_GL_CXXALIASWARN (wmemchr); ++# endif ++#elif defined GNULIB_POSIXCHECK ++# undef wmemchr ++# if HAVE_RAW_DECL_WMEMCHR ++_GL_WARN_ON_USE (wmemchr, "wmemchr is unportable - " ++ "use gnulib module wmemchr for portability"); ++# endif ++#endif ++ ++ ++/* Compare N wide characters of S1 and S2. */ ++#if @GNULIB_WMEMCMP@ ++# if !@HAVE_WMEMCMP@ ++_GL_FUNCDECL_SYS (wmemcmp, int, ++ (const wchar_t *s1, const wchar_t *s2, size_t n) ++ _GL_ATTRIBUTE_PURE); ++# endif ++_GL_CXXALIAS_SYS (wmemcmp, int, ++ (const wchar_t *s1, const wchar_t *s2, size_t n)); ++_GL_CXXALIASWARN (wmemcmp); ++#elif defined GNULIB_POSIXCHECK ++# undef wmemcmp ++# if HAVE_RAW_DECL_WMEMCMP ++_GL_WARN_ON_USE (wmemcmp, "wmemcmp is unportable - " ++ "use gnulib module wmemcmp for portability"); ++# endif ++#endif ++ ++ ++/* Copy N wide characters of SRC to DEST. */ ++#if @GNULIB_WMEMCPY@ ++# if !@HAVE_WMEMCPY@ ++_GL_FUNCDECL_SYS (wmemcpy, wchar_t *, ++ (wchar_t *dest, const wchar_t *src, size_t n)); ++# endif ++_GL_CXXALIAS_SYS (wmemcpy, wchar_t *, ++ (wchar_t *dest, const wchar_t *src, size_t n)); ++_GL_CXXALIASWARN (wmemcpy); ++#elif defined GNULIB_POSIXCHECK ++# undef wmemcpy ++# if HAVE_RAW_DECL_WMEMCPY ++_GL_WARN_ON_USE (wmemcpy, "wmemcpy is unportable - " ++ "use gnulib module wmemcpy for portability"); ++# endif ++#endif ++ ++ ++/* Copy N wide characters of SRC to DEST, guaranteeing correct behavior for ++ overlapping memory areas. */ ++#if @GNULIB_WMEMMOVE@ ++# if !@HAVE_WMEMMOVE@ ++_GL_FUNCDECL_SYS (wmemmove, wchar_t *, ++ (wchar_t *dest, const wchar_t *src, size_t n)); ++# endif ++_GL_CXXALIAS_SYS (wmemmove, wchar_t *, ++ (wchar_t *dest, const wchar_t *src, size_t n)); ++_GL_CXXALIASWARN (wmemmove); ++#elif defined GNULIB_POSIXCHECK ++# undef wmemmove ++# if HAVE_RAW_DECL_WMEMMOVE ++_GL_WARN_ON_USE (wmemmove, "wmemmove is unportable - " ++ "use gnulib module wmemmove for portability"); ++# endif ++#endif ++ ++ ++/* Set N wide characters of S to C. */ ++#if @GNULIB_WMEMSET@ ++# if !@HAVE_WMEMSET@ ++_GL_FUNCDECL_SYS (wmemset, wchar_t *, (wchar_t *s, wchar_t c, size_t n)); ++# endif ++_GL_CXXALIAS_SYS (wmemset, wchar_t *, (wchar_t *s, wchar_t c, size_t n)); ++_GL_CXXALIASWARN (wmemset); ++#elif defined GNULIB_POSIXCHECK ++# undef wmemset ++# if HAVE_RAW_DECL_WMEMSET ++_GL_WARN_ON_USE (wmemset, "wmemset is unportable - " ++ "use gnulib module wmemset for portability"); ++# endif ++#endif ++ ++ ++/* Return the number of wide characters in S. */ ++#if @GNULIB_WCSLEN@ ++# if !@HAVE_WCSLEN@ ++_GL_FUNCDECL_SYS (wcslen, size_t, (const wchar_t *s) _GL_ATTRIBUTE_PURE); ++# endif ++_GL_CXXALIAS_SYS (wcslen, size_t, (const wchar_t *s)); ++_GL_CXXALIASWARN (wcslen); ++#elif defined GNULIB_POSIXCHECK ++# undef wcslen ++# if HAVE_RAW_DECL_WCSLEN ++_GL_WARN_ON_USE (wcslen, "wcslen is unportable - " ++ "use gnulib module wcslen for portability"); ++# endif ++#endif ++ ++ ++/* Return the number of wide characters in S, but at most MAXLEN. */ ++#if @GNULIB_WCSNLEN@ ++# if !@HAVE_WCSNLEN@ ++_GL_FUNCDECL_SYS (wcsnlen, size_t, (const wchar_t *s, size_t maxlen) ++ _GL_ATTRIBUTE_PURE); ++# endif ++_GL_CXXALIAS_SYS (wcsnlen, size_t, (const wchar_t *s, size_t maxlen)); ++_GL_CXXALIASWARN (wcsnlen); ++#elif defined GNULIB_POSIXCHECK ++# undef wcsnlen ++# if HAVE_RAW_DECL_WCSNLEN ++_GL_WARN_ON_USE (wcsnlen, "wcsnlen is unportable - " ++ "use gnulib module wcsnlen for portability"); ++# endif ++#endif ++ ++ ++/* Copy SRC to DEST. */ ++#if @GNULIB_WCSCPY@ ++# if !@HAVE_WCSCPY@ ++_GL_FUNCDECL_SYS (wcscpy, wchar_t *, (wchar_t *dest, const wchar_t *src)); ++# endif ++_GL_CXXALIAS_SYS (wcscpy, wchar_t *, (wchar_t *dest, const wchar_t *src)); ++_GL_CXXALIASWARN (wcscpy); ++#elif defined GNULIB_POSIXCHECK ++# undef wcscpy ++# if HAVE_RAW_DECL_WCSCPY ++_GL_WARN_ON_USE (wcscpy, "wcscpy is unportable - " ++ "use gnulib module wcscpy for portability"); ++# endif ++#endif ++ ++ ++/* Copy SRC to DEST, returning the address of the terminating L'\0' in DEST. */ ++#if @GNULIB_WCPCPY@ ++# if !@HAVE_WCPCPY@ ++_GL_FUNCDECL_SYS (wcpcpy, wchar_t *, (wchar_t *dest, const wchar_t *src)); ++# endif ++_GL_CXXALIAS_SYS (wcpcpy, wchar_t *, (wchar_t *dest, const wchar_t *src)); ++_GL_CXXALIASWARN (wcpcpy); ++#elif defined GNULIB_POSIXCHECK ++# undef wcpcpy ++# if HAVE_RAW_DECL_WCPCPY ++_GL_WARN_ON_USE (wcpcpy, "wcpcpy is unportable - " ++ "use gnulib module wcpcpy for portability"); ++# endif ++#endif ++ ++ ++/* Copy no more than N wide characters of SRC to DEST. */ ++#if @GNULIB_WCSNCPY@ ++# if !@HAVE_WCSNCPY@ ++_GL_FUNCDECL_SYS (wcsncpy, wchar_t *, ++ (wchar_t *dest, const wchar_t *src, size_t n)); ++# endif ++_GL_CXXALIAS_SYS (wcsncpy, wchar_t *, ++ (wchar_t *dest, const wchar_t *src, size_t n)); ++_GL_CXXALIASWARN (wcsncpy); ++#elif defined GNULIB_POSIXCHECK ++# undef wcsncpy ++# if HAVE_RAW_DECL_WCSNCPY ++_GL_WARN_ON_USE (wcsncpy, "wcsncpy is unportable - " ++ "use gnulib module wcsncpy for portability"); ++# endif ++#endif ++ ++ ++/* Copy no more than N characters of SRC to DEST, returning the address of ++ the last character written into DEST. */ ++#if @GNULIB_WCPNCPY@ ++# if !@HAVE_WCPNCPY@ ++_GL_FUNCDECL_SYS (wcpncpy, wchar_t *, ++ (wchar_t *dest, const wchar_t *src, size_t n)); ++# endif ++_GL_CXXALIAS_SYS (wcpncpy, wchar_t *, ++ (wchar_t *dest, const wchar_t *src, size_t n)); ++_GL_CXXALIASWARN (wcpncpy); ++#elif defined GNULIB_POSIXCHECK ++# undef wcpncpy ++# if HAVE_RAW_DECL_WCPNCPY ++_GL_WARN_ON_USE (wcpncpy, "wcpncpy is unportable - " ++ "use gnulib module wcpncpy for portability"); ++# endif ++#endif ++ ++ ++/* Append SRC onto DEST. */ ++#if @GNULIB_WCSCAT@ ++# if !@HAVE_WCSCAT@ ++_GL_FUNCDECL_SYS (wcscat, wchar_t *, (wchar_t *dest, const wchar_t *src)); ++# endif ++_GL_CXXALIAS_SYS (wcscat, wchar_t *, (wchar_t *dest, const wchar_t *src)); ++_GL_CXXALIASWARN (wcscat); ++#elif defined GNULIB_POSIXCHECK ++# undef wcscat ++# if HAVE_RAW_DECL_WCSCAT ++_GL_WARN_ON_USE (wcscat, "wcscat is unportable - " ++ "use gnulib module wcscat for portability"); ++# endif ++#endif ++ ++ ++/* Append no more than N wide characters of SRC onto DEST. */ ++#if @GNULIB_WCSNCAT@ ++# if !@HAVE_WCSNCAT@ ++_GL_FUNCDECL_SYS (wcsncat, wchar_t *, ++ (wchar_t *dest, const wchar_t *src, size_t n)); ++# endif ++_GL_CXXALIAS_SYS (wcsncat, wchar_t *, ++ (wchar_t *dest, const wchar_t *src, size_t n)); ++_GL_CXXALIASWARN (wcsncat); ++#elif defined GNULIB_POSIXCHECK ++# undef wcsncat ++# if HAVE_RAW_DECL_WCSNCAT ++_GL_WARN_ON_USE (wcsncat, "wcsncat is unportable - " ++ "use gnulib module wcsncat for portability"); ++# endif ++#endif ++ ++ ++/* Compare S1 and S2. */ ++#if @GNULIB_WCSCMP@ ++# if !@HAVE_WCSCMP@ ++_GL_FUNCDECL_SYS (wcscmp, int, (const wchar_t *s1, const wchar_t *s2) ++ _GL_ATTRIBUTE_PURE); ++# endif ++_GL_CXXALIAS_SYS (wcscmp, int, (const wchar_t *s1, const wchar_t *s2)); ++_GL_CXXALIASWARN (wcscmp); ++#elif defined GNULIB_POSIXCHECK ++# undef wcscmp ++# if HAVE_RAW_DECL_WCSCMP ++_GL_WARN_ON_USE (wcscmp, "wcscmp is unportable - " ++ "use gnulib module wcscmp for portability"); ++# endif ++#endif ++ ++ ++/* Compare no more than N wide characters of S1 and S2. */ ++#if @GNULIB_WCSNCMP@ ++# if !@HAVE_WCSNCMP@ ++_GL_FUNCDECL_SYS (wcsncmp, int, ++ (const wchar_t *s1, const wchar_t *s2, size_t n) ++ _GL_ATTRIBUTE_PURE); ++# endif ++_GL_CXXALIAS_SYS (wcsncmp, int, ++ (const wchar_t *s1, const wchar_t *s2, size_t n)); ++_GL_CXXALIASWARN (wcsncmp); ++#elif defined GNULIB_POSIXCHECK ++# undef wcsncmp ++# if HAVE_RAW_DECL_WCSNCMP ++_GL_WARN_ON_USE (wcsncmp, "wcsncmp is unportable - " ++ "use gnulib module wcsncmp for portability"); ++# endif ++#endif ++ ++ ++/* Compare S1 and S2, ignoring case. */ ++#if @GNULIB_WCSCASECMP@ ++# if !@HAVE_WCSCASECMP@ ++_GL_FUNCDECL_SYS (wcscasecmp, int, (const wchar_t *s1, const wchar_t *s2) ++ _GL_ATTRIBUTE_PURE); ++# endif ++_GL_CXXALIAS_SYS (wcscasecmp, int, (const wchar_t *s1, const wchar_t *s2)); ++_GL_CXXALIASWARN (wcscasecmp); ++#elif defined GNULIB_POSIXCHECK ++# undef wcscasecmp ++# if HAVE_RAW_DECL_WCSCASECMP ++_GL_WARN_ON_USE (wcscasecmp, "wcscasecmp is unportable - " ++ "use gnulib module wcscasecmp for portability"); ++# endif ++#endif ++ ++ ++/* Compare no more than N chars of S1 and S2, ignoring case. */ ++#if @GNULIB_WCSNCASECMP@ ++# if !@HAVE_WCSNCASECMP@ ++_GL_FUNCDECL_SYS (wcsncasecmp, int, ++ (const wchar_t *s1, const wchar_t *s2, size_t n) ++ _GL_ATTRIBUTE_PURE); ++# endif ++_GL_CXXALIAS_SYS (wcsncasecmp, int, ++ (const wchar_t *s1, const wchar_t *s2, size_t n)); ++_GL_CXXALIASWARN (wcsncasecmp); ++#elif defined GNULIB_POSIXCHECK ++# undef wcsncasecmp ++# if HAVE_RAW_DECL_WCSNCASECMP ++_GL_WARN_ON_USE (wcsncasecmp, "wcsncasecmp is unportable - " ++ "use gnulib module wcsncasecmp for portability"); ++# endif ++#endif ++ ++ ++/* Compare S1 and S2, both interpreted as appropriate to the LC_COLLATE ++ category of the current locale. */ ++#if @GNULIB_WCSCOLL@ ++# if !@HAVE_WCSCOLL@ ++_GL_FUNCDECL_SYS (wcscoll, int, (const wchar_t *s1, const wchar_t *s2)); ++# endif ++_GL_CXXALIAS_SYS (wcscoll, int, (const wchar_t *s1, const wchar_t *s2)); ++_GL_CXXALIASWARN (wcscoll); ++#elif defined GNULIB_POSIXCHECK ++# undef wcscoll ++# if HAVE_RAW_DECL_WCSCOLL ++_GL_WARN_ON_USE (wcscoll, "wcscoll is unportable - " ++ "use gnulib module wcscoll for portability"); ++# endif ++#endif ++ ++ ++/* Transform S2 into array pointed to by S1 such that if wcscmp is applied ++ to two transformed strings the result is the as applying 'wcscoll' to the ++ original strings. */ ++#if @GNULIB_WCSXFRM@ ++# if !@HAVE_WCSXFRM@ ++_GL_FUNCDECL_SYS (wcsxfrm, size_t, (wchar_t *s1, const wchar_t *s2, size_t n)); ++# endif ++_GL_CXXALIAS_SYS (wcsxfrm, size_t, (wchar_t *s1, const wchar_t *s2, size_t n)); ++_GL_CXXALIASWARN (wcsxfrm); ++#elif defined GNULIB_POSIXCHECK ++# undef wcsxfrm ++# if HAVE_RAW_DECL_WCSXFRM ++_GL_WARN_ON_USE (wcsxfrm, "wcsxfrm is unportable - " ++ "use gnulib module wcsxfrm for portability"); ++# endif ++#endif ++ ++ ++/* Duplicate S, returning an identical malloc'd string. */ ++#if @GNULIB_WCSDUP@ ++# if !@HAVE_WCSDUP@ ++_GL_FUNCDECL_SYS (wcsdup, wchar_t *, (const wchar_t *s)); ++# endif ++_GL_CXXALIAS_SYS (wcsdup, wchar_t *, (const wchar_t *s)); ++_GL_CXXALIASWARN (wcsdup); ++#elif defined GNULIB_POSIXCHECK ++# undef wcsdup ++# if HAVE_RAW_DECL_WCSDUP ++_GL_WARN_ON_USE (wcsdup, "wcsdup is unportable - " ++ "use gnulib module wcsdup for portability"); ++# endif ++#endif ++ ++ ++/* Find the first occurrence of WC in WCS. */ ++#if @GNULIB_WCSCHR@ ++# if !@HAVE_WCSCHR@ ++_GL_FUNCDECL_SYS (wcschr, wchar_t *, (const wchar_t *wcs, wchar_t wc) ++ _GL_ATTRIBUTE_PURE); ++# endif ++ /* On some systems, this function is defined as an overloaded function: ++ extern "C++" { ++ const wchar_t * std::wcschr (const wchar_t *, wchar_t); ++ wchar_t * std::wcschr (wchar_t *, wchar_t); ++ } */ ++_GL_CXXALIAS_SYS_CAST2 (wcschr, ++ wchar_t *, (const wchar_t *, wchar_t), ++ const wchar_t *, (const wchar_t *, wchar_t)); ++# if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \ ++ && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) ++_GL_CXXALIASWARN1 (wcschr, wchar_t *, (wchar_t *wcs, wchar_t wc)); ++_GL_CXXALIASWARN1 (wcschr, const wchar_t *, (const wchar_t *wcs, wchar_t wc)); ++# else ++_GL_CXXALIASWARN (wcschr); ++# endif ++#elif defined GNULIB_POSIXCHECK ++# undef wcschr ++# if HAVE_RAW_DECL_WCSCHR ++_GL_WARN_ON_USE (wcschr, "wcschr is unportable - " ++ "use gnulib module wcschr for portability"); ++# endif ++#endif ++ ++ ++/* Find the last occurrence of WC in WCS. */ ++#if @GNULIB_WCSRCHR@ ++# if !@HAVE_WCSRCHR@ ++_GL_FUNCDECL_SYS (wcsrchr, wchar_t *, (const wchar_t *wcs, wchar_t wc) ++ _GL_ATTRIBUTE_PURE); ++# endif ++ /* On some systems, this function is defined as an overloaded function: ++ extern "C++" { ++ const wchar_t * std::wcsrchr (const wchar_t *, wchar_t); ++ wchar_t * std::wcsrchr (wchar_t *, wchar_t); ++ } */ ++_GL_CXXALIAS_SYS_CAST2 (wcsrchr, ++ wchar_t *, (const wchar_t *, wchar_t), ++ const wchar_t *, (const wchar_t *, wchar_t)); ++# if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \ ++ && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) ++_GL_CXXALIASWARN1 (wcsrchr, wchar_t *, (wchar_t *wcs, wchar_t wc)); ++_GL_CXXALIASWARN1 (wcsrchr, const wchar_t *, (const wchar_t *wcs, wchar_t wc)); ++# else ++_GL_CXXALIASWARN (wcsrchr); ++# endif ++#elif defined GNULIB_POSIXCHECK ++# undef wcsrchr ++# if HAVE_RAW_DECL_WCSRCHR ++_GL_WARN_ON_USE (wcsrchr, "wcsrchr is unportable - " ++ "use gnulib module wcsrchr for portability"); ++# endif ++#endif ++ ++ ++/* Return the length of the initial segmet of WCS which consists entirely ++ of wide characters not in REJECT. */ ++#if @GNULIB_WCSCSPN@ ++# if !@HAVE_WCSCSPN@ ++_GL_FUNCDECL_SYS (wcscspn, size_t, (const wchar_t *wcs, const wchar_t *reject) ++ _GL_ATTRIBUTE_PURE); ++# endif ++_GL_CXXALIAS_SYS (wcscspn, size_t, (const wchar_t *wcs, const wchar_t *reject)); ++_GL_CXXALIASWARN (wcscspn); ++#elif defined GNULIB_POSIXCHECK ++# undef wcscspn ++# if HAVE_RAW_DECL_WCSCSPN ++_GL_WARN_ON_USE (wcscspn, "wcscspn is unportable - " ++ "use gnulib module wcscspn for portability"); ++# endif ++#endif ++ ++ ++/* Return the length of the initial segmet of WCS which consists entirely ++ of wide characters in ACCEPT. */ ++#if @GNULIB_WCSSPN@ ++# if !@HAVE_WCSSPN@ ++_GL_FUNCDECL_SYS (wcsspn, size_t, (const wchar_t *wcs, const wchar_t *accept) ++ _GL_ATTRIBUTE_PURE); ++# endif ++_GL_CXXALIAS_SYS (wcsspn, size_t, (const wchar_t *wcs, const wchar_t *accept)); ++_GL_CXXALIASWARN (wcsspn); ++#elif defined GNULIB_POSIXCHECK ++# undef wcsspn ++# if HAVE_RAW_DECL_WCSSPN ++_GL_WARN_ON_USE (wcsspn, "wcsspn is unportable - " ++ "use gnulib module wcsspn for portability"); ++# endif ++#endif ++ ++ ++/* Find the first occurrence in WCS of any character in ACCEPT. */ ++#if @GNULIB_WCSPBRK@ ++# if !@HAVE_WCSPBRK@ ++_GL_FUNCDECL_SYS (wcspbrk, wchar_t *, ++ (const wchar_t *wcs, const wchar_t *accept) ++ _GL_ATTRIBUTE_PURE); ++# endif ++ /* On some systems, this function is defined as an overloaded function: ++ extern "C++" { ++ const wchar_t * std::wcspbrk (const wchar_t *, const wchar_t *); ++ wchar_t * std::wcspbrk (wchar_t *, const wchar_t *); ++ } */ ++_GL_CXXALIAS_SYS_CAST2 (wcspbrk, ++ wchar_t *, (const wchar_t *, const wchar_t *), ++ const wchar_t *, (const wchar_t *, const wchar_t *)); ++# if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \ ++ && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) ++_GL_CXXALIASWARN1 (wcspbrk, wchar_t *, ++ (wchar_t *wcs, const wchar_t *accept)); ++_GL_CXXALIASWARN1 (wcspbrk, const wchar_t *, ++ (const wchar_t *wcs, const wchar_t *accept)); ++# else ++_GL_CXXALIASWARN (wcspbrk); ++# endif ++#elif defined GNULIB_POSIXCHECK ++# undef wcspbrk ++# if HAVE_RAW_DECL_WCSPBRK ++_GL_WARN_ON_USE (wcspbrk, "wcspbrk is unportable - " ++ "use gnulib module wcspbrk for portability"); ++# endif ++#endif ++ ++ ++/* Find the first occurrence of NEEDLE in HAYSTACK. */ ++#if @GNULIB_WCSSTR@ ++# if !@HAVE_WCSSTR@ ++_GL_FUNCDECL_SYS (wcsstr, wchar_t *, ++ (const wchar_t *haystack, const wchar_t *needle) ++ _GL_ATTRIBUTE_PURE); ++# endif ++ /* On some systems, this function is defined as an overloaded function: ++ extern "C++" { ++ const wchar_t * std::wcsstr (const wchar_t *, const wchar_t *); ++ wchar_t * std::wcsstr (wchar_t *, const wchar_t *); ++ } */ ++_GL_CXXALIAS_SYS_CAST2 (wcsstr, ++ wchar_t *, (const wchar_t *, const wchar_t *), ++ const wchar_t *, (const wchar_t *, const wchar_t *)); ++# if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \ ++ && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) ++_GL_CXXALIASWARN1 (wcsstr, wchar_t *, ++ (wchar_t *haystack, const wchar_t *needle)); ++_GL_CXXALIASWARN1 (wcsstr, const wchar_t *, ++ (const wchar_t *haystack, const wchar_t *needle)); ++# else ++_GL_CXXALIASWARN (wcsstr); ++# endif ++#elif defined GNULIB_POSIXCHECK ++# undef wcsstr ++# if HAVE_RAW_DECL_WCSSTR ++_GL_WARN_ON_USE (wcsstr, "wcsstr is unportable - " ++ "use gnulib module wcsstr for portability"); ++# endif ++#endif ++ ++ ++/* Divide WCS into tokens separated by characters in DELIM. */ ++#if @GNULIB_WCSTOK@ ++# if !@HAVE_WCSTOK@ ++_GL_FUNCDECL_SYS (wcstok, wchar_t *, ++ (wchar_t *wcs, const wchar_t *delim, wchar_t **ptr)); ++# endif ++_GL_CXXALIAS_SYS (wcstok, wchar_t *, ++ (wchar_t *wcs, const wchar_t *delim, wchar_t **ptr)); ++_GL_CXXALIASWARN (wcstok); ++#elif defined GNULIB_POSIXCHECK ++# undef wcstok ++# if HAVE_RAW_DECL_WCSTOK ++_GL_WARN_ON_USE (wcstok, "wcstok is unportable - " ++ "use gnulib module wcstok for portability"); ++# endif ++#endif ++ ++ ++/* Determine number of column positions required for first N wide ++ characters (or fewer if S ends before this) in S. */ ++#if @GNULIB_WCSWIDTH@ ++# if @REPLACE_WCSWIDTH@ ++# if !(defined __cplusplus && defined GNULIB_NAMESPACE) ++# undef wcswidth ++# define wcswidth rpl_wcswidth ++# endif ++_GL_FUNCDECL_RPL (wcswidth, int, (const wchar_t *s, size_t n) ++ _GL_ATTRIBUTE_PURE); ++_GL_CXXALIAS_RPL (wcswidth, int, (const wchar_t *s, size_t n)); ++# else ++# if !@HAVE_WCSWIDTH@ ++_GL_FUNCDECL_SYS (wcswidth, int, (const wchar_t *s, size_t n) ++ _GL_ATTRIBUTE_PURE); ++# endif ++_GL_CXXALIAS_SYS (wcswidth, int, (const wchar_t *s, size_t n)); ++# endif ++_GL_CXXALIASWARN (wcswidth); ++#elif defined GNULIB_POSIXCHECK ++# undef wcswidth ++# if HAVE_RAW_DECL_WCSWIDTH ++_GL_WARN_ON_USE (wcswidth, "wcswidth is unportable - " ++ "use gnulib module wcswidth for portability"); ++# endif ++#endif ++ ++ ++#endif /* _@GUARD_PREFIX@_WCHAR_H */ ++#endif /* _@GUARD_PREFIX@_WCHAR_H */ + #endif +diff --git a/grub-core/gnulib/wcrtomb.c b/grub-core/gnulib/wcrtomb.c +index e7345f6..da42809 100644 +--- a/grub-core/gnulib/wcrtomb.c ++++ b/grub-core/gnulib/wcrtomb.c +@@ -1,5 +1,5 @@ + /* Convert wide character to multibyte character. +- Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc. ++ Copyright (C) 2008-2013 Free Software Foundation, Inc. + Written by Bruno Haible , 2008. + + This program is free software: you can redistribute it and/or modify +diff --git a/grub-core/gnulib/wctype-h.c b/grub-core/gnulib/wctype-h.c +new file mode 100644 +index 0000000..bb5f847 +--- /dev/null ++++ b/grub-core/gnulib/wctype-h.c +@@ -0,0 +1,4 @@ ++/* Normally this would be wctype.c, but that name's already taken. */ ++#include ++#define _GL_WCTYPE_INLINE _GL_EXTERN_INLINE ++#include "wctype.h" +diff --git a/grub-core/gnulib/wctype.in.h b/grub-core/gnulib/wctype.in.h +index 12c8975..0cd02d5 100644 +--- a/grub-core/gnulib/wctype.in.h ++++ b/grub-core/gnulib/wctype.in.h +@@ -1,6 +1,6 @@ + /* A substitute for ISO C99 , for platforms that lack it. + +- Copyright (C) 2006-2010 Free Software Foundation, Inc. ++ Copyright (C) 2006-2013 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 +@@ -13,8 +13,7 @@ + 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. */ ++ along with this program; if not, see . */ + + /* Written by Bruno Haible and Paul Eggert. */ + +@@ -26,11 +25,12 @@ + * wctrans_t, and wctype_t are not yet implemented. + */ + +-#ifndef _GL_WCTYPE_H ++#ifndef _@GUARD_PREFIX@_WCTYPE_H + + #if __GNUC__ >= 3 + @PRAGMA_SYSTEM_HEADER@ + #endif ++@PRAGMA_COLUMNS@ + + #if @HAVE_WINT_T@ + /* Solaris 2.5 has a bug: must be included before . +@@ -51,13 +51,31 @@ + # @INCLUDE_NEXT@ @NEXT_WCTYPE_H@ + #endif + +-#ifndef _GL_WCTYPE_H +-#define _GL_WCTYPE_H ++#ifndef _@GUARD_PREFIX@_WCTYPE_H ++#define _@GUARD_PREFIX@_WCTYPE_H ++ ++_GL_INLINE_HEADER_BEGIN ++#ifndef _GL_WCTYPE_INLINE ++# define _GL_WCTYPE_INLINE _GL_INLINE ++#endif + + /* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ + + /* The definition of _GL_WARN_ON_USE is copied here. */ + ++/* Solaris 2.6 includes which includes which ++ #defines a number of identifiers in the application namespace. Revert ++ these #defines. */ ++#ifdef __sun ++# undef multibyte ++# undef eucw1 ++# undef eucw2 ++# undef eucw3 ++# undef scrw1 ++# undef scrw2 ++# undef scrw3 ++#endif ++ + /* Define wint_t and WEOF. (Also done in wchar.in.h.) */ + #if !@HAVE_WINT_T@ && !defined wint_t + # define wint_t int +@@ -65,153 +83,171 @@ + # define WEOF -1 + # endif + #else ++/* MSVC defines wint_t as 'unsigned short' in . ++ This is too small: ISO C 99 section 7.24.1.(2) says that wint_t must be ++ "unchanged by default argument promotions". Override it. */ ++# if defined _MSC_VER ++# if !GNULIB_defined_wint_t ++# include ++typedef unsigned int rpl_wint_t; ++# undef wint_t ++# define wint_t rpl_wint_t ++# define GNULIB_defined_wint_t 1 ++# endif ++# endif + # ifndef WEOF + # define WEOF ((wint_t) -1) + # endif + #endif + + ++#if !GNULIB_defined_wctype_functions ++ + /* FreeBSD 4.4 to 4.11 has but lacks the functions. + Linux libc5 has and the functions but they are broken. + Assume all 11 functions (all isw* except iswblank) are implemented the + same way, or not at all. */ +-#if ! @HAVE_ISWCNTRL@ || @REPLACE_ISWCNTRL@ ++# if ! @HAVE_ISWCNTRL@ || @REPLACE_ISWCNTRL@ + + /* IRIX 5.3 has macros but no functions, its isw* macros refer to an + undefined variable _ctmp_ and to macros like _P, and they + refer to system functions like _iswctype that are not in the + standard C library. Rather than try to get ancient buggy + implementations like this to work, just disable them. */ +-# undef iswalnum +-# undef iswalpha +-# undef iswblank +-# undef iswcntrl +-# undef iswdigit +-# undef iswgraph +-# undef iswlower +-# undef iswprint +-# undef iswpunct +-# undef iswspace +-# undef iswupper +-# undef iswxdigit +-# undef towlower +-# undef towupper ++# undef iswalnum ++# undef iswalpha ++# undef iswblank ++# undef iswcntrl ++# undef iswdigit ++# undef iswgraph ++# undef iswlower ++# undef iswprint ++# undef iswpunct ++# undef iswspace ++# undef iswupper ++# undef iswxdigit ++# undef towlower ++# undef towupper + + /* Linux libc5 has and the functions but they are broken. */ +-# if @REPLACE_ISWCNTRL@ +-# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +-# define iswalnum rpl_iswalnum +-# define iswalpha rpl_iswalpha +-# define iswblank rpl_iswblank +-# define iswcntrl rpl_iswcntrl +-# define iswdigit rpl_iswdigit +-# define iswgraph rpl_iswgraph +-# define iswlower rpl_iswlower +-# define iswprint rpl_iswprint +-# define iswpunct rpl_iswpunct +-# define iswspace rpl_iswspace +-# define iswupper rpl_iswupper +-# define iswxdigit rpl_iswxdigit +-# define towlower rpl_towlower +-# define towupper rpl_towupper ++# if @REPLACE_ISWCNTRL@ ++# if !(defined __cplusplus && defined GNULIB_NAMESPACE) ++# define iswalnum rpl_iswalnum ++# define iswalpha rpl_iswalpha ++# define iswblank rpl_iswblank ++# define iswcntrl rpl_iswcntrl ++# define iswdigit rpl_iswdigit ++# define iswgraph rpl_iswgraph ++# define iswlower rpl_iswlower ++# define iswprint rpl_iswprint ++# define iswpunct rpl_iswpunct ++# define iswspace rpl_iswspace ++# define iswupper rpl_iswupper ++# define iswxdigit rpl_iswxdigit ++# endif ++# endif ++# if @REPLACE_TOWLOWER@ ++# if !(defined __cplusplus && defined GNULIB_NAMESPACE) ++# define towlower rpl_towlower ++# define towupper rpl_towupper ++# endif + # endif +-# endif + +-static inline int +-# if @REPLACE_ISWCNTRL@ ++_GL_WCTYPE_INLINE int ++# if @REPLACE_ISWCNTRL@ + rpl_iswalnum +-# else ++# else + iswalnum +-# endif ++# endif + (wint_t wc) + { + return ((wc >= '0' && wc <= '9') + || ((wc & ~0x20) >= 'A' && (wc & ~0x20) <= 'Z')); + } + +-static inline int +-# if @REPLACE_ISWCNTRL@ ++_GL_WCTYPE_INLINE int ++# if @REPLACE_ISWCNTRL@ + rpl_iswalpha +-# else ++# else + iswalpha +-# endif ++# endif + (wint_t wc) + { + return (wc & ~0x20) >= 'A' && (wc & ~0x20) <= 'Z'; + } + +-static inline int +-# if @REPLACE_ISWCNTRL@ ++_GL_WCTYPE_INLINE int ++# if @REPLACE_ISWCNTRL@ + rpl_iswblank +-# else ++# else + iswblank +-# endif ++# endif + (wint_t wc) + { + return wc == ' ' || wc == '\t'; + } + +-static inline int +-# if @REPLACE_ISWCNTRL@ ++_GL_WCTYPE_INLINE int ++# if @REPLACE_ISWCNTRL@ + rpl_iswcntrl +-# else ++# else + iswcntrl +-# endif ++# endif + (wint_t wc) + { + return (wc & ~0x1f) == 0 || wc == 0x7f; + } + +-static inline int +-# if @REPLACE_ISWCNTRL@ ++_GL_WCTYPE_INLINE int ++# if @REPLACE_ISWCNTRL@ + rpl_iswdigit +-# else ++# else + iswdigit +-# endif ++# endif + (wint_t wc) + { + return wc >= '0' && wc <= '9'; + } + +-static inline int +-# if @REPLACE_ISWCNTRL@ ++_GL_WCTYPE_INLINE int ++# if @REPLACE_ISWCNTRL@ + rpl_iswgraph +-# else ++# else + iswgraph +-# endif ++# endif + (wint_t wc) + { + return wc >= '!' && wc <= '~'; + } + +-static inline int +-# if @REPLACE_ISWCNTRL@ ++_GL_WCTYPE_INLINE int ++# if @REPLACE_ISWCNTRL@ + rpl_iswlower +-# else ++# else + iswlower +-# endif ++# endif + (wint_t wc) + { + return wc >= 'a' && wc <= 'z'; + } + +-static inline int +-# if @REPLACE_ISWCNTRL@ ++_GL_WCTYPE_INLINE int ++# if @REPLACE_ISWCNTRL@ + rpl_iswprint +-# else ++# else + iswprint +-# endif ++# endif + (wint_t wc) + { + return wc >= ' ' && wc <= '~'; + } + +-static inline int +-# if @REPLACE_ISWCNTRL@ ++_GL_WCTYPE_INLINE int ++# if @REPLACE_ISWCNTRL@ + rpl_iswpunct +-# else ++# else + iswpunct +-# endif ++# endif + (wint_t wc) + { + return (wc >= '!' && wc <= '~' +@@ -219,86 +255,78 @@ iswpunct + || ((wc & ~0x20) >= 'A' && (wc & ~0x20) <= 'Z'))); + } + +-static inline int +-# if @REPLACE_ISWCNTRL@ ++_GL_WCTYPE_INLINE int ++# if @REPLACE_ISWCNTRL@ + rpl_iswspace +-# else ++# else + iswspace +-# endif ++# endif + (wint_t wc) + { + return (wc == ' ' || wc == '\t' + || wc == '\n' || wc == '\v' || wc == '\f' || wc == '\r'); + } + +-static inline int +-# if @REPLACE_ISWCNTRL@ ++_GL_WCTYPE_INLINE int ++# if @REPLACE_ISWCNTRL@ + rpl_iswupper +-# else ++# else + iswupper +-# endif ++# endif + (wint_t wc) + { + return wc >= 'A' && wc <= 'Z'; + } + +-static inline int +-# if @REPLACE_ISWCNTRL@ ++_GL_WCTYPE_INLINE int ++# if @REPLACE_ISWCNTRL@ + rpl_iswxdigit +-# else ++# else + iswxdigit +-# endif ++# endif + (wint_t wc) + { + return ((wc >= '0' && wc <= '9') + || ((wc & ~0x20) >= 'A' && (wc & ~0x20) <= 'F')); + } + +-static inline wint_t +-# if @REPLACE_ISWCNTRL@ ++_GL_WCTYPE_INLINE wint_t ++# if @REPLACE_TOWLOWER@ + rpl_towlower +-# else ++# else + towlower +-# endif ++# endif + (wint_t wc) + { + return (wc >= 'A' && wc <= 'Z' ? wc - 'A' + 'a' : wc); + } + +-static inline wint_t +-# if @REPLACE_ISWCNTRL@ ++_GL_WCTYPE_INLINE wint_t ++# if @REPLACE_TOWLOWER@ + rpl_towupper +-# else ++# else + towupper +-# endif ++# endif + (wint_t wc) + { + return (wc >= 'a' && wc <= 'z' ? wc - 'a' + 'A' : wc); + } + +-#elif ! @HAVE_ISWBLANK@ || @REPLACE_ISWBLANK@ ++# elif @GNULIB_ISWBLANK@ && (! @HAVE_ISWBLANK@ || @REPLACE_ISWBLANK@) + /* Only the iswblank function is missing. */ + +-# if @REPLACE_ISWBLANK@ +-# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +-# define iswblank rpl_iswblank ++# if @REPLACE_ISWBLANK@ ++# if !(defined __cplusplus && defined GNULIB_NAMESPACE) ++# define iswblank rpl_iswblank ++# endif ++_GL_FUNCDECL_RPL (iswblank, int, (wint_t wc)); ++# else ++_GL_FUNCDECL_SYS (iswblank, int, (wint_t wc)); + # endif +-# endif + +-static inline int +-# if @REPLACE_ISWBLANK@ +-rpl_iswblank +-# else +-iswblank + # endif +- (wint_t wc) +-{ +- return wc == ' ' || wc == '\t'; +-} +- +-#endif + +-#if defined __MINGW32__ ++# if defined __MINGW32__ + + /* On native Windows, wchar_t is uint16_t, and wint_t is uint32_t. + The functions towlower and towupper are implemented in the MSVCRT library +@@ -313,30 +341,32 @@ iswblank + result register. We need to fix this by adding a zero-extend from + wchar_t to wint_t after the call. */ + +-static inline wint_t ++_GL_WCTYPE_INLINE wint_t + rpl_towlower (wint_t wc) + { + return (wint_t) (wchar_t) towlower (wc); + } +-# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +-# define towlower rpl_towlower +-# endif ++# if !(defined __cplusplus && defined GNULIB_NAMESPACE) ++# define towlower rpl_towlower ++# endif + +-static inline wint_t ++_GL_WCTYPE_INLINE wint_t + rpl_towupper (wint_t wc) + { + return (wint_t) (wchar_t) towupper (wc); + } +-# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +-# define towupper rpl_towupper +-# endif ++# if !(defined __cplusplus && defined GNULIB_NAMESPACE) ++# define towupper rpl_towupper ++# endif + +-#endif /* __MINGW32__ */ ++# endif /* __MINGW32__ */ ++ ++# define GNULIB_defined_wctype_functions 1 ++#endif + + #if @REPLACE_ISWCNTRL@ + _GL_CXXALIAS_RPL (iswalnum, int, (wint_t wc)); + _GL_CXXALIAS_RPL (iswalpha, int, (wint_t wc)); +-_GL_CXXALIAS_RPL (iswblank, int, (wint_t wc)); + _GL_CXXALIAS_RPL (iswcntrl, int, (wint_t wc)); + _GL_CXXALIAS_RPL (iswdigit, int, (wint_t wc)); + _GL_CXXALIAS_RPL (iswgraph, int, (wint_t wc)); +@@ -349,11 +379,6 @@ _GL_CXXALIAS_RPL (iswxdigit, int, (wint_t wc)); + #else + _GL_CXXALIAS_SYS (iswalnum, int, (wint_t wc)); + _GL_CXXALIAS_SYS (iswalpha, int, (wint_t wc)); +-# if @REPLACE_ISWBLANK@ +-_GL_CXXALIAS_RPL (iswblank, int, (wint_t wc)); +-# else +-_GL_CXXALIAS_SYS (iswblank, int, (wint_t wc)); +-# endif + _GL_CXXALIAS_SYS (iswcntrl, int, (wint_t wc)); + _GL_CXXALIAS_SYS (iswdigit, int, (wint_t wc)); + _GL_CXXALIAS_SYS (iswgraph, int, (wint_t wc)); +@@ -366,7 +391,6 @@ _GL_CXXALIAS_SYS (iswxdigit, int, (wint_t wc)); + #endif + _GL_CXXALIASWARN (iswalnum); + _GL_CXXALIASWARN (iswalpha); +-_GL_CXXALIASWARN (iswblank); + _GL_CXXALIASWARN (iswcntrl); + _GL_CXXALIASWARN (iswdigit); + _GL_CXXALIASWARN (iswgraph); +@@ -377,7 +401,55 @@ _GL_CXXALIASWARN (iswspace); + _GL_CXXALIASWARN (iswupper); + _GL_CXXALIASWARN (iswxdigit); + +-#if @REPLACE_ISWCNTRL@ || defined __MINGW32__ ++#if @GNULIB_ISWBLANK@ ++# if @REPLACE_ISWCNTRL@ || @REPLACE_ISWBLANK@ ++_GL_CXXALIAS_RPL (iswblank, int, (wint_t wc)); ++# else ++_GL_CXXALIAS_SYS (iswblank, int, (wint_t wc)); ++# endif ++_GL_CXXALIASWARN (iswblank); ++#endif ++ ++#if !@HAVE_WCTYPE_T@ ++# if !GNULIB_defined_wctype_t ++typedef void * wctype_t; ++# define GNULIB_defined_wctype_t 1 ++# endif ++#endif ++ ++/* Get a descriptor for a wide character property. */ ++#if @GNULIB_WCTYPE@ ++# if !@HAVE_WCTYPE_T@ ++_GL_FUNCDECL_SYS (wctype, wctype_t, (const char *name)); ++# endif ++_GL_CXXALIAS_SYS (wctype, wctype_t, (const char *name)); ++_GL_CXXALIASWARN (wctype); ++#elif defined GNULIB_POSIXCHECK ++# undef wctype ++# if HAVE_RAW_DECL_WCTYPE ++_GL_WARN_ON_USE (wctype, "wctype is unportable - " ++ "use gnulib module wctype for portability"); ++# endif ++#endif ++ ++/* Test whether a wide character has a given property. ++ The argument WC must be either a wchar_t value or WEOF. ++ The argument DESC must have been returned by the wctype() function. */ ++#if @GNULIB_ISWCTYPE@ ++# if !@HAVE_WCTYPE_T@ ++_GL_FUNCDECL_SYS (iswctype, int, (wint_t wc, wctype_t desc)); ++# endif ++_GL_CXXALIAS_SYS (iswctype, int, (wint_t wc, wctype_t desc)); ++_GL_CXXALIASWARN (iswctype); ++#elif defined GNULIB_POSIXCHECK ++# undef iswctype ++# if HAVE_RAW_DECL_ISWCTYPE ++_GL_WARN_ON_USE (iswctype, "iswctype is unportable - " ++ "use gnulib module iswctype for portability"); ++# endif ++#endif ++ ++#if @REPLACE_TOWLOWER@ || defined __MINGW32__ + _GL_CXXALIAS_RPL (towlower, wint_t, (wint_t wc)); + _GL_CXXALIAS_RPL (towupper, wint_t, (wint_t wc)); + #else +@@ -387,6 +459,46 @@ _GL_CXXALIAS_SYS (towupper, wint_t, (wint_t wc)); + _GL_CXXALIASWARN (towlower); + _GL_CXXALIASWARN (towupper); + ++#if !@HAVE_WCTRANS_T@ ++# if !GNULIB_defined_wctrans_t ++typedef void * wctrans_t; ++# define GNULIB_defined_wctrans_t 1 ++# endif ++#endif ++ ++/* Get a descriptor for a wide character case conversion. */ ++#if @GNULIB_WCTRANS@ ++# if !@HAVE_WCTRANS_T@ ++_GL_FUNCDECL_SYS (wctrans, wctrans_t, (const char *name)); ++# endif ++_GL_CXXALIAS_SYS (wctrans, wctrans_t, (const char *name)); ++_GL_CXXALIASWARN (wctrans); ++#elif defined GNULIB_POSIXCHECK ++# undef wctrans ++# if HAVE_RAW_DECL_WCTRANS ++_GL_WARN_ON_USE (wctrans, "wctrans is unportable - " ++ "use gnulib module wctrans for portability"); ++# endif ++#endif ++ ++/* Perform a given case conversion on a wide character. ++ The argument WC must be either a wchar_t value or WEOF. ++ The argument DESC must have been returned by the wctrans() function. */ ++#if @GNULIB_TOWCTRANS@ ++# if !@HAVE_WCTRANS_T@ ++_GL_FUNCDECL_SYS (towctrans, wint_t, (wint_t wc, wctrans_t desc)); ++# endif ++_GL_CXXALIAS_SYS (towctrans, wint_t, (wint_t wc, wctrans_t desc)); ++_GL_CXXALIASWARN (towctrans); ++#elif defined GNULIB_POSIXCHECK ++# undef towctrans ++# if HAVE_RAW_DECL_TOWCTRANS ++_GL_WARN_ON_USE (towctrans, "towctrans is unportable - " ++ "use gnulib module towctrans for portability"); ++# endif ++#endif ++ ++_GL_INLINE_HEADER_END + +-#endif /* _GL_WCTYPE_H */ +-#endif /* _GL_WCTYPE_H */ ++#endif /* _@GUARD_PREFIX@_WCTYPE_H */ ++#endif /* _@GUARD_PREFIX@_WCTYPE_H */ +diff --git a/grub-core/gnulib/wcwidth.c b/grub-core/gnulib/wcwidth.c +new file mode 100644 +index 0000000..253fcaa +--- /dev/null ++++ b/grub-core/gnulib/wcwidth.c +@@ -0,0 +1,50 @@ ++/* Determine the number of screen columns needed for a character. ++ Copyright (C) 2006-2007, 2010-2013 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 ++ ++/* Specification. */ ++#include ++ ++/* Get iswprint. */ ++#include ++ ++#include "localcharset.h" ++#include "streq.h" ++#include "uniwidth.h" ++ ++int ++wcwidth (wchar_t wc) ++#undef wcwidth ++{ ++ /* In UTF-8 locales, use a Unicode aware width function. */ ++ const char *encoding = locale_charset (); ++ if (STREQ_OPT (encoding, "UTF-8", 'U', 'T', 'F', '-', '8', 0, 0, 0 ,0)) ++ { ++ /* We assume that in a UTF-8 locale, a wide character is the same as a ++ Unicode character. */ ++ return uc_width (wc, encoding); ++ } ++ else ++ { ++ /* Otherwise, fall back to the system's wcwidth function. */ ++#if HAVE_WCWIDTH ++ return wcwidth (wc); ++#else ++ return wc == 0 ? 0 : iswprint (wc) ? 1 : -1; ++#endif ++ } ++} +diff --git a/grub-core/gnulib/xsize.c b/grub-core/gnulib/xsize.c +new file mode 100644 +index 0000000..4b4914c +--- /dev/null ++++ b/grub-core/gnulib/xsize.c +@@ -0,0 +1,3 @@ ++#include ++#define XSIZE_INLINE _GL_EXTERN_INLINE ++#include "xsize.h" +diff --git a/grub-core/gnulib/xsize.h b/grub-core/gnulib/xsize.h +index fbd6329..2922f35 100644 +--- a/grub-core/gnulib/xsize.h ++++ b/grub-core/gnulib/xsize.h +@@ -1,6 +1,6 @@ + /* xsize.h -- Checked size_t computations. + +- Copyright (C) 2003, 2008, 2009, 2010 Free Software Foundation, Inc. ++ Copyright (C) 2003, 2008-2013 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 +@@ -13,8 +13,7 @@ + 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. */ ++ along with this program; if not, see . */ + + #ifndef _XSIZE_H + #define _XSIZE_H +@@ -28,6 +27,11 @@ + # include + #endif + ++_GL_INLINE_HEADER_BEGIN ++#ifndef XSIZE_INLINE ++# define XSIZE_INLINE _GL_INLINE ++#endif ++ + /* The size of memory objects is often computed through expressions of + type size_t. Example: + void* p = malloc (header_size + n * element_size). +@@ -49,7 +53,7 @@ + ((N) <= SIZE_MAX ? (size_t) (N) : SIZE_MAX) + + /* Sum of two sizes, with overflow check. */ +-static inline size_t ++XSIZE_INLINE size_t + #if __GNUC__ >= 3 + __attribute__ ((__pure__)) + #endif +@@ -60,7 +64,7 @@ xsum (size_t size1, size_t size2) + } + + /* Sum of three sizes, with overflow check. */ +-static inline size_t ++XSIZE_INLINE size_t + #if __GNUC__ >= 3 + __attribute__ ((__pure__)) + #endif +@@ -70,7 +74,7 @@ xsum3 (size_t size1, size_t size2, size_t size3) + } + + /* Sum of four sizes, with overflow check. */ +-static inline size_t ++XSIZE_INLINE size_t + #if __GNUC__ >= 3 + __attribute__ ((__pure__)) + #endif +@@ -80,7 +84,7 @@ xsum4 (size_t size1, size_t size2, size_t size3, size_t size4) + } + + /* Maximum of two sizes, with overflow check. */ +-static inline size_t ++XSIZE_INLINE size_t + #if __GNUC__ >= 3 + __attribute__ ((__pure__)) + #endif +@@ -93,7 +97,7 @@ xmax (size_t size1, size_t size2) + + /* Multiplication of a count with an element size, with overflow check. + The count must be >= 0 and the element size must be > 0. +- This is a macro, not an inline function, so that it works correctly even ++ This is a macro, not a function, so that it works correctly even + when N is of a wider type and N > SIZE_MAX. */ + #define xtimes(N, ELSIZE) \ + ((N) <= SIZE_MAX / (ELSIZE) ? (size_t) (N) * (ELSIZE) : SIZE_MAX) +@@ -105,4 +109,6 @@ xmax (size_t size1, size_t size2) + #define size_in_bounds_p(SIZE) \ + ((SIZE) != SIZE_MAX) + ++_GL_INLINE_HEADER_END ++ + #endif /* _XSIZE_H */ +diff --git a/grub-core/kern/emu/argp_common.c b/grub-core/kern/emu/argp_common.c +index d6080ba..e519b52 100644 +--- a/grub-core/kern/emu/argp_common.c ++++ b/grub-core/kern/emu/argp_common.c +@@ -18,6 +18,7 @@ + */ + + #include ++#include + + #define _GNU_SOURCE 1 + #include +diff --git a/grub-core/kern/emu/error.c b/grub-core/kern/emu/error.c +new file mode 100644 +index 0000000..559412a +--- /dev/null ++++ b/grub-core/kern/emu/error.c +@@ -0,0 +1,2 @@ ++#include ++#include "../../gnulib/error.c" +diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c +index 4a5eee0..3142332 100644 +--- a/grub-core/kern/emu/hostdisk.c ++++ b/grub-core/kern/emu/hostdisk.c +@@ -17,6 +17,8 @@ + * along with GRUB. If not, see . + */ + ++#include ++ + #include + #include + #include +diff --git a/grub-core/kern/emu/hostfs.c b/grub-core/kern/emu/hostfs.c +index 46bf5e8..0bb3232 100644 +--- a/grub-core/kern/emu/hostfs.c ++++ b/grub-core/kern/emu/hostfs.c +@@ -16,6 +16,9 @@ + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ ++ ++#include ++ + #define _BSD_SOURCE + #include + #include +diff --git a/grub-core/kern/emu/main.c b/grub-core/kern/emu/main.c +index 0418aae..4a88905 100644 +--- a/grub-core/kern/emu/main.c ++++ b/grub-core/kern/emu/main.c +@@ -16,6 +16,9 @@ + * along with GRUB. If not, see . + */ + ++#include ++#include ++ + #include + #include + #include +diff --git a/grub-core/lib/posix_wrap/limits.h b/grub-core/lib/posix_wrap/limits.h +index 588e589..9552954 100644 +--- a/grub-core/lib/posix_wrap/limits.h ++++ b/grub-core/lib/posix_wrap/limits.h +@@ -25,6 +25,7 @@ + #define USHRT_MAX GRUB_USHRT_MAX + #define UINT_MAX GRUB_UINT_MAX + #define ULONG_MAX GRUB_ULONG_MAX ++#define SIZE_MAX GRUB_SIZE_MAX + + #define SHRT_MAX GRUB_SHRT_MAX + #define INT_MAX GRUB_INT_MAX +diff --git a/grub-core/lib/posix_wrap/sys/types.h b/grub-core/lib/posix_wrap/sys/types.h +index 62a2672..c88a96e 100644 +--- a/grub-core/lib/posix_wrap/sys/types.h ++++ b/grub-core/lib/posix_wrap/sys/types.h +@@ -51,6 +51,8 @@ typedef grub_uint16_t u16; + #define HAVE_BYTE_TYPEDEF 1 + typedef grub_uint8_t byte; + ++typedef grub_addr_t uintptr_t; ++ + #define SIZEOF_UNSIGNED_LONG GRUB_CPU_SIZEOF_LONG + #define SIZEOF_UNSIGNED_INT 4 + #define SIZEOF_UNSIGNED_LONG_LONG 8 +diff --git a/include/grub/types.h b/include/grub/types.h +index 7c56f40..775e03a 100644 +--- a/include/grub/types.h ++++ b/include/grub/types.h +@@ -90,6 +90,8 @@ typedef grub_uint64_t grub_addr_t; + typedef grub_uint64_t grub_size_t; + typedef grub_int64_t grub_ssize_t; + ++# define GRUB_SIZE_MAX 18446744073709551615UL ++ + # if GRUB_CPU_SIZEOF_LONG == 8 + # define PRIxGRUB_SIZE "lx" + # define PRIxGRUB_ADDR "lx" +@@ -106,6 +108,8 @@ typedef grub_uint32_t grub_addr_t; + typedef grub_uint32_t grub_size_t; + typedef grub_int32_t grub_ssize_t; + ++# define GRUB_SIZE_MAX 4294967295UL ++ + # define PRIxGRUB_SIZE "x" + # define PRIxGRUB_ADDR "x" + # define PRIuGRUB_SIZE "u" +diff --git a/m4/00gnulib.m4 b/m4/00gnulib.m4 +index 301469b..d4ad759 100644 +--- a/m4/00gnulib.m4 ++++ b/m4/00gnulib.m4 +@@ -1,5 +1,5 @@ + # 00gnulib.m4 serial 2 +-dnl Copyright (C) 2009-2010 Free Software Foundation, Inc. ++dnl Copyright (C) 2009-2013 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. +diff --git a/m4/alloca.m4 b/m4/alloca.m4 +index f3ee343..270abd0 100644 +--- a/m4/alloca.m4 ++++ b/m4/alloca.m4 +@@ -1,5 +1,5 @@ +-# alloca.m4 serial 9 +-dnl Copyright (C) 2002-2004, 2006-2007, 2009-2010 Free Software Foundation, ++# alloca.m4 serial 14 ++dnl Copyright (C) 2002-2004, 2006-2007, 2009-2013 Free Software Foundation, + dnl Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, +@@ -7,10 +7,6 @@ dnl with or without modifications, as long as this notice is preserved. + + AC_DEFUN([gl_FUNC_ALLOCA], + [ +- dnl Work around a bug of AC_EGREP_CPP in autoconf-2.57. +- AC_REQUIRE([AC_PROG_CPP]) +- AC_REQUIRE([AC_PROG_EGREP]) +- + AC_REQUIRE([AC_FUNC_ALLOCA]) + if test $ac_cv_func_alloca_works = no; then + gl_PREREQ_ALLOCA +@@ -40,8 +36,86 @@ AC_DEFUN([gl_FUNC_ALLOCA], + ALLOCA_H=alloca.h + fi + AC_SUBST([ALLOCA_H]) ++ AM_CONDITIONAL([GL_GENERATE_ALLOCA_H], [test -n "$ALLOCA_H"]) + ]) + + # Prerequisites of lib/alloca.c. + # STACK_DIRECTION is already handled by AC_FUNC_ALLOCA. + AC_DEFUN([gl_PREREQ_ALLOCA], [:]) ++ ++# This works around a bug in autoconf <= 2.68. ++# See . ++ ++m4_version_prereq([2.69], [] ,[ ++ ++# This is taken from the following Autoconf patch: ++# http://git.savannah.gnu.org/cgit/autoconf.git/commit/?id=6cd9f12520b0d6f76d3230d7565feba1ecf29497 ++ ++# _AC_LIBOBJ_ALLOCA ++# ----------------- ++# Set up the LIBOBJ replacement of 'alloca'. Well, not exactly ++# AC_LIBOBJ since we actually set the output variable 'ALLOCA'. ++# Nevertheless, for Automake, AC_LIBSOURCES it. ++m4_define([_AC_LIBOBJ_ALLOCA], ++[# The SVR3 libPW and SVR4 libucb both contain incompatible functions ++# that cause trouble. Some versions do not even contain alloca or ++# contain a buggy version. If you still want to use their alloca, ++# use ar to extract alloca.o from them instead of compiling alloca.c. ++AC_LIBSOURCES(alloca.c) ++AC_SUBST([ALLOCA], [\${LIBOBJDIR}alloca.$ac_objext])dnl ++AC_DEFINE(C_ALLOCA, 1, [Define to 1 if using 'alloca.c'.]) ++ ++AC_CACHE_CHECK(whether 'alloca.c' needs Cray hooks, ac_cv_os_cray, ++[AC_EGREP_CPP(webecray, ++[#if defined CRAY && ! defined CRAY2 ++webecray ++#else ++wenotbecray ++#endif ++], ac_cv_os_cray=yes, ac_cv_os_cray=no)]) ++if test $ac_cv_os_cray = yes; then ++ for ac_func in _getb67 GETB67 getb67; do ++ AC_CHECK_FUNC($ac_func, ++ [AC_DEFINE_UNQUOTED(CRAY_STACKSEG_END, $ac_func, ++ [Define to one of '_getb67', 'GETB67', ++ 'getb67' for Cray-2 and Cray-YMP ++ systems. This function is required for ++ 'alloca.c' support on those systems.]) ++ break]) ++ done ++fi ++ ++AC_CACHE_CHECK([stack direction for C alloca], ++ [ac_cv_c_stack_direction], ++[AC_RUN_IFELSE([AC_LANG_SOURCE( ++[AC_INCLUDES_DEFAULT ++int ++find_stack_direction (int *addr, int depth) ++{ ++ int dir, dummy = 0; ++ if (! addr) ++ addr = &dummy; ++ *addr = addr < &dummy ? 1 : addr == &dummy ? 0 : -1; ++ dir = depth ? find_stack_direction (addr, depth - 1) : 0; ++ return dir + dummy; ++} ++ ++int ++main (int argc, char **argv) ++{ ++ return find_stack_direction (0, argc + !argv + 20) < 0; ++}])], ++ [ac_cv_c_stack_direction=1], ++ [ac_cv_c_stack_direction=-1], ++ [ac_cv_c_stack_direction=0])]) ++AH_VERBATIM([STACK_DIRECTION], ++[/* If using the C implementation of alloca, define if you know the ++ direction of stack growth for your system; otherwise it will be ++ automatically deduced at runtime. ++ STACK_DIRECTION > 0 => grows toward higher addresses ++ STACK_DIRECTION < 0 => grows toward lower addresses ++ STACK_DIRECTION = 0 => direction of growth unknown */ ++@%:@undef STACK_DIRECTION])dnl ++AC_DEFINE_UNQUOTED(STACK_DIRECTION, $ac_cv_c_stack_direction) ++])# _AC_LIBOBJ_ALLOCA ++]) +diff --git a/m4/argp.m4 b/m4/argp.m4 +index d3ca5ba..4445d8e 100644 +--- a/m4/argp.m4 ++++ b/m4/argp.m4 +@@ -1,5 +1,5 @@ +-# argp.m4 serial 11 +-dnl Copyright (C) 2003-2010 Free Software Foundation, Inc. ++# argp.m4 serial 14 ++dnl Copyright (C) 2003-2013 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. +@@ -9,23 +9,15 @@ AC_DEFUN([gl_ARGP], + AC_REQUIRE([AC_C_INLINE]) + AC_REQUIRE([AC_C_RESTRICT]) + AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) +- dnl argp-parse.c depends on GNU getopt internals, therefore use GNU getopt +- dnl always. +- gl_REPLACE_GETOPT +- dnl Note: gl_REPLACE_GETOPT does AC_LIBOBJ([getopt]), AC_LIBOBJ([getopt1]). + +- AC_CHECK_DECL([program_invocation_name], +- [AC_DEFINE([HAVE_DECL_PROGRAM_INVOCATION_NAME], [1], +- [Define if program_invocation_name is declared])], +- [AC_DEFINE([GNULIB_PROGRAM_INVOCATION_NAME], [1], +- [Define to 1 to add extern declaration of program_invocation_name to argp.h])], +- [#include ]) +- AC_CHECK_DECL([program_invocation_short_name], +- [AC_DEFINE([HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME], [1], +- [Define if program_invocation_short_name is declared])], +- [AC_DEFINE([GNULIB_PROGRAM_INVOCATION_SHORT_NAME], [1], +- [Define to 1 to add extern declaration of program_invocation_short_name to argp.h])], +- [#include ]) ++ AC_CHECK_DECLS([program_invocation_name], [], ++ [AC_DEFINE([GNULIB_PROGRAM_INVOCATION_NAME], [1], ++ [Define to 1 to add extern declaration of program_invocation_name to argp.h])], ++ [[#include ]]) ++ AC_CHECK_DECLS([program_invocation_short_name], [], ++ [AC_DEFINE([GNULIB_PROGRAM_INVOCATION_SHORT_NAME], [1], ++ [Define to 1 to add extern declaration of program_invocation_short_name to argp.h])], ++ [[#include ]]) + + # Check if program_invocation_name and program_invocation_short_name + # are defined elsewhere. It is improbable that only one of them will +@@ -63,3 +55,7 @@ AC_DEFUN([gl_ARGP], + AC_CHECK_FUNCS_ONCE([flockfile funlockfile]) + AC_CHECK_HEADERS_ONCE([features.h linewrap.h]) + ]) ++ ++dnl argp-parse.c depends on GNU getopt internals, therefore use GNU getopt ++dnl always. ++AC_DEFUN([gl_REPLACE_GETOPT_ALWAYS], []) +diff --git a/m4/asm-underscore.m4 b/m4/asm-underscore.m4 +deleted file mode 100644 +index 1736cc4..0000000 +--- a/m4/asm-underscore.m4 ++++ /dev/null +@@ -1,48 +0,0 @@ +-# asm-underscore.m4 serial 1 +-dnl Copyright (C) 2010 Free Software Foundation, Inc. +-dnl This file is free software; the Free Software Foundation +-dnl gives unlimited permission to copy and/or distribute it, +-dnl with or without modifications, as long as this notice is preserved. +- +-dnl From Bruno Haible. Based on as-underscore.m4 in GNU clisp. +- +-# gl_ASM_SYMBOL_PREFIX +-# Tests for the prefix of C symbols at the assembly language level and the +-# linker level. This prefix is either an underscore or empty. Defines the +-# C macro USER_LABEL_PREFIX to this prefix, and sets ASM_SYMBOL_PREFIX to +-# a stringified variant of this prefix. +- +-AC_DEFUN([gl_ASM_SYMBOL_PREFIX], +-[ +- dnl We don't use GCC's __USER_LABEL_PREFIX__ here, because +- dnl 1. It works only for GCC. +- dnl 2. It is incorrectly defined on some platforms, in some GCC versions. +- AC_CACHE_CHECK( +- [whether C symbols are prefixed with underscore at the linker level], +- [gl_cv_prog_as_underscore], +- [cat > conftest.c </dev/null 2>&1 +- if grep _foo conftest.s >/dev/null ; then +- gl_cv_prog_as_underscore=yes +- else +- gl_cv_prog_as_underscore=no +- fi +- rm -f conftest* +- ]) +- if test $gl_cv_prog_as_underscore = yes; then +- USER_LABEL_PREFIX=_ +- else +- USER_LABEL_PREFIX= +- fi +- AC_DEFINE_UNQUOTED([USER_LABEL_PREFIX], [$USER_LABEL_PREFIX], +- [Define to the prefix of C symbols at the assembler and linker level, +- either an underscore or empty.]) +- ASM_SYMBOL_PREFIX='"'${USER_LABEL_PREFIX}'"' +- AC_SUBST([ASM_SYMBOL_PREFIX]) +-]) +diff --git a/m4/btowc.m4 b/m4/btowc.m4 +index b16b1f0..978a06e 100644 +--- a/m4/btowc.m4 ++++ b/m4/btowc.m4 +@@ -1,5 +1,5 @@ +-# btowc.m4 serial 7 +-dnl Copyright (C) 2008-2010 Free Software Foundation, Inc. ++# btowc.m4 serial 10 ++dnl Copyright (C) 2008-2013 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. +@@ -28,8 +28,14 @@ AC_DEFUN([gl_FUNC_BTOWC], + [ + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ +-#include + #include ++/* Tru64 with Desktop Toolkit C has a bug: must be included before ++ . ++ BSD/OS 4.0.1 has a bug: , and must be ++ included before . */ ++#include ++#include ++#include + #include + int main () + { +@@ -69,8 +75,14 @@ changequote([,])dnl + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ + #include +-#include + #include ++/* Tru64 with Desktop Toolkit C has a bug: must be included before ++ . ++ BSD/OS 4.0.1 has a bug: , and must be ++ included before . */ ++#include ++#include ++#include + #include + int main () + { +@@ -96,11 +108,6 @@ int main () + *) REPLACE_BTOWC=1 ;; + esac + fi +- if test $HAVE_BTOWC = 0 || test $REPLACE_BTOWC = 1; then +- gl_REPLACE_WCHAR_H +- AC_LIBOBJ([btowc]) +- gl_PREREQ_BTOWC +- fi + ]) + + # Prerequisites of lib/btowc.c. +diff --git a/m4/codeset.m4 b/m4/codeset.m4 +index f722b2e..c2761be 100644 +--- a/m4/codeset.m4 ++++ b/m4/codeset.m4 +@@ -1,5 +1,5 @@ + # codeset.m4 serial 5 (gettext-0.18.2) +-dnl Copyright (C) 2000-2002, 2006, 2008-2010 Free Software Foundation, Inc. ++dnl Copyright (C) 2000-2002, 2006, 2008-2013 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. +diff --git a/m4/configmake.m4 b/m4/configmake.m4 +new file mode 100644 +index 0000000..823ffc0 +--- /dev/null ++++ b/m4/configmake.m4 +@@ -0,0 +1,50 @@ ++# configmake.m4 serial 1 ++dnl Copyright (C) 2010-2013 Free Software Foundation, Inc. ++dnl This file is free software; the Free Software Foundation ++dnl gives unlimited permission to copy and/or distribute it, ++dnl with or without modifications, as long as this notice is preserved. ++ ++# gl_CONFIGMAKE_PREP ++# ------------------ ++# Guarantee all of the standard directory variables, even when used with ++# autoconf 2.59 (datarootdir wasn't supported until 2.59c) or automake ++# 1.9.6 (pkglibexecdir wasn't supported until 1.10b.). ++AC_DEFUN([gl_CONFIGMAKE_PREP], ++[ ++ dnl Technically, datadir should default to datarootdir. But if ++ dnl autoconf is too old to provide datarootdir, then reversing the ++ dnl definition is a reasonable compromise. Only AC_SUBST a variable ++ dnl if it was not already defined earlier by autoconf. ++ if test "x$datarootdir" = x; then ++ AC_SUBST([datarootdir], ['${datadir}']) ++ fi ++ dnl Copy the approach used in autoconf 2.60. ++ if test "x$docdir" = x; then ++ AC_SUBST([docdir], [m4_ifset([AC_PACKAGE_TARNAME], ++ ['${datarootdir}/doc/${PACKAGE_TARNAME}'], ++ ['${datarootdir}/doc/${PACKAGE}'])]) ++ fi ++ dnl The remaining variables missing from autoconf 2.59 are easier. ++ if test "x$htmldir" = x; then ++ AC_SUBST([htmldir], ['${docdir}']) ++ fi ++ if test "x$dvidir" = x; then ++ AC_SUBST([dvidir], ['${docdir}']) ++ fi ++ if test "x$pdfdir" = x; then ++ AC_SUBST([pdfdir], ['${docdir}']) ++ fi ++ if test "x$psdir" = x; then ++ AC_SUBST([psdir], ['${docdir}']) ++ fi ++ if test "x$lispdir" = x; then ++ AC_SUBST([lispdir], ['${datarootdir}/emacs/site-lisp']) ++ fi ++ if test "x$localedir" = x; then ++ AC_SUBST([localedir], ['${datarootdir}/locale']) ++ fi ++ ++ dnl Automake 1.9.6 only lacks pkglibexecdir; and since 1.11 merely ++ dnl provides it without AC_SUBST, this blind use of AC_SUBST is safe. ++ AC_SUBST([pkglibexecdir], ['${libexecdir}/${PACKAGE}']) ++]) +diff --git a/m4/dirname.m4 b/m4/dirname.m4 +index 576b5be..5897a2a 100644 +--- a/m4/dirname.m4 ++++ b/m4/dirname.m4 +@@ -1,5 +1,5 @@ +-#serial 8 -*- autoconf -*- +-dnl Copyright (C) 2002-2006, 2009-2010 Free Software Foundation, Inc. ++#serial 10 -*- autoconf -*- ++dnl Copyright (C) 2002-2006, 2009-2013 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. +@@ -7,18 +7,11 @@ dnl with or without modifications, as long as this notice is preserved. + AC_DEFUN([gl_DIRNAME], + [ + AC_REQUIRE([gl_DIRNAME_LGPL]) +- AC_LIBOBJ([basename]) +- AC_LIBOBJ([dirname]) + ]) + + AC_DEFUN([gl_DIRNAME_LGPL], + [ +- AC_LIBOBJ([basename-lgpl]) +- AC_LIBOBJ([dirname-lgpl]) +- AC_LIBOBJ([stripslash]) +- + dnl Prerequisites of lib/dirname.h. +- AC_REQUIRE([gl_AC_DOS]) + AC_REQUIRE([gl_DOUBLE_SLASH_ROOT]) + + dnl No prerequisites of lib/basename-lgpl.c, lib/dirname-lgpl.c, +diff --git a/m4/dos.m4 b/m4/dos.m4 +deleted file mode 100644 +index 5660542..0000000 +--- a/m4/dos.m4 ++++ /dev/null +@@ -1,71 +0,0 @@ +-#serial 11 -*- autoconf -*- +- +-# Define some macros required for proper operation of code in lib/*.c +-# on MSDOS/Windows systems. +- +-# Copyright (C) 2000-2001, 2004-2006, 2009-2010 Free Software Foundation, Inc. +-# This file is free software; the Free Software Foundation +-# gives unlimited permission to copy and/or distribute it, +-# with or without modifications, as long as this notice is preserved. +- +-# From Jim Meyering. +- +-AC_DEFUN([gl_AC_DOS], +- [ +- AC_CACHE_CHECK([whether system is Windows or MSDOS], [ac_cv_win_or_dos], +- [ +- AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [[ +-#if !defined _WIN32 && !defined __WIN32__ && !defined __MSDOS__ && !defined __CYGWIN__ +-neither MSDOS nor Windows +-#endif]])], +- [ac_cv_win_or_dos=yes], +- [ac_cv_win_or_dos=no]) +- ]) +- +- if test x"$ac_cv_win_or_dos" = xyes; then +- ac_fs_accepts_drive_letter_prefix=1 +- ac_fs_backslash_is_file_name_separator=1 +- AC_CACHE_CHECK([whether drive letter can start relative path], +- [ac_cv_drive_letter_can_be_relative], +- [ +- AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [[ +-#if defined __CYGWIN__ +-drive letters are always absolute +-#endif]])], +- [ac_cv_drive_letter_can_be_relative=yes], +- [ac_cv_drive_letter_can_be_relative=no]) +- ]) +- if test x"$ac_cv_drive_letter_can_be_relative" = xyes; then +- ac_fs_drive_letter_can_be_relative=1 +- else +- ac_fs_drive_letter_can_be_relative=0 +- fi +- else +- ac_fs_accepts_drive_letter_prefix=0 +- ac_fs_backslash_is_file_name_separator=0 +- ac_fs_drive_letter_can_be_relative=0 +- fi +- +- AC_DEFINE_UNQUOTED([FILE_SYSTEM_ACCEPTS_DRIVE_LETTER_PREFIX], +- $ac_fs_accepts_drive_letter_prefix, +- [Define on systems for which file names may have a so-called +- `drive letter' prefix, define this to compute the length of that +- prefix, including the colon.]) +- +- AH_VERBATIM(ISSLASH, +- [#if FILE_SYSTEM_BACKSLASH_IS_FILE_NAME_SEPARATOR +-# define ISSLASH(C) ((C) == '/' || (C) == '\\') +-#else +-# define ISSLASH(C) ((C) == '/') +-#endif]) +- +- AC_DEFINE_UNQUOTED([FILE_SYSTEM_BACKSLASH_IS_FILE_NAME_SEPARATOR], +- $ac_fs_backslash_is_file_name_separator, +- [Define if the backslash character may also serve as a file name +- component separator.]) +- +- AC_DEFINE_UNQUOTED([FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE], +- $ac_fs_drive_letter_can_be_relative, +- [Define if a drive letter prefix denotes a relative path if it is +- not followed by a file name component separator.]) +- ]) +diff --git a/m4/double-slash-root.m4 b/m4/double-slash-root.m4 +index 66a79c0..bd6f867 100644 +--- a/m4/double-slash-root.m4 ++++ b/m4/double-slash-root.m4 +@@ -1,5 +1,5 @@ + # double-slash-root.m4 serial 4 -*- Autoconf -*- +-dnl Copyright (C) 2006, 2008-2010 Free Software Foundation, Inc. ++dnl Copyright (C) 2006, 2008-2013 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. +diff --git a/m4/eealloc.m4 b/m4/eealloc.m4 +new file mode 100644 +index 0000000..c640ec1 +--- /dev/null ++++ b/m4/eealloc.m4 +@@ -0,0 +1,31 @@ ++# eealloc.m4 serial 3 ++dnl Copyright (C) 2003, 2009-2013 Free Software Foundation, Inc. ++dnl This file is free software; the Free Software Foundation ++dnl gives unlimited permission to copy and/or distribute it, ++dnl with or without modifications, as long as this notice is preserved. ++ ++AC_DEFUN([gl_EEALLOC], ++[ ++ AC_REQUIRE([gl_EEMALLOC]) ++ AC_REQUIRE([gl_EEREALLOC]) ++]) ++ ++AC_DEFUN([gl_EEMALLOC], ++[ ++ _AC_FUNC_MALLOC_IF( ++ [gl_cv_func_malloc_0_nonnull=1], ++ [gl_cv_func_malloc_0_nonnull=0]) ++ AC_DEFINE_UNQUOTED([MALLOC_0_IS_NONNULL], [$gl_cv_func_malloc_0_nonnull], ++ [If malloc(0) is != NULL, define this to 1. Otherwise define this ++ to 0.]) ++]) ++ ++AC_DEFUN([gl_EEREALLOC], ++[ ++ _AC_FUNC_REALLOC_IF( ++ [gl_cv_func_realloc_0_nonnull=1], ++ [gl_cv_func_realloc_0_nonnull=0]) ++ AC_DEFINE_UNQUOTED([REALLOC_0_IS_NONNULL], [$gl_cv_func_realloc_0_nonnull], ++ [If realloc(NULL,0) is != NULL, define this to 1. Otherwise define this ++ to 0.]) ++]) +diff --git a/m4/errno_h.m4 b/m4/errno_h.m4 +index d02a039..c813ea5 100644 +--- a/m4/errno_h.m4 ++++ b/m4/errno_h.m4 +@@ -1,5 +1,5 @@ +-# errno_h.m4 serial 6 +-dnl Copyright (C) 2004, 2006, 2008, 2009, 2010 Free Software Foundation, Inc. ++# errno_h.m4 serial 12 ++dnl Copyright (C) 2004, 2006, 2008-2013 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. +@@ -10,6 +10,9 @@ AC_DEFUN_ONCE([gl_HEADER_ERRNO_H], + AC_CACHE_CHECK([for complete errno.h], [gl_cv_header_errno_h_complete], [ + AC_EGREP_CPP([booboo],[ + #include ++#if !defined ETXTBSY ++booboo ++#endif + #if !defined ENOMSG + booboo + #endif +@@ -34,12 +37,30 @@ booboo + #if !defined ENOTSUP + booboo + #endif ++#if !defined ENETRESET ++booboo ++#endif ++#if !defined ECONNABORTED ++booboo ++#endif + #if !defined ESTALE + booboo + #endif ++#if !defined EDQUOT ++booboo ++#endif + #if !defined ECANCELED + booboo + #endif ++#if !defined EOWNERDEAD ++booboo ++#endif ++#if !defined ENOTRECOVERABLE ++booboo ++#endif ++#if !defined EILSEQ ++booboo ++#endif + ], + [gl_cv_header_errno_h_complete=no], + [gl_cv_header_errno_h_complete=yes]) +@@ -47,10 +68,11 @@ booboo + if test $gl_cv_header_errno_h_complete = yes; then + ERRNO_H='' + else +- gl_CHECK_NEXT_HEADERS([errno.h]) ++ gl_NEXT_HEADERS([errno.h]) + ERRNO_H='errno.h' + fi + AC_SUBST([ERRNO_H]) ++ AM_CONDITIONAL([GL_GENERATE_ERRNO_H], [test -n "$ERRNO_H"]) + gl_REPLACE_ERRNO_VALUE([EMULTIHOP]) + gl_REPLACE_ERRNO_VALUE([ENOLINK]) + gl_REPLACE_ERRNO_VALUE([EOVERFLOW]) +diff --git a/m4/error.m4 b/m4/error.m4 +index dd5a197..29e6fdc 100644 +--- a/m4/error.m4 ++++ b/m4/error.m4 +@@ -1,6 +1,6 @@ +-#serial 13 ++#serial 14 + +-# Copyright (C) 1996-1998, 2001-2004, 2009-2010 Free Software Foundation, Inc. ++# Copyright (C) 1996-1998, 2001-2004, 2009-2013 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -8,16 +8,8 @@ + + AC_DEFUN([gl_ERROR], + [ +- AC_FUNC_ERROR_AT_LINE +- dnl Note: AC_FUNC_ERROR_AT_LINE does AC_LIBSOURCES([error.h, error.c]). +- gl_PREREQ_ERROR +-]) +- +-# Redefine AC_FUNC_ERROR_AT_LINE, because it is no longer maintained in +-# Autoconf. +-AC_DEFUN([AC_FUNC_ERROR_AT_LINE], +-[ +- AC_LIBSOURCES([error.h, error.c])dnl ++ dnl We don't use AC_FUNC_ERROR_AT_LINE any more, because it is no longer ++ dnl maintained in Autoconf and because it invokes AC_LIBOBJ. + AC_CACHE_CHECK([for error_at_line], [ac_cv_lib_error_at_line], + [AC_LINK_IFELSE( + [AC_LANG_PROGRAM( +@@ -25,15 +17,11 @@ AC_DEFUN([AC_FUNC_ERROR_AT_LINE], + [[error_at_line (0, 0, "", 0, "an error occurred");]])], + [ac_cv_lib_error_at_line=yes], + [ac_cv_lib_error_at_line=no])]) +- if test $ac_cv_lib_error_at_line = no; then +- AC_LIBOBJ([error]) +- fi + ]) + + # Prerequisites of lib/error.c. + AC_DEFUN([gl_PREREQ_ERROR], + [ + AC_REQUIRE([AC_FUNC_STRERROR_R]) +- AC_REQUIRE([AC_C_INLINE]) + : + ]) +diff --git a/m4/exponentd.m4 b/m4/exponentd.m4 +new file mode 100644 +index 0000000..09df468 +--- /dev/null ++++ b/m4/exponentd.m4 +@@ -0,0 +1,116 @@ ++# exponentd.m4 serial 3 ++dnl Copyright (C) 2007-2008, 2010-2013 Free Software Foundation, Inc. ++dnl This file is free software; the Free Software Foundation ++dnl gives unlimited permission to copy and/or distribute it, ++dnl with or without modifications, as long as this notice is preserved. ++AC_DEFUN([gl_DOUBLE_EXPONENT_LOCATION], ++[ ++ AC_CACHE_CHECK([where to find the exponent in a 'double'], ++ [gl_cv_cc_double_expbit0], ++ [ ++ AC_RUN_IFELSE( ++ [AC_LANG_SOURCE([[ ++#include ++#include ++#include ++#include ++#define NWORDS \ ++ ((sizeof (double) + sizeof (unsigned int) - 1) / sizeof (unsigned int)) ++typedef union { double value; unsigned int word[NWORDS]; } memory_double; ++static unsigned int ored_words[NWORDS]; ++static unsigned int anded_words[NWORDS]; ++static void add_to_ored_words (double x) ++{ ++ memory_double m; ++ size_t i; ++ /* Clear it first, in case sizeof (double) < sizeof (memory_double). */ ++ memset (&m, 0, sizeof (memory_double)); ++ m.value = x; ++ for (i = 0; i < NWORDS; i++) ++ { ++ ored_words[i] |= m.word[i]; ++ anded_words[i] &= m.word[i]; ++ } ++} ++int main () ++{ ++ size_t j; ++ FILE *fp = fopen ("conftest.out", "w"); ++ if (fp == NULL) ++ return 1; ++ for (j = 0; j < NWORDS; j++) ++ anded_words[j] = ~ (unsigned int) 0; ++ add_to_ored_words (0.25); ++ add_to_ored_words (0.5); ++ add_to_ored_words (1.0); ++ add_to_ored_words (2.0); ++ add_to_ored_words (4.0); ++ /* Remove bits that are common (e.g. if representation of the first mantissa ++ bit is explicit). */ ++ for (j = 0; j < NWORDS; j++) ++ ored_words[j] &= ~anded_words[j]; ++ /* Now find the nonzero word. */ ++ for (j = 0; j < NWORDS; j++) ++ if (ored_words[j] != 0) ++ break; ++ if (j < NWORDS) ++ { ++ size_t i; ++ for (i = j + 1; i < NWORDS; i++) ++ if (ored_words[i] != 0) ++ { ++ fprintf (fp, "unknown"); ++ return (fclose (fp) != 0); ++ } ++ for (i = 0; ; i++) ++ if ((ored_words[j] >> i) & 1) ++ { ++ fprintf (fp, "word %d bit %d", (int) j, (int) i); ++ return (fclose (fp) != 0); ++ } ++ } ++ fprintf (fp, "unknown"); ++ return (fclose (fp) != 0); ++} ++ ]])], ++ [gl_cv_cc_double_expbit0=`cat conftest.out`], ++ [gl_cv_cc_double_expbit0="unknown"], ++ [ ++ dnl On ARM, there are two 'double' floating-point formats, used by ++ dnl different sets of instructions: The older FPA instructions assume ++ dnl that they are stored in big-endian word order, while the words ++ dnl (like integer types) are stored in little-endian byte order. ++ dnl The newer VFP instructions assume little-endian order ++ dnl consistently. ++ AC_EGREP_CPP([mixed_endianness], [ ++#if defined arm || defined __arm || defined __arm__ ++ mixed_endianness ++#endif ++ ], ++ [gl_cv_cc_double_expbit0="unknown"], ++ [ ++ pushdef([AC_MSG_CHECKING],[:])dnl ++ pushdef([AC_MSG_RESULT],[:])dnl ++ pushdef([AC_MSG_RESULT_UNQUOTED],[:])dnl ++ AC_C_BIGENDIAN( ++ [gl_cv_cc_double_expbit0="word 0 bit 20"], ++ [gl_cv_cc_double_expbit0="word 1 bit 20"], ++ [gl_cv_cc_double_expbit0="unknown"]) ++ popdef([AC_MSG_RESULT_UNQUOTED])dnl ++ popdef([AC_MSG_RESULT])dnl ++ popdef([AC_MSG_CHECKING])dnl ++ ]) ++ ]) ++ rm -f conftest.out ++ ]) ++ case "$gl_cv_cc_double_expbit0" in ++ word*bit*) ++ word=`echo "$gl_cv_cc_double_expbit0" | sed -e 's/word //' -e 's/ bit.*//'` ++ bit=`echo "$gl_cv_cc_double_expbit0" | sed -e 's/word.*bit //'` ++ AC_DEFINE_UNQUOTED([DBL_EXPBIT0_WORD], [$word], ++ [Define as the word index where to find the exponent of 'double'.]) ++ AC_DEFINE_UNQUOTED([DBL_EXPBIT0_BIT], [$bit], ++ [Define as the bit index in the word where to find bit 0 of the exponent of 'double'.]) ++ ;; ++ esac ++]) +diff --git a/m4/extensions.m4 b/m4/extensions.m4 +index 7d9458a..07ba376 100644 +--- a/m4/extensions.m4 ++++ b/m4/extensions.m4 +@@ -1,14 +1,14 @@ +-# serial 9 -*- Autoconf -*- ++# serial 13 -*- Autoconf -*- + # Enable extensions on systems that normally disable them. + +-# Copyright (C) 2003, 2006-2010 Free Software Foundation, Inc. ++# Copyright (C) 2003, 2006-2013 Free Software Foundation, Inc. + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, + # with or without modifications, as long as this notice is preserved. + + # This definition of AC_USE_SYSTEM_EXTENSIONS is stolen from CVS + # Autoconf. Perhaps we can remove this once we can assume Autoconf +-# 2.62 or later everywhere, but since CVS Autoconf mutates rapidly ++# 2.70 or later everywhere, but since Autoconf mutates rapidly + # enough in this area it's likely we'll need to redefine + # AC_USE_SYSTEM_EXTENSIONS for quite some time. + +@@ -30,6 +30,7 @@ + # ------------------------ + # Enable extensions on systems that normally disable them, + # typically due to standards-conformance issues. ++# + # Remember that #undef in AH_VERBATIM gets replaced with #define by + # AC_DEFINE. The goal here is to define all known feature-enabling + # macros, then, if reports of conflicts are made, disable macros that +@@ -38,35 +39,31 @@ AC_DEFUN_ONCE([AC_USE_SYSTEM_EXTENSIONS], + [AC_BEFORE([$0], [AC_COMPILE_IFELSE])dnl + AC_BEFORE([$0], [AC_RUN_IFELSE])dnl + +- AC_REQUIRE([AC_CANONICAL_HOST]) +- + AC_CHECK_HEADER([minix/config.h], [MINIX=yes], [MINIX=]) + if test "$MINIX" = yes; then + AC_DEFINE([_POSIX_SOURCE], [1], +- [Define to 1 if you need to in order for `stat' and other ++ [Define to 1 if you need to in order for 'stat' and other + things to work.]) + AC_DEFINE([_POSIX_1_SOURCE], [2], + [Define to 2 if the system does not provide POSIX.1 features + except with this defined.]) + AC_DEFINE([_MINIX], [1], + [Define to 1 if on MINIX.]) ++ AC_DEFINE([_NETBSD_SOURCE], [1], ++ [Define to 1 to make NetBSD features available. MINIX 3 needs this.]) + fi + +- dnl HP-UX 11.11 defines mbstate_t only if _XOPEN_SOURCE is defined to 500, +- dnl regardless of whether the flags -Ae or _D_HPUX_SOURCE=1 are already +- dnl provided. +- case "$host_os" in +- hpux*) +- AC_DEFINE([_XOPEN_SOURCE], [500], +- [Define to 500 only on HP-UX.]) +- ;; +- esac +- +- AH_VERBATIM([__EXTENSIONS__], ++dnl Use a different key than __EXTENSIONS__, as that name broke existing ++dnl configure.ac when using autoheader 2.62. ++ AH_VERBATIM([USE_SYSTEM_EXTENSIONS], + [/* Enable extensions on AIX 3, Interix. */ + #ifndef _ALL_SOURCE + # undef _ALL_SOURCE + #endif ++/* Enable general extensions on OS X. */ ++#ifndef _DARWIN_C_SOURCE ++# undef _DARWIN_C_SOURCE ++#endif + /* Enable GNU extensions on systems that have them. */ + #ifndef _GNU_SOURCE + # undef _GNU_SOURCE +@@ -79,6 +76,12 @@ AC_BEFORE([$0], [AC_RUN_IFELSE])dnl + #ifndef _TANDEM_SOURCE + # undef _TANDEM_SOURCE + #endif ++/* Enable X/Open extensions if necessary. HP-UX 11.11 defines ++ mbstate_t only if _XOPEN_SOURCE is defined to 500, regardless of ++ whether compiling with -Ae or -D_HPUX_SOURCE=1. */ ++#ifndef _XOPEN_SOURCE ++# undef _XOPEN_SOURCE ++#endif + /* Enable general extensions on Solaris. */ + #ifndef __EXTENSIONS__ + # undef __EXTENSIONS__ +@@ -95,9 +98,26 @@ AC_BEFORE([$0], [AC_RUN_IFELSE])dnl + test $ac_cv_safe_to_define___extensions__ = yes && + AC_DEFINE([__EXTENSIONS__]) + AC_DEFINE([_ALL_SOURCE]) ++ AC_DEFINE([_DARWIN_C_SOURCE]) + AC_DEFINE([_GNU_SOURCE]) + AC_DEFINE([_POSIX_PTHREAD_SEMANTICS]) + AC_DEFINE([_TANDEM_SOURCE]) ++ AC_CACHE_CHECK([whether _XOPEN_SOURCE should be defined], ++ [ac_cv_should_define__xopen_source], ++ [ac_cv_should_define__xopen_source=no ++ AC_COMPILE_IFELSE( ++ [AC_LANG_PROGRAM([[ ++ #include ++ mbstate_t x;]])], ++ [], ++ [AC_COMPILE_IFELSE( ++ [AC_LANG_PROGRAM([[ ++ #define _XOPEN_SOURCE 500 ++ #include ++ mbstate_t x;]])], ++ [ac_cv_should_define__xopen_source=yes])])]) ++ test $ac_cv_should_define__xopen_source = yes && ++ AC_DEFINE([_XOPEN_SOURCE], [500]) + ])# AC_USE_SYSTEM_EXTENSIONS + + # gl_USE_SYSTEM_EXTENSIONS +diff --git a/m4/extern-inline.m4 b/m4/extern-inline.m4 +new file mode 100644 +index 0000000..0152f29 +--- /dev/null ++++ b/m4/extern-inline.m4 +@@ -0,0 +1,65 @@ ++dnl 'extern inline' a la ISO C99. ++ ++dnl Copyright 2012-2013 Free Software Foundation, Inc. ++dnl This file is free software; the Free Software Foundation ++dnl gives unlimited permission to copy and/or distribute it, ++dnl with or without modifications, as long as this notice is preserved. ++ ++AC_DEFUN([gl_EXTERN_INLINE], ++[ ++ AH_VERBATIM([extern_inline], ++[/* _GL_INLINE is a portable alternative to ISO C99 plain 'inline'. ++ _GL_EXTERN_INLINE is a portable alternative to 'extern inline'. ++ _GL_INLINE_HEADER_BEGIN contains useful stuff to put ++ in an include file, before uses of _GL_INLINE. ++ It suppresses GCC's bogus "no previous prototype for 'FOO'" diagnostic, ++ when FOO is an inline function in the header; see ++ . ++ _GL_INLINE_HEADER_END contains useful stuff to put ++ in the same include file, after uses of _GL_INLINE. ++ ++ Suppress extern inline with HP-UX cc, as it appears to be broken; see ++ . ++ ++ Suppress the use of extern inline on Apple's platforms, ++ as Libc-825.25 (2012-09-19) is incompatible with it; see ++ . ++ Perhaps Apple will fix this some day. */ ++#if ((__GNUC__ \ ++ ? defined __GNUC_STDC_INLINE__ && __GNUC_STDC_INLINE__ \ ++ : 199901L <= __STDC_VERSION__ && !defined __HP_cc) \ ++ && !defined __APPLE__) ++# define _GL_INLINE inline ++# define _GL_EXTERN_INLINE extern inline ++#elif 2 < __GNUC__ + (7 <= __GNUC_MINOR__) && !defined __APPLE__ ++# if __GNUC_GNU_INLINE__ ++ /* __gnu_inline__ suppresses a GCC 4.2 diagnostic. */ ++# define _GL_INLINE extern inline __attribute__ ((__gnu_inline__)) ++# else ++# define _GL_INLINE extern inline ++# endif ++# define _GL_EXTERN_INLINE extern ++#else ++# define _GL_INLINE static _GL_UNUSED ++# define _GL_EXTERN_INLINE static _GL_UNUSED ++#endif ++ ++#if 4 < __GNUC__ + (6 <= __GNUC_MINOR__) ++# if defined __GNUC_STDC_INLINE__ && __GNUC_STDC_INLINE__ ++# define _GL_INLINE_HEADER_CONST_PRAGMA ++# else ++# define _GL_INLINE_HEADER_CONST_PRAGMA \ ++ _Pragma ("GCC diagnostic ignored \"-Wsuggest-attribute=const\"") ++# endif ++# define _GL_INLINE_HEADER_BEGIN \ ++ _Pragma ("GCC diagnostic push") \ ++ _Pragma ("GCC diagnostic ignored \"-Wmissing-prototypes\"") \ ++ _Pragma ("GCC diagnostic ignored \"-Wmissing-declarations\"") \ ++ _GL_INLINE_HEADER_CONST_PRAGMA ++# define _GL_INLINE_HEADER_END \ ++ _Pragma ("GCC diagnostic pop") ++#else ++# define _GL_INLINE_HEADER_BEGIN ++# define _GL_INLINE_HEADER_END ++#endif]) ++]) +diff --git a/m4/fcntl-o.m4 b/m4/fcntl-o.m4 +index 1adacc8..87cc4bd 100644 +--- a/m4/fcntl-o.m4 ++++ b/m4/fcntl-o.m4 +@@ -1,5 +1,5 @@ +-# fcntl-o.m4 serial 2 +-dnl Copyright (C) 2006, 2009-2010 Free Software Foundation, Inc. ++# fcntl-o.m4 serial 4 ++dnl Copyright (C) 2006, 2009-2013 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. +@@ -17,12 +17,21 @@ AC_DEFUN([gl_FCNTL_O_FLAGS], + m4_ifdef([AC_USE_SYSTEM_EXTENSIONS], + [AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])], + [AC_REQUIRE([AC_GNU_SOURCE])]) ++ ++ AC_CHECK_HEADERS_ONCE([unistd.h]) ++ AC_CHECK_FUNCS_ONCE([symlink]) + AC_CACHE_CHECK([for working fcntl.h], [gl_cv_header_working_fcntl_h], + [AC_RUN_IFELSE( + [AC_LANG_PROGRAM( + [[#include + #include +- #include ++ #if HAVE_UNISTD_H ++ # include ++ #else /* on Windows with MSVC */ ++ # include ++ # include ++ # defined sleep(n) _sleep ((n) * 1000) ++ #endif + #include + #ifndef O_NOATIME + #define O_NOATIME 0 +@@ -37,34 +46,74 @@ AC_DEFUN([gl_FCNTL_O_FLAGS], + }; + ]], + [[ +- int status = !constants; ++ int result = !constants; ++ #if HAVE_SYMLINK + { + static char const sym[] = "conftest.sym"; +- if (symlink (".", sym) != 0 +- || close (open (sym, O_RDONLY | O_NOFOLLOW)) == 0) +- status |= 32; ++ if (symlink ("/dev/null", sym) != 0) ++ result |= 2; ++ else ++ { ++ int fd = open (sym, O_WRONLY | O_NOFOLLOW | O_CREAT, 0); ++ if (fd >= 0) ++ { ++ close (fd); ++ result |= 4; ++ } ++ } ++ if (unlink (sym) != 0 || symlink (".", sym) != 0) ++ result |= 2; ++ else ++ { ++ int fd = open (sym, O_RDONLY | O_NOFOLLOW); ++ if (fd >= 0) ++ { ++ close (fd); ++ result |= 4; ++ } ++ } + unlink (sym); + } ++ #endif + { + static char const file[] = "confdefs.h"; + int fd = open (file, O_RDONLY | O_NOATIME); +- char c; +- struct stat st0, st1; +- if (fd < 0 +- || fstat (fd, &st0) != 0 +- || sleep (1) != 0 +- || read (fd, &c, 1) != 1 +- || close (fd) != 0 +- || stat (file, &st1) != 0 +- || st0.st_atime != st1.st_atime) +- status |= 64; ++ if (fd < 0) ++ result |= 8; ++ else ++ { ++ struct stat st0; ++ if (fstat (fd, &st0) != 0) ++ result |= 16; ++ else ++ { ++ char c; ++ sleep (1); ++ if (read (fd, &c, 1) != 1) ++ result |= 24; ++ else ++ { ++ if (close (fd) != 0) ++ result |= 32; ++ else ++ { ++ struct stat st1; ++ if (stat (file, &st1) != 0) ++ result |= 40; ++ else ++ if (st0.st_atime != st1.st_atime) ++ result |= 64; ++ } ++ } ++ } ++ } + } +- return status;]])], ++ return result;]])], + [gl_cv_header_working_fcntl_h=yes], + [case $? in #( +- 32) gl_cv_header_working_fcntl_h='no (bad O_NOFOLLOW)';; #( ++ 4) gl_cv_header_working_fcntl_h='no (bad O_NOFOLLOW)';; #( + 64) gl_cv_header_working_fcntl_h='no (bad O_NOATIME)';; #( +- 96) gl_cv_header_working_fcntl_h='no (bad O_NOATIME, O_NOFOLLOW)';; #( ++ 68) gl_cv_header_working_fcntl_h='no (bad O_NOATIME, O_NOFOLLOW)';; #( + *) gl_cv_header_working_fcntl_h='no';; + esac], + [gl_cv_header_working_fcntl_h=cross-compiling])]) +diff --git a/m4/float_h.m4 b/m4/float_h.m4 +index f6099db..397f2d1 100644 +--- a/m4/float_h.m4 ++++ b/m4/float_h.m4 +@@ -1,5 +1,5 @@ +-# float_h.m4 serial 4 +-dnl Copyright (C) 2007, 2009, 2010 Free Software Foundation, Inc. ++# float_h.m4 serial 9 ++dnl Copyright (C) 2007, 2009-2013 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. +@@ -9,11 +9,90 @@ AC_DEFUN([gl_FLOAT_H], + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_HOST]) + FLOAT_H= ++ REPLACE_FLOAT_LDBL=0 + case "$host_os" in +- beos* | openbsd* | mirbsd*) ++ aix* | beos* | openbsd* | mirbsd* | irix*) + FLOAT_H=float.h +- gl_CHECK_NEXT_HEADERS([float.h]) ++ ;; ++ freebsd*) ++ case "$host_cpu" in ++changequote(,)dnl ++ i[34567]86 ) ++changequote([,])dnl ++ FLOAT_H=float.h ++ ;; ++ x86_64 ) ++ # On x86_64 systems, the C compiler may still be generating ++ # 32-bit code. ++ AC_EGREP_CPP([yes], ++ [#if defined __LP64__ || defined __x86_64__ || defined __amd64__ ++ yes ++ #endif], ++ [], ++ [FLOAT_H=float.h]) ++ ;; ++ esac ++ ;; ++ linux*) ++ case "$host_cpu" in ++ powerpc*) ++ FLOAT_H=float.h ++ ;; ++ esac ++ ;; ++ esac ++ case "$host_os" in ++ aix* | freebsd* | linux*) ++ if test -n "$FLOAT_H"; then ++ REPLACE_FLOAT_LDBL=1 ++ fi + ;; + esac ++ ++ dnl Test against glibc-2.7 Linux/SPARC64 bug. ++ REPLACE_ITOLD=0 ++ AC_CACHE_CHECK([whether conversion from 'int' to 'long double' works], ++ [gl_cv_func_itold_works], ++ [ ++ AC_RUN_IFELSE( ++ [AC_LANG_SOURCE([[ ++int i = -1; ++volatile long double ld; ++int main () ++{ ++ ld += i * 1.0L; ++ if (ld > 0) ++ return 1; ++ return 0; ++}]])], ++ [gl_cv_func_itold_works=yes], ++ [gl_cv_func_itold_works=no], ++ [case "$host" in ++ sparc*-*-linux*) ++ AC_EGREP_CPP([yes], ++ [#if defined __LP64__ || defined __arch64__ ++ yes ++ #endif], ++ [gl_cv_func_itold_works="guessing no"], ++ [gl_cv_func_itold_works="guessing yes"]) ++ ;; ++ *) gl_cv_func_itold_works="guessing yes" ;; ++ esac ++ ]) ++ ]) ++ case "$gl_cv_func_itold_works" in ++ *no) ++ REPLACE_ITOLD=1 ++ dnl We add the workaround to but also to , ++ dnl to increase the chances that the fix function gets pulled in. ++ FLOAT_H=float.h ++ ;; ++ esac ++ ++ if test -n "$FLOAT_H"; then ++ gl_NEXT_HEADERS([float.h]) ++ fi + AC_SUBST([FLOAT_H]) ++ AM_CONDITIONAL([GL_GENERATE_FLOAT_H], [test -n "$FLOAT_H"]) ++ AC_SUBST([REPLACE_ITOLD]) + ]) +diff --git a/m4/fnmatch.m4 b/m4/fnmatch.m4 +index 212ead5..fa0ba4d 100644 +--- a/m4/fnmatch.m4 ++++ b/m4/fnmatch.m4 +@@ -1,6 +1,6 @@ +-# Check for fnmatch - serial 4. ++# Check for fnmatch - serial 9. + +-# Copyright (C) 2000-2007, 2009-2010 Free Software Foundation, Inc. ++# Copyright (C) 2000-2007, 2009-2013 Free Software Foundation, Inc. + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, + # with or without modifications, as long as this notice is preserved. +@@ -20,7 +20,9 @@ AC_DEFUN([gl_FUNC_FNMATCH_POSIX], + AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) + + FNMATCH_H= +- gl_fnmatch_required_lowercase=`echo $gl_fnmatch_required | tr 'A-Z' 'a-z'` ++ gl_fnmatch_required_lowercase=` ++ echo $gl_fnmatch_required | LC_ALL=C tr '[[A-Z]]' '[[a-z]]' ++ ` + gl_fnmatch_cache_var="gl_cv_func_fnmatch_${gl_fnmatch_required_lowercase}" + AC_CACHE_CHECK([for working $gl_fnmatch_required fnmatch], + [$gl_fnmatch_cache_var], +@@ -58,33 +60,62 @@ AC_DEFUN([gl_FUNC_FNMATCH_POSIX], + static char const a01[] = { 'a' + 1, 0 }; + static char const bs_1[] = { '\\\\' - 1, 0 }; + static char const bs01[] = { '\\\\' + 1, 0 }; +- return +- !(n ("a*", "", 0) +- && y ("a*", "abc", 0) +- && n ("d*/*1", "d/s/1", FNM_PATHNAME) +- && y ("a\\\\bc", "abc", 0) +- && n ("a\\\\bc", "abc", FNM_NOESCAPE) +- && y ("*x", ".x", 0) +- && n ("*x", ".x", FNM_PERIOD) +- && y (Apat, "\\\\", 0) && y (Apat, "A", 0) +- && y (apat, "\\\\", 0) && y (apat, "a", 0) +- && n (Apat, A_1, 0) == ('A' < '\\\\') +- && n (apat, a_1, 0) == ('a' < '\\\\') +- && y (Apat, A01, 0) == ('A' < '\\\\') +- && y (apat, a01, 0) == ('a' < '\\\\') +- && y (Apat, bs_1, 0) == ('A' < '\\\\') +- && y (apat, bs_1, 0) == ('a' < '\\\\') +- && n (Apat, bs01, 0) == ('A' < '\\\\') +- && n (apat, bs01, 0) == ('a' < '\\\\') +- $gl_fnmatch_gnu_start +- && y ("xxXX", "xXxX", FNM_CASEFOLD) +- && y ("a++(x|yy)b", "a+xyyyyxb", FNM_EXTMATCH) +- && n ("d*/*1", "d/s/1", FNM_FILE_NAME) +- && y ("*", "x", FNM_FILE_NAME | FNM_LEADING_DIR) +- && y ("x*", "x/y/z", FNM_FILE_NAME | FNM_LEADING_DIR) +- && y ("*c*", "c/x", FNM_FILE_NAME | FNM_LEADING_DIR) +- $gl_fnmatch_gnu_end +- ); ++ int result = 0; ++ if (!n ("a*", "", 0)) ++ return 1; ++ if (!y ("a*", "abc", 0)) ++ return 1; ++ if (!y ("[/b", "[/b", 0)) /*"]]"*/ /* glibc Bugzilla bug 12378 */ ++ return 1; ++ if (!n ("d*/*1", "d/s/1", FNM_PATHNAME)) ++ return 2; ++ if (!y ("a\\\\bc", "abc", 0)) ++ return 3; ++ if (!n ("a\\\\bc", "abc", FNM_NOESCAPE)) ++ return 3; ++ if (!y ("*x", ".x", 0)) ++ return 4; ++ if (!n ("*x", ".x", FNM_PERIOD)) ++ return 4; ++ if (!y (Apat, "\\\\", 0)) ++ return 5; ++ if (!y (Apat, "A", 0)) ++ return 5; ++ if (!y (apat, "\\\\", 0)) ++ return 5; ++ if (!y (apat, "a", 0)) ++ return 5; ++ if (!(n (Apat, A_1, 0) == ('A' < '\\\\'))) ++ return 5; ++ if (!(n (apat, a_1, 0) == ('a' < '\\\\'))) ++ return 5; ++ if (!(y (Apat, A01, 0) == ('A' < '\\\\'))) ++ return 5; ++ if (!(y (apat, a01, 0) == ('a' < '\\\\'))) ++ return 5; ++ if (!(y (Apat, bs_1, 0) == ('A' < '\\\\'))) ++ return 5; ++ if (!(y (apat, bs_1, 0) == ('a' < '\\\\'))) ++ return 5; ++ if (!(n (Apat, bs01, 0) == ('A' < '\\\\'))) ++ return 5; ++ if (!(n (apat, bs01, 0) == ('a' < '\\\\'))) ++ return 5; ++ $gl_fnmatch_gnu_start ++ if (!y ("xxXX", "xXxX", FNM_CASEFOLD)) ++ result |= 8; ++ if (!y ("a++(x|yy)b", "a+xyyyyxb", FNM_EXTMATCH)) ++ result |= 16; ++ if (!n ("d*/*1", "d/s/1", FNM_FILE_NAME)) ++ result |= 32; ++ if (!y ("*", "x", FNM_FILE_NAME | FNM_LEADING_DIR)) ++ result |= 64; ++ if (!y ("x*", "x/y/z", FNM_FILE_NAME | FNM_LEADING_DIR)) ++ result |= 64; ++ if (!y ("*c*", "c/x", FNM_FILE_NAME | FNM_LEADING_DIR)) ++ result |= 64; ++ $gl_fnmatch_gnu_end ++ return result; + ]])], + [eval "$gl_fnmatch_cache_var=yes"], + [eval "$gl_fnmatch_cache_var=no"], +@@ -97,19 +128,9 @@ AC_DEFUN([gl_FUNC_FNMATCH_POSIX], + rm -f "$gl_source_base/fnmatch.h" + else + FNMATCH_H=fnmatch.h +- AC_LIBOBJ([fnmatch]) +- dnl We must choose a different name for our function, since on ELF systems +- dnl a broken fnmatch() in libc.so would override our fnmatch() if it is +- dnl compiled into a shared library. +- AC_DEFINE_UNQUOTED([fnmatch], [${gl_fnmatch_required_lowercase}_fnmatch], +- [Define to a replacement function name for fnmatch().]) +- dnl Prerequisites of lib/fnmatch.c. +- AC_REQUIRE([AC_TYPE_MBSTATE_T]) +- AC_CHECK_DECLS([isblank], [], [], [#include ]) +- AC_CHECK_FUNCS_ONCE([btowc isblank iswctype mbsrtowcs mempcpy wmemchr wmemcpy wmempcpy]) +- AC_CHECK_HEADERS_ONCE([wctype.h]) + fi + AC_SUBST([FNMATCH_H]) ++ AM_CONDITIONAL([GL_GENERATE_FNMATCH_H], [test -n "$FNMATCH_H"]) + ]) + + # Request a POSIX compliant fnmatch function with GNU extensions. +@@ -119,3 +140,17 @@ AC_DEFUN([gl_FUNC_FNMATCH_GNU], + + AC_REQUIRE([gl_FUNC_FNMATCH_POSIX]) + ]) ++ ++AC_DEFUN([gl_PREREQ_FNMATCH], ++[ ++ dnl We must choose a different name for our function, since on ELF systems ++ dnl a broken fnmatch() in libc.so would override our fnmatch() if it is ++ dnl compiled into a shared library. ++ AC_DEFINE_UNQUOTED([fnmatch], [${gl_fnmatch_required_lowercase}_fnmatch], ++ [Define to a replacement function name for fnmatch().]) ++ dnl Prerequisites of lib/fnmatch.c. ++ AC_REQUIRE([AC_TYPE_MBSTATE_T]) ++ AC_CHECK_DECLS([isblank], [], [], [[#include ]]) ++ AC_CHECK_FUNCS_ONCE([btowc isblank iswctype mbsrtowcs mempcpy wmemchr wmemcpy wmempcpy]) ++ AC_CHECK_HEADERS_ONCE([wctype.h]) ++]) +diff --git a/m4/getdelim.m4 b/m4/getdelim.m4 +index 4beb150..36f66a1 100644 +--- a/m4/getdelim.m4 ++++ b/m4/getdelim.m4 +@@ -1,6 +1,6 @@ +-# getdelim.m4 serial 6 ++# getdelim.m4 serial 10 + +-dnl Copyright (C) 2005-2007, 2009-2010 Free Software Foundation, Inc. ++dnl Copyright (C) 2005-2007, 2009-2013 Free Software Foundation, Inc. + dnl + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, +@@ -19,6 +19,7 @@ AC_DEFUN([gl_FUNC_GETDELIM], + + AC_CHECK_FUNCS_ONCE([getdelim]) + if test $ac_cv_func_getdelim = yes; then ++ HAVE_GETDELIM=1 + dnl Found it in some library. Verify that it works. + AC_CACHE_CHECK([for working getdelim function], [gl_cv_func_working_getdelim], + [echo fooNbarN | tr -d '\012' | tr N '\012' > conftest.data +@@ -38,7 +39,7 @@ AC_DEFUN([gl_FUNC_GETDELIM], + size_t siz = 0; + int len = getdelim (&line, &siz, '\n', in); + if (!(len == 4 && line && strcmp (line, "foo\n") == 0)) +- return 1; ++ return 2; + } + { + /* Test result for a NULL buffer and a non-zero size. +@@ -46,7 +47,7 @@ AC_DEFUN([gl_FUNC_GETDELIM], + char *line = NULL; + size_t siz = (size_t)(~0) / 4; + if (getdelim (&line, &siz, '\n', in) == -1) +- return 1; ++ return 3; + } + return 0; + } +@@ -57,29 +58,26 @@ AC_DEFUN([gl_FUNC_GETDELIM], + [ + #include + #ifdef __GNU_LIBRARY__ +- #if (__GLIBC__ >= 2) ++ #if (__GLIBC__ >= 2) && !defined __UCLIBC__ + Lucky GNU user + #endif + #endif + ], +- [gl_cv_func_working_getdelim=yes], +- [gl_cv_func_working_getdelim=no])] ++ [gl_cv_func_working_getdelim="guessing yes"], ++ [gl_cv_func_working_getdelim="guessing no"])] + )]) ++ case "$gl_cv_func_working_getdelim" in ++ *no) ++ REPLACE_GETDELIM=1 ++ ;; ++ esac + else +- gl_cv_func_working_getdelim=no ++ HAVE_GETDELIM=0 + fi + + if test $ac_cv_have_decl_getdelim = no; then + HAVE_DECL_GETDELIM=0 + fi +- +- if test $gl_cv_func_working_getdelim = no; then +- if test $ac_cv_func_getdelim = yes; then +- REPLACE_GETDELIM=1 +- fi +- AC_LIBOBJ([getdelim]) +- gl_PREREQ_GETDELIM +- fi + ]) + + # Prerequisites of lib/getdelim.c. +diff --git a/m4/getline.m4 b/m4/getline.m4 +index 8300560..342bc99 100644 +--- a/m4/getline.m4 ++++ b/m4/getline.m4 +@@ -1,6 +1,6 @@ +-# getline.m4 serial 21 ++# getline.m4 serial 26 + +-dnl Copyright (C) 1998-2003, 2005-2007, 2009-2010 Free Software Foundation, ++dnl Copyright (C) 1998-2003, 2005-2007, 2009-2013 Free Software Foundation, + dnl Inc. + dnl + dnl This file is free software; the Free Software Foundation +@@ -46,7 +46,7 @@ AC_DEFUN([gl_FUNC_GETLINE], + size_t siz = 0; + int len = getline (&line, &siz, in); + if (!(len == 4 && line && strcmp (line, "foo\n") == 0)) +- return 1; ++ return 2; + } + { + /* Test result for a NULL buffer and a non-zero size. +@@ -54,7 +54,7 @@ AC_DEFUN([gl_FUNC_GETLINE], + char *line = NULL; + size_t siz = (size_t)(~0) / 4; + if (getline (&line, &siz, in) == -1) +- return 1; ++ return 3; + } + return 0; + } +@@ -65,13 +65,13 @@ AC_DEFUN([gl_FUNC_GETLINE], + [ + #include + #ifdef __GNU_LIBRARY__ +- #if (__GLIBC__ >= 2) ++ #if (__GLIBC__ >= 2) && !defined __UCLIBC__ + Lucky GNU user + #endif + #endif + ], +- [am_cv_func_working_getline=yes], +- [am_cv_func_working_getline=no])] ++ [am_cv_func_working_getline="guessing yes"], ++ [am_cv_func_working_getline="guessing no"])] + )]) + fi + +@@ -79,19 +79,18 @@ AC_DEFUN([gl_FUNC_GETLINE], + HAVE_DECL_GETLINE=0 + fi + +- if test $am_cv_func_working_getline = no; then +- dnl Set REPLACE_GETLINE always: Even if we have not found the broken +- dnl getline function among $LIBS, it may exist in libinet and the +- dnl executable may be linked with -linet. +- REPLACE_GETLINE=1 +- AC_LIBOBJ([getline]) +- +- gl_PREREQ_GETLINE +- fi ++ case "$am_cv_func_working_getline" in ++ *no) ++ dnl Set REPLACE_GETLINE always: Even if we have not found the broken ++ dnl getline function among $LIBS, it may exist in libinet and the ++ dnl executable may be linked with -linet. ++ REPLACE_GETLINE=1 ++ ;; ++ esac + ]) + + # Prerequisites of lib/getline.c. + AC_DEFUN([gl_PREREQ_GETLINE], + [ +- gl_FUNC_GETDELIM ++ : + ]) +diff --git a/m4/getopt.m4 b/m4/getopt.m4 +index d05e9d9..50f4509 100644 +--- a/m4/getopt.m4 ++++ b/m4/getopt.m4 +@@ -1,5 +1,5 @@ +-# getopt.m4 serial 31 +-dnl Copyright (C) 2002-2006, 2008-2010 Free Software Foundation, Inc. ++# getopt.m4 serial 44 ++dnl Copyright (C) 2002-2006, 2008-2013 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. +@@ -9,10 +9,22 @@ AC_DEFUN([gl_FUNC_GETOPT_POSIX], + [ + m4_divert_text([DEFAULTS], [gl_getopt_required=POSIX]) + AC_REQUIRE([gl_UNISTD_H_DEFAULTS]) +- gl_GETOPT_IFELSE([ +- gl_REPLACE_GETOPT +- ], +- []) ++ AC_REQUIRE([gl_GETOPT_CHECK_HEADERS]) ++ dnl Other modules can request the gnulib implementation of the getopt ++ dnl functions unconditionally, by defining gl_REPLACE_GETOPT_ALWAYS. ++ dnl argp.m4 does this. ++ m4_ifdef([gl_REPLACE_GETOPT_ALWAYS], [ ++ REPLACE_GETOPT=1 ++ ], [ ++ REPLACE_GETOPT=0 ++ if test -n "$gl_replace_getopt"; then ++ REPLACE_GETOPT=1 ++ fi ++ ]) ++ if test $REPLACE_GETOPT = 1; then ++ dnl Arrange for getopt.h to be created. ++ gl_GETOPT_SUBSTITUTE_HEADER ++ fi + ]) + + # Request a POSIX compliant getopt function with GNU extensions (such as +@@ -25,27 +37,6 @@ AC_DEFUN([gl_FUNC_GETOPT_GNU], + AC_REQUIRE([gl_FUNC_GETOPT_POSIX]) + ]) + +-# Request the gnulib implementation of the getopt functions unconditionally. +-# argp.m4 uses this. +-AC_DEFUN([gl_REPLACE_GETOPT], +-[ +- dnl Arrange for getopt.h to be created. +- gl_GETOPT_SUBSTITUTE_HEADER +- dnl Arrange for unistd.h to include getopt.h. +- GNULIB_UNISTD_H_GETOPT=1 +- dnl Arrange to compile the getopt implementation. +- AC_LIBOBJ([getopt]) +- AC_LIBOBJ([getopt1]) +- gl_PREREQ_GETOPT +-]) +- +-# emacs' configure.in uses this. +-AC_DEFUN([gl_GETOPT_IFELSE], +-[ +- AC_REQUIRE([gl_GETOPT_CHECK_HEADERS]) +- AS_IF([test -n "$gl_replace_getopt"], [$1], [$2]) +-]) +- + # Determine whether to replace the entire getopt facility. + AC_DEFUN([gl_GETOPT_CHECK_HEADERS], + [ +@@ -56,7 +47,6 @@ AC_DEFUN([gl_GETOPT_CHECK_HEADERS], + AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) + + gl_CHECK_NEXT_HEADERS([getopt.h]) +- AC_CHECK_HEADERS_ONCE([getopt.h]) + if test $ac_cv_header_getopt_h = yes; then + HAVE_GETOPT_H=1 + else +@@ -76,25 +66,6 @@ AC_DEFUN([gl_GETOPT_CHECK_HEADERS], + AC_CHECK_FUNCS([getopt_long_only], [], [gl_replace_getopt=yes]) + fi + +- dnl BSD getopt_long uses an incompatible method to reset option processing. +- dnl Existence of the variable, in and of itself, is not a reason to replace +- dnl getopt, but knowledge of the variable is needed to determine how to +- dnl reset and whether a reset reparses the environment. +- dnl Solaris supports neither optreset nor optind=0, but keeps no state that +- dnl needs a reset beyond setting optind=1; detect Solaris by getopt_clip. +- if test -z "$gl_replace_getopt"; then +- AC_CHECK_DECLS([optreset], [], +- [AC_CHECK_DECLS([getopt_clip], [], [], +- [[#include ]]) +- ], +- [[#include ]]) +- fi +- +- dnl mingw's getopt (in libmingwex.a) does weird things when the options +- dnl strings starts with '+' and it's not the first call. Some internal state +- dnl is left over from earlier calls, and neither setting optind = 0 nor +- dnl setting optreset = 1 get rid of this internal state. +- dnl POSIX is silent on optind vs. optreset, so we allow either behavior. + dnl POSIX 2008 does not specify leading '+' behavior, but see + dnl http://austingroupbugs.net/view.php?id=191 for a recommendation on + dnl the next version of POSIX. For now, we only guarantee leading '+' +@@ -103,105 +74,124 @@ AC_DEFUN([gl_GETOPT_CHECK_HEADERS], + AC_CACHE_CHECK([whether getopt is POSIX compatible], + [gl_cv_func_getopt_posix], + [ +- dnl This test fails on mingw and succeeds on many other platforms. +- AC_RUN_IFELSE([AC_LANG_SOURCE([[ ++ dnl Merging these three different test programs into a single one ++ dnl would require a reset mechanism. On BSD systems, it can be done ++ dnl through 'optreset'; on some others (glibc), it can be done by ++ dnl setting 'optind' to 0; on others again (HP-UX, IRIX, OSF/1, ++ dnl Solaris 9, musl libc), there is no such mechanism. ++ if test $cross_compiling = no; then ++ dnl Sanity check. Succeeds everywhere (except on MSVC, ++ dnl which lacks and getopt() entirely). ++ AC_RUN_IFELSE( ++ [AC_LANG_SOURCE([[ + #include + #include + #include + +-#if !HAVE_DECL_OPTRESET && !HAVE_DECL_GETOPT_CLIP +-# define OPTIND_MIN 0 +-#else +-# define OPTIND_MIN 1 +-#endif +- + int + main () + { +- { +- int argc = 0; +- char *argv[10]; +- int c; +- +- argv[argc++] = "program"; +- argv[argc++] = "-a"; +- argv[argc++] = "foo"; +- argv[argc++] = "bar"; +- argv[argc] = NULL; +- optind = OPTIND_MIN; +- opterr = 0; ++ static char program[] = "program"; ++ static char a[] = "-a"; ++ static char foo[] = "foo"; ++ static char bar[] = "bar"; ++ char *argv[] = { program, a, foo, bar, NULL }; ++ int c; + +- c = getopt (argc, argv, "ab"); +- if (!(c == 'a')) +- return 1; +- c = getopt (argc, argv, "ab"); +- if (!(c == -1)) +- return 2; +- if (!(optind == 2)) +- return 3; +- } +- /* Some internal state exists at this point. */ +- { +- int argc = 0; +- char *argv[10]; +- int c; ++ c = getopt (4, argv, "ab"); ++ if (!(c == 'a')) ++ return 1; ++ c = getopt (4, argv, "ab"); ++ if (!(c == -1)) ++ return 2; ++ if (!(optind == 2)) ++ return 3; ++ return 0; ++} ++]])], ++ [gl_cv_func_getopt_posix=maybe], ++ [gl_cv_func_getopt_posix=no]) ++ if test $gl_cv_func_getopt_posix = maybe; then ++ dnl Sanity check with '+'. Succeeds everywhere (except on MSVC, ++ dnl which lacks and getopt() entirely). ++ AC_RUN_IFELSE( ++ [AC_LANG_SOURCE([[ ++#include ++#include ++#include + +- argv[argc++] = "program"; +- argv[argc++] = "donald"; +- argv[argc++] = "-p"; +- argv[argc++] = "billy"; +- argv[argc++] = "duck"; +- argv[argc++] = "-a"; +- argv[argc++] = "bar"; +- argv[argc] = NULL; +- optind = OPTIND_MIN; +- opterr = 0; ++int ++main () ++{ ++ static char program[] = "program"; ++ static char donald[] = "donald"; ++ static char p[] = "-p"; ++ static char billy[] = "billy"; ++ static char duck[] = "duck"; ++ static char a[] = "-a"; ++ static char bar[] = "bar"; ++ char *argv[] = { program, donald, p, billy, duck, a, bar, NULL }; ++ int c; + +- c = getopt (argc, argv, "+abp:q:"); +- if (!(c == -1)) +- return 4; +- if (!(strcmp (argv[0], "program") == 0)) +- return 5; +- if (!(strcmp (argv[1], "donald") == 0)) +- return 6; +- if (!(strcmp (argv[2], "-p") == 0)) +- return 7; +- if (!(strcmp (argv[3], "billy") == 0)) +- return 8; +- if (!(strcmp (argv[4], "duck") == 0)) +- return 9; +- if (!(strcmp (argv[5], "-a") == 0)) +- return 10; +- if (!(strcmp (argv[6], "bar") == 0)) +- return 11; +- if (!(optind == 1)) +- return 12; +- } +- /* Detect MacOS 10.5, AIX 7.1 bug. */ +- { +- char *argv[3] = { "program", "-ab", NULL }; +- optind = OPTIND_MIN; +- opterr = 0; +- if (getopt (2, argv, "ab:") != 'a') +- return 13; +- if (getopt (2, argv, "ab:") != '?') +- return 14; +- if (optopt != 'b') +- return 15; +- if (optind != 2) +- return 16; +- } ++ c = getopt (7, argv, "+abp:q:"); ++ if (!(c == -1)) ++ return 4; ++ if (!(strcmp (argv[0], "program") == 0)) ++ return 5; ++ if (!(strcmp (argv[1], "donald") == 0)) ++ return 6; ++ if (!(strcmp (argv[2], "-p") == 0)) ++ return 7; ++ if (!(strcmp (argv[3], "billy") == 0)) ++ return 8; ++ if (!(strcmp (argv[4], "duck") == 0)) ++ return 9; ++ if (!(strcmp (argv[5], "-a") == 0)) ++ return 10; ++ if (!(strcmp (argv[6], "bar") == 0)) ++ return 11; ++ if (!(optind == 1)) ++ return 12; ++ return 0; ++} ++]])], ++ [gl_cv_func_getopt_posix=maybe], ++ [gl_cv_func_getopt_posix=no]) ++ fi ++ if test $gl_cv_func_getopt_posix = maybe; then ++ dnl Detect Mac OS X 10.5, AIX 7.1, mingw bug. ++ AC_RUN_IFELSE( ++ [AC_LANG_SOURCE([[ ++#include ++#include ++#include + ++int ++main () ++{ ++ static char program[] = "program"; ++ static char ab[] = "-ab"; ++ char *argv[3] = { program, ab, NULL }; ++ if (getopt (2, argv, "ab:") != 'a') ++ return 13; ++ if (getopt (2, argv, "ab:") != '?') ++ return 14; ++ if (optopt != 'b') ++ return 15; ++ if (optind != 2) ++ return 16; + return 0; + } + ]])], +- [gl_cv_func_getopt_posix=yes], [gl_cv_func_getopt_posix=no], +- [case "$host_os" in +- mingw*) gl_cv_func_getopt_posix="guessing no";; +- darwin* | aix*) gl_cv_func_getopt_posix="guessing no";; +- *) gl_cv_func_getopt_posix="guessing yes";; +- esac +- ]) ++ [gl_cv_func_getopt_posix=yes], ++ [gl_cv_func_getopt_posix=no]) ++ fi ++ else ++ case "$host_os" in ++ darwin* | aix* | mingw*) gl_cv_func_getopt_posix="guessing no";; ++ *) gl_cv_func_getopt_posix="guessing yes";; ++ esac ++ fi + ]) + case "$gl_cv_func_getopt_posix" in + *no) gl_replace_getopt=yes ;; +@@ -230,63 +220,83 @@ dnl is ambiguous with environment values that contain newlines. + [AC_LANG_PROGRAM([[#include + #include + #include ++ ]GL_NOCRASH[ + ]], [[ ++ int result = 0; ++ ++ nocrash_init(); ++ + /* This code succeeds on glibc 2.8, OpenBSD 4.0, Cygwin, mingw, +- and fails on MacOS X 10.5, AIX 5.2, HP-UX 11, IRIX 6.5, ++ and fails on Mac OS X 10.5, AIX 5.2, HP-UX 11, IRIX 6.5, + OSF/1 5.1, Solaris 10. */ + { +- char *myargv[3]; +- myargv[0] = "conftest"; +- myargv[1] = "-+"; +- myargv[2] = 0; ++ static char conftest[] = "conftest"; ++ static char plus[] = "-+"; ++ char *argv[3] = { conftest, plus, NULL }; + opterr = 0; +- if (getopt (2, myargv, "+a") != '?') +- return 1; ++ if (getopt (2, argv, "+a") != '?') ++ result |= 1; + } + /* This code succeeds on glibc 2.8, mingw, +- and fails on MacOS X 10.5, OpenBSD 4.0, AIX 5.2, HP-UX 11, ++ and fails on Mac OS X 10.5, OpenBSD 4.0, AIX 5.2, HP-UX 11, + IRIX 6.5, OSF/1 5.1, Solaris 10, Cygwin 1.5.x. */ + { +- char *argv[] = { "program", "-p", "foo", "bar", NULL }; ++ static char program[] = "program"; ++ static char p[] = "-p"; ++ static char foo[] = "foo"; ++ static char bar[] = "bar"; ++ char *argv[] = { program, p, foo, bar, NULL }; + + optind = 1; + if (getopt (4, argv, "p::") != 'p') +- return 2; +- if (optarg != NULL) +- return 3; +- if (getopt (4, argv, "p::") != -1) +- return 4; +- if (optind != 2) +- return 5; ++ result |= 2; ++ else if (optarg != NULL) ++ result |= 4; ++ else if (getopt (4, argv, "p::") != -1) ++ result |= 6; ++ else if (optind != 2) ++ result |= 8; + } + /* This code succeeds on glibc 2.8 and fails on Cygwin 1.7.0. */ + { +- char *argv[] = { "program", "foo", "-p", NULL }; ++ static char program[] = "program"; ++ static char foo[] = "foo"; ++ static char p[] = "-p"; ++ char *argv[] = { program, foo, p, NULL }; + optind = 0; + if (getopt (3, argv, "-p") != 1) +- return 6; +- if (getopt (3, argv, "-p") != 'p') +- return 7; ++ result |= 16; ++ else if (getopt (3, argv, "-p") != 'p') ++ result |= 16; + } + /* This code fails on glibc 2.11. */ + { +- char *argv[] = { "program", "-b", "-a", NULL }; ++ static char program[] = "program"; ++ static char b[] = "-b"; ++ static char a[] = "-a"; ++ char *argv[] = { program, b, a, NULL }; + optind = opterr = 0; + if (getopt (3, argv, "+:a:b") != 'b') +- return 8; +- if (getopt (3, argv, "+:a:b") != ':') +- return 9; ++ result |= 32; ++ else if (getopt (3, argv, "+:a:b") != ':') ++ result |= 32; ++ } ++ /* This code dumps core on glibc 2.14. */ ++ { ++ static char program[] = "program"; ++ static char w[] = "-W"; ++ static char dummy[] = "dummy"; ++ char *argv[] = { program, w, dummy, NULL }; ++ optind = opterr = 1; ++ if (getopt (3, argv, "W;") != 'W') ++ result |= 64; + } +- return 0; ++ return result; + ]])], + [gl_cv_func_getopt_gnu=yes], + [gl_cv_func_getopt_gnu=no], +- [dnl Cross compiling. Guess based on host and declarations. +- case $host_os:$ac_cv_have_decl_optreset in +- *-gnu*:* | mingw*:*) gl_cv_func_getopt_gnu=no;; +- *:yes) gl_cv_func_getopt_gnu=no;; +- *) gl_cv_func_getopt_gnu=yes;; +- esac ++ [dnl Cross compiling. Assume the worst, even on glibc platforms. ++ gl_cv_func_getopt_gnu="guessing no" + ]) + case $gl_had_POSIXLY_CORRECT in + exported) ;; +@@ -294,13 +304,54 @@ dnl is ambiguous with environment values that contain newlines. + *) AS_UNSET([POSIXLY_CORRECT]) ;; + esac + ]) +- if test "$gl_cv_func_getopt_gnu" = "no"; then ++ if test "$gl_cv_func_getopt_gnu" != yes; then + gl_replace_getopt=yes ++ else ++ AC_CACHE_CHECK([for working GNU getopt_long function], ++ [gl_cv_func_getopt_long_gnu], ++ [AC_RUN_IFELSE( ++ [AC_LANG_PROGRAM( ++ [[#include ++ #include ++ #include ++ ]], ++ [[static const struct option long_options[] = ++ { ++ { "xtremely-",no_argument, NULL, 1003 }, ++ { "xtra", no_argument, NULL, 1001 }, ++ { "xtreme", no_argument, NULL, 1002 }, ++ { "xtremely", no_argument, NULL, 1003 }, ++ { NULL, 0, NULL, 0 } ++ }; ++ /* This code fails on OpenBSD 5.0. */ ++ { ++ static char program[] = "program"; ++ static char xtremel[] = "--xtremel"; ++ char *argv[] = { program, xtremel, NULL }; ++ int option_index; ++ optind = 1; opterr = 0; ++ if (getopt_long (2, argv, "", long_options, &option_index) != 1003) ++ return 1; ++ } ++ return 0; ++ ]])], ++ [gl_cv_func_getopt_long_gnu=yes], ++ [gl_cv_func_getopt_long_gnu=no], ++ [dnl Cross compiling. Guess no on OpenBSD, yes otherwise. ++ case "$host_os" in ++ openbsd*) gl_cv_func_getopt_long_gnu="guessing no";; ++ *) gl_cv_func_getopt_long_gnu="guessing yes";; ++ esac ++ ]) ++ ]) ++ case "$gl_cv_func_getopt_long_gnu" in ++ *yes) ;; ++ *) gl_replace_getopt=yes ;; ++ esac + fi + fi + ]) + +-# emacs' configure.in uses this. + AC_DEFUN([gl_GETOPT_SUBSTITUTE_HEADER], + [ + GETOPT_H=getopt.h +@@ -311,7 +362,6 @@ AC_DEFUN([gl_GETOPT_SUBSTITUTE_HEADER], + ]) + + # Prerequisites of lib/getopt*. +-# emacs' configure.in uses this. + AC_DEFUN([gl_PREREQ_GETOPT], + [ + AC_CHECK_DECLS_ONCE([getenv]) +diff --git a/m4/gettext.m4 b/m4/gettext.m4 +index 979c52c..8d1f066 100644 +--- a/m4/gettext.m4 ++++ b/m4/gettext.m4 +@@ -1,5 +1,5 @@ +-# gettext.m4 serial 64 (gettext-0.18.2) +-dnl Copyright (C) 1995-2010 Free Software Foundation, Inc. ++# gettext.m4 serial 66 (gettext-0.18.2) ++dnl Copyright (C) 1995-2013 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. +@@ -35,7 +35,7 @@ dnl will be ignored. If NEEDSYMBOL is specified and is + dnl 'need-formatstring-macros', then GNU gettext implementations that don't + dnl support the ISO C 99 formatstring macros will be ignored. + dnl INTLDIR is used to find the intl libraries. If empty, +-dnl the value `$(top_builddir)/intl/' is used. ++dnl the value '$(top_builddir)/intl/' is used. + dnl + dnl The result of the configuration is one of three cases: + dnl 1) GNU gettext, as included in the intl subdirectory, will be compiled +@@ -97,7 +97,7 @@ AC_DEFUN([AM_GNU_GETTEXT], + AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY]) + ]) + +- dnl Sometimes, on MacOS X, libintl requires linking with CoreFoundation. ++ dnl Sometimes, on Mac OS X, libintl requires linking with CoreFoundation. + gt_INTL_MACOSX + + dnl Set USE_NLS. +diff --git a/m4/glibc2.m4 b/m4/glibc2.m4 +index f148c12..0e50682 100644 +--- a/m4/glibc2.m4 ++++ b/m4/glibc2.m4 +@@ -1,5 +1,6 @@ +-# glibc2.m4 serial 2 +-dnl Copyright (C) 2000-2002, 2004, 2008-2010 Free Software Foundation, Inc. ++# glibc2.m4 serial 3 ++dnl Copyright (C) 2000-2002, 2004, 2008, 2010-2013 Free Software Foundation, ++dnl Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. +@@ -15,7 +16,7 @@ AC_DEFUN([gt_GLIBC2], + [ + #include + #ifdef __GNU_LIBRARY__ +- #if (__GLIBC__ >= 2) ++ #if (__GLIBC__ >= 2) && !defined __UCLIBC__ + Lucky GNU user + #endif + #endif +diff --git a/m4/glibc21.m4 b/m4/glibc21.m4 +index 68ada9d..613fb2a 100644 +--- a/m4/glibc21.m4 ++++ b/m4/glibc21.m4 +@@ -1,17 +1,18 @@ +-# glibc21.m4 serial 4 +-dnl Copyright (C) 2000-2002, 2004, 2008-2010 Free Software Foundation, Inc. ++# glibc21.m4 serial 5 ++dnl Copyright (C) 2000-2002, 2004, 2008, 2010-2013 Free Software Foundation, ++dnl Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. + +-# Test for the GNU C Library, version 2.1 or newer. ++# Test for the GNU C Library, version 2.1 or newer, or uClibc. + # From Bruno Haible. + + AC_DEFUN([gl_GLIBC21], + [ +- AC_CACHE_CHECK([whether we are using the GNU C Library 2.1 or newer], ++ AC_CACHE_CHECK([whether we are using the GNU C Library >= 2.1 or uClibc], + [ac_cv_gnu_library_2_1], +- [AC_EGREP_CPP([Lucky GNU user], ++ [AC_EGREP_CPP([Lucky], + [ + #include + #ifdef __GNU_LIBRARY__ +@@ -19,6 +20,9 @@ AC_DEFUN([gl_GLIBC21], + Lucky GNU user + #endif + #endif ++#ifdef __UCLIBC__ ++ Lucky user ++#endif + ], + [ac_cv_gnu_library_2_1=yes], + [ac_cv_gnu_library_2_1=no]) +diff --git a/m4/gnulib-cache.m4 b/m4/gnulib-cache.m4 +index 3c094bc..4089184 100644 +--- a/m4/gnulib-cache.m4 ++++ b/m4/gnulib-cache.m4 +@@ -1,9 +1,21 @@ +-# Copyright (C) 2002-2010 Free Software Foundation, Inc. ++# Copyright (C) 2002-2013 Free Software Foundation, Inc. + # +-# This file is free software, distributed under the terms of the GNU +-# General Public License. As a special exception to the GNU General +-# Public License, this file may be distributed as part of a program +-# that contains a configuration script generated by Autoconf, under ++# This file 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 file 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 file. If not, see . ++# ++# As a special exception to the GNU General Public License, ++# this file may be distributed as part of a program that ++# contains a configuration script generated by Autoconf, under + # the same distribution terms as the rest of that program. + # + # Generated by gnulib-tool. +@@ -15,7 +27,7 @@ + + + # Specification in the form of a command-line invocation: +-# gnulib-tool --import --dir=. --lib=libgnu --source-base=grub-core/gnulib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --no-libtool --macro-prefix=gl --no-vc-files argp error fnmatch getdelim getline gettext progname regex ++# gnulib-tool --import --dir=. --lib=libgnu --source-base=grub-core/gnulib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --no-conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files argp error fnmatch getdelim getline gettext progname regex + + # Specification in the form of a few gnulib-tool.m4 macro invocations: + gl_LOCAL_DIR([]) +@@ -39,4 +51,5 @@ gl_LIB([libgnu]) + gl_MAKEFILE_NAME([]) + gl_MACRO_PREFIX([gl]) + gl_PO_DOMAIN([]) ++gl_WITNESS_C_MACRO([]) + gl_VC_FILES([false]) +diff --git a/m4/gnulib-common.m4 b/m4/gnulib-common.m4 +index 4c7ac30..0ae5a9e 100644 +--- a/m4/gnulib-common.m4 ++++ b/m4/gnulib-common.m4 +@@ -1,5 +1,5 @@ +-# gnulib-common.m4 serial 20 +-dnl Copyright (C) 2007-2010 Free Software Foundation, Inc. ++# gnulib-common.m4 serial 33 ++dnl Copyright (C) 2007-2013 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. +@@ -12,11 +12,25 @@ AC_DEFUN([gl_COMMON], [ + AC_REQUIRE([gl_COMMON_BODY]) + ]) + AC_DEFUN([gl_COMMON_BODY], [ ++ AH_VERBATIM([_Noreturn], ++[/* The _Noreturn keyword of C11. */ ++#if ! (defined _Noreturn \ ++ || (defined __STDC_VERSION__ && 201112 <= __STDC_VERSION__)) ++# if (3 <= __GNUC__ || (__GNUC__ == 2 && 8 <= __GNUC_MINOR__) \ ++ || 0x5110 <= __SUNPRO_C) ++# define _Noreturn __attribute__ ((__noreturn__)) ++# elif defined _MSC_VER && 1200 <= _MSC_VER ++# define _Noreturn __declspec (noreturn) ++# else ++# define _Noreturn ++# endif ++#endif ++]) + AH_VERBATIM([isoc99_inline], + [/* Work around a bug in Apple GCC 4.0.1 build 5465: In C99 mode, it supports + the ISO C 99 semantics of 'extern inline' (unlike the GNU C semantics of + earlier versions), but does not display it by setting __GNUC_STDC_INLINE__. +- __APPLE__ && __MACH__ test for MacOS X. ++ __APPLE__ && __MACH__ test for Mac OS X. + __APPLE_CC__ tests for the Apple compiler and its version. + __STDC_VERSION__ tests for the C99 mode. */ + #if defined __APPLE__ && defined __MACH__ && __APPLE_CC__ >= 5465 && !defined __cplusplus && __STDC_VERSION__ >= 199901L && !defined __GNUC_STDC_INLINE__ +@@ -34,6 +48,20 @@ AC_DEFUN([gl_COMMON_BODY], [ + /* The name _UNUSED_PARAMETER_ is an earlier spelling, although the name + is a misnomer outside of parameter lists. */ + #define _UNUSED_PARAMETER_ _GL_UNUSED ++ ++/* The __pure__ attribute was added in gcc 2.96. */ ++#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) ++# define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__)) ++#else ++# define _GL_ATTRIBUTE_PURE /* empty */ ++#endif ++ ++/* The __const__ attribute was added in gcc 2.95. */ ++#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) ++# define _GL_ATTRIBUTE_CONST __attribute__ ((__const__)) ++#else ++# define _GL_ATTRIBUTE_CONST /* empty */ ++#endif + ]) + dnl Preparation for running test programs: + dnl Tell glibc to write diagnostics from -D_FORTIFY_SOURCE=2 to stderr, not +@@ -47,16 +75,49 @@ AC_DEFUN([gl_COMMON_BODY], [ + # expands to a C preprocessor expression that evaluates to 1 or 0, depending + # whether a gnulib module that has been requested shall be considered present + # or not. +-AC_DEFUN([gl_MODULE_INDICATOR_CONDITION], [1]) ++m4_define([gl_MODULE_INDICATOR_CONDITION], [1]) + + # gl_MODULE_INDICATOR_SET_VARIABLE([modulename]) + # sets the shell variable that indicates the presence of the given module to + # a C preprocessor expression that will evaluate to 1. + AC_DEFUN([gl_MODULE_INDICATOR_SET_VARIABLE], + [ +- GNULIB_[]m4_translit([[$1]], +- [abcdefghijklmnopqrstuvwxyz./-], +- [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])=gl_MODULE_INDICATOR_CONDITION ++ gl_MODULE_INDICATOR_SET_VARIABLE_AUX( ++ [GNULIB_[]m4_translit([[$1]], ++ [abcdefghijklmnopqrstuvwxyz./-], ++ [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])], ++ [gl_MODULE_INDICATOR_CONDITION]) ++]) ++ ++# gl_MODULE_INDICATOR_SET_VARIABLE_AUX([variable]) ++# modifies the shell variable to include the gl_MODULE_INDICATOR_CONDITION. ++# The shell variable's value is a C preprocessor expression that evaluates ++# to 0 or 1. ++AC_DEFUN([gl_MODULE_INDICATOR_SET_VARIABLE_AUX], ++[ ++ m4_if(m4_defn([gl_MODULE_INDICATOR_CONDITION]), [1], ++ [ ++ dnl Simplify the expression VALUE || 1 to 1. ++ $1=1 ++ ], ++ [gl_MODULE_INDICATOR_SET_VARIABLE_AUX_OR([$1], ++ [gl_MODULE_INDICATOR_CONDITION])]) ++]) ++ ++# gl_MODULE_INDICATOR_SET_VARIABLE_AUX_OR([variable], [condition]) ++# modifies the shell variable to include the given condition. The shell ++# variable's value is a C preprocessor expression that evaluates to 0 or 1. ++AC_DEFUN([gl_MODULE_INDICATOR_SET_VARIABLE_AUX_OR], ++[ ++ dnl Simplify the expression 1 || CONDITION to 1. ++ if test "$[]$1" != 1; then ++ dnl Simplify the expression 0 || CONDITION to CONDITION. ++ if test "$[]$1" = 0; then ++ $1=$2 ++ else ++ $1="($[]$1 || $2)" ++ fi ++ fi + ]) + + # gl_MODULE_INDICATOR([modulename]) +@@ -102,6 +163,40 @@ AC_DEFUN([gl_MODULE_INDICATOR_FOR_TESTS], + [Define to 1 when the gnulib module $1 should be tested.]) + ]) + ++# gl_ASSERT_NO_GNULIB_POSIXCHECK ++# asserts that there will never be a need to #define GNULIB_POSIXCHECK. ++# and thereby enables an optimization of configure and config.h. ++# Used by Emacs. ++AC_DEFUN([gl_ASSERT_NO_GNULIB_POSIXCHECK], ++[ ++ dnl Override gl_WARN_ON_USE_PREPARE. ++ dnl But hide this definition from 'aclocal'. ++ AC_DEFUN([gl_W][ARN_ON_USE_PREPARE], []) ++]) ++ ++# gl_ASSERT_NO_GNULIB_TESTS ++# asserts that there will be no gnulib tests in the scope of the configure.ac ++# and thereby enables an optimization of config.h. ++# Used by Emacs. ++AC_DEFUN([gl_ASSERT_NO_GNULIB_TESTS], ++[ ++ dnl Override gl_MODULE_INDICATOR_FOR_TESTS. ++ AC_DEFUN([gl_MODULE_INDICATOR_FOR_TESTS], []) ++]) ++ ++# Test whether exists. ++# Set HAVE_FEATURES_H. ++AC_DEFUN([gl_FEATURES_H], ++[ ++ AC_CHECK_HEADERS_ONCE([features.h]) ++ if test $ac_cv_header_features_h = yes; then ++ HAVE_FEATURES_H=1 ++ else ++ HAVE_FEATURES_H=0 ++ fi ++ AC_SUBST([HAVE_FEATURES_H]) ++]) ++ + # m4_foreach_w + # is a backport of autoconf-2.59c's m4_foreach_w. + # Remove this macro when we can assume autoconf >= 2.60. +@@ -117,11 +212,90 @@ m4_ifndef([AS_VAR_IF], + [m4_define([AS_VAR_IF], + [AS_IF([test x"AS_VAR_GET([$1])" = x""$2], [$3], [$4])])]) + ++# gl_PROG_CC_C99 ++# Modifies the value of the shell variable CC in an attempt to make $CC ++# understand ISO C99 source code. ++# This is like AC_PROG_CC_C99, except that ++# - AC_PROG_CC_C99 did not exist in Autoconf versions < 2.60, ++# - AC_PROG_CC_C99 does not mix well with AC_PROG_CC_STDC ++# , ++# but many more packages use AC_PROG_CC_STDC than AC_PROG_CC_C99 ++# . ++# Remaining problems: ++# - When AC_PROG_CC_STDC is invoked twice, it adds the C99 enabling options ++# to CC twice ++# . ++# - AC_PROG_CC_STDC is likely to change now that C11 is an ISO standard. ++AC_DEFUN([gl_PROG_CC_C99], ++[ ++ dnl Change that version number to the minimum Autoconf version that supports ++ dnl mixing AC_PROG_CC_C99 calls with AC_PROG_CC_STDC calls. ++ m4_version_prereq([9.0], ++ [AC_REQUIRE([AC_PROG_CC_C99])], ++ [AC_REQUIRE([AC_PROG_CC_STDC])]) ++]) ++ ++# gl_PROG_AR_RANLIB ++# Determines the values for AR, ARFLAGS, RANLIB that fit with the compiler. ++# The user can set the variables AR, ARFLAGS, RANLIB if he wants to override ++# the values. ++AC_DEFUN([gl_PROG_AR_RANLIB], ++[ ++ dnl Minix 3 comes with two toolchains: The Amsterdam Compiler Kit compiler ++ dnl as "cc", and GCC as "gcc". They have different object file formats and ++ dnl library formats. In particular, the GNU binutils programs ar, ranlib ++ dnl produce libraries that work only with gcc, not with cc. ++ AC_REQUIRE([AC_PROG_CC]) ++ AC_CACHE_CHECK([for Minix Amsterdam compiler], [gl_cv_c_amsterdam_compiler], ++ [ ++ AC_EGREP_CPP([Amsterdam], ++ [ ++#ifdef __ACK__ ++Amsterdam ++#endif ++ ], ++ [gl_cv_c_amsterdam_compiler=yes], ++ [gl_cv_c_amsterdam_compiler=no]) ++ ]) ++ if test -z "$AR"; then ++ if test $gl_cv_c_amsterdam_compiler = yes; then ++ AR='cc -c.a' ++ if test -z "$ARFLAGS"; then ++ ARFLAGS='-o' ++ fi ++ else ++ dnl Use the Automake-documented default values for AR and ARFLAGS, ++ dnl but prefer ${host}-ar over ar (useful for cross-compiling). ++ AC_CHECK_TOOL([AR], [ar], [ar]) ++ if test -z "$ARFLAGS"; then ++ ARFLAGS='cru' ++ fi ++ fi ++ else ++ if test -z "$ARFLAGS"; then ++ ARFLAGS='cru' ++ fi ++ fi ++ AC_SUBST([AR]) ++ AC_SUBST([ARFLAGS]) ++ if test -z "$RANLIB"; then ++ if test $gl_cv_c_amsterdam_compiler = yes; then ++ RANLIB=':' ++ else ++ dnl Use the ranlib program if it is available. ++ AC_PROG_RANLIB ++ fi ++ fi ++ AC_SUBST([RANLIB]) ++]) ++ + # AC_PROG_MKDIR_P + # is a backport of autoconf-2.60's AC_PROG_MKDIR_P, with a fix + # for interoperability with automake-1.9.6 from autoconf-2.62. + # Remove this macro when we can assume autoconf >= 2.62 or + # autoconf >= 2.60 && automake >= 1.10. ++# AC_AUTOCONF_VERSION was introduced in 2.62, so use that as the witness. ++m4_ifndef([AC_AUTOCONF_VERSION],[ + m4_ifdef([AC_PROG_MKDIR_P], [ + dnl For automake-1.9.6 && autoconf < 2.62: Ensure MKDIR_P is AC_SUBSTed. + m4_define([AC_PROG_MKDIR_P], +@@ -132,13 +306,15 @@ m4_ifdef([AC_PROG_MKDIR_P], [ + [AC_REQUIRE([AM_PROG_MKDIR_P])dnl defined by automake + MKDIR_P='$(mkdir_p)' + AC_SUBST([MKDIR_P])])]) ++]) + + # AC_C_RESTRICT + # This definition overrides the AC_C_RESTRICT macro from autoconf 2.60..2.61, + # so that mixed use of GNU C and GNU C++ and mixed use of Sun C and Sun C++ + # works. + # This definition can be removed once autoconf >= 2.62 can be assumed. +-m4_if(m4_version_compare(m4_defn([m4_PACKAGE_VERSION]),[2.62]),[-1],[ ++# AC_AUTOCONF_VERSION was introduced in 2.62, so use that as the witness. ++m4_ifndef([AC_AUTOCONF_VERSION],[ + AC_DEFUN([AC_C_RESTRICT], + [AC_CACHE_CHECK([for C/C++ restrict keyword], [ac_cv_c_restrict], + [ac_cv_c_restrict=no +diff --git a/m4/gnulib-comp.m4 b/m4/gnulib-comp.m4 +index d3490c9..7a19f60 100644 +--- a/m4/gnulib-comp.m4 ++++ b/m4/gnulib-comp.m4 +@@ -1,10 +1,22 @@ + # DO NOT EDIT! GENERATED AUTOMATICALLY! +-# Copyright (C) 2002-2010 Free Software Foundation, Inc. ++# Copyright (C) 2002-2013 Free Software Foundation, Inc. + # +-# This file is free software, distributed under the terms of the GNU +-# General Public License. As a special exception to the GNU General +-# Public License, this file may be distributed as part of a program +-# that contains a configuration script generated by Autoconf, under ++# This file 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 file 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 file. If not, see . ++# ++# As a special exception to the GNU General Public License, ++# this file may be distributed as part of a program that ++# contains a configuration script generated by Autoconf, under + # the same distribution terms as the rest of that program. + # + # Generated by gnulib-tool. +@@ -25,20 +37,21 @@ AC_DEFUN([gl_EARLY], + m4_pattern_allow([^gl_ES$])dnl a valid locale name + m4_pattern_allow([^gl_LIBOBJS$])dnl a variable + m4_pattern_allow([^gl_LTLIBOBJS$])dnl a variable +- AC_REQUIRE([AC_PROG_RANLIB]) ++ AC_REQUIRE([gl_PROG_AR_RANLIB]) ++ AC_REQUIRE([AM_PROG_CC_C_O]) + # Code from module alloca: + # Code from module alloca-opt: +- # Code from module arg-nonnull: + # Code from module argp: + # Code from module btowc: +- # Code from module c++defs: + # Code from module configmake: + # Code from module dirname-lgpl: ++ # Code from module dosname: + # Code from module double-slash-root: + # Code from module errno: + # Code from module error: + # Code from module extensions: + AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) ++ # Code from module extern-inline: + # Code from module float: + # Code from module fnmatch: + # Code from module getdelim: +@@ -52,22 +65,34 @@ AC_DEFUN([gl_EARLY], + # Code from module intprops: + # Code from module langinfo: + # Code from module localcharset: ++ # Code from module locale: ++ # Code from module localeconv: + # Code from module malloc-gnu: + # Code from module malloc-posix: + # Code from module mbrtowc: + # Code from module mbsinit: + # Code from module mbsrtowcs: ++ # Code from module mbswidth: ++ # Code from module mbtowc: + # Code from module memchr: + # Code from module mempcpy: ++ # Code from module msvc-inval: ++ # Code from module msvc-nothrow: + # Code from module multiarch: + # Code from module nl_langinfo: ++ # Code from module nocrash: + # Code from module progname: + # Code from module rawmemchr: + # Code from module realloc-posix: + # Code from module regex: + # Code from module size_max: + # Code from module sleep: ++ # Code from module snippet/_Noreturn: ++ # Code from module snippet/arg-nonnull: ++ # Code from module snippet/c++defs: ++ # Code from module snippet/warn-on-use: + # Code from module ssize_t: ++ # Code from module stdalign: + # Code from module stdbool: + # Code from module stddef: + # Code from module stdint: +@@ -77,21 +102,25 @@ AC_DEFUN([gl_EARLY], + # Code from module strchrnul: + # Code from module streq: + # Code from module strerror: ++ # Code from module strerror-override: + # Code from module string: + # Code from module strings: + # Code from module strndup: + # Code from module strnlen: + # Code from module strnlen1: +- # Code from module sys_wait: ++ # Code from module sys_types: + # Code from module sysexits: + # Code from module unistd: ++ # Code from module unitypes: ++ # Code from module uniwidth/base: ++ # Code from module uniwidth/width: + # Code from module vasnprintf: + # Code from module verify: + # Code from module vsnprintf: +- # Code from module warn-on-use: + # Code from module wchar: + # Code from module wcrtomb: +- # Code from module wctype: ++ # Code from module wctype-h: ++ # Code from module wcwidth: + # Code from module xsize: + ]) + +@@ -111,158 +140,244 @@ AC_DEFUN([gl_INIT], + m4_pushdef([gl_LIBSOURCES_DIR], []) + gl_COMMON + gl_source_base='grub-core/gnulib' +- # Code from module alloca: +- # Code from module alloca-opt: + gl_FUNC_ALLOCA +- # Code from module arg-nonnull: +- # Code from module argp: + gl_ARGP + m4_ifdef([AM_XGETTEXT_OPTION], + [AM_][XGETTEXT_OPTION([--flag=argp_error:2:c-format]) + AM_][XGETTEXT_OPTION([--flag=argp_failure:4:c-format])]) +- # Code from module btowc: + gl_FUNC_BTOWC ++ if test $HAVE_BTOWC = 0 || test $REPLACE_BTOWC = 1; then ++ AC_LIBOBJ([btowc]) ++ gl_PREREQ_BTOWC ++ fi + gl_WCHAR_MODULE_INDICATOR([btowc]) +- # Code from module c++defs: +- # Code from module configmake: +- # Code from module dirname-lgpl: ++ gl_CONFIGMAKE_PREP + gl_DIRNAME_LGPL +- # Code from module double-slash-root: + gl_DOUBLE_SLASH_ROOT +- # Code from module errno: + gl_HEADER_ERRNO_H +- # Code from module error: + gl_ERROR ++ if test $ac_cv_lib_error_at_line = no; then ++ AC_LIBOBJ([error]) ++ gl_PREREQ_ERROR ++ fi + m4_ifdef([AM_XGETTEXT_OPTION], + [AM_][XGETTEXT_OPTION([--flag=error:3:c-format]) + AM_][XGETTEXT_OPTION([--flag=error_at_line:5:c-format])]) +- # Code from module extensions: +- # Code from module float: ++ AC_REQUIRE([gl_EXTERN_INLINE]) + gl_FLOAT_H +- # Code from module fnmatch: ++ if test $REPLACE_FLOAT_LDBL = 1; then ++ AC_LIBOBJ([float]) ++ fi ++ if test $REPLACE_ITOLD = 1; then ++ AC_LIBOBJ([itold]) ++ fi + gl_FUNC_FNMATCH_POSIX +- # Code from module getdelim: ++ if test -n "$FNMATCH_H"; then ++ AC_LIBOBJ([fnmatch]) ++ gl_PREREQ_FNMATCH ++ fi + gl_FUNC_GETDELIM ++ if test $HAVE_GETDELIM = 0 || test $REPLACE_GETDELIM = 1; then ++ AC_LIBOBJ([getdelim]) ++ gl_PREREQ_GETDELIM ++ fi + gl_STDIO_MODULE_INDICATOR([getdelim]) +- # Code from module getline: + gl_FUNC_GETLINE ++ if test $REPLACE_GETLINE = 1; then ++ AC_LIBOBJ([getline]) ++ gl_PREREQ_GETLINE ++ fi + gl_STDIO_MODULE_INDICATOR([getline]) +- # Code from module getopt-gnu: + gl_FUNC_GETOPT_GNU ++ if test $REPLACE_GETOPT = 1; then ++ AC_LIBOBJ([getopt]) ++ AC_LIBOBJ([getopt1]) ++ gl_PREREQ_GETOPT ++ dnl Arrange for unistd.h to include getopt.h. ++ GNULIB_GL_UNISTD_H_GETOPT=1 ++ fi ++ AC_SUBST([GNULIB_GL_UNISTD_H_GETOPT]) + gl_MODULE_INDICATOR_FOR_TESTS([getopt-gnu]) +- # Code from module getopt-posix: + gl_FUNC_GETOPT_POSIX +- # Code from module gettext: ++ if test $REPLACE_GETOPT = 1; then ++ AC_LIBOBJ([getopt]) ++ AC_LIBOBJ([getopt1]) ++ gl_PREREQ_GETOPT ++ dnl Arrange for unistd.h to include getopt.h. ++ GNULIB_GL_UNISTD_H_GETOPT=1 ++ fi ++ AC_SUBST([GNULIB_GL_UNISTD_H_GETOPT]) + dnl you must add AM_GNU_GETTEXT([external]) or similar to configure.ac. + AM_GNU_GETTEXT_VERSION([0.18.1]) +- # Code from module gettext-h: + AC_SUBST([LIBINTL]) + AC_SUBST([LTLIBINTL]) +- # Code from module havelib: +- # Code from module include_next: +- # Code from module intprops: +- # Code from module langinfo: + gl_LANGINFO_H +- # Code from module localcharset: + gl_LOCALCHARSET +- LOCALCHARSET_TESTS_ENVIRONMENT="CHARSETALIASDIR=\"\$(top_builddir)/$gl_source_base\"" ++ LOCALCHARSET_TESTS_ENVIRONMENT="CHARSETALIASDIR=\"\$(abs_top_builddir)/$gl_source_base\"" + AC_SUBST([LOCALCHARSET_TESTS_ENVIRONMENT]) +- # Code from module malloc-gnu: ++ gl_LOCALE_H ++ gl_FUNC_LOCALECONV ++ if test $REPLACE_LOCALECONV = 1; then ++ AC_LIBOBJ([localeconv]) ++ gl_PREREQ_LOCALECONV ++ fi ++ gl_LOCALE_MODULE_INDICATOR([localeconv]) + gl_FUNC_MALLOC_GNU ++ if test $REPLACE_MALLOC = 1; then ++ AC_LIBOBJ([malloc]) ++ fi + gl_MODULE_INDICATOR([malloc-gnu]) +- # Code from module malloc-posix: + gl_FUNC_MALLOC_POSIX ++ if test $REPLACE_MALLOC = 1; then ++ AC_LIBOBJ([malloc]) ++ fi + gl_STDLIB_MODULE_INDICATOR([malloc-posix]) +- # Code from module mbrtowc: + gl_FUNC_MBRTOWC ++ if test $HAVE_MBRTOWC = 0 || test $REPLACE_MBRTOWC = 1; then ++ AC_LIBOBJ([mbrtowc]) ++ gl_PREREQ_MBRTOWC ++ fi + gl_WCHAR_MODULE_INDICATOR([mbrtowc]) +- # Code from module mbsinit: + gl_FUNC_MBSINIT ++ if test $HAVE_MBSINIT = 0 || test $REPLACE_MBSINIT = 1; then ++ AC_LIBOBJ([mbsinit]) ++ gl_PREREQ_MBSINIT ++ fi + gl_WCHAR_MODULE_INDICATOR([mbsinit]) +- # Code from module mbsrtowcs: + gl_FUNC_MBSRTOWCS ++ if test $HAVE_MBSRTOWCS = 0 || test $REPLACE_MBSRTOWCS = 1; then ++ AC_LIBOBJ([mbsrtowcs]) ++ AC_LIBOBJ([mbsrtowcs-state]) ++ gl_PREREQ_MBSRTOWCS ++ fi + gl_WCHAR_MODULE_INDICATOR([mbsrtowcs]) +- # Code from module memchr: ++ gl_MBSWIDTH ++ gl_FUNC_MBTOWC ++ if test $REPLACE_MBTOWC = 1; then ++ AC_LIBOBJ([mbtowc]) ++ gl_PREREQ_MBTOWC ++ fi ++ gl_STDLIB_MODULE_INDICATOR([mbtowc]) + gl_FUNC_MEMCHR ++ if test $HAVE_MEMCHR = 0 || test $REPLACE_MEMCHR = 1; then ++ AC_LIBOBJ([memchr]) ++ gl_PREREQ_MEMCHR ++ fi + gl_STRING_MODULE_INDICATOR([memchr]) +- # Code from module mempcpy: + gl_FUNC_MEMPCPY ++ if test $HAVE_MEMPCPY = 0; then ++ AC_LIBOBJ([mempcpy]) ++ gl_PREREQ_MEMPCPY ++ fi + gl_STRING_MODULE_INDICATOR([mempcpy]) +- # Code from module multiarch: ++ gl_MSVC_INVAL ++ if test $HAVE_MSVC_INVALID_PARAMETER_HANDLER = 1; then ++ AC_LIBOBJ([msvc-inval]) ++ fi ++ gl_MSVC_NOTHROW ++ if test $HAVE_MSVC_INVALID_PARAMETER_HANDLER = 1; then ++ AC_LIBOBJ([msvc-nothrow]) ++ fi + gl_MULTIARCH +- # Code from module nl_langinfo: + gl_FUNC_NL_LANGINFO ++ if test $HAVE_NL_LANGINFO = 0 || test $REPLACE_NL_LANGINFO = 1; then ++ AC_LIBOBJ([nl_langinfo]) ++ fi + gl_LANGINFO_MODULE_INDICATOR([nl_langinfo]) +- # Code from module progname: + AC_CHECK_DECLS([program_invocation_name], [], [], [#include ]) + AC_CHECK_DECLS([program_invocation_short_name], [], [], [#include ]) +- # Code from module rawmemchr: + gl_FUNC_RAWMEMCHR ++ if test $HAVE_RAWMEMCHR = 0; then ++ AC_LIBOBJ([rawmemchr]) ++ gl_PREREQ_RAWMEMCHR ++ fi + gl_STRING_MODULE_INDICATOR([rawmemchr]) +- # Code from module realloc-posix: + gl_FUNC_REALLOC_POSIX ++ if test $REPLACE_REALLOC = 1; then ++ AC_LIBOBJ([realloc]) ++ fi + gl_STDLIB_MODULE_INDICATOR([realloc-posix]) +- # Code from module regex: + gl_REGEX +- # Code from module size_max: ++ if test $ac_use_included_regex = yes; then ++ AC_LIBOBJ([regex]) ++ gl_PREREQ_REGEX ++ fi + gl_SIZE_MAX +- # Code from module sleep: + gl_FUNC_SLEEP ++ if test $HAVE_SLEEP = 0 || test $REPLACE_SLEEP = 1; then ++ AC_LIBOBJ([sleep]) ++ fi + gl_UNISTD_MODULE_INDICATOR([sleep]) +- # Code from module ssize_t: + gt_TYPE_SSIZE_T +- # Code from module stdbool: ++ gl_STDALIGN_H + AM_STDBOOL_H +- # Code from module stddef: + gl_STDDEF_H +- # Code from module stdint: + gl_STDINT_H +- # Code from module stdio: + gl_STDIO_H +- # Code from module stdlib: + gl_STDLIB_H +- # Code from module strcase: + gl_STRCASE +- # Code from module strchrnul: ++ if test $HAVE_STRCASECMP = 0; then ++ AC_LIBOBJ([strcasecmp]) ++ gl_PREREQ_STRCASECMP ++ fi ++ if test $HAVE_STRNCASECMP = 0; then ++ AC_LIBOBJ([strncasecmp]) ++ gl_PREREQ_STRNCASECMP ++ fi + gl_FUNC_STRCHRNUL ++ if test $HAVE_STRCHRNUL = 0 || test $REPLACE_STRCHRNUL = 1; then ++ AC_LIBOBJ([strchrnul]) ++ gl_PREREQ_STRCHRNUL ++ fi + gl_STRING_MODULE_INDICATOR([strchrnul]) +- # Code from module streq: +- # Code from module strerror: + gl_FUNC_STRERROR ++ if test $REPLACE_STRERROR = 1; then ++ AC_LIBOBJ([strerror]) ++ fi ++ gl_MODULE_INDICATOR([strerror]) + gl_STRING_MODULE_INDICATOR([strerror]) +- # Code from module string: ++ AC_REQUIRE([gl_HEADER_ERRNO_H]) ++ AC_REQUIRE([gl_FUNC_STRERROR_0]) ++ if test -n "$ERRNO_H" || test $REPLACE_STRERROR_0 = 1; then ++ AC_LIBOBJ([strerror-override]) ++ gl_PREREQ_SYS_H_WINSOCK2 ++ fi + gl_HEADER_STRING_H +- # Code from module strings: + gl_HEADER_STRINGS_H +- # Code from module strndup: + gl_FUNC_STRNDUP ++ if test $HAVE_STRNDUP = 0 || test $REPLACE_STRNDUP = 1; then ++ AC_LIBOBJ([strndup]) ++ fi + gl_STRING_MODULE_INDICATOR([strndup]) +- # Code from module strnlen: + gl_FUNC_STRNLEN ++ if test $HAVE_DECL_STRNLEN = 0 || test $REPLACE_STRNLEN = 1; then ++ AC_LIBOBJ([strnlen]) ++ gl_PREREQ_STRNLEN ++ fi + gl_STRING_MODULE_INDICATOR([strnlen]) +- # Code from module strnlen1: +- # Code from module sys_wait: +- gl_SYS_WAIT_H ++ gl_SYS_TYPES_H + AC_PROG_MKDIR_P +- # Code from module sysexits: + gl_SYSEXITS +- # Code from module unistd: + gl_UNISTD_H +- # Code from module vasnprintf: ++ gl_LIBUNISTRING_LIBHEADER([0.9], [unitypes.h]) ++ gl_LIBUNISTRING_LIBHEADER([0.9], [uniwidth.h]) ++ gl_LIBUNISTRING_MODULE([0.9.4], [uniwidth/width]) + gl_FUNC_VASNPRINTF +- # Code from module verify: +- # Code from module vsnprintf: + gl_FUNC_VSNPRINTF + gl_STDIO_MODULE_INDICATOR([vsnprintf]) +- # Code from module warn-on-use: +- # Code from module wchar: + gl_WCHAR_H +- # Code from module wcrtomb: + gl_FUNC_WCRTOMB ++ if test $HAVE_WCRTOMB = 0 || test $REPLACE_WCRTOMB = 1; then ++ AC_LIBOBJ([wcrtomb]) ++ gl_PREREQ_WCRTOMB ++ fi + gl_WCHAR_MODULE_INDICATOR([wcrtomb]) +- # Code from module wctype: + gl_WCTYPE_H +- # Code from module xsize: ++ gl_FUNC_WCWIDTH ++ if test $HAVE_WCWIDTH = 0 || test $REPLACE_WCWIDTH = 1; then ++ AC_LIBOBJ([wcwidth]) ++ fi ++ gl_WCHAR_MODULE_INDICATOR([wcwidth]) + gl_XSIZE + # End of code from modules + m4_ifval(gl_LIBSOURCES_LIST, [ +@@ -404,10 +519,11 @@ AC_DEFUN([gltests_LIBSOURCES], [ + # This macro records the list of files which have been installed by + # gnulib-tool and may be removed by future gnulib-tool invocations. + AC_DEFUN([gl_FILE_LIST], [ +- build-aux/arg-nonnull.h +- build-aux/c++defs.h + build-aux/config.rpath +- build-aux/warn-on-use.h ++ build-aux/snippet/_Noreturn.h ++ build-aux/snippet/arg-nonnull.h ++ build-aux/snippet/c++defs.h ++ build-aux/snippet/warn-on-use.h + lib/alloca.c + lib/alloca.in.h + lib/argp-ba.c +@@ -429,10 +545,12 @@ AC_DEFUN([gl_FILE_LIST], [ + lib/config.charset + lib/dirname-lgpl.c + lib/dirname.h ++ lib/dosname.h + lib/errno.in.h + lib/error.c + lib/error.h + lib/float+.h ++ lib/float.c + lib/float.in.h + lib/fnmatch.c + lib/fnmatch.in.h +@@ -445,17 +563,29 @@ AC_DEFUN([gl_FILE_LIST], [ + lib/getopt_int.h + lib/gettext.h + lib/intprops.h ++ lib/itold.c + lib/langinfo.in.h + lib/localcharset.c + lib/localcharset.h ++ lib/locale.in.h ++ lib/localeconv.c + lib/malloc.c + lib/mbrtowc.c + lib/mbsinit.c ++ lib/mbsrtowcs-impl.h + lib/mbsrtowcs-state.c + lib/mbsrtowcs.c ++ lib/mbswidth.c ++ lib/mbswidth.h ++ lib/mbtowc-impl.h ++ lib/mbtowc.c + lib/memchr.c + lib/memchr.valgrind + lib/mempcpy.c ++ lib/msvc-inval.c ++ lib/msvc-inval.h ++ lib/msvc-nothrow.c ++ lib/msvc-nothrow.h + lib/nl_langinfo.c + lib/printf-args.c + lib/printf-args.h +@@ -476,16 +606,18 @@ AC_DEFUN([gl_FILE_LIST], [ + lib/regexec.c + lib/size_max.h + lib/sleep.c ++ lib/stdalign.in.h + lib/stdbool.in.h + lib/stddef.in.h + lib/stdint.in.h +- lib/stdio-write.c + lib/stdio.in.h + lib/stdlib.in.h + lib/strcasecmp.c + lib/strchrnul.c + lib/strchrnul.valgrind + lib/streq.h ++ lib/strerror-override.c ++ lib/strerror-override.h + lib/strerror.c + lib/string.in.h + lib/strings.in.h +@@ -495,29 +627,39 @@ AC_DEFUN([gl_FILE_LIST], [ + lib/strnlen.c + lib/strnlen1.c + lib/strnlen1.h +- lib/sys_wait.in.h ++ lib/sys_types.in.h + lib/sysexits.in.h ++ lib/unistd.c + lib/unistd.in.h ++ lib/unitypes.in.h ++ lib/uniwidth.in.h ++ lib/uniwidth/cjk.h ++ lib/uniwidth/width.c + lib/vasnprintf.c + lib/vasnprintf.h + lib/verify.h + lib/vsnprintf.c + lib/wchar.in.h + lib/wcrtomb.c ++ lib/wctype-h.c + lib/wctype.in.h ++ lib/wcwidth.c ++ lib/xsize.c + lib/xsize.h + m4/00gnulib.m4 + m4/alloca.m4 + m4/argp.m4 +- m4/asm-underscore.m4 + m4/btowc.m4 + m4/codeset.m4 ++ m4/configmake.m4 + m4/dirname.m4 +- m4/dos.m4 + m4/double-slash-root.m4 ++ m4/eealloc.m4 + m4/errno_h.m4 + m4/error.m4 ++ m4/exponentd.m4 + m4/extensions.m4 ++ m4/extern-inline.m4 + m4/fcntl-o.m4 + m4/float_h.m4 + m4/fnmatch.m4 +@@ -543,23 +685,33 @@ AC_DEFUN([gl_FILE_LIST], [ + m4/lib-ld.m4 + m4/lib-link.m4 + m4/lib-prefix.m4 ++ m4/libunistring-base.m4 + m4/localcharset.m4 + m4/locale-fr.m4 + m4/locale-ja.m4 + m4/locale-zh.m4 ++ m4/locale_h.m4 ++ m4/localeconv.m4 + m4/lock.m4 + m4/longlong.m4 + m4/malloc.m4 ++ m4/math_h.m4 + m4/mbrtowc.m4 + m4/mbsinit.m4 + m4/mbsrtowcs.m4 + m4/mbstate_t.m4 ++ m4/mbswidth.m4 ++ m4/mbtowc.m4 + m4/memchr.m4 + m4/mempcpy.m4 + m4/mmap-anon.m4 ++ m4/msvc-inval.m4 ++ m4/msvc-nothrow.m4 + m4/multiarch.m4 + m4/nl_langinfo.m4 + m4/nls.m4 ++ m4/nocrash.m4 ++ m4/off_t.m4 + m4/po.m4 + m4/printf-posix.m4 + m4/printf.m4 +@@ -570,6 +722,7 @@ AC_DEFUN([gl_FILE_LIST], [ + m4/size_max.m4 + m4/sleep.m4 + m4/ssize_t.m4 ++ m4/stdalign.m4 + m4/stdbool.m4 + m4/stddef_h.m4 + m4/stdint.m4 +@@ -583,7 +736,8 @@ AC_DEFUN([gl_FILE_LIST], [ + m4/strings_h.m4 + m4/strndup.m4 + m4/strnlen.m4 +- m4/sys_wait_h.m4 ++ m4/sys_socket_h.m4 ++ m4/sys_types_h.m4 + m4/sysexits.m4 + m4/threadlib.m4 + m4/uintmax_t.m4 +@@ -596,6 +750,7 @@ AC_DEFUN([gl_FILE_LIST], [ + m4/wchar_t.m4 + m4/wcrtomb.m4 + m4/wctype_h.m4 ++ m4/wcwidth.m4 + m4/wint_t.m4 + m4/xsize.m4 + ]) +diff --git a/m4/gnulib-tool.m4 b/m4/gnulib-tool.m4 +index 69e7733..f3dea1a 100644 +--- a/m4/gnulib-tool.m4 ++++ b/m4/gnulib-tool.m4 +@@ -1,5 +1,5 @@ + # gnulib-tool.m4 serial 2 +-dnl Copyright (C) 2004-2005, 2009-2010 Free Software Foundation, Inc. ++dnl Copyright (C) 2004-2005, 2009-2013 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. +diff --git a/m4/iconv.m4 b/m4/iconv.m4 +index 425145c..a503646 100644 +--- a/m4/iconv.m4 ++++ b/m4/iconv.m4 +@@ -1,5 +1,5 @@ +-# iconv.m4 serial 15 (gettext-0.18.2) +-dnl Copyright (C) 2000-2002, 2007-2010 Free Software Foundation, Inc. ++# iconv.m4 serial 18 (gettext-0.18.2) ++dnl Copyright (C) 2000-2002, 2007-2013 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. +@@ -78,6 +78,7 @@ AC_DEFUN([AM_ICONV_LINK], + #include + int main () + { ++ int result = 0; + /* Test against AIX 5.1 bug: Failures are not distinguishable from successful + returns. */ + { +@@ -94,7 +95,8 @@ int main () + (char **) &inptr, &inbytesleft, + &outptr, &outbytesleft); + if (res == 0) +- return 1; ++ result |= 1; ++ iconv_close (cd_utf8_to_88591); + } + } + /* Test against Solaris 10 bug: Failures are not distinguishable from +@@ -113,7 +115,8 @@ int main () + (char **) &inptr, &inbytesleft, + &outptr, &outbytesleft); + if (res == 0) +- return 1; ++ result |= 2; ++ iconv_close (cd_ascii_to_88591); + } + } + /* Test against AIX 6.1..7.1 bug: Buffer overrun. */ +@@ -131,7 +134,8 @@ int main () + (char **) &inptr, &inbytesleft, + &outptr, &outbytesleft); + if (res != (size_t)(-1) || outptr - buf > 1 || buf[1] != (char)0xAD) +- return 1; ++ result |= 4; ++ iconv_close (cd_88591_to_utf8); + } + } + #if 0 /* This bug could be worked around by the caller. */ +@@ -150,7 +154,8 @@ int main () + (char **) &inptr, &inbytesleft, + &outptr, &outbytesleft); + if ((int)res > 0) +- return 1; ++ result |= 8; ++ iconv_close (cd_88591_to_utf8); + } + } + #endif +@@ -164,8 +169,8 @@ int main () + && iconv_open ("UTF-8", "IBM-eucJP") == (iconv_t)(-1) + /* Try HP-UX names. */ + && iconv_open ("utf8", "eucJP") == (iconv_t)(-1)) +- return 1; +- return 0; ++ result |= 16; ++ return result; + }]])], + [am_cv_func_iconv_works=yes], + [am_cv_func_iconv_works=no], +@@ -237,7 +242,7 @@ extern + #ifdef __cplusplus + "C" + #endif +-#if defined(__STDC__) || defined(__cplusplus) ++#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus) + size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft); + #else + size_t iconv(); +@@ -252,5 +257,12 @@ size_t iconv(); + $am_cv_proto_iconv]) + AC_DEFINE_UNQUOTED([ICONV_CONST], [$am_cv_proto_iconv_arg1], + [Define as const if the declaration of iconv() needs const.]) ++ dnl Also substitute ICONV_CONST in the gnulib generated . ++ m4_ifdef([gl_ICONV_H_DEFAULTS], ++ [AC_REQUIRE([gl_ICONV_H_DEFAULTS]) ++ if test -n "$am_cv_proto_iconv_arg1"; then ++ ICONV_CONST="const" ++ fi ++ ]) + fi + ]) +diff --git a/m4/include_next.m4 b/m4/include_next.m4 +index 51a719b..108d945 100644 +--- a/m4/include_next.m4 ++++ b/m4/include_next.m4 +@@ -1,5 +1,5 @@ +-# include_next.m4 serial 15 +-dnl Copyright (C) 2006-2010 Free Software Foundation, Inc. ++# include_next.m4 serial 23 ++dnl Copyright (C) 2006-2013 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. +@@ -24,6 +24,13 @@ dnl does not warn about some things, and on some systems (Solaris and Interix) + dnl __STDC__ evaluates to 0 instead of to 1. The latter is an undesired side + dnl effect; we are therefore careful to use 'defined __STDC__' or '1' instead + dnl of plain '__STDC__'. ++dnl ++dnl PRAGMA_COLUMNS can be used in files that override system header files, so ++dnl as to avoid compilation errors on HP NonStop systems when the gnulib file ++dnl is included by a system header file that does a "#pragma COLUMNS 80" (which ++dnl has the effect of truncating the lines of that file and all files that it ++dnl includes to 80 columns) and the gnulib file has lines longer than 80 ++dnl columns. + + AC_DEFUN([gl_INCLUDE_NEXT], + [ +@@ -98,6 +105,24 @@ dnl We intentionally avoid using AC_LANG_SOURCE here. + AC_SUBST([INCLUDE_NEXT]) + AC_SUBST([INCLUDE_NEXT_AS_FIRST_DIRECTIVE]) + AC_SUBST([PRAGMA_SYSTEM_HEADER]) ++ AC_CACHE_CHECK([whether system header files limit the line length], ++ [gl_cv_pragma_columns], ++ [dnl HP NonStop systems, which define __TANDEM, have this misfeature. ++ AC_EGREP_CPP([choke me], ++ [ ++#ifdef __TANDEM ++choke me ++#endif ++ ], ++ [gl_cv_pragma_columns=yes], ++ [gl_cv_pragma_columns=no]) ++ ]) ++ if test $gl_cv_pragma_columns = yes; then ++ PRAGMA_COLUMNS="#pragma COLUMNS 10000" ++ else ++ PRAGMA_COLUMNS= ++ fi ++ AC_SUBST([PRAGMA_COLUMNS]) + ]) + + # gl_CHECK_NEXT_HEADERS(HEADER1 HEADER2 ...) +@@ -118,68 +143,121 @@ dnl We intentionally avoid using AC_LANG_SOURCE here. + # even if the compiler does not support include_next. + # The three "///" are to pacify Sun C 5.8, which otherwise would say + # "warning: #include of /usr/include/... may be non-portable". +-# Use `""', not `<>', so that the /// cannot be confused with a C99 comment. ++# Use '""', not '<>', so that the /// cannot be confused with a C99 comment. + # Note: This macro assumes that the header file is not empty after + # preprocessing, i.e. it does not only define preprocessor macros but also + # provides some type/enum definitions or function/variable declarations. ++# ++# This macro also checks whether each header exists, by invoking ++# AC_CHECK_HEADERS_ONCE or AC_CHECK_HEADERS on each argument. + AC_DEFUN([gl_CHECK_NEXT_HEADERS], + [ ++ gl_NEXT_HEADERS_INTERNAL([$1], [check]) ++]) ++ ++# gl_NEXT_HEADERS(HEADER1 HEADER2 ...) ++# ------------------------------------ ++# Like gl_CHECK_NEXT_HEADERS, except do not check whether the headers exist. ++# This is suitable for headers like that are standardized by C89 ++# and therefore can be assumed to exist. ++AC_DEFUN([gl_NEXT_HEADERS], ++[ ++ gl_NEXT_HEADERS_INTERNAL([$1], [assume]) ++]) ++ ++# The guts of gl_CHECK_NEXT_HEADERS and gl_NEXT_HEADERS. ++AC_DEFUN([gl_NEXT_HEADERS_INTERNAL], ++[ + AC_REQUIRE([gl_INCLUDE_NEXT]) + AC_REQUIRE([AC_CANONICAL_HOST]) +- AC_CHECK_HEADERS_ONCE([$1]) + ++ m4_if([$2], [check], ++ [AC_CHECK_HEADERS_ONCE([$1]) ++ ]) ++ ++dnl FIXME: gl_next_header and gl_header_exists must be used unquoted ++dnl until we can assume autoconf 2.64 or newer. + m4_foreach_w([gl_HEADER_NAME], [$1], + [AS_VAR_PUSHDEF([gl_next_header], + [gl_cv_next_]m4_defn([gl_HEADER_NAME])) + if test $gl_cv_have_include_next = yes; then +- AS_VAR_SET([gl_next_header], ['<'gl_HEADER_NAME'>']) ++ AS_VAR_SET(gl_next_header, ['<'gl_HEADER_NAME'>']) + else + AC_CACHE_CHECK( + [absolute name of <]m4_defn([gl_HEADER_NAME])[>], + m4_defn([gl_next_header]), +- [AS_VAR_PUSHDEF([gl_header_exists], +- [ac_cv_header_]m4_defn([gl_HEADER_NAME])) +- if test AS_VAR_GET(gl_header_exists) = yes; then +- AC_LANG_CONFTEST( +- [AC_LANG_SOURCE( +- [[#include <]]m4_dquote(m4_defn([gl_HEADER_NAME]))[[>]] +- )]) +- dnl AIX "xlc -E" and "cc -E" omit #line directives for header files +- dnl that contain only a #include of other header files and no +- dnl non-comment tokens of their own. This leads to a failure to +- dnl detect the absolute name of , , +- dnl and others. The workaround is to force preservation of comments +- dnl through option -C. This ensures all necessary #line directives +- dnl are present. GCC supports option -C as well. +- case "$host_os" in +- aix*) gl_absname_cpp="$ac_cpp -C" ;; +- *) gl_absname_cpp="$ac_cpp" ;; +- esac +- dnl eval is necessary to expand gl_absname_cpp. +- dnl Ultrix and Pyramid sh refuse to redirect output of eval, +- dnl so use subshell. +- AS_VAR_SET([gl_next_header], +- ['"'`(eval "$gl_absname_cpp conftest.$ac_ext") 2>&AS_MESSAGE_LOG_FD | +- sed -n '\#/]m4_defn([gl_HEADER_NAME])[#{ +- s#.*"\(.*/]m4_defn([gl_HEADER_NAME])[\)".*#\1# +- s#^/[^/]#//&# +- p +- q +- }'`'"']) +- else +- AS_VAR_SET([gl_next_header], ['<'gl_HEADER_NAME'>']) +- fi +- AS_VAR_POPDEF([gl_header_exists])]) ++ [m4_if([$2], [check], ++ [AS_VAR_PUSHDEF([gl_header_exists], ++ [ac_cv_header_]m4_defn([gl_HEADER_NAME])) ++ if test AS_VAR_GET(gl_header_exists) = yes; then ++ AS_VAR_POPDEF([gl_header_exists]) ++ ]) ++ AC_LANG_CONFTEST( ++ [AC_LANG_SOURCE( ++ [[#include <]]m4_dquote(m4_defn([gl_HEADER_NAME]))[[>]] ++ )]) ++ dnl AIX "xlc -E" and "cc -E" omit #line directives for header ++ dnl files that contain only a #include of other header files and ++ dnl no non-comment tokens of their own. This leads to a failure ++ dnl to detect the absolute name of , , ++ dnl and others. The workaround is to force preservation ++ dnl of comments through option -C. This ensures all necessary ++ dnl #line directives are present. GCC supports option -C as well. ++ case "$host_os" in ++ aix*) gl_absname_cpp="$ac_cpp -C" ;; ++ *) gl_absname_cpp="$ac_cpp" ;; ++ esac ++changequote(,) ++ case "$host_os" in ++ mingw*) ++ dnl For the sake of native Windows compilers (excluding gcc), ++ dnl treat backslash as a directory separator, like /. ++ dnl Actually, these compilers use a double-backslash as ++ dnl directory separator, inside the ++ dnl # line "filename" ++ dnl directives. ++ gl_dirsep_regex='[/\\]' ++ ;; ++ *) ++ gl_dirsep_regex='\/' ++ ;; ++ esac ++ dnl A sed expression that turns a string into a basic regular ++ dnl expression, for use within "/.../". ++ gl_make_literal_regex_sed='s,[]$^\\.*/[],\\&,g' ++changequote([,]) ++ gl_header_literal_regex=`echo ']m4_defn([gl_HEADER_NAME])[' \ ++ | sed -e "$gl_make_literal_regex_sed"` ++ gl_absolute_header_sed="/${gl_dirsep_regex}${gl_header_literal_regex}/"'{ ++ s/.*"\(.*'"${gl_dirsep_regex}${gl_header_literal_regex}"'\)".*/\1/ ++changequote(,)dnl ++ s|^/[^/]|//&| ++changequote([,])dnl ++ p ++ q ++ }' ++ dnl eval is necessary to expand gl_absname_cpp. ++ dnl Ultrix and Pyramid sh refuse to redirect output of eval, ++ dnl so use subshell. ++ AS_VAR_SET(gl_next_header, ++ ['"'`(eval "$gl_absname_cpp conftest.$ac_ext") 2>&AS_MESSAGE_LOG_FD | ++ sed -n "$gl_absolute_header_sed"`'"']) ++ m4_if([$2], [check], ++ [else ++ AS_VAR_SET(gl_next_header, ['<'gl_HEADER_NAME'>']) ++ fi ++ ]) ++ ]) + fi + AC_SUBST( + AS_TR_CPP([NEXT_]m4_defn([gl_HEADER_NAME])), +- [AS_VAR_GET([gl_next_header])]) ++ [AS_VAR_GET(gl_next_header)]) + if test $gl_cv_have_include_next = yes || test $gl_cv_have_include_next = buggy; then + # INCLUDE_NEXT_AS_FIRST_DIRECTIVE='include_next' + gl_next_as_first_directive='<'gl_HEADER_NAME'>' + else + # INCLUDE_NEXT_AS_FIRST_DIRECTIVE='include' +- gl_next_as_first_directive=AS_VAR_GET([gl_next_header]) ++ gl_next_as_first_directive=AS_VAR_GET(gl_next_header) + fi + AC_SUBST( + AS_TR_CPP([NEXT_AS_FIRST_DIRECTIVE_]m4_defn([gl_HEADER_NAME])), +diff --git a/m4/intdiv0.m4 b/m4/intdiv0.m4 +index 9b27ff1..74d0e80 100644 +--- a/m4/intdiv0.m4 ++++ b/m4/intdiv0.m4 +@@ -1,5 +1,5 @@ +-# intdiv0.m4 serial 4 (gettext-0.18.2) +-dnl Copyright (C) 2002, 2007-2008, 2010 Free Software Foundation, Inc. ++# intdiv0.m4 serial 6 (gettext-0.18.2) ++dnl Copyright (C) 2002, 2007-2008, 2010-2013 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. +@@ -18,7 +18,7 @@ AC_DEFUN([gt_INTDIV0], + changequote(,)dnl + case "$host_os" in + macos* | darwin[6-9]* | darwin[1-9][0-9]*) +- # On MacOS X 10.2 or newer, just assume the same as when cross- ++ # On Mac OS X 10.2 or newer, just assume the same as when cross- + # compiling. If we were to perform the real test, 1 Crash Report + # dialog window would pop up. + case "$host_cpu" in +@@ -60,7 +60,7 @@ int main () + + z = x / y; + nan = y / y; +- exit (1); ++ exit (2); + } + ]])], + [gt_cv_int_divbyzero_sigfpe=yes], +diff --git a/m4/intl.m4 b/m4/intl.m4 +index d84bc4a..486b5cc 100644 +--- a/m4/intl.m4 ++++ b/m4/intl.m4 +@@ -1,5 +1,5 @@ +-# intl.m4 serial 17b +-dnl Copyright (C) 1995-2010 Free Software Foundation, Inc. ++# intl.m4 serial 22 (gettext-0.18.2) ++dnl Copyright (C) 1995-2013 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. +@@ -17,7 +17,7 @@ dnl Authors: + dnl Ulrich Drepper , 1995-2000. + dnl Bruno Haible , 2000-2009. + +-AC_PREREQ([2.53]) ++AC_PREREQ([2.60]) + + dnl Checks for all prerequisites of the intl subdirectory, + dnl except for INTL_LIBTOOL_SUFFIX_PREFIX (and possibly LIBTOOL), INTLOBJS, +@@ -25,7 +25,7 @@ dnl USE_INCLUDED_LIBINTL, BUILD_INCLUDED_LIBINTL. + AC_DEFUN([AM_INTL_SUBDIR], + [ + AC_REQUIRE([AC_PROG_INSTALL])dnl +- AC_REQUIRE([AM_PROG_MKDIR_P])dnl defined by automake ++ AC_REQUIRE([AC_PROG_MKDIR_P])dnl + AC_REQUIRE([AC_PROG_CC])dnl + AC_REQUIRE([AC_CANONICAL_HOST])dnl + AC_REQUIRE([gt_GLIBC2])dnl +@@ -55,7 +55,7 @@ AC_DEFUN([AM_INTL_SUBDIR], + [AC_DEFINE([ptrdiff_t], [long], + [Define as the type of the result of subtracting two pointers, if the system doesn't define it.]) + ]) +- AC_CHECK_HEADERS([stddef.h stdlib.h string.h]) ++ AC_CHECK_HEADERS([features.h stddef.h stdlib.h string.h]) + AC_CHECK_FUNCS([asprintf fwprintf newlocale putenv setenv setlocale \ + snprintf strnlen wcslen wcsnlen mbrtowc wcrtomb]) + +@@ -295,6 +295,6 @@ AC_DEFUN([gt_CHECK_DECL], + else + gt_value=0 + fi +- AC_DEFINE_UNQUOTED([HAVE_DECL_]translit($1, [a-z], [A-Z]), [$gt_value], +- [Define to 1 if you have the declaration of `$1', and to 0 if you don't.]) ++ AC_DEFINE_UNQUOTED([HAVE_DECL_]m4_translit($1, [a-z], [A-Z]), [$gt_value], ++ [Define to 1 if you have the declaration of '$1', and to 0 if you don't.]) + ]) +diff --git a/m4/intldir.m4 b/m4/intldir.m4 +index ebae76d..388ecd6 100644 +--- a/m4/intldir.m4 ++++ b/m4/intldir.m4 +@@ -1,5 +1,5 @@ + # intldir.m4 serial 2 (gettext-0.18) +-dnl Copyright (C) 2006, 2009-2010 Free Software Foundation, Inc. ++dnl Copyright (C) 2006, 2009-2013 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. +diff --git a/m4/intlmacosx.m4 b/m4/intlmacosx.m4 +index f0f7c98..ab97d39 100644 +--- a/m4/intlmacosx.m4 ++++ b/m4/intlmacosx.m4 +@@ -1,5 +1,5 @@ +-# intlmacosx.m4 serial 4 (gettext-0.18.2) +-dnl Copyright (C) 2004-2010 Free Software Foundation, Inc. ++# intlmacosx.m4 serial 5 (gettext-0.18.2) ++dnl Copyright (C) 2004-2013 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. +@@ -13,11 +13,11 @@ dnl by the GNU Library General Public License, and the rest of the GNU + dnl gettext package package is covered by the GNU General Public License. + dnl They are *not* in the public domain. + +-dnl Checks for special options needed on MacOS X. ++dnl Checks for special options needed on Mac OS X. + dnl Defines INTL_MACOSX_LIBS. + AC_DEFUN([gt_INTL_MACOSX], + [ +- dnl Check for API introduced in MacOS X 10.2. ++ dnl Check for API introduced in Mac OS X 10.2. + AC_CACHE_CHECK([for CFPreferencesCopyAppValue], + [gt_cv_func_CFPreferencesCopyAppValue], + [gt_save_LIBS="$LIBS" +@@ -31,9 +31,9 @@ AC_DEFUN([gt_INTL_MACOSX], + LIBS="$gt_save_LIBS"]) + if test $gt_cv_func_CFPreferencesCopyAppValue = yes; then + AC_DEFINE([HAVE_CFPREFERENCESCOPYAPPVALUE], [1], +- [Define to 1 if you have the MacOS X function CFPreferencesCopyAppValue in the CoreFoundation framework.]) ++ [Define to 1 if you have the Mac OS X function CFPreferencesCopyAppValue in the CoreFoundation framework.]) + fi +- dnl Check for API introduced in MacOS X 10.3. ++ dnl Check for API introduced in Mac OS X 10.3. + AC_CACHE_CHECK([for CFLocaleCopyCurrent], [gt_cv_func_CFLocaleCopyCurrent], + [gt_save_LIBS="$LIBS" + LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation" +@@ -46,7 +46,7 @@ AC_DEFUN([gt_INTL_MACOSX], + LIBS="$gt_save_LIBS"]) + if test $gt_cv_func_CFLocaleCopyCurrent = yes; then + AC_DEFINE([HAVE_CFLOCALECOPYCURRENT], [1], +- [Define to 1 if you have the MacOS X function CFLocaleCopyCurrent in the CoreFoundation framework.]) ++ [Define to 1 if you have the Mac OS X function CFLocaleCopyCurrent in the CoreFoundation framework.]) + fi + INTL_MACOSX_LIBS= + if test $gt_cv_func_CFPreferencesCopyAppValue = yes || test $gt_cv_func_CFLocaleCopyCurrent = yes; then +diff --git a/m4/intmax.m4 b/m4/intmax.m4 +index 2c0f2af..18733a5 100644 +--- a/m4/intmax.m4 ++++ b/m4/intmax.m4 +@@ -1,5 +1,5 @@ + # intmax.m4 serial 6 (gettext-0.18.2) +-dnl Copyright (C) 2002-2005, 2008-2010 Free Software Foundation, Inc. ++dnl Copyright (C) 2002-2005, 2008-2013 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. +diff --git a/m4/intmax_t.m4 b/m4/intmax_t.m4 +index 493e4a9..6ea7053 100644 +--- a/m4/intmax_t.m4 ++++ b/m4/intmax_t.m4 +@@ -1,5 +1,5 @@ + # intmax_t.m4 serial 8 +-dnl Copyright (C) 1997-2004, 2006-2007, 2009-2010 Free Software Foundation, ++dnl Copyright (C) 1997-2004, 2006-2007, 2009-2013 Free Software Foundation, + dnl Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, +diff --git a/m4/inttypes-pri.m4 b/m4/inttypes-pri.m4 +index ee96bcd..e5a1e05 100644 +--- a/m4/inttypes-pri.m4 ++++ b/m4/inttypes-pri.m4 +@@ -1,5 +1,5 @@ + # inttypes-pri.m4 serial 7 (gettext-0.18.2) +-dnl Copyright (C) 1997-2002, 2006, 2008-2010 Free Software Foundation, Inc. ++dnl Copyright (C) 1997-2002, 2006, 2008-2013 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. +diff --git a/m4/inttypes_h.m4 b/m4/inttypes_h.m4 +index 9d8f926..5f05ac5 100644 +--- a/m4/inttypes_h.m4 ++++ b/m4/inttypes_h.m4 +@@ -1,5 +1,5 @@ + # inttypes_h.m4 serial 10 +-dnl Copyright (C) 1997-2004, 2006, 2008-2010 Free Software Foundation, Inc. ++dnl Copyright (C) 1997-2004, 2006, 2008-2013 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. +diff --git a/m4/langinfo_h.m4 b/m4/langinfo_h.m4 +index adc445e..73bef8b 100644 +--- a/m4/langinfo_h.m4 ++++ b/m4/langinfo_h.m4 +@@ -1,5 +1,5 @@ + # langinfo_h.m4 serial 7 +-dnl Copyright (C) 2009-2010 Free Software Foundation, Inc. ++dnl Copyright (C) 2009-2013 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. +diff --git a/m4/lcmessage.m4 b/m4/lcmessage.m4 +index 232da73..d62a175 100644 +--- a/m4/lcmessage.m4 ++++ b/m4/lcmessage.m4 +@@ -1,5 +1,5 @@ + # lcmessage.m4 serial 7 (gettext-0.18.2) +-dnl Copyright (C) 1995-2002, 2004-2005, 2008-2010 Free Software Foundation, ++dnl Copyright (C) 1995-2002, 2004-2005, 2008-2013 Free Software Foundation, + dnl Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, +diff --git a/m4/lib-ld.m4 b/m4/lib-ld.m4 +index 294db72..c145e47 100644 +--- a/m4/lib-ld.m4 ++++ b/m4/lib-ld.m4 +@@ -1,33 +1,39 @@ +-# lib-ld.m4 serial 5 (gettext-0.18.2) +-dnl Copyright (C) 1996-2003, 2009-2010 Free Software Foundation, Inc. ++# lib-ld.m4 serial 6 ++dnl Copyright (C) 1996-2003, 2009-2013 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. + + dnl Subroutines of libtool.m4, +-dnl with replacements s/AC_/AC_LIB/ and s/lt_cv/acl_cv/ to avoid collision +-dnl with libtool.m4. ++dnl with replacements s/_*LT_PATH/AC_LIB_PROG/ and s/lt_/acl_/ to avoid ++dnl collision with libtool.m4. + +-dnl From libtool-1.4. Sets the variable with_gnu_ld to yes or no. ++dnl From libtool-2.4. Sets the variable with_gnu_ld to yes or no. + AC_DEFUN([AC_LIB_PROG_LD_GNU], + [AC_CACHE_CHECK([if the linker ($LD) is GNU ld], [acl_cv_prog_gnu_ld], +-[# I'd rather use --version here, but apparently some GNU ld's only accept -v. ++[# I'd rather use --version here, but apparently some GNU lds only accept -v. + case `$LD -v 2>&1 /dev/null 2>&1; do ++ [[\\/]]* | ?:[[\\/]]*) ++ re_direlt='/[[^/]][[^/]]*/\.\./' ++ # Canonicalize the pathname of ld ++ ac_prog=`echo "$ac_prog"| sed 's%\\\\%/%g'` ++ while echo "$ac_prog" | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" +@@ -78,23 +85,26 @@ else + fi + AC_CACHE_VAL([acl_cv_path_LD], + [if test -z "$LD"; then +- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" ++ acl_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do ++ IFS="$acl_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + acl_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, +- # but apparently some GNU ld's only accept -v. ++ # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. +- case `"$acl_cv_path_LD" -v 2>&1 < /dev/null` in ++ case `"$acl_cv_path_LD" -v 2>&1 = the given VERSION. ++dnl Defines an automake conditional LIBUNISTRING_COMPILE_$MODULE that is ++dnl true if the source files of Module should be compiled. ++dnl This macro is to be used for public libunistring API, not for ++dnl undocumented API. ++dnl ++dnl You have to bump the VERSION argument to the next projected version ++dnl number each time you make a change that affects the behaviour of the ++dnl functions defined in Module (even if the sources of Module itself do not ++dnl change). ++ ++AC_DEFUN([gl_LIBUNISTRING_MODULE], ++[ ++ AC_REQUIRE([gl_LIBUNISTRING_LIB_PREPARE]) ++ dnl Use the variables HAVE_LIBUNISTRING, LIBUNISTRING_VERSION from ++ dnl gl_LIBUNISTRING_CORE if that macro has been run. ++ AM_CONDITIONAL(AS_TR_CPP([LIBUNISTRING_COMPILE_$2]), ++ [gl_LIBUNISTRING_VERSION_CMP([$1])]) ++]) ++ ++dnl gl_LIBUNISTRING_LIBHEADER([VERSION], [HeaderFile]) ++dnl Declares that HeaderFile should be created, unless we are linking ++dnl with libunistring and its version is >= the given VERSION. ++dnl HeaderFile should be relative to the lib directory and end in '.h'. ++dnl Prepares for substituting LIBUNISTRING_HEADERFILE (to HeaderFile or empty). ++dnl ++dnl When we are linking with the already installed libunistring and its version ++dnl is < VERSION, we create HeaderFile here, because we may compile functions ++dnl (via gl_LIBUNISTRING_MODULE above) that are not contained in the installed ++dnl version. ++dnl When we are linking with the already installed libunistring and its version ++dnl is > VERSION, we don't create HeaderFile here: it could cause compilation ++dnl errors in other libunistring header files if some types are missing. ++dnl ++dnl You have to bump the VERSION argument to the next projected version ++dnl number each time you make a non-comment change to the HeaderFile. ++ ++AC_DEFUN([gl_LIBUNISTRING_LIBHEADER], ++[ ++ AC_REQUIRE([gl_LIBUNISTRING_LIB_PREPARE]) ++ dnl Use the variables HAVE_LIBUNISTRING, LIBUNISTRING_VERSION from ++ dnl gl_LIBUNISTRING_CORE if that macro has been run. ++ if gl_LIBUNISTRING_VERSION_CMP([$1]); then ++ LIBUNISTRING_[]AS_TR_CPP([$2])='$2' ++ else ++ LIBUNISTRING_[]AS_TR_CPP([$2])= ++ fi ++ AC_SUBST([LIBUNISTRING_]AS_TR_CPP([$2])) ++]) ++ ++dnl Miscellaneous preparations/initializations. ++ ++AC_DEFUN([gl_LIBUNISTRING_LIB_PREPARE], ++[ ++ dnl Ensure that HAVE_LIBUNISTRING is fully determined at this point. ++ m4_ifdef([gl_LIBUNISTRING], [AC_REQUIRE([gl_LIBUNISTRING])]) ++ ++ AC_REQUIRE([AC_PROG_AWK]) ++ ++dnl Sed expressions to extract the parts of a version number. ++changequote(,) ++gl_libunistring_sed_extract_major='/^[0-9]/{s/^\([0-9]*\).*/\1/p;q;} ++i\ ++0 ++q ++' ++gl_libunistring_sed_extract_minor='/^[0-9][0-9]*[.][0-9]/{s/^[0-9]*[.]\([0-9]*\).*/\1/p;q;} ++i\ ++0 ++q ++' ++gl_libunistring_sed_extract_subminor='/^[0-9][0-9]*[.][0-9][0-9]*[.][0-9]/{s/^[0-9]*[.][0-9]*[.]\([0-9]*\).*/\1/p;q;} ++i\ ++0 ++q ++' ++changequote([,]) ++ ++ if test "$HAVE_LIBUNISTRING" = yes; then ++ LIBUNISTRING_VERSION_MAJOR=`echo "$LIBUNISTRING_VERSION" | sed -n -e "$gl_libunistring_sed_extract_major"` ++ LIBUNISTRING_VERSION_MINOR=`echo "$LIBUNISTRING_VERSION" | sed -n -e "$gl_libunistring_sed_extract_minor"` ++ LIBUNISTRING_VERSION_SUBMINOR=`echo "$LIBUNISTRING_VERSION" | sed -n -e "$gl_libunistring_sed_extract_subminor"` ++ fi ++]) ++ ++dnl gl_LIBUNISTRING_VERSION_CMP([VERSION]) ++dnl Expands to a shell statement that evaluates to true if LIBUNISTRING_VERSION ++dnl is less than the VERSION argument. ++AC_DEFUN([gl_LIBUNISTRING_VERSION_CMP], ++[ { test "$HAVE_LIBUNISTRING" != yes \ ++ || { ++ dnl AS_LITERAL_IF exists and works fine since autoconf-2.59 at least. ++ AS_LITERAL_IF([$1], ++ [dnl This is the optimized variant, that assumes the argument is a literal: ++ m4_pushdef([requested_version_major], ++ [gl_LIBUNISTRING_ARG_OR_ZERO(m4_bpatsubst([$1], [^\([0-9]*\).*], [\1]), [])]) ++ m4_pushdef([requested_version_minor], ++ [gl_LIBUNISTRING_ARG_OR_ZERO(m4_bpatsubst([$1], [^[0-9]*[.]\([0-9]*\).*], [\1]), [$1])]) ++ m4_pushdef([requested_version_subminor], ++ [gl_LIBUNISTRING_ARG_OR_ZERO(m4_bpatsubst([$1], [^[0-9]*[.][0-9]*[.]\([0-9]*\).*], [\1]), [$1])]) ++ test $LIBUNISTRING_VERSION_MAJOR -lt requested_version_major \ ++ || { test $LIBUNISTRING_VERSION_MAJOR -eq requested_version_major \ ++ && { test $LIBUNISTRING_VERSION_MINOR -lt requested_version_minor \ ++ || { test $LIBUNISTRING_VERSION_MINOR -eq requested_version_minor \ ++ && test $LIBUNISTRING_VERSION_SUBMINOR -lt requested_version_subminor ++ } ++ } ++ } ++ m4_popdef([requested_version_subminor]) ++ m4_popdef([requested_version_minor]) ++ m4_popdef([requested_version_major]) ++ ], ++ [dnl This is the unoptimized variant: ++ requested_version_major=`echo '$1' | sed -n -e "$gl_libunistring_sed_extract_major"` ++ requested_version_minor=`echo '$1' | sed -n -e "$gl_libunistring_sed_extract_minor"` ++ requested_version_subminor=`echo '$1' | sed -n -e "$gl_libunistring_sed_extract_subminor"` ++ test $LIBUNISTRING_VERSION_MAJOR -lt $requested_version_major \ ++ || { test $LIBUNISTRING_VERSION_MAJOR -eq $requested_version_major \ ++ && { test $LIBUNISTRING_VERSION_MINOR -lt $requested_version_minor \ ++ || { test $LIBUNISTRING_VERSION_MINOR -eq $requested_version_minor \ ++ && test $LIBUNISTRING_VERSION_SUBMINOR -lt $requested_version_subminor ++ } ++ } ++ } ++ ]) ++ } ++ }]) ++ ++dnl gl_LIBUNISTRING_ARG_OR_ZERO([ARG], [ORIG]) expands to ARG if it is not the ++dnl same as ORIG, otherwise to 0. ++m4_define([gl_LIBUNISTRING_ARG_OR_ZERO], [m4_if([$1], [$2], [0], [$1])]) +diff --git a/m4/localcharset.m4 b/m4/localcharset.m4 +index ee2e801..2e93e58 100644 +--- a/m4/localcharset.m4 ++++ b/m4/localcharset.m4 +@@ -1,5 +1,5 @@ + # localcharset.m4 serial 7 +-dnl Copyright (C) 2002, 2004, 2006, 2009, 2010 Free Software Foundation, Inc. ++dnl Copyright (C) 2002, 2004, 2006, 2009-2013 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. +diff --git a/m4/locale-fr.m4 b/m4/locale-fr.m4 +index 001f539..ef199e3 100644 +--- a/m4/locale-fr.m4 ++++ b/m4/locale-fr.m4 +@@ -1,5 +1,5 @@ +-# locale-fr.m4 serial 11 +-dnl Copyright (C) 2003, 2005-2010 Free Software Foundation, Inc. ++# locale-fr.m4 serial 17 ++dnl Copyright (C) 2003, 2005-2013 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. +@@ -25,17 +25,30 @@ struct tm t; + char buf[16]; + int main () { + /* Check whether the given locale name is recognized by the system. */ ++#if (defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__ ++ /* On native Windows, setlocale(category, "") looks at the system settings, ++ not at the environment variables. Also, when an encoding suffix such ++ as ".65001" or ".54936" is specified, it succeeds but sets the LC_CTYPE ++ category of the locale to "C". */ ++ if (setlocale (LC_ALL, getenv ("LC_ALL")) == NULL ++ || strcmp (setlocale (LC_CTYPE, NULL), "C") == 0) ++ return 1; ++#else + if (setlocale (LC_ALL, "") == NULL) return 1; ++#endif + /* Check whether nl_langinfo(CODESET) is nonempty and not "ASCII" or "646". +- On MacOS X 10.3.5 (Darwin 7.5) in the fr_FR locale, nl_langinfo(CODESET) ++ On Mac OS X 10.3.5 (Darwin 7.5) in the fr_FR locale, nl_langinfo(CODESET) + is empty, and the behaviour of Tcl 8.4 in this locale is not useful. + On OpenBSD 4.0, when an unsupported locale is specified, setlocale() + succeeds but then nl_langinfo(CODESET) is "646". In this situation, +- some unit tests fail. */ ++ some unit tests fail. ++ On MirBSD 10, when an unsupported locale is specified, setlocale() ++ succeeds but then nl_langinfo(CODESET) is "UTF-8". */ + #if HAVE_LANGINFO_CODESET + { + const char *cs = nl_langinfo (CODESET); +- if (cs[0] == '\0' || strcmp (cs, "ASCII") == 0 || strcmp (cs, "646") == 0) ++ if (cs[0] == '\0' || strcmp (cs, "ASCII") == 0 || strcmp (cs, "646") == 0 ++ || strcmp (cs, "UTF-8") == 0) + return 1; + } + #endif +@@ -50,46 +63,67 @@ int main () { + one byte long. This excludes the UTF-8 encoding. */ + t.tm_year = 1975 - 1900; t.tm_mon = 2 - 1; t.tm_mday = 4; + if (strftime (buf, sizeof (buf), "%b", &t) < 3 || buf[2] != 'v') return 1; ++#if !defined __BIONIC__ /* Bionic libc's 'struct lconv' is just a dummy. */ + /* Check whether the decimal separator is a comma. + On NetBSD 3.0 in the fr_FR.ISO8859-1 locale, localeconv()->decimal_point + are nl_langinfo(RADIXCHAR) are both ".". */ + if (localeconv () ->decimal_point[0] != ',') return 1; ++#endif + return 0; + } + changequote([,])dnl + ])]) + if AC_TRY_EVAL([ac_link]) && test -s conftest$ac_exeext; then +- # Setting LC_ALL is not enough. Need to set LC_TIME to empty, because +- # otherwise on MacOS X 10.3.5 the LC_TIME=C from the beginning of the +- # configure script would override the LC_ALL setting. Likewise for +- # LC_CTYPE, which is also set at the beginning of the configure script. +- # Test for the usual locale name. +- if (LC_ALL=fr_FR LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then +- gt_cv_locale_fr=fr_FR +- else +- # Test for the locale name with explicit encoding suffix. +- if (LC_ALL=fr_FR.ISO-8859-1 LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then +- gt_cv_locale_fr=fr_FR.ISO-8859-1 +- else +- # Test for the AIX, OSF/1, FreeBSD, NetBSD, OpenBSD locale name. +- if (LC_ALL=fr_FR.ISO8859-1 LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then +- gt_cv_locale_fr=fr_FR.ISO8859-1 ++ case "$host_os" in ++ # Handle native Windows specially, because there setlocale() interprets ++ # "ar" as "Arabic" or "Arabic_Saudi Arabia.1256", ++ # "fr" or "fra" as "French" or "French_France.1252", ++ # "ge"(!) or "deu"(!) as "German" or "German_Germany.1252", ++ # "ja" as "Japanese" or "Japanese_Japan.932", ++ # and similar. ++ mingw*) ++ # Test for the native Windows locale name. ++ if (LC_ALL=French_France.1252 LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then ++ gt_cv_locale_fr=French_France.1252 + else +- # Test for the HP-UX locale name. +- if (LC_ALL=fr_FR.iso88591 LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then +- gt_cv_locale_fr=fr_FR.iso88591 ++ # None found. ++ gt_cv_locale_fr=none ++ fi ++ ;; ++ *) ++ # Setting LC_ALL is not enough. Need to set LC_TIME to empty, because ++ # otherwise on Mac OS X 10.3.5 the LC_TIME=C from the beginning of the ++ # configure script would override the LC_ALL setting. Likewise for ++ # LC_CTYPE, which is also set at the beginning of the configure script. ++ # Test for the usual locale name. ++ if (LC_ALL=fr_FR LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then ++ gt_cv_locale_fr=fr_FR ++ else ++ # Test for the locale name with explicit encoding suffix. ++ if (LC_ALL=fr_FR.ISO-8859-1 LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then ++ gt_cv_locale_fr=fr_FR.ISO-8859-1 + else +- # Test for the Solaris 7 locale name. +- if (LC_ALL=fr LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then +- gt_cv_locale_fr=fr ++ # Test for the AIX, OSF/1, FreeBSD, NetBSD, OpenBSD locale name. ++ if (LC_ALL=fr_FR.ISO8859-1 LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then ++ gt_cv_locale_fr=fr_FR.ISO8859-1 + else +- # None found. +- gt_cv_locale_fr=none ++ # Test for the HP-UX locale name. ++ if (LC_ALL=fr_FR.iso88591 LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then ++ gt_cv_locale_fr=fr_FR.iso88591 ++ else ++ # Test for the Solaris 7 locale name. ++ if (LC_ALL=fr LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then ++ gt_cv_locale_fr=fr ++ else ++ # None found. ++ gt_cv_locale_fr=none ++ fi ++ fi + fi + fi + fi +- fi +- fi ++ ;; ++ esac + fi + rm -fr conftest* + ]) +@@ -119,9 +153,19 @@ int main () { + variables, and all locales use the UTF-8 encoding. */ + #if !(defined __BEOS__ || defined __HAIKU__) + /* Check whether the given locale name is recognized by the system. */ ++# if (defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__ ++ /* On native Windows, setlocale(category, "") looks at the system settings, ++ not at the environment variables. Also, when an encoding suffix such ++ as ".65001" or ".54936" is specified, it succeeds but sets the LC_CTYPE ++ category of the locale to "C". */ ++ if (setlocale (LC_ALL, getenv ("LC_ALL")) == NULL ++ || strcmp (setlocale (LC_CTYPE, NULL), "C") == 0) ++ return 1; ++# else + if (setlocale (LC_ALL, "") == NULL) return 1; ++# endif + /* Check whether nl_langinfo(CODESET) is nonempty and not "ASCII" or "646". +- On MacOS X 10.3.5 (Darwin 7.5) in the fr_FR locale, nl_langinfo(CODESET) ++ On Mac OS X 10.3.5 (Darwin 7.5) in the fr_FR locale, nl_langinfo(CODESET) + is empty, and the behaviour of Tcl 8.4 in this locale is not useful. + On OpenBSD 4.0, when an unsupported locale is specified, setlocale() + succeeds but then nl_langinfo(CODESET) is "646". In this situation, +@@ -147,36 +191,57 @@ int main () { + || buf[1] != (char) 0xc3 || buf[2] != (char) 0xa9 || buf[3] != 'v') + return 1; + #endif ++#if !defined __BIONIC__ /* Bionic libc's 'struct lconv' is just a dummy. */ + /* Check whether the decimal separator is a comma. + On NetBSD 3.0 in the fr_FR.ISO8859-1 locale, localeconv()->decimal_point + are nl_langinfo(RADIXCHAR) are both ".". */ + if (localeconv () ->decimal_point[0] != ',') return 1; ++#endif + return 0; + } + changequote([,])dnl + ])]) + if AC_TRY_EVAL([ac_link]) && test -s conftest$ac_exeext; then +- # Setting LC_ALL is not enough. Need to set LC_TIME to empty, because +- # otherwise on MacOS X 10.3.5 the LC_TIME=C from the beginning of the +- # configure script would override the LC_ALL setting. Likewise for +- # LC_CTYPE, which is also set at the beginning of the configure script. +- # Test for the usual locale name. +- if (LC_ALL=fr_FR LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then +- gt_cv_locale_fr_utf8=fr_FR +- else +- # Test for the locale name with explicit encoding suffix. +- if (LC_ALL=fr_FR.UTF-8 LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then +- gt_cv_locale_fr_utf8=fr_FR.UTF-8 +- else +- # Test for the Solaris 7 locale name. +- if (LC_ALL=fr.UTF-8 LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then +- gt_cv_locale_fr_utf8=fr.UTF-8 ++ case "$host_os" in ++ # Handle native Windows specially, because there setlocale() interprets ++ # "ar" as "Arabic" or "Arabic_Saudi Arabia.1256", ++ # "fr" or "fra" as "French" or "French_France.1252", ++ # "ge"(!) or "deu"(!) as "German" or "German_Germany.1252", ++ # "ja" as "Japanese" or "Japanese_Japan.932", ++ # and similar. ++ mingw*) ++ # Test for the hypothetical native Windows locale name. ++ if (LC_ALL=French_France.65001 LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then ++ gt_cv_locale_fr_utf8=French_France.65001 + else + # None found. + gt_cv_locale_fr_utf8=none + fi +- fi +- fi ++ ;; ++ *) ++ # Setting LC_ALL is not enough. Need to set LC_TIME to empty, because ++ # otherwise on Mac OS X 10.3.5 the LC_TIME=C from the beginning of the ++ # configure script would override the LC_ALL setting. Likewise for ++ # LC_CTYPE, which is also set at the beginning of the configure script. ++ # Test for the usual locale name. ++ if (LC_ALL=fr_FR LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then ++ gt_cv_locale_fr_utf8=fr_FR ++ else ++ # Test for the locale name with explicit encoding suffix. ++ if (LC_ALL=fr_FR.UTF-8 LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then ++ gt_cv_locale_fr_utf8=fr_FR.UTF-8 ++ else ++ # Test for the Solaris 7 locale name. ++ if (LC_ALL=fr.UTF-8 LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then ++ gt_cv_locale_fr_utf8=fr.UTF-8 ++ else ++ # None found. ++ gt_cv_locale_fr_utf8=none ++ fi ++ fi ++ fi ++ ;; ++ esac + fi + rm -fr conftest* + ]) +diff --git a/m4/locale-ja.m4 b/m4/locale-ja.m4 +index 0eedaf1..132a3e7 100644 +--- a/m4/locale-ja.m4 ++++ b/m4/locale-ja.m4 +@@ -1,5 +1,5 @@ +-# locale-ja.m4 serial 7 +-dnl Copyright (C) 2003, 2005-2010 Free Software Foundation, Inc. ++# locale-ja.m4 serial 12 ++dnl Copyright (C) 2003, 2005-2013 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. +@@ -27,17 +27,30 @@ int main () + { + const char *p; + /* Check whether the given locale name is recognized by the system. */ ++#if (defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__ ++ /* On native Windows, setlocale(category, "") looks at the system settings, ++ not at the environment variables. Also, when an encoding suffix such ++ as ".65001" or ".54936" is specified, it succeeds but sets the LC_CTYPE ++ category of the locale to "C". */ ++ if (setlocale (LC_ALL, getenv ("LC_ALL")) == NULL ++ || strcmp (setlocale (LC_CTYPE, NULL), "C") == 0) ++ return 1; ++#else + if (setlocale (LC_ALL, "") == NULL) return 1; ++#endif + /* Check whether nl_langinfo(CODESET) is nonempty and not "ASCII" or "646". +- On MacOS X 10.3.5 (Darwin 7.5) in the fr_FR locale, nl_langinfo(CODESET) ++ On Mac OS X 10.3.5 (Darwin 7.5) in the fr_FR locale, nl_langinfo(CODESET) + is empty, and the behaviour of Tcl 8.4 in this locale is not useful. + On OpenBSD 4.0, when an unsupported locale is specified, setlocale() + succeeds but then nl_langinfo(CODESET) is "646". In this situation, +- some unit tests fail. */ ++ some unit tests fail. ++ On MirBSD 10, when an unsupported locale is specified, setlocale() ++ succeeds but then nl_langinfo(CODESET) is "UTF-8". */ + #if HAVE_LANGINFO_CODESET + { + const char *cs = nl_langinfo (CODESET); +- if (cs[0] == '\0' || strcmp (cs, "ASCII") == 0 || strcmp (cs, "646") == 0) ++ if (cs[0] == '\0' || strcmp (cs, "ASCII") == 0 || strcmp (cs, "646") == 0 ++ || strcmp (cs, "UTF-8") == 0) + return 1; + } + #endif +@@ -52,7 +65,7 @@ int main () + if (MB_CUR_MAX == 1) + return 1; + /* Check whether in a month name, no byte in the range 0x80..0x9F occurs. +- This excludes the UTF-8 encoding. */ ++ This excludes the UTF-8 encoding (except on MirBSD). */ + t.tm_year = 1975 - 1900; t.tm_mon = 2 - 1; t.tm_mday = 4; + if (strftime (buf, sizeof (buf), "%B", &t) < 2) return 1; + for (p = buf; *p != '\0'; p++) +@@ -63,42 +76,58 @@ int main () + changequote([,])dnl + ])]) + if AC_TRY_EVAL([ac_link]) && test -s conftest$ac_exeext; then +- # Setting LC_ALL is not enough. Need to set LC_TIME to empty, because +- # otherwise on MacOS X 10.3.5 the LC_TIME=C from the beginning of the +- # configure script would override the LC_ALL setting. Likewise for +- # LC_CTYPE, which is also set at the beginning of the configure script. +- # Test for the AIX locale name. +- if (LC_ALL=ja_JP LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then +- gt_cv_locale_ja=ja_JP +- else +- # Test for the locale name with explicit encoding suffix. +- if (LC_ALL=ja_JP.EUC-JP LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then +- gt_cv_locale_ja=ja_JP.EUC-JP +- else +- # Test for the HP-UX, OSF/1, NetBSD locale name. +- if (LC_ALL=ja_JP.eucJP LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then +- gt_cv_locale_ja=ja_JP.eucJP ++ case "$host_os" in ++ # Handle native Windows specially, because there setlocale() interprets ++ # "ar" as "Arabic" or "Arabic_Saudi Arabia.1256", ++ # "fr" or "fra" as "French" or "French_France.1252", ++ # "ge"(!) or "deu"(!) as "German" or "German_Germany.1252", ++ # "ja" as "Japanese" or "Japanese_Japan.932", ++ # and similar. ++ mingw*) ++ # Note that on native Windows, the Japanese locale is ++ # Japanese_Japan.932, and CP932 is very different from EUC-JP, so we ++ # cannot use it here. ++ gt_cv_locale_ja=none ++ ;; ++ *) ++ # Setting LC_ALL is not enough. Need to set LC_TIME to empty, because ++ # otherwise on Mac OS X 10.3.5 the LC_TIME=C from the beginning of the ++ # configure script would override the LC_ALL setting. Likewise for ++ # LC_CTYPE, which is also set at the beginning of the configure script. ++ # Test for the AIX locale name. ++ if (LC_ALL=ja_JP LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then ++ gt_cv_locale_ja=ja_JP + else +- # Test for the IRIX, FreeBSD locale name. +- if (LC_ALL=ja_JP.EUC LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then +- gt_cv_locale_ja=ja_JP.EUC ++ # Test for the locale name with explicit encoding suffix. ++ if (LC_ALL=ja_JP.EUC-JP LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then ++ gt_cv_locale_ja=ja_JP.EUC-JP + else +- # Test for the Solaris 7 locale name. +- if (LC_ALL=ja LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then +- gt_cv_locale_ja=ja ++ # Test for the HP-UX, OSF/1, NetBSD locale name. ++ if (LC_ALL=ja_JP.eucJP LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then ++ gt_cv_locale_ja=ja_JP.eucJP + else +- # Special test for NetBSD 1.6. +- if test -f /usr/share/locale/ja_JP.eucJP/LC_CTYPE; then +- gt_cv_locale_ja=ja_JP.eucJP ++ # Test for the IRIX, FreeBSD locale name. ++ if (LC_ALL=ja_JP.EUC LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then ++ gt_cv_locale_ja=ja_JP.EUC + else +- # None found. +- gt_cv_locale_ja=none ++ # Test for the Solaris 7 locale name. ++ if (LC_ALL=ja LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then ++ gt_cv_locale_ja=ja ++ else ++ # Special test for NetBSD 1.6. ++ if test -f /usr/share/locale/ja_JP.eucJP/LC_CTYPE; then ++ gt_cv_locale_ja=ja_JP.eucJP ++ else ++ # None found. ++ gt_cv_locale_ja=none ++ fi ++ fi + fi + fi + fi + fi +- fi +- fi ++ ;; ++ esac + fi + rm -fr conftest* + ]) +diff --git a/m4/locale-zh.m4 b/m4/locale-zh.m4 +index 777fd14..4eed73f 100644 +--- a/m4/locale-zh.m4 ++++ b/m4/locale-zh.m4 +@@ -1,5 +1,5 @@ +-# locale-zh.m4 serial 6 +-dnl Copyright (C) 2003, 2005-2010 Free Software Foundation, Inc. ++# locale-zh.m4 serial 12 ++dnl Copyright (C) 2003, 2005-2013 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. +@@ -28,17 +28,30 @@ int main () + { + const char *p; + /* Check whether the given locale name is recognized by the system. */ ++#if (defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__ ++ /* On native Windows, setlocale(category, "") looks at the system settings, ++ not at the environment variables. Also, when an encoding suffix such ++ as ".65001" or ".54936" is specified, it succeeds but sets the LC_CTYPE ++ category of the locale to "C". */ ++ if (setlocale (LC_ALL, getenv ("LC_ALL")) == NULL ++ || strcmp (setlocale (LC_CTYPE, NULL), "C") == 0) ++ return 1; ++#else + if (setlocale (LC_ALL, "") == NULL) return 1; ++#endif + /* Check whether nl_langinfo(CODESET) is nonempty and not "ASCII" or "646". +- On MacOS X 10.3.5 (Darwin 7.5) in the fr_FR locale, nl_langinfo(CODESET) ++ On Mac OS X 10.3.5 (Darwin 7.5) in the fr_FR locale, nl_langinfo(CODESET) + is empty, and the behaviour of Tcl 8.4 in this locale is not useful. + On OpenBSD 4.0, when an unsupported locale is specified, setlocale() + succeeds but then nl_langinfo(CODESET) is "646". In this situation, +- some unit tests fail. */ ++ some unit tests fail. ++ On MirBSD 10, when an unsupported locale is specified, setlocale() ++ succeeds but then nl_langinfo(CODESET) is "UTF-8". */ + #if HAVE_LANGINFO_CODESET + { + const char *cs = nl_langinfo (CODESET); +- if (cs[0] == '\0' || strcmp (cs, "ASCII") == 0 || strcmp (cs, "646") == 0) ++ if (cs[0] == '\0' || strcmp (cs, "ASCII") == 0 || strcmp (cs, "646") == 0 ++ || strcmp (cs, "UTF-8") == 0) + return 1; + } + #endif +@@ -49,7 +62,7 @@ int main () + if (strchr (getenv ("LC_ALL"), '.') == NULL) return 1; + #endif + /* Check whether in a month name, no byte in the range 0x80..0x9F occurs. +- This excludes the UTF-8 encoding. */ ++ This excludes the UTF-8 encoding (except on MirBSD). */ + t.tm_year = 1975 - 1900; t.tm_mon = 2 - 1; t.tm_mday = 4; + if (strftime (buf, sizeof (buf), "%B", &t) < 2) return 1; + for (p = buf; *p != '\0'; p++) +@@ -64,22 +77,47 @@ int main () + changequote([,])dnl + ])]) + if AC_TRY_EVAL([ac_link]) && test -s conftest$ac_exeext; then +- # Setting LC_ALL is not enough. Need to set LC_TIME to empty, because +- # otherwise on MacOS X 10.3.5 the LC_TIME=C from the beginning of the +- # configure script would override the LC_ALL setting. Likewise for +- # LC_CTYPE, which is also set at the beginning of the configure script. +- # Test for the locale name without encoding suffix. +- if (LC_ALL=zh_CN LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then +- gt_cv_locale_zh_CN=zh_CN +- else +- # Test for the locale name with explicit encoding suffix. +- if (LC_ALL=zh_CN.GB18030 LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then +- gt_cv_locale_zh_CN=zh_CN.GB18030 +- else +- # None found. ++ case "$host_os" in ++ # Handle native Windows specially, because there setlocale() interprets ++ # "ar" as "Arabic" or "Arabic_Saudi Arabia.1256", ++ # "fr" or "fra" as "French" or "French_France.1252", ++ # "ge"(!) or "deu"(!) as "German" or "German_Germany.1252", ++ # "ja" as "Japanese" or "Japanese_Japan.932", ++ # and similar. ++ mingw*) ++ # Test for the hypothetical native Windows locale name. ++ if (LC_ALL=Chinese_China.54936 LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then ++ gt_cv_locale_zh_CN=Chinese_China.54936 ++ else ++ # None found. ++ gt_cv_locale_zh_CN=none ++ fi ++ ;; ++ solaris2.8) ++ # On Solaris 8, the locales zh_CN.GB18030, zh_CN.GBK, zh.GBK are ++ # broken. One witness is the test case in gl_MBRTOWC_SANITYCHECK. ++ # Another witness is that "LC_ALL=zh_CN.GB18030 bash -c true" dumps core. + gt_cv_locale_zh_CN=none +- fi +- fi ++ ;; ++ *) ++ # Setting LC_ALL is not enough. Need to set LC_TIME to empty, because ++ # otherwise on Mac OS X 10.3.5 the LC_TIME=C from the beginning of the ++ # configure script would override the LC_ALL setting. Likewise for ++ # LC_CTYPE, which is also set at the beginning of the configure script. ++ # Test for the locale name without encoding suffix. ++ if (LC_ALL=zh_CN LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then ++ gt_cv_locale_zh_CN=zh_CN ++ else ++ # Test for the locale name with explicit encoding suffix. ++ if (LC_ALL=zh_CN.GB18030 LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then ++ gt_cv_locale_zh_CN=zh_CN.GB18030 ++ else ++ # None found. ++ gt_cv_locale_zh_CN=none ++ fi ++ fi ++ ;; ++ esac + else + # If there was a link error, due to mblen(), the system is so old that + # it certainly doesn't have a chinese locale. +diff --git a/m4/locale_h.m4 b/m4/locale_h.m4 +new file mode 100644 +index 0000000..8bd12e8 +--- /dev/null ++++ b/m4/locale_h.m4 +@@ -0,0 +1,122 @@ ++# locale_h.m4 serial 19 ++dnl Copyright (C) 2007, 2009-2013 Free Software Foundation, Inc. ++dnl This file is free software; the Free Software Foundation ++dnl gives unlimited permission to copy and/or distribute it, ++dnl with or without modifications, as long as this notice is preserved. ++ ++AC_DEFUN([gl_LOCALE_H], ++[ ++ dnl Use AC_REQUIRE here, so that the default behavior below is expanded ++ dnl once only, before all statements that occur in other macros. ++ AC_REQUIRE([gl_LOCALE_H_DEFAULTS]) ++ ++ dnl Persuade glibc to define locale_t and the int_p_*, int_n_* ++ dnl members of 'struct lconv'. ++ AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) ++ ++ dnl If is replaced, then must also be replaced. ++ AC_REQUIRE([gl_STDDEF_H]) ++ ++ dnl Solaris 11 2011-11 defines the int_p_*, int_n_* members of 'struct lconv' ++ dnl only if _LCONV_C99 is defined. ++ AC_REQUIRE([AC_CANONICAL_HOST]) ++ case "$host_os" in ++ solaris*) ++ AC_DEFINE([_LCONV_C99], [1], [Define to 1 on Solaris.]) ++ ;; ++ esac ++ ++ AC_CACHE_CHECK([whether locale.h conforms to POSIX:2001], ++ [gl_cv_header_locale_h_posix2001], ++ [AC_COMPILE_IFELSE( ++ [AC_LANG_PROGRAM( ++ [[#include ++ int x = LC_MESSAGES; ++ int y = sizeof (((struct lconv *) 0)->decimal_point);]], ++ [[]])], ++ [gl_cv_header_locale_h_posix2001=yes], ++ [gl_cv_header_locale_h_posix2001=no])]) ++ ++ dnl Check for . ++ AC_CHECK_HEADERS_ONCE([xlocale.h]) ++ if test $ac_cv_header_xlocale_h = yes; then ++ HAVE_XLOCALE_H=1 ++ dnl Check whether use of locale_t requires inclusion of , ++ dnl e.g. on Mac OS X 10.5. If does not define locale_t by ++ dnl itself, we assume that will do so. ++ AC_CACHE_CHECK([whether locale.h defines locale_t], ++ [gl_cv_header_locale_has_locale_t], ++ [AC_COMPILE_IFELSE( ++ [AC_LANG_PROGRAM( ++ [[#include ++ locale_t x;]], ++ [[]])], ++ [gl_cv_header_locale_has_locale_t=yes], ++ [gl_cv_header_locale_has_locale_t=no]) ++ ]) ++ if test $gl_cv_header_locale_has_locale_t = yes; then ++ gl_cv_header_locale_h_needs_xlocale_h=no ++ else ++ gl_cv_header_locale_h_needs_xlocale_h=yes ++ fi ++ else ++ HAVE_XLOCALE_H=0 ++ gl_cv_header_locale_h_needs_xlocale_h=no ++ fi ++ AC_SUBST([HAVE_XLOCALE_H]) ++ ++ dnl Check whether 'struct lconv' is complete. ++ dnl Bionic libc's 'struct lconv' is just a dummy. ++ dnl On OpenBSD 4.9, HP-UX 11, IRIX 6.5, OSF/1 5.1, Solaris 9, Cygwin 1.5.x, ++ dnl mingw, MSVC 9, it lacks the int_p_* and int_n_* members. ++ AC_CACHE_CHECK([whether struct lconv is properly defined], ++ [gl_cv_sys_struct_lconv_ok], ++ [AC_COMPILE_IFELSE( ++ [AC_LANG_PROGRAM( ++ [[#include ++ struct lconv l; ++ int x = sizeof (l.decimal_point); ++ int y = sizeof (l.int_p_cs_precedes);]], ++ [[]])], ++ [gl_cv_sys_struct_lconv_ok=yes], ++ [gl_cv_sys_struct_lconv_ok=no]) ++ ]) ++ if test $gl_cv_sys_struct_lconv_ok = no; then ++ REPLACE_STRUCT_LCONV=1 ++ fi ++ ++ dnl is always overridden, because of GNULIB_POSIXCHECK. ++ gl_NEXT_HEADERS([locale.h]) ++ ++ dnl Check for declarations of anything we want to poison if the ++ dnl corresponding gnulib module is not in use. ++ gl_WARN_ON_USE_PREPARE([[#include ++/* Some systems provide declarations in a non-standard header. */ ++#if HAVE_XLOCALE_H ++# include ++#endif ++ ]], ++ [setlocale duplocale]) ++]) ++ ++AC_DEFUN([gl_LOCALE_MODULE_INDICATOR], ++[ ++ dnl Use AC_REQUIRE here, so that the default settings are expanded once only. ++ AC_REQUIRE([gl_LOCALE_H_DEFAULTS]) ++ gl_MODULE_INDICATOR_SET_VARIABLE([$1]) ++ dnl Define it also as a C macro, for the benefit of the unit tests. ++ gl_MODULE_INDICATOR_FOR_TESTS([$1]) ++]) ++ ++AC_DEFUN([gl_LOCALE_H_DEFAULTS], ++[ ++ GNULIB_LOCALECONV=0; AC_SUBST([GNULIB_LOCALECONV]) ++ GNULIB_SETLOCALE=0; AC_SUBST([GNULIB_SETLOCALE]) ++ GNULIB_DUPLOCALE=0; AC_SUBST([GNULIB_DUPLOCALE]) ++ dnl Assume proper GNU behavior unless another module says otherwise. ++ HAVE_DUPLOCALE=1; AC_SUBST([HAVE_DUPLOCALE]) ++ REPLACE_LOCALECONV=0; AC_SUBST([REPLACE_LOCALECONV]) ++ REPLACE_SETLOCALE=0; AC_SUBST([REPLACE_SETLOCALE]) ++ REPLACE_DUPLOCALE=0; AC_SUBST([REPLACE_DUPLOCALE]) ++ REPLACE_STRUCT_LCONV=0; AC_SUBST([REPLACE_STRUCT_LCONV]) ++]) +diff --git a/m4/localeconv.m4 b/m4/localeconv.m4 +new file mode 100644 +index 0000000..b8bb596 +--- /dev/null ++++ b/m4/localeconv.m4 +@@ -0,0 +1,22 @@ ++# localeconv.m4 serial 1 ++dnl Copyright (C) 2012-2013 Free Software Foundation, Inc. ++dnl This file is free software; the Free Software Foundation ++dnl gives unlimited permission to copy and/or distribute it, ++dnl with or without modifications, as long as this notice is preserved. ++ ++AC_DEFUN([gl_FUNC_LOCALECONV], ++[ ++ AC_REQUIRE([gl_LOCALE_H_DEFAULTS]) ++ AC_REQUIRE([gl_LOCALE_H]) ++ ++ if test $REPLACE_STRUCT_LCONV = 1; then ++ REPLACE_LOCALECONV=1 ++ fi ++]) ++ ++# Prerequisites of lib/localeconv.c. ++AC_DEFUN([gl_PREREQ_LOCALECONV], ++[ ++ AC_CHECK_MEMBERS([struct lconv.decimal_point], [], [], ++ [[#include ]]) ++]) +diff --git a/m4/lock.m4 b/m4/lock.m4 +index f71c664..d3fc1ef 100644 +--- a/m4/lock.m4 ++++ b/m4/lock.m4 +@@ -1,5 +1,5 @@ +-# lock.m4 serial 11 (gettext-0.18.2) +-dnl Copyright (C) 2005-2010 Free Software Foundation, Inc. ++# lock.m4 serial 13 (gettext-0.18.2) ++dnl Copyright (C) 2005-2013 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. +@@ -10,7 +10,7 @@ AC_DEFUN([gl_LOCK], + [ + AC_REQUIRE([gl_THREADLIB]) + if test "$gl_threads_api" = posix; then +- # OSF/1 4.0 and MacOS X 10.1 lack the pthread_rwlock_t type and the ++ # OSF/1 4.0 and Mac OS X 10.1 lack the pthread_rwlock_t type and the + # pthread_rwlock_* functions. + AC_CHECK_TYPE([pthread_rwlock_t], + [AC_DEFINE([HAVE_PTHREAD_RWLOCK], [1], +@@ -35,7 +35,5 @@ return !x; + gl_PREREQ_LOCK + ]) + +-# Prerequisites of lib/lock.c. +-AC_DEFUN([gl_PREREQ_LOCK], [ +- AC_REQUIRE([AC_C_INLINE]) +-]) ++# Prerequisites of lib/glthread/lock.c. ++AC_DEFUN([gl_PREREQ_LOCK], [:]) +diff --git a/m4/longlong.m4 b/m4/longlong.m4 +index cca3c1a..3af6ab5 100644 +--- a/m4/longlong.m4 ++++ b/m4/longlong.m4 +@@ -1,5 +1,5 @@ +-# longlong.m4 serial 14 +-dnl Copyright (C) 1999-2007, 2009-2010 Free Software Foundation, Inc. ++# longlong.m4 serial 17 ++dnl Copyright (C) 1999-2007, 2009-2013 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. +@@ -7,8 +7,8 @@ dnl with or without modifications, as long as this notice is preserved. + dnl From Paul Eggert. + + # Define HAVE_LONG_LONG_INT if 'long long int' works. +-# This fixes a bug in Autoconf 2.61, but can be removed once we +-# assume 2.62 everywhere. ++# This fixes a bug in Autoconf 2.61, and can be faster ++# than what's in Autoconf 2.62 through 2.68. + + # Note: If the type 'long long int' exists but is only 32 bits large + # (as on some very old compilers), HAVE_LONG_LONG_INT will not be +@@ -16,44 +16,48 @@ dnl From Paul Eggert. + + AC_DEFUN([AC_TYPE_LONG_LONG_INT], + [ ++ AC_REQUIRE([AC_TYPE_UNSIGNED_LONG_LONG_INT]) + AC_CACHE_CHECK([for long long int], [ac_cv_type_long_long_int], +- [AC_LINK_IFELSE( +- [_AC_TYPE_LONG_LONG_SNIPPET], +- [dnl This catches a bug in Tandem NonStop Kernel (OSS) cc -O circa 2004. +- dnl If cross compiling, assume the bug isn't important, since +- dnl nobody cross compiles for this platform as far as we know. +- AC_RUN_IFELSE( +- [AC_LANG_PROGRAM( +- [[@%:@include +- @%:@ifndef LLONG_MAX +- @%:@ define HALF \ +- (1LL << (sizeof (long long int) * CHAR_BIT - 2)) +- @%:@ define LLONG_MAX (HALF - 1 + HALF) +- @%:@endif]], +- [[long long int n = 1; +- int i; +- for (i = 0; ; i++) +- { +- long long int m = n << i; +- if (m >> i != n) +- return 1; +- if (LLONG_MAX / 2 < m) +- break; +- } +- return 0;]])], +- [ac_cv_type_long_long_int=yes], +- [ac_cv_type_long_long_int=no], +- [ac_cv_type_long_long_int=yes])], +- [ac_cv_type_long_long_int=no])]) ++ [ac_cv_type_long_long_int=yes ++ if test "x${ac_cv_prog_cc_c99-no}" = xno; then ++ ac_cv_type_long_long_int=$ac_cv_type_unsigned_long_long_int ++ if test $ac_cv_type_long_long_int = yes; then ++ dnl Catch a bug in Tandem NonStop Kernel (OSS) cc -O circa 2004. ++ dnl If cross compiling, assume the bug is not important, since ++ dnl nobody cross compiles for this platform as far as we know. ++ AC_RUN_IFELSE( ++ [AC_LANG_PROGRAM( ++ [[@%:@include ++ @%:@ifndef LLONG_MAX ++ @%:@ define HALF \ ++ (1LL << (sizeof (long long int) * CHAR_BIT - 2)) ++ @%:@ define LLONG_MAX (HALF - 1 + HALF) ++ @%:@endif]], ++ [[long long int n = 1; ++ int i; ++ for (i = 0; ; i++) ++ { ++ long long int m = n << i; ++ if (m >> i != n) ++ return 1; ++ if (LLONG_MAX / 2 < m) ++ break; ++ } ++ return 0;]])], ++ [], ++ [ac_cv_type_long_long_int=no], ++ [:]) ++ fi ++ fi]) + if test $ac_cv_type_long_long_int = yes; then + AC_DEFINE([HAVE_LONG_LONG_INT], [1], +- [Define to 1 if the system has the type `long long int'.]) ++ [Define to 1 if the system has the type 'long long int'.]) + fi + ]) + + # Define HAVE_UNSIGNED_LONG_LONG_INT if 'unsigned long long int' works. +-# This fixes a bug in Autoconf 2.61, but can be removed once we +-# assume 2.62 everywhere. ++# This fixes a bug in Autoconf 2.61, and can be faster ++# than what's in Autoconf 2.62 through 2.68. + + # Note: If the type 'unsigned long long int' exists but is only 32 bits + # large (as on some very old compilers), AC_TYPE_UNSIGNED_LONG_LONG_INT +@@ -64,13 +68,16 @@ AC_DEFUN([AC_TYPE_UNSIGNED_LONG_LONG_INT], + [ + AC_CACHE_CHECK([for unsigned long long int], + [ac_cv_type_unsigned_long_long_int], +- [AC_LINK_IFELSE( +- [_AC_TYPE_LONG_LONG_SNIPPET], +- [ac_cv_type_unsigned_long_long_int=yes], +- [ac_cv_type_unsigned_long_long_int=no])]) ++ [ac_cv_type_unsigned_long_long_int=yes ++ if test "x${ac_cv_prog_cc_c99-no}" = xno; then ++ AC_LINK_IFELSE( ++ [_AC_TYPE_LONG_LONG_SNIPPET], ++ [], ++ [ac_cv_type_unsigned_long_long_int=no]) ++ fi]) + if test $ac_cv_type_unsigned_long_long_int = yes; then + AC_DEFINE([HAVE_UNSIGNED_LONG_LONG_INT], [1], +- [Define to 1 if the system has the type `unsigned long long int'.]) ++ [Define to 1 if the system has the type 'unsigned long long int'.]) + fi + ]) + +diff --git a/m4/malloc.m4 b/m4/malloc.m4 +index 7a74925..4b24a0b 100644 +--- a/m4/malloc.m4 ++++ b/m4/malloc.m4 +@@ -1,9 +1,47 @@ +-# malloc.m4 serial 12 +-dnl Copyright (C) 2007, 2009, 2010 Free Software Foundation, Inc. ++# malloc.m4 serial 14 ++dnl Copyright (C) 2007, 2009-2013 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. + ++m4_version_prereq([2.70], [] ,[ ++ ++# This is taken from the following Autoconf patch: ++# http://git.savannah.gnu.org/gitweb/?p=autoconf.git;a=commitdiff;h=7fbb553727ed7e0e689a17594b58559ecf3ea6e9 ++AC_DEFUN([_AC_FUNC_MALLOC_IF], ++[ ++ AC_REQUIRE([AC_HEADER_STDC])dnl ++ AC_REQUIRE([AC_CANONICAL_HOST])dnl for cross-compiles ++ AC_CHECK_HEADERS([stdlib.h]) ++ AC_CACHE_CHECK([for GNU libc compatible malloc], ++ [ac_cv_func_malloc_0_nonnull], ++ [AC_RUN_IFELSE( ++ [AC_LANG_PROGRAM( ++ [[#if defined STDC_HEADERS || defined HAVE_STDLIB_H ++ # include ++ #else ++ char *malloc (); ++ #endif ++ ]], ++ [[return ! malloc (0);]]) ++ ], ++ [ac_cv_func_malloc_0_nonnull=yes], ++ [ac_cv_func_malloc_0_nonnull=no], ++ [case "$host_os" in ++ # Guess yes on platforms where we know the result. ++ *-gnu* | freebsd* | netbsd* | openbsd* \ ++ | hpux* | solaris* | cygwin* | mingw*) ++ ac_cv_func_malloc_0_nonnull=yes ;; ++ # If we don't know, assume the worst. ++ *) ac_cv_func_malloc_0_nonnull=no ;; ++ esac ++ ]) ++ ]) ++ AS_IF([test $ac_cv_func_malloc_0_nonnull = yes], [$1], [$2]) ++])# _AC_FUNC_MALLOC_IF ++ ++]) ++ + # gl_FUNC_MALLOC_GNU + # ------------------ + # Test whether 'malloc (0)' is handled like in GNU libc, and replace malloc if +@@ -17,7 +55,7 @@ AC_DEFUN([gl_FUNC_MALLOC_GNU], + [Define to 1 if your system has a GNU libc compatible 'malloc' + function, and to 0 otherwise.])], + [AC_DEFINE([HAVE_MALLOC_GNU], [0]) +- gl_REPLACE_MALLOC ++ REPLACE_MALLOC=1 + ]) + ]) + +@@ -33,7 +71,7 @@ AC_DEFUN([gl_FUNC_MALLOC_POSIX], + AC_DEFINE([HAVE_MALLOC_POSIX], [1], + [Define if the 'malloc' function is POSIX compliant.]) + else +- gl_REPLACE_MALLOC ++ REPLACE_MALLOC=1 + fi + ]) + +@@ -58,9 +96,3 @@ AC_DEFUN([gl_CHECK_MALLOC_POSIX], + [gl_cv_func_malloc_posix=no]) + ]) + ]) +- +-AC_DEFUN([gl_REPLACE_MALLOC], +-[ +- AC_LIBOBJ([malloc]) +- REPLACE_MALLOC=1 +-]) +diff --git a/m4/math_h.m4 b/m4/math_h.m4 +new file mode 100644 +index 0000000..bf0845f +--- /dev/null ++++ b/m4/math_h.m4 +@@ -0,0 +1,353 @@ ++# math_h.m4 serial 114 ++dnl Copyright (C) 2007-2013 Free Software Foundation, Inc. ++dnl This file is free software; the Free Software Foundation ++dnl gives unlimited permission to copy and/or distribute it, ++dnl with or without modifications, as long as this notice is preserved. ++ ++AC_DEFUN([gl_MATH_H], ++[ ++ AC_REQUIRE([gl_MATH_H_DEFAULTS]) ++ gl_CHECK_NEXT_HEADERS([math.h]) ++ ++ AC_CACHE_CHECK([whether NAN macro works], [gl_cv_header_math_nan_works], ++ [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include ]], ++ [[/* Solaris 10 has a broken definition of NAN. Other platforms ++ fail to provide NAN, or provide it only in C99 mode; this ++ test only needs to fail when NAN is provided but wrong. */ ++ float f = 1.0f; ++#ifdef NAN ++ f = NAN; ++#endif ++ return f == 0;]])], ++ [gl_cv_header_math_nan_works=yes], ++ [gl_cv_header_math_nan_works=no])]) ++ if test $gl_cv_header_math_nan_works = no; then ++ REPLACE_NAN=1 ++ fi ++ AC_CACHE_CHECK([whether HUGE_VAL works], [gl_cv_header_math_huge_val_works], ++ [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include ]], ++ [[/* Solaris 10 has a broken definition of HUGE_VAL. */ ++ double d = HUGE_VAL; ++ return d == 0;]])], ++ [gl_cv_header_math_huge_val_works=yes], ++ [gl_cv_header_math_huge_val_works=no])]) ++ if test $gl_cv_header_math_huge_val_works = no; then ++ REPLACE_HUGE_VAL=1 ++ fi ++ ++ dnl Check for declarations of anything we want to poison if the ++ dnl corresponding gnulib module is not in use. ++ gl_WARN_ON_USE_PREPARE([[#include ]], ++ [acosf acosl asinf asinl atanf atanl ++ cbrt cbrtf cbrtl ceilf ceill copysign copysignf copysignl cosf cosl coshf ++ expf expl exp2 exp2f exp2l expm1 expm1f expm1l ++ fabsf fabsl floorf floorl fma fmaf fmal ++ fmod fmodf fmodl frexpf frexpl hypotf hypotl ++ ilogb ilogbf ilogbl ++ ldexpf ldexpl ++ log logf logl log10 log10f log10l log1p log1pf log1pl log2 log2f log2l ++ logb logbf logbl ++ modf modff modfl powf ++ remainder remainderf remainderl ++ rint rintf rintl round roundf roundl sinf sinl sinhf sqrtf sqrtl ++ tanf tanl tanhf trunc truncf truncl]) ++]) ++ ++AC_DEFUN([gl_MATH_MODULE_INDICATOR], ++[ ++ dnl Use AC_REQUIRE here, so that the default settings are expanded once only. ++ AC_REQUIRE([gl_MATH_H_DEFAULTS]) ++ gl_MODULE_INDICATOR_SET_VARIABLE([$1]) ++ dnl Define it also as a C macro, for the benefit of the unit tests. ++ gl_MODULE_INDICATOR_FOR_TESTS([$1]) ++]) ++ ++AC_DEFUN([gl_MATH_H_DEFAULTS], ++[ ++ GNULIB_ACOSF=0; AC_SUBST([GNULIB_ACOSF]) ++ GNULIB_ACOSL=0; AC_SUBST([GNULIB_ACOSL]) ++ GNULIB_ASINF=0; AC_SUBST([GNULIB_ASINF]) ++ GNULIB_ASINL=0; AC_SUBST([GNULIB_ASINL]) ++ GNULIB_ATANF=0; AC_SUBST([GNULIB_ATANF]) ++ GNULIB_ATANL=0; AC_SUBST([GNULIB_ATANL]) ++ GNULIB_ATAN2F=0; AC_SUBST([GNULIB_ATAN2F]) ++ GNULIB_CBRT=0; AC_SUBST([GNULIB_CBRT]) ++ GNULIB_CBRTF=0; AC_SUBST([GNULIB_CBRTF]) ++ GNULIB_CBRTL=0; AC_SUBST([GNULIB_CBRTL]) ++ GNULIB_CEIL=0; AC_SUBST([GNULIB_CEIL]) ++ GNULIB_CEILF=0; AC_SUBST([GNULIB_CEILF]) ++ GNULIB_CEILL=0; AC_SUBST([GNULIB_CEILL]) ++ GNULIB_COPYSIGN=0; AC_SUBST([GNULIB_COPYSIGN]) ++ GNULIB_COPYSIGNF=0; AC_SUBST([GNULIB_COPYSIGNF]) ++ GNULIB_COPYSIGNL=0; AC_SUBST([GNULIB_COPYSIGNL]) ++ GNULIB_COSF=0; AC_SUBST([GNULIB_COSF]) ++ GNULIB_COSL=0; AC_SUBST([GNULIB_COSL]) ++ GNULIB_COSHF=0; AC_SUBST([GNULIB_COSHF]) ++ GNULIB_EXPF=0; AC_SUBST([GNULIB_EXPF]) ++ GNULIB_EXPL=0; AC_SUBST([GNULIB_EXPL]) ++ GNULIB_EXP2=0; AC_SUBST([GNULIB_EXP2]) ++ GNULIB_EXP2F=0; AC_SUBST([GNULIB_EXP2F]) ++ GNULIB_EXP2L=0; AC_SUBST([GNULIB_EXP2L]) ++ GNULIB_EXPM1=0; AC_SUBST([GNULIB_EXPM1]) ++ GNULIB_EXPM1F=0; AC_SUBST([GNULIB_EXPM1F]) ++ GNULIB_EXPM1L=0; AC_SUBST([GNULIB_EXPM1L]) ++ GNULIB_FABSF=0; AC_SUBST([GNULIB_FABSF]) ++ GNULIB_FABSL=0; AC_SUBST([GNULIB_FABSL]) ++ GNULIB_FLOOR=0; AC_SUBST([GNULIB_FLOOR]) ++ GNULIB_FLOORF=0; AC_SUBST([GNULIB_FLOORF]) ++ GNULIB_FLOORL=0; AC_SUBST([GNULIB_FLOORL]) ++ GNULIB_FMA=0; AC_SUBST([GNULIB_FMA]) ++ GNULIB_FMAF=0; AC_SUBST([GNULIB_FMAF]) ++ GNULIB_FMAL=0; AC_SUBST([GNULIB_FMAL]) ++ GNULIB_FMOD=0; AC_SUBST([GNULIB_FMOD]) ++ GNULIB_FMODF=0; AC_SUBST([GNULIB_FMODF]) ++ GNULIB_FMODL=0; AC_SUBST([GNULIB_FMODL]) ++ GNULIB_FREXPF=0; AC_SUBST([GNULIB_FREXPF]) ++ GNULIB_FREXP=0; AC_SUBST([GNULIB_FREXP]) ++ GNULIB_FREXPL=0; AC_SUBST([GNULIB_FREXPL]) ++ GNULIB_HYPOT=0; AC_SUBST([GNULIB_HYPOT]) ++ GNULIB_HYPOTF=0; AC_SUBST([GNULIB_HYPOTF]) ++ GNULIB_HYPOTL=0; AC_SUBST([GNULIB_HYPOTL]) ++ GNULIB_ILOGB=0; AC_SUBST([GNULIB_ILOGB]) ++ GNULIB_ILOGBF=0; AC_SUBST([GNULIB_ILOGBF]) ++ GNULIB_ILOGBL=0; AC_SUBST([GNULIB_ILOGBL]) ++ GNULIB_ISFINITE=0; AC_SUBST([GNULIB_ISFINITE]) ++ GNULIB_ISINF=0; AC_SUBST([GNULIB_ISINF]) ++ GNULIB_ISNAN=0; AC_SUBST([GNULIB_ISNAN]) ++ GNULIB_ISNANF=0; AC_SUBST([GNULIB_ISNANF]) ++ GNULIB_ISNAND=0; AC_SUBST([GNULIB_ISNAND]) ++ GNULIB_ISNANL=0; AC_SUBST([GNULIB_ISNANL]) ++ GNULIB_LDEXPF=0; AC_SUBST([GNULIB_LDEXPF]) ++ GNULIB_LDEXPL=0; AC_SUBST([GNULIB_LDEXPL]) ++ GNULIB_LOG=0; AC_SUBST([GNULIB_LOG]) ++ GNULIB_LOGF=0; AC_SUBST([GNULIB_LOGF]) ++ GNULIB_LOGL=0; AC_SUBST([GNULIB_LOGL]) ++ GNULIB_LOG10=0; AC_SUBST([GNULIB_LOG10]) ++ GNULIB_LOG10F=0; AC_SUBST([GNULIB_LOG10F]) ++ GNULIB_LOG10L=0; AC_SUBST([GNULIB_LOG10L]) ++ GNULIB_LOG1P=0; AC_SUBST([GNULIB_LOG1P]) ++ GNULIB_LOG1PF=0; AC_SUBST([GNULIB_LOG1PF]) ++ GNULIB_LOG1PL=0; AC_SUBST([GNULIB_LOG1PL]) ++ GNULIB_LOG2=0; AC_SUBST([GNULIB_LOG2]) ++ GNULIB_LOG2F=0; AC_SUBST([GNULIB_LOG2F]) ++ GNULIB_LOG2L=0; AC_SUBST([GNULIB_LOG2L]) ++ GNULIB_LOGB=0; AC_SUBST([GNULIB_LOGB]) ++ GNULIB_LOGBF=0; AC_SUBST([GNULIB_LOGBF]) ++ GNULIB_LOGBL=0; AC_SUBST([GNULIB_LOGBL]) ++ GNULIB_MODF=0; AC_SUBST([GNULIB_MODF]) ++ GNULIB_MODFF=0; AC_SUBST([GNULIB_MODFF]) ++ GNULIB_MODFL=0; AC_SUBST([GNULIB_MODFL]) ++ GNULIB_POWF=0; AC_SUBST([GNULIB_POWF]) ++ GNULIB_REMAINDER=0; AC_SUBST([GNULIB_REMAINDER]) ++ GNULIB_REMAINDERF=0; AC_SUBST([GNULIB_REMAINDERF]) ++ GNULIB_REMAINDERL=0; AC_SUBST([GNULIB_REMAINDERL]) ++ GNULIB_RINT=0; AC_SUBST([GNULIB_RINT]) ++ GNULIB_RINTF=0; AC_SUBST([GNULIB_RINTF]) ++ GNULIB_RINTL=0; AC_SUBST([GNULIB_RINTL]) ++ GNULIB_ROUND=0; AC_SUBST([GNULIB_ROUND]) ++ GNULIB_ROUNDF=0; AC_SUBST([GNULIB_ROUNDF]) ++ GNULIB_ROUNDL=0; AC_SUBST([GNULIB_ROUNDL]) ++ GNULIB_SIGNBIT=0; AC_SUBST([GNULIB_SIGNBIT]) ++ GNULIB_SINF=0; AC_SUBST([GNULIB_SINF]) ++ GNULIB_SINL=0; AC_SUBST([GNULIB_SINL]) ++ GNULIB_SINHF=0; AC_SUBST([GNULIB_SINHF]) ++ GNULIB_SQRTF=0; AC_SUBST([GNULIB_SQRTF]) ++ GNULIB_SQRTL=0; AC_SUBST([GNULIB_SQRTL]) ++ GNULIB_TANF=0; AC_SUBST([GNULIB_TANF]) ++ GNULIB_TANL=0; AC_SUBST([GNULIB_TANL]) ++ GNULIB_TANHF=0; AC_SUBST([GNULIB_TANHF]) ++ GNULIB_TRUNC=0; AC_SUBST([GNULIB_TRUNC]) ++ GNULIB_TRUNCF=0; AC_SUBST([GNULIB_TRUNCF]) ++ GNULIB_TRUNCL=0; AC_SUBST([GNULIB_TRUNCL]) ++ dnl Assume proper GNU behavior unless another module says otherwise. ++ HAVE_ACOSF=1; AC_SUBST([HAVE_ACOSF]) ++ HAVE_ACOSL=1; AC_SUBST([HAVE_ACOSL]) ++ HAVE_ASINF=1; AC_SUBST([HAVE_ASINF]) ++ HAVE_ASINL=1; AC_SUBST([HAVE_ASINL]) ++ HAVE_ATANF=1; AC_SUBST([HAVE_ATANF]) ++ HAVE_ATANL=1; AC_SUBST([HAVE_ATANL]) ++ HAVE_ATAN2F=1; AC_SUBST([HAVE_ATAN2F]) ++ HAVE_CBRT=1; AC_SUBST([HAVE_CBRT]) ++ HAVE_CBRTF=1; AC_SUBST([HAVE_CBRTF]) ++ HAVE_CBRTL=1; AC_SUBST([HAVE_CBRTL]) ++ HAVE_COPYSIGN=1; AC_SUBST([HAVE_COPYSIGN]) ++ HAVE_COPYSIGNL=1; AC_SUBST([HAVE_COPYSIGNL]) ++ HAVE_COSF=1; AC_SUBST([HAVE_COSF]) ++ HAVE_COSL=1; AC_SUBST([HAVE_COSL]) ++ HAVE_COSHF=1; AC_SUBST([HAVE_COSHF]) ++ HAVE_EXPF=1; AC_SUBST([HAVE_EXPF]) ++ HAVE_EXPL=1; AC_SUBST([HAVE_EXPL]) ++ HAVE_EXPM1=1; AC_SUBST([HAVE_EXPM1]) ++ HAVE_EXPM1F=1; AC_SUBST([HAVE_EXPM1F]) ++ HAVE_FABSF=1; AC_SUBST([HAVE_FABSF]) ++ HAVE_FABSL=1; AC_SUBST([HAVE_FABSL]) ++ HAVE_FMA=1; AC_SUBST([HAVE_FMA]) ++ HAVE_FMAF=1; AC_SUBST([HAVE_FMAF]) ++ HAVE_FMAL=1; AC_SUBST([HAVE_FMAL]) ++ HAVE_FMODF=1; AC_SUBST([HAVE_FMODF]) ++ HAVE_FMODL=1; AC_SUBST([HAVE_FMODL]) ++ HAVE_FREXPF=1; AC_SUBST([HAVE_FREXPF]) ++ HAVE_HYPOTF=1; AC_SUBST([HAVE_HYPOTF]) ++ HAVE_HYPOTL=1; AC_SUBST([HAVE_HYPOTL]) ++ HAVE_ILOGB=1; AC_SUBST([HAVE_ILOGB]) ++ HAVE_ILOGBF=1; AC_SUBST([HAVE_ILOGBF]) ++ HAVE_ILOGBL=1; AC_SUBST([HAVE_ILOGBL]) ++ HAVE_ISNANF=1; AC_SUBST([HAVE_ISNANF]) ++ HAVE_ISNAND=1; AC_SUBST([HAVE_ISNAND]) ++ HAVE_ISNANL=1; AC_SUBST([HAVE_ISNANL]) ++ HAVE_LDEXPF=1; AC_SUBST([HAVE_LDEXPF]) ++ HAVE_LOGF=1; AC_SUBST([HAVE_LOGF]) ++ HAVE_LOGL=1; AC_SUBST([HAVE_LOGL]) ++ HAVE_LOG10F=1; AC_SUBST([HAVE_LOG10F]) ++ HAVE_LOG10L=1; AC_SUBST([HAVE_LOG10L]) ++ HAVE_LOG1P=1; AC_SUBST([HAVE_LOG1P]) ++ HAVE_LOG1PF=1; AC_SUBST([HAVE_LOG1PF]) ++ HAVE_LOG1PL=1; AC_SUBST([HAVE_LOG1PL]) ++ HAVE_LOGBF=1; AC_SUBST([HAVE_LOGBF]) ++ HAVE_LOGBL=1; AC_SUBST([HAVE_LOGBL]) ++ HAVE_MODFF=1; AC_SUBST([HAVE_MODFF]) ++ HAVE_MODFL=1; AC_SUBST([HAVE_MODFL]) ++ HAVE_POWF=1; AC_SUBST([HAVE_POWF]) ++ HAVE_REMAINDER=1; AC_SUBST([HAVE_REMAINDER]) ++ HAVE_REMAINDERF=1; AC_SUBST([HAVE_REMAINDERF]) ++ HAVE_RINT=1; AC_SUBST([HAVE_RINT]) ++ HAVE_RINTL=1; AC_SUBST([HAVE_RINTL]) ++ HAVE_SINF=1; AC_SUBST([HAVE_SINF]) ++ HAVE_SINL=1; AC_SUBST([HAVE_SINL]) ++ HAVE_SINHF=1; AC_SUBST([HAVE_SINHF]) ++ HAVE_SQRTF=1; AC_SUBST([HAVE_SQRTF]) ++ HAVE_SQRTL=1; AC_SUBST([HAVE_SQRTL]) ++ HAVE_TANF=1; AC_SUBST([HAVE_TANF]) ++ HAVE_TANL=1; AC_SUBST([HAVE_TANL]) ++ HAVE_TANHF=1; AC_SUBST([HAVE_TANHF]) ++ HAVE_DECL_ACOSL=1; AC_SUBST([HAVE_DECL_ACOSL]) ++ HAVE_DECL_ASINL=1; AC_SUBST([HAVE_DECL_ASINL]) ++ HAVE_DECL_ATANL=1; AC_SUBST([HAVE_DECL_ATANL]) ++ HAVE_DECL_CBRTF=1; AC_SUBST([HAVE_DECL_CBRTF]) ++ HAVE_DECL_CBRTL=1; AC_SUBST([HAVE_DECL_CBRTL]) ++ HAVE_DECL_CEILF=1; AC_SUBST([HAVE_DECL_CEILF]) ++ HAVE_DECL_CEILL=1; AC_SUBST([HAVE_DECL_CEILL]) ++ HAVE_DECL_COPYSIGNF=1; AC_SUBST([HAVE_DECL_COPYSIGNF]) ++ HAVE_DECL_COSL=1; AC_SUBST([HAVE_DECL_COSL]) ++ HAVE_DECL_EXPL=1; AC_SUBST([HAVE_DECL_EXPL]) ++ HAVE_DECL_EXP2=1; AC_SUBST([HAVE_DECL_EXP2]) ++ HAVE_DECL_EXP2F=1; AC_SUBST([HAVE_DECL_EXP2F]) ++ HAVE_DECL_EXP2L=1; AC_SUBST([HAVE_DECL_EXP2L]) ++ HAVE_DECL_EXPM1L=1; AC_SUBST([HAVE_DECL_EXPM1L]) ++ HAVE_DECL_FLOORF=1; AC_SUBST([HAVE_DECL_FLOORF]) ++ HAVE_DECL_FLOORL=1; AC_SUBST([HAVE_DECL_FLOORL]) ++ HAVE_DECL_FREXPL=1; AC_SUBST([HAVE_DECL_FREXPL]) ++ HAVE_DECL_LDEXPL=1; AC_SUBST([HAVE_DECL_LDEXPL]) ++ HAVE_DECL_LOGL=1; AC_SUBST([HAVE_DECL_LOGL]) ++ HAVE_DECL_LOG10L=1; AC_SUBST([HAVE_DECL_LOG10L]) ++ HAVE_DECL_LOG2=1; AC_SUBST([HAVE_DECL_LOG2]) ++ HAVE_DECL_LOG2F=1; AC_SUBST([HAVE_DECL_LOG2F]) ++ HAVE_DECL_LOG2L=1; AC_SUBST([HAVE_DECL_LOG2L]) ++ HAVE_DECL_LOGB=1; AC_SUBST([HAVE_DECL_LOGB]) ++ HAVE_DECL_REMAINDER=1; AC_SUBST([HAVE_DECL_REMAINDER]) ++ HAVE_DECL_REMAINDERL=1; AC_SUBST([HAVE_DECL_REMAINDERL]) ++ HAVE_DECL_RINTF=1; AC_SUBST([HAVE_DECL_RINTF]) ++ HAVE_DECL_ROUND=1; AC_SUBST([HAVE_DECL_ROUND]) ++ HAVE_DECL_ROUNDF=1; AC_SUBST([HAVE_DECL_ROUNDF]) ++ HAVE_DECL_ROUNDL=1; AC_SUBST([HAVE_DECL_ROUNDL]) ++ HAVE_DECL_SINL=1; AC_SUBST([HAVE_DECL_SINL]) ++ HAVE_DECL_SQRTL=1; AC_SUBST([HAVE_DECL_SQRTL]) ++ HAVE_DECL_TANL=1; AC_SUBST([HAVE_DECL_TANL]) ++ HAVE_DECL_TRUNC=1; AC_SUBST([HAVE_DECL_TRUNC]) ++ HAVE_DECL_TRUNCF=1; AC_SUBST([HAVE_DECL_TRUNCF]) ++ HAVE_DECL_TRUNCL=1; AC_SUBST([HAVE_DECL_TRUNCL]) ++ REPLACE_CBRTF=0; AC_SUBST([REPLACE_CBRTF]) ++ REPLACE_CBRTL=0; AC_SUBST([REPLACE_CBRTL]) ++ REPLACE_CEIL=0; AC_SUBST([REPLACE_CEIL]) ++ REPLACE_CEILF=0; AC_SUBST([REPLACE_CEILF]) ++ REPLACE_CEILL=0; AC_SUBST([REPLACE_CEILL]) ++ REPLACE_EXPM1=0; AC_SUBST([REPLACE_EXPM1]) ++ REPLACE_EXPM1F=0; AC_SUBST([REPLACE_EXPM1F]) ++ REPLACE_EXP2=0; AC_SUBST([REPLACE_EXP2]) ++ REPLACE_EXP2L=0; AC_SUBST([REPLACE_EXP2L]) ++ REPLACE_FABSL=0; AC_SUBST([REPLACE_FABSL]) ++ REPLACE_FLOOR=0; AC_SUBST([REPLACE_FLOOR]) ++ REPLACE_FLOORF=0; AC_SUBST([REPLACE_FLOORF]) ++ REPLACE_FLOORL=0; AC_SUBST([REPLACE_FLOORL]) ++ REPLACE_FMA=0; AC_SUBST([REPLACE_FMA]) ++ REPLACE_FMAF=0; AC_SUBST([REPLACE_FMAF]) ++ REPLACE_FMAL=0; AC_SUBST([REPLACE_FMAL]) ++ REPLACE_FMOD=0; AC_SUBST([REPLACE_FMOD]) ++ REPLACE_FMODF=0; AC_SUBST([REPLACE_FMODF]) ++ REPLACE_FMODL=0; AC_SUBST([REPLACE_FMODL]) ++ REPLACE_FREXPF=0; AC_SUBST([REPLACE_FREXPF]) ++ REPLACE_FREXP=0; AC_SUBST([REPLACE_FREXP]) ++ REPLACE_FREXPL=0; AC_SUBST([REPLACE_FREXPL]) ++ REPLACE_HUGE_VAL=0; AC_SUBST([REPLACE_HUGE_VAL]) ++ REPLACE_HYPOT=0; AC_SUBST([REPLACE_HYPOT]) ++ REPLACE_HYPOTF=0; AC_SUBST([REPLACE_HYPOTF]) ++ REPLACE_HYPOTL=0; AC_SUBST([REPLACE_HYPOTL]) ++ REPLACE_ILOGB=0; AC_SUBST([REPLACE_ILOGB]) ++ REPLACE_ILOGBF=0; AC_SUBST([REPLACE_ILOGBF]) ++ REPLACE_ISFINITE=0; AC_SUBST([REPLACE_ISFINITE]) ++ REPLACE_ISINF=0; AC_SUBST([REPLACE_ISINF]) ++ REPLACE_ISNAN=0; AC_SUBST([REPLACE_ISNAN]) ++ REPLACE_LDEXPL=0; AC_SUBST([REPLACE_LDEXPL]) ++ REPLACE_LOG=0; AC_SUBST([REPLACE_LOG]) ++ REPLACE_LOGF=0; AC_SUBST([REPLACE_LOGF]) ++ REPLACE_LOGL=0; AC_SUBST([REPLACE_LOGL]) ++ REPLACE_LOG10=0; AC_SUBST([REPLACE_LOG10]) ++ REPLACE_LOG10F=0; AC_SUBST([REPLACE_LOG10F]) ++ REPLACE_LOG10L=0; AC_SUBST([REPLACE_LOG10L]) ++ REPLACE_LOG1P=0; AC_SUBST([REPLACE_LOG1P]) ++ REPLACE_LOG1PF=0; AC_SUBST([REPLACE_LOG1PF]) ++ REPLACE_LOG1PL=0; AC_SUBST([REPLACE_LOG1PL]) ++ REPLACE_LOG2=0; AC_SUBST([REPLACE_LOG2]) ++ REPLACE_LOG2F=0; AC_SUBST([REPLACE_LOG2F]) ++ REPLACE_LOG2L=0; AC_SUBST([REPLACE_LOG2L]) ++ REPLACE_LOGB=0; AC_SUBST([REPLACE_LOGB]) ++ REPLACE_LOGBF=0; AC_SUBST([REPLACE_LOGBF]) ++ REPLACE_LOGBL=0; AC_SUBST([REPLACE_LOGBL]) ++ REPLACE_MODF=0; AC_SUBST([REPLACE_MODF]) ++ REPLACE_MODFF=0; AC_SUBST([REPLACE_MODFF]) ++ REPLACE_MODFL=0; AC_SUBST([REPLACE_MODFL]) ++ REPLACE_NAN=0; AC_SUBST([REPLACE_NAN]) ++ REPLACE_REMAINDER=0; AC_SUBST([REPLACE_REMAINDER]) ++ REPLACE_REMAINDERF=0; AC_SUBST([REPLACE_REMAINDERF]) ++ REPLACE_REMAINDERL=0; AC_SUBST([REPLACE_REMAINDERL]) ++ REPLACE_ROUND=0; AC_SUBST([REPLACE_ROUND]) ++ REPLACE_ROUNDF=0; AC_SUBST([REPLACE_ROUNDF]) ++ REPLACE_ROUNDL=0; AC_SUBST([REPLACE_ROUNDL]) ++ REPLACE_SIGNBIT=0; AC_SUBST([REPLACE_SIGNBIT]) ++ REPLACE_SIGNBIT_USING_GCC=0; AC_SUBST([REPLACE_SIGNBIT_USING_GCC]) ++ REPLACE_SQRTL=0; AC_SUBST([REPLACE_SQRTL]) ++ REPLACE_TRUNC=0; AC_SUBST([REPLACE_TRUNC]) ++ REPLACE_TRUNCF=0; AC_SUBST([REPLACE_TRUNCF]) ++ REPLACE_TRUNCL=0; AC_SUBST([REPLACE_TRUNCL]) ++]) ++ ++# gl_LONG_DOUBLE_VS_DOUBLE ++# determines whether 'long double' and 'double' have the same representation. ++# Sets variable HAVE_SAME_LONG_DOUBLE_AS_DOUBLE to 0 or 1, and defines ++# HAVE_SAME_LONG_DOUBLE_AS_DOUBLE accordingly. ++# The currently known platforms where this is the case are: ++# Linux/HPPA, Minix 3.1.8, AIX 5, AIX 6 and 7 with xlc, MSVC 9. ++AC_DEFUN([gl_LONG_DOUBLE_VS_DOUBLE], ++[ ++ AC_CACHE_CHECK([whether long double and double are the same], ++ [gl_cv_long_double_equals_double], ++ [AC_COMPILE_IFELSE( ++ [AC_LANG_PROGRAM([[#include ]], ++ [[typedef int check[sizeof (long double) == sizeof (double) ++ && LDBL_MANT_DIG == DBL_MANT_DIG ++ && LDBL_MAX_EXP == DBL_MAX_EXP ++ && LDBL_MIN_EXP == DBL_MIN_EXP ++ ? 1 : -1]; ++ ]])], ++ [gl_cv_long_double_equals_double=yes], ++ [gl_cv_long_double_equals_double=no]) ++ ]) ++ if test $gl_cv_long_double_equals_double = yes; then ++ AC_DEFINE([HAVE_SAME_LONG_DOUBLE_AS_DOUBLE], [1], ++ [Define to 1 if 'long double' and 'double' have the same representation.]) ++ HAVE_SAME_LONG_DOUBLE_AS_DOUBLE=1 ++ else ++ HAVE_SAME_LONG_DOUBLE_AS_DOUBLE=0 ++ fi ++ AC_SUBST([HAVE_SAME_LONG_DOUBLE_AS_DOUBLE]) ++]) +diff --git a/m4/mbrtowc.m4 b/m4/mbrtowc.m4 +index 28b9c43..4c9f388 100644 +--- a/m4/mbrtowc.m4 ++++ b/m4/mbrtowc.m4 +@@ -1,5 +1,5 @@ +-# mbrtowc.m4 serial 18 +-dnl Copyright (C) 2001-2002, 2004-2005, 2008-2010 Free Software Foundation, ++# mbrtowc.m4 serial 25 ++dnl Copyright (C) 2001-2002, 2004-2005, 2008-2013 Free Software Foundation, + dnl Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, +@@ -15,16 +15,40 @@ AC_DEFUN([gl_FUNC_MBRTOWC], + AC_CHECK_FUNCS_ONCE([mbrtowc]) + if test $ac_cv_func_mbrtowc = no; then + HAVE_MBRTOWC=0 ++ AC_CHECK_DECLS([mbrtowc],,, [[ ++/* Tru64 with Desktop Toolkit C has a bug: must be included before ++ . ++ BSD/OS 4.0.1 has a bug: , and must be ++ included before . */ ++#include ++#include ++#include ++#include ++]]) ++ if test $ac_cv_have_decl_mbrtowc = yes; then ++ dnl On Minix 3.1.8, the system's declares mbrtowc() although ++ dnl it does not have the function. Avoid a collision with gnulib's ++ dnl replacement. ++ REPLACE_MBRTOWC=1 ++ fi + else + if test $REPLACE_MBSTATE_T = 1; then + REPLACE_MBRTOWC=1 + else +- gl_MBRTOWC_NULL_ARG ++ gl_MBRTOWC_NULL_ARG1 ++ gl_MBRTOWC_NULL_ARG2 + gl_MBRTOWC_RETVAL + gl_MBRTOWC_NUL_RETVAL +- case "$gl_cv_func_mbrtowc_null_arg" in ++ case "$gl_cv_func_mbrtowc_null_arg1" in ++ *yes) ;; ++ *) AC_DEFINE([MBRTOWC_NULL_ARG1_BUG], [1], ++ [Define if the mbrtowc function has the NULL pwc argument bug.]) ++ REPLACE_MBRTOWC=1 ++ ;; ++ esac ++ case "$gl_cv_func_mbrtowc_null_arg2" in + *yes) ;; +- *) AC_DEFINE([MBRTOWC_NULL_ARG_BUG], [1], ++ *) AC_DEFINE([MBRTOWC_NULL_ARG2_BUG], [1], + [Define if the mbrtowc function has the NULL string argument bug.]) + REPLACE_MBRTOWC=1 + ;; +@@ -45,11 +69,6 @@ AC_DEFUN([gl_FUNC_MBRTOWC], + esac + fi + fi +- if test $HAVE_MBRTOWC = 0 || test $REPLACE_MBRTOWC = 1; then +- gl_REPLACE_WCHAR_H +- AC_LIBOBJ([mbrtowc]) +- gl_PREREQ_MBRTOWC +- fi + ]) + + dnl Test whether mbsinit() and mbrtowc() need to be overridden in a way that +@@ -80,9 +99,6 @@ AC_DEFUN([gl_MBSTATE_T_BROKEN], + else + REPLACE_MBSTATE_T=1 + fi +- if test $REPLACE_MBSTATE_T = 1; then +- gl_REPLACE_WCHAR_H +- fi + ]) + + dnl Test whether mbrtowc puts the state into non-initial state when parsing an +@@ -112,6 +128,13 @@ changequote([,])dnl + [AC_LANG_SOURCE([[ + #include + #include ++/* Tru64 with Desktop Toolkit C has a bug: must be included before ++ . ++ BSD/OS 4.0.1 has a bug: , and must be ++ included before . */ ++#include ++#include ++#include + #include + int main () + { +@@ -162,6 +185,13 @@ changequote([,])dnl + #include + #include + #include ++/* Tru64 with Desktop Toolkit C has a bug: must be included before ++ . ++ BSD/OS 4.0.1 has a bug: , and must be ++ included before . */ ++#include ++#include ++#include + #include + int main () + { +@@ -188,25 +218,95 @@ int main () + ]) + ]) + ++dnl Test whether mbrtowc supports a NULL pwc argument correctly. ++dnl Result is gl_cv_func_mbrtowc_null_arg1. ++ ++AC_DEFUN([gl_MBRTOWC_NULL_ARG1], ++[ ++ AC_REQUIRE([AC_PROG_CC]) ++ AC_REQUIRE([gt_LOCALE_FR_UTF8]) ++ AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles ++ AC_CACHE_CHECK([whether mbrtowc handles a NULL pwc argument], ++ [gl_cv_func_mbrtowc_null_arg1], ++ [ ++ dnl Initial guess, used when cross-compiling or when no suitable locale ++ dnl is present. ++changequote(,)dnl ++ case "$host_os" in ++ # Guess no on Solaris. ++ solaris*) gl_cv_func_mbrtowc_null_arg1="guessing no" ;; ++ # Guess yes otherwise. ++ *) gl_cv_func_mbrtowc_null_arg1="guessing yes" ;; ++ esac ++changequote([,])dnl ++ if test $LOCALE_FR_UTF8 != none; then ++ AC_RUN_IFELSE( ++ [AC_LANG_SOURCE([[ ++#include ++#include ++#include ++/* Tru64 with Desktop Toolkit C has a bug: must be included before ++ . ++ BSD/OS 4.0.1 has a bug: , and must be ++ included before . */ ++#include ++#include ++#include ++#include ++int main () ++{ ++ int result = 0; ++ ++ if (setlocale (LC_ALL, "$LOCALE_FR_UTF8") != NULL) ++ { ++ char input[] = "\303\237er"; ++ mbstate_t state; ++ wchar_t wc; ++ size_t ret; ++ ++ memset (&state, '\0', sizeof (mbstate_t)); ++ wc = (wchar_t) 0xBADFACE; ++ ret = mbrtowc (&wc, input, 5, &state); ++ if (ret != 2) ++ result |= 1; ++ if (!mbsinit (&state)) ++ result |= 2; ++ ++ memset (&state, '\0', sizeof (mbstate_t)); ++ ret = mbrtowc (NULL, input, 5, &state); ++ if (ret != 2) /* Solaris 7 fails here: ret is -1. */ ++ result |= 4; ++ if (!mbsinit (&state)) ++ result |= 8; ++ } ++ return result; ++}]])], ++ [gl_cv_func_mbrtowc_null_arg1=yes], ++ [gl_cv_func_mbrtowc_null_arg1=no], ++ [:]) ++ fi ++ ]) ++]) ++ + dnl Test whether mbrtowc supports a NULL string argument correctly. +-dnl Result is gl_cv_func_mbrtowc_null_arg. ++dnl Result is gl_cv_func_mbrtowc_null_arg2. + +-AC_DEFUN([gl_MBRTOWC_NULL_ARG], ++AC_DEFUN([gl_MBRTOWC_NULL_ARG2], + [ + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([gt_LOCALE_FR_UTF8]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_CACHE_CHECK([whether mbrtowc handles a NULL string argument], +- [gl_cv_func_mbrtowc_null_arg], ++ [gl_cv_func_mbrtowc_null_arg2], + [ + dnl Initial guess, used when cross-compiling or when no suitable locale + dnl is present. + changequote(,)dnl + case "$host_os" in + # Guess no on OSF/1. +- osf*) gl_cv_func_mbrtowc_null_arg="guessing no" ;; ++ osf*) gl_cv_func_mbrtowc_null_arg2="guessing no" ;; + # Guess yes otherwise. +- *) gl_cv_func_mbrtowc_null_arg="guessing yes" ;; ++ *) gl_cv_func_mbrtowc_null_arg2="guessing yes" ;; + esac + changequote([,])dnl + if test $LOCALE_FR_UTF8 != none; then +@@ -214,6 +314,13 @@ changequote([,])dnl + [AC_LANG_SOURCE([[ + #include + #include ++/* Tru64 with Desktop Toolkit C has a bug: must be included before ++ . ++ BSD/OS 4.0.1 has a bug: , and must be ++ included before . */ ++#include ++#include ++#include + #include + int main () + { +@@ -232,8 +339,8 @@ int main () + } + return 0; + }]])], +- [gl_cv_func_mbrtowc_null_arg=yes], +- [gl_cv_func_mbrtowc_null_arg=no], ++ [gl_cv_func_mbrtowc_null_arg2=yes], ++ [gl_cv_func_mbrtowc_null_arg2=no], + [:]) + fi + ]) +@@ -249,7 +356,7 @@ AC_DEFUN([gl_MBRTOWC_RETVAL], + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([gt_LOCALE_FR_UTF8]) + AC_REQUIRE([gt_LOCALE_JA]) +- AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles ++ AC_REQUIRE([AC_CANONICAL_HOST]) + AC_CACHE_CHECK([whether mbrtowc has a correct return value], + [gl_cv_func_mbrtowc_retval], + [ +@@ -257,20 +364,30 @@ AC_DEFUN([gl_MBRTOWC_RETVAL], + dnl is present. + changequote(,)dnl + case "$host_os" in +- # Guess no on HP-UX and Solaris. +- hpux* | solaris*) gl_cv_func_mbrtowc_retval="guessing no" ;; +- # Guess yes otherwise. +- *) gl_cv_func_mbrtowc_retval="guessing yes" ;; ++ # Guess no on HP-UX, Solaris, native Windows. ++ hpux* | solaris* | mingw*) gl_cv_func_mbrtowc_retval="guessing no" ;; ++ # Guess yes otherwise. ++ *) gl_cv_func_mbrtowc_retval="guessing yes" ;; + esac + changequote([,])dnl +- if test $LOCALE_FR_UTF8 != none || test $LOCALE_JA != none; then ++ if test $LOCALE_FR_UTF8 != none || test $LOCALE_JA != none \ ++ || { case "$host_os" in mingw*) true;; *) false;; esac; }; then + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ + #include + #include ++/* Tru64 with Desktop Toolkit C has a bug: must be included before ++ . ++ BSD/OS 4.0.1 has a bug: , and must be ++ included before . */ ++#include ++#include ++#include + #include + int main () + { ++ int result = 0; ++ int found_some_locale = 0; + /* This fails on Solaris. */ + if (setlocale (LC_ALL, "$LOCALE_FR_UTF8") != NULL) + { +@@ -283,8 +400,9 @@ int main () + { + input[1] = '\0'; + if (mbrtowc (&wc, input + 2, 5, &state) != 1) +- return 1; ++ result |= 1; + } ++ found_some_locale = 1; + } + /* This fails on HP-UX 11.11. */ + if (setlocale (LC_ALL, "$LOCALE_JA") != NULL) +@@ -298,13 +416,63 @@ int main () + { + input[1] = '\0'; + if (mbrtowc (&wc, input + 2, 5, &state) != 2) +- return 1; ++ result |= 2; + } ++ found_some_locale = 1; + } +- return 0; ++ /* This fails on native Windows. */ ++ if (setlocale (LC_ALL, "Japanese_Japan.932") != NULL) ++ { ++ char input[] = "<\223\372\226\173\214\352>"; /* "<日本語>" */ ++ mbstate_t state; ++ wchar_t wc; ++ ++ memset (&state, '\0', sizeof (mbstate_t)); ++ if (mbrtowc (&wc, input + 3, 1, &state) == (size_t)(-2)) ++ { ++ input[3] = '\0'; ++ if (mbrtowc (&wc, input + 4, 4, &state) != 1) ++ result |= 4; ++ } ++ found_some_locale = 1; ++ } ++ if (setlocale (LC_ALL, "Chinese_Taiwan.950") != NULL) ++ { ++ char input[] = "<\244\351\245\273\273\171>"; /* "<日本語>" */ ++ mbstate_t state; ++ wchar_t wc; ++ ++ memset (&state, '\0', sizeof (mbstate_t)); ++ if (mbrtowc (&wc, input + 3, 1, &state) == (size_t)(-2)) ++ { ++ input[3] = '\0'; ++ if (mbrtowc (&wc, input + 4, 4, &state) != 1) ++ result |= 8; ++ } ++ found_some_locale = 1; ++ } ++ if (setlocale (LC_ALL, "Chinese_China.936") != NULL) ++ { ++ char input[] = "<\310\325\261\276\325\132>"; /* "<日本語>" */ ++ mbstate_t state; ++ wchar_t wc; ++ ++ memset (&state, '\0', sizeof (mbstate_t)); ++ if (mbrtowc (&wc, input + 3, 1, &state) == (size_t)(-2)) ++ { ++ input[3] = '\0'; ++ if (mbrtowc (&wc, input + 4, 4, &state) != 1) ++ result |= 16; ++ } ++ found_some_locale = 1; ++ } ++ return (found_some_locale ? result : 77); + }]])], + [gl_cv_func_mbrtowc_retval=yes], +- [gl_cv_func_mbrtowc_retval=no], ++ [if test $? != 77; then ++ gl_cv_func_mbrtowc_retval=no ++ fi ++ ], + [:]) + fi + ]) +@@ -336,6 +504,13 @@ changequote([,])dnl + [AC_LANG_SOURCE([[ + #include + #include ++/* Tru64 with Desktop Toolkit C has a bug: must be included before ++ . ++ BSD/OS 4.0.1 has a bug: , and must be ++ included before . */ ++#include ++#include ++#include + #include + int main () + { +@@ -366,10 +541,8 @@ AC_DEFUN([gl_PREREQ_MBRTOWC], [ + + dnl From Paul Eggert + +-dnl This override of an autoconf macro can be removed when autoconf 2.60 or +-dnl newer can be assumed everywhere. ++dnl This is an override of an autoconf macro. + +-m4_if(m4_version_compare(m4_defn([m4_PACKAGE_VERSION]),[2.60]),[-1],[ + AC_DEFUN([AC_FUNC_MBRTOWC], + [ + dnl Same as AC_FUNC_MBRTOWC in autoconf-2.60. +@@ -377,7 +550,14 @@ AC_DEFUN([AC_FUNC_MBRTOWC], + gl_cv_func_mbrtowc, + [AC_LINK_IFELSE( + [AC_LANG_PROGRAM( +- [[#include ]], ++ [[/* Tru64 with Desktop Toolkit C has a bug: must be ++ included before . ++ BSD/OS 4.0.1 has a bug: , and ++ must be included before . */ ++ #include ++ #include ++ #include ++ #include ]], + [[wchar_t wc; + char const s[] = ""; + size_t n = 1; +@@ -390,4 +570,3 @@ AC_DEFUN([AC_FUNC_MBRTOWC], + [Define to 1 if mbrtowc and mbstate_t are properly declared.]) + fi + ]) +-]) +diff --git a/m4/mbsinit.m4 b/m4/mbsinit.m4 +index 46c106f..2e6d092 100644 +--- a/m4/mbsinit.m4 ++++ b/m4/mbsinit.m4 +@@ -1,5 +1,5 @@ +-# mbsinit.m4 serial 4 +-dnl Copyright (C) 2008, 2010 Free Software Foundation, Inc. ++# mbsinit.m4 serial 8 ++dnl Copyright (C) 2008, 2010-2013 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. +@@ -7,6 +7,7 @@ dnl with or without modifications, as long as this notice is preserved. + AC_DEFUN([gl_FUNC_MBSINIT], + [ + AC_REQUIRE([gl_WCHAR_H_DEFAULTS]) ++ AC_REQUIRE([AC_CANONICAL_HOST]) + + AC_REQUIRE([AC_TYPE_MBSTATE_T]) + gl_MBSTATE_T_BROKEN +@@ -14,16 +15,34 @@ AC_DEFUN([gl_FUNC_MBSINIT], + AC_CHECK_FUNCS_ONCE([mbsinit]) + if test $ac_cv_func_mbsinit = no; then + HAVE_MBSINIT=0 ++ AC_CHECK_DECLS([mbsinit],,, [[ ++/* Tru64 with Desktop Toolkit C has a bug: must be included before ++ . ++ BSD/OS 4.0.1 has a bug: , and must be ++ included before . */ ++#include ++#include ++#include ++#include ++]]) ++ if test $ac_cv_have_decl_mbsinit = yes; then ++ dnl On Minix 3.1.8, the system's declares mbsinit() although ++ dnl it does not have the function. Avoid a collision with gnulib's ++ dnl replacement. ++ REPLACE_MBSINIT=1 ++ fi + else + if test $REPLACE_MBSTATE_T = 1; then + REPLACE_MBSINIT=1 ++ else ++ dnl On mingw, mbsinit() always returns 1, which is inappropriate for ++ dnl states produced by mbrtowc() for an incomplete multibyte character ++ dnl in multibyte locales. ++ case "$host_os" in ++ mingw*) REPLACE_MBSINIT=1 ;; ++ esac + fi + fi +- if test $HAVE_MBSINIT = 0 || test $REPLACE_MBSINIT = 1; then +- gl_REPLACE_WCHAR_H +- AC_LIBOBJ([mbsinit]) +- gl_PREREQ_MBSINIT +- fi + ]) + + # Prerequisites of lib/mbsinit.c. +diff --git a/m4/mbsrtowcs.m4 b/m4/mbsrtowcs.m4 +index e854337..c4934c2 100644 +--- a/m4/mbsrtowcs.m4 ++++ b/m4/mbsrtowcs.m4 +@@ -1,5 +1,5 @@ +-# mbsrtowcs.m4 serial 7 +-dnl Copyright (C) 2008-2010 Free Software Foundation, Inc. ++# mbsrtowcs.m4 serial 13 ++dnl Copyright (C) 2008-2013 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. +@@ -14,6 +14,22 @@ AC_DEFUN([gl_FUNC_MBSRTOWCS], + AC_CHECK_FUNCS_ONCE([mbsrtowcs]) + if test $ac_cv_func_mbsrtowcs = no; then + HAVE_MBSRTOWCS=0 ++ AC_CHECK_DECLS([mbsrtowcs],,, [[ ++/* Tru64 with Desktop Toolkit C has a bug: must be included before ++ . ++ BSD/OS 4.0.1 has a bug: , and must be ++ included before . */ ++#include ++#include ++#include ++#include ++]]) ++ if test $ac_cv_have_decl_mbsrtowcs = yes; then ++ dnl On Minix 3.1.8, the system's declares mbsrtowcs() although ++ dnl it does not have the function. Avoid a collision with gnulib's ++ dnl replacement. ++ REPLACE_MBSRTOWCS=1 ++ fi + else + if test $REPLACE_MBSTATE_T = 1; then + REPLACE_MBSRTOWCS=1 +@@ -25,12 +41,6 @@ AC_DEFUN([gl_FUNC_MBSRTOWCS], + esac + fi + fi +- if test $HAVE_MBSRTOWCS = 0 || test $REPLACE_MBSRTOWCS = 1; then +- gl_REPLACE_WCHAR_H +- AC_LIBOBJ([mbsrtowcs]) +- AC_LIBOBJ([mbsrtowcs-state]) +- gl_PREREQ_MBSRTOWCS +- fi + ]) + + dnl Test whether mbsrtowcs works. +@@ -39,6 +49,7 @@ dnl Result is gl_cv_func_mbsrtowcs_works. + AC_DEFUN([gl_MBSRTOWCS_WORKS], + [ + AC_REQUIRE([AC_PROG_CC]) ++ AC_REQUIRE([gt_LOCALE_FR]) + AC_REQUIRE([gt_LOCALE_FR_UTF8]) + AC_REQUIRE([gt_LOCALE_JA]) + AC_REQUIRE([gt_LOCALE_ZH_CN]) +@@ -50,20 +61,41 @@ AC_DEFUN([gl_MBSRTOWCS_WORKS], + dnl is present. + changequote(,)dnl + case "$host_os" in +- # Guess no on HP-UX and Solaris. +- hpux* | solaris*) gl_cv_func_mbsrtowcs_works="guessing no" ;; +- # Guess yes otherwise. +- *) gl_cv_func_mbsrtowcs_works="guessing yes" ;; ++ # Guess no on HP-UX, Solaris, mingw. ++ hpux* | solaris* | mingw*) gl_cv_func_mbsrtowcs_works="guessing no" ;; ++ # Guess yes otherwise. ++ *) gl_cv_func_mbsrtowcs_works="guessing yes" ;; + esac + changequote([,])dnl +- if test $LOCALE_FR_UTF8 != none || test $LOCALE_JA != none || test $LOCALE_ZH_CN != none; then ++ if test $LOCALE_FR != none || test $LOCALE_FR_UTF8 != none || test $LOCALE_JA != none || test $LOCALE_ZH_CN != none; then + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ + #include + #include ++/* Tru64 with Desktop Toolkit C has a bug: must be included before ++ . ++ BSD/OS 4.0.1 has a bug: , and must be ++ included before . */ ++#include ++#include ++#include + #include + int main () + { ++ int result = 0; ++ /* Test whether the function supports a NULL destination argument. ++ This fails on native Windows. */ ++ if (setlocale (LC_ALL, "$LOCALE_FR") != NULL) ++ { ++ const char input[] = "\337er"; ++ const char *src = input; ++ mbstate_t state; ++ ++ memset (&state, '\0', sizeof (mbstate_t)); ++ if (mbsrtowcs (NULL, &src, 1, &state) != 3 ++ || src != input) ++ result |= 1; ++ } + /* Test whether the function works when started with a conversion state + in non-initial state. This fails on HP-UX 11.11 and Solaris 10. */ + if (setlocale (LC_ALL, "$LOCALE_FR_UTF8") != NULL) +@@ -77,7 +109,7 @@ int main () + { + const char *src = input + 2; + if (mbsrtowcs (NULL, &src, 10, &state) != 4) +- return 1; ++ result |= 2; + } + } + if (setlocale (LC_ALL, "$LOCALE_JA") != NULL) +@@ -91,7 +123,7 @@ int main () + { + const char *src = input + 4; + if (mbsrtowcs (NULL, &src, 10, &state) != 3) +- return 1; ++ result |= 4; + } + } + if (setlocale (LC_ALL, "$LOCALE_ZH_CN") != NULL) +@@ -105,10 +137,10 @@ int main () + { + const char *src = input + 2; + if (mbsrtowcs (NULL, &src, 10, &state) != 4) +- return 1; ++ result |= 8; + } + } +- return 0; ++ return result; + }]])], + [gl_cv_func_mbsrtowcs_works=yes], + [gl_cv_func_mbsrtowcs_works=no], +diff --git a/m4/mbstate_t.m4 b/m4/mbstate_t.m4 +index 3e2df29..ed00117 100644 +--- a/m4/mbstate_t.m4 ++++ b/m4/mbstate_t.m4 +@@ -1,5 +1,5 @@ +-# mbstate_t.m4 serial 12 +-dnl Copyright (C) 2000-2002, 2008-2010 Free Software Foundation, Inc. ++# mbstate_t.m4 serial 13 ++dnl Copyright (C) 2000-2002, 2008-2013 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. +@@ -20,7 +20,14 @@ AC_DEFUN([AC_TYPE_MBSTATE_T], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [AC_INCLUDES_DEFAULT[ +-# include ]], ++/* Tru64 with Desktop Toolkit C has a bug: must be included before ++ . ++ BSD/OS 4.0.1 has a bug: , and must be ++ included before . */ ++#include ++#include ++#include ++#include ]], + [[mbstate_t x; return sizeof x;]])], + [ac_cv_type_mbstate_t=yes], + [ac_cv_type_mbstate_t=no])]) +diff --git a/m4/mbswidth.m4 b/m4/mbswidth.m4 +new file mode 100644 +index 0000000..39760fc +--- /dev/null ++++ b/m4/mbswidth.m4 +@@ -0,0 +1,46 @@ ++# mbswidth.m4 serial 18 ++dnl Copyright (C) 2000-2002, 2004, 2006-2013 Free Software Foundation, Inc. ++dnl This file is free software; the Free Software Foundation ++dnl gives unlimited permission to copy and/or distribute it, ++dnl with or without modifications, as long as this notice is preserved. ++ ++dnl autoconf tests required for use of mbswidth.c ++dnl From Bruno Haible. ++ ++AC_DEFUN([gl_MBSWIDTH], ++[ ++ AC_CHECK_HEADERS_ONCE([wchar.h]) ++ AC_CHECK_FUNCS_ONCE([isascii mbsinit]) ++ ++ dnl UnixWare 7.1.1 has a declaration of a function mbswidth() ++ dnl that clashes with ours. ++ AC_CACHE_CHECK([whether mbswidth is declared in ], ++ [ac_cv_have_decl_mbswidth], ++ [AC_COMPILE_IFELSE( ++ [AC_LANG_PROGRAM( ++ [[ ++/* Tru64 with Desktop Toolkit C has a bug: must be included before ++ . ++ BSD/OS 4.0.1 has a bug: , and must be included ++ before . */ ++#include ++#include ++#include ++#include ++ ]], ++ [[ ++ char *p = (char *) mbswidth; ++ return !p; ++ ]])], ++ [ac_cv_have_decl_mbswidth=yes], ++ [ac_cv_have_decl_mbswidth=no])]) ++ if test $ac_cv_have_decl_mbswidth = yes; then ++ ac_val=1 ++ else ++ ac_val=0 ++ fi ++ AC_DEFINE_UNQUOTED([HAVE_DECL_MBSWIDTH_IN_WCHAR_H], [$ac_val], ++ [Define to 1 if you have a declaration of mbswidth() in , and to 0 otherwise.]) ++ ++ AC_TYPE_MBSTATE_T ++]) +diff --git a/m4/mbtowc.m4 b/m4/mbtowc.m4 +new file mode 100644 +index 0000000..e479461 +--- /dev/null ++++ b/m4/mbtowc.m4 +@@ -0,0 +1,19 @@ ++# mbtowc.m4 serial 2 ++dnl Copyright (C) 2011-2013 Free Software Foundation, Inc. ++dnl This file is free software; the Free Software Foundation ++dnl gives unlimited permission to copy and/or distribute it, ++dnl with or without modifications, as long as this notice is preserved. ++ ++AC_DEFUN([gl_FUNC_MBTOWC], ++[ ++ AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) ++ ++ if false; then ++ REPLACE_MBTOWC=1 ++ fi ++]) ++ ++# Prerequisites of lib/mbtowc.c. ++AC_DEFUN([gl_PREREQ_MBTOWC], [ ++ : ++]) +diff --git a/m4/memchr.m4 b/m4/memchr.m4 +index b05a79a..2d8abe7 100644 +--- a/m4/memchr.m4 ++++ b/m4/memchr.m4 +@@ -1,5 +1,5 @@ +-# memchr.m4 serial 9 +-dnl Copyright (C) 2002-2004, 2009-2010 Free Software Foundation, Inc. ++# memchr.m4 serial 12 ++dnl Copyright (C) 2002-2004, 2009-2013 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. +@@ -11,10 +11,16 @@ AC_DEFUN_ONCE([gl_FUNC_MEMCHR], + AC_CHECK_HEADERS_ONCE([sys/mman.h]) + AC_CHECK_FUNCS_ONCE([mprotect]) + +- dnl These days, we assume memchr is present. But just in case... + AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS]) +- AC_CHECK_FUNCS_ONCE([memchr]) +- if test $ac_cv_func_memchr = yes; then ++ m4_ifdef([gl_FUNC_MEMCHR_OBSOLETE], [ ++ dnl These days, we assume memchr is present. But if support for old ++ dnl platforms is desired: ++ AC_CHECK_FUNCS_ONCE([memchr]) ++ if test $ac_cv_func_memchr = no; then ++ HAVE_MEMCHR=0 ++ fi ++ ]) ++ if test $HAVE_MEMCHR = 1; then + # Detect platform-specific bugs in some versions of glibc: + # memchr should not dereference anything with length 0 + # http://bugzilla.redhat.com/499689 +@@ -35,6 +41,7 @@ AC_DEFUN_ONCE([gl_FUNC_MEMCHR], + # endif + #endif + ]], [[ ++ int result = 0; + char *fence = NULL; + #if HAVE_SYS_MMAN_H && HAVE_MPROTECT + # if HAVE_MAP_ANONYMOUS +@@ -58,26 +65,20 @@ AC_DEFUN_ONCE([gl_FUNC_MEMCHR], + if (fence) + { + if (memchr (fence, 0, 0)) +- return 1; ++ result |= 1; + strcpy (fence - 9, "12345678"); + if (memchr (fence - 9, 0, 79) != fence - 1) +- return 2; ++ result |= 2; + if (memchr (fence - 1, 0, 3) != fence - 1) +- return 3; ++ result |= 4; + } +- return 0; ++ return result; + ]])], [gl_cv_func_memchr_works=yes], [gl_cv_func_memchr_works=no], + [dnl Be pessimistic for now. + gl_cv_func_memchr_works="guessing no"])]) + if test "$gl_cv_func_memchr_works" != yes; then + REPLACE_MEMCHR=1 + fi +- else +- HAVE_MEMCHR=0 +- fi +- if test $HAVE_MEMCHR = 0 || test $REPLACE_MEMCHR = 1; then +- AC_LIBOBJ([memchr]) +- gl_PREREQ_MEMCHR + fi + ]) + +diff --git a/m4/mempcpy.m4 b/m4/mempcpy.m4 +index 12df771..a48f2d1 100644 +--- a/m4/mempcpy.m4 ++++ b/m4/mempcpy.m4 +@@ -1,5 +1,5 @@ +-# mempcpy.m4 serial 10 +-dnl Copyright (C) 2003-2004, 2006-2007, 2009-2010 Free Software Foundation, ++# mempcpy.m4 serial 11 ++dnl Copyright (C) 2003-2004, 2006-2007, 2009-2013 Free Software Foundation, + dnl Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, +@@ -14,10 +14,9 @@ AC_DEFUN([gl_FUNC_MEMPCPY], + AC_REQUIRE([AC_C_RESTRICT]) + + AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS]) +- AC_REPLACE_FUNCS([mempcpy]) ++ AC_CHECK_FUNCS([mempcpy]) + if test $ac_cv_func_mempcpy = no; then + HAVE_MEMPCPY=0 +- gl_PREREQ_MEMPCPY + fi + ]) + +diff --git a/m4/mmap-anon.m4 b/m4/mmap-anon.m4 +index a6b7b9a..9b60ddf 100644 +--- a/m4/mmap-anon.m4 ++++ b/m4/mmap-anon.m4 +@@ -1,5 +1,5 @@ +-# mmap-anon.m4 serial 8 +-dnl Copyright (C) 2005, 2007, 2009-2010 Free Software Foundation, Inc. ++# mmap-anon.m4 serial 10 ++dnl Copyright (C) 2005, 2007, 2009-2013 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. +@@ -9,16 +9,12 @@ dnl with or without modifications, as long as this notice is preserved. + # - On Linux, AIX, OSF/1, Solaris, Cygwin, Interix, Haiku, both MAP_ANONYMOUS + # and MAP_ANON exist and have the same value. + # - On HP-UX, only MAP_ANONYMOUS exists. +-# - On MacOS X, FreeBSD, NetBSD, OpenBSD, only MAP_ANON exists. ++# - On Mac OS X, FreeBSD, NetBSD, OpenBSD, only MAP_ANON exists. + # - On IRIX, neither exists, and a file descriptor opened to /dev/zero must be + # used. + + AC_DEFUN([gl_FUNC_MMAP_ANON], + [ +- dnl Work around a bug of AC_EGREP_CPP in autoconf-2.57. +- AC_REQUIRE([AC_PROG_CPP]) +- AC_REQUIRE([AC_PROG_EGREP]) +- + dnl Persuade glibc to define MAP_ANONYMOUS. + AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) + +@@ -31,18 +27,18 @@ AC_DEFUN([gl_FUNC_MMAP_ANON], + gl_have_mmap_anonymous=no + if test $gl_have_mmap = yes; then + AC_MSG_CHECKING([for MAP_ANONYMOUS]) +- AC_EGREP_CPP([I cant identify this map.], [ ++ AC_EGREP_CPP([I cannot identify this map], [ + #include + #ifdef MAP_ANONYMOUS +- I cant identify this map. ++ I cannot identify this map + #endif + ], + [gl_have_mmap_anonymous=yes]) + if test $gl_have_mmap_anonymous != yes; then +- AC_EGREP_CPP([I cant identify this map.], [ ++ AC_EGREP_CPP([I cannot identify this map], [ + #include + #ifdef MAP_ANON +- I cant identify this map. ++ I cannot identify this map + #endif + ], + [AC_DEFINE([MAP_ANONYMOUS], [MAP_ANON], +diff --git a/m4/msvc-inval.m4 b/m4/msvc-inval.m4 +new file mode 100644 +index 0000000..9a6a47a +--- /dev/null ++++ b/m4/msvc-inval.m4 +@@ -0,0 +1,19 @@ ++# msvc-inval.m4 serial 1 ++dnl Copyright (C) 2011-2013 Free Software Foundation, Inc. ++dnl This file is free software; the Free Software Foundation ++dnl gives unlimited permission to copy and/or distribute it, ++dnl with or without modifications, as long as this notice is preserved. ++ ++AC_DEFUN([gl_MSVC_INVAL], ++[ ++ AC_CHECK_FUNCS_ONCE([_set_invalid_parameter_handler]) ++ if test $ac_cv_func__set_invalid_parameter_handler = yes; then ++ HAVE_MSVC_INVALID_PARAMETER_HANDLER=1 ++ AC_DEFINE([HAVE_MSVC_INVALID_PARAMETER_HANDLER], [1], ++ [Define to 1 on MSVC platforms that have the "invalid parameter handler" ++ concept.]) ++ else ++ HAVE_MSVC_INVALID_PARAMETER_HANDLER=0 ++ fi ++ AC_SUBST([HAVE_MSVC_INVALID_PARAMETER_HANDLER]) ++]) +diff --git a/m4/msvc-nothrow.m4 b/m4/msvc-nothrow.m4 +new file mode 100644 +index 0000000..a39618a +--- /dev/null ++++ b/m4/msvc-nothrow.m4 +@@ -0,0 +1,10 @@ ++# msvc-nothrow.m4 serial 1 ++dnl Copyright (C) 2011-2013 Free Software Foundation, Inc. ++dnl This file is free software; the Free Software Foundation ++dnl gives unlimited permission to copy and/or distribute it, ++dnl with or without modifications, as long as this notice is preserved. ++ ++AC_DEFUN([gl_MSVC_NOTHROW], ++[ ++ AC_REQUIRE([gl_MSVC_INVAL]) ++]) +diff --git a/m4/multiarch.m4 b/m4/multiarch.m4 +index 389bd2b..552ec7e 100644 +--- a/m4/multiarch.m4 ++++ b/m4/multiarch.m4 +@@ -1,12 +1,12 @@ +-# multiarch.m4 serial 5 +-dnl Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc. ++# multiarch.m4 serial 7 ++dnl Copyright (C) 2008-2013 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. + + # Determine whether the compiler is or may be producing universal binaries. + # +-# On MacOS X 10.5 and later systems, the user can create libraries and ++# On Mac OS X 10.5 and later systems, the user can create libraries and + # executables that work on multiple system types--known as "fat" or + # "universal" binaries--by specifying multiple '-arch' options to the + # compiler but only a single '-arch' option to the preprocessor. Like +@@ -16,8 +16,7 @@ dnl with or without modifications, as long as this notice is preserved. + # CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ + # CPP="gcc -E" CXXCPP="g++ -E" + # +-# Detect this situation and set the macro AA_APPLE_UNIVERSAL_BUILD at the +-# beginning of config.h and set APPLE_UNIVERSAL_BUILD accordingly. ++# Detect this situation and set APPLE_UNIVERSAL_BUILD accordingly. + + AC_DEFUN_ONCE([gl_MULTIARCH], + [ +@@ -55,8 +54,6 @@ AC_DEFUN_ONCE([gl_MULTIARCH], + done + ]) + if test $gl_cv_c_multiarch = yes; then +- AC_DEFINE([AA_APPLE_UNIVERSAL_BUILD], [1], +- [Define if the compiler is building for multiple architectures of Apple platforms at once.]) + APPLE_UNIVERSAL_BUILD=1 + else + APPLE_UNIVERSAL_BUILD=0 +diff --git a/m4/nl_langinfo.m4 b/m4/nl_langinfo.m4 +index ad456a2..25e2101 100644 +--- a/m4/nl_langinfo.m4 ++++ b/m4/nl_langinfo.m4 +@@ -1,5 +1,5 @@ +-# nl_langinfo.m4 serial 3 +-dnl Copyright (C) 2009, 2010 Free Software Foundation, Inc. ++# nl_langinfo.m4 serial 5 ++dnl Copyright (C) 2009-2013 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. +@@ -9,17 +9,42 @@ AC_DEFUN([gl_FUNC_NL_LANGINFO], + AC_REQUIRE([gl_LANGINFO_H_DEFAULTS]) + AC_REQUIRE([gl_LANGINFO_H]) + AC_CHECK_FUNCS_ONCE([nl_langinfo]) ++ AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + if test $ac_cv_func_nl_langinfo = yes; then +- if test $HAVE_LANGINFO_CODESET = 1 && test $HAVE_LANGINFO_ERA = 1; then ++ # On Irix 6.5, YESEXPR is defined, but nl_langinfo(YESEXPR) is broken. ++ AC_CACHE_CHECK([whether YESEXPR works], ++ [gl_cv_func_nl_langinfo_yesexpr_works], ++ [AC_RUN_IFELSE( ++ [AC_LANG_PROGRAM([[#include ++]], [[return !*nl_langinfo(YESEXPR); ++]])], ++ [gl_cv_func_nl_langinfo_yesexpr_works=yes], ++ [gl_cv_func_nl_langinfo_yesexpr_works=no], ++ [ ++ case "$host_os" in ++ # Guess no on irix systems. ++ irix*) gl_cv_func_nl_langinfo_yesexpr_works="guessing no";; ++ # Guess yes elsewhere. ++ *) gl_cv_func_nl_langinfo_yesexpr_works="guessing yes";; ++ esac ++ ]) ++ ]) ++ case $gl_cv_func_nl_langinfo_yesexpr_works in ++ *yes) FUNC_NL_LANGINFO_YESEXPR_WORKS=1 ;; ++ *) FUNC_NL_LANGINFO_YESEXPR_WORKS=0 ;; ++ esac ++ AC_DEFINE_UNQUOTED([FUNC_NL_LANGINFO_YESEXPR_WORKS], ++ [$FUNC_NL_LANGINFO_YESEXPR_WORKS], ++ [Define to 1 if nl_langinfo (YESEXPR) returns a non-empty string.]) ++ if test $HAVE_LANGINFO_CODESET = 1 && test $HAVE_LANGINFO_ERA = 1 \ ++ && test $FUNC_NL_LANGINFO_YESEXPR_WORKS = 1; then + : + else + REPLACE_NL_LANGINFO=1 + AC_DEFINE([REPLACE_NL_LANGINFO], [1], + [Define if nl_langinfo exists but is overridden by gnulib.]) +- AC_LIBOBJ([nl_langinfo]) + fi + else + HAVE_NL_LANGINFO=0 +- AC_LIBOBJ([nl_langinfo]) + fi + ]) +diff --git a/m4/nls.m4 b/m4/nls.m4 +index 003704c..8f8a147 100644 +--- a/m4/nls.m4 ++++ b/m4/nls.m4 +@@ -1,5 +1,5 @@ + # nls.m4 serial 5 (gettext-0.18) +-dnl Copyright (C) 1995-2003, 2005-2006, 2008-2010 Free Software Foundation, ++dnl Copyright (C) 1995-2003, 2005-2006, 2008-2013 Free Software Foundation, + dnl Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, +diff --git a/m4/nocrash.m4 b/m4/nocrash.m4 +new file mode 100644 +index 0000000..105b884 +--- /dev/null ++++ b/m4/nocrash.m4 +@@ -0,0 +1,130 @@ ++# nocrash.m4 serial 4 ++dnl Copyright (C) 2005, 2009-2013 Free Software Foundation, Inc. ++dnl This file is free software; the Free Software Foundation ++dnl gives unlimited permission to copy and/or distribute it, ++dnl with or without modifications, as long as this notice is preserved. ++ ++dnl Based on libsigsegv, from Bruno Haible and Paolo Bonzini. ++ ++AC_PREREQ([2.13]) ++ ++dnl Expands to some code for use in .c programs that will cause the configure ++dnl test to exit instead of crashing. This is useful to avoid triggering ++dnl action from a background debugger and to avoid core dumps. ++dnl Usage: ... ++dnl ]GL_NOCRASH[ ++dnl ... ++dnl int main() { nocrash_init(); ... } ++AC_DEFUN([GL_NOCRASH],[[ ++#include ++#if defined __MACH__ && defined __APPLE__ ++/* Avoid a crash on Mac OS X. */ ++#include ++#include ++#include ++#include ++#include ++#include ++/* The exception port on which our thread listens. */ ++static mach_port_t our_exception_port; ++/* The main function of the thread listening for exceptions of type ++ EXC_BAD_ACCESS. */ ++static void * ++mach_exception_thread (void *arg) ++{ ++ /* Buffer for a message to be received. */ ++ struct { ++ mach_msg_header_t head; ++ mach_msg_body_t msgh_body; ++ char data[1024]; ++ } msg; ++ mach_msg_return_t retval; ++ /* Wait for a message on the exception port. */ ++ retval = mach_msg (&msg.head, MACH_RCV_MSG | MACH_RCV_LARGE, 0, sizeof (msg), ++ our_exception_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); ++ if (retval != MACH_MSG_SUCCESS) ++ abort (); ++ exit (1); ++} ++static void ++nocrash_init (void) ++{ ++ mach_port_t self = mach_task_self (); ++ /* Allocate a port on which the thread shall listen for exceptions. */ ++ if (mach_port_allocate (self, MACH_PORT_RIGHT_RECEIVE, &our_exception_port) ++ == KERN_SUCCESS) { ++ /* See http://web.mit.edu/darwin/src/modules/xnu/osfmk/man/mach_port_insert_right.html. */ ++ if (mach_port_insert_right (self, our_exception_port, our_exception_port, ++ MACH_MSG_TYPE_MAKE_SEND) ++ == KERN_SUCCESS) { ++ /* The exceptions we want to catch. Only EXC_BAD_ACCESS is interesting ++ for us. */ ++ exception_mask_t mask = EXC_MASK_BAD_ACCESS; ++ /* Create the thread listening on the exception port. */ ++ pthread_attr_t attr; ++ pthread_t thread; ++ if (pthread_attr_init (&attr) == 0 ++ && pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED) == 0 ++ && pthread_create (&thread, &attr, mach_exception_thread, NULL) == 0) { ++ pthread_attr_destroy (&attr); ++ /* Replace the exception port info for these exceptions with our own. ++ Note that we replace the exception port for the entire task, not only ++ for a particular thread. This has the effect that when our exception ++ port gets the message, the thread specific exception port has already ++ been asked, and we don't need to bother about it. ++ See http://web.mit.edu/darwin/src/modules/xnu/osfmk/man/task_set_exception_ports.html. */ ++ task_set_exception_ports (self, mask, our_exception_port, ++ EXCEPTION_DEFAULT, MACHINE_THREAD_STATE); ++ } ++ } ++ } ++} ++#elif (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ ++/* Avoid a crash on native Windows. */ ++#define WIN32_LEAN_AND_MEAN ++#include ++#include ++static LONG WINAPI ++exception_filter (EXCEPTION_POINTERS *ExceptionInfo) ++{ ++ switch (ExceptionInfo->ExceptionRecord->ExceptionCode) ++ { ++ case EXCEPTION_ACCESS_VIOLATION: ++ case EXCEPTION_IN_PAGE_ERROR: ++ case EXCEPTION_STACK_OVERFLOW: ++ case EXCEPTION_GUARD_PAGE: ++ case EXCEPTION_PRIV_INSTRUCTION: ++ case EXCEPTION_ILLEGAL_INSTRUCTION: ++ case EXCEPTION_DATATYPE_MISALIGNMENT: ++ case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: ++ case EXCEPTION_NONCONTINUABLE_EXCEPTION: ++ exit (1); ++ } ++ return EXCEPTION_CONTINUE_SEARCH; ++} ++static void ++nocrash_init (void) ++{ ++ SetUnhandledExceptionFilter ((LPTOP_LEVEL_EXCEPTION_FILTER) exception_filter); ++} ++#else ++/* Avoid a crash on POSIX systems. */ ++#include ++/* A POSIX signal handler. */ ++static void ++exception_handler (int sig) ++{ ++ exit (1); ++} ++static void ++nocrash_init (void) ++{ ++#ifdef SIGSEGV ++ signal (SIGSEGV, exception_handler); ++#endif ++#ifdef SIGBUS ++ signal (SIGBUS, exception_handler); ++#endif ++} ++#endif ++]]) +diff --git a/m4/off_t.m4 b/m4/off_t.m4 +new file mode 100644 +index 0000000..d355d01 +--- /dev/null ++++ b/m4/off_t.m4 +@@ -0,0 +1,18 @@ ++# off_t.m4 serial 1 ++dnl Copyright (C) 2012-2013 Free Software Foundation, Inc. ++dnl This file is free software; the Free Software Foundation ++dnl gives unlimited permission to copy and/or distribute it, ++dnl with or without modifications, as long as this notice is preserved. ++ ++dnl Check whether to override the 'off_t' type. ++dnl Set WINDOWS_64_BIT_OFF_T. ++ ++AC_DEFUN([gl_TYPE_OFF_T], ++[ ++ m4_ifdef([gl_LARGEFILE], [ ++ AC_REQUIRE([gl_LARGEFILE]) ++ ], [ ++ WINDOWS_64_BIT_OFF_T=0 ++ ]) ++ AC_SUBST([WINDOWS_64_BIT_OFF_T]) ++]) +diff --git a/m4/po.m4 b/m4/po.m4 +index 47f36a4..f395723 100644 +--- a/m4/po.m4 ++++ b/m4/po.m4 +@@ -1,5 +1,5 @@ +-# po.m4 serial 17 (gettext-0.18) +-dnl Copyright (C) 1995-2010 Free Software Foundation, Inc. ++# po.m4 serial 20 (gettext-0.18.2) ++dnl Copyright (C) 1995-2013 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. +@@ -17,14 +17,14 @@ dnl Authors: + dnl Ulrich Drepper , 1995-2000. + dnl Bruno Haible , 2000-2003. + +-AC_PREREQ([2.50]) ++AC_PREREQ([2.60]) + + dnl Checks for all prerequisites of the po subdirectory. + AC_DEFUN([AM_PO_SUBDIRS], + [ + AC_REQUIRE([AC_PROG_MAKE_SET])dnl + AC_REQUIRE([AC_PROG_INSTALL])dnl +- AC_REQUIRE([AM_PROG_MKDIR_P])dnl defined by automake ++ AC_REQUIRE([AC_PROG_MKDIR_P])dnl + AC_REQUIRE([AM_NLS])dnl + + dnl Release version of the gettext macros. This is used to ensure that +@@ -102,7 +102,7 @@ changequote([,])dnl + case "$ac_file" in */Makefile.in) + # Adjust a relative srcdir. + ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'` +- ac_dir_suffix="/`echo "$ac_dir"|sed 's%^\./%%'`" ++ ac_dir_suffix=/`echo "$ac_dir"|sed 's%^\./%%'` + ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'` + # In autoconf-2.13 it is called $ac_given_srcdir. + # In autoconf-2.50 it is called $srcdir. +@@ -118,7 +118,8 @@ changequote([,])dnl + if test -f "$ac_given_srcdir/$ac_dir/POTFILES.in"; then + rm -f "$ac_dir/POTFILES" + test -n "$as_me" && echo "$as_me: creating $ac_dir/POTFILES" || echo "creating $ac_dir/POTFILES" +- cat "$ac_given_srcdir/$ac_dir/POTFILES.in" | sed -e "/^#/d" -e "/^[ ]*\$/d" -e "s,.*, $top_srcdir/& \\\\," | sed -e "\$s/\(.*\) \\\\/\1/" > "$ac_dir/POTFILES" ++ gt_tab=`printf '\t'` ++ cat "$ac_given_srcdir/$ac_dir/POTFILES.in" | sed -e "/^#/d" -e "/^[ ${gt_tab}]*\$/d" -e "s,.*, $top_srcdir/& \\\\," | sed -e "\$s/\(.*\) \\\\/\1/" > "$ac_dir/POTFILES" + POMAKEFILEDEPS="POTFILES.in" + # ALL_LINGUAS, POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES depend + # on $ac_dir but don't depend on user-specified configuration +@@ -129,12 +130,12 @@ changequote([,])dnl + test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is obsolete" + fi + ALL_LINGUAS_=`sed -e "/^#/d" -e "s/#.*//" "$ac_given_srcdir/$ac_dir/LINGUAS"` +- # Hide the ALL_LINGUAS assigment from automake < 1.5. ++ # Hide the ALL_LINGUAS assignment from automake < 1.5. + eval 'ALL_LINGUAS''=$ALL_LINGUAS_' + POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS" + else + # The set of available languages was given in configure.in. +- # Hide the ALL_LINGUAS assigment from automake < 1.5. ++ # Hide the ALL_LINGUAS assignment from automake < 1.5. + eval 'ALL_LINGUAS''=$OBSOLETE_ALL_LINGUAS' + fi + # Compute POFILES +@@ -226,7 +227,7 @@ AC_DEFUN([AM_POSTPROCESS_PO_MAKEFILE], + changequote(,)dnl + # Adjust a relative srcdir. + ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'` +- ac_dir_suffix="/`echo "$ac_dir"|sed 's%^\./%%'`" ++ ac_dir_suffix=/`echo "$ac_dir"|sed 's%^\./%%'` + ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'` + # In autoconf-2.13 it is called $ac_given_srcdir. + # In autoconf-2.50 it is called $srcdir. +@@ -254,6 +255,7 @@ EOT + fi + + # A sed script that extracts the value of VARIABLE from a Makefile. ++ tab=`printf '\t'` + sed_x_variable=' + # Test if the hold space is empty. + x +@@ -261,9 +263,9 @@ s/P/P/ + x + ta + # Yes it was empty. Look if we have the expected variable definition. +-/^[ ]*VARIABLE[ ]*=/{ ++/^['"${tab}"' ]*VARIABLE['"${tab}"' ]*=/{ + # Seen the first line of the variable definition. +- s/^[ ]*VARIABLE[ ]*=// ++ s/^['"${tab}"' ]*VARIABLE['"${tab}"' ]*=// + ba + } + bd +@@ -315,7 +317,7 @@ changequote([,])dnl + sed_x_LINGUAS=`$gt_echo "$sed_x_variable" | sed -e '/^ *#/d' -e 's/VARIABLE/LINGUAS/g'` + ALL_LINGUAS_=`sed -n -e "$sed_x_LINGUAS" < "$ac_file"` + fi +- # Hide the ALL_LINGUAS assigment from automake < 1.5. ++ # Hide the ALL_LINGUAS assignment from automake < 1.5. + eval 'ALL_LINGUAS''=$ALL_LINGUAS_' + # Compute POFILES + # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).po) +@@ -405,14 +407,15 @@ changequote([,])dnl + fi + + sed -e "s|@POTFILES_DEPS@|$POTFILES_DEPS|g" -e "s|@POFILES@|$POFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@PROPERTIESFILES@|$PROPERTIESFILES|g" -e "s|@CLASSFILES@|$CLASSFILES|g" -e "s|@QMFILES@|$QMFILES|g" -e "s|@MSGFILES@|$MSGFILES|g" -e "s|@RESOURCESDLLFILES@|$RESOURCESDLLFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" -e "s|@JAVACATALOGS@|$JAVACATALOGS|g" -e "s|@QTCATALOGS@|$QTCATALOGS|g" -e "s|@TCLCATALOGS@|$TCLCATALOGS|g" -e "s|@CSHARPCATALOGS@|$CSHARPCATALOGS|g" -e 's,^#distdir:,distdir:,' < "$ac_file" > "$ac_file.tmp" ++ tab=`printf '\t'` + if grep -l '@TCLCATALOGS@' "$ac_file" > /dev/null; then + # Add dependencies that cannot be formulated as a simple suffix rule. + for lang in $ALL_LINGUAS; do + frobbedlang=`echo $lang | sed -e 's/\..*$//' -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'` + cat >> "$ac_file.tmp" <> "$ac_file.tmp" <= 5. + freebsd[1-4]*) gl_cv_func_printf_sizes_c99="guessing no";; + freebsd* | kfreebsd*) gl_cv_func_printf_sizes_c99="guessing yes";; +- # Guess yes on MacOS X >= 10.3. ++ # Guess yes on Mac OS X >= 10.3. + darwin[1-6].*) gl_cv_func_printf_sizes_c99="guessing no";; + darwin*) gl_cv_func_printf_sizes_c99="guessing yes";; + # Guess yes on OpenBSD >= 3.9. +@@ -70,8 +71,8 @@ changequote(,)dnl + gl_cv_func_printf_sizes_c99="guessing no";; + openbsd*) gl_cv_func_printf_sizes_c99="guessing yes";; + # Guess yes on Solaris >= 2.10. +- solaris2.[0-9]*) gl_cv_func_printf_sizes_c99="guessing no";; +- solaris*) gl_cv_func_printf_sizes_c99="guessing yes";; ++ solaris2.[1-9][0-9]*) gl_cv_func_printf_sizes_c99="guessing yes";; ++ solaris*) gl_cv_func_printf_sizes_c99="guessing no";; + # Guess yes on NetBSD >= 3. + netbsd[1-2]* | netbsdelf[1-2]* | netbsdaout[1-2]* | netbsdcoff[1-2]*) + gl_cv_func_printf_sizes_c99="guessing no";; +@@ -102,19 +103,20 @@ AC_DEFUN([gl_PRINTF_LONG_DOUBLE], + static char buf[10000]; + int main () + { ++ int result = 0; + buf[0] = '\0'; + if (sprintf (buf, "%Lf %d", 1.75L, 33, 44, 55) < 0 + || strcmp (buf, "1.750000 33") != 0) +- return 1; ++ result |= 1; + buf[0] = '\0'; + if (sprintf (buf, "%Le %d", 1.75L, 33, 44, 55) < 0 + || strcmp (buf, "1.750000e+00 33") != 0) +- return 1; ++ result |= 2; + buf[0] = '\0'; + if (sprintf (buf, "%Lg %d", 1.75L, 33, 44, 55) < 0 + || strcmp (buf, "1.75 33") != 0) +- return 1; +- return 0; ++ result |= 4; ++ return result; + }]])], + [gl_cv_func_printf_long_double=yes], + [gl_cv_func_printf_long_double=no], +@@ -175,39 +177,40 @@ static char buf[10000]; + static double zero = 0.0; + int main () + { +- if (sprintf (buf, "%f", 1.0 / 0.0) < 0 ++ int result = 0; ++ if (sprintf (buf, "%f", 1.0 / zero) < 0 + || (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0)) +- return 1; +- if (sprintf (buf, "%f", -1.0 / 0.0) < 0 ++ result |= 1; ++ if (sprintf (buf, "%f", -1.0 / zero) < 0 + || (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0)) +- return 1; ++ result |= 1; + if (sprintf (buf, "%f", zero / zero) < 0 + || !strisnan (buf, 0, strlen (buf))) +- return 1; +- if (sprintf (buf, "%e", 1.0 / 0.0) < 0 ++ result |= 2; ++ if (sprintf (buf, "%e", 1.0 / zero) < 0 + || (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0)) +- return 1; +- if (sprintf (buf, "%e", -1.0 / 0.0) < 0 ++ result |= 4; ++ if (sprintf (buf, "%e", -1.0 / zero) < 0 + || (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0)) +- return 1; ++ result |= 4; + if (sprintf (buf, "%e", zero / zero) < 0 + || !strisnan (buf, 0, strlen (buf))) +- return 1; +- if (sprintf (buf, "%g", 1.0 / 0.0) < 0 ++ result |= 8; ++ if (sprintf (buf, "%g", 1.0 / zero) < 0 + || (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0)) +- return 1; +- if (sprintf (buf, "%g", -1.0 / 0.0) < 0 ++ result |= 16; ++ if (sprintf (buf, "%g", -1.0 / zero) < 0 + || (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0)) +- return 1; ++ result |= 16; + if (sprintf (buf, "%g", zero / zero) < 0 + || !strisnan (buf, 0, strlen (buf))) +- return 1; ++ result |= 32; + /* This test fails on HP-UX 10.20. */ + if (have_minus_zero ()) + if (sprintf (buf, "%g", - zero) < 0 + || strcmp (buf, "-0") != 0) +- return 1; +- return 0; ++ result |= 64; ++ return result; + }]])], + [gl_cv_func_printf_infinite=yes], + [gl_cv_func_printf_infinite=no], +@@ -219,7 +222,7 @@ changequote(,)dnl + # Guess yes on FreeBSD >= 6. + freebsd[1-5]*) gl_cv_func_printf_infinite="guessing no";; + freebsd* | kfreebsd*) gl_cv_func_printf_infinite="guessing yes";; +- # Guess yes on MacOS X >= 10.3. ++ # Guess yes on Mac OS X >= 10.3. + darwin[1-6].*) gl_cv_func_printf_infinite="guessing no";; + darwin*) gl_cv_func_printf_infinite="guessing yes";; + # Guess yes on HP-UX >= 11. +@@ -248,6 +251,7 @@ AC_DEFUN([gl_PRINTF_INFINITE_LONG_DOUBLE], + AC_REQUIRE([gl_PRINTF_LONG_DOUBLE]) + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([gl_BIGENDIAN]) ++ AC_REQUIRE([gl_LONG_DOUBLE_VS_DOUBLE]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + dnl The user can set or unset the variable gl_printf_safe to indicate + dnl that he wishes a safe handling of non-IEEE-754 'long double' values. +@@ -289,35 +293,36 @@ static char buf[10000]; + static long double zeroL = 0.0L; + int main () + { ++ int result = 0; + nocrash_init(); +- if (sprintf (buf, "%Lf", 1.0L / 0.0L) < 0 ++ if (sprintf (buf, "%Lf", 1.0L / zeroL) < 0 + || (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0)) +- return 1; +- if (sprintf (buf, "%Lf", -1.0L / 0.0L) < 0 ++ result |= 1; ++ if (sprintf (buf, "%Lf", -1.0L / zeroL) < 0 + || (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0)) +- return 1; ++ result |= 1; + if (sprintf (buf, "%Lf", zeroL / zeroL) < 0 + || !strisnan (buf, 0, strlen (buf))) +- return 1; +- if (sprintf (buf, "%Le", 1.0L / 0.0L) < 0 ++ result |= 1; ++ if (sprintf (buf, "%Le", 1.0L / zeroL) < 0 + || (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0)) +- return 1; +- if (sprintf (buf, "%Le", -1.0L / 0.0L) < 0 ++ result |= 1; ++ if (sprintf (buf, "%Le", -1.0L / zeroL) < 0 + || (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0)) +- return 1; ++ result |= 1; + if (sprintf (buf, "%Le", zeroL / zeroL) < 0 + || !strisnan (buf, 0, strlen (buf))) +- return 1; +- if (sprintf (buf, "%Lg", 1.0L / 0.0L) < 0 ++ result |= 1; ++ if (sprintf (buf, "%Lg", 1.0L / zeroL) < 0 + || (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0)) +- return 1; +- if (sprintf (buf, "%Lg", -1.0L / 0.0L) < 0 ++ result |= 1; ++ if (sprintf (buf, "%Lg", -1.0L / zeroL) < 0 + || (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0)) +- return 1; ++ result |= 1; + if (sprintf (buf, "%Lg", zeroL / zeroL) < 0 + || !strisnan (buf, 0, strlen (buf))) +- return 1; +-#if CHECK_PRINTF_SAFE && ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_)) ++ result |= 1; ++#if CHECK_PRINTF_SAFE && ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_)) && !HAVE_SAME_LONG_DOUBLE_AS_DOUBLE + /* Representation of an 80-bit 'long double' as an initializer for a sequence + of 'unsigned int' words. */ + # ifdef WORDS_BIGENDIAN +@@ -335,13 +340,13 @@ int main () + { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) }; + if (sprintf (buf, "%Lf", x.value) < 0 + || !strisnan (buf, 0, strlen (buf))) +- return 1; ++ result |= 2; + if (sprintf (buf, "%Le", x.value) < 0 + || !strisnan (buf, 0, strlen (buf))) +- return 1; ++ result |= 2; + if (sprintf (buf, "%Lg", x.value) < 0 + || !strisnan (buf, 0, strlen (buf))) +- return 1; ++ result |= 2; + } + { + /* Signalling NaN. */ +@@ -349,81 +354,81 @@ int main () + { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) }; + if (sprintf (buf, "%Lf", x.value) < 0 + || !strisnan (buf, 0, strlen (buf))) +- return 1; ++ result |= 2; + if (sprintf (buf, "%Le", x.value) < 0 + || !strisnan (buf, 0, strlen (buf))) +- return 1; ++ result |= 2; + if (sprintf (buf, "%Lg", x.value) < 0 + || !strisnan (buf, 0, strlen (buf))) +- return 1; ++ result |= 2; + } + { /* Pseudo-NaN. */ + static union { unsigned int word[4]; long double value; } x = + { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) }; + if (sprintf (buf, "%Lf", x.value) < 0 + || !strisnan (buf, 0, strlen (buf))) +- return 1; ++ result |= 4; + if (sprintf (buf, "%Le", x.value) < 0 + || !strisnan (buf, 0, strlen (buf))) +- return 1; ++ result |= 4; + if (sprintf (buf, "%Lg", x.value) < 0 + || !strisnan (buf, 0, strlen (buf))) +- return 1; ++ result |= 4; + } + { /* Pseudo-Infinity. */ + static union { unsigned int word[4]; long double value; } x = + { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) }; + if (sprintf (buf, "%Lf", x.value) < 0 + || !strisnan (buf, 0, strlen (buf))) +- return 1; ++ result |= 8; + if (sprintf (buf, "%Le", x.value) < 0 + || !strisnan (buf, 0, strlen (buf))) +- return 1; ++ result |= 8; + if (sprintf (buf, "%Lg", x.value) < 0 + || !strisnan (buf, 0, strlen (buf))) +- return 1; ++ result |= 8; + } + { /* Pseudo-Zero. */ + static union { unsigned int word[4]; long double value; } x = + { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) }; + if (sprintf (buf, "%Lf", x.value) < 0 + || !strisnan (buf, 0, strlen (buf))) +- return 1; ++ result |= 16; + if (sprintf (buf, "%Le", x.value) < 0 + || !strisnan (buf, 0, strlen (buf))) +- return 1; ++ result |= 16; + if (sprintf (buf, "%Lg", x.value) < 0 + || !strisnan (buf, 0, strlen (buf))) +- return 1; ++ result |= 16; + } + { /* Unnormalized number. */ + static union { unsigned int word[4]; long double value; } x = + { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) }; + if (sprintf (buf, "%Lf", x.value) < 0 + || !strisnan (buf, 0, strlen (buf))) +- return 1; ++ result |= 32; + if (sprintf (buf, "%Le", x.value) < 0 + || !strisnan (buf, 0, strlen (buf))) +- return 1; ++ result |= 32; + if (sprintf (buf, "%Lg", x.value) < 0 + || !strisnan (buf, 0, strlen (buf))) +- return 1; ++ result |= 32; + } + { /* Pseudo-Denormal. */ + static union { unsigned int word[4]; long double value; } x = + { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) }; + if (sprintf (buf, "%Lf", x.value) < 0 + || !strisnan (buf, 0, strlen (buf))) +- return 1; ++ result |= 64; + if (sprintf (buf, "%Le", x.value) < 0 + || !strisnan (buf, 0, strlen (buf))) +- return 1; ++ result |= 64; + if (sprintf (buf, "%Lg", x.value) < 0 + || !strisnan (buf, 0, strlen (buf))) +- return 1; ++ result |= 64; + } + #endif +- return 0; ++ return result; + }]])], + [gl_cv_func_printf_infinite_long_double=yes], + [gl_cv_func_printf_infinite_long_double=no], +@@ -439,16 +444,9 @@ changequote(,)dnl + # Guess yes on FreeBSD >= 6. + freebsd[1-5]*) gl_cv_func_printf_infinite_long_double="guessing no";; + freebsd* | kfreebsd*) gl_cv_func_printf_infinite_long_double="guessing yes";; +- # Guess yes on MacOS X >= 10.3. +- darwin[1-6].*) gl_cv_func_printf_infinite_long_double="guessing no";; +- darwin*) gl_cv_func_printf_infinite_long_double="guessing yes";; + # Guess yes on HP-UX >= 11. + hpux[7-9]* | hpux10*) gl_cv_func_printf_infinite_long_double="guessing no";; + hpux*) gl_cv_func_printf_infinite_long_double="guessing yes";; +- # Guess yes on NetBSD >= 3. +- netbsd[1-2]* | netbsdelf[1-2]* | netbsdaout[1-2]* | netbsdcoff[1-2]*) +- gl_cv_func_printf_infinite_long_double="guessing no";; +- netbsd*) gl_cv_func_printf_infinite_long_double="guessing yes";; + # If we don't know, assume the worst. + *) gl_cv_func_printf_infinite_long_double="guessing no";; + esac +@@ -481,48 +479,50 @@ AC_DEFUN([gl_PRINTF_DIRECTIVE_A], + #include + #include + static char buf[100]; ++static double zero = 0.0; + int main () + { ++ int result = 0; + if (sprintf (buf, "%a %d", 3.1416015625, 33, 44, 55) < 0 + || (strcmp (buf, "0x1.922p+1 33") != 0 + && strcmp (buf, "0x3.244p+0 33") != 0 + && strcmp (buf, "0x6.488p-1 33") != 0 + && strcmp (buf, "0xc.91p-2 33") != 0)) +- return 1; ++ result |= 1; + if (sprintf (buf, "%A %d", -3.1416015625, 33, 44, 55) < 0 + || (strcmp (buf, "-0X1.922P+1 33") != 0 + && strcmp (buf, "-0X3.244P+0 33") != 0 + && strcmp (buf, "-0X6.488P-1 33") != 0 + && strcmp (buf, "-0XC.91P-2 33") != 0)) +- return 1; ++ result |= 2; + /* This catches a FreeBSD 6.1 bug: it doesn't round. */ + if (sprintf (buf, "%.2a %d", 1.51, 33, 44, 55) < 0 + || (strcmp (buf, "0x1.83p+0 33") != 0 + && strcmp (buf, "0x3.05p-1 33") != 0 + && strcmp (buf, "0x6.0ap-2 33") != 0 + && strcmp (buf, "0xc.14p-3 33") != 0)) +- return 1; ++ result |= 4; + /* This catches a FreeBSD 6.1 bug. See + */ +- if (sprintf (buf, "%010a %d", 1.0 / 0.0, 33, 44, 55) < 0 ++ if (sprintf (buf, "%010a %d", 1.0 / zero, 33, 44, 55) < 0 + || buf[0] == '0') +- return 1; +- /* This catches a MacOS X 10.3.9 (Darwin 7.9) bug. */ ++ result |= 8; ++ /* This catches a Mac OS X 10.3.9 (Darwin 7.9) bug. */ + if (sprintf (buf, "%.1a", 1.999) < 0 + || (strcmp (buf, "0x1.0p+1") != 0 + && strcmp (buf, "0x2.0p+0") != 0 + && strcmp (buf, "0x4.0p-1") != 0 + && strcmp (buf, "0x8.0p-2") != 0)) +- return 1; +- /* This catches the same MacOS X 10.3.9 (Darwin 7.9) bug and also a ++ result |= 16; ++ /* This catches the same Mac OS X 10.3.9 (Darwin 7.9) bug and also a + glibc 2.4 bug . */ + if (sprintf (buf, "%.1La", 1.999L) < 0 + || (strcmp (buf, "0x1.0p+1") != 0 + && strcmp (buf, "0x2.0p+0") != 0 + && strcmp (buf, "0x4.0p-1") != 0 + && strcmp (buf, "0x8.0p-2") != 0)) +- return 1; +- return 0; ++ result |= 32; ++ return result; + }]])], + [gl_cv_func_printf_directive_a=yes], + [gl_cv_func_printf_directive_a=no], +@@ -533,7 +533,7 @@ int main () + AC_EGREP_CPP([BZ2908], [ + #include + #ifdef __GNU_LIBRARY__ +- #if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 5) || (__GLIBC__ > 2) ++ #if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 5) || (__GLIBC__ > 2)) && !defined __UCLIBC__ + BZ2908 + #endif + #endif +@@ -564,19 +564,21 @@ AC_DEFUN([gl_PRINTF_DIRECTIVE_F], + #include + #include + static char buf[100]; ++static double zero = 0.0; + int main () + { ++ int result = 0; + if (sprintf (buf, "%F %d", 1234567.0, 33, 44, 55) < 0 + || strcmp (buf, "1234567.000000 33") != 0) +- return 1; +- if (sprintf (buf, "%F", 1.0 / 0.0) < 0 ++ result |= 1; ++ if (sprintf (buf, "%F", 1.0 / zero) < 0 + || (strcmp (buf, "INF") != 0 && strcmp (buf, "INFINITY") != 0)) +- return 1; ++ result |= 2; + /* This catches a Cygwin 1.5.x bug. */ + if (sprintf (buf, "%.F", 1234.0) < 0 + || strcmp (buf, "1234") != 0) +- return 1; +- return 0; ++ result |= 4; ++ return result; + }]])], + [gl_cv_func_printf_directive_f=yes], + [gl_cv_func_printf_directive_f=no], +@@ -588,12 +590,12 @@ changequote(,)dnl + # Guess yes on FreeBSD >= 6. + freebsd[1-5]*) gl_cv_func_printf_directive_f="guessing no";; + freebsd* | kfreebsd*) gl_cv_func_printf_directive_f="guessing yes";; +- # Guess yes on MacOS X >= 10.3. ++ # Guess yes on Mac OS X >= 10.3. + darwin[1-6].*) gl_cv_func_printf_directive_f="guessing no";; + darwin*) gl_cv_func_printf_directive_f="guessing yes";; + # Guess yes on Solaris >= 2.10. +- solaris2.[0-9]*) gl_cv_func_printf_directive_f="guessing no";; +- solaris*) gl_cv_func_printf_directive_f="guessing yes";; ++ solaris2.[1-9][0-9]*) gl_cv_func_printf_sizes_c99="guessing yes";; ++ solaris*) gl_cv_func_printf_sizes_c99="guessing no";; + # If we don't know, assume the worst. + *) gl_cv_func_printf_directive_f="guessing no";; + esac +@@ -616,12 +618,27 @@ AC_DEFUN([gl_PRINTF_DIRECTIVE_N], + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ + #include ++#include + #include ++#ifdef _MSC_VER ++/* See page about "Parameter Validation" on msdn.microsoft.com. */ ++static void cdecl ++invalid_parameter_handler (const wchar_t *expression, ++ const wchar_t *function, ++ const wchar_t *file, unsigned int line, ++ uintptr_t dummy) ++{ ++ exit (1); ++} ++#endif + static char fmtstring[10]; + static char buf[100]; + int main () + { + int count = -1; ++#ifdef _MSC_VER ++ _set_invalid_parameter_handler (invalid_parameter_handler); ++#endif + /* Copy the format string. Some systems (glibc with _FORTIFY_SOURCE=2) + support %n in format strings in read-only memory but not in writable + memory. */ +@@ -637,7 +654,8 @@ int main () + [ + changequote(,)dnl + case "$host_os" in +- *) gl_cv_func_printf_directive_n="guessing yes";; ++ mingw*) gl_cv_func_printf_directive_n="guessing no";; ++ *) gl_cv_func_printf_directive_n="guessing yes";; + esac + changequote([,])dnl + ]) +@@ -671,6 +689,7 @@ AC_DEFUN([gl_PRINTF_DIRECTIVE_LS], + #include + int main () + { ++ int result = 0; + char buf[100]; + /* Test whether %ls works at all. + This test fails on OpenBSD 4.0, IRIX 6.5, Solaris 2.6, Haiku, but not on +@@ -680,7 +699,7 @@ int main () + buf[0] = '\0'; + if (sprintf (buf, "%ls", wstring) < 0 + || strcmp (buf, "abc") != 0) +- return 1; ++ result |= 1; + } + /* This test fails on IRIX 6.5, Solaris 2.6, Cygwin 1.5, Haiku (with an + assertion failure inside libc), but not on OpenBSD 4.0. */ +@@ -689,7 +708,7 @@ int main () + buf[0] = '\0'; + if (sprintf (buf, "%ls", wstring) < 0 + || strcmp (buf, "a") != 0) +- return 1; ++ result |= 2; + } + /* Test whether precisions in %ls are supported as specified in ISO C 99 + section 7.19.6.1: +@@ -704,9 +723,9 @@ int main () + buf[0] = '\0'; + if (sprintf (buf, "%.2ls", wstring) < 0 + || strcmp (buf, "ab") != 0) +- return 1; ++ result |= 8; + } +- return 0; ++ return result; + }]])], + [gl_cv_func_printf_directive_ls=yes], + [gl_cv_func_printf_directive_ls=no], +@@ -862,9 +881,10 @@ AC_DEFUN([gl_PRINTF_FLAG_ZERO], + #include + #include + static char buf[100]; ++static double zero = 0.0; + int main () + { +- if (sprintf (buf, "%010f", 1.0 / 0.0, 33, 44, 55) < 0 ++ if (sprintf (buf, "%010f", 1.0 / zero, 33, 44, 55) < 0 + || (strcmp (buf, " inf") != 0 + && strcmp (buf, " infinity") != 0)) + return 1; +@@ -889,8 +909,11 @@ changequote([,])dnl + + dnl Test whether the *printf family of functions supports large precisions. + dnl On mingw, precisions larger than 512 are treated like 512, in integer, +-dnl floating-point or pointer output. On BeOS, precisions larger than 1044 +-dnl crash the program. ++dnl floating-point or pointer output. On Solaris 10/x86, precisions larger ++dnl than 510 in floating-point output crash the program. On Solaris 10/SPARC, ++dnl precisions larger than 510 in floating-point output yield wrong results. ++dnl On AIX 7.1, precisions larger than 998 in floating-point output yield ++dnl wrong results. On BeOS, precisions larger than 1044 crash the program. + dnl Result is gl_cv_func_printf_precision. + + AC_DEFUN([gl_PRINTF_PRECISION], +@@ -907,20 +930,30 @@ AC_DEFUN([gl_PRINTF_PRECISION], + static char buf[5000]; + int main () + { ++ int result = 0; + #ifdef __BEOS__ + /* On BeOS, this would crash and show a dialog box. Avoid the crash. */ + return 1; + #endif + if (sprintf (buf, "%.4000d %d", 1, 33, 44) < 4000 + 3) +- return 1; +- return 0; ++ result |= 1; ++ if (sprintf (buf, "%.4000f %d", 1.0, 33, 44) < 4000 + 5) ++ result |= 2; ++ if (sprintf (buf, "%.511f %d", 1.0, 33, 44) < 511 + 5 ++ || buf[0] != '1') ++ result |= 4; ++ if (sprintf (buf, "%.999f %d", 1.0, 33, 44) < 999 + 5 ++ || buf[0] != '1') ++ result |= 4; ++ return result; + }]])], + [gl_cv_func_printf_precision=yes], + [gl_cv_func_printf_precision=no], + [ + changequote(,)dnl + case "$host_os" in +- # Guess no only on native Win32 and BeOS systems. ++ # Guess no only on Solaris, native Windows, and BeOS systems. ++ solaris*) gl_cv_func_printf_precision="guessing no" ;; + mingw* | pw*) gl_cv_func_printf_precision="guessing no" ;; + beos*) gl_cv_func_printf_precision="guessing no" ;; + *) gl_cv_func_printf_precision="guessing yes" ;; +@@ -995,8 +1028,9 @@ int main() + changequote([,])dnl + ])]) + if AC_TRY_EVAL([ac_link]) && test -s conftest$ac_exeext; then +- (./conftest ++ (./conftest 2>&AS_MESSAGE_LOG_FD + result=$? ++ _AS_ECHO_LOG([\$? = $result]) + if test $result != 0 && test $result != 77; then result=1; fi + exit $result + ) >/dev/null 2>/dev/null +@@ -1010,7 +1044,7 @@ changequote([,])dnl + fi + rm -fr conftest* + else +- dnl A universal build on Apple MacOS X platforms. ++ dnl A universal build on Apple Mac OS X platforms. + dnl The result would be 'no' in 32-bit mode and 'yes' in 64-bit mode. + dnl But we need a configuration result that is valid in both modes. + gl_cv_func_printf_enomem="guessing no" +@@ -1063,6 +1097,7 @@ AC_DEFUN([gl_SNPRINTF_TRUNCATION_C99], + [ + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles ++ AC_REQUIRE([gl_SNPRINTF_PRESENCE]) + AC_CACHE_CHECK([whether snprintf truncates the result as in C99], + [gl_cv_func_snprintf_truncation_c99], + [ +@@ -1070,11 +1105,25 @@ AC_DEFUN([gl_SNPRINTF_TRUNCATION_C99], + [AC_LANG_SOURCE([[ + #include + #include ++#if HAVE_SNPRINTF ++# define my_snprintf snprintf ++#else ++# include ++static int my_snprintf (char *buf, int size, const char *format, ...) ++{ ++ va_list args; ++ int ret; ++ va_start (args, format); ++ ret = vsnprintf (buf, size, format, args); ++ va_end (args); ++ return ret; ++} ++#endif + static char buf[100]; + int main () + { + strcpy (buf, "ABCDEF"); +- snprintf (buf, 3, "%d %d", 4567, 89); ++ my_snprintf (buf, 3, "%d %d", 4567, 89); + if (memcmp (buf, "45\0DEF", 6) != 0) + return 1; + return 0; +@@ -1089,7 +1138,7 @@ changequote(,)dnl + # Guess yes on FreeBSD >= 5. + freebsd[1-4]*) gl_cv_func_snprintf_truncation_c99="guessing no";; + freebsd* | kfreebsd*) gl_cv_func_snprintf_truncation_c99="guessing yes";; +- # Guess yes on MacOS X >= 10.3. ++ # Guess yes on Mac OS X >= 10.3. + darwin[1-6].*) gl_cv_func_snprintf_truncation_c99="guessing no";; + darwin*) gl_cv_func_snprintf_truncation_c99="guessing yes";; + # Guess yes on OpenBSD >= 3.9. +@@ -1097,7 +1146,8 @@ changequote(,)dnl + gl_cv_func_snprintf_truncation_c99="guessing no";; + openbsd*) gl_cv_func_snprintf_truncation_c99="guessing yes";; + # Guess yes on Solaris >= 2.6. +- solaris2.[0-5]*) gl_cv_func_snprintf_truncation_c99="guessing no";; ++ solaris2.[0-5] | solaris2.[0-5].*) ++ gl_cv_func_snprintf_truncation_c99="guessing no";; + solaris*) gl_cv_func_snprintf_truncation_c99="guessing yes";; + # Guess yes on AIX >= 4. + aix[1-3]*) gl_cv_func_snprintf_truncation_c99="guessing no";; +@@ -1143,6 +1193,7 @@ AC_DEFUN_ONCE([gl_SNPRINTF_RETVAL_C99], + [ + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles ++ AC_REQUIRE([gl_SNPRINTF_PRESENCE]) + AC_CACHE_CHECK([whether snprintf returns a byte count as in C99], + [gl_cv_func_snprintf_retval_c99], + [ +@@ -1150,12 +1201,30 @@ AC_DEFUN_ONCE([gl_SNPRINTF_RETVAL_C99], + [AC_LANG_SOURCE([[ + #include + #include ++#if HAVE_SNPRINTF ++# define my_snprintf snprintf ++#else ++# include ++static int my_snprintf (char *buf, int size, const char *format, ...) ++{ ++ va_list args; ++ int ret; ++ va_start (args, format); ++ ret = vsnprintf (buf, size, format, args); ++ va_end (args); ++ return ret; ++} ++#endif + static char buf[100]; + int main () + { + strcpy (buf, "ABCDEF"); +- if (snprintf (buf, 3, "%d %d", 4567, 89) != 7) ++ if (my_snprintf (buf, 3, "%d %d", 4567, 89) != 7) + return 1; ++ if (my_snprintf (buf, 0, "%d %d", 4567, 89) != 7) ++ return 2; ++ if (my_snprintf (NULL, 0, "%d %d", 4567, 89) != 7) ++ return 3; + return 0; + }]])], + [gl_cv_func_snprintf_retval_c99=yes], +@@ -1168,16 +1237,16 @@ changequote(,)dnl + # Guess yes on FreeBSD >= 5. + freebsd[1-4]*) gl_cv_func_snprintf_retval_c99="guessing no";; + freebsd* | kfreebsd*) gl_cv_func_snprintf_retval_c99="guessing yes";; +- # Guess yes on MacOS X >= 10.3. ++ # Guess yes on Mac OS X >= 10.3. + darwin[1-6].*) gl_cv_func_snprintf_retval_c99="guessing no";; + darwin*) gl_cv_func_snprintf_retval_c99="guessing yes";; + # Guess yes on OpenBSD >= 3.9. + openbsd[1-2].* | openbsd3.[0-8] | openbsd3.[0-8].*) + gl_cv_func_snprintf_retval_c99="guessing no";; + openbsd*) gl_cv_func_snprintf_retval_c99="guessing yes";; +- # Guess yes on Solaris >= 2.6. +- solaris2.[0-5]*) gl_cv_func_snprintf_retval_c99="guessing no";; +- solaris*) gl_cv_func_snprintf_retval_c99="guessing yes";; ++ # Guess yes on Solaris >= 2.10. ++ solaris2.[1-9][0-9]*) gl_cv_func_printf_sizes_c99="guessing yes";; ++ solaris*) gl_cv_func_printf_sizes_c99="guessing no";; + # Guess yes on AIX >= 4. + aix[1-3]*) gl_cv_func_snprintf_retval_c99="guessing no";; + aix*) gl_cv_func_snprintf_retval_c99="guessing yes";; +@@ -1203,6 +1272,7 @@ AC_DEFUN([gl_SNPRINTF_DIRECTIVE_N], + [ + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles ++ AC_REQUIRE([gl_SNPRINTF_PRESENCE]) + AC_CACHE_CHECK([whether snprintf fully supports the 'n' directive], + [gl_cv_func_snprintf_directive_n], + [ +@@ -1210,6 +1280,20 @@ AC_DEFUN([gl_SNPRINTF_DIRECTIVE_N], + [AC_LANG_SOURCE([[ + #include + #include ++#if HAVE_SNPRINTF ++# define my_snprintf snprintf ++#else ++# include ++static int my_snprintf (char *buf, int size, const char *format, ...) ++{ ++ va_list args; ++ int ret; ++ va_start (args, format); ++ ret = vsnprintf (buf, size, format, args); ++ va_end (args); ++ return ret; ++} ++#endif + static char fmtstring[10]; + static char buf[100]; + int main () +@@ -1219,7 +1303,7 @@ int main () + support %n in format strings in read-only memory but not in writable + memory. */ + strcpy (fmtstring, "%d %n"); +- snprintf (buf, 4, fmtstring, 12345, &count, 33, 44, 55); ++ my_snprintf (buf, 4, fmtstring, 12345, &count, 33, 44, 55); + if (count != 6) + return 1; + return 0; +@@ -1234,11 +1318,12 @@ changequote(,)dnl + # Guess yes on FreeBSD >= 5. + freebsd[1-4]*) gl_cv_func_snprintf_directive_n="guessing no";; + freebsd* | kfreebsd*) gl_cv_func_snprintf_directive_n="guessing yes";; +- # Guess yes on MacOS X >= 10.3. ++ # Guess yes on Mac OS X >= 10.3. + darwin[1-6].*) gl_cv_func_snprintf_directive_n="guessing no";; + darwin*) gl_cv_func_snprintf_directive_n="guessing yes";; + # Guess yes on Solaris >= 2.6. +- solaris2.[0-5]*) gl_cv_func_snprintf_directive_n="guessing no";; ++ solaris2.[0-5] | solaris2.[0-5].*) ++ gl_cv_func_snprintf_directive_n="guessing no";; + solaris*) gl_cv_func_snprintf_directive_n="guessing yes";; + # Guess yes on AIX >= 4. + aix[1-3]*) gl_cv_func_snprintf_directive_n="guessing no";; +@@ -1270,16 +1355,31 @@ dnl Result is gl_cv_func_snprintf_size1. + AC_DEFUN([gl_SNPRINTF_SIZE1], + [ + AC_REQUIRE([AC_PROG_CC]) ++ AC_REQUIRE([gl_SNPRINTF_PRESENCE]) + AC_CACHE_CHECK([whether snprintf respects a size of 1], + [gl_cv_func_snprintf_size1], + [ + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ + #include ++#if HAVE_SNPRINTF ++# define my_snprintf snprintf ++#else ++# include ++static int my_snprintf (char *buf, int size, const char *format, ...) ++{ ++ va_list args; ++ int ret; ++ va_start (args, format); ++ ret = vsnprintf (buf, size, format, args); ++ va_end (args); ++ return ret; ++} ++#endif + int main() + { + static char buf[8] = { 'D', 'E', 'A', 'D', 'B', 'E', 'E', 'F' }; +- snprintf (buf, 1, "%d", 12345); ++ my_snprintf (buf, 1, "%d", 12345); + return buf[1] != 'E'; + }]])], + [gl_cv_func_snprintf_size1=yes], +@@ -1360,13 +1460,14 @@ changequote(,)dnl + # Guess yes on FreeBSD >= 5. + freebsd[1-4]*) gl_cv_func_vsnprintf_zerosize_c99="guessing no";; + freebsd* | kfreebsd*) gl_cv_func_vsnprintf_zerosize_c99="guessing yes";; +- # Guess yes on MacOS X >= 10.3. ++ # Guess yes on Mac OS X >= 10.3. + darwin[1-6].*) gl_cv_func_vsnprintf_zerosize_c99="guessing no";; + darwin*) gl_cv_func_vsnprintf_zerosize_c99="guessing yes";; + # Guess yes on Cygwin. + cygwin*) gl_cv_func_vsnprintf_zerosize_c99="guessing yes";; + # Guess yes on Solaris >= 2.6. +- solaris2.[0-5]*) gl_cv_func_vsnprintf_zerosize_c99="guessing no";; ++ solaris2.[0-5] | solaris2.[0-5].*) ++ gl_cv_func_vsnprintf_zerosize_c99="guessing no";; + solaris*) gl_cv_func_vsnprintf_zerosize_c99="guessing yes";; + # Guess yes on AIX >= 4. + aix[1-3]*) gl_cv_func_vsnprintf_zerosize_c99="guessing no";; +@@ -1439,24 +1540,31 @@ dnl 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 + dnl glibc 2.5 . . . . . . . . . . . . . . . . . . . . + dnl glibc 2.3.6 . . . . # . . . . . . . . . . . . . . . + dnl FreeBSD 5.4, 6.1 . . . . # . . . . . . # . # . . . . . . +-dnl MacOS X 10.3.9 . . . . # . . . . . . # . # . . . . . . ++dnl Mac OS X 10.5.8 . . . # # . . . . . . # . . . . . . . . ++dnl Mac OS X 10.3.9 . . . . # . . . . . . # . # . . . . . . + dnl OpenBSD 3.9, 4.0 . . # # # # . # . # . # . # . . . . . . + dnl Cygwin 1.7.0 (2009) . . . # . . . ? . . . . . ? . . . . . . + dnl Cygwin 1.5.25 (2008) . . . # # . . # . . . . . # . . . . . . + dnl Cygwin 1.5.19 (2006) # . . # # # . # . # . # # # . . . . . . +-dnl Solaris 10 . . # # # . . # . . . # . . . . . . . . +-dnl Solaris 2.6 ... 9 # . # # # # . # . . . # . . . . . . . . ++dnl Solaris 11 2011-11 . . # # # . . # . . . # . . . . . . . . ++dnl Solaris 10 . . # # # . . # . . . # # . . . . . . . ++dnl Solaris 2.6 ... 9 # . # # # # . # . . . # # . . . # . . . + dnl Solaris 2.5.1 # . # # # # . # . . . # . . # # # # # # +-dnl AIX 5.2, 7.1 . . # # # . . . . . . # . . . . . . . . +-dnl AIX 4.3.2, 5.1 # . # # # # . . . . . # . . . . . . . . ++dnl AIX 7.1 . . # # # . . . . . . # # . . . . . . . ++dnl AIX 5.2 . . # # # . . . . . . # . . . . . . . . ++dnl AIX 4.3.2, 5.1 # . # # # # . . . . . # . . . . # . . . + dnl HP-UX 11.31 . . . . # . . . . . . # . . . . # # . . + dnl HP-UX 11.{00,11,23} # . . . # # . . . . . # . . . . # # . # + dnl HP-UX 10.20 # . # . # # . ? . . # # . . . . # # ? # + dnl IRIX 6.5 # . # # # # . # . . . # . . . . # . . . + dnl OSF/1 5.1 # . # # # # . . . . . # . . . . # . . # + dnl OSF/1 4.0d # . # # # # . . . . . # . . # # # # # # ++dnl NetBSD 5.0 . . . # # . . . . . . # . # . . . . . . + dnl NetBSD 4.0 . ? ? ? ? ? . ? . ? ? ? ? ? . . . ? ? ? + dnl NetBSD 3.0 . . . . # # . ? # # ? # . # . . . . . . +-dnl Haiku . . . # # # . # . . . . . ? . . . . . . +-dnl BeOS # # . # # # . ? # . ? . # ? . . . . . . +-dnl mingw # # # # # # . . # # . # # ? . # # # . . ++dnl Haiku . . . # # # . # . . . . . ? . . ? . . . ++dnl BeOS # # . # # # . ? # . ? . # ? . . ? . . . ++dnl old mingw / msvcrt # # # # # # . . # # . # # ? . # # # . . ++dnl MSVC 9 # # # # # # # . # # . # # ? # # # # . . ++dnl mingw 2009-2011 . # . # . . . . # # . . . ? . . . . . . ++dnl mingw-w64 2011 # # # # # # . . # # . # # ? . # # # . . +diff --git a/m4/progtest.m4 b/m4/progtest.m4 +index 9ffa5c0..7b39123 100644 +--- a/m4/progtest.m4 ++++ b/m4/progtest.m4 +@@ -1,5 +1,5 @@ + # progtest.m4 serial 7 (gettext-0.18.2) +-dnl Copyright (C) 1996-2003, 2005, 2008-2010 Free Software Foundation, Inc. ++dnl Copyright (C) 1996-2003, 2005, 2008-2013 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. +diff --git a/m4/rawmemchr.m4 b/m4/rawmemchr.m4 +index 2a25a49..8c50054 100644 +--- a/m4/rawmemchr.m4 ++++ b/m4/rawmemchr.m4 +@@ -1,5 +1,5 @@ +-# rawmemchr.m4 serial 1 +-dnl Copyright (C) 2003, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. ++# rawmemchr.m4 serial 2 ++dnl Copyright (C) 2003, 2007-2013 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. +@@ -10,10 +10,9 @@ AC_DEFUN([gl_FUNC_RAWMEMCHR], + AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) + + AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS]) +- AC_REPLACE_FUNCS([rawmemchr]) ++ AC_CHECK_FUNCS([rawmemchr]) + if test $ac_cv_func_rawmemchr = no; then + HAVE_RAWMEMCHR=0 +- gl_PREREQ_RAWMEMCHR + fi + ]) + +diff --git a/m4/realloc.m4 b/m4/realloc.m4 +index 01c1234..d477fb4 100644 +--- a/m4/realloc.m4 ++++ b/m4/realloc.m4 +@@ -1,9 +1,47 @@ +-# realloc.m4 serial 11 +-dnl Copyright (C) 2007, 2009, 2010 Free Software Foundation, Inc. ++# realloc.m4 serial 13 ++dnl Copyright (C) 2007, 2009-2013 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. + ++m4_version_prereq([2.70], [] ,[ ++ ++# This is taken from the following Autoconf patch: ++# http://git.savannah.gnu.org/gitweb/?p=autoconf.git;a=commitdiff;h=7fbb553727ed7e0e689a17594b58559ecf3ea6e9 ++AC_DEFUN([_AC_FUNC_REALLOC_IF], ++[ ++ AC_REQUIRE([AC_HEADER_STDC])dnl ++ AC_REQUIRE([AC_CANONICAL_HOST])dnl for cross-compiles ++ AC_CHECK_HEADERS([stdlib.h]) ++ AC_CACHE_CHECK([for GNU libc compatible realloc], ++ [ac_cv_func_realloc_0_nonnull], ++ [AC_RUN_IFELSE( ++ [AC_LANG_PROGRAM( ++ [[#if defined STDC_HEADERS || defined HAVE_STDLIB_H ++ # include ++ #else ++ char *realloc (); ++ #endif ++ ]], ++ [[return ! realloc (0, 0);]]) ++ ], ++ [ac_cv_func_realloc_0_nonnull=yes], ++ [ac_cv_func_realloc_0_nonnull=no], ++ [case "$host_os" in ++ # Guess yes on platforms where we know the result. ++ *-gnu* | freebsd* | netbsd* | openbsd* \ ++ | hpux* | solaris* | cygwin* | mingw*) ++ ac_cv_func_realloc_0_nonnull=yes ;; ++ # If we don't know, assume the worst. ++ *) ac_cv_func_realloc_0_nonnull=no ;; ++ esac ++ ]) ++ ]) ++ AS_IF([test $ac_cv_func_realloc_0_nonnull = yes], [$1], [$2]) ++])# AC_FUNC_REALLOC ++ ++]) ++ + # gl_FUNC_REALLOC_GNU + # ------------------- + # Test whether 'realloc (0, 0)' is handled like in GNU libc, and replace +@@ -17,7 +55,7 @@ AC_DEFUN([gl_FUNC_REALLOC_GNU], + [Define to 1 if your system has a GNU libc compatible 'realloc' + function, and to 0 otherwise.])], + [AC_DEFINE([HAVE_REALLOC_GNU], [0]) +- gl_REPLACE_REALLOC ++ REPLACE_REALLOC=1 + ]) + ])# gl_FUNC_REALLOC_GNU + +@@ -33,12 +71,6 @@ AC_DEFUN([gl_FUNC_REALLOC_POSIX], + AC_DEFINE([HAVE_REALLOC_POSIX], [1], + [Define if the 'realloc' function is POSIX compliant.]) + else +- gl_REPLACE_REALLOC ++ REPLACE_REALLOC=1 + fi + ]) +- +-AC_DEFUN([gl_REPLACE_REALLOC], +-[ +- AC_LIBOBJ([realloc]) +- REPLACE_REALLOC=1 +-]) +diff --git a/m4/regex.m4 b/m4/regex.m4 +index 38f1dd7..3334c10 100644 +--- a/m4/regex.m4 ++++ b/m4/regex.m4 +@@ -1,7 +1,6 @@ +-# serial 56 ++# serial 64 + +-# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, +-# 2007, 2008, 2009, 2010 Free Software Foundation, Inc. ++# Copyright (C) 1996-2001, 2003-2013 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -14,8 +13,6 @@ AC_PREREQ([2.50]) + + AC_DEFUN([gl_REGEX], + [ +- AC_CHECK_HEADERS_ONCE([locale.h]) +- + AC_ARG_WITH([included-regex], + [AS_HELP_STRING([--without-included-regex], + [don't compile regex; this is the default on systems +@@ -30,31 +27,41 @@ AC_DEFUN([gl_REGEX], + # following run test, then default to *not* using the included regex.c. + # If cross compiling, assume the test would fail and use the included + # regex.c. ++ AC_CHECK_DECLS_ONCE([alarm]) + AC_CACHE_CHECK([for working re_compile_pattern], + [gl_cv_func_re_compile_pattern_working], + [AC_RUN_IFELSE( + [AC_LANG_PROGRAM( +- [AC_INCLUDES_DEFAULT[ +- #if HAVE_LOCALE_H ++ [[#include ++ + #include +- #endif +- #include +- #include +- ]], +- [[static struct re_pattern_buffer regex; ++ #include ++ #include ++ #if HAVE_DECL_ALARM ++ # include ++ # include ++ #endif ++ ]], ++ [[int result = 0; ++ static struct re_pattern_buffer regex; + unsigned char folded_chars[UCHAR_MAX + 1]; + int i; + const char *s; + struct re_registers regs; + +- #if HAVE_LOCALE_H +- /* http://sourceware.org/ml/libc-hacker/2006-09/msg00008.html +- This test needs valgrind to catch the bug on Debian +- GNU/Linux 3.1 x86, but it might catch the bug better +- on other platforms and it shouldn't hurt to try the +- test here. */ +- if (setlocale (LC_ALL, "en_US.UTF-8")) ++#if HAVE_DECL_ALARM ++ /* Some builds of glibc go into an infinite loop on this test. */ ++ signal (SIGALRM, SIG_DFL); ++ alarm (2); ++#endif ++ if (setlocale (LC_ALL, "en_US.UTF-8")) ++ { + { ++ /* http://sourceware.org/ml/libc-hacker/2006-09/msg00008.html ++ This test needs valgrind to catch the bug on Debian ++ GNU/Linux 3.1 x86, but it might catch the bug better ++ on other platforms and it shouldn't hurt to try the ++ test here. */ + static char const pat[] = "insert into"; + static char const data[] = + "\xFF\0\x12\xA2\xAA\xC4\xB1,K\x12\xC4\xB1*\xACK"; +@@ -63,26 +70,46 @@ AC_DEFUN([gl_REGEX], + memset (®ex, 0, sizeof regex); + s = re_compile_pattern (pat, sizeof pat - 1, ®ex); + if (s) +- return 1; +- if (re_search (®ex, data, sizeof data - 1, +- 0, sizeof data - 1, ®s) +- != -1) +- return 1; +- if (! setlocale (LC_ALL, "C")) +- return 1; ++ result |= 1; ++ else if (re_search (®ex, data, sizeof data - 1, ++ 0, sizeof data - 1, ®s) ++ != -1) ++ result |= 1; ++ } ++ ++ { ++ /* This test is from glibc bug 15078. ++ The test case is from Andreas Schwab in ++ . ++ */ ++ static char const pat[] = "[^x]x"; ++ static char const data[] = ++ "\xe1\x80\x80\xe1\x80\xbb\xe1\x80\xbd\xe1\x80\x94\xe1\x80" ++ "\xba\xe1\x80\xaf\xe1\x80\x95\xe1\x80\xbax"; ++ re_set_syntax (0); ++ memset (®ex, 0, sizeof regex); ++ s = re_compile_pattern (pat, sizeof pat - 1, ®ex); ++ if (s) ++ result |= 1; ++ else if (re_search (®ex, data, sizeof data - 1, ++ 0, sizeof data - 1, 0) ++ != 21) ++ result |= 1; + } +- #endif ++ ++ if (! setlocale (LC_ALL, "C")) ++ return 1; ++ } + + /* This test is from glibc bug 3957, reported by Andrew Mackey. */ + re_set_syntax (RE_SYNTAX_EGREP | RE_HAT_LISTS_NOT_NEWLINE); + memset (®ex, 0, sizeof regex); + s = re_compile_pattern ("a[^x]b", 6, ®ex); + if (s) +- return 1; +- ++ result |= 2; + /* This should fail, but succeeds for glibc-2.5. */ +- if (re_search (®ex, "a\nb", 3, 0, 3, ®s) != -1) +- return 1; ++ else if (re_search (®ex, "a\nb", 3, 0, 3, ®s) != -1) ++ result |= 2; + + /* This regular expression is from Spencer ere test number 75 + in grep-2.3. */ +@@ -94,7 +121,7 @@ AC_DEFUN([gl_REGEX], + s = re_compile_pattern ("a[[:@:>@:]]b\n", 11, ®ex); + /* This should fail with _Invalid character class name_ error. */ + if (!s) +- return 1; ++ result |= 4; + + /* Ensure that [b-a] is diagnosed as invalid, when + using RE_NO_EMPTY_RANGES. */ +@@ -102,34 +129,31 @@ AC_DEFUN([gl_REGEX], + memset (®ex, 0, sizeof regex); + s = re_compile_pattern ("a[b-a]", 6, ®ex); + if (s == 0) +- return 1; ++ result |= 8; + + /* This should succeed, but does not for glibc-2.1.3. */ + memset (®ex, 0, sizeof regex); + s = re_compile_pattern ("{1", 2, ®ex); +- + if (s) +- return 1; ++ result |= 8; + + /* The following example is derived from a problem report + against gawk from Jorge Stolfi . */ + memset (®ex, 0, sizeof regex); + s = re_compile_pattern ("[an\371]*n", 7, ®ex); + if (s) +- return 1; +- ++ result |= 8; + /* This should match, but does not for glibc-2.2.1. */ +- if (re_match (®ex, "an", 2, 0, ®s) != 2) +- return 1; ++ else if (re_match (®ex, "an", 2, 0, ®s) != 2) ++ result |= 8; + + memset (®ex, 0, sizeof regex); + s = re_compile_pattern ("x", 1, ®ex); + if (s) +- return 1; +- ++ result |= 8; + /* glibc-2.2.93 does not work with a negative RANGE argument. */ +- if (re_search (®ex, "wxy", 3, 2, -2, ®s) != 1) +- return 1; ++ else if (re_search (®ex, "wxy", 3, 2, -2, ®s) != 1) ++ result |= 8; + + /* The version of regex.c in older versions of gnulib + ignored RE_ICASE. Detect that problem too. */ +@@ -137,10 +161,9 @@ AC_DEFUN([gl_REGEX], + memset (®ex, 0, sizeof regex); + s = re_compile_pattern ("x", 1, ®ex); + if (s) +- return 1; +- +- if (re_search (®ex, "WXY", 3, 0, 3, ®s) < 0) +- return 1; ++ result |= 16; ++ else if (re_search (®ex, "WXY", 3, 0, 3, ®s) < 0) ++ result |= 16; + + /* Catch a bug reported by Vin Shelton in + http://lists.gnu.org/archive/html/bug-coreutils/2007-06/msg00089.html +@@ -151,12 +174,12 @@ AC_DEFUN([gl_REGEX], + memset (®ex, 0, sizeof regex); + s = re_compile_pattern ("[[:alnum:]_-]\\\\+$", 16, ®ex); + if (s) +- return 1; ++ result |= 32; + + /* REG_STARTEND was added to glibc on 2004-01-15. + Reject older versions. */ + if (! REG_STARTEND) +- return 1; ++ result |= 64; + + #if 0 + /* It would be nice to reject hosts whose regoff_t values are too +@@ -167,10 +190,11 @@ AC_DEFUN([gl_REGEX], + when compiling --without-included-regex. */ + if (sizeof (regoff_t) < sizeof (ptrdiff_t) + || sizeof (regoff_t) < sizeof (ssize_t)) +- return 1; ++ result |= 64; + #endif + +- return 0;]])], ++ return result; ++ ]])], + [gl_cv_func_re_compile_pattern_working=yes], + [gl_cv_func_re_compile_pattern_working=no], + dnl When crosscompiling, assume it is not working. +@@ -185,6 +209,9 @@ AC_DEFUN([gl_REGEX], + esac + + if test $ac_use_included_regex = yes; then ++ AC_DEFINE([_REGEX_INCLUDE_LIMITS_H], [1], ++ [Define if you want to include , so that it ++ consistently overrides 's RE_DUP_MAX.]) + AC_DEFINE([_REGEX_LARGE_OFFSETS], [1], + [Define if you want regoff_t to be at least as wide POSIX requires.]) + AC_DEFINE([re_syntax_options], [rpl_re_syntax_options], +@@ -217,8 +244,6 @@ AC_DEFUN([gl_REGEX], + [Define to rpl_regerror if the replacement should be used.]) + AC_DEFINE([regfree], [rpl_regfree], + [Define to rpl_regfree if the replacement should be used.]) +- AC_LIBOBJ([regex]) +- gl_PREREQ_REGEX + fi + ]) + +@@ -229,7 +254,8 @@ AC_DEFUN([gl_PREREQ_REGEX], + AC_REQUIRE([AC_C_INLINE]) + AC_REQUIRE([AC_C_RESTRICT]) + AC_REQUIRE([AC_TYPE_MBSTATE_T]) ++ AC_REQUIRE([gl_EEMALLOC]) + AC_CHECK_HEADERS([libintl.h]) + AC_CHECK_FUNCS_ONCE([isblank iswctype wcscoll]) +- AC_CHECK_DECLS([isblank], [], [], [#include ]) ++ AC_CHECK_DECLS([isblank], [], [], [[#include ]]) + ]) +diff --git a/m4/size_max.m4 b/m4/size_max.m4 +index f3b1a9d..4b247ab 100644 +--- a/m4/size_max.m4 ++++ b/m4/size_max.m4 +@@ -1,5 +1,5 @@ + # size_max.m4 serial 10 +-dnl Copyright (C) 2003, 2005-2006, 2008-2010 Free Software Foundation, Inc. ++dnl Copyright (C) 2003, 2005-2006, 2008-2013 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. +diff --git a/m4/sleep.m4 b/m4/sleep.m4 +index a5ec655..a27baa6 100644 +--- a/m4/sleep.m4 ++++ b/m4/sleep.m4 +@@ -1,5 +1,5 @@ +-# sleep.m4 serial 3 +-dnl Copyright (C) 2007-2010 Free Software Foundation, Inc. ++# sleep.m4 serial 7 ++dnl Copyright (C) 2007-2013 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. +@@ -7,16 +7,16 @@ dnl with or without modifications, as long as this notice is preserved. + AC_DEFUN([gl_FUNC_SLEEP], + [ + AC_REQUIRE([gl_UNISTD_H_DEFAULTS]) ++ AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + dnl We expect to see the declaration of sleep() in a header file. + dnl Older versions of mingw have a sleep() function that is an alias to + dnl _sleep() in MSVCRT. It has a different signature than POSIX sleep(): + dnl it takes the number of milliseconds as argument and returns void. + dnl mingw does not declare this function. +- AC_CHECK_DECLS([sleep], , , [#include ]) ++ AC_CHECK_DECLS([sleep], , , [[#include ]]) + AC_CHECK_FUNCS_ONCE([sleep]) + if test $ac_cv_have_decl_sleep != yes; then + HAVE_SLEEP=0 +- AC_LIBOBJ([sleep]) + else + dnl Cygwin 1.5.x has a bug where sleep can't exceed 49.7 days. + AC_CACHE_CHECK([for working sleep], [gl_cv_func_sleep_works], +@@ -38,12 +38,25 @@ handle_alarm (int sig) + signal (SIGALRM, handle_alarm); + alarm (1); + remaining = sleep (pentecost); +- return !(pentecost - 10 < remaining && remaining <= pentecost);]])], ++ if (remaining > pentecost) ++ return 3; ++ if (remaining <= pentecost - 10) ++ return 4; ++ return 0; ++ ]])], + [gl_cv_func_sleep_works=yes], [gl_cv_func_sleep_works=no], +- [gl_cv_func_sleep_works="guessing no"])]) +- if test "$gl_cv_func_sleep_works" != yes; then +- REPLACE_SLEEP=1 +- AC_LIBOBJ([sleep]) +- fi ++ [case "$host_os" in ++ # Guess yes on glibc systems. ++ *-gnu*) gl_cv_func_sleep_works="guessing yes" ;; ++ # If we don't know, assume the worst. ++ *) gl_cv_func_sleep_works="guessing no" ;; ++ esac ++ ])]) ++ case "$gl_cv_func_sleep_works" in ++ *yes) ;; ++ *) ++ REPLACE_SLEEP=1 ++ ;; ++ esac + fi + ]) +diff --git a/m4/ssize_t.m4 b/m4/ssize_t.m4 +index e4c160b..6338134 100644 +--- a/m4/ssize_t.m4 ++++ b/m4/ssize_t.m4 +@@ -1,5 +1,5 @@ + # ssize_t.m4 serial 5 (gettext-0.18.2) +-dnl Copyright (C) 2001-2003, 2006, 2010 Free Software Foundation, Inc. ++dnl Copyright (C) 2001-2003, 2006, 2010-2013 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. +diff --git a/m4/stdalign.m4 b/m4/stdalign.m4 +new file mode 100644 +index 0000000..a866ff6 +--- /dev/null ++++ b/m4/stdalign.m4 +@@ -0,0 +1,52 @@ ++# Check for stdalign.h that conforms to C11. ++ ++dnl Copyright 2011-2013 Free Software Foundation, Inc. ++dnl This file is free software; the Free Software Foundation ++dnl gives unlimited permission to copy and/or distribute it, ++dnl with or without modifications, as long as this notice is preserved. ++ ++# Prepare for substituting if it is not supported. ++ ++AC_DEFUN([gl_STDALIGN_H], ++[ ++ AC_CACHE_CHECK([for working stdalign.h], ++ [gl_cv_header_working_stdalign_h], ++ [AC_COMPILE_IFELSE( ++ [AC_LANG_PROGRAM( ++ [[#include ++ #include ++ ++ /* Test that alignof yields a result consistent with offsetof. ++ This catches GCC bug 52023 ++ . */ ++ #ifdef __cplusplus ++ template struct alignof_helper { char a; t b; }; ++ # define ao(type) offsetof (alignof_helper, b) ++ #else ++ # define ao(type) offsetof (struct { char a; type b; }, b) ++ #endif ++ char test_double[ao (double) % _Alignof (double) == 0 ? 1 : -1]; ++ char test_long[ao (long int) % _Alignof (long int) == 0 ? 1 : -1]; ++ char test_alignof[alignof (double) == _Alignof (double) ? 1 : -1]; ++ ++ /* Test _Alignas only on platforms where gnulib can help. */ ++ #if \ ++ (__GNUC__ || __IBMC__ || __IBMCPP__ \ ++ || 0x5110 <= __SUNPRO_C || 1300 <= _MSC_VER) ++ struct alignas_test { char c; char alignas (8) alignas_8; }; ++ char test_alignas[offsetof (struct alignas_test, alignas_8) == 8 ++ ? 1 : -1]; ++ #endif ++ ]])], ++ [gl_cv_header_working_stdalign_h=yes], ++ [gl_cv_header_working_stdalign_h=no])]) ++ ++ if test $gl_cv_header_working_stdalign_h = yes; then ++ STDALIGN_H='' ++ else ++ STDALIGN_H='stdalign.h' ++ fi ++ ++ AC_SUBST([STDALIGN_H]) ++ AM_CONDITIONAL([GL_GENERATE_STDALIGN_H], [test -n "$STDALIGN_H"]) ++]) +diff --git a/m4/stdbool.m4 b/m4/stdbool.m4 +index 1efe59e..80d5559 100644 +--- a/m4/stdbool.m4 ++++ b/m4/stdbool.m4 +@@ -1,17 +1,17 @@ + # Check for stdbool.h that conforms to C99. + +-dnl Copyright (C) 2002-2006, 2009-2010 Free Software Foundation, Inc. ++dnl Copyright (C) 2002-2006, 2009-2013 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. + +-#serial 3 ++#serial 5 + + # Prepare for substituting if it is not supported. + + AC_DEFUN([AM_STDBOOL_H], + [ +- AC_REQUIRE([AC_HEADER_STDBOOL]) ++ AC_REQUIRE([AC_CHECK_HEADER_STDBOOL]) + + # Define two additional variables used in the Makefile substitution. + +@@ -21,6 +21,7 @@ AC_DEFUN([AM_STDBOOL_H], + STDBOOL_H='stdbool.h' + fi + AC_SUBST([STDBOOL_H]) ++ AM_CONDITIONAL([GL_GENERATE_STDBOOL_H], [test -n "$STDBOOL_H"]) + + if test "$ac_cv_type__Bool" = yes; then + HAVE__BOOL=1 +@@ -33,11 +34,9 @@ AC_DEFUN([AM_STDBOOL_H], + # AM_STDBOOL_H will be renamed to gl_STDBOOL_H in the future. + AC_DEFUN([gl_STDBOOL_H], [AM_STDBOOL_H]) + +-# This version of the macro is needed in autoconf <= 2.67. Autoconf has +-# it built in since 2.60, but we want the tweaks from the 2.68 version +-# to avoid rejecting xlc and clang due to relying on extensions. ++# This version of the macro is needed in autoconf <= 2.68. + +-AC_DEFUN([AC_HEADER_STDBOOL], ++AC_DEFUN([AC_CHECK_HEADER_STDBOOL], + [AC_CACHE_CHECK([for stdbool.h that conforms to C99], + [ac_cv_header_stdbool_h], + [AC_COMPILE_IFELSE( +@@ -98,6 +97,4 @@ AC_DEFUN([AC_HEADER_STDBOOL], + [ac_cv_header_stdbool_h=yes], + [ac_cv_header_stdbool_h=no])]) + AC_CHECK_TYPES([_Bool]) +- if test $ac_cv_header_stdbool_h = yes; then +- AC_DEFINE([HAVE_STDBOOL_H], [1], [Define to 1 if stdbool.h conforms to C99.]) +- fi]) ++]) +diff --git a/m4/stddef_h.m4 b/m4/stddef_h.m4 +index c3ae569..5da8ab1 100644 +--- a/m4/stddef_h.m4 ++++ b/m4/stddef_h.m4 +@@ -1,6 +1,6 @@ + dnl A placeholder for POSIX 2008 , for platforms that have issues. +-# stddef_h.m4 serial 2 +-dnl Copyright (C) 2009, 2010 Free Software Foundation, Inc. ++# stddef_h.m4 serial 4 ++dnl Copyright (C) 2009-2013 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. +@@ -9,6 +9,7 @@ AC_DEFUN([gl_STDDEF_H], + [ + AC_REQUIRE([gl_STDDEF_H_DEFAULTS]) + AC_REQUIRE([gt_TYPE_WCHAR_T]) ++ STDDEF_H= + if test $gt_cv_c_wchar_t = no; then + HAVE_WCHAR_T=0 + STDDEF_H=stddef.h +@@ -24,8 +25,10 @@ AC_DEFUN([gl_STDDEF_H], + REPLACE_NULL=1 + STDDEF_H=stddef.h + fi ++ AC_SUBST([STDDEF_H]) ++ AM_CONDITIONAL([GL_GENERATE_STDDEF_H], [test -n "$STDDEF_H"]) + if test -n "$STDDEF_H"; then +- gl_CHECK_NEXT_HEADERS([stddef.h]) ++ gl_NEXT_HEADERS([stddef.h]) + fi + ]) + +@@ -41,5 +44,4 @@ AC_DEFUN([gl_STDDEF_H_DEFAULTS], + dnl Assume proper GNU behavior unless another module says otherwise. + REPLACE_NULL=0; AC_SUBST([REPLACE_NULL]) + HAVE_WCHAR_T=1; AC_SUBST([HAVE_WCHAR_T]) +- STDDEF_H=''; AC_SUBST([STDDEF_H]) + ]) +diff --git a/m4/stdint.m4 b/m4/stdint.m4 +index c5e813a..27cdcdb 100644 +--- a/m4/stdint.m4 ++++ b/m4/stdint.m4 +@@ -1,5 +1,5 @@ +-# stdint.m4 serial 35 +-dnl Copyright (C) 2001-2010 Free Software Foundation, Inc. ++# stdint.m4 serial 43 ++dnl Copyright (C) 2001-2013 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. +@@ -7,7 +7,7 @@ dnl with or without modifications, as long as this notice is preserved. + dnl From Paul Eggert and Bruno Haible. + dnl Test whether is supported or must be substituted. + +-AC_DEFUN([gl_STDINT_H], ++AC_DEFUN_ONCE([gl_STDINT_H], + [ + AC_PREREQ([2.59])dnl + +@@ -27,6 +27,15 @@ AC_DEFUN([gl_STDINT_H], + fi + AC_SUBST([HAVE_UNSIGNED_LONG_LONG_INT]) + ++ dnl Check for , in the same way as gl_WCHAR_H does. ++ AC_CHECK_HEADERS_ONCE([wchar.h]) ++ if test $ac_cv_header_wchar_h = yes; then ++ HAVE_WCHAR_H=1 ++ else ++ HAVE_WCHAR_H=0 ++ fi ++ AC_SUBST([HAVE_WCHAR_H]) ++ + dnl Check for . + dnl AC_INCLUDES_DEFAULT defines $ac_cv_header_inttypes_h. + if test $ac_cv_header_inttypes_h = yes; then +@@ -60,8 +69,6 @@ AC_DEFUN([gl_STDINT_H], + [gl_cv_header_working_stdint_h=no + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([[ +-#define __STDC_LIMIT_MACROS 1 /* to make it work also in C++ mode */ +-#define __STDC_CONSTANT_MACROS 1 /* to make it work also in C++ mode */ + #define _GL_JUST_INCLUDE_SYSTEM_STDINT_H 1 /* work if build isn't clean */ + #include + /* Dragonfly defines WCHAR_MIN, WCHAR_MAX only in . */ +@@ -145,9 +152,11 @@ uintmax_t j = UINTMAX_MAX; + + #include /* for CHAR_BIT */ + #define TYPE_MINIMUM(t) \ +- ((t) ((t) 0 < (t) -1 ? (t) 0 : ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1))) ++ ((t) ((t) 0 < (t) -1 ? (t) 0 : ~ TYPE_MAXIMUM (t))) + #define TYPE_MAXIMUM(t) \ +- ((t) ((t) 0 < (t) -1 ? (t) -1 : ~ (~ (t) 0 << (sizeof (t) * CHAR_BIT - 1)))) ++ ((t) ((t) 0 < (t) -1 \ ++ ? (t) -1 \ ++ : ((((t) 1 << (sizeof (t) * CHAR_BIT - 2)) - 1) * 2 + 1))) + struct s { + int check_PTRDIFF: + PTRDIFF_MIN == TYPE_MINIMUM (ptrdiff_t) +@@ -208,8 +217,6 @@ struct s { + dnl This detects a bug on HP-UX 11.23/ia64. + AC_RUN_IFELSE([ + AC_LANG_PROGRAM([[ +-#define __STDC_LIMIT_MACROS 1 /* to make it work also in C++ mode */ +-#define __STDC_CONSTANT_MACROS 1 /* to make it work also in C++ mode */ + #define _GL_JUST_INCLUDE_SYSTEM_STDINT_H 1 /* work if build isn't clean */ + #include + ] +@@ -259,7 +266,7 @@ static const char *macro_values[] = + || strncmp (value, "((int)"/*)*/, 6) == 0 + || strncmp (value, "((signed short)"/*)*/, 15) == 0 + || strncmp (value, "((signed char)"/*)*/, 14) == 0) +- return 1; ++ return mv - macro_values + 1; + } + return 0; + ]])], +@@ -290,14 +297,11 @@ static const char *macro_values[] = + fi + AC_SUBST([HAVE_SYS_BITYPES_H]) + +- dnl Check for (missing in Linux uClibc when built without wide +- dnl character support). +- AC_CHECK_HEADERS_ONCE([wchar.h]) +- + gl_STDINT_TYPE_PROPERTIES + STDINT_H=stdint.h + fi + AC_SUBST([STDINT_H]) ++ AM_CONDITIONAL([GL_GENERATE_STDINT_H], [test -n "$STDINT_H"]) + ]) + + dnl gl_STDINT_BITSIZEOF(TYPES, INCLUDES) +@@ -458,6 +462,14 @@ AC_DEFUN([gl_STDINT_TYPE_PROPERTIES], + fi + gl_INTEGER_TYPE_SUFFIX([sig_atomic_t wchar_t wint_t], + [gl_STDINT_INCLUDES]) ++ ++ dnl If wint_t is smaller than 'int', it cannot satisfy the ISO C 99 ++ dnl requirement that wint_t is "unchanged by default argument promotions". ++ dnl In this case gnulib's and override wint_t. ++ dnl Set the variable BITSIZEOF_WINT_T accordingly. ++ if test $BITSIZEOF_WINT_T -lt 32; then ++ BITSIZEOF_WINT_T=32 ++ fi + ]) + + dnl Autoconf >= 2.61 has AC_COMPUTE_INT built-in. +diff --git a/m4/stdint_h.m4 b/m4/stdint_h.m4 +index 670c0cc..511ab4e 100644 +--- a/m4/stdint_h.m4 ++++ b/m4/stdint_h.m4 +@@ -1,5 +1,5 @@ + # stdint_h.m4 serial 9 +-dnl Copyright (C) 1997-2004, 2006, 2008-2010 Free Software Foundation, Inc. ++dnl Copyright (C) 1997-2004, 2006, 2008-2013 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. +diff --git a/m4/stdio_h.m4 b/m4/stdio_h.m4 +index d3edb42..ebade06 100644 +--- a/m4/stdio_h.m4 ++++ b/m4/stdio_h.m4 +@@ -1,5 +1,5 @@ +-# stdio_h.m4 serial 31 +-dnl Copyright (C) 2007-2010 Free Software Foundation, Inc. ++# stdio_h.m4 serial 43 ++dnl Copyright (C) 2007-2013 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. +@@ -7,9 +7,32 @@ dnl with or without modifications, as long as this notice is preserved. + AC_DEFUN([gl_STDIO_H], + [ + AC_REQUIRE([gl_STDIO_H_DEFAULTS]) +- AC_REQUIRE([AC_C_INLINE]) +- AC_REQUIRE([gl_ASM_SYMBOL_PREFIX]) +- gl_CHECK_NEXT_HEADERS([stdio.h]) ++ gl_NEXT_HEADERS([stdio.h]) ++ ++ dnl No need to create extra modules for these functions. Everyone who uses ++ dnl likely needs them. ++ GNULIB_FSCANF=1 ++ gl_MODULE_INDICATOR([fscanf]) ++ GNULIB_SCANF=1 ++ gl_MODULE_INDICATOR([scanf]) ++ GNULIB_FGETC=1 ++ GNULIB_GETC=1 ++ GNULIB_GETCHAR=1 ++ GNULIB_FGETS=1 ++ GNULIB_FREAD=1 ++ dnl This ifdef is necessary to avoid an error "missing file lib/stdio-read.c" ++ dnl "expected source file, required through AC_LIBSOURCES, not found". It is ++ dnl also an optimization, to avoid performing a configure check whose result ++ dnl is not used. But it does not make the test of GNULIB_STDIO_H_NONBLOCKING ++ dnl or GNULIB_NONBLOCKING redundant. ++ m4_ifdef([gl_NONBLOCKING_IO], [ ++ gl_NONBLOCKING_IO ++ if test $gl_cv_have_nonblocking != yes; then ++ REPLACE_STDIO_READ_FUNCS=1 ++ AC_LIBOBJ([stdio-read]) ++ fi ++ ]) ++ + dnl No need to create extra modules for these functions. Everyone who uses + dnl likely needs them. + GNULIB_FPRINTF=1 +@@ -22,9 +45,11 @@ AC_DEFUN([gl_STDIO_H], + GNULIB_FPUTS=1 + GNULIB_PUTS=1 + GNULIB_FWRITE=1 +- dnl This ifdef is just an optimization, to avoid performing a configure +- dnl check whose result is not used. It does not make the test of +- dnl GNULIB_STDIO_H_SIGPIPE or GNULIB_SIGPIPE redundant. ++ dnl This ifdef is necessary to avoid an error "missing file lib/stdio-write.c" ++ dnl "expected source file, required through AC_LIBSOURCES, not found". It is ++ dnl also an optimization, to avoid performing a configure check whose result ++ dnl is not used. But it does not make the test of GNULIB_STDIO_H_SIGPIPE or ++ dnl GNULIB_SIGPIPE redundant. + m4_ifdef([gl_SIGNAL_SIGPIPE], [ + gl_SIGNAL_SIGPIPE + if test $gl_cv_header_signal_h_SIGPIPE != yes; then +@@ -32,13 +57,25 @@ AC_DEFUN([gl_STDIO_H], + AC_LIBOBJ([stdio-write]) + fi + ]) ++ dnl This ifdef is necessary to avoid an error "missing file lib/stdio-write.c" ++ dnl "expected source file, required through AC_LIBSOURCES, not found". It is ++ dnl also an optimization, to avoid performing a configure check whose result ++ dnl is not used. But it does not make the test of GNULIB_STDIO_H_NONBLOCKING ++ dnl or GNULIB_NONBLOCKING redundant. ++ m4_ifdef([gl_NONBLOCKING_IO], [ ++ gl_NONBLOCKING_IO ++ if test $gl_cv_have_nonblocking != yes; then ++ REPLACE_STDIO_WRITE_FUNCS=1 ++ AC_LIBOBJ([stdio-write]) ++ fi ++ ]) + + dnl Check for declarations of anything we want to poison if the + dnl corresponding gnulib module is not in use, and which is not + dnl guaranteed by both C89 and C11. + gl_WARN_ON_USE_PREPARE([[#include +- ]], [dprintf fpurge fseeko ftello getdelim getline gets popen renameat +- snprintf tmpfile vdprintf vsnprintf]) ++ ]], [dprintf fpurge fseeko ftello getdelim getline gets pclose popen ++ renameat snprintf tmpfile vdprintf vsnprintf]) + ]) + + AC_DEFUN([gl_STDIO_MODULE_INDICATOR], +@@ -54,23 +91,31 @@ AC_DEFUN([gl_STDIO_H_DEFAULTS], + [ + GNULIB_DPRINTF=0; AC_SUBST([GNULIB_DPRINTF]) + GNULIB_FCLOSE=0; AC_SUBST([GNULIB_FCLOSE]) ++ GNULIB_FDOPEN=0; AC_SUBST([GNULIB_FDOPEN]) + GNULIB_FFLUSH=0; AC_SUBST([GNULIB_FFLUSH]) ++ GNULIB_FGETC=0; AC_SUBST([GNULIB_FGETC]) ++ GNULIB_FGETS=0; AC_SUBST([GNULIB_FGETS]) + GNULIB_FOPEN=0; AC_SUBST([GNULIB_FOPEN]) + GNULIB_FPRINTF=0; AC_SUBST([GNULIB_FPRINTF]) + GNULIB_FPRINTF_POSIX=0; AC_SUBST([GNULIB_FPRINTF_POSIX]) + GNULIB_FPURGE=0; AC_SUBST([GNULIB_FPURGE]) + GNULIB_FPUTC=0; AC_SUBST([GNULIB_FPUTC]) + GNULIB_FPUTS=0; AC_SUBST([GNULIB_FPUTS]) ++ GNULIB_FREAD=0; AC_SUBST([GNULIB_FREAD]) + GNULIB_FREOPEN=0; AC_SUBST([GNULIB_FREOPEN]) ++ GNULIB_FSCANF=0; AC_SUBST([GNULIB_FSCANF]) + GNULIB_FSEEK=0; AC_SUBST([GNULIB_FSEEK]) + GNULIB_FSEEKO=0; AC_SUBST([GNULIB_FSEEKO]) + GNULIB_FTELL=0; AC_SUBST([GNULIB_FTELL]) + GNULIB_FTELLO=0; AC_SUBST([GNULIB_FTELLO]) + GNULIB_FWRITE=0; AC_SUBST([GNULIB_FWRITE]) ++ GNULIB_GETC=0; AC_SUBST([GNULIB_GETC]) ++ GNULIB_GETCHAR=0; AC_SUBST([GNULIB_GETCHAR]) + GNULIB_GETDELIM=0; AC_SUBST([GNULIB_GETDELIM]) + GNULIB_GETLINE=0; AC_SUBST([GNULIB_GETLINE]) + GNULIB_OBSTACK_PRINTF=0; AC_SUBST([GNULIB_OBSTACK_PRINTF]) + GNULIB_OBSTACK_PRINTF_POSIX=0; AC_SUBST([GNULIB_OBSTACK_PRINTF_POSIX]) ++ GNULIB_PCLOSE=0; AC_SUBST([GNULIB_PCLOSE]) + GNULIB_PERROR=0; AC_SUBST([GNULIB_PERROR]) + GNULIB_POPEN=0; AC_SUBST([GNULIB_POPEN]) + GNULIB_PRINTF=0; AC_SUBST([GNULIB_PRINTF]) +@@ -81,11 +126,15 @@ AC_DEFUN([gl_STDIO_H_DEFAULTS], + GNULIB_REMOVE=0; AC_SUBST([GNULIB_REMOVE]) + GNULIB_RENAME=0; AC_SUBST([GNULIB_RENAME]) + GNULIB_RENAMEAT=0; AC_SUBST([GNULIB_RENAMEAT]) ++ GNULIB_SCANF=0; AC_SUBST([GNULIB_SCANF]) + GNULIB_SNPRINTF=0; AC_SUBST([GNULIB_SNPRINTF]) + GNULIB_SPRINTF_POSIX=0; AC_SUBST([GNULIB_SPRINTF_POSIX]) ++ GNULIB_STDIO_H_NONBLOCKING=0; AC_SUBST([GNULIB_STDIO_H_NONBLOCKING]) + GNULIB_STDIO_H_SIGPIPE=0; AC_SUBST([GNULIB_STDIO_H_SIGPIPE]) + GNULIB_TMPFILE=0; AC_SUBST([GNULIB_TMPFILE]) + GNULIB_VASPRINTF=0; AC_SUBST([GNULIB_VASPRINTF]) ++ GNULIB_VFSCANF=0; AC_SUBST([GNULIB_VFSCANF]) ++ GNULIB_VSCANF=0; AC_SUBST([GNULIB_VSCANF]) + GNULIB_VDPRINTF=0; AC_SUBST([GNULIB_VDPRINTF]) + GNULIB_VFPRINTF=0; AC_SUBST([GNULIB_VFPRINTF]) + GNULIB_VFPRINTF_POSIX=0; AC_SUBST([GNULIB_VFPRINTF_POSIX]) +@@ -95,6 +144,8 @@ AC_DEFUN([gl_STDIO_H_DEFAULTS], + GNULIB_VSPRINTF_POSIX=0; AC_SUBST([GNULIB_VSPRINTF_POSIX]) + dnl Assume proper GNU behavior unless another module says otherwise. + HAVE_DECL_FPURGE=1; AC_SUBST([HAVE_DECL_FPURGE]) ++ HAVE_DECL_FSEEKO=1; AC_SUBST([HAVE_DECL_FSEEKO]) ++ HAVE_DECL_FTELLO=1; AC_SUBST([HAVE_DECL_FTELLO]) + HAVE_DECL_GETDELIM=1; AC_SUBST([HAVE_DECL_GETDELIM]) + HAVE_DECL_GETLINE=1; AC_SUBST([HAVE_DECL_GETLINE]) + HAVE_DECL_OBSTACK_PRINTF=1; AC_SUBST([HAVE_DECL_OBSTACK_PRINTF]) +@@ -103,11 +154,14 @@ AC_DEFUN([gl_STDIO_H_DEFAULTS], + HAVE_DPRINTF=1; AC_SUBST([HAVE_DPRINTF]) + HAVE_FSEEKO=1; AC_SUBST([HAVE_FSEEKO]) + HAVE_FTELLO=1; AC_SUBST([HAVE_FTELLO]) ++ HAVE_PCLOSE=1; AC_SUBST([HAVE_PCLOSE]) ++ HAVE_POPEN=1; AC_SUBST([HAVE_POPEN]) + HAVE_RENAMEAT=1; AC_SUBST([HAVE_RENAMEAT]) + HAVE_VASPRINTF=1; AC_SUBST([HAVE_VASPRINTF]) + HAVE_VDPRINTF=1; AC_SUBST([HAVE_VDPRINTF]) + REPLACE_DPRINTF=0; AC_SUBST([REPLACE_DPRINTF]) + REPLACE_FCLOSE=0; AC_SUBST([REPLACE_FCLOSE]) ++ REPLACE_FDOPEN=0; AC_SUBST([REPLACE_FDOPEN]) + REPLACE_FFLUSH=0; AC_SUBST([REPLACE_FFLUSH]) + REPLACE_FOPEN=0; AC_SUBST([REPLACE_FOPEN]) + REPLACE_FPRINTF=0; AC_SUBST([REPLACE_FPRINTF]) +@@ -128,6 +182,7 @@ AC_DEFUN([gl_STDIO_H_DEFAULTS], + REPLACE_RENAMEAT=0; AC_SUBST([REPLACE_RENAMEAT]) + REPLACE_SNPRINTF=0; AC_SUBST([REPLACE_SNPRINTF]) + REPLACE_SPRINTF=0; AC_SUBST([REPLACE_SPRINTF]) ++ REPLACE_STDIO_READ_FUNCS=0; AC_SUBST([REPLACE_STDIO_READ_FUNCS]) + REPLACE_STDIO_WRITE_FUNCS=0; AC_SUBST([REPLACE_STDIO_WRITE_FUNCS]) + REPLACE_TMPFILE=0; AC_SUBST([REPLACE_TMPFILE]) + REPLACE_VASPRINTF=0; AC_SUBST([REPLACE_VASPRINTF]) +@@ -137,23 +192,3 @@ AC_DEFUN([gl_STDIO_H_DEFAULTS], + REPLACE_VSNPRINTF=0; AC_SUBST([REPLACE_VSNPRINTF]) + REPLACE_VSPRINTF=0; AC_SUBST([REPLACE_VSPRINTF]) + ]) +- +-dnl Code shared by fseeko and ftello. Determine if large files are supported, +-dnl but stdin does not start as a large file by default. +-AC_DEFUN([gl_STDIN_LARGE_OFFSET], +- [ +- AC_CACHE_CHECK([whether stdin defaults to large file offsets], +- [gl_cv_var_stdin_large_offset], +- [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], +-[[#if defined __SL64 && defined __SCLE /* cygwin */ +- /* Cygwin 1.5.24 and earlier fail to put stdin in 64-bit mode, making +- fseeko/ftello needlessly fail. This bug was fixed in 1.5.25, and +- it is easier to do a version check than building a runtime test. */ +-# include +-# if CYGWIN_VERSION_DLL_COMBINED < CYGWIN_VERSION_DLL_MAKE_COMBINED (1005, 25) +- choke me +-# endif +-#endif]])], +- [gl_cv_var_stdin_large_offset=yes], +- [gl_cv_var_stdin_large_offset=no])]) +-]) +diff --git a/m4/stdlib_h.m4 b/m4/stdlib_h.m4 +index fc15019..2027ab3 100644 +--- a/m4/stdlib_h.m4 ++++ b/m4/stdlib_h.m4 +@@ -1,5 +1,5 @@ +-# stdlib_h.m4 serial 30 +-dnl Copyright (C) 2007-2010 Free Software Foundation, Inc. ++# stdlib_h.m4 serial 42 ++dnl Copyright (C) 2007-2013 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. +@@ -7,21 +7,7 @@ dnl with or without modifications, as long as this notice is preserved. + AC_DEFUN([gl_STDLIB_H], + [ + AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) +- gl_CHECK_NEXT_HEADERS([stdlib.h]) +- AC_CHECK_HEADERS([random.h], [], [], [AC_INCLUDES_DEFAULT]) +- if test $ac_cv_header_random_h = yes; then +- HAVE_RANDOM_H=1 +- else +- HAVE_RANDOM_H=0 +- fi +- AC_SUBST([HAVE_RANDOM_H]) +- AC_CHECK_TYPES([struct random_data], +- [], [HAVE_STRUCT_RANDOM_DATA=0], +- [[#include +- #if HAVE_RANDOM_H +- # include +- #endif +- ]]) ++ gl_NEXT_HEADERS([stdlib.h]) + + dnl Check for declarations of anything we want to poison if the + dnl corresponding gnulib module is not in use, and which is not +@@ -33,10 +19,11 @@ AC_DEFUN([gl_STDLIB_H], + #if HAVE_RANDOM_H + # include + #endif +- ]], [_Exit atoll canonicalize_file_name getloadavg getsubopt grantpt mkdtemp +- mkostemp mkostemps mkstemp mkstemps ptsname random_r initstat_r srandom_r +- setstate_r realpath rpmatch setenv strtod strtoll strtoull unlockpt +- unsetenv]) ++ ]], [_Exit atoll canonicalize_file_name getloadavg getsubopt grantpt ++ initstate initstate_r mkdtemp mkostemp mkostemps mkstemp mkstemps ++ posix_openpt ptsname ptsname_r random random_r realpath rpmatch ++ secure_getenv setenv setstate setstate_r srandom srandom_r ++ strtod strtoll strtoull unlockpt unsetenv]) + ]) + + AC_DEFUN([gl_STDLIB_MODULE_INDICATOR], +@@ -58,23 +45,30 @@ AC_DEFUN([gl_STDLIB_H_DEFAULTS], + GNULIB_GETSUBOPT=0; AC_SUBST([GNULIB_GETSUBOPT]) + GNULIB_GRANTPT=0; AC_SUBST([GNULIB_GRANTPT]) + GNULIB_MALLOC_POSIX=0; AC_SUBST([GNULIB_MALLOC_POSIX]) ++ GNULIB_MBTOWC=0; AC_SUBST([GNULIB_MBTOWC]) + GNULIB_MKDTEMP=0; AC_SUBST([GNULIB_MKDTEMP]) + GNULIB_MKOSTEMP=0; AC_SUBST([GNULIB_MKOSTEMP]) + GNULIB_MKOSTEMPS=0; AC_SUBST([GNULIB_MKOSTEMPS]) + GNULIB_MKSTEMP=0; AC_SUBST([GNULIB_MKSTEMP]) + GNULIB_MKSTEMPS=0; AC_SUBST([GNULIB_MKSTEMPS]) ++ GNULIB_POSIX_OPENPT=0; AC_SUBST([GNULIB_POSIX_OPENPT]) + GNULIB_PTSNAME=0; AC_SUBST([GNULIB_PTSNAME]) ++ GNULIB_PTSNAME_R=0; AC_SUBST([GNULIB_PTSNAME_R]) + GNULIB_PUTENV=0; AC_SUBST([GNULIB_PUTENV]) ++ GNULIB_RANDOM=0; AC_SUBST([GNULIB_RANDOM]) + GNULIB_RANDOM_R=0; AC_SUBST([GNULIB_RANDOM_R]) + GNULIB_REALLOC_POSIX=0; AC_SUBST([GNULIB_REALLOC_POSIX]) + GNULIB_REALPATH=0; AC_SUBST([GNULIB_REALPATH]) + GNULIB_RPMATCH=0; AC_SUBST([GNULIB_RPMATCH]) ++ GNULIB_SECURE_GETENV=0; AC_SUBST([GNULIB_SECURE_GETENV]) + GNULIB_SETENV=0; AC_SUBST([GNULIB_SETENV]) + GNULIB_STRTOD=0; AC_SUBST([GNULIB_STRTOD]) + GNULIB_STRTOLL=0; AC_SUBST([GNULIB_STRTOLL]) + GNULIB_STRTOULL=0; AC_SUBST([GNULIB_STRTOULL]) ++ GNULIB_SYSTEM_POSIX=0; AC_SUBST([GNULIB_SYSTEM_POSIX]) + GNULIB_UNLOCKPT=0; AC_SUBST([GNULIB_UNLOCKPT]) + GNULIB_UNSETENV=0; AC_SUBST([GNULIB_UNSETENV]) ++ GNULIB_WCTOMB=0; AC_SUBST([GNULIB_WCTOMB]) + dnl Assume proper GNU behavior unless another module says otherwise. + HAVE__EXIT=1; AC_SUBST([HAVE__EXIT]) + HAVE_ATOLL=1; AC_SUBST([HAVE_ATOLL]) +@@ -87,26 +81,37 @@ AC_DEFUN([gl_STDLIB_H_DEFAULTS], + HAVE_MKOSTEMPS=1; AC_SUBST([HAVE_MKOSTEMPS]) + HAVE_MKSTEMP=1; AC_SUBST([HAVE_MKSTEMP]) + HAVE_MKSTEMPS=1; AC_SUBST([HAVE_MKSTEMPS]) ++ HAVE_POSIX_OPENPT=1; AC_SUBST([HAVE_POSIX_OPENPT]) + HAVE_PTSNAME=1; AC_SUBST([HAVE_PTSNAME]) ++ HAVE_PTSNAME_R=1; AC_SUBST([HAVE_PTSNAME_R]) ++ HAVE_RANDOM=1; AC_SUBST([HAVE_RANDOM]) ++ HAVE_RANDOM_H=1; AC_SUBST([HAVE_RANDOM_H]) + HAVE_RANDOM_R=1; AC_SUBST([HAVE_RANDOM_R]) + HAVE_REALPATH=1; AC_SUBST([HAVE_REALPATH]) + HAVE_RPMATCH=1; AC_SUBST([HAVE_RPMATCH]) ++ HAVE_SECURE_GETENV=1; AC_SUBST([HAVE_SECURE_GETENV]) + HAVE_SETENV=1; AC_SUBST([HAVE_SETENV]) ++ HAVE_DECL_SETENV=1; AC_SUBST([HAVE_DECL_SETENV]) + HAVE_STRTOD=1; AC_SUBST([HAVE_STRTOD]) + HAVE_STRTOLL=1; AC_SUBST([HAVE_STRTOLL]) + HAVE_STRTOULL=1; AC_SUBST([HAVE_STRTOULL]) + HAVE_STRUCT_RANDOM_DATA=1; AC_SUBST([HAVE_STRUCT_RANDOM_DATA]) + HAVE_SYS_LOADAVG_H=0; AC_SUBST([HAVE_SYS_LOADAVG_H]) + HAVE_UNLOCKPT=1; AC_SUBST([HAVE_UNLOCKPT]) +- HAVE_UNSETENV=1; AC_SUBST([HAVE_UNSETENV]) ++ HAVE_DECL_UNSETENV=1; AC_SUBST([HAVE_DECL_UNSETENV]) + REPLACE_CALLOC=0; AC_SUBST([REPLACE_CALLOC]) + REPLACE_CANONICALIZE_FILE_NAME=0; AC_SUBST([REPLACE_CANONICALIZE_FILE_NAME]) + REPLACE_MALLOC=0; AC_SUBST([REPLACE_MALLOC]) ++ REPLACE_MBTOWC=0; AC_SUBST([REPLACE_MBTOWC]) + REPLACE_MKSTEMP=0; AC_SUBST([REPLACE_MKSTEMP]) ++ REPLACE_PTSNAME=0; AC_SUBST([REPLACE_PTSNAME]) ++ REPLACE_PTSNAME_R=0; AC_SUBST([REPLACE_PTSNAME_R]) + REPLACE_PUTENV=0; AC_SUBST([REPLACE_PUTENV]) ++ REPLACE_RANDOM_R=0; AC_SUBST([REPLACE_RANDOM_R]) + REPLACE_REALLOC=0; AC_SUBST([REPLACE_REALLOC]) + REPLACE_REALPATH=0; AC_SUBST([REPLACE_REALPATH]) + REPLACE_SETENV=0; AC_SUBST([REPLACE_SETENV]) + REPLACE_STRTOD=0; AC_SUBST([REPLACE_STRTOD]) + REPLACE_UNSETENV=0; AC_SUBST([REPLACE_UNSETENV]) ++ REPLACE_WCTOMB=0; AC_SUBST([REPLACE_WCTOMB]) + ]) +diff --git a/m4/strcase.m4 b/m4/strcase.m4 +index 33de423..22bf57c 100644 +--- a/m4/strcase.m4 ++++ b/m4/strcase.m4 +@@ -1,5 +1,5 @@ +-# strcase.m4 serial 10 +-dnl Copyright (C) 2002, 2005-2010 Free Software Foundation, Inc. ++# strcase.m4 serial 11 ++dnl Copyright (C) 2002, 2005-2013 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. +@@ -13,19 +13,20 @@ AC_DEFUN([gl_STRCASE], + AC_DEFUN([gl_FUNC_STRCASECMP], + [ + AC_REQUIRE([gl_HEADER_STRINGS_H_DEFAULTS]) +- AC_REPLACE_FUNCS([strcasecmp]) ++ AC_CHECK_FUNCS([strcasecmp]) + if test $ac_cv_func_strcasecmp = no; then + HAVE_STRCASECMP=0 +- gl_PREREQ_STRCASECMP + fi + ]) + + AC_DEFUN([gl_FUNC_STRNCASECMP], + [ + AC_REQUIRE([gl_HEADER_STRINGS_H_DEFAULTS]) +- AC_REPLACE_FUNCS([strncasecmp]) +- if test $ac_cv_func_strncasecmp = no; then +- gl_PREREQ_STRNCASECMP ++ AC_CHECK_FUNCS([strncasecmp]) ++ if test $ac_cv_func_strncasecmp = yes; then ++ HAVE_STRNCASECMP=1 ++ else ++ HAVE_STRNCASECMP=0 + fi + AC_CHECK_DECLS([strncasecmp]) + if test $ac_cv_have_decl_strncasecmp = no; then +diff --git a/m4/strchrnul.m4 b/m4/strchrnul.m4 +index 0072e60..b59eda9 100644 +--- a/m4/strchrnul.m4 ++++ b/m4/strchrnul.m4 +@@ -1,5 +1,5 @@ +-# strchrnul.m4 serial 7 +-dnl Copyright (C) 2003, 2007, 2009, 2010 Free Software Foundation, Inc. ++# strchrnul.m4 serial 9 ++dnl Copyright (C) 2003, 2007, 2009-2013 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. +@@ -10,10 +10,39 @@ AC_DEFUN([gl_FUNC_STRCHRNUL], + AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) + + AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS]) +- AC_REPLACE_FUNCS([strchrnul]) ++ AC_CHECK_FUNCS([strchrnul]) + if test $ac_cv_func_strchrnul = no; then + HAVE_STRCHRNUL=0 +- gl_PREREQ_STRCHRNUL ++ else ++ AC_CACHE_CHECK([whether strchrnul works], ++ [gl_cv_func_strchrnul_works], ++ [AC_RUN_IFELSE([AC_LANG_PROGRAM([[ ++#include /* for strchrnul */ ++]], [[const char *buf = "a"; ++ return strchrnul (buf, 'b') != buf + 1; ++ ]])], ++ [gl_cv_func_strchrnul_works=yes], ++ [gl_cv_func_strchrnul_works=no], ++ [dnl Cygwin 1.7.9 introduced strchrnul, but it was broken until 1.7.10 ++ AC_EGREP_CPP([Lucky user], ++ [ ++#if defined __CYGWIN__ ++ #include ++ #if CYGWIN_VERSION_DLL_COMBINED > CYGWIN_VERSION_DLL_MAKE_COMBINED (1007, 9) ++ Lucky user ++ #endif ++#else ++ Lucky user ++#endif ++ ], ++ [gl_cv_func_strchrnul_works="guessing yes"], ++ [gl_cv_func_strchrnul_works="guessing no"]) ++ ]) ++ ]) ++ case "$gl_cv_func_strchrnul_works" in ++ *yes) ;; ++ *) REPLACE_STRCHRNUL=1 ;; ++ esac + fi + ]) + +diff --git a/m4/strerror.m4 b/m4/strerror.m4 +index 1649b24..3989844 100644 +--- a/m4/strerror.m4 ++++ b/m4/strerror.m4 +@@ -1,68 +1,96 @@ +-# strerror.m4 serial 9 +-dnl Copyright (C) 2002, 2007-2010 Free Software Foundation, Inc. ++# strerror.m4 serial 17 ++dnl Copyright (C) 2002, 2007-2013 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. + + AC_DEFUN([gl_FUNC_STRERROR], + [ +- AC_REQUIRE([gl_FUNC_STRERROR_SEPARATE]) +- if test $REPLACE_STRERROR = 1; then +- AC_LIBOBJ([strerror]) +- AC_DEFINE_UNQUOTED([REPLACE_STRERROR], [$REPLACE_STRERROR], +- [Define this to 1 if strerror is broken.]) +- fi +-]) +- +-# Like gl_FUNC_STRERROR, except prepare for separate compilation (no AC_LIBOBJ). +-AC_DEFUN([gl_FUNC_STRERROR_SEPARATE], +-[ + AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS]) + AC_REQUIRE([gl_HEADER_ERRNO_H]) +- if test -z "$ERRNO_H"; then ++ AC_REQUIRE([gl_FUNC_STRERROR_0]) ++ AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles ++ m4_ifdef([gl_FUNC_STRERROR_R_WORKS], [ ++ AC_REQUIRE([gl_FUNC_STRERROR_R_WORKS]) ++ ]) ++ if test "$ERRNO_H:$REPLACE_STRERROR_0" = :0; then + AC_CACHE_CHECK([for working strerror function], + [gl_cv_func_working_strerror], + [AC_RUN_IFELSE( + [AC_LANG_PROGRAM( + [[#include + ]], +- [[return !*strerror (-2);]])], ++ [[if (!*strerror (-2)) return 1;]])], + [gl_cv_func_working_strerror=yes], + [gl_cv_func_working_strerror=no], +- [dnl Assume crossbuild works if it compiles. +- AC_COMPILE_IFELSE( +- [AC_LANG_PROGRAM( +- [[#include +- ]], +- [[return !*strerror (-2);]])], +- [gl_cv_func_working_strerror=yes], +- [gl_cv_func_working_strerror=no]) +- ]) ++ [case "$host_os" in ++ # Guess yes on glibc systems. ++ *-gnu*) gl_cv_func_working_strerror="guessing yes" ;; ++ # If we don't know, assume the worst. ++ *) gl_cv_func_working_strerror="guessing no" ;; ++ esac ++ ]) ++ ]) ++ case "$gl_cv_func_working_strerror" in ++ *yes) ;; ++ *) ++ dnl The system's strerror() fails to return a string for out-of-range ++ dnl integers. Replace it. ++ REPLACE_STRERROR=1 ++ ;; ++ esac ++ m4_ifdef([gl_FUNC_STRERROR_R_WORKS], [ ++ dnl If the system's strerror_r or __xpg_strerror_r clobbers strerror's ++ dnl buffer, we must replace strerror. ++ case "$gl_cv_func_strerror_r_works" in ++ *no) REPLACE_STRERROR=1 ;; ++ esac + ]) +- if test $gl_cv_func_working_strerror = no; then +- dnl The system's strerror() fails to return a string for out-of-range +- dnl integers. Replace it. +- REPLACE_STRERROR=1 +- fi + else + dnl The system's strerror() cannot know about the new errno values we add +- dnl to . Replace it. ++ dnl to , or any fix for strerror(0). Replace it. + REPLACE_STRERROR=1 + fi +- if test $REPLACE_STRERROR = 1; then +- gl_PREREQ_STRERROR +- fi + ]) + +-# Prerequisites of lib/strerror.c. +-AC_DEFUN([gl_PREREQ_STRERROR], [ +- AC_CHECK_DECLS([strerror]) +- AC_CHECK_HEADERS_ONCE([sys/socket.h]) +- if test $ac_cv_header_sys_socket_h != yes; then +- dnl We cannot use AC_CHECK_HEADERS_ONCE here, because that would make +- dnl the check for those headers unconditional; yet cygwin reports +- dnl that the headers are present but cannot be compiled (since on +- dnl cygwin, all socket information should come from sys/socket.h). +- AC_CHECK_HEADERS([winsock2.h]) +- fi ++dnl Detect if strerror(0) passes (that is, does not set errno, and does not ++dnl return a string that matches strerror(-1)). ++AC_DEFUN([gl_FUNC_STRERROR_0], ++[ ++ AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles ++ REPLACE_STRERROR_0=0 ++ AC_CACHE_CHECK([whether strerror(0) succeeds], ++ [gl_cv_func_strerror_0_works], ++ [AC_RUN_IFELSE( ++ [AC_LANG_PROGRAM( ++ [[#include ++ #include ++ ]], ++ [[int result = 0; ++ char *str; ++ errno = 0; ++ str = strerror (0); ++ if (!*str) result |= 1; ++ if (errno) result |= 2; ++ if (strstr (str, "nknown") || strstr (str, "ndefined")) ++ result |= 4; ++ return result;]])], ++ [gl_cv_func_strerror_0_works=yes], ++ [gl_cv_func_strerror_0_works=no], ++ [case "$host_os" in ++ # Guess yes on glibc systems. ++ *-gnu*) gl_cv_func_strerror_0_works="guessing yes" ;; ++ # If we don't know, assume the worst. ++ *) gl_cv_func_strerror_0_works="guessing no" ;; ++ esac ++ ]) ++ ]) ++ case "$gl_cv_func_strerror_0_works" in ++ *yes) ;; ++ *) ++ REPLACE_STRERROR_0=1 ++ AC_DEFINE([REPLACE_STRERROR_0], [1], [Define to 1 if strerror(0) ++ does not return a message implying success.]) ++ ;; ++ esac + ]) +diff --git a/m4/string_h.m4 b/m4/string_h.m4 +index 1977aec..cc5fbbb 100644 +--- a/m4/string_h.m4 ++++ b/m4/string_h.m4 +@@ -1,11 +1,11 @@ + # Configure a GNU-like replacement for . + +-# Copyright (C) 2007-2010 Free Software Foundation, Inc. ++# Copyright (C) 2007-2013 Free Software Foundation, Inc. + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, + # with or without modifications, as long as this notice is preserved. + +-# serial 17 ++# serial 21 + + # Written by Paul Eggert. + +@@ -20,16 +20,16 @@ AC_DEFUN([gl_HEADER_STRING_H_BODY], + [ + AC_REQUIRE([AC_C_RESTRICT]) + AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS]) +- gl_CHECK_NEXT_HEADERS([string.h]) ++ gl_NEXT_HEADERS([string.h]) + + dnl Check for declarations of anything we want to poison if the + dnl corresponding gnulib module is not in use, and which is not + dnl guaranteed by C89. + gl_WARN_ON_USE_PREPARE([[#include + ]], +- [memmem mempcpy memrchr rawmemchr stpcpy stpncpy strchrnul strdup +- strncat strndup strnlen strpbrk strsep strcasestr strtok_r strsignal +- strverscmp]) ++ [ffsl ffsll memmem mempcpy memrchr rawmemchr stpcpy stpncpy strchrnul ++ strdup strncat strndup strnlen strpbrk strsep strcasestr strtok_r ++ strerror_r strsignal strverscmp]) + ]) + + AC_DEFUN([gl_STRING_MODULE_INDICATOR], +@@ -43,6 +43,8 @@ AC_DEFUN([gl_STRING_MODULE_INDICATOR], + + AC_DEFUN([gl_HEADER_STRING_H_DEFAULTS], + [ ++ GNULIB_FFSL=0; AC_SUBST([GNULIB_FFSL]) ++ GNULIB_FFSLL=0; AC_SUBST([GNULIB_FFSLL]) + GNULIB_MEMCHR=0; AC_SUBST([GNULIB_MEMCHR]) + GNULIB_MEMMEM=0; AC_SUBST([GNULIB_MEMMEM]) + GNULIB_MEMPCPY=0; AC_SUBST([GNULIB_MEMPCPY]) +@@ -75,10 +77,13 @@ AC_DEFUN([gl_HEADER_STRING_H_DEFAULTS], + GNULIB_MBSSEP=0; AC_SUBST([GNULIB_MBSSEP]) + GNULIB_MBSTOK_R=0; AC_SUBST([GNULIB_MBSTOK_R]) + GNULIB_STRERROR=0; AC_SUBST([GNULIB_STRERROR]) ++ GNULIB_STRERROR_R=0; AC_SUBST([GNULIB_STRERROR_R]) + GNULIB_STRSIGNAL=0; AC_SUBST([GNULIB_STRSIGNAL]) + GNULIB_STRVERSCMP=0; AC_SUBST([GNULIB_STRVERSCMP]) + HAVE_MBSLEN=0; AC_SUBST([HAVE_MBSLEN]) + dnl Assume proper GNU behavior unless another module says otherwise. ++ HAVE_FFSL=1; AC_SUBST([HAVE_FFSL]) ++ HAVE_FFSLL=1; AC_SUBST([HAVE_FFSLL]) + HAVE_MEMCHR=1; AC_SUBST([HAVE_MEMCHR]) + HAVE_DECL_MEMMEM=1; AC_SUBST([HAVE_DECL_MEMMEM]) + HAVE_MEMPCPY=1; AC_SUBST([HAVE_MEMPCPY]) +@@ -94,6 +99,7 @@ AC_DEFUN([gl_HEADER_STRING_H_DEFAULTS], + HAVE_STRSEP=1; AC_SUBST([HAVE_STRSEP]) + HAVE_STRCASESTR=1; AC_SUBST([HAVE_STRCASESTR]) + HAVE_DECL_STRTOK_R=1; AC_SUBST([HAVE_DECL_STRTOK_R]) ++ HAVE_DECL_STRERROR_R=1; AC_SUBST([HAVE_DECL_STRERROR_R]) + HAVE_DECL_STRSIGNAL=1; AC_SUBST([HAVE_DECL_STRSIGNAL]) + HAVE_STRVERSCMP=1; AC_SUBST([HAVE_STRVERSCMP]) + REPLACE_MEMCHR=0; AC_SUBST([REPLACE_MEMCHR]) +@@ -102,7 +108,9 @@ AC_DEFUN([gl_HEADER_STRING_H_DEFAULTS], + REPLACE_STRDUP=0; AC_SUBST([REPLACE_STRDUP]) + REPLACE_STRSTR=0; AC_SUBST([REPLACE_STRSTR]) + REPLACE_STRCASESTR=0; AC_SUBST([REPLACE_STRCASESTR]) ++ REPLACE_STRCHRNUL=0; AC_SUBST([REPLACE_STRCHRNUL]) + REPLACE_STRERROR=0; AC_SUBST([REPLACE_STRERROR]) ++ REPLACE_STRERROR_R=0; AC_SUBST([REPLACE_STRERROR_R]) + REPLACE_STRNCAT=0; AC_SUBST([REPLACE_STRNCAT]) + REPLACE_STRNDUP=0; AC_SUBST([REPLACE_STRNDUP]) + REPLACE_STRNLEN=0; AC_SUBST([REPLACE_STRNLEN]) +diff --git a/m4/strings_h.m4 b/m4/strings_h.m4 +index 4374c7c..76ef242 100644 +--- a/m4/strings_h.m4 ++++ b/m4/strings_h.m4 +@@ -1,7 +1,7 @@ +-# Configure a replacement for . +-# serial 3 ++# Configure a replacement for . ++# serial 6 + +-# Copyright (C) 2007, 2009-2010 Free Software Foundation, Inc. ++# Copyright (C) 2007, 2009-2013 Free Software Foundation, Inc. + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, + # with or without modifications, as long as this notice is preserved. +@@ -16,12 +16,23 @@ AC_DEFUN([gl_HEADER_STRINGS_H], + AC_DEFUN([gl_HEADER_STRINGS_H_BODY], + [ + AC_REQUIRE([gl_HEADER_STRINGS_H_DEFAULTS]) ++ + gl_CHECK_NEXT_HEADERS([strings.h]) ++ if test $ac_cv_header_strings_h = yes; then ++ HAVE_STRINGS_H=1 ++ else ++ HAVE_STRINGS_H=0 ++ fi ++ AC_SUBST([HAVE_STRINGS_H]) + + dnl Check for declarations of anything we want to poison if the + dnl corresponding gnulib module is not in use. +- gl_WARN_ON_USE_PREPARE([[#include +- ]], [strcasecmp strncasecmp]) ++ gl_WARN_ON_USE_PREPARE([[ ++ /* Minix 3.1.8 has a bug: must be included before ++ . */ ++ #include ++ #include ++ ]], [ffs strcasecmp strncasecmp]) + ]) + + AC_DEFUN([gl_STRINGS_MODULE_INDICATOR], +@@ -33,7 +44,9 @@ AC_DEFUN([gl_STRINGS_MODULE_INDICATOR], + + AC_DEFUN([gl_HEADER_STRINGS_H_DEFAULTS], + [ ++ GNULIB_FFS=0; AC_SUBST([GNULIB_FFS]) + dnl Assume proper GNU behavior unless another module says otherwise. ++ HAVE_FFS=1; AC_SUBST([HAVE_FFS]) + HAVE_STRCASECMP=1; AC_SUBST([HAVE_STRCASECMP]) + HAVE_DECL_STRNCASECMP=1; AC_SUBST([HAVE_DECL_STRNCASECMP]) + ]) +diff --git a/m4/strndup.m4 b/m4/strndup.m4 +index b3567d8..a1f8274 100644 +--- a/m4/strndup.m4 ++++ b/m4/strndup.m4 +@@ -1,5 +1,5 @@ +-# strndup.m4 serial 18 +-dnl Copyright (C) 2002-2003, 2005-2010 Free Software Foundation, Inc. ++# strndup.m4 serial 21 ++dnl Copyright (C) 2002-2003, 2005-2013 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. +@@ -18,13 +18,18 @@ AC_DEFUN([gl_FUNC_STRNDUP], + fi + + if test $ac_cv_func_strndup = yes; then ++ HAVE_STRNDUP=1 + # AIX 4.3.3, AIX 5.1 have a function that fails to add the terminating '\0'. + AC_CACHE_CHECK([for working strndup], [gl_cv_func_strndup_works], + [AC_RUN_IFELSE([ + AC_LANG_PROGRAM([[#include + #include ]], [[ +-#ifndef HAVE_DECL_STRNDUP +- extern char *strndup (const char *, size_t); ++#if !HAVE_DECL_STRNDUP ++ extern ++ #ifdef __cplusplus ++ "C" ++ #endif ++ char *strndup (const char *, size_t); + #endif + char *s; + s = strndup ("some longer string", 15); +@@ -42,12 +47,9 @@ changequote(,)dnl + changequote([,])dnl + ])]) + case $gl_cv_func_strndup_works in +- *no) +- REPLACE_STRNDUP=1 +- AC_LIBOBJ([strndup]) +- ;; ++ *no) REPLACE_STRNDUP=1 ;; + esac + else +- AC_LIBOBJ([strndup]) ++ HAVE_STRNDUP=0 + fi + ]) +diff --git a/m4/strnlen.m4 b/m4/strnlen.m4 +index 52bb838..eae82b7 100644 +--- a/m4/strnlen.m4 ++++ b/m4/strnlen.m4 +@@ -1,5 +1,5 @@ +-# strnlen.m4 serial 12 +-dnl Copyright (C) 2002-2003, 2005-2007, 2009-2010 Free Software Foundation, ++# strnlen.m4 serial 13 ++dnl Copyright (C) 2002-2003, 2005-2007, 2009-2013 Free Software Foundation, + dnl Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, +@@ -16,16 +16,14 @@ AC_DEFUN([gl_FUNC_STRNLEN], + if test $ac_cv_have_decl_strnlen = no; then + HAVE_DECL_STRNLEN=0 + else +- AC_FUNC_STRNLEN ++ m4_pushdef([AC_LIBOBJ], [:]) + dnl Note: AC_FUNC_STRNLEN does AC_LIBOBJ([strnlen]). ++ AC_FUNC_STRNLEN ++ m4_popdef([AC_LIBOBJ]) + if test $ac_cv_func_strnlen_working = no; then + REPLACE_STRNLEN=1 + fi + fi +- if test $HAVE_DECL_STRNLEN = 0 || test $REPLACE_STRNLEN = 1; then +- AC_LIBOBJ([strnlen]) +- gl_PREREQ_STRNLEN +- fi + ]) + + # Prerequisites of lib/strnlen.c. +diff --git a/m4/sys_socket_h.m4 b/m4/sys_socket_h.m4 +new file mode 100644 +index 0000000..9486377 +--- /dev/null ++++ b/m4/sys_socket_h.m4 +@@ -0,0 +1,176 @@ ++# sys_socket_h.m4 serial 23 ++dnl Copyright (C) 2005-2013 Free Software Foundation, Inc. ++dnl This file is free software; the Free Software Foundation ++dnl gives unlimited permission to copy and/or distribute it, ++dnl with or without modifications, as long as this notice is preserved. ++ ++dnl From Simon Josefsson. ++ ++AC_DEFUN([gl_HEADER_SYS_SOCKET], ++[ ++ AC_REQUIRE([gl_SYS_SOCKET_H_DEFAULTS]) ++ AC_REQUIRE([AC_CANONICAL_HOST]) ++ ++ dnl On OSF/1, the functions recv(), send(), recvfrom(), sendto() have ++ dnl old-style declarations (with return type 'int' instead of 'ssize_t') ++ dnl unless _POSIX_PII_SOCKET is defined. ++ case "$host_os" in ++ osf*) ++ AC_DEFINE([_POSIX_PII_SOCKET], [1], ++ [Define to 1 in order to get the POSIX compatible declarations ++ of socket functions.]) ++ ;; ++ esac ++ ++ AC_CACHE_CHECK([whether is self-contained], ++ [gl_cv_header_sys_socket_h_selfcontained], ++ [ ++ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[]])], ++ [gl_cv_header_sys_socket_h_selfcontained=yes], ++ [gl_cv_header_sys_socket_h_selfcontained=no]) ++ ]) ++ if test $gl_cv_header_sys_socket_h_selfcontained = yes; then ++ dnl If the shutdown function exists, should define ++ dnl SHUT_RD, SHUT_WR, SHUT_RDWR. ++ AC_CHECK_FUNCS([shutdown]) ++ if test $ac_cv_func_shutdown = yes; then ++ AC_CACHE_CHECK([whether defines the SHUT_* macros], ++ [gl_cv_header_sys_socket_h_shut], ++ [ ++ AC_COMPILE_IFELSE( ++ [AC_LANG_PROGRAM([[#include ]], ++ [[int a[] = { SHUT_RD, SHUT_WR, SHUT_RDWR };]])], ++ [gl_cv_header_sys_socket_h_shut=yes], ++ [gl_cv_header_sys_socket_h_shut=no]) ++ ]) ++ if test $gl_cv_header_sys_socket_h_shut = no; then ++ SYS_SOCKET_H='sys/socket.h' ++ fi ++ fi ++ fi ++ # We need to check for ws2tcpip.h now. ++ gl_PREREQ_SYS_H_SOCKET ++ AC_CHECK_TYPES([struct sockaddr_storage, sa_family_t],,,[ ++ /* sys/types.h is not needed according to POSIX, but the ++ sys/socket.h in i386-unknown-freebsd4.10 and ++ powerpc-apple-darwin5.5 required it. */ ++#include ++#ifdef HAVE_SYS_SOCKET_H ++#include ++#endif ++#ifdef HAVE_WS2TCPIP_H ++#include ++#endif ++]) ++ if test $ac_cv_type_struct_sockaddr_storage = no; then ++ HAVE_STRUCT_SOCKADDR_STORAGE=0 ++ fi ++ if test $ac_cv_type_sa_family_t = no; then ++ HAVE_SA_FAMILY_T=0 ++ fi ++ if test $ac_cv_type_struct_sockaddr_storage != no; then ++ AC_CHECK_MEMBERS([struct sockaddr_storage.ss_family], ++ [], ++ [HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY=0], ++ [#include ++ #ifdef HAVE_SYS_SOCKET_H ++ #include ++ #endif ++ #ifdef HAVE_WS2TCPIP_H ++ #include ++ #endif ++ ]) ++ fi ++ if test $HAVE_STRUCT_SOCKADDR_STORAGE = 0 || test $HAVE_SA_FAMILY_T = 0 \ ++ || test $HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY = 0; then ++ SYS_SOCKET_H='sys/socket.h' ++ fi ++ gl_PREREQ_SYS_H_WINSOCK2 ++ ++ dnl Check for declarations of anything we want to poison if the ++ dnl corresponding gnulib module is not in use. ++ gl_WARN_ON_USE_PREPARE([[ ++/* Some systems require prerequisite headers. */ ++#include ++#include ++ ]], [socket connect accept bind getpeername getsockname getsockopt ++ listen recv send recvfrom sendto setsockopt shutdown accept4]) ++]) ++ ++AC_DEFUN([gl_PREREQ_SYS_H_SOCKET], ++[ ++ dnl Check prerequisites of the replacement. ++ AC_REQUIRE([gl_CHECK_SOCKET_HEADERS]) ++ gl_CHECK_NEXT_HEADERS([sys/socket.h]) ++ if test $ac_cv_header_sys_socket_h = yes; then ++ HAVE_SYS_SOCKET_H=1 ++ HAVE_WS2TCPIP_H=0 ++ else ++ HAVE_SYS_SOCKET_H=0 ++ if test $ac_cv_header_ws2tcpip_h = yes; then ++ HAVE_WS2TCPIP_H=1 ++ else ++ HAVE_WS2TCPIP_H=0 ++ fi ++ fi ++ AC_SUBST([HAVE_SYS_SOCKET_H]) ++ AC_SUBST([HAVE_WS2TCPIP_H]) ++]) ++ ++# Common prerequisites of the replacement and of the ++# replacement. ++# Sets and substitutes HAVE_WINSOCK2_H. ++AC_DEFUN([gl_PREREQ_SYS_H_WINSOCK2], ++[ ++ m4_ifdef([gl_UNISTD_H_DEFAULTS], [AC_REQUIRE([gl_UNISTD_H_DEFAULTS])]) ++ m4_ifdef([gl_SYS_IOCTL_H_DEFAULTS], [AC_REQUIRE([gl_SYS_IOCTL_H_DEFAULTS])]) ++ AC_CHECK_HEADERS_ONCE([sys/socket.h]) ++ if test $ac_cv_header_sys_socket_h != yes; then ++ dnl We cannot use AC_CHECK_HEADERS_ONCE here, because that would make ++ dnl the check for those headers unconditional; yet cygwin reports ++ dnl that the headers are present but cannot be compiled (since on ++ dnl cygwin, all socket information should come from sys/socket.h). ++ AC_CHECK_HEADERS([winsock2.h]) ++ fi ++ if test "$ac_cv_header_winsock2_h" = yes; then ++ HAVE_WINSOCK2_H=1 ++ UNISTD_H_HAVE_WINSOCK2_H=1 ++ SYS_IOCTL_H_HAVE_WINSOCK2_H=1 ++ else ++ HAVE_WINSOCK2_H=0 ++ fi ++ AC_SUBST([HAVE_WINSOCK2_H]) ++]) ++ ++AC_DEFUN([gl_SYS_SOCKET_MODULE_INDICATOR], ++[ ++ dnl Use AC_REQUIRE here, so that the default settings are expanded once only. ++ AC_REQUIRE([gl_SYS_SOCKET_H_DEFAULTS]) ++ gl_MODULE_INDICATOR_SET_VARIABLE([$1]) ++ dnl Define it also as a C macro, for the benefit of the unit tests. ++ gl_MODULE_INDICATOR_FOR_TESTS([$1]) ++]) ++ ++AC_DEFUN([gl_SYS_SOCKET_H_DEFAULTS], ++[ ++ GNULIB_SOCKET=0; AC_SUBST([GNULIB_SOCKET]) ++ GNULIB_CONNECT=0; AC_SUBST([GNULIB_CONNECT]) ++ GNULIB_ACCEPT=0; AC_SUBST([GNULIB_ACCEPT]) ++ GNULIB_BIND=0; AC_SUBST([GNULIB_BIND]) ++ GNULIB_GETPEERNAME=0; AC_SUBST([GNULIB_GETPEERNAME]) ++ GNULIB_GETSOCKNAME=0; AC_SUBST([GNULIB_GETSOCKNAME]) ++ GNULIB_GETSOCKOPT=0; AC_SUBST([GNULIB_GETSOCKOPT]) ++ GNULIB_LISTEN=0; AC_SUBST([GNULIB_LISTEN]) ++ GNULIB_RECV=0; AC_SUBST([GNULIB_RECV]) ++ GNULIB_SEND=0; AC_SUBST([GNULIB_SEND]) ++ GNULIB_RECVFROM=0; AC_SUBST([GNULIB_RECVFROM]) ++ GNULIB_SENDTO=0; AC_SUBST([GNULIB_SENDTO]) ++ GNULIB_SETSOCKOPT=0; AC_SUBST([GNULIB_SETSOCKOPT]) ++ GNULIB_SHUTDOWN=0; AC_SUBST([GNULIB_SHUTDOWN]) ++ GNULIB_ACCEPT4=0; AC_SUBST([GNULIB_ACCEPT4]) ++ HAVE_STRUCT_SOCKADDR_STORAGE=1; AC_SUBST([HAVE_STRUCT_SOCKADDR_STORAGE]) ++ HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY=1; ++ AC_SUBST([HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY]) ++ HAVE_SA_FAMILY_T=1; AC_SUBST([HAVE_SA_FAMILY_T]) ++ HAVE_ACCEPT4=1; AC_SUBST([HAVE_ACCEPT4]) ++]) +diff --git a/m4/sys_types_h.m4 b/m4/sys_types_h.m4 +new file mode 100644 +index 0000000..d15c1b3 +--- /dev/null ++++ b/m4/sys_types_h.m4 +@@ -0,0 +1,24 @@ ++# sys_types_h.m4 serial 5 ++dnl Copyright (C) 2011-2013 Free Software Foundation, Inc. ++dnl This file is free software; the Free Software Foundation ++dnl gives unlimited permission to copy and/or distribute it, ++dnl with or without modifications, as long as this notice is preserved. ++ ++AC_DEFUN_ONCE([gl_SYS_TYPES_H], ++[ ++ AC_REQUIRE([gl_SYS_TYPES_H_DEFAULTS]) ++ gl_NEXT_HEADERS([sys/types.h]) ++ ++ dnl Ensure the type pid_t gets defined. ++ AC_REQUIRE([AC_TYPE_PID_T]) ++ ++ dnl Ensure the type mode_t gets defined. ++ AC_REQUIRE([AC_TYPE_MODE_T]) ++ ++ dnl Whether to override the 'off_t' type. ++ AC_REQUIRE([gl_TYPE_OFF_T]) ++]) ++ ++AC_DEFUN([gl_SYS_TYPES_H_DEFAULTS], ++[ ++]) +diff --git a/m4/sys_wait_h.m4 b/m4/sys_wait_h.m4 +deleted file mode 100644 +index b0d23fa..0000000 +--- a/m4/sys_wait_h.m4 ++++ /dev/null +@@ -1,25 +0,0 @@ +-# sys_wait_h.m4 serial 4 +-dnl Copyright (C) 2008-2010 Free Software Foundation, Inc. +-dnl This file is free software; the Free Software Foundation +-dnl gives unlimited permission to copy and/or distribute it, +-dnl with or without modifications, as long as this notice is preserved. +- +-AC_DEFUN([gl_SYS_WAIT_H], +-[ +- AC_REQUIRE([gl_SYS_WAIT_H_DEFAULTS]) +- +- dnl is always overridden, because of GNULIB_POSIXCHECK. +- gl_CHECK_NEXT_HEADERS([sys/wait.h]) +-]) +- +-AC_DEFUN([gl_SYS_WAIT_MODULE_INDICATOR], +-[ +- dnl Use AC_REQUIRE here, so that the default settings are expanded once only. +- AC_REQUIRE([gl_SYS_WAIT_H_DEFAULTS]) +- gl_MODULE_INDICATOR_SET_VARIABLE([$1]) +-]) +- +-AC_DEFUN([gl_SYS_WAIT_H_DEFAULTS], +-[ +- dnl Assume proper GNU behavior unless another module says otherwise. +-]) +diff --git a/m4/sysexits.m4 b/m4/sysexits.m4 +index b3baa51..bd8abaa 100644 +--- a/m4/sysexits.m4 ++++ b/m4/sysexits.m4 +@@ -1,5 +1,5 @@ +-# sysexits.m4 serial 5 +-dnl Copyright (C) 2003, 2005, 2007, 2009, 2010 Free Software Foundation, Inc. ++# sysexits.m4 serial 6 ++dnl Copyright (C) 2003, 2005, 2007, 2009-2013 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. +@@ -40,4 +40,5 @@ AC_DEFUN([gl_SYSEXITS], + fi + AC_SUBST([HAVE_SYSEXITS_H]) + AC_SUBST([SYSEXITS_H]) ++ AM_CONDITIONAL([GL_GENERATE_SYSEXITS_H], [test -n "$SYSEXITS_H"]) + ]) +diff --git a/m4/threadlib.m4 b/m4/threadlib.m4 +index bff01bc..26bdeb5 100644 +--- a/m4/threadlib.m4 ++++ b/m4/threadlib.m4 +@@ -1,5 +1,5 @@ +-# threadlib.m4 serial 6 (gettext-0.18.2) +-dnl Copyright (C) 2005-2010 Free Software Foundation, Inc. ++# threadlib.m4 serial 10 (gettext-0.18.2) ++dnl Copyright (C) 2005-2013 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. +@@ -9,8 +9,13 @@ dnl From Bruno Haible. + dnl gl_THREADLIB + dnl ------------ + dnl Tests for a multithreading library to be used. ++dnl If the configure.ac contains a definition of the gl_THREADLIB_DEFAULT_NO ++dnl (it must be placed before the invocation of gl_THREADLIB_EARLY!), then the ++dnl default is 'no', otherwise it is system dependent. In both cases, the user ++dnl can change the choice through the options --enable-threads=choice or ++dnl --disable-threads. + dnl Defines at most one of the macros USE_POSIX_THREADS, USE_SOLARIS_THREADS, +-dnl USE_PTH_THREADS, USE_WIN32_THREADS ++dnl USE_PTH_THREADS, USE_WINDOWS_THREADS + dnl Sets the variables LIBTHREAD and LTLIBTHREAD to the linker options for use + dnl in a Makefile (LIBTHREAD for use without libtool, LTLIBTHREAD for use with + dnl libtool). +@@ -44,10 +49,12 @@ AC_DEFUN([gl_THREADLIB_EARLY_BODY], + [AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])], + [AC_REQUIRE([AC_GNU_SOURCE])]) + dnl Check for multithreading. +- m4_divert_text([DEFAULTS], [gl_use_threads_default=]) ++ m4_ifdef([gl_THREADLIB_DEFAULT_NO], ++ [m4_divert_text([DEFAULTS], [gl_use_threads_default=no])], ++ [m4_divert_text([DEFAULTS], [gl_use_threads_default=])]) + AC_ARG_ENABLE([threads], +-AC_HELP_STRING([--enable-threads={posix|solaris|pth|win32}], [specify multithreading API]) +-AC_HELP_STRING([--disable-threads], [build without multithread safety]), ++AC_HELP_STRING([--enable-threads={posix|solaris|pth|windows}], [specify multithreading API])m4_ifdef([gl_THREADLIB_DEFAULT_NO], [], [ ++AC_HELP_STRING([--disable-threads], [build without multithread safety])]), + [gl_use_threads=$enableval], + [if test -n "$gl_use_threads_default"; then + gl_use_threads="$gl_use_threads_default" +@@ -243,7 +250,7 @@ int main () + AC_LIB_LINKFLAGS([pth]) + gl_have_pth= + gl_save_LIBS="$LIBS" +- LIBS="$LIBS -lpth" ++ LIBS="$LIBS $LIBPTH" + AC_LINK_IFELSE( + [AC_LANG_PROGRAM([[#include ]], [[pth_self();]])], + [gl_have_pth=yes]) +@@ -269,17 +276,19 @@ int main () + fi + fi + if test -z "$gl_have_pthread"; then +- if test "$gl_use_threads" = yes || test "$gl_use_threads" = win32; then +- if { case "$host_os" in +- mingw*) true;; +- *) false;; +- esac +- }; then +- gl_threads_api=win32 +- AC_DEFINE([USE_WIN32_THREADS], [1], +- [Define if the Win32 multithreading API can be used.]) +- fi +- fi ++ case "$gl_use_threads" in ++ yes | windows | win32) # The 'win32' is for backward compatibility. ++ if { case "$host_os" in ++ mingw*) true;; ++ *) false;; ++ esac ++ }; then ++ gl_threads_api=windows ++ AC_DEFINE([USE_WINDOWS_THREADS], [1], ++ [Define if the native Windows multithreading API can be used.]) ++ fi ++ ;; ++ esac + fi + fi + AC_MSG_CHECKING([for multithread API to use]) +@@ -310,50 +319,50 @@ AC_DEFUN([gl_DISABLE_THREADS], [ + + dnl Survey of platforms: + dnl +-dnl Platform Available Compiler Supports test-lock +-dnl flavours option weak result +-dnl --------------- --------- --------- -------- --------- +-dnl Linux 2.4/glibc posix -lpthread Y OK ++dnl Platform Available Compiler Supports test-lock ++dnl flavours option weak result ++dnl --------------- --------- --------- -------- --------- ++dnl Linux 2.4/glibc posix -lpthread Y OK + dnl +-dnl GNU Hurd/glibc posix ++dnl GNU Hurd/glibc posix + dnl +-dnl FreeBSD 5.3 posix -lc_r Y +-dnl posix -lkse ? Y +-dnl posix -lpthread ? Y +-dnl posix -lthr Y ++dnl FreeBSD 5.3 posix -lc_r Y ++dnl posix -lkse ? Y ++dnl posix -lpthread ? Y ++dnl posix -lthr Y + dnl +-dnl FreeBSD 5.2 posix -lc_r Y +-dnl posix -lkse Y +-dnl posix -lthr Y ++dnl FreeBSD 5.2 posix -lc_r Y ++dnl posix -lkse Y ++dnl posix -lthr Y + dnl +-dnl FreeBSD 4.0,4.10 posix -lc_r Y OK ++dnl FreeBSD 4.0,4.10 posix -lc_r Y OK + dnl +-dnl NetBSD 1.6 -- ++dnl NetBSD 1.6 -- + dnl +-dnl OpenBSD 3.4 posix -lpthread Y OK ++dnl OpenBSD 3.4 posix -lpthread Y OK + dnl +-dnl MacOS X 10.[123] posix -lpthread Y OK ++dnl Mac OS X 10.[123] posix -lpthread Y OK + dnl +-dnl Solaris 7,8,9 posix -lpthread Y Sol 7,8: 0.0; Sol 9: OK +-dnl solaris -lthread Y Sol 7,8: 0.0; Sol 9: OK ++dnl Solaris 7,8,9 posix -lpthread Y Sol 7,8: 0.0; Sol 9: OK ++dnl solaris -lthread Y Sol 7,8: 0.0; Sol 9: OK + dnl +-dnl HP-UX 11 posix -lpthread N (cc) OK ++dnl HP-UX 11 posix -lpthread N (cc) OK + dnl Y (gcc) + dnl +-dnl IRIX 6.5 posix -lpthread Y 0.5 ++dnl IRIX 6.5 posix -lpthread Y 0.5 + dnl +-dnl AIX 4.3,5.1 posix -lpthread N AIX 4: 0.5; AIX 5: OK ++dnl AIX 4.3,5.1 posix -lpthread N AIX 4: 0.5; AIX 5: OK + dnl +-dnl OSF/1 4.0,5.1 posix -pthread (cc) N OK ++dnl OSF/1 4.0,5.1 posix -pthread (cc) N OK + dnl -lpthread (gcc) Y + dnl +-dnl Cygwin posix -lpthread Y OK ++dnl Cygwin posix -lpthread Y OK + dnl +-dnl Any of the above pth -lpth 0.0 ++dnl Any of the above pth -lpth 0.0 + dnl +-dnl Mingw win32 N OK ++dnl Mingw windows N OK + dnl +-dnl BeOS 5 -- ++dnl BeOS 5 -- + dnl + dnl The test-lock result shows what happens if in test-lock.c EXPLICIT_YIELD is + dnl turned off: +diff --git a/m4/uintmax_t.m4 b/m4/uintmax_t.m4 +index 03b51bc..c6ff800 100644 +--- a/m4/uintmax_t.m4 ++++ b/m4/uintmax_t.m4 +@@ -1,5 +1,5 @@ + # uintmax_t.m4 serial 12 +-dnl Copyright (C) 1997-2004, 2007-2010 Free Software Foundation, Inc. ++dnl Copyright (C) 1997-2004, 2007-2013 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. +diff --git a/m4/unistd_h.m4 b/m4/unistd_h.m4 +index 48d06c7..32dcfa5 100644 +--- a/m4/unistd_h.m4 ++++ b/m4/unistd_h.m4 +@@ -1,5 +1,5 @@ +-# unistd_h.m4 serial 46 +-dnl Copyright (C) 2006-2010 Free Software Foundation, Inc. ++# unistd_h.m4 serial 66 ++dnl Copyright (C) 2006-2013 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. +@@ -11,11 +11,8 @@ AC_DEFUN([gl_UNISTD_H], + dnl Use AC_REQUIRE here, so that the default behavior below is expanded + dnl once only, before all statements that occur in other macros. + AC_REQUIRE([gl_UNISTD_H_DEFAULTS]) +- AC_REQUIRE([AC_C_INLINE]) + + gl_CHECK_NEXT_HEADERS([unistd.h]) +- +- AC_CHECK_HEADERS_ONCE([unistd.h]) + if test $ac_cv_header_unistd_h = yes; then + HAVE_UNISTD_H=1 + else +@@ -23,11 +20,20 @@ AC_DEFUN([gl_UNISTD_H], + fi + AC_SUBST([HAVE_UNISTD_H]) + ++ dnl Ensure the type pid_t gets defined. ++ AC_REQUIRE([AC_TYPE_PID_T]) ++ ++ dnl Determine WINDOWS_64_BIT_OFF_T. ++ AC_REQUIRE([gl_TYPE_OFF_T]) ++ + dnl Check for declarations of anything we want to poison if the + dnl corresponding gnulib module is not in use. +- gl_WARN_ON_USE_PREPARE([[#include ++ gl_WARN_ON_USE_PREPARE([[ ++#if HAVE_UNISTD_H ++# include ++#endif + /* Some systems declare various items in the wrong headers. */ +-#ifndef __GLIBC__ ++#if !(defined __GLIBC__ && !defined __UCLIBC__) + # include + # include + # include +@@ -35,12 +41,13 @@ AC_DEFUN([gl_UNISTD_H], + # include + # endif + #endif +- ]], [chown dup2 dup3 environ euidaccess faccessat fchdir fchownat +- fsync ftruncate getcwd getdomainname getdtablesize getgroups +- gethostname getlogin getlogin_r getpagesize getusershell setusershell +- endusershell lchown link linkat lseek pipe2 pread pwrite readlink +- readlinkat rmdir sleep symlink symlinkat ttyname_r unlink unlinkat +- usleep]) ++ ]], [chdir chown dup dup2 dup3 environ euidaccess faccessat fchdir fchownat ++ fdatasync fsync ftruncate getcwd getdomainname getdtablesize getgroups ++ gethostname getlogin getlogin_r getpagesize ++ getusershell setusershell endusershell ++ group_member isatty lchown link linkat lseek pipe pipe2 pread pwrite ++ readlink readlinkat rmdir sethostname sleep symlink symlinkat ttyname_r ++ unlink unlinkat usleep]) + ]) + + AC_DEFUN([gl_UNISTD_MODULE_INDICATOR], +@@ -54,46 +61,54 @@ AC_DEFUN([gl_UNISTD_MODULE_INDICATOR], + + AC_DEFUN([gl_UNISTD_H_DEFAULTS], + [ +- GNULIB_CHOWN=0; AC_SUBST([GNULIB_CHOWN]) +- GNULIB_CLOSE=0; AC_SUBST([GNULIB_CLOSE]) +- GNULIB_DUP2=0; AC_SUBST([GNULIB_DUP2]) +- GNULIB_DUP3=0; AC_SUBST([GNULIB_DUP3]) +- GNULIB_ENVIRON=0; AC_SUBST([GNULIB_ENVIRON]) +- GNULIB_EUIDACCESS=0; AC_SUBST([GNULIB_EUIDACCESS]) +- GNULIB_FACCESSAT=0; AC_SUBST([GNULIB_FACCESSAT]) +- GNULIB_FCHDIR=0; AC_SUBST([GNULIB_FCHDIR]) +- GNULIB_FCHOWNAT=0; AC_SUBST([GNULIB_FCHOWNAT]) +- GNULIB_FSYNC=0; AC_SUBST([GNULIB_FSYNC]) +- GNULIB_FTRUNCATE=0; AC_SUBST([GNULIB_FTRUNCATE]) +- GNULIB_GETCWD=0; AC_SUBST([GNULIB_GETCWD]) +- GNULIB_GETDOMAINNAME=0; AC_SUBST([GNULIB_GETDOMAINNAME]) +- GNULIB_GETDTABLESIZE=0; AC_SUBST([GNULIB_GETDTABLESIZE]) +- GNULIB_GETGROUPS=0; AC_SUBST([GNULIB_GETGROUPS]) +- GNULIB_GETHOSTNAME=0; AC_SUBST([GNULIB_GETHOSTNAME]) +- GNULIB_GETLOGIN=0; AC_SUBST([GNULIB_GETLOGIN]) +- GNULIB_GETLOGIN_R=0; AC_SUBST([GNULIB_GETLOGIN_R]) +- GNULIB_GETPAGESIZE=0; AC_SUBST([GNULIB_GETPAGESIZE]) +- GNULIB_GETUSERSHELL=0; AC_SUBST([GNULIB_GETUSERSHELL]) +- GNULIB_LCHOWN=0; AC_SUBST([GNULIB_LCHOWN]) +- GNULIB_LINK=0; AC_SUBST([GNULIB_LINK]) +- GNULIB_LINKAT=0; AC_SUBST([GNULIB_LINKAT]) +- GNULIB_LSEEK=0; AC_SUBST([GNULIB_LSEEK]) +- GNULIB_PIPE2=0; AC_SUBST([GNULIB_PIPE2]) +- GNULIB_PREAD=0; AC_SUBST([GNULIB_PREAD]) +- GNULIB_PWRITE=0; AC_SUBST([GNULIB_PWRITE]) +- GNULIB_READLINK=0; AC_SUBST([GNULIB_READLINK]) +- GNULIB_READLINKAT=0; AC_SUBST([GNULIB_READLINKAT]) +- GNULIB_RMDIR=0; AC_SUBST([GNULIB_RMDIR]) +- GNULIB_SLEEP=0; AC_SUBST([GNULIB_SLEEP]) +- GNULIB_SYMLINK=0; AC_SUBST([GNULIB_SYMLINK]) +- GNULIB_SYMLINKAT=0; AC_SUBST([GNULIB_SYMLINKAT]) +- GNULIB_TTYNAME_R=0; AC_SUBST([GNULIB_TTYNAME_R]) +- GNULIB_UNISTD_H_GETOPT=0; AC_SUBST([GNULIB_UNISTD_H_GETOPT]) +- GNULIB_UNISTD_H_SIGPIPE=0; AC_SUBST([GNULIB_UNISTD_H_SIGPIPE]) +- GNULIB_UNLINK=0; AC_SUBST([GNULIB_UNLINK]) +- GNULIB_UNLINKAT=0; AC_SUBST([GNULIB_UNLINKAT]) +- GNULIB_USLEEP=0; AC_SUBST([GNULIB_USLEEP]) +- GNULIB_WRITE=0; AC_SUBST([GNULIB_WRITE]) ++ GNULIB_CHDIR=0; AC_SUBST([GNULIB_CHDIR]) ++ GNULIB_CHOWN=0; AC_SUBST([GNULIB_CHOWN]) ++ GNULIB_CLOSE=0; AC_SUBST([GNULIB_CLOSE]) ++ GNULIB_DUP=0; AC_SUBST([GNULIB_DUP]) ++ GNULIB_DUP2=0; AC_SUBST([GNULIB_DUP2]) ++ GNULIB_DUP3=0; AC_SUBST([GNULIB_DUP3]) ++ GNULIB_ENVIRON=0; AC_SUBST([GNULIB_ENVIRON]) ++ GNULIB_EUIDACCESS=0; AC_SUBST([GNULIB_EUIDACCESS]) ++ GNULIB_FACCESSAT=0; AC_SUBST([GNULIB_FACCESSAT]) ++ GNULIB_FCHDIR=0; AC_SUBST([GNULIB_FCHDIR]) ++ GNULIB_FCHOWNAT=0; AC_SUBST([GNULIB_FCHOWNAT]) ++ GNULIB_FDATASYNC=0; AC_SUBST([GNULIB_FDATASYNC]) ++ GNULIB_FSYNC=0; AC_SUBST([GNULIB_FSYNC]) ++ GNULIB_FTRUNCATE=0; AC_SUBST([GNULIB_FTRUNCATE]) ++ GNULIB_GETCWD=0; AC_SUBST([GNULIB_GETCWD]) ++ GNULIB_GETDOMAINNAME=0; AC_SUBST([GNULIB_GETDOMAINNAME]) ++ GNULIB_GETDTABLESIZE=0; AC_SUBST([GNULIB_GETDTABLESIZE]) ++ GNULIB_GETGROUPS=0; AC_SUBST([GNULIB_GETGROUPS]) ++ GNULIB_GETHOSTNAME=0; AC_SUBST([GNULIB_GETHOSTNAME]) ++ GNULIB_GETLOGIN=0; AC_SUBST([GNULIB_GETLOGIN]) ++ GNULIB_GETLOGIN_R=0; AC_SUBST([GNULIB_GETLOGIN_R]) ++ GNULIB_GETPAGESIZE=0; AC_SUBST([GNULIB_GETPAGESIZE]) ++ GNULIB_GETUSERSHELL=0; AC_SUBST([GNULIB_GETUSERSHELL]) ++ GNULIB_GROUP_MEMBER=0; AC_SUBST([GNULIB_GROUP_MEMBER]) ++ GNULIB_ISATTY=0; AC_SUBST([GNULIB_ISATTY]) ++ GNULIB_LCHOWN=0; AC_SUBST([GNULIB_LCHOWN]) ++ GNULIB_LINK=0; AC_SUBST([GNULIB_LINK]) ++ GNULIB_LINKAT=0; AC_SUBST([GNULIB_LINKAT]) ++ GNULIB_LSEEK=0; AC_SUBST([GNULIB_LSEEK]) ++ GNULIB_PIPE=0; AC_SUBST([GNULIB_PIPE]) ++ GNULIB_PIPE2=0; AC_SUBST([GNULIB_PIPE2]) ++ GNULIB_PREAD=0; AC_SUBST([GNULIB_PREAD]) ++ GNULIB_PWRITE=0; AC_SUBST([GNULIB_PWRITE]) ++ GNULIB_READ=0; AC_SUBST([GNULIB_READ]) ++ GNULIB_READLINK=0; AC_SUBST([GNULIB_READLINK]) ++ GNULIB_READLINKAT=0; AC_SUBST([GNULIB_READLINKAT]) ++ GNULIB_RMDIR=0; AC_SUBST([GNULIB_RMDIR]) ++ GNULIB_SETHOSTNAME=0; AC_SUBST([GNULIB_SETHOSTNAME]) ++ GNULIB_SLEEP=0; AC_SUBST([GNULIB_SLEEP]) ++ GNULIB_SYMLINK=0; AC_SUBST([GNULIB_SYMLINK]) ++ GNULIB_SYMLINKAT=0; AC_SUBST([GNULIB_SYMLINKAT]) ++ GNULIB_TTYNAME_R=0; AC_SUBST([GNULIB_TTYNAME_R]) ++ GNULIB_UNISTD_H_NONBLOCKING=0; AC_SUBST([GNULIB_UNISTD_H_NONBLOCKING]) ++ GNULIB_UNISTD_H_SIGPIPE=0; AC_SUBST([GNULIB_UNISTD_H_SIGPIPE]) ++ GNULIB_UNLINK=0; AC_SUBST([GNULIB_UNLINK]) ++ GNULIB_UNLINKAT=0; AC_SUBST([GNULIB_UNLINKAT]) ++ GNULIB_USLEEP=0; AC_SUBST([GNULIB_USLEEP]) ++ GNULIB_WRITE=0; AC_SUBST([GNULIB_WRITE]) + dnl Assume proper GNU behavior unless another module says otherwise. + HAVE_CHOWN=1; AC_SUBST([HAVE_CHOWN]) + HAVE_DUP2=1; AC_SUBST([HAVE_DUP2]) +@@ -102,32 +117,39 @@ AC_DEFUN([gl_UNISTD_H_DEFAULTS], + HAVE_FACCESSAT=1; AC_SUBST([HAVE_FACCESSAT]) + HAVE_FCHDIR=1; AC_SUBST([HAVE_FCHDIR]) + HAVE_FCHOWNAT=1; AC_SUBST([HAVE_FCHOWNAT]) ++ HAVE_FDATASYNC=1; AC_SUBST([HAVE_FDATASYNC]) + HAVE_FSYNC=1; AC_SUBST([HAVE_FSYNC]) + HAVE_FTRUNCATE=1; AC_SUBST([HAVE_FTRUNCATE]) +- HAVE_GETDOMAINNAME=1; AC_SUBST([HAVE_GETDOMAINNAME]) + HAVE_GETDTABLESIZE=1; AC_SUBST([HAVE_GETDTABLESIZE]) + HAVE_GETGROUPS=1; AC_SUBST([HAVE_GETGROUPS]) + HAVE_GETHOSTNAME=1; AC_SUBST([HAVE_GETHOSTNAME]) + HAVE_GETLOGIN=1; AC_SUBST([HAVE_GETLOGIN]) + HAVE_GETPAGESIZE=1; AC_SUBST([HAVE_GETPAGESIZE]) ++ HAVE_GROUP_MEMBER=1; AC_SUBST([HAVE_GROUP_MEMBER]) + HAVE_LCHOWN=1; AC_SUBST([HAVE_LCHOWN]) + HAVE_LINK=1; AC_SUBST([HAVE_LINK]) + HAVE_LINKAT=1; AC_SUBST([HAVE_LINKAT]) ++ HAVE_PIPE=1; AC_SUBST([HAVE_PIPE]) + HAVE_PIPE2=1; AC_SUBST([HAVE_PIPE2]) + HAVE_PREAD=1; AC_SUBST([HAVE_PREAD]) + HAVE_PWRITE=1; AC_SUBST([HAVE_PWRITE]) + HAVE_READLINK=1; AC_SUBST([HAVE_READLINK]) + HAVE_READLINKAT=1; AC_SUBST([HAVE_READLINKAT]) ++ HAVE_SETHOSTNAME=1; AC_SUBST([HAVE_SETHOSTNAME]) + HAVE_SLEEP=1; AC_SUBST([HAVE_SLEEP]) + HAVE_SYMLINK=1; AC_SUBST([HAVE_SYMLINK]) + HAVE_SYMLINKAT=1; AC_SUBST([HAVE_SYMLINKAT]) +- HAVE_TTYNAME_R=1; AC_SUBST([HAVE_TTYNAME_R]) + HAVE_UNLINKAT=1; AC_SUBST([HAVE_UNLINKAT]) + HAVE_USLEEP=1; AC_SUBST([HAVE_USLEEP]) + HAVE_DECL_ENVIRON=1; AC_SUBST([HAVE_DECL_ENVIRON]) ++ HAVE_DECL_FCHDIR=1; AC_SUBST([HAVE_DECL_FCHDIR]) ++ HAVE_DECL_FDATASYNC=1; AC_SUBST([HAVE_DECL_FDATASYNC]) ++ HAVE_DECL_GETDOMAINNAME=1; AC_SUBST([HAVE_DECL_GETDOMAINNAME]) + HAVE_DECL_GETLOGIN_R=1; AC_SUBST([HAVE_DECL_GETLOGIN_R]) + HAVE_DECL_GETPAGESIZE=1; AC_SUBST([HAVE_DECL_GETPAGESIZE]) + HAVE_DECL_GETUSERSHELL=1; AC_SUBST([HAVE_DECL_GETUSERSHELL]) ++ HAVE_DECL_SETHOSTNAME=1; AC_SUBST([HAVE_DECL_SETHOSTNAME]) ++ HAVE_DECL_TTYNAME_R=1; AC_SUBST([HAVE_DECL_TTYNAME_R]) + HAVE_OS_H=0; AC_SUBST([HAVE_OS_H]) + HAVE_SYS_PARAM_H=0; AC_SUBST([HAVE_SYS_PARAM_H]) + REPLACE_CHOWN=0; AC_SUBST([REPLACE_CHOWN]) +@@ -135,15 +157,20 @@ AC_DEFUN([gl_UNISTD_H_DEFAULTS], + REPLACE_DUP=0; AC_SUBST([REPLACE_DUP]) + REPLACE_DUP2=0; AC_SUBST([REPLACE_DUP2]) + REPLACE_FCHOWNAT=0; AC_SUBST([REPLACE_FCHOWNAT]) ++ REPLACE_FTRUNCATE=0; AC_SUBST([REPLACE_FTRUNCATE]) + REPLACE_GETCWD=0; AC_SUBST([REPLACE_GETCWD]) ++ REPLACE_GETDOMAINNAME=0; AC_SUBST([REPLACE_GETDOMAINNAME]) ++ REPLACE_GETLOGIN_R=0; AC_SUBST([REPLACE_GETLOGIN_R]) + REPLACE_GETGROUPS=0; AC_SUBST([REPLACE_GETGROUPS]) + REPLACE_GETPAGESIZE=0; AC_SUBST([REPLACE_GETPAGESIZE]) ++ REPLACE_ISATTY=0; AC_SUBST([REPLACE_ISATTY]) + REPLACE_LCHOWN=0; AC_SUBST([REPLACE_LCHOWN]) + REPLACE_LINK=0; AC_SUBST([REPLACE_LINK]) + REPLACE_LINKAT=0; AC_SUBST([REPLACE_LINKAT]) + REPLACE_LSEEK=0; AC_SUBST([REPLACE_LSEEK]) + REPLACE_PREAD=0; AC_SUBST([REPLACE_PREAD]) + REPLACE_PWRITE=0; AC_SUBST([REPLACE_PWRITE]) ++ REPLACE_READ=0; AC_SUBST([REPLACE_READ]) + REPLACE_READLINK=0; AC_SUBST([REPLACE_READLINK]) + REPLACE_RMDIR=0; AC_SUBST([REPLACE_RMDIR]) + REPLACE_SLEEP=0; AC_SUBST([REPLACE_SLEEP]) +diff --git a/m4/vasnprintf.m4 b/m4/vasnprintf.m4 +index ebe3c52..d730e43 100644 +--- a/m4/vasnprintf.m4 ++++ b/m4/vasnprintf.m4 +@@ -1,5 +1,5 @@ +-# vasnprintf.m4 serial 31 +-dnl Copyright (C) 2002-2004, 2006-2010 Free Software Foundation, Inc. ++# vasnprintf.m4 serial 36 ++dnl Copyright (C) 2002-2004, 2006-2013 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. +@@ -29,7 +29,7 @@ AC_DEFUN([gl_REPLACE_VASNPRINTF], + gl_PREREQ_ASNPRINTF + ]) + +-# Prequisites of lib/printf-args.h, lib/printf-args.c. ++# Prerequisites of lib/printf-args.h, lib/printf-args.c. + AC_DEFUN([gl_PREREQ_PRINTF_ARGS], + [ + AC_REQUIRE([AC_TYPE_LONG_LONG_INT]) +@@ -37,9 +37,10 @@ AC_DEFUN([gl_PREREQ_PRINTF_ARGS], + AC_REQUIRE([gt_TYPE_WINT_T]) + ]) + +-# Prequisites of lib/printf-parse.h, lib/printf-parse.c. ++# Prerequisites of lib/printf-parse.h, lib/printf-parse.c. + AC_DEFUN([gl_PREREQ_PRINTF_PARSE], + [ ++ AC_REQUIRE([gl_FEATURES_H]) + AC_REQUIRE([AC_TYPE_LONG_LONG_INT]) + AC_REQUIRE([gt_TYPE_WCHAR_T]) + AC_REQUIRE([gt_TYPE_WINT_T]) +@@ -54,7 +55,6 @@ AC_DEFUN([gl_PREREQ_PRINTF_PARSE], + # Prerequisites of lib/vasnprintf.c. + AC_DEFUN_ONCE([gl_PREREQ_VASNPRINTF], + [ +- AC_REQUIRE([AC_C_INLINE]) + AC_REQUIRE([AC_FUNC_ALLOCA]) + AC_REQUIRE([AC_TYPE_LONG_LONG_INT]) + AC_REQUIRE([gt_TYPE_WCHAR_T]) +@@ -62,7 +62,10 @@ AC_DEFUN_ONCE([gl_PREREQ_VASNPRINTF], + AC_CHECK_FUNCS([snprintf strnlen wcslen wcsnlen mbrtowc wcrtomb]) + dnl Use the _snprintf function only if it is declared (because on NetBSD it + dnl is defined as a weak alias of snprintf; we prefer to use the latter). +- AC_CHECK_DECLS([_snprintf], , , [#include ]) ++ AC_CHECK_DECLS([_snprintf], , , [[#include ]]) ++ dnl Knowing DBL_EXPBIT0_WORD and DBL_EXPBIT0_BIT enables an optimization ++ dnl in the code for NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE. ++ AC_REQUIRE([gl_DOUBLE_EXPONENT_LOCATION]) + dnl We can avoid a lot of code by assuming that snprintf's return value + dnl conforms to ISO C99. So check that. + AC_REQUIRE([gl_SNPRINTF_RETVAL_C99]) +diff --git a/m4/visibility.m4 b/m4/visibility.m4 +index 19cd8f3..6cbd7e5 100644 +--- a/m4/visibility.m4 ++++ b/m4/visibility.m4 +@@ -1,5 +1,5 @@ +-# visibility.m4 serial 4 (gettext-0.18.2) +-dnl Copyright (C) 2005, 2008, 2010 Free Software Foundation, Inc. ++# visibility.m4 serial 5 (gettext-0.18.2) ++dnl Copyright (C) 2005, 2008, 2010-2013 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. +@@ -12,7 +12,7 @@ dnl __attribute__((__visibility__("hidden"))) and + dnl __attribute__((__visibility__("default"))). + dnl Does *not* test for __visibility__("protected") - which has tricky + dnl semantics (see the 'vismain' test in glibc) and does not exist e.g. on +-dnl MacOS X. ++dnl Mac OS X. + dnl Does *not* test for __visibility__("internal") - which has processor + dnl dependent semantics. + dnl Does *not* test for #pragma GCC visibility push(hidden) - which is +diff --git a/m4/vsnprintf.m4 b/m4/vsnprintf.m4 +index ed189c2..4900764 100644 +--- a/m4/vsnprintf.m4 ++++ b/m4/vsnprintf.m4 +@@ -1,9 +1,13 @@ +-# vsnprintf.m4 serial 5 +-dnl Copyright (C) 2002-2004, 2007-2010 Free Software Foundation, Inc. ++# vsnprintf.m4 serial 6 ++dnl Copyright (C) 2002-2004, 2007-2013 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. + ++dnl Libintl 0.17 will replace vsnprintf only if it does not support %1$s, ++dnl but defers to any gnulib vsnprintf replacements. Therefore, gnulib ++dnl must guarantee that the decision for replacing vsnprintf is a superset ++dnl of the reasons checked by libintl. + AC_DEFUN([gl_FUNC_VSNPRINTF], + [ + AC_REQUIRE([gl_STDIO_H_DEFAULTS]) +@@ -13,7 +17,17 @@ AC_DEFUN([gl_FUNC_VSNPRINTF], + gl_SNPRINTF_SIZE1 + case "$gl_cv_func_snprintf_size1" in + *yes) +- gl_cv_func_vsnprintf_usable=yes ++ gl_SNPRINTF_RETVAL_C99 ++ case "$gl_cv_func_snprintf_retval_c99" in ++ *yes) ++ gl_PRINTF_POSITIONS ++ case "$gl_cv_func_printf_positions" in ++ *yes) ++ gl_cv_func_vsnprintf_usable=yes ++ ;; ++ esac ++ ;; ++ esac + ;; + esac + fi +diff --git a/m4/warn-on-use.m4 b/m4/warn-on-use.m4 +index 42daae8..e43beeb 100644 +--- a/m4/warn-on-use.m4 ++++ b/m4/warn-on-use.m4 +@@ -1,5 +1,5 @@ +-# warn-on-use.m4 serial 2 +-dnl Copyright (C) 2010 Free Software Foundation, Inc. ++# warn-on-use.m4 serial 5 ++dnl Copyright (C) 2010-2013 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. +@@ -18,8 +18,8 @@ dnl with or without modifications, as long as this notice is preserved. + # some systems declare functions in the wrong header, then INCLUDES + # should do likewise. + # +-# If you assume C89, then it is generally safe to assume declarations +-# for functions declared in that standard (such as gets) without ++# It is generally safe to assume declarations for functions declared ++# in the intersection of C89 and C11 (such as printf) without + # needing gl_WARN_ON_USE_PREPARE. + AC_DEFUN([gl_WARN_ON_USE_PREPARE], + [ +@@ -27,6 +27,8 @@ AC_DEFUN([gl_WARN_ON_USE_PREPARE], + [AH_TEMPLATE([HAVE_RAW_DECL_]AS_TR_CPP(m4_defn([gl_decl])), + [Define to 1 if ]m4_defn([gl_decl])[ is declared even after + undefining macros.])])dnl ++dnl FIXME: gl_Symbol must be used unquoted until we can assume ++dnl autoconf 2.64 or newer. + for gl_func in m4_flatten([$2]); do + AS_VAR_PUSHDEF([gl_Symbol], [gl_cv_have_raw_decl_$gl_func])dnl + AC_CACHE_CHECK([whether $gl_func is declared without a macro], +@@ -35,8 +37,8 @@ AC_DEFUN([gl_WARN_ON_USE_PREPARE], + [@%:@undef $gl_func + (void) $gl_func;])], + [AS_VAR_SET(gl_Symbol, [yes])], [AS_VAR_SET(gl_Symbol, [no])])]) +- AS_VAR_IF(gl_Symbol, [yes], +- [AC_DEFINE_UNQUOTED(AS_TR_CPP([HAVE_RAW_DECL_$gl_func]), [1]) ++ AS_VAR_IF(gl_Symbol, [yes], ++ [AC_DEFINE_UNQUOTED(AS_TR_CPP([HAVE_RAW_DECL_$gl_func]), [1]) + dnl shortcut - if the raw declaration exists, then set a cache + dnl variable to allow skipping any later AC_CHECK_DECL efforts + eval ac_cv_have_decl_$gl_func=yes]) +diff --git a/m4/wchar_h.m4 b/m4/wchar_h.m4 +index 8cae82d..bedb15a 100644 +--- a/m4/wchar_h.m4 ++++ b/m4/wchar_h.m4 +@@ -1,13 +1,13 @@ + dnl A placeholder for ISO C99 , for platforms that have issues. + +-dnl Copyright (C) 2007-2010 Free Software Foundation, Inc. ++dnl Copyright (C) 2007-2013 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. + + dnl Written by Eric Blake. + +-# wchar_h.m4 serial 33 ++# wchar_h.m4 serial 39 + + AC_DEFUN([gl_WCHAR_H], + [ +@@ -17,7 +17,6 @@ AC_DEFUN([gl_WCHAR_H], + dnl Check for (missing in Linux uClibc when built without wide + dnl character support). + dnl is always overridden, because of GNULIB_POSIXCHECK. +- AC_CHECK_HEADERS_ONCE([wchar.h]) + gl_CHECK_NEXT_HEADERS([wchar.h]) + if test $ac_cv_header_wchar_h = yes; then + HAVE_WCHAR_H=1 +@@ -26,6 +25,8 @@ AC_DEFUN([gl_WCHAR_H], + fi + AC_SUBST([HAVE_WCHAR_H]) + ++ AC_REQUIRE([gl_FEATURES_H]) ++ + AC_REQUIRE([gt_TYPE_WINT_T]) + if test $gt_cv_c_wint_t = yes; then + HAVE_WINT_T=1 +@@ -37,15 +38,23 @@ AC_DEFUN([gl_WCHAR_H], + dnl Check for declarations of anything we want to poison if the + dnl corresponding gnulib module is not in use. + gl_WARN_ON_USE_PREPARE([[ +-/* Some systems require additional headers. */ +-#ifndef __GLIBC__ ++/* Tru64 with Desktop Toolkit C has a bug: must be included before ++ . ++ BSD/OS 4.0.1 has a bug: , and must be ++ included before . */ ++#if !(defined __GLIBC__ && !defined __UCLIBC__) + # include + # include + # include + #endif + #include +- ]], [btowc wctob mbsinit mbrtowc mbrlen mbsrtowcs mbsnrtowcs wcrtomb +- wcsrtombs wcsnrtombs wcwidth]) ++ ]], ++ [btowc wctob mbsinit mbrtowc mbrlen mbsrtowcs mbsnrtowcs wcrtomb ++ wcsrtombs wcsnrtombs wcwidth wmemchr wmemcmp wmemcpy wmemmove wmemset ++ wcslen wcsnlen wcscpy wcpcpy wcsncpy wcpncpy wcscat wcsncat wcscmp ++ wcsncmp wcscasecmp wcsncasecmp wcscoll wcsxfrm wcsdup wcschr wcsrchr ++ wcscspn wcsspn wcspbrk wcsstr wcstok wcswidth ++ ]) + ]) + + dnl Check whether is usable at all. +@@ -61,6 +70,13 @@ AC_DEFUN([gl_WCHAR_H_INLINE_OK], + [gl_cv_header_wchar_h_correct_inline=yes + AC_LANG_CONFTEST([ + AC_LANG_SOURCE([[#define wcstod renamed_wcstod ++/* Tru64 with Desktop Toolkit C has a bug: must be included before ++ . ++ BSD/OS 4.0.1 has a bug: , and must be ++ included before . */ ++#include ++#include ++#include + #include + extern int zero (void); + int main () { return zero(); } +@@ -69,6 +85,13 @@ int main () { return zero(); } + mv conftest.$ac_objext conftest1.$ac_objext + AC_LANG_CONFTEST([ + AC_LANG_SOURCE([[#define wcstod renamed_wcstod ++/* Tru64 with Desktop Toolkit C has a bug: must be included before ++ . ++ BSD/OS 4.0.1 has a bug: , and must be ++ included before . */ ++#include ++#include ++#include + #include + int zero (void) { return 0; } + ]])]) +@@ -96,13 +119,6 @@ Configuration aborted.]) + fi + ]) + +-dnl Unconditionally enables the replacement of . +-AC_DEFUN([gl_REPLACE_WCHAR_H], +-[ +- dnl This is a no-op, because is always overridden. +- : +-]) +- + AC_DEFUN([gl_WCHAR_MODULE_INDICATOR], + [ + dnl Use AC_REQUIRE here, so that the default settings are expanded once only. +@@ -114,17 +130,45 @@ AC_DEFUN([gl_WCHAR_MODULE_INDICATOR], + + AC_DEFUN([gl_WCHAR_H_DEFAULTS], + [ +- GNULIB_BTOWC=0; AC_SUBST([GNULIB_BTOWC]) +- GNULIB_WCTOB=0; AC_SUBST([GNULIB_WCTOB]) +- GNULIB_MBSINIT=0; AC_SUBST([GNULIB_MBSINIT]) +- GNULIB_MBRTOWC=0; AC_SUBST([GNULIB_MBRTOWC]) +- GNULIB_MBRLEN=0; AC_SUBST([GNULIB_MBRLEN]) +- GNULIB_MBSRTOWCS=0; AC_SUBST([GNULIB_MBSRTOWCS]) +- GNULIB_MBSNRTOWCS=0; AC_SUBST([GNULIB_MBSNRTOWCS]) +- GNULIB_WCRTOMB=0; AC_SUBST([GNULIB_WCRTOMB]) +- GNULIB_WCSRTOMBS=0; AC_SUBST([GNULIB_WCSRTOMBS]) +- GNULIB_WCSNRTOMBS=0; AC_SUBST([GNULIB_WCSNRTOMBS]) +- GNULIB_WCWIDTH=0; AC_SUBST([GNULIB_WCWIDTH]) ++ GNULIB_BTOWC=0; AC_SUBST([GNULIB_BTOWC]) ++ GNULIB_WCTOB=0; AC_SUBST([GNULIB_WCTOB]) ++ GNULIB_MBSINIT=0; AC_SUBST([GNULIB_MBSINIT]) ++ GNULIB_MBRTOWC=0; AC_SUBST([GNULIB_MBRTOWC]) ++ GNULIB_MBRLEN=0; AC_SUBST([GNULIB_MBRLEN]) ++ GNULIB_MBSRTOWCS=0; AC_SUBST([GNULIB_MBSRTOWCS]) ++ GNULIB_MBSNRTOWCS=0; AC_SUBST([GNULIB_MBSNRTOWCS]) ++ GNULIB_WCRTOMB=0; AC_SUBST([GNULIB_WCRTOMB]) ++ GNULIB_WCSRTOMBS=0; AC_SUBST([GNULIB_WCSRTOMBS]) ++ GNULIB_WCSNRTOMBS=0; AC_SUBST([GNULIB_WCSNRTOMBS]) ++ GNULIB_WCWIDTH=0; AC_SUBST([GNULIB_WCWIDTH]) ++ GNULIB_WMEMCHR=0; AC_SUBST([GNULIB_WMEMCHR]) ++ GNULIB_WMEMCMP=0; AC_SUBST([GNULIB_WMEMCMP]) ++ GNULIB_WMEMCPY=0; AC_SUBST([GNULIB_WMEMCPY]) ++ GNULIB_WMEMMOVE=0; AC_SUBST([GNULIB_WMEMMOVE]) ++ GNULIB_WMEMSET=0; AC_SUBST([GNULIB_WMEMSET]) ++ GNULIB_WCSLEN=0; AC_SUBST([GNULIB_WCSLEN]) ++ GNULIB_WCSNLEN=0; AC_SUBST([GNULIB_WCSNLEN]) ++ GNULIB_WCSCPY=0; AC_SUBST([GNULIB_WCSCPY]) ++ GNULIB_WCPCPY=0; AC_SUBST([GNULIB_WCPCPY]) ++ GNULIB_WCSNCPY=0; AC_SUBST([GNULIB_WCSNCPY]) ++ GNULIB_WCPNCPY=0; AC_SUBST([GNULIB_WCPNCPY]) ++ GNULIB_WCSCAT=0; AC_SUBST([GNULIB_WCSCAT]) ++ GNULIB_WCSNCAT=0; AC_SUBST([GNULIB_WCSNCAT]) ++ GNULIB_WCSCMP=0; AC_SUBST([GNULIB_WCSCMP]) ++ GNULIB_WCSNCMP=0; AC_SUBST([GNULIB_WCSNCMP]) ++ GNULIB_WCSCASECMP=0; AC_SUBST([GNULIB_WCSCASECMP]) ++ GNULIB_WCSNCASECMP=0; AC_SUBST([GNULIB_WCSNCASECMP]) ++ GNULIB_WCSCOLL=0; AC_SUBST([GNULIB_WCSCOLL]) ++ GNULIB_WCSXFRM=0; AC_SUBST([GNULIB_WCSXFRM]) ++ GNULIB_WCSDUP=0; AC_SUBST([GNULIB_WCSDUP]) ++ GNULIB_WCSCHR=0; AC_SUBST([GNULIB_WCSCHR]) ++ GNULIB_WCSRCHR=0; AC_SUBST([GNULIB_WCSRCHR]) ++ GNULIB_WCSCSPN=0; AC_SUBST([GNULIB_WCSCSPN]) ++ GNULIB_WCSSPN=0; AC_SUBST([GNULIB_WCSSPN]) ++ GNULIB_WCSPBRK=0; AC_SUBST([GNULIB_WCSPBRK]) ++ GNULIB_WCSSTR=0; AC_SUBST([GNULIB_WCSSTR]) ++ GNULIB_WCSTOK=0; AC_SUBST([GNULIB_WCSTOK]) ++ GNULIB_WCSWIDTH=0; AC_SUBST([GNULIB_WCSWIDTH]) + dnl Assume proper GNU behavior unless another module says otherwise. + HAVE_BTOWC=1; AC_SUBST([HAVE_BTOWC]) + HAVE_MBSINIT=1; AC_SUBST([HAVE_MBSINIT]) +@@ -135,6 +179,34 @@ AC_DEFUN([gl_WCHAR_H_DEFAULTS], + HAVE_WCRTOMB=1; AC_SUBST([HAVE_WCRTOMB]) + HAVE_WCSRTOMBS=1; AC_SUBST([HAVE_WCSRTOMBS]) + HAVE_WCSNRTOMBS=1; AC_SUBST([HAVE_WCSNRTOMBS]) ++ HAVE_WMEMCHR=1; AC_SUBST([HAVE_WMEMCHR]) ++ HAVE_WMEMCMP=1; AC_SUBST([HAVE_WMEMCMP]) ++ HAVE_WMEMCPY=1; AC_SUBST([HAVE_WMEMCPY]) ++ HAVE_WMEMMOVE=1; AC_SUBST([HAVE_WMEMMOVE]) ++ HAVE_WMEMSET=1; AC_SUBST([HAVE_WMEMSET]) ++ HAVE_WCSLEN=1; AC_SUBST([HAVE_WCSLEN]) ++ HAVE_WCSNLEN=1; AC_SUBST([HAVE_WCSNLEN]) ++ HAVE_WCSCPY=1; AC_SUBST([HAVE_WCSCPY]) ++ HAVE_WCPCPY=1; AC_SUBST([HAVE_WCPCPY]) ++ HAVE_WCSNCPY=1; AC_SUBST([HAVE_WCSNCPY]) ++ HAVE_WCPNCPY=1; AC_SUBST([HAVE_WCPNCPY]) ++ HAVE_WCSCAT=1; AC_SUBST([HAVE_WCSCAT]) ++ HAVE_WCSNCAT=1; AC_SUBST([HAVE_WCSNCAT]) ++ HAVE_WCSCMP=1; AC_SUBST([HAVE_WCSCMP]) ++ HAVE_WCSNCMP=1; AC_SUBST([HAVE_WCSNCMP]) ++ HAVE_WCSCASECMP=1; AC_SUBST([HAVE_WCSCASECMP]) ++ HAVE_WCSNCASECMP=1; AC_SUBST([HAVE_WCSNCASECMP]) ++ HAVE_WCSCOLL=1; AC_SUBST([HAVE_WCSCOLL]) ++ HAVE_WCSXFRM=1; AC_SUBST([HAVE_WCSXFRM]) ++ HAVE_WCSDUP=1; AC_SUBST([HAVE_WCSDUP]) ++ HAVE_WCSCHR=1; AC_SUBST([HAVE_WCSCHR]) ++ HAVE_WCSRCHR=1; AC_SUBST([HAVE_WCSRCHR]) ++ HAVE_WCSCSPN=1; AC_SUBST([HAVE_WCSCSPN]) ++ HAVE_WCSSPN=1; AC_SUBST([HAVE_WCSSPN]) ++ HAVE_WCSPBRK=1; AC_SUBST([HAVE_WCSPBRK]) ++ HAVE_WCSSTR=1; AC_SUBST([HAVE_WCSSTR]) ++ HAVE_WCSTOK=1; AC_SUBST([HAVE_WCSTOK]) ++ HAVE_WCSWIDTH=1; AC_SUBST([HAVE_WCSWIDTH]) + HAVE_DECL_WCTOB=1; AC_SUBST([HAVE_DECL_WCTOB]) + HAVE_DECL_WCWIDTH=1; AC_SUBST([HAVE_DECL_WCWIDTH]) + REPLACE_MBSTATE_T=0; AC_SUBST([REPLACE_MBSTATE_T]) +@@ -149,4 +221,5 @@ AC_DEFUN([gl_WCHAR_H_DEFAULTS], + REPLACE_WCSRTOMBS=0; AC_SUBST([REPLACE_WCSRTOMBS]) + REPLACE_WCSNRTOMBS=0; AC_SUBST([REPLACE_WCSNRTOMBS]) + REPLACE_WCWIDTH=0; AC_SUBST([REPLACE_WCWIDTH]) ++ REPLACE_WCSWIDTH=0; AC_SUBST([REPLACE_WCSWIDTH]) + ]) +diff --git a/m4/wchar_t.m4 b/m4/wchar_t.m4 +index a133e6a..e1e1e69 100644 +--- a/m4/wchar_t.m4 ++++ b/m4/wchar_t.m4 +@@ -1,5 +1,5 @@ + # wchar_t.m4 serial 4 (gettext-0.18.2) +-dnl Copyright (C) 2002-2003, 2008-2010 Free Software Foundation, Inc. ++dnl Copyright (C) 2002-2003, 2008-2013 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. +diff --git a/m4/wcrtomb.m4 b/m4/wcrtomb.m4 +index 0de262e..f56b5ba 100644 +--- a/m4/wcrtomb.m4 ++++ b/m4/wcrtomb.m4 +@@ -1,5 +1,5 @@ +-# wcrtomb.m4 serial 6 +-dnl Copyright (C) 2008-2010 Free Software Foundation, Inc. ++# wcrtomb.m4 serial 11 ++dnl Copyright (C) 2008-2013 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. +@@ -14,6 +14,22 @@ AC_DEFUN([gl_FUNC_WCRTOMB], + AC_CHECK_FUNCS_ONCE([wcrtomb]) + if test $ac_cv_func_wcrtomb = no; then + HAVE_WCRTOMB=0 ++ AC_CHECK_DECLS([wcrtomb],,, [[ ++/* Tru64 with Desktop Toolkit C has a bug: must be included before ++ . ++ BSD/OS 4.0.1 has a bug: , and must be ++ included before . */ ++#include ++#include ++#include ++#include ++]]) ++ if test $ac_cv_have_decl_wcrtomb = yes; then ++ dnl On Minix 3.1.8, the system's declares wcrtomb() although ++ dnl it does not have the function. Avoid a collision with gnulib's ++ dnl replacement. ++ REPLACE_WCRTOMB=1 ++ fi + else + if test $REPLACE_MBSTATE_T = 1; then + REPLACE_WCRTOMB=1 +@@ -43,32 +59,39 @@ changequote([,])dnl + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ + #include +-#include + #include ++/* Tru64 with Desktop Toolkit C has a bug: must be included before ++ . ++ BSD/OS 4.0.1 has a bug: , and must be ++ included before . */ ++#include ++#include ++#include + #include + int main () + { ++ int result = 0; + if (setlocale (LC_ALL, "$LOCALE_FR") != NULL) + { + if (wcrtomb (NULL, 0, NULL) != 1) +- return 1; ++ result |= 1; + } + if (setlocale (LC_ALL, "$LOCALE_FR_UTF8") != NULL) + { + if (wcrtomb (NULL, 0, NULL) != 1) +- return 1; ++ result |= 2; + } + if (setlocale (LC_ALL, "$LOCALE_JA") != NULL) + { + if (wcrtomb (NULL, 0, NULL) != 1) +- return 1; ++ result |= 4; + } + if (setlocale (LC_ALL, "$LOCALE_ZH_CN") != NULL) + { + if (wcrtomb (NULL, 0, NULL) != 1) +- return 1; ++ result |= 8; + } +- return 0; ++ return result; + }]])], + [gl_cv_func_wcrtomb_retval=yes], + [gl_cv_func_wcrtomb_retval=no], +@@ -81,11 +104,6 @@ int main () + esac + fi + fi +- if test $HAVE_WCRTOMB = 0 || test $REPLACE_WCRTOMB = 1; then +- gl_REPLACE_WCHAR_H +- AC_LIBOBJ([wcrtomb]) +- gl_PREREQ_WCRTOMB +- fi + ]) + + # Prerequisites of lib/wcrtomb.c. +diff --git a/m4/wctype_h.m4 b/m4/wctype_h.m4 +index bc6b6e7..82ada0e 100644 +--- a/m4/wctype_h.m4 ++++ b/m4/wctype_h.m4 +@@ -1,8 +1,8 @@ +-# wctype_h.m4 serial 8 ++# wctype_h.m4 serial 18 + + dnl A placeholder for ISO C99 , for platforms that lack it. + +-dnl Copyright (C) 2006-2010 Free Software Foundation, Inc. ++dnl Copyright (C) 2006-2013 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. +@@ -11,6 +11,7 @@ dnl Written by Paul Eggert. + + AC_DEFUN([gl_WCTYPE_H], + [ ++ AC_REQUIRE([gl_WCTYPE_H_DEFAULTS]) + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_CHECK_FUNCS_ONCE([iswcntrl]) +@@ -20,24 +21,6 @@ AC_DEFUN([gl_WCTYPE_H], + HAVE_ISWCNTRL=0 + fi + AC_SUBST([HAVE_ISWCNTRL]) +- AC_CHECK_FUNCS_ONCE([iswblank]) +- AC_CHECK_DECLS_ONCE([iswblank]) +- if test $ac_cv_func_iswblank = yes; then +- HAVE_ISWBLANK=1 +- REPLACE_ISWBLANK=0 +- else +- HAVE_ISWBLANK=0 +- if test $ac_cv_have_decl_iswblank = yes; then +- REPLACE_ISWBLANK=1 +- else +- REPLACE_ISWBLANK=0 +- fi +- fi +- AC_SUBST([HAVE_ISWBLANK]) +- AC_SUBST([REPLACE_ISWBLANK]) +- +- AC_CHECK_HEADERS_ONCE([wctype.h]) +- AC_REQUIRE([AC_C_INLINE]) + + AC_REQUIRE([gt_TYPE_WINT_T]) + if test $gt_cv_c_wint_t = yes; then +@@ -47,39 +30,180 @@ AC_DEFUN([gl_WCTYPE_H], + fi + AC_SUBST([HAVE_WINT_T]) + ++ gl_CHECK_NEXT_HEADERS([wctype.h]) + if test $ac_cv_header_wctype_h = yes; then + if test $ac_cv_func_iswcntrl = yes; then + dnl Linux libc5 has an iswprint function that returns 0 for all arguments. + dnl The other functions are likely broken in the same way. + AC_CACHE_CHECK([whether iswcntrl works], [gl_cv_func_iswcntrl_works], + [ +- AC_RUN_IFELSE([AC_LANG_SOURCE([[ +- #include +- #include +- #include +- #include +- #include +- int main () { return iswprint ('x') == 0; }]])], ++ AC_RUN_IFELSE( ++ [AC_LANG_SOURCE([[ ++ /* Tru64 with Desktop Toolkit C has a bug: must be ++ included before . ++ BSD/OS 4.0.1 has a bug: , and ++ must be included before . */ ++ #include ++ #include ++ #include ++ #include ++ #include ++ int main () { return iswprint ('x') == 0; } ++ ]])], + [gl_cv_func_iswcntrl_works=yes], [gl_cv_func_iswcntrl_works=no], + [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include + #if __GNU_LIBRARY__ == 1 + Linux libc5 i18n is broken. + #endif]], [])], +- [gl_cv_func_iswcntrl_works=yes], [gl_cv_func_iswcntrl_works=no]) ++ [gl_cv_func_iswcntrl_works="guessing yes"], ++ [gl_cv_func_iswcntrl_works="guessing no"]) + ]) + ]) + fi +- gl_CHECK_NEXT_HEADERS([wctype.h]) + HAVE_WCTYPE_H=1 + else + HAVE_WCTYPE_H=0 + fi + AC_SUBST([HAVE_WCTYPE_H]) + +- if test "$gl_cv_func_iswcntrl_works" = no; then +- REPLACE_ISWCNTRL=1 ++ case "$gl_cv_func_iswcntrl_works" in ++ *yes) REPLACE_ISWCNTRL=0 ;; ++ *) REPLACE_ISWCNTRL=1 ;; ++ esac ++ AC_SUBST([REPLACE_ISWCNTRL]) ++ ++ if test $HAVE_ISWCNTRL = 0 || test $REPLACE_ISWCNTRL = 1; then ++ dnl Redefine all of iswcntrl, ..., iswxdigit in . ++ : ++ fi ++ ++ if test $REPLACE_ISWCNTRL = 1; then ++ REPLACE_TOWLOWER=1 + else +- REPLACE_ISWCNTRL=0 ++ AC_CHECK_FUNCS([towlower]) ++ if test $ac_cv_func_towlower = yes; then ++ REPLACE_TOWLOWER=0 ++ else ++ AC_CHECK_DECLS([towlower],,, ++ [[/* Tru64 with Desktop Toolkit C has a bug: must be ++ included before . ++ BSD/OS 4.0.1 has a bug: , and ++ must be included before . */ ++ #include ++ #include ++ #include ++ #include ++ #if HAVE_WCTYPE_H ++ # include ++ #endif ++ ]]) ++ if test $ac_cv_have_decl_towlower = yes; then ++ dnl On Minix 3.1.8, the system's declares towlower() and ++ dnl towupper() although it does not have the functions. Avoid a ++ dnl collision with gnulib's replacement. ++ REPLACE_TOWLOWER=1 ++ else ++ REPLACE_TOWLOWER=0 ++ fi ++ fi + fi +- AC_SUBST([REPLACE_ISWCNTRL]) ++ AC_SUBST([REPLACE_TOWLOWER]) ++ ++ if test $HAVE_ISWCNTRL = 0 || test $REPLACE_TOWLOWER = 1; then ++ dnl Redefine towlower, towupper in . ++ : ++ fi ++ ++ dnl We assume that the wctype() and iswctype() functions exist if and only ++ dnl if the type wctype_t is defined in or in if that ++ dnl exists. ++ dnl HP-UX 11.00 declares all these in and lacks . ++ AC_CACHE_CHECK([for wctype_t], [gl_cv_type_wctype_t], ++ [AC_COMPILE_IFELSE( ++ [AC_LANG_PROGRAM( ++ [[/* Tru64 with Desktop Toolkit C has a bug: must be ++ included before . ++ BSD/OS 4.0.1 has a bug: , and ++ must be included before . */ ++ #include ++ #include ++ #include ++ #include ++ #if HAVE_WCTYPE_H ++ # include ++ #endif ++ wctype_t a; ++ ]], ++ [[]])], ++ [gl_cv_type_wctype_t=yes], ++ [gl_cv_type_wctype_t=no]) ++ ]) ++ if test $gl_cv_type_wctype_t = no; then ++ HAVE_WCTYPE_T=0 ++ fi ++ ++ dnl We assume that the wctrans() and towctrans() functions exist if and only ++ dnl if the type wctrans_t is defined in . ++ AC_CACHE_CHECK([for wctrans_t], [gl_cv_type_wctrans_t], ++ [AC_COMPILE_IFELSE( ++ [AC_LANG_PROGRAM( ++ [[/* Tru64 with Desktop Toolkit C has a bug: must be ++ included before . ++ BSD/OS 4.0.1 has a bug: , and ++ must be included before . */ ++ #include ++ #include ++ #include ++ #include ++ #include ++ wctrans_t a; ++ ]], ++ [[]])], ++ [gl_cv_type_wctrans_t=yes], ++ [gl_cv_type_wctrans_t=no]) ++ ]) ++ if test $gl_cv_type_wctrans_t = no; then ++ HAVE_WCTRANS_T=0 ++ fi ++ ++ dnl Check for declarations of anything we want to poison if the ++ dnl corresponding gnulib module is not in use. ++ gl_WARN_ON_USE_PREPARE([[ ++/* Tru64 with Desktop Toolkit C has a bug: must be included before ++ . ++ BSD/OS 4.0.1 has a bug: , and must be ++ included before . */ ++#if !(defined __GLIBC__ && !defined __UCLIBC__) ++# include ++# include ++# include ++# include ++#endif ++#include ++ ]], ++ [wctype iswctype wctrans towctrans ++ ]) ++]) ++ ++AC_DEFUN([gl_WCTYPE_MODULE_INDICATOR], ++[ ++ dnl Use AC_REQUIRE here, so that the default settings are expanded once only. ++ AC_REQUIRE([gl_WCTYPE_H_DEFAULTS]) ++ gl_MODULE_INDICATOR_SET_VARIABLE([$1]) ++ dnl Define it also as a C macro, for the benefit of the unit tests. ++ gl_MODULE_INDICATOR_FOR_TESTS([$1]) ++]) ++ ++AC_DEFUN([gl_WCTYPE_H_DEFAULTS], ++[ ++ GNULIB_ISWBLANK=0; AC_SUBST([GNULIB_ISWBLANK]) ++ GNULIB_WCTYPE=0; AC_SUBST([GNULIB_WCTYPE]) ++ GNULIB_ISWCTYPE=0; AC_SUBST([GNULIB_ISWCTYPE]) ++ GNULIB_WCTRANS=0; AC_SUBST([GNULIB_WCTRANS]) ++ GNULIB_TOWCTRANS=0; AC_SUBST([GNULIB_TOWCTRANS]) ++ dnl Assume proper GNU behavior unless another module says otherwise. ++ HAVE_ISWBLANK=1; AC_SUBST([HAVE_ISWBLANK]) ++ HAVE_WCTYPE_T=1; AC_SUBST([HAVE_WCTYPE_T]) ++ HAVE_WCTRANS_T=1; AC_SUBST([HAVE_WCTRANS_T]) ++ REPLACE_ISWBLANK=0; AC_SUBST([REPLACE_ISWBLANK]) + ]) +diff --git a/m4/wcwidth.m4 b/m4/wcwidth.m4 +new file mode 100644 +index 0000000..740f81e +--- /dev/null ++++ b/m4/wcwidth.m4 +@@ -0,0 +1,101 @@ ++# wcwidth.m4 serial 23 ++dnl Copyright (C) 2006-2013 Free Software Foundation, Inc. ++dnl This file is free software; the Free Software Foundation ++dnl gives unlimited permission to copy and/or distribute it, ++dnl with or without modifications, as long as this notice is preserved. ++ ++AC_DEFUN([gl_FUNC_WCWIDTH], ++[ ++ AC_REQUIRE([gl_WCHAR_H_DEFAULTS]) ++ AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles ++ ++ dnl Persuade glibc to declare wcwidth(). ++ AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) ++ ++ AC_REQUIRE([gt_TYPE_WCHAR_T]) ++ AC_REQUIRE([gt_TYPE_WINT_T]) ++ ++ AC_CHECK_HEADERS_ONCE([wchar.h]) ++ AC_CHECK_FUNCS_ONCE([wcwidth]) ++ ++ AC_CHECK_DECLS([wcwidth], [], [], [[ ++/* AIX 3.2.5 declares wcwidth in . */ ++#include ++/* Tru64 with Desktop Toolkit C has a bug: must be included before ++ . ++ BSD/OS 4.0.1 has a bug: , and must be included ++ before . */ ++#include ++#include ++#include ++#include ++]]) ++ if test $ac_cv_have_decl_wcwidth != yes; then ++ HAVE_DECL_WCWIDTH=0 ++ fi ++ ++ if test $ac_cv_func_wcwidth = yes; then ++ HAVE_WCWIDTH=1 ++ dnl On Mac OS X 10.3, wcwidth(0x0301) (COMBINING ACUTE ACCENT) returns 1. ++ dnl On OpenBSD 5.0, wcwidth(0x05B0) (HEBREW POINT SHEVA) returns 1. ++ dnl On OSF/1 5.1, wcwidth(0x200B) (ZERO WIDTH SPACE) returns 1. ++ dnl This leads to bugs in 'ls' (coreutils). ++ AC_CACHE_CHECK([whether wcwidth works reasonably in UTF-8 locales], ++ [gl_cv_func_wcwidth_works], ++ [ ++ AC_RUN_IFELSE( ++ [AC_LANG_SOURCE([[ ++#include ++/* AIX 3.2.5 declares wcwidth in . */ ++#include ++/* Tru64 with Desktop Toolkit C has a bug: must be included before ++ . ++ BSD/OS 4.0.1 has a bug: , and must be included ++ before . */ ++#include ++#include ++#include ++#include ++#if !HAVE_DECL_WCWIDTH ++extern ++# ifdef __cplusplus ++"C" ++# endif ++int wcwidth (int); ++#endif ++int main () ++{ ++ int result = 0; ++ if (setlocale (LC_ALL, "fr_FR.UTF-8") != NULL) ++ { ++ if (wcwidth (0x0301) > 0) ++ result |= 1; ++ if (wcwidth (0x05B0) > 0) ++ result |= 2; ++ if (wcwidth (0x200B) > 0) ++ result |= 4; ++ } ++ return result; ++}]])], ++ [gl_cv_func_wcwidth_works=yes], ++ [gl_cv_func_wcwidth_works=no], ++ [ ++changequote(,)dnl ++ case "$host_os" in ++ # Guess yes on glibc and AIX 7 systems. ++ *-gnu* | aix[7-9]*) gl_cv_func_wcwidth_works="guessing yes";; ++ *) gl_cv_func_wcwidth_works="guessing no";; ++ esac ++changequote([,])dnl ++ ]) ++ ]) ++ case "$gl_cv_func_wcwidth_works" in ++ *yes) ;; ++ *no) REPLACE_WCWIDTH=1 ;; ++ esac ++ else ++ HAVE_WCWIDTH=0 ++ fi ++ dnl We don't substitute HAVE_WCWIDTH. We assume that if the system does not ++ dnl have the wcwidth function, then it does not declare it. ++]) +diff --git a/m4/wint_t.m4 b/m4/wint_t.m4 +index 58ef865..d7cd3db 100644 +--- a/m4/wint_t.m4 ++++ b/m4/wint_t.m4 +@@ -1,5 +1,5 @@ + # wint_t.m4 serial 5 (gettext-0.18.2) +-dnl Copyright (C) 2003, 2007-2010 Free Software Foundation, Inc. ++dnl Copyright (C) 2003, 2007-2013 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. +diff --git a/m4/xsize.m4 b/m4/xsize.m4 +index b653693..8ea9f2c 100644 +--- a/m4/xsize.m4 ++++ b/m4/xsize.m4 +@@ -1,5 +1,5 @@ +-# xsize.m4 serial 4 +-dnl Copyright (C) 2003-2004, 2008-2010 Free Software Foundation, Inc. ++# xsize.m4 serial 5 ++dnl Copyright (C) 2003-2004, 2008-2013 Free Software Foundation, Inc. + dnl This file is free software; the Free Software Foundation + dnl gives unlimited permission to copy and/or distribute it, + dnl with or without modifications, as long as this notice is preserved. +@@ -8,6 +8,5 @@ AC_DEFUN([gl_XSIZE], + [ + dnl Prerequisites of lib/xsize.h. + AC_REQUIRE([gl_SIZE_MAX]) +- AC_REQUIRE([AC_C_INLINE]) + AC_CHECK_HEADERS([stdint.h]) + ]) +diff --git a/po/POTFILES.in b/po/POTFILES.in +index ec79914..ac39418 100644 +--- a/po/POTFILES.in ++++ b/po/POTFILES.in +@@ -1,6 +1,3 @@ +-./build-aux/arg-nonnull.h +-./build-aux/c++defs.h +-./build-aux/warn-on-use.h + ./grub-core/boot/decompressor/minilib.c + ./grub-core/boot/decompressor/none.c + ./grub-core/boot/decompressor/xz.c +@@ -168,6 +165,7 @@ + ./grub-core/fs/ntfs.c + ./grub-core/fs/ntfscomp.c + ./grub-core/fs/odc.c ++./grub-core/fs/proc.c + ./grub-core/fs/reiserfs.c + ./grub-core/fs/romfs.c + ./grub-core/fs/sfs.c +@@ -226,9 +224,11 @@ + ./grub-core/gnulib/btowc.c + ./grub-core/gnulib/dirname.h + ./grub-core/gnulib/dirname-lgpl.c ++./grub-core/gnulib/dosname.h + ./grub-core/gnulib/errno.in.h + ./grub-core/gnulib/error.c + ./grub-core/gnulib/error.h ++./grub-core/gnulib/float.c + ./grub-core/gnulib/float+.h + ./grub-core/gnulib/float.in.h + ./grub-core/gnulib/fnmatch.c +@@ -242,16 +242,28 @@ + ./grub-core/gnulib/getopt_int.h + ./grub-core/gnulib/gettext.h + ./grub-core/gnulib/intprops.h ++./grub-core/gnulib/itold.c + ./grub-core/gnulib/langinfo.in.h + ./grub-core/gnulib/localcharset.c + ./grub-core/gnulib/localcharset.h ++./grub-core/gnulib/localeconv.c ++./grub-core/gnulib/locale.in.h + ./grub-core/gnulib/malloc.c + ./grub-core/gnulib/mbrtowc.c + ./grub-core/gnulib/mbsinit.c + ./grub-core/gnulib/mbsrtowcs.c ++./grub-core/gnulib/mbsrtowcs-impl.h + ./grub-core/gnulib/mbsrtowcs-state.c ++./grub-core/gnulib/mbswidth.c ++./grub-core/gnulib/mbswidth.h ++./grub-core/gnulib/mbtowc.c ++./grub-core/gnulib/mbtowc-impl.h + ./grub-core/gnulib/memchr.c + ./grub-core/gnulib/mempcpy.c ++./grub-core/gnulib/msvc-inval.c ++./grub-core/gnulib/msvc-inval.h ++./grub-core/gnulib/msvc-nothrow.c ++./grub-core/gnulib/msvc-nothrow.h + ./grub-core/gnulib/nl_langinfo.c + ./grub-core/gnulib/printf-args.c + ./grub-core/gnulib/printf-args.h +@@ -269,16 +281,18 @@ + ./grub-core/gnulib/regex_internal.h + ./grub-core/gnulib/size_max.h + ./grub-core/gnulib/sleep.c ++./grub-core/gnulib/stdalign.in.h + ./grub-core/gnulib/stdbool.in.h + ./grub-core/gnulib/stddef.in.h + ./grub-core/gnulib/stdint.in.h + ./grub-core/gnulib/stdio.in.h +-./grub-core/gnulib/stdio-write.c + ./grub-core/gnulib/stdlib.in.h + ./grub-core/gnulib/strcasecmp.c + ./grub-core/gnulib/strchrnul.c + ./grub-core/gnulib/streq.h + ./grub-core/gnulib/strerror.c ++./grub-core/gnulib/strerror-override.c ++./grub-core/gnulib/strerror-override.h + ./grub-core/gnulib/string.in.h + ./grub-core/gnulib/strings.in.h + ./grub-core/gnulib/stripslash.c +@@ -288,15 +302,23 @@ + ./grub-core/gnulib/strnlen1.h + ./grub-core/gnulib/strnlen.c + ./grub-core/gnulib/sysexits.in.h +-./grub-core/gnulib/sys_wait.in.h ++./grub-core/gnulib/sys_types.in.h ++./grub-core/gnulib/unistd.c + ./grub-core/gnulib/unistd.in.h ++./grub-core/gnulib/unitypes.in.h ++./grub-core/gnulib/uniwidth/cjk.h ++./grub-core/gnulib/uniwidth.in.h ++./grub-core/gnulib/uniwidth/width.c + ./grub-core/gnulib/vasnprintf.c + ./grub-core/gnulib/vasnprintf.h + ./grub-core/gnulib/verify.h + ./grub-core/gnulib/vsnprintf.c + ./grub-core/gnulib/wchar.in.h + ./grub-core/gnulib/wcrtomb.c ++./grub-core/gnulib/wctype-h.c + ./grub-core/gnulib/wctype.in.h ++./grub-core/gnulib/wcwidth.c ++./grub-core/gnulib/xsize.c + ./grub-core/gnulib/xsize.h + ./grub-core/hello/hello.c + ./grub-core/hook/datehook.c +@@ -553,6 +575,7 @@ + ./grub-core/loader/i386/pc/pxechainloader.c + ./grub-core/loader/i386/xnu.c + ./grub-core/loader/ia64/efi/linux.c ++./grub-core/loader/linux.c + ./grub-core/loader/lzss.c + ./grub-core/loader/macho32.c + ./grub-core/loader/macho64.c +@@ -646,6 +669,7 @@ + ./grub-core/tests/lib/functional_test.c + ./grub-core/tests/lib/test.c + ./grub-core/tests/test_blockarg.c ++./grub-core/unidata.c + ./grub-core/video/bitmap.c + ./grub-core/video/bitmap_scale.c + ./grub-core/video/bochs.c +@@ -732,6 +756,8 @@ + ./include/grub/font.h + ./include/grub/fs.h + ./include/grub/fshelp.h ++./include/grub/gcrypt/g10lib.h ++./include/grub/gcrypt/gcrypt.h + ./include/grub/gcrypt/gpg-error.h + ./include/grub/gcry/types.h + ./include/grub/gdb.h +@@ -811,6 +837,7 @@ + ./include/grub/ia64/efi/memory.h + ./include/grub/ia64/efi/time.h + ./include/grub/ia64/kernel.h ++./include/grub/ia64/reloc.h + ./include/grub/ia64/setjmp.h + ./include/grub/ia64/time.h + ./include/grub/ia64/types.h +@@ -834,6 +861,7 @@ + ./include/grub/lib/LzmaTypes.h + ./include/grub/libpciaccess.h + ./include/grub/libusb.h ++./include/grub/linux.h + ./include/grub/list.h + ./include/grub/loader.h + ./include/grub/lvm.h +@@ -905,6 +933,7 @@ + ./include/grub/powerpc/time.h + ./include/grub/powerpc/types.h + ./include/grub/priority_queue.h ++./include/grub/procfs.h + ./include/grub/pubkey.h + ./include/grub/reader.h + ./include/grub/reed_solomon.h +-- +1.8.1.4 + diff --git a/0280-docs-grub.texi-Fix-description-of-GRUB_CMDLINE_XEN-a.patch b/0280-docs-grub.texi-Fix-description-of-GRUB_CMDLINE_XEN-a.patch new file mode 100644 index 0000000..5532e32 --- /dev/null +++ b/0280-docs-grub.texi-Fix-description-of-GRUB_CMDLINE_XEN-a.patch @@ -0,0 +1,47 @@ +From 5e6e83436dcaf78f4be5fad2d27c0a5df8fa57e0 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Thu, 11 Apr 2013 21:46:21 +0200 +Subject: [PATCH 280/364] * docs/grub.texi: Fix description of + GRUB_CMDLINE_XEN and GRUB_CMDLINE_XEN_DEFAULT. Reported by: Marc + Warne (GigaTux) + +--- + ChangeLog | 6 ++++++ + docs/grub.texi | 5 ++--- + 2 files changed, 8 insertions(+), 3 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 90aacbe..70f0074 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,11 @@ + 2013-04-11 Vladimir Serbinenko + ++ * docs/grub.texi: Fix description of GRUB_CMDLINE_XEN and ++ GRUB_CMDLINE_XEN_DEFAULT. ++ Reported by: Marc Warne (GigaTux) ++ ++2013-04-11 Vladimir Serbinenko ++ + Import new gnulib. + + 2013-04-11 Vladimir Serbinenko +diff --git a/docs/grub.texi b/docs/grub.texi +index bd366a6..f6f9506 100644 +--- a/docs/grub.texi ++++ b/docs/grub.texi +@@ -1290,9 +1290,8 @@ As @samp{GRUB_CMDLINE_LINUX}, but for GNU Mach. + + @item GRUB_CMDLINE_XEN + @itemx GRUB_CMDLINE_XEN_DEFAULT +-The values of these options are appended to the values of +-@samp{GRUB_CMDLINE_LINUX} and @samp{GRUB_CMDLINE_LINUX_DEFAULT} for Linux +-and Xen menu entries. ++The values of these options are passed to Xen hypervisor Xen menu entries, ++for all respectively normal entries. + + @item GRUB_CMDLINE_LINUX_XEN_REPLACE + @item GRUB_CMDLINE_LINUX_XEN_REPLACE_DEFAULT +-- +1.8.1.4 + diff --git a/0281-Merge-powerpc-grub-mkrescue-flavour-with-common.-Use.patch b/0281-Merge-powerpc-grub-mkrescue-flavour-with-common.-Use.patch new file mode 100644 index 0000000..0c7f644 --- /dev/null +++ b/0281-Merge-powerpc-grub-mkrescue-flavour-with-common.-Use.patch @@ -0,0 +1,1100 @@ +From 7ef3eb66fabfe125a79f6a88a25730a7a0bb9c05 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Thu, 11 Apr 2013 23:15:26 +0200 +Subject: [PATCH 281/364] Merge powerpc grub-mkrescue flavour with + common. Use xorriso HFS+ feature for it. + +--- + ChangeLog | 5 + + Makefile.util.def | 38 +++- + configure.ac | 1 + + docs/man/grub-render-label.h2m | 3 + + grub-core/Makefile.core.def | 6 + + grub-core/boot/powerpc/grub.chrp.in | 172 +++++++++++++++ + grub-core/font/font.c | 6 +- + grub-core/font/font_cmd.c | 2 +- + grub-core/video/video.c | 8 + + include/grub/font.h | 2 +- + include/grub/video.h | 5 + + util/grub-mkrescue.in | 80 +++++++ + util/grub-render-label.c | 393 +++++++++++++++++++++++++++++++++ + util/powerpc/ieee1275/grub-mkrescue.in | 146 ------------ + 14 files changed, 707 insertions(+), 160 deletions(-) + create mode 100644 docs/man/grub-render-label.h2m + create mode 100644 grub-core/boot/powerpc/grub.chrp.in + create mode 100644 util/grub-render-label.c + delete mode 100644 util/powerpc/ieee1275/grub-mkrescue.in + +diff --git a/ChangeLog b/ChangeLog +index 70f0074..0d62509 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,10 @@ + 2013-04-11 Vladimir Serbinenko + ++ Merge powerpc grub-mkrescue flavour with common. Use xorriso HFS+ ++ feature for it. ++ ++2013-04-11 Vladimir Serbinenko ++ + * docs/grub.texi: Fix description of GRUB_CMDLINE_XEN and + GRUB_CMDLINE_XEN_DEFAULT. + Reported by: Marc Warne (GigaTux) +diff --git a/Makefile.util.def b/Makefile.util.def +index 513dc38..bd286fc 100644 +--- a/Makefile.util.def ++++ b/Makefile.util.def +@@ -59,6 +59,17 @@ library = { + common = grub-core/disk/mdraid1x_linux.c; + common = grub-core/disk/raid5_recover.c; + common = grub-core/disk/raid6_recover.c; ++ common = grub-core/font/font.c; ++ common = grub-core/gfxmenu/font.c; ++ common = grub-core/normal/charset.c; ++ common = grub-core/video/fb/fbblit.c; ++ common = grub-core/video/fb/fbutil.c; ++ common = grub-core/video/fb/fbfill.c; ++ common = grub-core/video/fb/video_fb.c; ++ common = grub-core/video/video.c; ++ common = grub-core/video/colors.c; ++ common = grub-core/unidata.c; ++ common = grub-core/io/bufio.c; + common = grub-core/fs/affs.c; + common = grub-core/fs/afs.c; + common = grub-core/fs/bfs.c; +@@ -451,15 +462,8 @@ script = { + script = { + mansection = 1; + name = grub-mkrescue; +- x86 = util/grub-install_header; +- x86 = util/grub-mkrescue.in; +- mips_qemu_mips = util/grub-install_header; +- mips_qemu_mips = util/grub-mkrescue.in; +- mips_loongson = util/grub-install_header; +- mips_loongson = util/grub-mkrescue.in; +- ia64_efi = util/grub-install_header; +- ia64_efi = util/grub-mkrescue.in; +- powerpc_ieee1275 = util/powerpc/ieee1275/grub-mkrescue.in; ++ common = util/grub-install_header; ++ common = util/grub-mkrescue.in; + enable = i386_pc; + enable = i386_efi; + enable = x86_64_efi; +@@ -763,3 +767,19 @@ program = { + ldadd = grub-core/gnulib/libgnu.a; + ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; + }; ++ ++program = { ++ name = grub-render-label; ++ mansection = 1; ++ ++ common = util/grub-render-label.c; ++ common = grub-core/kern/emu/argp_common.c; ++ common = grub-core/kern/emu/hostfs.c; ++ common = grub-core/disk/host.c; ++ ++ ldadd = libgrubmods.a; ++ ldadd = libgrubgcry.a; ++ ldadd = libgrubkern.a; ++ ldadd = grub-core/gnulib/libgnu.a; ++ ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; ++}; +diff --git a/configure.ac b/configure.ac +index a39a025..19febfd 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -65,6 +65,7 @@ grub_TRANSFORM([grub-reboot]) + grub_TRANSFORM([grub-script-check]) + grub_TRANSFORM([grub-set-default]) + grub_TRANSFORM([grub-sparc64-setup]) ++grub_TRANSFORM([grub-render-label]) + + # Optimization flag. Allow user to override. + if test "x$TARGET_CFLAGS" = x; then +diff --git a/docs/man/grub-render-label.h2m b/docs/man/grub-render-label.h2m +new file mode 100644 +index 0000000..50ae524 +--- /dev/null ++++ b/docs/man/grub-render-label.h2m +@@ -0,0 +1,3 @@ ++[NAME] ++grub-render-label \- generate a .disk_label for Apple Macs. ++ +diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def +index 4c8e947..6aead4c 100644 +--- a/grub-core/Makefile.core.def ++++ b/grub-core/Makefile.core.def +@@ -30,6 +30,12 @@ script = { + common = gdb_grub.in; + }; + ++script = { ++ installdir = platform; ++ name = grub.chrp; ++ common = boot/powerpc/grub.chrp.in; ++}; ++ + kernel = { + name = kernel; + +diff --git a/grub-core/boot/powerpc/grub.chrp.in b/grub-core/boot/powerpc/grub.chrp.in +new file mode 100644 +index 0000000..9b22183 +--- /dev/null ++++ b/grub-core/boot/powerpc/grub.chrp.in +@@ -0,0 +1,172 @@ ++ ++ ++MacRISC MacRISC3 MacRISC4 ++ ++ ++@PACKAGE@ @VERSION@ ++ ++ ++3434 ++00000000000000F781FB8181818181FBFAF500000000000000000000000000000000000000F6FAFAFAFA81F9F600000000000000 ++0000000000F8FBF9F500F95656FCFB5656FBF800000000000000000000000000000000F5FAF9F5F7F600F6F6F9FAF70000000000 ++000000F5FBFA0056FDFEFEFDFDFAAC81FB56568181560000000000000000000000F9F9F9F7FCFDFEFEFEFFFC81F656FA00000000 ++0000F5AC2BF7FBFEFEFD2BF6568181F9F7F6F6F8FBF50000000000000000000000FAF700F600F5F7F7F6F7FEFFACF82BFB000000 ++0000FC2BF5FEFFFFF5F7FC81F70000F7F9FAFAF8000000000000000000000000000056F9F9FAF9F7F7FA812BF7FFFF56F7FA0000 ++005656F5FEFFAC2BF9FA000000000000000000000000000000000000000000000000000000000000000000FA56FAFEFEF8F9F700 ++00FB00F7FFFF56F9F800000000000000000000F656FAFA56F50000000000F5F8F9F8F5000000000000000000F9F7FCFFFB00FB00 ++F8F800ACFFACF6FA000000000000000000F6FA562BF5F5F781FA000000F9FA2B00F556F9F5000000000000000081F8FFFEF6562B ++810000FFFFF9FAF500000000000000002B8100F5F9FCACFBF82BFBF6FCFAF6FAFC81F600FA2B000000000000002BF8FEFFF8F5FA ++FA00F5FEFFFA8100000000000000002B8100F9FEFFFFFFFFFFFBF6FDFEACFDFEFFFFFFFBF581F600000000000000F9FEFFF700FA ++FA00FBFFFEF6F900000000000000F6FB00FCFFFFFFFFFFFFFFFFFCF600FCF7ACFEFFFFFFFDF6810000000000000056F9FFAC00FA ++FA00F6FFFFF856000000000000F5FBF5ACFFFFFFFFFFFFFFFFFFFF2B002BF8F5ACFFFFFFFFFDF6FA000000000000F9FCFF560081 ++FA0081FFFFF8F9000000000000FBF6FBFFFFFFFFFFFFFFFFFFFFFFF800F55600FCFFFFFFFFFF81F8F80000000000F981FFAC0081 ++FA0000FEFEF8FB0000000000812BFAFFFFFFFFFFFFFEFFFFFDF92BFA0000F6F981ACFEFFFFFFFF56F9F600000000F9FDFF2B0081 ++FA00FAFFFF81812B000000FAF8F9FFFFFEACFBF80000F500000000F9F900562B0000FCF7F9ACFFFF2BF9F50000F9F6FEFFFB0081 ++810000FCFFFBF6FB56F7FBF8F9FFFE5600000000F5FAAC000000F82BF6FAFBF800F556F80000F9FFFE2BFAFAFAF8FAFFFEF60081 ++FAF6F5ACFFFFAC00F856F7ACFFFCF500000000FAFCFFFC00000056AC00F581F92BFEF9FAF6000081FFFFFBF6F62BFFFFACF6F6FA ++F6FA00FAFFFFFFACFA56FFFFAC0000000000F6FD2BFEF6F5565600F5F800F60081FEF7F656000000FDFFFFFDFDFFFFFFAC0081F5 ++0081F52BFDFFFFFFFFFFFFFFF60000000000FBF6F6F5F656F52BF900FA000000FCFAF5F656000000F7FFFFFFFFFFFFFDF7F68100 ++00F6FB00F8FDFFFFFFFFFF810000000000F6F5000000F52B56F9FC00F7F70000FCF881FCF500000000FEFFFFFFFFAC5600FBF500 ++000056F900F8ACFDFFFFFFF5000000000000002B0000FDFEFFFE560000F60000F9ACFFFE810000000081FFFEFDFAF800FAF70000 ++000000FAF9002B56FAFDFC0000000000000000F80000FBF5FEFEF5000000000000ACFFFA2B0000000000FEFB2BF5008156000000 ++00000000F9FBF600F6FBF800000000000000F7F8000000F9F9F9F82B0000000000F6ACACF70000000000F7FD2BFA812B00000000 ++0000000000F681FCFBFD0000000000000000FBF6000000000000F52B000000000000F92B810000000000008181F6000000000000 ++0000000000000000F6FC00000000000000F6FF0000000000000000000000000000000081FBFB2B00000000F7F900000000000000 ++000000000000000000FC00000000000000FCFAF600000000000000000000000000000056ACF581FBF700000081FB000000000000 ++0000000000000000FAF90000000000008156F5F8000000000000002BFBFCFBF800000000FD2B000056FB8181FBF8000000000000 ++0000000000000000AC0000000000F5FBF90000F6000000000000F5AC56F6005681F50000F6ACFCFBF70000000000000000000000 ++00000000000000F881000000F5FAFDFD00000000000000000000F7FEFA2B0000F581F70000000000810000000000000000000000 ++000000000000F9FCF500FAFDACFAF5FD00000000000000000000F5ACF5FDFEFA0000F82B00000000810000000000000000000000 ++000000000000FCF8F9AC81FD000000FD000000000000FAF7000000F50081F9FAF800000000000000FB0000000000000000000000 ++000000000000FC81F956F5FD000000FD0000000000000000F800F5000000000056000000000000F7FB0000000000000000000000 ++00000000000000000000F5AC000000ACF800000000000000F5FAF80000000000F50000000000F8ACF50000000000000000000000 ++00000000000000000000F5AC000000F5AC000000000000000056F9000000000000000000F7ACFCF5000000000000000000000000 ++00000000000000000000F5FD00000000AC000000000000000000FB0000000000000000F5F6F5FCF6000000000000000000000000 ++0000000000000000000000FD00000000FBFDF600000000000000F8F900000000000000000000F5FB000000000000000000000000 ++0000000000000000000000FDF500000000F9ACF800000000000000815600000000F656818181AC56000000000000000000000000 ++000000000000000000000081F80000000000F9FC0000000000000000F9ACACACFCFBFAFA81FD2B00000000000000000000000000 ++0000000000000000000000F7FB0000000000FBF70000000000000000000000000000000000FB0000000000000000000000000000 ++000000000000000000000000ACF500000000F9FD56F5000000000000000000000000000000FB0000000000000000000000000000 ++000000000000000000000000F8FA0000000000F6FEFEF5000000000000F55681FCACFDACFC560000000000000000000000000000 ++00000000000000000000000000FBF600000000002BFCFA00F700000000F9FDFDFAFEF90000000000000000000000000000000000 ++00000000000000000000000000F5FB0000000000F5FEF7ACAC0000000000000000FCF50000000000000000000000000000000000 ++0000000000000000000000000000F6FA000000002BFF2BFFFFAC00000000000000F7FA0000000000000000000000000000000000 ++000000000000000000000000000000F65600000000FAFEFFFFAC0000000000F800F6810000000000000000000000000000000000 ++00000000000000000000000000000000F52B00000000F8FEFBFF5600000000FCFAACF60000000000000000000000000000000000 ++0000000000000000000000000000000000000000000000F9FCFCFFFB00F8FEFFFDF5000000000000000000000000000000000000 ++00000000000000000000000000000000000000000000F9FDF7F5FFFD56FFFFFFFD00000000000000000000000000000000000000 ++00000000000000000000000000000000000000000000810000FBFFFFFBFFFFFFFFACF9F5F5000000000000000000000000000000 ++0000000000000000000000000000000000000000000000F600FC81FFFEFFFFFFFFFFFE8100000000000000000000000000000000 ++00000000000000000000000000000000000000000000000000F7F6FDFFFFFFFEFFFFACF500000000000000000000000000000000 ++000000000000000000000000000000000000000000000000000000F5FC81FC81FAFBF9F500000000000000000000000000000000 ++ ++00000000000000F781FB8181818181FBFAF500000000000000000000000000000000000000F6FAFAFAFA81F9F600000000000000 ++0000000000F8FBF9F500F95656FCFB5656FBF800000000000000000000000000000000F5FAF9F5F7F600F6F6F9FAF70000000000 ++000000F5FBFA0056FDFEFEFDFDFAAC81FB56568181560000000000000000000000F9F9F9F7FCFDFEFEFEFFFC81F656FA00000000 ++0000F5AC2BF7FBFEFEFD2BF6568181F9F7F6F6F8FBF50000000000000000000000FAF700F600F5F7F7F6F7FEFFACF82BFB000000 ++0000FC2BF5FEFFFFF5F7FC81F70000F7F9FAFAF8000000000000000000000000000056F9F9FAF9F7F7FA812BF7FFFF56F7FA0000 ++005656F5FEFFAC2BF9FA000000000000000000000000000000000000000000000000000000000000000000FA56FAFEFEF8F9F700 ++00FB00F7FFFF56F9F800000000000000000000F656FAFA56F50000000000F5F8F9F8F5000000000000000000F9F7FCFFFB00FB00 ++F8F800ACFFACF6FA000000000000000000F6FA562BF5F5F781FA000000F9FA2B00F556F9F5000000000000000081F8FFFEF6562B ++810000FFFFF9FAF500000000000000002B8100F5F9FCACFBF82BFBF6FCFAF6FAFC81F600FA2B000000000000002BF8FEFFF8F5FA ++FA00F5FEFFFA8100000000000000002B8100F9FEFFFFFFFFFFFBF6FDFEACFDFEFFFFFFFBF581F600000000000000F9FEFFF700FA ++FA00FBFFFEF6F900000000000000F6FB00FCFFFFFFFFFFFFFFFFFCF600FCF7ACFEFFFFFFFDF6810000000000000056F9FFAC00FA ++FA00F6FFFFF856000000000000F5FBF5ACFFFFFFFFFFFFFFFFFFFF2B002BF8F5ACFFFFFFFFFDF6FA000000000000F9FCFF560081 ++FA0081FFFFF8F9000000000000FBF6FBFFFFFFFFFFFFFFFFFFFFFFF800F55600FCFFFFFFFFFF81F8F80000000000F981FFAC0081 ++FA0000FEFEF8FB0000000000812BFAFFFFFFFFFFFFFEFFFFFDF92BFA0000F6F981ACFEFFFFFFFF56F9F600000000F9FDFF2B0081 ++FA00FAFFFF81812B000000FAF8F9FFFFFEACFBF80000F500000000F9F900562B0000FCF7F9ACFFFF2BF9F50000F9F6FEFFFB0081 ++810000FCFFFBF6FB56F7FBF8F9FFFE5600000000F5FAAC000000F82BF6FAFBF800F556F80000F9FFFE2BFAFAFAF8FAFFFEF60081 ++FAF6F5ACFFFFAC00F856F7ACFFFCF500000000FAFCFFFC00000056AC00F581F92BFEF9FAF6000081FFFFFBF6F62BFFFFACF6F6FA ++F6FA00FAFFFFFFACFA56FFFFAC0000000000F6FD2BFEF6F5565600F5F800F60081FEF7F656000000FDFFFFFDFDFFFFFFAC0081F5 ++0081F52BFDFFFFFFFFFFFFFFF60000000000FBF6F6F5F656F52BF900FA000000FCFAF5F656000000F7FFFFFFFFFFFFFDF7F68100 ++00F6FB00F8FDFFFFFFFFFF810000000000F6F5000000F52B56F9FC00F7F70000FCF881FCF500000000FEFFFFFFFFAC5600FBF500 ++000056F900F8ACFDFFFFFFF5000000000000002B0000FDFEFFFE560000F60000F9ACFFFE810000000081FFFEFDFAF800FAF70000 ++000000FAF9002B56FAFDFC0000000000000000F80000FBF5FEFEF5000000000000ACFFFA2B0000000000FEFB2BF5008156000000 ++00000000F9FBF600F6FBF800000000000000F7F8000000F9F9F9F82B0000000000F6ACACF70000000000F7FD2BFA812B00000000 ++0000000000F681FCFBFD0000000000000000FBF6000000000000F52B000000000000F92B810000000000008181F6000000000000 ++0000000000000000F6FC00000000000000F6FF0000000000000000000000000000000081FBFB2B00000000F7F900000000000000 ++000000000000000000FC00000000000000FCFAF600000000000000000000000000000056ACF581FBF700000081FB000000000000 ++0000000000000000FAF90000000000008156F5F8000000000000002BFBFCFBF800000000FD2B000056FB8181FBF8000000000000 ++0000000000000000AC0000000000F5FBF90000F6000000000000F5AC56F6005681F50000F6ACFCFBF70000000000000000000000 ++00000000000000F881000000F5FAFDFD00000000000000000000F7FEFA2B0000F581F70000000000810000000000000000000000 ++000000000000F9FCF500FAFDACFAF5FD00000000000000000000F5ACF5FDFEFA0000F82B00000000810000000000000000000000 ++000000000000FCF8F9AC81FD000000FD000000000000FAF7000000F50081F9FAF800000000000000FB0000000000000000000000 ++000000000000FC81F956F5FD000000FD0000000000000000F800F5000000000056000000000000F7FB0000000000000000000000 ++00000000000000000000F5AC000000ACF800000000000000F5FAF80000000000F50000000000F8ACF50000000000000000000000 ++00000000000000000000F5AC000000F5AC000000000000000056F9000000000000000000F7ACFCF5000000000000000000000000 ++00000000000000000000F5FD00000000AC000000000000000000FB0000000000000000F5F6F5FCF6000000000000000000000000 ++0000000000000000000000FD00000000FBFDF600000000000000F8F900000000000000000000F5FB000000000000000000000000 ++0000000000000000000000FDF500000000F9ACF800000000000000815600000000F656818181AC56000000000000000000000000 ++000000000000000000000081F80000000000F9FC0000000000000000F9ACACACFCFBFAFA81FD2B00000000000000000000000000 ++0000000000000000000000F7FB0000000000FBF70000000000000000000000000000000000FB0000000000000000000000000000 ++000000000000000000000000ACF500000000F9FD56F5000000000000000000000000000000FB0000000000000000000000000000 ++000000000000000000000000F8FA0000000000F6FEFEF5000000000000F55681FCACFDACFC560000000000000000000000000000 ++00000000000000000000000000FBF600000000002BFCFA00F700000000F9FDFDFAFEF90000000000000000000000000000000000 ++00000000000000000000000000F5FB0000000000F5FEF7ACAC0000000000000000FCF50000000000000000000000000000000000 ++0000000000000000000000000000F6FA000000002BFF2BFFFFAC00000000000000F7FA0000000000000000000000000000000000 ++000000000000000000000000000000F65600000000FAFEFFFFAC0000000000F800F6810000000000000000000000000000000000 ++00000000000000000000000000000000F52B00000000F8FEFBFF5600000000FCFAACF60000000000000000000000000000000000 ++0000000000000000000000000000000000000000000000F9FCFCFFFB00F8FEFFFDF5000000000000000000000000000000000000 ++00000000000000000000000000000000000000000000F9FDF7F5FFFD56FFFFFFFD00000000000000000000000000000000000000 ++00000000000000000000000000000000000000000000810000FBFFFFFBFFFFFFFFACF9F5F5000000000000000000000000000000 ++0000000000000000000000000000000000000000000000F600FC81FFFEFFFFFFFFFFFE8100000000000000000000000000000000 ++00000000000000000000000000000000000000000000000000F7F6FDFFFFFFFEFFFFACF500000000000000000000000000000000 ++000000000000000000000000000000000000000000000000000000F5FC81FC81FAFBF9F500000000000000000000000000000000 ++ ++FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ++FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ++FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ++FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ++FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ++FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ++FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ++FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ++FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ++FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ++FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ++FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ++FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ++FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ++FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ++FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ++FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ++FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ++FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ++FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ++FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ++FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ++FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ++FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ++FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ++FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ++FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ++FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ++FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ++FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ++FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ++FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ++FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ++FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ++FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ++FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ++FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ++FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ++FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ++FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ++FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ++FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ++FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ++FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ++FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ++FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ++FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ++FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ++FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ++FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ++FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ++FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ++ ++ ++boot &device;:&partition;,\System\Library\CoreServices\grub.elf ++ ++ +diff --git a/grub-core/font/font.c b/grub-core/font/font.c +index 6b54a84..fbbb988 100644 +--- a/grub-core/font/font.c ++++ b/grub-core/font/font.c +@@ -422,7 +422,7 @@ read_section_as_short (struct font_file_section *section, + + /* Load a font and add it to the beginning of the global font list. + Returns 0 upon success, nonzero upon failure. */ +-int ++grub_font_t + grub_font_load (const char *filename) + { + grub_file_t file = 0; +@@ -657,7 +657,7 @@ grub_font_load (const char *filename) + if (register_font (font) != 0) + goto fail; + +- return 0; ++ return font; + + fail: + if (file) +@@ -666,7 +666,7 @@ fail: + font->file = 0; + + free_font (font); +- return 1; ++ return 0; + } + + /* Read a 16-bit big-endian integer from FILE, convert it to native byte +diff --git a/grub-core/font/font_cmd.c b/grub-core/font/font_cmd.c +index 90f605d..1d9ddea 100644 +--- a/grub-core/font/font_cmd.c ++++ b/grub-core/font/font_cmd.c +@@ -32,7 +32,7 @@ loadfont_command (grub_command_t cmd __attribute__ ((unused)), + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); + + while (argc--) +- if (grub_font_load (*args++) != 0) ++ if (grub_font_load (*args++) == 0) + { + if (!grub_errno) + return grub_error (GRUB_ERR_BAD_FONT, "invalid font"); +diff --git a/grub-core/video/video.c b/grub-core/video/video.c +index c36994f..aab9b18 100644 +--- a/grub-core/video/video.c ++++ b/grub-core/video/video.c +@@ -711,3 +711,11 @@ grub_video_set_mode (const char *modestring, + return grub_error (GRUB_ERR_BAD_ARGUMENT, + N_("no suitable video mode found")); + } ++ ++#ifdef GRUB_UTIL ++void ++grub_video_set_adapter (grub_video_adapter_t adapter) ++{ ++ grub_video_adapter_active = adapter; ++} ++#endif +diff --git a/include/grub/font.h b/include/grub/font.h +index 690363f..975432e 100644 +--- a/include/grub/font.h ++++ b/include/grub/font.h +@@ -81,7 +81,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); ++grub_font_t 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. +diff --git a/include/grub/video.h b/include/grub/video.h +index 9fe4783..40a7711 100644 +--- a/include/grub/video.h ++++ b/include/grub/video.h +@@ -542,4 +542,9 @@ extern void grub_video_sis315pro_fini (void); + extern void grub_video_radeon_fuloong2e_fini (void); + #endif + ++#ifdef GRUB_UTIL ++void ++grub_video_set_adapter (grub_video_adapter_t adapter); ++#endif ++ + #endif /* ! GRUB_VIDEO_HEADER */ +diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in +index c57a0d9..a6e4de6 100644 +--- a/util/grub-mkrescue.in ++++ b/util/grub-mkrescue.in +@@ -43,9 +43,16 @@ pc_dir="${libdir}/@PACKAGE@/i386-pc" + efi32_dir="${libdir}/@PACKAGE@/i386-efi" + efi64_dir="${libdir}/@PACKAGE@/x86_64-efi" + ia64_dir="${libdir}/@PACKAGE@/ia64-efi" ++ppc_dir="${libdir}/@PACKAGE@/powerpc-ieee1275" + rom_directory= + override_dir= + grub_mkimage="${bindir}/@grub_mkimage@" ++grub_render_label="${bindir}/@grub_render_label@" ++label_font="${pkgdatadir}/unicode.pf2" ++label_color="black" ++label_bgcolor="white" ++product_name="${PACKAGE_NAME}" ++product_version="${PACKAGE_VERSION}" + + xorriso=xorriso + +@@ -74,6 +81,12 @@ usage () { + # TRANSLATORS: xorriso is a program for creating ISOs and burning CDs + print_option_help "--xorriso=$filetrans" "$(gettext "use FILE as xorriso [optional]")" + print_option_help "--grub-mkimage=$filetrans" "$(gettext "use FILE as grub-mkimage")" ++ print_option_help "--grub-render-label=$filetrans" "$(gettext "use FILE as grub-render-label")" ++ print_option_help "--label-font=$filetrans" "$(gettext "use FILE as font for label")" ++ print_option_help "--label-color=$(gettext "COLOR")" "$(gettext "use COLOR for label")" ++ print_option_help "--label-bgcolor=$(gettext "COLOR")" "$(gettext "use COLOR for label background")" ++ print_option_help "--product-name=$(gettext "STR")" "$(gettext "use STR as product")" ++ print_option_help "--product-version=$(gettext "STR")" "$(gettext "use STR as product version")" + echo + gettext_printf "%s generates a bootable rescue image with specified source files, source directories, or mkisofs options listed by the output of \`%s'\n" "xorriso -as mkisofs -help" "$self" | grub_fmt + echo +@@ -131,11 +144,41 @@ do + export PATH + ;; + ++ --product-name) ++ product_name=`argument $option "$@"`; shift ;; ++ --product-name=*) ++ product_name=`echo "$option" | sed 's/--product-name=//'` ;; ++ ++ --product-version) ++ product_version=`argument $option "$@"`; shift ;; ++ --product-version=*) ++ product_version=`echo "$option" | sed 's/--product-version=//'` ;; ++ + --grub-mkimage) + grub_mkimage=`argument $option "$@"`; shift ;; + --grub-mkimage=*) + grub_mkimage=`echo "$option" | sed 's/--grub-mkimage=//'` ;; + ++ --grub-render-label) ++ grub_render_label=`argument $option "$@"`; shift ;; ++ --grub-render-label=*) ++ grub_render_label=`echo "$option" | sed 's/--grub-render-label=//'` ;; ++ ++ --label-font) ++ label_font=`argument $option "$@"`; shift ;; ++ --label-font=*) ++ label_font=`echo "$option" | sed 's/--label-font=//'` ;; ++ ++ --label-color) ++ label_color=`argument $option "$@"`; shift ;; ++ --label-color=*) ++ label_color=`echo "$option" | sed 's/--label-color=//'` ;; ++ ++ --label-bgcolor) ++ label_bgcolor=`argument $option "$@"`; shift ;; ++ --label-bgcolor=*) ++ label_bgcolor=`echo "$option" | sed 's/--label-bgcolor=//'` ;; ++ + --xorriso) + xorriso=`argument $option "$@"`; shift ;; + --xorriso=*) +@@ -231,6 +274,9 @@ if [ "${override_dir}" = "" ] ; then + if test -e "${loongson_dir}" ; then + process_input_dir "${loongson_dir}" mipsel-loongson + fi ++ if test -e "${ppc_dir}" ; then ++ process_input_dir "${ppc_dir}" mipsel-loongson ++ fi + else + . "${override_dir}"/modinfo.sh + process_input_dir "${override_dir}" ${grub_modinfo_target_cpu}-${grub_modinfo_platform} +@@ -244,6 +290,7 @@ else + mipsel_qemu_dir= + mips_qemu_dir= + loongson_dir= ++ ppc_dir= + case "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" in + i386-multiboot) multiboot_dir="${override_dir}" ;; + i386-coreboot) coreboot_dir="${override_dir}" ;; +@@ -255,6 +302,7 @@ else + mipsel-qemu_mips) mipsel_qemu_dir="${override_dir}" ;; + mipsel-loongson) loongson_dir="${override_dir}" ;; + mips-qemu_mips) mips_qemu_dir="${override_dir}" ;; ++ powerpc-ieee1275) ppc_dir="${override_dir}" ;; + esac + fi + +@@ -309,6 +357,38 @@ if test -e "${efi64_dir}" || test -e "${efi32_dir}" || test -e "${ia64_dir}"; th + grub_mkisofs_arguments="${grub_mkisofs_arguments} --efi-boot efi.img" + fi + ++make_image "${ppc_dir}" powerpc-ieee1275 "${iso9660_dir}/boot/powerpc.elf" "" ++if [ -e "${iso9660_dir}"/System/Library/CoreServices/boot.efi ] || [ -e "${iso9660_dir}/boot/powerpc.elf" ]; then ++ mkdir -p "${iso9660_dir}"/System/Library/CoreServices ++ touch "${iso9660_dir}/mach_kernel" ++ cat > "${iso9660_dir}/System/Library/CoreServices/SystemVersion.plist" < ++ ++ ProductBuildVersion ++ ++ ProductName ++ ${product_name} ++ ProductVersion ++ ${product_version} ++ ++ ++EOF ++ "$grub_render_label" -f "$label_font" -b "$label_bgcolor" -c "$label_color" -t "${product_name} ${product_version}" -o "${iso9660_dir}/System/Library/CoreServices/.disk_label" ++ echo "${product_name} ${product_version}" > "${iso9660_dir}/System/Library/CoreServices/.disk_label.contentDetails" ++ grub_mkisofs_arguments="${grub_mkisofs_arguments} -hfsplus -hfsplus-file-creator-type chrp tbxj /System/Library/CoreServices/.disk_label" ++fi ++ ++if [ -e "${iso9660_dir}/boot/powerpc.elf" ] ; then ++ cp "${ppc_dir}/grub.chrp" "${iso9660_dir}"/System/Library/CoreServices/BootX ++ cp "${iso9660_dir}/boot/powerpc.elf" "${iso9660_dir}"/System/Library/CoreServices/grub.elf ++ # FIXME: add PreP ++ grub_mkisofs_arguments="${grub_mkisofs_arguments} -hfsplus-file-creator-type chrp tbxi /System/Library/CoreServices/BootX -hfs-bless-by p /System/Library/CoreServices -sysid PPC" ++fi ++ ++if [ -e "${iso9660_dir}"/System/Library/CoreServices/boot.efi ]; then ++ grub_mkisofs_arguments="${grub_mkisofs_arguments} -hfs-bless-by i /System/Library/CoreServices/boot.efi" ++fi ++ + make_image "${mipsel_qemu_dir}" mipsel-qemu_mips-elf "${iso9660_dir}/boot/mipsel-qemu_mips.elf" "pata" + if [ -e "${iso9660_dir}/boot/mipsel-qemu_mips.elf" ] && [ -d "${rom_directory}" ]; then + cp "${iso9660_dir}/boot/mipsel-qemu_mips.elf" "${rom_directory}/mipsel-qemu_mips.elf" +diff --git a/util/grub-render-label.c b/util/grub-render-label.c +new file mode 100644 +index 0000000..7237759 +--- /dev/null ++++ b/util/grub-render-label.c +@@ -0,0 +1,393 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2010,2012 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 ++ ++#define _GNU_SOURCE 1 ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "progname.h" ++ ++struct arguments ++{ ++ char *input; ++ char *text; ++ char *output; ++ char *font; ++ grub_video_rgba_color_t fgcolor; ++ grub_video_rgba_color_t bgcolor; ++ int verbosity; ++}; ++ ++static struct argp_option options[] = { ++ {"input", 'i', N_("FILE"), 0, ++ N_("read text from FILE."), 0}, ++ {"color", 'c', N_("COLOR"), 0, ++ N_("use COLOR for text"), 0}, ++ {"bgcolor", 'b', N_("COLOR"), 0, ++ N_("use COLOR for background"), 0}, ++ {"text", 't', N_("STR"), 0, ++ N_("supply the string."), 0}, ++ {"output", 'o', N_("FILE"), 0, ++ N_("set output filename. Default is STDOUT"), 0}, ++ {"font", 'f', N_("FILE"), 0, ++ N_("use FILE as font (PF2)."), 0}, ++ {"verbose", 'v', 0, 0, N_("print verbose messages."), 0}, ++ { 0, 0, 0, 0, 0, 0 } ++}; ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++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_text_render_swap_buffers (void) ++{ ++ return GRUB_ERR_NONE; ++} ++ ++static grub_err_t ++grub_video_text_render_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 struct grub_video_adapter grub_video_text_render_adapter = ++ { ++ .name = "Text rendering", ++ ++ .prio = GRUB_VIDEO_ADAPTER_PRIO_FIRMWARE, ++ ++ .fini = grub_video_fb_fini, ++ .get_info = grub_video_fb_get_info, ++ .get_info_and_fini = 0, ++ .set_palette = grub_video_fb_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_text_render_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_text_render_set_active_render_target, ++ .get_active_render_target = grub_video_fb_get_active_render_target, ++ ++ .next = 0 ++ }; ++ ++static error_t ++argp_parser (int key, char *arg, struct argp_state *state) ++{ ++ /* Get the input argument from argp_parse, which we ++ know is a pointer to our arguments structure. */ ++ struct arguments *arguments = state->input; ++ grub_err_t err; ++ ++ switch (key) ++ { ++ case 'i': ++ arguments->input = xstrdup (arg); ++ break; ++ ++ case 'b': ++ err = grub_video_parse_color (arg, &arguments->bgcolor); ++ if (err) ++ grub_util_error (_("Invalud color `%s'"), arg); ++ break; ++ ++ case 'c': ++ err = grub_video_parse_color (arg, &arguments->fgcolor); ++ if (err) ++ grub_util_error (_("Invalud color `%s'"), arg); ++ break; ++ ++ case 'f': ++ arguments->font = xstrdup (arg); ++ break; ++ ++ case 't': ++ arguments->text = xstrdup (arg); ++ break; ++ ++ case 'o': ++ arguments->output = xstrdup (arg); ++ break; ++ ++ case 'v': ++ arguments->verbosity++; ++ break; ++ ++ default: ++ return ARGP_ERR_UNKNOWN; ++ } ++ ++ return 0; ++} ++ ++void grub_hostfs_init (void); ++void grub_host_init (void); ++ ++struct header ++{ ++ grub_uint8_t magic; ++ grub_uint16_t width; ++ grub_uint16_t height; ++} __attribute__ ((packed)); ++ ++static struct argp argp = { ++ options, argp_parser, N_("[OPTIONS]"), ++ N_("Render Apple .disk_label."), ++ NULL, NULL, NULL ++}; ++ ++static struct grub_video_palette_data ieee1275_palette[256]; ++ ++int ++main (int argc, char *argv[]) ++{ ++ FILE *out; ++ char *text; ++ char *fontfull; ++ struct arguments arguments; ++ grub_font_t font; ++ int width, height; ++ struct header head; ++ const grub_uint8_t vals[] = { 0xff, 0xda, 0xb3, 0x87, 0x54, 0x00 }; ++ const grub_uint8_t vals2[] = { 0xf3, 0xe7, 0xcd, 0xc0, 0xa5, 0x96, ++ 0x77, 0x66, 0x3f, 0x27 }; ++ int i, j, k, cptr = 0; ++ grub_uint8_t bg, fg; ++ ++ for (i = 0; i < 256; i++) ++ ieee1275_palette[i].a = 0xff; ++ ++ for (i = 0; i < 6; i++) ++ for (j = 0; j < 6; j++) ++ for (k = 0; k < 6; k++) ++ { ++ ieee1275_palette[cptr].r = vals[i]; ++ ieee1275_palette[cptr].g = vals[j]; ++ ieee1275_palette[cptr].b = vals[k]; ++ ieee1275_palette[cptr].a = 0xff; ++ cptr++; ++ } ++ cptr--; ++ for (i = 0; i < 10; i++) ++ { ++ ieee1275_palette[cptr].r = vals2[i]; ++ ieee1275_palette[cptr].g = 0; ++ ieee1275_palette[cptr].b = 0; ++ ieee1275_palette[cptr].a = 0xff; ++ cptr++; ++ } ++ for (i = 0; i < 10; i++) ++ { ++ ieee1275_palette[cptr].r = 0; ++ ieee1275_palette[cptr].g = vals2[i]; ++ ieee1275_palette[cptr].b = 0; ++ ieee1275_palette[cptr].a = 0xff; ++ cptr++; ++ } ++ for (i = 0; i < 10; i++) ++ { ++ ieee1275_palette[cptr].r = 0; ++ ieee1275_palette[cptr].g = 0; ++ ieee1275_palette[cptr].b = vals2[i]; ++ ieee1275_palette[cptr].a = 0xff; ++ cptr++; ++ } ++ for (i = 0; i < 10; i++) ++ { ++ ieee1275_palette[cptr].r = vals2[i]; ++ ieee1275_palette[cptr].g = vals2[i]; ++ ieee1275_palette[cptr].b = vals2[i]; ++ ieee1275_palette[cptr].a = 0xff; ++ cptr++; ++ } ++ ieee1275_palette[cptr].r = 0; ++ ieee1275_palette[cptr].g = 0; ++ ieee1275_palette[cptr].b = 0; ++ ieee1275_palette[cptr].a = 0xff; ++ ++ set_program_name (argv[0]); ++ ++ grub_util_init_nls (); ++ ++ /* Check for options. */ ++ memset (&arguments, 0, sizeof (struct arguments)); ++ arguments.bgcolor.red = 0xff; ++ arguments.bgcolor.green = 0xff; ++ arguments.bgcolor.blue = 0xff; ++ arguments.bgcolor.alpha = 0xff; ++ arguments.fgcolor.red = 0x00; ++ arguments.fgcolor.green = 0x00; ++ arguments.fgcolor.blue = 0x00; ++ arguments.fgcolor.alpha = 0xff; ++ if (argp_parse (&argp, argc, argv, 0, 0, &arguments) != 0) ++ { ++ fprintf (stderr, "%s", _("Error in parsing command line arguments\n")); ++ exit(1); ++ } ++ ++ if ((!arguments.input && !arguments.text) || !arguments.font) ++ { ++ fprintf (stderr, "%s", _("Missing arguments\n")); ++ exit(1); ++ } ++ ++ if (arguments.text) ++ text = arguments.text; ++ else ++ { ++ FILE *in = fopen (arguments.input, "r"); ++ size_t s; ++ if (!in) ++ grub_util_error (_("cannot open `%s': %s"), arguments.input, ++ strerror (errno)); ++ fseek (in, 0, SEEK_END); ++ s = ftell (in); ++ fseek (in, 0, SEEK_SET); ++ text = xmalloc (s + 1); ++ if (fread (text, 1, s, in) != s) ++ grub_util_error (_("cannot read `%s': %s"), arguments.input, ++ strerror (errno)); ++ text[s] = 0; ++ fclose (in); ++ } ++ ++ if (arguments.output) ++ out = fopen (arguments.output, "wb"); ++ else ++ out = stdout; ++ if (!out) ++ { ++ grub_util_error (_("cannot open `%s': %s"), arguments.output ? : "stdout", ++ strerror (errno)); ++ } ++ ++ fontfull = canonicalize_file_name (arguments.font); ++ if (!fontfull) ++ { ++ grub_util_error (_("cannot open `%s': %s"), arguments.font, ++ strerror (errno)); ++ } ++ ++ fontfull = xasprintf ("(host)/%s", fontfull); ++ ++ grub_init_all (); ++ grub_hostfs_init (); ++ grub_host_init (); ++ ++ grub_font_loader_init (); ++ font = grub_font_load (fontfull); ++ if (!font) ++ { ++ grub_util_error (_("cannot open `%s': %s"), arguments.font, ++ grub_errmsg); ++ } ++ ++ width = grub_font_get_string_width (font, text) + 10; ++ height = grub_font_get_height (font); ++ ++ grub_memset (&framebuffer, 0, sizeof (framebuffer)); ++ ++ grub_video_fb_init (); ++ ++ framebuffer.mode_info.width = width; ++ framebuffer.mode_info.height = height; ++ framebuffer.mode_info.pitch = width; ++ ++ framebuffer.mode_info.mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR; ++ framebuffer.mode_info.bpp = 8; ++ framebuffer.mode_info.bytes_per_pixel = 1; ++ framebuffer.mode_info.number_of_colors = 256; ++ ++ framebuffer.mode_info.blit_format = grub_video_get_blit_format (&framebuffer.mode_info); ++ ++ /* For some reason sparc64 uses 32-bit pointer too. */ ++ framebuffer.ptr = xmalloc (height * width); ++ ++ grub_video_fb_create_render_target_from_pointer (&framebuffer.render_target, ++ &framebuffer.mode_info, ++ framebuffer.ptr); ++ grub_video_fb_set_active_render_target (framebuffer.render_target); ++ grub_video_fb_set_palette (0, ARRAY_SIZE (ieee1275_palette), ++ ieee1275_palette); ++ ++ grub_video_set_adapter (&grub_video_text_render_adapter); ++ ++ fg = grub_video_map_rgb (arguments.fgcolor.red, ++ arguments.fgcolor.green, ++ arguments.fgcolor.blue); ++ bg = grub_video_map_rgb (arguments.bgcolor.red, ++ arguments.bgcolor.green, ++ arguments.bgcolor.blue); ++ ++ grub_memset (framebuffer.ptr, bg, height * width); ++ grub_font_draw_string (text, font, fg, ++ 5, grub_font_get_ascent (font)); ++ ++ grub_video_set_adapter (0); ++ ++ head.magic = 1; ++ head.width = grub_cpu_to_be16 (width); ++ head.height = grub_cpu_to_be16 (height); ++ fwrite (&head, 1, sizeof (head), out); ++ fwrite (framebuffer.ptr, 1, width * height, out); ++ ++ if (out != stdout) ++ fclose (out); ++ ++ return 0; ++} +diff --git a/util/powerpc/ieee1275/grub-mkrescue.in b/util/powerpc/ieee1275/grub-mkrescue.in +deleted file mode 100644 +index 2615cab..0000000 +--- a/util/powerpc/ieee1275/grub-mkrescue.in ++++ /dev/null +@@ -1,146 +0,0 @@ +-#! /bin/sh +-set -e +- +-# Make GRUB rescue image +-# Copyright (C) 1999,2000,2001,2002,2003,2004,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 . +- +-# Initialize some variables. +-prefix="@prefix@" +-exec_prefix="@exec_prefix@" +-bindir="@bindir@" +-libdir="@libdir@" +-PACKAGE_NAME=@PACKAGE_NAME@ +-PACKAGE_TARNAME=@PACKAGE_TARNAME@ +-PACKAGE_VERSION=@PACKAGE_VERSION@ +-input_dir="${libdir}/@PACKAGE@/powerpc-ieee1275" +-datarootdir="@datarootdir@" +-datadir="@datadir@" +-if [ "x$pkgdatadir" = x ]; then +- pkgdatadir="${datadir}/@PACKAGE@" +-fi +- +-self=`basename $0` +- +-grub_mkimage="${bindir}/@grub_mkimage@" +- +-export TEXTDOMAIN=@PACKAGE@ +-export TEXTDOMAINDIR="@localedir@" +- +-. "${pkgdatadir}/grub-mkconfig_lib" +- +-# Usage: usage +-# Print the usage. +-usage () { +- gettext_printf "Usage: %s [OPTION] SOURCE...\n" "$self" +- gettext "Make GRUB CD-ROM, disk, pendrive and floppy bootable image."; echo +- echo +- print_option_help "-h, --help" "$(gettext "print this message and exit")" +- print_option_help "-v, --version" "$(gettext "print the version information and exit")" +- print_option_help "--modules=$(gettext "MODULES")" "$(gettext "pre-load specified modules MODULES")" +- print_option_help "--grub-mkimage=$(gettext "FILE")" "$(gettext "use FILE as grub-mkimage")" +- echo +- gettext_printf "%s generates a bootable rescue image with specified source files, source directories, or mkisofs options listed by the output of \`%s'\n" "genisoimage -help" "$self" | grub_fmt +- echo +- gettext "Report bugs to ."; echo +-} +- +-argument () { +- opt=$1 +- shift +- +- if test $# -eq 0; then +- gettext_printf "%s: option requires an argument -- \`%s'\n" "$0" "$opt" 1>&2 +- exit 1 +- fi +- echo $1 +-} +- +-source= +-output_image= +- +-# Check the arguments. +-while test $# -gt 0 +-do +- option=$1 +- shift +- +- case "$option" in +- -h | --help) +- usage +- exit 0 ;; +- -v | --version) +- echo "$self (${PACKAGE_NAME}) ${PACKAGE_VERSION}" +- exit 0 ;; +- +- --modules) +- modules=`argument $option "$@"`; shift ;; +- --modules=*) +- modules=`echo "$option" | sed 's/--modules=//'` ;; +- +- --override-directory) +- input_dir=`argument $option "$@"`; shift ;; +- --override-directory=*) +- input_dir=`echo "$option" | sed 's/--override-directory=//'` ;; +- +- --grub-mkimage) +- grub_mkimage=`argument $option "$@"`; shift ;; +- --grub-mkimage=*) +- grub_mkimage=`echo "$option" | sed 's/--grub-mkimage=//'` ;; +- +- -o | --output) +- output_image=`argument $option "$@"`; shift ;; +- --output=*) +- output_image=`echo "$option" | sed 's/--output=//'` ;; +- +- --rom-directory=*) +- ;; +- --rom-directory) +- shift ;; +- +- *) +- source="${source} ${option} $@"; break ;; +- esac +-done +- +-if test "x$output_image" = x; then +- usage +- exit 1 +-fi +- +-if [ "x${modules}" = "x" ] ; then +- modules=`cd ${input_dir}/ && ls *.mod` +-fi +- +-map_file=`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1 +-cat >${map_file} < +Date: Fri, 12 Apr 2013 01:29:45 +0200 +Subject: [PATCH 282/364] Support i386-ieee1275 grub-mkrescue and make + check on it. + +--- + ChangeLog | 4 ++++ + Makefile.util.def | 1 + + grub-core/tests/boot/qemu-shutdown-x86.S | 9 +++++++++ + tests/grub_script_expansion.in | 2 +- + tests/partmap_test.in | 8 +++++++- + tests/util/grub-shell.in | 7 ++++--- + util/grub-mkrescue.in | 8 ++++++++ + 7 files changed, 34 insertions(+), 5 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 0d62509..c137b5f 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,9 @@ + 2013-04-11 Vladimir Serbinenko + ++ Support i386-ieee1275 grub-mkrescue and make check on it. ++ ++2013-04-11 Vladimir Serbinenko ++ + Merge powerpc grub-mkrescue flavour with common. Use xorriso HFS+ + feature for it. + +diff --git a/Makefile.util.def b/Makefile.util.def +index bd286fc..373c25b 100644 +--- a/Makefile.util.def ++++ b/Makefile.util.def +@@ -470,6 +470,7 @@ script = { + enable = i386_qemu; + enable = i386_multiboot; + enable = i386_coreboot; ++ enable = i386_ieee1275; + enable = mips_qemu_mips; + enable = mips_loongson; + enable = ia64_efi; +diff --git a/grub-core/tests/boot/qemu-shutdown-x86.S b/grub-core/tests/boot/qemu-shutdown-x86.S +index 8f794fc..9f8bc40 100644 +--- a/grub-core/tests/boot/qemu-shutdown-x86.S ++++ b/grub-core/tests/boot/qemu-shutdown-x86.S +@@ -1,3 +1,12 @@ ++ movl $0x80000b80, %eax ++ movw $0xcf8, %dx ++ outl %eax, %dx ++ movl $0x1001, %eax ++ movw $0xcfc, %dx ++ inb %al, %dx ++ orb $1, %al ++ outb %al, %dx ++ + movl $0x80000b40, %eax + movw $0xcf8, %dx + outl %eax, %dx +diff --git a/tests/grub_script_expansion.in b/tests/grub_script_expansion.in +index c476390..03dc510 100644 +--- a/tests/grub_script_expansion.in ++++ b/tests/grub_script_expansion.in +@@ -35,7 +35,7 @@ done + + other=`echo insmod regexp\; echo '(*)' | @builddir@/grub-shell` + for d in $disks; do +- if ! echo "$other" | grep "$d" >/dev/null; then ++ if ! echo "$other" | grep -F "$d" >/dev/null; then + echo "$d missing from (*) expansion" >&2 + exit 1 + fi +diff --git a/tests/partmap_test.in b/tests/partmap_test.in +index 1507220..a0beb2a 100644 +--- a/tests/partmap_test.in ++++ b/tests/partmap_test.in +@@ -49,7 +49,7 @@ list_parts () { + outfile="$1" + shift + +- echo ls | "${grubshell}" --qemu-opts="-hda ${imgfile}" \ ++ echo ls | "${grubshell}" --qemu-opts="-$qemudisk ${imgfile}" \ + --modules=$mod | tr -d "\n\r" > "${outfile}" + cat "${outfile}" + echo +@@ -58,12 +58,18 @@ list_parts () { + case "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" in + mips-qemu_mips | mipsel-qemu_mips | i386-qemu | i386-multiboot | i386-coreboot | mipsel-loongson) + disk=ata0 ++ qemudisk=hda + ;; + powerpc-ieee1275) + disk=ieee1275//pci@80000000/mac-io@4/ata-3@20000/disk@0 ++ qemudisk=hda + # QEMU firmware has bugs which prevent it from accessing hard disk. + exit 0 + ;; ++ i386-ieee1275) ++ disk=ieee1275/d ++ qemudisk=hdb ++ ;; + *) + disk=hd0 + ;; +diff --git a/tests/util/grub-shell.in b/tests/util/grub-shell.in +index 04e64da..c6d1cd7 100644 +--- a/tests/util/grub-shell.in ++++ b/tests/util/grub-shell.in +@@ -100,10 +100,11 @@ case "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" in + console=vga_text;; + + i386-ieee1275) +- boot=cd ++ boot=hd + qemu=qemu-system-i386 +- console=console;; +- ++ console=console ++ trim=1 ++ ;; + i386-qemu) + boot=qemu + qemu=qemu-system-i386 +diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in +index a6e4de6..510d95f 100644 +--- a/util/grub-mkrescue.in ++++ b/util/grub-mkrescue.in +@@ -40,6 +40,7 @@ mipsel_qemu_dir="${libdir}/@PACKAGE@/mipsel-qemu_mips" + loongson_dir="${libdir}/@PACKAGE@/mipsel-loongson" + mips_qemu_dir="${libdir}/@PACKAGE@/mips-qemu_mips" + pc_dir="${libdir}/@PACKAGE@/i386-pc" ++i386_ieee1275_dir="${libdir}/@PACKAGE@/i386-ieee1275" + efi32_dir="${libdir}/@PACKAGE@/i386-efi" + efi64_dir="${libdir}/@PACKAGE@/x86_64-efi" + ia64_dir="${libdir}/@PACKAGE@/ia64-efi" +@@ -256,6 +257,9 @@ if [ "${override_dir}" = "" ] ; then + if test -e "${pc_dir}" ; then + process_input_dir "${pc_dir}" i386-pc + fi ++ if test -e "${i386_ieee1275_dir}" ; then ++ process_input_dir "${i386_ieee1275_dir}" i386-ieee1275 ++ fi + if test -e "${efi32_dir}" ; then + process_input_dir "${efi32_dir}" i386-efi + fi +@@ -291,6 +295,7 @@ else + mips_qemu_dir= + loongson_dir= + ppc_dir= ++ i386_ieee1275_dir= + case "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" in + i386-multiboot) multiboot_dir="${override_dir}" ;; + i386-coreboot) coreboot_dir="${override_dir}" ;; +@@ -303,6 +308,7 @@ else + mipsel-loongson) loongson_dir="${override_dir}" ;; + mips-qemu_mips) mips_qemu_dir="${override_dir}" ;; + powerpc-ieee1275) ppc_dir="${override_dir}" ;; ++ i386-ieee1275) i386_ieee1275_dir="${override_dir}" ;; + esac + fi + +@@ -336,6 +342,8 @@ fi + # build multiboot core.img + make_image "${multiboot_dir}" i386-multiboot "${iso9660_dir}/boot/multiboot.img" "pata ahci at_keyboard" + ++make_image "${i386_ieee1275_dir}" i386-ieee1275 "${iso9660_dir}/boot/ofwx86.elf" "" ++ + if test -e "${efi64_dir}" || test -e "${efi32_dir}" || test -e "${ia64_dir}"; then + efi_dir=`mktemp -d "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1 + mkdir -p "${efi_dir}/efi/boot" +-- +1.8.1.4 + diff --git a/0283-tests-partmap_test.in-Fix-missing-qemudisk-setting.patch b/0283-tests-partmap_test.in-Fix-missing-qemudisk-setting.patch new file mode 100644 index 0000000..8105758 --- /dev/null +++ b/0283-tests-partmap_test.in-Fix-missing-qemudisk-setting.patch @@ -0,0 +1,38 @@ +From 4ad3b808b24202670c65a20e1f0a532499772312 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Fri, 12 Apr 2013 01:44:14 +0200 +Subject: [PATCH 283/364] * tests/partmap_test.in: Fix missing qemudisk + setting. + +--- + ChangeLog | 4 ++++ + tests/partmap_test.in | 1 + + 2 files changed, 5 insertions(+) + +diff --git a/ChangeLog b/ChangeLog +index c137b5f..0668a0f 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,7 @@ ++2013-04-12 Vladimir Serbinenko ++ ++ * tests/partmap_test.in: Fix missing qemudisk setting. ++ + 2013-04-11 Vladimir Serbinenko + + Support i386-ieee1275 grub-mkrescue and make check on it. +diff --git a/tests/partmap_test.in b/tests/partmap_test.in +index a0beb2a..8d68a28 100644 +--- a/tests/partmap_test.in ++++ b/tests/partmap_test.in +@@ -72,6 +72,7 @@ case "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" in + ;; + *) + disk=hd0 ++ qemudisk=hda + ;; + esac + imgfile="`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"`" || exit 1 +-- +1.8.1.4 + diff --git a/0284-tests-grub_cmd_date.in-New-test-for-datetime.patch b/0284-tests-grub_cmd_date.in-New-test-for-datetime.patch new file mode 100644 index 0000000..c05bc1d --- /dev/null +++ b/0284-tests-grub_cmd_date.in-New-test-for-datetime.patch @@ -0,0 +1,65 @@ +From 369b824667cc2a140e0efaccf480d43e07199d8d Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Fri, 12 Apr 2013 01:47:38 +0200 +Subject: [PATCH 284/364] * tests/grub_cmd_date.in: New test for + datetime. + +--- + ChangeLog | 4 ++++ + Makefile.util.def | 6 ++++++ + tests/grub_cmd_date.in | 12 ++++++++++++ + 3 files changed, 22 insertions(+) + create mode 100644 tests/grub_cmd_date.in + +diff --git a/ChangeLog b/ChangeLog +index 0668a0f..a2f1d5a 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,9 @@ + 2013-04-12 Vladimir Serbinenko + ++ * tests/grub_cmd_date.in: New test for datetime. ++ ++2013-04-12 Vladimir Serbinenko ++ + * tests/partmap_test.in: Fix missing qemudisk setting. + + 2013-04-11 Vladimir Serbinenko +diff --git a/Makefile.util.def b/Makefile.util.def +index 373c25b..a231b40 100644 +--- a/Makefile.util.def ++++ b/Makefile.util.def +@@ -676,6 +676,12 @@ script = { + + script = { + testcase; ++ name = grub_cmd_date; ++ common = tests/grub_cmd_date.in; ++}; ++ ++script = { ++ testcase; + name = grub_script_expansion; + common = tests/grub_script_expansion.in; + }; +diff --git a/tests/grub_cmd_date.in b/tests/grub_cmd_date.in +new file mode 100644 +index 0000000..1c8e7e6 +--- /dev/null ++++ b/tests/grub_cmd_date.in +@@ -0,0 +1,12 @@ ++#! /bin/bash ++set -e ++ ++pdt="$(date -u +%s)" ++dt=`echo date | @builddir@/grub-shell` ++dtg="$(date -u -d "$dt" +%s)" ++ndt="$(date -u +%s)" ++ ++if [ $pdt -le $dtg ] && [ $dtg -le $ndt ]; then ++ exit 0; ++fi ++echo "Date not in range: $pdt <= $dtg <= $ndt" +-- +1.8.1.4 + diff --git a/0285-docs-grub.texi-Update-coreboot-status-info.patch b/0285-docs-grub.texi-Update-coreboot-status-info.patch new file mode 100644 index 0000000..fc604b8 --- /dev/null +++ b/0285-docs-grub.texi-Update-coreboot-status-info.patch @@ -0,0 +1,132 @@ +From 17ed0de277435222aba484b3903a55710075f999 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Fri, 12 Apr 2013 14:03:52 +0200 +Subject: [PATCH 285/364] * docs/grub.texi: Update coreboot status info. + +--- + ChangeLog | 4 ++++ + docs/grub.texi | 40 ++++++++++++++++++++-------------------- + 2 files changed, 24 insertions(+), 20 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index a2f1d5a..5212955 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,9 @@ + 2013-04-12 Vladimir Serbinenko + ++ * docs/grub.texi: Update coreboot status info. ++ ++2013-04-12 Vladimir Serbinenko ++ + * tests/grub_cmd_date.in: New test for datetime. + + 2013-04-12 Vladimir Serbinenko +diff --git a/docs/grub.texi b/docs/grub.texi +index f6f9506..87d19ea 100644 +--- a/docs/grub.texi ++++ b/docs/grub.texi +@@ -4860,6 +4860,7 @@ Information retrieval: + @item mips-arc: lsdev + @item efi: lsefisystab, lssal, lsefimmap + @item i386-pc: lsapm ++@item i386-coreboot: lscoreboot, coreboot_boottime + @item acpi-enabled (i386-pc, i386-coreboot, i386-multiboot, *-efi): lsacpi + @end itemize + +@@ -4895,10 +4896,10 @@ X86 support is summarised in the following table. ``Yes'' means that the kernel + @item Plan9 @tab yes @tab no (1) + @item Freedos @tab yes @tab no (1) + @item FreeBSD bootloader @tab yes @tab crashes (1) +-@item 32-bit kFreeBSD @tab yes @tab crashes (2,6) +-@item 64-bit kFreeBSD @tab yes @tab crashes (2,6) ++@item 32-bit kFreeBSD @tab yes @tab crashes (5) ++@item 64-bit kFreeBSD @tab yes @tab crashes (5) + @item 32-bit kNetBSD @tab yes @tab crashes (1) +-@item 64-bit kNetBSD @tab yes @tab crashes (2) ++@item 64-bit kNetBSD @tab yes @tab crashes + @item 32-bit kOpenBSD @tab yes @tab yes + @item 64-bit kOpenBSD @tab yes @tab yes + @item Multiboot @tab yes @tab yes +@@ -4909,9 +4910,9 @@ X86 support is summarised in the following table. ``Yes'' means that the kernel + @item 64-bit Linux (modern protocol) @tab yes @tab yes + @item 32-bit XNU @tab yes @tab ? + @item 64-bit XNU @tab yes @tab ? +-@item 32-bit EFI chainloader @tab no (3) @tab no (3) +-@item 64-bit EFI chainloader @tab no (3) @tab no (3) +-@item Appleloader @tab no (3) @tab no (3) ++@item 32-bit EFI chainloader @tab no (2) @tab no (2) ++@item 64-bit EFI chainloader @tab no (2) @tab no (2) ++@item Appleloader @tab no (2) @tab no (2) + @end multitable + + @multitable @columnfractions .50 .22 .22 +@@ -4921,8 +4922,8 @@ X86 support is summarised in the following table. ``Yes'' means that the kernel + @item Plan9 @tab no (1) @tab no (1) + @item FreeDOS @tab no (1) @tab no (1) + @item FreeBSD bootloader @tab crashes (1) @tab crashes (1) +-@item 32-bit kFreeBSD @tab crashes (6) @tab crashes (6) +-@item 64-bit kFreeBSD @tab crashes (6) @tab crashes (6) ++@item 32-bit kFreeBSD @tab crashes (5) @tab crashes (5) ++@item 64-bit kFreeBSD @tab crashes (5) @tab crashes (5) + @item 32-bit kNetBSD @tab crashes (1) @tab crashes (1) + @item 64-bit kNetBSD @tab yes @tab yes + @item 32-bit kOpenBSD @tab yes @tab yes +@@ -4935,9 +4936,9 @@ X86 support is summarised in the following table. ``Yes'' means that the kernel + @item 64-bit Linux (modern protocol) @tab yes @tab yes + @item 32-bit XNU @tab ? @tab ? + @item 64-bit XNU @tab ? @tab ? +-@item 32-bit EFI chainloader @tab no (3) @tab no (3) +-@item 64-bit EFI chainloader @tab no (3) @tab no (3) +-@item Appleloader @tab no (3) @tab no (3) ++@item 32-bit EFI chainloader @tab no (2) @tab no (2) ++@item 64-bit EFI chainloader @tab no (2) @tab no (2) ++@item Appleloader @tab no (2) @tab no (2) + @end multitable + + @multitable @columnfractions .50 .22 .22 +@@ -4960,9 +4961,9 @@ X86 support is summarised in the following table. ``Yes'' means that the kernel + @item 32-bit Linux (modern protocol) @tab yes @tab yes + @item 64-bit Linux (modern protocol) @tab yes @tab yes + @item 32-bit XNU @tab yes @tab yes +-@item 64-bit XNU @tab yes (5) @tab yes +-@item 32-bit EFI chainloader @tab yes @tab no (4) +-@item 64-bit EFI chainloader @tab no (4) @tab yes ++@item 64-bit XNU @tab yes (4) @tab yes ++@item 32-bit EFI chainloader @tab yes @tab no (3) ++@item 64-bit EFI chainloader @tab no (3) @tab yes + @item Appleloader @tab yes @tab yes + @end multitable + +@@ -4973,8 +4974,8 @@ X86 support is summarised in the following table. ``Yes'' means that the kernel + @item Plan9 @tab no (1) + @item FreeDOS @tab no (1) + @item FreeBSD bootloader @tab crashes (1) +-@item 32-bit kFreeBSD @tab crashes (6) +-@item 64-bit kFreeBSD @tab crashes (6) ++@item 32-bit kFreeBSD @tab crashes (5) ++@item 64-bit kFreeBSD @tab crashes (5) + @item 32-bit kNetBSD @tab crashes (1) + @item 64-bit kNetBSD @tab ? + @item 32-bit kOpenBSD @tab ? +@@ -4987,14 +4988,13 @@ X86 support is summarised in the following table. ``Yes'' means that the kernel + @item 64-bit Linux (modern protocol) @tab ? + @item 32-bit XNU @tab ? + @item 64-bit XNU @tab ? +-@item 32-bit EFI chainloader @tab no (3) +-@item 64-bit EFI chainloader @tab no (3) +-@item Appleloader @tab no (3) ++@item 32-bit EFI chainloader @tab no (2) ++@item 64-bit EFI chainloader @tab no (2) ++@item Appleloader @tab no (2) + @end multitable + + @enumerate + @item Requires BIOS +-@item Crashes because the memory at 0x0-0x1000 isn't available + @item EFI only + @item 32-bit and 64-bit EFI have different structures and work in different CPU modes so it's not possible to chainload 32-bit bootloader on 64-bit platform and vice-versa + @item Some modules may need to be disabled +-- +1.8.1.4 + diff --git a/0286-Turn-off-QEMU-ACPI-way-since-new-releases-don-t-have.patch b/0286-Turn-off-QEMU-ACPI-way-since-new-releases-don-t-have.patch new file mode 100644 index 0000000..f0ff082 --- /dev/null +++ b/0286-Turn-off-QEMU-ACPI-way-since-new-releases-don-t-have.patch @@ -0,0 +1,250 @@ +From 4a1875b61089e467165be46a7e538e8beb47d8ac Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Fri, 12 Apr 2013 14:49:33 +0200 +Subject: [PATCH 286/364] Turn off QEMU ACPI-way since new releases + don't have shutdown port anymore. + +--- + ChangeLog | 5 +++++ + Makefile.am | 35 ++++++++++++++--------------- + grub-core/lib/i386/halt.c | 23 ++++++++++++++++++- + grub-core/tests/boot/kfreebsd.init-i386.S | 6 ++--- + grub-core/tests/boot/kfreebsd.init-x86_64.S | 2 +- + grub-core/tests/boot/qemu-shutdown-x86.S | 7 +++--- + 6 files changed, 51 insertions(+), 27 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 5212955..1c77abf 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,10 @@ + 2013-04-12 Vladimir Serbinenko + ++ Turn off QEMU ACPI-way since new releases don't have shutdown port ++ anymore. ++ ++2013-04-12 Vladimir Serbinenko ++ + * docs/grub.texi: Update coreboot status info. + + 2013-04-12 Vladimir Serbinenko +diff --git a/Makefile.am b/Makefile.am +index 30aa5a7..9d38405 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -153,10 +153,10 @@ if COND_x86_64_efi + QEMU32=qemu-system-x86_64 + endif + +-linux.init.x86_64: $(srcdir)/grub-core/tests/boot/linux.init-x86_64.S ++linux.init.x86_64: $(srcdir)/grub-core/tests/boot/linux.init-x86_64.S $(srcdir)/grub-core/tests/boot/qemu-shutdown-x86.S + $(TARGET_CC) -o $@ $< -m64 -nostdlib -nostdinc -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" + +-linux.init.i386: $(srcdir)/grub-core/tests/boot/linux.init-i386.S ++linux.init.i386: $(srcdir)/grub-core/tests/boot/linux.init-i386.S $(srcdir)/grub-core/tests/boot/qemu-shutdown-x86.S + $(TARGET_CC) -o $@ $< -m32 -nostdlib -nostdinc -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" + + linux.init.mips: $(srcdir)/grub-core/tests/boot/linux.init-mips.S +@@ -171,46 +171,46 @@ linux.init.mipsel: $(srcdir)/grub-core/tests/boot/linux.init-mips.S + linux.init.loongson: $(srcdir)/grub-core/tests/boot/linux.init-mips.S + $(TARGET_CC) -o $@ $< -nostdlib -nostdinc -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" -DREBOOT=1 + +-multiboot.elf: $(srcdir)/grub-core/tests/boot/kernel-i386.S ++multiboot.elf: $(srcdir)/grub-core/tests/boot/kernel-i386.S $(srcdir)/grub-core/tests/boot/qemu-shutdown-x86.S + $(TARGET_CC) -o $@ $< -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" -ffreestanding -nostdlib -nostdinc -DTARGET_MULTIBOOT=1 -Wl,--build-id=none -Wl,-N -Wl,-Ttext,0x100000 -m32 -I$(srcdir)/include + +-kfreebsd.elf: $(srcdir)/grub-core/tests/boot/kernel-i386.S ++kfreebsd.elf: $(srcdir)/grub-core/tests/boot/kernel-i386.S $(srcdir)/grub-core/tests/boot/qemu-shutdown-x86.S + $(TARGET_CC) -o $@ $< -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" -ffreestanding -nostdlib -nostdinc -Wl,--build-id=none -Wl,-N -Wl,-Ttext,0x100000 -m32 -I$(srcdir)/include + + kfreebsd.aout: kfreebsd.elf + $(OBJCOPY) -O a.out-i386-linux $< $@ -R .note.gnu.build-id -R .note.gnu.gold-version + +-pc-chainloader.elf: $(srcdir)/grub-core/tests/boot/kernel-8086.S ++pc-chainloader.elf: $(srcdir)/grub-core/tests/boot/kernel-8086.S $(srcdir)/grub-core/tests/boot/qemu-shutdown-x86.S + $(TARGET_CC) -o $@ $< -DTARGET_CHAINLOADER=1 -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" -ffreestanding -nostdlib -nostdinc -Wl,--build-id=none -Wl,-N -Wl,-Ttext,0x7c00 -m32 + + pc-chainloader.bin: pc-chainloader.elf + $(OBJCOPY) -O binary --strip-unneeded -R .note -R .comment -R .note.gnu.build-id -R .reginfo -R .rel.dyn -R .note.gnu.gold-version $< $@; + +-ntldr.elf: $(srcdir)/grub-core/tests/boot/kernel-8086.S ++ntldr.elf: $(srcdir)/grub-core/tests/boot/kernel-8086.S $(srcdir)/grub-core/tests/boot/qemu-shutdown-x86.S + $(TARGET_CC) -o $@ $< -DTARGET_NTLDR=1 -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" -ffreestanding -nostdlib -nostdinc -Wl,--build-id=none -Wl,-N -Wl,-Ttext,0 -m32 + + ntldr.bin: ntldr.elf + $(OBJCOPY) -O binary --strip-unneeded -R .note -R .comment -R .note.gnu.build-id -R .reginfo -R .rel.dyn -R .note.gnu.gold-version $< $@; + +-multiboot2.elf: $(srcdir)/grub-core/tests/boot/kernel-i386.S ++multiboot2.elf: $(srcdir)/grub-core/tests/boot/kernel-i386.S $(srcdir)/grub-core/tests/boot/qemu-shutdown-x86.S + $(TARGET_CC) -o $@ $< -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" -ffreestanding -nostdlib -nostdinc -Wl,--build-id=none -Wl,-N -Wl,-Ttext,0x100000 -m32 -I$(srcdir)/include -DTARGET_MULTIBOOT2=1 + +-kfreebsd.init.x86_64: $(srcdir)/grub-core/tests/boot/kfreebsd.init-x86_64.S ++kfreebsd.init.x86_64: $(srcdir)/grub-core/tests/boot/kfreebsd.init-x86_64.S $(srcdir)/grub-core/tests/boot/qemu-shutdown-x86.S + $(TARGET_CC) -o $@ $< -m64 -nostdlib -nostdinc -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" && freebsd-brandelf -t FreeBSD $@ + +-kfreebsd.init.i386: $(srcdir)/grub-core/tests/boot/kfreebsd.init-i386.S ++kfreebsd.init.i386: $(srcdir)/grub-core/tests/boot/kfreebsd.init-i386.S $(srcdir)/grub-core/tests/boot/qemu-shutdown-x86.S + $(TARGET_CC) -o $@ $< -m32 -nostdlib -nostdinc -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" && freebsd-brandelf -t FreeBSD $@ + +-knetbsd.init.i386: $(srcdir)/grub-core/tests/boot/kbsd.init-i386.S ++knetbsd.init.i386: $(srcdir)/grub-core/tests/boot/kbsd.init-i386.S $(srcdir)/grub-core/tests/boot/qemu-shutdown-x86.S + $(TARGET_CC) -o $@ $< -m32 -nostdlib -nostdinc -DTARGET_NETBSD=1 -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" + +-kopenbsd.init.i386: $(srcdir)/grub-core/tests/boot/kbsd.init-i386.S ++kopenbsd.init.i386: $(srcdir)/grub-core/tests/boot/kbsd.init-i386.S $(srcdir)/grub-core/tests/boot/qemu-shutdown-x86.S + $(TARGET_CC) -o $@ $< -m32 -nostdlib -nostdinc -DTARGET_OPENBSD=1 -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" + +-knetbsd.init.x86_64: $(srcdir)/grub-core/tests/boot/kbsd.init-x86_64.S ++knetbsd.init.x86_64: $(srcdir)/grub-core/tests/boot/kbsd.init-x86_64.S $(srcdir)/grub-core/tests/boot/qemu-shutdown-x86.S + $(TARGET_CC) -o $@ $< -m64 -DTARGET_NETBSD=1 -nostdlib -nostdinc -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" + +-kopenbsd.init.x86_64: $(srcdir)/grub-core/tests/boot/kbsd.init-x86_64.S ++kopenbsd.init.x86_64: $(srcdir)/grub-core/tests/boot/kbsd.init-x86_64.S $(srcdir)/grub-core/tests/boot/qemu-shutdown-x86.S + $(TARGET_CC) -o $@ $< -m64 -DTARGET_OPENBSD=1 -nostdlib -nostdinc -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" + + linux-initramfs.mips: linux.init.mips Makefile +@@ -335,18 +335,17 @@ BOOTCHECKS = bootcheck-kfreebsd-aout bootcheck-kopenbsd-i386 bootcheck-kopenbsd- + endif + + if COND_i386_multiboot +-# Freebsd crashes because memory at 0-0x1000 is occupied and requires ACPI ++# FreeBSD requires ACPI + BOOTCHECKS = bootcheck-kfreebsd-aout bootcheck-kopenbsd-i386 bootcheck-kopenbsd-x86_64 bootcheck-multiboot bootcheck-multiboot2 bootcheck-linux-i386 bootcheck-linux-x86_64 bootcheck-knetbsd-x86_64 + endif + + if COND_i386_coreboot +-# 64-bit NetBSD crashes because memory at 0-0x1000 is occupied +-# Freebsd crashes because memory at 0-0x1000 is occupied and requires ACPI +-BOOTCHECKS = bootcheck-kfreebsd-aout bootcheck-kopenbsd-i386 bootcheck-kopenbsd-x86_64 bootcheck-multiboot bootcheck-multiboot2 bootcheck-linux-i386 bootcheck-linux-x86_64 ++# Freebsd requires ACPI ++BOOTCHECKS = bootcheck-kfreebsd-aout bootcheck-kopenbsd-i386 bootcheck-kopenbsd-x86_64 bootcheck-multiboot bootcheck-multiboot2 bootcheck-linux-i386 bootcheck-linux-x86_64 bootcheck-knetbsd-x86_64 + endif + + if COND_i386_qemu +-# Freebsd crashes because memory at 0-0x1000 is occupied and requires ACPI ++# FreeBSD requires ACPI + BOOTCHECKS = bootcheck-kfreebsd-aout bootcheck-kopenbsd-i386 bootcheck-kopenbsd-x86_64 bootcheck-multiboot bootcheck-multiboot2 bootcheck-linux-i386 bootcheck-linux-x86_64 bootcheck-knetbsd-x86_64 + endif + +diff --git a/grub-core/lib/i386/halt.c b/grub-core/lib/i386/halt.c +index bd878c9..9f84054 100644 +--- a/grub-core/lib/i386/halt.c ++++ b/grub-core/lib/i386/halt.c +@@ -20,6 +20,8 @@ + #include + #include + #include ++#include ++#include + + const char bochs_shutdown[] = "Shutdown"; + +@@ -37,6 +39,23 @@ stop (void) + } + } + ++static int ++grub_shutdown_pci_iter (grub_pci_device_t dev, grub_pci_id_t pciid, ++ void *data __attribute__ ((unused))) ++{ ++ /* QEMU. */ ++ if (pciid == 0x71138086) ++ { ++ grub_pci_address_t addr; ++ addr = grub_pci_make_address (dev, 0x40); ++ grub_pci_write (addr, 0x7001); ++ addr = grub_pci_make_address (dev, 0x80); ++ grub_pci_write (addr, grub_pci_read (addr) | 1); ++ grub_outw (0x2000, 0x7004); ++ } ++ return 0; ++} ++ + void + grub_halt (void) + { +@@ -49,10 +68,12 @@ grub_halt (void) + /* Disable interrupts. */ + __asm__ __volatile__ ("cli"); + +- /* Bochs, QEMU, etc. */ ++ /* Bochs, QEMU, etc. Removed in newer QEMU releases. */ + for (i = 0; i < sizeof (bochs_shutdown) - 1; i++) + grub_outb (bochs_shutdown[i], 0x8900); + ++ grub_pci_iterate (grub_shutdown_pci_iter, NULL); ++ + grub_puts_ (N_("GRUB doesn't know how to halt this machine yet!")); + + /* In order to return we'd have to check what the previous status of IF +diff --git a/grub-core/tests/boot/kfreebsd.init-i386.S b/grub-core/tests/boot/kfreebsd.init-i386.S +index a448152..7a4baba 100644 +--- a/grub-core/tests/boot/kfreebsd.init-i386.S ++++ b/grub-core/tests/boot/kfreebsd.init-i386.S +@@ -65,7 +65,7 @@ _start: + + /* IOPERM. */ + movl $SYSCALL_ARCH, %eax +- pushl $iopl_arg1 ++ pushl $ioperm_arg1 + pushl $SYSCALL_ARCH_IOPERM + pushl $0 + int $SYSCALL_INT +@@ -73,7 +73,7 @@ _start: + + /* IOPERM. */ + movl $SYSCALL_ARCH, %eax +- pushl $iopl_arg2 ++ pushl $ioperm_arg2 + pushl $SYSCALL_ARCH_IOPERM + pushl $0 + int $SYSCALL_INT +@@ -104,6 +104,6 @@ ioperm_arg1: + .long 8 + .long 1 + ioperm_arg2: +- .long 0x1000 ++ .long 0x7000 + .long 8 + .long 1 +diff --git a/grub-core/tests/boot/kfreebsd.init-x86_64.S b/grub-core/tests/boot/kfreebsd.init-x86_64.S +index de7bab6..05e5760 100644 +--- a/grub-core/tests/boot/kfreebsd.init-x86_64.S ++++ b/grub-core/tests/boot/kfreebsd.init-x86_64.S +@@ -85,6 +85,6 @@ ioperm_arg1: + .long 8 + .long 1 + ioperm_arg2: +- .long 0x1000 ++ .long 0x7000 + .long 8 + .long 1 +diff --git a/grub-core/tests/boot/qemu-shutdown-x86.S b/grub-core/tests/boot/qemu-shutdown-x86.S +index 9f8bc40..e37f5df 100644 +--- a/grub-core/tests/boot/qemu-shutdown-x86.S ++++ b/grub-core/tests/boot/qemu-shutdown-x86.S +@@ -1,18 +1,17 @@ + movl $0x80000b80, %eax + movw $0xcf8, %dx + outl %eax, %dx +- movl $0x1001, %eax + movw $0xcfc, %dx +- inb %al, %dx ++ inb %dx, %al + orb $1, %al + outb %al, %dx + + movl $0x80000b40, %eax + movw $0xcf8, %dx + outl %eax, %dx +- movl $0x1001, %eax ++ movl $0x7001, %eax + movw $0xcfc, %dx + outl %eax, %dx + movw $0x2000, %ax +- movw $0x1004, %dx ++ movw $0x7004, %dx + outw %ax, %dx +-- +1.8.1.4 + diff --git a/0287-tests-util-grub-shell.in-Fix-it-on-powerpc.patch b/0287-tests-util-grub-shell.in-Fix-it-on-powerpc.patch new file mode 100644 index 0000000..14eb2b2 --- /dev/null +++ b/0287-tests-util-grub-shell.in-Fix-it-on-powerpc.patch @@ -0,0 +1,55 @@ +From 47af30033ffebe7e3fa55fe430d95241ccc46b6c Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Fri, 12 Apr 2013 14:52:05 +0200 +Subject: [PATCH 287/364] * tests/util/grub-shell.in: Fix it on powerpc. + +--- + ChangeLog | 4 ++++ + tests/util/grub-shell.in | 9 +++++++-- + 2 files changed, 11 insertions(+), 2 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 1c77abf..109bb4c 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,9 @@ + 2013-04-12 Vladimir Serbinenko + ++ * tests/util/grub-shell.in: Fix it on powerpc. ++ ++2013-04-12 Vladimir Serbinenko ++ + Turn off QEMU ACPI-way since new releases don't have shutdown port + anymore. + +diff --git a/tests/util/grub-shell.in b/tests/util/grub-shell.in +index c6d1cd7..e467b4a 100644 +--- a/tests/util/grub-shell.in ++++ b/tests/util/grub-shell.in +@@ -198,8 +198,13 @@ cfgfile=`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1 + cat <${cfgfile} + grubshell=yes + insmod serial ++EOF ++if [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = powerpc-ieee1275 ]; then ++ echo insmod escc >>${cfgfile} ++fi ++cat <>${cfgfile} + serial ${serial_port} +-terminfo serial_${serial_port} dumb ++terminfo -g 255x255 serial_${serial_port} dumb + terminal_input serial_${serial_port} + terminal_output serial_${serial_port} + EOF +@@ -228,7 +233,7 @@ echo "${halt_cmd}" >>${cfgfile} + + isofile=`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1 + if [ x$boot != xnet ]; then +- pkgdatadir="@builddir@" sh "@builddir@/grub-mkrescue" "--grub-mkimage=${builddir}/grub-mkimage" "--output=${isofile}" "--override-directory=${builddir}/grub-core" \ ++ pkgdatadir="@builddir@" sh "@builddir@/grub-mkrescue" "--grub-mkimage=${builddir}/grub-mkimage" "--grub-render-label=${builddir}/grub-render-label" "--output=${isofile}" "--override-directory=${builddir}/grub-core" \ + --rom-directory="${rom_directory}" \ + "/boot/grub/grub.cfg=${cfgfile}" "/boot/grub/testcase.cfg=${source}" \ + ${files} >/dev/null 2>&1 +-- +1.8.1.4 + diff --git a/0288-Disable-partmap-check-on-i386-ieee1275-due-to-openfi.patch b/0288-Disable-partmap-check-on-i386-ieee1275-due-to-openfi.patch new file mode 100644 index 0000000..2ec7102 --- /dev/null +++ b/0288-Disable-partmap-check-on-i386-ieee1275-due-to-openfi.patch @@ -0,0 +1,41 @@ +From 2afcbe8d422beb164190383d6c22dc3115d31bfd Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Fri, 12 Apr 2013 17:51:43 +0200 +Subject: [PATCH 288/364] Disable partmap check on i386-ieee1275 due to + openfirmware issues. + +--- + ChangeLog | 4 ++++ + tests/partmap_test.in | 2 ++ + 2 files changed, 6 insertions(+) + +diff --git a/ChangeLog b/ChangeLog +index 109bb4c..1f6ad7c 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,9 @@ + 2013-04-12 Vladimir Serbinenko + ++ Disable partmap check on i386-ieee1275 due to openfirmware issues. ++ ++2013-04-12 Vladimir Serbinenko ++ + * tests/util/grub-shell.in: Fix it on powerpc. + + 2013-04-12 Vladimir Serbinenko +diff --git a/tests/partmap_test.in b/tests/partmap_test.in +index 8d68a28..f667f86 100644 +--- a/tests/partmap_test.in ++++ b/tests/partmap_test.in +@@ -69,6 +69,8 @@ case "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" in + i386-ieee1275) + disk=ieee1275/d + qemudisk=hdb ++ # QEMU firmware has bugs which prevent it from accessing hard disk. ++ exit 0 + ;; + *) + disk=hd0 +-- +1.8.1.4 + diff --git a/0289-grub-core-net-drivers-ieee1275-ofnet.c-Don-t-attempt.patch b/0289-grub-core-net-drivers-ieee1275-ofnet.c-Don-t-attempt.patch new file mode 100644 index 0000000..4398392 --- /dev/null +++ b/0289-grub-core-net-drivers-ieee1275-ofnet.c-Don-t-attempt.patch @@ -0,0 +1,42 @@ +From 2754f0b18b723314a78d2cc8bc9d8cd4b6279e9b Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Fri, 12 Apr 2013 19:25:16 +0200 +Subject: [PATCH 289/364] * grub-core/net/drivers/ieee1275/ofnet.c: + Don't attempt to send more than buffer size. + +--- + ChangeLog | 5 +++++ + grub-core/net/drivers/ieee1275/ofnet.c | 2 +- + 2 files changed, 6 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index 1f6ad7c..ced68cc 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,10 @@ + 2013-04-12 Vladimir Serbinenko + ++ * grub-core/net/drivers/ieee1275/ofnet.c: Don't attempt to send more ++ than buffer size. ++ ++2013-04-12 Vladimir Serbinenko ++ + Disable partmap check on i386-ieee1275 due to openfirmware issues. + + 2013-04-12 Vladimir Serbinenko +diff --git a/grub-core/net/drivers/ieee1275/ofnet.c b/grub-core/net/drivers/ieee1275/ofnet.c +index 1acfb73..cd9b159 100644 +--- a/grub-core/net/drivers/ieee1275/ofnet.c ++++ b/grub-core/net/drivers/ieee1275/ofnet.c +@@ -79,7 +79,7 @@ send_card_buffer (struct grub_net_card *dev, struct grub_net_buff *pack) + + grub_memcpy (dev->txbuf, pack->data, len); + status = grub_ieee1275_write (data->handle, dev->txbuf, +- pack->tail - pack->data, &actual); ++ len, &actual); + + if (status) + return grub_error (GRUB_ERR_IO, N_("couldn't send network packet")); +-- +1.8.1.4 + diff --git a/0290-grub-core-net-http.c-Fix-bad-free.patch b/0290-grub-core-net-http.c-Fix-bad-free.patch new file mode 100644 index 0000000..74b9020 --- /dev/null +++ b/0290-grub-core-net-http.c-Fix-bad-free.patch @@ -0,0 +1,76 @@ +From 401a7131f31017fc73138d0e8c72ab92332b72c6 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Fri, 12 Apr 2013 20:17:53 +0200 +Subject: [PATCH 290/364] * grub-core/net/http.c: Fix bad free. + +--- + ChangeLog | 4 ++++ + grub-core/net/http.c | 15 ++++++++++++--- + 2 files changed, 16 insertions(+), 3 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index ced68cc..79563b8 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,9 @@ + 2013-04-12 Vladimir Serbinenko + ++ * grub-core/net/http.c: Fix bad free. ++ ++2013-04-12 Vladimir Serbinenko ++ + * grub-core/net/drivers/ieee1275/ofnet.c: Don't attempt to send more + than buffer size. + +diff --git a/grub-core/net/http.c b/grub-core/net/http.c +index a7542d1..4684f8b 100644 +--- a/grub-core/net/http.c ++++ b/grub-core/net/http.c +@@ -157,9 +157,10 @@ http_err (grub_net_tcp_socket_t sock __attribute__ ((unused)), + + if (data->sock) + grub_net_tcp_close (data->sock, GRUB_NET_TCP_ABORT); ++ data->sock = 0; + if (data->current_line) + grub_free (data->current_line); +- grub_free (data); ++ data->current_line = 0; + file->device->net->eof = 1; + file->device->net->stall = 1; + if (file->size == GRUB_FILE_SIZE_UNKNOWN) +@@ -175,6 +176,12 @@ http_receive (grub_net_tcp_socket_t sock __attribute__ ((unused)), + http_data_t data = file->data; + grub_err_t err; + ++ if (!data->sock) ++ { ++ grub_netbuff_free (nb); ++ return GRUB_ERR_NONE; ++ } ++ + while (1) + { + char *ptr = (char *) nb->data; +@@ -432,7 +439,8 @@ http_seek (struct grub_file *file, grub_off_t off) + grub_err_t err; + old_data = file->data; + /* FIXME: Reuse socket? */ +- grub_net_tcp_close (old_data->sock, GRUB_NET_TCP_ABORT); ++ if (old_data->sock) ++ grub_net_tcp_close (old_data->sock, GRUB_NET_TCP_ABORT); + old_data->sock = 0; + + while (file->device->net->packs.first) +@@ -529,7 +537,8 @@ http_packets_pulled (struct grub_file *file) + + if (!file->device->net->eof) + file->device->net->stall = 0; +- grub_net_tcp_unstall (data->sock); ++ if (data && data->sock) ++ grub_net_tcp_unstall (data->sock); + return 0; + } + +-- +1.8.1.4 + diff --git a/0291-Fix-handling-of-split-transfers.patch b/0291-Fix-handling-of-split-transfers.patch new file mode 100644 index 0000000..0773cc7 --- /dev/null +++ b/0291-Fix-handling-of-split-transfers.patch @@ -0,0 +1,203 @@ +From a79437c27655683e0d1bff3224c63839ae00455c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ale=C5=A1=20Nesrsta?= +Date: Fri, 12 Apr 2013 20:42:46 +0200 +Subject: [PATCH 291/364] Fix handling of split transfers. + +--- + ChangeLog | 4 ++++ + grub-core/bus/usb/ehci.c | 25 ++++++++++------------- + grub-core/bus/usb/usbhub.c | 50 +++++++++++++++++++++++++++++++++++++++------- + include/grub/usb.h | 4 ++-- + 4 files changed, 59 insertions(+), 24 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 79563b8..e8e4569 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,7 @@ ++2013-04-12 Aleš Nesrsta ++ ++ Fix handling of split transfers. ++ + 2013-04-12 Vladimir Serbinenko + + * grub-core/net/http.c: Fix bad free. +diff --git a/grub-core/bus/usb/ehci.c b/grub-core/bus/usb/ehci.c +index e902fcd..18b12b2 100644 +--- a/grub-core/bus/usb/ehci.c ++++ b/grub-core/bus/usb/ehci.c +@@ -798,7 +798,7 @@ grub_ehci_pci_iter (grub_pci_device_t dev, grub_pci_id_t pciid, + /* Set ownership of root hub ports to EHCI */ + grub_ehci_oper_write32 (e, GRUB_EHCI_CONFIG_FLAG, GRUB_EHCI_CF_EHCI_OWNER); + +- /* Enable asynchronous list */ ++ /* Enable both lists */ + grub_ehci_oper_write32 (e, GRUB_EHCI_COMMAND, + GRUB_EHCI_CMD_AS_ENABL + | GRUB_EHCI_CMD_PS_ENABL +@@ -942,9 +942,9 @@ grub_ehci_setup_qh (grub_ehci_qh_t qh, grub_usb_transfer_t transfer) + * SplitCompletionMask - AFAIK it is ignored in asynchronous list, + * InterruptScheduleMask - AFAIK it should be zero in async. list */ + ep_cap |= GRUB_EHCI_MULT_THREE; +- ep_cap |= (transfer->dev->port << GRUB_EHCI_DEVPORT_OFF) ++ ep_cap |= (transfer->dev->split_hubport << GRUB_EHCI_DEVPORT_OFF) + & GRUB_EHCI_DEVPORT_MASK; +- ep_cap |= (transfer->dev->hubaddr << GRUB_EHCI_HUBADDR_OFF) ++ ep_cap |= (transfer->dev->split_hubaddr << GRUB_EHCI_HUBADDR_OFF) + & GRUB_EHCI_HUBADDR_MASK; + if (transfer->dev->speed == GRUB_USB_SPEED_LOW + && transfer->type != GRUB_USB_TRANSACTION_TYPE_CONTROL) +@@ -1261,16 +1261,6 @@ grub_ehci_setup_transfer (grub_usb_controller_t dev, + /* XXX: Fix it: Currently we don't do anything to restart EHCI */ + return GRUB_USB_ERR_INTERNAL; + +- /* Check if transfer is not high speed and connected to root hub. +- * It should not happened but... */ +- if ((transfer->dev->speed != GRUB_USB_SPEED_HIGH) +- && !transfer->dev->hubaddr) +- { +- grub_error (GRUB_USB_ERR_BADDEVICE, +- "FULL/LOW speed device on EHCI port!?!"); +- return GRUB_USB_ERR_BADDEVICE; +- } +- + /* Allocate memory for controller transfer data. */ + cdata = grub_malloc (sizeof (*cdata)); + if (!cdata) +@@ -1887,13 +1877,18 @@ grub_ehci_fini_hw (int noreturn __attribute__ ((unused))) + /* We should disable all EHCI HW to prevent any DMA access etc. */ + for (e = ehci; e; e = e->next) + { ++ /* Disable both lists */ ++ grub_ehci_oper_write32 (e, GRUB_EHCI_COMMAND, ++ ~(GRUB_EHCI_CMD_AS_ENABL | GRUB_EHCI_CMD_PS_ENABL) ++ & grub_ehci_oper_read32 (e, GRUB_EHCI_COMMAND)); ++ + /* Check if EHCI is halted and halt it if not */ + if (grub_ehci_halt (e) != GRUB_USB_ERR_NONE) +- grub_error (GRUB_ERR_TIMEOUT, "restore_hw: EHCI halt timeout"); ++ grub_error (GRUB_ERR_TIMEOUT, "fini_hw: EHCI halt timeout"); + + /* Reset EHCI */ + if (grub_ehci_reset (e) != GRUB_USB_ERR_NONE) +- grub_error (GRUB_ERR_TIMEOUT, "restore_hw: EHCI reset timeout"); ++ grub_error (GRUB_ERR_TIMEOUT, "fini_hw: EHCI reset timeout"); + } + + return GRUB_USB_ERR_NONE; +diff --git a/grub-core/bus/usb/usbhub.c b/grub-core/bus/usb/usbhub.c +index 6fc9d02..e3b7d40 100644 +--- a/grub-core/bus/usb/usbhub.c ++++ b/grub-core/bus/usb/usbhub.c +@@ -49,7 +49,7 @@ static grub_usb_controller_dev_t grub_usb_list; + static grub_usb_device_t + grub_usb_hub_add_dev (grub_usb_controller_t controller, + grub_usb_speed_t speed, +- int port, int hubaddr) ++ int split_hubport, int split_hubaddr) + { + grub_usb_device_t dev; + int i; +@@ -63,8 +63,8 @@ grub_usb_hub_add_dev (grub_usb_controller_t controller, + + dev->controller = *controller; + dev->speed = speed; +- dev->port = port; +- dev->hubaddr = hubaddr; ++ dev->split_hubport = split_hubport; ++ dev->split_hubaddr = split_hubaddr; + + err = grub_usb_device_initialize (dev); + if (err) +@@ -108,8 +108,8 @@ grub_usb_hub_add_dev (grub_usb_controller_t controller, + + grub_dprintf ("usb", "Added new usb device: %p, addr=%d\n", + dev, i); +- grub_dprintf ("usb", "speed=%d, port=%d, hubaddr=%d\n", +- speed, port, hubaddr); ++ grub_dprintf ("usb", "speed=%d, split_hubport=%d, split_hubaddr=%d\n", ++ speed, split_hubport, split_hubaddr); + + /* Wait "recovery interval", spec. says 2ms */ + grub_millisleep (2); +@@ -219,7 +219,12 @@ attach_root_port (struct grub_usb_hub *hub, int portno, + grub_boot_time ("Port enabled"); + + /* Enable the port and create a device. */ +- dev = grub_usb_hub_add_dev (hub->controller, speed, portno, 0); ++ /* High speed device needs not transaction translation ++ and full/low speed device cannot be connected to EHCI root hub ++ and full/low speed device connected to OHCI/UHCI needs not ++ transaction translation - e.g. hubport and hubaddr should be ++ always none (zero) for any device connected to any root hub. */ ++ dev = grub_usb_hub_add_dev (hub->controller, speed, 0, 0); + hub->controller->dev->pending_reset = 0; + npending--; + if (! dev) +@@ -593,6 +598,8 @@ poll_nonroot_hub (grub_usb_device_t dev) + { + grub_usb_speed_t speed; + grub_usb_device_t next_dev; ++ int split_hubport = 0; ++ int split_hubaddr = 0; + + /* Determine the device speed. */ + if (status & GRUB_USB_HUB_STATUS_PORT_LOWSPEED) +@@ -608,8 +615,37 @@ poll_nonroot_hub (grub_usb_device_t dev) + /* Wait a recovery time after reset, spec. says 10ms */ + grub_millisleep (10); + ++ /* Find correct values for SPLIT hubport and hubaddr */ ++ if (speed == GRUB_USB_SPEED_HIGH) ++ { ++ /* HIGH speed device needs not transaction translation */ ++ split_hubport = 0; ++ split_hubaddr = 0; ++ } ++ else ++ /* FULL/LOW device needs hub port and hub address ++ for transaction translation (if connected to EHCI) */ ++ if (dev->speed == GRUB_USB_SPEED_HIGH) ++ { ++ /* This port is the first FULL/LOW speed port ++ in the chain from root hub. Attached device ++ should use its port number and hub address */ ++ split_hubport = i; ++ split_hubaddr = dev->addr; ++ } ++ else ++ { ++ /* This port is NOT the first FULL/LOW speed port ++ in the chain from root hub. Attached device ++ should use values inherited from some parent ++ HIGH speed hub - if any. */ ++ split_hubport = dev->split_hubport; ++ split_hubaddr = dev->split_hubaddr; ++ } ++ + /* Add the device and assign a device address to it. */ +- next_dev = grub_usb_hub_add_dev (&dev->controller, speed, i, dev->addr); ++ next_dev = grub_usb_hub_add_dev (&dev->controller, speed, ++ split_hubport, split_hubaddr); + if (dev->controller.dev->pending_reset) + { + dev->controller.dev->pending_reset = 0; +diff --git a/include/grub/usb.h b/include/grub/usb.h +index 9e2c221..1cc9942 100644 +--- a/include/grub/usb.h ++++ b/include/grub/usb.h +@@ -225,9 +225,9 @@ struct grub_usb_device + struct grub_usb_desc_endp *hub_endpoint; + + /* EHCI Split Transfer information */ +- int port; ++ int split_hubport; + +- int hubaddr; ++ int split_hubaddr; + }; + + +-- +1.8.1.4 + diff --git a/0292-grub-core-bus-usb-ehci.c-grub_ehci_fini_hw-Ignore-er.patch b/0292-grub-core-bus-usb-ehci.c-grub_ehci_fini_hw-Ignore-er.patch new file mode 100644 index 0000000..f295982 --- /dev/null +++ b/0292-grub-core-bus-usb-ehci.c-grub_ehci_fini_hw-Ignore-er.patch @@ -0,0 +1,47 @@ +From 7fa632d01cbce0bbbcceeb9823593a61f1e86820 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Fri, 12 Apr 2013 20:51:11 +0200 +Subject: [PATCH 292/364] * grub-core/bus/usb/ehci.c + (grub_ehci_fini_hw): Ignore errors, not much we can do about it + anyway. + +--- + ChangeLog | 5 +++++ + grub-core/bus/usb/ehci.c | 6 ++---- + 2 files changed, 7 insertions(+), 4 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index e8e4569..0d5c836 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,8 @@ ++2013-04-12 Vladimir Serbinenko ++ ++ * grub-core/bus/usb/ehci.c (grub_ehci_fini_hw): Ignore errors, not ++ much we can do about it anyway. ++ + 2013-04-12 Aleš Nesrsta + + Fix handling of split transfers. +diff --git a/grub-core/bus/usb/ehci.c b/grub-core/bus/usb/ehci.c +index 18b12b2..d18a87f 100644 +--- a/grub-core/bus/usb/ehci.c ++++ b/grub-core/bus/usb/ehci.c +@@ -1883,12 +1883,10 @@ grub_ehci_fini_hw (int noreturn __attribute__ ((unused))) + & grub_ehci_oper_read32 (e, GRUB_EHCI_COMMAND)); + + /* Check if EHCI is halted and halt it if not */ +- if (grub_ehci_halt (e) != GRUB_USB_ERR_NONE) +- grub_error (GRUB_ERR_TIMEOUT, "fini_hw: EHCI halt timeout"); ++ grub_ehci_halt (e); + + /* Reset EHCI */ +- if (grub_ehci_reset (e) != GRUB_USB_ERR_NONE) +- grub_error (GRUB_ERR_TIMEOUT, "fini_hw: EHCI reset timeout"); ++ grub_ehci_reset (e); + } + + return GRUB_USB_ERR_NONE; +-- +1.8.1.4 + diff --git a/0293-util-grub-mkimage.c-Document-memdisk-implying-prefix.patch b/0293-util-grub-mkimage.c-Document-memdisk-implying-prefix.patch new file mode 100644 index 0000000..bee1064 --- /dev/null +++ b/0293-util-grub-mkimage.c-Document-memdisk-implying-prefix.patch @@ -0,0 +1,43 @@ +From e187799c01b0eea975059eaa28356d0909e43a19 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Fri, 12 Apr 2013 21:08:53 +0200 +Subject: [PATCH 293/364] * util/grub-mkimage.c: Document memdisk + implying --prefix. + +--- + ChangeLog | 4 ++++ + util/grub-mkimage.c | 4 +++- + 2 files changed, 7 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index 0d5c836..92cb29d 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,9 @@ + 2013-04-12 Vladimir Serbinenko + ++ * util/grub-mkimage.c: Document memdisk implying --prefix. ++ ++2013-04-12 Vladimir Serbinenko ++ + * grub-core/bus/usb/ehci.c (grub_ehci_fini_hw): Ignore errors, not + much we can do about it anyway. + +diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c +index dce2c29..80e7d81 100644 +--- a/util/grub-mkimage.c ++++ b/util/grub-mkimage.c +@@ -1710,7 +1710,9 @@ static struct argp_option options[] = { + {"memdisk", 'm', N_("FILE"), 0, + /* TRANSLATORS: "memdisk" here isn't an identifier, it can be translated. + "embed" is a verb (command description). "*/ +- N_("embed FILE as a memdisk image"), 0}, ++ N_("embed FILE as a memdisk image\n" ++ "Implies `-p (memdisk)/boot/grub' but prefix can be overridden by " ++ "later options"), 0}, + /* TRANSLATORS: "embed" is a verb (command description). "*/ + {"config", 'c', N_("FILE"), 0, N_("embed FILE as an early config"), 0}, + /* TRANSLATORS: "embed" is a verb (command description). "*/ +-- +1.8.1.4 + diff --git a/0294-Handle-Japanese-special-keys.patch b/0294-Handle-Japanese-special-keys.patch new file mode 100644 index 0000000..3466315 --- /dev/null +++ b/0294-Handle-Japanese-special-keys.patch @@ -0,0 +1,151 @@ +From f32d4a82999ed508b131f882b7f058fd5467219d Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Fri, 12 Apr 2013 22:26:38 +0200 +Subject: [PATCH 294/364] Handle Japanese special keys. Reported by: + Hiroyuki YAMAMORI. Codes supplied by: Hiroyuki YAMAMORI. + +--- + ChangeLog | 6 ++++++ + grub-core/commands/keylayouts.c | 5 ++++- + grub-core/term/at_keyboard.c | 16 +++++++++++++--- + include/grub/keyboard_layouts.h | 6 ++++-- + util/grub-mklayout.c | 11 +++++++++-- + 5 files changed, 36 insertions(+), 8 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 92cb29d..7054441 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,11 @@ + 2013-04-12 Vladimir Serbinenko + ++ Handle Japanese special keys. ++ Reported by: Hiroyuki YAMAMORI. ++ Codes supplied by: Hiroyuki YAMAMORI. ++ ++2013-04-12 Vladimir Serbinenko ++ + * util/grub-mkimage.c: Document memdisk implying --prefix. + + 2013-04-12 Vladimir Serbinenko +diff --git a/grub-core/commands/keylayouts.c b/grub-core/commands/keylayouts.c +index 6b5141c..b93ddf1 100644 +--- a/grub-core/commands/keylayouts.c ++++ b/grub-core/commands/keylayouts.c +@@ -132,6 +132,9 @@ map_key_core (int code, int status, int *alt_gr_consumed) + { + *alt_gr_consumed = 0; + ++ if (code >= GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE) ++ return 0; ++ + if (status & GRUB_TERM_STATUS_RALT) + { + if (status & (GRUB_TERM_STATUS_LSHIFT | GRUB_TERM_STATUS_RSHIFT)) +@@ -242,7 +245,7 @@ grub_cmd_keymap (struct grub_command *cmd __attribute__ ((unused)), + goto fail; + } + +- if (grub_le_to_cpu32 (version) != GRUB_KEYBOARD_LAYOUTS_VERSION) ++ if (version != grub_cpu_to_le32_compile_time (GRUB_KEYBOARD_LAYOUTS_VERSION)) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid version"); + goto fail; +diff --git a/grub-core/term/at_keyboard.c b/grub-core/term/at_keyboard.c +index b2f328f..e255d40 100644 +--- a/grub-core/term/at_keyboard.c ++++ b/grub-core/term/at_keyboard.c +@@ -97,7 +97,17 @@ static const grub_uint8_t set1_mapping[128] = + /* OLPC keys. Just mapped to normal keys. */ + /* 0x64 */ 0, GRUB_KEYBOARD_KEY_UP, + /* 0x66 */ GRUB_KEYBOARD_KEY_DOWN, GRUB_KEYBOARD_KEY_LEFT, +- /* 0x68 */ GRUB_KEYBOARD_KEY_RIGHT ++ /* 0x68 */ GRUB_KEYBOARD_KEY_RIGHT, 0, ++ /* 0x6a */ 0, 0, ++ /* 0x6c */ 0, 0, ++ /* 0x6e */ 0, 0, ++ /* 0x70 */ 0, 0, ++ /* 0x72 */ 0, GRUB_KEYBOARD_KEY_JP_RO, ++ /* 0x74 */ 0, 0, ++ /* 0x76 */ 0, 0, ++ /* 0x78 */ 0, 0, ++ /* 0x7a */ 0, 0, ++ /* 0x7c */ 0, GRUB_KEYBOARD_KEY_JP_YEN, + }; + + static const struct +@@ -163,7 +173,7 @@ static const grub_uint8_t set2_mapping[256] = + /* 0x4a */ GRUB_KEYBOARD_KEY_SLASH, GRUB_KEYBOARD_KEY_L, + /* 0x4c */ GRUB_KEYBOARD_KEY_SEMICOLON, GRUB_KEYBOARD_KEY_P, + /* 0x4e */ GRUB_KEYBOARD_KEY_DASH, 0, +- /* 0x50 */ 0, 0, ++ /* 0x50 */ 0, GRUB_KEYBOARD_KEY_JP_RO, + /* 0x52 */ GRUB_KEYBOARD_KEY_DQUOTE, 0, + /* 0x54 */ GRUB_KEYBOARD_KEY_LBRACKET, GRUB_KEYBOARD_KEY_EQUAL, + /* 0x56 */ 0, 0, +@@ -176,7 +186,7 @@ static const grub_uint8_t set2_mapping[256] = + /* 0x64 */ 0, 0, + /* 0x66 */ GRUB_KEYBOARD_KEY_BACKSPACE, 0, + /* 0x68 */ 0, GRUB_KEYBOARD_KEY_NUM1, +- /* 0x6a */ 0, GRUB_KEYBOARD_KEY_NUM4, ++ /* 0x6a */ GRUB_KEYBOARD_KEY_JP_YEN, GRUB_KEYBOARD_KEY_NUM4, + /* 0x6c */ GRUB_KEYBOARD_KEY_NUM7, 0, + /* 0x6e */ 0, 0, + /* 0x70 */ GRUB_KEYBOARD_KEY_NUMDOT, GRUB_KEYBOARD_KEY_NUM0, +diff --git a/include/grub/keyboard_layouts.h b/include/grub/keyboard_layouts.h +index 1f7213c..8d94490 100644 +--- a/include/grub/keyboard_layouts.h ++++ b/include/grub/keyboard_layouts.h +@@ -21,9 +21,9 @@ + + #define GRUB_KEYBOARD_LAYOUTS_FILEMAGIC "GRUBLAYO" + #define GRUB_KEYBOARD_LAYOUTS_FILEMAGIC_SIZE (sizeof(GRUB_KEYBOARD_LAYOUTS_FILEMAGIC) - 1) +-#define GRUB_KEYBOARD_LAYOUTS_VERSION 8 ++#define GRUB_KEYBOARD_LAYOUTS_VERSION 10 + +-#define GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE 128 ++#define GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE 160 + + struct grub_keyboard_layout + { +@@ -129,6 +129,8 @@ typedef enum grub_keyboard_key + GRUB_KEYBOARD_KEY_NUM0 = 0x62, + GRUB_KEYBOARD_KEY_NUMDOT = 0x63, + GRUB_KEYBOARD_KEY_102ND = 0x64, ++ GRUB_KEYBOARD_KEY_JP_RO = 0x87, ++ GRUB_KEYBOARD_KEY_JP_YEN = 0x89, + GRUB_KEYBOARD_KEY_LEFT_CTRL = 0xe0, + GRUB_KEYBOARD_KEY_LEFT_SHIFT = 0xe1, + GRUB_KEYBOARD_KEY_LEFT_ALT = 0xe2, +diff --git a/util/grub-mklayout.c b/util/grub-mklayout.c +index bff4dd6..e53d710 100644 +--- a/util/grub-mklayout.c ++++ b/util/grub-mklayout.c +@@ -250,7 +250,7 @@ static grub_uint8_t linux_to_usb_map[128] = { + /* 0x52 */ GRUB_KEYBOARD_KEY_NUMDOT, GRUB_KEYBOARD_KEY_NUMDOT, + /* 0x54 */ 0, 0, + /* 0x56 */ GRUB_KEYBOARD_KEY_102ND, GRUB_KEYBOARD_KEY_F11, +- /* 0x58 */ GRUB_KEYBOARD_KEY_F12, 0, ++ /* 0x58 */ GRUB_KEYBOARD_KEY_F12, GRUB_KEYBOARD_KEY_JP_RO, + /* 0x5a */ 0, 0, + /* 0x5c */ 0, 0, + /* 0x5e */ 0, 0, +@@ -261,7 +261,14 @@ static grub_uint8_t linux_to_usb_map[128] = { + /* 0x68 */ GRUB_KEYBOARD_KEY_PPAGE, GRUB_KEYBOARD_KEY_LEFT, + /* 0x6a */ GRUB_KEYBOARD_KEY_RIGHT, GRUB_KEYBOARD_KEY_END, + /* 0x6c */ GRUB_KEYBOARD_KEY_DOWN, GRUB_KEYBOARD_KEY_NPAGE, +- /* 0x6e */ GRUB_KEYBOARD_KEY_INSERT, GRUB_KEYBOARD_KEY_DELETE ++ /* 0x6e */ GRUB_KEYBOARD_KEY_INSERT, GRUB_KEYBOARD_KEY_DELETE, ++ /* 0x70 */ 0, 0, ++ /* 0x72 */ 0, GRUB_KEYBOARD_KEY_JP_RO, ++ /* 0x74 */ 0, 0, ++ /* 0x76 */ 0, 0, ++ /* 0x78 */ 0, 0, ++ /* 0x7a */ 0, 0, ++ /* 0x7c */ GRUB_KEYBOARD_KEY_JP_YEN, + }; + + static void +-- +1.8.1.4 + diff --git a/0295-Replace-stpcpy-with-grub_stpcpy-in-tools.patch b/0295-Replace-stpcpy-with-grub_stpcpy-in-tools.patch new file mode 100644 index 0000000..9b715f3 --- /dev/null +++ b/0295-Replace-stpcpy-with-grub_stpcpy-in-tools.patch @@ -0,0 +1,89 @@ +From 319cf38364d89bba622424313e0da676c83b9a07 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Fri, 12 Apr 2013 22:37:59 +0200 +Subject: [PATCH 295/364] Replace stpcpy with grub_stpcpy in tools. + +--- + ChangeLog | 4 ++++ + util/getroot.c | 4 ++-- + util/grub-fstest.c | 4 ++-- + util/grub-probe.c | 4 ++-- + 4 files changed, 10 insertions(+), 6 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 7054441..f9d5dca 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,9 @@ + 2013-04-12 Vladimir Serbinenko + ++ Replace stpcpy with grub_stpcpy in tools. ++ ++2013-04-12 Vladimir Serbinenko ++ + Handle Japanese special keys. + Reported by: Hiroyuki YAMAMORI. + Codes supplied by: Hiroyuki YAMAMORI. +diff --git a/util/getroot.c b/util/getroot.c +index f65fd1e..4ea8e65 100644 +--- a/util/getroot.c ++++ b/util/getroot.c +@@ -667,14 +667,14 @@ grub_find_root_devices_from_mountinfo (const char *dir, char **relroot) + char *ptr; + *relroot = xmalloc (strlen (entries[i].enc_root) + + 2 + strlen (dir)); +- ptr = stpcpy (*relroot, entries[i].enc_root); ++ ptr = grub_stpcpy (*relroot, entries[i].enc_root); + if (strlen (dir) > strlen (entries[i].enc_path)) + { + while (ptr > *relroot && *(ptr - 1) == '/') + ptr--; + if (dir[strlen (entries[i].enc_path)] != '/') + *ptr++ = '/'; +- ptr = stpcpy (ptr, dir + strlen (entries[i].enc_path)); ++ ptr = grub_stpcpy (ptr, dir + strlen (entries[i].enc_path)); + } + *ptr = 0; + } +diff --git a/util/grub-fstest.c b/util/grub-fstest.c +index 253dee8..aa2ef7a 100644 +--- a/util/grub-fstest.c ++++ b/util/grub-fstest.c +@@ -289,10 +289,10 @@ cmd_cmp (char *src, char *dest) + + strlen (entry->d_name)); + destnew = xmalloc (strlen (dest) + sizeof ("/") + + strlen (entry->d_name)); +- ptr = stpcpy (srcnew, src); ++ ptr = grub_stpcpy (srcnew, src); + *ptr++ = '/'; + strcpy (ptr, entry->d_name); +- ptr = stpcpy (destnew, dest); ++ ptr = grub_stpcpy (destnew, dest); + *ptr++ = '/'; + strcpy (ptr, entry->d_name); + +diff --git a/util/grub-probe.c b/util/grub-probe.c +index b66cbea..a46f0b1 100644 +--- a/util/grub-probe.c ++++ b/util/grub-probe.c +@@ -499,7 +499,7 @@ probe (const char *path, char **device_names, char delim) + { + char *tmp = xmalloc (strlen (ofpath) + sizeof ("ieee1275/")); + char *p; +- p = stpcpy (tmp, "ieee1275/"); ++ p = grub_stpcpy (tmp, "ieee1275/"); + strcpy (p, ofpath); + printf ("--hint-ieee1275='"); + print_full_name (tmp, dev); +@@ -616,7 +616,7 @@ probe (const char *path, char **device_names, char delim) + { + char *tmp = xmalloc (strlen (ofpath) + sizeof ("ieee1275/")); + char *p; +- p = stpcpy (tmp, "ieee1275/"); ++ p = grub_stpcpy (tmp, "ieee1275/"); + strcpy (p, ofpath); + print_full_name (tmp, dev); + free (tmp); +-- +1.8.1.4 + diff --git a/0296-Better-support-Apple-Intel-Macs-on-CD.patch b/0296-Better-support-Apple-Intel-Macs-on-CD.patch new file mode 100644 index 0000000..a3a27ee --- /dev/null +++ b/0296-Better-support-Apple-Intel-Macs-on-CD.patch @@ -0,0 +1,385 @@ +From 4c5f9d222491cdfcc015b52a77706a64f305c024 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sat, 13 Apr 2013 00:38:04 +0200 +Subject: [PATCH 296/364] Better support Apple Intel Macs on CD. + +--- + ChangeLog | 4 + + Makefile.util.def | 14 +++ + configure.ac | 1 + + include/grub/i386/macho.h | 8 +- + include/grub/macho.h | 7 ++ + util/grub-glue-efi.c | 219 ++++++++++++++++++++++++++++++++++++++++++++++ + util/grub-mkrescue.in | 19 ++++ + 7 files changed, 268 insertions(+), 4 deletions(-) + create mode 100644 util/grub-glue-efi.c + +diff --git a/ChangeLog b/ChangeLog +index f9d5dca..80067df 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,9 @@ + 2013-04-12 Vladimir Serbinenko + ++ Better support Apple Intel Macs on CD. ++ ++2013-04-12 Vladimir Serbinenko ++ + Replace stpcpy with grub_stpcpy in tools. + + 2013-04-12 Vladimir Serbinenko +diff --git a/Makefile.util.def b/Makefile.util.def +index a231b40..ef3c4ea 100644 +--- a/Makefile.util.def ++++ b/Makefile.util.def +@@ -776,6 +776,20 @@ program = { + }; + + program = { ++ name = grub-glue-efi; ++ mansection = 1; ++ ++ common = util/grub-glue-efi.c; ++ common = grub-core/kern/emu/argp_common.c; ++ ++ ldadd = libgrubmods.a; ++ ldadd = libgrubgcry.a; ++ ldadd = libgrubkern.a; ++ ldadd = grub-core/gnulib/libgnu.a; ++ ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; ++}; ++ ++program = { + name = grub-render-label; + mansection = 1; + +diff --git a/configure.ac b/configure.ac +index 19febfd..ca180c6 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -56,6 +56,7 @@ grub_TRANSFORM([grub-install]) + grub_TRANSFORM([grub-mkconfig]) + grub_TRANSFORM([grub-mkfont]) + grub_TRANSFORM([grub-mkimage]) ++grub_TRANSFORM([grub-glue-efi]) + grub_TRANSFORM([grub-mklayout]) + grub_TRANSFORM([grub-mkpasswd-pbkdf2]) + grub_TRANSFORM([grub-mkrelpath]) +diff --git a/include/grub/i386/macho.h b/include/grub/i386/macho.h +index 5ee9f9e..437fa03 100644 +--- a/include/grub/i386/macho.h ++++ b/include/grub/i386/macho.h +@@ -21,12 +21,12 @@ + + #include + +-#define GRUB_MACHO_CPUTYPE_IS_HOST32(x) ((x)==0x00000007) +-#define GRUB_MACHO_CPUTYPE_IS_HOST64(x) ((x)==0x01000007) ++#define GRUB_MACHO_CPUTYPE_IS_HOST32(x) ((x) == GRUB_MACHO_CPUTYPE_IA32) ++#define GRUB_MACHO_CPUTYPE_IS_HOST64(x) ((x) == GRUB_MACHO_CPUTYPE_AMD64) + #ifdef __x86_64__ +-#define GRUB_MACHO_CPUTYPE_IS_HOST_CURRENT(x) ((x)==0x01000007) ++#define GRUB_MACHO_CPUTYPE_IS_HOST_CURRENT(x) ((x) == GRUB_MACHO_CPUTYPE_AMD64) + #else +-#define GRUB_MACHO_CPUTYPE_IS_HOST_CURRENT(x) ((x)==0x00000007) ++#define GRUB_MACHO_CPUTYPE_IS_HOST_CURRENT(x) ((x) == GRUB_MACHO_CPUTYPE_IA32) + #endif + + struct grub_macho_thread32 +diff --git a/include/grub/macho.h b/include/grub/macho.h +index 21f0714..18434ff 100644 +--- a/include/grub/macho.h ++++ b/include/grub/macho.h +@@ -26,6 +26,13 @@ struct grub_macho_fat_header + grub_uint32_t magic; + grub_uint32_t nfat_arch; + } __attribute__ ((packed)); ++ ++enum ++ { ++ GRUB_MACHO_CPUTYPE_IA32 = 0x00000007, ++ GRUB_MACHO_CPUTYPE_AMD64 = 0x01000007 ++ }; ++ + #define GRUB_MACHO_FAT_MAGIC 0xcafebabe + #define GRUB_MACHO_FAT_EFI_MAGIC 0x0ef1fab9 + +diff --git a/util/grub-glue-efi.c b/util/grub-glue-efi.c +new file mode 100644 +index 0000000..47e393a +--- /dev/null ++++ b/util/grub-glue-efi.c +@@ -0,0 +1,219 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2010,2012,2013 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 ++ ++#define _GNU_SOURCE 1 ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "progname.h" ++ ++struct arguments ++{ ++ char *input32; ++ char *input64; ++ char *output; ++ int verbosity; ++}; ++ ++static struct argp_option options[] = { ++ {"input32", '3', N_("FILE"), 0, ++ N_("set input filename for 32-bit part."), 0}, ++ {"input64", '6', N_("FILE"), 0, ++ N_("set input filename for 64-bit part."), 0}, ++ {"output", 'o', N_("FILE"), 0, ++ N_("set output filename. Default is STDOUT"), 0}, ++ {"verbose", 'v', 0, 0, N_("print verbose messages."), 0}, ++ { 0, 0, 0, 0, 0, 0 } ++}; ++ ++static error_t ++argp_parser (int key, char *arg, struct argp_state *state) ++{ ++ /* Get the input argument from argp_parse, which we ++ know is a pointer to our arguments structure. */ ++ struct arguments *arguments = state->input; ++ ++ switch (key) ++ { ++ case '6': ++ arguments->input64 = xstrdup (arg); ++ break; ++ case '3': ++ arguments->input32 = xstrdup (arg); ++ break; ++ ++ case 'o': ++ arguments->output = xstrdup (arg); ++ break; ++ ++ case 'v': ++ arguments->verbosity++; ++ break; ++ ++ default: ++ return ARGP_ERR_UNKNOWN; ++ } ++ ++ return 0; ++} ++ ++static struct argp argp = { ++ options, argp_parser, N_("[OPTIONS]"), ++ N_("Glue 32-bit and 64-binary into Apple fat one."), ++ NULL, NULL, NULL ++}; ++ ++static void ++write_fat (FILE *in32, FILE *in64, FILE *out, const char *out_filename, ++ const char *name32, const char *name64) ++{ ++ struct grub_macho_fat_header head; ++ struct grub_macho_fat_arch arch32, arch64; ++ grub_uint32_t size32, size64; ++ char *buf; ++ ++ fseek (in32, 0, SEEK_END); ++ size32 = ftell (in32); ++ fseek (in32, 0, SEEK_SET); ++ fseek (in64, 0, SEEK_END); ++ size64 = ftell (in64); ++ fseek (in64, 0, SEEK_SET); ++ ++ head.magic = grub_cpu_to_le32_compile_time (GRUB_MACHO_FAT_EFI_MAGIC); ++ head.nfat_arch = grub_cpu_to_le32_compile_time (2); ++ arch32.cputype = grub_cpu_to_le32_compile_time (GRUB_MACHO_CPUTYPE_IA32); ++ arch32.cpusubtype = grub_cpu_to_le32_compile_time (3); ++ arch32.offset = grub_cpu_to_le32_compile_time (sizeof (head) ++ + sizeof (arch32) ++ + sizeof (arch64)); ++ arch32.size = grub_cpu_to_le32 (size32); ++ arch32.align = 0; ++ ++ arch64.cputype = grub_cpu_to_le32_compile_time (GRUB_MACHO_CPUTYPE_AMD64); ++ arch64.cpusubtype = grub_cpu_to_le32_compile_time (3); ++ arch64.offset = grub_cpu_to_le32 (sizeof (head) + sizeof (arch32) ++ + sizeof (arch64) + size32); ++ arch64.size = grub_cpu_to_le32 (size64); ++ arch64.align = 0; ++ if (fwrite (&head, 1, sizeof (head), out) != sizeof (head) ++ || fwrite (&arch32, 1, sizeof (arch32), out) != sizeof (arch32) ++ || fwrite (&arch64, 1, sizeof (arch64), out) != sizeof (arch64)) ++ { ++ if (out_filename) ++ grub_util_error ("cannot write to `%s': %s", ++ out_filename, strerror (errno)); ++ else ++ grub_util_error ("cannot write to the stdout: %s", strerror (errno)); ++ } ++ ++ buf = xmalloc (size32); ++ if (fread (buf, 1, size32, in32) != size32) ++ grub_util_error (_("cannot read `%s': %s"), name32, ++ strerror (errno)); ++ if (fwrite (buf, 1, size32, out) != size32) ++ { ++ if (out_filename) ++ grub_util_error ("cannot write to `%s': %s", ++ out_filename, strerror (errno)); ++ else ++ grub_util_error ("cannot write to the stdout: %s", strerror (errno)); ++ } ++ free (buf); ++ ++ buf = xmalloc (size64); ++ if (fread (buf, 1, size64, in64) != size64) ++ grub_util_error (_("cannot read `%s': %s"), name64, ++ strerror (errno)); ++ if (fwrite (buf, 1, size64, out) != size64) ++ { ++ if (out_filename) ++ grub_util_error ("cannot write to `%s': %s", ++ out_filename, strerror (errno)); ++ else ++ grub_util_error ("cannot write to the stdout: %s", strerror (errno)); ++ } ++ free (buf); ++} ++ ++int ++main (int argc, char *argv[]) ++{ ++ FILE *in32, *in64, *out; ++ struct arguments arguments; ++ ++ set_program_name (argv[0]); ++ ++ /* Check for options. */ ++ memset (&arguments, 0, sizeof (struct arguments)); ++ if (argp_parse (&argp, argc, argv, 0, 0, &arguments) != 0) ++ { ++ fprintf (stderr, "%s", _("Error in parsing command line arguments\n")); ++ exit(1); ++ } ++ ++ if (!arguments.input32 || !arguments.input64) ++ { ++ fprintf (stderr, "%s", _("Missing input file\n")); ++ exit(1); ++ } ++ ++ in32 = fopen (arguments.input32, "r"); ++ ++ if (!in32) ++ grub_util_error (_("cannot open `%s': %s"), arguments.input32, ++ strerror (errno)); ++ ++ in64 = fopen (arguments.input64, "r"); ++ if (!in64) ++ grub_util_error (_("cannot open `%s': %s"), arguments.input64, ++ strerror (errno)); ++ ++ if (arguments.output) ++ out = fopen (arguments.output, "wb"); ++ else ++ out = stdout; ++ ++ if (!out) ++ { ++ grub_util_error (_("cannot open `%s': %s"), arguments.output ? : "stdout", ++ strerror (errno)); ++ } ++ ++ write_fat (in32, in64, out, arguments.output, ++ arguments.input32, arguments.input64); ++ ++ fclose (in32); ++ fclose (in64); ++ ++ if (out != stdout) ++ fclose (out); ++ ++ return 0; ++} +diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in +index 510d95f..6a38f84 100644 +--- a/util/grub-mkrescue.in ++++ b/util/grub-mkrescue.in +@@ -49,6 +49,7 @@ rom_directory= + override_dir= + grub_mkimage="${bindir}/@grub_mkimage@" + grub_render_label="${bindir}/@grub_render_label@" ++grub_glue_efi="${bindir}/@grub_glue_efi@" + label_font="${pkgdatadir}/unicode.pf2" + label_color="black" + label_bgcolor="white" +@@ -82,6 +83,7 @@ usage () { + # TRANSLATORS: xorriso is a program for creating ISOs and burning CDs + print_option_help "--xorriso=$filetrans" "$(gettext "use FILE as xorriso [optional]")" + print_option_help "--grub-mkimage=$filetrans" "$(gettext "use FILE as grub-mkimage")" ++ print_option_help "--grub-glue-efi=$filetrans" "$(gettext "use FILE as grub-glue-efi")" + print_option_help "--grub-render-label=$filetrans" "$(gettext "use FILE as grub-render-label")" + print_option_help "--label-font=$filetrans" "$(gettext "use FILE as font for label")" + print_option_help "--label-color=$(gettext "COLOR")" "$(gettext "use COLOR for label")" +@@ -160,6 +162,11 @@ do + --grub-mkimage=*) + grub_mkimage=`echo "$option" | sed 's/--grub-mkimage=//'` ;; + ++ --grub-glue-efi) ++ grub_glue_efi=`argument $option "$@"`; shift ;; ++ --grub-glue-efi=*) ++ grub_glue_efi=`echo "$option" | sed 's/--grub-glue-efi=//'` ;; ++ + --grub-render-label) + grub_render_label=`argument $option "$@"`; shift ;; + --grub-render-label=*) +@@ -359,6 +366,18 @@ if test -e "${efi64_dir}" || test -e "${efi32_dir}" || test -e "${ia64_dir}"; th + cp "${efi_dir}"/efi/boot/bootia32.efi "${efi_dir}"/efi/boot/boot.efi + fi + ++ if [ -e "${efi_dir}"/efi/boot/bootx64.efi ] || [ -e "${efi_dir}"/efi/boot/bootia32.efi ]; then ++ mkdir -p "${iso9660_dir}"/System/Library/CoreServices ++ fi ++ ++ if [ -e "${efi_dir}"/efi/boot/bootx64.efi ] && [ -e "${efi_dir}"/efi/boot/bootia32.efi ]; then ++ "$grub_glue_efi" -6 "${efi_dir}"/efi/boot/bootx64.efi -3 "${efi_dir}"/efi/boot/bootia32.efi -o "${iso9660_dir}"/System/Library/CoreServices/boot.efi ++ elif [ -e "${efi_dir}"/efi/boot/bootx64.efi ]; then ++ cp "${efi_dir}"/efi/boot/bootx64.efi "${iso9660_dir}"/System/Library/CoreServices/boot.efi ++ elif [ -e "${efi_dir}"/efi/boot/bootia32.efi ]; then ++ cp "${efi_dir}"/efi/boot/bootia32.efi "${iso9660_dir}"/System/Library/CoreServices/boot.efi ++ fi ++ + mformat -C -f 2880 -L 16 -i "${iso9660_dir}"/efi.img :: + mcopy -s -i "${iso9660_dir}"/efi.img ${efi_dir}/efi ::/ + rm -rf ${efi_dir} +-- +1.8.1.4 + diff --git a/0297-util-grub-mkrescue.in-Fix-wrong-architecture-for-ppc.patch b/0297-util-grub-mkrescue.in-Fix-wrong-architecture-for-ppc.patch new file mode 100644 index 0000000..8ab73de --- /dev/null +++ b/0297-util-grub-mkrescue.in-Fix-wrong-architecture-for-ppc.patch @@ -0,0 +1,41 @@ +From 680fda34242aa0a152bb92d20af9c4bca01a0a12 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sat, 13 Apr 2013 02:02:19 +0200 +Subject: [PATCH 297/364] * util/grub-mkrescue.in: Fix wrong + architecture for ppc dir. + +--- + ChangeLog | 4 ++++ + util/grub-mkrescue.in | 2 +- + 2 files changed, 5 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index 80067df..980dbbf 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,9 @@ + 2013-04-12 Vladimir Serbinenko + ++ * util/grub-mkrescue.in: Fix wrong architecture for ppc dir. ++ ++2013-04-12 Vladimir Serbinenko ++ + Better support Apple Intel Macs on CD. + + 2013-04-12 Vladimir Serbinenko +diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in +index 6a38f84..a244b2a 100644 +--- a/util/grub-mkrescue.in ++++ b/util/grub-mkrescue.in +@@ -286,7 +286,7 @@ if [ "${override_dir}" = "" ] ; then + process_input_dir "${loongson_dir}" mipsel-loongson + fi + if test -e "${ppc_dir}" ; then +- process_input_dir "${ppc_dir}" mipsel-loongson ++ process_input_dir "${ppc_dir}" powerpc-ieee1275 + fi + else + . "${override_dir}"/modinfo.sh +-- +1.8.1.4 + diff --git a/0298-docs-man-grub-glue-efi.h2m-Add-missing-file.patch b/0298-docs-man-grub-glue-efi.h2m-Add-missing-file.patch new file mode 100644 index 0000000..a322b1f --- /dev/null +++ b/0298-docs-man-grub-glue-efi.h2m-Add-missing-file.patch @@ -0,0 +1,39 @@ +From 8712bca2fcc73ebff8cfe4306af8a2d2db639a81 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sat, 13 Apr 2013 02:26:34 +0200 +Subject: [PATCH 298/364] * docs/man/grub-glue-efi.h2m: Add missing + file. + +--- + ChangeLog | 4 ++++ + docs/man/grub-glue-efi.h2m | 4 ++++ + 2 files changed, 8 insertions(+) + create mode 100644 docs/man/grub-glue-efi.h2m + +diff --git a/ChangeLog b/ChangeLog +index 980dbbf..a965117 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,9 @@ + 2013-04-12 Vladimir Serbinenko + ++ * docs/man/grub-glue-efi.h2m: Add missing file. ++ ++2013-04-12 Vladimir Serbinenko ++ + * util/grub-mkrescue.in: Fix wrong architecture for ppc dir. + + 2013-04-12 Vladimir Serbinenko +diff --git a/docs/man/grub-glue-efi.h2m b/docs/man/grub-glue-efi.h2m +new file mode 100644 +index 0000000..c1c6ded +--- /dev/null ++++ b/docs/man/grub-glue-efi.h2m +@@ -0,0 +1,4 @@ ++[NAME] ++grub-glue-efi \- generate a fat binary for EFI ++[DESCRIPTION] ++grub-glue-efi processes ia32 and amd64 EFI images and glues them according to Apple format. +-- +1.8.1.4 + diff --git a/0299-Fix-memory-leaks-in-ofnet.patch b/0299-Fix-memory-leaks-in-ofnet.patch new file mode 100644 index 0000000..56210a9 --- /dev/null +++ b/0299-Fix-memory-leaks-in-ofnet.patch @@ -0,0 +1,53 @@ +From 4c929bc63d926b9726b8e9a494c520432c051bc0 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sat, 13 Apr 2013 20:12:11 +0200 +Subject: [PATCH 299/364] Fix memory leaks in ofnet. Reported by: + Francesco Lavra. + +--- + ChangeLog | 5 +++++ + grub-core/net/drivers/ieee1275/ofnet.c | 8 ++++---- + 2 files changed, 9 insertions(+), 4 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index a965117..0514e73 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,8 @@ ++2013-04-13 Vladimir Serbinenko ++ ++ Fix memory leaks in ofnet. ++ Reported by: Francesco Lavra. ++ + 2013-04-12 Vladimir Serbinenko + + * docs/man/grub-glue-efi.h2m: Add missing file. +diff --git a/grub-core/net/drivers/ieee1275/ofnet.c b/grub-core/net/drivers/ieee1275/ofnet.c +index cd9b159..21b6214 100644 +--- a/grub-core/net/drivers/ieee1275/ofnet.c ++++ b/grub-core/net/drivers/ieee1275/ofnet.c +@@ -97,10 +97,7 @@ get_card_packet (struct grub_net_card *dev) + + nb = grub_netbuff_alloc (dev->mtu + 64 + 2); + if (!nb) +- { +- grub_netbuff_free (nb); +- return NULL; +- } ++ return NULL; + /* Reserve 2 bytes so that 2 + 14/18 bytes of ethernet header is divisible + by 4. So that IP header is aligned on 4 bytes. */ + grub_netbuff_reserve (nb, 2); +@@ -281,6 +278,9 @@ search_net_devices (struct grub_ieee1275_devalias *alias) + card->txbuf = grub_zalloc (card->txbufsize); + if (!card->txbuf) + { ++ grub_free (ofdata->path); ++ grub_free (ofdata); ++ grub_free (card); + grub_print_error (); + return 0; + } +-- +1.8.1.4 + diff --git a/0300-grub-core-kern-ieee1275-cmain.c-grub_ieee1275_find_o.patch b/0300-grub-core-kern-ieee1275-cmain.c-grub_ieee1275_find_o.patch new file mode 100644 index 0000000..96fb2fc --- /dev/null +++ b/0300-grub-core-kern-ieee1275-cmain.c-grub_ieee1275_find_o.patch @@ -0,0 +1,73 @@ +From e93b2affc943ee31304c9652798e88469f25ad53 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sun, 14 Apr 2013 16:52:49 +0200 +Subject: [PATCH 300/364] * grub-core/kern/ieee1275/cmain.c + (grub_ieee1275_find_options): Inline name defines used only once. + +--- + ChangeLog | 5 +++++ + grub-core/kern/ieee1275/cmain.c | 12 ++++-------- + 2 files changed, 9 insertions(+), 8 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 0514e73..9df4d1e 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,10 @@ + 2013-04-13 Vladimir Serbinenko + ++ * grub-core/kern/ieee1275/cmain.c (grub_ieee1275_find_options): ++ Inline name defines used only once. ++ ++2013-04-13 Vladimir Serbinenko ++ + Fix memory leaks in ofnet. + Reported by: Francesco Lavra. + +diff --git a/grub-core/kern/ieee1275/cmain.c b/grub-core/kern/ieee1275/cmain.c +index 789669a..5f6a6da 100644 +--- a/grub-core/kern/ieee1275/cmain.c ++++ b/grub-core/kern/ieee1275/cmain.c +@@ -43,9 +43,6 @@ grub_ieee1275_set_flag (enum grub_ieee1275_flag flag) + grub_ieee1275_flags |= (1 << flag); + } + +-#define SF "SmartFirmware(tm)" +-#define OHW "PPC Open Hack'Ware" +- + static void + grub_ieee1275_find_options (void) + { +@@ -76,7 +73,8 @@ grub_ieee1275_find_options (void) + + rc = grub_ieee1275_get_property (openprom, "CodeGen-copyright", + tmp, sizeof (tmp), 0); +- if (rc >= 0 && !grub_strncmp (tmp, SF, sizeof (SF) - 1)) ++ if (rc >= 0 && !grub_strncmp (tmp, "SmartFirmware(tm)", ++ sizeof ("SmartFirmware(tm)") - 1)) + is_smartfirmware = 1; + + rc = grub_ieee1275_get_property (root, "architecture", +@@ -191,7 +189,8 @@ grub_ieee1275_find_options (void) + if (! grub_ieee1275_finddevice ("/rom/boot-rom", &bootrom)) + { + rc = grub_ieee1275_get_property (bootrom, "model", tmp, sizeof (tmp), 0); +- if (rc >= 0 && !grub_strncmp (tmp, OHW, sizeof (OHW) - 1)) ++ if (rc >= 0 && !grub_strncmp (tmp, "PPC Open Hack'Ware", ++ sizeof ("PPC Open Hack'Ware") - 1)) + { + grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_BROKEN_OUTPUT); + grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_CANNOT_SET_COLORS); +@@ -202,9 +201,6 @@ grub_ieee1275_find_options (void) + } + } + +-#undef SF +-#undef OHW +- + void + grub_ieee1275_init (void) + { +-- +1.8.1.4 + diff --git a/0301-grub-core-disk-ieee1275-ofdisk.c-Iterate-over-bootpa.patch b/0301-grub-core-disk-ieee1275-ofdisk.c-Iterate-over-bootpa.patch new file mode 100644 index 0000000..228088d --- /dev/null +++ b/0301-grub-core-disk-ieee1275-ofdisk.c-Iterate-over-bootpa.patch @@ -0,0 +1,118 @@ +From 595ef9fc233b0cf6b4c07c02acce3f61c9a7b947 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sun, 14 Apr 2013 16:55:20 +0200 +Subject: [PATCH 301/364] * grub-core/disk/ieee1275/ofdisk.c: Iterate + over bootpath even if it would be otherwise excluded. + +--- + ChangeLog | 7 +++++- + grub-core/disk/ieee1275/ofdisk.c | 49 +++++++++++++++++++++++++++++++++++++--- + 2 files changed, 52 insertions(+), 4 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 9df4d1e..1088061 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,4 +1,9 @@ +-2013-04-13 Vladimir Serbinenko ++2013-04-14 Vladimir Serbinenko ++ ++ * grub-core/disk/ieee1275/ofdisk.c: Iterate over bootpath even if it ++ would be otherwise excluded. ++ ++2013-04-14 Vladimir Serbinenko + + * grub-core/kern/ieee1275/cmain.c (grub_ieee1275_find_options): + Inline name defines used only once. +diff --git a/grub-core/disk/ieee1275/ofdisk.c b/grub-core/disk/ieee1275/ofdisk.c +index 1d4de90..bebf777 100644 +--- a/grub-core/disk/ieee1275/ofdisk.c ++++ b/grub-core/disk/ieee1275/ofdisk.c +@@ -31,6 +31,7 @@ static grub_ieee1275_ihandle_t last_ihandle; + struct ofdisk_hash_ent + { + char *devpath; ++ int is_boot; + /* Pointer to shortest available name on nodes representing canonical names, + otherwise NULL. */ + const char *shortest; +@@ -69,13 +70,12 @@ ofdisk_hash_add_real (char *devpath) + struct ofdisk_hash_ent *p; + struct ofdisk_hash_ent **head = &ofdisk_hash[ofdisk_hash_fn(devpath)]; + +- p = grub_malloc(sizeof (*p)); ++ p = grub_zalloc (sizeof (*p)); + if (!p) + return NULL; + + p->devpath = devpath; + p->next = *head; +- p->shortest = 0; + *head = p; + return p; + } +@@ -267,7 +267,8 @@ grub_ofdisk_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data, + } + } + +- if (grub_strncmp (ent->shortest, "cdrom", 5) == 0) ++ if (grub_strncmp (ent->shortest, "cdrom", 5) == 0 ++ || ent->is_boot) + continue; + + { +@@ -491,9 +492,51 @@ static struct grub_disk_dev grub_ofdisk_dev = + .next = 0 + }; + ++static void ++insert_bootpath (void) ++{ ++ char *bootpath; ++ grub_ssize_t bootpath_size; ++ char *type; ++ ++ if (grub_ieee1275_get_property_length (grub_ieee1275_chosen, "bootpath", ++ &bootpath_size) ++ || bootpath_size <= 0) ++ { ++ /* Should never happen. */ ++ grub_printf ("/chosen/bootpath property missing!\n"); ++ return; ++ } ++ ++ bootpath = (char *) grub_malloc ((grub_size_t) bootpath_size + 64); ++ if (! bootpath) ++ { ++ grub_print_error (); ++ return; ++ } ++ grub_ieee1275_get_property (grub_ieee1275_chosen, "bootpath", bootpath, ++ (grub_size_t) bootpath_size + 1, 0); ++ bootpath[bootpath_size] = '\0'; ++ ++ /* Transform an OF device path to a GRUB path. */ ++ ++ type = grub_ieee1275_get_device_type (bootpath); ++ if (!(type && grub_strcmp (type, "network") == 0)) ++ { ++ struct ofdisk_hash_ent *op; ++ char *device = grub_ieee1275_get_devname (bootpath); ++ op = ofdisk_hash_add (device, NULL); ++ op->is_boot = 1; ++ } ++ grub_free (type); ++ grub_free (bootpath); ++} ++ + void + grub_ofdisk_init (void) + { ++ insert_bootpath (); ++ + grub_disk_dev_register (&grub_ofdisk_dev); + } + +-- +1.8.1.4 + diff --git a/0302-Allow-IEEE1275-ports-on-path-even-if-it-wasn-t-detec.patch b/0302-Allow-IEEE1275-ports-on-path-even-if-it-wasn-t-detec.patch new file mode 100644 index 0000000..cf95120 --- /dev/null +++ b/0302-Allow-IEEE1275-ports-on-path-even-if-it-wasn-t-detec.patch @@ -0,0 +1,186 @@ +From 8a592c562319ba4c802fa97605ef18bb8bddd112 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sun, 14 Apr 2013 17:01:31 +0200 +Subject: [PATCH 302/364] Allow IEEE1275 ports on path even if it wasn't + detected automatically. Needed on OpenBIOS due to incomplete device + tree. + +--- + ChangeLog | 5 +++ + grub-core/term/ieee1275/serial.c | 78 ++++++++++++++++++++++++++-------------- + grub-core/term/serial.c | 16 +++++++++ + include/grub/ieee1275/console.h | 3 ++ + 4 files changed, 76 insertions(+), 26 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 1088061..df9e300 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,10 @@ + 2013-04-14 Vladimir Serbinenko + ++ Allow IEEE1275 ports on path even if it wasn't detected automatically. ++ Needed on OpenBIOS due to incomplete device tree. ++ ++2013-04-14 Vladimir Serbinenko ++ + * grub-core/disk/ieee1275/ofdisk.c: Iterate over bootpath even if it + would be otherwise excluded. + +diff --git a/grub-core/term/ieee1275/serial.c b/grub-core/term/ieee1275/serial.c +index cda97d0..9e71ca4 100644 +--- a/grub-core/term/ieee1275/serial.c ++++ b/grub-core/term/ieee1275/serial.c +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include + + #define IEEE1275_IHANDLE_INVALID ((grub_ieee1275_cell_t) 0) + +@@ -216,11 +217,59 @@ dev_iterate (struct grub_ieee1275_devalias *alias) + return 0; + } + ++static const char * ++add_port (struct ofserial_hash_ent *ent) ++{ ++ struct grub_serial_port *port; ++ char *ptr; ++ grub_err_t err; ++ ++ if (!ent->shortest) ++ return NULL; ++ ++ port = grub_zalloc (sizeof (*port)); ++ if (!port) ++ return NULL; ++ port->name = grub_malloc (sizeof ("ieee1275/") ++ + grub_strlen (ent->shortest)); ++ port->elem = ent; ++ if (!port->name) ++ return NULL; ++ ptr = grub_stpcpy (port->name, "ieee1275/"); ++ grub_strcpy (ptr, ent->shortest); ++ ++ port->driver = &grub_ofserial_driver; ++ err = grub_serial_config_defaults (port); ++ if (err) ++ grub_print_error (); ++ ++ grub_serial_register (port); ++ ++ return port->name; ++} ++ ++const char * ++grub_ofserial_add_port (const char *path) ++{ ++ struct ofserial_hash_ent *ent; ++ char *name = grub_strdup (path); ++ char *can = grub_strdup (path); ++ ++ if (!name || ! can) ++ { ++ grub_free (name); ++ grub_free (can); ++ return NULL; ++ } ++ ++ ent = ofserial_hash_add (name, can); ++ return add_port (ent); ++} ++ + void + grub_ofserial_init (void) + { + unsigned i; +- grub_err_t err; + struct grub_ieee1275_devalias alias; + + FOR_IEEE1275_DEVALIASES(alias) +@@ -230,32 +279,9 @@ grub_ofserial_init (void) + + for (i = 0; i < ARRAY_SIZE (ofserial_hash); i++) + { +- static struct ofserial_hash_ent *ent; ++ struct ofserial_hash_ent *ent; + for (ent = ofserial_hash[i]; ent; ent = ent->next) +- { +- struct grub_serial_port *port; +- char *ptr; +- if (!ent->shortest) +- continue; +- +- port = grub_zalloc (sizeof (*port)); +- if (!port) +- return; +- port->name = grub_malloc (sizeof ("ieee1275/") +- + grub_strlen (ent->shortest)); +- port->elem = ent; +- if (!port->name) +- return; +- ptr = grub_stpcpy (port->name, "ieee1275/"); +- grub_strcpy (ptr, ent->shortest); +- +- port->driver = &grub_ofserial_driver; +- err = grub_serial_config_defaults (port); +- if (err) +- grub_print_error (); +- +- grub_serial_register (port); +- } ++ add_port (ent); + } + } + +diff --git a/grub-core/term/serial.c b/grub-core/term/serial.c +index cfcfe84..96f9d7f 100644 +--- a/grub-core/term/serial.c ++++ b/grub-core/term/serial.c +@@ -31,6 +31,9 @@ + #ifdef GRUB_MACHINE_MIPS_LOONGSON + #include + #endif ++#ifdef GRUB_MACHINE_IEEE1275 ++#include ++#endif + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -149,6 +152,19 @@ grub_serial_find (const char *name) + } + #endif + ++#ifdef GRUB_MACHINE_IEEE1275 ++ if (!port && grub_memcmp (name, "ieee1275/", sizeof ("ieee1275/") - 1) == 0) ++ { ++ name = grub_ofserial_add_port (&name[sizeof ("ieee1275/") - 1]); ++ if (!name) ++ return NULL; ++ ++ FOR_SERIAL_PORTS (port) ++ if (grub_strcmp (port->name, name) == 0) ++ break; ++ } ++#endif ++ + return port; + } + +diff --git a/include/grub/ieee1275/console.h b/include/grub/ieee1275/console.h +index e054f54..bdd98fe 100644 +--- a/include/grub/ieee1275/console.h ++++ b/include/grub/ieee1275/console.h +@@ -28,4 +28,7 @@ void grub_console_init_lately (void); + /* Finish the console system. */ + void grub_console_fini (void); + ++const char * ++grub_ofserial_add_port (const char *name); ++ + #endif /* ! GRUB_CONSOLE_MACHINE_HEADER */ +-- +1.8.1.4 + diff --git a/0303-Support-mkrescue-on-sparc64.patch b/0303-Support-mkrescue-on-sparc64.patch new file mode 100644 index 0000000..cb53124 --- /dev/null +++ b/0303-Support-mkrescue-on-sparc64.patch @@ -0,0 +1,403 @@ +From 8a02952132bdc58a643b468f28e38594d9caecfa Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sun, 14 Apr 2013 17:10:55 +0200 +Subject: [PATCH 303/364] Support mkrescue on sparc64. + +--- + ChangeLog | 4 ++ + INSTALL | 2 +- + Makefile.util.def | 1 + + grub-core/Makefile.core.def | 9 ++++ + grub-core/boot/sparc64/ieee1275/boot.S | 24 ++++++++- + util/grub-mkimage.c | 21 +++++++- + util/grub-mkrescue.in | 89 +++++++++++++++++++++++++--------- + 7 files changed, 123 insertions(+), 27 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index df9e300..4c1e28d 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,9 @@ + 2013-04-14 Vladimir Serbinenko + ++ Support mkrescue on sparc64. ++ ++2013-04-14 Vladimir Serbinenko ++ + Allow IEEE1275 ports on path even if it wasn't detected automatically. + Needed on OpenBIOS due to incomplete device tree. + +diff --git a/INSTALL b/INSTALL +index 128bf47..3333686 100644 +--- a/INSTALL ++++ b/INSTALL +@@ -45,7 +45,7 @@ need the following. + Prerequisites for make-check: + + * qemu, specifically the binary 'qemu-system-i386' +-* xorriso, for grub-mkrescue and grub-shell ++* xorriso 1.2.9 or later, for grub-mkrescue and grub-shell + + Configuring the GRUB + ==================== +diff --git a/Makefile.util.def b/Makefile.util.def +index ef3c4ea..ed7b412 100644 +--- a/Makefile.util.def ++++ b/Makefile.util.def +@@ -475,6 +475,7 @@ script = { + enable = mips_loongson; + enable = ia64_efi; + enable = powerpc_ieee1275; ++ enable = sparc64_ieee1275; + }; + + script = { +diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def +index 6aead4c..f1f1012 100644 +--- a/grub-core/Makefile.core.def ++++ b/grub-core/Makefile.core.def +@@ -283,10 +283,19 @@ image = { + + image = { + name = cdboot; ++ + i386_pc = boot/i386/pc/cdboot.S; + i386_pc_ldflags = '$(TARGET_IMG_LDFLAGS)'; + i386_pc_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x7C00'; ++ ++ sparc64_ieee1275 = boot/sparc64/ieee1275/boot.S; ++ sparc64_ieee1275_objcopyflags = '-O a.out-sunos-big'; ++ sparc64_ieee1275_ldflags = ' -Wl,-Ttext=0x4000'; ++ sparc64_ieee1275_cppflags = '-DCDBOOT=1'; ++ + objcopyflags = '-O binary'; ++ ++ enable = sparc64_ieee1275; + enable = i386_pc; + }; + +diff --git a/grub-core/boot/sparc64/ieee1275/boot.S b/grub-core/boot/sparc64/ieee1275/boot.S +index f796995..0ab9a4a 100644 +--- a/grub-core/boot/sparc64/ieee1275/boot.S ++++ b/grub-core/boot/sparc64/ieee1275/boot.S +@@ -28,6 +28,7 @@ pic_base: + call boot_continue + mov %o4, CIF_REG + ++#ifndef CDBOOT + /* The offsets to these locations are defined by the + * GRUB_BOOT_MACHINE_foo macros in include/grub/sparc/ieee1275/boot.h, + * and grub-setup uses this to patch these next three values as needed. +@@ -43,9 +44,19 @@ pic_base: + . = _start + GRUB_BOOT_MACHINE_BOOT_DEVPATH + boot_path: + . = _start + GRUB_BOOT_MACHINE_KERNEL_BYTE +-boot_path_end: + kernel_byte: .xword (2 << 9) ++boot_path_end: + kernel_address: .word GRUB_BOOT_MACHINE_KERNEL_ADDR ++#else ++#define boot_path (_start + 512) ++#define boot_path_end (_start + 1024) ++#include ++ ++ . = _start + 8 ++kernel_byte: .xword (2 << 9) ++kernel_size: .word 512 ++kernel_address: .word GRUB_BOOT_SPARC64_IEEE1275_IMAGE_ADDRESS ++#endif + + prom_finddev_name: .asciz "finddevice" + prom_chosen_path: .asciz "/chosen" +@@ -158,8 +169,10 @@ boot_continue: + mov GRUB_NAME_LEN, %o3 + + GET_ABS(boot_path, %o3) ++#ifndef CDBOOT + ldub [%o3], %o1 + brnz,pn %o1, bootpath_known ++#endif + + /* getprop(chosen_node, "bootpath", &buffer, buffer_size) */ + GET_ABS(prom_bootpath_name, %o2) +@@ -194,12 +207,19 @@ bootpath_known: + GET_ABS(prom_read_name, %o0) + LDUW_ABS(kernel_address, 0x00, %o2) + call prom_call_3_1_o1 ++#ifdef CDBOOT ++ LDUW_ABS(kernel_size, 0x00, %o3) ++#else + mov 512, %o3 ++#endif + + LDUW_ABS(kernel_address, 0x00, %o2) + jmpl %o2, %o7 ++#ifdef CDBOOT ++ mov CIF_REG, %o4 ++#else + nop +- ++#endif + . = _start + GRUB_BOOT_MACHINE_CODE_END + + /* the last 4 bytes in the sector 0 contain the signature */ +diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c +index 80e7d81..96279a4 100644 +--- a/util/grub-mkimage.c ++++ b/util/grub-mkimage.c +@@ -67,7 +67,8 @@ struct image_target_desc + int bigendian; + enum { + IMAGE_I386_PC, IMAGE_EFI, IMAGE_COREBOOT, +- IMAGE_SPARC64_AOUT, IMAGE_SPARC64_RAW, IMAGE_I386_IEEE1275, ++ IMAGE_SPARC64_AOUT, IMAGE_SPARC64_RAW, IMAGE_SPARC64_CDCORE, ++ IMAGE_I386_IEEE1275, + IMAGE_LOONGSON_ELF, IMAGE_QEMU, IMAGE_PPC, IMAGE_YEELOONG_FLASH, + IMAGE_FULOONG2F_FLASH, IMAGE_I386_PC_PXE, IMAGE_MIPS_ARC, + IMAGE_QEMU_MIPS_FLASH +@@ -336,6 +337,21 @@ struct image_target_desc image_targets[] = + }, + { + .dirname = "sparc64-ieee1275", ++ .names = { "sparc64-ieee1275-cdcore", NULL }, ++ .voidp_sizeof = 8, ++ .bigendian = 1, ++ .id = IMAGE_SPARC64_CDCORE, ++ .flags = PLATFORM_FLAGS_NONE, ++ .total_module_size = GRUB_KERNEL_SPARC64_IEEE1275_TOTAL_MODULE_SIZE, ++ .decompressor_compressed_size = TARGET_NO_FIELD, ++ .decompressor_uncompressed_size = TARGET_NO_FIELD, ++ .decompressor_uncompressed_addr = TARGET_NO_FIELD, ++ .section_align = 1, ++ .vaddr_offset = 0, ++ .link_addr = GRUB_KERNEL_SPARC64_IEEE1275_LINK_ADDR ++ }, ++ { ++ .dirname = "sparc64-ieee1275", + .names = { "sparc64-ieee1275-aout", NULL }, + .voidp_sizeof = 8, + .bigendian = 1, +@@ -1021,6 +1037,7 @@ generate_image (const char *dir, const char *prefix, + break; + case IMAGE_SPARC64_AOUT: + case IMAGE_SPARC64_RAW: ++ case IMAGE_SPARC64_CDCORE: + case IMAGE_I386_IEEE1275: + case IMAGE_PPC: + break; +@@ -1360,6 +1377,8 @@ generate_image (const char *dir, const char *prefix, + free (boot_path); + } + break; ++ case IMAGE_SPARC64_CDCORE: ++ break; + case IMAGE_YEELOONG_FLASH: + case IMAGE_FULOONG2F_FLASH: + { +diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in +index a244b2a..c74c8ca 100644 +--- a/util/grub-mkrescue.in ++++ b/util/grub-mkrescue.in +@@ -44,6 +44,7 @@ i386_ieee1275_dir="${libdir}/@PACKAGE@/i386-ieee1275" + efi32_dir="${libdir}/@PACKAGE@/i386-efi" + efi64_dir="${libdir}/@PACKAGE@/x86_64-efi" + ia64_dir="${libdir}/@PACKAGE@/ia64-efi" ++sparc64_dir="${libdir}/@PACKAGE@/sparc64-ieee1275" + ppc_dir="${libdir}/@PACKAGE@/powerpc-ieee1275" + rom_directory= + override_dir= +@@ -90,6 +91,7 @@ usage () { + print_option_help "--label-bgcolor=$(gettext "COLOR")" "$(gettext "use COLOR for label background")" + print_option_help "--product-name=$(gettext "STR")" "$(gettext "use STR as product")" + print_option_help "--product-version=$(gettext "STR")" "$(gettext "use STR as product version")" ++ print_option_help "--sparc-boot" "$(gettext "enable sparc boot. Disables HFS+, APM and boot as disk image for i386-pc")" + echo + gettext_printf "%s generates a bootable rescue image with specified source files, source directories, or mkisofs options listed by the output of \`%s'\n" "xorriso -as mkisofs -help" "$self" | grub_fmt + echo +@@ -99,6 +101,8 @@ usage () { + gettext "Mail xorriso support requests to ."; echo + } + ++system_area=auto ++ + # Check the arguments. + while test $# -gt 0 + do +@@ -147,6 +151,9 @@ do + export PATH + ;; + ++ --sparc-boot) ++ system_area=sparc64 ;; ++ + --product-name) + product_name=`argument $option "$@"`; shift ;; + --product-name=*) +@@ -230,9 +237,7 @@ make_image () + + gettext_printf "Enabling %s support ...\n" "$2" + +- memdisk_img="`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"`" || exit 1 +- memdisk_dir="`mktemp -d "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"`" || exit 1 +- mkdir -p "${memdisk_dir}/boot/grub" ++ load_cfg="`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"`" + + (cat << EOF + search --fs-uuid --set=root ${iso_uuid} +@@ -240,18 +245,36 @@ set prefix=(\${root})/boot/grub + EOF + for i in $(cat "${source_directory}/partmap.lst") ${modules} ; do + echo "insmod $i" +- done ; \ +- echo "source \$prefix/grub.cfg") \ +- > "${memdisk_dir}/boot/grub/grub.cfg" +- +- (cd "${memdisk_dir}"; tar -cf - boot) > "${memdisk_img}" +- 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}" ++ done ; ) > "${load_cfg}" ++ ++ "$grub_mkimage" -O ${platform} -d "${source_directory}" -c "${load_cfg}" -o "$3" \ ++ search iso9660 $4 ++ rm -rf "${load_cfg}" ++} ++ ++make_image_fwdisk () ++{ ++ source_directory="$1" ++ platform=$2 ++ if ! test -e "${source_directory}"; then ++ return; ++ fi ++ ++ gettext_printf "Enabling %s support ...\n" "$2" ++ ++ "$grub_mkimage" -O ${platform} -d "${source_directory}" -p '()/boot/grub' -o "$3" \ ++ iso9660 $4 + } + + if [ "${override_dir}" = "" ] ; then ++ if [ "$system_area" = auto ]; then ++ if test -e "${pc_dir}" || test -e "${ppc_dir}" \ ++ || test -e "${efi32_dir}" || test -e "${efi64_dir}"; then ++ system_area=common; ++ elif test -e "${sparc64_dir}" ; then ++ system_area=sparc64; ++ fi ++ fi + if test -e "${multiboot_dir}" ; then + process_input_dir "${multiboot_dir}" i386-multiboot + fi +@@ -288,6 +311,9 @@ if [ "${override_dir}" = "" ] ; then + if test -e "${ppc_dir}" ; then + process_input_dir "${ppc_dir}" powerpc-ieee1275 + fi ++ if test -e "${sparc64_dir}" ; then ++ process_input_dir "${sparc64_dir}" sparc64-ieee1275 ++ fi + else + . "${override_dir}"/modinfo.sh + process_input_dir "${override_dir}" ${grub_modinfo_target_cpu}-${grub_modinfo_platform} +@@ -303,18 +329,20 @@ else + loongson_dir= + ppc_dir= + i386_ieee1275_dir= ++ sparc64_dir= + case "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" in + 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}" ;; ++ i386-pc) pc_dir="${override_dir}"; system_area=common;; ++ i386-efi) efi32_dir="${override_dir}"; system_area=common ;; ++ x86_64-efi) efi64_dir="${override_dir}"; system_area=common ;; + ia64-efi) ia64_dir="${override_dir}" ;; + mipsel-qemu_mips) mipsel_qemu_dir="${override_dir}" ;; + mipsel-loongson) loongson_dir="${override_dir}" ;; + mips-qemu_mips) mips_qemu_dir="${override_dir}" ;; +- powerpc-ieee1275) ppc_dir="${override_dir}" ;; ++ powerpc-ieee1275) ppc_dir="${override_dir}"; system_area=common ;; ++ sparc64-ieee1275) sparc64_dir="${override_dir}"; system_area=sparc64 ;; + i386-ieee1275) i386_ieee1275_dir="${override_dir}" ;; + esac + fi +@@ -342,14 +370,16 @@ if test -e "${pc_dir}" ; then + + rm -f "${core_img}" + +- grub_mkisofs_arguments="${grub_mkisofs_arguments} -b boot/grub/i386-pc/eltorito.img -no-emul-boot -boot-info-table \ +- --embedded-boot ${embed_img}" ++ grub_mkisofs_arguments="${grub_mkisofs_arguments} -b boot/grub/i386-pc/eltorito.img -no-emul-boot -boot-load-size 4 -boot-info-table" ++ if [ "$system_area" = common ]; then ++ grub_mkisofs_arguments="--embedded-boot ${embed_img}" ++ fi + fi + + # build multiboot core.img + make_image "${multiboot_dir}" i386-multiboot "${iso9660_dir}/boot/multiboot.img" "pata ahci at_keyboard" + +-make_image "${i386_ieee1275_dir}" i386-ieee1275 "${iso9660_dir}/boot/ofwx86.elf" "" ++make_image_fwdisk "${i386_ieee1275_dir}" i386-ieee1275 "${iso9660_dir}/boot/ofwx86.elf" "" + + if test -e "${efi64_dir}" || test -e "${efi32_dir}" || test -e "${ia64_dir}"; then + efi_dir=`mktemp -d "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1 +@@ -384,7 +414,7 @@ if test -e "${efi64_dir}" || test -e "${efi32_dir}" || test -e "${ia64_dir}"; th + grub_mkisofs_arguments="${grub_mkisofs_arguments} --efi-boot efi.img" + fi + +-make_image "${ppc_dir}" powerpc-ieee1275 "${iso9660_dir}/boot/powerpc.elf" "" ++make_image_fwdisk "${ppc_dir}" powerpc-ieee1275 "${iso9660_dir}/boot/powerpc.elf" "" + if [ -e "${iso9660_dir}"/System/Library/CoreServices/boot.efi ] || [ -e "${iso9660_dir}/boot/powerpc.elf" ]; then + mkdir -p "${iso9660_dir}"/System/Library/CoreServices + touch "${iso9660_dir}/mach_kernel" +@@ -402,20 +432,32 @@ if [ -e "${iso9660_dir}"/System/Library/CoreServices/boot.efi ] || [ -e "${iso96 + EOF + "$grub_render_label" -f "$label_font" -b "$label_bgcolor" -c "$label_color" -t "${product_name} ${product_version}" -o "${iso9660_dir}/System/Library/CoreServices/.disk_label" + echo "${product_name} ${product_version}" > "${iso9660_dir}/System/Library/CoreServices/.disk_label.contentDetails" +- grub_mkisofs_arguments="${grub_mkisofs_arguments} -hfsplus -hfsplus-file-creator-type chrp tbxj /System/Library/CoreServices/.disk_label" ++ if [ "$system_area" = common ]; then ++ grub_mkisofs_arguments="${grub_mkisofs_arguments} -hfsplus -hfsplus-file-creator-type chrp tbxj /System/Library/CoreServices/.disk_label" ++ fi + fi + + if [ -e "${iso9660_dir}/boot/powerpc.elf" ] ; then + cp "${ppc_dir}/grub.chrp" "${iso9660_dir}"/System/Library/CoreServices/BootX + cp "${iso9660_dir}/boot/powerpc.elf" "${iso9660_dir}"/System/Library/CoreServices/grub.elf + # FIXME: add PreP +- grub_mkisofs_arguments="${grub_mkisofs_arguments} -hfsplus-file-creator-type chrp tbxi /System/Library/CoreServices/BootX -hfs-bless-by p /System/Library/CoreServices -sysid PPC" ++ if [ "$system_area" = common ]; then ++ grub_mkisofs_arguments="${grub_mkisofs_arguments} -hfsplus-file-creator-type chrp tbxi /System/Library/CoreServices/BootX -hfs-bless-by p /System/Library/CoreServices" ++ fi ++ grub_mkisofs_arguments="${grub_mkisofs_arguments} -sysid PPC" + fi + +-if [ -e "${iso9660_dir}"/System/Library/CoreServices/boot.efi ]; then ++if [ -e "${iso9660_dir}"/System/Library/CoreServices/boot.efi ] && [ "$system_area" = common ]; then + grub_mkisofs_arguments="${grub_mkisofs_arguments} -hfs-bless-by i /System/Library/CoreServices/boot.efi" + fi + ++make_image_fwdisk "${sparc64_dir}" sparc64-ieee1275-cdcore "${iso9660_dir}/boot/grub/sparc64-ieee1275/core.img" "" ++if [ -e "${iso9660_dir}"/boot/grub/sparc64-ieee1275/core.img ] && [ "$system_area" = sparc64 ]; then ++ sysarea_img="`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"`" || exit 1 ++ dd if=/dev/zero count=1 bs=512 | cat - "${sparc64_dir}"/cdboot.img > "$sysarea_img" ++ grub_mkisofs_arguments="${grub_mkisofs_arguments} -G $sysarea_img -B , --grub2-sparc-core /boot/grub/sparc64-ieee1275/core.img" ++fi ++ + make_image "${mipsel_qemu_dir}" mipsel-qemu_mips-elf "${iso9660_dir}/boot/mipsel-qemu_mips.elf" "pata" + if [ -e "${iso9660_dir}/boot/mipsel-qemu_mips.elf" ] && [ -d "${rom_directory}" ]; then + cp "${iso9660_dir}/boot/mipsel-qemu_mips.elf" "${rom_directory}/mipsel-qemu_mips.elf" +@@ -452,6 +494,7 @@ fi + "${xorriso}" -as mkisofs -graft-points ${grub_mkisofs_arguments} --protective-msdos-label -o "${output_image}" -r "${iso9660_dir}" --sort-weight 0 / --sort-weight 1 /boot ${source} + rm -rf "${iso9660_dir}" + ++rm -f "${sysarea_img}" + rm -f "${embed_img}" + + exit 0 +-- +1.8.1.4 + diff --git a/0304-Support-grub-shell-on-sparc64.patch b/0304-Support-grub-shell-on-sparc64.patch new file mode 100644 index 0000000..8474808 --- /dev/null +++ b/0304-Support-grub-shell-on-sparc64.patch @@ -0,0 +1,48 @@ +From 33f6759ef6669f4229e21296922bfad0bf9238c5 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sun, 14 Apr 2013 17:13:58 +0200 +Subject: [PATCH 304/364] Support grub-shell on sparc64. + +--- + ChangeLog | 4 ++++ + tests/util/grub-shell.in | 10 ++++++++++ + 2 files changed, 14 insertions(+) + +diff --git a/ChangeLog b/ChangeLog +index 4c1e28d..867cc5d 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,9 @@ + 2013-04-14 Vladimir Serbinenko + ++ Support grub-shell on sparc64. ++ ++2013-04-14 Vladimir Serbinenko ++ + Support mkrescue on sparc64. + + 2013-04-14 Vladimir Serbinenko +diff --git a/tests/util/grub-shell.in b/tests/util/grub-shell.in +index e467b4a..739c300 100644 +--- a/tests/util/grub-shell.in ++++ b/tests/util/grub-shell.in +@@ -69,6 +69,16 @@ case "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" in + serial_null="-serial null" + ;; + ++ sparc64-ieee1275) ++ boot=cd ++ qemu=qemu-system-sparc64 ++ console= ++ serial_port=ieee1275/ttya ++ trim=1 ++ qemuopts="$qemuopts -no-reboot" ++ halt_cmd=reboot ++ ;; ++ + mips-qemu_mips) + boot=mips_qemu + qemu=qemu-system-mips +-- +1.8.1.4 + diff --git a/0305-tests-partmap_test.in-Skip-on-sparc64.patch b/0305-tests-partmap_test.in-Skip-on-sparc64.patch new file mode 100644 index 0000000..291695a --- /dev/null +++ b/0305-tests-partmap_test.in-Skip-on-sparc64.patch @@ -0,0 +1,44 @@ +From 3a36b768d2472c81b0f2b34f6e7fb41230b8a00a Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sun, 14 Apr 2013 17:16:32 +0200 +Subject: [PATCH 305/364] * tests/partmap_test.in: Skip on sparc64. + +--- + ChangeLog | 4 ++++ + tests/partmap_test.in | 6 ++++++ + 2 files changed, 10 insertions(+) + +diff --git a/ChangeLog b/ChangeLog +index 867cc5d..402c79f 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,9 @@ + 2013-04-14 Vladimir Serbinenko + ++ * tests/partmap_test.in: Skip on sparc64. ++ ++2013-04-14 Vladimir Serbinenko ++ + Support grub-shell on sparc64. + + 2013-04-14 Vladimir Serbinenko +diff --git a/tests/partmap_test.in b/tests/partmap_test.in +index f667f86..bc503f5 100644 +--- a/tests/partmap_test.in ++++ b/tests/partmap_test.in +@@ -66,6 +66,12 @@ case "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" in + # QEMU firmware has bugs which prevent it from accessing hard disk. + exit 0 + ;; ++ sparc64-ieee1275) ++ disk=ieee1275//pci@1fe\,0/pci-ata@5/ide0@500/disk@0 ++ qemudisk=hda ++ # QEMU firmware has bugs which prevent it from accessing hard disk. ++ exit 0 ++ ;; + i386-ieee1275) + disk=ieee1275/d + qemudisk=hdb +-- +1.8.1.4 + diff --git a/0306-tests-grub_cmd_date.in-Add-missing-exit-1.patch b/0306-tests-grub_cmd_date.in-Add-missing-exit-1.patch new file mode 100644 index 0000000..238e03e --- /dev/null +++ b/0306-tests-grub_cmd_date.in-Add-missing-exit-1.patch @@ -0,0 +1,36 @@ +From 201834f4f66fa98a6de81d9440b0493a40d7f411 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sun, 14 Apr 2013 17:19:04 +0200 +Subject: [PATCH 306/364] * tests/grub_cmd_date.in: Add missing exit 1. + +--- + ChangeLog | 4 ++++ + tests/grub_cmd_date.in | 1 + + 2 files changed, 5 insertions(+) + +diff --git a/ChangeLog b/ChangeLog +index 402c79f..60effd3 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,9 @@ + 2013-04-14 Vladimir Serbinenko + ++ * tests/grub_cmd_date.in: Add missing exit 1. ++ ++2013-04-14 Vladimir Serbinenko ++ + * tests/partmap_test.in: Skip on sparc64. + + 2013-04-14 Vladimir Serbinenko +diff --git a/tests/grub_cmd_date.in b/tests/grub_cmd_date.in +index 1c8e7e6..254fb91 100644 +--- a/tests/grub_cmd_date.in ++++ b/tests/grub_cmd_date.in +@@ -10,3 +10,4 @@ if [ $pdt -le $dtg ] && [ $dtg -le $ndt ]; then + exit 0; + fi + echo "Date not in range: $pdt <= $dtg <= $ndt" ++exit 1 +-- +1.8.1.4 + diff --git a/0307-Move-GRUB-out-of-system-area-when-using-xorriso-1.2..patch b/0307-Move-GRUB-out-of-system-area-when-using-xorriso-1.2..patch new file mode 100644 index 0000000..d3f31d1 --- /dev/null +++ b/0307-Move-GRUB-out-of-system-area-when-using-xorriso-1.2..patch @@ -0,0 +1,373 @@ +From 46aa8934bbcbc427f7424e77bead7c0c8356a138 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sun, 14 Apr 2013 18:53:14 +0200 +Subject: [PATCH 307/364] Move GRUB out of system area when using + xorriso 1.2.9 or later. + +--- + ChangeLog | 4 + + grub-core/Makefile.core.def | 13 +++ + grub-core/boot/i386/pc/boot.S | 194 +++++++++++++++++++++++++--------------- + grub-core/boot/i386/pc/cdboot.S | 5 +- + util/grub-mkrescue.in | 23 +++-- + 5 files changed, 159 insertions(+), 80 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 60effd3..fc3dd51 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,9 @@ + 2013-04-14 Vladimir Serbinenko + ++ Move GRUB out of system area when using xorriso 1.2.9 or later. ++ ++2013-04-14 Vladimir Serbinenko ++ + * tests/grub_cmd_date.in: Add missing exit 1. + + 2013-04-14 Vladimir Serbinenko +diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def +index f1f1012..459e566 100644 +--- a/grub-core/Makefile.core.def ++++ b/grub-core/Makefile.core.def +@@ -282,6 +282,19 @@ image = { + }; + + image = { ++ name = boot_hybrid; ++ i386_pc = boot/i386/pc/boot.S; ++ ++ cppflags = '-DHYBRID_BOOT=1'; ++ ++ i386_pc_ldflags = '$(TARGET_IMG_LDFLAGS)'; ++ i386_pc_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x7C00'; ++ ++ objcopyflags = '-O binary'; ++ enable = i386_pc; ++}; ++ ++image = { + name = cdboot; + + i386_pc = boot/i386/pc/cdboot.S; +diff --git a/grub-core/boot/i386/pc/boot.S b/grub-core/boot/i386/pc/boot.S +index 314f140..c0880c6 100644 +--- a/grub-core/boot/i386/pc/boot.S ++++ b/grub-core/boot/i386/pc/boot.S +@@ -28,6 +28,81 @@ + #define MSG(x) movw $x, %si; call LOCAL(message) + #define ERR(x) movw $x, %si; jmp LOCAL(error_message) + ++ .macro floppy ++part_start: ++ ++probe_values: ++ .byte 36, 18, 15, 9, 0 ++ ++LOCAL(floppy_probe): ++/* ++ * Perform floppy probe. ++ */ ++ ++ movw $probe_values - 1, %si ++ ++LOCAL(probe_loop): ++ /* reset floppy controller INT 13h AH=0 */ ++ xorw %ax, %ax ++ int $0x13 ++ ++ incw %si ++ movb (%si), %cl ++ ++ /* if number of sectors is 0, display error and die */ ++ cmpb $0, %cl ++ jne 1f ++ ++/* ++ * Floppy disk probe failure. ++ */ ++ MSG(fd_probe_error_string) ++ jmp LOCAL(general_error) ++ ++/* "Floppy" */ ++fd_probe_error_string: .asciz "Floppy" ++ ++1: ++ /* perform read */ ++ movw $GRUB_BOOT_MACHINE_BUFFER_SEG, %bx ++ movw %bx, %es ++ xorw %bx, %bx ++ movw $0x201, %ax ++ movb $0, %ch ++ movb $0, %dh ++ int $0x13 ++ ++ /* if error, jump to "LOCAL(probe_loop)" */ ++ jc LOCAL(probe_loop) ++ ++ /* %cl is already the correct value! */ ++ movb $1, %dh ++ movb $79, %ch ++ ++ jmp LOCAL(final_init) ++ .endm ++ ++ .macro scratch ++ ++ /* scratch space */ ++mode: ++ .byte 0 ++disk_address_packet: ++sectors: ++ .long 0 ++heads: ++ .long 0 ++cylinders: ++ .word 0 ++sector_start: ++ .byte 0 ++head_start: ++ .byte 0 ++cylinder_start: ++ .word 0 ++ /* more space... */ ++ .endm ++ + .file "boot.S" + + .text +@@ -51,6 +126,34 @@ start: + jmp LOCAL(after_BPB) + nop /* do I care about this ??? */ + ++#ifdef HYBRID_BOOT ++ nop ++ nop ++ nop ++ nop ++ nop ++ nop ++ nop ++ nop ++ nop ++ nop ++ nop ++ nop ++ nop ++ ++ nop ++ nop ++ nop ++ nop ++ nop ++ nop ++ nop ++ nop ++ ++ nop ++ nop ++ jmp LOCAL(after_BPB) ++#else + /* + * This space is for the BIOS parameter block!!!! Don't change + * the first jump, nor start the code anywhere but right after +@@ -59,27 +162,14 @@ start: + + . = _start + GRUB_BOOT_MACHINE_BPB_START + . = _start + 4 +- +- /* scratch space */ +-mode: +- .byte 0 +-disk_address_packet: +-sectors: +- .long 0 +-heads: +- .long 0 +-cylinders: +- .word 0 +-sector_start: +- .byte 0 +-head_start: +- .byte 0 +-cylinder_start: +- .word 0 +- /* more space... */ ++#endif ++#ifdef HYBRID_BOOT ++ floppy ++#else ++ scratch ++#endif + + . = _start + GRUB_BOOT_MACHINE_BPB_END +- + /* + * End of BIOS parameter block. + */ +@@ -87,9 +177,11 @@ cylinder_start: + kernel_address: + .word GRUB_BOOT_MACHINE_KERNEL_ADDR + ++#ifndef HYBRID_BOOT + . = _start + GRUB_BOOT_MACHINE_KERNEL_SECTOR + kernel_sector: + .long 1, 0 ++#endif + + . = _start + GRUB_BOOT_MACHINE_BOOT_DRIVE + boot_drive: +@@ -410,6 +502,11 @@ LOCAL(message): + * number here. + */ + ++#ifdef HYBRID_BOOT ++ . = _start + 0x1b0 ++kernel_sector: ++ .long 1, 0 ++#endif + . = _start + GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC + nt_magic: + .long 0 +@@ -419,62 +516,17 @@ nt_magic: + * This is where an MBR would go if on a hard disk. The code + * here isn't even referenced unless we're on a floppy. Kinda + * sneaky, huh? +- */ ++ */ + + . = _start + GRUB_BOOT_MACHINE_PART_START +-part_start: +- +-probe_values: +- .byte 36, 18, 15, 9, 0 +- +-LOCAL(floppy_probe): +-/* +- * Perform floppy probe. +- */ +- +- movw $probe_values - 1, %si +- +-LOCAL(probe_loop): +- /* reset floppy controller INT 13h AH=0 */ +- xorw %ax, %ax +- int $0x13 +- +- incw %si +- movb (%si), %cl +- +- /* if number of sectors is 0, display error and die */ +- cmpb $0, %cl +- jne 1f +- +-/* +- * Floppy disk probe failure. +- */ +- MSG(fd_probe_error_string) +- jmp LOCAL(general_error) +- +-/* "Floppy" */ +-fd_probe_error_string: .asciz "Floppy" +- +-1: +- /* perform read */ +- movw $GRUB_BOOT_MACHINE_BUFFER_SEG, %bx +- movw %bx, %es +- xorw %bx, %bx +- movw $0x201, %ax +- movb $0, %ch +- movb $0, %dh +- int $0x13 + +- /* if error, jump to "LOCAL(probe_loop)" */ +- jc LOCAL(probe_loop) +- +- /* %cl is already the correct value! */ +- movb $1, %dh +- movb $79, %ch +- +- jmp LOCAL(final_init) ++#ifndef HYBRID_BOOT ++ floppy ++#else ++ scratch ++#endif + + . = _start + GRUB_BOOT_MACHINE_PART_END +- ++ + /* the last 2 bytes in the sector 0 contain the signature */ + .word GRUB_BOOT_MACHINE_SIGNATURE +diff --git a/grub-core/boot/i386/pc/cdboot.S b/grub-core/boot/i386/pc/cdboot.S +index d939835..92df7c7 100644 +--- a/grub-core/boot/i386/pc/cdboot.S ++++ b/grub-core/boot/i386/pc/cdboot.S +@@ -93,11 +93,12 @@ LOCAL(read_cdrom): + pushw $CDBLK_LENG + + /* Block number. */ ++ incl %esi + pushl %eax + pushl %esi + + /* Buffer address. */ +- pushw $((DATA_ADDR - 0x400)>> 4) ++ pushw $((DATA_ADDR - 0x200)>> 4) + pushl %eax + pushw $0x10 + +@@ -167,6 +168,6 @@ err_noboot_msg: + err_cdfail_msg: + .ascii "cdrom read fails\0" + +- . = start + 0x1FF ++ . = start + 0x7FF + + .byte 0 +diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in +index c74c8ca..b97d674 100644 +--- a/util/grub-mkrescue.in ++++ b/util/grub-mkrescue.in +@@ -365,15 +365,25 @@ if test -e "${pc_dir}" ; then + iso9660 biosdisk + cat "${pc_dir}/cdboot.img" "${core_img}" > "${iso9660_dir}/boot/grub/i386-pc/eltorito.img" + +- embed_img="`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"`" || exit 1 +- cat "${pc_dir}/boot.img" "${core_img}" > "${embed_img}" +- +- rm -f "${core_img}" +- + grub_mkisofs_arguments="${grub_mkisofs_arguments} -b boot/grub/i386-pc/eltorito.img -no-emul-boot -boot-load-size 4 -boot-info-table" + if [ "$system_area" = common ]; then +- grub_mkisofs_arguments="--embedded-boot ${embed_img}" ++ if "${xorriso}" -as mkisofs -help 2>&1 | fgrep "grub2-boot-info" >/dev/null; then ++ grub_mkisofs_arguments="${grub_mkisofs_arguments} --grub2-boot-info --grub2-mbr ${pc_dir}/boot_hybrid.img" ++ else ++ gettext "Your xorriso doesn't support \`--grub2-boot-info'. Some features are disabled. Please use xorriso 1.2.9 or later." ++ echo ++ sysarea_img="`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"`" || exit 1 ++ cat "${pc_dir}/boot.img" "${core_img}" > "${sysarea_img}" ++ if [ "$(wc -c "${sysarea_img}" | awk '{ print $1; }')" -gt 32768 ]; then ++ gettext "Your xorriso doesn't support \`--grub2-boot-info'. Your core image is too big. Boot as disk is disabled. Please use xorriso 1.2.9 or later." ++ echo ++ else ++ grub_mkisofs_arguments="${grub_mkisofs_arguments} -G ${sysarea_img}" ++ fi ++ fi + fi ++ ++ rm -f "${core_img}" + fi + + # build multiboot core.img +@@ -495,6 +505,5 @@ fi + rm -rf "${iso9660_dir}" + + rm -f "${sysarea_img}" +-rm -f "${embed_img}" + + exit 0 +-- +1.8.1.4 + diff --git a/0308-grub-core-loader-i386-linux.c-Remove-useless-leftove.patch b/0308-grub-core-loader-i386-linux.c-Remove-useless-leftove.patch new file mode 100644 index 0000000..04929a8 --- /dev/null +++ b/0308-grub-core-loader-i386-linux.c-Remove-useless-leftove.patch @@ -0,0 +1,155 @@ +From a68d80bd8b4ab9d3ca311ae33ef5e99c4f0017f0 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sun, 14 Apr 2013 19:01:23 +0200 +Subject: [PATCH 308/364] * grub-core/loader/i386/linux.c: Remove + useless leftover pointer. + +--- + ChangeLog | 4 +++ + grub-core/loader/i386/linux.c | 64 +++++++++++++++++++++---------------------- + 2 files changed, 35 insertions(+), 33 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index fc3dd51..1372be8 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,9 @@ + 2013-04-14 Vladimir Serbinenko + ++ * grub-core/loader/i386/linux.c: Remove useless leftover pointer. ++ ++2013-04-14 Vladimir Serbinenko ++ + Move GRUB out of system area when using xorriso 1.2.9 or later. + + 2013-04-14 Vladimir Serbinenko +diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c +index bdfe19a..5cd074b 100644 +--- a/grub-core/loader/i386/linux.c ++++ b/grub-core/loader/i386/linux.c +@@ -688,7 +688,6 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + { + grub_file_t file = 0; + struct linux_kernel_header lh; +- struct linux_kernel_params *params; + grub_uint8_t setup_sects; + grub_size_t real_size, prot_size, prot_file_size; + grub_ssize_t len; +@@ -808,16 +807,15 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + preferred_address)) + goto fail; + +- params = (struct linux_kernel_params *) &linux_params; +- grub_memset (params, 0, sizeof (*params)); +- grub_memcpy (¶ms->setup_sects, &lh.setup_sects, sizeof (lh) - 0x1F1); ++ grub_memset (&linux_params, 0, sizeof (linux_params)); ++ grub_memcpy (&linux_params.setup_sects, &lh.setup_sects, sizeof (lh) - 0x1F1); + +- params->code32_start = prot_mode_target + lh.code32_start - GRUB_LINUX_BZIMAGE_ADDR; +- params->kernel_alignment = (1 << align); +- params->ps_mouse = params->padding10 = 0; ++ linux_params.code32_start = prot_mode_target + lh.code32_start - GRUB_LINUX_BZIMAGE_ADDR; ++ linux_params.kernel_alignment = (1 << align); ++ linux_params.ps_mouse = linux_params.padding10 = 0; + +- len = sizeof (*params) - sizeof (lh); +- if (grub_file_read (file, (char *) params + sizeof (lh), len) != len) ++ len = sizeof (linux_params) - sizeof (lh); ++ if (grub_file_read (file, (char *) &linux_params + sizeof (lh), len) != len) + { + if (!grub_errno) + grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), +@@ -825,58 +823,58 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + goto fail; + } + +- params->type_of_loader = GRUB_LINUX_BOOT_LOADER_TYPE; ++ linux_params.type_of_loader = GRUB_LINUX_BOOT_LOADER_TYPE; + + /* These two are used (instead of cmd_line_ptr) by older versions of Linux, + and otherwise ignored. */ +- params->cl_magic = GRUB_LINUX_CL_MAGIC; +- params->cl_offset = 0x1000; ++ linux_params.cl_magic = GRUB_LINUX_CL_MAGIC; ++ linux_params.cl_offset = 0x1000; + +- params->ramdisk_image = 0; +- params->ramdisk_size = 0; ++ linux_params.ramdisk_image = 0; ++ linux_params.ramdisk_size = 0; + +- params->heap_end_ptr = GRUB_LINUX_HEAP_END_OFFSET; +- params->loadflags |= GRUB_LINUX_FLAG_CAN_USE_HEAP; ++ linux_params.heap_end_ptr = GRUB_LINUX_HEAP_END_OFFSET; ++ linux_params.loadflags |= GRUB_LINUX_FLAG_CAN_USE_HEAP; + + /* These are not needed to be precise, because Linux uses these values + only to raise an error when the decompression code cannot find good + space. */ +- params->ext_mem = ((32 * 0x100000) >> 10); +- params->alt_mem = ((32 * 0x100000) >> 10); ++ linux_params.ext_mem = ((32 * 0x100000) >> 10); ++ linux_params.alt_mem = ((32 * 0x100000) >> 10); + + /* Ignored by Linux. */ +- params->video_page = 0; ++ linux_params.video_page = 0; + + /* Only used when `video_mode == 0x7', otherwise ignored. */ +- params->video_ega_bx = 0; ++ linux_params.video_ega_bx = 0; + +- params->font_size = 16; /* XXX */ ++ linux_params.font_size = 16; /* XXX */ + + #ifdef GRUB_MACHINE_EFI + #ifdef __x86_64__ +- if (grub_le_to_cpu16 (params->version) < 0x0208 && ++ if (grub_le_to_cpu16 (linux_params.version) < 0x0208 && + ((grub_addr_t) grub_efi_system_table >> 32) != 0) + return grub_error(GRUB_ERR_BAD_OS, + "kernel does not support 64-bit addressing"); + #endif + +- if (grub_le_to_cpu16 (params->version) >= 0x0208) ++ if (grub_le_to_cpu16 (linux_params.version) >= 0x0208) + { +- params->v0208.efi_signature = GRUB_LINUX_EFI_SIGNATURE; +- params->v0208.efi_system_table = (grub_uint32_t) (unsigned long) grub_efi_system_table; ++ linux_params.v0208.efi_signature = GRUB_LINUX_EFI_SIGNATURE; ++ linux_params.v0208.efi_system_table = (grub_uint32_t) (unsigned long) grub_efi_system_table; + #ifdef __x86_64__ +- params->v0208.efi_system_table_hi = (grub_uint32_t) ((grub_uint64_t) grub_efi_system_table >> 32); ++ linux_params.v0208.efi_system_table_hi = (grub_uint32_t) ((grub_uint64_t) grub_efi_system_table >> 32); + #endif + } +- else if (grub_le_to_cpu16 (params->version) >= 0x0206) ++ else if (grub_le_to_cpu16 (linux_params.version) >= 0x0206) + { +- params->v0206.efi_signature = GRUB_LINUX_EFI_SIGNATURE; +- params->v0206.efi_system_table = (grub_uint32_t) (unsigned long) grub_efi_system_table; ++ linux_params.v0206.efi_signature = GRUB_LINUX_EFI_SIGNATURE; ++ linux_params.v0206.efi_system_table = (grub_uint32_t) (unsigned long) grub_efi_system_table; + } +- else if (grub_le_to_cpu16 (params->version) >= 0x0204) ++ else if (grub_le_to_cpu16 (linux_params.version) >= 0x0204) + { +- params->v0204.efi_signature = GRUB_LINUX_EFI_SIGNATURE_0204; +- params->v0204.efi_system_table = (grub_uint32_t) (unsigned long) grub_efi_system_table; ++ linux_params.v0204.efi_signature = GRUB_LINUX_EFI_SIGNATURE_0204; ++ linux_params.v0204.efi_system_table = (grub_uint32_t) (unsigned long) grub_efi_system_table; + } + #endif + +@@ -1012,7 +1010,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + } + else if (grub_memcmp (argv[i], "quiet", sizeof ("quiet") - 1) == 0) + { +- params->loadflags |= GRUB_LINUX_FLAG_QUIET; ++ linux_params.loadflags |= GRUB_LINUX_FLAG_QUIET; + } + + /* Create kernel command line. */ +-- +1.8.1.4 + diff --git a/0309-docs-grub-dev.texi-Rearrange-menu-to-match-the-secti.patch b/0309-docs-grub-dev.texi-Rearrange-menu-to-match-the-secti.patch new file mode 100644 index 0000000..faa2e72 --- /dev/null +++ b/0309-docs-grub-dev.texi-Rearrange-menu-to-match-the-secti.patch @@ -0,0 +1,53 @@ +From 7cdb4be61cce1354a4220741e2de5dac2dcd6f34 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sun, 14 Apr 2013 19:07:55 +0200 +Subject: [PATCH 309/364] * docs/grub-dev.texi: Rearrange menu to match + the section order. Reported by: Bryan Hundven. + +--- + ChangeLog | 5 +++++ + docs/grub-dev.texi | 4 ++-- + 2 files changed, 7 insertions(+), 2 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 1372be8..c01ae94 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,10 @@ + 2013-04-14 Vladimir Serbinenko + ++ * docs/grub-dev.texi: Rearrange menu to match the section order. ++ Reported by: Bryan Hundven. ++ ++2013-04-14 Vladimir Serbinenko ++ + * grub-core/loader/i386/linux.c: Remove useless leftover pointer. + + 2013-04-14 Vladimir Serbinenko +diff --git a/docs/grub-dev.texi b/docs/grub-dev.texi +index f74c966..53f7010 100644 +--- a/docs/grub-dev.texi ++++ b/docs/grub-dev.texi +@@ -74,8 +74,8 @@ This edition documents version @value{VERSION}. + + @menu + * Getting the source code:: +-* Finding your way around:: + * Coding style:: ++* Finding your way around:: + * Contributing Changes:: + * Porting:: + * Error Handling:: +@@ -948,8 +948,8 @@ driver manager works are not included here. + + @menu + * Video API:: +-* Bitmap API:: + * Example usage of Video API:: ++* Bitmap API:: + @end menu + + @node Video API +-- +1.8.1.4 + diff --git a/0310-Add-option-to-compress-files-on-install-image-creati.patch b/0310-Add-option-to-compress-files-on-install-image-creati.patch new file mode 100644 index 0000000..2e1e120 --- /dev/null +++ b/0310-Add-option-to-compress-files-on-install-image-creati.patch @@ -0,0 +1,285 @@ +From 9bdcd657c5b748ff8c0b4057be80add39d2addae Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sun, 14 Apr 2013 19:24:05 +0200 +Subject: [PATCH 310/364] Add option to compress files on install/image + creation. + +--- + ChangeLog | 4 ++++ + util/grub-install.in | 8 +++---- + util/grub-install_header | 61 ++++++++++++++++++++++++++++++++++++++++------- + util/grub-mkimage.c | 2 +- + util/grub-mknetdir.in | 2 +- + util/grub-mkrescue.in | 6 ++--- + util/grub-mkstandalone.in | 4 ++-- + 7 files changed, 67 insertions(+), 20 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index c01ae94..8cbf241 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,7 @@ ++2013-04-14 Szymon Janc ++ ++ Add option to compress files on install/image creation. ++ + 2013-04-14 Vladimir Serbinenko + + * docs/grub-dev.texi: Rearrange menu to match the section order. +diff --git a/util/grub-install.in b/util/grub-install.in +index 016b161..32a3be3 100644 +--- a/util/grub-install.in ++++ b/util/grub-install.in +@@ -684,9 +684,9 @@ case "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" in + esac + + if [ x"$config_opt_file" = x ]; then +- "$grub_mkimage" -d "${source_dir}" -O "${mkimage_target}" --output="${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/core.${imgext}" --prefix="${prefix_drive}${relative_grubdir}" $modules || exit 1 ++ "$grub_mkimage" -d "${source_dir}" -O "${mkimage_target}" --output="${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/core.${imgext}" --prefix="${prefix_drive}${relative_grubdir}" $grub_decompression_module $modules || exit 1 + else +- "$grub_mkimage" -c "${config_opt_file}" -d "${source_dir}" -O "${mkimage_target}" --output="${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/core.${imgext}" --prefix="${prefix_drive}${relative_grubdir}" $modules || exit 1 ++ "$grub_mkimage" -c "${config_opt_file}" -d "${source_dir}" -O "${mkimage_target}" --output="${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/core.${imgext}" --prefix="${prefix_drive}${relative_grubdir}" $grub_decompression_module $modules || exit 1 + fi + + # Backward-compatibility kludges +@@ -697,9 +697,9 @@ elif [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "i386-ieee1275" ] + elif [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "i386-efi" ] || [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "x86_64-efi" ]; then + + if [ x"$config_opt_file" = x ]; then +- "$grub_mkimage" -d "${source_dir}" -O "${mkimage_target}" --output="${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/grub.efi" --prefix="" $modules || exit 1 ++ "$grub_mkimage" -d "${source_dir}" -O "${mkimage_target}" --output="${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/grub.efi" --prefix="" $grub_decompression_module $modules || exit 1 + else +- "$grub_mkimage" -c "${config_opt_file}" -d "${source_dir}" -O "${mkimage_target}" --output="${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/grub.efi" --prefix="" $modules || exit 1 ++ "$grub_mkimage" -c "${config_opt_file}" -d "${source_dir}" -O "${mkimage_target}" --output="${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/grub.efi" --prefix="" $grub_decompression_module $modules || exit 1 + fi + fi + +diff --git a/util/grub-install_header b/util/grub-install_header +index 69aac46..805fc4f 100644 +--- a/util/grub-install_header ++++ b/util/grub-install_header +@@ -19,6 +19,14 @@ set -e + pkglib_DATA="moddep.lst command.lst fs.lst partmap.lst parttool.lst \ + handler.lst video.lst crypto.lst terminal.lst" + ++grub_compress_file () { ++ if [ "$compressor" != "" ] ; then ++ "$compressor" $compressor_opts "$1" > "$2" ++ else ++ cp -f "$1" "$2" ++ fi ++} ++ + grub_install_files () { + grub_install_files_source_directory="$1" + grub_install_files_target_directory="$2" +@@ -42,7 +50,7 @@ grub_install_files () { + + if [ x"$install_modules" = xall ]; then + for file in "${grub_install_files_source_directory}/"*.mod; do +- cp -f "$file" "${grub_install_files_target_directory}"/"${grub_install_files_platform}" ++ grub_compress_file "$file" "${grub_install_files_target_directory}"/"${grub_install_files_platform}/$(basename "$file")" + done + else + modules1= +@@ -56,13 +64,13 @@ grub_install_files () { + modules2="$modules3" + done + for file in $(echo "$modules1" | sed 's, ,\n,g' |sort -u); do +- cp -f "${grub_install_files_source_directory}/$file.mod" "${grub_install_files_target_directory}"/"${grub_install_files_platform}" ++ grub_compress_file "${grub_install_files_source_directory}/$file.mod" "${grub_install_files_target_directory}"/"${grub_install_files_platform}/$file.mod" + done + fi + + for file in ${pkglib_DATA} efiemu32.o efiemu64.o; do + if test -f "${grub_install_files_source_directory}/${file}"; then +- cp -f "${grub_install_files_source_directory}/${file}" "${grub_install_files_target_directory}"/"${grub_install_files_platform}" ++ grub_compress_file "${grub_install_files_source_directory}/${file}" "${grub_install_files_target_directory}"/"${grub_install_files_platform}/${file}" + fi + done + +@@ -78,34 +86,36 @@ grub_install_files () { + if [ x"$install_locales" = xall ]; then + for file in "${grub_install_files_source_directory}"/po/*.mo; do + if test -f "$file"; then +- cp -f "$file" "${grub_install_files_target_directory}"/locale/ ++ grub_compress_file "$file" "${grub_install_files_target_directory}"/locale/"$(basename "$file")" + fi + done + for dir in "${localedir}"/*; do + if test -f "$dir/LC_MESSAGES/@PACKAGE@.mo" && ! test -f "${grub_install_files_target_directory}"/locale/"${dir##*/}.mo"; then +- cp -f "$dir/LC_MESSAGES/@PACKAGE@.mo" "${grub_install_files_target_directory}"/locale/"${dir##*/}.mo" ++ grub_compress_file "$dir/LC_MESSAGES/@PACKAGE@.mo" "${grub_install_files_target_directory}"/locale/"${dir##*/}.mo" + fi + done + else + for locale in $install_locales; do + if test -f "${grub_install_files_source_directory}"/po/$locale.mo; then +- cp -f " "${grub_install_files_source_directory}"/po/$locale.mo" "${grub_install_files_target_directory}"/locale/$locale.mo ++ grub_compress_file "${grub_install_files_source_directory}"/po/locale.mo "${grub_install_files_target_directory}"/locale/$locale.mo + elif test -f "${localedir}/$locale/LC_MESSAGES/@PACKAGE@.mo"; then +- cp -f "${localedir}/$locale/LC_MESSAGES/@PACKAGE@.mo" "${grub_install_files_target_directory}"/locale/$locale.mo ++ grub_compress_file "${localedir}/$locale/LC_MESSAGES/@PACKAGE@.mo" "${grub_install_files_target_directory}"/locale/$locale.mo + fi + done + fi + for theme in ${install_themes} ; do + if test -f "${pkgdatadir}"/themes/"${theme}"/theme.txt; then + mkdir -p "${grub_install_files_target_directory}"/themes/"${theme}" +- cp "${pkgdatadir}"/themes/"${theme}"/* "${grub_install_files_target_directory}"/themes/"${theme}" ++ for file in "${pkgdatadir}"/themes/"${theme}"/*; do ++ grub_compress_file "$file" "${grub_install_files_target_directory}"/themes/"${theme}"/"$(basename "$file")" ++ done + fi + done + + for font in ${install_fonts} ; do + if test -f "${pkgdatadir}"/"$font".pf2; then + mkdir -p "${grub_install_files_target_directory}"/fonts +- cp "${pkgdatadir}"/"$font".pf2 "${grub_install_files_target_directory}"/fonts ++ grub_compress_file "${pkgdatadir}"/"$font".pf2 "${grub_install_files_target_directory}"/fonts/"$font".pf2 + fi + done + } +@@ -115,12 +125,17 @@ grub_print_install_files_help () { + print_option_help "--themes=THEMES" "$(gettext_printf "install THEMES [default=%s]" "starfield")" + print_option_help "--fonts=FONTS" "$(gettext_printf "install FONTS [default=%s]" "unicode")" + print_option_help "--locales=LOCALES" "$(gettext_printf "install only LOCALES [default=all]")" ++ print_option_help "--compress[=no,xz,gz,lzo]" "$(gettext "compress GRUB files [optional]")" + } + + install_modules=all + install_themes=starfield + install_fonts=unicode + install_locales=all ++compress=no ++grub_decompression_module="" ++compressor="" ++compressor_opts="" + + argument () { + opt=$1 +@@ -133,6 +148,29 @@ argument () { + echo $1 + } + ++grub_parse_compress () { ++ compress="$1" ++ case x"$compress" in ++ xno) ;; ++ xgz) ++ compressor=`which gzip || true` ++ grub_decompression_module="gzio" ++ compressor_opts="--best --stdout";; ++ xxz) ++ compressor=`which xz || true` ++ grub_decompression_module="xzio gcry_crc" ++ compressor_opts="--lzma2=dict=128KiB --check=none --stdout";; ++ xlzo) ++ compressor=`which lzop || true` ++ grub_decompression_module="lzopio adler32 gcry_crc" ++ compressor_opts="-9 -c";; ++ *) ++ gettext_printf "Unrecognized compression \`%s'\n" "$compress" 1>&2 ++ usage ++ exit 1 ++ esac ++} ++ + grub_process_install_options () { + option=$1 + shift +@@ -156,6 +194,11 @@ grub_process_install_options () { + install_locales=`argument $option "$@"`; grub_process_install_options_consumed=2; return ;; + --locales=*) + install_locales=`echo "$option" | sed 's/--locales=//'`; grub_process_install_options_consumed=1; return ;; ++ --compress) ++ grub_parse_compress `argument $option "$@"`; grub_process_install_options_consumed=2; return ;; ++ --compress=*) ++ grub_parse_compress `echo "${option}" | sed 's/--compress=//'`; grub_process_install_options_consumed=1; return ;; + esac + } + ++export grub_decompression_module +diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c +index 96279a4..0acc61e 100644 +--- a/util/grub-mkimage.c ++++ b/util/grub-mkimage.c +@@ -1740,7 +1740,7 @@ static struct argp_option options[] = { + {"note", 'n', 0, 0, N_("add NOTE segment for CHRP IEEE1275"), 0}, + {"output", 'o', N_("FILE"), 0, N_("output a generated image to FILE [default=stdout]"), 0}, + {"format", 'O', N_("FORMAT"), 0, 0, 0}, +- {"compression", 'C', "(xz|none|auto)", 0, N_("choose the compression to use"), 0}, ++ {"compression", 'C', "(xz|none|auto)", 0, N_("choose the compression to use for core image"), 0}, + {"verbose", 'v', 0, 0, N_("print verbose messages."), 0}, + { 0, 0, 0, 0, 0, 0 } + }; +diff --git a/util/grub-mknetdir.in b/util/grub-mknetdir.in +index 6df761a..d32de46 100644 +--- a/util/grub-mknetdir.in ++++ b/util/grub-mknetdir.in +@@ -191,7 +191,7 @@ process_input_dir () + source ${subdir}/grub.cfg + EOF + +- "$grub_mkimage" ${config_opt} -d "${input_dir}" -O ${mkimage_target} "--output=${grubdir}/core.$ext" "--prefix=$prefix" $modules $netmodules tftp || exit 1 ++ "$grub_mkimage" ${config_opt} -d "${input_dir}" -O ${mkimage_target} "--output=${grubdir}/core.$ext" "--prefix=$prefix" $modules $grub_decompression_module $netmodules tftp || exit 1 + # TRANSLATORS: First %s is replaced by platform name. Second one by filename. + gettext_printf "Netboot directory for %s created. Configure your DHCP server to point to %s\n" "${platform}" "${subdir}/${platform}/core.$ext" + } +diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in +index b97d674..7270d7f 100644 +--- a/util/grub-mkrescue.in ++++ b/util/grub-mkrescue.in +@@ -248,7 +248,7 @@ EOF + done ; ) > "${load_cfg}" + + "$grub_mkimage" -O ${platform} -d "${source_directory}" -c "${load_cfg}" -o "$3" \ +- search iso9660 $4 ++ $grub_decompression_module search iso9660 $4 + rm -rf "${load_cfg}" + } + +@@ -263,7 +263,7 @@ make_image_fwdisk () + gettext_printf "Enabling %s support ...\n" "$2" + + "$grub_mkimage" -O ${platform} -d "${source_directory}" -p '()/boot/grub' -o "$3" \ +- iso9660 $4 ++ $grub_decompression_module iso9660 $4 + } + + if [ "${override_dir}" = "" ] ; then +@@ -362,7 +362,7 @@ if test -e "${pc_dir}" ; then + done ;) > "${load_cfg}" + + "$grub_mkimage" -O i386-pc -d "${pc_dir}/" -o "${core_img}" -c "$load_cfg" --prefix=/boot/grub \ +- iso9660 biosdisk ++ $grub_decompression_module iso9660 biosdisk + cat "${pc_dir}/cdboot.img" "${core_img}" > "${iso9660_dir}/boot/grub/i386-pc/eltorito.img" + + grub_mkisofs_arguments="${grub_mkisofs_arguments} -b boot/grub/i386-pc/eltorito.img -no-emul-boot -boot-load-size 4 -boot-info-table" +diff --git a/util/grub-mkstandalone.in b/util/grub-mkstandalone.in +index a5434c4..927075b 100644 +--- a/util/grub-mkstandalone.in ++++ b/util/grub-mkstandalone.in +@@ -60,7 +60,7 @@ usage () { + print_option_help "-O, --format=$(gettext "FORMAT")" "$(gettext "generate an image in FORMAT")"; echo + print_option_help "" "$(gettext "available formats:") $formats" + echo +- print_option_help "-C, --compression=(xz|none|auto)" "$(gettext "choose the compression to use")" ++ print_option_help "-C, --compression=(xz|none|auto)" "$(gettext "choose the compression to use for core image")" + print_option_help "--modules=$(gettext "MODULES")" "$(gettext "pre-load specified modules MODULES")" + grub_print_install_files_help + print_option_help "--grub-mkimage=$(gettext "FILE")" "$(gettext "use FILE as grub-mkimage")" +@@ -170,7 +170,7 @@ memdisk_img=`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` || exit 1 + + (cd "${memdisk_dir}"; tar -cf - * $source) > "${memdisk_img}" + rm -rf "${memdisk_dir}" +-"$grub_mkimage" -O "${format}" -C "$compression" -d "${source_directory}" -m "${memdisk_img}" -o "$output_image" --prefix='(memdisk)/boot/grub' memdisk tar $modules ++"$grub_mkimage" -O "${format}" -C "$compression" -d "${source_directory}" -m "${memdisk_img}" -o "$output_image" --prefix='(memdisk)/boot/grub' memdisk tar $grub_decompression_module $modules + rm -rf "${memdisk_img}" + + exit 0 +-- +1.8.1.4 + diff --git a/0311-grub-core-lib-posix_wrap-sys-types.h-Make-WORDS_BIGE.patch b/0311-grub-core-lib-posix_wrap-sys-types.h-Make-WORDS_BIGE.patch new file mode 100644 index 0000000..02960b7 --- /dev/null +++ b/0311-grub-core-lib-posix_wrap-sys-types.h-Make-WORDS_BIGE.patch @@ -0,0 +1,43 @@ +From c7cfeef7d608f88328e7ab8dc004a2333d93da40 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sun, 14 Apr 2013 19:57:15 +0200 +Subject: [PATCH 311/364] * grub-core/lib/posix_wrap/sys/types.h: Make + WORDS_BIGENDIAN definition match config-util.h to avoid warnings and + increase compatibility. + +--- + ChangeLog | 6 ++++++ + grub-core/lib/posix_wrap/sys/types.h | 2 +- + 2 files changed, 7 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index 8cbf241..a4d9555 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,4 +1,10 @@ ++2013-04-14 Vladimir Serbinenko ++ ++ * grub-core/lib/posix_wrap/sys/types.h: Make WORDS_BIGENDIAN definition ++ match config-util.h to avoid warnings and increase compatibility. ++ + 2013-04-14 Szymon Janc ++2013-04-14 Vladimir Serbinenko + + Add option to compress files on install/image creation. + +diff --git a/grub-core/lib/posix_wrap/sys/types.h b/grub-core/lib/posix_wrap/sys/types.h +index c88a96e..6485a9a 100644 +--- a/grub-core/lib/posix_wrap/sys/types.h ++++ b/grub-core/lib/posix_wrap/sys/types.h +@@ -60,7 +60,7 @@ typedef grub_addr_t uintptr_t; + #define SIZEOF_UINT64_T 8 + + #ifdef GRUB_CPU_WORDS_BIGENDIAN +-#define WORDS_BIGENDIAN ++#define WORDS_BIGENDIAN 1 + #else + #undef WORDS_BIGENDIAN + #endif +-- +1.8.1.4 + diff --git a/0312-grub-core-disk-ieee1275-ofdisk.c-Fix-CD-ROM-and-boot.patch b/0312-grub-core-disk-ieee1275-ofdisk.c-Fix-CD-ROM-and-boot.patch new file mode 100644 index 0000000..e6ca406 --- /dev/null +++ b/0312-grub-core-disk-ieee1275-ofdisk.c-Fix-CD-ROM-and-boot.patch @@ -0,0 +1,87 @@ +From f0efb6d6b3660d99f2dbb55b1b12525ef4255368 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Mon, 15 Apr 2013 00:38:39 +0200 +Subject: [PATCH 312/364] * grub-core/disk/ieee1275/ofdisk.c: Fix CD-ROM + and boot device detection. + +--- + ChangeLog | 5 +++++ + grub-core/disk/ieee1275/ofdisk.c | 21 +++++++++++++++++++-- + 2 files changed, 24 insertions(+), 2 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index a4d9555..b372668 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,8 @@ ++2013-04-15 Vladimir Serbinenko ++ ++ * grub-core/disk/ieee1275/ofdisk.c: Fix CD-ROM and boot device ++ detection. ++ + 2013-04-14 Vladimir Serbinenko + + * grub-core/lib/posix_wrap/sys/types.h: Make WORDS_BIGENDIAN definition +diff --git a/grub-core/disk/ieee1275/ofdisk.c b/grub-core/disk/ieee1275/ofdisk.c +index bebf777..ec92c4d 100644 +--- a/grub-core/disk/ieee1275/ofdisk.c ++++ b/grub-core/disk/ieee1275/ofdisk.c +@@ -32,6 +32,7 @@ struct ofdisk_hash_ent + { + char *devpath; + int is_boot; ++ int is_cdrom; + /* Pointer to shortest available name on nodes representing canonical names, + otherwise NULL. */ + const char *shortest; +@@ -80,6 +81,18 @@ ofdisk_hash_add_real (char *devpath) + return p; + } + ++static int ++check_string_cdrom (const char *str) ++{ ++ const char *ptr = grub_strrchr (str, '/'); ++ ++ if (ptr) ++ ptr++; ++ else ++ ptr = str; ++ return (grub_strncmp (ptr, "cdrom", 5) == 0); ++} ++ + static struct ofdisk_hash_ent * + ofdisk_hash_add (char *devpath, char *curcan) + { +@@ -92,6 +105,8 @@ ofdisk_hash_add (char *devpath, char *curcan) + if (!curcan) + { + p->shortest = devpath; ++ if (check_string_cdrom (devpath)) ++ p->is_cdrom = 1; + return p; + } + +@@ -101,6 +116,9 @@ ofdisk_hash_add (char *devpath, char *curcan) + else + grub_free (curcan); + ++ if (check_string_cdrom (devpath) || check_string_cdrom (curcan)) ++ pcan->is_cdrom = 1; ++ + if (!pcan) + grub_errno = GRUB_ERR_NONE; + else +@@ -267,8 +285,7 @@ grub_ofdisk_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data, + } + } + +- if (grub_strncmp (ent->shortest, "cdrom", 5) == 0 +- || ent->is_boot) ++ if (!ent->is_boot && ent->is_cdrom) + continue; + + { +-- +1.8.1.4 + diff --git a/0313-grub-core-kern-ieee1275-openfw.c-grub_ieee1275_deval.patch b/0313-grub-core-kern-ieee1275-openfw.c-grub_ieee1275_deval.patch new file mode 100644 index 0000000..d4e0596 --- /dev/null +++ b/0313-grub-core-kern-ieee1275-openfw.c-grub_ieee1275_deval.patch @@ -0,0 +1,57 @@ +From d3b49c377da018a3a0064e2f53d8f35d2e678041 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Mon, 15 Apr 2013 00:40:19 +0200 +Subject: [PATCH 313/364] * grub-core/kern/ieee1275/openfw.c + (grub_ieee1275_devalias_next): Make source and destination differ. + +--- + ChangeLog | 5 +++++ + grub-core/kern/ieee1275/openfw.c | 6 +++++- + 2 files changed, 10 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index b372668..7469030 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,10 @@ + 2013-04-15 Vladimir Serbinenko + ++ * grub-core/kern/ieee1275/openfw.c (grub_ieee1275_devalias_next): Make ++ source and destination differ. ++ ++2013-04-15 Vladimir Serbinenko ++ + * grub-core/disk/ieee1275/ofdisk.c: Fix CD-ROM and boot device + detection. + +diff --git a/grub-core/kern/ieee1275/openfw.c b/grub-core/kern/ieee1275/openfw.c +index 90c092c..07c90f7 100644 +--- a/grub-core/kern/ieee1275/openfw.c ++++ b/grub-core/kern/ieee1275/openfw.c +@@ -193,18 +193,22 @@ grub_ieee1275_devalias_next (struct grub_ieee1275_devalias *alias) + { + grub_ssize_t pathlen; + grub_ssize_t actual; ++ char *tmp; + + if (alias->path) + { + grub_free (alias->path); + alias->path = 0; + } +- if (grub_ieee1275_next_property (alias->parent_dev, alias->name, ++ tmp = grub_strdup (alias->name); ++ if (grub_ieee1275_next_property (alias->parent_dev, tmp, + alias->name) <= 0) + { ++ grub_free (tmp); + grub_ieee1275_devalias_free (alias); + return 0; + } ++ grub_free (tmp); + + grub_dprintf ("devalias", "devalias name = %s\n", alias->name); + +-- +1.8.1.4 + diff --git a/0314-tests-grub_script_expansion.in-Use-fixed-string-grep.patch b/0314-tests-grub_script_expansion.in-Use-fixed-string-grep.patch new file mode 100644 index 0000000..95d4af0 --- /dev/null +++ b/0314-tests-grub_script_expansion.in-Use-fixed-string-grep.patch @@ -0,0 +1,57 @@ +From 966a29c8d4d95184f51f62698efadba5df80309b Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Mon, 15 Apr 2013 01:53:33 +0200 +Subject: [PATCH 314/364] * tests/grub_script_expansion.in: Use + fixed-string grep to skip over firmware error messages. + +--- + ChangeLog | 5 +++++ + tests/grub_script_expansion.in | 6 +++--- + 2 files changed, 8 insertions(+), 3 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 7469030..1391202 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,10 @@ + 2013-04-15 Vladimir Serbinenko + ++ * tests/grub_script_expansion.in: Use fixed-string grep to skip over ++ firmware error messages. ++ ++2013-04-15 Vladimir Serbinenko ++ + * grub-core/kern/ieee1275/openfw.c (grub_ieee1275_devalias_next): Make + source and destination differ. + +diff --git a/tests/grub_script_expansion.in b/tests/grub_script_expansion.in +index 03dc510..e46401c 100644 +--- a/tests/grub_script_expansion.in ++++ b/tests/grub_script_expansion.in +@@ -21,12 +21,12 @@ disks=`echo ls | @builddir@/grub-shell| grep -av '^Network protocols:$'| grep -a + other=`echo insmod regexp\; echo \* | @builddir@/grub-shell` + for d in $disks; do + if echo "$d" |grep ',' >/dev/null; then +- if echo "$other" | grep "$d" >/dev/null; then ++ if echo "$other" | grep -F -- "$d" >/dev/null; then + echo "$d should not occur in * expansion" >&2 + exit 1 + fi + else +- if ! echo "$other" | grep "$d" >/dev/null; then ++ if ! echo "$other" | grep -F -- "$d" >/dev/null; then + echo "$d missing from * expansion" >&2 + exit 1 + fi +@@ -35,7 +35,7 @@ done + + other=`echo insmod regexp\; echo '(*)' | @builddir@/grub-shell` + for d in $disks; do +- if ! echo "$other" | grep -F "$d" >/dev/null; then ++ if ! echo "$other" | grep -F -- "$d" >/dev/null; then + echo "$d missing from (*) expansion" >&2 + exit 1 + fi +-- +1.8.1.4 + diff --git a/0315-tests-grub_cmd_date.in-Skip-on-sparc64.patch b/0315-tests-grub_cmd_date.in-Skip-on-sparc64.patch new file mode 100644 index 0000000..17d1c2e --- /dev/null +++ b/0315-tests-grub_cmd_date.in-Skip-on-sparc64.patch @@ -0,0 +1,45 @@ +From b9e3a21d4c4ce7d70fe6a22283fc9a1dc1d31ce5 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Mon, 15 Apr 2013 01:54:23 +0200 +Subject: [PATCH 315/364] * tests/grub_cmd_date.in: Skip on sparc64. + +--- + ChangeLog | 4 ++++ + tests/grub_cmd_date.in | 7 +++++++ + 2 files changed, 11 insertions(+) + +diff --git a/ChangeLog b/ChangeLog +index 1391202..db6076c 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,9 @@ + 2013-04-15 Vladimir Serbinenko + ++ * tests/grub_cmd_date.in: Skip on sparc64. ++ ++2013-04-15 Vladimir Serbinenko ++ + * tests/grub_script_expansion.in: Use fixed-string grep to skip over + firmware error messages. + +diff --git a/tests/grub_cmd_date.in b/tests/grub_cmd_date.in +index 254fb91..76436a0 100644 +--- a/tests/grub_cmd_date.in ++++ b/tests/grub_cmd_date.in +@@ -1,6 +1,13 @@ + #! /bin/bash + set -e + ++. "@builddir@/grub-core/modinfo.sh" ++ ++# OpenBIOS on sparc64 doesn't implement RTC ++if [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = sparc64-ieee1275 ]; then ++ exit 0 ++fi ++ + pdt="$(date -u +%s)" + dt=`echo date | @builddir@/grub-shell` + dtg="$(date -u -d "$dt" +%s)" +-- +1.8.1.4 + diff --git a/0316-Fix-DMRAID-partition-handling.patch b/0316-Fix-DMRAID-partition-handling.patch new file mode 100644 index 0000000..5c5f743 --- /dev/null +++ b/0316-Fix-DMRAID-partition-handling.patch @@ -0,0 +1,49 @@ +From 5c5e65464abe032b3838359d35fdbd0c15fe6454 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Mon, 15 Apr 2013 08:37:13 +0200 +Subject: [PATCH 316/364] Fix DMRAID partition handling. + +--- + ChangeLog | 4 ++++ + util/getroot.c | 4 ++++ + 2 files changed, 8 insertions(+) + +diff --git a/ChangeLog b/ChangeLog +index db6076c..2dcf1f5 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,9 @@ + 2013-04-15 Vladimir Serbinenko + ++ Fix DMRAID partition handling. ++ ++2013-04-15 Vladimir Serbinenko ++ + * tests/grub_cmd_date.in: Skip on sparc64. + + 2013-04-15 Vladimir Serbinenko +diff --git a/util/getroot.c b/util/getroot.c +index 4ea8e65..ecf7ce1 100644 +--- a/util/getroot.c ++++ b/util/getroot.c +@@ -1956,6 +1956,7 @@ convert_system_partition_to_system_disk (const char *os_dev, struct stat *st, + grub_util_info ("dm_tree_find_node failed"); + goto devmapper_out; + } ++ reiterate: + node_uuid = dm_tree_node_get_uuid (node); + if (! node_uuid) + { +@@ -2030,6 +2031,9 @@ convert_system_partition_to_system_disk (const char *os_dev, struct stat *st, + goto devmapper_out; + } + mapper_name = child_name; ++ *is_part = 1; ++ node = child; ++ goto reiterate; + + devmapper_out: + if (! mapper_name && node) +-- +1.8.1.4 + diff --git a/0317-grub-core-disk-efi-efidisk.c-Limit-disk-read-or-writ.patch b/0317-grub-core-disk-efi-efidisk.c-Limit-disk-read-or-writ.patch new file mode 100644 index 0000000..7307987 --- /dev/null +++ b/0317-grub-core-disk-efi-efidisk.c-Limit-disk-read-or-writ.patch @@ -0,0 +1,115 @@ +From fe97d5b99bcfde6f46f57381df0d099de51d1709 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Mon, 15 Apr 2013 09:12:14 +0200 +Subject: [PATCH 317/364] * grub-core/disk/efi/efidisk.c: Limit disk + read or write chunk to 0x500 sectors. Based on patch by Peter Jones. + +--- + ChangeLog | 7 +++++++ + grub-core/disk/efi/efidisk.c | 50 +++++++++++++++++++++++++++++--------------- + 2 files changed, 40 insertions(+), 17 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 2dcf1f5..6f33ff1 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,4 +1,11 @@ + 2013-04-15 Vladimir Serbinenko ++2013-04-15 Peter Jones ++ ++ * grub-core/disk/efi/efidisk.c: Limit disk read or write chunk to 0x500 ++ sectors. ++ Based on patch by Peter Jones. ++ ++2013-04-15 Vladimir Serbinenko + + Fix DMRAID partition handling. + +diff --git a/grub-core/disk/efi/efidisk.c b/grub-core/disk/efi/efidisk.c +index 28b9fa1..5a6fc63 100644 +--- a/grub-core/disk/efi/efidisk.c ++++ b/grub-core/disk/efi/efidisk.c +@@ -528,9 +528,9 @@ grub_efidisk_close (struct grub_disk *disk __attribute__ ((unused))) + grub_dprintf ("efidisk", "closing %s\n", disk->name); + } + +-static grub_err_t +-grub_efidisk_read (struct grub_disk *disk, grub_disk_addr_t sector, +- grub_size_t size, char *buf) ++static grub_efi_status_t ++grub_efidisk_readwrite (struct grub_disk *disk, grub_disk_addr_t sector, ++ grub_size_t size, char *buf, int wr) + { + /* For now, use the disk io interface rather than the block io's. */ + struct grub_efidisk_data *d; +@@ -540,14 +540,38 @@ grub_efidisk_read (struct grub_disk *disk, grub_disk_addr_t sector, + d = disk->data; + bio = d->block_io; + ++ while (size > 0) ++ { ++ grub_size_t len; ++ len = 0x500; ++ if (len > size) ++ len = size; ++ status = efi_call_5 ((wr ? bio->write_blocks : bio->read_blocks), bio, ++ bio->media->media_id, ++ (grub_efi_uint64_t) sector, ++ (grub_efi_uintn_t) size << disk->log_sector_size, ++ buf); ++ size -= len; ++ buf += len << disk->log_sector_size; ++ sector += len; ++ if (status != GRUB_EFI_SUCCESS) ++ return status; ++ } ++ return GRUB_EFI_SUCCESS; ++} ++ ++static grub_err_t ++grub_efidisk_read (struct grub_disk *disk, grub_disk_addr_t sector, ++ grub_size_t size, char *buf) ++{ ++ grub_efi_status_t status; ++ + grub_dprintf ("efidisk", + "reading 0x%lx sectors at the sector 0x%llx from %s\n", + (unsigned long) size, (unsigned long long) sector, disk->name); + +- status = efi_call_5 (bio->read_blocks, bio, bio->media->media_id, +- (grub_efi_uint64_t) sector, +- (grub_efi_uintn_t) size << disk->log_sector_size, +- buf); ++ status = grub_efidisk_readwrite (disk, sector, size, buf, 0); ++ + if (status != GRUB_EFI_SUCCESS) + return grub_error (GRUB_ERR_READ_ERROR, + N_("failure reading sector 0x%llx from `%s'"), +@@ -561,22 +585,14 @@ static grub_err_t + grub_efidisk_write (struct grub_disk *disk, grub_disk_addr_t sector, + grub_size_t size, const char *buf) + { +- /* For now, use the disk io interface rather than the block io's. */ +- struct grub_efidisk_data *d; +- grub_efi_block_io_t *bio; + grub_efi_status_t status; + +- d = disk->data; +- bio = d->block_io; +- + grub_dprintf ("efidisk", + "writing 0x%lx sectors at the sector 0x%llx to %s\n", + (unsigned long) size, (unsigned long long) sector, disk->name); + +- status = efi_call_5 (bio->write_blocks, bio, bio->media->media_id, +- (grub_efi_uint64_t) sector, +- (grub_efi_uintn_t) size << disk->log_sector_size, +- (void *) buf); ++ status = grub_efidisk_readwrite (disk, sector, size, (char *) buf, 1); ++ + if (status != GRUB_EFI_SUCCESS) + return grub_error (GRUB_ERR_WRITE_ERROR, + N_("failure writing sector 0x%llx to `%s'"), +-- +1.8.1.4 + diff --git a/0318-autogen.sh-Use-f-in-addition-for-h-when-checking-fil.patch b/0318-autogen.sh-Use-f-in-addition-for-h-when-checking-fil.patch new file mode 100644 index 0000000..e4167a8 --- /dev/null +++ b/0318-autogen.sh-Use-f-in-addition-for-h-when-checking-fil.patch @@ -0,0 +1,39 @@ +From 25e2e87a9e3a65c9ccad0155f3969fb94325a32e Mon Sep 17 00:00:00 2001 +From: Andrey Borzenkov +Date: Tue, 16 Apr 2013 16:18:12 +0200 +Subject: [PATCH 318/364] * autogen.sh: Use "-f" in addition for "-h" + when checking file presence. + +--- + ChangeLog | 4 ++++ + autogen.sh | 2 +- + 2 files changed, 5 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index 6f33ff1..10db262 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,7 @@ ++2013-04-16 Andrey Borzenkov ++ ++ * autogen.sh: Use "-f" in addition for "-h" when checking file presence. ++ + 2013-04-15 Vladimir Serbinenko + 2013-04-15 Peter Jones + +diff --git a/autogen.sh b/autogen.sh +index d47650b..48d7a6e 100755 +--- a/autogen.sh ++++ b/autogen.sh +@@ -24,7 +24,7 @@ ln -s ../../../grub-core/lib/libgcrypt-grub/src/g10lib.h include/grub/gcrypt/g10 + cp -R grub-core/lib/libgcrypt/mpi/generic grub-core/lib/libgcrypt-grub/mpi/generic + + for x in mpi-asm-defs.h mpih-add1.c mpih-sub1.c mpih-mul1.c mpih-mul2.c mpih-mul3.c mpih-lshift.c mpih-rshift.c; do +- if [ -h grub-core/lib/libgcrypt-grub/mpi/"$x" ]; then ++ if [ -h grub-core/lib/libgcrypt-grub/mpi/"$x" ] || [ -f grub-core/lib/libgcrypt-grub/mpi/"$x" ]; then + rm grub-core/lib/libgcrypt-grub/mpi/"$x" + fi + ln -s generic/"$x" grub-core/lib/libgcrypt-grub/mpi/"$x" +-- +1.8.1.4 + diff --git a/0319-grub-core-disk-efi-efidisk.c-Really-limit-transfer-c.patch b/0319-grub-core-disk-efi-efidisk.c-Really-limit-transfer-c.patch new file mode 100644 index 0000000..0f93d84 --- /dev/null +++ b/0319-grub-core-disk-efi-efidisk.c-Really-limit-transfer-c.patch @@ -0,0 +1,41 @@ +From 8ddb11881a1bf16dce6efc8015d9e03df63eb403 Mon Sep 17 00:00:00 2001 +From: Andrey Borzenkov +Date: Tue, 16 Apr 2013 22:10:59 +0200 +Subject: [PATCH 319/364] * grub-core/disk/efi/efidisk.c: Really limit + transfer chunk size. + +--- + ChangeLog | 4 ++++ + grub-core/disk/efi/efidisk.c | 2 +- + 2 files changed, 5 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index 10db262..b60a71d 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,9 @@ + 2013-04-16 Andrey Borzenkov + ++ * grub-core/disk/efi/efidisk.c: Really limit transfer chunk size. ++ ++2013-04-16 Andrey Borzenkov ++ + * autogen.sh: Use "-f" in addition for "-h" when checking file presence. + + 2013-04-15 Vladimir Serbinenko +diff --git a/grub-core/disk/efi/efidisk.c b/grub-core/disk/efi/efidisk.c +index 5a6fc63..0e08d3b 100644 +--- a/grub-core/disk/efi/efidisk.c ++++ b/grub-core/disk/efi/efidisk.c +@@ -549,7 +549,7 @@ grub_efidisk_readwrite (struct grub_disk *disk, grub_disk_addr_t sector, + status = efi_call_5 ((wr ? bio->write_blocks : bio->read_blocks), bio, + bio->media->media_id, + (grub_efi_uint64_t) sector, +- (grub_efi_uintn_t) size << disk->log_sector_size, ++ (grub_efi_uintn_t) len << disk->log_sector_size, + buf); + size -= len; + buf += len << disk->log_sector_size; +-- +1.8.1.4 + diff --git a/0320-build-aux-snippet-Add-missing-gnulib-files.patch b/0320-build-aux-snippet-Add-missing-gnulib-files.patch new file mode 100644 index 0000000..542dc35 --- /dev/null +++ b/0320-build-aux-snippet-Add-missing-gnulib-files.patch @@ -0,0 +1,472 @@ +From d02bf953c4fb2eb34998274b304bf1a2ac755c89 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Wed, 17 Apr 2013 07:00:37 +0200 +Subject: [PATCH 320/364] * build-aux/snippet: Add missing gnulib files. + +--- + ChangeLog | 4 + + build-aux/snippet/_Noreturn.h | 10 ++ + build-aux/snippet/arg-nonnull.h | 26 ++++ + build-aux/snippet/c++defs.h | 271 ++++++++++++++++++++++++++++++++++++++++ + build-aux/snippet/warn-on-use.h | 109 ++++++++++++++++ + 5 files changed, 420 insertions(+) + create mode 100644 build-aux/snippet/_Noreturn.h + create mode 100644 build-aux/snippet/arg-nonnull.h + create mode 100644 build-aux/snippet/c++defs.h + create mode 100644 build-aux/snippet/warn-on-use.h + +diff --git a/ChangeLog b/ChangeLog +index b60a71d..073207a 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,7 @@ ++2013-04-17 Vladimir Serbinenko ++ ++ * build-aux/snippet: Add missing gnulib files. ++ + 2013-04-16 Andrey Borzenkov + + * grub-core/disk/efi/efidisk.c: Really limit transfer chunk size. +diff --git a/build-aux/snippet/_Noreturn.h b/build-aux/snippet/_Noreturn.h +new file mode 100644 +index 0000000..c44ad89 +--- /dev/null ++++ b/build-aux/snippet/_Noreturn.h +@@ -0,0 +1,10 @@ ++#if !defined _Noreturn && __STDC_VERSION__ < 201112 ++# if (3 <= __GNUC__ || (__GNUC__ == 2 && 8 <= __GNUC_MINOR__) \ ++ || 0x5110 <= __SUNPRO_C) ++# define _Noreturn __attribute__ ((__noreturn__)) ++# elif 1200 <= _MSC_VER ++# define _Noreturn __declspec (noreturn) ++# else ++# define _Noreturn ++# endif ++#endif +diff --git a/build-aux/snippet/arg-nonnull.h b/build-aux/snippet/arg-nonnull.h +new file mode 100644 +index 0000000..8ea2a47 +--- /dev/null ++++ b/build-aux/snippet/arg-nonnull.h +@@ -0,0 +1,26 @@ ++/* A C macro for declaring that specific arguments must not be NULL. ++ Copyright (C) 2009-2013 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 . */ ++ ++/* _GL_ARG_NONNULL((n,...,m)) tells the compiler and static analyzer tools ++ that the values passed as arguments n, ..., m must be non-NULL pointers. ++ n = 1 stands for the first argument, n = 2 for the second argument etc. */ ++#ifndef _GL_ARG_NONNULL ++# if (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) || __GNUC__ > 3 ++# define _GL_ARG_NONNULL(params) __attribute__ ((__nonnull__ params)) ++# else ++# define _GL_ARG_NONNULL(params) ++# endif ++#endif +diff --git a/build-aux/snippet/c++defs.h b/build-aux/snippet/c++defs.h +new file mode 100644 +index 0000000..b35b933 +--- /dev/null ++++ b/build-aux/snippet/c++defs.h +@@ -0,0 +1,271 @@ ++/* C++ compatible function declaration macros. ++ Copyright (C) 2010-2013 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 _GL_CXXDEFS_H ++#define _GL_CXXDEFS_H ++ ++/* The three most frequent use cases of these macros are: ++ ++ * For providing a substitute for a function that is missing on some ++ platforms, but is declared and works fine on the platforms on which ++ it exists: ++ ++ #if @GNULIB_FOO@ ++ # if !@HAVE_FOO@ ++ _GL_FUNCDECL_SYS (foo, ...); ++ # endif ++ _GL_CXXALIAS_SYS (foo, ...); ++ _GL_CXXALIASWARN (foo); ++ #elif defined GNULIB_POSIXCHECK ++ ... ++ #endif ++ ++ * For providing a replacement for a function that exists on all platforms, ++ but is broken/insufficient and needs to be replaced on some platforms: ++ ++ #if @GNULIB_FOO@ ++ # if @REPLACE_FOO@ ++ # if !(defined __cplusplus && defined GNULIB_NAMESPACE) ++ # undef foo ++ # define foo rpl_foo ++ # endif ++ _GL_FUNCDECL_RPL (foo, ...); ++ _GL_CXXALIAS_RPL (foo, ...); ++ # else ++ _GL_CXXALIAS_SYS (foo, ...); ++ # endif ++ _GL_CXXALIASWARN (foo); ++ #elif defined GNULIB_POSIXCHECK ++ ... ++ #endif ++ ++ * For providing a replacement for a function that exists on some platforms ++ but is broken/insufficient and needs to be replaced on some of them and ++ is additionally either missing or undeclared on some other platforms: ++ ++ #if @GNULIB_FOO@ ++ # if @REPLACE_FOO@ ++ # if !(defined __cplusplus && defined GNULIB_NAMESPACE) ++ # undef foo ++ # define foo rpl_foo ++ # endif ++ _GL_FUNCDECL_RPL (foo, ...); ++ _GL_CXXALIAS_RPL (foo, ...); ++ # else ++ # if !@HAVE_FOO@ or if !@HAVE_DECL_FOO@ ++ _GL_FUNCDECL_SYS (foo, ...); ++ # endif ++ _GL_CXXALIAS_SYS (foo, ...); ++ # endif ++ _GL_CXXALIASWARN (foo); ++ #elif defined GNULIB_POSIXCHECK ++ ... ++ #endif ++*/ ++ ++/* _GL_EXTERN_C declaration; ++ performs the declaration with C linkage. */ ++#if defined __cplusplus ++# define _GL_EXTERN_C extern "C" ++#else ++# define _GL_EXTERN_C extern ++#endif ++ ++/* _GL_FUNCDECL_RPL (func, rettype, parameters_and_attributes); ++ declares a replacement function, named rpl_func, with the given prototype, ++ consisting of return type, parameters, and attributes. ++ Example: ++ _GL_FUNCDECL_RPL (open, int, (const char *filename, int flags, ...) ++ _GL_ARG_NONNULL ((1))); ++ */ ++#define _GL_FUNCDECL_RPL(func,rettype,parameters_and_attributes) \ ++ _GL_FUNCDECL_RPL_1 (rpl_##func, rettype, parameters_and_attributes) ++#define _GL_FUNCDECL_RPL_1(rpl_func,rettype,parameters_and_attributes) \ ++ _GL_EXTERN_C rettype rpl_func parameters_and_attributes ++ ++/* _GL_FUNCDECL_SYS (func, rettype, parameters_and_attributes); ++ declares the system function, named func, with the given prototype, ++ consisting of return type, parameters, and attributes. ++ Example: ++ _GL_FUNCDECL_SYS (open, int, (const char *filename, int flags, ...) ++ _GL_ARG_NONNULL ((1))); ++ */ ++#define _GL_FUNCDECL_SYS(func,rettype,parameters_and_attributes) \ ++ _GL_EXTERN_C rettype func parameters_and_attributes ++ ++/* _GL_CXXALIAS_RPL (func, rettype, parameters); ++ declares a C++ alias called GNULIB_NAMESPACE::func ++ that redirects to rpl_func, if GNULIB_NAMESPACE is defined. ++ Example: ++ _GL_CXXALIAS_RPL (open, int, (const char *filename, int flags, ...)); ++ */ ++#define _GL_CXXALIAS_RPL(func,rettype,parameters) \ ++ _GL_CXXALIAS_RPL_1 (func, rpl_##func, rettype, parameters) ++#if defined __cplusplus && defined GNULIB_NAMESPACE ++# define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \ ++ namespace GNULIB_NAMESPACE \ ++ { \ ++ rettype (*const func) parameters = ::rpl_func; \ ++ } \ ++ _GL_EXTERN_C int _gl_cxxalias_dummy ++#else ++# define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \ ++ _GL_EXTERN_C int _gl_cxxalias_dummy ++#endif ++ ++/* _GL_CXXALIAS_RPL_CAST_1 (func, rpl_func, rettype, parameters); ++ is like _GL_CXXALIAS_RPL_1 (func, rpl_func, rettype, parameters); ++ except that the C function rpl_func may have a slightly different ++ declaration. A cast is used to silence the "invalid conversion" error ++ that would otherwise occur. */ ++#if defined __cplusplus && defined GNULIB_NAMESPACE ++# define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \ ++ namespace GNULIB_NAMESPACE \ ++ { \ ++ rettype (*const func) parameters = \ ++ reinterpret_cast(::rpl_func); \ ++ } \ ++ _GL_EXTERN_C int _gl_cxxalias_dummy ++#else ++# define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \ ++ _GL_EXTERN_C int _gl_cxxalias_dummy ++#endif ++ ++/* _GL_CXXALIAS_SYS (func, rettype, parameters); ++ declares a C++ alias called GNULIB_NAMESPACE::func ++ that redirects to the system provided function func, if GNULIB_NAMESPACE ++ is defined. ++ Example: ++ _GL_CXXALIAS_SYS (open, int, (const char *filename, int flags, ...)); ++ */ ++#if defined __cplusplus && defined GNULIB_NAMESPACE ++ /* If we were to write ++ rettype (*const func) parameters = ::func; ++ like above in _GL_CXXALIAS_RPL_1, the compiler could optimize calls ++ better (remove an indirection through a 'static' pointer variable), ++ but then the _GL_CXXALIASWARN macro below would cause a warning not only ++ for uses of ::func but also for uses of GNULIB_NAMESPACE::func. */ ++# define _GL_CXXALIAS_SYS(func,rettype,parameters) \ ++ namespace GNULIB_NAMESPACE \ ++ { \ ++ static rettype (*func) parameters = ::func; \ ++ } \ ++ _GL_EXTERN_C int _gl_cxxalias_dummy ++#else ++# define _GL_CXXALIAS_SYS(func,rettype,parameters) \ ++ _GL_EXTERN_C int _gl_cxxalias_dummy ++#endif ++ ++/* _GL_CXXALIAS_SYS_CAST (func, rettype, parameters); ++ is like _GL_CXXALIAS_SYS (func, rettype, parameters); ++ except that the C function func may have a slightly different declaration. ++ A cast is used to silence the "invalid conversion" error that would ++ otherwise occur. */ ++#if defined __cplusplus && defined GNULIB_NAMESPACE ++# define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \ ++ namespace GNULIB_NAMESPACE \ ++ { \ ++ static rettype (*func) parameters = \ ++ reinterpret_cast(::func); \ ++ } \ ++ _GL_EXTERN_C int _gl_cxxalias_dummy ++#else ++# define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \ ++ _GL_EXTERN_C int _gl_cxxalias_dummy ++#endif ++ ++/* _GL_CXXALIAS_SYS_CAST2 (func, rettype, parameters, rettype2, parameters2); ++ is like _GL_CXXALIAS_SYS (func, rettype, parameters); ++ except that the C function is picked among a set of overloaded functions, ++ namely the one with rettype2 and parameters2. Two consecutive casts ++ are used to silence the "cannot find a match" and "invalid conversion" ++ errors that would otherwise occur. */ ++#if defined __cplusplus && defined GNULIB_NAMESPACE ++ /* The outer cast must be a reinterpret_cast. ++ The inner cast: When the function is defined as a set of overloaded ++ functions, it works as a static_cast<>, choosing the designated variant. ++ When the function is defined as a single variant, it works as a ++ reinterpret_cast<>. The parenthesized cast syntax works both ways. */ ++# define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \ ++ namespace GNULIB_NAMESPACE \ ++ { \ ++ static rettype (*func) parameters = \ ++ reinterpret_cast( \ ++ (rettype2(*)parameters2)(::func)); \ ++ } \ ++ _GL_EXTERN_C int _gl_cxxalias_dummy ++#else ++# define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \ ++ _GL_EXTERN_C int _gl_cxxalias_dummy ++#endif ++ ++/* _GL_CXXALIASWARN (func); ++ causes a warning to be emitted when ::func is used but not when ++ GNULIB_NAMESPACE::func is used. func must be defined without overloaded ++ variants. */ ++#if defined __cplusplus && defined GNULIB_NAMESPACE ++# define _GL_CXXALIASWARN(func) \ ++ _GL_CXXALIASWARN_1 (func, GNULIB_NAMESPACE) ++# define _GL_CXXALIASWARN_1(func,namespace) \ ++ _GL_CXXALIASWARN_2 (func, namespace) ++/* To work around GCC bug , ++ we enable the warning only when not optimizing. */ ++# if !__OPTIMIZE__ ++# define _GL_CXXALIASWARN_2(func,namespace) \ ++ _GL_WARN_ON_USE (func, \ ++ "The symbol ::" #func " refers to the system function. " \ ++ "Use " #namespace "::" #func " instead.") ++# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING ++# define _GL_CXXALIASWARN_2(func,namespace) \ ++ extern __typeof__ (func) func ++# else ++# define _GL_CXXALIASWARN_2(func,namespace) \ ++ _GL_EXTERN_C int _gl_cxxalias_dummy ++# endif ++#else ++# define _GL_CXXALIASWARN(func) \ ++ _GL_EXTERN_C int _gl_cxxalias_dummy ++#endif ++ ++/* _GL_CXXALIASWARN1 (func, rettype, parameters_and_attributes); ++ causes a warning to be emitted when the given overloaded variant of ::func ++ is used but not when GNULIB_NAMESPACE::func is used. */ ++#if defined __cplusplus && defined GNULIB_NAMESPACE ++# define _GL_CXXALIASWARN1(func,rettype,parameters_and_attributes) \ ++ _GL_CXXALIASWARN1_1 (func, rettype, parameters_and_attributes, \ ++ GNULIB_NAMESPACE) ++# define _GL_CXXALIASWARN1_1(func,rettype,parameters_and_attributes,namespace) \ ++ _GL_CXXALIASWARN1_2 (func, rettype, parameters_and_attributes, namespace) ++/* To work around GCC bug , ++ we enable the warning only when not optimizing. */ ++# if !__OPTIMIZE__ ++# define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \ ++ _GL_WARN_ON_USE_CXX (func, rettype, parameters_and_attributes, \ ++ "The symbol ::" #func " refers to the system function. " \ ++ "Use " #namespace "::" #func " instead.") ++# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING ++# define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \ ++ extern __typeof__ (func) func ++# else ++# define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \ ++ _GL_EXTERN_C int _gl_cxxalias_dummy ++# endif ++#else ++# define _GL_CXXALIASWARN1(func,rettype,parameters_and_attributes) \ ++ _GL_EXTERN_C int _gl_cxxalias_dummy ++#endif ++ ++#endif /* _GL_CXXDEFS_H */ +diff --git a/build-aux/snippet/warn-on-use.h b/build-aux/snippet/warn-on-use.h +new file mode 100644 +index 0000000..1736a1b +--- /dev/null ++++ b/build-aux/snippet/warn-on-use.h +@@ -0,0 +1,109 @@ ++/* A C macro for emitting warnings if a function is used. ++ Copyright (C) 2010-2013 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 . */ ++ ++/* _GL_WARN_ON_USE (function, "literal string") issues a declaration ++ for FUNCTION which will then trigger a compiler warning containing ++ the text of "literal string" anywhere that function is called, if ++ supported by the compiler. If the compiler does not support this ++ feature, the macro expands to an unused extern declaration. ++ ++ This macro is useful for marking a function as a potential ++ portability trap, with the intent that "literal string" include ++ instructions on the replacement function that should be used ++ instead. However, one of the reasons that a function is a ++ portability trap is if it has the wrong signature. Declaring ++ FUNCTION with a different signature in C is a compilation error, so ++ this macro must use the same type as any existing declaration so ++ that programs that avoid the problematic FUNCTION do not fail to ++ compile merely because they included a header that poisoned the ++ function. But this implies that _GL_WARN_ON_USE is only safe to ++ use if FUNCTION is known to already have a declaration. Use of ++ this macro implies that there must not be any other macro hiding ++ the declaration of FUNCTION; but undefining FUNCTION first is part ++ of the poisoning process anyway (although for symbols that are ++ provided only via a macro, the result is a compilation error rather ++ than a warning containing "literal string"). Also note that in ++ C++, it is only safe to use if FUNCTION has no overloads. ++ ++ For an example, it is possible to poison 'getline' by: ++ - adding a call to gl_WARN_ON_USE_PREPARE([[#include ]], ++ [getline]) in configure.ac, which potentially defines ++ HAVE_RAW_DECL_GETLINE ++ - adding this code to a header that wraps the system : ++ #undef getline ++ #if HAVE_RAW_DECL_GETLINE ++ _GL_WARN_ON_USE (getline, "getline is required by POSIX 2008, but" ++ "not universally present; use the gnulib module getline"); ++ #endif ++ ++ It is not possible to directly poison global variables. But it is ++ possible to write a wrapper accessor function, and poison that ++ (less common usage, like &environ, will cause a compilation error ++ rather than issue the nice warning, but the end result of informing ++ the developer about their portability problem is still achieved): ++ #if HAVE_RAW_DECL_ENVIRON ++ static char ***rpl_environ (void) { return &environ; } ++ _GL_WARN_ON_USE (rpl_environ, "environ is not always properly declared"); ++ # undef environ ++ # define environ (*rpl_environ ()) ++ #endif ++ */ ++#ifndef _GL_WARN_ON_USE ++ ++# if 4 < __GNUC__ || (__GNUC__ == 4 && 3 <= __GNUC_MINOR__) ++/* A compiler attribute is available in gcc versions 4.3.0 and later. */ ++# define _GL_WARN_ON_USE(function, message) \ ++extern __typeof__ (function) function __attribute__ ((__warning__ (message))) ++# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING ++/* Verify the existence of the function. */ ++# define _GL_WARN_ON_USE(function, message) \ ++extern __typeof__ (function) function ++# else /* Unsupported. */ ++# define _GL_WARN_ON_USE(function, message) \ ++_GL_WARN_EXTERN_C int _gl_warn_on_use ++# endif ++#endif ++ ++/* _GL_WARN_ON_USE_CXX (function, rettype, parameters_and_attributes, "string") ++ is like _GL_WARN_ON_USE (function, "string"), except that the function is ++ declared with the given prototype, consisting of return type, parameters, ++ and attributes. ++ This variant is useful for overloaded functions in C++. _GL_WARN_ON_USE does ++ not work in this case. */ ++#ifndef _GL_WARN_ON_USE_CXX ++# if 4 < __GNUC__ || (__GNUC__ == 4 && 3 <= __GNUC_MINOR__) ++# define _GL_WARN_ON_USE_CXX(function,rettype,parameters_and_attributes,msg) \ ++extern rettype function parameters_and_attributes \ ++ __attribute__ ((__warning__ (msg))) ++# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING ++/* Verify the existence of the function. */ ++# define _GL_WARN_ON_USE_CXX(function,rettype,parameters_and_attributes,msg) \ ++extern rettype function parameters_and_attributes ++# else /* Unsupported. */ ++# define _GL_WARN_ON_USE_CXX(function,rettype,parameters_and_attributes,msg) \ ++_GL_WARN_EXTERN_C int _gl_warn_on_use ++# endif ++#endif ++ ++/* _GL_WARN_EXTERN_C declaration; ++ performs the declaration with C linkage. */ ++#ifndef _GL_WARN_EXTERN_C ++# if defined __cplusplus ++# define _GL_WARN_EXTERN_C extern "C" ++# else ++# define _GL_WARN_EXTERN_C extern ++# endif ++#endif +-- +1.8.1.4 + diff --git a/0321-grub-core-disk-efi-efidisk.c-Detect-floppies-by-ACPI.patch b/0321-grub-core-disk-efi-efidisk.c-Detect-floppies-by-ACPI.patch new file mode 100644 index 0000000..9580978 --- /dev/null +++ b/0321-grub-core-disk-efi-efidisk.c-Detect-floppies-by-ACPI.patch @@ -0,0 +1,66 @@ +From 8730a9587670ebd5f7cb14d6bd5e4c7d4003a71d Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Wed, 17 Apr 2013 19:05:57 +0200 +Subject: [PATCH 321/364] * grub-core/disk/efi/efidisk.c: Detect + floppies by ACPI ID. It improves performance in qemu. + +--- + ChangeLog | 5 +++++ + grub-core/disk/efi/efidisk.c | 18 ++++++++++++++---- + 2 files changed, 19 insertions(+), 4 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 073207a..9d77a7f 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,10 @@ + 2013-04-17 Vladimir Serbinenko + ++ * grub-core/disk/efi/efidisk.c: Detect floppies by ACPI ID. ++ It improves performance in qemu. ++ ++2013-04-17 Vladimir Serbinenko ++ + * build-aux/snippet: Add missing gnulib files. + + 2013-04-16 Andrey Borzenkov +diff --git a/grub-core/disk/efi/efidisk.c b/grub-core/disk/efi/efidisk.c +index 0e08d3b..e168d07 100644 +--- a/grub-core/disk/efi/efidisk.c ++++ b/grub-core/disk/efi/efidisk.c +@@ -329,18 +329,28 @@ name_devices (struct grub_efidisk_data *devices) + { + grub_efi_device_path_t *dp; + grub_efi_block_io_media_t *m; ++ int is_floppy = 0; + + dp = d->last_device_path; + if (! dp) + continue; + + m = d->block_io->media; +- if (m->logical_partition) ++ if (GRUB_EFI_DEVICE_PATH_TYPE (dp) == GRUB_EFI_ACPI_DEVICE_PATH_TYPE ++ && GRUB_EFI_DEVICE_PATH_SUBTYPE (dp) ++ == GRUB_EFI_ACPI_DEVICE_PATH_SUBTYPE) ++ { ++ grub_efi_acpi_device_path_t *acpi ++ = (grub_efi_acpi_device_path_t *) dp; ++ /* Floppy EISA ID. */ ++ if (acpi->hid == 0x60441d0 || acpi->hid == 0x70041d0 ++ || acpi->hid == 0x70141d1) ++ is_floppy = 1; ++ } ++ if (is_floppy) + { +- /* Only one partition in a non-media device. Assume that this +- is a floppy drive. */ + #ifdef DEBUG_NAMES +- grub_printf ("adding a floppy by guessing: "); ++ grub_printf ("adding a floppy: "); + grub_efi_print_device_path (d->device_path); + #endif + add_device (&fd_devices, d); +-- +1.8.1.4 + diff --git a/0322-util-grub-mkrescue.in-Add-GPT-for-EFI-boot.patch b/0322-util-grub-mkrescue.in-Add-GPT-for-EFI-boot.patch new file mode 100644 index 0000000..dd2f132 --- /dev/null +++ b/0322-util-grub-mkrescue.in-Add-GPT-for-EFI-boot.patch @@ -0,0 +1,49 @@ +From 5217d3b6a8fd78604b0c64a75e2f52308aade398 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Wed, 17 Apr 2013 19:08:31 +0200 +Subject: [PATCH 322/364] * util/grub-mkrescue.in: Add GPT for EFI boot. + +--- + ChangeLog | 4 ++++ + util/grub-mkrescue.in | 4 ++-- + 2 files changed, 6 insertions(+), 2 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 9d77a7f..eb92ae4 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,9 @@ + 2013-04-17 Vladimir Serbinenko + ++ * util/grub-mkrescue.in: Add GPT for EFI boot. ++ ++2013-04-17 Vladimir Serbinenko ++ + * grub-core/disk/efi/efidisk.c: Detect floppies by ACPI ID. + It improves performance in qemu. + +diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in +index 7270d7f..c3ed39b 100644 +--- a/util/grub-mkrescue.in ++++ b/util/grub-mkrescue.in +@@ -421,7 +421,7 @@ if test -e "${efi64_dir}" || test -e "${efi32_dir}" || test -e "${ia64_dir}"; th + mformat -C -f 2880 -L 16 -i "${iso9660_dir}"/efi.img :: + mcopy -s -i "${iso9660_dir}"/efi.img ${efi_dir}/efi ::/ + rm -rf ${efi_dir} +- grub_mkisofs_arguments="${grub_mkisofs_arguments} --efi-boot efi.img" ++ grub_mkisofs_arguments="${grub_mkisofs_arguments} --efi-boot efi.img -efi-boot-part --efi-boot-image" + fi + + make_image_fwdisk "${ppc_dir}" powerpc-ieee1275 "${iso9660_dir}/boot/powerpc.elf" "" +@@ -443,7 +443,7 @@ EOF + "$grub_render_label" -f "$label_font" -b "$label_bgcolor" -c "$label_color" -t "${product_name} ${product_version}" -o "${iso9660_dir}/System/Library/CoreServices/.disk_label" + echo "${product_name} ${product_version}" > "${iso9660_dir}/System/Library/CoreServices/.disk_label.contentDetails" + if [ "$system_area" = common ]; then +- grub_mkisofs_arguments="${grub_mkisofs_arguments} -hfsplus -hfsplus-file-creator-type chrp tbxj /System/Library/CoreServices/.disk_label" ++ grub_mkisofs_arguments="${grub_mkisofs_arguments} -hfsplus -apm-block-size 2048 -hfsplus-file-creator-type chrp tbxj /System/Library/CoreServices/.disk_label" + fi + fi + +-- +1.8.1.4 + diff --git a/0323-Add-support-for-pseries-and-other-bootinfo-machines-.patch b/0323-Add-support-for-pseries-and-other-bootinfo-machines-.patch new file mode 100644 index 0000000..dfa04b2 --- /dev/null +++ b/0323-Add-support-for-pseries-and-other-bootinfo-machines-.patch @@ -0,0 +1,143 @@ +From 1f474bdffde1f8693707ee85f9709381d7463439 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Fri, 19 Apr 2013 00:36:23 +0200 +Subject: [PATCH 323/364] Add support for pseries and other bootinfo + machines to grub-mkrescue. + + Tested by: Paulo Flabiano Smorigo. +--- + ChangeLog | 6 +++ + grub-core/Makefile.core.def | 8 ++++ + grub-core/boot/powerpc/bootinfo.txt.in | 73 ++++++++++++++++++++++++++++++++++ + util/grub-mkrescue.in | 2 + + 4 files changed, 89 insertions(+) + create mode 100644 grub-core/boot/powerpc/bootinfo.txt.in + +diff --git a/ChangeLog b/ChangeLog +index eb92ae4..f1750b0 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,9 @@ ++2013-04-19 Vladimir Serbinenko ++ ++ Add support for pseries and other bootinfo machines to grub-mkrescue. ++ ++ Tested by: Paulo Flabiano Smorigo. ++ + 2013-04-17 Vladimir Serbinenko + + * util/grub-mkrescue.in: Add GPT for EFI boot. +diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def +index 459e566..43c4cb6 100644 +--- a/grub-core/Makefile.core.def ++++ b/grub-core/Makefile.core.def +@@ -34,6 +34,14 @@ script = { + installdir = platform; + name = grub.chrp; + common = boot/powerpc/grub.chrp.in; ++ enable = powerpc_ieee1275; ++}; ++ ++script = { ++ installdir = platform; ++ name = bootinfo.txt; ++ common = boot/powerpc/bootinfo.txt.in; ++ enable = powerpc_ieee1275; + }; + + kernel = { +diff --git a/grub-core/boot/powerpc/bootinfo.txt.in b/grub-core/boot/powerpc/bootinfo.txt.in +new file mode 100644 +index 0000000..8d6b3b0 +--- /dev/null ++++ b/grub-core/boot/powerpc/bootinfo.txt.in +@@ -0,0 +1,73 @@ ++ ++@PACKAGE@ @VERSION@ ++@PACKAGE@ @VERSION@ ++boot &device;:\boot\powerpc.elf ++ ++ ++FF FF FF FF FF FF FF FF FF FF 92 6D 6D 6D 6D 6D 6D 6D 6D 6D DB FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF B6 92 6D 92 92 92 DB FF FF FF FF FF FF FF FF FF FF ++FF FF FF FF FF FF FF DB 6D 92 DB FF FF FF FF FF DB B6 FF FF 92 6D FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 92 92 DB FF FF FF FF FF B6 6D 92 DB FF FF FF FF FF FF FF ++FF FF FF FF FF FF 49 92 FF FF B6 B6 24 00 24 00 00 00 00 49 6D DB 6D 92 DB B6 DB FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF B6 6D DB 92 6D 24 49 92 6D 6D FF FF FF 92 6D FF FF FF FF FF FF ++FF FF FF FF B6 49 DB FF FF 24 00 00 00 92 92 B6 FF DB DB FF DB B6 FF DB 92 49 DB FF FF FF FF FF FF FF FF FF FF FF FF FF DB 49 6D B6 FF 6D B6 6D 6D 92 24 24 00 00 24 6D FF FF 49 DB FF FF FF FF ++FF FF FF B6 49 FF DB 49 24 00 49 6D B6 FF B6 92 6D 6D 6D 92 DB DB DB B6 6D 92 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 6D DB FF FF FF FF DB B6 B6 B6 FF DB 24 00 00 92 B6 FF 49 FF FF FF FF ++FF FF DB 49 FF FF 49 00 00 24 FF FF 6D 49 92 DB FF FF FF DB 92 92 92 B6 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 92 92 92 6D 6D B6 DB DB B6 6D 6D FF FF 24 00 00 DB FF 49 FF FF FF ++FF FF 49 FF FF 49 00 00 6D DB DB 49 DB FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 92 B6 B6 24 00 24 DB DB 6D FF FF ++FF B6 92 FF B6 00 00 24 FF DB 6D FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 92 B6 FF 00 00 49 FF 92 B6 FF ++FF 6D FF FF 92 00 00 49 FF 6D FF FF FF FF FF FF FF FF FF FF FF FF FF B6 92 92 6D 6D 6D 6D DB FF FF FF FF FF FF B6 92 92 92 92 92 FF FF FF FF FF FF FF FF FF FF FF FF 6D FF 24 00 24 FF FF 6D FF ++DB 92 FF DB 00 00 49 FF 92 DB FF FF FF FF FF FF FF FF FF FF FF DB 6D B6 FF FF FF FF FF FF 92 6D FF FF FF FF 6D B6 FF FF FF FF FF B6 B6 FF FF FF FF FF FF FF FF FF FF FF 92 DB 00 00 92 FF 92 DB ++92 FF FF B6 00 00 6D FF 6D FF FF FF FF FF FF FF FF FF FF FF DB 6D FF FF FF 92 49 49 49 92 FF FF 49 DB DB 24 DB FF B6 49 49 92 FF FF DB 92 FF FF FF FF FF FF FF FF FF FF 92 FF 00 00 6D FF DB 92 ++6D FF FF FF 00 00 49 92 DB FF FF FF FF FF FF FF FF FF FF DB 6D FF FF 6D 00 00 00 00 00 00 00 B6 FF 49 00 24 24 49 24 00 00 00 00 6D FF DB 92 FF FF FF FF FF FF FF FF FF DB B6 00 00 92 FF FF 6D ++6D FF FF 24 00 00 DB 6D FF FF FF FF FF FF FF FF FF FF DB 6D FF DB 00 00 00 00 00 00 00 00 00 00 B6 FF DB B6 49 92 24 24 00 00 00 00 24 FF DB 92 FF FF FF FF FF FF FF FF FF 92 6D 00 00 DB FF 6D ++6D FF FF 24 00 00 FF 6D FF FF FF FF FF FF FF FF FF FF 49 FF B6 00 00 00 00 00 00 00 00 00 00 00 00 92 FF FF 92 DB DB 24 24 00 00 00 00 24 FF 92 DB FF FF FF FF FF FF FF FF 92 92 00 00 FF FF 6D ++6D FF FF B6 00 00 92 6D FF FF FF FF FF FF FF FF FF 49 FF DB 00 00 00 00 00 00 00 00 00 00 00 00 00 92 FF FF B6 B6 FF 92 24 00 00 00 00 00 49 FF 6D FF FF FF FF FF FF FF FF 92 24 00 49 FF FF 6D ++6D FF FF 00 00 00 DB 6D FF FF FF FF FF FF FF FF 6D DB DB 00 00 00 00 00 00 00 00 00 00 00 00 00 00 92 FF FF DB B6 FF B6 49 00 00 00 00 00 00 6D FF 6D FF FF FF FF FF FF FF 92 92 00 00 DB FF 6D ++6D FF FF DB 00 00 B6 6D FF FF FF FF FF FF FF 6D B6 FF 24 00 00 00 00 00 00 00 00 00 00 00 24 B6 DB 6D FF FF FF FF FF 6D 49 24 00 00 00 00 00 00 B6 DB B6 FF FF FF FF FF B6 DB 24 00 92 FF FF 6D ++6D FF FF 6D 00 00 24 DB 92 FF FF FF FF FF 92 92 FF 49 00 00 00 00 00 49 B6 FF FF DB B6 DB FF FF FF B6 92 FF FF DB 92 FF FF FF 49 6D 92 24 00 00 00 DB B6 DB FF FF FF FF 6D FF 00 00 00 DB FF 6D ++6D FF FF 92 24 00 49 FF 6D B6 FF FF FF 6D 92 FF 49 00 00 49 DB FF FF FF FF FF FF B6 FF FF FF FF FF FF B6 6D 92 92 FF FF FF FF 6D FF FF FF DB 24 00 24 FF 92 B6 FF FF 92 B6 FF 00 00 B6 FF FF 6D ++92 FF FF FF 00 00 24 92 FF 92 6D 92 49 B6 DB 24 00 24 DB FF FF FF FF FF DB 92 24 00 FF FF FF FF 6D 6D FF FF FF 6D 6D FF FF B6 DB 6D FF FF FF FF 00 00 24 DB B6 6D 6D B6 DB 00 00 00 6D FF FF 6D ++DB 92 FF DB 49 00 00 00 B6 FF FF DB FF 6D 00 00 6D FF FF FF FF FF FF FF 24 92 00 49 FF FF FF FF FF 6D B6 FF FF 6D 6D FF 6D 00 DB DB 92 FF FF FF DB 00 00 00 6D FF FF DB 6D 00 00 24 FF FF 92 DB ++FF 49 FF FF 6D 00 00 00 24 49 B6 FF 24 00 00 6D FF FF FF FF FF FF FF 49 92 B6 00 DB FF FF DB DB FF FF B6 FF FF FF FF FF 00 49 DB FF 92 FF FF FF FF 92 00 00 00 24 6D 00 00 00 00 24 DB FF 49 FF ++FF 92 B6 FF 92 49 00 00 00 00 00 24 00 00 00 FF FF FF FF FF FF FF 92 6D FF B6 DB FF DB B6 DB B6 B6 FF FF B6 FF FF FF DB 00 B6 DB FF 92 FF FF FF FF FF 24 00 00 00 00 00 00 00 00 B6 FF 92 B6 FF ++FF FF 49 FF FF 49 24 00 00 00 00 00 00 00 B6 FF FF FF FF FF FF FF B6 FF FF FF FF FF FF FF FF FF 6D FF FF 6D FF FF FF DB 24 FF FF FF 92 FF FF FF FF FF 6D 00 00 00 00 00 00 00 DB FF FF 6D FF FF ++FF FF DB 6D FF FF 6D 49 00 00 00 00 00 24 FF FF FF FF FF FF FF FF FF FF FF FF FF DB 6D 49 24 24 24 FF FF DB FF FF FF FF 24 24 00 00 92 FF FF FF FF FF DB 00 00 00 00 00 00 FF DB FF 6D FF FF FF ++FF FF FF 92 B6 FF FF DB 49 24 00 00 00 92 FF FF FF FF FF FF FF FF FF DB FF FF FF 49 49 24 00 24 FF FF FF FF FF FF FF FF 49 6D 00 24 49 FF FF FF FF FF FF 49 00 24 6D 6D B6 FF FF 6D B6 FF FF FF ++FF FF FF FF 6D B6 FF FF DB 92 B6 49 00 FF FF FF FF FF FF FF FF FF FF B6 FF FF FF 92 DB 92 00 24 FF FF FF FF FF FF FF FF FF 00 00 6D FF FF FF FF FF FF FF DB 00 6D DB FF FF FF 6D B6 FF FF FF FF ++FF FF FF FF FF 92 6D FF FF FF FF B6 49 FF FF FF FF FF FF FF FF FF FF 6D FF FF FF FF B6 92 92 B6 B6 DB FF FF FF FF FF FF FF B6 6D 49 6D FF FF FF FF FF FF FF 92 24 FF FF B6 6D DB FF FF FF FF FF ++FF FF FF FF FF FF DB 49 6D B6 FF 6D 92 FF FF FF FF FF FF FF FF FF DB 6D FF FF FF FF FF FF FF FF FF 92 FF FF FF FF FF FF FF FF 6D DB 92 FF FF FF FF FF FF FF FF 6D 49 6D DB FF FF FF FF FF FF FF ++FF FF FF FF FF FF FF FF DB 92 49 00 FF FF FF FF FF FF FF FF FF FF 6D 92 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 92 92 6D FF FF FF FF FF FF FF DB 92 FF FF FF FF FF FF FF FF FF ++FF FF FF FF FF FF FF FF FF FF FF 49 FF FF FF FF FF FF FF FF FF DB 00 92 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 92 B6 92 6D B6 FF FF FF FF FF FF 49 DB FF FF FF FF FF FF FF FF ++FF FF FF FF FF FF FF FF FF FF FF 24 FF FF FF FF FF FF FF FF FF 49 DB 92 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 6D 6D FF 92 49 92 FF FF FF FF DB 49 DB FF FF FF FF FF FF FF ++FF FF FF FF FF FF FF FF FF FF B6 49 FF FF FF FF FF FF FF FF 6D 92 FF 92 FF FF FF FF FF FF FF FF FF FF B6 6D 49 6D DB FF FF FF FF FF 6D 49 FF FF FF DB 6D 6D 92 92 6D 49 FF FF FF FF FF FF FF FF ++FF FF FF FF FF FF FF FF FF FF 24 FF FF FF FF FF FF FF FF 6D 92 FF FF FF DB FF FF FF FF FF FF FF FF 6D 6D FF FF FF 92 6D FF FF FF FF FF 49 92 B6 92 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ++FF FF FF FF FF FF FF FF FF DB 6D FF FF FF FF FF FF DB 24 92 FF FF FF FF FF FF FF FF FF FF FF FF FF 49 49 6D DB FF FF DB 6D B6 FF FF FF FF B6 B6 DB 49 FF FF FF FF FF FF FF FF FF FF FF FF FF FF ++FF FF FF FF FF FF FF FF FF 24 B6 FF FF FF FF B6 49 49 24 B6 FF FF FF FF FF FF FF FF FF FF FF FF FF 00 49 FF DB DB FF FF FF B6 92 FF FF FF FF FF FF 92 DB FF FF FF FF FF FF FF FF FF FF FF FF FF ++FF FF FF FF FF FF FF FF 24 B6 FF FF B6 24 00 6D DB FF 6D 92 FF FF FF FF FF FF FF FF FF FF FF FF FF 6D DB DB 00 00 24 FF FF FF FF B6 FF FF FF FF FF B6 B6 FF FF FF FF FF FF FF FF FF FF FF FF FF ++FF FF FF FF FF FF FF B6 B6 DB B6 6D 49 49 92 FF FF FF B6 6D FF FF FF FF FF FF FF 92 92 FF FF FF FF FF FF FF 49 92 DB 49 FF FF FF FF FF FF FF FF FF 92 B6 FF FF FF FF FF FF FF FF FF FF FF FF FF ++FF FF FF FF FF FF FF 92 24 49 49 6D FF 6D 92 FF FF FF B6 6D FF FF FF FF FF FF FF FF FF FF DB FF FF FF FF FF FF FF FF B6 FF FF FF FF FF FF FF FF FF 49 FF FF FF FF FF FF FF FF FF FF FF FF FF FF ++FF FF FF FF FF FF FF FF FF FF FF FF FF 6D 92 FF FF FF B6 6D FF FF FF FF FF FF FF FF FF FF B6 DB DB FF FF FF FF FF FF FF DB FF FF FF FF FF FF FF 6D 92 FF FF FF FF FF FF FF FF FF FF FF FF FF FF ++FF FF FF FF FF FF FF FF FF FF FF FF FF 6D 92 FF FF FF FF 24 92 FF FF FF FF FF FF FF FF FF FF 6D B6 FF FF FF FF FF FF FF FF FF FF FF FF FF DB 49 92 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ++FF FF FF FF FF FF FF FF FF FF FF FF FF 6D B6 FF FF FF FF B6 6D FF FF FF FF FF FF FF FF FF FF B6 92 FF FF FF FF FF FF FF FF FF FF FF DB 6D 00 B6 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ++FF FF FF FF FF FF FF FF FF FF FF FF FF 6D 92 FF FF FF FF DB 49 FF FF FF FF FF FF FF FF FF FF FF 49 FF FF FF FF FF FF FF FF FF FF FF FF FF DB 49 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ++FF FF FF FF FF FF FF FF FF FF FF FF FF 92 6D FF FF FF FF FF 00 24 DB FF FF FF FF FF FF FF FF FF DB 6D FF FF FF FF FF FF FF FF FF FF FF FF FF FF 49 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ++FF FF FF FF FF FF FF FF FF FF FF FF FF B6 49 FF FF FF FF FF FF 92 6D FF FF FF FF FF FF FF FF FF FF 6D B6 FF FF FF FF FF FF FF FF FF FF FF FF B6 49 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ++FF FF FF FF FF FF FF FF FF FF FF FF FF FF 00 FF FF FF FF FF FF FF 49 00 DB FF FF FF FF FF FF FF FF FF 6D 6D B6 DB DB DB 92 49 00 00 00 00 00 49 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ++FF FF FF FF FF FF FF FF FF FF FF FF FF FF 49 DB FF FF FF FF FF FF FF 24 FF FF FF FF FF FF FF FF FF FF FF DB 6D 49 49 6D B6 DB FF FF FF B6 6D FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ++FF FF FF FF FF FF FF FF FF FF FF FF FF FF 92 92 FF FF FF FF FF FF B6 6D FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 6D FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ++FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 24 FF FF FF FF FF FF DB 00 B6 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF DB 92 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ++FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 92 B6 FF FF FF FF FF FF DB 6D 00 49 FF FF FF FF FF FF FF FF FF FF FF FF DB B6 92 6D 6D 6D 49 DB FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ++FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 49 FF FF FF FF FF FF FF FF 49 00 92 FF FF FF FF FF FF FF FF 49 00 00 00 00 00 49 B6 DB FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ++FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF DB 6D FF FF FF FF FF FF FF FF 6D 6D FF B6 B6 FF FF FF FF FF FF 92 92 FF FF 00 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ++FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 92 B6 FF FF FF FF FF FF DB 00 DB 6D 00 B6 FF FF FF FF FF FF FF FF FF FF 24 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ++FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 92 DB FF FF FF FF FF 92 00 FF 24 00 00 49 FF FF FF FF FF FF FF FF FF B6 B6 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ++FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 92 FF FF FF FF FF FF 49 24 24 00 00 6D FF FF FF FF FF FF FF DB FF DB 6D FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ++FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF B6 FF FF FF FF FF FF 6D 00 24 24 24 FF FF FF FF FF FF DB B6 DB 49 B6 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ++FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF B6 00 B6 00 49 DB FF FF FF DB 24 6D 24 B6 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ++FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 00 B6 6D 00 00 DB FF 6D 00 00 00 DB FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ++FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF DB 00 6D FF FF 00 00 DB 49 00 00 00 00 B6 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ++FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 92 DB FF FF 6D 00 00 92 24 00 00 00 00 00 B6 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ++FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF B6 FF FF 00 6D 00 00 24 00 00 00 00 00 00 24 92 DB FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ++FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 6D DB 00 00 00 00 00 00 00 00 00 00 92 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ++FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF DB 00 24 00 00 6D 00 00 00 B6 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ++FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF DB 49 92 6D 6D DB B6 92 92 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ++ ++ ++ +diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in +index c3ed39b..5a5d4e3 100644 +--- a/util/grub-mkrescue.in ++++ b/util/grub-mkrescue.in +@@ -449,6 +449,8 @@ fi + + if [ -e "${iso9660_dir}/boot/powerpc.elf" ] ; then + cp "${ppc_dir}/grub.chrp" "${iso9660_dir}"/System/Library/CoreServices/BootX ++ mkdir -p "${iso9660_dir}"/ppc/chrp ++ cp "${ppc_dir}/bootinfo.txt" "${iso9660_dir}"/ppc/bootinfo.txt + cp "${iso9660_dir}/boot/powerpc.elf" "${iso9660_dir}"/System/Library/CoreServices/grub.elf + # FIXME: add PreP + if [ "$system_area" = common ]; then +-- +1.8.1.4 + diff --git a/0324-util-grub.d-30_os-prober.in-Add-onstr-to-linux-entri.patch b/0324-util-grub.d-30_os-prober.in-Add-onstr-to-linux-entri.patch new file mode 100644 index 0000000..319afe2 --- /dev/null +++ b/0324-util-grub.d-30_os-prober.in-Add-onstr-to-linux-entri.patch @@ -0,0 +1,40 @@ +From c41277eb3f80c1ed4cde9c0536abaa31becba0c5 Mon Sep 17 00:00:00 2001 +From: Andrey Borzenkov +Date: Fri, 19 Apr 2013 12:08:46 +0400 +Subject: [PATCH 324/364] * util/grub.d/30_os-prober.in: Add onstr to linux + entries in one more place. + +--- + ChangeLog | 5 +++++ + util/grub.d/30_os-prober.in | 2 +- + 2 files changed, 6 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index f1750b0..7450036 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,8 @@ ++2013-04-19 Andrey Borzenkov ++ ++ * util/grub.d/30_os-prober.in: Add onstr to linux entries in one ++ more place. ++ + 2013-04-19 Vladimir Serbinenko + + Add support for pseries and other bootinfo machines to grub-mkrescue. +diff --git a/util/grub.d/30_os-prober.in b/util/grub.d/30_os-prober.in +index 5500a3c..04f32a1 100644 +--- a/util/grub.d/30_os-prober.in ++++ b/util/grub.d/30_os-prober.in +@@ -231,7 +231,7 @@ EOF + } + EOF + if [ x"$title" = x"$GRUB_ACTUAL_DEFAULT" ] || [ x"Previous Linux versions>$title" = x"$GRUB_ACTUAL_DEFAULT" ]; then +- replacement_title="$(echo "Advanced options for ${OS}" | sed 's,>,>>,g')>$(echo "$title" | sed 's,>,>>,g')" ++ replacement_title="$(echo "Advanced options for ${OS} $onstr" | sed 's,>,>>,g')>$(echo "$title" | sed 's,>,>>,g')" + quoted="$(echo "$GRUB_ACTUAL_DEFAULT" | grub_quote)" + title_correction_code="${title_correction_code}if [ \"x\$default\" = '$quoted' ]; then default='$(echo "$replacement_title" | grub_quote)'; fi;" + grub_warn "$(gettext_printf "Please don't use old title \`%s' for GRUB_DEFAULT, use \`%s' (for versions before 2.00) or \`%s' (for 2.00 or later)" "$GRUB_ACTUAL_DEFAULT" "$replacement_title" "gnulinux-advanced-$boot_device_id>gnulinux-$version-$type-$boot_device_id")" +-- +1.8.1.4 + diff --git a/0325-grub-core-kern-elfXX.c-grub_elfXX_load-Handle.patch b/0325-grub-core-kern-elfXX.c-grub_elfXX_load-Handle.patch new file mode 100644 index 0000000..28887e8 --- /dev/null +++ b/0325-grub-core-kern-elfXX.c-grub_elfXX_load-Handle.patch @@ -0,0 +1,98 @@ +From 8968eeb2ff92930128a5d9820157de08876ab489 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Fri, 19 Apr 2013 15:05:11 +0200 +Subject: [PATCH 325/364] * grub-core/kern/elfXX.c (grub_elfXX_load): + Handle GRUB_ELF_LOAD_FLAGS_30BITS and GRUB_ELF_LOAD_FLAGS_62BITS. + * grub-core/loader/powerpc/ieee1275/linux.c (grub_linux_load32), + (grub_linux_load64): Mask out 2 high bits. + +--- + ChangeLog | 7 +++++++ + grub-core/kern/elfXX.c | 16 ++++++++++++++-- + grub-core/loader/powerpc/ieee1275/linux.c | 4 ++-- + include/grub/elfload.h | 4 ++++ + 4 files changed, 27 insertions(+), 4 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 7450036..3799129 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,10 @@ ++2013-04-19 Vladimir Serbinenko ++ ++ * grub-core/kern/elfXX.c (grub_elfXX_load): Handle ++ GRUB_ELF_LOAD_FLAGS_30BITS and GRUB_ELF_LOAD_FLAGS_62BITS. ++ * grub-core/loader/powerpc/ieee1275/linux.c (grub_linux_load32), ++ (grub_linux_load64): Mask out 2 high bits. ++ + 2013-04-19 Andrey Borzenkov + + * util/grub.d/30_os-prober.in: Add onstr to linux entries in one +diff --git a/grub-core/kern/elfXX.c b/grub-core/kern/elfXX.c +index b35e235..2e45449 100644 +--- a/grub-core/kern/elfXX.c ++++ b/grub-core/kern/elfXX.c +@@ -101,8 +101,20 @@ grub_elfXX_load (grub_elf_t elf, const char *filename, + continue; + + load_addr = (grub_addr_t) phdr->p_paddr; +- if (load_flags & GRUB_ELF_LOAD_FLAGS_28BITS) +- load_addr &= 0xFFFFFFF; ++ switch (load_flags & GRUB_ELF_LOAD_FLAGS_BITS) ++ { ++ case GRUB_ELF_LOAD_FLAGS_ALL_BITS: ++ break; ++ case GRUB_ELF_LOAD_FLAGS_28BITS: ++ load_addr &= 0xFFFFFFF; ++ break; ++ case GRUB_ELF_LOAD_FLAGS_30BITS: ++ load_addr &= 0x3FFFFFFF; ++ break; ++ case GRUB_ELF_LOAD_FLAGS_62BITS: ++ load_addr &= 0x3FFFFFFFFFFFFFFFULL; ++ break; ++ } + load_addr += (grub_addr_t) load_offset; + + if (load_addr < load_base) +diff --git a/grub-core/loader/powerpc/ieee1275/linux.c b/grub-core/loader/powerpc/ieee1275/linux.c +index cff4fd1..3356d51 100644 +--- a/grub-core/loader/powerpc/ieee1275/linux.c ++++ b/grub-core/loader/powerpc/ieee1275/linux.c +@@ -204,7 +204,7 @@ grub_linux_load32 (grub_elf_t elf, const char *filename) + linux_addr = seg_addr; + + /* Now load the segments into the area we claimed. */ +- return grub_elf32_load (elf, filename, (void *) (seg_addr - base_addr), GRUB_ELF_LOAD_FLAGS_NONE, 0, 0); ++ return grub_elf32_load (elf, filename, (void *) (seg_addr - base_addr), GRUB_ELF_LOAD_FLAGS_30BITS, 0, 0); + } + + static grub_err_t +@@ -238,7 +238,7 @@ grub_linux_load64 (grub_elf_t elf, const char *filename) + linux_addr = seg_addr; + + /* Now load the segments into the area we claimed. */ +- return grub_elf64_load (elf, filename, (void *) (grub_addr_t) (seg_addr - base_addr), GRUB_ELF_LOAD_FLAGS_NONE, 0, 0); ++ return grub_elf64_load (elf, filename, (void *) (grub_addr_t) (seg_addr - base_addr), GRUB_ELF_LOAD_FLAGS_62BITS, 0, 0); + } + + static grub_err_t +diff --git a/include/grub/elfload.h b/include/grub/elfload.h +index f854d0b..9a7ae4e 100644 +--- a/include/grub/elfload.h ++++ b/include/grub/elfload.h +@@ -53,7 +53,11 @@ enum grub_elf_load_flags + { + GRUB_ELF_LOAD_FLAGS_NONE = 0, + GRUB_ELF_LOAD_FLAGS_LOAD_PT_DYNAMIC = 1, ++ GRUB_ELF_LOAD_FLAGS_BITS = 6, ++ GRUB_ELF_LOAD_FLAGS_ALL_BITS = 0, + GRUB_ELF_LOAD_FLAGS_28BITS = 2, ++ GRUB_ELF_LOAD_FLAGS_30BITS = 4, ++ GRUB_ELF_LOAD_FLAGS_62BITS = 6, + }; + grub_err_t grub_elf32_load (grub_elf_t, const char *filename, + void *load_offset, enum grub_elf_load_flags flags, grub_addr_t *, +-- +1.8.1.4 + diff --git a/0326-grub-core-commands-videotest.c-grub_cmd_videotest-Fi.patch b/0326-grub-core-commands-videotest.c-grub_cmd_videotest-Fi.patch new file mode 100644 index 0000000..21a7877 --- /dev/null +++ b/0326-grub-core-commands-videotest.c-grub_cmd_videotest-Fi.patch @@ -0,0 +1,76 @@ +From 6ca7e5c09db09a01fad50538908e5d8da439d15b Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Fri, 19 Apr 2013 15:09:15 +0200 +Subject: [PATCH 326/364] * grub-core/commands/videotest.c + (grub_cmd_videotest): Fix error handling when creating text_layer + failed. * grub-core/video/video.c (grub_video_create_render_target): + Set result to 0 on error. (grub_video_delete_render_target): Do not + dereference NULL. + +--- + ChangeLog | 8 ++++++++ + grub-core/commands/videotest.c | 8 ++++---- + grub-core/video/video.c | 3 +++ + 3 files changed, 15 insertions(+), 4 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 3799129..3d4b23d 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,13 @@ + 2013-04-19 Vladimir Serbinenko + ++ * grub-core/commands/videotest.c (grub_cmd_videotest): Fix error ++ handling when creating text_layer failed. ++ * grub-core/video/video.c (grub_video_create_render_target): ++ Set result to 0 on error. ++ (grub_video_delete_render_target): Do not dereference NULL. ++ ++2013-04-19 Vladimir Serbinenko ++ + * grub-core/kern/elfXX.c (grub_elfXX_load): Handle + GRUB_ELF_LOAD_FLAGS_30BITS and GRUB_ELF_LOAD_FLAGS_62BITS. + * grub-core/loader/powerpc/ieee1275/linux.c (grub_linux_load32), +diff --git a/grub-core/commands/videotest.c b/grub-core/commands/videotest.c +index 2e4b3a2..2256237 100644 +--- a/grub-core/commands/videotest.c ++++ b/grub-core/commands/videotest.c +@@ -71,10 +71,10 @@ grub_cmd_videotest (grub_command_t cmd __attribute__ ((unused)), + grub_font_t fixed; + struct grub_font_glyph *glyph; + +- grub_video_create_render_target (&text_layer, width, height, +- GRUB_VIDEO_MODE_TYPE_RGB +- | GRUB_VIDEO_MODE_TYPE_ALPHA); +- if (!text_layer) ++ if (grub_video_create_render_target (&text_layer, width, height, ++ GRUB_VIDEO_MODE_TYPE_RGB ++ | GRUB_VIDEO_MODE_TYPE_ALPHA) ++ || !text_layer) + goto fail; + + grub_video_set_active_render_target (text_layer); +diff --git a/grub-core/video/video.c b/grub-core/video/video.c +index aab9b18..844f36c 100644 +--- a/grub-core/video/video.c ++++ b/grub-core/video/video.c +@@ -339,6 +339,7 @@ grub_video_create_render_target (struct grub_video_render_target **result, + unsigned int width, unsigned int height, + unsigned int mode_type) + { ++ *result = 0; + if (! grub_video_adapter_active) + return grub_error (GRUB_ERR_BAD_DEVICE, "no video mode activated"); + +@@ -351,6 +352,8 @@ grub_video_create_render_target (struct grub_video_render_target **result, + grub_err_t + grub_video_delete_render_target (struct grub_video_render_target *target) + { ++ if (!target) ++ return GRUB_ERR_NONE; + if (! grub_video_adapter_active) + return grub_error (GRUB_ERR_BAD_DEVICE, "no video mode activated"); + +-- +1.8.1.4 + diff --git a/0327-grub-core-kern-ieee1275-cmain.c-grub_ieee1275_find_o.patch b/0327-grub-core-kern-ieee1275-cmain.c-grub_ieee1275_find_o.patch new file mode 100644 index 0000000..0c5db97 --- /dev/null +++ b/0327-grub-core-kern-ieee1275-cmain.c-grub_ieee1275_find_o.patch @@ -0,0 +1,43 @@ +From 75986a1d11394947d19381a7d8a7ff677caccbbe Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Fri, 19 Apr 2013 15:14:28 +0200 +Subject: [PATCH 327/364] * grub-core/kern/ieee1275/cmain.c + (grub_ieee1275_find_options): Look for /boot-rom as well as /rom/boot-rom. + +--- + ChangeLog | 5 +++++ + grub-core/kern/ieee1275/cmain.c | 3 ++- + 2 files changed, 7 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index 3d4b23d..488be60 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,10 @@ + 2013-04-19 Vladimir Serbinenko + ++ * grub-core/kern/ieee1275/cmain.c (grub_ieee1275_find_options): ++ Look for /boot-rom as well as /rom/boot-rom. ++ ++2013-04-19 Vladimir Serbinenko ++ + * grub-core/commands/videotest.c (grub_cmd_videotest): Fix error + handling when creating text_layer failed. + * grub-core/video/video.c (grub_video_create_render_target): +diff --git a/grub-core/kern/ieee1275/cmain.c b/grub-core/kern/ieee1275/cmain.c +index 5f6a6da..abd1ca9 100644 +--- a/grub-core/kern/ieee1275/cmain.c ++++ b/grub-core/kern/ieee1275/cmain.c +@@ -186,7 +186,8 @@ grub_ieee1275_find_options (void) + grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_HAS_CURSORONOFF); + } + +- if (! grub_ieee1275_finddevice ("/rom/boot-rom", &bootrom)) ++ if (! grub_ieee1275_finddevice ("/rom/boot-rom", &bootrom) ++ || ! grub_ieee1275_finddevice ("/boot-rom", &bootrom)) + { + rc = grub_ieee1275_get_property (bootrom, "model", tmp, sizeof (tmp), 0); + if (rc >= 0 && !grub_strncmp (tmp, "PPC Open Hack'Ware", +-- +1.8.1.4 + diff --git a/0328-grub-core-kern-ieee1275-init.c-grub_claim_heap-Impro.patch b/0328-grub-core-kern-ieee1275-init.c-grub_claim_heap-Impro.patch new file mode 100644 index 0000000..3340bfe --- /dev/null +++ b/0328-grub-core-kern-ieee1275-init.c-grub_claim_heap-Impro.patch @@ -0,0 +1,118 @@ +From 00c99f9ffcadba94105b7871744f2a3760b7dd35 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Fri, 19 Apr 2013 15:27:09 +0200 +Subject: [PATCH 328/364] * grub-core/kern/ieee1275/init.c + (grub_claim_heap): Improve handling of GRUB_IEEE1275_FLAG_FORCE_CLAIM. + * grub-core/loader/powerpc/ieee1275/linux.c (grub_linux_claimmap_iterate): + Handle GRUB_IEEE1275_FLAG_FORCE_CLAIM. + +--- + ChangeLog | 7 +++++++ + grub-core/kern/ieee1275/init.c | 5 +++-- + grub-core/lib/ieee1275/relocator.c | 4 ++-- + grub-core/loader/powerpc/ieee1275/linux.c | 14 ++++++++++++++ + include/grub/ieee1275/ieee1275.h | 8 ++++++++ + 5 files changed, 34 insertions(+), 4 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 488be60..3e606cb 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,12 @@ + 2013-04-19 Vladimir Serbinenko + ++ * grub-core/kern/ieee1275/init.c (grub_claim_heap): Improve handling ++ of GRUB_IEEE1275_FLAG_FORCE_CLAIM. ++ * grub-core/loader/powerpc/ieee1275/linux.c ++ (grub_linux_claimmap_iterate): Handle GRUB_IEEE1275_FLAG_FORCE_CLAIM. ++ ++2013-04-19 Vladimir Serbinenko ++ + * grub-core/kern/ieee1275/cmain.c (grub_ieee1275_find_options): + Look for /boot-rom as well as /rom/boot-rom. + +diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c +index 391a734..ce8eadb 100644 +--- a/grub-core/kern/ieee1275/init.c ++++ b/grub-core/kern/ieee1275/init.c +@@ -225,8 +225,9 @@ grub_claim_heap (void) + { + unsigned long total = 0; + +- if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_CANNOT_INTERPRET)) +- heap_init (HEAP_MAX_ADDR - HEAP_MIN_SIZE, HEAP_MIN_SIZE, 1, &total); ++ if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_FORCE_CLAIM)) ++ heap_init (GRUB_IEEE1275_STATIC_HEAP_START, GRUB_IEEE1275_STATIC_HEAP_LEN, ++ 1, &total); + else + grub_machine_mmap_iterate (heap_init, &total); + } +diff --git a/grub-core/lib/ieee1275/relocator.c b/grub-core/lib/ieee1275/relocator.c +index f6ecadd..c6dd8fa 100644 +--- a/grub-core/lib/ieee1275/relocator.c ++++ b/grub-core/lib/ieee1275/relocator.c +@@ -38,7 +38,7 @@ grub_relocator_firmware_get_max_events (void) + { + int counter = 0; + +- if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_CANNOT_INTERPRET)) ++ if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_FORCE_CLAIM)) + return 0; + grub_machine_mmap_iterate (count, &counter); + return 2 * counter; +@@ -92,7 +92,7 @@ grub_relocator_firmware_fill_events (struct grub_relocator_mmap_event *events) + .counter = 0 + }; + +- if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_CANNOT_INTERPRET)) ++ if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_FORCE_CLAIM)) + return 0; + grub_machine_mmap_iterate (grub_relocator_firmware_fill_events_iter, &ctx); + return ctx.counter; +diff --git a/grub-core/loader/powerpc/ieee1275/linux.c b/grub-core/loader/powerpc/ieee1275/linux.c +index 3356d51..4a14f66 100644 +--- a/grub-core/loader/powerpc/ieee1275/linux.c ++++ b/grub-core/loader/powerpc/ieee1275/linux.c +@@ -111,6 +111,20 @@ grub_linux_claimmap_iterate (grub_addr_t target, grub_size_t size, + .found_addr = (grub_addr_t) -1 + }; + ++ if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_FORCE_CLAIM)) ++ { ++ grub_uint64_t addr = target; ++ if (addr < GRUB_IEEE1275_STATIC_HEAP_START ++ + GRUB_IEEE1275_STATIC_HEAP_LEN) ++ addr = GRUB_IEEE1275_STATIC_HEAP_START ++ + GRUB_IEEE1275_STATIC_HEAP_LEN; ++ addr = ALIGN_UP (addr, align); ++ if (grub_claimmap (addr, size) == GRUB_ERR_NONE) ++ return addr; ++ return (grub_addr_t) -1; ++ } ++ ++ + grub_machine_mmap_iterate (alloc_mem, &ctx); + + return ctx.found_addr; +diff --git a/include/grub/ieee1275/ieee1275.h b/include/grub/ieee1275/ieee1275.h +index 1e8ba6f..1b240d3 100644 +--- a/include/grub/ieee1275/ieee1275.h ++++ b/include/grub/ieee1275/ieee1275.h +@@ -78,6 +78,14 @@ extern grub_ieee1275_phandle_t EXPORT_VAR(grub_ieee1275_chosen); + extern grub_ieee1275_ihandle_t EXPORT_VAR(grub_ieee1275_mmu); + extern int (* EXPORT_VAR(grub_ieee1275_entry_fn)) (void *); + ++/* Static heap, used only if FORCE_CLAIM is set, ++ happens on Open Hack'Ware. Should be in platform-specific ++ header but is used only on PPC anyway. ++*/ ++#define GRUB_IEEE1275_STATIC_HEAP_START 0x1000000 ++#define GRUB_IEEE1275_STATIC_HEAP_LEN 0x1000000 ++ ++ + enum grub_ieee1275_flag + { + /* Old World Macintosh firmware fails seek when "dev:0" is opened. */ +-- +1.8.1.4 + diff --git a/0329-grub-core-lib-efi-relocator.c-grub_relocator_firmwar.patch b/0329-grub-core-lib-efi-relocator.c-grub_relocator_firmwar.patch new file mode 100644 index 0000000..1428e07 --- /dev/null +++ b/0329-grub-core-lib-efi-relocator.c-grub_relocator_firmwar.patch @@ -0,0 +1,63 @@ +From 341b25a836be3f65230eb4077a202c66e9160b29 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sat, 20 Apr 2013 13:39:04 +0200 +Subject: [PATCH 329/364] * grub-core/lib/efi/relocator.c + (grub_relocator_firmware_alloc_region): Remove dprintf. * + grub-core/lib/relocator.c (malloc_in_range): Likewise. + +--- + ChangeLog | 6 ++++++ + grub-core/lib/efi/relocator.c | 4 ++-- + grub-core/lib/relocator.c | 2 ++ + 3 files changed, 10 insertions(+), 2 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 3e606cb..6ca70a6 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,9 @@ ++2013-04-20 Vladimir Serbinenko ++ ++ * grub-core/lib/efi/relocator.c (grub_relocator_firmware_alloc_region): ++ Remove dprintf. ++ * grub-core/lib/relocator.c (malloc_in_range): Likewise. ++ + 2013-04-19 Vladimir Serbinenko + + * grub-core/kern/ieee1275/init.c (grub_claim_heap): Improve handling +diff --git a/grub-core/lib/efi/relocator.c b/grub-core/lib/efi/relocator.c +index 0d346be..319b69e 100644 +--- a/grub-core/lib/efi/relocator.c ++++ b/grub-core/lib/efi/relocator.c +@@ -96,10 +96,10 @@ grub_relocator_firmware_alloc_region (grub_addr_t start, grub_size_t size) + + if (grub_efi_is_finished) + return 1; +- ++#ifdef DEBUG_RELOCATOR_NOMEM_DPRINTF + grub_dprintf ("relocator", "EFI alloc: %llx, %llx\n", + (unsigned long long) start, (unsigned long long) size); +- ++#endif + b = grub_efi_system_table->boot_services; + status = efi_call_4 (b->allocate_pages, GRUB_EFI_ALLOCATE_ADDRESS, + GRUB_EFI_LOADER_DATA, size >> 12, &address); +diff --git a/grub-core/lib/relocator.c b/grub-core/lib/relocator.c +index 350066d..e085514 100644 +--- a/grub-core/lib/relocator.c ++++ b/grub-core/lib/relocator.c +@@ -984,9 +984,11 @@ malloc_in_range (struct grub_relocator *rel, + alloc_end = min (events[j].pos, target + size); + if (alloc_end > alloc_start) + { ++#ifdef DEBUG_RELOCATOR_NOMEM_DPRINTF + grub_dprintf ("relocator", "subchunk 0x%lx-0x%lx, %d\n", + (unsigned long) alloc_start, + (unsigned long) alloc_end, typepre); ++#endif + curschu->type = typepre; + curschu->start = alloc_start; + curschu->size = alloc_end - alloc_start; +-- +1.8.1.4 + diff --git a/0330-grub-core-Makefile.core.def-legacycfg-Enable-on-EFI.patch b/0330-grub-core-Makefile.core.def-legacycfg-Enable-on-EFI.patch new file mode 100644 index 0000000..ea91df7 --- /dev/null +++ b/0330-grub-core-Makefile.core.def-legacycfg-Enable-on-EFI.patch @@ -0,0 +1,45 @@ +From 786c3d387a87687707eff778ea77a17b7a1b1ab7 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sat, 20 Apr 2013 13:46:58 +0200 +Subject: [PATCH 330/364] * grub-core/Makefile.core.def (legacycfg): + Enable on EFI. + +--- + ChangeLog | 4 ++++ + grub-core/Makefile.core.def | 5 +++++ + 2 files changed, 9 insertions(+) + +diff --git a/ChangeLog b/ChangeLog +index 6ca70a6..b2e3ccc 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,9 @@ + 2013-04-20 Vladimir Serbinenko + ++ * grub-core/Makefile.core.def (legacycfg): Enable on EFI. ++ ++2013-04-20 Vladimir Serbinenko ++ + * grub-core/lib/efi/relocator.c (grub_relocator_firmware_alloc_region): + Remove dprintf. + * grub-core/lib/relocator.c (malloc_in_range): Likewise. +diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def +index 43c4cb6..1f04afb 100644 +--- a/grub-core/Makefile.core.def ++++ b/grub-core/Makefile.core.def +@@ -1856,7 +1856,12 @@ module = { + common = commands/legacycfg.c; + common = lib/legacy_parse.c; + emu = lib/i386/pc/vesa_modes_table.c; ++ i386_efi = lib/i386/pc/vesa_modes_table.c; ++ x86_64_efi = lib/i386/pc/vesa_modes_table.c; ++ + enable = i386_pc; ++ enable = i386_efi; ++ enable = x86_64_efi; + enable = emu; + }; + +-- +1.8.1.4 + diff --git a/0331-grub-core-kern-mm.c-grub_mm_init_region-Fix-conditio.patch b/0331-grub-core-kern-mm.c-grub_mm_init_region-Fix-conditio.patch new file mode 100644 index 0000000..ad9e8a2 --- /dev/null +++ b/0331-grub-core-kern-mm.c-grub_mm_init_region-Fix-conditio.patch @@ -0,0 +1,49 @@ +From 761e63a2a5f38419acd0e54d6b54845e65a152dc Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sat, 20 Apr 2013 17:39:49 +0200 +Subject: [PATCH 331/364] * grub-core/kern/mm.c (grub_mm_init_region): + Fix condition for detecting too small regions. + +--- + ChangeLog | 5 +++++ + grub-core/kern/mm.c | 5 +++-- + 2 files changed, 8 insertions(+), 2 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index b2e3ccc..2a4264c 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,10 @@ + 2013-04-20 Vladimir Serbinenko + ++ * grub-core/kern/mm.c (grub_mm_init_region): Fix condition for ++ detecting too small regions. ++ ++2013-04-20 Vladimir Serbinenko ++ + * grub-core/Makefile.core.def (legacycfg): Enable on EFI. + + 2013-04-20 Vladimir Serbinenko +diff --git a/grub-core/kern/mm.c b/grub-core/kern/mm.c +index d869091..959c3ba 100644 +--- a/grub-core/kern/mm.c ++++ b/grub-core/kern/mm.c +@@ -140,12 +140,13 @@ grub_mm_init_region (void *addr, grub_size_t size) + + /* Allocate a region from the head. */ + 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) ++ if (size < GRUB_MM_ALIGN + (char *) r - (char *) addr + sizeof (*r)) + return; + ++ size -= (char *) r - (char *) addr + sizeof (*r); ++ + h = (grub_mm_header_t) (r + 1); + h->next = h; + h->magic = GRUB_MM_FREE_MAGIC; +-- +1.8.1.4 + diff --git a/0332-Support-coreboot-framebuffer.patch b/0332-Support-coreboot-framebuffer.patch new file mode 100644 index 0000000..f771926 --- /dev/null +++ b/0332-Support-coreboot-framebuffer.patch @@ -0,0 +1,321 @@ +From 839b333ad80db4f39a97b7aedc927147794e576b Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sun, 21 Apr 2013 13:02:10 +0200 +Subject: [PATCH 332/364] Support coreboot framebuffer. + + * grub-core/video/i386/coreboot/cbfb.c: New file. +--- + ChangeLog | 6 ++ + grub-core/Makefile.core.def | 6 ++ + grub-core/commands/i386/coreboot/cbls.c | 16 ++- + grub-core/video/i386/coreboot/cbfb.c | 180 ++++++++++++++++++++++++++++++++ + include/grub/i386/coreboot/lbio.h | 36 +++++-- + 5 files changed, 236 insertions(+), 8 deletions(-) + create mode 100644 grub-core/video/i386/coreboot/cbfb.c + +diff --git a/ChangeLog b/ChangeLog +index 2a4264c..6be583e 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,9 @@ ++2013-04-21 Vladimir Serbinenko ++ ++ Support coreboot framebuffer. ++ ++ * grub-core/video/i386/coreboot/cbfb.c: New file. ++ + 2013-04-20 Vladimir Serbinenko + + * grub-core/kern/mm.c (grub_mm_init_region): Fix condition for +diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def +index 1f04afb..7269609 100644 +--- a/grub-core/Makefile.core.def ++++ b/grub-core/Makefile.core.def +@@ -1797,6 +1797,12 @@ module = { + }; + + module = { ++ name = coreboot_fb; ++ common = video/i386/coreboot/cbfb.c; ++ enable = i386_coreboot; ++}; ++ ++module = { + name = sdl; + emu = video/emu/sdl.c; + enable = emu; +diff --git a/grub-core/commands/i386/coreboot/cbls.c b/grub-core/commands/i386/coreboot/cbls.c +index 151f9e8..a3542f3 100644 +--- a/grub-core/commands/i386/coreboot/cbls.c ++++ b/grub-core/commands/i386/coreboot/cbls.c +@@ -50,7 +50,7 @@ static const char *descs[] = { + [0xd] = "assembler", + [0xf] = "serial", + [GRUB_LINUXBIOS_MEMBER_CONSOLE] = "console", +- [0x12] = "framebuffer", ++ [GRUB_LINUXBIOS_MEMBER_FRAMEBUFFER] = "framebuffer", + [0x13] = "GPIO", + [0x15] = "VDAT", + [GRUB_LINUXBIOS_MEMBER_TIMESTAMPS] = "timestamps (`coreboot_boottime' to list)", +@@ -77,6 +77,20 @@ iterate_linuxbios_table (grub_linuxbios_table_item_t table_item, + + switch (table_item->tag) + { ++ case GRUB_LINUXBIOS_MEMBER_FRAMEBUFFER: ++ { ++ struct grub_linuxbios_table_framebuffer *fb; ++ fb = (struct grub_linuxbios_table_framebuffer *) (table_item + 1); ++ ++ grub_printf (": %dx%dx%d pitch=%d lfb=0x%llx %d/%d/%d/%d %d/%d/%d/%d", ++ fb->width, fb->height, ++ fb->bpp, fb->pitch, fb->lfb, ++ fb->red_mask_size, fb->green_mask_size, ++ fb->blue_mask_size, fb->reserved_mask_size, ++ fb->red_field_pos, fb->green_field_pos, ++ fb->blue_field_pos, fb->reserved_field_pos); ++ break; ++ } + case GRUB_LINUXBIOS_MEMBER_MAINBOARD: + { + struct grub_linuxbios_mainboard *mb; +diff --git a/grub-core/video/i386/coreboot/cbfb.c b/grub-core/video/i386/coreboot/cbfb.c +new file mode 100644 +index 0000000..000efdb +--- /dev/null ++++ b/grub-core/video/i386/coreboot/cbfb.c +@@ -0,0 +1,180 @@ ++/* ++ * 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 ++ ++GRUB_MOD_LICENSE ("GPLv3+"); ++ ++static struct grub_linuxbios_table_framebuffer *cbfb; ++ ++static struct ++{ ++ struct grub_video_mode_info mode_info; ++ grub_uint8_t *ptr; ++} framebuffer; ++ ++static grub_err_t ++grub_video_cbfb_init (void) ++{ ++ grub_memset (&framebuffer, 0, sizeof(framebuffer)); ++ ++ return grub_video_fb_init (); ++} ++ ++static grub_err_t ++grub_video_cbfb_fill_mode_info (struct grub_video_mode_info *out) ++{ ++ grub_memset (out, 0, sizeof (*out)); ++ ++ out->width = cbfb->width; ++ out->height = cbfb->height; ++ out->pitch = cbfb->pitch; ++ ++ out->red_field_pos = cbfb->red_field_pos; ++ out->red_mask_size = cbfb->red_mask_size; ++ out->green_field_pos = cbfb->green_field_pos; ++ out->green_mask_size = cbfb->green_mask_size; ++ out->blue_field_pos = cbfb->blue_field_pos; ++ out->blue_mask_size = cbfb->blue_mask_size; ++ out->reserved_field_pos = cbfb->reserved_field_pos; ++ out->reserved_mask_size = cbfb->reserved_mask_size; ++ ++ out->mode_type = GRUB_VIDEO_MODE_TYPE_RGB; ++ out->bpp = cbfb->bpp; ++ out->bytes_per_pixel = (cbfb->bpp + 7) / 8; ++ out->number_of_colors = 256; ++ ++ out->blit_format = grub_video_get_blit_format (out); ++ return GRUB_ERR_NONE; ++} ++ ++static grub_err_t ++grub_video_cbfb_setup (unsigned int width, unsigned int height, ++ unsigned int mode_type __attribute__ ((unused)), ++ unsigned int mode_mask __attribute__ ((unused))) ++{ ++ grub_err_t err; ++ ++ if (!cbfb) ++ return grub_error (GRUB_ERR_IO, "Couldn't find display device."); ++ ++ if (!((width == cbfb->width && height == cbfb->height) ++ || (width == 0 && height == 0))) ++ return grub_error (GRUB_ERR_IO, "can't set mode %dx%d", width, height); ++ ++ err = grub_video_cbfb_fill_mode_info (&framebuffer.mode_info); ++ if (err) ++ { ++ grub_dprintf ("video", "CBFB: couldn't fill mode info\n"); ++ return err; ++ } ++ ++ framebuffer.ptr = (void *) (grub_addr_t) cbfb->lfb; ++ ++ grub_dprintf ("video", "CBFB: 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_setup (mode_type, mode_mask, ++ &framebuffer.mode_info, ++ framebuffer.ptr, NULL, NULL); ++ if (err) ++ return err; ++ ++ grub_video_fb_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS, ++ grub_video_fbstd_colors); ++ ++ return err; ++} ++ ++static grub_err_t ++grub_video_cbfb_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_cbfb_adapter = ++ { ++ .name = "Coreboot video driver", ++ ++ .prio = GRUB_VIDEO_ADAPTER_PRIO_FIRMWARE_DIRTY, ++ ++ .init = grub_video_cbfb_init, ++ .fini = grub_video_fb_fini, ++ .setup = grub_video_cbfb_setup, ++ .get_info = grub_video_fb_get_info, ++ .get_info_and_fini = grub_video_cbfb_get_info_and_fini, ++ .set_palette = grub_video_fb_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_fb_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_fb_set_active_render_target, ++ .get_active_render_target = grub_video_fb_get_active_render_target, ++ ++ .next = 0 ++ }; ++ ++static int ++iterate_linuxbios_table (grub_linuxbios_table_item_t table_item, ++ void *data __attribute__ ((unused))) ++{ ++ if (table_item->tag != GRUB_LINUXBIOS_MEMBER_FRAMEBUFFER) ++ return 0; ++ cbfb = (struct grub_linuxbios_table_framebuffer *) (table_item + 1); ++ return 1; ++} ++ ++GRUB_MOD_INIT(coreboot_fb) ++{ ++ grub_linuxbios_table_iterate (iterate_linuxbios_table, 0); ++ ++ if (cbfb) ++ grub_video_register (&grub_video_cbfb_adapter); ++} ++ ++GRUB_MOD_FINI(coreboot_fb) ++{ ++ if (cbfb) ++ grub_video_unregister (&grub_video_cbfb_adapter); ++} +diff --git a/include/grub/i386/coreboot/lbio.h b/include/grub/i386/coreboot/lbio.h +index b4150f4..9a93046 100644 +--- a/include/grub/i386/coreboot/lbio.h ++++ b/include/grub/i386/coreboot/lbio.h +@@ -54,18 +54,40 @@ struct grub_linuxbios_mainboard + + struct grub_linuxbios_table_item + { +-#define GRUB_LINUXBIOS_MEMBER_UNUSED 0x00 +-#define GRUB_LINUXBIOS_MEMBER_MEMORY 0x01 +-#define GRUB_LINUXBIOS_MEMBER_MAINBOARD 0x03 +-#define GRUB_LINUXBIOS_MEMBER_CONSOLE 0x10 +-#define GRUB_LINUXBIOS_MEMBER_LINK 0x11 +-#define GRUB_LINUXBIOS_MEMBER_TIMESTAMPS 0x16 +-#define GRUB_LINUXBIOS_MEMBER_CBMEMC 0x17 + grub_uint32_t tag; + grub_uint32_t size; + }; + typedef struct grub_linuxbios_table_item *grub_linuxbios_table_item_t; + ++enum ++ { ++ GRUB_LINUXBIOS_MEMBER_UNUSED = 0x00, ++ GRUB_LINUXBIOS_MEMBER_MEMORY = 0x01, ++ GRUB_LINUXBIOS_MEMBER_MAINBOARD = 0x03, ++ GRUB_LINUXBIOS_MEMBER_CONSOLE = 0x10, ++ GRUB_LINUXBIOS_MEMBER_LINK = 0x11, ++ GRUB_LINUXBIOS_MEMBER_FRAMEBUFFER = 0x12, ++ GRUB_LINUXBIOS_MEMBER_TIMESTAMPS = 0x16, ++ GRUB_LINUXBIOS_MEMBER_CBMEMC = 0x17 ++ }; ++ ++struct grub_linuxbios_table_framebuffer { ++ grub_uint64_t lfb; ++ grub_uint32_t width; ++ grub_uint32_t height; ++ grub_uint32_t pitch; ++ grub_uint8_t bpp; ++ ++ grub_uint8_t red_field_pos; ++ grub_uint8_t red_mask_size; ++ grub_uint8_t green_field_pos; ++ grub_uint8_t green_mask_size; ++ grub_uint8_t blue_field_pos; ++ grub_uint8_t blue_mask_size; ++ grub_uint8_t reserved_field_pos; ++ grub_uint8_t reserved_mask_size; ++}; ++ + struct grub_linuxbios_mem_region + { + grub_uint64_t addr; +-- +1.8.1.4 + diff --git a/0333-grub-core-disk-arc-arcdisk.c-grub_arcdisk_iterate_it.patch b/0333-grub-core-disk-arc-arcdisk.c-grub_arcdisk_iterate_it.patch new file mode 100644 index 0000000..0c71dc2 --- /dev/null +++ b/0333-grub-core-disk-arc-arcdisk.c-grub_arcdisk_iterate_it.patch @@ -0,0 +1,43 @@ +From b8ba23b222923c7f1d03c5b3b061938860ca7441 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Sun, 21 Apr 2013 13:06:22 +0200 +Subject: [PATCH 333/364] * grub-core/disk/arc/arcdisk.c + (grub_arcdisk_iterate_iter): Fix a type which prevented CD-ROM and floppy + boot. + +--- + ChangeLog | 5 +++++ + grub-core/disk/arc/arcdisk.c | 2 +- + 2 files changed, 6 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index 6be583e..2150d3d 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,10 @@ + 2013-04-21 Vladimir Serbinenko + ++ * grub-core/disk/arc/arcdisk.c (grub_arcdisk_iterate_iter): ++ Fix a type which prevented CD-ROM and floppy boot. ++ ++2013-04-21 Vladimir Serbinenko ++ + Support coreboot framebuffer. + + * grub-core/video/i386/coreboot/cbfb.c: New file. +diff --git a/grub-core/disk/arc/arcdisk.c b/grub-core/disk/arc/arcdisk.c +index 5d12128..780728f 100644 +--- a/grub-core/disk/arc/arcdisk.c ++++ b/grub-core/disk/arc/arcdisk.c +@@ -95,7 +95,7 @@ grub_arcdisk_iterate_iter (const char *name, + struct grub_arcdisk_iterate_ctx *ctx = data; + + if (!(comp->type == GRUB_ARC_COMPONENT_TYPE_DISK +- || comp->type == GRUB_ARC_COMPONENT_TYPE_DISK ++ || comp->type == GRUB_ARC_COMPONENT_TYPE_FLOPPY + || comp->type == GRUB_ARC_COMPONENT_TYPE_TAPE)) + return 0; + return ctx->hook (name, ctx->hook_data); +-- +1.8.1.4 + diff --git a/0334-Move-mips-arc-link-address.-Previous-link-address-wa.patch b/0334-Move-mips-arc-link-address.-Previous-link-address-wa.patch new file mode 100644 index 0000000..fb2b36d --- /dev/null +++ b/0334-Move-mips-arc-link-address.-Previous-link-address-wa.patch @@ -0,0 +1,178 @@ +From 9fb5d59797c2de5670f1c2044a1323fc410eb125 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Wed, 24 Apr 2013 13:54:17 +0200 +Subject: [PATCH 334/364] Move mips-arc link address. Previous link + address was chosen in belief that RAM on SGI platforms grows down while + in fact it grows up from an unusual base. + +--- + ChangeLog | 6 ++++++ + grub-core/Makefile.core.def | 6 +++--- + grub-core/kern/mips/arc/init.c | 14 +++++++++----- + grub-core/kern/mips/startup.S | 2 -- + include/grub/mips/arc/memory.h | 2 +- + include/grub/offsets.h | 2 +- + util/grub-mkimage.c | 11 ++++------- + 7 files changed, 24 insertions(+), 19 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 2150d3d..39bb827 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,9 @@ ++2013-04-24 Vladimir Serbinenko ++ ++ Move mips-arc link address. Previous link address was chosen ++ in belief that RAM on SGI platforms grows down while in fact it ++ grows up from an unusual base. ++ + 2013-04-21 Vladimir Serbinenko + + * grub-core/disk/arc/arcdisk.c (grub_arcdisk_iterate_iter): +diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def +index 7269609..8f36ea0 100644 +--- a/grub-core/Makefile.core.def ++++ b/grub-core/Makefile.core.def +@@ -73,7 +73,7 @@ kernel = { + mips_loongson_ldflags = '-Wl,-Ttext,0x80200000'; + powerpc_ieee1275_ldflags = '-Wl,-Ttext,0x200000'; + sparc64_ieee1275_ldflags = '-Wl,-Ttext,0x4400'; +- mips_arc_ldflags = '-Wl,-Ttext,0x8bd00000'; ++ mips_arc_ldflags = '-Wl,-Ttext,0x88200000'; + mips_qemu_mips_ldflags = '-Wl,-Ttext,0x80200000'; + + mips_loongson_cppflags = '-DUSE_ASCII_FAILBACK'; +@@ -372,7 +372,7 @@ image = { + objcopyflags = '-O binary'; + mips_loongson_ldflags = '-static-libgcc -Wl,-Ttext,0x80100000'; + mips_qemu_mips_ldflags = '-static-libgcc -Wl,-Ttext,0x80100000'; +- mips_arc_ldflags = '-static-libgcc -Wl,-Ttext,0x8bc00000'; ++ mips_arc_ldflags = '-static-libgcc -Wl,-Ttext,0x88100000'; + ldadd = '-lgcc'; + cflags = '-Wno-unreachable-code -static-libgcc'; + enable = mips; +@@ -388,7 +388,7 @@ image = { + objcopyflags = '-O binary'; + mips_loongson_ldflags = '-static-libgcc -Wl,-Ttext,0x80100000'; + mips_qemu_mips_ldflags = '-static-libgcc -Wl,-Ttext,0x80100000'; +- mips_arc_ldflags = '-static-libgcc -Wl,-Ttext,0x8bc00000'; ++ mips_arc_ldflags = '-static-libgcc -Wl,-Ttext,0x88100000'; + ldadd = '-lgcc'; + cflags = '-static-libgcc'; + enable = mips; +diff --git a/grub-core/kern/mips/arc/init.c b/grub-core/kern/mips/arc/init.c +index f63ac6d..011c63f 100644 +--- a/grub-core/kern/mips/arc/init.c ++++ b/grub-core/kern/mips/arc/init.c +@@ -128,12 +128,16 @@ grub_machine_mmap_iterate (grub_memory_hook_t hook, void *hook_data) + extern grub_uint32_t grub_total_modules_size __attribute__ ((section(".text"))); + grub_addr_t grub_modbase; + ++extern char _end[]; ++ + void + grub_machine_init (void) + { + struct grub_arc_memory_descriptor *cur = NULL; ++ grub_addr_t modend; + +- grub_modbase = GRUB_KERNEL_MIPS_ARC_LINK_ADDR - grub_total_modules_size; ++ grub_modbase = ALIGN_UP ((grub_addr_t) _end, GRUB_KERNEL_MACHINE_MOD_ALIGN); ++ modend = grub_modbase + grub_total_modules_size; + grub_console_init_early (); + + /* FIXME: measure this. */ +@@ -153,10 +157,10 @@ grub_machine_init (void) + start = ((grub_uint64_t) cur->start_page) << 12; + end = ((grub_uint64_t) cur->num_pages) << 12; + end += start; +- if ((grub_uint64_t) end > ((GRUB_KERNEL_MIPS_ARC_LINK_ADDR +- - grub_total_modules_size) & 0x1fffffff)) +- end = ((GRUB_KERNEL_MIPS_ARC_LINK_ADDR - grub_total_modules_size) +- & 0x1fffffff); ++ if ((grub_uint64_t) start < (modend & 0x1fffffff)) ++ start = (modend & 0x1fffffff); ++ if ((grub_uint64_t) end > 0x20000000) ++ end = 0x20000000; + if (end > start) + grub_mm_init_region ((void *) (grub_addr_t) (start | 0x80000000), + end - start); +diff --git a/grub-core/kern/mips/startup.S b/grub-core/kern/mips/startup.S +index 2476038..35a11bc 100644 +--- a/grub-core/kern/mips/startup.S ++++ b/grub-core/kern/mips/startup.S +@@ -73,7 +73,6 @@ cont: + #endif + + /* Move the modules out of BSS. */ +-#ifndef GRUB_MACHINE_ARC + lui $t2, %hi(__bss_start) + addiu $t2, %lo(__bss_start) + +@@ -103,7 +102,6 @@ modulesmovcont: + b modulesmovcont + addiu $t3, $t3, -1 + modulesmovdone: +-#endif + + /* Clean BSS. */ + +diff --git a/include/grub/mips/arc/memory.h b/include/grub/mips/arc/memory.h +index b960d2a..68b425f 100644 +--- a/include/grub/mips/arc/memory.h ++++ b/include/grub/mips/arc/memory.h +@@ -19,7 +19,7 @@ + #ifndef GRUB_MEMORY_MACHINE_HEADER + #define GRUB_MEMORY_MACHINE_HEADER 1 + +-#define GRUB_MACHINE_MEMORY_STACK_HIGH 0x8bfffff0 ++#define GRUB_MACHINE_MEMORY_STACK_HIGH 0x881ffff0 + + #ifndef ASM_FILE + +diff --git a/include/grub/offsets.h b/include/grub/offsets.h +index bce755d..1e673d5 100644 +--- a/include/grub/offsets.h ++++ b/include/grub/offsets.h +@@ -80,7 +80,7 @@ + #define GRUB_DECOMPRESSOR_MIPS_QEMU_MIPS_UNCOMPRESSED_ADDR 0x10 + #define GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZE 0x08 + +-#define GRUB_KERNEL_MIPS_ARC_LINK_ADDR 0x8bd00000 ++#define GRUB_KERNEL_MIPS_ARC_LINK_ADDR 0x88200000 + + #define GRUB_KERNEL_MIPS_ARC_LINK_ALIGN 32 + +diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c +index 0acc61e..41f795a 100644 +--- a/util/grub-mkimage.c ++++ b/util/grub-mkimage.c +@@ -387,8 +387,7 @@ struct image_target_desc image_targets[] = + .voidp_sizeof = 4, + .bigendian = 1, + .id = IMAGE_MIPS_ARC, +- .flags = (PLATFORM_FLAGS_DECOMPRESSORS +- | PLATFORM_FLAGS_MODULES_BEFORE_KERNEL), ++ .flags = PLATFORM_FLAGS_DECOMPRESSORS, + .total_module_size = GRUB_KERNEL_MIPS_ARC_TOTAL_MODULE_SIZE, + .decompressor_compressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE, + .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE, +@@ -1522,12 +1521,10 @@ generate_image (const char *dir, const char *prefix, + + program_size = ALIGN_ADDR (core_size); + if (comp == COMPRESSION_NONE) +- target_addr = (image_target->link_addr +- - total_module_size - decompress_size); ++ target_addr = (image_target->link_addr - decompress_size); + else +- target_addr = (image_target->link_addr +- - ALIGN_UP(total_module_size + core_size, 1048576) +- - (1 << 20)); ++ target_addr = ALIGN_UP (image_target->link_addr ++ + kernel_size + total_module_size, 32); + + ecoff_img = xmalloc (program_size + sizeof (*head) + sizeof (*section)); + grub_memset (ecoff_img, 0, program_size + sizeof (*head) + sizeof (*section)); +-- +1.8.1.4 + diff --git a/0335-grub-core-kern-dl.c-grub_dl_resolve_symbols-Handle-m.patch b/0335-grub-core-kern-dl.c-grub_dl_resolve_symbols-Handle-m.patch new file mode 100644 index 0000000..b246f92 --- /dev/null +++ b/0335-grub-core-kern-dl.c-grub_dl_resolve_symbols-Handle-m.patch @@ -0,0 +1,41 @@ +From 92dc25b822630bc379e52c48c03afddd35ec895d Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Wed, 24 Apr 2013 13:58:31 +0200 +Subject: [PATCH 335/364] * grub-core/kern/dl.c + (grub_dl_resolve_symbols): Handle malloc failure. + +--- + ChangeLog | 4 ++++ + grub-core/kern/dl.c | 2 ++ + 2 files changed, 6 insertions(+) + +diff --git a/ChangeLog b/ChangeLog +index 39bb827..598d16c 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,9 @@ + 2013-04-24 Vladimir Serbinenko + ++ * grub-core/kern/dl.c (grub_dl_resolve_symbols): Handle malloc failure. ++ ++2013-04-24 Vladimir Serbinenko ++ + Move mips-arc link address. Previous link address was chosen + in belief that RAM on SGI platforms grows down while in fact it + grows up from an unusual base. +diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c +index d06b6ae..c6d9ec9 100644 +--- a/grub-core/kern/dl.c ++++ b/grub-core/kern/dl.c +@@ -359,6 +359,8 @@ grub_dl_resolve_symbols (grub_dl_t mod, Elf_Ehdr *e) + + #ifdef GRUB_MODULES_MACHINE_READONLY + mod->symtab = grub_malloc (s->sh_size); ++ if (!mod->symtab) ++ return grub_errno; + memcpy (mod->symtab, (char *) e + s->sh_offset, s->sh_size); + #else + mod->symtab = (Elf_Sym *) ((char *) e + s->sh_offset); +-- +1.8.1.4 + diff --git a/0336-util-grub-mkrescue.in-Add-mips-arc-support.patch b/0336-util-grub-mkrescue.in-Add-mips-arc-support.patch new file mode 100644 index 0000000..c2c69aa --- /dev/null +++ b/0336-util-grub-mkrescue.in-Add-mips-arc-support.patch @@ -0,0 +1,134 @@ +From 5aa38752440cb6871b83eb1d36947c514acfc559 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Wed, 24 Apr 2013 14:02:58 +0200 +Subject: [PATCH 336/364] * util/grub-mkrescue.in: Add mips-arc support. + +--- + ChangeLog | 4 ++++ + Makefile.util.def | 13 +------------ + util/grub-mkrescue.in | 22 +++++++++++++++++++++- + 3 files changed, 26 insertions(+), 13 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 598d16c..c2d56f1 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,9 @@ + 2013-04-24 Vladimir Serbinenko + ++ * util/grub-mkrescue.in: Add mips-arc support. ++ ++2013-04-24 Vladimir Serbinenko ++ + * grub-core/kern/dl.c (grub_dl_resolve_symbols): Handle malloc failure. + + 2013-04-24 Vladimir Serbinenko +diff --git a/Makefile.util.def b/Makefile.util.def +index ed7b412..4fa37bc 100644 +--- a/Makefile.util.def ++++ b/Makefile.util.def +@@ -464,18 +464,7 @@ script = { + name = grub-mkrescue; + common = util/grub-install_header; + common = util/grub-mkrescue.in; +- enable = i386_pc; +- enable = i386_efi; +- enable = x86_64_efi; +- enable = i386_qemu; +- enable = i386_multiboot; +- enable = i386_coreboot; +- enable = i386_ieee1275; +- enable = mips_qemu_mips; +- enable = mips_loongson; +- enable = ia64_efi; +- enable = powerpc_ieee1275; +- enable = sparc64_ieee1275; ++ enable = noemu; + }; + + script = { +diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in +index 5a5d4e3..634318b 100644 +--- a/util/grub-mkrescue.in ++++ b/util/grub-mkrescue.in +@@ -45,6 +45,7 @@ efi32_dir="${libdir}/@PACKAGE@/i386-efi" + efi64_dir="${libdir}/@PACKAGE@/x86_64-efi" + ia64_dir="${libdir}/@PACKAGE@/ia64-efi" + sparc64_dir="${libdir}/@PACKAGE@/sparc64-ieee1275" ++arcs_dir="${libdir}/@PACKAGE@/mips-arc" + ppc_dir="${libdir}/@PACKAGE@/powerpc-ieee1275" + rom_directory= + override_dir= +@@ -91,7 +92,8 @@ usage () { + print_option_help "--label-bgcolor=$(gettext "COLOR")" "$(gettext "use COLOR for label background")" + print_option_help "--product-name=$(gettext "STR")" "$(gettext "use STR as product")" + print_option_help "--product-version=$(gettext "STR")" "$(gettext "use STR as product version")" +- print_option_help "--sparc-boot" "$(gettext "enable sparc boot. Disables HFS+, APM and boot as disk image for i386-pc")" ++ print_option_help "--sparc-boot" "$(gettext "enable sparc boot. Disables HFS+, APM, ARCS and boot as disk image for i386-pc")" ++ print_option_help "--arcs-boot" "$(gettext "enable ARCS (big-endian mips machines, mostly SGI) boot. Disables HFS+, APM, sparc64 and boot as disk image for i386-pc")" + echo + gettext_printf "%s generates a bootable rescue image with specified source files, source directories, or mkisofs options listed by the output of \`%s'\n" "xorriso -as mkisofs -help" "$self" | grub_fmt + echo +@@ -154,6 +156,9 @@ do + --sparc-boot) + system_area=sparc64 ;; + ++ --arcs-boot) ++ system_area=arcs ;; ++ + --product-name) + product_name=`argument $option "$@"`; shift ;; + --product-name=*) +@@ -273,6 +278,8 @@ if [ "${override_dir}" = "" ] ; then + system_area=common; + elif test -e "${sparc64_dir}" ; then + system_area=sparc64; ++ elif test -e "${arcs_dir}" ; then ++ system_area=arcs; + fi + fi + if test -e "${multiboot_dir}" ; then +@@ -314,6 +321,9 @@ if [ "${override_dir}" = "" ] ; then + if test -e "${sparc64_dir}" ; then + process_input_dir "${sparc64_dir}" sparc64-ieee1275 + fi ++ if test -e "${arcs_dir}" ; then ++ process_input_dir "${arcs_dir}" mips-arc ++ fi + else + . "${override_dir}"/modinfo.sh + process_input_dir "${override_dir}" ${grub_modinfo_target_cpu}-${grub_modinfo_platform} +@@ -330,6 +340,7 @@ else + ppc_dir= + i386_ieee1275_dir= + sparc64_dir= ++ arcs_dir= + case "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" in + i386-multiboot) multiboot_dir="${override_dir}" ;; + i386-coreboot) coreboot_dir="${override_dir}" ;; +@@ -343,6 +354,7 @@ else + mips-qemu_mips) mips_qemu_dir="${override_dir}" ;; + powerpc-ieee1275) ppc_dir="${override_dir}"; system_area=common ;; + sparc64-ieee1275) sparc64_dir="${override_dir}"; system_area=sparc64 ;; ++ mips-arc) arcs_dir="${override_dir}"; system_area=arcs ;; + i386-ieee1275) i386_ieee1275_dir="${override_dir}" ;; + esac + fi +@@ -470,6 +482,14 @@ if [ -e "${iso9660_dir}"/boot/grub/sparc64-ieee1275/core.img ] && [ "$system_are + grub_mkisofs_arguments="${grub_mkisofs_arguments} -G $sysarea_img -B , --grub2-sparc-core /boot/grub/sparc64-ieee1275/core.img" + fi + ++make_image "${arcs_dir}" mips-arc "${iso9660_dir}/boot/grub/mips-arc/core.img" "" ++if [ -e "${iso9660_dir}/boot/grub/mips-arc/core.img" ]; then ++ grub_mkisofs_arguments="${grub_mkisofs_arguments} /boot/grub/mips-arc/grub=${iso9660_dir}/boot/grub/mips-arc/core.img /boot/grub/mips-arc/sashARCS=${iso9660_dir}/boot/grub/mips-arc/core.img" ++fi ++if [ -e "${iso9660_dir}/boot/grub/mips-arc/core.img" ] && [ "$system_area" = arcs ]; then ++ grub_mkisofs_arguments="${grub_mkisofs_arguments} -mips-boot /boot/grub/mips-arc/sashARCS -mips-boot /boot/grub/mips-arc/grub" ++fi ++ + make_image "${mipsel_qemu_dir}" mipsel-qemu_mips-elf "${iso9660_dir}/boot/mipsel-qemu_mips.elf" "pata" + if [ -e "${iso9660_dir}/boot/mipsel-qemu_mips.elf" ] && [ -d "${rom_directory}" ]; then + cp "${iso9660_dir}/boot/mipsel-qemu_mips.elf" "${rom_directory}/mipsel-qemu_mips.elf" +-- +1.8.1.4 + diff --git a/0337-Add-missing-video-ids-to-coreboot-and-ieee1275-video.patch b/0337-Add-missing-video-ids-to-coreboot-and-ieee1275-video.patch new file mode 100644 index 0000000..845793d --- /dev/null +++ b/0337-Add-missing-video-ids-to-coreboot-and-ieee1275-video.patch @@ -0,0 +1,81 @@ +From d1523e26a44daeca832ccd51d6a2126c026d54d3 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Wed, 24 Apr 2013 14:44:15 +0200 +Subject: [PATCH 337/364] Add missing video ids to coreboot and ieee1275 + video. + +--- + ChangeLog | 4 ++++ + grub-core/loader/i386/linux.c | 2 ++ + grub-core/video/i386/coreboot/cbfb.c | 1 + + grub-core/video/ieee1275.c | 1 + + include/grub/video.h | 2 ++ + 5 files changed, 10 insertions(+) + +diff --git a/ChangeLog b/ChangeLog +index c2d56f1..d863bb3 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,9 @@ + 2013-04-24 Vladimir Serbinenko + ++ Add missing video ids to coreboot and ieee1275 video. ++ ++2013-04-24 Vladimir Serbinenko ++ + * util/grub-mkrescue.in: Add mips-arc support. + + 2013-04-24 Vladimir Serbinenko +diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c +index 5cd074b..db81ca1 100644 +--- a/grub-core/loader/i386/linux.c ++++ b/grub-core/loader/i386/linux.c +@@ -338,6 +338,8 @@ grub_linux_setup_video (struct linux_kernel_params *params) + case GRUB_VIDEO_DRIVER_CIRRUS: + case GRUB_VIDEO_DRIVER_BOCHS: + case GRUB_VIDEO_DRIVER_RADEON_FULOONG2E: ++ case GRUB_VIDEO_DRIVER_IEEE1275: ++ case GRUB_VIDEO_DRIVER_COREBOOT: + /* Make gcc happy. */ + case GRUB_VIDEO_DRIVER_SDL: + case GRUB_VIDEO_DRIVER_NONE: +diff --git a/grub-core/video/i386/coreboot/cbfb.c b/grub-core/video/i386/coreboot/cbfb.c +index 000efdb..984b594 100644 +--- a/grub-core/video/i386/coreboot/cbfb.c ++++ b/grub-core/video/i386/coreboot/cbfb.c +@@ -128,6 +128,7 @@ static struct grub_video_adapter grub_video_cbfb_adapter = + .name = "Coreboot video driver", + + .prio = GRUB_VIDEO_ADAPTER_PRIO_FIRMWARE_DIRTY, ++ .id = GRUB_VIDEO_DRIVER_COREBOOT, + + .init = grub_video_cbfb_init, + .fini = grub_video_fb_fini, +diff --git a/grub-core/video/ieee1275.c b/grub-core/video/ieee1275.c +index 93feeb5..5830b68 100644 +--- a/grub-core/video/ieee1275.c ++++ b/grub-core/video/ieee1275.c +@@ -241,6 +241,7 @@ static struct grub_video_adapter grub_video_ieee1275_adapter = + .name = "IEEE1275 video driver", + + .prio = GRUB_VIDEO_ADAPTER_PRIO_FIRMWARE, ++ .id = GRUB_VIDEO_DRIVER_IEEE1275, + + .init = grub_video_ieee1275_init, + .fini = grub_video_ieee1275_fini, +diff --git a/include/grub/video.h b/include/grub/video.h +index 40a7711..bd5852e 100644 +--- a/include/grub/video.h ++++ b/include/grub/video.h +@@ -283,6 +283,8 @@ typedef enum grub_video_driver_id + GRUB_VIDEO_DRIVER_SDL, + GRUB_VIDEO_DRIVER_SIS315PRO, + GRUB_VIDEO_DRIVER_RADEON_FULOONG2E, ++ GRUB_VIDEO_DRIVER_COREBOOT, ++ GRUB_VIDEO_DRIVER_IEEE1275 + } grub_video_driver_id_t; + + typedef enum grub_video_adapter_prio +-- +1.8.1.4 + diff --git a/0338-grub-core-disk-ata.c-grub_ata_real_open-Use-grub_err.patch b/0338-grub-core-disk-ata.c-grub_ata_real_open-Use-grub_err.patch new file mode 100644 index 0000000..4b6d2fe --- /dev/null +++ b/0338-grub-core-disk-ata.c-grub_ata_real_open-Use-grub_err.patch @@ -0,0 +1,41 @@ +From 2e6bc59b479c674f58216d153a6bdd92bcb5d1c7 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Wed, 24 Apr 2013 14:47:14 +0200 +Subject: [PATCH 338/364] * grub-core/disk/ata.c (grub_ata_real_open): + Use grub_error properly. + +--- + ChangeLog | 4 ++++ + grub-core/disk/ata.c | 2 ++ + 2 files changed, 6 insertions(+) + +diff --git a/ChangeLog b/ChangeLog +index d863bb3..6d9ffdc 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,9 @@ + 2013-04-24 Vladimir Serbinenko + ++ * grub-core/disk/ata.c (grub_ata_real_open): Use grub_error properly. ++ ++2013-04-24 Vladimir Serbinenko ++ + Add missing video ids to coreboot and ieee1275 video. + + 2013-04-24 Vladimir Serbinenko +diff --git a/grub-core/disk/ata.c b/grub-core/disk/ata.c +index c84d316..dada56d 100644 +--- a/grub-core/disk/ata.c ++++ b/grub-core/disk/ata.c +@@ -382,6 +382,8 @@ grub_ata_real_open (int id, int bus) + err = grub_ata_identify (ata); + if (err) + { ++ if (!grub_errno) ++ grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no such ATA device"); + grub_free (ata); + return NULL; + } +-- +1.8.1.4 + diff --git a/0339-grub-core-loader-i386-linux.c-grub_linux_boot-Defaul.patch b/0339-grub-core-loader-i386-linux.c-grub_linux_boot-Defaul.patch new file mode 100644 index 0000000..b6d33ec --- /dev/null +++ b/0339-grub-core-loader-i386-linux.c-grub_linux_boot-Defaul.patch @@ -0,0 +1,59 @@ +From bee9741e358d7d48c117150ece8cc1879130c39c Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Wed, 24 Apr 2013 14:53:00 +0200 +Subject: [PATCH 339/364] * grub-core/loader/i386/linux.c + (grub_linux_boot): Default to gfxpayload=keep if cbfb is active. + +--- + ChangeLog | 5 +++++ + grub-core/loader/i386/linux.c | 15 ++++++++++----- + 2 files changed, 15 insertions(+), 5 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 6d9ffdc..5854326 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,10 @@ + 2013-04-24 Vladimir Serbinenko + ++ * grub-core/loader/i386/linux.c (grub_linux_boot): Default to ++ gfxpayload=keep if cbfb is active. ++ ++2013-04-24 Vladimir Serbinenko ++ + * grub-core/disk/ata.c (grub_ata_real_open): Use grub_error properly. + + 2013-04-24 Vladimir Serbinenko +diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c +index db81ca1..106496b 100644 +--- a/grub-core/loader/i386/linux.c ++++ b/grub-core/loader/i386/linux.c +@@ -503,15 +503,20 @@ grub_linux_boot (void) + #endif + grub_free (tmp); + } +- else +- { ++ else /* We can't go back to text mode from coreboot fb. */ ++#ifdef GRUB_MACHINE_COREBOOT ++ if (grub_video_get_driver_id () == GRUB_VIDEO_DRIVER_COREBOOT) ++ err = GRUB_ERR_NONE; ++ else ++#endif ++ { + #if ACCEPTS_PURE_TEXT +- err = grub_video_set_mode (DEFAULT_VIDEO_MODE, 0, 0); ++ err = grub_video_set_mode (DEFAULT_VIDEO_MODE, 0, 0); + #else +- err = grub_video_set_mode (DEFAULT_VIDEO_MODE, ++ err = grub_video_set_mode (DEFAULT_VIDEO_MODE, + GRUB_VIDEO_MODE_TYPE_PURE_TEXT, 0); + #endif +- } ++ } + + if (err) + { +-- +1.8.1.4 + diff --git a/0340-grub-core-normal-menu_text.c-print_entry-Put-an-aste.patch b/0340-grub-core-normal-menu_text.c-print_entry-Put-an-aste.patch new file mode 100644 index 0000000..a27aab8 --- /dev/null +++ b/0340-grub-core-normal-menu_text.c-print_entry-Put-an-aste.patch @@ -0,0 +1,52 @@ +From a6d176e62f7b6c03e680287972b95dae59bef125 Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Wed, 24 Apr 2013 15:07:24 +0200 +Subject: [PATCH 340/364] * grub-core/normal/menu_text.c (print_entry): + Put an asterisk in front of chosen entry to mark it even if + highlighting is lost. + +--- + ChangeLog | 5 +++++ + grub-core/normal/menu_text.c | 4 +++- + 2 files changed, 8 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index 5854326..7e29788 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,10 @@ + 2013-04-24 Vladimir Serbinenko + ++ * grub-core/normal/menu_text.c (print_entry): Put an asterisk ++ in front of chosen entry to mark it even if highlighting is lost. ++ ++2013-04-24 Vladimir Serbinenko ++ + * grub-core/loader/i386/linux.c (grub_linux_boot): Default to + gfxpayload=keep if cbfb is active. + +diff --git a/grub-core/normal/menu_text.c b/grub-core/normal/menu_text.c +index 0031b0c..e1d3c8f 100644 +--- a/grub-core/normal/menu_text.c ++++ b/grub-core/normal/menu_text.c +@@ -242,7 +242,7 @@ print_entry (int y, int highlight, grub_menu_entry_t entry, + || unicode_title[i] == '\r' || unicode_title[i] == '\e') + unicode_title[i] = ' '; + +- for (x = GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN + 1, i = 0; ++ for (x = GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN + 2, i = 0; + x < (int) (GRUB_TERM_LEFT_BORDER_X + grub_term_border_width (term) + - GRUB_TERM_MARGIN);) + { +@@ -269,6 +269,8 @@ print_entry (int y, int highlight, grub_menu_entry_t entry, + break; + } + ++ grub_putcode (highlight ? '*' : ' ', term); ++ + grub_print_ucs4 (unicode_title, + unicode_title + last_printed, 0, 0, term); + +-- +1.8.1.4 + diff --git a/0341-util-grub-install.in-Fix-target-fo-qemu_mips.patch b/0341-util-grub-install.in-Fix-target-fo-qemu_mips.patch new file mode 100644 index 0000000..4b38e13 --- /dev/null +++ b/0341-util-grub-install.in-Fix-target-fo-qemu_mips.patch @@ -0,0 +1,50 @@ +From 8330cd6cfd3c6d2e63644849817379a7da9fc42f Mon Sep 17 00:00:00 2001 +From: Vladimir 'phcoder' Serbinenko +Date: Wed, 24 Apr 2013 15:10:29 +0200 +Subject: [PATCH 341/364] * util/grub-install.in: Fix target fo + qemu_mips. Fix extension on EFI. + +--- + ChangeLog | 5 +++++ + util/grub-install.in | 5 +++-- + 2 files changed, 8 insertions(+), 2 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 7e29788..2f55104 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,10 @@ + 2013-04-24 Vladimir Serbinenko + ++ * util/grub-install.in: Fix target fo qemu_mips. ++ Fix extension on EFI. ++ ++2013-04-24 Vladimir Serbinenko ++ + * grub-core/normal/menu_text.c (print_entry): Put an asterisk + in front of chosen entry to mark it even if highlighting is lost. + +diff --git a/util/grub-install.in b/util/grub-install.in +index 32a3be3..271e447 100644 +--- a/util/grub-install.in ++++ b/util/grub-install.in +@@ -673,13 +673,14 @@ fi + case "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" in + sparc64-ieee1275) mkimage_target=sparc64-ieee1275-raw ;; + mipsel-loongson) mkimage_target=mipsel-loongson-elf ;; ++ mips-qemu_mips | mipsel-qemu_mips) mkimage_target="${grub_modinfo_target_cpu}-${grub_modinfo_platform}"-elf ;; + *) mkimage_target="${grub_modinfo_target_cpu}-${grub_modinfo_platform}" ;; + esac + + case "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" in +- i386-efi | x86_64-efi) imgext=efi ;; ++ i386-efi | x86_64-efi | ia64-efi) imgext=efi ;; + mipsel-loongson | i386-coreboot | i386-multiboot | i386-ieee1275 \ +- | powerpc-ieee1275) imgext=elf ;; ++ | powerpc-ieee1275 | mips-qemu_mips | mipsel-qemu_mips) imgext=elf ;; + *) imgext=img ;; + esac + +-- +1.8.1.4 + diff --git a/0342-Don-t-say-GNU-Linux-in-generated-menus.patch b/0342-Don-t-say-GNU-Linux-in-generated-menus.patch new file mode 100644 index 0000000..afde264 --- /dev/null +++ b/0342-Don-t-say-GNU-Linux-in-generated-menus.patch @@ -0,0 +1,45 @@ +From 75261365c2601a2e98dae5b872de61930546bac7 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Mon, 14 Mar 2011 14:27:42 -0400 +Subject: [PATCH 342/364] Don't say "GNU/Linux" in generated menus. + +--- + util/grub.d/10_linux.in | 4 ++-- + util/grub.d/20_linux_xen.in | 4 ++-- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in +index 0724e16..368f609 100644 +--- a/util/grub.d/10_linux.in ++++ b/util/grub.d/10_linux.in +@@ -29,9 +29,9 @@ export TEXTDOMAINDIR="@localedir@" + CLASS="--class gnu-linux --class gnu --class os" + + if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then +- OS=GNU/Linux ++ OS="$(sed 's, release .*$,,g' /etc/system-release)" + else +- OS="${GRUB_DISTRIBUTOR} GNU/Linux" ++ OS="${GRUB_DISTRIBUTOR}" + CLASS="--class $(echo ${GRUB_DISTRIBUTOR} | tr 'A-Z' 'a-z' | cut -d' ' -f1) ${CLASS}" + fi + +diff --git a/util/grub.d/20_linux_xen.in b/util/grub.d/20_linux_xen.in +index 6651cbc..4372c0c 100644 +--- a/util/grub.d/20_linux_xen.in ++++ b/util/grub.d/20_linux_xen.in +@@ -29,9 +29,9 @@ export TEXTDOMAINDIR="@localedir@" + CLASS="--class gnu-linux --class gnu --class os --class xen" + + if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then +- OS=GNU/Linux ++ OS="$(sed 's, release .*$,,g' /etc/system-release)" + else +- OS="${GRUB_DISTRIBUTOR} GNU/Linux" ++ OS="${GRUB_DISTRIBUTOR}" + CLASS="--class $(echo ${GRUB_DISTRIBUTOR} | tr 'A-Z' 'a-z' | cut -d' ' -f1) ${CLASS}" + fi + +-- +1.8.1.4 + diff --git a/0343-Migrate-PPC-from-Yaboot-to-Grub2.patch b/0343-Migrate-PPC-from-Yaboot-to-Grub2.patch new file mode 100644 index 0000000..f8ba45f --- /dev/null +++ b/0343-Migrate-PPC-from-Yaboot-to-Grub2.patch @@ -0,0 +1,154 @@ +From 5c27f1d4e94b5649aba55d1aa53a4c154949005c Mon Sep 17 00:00:00 2001 +From: Mark Hamzy +Date: Wed, 28 Mar 2012 14:46:41 -0500 +Subject: [PATCH 343/364] Migrate PPC from Yaboot to Grub2 + +Add configuration support for serial terminal consoles. This will set the +maximum screen size so that text is not overwritten. +--- + Makefile.util.def | 7 +++ + util/grub.d/20_ppc_terminfo.in | 114 +++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 121 insertions(+) + create mode 100644 util/grub.d/20_ppc_terminfo.in + +diff --git a/Makefile.util.def b/Makefile.util.def +index 4fa37bc..2f3bf5f 100644 +--- a/Makefile.util.def ++++ b/Makefile.util.def +@@ -442,6 +442,13 @@ script = { + }; + + script = { ++ name = '20_ppc_terminfo'; ++ common = util/grub.d/20_ppc_terminfo.in; ++ installdir = grubconf; ++ condition = COND_HOST_LINUX; ++}; ++ ++script = { + name = '30_os-prober'; + common = util/grub.d/30_os-prober.in; + installdir = grubconf; +diff --git a/util/grub.d/20_ppc_terminfo.in b/util/grub.d/20_ppc_terminfo.in +new file mode 100644 +index 0000000..10d6658 +--- /dev/null ++++ b/util/grub.d/20_ppc_terminfo.in +@@ -0,0 +1,114 @@ ++#! /bin/sh ++set -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@ ++. "@datadir@/@PACKAGE@/grub-mkconfig_lib" ++ ++export TEXTDOMAIN=@PACKAGE@ ++export TEXTDOMAINDIR=@localedir@ ++ ++X=80 ++Y=24 ++TERMINAL=ofconsole ++ ++argument () { ++ opt=$1 ++ shift ++ ++ if test $# -eq 0; then ++ echo "$0: option requires an argument -- '$opt'" 1>&2 ++ exit 1 ++ fi ++ echo $1 ++} ++ ++check_terminfo () { ++ ++ while test $# -gt 0 ++ do ++ option=$1 ++ shift ++ ++ case "$option" in ++ terminfo | TERMINFO) ++ ;; ++ ++ -g) ++ NEWXY=`argument $option "$@"` ++ NEWX=`echo $NEWXY | cut -d x -f 1` ++ NEWY=`echo $NEWXY | cut -d x -f 2` ++ ++ if [ ${NEWX} -ge 80 ] ; then ++ X=${NEWX} ++ else ++ echo "Warning: ${NEWX} is less than the minimum size of 80" ++ fi ++ ++ if [ ${NEWY} -ge 24 ] ; then ++ Y=${NEWY} ++ else ++ echo "Warning: ${NEWY} is less than the minimum size of 24" ++ fi ++ ++ shift ++ ;; ++ ++ *) ++# # accept console or ofconsole ++# if [ "$option" != "console" -a "$option" != "ofconsole" ] ; then ++# echo "Error: GRUB_TERMINFO unknown console: $option" ++# exit 1 ++# fi ++# # perfer console ++# TERMINAL=console ++ # accept ofconsole ++ if [ "$option" != "ofconsole" ] ; then ++ echo "Error: GRUB_TERMINFO unknown console: $option" ++ exit 1 ++ fi ++ # perfer console ++ TERMINAL=ofconsole ++ ;; ++ esac ++ ++ done ++ ++} ++ ++if ! uname -m | grep -q ppc ; then ++ exit 0 ++fi ++ ++if [ "x${GRUB_TERMINFO}" != "x" ] ; then ++ F1=`echo ${GRUB_TERMINFO} | cut -d " " -f 1` ++ ++ if [ "${F1}" != "terminfo" ] ; then ++ echo "Error: GRUB_TERMINFO is set to \"${GRUB_TERMINFO}\" The first word should be terminfo." ++ exit 1 ++ fi ++ ++ check_terminfo ${GRUB_TERMINFO} ++fi ++ ++cat << EOF ++ terminfo -g ${X}x${Y} ${TERMINAL} ++EOF +-- +1.8.1.4 + diff --git a/0344-Add-fw_path-variable-revised.patch b/0344-Add-fw_path-variable-revised.patch new file mode 100644 index 0000000..f4b069a --- /dev/null +++ b/0344-Add-fw_path-variable-revised.patch @@ -0,0 +1,88 @@ +From 3198c6026265f42d043e61587579ea590fcd2ad4 Mon Sep 17 00:00:00 2001 +From: Paulo Flabiano Smorigo +Date: Wed, 19 Sep 2012 21:22:55 -0300 +Subject: [PATCH 344/364] Add fw_path variable (revised) + +This patch makes grub look for its config file on efi where the app was +found. It was originally written by Matthew Garrett, and adapted to fix the +"No modules are loaded on grub2 network boot" issue: + +https://bugzilla.redhat.com/show_bug.cgi?id=857936 +--- + grub-core/kern/main.c | 16 ++++++++++++++-- + grub-core/normal/main.c | 25 ++++++++++++++++++++++++- + 2 files changed, 38 insertions(+), 3 deletions(-) + +diff --git a/grub-core/kern/main.c b/grub-core/kern/main.c +index 19dc988..8ab7794 100644 +--- a/grub-core/kern/main.c ++++ b/grub-core/kern/main.c +@@ -125,6 +125,20 @@ grub_set_prefix_and_root (void) + + grub_register_variable_hook ("root", 0, grub_env_write_root); + ++ grub_machine_get_bootlocation (&fwdevice, &fwpath); ++ ++ if (fwdevice && fwpath) ++ { ++ char *fw_path; ++ ++ fw_path = grub_xasprintf ("(%s)/%s", fwdevice, fwpath); ++ if (fw_path) ++ { ++ grub_env_set ("fw_path", fw_path); ++ grub_free (fw_path); ++ } ++ } ++ + if (prefix) + { + char *pptr = NULL; +@@ -142,8 +156,6 @@ grub_set_prefix_and_root (void) + if (pptr[0]) + path = grub_strdup (pptr); + } +- if ((!device || device[0] == ',' || !device[0]) || !path) +- grub_machine_get_bootlocation (&fwdevice, &fwpath); + + if (!device && fwdevice) + device = fwdevice; +diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c +index 9aaa3b2..ea8cd53 100644 +--- a/grub-core/normal/main.c ++++ b/grub-core/normal/main.c +@@ -346,7 +346,30 @@ grub_cmd_normal (struct grub_command *cmd __attribute__ ((unused)), + /* Guess the config filename. It is necessary to make CONFIG static, + so that it won't get broken by longjmp. */ + char *config; +- const char *prefix; ++ const char *prefix, *fw_path; ++ ++ fw_path = grub_env_get ("fw_path"); ++ if (fw_path) ++ { ++ config = grub_xasprintf ("%s/grub.cfg", fw_path); ++ if (config) ++ { ++ grub_file_t file; ++ ++ file = grub_file_open (config); ++ if (file) ++ { ++ grub_file_close (file); ++ grub_enter_normal_mode (config); ++ } ++ else ++ { ++ /* Ignore all errors. */ ++ grub_errno = 0; ++ } ++ grub_free (config); ++ } ++ } + + prefix = grub_env_get ("prefix"); + if (prefix) +-- +1.8.1.4 + diff --git a/0345-Don-t-set-boot-device-on-ppc-ieee1275.patch b/0345-Don-t-set-boot-device-on-ppc-ieee1275.patch new file mode 100644 index 0000000..c8c8f2e --- /dev/null +++ b/0345-Don-t-set-boot-device-on-ppc-ieee1275.patch @@ -0,0 +1,43 @@ +From 8aa77af6f9aad0d8a5b50a0670f85668ad489022 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Fri, 25 May 2012 14:57:38 -0400 +Subject: [PATCH 345/364] Don't set boot device on ppc-ieee1275 + +This started with the problem that powerkvm doesn't have /dev/nvram and so +there is no way to set boot-device. +--- + util/grub-install.in | 18 ++++++++++-------- + 1 file changed, 10 insertions(+), 8 deletions(-) + +diff --git a/util/grub-install.in b/util/grub-install.in +index 271e447..c9f66c7 100644 +--- a/util/grub-install.in ++++ b/util/grub-install.in +@@ -777,14 +777,16 @@ elif [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "i386-ieee1275" ] + } + fi + +- "$nvsetenv" boot-device "$boot_device" || { +- # TRANSLATORS: The %s will be replaced by an external program name. +- gettext_printf "\`%s' failed.\n" "$nvsetenv" 1>&2 +- gettext "You will have to set \`boot-device' variable manually. At the IEEE1275 prompt, type:" 1>&2 +- echo 1>&2 +- echo " setenv boot-device $boot_device" 1>&2 +- exit 1 +- } ++ if [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "i386-ieee1275" ]; then ++ "$nvsetenv" boot-device "$boot_device" || { ++ # TRANSLATORS: The %s will be replaced by an external program name. ++ gettext_printf "\`%s' failed.\n" "$nvsetenv" 1>&2 ++ gettext "You will have to set \`boot-device' variable manually. At the IEEE1275 prompt, type:" 1>&2 ++ echo 1>&2 ++ echo " setenv boot-device $boot_device" 1>&2 ++ exit 1 ++ } ++ fi + fi + elif [ x"${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = xmips-arc ]; then + dvhtool -d "${install_device}" --unix-to-vh "${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/core.${imgext}" grub +-- +1.8.1.4 + diff --git a/0346-Add-support-for-linuxefi.patch b/0346-Add-support-for-linuxefi.patch new file mode 100644 index 0000000..9e34dbd --- /dev/null +++ b/0346-Add-support-for-linuxefi.patch @@ -0,0 +1,482 @@ +From b9ec45bae44866fe0aff006d645d7b89efa4bc2f Mon Sep 17 00:00:00 2001 +From: Matthew Garrett +Date: Tue, 10 Jul 2012 11:58:52 -0400 +Subject: [PATCH 346/364] Add support for linuxefi + +--- + grub-core/Makefile.core.def | 8 + + grub-core/kern/efi/mm.c | 32 ++++ + grub-core/loader/i386/efi/linux.c | 371 ++++++++++++++++++++++++++++++++++++++ + include/grub/efi/efi.h | 3 + + include/grub/i386/linux.h | 1 + + 5 files changed, 415 insertions(+) + create mode 100644 grub-core/loader/i386/efi/linux.c + +diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def +index 8f36ea0..ca09eed 100644 +--- a/grub-core/Makefile.core.def ++++ b/grub-core/Makefile.core.def +@@ -1521,6 +1521,14 @@ module = { + }; + + module = { ++ name = linuxefi; ++ efi = loader/i386/efi/linux.c; ++ efi = lib/cmdline.c; ++ enable = i386_efi; ++ enable = x86_64_efi; ++}; ++ ++module = { + name = chain; + efi = loader/efi/chainloader.c; + i386_pc = loader/i386/pc/chainloader.c; +diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c +index 77c9384..025d665 100644 +--- a/grub-core/kern/efi/mm.c ++++ b/grub-core/kern/efi/mm.c +@@ -47,6 +47,38 @@ static grub_efi_uintn_t finish_desc_size; + static grub_efi_uint32_t finish_desc_version; + int grub_efi_is_finished = 0; + ++/* Allocate pages below a specified address */ ++void * ++grub_efi_allocate_pages_max (grub_efi_physical_address_t max, ++ grub_efi_uintn_t pages) ++{ ++ grub_efi_status_t status; ++ grub_efi_boot_services_t *b; ++ grub_efi_physical_address_t address = max; ++ ++ if (max > 0xffffffff) ++ return 0; ++ ++ b = grub_efi_system_table->boot_services; ++ status = efi_call_4 (b->allocate_pages, GRUB_EFI_ALLOCATE_MAX_ADDRESS, GRUB_EFI_LOADER_DATA, pages, &address); ++ ++ if (status != GRUB_EFI_SUCCESS) ++ return 0; ++ ++ if (address == 0) ++ { ++ /* Uggh, the address 0 was allocated... This is too annoying, ++ so reallocate another one. */ ++ address = max; ++ status = efi_call_4 (b->allocate_pages, GRUB_EFI_ALLOCATE_MAX_ADDRESS, GRUB_EFI_LOADER_DATA, pages, &address); ++ grub_efi_free_pages (0, pages); ++ if (status != GRUB_EFI_SUCCESS) ++ return 0; ++ } ++ ++ return (void *) ((grub_addr_t) address); ++} ++ + /* Allocate pages. Return the pointer to the first of allocated pages. */ + void * + grub_efi_allocate_pages (grub_efi_physical_address_t address, +diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c +new file mode 100644 +index 0000000..b79e632 +--- /dev/null ++++ b/grub-core/loader/i386/efi/linux.c +@@ -0,0 +1,371 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2012 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_MOD_LICENSE ("GPLv3+"); ++ ++static grub_dl_t my_mod; ++static int loaded; ++static void *kernel_mem; ++static grub_uint64_t kernel_size; ++static grub_uint8_t *initrd_mem; ++static grub_uint32_t handover_offset; ++struct linux_kernel_params *params; ++static char *linux_cmdline; ++ ++#define BYTES_TO_PAGES(bytes) (((bytes) + 0xfff) >> 12) ++ ++#define SHIM_LOCK_GUID \ ++ { 0x605dab50, 0xe046, 0x4300, {0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23} } ++ ++struct grub_efi_shim_lock ++{ ++ grub_efi_status_t (*verify) (void *buffer, grub_uint32_t size); ++}; ++typedef struct grub_efi_shim_lock grub_efi_shim_lock_t; ++ ++static grub_efi_boolean_t ++grub_linuxefi_secure_validate (void *data, grub_uint32_t size) ++{ ++ grub_efi_guid_t guid = SHIM_LOCK_GUID; ++ grub_efi_shim_lock_t *shim_lock; ++ ++ shim_lock = grub_efi_locate_protocol(&guid, NULL); ++ ++ if (!shim_lock) ++ return 1; ++ ++ if (shim_lock->verify(data, size) == GRUB_EFI_SUCCESS) ++ return 1; ++ ++ return 0; ++} ++ ++typedef void(*handover_func)(void *, grub_efi_system_table_t *, struct linux_kernel_params *); ++ ++static grub_err_t ++grub_linuxefi_boot (void) ++{ ++ handover_func hf; ++ int offset = 0; ++ ++#ifdef __x86_64__ ++ offset = 512; ++#endif ++ ++ hf = (handover_func)((char *)kernel_mem + handover_offset + offset); ++ ++ asm volatile ("cli"); ++ ++ hf (grub_efi_image_handle, grub_efi_system_table, params); ++ ++ /* Not reached */ ++ return GRUB_ERR_NONE; ++} ++ ++static grub_err_t ++grub_linuxefi_unload (void) ++{ ++ grub_dl_unref (my_mod); ++ loaded = 0; ++ if (initrd_mem) ++ grub_efi_free_pages((grub_efi_physical_address_t)initrd_mem, BYTES_TO_PAGES(params->ramdisk_size)); ++ if (linux_cmdline) ++ grub_efi_free_pages((grub_efi_physical_address_t)linux_cmdline, BYTES_TO_PAGES(params->cmdline_size + 1)); ++ if (kernel_mem) ++ grub_efi_free_pages((grub_efi_physical_address_t)kernel_mem, BYTES_TO_PAGES(kernel_size)); ++ if (params) ++ grub_efi_free_pages((grub_efi_physical_address_t)params, BYTES_TO_PAGES(16384)); ++ return GRUB_ERR_NONE; ++} ++ ++static grub_err_t ++grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), ++ int argc, char *argv[]) ++{ ++ grub_file_t *files = 0; ++ int i, nfiles = 0; ++ grub_size_t size = 0; ++ grub_uint8_t *ptr; ++ ++ if (argc == 0) ++ { ++ grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); ++ goto fail; ++ } ++ ++ if (!loaded) ++ { ++ grub_error (GRUB_ERR_BAD_ARGUMENT, N_("you need to load the kernel first")); ++ goto fail; ++ } ++ ++ files = grub_zalloc (argc * sizeof (files[0])); ++ if (!files) ++ goto fail; ++ ++ for (i = 0; i < argc; i++) ++ { ++ grub_file_filter_disable_compression (); ++ files[i] = grub_file_open (argv[i]); ++ if (! files[i]) ++ goto fail; ++ nfiles++; ++ size += ALIGN_UP (grub_file_size (files[i]), 4); ++ } ++ ++ initrd_mem = grub_efi_allocate_pages_max (0x3fffffff, BYTES_TO_PAGES(size)); ++ ++ if (!initrd_mem) ++ { ++ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate initrd")); ++ goto fail; ++ } ++ ++ params->ramdisk_size = size; ++ params->ramdisk_image = (grub_uint32_t)(grub_uint64_t) initrd_mem; ++ ++ ptr = initrd_mem; ++ ++ for (i = 0; i < nfiles; i++) ++ { ++ grub_ssize_t cursize = grub_file_size (files[i]); ++ if (grub_file_read (files[i], ptr, cursize) != cursize) ++ { ++ if (!grub_errno) ++ grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"), ++ argv[i]); ++ goto fail; ++ } ++ ptr += cursize; ++ grub_memset (ptr, 0, ALIGN_UP_OVERHEAD (cursize, 4)); ++ ptr += ALIGN_UP_OVERHEAD (cursize, 4); ++ } ++ ++ params->ramdisk_size = size; ++ ++ fail: ++ for (i = 0; i < nfiles; i++) ++ grub_file_close (files[i]); ++ grub_free (files); ++ ++ if (initrd_mem && grub_errno) ++ grub_efi_free_pages((grub_efi_physical_address_t)initrd_mem, BYTES_TO_PAGES(size)); ++ ++ return grub_errno; ++} ++ ++static grub_err_t ++grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), ++ int argc, char *argv[]) ++{ ++ grub_file_t file = 0; ++ struct linux_kernel_header lh; ++ grub_ssize_t len, start, filelen; ++ void *kernel; ++ ++ grub_dl_ref (my_mod); ++ ++ if (argc == 0) ++ { ++ grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); ++ goto fail; ++ } ++ ++ file = grub_file_open (argv[0]); ++ if (! file) ++ goto fail; ++ ++ filelen = grub_file_size (file); ++ ++ kernel = grub_malloc(filelen); ++ ++ if (!kernel) ++ { ++ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("cannot allocate kernel buffer")); ++ goto fail; ++ } ++ ++ if (grub_file_read (file, kernel, filelen) != filelen) ++ { ++ grub_error (GRUB_ERR_FILE_READ_ERROR, N_("Can't read kernel %s"), argv[0]); ++ goto fail; ++ } ++ ++ if (! grub_linuxefi_secure_validate (kernel, filelen)) ++ { ++ grub_error (GRUB_ERR_INVALID_COMMAND, N_("%s has invalid signature"), argv[0]); ++ grub_free (kernel); ++ goto fail; ++ } ++ ++ grub_file_seek (file, 0); ++ ++ grub_free(kernel); ++ ++ params = grub_efi_allocate_pages_max (0x3fffffff, BYTES_TO_PAGES(16384)); ++ ++ if (! params) ++ { ++ grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate kernel parameters"); ++ goto fail; ++ } ++ ++ memset (params, 0, 16384); ++ ++ if (grub_file_read (file, &lh, sizeof (lh)) != sizeof (lh)) ++ { ++ if (!grub_errno) ++ grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), ++ argv[0]); ++ goto fail; ++ } ++ ++ if (lh.boot_flag != grub_cpu_to_le16 (0xaa55)) ++ { ++ grub_error (GRUB_ERR_BAD_OS, N_("invalid magic number")); ++ goto fail; ++ } ++ ++ if (lh.setup_sects > GRUB_LINUX_MAX_SETUP_SECTS) ++ { ++ grub_error (GRUB_ERR_BAD_OS, N_("too many setup sectors")); ++ goto fail; ++ } ++ ++ if (lh.version < grub_cpu_to_le16 (0x020b)) ++ { ++ grub_error (GRUB_ERR_BAD_OS, N_("kernel too old")); ++ goto fail; ++ } ++ ++ if (!lh.handover_offset) ++ { ++ grub_error (GRUB_ERR_BAD_OS, N_("kernel doesn't support EFI handover")); ++ goto fail; ++ } ++ ++ linux_cmdline = grub_efi_allocate_pages_max(0x3fffffff, ++ BYTES_TO_PAGES(lh.cmdline_size + 1)); ++ ++ if (!linux_cmdline) ++ { ++ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate cmdline")); ++ goto fail; ++ } ++ ++ grub_memcpy (linux_cmdline, LINUX_IMAGE, sizeof (LINUX_IMAGE)); ++ grub_create_loader_cmdline (argc, argv, ++ linux_cmdline + sizeof (LINUX_IMAGE) - 1, ++ lh.cmdline_size - (sizeof (LINUX_IMAGE) - 1)); ++ ++ lh.cmd_line_ptr = (grub_uint32_t)(grub_uint64_t)linux_cmdline; ++ ++ handover_offset = lh.handover_offset; ++ ++ start = (lh.setup_sects + 1) * 512; ++ len = grub_file_size(file) - start; ++ ++ kernel_mem = grub_efi_allocate_pages(lh.pref_address, ++ BYTES_TO_PAGES(lh.init_size)); ++ ++ if (!kernel_mem) ++ kernel_mem = grub_efi_allocate_pages_max(0x3fffffff, ++ BYTES_TO_PAGES(lh.init_size)); ++ ++ if (!kernel_mem) ++ { ++ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate kernel")); ++ goto fail; ++ } ++ ++ if (grub_file_seek (file, start) == (grub_off_t) -1) ++ { ++ grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), ++ argv[0]); ++ goto fail; ++ } ++ ++ if (grub_file_read (file, kernel_mem, len) != len && !grub_errno) ++ { ++ grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), ++ argv[0]); ++ } ++ ++ if (grub_errno == GRUB_ERR_NONE) ++ { ++ grub_loader_set (grub_linuxefi_boot, grub_linuxefi_unload, 0); ++ loaded = 1; ++ lh.code32_start = (grub_uint32_t)(grub_uint64_t) kernel_mem; ++ } ++ ++ memcpy(params, &lh, 2 * 512); ++ ++ params->type_of_loader = 0x21; ++ ++ fail: ++ ++ if (file) ++ grub_file_close (file); ++ ++ if (grub_errno != GRUB_ERR_NONE) ++ { ++ grub_dl_unref (my_mod); ++ loaded = 0; ++ } ++ ++ if (linux_cmdline && !loaded) ++ grub_efi_free_pages((grub_efi_physical_address_t)linux_cmdline, BYTES_TO_PAGES(lh.cmdline_size + 1)); ++ ++ if (kernel_mem && !loaded) ++ grub_efi_free_pages((grub_efi_physical_address_t)kernel_mem, BYTES_TO_PAGES(kernel_size)); ++ ++ if (params && !loaded) ++ grub_efi_free_pages((grub_efi_physical_address_t)params, BYTES_TO_PAGES(16384)); ++ ++ return grub_errno; ++} ++ ++static grub_command_t cmd_linux, cmd_initrd; ++ ++GRUB_MOD_INIT(linuxefi) ++{ ++ cmd_linux = ++ grub_register_command ("linuxefi", grub_cmd_linux, ++ 0, N_("Load Linux.")); ++ cmd_initrd = ++ grub_register_command ("initrdefi", grub_cmd_initrd, ++ 0, N_("Load initrd.")); ++ my_mod = mod; ++} ++ ++GRUB_MOD_FINI(linuxefi) ++{ ++ grub_unregister_command (cmd_linux); ++ grub_unregister_command (cmd_initrd); ++} +diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h +index 489cf9e..9370fd5 100644 +--- a/include/grub/efi/efi.h ++++ b/include/grub/efi/efi.h +@@ -40,6 +40,9 @@ void EXPORT_FUNC(grub_efi_stall) (grub_efi_uintn_t microseconds); + void * + EXPORT_FUNC(grub_efi_allocate_pages) (grub_efi_physical_address_t address, + grub_efi_uintn_t pages); ++void * ++EXPORT_FUNC(grub_efi_allocate_pages_max) (grub_efi_physical_address_t max, ++ grub_efi_uintn_t pages); + void EXPORT_FUNC(grub_efi_free_pages) (grub_efi_physical_address_t address, + grub_efi_uintn_t pages); + int +diff --git a/include/grub/i386/linux.h b/include/grub/i386/linux.h +index 9d064c8..c29c5af 100644 +--- a/include/grub/i386/linux.h ++++ b/include/grub/i386/linux.h +@@ -139,6 +139,7 @@ struct linux_kernel_header + grub_uint64_t setup_data; + grub_uint64_t pref_address; + grub_uint32_t init_size; ++ grub_uint32_t handover_offset; + } __attribute__ ((packed)); + + /* Boot parameters for Linux based on 2.6.12. This is used by the setup +-- +1.8.1.4 + diff --git a/0347-Add-support-for-crappy-cd-craparino.patch b/0347-Add-support-for-crappy-cd-craparino.patch new file mode 100644 index 0000000..bd509a4 --- /dev/null +++ b/0347-Add-support-for-crappy-cd-craparino.patch @@ -0,0 +1,33 @@ +From 3a38d333bfdcdca7546b7c005453cd02a78c8423 Mon Sep 17 00:00:00 2001 +From: Matthew Garrett +Date: Tue, 10 Jul 2012 11:58:52 -0400 +Subject: [PATCH 347/364] Add support for crappy cd craparino + +--- + grub-core/disk/efi/efidisk.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/grub-core/disk/efi/efidisk.c b/grub-core/disk/efi/efidisk.c +index e168d07..3a006ab 100644 +--- a/grub-core/disk/efi/efidisk.c ++++ b/grub-core/disk/efi/efidisk.c +@@ -794,6 +794,16 @@ grub_efidisk_get_device_name (grub_efi_handle_t *handle) + if (! ldp) + return 0; + ++ if (GRUB_EFI_DEVICE_PATH_TYPE (ldp) == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE && ++ (GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) == GRUB_EFI_CDROM_DEVICE_PATH_SUBTYPE)) ++ { ++ ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE; ++ ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE; ++ ldp->length[0] = 4; ++ ldp->length[1] = 0; ++ ldp = find_last_device_path(dp); ++ } ++ + if (GRUB_EFI_DEVICE_PATH_TYPE (ldp) == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE + && (GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) + == GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE)) +-- +1.8.1.4 + diff --git a/0348-Use-linuxefi-and-initrdefi-where-appropriate.patch b/0348-Use-linuxefi-and-initrdefi-where-appropriate.patch new file mode 100644 index 0000000..a81eab9 --- /dev/null +++ b/0348-Use-linuxefi-and-initrdefi-where-appropriate.patch @@ -0,0 +1,50 @@ +From 2398a5d9dbf6b095513d3a469d2711ca25f85311 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Mon, 16 Jul 2012 18:57:11 -0400 +Subject: [PATCH 348/364] Use "linuxefi" and "initrdefi" where appropriate. + +--- + util/grub.d/10_linux.in | 18 ++++++++++++++++-- + 1 file changed, 16 insertions(+), 2 deletions(-) + +diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in +index 368f609..4807d84 100644 +--- a/util/grub.d/10_linux.in ++++ b/util/grub.d/10_linux.in +@@ -133,17 +133,31 @@ linux_entry () + printf '%s\n' "${prepare_boot_cache}" | sed "s/^/$submenu_indentation/" + fi + message="$(gettext_printf "Loading Linux %s ..." ${version})" +- sed "s/^/$submenu_indentation/" << EOF ++ if [ -d /sys/firmware/efi ]; then ++ sed "s/^/$submenu_indentation/" << EOF ++ echo '$(echo "$message" | grub_quote)' ++ linuxefi ${rel_dirname}/${basename} root=${linux_root_device_thisversion} ro ${args} ++EOF ++ else ++ sed "s/^/$submenu_indentation/" << EOF + echo '$(echo "$message" | grub_quote)' + linux ${rel_dirname}/${basename} root=${linux_root_device_thisversion} ro ${args} + EOF ++ fi + if test -n "${initrd}" ; then + # TRANSLATORS: ramdisk isn't identifier. Should be translated. + message="$(gettext_printf "Loading initial ramdisk ...")" +- sed "s/^/$submenu_indentation/" << EOF ++ if [ -d /sys/firmware/efi ]; then ++ sed "s/^/$submenu_indentation/" << EOF + echo '$(echo "$message" | grub_quote)' ++ initrdefi ${rel_dirname}/${initrd} ++EOF ++ else ++ sed "s/^/$submenu_indentation/" << EOF ++ echo '$message' + initrd ${rel_dirname}/${initrd} + EOF ++ fi + fi + sed "s/^/$submenu_indentation/" << EOF + } +-- +1.8.1.4 + diff --git a/0349-Don-t-allow-insmod-when-secure-boot-is-enabled.patch b/0349-Don-t-allow-insmod-when-secure-boot-is-enabled.patch new file mode 100644 index 0000000..084991b --- /dev/null +++ b/0349-Don-t-allow-insmod-when-secure-boot-is-enabled.patch @@ -0,0 +1,113 @@ +From 16841c32f8cdb8ded3ac7bb2e2a4eb2fcfe9d93f Mon Sep 17 00:00:00 2001 +From: Colin Watson +Date: Tue, 23 Oct 2012 10:40:49 -0400 +Subject: [PATCH 349/364] Don't allow insmod when secure boot is enabled. + +Hi, + +Fedora's patch to forbid insmod in UEFI Secure Boot environments is fine +as far as it goes. However, the insmod command is not the only way that +modules can be loaded. In particular, the 'normal' command, which +implements the usual GRUB menu and the fully-featured command prompt, +will implicitly load commands not currently loaded into memory. This +permits trivial Secure Boot violations by writing commands implementing +whatever you want to do and pointing $prefix at the malicious code. + +I'm currently test-building this patch (replacing your current +grub-2.00-no-insmod-on-sb.patch), but this should be more correct. It +moves the check into grub_dl_load_file. +--- + grub-core/kern/dl.c | 17 +++++++++++++++++ + grub-core/kern/efi/efi.c | 28 ++++++++++++++++++++++++++++ + include/grub/efi/efi.h | 1 + + 3 files changed, 46 insertions(+) + +diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c +index c6d9ec9..570be12 100644 +--- a/grub-core/kern/dl.c ++++ b/grub-core/kern/dl.c +@@ -42,6 +42,10 @@ + #include + #endif + ++#ifdef GRUB_MACHINE_EFI ++#include ++#endif ++ + + + #pragma GCC diagnostic ignored "-Wcast-align" +@@ -673,6 +677,19 @@ grub_dl_load_file (const char *filename) + void *core = 0; + grub_dl_t mod = 0; + ++#ifdef GRUB_MACHINE_EFI ++ if (grub_efi_secure_boot ()) ++ { ++#if 0 ++ /* This is an error, but grub2-mkconfig still generates a pile of ++ * insmod commands, so emitting it would be mostly just obnoxious. */ ++ grub_error (GRUB_ERR_ACCESS_DENIED, ++ "Secure Boot forbids loading module from %s", filename); ++#endif ++ return 0; ++ } ++#endif ++ + file = grub_file_open (filename); + if (! file) + return 0; +diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c +index e8a62ec..0f513e8 100644 +--- a/grub-core/kern/efi/efi.c ++++ b/grub-core/kern/efi/efi.c +@@ -259,6 +259,34 @@ grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid, + return NULL; + } + ++grub_efi_boolean_t ++grub_efi_secure_boot (void) ++{ ++ grub_efi_guid_t efi_var_guid = GRUB_EFI_GLOBAL_VARIABLE_GUID; ++ grub_size_t datasize; ++ char *secure_boot = NULL; ++ char *setup_mode = NULL; ++ grub_efi_boolean_t ret = 0; ++ ++ secure_boot = grub_efi_get_variable("SecureBoot", &efi_var_guid, &datasize); ++ ++ if (datasize != 1 || !secure_boot) ++ goto out; ++ ++ setup_mode = grub_efi_get_variable("SetupMode", &efi_var_guid, &datasize); ++ ++ if (datasize != 1 || !setup_mode) ++ goto out; ++ ++ if (*secure_boot && !*setup_mode) ++ ret = 1; ++ ++ out: ++ grub_free (secure_boot); ++ grub_free (setup_mode); ++ return ret; ++} ++ + #pragma GCC diagnostic ignored "-Wcast-align" + + /* Search the mods section from the PE32/PE32+ image. This code uses +diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h +index 9370fd5..a000c38 100644 +--- a/include/grub/efi/efi.h ++++ b/include/grub/efi/efi.h +@@ -72,6 +72,7 @@ EXPORT_FUNC (grub_efi_set_variable) (const char *var, + const grub_efi_guid_t *guid, + void *data, + grub_size_t datasize); ++grub_efi_boolean_t EXPORT_FUNC (grub_efi_secure_boot) (void); + int + EXPORT_FUNC (grub_efi_compare_device_paths) (const grub_efi_device_path_t *dp1, + const grub_efi_device_path_t *dp2); +-- +1.8.1.4 + diff --git a/0351-Pass-x-hex-hex-straight-through-unmolested.patch b/0351-Pass-x-hex-hex-straight-through-unmolested.patch new file mode 100644 index 0000000..e2ea5c3 --- /dev/null +++ b/0351-Pass-x-hex-hex-straight-through-unmolested.patch @@ -0,0 +1,183 @@ +From a20c29e7b8c9b92fc8919968a2382737d6662695 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Mon, 1 Oct 2012 13:24:37 -0400 +Subject: [PATCH 351/364] Pass "\x[[:hex:]][[:hex:]]" straight through + unmolested. + +--- + grub-core/commands/wildcard.c | 16 +++++++++++++++- + grub-core/lib/cmdline.c | 34 ++++++++++++++++++++++++++++++++-- + grub-core/script/execute.c | 43 +++++++++++++++++++++++++++++++++++++------ + 3 files changed, 84 insertions(+), 9 deletions(-) + +diff --git a/grub-core/commands/wildcard.c b/grub-core/commands/wildcard.c +index 2807f80..0f40e04 100644 +--- a/grub-core/commands/wildcard.c ++++ b/grub-core/commands/wildcard.c +@@ -458,6 +458,12 @@ check_file (const char *dir, const char *basename) + return ctx.found; + } + ++static int ++is_hex(char c) ++{ ++ return ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')); ++} ++ + static void + unescape (char *out, const char *in, const char *end) + { +@@ -466,7 +472,15 @@ unescape (char *out, const char *in, const char *end) + + for (optr = out, iptr = in; iptr < end;) + { +- if (*iptr == '\\' && iptr + 1 < end) ++ if (*iptr == '\\' && iptr + 3 < end && iptr[1] == 'x' && is_hex(iptr[2]) && is_hex(iptr[3])) ++ { ++ *optr++ = *iptr++; ++ *optr++ = *iptr++; ++ *optr++ = *iptr++; ++ *optr++ = *iptr++; ++ continue; ++ } ++ else if (*iptr == '\\' && iptr + 1 < end) + { + *optr++ = iptr[1]; + iptr += 2; +diff --git a/grub-core/lib/cmdline.c b/grub-core/lib/cmdline.c +index a702e64..c8605a7 100644 +--- a/grub-core/lib/cmdline.c ++++ b/grub-core/lib/cmdline.c +@@ -20,6 +20,12 @@ + #include + #include + ++static int ++is_hex(char c) ++{ ++ return ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')); ++} ++ + static unsigned int check_arg (char *c, int *has_space) + { + int space = 0; +@@ -27,7 +33,13 @@ static unsigned int check_arg (char *c, int *has_space) + + while (*c) + { +- if (*c == '\\' || *c == '\'' || *c == '"') ++ if (*c == '\\' && *(c+1) == 'x' && is_hex(*(c+2)) && is_hex(*(c+3))) ++ { ++ size += 4; ++ c += 4; ++ continue; ++ } ++ else if (*c == '\\' || *c == '\'' || *c == '"') + size++; + else if (*c == ' ') + space = 1; +@@ -82,7 +94,25 @@ int grub_create_loader_cmdline (int argc, char *argv[], char *buf, + + while (*c) + { +- if (*c == '\\' || *c == '\'' || *c == '"') ++ if (*c == ' ') ++ { ++ *buf++ = '\\'; ++ *buf++ = 'x'; ++ *buf++ = '2'; ++ *buf++ = '0'; ++ c++; ++ continue; ++ } ++ else if (*c == '\\' && *(c+1) == 'x' && ++ is_hex(*(c+2)) && is_hex(*(c+3))) ++ { ++ *buf++ = *c++; ++ *buf++ = *c++; ++ *buf++ = *c++; ++ *buf++ = *c++; ++ continue; ++ } ++ else if (*c == '\\' || *c == '\'' || *c == '"') + *buf++ = '\\'; + + *buf++ = *c; +diff --git a/grub-core/script/execute.c b/grub-core/script/execute.c +index a1dcc34..686e1fa 100644 +--- a/grub-core/script/execute.c ++++ b/grub-core/script/execute.c +@@ -52,6 +52,12 @@ static struct grub_script_scope *scope = 0; + /* Wildcard translator for GRUB script. */ + struct grub_script_wildcard_translator *grub_wildcard_translator; + ++static int ++is_hex(char c) ++{ ++ return ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')); ++} ++ + static char* + wildcard_escape (const char *s) + { +@@ -68,7 +74,15 @@ wildcard_escape (const char *s) + i = 0; + while ((ch = *s++)) + { +- if (ch == '*' || ch == '\\' || ch == '?') ++ if (ch == '\\' && s[0] == 'x' && is_hex(s[1]) && is_hex(s[2])) ++ { ++ p[i++] = ch; ++ p[i++] = *s++; ++ p[i++] = *s++; ++ p[i++] = *s++; ++ continue; ++ } ++ else if (ch == '*' || ch == '\\' || ch == '?') + p[i++] = '\\'; + p[i++] = ch; + } +@@ -92,7 +106,14 @@ wildcard_unescape (const char *s) + i = 0; + while ((ch = *s++)) + { +- if (ch == '\\') ++ if (ch == '\\' && s[0] == 'x' && is_hex(s[1]) && is_hex(s[2])) ++ { ++ p[i++] = '\\'; ++ p[i++] = *s++; ++ p[i++] = *s++; ++ p[i++] = *s++; ++ } ++ else if (ch == '\\') + p[i++] = *s++; + else + p[i++] = ch; +@@ -394,10 +415,20 @@ parse_string (const char *str, + switch (*ptr) + { + case '\\': +- escaped = !escaped; +- if (!escaped && put) +- *(put++) = '\\'; +- ptr++; ++ if (!escaped && put && *(ptr+1) == 'x' && is_hex(*(ptr+2)) && is_hex(*(ptr+3))) ++ { ++ *(put++) = *ptr++; ++ *(put++) = *ptr++; ++ *(put++) = *ptr++; ++ *(put++) = *ptr++; ++ } ++ else ++ { ++ escaped = !escaped; ++ if (!escaped && put) ++ *(put++) = '\\'; ++ ptr++; ++ } + break; + case '$': + if (escaped) +-- +1.8.1.4 + diff --git a/0352-Fix-crash-on-http.patch b/0352-Fix-crash-on-http.patch new file mode 100644 index 0000000..fc2273f --- /dev/null +++ b/0352-Fix-crash-on-http.patch @@ -0,0 +1,28 @@ +From 8f9b02e937baf68c322b5798b59fbe4617712133 Mon Sep 17 00:00:00 2001 +From: Gustavo Luiz Duarte +Date: Tue, 25 Sep 2012 18:40:55 -0400 +Subject: [PATCH 352/364] Fix crash on http + +Don't free file->data on receiving FIN flag since it is used all over without +checking. http_close() will be called later to free that memory. +https://bugzilla.redhat.com/show_bug.cgi?id=860834 +--- + grub-core/net/http.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/grub-core/net/http.c b/grub-core/net/http.c +index 4684f8b..ef9538c 100644 +--- a/grub-core/net/http.c ++++ b/grub-core/net/http.c +@@ -393,7 +393,7 @@ http_establish (struct grub_file *file, grub_off_t offset, int initial) + + data->sock = grub_net_tcp_open (file->device->net->server, + HTTP_PORT, http_receive, +- http_err, http_err, ++ http_err, NULL, + file); + if (!data->sock) + { +-- +1.8.1.4 + diff --git a/0353-Issue-separate-DNS-queries-for-ipv4-and-ipv6.patch b/0353-Issue-separate-DNS-queries-for-ipv4-and-ipv6.patch new file mode 100644 index 0000000..c3d8234 --- /dev/null +++ b/0353-Issue-separate-DNS-queries-for-ipv4-and-ipv6.patch @@ -0,0 +1,230 @@ +From 90e4864ecae8cc40d1f9562556a866d15ddc491f Mon Sep 17 00:00:00 2001 +From: Gustavo Luiz Duarte +Date: Fri, 28 Sep 2012 19:42:07 -0400 +Subject: [PATCH 353/364] Issue separate DNS queries for ipv4 and ipv6 + +Adding multiple questions on a single DNS query is not supportted by +most DNS servers. This patch issues two separate DNS queries +sequentially for ipv4 and then for ipv6. + +There are 4 possible config options: + DNS_OPTION_IPV4: issue only one ipv4 query + DNS_OPTION_IPV6: issue only one ipv6 query + DNS_OPTION_PREFER_IPV4: issue the ipv4 query first and fallback to ipv6 + DNS_OPTION_PREFER_IPV6: issue the ipv6 query first and fallback to ipv4 +However, there is no code yet to set such config option. The default is +DNS_OPTION_PREFER_IPV4. + +Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=860829 +--- + grub-core/net/dns.c | 99 ++++++++++++++++++++++++++++++++++++----------------- + include/grub/net.h | 9 +++++ + 2 files changed, 76 insertions(+), 32 deletions(-) + +diff --git a/grub-core/net/dns.c b/grub-core/net/dns.c +index 3381ea7..fac97b0 100644 +--- a/grub-core/net/dns.c ++++ b/grub-core/net/dns.c +@@ -34,6 +34,14 @@ struct dns_cache_element + #define DNS_CACHE_SIZE 1021 + #define DNS_HASH_BASE 423 + ++typedef enum grub_dns_qtype_id ++ { ++ GRUB_DNS_QTYPE_A = 1, ++ GRUB_DNS_QTYPE_AAAA = 28 ++ } grub_dns_qtype_id_t; ++ ++static grub_dns_option_t dns_type_option = DNS_OPTION_PREFER_IPV4; ++ + static struct dns_cache_element dns_cache[DNS_CACHE_SIZE]; + static struct grub_net_network_level_address *dns_servers; + static grub_size_t dns_nservers, dns_servers_alloc; +@@ -410,13 +418,13 @@ recv_hook (grub_net_udp_socket_t sock __attribute__ ((unused)), + return GRUB_ERR_NONE; + } + +-grub_err_t +-grub_net_dns_lookup (const char *name, ++static grub_err_t ++grub_net_dns_lookup_qtype (const char *name, + const struct grub_net_network_level_address *servers, + grub_size_t n_servers, + grub_size_t *naddresses, + struct grub_net_network_level_address **addresses, +- int cache) ++ int cache, grub_dns_qtype_id_t qtype) + { + grub_size_t send_servers = 0; + grub_size_t i, j; +@@ -471,8 +479,7 @@ grub_net_dns_lookup (const char *name, + + GRUB_NET_MAX_LINK_HEADER_SIZE + + GRUB_NET_UDP_HEADER_SIZE + + sizeof (struct dns_header) +- + grub_strlen (name) + 2 + 4 +- + 2 + 4); ++ + grub_strlen (name) + 2 + 4); + if (!nb) + { + grub_free (data.name); +@@ -482,7 +489,7 @@ grub_net_dns_lookup (const char *name, + + GRUB_NET_MAX_LINK_HEADER_SIZE + + GRUB_NET_UDP_HEADER_SIZE); + grub_netbuff_put (nb, sizeof (struct dns_header) +- + grub_strlen (name) + 2 + 4 + 2 + 4); ++ + grub_strlen (name) + 2 + 4); + head = (struct dns_header *) nb->data; + optr = (grub_uint8_t *) (head + 1); + for (iptr = name; *iptr; ) +@@ -509,18 +516,7 @@ grub_net_dns_lookup (const char *name, + + /* Type: A. */ + *optr++ = 0; +- *optr++ = 1; +- +- /* Class. */ +- *optr++ = 0; +- *optr++ = 1; +- +- /* Compressed name. */ +- *optr++ = 0xc0; +- *optr++ = 0x0c; +- /* Type: AAAA. */ +- *optr++ = 0; +- *optr++ = 28; ++ *optr++ = qtype; + + /* Class. */ + *optr++ = 0; +@@ -529,7 +525,7 @@ grub_net_dns_lookup (const char *name, + head->id = data.id; + head->flags = FLAGS_RD; + head->ra_z_r_code = 0; +- head->qdcount = grub_cpu_to_be16_compile_time (2); ++ head->qdcount = grub_cpu_to_be16_compile_time (1); + head->ancount = grub_cpu_to_be16_compile_time (0); + head->nscount = grub_cpu_to_be16_compile_time (0); + head->arcount = grub_cpu_to_be16_compile_time (0); +@@ -587,16 +583,47 @@ grub_net_dns_lookup (const char *name, + if (*data.naddresses) + return GRUB_ERR_NONE; + if (data.dns_err) +- return grub_error (GRUB_ERR_NET_NO_DOMAIN, +- N_("no DNS record found")); +- ++ { ++ grub_dprintf ("dns", "%s. QTYPE: %u QNAME: %s\n", ++ N_("no DNS record found"), qtype, name); ++ return GRUB_ERR_NET_NO_DOMAIN; ++ } + if (err) + { + grub_errno = err; + return err; + } +- return grub_error (GRUB_ERR_TIMEOUT, +- N_("no DNS reply received")); ++ grub_dprintf ("dns", "%s. QTYPE: %u QNAME: %s\n", ++ N_("no DNS reply received"), qtype, name); ++ return GRUB_ERR_TIMEOUT; ++} ++ ++grub_err_t ++grub_net_dns_lookup (const char *name, ++ const struct grub_net_network_level_address *servers, ++ grub_size_t n_servers, ++ grub_size_t *naddresses, ++ struct grub_net_network_level_address **addresses, ++ int cache) ++{ ++ if (dns_type_option == DNS_OPTION_IPV6 || dns_type_option == DNS_OPTION_PREFER_IPV6) ++ grub_net_dns_lookup_qtype (name, servers, n_servers, naddresses, ++ addresses, cache, GRUB_DNS_QTYPE_AAAA); ++ else ++ grub_net_dns_lookup_qtype (name, servers, n_servers, naddresses, ++ addresses, cache, GRUB_DNS_QTYPE_A); ++ if (!*naddresses) ++ { ++ if (dns_type_option == DNS_OPTION_PREFER_IPV4) ++ grub_net_dns_lookup_qtype (name, servers, n_servers, naddresses, ++ addresses, cache, GRUB_DNS_QTYPE_AAAA); ++ else if (dns_type_option == DNS_OPTION_PREFER_IPV6) ++ grub_net_dns_lookup_qtype (name, servers, n_servers, naddresses, ++ addresses, cache, GRUB_DNS_QTYPE_A); ++ } ++ if (!*naddresses) ++ return GRUB_ERR_NET_NO_DOMAIN; ++ return GRUB_ERR_NONE; + } + + static grub_err_t +@@ -604,22 +631,28 @@ grub_cmd_nslookup (struct grub_command *cmd __attribute__ ((unused)), + int argc, char **args) + { + grub_err_t err; +- grub_size_t naddresses, i; ++ struct grub_net_network_level_address cmd_server; ++ struct grub_net_network_level_address *servers; ++ grub_size_t nservers, i, naddresses = 0; + struct grub_net_network_level_address *addresses = 0; + if (argc != 2 && argc != 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("two arguments expected")); + if (argc == 2) + { +- struct grub_net_network_level_address server; +- err = grub_net_resolve_address (args[1], &server); ++ err = grub_net_resolve_address (args[1], &cmd_server); + if (err) + return err; +- err = grub_net_dns_lookup (args[0], &server, 1, &naddresses, +- &addresses, 0); ++ servers = &cmd_server; ++ nservers = 1; + } + else +- err = grub_net_dns_lookup (args[0], dns_servers, dns_nservers, &naddresses, +- &addresses, 0); ++ { ++ servers = dns_servers; ++ nservers = dns_nservers; ++ } ++ ++ grub_net_dns_lookup (args[0], servers, nservers, &naddresses, ++ &addresses, 0); + + for (i = 0; i < naddresses; i++) + { +@@ -628,7 +661,9 @@ grub_cmd_nslookup (struct grub_command *cmd __attribute__ ((unused)), + grub_printf ("%s\n", buf); + } + grub_free (addresses); +- return GRUB_ERR_NONE; ++ if (naddresses) ++ return GRUB_ERR_NONE; ++ return grub_error (GRUB_ERR_NET_NO_DOMAIN, N_("no DNS record found")); + } + + static grub_err_t +diff --git a/include/grub/net.h b/include/grub/net.h +index 1bd7af2..e677246 100644 +--- a/include/grub/net.h ++++ b/include/grub/net.h +@@ -506,6 +506,15 @@ grub_err_t + grub_net_link_layer_resolve (struct grub_net_network_level_interface *inf, + const grub_net_network_level_address_t *proto_addr, + grub_net_link_level_address_t *hw_addr); ++ ++typedef enum ++ { ++ DNS_OPTION_IPV4, ++ DNS_OPTION_IPV6, ++ DNS_OPTION_PREFER_IPV4, ++ DNS_OPTION_PREFER_IPV6 ++ } grub_dns_option_t; ++ + grub_err_t + grub_net_dns_lookup (const char *name, + const struct grub_net_network_level_address *servers, +-- +1.8.1.4 + diff --git a/0354-IBM-client-architecture-CAS-reboot-support.patch b/0354-IBM-client-architecture-CAS-reboot-support.patch new file mode 100644 index 0000000..bdb73df --- /dev/null +++ b/0354-IBM-client-architecture-CAS-reboot-support.patch @@ -0,0 +1,175 @@ +From 057b6211bfba83caa9af3276fbbf8902cd1082a2 Mon Sep 17 00:00:00 2001 +From: Paulo Flabiano Smorigo +Date: Thu, 20 Sep 2012 18:07:39 -0300 +Subject: [PATCH 354/364] IBM client architecture (CAS) reboot support + +This is an implementation of IBM client architecture (CAS) reboot for GRUB. + +There are cases where the POWER firmware must reboot in order to support +specific features requested by a kernel. The kernel calls +ibm,client-architecture-support and it may either return or reboot with the new +feature set. eg: + +Calling ibm,client-architecture-support.../ +Elapsed time since release of system processors: 70959 mins 50 secs +Welcome to GRUB! + +Instead of return to the GRUB menu, it will check if the flag for CAS reboot is +set. If so, grub will automatically boot the last booted kernel using the same +parameters +--- + grub-core/kern/ieee1275/openfw.c | 63 ++++++++++++++++++++++++++++++++++++++++ + grub-core/normal/main.c | 19 ++++++++++++ + grub-core/script/execute.c | 7 +++++ + include/grub/ieee1275/ieee1275.h | 2 ++ + 4 files changed, 91 insertions(+) + +diff --git a/grub-core/kern/ieee1275/openfw.c b/grub-core/kern/ieee1275/openfw.c +index 07c90f7..09e9e57 100644 +--- a/grub-core/kern/ieee1275/openfw.c ++++ b/grub-core/kern/ieee1275/openfw.c +@@ -561,3 +561,66 @@ grub_ieee1275_canonicalise_devname (const char *path) + return NULL; + } + ++/* Check if it's a CAS reboot. If so, set the script to be executed. */ ++int ++grub_ieee1275_cas_reboot (char *script) ++{ ++ grub_uint32_t ibm_ca_support_reboot; ++ grub_uint32_t ibm_fw_nbr_reboots; ++ char property_value[10]; ++ grub_ssize_t actual; ++ grub_ieee1275_ihandle_t options; ++ ++ if (grub_ieee1275_finddevice ("/options", &options) < 0) ++ return -1; ++ ++ /* Check two properties, one is enough to get cas reboot value */ ++ ibm_ca_support_reboot = 0; ++ if (grub_ieee1275_get_integer_property (grub_ieee1275_chosen, ++ "ibm,client-architecture-support-reboot", ++ &ibm_ca_support_reboot, ++ sizeof (ibm_ca_support_reboot), ++ &actual) >= 0) ++ grub_dprintf("ieee1275", "ibm,client-architecture-support-reboot: %u\n", ++ ibm_ca_support_reboot); ++ ++ ibm_fw_nbr_reboots = 0; ++ if (grub_ieee1275_get_property (options, "ibm,fw-nbr-reboots", ++ property_value, sizeof (property_value), ++ &actual) >= 0) ++ { ++ property_value[sizeof (property_value) - 1] = 0; ++ ibm_fw_nbr_reboots = (grub_uint8_t) grub_strtoul (property_value, 0, 10); ++ grub_dprintf("ieee1275", "ibm,fw-nbr-reboots: %u\n", ibm_fw_nbr_reboots); ++ } ++ ++ if (ibm_ca_support_reboot || ibm_fw_nbr_reboots) ++ { ++ if (! grub_ieee1275_get_property_length (options, "boot-last-label", &actual)) ++ { ++ if (actual > 1024) ++ script = grub_realloc (script, actual + 1); ++ grub_ieee1275_get_property (options, "boot-last-label", script, actual, ++ &actual); ++ return 0; ++ } ++ } ++ ++ grub_ieee1275_set_boot_last_label (""); ++ ++ return -1; ++} ++ ++int grub_ieee1275_set_boot_last_label (const char *text) ++{ ++ grub_ieee1275_ihandle_t options; ++ grub_ssize_t actual; ++ ++ grub_dprintf("ieee1275", "set boot_last_label (size: %u)\n", grub_strlen(text)); ++ if (! grub_ieee1275_finddevice ("/options", &options) && ++ options != (grub_ieee1275_ihandle_t) -1) ++ grub_ieee1275_set_property (options, "boot-last-label", text, ++ grub_strlen (text), &actual); ++ return 0; ++} ++ +diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c +index ea8cd53..1f14826 100644 +--- a/grub-core/normal/main.c ++++ b/grub-core/normal/main.c +@@ -32,6 +32,9 @@ + #include + #include + #include ++#ifdef GRUB_MACHINE_IEEE1275 ++#include ++#endif + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -302,6 +305,22 @@ grub_normal_execute (const char *config, int nested, int batch) + { + menu = read_config_file (config); + ++#ifdef GRUB_MACHINE_IEEE1275 ++ int boot; ++ boot = 0; ++ char *script; ++ script = grub_malloc (1024); ++ if (! grub_ieee1275_cas_reboot (script)) ++ { ++ char *dummy[1] = { NULL }; ++ if (! grub_script_execute_sourcecode (script, 0, dummy)) ++ boot = 1; ++ } ++ grub_free (script); ++ if (boot) ++ grub_command_execute ("boot", 0, 0); ++#endif ++ + /* Ignore any error. */ + grub_errno = GRUB_ERR_NONE; + } +diff --git a/grub-core/script/execute.c b/grub-core/script/execute.c +index 686e1fa..7dcdab7 100644 +--- a/grub-core/script/execute.c ++++ b/grub-core/script/execute.c +@@ -27,6 +27,9 @@ + #include + #include + #include ++#ifdef GRUB_MACHINE_IEEE1275 ++#include ++#endif + + /* 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. */ +@@ -872,6 +875,10 @@ grub_script_execute_sourcecode (const char *source, int argc, char **args) + old_scope = scope; + scope = &new_scope; + ++#ifdef GRUB_MACHINE_IEEE1275 ++ grub_ieee1275_set_boot_last_label (source); ++#endif ++ + while (source) + { + char *line; +diff --git a/include/grub/ieee1275/ieee1275.h b/include/grub/ieee1275/ieee1275.h +index 1b240d3..eabbe9b 100644 +--- a/include/grub/ieee1275/ieee1275.h ++++ b/include/grub/ieee1275/ieee1275.h +@@ -227,6 +227,8 @@ int EXPORT_FUNC(grub_ieee1275_devalias_next) (struct grub_ieee1275_devalias *ali + void EXPORT_FUNC(grub_ieee1275_children_peer) (struct grub_ieee1275_devalias *alias); + void EXPORT_FUNC(grub_ieee1275_children_first) (const char *devpath, + struct grub_ieee1275_devalias *alias); ++int EXPORT_FUNC(grub_ieee1275_cas_reboot) (char *script); ++int EXPORT_FUNC(grub_ieee1275_set_boot_last_label) (const char *text); + + #define FOR_IEEE1275_DEVALIASES(alias) for (grub_ieee1275_devalias_init_iterator (&(alias)); grub_ieee1275_devalias_next (&(alias));) + +-- +1.8.1.4 + diff --git a/0355-for-ppc-include-all-modules-in-the-core-image.patch b/0355-for-ppc-include-all-modules-in-the-core-image.patch new file mode 100644 index 0000000..f08695d --- /dev/null +++ b/0355-for-ppc-include-all-modules-in-the-core-image.patch @@ -0,0 +1,332 @@ +From 3c4e4115b161354823e6b6a6f6c9da2fa3f3962c Mon Sep 17 00:00:00 2001 +From: Paulo Flabiano Smorigo +Date: Mon, 15 Oct 2012 17:21:01 -0300 +Subject: [PATCH 355/364] for ppc, include all modules in the core image + +This patch implements the solution suggested by Gustavo Luiz Duarte +: + +Adding more modules to be built-in to the grub core ELF is easy. It is a +parameter passed by grub2-install to grub2-mkimage. However, there is a downside +on adding many modules to the core ELF: they are fully initialized in the grub's +first stage. It means you could hit a bug on a module you don't need and end up +with a non-bootable system. + +Another downside is that you wouldn't get updates for these built-in modules, as +updating the grub2 package only updates the modules residing in /boot and not +the grub core ELF in the PReP partition. + +A proper solution would be to add to grub the ability of having built-in +*inactive* modules which would be loaded and initialized only on demand (i.e. +explicitly calling the insmod command). + +This patch fix this bugzilla: +https://bugzilla.redhat.com/show_bug.cgi?id=866559 +--- + grub-core/kern/corecmd.c | 3 ++ + grub-core/kern/dl.c | 67 ++++++++++++++++++++++++++++++++++++++++++--- + include/grub/dl.h | 1 + + include/grub/kernel.h | 1 + + include/grub/util/resolve.h | 5 ++++ + util/grub-mkimage.c | 37 ++++++++++++++++++++++++- + util/resolve.c | 57 ++++++++++++++++++++++++++++++++++++++ + 7 files changed, 166 insertions(+), 5 deletions(-) + +diff --git a/grub-core/kern/corecmd.c b/grub-core/kern/corecmd.c +index cfab676..a4465eb 100644 +--- a/grub-core/kern/corecmd.c ++++ b/grub-core/kern/corecmd.c +@@ -83,6 +83,9 @@ grub_core_cmd_insmod (struct grub_command *cmd __attribute__ ((unused)), + else + mod = grub_dl_load (argv[0]); + ++ if (!mod) ++ grub_dl_load_core_by_name (argv[0]); ++ + if (mod) + grub_dl_ref (mod); + +diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c +index 570be12..fe46aa4 100644 +--- a/grub-core/kern/dl.c ++++ b/grub-core/kern/dl.c +@@ -32,6 +32,7 @@ + #include + #include + #include ++#include + + /* Platforms where modules are in a readonly area of memory. */ + #if defined(GRUB_MACHINE_QEMU) +@@ -51,6 +52,7 @@ + #pragma GCC diagnostic ignored "-Wcast-align" + + grub_dl_t grub_dl_head = 0; ++char grub_use_stale_modules = 0; + + grub_err_t + grub_dl_add (grub_dl_t mod); +@@ -668,6 +670,57 @@ grub_dl_load_core (void *addr, grub_size_t size) + return mod; + } + ++/* Load a module from core using a symbolic name. */ ++grub_dl_t ++grub_dl_load_core_by_name (const char *name) ++{ ++ struct grub_module_header *header; ++ grub_dl_t mod; ++ char *module_addr; ++ ++ mod = (grub_dl_t) grub_zalloc (sizeof (*mod)); ++ if (! mod) ++ return 0; ++ ++ grub_use_stale_modules = 1; ++ ++ FOR_MODULES (header) ++ { ++ /* Not an ELF module, skip. */ ++ if ((header->type != OBJ_TYPE_ELF) && ++ (header->type != OBJ_TYPE_ELF_STALE)) ++ continue; ++ ++ module_addr = (char *) header + sizeof (struct grub_module_header); ++ grub_dl_resolve_name (mod, (Elf_Ehdr *) module_addr); ++ ++ if (grub_strcmp(name, mod->name) == 0) ++ { ++ grub_printf ("WARNING: You are using the built-in '%s' module!\n", name); ++ ++ mod = grub_dl_load_core ((char *) header + sizeof (struct grub_module_header), ++ (header->size - sizeof (struct grub_module_header))); ++ ++ break; ++ } ++ else ++ mod = 0; ++ } ++ ++ if (! mod) ++ return 0; ++ else ++ { ++ if (grub_errno == GRUB_ERR_IO) ++ grub_errno = GRUB_ERR_NONE; ++ } ++ ++ if (grub_strcmp (mod->name, name) != 0) ++ grub_error (GRUB_ERR_BAD_MODULE, "mismatched names"); ++ ++ return mod; ++} ++ + /* Load a module from the file FILENAME. */ + grub_dl_t + grub_dl_load_file (const char *filename) +@@ -740,13 +793,19 @@ grub_dl_load (const char *name) + return 0; + } + ++ /* First, try to load module from the grub directory */ + filename = grub_xasprintf ("%s/" GRUB_TARGET_CPU "-" GRUB_PLATFORM "/%s.mod", + grub_dl_dir, name); +- if (! filename) +- return 0; ++ if (filename) ++ { ++ mod = grub_dl_load_file (filename); ++ grub_free (filename); ++ } + +- mod = grub_dl_load_file (filename); +- grub_free (filename); ++ /* If the module isn't loaded, check if there is a stale module available and ++ * use it*/ ++ if (! mod && grub_use_stale_modules) ++ mod = grub_dl_load_core_by_name (name); + + if (! mod) + return 0; +diff --git a/include/grub/dl.h b/include/grub/dl.h +index 3119978..30f12f9 100644 +--- a/include/grub/dl.h ++++ b/include/grub/dl.h +@@ -181,6 +181,7 @@ typedef struct grub_dl *grub_dl_t; + grub_dl_t grub_dl_load_file (const char *filename); + grub_dl_t EXPORT_FUNC(grub_dl_load) (const char *name); + grub_dl_t grub_dl_load_core (void *addr, grub_size_t size); ++grub_dl_t grub_dl_load_core_by_name (const char *name); + int EXPORT_FUNC(grub_dl_unload) (grub_dl_t mod); + void grub_dl_unload_unneeded (void); + int EXPORT_FUNC(grub_dl_ref) (grub_dl_t mod); +diff --git a/include/grub/kernel.h b/include/grub/kernel.h +index 73ea416..e837b1f 100644 +--- a/include/grub/kernel.h ++++ b/include/grub/kernel.h +@@ -25,6 +25,7 @@ + enum + { + OBJ_TYPE_ELF, ++ OBJ_TYPE_ELF_STALE, + OBJ_TYPE_MEMDISK, + OBJ_TYPE_CONFIG, + OBJ_TYPE_PREFIX, +diff --git a/include/grub/util/resolve.h b/include/grub/util/resolve.h +index f42df32..1d0252c 100644 +--- a/include/grub/util/resolve.h ++++ b/include/grub/util/resolve.h +@@ -32,4 +32,9 @@ grub_util_resolve_dependencies (const char *prefix, + const char *dep_list_file, + char *modules[]); + ++struct grub_util_path_list * ++grub_util_create_complementary_module_list (const char *prefix, ++ const char *dep_list_file, ++ struct grub_util_path_list *path_list); ++ + #endif /* ! GRUB_UTIL_RESOLVE_HEADER */ +diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c +index 41f795a..fa601ec 100644 +--- a/util/grub-mkimage.c ++++ b/util/grub-mkimage.c +@@ -729,7 +729,7 @@ generate_image (const char *dir, const char *prefix, + size_t prefix_size = 0; + char *kernel_path; + size_t offset; +- struct grub_util_path_list *path_list, *p, *next; ++ struct grub_util_path_list *path_list, *path_list_comp = 0, *p, *next; + grub_size_t bss_size; + grub_uint64_t start_address; + void *rel_section = 0; +@@ -745,6 +745,10 @@ generate_image (const char *dir, const char *prefix, + + path_list = grub_util_resolve_dependencies (dir, "moddep.lst", mods); + ++ if (image_target->id == IMAGE_PPC) ++ path_list_comp = grub_util_create_complementary_module_list (dir, ++ "moddep.lst", path_list); ++ + kernel_path = grub_util_get_path (dir, "kernel.img"); + + if (image_target->voidp_sizeof == 8) +@@ -791,6 +795,10 @@ generate_image (const char *dir, const char *prefix, + total_module_size += (ALIGN_ADDR (grub_util_get_image_size (p->name)) + + sizeof (struct grub_module_header)); + ++ for (p = path_list_comp; p; p = p->next) ++ 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%llx", + (unsigned long long) total_module_size); + +@@ -865,6 +873,25 @@ generate_image (const char *dir, const char *prefix, + offset += mod_size; + } + ++ for (p = path_list_comp; p; p = p->next) ++ { ++ struct grub_module_header *header; ++ size_t mod_size, orig_size; ++ ++ orig_size = grub_util_get_image_size (p->name); ++ mod_size = ALIGN_ADDR (orig_size); ++ ++ header = (struct grub_module_header *) (kernel_img + offset); ++ memset (header, 0, sizeof (struct grub_module_header)); ++ header->type = grub_host_to_target32 (OBJ_TYPE_ELF_STALE); ++ 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; ++ } ++ + { + size_t i; + for (i = 0; i < npubkeys; i++) +@@ -1714,6 +1741,14 @@ generate_image (const char *dir, const char *prefix, + free (path_list); + path_list = next; + } ++ ++ while (path_list_comp) ++ { ++ next = path_list_comp->next; ++ free ((void *) path_list_comp->name); ++ free (path_list_comp); ++ path_list_comp = next; ++ } + } + + +diff --git a/util/resolve.c b/util/resolve.c +index 1af24e6..997db99 100644 +--- a/util/resolve.c ++++ b/util/resolve.c +@@ -271,3 +271,60 @@ grub_util_resolve_dependencies (const char *prefix, + return prev; + } + } ++ ++struct grub_util_path_list * ++grub_util_create_complementary_module_list (const char *prefix, ++ const char *dep_list_file, ++ struct grub_util_path_list *path_list) ++{ ++ char *path; ++ FILE *fp; ++ struct grub_util_path_list *path_list_comp = 0; ++ struct grub_util_path_list *new_path; ++ char skip; ++ ++ path = grub_util_get_path (prefix, dep_list_file); ++ fp = fopen (path, "r"); ++ if (! fp) ++ grub_util_error (_("cannot open `%s': %s"), path, strerror (errno)); ++ ++ while (fgets (buf, sizeof (buf), fp)) ++ { ++ char *p; ++ struct grub_util_path_list *pl; ++ ++ skip = 0; ++ ++ /* Get the target name. */ ++ p = strchr (buf, ':'); ++ if (! p) ++ grub_util_error (_("invalid line format: %s"), buf); ++ ++ *p++ = '\0'; ++ ++ /* kernel is not a module */ ++ if (strcmp(buf, "kernel") == 0) ++ continue; ++ ++ /* Check if the module is already in the core. */ ++ for (pl = path_list; pl; pl = pl->next) ++ { ++ if (strcmp(buf, get_module_name(pl->name)) == 0) ++ { ++ skip = 1; ++ break; ++ } ++ } ++ ++ if (skip) ++ continue; ++ ++ /* Add the new path. */ ++ new_path = (struct grub_util_path_list *) xmalloc (sizeof (*new_path)); ++ new_path->name = get_module_path (prefix, buf); ++ new_path->next = path_list_comp; ++ path_list_comp = new_path; ++ } ++ ++ return path_list_comp; ++} +-- +1.8.1.4 + diff --git a/0356-Add-vlan-tag-support.patch b/0356-Add-vlan-tag-support.patch new file mode 100644 index 0000000..b9dc8cd --- /dev/null +++ b/0356-Add-vlan-tag-support.patch @@ -0,0 +1,186 @@ +From d898f409ae3c0d09ec244f2a113c67ca8b4b8079 Mon Sep 17 00:00:00 2001 +From: Paulo Flabiano Smorigo +Date: Tue, 30 Oct 2012 15:19:39 -0200 +Subject: [PATCH 356/364] Add vlan-tag support + +This patch adds support for virtual LAN (VLAN) tagging. VLAN tagging allows +multiple VLANs in a bridged network to share the same physical network link but +maintain isolation: + +http://en.wikipedia.org/wiki/IEEE_802.1Q + +This patch should fix this bugzilla: +https://bugzilla.redhat.com/show_bug.cgi?id=871563 +--- + grub-core/kern/ieee1275/init.c | 1 + + grub-core/kern/ieee1275/openfw.c | 30 ++++++++++++++++++++++++++++ + grub-core/net/ethernet.c | 42 +++++++++++++++++++++++++++++++++++++--- + include/grub/ieee1275/ieee1275.h | 1 + + include/grub/net.h | 2 ++ + 5 files changed, 73 insertions(+), 3 deletions(-) + +diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c +index ce8eadb..3af15d8 100644 +--- a/grub-core/kern/ieee1275/init.c ++++ b/grub-core/kern/ieee1275/init.c +@@ -117,6 +117,7 @@ grub_machine_get_bootlocation (char **device, char **path) + char *dev, *canon; + char *ptr; + dev = grub_ieee1275_get_aliasdevname (bootpath); ++ grub_ieee1275_parse_net_options (bootpath); + canon = grub_ieee1275_canonicalise_devname (dev); + ptr = canon + grub_strlen (canon) - 1; + while (ptr > canon && (*ptr == ',' || *ptr == ':')) +diff --git a/grub-core/kern/ieee1275/openfw.c b/grub-core/kern/ieee1275/openfw.c +index 09e9e57..2a01146 100644 +--- a/grub-core/kern/ieee1275/openfw.c ++++ b/grub-core/kern/ieee1275/openfw.c +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include + + enum grub_ieee1275_parse_type + { +@@ -451,6 +452,35 @@ fail: + return ret; + } + ++int ++grub_ieee1275_parse_net_options (const char *path) ++{ ++ char *comma; ++ char *args; ++ char *option = 0; ++ ++ args = grub_ieee1275_get_devargs (path); ++ if (!args) ++ /* There is no option. */ ++ return -1; ++ ++ do ++ { ++ comma = grub_strchr (args, ','); ++ if (! comma) ++ option = grub_strdup (args); ++ else ++ option = grub_strndup (args, (grub_size_t)(comma - args)); ++ args = comma + 1; ++ ++ if (! grub_strncmp(option, "vtag", 4)) ++ grub_env_set ("vlan-tag", option + grub_strlen("vtag=")); ++ ++ } while (comma); ++ ++ return 0; ++} ++ + char * + grub_ieee1275_get_device_type (const char *path) + { +diff --git a/grub-core/net/ethernet.c b/grub-core/net/ethernet.c +index b38e2c8..5e45d46 100644 +--- a/grub-core/net/ethernet.c ++++ b/grub-core/net/ethernet.c +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -56,10 +57,19 @@ send_ethernet_packet (struct grub_net_network_level_interface *inf, + { + struct etherhdr *eth; + grub_err_t err; ++ grub_uint32_t vlantag = 0; ++ grub_uint8_t etherhdr_size; + +- COMPILE_TIME_ASSERT (sizeof (*eth) < GRUB_NET_MAX_LINK_HEADER_SIZE); ++ etherhdr_size = sizeof (*eth); ++ COMPILE_TIME_ASSERT (sizeof (*eth) + 4 < GRUB_NET_MAX_LINK_HEADER_SIZE); + +- err = grub_netbuff_push (nb, sizeof (*eth)); ++ const char *vlantag_text = grub_env_get ("vlan-tag"); ++ if (vlantag_text != 0) { ++ etherhdr_size += 4; ++ vlantag = grub_strtoul (vlantag_text, 0, 16); ++ } ++ ++ err = grub_netbuff_push (nb, etherhdr_size); + if (err) + return err; + eth = (struct etherhdr *) nb->data; +@@ -76,6 +86,19 @@ send_ethernet_packet (struct grub_net_network_level_interface *inf, + return err; + inf->card->opened = 1; + } ++ ++ /* Check if a vlan-tag is needed. */ ++ if (vlantag != 0) ++ { ++ /* Move eth type to the right */ ++ grub_memcpy((char *) nb->data + etherhdr_size - 2, ++ (char *) nb->data + etherhdr_size - 6, 2); ++ ++ /* Add the tag in the middle */ ++ grub_memcpy((char *) nb->data + etherhdr_size - 6, ++ &vlantag, 4); ++ } ++ + return inf->card->driver->send (inf->card, nb); + } + +@@ -90,10 +113,23 @@ grub_net_recv_ethernet_packet (struct grub_net_buff *nb, + grub_net_link_level_address_t hwaddress; + grub_net_link_level_address_t src_hwaddress; + grub_err_t err; ++ grub_uint8_t etherhdr_size = sizeof (*eth); ++ ++ grub_uint16_t vlantag_identifier = 0; ++ grub_memcpy (&vlantag_identifier, nb->data + etherhdr_size - 2, 2); ++ ++ /* Check if a vlan-tag is present. */ ++ if (vlantag_identifier == VLANTAG_IDENTIFIER) ++ { ++ etherhdr_size += 4; ++ /* Move eth type to the original position */ ++ grub_memcpy((char *) nb->data + etherhdr_size - 6, ++ (char *) nb->data + etherhdr_size - 2, 2); ++ } + + eth = (struct etherhdr *) nb->data; + type = grub_be_to_cpu16 (eth->type); +- err = grub_netbuff_pull (nb, sizeof (*eth)); ++ err = grub_netbuff_pull (nb, etherhdr_size); + if (err) + return err; + +diff --git a/include/grub/ieee1275/ieee1275.h b/include/grub/ieee1275/ieee1275.h +index eabbe9b..61d5769 100644 +--- a/include/grub/ieee1275/ieee1275.h ++++ b/include/grub/ieee1275/ieee1275.h +@@ -229,6 +229,7 @@ void EXPORT_FUNC(grub_ieee1275_children_first) (const char *devpath, + struct grub_ieee1275_devalias *alias); + int EXPORT_FUNC(grub_ieee1275_cas_reboot) (char *script); + int EXPORT_FUNC(grub_ieee1275_set_boot_last_label) (const char *text); ++int EXPORT_FUNC(grub_ieee1275_parse_net_options) (const char *path); + + #define FOR_IEEE1275_DEVALIASES(alias) for (grub_ieee1275_devalias_init_iterator (&(alias)); grub_ieee1275_devalias_next (&(alias));) + +diff --git a/include/grub/net.h b/include/grub/net.h +index e677246..fe29b16 100644 +--- a/include/grub/net.h ++++ b/include/grub/net.h +@@ -533,4 +533,6 @@ extern char *grub_net_default_server; + #define GRUB_NET_TRIES 40 + #define GRUB_NET_INTERVAL 400 + ++#define VLANTAG_IDENTIFIER 0x8100 ++ + #endif /* ! GRUB_NET_HEADER */ +-- +1.8.1.4 + diff --git a/0357-Add-X-option-to-printf-functions.patch b/0357-Add-X-option-to-printf-functions.patch new file mode 100644 index 0000000..68c9afb --- /dev/null +++ b/0357-Add-X-option-to-printf-functions.patch @@ -0,0 +1,58 @@ +From f1673a4b7079d134fa966da37adf409ea42efe8c Mon Sep 17 00:00:00 2001 +From: Paulo Flabiano Smorigo +Date: Tue, 27 Nov 2012 16:58:39 -0200 +Subject: [PATCH 357/364] Add %X option to printf functions. + +--- + grub-core/kern/misc.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c +index 94b88a3..d5ca312 100644 +--- a/grub-core/kern/misc.c ++++ b/grub-core/kern/misc.c +@@ -596,7 +596,7 @@ grub_divmod64 (grub_uint64_t n, grub_uint64_t d, grub_uint64_t *r) + static char * + grub_lltoa (char *str, int c, unsigned long long n) + { +- unsigned base = (c == 'x') ? 16 : 10; ++ unsigned base = ((c == 'x') || (c == 'X')) ? 16 : 10; + char *p; + + if ((long long) n < 0 && c == 'd') +@@ -611,7 +611,7 @@ grub_lltoa (char *str, int c, unsigned long long n) + do + { + unsigned d = (unsigned) (n & 0xf); +- *p++ = (d > 9) ? d + 'a' - 10 : d + '0'; ++ *p++ = (d > 9) ? d + ((c == 'x') ? 'a' : 'A') - 10 : d + '0'; + } + while (n >>= 4); + else +@@ -702,6 +702,7 @@ grub_vsnprintf_real (char *str, grub_size_t max_len, const char *fmt0, va_list a + { + case 'p': + case 'x': ++ case 'X': + case 'u': + case 'd': + case 'c': +@@ -780,6 +781,7 @@ grub_vsnprintf_real (char *str, grub_size_t max_len, const char *fmt0, va_list a + switch (c) + { + case 'x': ++ case 'X': + case 'u': + case 'd': + if (longlongfmt) +@@ -921,6 +923,7 @@ grub_vsnprintf_real (char *str, grub_size_t max_len, const char *fmt0, va_list a + longlongfmt |= (sizeof (void *) == sizeof (long long)); + /* Fall through. */ + case 'x': ++ case 'X': + case 'u': + unsig = 1; + /* Fall through. */ +-- +1.8.1.4 + diff --git a/0358-DHCP-client-ID-and-UUID-options-added.patch b/0358-DHCP-client-ID-and-UUID-options-added.patch new file mode 100644 index 0000000..b463d62 --- /dev/null +++ b/0358-DHCP-client-ID-and-UUID-options-added.patch @@ -0,0 +1,110 @@ +From 555f1022f967f98c541617df6b34ca272504d97b Mon Sep 17 00:00:00 2001 +From: Paulo Flabiano Smorigo +Date: Tue, 27 Nov 2012 17:18:53 -0200 +Subject: [PATCH 358/364] DHCP client ID and UUID options added. + +--- + grub-core/net/bootp.c | 52 +++++++++++++++++++++++++++++++++++++++++++-------- + include/grub/net.h | 2 ++ + 2 files changed, 46 insertions(+), 8 deletions(-) + +diff --git a/grub-core/net/bootp.c b/grub-core/net/bootp.c +index 33f860a..de34966 100644 +--- a/grub-core/net/bootp.c ++++ b/grub-core/net/bootp.c +@@ -51,6 +51,14 @@ set_env_limn_ro (const char *intername, const char *suffix, + grub_register_variable_hook (varname, 0, grub_env_write_readonly); + } + ++static char ++hexdigit (grub_uint8_t val) ++{ ++ if (val < 10) ++ return val + '0'; ++ return val + 'a' - 10; ++} ++ + static void + parse_dhcp_vendor (const char *name, void *vend, int limit, int *mask) + { +@@ -81,6 +89,9 @@ parse_dhcp_vendor (const char *name, void *vend, int limit, int *mask) + + taglength = *ptr++; + ++ grub_dprintf("net", "DHCP option %u (0x%02x) found with length %u.\n", ++ tagtype, tagtype, taglength); ++ + switch (tagtype) + { + case GRUB_NET_BOOTP_NETMASK: +@@ -139,6 +150,39 @@ parse_dhcp_vendor (const char *name, void *vend, int limit, int *mask) + set_env_limn_ro (name, "extensionspath", (char *) ptr, taglength); + break; + ++ case GRUB_NET_BOOTP_CLIENT_ID: ++ set_env_limn_ro (name, "clientid", (char *) ptr, taglength); ++ break; ++ ++ case GRUB_NET_BOOTP_CLIENT_UUID: ++ { ++ if (taglength != 17) ++ break; ++ ++ /* The format is 9cfe245e-d0c8-bd45-a79f-54ea5fbd3d97 */ ++ ++ ptr += 1; ++ taglength -= 1; ++ ++ char *val = grub_malloc (2 * taglength + 4 + 1); ++ int i = 0; ++ int j = 0; ++ for (i = 0; i < taglength; i++) ++ { ++ val[2 * i + j] = hexdigit (ptr[i] >> 4); ++ val[2 * i + 1 + j] = hexdigit (ptr[i] & 0xf); ++ ++ if ((i == 3) || (i == 5) || (i == 7) || (i == 9)) ++ { ++ j++; ++ val[2 * i + 1+ j] = '-'; ++ } ++ } ++ ++ set_env_limn_ro (name, "clientuuid", (char *) val, 2 * taglength + 4); ++ } ++ break; ++ + /* If you need any other options please contact GRUB + development team. */ + } +@@ -299,14 +343,6 @@ grub_net_process_dhcp (struct grub_net_buff *nb, + } + } + +-static char +-hexdigit (grub_uint8_t val) +-{ +- if (val < 10) +- return val + '0'; +- return val + 'a' - 10; +-} +- + static grub_err_t + grub_cmd_dhcpopt (struct grub_command *cmd __attribute__ ((unused)), + int argc, char **args) +diff --git a/include/grub/net.h b/include/grub/net.h +index fe29b16..36ac906 100644 +--- a/include/grub/net.h ++++ b/include/grub/net.h +@@ -424,6 +424,8 @@ enum + GRUB_NET_BOOTP_DOMAIN = 0x0f, + GRUB_NET_BOOTP_ROOT_PATH = 0x11, + GRUB_NET_BOOTP_EXTENSIONS_PATH = 0x12, ++ GRUB_NET_BOOTP_CLIENT_ID = 0x3d, ++ GRUB_NET_BOOTP_CLIENT_UUID = 0x61, + GRUB_NET_BOOTP_END = 0xff + }; + +-- +1.8.1.4 + diff --git a/0359-Search-for-specific-config-file-for-netboot.patch b/0359-Search-for-specific-config-file-for-netboot.patch new file mode 100644 index 0000000..6d44326 --- /dev/null +++ b/0359-Search-for-specific-config-file-for-netboot.patch @@ -0,0 +1,203 @@ +From 773d8cadb15a4bea164863268068e2f421b8324c Mon Sep 17 00:00:00 2001 +From: Paulo Flabiano Smorigo +Date: Tue, 27 Nov 2012 17:22:07 -0200 +Subject: [PATCH 359/364] Search for specific config file for netboot + +This patch implements a search for a specific configuration when the config +file is on a remoteserver. It uses the following order: + 1) DHCP client UUID option. + 2) MAC address (in lower case hexadecimal with dash separators); + 3) IP (in upper case hexadecimal) or IPv6; + 4) The original grub.cfg file. + +This procedure is similar to what is used by pxelinux and yaboot: +http://www.syslinux.org/wiki/index.php/PXELINUX#config + +This should close the bugzilla: +https://bugzilla.redhat.com/show_bug.cgi?id=873406 +--- + grub-core/net/net.c | 118 ++++++++++++++++++++++++++++++++++++++++++++++++ + grub-core/normal/main.c | 18 ++++++-- + include/grub/net.h | 3 ++ + 3 files changed, 135 insertions(+), 4 deletions(-) + +diff --git a/grub-core/net/net.c b/grub-core/net/net.c +index aebbe4b..9a601d7 100644 +--- a/grub-core/net/net.c ++++ b/grub-core/net/net.c +@@ -1548,6 +1548,124 @@ grub_net_restore_hw (void) + return GRUB_ERR_NONE; + } + ++grub_err_t ++grub_net_search_configfile (char *config) ++{ ++ grub_size_t config_len; ++ char *suffix; ++ ++ auto int search_through (grub_size_t num_tries, grub_size_t slice_size); ++ int search_through (grub_size_t num_tries, grub_size_t slice_size) ++ { ++ while (num_tries-- > 0) ++ { ++ grub_dprintf ("net", "probe %s\n", config); ++ ++ grub_file_t file; ++ file = grub_file_open (config); ++ ++ if (file) ++ { ++ grub_file_close (file); ++ grub_dprintf ("net", "found!\n"); ++ return 0; ++ } ++ else ++ { ++ if (grub_errno == GRUB_ERR_IO) ++ grub_errno = GRUB_ERR_NONE; ++ } ++ ++ if (grub_strlen (suffix) < slice_size) ++ break; ++ ++ config[grub_strlen (config) - slice_size] = '\0'; ++ } ++ ++ return 1; ++ } ++ ++ config_len = grub_strlen (config); ++ config[config_len] = '-'; ++ suffix = config + config_len + 1; ++ ++ struct grub_net_network_level_interface *inf; ++ FOR_NET_NETWORK_LEVEL_INTERFACES (inf) ++ { ++ /* By the Client UUID. */ ++ ++ char client_uuid_var[sizeof ("net_") + grub_strlen (inf->name) + ++ sizeof ("_clientuuid") + 1]; ++ grub_snprintf (client_uuid_var, sizeof (client_uuid_var), ++ "net_%s_clientuuid", inf->name); ++ ++ const char *client_uuid; ++ client_uuid = grub_env_get (client_uuid_var); ++ ++ if (client_uuid) ++ { ++ grub_strcpy (suffix, client_uuid); ++ if (search_through (1, 0) == 0) return GRUB_ERR_NONE; ++ } ++ ++ /* By the MAC address. */ ++ ++ /* Add ethernet type */ ++ grub_strcpy (suffix, "01-"); ++ ++ grub_net_hwaddr_to_str (&inf->hwaddress, suffix + 3); ++ ++ char *ptr; ++ for (ptr = suffix; *ptr; ptr++) ++ if (*ptr == ':') ++ *ptr = '-'; ++ ++ if (search_through (1, 0) == 0) return GRUB_ERR_NONE; ++ ++ /* By IP address */ ++ ++ switch ((&inf->address)->type) ++ { ++ case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4: ++ { ++ grub_uint32_t n = grub_be_to_cpu32 ((&inf->address)->ipv4); ++ grub_snprintf (suffix, GRUB_NET_MAX_STR_ADDR_LEN, "%02X%02X%02X%02X", \ ++ ((n >> 24) & 0xff), ((n >> 16) & 0xff), \ ++ ((n >> 8) & 0xff), ((n >> 0) & 0xff)); ++ ++ if (search_through (8, 1) == 0) return GRUB_ERR_NONE; ++ break; ++ } ++ case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6: ++ { ++ char buf[GRUB_NET_MAX_STR_ADDR_LEN]; ++ struct grub_net_network_level_address base; ++ base.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6; ++ grub_memcpy (&base.ipv6, ((&inf->address)->ipv6), 16); ++ grub_net_addr_to_str (&base, buf); ++ ++ for (ptr = buf; *ptr; ptr++) ++ if (*ptr == ':') ++ *ptr = '-'; ++ ++ grub_snprintf (suffix, GRUB_NET_MAX_STR_ADDR_LEN, "%s", buf); ++ if (search_through (1, 0) == 0) return GRUB_ERR_NONE; ++ break; ++ } ++ case GRUB_NET_NETWORK_LEVEL_PROTOCOL_DHCP_RECV: ++ return grub_error (GRUB_ERR_BUG, "shouldn't reach here"); ++ default: ++ return grub_error (GRUB_ERR_BUG, ++ "unsupported address type %d", (&inf->address)->type); ++ } ++ } ++ ++ /* Remove the remaining minus sign at the end. */ ++ config[config_len] = '\0'; ++ ++ return GRUB_ERR_NONE; ++} ++ + static struct grub_preboot *fini_hnd; + + static grub_command_t cmd_addaddr, cmd_deladdr, cmd_addroute, cmd_delroute; +diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c +index 1f14826..b40d987 100644 +--- a/grub-core/normal/main.c ++++ b/grub-core/normal/main.c +@@ -32,6 +32,7 @@ + #include + #include + #include ++#include + #ifdef GRUB_MACHINE_IEEE1275 + #include + #endif +@@ -392,10 +393,19 @@ grub_cmd_normal (struct grub_command *cmd __attribute__ ((unused)), + + prefix = grub_env_get ("prefix"); + if (prefix) +- { +- config = grub_xasprintf ("%s/grub.cfg", prefix); +- if (! config) +- goto quit; ++ { ++ grub_size_t config_len; ++ config_len = grub_strlen (prefix) + ++ sizeof ("/grub.cfg-XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"); ++ config = grub_malloc (config_len); ++ ++ if (! config) ++ goto quit; ++ ++ grub_snprintf (config, config_len, "%s/grub.cfg", prefix); ++ ++ if (grub_strncmp (prefix + 1, "tftp", sizeof ("tftp") - 1) == 0) ++ grub_net_search_configfile (config); + + grub_enter_normal_mode (config); + grub_free (config); +diff --git a/include/grub/net.h b/include/grub/net.h +index 36ac906..c7d5ce0 100644 +--- a/include/grub/net.h ++++ b/include/grub/net.h +@@ -537,4 +537,7 @@ extern char *grub_net_default_server; + + #define VLANTAG_IDENTIFIER 0x8100 + ++grub_err_t ++grub_net_search_configfile (char *config); ++ + #endif /* ! GRUB_NET_HEADER */ +-- +1.8.1.4 + diff --git a/0360-Add-bootpath-device-to-the-list.patch b/0360-Add-bootpath-device-to-the-list.patch new file mode 100644 index 0000000..bef6989 --- /dev/null +++ b/0360-Add-bootpath-device-to-the-list.patch @@ -0,0 +1,64 @@ +From 68cae0b32cf36c7a8ccd0b2344afdb8ad5f9c473 Mon Sep 17 00:00:00 2001 +From: Fedora Ninjas +Date: Fri, 14 Dec 2012 20:10:21 -0200 +Subject: [PATCH 360/364] Add bootpath device to the list + +When scanning the devices, always check (and add) the bootpath device if it +isn't in the device list. +--- + grub-core/disk/ieee1275/ofdisk.c | 32 ++++++++++++++++++++++++++++++++ + 1 file changed, 32 insertions(+) + +diff --git a/grub-core/disk/ieee1275/ofdisk.c b/grub-core/disk/ieee1275/ofdisk.c +index ec92c4d..f056466 100644 +--- a/grub-core/disk/ieee1275/ofdisk.c ++++ b/grub-core/disk/ieee1275/ofdisk.c +@@ -229,6 +229,10 @@ dev_iterate (const struct grub_ieee1275_devalias *alias) + static void + scan (void) + { ++ char *bootpath; ++ int bootpath_size; ++ char *type; ++ + struct grub_ieee1275_devalias alias; + FOR_IEEE1275_DEVALIASES(alias) + { +@@ -239,6 +243,34 @@ scan (void) + + FOR_IEEE1275_DEVCHILDREN("/", alias) + dev_iterate (&alias); ++ ++ if (grub_ieee1275_get_property_length (grub_ieee1275_chosen, "bootpath", ++ &bootpath_size) ++ || bootpath_size <= 0) ++ { ++ /* Should never happen. */ ++ grub_printf ("/chosen/bootpath property missing!\n"); ++ return; ++ } ++ ++ bootpath = (char *) grub_malloc ((grub_size_t) bootpath_size + 64); ++ if (! bootpath) ++ { ++ grub_print_error (); ++ return; ++ } ++ grub_ieee1275_get_property (grub_ieee1275_chosen, "bootpath", bootpath, ++ (grub_size_t) bootpath_size + 1, 0); ++ bootpath[bootpath_size] = '\0'; ++ ++ type = grub_ieee1275_get_device_type (bootpath); ++ if (type && grub_strcmp (type, "block") == 0) ++ dev_iterate_real (bootpath, bootpath); ++ ++ grub_free (bootpath); ++ ++ grub_devalias_iterate (dev_iterate_alias); ++ grub_children_iterate ("/", dev_iterate); + } + + static int +-- +1.8.1.4 + diff --git a/0361-add-GRUB_DISABLE_SUBMENU-option.patch b/0361-add-GRUB_DISABLE_SUBMENU-option.patch new file mode 100644 index 0000000..ff84415 --- /dev/null +++ b/0361-add-GRUB_DISABLE_SUBMENU-option.patch @@ -0,0 +1,78 @@ +From 226913e340f31cb8c2d98d09cb4186f1825cffe5 Mon Sep 17 00:00:00 2001 +From: Prarit Bhargava +Date: Thu, 7 Feb 2013 11:53:41 -0500 +Subject: [PATCH 361/364] add GRUB_DISABLE_SUBMENU option + +This patch adds the ability to disable the grub2 submenus from +/etc/default/grub + +To disable the submenus + +echo 'GRUB_DISABLE_SUBMENU="true"' >> /etc/default/grub +--- + util/grub-mkconfig.in | 3 ++- + util/grub.d/10_linux.in | 24 ++++++++++++++---------- + 2 files changed, 16 insertions(+), 11 deletions(-) + +diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in +index 8decc1d..ea42cab 100644 +--- a/util/grub-mkconfig.in ++++ b/util/grub-mkconfig.in +@@ -215,7 +215,8 @@ export GRUB_DEFAULT \ + GRUB_INIT_TUNE \ + GRUB_SAVEDEFAULT \ + GRUB_ENABLE_CRYPTODISK \ +- GRUB_BADRAM ++ GRUB_BADRAM \ ++ GRUB_DISABLE_SUBMENU + + if test "x${grub_cfg}" != "x"; then + rm -f "${grub_cfg}.new" +diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in +index 4807d84..d7ea670 100644 +--- a/util/grub.d/10_linux.in ++++ b/util/grub.d/10_linux.in +@@ -240,17 +240,19 @@ while [ "x$list" != "x" ] ; do + linux_root_device_thisversion=${GRUB_DEVICE} + fi + +- if [ "x$is_first_entry" = xtrue ]; then +- linux_entry "${OS}" "${version}" simple \ +- "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}" ++ if [ "x${GRUB_DISABLE_SUBMENU}" = x ]; then ++ if [ "x$is_first_entry" = xtrue ]; then ++ linux_entry "${OS}" "${version}" simple \ ++ "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}" + +- submenu_indentation="$grub_tab" ++ submenu_indentation="$grub_tab" + +- if [ -z "$boot_device_id" ]; then +- boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")" ++ if [ -z "$boot_device_id" ]; then ++ boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")" ++ fi ++ # TRANSLATORS: %s is replaced with an OS name ++ echo "submenu '$(gettext_printf "Advanced options for %s" "${OS}" | grub_quote)' \$menuentry_id_option 'gnulinux-advanced-$boot_device_id' {" + fi +- # TRANSLATORS: %s is replaced with an OS name +- echo "submenu '$(gettext_printf "Advanced options for %s" "${OS}" | grub_quote)' \$menuentry_id_option 'gnulinux-advanced-$boot_device_id' {" + fi + + linux_entry "${OS}" "${version}" advanced \ +@@ -266,8 +268,10 @@ done + + # If at least one kernel was found, then we need to + # add a closing '}' for the submenu command. +-if [ x"$is_first_entry" != xtrue ]; then +- echo '}' ++if [ "x${GRUB_DISABLE_SUBMENU}" = x ]; then ++ if [ x"$is_first_entry" != xtrue ]; then ++ echo '}' ++ fi + fi + + echo "$title_correction_code" +-- +1.8.1.4 + diff --git a/0362-blscfg-add-blscfg-module-to-parse-Boot-Loader-Specif.patch b/0362-blscfg-add-blscfg-module-to-parse-Boot-Loader-Specif.patch new file mode 100644 index 0000000..05dbb8a --- /dev/null +++ b/0362-blscfg-add-blscfg-module-to-parse-Boot-Loader-Specif.patch @@ -0,0 +1,251 @@ +From f46a9b399b30b4883cb472f096e9b2d666a29ee5 Mon Sep 17 00:00:00 2001 +From: Fedora Ninjas +Date: Tue, 22 Jan 2013 06:31:38 +0100 +Subject: [PATCH 362/364] blscfg: add blscfg module to parse Boot Loader + Specification snippets + +http://www.freedesktop.org/wiki/Specifications/BootLoaderSpec + +Works like this: + + insmod blscfg + bls_import + +Done! You should now have menu items for your snippets in place. + +Signed-off-by: Peter Jones +--- + grub-core/Makefile.core.def | 8 ++ + grub-core/commands/blscfg.c | 201 ++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 209 insertions(+) + create mode 100644 grub-core/commands/blscfg.c + +diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def +index ca09eed..ef4754f 100644 +--- a/grub-core/Makefile.core.def ++++ b/grub-core/Makefile.core.def +@@ -645,6 +645,14 @@ module = { + }; + + module = { ++ name = blscfg; ++ common = commands/blscfg.c; ++ enable = i386_efi; ++ enable = x86_64_efi; ++ enable = i386_pc; ++}; ++ ++module = { + name = boot; + common = commands/boot.c; + i386_pc = lib/i386/pc/biosnum.c; +diff --git a/grub-core/commands/blscfg.c b/grub-core/commands/blscfg.c +new file mode 100644 +index 0000000..4274aca +--- /dev/null ++++ b/grub-core/commands/blscfg.c +@@ -0,0 +1,201 @@ ++/*-*- Mode: C; c-basic-offset: 2; indent-tabs-mode: t -*-*/ ++ ++/* bls.c - implementation of the boot loader spec */ ++ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * ++ * 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 ++ ++GRUB_MOD_LICENSE ("GPLv3+"); ++ ++#ifdef GRUB_MACHINE_EFI ++#define GRUB_LINUX_CMD "linuxefi" ++#define GRUB_INITRD_CMD "initrdefi" ++#define GRUB_BLS_CONFIG_PATH "/EFI/fedora/loader/entries/" ++#define GRUB_BOOT_DEVICE "($boot)" ++#else ++#define GRUB_LINUX_CMD "linux" ++#define GRUB_INITRD_CMD "initrd" ++#define GRUB_BLS_CONFIG_PATH "/loader/entries/" ++#define GRUB_BOOT_DEVICE "($root)" ++#endif ++ ++static int parse_entry ( ++ const char *filename, ++ const struct grub_dirhook_info *info __attribute__ ((unused)), ++ void *data __attribute__ ((unused))) ++{ ++ grub_size_t n; ++ char *p; ++ grub_file_t f = NULL; ++ grub_off_t sz; ++ char *title = NULL, *options = NULL, *clinux = NULL, *initrd = NULL, *src = NULL; ++ const char *args[2] = { NULL, NULL }; ++ ++ if (filename[0] == '.') ++ return 0; ++ ++ n = grub_strlen (filename); ++ if (n <= 5) ++ return 0; ++ ++ if (grub_strcmp (filename + n - 5, ".conf") != 0) ++ return 0; ++ ++ p = grub_xasprintf (GRUB_BLS_CONFIG_PATH "%s", filename); ++ ++ f = grub_file_open (p); ++ if (!f) ++ goto finish; ++ ++ sz = grub_file_size (f); ++ if (sz == GRUB_FILE_SIZE_UNKNOWN || sz > 1024*1024) ++ goto finish; ++ ++ for (;;) ++ { ++ char *buf; ++ ++ buf = grub_file_getline (f); ++ if (!buf) ++ break; ++ ++ if (grub_strncmp (buf, "title ", 6) == 0) ++ { ++ grub_free (title); ++ title = grub_strdup (buf + 6); ++ if (!title) ++ goto finish; ++ } ++ else if (grub_strncmp (buf, "options ", 8) == 0) ++ { ++ grub_free (options); ++ options = grub_strdup (buf + 8); ++ if (!options) ++ goto finish; ++ } ++ else if (grub_strncmp (buf, "linux ", 6) == 0) ++ { ++ grub_free (clinux); ++ clinux = grub_strdup (buf + 6); ++ if (!clinux) ++ goto finish; ++ } ++ else if (grub_strncmp (buf, "initrd ", 7) == 0) ++ { ++ grub_free (initrd); ++ initrd = grub_strdup (buf + 7); ++ if (!initrd) ++ goto finish; ++ } ++ ++ grub_free(buf); ++ } ++ ++ if (!linux) ++ { ++ grub_printf ("Skipping file %s with no 'linux' key.", p); ++ goto finish; ++ } ++ ++ args[0] = title ? title : filename; ++ ++ src = grub_xasprintf ("load_video\n" ++ "set gfx_payload=keep\n" ++ "insmod gzio\n" ++ GRUB_LINUX_CMD " %s%s%s%s\n" ++ "%s%s%s%s", ++ GRUB_BOOT_DEVICE, clinux, options ? " " : "", options ? options : "", ++ initrd ? GRUB_INITRD_CMD " " : "", initrd ? GRUB_BOOT_DEVICE : "", initrd ? initrd : "", initrd ? "\n" : ""); ++ ++ grub_normal_add_menu_entry (1, args, NULL, NULL, "bls", NULL, NULL, src, 0); ++ ++finish: ++ grub_free (p); ++ grub_free (title); ++ grub_free (options); ++ grub_free (clinux); ++ grub_free (initrd); ++ grub_free (src); ++ ++ if (f) ++ grub_file_close (f); ++ ++ return 0; ++} ++ ++static grub_err_t ++grub_cmd_bls_import (grub_extcmd_context_t ctxt __attribute__ ((unused)), ++ int argc __attribute__ ((unused)), ++ char **args __attribute__ ((unused))) ++{ ++ grub_fs_t fs; ++ grub_device_t dev; ++ static grub_err_t r; ++ const char *devid; ++ ++ devid = grub_env_get ("root"); ++ if (!devid) ++ return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("variable `%s' isn't set"), "root"); ++ ++ dev = grub_device_open (devid); ++ if (!dev) ++ return grub_errno; ++ ++ fs = grub_fs_probe (dev); ++ if (!fs) ++ { ++ r = grub_errno; ++ goto finish; ++ } ++ ++ r = fs->dir (dev, GRUB_BLS_CONFIG_PATH, parse_entry, NULL); ++ ++finish: ++ if (dev) ++ grub_device_close (dev); ++ ++ return r; ++} ++ ++static grub_extcmd_t cmd; ++ ++GRUB_MOD_INIT(bls) ++{ ++ cmd = grub_register_extcmd ("bls_import", ++ grub_cmd_bls_import, ++ 0, ++ NULL, ++ N_("Import Boot Loader Specification snippets."), ++ NULL); ++} ++ ++GRUB_MOD_FINI(bls) ++{ ++ grub_unregister_extcmd (cmd); ++} +-- +1.8.1.4 + diff --git a/0363-Move-bash-completion-script-922997.patch b/0363-Move-bash-completion-script-922997.patch new file mode 100644 index 0000000..62402cb --- /dev/null +++ b/0363-Move-bash-completion-script-922997.patch @@ -0,0 +1,26 @@ +From 03be782b24b462cfaa4a3fb5db0584b62b515bee Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Wed, 3 Apr 2013 14:35:34 -0400 +Subject: [PATCH 363/364] Move bash completion script (#922997) + +Apparently these go in a new place now. +--- + util/bash-completion.d/Makefile.am | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/util/bash-completion.d/Makefile.am b/util/bash-completion.d/Makefile.am +index 136287c..0bcdb06 100644 +--- a/util/bash-completion.d/Makefile.am ++++ b/util/bash-completion.d/Makefile.am +@@ -6,7 +6,7 @@ EXTRA_DIST = $(bash_completion_source) + + CLEANFILES = $(bash_completion_script) config.log + +-bashcompletiondir = $(sysconfdir)/bash_completion.d ++bashcompletiondir = $(datarootdir)/bash-completion/completions + bashcompletion_DATA = $(bash_completion_script) + + $(bash_completion_script): $(bash_completion_source) $(top_builddir)/config.status +-- +1.8.1.4 + diff --git a/0364-Use-memcpy-instead-of-direct-assignment-for-complex-.patch b/0364-Use-memcpy-instead-of-direct-assignment-for-complex-.patch new file mode 100644 index 0000000..897020f --- /dev/null +++ b/0364-Use-memcpy-instead-of-direct-assignment-for-complex-.patch @@ -0,0 +1,200 @@ +From 14870ff4617fd482054ceb2f307a91582e5e8817 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Thu, 18 Apr 2013 13:10:53 -0400 +Subject: [PATCH] Use memcpy instead of direct assignment for complex values. + (#949761) + +gcc 4.8.0 will emit SSE copies for such large chunks of data, and that +means using XMM0, which the UEFI ABI forbids. + +So with 4.7.2, you get: +000000000000000f : + f: 48 8b 06 mov (%rsi),%rax + 12: 48 89 47 38 mov %rax,0x38(%rdi) + 16: 48 8b 46 08 mov 0x8(%rsi),%rax + 1a: 48 89 47 40 mov %rax,0x40(%rdi) + 1e: c3 retq + +And with 4.8.0 you get: +000000000000000f : + f: 48 83 ec 18 sub $0x18,%rsp + 13: 0f 10 06 movups (%rsi),%xmm0 + 16: 0f 29 04 24 movaps %xmm0,(%rsp) + 1a: 0f 11 47 38 movups %xmm0,0x38(%rdi) + 1e: 48 83 c4 18 add $0x18,%rsp + 22: c3 retq + +As soon as we hit the movaps, we hit a trap. Once we do, though, since the +memory pointed at by the IDT is basically random memory during UEFI execution, +we find our CPU looping between the entry point for #UD (invalid opcode) and +the first piece of garbage in RAM after it. + +Right now, we have two options. Either 1) trick the compiler into not +emitting that sequence of instructions, or 2) turn off SSE instruction +generation. Number 2 currently requires making gnulib's printf not use +double or long double. It's probably the right thing to do, but I'm not +sure what the right way to do it is. + +So the following is method #1. +--- + grub-core/gfxmenu/gui_box.c | 4 ++-- + grub-core/gfxmenu/gui_canvas.c | 4 ++-- + grub-core/gfxmenu/gui_circular_progress.c | 4 ++-- + grub-core/gfxmenu/gui_image.c | 4 ++-- + grub-core/gfxmenu/gui_label.c | 4 ++-- + grub-core/gfxmenu/gui_list.c | 4 ++-- + grub-core/gfxmenu/gui_progress_bar.c | 4 ++-- + 7 files changed, 14 insertions(+), 14 deletions(-) + +diff --git a/grub-core/gfxmenu/gui_box.c b/grub-core/gfxmenu/gui_box.c +index 38b15f9..702f844 100644 +--- a/grub-core/gfxmenu/gui_box.c ++++ b/grub-core/gfxmenu/gui_box.c +@@ -264,7 +264,7 @@ static void + box_set_bounds (void *vself, const grub_video_rect_t *bounds) + { + grub_gui_box_t self = vself; +- self->bounds = *bounds; ++ memcpy(&self->bounds, bounds, sizeof (*bounds)); + self->layout_func (self, 1, 0, 0); /* Relayout the children. */ + } + +@@ -272,7 +272,7 @@ static void + box_get_bounds (void *vself, grub_video_rect_t *bounds) + { + grub_gui_box_t self = vself; +- *bounds = self->bounds; ++ memcpy(bounds, &self->bounds, sizeof (*bounds)); + } + + /* The box's preferred size is based on the preferred sizes +diff --git a/grub-core/gfxmenu/gui_canvas.c b/grub-core/gfxmenu/gui_canvas.c +index b3919c2..3d4fae9 100644 +--- a/grub-core/gfxmenu/gui_canvas.c ++++ b/grub-core/gfxmenu/gui_canvas.c +@@ -160,14 +160,14 @@ static void + canvas_set_bounds (void *vself, const grub_video_rect_t *bounds) + { + grub_gui_canvas_t self = vself; +- self->bounds = *bounds; ++ memcpy(&self->bounds, bounds, sizeof (*bounds)); + } + + static void + canvas_get_bounds (void *vself, grub_video_rect_t *bounds) + { + grub_gui_canvas_t self = vself; +- *bounds = self->bounds; ++ memcpy(bounds, &self->bounds, sizeof (*bounds)); + } + + static grub_err_t +diff --git a/grub-core/gfxmenu/gui_circular_progress.c b/grub-core/gfxmenu/gui_circular_progress.c +index e06d40c..f7684cc 100644 +--- a/grub-core/gfxmenu/gui_circular_progress.c ++++ b/grub-core/gfxmenu/gui_circular_progress.c +@@ -202,14 +202,14 @@ static void + circprog_set_bounds (void *vself, const grub_video_rect_t *bounds) + { + circular_progress_t self = vself; +- self->bounds = *bounds; ++ memcpy(&self->bounds, bounds, sizeof (*bounds)); + } + + static void + circprog_get_bounds (void *vself, grub_video_rect_t *bounds) + { + circular_progress_t self = vself; +- *bounds = self->bounds; ++ memcpy(bounds, &self->bounds, sizeof (*bounds)); + } + + static void +diff --git a/grub-core/gfxmenu/gui_image.c b/grub-core/gfxmenu/gui_image.c +index 29784ed..d864096 100644 +--- a/grub-core/gfxmenu/gui_image.c ++++ b/grub-core/gfxmenu/gui_image.c +@@ -158,7 +158,7 @@ static void + image_set_bounds (void *vself, const grub_video_rect_t *bounds) + { + grub_gui_image_t self = vself; +- self->bounds = *bounds; ++ memcpy(&self->bounds, bounds, sizeof (*bounds)); + rescale_image (self); + } + +@@ -166,7 +166,7 @@ static void + image_get_bounds (void *vself, grub_video_rect_t *bounds) + { + grub_gui_image_t self = vself; +- *bounds = self->bounds; ++ memcpy(bounds, &self->bounds, sizeof (*bounds)); + } + + /* FIXME: inform rendering system it's not forced minimum. */ +diff --git a/grub-core/gfxmenu/gui_label.c b/grub-core/gfxmenu/gui_label.c +index 637578f..daf6290 100644 +--- a/grub-core/gfxmenu/gui_label.c ++++ b/grub-core/gfxmenu/gui_label.c +@@ -134,14 +134,14 @@ static void + label_set_bounds (void *vself, const grub_video_rect_t *bounds) + { + grub_gui_label_t self = vself; +- self->bounds = *bounds; ++ memcpy(&self->bounds, bounds, sizeof (*bounds)); + } + + static void + label_get_bounds (void *vself, grub_video_rect_t *bounds) + { + grub_gui_label_t self = vself; +- *bounds = self->bounds; ++ memcpy(bounds, &self->bounds, sizeof (*bounds)); + } + + static void +diff --git a/grub-core/gfxmenu/gui_list.c b/grub-core/gfxmenu/gui_list.c +index 1982d9a..23b29ba 100644 +--- a/grub-core/gfxmenu/gui_list.c ++++ b/grub-core/gfxmenu/gui_list.c +@@ -362,14 +362,14 @@ static void + list_set_bounds (void *vself, const grub_video_rect_t *bounds) + { + list_impl_t self = vself; +- self->bounds = *bounds; ++ memcpy(&self->bounds, bounds, sizeof (*bounds)); + } + + static void + list_get_bounds (void *vself, grub_video_rect_t *bounds) + { + list_impl_t self = vself; +- *bounds = self->bounds; ++ memcpy(bounds, &self->bounds, sizeof (*bounds)); + } + + static void +diff --git a/grub-core/gfxmenu/gui_progress_bar.c b/grub-core/gfxmenu/gui_progress_bar.c +index 965c6b3..4e458e9 100644 +--- a/grub-core/gfxmenu/gui_progress_bar.c ++++ b/grub-core/gfxmenu/gui_progress_bar.c +@@ -232,14 +232,14 @@ static void + progress_bar_set_bounds (void *vself, const grub_video_rect_t *bounds) + { + grub_gui_progress_bar_t self = vself; +- self->bounds = *bounds; ++ memcpy(&self->bounds, bounds, sizeof (*bounds)); + } + + static void + progress_bar_get_bounds (void *vself, grub_video_rect_t *bounds) + { + grub_gui_progress_bar_t self = vself; +- *bounds = self->bounds; ++ memcpy(bounds, &self->bounds, sizeof (*bounds)); + } + + static void +-- +1.8.2.1 + diff --git a/add-vlan-tag-support.patch b/add-vlan-tag-support.patch deleted file mode 100644 index 15f92f8..0000000 --- a/add-vlan-tag-support.patch +++ /dev/null @@ -1,185 +0,0 @@ -From 5573f16fd05c1f8f310f2ead176b52ed6d4a08ec Mon Sep 17 00:00:00 2001 -From: Paulo Flabiano Smorigo -Date: Tue, 30 Oct 2012 15:19:39 -0200 -Subject: [PATCH] Add vlan-tag support - -This patch adds support for virtual LAN (VLAN) tagging. VLAN tagging allows -multiple VLANs in a bridged network to share the same physical network link but -maintain isolation: - -http://en.wikipedia.org/wiki/IEEE_802.1Q - -This patch should fix this bugzilla: -https://bugzilla.redhat.com/show_bug.cgi?id=871563 ---- - grub-core/kern/ieee1275/init.c | 1 + - grub-core/kern/ieee1275/openfw.c | 30 +++++++++++++++++++++++++++ - grub-core/net/ethernet.c | 42 +++++++++++++++++++++++++++++++++++--- - include/grub/ieee1275/ieee1275.h | 1 + - include/grub/net.h | 2 ++ - 5 files changed, 73 insertions(+), 3 deletions(-) - -diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c -index 5c45947..209cf8a 100644 ---- a/grub-core/kern/ieee1275/init.c -+++ b/grub-core/kern/ieee1275/init.c -@@ -102,6 +102,7 @@ grub_machine_get_bootlocation (char **device, char **path) - char *dev, *canon; - char *ptr; - dev = grub_ieee1275_get_aliasdevname (bootpath); -+ grub_ieee1275_parse_net_options (bootpath); - canon = grub_ieee1275_canonicalise_devname (dev); - ptr = canon + grub_strlen (canon) - 1; - while (ptr > canon && (*ptr == ',' || *ptr == ':')) -diff --git a/grub-core/kern/ieee1275/openfw.c b/grub-core/kern/ieee1275/openfw.c -index c2b1bdf..9fdfafa 100644 ---- a/grub-core/kern/ieee1275/openfw.c -+++ b/grub-core/kern/ieee1275/openfw.c -@@ -23,6 +23,7 @@ - #include - #include - #include -+#include - - enum grub_ieee1275_parse_type - { -@@ -413,6 +414,35 @@ fail: - return ret; - } - -+int -+grub_ieee1275_parse_net_options (const char *path) -+{ -+ char *comma; -+ char *args; -+ char *option = 0; -+ -+ args = grub_ieee1275_get_devargs (path); -+ if (!args) -+ /* There is no option. */ -+ return -1; -+ -+ do -+ { -+ comma = grub_strchr (args, ','); -+ if (! comma) -+ option = grub_strdup (args); -+ else -+ option = grub_strndup (args, (grub_size_t)(comma - args)); -+ args = comma + 1; -+ -+ if (! grub_strncmp(option, "vtag", 4)) -+ grub_env_set ("vlan-tag", option + grub_strlen("vtag=")); -+ -+ } while (comma); -+ -+ return 0; -+} -+ - char * - grub_ieee1275_get_device_type (const char *path) - { -diff --git a/grub-core/net/ethernet.c b/grub-core/net/ethernet.c -index b38e2c8..5e45d46 100644 ---- a/grub-core/net/ethernet.c -+++ b/grub-core/net/ethernet.c -@@ -23,6 +23,7 @@ - #include - #include - #include -+#include - #include - #include - -@@ -56,10 +57,19 @@ send_ethernet_packet (struct grub_net_network_level_interface *inf, - { - struct etherhdr *eth; - grub_err_t err; -+ grub_uint32_t vlantag = 0; -+ grub_uint8_t etherhdr_size; - -- COMPILE_TIME_ASSERT (sizeof (*eth) < GRUB_NET_MAX_LINK_HEADER_SIZE); -+ etherhdr_size = sizeof (*eth); -+ COMPILE_TIME_ASSERT (sizeof (*eth) + 4 < GRUB_NET_MAX_LINK_HEADER_SIZE); - -- err = grub_netbuff_push (nb, sizeof (*eth)); -+ const char *vlantag_text = grub_env_get ("vlan-tag"); -+ if (vlantag_text != 0) { -+ etherhdr_size += 4; -+ vlantag = grub_strtoul (vlantag_text, 0, 16); -+ } -+ -+ err = grub_netbuff_push (nb, etherhdr_size); - if (err) - return err; - eth = (struct etherhdr *) nb->data; -@@ -76,6 +86,19 @@ send_ethernet_packet (struct grub_net_network_level_interface *inf, - return err; - inf->card->opened = 1; - } -+ -+ /* Check if a vlan-tag is needed. */ -+ if (vlantag != 0) -+ { -+ /* Move eth type to the right */ -+ grub_memcpy((char *) nb->data + etherhdr_size - 2, -+ (char *) nb->data + etherhdr_size - 6, 2); -+ -+ /* Add the tag in the middle */ -+ grub_memcpy((char *) nb->data + etherhdr_size - 6, -+ &vlantag, 4); -+ } -+ - return inf->card->driver->send (inf->card, nb); - } - -@@ -90,10 +113,23 @@ grub_net_recv_ethernet_packet (struct grub_net_buff *nb, - grub_net_link_level_address_t hwaddress; - grub_net_link_level_address_t src_hwaddress; - grub_err_t err; -+ grub_uint8_t etherhdr_size = sizeof (*eth); -+ -+ grub_uint16_t vlantag_identifier = 0; -+ grub_memcpy (&vlantag_identifier, nb->data + etherhdr_size - 2, 2); -+ -+ /* Check if a vlan-tag is present. */ -+ if (vlantag_identifier == VLANTAG_IDENTIFIER) -+ { -+ etherhdr_size += 4; -+ /* Move eth type to the original position */ -+ grub_memcpy((char *) nb->data + etherhdr_size - 6, -+ (char *) nb->data + etherhdr_size - 2, 2); -+ } - - eth = (struct etherhdr *) nb->data; - type = grub_be_to_cpu16 (eth->type); -- err = grub_netbuff_pull (nb, sizeof (*eth)); -+ err = grub_netbuff_pull (nb, etherhdr_size); - if (err) - return err; - -diff --git a/include/grub/ieee1275/ieee1275.h b/include/grub/ieee1275/ieee1275.h -index 416a544..a8cf093 100644 ---- a/include/grub/ieee1275/ieee1275.h -+++ b/include/grub/ieee1275/ieee1275.h -@@ -210,5 +210,6 @@ char *EXPORT_FUNC(grub_ieee1275_canonicalise_devname) (const char *path); - char *EXPORT_FUNC(grub_ieee1275_get_device_type) (const char *path); - int EXPORT_FUNC(grub_ieee1275_cas_reboot) (char *script); - int EXPORT_FUNC(grub_ieee1275_set_boot_last_label) (const char *text); -+int EXPORT_FUNC(grub_ieee1275_parse_net_options) (const char *path); - - #endif /* ! GRUB_IEEE1275_HEADER */ -diff --git a/include/grub/net.h b/include/grub/net.h -index a7e5b2c..f4fec17 100644 ---- a/include/grub/net.h -+++ b/include/grub/net.h -@@ -532,4 +532,6 @@ extern char *grub_net_default_server; - #define GRUB_NET_TRIES 40 - #define GRUB_NET_INTERVAL 400 - -+#define VLANTAG_IDENTIFIER 0x8100 -+ - #endif /* ! GRUB_NET_HEADER */ --- -1.7.10.4 - diff --git a/follow-the-symbolic-link-ieee1275.patch b/follow-the-symbolic-link-ieee1275.patch deleted file mode 100644 index 0cf624b..0000000 --- a/follow-the-symbolic-link-ieee1275.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 9436d0324b98e71c8ab55b09b4248a617cd463a8 Mon Sep 17 00:00:00 2001 -From: Paulo Flabiano Smorigo -Date: Wed, 7 Nov 2012 16:22:33 -0200 -Subject: [PATCH] Follow the symbolic link (ieee1275) - -If the device used is a symlink, the file command must "follow -the link" in order to check the real device. ---- - 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 69a97ad..19dc3b4 100644 ---- a/util/grub-install.in -+++ b/util/grub-install.in -@@ -750,7 +750,7 @@ elif [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "i386-ieee1275" ] - exit 1 - fi - -- if [ "$(file -s "${install_device}" -b | awk '{ print $1 }')" = ELF ] || [ x$("${grub_probe}" -m "${device_map}" -d "${install_device}" -t zero_check) = xtrue ]; then -+ if [ "$(file -s -b -L "${install_device}" | awk '{ print $1 }')" = ELF ] || [ x$("${grub_probe}" -m "${device_map}" -d "${install_device}" -t zero_check) = xtrue ]; then - dd if="${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/core.${imgext}" of="${install_device}" status=noxfer || { - gettext "Failed to copy Grub to the PReP partition." 1>&2 - echo 1>&2 --- -1.7.10.4 - diff --git a/grub-1.99-just-say-linux.patch b/grub-1.99-just-say-linux.patch deleted file mode 100644 index 62a6b32..0000000 --- a/grub-1.99-just-say-linux.patch +++ /dev/null @@ -1,45 +0,0 @@ -From d4bd41f972c6e22b86c773cbba2a1e14f400a8be Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Mon, 14 Mar 2011 14:27:42 -0400 -Subject: [PATCH] Don't say "GNU/Linux" in generated menus. - ---- - util/grub.d/10_linux.in | 4 ++-- - util/grub.d/20_linux_xen.in | 4 ++-- - 2 files changed, 4 insertions(+), 4 deletions(-) - -diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in -index a09c3e6..0b0df78 100644 ---- a/util/grub.d/10_linux.in -+++ b/util/grub.d/10_linux.in -@@ -29,9 +29,9 @@ export TEXTDOMAINDIR=@localedir@ - CLASS="--class gnu-linux --class gnu --class os" - - if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then -- OS=GNU/Linux -+ OS="$(sed 's, release .*$,,g' /etc/system-release)" - else -- OS="${GRUB_DISTRIBUTOR} GNU/Linux" -+ OS="${GRUB_DISTRIBUTOR}" - CLASS="--class $(echo ${GRUB_DISTRIBUTOR} | tr 'A-Z' 'a-z' | cut -d' ' -f1) ${CLASS}" - fi - -diff --git a/util/grub.d/20_linux_xen.in b/util/grub.d/20_linux_xen.in -index ee49cd9..10422b0 100644 ---- a/util/grub.d/20_linux_xen.in -+++ b/util/grub.d/20_linux_xen.in -@@ -29,9 +29,9 @@ export TEXTDOMAINDIR=@localedir@ - CLASS="--class gnu-linux --class gnu --class os --class xen" - - if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then -- OS=GNU/Linux -+ OS="$(sed 's, release .*$,,g' /etc/system-release)" - else -- OS="${GRUB_DISTRIBUTOR} GNU/Linux" -+ OS="${GRUB_DISTRIBUTOR}" - CLASS="--class $(echo ${GRUB_DISTRIBUTOR} | tr 'A-Z' 'a-z' | cut -d' ' -f1) ${CLASS}" - fi - --- -1.7.4 - diff --git a/grub-1.99-ppc-terminfo.patch b/grub-1.99-ppc-terminfo.patch deleted file mode 100644 index b2b0d78..0000000 --- a/grub-1.99-ppc-terminfo.patch +++ /dev/null @@ -1,155 +0,0 @@ -From e263907f50e496e602edd9bd846ccb6e0565a085 Mon Sep 17 00:00:00 2001 -From: Mark Hamzy -Date: Wed, 28 Mar 2012 14:46:41 -0500 -Subject: [PATCH] Migrate PPC from Yaboot to Grub2 - -Add configuration support for serial terminal consoles. This will set the -maximum screen size so that text is not overwritten. - ---- - Makefile.util.def | 7 +++ - util/grub.d/20_ppc_terminfo.in | 114 ++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 121 insertions(+), 0 deletions(-) - create mode 100644 util/grub.d/20_ppc_terminfo.in - -diff --git a/Makefile.util.def b/Makefile.util.def -index c41b76e..b349758 100644 ---- a/Makefile.util.def -+++ b/Makefile.util.def -@@ -423,6 +423,13 @@ script = { - }; - - script = { -+ name = '20_ppc_terminfo'; -+ common = util/grub.d/20_ppc_terminfo.in; -+ installdir = grubconf; -+ condition = COND_HOST_LINUX; -+}; -+ -+script = { - name = '30_os-prober'; - common = util/grub.d/30_os-prober.in; - installdir = grubconf; -diff --git a/util/grub.d/20_ppc_terminfo.in b/util/grub.d/20_ppc_terminfo.in -new file mode 100644 -index 0000000..10d6658 ---- /dev/null -+++ b/util/grub.d/20_ppc_terminfo.in -@@ -0,0 +1,114 @@ -+#! /bin/sh -+set -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@ -+. "@datadir@/@PACKAGE@/grub-mkconfig_lib" -+ -+export TEXTDOMAIN=@PACKAGE@ -+export TEXTDOMAINDIR=@localedir@ -+ -+X=80 -+Y=24 -+TERMINAL=ofconsole -+ -+argument () { -+ opt=$1 -+ shift -+ -+ if test $# -eq 0; then -+ echo "$0: option requires an argument -- '$opt'" 1>&2 -+ exit 1 -+ fi -+ echo $1 -+} -+ -+check_terminfo () { -+ -+ while test $# -gt 0 -+ do -+ option=$1 -+ shift -+ -+ case "$option" in -+ terminfo | TERMINFO) -+ ;; -+ -+ -g) -+ NEWXY=`argument $option "$@"` -+ NEWX=`echo $NEWXY | cut -d x -f 1` -+ NEWY=`echo $NEWXY | cut -d x -f 2` -+ -+ if [ ${NEWX} -ge 80 ] ; then -+ X=${NEWX} -+ else -+ echo "Warning: ${NEWX} is less than the minimum size of 80" -+ fi -+ -+ if [ ${NEWY} -ge 24 ] ; then -+ Y=${NEWY} -+ else -+ echo "Warning: ${NEWY} is less than the minimum size of 24" -+ fi -+ -+ shift -+ ;; -+ -+ *) -+# # accept console or ofconsole -+# if [ "$option" != "console" -a "$option" != "ofconsole" ] ; then -+# echo "Error: GRUB_TERMINFO unknown console: $option" -+# exit 1 -+# fi -+# # perfer console -+# TERMINAL=console -+ # accept ofconsole -+ if [ "$option" != "ofconsole" ] ; then -+ echo "Error: GRUB_TERMINFO unknown console: $option" -+ exit 1 -+ fi -+ # perfer console -+ TERMINAL=ofconsole -+ ;; -+ esac -+ -+ done -+ -+} -+ -+if ! uname -m | grep -q ppc ; then -+ exit 0 -+fi -+ -+if [ "x${GRUB_TERMINFO}" != "x" ] ; then -+ F1=`echo ${GRUB_TERMINFO} | cut -d " " -f 1` -+ -+ if [ "${F1}" != "terminfo" ] ; then -+ echo "Error: GRUB_TERMINFO is set to \"${GRUB_TERMINFO}\" The first word should be terminfo." -+ exit 1 -+ fi -+ -+ check_terminfo ${GRUB_TERMINFO} -+fi -+ -+cat << EOF -+ terminfo -g ${X}x${Y} ${TERMINAL} -+EOF --- -1.7.7.2 - diff --git a/grub-2.00-Add-check_completed_boot.patch b/grub-2.00-Add-check_completed_boot.patch deleted file mode 100644 index f7f0f8f..0000000 --- a/grub-2.00-Add-check_completed_boot.patch +++ /dev/null @@ -1,161 +0,0 @@ -From 7b886580f92bf6b766b042b6ef46cb77a5ba7451 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Fri, 25 May 2012 10:49:06 -0400 -Subject: [PATCH] Add check_completed_boot command on EFI systems. - -check_completed_boot [] - -checks for a 1-byte integer in an EFI variable guid:CompletedBoot and sets -a command-line specified timeout, with a default of 30s, if the variable is -not equal to 1. This can be used to enter the grub menus in the event that -your OS did not correctly boot on the previous boot. It also unconditionally -sets the value to 0. ---- - grub-core/Makefile.core.def | 6 ++ - grub-core/commands/efi/eficompleted.c | 117 +++++++++++++++++++++++++++++++++ - 2 files changed, 123 insertions(+) - create mode 100644 grub-core/commands/efi/eficompleted.c - -diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def -index d0c06d5..0a21838 100644 ---- a/grub-core/Makefile.core.def -+++ b/grub-core/Makefile.core.def -@@ -582,6 +582,12 @@ module = { - }; - - module = { -+ name = eficompleted; -+ efi = commands/efi/eficompleted.c; -+ enable = efi; -+}; -+ -+module = { - name = blocklist; - common = commands/blocklist.c; - }; -diff --git a/grub-core/commands/efi/eficompleted.c b/grub-core/commands/efi/eficompleted.c -new file mode 100644 -index 0000000..77a856a ---- /dev/null -+++ b/grub-core/commands/efi/eficompleted.c -@@ -0,0 +1,117 @@ -+/* completed.c - Check if previous boot was successful. */ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2012 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 -+ -+GRUB_MOD_LICENSE ("GPLv3+"); -+ -+static grub_err_t -+grub_efi_parse_guid(char *arg, grub_efi_guid_t *outguid) -+{ -+ grub_err_t status = GRUB_ERR_NONE; -+ grub_efi_guid_t guid; -+ char *s = arg; -+ grub_uint64_t guidcomp; -+ int i; -+ -+ guid.data1 = grub_cpu_to_le32 (grub_strtoul(s, &s, 16)); -+ if (*s != '-') -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid guid `%s'", arg); -+ s++; -+ -+ guid.data2 = grub_cpu_to_le16 (grub_strtoul(s, &s, 16)); -+ if (*s != '-') -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid guid `%s'", arg); -+ s++; -+ -+ guid.data2 = grub_cpu_to_le16 (grub_strtoul(s, &s, 16)); -+ if (*s != '-') -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid guid `%s'", arg); -+ s++; -+ -+ guidcomp = grub_strtoull (s, 0, 16); -+ for (i = 0; i < 8; i++) -+ guid.data4[i] = (guidcomp >> (56 - 8 * i)) & 0xff; -+ -+ grub_memcpy(outguid, &guid, sizeof (*outguid)); -+ return GRUB_ERR_NONE; -+} -+ -+static grub_err_t -+grub_cmd_completed (grub_command_t cmd __attribute__ ((unused)), -+ int argc __attribute__ ((unused)), -+ char **args __attribute__ ((unused))) -+{ -+ grub_efi_uint8_t *old_completed_boot; -+ grub_efi_uint8_t completed_boot = 0; -+ unsigned long timeout = 30; -+ grub_efi_guid_t guid; -+ grub_err_t status; -+ grub_size_t cb_size; -+ -+ if (argc < 2) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "too few arguments"); -+ -+ if (argc > 3) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "too many arguments"); -+ -+ status = grub_efi_parse_guid(args[1], &guid); -+ if (status != GRUB_ERR_NONE) -+ return status; -+ -+ if (argc > 2) -+ { -+ char *s = args[2]; -+ timeout = grub_strtoul(s, &s, 0); -+ if (grub_errno != GRUB_ERR_NONE) -+ return grub_errno; -+ } -+ -+ old_completed_boot = grub_efi_get_variable("CompletedBoot", &guid, &cb_size); -+ status = grub_efi_set_variable("CompletedBoot", &guid, &completed_boot, -+ sizeof (completed_boot)); -+ -+ if (old_completed_boot == NULL) -+ { -+ /* We assume this means it's our first boot after installation. */ -+ return GRUB_ERR_NONE; -+ } -+ -+ if (cb_size != sizeof(*old_completed_boot) || *old_completed_boot != 1) -+ grub_env_set("timeout", timeout); -+ -+ return GRUB_ERR_NONE; -+} -+ -+static grub_command_t cmd = NULL; -+ -+GRUB_MOD_INIT(eficompleted) -+{ -+ cmd = grub_register_command("check_completed_boot", grub_cmd_completed, "", -+ "Check if the last boot completed successfully."); -+} -+ -+GRUB_MOD_FINI(eficompleted) -+{ -+ grub_unregister_command (cmd); -+} --- -1.7.10.1 - diff --git a/grub-2.00-Add-fwsetup.patch b/grub-2.00-Add-fwsetup.patch deleted file mode 100644 index 5abae3b..0000000 --- a/grub-2.00-Add-fwsetup.patch +++ /dev/null @@ -1,218 +0,0 @@ -From 2c7cdc59a8d6cb7800c73b90aa75cc8b21807af6 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Thu, 24 May 2012 08:37:21 -0400 -Subject: [PATCH] Add support for entering the firmware setup screen. - -This adds a command "fwsetup", with which you can enter your firmware -setup screen. The mechanism is to set a global UEFI variable with a -specific value and reboot. ---- - ChangeLog | 8 ++++ - grub-core/Makefile.core.def | 6 +++ - grub-core/commands/efi/efifwsetup.c | 88 +++++++++++++++++++++++++++++++++++ - grub-core/kern/efi/efi.c | 30 ++++++++++++ - include/grub/efi/api.h | 2 + - include/grub/efi/efi.h | 5 ++ - 6 files changed, 139 insertions(+) - create mode 100644 grub-core/commands/efi/efifwsetup.c - -#diff --git a/ChangeLog b/ChangeLog -#index ce52576..29ebcbd 100644 -#--- a/ChangeLog -#+++ b/ChangeLog -#@@ -1,3 +1,11 @@ -#+2012-05-24 Peter Jones -#+ -#+ * grub-core/Makefile.core.def: add efifwsetup module -#+ * grub-core/commands/efi/efifwsetup.c: add code for fwsetup command -#+ * grub-core/kern/efi/efi.c (grub_efi_set_variable): New function -#+ * include/grub/efi/api.h: add define for OsIndications variable -#+ * include/grub/efi/efi.h: export grub_efi_set_variable -#+ -# 2012-05-31 Vladimir Serbinenko -# -# * configure.ac: Bump to beta6. -diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def -index 000cf0d..d0c06d5 100644 ---- a/grub-core/Makefile.core.def -+++ b/grub-core/Makefile.core.def -@@ -576,6 +576,12 @@ module = { - }; - - module = { -+ name = efifwsetup; -+ efi = commands/efi/efifwsetup.c; -+ enable = efi; -+}; -+ -+module = { - name = blocklist; - common = commands/blocklist.c; - }; -diff --git a/grub-core/commands/efi/efifwsetup.c b/grub-core/commands/efi/efifwsetup.c -new file mode 100644 -index 0000000..756a14c ---- /dev/null -+++ b/grub-core/commands/efi/efifwsetup.c -@@ -0,0 +1,88 @@ -+/* fwsetup.c - Reboot into firmware setup menu. */ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2012 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 -+ -+GRUB_MOD_LICENSE ("GPLv3+"); -+ -+static grub_err_t -+grub_cmd_fwsetup (grub_command_t cmd __attribute__ ((unused)), -+ int argc __attribute__ ((unused)), -+ char **args __attribute__ ((unused))) -+{ -+ grub_efi_uint64_t *old_os_indications; -+ grub_efi_uint64_t os_indications = GRUB_EFI_OS_INDICATIONS_BOOT_TO_FW_UI; -+ grub_err_t status; -+ grub_size_t oi_size; -+ grub_efi_guid_t global = GRUB_EFI_GLOBAL_VARIABLE_GUID; -+ -+ old_os_indications = grub_efi_get_variable("OsIndications", &global, -+ &oi_size); -+ -+ if (old_os_indications != NULL && oi_size == sizeof(*old_os_indications)) -+ os_indications |= *old_os_indications; -+ -+ status = grub_efi_set_variable("OsIndications", &global, &os_indications, -+ sizeof (os_indications)); -+ if (status != GRUB_ERR_NONE) -+ return status; -+ -+ grub_reboot(); -+ -+ return GRUB_ERR_BUG; -+} -+ -+static grub_command_t cmd = NULL; -+ -+static grub_efi_boolean_t -+efifwsetup_is_supported(void) -+{ -+ grub_efi_uint64_t *os_indications_supported = NULL; -+ grub_size_t oi_size = 0; -+ grub_efi_guid_t global = GRUB_EFI_GLOBAL_VARIABLE_GUID; -+ -+ os_indications_supported = grub_efi_get_variable("OsIndicationsSupported", -+ &global, &oi_size); -+ -+ if (!os_indications_supported) -+ return 0; -+ -+ if (*os_indications_supported & GRUB_EFI_OS_INDICATIONS_BOOT_TO_FW_UI) -+ return 1; -+ -+ return 0; -+} -+ -+GRUB_MOD_INIT(efifwsetup) -+{ -+ if (efifwsetup_is_supported()) -+ cmd = grub_register_command("fwsetup", grub_cmd_fwsetup, "", -+ "Reboot into firmware setup menu."); -+ -+} -+ -+GRUB_MOD_FINI(efifwsetup) -+{ -+ if (cmd) -+ grub_unregister_command (cmd); -+} -diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c -index 6f12c76..7a418a6 100644 ---- a/grub-core/kern/efi/efi.c -+++ b/grub-core/kern/efi/efi.c -@@ -230,6 +230,36 @@ grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid, - return NULL; - } - -+grub_err_t -+grub_efi_set_variable(const char *var, const grub_efi_guid_t *guid, -+ void *data, grub_size_t datasize) -+{ -+ grub_efi_status_t status; -+ grub_efi_runtime_services_t *r; -+ grub_efi_char16_t *var16; -+ grub_size_t len, len16; -+ -+ len = grub_strlen (var); -+ len16 = len * GRUB_MAX_UTF16_PER_UTF8; -+ var16 = grub_malloc ((len16 + 1) * sizeof (var16[0])); -+ if (!var16) -+ return grub_errno; -+ len16 = grub_utf8_to_utf16 (var16, len16, (grub_uint8_t *) var, len, NULL); -+ var16[len16] = 0; -+ -+ r = grub_efi_system_table->runtime_services; -+ -+ grub_efi_uint32_t attributes = GRUB_EFI_VARIABLE_NON_VOLATILE | -+ GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS | -+ GRUB_EFI_VARIABLE_RUNTIME_ACCESS; -+ -+ status = efi_call_5 (r->set_variable, var16, guid, attributes, datasize,data); -+ if (status == GRUB_EFI_SUCCESS) -+ return GRUB_ERR_NONE; -+ -+ return grub_error (GRUB_ERR_IO, "could not set EFI variable `%s'", var); -+} -+ - #pragma GCC diagnostic ignored "-Wcast-align" - - /* Search the mods section from the PE32/PE32+ image. This code uses -diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h -index 26127de..a47a4e3 100644 ---- a/include/grub/efi/api.h -+++ b/include/grub/efi/api.h -@@ -58,6 +58,8 @@ - #define GRUB_EFI_OPEN_PROTOCOL_BY_DRIVER 0x00000010 - #define GRUB_EFI_OPEN_PROTOCOL_BY_EXCLUSIVE 0x00000020 - -+#define GRUB_EFI_OS_INDICATIONS_BOOT_TO_FW_UI 0x0000000000000001ULL -+ - #define GRUB_EFI_VARIABLE_NON_VOLATILE 0x0000000000000001 - #define GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS 0x0000000000000002 - #define GRUB_EFI_VARIABLE_RUNTIME_ACCESS 0x0000000000000004 -diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h -index e67d92b..489cf9e 100644 ---- a/include/grub/efi/efi.h -+++ b/include/grub/efi/efi.h -@@ -64,6 +64,11 @@ grub_err_t EXPORT_FUNC (grub_efi_set_virtual_address_map) (grub_efi_uintn_t memo - void *EXPORT_FUNC (grub_efi_get_variable) (const char *variable, - const grub_efi_guid_t *guid, - grub_size_t *datasize_out); -+grub_err_t -+EXPORT_FUNC (grub_efi_set_variable) (const char *var, -+ const grub_efi_guid_t *guid, -+ void *data, -+ grub_size_t datasize); - int - EXPORT_FUNC (grub_efi_compare_device_paths) (const grub_efi_device_path_t *dp1, - const grub_efi_device_path_t *dp2); --- -1.7.10.1 - diff --git a/grub-2.00-Dont-set-boot-on-ppc.patch b/grub-2.00-Dont-set-boot-on-ppc.patch deleted file mode 100644 index 481d8b9..0000000 --- a/grub-2.00-Dont-set-boot-on-ppc.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 28d9f3965f095a765ec8aaa589b4e04608b69901 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Fri, 25 May 2012 14:57:38 -0400 -Subject: [PATCH] Don't set boot device on ppc-ieee1275 - -This started with the problem that powerkvm doesn't have /dev/nvram and so -there is no way to set boot-device. ---- - util/grub-install.in | 18 ++++++++++-------- - 1 file changed, 10 insertions(+), 8 deletions(-) - -diff --git a/util/grub-install.in b/util/grub-install.in -index e19f1cd..69a97ad 100644 ---- a/util/grub-install.in -+++ b/util/grub-install.in -@@ -807,14 +807,16 @@ elif [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "i386-ieee1275" ] - } - fi - -- "$nvsetenv" boot-device "$boot_device" || { -- # TRANSLATORS: The %s will be replaced by an external program name. -- gettext_printf "\`%s' failed.\n" "$nvsetenv" 1>&2 -- gettext "You will have to set \`boot-device' variable manually. At the IEEE1275 prompt, type:" 1>&2 -- echo 1>&2 -- echo " setenv boot-device $boot_device" 1>&2 -- exit 1 -- } -+ if [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "i386-ieee1275" ]; then -+ "$nvsetenv" boot-device "$boot_device" || { -+ # TRANSLATORS: The %s will be replaced by an external program name. -+ gettext_printf "\`%s' failed.\n" "$nvsetenv" 1>&2 -+ gettext "You will have to set \`boot-device' variable manually. At the IEEE1275 prompt, type:" 1>&2 -+ echo 1>&2 -+ echo " setenv boot-device $boot_device" 1>&2 -+ exit 1 -+ } -+ fi - fi - elif [ x"${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = xmips-arc ]; then - dvhtool -d "${install_device}" --unix-to-vh "${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/core.${imgext}" grub diff --git a/grub-2.00-Handle-escapes-in-labels.patch b/grub-2.00-Handle-escapes-in-labels.patch deleted file mode 100644 index 65a2a41..0000000 --- a/grub-2.00-Handle-escapes-in-labels.patch +++ /dev/null @@ -1,186 +0,0 @@ -From d08e2511db353b2db9c5785d3f22079674abd708 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Mon, 1 Oct 2012 13:24:37 -0400 -Subject: [PATCH] Pass "\x[[:hex:]][[:hex:]]" straight through unmolested. - ---- - grub-core/commands/wildcard.c | 16 +++++++++++++++- - grub-core/lib/cmdline.c | 34 +++++++++++++++++++++++++++++++-- - grub-core/script/execute.c | 44 +++++++++++++++++++++++++++++++++++++------ - 3 files changed, 85 insertions(+), 9 deletions(-) - -diff --git a/grub-core/commands/wildcard.c b/grub-core/commands/wildcard.c -index 2b73d9a..d1235dc 100644 ---- a/grub-core/commands/wildcard.c -+++ b/grub-core/commands/wildcard.c -@@ -420,6 +420,12 @@ check_file (const char *dir, const char *basename) - return found; - } - -+static int -+is_hex(char c) -+{ -+ return ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')); -+} -+ - static void - unescape (char *out, const char *in, const char *end) - { -@@ -428,7 +434,15 @@ unescape (char *out, const char *in, const char *end) - - for (optr = out, iptr = in; iptr < end;) - { -- if (*iptr == '\\' && iptr + 1 < end) -+ if (*iptr == '\\' && iptr + 3 < end && iptr[1] == 'x' && is_hex(iptr[2]) && is_hex(iptr[3])) -+ { -+ *optr++ = *iptr++; -+ *optr++ = *iptr++; -+ *optr++ = *iptr++; -+ *optr++ = *iptr++; -+ continue; -+ } -+ else if (*iptr == '\\' && iptr + 1 < end) - { - *optr++ = iptr[1]; - iptr += 2; -diff --git a/grub-core/lib/cmdline.c b/grub-core/lib/cmdline.c -index a702e64..c8605a7 100644 ---- a/grub-core/lib/cmdline.c -+++ b/grub-core/lib/cmdline.c -@@ -20,6 +20,12 @@ - #include - #include - -+static int -+is_hex(char c) -+{ -+ return ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')); -+} -+ - static unsigned int check_arg (char *c, int *has_space) - { - int space = 0; -@@ -27,7 +33,13 @@ static unsigned int check_arg (char *c, int *has_space) - - while (*c) - { -- if (*c == '\\' || *c == '\'' || *c == '"') -+ if (*c == '\\' && *(c+1) == 'x' && is_hex(*(c+2)) && is_hex(*(c+3))) -+ { -+ size += 4; -+ c += 4; -+ continue; -+ } -+ else if (*c == '\\' || *c == '\'' || *c == '"') - size++; - else if (*c == ' ') - space = 1; -@@ -82,7 +94,25 @@ int grub_create_loader_cmdline (int argc, char *argv[], char *buf, - - while (*c) - { -- if (*c == '\\' || *c == '\'' || *c == '"') -+ if (*c == ' ') -+ { -+ *buf++ = '\\'; -+ *buf++ = 'x'; -+ *buf++ = '2'; -+ *buf++ = '0'; -+ c++; -+ continue; -+ } -+ else if (*c == '\\' && *(c+1) == 'x' && -+ is_hex(*(c+2)) && is_hex(*(c+3))) -+ { -+ *buf++ = *c++; -+ *buf++ = *c++; -+ *buf++ = *c++; -+ *buf++ = *c++; -+ continue; -+ } -+ else if (*c == '\\' || *c == '\'' || *c == '"') - *buf++ = '\\'; - - *buf++ = *c; -diff --git a/grub-core/script/execute.c b/grub-core/script/execute.c -index b5e6eb0..c44eced 100644 ---- a/grub-core/script/execute.c -+++ b/grub-core/script/execute.c -@@ -52,6 +52,12 @@ static struct grub_script_scope *scope = 0; - /* Wildcard translator for GRUB script. */ - struct grub_script_wildcard_translator *grub_wildcard_translator; - -+static int -+is_hex(char c) -+{ -+ return ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')); -+} -+ - static char* - wildcard_escape (const char *s) - { -@@ -68,7 +74,15 @@ wildcard_escape (const char *s) - i = 0; - while ((ch = *s++)) - { -- if (ch == '*' || ch == '\\' || ch == '?') -+ if (ch == '\\' && s[0] == 'x' && is_hex(s[1]) && is_hex(s[2])) -+ { -+ p[i++] = ch; -+ p[i++] = *s++; -+ p[i++] = *s++; -+ p[i++] = *s++; -+ continue; -+ } -+ else if (ch == '*' || ch == '\\' || ch == '?') - p[i++] = '\\'; - p[i++] = ch; - } -@@ -92,7 +106,14 @@ wildcard_unescape (const char *s) - i = 0; - while ((ch = *s++)) - { -- if (ch == '\\') -+ if (ch == '\\' && s[0] == 'x' && is_hex(s[1]) && is_hex(s[2])) -+ { -+ p[i++] = '\\'; -+ p[i++] = *s++; -+ p[i++] = *s++; -+ p[i++] = *s++; -+ } -+ else if (ch == '\\') - p[i++] = *s++; - else - p[i++] = ch; -@@ -381,14 +402,24 @@ parse_string (const char *str, - int escaped = 0; - const char *optr; - - for (ptr = str; ptr && *ptr; ) - switch (*ptr) - { - case '\\': -- escaped = !escaped; -- if (!escaped && put) -- *((*put)++) = '\\'; -- ptr++; -+ if (!escaped && put && *(ptr+1) == 'x' && is_hex(*(ptr+2)) && is_hex(*(ptr+3))) -+ { -+ *((*put)++) = *ptr++; -+ *((*put)++) = *ptr++; -+ *((*put)++) = *ptr++; -+ *((*put)++) = *ptr++; -+ } -+ else -+ { -+ escaped = !escaped; -+ if (!escaped && put) -+ *((*put)++) = '\\'; -+ ptr++; -+ } - break; - case '$': - if (escaped) --- -1.7.12.1 - diff --git a/grub-2.00-Issue-separate-DNS-queries-for-ipv4-and-ipv6.patch b/grub-2.00-Issue-separate-DNS-queries-for-ipv4-and-ipv6.patch deleted file mode 100644 index 953f2bd..0000000 --- a/grub-2.00-Issue-separate-DNS-queries-for-ipv4-and-ipv6.patch +++ /dev/null @@ -1,230 +0,0 @@ -From 3e00d82827f80461f9fe6da37acd84235c08e5a5 Mon Sep 17 00:00:00 2001 -From: Gustavo Luiz Duarte -Date: Fri, 28 Sep 2012 19:42:07 -0400 -Subject: [PATCH] Issue separate DNS queries for ipv4 and ipv6 - -Adding multiple questions on a single DNS query is not supportted by -most DNS servers. This patch issues two separate DNS queries -sequentially for ipv4 and then for ipv6. - -There are 4 possible config options: - DNS_OPTION_IPV4: issue only one ipv4 query - DNS_OPTION_IPV6: issue only one ipv6 query - DNS_OPTION_PREFER_IPV4: issue the ipv4 query first and fallback to ipv6 - DNS_OPTION_PREFER_IPV6: issue the ipv6 query first and fallback to ipv4 -However, there is no code yet to set such config option. The default is -DNS_OPTION_PREFER_IPV4. - -Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=860829 ---- - grub-core/net/dns.c | 99 ++++++++++++++++++++++++++++++++++++----------------- - include/grub/net.h | 9 +++++ - 2 files changed, 76 insertions(+), 32 deletions(-) - -diff --git a/grub-core/net/dns.c b/grub-core/net/dns.c -index 3381ea7..725725c 100644 ---- a/grub-core/net/dns.c -+++ b/grub-core/net/dns.c -@@ -34,6 +34,14 @@ struct dns_cache_element - #define DNS_CACHE_SIZE 1021 - #define DNS_HASH_BASE 423 - -+typedef enum grub_dns_qtype_id -+ { -+ GRUB_DNS_QTYPE_A = 1, -+ GRUB_DNS_QTYPE_AAAA = 28 -+ } grub_dns_qtype_id_t; -+ -+static grub_dns_option_t dns_type_option = DNS_OPTION_PREFER_IPV4; -+ - static struct dns_cache_element dns_cache[DNS_CACHE_SIZE]; - static struct grub_net_network_level_address *dns_servers; - static grub_size_t dns_nservers, dns_servers_alloc; -@@ -410,13 +418,13 @@ recv_hook (grub_net_udp_socket_t sock __attribute__ ((unused)), - return GRUB_ERR_NONE; - } - --grub_err_t --grub_net_dns_lookup (const char *name, -+static grub_err_t -+grub_net_dns_lookup_qtype (const char *name, - const struct grub_net_network_level_address *servers, - grub_size_t n_servers, - grub_size_t *naddresses, - struct grub_net_network_level_address **addresses, -- int cache) -+ int cache, grub_dns_qtype_id_t qtype) - { - grub_size_t send_servers = 0; - grub_size_t i, j; -@@ -471,8 +479,7 @@ grub_net_dns_lookup (const char *name, - + GRUB_NET_MAX_LINK_HEADER_SIZE - + GRUB_NET_UDP_HEADER_SIZE - + sizeof (struct dns_header) -- + grub_strlen (name) + 2 + 4 -- + 2 + 4); -+ + grub_strlen (name) + 2 + 4); - if (!nb) - { - grub_free (data.name); -@@ -482,7 +489,7 @@ grub_net_dns_lookup (const char *name, - + GRUB_NET_MAX_LINK_HEADER_SIZE - + GRUB_NET_UDP_HEADER_SIZE); - grub_netbuff_put (nb, sizeof (struct dns_header) -- + grub_strlen (name) + 2 + 4 + 2 + 4); -+ + grub_strlen (name) + 2 + 4); - head = (struct dns_header *) nb->data; - optr = (grub_uint8_t *) (head + 1); - for (iptr = name; *iptr; ) -@@ -509,18 +516,7 @@ grub_net_dns_lookup (const char *name, - - /* Type: A. */ - *optr++ = 0; -- *optr++ = 1; -- -- /* Class. */ -- *optr++ = 0; -- *optr++ = 1; -- -- /* Compressed name. */ -- *optr++ = 0xc0; -- *optr++ = 0x0c; -- /* Type: AAAA. */ -- *optr++ = 0; -- *optr++ = 28; -+ *optr++ = qtype; - - /* Class. */ - *optr++ = 0; -@@ -529,7 +525,7 @@ grub_net_dns_lookup (const char *name, - head->id = data.id; - head->flags = FLAGS_RD; - head->ra_z_r_code = 0; -- head->qdcount = grub_cpu_to_be16_compile_time (2); -+ head->qdcount = grub_cpu_to_be16_compile_time (1); - head->ancount = grub_cpu_to_be16_compile_time (0); - head->nscount = grub_cpu_to_be16_compile_time (0); - head->arcount = grub_cpu_to_be16_compile_time (0); -@@ -587,16 +583,47 @@ grub_net_dns_lookup (const char *name, - if (*data.naddresses) - return GRUB_ERR_NONE; - if (data.dns_err) -- return grub_error (GRUB_ERR_NET_NO_DOMAIN, -- N_("no DNS record found")); -- -+ { -+ grub_dprintf ("dns", "%s. QTYPE: %u QNAME: %s\n", -+ N_("no DNS record found"), qtype, name); -+ return GRUB_ERR_NET_NO_DOMAIN; -+ } - if (err) - { - grub_errno = err; - return err; - } -- return grub_error (GRUB_ERR_TIMEOUT, -- N_("no DNS reply received")); -+ grub_dprintf ("dns", "%s. QTYPE: %u QNAME: %s\n", -+ N_("no DNS reply received"), qtype, name); -+ return GRUB_ERR_TIMEOUT; -+} -+ -+grub_err_t -+grub_net_dns_lookup (const char *name, -+ const struct grub_net_network_level_address *servers, -+ grub_size_t n_servers, -+ grub_size_t *naddresses, -+ struct grub_net_network_level_address **addresses, -+ int cache) -+{ -+ if (dns_type_option == DNS_OPTION_IPV6 || dns_type_option == DNS_OPTION_PREFER_IPV6) -+ grub_net_dns_lookup_qtype (name, servers, n_servers, naddresses, -+ addresses, cache, GRUB_DNS_QTYPE_AAAA); -+ else -+ grub_net_dns_lookup_qtype (name, servers, n_servers, naddresses, -+ addresses, cache, GRUB_DNS_QTYPE_A); -+ if (!*naddresses) -+ { -+ if (dns_type_option == DNS_OPTION_PREFER_IPV4) -+ grub_net_dns_lookup_qtype (name, servers, n_servers, naddresses, -+ addresses, cache, GRUB_DNS_QTYPE_AAAA); -+ else if (dns_type_option == DNS_OPTION_PREFER_IPV6) -+ grub_net_dns_lookup_qtype (name, servers, n_servers, naddresses, -+ addresses, cache, GRUB_DNS_QTYPE_A); -+ } -+ if (!*naddresses) -+ return GRUB_ERR_NET_NO_DOMAIN; -+ return GRUB_ERR_NONE; - } - - static grub_err_t -@@ -604,22 +631,28 @@ grub_cmd_nslookup (struct grub_command *cmd __attribute__ ((unused)), - int argc, char **args) - { - grub_err_t err; -- grub_size_t naddresses, i; -+ struct grub_net_network_level_address cmd_server; -+ struct grub_net_network_level_address *servers; -+ grub_size_t nservers, i, naddresses = 0; - struct grub_net_network_level_address *addresses = 0; - if (argc != 2 && argc != 1) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("two arguments expected")); - if (argc == 2) - { -- struct grub_net_network_level_address server; -- err = grub_net_resolve_address (args[1], &server); -+ err = grub_net_resolve_address (args[1], &cmd_server); - if (err) - return err; -- err = grub_net_dns_lookup (args[0], &server, 1, &naddresses, -- &addresses, 0); -+ servers = &cmd_server; -+ nservers = 1; - } - else -- err = grub_net_dns_lookup (args[0], dns_servers, dns_nservers, &naddresses, -- &addresses, 0); -+ { -+ servers = dns_servers; -+ nservers = dns_nservers; -+ } -+ -+ grub_net_dns_lookup (args[0], servers, nservers, &naddresses, -+ &addresses, 0); - - for (i = 0; i < naddresses; i++) - { -@@ -628,7 +661,9 @@ grub_cmd_nslookup (struct grub_command *cmd __attribute__ ((unused)), - grub_printf ("%s\n", buf); - } - grub_free (addresses); -- return GRUB_ERR_NONE; -+ if (naddresses) -+ return GRUB_ERR_NONE; -+ return grub_error (GRUB_ERR_NET_NO_DOMAIN, N_("no DNS record found")); - } - - static grub_err_t -diff --git a/include/grub/net.h b/include/grub/net.h -index 3877451..a7e5b2c 100644 ---- a/include/grub/net.h -+++ b/include/grub/net.h -@@ -505,6 +505,15 @@ grub_err_t - grub_net_link_layer_resolve (struct grub_net_network_level_interface *inf, - const grub_net_network_level_address_t *proto_addr, - grub_net_link_level_address_t *hw_addr); -+ -+typedef enum -+ { -+ DNS_OPTION_IPV4, -+ DNS_OPTION_IPV6, -+ DNS_OPTION_PREFER_IPV4, -+ DNS_OPTION_PREFER_IPV6 -+ } grub_dns_option_t; -+ - grub_err_t - grub_net_dns_lookup (const char *name, - const struct grub_net_network_level_address *servers, --- -1.7.11.4 - diff --git a/grub-2.00-add-GRUB-DISABLE-SUBMENU-option.patch b/grub-2.00-add-GRUB-DISABLE-SUBMENU-option.patch deleted file mode 100644 index 1fd1630..0000000 --- a/grub-2.00-add-GRUB-DISABLE-SUBMENU-option.patch +++ /dev/null @@ -1,80 +0,0 @@ -From 81e46875469ae8b2a803e6457784801a0a7a7963 Mon Sep 17 00:00:00 2001 -From: Prarit Bhargava -Date: Thu, 7 Feb 2013 11:53:41 -0500 -Subject: [PATCH] add GRUB_DISABLE_SUBMENU option - -This patch adds the ability to disable the grub2 submenus from -/etc/default/grub - -To disable the submenus - -echo 'GRUB_DISABLE_SUBMENU="true"' >> /etc/default/grub - - ---- - util/grub-mkconfig.in | 3 ++- - util/grub.d/10_linux.in | 24 ++++++++++++++---------- - 2 files changed, 16 insertions(+), 11 deletions(-) - -diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in -index 516be86..354eb43 100644 ---- a/util/grub-mkconfig.in -+++ b/util/grub-mkconfig.in -@@ -216,7 +216,8 @@ export GRUB_DEFAULT \ - GRUB_INIT_TUNE \ - GRUB_SAVEDEFAULT \ - GRUB_ENABLE_CRYPTODISK \ -- GRUB_BADRAM -+ GRUB_BADRAM \ -+ GRUB_DISABLE_SUBMENU - - if test "x${grub_cfg}" != "x"; then - rm -f "${grub_cfg}.new" -diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in -index e2b8ab3..9427a39 100644 ---- a/util/grub.d/10_linux.in -+++ b/util/grub.d/10_linux.in -@@ -240,17 +240,19 @@ while [ "x$list" != "x" ] ; do - linux_root_device_thisversion=${GRUB_DEVICE} - fi - -- if [ "x$is_first_entry" = xtrue ]; then -- linux_entry "${OS}" "${version}" simple \ -- "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}" -+ if [ "x${GRUB_DISABLE_SUBMENU}" = x ]; then -+ if [ "x$is_first_entry" = xtrue ]; then -+ linux_entry "${OS}" "${version}" simple \ -+ "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}" - -- submenu_indentation="\t" -+ submenu_indentation="\t" - -- if [ -z "$boot_device_id" ]; then -- boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")" -+ if [ -z "$boot_device_id" ]; then -+ boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")" -+ fi -+ # TRANSLATORS: %s is replaced with an OS name -+ echo "submenu '$(gettext_printf "Advanced options for %s" "${OS}" | grub_quote)' \$menuentry_id_option 'gnulinux-advanced-$boot_device_id' {" - fi -- # TRANSLATORS: %s is replaced with an OS name -- echo "submenu '$(gettext_printf "Advanced options for %s" "${OS}" | grub_quote)' \$menuentry_id_option 'gnulinux-advanced-$boot_device_id' {" - fi - - linux_entry "${OS}" "${version}" advanced \ -@@ -266,8 +268,10 @@ done - - # If at least one kernel was found, then we need to - # add a closing '}' for the submenu command. --if [ x"$is_first_entry" != xtrue ]; then -- echo '}' -+if [ "x${GRUB_DISABLE_SUBMENU}" = x ]; then -+ if [ x"$is_first_entry" != xtrue ]; then -+ echo '}' -+ fi - fi - - echo "$title_correction_code" --- -1.8.1 - diff --git a/grub-2.00-add-X-option-to-printf-functions.patch b/grub-2.00-add-X-option-to-printf-functions.patch deleted file mode 100644 index 63d7b79..0000000 --- a/grub-2.00-add-X-option-to-printf-functions.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 80f81f233bf74aac740d7a299d075ea46c9c7bd4 Mon Sep 17 00:00:00 2001 -From: Paulo Flabiano Smorigo -Date: Tue, 27 Nov 2012 16:58:39 -0200 -Subject: [PATCH 1/3] Add %X option to printf functions. - ---- - grub-core/kern/misc.c | 7 +++++-- - 1 file changed, 5 insertions(+), 2 deletions(-) - -diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c -index 95d4624..8ac087a 100644 ---- a/grub-core/kern/misc.c -+++ b/grub-core/kern/misc.c -@@ -596,7 +596,7 @@ grub_divmod64 (grub_uint64_t n, grub_uint64_t d, grub_uint64_t *r) - static char * - grub_lltoa (char *str, int c, unsigned long long n) - { -- unsigned base = (c == 'x') ? 16 : 10; -+ unsigned base = ((c == 'x') || (c == 'X')) ? 16 : 10; - char *p; - - if ((long long) n < 0 && c == 'd') -@@ -611,7 +611,7 @@ grub_lltoa (char *str, int c, unsigned long long n) - do - { - unsigned d = (unsigned) (n & 0xf); -- *p++ = (d > 9) ? d + 'a' - 10 : d + '0'; -+ *p++ = (d > 9) ? d + ((c == 'x') ? 'a' : 'A') - 10 : d + '0'; - } - while (n >>= 4); - else -@@ -702,6 +702,7 @@ grub_vsnprintf_real (char *str, grub_size_t max_len, const char *fmt0, va_list a - { - case 'p': - case 'x': -+ case 'X': - case 'u': - case 'd': - case 'c': -@@ -777,6 +778,7 @@ grub_vsnprintf_real (char *str, grub_size_t max_len, const char *fmt0, va_list a - switch (c) - { - case 'x': -+ case 'X': - case 'u': - case 'd': - if (longlongfmt) -@@ -918,6 +920,7 @@ grub_vsnprintf_real (char *str, grub_size_t max_len, const char *fmt0, va_list a - longlongfmt |= (sizeof (void *) == sizeof (long long)); - /* Fall through. */ - case 'x': -+ case 'X': - case 'u': - unsig = 1; - /* Fall through. */ --- -1.7.10.4 - diff --git a/grub-2.00-add-fw_path-search_v2.patch b/grub-2.00-add-fw_path-search_v2.patch deleted file mode 100644 index c7857c3..0000000 --- a/grub-2.00-add-fw_path-search_v2.patch +++ /dev/null @@ -1,88 +0,0 @@ -From 40d6b00fa48ae9c1cecf143da5c6061f6ffcb719 Mon Sep 17 00:00:00 2001 -From: Paulo Flabiano Smorigo -Date: Wed, 19 Sep 2012 21:22:55 -0300 -Subject: [PATCH] Add fw_path variable (revised) - -This patch makes grub look for its config file on efi where the app was -found. It was originally written by Matthew Garrett, and adapted to fix the -"No modules are loaded on grub2 network boot" issue: - -https://bugzilla.redhat.com/show_bug.cgi?id=857936 ---- - grub-core/kern/main.c | 16 ++++++++++++++-- - grub-core/normal/main.c | 25 ++++++++++++++++++++++++- - 2 files changed, 38 insertions(+), 3 deletions(-) - -diff --git a/grub-core/kern/main.c b/grub-core/kern/main.c -index 3262444..820fd66 100644 ---- a/grub-core/kern/main.c -+++ b/grub-core/kern/main.c -@@ -114,6 +114,20 @@ grub_set_prefix_and_root (void) - - grub_register_variable_hook ("root", 0, grub_env_write_root); - -+ grub_machine_get_bootlocation (&fwdevice, &fwpath); -+ -+ if (fwdevice && fwpath) -+ { -+ char *fw_path; -+ -+ fw_path = grub_xasprintf ("(%s)/%s", fwdevice, fwpath); -+ if (fw_path) -+ { -+ grub_env_set ("fw_path", fw_path); -+ grub_free (fw_path); -+ } -+ } -+ - if (prefix) - { - char *pptr = NULL; -@@ -131,8 +145,6 @@ grub_set_prefix_and_root (void) - if (pptr[0]) - path = grub_strdup (pptr); - } -- if ((!device || device[0] == ',' || !device[0]) || !path) -- grub_machine_get_bootlocation (&fwdevice, &fwpath); - - if (!device && fwdevice) - device = fwdevice; -diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c -index 13473ec..39bb734 100644 ---- a/grub-core/normal/main.c -+++ b/grub-core/normal/main.c -@@ -333,7 +333,30 @@ grub_cmd_normal (struct grub_command *cmd __attribute__ ((unused)), - /* Guess the config filename. It is necessary to make CONFIG static, - so that it won't get broken by longjmp. */ - char *config; -- const char *prefix; -+ const char *prefix, *fw_path; -+ -+ fw_path = grub_env_get ("fw_path"); -+ if (fw_path) -+ { -+ config = grub_xasprintf ("%s/grub.cfg", fw_path); -+ if (config) -+ { -+ grub_file_t file; -+ -+ file = grub_file_open (config); -+ if (file) -+ { -+ grub_file_close (file); -+ grub_enter_normal_mode (config); -+ } -+ else -+ { -+ /* Ignore all errors. */ -+ grub_errno = 0; -+ } -+ grub_free (config); -+ } -+ } - - prefix = grub_env_get ("prefix"); - if (prefix) --- -1.7.10.4 - diff --git a/grub-2.00-cas-reboot-support.patch b/grub-2.00-cas-reboot-support.patch deleted file mode 100644 index f0085a4..0000000 --- a/grub-2.00-cas-reboot-support.patch +++ /dev/null @@ -1,174 +0,0 @@ -From be9ee2df83a927d49184026154dd8d5039a8b664 Mon Sep 17 00:00:00 2001 -From: Paulo Flabiano Smorigo -Date: Thu, 20 Sep 2012 18:07:39 -0300 -Subject: [PATCH] IBM client architecture (CAS) reboot support - -This is an implementation of IBM client architecture (CAS) reboot for GRUB. - -There are cases where the POWER firmware must reboot in order to support -specific features requested by a kernel. The kernel calls -ibm,client-architecture-support and it may either return or reboot with the new -feature set. eg: - -Calling ibm,client-architecture-support.../ -Elapsed time since release of system processors: 70959 mins 50 secs -Welcome to GRUB! - -Instead of return to the GRUB menu, it will check if the flag for CAS reboot is -set. If so, grub will automatically boot the last booted kernel using the same -parameters ---- - grub-core/kern/ieee1275/openfw.c | 63 ++++++++++++++++++++++++++++++++++++++ - grub-core/normal/main.c | 19 ++++++++++++ - grub-core/script/execute.c | 7 +++++ - include/grub/ieee1275/ieee1275.h | 2 ++ - 4 files changed, 91 insertions(+) - -diff --git a/grub-core/kern/ieee1275/openfw.c b/grub-core/kern/ieee1275/openfw.c -index 40abaa3..c2b1bdf 100644 ---- a/grub-core/kern/ieee1275/openfw.c -+++ b/grub-core/kern/ieee1275/openfw.c -@@ -523,3 +523,66 @@ grub_ieee1275_canonicalise_devname (const char *path) - return NULL; - } - -+/* Check if it's a CAS reboot. If so, set the script to be executed. */ -+int -+grub_ieee1275_cas_reboot (char *script) -+{ -+ grub_uint32_t ibm_ca_support_reboot; -+ grub_uint32_t ibm_fw_nbr_reboots; -+ char property_value[10]; -+ grub_ssize_t actual; -+ grub_ieee1275_ihandle_t options; -+ -+ if (grub_ieee1275_finddevice ("/options", &options) < 0) -+ return -1; -+ -+ /* Check two properties, one is enough to get cas reboot value */ -+ ibm_ca_support_reboot = 0; -+ if (grub_ieee1275_get_integer_property (grub_ieee1275_chosen, -+ "ibm,client-architecture-support-reboot", -+ &ibm_ca_support_reboot, -+ sizeof (ibm_ca_support_reboot), -+ &actual) >= 0) -+ grub_dprintf("ieee1275", "ibm,client-architecture-support-reboot: %u\n", -+ ibm_ca_support_reboot); -+ -+ ibm_fw_nbr_reboots = 0; -+ if (grub_ieee1275_get_property (options, "ibm,fw-nbr-reboots", -+ property_value, sizeof (property_value), -+ &actual) >= 0) -+ { -+ property_value[sizeof (property_value) - 1] = 0; -+ ibm_fw_nbr_reboots = (grub_uint8_t) grub_strtoul (property_value, 0, 10); -+ grub_dprintf("ieee1275", "ibm,fw-nbr-reboots: %u\n", ibm_fw_nbr_reboots); -+ } -+ -+ if (ibm_ca_support_reboot || ibm_fw_nbr_reboots) -+ { -+ if (! grub_ieee1275_get_property_length (options, "boot-last-label", &actual)) -+ { -+ if (actual > 1024) -+ script = grub_realloc (script, actual + 1); -+ grub_ieee1275_get_property (options, "boot-last-label", script, actual, -+ &actual); -+ return 0; -+ } -+ } -+ -+ grub_ieee1275_set_boot_last_label (""); -+ -+ return -1; -+} -+ -+int grub_ieee1275_set_boot_last_label (const char *text) -+{ -+ grub_ieee1275_ihandle_t options; -+ grub_ssize_t actual; -+ -+ grub_dprintf("ieee1275", "set boot_last_label (size: %u)\n", grub_strlen(text)); -+ if (! grub_ieee1275_finddevice ("/options", &options) && -+ options != (grub_ieee1275_ihandle_t) -1) -+ grub_ieee1275_set_property (options, "boot-last-label", text, -+ grub_strlen (text), &actual); -+ return 0; -+} -+ -diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c -index 39bb734..aa0b3e5 100644 ---- a/grub-core/normal/main.c -+++ b/grub-core/normal/main.c -@@ -32,6 +32,9 @@ - #include - #include - #include -+#ifdef GRUB_MACHINE_IEEE1275 -+#include -+#endif - - GRUB_MOD_LICENSE ("GPLv3+"); - -@@ -296,6 +299,22 @@ grub_normal_execute (const char *config, int nested, int batch) - { - menu = read_config_file (config); - -+#ifdef GRUB_MACHINE_IEEE1275 -+ int boot; -+ boot = 0; -+ char *script; -+ script = grub_malloc (1024); -+ if (! grub_ieee1275_cas_reboot (script)) -+ { -+ char *dummy[1] = { NULL }; -+ if (! grub_script_execute_sourcecode (script, 0, dummy)) -+ boot = 1; -+ } -+ grub_free (script); -+ if (boot) -+ grub_command_execute ("boot", 0, 0); -+#endif -+ - /* Ignore any error. */ - grub_errno = GRUB_ERR_NONE; - } -diff --git a/grub-core/script/execute.c b/grub-core/script/execute.c -index b5e6eb0..4397540 100644 ---- a/grub-core/script/execute.c -+++ b/grub-core/script/execute.c -@@ -27,6 +27,9 @@ - #include - #include - #include -+#ifdef GRUB_MACHINE_IEEE1275 -+#include -+#endif - - /* 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. */ -@@ -820,6 +823,10 @@ grub_script_execute_sourcecode (const char *source, int argc, char **args) - old_scope = scope; - scope = &new_scope; - -+#ifdef GRUB_MACHINE_IEEE1275 -+ grub_ieee1275_set_boot_last_label (source); -+#endif -+ - while (source) - { - char *line; -diff --git a/include/grub/ieee1275/ieee1275.h b/include/grub/ieee1275/ieee1275.h -index 38a75fd..416a544 100644 ---- a/include/grub/ieee1275/ieee1275.h -+++ b/include/grub/ieee1275/ieee1275.h -@@ -208,5 +208,7 @@ int EXPORT_FUNC(grub_ieee1275_devices_iterate) (int (*hook) - char *EXPORT_FUNC(grub_ieee1275_get_aliasdevname) (const char *path); - char *EXPORT_FUNC(grub_ieee1275_canonicalise_devname) (const char *path); - char *EXPORT_FUNC(grub_ieee1275_get_device_type) (const char *path); -+int EXPORT_FUNC(grub_ieee1275_cas_reboot) (char *script); -+int EXPORT_FUNC(grub_ieee1275_set_boot_last_label) (const char *text); - - #endif /* ! GRUB_IEEE1275_HEADER */ --- -1.7.10.4 - diff --git a/grub-2.00-dhcp-client-id-and-uuid-options-added.patch b/grub-2.00-dhcp-client-id-and-uuid-options-added.patch deleted file mode 100644 index c573936..0000000 --- a/grub-2.00-dhcp-client-id-and-uuid-options-added.patch +++ /dev/null @@ -1,121 +0,0 @@ -From d63a0b7fd665fae1dd34d3e86127b93dd87b8114 Mon Sep 17 00:00:00 2001 -From: Paulo Flabiano Smorigo -Date: Tue, 27 Nov 2012 17:18:53 -0200 -Subject: [PATCH 2/3] DHCP client ID and UUID options added. - ---- - grub-core/net/bootp.c | 56 +++++++++++++++++++++++++++++++++++++++++-------- - include/grub/net.h | 2 ++ - 2 files changed, 49 insertions(+), 9 deletions(-) - -diff --git a/grub-core/net/bootp.c b/grub-core/net/bootp.c -index bc07d53..3b4130d 100644 ---- a/grub-core/net/bootp.c -+++ b/grub-core/net/bootp.c -@@ -51,6 +51,14 @@ set_env_limn_ro (const char *intername, const char *suffix, - grub_register_variable_hook (varname, 0, grub_env_write_readonly); - } - -+static char -+hexdigit (grub_uint8_t val) -+{ -+ if (val < 10) -+ return val + '0'; -+ return val + 'a' - 10; -+} -+ - static void - parse_dhcp_vendor (const char *name, void *vend, int limit, int *mask) - { -@@ -81,6 +89,9 @@ parse_dhcp_vendor (const char *name, void *vend, int limit, int *mask) - - taglength = *ptr++; - -+ grub_dprintf("net", "DHCP option %u (0x%02x) found with length %u.\n", -+ tagtype, tagtype, taglength); -+ - switch (tagtype) - { - case GRUB_NET_BOOTP_NETMASK: -@@ -121,7 +132,9 @@ parse_dhcp_vendor (const char *name, void *vend, int limit, int *mask) - grub_net_add_dns_server (&s); - ptr += 4; - } -- } -+ /* Skip adittional increment */ -+ continue; -+ } - break; - case GRUB_NET_BOOTP_HOSTNAME: - set_env_limn_ro (name, "hostname", (char *) ptr, taglength); -@@ -139,6 +152,39 @@ parse_dhcp_vendor (const char *name, void *vend, int limit, int *mask) - set_env_limn_ro (name, "extensionspath", (char *) ptr, taglength); - break; - -+ case GRUB_NET_BOOTP_CLIENT_ID: -+ set_env_limn_ro (name, "clientid", (char *) ptr, taglength); -+ break; -+ -+ case GRUB_NET_BOOTP_CLIENT_UUID: -+ { -+ if (taglength != 17) -+ break; -+ -+ /* The format is 9cfe245e-d0c8-bd45-a79f-54ea5fbd3d97 */ -+ -+ ptr += 1; -+ taglength -= 1; -+ -+ char *val = grub_malloc (2 * taglength + 4 + 1); -+ int i = 0; -+ int j = 0; -+ for (i = 0; i < taglength; i++) -+ { -+ val[2 * i + j] = hexdigit (ptr[i] >> 4); -+ val[2 * i + 1 + j] = hexdigit (ptr[i] & 0xf); -+ -+ if ((i == 3) || (i == 5) || (i == 7) || (i == 9)) -+ { -+ j++; -+ val[2 * i + 1+ j] = '-'; -+ } -+ } -+ -+ set_env_limn_ro (name, "clientuuid", (char *) val, 2 * taglength + 4); -+ } -+ break; -+ - /* If you need any other options please contact GRUB - developpement team. */ - } -@@ -299,14 +345,6 @@ grub_net_process_dhcp (struct grub_net_buff *nb, - } - } - --static char --hexdigit (grub_uint8_t val) --{ -- if (val < 10) -- return val + '0'; -- return val + 'a' - 10; --} -- - static grub_err_t - grub_cmd_dhcpopt (struct grub_command *cmd __attribute__ ((unused)), - int argc, char **args) -diff --git a/include/grub/net.h b/include/grub/net.h -index a7e5b2c..45348dd 100644 ---- a/include/grub/net.h -+++ b/include/grub/net.h -@@ -423,6 +423,8 @@ enum - GRUB_NET_BOOTP_DOMAIN = 0x0f, - GRUB_NET_BOOTP_ROOT_PATH = 0x11, - GRUB_NET_BOOTP_EXTENSIONS_PATH = 0x12, -+ GRUB_NET_BOOTP_CLIENT_ID = 0x3d, -+ GRUB_NET_BOOTP_CLIENT_UUID = 0x61, - GRUB_NET_BOOTP_END = 0xff - }; - --- -1.7.10.4 - diff --git a/grub-2.00-dont-decrease-mmap-size.patch b/grub-2.00-dont-decrease-mmap-size.patch deleted file mode 100644 index 8139fc2..0000000 --- a/grub-2.00-dont-decrease-mmap-size.patch +++ /dev/null @@ -1,34 +0,0 @@ -From: Stuart Hayes -Subject: Don't decrease efi memory map size -Date: 2012-07-02 09:14:37 +0000 - - - ---- a/grub-core/loader/i386/linux.c 2012-06-27 20:55:09 +0000 -+++ b/grub-core/loader/i386/linux.c 2012-07-02 09:14:37 +0000 -@@ -118,12 +118,13 @@ - int ret; - grub_efi_memory_descriptor_t *mmap; - grub_efi_uintn_t desc_size; -+ grub_efi_uintn_t cur_mmap_size = mmap_size; - -- mmap = grub_malloc (mmap_size); -+ mmap = grub_malloc (cur_mmap_size); - if (! mmap) - return 0; - -- ret = grub_efi_get_memory_map (&mmap_size, mmap, 0, &desc_size, 0); -+ ret = grub_efi_get_memory_map (&cur_mmap_size, mmap, 0, &desc_size, 0); - grub_free (mmap); - - if (ret < 0) -@@ -134,6 +135,8 @@ - else if (ret > 0) - break; - -+ if (mmap_size < cur_mmap_size) -+ mmap_size = cur_mmap_size; - mmap_size += (1 << 12); - } - - diff --git a/grub-2.00-efidisk-ahci-workaround.patch b/grub-2.00-efidisk-ahci-workaround.patch deleted file mode 100644 index 36a91c8..0000000 --- a/grub-2.00-efidisk-ahci-workaround.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 61474615b8e177881caa89fc04cae16019cf01b9 Mon Sep 17 00:00:00 2001 -From: Matthew Garrett -Date: Wed, 15 Aug 2012 14:37:07 -0400 -Subject: [PATCH] efidisk: Read chunks in smaller blocks - ---- - grub-core/disk/efi/efidisk.c | 26 ++++++++++++++++++++++---- - 1 file changed, 22 insertions(+), 4 deletions(-) - -diff --git a/grub-core/disk/efi/efidisk.c b/grub-core/disk/efi/efidisk.c -index a432b44..77ab5b0 100644 ---- a/grub-core/disk/efi/efidisk.c -+++ b/grub-core/disk/efi/efidisk.c -@@ -546,6 +546,9 @@ grub_efidisk_read (struct grub_disk *disk, grub_disk_addr_t sector, - struct grub_efidisk_data *d; - grub_efi_block_io_t *bio; - grub_efi_status_t status; -+ grub_size_t remaining = size; -+ grub_size_t read = 0; -+ grub_size_t chunk = 0x500; - - d = disk->data; - bio = d->block_io; -@@ -554,14 +557,29 @@ grub_efidisk_read (struct grub_disk *disk, grub_disk_addr_t sector, - "reading 0x%lx sectors at the sector 0x%llx from %s\n", - (unsigned long) size, (unsigned long long) sector, disk->name); - -+ while (remaining > chunk) { -+ status = efi_call_5 (bio->read_blocks, bio, bio->media->media_id, -+ (grub_efi_uint64_t) sector + read, -+ (grub_efi_uintn_t) chunk << disk->log_sector_size, -+ buf + (read << disk->log_sector_size)); -+ if (status != GRUB_EFI_SUCCESS) -+ return grub_error (GRUB_ERR_READ_ERROR, -+ N_("failure reading sector 0x%llx from `%s'"), -+ (unsigned long long) sector + read, -+ disk->name); -+ read += chunk; -+ remaining -= chunk; -+ } -+ - status = efi_call_5 (bio->read_blocks, bio, bio->media->media_id, -- (grub_efi_uint64_t) sector, -- (grub_efi_uintn_t) size << disk->log_sector_size, -- buf); -+ (grub_efi_uint64_t) sector + read, -+ (grub_efi_uintn_t) remaining << disk->log_sector_size, -+ buf + (read << disk->log_sector_size)); -+ - if (status != GRUB_EFI_SUCCESS) - return grub_error (GRUB_ERR_READ_ERROR, - N_("failure reading sector 0x%llx from `%s'"), -- (unsigned long long) sector, -+ (unsigned long long) sector + read, - disk->name); - - return GRUB_ERR_NONE; --- -1.7.11.2 - diff --git a/grub-2.00-fix-http-crash.patch b/grub-2.00-fix-http-crash.patch deleted file mode 100644 index ac110c3..0000000 --- a/grub-2.00-fix-http-crash.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 4414df5e72937b0bb1c4a0bb66cd1132ec2a5720 Mon Sep 17 00:00:00 2001 -From: Gustavo Luiz Duarte -Date: Tue, 25 Sep 2012 18:40:55 -0400 -Subject: [PATCH] Fix crash on http - -Don't free file->data on receiving FIN flag since it is used all over without -checking. http_close() will be called later to free that memory. -https://bugzilla.redhat.com/show_bug.cgi?id=860834 ---- - grub-core/net/http.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/grub-core/net/http.c b/grub-core/net/http.c -index a7542d1..a5f6f31 100644 ---- a/grub-core/net/http.c -+++ b/grub-core/net/http.c -@@ -386,7 +386,7 @@ http_establish (struct grub_file *file, grub_off_t offset, int initial) - - data->sock = grub_net_tcp_open (file->device->net->server, - HTTP_PORT, http_receive, -- http_err, http_err, -+ http_err, NULL, - file); - if (!data->sock) - { --- -1.7.11.4 - diff --git a/grub-2.00-for-ppc-include-all-modules-in-the-core-image.patch b/grub-2.00-for-ppc-include-all-modules-in-the-core-image.patch deleted file mode 100644 index 1244650..0000000 --- a/grub-2.00-for-ppc-include-all-modules-in-the-core-image.patch +++ /dev/null @@ -1,332 +0,0 @@ -From 4613775aee8b413ba89bfb7233d49a4288e13390 Mon Sep 17 00:00:00 2001 -From: Paulo Flabiano Smorigo -Date: Mon, 15 Oct 2012 17:21:01 -0300 -Subject: [PATCH] for ppc, include all modules in the core image - -This patch implements the solution suggested by Gustavo Luiz Duarte -: - -Adding more modules to be built-in to the grub core ELF is easy. It is a -parameter passed by grub2-install to grub2-mkimage. However, there is a downside -on adding many modules to the core ELF: they are fully initialized in the grub's -first stage. It means you could hit a bug on a module you don't need and end up -with a non-bootable system. - -Another downside is that you wouldn't get updates for these built-in modules, as -updating the grub2 package only updates the modules residing in /boot and not -the grub core ELF in the PReP partition. - -A proper solution would be to add to grub the ability of having built-in -*inactive* modules which would be loaded and initialized only on demand (i.e. -explicitly calling the insmod command). - -This patch fix this bugzilla: -https://bugzilla.redhat.com/show_bug.cgi?id=866559 ---- - grub-core/kern/corecmd.c | 3 ++ - grub-core/kern/dl.c | 67 ++++++++++++++++++++++++++++++++++++++++--- - include/grub/dl.h | 1 + - include/grub/kernel.h | 1 + - include/grub/util/resolve.h | 5 ++++ - util/grub-mkimage.c | 37 +++++++++++++++++++++++- - util/resolve.c | 57 ++++++++++++++++++++++++++++++++++++ - 7 files changed, 166 insertions(+), 5 deletions(-) - -diff --git a/grub-core/kern/corecmd.c b/grub-core/kern/corecmd.c -index 16c03df..8684139 100644 ---- a/grub-core/kern/corecmd.c -+++ b/grub-core/kern/corecmd.c -@@ -100,6 +100,9 @@ grub_core_cmd_insmod (struct grub_command *cmd __attribute__ ((unused)), - else - mod = grub_dl_load (argv[0]); - -+ if (!mod) -+ grub_dl_load_core_by_name (argv[0]); -+ - if (mod) - grub_dl_ref (mod); - -diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c -index 5b0aa65..a498682 100644 ---- a/grub-core/kern/dl.c -+++ b/grub-core/kern/dl.c -@@ -32,6 +32,7 @@ - #include - #include - #include -+#include - - /* Platforms where modules are in a readonly area of memory. */ - #if defined(GRUB_MACHINE_QEMU) -@@ -47,6 +48,7 @@ - #pragma GCC diagnostic ignored "-Wcast-align" - - grub_dl_t grub_dl_head = 0; -+char grub_use_stale_modules = 0; - - grub_err_t - grub_dl_add (grub_dl_t mod); -@@ -659,6 +661,57 @@ grub_dl_load_core (void *addr, grub_size_t size) - return mod; - } - -+/* Load a module from core using a symbolic name. */ -+grub_dl_t -+grub_dl_load_core_by_name (const char *name) -+{ -+ struct grub_module_header *header; -+ grub_dl_t mod; -+ char *module_addr; -+ -+ mod = (grub_dl_t) grub_zalloc (sizeof (*mod)); -+ if (! mod) -+ return 0; -+ -+ grub_use_stale_modules = 1; -+ -+ FOR_MODULES (header) -+ { -+ /* Not an ELF module, skip. */ -+ if ((header->type != OBJ_TYPE_ELF) && -+ (header->type != OBJ_TYPE_ELF_STALE)) -+ continue; -+ -+ module_addr = (char *) header + sizeof (struct grub_module_header); -+ grub_dl_resolve_name (mod, (Elf_Ehdr *) module_addr); -+ -+ if (grub_strcmp(name, mod->name) == 0) -+ { -+ grub_printf ("WARNING: You are using the built-in '%s' module!\n", name); -+ -+ mod = grub_dl_load_core ((char *) header + sizeof (struct grub_module_header), -+ (header->size - sizeof (struct grub_module_header))); -+ -+ break; -+ } -+ else -+ mod = 0; -+ } -+ -+ if (! mod) -+ return 0; -+ else -+ { -+ if (grub_errno == GRUB_ERR_IO) -+ grub_errno = GRUB_ERR_NONE; -+ } -+ -+ if (grub_strcmp (mod->name, name) != 0) -+ grub_error (GRUB_ERR_BAD_MODULE, "mismatched names"); -+ -+ return mod; -+} -+ - /* Load a module from the file FILENAME. */ - grub_dl_t - grub_dl_load_file (const char *filename) -@@ -718,13 +771,19 @@ grub_dl_load (const char *name) - return 0; - } - -+ /* First, try to load module from the grub directory */ - filename = grub_xasprintf ("%s/" GRUB_TARGET_CPU "-" GRUB_PLATFORM "/%s.mod", - grub_dl_dir, name); -- if (! filename) -- return 0; -+ if (filename) -+ { -+ mod = grub_dl_load_file (filename); -+ grub_free (filename); -+ } - -- mod = grub_dl_load_file (filename); -- grub_free (filename); -+ /* If the module isn't loaded, check if there is a stale module available and -+ * use it*/ -+ if (! mod && grub_use_stale_modules) -+ mod = grub_dl_load_core_by_name (name); - - if (! mod) - return 0; -diff --git a/include/grub/dl.h b/include/grub/dl.h -index 3119978..30f12f9 100644 ---- a/include/grub/dl.h -+++ b/include/grub/dl.h -@@ -181,6 +181,7 @@ typedef struct grub_dl *grub_dl_t; - grub_dl_t grub_dl_load_file (const char *filename); - grub_dl_t EXPORT_FUNC(grub_dl_load) (const char *name); - grub_dl_t grub_dl_load_core (void *addr, grub_size_t size); -+grub_dl_t grub_dl_load_core_by_name (const char *name); - int EXPORT_FUNC(grub_dl_unload) (grub_dl_t mod); - void grub_dl_unload_unneeded (void); - int EXPORT_FUNC(grub_dl_ref) (grub_dl_t mod); -diff --git a/include/grub/kernel.h b/include/grub/kernel.h -index eef4c3f..4cd2cb0 100644 ---- a/include/grub/kernel.h -+++ b/include/grub/kernel.h -@@ -25,6 +25,7 @@ - enum - { - OBJ_TYPE_ELF, -+ OBJ_TYPE_ELF_STALE, - OBJ_TYPE_MEMDISK, - OBJ_TYPE_CONFIG, - OBJ_TYPE_PREFIX -diff --git a/include/grub/util/resolve.h b/include/grub/util/resolve.h -index f42df32..1d0252c 100644 ---- a/include/grub/util/resolve.h -+++ b/include/grub/util/resolve.h -@@ -32,4 +32,9 @@ grub_util_resolve_dependencies (const char *prefix, - const char *dep_list_file, - char *modules[]); - -+struct grub_util_path_list * -+grub_util_create_complementary_module_list (const char *prefix, -+ const char *dep_list_file, -+ struct grub_util_path_list *path_list); -+ - #endif /* ! GRUB_UTIL_RESOLVE_HEADER */ -diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c -index a551bbb..b06f37a 100644 ---- a/util/grub-mkimage.c -+++ b/util/grub-mkimage.c -@@ -711,7 +711,7 @@ generate_image (const char *dir, const char *prefix, - size_t prefix_size = 0; - char *kernel_path; - size_t offset; -- struct grub_util_path_list *path_list, *p, *next; -+ struct grub_util_path_list *path_list, *path_list_comp = 0, *p, *next; - grub_size_t bss_size; - grub_uint64_t start_address; - void *rel_section = 0; -@@ -727,6 +727,10 @@ generate_image (const char *dir, const char *prefix, - - path_list = grub_util_resolve_dependencies (dir, "moddep.lst", mods); - -+ if (image_target->id == IMAGE_PPC) -+ path_list_comp = grub_util_create_complementary_module_list (dir, -+ "moddep.lst", path_list); -+ - kernel_path = grub_util_get_path (dir, "kernel.img"); - - if (image_target->voidp_sizeof == 8) -@@ -761,6 +765,10 @@ generate_image (const char *dir, const char *prefix, - total_module_size += (ALIGN_ADDR (grub_util_get_image_size (p->name)) - + sizeof (struct grub_module_header)); - -+ for (p = path_list_comp; p; p = p->next) -+ 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%llx", - (unsigned long long) total_module_size); - -@@ -835,6 +843,25 @@ generate_image (const char *dir, const char *prefix, - offset += mod_size; - } - -+ for (p = path_list_comp; p; p = p->next) -+ { -+ struct grub_module_header *header; -+ size_t mod_size, orig_size; -+ -+ orig_size = grub_util_get_image_size (p->name); -+ mod_size = ALIGN_ADDR (orig_size); -+ -+ header = (struct grub_module_header *) (kernel_img + offset); -+ memset (header, 0, sizeof (struct grub_module_header)); -+ header->type = grub_host_to_target32 (OBJ_TYPE_ELF_STALE); -+ 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; -+ } -+ - if (memdisk_path) - { - struct grub_module_header *header; -@@ -1639,6 +1666,14 @@ generate_image (const char *dir, const char *prefix, - free (path_list); - path_list = next; - } -+ -+ while (path_list_comp) -+ { -+ next = path_list_comp->next; -+ free ((void *) path_list_comp->name); -+ free (path_list_comp); -+ path_list_comp = next; -+ } - } - - -diff --git a/util/resolve.c b/util/resolve.c -index 1af24e6..997db99 100644 ---- a/util/resolve.c -+++ b/util/resolve.c -@@ -271,3 +271,60 @@ grub_util_resolve_dependencies (const char *prefix, - return prev; - } - } -+ -+struct grub_util_path_list * -+grub_util_create_complementary_module_list (const char *prefix, -+ const char *dep_list_file, -+ struct grub_util_path_list *path_list) -+{ -+ char *path; -+ FILE *fp; -+ struct grub_util_path_list *path_list_comp = 0; -+ struct grub_util_path_list *new_path; -+ char skip; -+ -+ path = grub_util_get_path (prefix, dep_list_file); -+ fp = fopen (path, "r"); -+ if (! fp) -+ grub_util_error (_("cannot open `%s': %s"), path, strerror (errno)); -+ -+ while (fgets (buf, sizeof (buf), fp)) -+ { -+ char *p; -+ struct grub_util_path_list *pl; -+ -+ skip = 0; -+ -+ /* Get the target name. */ -+ p = strchr (buf, ':'); -+ if (! p) -+ grub_util_error (_("invalid line format: %s"), buf); -+ -+ *p++ = '\0'; -+ -+ /* kernel is not a module */ -+ if (strcmp(buf, "kernel") == 0) -+ continue; -+ -+ /* Check if the module is already in the core. */ -+ for (pl = path_list; pl; pl = pl->next) -+ { -+ if (strcmp(buf, get_module_name(pl->name)) == 0) -+ { -+ skip = 1; -+ break; -+ } -+ } -+ -+ if (skip) -+ continue; -+ -+ /* Add the new path. */ -+ new_path = (struct grub_util_path_list *) xmalloc (sizeof (*new_path)); -+ new_path->name = get_module_path (prefix, buf); -+ new_path->next = path_list_comp; -+ path_list_comp = new_path; -+ } -+ -+ return path_list_comp; -+} --- -1.7.10.4 - diff --git a/grub-2.00-ignore-gnulib-gets-stupidity.patch b/grub-2.00-ignore-gnulib-gets-stupidity.patch deleted file mode 100644 index 345c19d..0000000 --- a/grub-2.00-ignore-gnulib-gets-stupidity.patch +++ /dev/null @@ -1,26 +0,0 @@ -From f66d54b934710f54999debb72e8b7c620edece1d Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Fri, 25 May 2012 15:28:19 -0400 -Subject: [PATCH] gnulib accused in build breaking shocker. - ---- - grub-core/gnulib/stdio.in.h | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/grub-core/gnulib/stdio.in.h b/grub-core/gnulib/stdio.in.h -index 80b9dbf..69932d9 100644 ---- a/grub-core/gnulib/stdio.in.h -+++ b/grub-core/gnulib/stdio.in.h -@@ -141,7 +141,9 @@ _GL_WARN_ON_USE (fflush, "fflush is not always POSIX compliant - " - so any use of gets warrants an unconditional warning. Assume it is - always declared, since it is required by C89. */ - #undef gets -+#if 0 - _GL_WARN_ON_USE (gets, "gets is a security hole - use fgets instead"); -+#endif - - #if @GNULIB_FOPEN@ - # if @REPLACE_FOPEN@ --- -1.7.10.1 - diff --git a/grub-2.00-increase-the-ieee1275-device-path-buffer-size.patch b/grub-2.00-increase-the-ieee1275-device-path-buffer-size.patch deleted file mode 100644 index 8d254bf..0000000 --- a/grub-2.00-increase-the-ieee1275-device-path-buffer-size.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 7e1f42417dab20d470d1e45dfa73d00c763d792d Mon Sep 17 00:00:00 2001 -From: Paulo Flabiano Smorigo -Date: Wed, 19 Sep 2012 20:50:38 -0300 -Subject: [PATCH] increase the ieee1275 device path buffer size - -There are cases when the openfirmware device path is bigger then 64 chars. - -This should fix this bugzilla: -https://bugzilla.redhat.com/show_bug.cgi?id=857936 ---- - grub-core/kern/ieee1275/init.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c -index 7d03a8a..5c45947 100644 ---- a/grub-core/kern/ieee1275/init.c -+++ b/grub-core/kern/ieee1275/init.c -@@ -82,7 +82,7 @@ void (*grub_ieee1275_net_config) (const char *dev, - void - grub_machine_get_bootlocation (char **device, char **path) - { -- char bootpath[64]; /* XXX check length */ -+ char bootpath[256]; /* Max device path length */ - char *filename; - char *type; - --- -1.7.10.4 - diff --git a/grub-2.00-no-insmod-on-sb.patch b/grub-2.00-no-insmod-on-sb.patch deleted file mode 100644 index 1bfd6f8..0000000 --- a/grub-2.00-no-insmod-on-sb.patch +++ /dev/null @@ -1,113 +0,0 @@ -From 8a2a8d6021d926f00c5f85dab2d66f4ed8be86a2 Mon Sep 17 00:00:00 2001 -From: Colin Watson -Date: Tue, 23 Oct 2012 10:40:49 -0400 -Subject: [PATCH] Don't allow insmod when secure boot is enabled. - -Hi, - -Fedora's patch to forbid insmod in UEFI Secure Boot environments is fine -as far as it goes. However, the insmod command is not the only way that -modules can be loaded. In particular, the 'normal' command, which -implements the usual GRUB menu and the fully-featured command prompt, -will implicitly load commands not currently loaded into memory. This -permits trivial Secure Boot violations by writing commands implementing -whatever you want to do and pointing $prefix at the malicious code. - -I'm currently test-building this patch (replacing your current -grub-2.00-no-insmod-on-sb.patch), but this should be more correct. It -moves the check into grub_dl_load_file. ---- - grub-core/kern/dl.c | 17 +++++++++++++++++ - grub-core/kern/efi/efi.c | 28 ++++++++++++++++++++++++++++ - include/grub/efi/efi.h | 1 + - 3 files changed, 46 insertions(+) - -diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c -index a498682..2578fce 100644 ---- a/grub-core/kern/dl.c -+++ b/grub-core/kern/dl.c -@@ -43,6 +43,10 @@ - #include - #endif - -+#ifdef GRUB_MACHINE_EFI -+#include -+#endif -+ - - - #pragma GCC diagnostic ignored "-Wcast-align" -@@ -721,6 +725,19 @@ grub_dl_load_file (const char *filename) - void *core = 0; - grub_dl_t mod = 0; - -+#ifdef GRUB_MACHINE_EFI -+ if (grub_efi_secure_boot ()) -+ { -+#if 0 -+ /* This is an error, but grub2-mkconfig still generates a pile of -+ * insmod commands, so emitting it would be mostly just obnoxious. */ -+ grub_error (GRUB_ERR_ACCESS_DENIED, -+ "Secure Boot forbids loading module from %s", filename); -+#endif -+ return 0; -+ } -+#endif -+ - file = grub_file_open (filename); - if (! file) - return 0; -diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c -index 820968f..ad7aa8d 100644 ---- a/grub-core/kern/efi/efi.c -+++ b/grub-core/kern/efi/efi.c -@@ -259,6 +259,34 @@ grub_efi_set_variable(const char *var, const grub_efi_guid_t *guid, - return grub_error (GRUB_ERR_IO, "could not set EFI variable `%s'", var); - } - -+grub_efi_boolean_t -+grub_efi_secure_boot (void) -+{ -+ grub_efi_guid_t efi_var_guid = GRUB_EFI_GLOBAL_VARIABLE_GUID; -+ grub_size_t datasize; -+ char *secure_boot = NULL; -+ char *setup_mode = NULL; -+ grub_efi_boolean_t ret = 0; -+ -+ secure_boot = grub_efi_get_variable("SecureBoot", &efi_var_guid, &datasize); -+ -+ if (datasize != 1 || !secure_boot) -+ goto out; -+ -+ setup_mode = grub_efi_get_variable("SetupMode", &efi_var_guid, &datasize); -+ -+ if (datasize != 1 || !setup_mode) -+ goto out; -+ -+ if (*secure_boot && !*setup_mode) -+ ret = 1; -+ -+ out: -+ grub_free (secure_boot); -+ grub_free (setup_mode); -+ return ret; -+} -+ - #pragma GCC diagnostic ignored "-Wcast-align" - - /* Search the mods section from the PE32/PE32+ image. This code uses -diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h -index 9370fd5..a000c38 100644 ---- a/include/grub/efi/efi.h -+++ b/include/grub/efi/efi.h -@@ -72,6 +72,7 @@ EXPORT_FUNC (grub_efi_set_variable) (const char *var, - const grub_efi_guid_t *guid, - void *data, - grub_size_t datasize); -+grub_efi_boolean_t EXPORT_FUNC (grub_efi_secure_boot) (void); - int - EXPORT_FUNC (grub_efi_compare_device_paths) (const grub_efi_device_path_t *dp1, - const grub_efi_device_path_t *dp2); --- -1.7.12.1 - diff --git a/grub-2.00-search-for-specific-config-file-for-netboot.patch b/grub-2.00-search-for-specific-config-file-for-netboot.patch deleted file mode 100644 index 026d002..0000000 --- a/grub-2.00-search-for-specific-config-file-for-netboot.patch +++ /dev/null @@ -1,205 +0,0 @@ -From 38d458ddd69cb7dd6e7f58f9e9f3197c6b6184f3 Mon Sep 17 00:00:00 2001 -From: Paulo Flabiano Smorigo -Date: Tue, 27 Nov 2012 17:22:07 -0200 -Subject: [PATCH 3/3] Search for specific config file for netboot - -This patch implements a search for a specific configuration when the config -file is on a remoteserver. It uses the following order: - 1) DHCP client UUID option. - 2) MAC address (in lower case hexadecimal with dash separators); - 3) IP (in upper case hexadecimal) or IPv6; - 4) The original grub.cfg file. - -This procedure is similar to what is used by pxelinux and yaboot: -http://www.syslinux.org/wiki/index.php/PXELINUX#config - -This should close the bugzilla: -https://bugzilla.redhat.com/show_bug.cgi?id=873406 ---- - grub-core/net/net.c | 118 +++++++++++++++++++++++++++++++++++++++++++++++ - grub-core/normal/main.c | 18 ++++++-- - include/grub/net.h | 3 ++ - 3 files changed, 135 insertions(+), 4 deletions(-) - -diff --git a/grub-core/net/net.c b/grub-core/net/net.c -index 01c5d32..49c32c5 100644 ---- a/grub-core/net/net.c -+++ b/grub-core/net/net.c -@@ -1548,6 +1548,124 @@ grub_net_restore_hw (void) - return GRUB_ERR_NONE; - } - -+grub_err_t -+grub_net_search_configfile (char *config) -+{ -+ grub_size_t config_len; -+ char *suffix; -+ -+ auto int search_through (grub_size_t num_tries, grub_size_t slice_size); -+ int search_through (grub_size_t num_tries, grub_size_t slice_size) -+ { -+ while (num_tries-- > 0) -+ { -+ grub_dprintf ("net", "probe %s\n", config); -+ -+ grub_file_t file; -+ file = grub_file_open (config); -+ -+ if (file) -+ { -+ grub_file_close (file); -+ grub_dprintf ("net", "found!\n"); -+ return 0; -+ } -+ else -+ { -+ if (grub_errno == GRUB_ERR_IO) -+ grub_errno = GRUB_ERR_NONE; -+ } -+ -+ if (grub_strlen (suffix) < slice_size) -+ break; -+ -+ config[grub_strlen (config) - slice_size] = '\0'; -+ } -+ -+ return 1; -+ } -+ -+ config_len = grub_strlen (config); -+ config[config_len] = '-'; -+ suffix = config + config_len + 1; -+ -+ struct grub_net_network_level_interface *inf; -+ FOR_NET_NETWORK_LEVEL_INTERFACES (inf) -+ { -+ /* By the Client UUID. */ -+ -+ char client_uuid_var[sizeof ("net_") + grub_strlen (inf->name) + -+ sizeof ("_clientuuid") + 1]; -+ grub_snprintf (client_uuid_var, sizeof (client_uuid_var), -+ "net_%s_clientuuid", inf->name); -+ -+ const char *client_uuid; -+ client_uuid = grub_env_get (client_uuid_var); -+ -+ if (client_uuid) -+ { -+ grub_strcpy (suffix, client_uuid); -+ if (search_through (1, 0) == 0) return GRUB_ERR_NONE; -+ } -+ -+ /* By the MAC address. */ -+ -+ /* Add ethernet type */ -+ grub_strcpy (suffix, "01-"); -+ -+ grub_net_hwaddr_to_str (&inf->hwaddress, suffix + 3); -+ -+ char *ptr; -+ for (ptr = suffix; *ptr; ptr++) -+ if (*ptr == ':') -+ *ptr = '-'; -+ -+ if (search_through (1, 0) == 0) return GRUB_ERR_NONE; -+ -+ /* By IP address */ -+ -+ switch ((&inf->address)->type) -+ { -+ case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4: -+ { -+ grub_uint32_t n = grub_be_to_cpu32 ((&inf->address)->ipv4); -+ grub_snprintf (suffix, GRUB_NET_MAX_STR_ADDR_LEN, "%02X%02X%02X%02X", \ -+ ((n >> 24) & 0xff), ((n >> 16) & 0xff), \ -+ ((n >> 8) & 0xff), ((n >> 0) & 0xff)); -+ -+ if (search_through (8, 1) == 0) return GRUB_ERR_NONE; -+ break; -+ } -+ case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6: -+ { -+ char buf[GRUB_NET_MAX_STR_ADDR_LEN]; -+ struct grub_net_network_level_address base; -+ base.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6; -+ grub_memcpy (&base.ipv6, ((&inf->address)->ipv6), 16); -+ grub_net_addr_to_str (&base, buf); -+ -+ for (ptr = buf; *ptr; ptr++) -+ if (*ptr == ':') -+ *ptr = '-'; -+ -+ grub_snprintf (suffix, GRUB_NET_MAX_STR_ADDR_LEN, "%s", buf); -+ if (search_through (1, 0) == 0) return GRUB_ERR_NONE; -+ break; -+ } -+ case GRUB_NET_NETWORK_LEVEL_PROTOCOL_DHCP_RECV: -+ return grub_error (GRUB_ERR_BUG, "shouldn't reach here"); -+ default: -+ return grub_error (GRUB_ERR_BUG, -+ "unsupported address type %d", (&inf->address)->type); -+ } -+ } -+ -+ /* Remove the remaining minus sign at the end. */ -+ config[config_len] = '\0'; -+ -+ return GRUB_ERR_NONE; -+} -+ - static struct grub_preboot *fini_hnd; - - static grub_command_t cmd_addaddr, cmd_deladdr, cmd_addroute, cmd_delroute; -diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c -index aa0b3e5..cc519a5 100644 ---- a/grub-core/normal/main.c -+++ b/grub-core/normal/main.c -@@ -32,6 +32,7 @@ - #include - #include - #include -+#include - #ifdef GRUB_MACHINE_IEEE1275 - #include - #endif -@@ -379,10 +380,19 @@ grub_cmd_normal (struct grub_command *cmd __attribute__ ((unused)), - - prefix = grub_env_get ("prefix"); - if (prefix) -- { -- config = grub_xasprintf ("%s/grub.cfg", prefix); -- if (! config) -- goto quit; -+ { -+ grub_size_t config_len; -+ config_len = grub_strlen (prefix) + -+ sizeof ("/grub.cfg-XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"); -+ config = grub_malloc (config_len); -+ -+ if (! config) -+ goto quit; -+ -+ grub_snprintf (config, config_len, "%s/grub.cfg", prefix); -+ -+ if (grub_strncmp (prefix + 1, "tftp", sizeof ("tftp") - 1) == 0) -+ grub_net_search_configfile (config); - - grub_enter_normal_mode (config); - grub_free (config); -diff --git a/include/grub/net.h b/include/grub/net.h -index 45348dd..09b8d56 100644 ---- a/include/grub/net.h -+++ b/include/grub/net.h -@@ -534,6 +534,9 @@ extern char *grub_net_default_server; - #define GRUB_NET_TRIES 40 - #define GRUB_NET_INTERVAL 400 - - #define VLANTAG_IDENTIFIER 0x8100 - -+grub_err_t -+grub_net_search_configfile (char *config); -+ - #endif /* ! GRUB_NET_HEADER */ --- -1.7.10.4 - diff --git a/grub-2.00-support-bls-config.patch b/grub-2.00-support-bls-config.patch deleted file mode 100644 index 10e9cba..0000000 --- a/grub-2.00-support-bls-config.patch +++ /dev/null @@ -1,324 +0,0 @@ -From 4b7a3f2abc7f1017e69de197c5a970c4451ff1ff Mon Sep 17 00:00:00 2001 -From: Fedora Ninjas -Date: Tue, 22 Jan 2013 06:31:38 +0100 -Subject: [PATCH] blscfg: add blscfg module to parse Boot Loader Specification - snippets - -http://www.freedesktop.org/wiki/Specifications/BootLoaderSpec - -Works like this: - - insmod blscfg - bls_import - -Done! You should now have menu items for your snippets in place. - -Signed-off-by: Peter Jones ---- - grub-core/Makefile.core.am | 65 ++++++++++++++ - grub-core/Makefile.core.def | 8 ++ - grub-core/commands/blscfg.c | 200 ++++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 273 insertions(+) - create mode 100644 grub-core/commands/blscfg.c - -diff --git a/grub-core/Makefile.core.am b/grub-core/Makefile.core.am -index 79d22c3..e2561d2 100644 ---- a/grub-core/Makefile.core.am -+++ b/grub-core/Makefile.core.am -@@ -58369,3 +58369,68 @@ CLEANFILES += gdb_grub - dist_noinst_DATA += gdb_grub.in - endif - -+if COND_i386_pc -+platform_PROGRAMS += blscfg.module -+MODULE_FILES += blscfg.module$(EXEEXT) -+blscfg_module_SOURCES = commands/blscfg.c ## platform sources -+nodist_blscfg_module_SOURCES = ## platform nodist sources -+blscfg_module_LDADD = -+blscfg_module_CFLAGS = $(AM_CFLAGS) $(CFLAGS_MODULE) -+blscfg_module_LDFLAGS = $(AM_LDFLAGS) $(LDFLAGS_MODULE) -+blscfg_module_CPPFLAGS = $(AM_CPPFLAGS) $(CPPFLAGS_MODULE) -+blscfg_module_CCASFLAGS = $(AM_CCASFLAGS) $(CCASFLAGS_MODULE) -+EXTRA_DIST += -+BUILT_SOURCES += $(nodist_blscfg_module_SOURCES) -+CLEANFILES += $(nodist_blscfg_module_SOURCES) -+MOD_FILES += blscfg.mod -+MARKER_FILES += blscfg.marker -+CLEANFILES += blscfg.marker -+ -+blscfg.marker: $(blscfg_module_SOURCES) $(nodist_blscfg_module_SOURCES) -+ $(TARGET_CPP) -DGRUB_LST_GENERATOR $(CPPFLAGS_MARKER) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(blscfg_module_CPPFLAGS) $(CPPFLAGS) $^ > $@.new || (rm -f $@; exit 1) -+ grep 'MARKER' $@.new > $@; rm -f $@.new -+endif -+ -+if COND_i386_efi -+platform_PROGRAMS += blscfg.module -+MODULE_FILES += blscfg.module$(EXEEXT) -+blscfg_module_SOURCES = commands/blscfg.c ## platform sources -+nodist_blscfg_module_SOURCES = ## platform nodist sources -+blscfg_module_LDADD = -+blscfg_module_CFLAGS = $(AM_CFLAGS) $(CFLAGS_MODULE) -+blscfg_module_LDFLAGS = $(AM_LDFLAGS) $(LDFLAGS_MODULE) -+blscfg_module_CPPFLAGS = $(AM_CPPFLAGS) $(CPPFLAGS_MODULE) -+blscfg_module_CCASFLAGS = $(AM_CCASFLAGS) $(CCASFLAGS_MODULE) -+EXTRA_DIST += -+BUILT_SOURCES += $(nodist_blscfg_module_SOURCES) -+CLEANFILES += $(nodist_blscfg_module_SOURCES) -+MOD_FILES += blscfg.mod -+MARKER_FILES += blscfg.marker -+CLEANFILES += blscfg.marker -+ -+blscfg.marker: $(blscfg_module_SOURCES) $(nodist_blscfg_module_SOURCES) -+ $(TARGET_CPP) -DGRUB_LST_GENERATOR $(CPPFLAGS_MARKER) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(blscfg_module_CPPFLAGS) $(CPPFLAGS) $^ > $@.new || (rm -f $@; exit 1) -+ grep 'MARKER' $@.new > $@; rm -f $@.new -+endif -+ -+if COND_x86_64_efi -+platform_PROGRAMS += blscfg.module -+MODULE_FILES += blscfg.module$(EXEEXT) -+blscfg_module_SOURCES = commands/blscfg.c ## platform sources -+nodist_blscfg_module_SOURCES = ## platform nodist sources -+blscfg_module_LDADD = -+blscfg_module_CFLAGS = $(AM_CFLAGS) $(CFLAGS_MODULE) -+blscfg_module_LDFLAGS = $(AM_LDFLAGS) $(LDFLAGS_MODULE) -+blscfg_module_CPPFLAGS = $(AM_CPPFLAGS) $(CPPFLAGS_MODULE) -+blscfg_module_CCASFLAGS = $(AM_CCASFLAGS) $(CCASFLAGS_MODULE) -+EXTRA_DIST += -+BUILT_SOURCES += $(nodist_blscfg_module_SOURCES) -+CLEANFILES += $(nodist_blscfg_module_SOURCES) -+MOD_FILES += blscfg.mod -+MARKER_FILES += blscfg.marker -+CLEANFILES += blscfg.marker -+ -+blscfg.marker: $(blscfg_module_SOURCES) $(nodist_blscfg_module_SOURCES) -+ $(TARGET_CPP) -DGRUB_LST_GENERATOR $(CPPFLAGS_MARKER) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(blscfg_module_CPPFLAGS) $(CPPFLAGS) $^ > $@.new || (rm -f $@; exit 1) -+ grep 'MARKER' $@.new > $@; rm -f $@.new -+endif -diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def -index fd4c54e..cfd3b09 100644 ---- a/grub-core/Makefile.core.def -+++ b/grub-core/Makefile.core.def -@@ -584,6 +584,14 @@ module = { - }; - - module = { -+ name = blscfg; -+ common = commands/blscfg.c; -+ enable = i386_efi; -+ enable = x86_64_efi; -+ enable = i386_pc; -+}; -+ -+module = { - name = boot; - common = commands/boot.c; - i386_pc = lib/i386/pc/biosnum.c; -diff --git a/grub-core/commands/blscfg.c b/grub-core/commands/blscfg.c -new file mode 100644 -index 0000000..8a07c57 ---- /dev/null -+++ b/grub-core/commands/blscfg.c -@@ -0,0 +1,200 @@ -+/*-*- Mode: C; c-basic-offset: 2; indent-tabs-mode: t -*-*/ -+ -+/* bls.c - implementation of the boot loader spec */ -+ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * -+ * 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 -+ -+GRUB_MOD_LICENSE ("GPLv3+"); -+ -+#ifdef GRUB_MACHINE_EFI -+#define GRUB_LINUX_CMD "linuxefi" -+#define GRUB_INITRD_CMD "initrdefi" -+#define GRUB_BLS_CONFIG_PATH "/EFI/fedora/loader/entries/" -+#define GRUB_BOOT_DEVICE "($boot)" -+#else -+#define GRUB_LINUX_CMD "linux" -+#define GRUB_INITRD_CMD "initrd" -+#define GRUB_BLS_CONFIG_PATH "/loader/entries/" -+#define GRUB_BOOT_DEVICE "($root)" -+#endif -+ -+static int parse_entry ( -+ const char *filename, -+ const struct grub_dirhook_info *info __attribute__ ((unused))) -+{ -+ grub_size_t n; -+ char *p; -+ grub_file_t f = NULL; -+ grub_off_t sz; -+ char *title = NULL, *options = NULL, *clinux = NULL, *initrd = NULL, *src = NULL; -+ const char *args[2] = { NULL, NULL }; -+ -+ if (filename[0] == '.') -+ return 0; -+ -+ n = grub_strlen (filename); -+ if (n <= 5) -+ return 0; -+ -+ if (grub_strcmp (filename + n - 5, ".conf") != 0) -+ return 0; -+ -+ p = grub_xasprintf (GRUB_BLS_CONFIG_PATH "%s", filename); -+ -+ f = grub_file_open (p); -+ if (!f) -+ goto finish; -+ -+ sz = grub_file_size (f); -+ if (sz == GRUB_FILE_SIZE_UNKNOWN || sz > 1024*1024) -+ goto finish; -+ -+ for (;;) -+ { -+ char *buf; -+ -+ buf = grub_file_getline (f); -+ if (!buf) -+ break; -+ -+ if (grub_strncmp (buf, "title ", 6) == 0) -+ { -+ grub_free (title); -+ title = grub_strdup (buf + 6); -+ if (!title) -+ goto finish; -+ } -+ else if (grub_strncmp (buf, "options ", 8) == 0) -+ { -+ grub_free (options); -+ options = grub_strdup (buf + 8); -+ if (!options) -+ goto finish; -+ } -+ else if (grub_strncmp (buf, "linux ", 6) == 0) -+ { -+ grub_free (clinux); -+ clinux = grub_strdup (buf + 6); -+ if (!clinux) -+ goto finish; -+ } -+ else if (grub_strncmp (buf, "initrd ", 7) == 0) -+ { -+ grub_free (initrd); -+ initrd = grub_strdup (buf + 7); -+ if (!initrd) -+ goto finish; -+ } -+ -+ grub_free(buf); -+ } -+ -+ if (!linux) -+ { -+ grub_printf ("Skipping file %s with no 'linux' key.", p); -+ goto finish; -+ } -+ -+ args[0] = title ? title : filename; -+ -+ src = grub_xasprintf ("load_video\n" -+ "set gfx_payload=keep\n" -+ "insmod gzio\n" -+ GRUB_LINUX_CMD " %s%s%s%s\n" -+ "%s%s%s%s", -+ GRUB_BOOT_DEVICE, clinux, options ? " " : "", options ? options : "", -+ initrd ? GRUB_INITRD_CMD " " : "", initrd ? GRUB_BOOT_DEVICE : "", initrd ? initrd : "", initrd ? "\n" : ""); -+ -+ grub_normal_add_menu_entry (1, args, NULL, NULL, "bls", NULL, NULL, src, 0); -+ -+finish: -+ grub_free (p); -+ grub_free (title); -+ grub_free (options); -+ grub_free (clinux); -+ grub_free (initrd); -+ grub_free (src); -+ -+ if (f) -+ grub_file_close (f); -+ -+ return 0; -+} -+ -+static grub_err_t -+grub_cmd_bls_import (grub_extcmd_context_t ctxt __attribute__ ((unused)), -+ int argc __attribute__ ((unused)), -+ char **args __attribute__ ((unused))) -+{ -+ grub_fs_t fs; -+ grub_device_t dev; -+ static grub_err_t r; -+ const char *devid; -+ -+ devid = grub_env_get ("root"); -+ if (!devid) -+ return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("variable `%s' isn't set"), "root"); -+ -+ dev = grub_device_open (devid); -+ if (!dev) -+ return grub_errno; -+ -+ fs = grub_fs_probe (dev); -+ if (!fs) -+ { -+ r = grub_errno; -+ goto finish; -+ } -+ -+ r = fs->dir (dev, GRUB_BLS_CONFIG_PATH, parse_entry); -+ -+finish: -+ if (dev) -+ grub_device_close (dev); -+ -+ return r; -+} -+ -+static grub_extcmd_t cmd; -+ -+GRUB_MOD_INIT(bls) -+{ -+ cmd = grub_register_extcmd ("bls_import", -+ grub_cmd_bls_import, -+ 0, -+ NULL, -+ N_("Import Boot Loader Specification snippets."), -+ NULL); -+} -+ -+GRUB_MOD_FINI(bls) -+{ -+ grub_unregister_extcmd (cmd); -+} --- -1.8.1.2 - diff --git a/grub-2.00-who-trusts-you-and-who-do-you-trust.patch b/grub-2.00-who-trusts-you-and-who-do-you-trust.patch deleted file mode 100644 index e374ac2..0000000 --- a/grub-2.00-who-trusts-you-and-who-do-you-trust.patch +++ /dev/null @@ -1,217 +0,0 @@ -From 44cee23d139fe8faaca2622cc09041b1d684265b Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Tue, 5 Jun 2012 09:23:25 -0400 -Subject: [PATCH] Support secure boot. - -If SecureBoot is enabled, treat all authentications as failure, and also -use shim's verify routine to verify the kernel before loading. ---- - grub-core/loader/i386/linux.c | 26 +++++++++++++ - grub-core/normal/auth.c | 85 +++++++++++++++++++++++++++++++++++++++++ - grub-core/normal/main.c | 4 +- - grub-core/normal/menu_entry.c | 5 ++- - include/grub/auth.h | 3 ++ - 5 files changed, 121 insertions(+), 2 deletions(-) - -diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c -index 6e8238e..090484c 100644 ---- a/grub-core/loader/i386/linux.c -+++ b/grub-core/loader/i386/linux.c -@@ -34,6 +34,7 @@ - #include - #include - #include -+#include - - GRUB_MOD_LICENSE ("GPLv3+"); - -@@ -681,6 +682,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - int relocatable; - grub_uint64_t preffered_address = GRUB_LINUX_BZIMAGE_ADDR; - -+ void *buffer; -+ grub_err_t verified; -+ - grub_dl_ref (my_mod); - - if (argc == 0) -@@ -693,6 +697,28 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - if (! file) - goto fail; - -+ buffer = grub_malloc(grub_file_size(file)); -+ if (!buffer) -+ return grub_errno; -+ -+ if (grub_file_read (file, buffer, grub_file_size(file))) -+ { -+ if (!grub_errno) -+ grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), -+ argv[0]); -+ goto fail; -+ } -+ -+ verified = grub_auth_verify_signature(buffer, grub_file_size(file)); -+ grub_free(buffer); -+ if (verified != GRUB_ERR_NONE) -+ { -+ grub_errno = verified; -+ goto fail; -+ } -+ -+ grub_free(buffer); -+ grub_file_seek(file, 0); - if (grub_file_read (file, &lh, sizeof (lh)) != sizeof (lh)) - { - if (!grub_errno) -diff --git a/grub-core/normal/auth.c b/grub-core/normal/auth.c -index c6bd96e..3e83ee8 100644 ---- a/grub-core/normal/auth.c -+++ b/grub-core/normal/auth.c -@@ -24,6 +24,8 @@ - #include - #include - #include -+#include -+#include - - struct grub_auth_user - { -@@ -198,6 +200,89 @@ grub_username_get (char buf[], unsigned buf_size) - } - - grub_err_t -+grub_auth_secure_boot (void) -+{ -+#ifdef GRUB_MACHINE_EFI -+ grub_size_t datasize = 0; -+ grub_uint8_t *data; -+ grub_efi_guid_t guid = GRUB_EFI_GLOBAL_VARIABLE_GUID; -+ unsigned int x; -+ -+ data = grub_efi_get_variable ("SecureBoot", &guid, &datasize); -+ if (!data) -+ return GRUB_ERR_NONE; -+ -+ for (x = 0; x < datasize; x++) -+ if (data[x] == 1) -+ return GRUB_ACCESS_DENIED; -+#endif -+ -+ return GRUB_ERR_NONE; -+} -+ -+int -+grub_is_secure_boot (void) -+{ -+ return grub_auth_secure_boot() == GRUB_ACCESS_DENIED; -+} -+ -+#define SHIM_LOCK_GUID \ -+ { 0x605dab50, 0xe046, 0x4300, {0xab,0xb6,0x3d,0xd8,0x10,0xdd,0x8b,0x23} } -+ -+typedef grub_efi_status_t (*EFI_SHIM_LOCK_VERIFY)(void *buffer, grub_efi_uint32_t size); -+ -+typedef struct _SHIM_LOCK { -+ EFI_SHIM_LOCK_VERIFY Verify; -+} SHIM_LOCK; -+ -+grub_err_t -+grub_auth_verify_signature (void *buffer, grub_uint32_t size) -+{ -+#ifdef GRUB_MACHINE_EFI -+ grub_efi_guid_t shim_guid = SHIM_LOCK_GUID; -+ SHIM_LOCK *shim = NULL; -+ grub_efi_handle_t *handles, shim_handle = NULL; -+ grub_efi_uintn_t num_handles, i; -+ grub_efi_status_t status; -+ -+ if (!grub_is_secure_boot()) -+ return GRUB_ERR_NONE; -+ -+ handles = grub_efi_locate_handle (GRUB_EFI_BY_PROTOCOL, &shim_guid, NULL, -+ &num_handles); -+ if (!handles || num_handles == 0) -+no_verify: -+ return grub_error (GRUB_ACCESS_DENIED, "Could not find signature verification routine"); -+ -+ for (i = 0; i < num_handles; i++) -+ { -+ shim_handle = handles[i]; -+ shim = grub_efi_open_protocol (shim_handle, &shim_guid, -+ GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); -+ if (shim) -+ break; -+ } -+ -+ if (!shim) -+ { -+ grub_free(handles); -+ goto no_verify; -+ } -+ -+ status = shim->Verify(buffer, size); -+ -+ grub_free(handles); -+ -+ if (status == GRUB_EFI_SUCCESS) -+ return GRUB_ERR_NONE; -+ -+ return grub_error (GRUB_ACCESS_DENIED, "Signature verification failed"); -+#else -+ return GRUB_ERR_NONE; -+#endif -+} -+ -+grub_err_t - grub_auth_check_authentication (const char *userlist) - { - char login[1024]; -diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c -index 193d7d3..1e321a4 100644 ---- a/grub-core/normal/main.c -+++ b/grub-core/normal/main.c -@@ -455,7 +455,9 @@ grub_cmdline_run (int nested) - { - grub_err_t err = GRUB_ERR_NONE; - -- err = grub_auth_check_authentication (NULL); -+ err = grub_auth_secure_boot (); -+ if (err == GRUB_ERR_NONE) -+ err = grub_auth_check_authentication (NULL); - - if (err) - { -diff --git a/grub-core/normal/menu_entry.c b/grub-core/normal/menu_entry.c -index 7fc890d..4e7a08c 100644 ---- a/grub-core/normal/menu_entry.c -+++ b/grub-core/normal/menu_entry.c -@@ -1287,7 +1287,10 @@ grub_menu_entry_run (grub_menu_entry_t entry) - unsigned i; - grub_term_output_t term; - -- err = grub_auth_check_authentication (NULL); -+ -+ err = grub_auth_secure_boot (); -+ if (err == GRUB_ERR_NONE) -+ err = grub_auth_check_authentication (NULL); - - if (err) - { -diff --git a/include/grub/auth.h b/include/grub/auth.h -index 7473344..b933fa1 100644 ---- a/include/grub/auth.h -+++ b/include/grub/auth.h -@@ -32,6 +32,9 @@ grub_err_t grub_auth_unregister_authentication (const char *user); - - grub_err_t grub_auth_authenticate (const char *user); - grub_err_t grub_auth_deauthenticate (const char *user); -+grub_err_t grub_auth_secure_boot (void); -+int grub_is_secure_boot (void); -+grub_err_t grub_auth_verify_signature (void *buffer, grub_uint32_t size); - grub_err_t grub_auth_check_authentication (const char *userlist); - - #endif /* ! GRUB_AUTH_HEADER */ --- -1.7.10.2 - diff --git a/grub2-add-bootpath-device-to-the-list.patch b/grub2-add-bootpath-device-to-the-list.patch deleted file mode 100644 index d493bb5..0000000 --- a/grub2-add-bootpath-device-to-the-list.patch +++ /dev/null @@ -1,54 +0,0 @@ -From d2863ca186a6d4ba2a56559bf522f46c18403645 Mon Sep 17 00:00:00 2001 -From: Fedora Ninjas -Date: Fri, 14 Dec 2012 20:10:21 -0200 -Subject: [PATCH] Add bootpath device to the list - -When scanning the devices, always check (and add) the bootpath device if it -isn't in the device list. ---- - grub-core/disk/ieee1275/ofdisk.c | 29 +++++++++++++++++++++++++++++ - 1 file changed, 29 insertions(+) - -diff --git a/grub-core/disk/ieee1275/ofdisk.c b/grub-core/disk/ieee1275/ofdisk.c -index b0aa7ec..99b156e 100644 ---- a/grub-core/disk/ieee1275/ofdisk.c -+++ b/grub-core/disk/ieee1275/ofdisk.c -@@ -213,6 +213,35 @@ scan (void) - return grub_children_iterate (alias->path, dev_iterate); - } - -+ char *bootpath; -+ int bootpath_size; -+ char *type; -+ -+ if (grub_ieee1275_get_property_length (grub_ieee1275_chosen, "bootpath", -+ &bootpath_size) -+ || bootpath_size <= 0) -+ { -+ /* Should never happen. */ -+ grub_printf ("/chosen/bootpath property missing!\n"); -+ return; -+ } -+ -+ bootpath = (char *) grub_malloc ((grub_size_t) bootpath_size + 64); -+ if (! bootpath) -+ { -+ grub_print_error (); -+ return; -+ } -+ grub_ieee1275_get_property (grub_ieee1275_chosen, "bootpath", bootpath, -+ (grub_size_t) bootpath_size + 1, 0); -+ bootpath[bootpath_size] = '\0'; -+ -+ type = grub_ieee1275_get_device_type (bootpath); -+ if (type && grub_strcmp (type, "block") == 0) -+ dev_iterate_real (bootpath, bootpath); -+ -+ grub_free (bootpath); -+ - grub_devalias_iterate (dev_iterate_alias); - grub_children_iterate ("/", dev_iterate); - } --- -1.8.0 - diff --git a/grub2-cdpath.patch b/grub2-cdpath.patch deleted file mode 100644 index 3e00db4..0000000 --- a/grub2-cdpath.patch +++ /dev/null @@ -1,25 +0,0 @@ -From: Matthew Garrett -Date: 2012-07-10 11:58:52 EDT -Subject: [PATCH] Add support for crappy cd craparino - -diff --git a/grub-core/disk/efi/efidisk.c b/grub-core/disk/efi/efidisk.c -index d9d788c..a432b44 100644 ---- a/grub-core/disk/efi/efidisk.c -+++ b/grub-core/disk/efi/efidisk.c -@@ -750,6 +750,16 @@ grub_efidisk_get_device_name (grub_efi_handle_t *handle) - if (! ldp) - return 0; - -+ if (GRUB_EFI_DEVICE_PATH_TYPE (ldp) == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE && -+ (GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) == GRUB_EFI_CDROM_DEVICE_PATH_SUBTYPE)) -+ { -+ ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE; -+ ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE; -+ ldp->length[0] = 4; -+ ldp->length[1] = 0; -+ ldp = find_last_device_path(dp); -+ } -+ - if (GRUB_EFI_DEVICE_PATH_TYPE (ldp) == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE - && (GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) - == GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE)) diff --git a/grub2-linuxefi.patch b/grub2-linuxefi.patch deleted file mode 100644 index c0282d0..0000000 --- a/grub2-linuxefi.patch +++ /dev/null @@ -1,480 +0,0 @@ -From: Matthew Garrett -Date: 2012-07-10 11:58:52 EDT -Subject: [PATCH] Add support for linuxefi - -diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def -index 39e77a4..f9cbfc3 100644 ---- a/grub-core/Makefile.core.def -+++ b/grub-core/Makefile.core.def -@@ -1415,6 +1415,14 @@ module = { - }; - - module = { -+ name = linuxefi; -+ efi = loader/i386/efi/linux.c; -+ efi = lib/cmdline.c; -+ enable = i386_efi; -+ enable = x86_64_efi; -+}; -+ -+module = { - name = chain; - efi = loader/efi/chainloader.c; - i386_pc = loader/i386/pc/chainloader.c; -diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c -index a2edc84..88b2557 100644 ---- a/grub-core/kern/efi/mm.c -+++ b/grub-core/kern/efi/mm.c -@@ -47,6 +47,38 @@ static grub_efi_uintn_t finish_desc_size; - static grub_efi_uint32_t finish_desc_version; - int grub_efi_is_finished = 0; - -+/* Allocate pages below a specified address */ -+void * -+grub_efi_allocate_pages_max (grub_efi_physical_address_t max, -+ grub_efi_uintn_t pages) -+{ -+ grub_efi_status_t status; -+ grub_efi_boot_services_t *b; -+ grub_efi_physical_address_t address = max; -+ -+ if (max > 0xffffffff) -+ return 0; -+ -+ b = grub_efi_system_table->boot_services; -+ status = efi_call_4 (b->allocate_pages, GRUB_EFI_ALLOCATE_MAX_ADDRESS, GRUB_EFI_LOADER_DATA, pages, &address); -+ -+ if (status != GRUB_EFI_SUCCESS) -+ return 0; -+ -+ if (address == 0) -+ { -+ /* Uggh, the address 0 was allocated... This is too annoying, -+ so reallocate another one. */ -+ address = max; -+ status = efi_call_4 (b->allocate_pages, GRUB_EFI_ALLOCATE_MAX_ADDRESS, GRUB_EFI_LOADER_DATA, pages, &address); -+ grub_efi_free_pages (0, pages); -+ if (status != GRUB_EFI_SUCCESS) -+ return 0; -+ } -+ -+ return (void *) ((grub_addr_t) address); -+} -+ - /* Allocate pages. Return the pointer to the first of allocated pages. */ - void * - grub_efi_allocate_pages (grub_efi_physical_address_t address, -diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c -new file mode 100644 -index 0000000..d06a0e3 ---- /dev/null -+++ b/grub-core/loader/i386/efi/linux.c -@@ -0,0 +1,369 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2012 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_MOD_LICENSE ("GPLv3+"); -+ -+static grub_dl_t my_mod; -+static int loaded; -+static void *kernel_mem; -+static grub_uint64_t kernel_size; -+static grub_uint8_t *initrd_mem; -+static grub_uint32_t handover_offset; -+struct linux_kernel_params *params; -+static char *linux_cmdline; -+ -+#define BYTES_TO_PAGES(bytes) (((bytes) + 0xfff) >> 12) -+ -+#define SHIM_LOCK_GUID \ -+ { 0x605dab50, 0xe046, 0x4300, {0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23} } -+ -+struct grub_efi_shim_lock -+{ -+ grub_efi_status_t (*verify) (void *buffer, grub_uint32_t size); -+}; -+typedef struct grub_efi_shim_lock grub_efi_shim_lock_t; -+ -+static grub_efi_boolean_t -+grub_linuxefi_secure_validate (void *data, grub_uint32_t size) -+{ -+ grub_efi_guid_t guid = SHIM_LOCK_GUID; -+ grub_efi_shim_lock_t *shim_lock; -+ -+ shim_lock = grub_efi_locate_protocol(&guid, NULL); -+ -+ if (!shim_lock) -+ return 1; -+ -+ if (shim_lock->verify(data, size) == GRUB_EFI_SUCCESS) -+ return 1; -+ -+ return 0; -+} -+ -+typedef void(*handover_func)(void *, grub_efi_system_table_t *, struct linux_kernel_params *); -+ -+static grub_err_t -+grub_linuxefi_boot (void) -+{ -+ handover_func hf; -+ int offset = 0; -+ -+#ifdef __x86_64__ -+ offset = 512; -+#endif -+ -+ hf = (handover_func)((char *)kernel_mem + handover_offset + offset); -+ -+ asm volatile ("cli"); -+ -+ hf (grub_efi_image_handle, grub_efi_system_table, params); -+ -+ /* Not reached */ -+ return GRUB_ERR_NONE; -+} -+ -+static grub_err_t -+grub_linuxefi_unload (void) -+{ -+ grub_dl_unref (my_mod); -+ loaded = 0; -+ if (initrd_mem) -+ grub_efi_free_pages((grub_efi_physical_address_t)initrd_mem, BYTES_TO_PAGES(params->ramdisk_size)); -+ if (linux_cmdline) -+ grub_efi_free_pages((grub_efi_physical_address_t)linux_cmdline, BYTES_TO_PAGES(params->cmdline_size + 1)); -+ if (kernel_mem) -+ grub_efi_free_pages((grub_efi_physical_address_t)kernel_mem, BYTES_TO_PAGES(kernel_size)); -+ if (params) -+ grub_efi_free_pages((grub_efi_physical_address_t)params, BYTES_TO_PAGES(16384)); -+ return GRUB_ERR_NONE; -+} -+ -+static grub_err_t -+grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), -+ int argc, char *argv[]) -+{ -+ grub_file_t *files = 0; -+ int i, nfiles = 0; -+ grub_size_t size = 0; -+ grub_uint8_t *ptr; -+ -+ if (argc == 0) -+ { -+ grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); -+ goto fail; -+ } -+ -+ if (!loaded) -+ { -+ grub_error (GRUB_ERR_BAD_ARGUMENT, N_("you need to load the kernel first")); -+ goto fail; -+ } -+ -+ files = grub_zalloc (argc * sizeof (files[0])); -+ if (!files) -+ goto fail; -+ -+ for (i = 0; i < argc; i++) -+ { -+ grub_file_filter_disable_compression (); -+ files[i] = grub_file_open (argv[i]); -+ if (! files[i]) -+ goto fail; -+ nfiles++; -+ size += ALIGN_UP (grub_file_size (files[i]), 4); -+ } -+ -+ initrd_mem = grub_efi_allocate_pages_max (0x3fffffff, BYTES_TO_PAGES(size)); -+ -+ if (!initrd_mem) -+ { -+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate initrd")); -+ goto fail; -+ } -+ -+ params->ramdisk_size = size; -+ params->ramdisk_image = (grub_uint32_t)(grub_uint64_t) initrd_mem; -+ -+ ptr = initrd_mem; -+ -+ for (i = 0; i < nfiles; i++) -+ { -+ grub_ssize_t cursize = grub_file_size (files[i]); -+ if (grub_file_read (files[i], ptr, cursize) != cursize) -+ { -+ if (!grub_errno) -+ grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"), -+ argv[i]); -+ goto fail; -+ } -+ ptr += cursize; -+ grub_memset (ptr, 0, ALIGN_UP_OVERHEAD (cursize, 4)); -+ ptr += ALIGN_UP_OVERHEAD (cursize, 4); -+ } -+ -+ params->ramdisk_size = size; -+ -+ fail: -+ for (i = 0; i < nfiles; i++) -+ grub_file_close (files[i]); -+ grub_free (files); -+ -+ if (initrd_mem && grub_errno) -+ grub_efi_free_pages((grub_efi_physical_address_t)initrd_mem, BYTES_TO_PAGES(size)); -+ -+ return grub_errno; -+} -+ -+static grub_err_t -+grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), -+ int argc, char *argv[]) -+{ -+ grub_file_t file = 0; -+ struct linux_kernel_header lh; -+ grub_ssize_t len, start, filelen; -+ void *kernel; -+ -+ grub_dl_ref (my_mod); -+ -+ if (argc == 0) -+ { -+ grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); -+ goto fail; -+ } -+ -+ file = grub_file_open (argv[0]); -+ if (! file) -+ goto fail; -+ -+ filelen = grub_file_size (file); -+ -+ kernel = grub_malloc(filelen); -+ -+ if (!kernel) -+ { -+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("cannot allocate kernel buffer")); -+ goto fail; -+ } -+ -+ if (grub_file_read (file, kernel, filelen) != filelen) -+ { -+ grub_error (GRUB_ERR_FILE_READ_ERROR, N_("Can't read kernel %s"), argv[0]); -+ goto fail; -+ } -+ -+ if (! grub_linuxefi_secure_validate (kernel, filelen)) -+ { -+ grub_error (GRUB_ERR_INVALID_COMMAND, N_("%s has invalid signature"), argv[0]); -+ grub_free (kernel); -+ goto fail; -+ } -+ -+ grub_file_seek (file, 0); -+ -+ grub_free(kernel); -+ -+ params = grub_efi_allocate_pages_max (0x3fffffff, BYTES_TO_PAGES(16384)); -+ -+ if (! params) -+ { -+ grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate kernel parameters"); -+ goto fail; -+ } -+ -+ memset (params, 0, 16384); -+ -+ if (grub_file_read (file, &lh, sizeof (lh)) != sizeof (lh)) -+ { -+ if (!grub_errno) -+ grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), -+ argv[0]); -+ goto fail; -+ } -+ -+ if (lh.boot_flag != grub_cpu_to_le16 (0xaa55)) -+ { -+ grub_error (GRUB_ERR_BAD_OS, N_("invalid magic number")); -+ goto fail; -+ } -+ -+ if (lh.setup_sects > GRUB_LINUX_MAX_SETUP_SECTS) -+ { -+ grub_error (GRUB_ERR_BAD_OS, N_("too many setup sectors")); -+ goto fail; -+ } -+ -+ if (lh.version < grub_cpu_to_le16 (0x020b)) -+ { -+ grub_error (GRUB_ERR_BAD_OS, N_("kernel too old")); -+ goto fail; -+ } -+ -+ if (!lh.handover_offset) -+ { -+ grub_error (GRUB_ERR_BAD_OS, N_("kernel doesn't support EFI handover")); -+ goto fail; -+ } -+ -+ linux_cmdline = grub_efi_allocate_pages_max(0x3fffffff, -+ BYTES_TO_PAGES(lh.cmdline_size + 1)); -+ -+ if (!linux_cmdline) -+ { -+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate cmdline")); -+ goto fail; -+ } -+ -+ grub_memcpy (linux_cmdline, LINUX_IMAGE, sizeof (LINUX_IMAGE)); -+ grub_create_loader_cmdline (argc, argv, -+ linux_cmdline + sizeof (LINUX_IMAGE) - 1, -+ lh.cmdline_size - (sizeof (LINUX_IMAGE) - 1)); -+ -+ lh.cmd_line_ptr = (grub_uint32_t)(grub_uint64_t)linux_cmdline; -+ -+ handover_offset = lh.handover_offset; -+ -+ start = (lh.setup_sects + 1) * 512; -+ len = grub_file_size(file) - start; -+ -+ kernel_mem = grub_efi_allocate_pages(lh.pref_address, -+ BYTES_TO_PAGES(lh.init_size)); -+ -+ if (!kernel_mem) -+ kernel_mem = grub_efi_allocate_pages_max(0x3fffffff, -+ BYTES_TO_PAGES(lh.init_size)); -+ -+ if (!kernel_mem) -+ { -+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate kernel")); -+ goto fail; -+ } -+ -+ if (grub_file_seek (file, start) == (grub_off_t) -1) -+ { -+ grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), -+ argv[0]); -+ goto fail; -+ } -+ -+ if (grub_file_read (file, kernel_mem, len) != len && !grub_errno) -+ { -+ grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), -+ argv[0]); -+ } -+ -+ if (grub_errno == GRUB_ERR_NONE) -+ { -+ grub_loader_set (grub_linuxefi_boot, grub_linuxefi_unload, 0); -+ loaded = 1; -+ lh.code32_start = (grub_uint32_t)(grub_uint64_t) kernel_mem; -+ } -+ -+ memcpy(params, &lh, 2 * 512); -+ -+ fail: -+ -+ if (file) -+ grub_file_close (file); -+ -+ if (grub_errno != GRUB_ERR_NONE) -+ { -+ grub_dl_unref (my_mod); -+ loaded = 0; -+ } -+ -+ if (linux_cmdline && !loaded) -+ grub_efi_free_pages((grub_efi_physical_address_t)linux_cmdline, BYTES_TO_PAGES(lh.cmdline_size + 1)); -+ -+ if (kernel_mem && !loaded) -+ grub_efi_free_pages((grub_efi_physical_address_t)kernel_mem, BYTES_TO_PAGES(kernel_size)); -+ -+ if (params && !loaded) -+ grub_efi_free_pages((grub_efi_physical_address_t)params, BYTES_TO_PAGES(16384)); -+ -+ return grub_errno; -+} -+ -+static grub_command_t cmd_linux, cmd_initrd; -+ -+GRUB_MOD_INIT(linuxefi) -+{ -+ cmd_linux = -+ grub_register_command ("linuxefi", grub_cmd_linux, -+ 0, N_("Load Linux.")); -+ cmd_initrd = -+ grub_register_command ("initrdefi", grub_cmd_initrd, -+ 0, N_("Load initrd.")); -+ my_mod = mod; -+} -+ -+GRUB_MOD_FINI(linuxefi) -+{ -+ grub_unregister_command (cmd_linux); -+ grub_unregister_command (cmd_initrd); -+} -diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h -index e67d92b..1b0e7ae 100644 ---- a/include/grub/efi/efi.h -+++ b/include/grub/efi/efi.h -@@ -40,6 +40,9 @@ void EXPORT_FUNC(grub_efi_stall) (grub_efi_uintn_t microseconds); - void * - EXPORT_FUNC(grub_efi_allocate_pages) (grub_efi_physical_address_t address, - grub_efi_uintn_t pages); -+void * -+EXPORT_FUNC(grub_efi_allocate_pages_max) (grub_efi_physical_address_t max, -+ grub_efi_uintn_t pages); - void EXPORT_FUNC(grub_efi_free_pages) (grub_efi_physical_address_t address, - grub_efi_uintn_t pages); - int -diff --git a/include/grub/i386/linux.h b/include/grub/i386/linux.h -index 9d064c8..c29c5af 100644 ---- a/include/grub/i386/linux.h -+++ b/include/grub/i386/linux.h -@@ -139,6 +139,7 @@ struct linux_kernel_header - grub_uint64_t setup_data; - grub_uint64_t pref_address; - grub_uint32_t init_size; -+ grub_uint32_t handover_offset; - } __attribute__ ((packed)); - - /* Boot parameters for Linux based on 2.6.12. This is used by the setup -diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c -index d06a0e3..b79e632 100644 ---- a/grub-core/loader/i386/efi/linux.c -+++ b/grub-core/loader/i386/efi/linux.c -@@ -326,6 +326,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - - memcpy(params, &lh, 2 * 512); - -+ params->type_of_loader = 0x21; -+ - fail: - - if (file) diff --git a/grub2-use-linuxefi.patch b/grub2-use-linuxefi.patch deleted file mode 100644 index 18684b0..0000000 --- a/grub2-use-linuxefi.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 151b1691fe0cf885df101c6e6a7cb1defc50428b Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Mon, 16 Jul 2012 18:57:11 -0400 -Subject: [PATCH] Use "linuxefi" and "initrdefi" where appropriate. - ---- - util/grub.d/10_linux.in | 18 ++++++++++++++++-- - 1 file changed, 16 insertions(+), 2 deletions(-) - -diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in -index cd543bd..e2b8ab3 100644 ---- a/util/grub.d/10_linux.in -+++ b/util/grub.d/10_linux.in -@@ -133,17 +133,31 @@ linux_entry () - printf '%s\n' "${prepare_boot_cache}" | sed "s/^/$submenu_indentation/" - fi - message="$(gettext_printf "Loading Linux %s ..." ${version})" -- sed "s/^/$submenu_indentation/" << EOF -+ if [ -d /sys/firmware/efi ]; then -+ sed "s/^/$submenu_indentation/" << EOF -+ echo '$message' -+ linuxefi ${rel_dirname}/${basename} root=${linux_root_device_thisversion} ro ${args} -+EOF -+ else -+ sed "s/^/$submenu_indentation/" << EOF - echo '$message' - linux ${rel_dirname}/${basename} root=${linux_root_device_thisversion} ro ${args} - EOF -+ fi - if test -n "${initrd}" ; then - # TRANSLATORS: ramdisk isn't identifier. Should be translated. - message="$(gettext_printf "Loading initial ramdisk ...")" -- sed "s/^/$submenu_indentation/" << EOF -+ if [ -d /sys/firmware/efi ]; then -+ sed "s/^/$submenu_indentation/" << EOF -+ echo '$message' -+ initrdefi ${rel_dirname}/${initrd} -+EOF -+ else -+ sed "s/^/$submenu_indentation/" << EOF - echo '$message' - initrd ${rel_dirname}/${initrd} - EOF -+ fi - fi - sed "s/^/$submenu_indentation/" << EOF - } --- -1.7.10.4 - diff --git a/grub2.spec b/grub2.spec index f71e27e..275b2fe 100644 --- a/grub2.spec +++ b/grub2.spec @@ -41,7 +41,7 @@ Name: grub2 Epoch: 1 Version: 2.00 -Release: 16%{?dist} +Release: 18%{?dist} Summary: Bootloader with support for Linux, Multiboot and more Group: System Environment/Base @@ -53,34 +53,369 @@ Source3: README.Fedora Source4: http://unifoundry.com/unifont-5.1.20080820.pcf.gz Source5: theme.tar.bz2 #Source6: grub-cd.cfg -Patch2: grub-1.99-just-say-linux.patch -Patch5: grub-1.99-ppc-terminfo.patch -Patch10: grub-2.00-add-fw_path-search_v2.patch -Patch11: grub-2.00-Add-fwsetup.patch -Patch13: grub-2.00-Dont-set-boot-on-ppc.patch -Patch18: grub-2.00-ignore-gnulib-gets-stupidity.patch -#Patch19: grub-2.00-who-trusts-you-and-who-do-you-trust.patch -Patch20: grub2-linuxefi.patch -Patch21: grub2-cdpath.patch -Patch22: grub2-use-linuxefi.patch -Patch23: grub-2.00-dont-decrease-mmap-size.patch -Patch24: grub-2.00-no-insmod-on-sb.patch -Patch25: grub-2.00-efidisk-ahci-workaround.patch -Patch26: grub-2.00-increase-the-ieee1275-device-path-buffer-size.patch -Patch27: grub-2.00-Handle-escapes-in-labels.patch -Patch28: grub-2.00-fix-http-crash.patch -Patch29: grub-2.00-Issue-separate-DNS-queries-for-ipv4-and-ipv6.patch -Patch30: grub-2.00-cas-reboot-support.patch -Patch31: grub-2.00-for-ppc-include-all-modules-in-the-core-image.patch -Patch32: add-vlan-tag-support.patch -Patch33: follow-the-symbolic-link-ieee1275.patch -Patch34: grub-2.00-add-X-option-to-printf-functions.patch -Patch35: grub-2.00-dhcp-client-id-and-uuid-options-added.patch -Patch36: grub-2.00-search-for-specific-config-file-for-netboot.patch -Patch37: grub2-add-bootpath-device-to-the-list.patch -Patch38: grub-2.00-add-GRUB-DISABLE-SUBMENU-option.patch -Patch39: grub-2.00-support-bls-config.patch -Patch40: grub-2.00-fix-docs.patch +Patch0001: 0001-Add-monochrome-text-support-mda_text-aka-hercules-in.patch +Patch0002: 0002-missing-file-from-last-commit.patch +Patch0003: 0003-grub-core-loader-i386-linux.c-find_efi_mmap_size-Don.patch +Patch0004: 0004-include-grub-list.h-FOR_LIST_ELEMENTS_SAFE-New-macro.patch +Patch0005: 0005-gentpl.py-Make-mans-depend-on-grub-mkconfig_lib.patch +Patch0006: 0006-grub-core-net-tftp.c-ack-Fix-endianness-problem.patch +Patch0007: 0007-grub-core-fs-ext2.c-Experimental-support-for-64-bit.patch +Patch0008: 0008-grub-core-term-efi-serial.c-Support-1.5-stop-bits.patch +Patch0009: 0009-grub-core-lib-legacy_parse.c-Support-clear-and-testl.patch +Patch0010: 0010-grub-core-Makefile.am-Fix-path-to-boot-i386-pc-start.patch +Patch0011: 0011-Fix-coreboot-compilation.patch +Patch0012: 0012-grub-core-normal-autofs.c-autoload_fs_module-Save-an.patch +Patch0013: 0013-grub-core-lib-xzembed-xz_dec_stream.c-hash_validate-.patch +Patch0014: 0014-grub-core-loader-i386-bsd.c-grub_bsd_elf32_size_hook.patch +Patch0015: 0015-New-command-lsefi.patch +Patch0016: 0016-util-grub-mkconfig_lib.in-grub_quote-Remove-extra-la.patch +Patch0017: 0017-EHCI-and-OHCI-PCI-bus-master.patch +Patch0018: 0018-Update-manual-NetBSD-wise.patch +Patch0019: 0019-Regenerate-po-POTFILES.in-with-the-following-commman.patch +Patch0020: 0020-Strengthen-the-configure-test-for-working-nostdinc-i.patch +Patch0021: 0021-.bzrignore-Add-grub-bios-setup-grub-ofpathname-and.patch +Patch0022: 0022-docs-man-grub-mkdevicemap.h2m-Remove-since-grub-mkde.patch +Patch0023: 0023-grub-core-mmap-mips-loongson-Remove-empty-directory.patch +Patch0024: 0024-Makefile.am-EXTRA_DIST-Add.patch +Patch0025: 0025-Makefile.am-EXTRA_DIST-Add-linguas.sh.-It-s-only-str.patch +Patch0026: 0026-grub-core-fs-xfs.c-grub_xfs_read_block-Make-keys-a-c.patch +Patch0027: 0027-grub-core-partmap-dvh.c-grub_dvh_is_valid-Add-missin.patch +Patch0028: 0028-grub-core-script-yylex.l-Ignore-unused-function-and-.patch +Patch0029: 0029-grub-core-disk-ieee1275-ofdisk.c-scan-Check-function.patch +Patch0030: 0030-util-import_gcry.py-Sort-cipher_files-to-make-build-.patch +Patch0031: 0031-NEWS-Fix-typo.patch +Patch0032: 0032-configure.ac-Add-SuSe-path.patch +Patch0033: 0033-grub-core-Makefile.core.def-efifwsetup-New-module.patch +Patch0034: 0034-grub-core-loader-efi-appleloader.c-devpath_8-New-var.patch +Patch0035: 0035-grub-core-disk-diskfilter.c-free_array-GRUB_UTIL-Fix.patch +Patch0036: 0036-Don-t-require-grub-mkconfig_lib-to-generate-manpages.patch +Patch0037: 0037-include-grub-efi-api.h-grub_efi_runtime_services-Mak.patch +Patch0038: 0038-grub-core-term-terminfo.c-Only-fix-up-powerpc-key-re.patch +Patch0039: 0039-util-grub-mkconfig_lib.in-grub_quote-Remove-outdated.patch +Patch0040: 0040-grub-core-loader-i386-linux.c-grub_cmd_linux-Fix-inc.patch +Patch0041: 0041-grub-core-kern-ieee1275-cmain.c-grub_ieee1275_find_o.patch +Patch0042: 0042-util-grub-mkconfig_lib.in-grub_tab-New-variable.patch +Patch0043: 0043-util-grub-setup.c-write_rootdev-Remove-unused-core_i.patch +Patch0044: 0044-grub-core-partmap-msdos.c-pc_partition_map_embed-Rev.patch +Patch0045: 0045-Fix-grub-emu-build-on-FreeBSD.patch +Patch0046: 0046-util-grub-install.in-Make-the-error-message-if-sourc.patch +Patch0047: 0047-grub-core-fs-affs.c-grub_affs_mount-Support-AFFS-boo.patch +Patch0048: 0048-util-grub-mkconfig_lib.in-is_path_readable_by_grub-R.patch +Patch0049: 0049-Makefile.util.def-grub-mknetdir-Move-to-prefix-bin.patch +Patch0050: 0050-grub-core-loader-i386-linux.c-allocate_pages-Fix-spe.patch +Patch0051: 0051-grub-core-Makefile.am-moddep.lst-Use-AWK-instead-of-.patch +Patch0052: 0052-grub-core-commands-configfile.c-GRUB_MOD_INIT-Correc.patch +Patch0053: 0053-Fix-ordering-and-tab-indentation-of-NetBSD-boot-menu.patch +Patch0054: 0054-grub-core-net-bootp.c-parse_dhcp_vendor-Fix-double-i.patch +Patch0055: 0055-include-grub-types.h-Fix-functionality-unaffecting-t.patch +Patch0056: 0056-Support-big-endian-UFS1.patch +Patch0057: 0057-Fix-big-endian-mtime.patch +Patch0058: 0058-grub-core-fs-ufs.c-grub_ufs_dir-Stop-if-direntlen-is.patch +Patch0059: 0059-util-getroot.c-convert_system_partition_to_system_di.patch +Patch0060: 0060-util-grub-mkfont.c-argp_parser-Fix-a-typo-which-prev.patch +Patch0061: 0061-grub-core-term-gfxterm.c-grub_virtual_screen_setup-G.patch +Patch0062: 0062-grub-core-gfxmenu-view.c-init_terminal-Avoid-making-.patch +Patch0063: 0063-grub-core-kern-ieee1275-init.c-grub_machine_get_boot.patch +Patch0064: 0064-util-grub-install.in-Remove-stale-TODO.patch +Patch0065: 0065-util-grub-install.in-Follow-the-symbolic-link-parame.patch +Patch0066: 0066-grub-core-disk-cryptodisk.c-grub_cmd_cryptomount-Str.patch +Patch0067: 0067-docs-grub.texi-Network-Update-instructions-on-genera.patch +Patch0068: 0068-util-grub.d-20_linux_xen.in-Addmissing-assignment-to.patch +Patch0069: 0069-Backport-gnulib-fixes-for-C11.-Fixes-Savannah-bug-37.patch +Patch0070: 0070-Apply-program-name-transformations-at-build-time-rat.patch +Patch0071: 0071-neater-gnulib-backport.patch +Patch0072: 0072-util-grub-mkconfig.in-Accept-GRUB_TERMINAL_OUTPUT-vg.patch +Patch0073: 0073-grub-core-bus-usb-ehci.c-grub_ehci_pci_iter-Remove-i.patch +Patch0074: 0074-Remove-several-trivially-unnecessary-uses-of-nested-.patch +Patch0075: 0075-docs-grub.texi-configfile-Explain-environment-variab.patch +Patch0076: 0076-Fix-failing-printf-test.patch +Patch0077: 0077-grub-core-tests-lib-test.c-grub_test_run-Return-non-.patch +Patch0078: 0078-docs-grub.texi-Invoking-grub-mount-New-section.patch +Patch0079: 0079-docs-grub.texi-Invoking-grub-mkrelpath-New-section.patch +Patch0080: 0080-grub-core-fs-iso9660.c-grub_iso9660_susp_iterate-Avo.patch +Patch0081: 0081-configure.ac-Extend-Wno-trampolines-to-host.patch +Patch0082: 0082-util-grub.d-10_kfreebsd.in-Fix-improper-references-t.patch +Patch0083: 0083-util-grub.d-10_kfreebsd.in-Correct-the-patch-to-zpoo.patch +Patch0084: 0084-grub-core-disk-diskfilter.c-grub_diskfilter_write-Ca.patch +Patch0085: 0085-grub-core-fs-nilfs2.c-grub_nilfs2_palloc_groups_per_.patch +Patch0086: 0086-grub-core-fs-ntfs.c-Eliminate-useless-divisions-in-f.patch +Patch0087: 0087-grub-core-fs-ext2.c-grub_ext2_read_block-Use-shifts-.patch +Patch0088: 0088-grub-core-fs-minix.c-grub_minix_read_file-Simplify-a.patch +Patch0089: 0089-docs-grub.texi-grub_cpu-New-subsection.patch +Patch0090: 0090-grub-core-io-bufio.c-grub_bufio_open-Use-grub_zalloc.patch +Patch0091: 0091-grub-core-kern-disk.c-grub_disk_write-Fix-sector-num.patch +Patch0092: 0092-Support-Apple-FAT-binaries-on-non-Apple-platforms.patch +Patch0093: 0093-grub-core-fs-ntfs.c-Ue-more-appropriate-types.patch +Patch0094: 0094-Import-gcrypt-public-key-cryptography-and-implement-.patch +Patch0095: 0095-Clean-up-dangling-references-to-grub-setup.patch +Patch0096: 0096-autogen.sh-Do-not-try-to-delete-nonexistant-files.patch +Patch0097: 0097-Remove-autogenerated-files-from-VCS.patch +Patch0098: 0098-grub-core-lib-libgcrypt_wrap-mem.c-_gcry_log_bug-Mak.patch +Patch0099: 0099-grub-core-lib-libgcrypt_wrap-mem.c-gcry_x-alloc-Make.patch +Patch0100: 0100-grub-core-commands-verify.c-Mark-messages-for-transl.patch +Patch0101: 0101-Remove-nested-functions-from-PCI-iterators.patch +Patch0102: 0102-util-grub-mkimage.c-generate_image-Fix-size-of-publi.patch +Patch0103: 0103-New-command-list_trusted.patch +Patch0104: 0104-Fix-compilation-with-older-compilers.patch +Patch0105: 0105-grub-core-kern-emu-hostdisk.c-read_device_map-Explic.patch +Patch0106: 0106-Remove-nested-functions-from-memory-map-iterators.patch +Patch0107: 0107-Remove-nested-functions-from-script-reading-and-pars.patch +Patch0108: 0108-grub-core-script-lexer.c-grub_script_lexer_init-Rena.patch +Patch0109: 0109-Improve-bidi-handling-in-entry-editor.patch +Patch0110: 0110-New-terminal-outputs-using-serial-morse-and-spkmodem.patch +Patch0111: 0111-Add-new-command-pcidump.patch +Patch0112: 0112-Rewrite-spkmodem-to-use-PIT-for-timing.-Double-the-s.patch +Patch0113: 0113-Add-license-header-to-spkmodem-recv.c.patch +Patch0114: 0114-Fix-typos-for-developer-and-development.patch +Patch0115: 0115-Remove-nested-functions-from-device-iterators.patch +Patch0116: 0116-Remove-nested-functions-from-ELF-iterators.patch +Patch0117: 0117-util-grub-script-check.c-main-Uniform-the-error-mess.patch +Patch0118: 0118-docs-grub.texi-Simple-configuration-Clarify-GRUB_HID.patch +Patch0119: 0119-Split-long-USB-transfers-into-short-ones.patch +Patch0120: 0120-include-grub-elf.h-Update-ARM-definitions-based-on-b.patch +Patch0121: 0121-conf-Makefile.common-Fix-autogen-rules-to-pass-defin.patch +Patch0122: 0122-grub-core-loader-i386-linux.c-grub_cmd_initrd-Don-t-.patch +Patch0123: 0123-util-grub-mkimage.c-main-Postpone-freeing-arguments..patch +Patch0124: 0124-docs-grub.texi-Multi-boot-manual-config-Fix-typo-for.patch +Patch0125: 0125-Remove-nested-functions-from-filesystem-directory-it.patch +Patch0126: 0126-grub-core-partmap-msdos.c-embed_signatures-Add-the-s.patch +Patch0127: 0127-Improve-spkmomdem-reliability-by-adding-a-separator-.patch +Patch0128: 0128-grub-core-commands-lsmmap.c-Fix-unused-variable-on-e.patch +Patch0129: 0129-grub-core-disk-arc-arcdisk.c-grub_arcdisk_iterate-Fi.patch +Patch0130: 0130-Fix-powerpc-and-sparc64-build-failures-caused-by-un-.patch +Patch0131: 0131-grub-core-commands-ls.c-grub_ls_print_devices-Add-mi.patch +Patch0132: 0132-Make-color-variables-global-instead-of-it-being-per-.patch +Patch0133: 0133-Improve-spkmomdem-reliability-by-adding-a-separator-.patch +Patch0134: 0134-grub-core-normal-term.c-print_ucs4_terminal-Don-t-ou.patch +Patch0135: 0135-Improve-spkmodem-reliability-by-adding-a-separator-b.patch +Patch0136: 0136-Remove-nested-functions-from-USB-iterators.patch +Patch0137: 0137-grub-core-font-font.c-blit_comb-do_blit-Make-static-.patch +Patch0138: 0138-include-grub-kernel.h-FOR_MODULES-Adjust-to-preserve.patch +Patch0139: 0139-grub-core-lib-libgcrypt_wrap-cipher_wrap.h-Include-s.patch +Patch0140: 0140-util-grub-reboot.in-usage-Document-the-need-for.patch +Patch0141: 0141-Improve-FreeDOS-direct-loading-support-compatibility.patch +Patch0142: 0142-grub-core-normal-menu_text.c-grub_menu_init_page-Fix.patch +Patch0143: 0143-util-grub-install.in-change-misleading-comment-about.patch +Patch0144: 0144-grub-core-fs-xfs.c-grub_xfs_read_block-Fix-computati.patch +Patch0145: 0145-grub-core-bus-usb-serial-common.c-grub_usbserial_att.patch +Patch0146: 0146-grub-core-bus-usb-usb.c-grub_usb_device_attach-Add-m.patch +Patch0147: 0147-grub-core-commands-lsacpi.c-Show-more-info.-Hide-som.patch +Patch0148: 0148-Missing-part-of-last-commit.patch +Patch0149: 0149-Implement-USBDebug-full-USB-stack-variant.patch +Patch0150: 0150-grub-core-fs-fshelp.c-find_file-Set-oldnode-to-zero-.patch +Patch0151: 0151-grub-core-disk-cryptodisk.c-grub_cryptodisk_scan_dev.patch +Patch0152: 0152-grub-core-commands-lsacpi.c-Fix-types-on-64-bit-plat.patch +Patch0153: 0153-Support-Openfirmware-disks-with-non-512B-sectors.patch +Patch0154: 0154-Implement-new-command-cmosdump.patch +Patch0155: 0155-grub-core-normal-misc.c-grub_normal_print_device_inf.patch +Patch0156: 0156-Makefile.util.def-Add-partmap-msdos.c-to-common-libr.patch +Patch0157: 0157-grub-core-normal-menu_entry.c-insert_string-fix-off-.patch +Patch0158: 0158-grub-core-normal-menu_entry.c-update_screen-remove.patch +Patch0159: 0159-grub-core-disk-efi-efidisk.c-grub_efidisk_get_device.patch +Patch0160: 0160-grub-core-partmap-msdos.c-grub_partition_msdos_itera.patch +Patch0161: 0161-Remove-nested-functions-from-disk-and-file-read-hook.patch +Patch0162: 0162-grub-core-loader-machoXX.c-Remove-nested-functions.patch +Patch0163: 0163-util-grub-fstest.c-Remove-nested-functions.patch +Patch0164: 0164-grub-core-commands-parttool.c-grub_cmd_parttool-Move.patch +Patch0165: 0165-grub-core-fs-iso9660.c-Remove-nested-functions.patch +Patch0166: 0166-grub-core-fs-minix.c-Remove-nested-functions.patch +Patch0167: 0167-grub-core-fs-jfs.c-Remove-nested-functions.patch +Patch0168: 0168-grub-core-lib-arg.c-grub_arg_show_help-Move-showargs.patch +Patch0169: 0169-grub-core-kern-i386-coreboot-mmap.c-grub_linuxbios_t.patch +Patch0170: 0170-Enable-linux16-on-non-BIOS-systems-for-i.a.-memtest.patch +Patch0171: 0171-grub-core-kern-main.c-grub_set_prefix_and_root-Strip.patch +Patch0172: 0172-grub-core-disk-efi-efidisk.c-Transform-iterate_child.patch +Patch0173: 0173-grub-core-loader-i386-pc-linux.c-grub_cmd_linux-Fix-.patch +Patch0174: 0174-Remove-nested-functions-from-videoinfo-iterators.patch +Patch0175: 0175-grub-core-gentrigtables.c-Make-tables-const.patch +Patch0176: 0176-grub-core-kern-emu-hostdisk.c-read_device_map-Remove.patch +Patch0177: 0177-util-grub-editenv.c-list_variables-Move-print_var-ou.patch +Patch0178: 0178-grub-core-fs-hfsplus.c-grub_hfsplus_btree_iterate_no.patch +Patch0179: 0179-grub-core-fs-hfs.c-Remove-nested-functions.patch +Patch0180: 0180-grub-core-commands-loadenv.c-grub_cmd_list_env-Move-.patch +Patch0181: 0181-grub-core-normal-charset.c-grub_bidi_logical_to_visu.patch +Patch0182: 0182-grub-core-script-execute.c-gettext_append-Remove-nes.patch +Patch0183: 0183-grub-core-lib-ia64-longjmp.S-Fix-the-name-of-longjmp.patch +Patch0184: 0184-Make-elfload-not-use-hooks.-Opt-for-flags-and-iterat.patch +Patch0185: 0185-grub-core-kern-term.c-grub_term_normal_color.patch +Patch0186: 0186-Move-to-more-hookless-approach-in-IEEE1275-devices-h.patch +Patch0187: 0187-include-grub-mips-loongson-cmos.h-Fix-high-CMOS-addr.patch +Patch0188: 0188-include-grub-cmos.h-Handle-high-CMOS-addresses-on-sp.patch +Patch0189: 0189-grub-core-disk-ieee1275-nand.c-Fix-compilation-on.patch +Patch0190: 0190-grub-core-kern-env.c-include-grub-env.h-Change-itera.patch +Patch0191: 0191-grub-core-commands-regexp.c-set_matches-Move-setvar-.patch +Patch0192: 0192-grub-core-script-execute.c-grub_script_arglist_to_ar.patch +Patch0193: 0193-Remove-all-trampoline-support.-Add-Wtrampolines-when.patch +Patch0194: 0194-grub-core-term-terminfo.c-grub_terminfo_cls-Issue-an.patch +Patch0195: 0195-Lift-up-core-size-limits-on-some-platforms.-Fix-pote.patch +Patch0196: 0196-grub-core-normal-crypto.c-read_crypto_list-Fix-incor.patch +Patch0197: 0197-grub-core-commands-acpi.c-grub_acpi_create_ebda-Don-.patch +Patch0198: 0198-grub-core-fs-iso9660.c-add_part-Remove-always_inline.patch +Patch0199: 0199-grub-core-fs-fshelp.c-grub_fshelp_log2blksize-Remove.patch +Patch0200: 0200-Avoid-costly-64-bit-division-in-grub_get_time_ms-on-.patch +Patch0201: 0201-grub-core-fs-hfs.c-grub_hfs_read_file-Avoid-divmod64.patch +Patch0202: 0202-Adjust-types-in-gdb-module-to-have-intended-unsigned.patch +Patch0203: 0203-grub-core-video-i386-pc-vbe.c.patch +Patch0204: 0204-include-grub-datetime.h-grub_datetime2unixtime-Fix-u.patch +Patch0205: 0205-grub-core-loader-i386-pc-plan9.c-fill_disk-Fix-types.patch +Patch0206: 0206-grub-core-commands-verify.c-grub_verify_signature-Us.patch +Patch0207: 0207-grub-core-lib-arg.c-grub_arg_list_alloc-Use-shifts-r.patch +Patch0208: 0208-grub-core-loader-i386-bsdXX.c-grub_openbsd_find_ramd.patch +Patch0209: 0209-Resend-a-packet-if-we-got-the-wrong-buffer-in-status.patch +Patch0210: 0210-Better-estimate-the-maximum-USB-transfer-size.patch +Patch0211: 0211-remove-get_endpoint_descriptor-and-change-all-functi.patch +Patch0212: 0212-Implement-boot-time-analysis-framework.patch +Patch0213: 0213-Fix-USB-devices-not-being-detected-when-requested.patch +Patch0214: 0214-Initialize-USB-ports-in-parallel-to-speed-up-boot.patch +Patch0215: 0215-include-grub-boottime.h-Add-missing-file.patch +Patch0216: 0216-Fix-a-conflict-between-ports-structures-with-2-contr.patch +Patch0217: 0217-New-commands-cbmemc-lscoreboot-coreboot_boottime-to-.patch +Patch0218: 0218-grub-core-commands-boottime.c-Fix-copyright-header.patch +Patch0219: 0219-Slight-improve-in-USB-related-boot-time-checkpoints.patch +Patch0220: 0220-grub-core-commands-verify.c-hashes-Add-several-hashe.patch +Patch0221: 0221-po-POTFILES.in-Regenerate.patch +Patch0222: 0222-grub-core-commands-i386-coreboot-cbls.c-Fix-typos-an.patch +Patch0223: 0223-Add-ability-to-generate-newc-additions-on-runtime.patch +Patch0224: 0224-grub-core-fs-zfs-zfs.c-Fix-incorrect-handling-of-spe.patch +Patch0225: 0225-grub-core-term-at_keyboard.c-Increase-robustness-on-.patch +Patch0226: 0226-Add-new-proc-filesystem-framework-and-put-luks_scrip.patch +Patch0227: 0227-grub-core-Makefile.core.def-vbe-Disable-on-coreboot-.patch +Patch0228: 0228-util-grub-mkconfig_lib.in-prepare_grub_to_access_dev.patch +Patch0229: 0229-grub-core-Makefile.core.def-vga-Disable-on-coreboot-.patch +Patch0230: 0230-util-grub.d-20_linux_xen.in-Automatically-add-no-rea.patch +Patch0231: 0231-Replace-the-region-at-0-from-coreboot-tables-to-avai.patch +Patch0232: 0232-grub-core-normal-menu.c-Wait-if-there-were-errors-sh.patch +Patch0233: 0233-grub-core-disk-ahci.c-Give-more-time-for-AHCI-reques.patch +Patch0234: 0234-grub-core-gfxmenu-font.c-grub_font_get_string_width-.patch +Patch0235: 0235-grub-core-commands-acpihalt.c-skip_ext_op-Add-suppor.patch +Patch0236: 0236-grub-core-kern-efi-mm.c-grub_efi_finish_boot_service.patch +Patch0237: 0237-grub-core-commands-verify.c-Fix-hash-algorithms-valu.patch +Patch0238: 0238-INSTALL-Mention-xorriso-requirement.patch +Patch0239: 0239-grub-core-partmap-apple.c-apple_partition_map_iterat.patch +Patch0240: 0240-grub-core-gfxmenu-gui_circular_progress.c-Fix-off-by.patch +Patch0241: 0241-grub-core-gfxmenu-view.c-Fix-off-by-one-error.patch +Patch0242: 0242-grub-core-gfxmenu-gui_circular_progress.c-Take-both-.patch +Patch0243: 0243-grub-core-gfxmenu-gui_progress_bar.c-Handle-padding-.patch +Patch0244: 0244-include-grub-elf.h-Add-missing-ARM-relocation-codes-.patch +Patch0245: 0245-util-grub-mount.c-fuse_init-Return-error-if-fuse_mai.patch +Patch0246: 0246-Fix-screen-corruption-in-menu-entry-editor-and-simpl.patch +Patch0247: 0247-grub-core-term-i386-pc-console.c-grub_console_getwh-.patch +Patch0248: 0248-grub-core-commands-verify.c-Save-verified-file-to-av.patch +Patch0249: 0249-grub-core-lib-posix_wrap-locale.h-GRUB_UTIL-Include-.patch +Patch0250: 0250-util-grub-setup.c-setup-Handle-some-corner-cases.patch +Patch0251: 0251-grub-core-bus-usb-usbtrans.c-grub_usb_bulk_readwrite.patch +Patch0252: 0252-Use-TSC-as-a-possible-time-source-on-i386-ieee1275.patch +Patch0253: 0253-grub-core-disk-efi-efidisk.c-Handle-partitions-on-no.patch +Patch0254: 0254-Unify-file-copying-setup-across-different-install-sc.patch +Patch0255: 0255-util-grub-mkimage.c-Introduce-new-define-EFI32_HEADE.patch +Patch0256: 0256-docs-grub.texi-Document-menuentry-id-option.patch +Patch0257: 0257-docs-grub.texi-Document-more-user-commands.patch +Patch0258: 0258-Move-GRUB_CHAR_BIT-to-types.h.patch +Patch0259: 0259-include-grub-bsdlabel.h-Use-enums.patch +Patch0260: 0260-grub-core-commands-verify.c-Use-GRUB_CHAR_BIT.patch +Patch0261: 0261-Add-new-defines-GRUB_RSDP_SIGNATURE_SIZE-and-GRUB_RS.patch +Patch0262: 0262-Replace-8-with-GRUB_CHAR_BIT-in-several-places-when-.patch +Patch0263: 0263-grub-core-commands-acpi.c-Use-sizeof-rather-than-har.patch +Patch0264: 0264-util-grub-mkfont.c-Prefer-enum-to-define.patch +Patch0265: 0265-Use-GRUB_PROPERLY_ALIGNED_ARRAY-in-grub-core-disk-cr.patch +Patch0266: 0266-util-grub.d-30_os-prober.in-Support-btrrfs-linux-pro.patch +Patch0267: 0267-util-grub-install_header-Use-PACKAGE-.mo-in-message-.patch +Patch0268: 0268-conf-Makefile.extra-dist-EXTRA_DIST-Add.patch +Patch0269: 0269-grub-core-normal-term.c-Few-more-fixes-for-menu-entr.patch +Patch0270: 0270-grub-core-normal-term.c-Few-more-fixes-for-menu-entr.patch +Patch0271: 0271-docs-grub-dev.texi-Move-itemize-after-subsection-to-.patch +Patch0272: 0272-grub-core-term-i386-pc-console.c-Fix-cursor-moving-a.patch +Patch0273: 0273-grub-core-Makefile.core.def-Add-kern-elfXX.c-to-elf-.patch +Patch0274: 0274-Fix-ia64-efi-image-generation-on-big-endian-machines.patch +Patch0275: 0275-autogen.sh-Use-h-not-f-to-test-for-existence-of-symb.patch +Patch0276: 0276-Fix-missing-PVs-if-they-don-t-contain-interesting-LV.patch +Patch0277: 0277-util-grub.d-30_os-prober.in-Add-onstr-to-entries-for.patch +Patch0278: 0278-Use-ACPI-shutdown-intests-as-traditional-port-was-re.patch +Patch0279: 0279-Import-new-gnulib.patch +Patch0280: 0280-docs-grub.texi-Fix-description-of-GRUB_CMDLINE_XEN-a.patch +Patch0281: 0281-Merge-powerpc-grub-mkrescue-flavour-with-common.-Use.patch +Patch0282: 0282-Support-i386-ieee1275-grub-mkrescue-and-make-check-o.patch +Patch0283: 0283-tests-partmap_test.in-Fix-missing-qemudisk-setting.patch +Patch0284: 0284-tests-grub_cmd_date.in-New-test-for-datetime.patch +Patch0285: 0285-docs-grub.texi-Update-coreboot-status-info.patch +Patch0286: 0286-Turn-off-QEMU-ACPI-way-since-new-releases-don-t-have.patch +Patch0287: 0287-tests-util-grub-shell.in-Fix-it-on-powerpc.patch +Patch0288: 0288-Disable-partmap-check-on-i386-ieee1275-due-to-openfi.patch +Patch0289: 0289-grub-core-net-drivers-ieee1275-ofnet.c-Don-t-attempt.patch +Patch0290: 0290-grub-core-net-http.c-Fix-bad-free.patch +Patch0291: 0291-Fix-handling-of-split-transfers.patch +Patch0292: 0292-grub-core-bus-usb-ehci.c-grub_ehci_fini_hw-Ignore-er.patch +Patch0293: 0293-util-grub-mkimage.c-Document-memdisk-implying-prefix.patch +Patch0294: 0294-Handle-Japanese-special-keys.patch +Patch0295: 0295-Replace-stpcpy-with-grub_stpcpy-in-tools.patch +Patch0296: 0296-Better-support-Apple-Intel-Macs-on-CD.patch +Patch0297: 0297-util-grub-mkrescue.in-Fix-wrong-architecture-for-ppc.patch +Patch0298: 0298-docs-man-grub-glue-efi.h2m-Add-missing-file.patch +Patch0299: 0299-Fix-memory-leaks-in-ofnet.patch +Patch0300: 0300-grub-core-kern-ieee1275-cmain.c-grub_ieee1275_find_o.patch +Patch0301: 0301-grub-core-disk-ieee1275-ofdisk.c-Iterate-over-bootpa.patch +Patch0302: 0302-Allow-IEEE1275-ports-on-path-even-if-it-wasn-t-detec.patch +Patch0303: 0303-Support-mkrescue-on-sparc64.patch +Patch0304: 0304-Support-grub-shell-on-sparc64.patch +Patch0305: 0305-tests-partmap_test.in-Skip-on-sparc64.patch +Patch0306: 0306-tests-grub_cmd_date.in-Add-missing-exit-1.patch +Patch0307: 0307-Move-GRUB-out-of-system-area-when-using-xorriso-1.2..patch +Patch0308: 0308-grub-core-loader-i386-linux.c-Remove-useless-leftove.patch +Patch0309: 0309-docs-grub-dev.texi-Rearrange-menu-to-match-the-secti.patch +Patch0310: 0310-Add-option-to-compress-files-on-install-image-creati.patch +Patch0311: 0311-grub-core-lib-posix_wrap-sys-types.h-Make-WORDS_BIGE.patch +Patch0312: 0312-grub-core-disk-ieee1275-ofdisk.c-Fix-CD-ROM-and-boot.patch +Patch0313: 0313-grub-core-kern-ieee1275-openfw.c-grub_ieee1275_deval.patch +Patch0314: 0314-tests-grub_script_expansion.in-Use-fixed-string-grep.patch +Patch0315: 0315-tests-grub_cmd_date.in-Skip-on-sparc64.patch +Patch0316: 0316-Fix-DMRAID-partition-handling.patch +Patch0317: 0317-grub-core-disk-efi-efidisk.c-Limit-disk-read-or-writ.patch +Patch0318: 0318-autogen.sh-Use-f-in-addition-for-h-when-checking-fil.patch +Patch0319: 0319-grub-core-disk-efi-efidisk.c-Really-limit-transfer-c.patch +Patch0320: 0320-build-aux-snippet-Add-missing-gnulib-files.patch +Patch0321: 0321-grub-core-disk-efi-efidisk.c-Detect-floppies-by-ACPI.patch +Patch0322: 0322-util-grub-mkrescue.in-Add-GPT-for-EFI-boot.patch +Patch0323: 0323-Add-support-for-pseries-and-other-bootinfo-machines-.patch +Patch0324: 0324-util-grub.d-30_os-prober.in-Add-onstr-to-linux-entri.patch +Patch0325: 0325-grub-core-kern-elfXX.c-grub_elfXX_load-Handle.patch +Patch0326: 0326-grub-core-commands-videotest.c-grub_cmd_videotest-Fi.patch +Patch0327: 0327-grub-core-kern-ieee1275-cmain.c-grub_ieee1275_find_o.patch +Patch0328: 0328-grub-core-kern-ieee1275-init.c-grub_claim_heap-Impro.patch +Patch0329: 0329-grub-core-lib-efi-relocator.c-grub_relocator_firmwar.patch +Patch0330: 0330-grub-core-Makefile.core.def-legacycfg-Enable-on-EFI.patch +Patch0331: 0331-grub-core-kern-mm.c-grub_mm_init_region-Fix-conditio.patch +Patch0332: 0332-Support-coreboot-framebuffer.patch +Patch0333: 0333-grub-core-disk-arc-arcdisk.c-grub_arcdisk_iterate_it.patch +Patch0334: 0334-Move-mips-arc-link-address.-Previous-link-address-wa.patch +Patch0335: 0335-grub-core-kern-dl.c-grub_dl_resolve_symbols-Handle-m.patch +Patch0336: 0336-util-grub-mkrescue.in-Add-mips-arc-support.patch +Patch0337: 0337-Add-missing-video-ids-to-coreboot-and-ieee1275-video.patch +Patch0338: 0338-grub-core-disk-ata.c-grub_ata_real_open-Use-grub_err.patch +Patch0339: 0339-grub-core-loader-i386-linux.c-grub_linux_boot-Defaul.patch +Patch0340: 0340-grub-core-normal-menu_text.c-print_entry-Put-an-aste.patch +Patch0341: 0341-util-grub-install.in-Fix-target-fo-qemu_mips.patch +Patch0342: 0342-Don-t-say-GNU-Linux-in-generated-menus.patch +Patch0343: 0343-Migrate-PPC-from-Yaboot-to-Grub2.patch +Patch0344: 0344-Add-fw_path-variable-revised.patch +Patch0345: 0345-Don-t-set-boot-device-on-ppc-ieee1275.patch +Patch0346: 0346-Add-support-for-linuxefi.patch +Patch0347: 0347-Add-support-for-crappy-cd-craparino.patch +Patch0348: 0348-Use-linuxefi-and-initrdefi-where-appropriate.patch +Patch0349: 0349-Don-t-allow-insmod-when-secure-boot-is-enabled.patch +Patch0351: 0351-Pass-x-hex-hex-straight-through-unmolested.patch +Patch0352: 0352-Fix-crash-on-http.patch +Patch0353: 0353-Issue-separate-DNS-queries-for-ipv4-and-ipv6.patch +Patch0354: 0354-IBM-client-architecture-CAS-reboot-support.patch +Patch0355: 0355-for-ppc-include-all-modules-in-the-core-image.patch +Patch0356: 0356-Add-vlan-tag-support.patch +Patch0357: 0357-Add-X-option-to-printf-functions.patch +Patch0358: 0358-DHCP-client-ID-and-UUID-options-added.patch +Patch0359: 0359-Search-for-specific-config-file-for-netboot.patch +Patch0360: 0360-Add-bootpath-device-to-the-list.patch +Patch0361: 0361-add-GRUB_DISABLE_SUBMENU-option.patch +Patch0362: 0362-blscfg-add-blscfg-module-to-parse-Boot-Loader-Specif.patch +Patch0363: 0363-Move-bash-completion-script-922997.patch +Patch0364: 0364-Use-memcpy-instead-of-direct-assignment-for-complex-.patch BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) @@ -102,7 +437,7 @@ BuildRequires: dejavu-sans-fonts BuildRequires: pesign >= 0.99-8 %endif -Requires: gettext os-prober which file system-logos +Requires: gettext os-prober which file Requires: %{name}-tools = %{epoch}:%{version}-%{release} Requires(pre): dracut Requires(post): dracut @@ -139,6 +474,17 @@ bootloader with modular architecture. It support rich varietyof kernel formats, file systems, computer architectures and hardware devices. This subpackage provides tools for support of all platforms. +%package starfield-theme +Summary: An example theme for GRUB. +Group: System Environment/Base +Requires: system-logos + +%description starfield-theme +The GRand Unified Bootloader (GRUB) is a highly configurable and customizable +bootloader with modular architecture. It support rich varietyof kernel formats, +file systems, computer architectures and hardware devices. This subpackage +provides an example theme for the grub screen. + %prep %setup -T -c -n grub-%{tarversion} %ifarch %{efiarchs} @@ -188,8 +534,8 @@ cd grub-efi-%{tarversion} make %{?_smp_mflags} GRUB_MODULES=" all_video boot btrfs cat chain configfile echo efifwsetup \ efinet ext2 fat font gfxmenu gfxterm gzio halt hfsplus iso9660 \ - jpeg linuxefi minicmd normal part_apple part_msdos part_gpt \ - password_pbkdf2 png reboot search search_fs_uuid \ + jpeg linuxefi lvm minicmd normal part_apple part_msdos \ + part_gpt password_pbkdf2 png reboot search search_fs_uuid \ search_fs_file search_label sleep test video xfs \ mdraid09 mdraid1x blscfg" ./grub-mkimage -O %{grubefiarch} -o %{grubeficdname}.orig -p /EFI/BOOT \ @@ -390,9 +736,10 @@ fi %files tools -f grub.lang %defattr(-,root,root,-) %dir %{_libdir}/grub/ -%{_datarootdir}/grub/ +dir %{_datarootdir}/grub/ +dir %{_datarootdir}/grub/themes +%{_datarootdir}/grub/* %{_sbindir}/%{name}-mkconfig -%{_sbindir}/%{name}-mknetdir %{_sbindir}/%{name}-install %{_sbindir}/%{name}-probe %{_sbindir}/%{name}-reboot @@ -400,6 +747,7 @@ fi %{_sbindir}/%{name}-bios-setup %{_sbindir}/%{name}-ofpathname %{_sbindir}/%{name}-sparc64-setup +%{_bindir}/%{name}-mknetdir %{_bindir}/%{name}-mkstandalone %{_bindir}/%{name}-editenv %{_bindir}/%{name}-fstest @@ -410,11 +758,14 @@ fi %{_bindir}/%{name}-mkimage %{_bindir}/%{name}-mkpasswd-pbkdf2 %{_bindir}/%{name}-mkrelpath +%{_bindir}/%{name}-mount +%{_bindir}/%{name}-glue-efi +%{_bindir}/%{name}-render-label %ifnarch %{sparc} %{_bindir}/%{name}-mkrescue %endif %{_bindir}/%{name}-script-check -%{_sysconfdir}/bash_completion.d/grub +%{_datarootdir}/bash-completion/completions/grub %{_sysconfdir}/prelink.conf.d/grub2.conf %attr(0700,root,root) %dir %{_sysconfdir}/grub.d %config %{_sysconfdir}/grub.d/??_* @@ -433,7 +784,21 @@ fi %doc grub-%{tarversion}/grub-dev.html grub-%{tarversion}/docs/font_char_metrics.png %doc grub-%{tarversion}/themes/starfield/COPYING.CC-BY-SA-3.0 +%files starfield-theme +%{_datarootdir}/grub/themes/starfield + %changelog +* Fri May 10 2013 Matthias Clasen - 2.00-18 +- Move the starfield theme to a subpackage (#962004) + +* Wed Apr 24 2013 Peter Jones - 2.00-17.pj0 +- Rebase to upstream snapshot. + +* Thu Apr 04 2013 Peter Jones - 2.00-17 +- Fix booting from drives with 4k sectors on UEFI. +- Move bash completion to new location (#922997) +- Include lvm support for /boot (#906203) + * Thu Feb 14 2013 Peter Jones - 2.00-16 - Allow the user to disable submenu generation - (partially) support BLS-style configuration stanzas. @@ -682,102 +1047,3 @@ fi * Wed Feb 09 2011 Fedora Release Engineering - 1:1.98-4 - Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild - -* Sat Jul 17 2010 Dennis Gilmore - 1:1.98-3 -- correctly generate a grub.cfg on kernel update - -* Fri May 28 2010 Dennis Gilmore - 1:1.98-2 -- add patch so grub2-probe works with lvm to detect devices correctly - -* Wed Apr 21 2010 Dennis Gilmore - 1:1.98-1 -- update to 1.98 - -* Fri Feb 12 2010 Dennis Gilmore - 1:1.97.2-1 -- update to 1.97.2 - -* Wed Jan 20 2010 Dennis Gilmore - 1:1.97.1-5 -- drop requires on mkinitrd - -* Tue Dec 01 2009 Dennis Gilmore - 1:1.97.1-4 -- add patch so that grub2 finds fedora's initramfs - -* Tue Nov 10 2009 Dennis Gilmore - 1:1.97.1-3 -- no mkrescue on sparc arches -- ofpathname on sparc arches -- Requires dracut, not sure if we should just drop mkinitrd for dracut - -* Tue Nov 10 2009 Dennis Gilmore - 1:1.97.1-2 -- update filelists - -* Tue Nov 10 2009 Dennis Gilmore - 1:1.97.1-1 -- update to 1.97.1 release -- introduce epoch for upgrades - -* Tue Nov 10 2009 Dennis Gilmore - 1.98-0.7.20090911svn -- fix BR - -* Fri Sep 11 2009 Dennis Gilmore - 1.98-0.6.20090911svn -- update to new svn snapshot -- add sparc support - -* Fri Jul 24 2009 Fedora Release Engineering - 1.98-0.6.20080827svn -- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild - -* Sun Mar 01 2009 Lubomir Rintel - 1.98-0.4.20080827svn -- Add missing BR - -* Tue Feb 24 2009 Fedora Release Engineering - 1.98-0.4.20080827svn -- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild - -* Wed Aug 27 2008 Lubomir Rintel - 1.98-0.3.20080827svn -- Updated SVN snapshot -- Added huge fat warnings - -* Fri Aug 08 2008 Lubomir Rintel - 1.98-0.2.20080807svn -- Correct scriptlet dependencies, trigger on kernel-PAE (thanks to Till Maas) -- Fix build on x86_64 (thanks to Marek Mahut) - -* Thu Aug 07 2008 Lubomir Rintel 1.98-0.1.20080807svn -- Another snapshot -- And much more! - -* Mon May 12 2008 Lubomir Kundrak 1.97-0.1.20080512cvs -- CVS snapshot -- buildid patch upstreamed - -* Sat Apr 12 2008 Lubomir Kundrak 1.96-2 -- Pull in 32 bit glibc -- Fix builds on 64 bit - -* Sun Mar 16 2008 Lubomir Kundrak 1.96-1 -- New upstream release -- More transformation fixes -- Generate -debuginfo from modules again. This time for real. -- grubby stub -- Make it possible to do configuration changes directly in grub.cfg -- grub.cfg symlink in /etc - -* Thu Feb 14 2008 Lubomir Kundrak 1.95.cvs20080214-3 -- Update to latest trunk -- Manual pages -- Add pci.c to DISTLIST - -* Mon Nov 26 2007 Lubomir Kundrak 1.95.cvs20071119-2 -- Fix program name transformation in utils -- Moved the modules to /lib -- Generate -debuginfo from modules again - -* Sun Nov 18 2007 Lubomir Kundrak 1.95.cvs20071119-1 -- Synchronized with CVS, major specfile cleanup - -* Tue Jan 30 2007 Lubomir Kundrak 1.95-lkundrak1 -- Removed redundant filelist entries - -* Mon Jan 29 2007 Lubomir Kundrak 1.95-lkundrak0 -- Program name transformation -- Bump to 1.95 -- grub-probefs -> grub-probe -- Add modules to -debuginfo - -* Tue Sep 12 2006 Lubomir Kundrak 1.94-lkundrak0 -- built the package