merge mainline into backtrace
This commit is contained in:
commit
245f4582f9
871 changed files with 102908 additions and 16407 deletions
|
@ -24,6 +24,9 @@
|
|||
* See <http://www.7-zip.org>, for more information about LZMA.
|
||||
*/
|
||||
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <grub/lib/LzFind.h>
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
* See <http://www.7-zip.org>, for more information about LZMA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
|
@ -1992,13 +1994,15 @@ static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize
|
|||
static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)
|
||||
{
|
||||
UInt32 beforeSize = kNumOpts;
|
||||
#ifdef COMPRESS_MF_MT
|
||||
Bool btMode;
|
||||
#endif
|
||||
if (!RangeEnc_Alloc(&p->rc, alloc))
|
||||
return SZ_ERROR_MEM;
|
||||
#ifdef COMPRESS_MF_MT
|
||||
btMode = (p->matchFinderBase.btMode != 0);
|
||||
#ifdef COMPRESS_MF_MT
|
||||
p->mtMode = (p->multiThread && !p->fastMode && btMode);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
{
|
||||
unsigned lclp = p->lc + p->lp;
|
||||
|
|
151
grub-core/lib/adler32.c
Normal file
151
grub-core/lib/adler32.c
Normal file
|
@ -0,0 +1,151 @@
|
|||
/* adler32.c - adler32 check. */
|
||||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <grub/types.h>
|
||||
#include <grub/dl.h>
|
||||
#include <grub/crypto.h>
|
||||
|
||||
/* Based on adler32() from adler32.c of zlib-1.2.5 library. */
|
||||
|
||||
#define BASE 65521UL
|
||||
#define NMAX 5552
|
||||
|
||||
#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;}
|
||||
#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
|
||||
#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
|
||||
#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
|
||||
#define DO16(buf) DO8(buf,0); DO8(buf,8);
|
||||
|
||||
static grub_uint32_t
|
||||
update_adler32 (grub_uint32_t adler, const grub_uint8_t *buf, grub_size_t len)
|
||||
{
|
||||
unsigned long sum2;
|
||||
unsigned int n;
|
||||
|
||||
sum2 = (adler >> 16) & 0xffff;
|
||||
adler &= 0xffff;
|
||||
|
||||
if (len == 1)
|
||||
{
|
||||
adler += buf[0];
|
||||
if (adler >= BASE)
|
||||
adler -= BASE;
|
||||
sum2 += adler;
|
||||
if (sum2 >= BASE)
|
||||
sum2 -= BASE;
|
||||
return adler | (sum2 << 16);
|
||||
}
|
||||
|
||||
if (len < 16)
|
||||
{
|
||||
while (len--)
|
||||
{
|
||||
adler += *buf++;
|
||||
sum2 += adler;
|
||||
}
|
||||
if (adler >= BASE)
|
||||
adler -= BASE;
|
||||
sum2 %= BASE;
|
||||
return adler | (sum2 << 16);
|
||||
}
|
||||
|
||||
while (len >= NMAX)
|
||||
{
|
||||
len -= NMAX;
|
||||
n = NMAX / 16;
|
||||
do
|
||||
{
|
||||
DO16 (buf);
|
||||
buf += 16;
|
||||
}
|
||||
while (--n);
|
||||
adler %= BASE;
|
||||
sum2 %= BASE;
|
||||
}
|
||||
|
||||
if (len)
|
||||
{
|
||||
while (len >= 16)
|
||||
{
|
||||
len -= 16;
|
||||
DO16 (buf);
|
||||
buf += 16;
|
||||
}
|
||||
while (len--)
|
||||
{
|
||||
adler += *buf++;
|
||||
sum2 += adler;
|
||||
}
|
||||
adler %= BASE;
|
||||
sum2 %= BASE;
|
||||
}
|
||||
|
||||
return adler | (sum2 << 16);
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
grub_uint32_t adler;
|
||||
}
|
||||
adler32_context;
|
||||
|
||||
static void
|
||||
adler32_init (void *context)
|
||||
{
|
||||
adler32_context *ctx = (adler32_context *) context;
|
||||
ctx->adler = 1;
|
||||
}
|
||||
|
||||
static void
|
||||
adler32_write (void *context, const void *inbuf, grub_size_t inlen)
|
||||
{
|
||||
adler32_context *ctx = (adler32_context *) context;
|
||||
if (!inbuf)
|
||||
return;
|
||||
ctx->adler = update_adler32 (ctx->adler, inbuf, inlen);
|
||||
}
|
||||
|
||||
static grub_uint8_t *
|
||||
adler32_read (void *context)
|
||||
{
|
||||
adler32_context *ctx = (adler32_context *) context;
|
||||
return (grub_uint8_t *) &ctx->adler;
|
||||
}
|
||||
|
||||
static void
|
||||
adler32_final (void *context __attribute__ ((unused)))
|
||||
{
|
||||
}
|
||||
|
||||
gcry_md_spec_t _gcry_digest_spec_adler32 = {
|
||||
"ADLER32",0 , 0, 0 , 4,
|
||||
adler32_init, adler32_write, adler32_final, adler32_read,
|
||||
sizeof (adler32_context),
|
||||
.blocksize = 64
|
||||
};
|
||||
|
||||
GRUB_MOD_INIT(adler32)
|
||||
{
|
||||
grub_md_register (&_gcry_digest_spec_adler32);
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI(adler32)
|
||||
{
|
||||
grub_md_unregister (&_gcry_digest_spec_adler32);
|
||||
}
|
48
grub-core/lib/arc/datetime.c
Normal file
48
grub-core/lib/arc/datetime.c
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <grub/datetime.h>
|
||||
#include <grub/dl.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/arc/arc.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
grub_err_t
|
||||
grub_get_datetime (struct grub_datetime *datetime)
|
||||
{
|
||||
struct grub_arc_timeinfo *dt;
|
||||
grub_memset (datetime, 0, sizeof (*datetime));
|
||||
|
||||
dt = GRUB_ARC_FIRMWARE_VECTOR->gettime ();
|
||||
|
||||
datetime->year = dt->y;
|
||||
datetime->month = dt->m;
|
||||
datetime->day = dt->d;
|
||||
datetime->hour = dt->h;
|
||||
datetime->minute = dt->min;
|
||||
datetime->second = dt->s;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
grub_err_t
|
||||
grub_set_datetime (struct grub_datetime *datetime __attribute__ ((unused)))
|
||||
{
|
||||
return grub_error (GRUB_ERR_IO, "setting time isn't supported");
|
||||
}
|
|
@ -144,6 +144,9 @@ grub_arg_show_help (grub_extcmd_t cmd)
|
|||
}
|
||||
}
|
||||
|
||||
if (spacing < 0)
|
||||
spacing = 3;
|
||||
|
||||
while (spacing--)
|
||||
grub_xputs (" ");
|
||||
|
||||
|
@ -257,7 +260,7 @@ grub_arg_parse (grub_extcmd_t cmd, int argc, char **argv,
|
|||
char *option = 0;
|
||||
|
||||
/* No option is used. */
|
||||
if ((num && GRUB_COMMAND_OPTIONS_AT_START)
|
||||
if ((num && (cmd->cmd->flags & GRUB_COMMAND_OPTIONS_AT_START))
|
||||
|| arg[0] != '-' || grub_strlen (arg) == 1)
|
||||
{
|
||||
if (add_arg (arg) != 0)
|
||||
|
@ -337,17 +340,20 @@ grub_arg_parse (grub_extcmd_t cmd, int argc, char **argv,
|
|||
}
|
||||
|
||||
option = grub_strchr (arg, '=');
|
||||
if (option) {
|
||||
arglen = option - arg - 2;
|
||||
option++;
|
||||
} else {
|
||||
if (option)
|
||||
{
|
||||
arglen = option - arg - 2;
|
||||
option++;
|
||||
}
|
||||
else
|
||||
arglen = grub_strlen (arg) - 2;
|
||||
if (argv[curarg + 1])
|
||||
option = argv[curarg + 1][0] == '-' ? 0 : argv[++curarg];
|
||||
}
|
||||
|
||||
opt = find_long (cmd->options, arg + 2, arglen);
|
||||
|
||||
if (!option && argv[curarg + 1] && argv[curarg + 1][0] != '-'
|
||||
&& opt->type != ARG_TYPE_NONE)
|
||||
option = argv[++curarg];
|
||||
|
||||
if (!opt && (cmd->cmd->flags & GRUB_COMMAND_ACCEPT_DASH))
|
||||
{
|
||||
if (add_arg (arg) != 0)
|
||||
|
|
105
grub-core/lib/cmdline.c
Normal file
105
grub-core/lib/cmdline.c
Normal file
|
@ -0,0 +1,105 @@
|
|||
/* cmdline.c - linux command line handling */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2010 Free Software Foundation, Inc.
|
||||
*
|
||||
* GRUB is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GRUB is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <grub/lib/cmdline.h>
|
||||
#include <grub/misc.h>
|
||||
|
||||
static unsigned int check_arg (char *c, int *has_space)
|
||||
{
|
||||
int space = 0;
|
||||
unsigned int size = 0;
|
||||
|
||||
while (*c)
|
||||
{
|
||||
if (*c == '\\' || *c == '\'' || *c == '"')
|
||||
size++;
|
||||
else if (*c == ' ')
|
||||
space = 1;
|
||||
|
||||
size++;
|
||||
c++;
|
||||
}
|
||||
|
||||
if (space)
|
||||
size += 2;
|
||||
|
||||
if (has_space)
|
||||
*has_space = space;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
unsigned int grub_loader_cmdline_size (int argc, char *argv[])
|
||||
{
|
||||
int i;
|
||||
unsigned int size = 0;
|
||||
|
||||
for (i = 0; i < argc; i++)
|
||||
{
|
||||
size += check_arg (argv[i], 0);
|
||||
size++; /* Separator space or NULL. */
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
int grub_create_loader_cmdline (int argc, char *argv[], char *buf,
|
||||
grub_size_t size)
|
||||
{
|
||||
int i, space;
|
||||
unsigned int arg_size;
|
||||
char *c;
|
||||
|
||||
for (i = 0; i < argc; i++)
|
||||
{
|
||||
c = argv[i];
|
||||
arg_size = check_arg(argv[i], &space);
|
||||
arg_size++; /* Separator space or NULL. */
|
||||
|
||||
if (size < arg_size)
|
||||
break;
|
||||
|
||||
size -= arg_size;
|
||||
|
||||
if (space)
|
||||
*buf++ = '"';
|
||||
|
||||
while (*c)
|
||||
{
|
||||
if (*c == '\\' || *c == '\'' || *c == '"')
|
||||
*buf++ = '\\';
|
||||
|
||||
*buf++ = *c;
|
||||
c++;
|
||||
}
|
||||
|
||||
if (space)
|
||||
*buf++ = '"';
|
||||
|
||||
*buf++ = ' ';
|
||||
}
|
||||
|
||||
/* Replace last space with null. */
|
||||
if (i)
|
||||
buf--;
|
||||
|
||||
*buf = 0;
|
||||
|
||||
return i;
|
||||
}
|
|
@ -19,31 +19,48 @@
|
|||
|
||||
#include <grub/datetime.h>
|
||||
#include <grub/cmos.h>
|
||||
#include <grub/dl.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
#if !defined (__powerpc__) && !defined (__sparc__)
|
||||
#define grub_get_datetime_cmos grub_get_datetime
|
||||
#define grub_set_datetime_cmos grub_set_datetime
|
||||
#endif
|
||||
|
||||
grub_err_t
|
||||
grub_get_datetime (struct grub_datetime *datetime)
|
||||
grub_get_datetime_cmos (struct grub_datetime *datetime)
|
||||
{
|
||||
int is_bcd, is_12hour;
|
||||
grub_uint8_t value, flag;
|
||||
grub_err_t err;
|
||||
|
||||
flag = grub_cmos_read (GRUB_CMOS_INDEX_STATUS_B);
|
||||
err = grub_cmos_read (GRUB_CMOS_INDEX_STATUS_B, &flag);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
is_bcd = ! (flag & GRUB_CMOS_STATUS_B_BINARY);
|
||||
|
||||
value = grub_cmos_read (GRUB_CMOS_INDEX_YEAR);
|
||||
err = grub_cmos_read (GRUB_CMOS_INDEX_YEAR, &value);
|
||||
if (err)
|
||||
return err;
|
||||
if (is_bcd)
|
||||
value = grub_bcd_to_num (value);
|
||||
|
||||
datetime->year = value;
|
||||
datetime->year += (value < 80) ? 2000 : 1900;
|
||||
|
||||
value = grub_cmos_read (GRUB_CMOS_INDEX_MONTH);
|
||||
err = grub_cmos_read (GRUB_CMOS_INDEX_MONTH, &value);
|
||||
if (err)
|
||||
return err;
|
||||
if (is_bcd)
|
||||
value = grub_bcd_to_num (value);
|
||||
|
||||
datetime->month = value;
|
||||
|
||||
value = grub_cmos_read (GRUB_CMOS_INDEX_DAY_OF_MONTH);
|
||||
err = grub_cmos_read (GRUB_CMOS_INDEX_DAY_OF_MONTH, &value);
|
||||
if (err)
|
||||
return err;
|
||||
if (is_bcd)
|
||||
value = grub_bcd_to_num (value);
|
||||
|
||||
|
@ -51,7 +68,9 @@ grub_get_datetime (struct grub_datetime *datetime)
|
|||
|
||||
is_12hour = ! (flag & GRUB_CMOS_STATUS_B_24HOUR);
|
||||
|
||||
value = grub_cmos_read (GRUB_CMOS_INDEX_HOUR);
|
||||
err = grub_cmos_read (GRUB_CMOS_INDEX_HOUR, &value);
|
||||
if (err)
|
||||
return err;
|
||||
if (is_12hour)
|
||||
{
|
||||
is_12hour = (value & 0x80);
|
||||
|
@ -68,13 +87,18 @@ grub_get_datetime (struct grub_datetime *datetime)
|
|||
|
||||
datetime->hour = value;
|
||||
|
||||
value = grub_cmos_read (GRUB_CMOS_INDEX_MINUTE);
|
||||
err = grub_cmos_read (GRUB_CMOS_INDEX_MINUTE, &value);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (is_bcd)
|
||||
value = grub_bcd_to_num (value);
|
||||
|
||||
datetime->minute = value;
|
||||
|
||||
value = grub_cmos_read (GRUB_CMOS_INDEX_SECOND);
|
||||
err = grub_cmos_read (GRUB_CMOS_INDEX_SECOND, &value);
|
||||
if (err)
|
||||
return err;
|
||||
if (is_bcd)
|
||||
value = grub_bcd_to_num (value);
|
||||
|
||||
|
@ -84,12 +108,15 @@ grub_get_datetime (struct grub_datetime *datetime)
|
|||
}
|
||||
|
||||
grub_err_t
|
||||
grub_set_datetime (struct grub_datetime *datetime)
|
||||
grub_set_datetime_cmos (struct grub_datetime *datetime)
|
||||
{
|
||||
int is_bcd, is_12hour;
|
||||
grub_uint8_t value, flag;
|
||||
grub_err_t err;
|
||||
|
||||
flag = grub_cmos_read (GRUB_CMOS_INDEX_STATUS_B);
|
||||
err = grub_cmos_read (GRUB_CMOS_INDEX_STATUS_B, &flag);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
is_bcd = ! (flag & GRUB_CMOS_STATUS_B_BINARY);
|
||||
|
||||
|
@ -99,21 +126,27 @@ grub_set_datetime (struct grub_datetime *datetime)
|
|||
if (is_bcd)
|
||||
value = grub_num_to_bcd (value);
|
||||
|
||||
grub_cmos_write (GRUB_CMOS_INDEX_YEAR, value);
|
||||
err = grub_cmos_write (GRUB_CMOS_INDEX_YEAR, value);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
value = datetime->month;
|
||||
|
||||
if (is_bcd)
|
||||
value = grub_num_to_bcd (value);
|
||||
|
||||
grub_cmos_write (GRUB_CMOS_INDEX_MONTH, value);
|
||||
err = grub_cmos_write (GRUB_CMOS_INDEX_MONTH, value);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
value = datetime->day;
|
||||
|
||||
if (is_bcd)
|
||||
value = grub_num_to_bcd (value);
|
||||
|
||||
grub_cmos_write (GRUB_CMOS_INDEX_DAY_OF_MONTH, value);
|
||||
err = grub_cmos_write (GRUB_CMOS_INDEX_DAY_OF_MONTH, value);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
value = datetime->hour;
|
||||
|
||||
|
@ -135,21 +168,27 @@ grub_set_datetime (struct grub_datetime *datetime)
|
|||
if (is_12hour)
|
||||
value |= 0x80;
|
||||
|
||||
grub_cmos_write (GRUB_CMOS_INDEX_HOUR, value);
|
||||
err = grub_cmos_write (GRUB_CMOS_INDEX_HOUR, value);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
value = datetime->minute;
|
||||
|
||||
if (is_bcd)
|
||||
value = grub_num_to_bcd (value);
|
||||
|
||||
grub_cmos_write (GRUB_CMOS_INDEX_MINUTE, value);
|
||||
err = grub_cmos_write (GRUB_CMOS_INDEX_MINUTE, value);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
value = datetime->second;
|
||||
|
||||
if (is_bcd)
|
||||
value = grub_num_to_bcd (value);
|
||||
|
||||
grub_cmos_write (GRUB_CMOS_INDEX_SECOND, value);
|
||||
err = grub_cmos_write (GRUB_CMOS_INDEX_SECOND, value);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -20,10 +20,10 @@
|
|||
#include <grub/types.h>
|
||||
#include <grub/lib/crc.h>
|
||||
|
||||
static grub_uint32_t crc32_table [256];
|
||||
static grub_uint32_t crc32c_table [256];
|
||||
|
||||
static void
|
||||
init_crc32_table (void)
|
||||
init_crc32c_table (void)
|
||||
{
|
||||
auto grub_uint32_t reflect (grub_uint32_t ref, int len);
|
||||
grub_uint32_t reflect (grub_uint32_t ref, int len)
|
||||
|
@ -41,33 +41,33 @@ init_crc32_table (void)
|
|||
return result;
|
||||
}
|
||||
|
||||
grub_uint32_t polynomial = 0x04c11db7;
|
||||
grub_uint32_t polynomial = 0x1edc6f41;
|
||||
int i, j;
|
||||
|
||||
for(i = 0; i < 256; i++)
|
||||
{
|
||||
crc32_table[i] = reflect(i, 8) << 24;
|
||||
crc32c_table[i] = reflect(i, 8) << 24;
|
||||
for (j = 0; j < 8; j++)
|
||||
crc32_table[i] = (crc32_table[i] << 1) ^
|
||||
(crc32_table[i] & (1 << 31) ? polynomial : 0);
|
||||
crc32_table[i] = reflect(crc32_table[i], 32);
|
||||
crc32c_table[i] = (crc32c_table[i] << 1) ^
|
||||
(crc32c_table[i] & (1 << 31) ? polynomial : 0);
|
||||
crc32c_table[i] = reflect(crc32c_table[i], 32);
|
||||
}
|
||||
}
|
||||
|
||||
grub_uint32_t
|
||||
grub_getcrc32 (grub_uint32_t crc, void *buf, int size)
|
||||
grub_getcrc32c (grub_uint32_t crc, const void *buf, int size)
|
||||
{
|
||||
int i;
|
||||
grub_uint8_t *data = buf;
|
||||
const grub_uint8_t *data = buf;
|
||||
|
||||
if (! crc32_table[1])
|
||||
init_crc32_table ();
|
||||
if (! crc32c_table[1])
|
||||
init_crc32c_table ();
|
||||
|
||||
crc^= 0xffffffff;
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
crc = (crc >> 8) ^ crc32_table[(crc & 0xFF) ^ *data];
|
||||
crc = (crc >> 8) ^ crc32c_table[(crc & 0xFF) ^ *data];
|
||||
data++;
|
||||
}
|
||||
|
||||
|
|
111
grub-core/lib/crc64.c
Normal file
111
grub-core/lib/crc64.c
Normal file
|
@ -0,0 +1,111 @@
|
|||
/* crc64.c - crc64 function */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2008,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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <grub/types.h>
|
||||
#include <grub/dl.h>
|
||||
#include <grub/crypto.h>
|
||||
|
||||
static grub_uint64_t crc64_table [256];
|
||||
|
||||
static void
|
||||
init_crc64_table (void)
|
||||
{
|
||||
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;
|
||||
|
||||
for (i = 1; i <= len; i++)
|
||||
{
|
||||
if (ref & 1)
|
||||
result |= 1ULL << (len - i);
|
||||
ref >>= 1;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
grub_uint64_t polynomial = 0x42f0e1eba9ea3693ULL;
|
||||
int i, j;
|
||||
|
||||
for(i = 0; i < 256; i++)
|
||||
{
|
||||
crc64_table[i] = reflect(i, 8) << 56;
|
||||
for (j = 0; j < 8; j++)
|
||||
{
|
||||
crc64_table[i] = (crc64_table[i] << 1) ^
|
||||
(crc64_table[i] & (1ULL << 63) ? polynomial : 0);
|
||||
}
|
||||
crc64_table[i] = reflect(crc64_table[i], 64);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
crc64_init (void *context)
|
||||
{
|
||||
if (! crc64_table[1])
|
||||
init_crc64_table ();
|
||||
*(grub_uint64_t *) context = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
crc64_write (void *context, const void *buf, grub_size_t size)
|
||||
{
|
||||
unsigned i;
|
||||
const grub_uint8_t *data = buf;
|
||||
grub_uint64_t crc = ~grub_le_to_cpu64 (*(grub_uint64_t *) context);
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
crc = (crc >> 8) ^ crc64_table[(crc & 0xFF) ^ *data];
|
||||
data++;
|
||||
}
|
||||
|
||||
*(grub_uint64_t *) context = grub_cpu_to_le64 (~crc);
|
||||
}
|
||||
|
||||
static grub_uint8_t *
|
||||
crc64_read (void *context)
|
||||
{
|
||||
return context;
|
||||
}
|
||||
|
||||
static void
|
||||
crc64_final (void *context __attribute__ ((unused)))
|
||||
{
|
||||
}
|
||||
|
||||
gcry_md_spec_t _gcry_digest_spec_crc64 =
|
||||
{
|
||||
"CRC64", 0, 0, 0, 8,
|
||||
crc64_init, crc64_write, crc64_final, crc64_read,
|
||||
sizeof (grub_uint64_t),
|
||||
.blocksize = 64
|
||||
};
|
||||
|
||||
GRUB_MOD_INIT(crc64)
|
||||
{
|
||||
grub_md_register (&_gcry_digest_spec_crc64);
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI(crc64)
|
||||
{
|
||||
grub_md_unregister (&_gcry_digest_spec_crc64);
|
||||
}
|
|
@ -21,6 +21,16 @@
|
|||
#include <grub/misc.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/term.h>
|
||||
#include <grub/dl.h>
|
||||
|
||||
#ifdef GRUB_UTIL
|
||||
#include <termios.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
struct grub_crypto_hmac_handle
|
||||
{
|
||||
|
@ -159,14 +169,6 @@ grub_crypto_cipher_set_key (grub_crypto_cipher_handle_t cipher,
|
|||
return cipher->cipher->setkey (cipher->ctx, key, keylen);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
grub_crypto_cipher_close (grub_crypto_cipher_handle_t cipher)
|
||||
{
|
||||
grub_free (cipher);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
grub_crypto_xor (void *out, const void *in1, const void *in2, grub_size_t size)
|
||||
{
|
||||
|
@ -183,9 +185,10 @@ grub_crypto_xor (void *out, const void *in1, const void *in2, grub_size_t size)
|
|||
|
||||
gcry_err_code_t
|
||||
grub_crypto_ecb_decrypt (grub_crypto_cipher_handle_t cipher,
|
||||
void *out, void *in, grub_size_t size)
|
||||
void *out, const void *in, grub_size_t size)
|
||||
{
|
||||
grub_uint8_t *inptr, *outptr, *end;
|
||||
const grub_uint8_t *inptr;
|
||||
grub_uint8_t *outptr, *end;
|
||||
if (!cipher->cipher->decrypt)
|
||||
return GPG_ERR_NOT_SUPPORTED;
|
||||
if (size % cipher->cipher->blocksize != 0)
|
||||
|
@ -199,9 +202,10 @@ grub_crypto_ecb_decrypt (grub_crypto_cipher_handle_t cipher,
|
|||
|
||||
gcry_err_code_t
|
||||
grub_crypto_ecb_encrypt (grub_crypto_cipher_handle_t cipher,
|
||||
void *out, void *in, grub_size_t size)
|
||||
void *out, const void *in, grub_size_t size)
|
||||
{
|
||||
grub_uint8_t *inptr, *outptr, *end;
|
||||
const grub_uint8_t *inptr;
|
||||
grub_uint8_t *outptr, *end;
|
||||
if (!cipher->cipher->encrypt)
|
||||
return GPG_ERR_NOT_SUPPORTED;
|
||||
if (size % cipher->cipher->blocksize != 0)
|
||||
|
@ -239,10 +243,11 @@ grub_crypto_cbc_encrypt (grub_crypto_cipher_handle_t cipher,
|
|||
|
||||
gcry_err_code_t
|
||||
grub_crypto_cbc_decrypt (grub_crypto_cipher_handle_t cipher,
|
||||
void *out, void *in, grub_size_t size,
|
||||
void *out, const void *in, grub_size_t size,
|
||||
void *iv)
|
||||
{
|
||||
grub_uint8_t *inptr, *outptr, *end;
|
||||
const grub_uint8_t *inptr;
|
||||
grub_uint8_t *outptr, *end;
|
||||
grub_uint8_t ivt[cipher->cipher->blocksize];
|
||||
if (!cipher->cipher->decrypt)
|
||||
return GPG_ERR_NOT_SUPPORTED;
|
||||
|
@ -333,7 +338,8 @@ grub_crypto_hmac_init (const struct gcry_md_spec *md,
|
|||
}
|
||||
|
||||
void
|
||||
grub_crypto_hmac_write (struct grub_crypto_hmac_handle *hnd, void *data,
|
||||
grub_crypto_hmac_write (struct grub_crypto_hmac_handle *hnd,
|
||||
const void *data,
|
||||
grub_size_t datalen)
|
||||
{
|
||||
hnd->md->write (hnd->ctx, data, datalen);
|
||||
|
@ -375,7 +381,7 @@ grub_crypto_hmac_fini (struct grub_crypto_hmac_handle *hnd, void *out)
|
|||
gcry_err_code_t
|
||||
grub_crypto_hmac_buffer (const struct gcry_md_spec *md,
|
||||
const void *key, grub_size_t keylen,
|
||||
void *data, grub_size_t datalen, void *out)
|
||||
const void *data, grub_size_t datalen, void *out)
|
||||
{
|
||||
struct grub_crypto_hmac_handle *hnd;
|
||||
|
||||
|
@ -411,16 +417,49 @@ grub_crypto_memcmp (const void *a, const void *b, grub_size_t n)
|
|||
return !!counter;
|
||||
}
|
||||
|
||||
#ifndef GRUB_MKPASSWD
|
||||
int
|
||||
grub_password_get (char buf[], unsigned buf_size)
|
||||
{
|
||||
#ifdef GRUB_UTIL
|
||||
FILE *in;
|
||||
struct termios s, t;
|
||||
int tty_changed = 0;
|
||||
char *ptr;
|
||||
|
||||
/* Disable echoing. Based on glibc. */
|
||||
in = fopen ("/dev/tty", "w+c");
|
||||
if (in == NULL)
|
||||
in = stdin;
|
||||
|
||||
if (tcgetattr (fileno (in), &t) == 0)
|
||||
{
|
||||
/* Save the old one. */
|
||||
s = t;
|
||||
/* Tricky, tricky. */
|
||||
t.c_lflag &= ~(ECHO|ISIG);
|
||||
tty_changed = (tcsetattr (fileno (in), TCSAFLUSH, &t) == 0);
|
||||
}
|
||||
else
|
||||
tty_changed = 0;
|
||||
fgets (buf, buf_size, stdin);
|
||||
ptr = buf + strlen (buf) - 1;
|
||||
while (buf <= ptr && (*ptr == '\n' || *ptr == '\r'))
|
||||
*ptr-- = 0;
|
||||
/* Restore the original setting. */
|
||||
if (tty_changed)
|
||||
(void) tcsetattr (fileno (in), TCSAFLUSH, &s);
|
||||
|
||||
grub_xputs ("\n");
|
||||
grub_refresh ();
|
||||
|
||||
return 1;
|
||||
#else
|
||||
unsigned cur_len = 0;
|
||||
int key;
|
||||
|
||||
while (1)
|
||||
{
|
||||
key = GRUB_TERM_ASCII_CHAR (grub_getkey ());
|
||||
key = grub_getkey ();
|
||||
if (key == '\n' || key == '\r')
|
||||
break;
|
||||
|
||||
|
@ -449,5 +488,5 @@ grub_password_get (char buf[], unsigned buf_size)
|
|||
grub_refresh ();
|
||||
|
||||
return (key != '\e');
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -22,6 +22,9 @@
|
|||
#include <grub/efi/api.h>
|
||||
#include <grub/efi/efi.h>
|
||||
#include <grub/datetime.h>
|
||||
#include <grub/dl.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
grub_err_t
|
||||
grub_get_datetime (struct grub_datetime *datetime)
|
||||
|
|
|
@ -28,7 +28,9 @@ void
|
|||
grub_halt (void)
|
||||
{
|
||||
grub_machine_fini ();
|
||||
#ifndef __ia64__
|
||||
grub_acpi_halt ();
|
||||
#endif
|
||||
efi_call_4 (grub_efi_system_table->runtime_services->reset_system,
|
||||
GRUB_EFI_RESET_SHUTDOWN, GRUB_EFI_SUCCESS, 0, NULL);
|
||||
|
||||
|
|
32
grub-core/lib/efi/reboot.c
Normal file
32
grub-core/lib/efi/reboot.c
Normal file
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <grub/efi/api.h>
|
||||
#include <grub/efi/efi.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/kernel.h>
|
||||
|
||||
void
|
||||
grub_reboot (void)
|
||||
{
|
||||
grub_machine_fini ();
|
||||
efi_call_4 (grub_efi_system_table->runtime_services->reset_system,
|
||||
GRUB_EFI_RESET_COLD, GRUB_EFI_SUCCESS, 0, NULL);
|
||||
for (;;) ;
|
||||
}
|
|
@ -62,13 +62,25 @@ grub_relocator_firmware_fill_events (struct grub_relocator_mmap_event *events)
|
|||
(char *) desc < ((char *) descs + mmapsize);
|
||||
desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size))
|
||||
{
|
||||
grub_uint64_t start = desc->physical_start;
|
||||
grub_uint64_t end = desc->physical_start + (desc->num_pages << 12);
|
||||
|
||||
/* post-4G addresses are never supported on 32-bit EFI.
|
||||
Moreover it has been reported that some 64-bit EFI contrary to the
|
||||
spec don't map post-4G pages. So if you enable post-4G allocations,
|
||||
map pages manually or check that they are mapped.
|
||||
*/
|
||||
if (end >= 0x100000000ULL)
|
||||
end = 0x100000000ULL;
|
||||
if (end <= start)
|
||||
continue;
|
||||
if (desc->type != GRUB_EFI_CONVENTIONAL_MEMORY)
|
||||
continue;
|
||||
events[counter].type = REG_FIRMWARE_START;
|
||||
events[counter].pos = desc->physical_start;
|
||||
events[counter].pos = start;
|
||||
counter++;
|
||||
events[counter].type = REG_FIRMWARE_END;
|
||||
events[counter].pos = desc->physical_start + (desc->num_pages << 12);
|
||||
events[counter].pos = end;
|
||||
counter++;
|
||||
}
|
||||
|
||||
|
@ -85,6 +97,9 @@ grub_relocator_firmware_alloc_region (grub_addr_t start, grub_size_t size)
|
|||
if (grub_efi_is_finished)
|
||||
return 1;
|
||||
|
||||
grub_dprintf ("relocator", "EFI alloc: %llx, %llx\n",
|
||||
(unsigned long long) start, (unsigned long long) size);
|
||||
|
||||
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);
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include <grub/cpu/io.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/acpi.h>
|
||||
#include <grub/i18n.h>
|
||||
|
||||
const char bochs_shutdown[] = "Shutdown";
|
||||
|
||||
|
@ -52,7 +53,7 @@ grub_halt (void)
|
|||
for (i = 0; i < sizeof (bochs_shutdown) - 1; i++)
|
||||
grub_outb (bochs_shutdown[i], 0x8900);
|
||||
|
||||
grub_printf ("GRUB doesn't know how to halt this machine yet!\n");
|
||||
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
|
||||
flag was. But user most likely doesn't want to return anyway ... */
|
||||
|
|
|
@ -19,11 +19,12 @@
|
|||
#include <grub/env.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/disk.h>
|
||||
#include <grub/machine/biosnum.h>
|
||||
|
||||
static int
|
||||
grub_get_root_biosnumber_default (void)
|
||||
{
|
||||
char *biosnum;
|
||||
const char *biosnum;
|
||||
int ret = -1;
|
||||
grub_device_t dev;
|
||||
|
||||
|
|
127
grub-core/lib/i386/pc/vesa_modes_table.c
Normal file
127
grub-core/lib/i386/pc/vesa_modes_table.c
Normal file
|
@ -0,0 +1,127 @@
|
|||
|
||||
#include <grub/i386/pc/vesa_modes_table.h>
|
||||
|
||||
/* This is the reverse of the table in [linux]/Documentation/fb/vesafb.txt
|
||||
plus a few more modes based on the table in
|
||||
http://en.wikipedia.org/wiki/VESA_BIOS_Extensions */
|
||||
struct grub_vesa_mode_table_entry
|
||||
grub_vesa_mode_table[GRUB_VESA_MODE_TABLE_END
|
||||
- GRUB_VESA_MODE_TABLE_START + 1] =
|
||||
{
|
||||
{ 640, 400, 8 }, /* 0x300 */
|
||||
{ 640, 480, 8 }, /* 0x301 */
|
||||
{ 800, 600, 4 }, /* 0x302 */
|
||||
{ 800, 600, 8 }, /* 0x303 */
|
||||
{ 1024, 768, 4 }, /* 0x304 */
|
||||
{ 1024, 768, 8 }, /* 0x305 */
|
||||
{ 1280, 1024, 4 }, /* 0x306 */
|
||||
{ 1280, 1024, 8 }, /* 0x307 */
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 0, 0 },
|
||||
{ 320, 200, 15 }, /* 0x30d */
|
||||
{ 320, 200, 16 }, /* 0x30e */
|
||||
{ 320, 200, 24 }, /* 0x30f */
|
||||
{ 640, 480, 15 }, /* 0x310 */
|
||||
{ 640, 480, 16 }, /* 0x311 */
|
||||
{ 640, 480, 24 }, /* 0x312 */
|
||||
{ 800, 600, 15 }, /* 0x313 */
|
||||
{ 800, 600, 16 }, /* 0x314 */
|
||||
{ 800, 600, 24 }, /* 0x315 */
|
||||
{ 1024, 768, 15 }, /* 0x316 */
|
||||
{ 1024, 768, 16 }, /* 0x317 */
|
||||
{ 1024, 768, 24 }, /* 0x318 */
|
||||
{ 1280, 1024, 15 }, /* 0x319 */
|
||||
{ 1280, 1024, 16 }, /* 0x31a */
|
||||
{ 1280, 1024, 24 }, /* 0x31b */
|
||||
{ 1600, 1200, 8 }, /* 0x31c */
|
||||
{ 1600, 1200, 15 }, /* 0x31d */
|
||||
{ 1600, 1200, 16 }, /* 0x31e */
|
||||
{ 1600, 1200, 24 }, /* 0x31f */
|
||||
{ 0, 0, 0 },
|
||||
{ 640, 400, 15 }, /* 0x321 */
|
||||
{ 640, 400, 16 }, /* 0x322 */
|
||||
{ 640, 400, 24 }, /* 0x323 */
|
||||
{ 640, 400, 32 }, /* 0x324 */
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 0, 0 },
|
||||
{ 640, 480, 32 }, /* 0x329 */
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 0, 0 },
|
||||
{ 896, 672, 8 }, /* 0x32f */
|
||||
{ 896, 672, 15 }, /* 0x330 */
|
||||
{ 896, 672, 16 }, /* 0x331 */
|
||||
{ 896, 672, 24 }, /* 0x332 */
|
||||
{ 896, 672, 32 }, /* 0x333 */
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 0, 0 },
|
||||
{ 1600, 1200, 32 }, /* 0x342 */
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 0, 0 },
|
||||
{ 0, 0, 0 },
|
||||
{ 1440, 900, 8 }, /* 0x360 */
|
||||
{ 1440, 900, 15 }, /* 0x361 */
|
||||
{ 1440, 900, 16 }, /* 0x362 */
|
||||
{ 1440, 900, 24 }, /* 0x363 */
|
||||
{ 1440, 900, 32 }, /* 0x364 */
|
||||
{ 1152, 720, 8 }, /* 0x365 */
|
||||
{ 1152, 720, 15 }, /* 0x366 */
|
||||
{ 1152, 720, 16 }, /* 0x367 */
|
||||
{ 1152, 720, 24 }, /* 0x368 */
|
||||
{ 1152, 720, 32 }, /* 0x369 */
|
||||
{ 1024, 640, 8 }, /* 0x36a */
|
||||
{ 1024, 640, 15 }, /* 0x36b */
|
||||
{ 1024, 640, 16 }, /* 0x36c */
|
||||
{ 1024, 640, 24 }, /* 0x36d */
|
||||
{ 1024, 640, 32 }, /* 0x36e */
|
||||
{ 800, 500, 8 }, /* 0x36f */
|
||||
{ 800, 500, 15 }, /* 0x370 */
|
||||
{ 800, 500, 16 }, /* 0x371 */
|
||||
{ 800, 500, 24 }, /* 0x372 */
|
||||
{ 800, 500, 32 }, /* 0x373 */
|
||||
};
|
60
grub-core/lib/i386/reboot.c
Normal file
60
grub-core/lib/i386/reboot.c
Normal file
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <grub/relocator.h>
|
||||
#include <grub/cpu/relocator.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/cpu/reboot.h>
|
||||
#include <grub/i386/floppy.h>
|
||||
|
||||
void
|
||||
grub_reboot (void)
|
||||
{
|
||||
struct grub_relocator *relocator = NULL;
|
||||
grub_relocator_chunk_t ch;
|
||||
grub_err_t err;
|
||||
void *buf;
|
||||
struct grub_relocator16_state state;
|
||||
grub_uint16_t segment;
|
||||
|
||||
relocator = grub_relocator_new ();
|
||||
if (!relocator)
|
||||
while (1);
|
||||
err = grub_relocator_alloc_chunk_align (relocator, &ch, 0x1000, 0x1000,
|
||||
grub_reboot_end - grub_reboot_start,
|
||||
16, GRUB_RELOCATOR_PREFERENCE_NONE);
|
||||
if (err)
|
||||
while (1);
|
||||
buf = get_virtual_current_address (ch);
|
||||
grub_memcpy (buf, grub_reboot_start, grub_reboot_end - grub_reboot_start);
|
||||
|
||||
segment = ((grub_addr_t) get_physical_target_address (ch)) >> 4;
|
||||
state.gs = state.fs = state.es = state.ds = state.ss = segment;
|
||||
state.sp = 0;
|
||||
state.cs = segment;
|
||||
state.ip = 0;
|
||||
state.a20 = 0;
|
||||
|
||||
grub_stop_floppy ();
|
||||
|
||||
err = grub_relocator16_boot (relocator, state);
|
||||
|
||||
while (1);
|
||||
}
|
||||
|
34
grub-core/lib/i386/reboot_trampoline.S
Normal file
34
grub-core/lib/i386/reboot_trampoline.S
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <grub/symbol.h>
|
||||
#include <grub/i386/reboot.h>
|
||||
|
||||
.p2align 4
|
||||
|
||||
VARIABLE(grub_reboot_start)
|
||||
.code16
|
||||
|
||||
/* set 0x472 to 0x0000 for cold boot (0x1234 for warm boot) */
|
||||
movw $0x0472, %di
|
||||
xorw %ax, %ax
|
||||
movw %ax, (%di)
|
||||
ljmp $0xf000, $0xfff0
|
||||
|
||||
.code32
|
||||
VARIABLE(grub_reboot_end)
|
|
@ -50,6 +50,10 @@ extern grub_uint16_t grub_relocator16_gs;
|
|||
extern grub_uint16_t grub_relocator16_ss;
|
||||
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_uint16_t grub_relocator16_keep_a20_enabled;
|
||||
|
||||
extern grub_uint8_t grub_relocator32_start;
|
||||
extern grub_uint8_t grub_relocator32_end;
|
||||
|
@ -194,7 +198,8 @@ grub_relocator16_boot (struct grub_relocator *rel,
|
|||
void *relst;
|
||||
grub_relocator_chunk_t ch;
|
||||
|
||||
err = grub_relocator_alloc_chunk_align (rel, &ch, 0,
|
||||
/* Put it higher than the byte it checks for A20 check. */
|
||||
err = grub_relocator_alloc_chunk_align (rel, &ch, 0x8010,
|
||||
0xa0000 - RELOCATOR_SIZEOF (16),
|
||||
RELOCATOR_SIZEOF (16), 16,
|
||||
GRUB_RELOCATOR_PREFERENCE_NONE);
|
||||
|
@ -212,7 +217,11 @@ grub_relocator16_boot (struct grub_relocator *rel,
|
|||
grub_relocator16_ss = state.ss;
|
||||
grub_relocator16_sp = state.sp;
|
||||
|
||||
grub_relocator16_ebx = state.ebx;
|
||||
grub_relocator16_edx = state.edx;
|
||||
grub_relocator16_esi = state.esi;
|
||||
|
||||
grub_relocator16_keep_a20_enabled = state.a20;
|
||||
|
||||
grub_memmove (get_virtual_current_address (ch), &grub_relocator16_start,
|
||||
RELOCATOR_SIZEOF (16));
|
||||
|
|
|
@ -93,6 +93,85 @@ LOCAL(segment):
|
|||
.word 0
|
||||
|
||||
LOCAL(cont3):
|
||||
|
||||
/* movw imm16, %ax. */
|
||||
.byte 0xb8
|
||||
VARIABLE(grub_relocator16_keep_a20_enabled)
|
||||
.word 0
|
||||
test %ax, %ax
|
||||
jnz LOCAL(gate_a20_done)
|
||||
|
||||
/* first of all, test if already in a good state */
|
||||
call LOCAL(gate_a20_check_state)
|
||||
testb %al, %al
|
||||
jz LOCAL(gate_a20_done)
|
||||
|
||||
/* second, try a BIOS call */
|
||||
movw $0x2400, %ax
|
||||
int $0x15
|
||||
|
||||
call LOCAL(gate_a20_check_state)
|
||||
testb %al, %al
|
||||
jz LOCAL(gate_a20_done)
|
||||
|
||||
/*
|
||||
* In macbook, the keyboard test would hang the machine, so we move
|
||||
* this forward.
|
||||
*/
|
||||
/* fourth, try the system control port A */
|
||||
inb $0x92
|
||||
andb $(~0x03), %al
|
||||
outb $0x92
|
||||
|
||||
/* When turning off Gate A20, do not check the state strictly,
|
||||
because a failure is not fatal usually, and Gate A20 is always
|
||||
on some modern machines. */
|
||||
jmp LOCAL(gate_a20_done)
|
||||
|
||||
LOCAL(gate_a20_check_state):
|
||||
/* iterate the checking for a while */
|
||||
movw $100, %cx
|
||||
1:
|
||||
call 3f
|
||||
testb %al, %al
|
||||
jz 2f
|
||||
loop 1b
|
||||
2:
|
||||
ret
|
||||
|
||||
3:
|
||||
xorw %ax, %ax
|
||||
movw %ax, %ds
|
||||
decw %ax
|
||||
movw %ax, %es
|
||||
xorw %ax, %ax
|
||||
|
||||
movw $0x8000, %ax
|
||||
/* compare the byte at ADDR with that at 0x100000 + ADDR */
|
||||
movw %ax, %si
|
||||
addw $0x10, %ax
|
||||
movw %ax, %di
|
||||
|
||||
/* save the original byte in DL */
|
||||
movb %ds:(%si), %dl
|
||||
movb %es:(%di), %al
|
||||
/* try to set one less value at ADDR */
|
||||
movb %al, %dh
|
||||
decb %dh
|
||||
movb %dh, %ds:(%si)
|
||||
/* serialize */
|
||||
outb %al, $0x80
|
||||
outb %al, $0x80
|
||||
/* obtain the value at 0x100000 + ADDR in CH */
|
||||
movb %es:(%di), %dh
|
||||
/* this result is 1 if A20 is on or 0 if it is off */
|
||||
subb %dh, %al
|
||||
xorb $1, %al
|
||||
/* restore the original */
|
||||
movb %dl, %es:(%di)
|
||||
ret
|
||||
|
||||
LOCAL(gate_a20_done):
|
||||
/* we are in real mode now
|
||||
* set up the real mode segment registers : DS, SS, ES
|
||||
*/
|
||||
|
@ -130,13 +209,24 @@ VARIABLE(grub_relocator16_ss)
|
|||
.byte 0xb8
|
||||
VARIABLE(grub_relocator16_sp)
|
||||
.word 0
|
||||
movw %ax, %ss
|
||||
movzwl %ax, %esp
|
||||
|
||||
/* movw imm32, %eax. */
|
||||
.byte 0x66, 0xb8
|
||||
VARIABLE(grub_relocator16_esi)
|
||||
.long 0
|
||||
movl %eax, %esi
|
||||
|
||||
/* movw imm32, %edx. */
|
||||
.byte 0x66, 0xba
|
||||
VARIABLE(grub_relocator16_edx)
|
||||
.long 0
|
||||
|
||||
|
||||
/* movw imm32, %ebx. */
|
||||
.byte 0x66, 0xbb
|
||||
VARIABLE(grub_relocator16_ebx)
|
||||
.long 0
|
||||
|
||||
/* Cleared direction flag is of no problem with any current
|
||||
payload and makes this implementation easier. */
|
||||
cld
|
||||
|
|
|
@ -17,9 +17,12 @@
|
|||
*/
|
||||
|
||||
#include <grub/symbol.h>
|
||||
#include <grub/dl.h>
|
||||
|
||||
.file "setjmp.S"
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+")
|
||||
|
||||
.text
|
||||
|
||||
/*
|
||||
|
|
162
grub-core/lib/ia64/longjmp.S
Normal file
162
grub-core/lib/ia64/longjmp.S
Normal file
|
@ -0,0 +1,162 @@
|
|||
/* Copyright (C) 1999, 2000, 2001, 2002, 2008 Free Software Foundation, Inc.
|
||||
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>.
|
||||
|
||||
The GNU C 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 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA.
|
||||
|
||||
Note that __sigsetjmp() did NOT flush the register stack. Instead,
|
||||
we do it here since __longjmp() is usually much less frequently
|
||||
invoked than __sigsetjmp(). The only difficulty is that __sigsetjmp()
|
||||
didn't (and wouldn't be able to) save ar.rnat either. This is a problem
|
||||
because if we're not careful, we could end up loading random NaT bits.
|
||||
There are two cases:
|
||||
|
||||
(i) ar.bsp < ia64_rse_rnat_addr(jmpbuf.ar_bsp)
|
||||
ar.rnat contains the desired bits---preserve ar.rnat
|
||||
across loadrs and write to ar.bspstore
|
||||
|
||||
(ii) ar.bsp >= ia64_rse_rnat_addr(jmpbuf.ar_bsp)
|
||||
The desired ar.rnat is stored in
|
||||
ia64_rse_rnat_addr(jmpbuf.ar_bsp). Load those
|
||||
bits into ar.rnat after setting ar.bspstore. */
|
||||
|
||||
|
||||
|
||||
# define pPos p6 /* is rotate count positive? */
|
||||
# define pNeg p7 /* is rotate count negative? */
|
||||
|
||||
|
||||
/* __longjmp(__jmp_buf buf, int val) */
|
||||
|
||||
.text
|
||||
.global longjmp
|
||||
.proc longjmp
|
||||
longjmp:
|
||||
alloc r8=ar.pfs,2,1,0,0
|
||||
mov r27=ar.rsc
|
||||
add r2=0x98,in0 // r2 <- &jmpbuf.orig_jmp_buf_addr
|
||||
;;
|
||||
ld8 r8=[r2],-16 // r8 <- orig_jmp_buf_addr
|
||||
mov r10=ar.bsp
|
||||
and r11=~0x3,r27 // clear ar.rsc.mode
|
||||
;;
|
||||
flushrs // flush dirty regs to backing store (must be first in insn grp)
|
||||
ld8 r23=[r2],8 // r23 <- jmpbuf.ar_bsp
|
||||
sub r8=r8,in0 // r8 <- &orig_jmpbuf - &jmpbuf
|
||||
;;
|
||||
ld8 r25=[r2] // r25 <- jmpbuf.ar_unat
|
||||
extr.u r8=r8,3,6 // r8 <- (&orig_jmpbuf - &jmpbuf)/8 & 0x3f
|
||||
;;
|
||||
cmp.lt pNeg,pPos=r8,r0
|
||||
mov r2=in0
|
||||
;;
|
||||
(pPos) mov r16=r8
|
||||
(pNeg) add r16=64,r8
|
||||
(pPos) sub r17=64,r8
|
||||
(pNeg) sub r17=r0,r8
|
||||
;;
|
||||
mov ar.rsc=r11 // put RSE in enforced lazy mode
|
||||
shr.u r8=r25,r16
|
||||
add r3=8,in0 // r3 <- &jmpbuf.r1
|
||||
shl r9=r25,r17
|
||||
;;
|
||||
or r25=r8,r9
|
||||
;;
|
||||
mov r26=ar.rnat
|
||||
mov ar.unat=r25 // setup ar.unat (NaT bits for r1, r4-r7, and r12)
|
||||
;;
|
||||
ld8.fill.nta sp=[r2],16 // r12 (sp)
|
||||
ld8.fill.nta gp=[r3],16 // r1 (gp)
|
||||
dep r11=-1,r23,3,6 // r11 <- ia64_rse_rnat_addr(jmpbuf.ar_bsp)
|
||||
;;
|
||||
ld8.nta r16=[r2],16 // caller's unat
|
||||
ld8.nta r17=[r3],16 // fpsr
|
||||
;;
|
||||
ld8.fill.nta r4=[r2],16 // r4
|
||||
ld8.fill.nta r5=[r3],16 // r5 (gp)
|
||||
cmp.geu p8,p0=r10,r11 // p8 <- (ar.bsp >= jmpbuf.ar_bsp)
|
||||
;;
|
||||
ld8.fill.nta r6=[r2],16 // r6
|
||||
ld8.fill.nta r7=[r3],16 // r7
|
||||
;;
|
||||
mov ar.unat=r16 // restore caller's unat
|
||||
mov ar.fpsr=r17 // restore fpsr
|
||||
;;
|
||||
ld8.nta r16=[r2],16 // b0
|
||||
ld8.nta r17=[r3],16 // b1
|
||||
;;
|
||||
(p8) ld8 r26=[r11] // r26 <- *ia64_rse_rnat_addr(jmpbuf.ar_bsp)
|
||||
mov ar.bspstore=r23 // restore ar.bspstore
|
||||
;;
|
||||
ld8.nta r18=[r2],16 // b2
|
||||
ld8.nta r19=[r3],16 // b3
|
||||
;;
|
||||
ld8.nta r20=[r2],16 // b4
|
||||
ld8.nta r21=[r3],16 // b5
|
||||
;;
|
||||
ld8.nta r11=[r2],16 // ar.pfs
|
||||
ld8.nta r22=[r3],56 // ar.lc
|
||||
;;
|
||||
ld8.nta r24=[r2],32 // pr
|
||||
mov b0=r16
|
||||
;;
|
||||
ldf.fill.nta f2=[r2],32
|
||||
ldf.fill.nta f3=[r3],32
|
||||
mov b1=r17
|
||||
;;
|
||||
ldf.fill.nta f4=[r2],32
|
||||
ldf.fill.nta f5=[r3],32
|
||||
mov b2=r18
|
||||
;;
|
||||
ldf.fill.nta f16=[r2],32
|
||||
ldf.fill.nta f17=[r3],32
|
||||
mov b3=r19
|
||||
;;
|
||||
ldf.fill.nta f18=[r2],32
|
||||
ldf.fill.nta f19=[r3],32
|
||||
mov b4=r20
|
||||
;;
|
||||
ldf.fill.nta f20=[r2],32
|
||||
ldf.fill.nta f21=[r3],32
|
||||
mov b5=r21
|
||||
;;
|
||||
ldf.fill.nta f22=[r2],32
|
||||
ldf.fill.nta f23=[r3],32
|
||||
mov ar.lc=r22
|
||||
;;
|
||||
ldf.fill.nta f24=[r2],32
|
||||
ldf.fill.nta f25=[r3],32
|
||||
cmp.eq p8,p9=0,in1
|
||||
;;
|
||||
ldf.fill.nta f26=[r2],32
|
||||
ldf.fill.nta f27=[r3],32
|
||||
mov ar.pfs=r11
|
||||
;;
|
||||
ldf.fill.nta f28=[r2],32
|
||||
ldf.fill.nta f29=[r3],32
|
||||
;;
|
||||
ldf.fill.nta f30=[r2]
|
||||
ldf.fill.nta f31=[r3]
|
||||
(p8) mov r8=1
|
||||
|
||||
mov ar.rnat=r26 // restore ar.rnat
|
||||
;;
|
||||
mov ar.rsc=r27 // restore ar.rsc
|
||||
(p9) mov r8=in1
|
||||
|
||||
invala // virt. -> phys. regnum mapping may change
|
||||
mov pr=r24,-1
|
||||
br.ret.dptk.few rp
|
||||
.endp longjmp
|
177
grub-core/lib/ia64/setjmp.S
Normal file
177
grub-core/lib/ia64/setjmp.S
Normal file
|
@ -0,0 +1,177 @@
|
|||
/* Copyright (C) 1999, 2000, 2001, 2002, 2008 Free Software Foundation, Inc.
|
||||
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>.
|
||||
|
||||
The GNU C 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 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA.
|
||||
|
||||
The layout of the jmp_buf is as follows. This is subject to change
|
||||
and user-code should never depend on the particular layout of
|
||||
jmp_buf!
|
||||
|
||||
|
||||
offset: description:
|
||||
------- ------------
|
||||
0x000 stack pointer (r12) ; unchangeable (see _JMPBUF_UNWINDS)
|
||||
0x008 r1 (gp)
|
||||
0x010 caller's unat
|
||||
0x018 fpsr
|
||||
0x020 r4
|
||||
0x028 r5
|
||||
0x030 r6
|
||||
0x038 r7
|
||||
0x040 rp (b0)
|
||||
0x048 b1
|
||||
0x050 b2
|
||||
0x058 b3
|
||||
0x060 b4
|
||||
0x068 b5
|
||||
0x070 ar.pfs
|
||||
0x078 ar.lc
|
||||
0x080 pr
|
||||
0x088 ar.bsp ; unchangeable (see __longjmp.S)
|
||||
0x090 ar.unat
|
||||
0x098 &__jmp_buf ; address of the jmpbuf (needed to locate NaT bits in unat)
|
||||
0x0a0 f2
|
||||
0x0b0 f3
|
||||
0x0c0 f4
|
||||
0x0d0 f5
|
||||
0x0e0 f16
|
||||
0x0f0 f17
|
||||
0x100 f18
|
||||
0x110 f19
|
||||
0x120 f20
|
||||
0x130 f21
|
||||
0x130 f22
|
||||
0x140 f23
|
||||
0x150 f24
|
||||
0x160 f25
|
||||
0x170 f26
|
||||
0x180 f27
|
||||
0x190 f28
|
||||
0x1a0 f29
|
||||
0x1b0 f30
|
||||
0x1c0 f31 */
|
||||
|
||||
#include <grub/symbol.h>
|
||||
#include <grub/dl.h>
|
||||
|
||||
.file "setjmp.S"
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv2+")
|
||||
|
||||
/* The following two entry points are the traditional entry points: */
|
||||
|
||||
.text
|
||||
.global setjmp
|
||||
.proc setjmp
|
||||
setjmp:
|
||||
alloc r8=ar.pfs,2,0,0,0
|
||||
mov in1=1
|
||||
br.cond.sptk.many __sigsetjmp
|
||||
.endp setjmp
|
||||
|
||||
/* __sigsetjmp(__jmp_buf buf, int savemask) */
|
||||
|
||||
.proc __sigsetjmp
|
||||
__sigsetjmp:
|
||||
//.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(2)
|
||||
alloc loc1=ar.pfs,2,2,2,0
|
||||
mov r16=ar.unat
|
||||
;;
|
||||
mov r17=ar.fpsr
|
||||
mov r2=in0
|
||||
add r3=8,in0
|
||||
;;
|
||||
st8.spill.nta [r2]=sp,16 // r12 (sp)
|
||||
st8.spill.nta [r3]=gp,16 // r1 (gp)
|
||||
;;
|
||||
st8.nta [r2]=r16,16 // save caller's unat
|
||||
st8.nta [r3]=r17,16 // save fpsr
|
||||
add r8=0xa0,in0
|
||||
;;
|
||||
st8.spill.nta [r2]=r4,16 // r4
|
||||
st8.spill.nta [r3]=r5,16 // r5
|
||||
add r9=0xb0,in0
|
||||
;;
|
||||
stf.spill.nta [r8]=f2,32
|
||||
stf.spill.nta [r9]=f3,32
|
||||
mov loc0=rp
|
||||
.body
|
||||
;;
|
||||
stf.spill.nta [r8]=f4,32
|
||||
stf.spill.nta [r9]=f5,32
|
||||
mov r17=b1
|
||||
;;
|
||||
stf.spill.nta [r8]=f16,32
|
||||
stf.spill.nta [r9]=f17,32
|
||||
mov r18=b2
|
||||
;;
|
||||
stf.spill.nta [r8]=f18,32
|
||||
stf.spill.nta [r9]=f19,32
|
||||
mov r19=b3
|
||||
;;
|
||||
stf.spill.nta [r8]=f20,32
|
||||
stf.spill.nta [r9]=f21,32
|
||||
mov r20=b4
|
||||
;;
|
||||
stf.spill.nta [r8]=f22,32
|
||||
stf.spill.nta [r9]=f23,32
|
||||
mov r21=b5
|
||||
;;
|
||||
stf.spill.nta [r8]=f24,32
|
||||
stf.spill.nta [r9]=f25,32
|
||||
mov r22=ar.lc
|
||||
;;
|
||||
stf.spill.nta [r8]=f26,32
|
||||
stf.spill.nta [r9]=f27,32
|
||||
mov r24=pr
|
||||
;;
|
||||
stf.spill.nta [r8]=f28,32
|
||||
stf.spill.nta [r9]=f29,32
|
||||
;;
|
||||
stf.spill.nta [r8]=f30
|
||||
stf.spill.nta [r9]=f31
|
||||
|
||||
st8.spill.nta [r2]=r6,16 // r6
|
||||
st8.spill.nta [r3]=r7,16 // r7
|
||||
;;
|
||||
mov r23=ar.bsp
|
||||
mov r25=ar.unat
|
||||
mov out0=in0
|
||||
|
||||
st8.nta [r2]=loc0,16 // b0
|
||||
st8.nta [r3]=r17,16 // b1
|
||||
mov out1=in1
|
||||
;;
|
||||
st8.nta [r2]=r18,16 // b2
|
||||
st8.nta [r3]=r19,16 // b3
|
||||
;;
|
||||
st8.nta [r2]=r20,16 // b4
|
||||
st8.nta [r3]=r21,16 // b5
|
||||
;;
|
||||
st8.nta [r2]=loc1,16 // ar.pfs
|
||||
st8.nta [r3]=r22,16 // ar.lc
|
||||
;;
|
||||
st8.nta [r2]=r24,16 // pr
|
||||
st8.nta [r3]=r23,16 // ar.bsp
|
||||
;;
|
||||
st8.nta [r2]=r25 // ar.unat
|
||||
st8.nta [r3]=in0 // &__jmp_buf
|
||||
mov r8=0
|
||||
mov rp=loc0
|
||||
mov ar.pfs=loc1
|
||||
br.ret.sptk.many rp
|
||||
|
||||
.endp __sigsetjmp
|
75
grub-core/lib/ieee1275/cmos.c
Normal file
75
grub-core/lib/ieee1275/cmos.c
Normal file
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <grub/datetime.h>
|
||||
#include <grub/cmos.h>
|
||||
#include <grub/dl.h>
|
||||
#include <grub/ieee1275/ieee1275.h>
|
||||
#include <grub/misc.h>
|
||||
|
||||
volatile grub_uint8_t *grub_cmos_port = 0;
|
||||
grub_err_t
|
||||
grub_cmos_find_port (void)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
#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;
|
||||
}
|
||||
#else
|
||||
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);
|
||||
if (!grub_cmos_port)
|
||||
return grub_error (GRUB_ERR_IO, "no cmos found");
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
|
@ -20,8 +20,15 @@
|
|||
#include <grub/datetime.h>
|
||||
#include <grub/ieee1275/ieee1275.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/dl.h>
|
||||
#if defined (__powerpc__) || defined (__sparc__)
|
||||
#include <grub/cmos.h>
|
||||
#endif
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
static char *rtc = 0;
|
||||
static int no_ieee1275_rtc = 0;
|
||||
|
||||
static void
|
||||
find_rtc (void)
|
||||
|
@ -39,6 +46,8 @@ find_rtc (void)
|
|||
}
|
||||
|
||||
grub_ieee1275_devices_iterate (hook);
|
||||
if (!rtc)
|
||||
no_ieee1275_rtc = 1;
|
||||
}
|
||||
|
||||
grub_err_t
|
||||
|
@ -61,10 +70,12 @@ grub_get_datetime (struct grub_datetime *datetime)
|
|||
int status;
|
||||
grub_ieee1275_ihandle_t ihandle;
|
||||
|
||||
if (no_ieee1275_rtc)
|
||||
return grub_get_datetime_cmos (datetime);
|
||||
if (!rtc)
|
||||
find_rtc ();
|
||||
if (!rtc)
|
||||
return grub_error (GRUB_ERR_IO, "no RTC found");
|
||||
return grub_get_datetime_cmos (datetime);
|
||||
|
||||
status = grub_ieee1275_open (rtc, &ihandle);
|
||||
if (status == -1)
|
||||
|
@ -111,10 +122,12 @@ grub_set_datetime (struct grub_datetime *datetime)
|
|||
int status;
|
||||
grub_ieee1275_ihandle_t ihandle;
|
||||
|
||||
if (no_ieee1275_rtc)
|
||||
return grub_set_datetime_cmos (datetime);
|
||||
if (!rtc)
|
||||
find_rtc ();
|
||||
if (!rtc)
|
||||
return grub_error (GRUB_ERR_IO, "no RTC found");
|
||||
return grub_set_datetime_cmos (datetime);
|
||||
|
||||
status = grub_ieee1275_open (rtc, &ihandle);
|
||||
if (status == -1)
|
||||
|
|
27
grub-core/lib/ieee1275/reboot.c
Normal file
27
grub-core/lib/ieee1275/reboot.c
Normal file
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <grub/ieee1275/ieee1275.h>
|
||||
#include <grub/misc.h>
|
||||
|
||||
void
|
||||
grub_reboot (void)
|
||||
{
|
||||
grub_ieee1275_interpret ("reset-all", 0);
|
||||
for (;;) ;
|
||||
}
|
|
@ -27,10 +27,10 @@ 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_uint32_t type __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_uint32_t type __attribute__ ((unused)))
|
||||
grub_memory_type_t type __attribute__ ((unused)))
|
||||
{
|
||||
counter++;
|
||||
return 0;
|
||||
|
@ -47,11 +47,11 @@ grub_relocator_firmware_fill_events (struct grub_relocator_mmap_event *events)
|
|||
{
|
||||
int counter = 0;
|
||||
auto int NESTED_FUNC_ATTR fill (grub_uint64_t addr, grub_uint64_t len,
|
||||
grub_uint32_t type);
|
||||
grub_memory_type_t type);
|
||||
int NESTED_FUNC_ATTR fill (grub_uint64_t addr, grub_uint64_t len,
|
||||
grub_uint32_t type)
|
||||
grub_memory_type_t type)
|
||||
{
|
||||
if (type != GRUB_MACHINE_MEMORY_AVAILABLE)
|
||||
if (type != GRUB_MEMORY_AVAILABLE)
|
||||
return 0;
|
||||
|
||||
if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_PRE1_5M_CLAIM))
|
||||
|
|
818
grub-core/lib/legacy_parse.c
Normal file
818
grub-core/lib/legacy_parse.c
Normal file
|
@ -0,0 +1,818 @@
|
|||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 1999,2000,2001,2002,2003,2004,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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <grub/types.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/err.h>
|
||||
#include <grub/legacy_parse.h>
|
||||
#include <grub/i386/pc/vesa_modes_table.h>
|
||||
|
||||
struct legacy_command
|
||||
{
|
||||
const char *name;
|
||||
const char *map;
|
||||
const char *suffix;
|
||||
unsigned suffixarg;
|
||||
unsigned argc;
|
||||
enum arg_type {
|
||||
TYPE_VERBATIM,
|
||||
TYPE_FORCE_OPTION,
|
||||
TYPE_NOAPM_OPTION,
|
||||
TYPE_TYPE_OR_NOMEM_OPTION,
|
||||
TYPE_OPTION,
|
||||
TYPE_FILE,
|
||||
TYPE_FILE_NO_CONSUME,
|
||||
TYPE_PARTITION,
|
||||
TYPE_BOOL,
|
||||
TYPE_INT,
|
||||
TYPE_REST_VERBATIM,
|
||||
TYPE_VBE_MODE
|
||||
} argt[4];
|
||||
enum {
|
||||
FLAG_IGNORE_REST = 0x001,
|
||||
FLAG_FALLBACK_AVAILABLE = 0x004,
|
||||
FLAG_FALLBACK = 0x008,
|
||||
FLAG_COLOR_INVERT = 0x010,
|
||||
FLAG_NO_MENUENTRY = 0x020,
|
||||
FLAG_MENUENTRY_ONLY = 0x040,
|
||||
FLAG_TERMINAL = 0x080,
|
||||
FLAG_TITLE = 0x100,
|
||||
} flags;
|
||||
const char *shortdesc;
|
||||
const char *longdesc;
|
||||
};
|
||||
|
||||
/* Help texts are kept here mostly for reference. They are never shown. So
|
||||
no need to gettextize.
|
||||
*/
|
||||
static struct legacy_command legacy_commands[] =
|
||||
{
|
||||
{"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,
|
||||
"Boot the OS/chain-loader which has been loaded."},
|
||||
/* FIXME: bootp unsupported. */
|
||||
{"cat", "cat '%s'\n", NULL, 0, 1, {TYPE_FILE}, 0, "FILE",
|
||||
"Print the contents of the file FILE."},
|
||||
{"chainloader", "chainloader %s '%s'\n", NULL, 0,
|
||||
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."},
|
||||
{"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"
|
||||
" if any."},
|
||||
{"color", "set color_normal='%s'; set color_highlight='%s'\n", NULL, 0,
|
||||
2, {TYPE_VERBATIM, TYPE_VERBATIM},
|
||||
FLAG_IGNORE_REST | FLAG_FALLBACK_AVAILABLE, "NORMAL [HIGHLIGHT]",
|
||||
"Change the menu colors. The color NORMAL is used for most"
|
||||
" lines in the menu, and the color HIGHLIGHT is used to highlight the"
|
||||
" line where the cursor points. If you omit HIGHLIGHT, then the"
|
||||
" inverted color of NORMAL is used for the highlighted line."
|
||||
" The format of a color is \"FG/BG\". FG and BG are symbolic color names."
|
||||
" A symbolic color name must be one of these: black, blue, green,"
|
||||
" cyan, red, magenta, brown, light-gray, dark-gray, light-blue,"
|
||||
" light-green, light-cyan, light-red, light-magenta, yellow and white."
|
||||
" But only the first eight names can be used for BG. You can prefix"
|
||||
" \"blink-\" to FG if you want a blinking foreground color."},
|
||||
{"color", "set color_normal='%s'; set color_highlight='%s'\n", NULL, 0,
|
||||
1, {TYPE_VERBATIM},
|
||||
FLAG_IGNORE_REST | FLAG_FALLBACK | FLAG_COLOR_INVERT, NULL, NULL},
|
||||
{"configfile", "legacy_configfile '%s'\n", NULL, 0, 1, {TYPE_FILE},
|
||||
0, "FILE", "Load FILE as the configuration file."},
|
||||
{"debug",
|
||||
"if [ -z \"$debug\" ]; then set debug=all; else set debug=; fi\n", NULL, 0,
|
||||
0, {}, 0, 0, "Turn on/off the debug mode."},
|
||||
{"default",
|
||||
"set default='%s'; if [ x\"$default\" = xsaved ]; then load_env; "
|
||||
"set default=\"$saved_entry\"; fi\n", NULL, 0, 1, {TYPE_VERBATIM}, 0,
|
||||
"[NUM | `saved']",
|
||||
"Set the default entry to entry number NUM (if not specified, it is"
|
||||
" 0, the first entry) or the entry number saved by savedefault."},
|
||||
/* FIXME: dhcp unsupported. */
|
||||
{"displayapm", "lsapm\n", NULL, 0, 0, {}, 0, 0,
|
||||
"Display APM BIOS information."},
|
||||
{"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."},
|
||||
/* NOTE: embed unsupported. */
|
||||
{"fallback", "set fallback='%s'\n", NULL, 0,
|
||||
1, {TYPE_VERBATIM}, 0, "NUM...",
|
||||
"Go into unattended boot mode: if the default boot entry has any"
|
||||
" errors, instead of waiting for the user to do anything, it"
|
||||
" immediately starts over using the NUM entry (same numbering as the"
|
||||
" `default' command). This obviously won't help if the machine"
|
||||
" was rebooted by a kernel that GRUB loaded."},
|
||||
{"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: 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",
|
||||
"Print the information for a drive DRIVE. "},
|
||||
{"halt", "halt %s\n", NULL, 0, 1, {TYPE_NOAPM_OPTION}, 0, "[--no-apm]",
|
||||
"Halt your system. If APM is available on it, turn off the power using"
|
||||
" the APM BIOS, unless you specify the option `--no-apm'."},
|
||||
/* FIXME: help unsupported. */ /* NUL_TERMINATE */
|
||||
{"hiddenmenu", NULL,
|
||||
"if sleep -i $timeout; then timeout=0; else timeout=-1; fi\n", 0,
|
||||
0, {}, 0, "", "Hide the menu."},
|
||||
{"hide", "parttool '%s' hidden+\n", NULL, 0, 1, {TYPE_PARTITION},
|
||||
0, "PARTITION",
|
||||
"Hide PARTITION by setting the \"hidden\" bit in"
|
||||
" its partition type code."},
|
||||
/* FIXME: ifconfig unsupported. */
|
||||
/* FIXME: impsprobe unsupported. */
|
||||
{"initrd", "legacy_initrd '%s' %s\n", NULL, 0, 2, {TYPE_FILE_NO_CONSUME,
|
||||
TYPE_REST_VERBATIM}, 0,
|
||||
"FILE [ARG ...]",
|
||||
"Load an initial ramdisk FILE for a Linux format boot image and set the"
|
||||
" appropriate parameters in the Linux setup area in memory."},
|
||||
/* NOTE: install unsupported. */
|
||||
/* FIXME: ioprobe unsupported. */
|
||||
/* FIXME: really support --no-mem-option. */
|
||||
{"kernel", "legacy_kernel %s %s '%s' %s\n", NULL, 0,
|
||||
4, {TYPE_TYPE_OR_NOMEM_OPTION, TYPE_TYPE_OR_NOMEM_OPTION,
|
||||
TYPE_FILE_NO_CONSUME, TYPE_REST_VERBATIM}, 0,
|
||||
"[--no-mem-option] [--type=TYPE] FILE [ARG ...]",
|
||||
"Attempt to load the primary boot image from FILE. The rest of the"
|
||||
" line is passed verbatim as the \"kernel command line\". Any modules"
|
||||
" must be reloaded after using this command. The option --type is used"
|
||||
" to suggest what type of kernel to be loaded. TYPE must be either of"
|
||||
" \"netbsd\", \"freebsd\", \"openbsd\", \"linux\", \"biglinux\" and"
|
||||
" \"multiboot\". The option --no-mem-option tells GRUB not to pass a"
|
||||
" Linux's mem option automatically."},
|
||||
{"lock", "if ! authenticate legacy; then return; fi", NULL, 0, 0, {}, 0,
|
||||
0, "Break a command execution unless the user is authenticated."},
|
||||
{"makeactive", "parttool \"$root\" boot+\n", NULL, 0, 0, {}, 0, 0,
|
||||
"Set the active partition on the root disk to GRUB's root device."
|
||||
" This command is limited to _primary_ PC partitions on a hard disk."},
|
||||
{"map", "drivemap '%s' '%s'\n", NULL, 0,
|
||||
2, {TYPE_PARTITION, TYPE_PARTITION},
|
||||
FLAG_IGNORE_REST, "TO_DRIVE FROM_DRIVE",
|
||||
"Map the drive FROM_DRIVE to the drive TO_DRIVE. This is necessary"
|
||||
" when you chain-load some operating systems, such as DOS, if such an"
|
||||
" OS resides at a non-first drive."},
|
||||
/* NOTE: md5crypt unsupported since GRUB has not enough entropy and this
|
||||
hash shouldn't be used anymore. */
|
||||
{"module", "legacy_initrd '%s' %s\n", NULL, 0, 2, {TYPE_FILE_NO_CONSUME,
|
||||
TYPE_REST_VERBATIM}, 0,
|
||||
"FILE [ARG ...]",
|
||||
"Load a boot module FILE for a Multiboot format boot image (no"
|
||||
" interpretation of the file contents is made, so users of this"
|
||||
" command must know what the kernel in question expects). The"
|
||||
" rest of the line is passed as the \"module command line\", like"
|
||||
" the `kernel' command."},
|
||||
{"modulenounzip", "legacy_initrd_nounzip '%s' %s\n", NULL, 0, 2,
|
||||
{TYPE_FILE_NO_CONSUME, TYPE_REST_VERBATIM}, 0,
|
||||
"FILE [ARG ...]",
|
||||
"The same as `module', except that automatic decompression is"
|
||||
" disabled."},
|
||||
{"pager", "set pager=%s; if [ \"$pager\" = 0 ]; then "
|
||||
" echo Internal pager is now off; else "
|
||||
"echo Internal pager is now on; fi\n", NULL, 0,
|
||||
1, {TYPE_BOOL}, FLAG_FALLBACK_AVAILABLE, "[FLAG]",
|
||||
"Toggle pager mode with no argument. If FLAG is given and its value"
|
||||
" is `on', turn on the mode. If FLAG is `off', turn off the mode."},
|
||||
{"pager",
|
||||
"if [ \"$pager\" = 1 ]; then pager=0; echo Internal pager is now off;"
|
||||
"else pager=1; echo Internal pager is now on; fi\n", NULL, 0, 0, {},
|
||||
FLAG_FALLBACK, NULL, NULL},
|
||||
/* FIXME: partnew unsupported. */
|
||||
{"parttype", "parttool '%s' type=%s\n", NULL, 0,
|
||||
2, {TYPE_PARTITION, TYPE_INT}, 0,
|
||||
"PART TYPE", "Change the type of the partition PART to TYPE."},
|
||||
{"password", "if [ \"$superusers\" = "" ]; then superusers=legacy; fi;\n"
|
||||
"legacy_password %s '%s'\n",
|
||||
"menuentry \"Superuser menu\" --users \"legacy\" { configfile '%s'; }\n",
|
||||
2, 3, {TYPE_OPTION, TYPE_VERBATIM, TYPE_FILE},
|
||||
FLAG_IGNORE_REST | FLAG_FALLBACK_AVAILABLE | FLAG_NO_MENUENTRY,
|
||||
"[--md5] PASSWD [FILE]",
|
||||
"If used in the first section of a menu file, disable all"
|
||||
" interactive editing control (menu entry editor and"
|
||||
" command line). If the password PASSWD is entered, it loads the"
|
||||
" FILE as a new config file and restarts the GRUB Stage 2. If you"
|
||||
" omit the argument FILE, then GRUB just unlocks privileged"
|
||||
" instructions. You can also use it in the script section, in"
|
||||
" which case it will ask for the password, before continuing."
|
||||
" The option --md5 tells GRUB that PASSWD is encrypted with"
|
||||
" md5crypt."},
|
||||
{"password", "if [ \"$superusers\" = "" ]; then superusers=legacy; fi;\n"
|
||||
"legacy_password %s '%s'\n", NULL, 0, 2, {TYPE_OPTION, TYPE_VERBATIM},
|
||||
FLAG_IGNORE_REST | FLAG_FALLBACK | FLAG_NO_MENUENTRY, NULL, NULL},
|
||||
{"password", "if legacy_check_password %s '%s'; then configfile '%s'; "
|
||||
"else return; fi\n", NULL, 2, 3, {TYPE_OPTION, TYPE_VERBATIM, TYPE_FILE},
|
||||
FLAG_IGNORE_REST | FLAG_FALLBACK_AVAILABLE | FLAG_MENUENTRY_ONLY,
|
||||
NULL, NULL},
|
||||
{"password", "if ! legacy_check_password %s '%s'; then return fi;\n",
|
||||
NULL, 0, 2, {TYPE_OPTION, TYPE_VERBATIM},
|
||||
FLAG_IGNORE_REST | FLAG_FALLBACK | FLAG_MENUENTRY_ONLY, NULL, NULL},
|
||||
/* NOTE: GRUB2 has a design principle of not eternally waiting for user
|
||||
input. 60 seconds should be enough.
|
||||
*/
|
||||
{"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: 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"
|
||||
" display it in hex format."},
|
||||
{"reboot", "reboot\n", NULL, 0, 0, {}, 0, 0, "Reboot your system."},
|
||||
{"root", "set root='%s'; set legacy_hdbias='%s'\n", NULL, 0,
|
||||
2, {TYPE_PARTITION, TYPE_INT}, FLAG_FALLBACK_AVAILABLE,
|
||||
"[DEVICE [HDBIAS]]",
|
||||
"Set the current \"root device\" to the device DEVICE, then"
|
||||
" attempt to mount it to get the partition size (for passing the"
|
||||
" partition descriptor in `ES:ESI', used by some chain-loaded"
|
||||
" bootloaders), the BSD drive-type (for booting BSD kernels using"
|
||||
" their native boot format), and correctly determine "
|
||||
" the PC partition where a BSD sub-partition is located. The"
|
||||
" optional HDBIAS parameter is a number to tell a BSD kernel"
|
||||
" how many BIOS drive numbers are on controllers before the current"
|
||||
" one. For example, if there is an IDE disk and a SCSI disk, and your"
|
||||
" FreeBSD root partition is on the SCSI disk, then use a `1' for HDBIAS."},
|
||||
{"root", "echo \"$root\"\n", NULL, 0, 0, {}, FLAG_FALLBACK, NULL, NULL},
|
||||
{"rootnoverify", "set root='%s'; set legacy_hdbias='%s'\n", NULL, 0,
|
||||
2, {TYPE_PARTITION, TYPE_INT}, 0,
|
||||
"[DEVICE [HDBIAS]]",
|
||||
"Similar to `root', but don't attempt to mount the partition. This"
|
||||
" is useful for when an OS is outside of the area of the disk that"
|
||||
" GRUB can read, but setting the correct root device is still"
|
||||
" desired. Note that the items mentioned in `root' which"
|
||||
" derived from attempting the mount will NOT work correctly."},
|
||||
{"rootnoverify", "echo \"$root\"\n", NULL, 0,
|
||||
0, {}, FLAG_FALLBACK, NULL, NULL},
|
||||
/* FIXME: support saving NUM and fallback. */
|
||||
{"savedefault", "saved_entry=${chosen}; save_env saved_entry\n", NULL, 0,
|
||||
0, {}, 0, "[NUM | `fallback']",
|
||||
"Save the current entry as the default boot entry if no argument is"
|
||||
" specified. If a number is specified, this number is saved. If"
|
||||
" `fallback' is used, next fallback entry is saved."},
|
||||
{"serial", "serial %s\n", NULL, 0, 1, {TYPE_REST_VERBATIM}, 0,
|
||||
"[--unit=UNIT] [--port=PORT] [--speed=SPEED] [--word=WORD] "
|
||||
"[--parity=PARITY] [--stop=STOP] [--device=DEV]",
|
||||
"Initialize a serial device. UNIT is a digit that specifies which serial"
|
||||
" device is used (e.g. 0 == COM1). If you need to specify the port number,"
|
||||
" set it by --port. SPEED is the DTE-DTE speed. WORD is the word length,"
|
||||
" PARITY is the type of parity, which is one of `no', `odd' and `even'."
|
||||
" 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: setkey unsupported. */ /* NUL_TERMINATE */
|
||||
/* NOTE: setup unsupported. */
|
||||
/* FIXME: --no-echo, --no-edit, hercules unsupported. */
|
||||
/* NOTE: both terminals are activated so --silent and --timeout
|
||||
are useless. */
|
||||
{"terminal", NULL, NULL, 0, 0, {}, FLAG_TERMINAL | FLAG_IGNORE_REST,
|
||||
"[--dumb] [--no-echo] [--no-edit] [--timeout=SECS] [--lines=LINES] "
|
||||
"[--silent] [console] [serial] [hercules]",
|
||||
"Select a terminal. When multiple terminals are specified, wait until"
|
||||
" you push any key to continue. If both console and serial are specified,"
|
||||
" the terminal to which you input a key first will be selected. If no"
|
||||
" argument is specified, print current setting. The option --dumb"
|
||||
" specifies that your terminal is dumb, otherwise, vt100-compatibility"
|
||||
" is assumed. If you specify --no-echo, input characters won't be echoed."
|
||||
" If you specify --no-edit, the BASH-like editing feature will be disabled."
|
||||
" If --timeout is present, this command will wait at most for SECS"
|
||||
" 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",
|
||||
"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"
|
||||
" step is to try loading a kernel."},
|
||||
{"testvbe", "insmod vbe; videotest '%s'\n", NULL, 0, 1, {TYPE_VBE_MODE}, 0,
|
||||
"MODE", "Test the VBE mode MODE. Hit any key to return."},
|
||||
/* FIXME: tftpserver unsupported. */
|
||||
{"timeout", "set timeout=%s\n", NULL, 0, 1, {TYPE_INT}, 0, "SEC",
|
||||
"Set a timeout, in SEC seconds, before automatically booting the"
|
||||
" default entry (normally the first entry defined)."},
|
||||
{"title", NULL, NULL, 0, 0, {}, FLAG_TITLE, "NAME ...",
|
||||
"Start a new boot entry, and set its name to the contents of the"
|
||||
" rest of the line, starting with the first non-space character."},
|
||||
{"unhide", "parttool '%s' hidden-\n", NULL, 0,
|
||||
1, {TYPE_PARTITION}, 0, "PARTITION",
|
||||
"Unhide PARTITION by clearing the \"hidden\" bit in its"
|
||||
" partition type code."},
|
||||
/* FIXME: uppermem unsupported. */
|
||||
{"uuid", "search --set=root --fs-uuid '%s'\n", NULL, 0, 1, {TYPE_VERBATIM},
|
||||
0, "UUID", "Find root by UUID"},
|
||||
{"vbeprobe", "insmod vbe; videoinfo '%s'\n", NULL, 0, 1, {TYPE_VBE_MODE},
|
||||
FLAG_FALLBACK_AVAILABLE, "[MODE]",
|
||||
"Probe VBE information. If the mode number MODE is specified, show only"
|
||||
" the information about only the mode."},
|
||||
{"vbeprobe", "insmod vbe; videoinfo\n", NULL, 0, 0, {},
|
||||
FLAG_FALLBACK, NULL, NULL}
|
||||
};
|
||||
|
||||
char *
|
||||
grub_legacy_escape (const char *in, grub_size_t len)
|
||||
{
|
||||
char *ptr;
|
||||
char *ret;
|
||||
char saved;
|
||||
int overhead = 0;
|
||||
|
||||
for (ptr = (char*)in; ptr < in + len && *ptr; ptr++)
|
||||
if (*ptr == '\'')
|
||||
overhead += 3;
|
||||
ret = grub_malloc (ptr - in + overhead + 1);
|
||||
if (!ret)
|
||||
return NULL;
|
||||
|
||||
ptr = (char*)in;
|
||||
saved = ptr[len];
|
||||
ptr[len] = '\0';
|
||||
grub_strchrsub (ret, ptr, '\'', "'\\''");
|
||||
ptr[len] = saved;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static char *
|
||||
adjust_file (const char *in, grub_size_t len)
|
||||
{
|
||||
const char *comma, *ptr, *rest;
|
||||
char *ret, *outptr;
|
||||
int overhead = 0;
|
||||
int part = -1, subpart = -1;
|
||||
if (in[0] != '(')
|
||||
return grub_legacy_escape (in, len);
|
||||
for (ptr = in + 1; ptr < in + len && *ptr && *ptr != ')'
|
||||
&& *ptr != ','; ptr++)
|
||||
if (*ptr == '\'' || *ptr == '\\')
|
||||
overhead++;
|
||||
comma = ptr;
|
||||
if (*comma != ',')
|
||||
return grub_legacy_escape (in, len);
|
||||
part = grub_strtoull (comma + 1, (char **) &rest, 0);
|
||||
if (rest[0] == ',' && rest[1] >= 'a' && rest[1] <= 'z')
|
||||
{
|
||||
subpart = rest[1] - 'a';
|
||||
rest += 2;
|
||||
}
|
||||
for (ptr = rest; ptr < in + len && *ptr; ptr++)
|
||||
if (*ptr == '\'' || *ptr == '\\')
|
||||
overhead++;
|
||||
|
||||
/* 35 is enough for any 2 numbers. */
|
||||
ret = grub_malloc (ptr - in + overhead + 35);
|
||||
if (!ret)
|
||||
return NULL;
|
||||
|
||||
outptr = ret;
|
||||
for (ptr = in; ptr < in + len && ptr <= comma; ptr++)
|
||||
{
|
||||
if (*ptr == '\'' || *ptr == '\\')
|
||||
*outptr++ = '\\';
|
||||
|
||||
*outptr++ = *ptr;
|
||||
}
|
||||
if (subpart != -1)
|
||||
grub_snprintf (outptr, 35, "%d,%d", part + 1, subpart + 1);
|
||||
else
|
||||
grub_snprintf (outptr, 35, "%d", part + 1);
|
||||
while (*outptr)
|
||||
outptr++;
|
||||
for (ptr = rest; ptr < in + len; ptr++)
|
||||
{
|
||||
if (*ptr == '\'' || *ptr == '\\')
|
||||
*outptr++ = '\\';
|
||||
|
||||
*outptr++ = *ptr;
|
||||
}
|
||||
*outptr = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
check_option (const char *a, char *b, grub_size_t len)
|
||||
{
|
||||
if (grub_strlen (b) != len)
|
||||
return 0;
|
||||
return grub_strncmp (a, b, len) == 0;
|
||||
}
|
||||
|
||||
static int
|
||||
is_option (enum arg_type opt, const char *curarg, grub_size_t len)
|
||||
{
|
||||
switch (opt)
|
||||
{
|
||||
case TYPE_NOAPM_OPTION:
|
||||
return check_option (curarg, "--no-apm", len);
|
||||
case TYPE_FORCE_OPTION:
|
||||
return check_option (curarg, "--force", len);
|
||||
case TYPE_TYPE_OR_NOMEM_OPTION:
|
||||
return check_option (curarg, "--type=netbsd", len)
|
||||
|| check_option (curarg, "--type=freebsd", len)
|
||||
|| check_option (curarg, "--type=openbsd", len)
|
||||
|| check_option (curarg, "--type=linux", len)
|
||||
|| check_option (curarg, "--type=biglinux", len)
|
||||
|| check_option (curarg, "--type=multiboot", len)
|
||||
|| check_option (curarg, "--no-mem-option", len);
|
||||
case TYPE_OPTION:
|
||||
return (len >= 2 && curarg[0] == '-' && curarg[1] == '-');
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
char *
|
||||
grub_legacy_parse (const char *buf, char **entryname, char **suffix)
|
||||
{
|
||||
const char *ptr;
|
||||
const char *cmdname;
|
||||
unsigned i, cmdnum;
|
||||
char *args[ARRAY_SIZE (legacy_commands[0].argt)];
|
||||
|
||||
*suffix = NULL;
|
||||
|
||||
for (ptr = buf; *ptr && grub_isspace (*ptr); ptr++);
|
||||
if (!*ptr || *ptr == '#')
|
||||
{
|
||||
char *ret;
|
||||
int len = grub_strlen (buf);
|
||||
ret = grub_malloc (len + 2);
|
||||
grub_memcpy (ret, buf, len);
|
||||
if (len && ret[len - 1] == '\n')
|
||||
ret[len] = 0;
|
||||
else
|
||||
{
|
||||
ret[len] = '\n';
|
||||
ret[len + 1] = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
cmdname = ptr;
|
||||
for (ptr = buf; *ptr && !grub_isspace (*ptr) && *ptr != '='; ptr++);
|
||||
|
||||
for (cmdnum = 0; cmdnum < ARRAY_SIZE (legacy_commands); cmdnum++)
|
||||
if (grub_strncmp (legacy_commands[cmdnum].name, cmdname, ptr - cmdname) == 0
|
||||
&& legacy_commands[cmdnum].name[ptr - cmdname] == 0
|
||||
&& (!(*entryname != NULL && (legacy_commands[cmdnum].flags
|
||||
& FLAG_NO_MENUENTRY)))
|
||||
&& (!(*entryname == NULL && (legacy_commands[cmdnum].flags
|
||||
& FLAG_MENUENTRY_ONLY))))
|
||||
break;
|
||||
if (cmdnum == ARRAY_SIZE (legacy_commands))
|
||||
return grub_xasprintf ("# Unsupported legacy command: %s\n", buf);
|
||||
|
||||
for (; grub_isspace (*ptr) || *ptr == '='; ptr++);
|
||||
|
||||
if (legacy_commands[cmdnum].flags & FLAG_TITLE)
|
||||
{
|
||||
const char *ptr2;
|
||||
ptr2 = ptr + grub_strlen (ptr);
|
||||
while (ptr2 > ptr && grub_isspace (*(ptr2 - 1)))
|
||||
ptr2--;
|
||||
*entryname = grub_strndup (ptr, ptr2 - ptr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (legacy_commands[cmdnum].flags & FLAG_TERMINAL)
|
||||
{
|
||||
int dumb = 0, lines = 24;
|
||||
#ifdef TODO
|
||||
int no_echo = 0, no_edit = 0;
|
||||
int hercules = 0;
|
||||
#endif
|
||||
int console = 0, serial = 0;
|
||||
/* Big enough for any possible resulting command. */
|
||||
char outbuf[256] = "";
|
||||
char *outptr;
|
||||
while (*ptr)
|
||||
{
|
||||
/* "[--timeout=SECS] [--silent]"
|
||||
" [console] [serial] [hercules]"*/
|
||||
if (grub_memcmp (ptr, "--dumb", sizeof ("--dumb") - 1) == 0)
|
||||
dumb = 1;
|
||||
#ifdef TODO
|
||||
if (grub_memcmp (ptr, "--no-echo", sizeof ("--no-echo") - 1) == 0)
|
||||
no_echo = 1;
|
||||
|
||||
if (grub_memcmp (ptr, "--no-edit", sizeof ("--no-edit") - 1) == 0)
|
||||
no_edit = 1;
|
||||
#endif
|
||||
if (grub_memcmp (ptr, "--lines=", sizeof ("--lines=") - 1) == 0)
|
||||
{
|
||||
lines = grub_strtoul (ptr + sizeof ("--lines=") - 1, 0, 0);
|
||||
if (grub_errno)
|
||||
{
|
||||
lines = 24;
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
if (grub_memcmp (ptr, "console", sizeof ("console") - 1) == 0)
|
||||
console = 1;
|
||||
|
||||
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))
|
||||
ptr++;
|
||||
}
|
||||
|
||||
if (!console && !serial)
|
||||
return grub_strdup ("terminal_input; terminal_output; terminfo\n");
|
||||
|
||||
grub_strcpy (outbuf, "terminal_input ");
|
||||
outptr = outbuf + grub_strlen (outbuf);
|
||||
if (serial)
|
||||
{
|
||||
grub_strcpy (outptr, "serial ");
|
||||
outptr += grub_strlen (outptr);
|
||||
}
|
||||
if (console)
|
||||
{
|
||||
grub_strcpy (outptr, "console ");
|
||||
outptr += grub_strlen (outptr);
|
||||
}
|
||||
grub_strcpy (outptr, "; terminal_output ");
|
||||
outptr += grub_strlen (outptr);
|
||||
if (serial)
|
||||
{
|
||||
grub_strcpy (outptr, "serial ");
|
||||
outptr += grub_strlen (outptr);
|
||||
}
|
||||
if (console)
|
||||
{
|
||||
grub_strcpy (outptr, "console ");
|
||||
outptr += grub_strlen (outptr);
|
||||
}
|
||||
grub_strcpy (outptr, "; ");
|
||||
outptr += grub_strlen (outptr);
|
||||
if (serial)
|
||||
{
|
||||
grub_snprintf (outptr, outbuf + sizeof (outbuf) - outptr,
|
||||
"terminfo serial -g 80x%d %s; ",
|
||||
lines, dumb ? "dumb" : "vt100");
|
||||
outptr += grub_strlen (outptr);
|
||||
}
|
||||
|
||||
grub_strcpy (outptr, "\n");
|
||||
|
||||
return grub_strdup (outbuf);
|
||||
}
|
||||
|
||||
grub_memset (args, 0, sizeof (args));
|
||||
|
||||
{
|
||||
int hold_arg = 0;
|
||||
const char *curarg = NULL;
|
||||
for (i = 0; i < legacy_commands[cmdnum].argc; i++)
|
||||
{
|
||||
grub_size_t curarglen;
|
||||
if (hold_arg)
|
||||
{
|
||||
ptr = curarg;
|
||||
hold_arg = 0;
|
||||
}
|
||||
for (; grub_isspace (*ptr); ptr++);
|
||||
curarg = ptr;
|
||||
if (!*curarg)
|
||||
break;
|
||||
for (; *ptr && !grub_isspace (*ptr); ptr++);
|
||||
if (i != legacy_commands[cmdnum].argc - 1
|
||||
|| (legacy_commands[cmdnum].flags & FLAG_IGNORE_REST))
|
||||
curarglen = ptr - curarg;
|
||||
else
|
||||
{
|
||||
curarglen = grub_strlen (curarg);
|
||||
while (curarglen > 0 && grub_isspace (curarg[curarglen - 1]))
|
||||
curarglen--;
|
||||
}
|
||||
if (*ptr)
|
||||
ptr++;
|
||||
switch (legacy_commands[cmdnum].argt[i])
|
||||
{
|
||||
case TYPE_FILE_NO_CONSUME:
|
||||
hold_arg = 1;
|
||||
case TYPE_PARTITION:
|
||||
case TYPE_FILE:
|
||||
args[i] = adjust_file (curarg, curarglen);
|
||||
break;
|
||||
|
||||
case TYPE_REST_VERBATIM:
|
||||
{
|
||||
char *outptr, *outptr0;
|
||||
int overhead = 3;
|
||||
ptr = curarg;
|
||||
while (*ptr)
|
||||
{
|
||||
for (; *ptr && grub_isspace (*ptr); ptr++);
|
||||
for (; *ptr && !grub_isspace (*ptr); ptr++)
|
||||
if (*ptr == '\'')
|
||||
overhead += 3;
|
||||
if (*ptr)
|
||||
ptr++;
|
||||
overhead += 3;
|
||||
}
|
||||
|
||||
outptr0 = args[i] = grub_malloc (overhead + (ptr - curarg));
|
||||
if (!outptr0)
|
||||
return NULL;
|
||||
ptr = curarg;
|
||||
outptr = outptr0;
|
||||
while (*ptr)
|
||||
{
|
||||
for (; *ptr && grub_isspace (*ptr); ptr++);
|
||||
if (outptr != outptr0)
|
||||
*outptr++ = ' ';
|
||||
*outptr++ = '\'';
|
||||
for (; *ptr && !grub_isspace (*ptr); ptr++)
|
||||
{
|
||||
if (*ptr == '\'')
|
||||
{
|
||||
*outptr++ = '\'';
|
||||
*outptr++ = '\\';
|
||||
*outptr++ = '\'';
|
||||
*outptr++ = '\'';
|
||||
}
|
||||
else
|
||||
*outptr++ = *ptr;
|
||||
}
|
||||
*outptr++ = '\'';
|
||||
if (*ptr)
|
||||
ptr++;
|
||||
}
|
||||
*outptr++ = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case TYPE_VERBATIM:
|
||||
args[i] = grub_legacy_escape (curarg, curarglen);
|
||||
break;
|
||||
case TYPE_FORCE_OPTION:
|
||||
case TYPE_NOAPM_OPTION:
|
||||
case TYPE_TYPE_OR_NOMEM_OPTION:
|
||||
case TYPE_OPTION:
|
||||
if (is_option (legacy_commands[cmdnum].argt[i], curarg, curarglen))
|
||||
{
|
||||
args[i] = grub_strndup (curarg, curarglen);
|
||||
break;
|
||||
}
|
||||
args[i] = grub_strdup ("");
|
||||
hold_arg = 1;
|
||||
break;
|
||||
case TYPE_INT:
|
||||
{
|
||||
const char *brk;
|
||||
int base = 10;
|
||||
brk = curarg;
|
||||
if (brk[0] == '0' && brk[1] == 'x')
|
||||
{
|
||||
base = 16;
|
||||
brk += 2;
|
||||
}
|
||||
else if (brk[0] == '0')
|
||||
base = 8;
|
||||
for (; *brk && brk < curarg + curarglen; brk++)
|
||||
{
|
||||
if (base == 8 && (*brk == '8' || *brk == '9'))
|
||||
break;
|
||||
if (grub_isdigit (*brk))
|
||||
continue;
|
||||
if (base != 16)
|
||||
break;
|
||||
if (!(*brk >= 'a' && *brk <= 'f')
|
||||
&& !(*brk >= 'A' && *brk <= 'F'))
|
||||
break;
|
||||
}
|
||||
if (brk == curarg)
|
||||
args[i] = grub_strdup ("0");
|
||||
else
|
||||
args[i] = grub_strndup (curarg, brk - curarg);
|
||||
}
|
||||
break;
|
||||
case TYPE_VBE_MODE:
|
||||
{
|
||||
unsigned mod;
|
||||
struct grub_vesa_mode_table_entry *modedesc;
|
||||
|
||||
mod = grub_strtoul (curarg, 0, 0);
|
||||
if (grub_errno)
|
||||
{
|
||||
mod = 0;
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
}
|
||||
if (mod < GRUB_VESA_MODE_TABLE_START
|
||||
|| mod > GRUB_VESA_MODE_TABLE_END)
|
||||
{
|
||||
args[i] = grub_strdup ("auto");
|
||||
break;
|
||||
}
|
||||
modedesc = &grub_vesa_mode_table[mod - GRUB_VESA_MODE_TABLE_START];
|
||||
if (!modedesc->width)
|
||||
{
|
||||
args[i] = grub_strdup ("auto");
|
||||
break;
|
||||
}
|
||||
args[i] = grub_xasprintf ("%ux%ux%u",
|
||||
modedesc->width, modedesc->height,
|
||||
modedesc->depth);
|
||||
break;
|
||||
}
|
||||
case TYPE_BOOL:
|
||||
if (curarglen == 2 && curarg[0] == 'o' && curarg[1] == 'n')
|
||||
args[i] = grub_strdup ("1");
|
||||
else
|
||||
args[i] = grub_strdup ("0");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (legacy_commands[cmdnum].argc > 0
|
||||
&& args[legacy_commands[cmdnum].argc - 1] == NULL
|
||||
&& (legacy_commands[cmdnum].flags & FLAG_FALLBACK_AVAILABLE)
|
||||
&& args[legacy_commands[cmdnum + 1].argc] == NULL)
|
||||
cmdnum++;
|
||||
|
||||
for (; i < legacy_commands[cmdnum].argc; i++)
|
||||
switch (legacy_commands[cmdnum].argt[i])
|
||||
{
|
||||
case TYPE_FILE_NO_CONSUME:
|
||||
case TYPE_PARTITION:
|
||||
case TYPE_FILE:
|
||||
case TYPE_REST_VERBATIM:
|
||||
case TYPE_VERBATIM:
|
||||
case TYPE_FORCE_OPTION:
|
||||
case TYPE_NOAPM_OPTION:
|
||||
case TYPE_TYPE_OR_NOMEM_OPTION:
|
||||
case TYPE_OPTION:
|
||||
args[i] = grub_strdup ("");
|
||||
break;
|
||||
case TYPE_BOOL:
|
||||
case TYPE_INT:
|
||||
args[i] = grub_strdup ("0");
|
||||
break;
|
||||
case TYPE_VBE_MODE:
|
||||
args[i] = grub_strdup ("auto");
|
||||
break;
|
||||
}
|
||||
|
||||
if (legacy_commands[cmdnum].flags & FLAG_COLOR_INVERT)
|
||||
{
|
||||
char *corig = args[legacy_commands[cmdnum].argc - 1];
|
||||
char *slash = grub_strchr (corig, '/');
|
||||
char *invert;
|
||||
grub_size_t len;
|
||||
|
||||
len = grub_strlen (corig);
|
||||
if (!slash)
|
||||
{
|
||||
grub_error (GRUB_ERR_BAD_ARGUMENT, "bad color specification %s",
|
||||
args[0]);
|
||||
return NULL;
|
||||
}
|
||||
invert = grub_malloc (len + 1);
|
||||
if (!invert)
|
||||
return NULL;
|
||||
grub_memcpy (invert, slash + 1, len - (slash - corig) - 1);
|
||||
invert[len - (slash - args[0]) - 1] = '/';
|
||||
grub_memcpy (invert + len - (slash - corig), corig, slash - corig);
|
||||
invert[len] = 0;
|
||||
args[legacy_commands[cmdnum].argc] = invert;
|
||||
}
|
||||
|
||||
if (legacy_commands[cmdnum].suffix)
|
||||
{
|
||||
*suffix = grub_xasprintf (legacy_commands[cmdnum].suffix,
|
||||
args[legacy_commands[cmdnum].suffixarg]);
|
||||
if (*suffix)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
{
|
||||
char *ret = grub_xasprintf (legacy_commands[cmdnum].map, args[0], args[1],
|
||||
args[2], args[3]);
|
||||
grub_free (args[0]);
|
||||
grub_free (args[1]);
|
||||
grub_free (args[2]);
|
||||
grub_free (args[3]);
|
||||
return ret;
|
||||
}
|
||||
}
|
|
@ -25,6 +25,12 @@
|
|||
#include <grub/dl.h>
|
||||
#include <grub/crypto.h>
|
||||
|
||||
#ifdef GRUB_CPU_WORDS_BIGENDIAN
|
||||
#define WORDS_BIGENDIAN
|
||||
#else
|
||||
#undef WORDS_BIGENDIAN
|
||||
#endif
|
||||
|
||||
#define __GNU_LIBRARY__
|
||||
|
||||
#define DIM ARRAY_SIZE
|
||||
|
@ -81,6 +87,25 @@ fips_mode (void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#define memset grub_memset
|
||||
#ifdef GRUB_UTIL
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
|
446
grub-core/lib/minilzo/lzoconf.h
Normal file
446
grub-core/lib/minilzo/lzoconf.h
Normal file
|
@ -0,0 +1,446 @@
|
|||
/* lzoconf.h -- configuration of the LZO data compression library
|
||||
|
||||
This file is part of the LZO real-time data compression library.
|
||||
|
||||
Copyright (C) 2011 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 2010 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 2009 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 2008 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 2005 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 2004 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 2003 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer
|
||||
All Rights Reserved.
|
||||
|
||||
The LZO 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 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
The LZO 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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the LZO library; see the file COPYING.
|
||||
If not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer
|
||||
<markus@oberhumer.com>
|
||||
http://www.oberhumer.com/opensource/lzo/
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __LZOCONF_H_INCLUDED
|
||||
#define __LZOCONF_H_INCLUDED 1
|
||||
|
||||
#define LZO_VERSION 0x2050
|
||||
#define LZO_VERSION_STRING "2.05"
|
||||
#define LZO_VERSION_DATE "Apr 23 2011"
|
||||
|
||||
/* internal Autoconf configuration file - only used when building LZO */
|
||||
#if defined(LZO_HAVE_CONFIG_H)
|
||||
# include <config.h>
|
||||
#endif
|
||||
#include <limits.h>
|
||||
#include <stddef.h>
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
// LZO requires a conforming <limits.h>
|
||||
************************************************************************/
|
||||
|
||||
#if !defined(CHAR_BIT) || (CHAR_BIT != 8)
|
||||
# error "invalid CHAR_BIT"
|
||||
#endif
|
||||
#if !defined(UCHAR_MAX) || !defined(UINT_MAX) || !defined(ULONG_MAX)
|
||||
# error "check your compiler installation"
|
||||
#endif
|
||||
#if (USHRT_MAX < 1) || (UINT_MAX < 1) || (ULONG_MAX < 1)
|
||||
# error "your limits.h macros are broken"
|
||||
#endif
|
||||
|
||||
/* get OS and architecture defines */
|
||||
#ifndef __LZODEFS_H_INCLUDED
|
||||
#include "lzodefs.h"
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
// some core defines
|
||||
************************************************************************/
|
||||
|
||||
#if !defined(LZO_UINT32_C)
|
||||
# if (UINT_MAX < LZO_0xffffffffL)
|
||||
# define LZO_UINT32_C(c) c ## UL
|
||||
# else
|
||||
# define LZO_UINT32_C(c) ((c) + 0U)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* memory checkers */
|
||||
#if !defined(__LZO_CHECKER)
|
||||
# if defined(__BOUNDS_CHECKING_ON)
|
||||
# define __LZO_CHECKER 1
|
||||
# elif defined(__CHECKER__)
|
||||
# define __LZO_CHECKER 1
|
||||
# elif defined(__INSURE__)
|
||||
# define __LZO_CHECKER 1
|
||||
# elif defined(__PURIFY__)
|
||||
# define __LZO_CHECKER 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
// integral and pointer types
|
||||
************************************************************************/
|
||||
|
||||
/* lzo_uint should match size_t */
|
||||
#if !defined(LZO_UINT_MAX)
|
||||
# if defined(LZO_ABI_LLP64) /* WIN64 */
|
||||
# if defined(LZO_OS_WIN64)
|
||||
typedef unsigned __int64 lzo_uint;
|
||||
typedef __int64 lzo_int;
|
||||
# else
|
||||
typedef unsigned long long lzo_uint;
|
||||
typedef long long lzo_int;
|
||||
# endif
|
||||
# define LZO_UINT_MAX 0xffffffffffffffffull
|
||||
# define LZO_INT_MAX 9223372036854775807LL
|
||||
# define LZO_INT_MIN (-1LL - LZO_INT_MAX)
|
||||
# elif defined(LZO_ABI_IP32L64) /* MIPS R5900 */
|
||||
typedef unsigned int lzo_uint;
|
||||
typedef int lzo_int;
|
||||
# define LZO_UINT_MAX UINT_MAX
|
||||
# define LZO_INT_MAX INT_MAX
|
||||
# define LZO_INT_MIN INT_MIN
|
||||
# elif (ULONG_MAX >= LZO_0xffffffffL)
|
||||
typedef unsigned long lzo_uint;
|
||||
typedef long lzo_int;
|
||||
# define LZO_UINT_MAX ULONG_MAX
|
||||
# define LZO_INT_MAX LONG_MAX
|
||||
# define LZO_INT_MIN LONG_MIN
|
||||
# else
|
||||
# error "lzo_uint"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Integral types with 32 bits or more. */
|
||||
#if !defined(LZO_UINT32_MAX)
|
||||
# if (UINT_MAX >= LZO_0xffffffffL)
|
||||
typedef unsigned int lzo_uint32;
|
||||
typedef int lzo_int32;
|
||||
# define LZO_UINT32_MAX UINT_MAX
|
||||
# define LZO_INT32_MAX INT_MAX
|
||||
# define LZO_INT32_MIN INT_MIN
|
||||
# elif (ULONG_MAX >= LZO_0xffffffffL)
|
||||
typedef unsigned long lzo_uint32;
|
||||
typedef long lzo_int32;
|
||||
# define LZO_UINT32_MAX ULONG_MAX
|
||||
# define LZO_INT32_MAX LONG_MAX
|
||||
# define LZO_INT32_MIN LONG_MIN
|
||||
# else
|
||||
# error "lzo_uint32"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Integral types with exactly 64 bits. */
|
||||
#if !defined(LZO_UINT64_MAX)
|
||||
# if (LZO_UINT_MAX >= LZO_0xffffffffL)
|
||||
# if ((((LZO_UINT_MAX) >> 31) >> 31) == 3)
|
||||
# define lzo_uint64 lzo_uint
|
||||
# define lzo_int64 lzo_int
|
||||
# define LZO_UINT64_MAX LZO_UINT_MAX
|
||||
# define LZO_INT64_MAX LZO_INT_MAX
|
||||
# define LZO_INT64_MIN LZO_INT_MIN
|
||||
# endif
|
||||
# elif (ULONG_MAX >= LZO_0xffffffffL)
|
||||
# if ((((ULONG_MAX) >> 31) >> 31) == 3)
|
||||
typedef unsigned long lzo_uint64;
|
||||
typedef long lzo_int64;
|
||||
# define LZO_UINT64_MAX ULONG_MAX
|
||||
# define LZO_INT64_MAX LONG_MAX
|
||||
# define LZO_INT64_MIN LONG_MIN
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* The larger type of lzo_uint and lzo_uint32. */
|
||||
#if (LZO_UINT_MAX >= LZO_UINT32_MAX)
|
||||
# define lzo_xint lzo_uint
|
||||
#else
|
||||
# define lzo_xint lzo_uint32
|
||||
#endif
|
||||
|
||||
/* Memory model that allows to access memory at offsets of lzo_uint. */
|
||||
#if !defined(__LZO_MMODEL)
|
||||
# if (LZO_UINT_MAX <= UINT_MAX)
|
||||
# define __LZO_MMODEL /*empty*/
|
||||
# elif defined(LZO_HAVE_MM_HUGE_PTR)
|
||||
# define __LZO_MMODEL_HUGE 1
|
||||
# define __LZO_MMODEL __huge
|
||||
# else
|
||||
# define __LZO_MMODEL /*empty*/
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* no typedef here because of const-pointer issues */
|
||||
#define lzo_bytep unsigned char __LZO_MMODEL *
|
||||
#define lzo_charp char __LZO_MMODEL *
|
||||
#define lzo_voidp void __LZO_MMODEL *
|
||||
#define lzo_shortp short __LZO_MMODEL *
|
||||
#define lzo_ushortp unsigned short __LZO_MMODEL *
|
||||
#define lzo_uint32p lzo_uint32 __LZO_MMODEL *
|
||||
#define lzo_int32p lzo_int32 __LZO_MMODEL *
|
||||
#if defined(LZO_UINT64_MAX)
|
||||
#define lzo_uint64p lzo_uint64 __LZO_MMODEL *
|
||||
#define lzo_int64p lzo_int64 __LZO_MMODEL *
|
||||
#endif
|
||||
#define lzo_uintp lzo_uint __LZO_MMODEL *
|
||||
#define lzo_intp lzo_int __LZO_MMODEL *
|
||||
#define lzo_xintp lzo_xint __LZO_MMODEL *
|
||||
#define lzo_voidpp lzo_voidp __LZO_MMODEL *
|
||||
#define lzo_bytepp lzo_bytep __LZO_MMODEL *
|
||||
/* deprecated - use 'lzo_bytep' instead of 'lzo_byte *' */
|
||||
#define lzo_byte unsigned char __LZO_MMODEL
|
||||
|
||||
typedef int lzo_bool;
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
// function types
|
||||
************************************************************************/
|
||||
|
||||
/* name mangling */
|
||||
#if !defined(__LZO_EXTERN_C)
|
||||
# ifdef __cplusplus
|
||||
# define __LZO_EXTERN_C extern "C"
|
||||
# else
|
||||
# define __LZO_EXTERN_C extern
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* calling convention */
|
||||
#if !defined(__LZO_CDECL)
|
||||
# define __LZO_CDECL __lzo_cdecl
|
||||
#endif
|
||||
|
||||
/* DLL export information */
|
||||
#if !defined(__LZO_EXPORT1)
|
||||
# define __LZO_EXPORT1 /*empty*/
|
||||
#endif
|
||||
#if !defined(__LZO_EXPORT2)
|
||||
# define __LZO_EXPORT2 /*empty*/
|
||||
#endif
|
||||
|
||||
/* __cdecl calling convention for public C and assembly functions */
|
||||
#if !defined(LZO_PUBLIC)
|
||||
# define LZO_PUBLIC(_rettype) __LZO_EXPORT1 _rettype __LZO_EXPORT2 __LZO_CDECL
|
||||
#endif
|
||||
#if !defined(LZO_EXTERN)
|
||||
# define LZO_EXTERN(_rettype) __LZO_EXTERN_C LZO_PUBLIC(_rettype)
|
||||
#endif
|
||||
#if !defined(LZO_PRIVATE)
|
||||
# define LZO_PRIVATE(_rettype) static _rettype __LZO_CDECL
|
||||
#endif
|
||||
|
||||
/* function types */
|
||||
typedef int
|
||||
(__LZO_CDECL *lzo_compress_t) ( const lzo_bytep src, lzo_uint src_len,
|
||||
lzo_bytep dst, lzo_uintp dst_len,
|
||||
lzo_voidp wrkmem );
|
||||
|
||||
typedef int
|
||||
(__LZO_CDECL *lzo_decompress_t) ( const lzo_bytep src, lzo_uint src_len,
|
||||
lzo_bytep dst, lzo_uintp dst_len,
|
||||
lzo_voidp wrkmem );
|
||||
|
||||
typedef int
|
||||
(__LZO_CDECL *lzo_optimize_t) ( lzo_bytep src, lzo_uint src_len,
|
||||
lzo_bytep dst, lzo_uintp dst_len,
|
||||
lzo_voidp wrkmem );
|
||||
|
||||
typedef int
|
||||
(__LZO_CDECL *lzo_compress_dict_t)(const lzo_bytep src, lzo_uint src_len,
|
||||
lzo_bytep dst, lzo_uintp dst_len,
|
||||
lzo_voidp wrkmem,
|
||||
const lzo_bytep dict, lzo_uint dict_len );
|
||||
|
||||
typedef int
|
||||
(__LZO_CDECL *lzo_decompress_dict_t)(const lzo_bytep src, lzo_uint src_len,
|
||||
lzo_bytep dst, lzo_uintp dst_len,
|
||||
lzo_voidp wrkmem,
|
||||
const lzo_bytep dict, lzo_uint dict_len );
|
||||
|
||||
|
||||
/* Callback interface. Currently only the progress indicator ("nprogress")
|
||||
* is used, but this may change in a future release. */
|
||||
|
||||
struct lzo_callback_t;
|
||||
typedef struct lzo_callback_t lzo_callback_t;
|
||||
#define lzo_callback_p lzo_callback_t __LZO_MMODEL *
|
||||
|
||||
/* malloc & free function types */
|
||||
typedef lzo_voidp (__LZO_CDECL *lzo_alloc_func_t)
|
||||
(lzo_callback_p self, lzo_uint items, lzo_uint size);
|
||||
typedef void (__LZO_CDECL *lzo_free_func_t)
|
||||
(lzo_callback_p self, lzo_voidp ptr);
|
||||
|
||||
/* a progress indicator callback function */
|
||||
typedef void (__LZO_CDECL *lzo_progress_func_t)
|
||||
(lzo_callback_p, lzo_uint, lzo_uint, int);
|
||||
|
||||
struct lzo_callback_t
|
||||
{
|
||||
/* custom allocators (set to 0 to disable) */
|
||||
lzo_alloc_func_t nalloc; /* [not used right now] */
|
||||
lzo_free_func_t nfree; /* [not used right now] */
|
||||
|
||||
/* a progress indicator callback function (set to 0 to disable) */
|
||||
lzo_progress_func_t nprogress;
|
||||
|
||||
/* NOTE: the first parameter "self" of the nalloc/nfree/nprogress
|
||||
* callbacks points back to this struct, so you are free to store
|
||||
* some extra info in the following variables. */
|
||||
lzo_voidp user1;
|
||||
lzo_xint user2;
|
||||
lzo_xint user3;
|
||||
};
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
// error codes and prototypes
|
||||
************************************************************************/
|
||||
|
||||
/* Error codes for the compression/decompression functions. Negative
|
||||
* values are errors, positive values will be used for special but
|
||||
* normal events.
|
||||
*/
|
||||
#define LZO_E_OK 0
|
||||
#define LZO_E_ERROR (-1)
|
||||
#define LZO_E_OUT_OF_MEMORY (-2) /* [lzo_alloc_func_t failure] */
|
||||
#define LZO_E_NOT_COMPRESSIBLE (-3) /* [not used right now] */
|
||||
#define LZO_E_INPUT_OVERRUN (-4)
|
||||
#define LZO_E_OUTPUT_OVERRUN (-5)
|
||||
#define LZO_E_LOOKBEHIND_OVERRUN (-6)
|
||||
#define LZO_E_EOF_NOT_FOUND (-7)
|
||||
#define LZO_E_INPUT_NOT_CONSUMED (-8)
|
||||
#define LZO_E_NOT_YET_IMPLEMENTED (-9) /* [not used right now] */
|
||||
#define LZO_E_INVALID_ARGUMENT (-10)
|
||||
|
||||
|
||||
#ifndef lzo_sizeof_dict_t
|
||||
# define lzo_sizeof_dict_t ((unsigned)sizeof(lzo_bytep))
|
||||
#endif
|
||||
|
||||
/* lzo_init() should be the first function you call.
|
||||
* Check the return code !
|
||||
*
|
||||
* lzo_init() is a macro to allow checking that the library and the
|
||||
* compiler's view of various types are consistent.
|
||||
*/
|
||||
#define lzo_init() __lzo_init_v2(LZO_VERSION,(int)sizeof(short),(int)sizeof(int),\
|
||||
(int)sizeof(long),(int)sizeof(lzo_uint32),(int)sizeof(lzo_uint),\
|
||||
(int)lzo_sizeof_dict_t,(int)sizeof(char *),(int)sizeof(lzo_voidp),\
|
||||
(int)sizeof(lzo_callback_t))
|
||||
LZO_EXTERN(int) __lzo_init_v2(unsigned,int,int,int,int,int,int,int,int,int);
|
||||
|
||||
/* version functions (useful for shared libraries) */
|
||||
LZO_EXTERN(unsigned) lzo_version(void);
|
||||
LZO_EXTERN(const char *) lzo_version_string(void);
|
||||
LZO_EXTERN(const char *) lzo_version_date(void);
|
||||
LZO_EXTERN(const lzo_charp) _lzo_version_string(void);
|
||||
LZO_EXTERN(const lzo_charp) _lzo_version_date(void);
|
||||
|
||||
/* string functions */
|
||||
LZO_EXTERN(int)
|
||||
lzo_memcmp(const lzo_voidp a, const lzo_voidp b, lzo_uint len);
|
||||
LZO_EXTERN(lzo_voidp)
|
||||
lzo_memcpy(lzo_voidp dst, const lzo_voidp src, lzo_uint len);
|
||||
LZO_EXTERN(lzo_voidp)
|
||||
lzo_memmove(lzo_voidp dst, const lzo_voidp src, lzo_uint len);
|
||||
LZO_EXTERN(lzo_voidp)
|
||||
lzo_memset(lzo_voidp buf, int c, lzo_uint len);
|
||||
|
||||
/* checksum functions */
|
||||
LZO_EXTERN(lzo_uint32)
|
||||
lzo_adler32(lzo_uint32 c, const lzo_bytep buf, lzo_uint len);
|
||||
LZO_EXTERN(lzo_uint32)
|
||||
lzo_crc32(lzo_uint32 c, const lzo_bytep buf, lzo_uint len);
|
||||
LZO_EXTERN(const lzo_uint32p)
|
||||
lzo_get_crc32_table(void);
|
||||
|
||||
/* misc. */
|
||||
LZO_EXTERN(int) _lzo_config_check(void);
|
||||
typedef union { lzo_bytep p; lzo_uint u; } __lzo_pu_u;
|
||||
typedef union { lzo_bytep p; lzo_uint32 u32; } __lzo_pu32_u;
|
||||
typedef union { void *vp; lzo_bytep bp; lzo_uint u; lzo_uint32 u32; unsigned long l; } lzo_align_t;
|
||||
|
||||
/* align a char pointer on a boundary that is a multiple of 'size' */
|
||||
LZO_EXTERN(unsigned) __lzo_align_gap(const lzo_voidp p, lzo_uint size);
|
||||
#define LZO_PTR_ALIGN_UP(p,size) \
|
||||
((p) + (lzo_uint) __lzo_align_gap((const lzo_voidp)(p),(lzo_uint)(size)))
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
// deprecated macros - only for backward compatibility with LZO v1.xx
|
||||
************************************************************************/
|
||||
|
||||
#if defined(LZO_CFG_COMPAT)
|
||||
|
||||
#define __LZOCONF_H 1
|
||||
|
||||
#if defined(LZO_ARCH_I086)
|
||||
# define __LZO_i386 1
|
||||
#elif defined(LZO_ARCH_I386)
|
||||
# define __LZO_i386 1
|
||||
#endif
|
||||
|
||||
#if defined(LZO_OS_DOS16)
|
||||
# define __LZO_DOS 1
|
||||
# define __LZO_DOS16 1
|
||||
#elif defined(LZO_OS_DOS32)
|
||||
# define __LZO_DOS 1
|
||||
#elif defined(LZO_OS_WIN16)
|
||||
# define __LZO_WIN 1
|
||||
# define __LZO_WIN16 1
|
||||
#elif defined(LZO_OS_WIN32)
|
||||
# define __LZO_WIN 1
|
||||
#endif
|
||||
|
||||
#define __LZO_CMODEL /*empty*/
|
||||
#define __LZO_DMODEL /*empty*/
|
||||
#define __LZO_ENTRY __LZO_CDECL
|
||||
#define LZO_EXTERN_CDECL LZO_EXTERN
|
||||
#define LZO_ALIGN LZO_PTR_ALIGN_UP
|
||||
|
||||
#define lzo_compress_asm_t lzo_compress_t
|
||||
#define lzo_decompress_asm_t lzo_decompress_t
|
||||
|
||||
#endif /* LZO_CFG_COMPAT */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* already included */
|
||||
|
||||
|
||||
/* vim:set ts=4 et: */
|
1852
grub-core/lib/minilzo/lzodefs.h
Normal file
1852
grub-core/lib/minilzo/lzodefs.h
Normal file
File diff suppressed because it is too large
Load diff
4562
grub-core/lib/minilzo/minilzo.c
Normal file
4562
grub-core/lib/minilzo/minilzo.c
Normal file
File diff suppressed because it is too large
Load diff
109
grub-core/lib/minilzo/minilzo.h
Normal file
109
grub-core/lib/minilzo/minilzo.h
Normal file
|
@ -0,0 +1,109 @@
|
|||
/* minilzo.h -- mini subset of the LZO real-time data compression library
|
||||
|
||||
This file is part of the LZO real-time data compression library.
|
||||
|
||||
Copyright (C) 2011 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 2010 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 2009 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 2008 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 2005 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 2004 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 2003 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer
|
||||
All Rights Reserved.
|
||||
|
||||
The LZO 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 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
The LZO 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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the LZO library; see the file COPYING.
|
||||
If not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer
|
||||
<markus@oberhumer.com>
|
||||
http://www.oberhumer.com/opensource/lzo/
|
||||
*/
|
||||
|
||||
/*
|
||||
* NOTE:
|
||||
* the full LZO package can be found at
|
||||
* http://www.oberhumer.com/opensource/lzo/
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __MINILZO_H
|
||||
#define __MINILZO_H 1
|
||||
|
||||
#define MINILZO_VERSION 0x2050
|
||||
|
||||
#ifdef __LZOCONF_H
|
||||
# error "you cannot use both LZO and miniLZO"
|
||||
#endif
|
||||
|
||||
#undef LZO_HAVE_CONFIG_H
|
||||
#include "lzoconf.h"
|
||||
|
||||
#if !defined(LZO_VERSION) || (LZO_VERSION != MINILZO_VERSION)
|
||||
# error "version mismatch in header files"
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
//
|
||||
************************************************************************/
|
||||
|
||||
/* Memory required for the wrkmem parameter.
|
||||
* When the required size is 0, you can also pass a NULL pointer.
|
||||
*/
|
||||
|
||||
#define LZO1X_MEM_COMPRESS LZO1X_1_MEM_COMPRESS
|
||||
#define LZO1X_1_MEM_COMPRESS ((lzo_uint32) (16384L * lzo_sizeof_dict_t))
|
||||
#define LZO1X_MEM_DECOMPRESS (0)
|
||||
|
||||
|
||||
/* compression */
|
||||
LZO_EXTERN(int)
|
||||
lzo1x_1_compress ( const lzo_bytep src, lzo_uint src_len,
|
||||
lzo_bytep dst, lzo_uintp dst_len,
|
||||
lzo_voidp wrkmem );
|
||||
|
||||
/* decompression */
|
||||
LZO_EXTERN(int)
|
||||
lzo1x_decompress ( const lzo_bytep src, lzo_uint src_len,
|
||||
lzo_bytep dst, lzo_uintp dst_len,
|
||||
lzo_voidp wrkmem /* NOT USED */ );
|
||||
|
||||
/* safe decompression with overrun testing */
|
||||
LZO_EXTERN(int)
|
||||
lzo1x_decompress_safe ( const lzo_bytep src, lzo_uint src_len,
|
||||
lzo_bytep dst, lzo_uintp dst_len,
|
||||
lzo_voidp wrkmem /* NOT USED */ );
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* already included */
|
||||
|
35
grub-core/lib/mips/arc/reboot.c
Normal file
35
grub-core/lib/mips/arc/reboot.c
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <grub/arc/arc.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/time.h>
|
||||
#include <grub/term.h>
|
||||
#include <grub/i18n.h>
|
||||
|
||||
void
|
||||
grub_reboot (void)
|
||||
{
|
||||
GRUB_ARC_FIRMWARE_VECTOR->restart ();
|
||||
|
||||
grub_millisleep (1500);
|
||||
|
||||
grub_puts_ (N_("Reboot failed"));
|
||||
grub_refresh ();
|
||||
while (1);
|
||||
}
|
58
grub-core/lib/mips/loongson/reboot.c
Normal file
58
grub-core/lib/mips/loongson/reboot.c
Normal file
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <grub/machine/ec.h>
|
||||
#include <grub/machine/kernel.h>
|
||||
#include <grub/machine/memory.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/pci.h>
|
||||
#include <grub/cs5536.h>
|
||||
#include <grub/time.h>
|
||||
#include <grub/term.h>
|
||||
#include <grub/i18n.h>
|
||||
|
||||
void
|
||||
grub_reboot (void)
|
||||
{
|
||||
switch (grub_arch_machine)
|
||||
{
|
||||
case GRUB_ARCH_MACHINE_FULOONG2E:
|
||||
grub_outb (grub_inb (0xbfe00104) & ~4, 0xbfe00104);
|
||||
grub_outb (grub_inb (0xbfe00104) | 4, 0xbfe00104);
|
||||
break;
|
||||
case GRUB_ARCH_MACHINE_FULOONG2F:
|
||||
{
|
||||
grub_pci_device_t dev;
|
||||
if (!grub_cs5536_find (&dev))
|
||||
break;
|
||||
grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_DIVIL_RESET,
|
||||
grub_cs5536_read_msr (dev,
|
||||
GRUB_CS5536_MSR_DIVIL_RESET)
|
||||
| 1);
|
||||
break;
|
||||
}
|
||||
case GRUB_ARCH_MACHINE_YEELOONG:
|
||||
grub_write_ec (GRUB_MACHINE_EC_COMMAND_REBOOT);
|
||||
break;
|
||||
}
|
||||
grub_millisleep (1500);
|
||||
|
||||
grub_puts_ (N_("Reboot failed"));
|
||||
grub_refresh ();
|
||||
while (1);
|
||||
}
|
25
grub-core/lib/mips/qemu_mips/reboot.c
Normal file
25
grub-core/lib/mips/qemu_mips/reboot.c
Normal file
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <grub/misc.h>
|
||||
|
||||
void
|
||||
grub_reboot (void)
|
||||
{
|
||||
while (1);
|
||||
}
|
|
@ -20,6 +20,9 @@
|
|||
|
||||
.p2align 4 /* force 16-byte alignment */
|
||||
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
|
||||
VARIABLE (grub_relocator_forward_start)
|
||||
move $a0, $9
|
||||
move $a1, $10
|
||||
|
@ -28,9 +31,9 @@ copycont1:
|
|||
lb $11,0($8)
|
||||
sb $11,0($9)
|
||||
addiu $8, $8, 1
|
||||
addiu $9, $9, 1
|
||||
addiu $10, $10, -1
|
||||
bne $10, $0, copycont1
|
||||
addiu $9, $9, 1
|
||||
|
||||
#include "../../kern/mips/cache_flush.S"
|
||||
|
||||
|
@ -49,9 +52,9 @@ copycont2:
|
|||
lb $11,0($8)
|
||||
sb $11,0($9)
|
||||
addiu $8, $8, -1
|
||||
addiu $9, $9, -1
|
||||
addiu $10, $10, -1
|
||||
bne $10, $0, copycont2
|
||||
addiu $9, $9, -1
|
||||
|
||||
#include "../../kern/mips/cache_flush.S"
|
||||
|
||||
|
|
|
@ -17,9 +17,12 @@
|
|||
*/
|
||||
|
||||
#include <grub/symbol.h>
|
||||
#include <grub/dl.h>
|
||||
|
||||
.file "setjmp.S"
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+")
|
||||
|
||||
.text
|
||||
|
||||
/*
|
||||
|
|
|
@ -21,6 +21,9 @@
|
|||
#include <grub/crypto.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/dl.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv2+");
|
||||
|
||||
/* Implement PKCS#5 PBKDF2 as per RFC 2898. The PRF to use is HMAC variant
|
||||
of digest supplied by MD. Inputs are the password P of length PLEN,
|
||||
|
|
|
@ -54,8 +54,7 @@ isupper (int c)
|
|||
static inline int
|
||||
isxdigit (int c)
|
||||
{
|
||||
return (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')
|
||||
|| (c >= '0' && c <= '9');
|
||||
return grub_isxdigit (c);
|
||||
}
|
||||
|
||||
static inline int
|
||||
|
|
1
grub-core/lib/posix_wrap/inttypes.h
Normal file
1
grub-core/lib/posix_wrap/inttypes.h
Normal file
|
@ -0,0 +1 @@
|
|||
#include <sys/types.h>
|
|
@ -29,7 +29,7 @@ nl_langinfo (nl_item item)
|
|||
switch (item)
|
||||
{
|
||||
case CODESET:
|
||||
return locale_charset ();
|
||||
return "UTF-8";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2010 Free Software Foundation, Inc.
|
||||
*
|
||||
* GRUB is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GRUB is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef GRUB_POSIX_LIMITS_H
|
||||
#define GRUB_POSIX_LIMITS_H
|
||||
|
||||
#include <grub/types.h>
|
||||
|
||||
#define UCHAR_MAX GRUB_UCHAR_MAX
|
||||
#define USHRT_MAX GRUB_USHRT_MAX
|
||||
#define UINT_MAX GRUB_UINT_MAX
|
||||
#define ULONG_MAX GRUB_ULONG_MAX
|
||||
|
||||
#define CHAR_BIT 8
|
||||
|
||||
#endif
|
|
@ -19,7 +19,7 @@
|
|||
#ifndef GRUB_POSIX_LOCALCHARSET_H
|
||||
#define GRUB_POSIX_LOCALCHARSET_H 1
|
||||
|
||||
static inline char *
|
||||
static inline const char *
|
||||
locale_charset (void)
|
||||
{
|
||||
return "UTF-8";
|
||||
|
|
|
@ -39,4 +39,12 @@ strcasecmp (const char *s1, const char *s2)
|
|||
return grub_strcasecmp (s1, s2);
|
||||
}
|
||||
|
||||
#ifdef GRUB_UTIL
|
||||
static inline void *
|
||||
memcpy (void *dest, const void *src, grub_size_t n)
|
||||
{
|
||||
return grub_memcpy (dest, src, n);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -24,12 +24,20 @@
|
|||
typedef grub_size_t size_t;
|
||||
typedef enum { false = 0, true = 1 } bool;
|
||||
|
||||
#define ULONG_MAX GRUB_ULONG_MAX
|
||||
#define UCHAR_MAX 0xff
|
||||
|
||||
typedef grub_uint8_t uint8_t;
|
||||
typedef grub_uint16_t uint16_t;
|
||||
typedef grub_uint32_t uint32_t;
|
||||
typedef grub_uint64_t uint64_t;
|
||||
|
||||
typedef grub_int8_t int8_t;
|
||||
typedef grub_int16_t int16_t;
|
||||
typedef grub_int32_t int32_t;
|
||||
typedef grub_int64_t int64_t;
|
||||
|
||||
#ifdef GRUB_CPU_WORDS_BIGENDIAN
|
||||
#define WORDS_BIGENDIAN
|
||||
#else
|
||||
#undef WORDS_BIGENDIAN
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -17,9 +17,12 @@
|
|||
*/
|
||||
|
||||
#include <grub/symbol.h>
|
||||
#include <grub/dl.h>
|
||||
|
||||
.file "setjmp.S"
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+")
|
||||
|
||||
.text
|
||||
|
||||
/*
|
||||
|
|
548
grub-core/lib/reed_solomon.c
Normal file
548
grub-core/lib/reed_solomon.c
Normal file
|
@ -0,0 +1,548 @@
|
|||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2010 Free Software Foundation, Inc.
|
||||
*
|
||||
* GRUB is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GRUB is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef TEST
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#define xmalloc malloc
|
||||
#define grub_memset memset
|
||||
#define grub_memcpy memcpy
|
||||
#endif
|
||||
|
||||
#ifndef STANDALONE
|
||||
#ifdef TEST
|
||||
typedef unsigned int grub_size_t;
|
||||
typedef unsigned char grub_uint8_t;
|
||||
#else
|
||||
#include <grub/types.h>
|
||||
#include <grub/reed_solomon.h>
|
||||
#include <grub/util/misc.h>
|
||||
#include <grub/misc.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef STANDALONE
|
||||
#ifdef TEST
|
||||
typedef unsigned int grub_size_t;
|
||||
typedef unsigned char grub_uint8_t;
|
||||
#else
|
||||
#include <grub/types.h>
|
||||
#include <grub/misc.h>
|
||||
#endif
|
||||
void
|
||||
grub_reed_solomon_recover (void *ptr_, grub_size_t s, grub_size_t rs);
|
||||
#endif
|
||||
|
||||
#define GF_SIZE 8
|
||||
typedef grub_uint8_t gf_single_t;
|
||||
#define GF_POLYNOMIAL 0x1d
|
||||
#define GF_INVERT2 0x8e
|
||||
#if defined (STANDALONE) && !defined (TEST)
|
||||
static gf_single_t * const gf_powx __attribute__ ((section(".text"))) = (void *) 0x100000;
|
||||
static gf_single_t * const gf_powx_inv __attribute__ ((section(".text"))) = (void *) 0x100200;
|
||||
|
||||
static char *scratch __attribute__ ((section(".text"))) = (void *) 0x100300;
|
||||
#else
|
||||
#if defined (STANDALONE)
|
||||
static char *scratch;
|
||||
#endif
|
||||
static gf_single_t gf_powx[255 * 2];
|
||||
static gf_single_t gf_powx_inv[256];
|
||||
#endif
|
||||
|
||||
#define SECTOR_SIZE 512
|
||||
#define MAX_BLOCK_SIZE (200 * SECTOR_SIZE)
|
||||
|
||||
static gf_single_t
|
||||
gf_mul (gf_single_t a, gf_single_t b)
|
||||
{
|
||||
if (a == 0 || b == 0)
|
||||
return 0;
|
||||
return gf_powx[(int) gf_powx_inv[a] + (int) gf_powx_inv[b]];
|
||||
}
|
||||
|
||||
static inline gf_single_t
|
||||
gf_invert (gf_single_t a)
|
||||
{
|
||||
return gf_powx[255 - (int) gf_powx_inv[a]];
|
||||
}
|
||||
|
||||
static void
|
||||
init_powx (void)
|
||||
{
|
||||
int i;
|
||||
grub_uint8_t cur = 1;
|
||||
|
||||
for (i = 0; i < 255; i++)
|
||||
{
|
||||
gf_powx[i] = cur;
|
||||
gf_powx[i + 255] = cur;
|
||||
gf_powx_inv[cur] = i;
|
||||
if (cur & (1ULL << (GF_SIZE - 1)))
|
||||
cur = (cur << 1) ^ GF_POLYNOMIAL;
|
||||
else
|
||||
cur <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
static gf_single_t
|
||||
pol_evaluate (gf_single_t *pol, grub_size_t degree, gf_single_t x)
|
||||
{
|
||||
int i;
|
||||
gf_single_t s = 0;
|
||||
int log_xn = 0, log_x;
|
||||
if (x == 0)
|
||||
return pol[0];
|
||||
log_x = gf_powx_inv[x];
|
||||
for (i = degree; i >= 0; i--)
|
||||
{
|
||||
if (pol[i])
|
||||
s ^= gf_powx[(int) gf_powx_inv[pol[i]] + log_xn];
|
||||
log_xn += log_x;
|
||||
if (log_xn >= ((1 << GF_SIZE) - 1))
|
||||
log_xn -= ((1 << GF_SIZE) - 1);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
#if !defined (STANDALONE)
|
||||
static void
|
||||
rs_encode (gf_single_t *data, grub_size_t s, grub_size_t rs)
|
||||
{
|
||||
gf_single_t *rs_polynomial;
|
||||
int i, j;
|
||||
gf_single_t *m;
|
||||
m = xmalloc ((s + rs) * sizeof (gf_single_t));
|
||||
grub_memcpy (m, data, s * sizeof (gf_single_t));
|
||||
grub_memset (m + s, 0, rs * sizeof (gf_single_t));
|
||||
rs_polynomial = xmalloc ((rs + 1) * sizeof (gf_single_t));
|
||||
grub_memset (rs_polynomial, 0, (rs + 1) * sizeof (gf_single_t));
|
||||
rs_polynomial[rs] = 1;
|
||||
/* Multiply with X - a^r */
|
||||
for (j = 0; j < rs; j++)
|
||||
{
|
||||
for (i = 0; i < rs; i++)
|
||||
if (rs_polynomial[i])
|
||||
rs_polynomial[i] = (rs_polynomial[i + 1]
|
||||
^ gf_powx[j + (int) gf_powx_inv[rs_polynomial[i]]]);
|
||||
else
|
||||
rs_polynomial[i] = rs_polynomial[i + 1];
|
||||
if (rs_polynomial[rs])
|
||||
rs_polynomial[rs] = gf_powx[j + (int) gf_powx_inv[rs_polynomial[rs]]];
|
||||
}
|
||||
for (j = 0; j < s; j++)
|
||||
if (m[j])
|
||||
{
|
||||
gf_single_t f = m[j];
|
||||
for (i = 0; i <= rs; i++)
|
||||
m[i+j] ^= gf_mul (rs_polynomial[i], f);
|
||||
}
|
||||
free (rs_polynomial);
|
||||
grub_memcpy (data + s, m + s, rs * sizeof (gf_single_t));
|
||||
free (m);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
syndroms (gf_single_t *m, grub_size_t s, grub_size_t rs,
|
||||
gf_single_t *sy)
|
||||
{
|
||||
gf_single_t xn = 1;
|
||||
unsigned i;
|
||||
for (i = 0; i < rs; i++)
|
||||
{
|
||||
if (xn & (1 << (GF_SIZE - 1)))
|
||||
{
|
||||
xn <<= 1;
|
||||
xn ^= GF_POLYNOMIAL;
|
||||
}
|
||||
else
|
||||
xn <<= 1;
|
||||
sy[i] = pol_evaluate (m, s + rs - 1, xn);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gauss_eliminate (gf_single_t *eq, int n, int m, int *chosen)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i = 0 ; i < n; i++)
|
||||
{
|
||||
int nzidx;
|
||||
int k;
|
||||
gf_single_t r;
|
||||
for (nzidx = 0; nzidx < m && (eq[i * (m + 1) + nzidx] == 0);
|
||||
nzidx++);
|
||||
if (nzidx == m)
|
||||
continue;
|
||||
chosen[i] = nzidx;
|
||||
r = gf_invert (eq[i * (m + 1) + nzidx]);
|
||||
for (j = 0; j < m + 1; j++)
|
||||
eq[i * (m + 1) + j] = gf_mul (eq[i * (m + 1) + j], r);
|
||||
for (j = i + 1; j < n; j++)
|
||||
{
|
||||
gf_single_t rr = eq[j * (m + 1) + nzidx];
|
||||
for (k = 0; k < m + 1; k++)
|
||||
eq[j * (m + 1) + k] ^= gf_mul (eq[i * (m + 1) + k], rr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gauss_solve (gf_single_t *eq, int n, int m, gf_single_t *sol)
|
||||
{
|
||||
int *chosen;
|
||||
int i, j;
|
||||
|
||||
#ifndef STANDALONE
|
||||
chosen = xmalloc (n * sizeof (int));
|
||||
#else
|
||||
chosen = (void *) scratch;
|
||||
scratch += n * sizeof (int);
|
||||
#endif
|
||||
for (i = 0; i < n; i++)
|
||||
chosen[i] = -1;
|
||||
for (i = 0; i < m; i++)
|
||||
sol[i] = 0;
|
||||
gauss_eliminate (eq, n, m, chosen);
|
||||
for (i = n - 1; i >= 0; i--)
|
||||
{
|
||||
gf_single_t s = 0;
|
||||
if (chosen[i] == -1)
|
||||
continue;
|
||||
for (j = 0; j < m; j++)
|
||||
s ^= gf_mul (eq[i * (m + 1) + j], sol[j]);
|
||||
s ^= eq[i * (m + 1) + m];
|
||||
sol[chosen[i]] = s;
|
||||
}
|
||||
#ifndef STANDALONE
|
||||
free (chosen);
|
||||
#else
|
||||
scratch -= n * sizeof (int);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
rs_recover (gf_single_t *m, grub_size_t s, grub_size_t rs)
|
||||
{
|
||||
grub_size_t rs2 = rs / 2;
|
||||
gf_single_t *sigma;
|
||||
gf_single_t *errpot;
|
||||
int *errpos;
|
||||
gf_single_t *sy;
|
||||
int errnum = 0;
|
||||
int i, j;
|
||||
|
||||
#ifndef STANDALONE
|
||||
sigma = xmalloc (rs2 * sizeof (gf_single_t));
|
||||
errpot = xmalloc (rs2 * sizeof (gf_single_t));
|
||||
errpos = xmalloc (rs2 * sizeof (int));
|
||||
sy = xmalloc (rs * sizeof (gf_single_t));
|
||||
#else
|
||||
sigma = (void *) scratch;
|
||||
scratch += rs2 * sizeof (gf_single_t);
|
||||
errpot = (void *) scratch;
|
||||
scratch += rs2 * sizeof (gf_single_t);
|
||||
errpos = (void *) scratch;
|
||||
scratch += rs2 * sizeof (int);
|
||||
sy = (void *) scratch;
|
||||
scratch += rs * sizeof (gf_single_t);
|
||||
#endif
|
||||
|
||||
syndroms (m, s, rs, sy);
|
||||
|
||||
for (i = 0; i < (int) rs; i++)
|
||||
if (sy[i] != 0)
|
||||
break;
|
||||
|
||||
/* No error detected. */
|
||||
if (i == (int) rs)
|
||||
{
|
||||
#ifndef STANDALONE
|
||||
free (sigma);
|
||||
free (errpot);
|
||||
free (errpos);
|
||||
free (sy);
|
||||
#else
|
||||
scratch -= rs2 * sizeof (gf_single_t);
|
||||
scratch -= rs2 * sizeof (gf_single_t);
|
||||
scratch -= rs2 * sizeof (int);
|
||||
scratch -= rs * sizeof (gf_single_t);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
gf_single_t *eq;
|
||||
|
||||
#ifndef STANDALONE
|
||||
eq = xmalloc (rs2 * (rs2 + 1) * sizeof (gf_single_t));
|
||||
#else
|
||||
eq = (void *) scratch;
|
||||
scratch += rs2 * (rs2 + 1) * sizeof (gf_single_t);
|
||||
#endif
|
||||
|
||||
for (i = 0; i < (int) rs2; i++)
|
||||
for (j = 0; j < (int) rs2 + 1; j++)
|
||||
eq[i * (rs2 + 1) + j] = sy[i+j];
|
||||
|
||||
for (i = 0; i < (int) rs2; i++)
|
||||
sigma[i] = 0;
|
||||
|
||||
gauss_solve (eq, rs2, rs2, sigma);
|
||||
|
||||
#ifndef STANDALONE
|
||||
free (eq);
|
||||
#else
|
||||
scratch -= rs2 * (rs2 + 1) * sizeof (gf_single_t);
|
||||
#endif
|
||||
}
|
||||
|
||||
{
|
||||
gf_single_t xn = 1, yn = 1;
|
||||
for (i = 0; i < (int) (rs + s); i++)
|
||||
{
|
||||
gf_single_t ev = (gf_mul (pol_evaluate (sigma, rs2 - 1, xn), xn) ^ 1);
|
||||
if (ev == 0)
|
||||
{
|
||||
errpot[errnum] = yn;
|
||||
errpos[errnum++] = s + rs - i - 1;
|
||||
}
|
||||
yn = gf_mul (yn, 2);
|
||||
xn = gf_mul (xn, GF_INVERT2);
|
||||
}
|
||||
}
|
||||
{
|
||||
gf_single_t *errvals;
|
||||
gf_single_t *eq;
|
||||
|
||||
#ifndef STANDALONE
|
||||
eq = xmalloc (rs * (errnum + 1) * sizeof (gf_single_t));
|
||||
errvals = xmalloc (errnum * sizeof (int));
|
||||
#else
|
||||
eq = (void *) scratch;
|
||||
scratch += rs * (errnum + 1) * sizeof (gf_single_t);
|
||||
errvals = (void *) scratch;
|
||||
scratch += errnum * sizeof (int);
|
||||
#endif
|
||||
|
||||
for (j = 0; j < errnum; j++)
|
||||
eq[j] = errpot[j];
|
||||
eq[errnum] = sy[0];
|
||||
for (i = 1; i < (int) rs; i++)
|
||||
{
|
||||
for (j = 0; j < (int) errnum; j++)
|
||||
eq[(errnum + 1) * i + j] = gf_mul (errpot[j],
|
||||
eq[(errnum + 1) * (i - 1) + j]);
|
||||
eq[(errnum + 1) * i + errnum] = sy[i];
|
||||
}
|
||||
|
||||
gauss_solve (eq, rs, errnum, errvals);
|
||||
|
||||
for (i = 0; i < (int) errnum; i++)
|
||||
m[errpos[i]] ^= errvals[i];
|
||||
#ifndef STANDALONE
|
||||
free (eq);
|
||||
free (errvals);
|
||||
#else
|
||||
scratch -= rs * (errnum + 1) * sizeof (gf_single_t);
|
||||
scratch -= errnum * sizeof (int);
|
||||
#endif
|
||||
}
|
||||
#ifndef STANDALONE
|
||||
free (sigma);
|
||||
free (errpot);
|
||||
free (errpos);
|
||||
free (sy);
|
||||
#else
|
||||
scratch -= rs2 * sizeof (gf_single_t);
|
||||
scratch -= rs2 * sizeof (gf_single_t);
|
||||
scratch -= rs2 * sizeof (int);
|
||||
scratch -= rs * sizeof (gf_single_t);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
decode_block (gf_single_t *ptr, grub_size_t s,
|
||||
gf_single_t *rptr, grub_size_t rs)
|
||||
{
|
||||
int i, j;
|
||||
for (i = 0; i < SECTOR_SIZE; i++)
|
||||
{
|
||||
grub_size_t ds = (s + SECTOR_SIZE - 1 - i) / SECTOR_SIZE;
|
||||
grub_size_t rr = (rs + SECTOR_SIZE - 1 - i) / SECTOR_SIZE;
|
||||
gf_single_t m[ds + rr];
|
||||
|
||||
/* Nothing to do. */
|
||||
if (!ds || !rr)
|
||||
continue;
|
||||
|
||||
for (j = 0; j < (int) ds; j++)
|
||||
m[j] = ptr[SECTOR_SIZE * j + i];
|
||||
for (j = 0; j < (int) rr; j++)
|
||||
m[j + ds] = rptr[SECTOR_SIZE * j + i];
|
||||
|
||||
rs_recover (m, ds, rr);
|
||||
|
||||
for (j = 0; j < (int) ds; j++)
|
||||
ptr[SECTOR_SIZE * j + i] = m[j];
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined (STANDALONE)
|
||||
static void
|
||||
encode_block (gf_single_t *ptr, grub_size_t s,
|
||||
gf_single_t *rptr, grub_size_t rs)
|
||||
{
|
||||
int i, j;
|
||||
for (i = 0; i < SECTOR_SIZE; i++)
|
||||
{
|
||||
grub_size_t ds = (s + SECTOR_SIZE - 1 - i) / SECTOR_SIZE;
|
||||
grub_size_t rr = (rs + SECTOR_SIZE - 1 - i) / SECTOR_SIZE;
|
||||
gf_single_t m[ds + rr];
|
||||
for (j = 0; j < ds; j++)
|
||||
m[j] = ptr[SECTOR_SIZE * j + i];
|
||||
rs_encode (m, ds, rr);
|
||||
for (j = 0; j < rr; j++)
|
||||
rptr[SECTOR_SIZE * j + i] = m[j + ds];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined (STANDALONE)
|
||||
void
|
||||
grub_reed_solomon_add_redundancy (void *buffer, grub_size_t data_size,
|
||||
grub_size_t redundancy)
|
||||
{
|
||||
grub_size_t s = data_size;
|
||||
grub_size_t rs = redundancy;
|
||||
gf_single_t *ptr = buffer;
|
||||
gf_single_t *rptr = ptr + s;
|
||||
|
||||
/* Nothing to do. */
|
||||
if (!rs)
|
||||
return;
|
||||
|
||||
init_powx ();
|
||||
|
||||
while (s > 0)
|
||||
{
|
||||
grub_size_t tt;
|
||||
grub_size_t cs, crs;
|
||||
cs = s;
|
||||
crs = rs;
|
||||
tt = cs + crs;
|
||||
if (tt > MAX_BLOCK_SIZE)
|
||||
{
|
||||
cs = ((cs * (MAX_BLOCK_SIZE / 512)) / tt) * 512;
|
||||
crs = ((crs * (MAX_BLOCK_SIZE / 512)) / tt) * 512;
|
||||
}
|
||||
encode_block (ptr, cs, rptr, crs);
|
||||
ptr += cs;
|
||||
rptr += crs;
|
||||
s -= cs;
|
||||
rs -= crs;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
grub_reed_solomon_recover (void *ptr_, grub_size_t s, grub_size_t rs)
|
||||
{
|
||||
gf_single_t *ptr = ptr_;
|
||||
gf_single_t *rptr = ptr + s;
|
||||
|
||||
/* Nothing to do. */
|
||||
if (!rs)
|
||||
return;
|
||||
|
||||
init_powx ();
|
||||
|
||||
while (s > 0)
|
||||
{
|
||||
grub_size_t tt;
|
||||
grub_size_t cs, crs;
|
||||
cs = s;
|
||||
crs = rs;
|
||||
tt = cs + crs;
|
||||
if (tt > MAX_BLOCK_SIZE)
|
||||
{
|
||||
cs = ((cs * (MAX_BLOCK_SIZE / 512)) / tt) * 512;
|
||||
crs = ((crs * (MAX_BLOCK_SIZE / 512)) / tt) * 512;
|
||||
}
|
||||
decode_block (ptr, cs, rptr, crs);
|
||||
ptr += cs;
|
||||
rptr += crs;
|
||||
s -= cs;
|
||||
rs -= crs;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef TEST
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
FILE *in, *out;
|
||||
grub_size_t s, rs;
|
||||
char *buf;
|
||||
|
||||
grub_memset (gf_powx, 0xee, sizeof (gf_powx));
|
||||
grub_memset (gf_powx_inv, 0xdd, sizeof (gf_powx_inv));
|
||||
|
||||
#ifdef STANDALONE
|
||||
scratch = xmalloc (1048576);
|
||||
#endif
|
||||
|
||||
#ifndef STANDALONE
|
||||
init_powx ();
|
||||
#endif
|
||||
|
||||
in = fopen ("tst.bin", "rb");
|
||||
if (!in)
|
||||
return 1;
|
||||
fseek (in, 0, SEEK_END);
|
||||
s = ftell (in);
|
||||
fseek (in, 0, SEEK_SET);
|
||||
rs = 0x7007;
|
||||
buf = xmalloc (s + rs + SECTOR_SIZE);
|
||||
fread (buf, 1, s, in);
|
||||
fclose (in);
|
||||
|
||||
grub_reed_solomon_add_redundancy (buf, s, rs);
|
||||
|
||||
out = fopen ("tst_rs.bin", "wb");
|
||||
fwrite (buf, 1, s + rs, out);
|
||||
fclose (out);
|
||||
#if 0
|
||||
grub_memset (buf + 512 * 15, 0, 512);
|
||||
#endif
|
||||
|
||||
out = fopen ("tst_dam.bin", "wb");
|
||||
fwrite (buf, 1, s + rs, out);
|
||||
fclose (out);
|
||||
grub_reed_solomon_recover (buf, s, rs);
|
||||
|
||||
out = fopen ("tst_rec.bin", "wb");
|
||||
fwrite (buf, 1, s, out);
|
||||
fclose (out);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
|
@ -22,6 +22,9 @@
|
|||
#include <grub/misc.h>
|
||||
#include <grub/cache.h>
|
||||
#include <grub/memory.h>
|
||||
#include <grub/dl.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
struct grub_relocator
|
||||
{
|
||||
|
@ -40,7 +43,6 @@ struct grub_relocator_subchunk
|
|||
#endif
|
||||
} type;
|
||||
grub_mm_region_t reg;
|
||||
grub_mm_header_t head;
|
||||
grub_phys_addr_t start;
|
||||
grub_size_t size;
|
||||
grub_size_t pre_size;
|
||||
|
@ -78,10 +80,10 @@ struct grub_relocator_fw_leftover
|
|||
grub_uint8_t freebytes[GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT / 8];
|
||||
};
|
||||
|
||||
struct grub_relocator_fw_leftover *leftovers;
|
||||
static struct grub_relocator_fw_leftover *leftovers;
|
||||
#endif
|
||||
|
||||
struct grub_relocator_extra_block *extra_blocks;
|
||||
static struct grub_relocator_extra_block *extra_blocks;
|
||||
|
||||
void *
|
||||
get_virtual_current_address (grub_relocator_chunk_t in)
|
||||
|
@ -135,9 +137,10 @@ allocate_regstart (grub_phys_addr_t addr, grub_size_t size, grub_mm_region_t rb,
|
|||
grub_addr_t newreg_size, newreg_presize;
|
||||
grub_mm_header_t new_header;
|
||||
grub_mm_header_t hb = (grub_mm_header_t) (rb + 1);
|
||||
|
||||
grub_dprintf ("relocator", "ra = %p, rb = %p\n", regancestor, rb);
|
||||
|
||||
#ifdef DEBUG_RELOCATOR_NOMEM_DPRINTF
|
||||
grub_dprintf ("relocator", "ra = %p, rb = %p\n", regancestor, rb);
|
||||
#endif
|
||||
newreg_start = ALIGN_UP (newreg_raw_start, GRUB_MM_ALIGN);
|
||||
newreg_presize = newreg_start - newreg_raw_start;
|
||||
newreg_size = rb->size - (newreg_start - (grub_addr_t) rb);
|
||||
|
@ -180,11 +183,12 @@ allocate_regstart (grub_phys_addr_t addr, grub_size_t size, grub_mm_region_t rb,
|
|||
if ((void *) h < (void *) (newreg + 1))
|
||||
grub_fatal ("Failed to adjust memory region: %p, %p, %p, %p, %p",
|
||||
newreg, newreg->first, h, hp, hb);
|
||||
#ifdef DEBUG_RELOCATOR_NOMEM_DPRINTF
|
||||
if ((void *) h == (void *) (newreg + 1))
|
||||
grub_dprintf ("relocator",
|
||||
"Free start memory region: %p, %p, %p, %p, %p",
|
||||
newreg, newreg->first, h, hp, hb);
|
||||
|
||||
#endif
|
||||
hp = h;
|
||||
h = h->next;
|
||||
}
|
||||
|
@ -201,10 +205,12 @@ allocate_inreg (grub_phys_addr_t paddr, grub_size_t size,
|
|||
struct grub_mm_header *foll = NULL;
|
||||
grub_addr_t vaddr = (grub_addr_t) hb + (paddr - grub_vtop (hb));
|
||||
|
||||
#ifdef DEBUG_RELOCATOR_NOMEM_DPRINTF
|
||||
grub_dprintf ("relocator", "inreg paddr = 0x%lx, size = %lu,"
|
||||
" hb = %p, hbp = %p, rb = %p, vaddr = 0x%lx\n",
|
||||
(unsigned long) paddr, (unsigned long) size, hb, hbp,
|
||||
rb, (unsigned long) vaddr);
|
||||
#endif
|
||||
|
||||
if (ALIGN_UP (vaddr + size, GRUB_MM_ALIGN) + GRUB_MM_ALIGN
|
||||
<= (grub_addr_t) (hb + hb->size))
|
||||
|
@ -212,8 +218,10 @@ allocate_inreg (grub_phys_addr_t paddr, grub_size_t size,
|
|||
foll = (void *) ALIGN_UP (vaddr + size, GRUB_MM_ALIGN);
|
||||
foll->magic = GRUB_MM_FREE_MAGIC;
|
||||
foll->size = hb + hb->size - foll;
|
||||
#ifdef DEBUG_RELOCATOR_NOMEM_DPRINTF
|
||||
grub_dprintf ("relocator", "foll = %p, foll->size = %lu\n", foll,
|
||||
(unsigned long) foll->size);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (vaddr - (grub_addr_t) hb >= sizeof (*hb))
|
||||
|
@ -355,11 +363,11 @@ free_subchunk (const struct grub_relocator_subchunk *subchu)
|
|||
}
|
||||
case CHUNK_TYPE_IN_REGION:
|
||||
{
|
||||
grub_mm_header_t h = (grub_mm_header_t) ALIGN_DOWN ((grub_addr_t) subchu->head,
|
||||
grub_mm_header_t h = (grub_mm_header_t) ALIGN_DOWN ((grub_addr_t) subchu->start,
|
||||
GRUB_MM_ALIGN);
|
||||
h->size
|
||||
= ((subchu->start + subchu->size + GRUB_MM_ALIGN - 1) / GRUB_MM_ALIGN)
|
||||
- (subchu->start / GRUB_MM_ALIGN);
|
||||
- (subchu->start / GRUB_MM_ALIGN) - 1;
|
||||
h->next = h;
|
||||
h->magic = GRUB_MM_ALLOC_MAGIC;
|
||||
grub_free (h + 1);
|
||||
|
@ -579,21 +587,17 @@ malloc_in_range (struct grub_relocator *rel,
|
|||
|
||||
for (ra = &base_saved, r = *ra; r; ra = &(r->next), r = *ra)
|
||||
{
|
||||
int pre_added = 0;
|
||||
pa = r->first;
|
||||
p = pa->next;
|
||||
if (p->magic == GRUB_MM_ALLOC_MAGIC)
|
||||
continue;
|
||||
do
|
||||
{
|
||||
grub_dprintf ("relocator", "free block %p+0x%lx\n",
|
||||
p, (unsigned long) p->size);
|
||||
if (p->magic != GRUB_MM_FREE_MAGIC)
|
||||
grub_fatal (__FILE__":%d free magic broken at %p (0x%x)\n",
|
||||
__LINE__, p, p->magic);
|
||||
if (p == (grub_mm_header_t) (r + 1))
|
||||
{
|
||||
pre_added = 1;
|
||||
events[N].type = REG_BEG_START;
|
||||
events[N].pos = grub_vtop (r) - r->pre_size;
|
||||
events[N].reg = r;
|
||||
|
@ -602,7 +606,8 @@ malloc_in_range (struct grub_relocator *rel,
|
|||
events[N].hancestor = pa;
|
||||
N++;
|
||||
events[N].type = REG_BEG_END;
|
||||
events[N].pos = grub_vtop (p + p->size) - sizeof (*r);
|
||||
events[N].pos = grub_vtop (p + p->size) - sizeof (*r)
|
||||
- sizeof (struct grub_mm_header);
|
||||
N++;
|
||||
}
|
||||
else
|
||||
|
@ -669,7 +674,6 @@ malloc_in_range (struct grub_relocator *rel,
|
|||
const int nlefto = 0;
|
||||
#endif
|
||||
grub_addr_t starta = 0;
|
||||
int numstarted;
|
||||
for (j = from_low_priv ? 0 : N - 1; from_low_priv ? j < N : (j + 1);
|
||||
from_low_priv ? j++ : j--)
|
||||
{
|
||||
|
@ -727,11 +731,8 @@ malloc_in_range (struct grub_relocator *rel,
|
|||
isinsideafter = (!ncollisions && (nstarted || ((nlefto || nstartedfw)
|
||||
&& !nblockfw)));
|
||||
if (!isinsidebefore && isinsideafter)
|
||||
{
|
||||
starta = from_low_priv ? ALIGN_UP (events[j].pos, align)
|
||||
: ALIGN_DOWN (events[j].pos - size, align) + size;
|
||||
numstarted = j;
|
||||
}
|
||||
starta = from_low_priv ? ALIGN_UP (events[j].pos, align)
|
||||
: ALIGN_DOWN (events[j].pos - size, align) + size;
|
||||
if (isinsidebefore && !isinsideafter && from_low_priv)
|
||||
{
|
||||
target = starta;
|
||||
|
@ -763,6 +764,9 @@ malloc_in_range (struct grub_relocator *rel,
|
|||
int inreg = 0, regbeg = 0, ncol = 0;
|
||||
#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS
|
||||
int fwin = 0, fwb = 0, fwlefto = 0;
|
||||
#endif
|
||||
#if GRUB_RELOCATOR_HAVE_LEFTOVERS
|
||||
int last_lo = 0;
|
||||
#endif
|
||||
int last_start = 0;
|
||||
for (j = 0; j < N; j++)
|
||||
|
@ -827,9 +831,11 @@ malloc_in_range (struct grub_relocator *rel,
|
|||
fend
|
||||
= ALIGN_UP (alloc_end,
|
||||
GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT);
|
||||
#ifdef DEBUG_RELOCATOR_NOMEM_DPRINTF
|
||||
grub_dprintf ("relocator", "requesting %lx-%lx\n",
|
||||
(unsigned long) fstart,
|
||||
(unsigned long) fend);
|
||||
#endif
|
||||
/* The failure here can be very expensive. */
|
||||
if (!grub_relocator_firmware_alloc_region (fstart,
|
||||
fend - fstart))
|
||||
|
@ -852,7 +858,7 @@ malloc_in_range (struct grub_relocator *rel,
|
|||
unsigned offend = alloc_end
|
||||
% GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT;
|
||||
struct grub_relocator_fw_leftover *lo
|
||||
= events[last_start].leftover;
|
||||
= events[last_lo].leftover;
|
||||
lo->freebytes[offstart / 8]
|
||||
&= ((1 << (8 - (start % 8))) - 1);
|
||||
grub_memset (lo->freebytes + (offstart + 7) / 8, 0,
|
||||
|
@ -907,6 +913,7 @@ malloc_in_range (struct grub_relocator *rel,
|
|||
#if GRUB_RELOCATOR_HAVE_LEFTOVERS
|
||||
case REG_LEFTOVER_START:
|
||||
fwlefto++;
|
||||
last_lo = j;
|
||||
break;
|
||||
|
||||
case REG_LEFTOVER_END:
|
||||
|
@ -979,7 +986,6 @@ malloc_in_range (struct grub_relocator *rel,
|
|||
|| typepre == CHUNK_TYPE_IN_REGION)
|
||||
{
|
||||
curschu->reg = events[last_start].reg;
|
||||
curschu->head = events[last_start].head;
|
||||
curschu->pre_size = alloc_start - events[j - 1].pos;
|
||||
}
|
||||
if (!oom && (typepre == CHUNK_TYPE_REGION_START
|
||||
|
@ -1007,7 +1013,8 @@ malloc_in_range (struct grub_relocator *rel,
|
|||
curschu->extra = ne;
|
||||
}
|
||||
}
|
||||
#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS
|
||||
|
||||
#if GRUB_RELOCATOR_HAVE_LEFTOVERS
|
||||
if (!oom && typepre == CHUNK_TYPE_FIRMWARE)
|
||||
{
|
||||
grub_addr_t fstart, fend;
|
||||
|
@ -1019,7 +1026,6 @@ malloc_in_range (struct grub_relocator *rel,
|
|||
= ALIGN_UP (alloc_end,
|
||||
GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT);
|
||||
|
||||
#if GRUB_RELOCATOR_HAVE_LEFTOVERS
|
||||
{
|
||||
struct grub_relocator_fw_leftover *lo1 = NULL;
|
||||
struct grub_relocator_fw_leftover *lo2 = NULL;
|
||||
|
@ -1079,10 +1085,8 @@ malloc_in_range (struct grub_relocator *rel,
|
|||
curschu->pre = lo1;
|
||||
curschu->post = lo2;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if GRUB_RELOCATOR_HAVE_LEFTOVERS
|
||||
if (typepre == CHUNK_TYPE_LEFTOVER)
|
||||
{
|
||||
curschu->pre = events[last_start].leftover;
|
||||
|
@ -1090,7 +1094,6 @@ malloc_in_range (struct grub_relocator *rel,
|
|||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
if (!oom)
|
||||
cural++;
|
||||
else
|
||||
|
@ -1291,23 +1294,8 @@ grub_relocator_alloc_chunk_addr (struct grub_relocator *rel,
|
|||
chunk->srcv = grub_map_memory (chunk->src, chunk->size);
|
||||
*out = chunk;
|
||||
#ifdef DEBUG_RELOCATOR
|
||||
{
|
||||
grub_mm_region_t r;
|
||||
grub_mm_header_t p;
|
||||
grub_memset (chunk->srcv, 0xfa, chunk->size);
|
||||
for (r = grub_mm_base; r; r = r->next)
|
||||
{
|
||||
p = r->first;
|
||||
do
|
||||
{
|
||||
if ((grub_addr_t) p < (grub_addr_t) (r + 1)
|
||||
|| (grub_addr_t) p >= (grub_addr_t) (r + 1) + r->size)
|
||||
grub_fatal (__FILE__ ":%d: out of range pointer: %p\n", __LINE__, p);
|
||||
p = p->next;
|
||||
}
|
||||
while (p != r->first);
|
||||
}
|
||||
}
|
||||
grub_memset (chunk->srcv, 0xfa, chunk->size);
|
||||
grub_mm_check ();
|
||||
#endif
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
@ -1379,11 +1367,13 @@ grub_relocator_alloc_chunk_align (struct grub_relocator *rel,
|
|||
|
||||
{
|
||||
int found = 0;
|
||||
auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
|
||||
int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t sz, grub_uint32_t type)
|
||||
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_MACHINE_MEMORY_AVAILABLE)
|
||||
if (type != GRUB_MEMORY_AVAILABLE)
|
||||
return 0;
|
||||
candidate = ALIGN_UP (addr, align);
|
||||
if (candidate < min_addr)
|
||||
|
@ -1430,11 +1420,17 @@ grub_relocator_alloc_chunk_align (struct grub_relocator *rel,
|
|||
break;
|
||||
}
|
||||
|
||||
grub_dprintf ("relocator", "relocators_size=%ld\n",
|
||||
(unsigned long) rel->relocators_size);
|
||||
|
||||
if (chunk->src < chunk->target)
|
||||
rel->relocators_size += grub_relocator_backward_size;
|
||||
if (chunk->src > 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;
|
||||
|
@ -1443,24 +1439,8 @@ grub_relocator_alloc_chunk_align (struct grub_relocator *rel,
|
|||
chunk->srcv = grub_map_memory (chunk->src, chunk->size);
|
||||
*out = chunk;
|
||||
#ifdef DEBUG_RELOCATOR
|
||||
{
|
||||
grub_mm_region_t r;
|
||||
grub_mm_header_t p;
|
||||
|
||||
grub_memset (chunk->srcv, 0xfa, chunk->size);
|
||||
for (r = grub_mm_base; r; r = r->next)
|
||||
{
|
||||
p = r->first;
|
||||
do
|
||||
{
|
||||
if ((grub_addr_t) p < (grub_addr_t) (r + 1)
|
||||
|| (grub_addr_t) p >= (grub_addr_t) (r + 1) + r->size)
|
||||
grub_fatal (__FILE__ "%d: out of range pointer: %p\n", __LINE__, p);
|
||||
p = p->next;
|
||||
}
|
||||
while (p != r->first);
|
||||
}
|
||||
}
|
||||
grub_memset (chunk->srcv, 0xfa, chunk->size);
|
||||
grub_mm_check ();
|
||||
#endif
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
@ -1502,7 +1482,8 @@ grub_relocator_prepare_relocs (struct grub_relocator *rel, grub_addr_t addr,
|
|||
grub_relocator_align,
|
||||
rel->relocators_size, &movers_chunk, 1, 1))
|
||||
return grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory");
|
||||
rels = rels0 = grub_map_memory (movers_chunk.src, movers_chunk.size);
|
||||
movers_chunk.srcv = rels = rels0
|
||||
= grub_map_memory (movers_chunk.src, movers_chunk.size);
|
||||
|
||||
if (relsize)
|
||||
*relsize = rel->relocators_size;
|
||||
|
|
|
@ -8,6 +8,9 @@
|
|||
#include "./mips/setjmp.S"
|
||||
#elif defined(__powerpc__)
|
||||
#include "./powerpc/setjmp.S"
|
||||
#elif defined(__ia64__)
|
||||
#include "./ia64/setjmp.S"
|
||||
#include "./ia64/longjmp.S"
|
||||
#else
|
||||
#error "Unknwon target cpu type"
|
||||
#error "Unknown target cpu type"
|
||||
#endif
|
||||
|
|
|
@ -17,9 +17,12 @@
|
|||
*/
|
||||
|
||||
#include <grub/symbol.h>
|
||||
#include <grub/dl.h>
|
||||
|
||||
.file "setjmp.S"
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+")
|
||||
|
||||
.text
|
||||
|
||||
/*
|
||||
|
|
|
@ -17,9 +17,12 @@
|
|||
*/
|
||||
|
||||
#include <grub/symbol.h>
|
||||
#include <grub/dl.h>
|
||||
|
||||
.file "setjmp.S"
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+")
|
||||
|
||||
.text
|
||||
|
||||
/*
|
||||
|
|
|
@ -520,9 +520,18 @@ enum xz_ret xz_dec_bcj_run(struct xz_dec_bcj *s,
|
|||
return s->ret;
|
||||
}
|
||||
|
||||
#ifdef GRUB_EMBED_DECOMPRESSOR
|
||||
struct xz_dec_bcj bcj;
|
||||
#endif
|
||||
|
||||
struct xz_dec_bcj * xz_dec_bcj_create(bool single_call)
|
||||
{
|
||||
struct xz_dec_bcj *s = kmalloc(sizeof(*s), GFP_KERNEL);
|
||||
struct xz_dec_bcj *s;
|
||||
#ifdef GRUB_EMBED_DECOMPRESSOR
|
||||
s = &bcj;
|
||||
#else
|
||||
s = kmalloc(sizeof(*s), GFP_KERNEL);
|
||||
#endif
|
||||
if (s != NULL)
|
||||
s->single_call = single_call;
|
||||
|
||||
|
|
|
@ -1100,10 +1100,16 @@ enum xz_ret xz_dec_lzma2_run(
|
|||
return XZ_OK;
|
||||
}
|
||||
|
||||
#ifdef GRUB_EMBED_DECOMPRESSOR
|
||||
#include <grub/decompressor.h>
|
||||
static struct xz_dec_lzma2 lzma2;
|
||||
#endif
|
||||
|
||||
struct xz_dec_lzma2 * xz_dec_lzma2_create(uint32_t dict_max)
|
||||
{
|
||||
struct xz_dec_lzma2 *s;
|
||||
|
||||
#ifndef GRUB_EMBED_DECOMPRESSOR
|
||||
/* Maximum supported dictionary by this implementation is 3 GiB. */
|
||||
if (dict_max > ((uint32_t)3 << 30))
|
||||
return NULL;
|
||||
|
@ -1120,6 +1126,11 @@ struct xz_dec_lzma2 * xz_dec_lzma2_create(uint32_t dict_max)
|
|||
}
|
||||
}
|
||||
|
||||
#else
|
||||
s = &lzma2;
|
||||
s->dict.buf = grub_decompressor_scratch;
|
||||
#endif
|
||||
|
||||
s->dict.allocated = dict_max;
|
||||
|
||||
return s;
|
||||
|
@ -1135,6 +1146,7 @@ enum xz_ret xz_dec_lzma2_reset(
|
|||
s->dict.size = 2 + (props & 1);
|
||||
s->dict.size <<= (props >> 1) + 11;
|
||||
|
||||
#ifndef GRUB_EMBED_DECOMPRESSOR
|
||||
if (s->dict.allocated > 0 && s->dict.allocated < s->dict.size)
|
||||
{
|
||||
/* enlarge dictionary buffer */
|
||||
|
@ -1146,7 +1158,7 @@ enum xz_ret xz_dec_lzma2_reset(
|
|||
s->dict.buf = newdict;
|
||||
s->dict.allocated = s->dict.size;
|
||||
}
|
||||
|
||||
#endif
|
||||
s->dict.end = s->dict.size;
|
||||
|
||||
s->lzma.len = 0;
|
||||
|
@ -1159,10 +1171,12 @@ enum xz_ret xz_dec_lzma2_reset(
|
|||
return XZ_OK;
|
||||
}
|
||||
|
||||
void xz_dec_lzma2_end(struct xz_dec_lzma2 *s)
|
||||
void xz_dec_lzma2_end(struct xz_dec_lzma2 *s __attribute__ ((unused)))
|
||||
{
|
||||
#ifndef GRUB_EMBED_DECOMPRESSOR
|
||||
if (s->dict.allocated > 0)
|
||||
vfree(s->dict.buf);
|
||||
|
||||
kfree(s);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -31,9 +31,14 @@
|
|||
struct xz_dec_hash {
|
||||
vli_type unpadded;
|
||||
vli_type uncompressed;
|
||||
uint8_t *crc32_context;
|
||||
#ifndef GRUB_EMBED_DECOMPRESSOR
|
||||
uint64_t *hash_context;
|
||||
#endif
|
||||
};
|
||||
|
||||
/* Enough for up to 512 bits. */
|
||||
#define MAX_HASH_SIZE 64
|
||||
|
||||
struct xz_dec {
|
||||
/* Position in dec_main() */
|
||||
enum {
|
||||
|
@ -60,11 +65,22 @@ struct xz_dec {
|
|||
size_t out_start;
|
||||
|
||||
/* CRC32 value in Block or Index */
|
||||
uint32_t crc32_temp; /* need for crc32_validate*/
|
||||
uint8_t *crc32_context;
|
||||
#ifndef GRUB_EMBED_DECOMPRESSOR
|
||||
uint8_t hash_value[MAX_HASH_SIZE]; /* need for crc32_validate*/
|
||||
#endif
|
||||
int have_hash_value;
|
||||
#ifndef GRUB_EMBED_DECOMPRESSOR
|
||||
uint64_t *hash_context;
|
||||
uint64_t *crc32_context;
|
||||
#endif
|
||||
|
||||
/* True if CRC32 is calculated from uncompressed data */
|
||||
bool has_crc32;
|
||||
/* Hash function calculated from uncompressed data */
|
||||
#ifndef GRUB_EMBED_DECOMPRESSOR
|
||||
const gcry_md_spec_t *hash;
|
||||
const gcry_md_spec_t *crc32;
|
||||
grub_uint8_t hash_id;
|
||||
#endif
|
||||
grub_size_t hash_size;
|
||||
|
||||
/* True if we are operating in single-call mode. */
|
||||
bool single_call;
|
||||
|
@ -247,9 +263,14 @@ static enum xz_ret dec_block(struct xz_dec *s, struct xz_buf *b)
|
|||
> s->block_header.uncompressed)
|
||||
return XZ_DATA_ERROR;
|
||||
|
||||
if (s->has_crc32)
|
||||
GRUB_MD_CRC32->write(s->crc32_context,b->out + s->out_start,
|
||||
b->out_pos - s->out_start);
|
||||
#ifndef GRUB_EMBED_DECOMPRESSOR
|
||||
if (s->hash)
|
||||
s->hash->write(s->hash_context,b->out + s->out_start,
|
||||
b->out_pos - s->out_start);
|
||||
if (s->crc32)
|
||||
s->crc32->write(s->crc32_context,b->out + s->out_start,
|
||||
b->out_pos - s->out_start);
|
||||
#endif
|
||||
|
||||
if (ret == XZ_STREAM_END) {
|
||||
if (s->block_header.compressed != VLI_UNKNOWN
|
||||
|
@ -264,13 +285,16 @@ static enum xz_ret dec_block(struct xz_dec *s, struct xz_buf *b)
|
|||
|
||||
s->block.hash.unpadded += s->block_header.size
|
||||
+ s->block.compressed;
|
||||
if (s->has_crc32)
|
||||
s->block.hash.unpadded += 4;
|
||||
s->block.hash.unpadded += s->hash_size;
|
||||
|
||||
s->block.hash.uncompressed += s->block.uncompressed;
|
||||
|
||||
GRUB_MD_CRC32->write(s->block.hash.crc32_context,
|
||||
(const uint8_t *)&s->block.hash, 2 * sizeof(vli_type));
|
||||
#ifndef GRUB_EMBED_DECOMPRESSOR
|
||||
if (s->hash)
|
||||
s->hash->write(s->block.hash.hash_context,
|
||||
(const uint8_t *)&s->block.hash,
|
||||
2 * sizeof(vli_type));
|
||||
#endif
|
||||
|
||||
++s->block.count;
|
||||
}
|
||||
|
@ -283,7 +307,12 @@ static void index_update(struct xz_dec *s, const struct xz_buf *b)
|
|||
{
|
||||
size_t in_used = b->in_pos - s->in_start;
|
||||
s->index.size += in_used;
|
||||
GRUB_MD_CRC32->write(s->crc32_context,b->in + s->in_start, in_used);
|
||||
#ifndef GRUB_EMBED_DECOMPRESSOR
|
||||
if (s->hash)
|
||||
s->hash->write(s->hash_context,b->in + s->in_start, in_used);
|
||||
if (s->crc32)
|
||||
s->crc32->write(s->crc32_context,b->in + s->in_start, in_used);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -328,8 +357,11 @@ static enum xz_ret dec_index(struct xz_dec *s, struct xz_buf *b)
|
|||
case SEQ_INDEX_UNCOMPRESSED:
|
||||
s->index.hash.uncompressed += s->vli;
|
||||
|
||||
GRUB_MD_CRC32->write(s->index.hash.crc32_context,
|
||||
(const uint8_t *)&s->index.hash, 2 * sizeof(vli_type));
|
||||
#ifndef GRUB_EMBED_DECOMPRESSOR
|
||||
if (s->hash)
|
||||
s->hash->write(s->index.hash.hash_context,
|
||||
(const uint8_t *)&s->index.hash, 2 * sizeof(vli_type));
|
||||
#endif
|
||||
|
||||
--s->index.count;
|
||||
s->index.sequence = SEQ_INDEX_UNPADDED;
|
||||
|
@ -344,59 +376,171 @@ static enum xz_ret dec_index(struct xz_dec *s, struct xz_buf *b)
|
|||
* Validate that the next four input bytes match the value of s->crc32.
|
||||
* s->pos must be zero when starting to validate the first byte.
|
||||
*/
|
||||
static enum xz_ret crc32_validate(struct xz_dec *s, struct xz_buf *b)
|
||||
static enum xz_ret hash_validate(struct xz_dec *s, struct xz_buf *b,
|
||||
int crc32)
|
||||
{
|
||||
if(s->crc32_temp == 0)
|
||||
#ifndef GRUB_EMBED_DECOMPRESSOR
|
||||
const gcry_md_spec_t *hash = crc32 ? s->crc32 : s->hash;
|
||||
grub_uint64_t *hash_context = crc32 ? s->crc32_context
|
||||
: s->hash_context;
|
||||
if(!s->have_hash_value && hash
|
||||
&& sizeof (s->hash_value) >= hash->mdlen)
|
||||
{
|
||||
GRUB_MD_CRC32->final(s->crc32_context);
|
||||
s->crc32_temp = get_unaligned_be32(GRUB_MD_CRC32->read(s->crc32_context));
|
||||
hash->final(hash_context);
|
||||
grub_memcpy (s->hash_value, hash->read(hash_context),
|
||||
hash->mdlen);
|
||||
s->have_hash_value = 1;
|
||||
if (s->hash_id == 1 || crc32)
|
||||
{
|
||||
grub_uint8_t t;
|
||||
t = s->hash_value[0];
|
||||
s->hash_value[0] = s->hash_value[3];
|
||||
s->hash_value[3] = t;
|
||||
t = s->hash_value[1];
|
||||
s->hash_value[1] = s->hash_value[2];
|
||||
s->hash_value[2] = t;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
do {
|
||||
if (b->in_pos == b->in_size)
|
||||
return XZ_OK;
|
||||
|
||||
if (((s->crc32_temp >> s->pos) & 0xFF) != b->in[b->in_pos++])
|
||||
#ifndef GRUB_EMBED_DECOMPRESSOR
|
||||
if (hash && s->hash_value[s->pos / 8] != b->in[b->in_pos++])
|
||||
return XZ_DATA_ERROR;
|
||||
#endif
|
||||
|
||||
s->pos += 8;
|
||||
|
||||
} while (s->pos < 32);
|
||||
} while (s->pos < (crc32 ? 32 : s->hash_size * 8));
|
||||
|
||||
GRUB_MD_CRC32->init(s->crc32_context);
|
||||
s->crc32_temp = 0;
|
||||
#ifndef GRUB_EMBED_DECOMPRESSOR
|
||||
if (s->hash)
|
||||
s->hash->init(s->hash_context);
|
||||
if (s->crc32)
|
||||
s->crc32->init(s->crc32_context);
|
||||
#endif
|
||||
s->have_hash_value = 0;
|
||||
s->pos = 0;
|
||||
|
||||
return XZ_STREAM_END;
|
||||
}
|
||||
|
||||
static const struct
|
||||
{
|
||||
const char *name;
|
||||
grub_size_t size;
|
||||
} hashes[] = {
|
||||
[0x01] = { "CRC32", 4},
|
||||
[0x04] = { "CRC64", 8},
|
||||
[0x0A] = { "SHA256", 32},
|
||||
};
|
||||
|
||||
/* Decode the Stream Header field (the first 12 bytes of the .xz Stream). */
|
||||
static enum xz_ret dec_stream_header(struct xz_dec *s)
|
||||
{
|
||||
if (! memeq(s->temp.buf, HEADER_MAGIC, HEADER_MAGIC_SIZE))
|
||||
return XZ_FORMAT_ERROR;
|
||||
|
||||
uint8_t crc32_context[GRUB_MD_CRC32->contextsize];
|
||||
#ifndef GRUB_EMBED_DECOMPRESSOR
|
||||
if (s->crc32)
|
||||
{
|
||||
uint64_t hash_context[(s->crc32->contextsize + 7) / 8];
|
||||
uint8_t resulthash[s->crc32->mdlen];
|
||||
uint8_t readhash[4];
|
||||
|
||||
GRUB_MD_CRC32->init(crc32_context);
|
||||
GRUB_MD_CRC32->write(crc32_context,s->temp.buf + HEADER_MAGIC_SIZE, 2);
|
||||
GRUB_MD_CRC32->final(crc32_context);
|
||||
s->crc32->init(hash_context);
|
||||
s->crc32->write(hash_context,s->temp.buf + HEADER_MAGIC_SIZE, 2);
|
||||
s->crc32->final(hash_context);
|
||||
|
||||
uint32_t resultcrc = get_unaligned_be32(GRUB_MD_CRC32->read(crc32_context));
|
||||
uint32_t readcrc = get_unaligned_le32(s->temp.buf + HEADER_MAGIC_SIZE + 2);
|
||||
grub_memcpy (resulthash, s->crc32->read(hash_context),
|
||||
s->crc32->mdlen);
|
||||
readhash[0] = s->temp.buf[HEADER_MAGIC_SIZE + 5];
|
||||
readhash[1] = s->temp.buf[HEADER_MAGIC_SIZE + 4];
|
||||
readhash[2] = s->temp.buf[HEADER_MAGIC_SIZE + 3];
|
||||
readhash[3] = s->temp.buf[HEADER_MAGIC_SIZE + 2];
|
||||
|
||||
if(resultcrc != readcrc)
|
||||
return XZ_DATA_ERROR;
|
||||
if(4 != s->crc32->mdlen
|
||||
|| grub_memcmp (readhash, resulthash, s->crc32->mdlen) != 0)
|
||||
return XZ_DATA_ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef GRUB_EMBED_DECOMPRESSOR
|
||||
/*
|
||||
* Decode the Stream Flags field. Of integrity checks, we support
|
||||
* only none (Check ID = 0) and CRC32 (Check ID = 1).
|
||||
* Decode the Stream Flags field.
|
||||
*/
|
||||
if (s->temp.buf[HEADER_MAGIC_SIZE] != 0
|
||||
|| s->temp.buf[HEADER_MAGIC_SIZE + 1] > 1)
|
||||
|| s->temp.buf[HEADER_MAGIC_SIZE + 1] >= ARRAY_SIZE (hashes)
|
||||
|| (hashes[s->temp.buf[HEADER_MAGIC_SIZE + 1]].name == 0
|
||||
&& s->temp.buf[HEADER_MAGIC_SIZE + 1] != 0))
|
||||
return XZ_OPTIONS_ERROR;
|
||||
|
||||
s->has_crc32 = s->temp.buf[HEADER_MAGIC_SIZE + 1];
|
||||
s->hash_id = s->temp.buf[HEADER_MAGIC_SIZE + 1];
|
||||
|
||||
if (s->crc32)
|
||||
{
|
||||
s->crc32_context = kmalloc(s->crc32->contextsize, GFP_KERNEL);
|
||||
if (s->crc32_context == NULL)
|
||||
return XZ_MEMLIMIT_ERROR;
|
||||
s->crc32->init(s->crc32_context);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (s->temp.buf[HEADER_MAGIC_SIZE + 1])
|
||||
{
|
||||
s->hash_size = hashes[s->temp.buf[HEADER_MAGIC_SIZE + 1]].size;
|
||||
#ifndef GRUB_EMBED_DECOMPRESSOR
|
||||
s->hash = grub_crypto_lookup_md_by_name (hashes[s->temp.buf[HEADER_MAGIC_SIZE + 1]].name);
|
||||
if (s->hash)
|
||||
{
|
||||
if (s->hash->mdlen != s->hash_size)
|
||||
return XZ_OPTIONS_ERROR;
|
||||
s->hash_context = kmalloc(s->hash->contextsize, GFP_KERNEL);
|
||||
if (s->hash_context == NULL)
|
||||
{
|
||||
kfree(s->crc32_context);
|
||||
return XZ_MEMLIMIT_ERROR;
|
||||
}
|
||||
|
||||
s->index.hash.hash_context = kmalloc(s->hash->contextsize,
|
||||
GFP_KERNEL);
|
||||
if (s->index.hash.hash_context == NULL)
|
||||
{
|
||||
kfree(s->hash_context);
|
||||
kfree(s->crc32_context);
|
||||
return XZ_MEMLIMIT_ERROR;
|
||||
}
|
||||
|
||||
s->block.hash.hash_context = kmalloc(s->hash->contextsize, GFP_KERNEL);
|
||||
if (s->block.hash.hash_context == NULL)
|
||||
{
|
||||
kfree(s->index.hash.hash_context);
|
||||
kfree(s->hash_context);
|
||||
kfree(s->crc32_context);
|
||||
return XZ_MEMLIMIT_ERROR;
|
||||
}
|
||||
|
||||
s->hash->init(s->hash_context);
|
||||
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
|
||||
{
|
||||
#ifndef GRUB_EMBED_DECOMPRESSOR
|
||||
s->hash = 0;
|
||||
#endif
|
||||
s->hash_size = 0;
|
||||
}
|
||||
|
||||
s->have_hash_value = 0;
|
||||
|
||||
|
||||
return XZ_OK;
|
||||
}
|
||||
|
@ -407,17 +551,30 @@ static enum xz_ret dec_stream_footer(struct xz_dec *s)
|
|||
if (! memeq(s->temp.buf + 10, FOOTER_MAGIC, FOOTER_MAGIC_SIZE))
|
||||
return XZ_DATA_ERROR;
|
||||
|
||||
uint8_t crc32_context[GRUB_MD_CRC32->contextsize];
|
||||
#ifndef GRUB_EMBED_DECOMPRESSOR
|
||||
if (s->crc32)
|
||||
{
|
||||
uint64_t hash_context[(s->crc32->contextsize + 7) / 8];
|
||||
uint8_t resulthash[s->crc32->mdlen];
|
||||
uint8_t readhash[4];
|
||||
|
||||
GRUB_MD_CRC32->init(crc32_context);
|
||||
GRUB_MD_CRC32->write(crc32_context, s->temp.buf + 4, 6);
|
||||
GRUB_MD_CRC32->final(crc32_context);
|
||||
s->crc32->init(hash_context);
|
||||
s->crc32->write(hash_context,s->temp.buf + 4, 6);
|
||||
s->crc32->final(hash_context);
|
||||
|
||||
uint32_t resultcrc = get_unaligned_be32(GRUB_MD_CRC32->read(crc32_context));
|
||||
uint32_t readcrc = get_unaligned_le32(s->temp.buf);
|
||||
grub_memcpy (resulthash, s->crc32->read(hash_context),
|
||||
s->crc32->mdlen);
|
||||
readhash[0] = s->temp.buf[3];
|
||||
readhash[1] = s->temp.buf[2];
|
||||
readhash[2] = s->temp.buf[1];
|
||||
readhash[3] = s->temp.buf[0];
|
||||
|
||||
if(4 != s->crc32->mdlen
|
||||
|| grub_memcmp (readhash, resulthash, s->crc32->mdlen) != 0)
|
||||
return XZ_DATA_ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
if(resultcrc != readcrc)
|
||||
return XZ_DATA_ERROR;
|
||||
|
||||
/*
|
||||
* Validate Backward Size. Note that we never added the size of the
|
||||
|
@ -427,8 +584,10 @@ static enum xz_ret dec_stream_footer(struct xz_dec *s)
|
|||
if ((s->index.size >> 2) != get_le32(s->temp.buf + 4))
|
||||
return XZ_DATA_ERROR;
|
||||
|
||||
if (s->temp.buf[8] != 0 || s->temp.buf[9] != s->has_crc32)
|
||||
#ifndef GRUB_EMBED_DECOMPRESSOR
|
||||
if (s->temp.buf[8] != 0 || s->temp.buf[9] != s->hash_id)
|
||||
return XZ_DATA_ERROR;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Use XZ_STREAM_END instead of XZ_OK to be more convenient
|
||||
|
@ -447,18 +606,29 @@ static enum xz_ret dec_block_header(struct xz_dec *s)
|
|||
* eight bytes so this is safe.
|
||||
*/
|
||||
s->temp.size -= 4;
|
||||
#ifndef GRUB_EMBED_DECOMPRESSOR
|
||||
if (s->crc32)
|
||||
{
|
||||
uint64_t hash_context[(s->crc32->contextsize + 7) / 8];
|
||||
uint8_t resulthash[s->crc32->mdlen];
|
||||
uint8_t readhash[4];
|
||||
|
||||
uint8_t crc32_context[GRUB_MD_CRC32->contextsize];
|
||||
s->crc32->init(hash_context);
|
||||
s->crc32->write(hash_context,s->temp.buf, s->temp.size);
|
||||
s->crc32->final(hash_context);
|
||||
|
||||
GRUB_MD_CRC32->init(crc32_context);
|
||||
GRUB_MD_CRC32->write(crc32_context, s->temp.buf, s->temp.size);
|
||||
GRUB_MD_CRC32->final(crc32_context);
|
||||
grub_memcpy (resulthash, s->crc32->read(hash_context),
|
||||
s->crc32->mdlen);
|
||||
readhash[3] = s->temp.buf[s->temp.size];
|
||||
readhash[2] = s->temp.buf[s->temp.size + 1];
|
||||
readhash[1] = s->temp.buf[s->temp.size + 2];
|
||||
readhash[0] = s->temp.buf[s->temp.size + 3];
|
||||
|
||||
uint32_t resultcrc = get_unaligned_be32(GRUB_MD_CRC32->read(crc32_context));
|
||||
uint32_t readcrc = get_unaligned_le32(s->temp.buf + s->temp.size);
|
||||
|
||||
if (resultcrc != readcrc)
|
||||
return XZ_DATA_ERROR;
|
||||
if(4 != s->crc32->mdlen
|
||||
|| grub_memcmp (readhash, resulthash, s->crc32->mdlen) != 0)
|
||||
return XZ_DATA_ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
s->temp.pos = 2;
|
||||
|
||||
|
@ -638,11 +808,9 @@ static enum xz_ret dec_main(struct xz_dec *s, struct xz_buf *b)
|
|||
s->sequence = SEQ_BLOCK_CHECK;
|
||||
|
||||
case SEQ_BLOCK_CHECK:
|
||||
if (s->has_crc32) {
|
||||
ret = crc32_validate(s, b);
|
||||
if (ret != XZ_STREAM_END)
|
||||
return ret;
|
||||
}
|
||||
ret = hash_validate(s, b, 0);
|
||||
if (ret != XZ_STREAM_END)
|
||||
return ret;
|
||||
|
||||
s->sequence = SEQ_BLOCK_START;
|
||||
break;
|
||||
|
@ -669,23 +837,32 @@ static enum xz_ret dec_main(struct xz_dec *s, struct xz_buf *b)
|
|||
/* Finish the CRC32 value and Index size. */
|
||||
index_update(s, b);
|
||||
|
||||
/* Compare the hashes to validate the Index field. */
|
||||
GRUB_MD_CRC32->final(s->block.hash.crc32_context);
|
||||
GRUB_MD_CRC32->final(s->index.hash.crc32_context);
|
||||
uint32_t block_crc = *(uint32_t*)GRUB_MD_CRC32->read(s->block.hash.crc32_context);
|
||||
uint32_t index_crc = *(uint32_t*)GRUB_MD_CRC32->read(s->index.hash.crc32_context);
|
||||
|
||||
if (s->block.hash.unpadded != s->index.hash.unpadded
|
||||
|| s->block.hash.uncompressed != s->index.hash.uncompressed
|
||||
|| block_crc != index_crc)
|
||||
#ifndef GRUB_EMBED_DECOMPRESSOR
|
||||
if (s->hash)
|
||||
{
|
||||
return XZ_DATA_ERROR;
|
||||
uint8_t block_hash[s->hash->mdlen];
|
||||
uint8_t index_hash[s->hash->mdlen];
|
||||
/* Compare the hashes to validate the Index field. */
|
||||
s->hash->final(s->block.hash.hash_context);
|
||||
s->hash->final(s->index.hash.hash_context);
|
||||
grub_memcpy (block_hash,
|
||||
s->hash->read(s->block.hash.hash_context),
|
||||
s->hash->mdlen);
|
||||
grub_memcpy (index_hash,
|
||||
s->hash->read(s->index.hash.hash_context),
|
||||
s->hash->mdlen);
|
||||
|
||||
if (s->block.hash.unpadded != s->index.hash.unpadded
|
||||
|| s->block.hash.uncompressed != s->index.hash.uncompressed
|
||||
|| grub_memcmp (block_hash, index_hash, s->hash->mdlen) != 0)
|
||||
return XZ_DATA_ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
s->sequence = SEQ_INDEX_CRC32;
|
||||
|
||||
case SEQ_INDEX_CRC32:
|
||||
ret = crc32_validate(s, b);
|
||||
ret = hash_validate(s, b, 1);
|
||||
if (ret != XZ_STREAM_END)
|
||||
return ret;
|
||||
|
||||
|
@ -764,49 +941,26 @@ enum xz_ret xz_dec_run(struct xz_dec *s, struct xz_buf *b)
|
|||
return ret;
|
||||
}
|
||||
|
||||
#ifdef GRUB_EMBED_DECOMPRESSOR
|
||||
struct xz_dec decoder;
|
||||
#endif
|
||||
|
||||
struct xz_dec * xz_dec_init(uint32_t dict_max)
|
||||
{
|
||||
struct xz_dec *s = kmalloc(sizeof(*s), GFP_KERNEL);
|
||||
struct xz_dec *s;
|
||||
#ifdef GRUB_EMBED_DECOMPRESSOR
|
||||
s = &decoder;
|
||||
#else
|
||||
s = kmalloc(sizeof(*s), GFP_KERNEL);
|
||||
if (s == NULL)
|
||||
return NULL;
|
||||
#endif
|
||||
|
||||
/* prepare CRC32 calculators */
|
||||
if(GRUB_MD_CRC32 == NULL)
|
||||
{
|
||||
kfree(s);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
s->crc32_context = kmalloc(GRUB_MD_CRC32->contextsize, GFP_KERNEL);
|
||||
if (s->crc32_context == NULL)
|
||||
{
|
||||
kfree(s);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
s->index.hash.crc32_context = kmalloc(GRUB_MD_CRC32->contextsize, GFP_KERNEL);
|
||||
if (s->index.hash.crc32_context == NULL)
|
||||
{
|
||||
kfree(s->crc32_context);
|
||||
kfree(s);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
s->block.hash.crc32_context = kmalloc(GRUB_MD_CRC32->contextsize, GFP_KERNEL);
|
||||
if (s->block.hash.crc32_context == NULL)
|
||||
{
|
||||
kfree(s->index.hash.crc32_context);
|
||||
kfree(s->crc32_context);
|
||||
kfree(s);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
GRUB_MD_CRC32->init(s->crc32_context);
|
||||
s->crc32_temp = 0;
|
||||
GRUB_MD_CRC32->init(s->index.hash.crc32_context);
|
||||
GRUB_MD_CRC32->init(s->block.hash.crc32_context);
|
||||
memset (s, 0, sizeof (*s));
|
||||
|
||||
#ifndef GRUB_EMBED_DECOMPRESSOR
|
||||
s->crc32 = grub_crypto_lookup_md_by_name ("CRC32");
|
||||
#endif
|
||||
|
||||
s->single_call = dict_max == 0;
|
||||
|
||||
|
@ -828,7 +982,9 @@ error_lzma2:
|
|||
xz_dec_bcj_end(s->bcj);
|
||||
error_bcj:
|
||||
#endif
|
||||
#ifndef GRUB_EMBED_DECOMPRESSOR
|
||||
kfree(s);
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -839,34 +995,49 @@ void xz_dec_reset(struct xz_dec *s)
|
|||
s->pos = 0;
|
||||
|
||||
{
|
||||
uint8_t *t;
|
||||
t = s->block.hash.crc32_context;
|
||||
#ifndef GRUB_EMBED_DECOMPRESSOR
|
||||
uint64_t *t;
|
||||
t = s->block.hash.hash_context;
|
||||
#endif
|
||||
memzero(&s->block, sizeof(s->block));
|
||||
s->block.hash.crc32_context = t;
|
||||
t = s->index.hash.crc32_context;
|
||||
#ifndef GRUB_EMBED_DECOMPRESSOR
|
||||
s->block.hash.hash_context = t;
|
||||
t = s->index.hash.hash_context;
|
||||
#endif
|
||||
memzero(&s->index, sizeof(s->index));
|
||||
s->index.hash.crc32_context = t;
|
||||
#ifndef GRUB_EMBED_DECOMPRESSOR
|
||||
s->index.hash.hash_context = t;
|
||||
#endif
|
||||
}
|
||||
s->temp.pos = 0;
|
||||
s->temp.size = STREAM_HEADER_SIZE;
|
||||
|
||||
GRUB_MD_CRC32->init(s->crc32_context);
|
||||
s->crc32_temp = 0;
|
||||
GRUB_MD_CRC32->init(s->index.hash.crc32_context);
|
||||
GRUB_MD_CRC32->init(s->block.hash.crc32_context);
|
||||
|
||||
#ifndef GRUB_EMBED_DECOMPRESSOR
|
||||
if (s->hash)
|
||||
{
|
||||
s->hash->init(s->hash_context);
|
||||
s->hash->init(s->index.hash.hash_context);
|
||||
s->hash->init(s->block.hash.hash_context);
|
||||
}
|
||||
#endif
|
||||
s->have_hash_value = 0;
|
||||
}
|
||||
|
||||
void xz_dec_end(struct xz_dec *s)
|
||||
{
|
||||
if (s != NULL) {
|
||||
xz_dec_lzma2_end(s->lzma2);
|
||||
kfree(s->index.hash.crc32_context);
|
||||
kfree(s->block.hash.crc32_context);
|
||||
#ifndef GRUB_EMBED_DECOMPRESSOR
|
||||
kfree(s->index.hash.hash_context);
|
||||
kfree(s->block.hash.hash_context);
|
||||
kfree(s->hash_context);
|
||||
kfree(s->crc32_context);
|
||||
#endif
|
||||
#ifdef XZ_DEC_BCJ
|
||||
xz_dec_bcj_end(s->bcj);
|
||||
#endif
|
||||
#ifndef GRUB_EMBED_DECOMPRESSOR
|
||||
kfree(s);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue