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/grub-2.00-Add-fwsetup.patch b/0033-grub-core-Makefile.core.def-efifwsetup-New-module.patch similarity index 63% rename from grub-2.00-Add-fwsetup.patch rename to 0033-grub-core-Makefile.core.def-efifwsetup-New-module.patch index 5abae3b..112daae 100644 --- a/grub-2.00-Add-fwsetup.patch +++ b/0033-grub-core-Makefile.core.def-efifwsetup-New-module.patch @@ -1,42 +1,44 @@ -From 2c7cdc59a8d6cb7800c73b90aa75cc8b21807af6 Mon Sep 17 00:00:00 2001 +From 9e9382ece3511ff530cfb3e1c1e7a7dbaa3416b6 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. +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. -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(+) + 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 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/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 000cf0d..d0c06d5 100644 +index de702d6..7a7b97a 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def -@@ -576,6 +576,12 @@ module = { +@@ -575,6 +575,12 @@ module = { }; module = { @@ -51,10 +53,10 @@ index 000cf0d..d0c06d5 100644 }; diff --git a/grub-core/commands/efi/efifwsetup.c b/grub-core/commands/efi/efifwsetup.c new file mode 100644 -index 0000000..756a14c +index 0000000..7a137a7 --- /dev/null +++ b/grub-core/commands/efi/efifwsetup.c -@@ -0,0 +1,88 @@ +@@ -0,0 +1,90 @@ +/* fwsetup.c - Reboot into firmware setup menu. */ +/* + * GRUB -- GRand Unified Bootloader @@ -73,12 +75,14 @@ index 0000000..756a14c + * 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+"); + @@ -93,18 +97,18 @@ index 0000000..756a14c + 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); ++ old_os_indications = grub_efi_get_variable ("OsIndications", &global, ++ &oi_size); + -+ if (old_os_indications != NULL && oi_size == sizeof(*old_os_indications)) ++ 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)); ++ status = grub_efi_set_variable ("OsIndications", &global, &os_indications, ++ sizeof (os_indications)); + if (status != GRUB_ERR_NONE) + return status; + -+ grub_reboot(); ++ grub_reboot (); + + return GRUB_ERR_BUG; +} @@ -112,14 +116,14 @@ index 0000000..756a14c +static grub_command_t cmd = NULL; + +static grub_efi_boolean_t -+efifwsetup_is_supported(void) ++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); ++ os_indications_supported = grub_efi_get_variable ("OsIndicationsSupported", ++ &global, &oi_size); + + if (!os_indications_supported) + return 0; @@ -130,25 +134,25 @@ index 0000000..756a14c + return 0; +} + -+GRUB_MOD_INIT(efifwsetup) ++GRUB_MOD_INIT (efifwsetup) +{ -+ if (efifwsetup_is_supported()) -+ cmd = grub_register_command("fwsetup", grub_cmd_fwsetup, "", -+ "Reboot into firmware setup menu."); ++ if (efifwsetup_is_supported ()) ++ cmd = grub_register_command ("fwsetup", grub_cmd_fwsetup, NULL, ++ N_("Reboot into firmware setup menu.")); + +} + -+GRUB_MOD_FINI(efifwsetup) ++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 +index 02d2f9a..e8a62ec 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; +@@ -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 @@ -170,22 +174,22 @@ index 6f12c76..7a418a6 100644 + + 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); ++ 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); +} + - #pragma GCC diagnostic ignored "-Wcast-align" - - /* Search the mods section from the PE32/PE32+ image. This code uses + 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 26127de..a47a4e3 100644 +index 9e7a8d8..ae61730 100644 --- a/include/grub/efi/api.h +++ b/include/grub/efi/api.h @@ -58,6 +58,8 @@ @@ -214,5 +218,5 @@ index e67d92b..489cf9e 100644 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 +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/follow-the-symbolic-link-ieee1275.patch b/0065-util-grub-install.in-Follow-the-symbolic-link-parame.patch similarity index 51% rename from follow-the-symbolic-link-ieee1275.patch rename to 0065-util-grub-install.in-Follow-the-symbolic-link-parame.patch index 0cf624b..0560d8e 100644 --- a/follow-the-symbolic-link-ieee1275.patch +++ b/0065-util-grub-install.in-Follow-the-symbolic-link-parame.patch @@ -1,19 +1,32 @@ -From 9436d0324b98e71c8ab55b09b4248a617cd463a8 Mon Sep 17 00:00:00 2001 +From 28e8ed1fc8a89e3d4c71be6b27166b26b4e61570 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) +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. -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(-) + 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 69a97ad..19dc3b4 100644 +index a2cf07a..9dc4e0b 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" ] +@@ -748,7 +748,7 @@ elif [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "i386-ieee1275" ] exit 1 fi @@ -23,5 +36,5 @@ index 69a97ad..19dc3b4 100644 gettext "Failed to copy Grub to the PReP partition." 1>&2 echo 1>&2 -- -1.7.10.4 +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/grub-1.99-just-say-linux.patch b/0342-Don-t-say-GNU-Linux-in-generated-menus.patch similarity index 74% rename from grub-1.99-just-say-linux.patch rename to 0342-Don-t-say-GNU-Linux-in-generated-menus.patch index 62a6b32..afde264 100644 --- a/grub-1.99-just-say-linux.patch +++ b/0342-Don-t-say-GNU-Linux-in-generated-menus.patch @@ -1,18 +1,18 @@ -From d4bd41f972c6e22b86c773cbba2a1e14f400a8be Mon Sep 17 00:00:00 2001 +From 75261365c2601a2e98dae5b872de61930546bac7 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. +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 ++-- + 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 +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@ +@@ -29,9 +29,9 @@ export TEXTDOMAINDIR="@localedir@" CLASS="--class gnu-linux --class gnu --class os" if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then @@ -25,10 +25,10 @@ index a09c3e6..0b0df78 100644 fi diff --git a/util/grub.d/20_linux_xen.in b/util/grub.d/20_linux_xen.in -index ee49cd9..10422b0 100644 +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@ +@@ -29,9 +29,9 @@ export TEXTDOMAINDIR="@localedir@" CLASS="--class gnu-linux --class gnu --class os --class xen" if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then @@ -41,5 +41,5 @@ index ee49cd9..10422b0 100644 fi -- -1.7.4 +1.8.1.4 diff --git a/grub-1.99-ppc-terminfo.patch b/0343-Migrate-PPC-from-Yaboot-to-Grub2.patch similarity index 91% rename from grub-1.99-ppc-terminfo.patch rename to 0343-Migrate-PPC-from-Yaboot-to-Grub2.patch index b2b0d78..f8ba45f 100644 --- a/grub-1.99-ppc-terminfo.patch +++ b/0343-Migrate-PPC-from-Yaboot-to-Grub2.patch @@ -1,22 +1,21 @@ -From e263907f50e496e602edd9bd846ccb6e0565a085 Mon Sep 17 00:00:00 2001 +From 5c27f1d4e94b5649aba55d1aa53a4c154949005c 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 +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(+), 0 deletions(-) + 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 c41b76e..b349758 100644 +index 4fa37bc..2f3bf5f 100644 --- a/Makefile.util.def +++ b/Makefile.util.def -@@ -423,6 +423,13 @@ script = { +@@ -442,6 +442,13 @@ script = { }; script = { @@ -151,5 +150,5 @@ index 0000000..10d6658 + terminfo -g ${X}x${Y} ${TERMINAL} +EOF -- -1.7.7.2 +1.8.1.4 diff --git a/grub-2.00-add-fw_path-search_v2.patch b/0344-Add-fw_path-variable-revised.patch similarity index 81% rename from grub-2.00-add-fw_path-search_v2.patch rename to 0344-Add-fw_path-variable-revised.patch index c7857c3..f4b069a 100644 --- a/grub-2.00-add-fw_path-search_v2.patch +++ b/0344-Add-fw_path-variable-revised.patch @@ -1,7 +1,7 @@ -From 40d6b00fa48ae9c1cecf143da5c6061f6ffcb719 Mon Sep 17 00:00:00 2001 +From 3198c6026265f42d043e61587579ea590fcd2ad4 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) +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 @@ -9,15 +9,15 @@ found. It was originally written by Matthew Garrett, and adapted to fix the https://bugzilla.redhat.com/show_bug.cgi?id=857936 --- - grub-core/kern/main.c | 16 ++++++++++++++-- - grub-core/normal/main.c | 25 ++++++++++++++++++++++++- + 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 +index 19dc988..8ab7794 100644 --- a/grub-core/kern/main.c +++ b/grub-core/kern/main.c -@@ -114,6 +114,20 @@ grub_set_prefix_and_root (void) +@@ -125,6 +125,20 @@ grub_set_prefix_and_root (void) grub_register_variable_hook ("root", 0, grub_env_write_root); @@ -38,7 +38,7 @@ index 3262444..820fd66 100644 if (prefix) { char *pptr = NULL; -@@ -131,8 +145,6 @@ grub_set_prefix_and_root (void) +@@ -142,8 +156,6 @@ grub_set_prefix_and_root (void) if (pptr[0]) path = grub_strdup (pptr); } @@ -48,10 +48,10 @@ index 3262444..820fd66 100644 if (!device && fwdevice) device = fwdevice; diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c -index 13473ec..39bb734 100644 +index 9aaa3b2..ea8cd53 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)), +@@ -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; @@ -84,5 +84,5 @@ index 13473ec..39bb734 100644 prefix = grub_env_get ("prefix"); if (prefix) -- -1.7.10.4 +1.8.1.4 diff --git a/grub-2.00-Dont-set-boot-on-ppc.patch b/0345-Don-t-set-boot-device-on-ppc-ieee1275.patch similarity index 84% rename from grub-2.00-Dont-set-boot-on-ppc.patch rename to 0345-Don-t-set-boot-device-on-ppc-ieee1275.patch index 481d8b9..c8c8f2e 100644 --- a/grub-2.00-Dont-set-boot-on-ppc.patch +++ b/0345-Don-t-set-boot-device-on-ppc-ieee1275.patch @@ -1,19 +1,19 @@ -From 28d9f3965f095a765ec8aaa589b4e04608b69901 Mon Sep 17 00:00:00 2001 +From 8aa77af6f9aad0d8a5b50a0670f85668ad489022 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 +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 ++++++++++-------- + 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 +index 271e447..c9f66c7 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" ] +@@ -777,14 +777,16 @@ elif [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = "i386-ieee1275" ] } fi @@ -38,3 +38,6 @@ index e19f1cd..69a97ad 100644 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/grub2-linuxefi.patch b/0346-Add-support-for-linuxefi.patch similarity index 94% rename from grub2-linuxefi.patch rename to 0346-Add-support-for-linuxefi.patch index c0282d0..9e34dbd 100644 --- a/grub2-linuxefi.patch +++ b/0346-Add-support-for-linuxefi.patch @@ -1,12 +1,22 @@ +From b9ec45bae44866fe0aff006d645d7b89efa4bc2f Mon Sep 17 00:00:00 2001 From: Matthew Garrett -Date: 2012-07-10 11:58:52 EDT -Subject: [PATCH] Add support for linuxefi +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 39e77a4..f9cbfc3 100644 +index 8f36ea0..ca09eed 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def -@@ -1415,6 +1415,14 @@ module = { +@@ -1521,6 +1521,14 @@ module = { }; module = { @@ -22,7 +32,7 @@ index 39e77a4..f9cbfc3 100644 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 +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; @@ -66,10 +76,10 @@ index a2edc84..88b2557 100644 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 +index 0000000..b79e632 --- /dev/null +++ b/grub-core/loader/i386/efi/linux.c -@@ -0,0 +1,369 @@ +@@ -0,0 +1,371 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2012 Free Software Foundation, Inc. @@ -398,6 +408,8 @@ index 0000000..d06a0e3 + + memcpy(params, &lh, 2 * 512); + ++ params->type_of_loader = 0x21; ++ + fail: + + if (file) @@ -440,7 +452,7 @@ index 0000000..d06a0e3 + grub_unregister_command (cmd_initrd); +} diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h -index e67d92b..1b0e7ae 100644 +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); @@ -465,16 +477,6 @@ index 9d064c8..c29c5af 100644 } __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) +-- +1.8.1.4 + diff --git a/grub2-cdpath.patch b/0347-Add-support-for-crappy-cd-craparino.patch similarity index 68% rename from grub2-cdpath.patch rename to 0347-Add-support-for-crappy-cd-craparino.patch index 3e00db4..bd509a4 100644 --- a/grub2-cdpath.patch +++ b/0347-Add-support-for-crappy-cd-craparino.patch @@ -1,12 +1,17 @@ +From 3a38d333bfdcdca7546b7c005453cd02a78c8423 Mon Sep 17 00:00:00 2001 From: Matthew Garrett -Date: 2012-07-10 11:58:52 EDT -Subject: [PATCH] Add support for crappy cd craparino +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 d9d788c..a432b44 100644 +index e168d07..3a006ab 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) +@@ -794,6 +794,16 @@ grub_efidisk_get_device_name (grub_efi_handle_t *handle) if (! ldp) return 0; @@ -23,3 +28,6 @@ index d9d788c..a432b44 100644 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/grub2-use-linuxefi.patch b/0348-Use-linuxefi-and-initrdefi-where-appropriate.patch similarity index 79% rename from grub2-use-linuxefi.patch rename to 0348-Use-linuxefi-and-initrdefi-where-appropriate.patch index 18684b0..a81eab9 100644 --- a/grub2-use-linuxefi.patch +++ b/0348-Use-linuxefi-and-initrdefi-where-appropriate.patch @@ -1,14 +1,14 @@ -From 151b1691fe0cf885df101c6e6a7cb1defc50428b Mon Sep 17 00:00:00 2001 +From 2398a5d9dbf6b095513d3a469d2711ca25f85311 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. +Subject: [PATCH 348/364] Use "linuxefi" and "initrdefi" where appropriate. --- - util/grub.d/10_linux.in | 18 ++++++++++++++++-- + 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 +index 368f609..4807d84 100644 --- a/util/grub.d/10_linux.in +++ b/util/grub.d/10_linux.in @@ -133,17 +133,31 @@ linux_entry () @@ -18,12 +18,12 @@ index cd543bd..e2b8ab3 100644 - sed "s/^/$submenu_indentation/" << EOF + if [ -d /sys/firmware/efi ]; then + sed "s/^/$submenu_indentation/" << EOF -+ echo '$message' ++ echo '$(echo "$message" | grub_quote)' + linuxefi ${rel_dirname}/${basename} root=${linux_root_device_thisversion} ro ${args} +EOF + else + sed "s/^/$submenu_indentation/" << EOF - echo '$message' + echo '$(echo "$message" | grub_quote)' linux ${rel_dirname}/${basename} root=${linux_root_device_thisversion} ro ${args} EOF + fi @@ -33,12 +33,12 @@ index cd543bd..e2b8ab3 100644 - sed "s/^/$submenu_indentation/" << EOF + if [ -d /sys/firmware/efi ]; then + sed "s/^/$submenu_indentation/" << EOF -+ echo '$message' + echo '$(echo "$message" | grub_quote)' + initrdefi ${rel_dirname}/${initrd} +EOF + else + sed "s/^/$submenu_indentation/" << EOF - echo '$message' ++ echo '$message' initrd ${rel_dirname}/${initrd} EOF + fi @@ -46,5 +46,5 @@ index cd543bd..e2b8ab3 100644 sed "s/^/$submenu_indentation/" << EOF } -- -1.7.10.4 +1.8.1.4 diff --git a/grub-2.00-no-insmod-on-sb.patch b/0349-Don-t-allow-insmod-when-secure-boot-is-enabled.patch similarity index 87% rename from grub-2.00-no-insmod-on-sb.patch rename to 0349-Don-t-allow-insmod-when-secure-boot-is-enabled.patch index 1bfd6f8..084991b 100644 --- a/grub-2.00-no-insmod-on-sb.patch +++ b/0349-Don-t-allow-insmod-when-secure-boot-is-enabled.patch @@ -1,7 +1,7 @@ -From 8a2a8d6021d926f00c5f85dab2d66f4ed8be86a2 Mon Sep 17 00:00:00 2001 +From 16841c32f8cdb8ded3ac7bb2e2a4eb2fcfe9d93f 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. +Subject: [PATCH 349/364] Don't allow insmod when secure boot is enabled. Hi, @@ -23,10 +23,10 @@ moves the check into grub_dl_load_file. 3 files changed, 46 insertions(+) diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c -index a498682..2578fce 100644 +index c6d9ec9..570be12 100644 --- a/grub-core/kern/dl.c +++ b/grub-core/kern/dl.c -@@ -43,6 +43,10 @@ +@@ -42,6 +42,10 @@ #include #endif @@ -37,7 +37,7 @@ index a498682..2578fce 100644 #pragma GCC diagnostic ignored "-Wcast-align" -@@ -721,6 +725,19 @@ grub_dl_load_file (const char *filename) +@@ -673,6 +677,19 @@ grub_dl_load_file (const char *filename) void *core = 0; grub_dl_t mod = 0; @@ -58,11 +58,11 @@ index a498682..2578fce 100644 if (! file) return 0; diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c -index 820968f..ad7aa8d 100644 +index e8a62ec..0f513e8 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); +@@ -259,6 +259,34 @@ grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid, + return NULL; } +grub_efi_boolean_t @@ -109,5 +109,5 @@ index 9370fd5..a000c38 100644 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 +1.8.1.4 diff --git a/grub-2.00-Handle-escapes-in-labels.patch b/0351-Pass-x-hex-hex-straight-through-unmolested.patch similarity index 83% rename from grub-2.00-Handle-escapes-in-labels.patch rename to 0351-Pass-x-hex-hex-straight-through-unmolested.patch index 65a2a41..e2ea5c3 100644 --- a/grub-2.00-Handle-escapes-in-labels.patch +++ b/0351-Pass-x-hex-hex-straight-through-unmolested.patch @@ -1,20 +1,21 @@ -From d08e2511db353b2db9c5785d3f22079674abd708 Mon Sep 17 00:00:00 2001 +From a20c29e7b8c9b92fc8919968a2382737d6662695 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. +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 | 44 +++++++++++++++++++++++++++++++++++++------ - 3 files changed, 85 insertions(+), 9 deletions(-) + 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 2b73d9a..d1235dc 100644 +index 2807f80..0f40e04 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; +@@ -458,6 +458,12 @@ check_file (const char *dir, const char *basename) + return ctx.found; } +static int @@ -26,7 +27,7 @@ index 2b73d9a..d1235dc 100644 static void unescape (char *out, const char *in, const char *end) { -@@ -428,7 +434,15 @@ 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;) { @@ -103,7 +104,7 @@ index a702e64..c8605a7 100644 *buf++ = *c; diff --git a/grub-core/script/execute.c b/grub-core/script/execute.c -index b5e6eb0..c44eced 100644 +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; @@ -152,35 +153,31 @@ index b5e6eb0..c44eced 100644 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; ) +@@ -394,10 +415,20 @@ parse_string (const char *str, switch (*ptr) { case '\\': - escaped = !escaped; - if (!escaped && put) -- *((*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++; ++ *(put++) = *ptr++; ++ *(put++) = *ptr++; ++ *(put++) = *ptr++; ++ *(put++) = *ptr++; + } + else + { + escaped = !escaped; + if (!escaped && put) -+ *((*put)++) = '\\'; ++ *(put++) = '\\'; + ptr++; + } break; case '$': if (escaped) -- -1.7.12.1 +1.8.1.4 diff --git a/grub-2.00-fix-http-crash.patch b/0352-Fix-crash-on-http.patch similarity index 77% rename from grub-2.00-fix-http-crash.patch rename to 0352-Fix-crash-on-http.patch index ac110c3..fc2273f 100644 --- a/grub-2.00-fix-http-crash.patch +++ b/0352-Fix-crash-on-http.patch @@ -1,7 +1,7 @@ -From 4414df5e72937b0bb1c4a0bb66cd1132ec2a5720 Mon Sep 17 00:00:00 2001 +From 8f9b02e937baf68c322b5798b59fbe4617712133 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 +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. @@ -11,10 +11,10 @@ https://bugzilla.redhat.com/show_bug.cgi?id=860834 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 +index 4684f8b..ef9538c 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) +@@ -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, @@ -24,5 +24,5 @@ index a7542d1..a5f6f31 100644 if (!data->sock) { -- -1.7.11.4 +1.8.1.4 diff --git a/grub-2.00-Issue-separate-DNS-queries-for-ipv4-and-ipv6.patch b/0353-Issue-separate-DNS-queries-for-ipv4-and-ipv6.patch similarity index 96% rename from grub-2.00-Issue-separate-DNS-queries-for-ipv4-and-ipv6.patch rename to 0353-Issue-separate-DNS-queries-for-ipv4-and-ipv6.patch index 953f2bd..c3d8234 100644 --- a/grub-2.00-Issue-separate-DNS-queries-for-ipv4-and-ipv6.patch +++ b/0353-Issue-separate-DNS-queries-for-ipv4-and-ipv6.patch @@ -1,7 +1,7 @@ -From 3e00d82827f80461f9fe6da37acd84235c08e5a5 Mon Sep 17 00:00:00 2001 +From 90e4864ecae8cc40d1f9562556a866d15ddc491f 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 +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 @@ -22,7 +22,7 @@ Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=860829 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 +index 3381ea7..fac97b0 100644 --- a/grub-core/net/dns.c +++ b/grub-core/net/dns.c @@ -34,6 +34,14 @@ struct dns_cache_element @@ -206,10 +206,10 @@ index 3381ea7..725725c 100644 static grub_err_t diff --git a/include/grub/net.h b/include/grub/net.h -index 3877451..a7e5b2c 100644 +index 1bd7af2..e677246 100644 --- a/include/grub/net.h +++ b/include/grub/net.h -@@ -505,6 +505,15 @@ grub_err_t +@@ -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); @@ -226,5 +226,5 @@ index 3877451..a7e5b2c 100644 grub_net_dns_lookup (const char *name, const struct grub_net_network_level_address *servers, -- -1.7.11.4 +1.8.1.4 diff --git a/grub-2.00-cas-reboot-support.patch b/0354-IBM-client-architecture-CAS-reboot-support.patch similarity index 82% rename from grub-2.00-cas-reboot-support.patch rename to 0354-IBM-client-architecture-CAS-reboot-support.patch index f0085a4..bdb73df 100644 --- a/grub-2.00-cas-reboot-support.patch +++ b/0354-IBM-client-architecture-CAS-reboot-support.patch @@ -1,7 +1,7 @@ -From be9ee2df83a927d49184026154dd8d5039a8b664 Mon Sep 17 00:00:00 2001 +From 057b6211bfba83caa9af3276fbbf8902cd1082a2 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 +Subject: [PATCH 354/364] IBM client architecture (CAS) reboot support This is an implementation of IBM client architecture (CAS) reboot for GRUB. @@ -18,17 +18,17 @@ 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 ++ + 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 +index 07c90f7..09e9e57 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) +@@ -561,3 +561,66 @@ grub_ieee1275_canonicalise_devname (const char *path) return NULL; } @@ -96,7 +96,7 @@ index 40abaa3..c2b1bdf 100644 +} + diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c -index 39bb734..aa0b3e5 100644 +index ea8cd53..1f14826 100644 --- a/grub-core/normal/main.c +++ b/grub-core/normal/main.c @@ -32,6 +32,9 @@ @@ -109,7 +109,7 @@ index 39bb734..aa0b3e5 100644 GRUB_MOD_LICENSE ("GPLv3+"); -@@ -296,6 +299,22 @@ grub_normal_execute (const char *config, int nested, int batch) +@@ -302,6 +305,22 @@ grub_normal_execute (const char *config, int nested, int batch) { menu = read_config_file (config); @@ -133,7 +133,7 @@ index 39bb734..aa0b3e5 100644 grub_errno = GRUB_ERR_NONE; } diff --git a/grub-core/script/execute.c b/grub-core/script/execute.c -index b5e6eb0..4397540 100644 +index 686e1fa..7dcdab7 100644 --- a/grub-core/script/execute.c +++ b/grub-core/script/execute.c @@ -27,6 +27,9 @@ @@ -146,7 +146,7 @@ index b5e6eb0..4397540 100644 /* 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) +@@ -872,6 +875,10 @@ grub_script_execute_sourcecode (const char *source, int argc, char **args) old_scope = scope; scope = &new_scope; @@ -158,17 +158,18 @@ index b5e6eb0..4397540 100644 { char *line; diff --git a/include/grub/ieee1275/ieee1275.h b/include/grub/ieee1275/ieee1275.h -index 38a75fd..416a544 100644 +index 1b240d3..eabbe9b 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); +@@ -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); - #endif /* ! GRUB_IEEE1275_HEADER */ + #define FOR_IEEE1275_DEVALIASES(alias) for (grub_ieee1275_devalias_init_iterator (&(alias)); grub_ieee1275_devalias_next (&(alias));) + -- -1.7.10.4 +1.8.1.4 diff --git a/grub-2.00-for-ppc-include-all-modules-in-the-core-image.patch b/0355-for-ppc-include-all-modules-in-the-core-image.patch similarity index 87% rename from grub-2.00-for-ppc-include-all-modules-in-the-core-image.patch rename to 0355-for-ppc-include-all-modules-in-the-core-image.patch index 1244650..f08695d 100644 --- a/grub-2.00-for-ppc-include-all-modules-in-the-core-image.patch +++ b/0355-for-ppc-include-all-modules-in-the-core-image.patch @@ -1,7 +1,7 @@ -From 4613775aee8b413ba89bfb7233d49a4288e13390 Mon Sep 17 00:00:00 2001 +From 3c4e4115b161354823e6b6a6f6c9da2fa3f3962c 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 +Subject: [PATCH 355/364] for ppc, include all modules in the core image This patch implements the solution suggested by Gustavo Luiz Duarte : @@ -23,20 +23,20 @@ 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 ++++++++++++++++++++++++++++++++++++ + 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 +index cfab676..a4465eb 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)), +@@ -83,6 +83,9 @@ grub_core_cmd_insmod (struct grub_command *cmd __attribute__ ((unused)), else mod = grub_dl_load (argv[0]); @@ -47,7 +47,7 @@ index 16c03df..8684139 100644 grub_dl_ref (mod); diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c -index 5b0aa65..a498682 100644 +index 570be12..fe46aa4 100644 --- a/grub-core/kern/dl.c +++ b/grub-core/kern/dl.c @@ -32,6 +32,7 @@ @@ -58,7 +58,7 @@ index 5b0aa65..a498682 100644 /* Platforms where modules are in a readonly area of memory. */ #if defined(GRUB_MACHINE_QEMU) -@@ -47,6 +48,7 @@ +@@ -51,6 +52,7 @@ #pragma GCC diagnostic ignored "-Wcast-align" grub_dl_t grub_dl_head = 0; @@ -66,7 +66,7 @@ index 5b0aa65..a498682 100644 grub_err_t grub_dl_add (grub_dl_t mod); -@@ -659,6 +661,57 @@ grub_dl_load_core (void *addr, grub_size_t size) +@@ -668,6 +670,57 @@ grub_dl_load_core (void *addr, grub_size_t size) return mod; } @@ -124,7 +124,7 @@ index 5b0aa65..a498682 100644 /* 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) +@@ -740,13 +793,19 @@ grub_dl_load (const char *name) return 0; } @@ -161,7 +161,7 @@ index 3119978..30f12f9 100644 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 +index 73ea416..e837b1f 100644 --- a/include/grub/kernel.h +++ b/include/grub/kernel.h @@ -25,6 +25,7 @@ @@ -171,7 +171,7 @@ index eef4c3f..4cd2cb0 100644 + OBJ_TYPE_ELF_STALE, OBJ_TYPE_MEMDISK, OBJ_TYPE_CONFIG, - OBJ_TYPE_PREFIX + 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 @@ -187,10 +187,10 @@ index f42df32..1d0252c 100644 + #endif /* ! GRUB_UTIL_RESOLVE_HEADER */ diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c -index a551bbb..b06f37a 100644 +index 41f795a..fa601ec 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c -@@ -711,7 +711,7 @@ generate_image (const char *dir, const char *prefix, +@@ -729,7 +729,7 @@ generate_image (const char *dir, const char *prefix, size_t prefix_size = 0; char *kernel_path; size_t offset; @@ -199,7 +199,7 @@ index a551bbb..b06f37a 100644 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, +@@ -745,6 +745,10 @@ generate_image (const char *dir, const char *prefix, path_list = grub_util_resolve_dependencies (dir, "moddep.lst", mods); @@ -210,7 +210,7 @@ index a551bbb..b06f37a 100644 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, +@@ -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)); @@ -221,7 +221,7 @@ index a551bbb..b06f37a 100644 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, +@@ -865,6 +873,25 @@ generate_image (const char *dir, const char *prefix, offset += mod_size; } @@ -244,10 +244,10 @@ index a551bbb..b06f37a 100644 + offset += mod_size; + } + - if (memdisk_path) - { - struct grub_module_header *header; -@@ -1639,6 +1666,14 @@ generate_image (const char *dir, const char *prefix, + { + 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; } @@ -328,5 +328,5 @@ index 1af24e6..997db99 100644 + return path_list_comp; +} -- -1.7.10.4 +1.8.1.4 diff --git a/add-vlan-tag-support.patch b/0356-Add-vlan-tag-support.patch similarity index 84% rename from add-vlan-tag-support.patch rename to 0356-Add-vlan-tag-support.patch index 15f92f8..b9dc8cd 100644 --- a/add-vlan-tag-support.patch +++ b/0356-Add-vlan-tag-support.patch @@ -1,7 +1,7 @@ -From 5573f16fd05c1f8f310f2ead176b52ed6d4a08ec Mon Sep 17 00:00:00 2001 +From d898f409ae3c0d09ec244f2a113c67ca8b4b8079 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 +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 @@ -12,18 +12,18 @@ 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 ++ + 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 +index ce8eadb..3af15d8 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) +@@ -117,6 +117,7 @@ grub_machine_get_bootlocation (char **device, char **path) char *dev, *canon; char *ptr; dev = grub_ieee1275_get_aliasdevname (bootpath); @@ -32,7 +32,7 @@ index 5c45947..209cf8a 100644 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 +index 09e9e57..2a01146 100644 --- a/grub-core/kern/ieee1275/openfw.c +++ b/grub-core/kern/ieee1275/openfw.c @@ -23,6 +23,7 @@ @@ -43,7 +43,7 @@ index c2b1bdf..9fdfafa 100644 enum grub_ieee1275_parse_type { -@@ -413,6 +414,35 @@ fail: +@@ -451,6 +452,35 @@ fail: return ret; } @@ -159,21 +159,22 @@ index b38e2c8..5e45d46 100644 return err; diff --git a/include/grub/ieee1275/ieee1275.h b/include/grub/ieee1275/ieee1275.h -index 416a544..a8cf093 100644 +index eabbe9b..61d5769 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); +@@ -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); - #endif /* ! GRUB_IEEE1275_HEADER */ + #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 a7e5b2c..f4fec17 100644 +index e677246..fe29b16 100644 --- a/include/grub/net.h +++ b/include/grub/net.h -@@ -532,4 +532,6 @@ extern char *grub_net_default_server; +@@ -533,4 +533,6 @@ extern char *grub_net_default_server; #define GRUB_NET_TRIES 40 #define GRUB_NET_INTERVAL 400 @@ -181,5 +182,5 @@ index a7e5b2c..f4fec17 100644 + #endif /* ! GRUB_NET_HEADER */ -- -1.7.10.4 +1.8.1.4 diff --git a/grub-2.00-add-X-option-to-printf-functions.patch b/0357-Add-X-option-to-printf-functions.patch similarity index 80% rename from grub-2.00-add-X-option-to-printf-functions.patch rename to 0357-Add-X-option-to-printf-functions.patch index 63d7b79..68c9afb 100644 --- a/grub-2.00-add-X-option-to-printf-functions.patch +++ b/0357-Add-X-option-to-printf-functions.patch @@ -1,14 +1,14 @@ -From 80f81f233bf74aac740d7a299d075ea46c9c7bd4 Mon Sep 17 00:00:00 2001 +From f1673a4b7079d134fa966da37adf409ea42efe8c 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. +Subject: [PATCH 357/364] Add %X option to printf functions. --- - grub-core/kern/misc.c | 7 +++++-- + 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 +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) @@ -37,7 +37,7 @@ index 95d4624..8ac087a 100644 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 +@@ -780,6 +781,7 @@ grub_vsnprintf_real (char *str, grub_size_t max_len, const char *fmt0, va_list a switch (c) { case 'x': @@ -45,7 +45,7 @@ index 95d4624..8ac087a 100644 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 +@@ -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': @@ -54,5 +54,5 @@ index 95d4624..8ac087a 100644 unsig = 1; /* Fall through. */ -- -1.7.10.4 +1.8.1.4 diff --git a/grub-2.00-dhcp-client-id-and-uuid-options-added.patch b/0358-DHCP-client-ID-and-UUID-options-added.patch similarity index 75% rename from grub-2.00-dhcp-client-id-and-uuid-options-added.patch rename to 0358-DHCP-client-ID-and-UUID-options-added.patch index c573936..b463d62 100644 --- a/grub-2.00-dhcp-client-id-and-uuid-options-added.patch +++ b/0358-DHCP-client-ID-and-UUID-options-added.patch @@ -1,15 +1,15 @@ -From d63a0b7fd665fae1dd34d3e86127b93dd87b8114 Mon Sep 17 00:00:00 2001 +From 555f1022f967f98c541617df6b34ca272504d97b 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. +Subject: [PATCH 358/364] 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(-) + 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 bc07d53..3b4130d 100644 +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, @@ -37,18 +37,7 @@ index bc07d53..3b4130d 100644 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) +@@ -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; @@ -86,9 +75,9 @@ index bc07d53..3b4130d 100644 + break; + /* If you need any other options please contact GRUB - developpement team. */ + development team. */ } -@@ -299,14 +345,6 @@ grub_net_process_dhcp (struct grub_net_buff *nb, +@@ -299,14 +343,6 @@ grub_net_process_dhcp (struct grub_net_buff *nb, } } @@ -104,10 +93,10 @@ index bc07d53..3b4130d 100644 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 +index fe29b16..36ac906 100644 --- a/include/grub/net.h +++ b/include/grub/net.h -@@ -423,6 +423,8 @@ enum +@@ -424,6 +424,8 @@ enum GRUB_NET_BOOTP_DOMAIN = 0x0f, GRUB_NET_BOOTP_ROOT_PATH = 0x11, GRUB_NET_BOOTP_EXTENSIONS_PATH = 0x12, @@ -117,5 +106,5 @@ index a7e5b2c..45348dd 100644 }; -- -1.7.10.4 +1.8.1.4 diff --git a/grub-2.00-search-for-specific-config-file-for-netboot.patch b/0359-Search-for-specific-config-file-for-netboot.patch similarity index 91% rename from grub-2.00-search-for-specific-config-file-for-netboot.patch rename to 0359-Search-for-specific-config-file-for-netboot.patch index 026d002..6d44326 100644 --- a/grub-2.00-search-for-specific-config-file-for-netboot.patch +++ b/0359-Search-for-specific-config-file-for-netboot.patch @@ -1,7 +1,7 @@ -From 38d458ddd69cb7dd6e7f58f9e9f3197c6b6184f3 Mon Sep 17 00:00:00 2001 +From 773d8cadb15a4bea164863268068e2f421b8324c 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 +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: @@ -16,13 +16,13 @@ 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 ++ + 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 +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) @@ -151,7 +151,7 @@ index 01c5d32..49c32c5 100644 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 +index 1f14826..b40d987 100644 --- a/grub-core/normal/main.c +++ b/grub-core/normal/main.c @@ -32,6 +32,7 @@ @@ -162,7 +162,7 @@ index aa0b3e5..cc519a5 100644 #ifdef GRUB_MACHINE_IEEE1275 #include #endif -@@ -379,10 +380,19 @@ grub_cmd_normal (struct grub_command *cmd __attribute__ ((unused)), +@@ -392,10 +393,19 @@ grub_cmd_normal (struct grub_command *cmd __attribute__ ((unused)), prefix = grub_env_get ("prefix"); if (prefix) @@ -187,13 +187,11 @@ index aa0b3e5..cc519a5 100644 grub_enter_normal_mode (config); grub_free (config); diff --git a/include/grub/net.h b/include/grub/net.h -index 45348dd..09b8d56 100644 +index 36ac906..c7d5ce0 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 - +@@ -537,4 +537,7 @@ extern char *grub_net_default_server; + #define VLANTAG_IDENTIFIER 0x8100 +grub_err_t @@ -201,5 +199,5 @@ index 45348dd..09b8d56 100644 + #endif /* ! GRUB_NET_HEADER */ -- -1.7.10.4 +1.8.1.4 diff --git a/grub2-add-bootpath-device-to-the-list.patch b/0360-Add-bootpath-device-to-the-list.patch similarity index 64% rename from grub2-add-bootpath-device-to-the-list.patch rename to 0360-Add-bootpath-device-to-the-list.patch index d493bb5..bef6989 100644 --- a/grub2-add-bootpath-device-to-the-list.patch +++ b/0360-Add-bootpath-device-to-the-list.patch @@ -1,25 +1,33 @@ -From d2863ca186a6d4ba2a56559bf522f46c18403645 Mon Sep 17 00:00:00 2001 +From 68cae0b32cf36c7a8ccd0b2344afdb8ad5f9c473 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 +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 | 29 +++++++++++++++++++++++++++++ - 1 file changed, 29 insertions(+) + 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 b0aa7ec..99b156e 100644 +index ec92c4d..f056466 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); - } - +@@ -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) @@ -46,9 +54,11 @@ index b0aa7ec..99b156e 100644 + + grub_free (bootpath); + - grub_devalias_iterate (dev_iterate_alias); - grub_children_iterate ("/", dev_iterate); ++ grub_devalias_iterate (dev_iterate_alias); ++ grub_children_iterate ("/", dev_iterate); } + + static int -- -1.8.0 +1.8.1.4 diff --git a/grub-2.00-add-GRUB-DISABLE-SUBMENU-option.patch b/0361-add-GRUB_DISABLE_SUBMENU-option.patch similarity index 88% rename from grub-2.00-add-GRUB-DISABLE-SUBMENU-option.patch rename to 0361-add-GRUB_DISABLE_SUBMENU-option.patch index 1fd1630..ff84415 100644 --- a/grub-2.00-add-GRUB-DISABLE-SUBMENU-option.patch +++ b/0361-add-GRUB_DISABLE_SUBMENU-option.patch @@ -1,7 +1,7 @@ -From 81e46875469ae8b2a803e6457784801a0a7a7963 Mon Sep 17 00:00:00 2001 +From 226913e340f31cb8c2d98d09cb4186f1825cffe5 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 +Subject: [PATCH 361/364] add GRUB_DISABLE_SUBMENU option This patch adds the ability to disable the grub2 submenus from /etc/default/grub @@ -9,18 +9,16 @@ This patch adds the ability to disable the grub2 submenus from 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 +index 8decc1d..ea42cab 100644 --- a/util/grub-mkconfig.in +++ b/util/grub-mkconfig.in -@@ -216,7 +216,8 @@ export GRUB_DEFAULT \ +@@ -215,7 +215,8 @@ export GRUB_DEFAULT \ GRUB_INIT_TUNE \ GRUB_SAVEDEFAULT \ GRUB_ENABLE_CRYPTODISK \ @@ -31,7 +29,7 @@ index 516be86..354eb43 100644 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 +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 @@ -46,8 +44,8 @@ index e2b8ab3..9427a39 100644 + linux_entry "${OS}" "${version}" simple \ + "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}" -- submenu_indentation="\t" -+ submenu_indentation="\t" +- submenu_indentation="$grub_tab" ++ submenu_indentation="$grub_tab" - if [ -z "$boot_device_id" ]; then - boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")" @@ -76,5 +74,5 @@ index e2b8ab3..9427a39 100644 echo "$title_correction_code" -- -1.8.1 +1.8.1.4 diff --git a/grub-2.00-support-bls-config.patch b/0362-blscfg-add-blscfg-module-to-parse-Boot-Loader-Specif.patch similarity index 60% rename from grub-2.00-support-bls-config.patch rename to 0362-blscfg-add-blscfg-module-to-parse-Boot-Loader-Specif.patch index 10e9cba..05dbb8a 100644 --- a/grub-2.00-support-bls-config.patch +++ b/0362-blscfg-add-blscfg-module-to-parse-Boot-Loader-Specif.patch @@ -1,8 +1,8 @@ -From 4b7a3f2abc7f1017e69de197c5a970c4451ff1ff Mon Sep 17 00:00:00 2001 +From f46a9b399b30b4883cb472f096e9b2d666a29ee5 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 +Subject: [PATCH 362/364] blscfg: add blscfg module to parse Boot Loader + Specification snippets http://www.freedesktop.org/wiki/Specifications/BootLoaderSpec @@ -15,90 +15,16 @@ 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(+) + 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.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 +index ca09eed..ef4754f 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def -@@ -584,6 +584,14 @@ module = { +@@ -645,6 +645,14 @@ module = { }; module = { @@ -115,10 +41,10 @@ index fd4c54e..cfd3b09 100644 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 +index 0000000..4274aca --- /dev/null +++ b/grub-core/commands/blscfg.c -@@ -0,0 +1,200 @@ +@@ -0,0 +1,201 @@ +/*-*- Mode: C; c-basic-offset: 2; indent-tabs-mode: t -*-*/ + +/* bls.c - implementation of the boot loader spec */ @@ -168,7 +94,8 @@ index 0000000..8a07c57 + +static int parse_entry ( + const char *filename, -+ const struct grub_dirhook_info *info __attribute__ ((unused))) ++ const struct grub_dirhook_info *info __attribute__ ((unused)), ++ void *data __attribute__ ((unused))) +{ + grub_size_t n; + char *p; @@ -294,7 +221,7 @@ index 0000000..8a07c57 + goto finish; + } + -+ r = fs->dir (dev, GRUB_BLS_CONFIG_PATH, parse_entry); ++ r = fs->dir (dev, GRUB_BLS_CONFIG_PATH, parse_entry, NULL); + +finish: + if (dev) @@ -320,5 +247,5 @@ index 0000000..8a07c57 + grub_unregister_extcmd (cmd); +} -- -1.8.1.2 +1.8.1.4 diff --git a/grub-2.00-move-bash-completions.patch b/0363-Move-bash-completion-script-922997.patch similarity index 82% rename from grub-2.00-move-bash-completions.patch rename to 0363-Move-bash-completion-script-922997.patch index a15aaf5..62402cb 100644 --- a/grub-2.00-move-bash-completions.patch +++ b/0363-Move-bash-completion-script-922997.patch @@ -1,7 +1,7 @@ -From 6713bba005b733b3c74fafbdb7c655dd6635bd15 Mon Sep 17 00:00:00 2001 +From 03be782b24b462cfaa4a3fb5db0584b62b515bee Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Wed, 3 Apr 2013 14:35:34 -0400 -Subject: [PATCH] Move bash completion script (#922997) +Subject: [PATCH 363/364] Move bash completion script (#922997) Apparently these go in a new place now. --- @@ -9,7 +9,7 @@ Apparently these go in a new place now. 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..9aaaee0 100644 +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) 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-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-handle-4k-sectors.patch b/grub-2.00-handle-4k-sectors.patch deleted file mode 100644 index 64842ea..0000000 --- a/grub-2.00-handle-4k-sectors.patch +++ /dev/null @@ -1,41 +0,0 @@ -From f923381741b5a56115c5860a593e94539c5bbc8f Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Wed, 3 Apr 2013 11:41:52 -0400 -Subject: [PATCH] Make grub_efidisk_get_device_name() work on 4K native disks. - -When we have 4kB sectors instead of 512b sectors, hd.partition_start and -grub_partition_get_start() won't match - the latter assumes 512-byte -sectors, and the former gives us the correct number based on the -physical media's sector size. So when we have to compare them, we need -to compensate. - -Signed-off-by: Peter Jones ---- - grub-core/disk/efi/efidisk.c | 10 ++++++---- - 1 file changed, 6 insertions(+), 4 deletions(-) - -diff --git a/grub-core/disk/efi/efidisk.c b/grub-core/disk/efi/efidisk.c -index 77ab5b0..a905b52 100644 ---- a/grub-core/disk/efi/efidisk.c -+++ b/grub-core/disk/efi/efidisk.c -@@ -791,11 +791,13 @@ grub_efidisk_get_device_name (grub_efi_handle_t *handle) - 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) -+ int find_partition (grub_disk_t disk, const grub_partition_t part) - { -- if (grub_partition_get_start (part) == hd.partition_start -- && grub_partition_get_len (part) == hd.partition_size) -+ struct grub_efidisk_data *d = disk->data; -+ grub_efi_block_io_media_t *m = d->block_io->media; -+ -+ if (grub_partition_get_start (part) / (m->block_size / 512) == hd.partition_start -+ && grub_partition_get_len (part) / (m->block_size / 512) == hd.partition_size) - { - partition_name = grub_partition_get_name (part); - return 1; --- -1.8.1.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-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.spec b/grub2.spec index 7fb2cf1..2674d82 100644 --- a/grub2.spec +++ b/grub2.spec @@ -41,7 +41,7 @@ Name: grub2 Epoch: 1 Version: 2.00 -Release: 17%{?dist} +Release: 17%{?dist}.pj0 Summary: Bootloader with support for Linux, Multiboot and more Group: System Environment/Base @@ -53,35 +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-handle-4k-sectors.patch -Patch41: grub-2.00-move-bash-completions.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) @@ -393,7 +727,6 @@ fi %dir %{_libdir}/grub/ %{_datarootdir}/grub/ %{_sbindir}/%{name}-mkconfig -%{_sbindir}/%{name}-mknetdir %{_sbindir}/%{name}-install %{_sbindir}/%{name}-probe %{_sbindir}/%{name}-reboot @@ -401,6 +734,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 @@ -411,6 +745,8 @@ fi %{_bindir}/%{name}-mkimage %{_bindir}/%{name}-mkpasswd-pbkdf2 %{_bindir}/%{name}-mkrelpath +%{_bindir}/%{name}-glue-efi +%{_bindir}/%{name}-render-label %ifnarch %{sparc} %{_bindir}/%{name}-mkrescue %endif @@ -435,6 +771,9 @@ fi %doc grub-%{tarversion}/themes/starfield/COPYING.CC-BY-SA-3.0 %changelog +* 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)