merge mainline into backtrace

This commit is contained in:
Vladimir 'phcoder' Serbinenko 2011-11-14 10:50:24 +01:00
commit 245f4582f9
871 changed files with 102908 additions and 16407 deletions

View file

@ -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>

View file

@ -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
View 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);
}

View 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");
}

View file

@ -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
View 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;
}

View file

@ -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;
}

View file

@ -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
View 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);
}

View file

@ -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
}

View file

@ -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)

View file

@ -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);

View 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 (;;) ;
}

View file

@ -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);

View file

@ -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 ... */

View file

@ -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;

View 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 */
};

View 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);
}

View 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)

View file

@ -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));

View file

@ -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

View file

@ -17,9 +17,12 @@
*/
#include <grub/symbol.h>
#include <grub/dl.h>
.file "setjmp.S"
GRUB_MOD_LICENSE ("GPLv3+")
.text
/*

View 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
View 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

View 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;
}

View file

@ -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)

View 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 (;;) ;
}

View file

@ -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))

View 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;
}
}

View file

@ -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

View 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: */

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View 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 */

View 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);
}

View 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);
}

View 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);
}

View file

@ -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"

View file

@ -17,9 +17,12 @@
*/
#include <grub/symbol.h>
#include <grub/dl.h>
.file "setjmp.S"
GRUB_MOD_LICENSE ("GPLv3+")
.text
/*

View file

@ -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,

View file

@ -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

View file

@ -0,0 +1 @@
#include <sys/types.h>

View file

@ -29,7 +29,7 @@ nl_langinfo (nl_item item)
switch (item)
{
case CODESET:
return locale_charset ();
return "UTF-8";
default:
return "";
}

View file

@ -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

View file

@ -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";

View file

@ -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

View file

@ -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

View file

@ -17,9 +17,12 @@
*/
#include <grub/symbol.h>
#include <grub/dl.h>
.file "setjmp.S"
GRUB_MOD_LICENSE ("GPLv3+")
.text
/*

View 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

View file

@ -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;

View file

@ -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

View file

@ -17,9 +17,12 @@
*/
#include <grub/symbol.h>
#include <grub/dl.h>
.file "setjmp.S"
GRUB_MOD_LICENSE ("GPLv3+")
.text
/*

View file

@ -17,9 +17,12 @@
*/
#include <grub/symbol.h>
#include <grub/dl.h>
.file "setjmp.S"
GRUB_MOD_LICENSE ("GPLv3+")
.text
/*

View file

@ -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;

View file

@ -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
}

View file

@ -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
}
}